Compare commits

..

197 Commits

Author SHA1 Message Date
thor2016 2b8f6e7627
Merge pull request #776 from awjackson/mapper92
Reimplement mapper 92 correctly
2025-01-19 15:03:14 -05:00
thor2016 eb5ca2e6d6
Merge pull request #778 from awjackson/mapper97
More mapper fixes
2025-01-19 15:02:12 -05:00
Alex W. Jackson 4008488b80 Mapper fixes: Fix 97, remove deprecated 101 and 151, add names to various mappers 2025-01-14 07:16:18 -05:00
Alex W. Jackson f15fb4f37c Implement mapper 92 correctly (it's not an address latching mapper but a mapper 72 variant) 2025-01-12 22:38:01 -05:00
thor2016 71ba361794
Merge pull request #774 from chenrui333/revert-766-fix-x265-4.0
chore: scope the patch for x265 4.0 build
2025-01-03 13:22:27 -05:00
Rui Chen 3bf931e5ca
chore: scope the patch for x265 4.0 build
upstream has reverted the x265_encoder_encode api change in 78e5b703b1 per 4.1 release, thus the patch is no longer needed, hence reverting for now. (previous 4.0 API change commit, c69c113960)

Signed-off-by: Rui Chen <rui@chenrui.dev>
2024-12-28 22:12:52 -05:00
thor2016 fe65681012
Merge pull request #772 from brad0/arm64_build
Use proper symbol name checking for arm64
2024-12-08 09:23:39 -05:00
Brad Smith f803006608 Use proper symbol name checking for arm64
The proper symbol for checking for 64-bit ARM is __aarch64__
2024-12-08 07:49:34 -05:00
harry e315b06ff3 Updated MacOSX auto build environment to ventura OS. 2024-11-24 04:22:51 -05:00
harry 214773faae Added tas editor lua null checks for Qt GUI. 2024-11-24 04:16:27 -05:00
thor2016 0ba9ffe3a4
Merge pull request #755 from parasyte/fix/cdlogger-invalidation
Fix PRG reads and writes in CD Logger
2024-11-24 03:49:19 -05:00
thor2016 6dc277a27c
Merge pull request #756 from parasyte/fix/debugger-overflow
Fix "OVERFLOW" byte not being shown at address $FFFF.
2024-11-24 03:47:20 -05:00
thor2016 3c8e0a0dcb
Merge pull request #754 from parasyte/fix/attribution
Fix attribution
2024-11-24 03:45:48 -05:00
thor2016 4a2d980f9d
Merge pull request #765 from negativeExponent/patch-2
MMC5: Fix initial values for chr banks and nametables
2024-11-24 03:41:08 -05:00
thor2016 940c895de5
Merge pull request #767 from negativeExponent/add_m451_m471
Add mappers 451 and 471
2024-11-24 03:39:46 -05:00
thor2016 3f599cb3e6
Merge pull request #758 from silverslither/master
Enable TAS Editor Lua functions on QT
2024-11-24 03:38:45 -05:00
thor2016 cd057bb13f
Merge pull request #766 from chenrui333/fix-x265-4.0
chore: update AviRecord to comply with updated x265 API
2024-11-24 03:35:45 -05:00
Rui Chen a6fcb73b11
chore: update AviRecord to comply with updated x265 API
Some patch ref: https://code.videolan.org/videolan/vlc/-/merge_requests/6167
upstream commit: c69c113960

Signed-off-by: Rui Chen <rui@chenrui.dev>
2024-11-23 17:17:48 -05:00
negative fb0b178c1d
Add mappers 451 and 471
As requested.
Fix https://github.com/TASEmulators/fceux/issues/761
2024-10-31 11:07:19 +08:00
negativeExponent 4441f3cbdf
MMC5: Fix initial values for chr banks and nametables
At least 1 game expect chr bank and nametables to be initialized at zero (fix Deathloop 256)
2024-10-28 15:32:24 +08:00
Jay Oster 65f4a482d5 Do not treat jump destinations as data accesses
The two JMP instructions have address modes that imply a data access
occurs. All branch instructions and JSR have `optype` 0, so they don't
have this problem.
2024-09-13 12:46:48 -07:00
silverslither daa2f817a9 enabled taseditor lua functions for QT 2024-09-13 13:02:38 -04:00
Jay Oster 5886b9e157 Fix "OVERFLOW" byte not being shown at address $FFFF. 2024-09-13 00:59:01 -07:00
Jay Oster 9da80206f8 Fix PRG writes in CD Logger
This code was added for FDS RAM, but it breaks PRG writes with normal
cartridge-based memory controllers.

The bug inappropriately resets (clears) the access mode bits previously
recorded when an MMIO register is written in PRG address space. For
instance, if an instruction is executed at $8000 and then some code
later writes to $8000, the instruction execution would have been
forgotten.
2024-09-12 15:25:00 -07:00
Jay Oster 0f6c5b2936 Fix attribution
This change de-duplicates Xodnizel's identity in some "About" windows.

Closes #753
2024-08-19 13:04:40 -07:00
thor2016 f980ec2bc7
Merge pull request #732 from awjackson/fix_731
Make X24C02 only enter read/write state if I2C address matches; fixes #731
2024-06-09 14:22:20 -04:00
harry e6efd7f694 Fix for gcc misleading indentation in lua-engine.cpp. 2024-06-09 14:10:15 -04:00
harry eecb2e77b6 Replace strncpy usage in favor of Strlcpy to get rid of compiler warnings. 2024-06-09 14:07:41 -04:00
harry ecbfca1084 Minor gcc/clang compiler warning fix. 2024-06-09 09:34:08 -04:00
thor2016 c919de08b2
Merge pull request #735 from awjackson/fixbuild
Fix Linux build
2024-05-29 07:35:46 -04:00
Alex W. Jackson d94157e125 Fix Linux build 2024-05-28 19:56:07 -04:00
Alexey Cluster 14df08d804 Take NES 2.0 header WRAM size into account for MMC3 2024-05-28 14:03:27 +04:00
harry ffb28e1131 Changed Qt Avi recording to use atomic buffer indices to ensure both threads are aware of changes when they happen. 2024-05-11 07:09:42 -04:00
harry 283aea91db For Qt netplay, reset client frame rate adjustment to normal on disconnect. 2024-05-11 06:16:12 -04:00
Alex W. Jackson 38bb5b1f51 Make X24C02 only enter read/write state if I2C address matches; fixes SD Gundam Gaiden 2 2024-05-07 17:32:15 -04:00
harry c4dd4f5153 Updated client netplay rom requests to only send extracted archive files as well. 2024-05-05 06:29:47 -04:00
harry 0ea2670ae0 For Qt GUI, store archive file index so that a hard reload knows how to refind the ROM inside the archive. For netplay, don't send entire zip archives. Instead just send the single extracted ROM of interest. 2024-05-05 05:57:11 -04:00
harry 4b36de6ec9 Build fix. 2024-05-04 23:08:34 -04:00
harry 4e57ca40ae For Qt GUI, create a temp directory per every boot of application that can be used to store temporary files for things such as netplay roms. This folder is deleted at application exit. 2024-05-04 22:04:29 -04:00
thor2016 151c951d63
Merge pull request #730 from TheRealQuantam/indy-fix
"(z),Y" addressing incorrectly shown as "(z,Y)" in debugger
2024-04-18 21:29:12 -04:00
TheRealQuantam 1028732d84 Remember that Qt and Win versions have different disassembly code 2024-04-16 18:40:09 -07:00
TheRealQuantam fa6e4411dd "(z),Y" addressing incorrectly shown as "(z,Y)" in debugger 2024-04-16 18:15:22 -07:00
harry 84b823ffa7 Added more netplay status data to host status dialog. 2024-04-13 15:57:09 -04:00
harry 94975d7dbe Fix code so that FCEUGI fully constructs properly and is not clobbered after the construction by a memset. Also, some minor code cleanup in related areas. 2024-04-12 08:14:20 -04:00
harry c97e2c9ad3 For Qt Netplay, added code to sync cheats between server and clients. 2024-04-11 06:58:43 -04:00
harry 6e698433aa Added netplay debug mode for interface debug logging. 2024-04-08 07:07:08 -04:00
harry 9036dd07bd Added logic to allow netplay host to control pause state of clients. 2024-04-07 21:21:18 -04:00
harry e7d234136c Netplay sync state fixes. 2024-04-07 20:22:32 -04:00
harry 9f8310bbe1 Minor cleanup of netplay main menu. 2024-04-07 15:11:27 -04:00
harry e032d65811 For Qt netplay, changed client message dialogs to be non-blocking. This prevents re-entrant event loops. 2024-04-07 14:53:06 -04:00
thor2016 e751431099
Merge pull request #726 from negativeExponent/patch-1
unrom512.cpp: Expand support for PRG ROM size upto 4M
2024-04-06 10:07:36 -04:00
thor2016 3e1a8ec486
Merge pull request #728 from liyansong2018/master
Fix Path Traversal #727 in Netplay server
2024-04-06 10:05:08 -04:00
liyansong2018 48b48e7c13 Fix Path Traversal in Netplay server 2024-04-06 10:40:29 +08:00
harry f71b912afb Qt netplay fixes for processing input packet data. Don't attempt spawn dialog windows when in read loop, it will cause event loop re-entrancy issues. 2024-04-04 06:43:10 -04:00
harry 10418f551a Added framework for Qt netplay client status dialog. 2024-04-03 04:55:07 -04:00
harry 2fe563181e Added ROM unload handling logic for netplay. 2024-03-26 20:58:21 -04:00
harry 25cab8195f Bug fix for Qt win64 netplay, make sure rom files are opened in binary mode. 2024-03-26 20:20:01 -04:00
harry f50b70b87e Reduce netplay max tcp transmission size to 8k for ROM transfers. 2024-03-24 22:08:15 -04:00
harry 84654b1c06 Set low delay tcp option for netplay. 2024-03-24 21:34:07 -04:00
harry 6e22998336 Increased netplay tcp OS level send/receive buffer sizes. 2024-03-24 21:29:41 -04:00
harry a63f5e6051 Netplay modified data read code to allow smaller buffered data to arrive in pieces rather than waiting for full data set. 2024-03-24 20:49:17 -04:00
harry 450870ef77 Build fix for constexpr vars that conflicted with some win macros. 2024-03-24 16:29:13 -04:00
harry bed9b10380 Added netplay ROM comparison logic. 2024-03-24 15:42:10 -04:00
negativeExponent 79c533ffdc
unrom512.cpp: Expand support for PRG ROM size upto 4M
at least 1 cart in Mapper30 has 2MB. current implementation only allows carts of upto 512K
2024-03-24 10:27:52 +08:00
harry cc61b7b5ab Added app version check between netplay host and clients to ensure interface compatibility. 2024-03-23 19:01:33 -04:00
harry cc234ae04b Added on state loaded callback function to core so that driver code can be notified of a new state being loaded. In Qt driver, emit a signal on state loads that objects can connect to. For a resync of all netplay clients when server detects a new state load. 2024-03-23 07:32:25 -04:00
harry 2ff6084935 Qt netplay host game UI dialog improvements. 2024-03-21 22:29:15 -04:00
harry 5a0898ccbe For Qt GUI, added netplay client state load request functionality. 2024-03-21 22:06:40 -04:00
harry 55654f7191 For Qt GUI, changed instruction tracing to be enabled/disabled by registering callback functions. This increases efficiency when tracing is disabled. 2024-03-18 06:02:30 -04:00
thor2016 5eeeb2219f
Merge pull request #721 from vampirecat35/master
Update StringBuilder.h
2024-03-05 08:36:48 -05:00
Andy Vandijck 1926729680
Update StringBuilder.h
Fix nullptr_t to std::nullptr_t
2024-03-05 11:12:34 +01:00
harry 72d1a8edf2 Added netplay client frame throttling functionality to keep it in step with server. 2024-03-04 06:47:09 -05:00
harry 798c5a1d9c For NetPlay, added ability for client to request a ROM to load. 2024-03-03 20:30:35 -05:00
harry ee814f99e5 Added NetPlay server force resync and drop player UI functionality. 2024-03-03 13:09:28 -05:00
harry 75e9627aa8 Added framework for a net play host status dialog window. 2024-02-28 07:18:19 -05:00
harry d212b894a7 Added ROM loaded and NES reset signals to allow for net play to reconfigure accordingly during those events. 2024-02-26 07:02:59 -05:00
harry 145fc1614f Added a simple ping message to Qt netplay in an effort to measure round trip message delay. 2024-02-26 06:05:01 -05:00
harry 015f6a0acd Added client pause flag to status message for net play. 2024-02-25 16:22:18 -05:00
harry 6832eaa964 Added custom string class that mirrors the C++ std::string API but also allows for fixed size buffers on the stack. This new class also has various C style functions (like sprintf) built into it. 2024-02-25 16:08:35 -05:00
harry 0123e1fbf8 Added sync checking and network byte ordering code for Qt net play. 2024-02-25 08:40:36 -05:00
harry 8d93015a56 Put win64 auto build back to Qt5 until the Qt6 build issue can be solved. 2024-02-24 18:19:34 -05:00
harry 245a8701e0 More attempted to fix Qt6 win build. 2024-02-24 17:37:00 -05:00
harry 9d08ff453a Another win64 Qt6 build fix 2024-02-24 17:01:43 -05:00
harry ce0dd16abd QHelp build for Mac OSX 2024-02-24 14:03:14 -05:00
harry c14dd99efc Build fix for Qt win platforms when UNICODE defaults to wide chars. 2024-02-24 14:00:31 -05:00
harry f63ac15aa2 Help pages build fixes for Qt6. 2024-02-24 13:56:06 -05:00
harry de549f0eb9 Build fix for const qualifier not being respected. 2024-02-24 13:28:36 -05:00
harry 5f3ce5896a Compile fix for <QtPlatformHeaders/QWindowsWindowFunctions> header not existing in Windows Qt 6. Set Qt win64 auto build to build against Qt 6. 2024-02-24 10:35:09 -05:00
harry e2ac013cbb Run cppcheck static analyzer against code base. Fixed a few warnings. 2024-02-24 08:46:06 -05:00
harry c324a82526 More cleanup of sprintf usage in favor of snprintf. This is to resolve deprecation warnings on Mac OSX 2024-02-24 07:27:20 -05:00
thor2016 db8fd407ab
Merge pull request #718 from TheRealQuantam/tracefix4
Non-SDL/Qt Windows Trace Logging Optimizations
2024-02-24 07:10:36 -05:00
TheRealQuantam 0605967820 Non-SDL/Qt Windows optimizations 2024-02-24 00:11:56 -08:00
harry 548635a2f2 Resolved vsprintf deprecation compiler warning, swap out for vsnprintf 2024-02-23 22:56:27 -05:00
harry 37574f9bef More cleanup of sprintf usage in favor of snprintf. This is to resolve deprecation warnings on Mac OSX 2024-02-23 22:38:40 -05:00
harry 7b79d9db4c Partial cleanup of sprintf usage in favor of snprintf. This is to resolve deprecation warnings on Mac OSX 2024-02-23 20:53:01 -05:00
harry 80f17c664b Resolved a couple gcc compiler warnings in trace logger. 2024-02-23 09:09:08 -05:00
thor2016 b25f56fe12
Merge pull request #686 from negativeExponent/vrc5_128k
Fix 128K CHR-ROM variants for VRC5
2024-02-23 07:34:17 -05:00
thor2016 3d5a062799
Merge pull request #714 from TheRealQuantam/tracefix2
Trace logging optimizations and bug fixes
2024-02-23 07:33:55 -05:00
TheRealQuantam 2d468d7926 Dummy commit to re-validate PR 2024-02-22 00:19:51 -08:00
TheRealQuantam 56980510b7 Trace logging optimizations and bug fixes 2024-02-21 21:00:05 -08:00
harry 780a445468 Added global module import function to Qt GUI JS engine. 2024-02-21 06:59:43 -05:00
harry f04e8a5ea4 NetPlay config and GUI improvements. 2024-02-20 06:56:26 -05:00
harry 0e4c122623 Added a clear recent ROM list menu item to Qt GUI. 2024-02-20 05:11:58 -05:00
harry 36614540fd Minor config improvements. Modified Qt recent ROM menu to drop file entries that no longer exist on disk. 2024-02-20 04:54:07 -05:00
harry cb45321433 More Qt netplay updates. 2024-02-19 15:53:11 -05:00
harry 84c2591d3f Added initial framework for netplay on Qt GUI. Still much TODO here. 2024-02-19 11:57:12 -05:00
harry 2f2279f5ff Added more functions to JS File object. 2024-02-18 21:10:24 -05:00
thor2016 72b297980b
Merge pull request #709 from andyvand/master
Fix strings
2024-02-18 16:08:56 -05:00
harry c62f62b497 Added option on how to handle new gamepad device detection. Can now choose to do nothing, prompt user, or auto reconfigure of button mappings when a new device is detected. 2024-02-18 16:04:00 -05:00
Andy Vandijck 3cf7615aeb
Merge pull request #3 from TASEmulators/master
For Qt GUI, poll SDL events immediately after initializing the joysti…
2024-02-18 17:25:49 +01:00
harry 9ed1dd481b For Qt GUI, poll SDL events immediately after initializing the joystick subsystem to process all input device add events. Added gamepad init logging. 2024-02-18 10:37:26 -05:00
Andy Vandijck 2e18434959 Fix Linux build
Fix Linux build
2024-02-18 15:52:24 +01:00
Andy Vandijck 897849111c Fix Linux build
Fix Linux build
2024-02-18 15:51:11 +01:00
Andy Vandijck b8fce760dd Fix Linux
Fix Linux build
2024-02-18 15:49:36 +01:00
Andy Vandijck 1227e9ebc0 Fix Linux build
Fix Linux build
2024-02-18 15:45:48 +01:00
Andy Vandijck b8ebb122cd Remove .orig file
Remove left overs from patch
2024-02-18 15:14:51 +01:00
Andy Vandijck 2d632dfeeb Change toUtf8() to toLocal8Bit()
Change strings
2024-02-18 14:52:19 +01:00
Andy Vandijck 6e33b530c0
Merge pull request #2 from TASEmulators/master
Improvements
2024-02-18 09:15:04 +01:00
harry 9cd7b620dd Minor JS File object fixes. 2024-02-17 21:01:24 -05:00
harry 460bf597d5 Added initial framework for a JS File object. 2024-02-17 20:52:09 -05:00
harry b5ae9012ce Include missing headers to fix build. 2024-02-17 19:20:04 -05:00
Andy Vandijck ef5df90e69
Update CMakeLists.txt 2024-02-17 20:11:10 +01:00
Andy Vandijck 56b24556df
Merge pull request #1 from TASEmulators/master
Add improvements
2024-02-17 20:08:20 +01:00
Andy Vandijck cde83851ba Fix build for newer targets
Fix build
2024-02-17 19:21:47 +01:00
thor2016 3f81906926
Merge pull request #708 from andyvand/master
Fix timestamp arm64
2024-02-17 10:26:20 -05:00
harry 7b9829eda9 Changed JS log file save function so that it doesn't truncate the current temp file. 2024-02-17 08:42:12 -05:00
harry a929eda845 Added JS log file functionality. 2024-02-17 07:54:00 -05:00
Andy Vandijck 6332900833 Fix timestamp arm64
Fix timestamp arm64
2024-02-17 11:22:03 +01:00
harry ab46158f05 Added movie js function remaps 2024-02-17 04:23:11 -05:00
harry df12fa2a85 Added more movie JS interface functions. Hooked up lua joypad.getimmediate functionality for Qt GUI. 2024-02-16 22:52:04 -05:00
harry aaa519d29c Added initial framework for movie JS API. Still TODO implement rest of movie functions. 2024-02-16 07:12:25 -05:00
harry af9b53ba75 Added joypad button override functionality to JS API. 2024-02-15 22:04:11 -05:00
harry f85f93c5bd JS joypad API improvements. 2024-02-14 06:28:26 -05:00
harry 446763b232 Added JS joypad object functionality. 2024-02-11 14:56:58 -05:00
harry 6248b0ee64 Added ability to pass command line arguments to JS scripts. 2024-02-11 10:43:40 -05:00
harry 20a9c151be JS logging improvements. 2024-02-11 10:25:47 -05:00
harry 2229d32720 Added a QJSEngine wrapper class to maintain link to script instance and dialog window with new script objects. 2024-02-10 23:00:07 -05:00
thor2016 290c4ccd96
Merge pull request #706 from negativeExponent/patch-1
QT: Fix volume adjustment for APU
2024-02-10 08:49:11 -05:00
negativeExponent 8d0fe851bf
QT: Fix volume adjustment for APU
Volume adjustments for the apu channel has a range of 0-256. With a value of 256, this acts as a bypass (toggle) and skips the computation entirely when set. This fixes issues when the original signal is too low already that passing it through volume controls will attunuate the signal instead and silence it.

The main volume does not behave the same way and 256 is not a toggle, so left it as-is.

@thor2016 feel free to make it better if necessary, maybe a toggle instead of a 256 max value or something.
2024-02-09 10:19:47 +08:00
harry 8ebb560d1c Added emulator save state JS interface. 2024-02-06 22:44:08 -05:00
harry 2f2482e950 Minor null check fix. 2024-02-05 18:34:03 -05:00
harry 401110bae8 Added ppu interface functions to JS engine. 2024-02-05 18:29:25 -05:00
harry a5071f10f0 Implemented ROM JS interface object. 2024-02-05 06:43:27 -05:00
harry 61da515f11 Finished remaining JS interface functions for JS emu object. 2024-02-05 05:56:40 -05:00
harry 1fc813803e Added JS script monitoring thread to prevent bad scripts from hanging the gui. 2024-02-04 22:09:59 -05:00
thor2016 5495c7eddc
Merge pull request #699 from TheRealQuantam/luafixes2
Multiple Lua Implementation Fixes
2024-02-04 09:07:23 -05:00
harry 4fa0d0651a Added vsync timer logic to Qt OpenGL video driver. 2024-01-31 07:08:08 -05:00
harry 01358407fd For Qt GUI, changed onFrameFinished callback to only update video buffer. Don't do any input processing as this will mess up when running turbo mode. Added a draw timer to SDL video renderer to better align is scheduling with the next vsync. 2024-01-31 06:49:54 -05:00
harry d363d04dbb For Qt GUI, add video buffer mutex to ensure clean transfer between emulation and GUI threads. Use common FCEU::mutex wrapper for cleaner code. 2024-01-31 05:28:41 -05:00
thor2016 cb0edc5a21
Merge pull request #695 from negativeExponent/mapper413
Mapper413
2024-01-31 04:29:21 -05:00
TheRealQuantam f702b5b989 Retriggering checks 2024-01-30 14:25:06 -08:00
harry 19abb0b249 Fix for build break, QJSEngine::setObjectOwnership does not exist in Qt5. Only in version 6. 2024-01-30 06:50:40 -05:00
TheRealQuantam c56b234b85 Multiple Lua support fixes:
- Do not crash when a Lua script calls rom.gethash when no ROM is loaded
- Do NOT assume the error message from lua_pcall will always be in stack slot 1, as sometimes it won't be
2024-01-30 02:41:42 -08:00
TheRealQuantam c7330d4543 Revert bad fix for not terminating script on initial error 2024-01-30 01:41:13 -08:00
harry 6b96016047 JS scripting in work. 2024-01-29 23:17:15 -05:00
harry 813d4c0c4b Added nullptr check in the event QStyle factory fails. 2024-01-29 20:19:36 -05:00
TheRealQuantam 5ff4edbdad Multiple Lua support fixes:
- Move call to info_onstop from FCEU_LuaStop to FCEU_LuaOnStop so it will always get called
- Do NOT assume the error message from lua_pcall will always be in stack slot 1, as sometimes it won't be
- After calling HandleCallbackError ensure L still exists before calling lua_settop
2024-01-28 19:01:49 -08:00
negative 5631e488f4
fix indents 2024-01-29 07:57:43 +08:00
harry a85f348e50 For Qt GUI, edit frame throttling logic when using turbo mode or really fast emulation speed to not be so wasteful when emulation is paused. Don't make sense to waste CPU resources spinning on nothing. Fixes #681. 2024-01-28 08:15:00 -05:00
harry c50c1d570c Change linear filter checkbox text to not include OpenGL. This function not specific to OpenGL and works for all supported video drivers. 2024-01-27 19:35:01 -05:00
harry b03c9c9c8b Removed const qualifiers to fix Qt build. Different versions of Qt QJSValue don't allow the call method to called from a const object. 2024-01-27 01:04:48 -05:00
harry fe0496a6cf Bug fix for issue in new LUA memory hook scheme where the callbacks get unregistered from the x6502 while still running. Fixes #693 2024-01-27 00:39:23 -05:00
harry a02ae8d3e0 Added memory hooks to JS engine. 2024-01-26 22:57:54 -05:00
thor2016 4f604b7708
Merge pull request #690 from negativeExponent/fix_ntsc_clip
Clip Left/Right Sides option now taken into account when using NTSC s…
2024-01-26 22:04:15 -05:00
harry 23cf99afe5 Added source listing to gdb debug output. 2024-01-26 22:00:20 -05:00
harry 3e8978c2aa Added debug script to aid in getting crash callstacks from users. 2024-01-26 20:33:40 -05:00
negative 82a99060e5
Use macro and minor offset adjustment 2024-01-25 18:10:48 +08:00
negative 8e935a05a6
Clip Left/Right Sides option now taken into account when using NTSC scaler 2024-01-24 14:52:45 +08:00
harry 2fce5ffe74 Added memory access functions for JS script interface. 2024-01-19 16:54:56 -05:00
harry 7a0be296fa Added logic to realtime update js global variable viewer. 2024-01-17 07:14:10 -05:00
harry 1dde9e7e75 Minor fixes for JS global variable viewer. 2024-01-16 22:04:00 -05:00
harry dc2d3c26aa Added global JS property tree to allow exploring of engine data. 2024-01-16 21:48:13 -05:00
harry 9a9f9541d6 Build fix for systems without Qt QML installed. 2024-01-15 20:09:25 -05:00
harry 198cdafbf8 Qt JS script engine interface in work. 2024-01-15 14:17:13 -05:00
harry 8e7e5e8c05 Minor refactor of script memory hook interface so that both lua and js script can coexist nicely. Script engines now register themselves with the CPU module for their functions to be called. 2024-01-15 09:31:53 -05:00
harry f90a269386 Build fix for Qt6. 2024-01-15 05:57:24 -05:00
harry e51a748a05 Qt JS engine in work. 2024-01-15 05:34:13 -05:00
harry ecda95ed70 Qt JS engine in work. 2024-01-15 04:33:27 -05:00
harry 3436e221de For Qt GUI, added initial framework for use of the Qt built-in ECMAScript (javascript based) engine. This scripting capability will allow users to load their own custom UI windows (created using Qt Creator tool) in the GUI. This is intended to serve as a the Qt GUI's functional replacement for building GUI elements using IUP in LUA scripts. This is a work in progress. 2024-01-14 08:58:10 -05:00
negative d742620d72
Fix 128K CHR-ROM variants for VRC5 2024-01-13 09:30:42 +08:00
negative aace08d0b6
Add mapper 413 support 2024-01-07 22:03:33 +08:00
negative 647c08e1e6
Add support for misc rom area 2024-01-07 21:59:25 +08:00
harry b53d087fca Changed Qt Win64 1px fullscreen window border to be a configuration option. Doesn't seem to be necessary for all users and maybe not at all anymore. We will see if the QOpenGLWidget issue resurfaces with this setting off. Fixes #514 2023-12-12 21:27:55 -05:00
Alexey Cluster e806a5a25a
Merge pull request #676 from negativeExponent/master
Fix handling of roms with  prg size below 16K
2023-12-09 22:46:54 +04:00
negative 1bd7e2f5b9
Fix handling of roms with prg size below 16K
Fix https://github.com/TASEmulators/fceux/issues/675
2023-12-08 18:39:15 +08:00
harry 72b949efcd For Qt GUI, added hot keys for certain emulation speed presets. Presets are: 1/4x, 1/2x, Normal 1x, 2x, 4x, 8x, and 16x. These hot keys can be mapped to gamepads using advanced key bindings. 2023-11-30 21:09:52 -05:00
harry 8600679636 Comment out warning message about debug file not being able to be opened for reading. It is normal for the file to not exist so it seems silly to warn about not being able to open it. 2023-11-24 09:02:50 -05:00
harry 2909846446 Upgrade appveyor macos build environment to monterey. Also auto build macos app with Qt6. 2023-11-17 21:57:16 -05:00
Alexey 'Cluster' Avdyukhin 5a5faa7372 More mapper 45 fixes 2023-10-26 23:33:49 +04:00
Alexey 'Cluster' Avdyukhin 764e1ebd76 Mapper 45 fixes 2023-10-26 23:19:38 +04:00
Alexey 'Cluster' Avdyukhin 33aca22af2 Issue #654 fix 2023-10-02 23:38:44 +04:00
Alexey 'Cluster' Avdyukhin e0138e5bfd Mapper 134 fix 2023-10-02 22:57:04 +04:00
Alexey 'Cluster' Avdyukhin 1ffa4d7f0c Mapper 134 CHR and PRG masks 2023-10-02 22:42:48 +04:00
harry d2ee6351c0 Added feature macro __FCEU_X86_TSC_ENABLE to enable usage of the X86 TSC. 2023-09-07 19:12:44 -04:00
zeromus 396096223e fix build errors from rdtsc (fixes #663) 2023-09-07 18:56:48 -04:00
harry d86c81e26e Fixed memory leak bug where FCEU_LoadGameSave and FCEU_SaveGameSave functions were not closing out their file handles. 2023-08-30 17:47:16 -04:00
harry 5252188010 Updated web pages and download links for 2.6.6 release. 2023-08-28 06:56:26 -04:00
156 changed files with 14085 additions and 2389 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
build
/vc/defaultconfig/scmrev.h
/vc/.vs
/vc/vc14_bin_Debug

View File

@ -16,7 +16,7 @@ environment:
appveyor_build_worker_image: Ubuntu2004
- job_name: MacOS
appveyor_build_worker_image: macos-bigsur
appveyor_build_worker_image: macos-ventura
for:

View File

@ -9,7 +9,7 @@ env
SCRIPT_DIR=$( cd $(dirname $BASH_SOURCE[0]); pwd );
QT_MAJOR=5;
QT_MAJOR=6;
QT_PKGNAME=qt$QT_MAJOR;
FCEUX_VERSION_MAJOR=`perl $SCRIPT_DIR/../scripts/fceuVersion.pl -major`;
FCEUX_VERSION_MINOR=`perl $SCRIPT_DIR/../scripts/fceuVersion.pl -minor`;

View File

@ -3,7 +3,7 @@ set PROJECT_ROOT=%~dp0..
set CWD=%CD%
call "C:\Qt\5.15\msvc2019_64\bin\qtenv2.bat"
REM call "C:\Qt\6.0\msvc2019_64\bin\qtenv2.bat"
REM call "C:\Qt\6.5\msvc2019_64\bin\qtenv2.bat"
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
cd /d %CWD%
@ -50,7 +50,7 @@ IF DEFINED FCEU_RELEASE_VERSION (set PUBLIC_RELEASE=1)
REM cmake -h
REM cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DSDL_INSTALL_PREFIX=%SDL_INSTALL_PREFIX% ..
cmake -DQT6=0 -DPUBLIC_RELEASE=%PUBLIC_RELEASE% -DSDL_INSTALL_PREFIX=%SDL_INSTALL_PREFIX% -DLIBARCHIVE_INSTALL_PREFIX=%LIBARCHIVE_INSTALL_PREFIX% -DUSE_LIBAV=1 -DFFMPEG_INSTALL_PREFIX=%FFMPEG_INSTALL_PREFIX% -G"Visual Studio 16" -T"v142" ..
cmake -DQT=5 -DPUBLIC_RELEASE=%PUBLIC_RELEASE% -DSDL_INSTALL_PREFIX=%SDL_INSTALL_PREFIX% -DLIBARCHIVE_INSTALL_PREFIX=%LIBARCHIVE_INSTALL_PREFIX% -DUSE_LIBAV=1 -DFFMPEG_INSTALL_PREFIX=%FFMPEG_INSTALL_PREFIX% -G"Visual Studio 16" -T"v142" ..
REM nmake
msbuild /m fceux.sln /p:Configuration=Release

View File

@ -18,4 +18,4 @@ You should get releases from here: https://sourceforge.net/projects/fceultra/fil
That's because github forces us to use tags we don't have for releases.
2.6.5 is the most recent release but most people are using the autobuilds.
2.6.6 is the most recent release but most people are using the autobuilds.

25
scripts/linux_debug.pl Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/perl
use strict;
my $i; my $findResult;
my $exe = "fceux";
$findResult = `find . -name fceux`;
if ( $findResult ne "")
{
$findResult =~ s/\n.*//;
$exe=$findResult;
}
print "Executable: $exe\n";
my $gdbCmdFile = "/tmp/gdbCmdFile";
open CMD_FILE, ">$gdbCmdFile" or die "Error: Could not open file: $gdbCmdFile\n";
print CMD_FILE "run\n";
print CMD_FILE "list\n";
print CMD_FILE "backtrace\n";
close(CMD_FILE);
system("gdb -x $gdbCmdFile $exe");

16
scripts/runCppCheck.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/bash
PROJECT_ROOT=$( cd "$(dirname ${BASH_SOURCE[0]})"/.. && pwd )
echo $PROJECT_ROOT;
SRC_DIR=$PROJECT_ROOT/src
cd $SRC_DIR;
cppcheck --version
IGNORE_DIRS=" -i ./attic "
IGNORE_DIRS+="-i ./drivers/sdl "
#IGNORE_DIRS+="-i ./drivers/win "
cppcheck --force $IGNORE_DIRS .

View File

@ -10,34 +10,113 @@ if (${PUBLIC_RELEASE})
endif()
if ( ${QT6} )
message( STATUS "GUI Frontend: Qt6")
set( Qt Qt6 )
else()
message( STATUS "GUI Frontend: Qt5")
set( Qt Qt5 )
set( QT 6 )
endif()
if ( ${QHELP} )
set(QtHelpModule Help)
add_definitions( -D_USE_QHELP )
if (NOT DEFINED QT)
message( STATUS "Attempting to determine Qt Version...")
find_package( Qt6 COMPONENTS Core QUIET)
if (${Qt6Core_FOUND})
message( STATUS "Found Qt Version: ${Qt6Core_VERSION}")
set( QT 6 )
else()
find_package( Qt5 COMPONENTS Core QUIET)
if (${Qt5Core_FOUND})
message( STATUS "Found Qt Version: ${Qt5Core_VERSION}")
set( QT 5 )
endif()
endif()
endif()
if ( ${FCEU_PROFILER_ENABLE} )
message( STATUS "FCEU Profiler Enabled")
add_definitions( -D__FCEU_PROFILER_ENABLE__ )
endif()
if ( ${QT6} )
find_package( Qt6 REQUIRED COMPONENTS Widgets OpenGL OpenGLWidgets ${QtHelpModule})
add_definitions( ${Qt6Widgets_DEFINITIONS} ${Qt6Help_DEFINITIONS} ${Qt6OpenGLWidgets_DEFINITIONS} )
include_directories( ${Qt6Widgets_INCLUDE_DIRS} ${Qt6Help_INCLUDE_DIRS} ${Qt6OpenGLWidgets_INCLUDE_DIRS} )
if ( ${QT} EQUAL 6 )
message( STATUS "GUI Frontend: Qt6")
set( Qt Qt6 )
find_package( Qt6 REQUIRED COMPONENTS Widgets OpenGL OpenGLWidgets)
find_package( Qt6 REQUIRED COMPONENTS Network)
find_package( Qt6 COMPONENTS Help QUIET)
find_package( Qt6 COMPONENTS Qml)
find_package( Qt6 COMPONENTS UiTools)
add_definitions( ${Qt6Widgets_DEFINITIONS} ${Qt6Qml_DEFINITIONS} ${Qt6Network_DEFINITIONS} ${Qt6Help_DEFINITIONS} ${Qt6OpenGLWidgets_DEFINITIONS} )
# add_definitions(${Qt6UiTools_DEFINITIONS}) # Leave ${Qt6UiTools_DEFINITIONS} out as this is causing a build error
include_directories( ${Qt6Widgets_INCLUDE_DIRS} ${Qt6Qml_INCLUDE_DIRS} ${Qt6UiTools_INCLUDE_DIRS} ${Qt6Network_INCLUDE_DIRS} ${Qt6Help_INCLUDE_DIRS} ${Qt6OpenGLWidgets_INCLUDE_DIRS} )
if (${Qt6Help_FOUND})
message( STATUS "Qt6 Help Module Found")
if (${QHELP})
add_definitions( -D_USE_QHELP )
endif()
else()
message( STATUS "Qt6 Help Module Not Found")
endif()
if (${Qt6Network_FOUND})
message( STATUS "Qt6 Network Module Found")
add_definitions( -D__FCEU_QNETWORK_ENABLE__ )
else()
message( STATUS "Qt6 Network Module Not Found")
endif()
if (${Qt6Qml_FOUND})
message( STATUS "Qt6 Qml Module Found")
add_definitions( -D__FCEU_QSCRIPT_ENABLE__ )
else()
message( STATUS "Qt6 Qml Module Not Found")
endif()
if (${Qt6UiTools_FOUND})
message( STATUS "Qt6 UiTools Module Found")
add_definitions( -D__QT_UI_TOOLS__ )
else()
message( STATUS "Qt6 UiTools Module Not Found")
endif()
else()
find_package( Qt5 REQUIRED COMPONENTS Widgets OpenGL ${QtHelpModule})
add_definitions( ${Qt5Widgets_DEFINITIONS} ${Qt5Help_DEFINITIONS} )
include_directories( ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Help_INCLUDE_DIRS} )
endif()
message( STATUS "GUI Frontend: Qt5")
set( Qt Qt5 )
find_package( Qt5 REQUIRED COMPONENTS Widgets OpenGL)
find_package( Qt5 COMPONENTS Help QUIET)
find_package( Qt5 COMPONENTS Network)
find_package( Qt5 COMPONENTS Qml)
find_package( Qt5 COMPONENTS UiTools)
add_definitions( ${Qt5Widgets_DEFINITIONS} ${Qt5Qml_DEFINITIONS} ${Qt5UiTools_DEFINITIONS} ${Qt5Network_DEFINITIONS} ${Qt5Help_DEFINITIONS} )
include_directories( ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Qml_INCLUDE_DIRS} ${Qt5UiTools_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Help_INCLUDE_DIRS} )
if (${Qt5Help_FOUND})
message( STATUS "Qt5 Help Module Found")
if (${QHELP})
add_definitions( -D_USE_QHELP )
endif()
else()
message( STATUS "Qt5 Help Module Not Found")
endif()
if (${Qt5Network_FOUND})
message( STATUS "Qt5 Network Module Found")
add_definitions( -D__FCEU_NETWORK_ENABLE__ )
else()
message( STATUS "Qt5 Network Module Not Found")
endif()
if (${Qt5Qml_FOUND})
message( STATUS "Qt5 Qml Module Found")
add_definitions( -D__FCEU_QSCRIPT_ENABLE__ )
else()
message( STATUS "Qt5 Qml Module Not Found")
endif()
if (${Qt5UiTools_FOUND})
message( STATUS "Qt5 UiTools Module Found")
add_definitions( -D__QT_UI_TOOLS__ )
else()
message( STATUS "Qt5 UiTools Module Not Found")
endif()
endif()
if(WIN32)
find_package(OpenGL REQUIRED)
@ -285,14 +364,6 @@ endif()
include_directories( ${CMAKE_SOURCE_DIR}/src )
include_directories( ${CMAKE_SOURCE_DIR}/src/drivers )
if(APPLE)
add_definitions( -DPSS_STYLE=1 )
else(APPLE)
if(UNIX)
add_definitions( -DPSS_STYLE=1 )
endif(UNIX)
endif(APPLE)
set(SRC_CORE
${CMAKE_CURRENT_SOURCE_DIR}/asm.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cart.cpp
@ -337,7 +408,6 @@ set(SRC_CORE
${CMAKE_CURRENT_SOURCE_DIR}/boards/120.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/121.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/12in1.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/151.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/156.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/158B.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/15.cpp
@ -375,7 +445,10 @@ set(SRC_CORE
${CMAKE_CURRENT_SOURCE_DIR}/boards/33.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/34.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/354.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/36.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/413.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/471.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/451.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/36.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/3d-block.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/40.cpp
${CMAKE_CURRENT_SOURCE_DIR}/boards/411120-c.cpp
@ -579,6 +652,7 @@ set(SRC_DRIVERS_SDL
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleSoundConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/StateRecorderConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/iNesHeaderEditor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/QtScriptManager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/SplashScreen.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TraceLogger.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/AboutWindow.cpp
@ -596,6 +670,7 @@ set(SRC_DRIVERS_SDL
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/sdl-joystick.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/sdl-throttle.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/unix-netplay.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/NetPlay.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/AviRecord.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/AviRiffViewer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/avi/avi-utils.cpp
@ -666,6 +741,9 @@ target_link_libraries( ${APP_NAME}
${ASAN_LDFLAGS} ${GPROF_LDFLAGS}
${${Qt}Widgets_LIBRARIES}
${${Qt}Help_LIBRARIES}
${${Qt}Qml_LIBRARIES}
${${Qt}UiTools_LIBRARIES}
${${Qt}Network_LIBRARIES}
${${Qt}OpenGL_LIBRARIES}
${${Qt}OpenGLWidgets_LIBRARIES}
${OPENGL_LDFLAGS}

View File

@ -3,6 +3,7 @@
#include "types.h"
#include "utils/xstring.h"
#include "utils/StringBuilder.h"
#include "debug.h"
#include "asm.h"
#include "x6502.h"
@ -256,8 +257,11 @@ int Assemble(unsigned char *output, int addr, char *str) {
///disassembles the opcodes in the buffer assuming the provided address. Uses GetMem() and 6502 current registers to query referenced values. returns a static string buffer.
char *Disassemble(int addr, uint8 *opcode) {
static char str[64]={0},chr[5]={0};
static char str[64]={0};
const char *chr;
char indReg;
uint16 tmp,tmp2;
StringBuilder sb(str);
//these may be replaced later with passed-in values to make a lighter-weight disassembly mode that may not query the referenced values
#define RX (X.X)
@ -286,7 +290,7 @@ char *Disassemble(int addr, uint8 *opcode) {
#ifdef BRK_3BYTE_HACK
case 0x00:
sprintf(str,"BRK %02X %02X", opcode[1], opcode[2]);
sb << "BRK " << sb_hex(opcode[1], 2) << ' ' << sb_hex(opcode[2], 2);
break;
#else
case 0x00: strcpy(str,"BRK"); break;
@ -323,207 +327,226 @@ char *Disassemble(int addr, uint8 *opcode) {
case 0xF8: strcpy(str,"SED"); break;
//(Indirect,X)
case 0x01: strcpy(chr,"ORA"); goto _indirectx;
case 0x21: strcpy(chr,"AND"); goto _indirectx;
case 0x41: strcpy(chr,"EOR"); goto _indirectx;
case 0x61: strcpy(chr,"ADC"); goto _indirectx;
case 0x81: strcpy(chr,"STA"); goto _indirectx;
case 0xA1: strcpy(chr,"LDA"); goto _indirectx;
case 0xC1: strcpy(chr,"CMP"); goto _indirectx;
case 0xE1: strcpy(chr,"SBC"); goto _indirectx;
case 0x01: chr = "ORA"; goto _indirectx;
case 0x21: chr = "AND"; goto _indirectx;
case 0x41: chr = "EOR"; goto _indirectx;
case 0x61: chr = "ADC"; goto _indirectx;
case 0x81: chr = "STA"; goto _indirectx;
case 0xA1: chr = "LDA"; goto _indirectx;
case 0xC1: chr = "CMP"; goto _indirectx;
case 0xE1: chr = "SBC"; goto _indirectx;
_indirectx:
indirectX(tmp);
sprintf(str,"%s ($%02X,X) @ $%04X = #$%02X", chr,opcode[1],tmp,GetMem(tmp));
sb << chr << " (" << sb_addr(opcode[1], 2) << ",X) @ " << sb_addr(tmp) << " = " << sb_lit(GetMem(tmp));
break;
//Zero Page
case 0x05: strcpy(chr,"ORA"); goto _zeropage;
case 0x06: strcpy(chr,"ASL"); goto _zeropage;
case 0x24: strcpy(chr,"BIT"); goto _zeropage;
case 0x25: strcpy(chr,"AND"); goto _zeropage;
case 0x26: strcpy(chr,"ROL"); goto _zeropage;
case 0x45: strcpy(chr,"EOR"); goto _zeropage;
case 0x46: strcpy(chr,"LSR"); goto _zeropage;
case 0x65: strcpy(chr,"ADC"); goto _zeropage;
case 0x66: strcpy(chr,"ROR"); goto _zeropage;
case 0x84: strcpy(chr,"STY"); goto _zeropage;
case 0x85: strcpy(chr,"STA"); goto _zeropage;
case 0x86: strcpy(chr,"STX"); goto _zeropage;
case 0xA4: strcpy(chr,"LDY"); goto _zeropage;
case 0xA5: strcpy(chr,"LDA"); goto _zeropage;
case 0xA6: strcpy(chr,"LDX"); goto _zeropage;
case 0xC4: strcpy(chr,"CPY"); goto _zeropage;
case 0xC5: strcpy(chr,"CMP"); goto _zeropage;
case 0xC6: strcpy(chr,"DEC"); goto _zeropage;
case 0xE4: strcpy(chr,"CPX"); goto _zeropage;
case 0xE5: strcpy(chr,"SBC"); goto _zeropage;
case 0xE6: strcpy(chr,"INC"); goto _zeropage;
case 0x05: chr = "ORA"; goto _zeropage;
case 0x06: chr = "ASL"; goto _zeropage;
case 0x24: chr = "BIT"; goto _zeropage;
case 0x25: chr = "AND"; goto _zeropage;
case 0x26: chr = "ROL"; goto _zeropage;
case 0x45: chr = "EOR"; goto _zeropage;
case 0x46: chr = "LSR"; goto _zeropage;
case 0x65: chr = "ADC"; goto _zeropage;
case 0x66: chr = "ROR"; goto _zeropage;
case 0x84: chr = "STY"; goto _zeropage;
case 0x85: chr = "STA"; goto _zeropage;
case 0x86: chr = "STX"; goto _zeropage;
case 0xA4: chr = "LDY"; goto _zeropage;
case 0xA5: chr = "LDA"; goto _zeropage;
case 0xA6: chr = "LDX"; goto _zeropage;
case 0xC4: chr = "CPY"; goto _zeropage;
case 0xC5: chr = "CMP"; goto _zeropage;
case 0xC6: chr = "DEC"; goto _zeropage;
case 0xE4: chr = "CPX"; goto _zeropage;
case 0xE5: chr = "SBC"; goto _zeropage;
case 0xE6: chr = "INC"; goto _zeropage;
_zeropage:
// ################################## Start of SP CODE ###########################
// Change width to %04X // don't!
sprintf(str,"%s $%02X = #$%02X", chr,opcode[1],GetMem(opcode[1]));
sb << chr << ' ' << sb_addr(opcode[1], 2) << " = " << sb_lit(GetMem(opcode[1]));
// ################################## End of SP CODE ###########################
break;
//#Immediate
case 0x09: strcpy(chr,"ORA"); goto _immediate;
case 0x29: strcpy(chr,"AND"); goto _immediate;
case 0x49: strcpy(chr,"EOR"); goto _immediate;
case 0x69: strcpy(chr,"ADC"); goto _immediate;
//case 0x89: strcpy(chr,"STA"); goto _immediate; //baka, no STA #imm!!
case 0xA0: strcpy(chr,"LDY"); goto _immediate;
case 0xA2: strcpy(chr,"LDX"); goto _immediate;
case 0xA9: strcpy(chr,"LDA"); goto _immediate;
case 0xC0: strcpy(chr,"CPY"); goto _immediate;
case 0xC9: strcpy(chr,"CMP"); goto _immediate;
case 0xE0: strcpy(chr,"CPX"); goto _immediate;
case 0xE9: strcpy(chr,"SBC"); goto _immediate;
case 0x09: chr = "ORA"; goto _immediate;
case 0x29: chr = "AND"; goto _immediate;
case 0x49: chr = "EOR"; goto _immediate;
case 0x69: chr = "ADC"; goto _immediate;
//case 0x89: chr = "STA"; goto _immediate; //baka, no STA #imm!!
case 0xA0: chr = "LDY"; goto _immediate;
case 0xA2: chr = "LDX"; goto _immediate;
case 0xA9: chr = "LDA"; goto _immediate;
case 0xC0: chr = "CPY"; goto _immediate;
case 0xC9: chr = "CMP"; goto _immediate;
case 0xE0: chr = "CPX"; goto _immediate;
case 0xE9: chr = "SBC"; goto _immediate;
_immediate:
sprintf(str,"%s #$%02X", chr,opcode[1]);
sb << chr << ' ' << sb_lit(opcode[1]);
break;
//Absolute
case 0x0D: strcpy(chr,"ORA"); goto _absolute;
case 0x0E: strcpy(chr,"ASL"); goto _absolute;
case 0x2C: strcpy(chr,"BIT"); goto _absolute;
case 0x2D: strcpy(chr,"AND"); goto _absolute;
case 0x2E: strcpy(chr,"ROL"); goto _absolute;
case 0x4D: strcpy(chr,"EOR"); goto _absolute;
case 0x4E: strcpy(chr,"LSR"); goto _absolute;
case 0x6D: strcpy(chr,"ADC"); goto _absolute;
case 0x6E: strcpy(chr,"ROR"); goto _absolute;
case 0x8C: strcpy(chr,"STY"); goto _absolute;
case 0x8D: strcpy(chr,"STA"); goto _absolute;
case 0x8E: strcpy(chr,"STX"); goto _absolute;
case 0xAC: strcpy(chr,"LDY"); goto _absolute;
case 0xAD: strcpy(chr,"LDA"); goto _absolute;
case 0xAE: strcpy(chr,"LDX"); goto _absolute;
case 0xCC: strcpy(chr,"CPY"); goto _absolute;
case 0xCD: strcpy(chr,"CMP"); goto _absolute;
case 0xCE: strcpy(chr,"DEC"); goto _absolute;
case 0xEC: strcpy(chr,"CPX"); goto _absolute;
case 0xED: strcpy(chr,"SBC"); goto _absolute;
case 0xEE: strcpy(chr,"INC"); goto _absolute;
case 0x0D: chr = "ORA"; goto _absolute;
case 0x0E: chr = "ASL"; goto _absolute;
case 0x2C: chr = "BIT"; goto _absolute;
case 0x2D: chr = "AND"; goto _absolute;
case 0x2E: chr = "ROL"; goto _absolute;
case 0x4D: chr = "EOR"; goto _absolute;
case 0x4E: chr = "LSR"; goto _absolute;
case 0x6D: chr = "ADC"; goto _absolute;
case 0x6E: chr = "ROR"; goto _absolute;
case 0x8C: chr = "STY"; goto _absolute;
case 0x8D: chr = "STA"; goto _absolute;
case 0x8E: chr = "STX"; goto _absolute;
case 0xAC: chr = "LDY"; goto _absolute;
case 0xAD: chr = "LDA"; goto _absolute;
case 0xAE: chr = "LDX"; goto _absolute;
case 0xCC: chr = "CPY"; goto _absolute;
case 0xCD: chr = "CMP"; goto _absolute;
case 0xCE: chr = "DEC"; goto _absolute;
case 0xEC: chr = "CPX"; goto _absolute;
case 0xED: chr = "SBC"; goto _absolute;
case 0xEE: chr = "INC"; goto _absolute;
_absolute:
absolute(tmp);
sprintf(str,"%s $%04X = #$%02X", chr,tmp,GetMem(tmp));
sb << chr << ' ' << sb_addr(tmp) << " = " << sb_lit(GetMem(tmp));
break;
//branches
case 0x10: strcpy(chr,"BPL"); goto _branch;
case 0x30: strcpy(chr,"BMI"); goto _branch;
case 0x50: strcpy(chr,"BVC"); goto _branch;
case 0x70: strcpy(chr,"BVS"); goto _branch;
case 0x90: strcpy(chr,"BCC"); goto _branch;
case 0xB0: strcpy(chr,"BCS"); goto _branch;
case 0xD0: strcpy(chr,"BNE"); goto _branch;
case 0xF0: strcpy(chr,"BEQ"); goto _branch;
case 0x10: chr = "BPL"; goto _branch;
case 0x30: chr = "BMI"; goto _branch;
case 0x50: chr = "BVC"; goto _branch;
case 0x70: chr = "BVS"; goto _branch;
case 0x90: chr = "BCC"; goto _branch;
case 0xB0: chr = "BCS"; goto _branch;
case 0xD0: chr = "BNE"; goto _branch;
case 0xF0: chr = "BEQ"; goto _branch;
_branch:
relative(tmp);
sprintf(str,"%s $%04X", chr,tmp);
sb << chr << ' ' << sb_addr(tmp);
break;
//(Indirect),Y
case 0x11: strcpy(chr,"ORA"); goto _indirecty;
case 0x31: strcpy(chr,"AND"); goto _indirecty;
case 0x51: strcpy(chr,"EOR"); goto _indirecty;
case 0x71: strcpy(chr,"ADC"); goto _indirecty;
case 0x91: strcpy(chr,"STA"); goto _indirecty;
case 0xB1: strcpy(chr,"LDA"); goto _indirecty;
case 0xD1: strcpy(chr,"CMP"); goto _indirecty;
case 0xF1: strcpy(chr,"SBC"); goto _indirecty;
case 0x11: chr = "ORA"; goto _indirecty;
case 0x31: chr = "AND"; goto _indirecty;
case 0x51: chr = "EOR"; goto _indirecty;
case 0x71: chr = "ADC"; goto _indirecty;
case 0x91: chr = "STA"; goto _indirecty;
case 0xB1: chr = "LDA"; goto _indirecty;
case 0xD1: chr = "CMP"; goto _indirecty;
case 0xF1: chr = "SBC"; goto _indirecty;
_indirecty:
indirectY(tmp);
sprintf(str,"%s ($%02X),Y @ $%04X = #$%02X", chr,opcode[1],tmp,GetMem(tmp));
sb << chr << " (" << sb_addr(opcode[1], 2) << "),Y @ " << sb_addr(tmp) << " = " << sb_lit(GetMem(tmp));
break;
//Zero Page,X
case 0x15: strcpy(chr,"ORA"); goto _zeropagex;
case 0x16: strcpy(chr,"ASL"); goto _zeropagex;
case 0x35: strcpy(chr,"AND"); goto _zeropagex;
case 0x36: strcpy(chr,"ROL"); goto _zeropagex;
case 0x55: strcpy(chr,"EOR"); goto _zeropagex;
case 0x56: strcpy(chr,"LSR"); goto _zeropagex;
case 0x75: strcpy(chr,"ADC"); goto _zeropagex;
case 0x76: strcpy(chr,"ROR"); goto _zeropagex;
case 0x94: strcpy(chr,"STY"); goto _zeropagex;
case 0x95: strcpy(chr,"STA"); goto _zeropagex;
case 0xB4: strcpy(chr,"LDY"); goto _zeropagex;
case 0xB5: strcpy(chr,"LDA"); goto _zeropagex;
case 0xD5: strcpy(chr,"CMP"); goto _zeropagex;
case 0xD6: strcpy(chr,"DEC"); goto _zeropagex;
case 0xF5: strcpy(chr,"SBC"); goto _zeropagex;
case 0xF6: strcpy(chr,"INC"); goto _zeropagex;
case 0x15: chr = "ORA"; goto _zeropagex;
case 0x16: chr = "ASL"; goto _zeropagex;
case 0x35: chr = "AND"; goto _zeropagex;
case 0x36: chr = "ROL"; goto _zeropagex;
case 0x55: chr = "EOR"; goto _zeropagex;
case 0x56: chr = "LSR"; goto _zeropagex;
case 0x75: chr = "ADC"; goto _zeropagex;
case 0x76: chr = "ROR"; goto _zeropagex;
case 0x94: chr = "STY"; goto _zeropagex;
case 0x95: chr = "STA"; goto _zeropagex;
case 0xB4: chr = "LDY"; goto _zeropagex;
case 0xB5: chr = "LDA"; goto _zeropagex;
case 0xD5: chr = "CMP"; goto _zeropagex;
case 0xD6: chr = "DEC"; goto _zeropagex;
case 0xF5: chr = "SBC"; goto _zeropagex;
case 0xF6: chr = "INC"; goto _zeropagex;
_zeropagex:
zpIndex(tmp,RX);
zpIndex(tmp, RX);
indReg = 'X';
_indexed:
// ################################## Start of SP CODE ###########################
// Change width to %04X // don't!
sprintf(str,"%s $%02X,X @ $%04X = #$%02X", chr,opcode[1],tmp,GetMem(tmp));
sb << chr << ' ' << sb_addr(opcode[1], 2) << ',' << indReg << " @ " << sb_addr(tmp) << " = " << sb_lit(GetMem(tmp));
// ################################## End of SP CODE ###########################
break;
//Absolute,Y
case 0x19: strcpy(chr,"ORA"); goto _absolutey;
case 0x39: strcpy(chr,"AND"); goto _absolutey;
case 0x59: strcpy(chr,"EOR"); goto _absolutey;
case 0x79: strcpy(chr,"ADC"); goto _absolutey;
case 0x99: strcpy(chr,"STA"); goto _absolutey;
case 0xB9: strcpy(chr,"LDA"); goto _absolutey;
case 0xBE: strcpy(chr,"LDX"); goto _absolutey;
case 0xD9: strcpy(chr,"CMP"); goto _absolutey;
case 0xF9: strcpy(chr,"SBC"); goto _absolutey;
case 0x19: chr = "ORA"; goto _absolutey;
case 0x39: chr = "AND"; goto _absolutey;
case 0x59: chr = "EOR"; goto _absolutey;
case 0x79: chr = "ADC"; goto _absolutey;
case 0x99: chr = "STA"; goto _absolutey;
case 0xB9: chr = "LDA"; goto _absolutey;
case 0xBE: chr = "LDX"; goto _absolutey;
case 0xD9: chr = "CMP"; goto _absolutey;
case 0xF9: chr = "SBC"; goto _absolutey;
_absolutey:
absolute(tmp);
tmp2=(tmp+RY);
sprintf(str,"%s $%04X,Y @ $%04X = #$%02X", chr,tmp,tmp2,GetMem(tmp2));
tmp2 = (tmp + RY);
indReg = 'Y';
_absindexed:
sb << chr << ' ' << sb_addr(tmp) << ',' << indReg << " @ " << sb_addr(tmp2) << " = " << sb_lit(GetMem(tmp2));
break;
//Absolute,X
case 0x1D: strcpy(chr,"ORA"); goto _absolutex;
case 0x1E: strcpy(chr,"ASL"); goto _absolutex;
case 0x3D: strcpy(chr,"AND"); goto _absolutex;
case 0x3E: strcpy(chr,"ROL"); goto _absolutex;
case 0x5D: strcpy(chr,"EOR"); goto _absolutex;
case 0x5E: strcpy(chr,"LSR"); goto _absolutex;
case 0x7D: strcpy(chr,"ADC"); goto _absolutex;
case 0x7E: strcpy(chr,"ROR"); goto _absolutex;
case 0x9D: strcpy(chr,"STA"); goto _absolutex;
case 0xBC: strcpy(chr,"LDY"); goto _absolutex;
case 0xBD: strcpy(chr,"LDA"); goto _absolutex;
case 0xDD: strcpy(chr,"CMP"); goto _absolutex;
case 0xDE: strcpy(chr,"DEC"); goto _absolutex;
case 0xFD: strcpy(chr,"SBC"); goto _absolutex;
case 0xFE: strcpy(chr,"INC"); goto _absolutex;
case 0x1D: chr = "ORA"; goto _absolutex;
case 0x1E: chr = "ASL"; goto _absolutex;
case 0x3D: chr = "AND"; goto _absolutex;
case 0x3E: chr = "ROL"; goto _absolutex;
case 0x5D: chr = "EOR"; goto _absolutex;
case 0x5E: chr = "LSR"; goto _absolutex;
case 0x7D: chr = "ADC"; goto _absolutex;
case 0x7E: chr = "ROR"; goto _absolutex;
case 0x9D: chr = "STA"; goto _absolutex;
case 0xBC: chr = "LDY"; goto _absolutex;
case 0xBD: chr = "LDA"; goto _absolutex;
case 0xDD: chr = "CMP"; goto _absolutex;
case 0xDE: chr = "DEC"; goto _absolutex;
case 0xFD: chr = "SBC"; goto _absolutex;
case 0xFE: chr = "INC"; goto _absolutex;
_absolutex:
absolute(tmp);
tmp2=(tmp+RX);
sprintf(str,"%s $%04X,X @ $%04X = #$%02X", chr,tmp,tmp2,GetMem(tmp2));
break;
tmp2 = (tmp + RX);
indReg = 'X';
goto _absindexed;
//jumps
case 0x20: strcpy(chr,"JSR"); goto _jump;
case 0x4C: strcpy(chr,"JMP"); goto _jump;
case 0x6C: absolute(tmp); sprintf(str,"JMP ($%04X) = $%04X", tmp,GetMem(tmp)|GetMem(tmp+1)<<8); break;
case 0x20: chr = "JSR"; goto _jump;
case 0x4C: chr = "JMP"; goto _jump;
_jump:
absolute(tmp);
sprintf(str,"%s $%04X", chr,tmp);
sb << chr << ' ' << sb_addr(tmp);
break;
case 0x6C:
absolute(tmp);
sb << "JMP (" << sb_addr(tmp);
sb << ") = " << sb_addr(GetMem(tmp) | GetMem(tmp + 1) << 8);
break;
//Zero Page,Y
case 0x96: strcpy(chr,"STX"); goto _zeropagey;
case 0xB6: strcpy(chr,"LDX"); goto _zeropagey;
case 0x96: chr = "STX"; goto _zeropagey;
case 0xB6: chr = "LDX"; goto _zeropagey;
_zeropagey:
zpIndex(tmp,RY);
// ################################## Start of SP CODE ###########################
// Change width to %04X // don't!
sprintf(str,"%s $%02X,Y @ $%04X = #$%02X", chr,opcode[1],tmp,GetMem(tmp));
// ################################## End of SP CODE ###########################
break;
zpIndex(tmp, RY);
indReg = 'Y';
goto _indexed;
//UNDEFINED
default: strcpy(str,"ERROR"); break;
default: strcpy(str, "ERROR"); break;
}
return str;
}

View File

@ -16,6 +16,9 @@
* 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
*
* The Moero!! Pro Yakyuu series have an ADPCM chip with internal ROM,
* used for voice samples (not dumped, so emulation isn't possible)
*/
#include "mapinc.h"

147
src/boards/413.cpp Normal file
View File

@ -0,0 +1,147 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2024
*
* 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
*/
#include "mapinc.h"
#include "../ines.h"
static uint8 reg[4];
static uint8 IRQCount;
static uint8 IRQReload;
static uint8 IRQa;
static uint8 serialControl;
static uint32 serialAddress;
static SFORMAT StateRegs[] = {
{ reg, 4, "REGS" },
{ &IRQCount, 1, "IRQC" },
{ &IRQReload, 1, "IRQR" },
{ &IRQa, 1, "IRQA" },
{ &serialAddress, 4, "ADDR" },
{ &serialControl, 1, "CTRL" },
{ 0 }
};
static void Sync(void) {
setprg4(0x5000, 0x01);
setprg8(0x6000, reg[0]);
setprg8(0x8000, reg[1]);
setprg8(0xA000, reg[2]);
setprg4(0xD000, 0x07);
setprg8(0xE000, 0x04);
setchr4(0x0000, reg[3]);
setchr4(0x1000, ~0x02);
}
static uint64 lreset;
static uint32 laddr;
static DECLFR(M413ReadPCM) {
uint8 ret = X.DB;
if ((A == laddr) && ((timestampbase + timestamp) < (lreset + 4))) {
return ret;
}
if (serialControl & 0x02) {
ret = MiscROM[serialAddress++ & (MiscROM_size - 1)];
} else {
ret = MiscROM[serialAddress & (MiscROM_size - 1)];
}
laddr = A;
lreset = timestampbase + timestamp;
return ret;
}
static DECLFW(M413Write) {
switch (A & 0xF000) {
case 0x8000:
IRQReload = V;
break;
case 0x9000:
IRQCount = 0;
break;
case 0xA000:
case 0xB000:
IRQa = (A & 0x1000) != 0;
if (!IRQa) {
X6502_IRQEnd(FCEU_IQEXT);
}
break;
case 0xC000:
serialAddress = (serialAddress << 1) | (V >> 7);
break;
case 0xD000:
serialControl = V;
break;
case 0xE000:
case 0xF000:
reg[V >> 6] = V & 0x3F;
Sync();
break;
}
}
static void M413Power(void) {
serialAddress = 0;
serialControl = 0;
IRQCount = 0;
IRQReload = 0;
IRQa = 0;
reg[0] = 0;
reg[1] = 0;
reg[2] = 0;
reg[3] = 0;
laddr = 0;
lreset = 0;
Sync();
SetReadHandler(0x4800, 0x4FFF, M413ReadPCM);
SetReadHandler(0x5000, 0x7FFF, CartBR);
SetReadHandler(0x8000, 0xBFFF, CartBR);
SetReadHandler(0xC000, 0xCFFF, M413ReadPCM);
SetReadHandler(0xD000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M413Write);
}
static void M413IRQHook(void) {
if (IRQCount == 0) {
IRQCount = IRQReload;
} else {
IRQCount--;
}
if ((IRQCount == 0) && IRQa) {
X6502_IRQBegin(FCEU_IQEXT);
}
}
static void StateRestore(int version) {
Sync();
}
void Mapper413_Init(CartInfo *info) {
info->Power = M413Power;
GameHBIRQHook = M413IRQHook;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

216
src/boards/451.cpp Normal file
View File

@ -0,0 +1,216 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2024 negativeExponent
*
* 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
*/
/* NES 2.0 Mapper 451 is used for the homebrew game Haratyler HP/MP. It is
* basically a homebrew TLROM-like circuit board that implements the MMC3
* register's in an unusual fashion, and saves the high score to flash ROM */
#include "mapinc.h"
#include "mmc3.h"
#include "../ines.h"
const int ROM_CHIP = 0x00;
const int CFI_CHIP = 0x10;
const int FLASH_CHIP = 0x11;
const int FLASH_SECTOR_SIZE = 64 * 1024;
const int magic_addr1 = 0x0555;
const int magic_addr2 = 0x02AA;
static uint8 flash_state, flash_id_mode;
static uint8 *flash_data;
static uint16 flash_buffer_a[10];
static uint8 flash_buffer_v[10];
static uint8 flash_id[2];
static DECLFW(M451FlashWrite)
{
if (flash_state < sizeof(flash_buffer_a) / sizeof(flash_buffer_a[0])) {
flash_buffer_a[flash_state] = (A & 0xFFF);
flash_buffer_v[flash_state] = V;
flash_state++;
// enter flash ID mode
if ((flash_state == 2) &&
(flash_buffer_a[0] == magic_addr1) && (flash_buffer_v[0] == 0xAA) &&
(flash_buffer_a[1] == magic_addr2) && (flash_buffer_v[1] == 0x55) &&
(flash_buffer_a[1] == magic_addr1) && (flash_buffer_v[1] == 0x90)) {
flash_id_mode = 0;
flash_state = 0;
}
// erase sector
if ((flash_state == 6) &&
(flash_buffer_a[0] == magic_addr1) && (flash_buffer_v[0] == 0xAA) &&
(flash_buffer_a[1] == magic_addr2) && (flash_buffer_v[1] == 0x55) &&
(flash_buffer_a[2] == magic_addr1) && (flash_buffer_v[2] == 0x80) &&
(flash_buffer_a[3] == magic_addr1) && (flash_buffer_v[3] == 0xAA) &&
(flash_buffer_a[4] == magic_addr2) && (flash_buffer_v[4] == 0x55) &&
(flash_buffer_v[5] == 0x30)) {
int offset = &Page[A >> 11][A] - flash_data;
int sector = offset / FLASH_SECTOR_SIZE;
for (int i = sector * FLASH_SECTOR_SIZE; i < (sector + 1) * FLASH_SECTOR_SIZE; i++)
flash_data[i % PRGsize[ROM_CHIP]] = 0xFF;
FCEU_printf("Flash sector #%d is erased (0x%08x - 0x%08x).\n", sector, offset, offset + FLASH_SECTOR_SIZE);
}
// erase chip
if ((flash_state == 6) &&
(flash_buffer_a[0] == magic_addr1) && (flash_buffer_v[0] == 0xAA) &&
(flash_buffer_a[1] == magic_addr2) && (flash_buffer_v[1] == 0x55) &&
(flash_buffer_a[2] == magic_addr1) && (flash_buffer_v[2] == 0x80) &&
(flash_buffer_a[3] == magic_addr1) && (flash_buffer_v[3] == 0xAA) &&
(flash_buffer_a[4] == magic_addr2) && (flash_buffer_v[4] == 0x55) &&
(flash_buffer_a[4] == magic_addr1) && (flash_buffer_v[4] == 0x10)) {
memset(flash_data, 0xFF, PRGsize[ROM_CHIP]);
FCEU_printf("Flash chip erased.\n");
flash_state = 0;
}
// write byte
if ((flash_state == 4) &&
(flash_buffer_a[0] == magic_addr1) && (flash_buffer_v[0] == 0xAA) &&
(flash_buffer_a[1] == magic_addr2) && (flash_buffer_v[1] == 0x55) &&
(flash_buffer_a[2] == magic_addr1) && (flash_buffer_v[2] == 0xA0)) {
int offset = &Page[A >> 11][A] - flash_data;
if (CartBR(A) != 0xFF) {
FCEU_PrintError("Error: can't write to 0x%08x, flash sector is not erased.\n", offset);
}
else {
CartBW(A, V);
}
flash_state = 0;
}
}
// not a command
if (((A & 0x00FF) != (magic_addr1 & 0x00FF)) && ((A & 0x00FF) != (magic_addr2 & 0x00FF))) {
flash_state = 0;
}
// reset
if (V == 0xF0) {
flash_state = 0;
flash_id_mode = 0;
}
FixMMC3PRG(MMC3_cmd);
}
static void M451FixPRG(uint32 A, uint8 V) {
setprg8r(FLASH_CHIP, 0x8000, 0);
setprg8r(FLASH_CHIP, 0xA000, 0x10 | ((EXPREGS[0] << 2) & 0x08) | (EXPREGS[0] & 0x01));
setprg8r(FLASH_CHIP, 0xC000, 0x20 | ((EXPREGS[0] << 2) & 0x08) | (EXPREGS[0] & 0x01));
setprg8r(FLASH_CHIP, 0xE000, 0x30);
}
static void M451FixCHR(uint32 A, uint8 V) {
setchr8(EXPREGS[0] & 0x01);
}
static DECLFR(M451Read) {
if (flash_state == 0x90) {
return flash_id[A & 1];
}
return CartBR(A);
}
static DECLFW(M451Write) {
M451FlashWrite(A, V);
switch (A & 0xE000) {
case 0xA000:
MMC3_CMDWrite(0xA000, A & 0x01);
break;
case 0xC000:
A &= 0xFF;
MMC3_IRQWrite(0xC000, A - 1);
MMC3_IRQWrite(0xC001, 0);
MMC3_IRQWrite(0xE000 + ((A == 0xFF) ? 0x00 : 0x01), 0x00);
break;
case 0xE000:
EXPREGS[0] = A & 0x03;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
break;
}
}
static void M451Power(void) {
GenMMC3Power();
SetReadHandler(0x8000, 0xFFFF, M451Read);
SetWriteHandler(0x8000, 0xFFFF, M451Write);
}
static void StateRestore(int version) {
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
static void M451Close(void) {
if(flash_data)
FCEU_gfree(flash_data);
flash_data = NULL;
}
static void M451FlashReset(void)
{
if (flash_data)
{
size_t flash_size = PRGsize[ROM_CHIP];
// Copy ROM to flash data
for (size_t i = 0; i < flash_size; i++) {
flash_data[i] = PRGptr[ROM_CHIP][i];
}
}
}
void Mapper451_Init(CartInfo *info) {
GenMMC3_Init(info, 512, 16, 0, 0);
pwrap = M451FixPRG;
cwrap = M451FixCHR;
info->Power = M451Power;
info->Close = M451Close;
GameStateRestore = StateRestore;
flash_state = 0;
flash_id_mode = 0;
info->battery = 1;
// Allocate memory for flash
size_t flash_size = PRGsize[ROM_CHIP];
flash_data = (uint8*)FCEU_gmalloc(flash_size);
// Copy ROM to flash data
for (size_t i = 0; i < flash_size; i++) {
flash_data[i] = PRGptr[ROM_CHIP][i];
}
SetupCartPRGMapping(FLASH_CHIP, flash_data, flash_size, 1);
info->addSaveGameBuf( flash_data, flash_size, M451FlashReset );
flash_id[0] = 0x37;
flash_id[1] = 0x86;
SetupCartPRGMapping(CFI_CHIP, flash_id, sizeof(flash_id), 0);
AddExState(flash_data, flash_size, 0, "FLSH");
AddExState(&flash_state, sizeof(flash_state), 0, "FLST");
AddExState(&flash_id_mode, sizeof(flash_id_mode), 0, "FLMD");
AddExState(flash_buffer_a, sizeof(flash_buffer_a), 0, "FLBA");
AddExState(flash_buffer_v, sizeof(flash_buffer_v), 0, "FLBV");
}

View File

@ -1,59 +1,65 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2012 CaH4e3
*
* 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
*/
#include "mapinc.h"
static uint8 regs[8];
static SFORMAT StateRegs[] =
{
{ regs, 8, "REGS" },
{ 0 }
};
static void Sync(void) {
setprg8(0x8000, regs[0]);
setprg8(0xA000, regs[2]);
setprg8(0xC000, regs[4]);
setprg8(0xE000, ~0);
setchr4(0x0000, regs[6]);
setchr4(0x1000, regs[7]);
}
static DECLFW(M151Write) {
regs[(A >> 12) & 7] = V;
Sync();
}
static void M151Power(void) {
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M151Write);
}
static void StateRestore(int version) {
Sync();
}
void Mapper151_Init(CartInfo *info) {
info->Power = M151Power;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2024 negativeExponent
*
* 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
*/
/* NES 2.0 Mapper 471 denotes the Impact Soft IM1 circuit board, used for
* Haratyler (without HG or MP) and Haraforce. It is basically INES Mapper 201
* with the addition of a scanline IRQ.*/
#include "mapinc.h"
static uint32 latch;
static void Sync() {
setprg32(0x8000, latch);
setchr8(latch);
}
static DECLFW(Write) {
X6502_IRQEnd(FCEU_IQEXT);
latch = A;
Sync();
}
static void Reset() {
latch = 0;
Sync();
}
static void Power() {
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, Write);
Reset();
}
static void StateRestore(int version) {
Sync();
}
static void HBHook() {
X6502_IRQBegin(FCEU_IQEXT);
}
void Mapper471_Init(CartInfo *info) {
info->Power = Power;
info->Reset = Reset;
GameHBIRQHook = HBHook;
GameStateRestore = StateRestore;
AddExState(&latch, sizeof(latch), 0, "LATC");
}

View File

@ -17,13 +17,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Moero!! Pro Tennis have ADPCM codec on-board, PROM isn't dumped, emulation isn't
* possible just now.
* Moero!! Pro Tennis and Moero!! Pro Yakyuu '88 Ketteiban have an ADPCM chip with
* internal ROM, used for voice samples (not dumped, so emulation isn't possible)
*/
#include "mapinc.h"
static uint8 preg, creg;
static void (*Sync)(void);
static SFORMAT StateRegs[] =
{
@ -32,13 +33,19 @@ static SFORMAT StateRegs[] =
{ 0 }
};
static void Sync(void) {
static void M72Sync(void) {
setprg16(0x8000, preg);
setprg16(0xC000, ~0);
setchr8(creg);
}
static DECLFW(M72Write) {
static void M92Sync(void) {
setprg16(0x8000, 0);
setprg16(0xC000, preg);
setchr8(creg);
}
static DECLFW(Write) {
if (V & 0x80)
preg = V & 0xF;
if (V & 0x40)
@ -46,10 +53,10 @@ static DECLFW(M72Write) {
Sync();
}
static void M72Power(void) {
static void Power(void) {
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0xFFFF, M72Write);
SetWriteHandler(0x8000, 0xFFFF, Write);
}
static void StateRestore(int version) {
@ -57,7 +64,16 @@ static void StateRestore(int version) {
}
void Mapper72_Init(CartInfo *info) {
info->Power = M72Power;
Sync = M72Sync;
info->Power = Power;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}
void Mapper92_Init(CartInfo *info) {
Sync = M92Sync;
info->Power = Power;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);

View File

@ -181,6 +181,7 @@ void Mapper59_Init(CartInfo *info) {
}
//------------------ Map 061 ---------------------------
static void M61Sync(void) {
if (((latche & 0x10) << 1) ^ (latche & 0x20)) {
setprg16(0x8000, ((latche & 0xF) << 1) | (((latche & 0x20) >> 4)));
@ -195,32 +196,6 @@ void Mapper61_Init(CartInfo *info) {
Latch_Init(info, M61Sync, NULL, 0x0000, 0x8000, 0xFFFF, 0);
}
//------------------ Map 092 ---------------------------
// Another two-in-one mapper, two Jaleco carts uses similar
// hardware, but with different wiring.
// Original code provided by LULU
// Additionally, PCB contains DSP extra sound chip, used for voice samples (unemulated)
static void M92Sync(void) {
uint8 reg = latche & 0xF0;
setprg16(0x8000, 0);
if (latche >= 0x9000) {
switch (reg) {
case 0xD0: setprg16(0xc000, latche & 15); break;
case 0xE0: setchr8(latche & 15); break;
}
} else {
switch (reg) {
case 0xB0: setprg16(0xc000, latche & 15); break;
case 0x70: setchr8(latche & 15); break;
}
}
}
void Mapper92_Init(CartInfo *info) {
Latch_Init(info, M92Sync, NULL, 0x80B0, 0x8000, 0xFFFF, 0);
}
//------------------ Map 174 ---------------------------
static void M174Sync(void) {

View File

@ -178,9 +178,12 @@ static void x24c02_write(uint8 data) {
x24c02_addr <<= 1;
x24c02_addr |= sda;
} else {
if (sda) // READ COMMAND
if ((x24c02_addr & 0x78) != 0x50) { // WRONG DEVICE ADDRESS
x24c02_out = 1;
x24c02_state = X24C0X_STANDBY;
} else if (sda) // READ COMMAND
x24c02_state = X24C0X_READ;
else // WRITE COMMAND
else // WRITE COMMAND
x24c02_state = X24C0X_WORD;
}
x24c02_bitcount++;

View File

@ -227,7 +227,7 @@ static uint8 flash_buffer_v[10];
static uint8 cfi_mode = 0;
// Micron 4-gbit memory CFI data
const uint8 cfi_data[] =
static const uint8 cfi_data[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x51, 0x52, 0x59, 0x02, 0x00, 0x40, 0x00, 0x00,
@ -247,7 +247,7 @@ const uint8 cfi_data[] =
#define SET_BITS(target, target_bits, source, source_bits) target = set_bits(target, target_bits, get_bits(source, source_bits))
static inline uint8 string_to_bits(char* bitsstr, int* bits)
static inline uint8 string_to_bits(const char* bitsstr, int* bits)
{
uint8 bit1, bit2, count = 0;
for (int i = 0; i < 32; i++)
@ -298,7 +298,7 @@ static inline uint8 string_to_bits(char* bitsstr, int* bits)
return count;
}
static inline uint32 get_bits(uint32 V, char* bitsstr)
static inline uint32 get_bits(const uint32 V, const char* bitsstr)
{
uint32 result = 0;
int bits[32];
@ -311,7 +311,7 @@ static inline uint32 get_bits(uint32 V, char* bitsstr)
return result;
}
static inline uint32 set_bits(uint32 V, char* bitsstr, uint32 new_bits)
static inline uint32 set_bits(uint32 V, const char* bitsstr, const uint32 new_bits)
{
int bits[32];
uint8 count = string_to_bits(bitsstr, bits);

View File

@ -309,7 +309,8 @@ void Mapper78_Init(CartInfo *info) {
}
//------------------ Map 86 ---------------------------
// Moero!! Pro Yakyuu has an ADPCM chip with internal ROM,
// used for voice samples (not dumped, so emulation isn't possible)
static void M86Sync(void) {
setprg32(0x8000, (latche >> 4) & 3);
setchr8((latche & 3) | ((latche >> 4) & 4));
@ -370,31 +371,14 @@ void Mapper94_Init(CartInfo *info) {
//------------------ Map 97 ---------------------------
static void M97Sync(void) {
setchr8(0);
setprg16(0x8000, ~0);
setprg16(0xc000, latche & 15);
switch (latche >> 6) {
case 0: break;
case 1: setmirror(MI_H); break;
case 2: setmirror(MI_V); break;
case 3: break;
}
setchr8(((latche >> 1) & 1) | ((latche << 1) & 2));
setmirror((latche >> 7) & 1);
setchr8(0);
}
void Mapper97_Init(CartInfo *info) {
Latch_Init(info, M97Sync, ~0, 0x8000, 0xFFFF, 0, 0);
}
//------------------ Map 101 ---------------------------
static void M101Sync(void) {
setprg32(0x8000, 0);
setchr8(latche);
}
void Mapper101_Init(CartInfo *info) {
Latch_Init(info, M101Sync, ~0, 0x6000, 0x7FFF, 0, 0);
Latch_Init(info, M97Sync, ~0, 0x8000, 0xBFFF, 0, 0);
}
//------------------ Map 107 ---------------------------

View File

@ -363,8 +363,10 @@ static void M4Power(void) {
void Mapper4_Init(CartInfo *info) {
int ws = 8;
if ((info->CRC32 == 0x93991433 || info->CRC32 == 0xaf65aa84)) {
FCEU_printf("Low-G-Man can not work normally in the iNES format.\nThis game has been recognized by its CRC32 value, and the appropriate changes will be made so it will run.\nIf you wish to hack this game, you should use the UNIF format for your hack.\n\n");
if (info->ines2) {
ws = (info->wram_size + info->battery_wram_size) / 1024;
} else if ((info->CRC32 == 0x93991433 || info->CRC32 == 0xaf65aa84)) {
FCEU_printf("Low-G-Man can not work normally in the iNES format.\nThis game has been recognized by its CRC32 value, and the appropriate changes will be made so it will run.\nIf you wish to hack this game, you should use the NES 2.0 format for your hack.\n\n");
ws = 0;
}
GenMMC3_Init(info, 512, 256, ws, info->battery);
@ -498,38 +500,38 @@ void Mapper44_Init(CartInfo *info) {
// ---------------------------- Mapper 45 -------------------------------
static void M45CW(uint32 A, uint8 V) {
if (!UNIFchrrama) {
uint32 NV = V;
if (EXPREGS[2] & 8)
NV &= (1 << ((EXPREGS[2] & 7) + 1)) - 1;
else
if (EXPREGS[2])
NV &= 0; // hack ;( don't know exactly how it should be
NV |= EXPREGS[0] | ((EXPREGS[2] & 0xF0) << 4);
setchr1(A, NV);
} else
// setchr8(0); // i don't know what cart need this, but a new one need other lol
setchr1(A, V);
uint32 NV = V;
const int mask = ((EXPREGS[2] & 0x0F) > 7)
? ((1 << (EXPREGS[2] & 0x0F) << 3) - 1)
: 0;
NV |= (EXPREGS[0] & mask) | ((EXPREGS[2] & 0xF0) << 4);
setchr1(A, NV);
}
static void M45PW(uint32 A, uint8 V) {
uint32 MV = V & ((EXPREGS[3] & 0x3F) ^ 0x3F);
MV |= EXPREGS[1];
if(UNIFchrrama)
MV |= ((EXPREGS[2] & 0x40) << 2);
uint32 MV = V;
const int mask = (EXPREGS[3] & 0x3F) ^ 0x3F;
MV |= (EXPREGS[1] & 0x3F & mask) | (EXPREGS[1] & 0xC0);
setprg8(A, MV);
// FCEU_printf("1:%02x 2:%02x 3:%02x A=%04x V=%03x\n",EXPREGS[1],EXPREGS[2],EXPREGS[3],A,MV);
}
static DECLFW(M45Write) {
if (EXPREGS[3] & 0x40) {
WRAM[A - 0x6000] = V;
return;
WRAM[A - 0x6000] = V;
if (!(A & 1))
{
if (EXPREGS[3] & 0x40) {
WRAM[A - 0x6000] = V;
return;
}
EXPREGS[EXPREGS[4]] = V;
EXPREGS[4] = (EXPREGS[4] + 1) & 3;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
else {
// lock reset
EXPREGS[3] &= ~0x40;
}
EXPREGS[EXPREGS[4]] = V;
EXPREGS[4] = (EXPREGS[4] + 1) & 3;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
static DECLFR(M45Read) {
@ -550,7 +552,7 @@ static void M45Reset(void) {
static void M45Power(void) {
GenMMC3Power();
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = EXPREGS[4] = EXPREGS[5] = 0;
SetWriteHandler(0x5000, 0x7FFF, M45Write);
SetWriteHandler(0x6000, 0x7FFF, M45Write);
SetReadHandler(0x5000, 0x5FFF, M45Read);
}
@ -860,32 +862,52 @@ void Mapper119_Init(CartInfo *info) {
// ---------------------------- Mapper 134 ------------------------------
static void M134PW(uint32 A, uint8 V) {
setprg8(A, (V & 0x1F) | ((EXPREGS[0] & 2) << 4));
if ((EXPREGS[1] & 0x88) == 0x80)
setprg32(A, (EXPREGS[0] & 0x10) | ((EXPREGS[1] & 2) << 2)); // NROM-256
else if ((EXPREGS[1] & 0x88) == 0x88)
setprg16(0x8000 | (A & 0x4000), ((EXPREGS[0] & 0x10) << 1) | ((V & 0x10) >> 1) | ((EXPREGS[1] & 3) << 3)); // NROM-128
else if (EXPREGS[1] & 4)
setprg8(A, ((EXPREGS[0] & 0x10) << 2) | (V & 0x0F) | ((EXPREGS[1] & 3) << 4)); // MMC3 128KB mask
else
setprg8(A, ((EXPREGS[0] & 0x10) << 2) | (V & 0x1F) | ((EXPREGS[1] & 2) << 4)); // MMC3 256KB mask
}
static void M134CW(uint32 A, uint8 V) {
setchr1(A, (V & 0xFF) | ((EXPREGS[0] & 0x20) << 3));
// CNROM mode. Unclear. Untested.
if (EXPREGS[0] & 0x08)
setchr8(EXPREGS[2]);
else if (EXPREGS[1] & 0x40)
setchr1(A, ((EXPREGS[0] & 0x20) << 4) | (V & 0x7F) | ((EXPREGS[1] & 0x30) << 3)); // 128KB mask
else
setchr1(A, ((EXPREGS[0] & 0x20) << 4) | (V & 0xFF) | ((EXPREGS[1] & 0x20) << 3)); // 256KB mask
}
static DECLFW(M134Write) {
EXPREGS[0] = V;
if (EXPREGS[0] & 0x80)
{
// locked (except $6002.0-1)
if ((A & 3) == 2)
EXPREGS[2] = (EXPREGS[2] & 0xFC) | (V & 3);
return;
}
EXPREGS[A & 3] = V;
FixMMC3CHR(MMC3_cmd);
FixMMC3PRG(MMC3_cmd);
}
static void M134Power(void) {
EXPREGS[0] = 0;
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
GenMMC3Power();
SetWriteHandler(0x6001, 0x6001, M134Write);
SetWriteHandler(0x6000, 0x7FFF, M134Write);
}
static void M134Reset(void) {
EXPREGS[0] = 0;
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
MMC3RegReset();
}
void Mapper134_Init(CartInfo *info) {
GenMMC3_Init(info, 256, 256, 0, 0);
GenMMC3_Init(info, 512, 512, 0, 0);
pwrap = M134PW;
cwrap = M134CW;
info->Power = M134Power;

View File

@ -903,14 +903,14 @@ static void GenMMC5Power(void) {
PRGBanks.fill(0xFF);
WRAMPage = 0;
CHRBanksA.fill(0xFF);
CHRBanksB.fill(0xFF);
CHRBanksA.fill(0);
CHRBanksB.fill(0);
WRAMMaskEnable.fill(0xFF);
mmc5ABMode = 0;
IRQScanline = 0;
IRQEnable = 0;
CHRMode = 0;
NTAMirroring = NTFill = ATFill = 0xFF;
NTAMirroring = NTFill = ATFill = 0;
MMC5IRQR = 0;
MMC5LineCounter = 0;
mmc5psize = mmc5vsize = 3;

View File

@ -55,9 +55,9 @@ static void UNROM512_Sync() {
chip = !flash_id_mode ? FLASH_CHIP : CFI_CHIP;
else
chip = ROM_CHIP;
setprg16r(chip, 0x8000, latche & 0b11111);
setprg16r(chip, 0x8000, latche);
setprg16r(chip, 0xc000, ~0);
setchr8((latche >> 5) & 0b11);
setchr8(latche >> 5);
setmirror(MI_0 + ((latche >> 7) & 1));
}

View File

@ -557,6 +557,7 @@ void FCEU_SaveGameSave(CartInfo *LocalHWInfo)
LocalHWInfo->SaveGame[x].buflen, sp);
}
}
fclose(sp);
}
}
}
@ -584,6 +585,7 @@ void FCEU_LoadGameSave(CartInfo *LocalHWInfo)
}
}
}
fclose(sp);
}
}
}

View File

@ -58,6 +58,15 @@ void FCEU_CheatAddRAM(int s, uint32 A, uint8 *p)
CheatRPtrs[AB+x]=p-A;
}
// Cheat change event callback. Called whenever cheat map is changed or recalculated.
static void (*cheatsChangeEventCB)(void*) = nullptr;
static void* cheatsChangeEventUserData = nullptr;
void FCEU_SetCheatChangeEventCallback( void (*func)(void*), void* userData )
{
cheatsChangeEventCB = func;
cheatsChangeEventUserData = userData;
}
CHEATF_SUBFAST SubCheats[256];
uint32 numsubcheats = 0;
@ -132,6 +141,11 @@ void RebuildSubCheats(void)
}
FrozenAddressCount = numsubcheats; //Update the frozen address list
// Notify the system of a change
if (cheatsChangeEventCB != nullptr)
{
cheatsChangeEventCB( cheatsChangeEventUserData );
}
}
void FCEU_PowerCheats()
@ -368,12 +382,15 @@ void FCEU_FlushGameCheats(FILE *override, int nosave)
}
int FCEUI_AddCheat(const char *name, uint32 addr, uint8 val, int compare, int type)
int FCEUI_AddCheat(const char *name, uint32 addr, uint8 val, int compare, int type, int status, bool rebuild)
{
AddCheatEntry(name, addr, val, compare, 1, type);
AddCheatEntry(name, addr, val, compare, status, type);
savecheats = 1;
RebuildSubCheats();
if (rebuild)
{
RebuildSubCheats();
}
return 1;
}

View File

@ -33,6 +33,8 @@ extern int disableAutoLSCheats;
int FCEU_DisableAllCheats(void);
int FCEU_DeleteAllCheats(void);
void FCEU_SetCheatChangeEventCallback( void (*func)(void*) = nullptr, void* userData = nullptr );
struct CHEATF_SUBFAST
{
uint16 addr;

View File

@ -19,6 +19,14 @@ unsigned int debuggerPageSize = 14;
int vblankScanLines = 0; //Used to calculate scanlines 240-261 (vblank)
int vblankPixel = 0; //Used to calculate the pixels in vblank
struct TraceInstructionCallback
{
void (*func)(uint8 *opcode, int size) = nullptr;
TraceInstructionCallback* next = nullptr;
};
static TraceInstructionCallback* traceInstructionCB = nullptr;
int offsetStringToInt(unsigned int type, const char* offsetBuffer, bool *conversionOk)
{
int offset = -1;
@ -546,7 +554,7 @@ void LogCDData(uint8 *opcode, uint16 A, int size)
case 4: memop = 0x20; break;
}
if ((j = GetPRGAddress(A)) != -1)
if (((j = GetPRGAddress(A)) != -1) && (opcode[0] != 0x4C) && (opcode[0] != 0x6C))
{
if (opwrite[opcode[0]] == 0)
{
@ -561,7 +569,12 @@ void LogCDData(uint8 *opcode, uint16 A, int size)
newDataHit = true;
}
}
else
// Unclear why the write destination's access types gets reset for FDS...
// See:
// - https://github.com/TASEmulators/fceux/commit/a4fa6225a04b5ab8d3dfca3fc9abd7190bceec85
// - https://github.com/TASEmulators/fceux/commit/b10b6254c3d5c9519a85cb4382cdb22846d2e394
// - https://github.com/TASEmulators/fceux/commit/67942accc72149ae028d58f36419b64ea8651db9?diff=unified&w=1
else if(GameInfo && GameInfo->type == GIT_FDS)
{
if (cdloggerdata[j] & 1)
{
@ -989,5 +1002,82 @@ void DebugCycle()
if(debug_loggingCD)
LogCDData(opcode, A, size);
#ifdef __WIN_DRIVER__
FCEUD_TraceInstruction(opcode, size);
#else
// Use callback pointer that can be null checked, this saves on the overhead
// of calling a function for every instruction when we aren't tracing.
if (traceInstructionCB != nullptr)
{
auto* cb = traceInstructionCB;
while (cb != nullptr)
{
cb->func(opcode, size);
cb = cb->next;
}
}
#endif
}
void* FCEUI_TraceInstructionRegister( void (*func)(uint8*,int) )
{
TraceInstructionCallback* cb = nullptr;
if (traceInstructionCB == nullptr)
{
cb = traceInstructionCB = new TraceInstructionCallback();
cb->func = func;
}
else
{
cb = traceInstructionCB;
while (cb != nullptr)
{
if (cb->func == func)
{
// This function has already been registered, don't double add.
return nullptr;
}
if (cb->next == nullptr)
{
auto* newCB = new TraceInstructionCallback();
newCB->func = func;
cb->next = newCB;
return newCB;
}
cb = cb->next;
}
}
return cb;
}
bool FCEUI_TraceInstructionUnregisterHandle( void* handle )
{
TraceInstructionCallback* cb, *cb_prev, *cb_handle;
cb_handle = static_cast<TraceInstructionCallback*>(handle);
cb_prev = nullptr;
cb = traceInstructionCB;
while (cb != nullptr)
{
if (cb == cb_handle)
{ // Match we are going to remove from list and delete
if (cb_prev != nullptr)
{
cb_prev = cb->next;
}
else
{
traceInstructionCB = cb->next;
}
delete cb;
return true;
}
cb_prev = cb;
cb = cb->next;
}
return false;
}

View File

@ -175,4 +175,7 @@ DebuggerState &FCEUI_Debugger();
int offsetStringToInt(unsigned int type, const char* offsetBuffer, bool *conversionOk = nullptr);
unsigned int NewBreak(const char* name, int start, int end, unsigned int type, const char* condition, unsigned int num, bool enable);
void* FCEUI_TraceInstructionRegister( void (*func)(uint8*,int) );
bool FCEUI_TraceInstructionUnregisterHandle( void* handle );
#endif

View File

@ -197,7 +197,7 @@ void FCEU_DispMessage( __FCEU_PRINTF_FORMAT const char *format, int disppos, ...
int FCEUI_DecodePAR(const char *code, int *a, int *v, int *c, int *type);
int FCEUI_DecodeGG(const char *str, int *a, int *v, int *c);
int FCEUI_AddCheat(const char *name, uint32 addr, uint8 val, int compare, int type);
int FCEUI_AddCheat(const char *name, uint32 addr, uint8 val, int compare, int type, int status = 1, bool rebuild = true);
int FCEUI_DelCheat(uint32 which);
int FCEUI_ToggleCheat(uint32 which);
int FCEUI_GlobalToggleCheat(int global_enable);
@ -275,6 +275,8 @@ void FCEUI_SetEmulationPaused(int val);
void FCEUI_ToggleEmulationPause();
void FCEUI_PauseForDuration(int secs);
int FCEUI_PauseFramesRemaining();
void FCEUI_SetNetPlayPause(bool value);
bool FCEUI_GetNetPlayPause();
//indicates whether input aids should be drawn (such as crosshairs, etc; usually in fullscreen mode)
bool FCEUD_ShouldDrawInputAids();
@ -365,7 +367,11 @@ bool FCEU_IsValidUI(EFCEUI ui);
#ifdef __cplusplus
extern "C"
{
#endif
FILE *FCEUI_UTF8fopen_C(const char *n, const char *m);
#ifdef __cplusplus
} // extern C
#endif
FILE *FCEUI_UTF8fopen_C(const char *n, const char *m);
#endif //__DRIVER_H_

View File

@ -74,7 +74,7 @@ static const char *Authors[] = {
"\t rainwarrior", "\t feos",
"Pre 2.0 Guys:",
"\t Bero", "\t Xodnizel", "\t Aaron Oneal", "\t Joe Nahmias",
"\t Paul Kuliniewicz", "\t Quietust", "\t Ben Parnell",
"\t Paul Kuliniewicz", "\t Quietust",
"\t Parasyte &amp; bbitmaster",
"\t blip & nitsuja",
"Included components:",
@ -130,7 +130,7 @@ AboutWindow::AboutWindow(QWidget *parent)
mainLayout->addLayout( hbox1 );
sprintf( stmp, "git URL: %s", fceu_get_git_url() );
snprintf( stmp, sizeof(stmp), "git URL: %s", fceu_get_git_url() );
hbox1 = new QHBoxLayout();
lbl = new QLabel( tr(stmp) );
@ -140,7 +140,7 @@ AboutWindow::AboutWindow(QWidget *parent)
mainLayout->addLayout( hbox1 );
sprintf( stmp, "git Revision: %s", fceu_get_git_rev() );
snprintf( stmp, sizeof(stmp), "git Revision: %s", fceu_get_git_rev() );
hbox1 = new QHBoxLayout();
lbl = new QLabel( tr(stmp) );
@ -191,23 +191,23 @@ AboutWindow::AboutWindow(QWidget *parent)
credits->insertPlainText( "\nOpen Source Dependencies:\n" );
sprintf( stmp, " Compiled with Qt version %d.%d.%d\n", QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH );
snprintf( stmp, sizeof(stmp), " Compiled with Qt version %d.%d.%d\n", QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH );
credits->insertPlainText( stmp );
sprintf( stmp, " Compiled with SDL version %d.%d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL );
snprintf( stmp, sizeof(stmp), " Compiled with SDL version %d.%d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL );
credits->insertPlainText( stmp );
SDL_version v;
SDL_GetVersion(&v);
sprintf( stmp, " Linked with SDL version %d.%d.%d\n", v.major, v.minor, v.patch);
snprintf( stmp, sizeof(stmp), " Linked with SDL version %d.%d.%d\n", v.major, v.minor, v.patch);
credits->insertPlainText( stmp );
#ifdef ZLIB_VERSION
sprintf( stmp, " Compiled with zlib %s\n", ZLIB_VERSION );
snprintf( stmp, sizeof(stmp), " Compiled with zlib %s\n", ZLIB_VERSION );
credits->insertPlainText( stmp );
#endif
#ifdef _USE_LIBARCHIVE
sprintf( stmp, " Compiled with libarchive %s\n", ARCHIVE_VERSION_ONLY_STRING );
snprintf( stmp, sizeof(stmp), " Compiled with libarchive %s\n", ARCHIVE_VERSION_ONLY_STRING );
credits->insertPlainText( stmp );
const char *libArcName[] = { "zlib", "liblzma", "bzlib", "liblz4", "libzstd", nullptr };
const char *libArcVersion[] = { archive_zlib_version(), archive_liblzma_version(),
@ -217,7 +217,7 @@ AboutWindow::AboutWindow(QWidget *parent)
{
if (libArcVersion[i])
{
sprintf( stmp, " %s %s\n", libArcName[i], libArcVersion[i]);
snprintf( stmp, sizeof(stmp), " %s %s\n", libArcName[i], libArcVersion[i]);
credits->insertPlainText( stmp );
}
i++;
@ -225,27 +225,27 @@ AboutWindow::AboutWindow(QWidget *parent)
#endif
#ifdef _S9XLUA_H
sprintf( stmp, " Compiled with %s\n", LUA_RELEASE );
snprintf( stmp, sizeof(stmp), " Compiled with %s\n", LUA_RELEASE );
credits->insertPlainText( stmp );
#endif
#ifdef _USE_LIBAV
sprintf( stmp, " Compiled with ffmpeg libraries:\n");
snprintf( stmp, sizeof(stmp), " Compiled with ffmpeg libraries:\n");
credits->insertPlainText( stmp );
sprintf( stmp, " libavutil %i.%i.%i\n", LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO);
snprintf( stmp, sizeof(stmp), " libavutil %i.%i.%i\n", LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO);
credits->insertPlainText( stmp );
sprintf( stmp, " libavformat %i.%i.%i\n", LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO);
snprintf( stmp, sizeof(stmp), " libavformat %i.%i.%i\n", LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO);
credits->insertPlainText( stmp );
sprintf( stmp, " libavcodec %i.%i.%i\n", LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO);
snprintf( stmp, sizeof(stmp), " libavcodec %i.%i.%i\n", LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO);
credits->insertPlainText( stmp );
sprintf( stmp, " libswscale %i.%i.%i\n", LIBSWSCALE_VERSION_MAJOR, LIBSWSCALE_VERSION_MINOR, LIBSWSCALE_VERSION_MICRO);
snprintf( stmp, sizeof(stmp), " libswscale %i.%i.%i\n", LIBSWSCALE_VERSION_MAJOR, LIBSWSCALE_VERSION_MINOR, LIBSWSCALE_VERSION_MICRO);
credits->insertPlainText( stmp );
sprintf( stmp, " libswresample %i.%i.%i\n", LIBSWRESAMPLE_VERSION_MAJOR, LIBSWRESAMPLE_VERSION_MINOR, LIBSWRESAMPLE_VERSION_MICRO);
snprintf( stmp, sizeof(stmp), " libswresample %i.%i.%i\n", LIBSWRESAMPLE_VERSION_MAJOR, LIBSWRESAMPLE_VERSION_MINOR, LIBSWRESAMPLE_VERSION_MICRO);
credits->insertPlainText( stmp );
#endif
#ifdef _USE_X264
sprintf( stmp, " Compiled with x264 version %s\n", X264_POINTVER );
snprintf( stmp, sizeof(stmp), " Compiled with x264 version %s\n", X264_POINTVER );
credits->insertPlainText( stmp );
#endif

View File

@ -26,6 +26,7 @@
#include <stdarg.h>
#include <string.h>
#include <string>
#include <atomic>
#ifdef WIN32
#include <windows.h>
@ -79,12 +80,12 @@ extern "C"
static gwavi_t *gwavi = NULL;
static bool recordEnable = false;
static bool recordAudio = true;
static int vbufHead = 0;
static int vbufTail = 0;
static int vbufSize = 0;
static int abufHead = 0;
static int abufTail = 0;
static int abufSize = 0;
static std::atomic<int> vbufHead(0);
static std::atomic<int> vbufTail(0);
static constexpr int vbufSize = 1024 * 1024 * 64;
static std::atomic<int> abufHead(0);
static std::atomic<int> abufTail(0);
static constexpr int abufSize = 256 * 1024;
static uint32_t *rawVideoBuf = NULL;
static int16_t *rawAudioBuf = NULL;
static int aviDriver = 0;
@ -460,7 +461,14 @@ static int encode_frame( unsigned char *inBuf, int width, int height )
pic->stride[1] = width/2;
pic->stride[2] = width/2;
#if defined(MAX_SCALABLE_LAYERS) && (X265_BUILD >= 210) && (X265_BUILD < 213)
/* Handle API changes for scalable layers output in x265 4.0 */
x265_picture *pics[MAX_SCALABLE_LAYERS] = {NULL};
pics[0] = pic;
ret = x265_encoder_encode( hdl, &nal, &i_nal, pic, pics );
#else
ret = x265_encoder_encode( hdl, &nal, &i_nal, pic, &pic_out );
#endif
if ( ret <= 0 )
{
@ -493,7 +501,14 @@ static int close(void)
/* Flush delayed frames */
while( hdl != NULL )
{
#if defined(MAX_SCALABLE_LAYERS) && (X265_BUILD >= 210) && (X265_BUILD < 213)
/* Handle API changes for scalable layers output in x265 4.0 */
x265_picture *pics[MAX_SCALABLE_LAYERS] = {NULL};
pics[0] = pic;
ret = x265_encoder_encode( hdl, &nal, &i_nal, pic, pics );
#else
ret = x265_encoder_encode( hdl, &nal, &i_nal, NULL, &pic_out );
#endif
if ( ret <= 0 )
{
@ -795,7 +810,7 @@ struct OutputStream
if ( writeError )
{
char msg[512];
sprintf( msg, "%s Stream Write Errors Detected.\nOutput may be incomplete or corrupt.\nSee log file '%s' for details\n",
snprintf( msg, sizeof(msg), "%s Stream Write Errors Detected.\nOutput may be incomplete or corrupt.\nSee log file '%s' for details\n",
isAudio ? "Audio" : "Video", AV_LOG_FILE_NAME);
FCEUD_PrintError(msg);
}
@ -2123,7 +2138,7 @@ int aviRecordLogOpen(void)
if ( avLogFp == NULL )
{
char msg[512];
sprintf( msg, "Error: Failed to open AV Recording log file for writing: %s\n", AV_LOG_FILE_NAME);
snprintf( msg, sizeof(msg), "Error: Failed to open AV Recording log file for writing: %s\n", AV_LOG_FILE_NAME);
FCEUD_PrintError(msg);
avLogFp = stdout;
}
@ -2216,15 +2231,15 @@ int aviRecordOpenFile( const char *filepath )
date = QDate::currentDate();
avi_info.add_pair( "ICRD", date.toString(Qt::ISODate).toStdString().c_str() );
avi_info.add_pair( "ICRD", date.toString(Qt::ISODate).toLocal8Bit().constData() );
avi_info.add_pair( "ILNG", QLocale::languageToString( locale.language() ).toStdString().c_str() );
avi_info.add_pair( "ILNG", QLocale::languageToString( locale.language() ).toLocal8Bit().constData() );
avi_info.add_pair( "IARL", QLocale::countryToString( locale.country() ).toStdString().c_str() );
avi_info.add_pair( "IARL", QLocale::countryToString( locale.country() ).toLocal8Bit().constData() );
avi_info.add_pair( "IMED", QSysInfo::prettyProductName().toStdString().c_str() );
avi_info.add_pair( "IMED", QSysInfo::prettyProductName().toLocal8Bit().constData() );
sprintf( txt, "FCEUX %s", FCEU_VERSION_STRING );
snprintf( txt, sizeof(txt), "FCEUX %s", FCEU_VERSION_STRING );
avi_info.add_pair( "ITCH", txt );
romFile = getRomFile();
@ -2305,7 +2320,7 @@ int aviRecordOpenFile( const char *filepath )
char msg[512];
fprintf( avLogFp, "Error: Failed to open AVI file.\n");
recordEnable = false;
sprintf( msg, "Error: AV Recording Initialization Failed.\nSee %s for details...\n", AV_LOG_FILE_NAME);
snprintf( msg, sizeof(msg), "Error: AV Recording Initialization Failed.\nSee %s for details...\n", AV_LOG_FILE_NAME);
FCEUD_PrintError(msg);
return -1;
}
@ -2320,16 +2335,14 @@ int aviRecordOpenFile( const char *filepath )
char msg[512];
fprintf( avLogFp, "Error: Failed to open AVI file.\n");
recordEnable = false;
sprintf( msg, "Error: AV Recording Initialization Failed.\nSee %s for details...\n", AV_LOG_FILE_NAME);
snprintf( msg, sizeof(msg), "Error: AV Recording Initialization Failed.\nSee %s for details...\n", AV_LOG_FILE_NAME);
FCEUD_PrintError(msg);
return -1;
}
}
vbufSize = 1024 * 1024 * 60;
rawVideoBuf = (uint32_t*)malloc( vbufSize * sizeof(uint32_t) );
abufSize = 96000;
rawAudioBuf = (int16_t*)malloc( abufSize * sizeof(uint16_t) );
vbufHead = 0;
@ -2348,10 +2361,6 @@ int aviRecordAddFrame( void )
return -1;
}
//if ( gwavi == NULL )
//{
// return -1;
//}
if ( FCEUI_EmulationPaused() )
{
return 0;
@ -2361,25 +2370,28 @@ int aviRecordAddFrame( void )
numPixels = nes_shm->video.ncol * nes_shm->video.nrow;
availSize = (vbufTail - vbufHead);
if ( availSize <= 0 )
head = vbufHead;
auto calcAvailSize = [&]()
{
availSize += vbufSize;
}
availSize = (vbufTail - head);
if ( availSize <= 0 )
{
availSize += vbufSize;
}
};
calcAvailSize();
while ( numPixels > availSize )
{
//printf("Video Unavail %i \n", availSize );
msleep(1);
availSize = (vbufTail - vbufHead);
if ( availSize <= 0 )
{
availSize += vbufSize;
}
calcAvailSize();
}
i = 0; head = vbufHead;
i = 0;
while ( i < numPixels )
{
@ -2408,12 +2420,17 @@ int aviRecordAddAudioFrame( int32_t *buf, int numSamples )
return -1;
}
// Get current buffer index values from atomic variables and store in stack variables
// Do loop processing with stack variables and then update atomics when finished
int head = abufHead;
for (int i=0; i<numSamples; i++)
{
rawAudioBuf[ abufHead ] = buf[i];
rawAudioBuf[ head ] = buf[i];
abufHead = (abufHead + 1) % abufSize;
head = (head + 1) % abufSize;
}
abufHead = head;
return 0;
}
@ -2437,8 +2454,10 @@ int aviRecordClose(void)
{
free(rawAudioBuf); rawAudioBuf = NULL;
}
vbufTail = abufTail = 0;
vbufSize = abufSize = 0;
vbufHead = 0;
abufHead = 0;
vbufTail = 0;
abufTail = 0;
return 0;
}
@ -2600,6 +2619,8 @@ void AviRecordDiskThread_t::run(void)
char localRecordAudio = 0;
int avgAudioPerFrame, audioChunkSize, audioSamplesAvail=0;
int localVideoFormat;
int audioHead = 0;
int audioTail = 0;
fprintf( avLogFp, "AVI Record Disk Thread Start\n");
@ -2672,12 +2693,19 @@ void AviRecordDiskThread_t::run(void)
// Main Disk Record Loop
while ( !isInterruptionRequested() )
{
while ( (numPixelsReady < numPixels) && (vbufTail != vbufHead) )
{
videoOut[ numPixelsReady ] = rawVideoBuf[ vbufTail ]; numPixelsReady++;
vbufTail = (vbufTail + 1) % vbufSize;
// Get current buffer index values from atomic variables and store in stack variables
// Do loop processing with stack variables and then update atomics when finished
int vhead = vbufHead;
int vtail = vbufTail;
while ( (numPixelsReady < numPixels) && (vtail != vhead) )
{
videoOut[ numPixelsReady ] = rawVideoBuf[ vtail ]; numPixelsReady++;
vtail = (vtail + 1) % vbufSize;
}
vbufTail = vtail;
}
if ( numPixelsReady >= numPixels )
@ -2731,7 +2759,11 @@ void AviRecordDiskThread_t::run(void)
numPixelsReady = 0;
audioSamplesAvail = abufHead - abufTail;
// Get current buffer index values from atomic variables and store in stack variables
// Do loop processing with stack variables and then update atomics when finished
audioHead = abufHead;
audioTail = abufTail;
audioSamplesAvail = audioHead - audioTail;
if ( audioSamplesAvail < 0 )
{
@ -2743,17 +2775,18 @@ void AviRecordDiskThread_t::run(void)
{
numSamples = 0;
while ( abufHead != abufTail )
while ( audioHead != audioTail )
{
audioOut[ numSamples ] = rawAudioBuf[ abufTail ]; numSamples++;
audioOut[ numSamples ] = rawAudioBuf[ audioTail ]; numSamples++;
abufTail = (abufTail + 1) % abufSize;
audioTail = (audioTail + 1) % abufSize;
if ( numSamples >= audioChunkSize )
{
break;
}
}
abufTail = audioTail;
if ( numSamples > 0 )
{
@ -2779,8 +2812,11 @@ void AviRecordDiskThread_t::run(void)
}
}
audioHead = abufHead;
audioTail = abufTail;
// Write Leftover Audio Samples
audioSamplesAvail = abufHead - abufTail;
audioSamplesAvail = audioHead - audioTail;
if ( audioSamplesAvail < 0 )
{
@ -2793,12 +2829,13 @@ void AviRecordDiskThread_t::run(void)
//printf("Writing Last %i Audio Samples\n", audioSamplesAvail );
numSamples = 0;
while ( abufHead != abufTail )
while ( audioHead != audioTail )
{
audioOut[ numSamples ] = rawAudioBuf[ abufTail ]; numSamples++;
audioOut[ numSamples ] = rawAudioBuf[ audioTail ]; numSamples++;
abufTail = (abufTail + 1) % abufSize;
audioTail = (audioTail + 1) % abufSize;
}
abufTail = audioTail;
if ( numSamples > 0 )
{
@ -3136,7 +3173,7 @@ void LibavOptionsPage::initSampleRateSelect( const char *codec_name )
while ( c->supported_samplerates[i] != 0 )
{
sprintf( rateName, "%i", c->supported_samplerates[i] );
snprintf( rateName, sizeof(rateName), "%i", c->supported_samplerates[i] );
audioSampleRate->addItem( tr(rateName), c->supported_samplerates[i] );
@ -3263,10 +3300,10 @@ void LibavOptionsPage::initCodecLists(void)
c = av_codec_iterate( &it );
}
initPixelFormatSelect( videoEncSel->currentText().toStdString().c_str() );
initSampleFormatSelect( audioEncSel->currentText().toStdString().c_str() );
initSampleRateSelect( audioEncSel->currentText().toStdString().c_str() );
initChannelLayoutSelect( audioEncSel->currentText().toStdString().c_str() );
initPixelFormatSelect( videoEncSel->currentText().toLocal8Bit().constData() );
initSampleFormatSelect( audioEncSel->currentText().toLocal8Bit().constData() );
initSampleRateSelect( audioEncSel->currentText().toLocal8Bit().constData() );
initChannelLayoutSelect( audioEncSel->currentText().toLocal8Bit().constData() );
videoEncSel->model()->sort(0, Qt::AscendingOrder);
audioEncSel->model()->sort(0, Qt::AscendingOrder);
@ -3281,7 +3318,7 @@ void LibavOptionsPage::videoCodecChanged(int idx)
{
const AVCodec *c;
LIBAV::video_st.selEnc = videoEncSel->currentText().toStdString().c_str();
LIBAV::video_st.selEnc = videoEncSel->currentText().toLocal8Bit().constData();
c = avcodec_find_encoder_by_name( LIBAV::video_st.selEnc.c_str() );
@ -3296,7 +3333,7 @@ void LibavOptionsPage::audioCodecChanged(int idx)
{
const AVCodec *c;
LIBAV::audio_st.selEnc = audioEncSel->currentText().toStdString().c_str();
LIBAV::audio_st.selEnc = audioEncSel->currentText().toLocal8Bit().constData();
c = avcodec_find_encoder_by_name( LIBAV::audio_st.selEnc.c_str() );
@ -3410,7 +3447,7 @@ void LibavEncOptItem::setValueText(void)
if ( units[x]->default_val.i64 & i )
{
char stmp2[128];
sprintf( stmp2, "%s", units[x]->name );
snprintf( stmp2, sizeof(stmp2), "%s", units[x]->name );
if (j>0)
{
strcat( stmp, ",");
@ -3445,7 +3482,7 @@ void LibavEncOptItem::setValueText(void)
if ( units[x]->default_val.i64 == i )
{
char stmp2[128];
sprintf( stmp2, " (%s)", units[x]->name );
snprintf( stmp2, sizeof(stmp2), " (%s)", units[x]->name );
strcat( stmp, stmp2 );
break;
}
@ -3481,12 +3518,12 @@ LibavEncOptWin::LibavEncOptWin(int type, QWidget *parent)
if ( type )
{
codec_name = LIBAV::audio_st.selEnc.c_str();
sprintf( title, "%s Audio Encoder Configuration", codec_name );
snprintf( title, sizeof(title), "%s Audio Encoder Configuration", codec_name );
}
else
{
codec_name = LIBAV::video_st.selEnc.c_str();
sprintf( title, "%s Video Encoder Configuration", codec_name );
snprintf( title, sizeof(title), "%s Video Encoder Configuration", codec_name );
}
setWindowTitle( title );
resize(512, 512);
@ -3816,13 +3853,13 @@ LibavEncOptInputWin::LibavEncOptInputWin( LibavEncOptItem *itemIn, QWidget *pare
grid->addWidget( new QLabel( tr("Range:") ), 2, 0 );
sprintf( stmp, "[ %.0f, %.0f ]", opt->min, opt->max );
snprintf( stmp, sizeof(stmp), "[ %.0f, %.0f ]", opt->min, opt->max );
grid->addWidget( new QLabel( tr(stmp) ), 2, 1 );
grid->addWidget( new QLabel( tr("Default:") ), 3, 0 );
sprintf( stmp, "%lli", (long long)opt->default_val.i64 );
snprintf( stmp, sizeof(stmp), "%lli", (long long)opt->default_val.i64 );
grid->addWidget( new QLabel( tr(stmp) ), 3, 1 );
@ -3838,12 +3875,12 @@ LibavEncOptInputWin::LibavEncOptInputWin( LibavEncOptItem *itemIn, QWidget *pare
{
if ( item->units[i]->help )
{
sprintf( stmp, "%3lli: %s - %s", (long long)item->units[i]->default_val.i64,
snprintf( stmp, sizeof(stmp), "%3lli: %s - %s", (long long)item->units[i]->default_val.i64,
item->units[i]->name, item->units[i]->help );
}
else
{
sprintf( stmp, "%3lli: %s", (long long)item->units[i]->default_val.i64,
snprintf( stmp, sizeof(stmp), "%3lli: %s", (long long)item->units[i]->default_val.i64,
item->units[i]->name );
}
@ -3874,13 +3911,13 @@ LibavEncOptInputWin::LibavEncOptInputWin( LibavEncOptItem *itemIn, QWidget *pare
grid->addWidget( new QLabel( tr("Range:") ), 2, 0 );
sprintf( stmp, "[ %e, %e ]", opt->min, opt->max );
snprintf( stmp, sizeof(stmp), "[ %e, %e ]", opt->min, opt->max );
grid->addWidget( new QLabel( tr(stmp) ), 2, 1 );
grid->addWidget( new QLabel( tr("Default:") ), 3, 0 );
sprintf( stmp, "%f", opt->default_val.dbl );
snprintf( stmp, sizeof(stmp), "%f", opt->default_val.dbl );
grid->addWidget( new QLabel( tr(stmp) ), 3, 1 );
@ -3905,7 +3942,7 @@ LibavEncOptInputWin::LibavEncOptInputWin( LibavEncOptItem *itemIn, QWidget *pare
if ( opt->default_val.str )
{
sprintf( stmp, "%s", opt->default_val.str );
snprintf( stmp, sizeof(stmp), "%s", opt->default_val.str );
}
grid->addWidget( new QLabel( tr(stmp) ), 2, 1 );
@ -3929,7 +3966,7 @@ LibavEncOptInputWin::LibavEncOptInputWin( LibavEncOptItem *itemIn, QWidget *pare
grid->addWidget( new QLabel( tr("Default:") ), 2, 0 );
sprintf( stmp, "%i/%i", opt->default_val.q.num, opt->default_val.q.den );
snprintf( stmp, sizeof(stmp), "%i/%i", opt->default_val.q.num, opt->default_val.q.den );
grid->addWidget( new QLabel( tr(stmp) ), 2, 1 );
@ -3959,7 +3996,7 @@ LibavEncOptInputWin::LibavEncOptInputWin( LibavEncOptItem *itemIn, QWidget *pare
grid->addWidget( new QLabel( tr("Default:") ), 2, 0 );
sprintf( stmp, "%s", opt->default_val.i64 ? "true" : "false" );
snprintf( stmp, sizeof(stmp), "%s", opt->default_val.i64 ? "true" : "false" );
grid->addWidget( new QLabel( tr(stmp) ), 2, 1 );
@ -3983,7 +4020,7 @@ LibavEncOptInputWin::LibavEncOptInputWin( LibavEncOptItem *itemIn, QWidget *pare
grid->addWidget( new QLabel( tr("Default:") ), 2, 0 );
sprintf( stmp, "0x%08llX", (unsigned long long)opt->default_val.i64 );
snprintf( stmp, sizeof(stmp), "0x%08llX", (unsigned long long)opt->default_val.i64 );
grid->addWidget( new QLabel( tr(stmp) ), 2, 1 );
@ -3993,7 +4030,7 @@ LibavEncOptInputWin::LibavEncOptInputWin( LibavEncOptItem *itemIn, QWidget *pare
for (size_t i=0; i<item->units.size(); i++)
{
sprintf( stmp, "%s", item->units[i]->name );
snprintf( stmp, sizeof(stmp), "%s", item->units[i]->name );
c = new QCheckBox( tr(stmp) );
@ -4102,7 +4139,7 @@ void LibavEncOptInputWin::applyChanges(void)
{
if ( strEntry )
{
av_opt_set( item->obj, item->opt->name, strEntry->text().toStdString().c_str(), 0 );
av_opt_set( item->obj, item->opt->name, strEntry->text().toLocal8Bit().constData(), 0 );
}
}
break;

View File

@ -294,18 +294,18 @@ void AviRiffViewerDialog::openAviFileDialog(void)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
printf( "AVI Debug movie %s\n", filename.toStdString().c_str() );
printf( "AVI Debug movie %s\n", filename.toLocal8Bit().constData() );
lastPath = QFileInfo(filename).absolutePath().toStdString();
lastPath = QFileInfo(filename).absolutePath().toLocal8Bit().constData();
if ( lastPath.size() > 0 )
{
g_config->setOption ("SDL.AviFilePath", lastPath);
}
openFile( filename.toStdString().c_str() );
openFile( filename.toLocal8Bit().constData() );
}
//----------------------------------------------------------------------------
int AviRiffViewerDialog::openFile( const char *filepath )
@ -475,112 +475,112 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item )
avi->getChunkData( item->filePos(), data.buf, item->getSize()+8 );
sprintf( stmp, "%c%c%c%c", data.buf[0], data.buf[1], data.buf[2], data.buf[3] );
snprintf( stmp, sizeof(stmp), "%c%c%c%c", data.buf[0], data.buf[1], data.buf[2], data.buf[3] );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("fcc") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(4) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(4) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("cb") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(8) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(8) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwMicroSecPerFrame") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(12) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(12) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwMaxBytesPerSec") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(16) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(16) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwPaddingGranularity") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "0x%X", data.readU32(20) );
snprintf( stmp, sizeof(stmp), "0x%X", data.readU32(20) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwFlags") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(24) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(24) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwTotalFrames") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(28) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(28) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwInitialFrames") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(32) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(32) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwStreams") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(36) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(36) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwSuggestedBufferSize") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(40) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(40) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwWidth") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(44) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(44) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwHeight") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(48) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(48) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwScale") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(52) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(52) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwRate") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(56) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(56) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwStart") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(60) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(60) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwLength") );
@ -593,21 +593,21 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item )
avi->getChunkData( item->filePos(), data.buf, item->getSize()+8 );
sprintf( stmp, "%c%c%c%c", data.buf[0], data.buf[1], data.buf[2], data.buf[3] );
snprintf( stmp, sizeof(stmp), "%c%c%c%c", data.buf[0], data.buf[1], data.buf[2], data.buf[3] );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("fcc") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(4) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(4) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("cb") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%c%c%c%c", data.buf[8], data.buf[9], data.buf[10], data.buf[11] );
snprintf( stmp, sizeof(stmp), "%c%c%c%c", data.buf[8], data.buf[9], data.buf[10], data.buf[11] );
strcpy( strhType, stmp );
twi = new QTreeWidgetItem();
@ -617,11 +617,11 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item )
if ( isalnum(data.buf[12]) )
{
sprintf( stmp, "%c%c%c%c", data.buf[12], data.buf[13], data.buf[14], data.buf[15] );
snprintf( stmp, sizeof(stmp), "%c%c%c%c", data.buf[12], data.buf[13], data.buf[14], data.buf[15] );
}
else
{
sprintf( stmp, "0x%X", data.readU32(12) );
snprintf( stmp, sizeof(stmp), "0x%X", data.readU32(12) );
}
twi = new QTreeWidgetItem();
@ -629,42 +629,42 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item )
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "0x%X", data.readU32(16) );
snprintf( stmp, sizeof(stmp), "0x%X", data.readU32(16) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwFlags") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU16(20) );
snprintf( stmp, sizeof(stmp), "%u", data.readU16(20) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("wPriority") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU16(22) );
snprintf( stmp, sizeof(stmp), "%u", data.readU16(22) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("wLanguage") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(24) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(24) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwInitialFrames") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(28) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(28) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwScale") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(32) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(32) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwRate") );
@ -672,68 +672,68 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item )
if ( strcmp( strhType, "vids" ) == 0 )
{
sprintf( stmp, "(%13.10f Hz)", (double)data.readU32(32) / (double)data.readU32(28) );
snprintf( stmp, sizeof(stmp), "(%13.10f Hz)", (double)data.readU32(32) / (double)data.readU32(28) );
twi->setText( 3, tr(stmp) );
}
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(36) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(36) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwStart") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(40) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(40) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwLength") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(44) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(44) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwSuggestedBufferSize") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%i", data.readI32(48) );
snprintf( stmp, sizeof(stmp), "%i", data.readI32(48) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwQuality") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(52) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(52) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("dwSampleSize") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU16(56) );
snprintf( stmp, sizeof(stmp), "%u", data.readU16(56) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("rcFrame.left") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU16(58) );
snprintf( stmp, sizeof(stmp), "%u", data.readU16(58) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("rcFrame.top") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU16(60) );
snprintf( stmp, sizeof(stmp), "%u", data.readU16(60) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("rcFrame.right") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU16(62) );
snprintf( stmp, sizeof(stmp), "%u", data.readU16(62) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("rcFrame.bottom") );
@ -748,49 +748,49 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item )
avi->getChunkData( item->filePos(), data.buf, item->getSize()+8 );
sprintf( stmp, "%c%c%c%c", data.buf[0], data.buf[1], data.buf[2], data.buf[3] );
snprintf( stmp, sizeof(stmp), "%c%c%c%c", data.buf[0], data.buf[1], data.buf[2], data.buf[3] );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("fcc") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(4) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(4) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("cb") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(8) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(8) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("biSize") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%i", data.readI32(12) );
snprintf( stmp, sizeof(stmp), "%i", data.readI32(12) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("biWidth") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%i", data.readI32(16) );
snprintf( stmp, sizeof(stmp), "%i", data.readI32(16) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("biHeight") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU16(20) );
snprintf( stmp, sizeof(stmp), "%u", data.readU16(20) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("biPlanes") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU16(22) );
snprintf( stmp, sizeof(stmp), "%u", data.readU16(22) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("biBitCount") );
@ -799,11 +799,11 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item )
if ( isalnum(data.buf[24]) )
{
sprintf( stmp, "%c%c%c%c", data.buf[24], data.buf[25], data.buf[26], data.buf[27] );
snprintf( stmp, sizeof(stmp), "%c%c%c%c", data.buf[24], data.buf[25], data.buf[26], data.buf[27] );
}
else
{
sprintf( stmp, "0x%X", data.readU32(24) );
snprintf( stmp, sizeof(stmp), "0x%X", data.readU32(24) );
}
twi = new QTreeWidgetItem();
@ -811,35 +811,35 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item )
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(28) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(28) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("biSizeImage") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%i", data.readI32(32) );
snprintf( stmp, sizeof(stmp), "%i", data.readI32(32) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("biXPelsPerMeter") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%i", data.readI32(36) );
snprintf( stmp, sizeof(stmp), "%i", data.readI32(36) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("biYPelsPerMeter") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(40) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(40) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("biClrUsed") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(44) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(44) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("biClrImportant") );
@ -854,56 +854,56 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item )
avi->getChunkData( item->filePos(), data.buf, dataSize );
sprintf( stmp, "%c%c%c%c", data.buf[0], data.buf[1], data.buf[2], data.buf[3] );
snprintf( stmp, sizeof(stmp), "%c%c%c%c", data.buf[0], data.buf[1], data.buf[2], data.buf[3] );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("fcc") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(4) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(4) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("cb") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU16(8) );
snprintf( stmp, sizeof(stmp), "%u", data.readU16(8) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("wFormatTag") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU16(10) );
snprintf( stmp, sizeof(stmp), "%u", data.readU16(10) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("nChannels") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(12) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(12) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("nSamplesPerSec") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(16) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(16) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("nAvgBytesPerSec") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU16(20) );
snprintf( stmp, sizeof(stmp), "%u", data.readU16(20) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("nBlockAlign") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU16(22) );
snprintf( stmp, sizeof(stmp), "%u", data.readU16(22) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("nBitsPerSample") );
@ -929,21 +929,21 @@ int AviRiffViewerDialog::processChunk( AviRiffTreeItem *item )
avi->getChunkData( item->filePos(), data.buf, item->getSize()+8 );
sprintf( stmp, "%c%c%c%c", data.buf[0], data.buf[1], data.buf[2], data.buf[3] );
snprintf( stmp, sizeof(stmp), "%c%c%c%c", data.buf[0], data.buf[1], data.buf[2], data.buf[3] );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("fcc") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(4) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(4) );
twi = new QTreeWidgetItem();
twi->setText( 0, tr("cb") );
twi->setText( 2, tr(stmp) );
item->addChild(twi);
sprintf( stmp, "%u", data.readU32(8) );
snprintf( stmp, sizeof(stmp), "%u", data.readU32(8) );
for (i=0; i < static_cast<int>(item->getSize()); i++)
{
@ -991,7 +991,7 @@ AviRiffTreeItem::AviRiffTreeItem(int typeIn, long long int fposIn, const char *f
strcpy( fourcc, fourccIn );
//sprintf( stmp, "0x%08llX", fposIn );
//snprintf( stmp, sizeof(stmp), "0x%08llX", fposIn );
switch ( type )
{
@ -1013,16 +1013,16 @@ AviRiffTreeItem::AviRiffTreeItem(int typeIn, long long int fposIn, const char *f
if ( showSizeHex )
{
sprintf( stmp, "0x%08lX", (unsigned long)size );
snprintf( stmp, sizeof(stmp), "0x%08lX", (unsigned long)size );
}
else
{
sprintf( stmp, "%zu", size );
snprintf( stmp, sizeof(stmp), "%zu", size );
}
setText( 2, QString(stmp) );
sprintf( stmp, "0x%08llX", fposIn );
snprintf( stmp, sizeof(stmp), "0x%08llX", fposIn );
setText( 3, QString(stmp) );
}

View File

@ -517,9 +517,9 @@ int GuiCheatsDialog_t::addSearchResult(uint32_t a, uint8_t last, uint8_t current
item = new QTreeWidgetItem();
sprintf(addrStr, "$%04X", a);
sprintf(lastStr, "%02X", last);
sprintf(curStr, "%02X", current);
snprintf(addrStr, sizeof(addrStr), "$%04X", a);
snprintf(lastStr, sizeof(lastStr), "%02X", last);
snprintf(curStr, sizeof(curStr), "%02X", current);
//item->setFont( 0, font );
//item->setFont( 1, font );
@ -591,9 +591,9 @@ void GuiCheatsDialog_t::knownValueCallback(void)
//printf("Cheat Search Known!\n");
FCEU_WRAPPER_LOCK();
//printf("'%s'\n", knownValEntry->displayText().toStdString().c_str() );
//printf("'%s'\n", knownValEntry->displayText().toLocal8Bit().constData() );
value = strtol(knownValEntry->displayText().toStdString().c_str(), NULL, 16);
value = strtol(knownValEntry->displayText().toLocal8Bit().constData(), NULL, 16);
FCEUI_CheatSearchEnd(FCEU_SEARCH_NEWVAL_KNOWN, value, 0);
@ -624,7 +624,7 @@ void GuiCheatsDialog_t::notEqualValueCallback(void)
if (checked)
{
value = strtol(neValEntry->displayText().toStdString().c_str(), NULL, 16);
value = strtol(neValEntry->displayText().toLocal8Bit().constData(), NULL, 16);
FCEUI_CheatSearchEnd(FCEU_SEARCH_PUERLY_RELATIVE_CHANGE, 0, value);
}
@ -648,7 +648,7 @@ void GuiCheatsDialog_t::greaterThanValueCallback(void)
if (checked)
{
value = strtol(grValEntry->displayText().toStdString().c_str(), NULL, 16);
value = strtol(grValEntry->displayText().toLocal8Bit().constData(), NULL, 16);
FCEUI_CheatSearchEnd(FCEU_SEARCH_NEWVAL_GT_KNOWN, 0, value);
}
@ -672,7 +672,7 @@ void GuiCheatsDialog_t::lessThanValueCallback(void)
if (checked)
{
value = strtol(ltValEntry->displayText().toStdString().c_str(), NULL, 16);
value = strtol(ltValEntry->displayText().toLocal8Bit().constData(), NULL, 16);
FCEUI_CheatSearchEnd(FCEU_SEARCH_NEWVAL_LT_KNOWN, 0, value);
}
@ -693,11 +693,11 @@ int GuiCheatsDialog_t::activeCheatListCB(const char *name, uint32 a, uint8 v, in
if (c >= 0)
{
sprintf(codeStr, "$%04X?%02X:%02X", a, c, v);
snprintf(codeStr, sizeof(codeStr), "$%04X?%02X:%02X", a, c, v);
}
else
{
sprintf(codeStr, "$%04X:%02X ", a, v);
snprintf(codeStr, sizeof(codeStr), "$%04X:%02X ", a, v);
}
item = actvCheatList->topLevelItem(actvCheatIdx);
@ -789,13 +789,13 @@ void GuiCheatsDialog_t::openCheatFile(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
g_config->setOption("SDL.LastOpenFile", filename.toStdString().c_str());
g_config->setOption("SDL.LastOpenFile", filename.toLocal8Bit().constData());
FCEU_WRAPPER_LOCK();
fp = fopen(filename.toStdString().c_str(), "r");
fp = fopen(filename.toLocal8Bit().constData(), "r");
if (fp != NULL)
{
@ -834,7 +834,7 @@ void GuiCheatsDialog_t::saveCheatFile(void)
dialog.selectFile(dir);
}
sprintf(dir, "%s/cheats", FCEUI_GetBaseDirectory());
snprintf(dir, sizeof(dir), "%s/cheats", FCEUI_GetBaseDirectory());
dialog.setDirectory(tr(dir));
@ -860,13 +860,13 @@ void GuiCheatsDialog_t::saveCheatFile(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
//g_config->setOption ("SDL.LastOpenFile", filename.toStdString().c_str() );
//g_config->setOption ("SDL.LastOpenFile", filename.toLocal8Bit().constData() );
FCEU_WRAPPER_LOCK();
fp = FCEUD_UTF8fopen(filename.toStdString().c_str(), "wb");
fp = FCEUD_UTF8fopen(filename.toLocal8Bit().constData(), "wb");
if (fp != NULL)
{
@ -888,11 +888,11 @@ void GuiCheatsDialog_t::addActvCheat(void)
int t = 1;
std::string name, cmpStr;
a = strtoul(cheatAddrEntry->displayText().toStdString().c_str(), NULL, 16);
a = strtoul(cheatAddrEntry->displayText().toLocal8Bit().constData(), NULL, 16);
v = strtoul(cheatValEntry->displayText().toStdString().c_str(), NULL, 16);
v = strtoul(cheatValEntry->displayText().toLocal8Bit().constData(), NULL, 16);
cmpStr = cheatCmpEntry->displayText().toStdString();
cmpStr = cheatCmpEntry->displayText().toLocal8Bit().constData();
if (isxdigit(cmpStr[0]))
{
@ -903,7 +903,7 @@ void GuiCheatsDialog_t::addActvCheat(void)
c = -1;
}
name = cheatNameEntry->text().toStdString();
name = cheatNameEntry->text().toLocal8Bit().constData();
t = typeEntry->currentData().toInt();
@ -965,11 +965,11 @@ void GuiCheatsDialog_t::updateCheatParameters(void)
}
//printf("Row: %i \n", row );
a = strtoul(cheatAddrEntry->displayText().toStdString().c_str(), NULL, 16);
a = strtoul(cheatAddrEntry->displayText().toLocal8Bit().constData(), NULL, 16);
v = strtoul(cheatValEntry->displayText().toStdString().c_str(), NULL, 16);
v = strtoul(cheatValEntry->displayText().toLocal8Bit().constData(), NULL, 16);
cmpStr = cheatCmpEntry->displayText().toStdString();
cmpStr = cheatCmpEntry->displayText().toLocal8Bit().constData();
//printf("CMP: '%s' \n", cmpStr.c_str() );
@ -983,7 +983,7 @@ void GuiCheatsDialog_t::updateCheatParameters(void)
}
//printf("CMP: '%i' 0x%X\n", c, c );
name = cheatNameEntry->text().toStdString();
name = cheatNameEntry->text().toLocal8Bit().constData();
//printf("Name: %s \n", name.c_str() );
@ -1025,15 +1025,15 @@ void GuiCheatsDialog_t::actvCheatItemClicked(QTreeWidgetItem *item, int column)
FCEUI_ToggleCheat(row);
}
}
sprintf(stmp, "%04X", a);
snprintf(stmp, sizeof(stmp), "%04X", a);
cheatAddrEntry->setText(tr(stmp));
sprintf(stmp, "%02X", v);
snprintf(stmp, sizeof(stmp), "%02X", v);
cheatValEntry->setText(tr(stmp));
if (c >= 0)
{
sprintf(stmp, "%02X", c);
snprintf(stmp, sizeof(stmp), "%02X", c);
cheatCmpEntry->setText(tr(stmp));
}
else

View File

@ -364,22 +364,22 @@ void CodeDataLoggerDialog_t::updatePeriodic(void)
if (cdloggerdataSize > 0)
{
sprintf(str, "0x%06x %.2f%%", codecount, (fcodecount / fromsize) * 100);
snprintf(str, sizeof(str), "0x%06x %.2f%%", codecount, (fcodecount / fromsize) * 100);
prgLoggedCodeLabel->setText(tr(str));
sprintf(str, "0x%06x %.2f%%", datacount, (fdatacount / fromsize) * 100);
snprintf(str, sizeof(str), "0x%06x %.2f%%", datacount, (fdatacount / fromsize) * 100);
prgLoggedDataLabel->setText(tr(str));
sprintf(str, "0x%06x %.2f%%", undefinedcount, (fundefinedcount / fromsize) * 100);
snprintf(str, sizeof(str), "0x%06x %.2f%%", undefinedcount, (fundefinedcount / fromsize) * 100);
prgUnloggedLabel->setText(tr(str));
sprintf(str, "0x%06x %.2f%%", rendercount, (frendercount / fvromsize) * 100);
snprintf(str, sizeof(str), "0x%06x %.2f%%", rendercount, (frendercount / fvromsize) * 100);
chrLoggedCodeLabel->setText(tr(str));
sprintf(str, "0x%06x %.2f%%", vromreadcount, (fvromreadcount / fvromsize) * 100);
snprintf(str, sizeof(str), "0x%06x %.2f%%", vromreadcount, (fvromreadcount / fvromsize) * 100);
chrLoggedDataLabel->setText(tr(str));
sprintf(str, "0x%06x %.2f%%", undefinedvromcount, (fundefinedvromcount / fvromsize) * 100);
snprintf(str, sizeof(str), "0x%06x %.2f%%", undefinedvromcount, (fundefinedvromcount / fvromsize) * 100);
chrUnloggedLabel->setText(tr(str));
}
else
@ -392,7 +392,7 @@ void CodeDataLoggerDialog_t::updatePeriodic(void)
chrUnloggedLabel->setText(tr("------"));
}
sprintf(str, "CDL File: %s", loadedcdfile);
snprintf(str, sizeof(str), "CDL File: %s", loadedcdfile);
cdlFileLabel->setText(tr(str));
}
@ -476,10 +476,10 @@ void CodeDataLoggerDialog_t::saveCdlFileAs(void)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
FCEU_WRAPPER_LOCK();
strcpy(loadedcdfile, filename.toStdString().c_str());
strcpy(loadedcdfile, filename.toLocal8Bit().constData());
SaveCDLogFile();
FCEU_WRAPPER_UNLOCK();
}
@ -531,10 +531,10 @@ void CodeDataLoggerDialog_t::loadCdlFile(void)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
FCEU_WRAPPER_LOCK();
LoadCDLog(filename.toStdString().c_str());
LoadCDLog(filename.toLocal8Bit().constData());
FCEU_WRAPPER_UNLOCK();
return;
@ -615,9 +615,9 @@ void CodeDataLoggerDialog_t::SaveStrippedROM(int invert)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
FILE *fp = fopen(filename.toStdString().c_str(), "wb");
FILE *fp = fopen(filename.toLocal8Bit().constData(), "wb");
if (!fp)
{
FCEUD_PrintError("Error opening target stripped rom file!");

View File

@ -73,7 +73,7 @@ void ColorMenuItem::setImageColor( QColor c )
lastColor = c;
b = parentWidget()->palette().color(QPalette::WindowText);
b = qobject_cast<QWidget*>(parent())->palette().color(QPalette::WindowText);
i=0;
@ -119,9 +119,9 @@ void ColorMenuItem::pickerClosed(int ret)
colorText = colorPtr->name();
//printf("Saving '%s' = Color string '%s'\n", confName.c_str(), colorText.toStdString().c_str() );
//printf("Saving '%s' = Color string '%s'\n", confName.c_str(), colorText.toLocal8Bit().constData() );
g_config->setOption( confName, colorText.toStdString().c_str() );
g_config->setOption( confName, colorText.toLocal8Bit().constData() );
g_config->save();
}
@ -140,7 +140,7 @@ void ColorMenuItem::openColorPicker(void)
qs = title;
qs.replace( "&", "", Qt::CaseInsensitive); // get rid of & accelerator characters
picker = new ColorMenuPickerDialog_t( colorPtr, qs.toStdString().c_str(), parentWidget() );
picker = new ColorMenuPickerDialog_t( colorPtr, qs.toLocal8Bit().constData(), qobject_cast<QWidget*>(parent()) );
picker->show();
@ -167,7 +167,7 @@ ColorMenuPickerDialog_t::ColorMenuPickerDialog_t( QColor *c, const char *titleTe
style = this->style();
sprintf( stmp, "Pick Color for %s", titleText);
snprintf( stmp, sizeof(stmp), "Pick Color for %s", titleText);
setWindowTitle( stmp );

View File

@ -150,7 +150,7 @@ ConsoleDebugger::ConsoleDebugger(QWidget *parent)
tabView[i][j] = new DebuggerTabWidget(i,j);
sprintf( stmp, "debuggerTabView%i%i\n", i+1, j+1 );
snprintf( stmp, sizeof(stmp), "debuggerTabView%i%i\n", i+1, j+1 );
tabView[i][j]->setObjectName( tr(stmp) );
@ -352,7 +352,7 @@ void ConsoleDebugger::ld65ImportDebug(void)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
if (debugSymbolTable.numSymbols() > 0)
{
@ -371,7 +371,7 @@ void ConsoleDebugger::ld65ImportDebug(void)
debugSymbolTable.loadRegisterMap();
debugSymbolTable.ld65LoadDebugFile( filename.toStdString().c_str() );
debugSymbolTable.ld65LoadDebugFile( filename.toLocal8Bit().constData() );
queueUpdate(QAsmView::UPDATE_ALL);
@ -1553,7 +1553,7 @@ void ConsoleDebugger::loadDisplayViews(void)
for (int j=0; j<4; j++)
{
QString tabListVal;
sprintf( key, "debugger/tabView%i%i", i+1, j+1 );
snprintf( key, sizeof(key), "debugger/tabView%i%i", i+1, j+1 );
tabListVal = settings.value(key).toString();
QStringList tabList = tabListVal.split(',');
@ -1561,7 +1561,7 @@ void ConsoleDebugger::loadDisplayViews(void)
{
if ( tabList[k].size() > 0 )
{
//printf(" %i: %s\n", k, tabList[k].toStdString().c_str() );
//printf(" %i: %s\n", k, tabList[k].toLocal8Bit().constData() );
if ( tabList[k].compare( cpuFrame->objectName() ) == 0 )
{
@ -1610,7 +1610,7 @@ void ConsoleDebugger::loadDisplayViews(void)
// Save Vertical Panel State
for (int i=0; i<2; i++)
{
sprintf( key, "debugger/vPanelState%i", i+1);
snprintf( key, sizeof(key), "debugger/vPanelState%i", i+1);
vsplitter[i]->restoreState( settings.value(key).toByteArray() );
}
@ -1628,18 +1628,18 @@ void ConsoleDebugger::saveDisplayViews(void)
for (int j=0; j<4; j++)
{
QString tabListVal;
sprintf( key, "debugger/tabView%i%i", i+1, j+1 );
snprintf( key, sizeof(key), "debugger/tabView%i%i", i+1, j+1 );
for (int k=0; k<tabView[i][j]->count(); k++)
{
QWidget *w = tabView[i][j]->widget(k);
//printf("(%i,%i,%i) %s\n", i, j, k, w->objectName().toStdString().c_str() );
//printf("(%i,%i,%i) %s\n", i, j, k, w->objectName().toLocal8Bit().constData() );
tabListVal += w->objectName() + ",";
}
//printf("(%i,%i) %s\n", i, j, tabListVal.toStdString().c_str() );
//printf("(%i,%i) %s\n", i, j, tabListVal.toLocal8Bit().constData() );
settings.setValue( key, tabListVal );
}
}
@ -1650,7 +1650,7 @@ void ConsoleDebugger::saveDisplayViews(void)
// Save Vertical Panel State
for (int i=0; i<2; i++)
{
sprintf( key, "debugger/vPanelState%i", i+1);
snprintf( key, sizeof(key), "debugger/vPanelState%i", i+1);
settings.setValue( key, vsplitter[i]->saveState());
}
@ -1711,7 +1711,7 @@ void ConsoleDebugger::moveTab( QWidget *w, int row, int column)
QString txt = p->tabBar()->tabText( idx );
p->removeTab( idx );
tabView[column][row]->addTab(w, txt);
//printf("Move Widget %p to (%i,%i) %s\n", w, row, column, txt.toStdString().c_str() );
//printf("Move Widget %p to (%i,%i) %s\n", w, row, column, txt.toLocal8Bit().constData() );
}
updateTabVisibility();
}
@ -1830,7 +1830,7 @@ void ConsoleDebugger::bmItemDoubleClicked( QTreeWidgetItem *item, int column)
//printf("Row: %i Column: %i \n", row, column );
addr = strtol( item->text(0).toStdString().c_str(), NULL, 16 );
addr = strtol( item->text(0).toLocal8Bit().constData(), NULL, 16 );
line = asmView->getAsmLineFromAddr( addr );
@ -1839,7 +1839,7 @@ void ConsoleDebugger::bmItemDoubleClicked( QTreeWidgetItem *item, int column)
//----------------------------------------------------------------------------
void ConsoleDebugger::selBmAddrChanged(const QString &txt)
{
selBmAddrVal = strtol( txt.toStdString().c_str(), NULL, 16 );
selBmAddrVal = strtol( txt.toLocal8Bit().constData(), NULL, 16 );
//printf("selBmAddrVal = %04X\n", selBmAddrVal );
}
@ -1981,13 +1981,13 @@ DebuggerBreakpointEditor::DebuggerBreakpointEditor(int editIndex, watchpointinfo
rom_radio->setChecked(true);
}
sprintf( stmp, "%04X", wp->address );
snprintf( stmp, sizeof(stmp), "%04X", wp->address );
addr1->setText( tr(stmp) );
if ( wp->endaddress > 0 )
{
sprintf( stmp, "%04X", wp->endaddress );
snprintf( stmp, sizeof(stmp), "%04X", wp->endaddress );
addr2->setText( tr(stmp) );
}
@ -2032,14 +2032,14 @@ DebuggerBreakpointEditor::DebuggerBreakpointEditor(int editIndex, watchpointinfo
if ( romAddr >= 0 )
{
wp->address = romAddr;
sprintf( stmp, "%X", wp->address );
snprintf( stmp, sizeof(stmp), "%X", wp->address );
addr1->setText( tr(stmp) );
rom_radio->setChecked(true);
}
else
{
char str[64];
sprintf(str, "K==#%02X", getBank(wp->address));
snprintf(str, sizeof(str), "K==#%02X", getBank(wp->address));
cond->setText( tr(str) );
}
}
@ -2129,7 +2129,7 @@ void DebuggerBreakpointEditor::checkDataValid(void)
{
bool convOk = false;
start_addr = offsetStringToInt( type, addr1->text().toStdString().c_str(), &convOk );
start_addr = offsetStringToInt( type, addr1->text().toLocal8Bit().constData(), &convOk );
//printf("StartAddr:0x%04X Upper:0x%04X\n", start_addr, addrUpperBound);
startAddrValid = convOk && (start_addr >= addrLowerBound) && (start_addr < addrUpperBound);
@ -2143,7 +2143,7 @@ void DebuggerBreakpointEditor::checkDataValid(void)
{
bool convOk = false;
end_addr = offsetStringToInt( type, addr2->text().toStdString().c_str(), &convOk );
end_addr = offsetStringToInt( type, addr2->text().toLocal8Bit().constData(), &convOk );
endAddrValid = convOk && (end_addr >= addrLowerBound) &&
(end_addr < addrUpperBound) && (start_addr < end_addr);
@ -2196,7 +2196,7 @@ void DebuggerBreakpointEditor::conditionTextChanged(const QString &txt)
{
if ( txt.size() > 0 )
{
Condition *c = generateCondition( txt.toStdString().c_str() );
Condition *c = generateCondition( txt.toLocal8Bit().constData() );
condValid = (c != nullptr);
@ -2238,14 +2238,14 @@ void DebuggerBreakpointEditor::loadBreakpoint(void)
type |= BT_R;
}
s = addr1->text().toStdString();
s = addr1->text().toLocal8Bit().constData();
if ( s.size() > 0 )
{
start_addr = offsetStringToInt( type, s.c_str() );
}
s = addr2->text().toStdString();
s = addr2->text().toLocal8Bit().constData();
if ( s.size() > 0 )
{
@ -2277,8 +2277,8 @@ void DebuggerBreakpointEditor::loadBreakpoint(void)
unsigned int retval;
std::string nameString, condString;
nameString = name->text().toStdString();
condString = cond->text().toStdString();
nameString = name->text().toLocal8Bit().constData();
condString = cond->text().toLocal8Bit().constData();
retval = NewBreak( nameString.c_str(), start_addr, end_addr, type, condString.c_str(), slot, enable);
@ -2388,11 +2388,11 @@ void ConsoleDebugger::bpListUpdate( bool reset )
if ( watchpoint[i].endaddress > 0 )
{
sprintf( addrStr, "$%04X-%04X:", watchpoint[i].address, watchpoint[i].endaddress );
snprintf( addrStr, sizeof(addrStr), "$%04X-%04X:", watchpoint[i].address, watchpoint[i].endaddress );
}
else
{
sprintf( addrStr, "$%04X:", watchpoint[i].address );
snprintf( addrStr, sizeof(addrStr), "$%04X:", watchpoint[i].address );
}
flags[0] = (watchpoint[i].flags & WP_E) ? 'E' : '-';
@ -2478,7 +2478,7 @@ void ConsoleDebugger::edit_BM_CB(void)
printf( "No Item Selected\n");
return;
}
s = item->text(0).toStdString();
s = item->text(0).toLocal8Bit().constData();
addr = strtol( s.c_str(), NULL, 16 );
@ -2499,7 +2499,7 @@ void ConsoleDebugger::delete_BM_CB(void)
printf( "No Item Selected\n");
return;
}
s = item->text(0).toStdString();
s = item->text(0).toLocal8Bit().constData();
addr = strtol( s.c_str(), NULL, 16 );
@ -2519,7 +2519,7 @@ void ConsoleDebugger::edit_BM_name( int addr )
bm = dbgBmMgr.getAddr( addr );
sprintf( stmp, "Specify Bookmark Name for %04X", addr );
snprintf( stmp, sizeof(stmp), "Specify Bookmark Name for %04X", addr );
dialog.setWindowTitle( tr("Edit Bookmark") );
dialog.setLabelText( tr(stmp) );
@ -2534,7 +2534,7 @@ void ConsoleDebugger::edit_BM_name( int addr )
if ( QDialog::Accepted == ret )
{
bm->name = dialog.textValue().toStdString();
bm->name = dialog.textValue().toLocal8Bit().constData();
bmListUpdate(false);
}
}
@ -2571,7 +2571,7 @@ void ConsoleDebugger::bmListUpdate( bool reset )
bmTree->addTopLevelItem( item );
}
sprintf( addrStr, "%04X", bm->addr );
snprintf( addrStr, sizeof(addrStr), "%04X", bm->addr );
//item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsUserCheckable );
item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren );
@ -2764,7 +2764,7 @@ void ConsoleDebugger::breakOnCyclesCB( bool value )
break_on_cycles = value;
}
//s = cpuCycExdVal->text().toStdString();
//s = cpuCycExdVal->text().toLocal8Bit().constData();
//printf("'%s'\n", txt );
@ -2778,7 +2778,7 @@ void ConsoleDebugger::cpuCycleThresChanged(const QString &txt)
{
std::string s;
s = txt.toStdString();
s = txt.toLocal8Bit().constData();
//printf("Cycles: '%s'\n", s.c_str() );
@ -2802,7 +2802,7 @@ void ConsoleDebugger::breakOnInstructionsCB( bool value )
break_on_instructions = value;
}
//s = instrExdVal->text().toStdString();
//s = instrExdVal->text().toLocal8Bit().constData();
//printf("'%s'\n", txt );
@ -2816,7 +2816,7 @@ void ConsoleDebugger::instructionsThresChanged(const QString &txt)
{
std::string s;
s = txt.toStdString();
s = txt.toLocal8Bit().constData();
//printf("Instructions: '%s'\n", s.c_str() );
@ -2896,9 +2896,9 @@ void ConsoleDebugger::changeAsmFontCB(void)
asmView->setFont( selFont );
asmView->updateAssemblyView();
//printf("Font Changed to: '%s'\n", font.toString().toStdString().c_str() );
//printf("Font Changed to: '%s'\n", font.toString().toLocal8Bit().constData() );
g_config->setOption("SDL.DebuggerAsmFont", selFont.toString().toStdString().c_str() );
g_config->setOption("SDL.DebuggerAsmFont", selFont.toString().toLocal8Bit().constData() );
}
}
//----------------------------------------------------------------------------
@ -2912,9 +2912,9 @@ void ConsoleDebugger::changeStackFontCB(void)
{
stackText->setFont( selFont );
//printf("Font Changed to: '%s'\n", font.toString().toStdString().c_str() );
//printf("Font Changed to: '%s'\n", font.toString().toLocal8Bit().constData() );
g_config->setOption("SDL.DebuggerStackFont", selFont.toString().toStdString().c_str() );
g_config->setOption("SDL.DebuggerStackFont", selFont.toString().toLocal8Bit().constData() );
}
}
//----------------------------------------------------------------------------
@ -2930,9 +2930,9 @@ void ConsoleDebugger::changeCpuFontCB(void)
setCpuStatusFont( selFont );
setPpuStatusFont( selFont );
//printf("Font Changed to: '%s'\n", font.toString().toStdString().c_str() );
//printf("Font Changed to: '%s'\n", font.toString().toLocal8Bit().constData() );
g_config->setOption("SDL.DebuggerCpuStatusFont", selFont.toString().toStdString().c_str() );
g_config->setOption("SDL.DebuggerCpuStatusFont", selFont.toString().toLocal8Bit().constData() );
}
}
//----------------------------------------------------------------------------
@ -3148,7 +3148,7 @@ void ConsoleDebugger::debugRunLine128CB(void)
//{
// std::string s;
//
// s = seekEntry->displayText().toStdString();
// s = seekEntry->displayText().toLocal8Bit().constData();
//
// //printf("Seek To: '%s'\n", s.c_str() );
//
@ -3501,7 +3501,7 @@ void ConsoleDebugger::setBookmarkSelectedAddress( int addr )
{
char stmp[32];
sprintf( stmp, "%04X", addr );
snprintf( stmp, sizeof(stmp), "%04X", addr );
selBmAddr->setText( tr(stmp) );
@ -3947,16 +3947,16 @@ void QAsmView::updateAssemblyView(void)
if (displayROMoffsets && (a->rom != -1) )
{
sprintf(chr, " %06X: ", a->rom);
snprintf(chr, sizeof(chr), " %06X: ", a->rom);
}
else
{
sprintf(chr, "%02X:%04X: ", a->bank, addr);
snprintf(chr, sizeof(chr), "%02X:%04X: ", a->bank, addr);
}
}
else
{
sprintf(chr, " :%04X: ", addr);
snprintf(chr, sizeof(chr), " :%04X: ", addr);
}
line.append(chr);
@ -3964,7 +3964,7 @@ void QAsmView::updateAssemblyView(void)
if (size == 0)
{
sprintf(chr, "%02X UNDEFINED", GetMem(addr++));
snprintf(chr, sizeof(chr), "%02X UNDEFINED", GetMem(addr++));
line.append(chr);
}
else
@ -3973,7 +3973,7 @@ void QAsmView::updateAssemblyView(void)
{
while (addr < 0xFFFF)
{
sprintf(chr, "%02X OVERFLOW\n", GetMem(addr++));
snprintf(chr, sizeof(chr), "%02X OVERFLOW\n", GetMem(addr++));
line.append(chr);
}
delete a;
@ -3981,7 +3981,7 @@ void QAsmView::updateAssemblyView(void)
}
for (int j = 0; j < size; j++)
{
sprintf(chr, "%02X ", opcode[j] = GetMem(addr++));
snprintf(chr, sizeof(chr), "%02X ", opcode[j] = GetMem(addr++));
if ( showByteCodes ) line.append(chr);
}
while (size < 3)
@ -4122,7 +4122,7 @@ void ConsoleDebugger::setRegsFromEntry(void)
std::string s;
long int i;
s = pcEntry->displayText().toStdString();
s = pcEntry->displayText().toLocal8Bit().constData();
if ( s.size() > 0 )
{
@ -4135,7 +4135,7 @@ void ConsoleDebugger::setRegsFromEntry(void)
X.PC = i;
//printf("Set PC: '%s' %04X\n", s.c_str(), X.PC );
s = regAEntry->displayText().toStdString();
s = regAEntry->displayText().toLocal8Bit().constData();
if ( s.size() > 0 )
{
@ -4148,7 +4148,7 @@ void ConsoleDebugger::setRegsFromEntry(void)
X.A = i;
//printf("Set A: '%s' %02X\n", s.c_str(), X.A );
s = regXEntry->displayText().toStdString();
s = regXEntry->displayText().toLocal8Bit().constData();
if ( s.size() > 0 )
{
@ -4161,7 +4161,7 @@ void ConsoleDebugger::setRegsFromEntry(void)
X.X = i;
//printf("Set X: '%s' %02X\n", s.c_str(), X.X );
s = regYEntry->displayText().toStdString();
s = regYEntry->displayText().toLocal8Bit().constData();
if ( s.size() > 0 )
{
@ -4217,23 +4217,23 @@ void ConsoleDebugger::updateRegisterView(void)
char stmp[64];
char str[32], str2[32];
sprintf( stmp, "%04X", X.PC );
snprintf( stmp, sizeof(stmp), "%04X", X.PC );
pcEntry->setText( tr(stmp) );
sprintf( stmp, "%02X", X.A );
snprintf( stmp, sizeof(stmp), "%02X", X.A );
regAEntry->setText( tr(stmp) );
sprintf( stmp, "%02X", X.X );
snprintf( stmp, sizeof(stmp), "%02X", X.X );
regXEntry->setText( tr(stmp) );
sprintf( stmp, "%02X", X.Y );
snprintf( stmp, sizeof(stmp), "%02X", X.Y );
regYEntry->setText( tr(stmp) );
sprintf( stmp, "%02X", X.P );
snprintf( stmp, sizeof(stmp), "%02X", X.P );
regPEntry->setText( tr(stmp) );
@ -4248,7 +4248,7 @@ void ConsoleDebugger::updateRegisterView(void)
stackPtr = X.S | 0x0100;
sprintf( stmp, "Stack: $%04X", stackPtr );
snprintf( stmp, sizeof(stmp), "Stack: $%04X", stackPtr );
stackFrame->setTitle( tr(stmp) );
stackText->updateText();
@ -4266,26 +4266,26 @@ void ConsoleDebugger::updateRegisterView(void)
ResetDebugStatisticsCounters();
counter_value2 = 0;
}
sprintf(stmp, "%10llu (+%llu)", counter_value1, counter_value2);
snprintf(stmp, sizeof(stmp), "%10llu (+%llu)", counter_value1, counter_value2);
cpuCyclesVal->setText( tr(stmp) );
sprintf(stmp, "%10llu (+%llu)", total_instructions, delta_instructions);
snprintf(stmp, sizeof(stmp), "%10llu (+%llu)", total_instructions, delta_instructions);
cpuInstrsVal->setText( tr(stmp) );
// PPU Labels
sprintf(stmp, "$%02X", PPU[0] );
snprintf(stmp, sizeof(stmp), "$%02X", PPU[0] );
ppuCtrlReg->setText( tr(stmp) );
sprintf(stmp, "$%02X", PPU[1] );
snprintf(stmp, sizeof(stmp), "$%02X", PPU[1] );
ppuMaskReg->setText( tr(stmp) );
sprintf(stmp, "$%02X", PPU[2] );
snprintf(stmp, sizeof(stmp), "$%02X", PPU[2] );
ppuStatReg->setText( tr(stmp) );
sprintf(stmp, "$%04X", (int)FCEUPPU_PeekAddress());
snprintf(stmp, sizeof(stmp), "$%04X", (int)FCEUPPU_PeekAddress());
ppuAddrDsp->setText( tr(stmp) );
sprintf(stmp, "$%02X", PPU[3] );
snprintf(stmp, sizeof(stmp), "$%02X", PPU[3] );
oamAddrDsp->setText( tr(stmp) );
extern int linestartts;
@ -4302,41 +4302,41 @@ void ConsoleDebugger::updateRegisterView(void)
if (!vblankScanLines)
{
// Idle scanline (240)
sprintf(str, "%d", scanline); // was "Idle %d"
snprintf(str, sizeof(str), "%d", scanline); // was "Idle %d"
} else if (scanline + vblankScanLines == (PAL?311:261))
{
// Pre-render
sprintf(str, "-1"); // was "Prerender -1"
snprintf(str, sizeof(str), "-1"); // was "Prerender -1"
} else
{
// Vblank lines (241-260/310)
sprintf(str, "%d", scanline + vblankScanLines); // was "Vblank %d"
snprintf(str, sizeof(str), "%d", scanline + vblankScanLines); // was "Vblank %d"
}
sprintf(str2, "%d", vblankPixel);
snprintf(str2, sizeof(str2), "%d", vblankPixel);
} else
{
// Scanlines 0 - 239
sprintf(str, "%d", scanline);
sprintf(str2, "%d", ppupixel);
snprintf(str, sizeof(str), "%d", scanline);
snprintf(str2, sizeof(str2), "%d", ppupixel);
}
if(newppu)
{
sprintf(str ,"%d",newppu_get_scanline());
sprintf(str2,"%d",newppu_get_dot());
snprintf(str , sizeof(str), "%d",newppu_get_scanline());
snprintf(str2, sizeof(str2), "%d",newppu_get_dot());
}
sprintf( stmp, "%s", str );
snprintf( stmp, sizeof(stmp), "%s", str );
ppuScanLineDsp->setText( tr(stmp) );
sprintf( stmp, "%s", str2 );
snprintf( stmp, sizeof(stmp), "%s", str2 );
ppuPixelDsp->setText( tr(stmp) );
int ppuScrollPosX, ppuScrollPosY;
ppu_getScroll( ppuScrollPosX, ppuScrollPosY);
sprintf( stmp, "%i", ppuScrollPosX );
snprintf( stmp, sizeof(stmp), "%i", ppuScrollPosX );
ppuScrollX->setText( tr(stmp) );
sprintf( stmp, "%i", ppuScrollPosY );
snprintf( stmp, sizeof(stmp), "%i", ppuScrollPosY );
ppuScrollY->setText( tr(stmp) );
}
//----------------------------------------------------------------------------
@ -4415,7 +4415,7 @@ void ConsoleDebugger::updatePeriodic(void)
if ( lastBpIdx >= 0 )
{
char stmp[128];
sprintf( stmp, " Emulator Stopped / Paused at Breakpoint: %i", lastBpIdx );
snprintf( stmp, sizeof(stmp), " Emulator Stopped / Paused at Breakpoint: %i", lastBpIdx );
emuStatLbl->setText( tr(stmp) );
}
else
@ -4892,7 +4892,7 @@ void loadGameDebugBreakpoints(void)
if ( fp == NULL )
{
printf("Warning: Failed to open file '%s' for reading\n", fileName.c_str() );
//printf("Warning: Failed to open file '%s' for reading\n", fileName.c_str() );
return;
}
@ -5374,7 +5374,7 @@ void QAsmView::setSelAddrToLine( int line )
selAddrWidth = 4;
selAddrValue = addr;
selAddrType = 0;
sprintf( selAddrText, "%04X", addr );
snprintf( selAddrText, sizeof(selAddrText), "%04X", addr );
if ( parent )
@ -5598,7 +5598,7 @@ bool QAsmView::event(QEvent *event)
}
else if ( showSymHexDecode )
{
sprintf( stmp, "$%04X", asmEntry[line]->sym.offset() );
snprintf( stmp, sizeof(stmp), "$%04X", asmEntry[line]->sym.offset() );
QToolTip::showText(helpEvent->globalPos(), tr(stmp), this );
}
@ -5606,11 +5606,11 @@ bool QAsmView::event(QEvent *event)
{
if ( asmEntry[line]->bank < 0 )
{
sprintf( stmp, "ADDR:\t$%04X", asmEntry[line]->addr );
snprintf( stmp, sizeof(stmp), "ADDR:\t$%04X", asmEntry[line]->addr );
}
else
{
sprintf( stmp, "ADDR:\t$%04X\nBANK:\t$%02X\nROM:\t$%06X",
snprintf( stmp, sizeof(stmp), "ADDR:\t$%04X\nBANK:\t$%02X\nROM:\t$%06X",
asmEntry[line]->addr, asmEntry[line]->bank, asmEntry[line]->rom );
}
@ -5631,11 +5631,11 @@ bool QAsmView::event(QEvent *event)
if ( bank < 0 )
{
sprintf( stmp, "ADDR:\t$%04X", addr );
snprintf( stmp, sizeof(stmp), "ADDR:\t$%04X", addr );
}
else
{
sprintf( stmp, "ADDR:\t$%04X\nBANK:\t$%02X\nROM:\t$%06X",
snprintf( stmp, sizeof(stmp), "ADDR:\t$%04X\nBANK:\t$%02X\nROM:\t$%06X",
addr, bank, romOfs );
}
@ -5909,7 +5909,7 @@ void QAsmView::mouseMoveEvent(QMouseEvent * event)
bank = getBank(addr);
romOfs = GetNesFileAddress(addr);
sprintf( txt, "CPU Address: %02X:%04X", bank, addr);
snprintf( txt, sizeof(txt), "CPU Address: %02X:%04X", bank, addr);
s.assign( txt );
@ -5923,14 +5923,14 @@ void QAsmView::mouseMoveEvent(QMouseEvent * event)
{
fileName = "...";
}
sprintf( txt, "\nOffset 0x%06X in File \"%s\" (NL file: %X)", romOfs, fileName, bank);
snprintf( txt, sizeof(txt), "\nOffset 0x%06X in File \"%s\" (NL file: %X)", romOfs, fileName, bank);
s.append( txt );
}
}
else
{
sprintf( txt, "CPU Address: %04X", addr);
snprintf( txt, sizeof(txt), "CPU Address: %04X", addr);
s.assign( txt );
}
@ -6212,13 +6212,13 @@ void QAsmView::mousePressEvent(QMouseEvent * event)
if ( selAddrType )
{
sprintf( selAddrText, "%06X", addr );
snprintf( selAddrText, sizeof(selAddrText), "%06X", addr );
selAddrWidth = 6;
selAddrChar = pcLocLinePos+1;
}
else
{
sprintf( selAddrText, "%04X", addr );
snprintf( selAddrText, sizeof(selAddrText), "%04X", addr );
selAddrWidth = 4;
selAddrChar = pcLocLinePos+3;
}
@ -6357,7 +6357,7 @@ void QAsmView::contextMenuEvent(QContextMenuEvent *event)
if ( ctxMenuAddrType == 0 )
{
sprintf( stmp, "Go to $%04X\tDouble+Click", ctxMenuAddr );
snprintf( stmp, sizeof(stmp), "Go to $%04X\tDouble+Click", ctxMenuAddr );
act = new QAction(tr(stmp), &menu);
menu.addAction(act);
//act->setShortcut( QKeySequence(tr("Ctrl+F10")));
@ -7105,7 +7105,7 @@ void DebuggerStackDisplay::contextMenuEvent(QContextMenuEvent *event)
{
char stmp[8];
sprintf( stmp, "%i", i+1 );
snprintf( stmp, sizeof(stmp), "%i", i+1 );
bytesPerLineAct[i] = new QAction(tr(stmp), &menu);
bytesPerLineAct[i]->setCheckable(true);
@ -7172,11 +7172,11 @@ void DebuggerStackDisplay::updateText(void)
{
if ( showAddrs || (stackBytesPerLine <= 1) )
{
sprintf( stmp, "%03X: %02X", stackPtr, GetMem(stackPtr) );
snprintf( stmp, sizeof(stmp), "%03X: %02X", stackPtr, GetMem(stackPtr) );
}
else
{
sprintf( stmp, "%02X", GetMem(stackPtr) );
snprintf( stmp, sizeof(stmp), "%02X", GetMem(stackPtr) );
}
stackLine.assign( stmp );
@ -7194,21 +7194,21 @@ void DebuggerStackDisplay::updateText(void)
{
if ( showAddrs )
{
sprintf( stmp, "\n%03X: %02X", stackPtr, GetMem(stackPtr) );
snprintf( stmp, sizeof(stmp), "\n%03X: %02X", stackPtr, GetMem(stackPtr) );
}
else
{
sprintf( stmp, "\n%02X", GetMem(stackPtr) );
snprintf( stmp, sizeof(stmp), "\n%02X", GetMem(stackPtr) );
}
}
else
{
sprintf( stmp, ",%02X", GetMem(stackPtr) );
snprintf( stmp, sizeof(stmp), ",%02X", GetMem(stackPtr) );
}
}
else
{
sprintf( stmp, "\n%03X: %02X", stackPtr, GetMem(stackPtr) );
snprintf( stmp, sizeof(stmp), "\n%03X: %02X", stackPtr, GetMem(stackPtr) );
}
stackLine.append( stmp );
@ -7312,11 +7312,11 @@ asmLookAheadPopup::asmLookAheadPopup( int addr, QWidget *parent )
hbox = new QHBoxLayout();
vbox->addLayout( hbox );
sprintf( stmp, "%02X : $%04X", bank, addr );
snprintf( stmp, sizeof(stmp), "%02X : $%04X", bank, addr );
cpuAddr->setText( tr(stmp) );
sprintf( stmp, "#$%02X", GetMem(addr) );
snprintf( stmp, sizeof(stmp), "#$%02X", GetMem(addr) );
cpuVal->setText( tr(stmp) );
sprintf( stmp, "$%06X", romOfs );
snprintf( stmp, sizeof(stmp), "$%06X", romOfs );
romAddr->setText( tr(stmp) );
lbl = new QLabel( tr("CPU ADDR:") );
@ -7343,9 +7343,9 @@ asmLookAheadPopup::asmLookAheadPopup( int addr, QWidget *parent )
hbox = new QHBoxLayout();
vbox->addLayout( hbox );
sprintf( stmp, "$%04X", addr );
snprintf( stmp, sizeof(stmp), "$%04X", addr );
cpuAddr->setText( tr(stmp) );
sprintf( stmp, "#$%02X", GetMem(addr) );
snprintf( stmp, sizeof(stmp), "#$%02X", GetMem(addr) );
cpuVal->setText( tr(stmp) );
lbl = new QLabel( tr("CPU ADDR:") );
@ -7502,10 +7502,10 @@ ppuRegPopup::ppuRegPopup( QWidget *parent )
sprite0hit_cbox = new QCheckBox( tr("Sprite 0 Hit") );
spriteOvrflw_cbox = new QCheckBox( tr("Sprite Overflow") );
sprintf( stmp, "$%04X", 0x2000 + (0x400*(PPU[0] & 0x03)));
snprintf( stmp, sizeof(stmp), "$%04X", 0x2000 + (0x400*(PPU[0] & 0x03)));
ppuBgAddr->setText( tr(stmp) );
sprintf( stmp, "$%04X", (PPU[0] & 0x08) ? 0x1000 : 0x0000 );
snprintf( stmp, sizeof(stmp), "$%04X", (PPU[0] & 0x08) ? 0x1000 : 0x0000 );
ppuSprAddr->setText( tr(stmp) );
nmiBlank_cbox->setChecked( PPU[0] & 0x80 );
@ -7865,7 +7865,7 @@ DebugBreakOnDialog::DebugBreakOnDialog(int type, QWidget *parent )
refMode = breakOnInstrMode;
threshold = break_instructions_limit;
sprintf(stmp, "Current Instruction Count: %10llu (+%llu)", totalCount, deltaCount);
snprintf(stmp, sizeof(stmp), "Current Instruction Count: %10llu (+%llu)", totalCount, deltaCount);
currLbl->setText( tr(stmp) );
}
@ -7889,7 +7889,7 @@ DebugBreakOnDialog::DebugBreakOnDialog(int type, QWidget *parent )
refMode = breakOnCycleMode;
threshold = break_cycles_limit;
sprintf(stmp, "Current Cycle Count: %10llu (+%llu)", totalCount, deltaCount);
snprintf(stmp, sizeof(stmp), "Current Cycle Count: %10llu (+%llu)", totalCount, deltaCount);
currLbl->setText( tr(stmp) );
}
@ -7969,7 +7969,7 @@ DebugBreakOnDialog::DebugBreakOnDialog(int type, QWidget *parent )
grid->addWidget( btn, row, 4-(col*2) );
sprintf( stmp, "%+i%c", -bb, c);
snprintf( stmp, sizeof(stmp), "%+i%c", -bb, c);
btn->setText( tr(stmp) );
@ -7979,7 +7979,7 @@ DebugBreakOnDialog::DebugBreakOnDialog(int type, QWidget *parent )
grid->addWidget( btn, row, 4-(col*2)+1 );
sprintf( stmp, "%+i%c", bb, c);
snprintf( stmp, sizeof(stmp), "%+i%c", bb, c);
btn->setText( tr(stmp) );
@ -8118,7 +8118,7 @@ void DebugBreakOnDialog::updateCurrent(void)
totalCount = total_instructions;
deltaCount = delta_instructions;
sprintf(stmp, "Current Instruction Count: %10llu (+%llu)", totalCount, deltaCount);
snprintf(stmp, sizeof(stmp), "Current Instruction Count: %10llu (+%llu)", totalCount, deltaCount);
currLbl->setText( tr(stmp) );
}
@ -8137,7 +8137,7 @@ void DebugBreakOnDialog::updateCurrent(void)
ResetDebugStatisticsCounters();
deltaCount = 0;
}
sprintf(stmp, "Current Cycle Count: %10llu (+%llu)", totalCount, deltaCount);
snprintf(stmp, sizeof(stmp), "Current Cycle Count: %10llu (+%llu)", totalCount, deltaCount);
currLbl->setText( tr(stmp) );
}
@ -8195,7 +8195,7 @@ void DebugBreakOnDialog::setThreshold( unsigned long long int val )
threshold = val;
sprintf( stmp, "%llu", threshold );
snprintf( stmp, sizeof(stmp), "%llu", threshold );
countEntryBox->setText( tr(stmp) );
@ -8204,7 +8204,7 @@ void DebugBreakOnDialog::setThreshold( unsigned long long int val )
//----------------------------------------------------------------------------
void DebugBreakOnDialog::setThreshold( const QString &text )
{
threshold = strtoull( text.toStdString().c_str(), NULL, 10 );
threshold = strtoull( text.toLocal8Bit().constData(), NULL, 10 );
updateLabel();
}
@ -8229,11 +8229,11 @@ void DebugBreakOnDialog::updateLabel(void)
if ( delta > 0 )
{
sprintf( stmp, "Will break in %lli CPU Instruction%s", delta, (delta > 1) ? "s":"" );
snprintf( stmp, sizeof(stmp), "Will break in %lli CPU Instruction%s", delta, (delta > 1) ? "s":"" );
}
else
{
sprintf( stmp, "Will break immediately, CPU instruction count already exceeds value by %lli.", -delta);
snprintf( stmp, sizeof(stmp), "Will break immediately, CPU instruction count already exceeds value by %lli.", -delta);
}
}
else
@ -8242,11 +8242,11 @@ void DebugBreakOnDialog::updateLabel(void)
if ( delta > 0 )
{
sprintf( stmp, "Will break in %lli CPU Instruction%s", delta, (delta > 1) ? "s":"" );
snprintf( stmp, sizeof(stmp), "Will break in %lli CPU Instruction%s", delta, (delta > 1) ? "s":"" );
}
else
{
sprintf( stmp, "Will break immediately, CPU instruction count already exceeds value by %lli.", -delta);
snprintf( stmp, sizeof(stmp), "Will break immediately, CPU instruction count already exceeds value by %lli.", -delta);
}
}
}
@ -8258,11 +8258,11 @@ void DebugBreakOnDialog::updateLabel(void)
if ( delta > 0 )
{
sprintf( stmp, "Will break in %lli CPU cycle%s", delta, (delta > 1) ? "s":"" );
snprintf( stmp, sizeof(stmp), "Will break in %lli CPU cycle%s", delta, (delta > 1) ? "s":"" );
}
else
{
sprintf( stmp, "Will break immediately, CPU cycle count already exceeds value by %lli.", -delta);
snprintf( stmp, sizeof(stmp), "Will break immediately, CPU cycle count already exceeds value by %lli.", -delta);
}
}
else
@ -8271,11 +8271,11 @@ void DebugBreakOnDialog::updateLabel(void)
if ( delta > 0 )
{
sprintf( stmp, "Will break in %lli CPU cycle%s", delta, (delta > 1) ? "s":"" );
snprintf( stmp, sizeof(stmp), "Will break in %lli CPU cycle%s", delta, (delta > 1) ? "s":"" );
}
else
{
sprintf( stmp, "Will break immediately, CPU cycle count already exceeds value %lli.", -delta);
snprintf( stmp, sizeof(stmp), "Will break immediately, CPU cycle count already exceeds value %lli.", -delta);
}
}
}

View File

@ -189,10 +189,10 @@ ConsoleSndConfDialog_t::ConsoleSndConfDialog_t(QWidget *parent)
frame = new QGroupBox(tr("Triangle"));
vbox2 = new QVBoxLayout();
triLbl = new QLabel("255");
triLbl = new QLabel("256");
vslider = new QSlider(Qt::Vertical);
vslider->setMinimum(0);
vslider->setMaximum(255);
vslider->setMaximum(256);
setSliderFromProperty(vslider, triLbl, "SDL.Sound.TriangleVolume");
vbox2->addWidget(triLbl);
@ -204,10 +204,10 @@ ConsoleSndConfDialog_t::ConsoleSndConfDialog_t(QWidget *parent)
frame = new QGroupBox(tr("Square1"));
vbox2 = new QVBoxLayout();
sqr1Lbl = new QLabel("255");
sqr1Lbl = new QLabel("256");
vslider = new QSlider(Qt::Vertical);
vslider->setMinimum(0);
vslider->setMaximum(255);
vslider->setMaximum(256);
setSliderFromProperty(vslider, sqr1Lbl, "SDL.Sound.Square1Volume");
vbox2->addWidget(sqr1Lbl);
@ -219,10 +219,10 @@ ConsoleSndConfDialog_t::ConsoleSndConfDialog_t(QWidget *parent)
frame = new QGroupBox(tr("Square2"));
vbox2 = new QVBoxLayout();
sqr2Lbl = new QLabel("255");
sqr2Lbl = new QLabel("256");
sqr2Slider = new QSlider(Qt::Vertical);
sqr2Slider->setMinimum(0);
sqr2Slider->setMaximum(255);
sqr2Slider->setMaximum(256);
setSliderFromProperty(sqr2Slider, sqr2Lbl, "SDL.Sound.Square2Volume");
vbox2->addWidget(sqr2Lbl);
@ -234,10 +234,10 @@ ConsoleSndConfDialog_t::ConsoleSndConfDialog_t(QWidget *parent)
frame = new QGroupBox(tr("Noise"));
vbox2 = new QVBoxLayout();
nseLbl = new QLabel("255");
nseLbl = new QLabel("256");
nseSlider = new QSlider(Qt::Vertical);
nseSlider->setMinimum(0);
nseSlider->setMaximum(255);
nseSlider->setMaximum(256);
setSliderFromProperty(nseSlider, nseLbl, "SDL.Sound.NoiseVolume");
vbox2->addWidget(nseLbl);
@ -249,10 +249,10 @@ ConsoleSndConfDialog_t::ConsoleSndConfDialog_t(QWidget *parent)
frame = new QGroupBox(tr("PCM"));
vbox2 = new QVBoxLayout();
pcmLbl = new QLabel("255");
pcmLbl = new QLabel("256");
pcmSlider = new QSlider(Qt::Vertical);
pcmSlider->setMinimum(0);
pcmSlider->setMaximum(255);
pcmSlider->setMaximum(256);
setSliderFromProperty(pcmSlider, pcmLbl, "SDL.Sound.PCMVolume");
vbox2->addWidget(pcmLbl);
@ -332,7 +332,7 @@ void ConsoleSndConfDialog_t::periodicUpdate(void)
bufUsage->setValue( (int)(percBufUse) );
sprintf( stmp, "Sink Starve Count: %u", nes_shm->sndBuf.starveCounter );
snprintf( stmp, sizeof(stmp), "Sink Starve Count: %u", nes_shm->sndBuf.starveCounter );
starveLbl->setText( tr(stmp) );
@ -396,7 +396,7 @@ void ConsoleSndConfDialog_t::setSliderFromProperty(QSlider *slider, QLabel *lbl,
char stmp[32];
g_config->getOption(property, &pval);
slider->setValue(pval);
sprintf(stmp, "%i", pval);
snprintf(stmp, sizeof(stmp), "%i", pval);
lbl->setText(stmp);
}
//----------------------------------------------------
@ -404,7 +404,7 @@ void ConsoleSndConfDialog_t::bufSizeChanged(int value)
{
char stmp[32];
sprintf(stmp, "%i", value);
snprintf(stmp, sizeof(stmp), "%i", value);
bufSizeLabel->setText(stmp);
@ -422,7 +422,7 @@ void ConsoleSndConfDialog_t::volumeChanged(int value)
{
char stmp[32];
sprintf(stmp, "%i", value);
snprintf(stmp, sizeof(stmp), "%i", value);
volLbl->setText(stmp);
@ -439,7 +439,7 @@ void ConsoleSndConfDialog_t::triangleChanged(int value)
{
char stmp[32];
sprintf(stmp, "%i", value);
snprintf(stmp, sizeof(stmp), "%i", value);
triLbl->setText(stmp);
@ -456,7 +456,7 @@ void ConsoleSndConfDialog_t::square1Changed(int value)
{
char stmp[32];
sprintf(stmp, "%i", value);
snprintf(stmp, sizeof(stmp), "%i", value);
sqr1Lbl->setText(stmp);
@ -473,7 +473,7 @@ void ConsoleSndConfDialog_t::square2Changed(int value)
{
char stmp[32];
sprintf(stmp, "%i", value);
snprintf(stmp, sizeof(stmp), "%i", value);
sqr2Lbl->setText(stmp);
@ -490,7 +490,7 @@ void ConsoleSndConfDialog_t::noiseChanged(int value)
{
char stmp[32];
sprintf(stmp, "%i", value);
snprintf(stmp, sizeof(stmp), "%i", value);
nseLbl->setText(stmp);
@ -507,7 +507,7 @@ void ConsoleSndConfDialog_t::pcmChanged(int value)
{
char stmp[32];
sprintf(stmp, "%i", value);
snprintf(stmp, sizeof(stmp), "%i", value);
pcmLbl->setText(stmp);

View File

@ -62,11 +62,11 @@ int getDirFromFile( const char *path, std::string &dir )
if (fi.exists())
{
dir = fi.canonicalPath().toStdString();
dir = fi.canonicalPath().toLocal8Bit().constData();
}
else
{
dir = fi.absolutePath().toStdString();
dir = fi.absolutePath().toLocal8Bit().constData();
}
//printf("Dir: '%s'\n", dir.c_str());
}
@ -535,13 +535,13 @@ void fceuDecIntValidtor::setMinMax( long long int min, long long int max)
QValidator::State fceuDecIntValidtor::validate(QString &input, int &pos) const
{
long long int i, v;
//printf("Validate: %i '%s'\n", input.size(), input.toStdString().c_str() );
//printf("Validate: %i '%s'\n", input.size(), input.toLocal8Bit().constData() );
if ( input.size() == 0 )
{
return QValidator::Acceptable;
}
std::string s = input.toStdString();
std::string s = input.toLocal8Bit().constData();
i=0;
if (s[i] == '-')
@ -602,14 +602,14 @@ void fceuHexIntValidtor::setMinMax( long long int min, long long int max)
QValidator::State fceuHexIntValidtor::validate(QString &input, int &pos) const
{
long long int i, v;
//printf("Validate: %i '%s'\n", input.size(), input.toStdString().c_str() );
//printf("Validate: %i '%s'\n", input.size(), input.toLocal8Bit().constData() );
if ( input.size() == 0 )
{
return QValidator::Acceptable;
}
input = input.toUpper();
std::string s = input.toStdString();
std::string s = input.toLocal8Bit().constData();
i=0;
if (s[i] == '-')
@ -1339,7 +1339,7 @@ QString fceuGetOpcodeToolTip( uint8_t *opcode, int size )
for (int i=0; i<size; i++)
{
sprintf(stmp, "$%02X ", opcode[i] );
snprintf(stmp, sizeof(stmp), "$%02X ", opcode[i] );
text.append( stmp );
}
@ -1347,7 +1347,7 @@ QString fceuGetOpcodeToolTip( uint8_t *opcode, int size )
text.append( addrMode );
text.append( "\nCycle Count:\t\t" );
sprintf( stmp, "%i", X6502_GetOpcodeCycles( opcode[0] ) );
snprintf( stmp, sizeof(stmp), "%i", X6502_GetOpcodeCycles( opcode[0] ) );
text.append( stmp );
text.append( "\n" );
@ -1382,4 +1382,37 @@ QString fceuGetOpcodeToolTip( uint8_t *opcode, int size )
return QString::fromStdString( text );
}
//----------------------------------------------------
void setCheckBoxFromProperty( QCheckBox *cbx, const char *property )
{
int pval;
g_config->getOption (property, &pval);
cbx->setCheckState( pval ? Qt::Checked : Qt::Unchecked );
}
//----------------------------------------------------
void setComboBoxFromProperty( QComboBox *cbx, const char *property )
{
int i, pval;
g_config->getOption (property, &pval);
for (i=0; i<cbx->count(); i++)
{
if ( pval == cbx->itemData(i).toInt() )
{
cbx->setCurrentIndex(i); break;
}
}
}
//---------------------------------------------------------------------------
void setComboBoxFromValue( QComboBox *cbx, int pval )
{
for (int i=0; i<cbx->count(); i++)
{
if ( pval == cbx->itemData(i).toInt() )
{
cbx->setCurrentIndex(i); break;
}
}
}
//---------------------------------------------------------------------------

View File

@ -9,6 +9,7 @@
#include <QValidator>
#include <QDialog>
#include <QHelpEvent>
#include <QComboBox>
#include <QCheckBox>
int getDirFromFile( const char *path, std::string &dir );
@ -93,3 +94,8 @@ class QCheckBoxRO : public QCheckBox
QString fceuGetOpcodeToolTip( uint8_t *opcode, int size );
QDialog *fceuCustomToolTipShow( const QPoint &globalPos, QDialog *popup );
//----------------------------------------------------
void setCheckBoxFromProperty( QCheckBox *cbx, const char *property );
void setComboBoxFromProperty( QComboBox *cbx, const char *property );
void setComboBoxFromValue( QComboBox *cbx, int pval );

View File

@ -35,6 +35,10 @@
#include "Qt/ConsoleVideoConf.h"
#include "Qt/nes_shm.h"
#if defined(WIN32) && (QT_VERSION_MAJOR < 6)
#include <QtPlatformHeaders/QWindowsWindowFunctions>
#endif
extern int input_display;
extern int frame_display;
extern int rerecord_display;
@ -119,8 +123,8 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
vbox1->addLayout( hbox1 );
// Enable OpenGL Linear Filter Checkbox
gl_LF_chkBox = new QCheckBox( tr("Enable OpenGL Linear Filter") );
// Enable Linear Filter Checkbox
gl_LF_chkBox = new QCheckBox( tr("Enable Linear Filter") );
setCheckBoxFromProperty( gl_LF_chkBox , "SDL.OpenGLip");
@ -128,6 +132,18 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
vbox1->addWidget( gl_LF_chkBox );
#if defined(WIN32) && (QT_VERSION_MAJOR < 6)
// 1px full screen border - hack fix for QOpenGLWidget fullscreen issues
winFullScreenBorderCbx = new QCheckBox( tr("Fullscreen Border (1px)") );
winFullScreenBorderCbx->setToolTip(tr("Hack fix for QOpenGLWidget fullscreen issue. May not be needed."));
setCheckBoxFromProperty( winFullScreenBorderCbx , "SDL.winFullScreenBorder");
connect(winFullScreenBorderCbx, SIGNAL(stateChanged(int)), this, SLOT(winFullScreenBorderChanged(int)) );
vbox1->addWidget(winFullScreenBorderCbx);
#endif
// Region Select
lbl = new QLabel( tr("Region:") );
@ -502,7 +518,7 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
scrRateReadout->setFont( font );
scrRateReadout->setReadOnly(true);
scrRateReadout->setAlignment(Qt::AlignCenter);
sprintf( stmp, "%.3f", consoleWindow->getRefreshRate() );
snprintf( stmp, sizeof(stmp), "%.3f", consoleWindow->getRefreshRate() );
scrRateReadout->setText( tr(stmp) );
hbox->addWidget( new QLabel( tr("Refresh Rate (Hz):") ) );
@ -590,11 +606,11 @@ void ConsoleVideoConfDialog_t::updateReadouts(void)
v = consoleWindow->viewport_Interface->size();
}
sprintf( stmp, "%i x %i ", w.width(), w.height() );
snprintf( stmp, sizeof(stmp), "%i x %i ", w.width(), w.height() );
winSizeReadout->setText( tr(stmp) );
sprintf( stmp, "%i x %i ", v.width(), v.height() );
snprintf( stmp, sizeof(stmp), "%i x %i ", v.width(), v.height() );
vpSizeReadout->setText( tr(stmp) );
}
@ -709,7 +725,7 @@ void ConsoleVideoConfDialog_t::openGL_linearFilterChanged( int value )
{
bool opt = (value != Qt::Unchecked);
g_config->setOption("SDL.OpenGLip", opt );
g_config->save ();
g_config->save();
if ( consoleWindow != NULL )
{
@ -720,6 +736,20 @@ void ConsoleVideoConfDialog_t::openGL_linearFilterChanged( int value )
}
}
//----------------------------------------------------
#if defined(WIN32) && (QT_VERSION_MAJOR < 6)
void ConsoleVideoConfDialog_t::winFullScreenBorderChanged(int value)
{
bool opt = (value != Qt::Unchecked);
// This function is needed to fix the issue referenced below. It adds a 1-pixel border
// around the fullscreen window due to some limitation in windows.
// https://doc.qt.io/qt-5/windows-issues.html#fullscreen-opengl-based-windows
QWindowsWindowFunctions::setHasBorderInFullScreen( consoleWindow->windowHandle(), opt);
g_config->setOption("SDL.winFullScreenBorder", opt );
g_config->save();
}
#endif
//----------------------------------------------------
void ConsoleVideoConfDialog_t::autoScaleChanged( int value )
{
bool opt = (value != Qt::Unchecked);

View File

@ -55,6 +55,9 @@ class ConsoleVideoConfDialog_t : public QDialog
QCheckBox *showFrameCount_cbx;
QCheckBox *showLagCount_cbx;
QCheckBox *showRerecordCount_cbx;
#if defined(WIN32) && (QT_VERSION_MAJOR < 6)
QCheckBox *winFullScreenBorderCbx;
#endif
QDoubleSpinBox *xScaleBox;
QDoubleSpinBox *yScaleBox;
QLabel *aspectSelectLabel;
@ -111,6 +114,9 @@ class ConsoleVideoConfDialog_t : public QDialog
void ntscEndScanLineChanged(int value);
void palStartScanLineChanged(int value);
void palEndScanLineChanged(int value);
#if defined(WIN32) && (QT_VERSION_MAJOR < 6)
void winFullScreenBorderChanged(int value);
#endif
};

View File

@ -86,6 +86,12 @@ ConsoleViewGL_t::ConsoleViewGL_t(QWidget *parent)
setFocusPolicy(Qt::StrongFocus);
//setAttribute(Qt::WA_OpaquePaintEvent);
drawTimer = new QTimer(this);
drawTimer->setInterval(14);
drawTimer->setSingleShot(true);
drawTimer->setTimerType(Qt::PreciseTimer);
connect(drawTimer, &QTimer::timeout, this, &ConsoleViewGL_t::onDrawSignal);
localBufSize = (4 * GL_NES_WIDTH) * (4 * GL_NES_HEIGHT) * sizeof(uint32_t);
localBuf = (uint32_t*)malloc( localBufSize );
@ -137,6 +143,8 @@ ConsoleViewGL_t::ConsoleViewGL_t(QWidget *parent)
ConsoleViewGL_t::~ConsoleViewGL_t(void)
{
//printf("Destroying GL Viewport\n");
drawTimer->stop();
delete drawTimer;
if ( localBuf )
{
@ -566,6 +574,22 @@ void ConsoleViewGL_t::getNormalizedCursorPos( double &x, double &y )
void ConsoleViewGL_t::renderFinished(void)
{
videoBufferSwapMark();
// Schedule draw timing inline with vsync
drawTimer->start();
}
void ConsoleViewGL_t::queueRedraw(void)
{
if (!drawTimer->isActive())
{
update();
}
}
void ConsoleViewGL_t::onDrawSignal(void)
{
update();
}
void ConsoleViewGL_t::paintGL(void)

View File

@ -22,7 +22,7 @@ class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions, public
int init(void);
void reset(void);
void queueRedraw(void){ update(); };
void queueRedraw(void);
int driver(void){ return VIDEO_DRIVER_OPENGL; };
void transfer2LocalBuffer(void);
@ -90,6 +90,7 @@ class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions, public
unsigned int textureType;
unsigned int mouseButtonMask;
QColor *bgColor;
QTimer *drawTimer;
uint32_t *localBuf;
uint32_t localBufSize;
@ -97,5 +98,6 @@ class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions, public
private slots:
void cleanupGL(void);
void renderFinished(void);
void onDrawSignal();
};

View File

@ -82,6 +82,11 @@ ConsoleViewSDL_t::ConsoleViewSDL_t(QWidget *parent)
vsyncEnabled = false;
mouseButtonMask = 0;
drawTimer = new QTimer(this);
drawTimer->setInterval(14);
drawTimer->setSingleShot(true);
drawTimer->setTimerType(Qt::PreciseTimer);
connect(drawTimer, &QTimer::timeout, this, &ConsoleViewSDL_t::onDrawSignal);
localBufSize = (4 * GL_NES_WIDTH) * (4 * GL_NES_HEIGHT) * sizeof(uint32_t);
@ -123,6 +128,8 @@ ConsoleViewSDL_t::ConsoleViewSDL_t(QWidget *parent)
ConsoleViewSDL_t::~ConsoleViewSDL_t(void)
{
//printf("Destroying SDL Viewport\n");
drawTimer->stop();
delete drawTimer;
if ( localBuf )
{
@ -585,6 +592,19 @@ void ConsoleViewSDL_t::getNormalizedCursorPos( double &x, double &y )
//printf("Normalized Cursor (%f,%f) \n", x, y );
}
void ConsoleViewSDL_t::queueRedraw(void)
{
if (!drawTimer->isActive())
{
render();
}
}
void ConsoleViewSDL_t::onDrawSignal(void)
{
render();
}
void ConsoleViewSDL_t::render(void)
{
int nesWidth = GL_NES_WIDTH;
@ -707,5 +727,8 @@ void ConsoleViewSDL_t::render(void)
videoBufferSwapMark();
// Schedule draw timing inline with vsync
drawTimer->start();
nes_shm->render_count++;
}

View File

@ -24,7 +24,7 @@ class ConsoleViewSDL_t : public QWidget, public ConsoleViewerBase
void reset(void);
void cleanup(void);
void render(void);
void queueRedraw(void){ render(); };
void queueRedraw(void);
int driver(void){ return VIDEO_DRIVER_SDL; };
void transfer2LocalBuffer(void);
@ -83,6 +83,7 @@ class ConsoleViewSDL_t : public QWidget, public ConsoleViewerBase
bool forceAspect;
bool autoScaleEna;
QColor *bgColor;
QTimer *drawTimer;
uint32_t *localBuf;
uint32_t localBufSize;
@ -95,5 +96,6 @@ class ConsoleViewSDL_t : public QWidget, public ConsoleViewerBase
//SDL_Rect sdlViewport;
private slots:
void onDrawSignal();
};

View File

@ -47,6 +47,7 @@
#include <QActionGroup>
#include <QShortcut>
#include <QUrl>
#include <QDir>
#include "../../fceu.h"
#include "../../fds.h"
@ -55,6 +56,7 @@
#include "../../movie.h"
#include "../../wave.h"
#include "../../state.h"
#include "../../cheat.h"
#include "../../profiler.h"
#include "../../version.h"
#include "common/os_utils.h"
@ -67,6 +69,7 @@
#include "Qt/main.h"
#include "Qt/dface.h"
#include "Qt/input.h"
#include "Qt/throttle.h"
#include "Qt/ColorMenu.h"
#include "Qt/ConsoleWindow.h"
#include "Qt/InputConf.h"
@ -86,6 +89,7 @@
#include "Qt/TimingConf.h"
#include "Qt/FrameTimingStats.h"
#include "Qt/LuaControl.h"
#include "Qt/QtScriptManager.h"
#include "Qt/CheatsConf.h"
#include "Qt/GameGenie.h"
#include "Qt/HexEditor.h"
@ -105,6 +109,7 @@
#include "Qt/RamSearch.h"
#include "Qt/keyscan.h"
#include "Qt/nes_shm.h"
#include "Qt/NetPlay.h"
#include "Qt/TasEditor/TasEditorWindow.h"
#ifdef __APPLE__
@ -119,13 +124,19 @@ consoleWin_t::consoleWin_t(QWidget *parent)
int setFullScreen = false;
//QString libpath = QLibraryInfo::location(QLibraryInfo::PluginsPath);
//printf("LibPath: '%s'\n", libpath.toStdString().c_str() );
//printf("LibPath: '%s'\n", libpath.toLocal8Bit().constData() );
tempDir = new QTemporaryDir();
if (tempDir->isValid())
{
printf("Temp Folder: %s\n", tempDir->path().toLocal8Bit().constData());
}
#ifdef __APPLE__
qt_set_sequence_auto_mnemonic(true);
#endif
printf("Running on Platform: %s\n", QGuiApplication::platformName().toStdString().c_str() );
printf("Running on Platform: %s\n", QGuiApplication::platformName().toLocal8Bit().constData() );
QThread *thread = QThread::currentThread();
@ -152,6 +163,7 @@ consoleWin_t::consoleWin_t(QWidget *parent)
mainMenuEmuWasPaused = false;
mainMenuPauseWhenActv = false;
autoHideMenuFullscreen = false;
redrawVideoRequest = false;
createMainMenu();
@ -168,11 +180,6 @@ consoleWin_t::consoleWin_t(QWidget *parent)
setAcceptDrops(true);
gameTimer = new QTimer( this );
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
mutex = new QRecursiveMutex();
#else
mutex = new QMutex( QMutex::Recursive );
#endif
emulatorThread = new emulatorThread_t(this);
connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater);
@ -184,6 +191,10 @@ consoleWin_t::consoleWin_t(QWidget *parent)
gameTimer->setTimerType( Qt::PreciseTimer );
gameTimer->start( 8 ); // 120hz
#ifdef __FCEU_QSCRIPT_ENABLE__
QtScriptManager::create(nullptr);
#endif
emulatorThread->start();
g_config->getOption( "SDL.SetSchedParam", &opt );
@ -271,6 +282,30 @@ consoleWin_t::consoleWin_t(QWidget *parent)
aviDiskThread = new AviRecordDiskThread_t(this);
scrHandlerConnected = false;
// Register State Load Callback with Emulation Core
auto stateLoadCallback = []( bool loadSuccess )
{
//printf("State Loaded: %i \n", loadSuccess );
if (loadSuccess && (consoleWindow != nullptr) )
{
emit consoleWindow->stateLoaded();
}
};
FCEUSS_SetLoadCallback( stateLoadCallback );
// Register Cheat Change Callback
auto cheatChangeCallback = []( void* userData )
{
FCEU_UNUSED(userData);
//printf("Cheats Changed Event!\n");
if (consoleWindow != nullptr)
{
emit consoleWindow->cheatsChanged();
}
};
FCEU_SetCheatChangeEventCallback( cheatChangeCallback, this );
}
consoleWin_t::~consoleWin_t(void)
@ -311,6 +346,12 @@ consoleWin_t::~consoleWin_t(void)
closeGamePadConfWindow();
#ifdef __FCEU_QSCRIPT_ENABLE__
QtScriptManager::destroy();
#endif
NetPlayCloseSession();
// The closeApp function call stops all threads.
// Calling quit on threads should not happen here.
//printf("Thread Finished: %i \n", emulatorThread->isFinished() );
@ -327,8 +368,6 @@ consoleWin_t::~consoleWin_t(void)
unloadVideoDriver();
delete mutex;
// LoadGame() checks for an IP and if it finds one begins a network session
// clear the NetworkIP field so this doesn't happen unintentionally
//g_config->setOption ("SDL.NetworkIP", "");
@ -353,6 +392,11 @@ consoleWin_t::~consoleWin_t(void)
consoleWindow = NULL;
}
if (tempDir != nullptr)
{
delete tempDir;
tempDir = nullptr;
}
}
int consoleWin_t::videoInit(void)
@ -410,7 +454,7 @@ void consoleWin_t::winScreenChanged(QScreen *scr)
return;
}
refreshRate = scr->refreshRate();
//printf("Screen Refresh Rate: %f\n", scr->refreshRate() );
printf("Screen Refresh Rate: %f\n", scr->refreshRate() );
//printf("Screen Changed: %p\n", scr );
if ( viewport_GL != NULL )
@ -747,12 +791,12 @@ void consoleWin_t::dropEvent(QDropEvent *event)
(suffix[0] == 'f') && (suffix[1] == 'c') &&
( (suffix[2] == 's') || suffix[2].isDigit() );
//printf("DragNDrop Suffix: %s\n", suffix.toStdString().c_str() );
//printf("DragNDrop Suffix: %s\n", suffix.toLocal8Bit().constData() );
if (isStateSaveFile)
{
FCEU_WRAPPER_LOCK();
FCEUI_LoadState( filename.toStdString().c_str() );
FCEUI_LoadState( filename.toLocal8Bit().constData() );
FCEU_WRAPPER_UNLOCK();
event->accept();
@ -762,12 +806,12 @@ void consoleWin_t::dropEvent(QDropEvent *event)
int luaLoadSuccess;
FCEU_WRAPPER_LOCK();
luaLoadSuccess = FCEU_LoadLuaCode( filename.toStdString().c_str() );
luaLoadSuccess = FCEU_LoadLuaCode( filename.toLocal8Bit().constData() );
FCEU_WRAPPER_UNLOCK();
if (luaLoadSuccess)
{
g_config->setOption("SDL.LastLoadLua", filename.toStdString().c_str());
g_config->setOption("SDL.LastLoadLua", filename.toLocal8Bit().constData());
}
event->accept();
}
@ -776,12 +820,12 @@ void consoleWin_t::dropEvent(QDropEvent *event)
int romLoadSuccess;
FCEU_WRAPPER_LOCK();
romLoadSuccess = LoadGame( filename.toStdString().c_str() );
romLoadSuccess = LoadGame( filename.toLocal8Bit().constData() );
FCEU_WRAPPER_UNLOCK();
if (!romLoadSuccess)
{
printf("DragNDrop ROM Load Failed for %s\n", filename.toStdString().c_str() );
printf("DragNDrop ROM Load Failed for %s\n", filename.toLocal8Bit().constData() );
}
event->accept();
}
@ -855,6 +899,14 @@ void consoleWin_t::initHotKeys(void)
Hotkeys[HK_FRAME_ADVANCE].getShortcut()->setEnabled(false);
Hotkeys[HK_TURBO ].getShortcut()->setEnabled(false);
connect( Hotkeys[ HK_SPEED_QUARTER ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed( 25); } );
connect( Hotkeys[ HK_SPEED_HALF ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed( 50); } );
connect( Hotkeys[ HK_SPEED_NORMAL ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed( 100); } );
connect( Hotkeys[ HK_SPEED_2X ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed( 200); } );
connect( Hotkeys[ HK_SPEED_4X ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed( 400); } );
connect( Hotkeys[ HK_SPEED_8X ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed( 800); } );
connect( Hotkeys[ HK_SPEED_16X ].getShortcut(), &QShortcut::activated, [] { CustomEmulationSpeed(1600); } );
connect( Hotkeys[ HK_VOLUME_MUTE ].getShortcut(), SIGNAL(activated()), this, SLOT(muteSoundVolume(void)) );
connect( Hotkeys[ HK_VOLUME_DOWN ].getShortcut(), SIGNAL(activated()), this, SLOT(decrSoundVolume(void)) );
connect( Hotkeys[ HK_VOLUME_UP ].getShortcut(), SIGNAL(activated()), this, SLOT(incrSoundVolume(void)) );
@ -915,13 +967,14 @@ void consoleWin_t::createMainMenu(void)
menubar->setNativeMenuBar( useNativeMenuBar ? true : false );
// Top Level Menu Iterms
fileMenu = menubar->addMenu(tr("&File"));
movieMenu = menubar->addMenu(tr("&Movie"));
optMenu = menubar->addMenu(tr("&Options"));
emuMenu = menubar->addMenu(tr("&Emulation"));
toolsMenu = menubar->addMenu(tr("&Tools"));
debugMenu = menubar->addMenu(tr("&Debug"));
helpMenu = menubar->addMenu(tr("&Help"));
fileMenu = menubar->addMenu(tr("&File"));
movieMenu = menubar->addMenu(tr("&Movie"));
optMenu = menubar->addMenu(tr("&Options"));
emuMenu = menubar->addMenu(tr("&Emulation"));
toolsMenu = menubar->addMenu(tr("&Tools"));
debugMenu = menubar->addMenu(tr("&Debug"));
netPlayMenu = menubar->addMenu(tr("&NetPlay"));
helpMenu = menubar->addMenu(tr("&Help"));
//-----------------------------------------------------------------------
// File
@ -1022,7 +1075,7 @@ void consoleWin_t::createMainMenu(void)
{
char stmp[8];
sprintf( stmp, "Slot &%i", i );
snprintf( stmp, sizeof(stmp), "Slot &%i", i );
state[i] = new QAction(tr(stmp), this);
state[i]->setCheckable(true);
@ -1071,7 +1124,7 @@ void consoleWin_t::createMainMenu(void)
connect( Hotkeys[ HK_SELECT_STATE_NEXT ].getShortcut(), SIGNAL(activated()), this, SLOT(incrementState(void)) );
#ifdef _S9XLUA_H
// File -> Quick Save
// File -> Load Lua
loadLuaAct = new QAction(tr("Load &Lua Script"), this);
//loadLuaAct->setShortcut( QKeySequence(tr("F5")));
loadLuaAct->setStatusTip(tr("Load Lua Script"));
@ -1082,7 +1135,20 @@ void consoleWin_t::createMainMenu(void)
fileMenu->addSeparator();
#else
loadLuaAct = NULL;
loadLuaAct = nullptr;
#endif
#ifdef __FCEU_QSCRIPT_ENABLE__
// File -> Load JavaScript
loadJsAct = new QAction(tr("Load &JavaScript"), this);
loadJsAct->setStatusTip(tr("Load JavaScript"));
connect(loadJsAct, SIGNAL(triggered()), this, SLOT(loadJs(void)) );
fileMenu->addAction(loadJsAct);
fileMenu->addSeparator();
#else
loadJsAct = NULL;
#endif
// File -> Screenshot
@ -1225,7 +1291,7 @@ void consoleWin_t::createMainMenu(void)
{
char stmp[8];
sprintf( stmp, "&%ix", i+1 );
snprintf( stmp, sizeof(stmp), "&%ix", i+1 );
winSizeAct[i] = new QAction(tr(stmp), this);
@ -1600,7 +1666,7 @@ void consoleWin_t::createMainMenu(void)
for (int j=1; j<=(6-i); j++)
{
sprintf( stmp, "%i On, %i Off", i, j );
snprintf( stmp, sizeof(stmp), "%i On, %i Off", i, j );
autoFireMenuAction *afAct = new autoFireMenuAction( i, j, tr(stmp), this);
afAct->setCheckable(true);
group->addAction(afAct);
@ -1633,6 +1699,69 @@ void consoleWin_t::createMainMenu(void)
subMenu->addAction(act);
//-----------------------------------------------------------------------
// NetPlay
connect( netPlayMenu, SIGNAL(aboutToShow(void)), this, SLOT(mainMenuOpen(void)) );
connect( netPlayMenu, SIGNAL(aboutToHide(void)), this, SLOT(mainMenuClose(void)) );
// NetPlay -> Host
act = new QAction(tr("&Host"), this);
//act->setShortcut( QKeySequence(tr("Shift+F7")));
act->setStatusTip(tr("Host Game Window"));
connect(act, SIGNAL(triggered()), this, SLOT(openNetPlayHostWindow(void)) );
netPlayHostAct = act;
netPlayMenu->addAction(act);
// NetPlay -> Join
act = new QAction(tr("&Join"), this);
//act->setShortcut( QKeySequence(tr("Shift+F7")));
act->setStatusTip(tr("Join Game Window"));
connect(act, SIGNAL(triggered()), this, SLOT(openNetPlayJoinWindow(void)) );
netPlayJoinAct = act;
netPlayMenu->addAction(act);
// NetPlay -> Client Status Dialog
act = new QAction(tr("Host &Status"), this);
//act->setShortcut( QKeySequence(tr("Shift+F7")));
act->setStatusTip(tr("Open Netplay Host Status Dialog"));
connect(act, SIGNAL(triggered()), this, SLOT(openNetPlayStatusWindow(void)) );
act->setEnabled(false);
act->setVisible(false);
netPlayHostStatAct = act;
netPlayMenu->addAction(act);
// NetPlay -> Client Status Dialog
act = new QAction(tr("Client &Status"), this);
//act->setShortcut( QKeySequence(tr("Shift+F7")));
act->setStatusTip(tr("Open Netplay Client Status Dialog"));
connect(act, SIGNAL(triggered()), this, SLOT(openNetPlayStatusWindow(void)) );
act->setEnabled(false);
act->setVisible(false);
netPlayClientStatAct = act;
netPlayMenu->addAction(act);
netPlayMenu->addSeparator();
act = new QAction(tr(""), this);
act->setEnabled(false);
netPlayMenu->addAction(act);
// NetPlay -> End Game / Disconnect
act = new QAction(tr("&Disconnect/End Game"), this);
//act->setShortcut( QKeySequence(tr("Shift+F7")));
act->setStatusTip(tr("Disconnect Netplay Game"));
connect(act, SIGNAL(triggered()), this, SLOT(closeNetPlaySession(void)) );
act->setEnabled(false);
netPlayDiscAct = act;
netPlayMenu->addAction(act);
//netPlayMenu->setEnabled(false);
//-----------------------------------------------------------------------
// Tools
@ -2154,13 +2283,14 @@ void consoleWin_t::buildRecentRomMenu(void)
for (int i=0; i<10; i++)
{
sprintf(buf, "SDL.RecentRom%02i", i);
snprintf(buf, sizeof(buf), "SDL.RecentRom%02i", i);
g_config->getOption( buf, &s);
//printf("Recent Rom:%i '%s'\n", i, s.c_str() );
bool fileExists = !s.empty() && QFile::exists(tr(s.c_str()));
if ( s.size() > 0 )
if ( fileExists )
{
act = new consoleRecentRomAction( tr(s.c_str()), recentRomMenu);
@ -2174,7 +2304,24 @@ void consoleWin_t::buildRecentRomMenu(void)
romList.push_front( sptr );
}
else
{
// Clear the option if file does not exist
s.clear();
g_config->setOption( buf, s);
}
}
// Add a dummy disable QAction to create a larger dead space between the ROM list and the clear item.
// Helps prevent accidental unintended clicking of the clear list item
recentRomMenu->addSeparator();
act = new QAction(recentRomMenu);
act->setEnabled(false);
recentRomMenu->addAction(act);
act = new QAction(tr("Clear Recent ROM List"), recentRomMenu);
connect(act, SIGNAL(triggered()), this, SLOT(clearRecentRomMenu(void)) );
recentRomMenu->addAction(act);
}
//---------------------------------------------------------------------------
void consoleWin_t::saveRecentRomMenu(void)
@ -2189,13 +2336,32 @@ void consoleWin_t::saveRecentRomMenu(void)
for (it=romList.begin(); it != romList.end(); it++)
{
s = *it;
sprintf(buf, "SDL.RecentRom%02i", i);
snprintf(buf, sizeof(buf), "SDL.RecentRom%02i", i);
g_config->setOption( buf, s->c_str() );
g_config->setOption( buf, *s );
//printf("Recent Rom:%u '%s'\n", i, s->c_str() );
i--;
}
for (i = romList.size(); i < 10; i++)
{
snprintf(buf, sizeof(buf), "SDL.RecentRom%02i", i);
g_config->setOption( buf, "");
}
}
//---------------------------------------------------------------------------
void consoleWin_t::clearRecentRomMenu()
{
char buf[128];
for (int i = 0; i < 10; i++)
{
snprintf(buf, sizeof(buf), "SDL.RecentRom%02i", i);
g_config->setOption( buf, "");
}
clearRomList();
recentRomMenuReset = true;
}
//---------------------------------------------------------------------------
void consoleWin_t::addRecentRom( const char *rom )
@ -2490,13 +2656,13 @@ void consoleWin_t::openROMFile(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
g_config->setOption ("SDL.LastOpenFile", filename.toStdString().c_str() );
g_config->setOption ("SDL.LastOpenFile", filename.toLocal8Bit().constData() );
FCEU_WRAPPER_LOCK();
CloseGame ();
LoadGame ( filename.toStdString().c_str() );
LoadGame ( filename.toLocal8Bit().constData() );
FCEU_WRAPPER_UNLOCK();
return;
@ -2504,15 +2670,27 @@ void consoleWin_t::openROMFile(void)
void consoleWin_t::loadRomRequestCB( QString s )
{
printf("Load ROM Req: '%s'\n", s.toStdString().c_str() );
printf("Load ROM Req: '%s'\n", s.toLocal8Bit().constData() );
FCEU_WRAPPER_LOCK();
CloseGame ();
LoadGame ( s.toStdString().c_str() );
LoadGame ( s.toLocal8Bit().constData() );
FCEU_WRAPPER_UNLOCK();
}
void consoleWin_t::closeROMCB(void)
{
if (isNetPlayClient())
{
QString msgBoxTxt = tr("Unloading ROM will cause a disconnect from the current netplay session.\n\nDo you want to continue with unloading and disconnection?");
int ans = QMessageBox::question( this, tr("NetPlay Client ROM Unload Warning"), msgBoxTxt, QMessageBox::Yes | QMessageBox::No );
if (ans == QMessageBox::No)
{
return;
}
NetPlayCloseSession();
}
FCEU_WRAPPER_LOCK();
CloseGame();
FCEU_WRAPPER_UNLOCK();
@ -2583,12 +2761,12 @@ void consoleWin_t::loadNSF(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
g_config->setOption ("SDL.LastOpenNSF", filename.toStdString().c_str() );
g_config->setOption ("SDL.LastOpenNSF", filename.toLocal8Bit().constData() );
FCEU_WRAPPER_LOCK();
LoadGame( filename.toStdString().c_str() );
LoadGame( filename.toLocal8Bit().constData() );
FCEU_WRAPPER_UNLOCK();
}
@ -2667,12 +2845,12 @@ void consoleWin_t::loadStateFrom(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
g_config->setOption ("SDL.LastLoadStateFrom", filename.toStdString().c_str() );
g_config->setOption ("SDL.LastLoadStateFrom", filename.toLocal8Bit().constData() );
FCEU_WRAPPER_LOCK();
FCEUI_LoadState( filename.toStdString().c_str() );
FCEUI_LoadState( filename.toLocal8Bit().constData() );
FCEU_WRAPPER_UNLOCK();
}
@ -2758,12 +2936,12 @@ void consoleWin_t::saveStateAs(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
g_config->setOption ("SDL.LastSaveStateAs", filename.toStdString().c_str() );
g_config->setOption ("SDL.LastSaveStateAs", filename.toLocal8Bit().constData() );
FCEU_WRAPPER_LOCK();
FCEUI_SaveState( filename.toStdString().c_str() );
FCEUI_SaveState( filename.toLocal8Bit().constData() );
FCEU_WRAPPER_UNLOCK();
}
@ -2973,6 +3151,19 @@ void consoleWin_t::loadLua(void)
#endif
}
void consoleWin_t::loadJs(void)
{
#ifdef __FCEU_QSCRIPT_ENABLE__
QScriptDialog_t *jsCtrlWin;
//printf("Open JS Control Window\n");
jsCtrlWin = new QScriptDialog_t(this);
jsCtrlWin->show();
#endif
}
void consoleWin_t::openInputConfWin(void)
{
//printf("Open Input Config Window\n");
@ -3075,6 +3266,39 @@ void consoleWin_t::openPaletteEditorWin(void)
win->show();
}
void consoleWin_t::openNetPlayHostWindow(void)
{
//printf("Open NetPlay Host Window\n");
openNetPlayHostDialog(this);
}
void consoleWin_t::openNetPlayJoinWindow(void)
{
//printf("Open NetPlay Join Window\n");
openNetPlayJoinDialog(this);
}
void consoleWin_t::openNetPlayStatusWindow(void)
{
//printf("Open NetPlay Status Window\n");
if (isNetPlayHost())
{
openNetPlayHostStatusDialog(this);
}
else
{
openNetPlayClientStatusDialog(this);
}
}
void consoleWin_t::closeNetPlaySession(void)
{
NetPlayCloseSession();
}
void consoleWin_t::openAviRiffViewer(void)
{
AviRiffViewerDialog *win;
@ -3344,7 +3568,7 @@ void consoleWin_t::warnAmbiguousShortcut( QShortcut *shortcut)
std::string msg;
int c = 0;
sprintf( stmp, "Error: Ambiguous Shortcut Activation for Key Sequence: '%s'\n", shortcut->key().toString().toStdString().c_str() );
snprintf( stmp, sizeof(stmp), "Error: Ambiguous Shortcut Activation for Key Sequence: '%s'\n", shortcut->key().toString().toLocal8Bit().constData() );
msg.assign( stmp );
@ -3403,6 +3627,9 @@ void consoleWin_t::consolePause(void)
fceuWrapperTogglePause();
FCEU_WRAPPER_UNLOCK();
bool isPaused = FCEUI_EmulationPaused() ? true : false;
emit pauseToggled( isPaused );
mainMenuEmuPauseSet = false;
return;
}
@ -3539,12 +3766,12 @@ void consoleWin_t::loadGameGenieROM(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
g_config->setOption ("SDL.LastOpenFile", filename.toStdString().c_str() );
g_config->setOption ("SDL.LastOpenFile", filename.toLocal8Bit().constData() );
// copy file to proper place (~/.fceux/gg.rom)
std::ifstream f1 ( filename.toStdString().c_str(), std::fstream::binary);
std::ifstream f1 ( filename.toLocal8Bit().constData(), std::fstream::binary);
std::string fn_out = FCEU_MakeFName (FCEUMKF_GGROM, 0, "");
std::ofstream f2 (fn_out.c_str (),
std::fstream::trunc | std::fstream::binary);
@ -3634,10 +3861,10 @@ void consoleWin_t::fdsLoadBiosFile(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
// copy BIOS file to proper place (~/.fceux/disksys.rom)
std::ifstream fdsBios (filename.toStdString().c_str(), std::fstream::binary);
std::ifstream fdsBios (filename.toLocal8Bit().constData(), std::fstream::binary);
std::string output_filename =
FCEU_MakeFName (FCEUMKF_FDSROM, 0, "");
std::ofstream outFile (output_filename.c_str (),
@ -4069,11 +4296,11 @@ void consoleWin_t::aviRecordAsStart(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
FCEUI_printf ("AVI Recording movie to %s\n", filename.toStdString().c_str() );
FCEUI_printf ("AVI Recording movie to %s\n", filename.toLocal8Bit().constData() );
lastPath = QFileInfo(filename).absolutePath().toStdString();
lastPath = QFileInfo(filename).absolutePath().toLocal8Bit().constData();
if ( lastPath.size() > 0 )
{
@ -4081,7 +4308,7 @@ void consoleWin_t::aviRecordAsStart(void)
}
FCEU_WRAPPER_LOCK();
if ( aviRecordOpenFile( filename.toStdString().c_str() ) == 0 )
if ( aviRecordOpenFile( filename.toLocal8Bit().constData() ) == 0 )
{
aviDiskThread->start();
}
@ -4261,11 +4488,11 @@ void consoleWin_t::wavRecordAsStart(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
FCEUI_printf ("WAV Recording movie to %s\n", filename.toStdString().c_str() );
FCEUI_printf ("WAV Recording movie to %s\n", filename.toLocal8Bit().constData() );
lastPath = QFileInfo(filename).absolutePath().toStdString();
lastPath = QFileInfo(filename).absolutePath().toLocal8Bit().constData();
if ( lastPath.size() > 0 )
{
@ -4273,7 +4500,7 @@ void consoleWin_t::wavRecordAsStart(void)
}
FCEU_WRAPPER_LOCK();
FCEUI_BeginWaveRecord( filename.toStdString().c_str() );
FCEUI_BeginWaveRecord( filename.toLocal8Bit().constData() );
FCEU_WRAPPER_UNLOCK();
}
@ -4514,46 +4741,80 @@ void consoleWin_t::loadMostRecentROM(void)
FCEU_WRAPPER_UNLOCK();
}
QString consoleWin_t::getTempDir()
{
QString path;
if (tempDir->isValid())
{
path = tempDir->path();
}
else
{
path = QDir::tempPath();
}
return path;
}
int consoleWin_t::getPeriodicInterval(void)
{
return gameTimer->interval();
}
void consoleWin_t::transferVideoBuffer(void)
void consoleWin_t::transferVideoBuffer(bool allowRedraw)
{
FCEU_PROFILE_FUNC(prof, "VideoXfer");
if ( nes_shm->blitUpdated )
{
nes_shm->blitUpdated = 0;
if (viewport_Interface)
{
FCEU::autoScopedLock lock(videoBufferMutex);
if ( nes_shm->blitUpdated )
{
viewport_Interface->transfer2LocalBuffer();
viewport_Interface->queueRedraw();
nes_shm->blitUpdated = 0;
if (viewport_Interface != nullptr)
{
viewport_Interface->transfer2LocalBuffer();
redrawVideoRequest = true;
}
}
}
// Don't queue redraw in mutex lock scope
if (allowRedraw && redrawVideoRequest && (viewport_Interface != nullptr))
{
viewport_Interface->queueRedraw();
redrawVideoRequest = false;
}
}
void consoleWin_t::emuFrameFinish(void)
{
static bool eventProcessingInProg = false;
//static bool eventProcessingInProg = false;
if ( eventProcessingInProg )
{ // Prevent recursion as processEvents function can double back on us
return;
}
eventProcessingInProg = true;
// Process all events before attempting to render viewport
QCoreApplication::processEvents();
guiSignalRecvMark();
eventProcessingInProg = false;
//if ( eventProcessingInProg )
//{ // Prevent recursion as processEvents function can double back on us
// return;
//}
// Prevent recursion as processEvents function can double back on us
//if ( !eventProcessingInProg )
//{
// eventProcessingInProg = true;
// // Process all events before attempting to render viewport
// QCoreApplication::processEvents();
// eventProcessingInProg = false;
//}
// Update Input Devices
FCEUD_UpdateInput();
//FCEUD_UpdateInput();
//printf("EMU Frame Finish\n");
transferVideoBuffer();
//#ifdef __FCEU_QSCRIPT_ENABLE__
// QtScriptManager::getInstance()->frameFinishedUpdate();
//#endif
transferVideoBuffer(false);
}
void consoleWin_t::updatePeriodic(void)
@ -4561,21 +4822,24 @@ void consoleWin_t::updatePeriodic(void)
FCEU_PROFILE_FUNC(prof, "updatePeriodic");
static bool eventProcessingInProg = false;
if ( eventProcessingInProg )
{ // Prevent recursion as processEvents function can double back on us
return;
//if ( eventProcessingInProg )
//{ // Prevent recursion as processEvents function can double back on us
// return;
//}
// Prevent recursion as processEvents function can double back on us
if ( !eventProcessingInProg )
{
eventProcessingInProg = true;
// Process all events before attempting to render viewport
QCoreApplication::processEvents();
eventProcessingInProg = false;
}
eventProcessingInProg = true;
// Process all events before attempting to render viewport
QCoreApplication::processEvents();
eventProcessingInProg = false;
// Update Input Devices
FCEUD_UpdateInput();
// RePaint Game Viewport
transferVideoBuffer();
transferVideoBuffer(true);
// Low Rate Updates
if ( (updateCounter % 30) == 0 )
@ -4632,6 +4896,8 @@ void consoleWin_t::updatePeriodic(void)
closeRequested = false;
}
NetPlayPeriodicUpdate();
updateCounter++;
#ifdef __FCEU_PROFILER_ENABLE__
@ -4640,6 +4906,31 @@ void consoleWin_t::updatePeriodic(void)
return;
}
void consoleWin_t::onNetPlayChange(void)
{
const bool netPlayactv = NetPlayActive();
netPlayHostAct->setEnabled( !netPlayactv );
netPlayJoinAct->setEnabled( !netPlayactv );
netPlayDiscAct->setEnabled( netPlayactv );
if (netPlayactv)
{
const bool isHost = isNetPlayHost();
netPlayHostStatAct->setEnabled(isHost);
netPlayHostStatAct->setVisible(isHost);
netPlayClientStatAct->setEnabled(!isHost);
netPlayClientStatAct->setVisible(!isHost);
}
else
{
netPlayHostStatAct->setEnabled(false);
netPlayHostStatAct->setVisible(false);
netPlayClientStatAct->setEnabled(false);
netPlayClientStatAct->setVisible(false);
}
}
emulatorThread_t::emulatorThread_t( QObject *parent )
: QThread(parent)
{
@ -4855,6 +5146,7 @@ void emulatorThread_t::run(void)
void emulatorThread_t::signalFrameFinished(void)
{
emuSignalSendMark();
emit frameFinished();
}
@ -4908,7 +5200,7 @@ consoleRecentRomAction::consoleRecentRomAction(QString desc, QWidget *parent)
QString txt;
QFileInfo fi(desc);
path = desc.toStdString();
path = desc.toLocal8Bit().constData();
txt = fi.fileName();
txt += QString("\t");

View File

@ -23,10 +23,12 @@
#include <QCursor>
#include <QMutex>
#include <QColor>
#include <QTemporaryDir>
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
#include <QRecursiveMutex>
#endif
#include "utils/mutex.h"
#include "Qt/ColorMenu.h"
#include "Qt/ConsoleViewerGL.h"
#include "Qt/ConsoleViewerSDL.h"
@ -134,11 +136,8 @@ class consoleWin_t : public QMainWindow
void setCyclePeriodms( int ms );
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
QRecursiveMutex *mutex;
#else
QMutex *mutex;
#endif
FCEU::mutex emulatorMutex;
FCEU::mutex videoBufferMutex;
int videoInit(void);
void videoReset(void);
@ -180,12 +179,14 @@ class consoleWin_t : public QMainWindow
void setContextMenuEnable(bool enable);
void setSoundUseGlobalFocus(bool enable);
void OpenHelpWindow(std::string subpage = "");
void OpenHelpWindow(QString subpage = QString());
int getPeriodicInterval(void);
QColor *getVideoBgColorPtr(void){ return &videoBgColor; }
QString getTempDir();
protected:
consoleMenuBar *menubar;
@ -195,6 +196,7 @@ class consoleWin_t : public QMainWindow
QMenu *toolsMenu;
QMenu *debugMenu;
QMenu *movieMenu;
QMenu *netPlayMenu;
QMenu *helpMenu;
QMenu *recentRomMenu;
@ -206,6 +208,7 @@ class consoleWin_t : public QMainWindow
QAction *quickLoadAct;
QAction *quickSaveAct;
QAction *loadLuaAct;
QAction *loadJsAct;
QAction *scrShotAct;
QAction *quitAct;
QAction *inputConfig;
@ -260,12 +263,18 @@ class consoleWin_t : public QMainWindow
QAction *recAsWavAct;
QAction *stopWavAct;
QAction *tasEditorAct;
QAction *netPlayHostAct;
QAction *netPlayJoinAct;
QAction *netPlayDiscAct;
QAction *netPlayHostStatAct;
QAction *netPlayClientStatAct;
//QAction *aviHudAct;
//QAction *aviMsgAct;
QTimer *gameTimer;
QColor videoBgColor;
ColorMenuItem *bgColorMenuItem;
QTemporaryDir *tempDir;
std::string errorMsg;
bool errorMsgValid;
@ -279,6 +288,7 @@ class consoleWin_t : public QMainWindow
bool contextMenuEnable;
bool soundUseGlobalFocus;
bool autoHideMenuFullscreen;
bool redrawVideoRequest;
std::list <std::string*> romList;
std::vector <autoFireMenuAction*> afActList;
@ -314,10 +324,19 @@ class consoleWin_t : public QMainWindow
void changeState(int slot);
void saveState(int slot);
void loadState(int slot);
void transferVideoBuffer(void);
void transferVideoBuffer(bool allowRedraw);
void syncAutoFirePatternMenu(void);
std::string findHelpFile(void);
QString findHelpFile(void);
public:
signals:
void romLoaded(void);
void romUnload(void);
void stateLoaded(void);
void nesResetOccurred(void);
void pauseToggled(bool state);
void cheatsChanged(void);
public slots:
void openDebugWindow(void);
@ -327,6 +346,7 @@ class consoleWin_t : public QMainWindow
void toggleMenuVis(void);
void recordMovie(void);
void winResizeIx(int iScale);
void onNetPlayChange(void);
private slots:
void closeApp(void);
void openROMFile(void);
@ -351,6 +371,10 @@ class consoleWin_t : public QMainWindow
void openTimingConfWin(void);
void openStateRecorderConfWin(void);
void openPaletteEditorWin(void);
void openNetPlayHostWindow(void);
void openNetPlayJoinWindow(void);
void openNetPlayStatusWindow(void);
void closeNetPlaySession(void);
void openAviRiffViewer(void);
void openTimingStatWin(void);
void openMovieOptWin(void);
@ -372,6 +396,7 @@ class consoleWin_t : public QMainWindow
void incrementState(void);
void decrementState(void);
void loadLua(void);
void loadJs(void);
void takeScreenShot(void);
void prepareScreenShot(void);
void powerConsoleCB(void);
@ -381,6 +406,7 @@ class consoleWin_t : public QMainWindow
void toggleGameGenie(bool checked);
void loadGameGenieROM(void);
void loadMostRecentROM(void);
void clearRecentRomMenu(void);
void setRegionNTSC(void);
void setRegionPAL(void);
void setRegionDendy(void);

View File

@ -616,11 +616,11 @@ FKBConfigDialog::FKBConfigDialog(QWidget *parent)
if ( strcmp( keyNames[j], keyNames[j+1] ) == 0 )
{
sprintf( stmp, " %s ", keyNames[j] );
snprintf( stmp, sizeof(stmp), " %s ", keyNames[j] );
}
else
{
sprintf( stmp, " %s - %s ", keyNames[j], keyNames[j+1] );
snprintf( stmp, sizeof(stmp), " %s - %s ", keyNames[j], keyNames[j+1] );
}
item->setText(0, tr(stmp) );
@ -858,9 +858,9 @@ void FKBConfigDialog::openFontDialog(void)
keyboard->setFont( selFont );
keyboard->update();
//printf("Font Changed to: '%s'\n", font.toString().toStdString().c_str() );
//printf("Font Changed to: '%s'\n", font.toString().toLocal8Bit().constData() );
g_config->setOption("SDL.FamilyKeyboardFont", selFont.toString().toStdString().c_str() );
g_config->setOption("SDL.FamilyKeyboardFont", selFont.toString().toLocal8Bit().constData() );
QTimer::singleShot( 100, this, SLOT(keyTreeResizeDone(void)) );
}
@ -1189,9 +1189,9 @@ void FKBConfigDialog::mappingLoad(void)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
mappingLoad( filename.toStdString().c_str() );
mappingLoad( filename.toLocal8Bit().constData() );
return;
}
@ -1331,26 +1331,26 @@ void FKBConfigDialog::mappingSave(void)
}
stmp[k] = 0;
//sprintf(stmp, "k%s", SDL_GetKeyName(bmap[c][i].ButtonNum));
//snprintf(stmp, sizeof(stmp), "k%s", SDL_GetKeyName(bmap[c][i].ButtonNum));
}
else
{
if (fkbmap[i].ButtonNum & 0x2000)
{
/* Hat "button" */
sprintf(stmp, "h%i.%i",
snprintf(stmp, sizeof(stmp), "h%i.%i",
(fkbmap[i].ButtonNum >> 8) & 0x1F, fkbmap[i].ButtonNum & 0xFF);
}
else if (fkbmap[i].ButtonNum & 0x8000)
{
/* Axis "button" */
sprintf(stmp, "%ca%i",
snprintf(stmp, sizeof(stmp), "%ca%i",
(fkbmap[i].ButtonNum & 0x4000) ? '-' : '+', fkbmap[i].ButtonNum & 0x3FFF);
}
else
{
/* Button */
sprintf(stmp, "b%i", fkbmap[i].ButtonNum);
snprintf(stmp, sizeof(stmp), "b%i", fkbmap[i].ButtonNum);
}
}
fprintf( fp, "%s=%s\n", FamilyKeyBoardNames[i], stmp );
@ -1432,7 +1432,7 @@ void FKBConfigDialog::mappingSaveAs(void)
return;
}
saveFileName = filename.toStdString();
saveFileName = filename.toLocal8Bit().constData();
mappingSave();
}
@ -1462,7 +1462,7 @@ FKBKeyMapDialog::FKBKeyMapDialog( int idx, QWidget *parent )
setLayout( mainLayout );
sprintf( stmp, "Press a key to set new physical mapping for the '%s' Key", keyNames[idx*2] );
snprintf( stmp, sizeof(stmp), "Press a key to set new physical mapping for the '%s' Key", keyNames[idx*2] );
msgLbl = new QLabel( tr(stmp) );

View File

@ -89,6 +89,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
frameTimeIdlePct = new QTreeWidgetItem();
frameLateCount = new QTreeWidgetItem();
videoTimeAbs = new QTreeWidgetItem();
emuSignalDelay = new QTreeWidgetItem();
tree->addTopLevelItem(frameTimeAbs);
tree->addTopLevelItem(frameTimeDel);
@ -97,6 +98,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
tree->addTopLevelItem(frameTimeWorkPct);
tree->addTopLevelItem(frameTimeIdlePct);
tree->addTopLevelItem(videoTimeAbs);
tree->addTopLevelItem(emuSignalDelay);
tree->addTopLevelItem(frameLateCount);
frameTimeAbs->setFlags(Qt::ItemIsEnabled | Qt::ItemNeverHasChildren);
@ -109,6 +111,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
frameTimeWorkPct->setText(0, tr("Frame Work %"));
frameTimeIdlePct->setText(0, tr("Frame Idle %"));
frameLateCount->setText(0, tr("Frame Late Count"));
emuSignalDelay->setText(0, tr("EMU Signal Delay ms"));
videoTimeAbs->setText(0, tr("Video Period ms"));
frameTimeAbs->setTextAlignment(0, Qt::AlignLeft);
@ -119,6 +122,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
frameTimeIdlePct->setTextAlignment(0, Qt::AlignLeft);
frameLateCount->setTextAlignment(0, Qt::AlignLeft);
videoTimeAbs->setTextAlignment(0, Qt::AlignLeft);
emuSignalDelay->setTextAlignment(0, Qt::AlignLeft);
for (int i = 0; i < 4; i++)
{
@ -130,6 +134,7 @@ FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
frameTimeIdlePct->setTextAlignment(i + 1, Qt::AlignCenter);
frameLateCount->setTextAlignment(i + 1, Qt::AlignCenter);
videoTimeAbs->setTextAlignment(i + 1, Qt::AlignCenter);
emuSignalDelay->setTextAlignment(i + 1, Qt::AlignCenter);
}
hbox = new QHBoxLayout();
@ -204,98 +209,111 @@ void FrameTimingDialog_t::updateTimingStats(void)
getFrameTimingStats(&stats);
// Absolute
sprintf(stmp, "%.3f", stats.frameTimeAbs.tgt * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeAbs.tgt * 1e3);
frameTimeAbs->setText(1, tr(stmp));
sprintf(stmp, "%.3f", stats.frameTimeAbs.cur * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeAbs.cur * 1e3);
frameTimeAbs->setText(2, tr(stmp));
sprintf(stmp, "%.3f", stats.frameTimeAbs.min * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeAbs.min * 1e3);
frameTimeAbs->setText(3, tr(stmp));
sprintf(stmp, "%.3f", stats.frameTimeAbs.max * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeAbs.max * 1e3);
frameTimeAbs->setText(4, tr(stmp));
// Delta
sprintf(stmp, "%.3f", stats.frameTimeDel.tgt * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeDel.tgt * 1e3);
frameTimeDel->setText(1, tr(stmp));
sprintf(stmp, "%.3f", stats.frameTimeDel.cur * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeDel.cur * 1e3);
frameTimeDel->setText(2, tr(stmp));
sprintf(stmp, "%.3f", stats.frameTimeDel.min * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeDel.min * 1e3);
frameTimeDel->setText(3, tr(stmp));
sprintf(stmp, "%.3f", stats.frameTimeDel.max * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeDel.max * 1e3);
frameTimeDel->setText(4, tr(stmp));
// Work
sprintf(stmp, "lt %.3f", stats.frameTimeWork.tgt * 1e3);
snprintf(stmp, sizeof(stmp), "lt %.3f", stats.frameTimeWork.tgt * 1e3);
frameTimeWork->setText(1, tr(stmp));
sprintf(stmp, "%.3f", stats.frameTimeWork.cur * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeWork.cur * 1e3);
frameTimeWork->setText(2, tr(stmp));
sprintf(stmp, "%.3f", stats.frameTimeWork.min * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeWork.min * 1e3);
frameTimeWork->setText(3, tr(stmp));
sprintf(stmp, "%.3f", stats.frameTimeWork.max * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeWork.max * 1e3);
frameTimeWork->setText(4, tr(stmp));
// Idle
sprintf(stmp, "gt %.3f", stats.frameTimeIdle.tgt * 1e3);
snprintf(stmp, sizeof(stmp), "gt %.3f", stats.frameTimeIdle.tgt * 1e3);
frameTimeIdle->setText(1, tr(stmp));
sprintf(stmp, "%.3f", stats.frameTimeIdle.cur * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeIdle.cur * 1e3);
frameTimeIdle->setText(2, tr(stmp));
sprintf(stmp, "%.3f", stats.frameTimeIdle.min * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeIdle.min * 1e3);
frameTimeIdle->setText(3, tr(stmp));
sprintf(stmp, "%.3f", stats.frameTimeIdle.max * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.frameTimeIdle.max * 1e3);
frameTimeIdle->setText(4, tr(stmp));
// Work %
sprintf(stmp, "lt %.1f", 100.0 * stats.frameTimeWork.tgt / stats.frameTimeAbs.tgt);
snprintf(stmp, sizeof(stmp), "lt %.1f", 100.0 * stats.frameTimeWork.tgt / stats.frameTimeAbs.tgt);
frameTimeWorkPct->setText(1, tr(stmp));
sprintf(stmp, "%.1f", 100.0 * stats.frameTimeWork.cur / stats.frameTimeAbs.tgt);
snprintf(stmp, sizeof(stmp), "%.1f", 100.0 * stats.frameTimeWork.cur / stats.frameTimeAbs.tgt);
frameTimeWorkPct->setText(2, tr(stmp));
sprintf(stmp, "%.1f", 100.0 * stats.frameTimeWork.min / stats.frameTimeAbs.tgt);
snprintf(stmp, sizeof(stmp), "%.1f", 100.0 * stats.frameTimeWork.min / stats.frameTimeAbs.tgt);
frameTimeWorkPct->setText(3, tr(stmp));
sprintf(stmp, "%.1f", 100.0 * stats.frameTimeWork.max / stats.frameTimeAbs.tgt);
snprintf(stmp, sizeof(stmp), "%.1f", 100.0 * stats.frameTimeWork.max / stats.frameTimeAbs.tgt);
frameTimeWorkPct->setText(4, tr(stmp));
// Idle %
sprintf(stmp, "gt %.1f", 100.0 * stats.frameTimeIdle.tgt / stats.frameTimeAbs.tgt);
snprintf(stmp, sizeof(stmp), "gt %.1f", 100.0 * stats.frameTimeIdle.tgt / stats.frameTimeAbs.tgt);
frameTimeIdlePct->setText(1, tr(stmp));
sprintf(stmp, "%.1f", 100.0 * stats.frameTimeIdle.cur / stats.frameTimeAbs.tgt);
snprintf(stmp, sizeof(stmp), "%.1f", 100.0 * stats.frameTimeIdle.cur / stats.frameTimeAbs.tgt);
frameTimeIdlePct->setText(2, tr(stmp));
sprintf(stmp, "%.1f", 100.0 * stats.frameTimeIdle.min / stats.frameTimeAbs.tgt);
snprintf(stmp, sizeof(stmp), "%.1f", 100.0 * stats.frameTimeIdle.min / stats.frameTimeAbs.tgt);
frameTimeIdlePct->setText(3, tr(stmp));
sprintf(stmp, "%.1f", 100.0 * stats.frameTimeIdle.max / stats.frameTimeAbs.tgt);
snprintf(stmp, sizeof(stmp), "%.1f", 100.0 * stats.frameTimeIdle.max / stats.frameTimeAbs.tgt);
frameTimeIdlePct->setText(4, tr(stmp));
// Video
sprintf(stmp, "%.3f", stats.videoTimeDel.tgt * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.videoTimeDel.tgt * 1e3);
videoTimeAbs->setText(1, tr(stmp));
sprintf(stmp, "%.3f", stats.videoTimeDel.cur * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.videoTimeDel.cur * 1e3);
videoTimeAbs->setText(2, tr(stmp));
sprintf(stmp, "%.3f", stats.videoTimeDel.min * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.videoTimeDel.min * 1e3);
videoTimeAbs->setText(3, tr(stmp));
sprintf(stmp, "%.3f", stats.videoTimeDel.max * 1e3);
snprintf(stmp, sizeof(stmp), "%.3f", stats.videoTimeDel.max * 1e3);
videoTimeAbs->setText(4, tr(stmp));
// Emulator to GUI Thread Signal Delay
snprintf(stmp, sizeof(stmp), "%.3f", stats.emuSignalDelay.tgt * 1e3);
emuSignalDelay->setText(1, tr(stmp));
snprintf(stmp, sizeof(stmp), "%.3f", stats.emuSignalDelay.cur * 1e3);
emuSignalDelay->setText(2, tr(stmp));
snprintf(stmp, sizeof(stmp), "%.3f", stats.emuSignalDelay.min * 1e3);
emuSignalDelay->setText(3, tr(stmp));
snprintf(stmp, sizeof(stmp), "%.3f", stats.emuSignalDelay.max * 1e3);
emuSignalDelay->setText(4, tr(stmp));
// Late Count
sprintf(stmp, "%u", stats.lateCount);
snprintf(stmp, sizeof(stmp), "%u", stats.lateCount);
frameLateCount->setText(1, tr("0"));
frameLateCount->setText(2, tr(stmp));

View File

@ -40,6 +40,7 @@ protected:
QTreeWidgetItem *frameTimeIdlePct;
QTreeWidgetItem *frameLateCount;
QTreeWidgetItem *videoTimeAbs;
QTreeWidgetItem *emuSignalDelay;
QGroupBox *statFrame;
QTreeWidget *tree;

View File

@ -60,14 +60,14 @@ class fceuGGCodeValidtor : public QValidator
QValidator::State validate(QString &input, int &pos) const
{
int i,j, ok;
//printf("Validate: %i '%s'\n", input.size(), input.toStdString().c_str() );
//printf("Validate: %i '%s'\n", input.size(), input.toLocal8Bit().constData() );
if ( input.size() == 0 )
{
return QValidator::Acceptable;
}
input = input.toUpper();
std::string s = input.toStdString();
std::string s = input.toLocal8Bit().constData();
i=0;
while ( s[i] != 0 )
@ -262,19 +262,19 @@ void GameGenieDialog_t::addCheatClicked(void)
int a = -1, v = -1, c = -1;
std::string name;
name = ggCode->text().toStdString();
name = ggCode->text().toLocal8Bit().constData();
if ( addr->text().size() > 0 )
{
a = strtol( addr->text().toStdString().c_str(), NULL, 16 );
a = strtol( addr->text().toLocal8Bit().constData(), NULL, 16 );
}
if ( val->text().size() > 0 )
{
v = strtol( val->text().toStdString().c_str(), NULL, 16 );
v = strtol( val->text().toLocal8Bit().constData(), NULL, 16 );
}
if ( cmp->text().size() > 0 )
{
c = strtol( cmp->text().toStdString().c_str(), NULL, 16 );
c = strtol( cmp->text().toLocal8Bit().constData(), NULL, 16 );
}
FCEU_WRAPPER_LOCK();
@ -288,7 +288,7 @@ void GameGenieDialog_t::romAddrDoubleClicked(QTreeWidgetItem *item, int column)
{
int addr;
addr = strtol( item->text(0).toStdString().c_str(), NULL, 16 );
addr = strtol( item->text(0).toLocal8Bit().constData(), NULL, 16 );
printf("ROM Addr: %06X \n", addr );
@ -300,12 +300,12 @@ void GameGenieDialog_t::addrChanged(const QString &s)
int a, v, c = -1;
char gg[12];
a = strtol( s.toStdString().c_str(), NULL, 16 );
v = strtol( val->text().toStdString().c_str(), NULL, 16 );
a = strtol( s.toLocal8Bit().constData(), NULL, 16 );
v = strtol( val->text().toLocal8Bit().constData(), NULL, 16 );
if ( cmp->text().size() > 0 )
{
c = strtol( cmp->text().toStdString().c_str(), NULL, 16 );
c = strtol( cmp->text().toLocal8Bit().constData(), NULL, 16 );
}
EncodeGG( gg, a, v, c );
@ -320,12 +320,12 @@ void GameGenieDialog_t::cmpChanged(const QString &s)
int a, v, c = -1;
char gg[12];
a = strtol( addr->text().toStdString().c_str(), NULL, 16 );
v = strtol( val->text().toStdString().c_str(), NULL, 16 );
a = strtol( addr->text().toLocal8Bit().constData(), NULL, 16 );
v = strtol( val->text().toLocal8Bit().constData(), NULL, 16 );
if ( s.size() > 0 )
{
c = strtol( s.toStdString().c_str(), NULL, 16 );
c = strtol( s.toLocal8Bit().constData(), NULL, 16 );
}
EncodeGG( gg, a, v, c );
@ -340,12 +340,12 @@ void GameGenieDialog_t::valChanged(const QString &s)
int a, v, c = -1;
char gg[12];
a = strtol( addr->text().toStdString().c_str(), NULL, 16 );
v = strtol( s.toStdString().c_str(), NULL, 16 );
a = strtol( addr->text().toLocal8Bit().constData(), NULL, 16 );
v = strtol( s.toLocal8Bit().constData(), NULL, 16 );
if ( cmp->text().size() > 0 )
{
c = strtol( cmp->text().toStdString().c_str(), NULL, 16 );
c = strtol( cmp->text().toLocal8Bit().constData(), NULL, 16 );
}
EncodeGG( gg, a, v, c );
@ -362,13 +362,13 @@ void GameGenieDialog_t::ggChanged(const QString &s)
memset( gg, 0, sizeof(gg) );
strncpy( gg, ggCode->text().toStdString().c_str(), 8 );
strncpy( gg, ggCode->text().toLocal8Bit().constData(), 8 );
FCEUI_DecodeGG( gg, &a, &v, &c);
if ( a >= 0 )
{
sprintf( stmp, "%04X", a );
snprintf( stmp, sizeof(stmp), "%04X", a );
addr->setText( tr(stmp) );
}
@ -379,7 +379,7 @@ void GameGenieDialog_t::ggChanged(const QString &s)
if ( v >= 0 )
{
sprintf( stmp, "%02X", v );
snprintf( stmp, sizeof(stmp), "%02X", v );
val->setText( tr(stmp) );
}
@ -390,7 +390,7 @@ void GameGenieDialog_t::ggChanged(const QString &s)
if ( c >= 0 )
{
sprintf( stmp, "%02X", c );
snprintf( stmp, sizeof(stmp), "%02X", c );
cmp->setText( tr(stmp) );
}
@ -442,15 +442,15 @@ void GameGenieDialog_t::ListGGAddresses(void)
if ( addr->text().size() > 0 )
{
a = strtol( addr->text().toStdString().c_str(), NULL, 16 );
a = strtol( addr->text().toLocal8Bit().constData(), NULL, 16 );
}
if ( val->text().size() > 0 )
{
v = strtol( val->text().toStdString().c_str(), NULL, 16 );
v = strtol( val->text().toLocal8Bit().constData(), NULL, 16 );
}
if ( cmp->text().size() > 0 )
{
c = strtol( cmp->text().toStdString().c_str(), NULL, 16 );
c = strtol( cmp->text().toLocal8Bit().constData(), NULL, 16 );
}
// also enable/disable the add GG button here
addCheatEmable = (a >= 0) && ( (ggCode->text().size() == 6) || (ggCode->text().size() == 8) );
@ -467,7 +467,7 @@ void GameGenieDialog_t::ListGGAddresses(void)
{
item = new QTreeWidgetItem();
sprintf(str, "%06X", i + (a & 0x1FFF) + 0x10);
snprintf(str, sizeof(str), "%06X", i + (a & 0x1FFF) + 0x10);
//printf("Added ROM ADDR: %s\n", str );
item->setText( 0, tr(str) );

View File

@ -215,7 +215,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
{
if (js->isConnected())
{
sprintf(stmp, "%i: %s", i, js->getName());
snprintf(stmp, sizeof(stmp), "%i: %s", i, js->getName());
devSel->addItem(tr(stmp), i);
}
}
@ -328,7 +328,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
char text[64];
QLabel *buttonName;
sprintf(text, "%s:", GamePadNames[i]);
snprintf(text, sizeof(text), "%s:", GamePadNames[i]);
//hbox2 = new QHBoxLayout();
@ -506,7 +506,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
for (int i = 0; i < GAMEPAD_NUM_DEVICES; i++)
{
sprintf(stmp, "SDL.Input.GamePad.%i.", i);
snprintf(stmp, sizeof(stmp), "SDL.Input.GamePad.%i.", i);
prefix = stmp;
g_config->getOption(prefix + "Profile", &lcl[i].profile);
@ -595,7 +595,7 @@ void GamePadConfDialog_t::loadMapList(void)
fileList = dir.entryList(filters, QDir::Files, QDir::NoSort);
sprintf(stmp, "SDL.Input.GamePad.%u.", portNum);
snprintf(stmp, sizeof(stmp), "SDL.Input.GamePad.%u.", portNum);
prefix = stmp;
g_config->getOption(prefix + "Profile", &mapName);
@ -607,7 +607,7 @@ void GamePadConfDialog_t::loadMapList(void)
for (int i = 0; i < static_cast<int>(fileList.size()); i++)
{
size_t suffixIdx;
std::string fileName = fileList[i].toStdString();
std::string fileName = fileList[i].toLocal8Bit().constData();
suffixIdx = fileName.find_last_of('.');
@ -880,7 +880,7 @@ void GamePadConfDialog_t::changeButton(int padNo, int x)
( strcmp( js1->getGUID(), js2->getGUID() ) != 0 ) )
{
char stmp[256];
sprintf( stmp, "Joystick device GUID MisMatch\n\nSelected device is: \n\t%s\n\nbut button mapping is from: \n\t%s",
snprintf( stmp, sizeof(stmp), "Joystick device GUID MisMatch\n\nSelected device is: \n\t%s\n\nbut button mapping is from: \n\t%s",
js1->getName(), js2->getName() );
QMessageBox::warning( this, tr("Mapping Error"), tr(stmp),
QMessageBox::Cancel, QMessageBox::Cancel );
@ -1100,10 +1100,10 @@ void GamePadConfDialog_t::saveConfig(void)
const char *guid;
std::string prefix, mapName;
sprintf(stmp, "SDL.Input.GamePad.%u.", portNum);
snprintf(stmp, sizeof(stmp), "SDL.Input.GamePad.%u.", portNum);
prefix = stmp;
mapName = mapSel->currentText().toStdString();
mapName = mapSel->currentText().toLocal8Bit().constData();
guid = GamePad[portNum].getGUID();
@ -1134,7 +1134,7 @@ void GamePadConfDialog_t::createNewProfile(const char *name)
mapSel->setCurrentIndex(mapSel->count() - 1);
saveConfig();
sprintf(stmp, "Mapping Created: %s/%s \n", GamePad[portNum].getGUID(), name);
snprintf(stmp, sizeof(stmp), "Mapping Created: %s/%s \n", GamePad[portNum].getGUID(), name);
mapMsg->setText(tr(stmp));
}
//----------------------------------------------------
@ -1151,7 +1151,7 @@ void GamePadConfDialog_t::newProfileCallback(void)
if (QDialog::Accepted == ret)
{
createNewProfile(dialog.textValue().toStdString().c_str());
createNewProfile(dialog.textValue().toLocal8Bit().constData());
}
}
//----------------------------------------------------
@ -1164,7 +1164,7 @@ void GamePadConfDialog_t::loadProfileCallback(void)
index = devSel->currentIndex();
devIdx = devSel->itemData(index).toInt();
mapName = mapSel->currentText().toStdString();
mapName = mapSel->currentText().toLocal8Bit().constData();
GamePad[portNum].setDeviceIndex(devIdx);
@ -1180,11 +1180,11 @@ void GamePadConfDialog_t::loadProfileCallback(void)
{
saveConfig();
sprintf(stmp, "Mapping Loaded: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str());
snprintf(stmp, sizeof(stmp), "Mapping Loaded: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str());
}
else
{
sprintf(stmp, "Error: Failed to Load Mapping: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str());
snprintf(stmp, sizeof(stmp), "Error: Failed to Load Mapping: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str());
}
mapMsg->setText(tr(stmp));
@ -1199,7 +1199,7 @@ void GamePadConfDialog_t::saveProfileCallback(void)
std::string mapName;
char stmp[256];
mapName = mapSel->currentText().toStdString();
mapName = mapSel->currentText().toLocal8Bit().constData();
ret = GamePad[portNum].saveCurrentMapToFile(mapName.c_str());
@ -1207,11 +1207,11 @@ void GamePadConfDialog_t::saveProfileCallback(void)
{
saveConfig();
sprintf(stmp, "Mapping Saved: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str());
snprintf(stmp, sizeof(stmp), "Mapping Saved: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str());
}
else
{
sprintf(stmp, "Error: Failed to Save Mapping: %s \n", mapName.c_str());
snprintf(stmp, sizeof(stmp), "Error: Failed to Save Mapping: %s \n", mapName.c_str());
}
mapMsg->setText(tr(stmp));
}
@ -1222,17 +1222,17 @@ void GamePadConfDialog_t::deleteProfileCallback(void)
std::string mapName;
char stmp[256];
mapName = mapSel->currentText().toStdString();
mapName = mapSel->currentText().toLocal8Bit().constData();
ret = GamePad[portNum].deleteMapping(mapName.c_str());
if (ret == 0)
{
sprintf(stmp, "Mapping Deleted: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str());
snprintf(stmp, sizeof(stmp), "Mapping Deleted: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str());
}
else
{
sprintf(stmp, "Error: Failed to Delete Mapping: %s \n", mapName.c_str());
snprintf(stmp, sizeof(stmp), "Error: Failed to Delete Mapping: %s \n", mapName.c_str());
}
mapMsg->setText(tr(stmp));
@ -1269,7 +1269,7 @@ int GamePadConfDialog_t::promptToSave(void)
{
return 0;
}
sprintf(stmp, "Warning: Gamepad mappings have not been saved for port%c ", (n > 1) ? 's' : ' ');
snprintf(stmp, sizeof(stmp), "Warning: Gamepad mappings have not been saved for port%c ", (n > 1) ? 's' : ' ');
msg.assign(stmp);
@ -1278,7 +1278,7 @@ int GamePadConfDialog_t::promptToSave(void)
{
if (padNeedsSave[i])
{
sprintf(stmp, "%i", i + 1);
snprintf(stmp, sizeof(stmp), "%i", i + 1);
msg.append(stmp);
@ -1427,7 +1427,7 @@ void GamePadConfDialog_t::updatePeriodic(void)
{
char stmp[256];
//printf("Adding Newly Connected JS\n");
sprintf(stmp, "%i: %s", i, js->getName());
snprintf(stmp, sizeof(stmp), "%i: %s", i, js->getName());
devSel->addItem(tr(stmp), i);
}
}
@ -2226,7 +2226,7 @@ void GamePadConfigHotKey_t::setKeyNameLbl( QLineEdit *lbl )
void GamePadConfigHotKey_t::keyPressEvent(QKeyEvent *event)
{
bool isModifier;
//printf("GamePad Hot Key Press: 0x%x '%s'\n", event->key(), event->text().toStdString().c_str() );
//printf("GamePad Hot Key Press: 0x%x '%s'\n", event->key(), event->text().toLocal8Bit().constData() );
isModifier = (event->key() == Qt::Key_Shift ) ||
(event->key() == Qt::Key_Control ) ||
@ -2241,7 +2241,7 @@ void GamePadConfigHotKey_t::keyPressEvent(QKeyEvent *event)
k->keySeq[idx].key = event->key();
k->keySeq[idx].modifier = event->modifiers();
k->keySeq[idx].name = ks.toString().toStdString();
k->keySeq[idx].name = ks.toString().toLocal8Bit().constData();
if ( keySeqLbl )
{

View File

@ -43,7 +43,7 @@
static int writeQPaletteToFile( const char *path, QPalette *pal );
static int readQPaletteFromFile( const char *path, QPalette *pal );
static GuiPaletteEditDialog_t *editDialog = NULL;
static GuiPaletteEditDialog_t *editDialog = nullptr;
//----------------------------------------------------
GuiConfDialog_t::GuiConfDialog_t(QWidget *parent)
: QDialog(parent)
@ -66,7 +66,7 @@ GuiConfDialog_t::GuiConfDialog_t(QWidget *parent)
QSettings settings;
//resize( 512, 600 );
//printf("Style: %s \n", style()->objectName().toStdString().c_str() );
//printf("Style: %s \n", style()->objectName().toLocal8Bit().constData() );
selStyle = style()->objectName();
@ -153,7 +153,7 @@ GuiConfDialog_t::GuiConfDialog_t(QWidget *parent)
if ( selStyle.compare( styleKeys[i], Qt::CaseInsensitive ) == 0 )
{
//printf("Style Match: %s \n", selStyle.toStdString().c_str() );
//printf("Style Match: %s \n", selStyle.toLocal8Bit().constData() );
styleComboBox->setCurrentIndex(i);
}
}
@ -348,7 +348,7 @@ void GuiConfDialog_t::styleChanged(int index)
s = styleComboBox->currentText();
g_config->setOption("SDL.GuiStyle", s.toStdString().c_str() );
g_config->setOption("SDL.GuiStyle", s.toLocal8Bit().constData() );
g_config->save();
QApplication::setStyle( new fceuStyle() );
@ -389,7 +389,7 @@ void GuiConfDialog_t::openQss(void)
if (d.exists())
{
urls << QUrl::fromLocalFile(d.absolutePath());
iniPath = d.absolutePath().toStdString();
iniPath = d.absolutePath().toLocal8Bit().constData();
}
}
#ifdef WIN32
@ -400,7 +400,7 @@ void GuiConfDialog_t::openQss(void)
if (d.exists())
{
urls << QUrl::fromLocalFile(d.absolutePath());
iniPath = d.absolutePath().toStdString();
iniPath = d.absolutePath().toLocal8Bit().constData();
}
#endif
@ -446,11 +446,11 @@ void GuiConfDialog_t::openQss(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
custom_qss_path->setText(filename.toStdString().c_str());
custom_qss_path->setText(filename.toLocal8Bit().constData());
g_config->setOption("SDL.QtStyleSheet", filename.toStdString().c_str() );
g_config->setOption("SDL.QtStyleSheet", filename.toLocal8Bit().constData() );
g_config->save();
QApplication::setStyle( new fceuStyle() );
@ -493,7 +493,7 @@ void GuiConfDialog_t::openQPal(void)
if (d.exists())
{
urls << QUrl::fromLocalFile(d.absolutePath());
iniPath = d.absolutePath().toStdString();
iniPath = d.absolutePath().toLocal8Bit().constData();
}
}
#ifdef WIN32
@ -504,7 +504,7 @@ void GuiConfDialog_t::openQPal(void)
if (d.exists())
{
urls << QUrl::fromLocalFile(d.absolutePath());
iniPath = d.absolutePath().toStdString();
iniPath = d.absolutePath().toLocal8Bit().constData();
}
#endif
@ -550,11 +550,11 @@ void GuiConfDialog_t::openQPal(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
custom_qpal_path->setText(filename.toStdString().c_str());
custom_qpal_path->setText(filename.toLocal8Bit().constData());
g_config->setOption("SDL.QPaletteFile", filename.toStdString().c_str() );
g_config->setOption("SDL.QPaletteFile", filename.toLocal8Bit().constData() );
g_config->save();
QApplication::setStyle( new fceuStyle() );
@ -590,12 +590,19 @@ fceuStyle::fceuStyle(QStyle *style) : QProxyStyle(style)
{
//printf("New Style!!!\n");
setObjectName( style->objectName() );
if (style != nullptr)
{
setObjectName( style->objectName() );
}
else
{
setObjectName("fusion");
}
}
fceuStyle::~fceuStyle(void)
{
//printf("Style Deleted: %s\n", objectName().toStdString().c_str() );
//printf("Style Deleted: %s\n", objectName().toLocal8Bit().constData() );
if ( rccFilePath.size() > 0 )
{
@ -609,35 +616,31 @@ fceuStyle::~fceuStyle(void)
QStyle *fceuStyle::styleBase(QStyle *style) const
{
std::string s;
static QStyle *base;
static QStyle *base = nullptr;
#ifdef WIN32
//QString defaultStyle("windows"); // fusion is much more stable and consistent.
QString styleName("fusion");
#else
QString styleName("fusion");
#endif
if ( g_config != NULL )
if ( g_config != nullptr )
{
g_config->getOption("SDL.GuiStyle", &s );
g_config->getOption("SDL.GuiStyle", &styleName );
}
if ( s.size() == 0 )
{
int i, idx = -1;
#ifdef WIN32
//QString defaultStyle("windows"); // fusion is much more stable and consistent.
QString defaultStyle("fusion");
#elif __APPLE__
QString defaultStyle("fusion");
#else
QString defaultStyle("fusion");
#endif
QStringList styleKeys = QStyleFactory::keys();
for (i=0; i<styleKeys.size(); i++)
{
//printf("Style: '%s'\n", styleKeys[i].toStdString().c_str() );
//printf("Style: '%s'\n", styleKeys[i].toLocal8Bit().constData() );
if ( defaultStyle.compare( styleKeys[i], Qt::CaseInsensitive ) == 0 )
if ( styleName.compare( styleKeys[i], Qt::CaseInsensitive ) == 0 )
{
//printf("Style Match: %s\n", styleKeys[i].toStdString().c_str() );
//printf("Style Match: %s\n", styleKeys[i].toLocal8Bit().constData() );
idx = i;
break;
}
@ -645,17 +648,13 @@ QStyle *fceuStyle::styleBase(QStyle *style) const
if ( (idx >= 0) && (idx < styleKeys.size()) )
{
s = styleKeys[idx].toStdString();
}
else
{
s.assign("fusion");
styleName = styleKeys[idx];
}
}
if ( style == NULL )
if ( style == nullptr )
{
base = QStyleFactory::create(QString::fromStdString(s));
base = QStyleFactory::create(styleName);
}
else
{
@ -772,7 +771,7 @@ void fceuStyle::polish(QApplication *app)
}
else
{
app->setStyleSheet(NULL);
app->setStyleSheet(nullptr);
}
}
//----------------------------------------------------
@ -852,7 +851,7 @@ static const char *getRoleText( QPalette::ColorRole role )
rTxt = "NoRole";
break;
default:
rTxt = NULL;
rTxt = nullptr;
break;
}
return rTxt;
@ -869,7 +868,7 @@ static int writeQPaletteToFile( const char *path, QPalette *pal )
fp = fopen( path, "w");
if ( fp == NULL )
if ( fp == nullptr )
{
printf("Error: Failed to Open File for writing: '%s'\n", path );
return -1;
@ -904,7 +903,7 @@ static int writeQPaletteToFile( const char *path, QPalette *pal )
{
c = pal->color( g, r );
fprintf( fp, "%s::%s = %s \n", gTxt, rTxt, c.name().toStdString().c_str() );
fprintf( fp, "%s::%s = %s \n", gTxt, rTxt, c.name().toLocal8Bit().constData() );
}
}
}
@ -928,7 +927,7 @@ static int readQPaletteFromFile( const char *path, QPalette *pal )
fp = fopen( path, "r");
if ( fp == NULL )
if ( fp == nullptr )
{
printf("Error: Failed to Open File for writing: '%s'\n", path );
return -1;
@ -987,7 +986,7 @@ static int readQPaletteFromFile( const char *path, QPalette *pal )
continue;
}
rTxtMatch = NULL;
rTxtMatch = nullptr;
r = QPalette::WindowText;
@ -1006,7 +1005,7 @@ static int readQPaletteFromFile( const char *path, QPalette *pal )
}
}
if ( rTxtMatch == NULL ) continue;
if ( rTxtMatch == nullptr ) continue;
color = pal->color( g, r );
@ -1156,7 +1155,7 @@ GuiPaletteEditDialog_t::~GuiPaletteEditDialog_t(void)
{
if ( editDialog == this )
{
editDialog = NULL;
editDialog = nullptr;
}
}
//----------------------------------------------------
@ -1201,7 +1200,7 @@ void GuiPaletteEditDialog_t::paletteSaveAs(void)
if (d.exists())
{
urls << QUrl::fromLocalFile(d.absolutePath());
iniPath = d.absolutePath().toStdString();
iniPath = d.absolutePath().toLocal8Bit().constData();
}
}
#ifdef WIN32
@ -1212,7 +1211,7 @@ void GuiPaletteEditDialog_t::paletteSaveAs(void)
if (d.exists())
{
urls << QUrl::fromLocalFile(d.absolutePath());
iniPath = d.absolutePath().toStdString();
iniPath = d.absolutePath().toLocal8Bit().constData();
}
#endif
@ -1259,11 +1258,11 @@ void GuiPaletteEditDialog_t::paletteSaveAs(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
writeQPaletteToFile( filename.toStdString().c_str(), &pal );
writeQPaletteToFile( filename.toLocal8Bit().constData(), &pal );
//g_config->setOption("SDL.QPaletteFile", filename.toStdString().c_str() );
//g_config->setOption("SDL.QPaletteFile", filename.toLocal8Bit().constData() );
//g_config->save();
//QApplication::setStyle( new fceuStyle() );
@ -1328,17 +1327,17 @@ void GuiPaletteColorSelect::setText(void)
gTxt = "Inactive";
break;
default:
gTxt = NULL;
gTxt = nullptr;
break;
}
rTxt = getRoleText( role );
if ( (gTxt == NULL) || (rTxt == NULL) )
if ( (gTxt == nullptr) || (rTxt == nullptr) )
{
return;
}
sprintf( stmp, "%s :: %s", gTxt, rTxt );
snprintf( stmp, sizeof(stmp), "%s :: %s", gTxt, rTxt );
lbl->setText( tr(stmp) );
@ -1357,8 +1356,8 @@ void GuiPaletteColorSelect::updateColor(void)
{
txtColor.setRgb( 255, 255, 255 );
}
sprintf( stmp, "QLabel { background-color : %s; color : %s; border-color : black; }",
color.name().toStdString().c_str(), txtColor.name().toStdString().c_str() );
snprintf( stmp, sizeof(stmp), "QLabel { background-color : %s; color : %s; border-color : black; }",
color.name().toLocal8Bit().constData(), txtColor.name().toLocal8Bit().constData() );
lbl->setStyleSheet( stmp );
}

View File

@ -33,8 +33,6 @@ public:
~fceuStyle(void);
QStyle *baseStyle() const;
void polish(QPalette &palette) override;
void polish(QApplication *app) override;

View File

@ -44,19 +44,11 @@
#ifdef WIN32
#include <Windows.h>
#include <htmlhelp.h>
//#else // Linux or Unix or APPLE
//#include <unistd.h>
//#include <sys/types.h>
//#include <sys/wait.h>
#endif
//#if defined(__linux__) || defined(__unix__) || defined(__APPLE__)
//static int forkHelpFileViewer( const char *chmViewer, const char *filepath );
//#endif
void consoleWin_t::OpenHelpWindow(std::string subpage)
void consoleWin_t::OpenHelpWindow(QString subpage)
{
std::string helpFileName;
QString helpFileName;
g_config->getOption ("SDL.HelpFilePath", &helpFileName );
@ -70,15 +62,15 @@ void consoleWin_t::OpenHelpWindow(std::string subpage)
#endif
#ifdef __APPLE__
if ( !QFile( QString::fromStdString(helpFileName) ).exists() )
if ( !QFile( helpFileName ).exists() )
{
// Search for MacOSX DragNDrop Resources
helpFileName = QApplication::applicationDirPath().toStdString() + "/../Resources/fceux.qhc";
helpFileName = QApplication::applicationDirPath() + QString("/../Resources/fceux.qhc");
}
#endif
}
if ( !QFile( QString::fromStdString(helpFileName) ).exists() )
if ( !QFile( helpFileName ).exists() )
{
helpFileName = findHelpFile();
}
@ -91,7 +83,7 @@ void consoleWin_t::OpenHelpWindow(std::string subpage)
#ifdef WIN32
if (subpage.length() > 0)
{
helpFileName = helpFileName + "::/" + subpage + ".htm";
helpFileName = helpFileName + QString("::/") + subpage + QString(".htm");
}
#else
// Subpage indexing is not supported by linux chm viewer
@ -101,10 +93,10 @@ void consoleWin_t::OpenHelpWindow(std::string subpage)
#ifdef WIN32
// Windows specific HtmlHelp library function
helpWin = HtmlHelp( HWND(winId()), helpFileName.c_str(), HH_DISPLAY_TOPIC, (DWORD)NULL);
helpWin = HtmlHelpA( HWND(winId()), helpFileName.toLocal8Bit().constData(), HH_DISPLAY_TOPIC, (DWORD)NULL);
if ( helpWin == NULL )
{
printf("Error: Failed to open help file '%s'\n", helpFileName.c_str() );
printf("Error: Failed to open help file '%s'\n", helpFileName.toLocal8Bit().constData() );
}
#else
if ( helpWin > 0 )
@ -115,7 +107,7 @@ void consoleWin_t::OpenHelpWindow(std::string subpage)
//helpWin = forkHelpFileViewer( helpFileViewer.c_str(), helpFileName.c_str() );
#ifdef _USE_QHELP
HelpDialog *win = new HelpDialog( helpFileName.c_str(), this);
HelpDialog *win = new HelpDialog( helpFileName, this);
win->show();
#endif
@ -123,32 +115,11 @@ void consoleWin_t::OpenHelpWindow(std::string subpage)
#endif
}
//void consoleWin_t::helpPageMaint(void)
//{
//#ifdef WIN32
// // Does any help page cleanup need to be done in windows?
//#else
// if ( helpWin > 0 )
// { // Calling waitpid is important to ensure that CHM viewer process is cleaned up
// // in the event that it exits. Otherwise zombie processes will be left.
// int pid, wstat=0;
//
// pid = waitpid( -1, &wstat, WNOHANG );
//
// if ( pid == helpWin )
// {
// //printf("Help CHM Viewer Closed\n");
// helpWin = 0;
// }
// }
//
//#endif
//}
std::string consoleWin_t::findHelpFile(void)
QString consoleWin_t::findHelpFile(void)
{
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
QString last;
std::string dir;
QFileDialog dialog(this, tr("Open Help File") );
QList<QUrl> urls;
@ -175,7 +146,7 @@ std::string consoleWin_t::findHelpFile(void)
if ( last.size() > 0 )
{
getDirFromFile( last.c_str(), dir );
getDirFromFile( last.toLocal8Bit().constData(), dir );
dialog.setDirectory( tr(dir.c_str()) );
}
@ -207,11 +178,11 @@ std::string consoleWin_t::findHelpFile(void)
{
return last;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
g_config->setOption ("SDL.HelpFilePath", filename.toStdString().c_str() );
g_config->setOption ("SDL.HelpFilePath", filename);
return filename.toStdString();
return filename;
}
//#if defined(__linux__) || defined(__unix__) || defined(__APPLE__)
@ -239,7 +210,7 @@ std::string consoleWin_t::findHelpFile(void)
//-----------------------------------------------------------------------------------------------
//--- Help Page Dialog
//-----------------------------------------------------------------------------------------------
HelpDialog::HelpDialog( const char *helpFileName, QWidget *parent)
HelpDialog::HelpDialog( const QString& helpFileName, QWidget *parent)
: QDialog(parent, Qt::Window)
{
int useNativeMenuBar;

View File

@ -25,7 +25,7 @@ class HelpDialog : public QDialog
Q_OBJECT
public:
HelpDialog( const char *helpFileName, QWidget *parent = 0);
HelpDialog( const QString& helpFileName, QWidget *parent = 0);
~HelpDialog(void);
protected:

View File

@ -865,7 +865,7 @@ int HexEditorCharTable_t::loadFromFile( const char *filepath )
if ( hexValue > 255 )
{
sprintf( errMsg, "Error: Line %i: Hex Value 0x%X exceeds 0xFF \n", lineNum, hexValue );
snprintf( errMsg, sizeof(errMsg), "Error: Line %i: Hex Value 0x%X exceeds 0xFF \n", lineNum, hexValue );
retVal = -1;
continue;
}
@ -874,7 +874,7 @@ int HexEditorCharTable_t::loadFromFile( const char *filepath )
if ( line[i] != '=' )
{
sprintf( errMsg, "Error: Line %i: Expected assignment operator '=' but got '%c' \n", lineNum, line[i] );
snprintf( errMsg, sizeof(errMsg), "Error: Line %i: Expected assignment operator '=' but got '%c' \n", lineNum, line[i] );
retVal = -1;
continue;
}
@ -929,7 +929,7 @@ int HexEditorCharTable_t::loadFromFile( const char *filepath )
if ( mapValue > 255 )
{
sprintf( errMsg, "Error: Line %i: Map Value 0x%X exceeds 0xFF \n", lineNum, mapValue );
snprintf( errMsg, sizeof(errMsg), "Error: Line %i: Map Value 0x%X exceeds 0xFF \n", lineNum, mapValue );
retVal = -1;
continue;
}
@ -1048,7 +1048,7 @@ void HexEditorFindDialog_t::runSearch(void)
{
int i=0;
unsigned char v;
std::string s = searchBox->text().toStdString();
std::string s = searchBox->text().toLocal8Bit().constData();
std::vector <unsigned char> varray;
if ( s.size() == 0 )
@ -1519,7 +1519,7 @@ void HexEditorDialog_t::setWindowTitle(void)
modeString = memViewNames[ editor->getMode() ];
sprintf( stmp, "Hex Editor - %s: 0x%04X", modeString, editor->getAddr() );
snprintf( stmp, sizeof(stmp), "Hex Editor - %s: 0x%04X", modeString, editor->getAddr() );
QDialog::setWindowTitle( tr(stmp) );
@ -1667,9 +1667,9 @@ void HexEditorDialog_t::saveRomFileAs(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
iNesSaveAs( filename.toStdString().c_str() );
iNesSaveAs( filename.toLocal8Bit().constData() );
}
//----------------------------------------------------------------------------
void HexEditorDialog_t::loadTableFromFile(void)
@ -1709,9 +1709,9 @@ void HexEditorDialog_t::loadTableFromFile(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
editor->charTable.loadFromFile( filename.toStdString().c_str() );
editor->charTable.loadFromFile( filename.toLocal8Bit().constData() );
unloadTableAct->setEnabled( editor->charTable.customMapLoaded );
}
@ -2118,9 +2118,9 @@ void QHexEdit::changeFontRequest(void)
calcFontData();
//printf("Font Changed to: '%s'\n", font.toString().toStdString().c_str() );
//printf("Font Changed to: '%s'\n", font.toString().toLocal8Bit().constData() );
g_config->setOption("SDL.HexEditFont", font.toString().toStdString().c_str() );
g_config->setOption("SDL.HexEditFont", font.toString().toLocal8Bit().constData() );
}
}
//----------------------------------------------------------------------------
@ -2253,7 +2253,7 @@ void QHexEdit::openGotoAddrDialog(void)
QHBoxLayout *hbox;
QPushButton *okButton, *cancelButton;
sprintf( stmp, "Specify Address [ 0x0 -> 0x%X ]", mb.size()-1 );
snprintf( stmp, sizeof(stmp), "Specify Address [ 0x0 -> 0x%X ]", mb.size()-1 );
vbox = new QVBoxLayout();
hbox = new QHBoxLayout();
@ -2337,7 +2337,7 @@ void QHexEdit::loadClipboard( const char *txt )
void QHexEdit::pasteFromClipboard(void)
{
int i, nbytes=0, val, addr;
std::string s = clipboard->text().toStdString();
std::string s = clipboard->text().toLocal8Bit().constData();
const char *c;
unsigned char *buf;
@ -2418,7 +2418,7 @@ void QHexEdit::loadHighlightToClipboard(void)
for (a=startAddr; a<=endAddr; a++)
{
sprintf( c, "%02X ", memAccessFunc(a) );
snprintf( c, sizeof(c), "%02X ", memAccessFunc(a) );
s.append(c);
}
@ -3145,17 +3145,17 @@ void QHexEdit::contextMenuEvent(QContextMenuEvent *event)
subMenu->addAction(act);
connect( act, SIGNAL(triggered(void)), this, SLOT(frzRamUnsetAll(void)) );
sprintf( stmp, "Add &Read Breakpoint for Address $%04X", addr );
snprintf( stmp, sizeof(stmp), "Add &Read Breakpoint for Address $%04X", addr );
act = new QAction(tr(stmp), &menu);
menu.addAction(act);
connect( act, SIGNAL(triggered(void)), this, SLOT(addRamReadBP(void)) );
sprintf( stmp, "Add &Write Breakpoint for Address $%04X", addr );
snprintf( stmp, sizeof(stmp), "Add &Write Breakpoint for Address $%04X", addr );
act = new QAction(tr(stmp), &menu);
menu.addAction(act);
connect( act, SIGNAL(triggered(void)), this, SLOT(addRamWriteBP(void)) );
sprintf( stmp, "Add &Execute Breakpoint for Address $%04X", addr );
snprintf( stmp, sizeof(stmp), "Add &Execute Breakpoint for Address $%04X", addr );
act = new QAction(tr(stmp), &menu);
menu.addAction(act);
connect( act, SIGNAL(triggered(void)), this, SLOT(addRamExecuteBP(void)) );
@ -3167,7 +3167,7 @@ void QHexEdit::contextMenuEvent(QContextMenuEvent *event)
if ( romAddr >= 0 )
{
jumpToRomValue = romAddr;
sprintf( stmp, "&Go Here in ROM File: (%08X)", romAddr );
snprintf( stmp, sizeof(stmp), "&Go Here in ROM File: (%08X)", romAddr );
act = new QAction(tr(stmp), &menu);
menu.addAction(act);
connect( act, SIGNAL(triggered(void)), this, SLOT(jumpToROM(void)) );
@ -3181,12 +3181,12 @@ void QHexEdit::contextMenuEvent(QContextMenuEvent *event)
break;
case MODE_NES_PPU:
{
sprintf( stmp, "Add &Read Breakpoint for Address $%04X", addr );
snprintf( stmp, sizeof(stmp), "Add &Read Breakpoint for Address $%04X", addr );
act = new QAction(tr(stmp), &menu);
menu.addAction(act);
connect( act, SIGNAL(triggered(void)), this, SLOT(addPpuReadBP(void)) );
sprintf( stmp, "Add &Write Breakpoint for Address $%04X", addr );
snprintf( stmp, sizeof(stmp), "Add &Write Breakpoint for Address $%04X", addr );
act = new QAction(tr(stmp), &menu);
menu.addAction(act);
connect( act, SIGNAL(triggered(void)), this, SLOT(addPpuWriteBP(void)) );
@ -3236,16 +3236,16 @@ void QHexEdit::addBookMarkCB(void)
{
default:
case MODE_NES_RAM:
sprintf( stmp, "CPU %04X", ctxAddr );
snprintf( stmp, sizeof(stmp), "CPU %04X", ctxAddr );
break;
case MODE_NES_PPU:
sprintf( stmp, "PPU %04X", ctxAddr );
snprintf( stmp, sizeof(stmp), "PPU %04X", ctxAddr );
break;
case MODE_NES_OAM:
sprintf( stmp, "OAM %04X", ctxAddr );
snprintf( stmp, sizeof(stmp), "OAM %04X", ctxAddr );
break;
case MODE_NES_ROM:
sprintf( stmp, "ROM %04X", ctxAddr );
snprintf( stmp, sizeof(stmp), "ROM %04X", ctxAddr );
break;
}
@ -3258,7 +3258,7 @@ void QHexEdit::addBookMarkCB(void)
if ( QDialog::Accepted == ret )
{
hbm.addBookMark( ctxAddr, viewMode, dialog.textValue().toStdString().c_str() );
hbm.addBookMark( ctxAddr, viewMode, dialog.textValue().toLocal8Bit().constData() );
parent->populateBookmarkMenu();
}
}
@ -3436,7 +3436,7 @@ void QHexEdit::addRamReadBP(void)
if ( ctxAddr >= 0x8000 )
{
sprintf(cond, "K==#%02X", getBank(ctxAddr));
snprintf(cond, sizeof(cond), "K==#%02X", getBank(ctxAddr));
}
retval = NewBreak( name, ctxAddr, -1, type, cond, numWPs, true);
@ -3463,7 +3463,7 @@ void QHexEdit::addRamWriteBP(void)
if ( ctxAddr >= 0x8000 )
{
sprintf(cond, "K==#%02X", getBank(ctxAddr));
snprintf(cond, sizeof(cond), "K==#%02X", getBank(ctxAddr));
}
retval = NewBreak( name, ctxAddr, -1, type, cond, numWPs, true);
@ -3490,7 +3490,7 @@ void QHexEdit::addRamExecuteBP(void)
if ( ctxAddr >= 0x8000 )
{
sprintf(cond, "K==#%02X", getBank(ctxAddr));
snprintf(cond, sizeof(cond), "K==#%02X", getBank(ctxAddr));
}
retval = NewBreak( name, ctxAddr, -1, type, cond, numWPs, true);
@ -3920,7 +3920,7 @@ void QHexEdit::paintEvent(QPaintEvent *event)
painter.setPen( fgColor );
sprintf( txt, "%06X", addr );
snprintf( txt, sizeof(txt), "%06X", addr );
painter.drawText( x, y, tr(txt) );
x = pxHexOffset - pxLineXScroll;

View File

@ -442,7 +442,7 @@ void HotKeyConfSetDialog_t::assignHotkey(QKeyEvent *event)
(k == SDLK_LGUI) || (k == SDLK_RGUI) ||
(k == SDLK_CAPSLOCK);
//printf("Assign: '%s' %i 0x%08x\n", ks.toString().toStdString().c_str(), event->key(), event->key() );
//printf("Assign: '%s' %i 0x%08x\n", ks.toString().toLocal8Bit().constData(), event->key(), event->key() );
if ((k != SDLK_UNKNOWN) && !keyIsModifier)
{
@ -452,7 +452,7 @@ void HotKeyConfSetDialog_t::assignHotkey(QKeyEvent *event)
confName = prefix + Hotkeys[item->hkIdx].getConfigName();
keyText = ks.toString().toStdString();
keyText = ks.toString().toLocal8Bit().constData();
g_config->setOption( confName, keyText);

View File

@ -66,7 +66,7 @@ InputConfDialog_t::InputConfDialog_t(QWidget *parent)
QPalette pal;
QColor color;
char stmp[256];
int fourscore, autoInputPreset;
int fourscore, autoInputPreset, newDeviceBehavior;
pal = this->palette();
@ -80,11 +80,23 @@ InputConfDialog_t::InputConfDialog_t(QWidget *parent)
nesInputFrame = new QGroupBox(tr("NES-Style Input Ports"));
vbox1 = new QVBoxLayout();
hbox = new QHBoxLayout();
newDeviceOptionBox = new QComboBox();
fourScoreEna = new QCheckBox(tr("Attach 4-Score (Implies four gamepads)"));
port2Mic = new QCheckBox(tr("Replace Port 2 Start with Microphone"));
autoPreset = new QCheckBox(tr("Auto Load/Save Presets at ROM Open/Close"));
hbox = new QHBoxLayout();
hbox->addWidget( new QLabel(tr("On New Gamepad Device Detection:")), 1);
hbox->addWidget(newDeviceOptionBox, 3);
vbox1->addLayout(hbox);
newDeviceOptionBox->addItem("Do nothing", 0);
newDeviceOptionBox->addItem("Prompt User for Reconfigure", 1);
newDeviceOptionBox->addItem("Auto Reconfigure", 2);
g_config->getOption("SDL.NewInputDeviceBehavior", &newDeviceBehavior);
setComboBoxFromValue( newDeviceOptionBox, newDeviceBehavior );
g_config->getOption("SDL.FourScore", &fourscore);
fourScoreEna->setChecked(fourscore);
port2Mic->setChecked(replaceP2StartWithMicrophone);
@ -92,6 +104,7 @@ InputConfDialog_t::InputConfDialog_t(QWidget *parent)
g_config->getOption("SDL.AutoInputPreset", &autoInputPreset);
autoPreset->setChecked(autoInputPreset);
hbox = new QHBoxLayout();
hbox->addWidget(fourScoreEna);
hbox->addWidget(port2Mic);
vbox1->addLayout(hbox);
@ -168,7 +181,7 @@ InputConfDialog_t::InputConfDialog_t(QWidget *parent)
color = pal.color(QPalette::WindowText);
sprintf(stmp, "border: 2px solid #%02X%02X%02X", color.red(), color.green(), color.blue());
snprintf(stmp, sizeof(stmp), "border: 2px solid #%02X%02X%02X", color.red(), color.green(), color.blue());
//printf("%s\n", stmp);
nesPortLabel[0]->setAlignment(Qt::AlignCenter);
@ -240,6 +253,7 @@ InputConfDialog_t::InputConfDialog_t(QWidget *parent)
connect(port2Mic, SIGNAL(stateChanged(int)), this, SLOT(port2MicChanged(int)));
connect(autoPreset, SIGNAL(stateChanged(int)), this, SLOT(autoPresetChanged(int)));
connect(newDeviceOptionBox , SIGNAL(activated(int)), this, SLOT(newDeviceSettingsChange(int)));
connect(nesPortComboxBox[0], SIGNAL(activated(int)), this, SLOT(port1Select(int)));
connect(nesPortComboxBox[1], SIGNAL(activated(int)), this, SLOT(port2Select(int)));
connect(expPortComboxBox, SIGNAL(activated(int)), this, SLOT(expSelect(int)));
@ -362,6 +376,12 @@ void InputConfDialog_t::updatePortComboBoxes(void)
}
}
//----------------------------------------------------------------------------
void InputConfDialog_t::newDeviceSettingsChange(int index)
{
g_config->setOption("SDL.NewInputDeviceBehavior", newDeviceOptionBox->itemData(index).toInt());
g_config->save();
}
//----------------------------------------------------------------------------
void InputConfDialog_t::port1Select(int index)
{
//printf("Port 1 Number:%i \n", index);
@ -489,10 +509,10 @@ void InputConfDialog_t::openLoadPresetFile(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
FCEU_WRAPPER_LOCK();
loadInputSettingsFromFile(filename.toStdString().c_str());
loadInputSettingsFromFile(filename.toLocal8Bit().constData());
FCEU_WRAPPER_UNLOCK();
updatePortLabels();
@ -561,9 +581,9 @@ void InputConfDialog_t::openSavePresetFile(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
saveInputSettingsToFile(filename.toStdString().c_str());
saveInputSettingsToFile(filename.toLocal8Bit().constData());
}
//----------------------------------------------------------------------------
void InputConfDialog_t::updatePeriodic(void)

View File

@ -43,6 +43,7 @@ protected:
QComboBox *expPortComboxBox;
QPushButton *loadConfigButton;
QPushButton *saveConfigButton;
QComboBox* newDeviceOptionBox;
int curNesInput[3];
int usrNesInput[3];
@ -62,6 +63,7 @@ private slots:
void port1Select(int index);
void port2Select(int index);
void expSelect(int index);
void newDeviceSettingsChange(int index);
void fourScoreChanged(int state);
void port2MicChanged(int state);
void autoPresetChanged(int state);

View File

@ -406,9 +406,9 @@ void LuaControlDialog_t::openLuaScriptFile(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
g_config->setOption("SDL.LastLoadLua", filename.toStdString().c_str());
g_config->setOption("SDL.LastLoadLua", filename.toLocal8Bit().constData());
scriptPath->setText(filename);
@ -420,10 +420,10 @@ void LuaControlDialog_t::startLuaScript(void)
#ifdef _S9XLUA_H
outBuf.clear();
FCEU_WRAPPER_LOCK();
if (0 == FCEU_LoadLuaCode(scriptPath->text().toStdString().c_str(), scriptArgs->text().toStdString().c_str()))
if (0 == FCEU_LoadLuaCode(scriptPath->text().toLocal8Bit().constData(), scriptArgs->text().toLocal8Bit().constData()))
{
char error_msg[2048];
sprintf( error_msg, "Error: Could not open the selected lua script: '%s'\n", scriptPath->text().toStdString().c_str());
snprintf( error_msg, sizeof(error_msg), "Error: Could not open the selected lua script: '%s'\n", scriptPath->text().toLocal8Bit().constData());
FCEUD_PrintError(error_msg);
}
FCEU_WRAPPER_UNLOCK();

View File

@ -241,13 +241,13 @@ void MoviePlayDialog_t::updateMovieText(void)
}
idx = movSelBox->currentIndex();
path = movSelBox->itemText(idx).toStdString();
path = movSelBox->itemText(idx).toLocal8Bit().constData();
fp = FCEU_fopen(path.c_str(), 0, "rb", 0);
if (fp == NULL)
{
sprintf(stmp, "Error: Failed to open file '%s'", path.c_str());
snprintf(stmp, sizeof(stmp), "Error: Failed to open file '%s'", path.c_str());
showErrorMsgWindow(stmp);
clearMovieText();
return;
@ -260,7 +260,7 @@ void MoviePlayDialog_t::updateMovieText(void)
validator->setMinMax(0, info.num_frames);
sprintf(stmp, "%u", (unsigned)info.num_frames);
snprintf(stmp, sizeof(stmp), "%u", (unsigned)info.num_frames);
movFramesLbl->setText(tr(stmp));
pauseAtFrameEntry->setText(tr(stmp));
@ -272,11 +272,11 @@ void MoviePlayDialog_t::updateMovieText(void)
int seconds = num_seconds % 60;
int minutes = (num_seconds / 60) % 60;
int hours = (num_seconds / 60 / 60) % 60;
sprintf(stmp, "%02d:%02d:%02d.%02d", hours, minutes, seconds, fraction);
snprintf(stmp, sizeof(stmp), "%02d:%02d:%02d.%02d", hours, minutes, seconds, fraction);
movLenLbl->setText(tr(stmp));
sprintf(stmp, "%u", (unsigned)info.rerecord_count);
snprintf(stmp, sizeof(stmp), "%u", (unsigned)info.rerecord_count);
recCountLbl->setText(tr(stmp));
@ -297,11 +297,11 @@ void MoviePlayDialog_t::updateMovieText(void)
if (info.emu_version_used < 20000)
{
sprintf(stmp, "FCEU %u.%02u.%02u%s", info.emu_version_used / 10000, (info.emu_version_used / 100) % 100, (info.emu_version_used) % 100, info.emu_version_used < 9813 ? " (blip)" : "");
snprintf(stmp, sizeof(stmp), "FCEU %u.%02u.%02u%s", info.emu_version_used / 10000, (info.emu_version_used / 100) % 100, (info.emu_version_used) % 100, info.emu_version_used < 9813 ? " (blip)" : "");
}
else
{
sprintf(stmp, "FCEUX %u.%02u.%02u", info.emu_version_used / 10000, (info.emu_version_used / 100) % 100, (info.emu_version_used) % 100);
snprintf(stmp, sizeof(stmp), "FCEUX %u.%02u.%02u", info.emu_version_used / 10000, (info.emu_version_used / 100) % 100, (info.emu_version_used) % 100);
}
emuUsedLbl->setText(tr(stmp));
@ -315,14 +315,14 @@ void MoviePlayDialog_t::updateMovieText(void)
if (strcmp(stmp, md5_asciistr(info.md5_of_rom_used)) != 0)
{
sprintf(stmp, "Warning: Selected movie file '%s' may not have been created using the currently loaded ROM.", path.c_str());
snprintf(stmp, sizeof(stmp), "Warning: Selected movie file '%s' may not have been created using the currently loaded ROM.", path.c_str());
showWarningMsgWindow(stmp);
}
}
}
else
{
sprintf(stmp, "Error: Selected file '%s' does not have a recognized movie format.", path.c_str());
snprintf(stmp, sizeof(stmp), "Error: Selected file '%s' does not have a recognized movie format.", path.c_str());
showErrorMsgWindow(stmp);
clearMovieText();
}
@ -337,7 +337,7 @@ int MoviePlayDialog_t::addFileToList(const char *file, bool setActive)
for (int i = 0; i < movSelBox->count(); i++)
{
if (strcmp(file, movSelBox->itemText(i).toStdString().c_str()) == 0)
if (strcmp(file, movSelBox->itemText(i).toLocal8Bit().constData()) == 0)
{
if (setActive)
{
@ -402,7 +402,7 @@ void MoviePlayDialog_t::scanDirectory(const char *dirPath, const char *md5)
{
QFileInfo fileInfo = list.at(i);
path = std::string(dirPath) + fileInfo.fileName().toStdString();
path = std::string(dirPath) + fileInfo.fileName().toLocal8Bit().constData();
//printf("File: '%s'\n", path.c_str() );
@ -465,13 +465,13 @@ void MoviePlayDialog_t::playMovie(void)
idx = movSelBox->currentIndex();
path = movSelBox->itemText(idx).toStdString();
path = movSelBox->itemText(idx).toLocal8Bit().constData();
replayReadOnlySetting = openReadOnly->isChecked();
if (pauseAtFrame->isChecked())
{
pauseframe = strtol(pauseAtFrameEntry->text().toStdString().c_str(), NULL, 0);
pauseframe = strtol(pauseAtFrameEntry->text().toLocal8Bit().constData(), NULL, 0);
}
FCEU_WRAPPER_LOCK();
@ -485,7 +485,7 @@ void MoviePlayDialog_t::playMovie(void)
if (movieLoadError)
{
char stmp[256];
sprintf(stmp, "Error: Could not load movie file: %s \n", path.c_str());
snprintf(stmp, sizeof(stmp), "Error: Could not load movie file: %s \n", path.c_str());
showErrorMsgWindow(stmp);
}
else
@ -539,7 +539,7 @@ void MoviePlayDialog_t::openMovie(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
if (GameInfo)
{
@ -547,7 +547,7 @@ void MoviePlayDialog_t::openMovie(void)
strcpy(md5, md5_asciistr(GameInfo->MD5));
if (checkMD5Sum(filename.toStdString().c_str(), md5))
if (checkMD5Sum(filename.toLocal8Bit().constData(), md5))
{
md5Match = 1;
}
@ -558,11 +558,11 @@ void MoviePlayDialog_t::openMovie(void)
}
}
addFileToList(filename.toStdString().c_str(), true);
addFileToList(filename.toLocal8Bit().constData(), true);
updateMovieText();
g_config->setOption("SDL.LastOpenMovie", filename.toStdString().c_str());
g_config->setOption("SDL.LastOpenMovie", filename.toLocal8Bit().constData());
return;
}

View File

@ -156,7 +156,7 @@ void MovieRecordDialog_t::setFilePath( QString s )
dirEdit->setText( fi.absolutePath() );
fileEdit->setText( fi.fileName() );
filepath = s.toStdString();
filepath = s.toLocal8Bit().constData();
}
//----------------------------------------------------------------------------
void MovieRecordDialog_t::stateSelChanged( int idx )
@ -249,11 +249,11 @@ void MovieRecordDialog_t::setLoadState(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
g_config->setOption ("SDL.LastLoadStateFrom", filename.toStdString().c_str() );
g_config->setOption ("SDL.LastLoadStateFrom", filename.toLocal8Bit().constData() );
ic_file = filename.toStdString();
ic_file = filename.toLocal8Bit().constData();
}
//----------------------------------------------------------------------------
void MovieRecordDialog_t::recordMovie(void)
@ -277,7 +277,7 @@ void MovieRecordDialog_t::recordMovie(void)
if (loadStateFailed)
{
char str [1024];
sprintf(str, "Failed to load save state \"%s\".\nRecording from current state instead...", ic_file.c_str());
snprintf(str, sizeof(str), "Failed to load save state \"%s\".\nRecording from current state instead...", ic_file.c_str());
FCEUD_PrintError(str);
}
}
@ -300,7 +300,7 @@ void MovieRecordDialog_t::recordMovie(void)
if ( startRecording )
{
std::string s = authorEdit->text().toStdString();
std::string s = authorEdit->text().toLocal8Bit().constData();
std::wstring author (s.begin (), s.end ());
FCEUI_printf("Recording movie to %s\n", filepath.c_str ());
FCEUI_SaveMovie (filepath.c_str(), flags, author);
@ -356,13 +356,13 @@ void MovieRecordDialog_t::browseFiles(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
int pauseframe;
g_config->getOption ("SDL.PauseFrame", &pauseframe);
g_config->setOption ("SDL.PauseFrame", 0);
FCEUI_printf ("Recording movie to %s\n", filename.toStdString().c_str() );
FCEUI_printf ("Recording movie to %s\n", filename.toLocal8Bit().constData() );
setFilePath( filename );
return;

View File

@ -284,7 +284,7 @@ ppuNameTableViewerDialog_t::ppuNameTableViewerDialog_t(QWidget *parent)
{
char stmp[8];
sprintf( stmp, "&%ix", i+1 );
snprintf( stmp, sizeof(stmp), "&%ix", i+1 );
zoomAct[i] = new QAction(tr(stmp), this);
zoomAct[i]->setCheckable(true);
@ -346,7 +346,7 @@ ppuNameTableViewerDialog_t::ppuNameTableViewerDialog_t(QWidget *parent)
strcpy( stmp, "Full" );
break;
default:
sprintf( stmp, "1/%i", 0x01 << i );
snprintf( stmp, sizeof(stmp), "1/%i", 0x01 << i );
break;
}
@ -768,28 +768,28 @@ void ppuNameTableViewerDialog_t::setPropertyLabels( int TileID, int TileX, int T
{
char stmp[32];
sprintf( stmp, "%02X", TileID);
snprintf( stmp, sizeof(stmp), "%02X", TileID);
tileIdxLbl->setText( tr(stmp) );
sprintf( stmp, "%04X", TileID << 4);
snprintf( stmp, sizeof(stmp), "%04X", TileID << 4);
tileAddrLbl->setText( tr(stmp) );
sprintf( stmp, "%0d, %0d", TileX, TileY);
snprintf( stmp, sizeof(stmp), "%0d, %0d", TileX, TileY);
tileLocLbl->setText( tr(stmp) );
sprintf(stmp,"%04X",PPUAddress);
snprintf( stmp, sizeof(stmp), "%04X",PPUAddress);
ppuAddrLbl->setText( tr(stmp) );
sprintf(stmp,"%1X",NameTable);
snprintf( stmp, sizeof(stmp), "%1X",NameTable);
nameTableLbl->setText( tr(stmp) );
sprintf(stmp,"%02X",Attrib);
snprintf( stmp, sizeof(stmp), "%02X",Attrib);
attrDataLbl->setText( tr(stmp) );
sprintf(stmp,"%04X",AttAddress);
snprintf( stmp, sizeof(stmp), "%04X",AttAddress);
attrAddrLbl->setText( tr(stmp) );
sprintf(stmp,"%04X", palAddr );
snprintf( stmp, sizeof(stmp), "%04X", palAddr );
palAddrLbl->setText( tr(stmp) );
}
@ -1341,25 +1341,25 @@ void ppuNameTableView_t::contextMenuEvent(QContextMenuEvent *event)
redrawtables = true;
sprintf( stmp, "Open Tile $%04X in PPU &Viewer", tileAddr );
snprintf( stmp, sizeof(stmp), "Open Tile $%04X in PPU &Viewer", tileAddr );
act = new QAction(tr(stmp), &menu);
//act->setShortcut( QKeySequence(tr("V")));
connect( act, SIGNAL(triggered(void)), this, SLOT(openTilePpuViewer(void)) );
menu.addAction( act );
sprintf( stmp, "Open &Tile Addr $%04X in Hex Editor", tileAddr );
snprintf( stmp, sizeof(stmp), "Open &Tile Addr $%04X in Hex Editor", tileAddr );
act = new QAction(tr(stmp), &menu);
//act->setShortcut( QKeySequence(tr("H")));
connect( act, SIGNAL(triggered(void)), this, SLOT(openTileAddrHexEdit(void)) );
menu.addAction( act );
sprintf( stmp, "Open &Attr Addr $%04X in Hex Editor", atrbAddr );
snprintf( stmp, sizeof(stmp), "Open &Attr Addr $%04X in Hex Editor", atrbAddr );
act = new QAction(tr(stmp), &menu);
//act->setShortcut( QKeySequence(tr("H")));
connect( act, SIGNAL(triggered(void)), this, SLOT(openAtrbAddrHexEdit(void)) );
menu.addAction( act );
sprintf( stmp, "Open &PPU Addr $%04X in Hex Editor", ppuAddr );
snprintf( stmp, sizeof(stmp), "Open &PPU Addr $%04X in Hex Editor", ppuAddr );
act = new QAction(tr(stmp), &menu);
//act->setShortcut( QKeySequence(tr("H")));
connect( act, SIGNAL(triggered(void)), this, SLOT(openPpuAddrHexEdit(void)) );

3267
src/drivers/Qt/NetPlay.cpp Normal file

File diff suppressed because it is too large Load Diff

532
src/drivers/Qt/NetPlay.h Normal file
View File

@ -0,0 +1,532 @@
// NetPlay.h
//
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <list>
#include <functional>
#include <QFile>
#include <QTemporaryFile>
#include <QWidget>
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QComboBox>
#include <QCheckBox>
#include <QSpinBox>
#include <QPushButton>
#include <QLineEdit>
#include <QLabel>
#include <QFrame>
#include <QGroupBox>
#include <QCloseEvent>
#include <QTreeView>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QTcpSocket>
#include <QTcpServer>
#include "utils/mutex.h"
class NetPlayClient;
struct NetPlayFrameInput
{
static constexpr uint32_t ownsData = 0x01;
NetPlayFrameInput(void)
{
flags = 0; frameCounter = 0;
ctrl[0] = ctrl[1] = ctrl[2] = ctrl[3] = 0;
data = nullptr;
}
~NetPlayFrameInput()
{
if (data)
{
if (flags & ownsData)
{
::free(data);
data = nullptr;
}
}
}
uint32_t flags;
uint32_t frameCounter;
uint8_t ctrl[4];
uint8_t *data;
};
class NetPlayServer : public QTcpServer
{
Q_OBJECT
public:
NetPlayServer(QObject *parent = 0);
~NetPlayServer(void);
static constexpr int DefaultPort = 4046;
static NetPlayServer *GetInstance(void){ return instance; };
static int Create(QObject *parent = 0);
static int Destroy();
typedef std::list <NetPlayClient*> ClientList_t;
int closeAllConnections(void);
void update(void);
size_t inputAvailable(void)
{
FCEU::autoScopedLock alock(inputMtx);
return input.size();
};
void pushBackInput( NetPlayFrameInput &in )
{
FCEU::autoScopedLock alock(inputMtx);
input.push_back(in);
};
NetPlayFrameInput getNextInput(void)
{
NetPlayFrameInput in;
FCEU::autoScopedLock alock(inputMtx);
if (!input.empty())
{
in = input.front();
input.pop_front();
}
return in;
};
uint32_t inputFrameBack()
{
uint32_t frame = 0;
FCEU::autoScopedLock alock(inputMtx);
if (!input.empty())
{
NetPlayFrameInput &in = input.back();
frame = in.frameCounter;
}
return frame;
}
void inputClear()
{
FCEU::autoScopedLock alock(inputMtx);
input.clear();
}
void resyncClient( NetPlayClient *client );
void resyncAllClients();
int sendMsg( NetPlayClient *client, const void *msg, size_t msgSize, std::function<void(void)> netByteOrderConvertFunc = []{});
int sendRomLoadReq( NetPlayClient *client );
int sendStateSyncReq( NetPlayClient *client );
int sendPause( NetPlayClient *client );
int sendUnpause( NetPlayClient *client );
int sendPauseAll(void);
int sendUnpauseAll(void);
void setRole(int _role);
int getRole(void){ return role; }
bool claimRole(NetPlayClient* client, int _role);
void releaseRole(NetPlayClient* client);
bool waitingOnClients(){ return clientWaitCounter > 3; }
uint32_t getMaxLeadFrames(){ return maxLeadFrames; }
void setMaxLeadFrames(uint32_t value){ maxLeadFrames = value; }
void setEnforceAppVersionCheck(bool value){ enforceAppVersionCheck = value; }
void setAllowClientRomLoadRequest(bool value){ allowClientRomLoadReq = value; }
void setAllowClientStateLoadRequest(bool value){ allowClientStateLoadReq = value; }
void setDebugMode(bool value){ debugMode = value; }
void serverProcessMessage( NetPlayClient *client, void *msgBuf, size_t msgSize );
ClientList_t& getClientList(){ return clientList; }
QString sessionName;
QString sessionPasswd;
private:
static NetPlayServer *instance;
void processPendingConnections(void);
ClientList_t clientList;
std::list <NetPlayFrameInput> input;
FCEU::mutex inputMtx;
int role = -1;
int roleMask = 0;
NetPlayClient* clientPlayer[4] = { nullptr };
uint32_t forceResyncCount = 10;
uint32_t cycleCounter = 0;
uint32_t maxLeadFrames = 10u;
uint32_t clientWaitCounter = 0;
uint32_t inputFrameCount = 0;
uint32_t romCrc32 = 0;
bool enforceAppVersionCheck = true;
bool allowClientRomLoadReq = false;
bool allowClientStateLoadReq = false;
bool debugMode = false;
public:
signals:
void clientConnected(void);
void clientDisconnected(void);
public slots:
void newConnectionRdy(void);
void onRomLoad(void);
void onRomUnload(void);
void onStateLoad(void);
void onNesReset(void);
void onPauseToggled(bool);
void onCheatsChanged(void);
void processClientRomLoadRequests(void);
void processClientStateLoadRequests(void);
};
class NetPlayClient : public QObject
{
Q_OBJECT
public:
NetPlayClient(QObject *parent = 0, bool outGoing = false);
~NetPlayClient(void);
static NetPlayClient *GetInstance(void){ return instance; };
static int Create(QObject *parent = 0);
static int Destroy();
int connectToHost( const QString host, int port );
bool isConnected(void){ return _connected; }
bool disconnectRequested(){ return disconnectPending; }
void forceDisconnect();
bool flushData();
int requestRomLoad( const char *romPath );
int requestStateLoad(EMUFILE* is);
int requestSync(void);
QTcpSocket* createSocket(void);
void setSocket(QTcpSocket *s);
QTcpSocket* getSocket(void){ return sock; };
void update(void);
int readMessages( void (*msgCallback)( void *userData, void *msgBuf, size_t msgSize ), void *userData );
void clientProcessMessage( void *msgBuf, size_t msgSize );
bool inputAvailable(void)
{
FCEU::autoScopedLock alock(inputMtx);
return !input.empty();
};
size_t inputAvailableCount(void)
{
FCEU::autoScopedLock alock(inputMtx);
return input.size();
};
void pushBackInput( NetPlayFrameInput &in )
{
FCEU::autoScopedLock alock(inputMtx);
input.push_back(in);
};
NetPlayFrameInput getNextInput(void)
{
NetPlayFrameInput in;
FCEU::autoScopedLock alock(inputMtx);
if (!input.empty())
{
in = input.front();
input.pop_front();
}
return in;
};
uint32_t inputFrameBack()
{
uint32_t frame = 0;
FCEU::autoScopedLock alock(inputMtx);
if (!input.empty())
{
NetPlayFrameInput &in = input.back();
frame = in.frameCounter;
}
return frame;
}
void inputClear()
{
FCEU::autoScopedLock alock(inputMtx);
input.clear();
}
bool isAuthenticated();
bool isPlayerRole();
bool shouldDestroy(){ return needsDestroy; }
bool isPaused(){ return paused; }
void setPaused(bool value){ paused = value; }
bool hasDesync(){ return desync; }
void setDesync(bool value){ desync = value; }
void recordPingResult( const uint64_t delay_ms );
void resetPingData(void);
double getAvgPingDelay();
unsigned long long getLastPingDelay(){ return pingDelayLast; };
unsigned long long getMinPingDelay(){ return pingDelayMin; };
unsigned long long getMaxPingDelay(){ return pingDelayMax; };
void setDebugLog(QFile* file){ debugLog = file; };
QString userName;
QString password;
int role = -1;
int state = 0;
unsigned int desyncCount = 0;
unsigned int desyncSinceReset = 0;
unsigned int totalDesyncCount = 0;
bool syncOk = false;
bool romMatch = false;
unsigned int currentFrame = 0;
unsigned int readyFrame = 0;
unsigned int catchUpThreshold = 10;
unsigned int tailTarget = 3;
uint8_t gpData[4];
struct RomLoadReqData
{
char* buf = nullptr;
size_t size = 0;
QString fileName;
bool pending(){ return buf != nullptr; }
} romLoadData;
struct StateLoadReqData
{
char* buf = nullptr;
size_t size = 0;
bool pending(){ return buf != nullptr; }
} stateLoadData;
private:
static NetPlayClient *instance;
QTcpSocket *sock = nullptr;
int recvMsgId = 0;
int recvMsgSize = 0;
int recvMsgBytesLeft = 0;
int recvMsgByteIndex = 0;
char *recvMsgBuf = nullptr;
bool disconnectPending = false;
bool needsDestroy = false;
bool _connected = false;
bool paused = false;
bool desync = false;
bool readMessageProcessing = false;
uint64_t pingDelaySum = 0;
uint64_t pingDelayLast = 0;
uint64_t pingDelayMin = 1000;
uint64_t pingDelayMax = 0;
uint64_t pingNumSamples = 0;
uint32_t romCrc32 = 0;
uint32_t numMsgBoxObjs = 0;
long int spawnTimeStampMs = 0;
std::list <NetPlayFrameInput> input;
FCEU::mutex inputMtx;
QFile* debugLog = nullptr;
static constexpr size_t recvMsgBufSize = 2 * 1024 * 1024;
signals:
void connected(void);
void errorOccurred(const QString&);
public slots:
void onConnect(void);
void onDisconnect(void);
void onSocketError(QAbstractSocket::SocketError);
void onRomLoad(void);
void onRomUnload(void);
void serverReadyRead(void);
void clientReadyRead(void);
void onMessageBoxDestroy(QObject* obj);
};
class NetPlayHostDialog : public QDialog
{
Q_OBJECT
public:
NetPlayHostDialog(QWidget *parent = 0);
~NetPlayHostDialog(void);
static NetPlayHostDialog *GetInstance(void){ return instance; };
protected:
void closeEvent(QCloseEvent *event);
QLineEdit *sessionNameEntry;
QSpinBox *portEntry;
QComboBox *playerRoleBox;
QLineEdit *passwordEntry;
QCheckBox *passwordRequiredCBox;
QSpinBox *frameLeadSpinBox;
QCheckBox *enforceAppVersionChkCBox;
QCheckBox *allowClientRomReqCBox;
QCheckBox *allowClientStateReqCBox;
QCheckBox *debugModeCBox;
static NetPlayHostDialog* instance;
public slots:
void closeWindow(void);
void onStartClicked(void);
void passwordRequiredChanged(int state);
void allowClientRomReqChanged(int state);
void allowClientStateReqChanged(int state);
void enforceAppVersionChkChanged(int state);
};
class NetPlayJoinDialog : public QDialog
{
Q_OBJECT
public:
NetPlayJoinDialog(QWidget *parent = 0);
~NetPlayJoinDialog(void);
static NetPlayJoinDialog *GetInstance(void){ return instance; };
protected:
void closeEvent(QCloseEvent *event);
QLineEdit *hostEntry;
QSpinBox *portEntry;
QComboBox *playerRoleBox;
QLineEdit *userNameEntry;
QLineEdit *passwordEntry;
static NetPlayJoinDialog* instance;
public slots:
void closeWindow(void);
void onJoinClicked(void);
void onConnect(void);
void onSocketError(const QString& errorMsg);
};
class NetPlayClientTreeItem : public QTreeWidgetItem
{
public:
NetPlayClientTreeItem()
: QTreeWidgetItem()
{
}
enum Type
{
StatusInfo = 0,
PingInfo,
DesyncInfo
};
int type = StatusInfo;
NetPlayClient* client = nullptr;
NetPlayServer* server = nullptr;
void updateData();
private:
};
class NetPlayClientStatusDialog : public QDialog
{
Q_OBJECT
public:
NetPlayClientStatusDialog(QWidget *parent = 0);
~NetPlayClientStatusDialog(void);
static NetPlayClientStatusDialog *GetInstance(void){ return instance; };
protected:
void closeEvent(QCloseEvent *event);
void updateStatusDisplay(void);
QLabel *hostStateLbl;
QTimer *periodicTimer;
QPushButton *requestResyncButton;
static NetPlayClientStatusDialog* instance;
public slots:
void closeWindow(void);
void updatePeriodic(void);
void resyncButtonClicked(void);
};
class NetPlayHostStatusDialog : public QDialog
{
Q_OBJECT
public:
NetPlayHostStatusDialog(QWidget *parent = 0);
~NetPlayHostStatusDialog(void);
static NetPlayHostStatusDialog *GetInstance(void){ return instance; };
protected:
void closeEvent(QCloseEvent *event);
QTreeWidget *clientTree;
QPushButton *dropPlayerButton;
QPushButton *resyncPlayerButton;
QPushButton *resyncAllButton;
QTimer *periodicTimer;
static NetPlayHostStatusDialog* instance;
public slots:
void closeWindow(void);
void updatePeriodic(void);
void loadClientTree(void);
void onClientTreeContextMenu(const QPoint &pos);
void clientItemClicked(QTreeWidgetItem* item, int);
void dropPlayer(void);
void resyncPlayer(void);
void resyncAllPlayers(void);
};
bool NetPlayActive(void);
bool isNetPlayHost(void);
bool isNetPlayClient(void);
void NetPlayPeriodicUpdate(void);
bool NetPlaySkipWait(void);
int NetPlayFrameWait(void);
void NetPlayOnFrameBegin(void);
void NetPlayReadInputFrame(uint8_t* joy);
void NetPlayCloseSession(void);
bool NetPlayStateLoadReq(EMUFILE* is);
void NetPlayTraceInstruction(uint8_t *opcode, int size);
void openNetPlayHostDialog(QWidget* parent = nullptr);
void openNetPlayJoinDialog(QWidget* parent = nullptr);
void openNetPlayHostStatusDialog(QWidget* parent = nullptr);
void openNetPlayClientStatusDialog(QWidget* parent = nullptr);
const char* NetPlayPlayerRoleToString(int role);

View File

@ -0,0 +1,517 @@
// NetPlayMsgDef.h
#pragma once
#include <string.h>
#include <stdint.h>
#include "version.h"
// Network Byte Swap Functions
uint16_t netPlayByteSwap(uint16_t);
uint32_t netPlayByteSwap(uint32_t);
uint64_t netPlayByteSwap(uint64_t);
#pragma pack(push,4)
enum netPlayMsgType
{
NETPLAY_AUTH_REQ = 0,
NETPLAY_AUTH_RESP,
NETPLAY_LOAD_ROM_REQ = 10,
NETPLAY_UNLOAD_ROM_REQ,
NETPLAY_SYNC_STATE_REQ = 20,
NETPLAY_SYNC_STATE_RESP,
NETPLAY_RUN_FRAME_REQ = 30,
NETPLAY_CLIENT_STATE = 40,
NETPLAY_CLIENT_PAUSE_REQ,
NETPLAY_CLIENT_UNPAUSE_REQ,
NETPLAY_INFO_MSG = 50,
NETPLAY_ERROR_MSG,
NETPLAY_CHAT_MSG,
NETPLAY_PING_REQ = 100,
NETPLAY_PING_RESP,
};
enum netPlayerId
{
NETPLAY_SPECTATOR = -1,
NETPLAY_PLAYER1,
NETPLAY_PLAYER2,
NETPLAY_PLAYER3,
NETPLAY_PLAYER4
};
static constexpr uint32_t NETPLAY_MAGIC_NUMBER = 0xaa55aa55;
struct netPlayMsgHdr
{
uint32_t magic[2];
uint32_t msgId;
uint32_t msgSize;
netPlayMsgHdr( uint32_t id, uint32_t size = sizeof(netPlayMsgHdr) )
{
magic[0] = NETPLAY_MAGIC_NUMBER;
magic[1] = NETPLAY_MAGIC_NUMBER;
msgId = id; msgSize = size;
}
void toHostByteOrder()
{
magic[0] = netPlayByteSwap(magic[0]);
magic[1] = netPlayByteSwap(magic[1]);
msgId = netPlayByteSwap(msgId);
msgSize = netPlayByteSwap(msgSize);
};
void toNetworkByteOrder()
{
magic[0] = netPlayByteSwap(magic[0]);
magic[1] = netPlayByteSwap(magic[1]);
msgId = netPlayByteSwap(msgId);
msgSize = netPlayByteSwap(msgSize);
}
};
struct netPlayAuthReq
{
netPlayMsgHdr hdr;
netPlayAuthReq(void)
: hdr(NETPLAY_AUTH_REQ, sizeof(netPlayAuthReq))
{
}
void toHostByteOrder()
{
hdr.toHostByteOrder();
}
void toNetworkByteOrder()
{
hdr.toNetworkByteOrder();
}
};
struct netPlayAuthResp
{
netPlayMsgHdr hdr;
uint16_t appVersionMajor;
uint16_t appVersionMinor;
uint32_t appVersionPatch;
char playerId;
char userName[64];
char pswd[72];
netPlayAuthResp(void)
: hdr(NETPLAY_AUTH_RESP, sizeof(netPlayAuthResp)),
appVersionMajor(FCEU_VERSION_MAJOR), appVersionMinor(FCEU_VERSION_MINOR), appVersionPatch(FCEU_VERSION_PATCH),
playerId(NETPLAY_SPECTATOR)
{
memset(pswd, 0, sizeof(pswd));
}
void toHostByteOrder()
{
hdr.toHostByteOrder();
appVersionMajor = netPlayByteSwap(appVersionMajor);
appVersionMinor = netPlayByteSwap(appVersionMinor);
appVersionPatch = netPlayByteSwap(appVersionPatch);
}
void toNetworkByteOrder()
{
hdr.toNetworkByteOrder();
appVersionMajor = netPlayByteSwap(appVersionMajor);
appVersionMinor = netPlayByteSwap(appVersionMinor);
appVersionPatch = netPlayByteSwap(appVersionPatch);
}
};
struct netPlayTextMsgFlags
{
static constexpr uint32_t Disconnect = 0x00000001;
static constexpr uint32_t Error = 0x00000002;
static constexpr uint32_t Warning = 0x00000004;
static constexpr uint32_t Info = 0x00000008;
};
template <size_t N=8>
struct netPlayTextMsg
{
netPlayMsgHdr hdr;
uint32_t flags;
uint16_t dataSize;
netPlayTextMsg(int type)
: hdr(type, sizeof(netPlayTextMsg)), flags(0), dataSize(0)
{
hdr.msgSize = sizeof(*this) - N + 1;
memset(data, 0, N);
}
void setFlag(uint32_t flag)
{
flags |= flag;
}
bool isFlagSet(uint32_t flag)
{
return (flags & flag) ? true : false;
}
const char *getBuffer()
{
return &data[0];
}
int printf(const char* format, ...)
{
int retval;
va_list args;
va_start(args, format);
retval = ::vsnprintf(data, N, format, args);
va_end(args);
if (retval > static_cast<int>(N-1))
{
retval = static_cast<int>(N-1);
}
dataSize = retval;
hdr.msgSize = sizeof(*this) - N + retval + 1;
return retval;
}
void assign(const char *msg)
{
int i=0;
while ( (i < (N-1)) && (msg[i] != 0) )
{
data[i] = msg[i]; i++;
}
data[i] = 0;
dataSize = i;
hdr.msgSize = sizeof(*this) - N + i + 1;
}
void append(const char *msg)
{
int i=dataSize, j=0;
while ( (i < (N-1)) && (msg[j] != 0) )
{
data[i] = msg[j]; i++; j++;
}
data[i] = 0;
dataSize = i;
hdr.msgSize = sizeof(*this) - N + i + 1;
}
void toHostByteOrder()
{
hdr.toHostByteOrder();
flags = netPlayByteSwap(flags);
dataSize = netPlayByteSwap(dataSize);
}
void toNetworkByteOrder()
{
hdr.toNetworkByteOrder();
flags = netPlayByteSwap(flags);
dataSize = netPlayByteSwap(dataSize);
}
private:
char data[N];
};
struct netPlayLoadRomReq
{
netPlayMsgHdr hdr;
uint32_t fileSize;
uint32_t archiveIndex;
char fileName[256];
netPlayLoadRomReq(void)
: hdr(NETPLAY_LOAD_ROM_REQ, sizeof(netPlayLoadRomReq)), fileSize(0), archiveIndex(0)
{
memset(fileName, 0, sizeof(fileName));
}
void toHostByteOrder()
{
hdr.toHostByteOrder();
fileSize = netPlayByteSwap(fileSize);
archiveIndex = netPlayByteSwap(archiveIndex);
}
void toNetworkByteOrder()
{
hdr.toNetworkByteOrder();
fileSize = netPlayByteSwap(fileSize);
archiveIndex = netPlayByteSwap(archiveIndex);
}
};
struct netPlayLoadStateResp
{
netPlayMsgHdr hdr;
uint32_t stateSize;
uint32_t numCtrlFrames;
uint32_t numCheats;
uint32_t opsCrc32;
uint32_t romCrc32;
struct {
uint32_t num = 0;
uint32_t opsCrc32 = 0;
uint32_t ramCrc32 = 0;
} lastFrame;
static constexpr int MaxCtrlFrames = 10;
static constexpr int MaxCheats = 64;
struct CtrlData
{
uint32_t frameNum = 0;
uint8_t ctrlState[4] = {0};
void toHostByteOrder()
{
frameNum = netPlayByteSwap(frameNum);
}
void toNetworkByteOrder()
{
frameNum = netPlayByteSwap(frameNum);
}
};
struct CheatData
{
uint16_t addr = 0;
uint8_t val = 0;
int8_t cmp = -1; /* -1 for no compare. */
int8_t type = 0; /* 0 for replace, 1 for substitute(GG). */
int8_t stat = 0;
char name[64] = {0};
void toHostByteOrder()
{
addr = netPlayByteSwap(addr);
}
void toNetworkByteOrder()
{
addr = netPlayByteSwap(addr);
}
};
netPlayLoadStateResp(void)
: hdr(NETPLAY_SYNC_STATE_RESP, sizeof(netPlayLoadStateResp)),
stateSize(0), numCtrlFrames(0), numCheats(0), opsCrc32(0), romCrc32(0)
{
}
size_t calcTotalSize()
{
size_t size = sizeof(netPlayLoadStateResp) +
(numCtrlFrames * sizeof(CtrlData) ) +
(numCheats * sizeof(CheatData)) +
stateSize;
hdr.msgSize = size;
return size;
}
void toHostByteOrder()
{
hdr.toHostByteOrder();
stateSize = netPlayByteSwap(stateSize);
numCtrlFrames = netPlayByteSwap(numCtrlFrames);
numCheats = netPlayByteSwap(numCheats);
opsCrc32 = netPlayByteSwap(opsCrc32);
romCrc32 = netPlayByteSwap(romCrc32);
lastFrame.num = netPlayByteSwap(lastFrame.num);
lastFrame.opsCrc32 = netPlayByteSwap(lastFrame.opsCrc32);
lastFrame.ramCrc32 = netPlayByteSwap(lastFrame.ramCrc32);
}
void toNetworkByteOrder()
{
hdr.toNetworkByteOrder();
stateSize = netPlayByteSwap(stateSize);
numCtrlFrames = netPlayByteSwap(numCtrlFrames);
numCheats = netPlayByteSwap(numCheats);
opsCrc32 = netPlayByteSwap(opsCrc32);
romCrc32 = netPlayByteSwap(romCrc32);
lastFrame.num = netPlayByteSwap(lastFrame.num);
lastFrame.opsCrc32 = netPlayByteSwap(lastFrame.opsCrc32);
lastFrame.ramCrc32 = netPlayByteSwap(lastFrame.ramCrc32);
}
CtrlData* ctrlDataBuf()
{
uintptr_t buf = ((uintptr_t)this) + sizeof(netPlayLoadStateResp);
return (CtrlData*)buf;
}
CheatData* cheatDataBuf()
{
uintptr_t buf = ((uintptr_t)this) + sizeof(netPlayLoadStateResp) +
(numCtrlFrames * sizeof(CtrlData));
return (CheatData*)buf;
}
char* stateDataBuf()
{
uintptr_t buf = ((uintptr_t)this) + sizeof(netPlayLoadStateResp) +
(numCtrlFrames * sizeof(CtrlData)) + (numCheats * sizeof(CheatData));
return (char*)buf;
}
const uint32_t stateDataSize()
{
return stateSize;
}
};
struct netPlayRunFrameReq
{
netPlayMsgHdr hdr;
uint32_t flags;
uint32_t frameNum;
uint8_t ctrlState[4];
uint8_t catchUpThreshold;
netPlayRunFrameReq(void)
: hdr(NETPLAY_RUN_FRAME_REQ, sizeof(netPlayRunFrameReq)), flags(0), frameNum(0), catchUpThreshold(10)
{
memset( ctrlState, 0, sizeof(ctrlState) );
}
void toHostByteOrder()
{
hdr.toHostByteOrder();
flags = netPlayByteSwap(flags);
frameNum = netPlayByteSwap(frameNum);
}
void toNetworkByteOrder()
{
hdr.toNetworkByteOrder();
flags = netPlayByteSwap(flags);
frameNum = netPlayByteSwap(frameNum);
}
};
struct netPlayClientState
{
netPlayMsgHdr hdr;
uint32_t flags;
uint32_t frameRdy; // What frame we have input ready for
uint32_t frameRun;
uint32_t opsFrame; // Last frame for ops data
uint32_t opsChkSum;
uint32_t ramChkSum;
uint32_t romCrc32;
uint8_t ctrlState[4];
static constexpr uint32_t PauseFlag = 0x0001;
static constexpr uint32_t DesyncFlag = 0x0002;
netPlayClientState(void)
: hdr(NETPLAY_CLIENT_STATE, sizeof(netPlayClientState)), flags(0),
frameRdy(0), frameRun(0), opsChkSum(0), ramChkSum(0), romCrc32(0)
{
memset( ctrlState, 0, sizeof(ctrlState) );
}
void toHostByteOrder()
{
hdr.toHostByteOrder();
flags = netPlayByteSwap(flags);
frameRdy = netPlayByteSwap(frameRdy);
frameRun = netPlayByteSwap(frameRun);
opsFrame = netPlayByteSwap(opsFrame);
opsChkSum = netPlayByteSwap(opsChkSum);
ramChkSum = netPlayByteSwap(ramChkSum);
romCrc32 = netPlayByteSwap(romCrc32);
}
void toNetworkByteOrder()
{
hdr.toNetworkByteOrder();
flags = netPlayByteSwap(flags);
frameRdy = netPlayByteSwap(frameRdy);
frameRun = netPlayByteSwap(frameRun);
opsFrame = netPlayByteSwap(opsFrame);
opsChkSum = netPlayByteSwap(opsChkSum);
ramChkSum = netPlayByteSwap(ramChkSum);
romCrc32 = netPlayByteSwap(romCrc32);
}
};
struct netPlayPingReq
{
netPlayMsgHdr hdr;
uint64_t hostTimeStamp;
netPlayPingReq(void)
: hdr(NETPLAY_PING_REQ, sizeof(netPlayPingReq)), hostTimeStamp(0)
{
}
void toHostByteOrder()
{
hdr.toHostByteOrder();
hostTimeStamp = netPlayByteSwap(hostTimeStamp);
}
void toNetworkByteOrder()
{
hdr.toNetworkByteOrder();
hostTimeStamp = netPlayByteSwap(hostTimeStamp);
}
};
struct netPlayPingResp
{
netPlayMsgHdr hdr;
uint64_t hostTimeStamp;
netPlayPingResp(void)
: hdr(NETPLAY_PING_RESP, sizeof(netPlayPingResp)), hostTimeStamp(0)
{
}
void toHostByteOrder()
{
hdr.toHostByteOrder();
hostTimeStamp = netPlayByteSwap(hostTimeStamp);
}
void toNetworkByteOrder()
{
hdr.toNetworkByteOrder();
hostTimeStamp = netPlayByteSwap(hostTimeStamp);
}
};
#pragma pack(pop)

View File

@ -143,7 +143,7 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
connect(ntscFrame, SIGNAL(clicked(bool)), this, SLOT(use_NTSC_Changed(bool)));
sprintf(stmp, "Tint: %3i", tint);
snprintf(stmp, sizeof(stmp), "Tint: %3i", tint);
tintFrame = new QGroupBox(tr(stmp));
hbox1 = new QHBoxLayout();
tintSlider = new QSlider(Qt::Horizontal);
@ -157,7 +157,7 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
tintFrame->setLayout(hbox1);
hbox2->addWidget(tintFrame);
sprintf(stmp, "Hue: %3i", hue);
snprintf(stmp, sizeof(stmp), "Hue: %3i", hue);
hueFrame = new QGroupBox(tr(stmp));
hbox1 = new QHBoxLayout();
hueSlider = new QSlider(Qt::Horizontal);
@ -190,7 +190,7 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
grid->setColumnStretch( 1, 40 );
grid->setColumnStretch( 2, 20 );
sprintf(stmp, "Notch: %3i%%", palnotch);
snprintf(stmp, sizeof(stmp), "Notch: %3i%%", palnotch);
notchFrame = new QGroupBox(tr(stmp));
#if QT_VERSION > QT_VERSION_CHECK(5, 11, 0)
notchFrame->setMinimumWidth( notchFrame->fontMetrics().horizontalAdvance('2') * strlen(stmp) );
@ -207,7 +207,7 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
hbox1->addWidget(notchSlider);
notchFrame->setLayout(hbox1);
sprintf(stmp, "Saturation: %3i%%", palsaturation);
snprintf(stmp, sizeof(stmp), "Saturation: %3i%%", palsaturation);
saturationFrame = new QGroupBox(tr(stmp));
#if QT_VERSION > QT_VERSION_CHECK(5, 11, 0)
saturationFrame->setMinimumWidth( saturationFrame->fontMetrics().horizontalAdvance('2') * strlen(stmp) );
@ -224,7 +224,7 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
hbox1->addWidget(saturationSlider);
saturationFrame->setLayout(hbox1);
sprintf(stmp, "Sharpness: %3i%%", palsharpness*2);
snprintf(stmp, sizeof(stmp), "Sharpness: %3i%%", palsharpness*2);
sharpnessFrame = new QGroupBox(tr(stmp));
#if QT_VERSION > QT_VERSION_CHECK(5, 11, 0)
sharpnessFrame->setMinimumWidth( sharpnessFrame->fontMetrics().horizontalAdvance('2') * strlen(stmp) );
@ -241,7 +241,7 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
hbox1->addWidget(sharpnessSlider);
sharpnessFrame->setLayout(hbox1);
sprintf(stmp, "Contrast: %3i%%", palcontrast);
snprintf(stmp, sizeof(stmp), "Contrast: %3i%%", palcontrast);
contrastFrame = new QGroupBox(tr(stmp));
#if QT_VERSION > QT_VERSION_CHECK(5, 11, 0)
contrastFrame->setMinimumWidth( contrastFrame->fontMetrics().horizontalAdvance('2') * strlen(stmp) );
@ -258,7 +258,7 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
hbox1->addWidget(contrastSlider);
contrastFrame->setLayout(hbox1);
sprintf(stmp, "Brightness: %3i%%", palbrightness);
snprintf(stmp, sizeof(stmp), "Brightness: %3i%%", palbrightness);
brightnessFrame = new QGroupBox(tr(stmp));
#if QT_VERSION > QT_VERSION_CHECK(5, 11, 0)
brightnessFrame->setMinimumWidth( brightnessFrame->fontMetrics().horizontalAdvance('2') * strlen(stmp) );
@ -361,7 +361,7 @@ void PaletteConfDialog_t::hueChanged(int v)
int c, t;
char stmp[64];
sprintf(stmp, "Hue: %3i", v);
snprintf(stmp, sizeof(stmp), "Hue: %3i", v);
hueFrame->setTitle(stmp);
@ -382,7 +382,7 @@ void PaletteConfDialog_t::tintChanged(int v)
int c, h;
char stmp[64];
sprintf(stmp, "Tint: %3i", v);
snprintf(stmp, sizeof(stmp), "Tint: %3i", v);
tintFrame->setTitle(stmp);
@ -516,19 +516,19 @@ void PaletteConfDialog_t::openPaletteFile(void)
if (d.exists())
{
urls << QUrl::fromLocalFile(d.absolutePath());
iniPath = d.absolutePath().toStdString();
iniPath = d.absolutePath().toLocal8Bit().constData();
}
#ifdef __APPLE__
// Search for MacOSX DragNDrop Resources
d.setPath(QString(exePath) + "/../Resources/palettes");
//printf("Looking for: '%s'\n", d.path().toStdString().c_str());
//printf("Looking for: '%s'\n", d.path().toLocal8Bit().constData());
if (d.exists())
{
urls << QUrl::fromLocalFile(d.absolutePath());
iniPath = d.absolutePath().toStdString();
iniPath = d.absolutePath().toLocal8Bit().constData();
}
#endif
}
@ -553,12 +553,12 @@ void PaletteConfDialog_t::openPaletteFile(void)
d.setPath(QString("/usr/share/fceux/palettes"));
}
//printf("Looking for: '%s'\n", d.path().toStdString().c_str());
//printf("Looking for: '%s'\n", d.path().toLocal8Bit().constData());
if (d.exists())
{
urls << QUrl::fromLocalFile(d.absolutePath());
iniPath = d.absolutePath().toStdString();
iniPath = d.absolutePath().toLocal8Bit().constData();
}
#endif
@ -604,18 +604,18 @@ void PaletteConfDialog_t::openPaletteFile(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
if (fceuWrapperTryLock())
{
if (LoadCPalette(filename.toStdString().c_str()))
if (LoadCPalette(filename.toLocal8Bit().constData()))
{
g_config->setOption("SDL.Palette", filename.toStdString().c_str());
custom_palette_path->setText(filename.toStdString().c_str());
g_config->setOption("SDL.Palette", filename.toLocal8Bit().constData());
custom_palette_path->setText(filename.toLocal8Bit().constData());
}
else
{
printf("Error: Failed to Load Palette File: %s \n", filename.toStdString().c_str());
printf("Error: Failed to Load Palette File: %s \n", filename.toLocal8Bit().constData());
}
palupdate = 1;
fceuWrapperUnLock();
@ -653,7 +653,7 @@ void PaletteConfDialog_t::palNotchChanged(int value)
{
char stmp[64];
sprintf( stmp, "Notch: %3i%%", value );
snprintf( stmp, sizeof(stmp), "Notch: %3i%%", value );
notchFrame->setTitle( tr(stmp) );
palnotch = value;
@ -671,7 +671,7 @@ void PaletteConfDialog_t::palSaturationChanged(int value)
{
char stmp[64];
sprintf( stmp, "Saturation: %3i%%", value );
snprintf( stmp, sizeof(stmp), "Saturation: %3i%%", value );
saturationFrame->setTitle( tr(stmp) );
palsaturation = value;
@ -689,7 +689,7 @@ void PaletteConfDialog_t::palSharpnessChanged(int value)
{
char stmp[64];
sprintf( stmp, "Sharpness: %3i%%", value*2 );
snprintf( stmp, sizeof(stmp), "Sharpness: %3i%%", value*2 );
sharpnessFrame->setTitle( tr(stmp) );
palsharpness = value;
@ -707,7 +707,7 @@ void PaletteConfDialog_t::palContrastChanged(int value)
{
char stmp[64];
sprintf( stmp, "Contrast: %3i%%", value );
snprintf( stmp, sizeof(stmp), "Contrast: %3i%%", value );
contrastFrame->setTitle( tr(stmp) );
palcontrast = value;
@ -725,7 +725,7 @@ void PaletteConfDialog_t::palBrightnessChanged(int value)
{
char stmp[64];
sprintf( stmp, "Brightness: %3i%%", value );
snprintf( stmp, sizeof(stmp), "Brightness: %3i%%", value );
brightnessFrame->setTitle( tr(stmp) );
palbrightness = value;

View File

@ -232,7 +232,7 @@ void PaletteEditorDialog_t::updatePeriodic(void)
chg = undoColorHistory.back();
sprintf( stmp, "&Undo $%02X = rgb(%3i,%3i,%3i)", chg.palIdx,
snprintf( stmp, sizeof(stmp), "&Undo $%02X = rgb(%3i,%3i,%3i)", chg.palIdx,
chg.newColor.red(), chg.newColor.green(), chg.newColor.blue() );
undoAct->setText( tr(stmp) );
@ -249,7 +249,7 @@ void PaletteEditorDialog_t::updatePeriodic(void)
chg = redoColorHistory.back();
sprintf( stmp, "&Redo $%02X = rgb(%3i,%3i,%3i)", chg.palIdx,
snprintf( stmp, sizeof(stmp), "&Redo $%02X = rgb(%3i,%3i,%3i)", chg.palIdx,
chg.newColor.red(), chg.newColor.green(), chg.newColor.blue() );
redoAct->setText( tr(stmp) );
@ -335,19 +335,19 @@ void PaletteEditorDialog_t::openPaletteFileDialog(void)
if ( d.exists() )
{
urls << QUrl::fromLocalFile( d.absolutePath() );
iniPath = d.absolutePath().toStdString();
iniPath = d.absolutePath().toLocal8Bit().constData();
}
#ifdef __APPLE__
// Search for MacOSX DragNDrop Resources
d.setPath(QString(exePath) + "/../Resources/palettes");
//printf("Looking for: '%s'\n", d.path().toStdString().c_str());
//printf("Looking for: '%s'\n", d.path().toLocal8Bit().constData());
if (d.exists())
{
urls << QUrl::fromLocalFile(d.absolutePath());
iniPath = d.absolutePath().toStdString();
iniPath = d.absolutePath().toLocal8Bit().constData();
}
#endif
}
@ -372,12 +372,12 @@ void PaletteEditorDialog_t::openPaletteFileDialog(void)
d.setPath(QString("/usr/share/fceux/palettes"));
}
//printf("Looking for: '%s'\n", d.path().toStdString().c_str());
//printf("Looking for: '%s'\n", d.path().toLocal8Bit().constData());
if (d.exists())
{
urls << QUrl::fromLocalFile(d.absolutePath());
iniPath = d.absolutePath().toStdString();
iniPath = d.absolutePath().toLocal8Bit().constData();
}
#endif
@ -428,10 +428,10 @@ void PaletteEditorDialog_t::openPaletteFileDialog(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
palView->loadFromFile( filename.toStdString().c_str() );
g_config->setOption ("SDL.Palette", filename.toStdString().c_str() );
palView->loadFromFile( filename.toLocal8Bit().constData() );
g_config->setOption ("SDL.Palette", filename.toLocal8Bit().constData() );
return;
}
@ -481,9 +481,9 @@ void PaletteEditorDialog_t::savePaletteFileDialog(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
palView->saveToFile( filename.toStdString().c_str() );
palView->saveToFile( filename.toLocal8Bit().constData() );
}
//----------------------------------------------------------------------------
void PaletteEditorDialog_t::exportPaletteFileDialog(void)
@ -531,9 +531,9 @@ void PaletteEditorDialog_t::exportPaletteFileDialog(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
palView->exportToFileACT( filename.toStdString().c_str() );
palView->exportToFileACT( filename.toLocal8Bit().constData() );
}
//----------------------------------------------------------------------------
//---NES Color Palette Viewer
@ -798,7 +798,7 @@ void nesPaletteView::contextMenuEvent(QContextMenuEvent *event)
update();
}
sprintf( stmp, "Edit Color %X%X", selCell.y(), selCell.x() );
snprintf( stmp, sizeof(stmp), "Edit Color %X%X", selCell.y(), selCell.x() );
act = new QAction(tr(stmp), &menu);
act->setShortcut( QKeySequence(tr("E")));
connect( act, SIGNAL(triggered(void)), this, SLOT(editSelColor(void)) );
@ -947,7 +947,7 @@ nesColorPickerDialog_t::nesColorPickerDialog_t( int palIndex, QColor *c, QWidget
style = this->style();
sprintf( stmp, "Pick Palette Color $%02X", palIndex );
snprintf( stmp, sizeof(stmp), "Pick Palette Color $%02X", palIndex );
setWindowTitle( stmp );
@ -1220,7 +1220,7 @@ void nesPalettePickerView::contextMenuEvent(QContextMenuEvent *event)
// //QActionGroup *group;
// char stmp[64];
//
// sprintf( stmp, "Edit Color %X%X", selCell.y(), selCell.x() );
// snprintf( stmp, sizeof(stmp), "Edit Color %X%X", selCell.y(), selCell.x() );
// act = new QAction(tr(stmp), &menu);
// act->setShortcut( QKeySequence(tr("E")));
// connect( act, SIGNAL(triggered(void)), this, SLOT(editSelColor(void)) );
@ -1341,7 +1341,7 @@ nesPalettePickerDialog::nesPalettePickerDialog( int idx, QWidget *parent)
palIdx = idx;
palAddr = 0x3F00 + palIdx;
sprintf( stmp, "Pick Palette Color for Address $%04X", palAddr );
snprintf( stmp, sizeof(stmp), "Pick Palette Color for Address $%04X", palAddr );
setWindowTitle( tr(stmp) );
palOrigVal = READPAL_MOTHEROFALL(palIdx & 0x1F);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,861 @@
// QtScriptManager.h
//
#pragma once
#ifdef __FCEU_QSCRIPT_ENABLE__
#include <stdio.h>
#include <stdarg.h>
#include <QFile>
#include <QColor>
#include <QWidget>
#include <QDialog>
#include <QTabWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QCheckBox>
#include <QPushButton>
#include <QLabel>
#include <QFrame>
#include <QGroupBox>
#include <QLineEdit>
#include <QTextEdit>
#include <QTreeView>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QJSEngine>
#include <QThread>
#include <QTemporaryFile>
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include "Qt/main.h"
#include "utils/mutex.h"
#include "utils/timeStamp.h"
class QScriptDialog_t;
class QtScriptInstance;
namespace FCEU
{
class JSEngine : public QJSEngine
{
Q_OBJECT
public:
JSEngine(QObject* parent = nullptr);
~JSEngine();
QScriptDialog_t* getDialog(){ return dialog; }
QtScriptInstance* getScript(){ return script; }
void setDialog(QScriptDialog_t* _dialog){ dialog = _dialog; }
void setScript(QtScriptInstance* _script){ script = _script; }
enum logLevel
{
FATAL = 0,
CRITICAL,
WARNING,
INFO,
DEBUG,
};
void acquireThreadContext();
void releaseThreadContext();
void setLogLevel(enum logLevel lvl){ _logLevel = lvl; }
void logMessage(int lvl, const QString& msg);
static JSEngine* getCurrent();
private:
QScriptDialog_t* dialog = nullptr;
QtScriptInstance* script = nullptr;
int _logLevel = WARNING;
JSEngine* prevContext = nullptr;
};
} // FCEU
namespace JS
{
class ColorScriptObject: public QObject
{
Q_OBJECT
Q_PROPERTY(int red READ getRed WRITE setRed)
Q_PROPERTY(int green READ getGreen WRITE setGreen)
Q_PROPERTY(int blue READ getBlue WRITE setBlue)
Q_PROPERTY(int palette READ getPalette WRITE setPalette)
public:
Q_INVOKABLE ColorScriptObject(int r=0, int g=0, int b=0);
~ColorScriptObject();
private:
QColor color;
int _palette;
static int numInstances;
public slots:
Q_INVOKABLE int getRed(){ return color.red(); }
Q_INVOKABLE int getGreen(){ return color.green(); }
Q_INVOKABLE int getBlue(){ return color.blue(); }
Q_INVOKABLE void setRed(int r){ color.setRed(r); }
Q_INVOKABLE void setGreen(int g){ color.setGreen(g); }
Q_INVOKABLE void setBlue(int b){ color.setBlue(b); }
Q_INVOKABLE int getPalette(){ return _palette; }
Q_INVOKABLE void setPalette(int p){ _palette = p; }
Q_INVOKABLE int toRGB8(){ return color.value(); }
Q_INVOKABLE QString name(){ return color.name(QColor::HexRgb); }
};
class FileScriptObject: public QObject
{
Q_OBJECT
public:
Q_INVOKABLE FileScriptObject(const QString& path = QString());
~FileScriptObject();
enum Mode
{
ReadOnly = 0x01,
WriteOnly = 0x02,
ReadWrite = 0x03,
Append = 0x04,
Truncate = 0x08
};
Q_ENUM(Mode);
private:
static int numInstances;
QString filepath;
bool tmp = false;
QFile *file = nullptr;
public slots:
Q_INVOKABLE bool open(int mode = ReadOnly);
Q_INVOKABLE void close();
Q_INVOKABLE bool isOpen();
Q_INVOKABLE bool isReadable();
Q_INVOKABLE bool isWritable();
Q_INVOKABLE bool flush();
Q_INVOKABLE bool atEnd();
Q_INVOKABLE bool truncate();
Q_INVOKABLE bool resize(int64_t size);
Q_INVOKABLE bool seek(int64_t pos);
Q_INVOKABLE int64_t pos();
Q_INVOKABLE int64_t bytesAvailable();
Q_INVOKABLE bool isTemporary(){ return tmp; }
Q_INVOKABLE void setTemporary(bool value);
Q_INVOKABLE void setFilePath(const QString& path);
Q_INVOKABLE QString fileName();
Q_INVOKABLE QString fileSuffix();
Q_INVOKABLE QString filePath(){ return filepath; }
Q_INVOKABLE QString readLine();
Q_INVOKABLE int64_t skip(int64_t size);
Q_INVOKABLE QByteArray readData(unsigned int maxBytes = 0);
Q_INVOKABLE QByteArray peekData(unsigned int maxSize);
Q_INVOKABLE int writeString(const QString& s);
Q_INVOKABLE int writeData(const QByteArray& data);
Q_INVOKABLE bool putChar(char c);
Q_INVOKABLE char getChar();
};
class JoypadScriptObject: public QObject
{
Q_OBJECT
Q_PROPERTY(bool up READ getUp)
Q_PROPERTY(bool down READ getDown)
Q_PROPERTY(bool left READ getLeft)
Q_PROPERTY(bool right READ getRight)
Q_PROPERTY(bool select READ getSelect)
Q_PROPERTY(bool start READ getStart)
Q_PROPERTY(bool a READ getA)
Q_PROPERTY(bool b READ getB)
Q_PROPERTY(int player READ getPlayer WRITE setPlayer)
public:
Q_INVOKABLE JoypadScriptObject(int playerIdx = 0, bool immediate = false);
~JoypadScriptObject();
static constexpr int MAX_JOYPAD_PLAYERS = 4;
enum Button
{
FIRST_BUTTON = 0,
A_BUTTON = FIRST_BUTTON,
B_BUTTON,
SELECT_BUTTON,
START_BUTTON,
UP_BUTTON,
DOWN_BUTTON,
LEFT_BUTTON,
RIGHT_BUTTON,
LAST_BUTTON = RIGHT_BUTTON,
END_BUTTON
};
Q_ENUM(Button);
// Joypad Override Function
static uint8_t readOverride(int which, uint8_t joyl);
private:
// Joypad Override Bit Masks
static uint8_t jsOverrideMask1[MAX_JOYPAD_PLAYERS];
static uint8_t jsOverrideMask2[MAX_JOYPAD_PLAYERS];
struct buttonState
{
uint32_t buttonMask = 0;
bool _immediate = false;
};
buttonState current;
buttonState prev;
int player = 0;
static int numInstances;
static constexpr uint32_t ButtonMaskA = 0x01;
static constexpr uint32_t ButtonMaskB = 0x02;
static constexpr uint32_t ButtonMaskSelect = 0x04;
static constexpr uint32_t ButtonMaskStart = 0x08;
static constexpr uint32_t ButtonMaskUp = 0x10;
static constexpr uint32_t ButtonMaskDown = 0x20;
static constexpr uint32_t ButtonMaskLeft = 0x40;
static constexpr uint32_t ButtonMaskRight = 0x80;
template <uint32_t mask> bool isBitSet(uint32_t& byte)
{
return (byte & mask) ? true : false;
}
template <uint32_t mask> bool isChanged()
{
return ((current.buttonMask ^ prev.buttonMask) & mask) ? true : false;
}
template <uint32_t mask> void setButtonOverride(bool value)
{
if (value)
{
jsOverrideMask1[player] |= mask;
jsOverrideMask2[player] |= mask;
}
else
{
jsOverrideMask1[player] &= ~mask;
jsOverrideMask2[player] &= ~mask;
}
}
template <uint32_t mask> void clearButtonOverride()
{
jsOverrideMask1[player] |= mask;
jsOverrideMask2[player] &= ~mask;
}
template <uint32_t mask> void invertButtonOverride()
{
jsOverrideMask1[player] &= ~mask;
jsOverrideMask2[player] |= mask;
}
public slots:
Q_INVOKABLE void refreshData(bool immediate = false);
Q_INVOKABLE bool getUp(){ return isBitSet<ButtonMaskUp>(current.buttonMask); }
Q_INVOKABLE bool getDown(){ return isBitSet<ButtonMaskDown>(current.buttonMask); }
Q_INVOKABLE bool getLeft(){ return isBitSet<ButtonMaskLeft>(current.buttonMask); }
Q_INVOKABLE bool getRight(){ return isBitSet<ButtonMaskRight>(current.buttonMask); }
Q_INVOKABLE bool getSelect(){ return isBitSet<ButtonMaskSelect>(current.buttonMask); }
Q_INVOKABLE bool getStart(){ return isBitSet<ButtonMaskStart>(current.buttonMask); }
Q_INVOKABLE bool getA(){ return isBitSet<ButtonMaskA>(current.buttonMask); }
Q_INVOKABLE bool getB(){ return isBitSet<ButtonMaskB>(current.buttonMask); }
Q_INVOKABLE bool upChanged(){ return isChanged<ButtonMaskUp>(); }
Q_INVOKABLE bool downChanged(){ return isChanged<ButtonMaskDown>(); }
Q_INVOKABLE bool leftChanged(){ return isChanged<ButtonMaskLeft>(); }
Q_INVOKABLE bool rightChanged(){ return isChanged<ButtonMaskRight>(); }
Q_INVOKABLE bool selectChanged(){ return isChanged<ButtonMaskSelect>(); }
Q_INVOKABLE bool startChanged(){ return isChanged<ButtonMaskStart>(); }
Q_INVOKABLE bool aChanged(){ return isChanged<ButtonMaskA>(); }
Q_INVOKABLE bool bChanged(){ return isChanged<ButtonMaskB>(); }
Q_INVOKABLE bool isImmediate(){ return current._immediate; }
Q_INVOKABLE bool getButton(enum Button b);
Q_INVOKABLE bool buttonChanged(enum Button b);
Q_INVOKABLE bool stateChanged(){ return prev.buttonMask != current.buttonMask; }
Q_INVOKABLE void setState(int mask){ prev.buttonMask = current.buttonMask; current.buttonMask = mask; }
Q_INVOKABLE int getState(){ return current.buttonMask; }
Q_INVOKABLE int maxPlayers(){ return MAX_JOYPAD_PLAYERS; }
Q_INVOKABLE int getPlayer(){ return player; }
Q_INVOKABLE void setPlayer(int newPlayerIdx){ player = newPlayerIdx; }
Q_INVOKABLE void ovrdClearA(){ clearButtonOverride<ButtonMaskA>(); }
Q_INVOKABLE void ovrdClearB(){ clearButtonOverride<ButtonMaskB>(); }
Q_INVOKABLE void ovrdClearStart(){ clearButtonOverride<ButtonMaskStart>(); }
Q_INVOKABLE void ovrdClearSelect(){ clearButtonOverride<ButtonMaskSelect>(); }
Q_INVOKABLE void ovrdClearUp(){ clearButtonOverride<ButtonMaskUp>(); }
Q_INVOKABLE void ovrdClearDown(){ clearButtonOverride<ButtonMaskDown>(); }
Q_INVOKABLE void ovrdClearLeft(){ clearButtonOverride<ButtonMaskLeft>(); }
Q_INVOKABLE void ovrdClearRight(){ clearButtonOverride<ButtonMaskRight>(); }
Q_INVOKABLE void ovrdClear(){ ovrdReset(); }
Q_INVOKABLE void ovrdInvertA(){ invertButtonOverride<ButtonMaskA>(); }
Q_INVOKABLE void ovrdInvertB(){ invertButtonOverride<ButtonMaskB>(); }
Q_INVOKABLE void ovrdInvertStart(){ invertButtonOverride<ButtonMaskStart>(); }
Q_INVOKABLE void ovrdInvertSelect(){ invertButtonOverride<ButtonMaskSelect>(); }
Q_INVOKABLE void ovrdInvertUp(){ invertButtonOverride<ButtonMaskUp>(); }
Q_INVOKABLE void ovrdInvertDown(){ invertButtonOverride<ButtonMaskDown>(); }
Q_INVOKABLE void ovrdInvertLeft(){ invertButtonOverride<ButtonMaskLeft>(); }
Q_INVOKABLE void ovrdInvertRight(){ invertButtonOverride<ButtonMaskRight>(); }
Q_INVOKABLE void ovrdA(bool value){ setButtonOverride<ButtonMaskA>(value); }
Q_INVOKABLE void ovrdB(bool value){ setButtonOverride<ButtonMaskB>(value); }
Q_INVOKABLE void ovrdStart(bool value){ setButtonOverride<ButtonMaskStart>(value); }
Q_INVOKABLE void ovrdSelect(bool value){ setButtonOverride<ButtonMaskSelect>(value); }
Q_INVOKABLE void ovrdUp(bool value){ setButtonOverride<ButtonMaskUp>(value); }
Q_INVOKABLE void ovrdDown(bool value){ setButtonOverride<ButtonMaskDown>(value); }
Q_INVOKABLE void ovrdLeft(bool value){ setButtonOverride<ButtonMaskLeft>(value); }
Q_INVOKABLE void ovrdRight(bool value){ setButtonOverride<ButtonMaskRight>(value); }
Q_INVOKABLE void ovrdReset()
{
jsOverrideMask1[player] = 0xFF;
jsOverrideMask2[player] = 0x00;
}
Q_INVOKABLE static void ovrdResetAll();
};
class EmuStateScriptObject: public QObject
{
Q_OBJECT
public:
Q_INVOKABLE EmuStateScriptObject(const QJSValue& jsArg1 = QJSValue(), const QJSValue& jsArg2 = QJSValue());
~EmuStateScriptObject();
Q_PROPERTY(bool persist READ isPersistent WRITE setPersistent)
Q_PROPERTY(int slot READ getSlot WRITE setSlot)
Q_PROPERTY(int compressionLevel READ getCompressionLevel WRITE setCompressionLevel)
EmuStateScriptObject& operator= (const EmuStateScriptObject& obj);
private:
QString filename;
EMUFILE_MEMORY *data = nullptr;
int compression = 0;
int slot = -1;
bool persist = false;
static int numInstances;
void logMessage(int lvl, QString& msg);
public slots:
Q_INVOKABLE bool save();
Q_INVOKABLE bool load();
Q_INVOKABLE bool isValid(){ return (data != nullptr); }
Q_INVOKABLE bool isPersistent(){ return persist; }
Q_INVOKABLE void setPersistent(bool value){ persist = value; }
Q_INVOKABLE int getSlot(){ return slot; }
Q_INVOKABLE void setSlot(int value);
Q_INVOKABLE int getCompressionLevel(){ return compression; }
Q_INVOKABLE void setCompressionLevel(int value){ compression = value; }
Q_INVOKABLE void setFilename(const QString& name){ filename = name; }
Q_INVOKABLE bool saveToFile(const QString& filepath);
Q_INVOKABLE bool loadFromFile(const QString& filepath);
Q_INVOKABLE bool saveFileExists();
Q_INVOKABLE QJSValue copy();
};
class EmuScriptObject: public QObject
{
Q_OBJECT
public:
EmuScriptObject(QObject* parent = nullptr);
~EmuScriptObject();
void setEngine(FCEU::JSEngine* _engine){ engine = _engine; }
void setDialog(QScriptDialog_t* _dialog){ dialog = _dialog; }
private:
FCEU::JSEngine* engine = nullptr;
QScriptDialog_t* dialog = nullptr;
QtScriptInstance* script = nullptr;
public slots:
Q_INVOKABLE void print(const QString& msg);
Q_INVOKABLE void powerOn();
Q_INVOKABLE void softReset();
Q_INVOKABLE void pause();
Q_INVOKABLE void unpause();
Q_INVOKABLE bool paused();
Q_INVOKABLE void frameAdvance();
Q_INVOKABLE int frameCount();
Q_INVOKABLE int lagCount();
Q_INVOKABLE bool lagged();
Q_INVOKABLE void setLagFlag(bool flag);
Q_INVOKABLE bool emulating();
Q_INVOKABLE bool isReadOnly();
Q_INVOKABLE void setReadOnly(bool flag);
Q_INVOKABLE void setRenderPlanes(bool sprites, bool background);
Q_INVOKABLE void registerBeforeFrame(const QJSValue& func);
Q_INVOKABLE void registerAfterFrame(const QJSValue& func);
Q_INVOKABLE void registerStop(const QJSValue& func);
Q_INVOKABLE void message(const QString& msg);
Q_INVOKABLE void speedMode(const QString& mode);
Q_INVOKABLE bool loadRom(const QString& romPath);
Q_INVOKABLE bool onEmulationThread();
Q_INVOKABLE bool addGameGenie(const QString& code);
Q_INVOKABLE bool delGameGenie(const QString& code);
Q_INVOKABLE void exit();
Q_INVOKABLE QString getDir();
Q_INVOKABLE QJSValue getScreenPixel(int x, int y, bool useBackup = false);
Q_INVOKABLE QJSValue createState(int slot = -1);
};
class RomScriptObject: public QObject
{
Q_OBJECT
public:
RomScriptObject(QObject* parent = nullptr);
~RomScriptObject();
void setEngine(FCEU::JSEngine* _engine){ engine = _engine; }
void setDialog(QScriptDialog_t* _dialog){ dialog = _dialog; }
private:
FCEU::JSEngine* engine = nullptr;
QScriptDialog_t* dialog = nullptr;
QtScriptInstance* script = nullptr;
public slots:
Q_INVOKABLE bool isLoaded();
Q_INVOKABLE QString getFileName();
Q_INVOKABLE QString getHash(const QString& type);
Q_INVOKABLE uint8_t readByte(int address);
Q_INVOKABLE int8_t readByteSigned(int address);
Q_INVOKABLE uint8_t readByteUnsigned(int address);
Q_INVOKABLE QJSValue readByteRange(int start, int end);
Q_INVOKABLE void writeByte(int address, int value);
};
class MemoryScriptObject: public QObject
{
Q_OBJECT
public:
MemoryScriptObject(QObject* parent = nullptr);
~MemoryScriptObject();
void setEngine(FCEU::JSEngine* _engine){ engine = _engine; }
void setDialog(QScriptDialog_t* _dialog){ dialog = _dialog; }
void reset();
QtScriptInstance* getScript(){ return script; }
QJSValue* getReadFunc(int address) { return readFunc[address]; }
QJSValue* getWriteFunc(int address) { return writeFunc[address]; }
QJSValue* getExecFunc(int address) { return execFunc[address]; }
private:
static constexpr int AddressRange = 0x10000;
FCEU::JSEngine* engine = nullptr;
QScriptDialog_t* dialog = nullptr;
QtScriptInstance* script = nullptr;
QJSValue* readFunc[AddressRange] = { nullptr };
QJSValue* writeFunc[AddressRange] = { nullptr };
QJSValue* execFunc[AddressRange] = { nullptr };
int numReadFuncsRegistered = 0;
int numWriteFuncsRegistered = 0;
int numExecFuncsRegistered = 0;
void registerCallback(int type, const QJSValue& func, int address, int size = 1);
void unregisterCallback(int type, const QJSValue& func, int address, int size = 1);
public slots:
Q_INVOKABLE uint8_t readByte(int address);
Q_INVOKABLE int8_t readByteSigned(int address);
Q_INVOKABLE uint8_t readByteUnsigned(int address);
Q_INVOKABLE uint16_t readWord(int addressLow, int addressHigh = -1);
Q_INVOKABLE int16_t readWordSigned(int addressLow, int addressHigh = -1);
Q_INVOKABLE uint16_t readWordUnsigned(int addressLow, int addressHigh = -1);
Q_INVOKABLE void writeByte(int address, int value);
Q_INVOKABLE uint16_t getRegisterPC();
Q_INVOKABLE uint8_t getRegisterA();
Q_INVOKABLE uint8_t getRegisterX();
Q_INVOKABLE uint8_t getRegisterY();
Q_INVOKABLE uint8_t getRegisterS();
Q_INVOKABLE uint8_t getRegisterP();
Q_INVOKABLE void setRegisterPC(uint16_t v);
Q_INVOKABLE void setRegisterA(uint8_t v);
Q_INVOKABLE void setRegisterX(uint8_t v);
Q_INVOKABLE void setRegisterY(uint8_t v);
Q_INVOKABLE void setRegisterS(uint8_t v);
Q_INVOKABLE void setRegisterP(uint8_t v);
Q_INVOKABLE void registerRead(const QJSValue& func, int address, int size = 1);
Q_INVOKABLE void registerWrite(const QJSValue& func, int address, int size = 1);
Q_INVOKABLE void registerExec(const QJSValue& func, int address, int size = 1);
Q_INVOKABLE void unregisterRead(const QJSValue& func, int address, int size = 1);
Q_INVOKABLE void unregisterWrite(const QJSValue& func, int address, int size = 1);
Q_INVOKABLE void unregisterExec(const QJSValue& func, int address, int size = 1);
Q_INVOKABLE void unregisterAll();
};
class PpuScriptObject: public QObject
{
Q_OBJECT
public:
PpuScriptObject(QObject* parent = nullptr);
~PpuScriptObject();
void setEngine(FCEU::JSEngine* _engine){ engine = _engine; }
void setDialog(QScriptDialog_t* _dialog){ dialog = _dialog; }
private:
FCEU::JSEngine* engine = nullptr;
QScriptDialog_t* dialog = nullptr;
QtScriptInstance* script = nullptr;
public slots:
Q_INVOKABLE uint8_t readByte(int address);
Q_INVOKABLE int8_t readByteSigned(int address);
Q_INVOKABLE uint8_t readByteUnsigned(int address);
Q_INVOKABLE QJSValue readByteRange(int start, int end);
Q_INVOKABLE void writeByte(int address, int value);
};
class MovieScriptObject: public QObject
{
Q_OBJECT
public:
MovieScriptObject(QObject* parent = nullptr);
~MovieScriptObject();
void setEngine(FCEU::JSEngine* _engine){ engine = _engine; }
enum Mode
{
IDLE = 0,
RECORD,
PLAYBACK,
FINISHED,
TAS_EDITOR
};
Q_ENUM(Mode);
enum SaveType
{
FROM_POWERON = 0,
FROM_SAVESTATE,
FROM_SAVERAM,
};
Q_ENUM(SaveType);
static bool skipRerecords;
private:
FCEU::JSEngine* engine = nullptr;
QtScriptInstance* script = nullptr;
public slots:
Q_INVOKABLE bool active();
Q_INVOKABLE bool isPlaying();
Q_INVOKABLE bool isRecording();
Q_INVOKABLE bool isPowerOn();
Q_INVOKABLE bool isFromSaveState();
Q_INVOKABLE void replay();
Q_INVOKABLE bool getReadOnly();
Q_INVOKABLE void setReadOnly(bool which);
Q_INVOKABLE bool play(const QString& filename, bool readOnly = false, int pauseFrame = 0);
Q_INVOKABLE bool record(const QString& filename, int saveType = FROM_POWERON, const QString author = QString());
Q_INVOKABLE int frameCount();
Q_INVOKABLE int mode();
Q_INVOKABLE void stop();
Q_INVOKABLE int length();
Q_INVOKABLE int rerecordCount();
Q_INVOKABLE void rerecordCounting(bool counting);
Q_INVOKABLE QString getFilename();
Q_INVOKABLE QString getFilepath();
Q_INVOKABLE void close(){ stop(); }
Q_INVOKABLE bool readOnly(){ return getReadOnly(); }
Q_INVOKABLE void playBeginning(){ replay(); }
Q_INVOKABLE bool playback(const QString& filename, bool readOnly = false, int pauseFrame = 0){ return play(filename, readOnly, pauseFrame); }
Q_INVOKABLE bool load(const QString& filename, bool readOnly = false, int pauseFrame = 0){ return play(filename, readOnly, pauseFrame); }
Q_INVOKABLE bool save(const QString& filename, int saveType = FROM_POWERON, const QString author = QString()){ return record(filename, saveType, author); }
};
class InputScriptObject: public QObject
{
Q_OBJECT
public:
InputScriptObject(QObject* parent = nullptr);
~InputScriptObject();
void setEngine(FCEU::JSEngine* _engine){ engine = _engine; }
private:
FCEU::JSEngine* engine = nullptr;
QtScriptInstance* script = nullptr;
public slots:
Q_INVOKABLE QJSValue readJoypad(int player = 0, bool immediate = false);
Q_INVOKABLE int maxJoypadPlayers(){ return JoypadScriptObject::MAX_JOYPAD_PLAYERS; }
};
class ModuleLoaderObject: public QObject
{
Q_OBJECT
public:
ModuleLoaderObject(QObject* parent = nullptr);
~ModuleLoaderObject();
void setEngine(FCEU::JSEngine* _engine){ engine = _engine; }
private:
FCEU::JSEngine* engine = nullptr;
QtScriptInstance* script = nullptr;
int scopeCounter = 0;
public slots:
Q_INVOKABLE void GlobalImport(const QString& ns, const QString& file);
};
} // JS
class ScriptExecutionState
{
public:
void start()
{
timeMs = 0;
executing = true;
}
void stop()
{
executing = false;
timeMs = 0;
}
bool isRunning(){ return executing; }
unsigned int timeCheck()
{
unsigned int retval = timeMs;
timeMs += checkPeriod;
return retval;
}
static constexpr unsigned int checkPeriod = 100;
private:
bool executing = false;
unsigned int timeMs = 0;
};
class QtScriptInstance : public QObject
{
Q_OBJECT
public:
QtScriptInstance(QObject* parent = nullptr);
~QtScriptInstance();
void resetEngine();
int loadScriptFile(QString filepath);
bool isRunning(){ return running; };
void stopRunning();
int call(const QString& funcName, const QJSValueList& args = QJSValueList());
void frameAdvance();
void onFrameBegin();
void onFrameFinish();
void onGuiUpdate();
void checkForHang();
void flushLog();
int runFunc(QJSValue &func, const QJSValueList& args = QJSValueList());
int throwError(QJSValue::ErrorType errorType, const QString &message = QString());
const QString& getSrcFile(){ return srcFile; };
FCEU::JSEngine* getEngine(){ return engine; };
private:
int initEngine();
void shutdownEngine();
void printSymbols(QJSValue& val, int iter = 0);
void loadObjectChildren(QJSValue& jsObject, QObject* obj);
ScriptExecutionState* getExecutionState();
FCEU::JSEngine* engine = nullptr;
QScriptDialog_t* dialog = nullptr;
JS::EmuScriptObject* emu = nullptr;
JS::RomScriptObject* rom = nullptr;
JS::PpuScriptObject* ppu = nullptr;
JS::MemoryScriptObject* mem = nullptr;
JS::InputScriptObject* input = nullptr;
JS::MovieScriptObject* movie = nullptr;
JS::ModuleLoaderObject* moduleLoader = nullptr;
QWidget* ui_rootWidget = nullptr;
QJSValue *onFrameBeginCallback = nullptr;
QJSValue *onFrameFinishCallback = nullptr;
QJSValue *onScriptStopCallback = nullptr;
QJSValue *onGuiUpdateCallback = nullptr;
ScriptExecutionState guiFuncState;
ScriptExecutionState emuFuncState;
int frameAdvanceCount = 0;
int frameAdvanceState = 0;
bool running = false;
QString srcFile;
signals:
void errorNotify();
public slots:
Q_INVOKABLE void print(const QString& msg);
Q_INVOKABLE void loadUI(const QString& uiFilePath);
Q_INVOKABLE QString openFileBrowser(const QString& initialPath = QString());
Q_INVOKABLE void registerBeforeEmuFrame(const QJSValue& func);
Q_INVOKABLE void registerAfterEmuFrame(const QJSValue& func);
Q_INVOKABLE void registerStop(const QJSValue& func);
Q_INVOKABLE void registerGuiUpdate(const QJSValue& func);
Q_INVOKABLE bool onGuiThread();
Q_INVOKABLE bool onEmulationThread();
};
class ScriptMonitorThread_t : public QThread
{
Q_OBJECT
protected:
void run( void ) override;
public:
ScriptMonitorThread_t( QObject *parent = 0 );
};
class QtScriptManager : public QObject
{
Q_OBJECT
public:
QtScriptManager(QObject* parent = nullptr);
~QtScriptManager();
static QtScriptManager* getInstance(){ return _instance; }
static QtScriptManager* create(QObject* parent = nullptr);
static void destroy();
static void logMessageQt(QtMsgType type, const QString &msg);
int numScriptsLoaded(void){ return scriptList.size(); }
void addScriptInstance(QtScriptInstance* script);
void removeScriptInstance(QtScriptInstance* script);
private:
static QtScriptManager* _instance;
FCEU::mutex scriptListMutex;
QList<QtScriptInstance*> scriptList;
QTimer *periodicUpdateTimer = nullptr;
ScriptMonitorThread_t *monitorThread = nullptr;
friend class ScriptMonitorThread_t;
public slots:
void frameBeginUpdate();
void frameFinishedUpdate();
void guiUpdate();
};
class JsPropertyItem : public QTreeWidgetItem
{
public:
JsPropertyItem()
: QTreeWidgetItem()
{
}
virtual ~JsPropertyItem() override
{
}
QJSValue jsValue;
QMap<QString, JsPropertyItem*> childMap;
};
class JsPropertyTree : public QTreeWidget
{
Q_OBJECT
public:
JsPropertyTree(QWidget *parent = nullptr)
: QTreeWidget(parent)
{
}
virtual ~JsPropertyTree() override
{
}
QMap<QString, JsPropertyItem*> childMap;
};
class QScriptDialog_t : public QDialog
{
Q_OBJECT
public:
QScriptDialog_t(QWidget *parent = nullptr);
~QScriptDialog_t(void);
void refreshState(void);
void logOutput(const QString& text);
protected:
void resetLog();
void closeEvent(QCloseEvent *bar);
void openJSKillMessageBox(void);
void clearPropertyTree();
void loadPropertyTree(QJSValue& val, JsPropertyItem* parentItem = nullptr);
QMenuBar* buildMenuBar();
QMenuBar* menuBar;
QTemporaryFile *logFile = nullptr;
QTimer *periodicTimer;
QLineEdit *scriptPath;
QLineEdit *scriptArgs;
QPushButton *browseButton;
QPushButton *stopButton;
QPushButton *startButton;
QPushButton *clearButton;
QTabWidget *tabWidget;
QTextEdit *jsOutput;
JsPropertyTree *propTree;
QtScriptInstance *scriptInstance;
QString emuThreadText;
QString logSavePath;
QLabel *logFilepathLbl;
QLabel *logFilepath;
private:
public slots:
void flushLog();
void closeWindow(void);
private slots:
void saveLog(bool openFileBrowser = false);
void updatePeriodic(void);
void openScriptFile(void);
void startScript(void);
void stopScript(void);
void onLogLinkClicked(const QString&);
void onScriptError(void);
void reloadGlobalTree(void);
};
bool FCEU_JSRerecordCountSkip();
uint8_t FCEU_JSReadJoypad(int which, uint8_t phyState);
#endif // __FCEU_QSCRIPT_ENABLE__

View File

@ -127,13 +127,13 @@ public:
QValidator::State validate(QString &input, int &pos) const
{
int i;
//printf("Validate: %i '%s'\n", input.size(), input.toStdString().c_str() );
//printf("Validate: %i '%s'\n", input.size(), input.toLocal8Bit().constData() );
if (input.size() == 0)
{
return QValidator::Acceptable;
}
std::string s = input.toStdString();
std::string s = input.toLocal8Bit().constData();
i = 0;
if ((s[i] == '-') || (s[i] == '+'))
@ -648,7 +648,7 @@ static int64_t getLineEditValue(QLineEdit *edit, bool forceHex = false)
int64_t val = 0;
std::string s;
s = edit->text().toStdString();
s = edit->text().toLocal8Bit().constData();
if (s.size() > 0)
{
@ -2012,63 +2012,63 @@ void QRamSearchView::paintEvent(QPaintEvent *event)
painter.fillRect(0, y - pxLineSpacing + pxLineLead, viewWidth, pxLineSpacing, QColor("light blue"));
}
sprintf(addrStr, "$%04X", loc->addr);
snprintf(addrStr, sizeof(addrStr), "$%04X", loc->addr);
if (dpySize == 'd')
{
if (dpyType == 'h')
{
sprintf(valStr, "0x%08X", loc->val.v32.u);
sprintf(prevStr, "0x%08X", loc->hist.back().v32.u);
snprintf(valStr, sizeof(valStr), "0x%08X", loc->val.v32.u);
snprintf(prevStr, sizeof(prevStr), "0x%08X", loc->hist.back().v32.u);
}
else if (dpyType == 'u')
{
sprintf(valStr, "%u", loc->val.v32.u);
sprintf(prevStr, "%u", loc->hist.back().v32.u);
snprintf(valStr, sizeof(valStr), "%u", loc->val.v32.u);
snprintf(prevStr, sizeof(prevStr), "%u", loc->hist.back().v32.u);
}
else
{
sprintf(valStr, "%i", loc->val.v32.i);
sprintf(prevStr, "%i", loc->hist.back().v32.i);
snprintf(valStr, sizeof(valStr), "%i", loc->val.v32.i);
snprintf(prevStr, sizeof(prevStr), "%i", loc->hist.back().v32.i);
}
}
else if (dpySize == 'w')
{
if (dpyType == 'h')
{
sprintf(valStr, "0x%04X", loc->val.v16.u);
sprintf(prevStr, "0x%04X", loc->hist.back().v16.u);
snprintf(valStr, sizeof(valStr), "0x%04X", loc->val.v16.u);
snprintf(prevStr, sizeof(prevStr), "0x%04X", loc->hist.back().v16.u);
}
else if (dpyType == 'u')
{
sprintf(valStr, "%u", loc->val.v16.u);
sprintf(prevStr, "%u", loc->hist.back().v16.u);
snprintf(valStr, sizeof(valStr), "%u", loc->val.v16.u);
snprintf(prevStr, sizeof(prevStr), "%u", loc->hist.back().v16.u);
}
else
{
sprintf(valStr, "%i", loc->val.v16.i);
sprintf(prevStr, "%i", loc->hist.back().v16.i);
snprintf(valStr, sizeof(valStr), "%i", loc->val.v16.i);
snprintf(prevStr, sizeof(prevStr), "%i", loc->hist.back().v16.i);
}
}
else
{
if (dpyType == 'h')
{
sprintf(valStr, "0x%02X", loc->val.v8.u);
sprintf(prevStr, "0x%02X", loc->hist.back().v8.u);
snprintf(valStr, sizeof(valStr), "0x%02X", loc->val.v8.u);
snprintf(prevStr, sizeof(prevStr), "0x%02X", loc->hist.back().v8.u);
}
else if (dpyType == 'u')
{
sprintf(valStr, "%u", loc->val.v8.u);
sprintf(prevStr, "%u", loc->hist.back().v8.u);
snprintf(valStr, sizeof(valStr), "%u", loc->val.v8.u);
snprintf(prevStr, sizeof(prevStr), "%u", loc->hist.back().v8.u);
}
else
{
sprintf(valStr, "%i", loc->val.v8.i);
sprintf(prevStr, "%i", loc->hist.back().v8.i);
snprintf(valStr, sizeof(valStr), "%i", loc->val.v8.i);
snprintf(prevStr, sizeof(prevStr), "%i", loc->hist.back().v8.i);
}
}
sprintf(chgStr, "%u", loc->chgCount);
snprintf(chgStr, sizeof(chgStr), "%u", loc->chgCount);
for (i = 0; i < 4; i++)
{

View File

@ -41,6 +41,7 @@
#include "../../fceu.h"
#include "../../cheat.h"
#include "../../debug.h"
#include "utils/StringUtils.h"
#include "Qt/main.h"
#include "Qt/dface.h"
@ -375,7 +376,8 @@ void RamWatchDialog_t::updateRamWatchDisplay(void)
int idx=0;
QTreeWidgetItem *item;
std::list < ramWatch_t * >::iterator it;
char addrStr[32], valStr1[16], valStr2[16];
FCEU::FixedString<32> addrStr;
FCEU::FixedString<16> valStr1, valStr2;
ramWatch_t *rw;
for (it = ramWatchList.ls.begin (); it != ramWatchList.ls.end (); it++)
@ -397,17 +399,17 @@ void RamWatchDialog_t::updateRamWatchDisplay(void)
}
if ( rw->isSep || (rw->addr < 0) )
{
strcpy (addrStr, "--------");
addrStr = "--------";
}
else
{
if ( rw->size > 1 )
{
sprintf (addrStr, "$%04X-$%04X", rw->addr, rw->addr + rw->size - 1);
addrStr.sprintf("$%04X-$%04X", rw->addr, rw->addr + rw->size - 1);
}
else
{
sprintf (addrStr, "$%04X", rw->addr);
addrStr.sprintf("$%04X", rw->addr);
}
}
@ -415,8 +417,7 @@ void RamWatchDialog_t::updateRamWatchDisplay(void)
if ( rw->isSep || (rw->addr < 0) )
{
strcpy( valStr1, "--------");
strcpy( valStr2, "--------");
valStr1 = valStr2 = "--------";
}
else
{
@ -424,37 +425,37 @@ void RamWatchDialog_t::updateRamWatchDisplay(void)
{
if (rw->type == 's')
{
sprintf (valStr1, "%i", rw->val.i32);
valStr1.sprintf("%i", rw->val.i32);
}
else
{
sprintf (valStr1, "%u", rw->val.u32);
valStr1.sprintf("%u", rw->val.u32);
}
sprintf (valStr2, "0x%08X", rw->val.u32);
valStr2.sprintf("0x%08X", rw->val.u32);
}
else if (rw->size == 2)
{
if (rw->type == 's')
{
sprintf (valStr1, "%6i", rw->val.i16);
valStr1.sprintf("%6i", rw->val.i16);
}
else
{
sprintf (valStr1, "%6u", rw->val.u16);
valStr1.sprintf("%6u", rw->val.u16);
}
sprintf (valStr2, "0x%04X", rw->val.u16);
valStr2.sprintf("0x%04X", rw->val.u16);
}
else
{
if (rw->type == 's')
{
sprintf (valStr1, "%6i", rw->val.i8);
valStr1.sprintf("%6i", rw->val.i8);
}
else
{
sprintf (valStr1, "%6u", rw->val.u8);
valStr1.sprintf("%6u", rw->val.u8);
}
sprintf (valStr2, "0x%02X", rw->val.u8);
valStr2.sprintf("0x%02X", rw->val.u8);
}
}
@ -494,9 +495,9 @@ void RamWatchDialog_t::updateRamWatchDisplay(void)
else
{
item->setFirstColumnSpanned(false);
item->setText( 0, tr(addrStr) );
item->setText( 1, tr(valStr1) );
item->setText( 2, tr(valStr2) );
item->setText( 0, tr(addrStr.c_str()) );
item->setText( 1, tr(valStr1.c_str()) );
item->setText( 2, tr(valStr2.c_str()) );
item->setText( 3, tr(rw->name.c_str()) );
}
@ -577,9 +578,9 @@ void RamWatchDialog_t::openListCB(void)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
loadWatchFile ( filename.toStdString().c_str() );
loadWatchFile ( filename.toLocal8Bit().constData() );
return;
}
@ -637,9 +638,9 @@ void RamWatchDialog_t::appendListCB(void)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
loadWatchFile( filename.toStdString().c_str(), 1 );
loadWatchFile( filename.toLocal8Bit().constData(), 1 );
}
//----------------------------------------------------------------------------
void RamWatchDialog_t::saveListCB(void)
@ -716,9 +717,9 @@ void RamWatchDialog_t::saveListAs(void)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
saveWatchFile( filename.toStdString().c_str() );
saveWatchFile( filename.toLocal8Bit().constData() );
}
//----------------------------------------------------------------------------
void ramWatch_t::updateMem (void)
@ -851,7 +852,7 @@ void RamWatchDialog_t::openWatchEditWindow( ramWatch_t *rw, int mode)
if ( (rw->addr >= 0) && !rw->isSep )
{
sprintf( stmp, "%04X", rw->addr );
snprintf( stmp, sizeof(stmp), "%04X", rw->addr );
addrEntry->setText( tr(stmp) );
}
else
@ -893,7 +894,7 @@ void RamWatchDialog_t::openWatchEditWindow( ramWatch_t *rw, int mode)
{
int addr = -1, size = 1;
addr = ::strtol( addrEntry->text().toStdString().c_str(), NULL, 16 );
addr = ::strtol( addrEntry->text().toLocal8Bit().constData(), NULL, 16 );
if ( dataSize4Btn->isChecked() )
{
@ -910,12 +911,12 @@ void RamWatchDialog_t::openWatchEditWindow( ramWatch_t *rw, int mode)
if ( (rw == NULL) || mode )
{
ramWatchList.add_entry( notesEntry->text().toStdString().c_str(),
ramWatchList.add_entry( notesEntry->text().toLocal8Bit().constData(),
addr, unsignedTypeBtn->isChecked() ? 'u' : 's', size, isSep);
}
else
{
rw->name = notesEntry->text().toStdString();
rw->name = notesEntry->text().toLocal8Bit().constData();
rw->type = unsignedTypeBtn->isChecked() ? 'u' : 's';
rw->addr = addr;
rw->size = size;

View File

@ -606,7 +606,7 @@ void StateRecorderDialog_t::recalcMemoryUsage(void)
int inumSnaps = static_cast<int>( fnumSnaps + 0.5f );
sprintf( stmp, "%i", inumSnaps );
snprintf( stmp, sizeof(stmp), "%i", inumSnaps );
numSnapsLbl->setText( tr(stmp) );
@ -642,11 +642,11 @@ void StateRecorderDialog_t::recalcMemoryUsage(void)
if (fsnapSize >= oneKiloByte)
{
sprintf( stmp, "%.02f kB", fsnapSize / oneKiloByte );
snprintf( stmp, sizeof(stmp), "%.02f kB", fsnapSize / oneKiloByte );
}
else
{
sprintf( stmp, "%.0f B", fsnapSize );
snprintf( stmp, sizeof(stmp), "%.0f B", fsnapSize );
}
snapMemSizeLbl->setText( tr(stmp) );
@ -655,20 +655,20 @@ void StateRecorderDialog_t::recalcMemoryUsage(void)
if (ftotalSize >= oneMegaByte)
{
sprintf( stmp, "%.02f MB", ftotalSize / oneMegaByte );
snprintf( stmp, sizeof(stmp), "%.02f MB", ftotalSize / oneMegaByte );
}
else if (ftotalSize >= oneKiloByte)
{
sprintf( stmp, "%.02f kB", ftotalSize / oneKiloByte );
snprintf( stmp, sizeof(stmp), "%.02f kB", ftotalSize / oneKiloByte );
}
else
{
sprintf( stmp, "%.0f B", ftotalSize );
snprintf( stmp, sizeof(stmp), "%.0f B", ftotalSize );
}
totalMemUsageLbl->setText( tr(stmp) );
sprintf( stmp, "%.02f ms", saveTimeMs);
snprintf( stmp, sizeof(stmp), "%.02f ms", saveTimeMs);
saveTimeLbl->setText( tr(stmp) );
}
//----------------------------------------------------------------------------

View File

@ -31,6 +31,7 @@
#include "../../ines.h"
#include "../../asm.h"
#include "../../x6502.h"
#include "utils/StringBuilder.h"
#include "Qt/fceuWrapper.h"
#include "Qt/SymbolicDebug.h"
@ -42,6 +43,7 @@
debugSymbol_t *replaceSymbols( int flags, int addr, char *str )
{
debugSymbol_t *sym;
StringBuilder sb(str);
if ( addr >= 0x8000 )
{
@ -59,36 +61,16 @@ debugSymbol_t *replaceSymbols( int flags, int addr, char *str )
}
}
if ( !sym || !( flags & ASM_DEBUG_REPLACE ) )
{
sb << sb_addr( addr, flags & ASM_DEBUG_ADDR_02X ? 2 : 4 );
if ( sym )
sb << ' ';
}
if ( sym )
{
if ( flags & ASM_DEBUG_REPLACE )
{
strcpy( str, sym->name().c_str() );
}
else
{
if ( flags & ASM_DEBUG_ADDR_02X )
{
sprintf( str, "$%02X ", addr );
}
else
{
sprintf( str, "$%04X ", addr );
}
strcat( str, sym->name().c_str() );
}
}
else
{
if ( flags & ASM_DEBUG_ADDR_02X )
{
sprintf( str, "$%02X", addr );
}
else
{
sprintf( str, "$%04X", addr );
}
}
sb << sym->name().c_str();
return sym;
}
@ -97,10 +79,12 @@ int DisassembleWithDebug(int addr, uint8_t *opcode, int flags, char *str, debugS
{
debugSymbol_t *sym = NULL;
debugSymbol_t *sym2 = NULL;
static char chr[8]={0};
const char *chr;
char indReg;
uint16_t tmp,tmp2;
char stmp[128], stmp2[128];
bool symDebugEnable, showTrace;
StringBuilder sb(str);
symDebugEnable = (flags & ASM_DEBUG_SYMS ) ? true : false;
showTrace = (flags & ASM_DEBUG_TRACES) ? true : false;
@ -133,7 +117,7 @@ int DisassembleWithDebug(int addr, uint8_t *opcode, int flags, char *str, debugS
#ifdef BRK_3BYTE_HACK
case 0x00:
sprintf(str,"BRK %02X %02X", opcode[1], opcode[2]);
snprintf(str, sizeof(str), "BRK %02X %02X", opcode[1], opcode[2]);
break;
#else
case 0x00: strcpy(str,"BRK"); break;
@ -170,321 +154,321 @@ int DisassembleWithDebug(int addr, uint8_t *opcode, int flags, char *str, debugS
case 0xF8: strcpy(str,"SED"); break;
//(Indirect,X)
case 0x01: strcpy(chr,"ORA"); goto _indirectx;
case 0x21: strcpy(chr,"AND"); goto _indirectx;
case 0x41: strcpy(chr,"EOR"); goto _indirectx;
case 0x61: strcpy(chr,"ADC"); goto _indirectx;
case 0x81: strcpy(chr,"STA"); goto _indirectx;
case 0xA1: strcpy(chr,"LDA"); goto _indirectx;
case 0xC1: strcpy(chr,"CMP"); goto _indirectx;
case 0xE1: strcpy(chr,"SBC"); goto _indirectx;
case 0x01: chr = "ORA"; goto _indirectx;
case 0x21: chr = "AND"; goto _indirectx;
case 0x41: chr = "EOR"; goto _indirectx;
case 0x61: chr = "ADC"; goto _indirectx;
case 0x81: chr = "STA"; goto _indirectx;
case 0xA1: chr = "LDA"; goto _indirectx;
case 0xC1: chr = "CMP"; goto _indirectx;
case 0xE1: chr = "SBC"; goto _indirectx;
_indirectx:
indirectX(tmp);
if ( symDebugEnable )
{
sym = replaceSymbols( flags, tmp, stmp );
showTrace
? sprintf(str,"%s ($%02X,X) @ %s = #$%02X", chr,opcode[1],stmp,GetMem(tmp))
: sprintf(str,"%s ($%02X,X)", chr,opcode[1]);
}
else
sb << chr << " (" << sb_addr(opcode[1], 2) << ",X)";
if (showTrace)
{
showTrace
? sprintf(str,"%s ($%02X,X) @ $%04X = #$%02X", chr,opcode[1],tmp,GetMem(tmp))
: sprintf(str,"%s ($%02X,X)", chr,opcode[1]);
sb << " @ ";
if (symDebugEnable)
sb << stmp;
else
sb << sb_addr(tmp);
sb << " = " << sb_lit(GetMem(tmp));
}
break;
//Zero Page
case 0x05: strcpy(chr,"ORA"); goto _zeropage;
case 0x06: strcpy(chr,"ASL"); goto _zeropage;
case 0x24: strcpy(chr,"BIT"); goto _zeropage;
case 0x25: strcpy(chr,"AND"); goto _zeropage;
case 0x26: strcpy(chr,"ROL"); goto _zeropage;
case 0x45: strcpy(chr,"EOR"); goto _zeropage;
case 0x46: strcpy(chr,"LSR"); goto _zeropage;
case 0x65: strcpy(chr,"ADC"); goto _zeropage;
case 0x66: strcpy(chr,"ROR"); goto _zeropage;
case 0x84: strcpy(chr,"STY"); goto _zeropage;
case 0x85: strcpy(chr,"STA"); goto _zeropage;
case 0x86: strcpy(chr,"STX"); goto _zeropage;
case 0xA4: strcpy(chr,"LDY"); goto _zeropage;
case 0xA5: strcpy(chr,"LDA"); goto _zeropage;
case 0xA6: strcpy(chr,"LDX"); goto _zeropage;
case 0xC4: strcpy(chr,"CPY"); goto _zeropage;
case 0xC5: strcpy(chr,"CMP"); goto _zeropage;
case 0xC6: strcpy(chr,"DEC"); goto _zeropage;
case 0xE4: strcpy(chr,"CPX"); goto _zeropage;
case 0xE5: strcpy(chr,"SBC"); goto _zeropage;
case 0xE6: strcpy(chr,"INC"); goto _zeropage;
case 0x05: chr = "ORA"; goto _zeropage;
case 0x06: chr = "ASL"; goto _zeropage;
case 0x24: chr = "BIT"; goto _zeropage;
case 0x25: chr = "AND"; goto _zeropage;
case 0x26: chr = "ROL"; goto _zeropage;
case 0x45: chr = "EOR"; goto _zeropage;
case 0x46: chr = "LSR"; goto _zeropage;
case 0x65: chr = "ADC"; goto _zeropage;
case 0x66: chr = "ROR"; goto _zeropage;
case 0x84: chr = "STY"; goto _zeropage;
case 0x85: chr = "STA"; goto _zeropage;
case 0x86: chr = "STX"; goto _zeropage;
case 0xA4: chr = "LDY"; goto _zeropage;
case 0xA5: chr = "LDA"; goto _zeropage;
case 0xA6: chr = "LDX"; goto _zeropage;
case 0xC4: chr = "CPY"; goto _zeropage;
case 0xC5: chr = "CMP"; goto _zeropage;
case 0xC6: chr = "DEC"; goto _zeropage;
case 0xE4: chr = "CPX"; goto _zeropage;
case 0xE5: chr = "SBC"; goto _zeropage;
case 0xE6: chr = "INC"; goto _zeropage;
_zeropage:
// ################################## Start of SP CODE ###########################
// Change width to %04X // don't!
sb << chr << ' ';
if ( symDebugEnable )
{
sym = replaceSymbols( flags | ASM_DEBUG_ADDR_02X, opcode[1], stmp );
showTrace
? sprintf(str,"%s %s = #$%02X", chr,stmp,GetMem(opcode[1]))
: sprintf(str,"%s %s", chr,stmp);
sb << stmp;
}
else
{
showTrace
? sprintf(str,"%s $%02X = #$%02X", chr,opcode[1],GetMem(opcode[1]))
: sprintf(str,"%s $%02X", chr,opcode[1]);
}
sb << sb_addr(opcode[1], 2);
if (showTrace)
sb << " = " << sb_lit(GetMem(opcode[1]));
// ################################## End of SP CODE ###########################
break;
//#Immediate
case 0x09: strcpy(chr,"ORA"); goto _immediate;
case 0x29: strcpy(chr,"AND"); goto _immediate;
case 0x49: strcpy(chr,"EOR"); goto _immediate;
case 0x69: strcpy(chr,"ADC"); goto _immediate;
//case 0x89: strcpy(chr,"STA"); goto _immediate; //baka, no STA #imm!!
case 0xA0: strcpy(chr,"LDY"); goto _immediate;
case 0xA2: strcpy(chr,"LDX"); goto _immediate;
case 0xA9: strcpy(chr,"LDA"); goto _immediate;
case 0xC0: strcpy(chr,"CPY"); goto _immediate;
case 0xC9: strcpy(chr,"CMP"); goto _immediate;
case 0xE0: strcpy(chr,"CPX"); goto _immediate;
case 0xE9: strcpy(chr,"SBC"); goto _immediate;
case 0x09: chr = "ORA"; goto _immediate;
case 0x29: chr = "AND"; goto _immediate;
case 0x49: chr = "EOR"; goto _immediate;
case 0x69: chr = "ADC"; goto _immediate;
//case 0x89: chr = "STA"; goto _immediate; //baka, no STA #imm!!
case 0xA0: chr = "LDY"; goto _immediate;
case 0xA2: chr = "LDX"; goto _immediate;
case 0xA9: chr = "LDA"; goto _immediate;
case 0xC0: chr = "CPY"; goto _immediate;
case 0xC9: chr = "CMP"; goto _immediate;
case 0xE0: chr = "CPX"; goto _immediate;
case 0xE9: chr = "SBC"; goto _immediate;
_immediate:
sprintf(str,"%s #$%02X", chr,opcode[1]);
sb << chr << ' ' << sb_lit(opcode[1]);
break;
//Absolute
case 0x0D: strcpy(chr,"ORA"); goto _absolute;
case 0x0E: strcpy(chr,"ASL"); goto _absolute;
case 0x2C: strcpy(chr,"BIT"); goto _absolute;
case 0x2D: strcpy(chr,"AND"); goto _absolute;
case 0x2E: strcpy(chr,"ROL"); goto _absolute;
case 0x4D: strcpy(chr,"EOR"); goto _absolute;
case 0x4E: strcpy(chr,"LSR"); goto _absolute;
case 0x6D: strcpy(chr,"ADC"); goto _absolute;
case 0x6E: strcpy(chr,"ROR"); goto _absolute;
case 0x8C: strcpy(chr,"STY"); goto _absolute;
case 0x8D: strcpy(chr,"STA"); goto _absolute;
case 0x8E: strcpy(chr,"STX"); goto _absolute;
case 0xAC: strcpy(chr,"LDY"); goto _absolute;
case 0xAD: strcpy(chr,"LDA"); goto _absolute;
case 0xAE: strcpy(chr,"LDX"); goto _absolute;
case 0xCC: strcpy(chr,"CPY"); goto _absolute;
case 0xCD: strcpy(chr,"CMP"); goto _absolute;
case 0xCE: strcpy(chr,"DEC"); goto _absolute;
case 0xEC: strcpy(chr,"CPX"); goto _absolute;
case 0xED: strcpy(chr,"SBC"); goto _absolute;
case 0xEE: strcpy(chr,"INC"); goto _absolute;
case 0x0D: chr = "ORA"; goto _absolute;
case 0x0E: chr = "ASL"; goto _absolute;
case 0x2C: chr = "BIT"; goto _absolute;
case 0x2D: chr = "AND"; goto _absolute;
case 0x2E: chr = "ROL"; goto _absolute;
case 0x4D: chr = "EOR"; goto _absolute;
case 0x4E: chr = "LSR"; goto _absolute;
case 0x6D: chr = "ADC"; goto _absolute;
case 0x6E: chr = "ROR"; goto _absolute;
case 0x8C: chr = "STY"; goto _absolute;
case 0x8D: chr = "STA"; goto _absolute;
case 0x8E: chr = "STX"; goto _absolute;
case 0xAC: chr = "LDY"; goto _absolute;
case 0xAD: chr = "LDA"; goto _absolute;
case 0xAE: chr = "LDX"; goto _absolute;
case 0xCC: chr = "CPY"; goto _absolute;
case 0xCD: chr = "CMP"; goto _absolute;
case 0xCE: chr = "DEC"; goto _absolute;
case 0xEC: chr = "CPX"; goto _absolute;
case 0xED: chr = "SBC"; goto _absolute;
case 0xEE: chr = "INC"; goto _absolute;
_absolute:
absolute(tmp);
sb << chr << ' ';
if ( symDebugEnable )
{
sym = replaceSymbols( flags, tmp, stmp );
showTrace
? sprintf(str,"%s %s = #$%02X", chr,stmp,GetMem(tmp))
: sprintf(str,"%s %s", chr,stmp);
sb << stmp;
}
else
{
showTrace
? sprintf(str,"%s $%04X = #$%02X", chr,tmp,GetMem(tmp))
: sprintf(str,"%s $%04X", chr,tmp);
}
sb << sb_addr(tmp);
if (showTrace)
sb << " = " << sb_lit(GetMem(tmp));
break;
//branches
case 0x10: strcpy(chr,"BPL"); goto _branch;
case 0x30: strcpy(chr,"BMI"); goto _branch;
case 0x50: strcpy(chr,"BVC"); goto _branch;
case 0x70: strcpy(chr,"BVS"); goto _branch;
case 0x90: strcpy(chr,"BCC"); goto _branch;
case 0xB0: strcpy(chr,"BCS"); goto _branch;
case 0xD0: strcpy(chr,"BNE"); goto _branch;
case 0xF0: strcpy(chr,"BEQ"); goto _branch;
case 0x10: chr = "BPL"; goto _branch;
case 0x30: chr = "BMI"; goto _branch;
case 0x50: chr = "BVC"; goto _branch;
case 0x70: chr = "BVS"; goto _branch;
case 0x90: chr = "BCC"; goto _branch;
case 0xB0: chr = "BCS"; goto _branch;
case 0xD0: chr = "BNE"; goto _branch;
case 0xF0: chr = "BEQ"; goto _branch;
_branch:
relative(tmp);
sb << chr << ' ';
if ( symDebugEnable )
{
sym = replaceSymbols( flags, tmp, stmp );
sprintf(str,"%s %s", chr,stmp);
sb << stmp;
}
else
{
sprintf(str,"%s $%04X", chr,tmp);
}
sb << sb_addr(tmp);
break;
//(Indirect),Y
case 0x11: strcpy(chr,"ORA"); goto _indirecty;
case 0x31: strcpy(chr,"AND"); goto _indirecty;
case 0x51: strcpy(chr,"EOR"); goto _indirecty;
case 0x71: strcpy(chr,"ADC"); goto _indirecty;
case 0x91: strcpy(chr,"STA"); goto _indirecty;
case 0xB1: strcpy(chr,"LDA"); goto _indirecty;
case 0xD1: strcpy(chr,"CMP"); goto _indirecty;
case 0xF1: strcpy(chr,"SBC"); goto _indirecty;
case 0x11: chr = "ORA"; goto _indirecty;
case 0x31: chr = "AND"; goto _indirecty;
case 0x51: chr = "EOR"; goto _indirecty;
case 0x71: chr = "ADC"; goto _indirecty;
case 0x91: chr = "STA"; goto _indirecty;
case 0xB1: chr = "LDA"; goto _indirecty;
case 0xD1: chr = "CMP"; goto _indirecty;
case 0xF1: chr = "SBC"; goto _indirecty;
_indirecty:
indirectY(tmp);
if ( symDebugEnable )
if (symDebugEnable)
sym = replaceSymbols(flags, tmp, stmp);
sb << chr << " (" << sb_addr(opcode[1], 2) << "),Y";
if (showTrace)
{
sym = replaceSymbols( flags, tmp, stmp );
showTrace
? sprintf(str,"%s ($%02X),Y @ %s = #$%02X", chr,opcode[1],stmp,GetMem(tmp))
: sprintf(str,"%s ($%02X),Y", chr,opcode[1]);
}
else
{
showTrace
? sprintf(str,"%s ($%02X),Y @ $%04X = #$%02X", chr,opcode[1],tmp,GetMem(tmp))
: sprintf(str,"%s ($%02X),Y", chr,opcode[1]);
sb << " @ ";
if (symDebugEnable)
sb << stmp;
else
sb << sb_addr(tmp);
sb << " = " << sb_lit(GetMem(tmp));
}
break;
//Zero Page,X
case 0x15: strcpy(chr,"ORA"); goto _zeropagex;
case 0x16: strcpy(chr,"ASL"); goto _zeropagex;
case 0x35: strcpy(chr,"AND"); goto _zeropagex;
case 0x36: strcpy(chr,"ROL"); goto _zeropagex;
case 0x55: strcpy(chr,"EOR"); goto _zeropagex;
case 0x56: strcpy(chr,"LSR"); goto _zeropagex;
case 0x75: strcpy(chr,"ADC"); goto _zeropagex;
case 0x76: strcpy(chr,"ROR"); goto _zeropagex;
case 0x94: strcpy(chr,"STY"); goto _zeropagex;
case 0x95: strcpy(chr,"STA"); goto _zeropagex;
case 0xB4: strcpy(chr,"LDY"); goto _zeropagex;
case 0xB5: strcpy(chr,"LDA"); goto _zeropagex;
case 0xD5: strcpy(chr,"CMP"); goto _zeropagex;
case 0xD6: strcpy(chr,"DEC"); goto _zeropagex;
case 0xF5: strcpy(chr,"SBC"); goto _zeropagex;
case 0xF6: strcpy(chr,"INC"); goto _zeropagex;
case 0x15: chr = "ORA"; goto _zeropagex;
case 0x16: chr = "ASL"; goto _zeropagex;
case 0x35: chr = "AND"; goto _zeropagex;
case 0x36: chr = "ROL"; goto _zeropagex;
case 0x55: chr = "EOR"; goto _zeropagex;
case 0x56: chr = "LSR"; goto _zeropagex;
case 0x75: chr = "ADC"; goto _zeropagex;
case 0x76: chr = "ROR"; goto _zeropagex;
case 0x94: chr = "STY"; goto _zeropagex;
case 0x95: chr = "STA"; goto _zeropagex;
case 0xB4: chr = "LDY"; goto _zeropagex;
case 0xB5: chr = "LDA"; goto _zeropagex;
case 0xD5: chr = "CMP"; goto _zeropagex;
case 0xD6: chr = "DEC"; goto _zeropagex;
case 0xF5: chr = "SBC"; goto _zeropagex;
case 0xF6: chr = "INC"; goto _zeropagex;
_zeropagex:
zpIndex(tmp,RX);
indReg = 'X';
_indexed:
// ################################## Start of SP CODE ###########################
// Change width to %04X // don't!
if ( symDebugEnable )
{
sym = replaceSymbols( flags, tmp, stmp );
showTrace
? sprintf(str,"%s $%02X,X @ %s = #$%02X", chr,opcode[1],stmp,GetMem(tmp))
: sprintf(str,"%s $%02X,X", chr,opcode[1]);
}
else
sb << chr << ' ' << sb_addr(opcode[1], 2) << ',' << indReg;
if (showTrace)
{
showTrace
? sprintf(str,"%s $%02X,X @ $%04X = #$%02X", chr,opcode[1],tmp,GetMem(tmp))
: sprintf(str,"%s $%02X,X", chr,opcode[1]);
sb << " @ ";
if (symDebugEnable)
sb << stmp;
else
sb << sb_addr(tmp);
sb << " = " << sb_lit(GetMem(tmp));
}
// ################################## End of SP CODE ###########################
break;
//Absolute,Y
case 0x19: strcpy(chr,"ORA"); goto _absolutey;
case 0x39: strcpy(chr,"AND"); goto _absolutey;
case 0x59: strcpy(chr,"EOR"); goto _absolutey;
case 0x79: strcpy(chr,"ADC"); goto _absolutey;
case 0x99: strcpy(chr,"STA"); goto _absolutey;
case 0xB9: strcpy(chr,"LDA"); goto _absolutey;
case 0xBE: strcpy(chr,"LDX"); goto _absolutey;
case 0xD9: strcpy(chr,"CMP"); goto _absolutey;
case 0xF9: strcpy(chr,"SBC"); goto _absolutey;
case 0x19: chr = "ORA"; goto _absolutey;
case 0x39: chr = "AND"; goto _absolutey;
case 0x59: chr = "EOR"; goto _absolutey;
case 0x79: chr = "ADC"; goto _absolutey;
case 0x99: chr = "STA"; goto _absolutey;
case 0xB9: chr = "LDA"; goto _absolutey;
case 0xBE: chr = "LDX"; goto _absolutey;
case 0xD9: chr = "CMP"; goto _absolutey;
case 0xF9: chr = "SBC"; goto _absolutey;
_absolutey:
absolute(tmp);
tmp2=(tmp+RY);
indReg = 'Y';
_absindexed:
sb << chr << ' ';
if ( symDebugEnable )
{
sym = replaceSymbols( flags, tmp , stmp );
sym2 = replaceSymbols( flags, tmp2, stmp2 );
showTrace
? sprintf(str,"%s %s,Y @ %s = #$%02X", chr,stmp,stmp2,GetMem(tmp2))
: sprintf(str,"%s %s,Y", chr,stmp);
sb << stmp;
}
else
sb << sb_addr(tmp);
sb << ',' << indReg;
if (showTrace)
{
showTrace
? sprintf(str,"%s $%04X,Y @ $%04X = #$%02X", chr,tmp,tmp2,GetMem(tmp2))
: sprintf(str,"%s $%04X,Y", chr,tmp);
sb << " @ ";
if (symDebugEnable)
sb << stmp2;
else
sb << sb_addr(tmp2);
sb << " = " << sb_lit(GetMem(tmp2));
}
break;
//Absolute,X
case 0x1D: strcpy(chr,"ORA"); goto _absolutex;
case 0x1E: strcpy(chr,"ASL"); goto _absolutex;
case 0x3D: strcpy(chr,"AND"); goto _absolutex;
case 0x3E: strcpy(chr,"ROL"); goto _absolutex;
case 0x5D: strcpy(chr,"EOR"); goto _absolutex;
case 0x5E: strcpy(chr,"LSR"); goto _absolutex;
case 0x7D: strcpy(chr,"ADC"); goto _absolutex;
case 0x7E: strcpy(chr,"ROR"); goto _absolutex;
case 0x9D: strcpy(chr,"STA"); goto _absolutex;
case 0xBC: strcpy(chr,"LDY"); goto _absolutex;
case 0xBD: strcpy(chr,"LDA"); goto _absolutex;
case 0xDD: strcpy(chr,"CMP"); goto _absolutex;
case 0xDE: strcpy(chr,"DEC"); goto _absolutex;
case 0xFD: strcpy(chr,"SBC"); goto _absolutex;
case 0xFE: strcpy(chr,"INC"); goto _absolutex;
case 0x1D: chr = "ORA"; goto _absolutex;
case 0x1E: chr = "ASL"; goto _absolutex;
case 0x3D: chr = "AND"; goto _absolutex;
case 0x3E: chr = "ROL"; goto _absolutex;
case 0x5D: chr = "EOR"; goto _absolutex;
case 0x5E: chr = "LSR"; goto _absolutex;
case 0x7D: chr = "ADC"; goto _absolutex;
case 0x7E: chr = "ROR"; goto _absolutex;
case 0x9D: chr = "STA"; goto _absolutex;
case 0xBC: chr = "LDY"; goto _absolutex;
case 0xBD: chr = "LDA"; goto _absolutex;
case 0xDD: chr = "CMP"; goto _absolutex;
case 0xDE: chr = "DEC"; goto _absolutex;
case 0xFD: chr = "SBC"; goto _absolutex;
case 0xFE: chr = "INC"; goto _absolutex;
_absolutex:
absolute(tmp);
tmp2=(tmp+RX);
if ( symDebugEnable )
{
sym = replaceSymbols( flags, tmp , stmp );
sym2 = replaceSymbols( flags, tmp2, stmp2 );
showTrace
? sprintf(str,"%s %s,X @ %s = #$%02X", chr,stmp,stmp2,GetMem(tmp2))
: sprintf(str,"%s %s,X", chr,stmp);
}
else
{
showTrace
? sprintf(str,"%s $%04X,X @ $%04X = #$%02X", chr,tmp,tmp2,GetMem(tmp2))
: sprintf(str,"%s $%04X,X", chr,tmp);
}
break;
indReg = 'X';
goto _absindexed;
//jumps
case 0x20: strcpy(chr,"JSR"); goto _jump;
case 0x4C: strcpy(chr,"JMP"); goto _jump;
case 0x6C: absolute(tmp); sprintf(str,"JMP ($%04X) = $%04X", tmp,GetMem(tmp)|GetMem(tmp+1)<<8); break;
case 0x20: chr = "JSR"; goto _jump;
case 0x4C: chr = "JMP"; goto _jump;
_jump:
absolute(tmp);
if ( symDebugEnable )
sb << chr << ' ';
if (symDebugEnable)
{
sym = replaceSymbols( flags, tmp, stmp );
sprintf(str,"%s %s", chr,stmp);
sym = replaceSymbols(flags, tmp, stmp);
sb << stmp;
}
else
{
sprintf(str,"%s $%04X", chr,tmp);
}
sb << sb_addr(tmp);
break;
case 0x6C:
absolute(tmp);
sb << "JMP (" << sb_addr(tmp);
sb << ") = " << sb_addr(GetMem(tmp) | GetMem(tmp + 1) << 8);
break;
//Zero Page,Y
case 0x96: strcpy(chr,"STX"); goto _zeropagey;
case 0xB6: strcpy(chr,"LDX"); goto _zeropagey;
case 0x96: chr = "STX"; goto _zeropagey;
case 0xB6: chr = "LDX"; goto _zeropagey;
_zeropagey:
zpIndex(tmp,RY);
// ################################## Start of SP CODE ###########################
// Change width to %04X // don't!
if ( symDebugEnable )
{
sym = replaceSymbols( flags, tmp, stmp );
showTrace
? sprintf(str,"%s $%02X,Y @ %s = #$%02X", chr,opcode[1],stmp,GetMem(tmp))
: sprintf(str,"%s $%02X,Y", chr,opcode[1]);
}
else
{
showTrace
? sprintf(str,"%s $%02X,Y @ $%04X = #$%02X", chr,opcode[1],tmp,GetMem(tmp))
: sprintf(str,"%s $%02X,Y", chr,opcode[1]);
}
// ################################## End of SP CODE ###########################
break;
indReg = 'Y';
goto _indexed;
//UNDEFINED
default: strcpy(str,"ERROR"); break;
@ -727,7 +711,7 @@ void SymbolEditWindow::setAddr( int addrIn )
addr = addrIn;
sprintf( stmp, "%04X", addr );
snprintf( stmp, sizeof(stmp), "%04X", addr );
addrEntry->setText( tr(stmp) );
@ -794,8 +778,8 @@ int SymbolEditWindow::exec(void)
FCEU_WRAPPER_LOCK();
if ( isArrayBox->isChecked() )
{
size = atoi( arraySize->text().toStdString().c_str() );
init = atoi( arrayInit->text().toStdString().c_str() );
size = atoi( arraySize->text().toLocal8Bit().constData() );
init = atoi( arrayInit->text().toLocal8Bit().constData() );
for (i=0; i<size; i++)
{
@ -847,7 +831,7 @@ int SymbolEditWindow::exec(void)
{
if ( isNew || arrayCommentOverWrite->isChecked() || (i == 0) )
{
sym->commentAssign( commentEntry->toPlainText().toStdString() );
sym->commentAssign( commentEntry->toPlainText().toLocal8Bit().constData() );
}
}
sym->trimTrailingSpaces();
@ -865,8 +849,8 @@ int SymbolEditWindow::exec(void)
}
else if ( sym == NULL )
{
sym = new debugSymbol_t( addr, nameEntry->text().toStdString().c_str(),
commentEntry->toPlainText().toStdString().c_str());
sym = new debugSymbol_t( addr, nameEntry->text().toLocal8Bit().constData(),
commentEntry->toPlainText().toLocal8Bit().constData());
if ( debugSymbolTable.addSymbolAtBankOffset( bank, addr, sym ) )
{
@ -879,14 +863,14 @@ int SymbolEditWindow::exec(void)
}
else
{
if ( sym->updateName( nameEntry->text().toStdString().c_str() ) )
if ( sym->updateName( nameEntry->text().toLocal8Bit().constData() ) )
{
if (consoleWindow)
{
consoleWindow->QueueErrorMsgWindow( debugSymbolTable.errorMessage() );
}
}
sym->commentAssign( commentEntry->toPlainText().toStdString().c_str() );
sym->commentAssign( commentEntry->toPlainText().toLocal8Bit().constData() );
sym->trimTrailingSpaces();
}
}
@ -906,7 +890,7 @@ void SymbolEditWindow::determineArrayStart(void)
{
return;
}
strcpy( stmp, nameEntry->text().toStdString().c_str() );
strcpy( stmp, nameEntry->text().toLocal8Bit().constData() );
// Find Current Array Braces
i=0;
@ -949,7 +933,7 @@ void SymbolEditWindow::determineArrayStart(void)
if ( (val >= 0) && (val < 256) )
{
sprintf( digits, "%02X", val );
snprintf( digits, sizeof(digits), "%02X", val );
arrayInit->setText( tr(digits) );
}
@ -967,7 +951,7 @@ void SymbolEditWindow::setSymNameWithArray(int idx)
{
return;
}
strcpy( stmp, nameEntry->text().toStdString().c_str() );
strcpy( stmp, nameEntry->text().toLocal8Bit().constData() );
// Remove Current Array Braces
i=0;

View File

@ -1301,7 +1301,7 @@ void TasEditorWindow::initHotKeys(void)
QKeySequence ks = Hotkeys[i].getKeySeq();
QShortcut *shortcut = Hotkeys[i].getShortcut();
//printf("HotKey: %i %s\n", i, ks.toString().toStdString().c_str() );
//printf("HotKey: %i %s\n", i, ks.toString().toLocal8Bit().constData() );
if ( hotkeyShortcut[i] == nullptr )
{
@ -1714,8 +1714,8 @@ bool TasEditorWindow::saveProjectAs(bool save_compact)
int ret;
std::string msg;
msg = "Pre-existing TAS project file will be overwritten:\n\n" +
fi.fileName().toStdString() + "\n\nReplace file?";
msg = "Pre-existing TAS project file will be overwritten:\n\n" +
std::string(fi.fileName().toLocal8Bit()) + "\n\nReplace file?";
ret = QMessageBox::warning( this, QObject::tr("Overwrite Warning"),
QString::fromStdString(msg), QMessageBox::Yes | QMessageBox::No, QMessageBox::No );
@ -1725,18 +1725,18 @@ bool TasEditorWindow::saveProjectAs(bool save_compact)
return false;
}
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
project.renameProject( filename.toStdString().c_str(), true);
project.renameProject( filename.toLocal8Bit().constData(), true);
if (save_compact)
{
project.save( filename.toStdString().c_str(), taseditorConfig.saveCompact_SaveInBinary, taseditorConfig.saveCompact_SaveMarkers, taseditorConfig.saveCompact_SaveBookmarks, taseditorConfig.saveCompact_GreenzoneSavingMode, taseditorConfig.saveCompact_SaveHistory, taseditorConfig.saveCompact_SavePianoRoll, taseditorConfig.saveCompact_SaveSelection);
project.save( filename.toLocal8Bit().constData(), taseditorConfig.saveCompact_SaveInBinary, taseditorConfig.saveCompact_SaveMarkers, taseditorConfig.saveCompact_SaveBookmarks, taseditorConfig.saveCompact_GreenzoneSavingMode, taseditorConfig.saveCompact_SaveHistory, taseditorConfig.saveCompact_SavePianoRoll, taseditorConfig.saveCompact_SaveSelection);
}
else
{
project.save( filename.toStdString().c_str(), taseditorConfig.projectSavingOptions_SaveInBinary, taseditorConfig.projectSavingOptions_SaveMarkers, taseditorConfig.projectSavingOptions_SaveBookmarks, taseditorConfig.projectSavingOptions_GreenzoneSavingMode, taseditorConfig.projectSavingOptions_SaveHistory, taseditorConfig.projectSavingOptions_SavePianoRoll, taseditorConfig.projectSavingOptions_SaveSelection);
project.save( filename.toLocal8Bit().constData(), taseditorConfig.projectSavingOptions_SaveInBinary, taseditorConfig.projectSavingOptions_SaveMarkers, taseditorConfig.projectSavingOptions_SaveBookmarks, taseditorConfig.projectSavingOptions_GreenzoneSavingMode, taseditorConfig.projectSavingOptions_SaveHistory, taseditorConfig.projectSavingOptions_SavePianoRoll, taseditorConfig.projectSavingOptions_SaveSelection);
}
addRecentProject( filename.toStdString().c_str() );
addRecentProject( filename.toLocal8Bit().constData() );
// saved successfully - remove * mark from caption
project.reset();
updateCaption();
@ -1852,9 +1852,9 @@ void TasEditorWindow::openProject(void)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
loadProject( filename.toStdString().c_str());
loadProject( filename.toLocal8Bit().constData());
return;
}
@ -2030,9 +2030,9 @@ void TasEditorWindow::importMovieFile( const char *path )
QFileInfo fi( path );
// loaded successfully, now register Input changes
//char drv[512], dir[512], name[1024], ext[512];
//splitpath(filename.toStdString().c_str(), drv, dir, name, ext);
//splitpath(filename.toLocal8Bit().constData(), drv, dir, name, ext);
//strcat(name, ext);
int result = history.registerImport(md, fi.fileName().toStdString().c_str() );
int result = history.registerImport(md, fi.fileName().toLocal8Bit().constData() );
if (result >= 0)
{
greenzone.invalidateAndUpdatePlayback(result);
@ -2135,11 +2135,11 @@ void TasEditorWindow::importMovieFile(void)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
importMovieFile( filename.toStdString().c_str() );
importMovieFile( filename.toLocal8Bit().constData() );
//EMUFILE_FILE ifs( filename.toStdString().c_str(), "rb");
//EMUFILE_FILE ifs( filename.toLocal8Bit().constData(), "rb");
//// Load Input to temporary moviedata
//MovieData md;
@ -2148,9 +2148,9 @@ void TasEditorWindow::importMovieFile(void)
// QFileInfo fi( filename );
// // loaded successfully, now register Input changes
// //char drv[512], dir[512], name[1024], ext[512];
// //splitpath(filename.toStdString().c_str(), drv, dir, name, ext);
// //splitpath(filename.toLocal8Bit().constData(), drv, dir, name, ext);
// //strcat(name, ext);
// int result = history.registerImport(md, fi.fileName().toStdString().c_str() );
// int result = history.registerImport(md, fi.fileName().toLocal8Bit().constData() );
// if (result >= 0)
// {
// greenzone.invalidateAndUpdatePlayback(result);
@ -2256,7 +2256,7 @@ void TasEditorWindow::exportMovieFile(void)
return;
}
EMUFILE* osRecordingMovie = FCEUD_UTF8_fstream( filename.toStdString().c_str(), "wb");
EMUFILE* osRecordingMovie = FCEUD_UTF8_fstream( filename.toLocal8Bit().constData(), "wb");
// create copy of current movie data
MovieData temp_md = currMovieData;
// modify the copy according to selected type of export
@ -2274,7 +2274,7 @@ void TasEditorWindow::exportMovieFile(void)
markerID = markersManager.getMarkerAtFrame(i);
if (markerID)
{
sprintf( framenum, "%i ", i );
snprintf( framenum, sizeof(framenum), "%i ", i );
//_itoa(i, framenum, 10);
//strcat(framenum, " ");
subtitle = framenum;
@ -2337,7 +2337,7 @@ void TasEditorWindow::buildRecentProjectMenu(void)
for (int i=0; i<10; i++)
{
sprintf(buf, "SDL.RecentTasProject%02i", i);
snprintf(buf, sizeof(buf), "SDL.RecentTasProject%02i", i);
g_config->getOption( buf, &s);
@ -2373,7 +2373,7 @@ void TasEditorWindow::saveRecentProjectMenu(void)
for (it=projList.begin(); it != projList.end(); it++)
{
s = *it;
sprintf(buf, "SDL.RecentTasProject%02i", i);
snprintf(buf, sizeof(buf), "SDL.RecentTasProject%02i", i);
g_config->setOption( buf, s->c_str() );
@ -2550,8 +2550,8 @@ bool TasEditorWindow::saveCompactGetFilename( QString &outputFilePath )
int ret;
std::string msg;
msg = "Pre-existing TAS project file will be overwritten:\n\n" +
fi.fileName().toStdString() + "\n\nReplace file?";
msg = "Pre-existing TAS project file will be overwritten:\n\n" +
std::string(fi.fileName().toLocal8Bit()) + "\n\nReplace file?";
ret = QMessageBox::warning( this, QObject::tr("Overwrite Warning"),
QString::fromStdString(msg), QMessageBox::Yes | QMessageBox::No, QMessageBox::No );
@ -2563,7 +2563,7 @@ bool TasEditorWindow::saveCompactGetFilename( QString &outputFilePath )
}
outputFilePath = filename;
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
return true;
}
@ -2683,7 +2683,7 @@ void TasEditorWindow::saveProjectCompactCb(void)
if ( saveCompactGetFilename( filename ) )
{
project.save(filename.toStdString().c_str(), taseditorConfig.saveCompact_SaveInBinary, taseditorConfig.saveCompact_SaveMarkers, taseditorConfig.saveCompact_SaveBookmarks, taseditorConfig.saveCompact_GreenzoneSavingMode, taseditorConfig.saveCompact_SaveHistory, taseditorConfig.saveCompact_SavePianoRoll, taseditorConfig.saveCompact_SaveSelection);
project.save(filename.toLocal8Bit().constData(), taseditorConfig.saveCompact_SaveInBinary, taseditorConfig.saveCompact_SaveMarkers, taseditorConfig.saveCompact_SaveBookmarks, taseditorConfig.saveCompact_GreenzoneSavingMode, taseditorConfig.saveCompact_SaveHistory, taseditorConfig.saveCompact_SavePianoRoll, taseditorConfig.saveCompact_SaveSelection);
}
}
}
@ -3113,9 +3113,9 @@ void TasEditorWindow::changePianoRollFontCB(void)
{
pianoRoll->setFont( selFont );
//printf("Font Changed to: '%s'\n", selFont.toString().toStdString().c_str() );
//printf("Font Changed to: '%s'\n", selFont.toString().toLocal8Bit().constData() );
g_config->setOption("SDL.TasPianoRollFont", selFont.toString().toStdString().c_str() );
g_config->setOption("SDL.TasPianoRollFont", selFont.toString().toLocal8Bit().constData() );
}
}
//----------------------------------------------------------------------------
@ -3129,9 +3129,9 @@ void TasEditorWindow::changeBookmarksFontCB(void)
{
bookmarks.setFont( selFont );
//printf("Font Changed to: '%s'\n", selFont.toString().toStdString().c_str() );
//printf("Font Changed to: '%s'\n", selFont.toString().toLocal8Bit().constData() );
g_config->setOption("SDL.TasBookmarksFont", selFont.toString().toStdString().c_str() );
g_config->setOption("SDL.TasBookmarksFont", selFont.toString().toLocal8Bit().constData() );
}
}
//----------------------------------------------------------------------------
@ -3145,9 +3145,9 @@ void TasEditorWindow::changeBranchesFontCB(void)
{
branches.setFont( selFont );
//printf("Font Changed to: '%s'\n", selFont.toString().toStdString().c_str() );
//printf("Font Changed to: '%s'\n", selFont.toString().toLocal8Bit().constData() );
g_config->setOption("SDL.TasBranchesFont", selFont.toString().toStdString().c_str() );
g_config->setOption("SDL.TasBranchesFont", selFont.toString().toLocal8Bit().constData() );
}
}
//----------------------------------------------------------------------------
@ -5256,7 +5256,7 @@ void QPianoRoll::dragEnterEvent(QDragEnterEvent *event)
QList<QUrl> urls = event->mimeData()->urls();
QFileInfo fi( urls[0].toString( QUrl::PreferLocalFile ) );
//printf("Suffix: '%s'\n", fi.suffix().toStdString().c_str() );
//printf("Suffix: '%s'\n", fi.suffix().toLocal8Bit().constData() );
if ( fi.suffix().compare("fm3") == 0)
{
@ -5287,14 +5287,14 @@ void QPianoRoll::dropEvent(QDropEvent *event)
if ( fi.suffix().compare("fm3") == 0 )
{
FCEU_WRAPPER_LOCK();
tasWin->loadProject( fi.filePath().toStdString().c_str() );
tasWin->loadProject( fi.filePath().toLocal8Bit().constData() );
FCEU_WRAPPER_UNLOCK();
event->accept();
}
else if ( fi.suffix().compare("fm2") == 0 )
{
FCEU_WRAPPER_LOCK();
tasWin->importMovieFile( fi.filePath().toStdString().c_str() );
tasWin->importMovieFile( fi.filePath().toLocal8Bit().constData() );
FCEU_WRAPPER_UNLOCK();
event->accept();
}
@ -6651,7 +6651,7 @@ void QPianoRoll::paintEvent(QPaintEvent *event)
//rect = QRect( -pxLineXScroll + pxFrameColX, y, pxWidthFrameCol, pxLineSpacing );
sprintf( stmp, "%07i", lineNum );
snprintf( stmp, sizeof(stmp), "%07i", lineNum );
rect = painter.fontMetrics().boundingRect( tr(stmp) );
@ -7228,7 +7228,7 @@ void TasFindNoteWindow::findNextClicked(void)
{
return;
}
strncpy( markersManager->findNoteString, searchPattern->text().toStdString().c_str(), MAX_NOTE_LEN-1 );
strncpy( markersManager->findNoteString, searchPattern->text().toLocal8Bit().constData(), MAX_NOTE_LEN-1 );
markersManager->findNoteString[MAX_NOTE_LEN-1] = 0;
// scan frames from current Selection to the border
@ -7306,7 +7306,7 @@ TasRecentProjectAction::TasRecentProjectAction(QString desc, QWidget *parent)
QString txt;
QFileInfo fi(desc);
path = desc.toStdString();
path = desc.toLocal8Bit().constData();
txt = fi.fileName();
txt += QString("\t");
@ -7492,7 +7492,7 @@ void markerDragPopup::paintEvent(QPaintEvent *event)
w = event->rect().width();
h = event->rect().height();
sprintf( txt, "%07i", rowIndex );
snprintf( txt, sizeof(txt), "%07i", rowIndex );
//painter.setFont(font);
//I want to make the title bar pasted on the content

View File

@ -658,7 +658,7 @@ void BOOKMARKS::paintEvent(QPaintEvent *event)
}
x = pxStartCol1 + pxCharWidth;
sprintf( txt, "%i", item );
snprintf( txt, sizeof(txt), "%i", item );
painter.drawText( x, y+pxLineTextOfs, tr(txt) );

View File

@ -1023,11 +1023,11 @@ void BRANCHES::paintEvent(QPaintEvent *event)
char framenum_string[16] = {0};
if (bookmarks->itemUnderMouse < TOTAL_BOOKMARKS)
{
sprintf( framenum_string, "%07i", bookmarks->bookmarksArray[bookmarks->itemUnderMouse].snapshot.keyFrame );
snprintf( framenum_string, sizeof(framenum_string), "%07i", bookmarks->bookmarksArray[bookmarks->itemUnderMouse].snapshot.keyFrame );
}
else
{
sprintf( framenum_string, "%07i", currFrameCounter );
snprintf( framenum_string, sizeof(framenum_string), "%07i", currFrameCounter );
}
x = viewRect.x() + (2 * pxBoxWidth);
y = pxLineSpacing;

View File

@ -522,7 +522,7 @@ int HISTORY::registerChanges(int mod_type, int start, int end, int size, const c
if (mod_type == MODTYPE_INSERTNUM)
{
snap.endFrame = start + size - 1;
sprintf( framenum, "%i", size);
snprintf( framenum, sizeof(framenum), "%i", size);
strcat(snap.description, framenum);
} else
{
@ -540,12 +540,12 @@ int HISTORY::registerChanges(int mod_type, int start, int end, int size, const c
snap.endFrame = snapshots[real_pos].endFrame;
// add upper and lower frame to description
strcat(snap.description, " ");
sprintf( framenum, "%i", snap.startFrame);
snprintf( framenum, sizeof(framenum), "%i", snap.startFrame);
strcat(snap.description, framenum);
if (snap.endFrame > snap.startFrame)
{
strcat(snap.description, "-");
sprintf( framenum, "%i", snap.endFrame);
snprintf( framenum, sizeof(framenum), "%i", snap.endFrame);
strcat(snap.description, framenum);
}
// add comment if there is one specified
@ -570,12 +570,12 @@ int HISTORY::registerChanges(int mod_type, int start, int end, int size, const c
// don't combine
// add upper and lower frame to description
strcat(snap.description, " ");
sprintf( framenum, "%i", snap.startFrame);
snprintf( framenum, sizeof(framenum), "%i", snap.startFrame);
strcat(snap.description, framenum);
if (snap.endFrame > snap.startFrame)
{
strcat(snap.description, "-");
sprintf( framenum, "%i", snap.endFrame);
snprintf( framenum, sizeof(framenum), "%i", snap.endFrame);
strcat(snap.description, framenum);
}
// add comment if there is one specified
@ -681,7 +681,7 @@ void HISTORY::registerMarkersChange(int modificationType, int start, int end, co
// add the frame to description
char framenum[16];
strcat(snap.description, " ");
sprintf( framenum, "%i", snap.startFrame);
snprintf( framenum, sizeof(framenum), "%i", snap.startFrame);
strcat(snap.description, framenum);
if (snap.endFrame > snap.startFrame || modificationType == MODTYPE_MARKER_DRAG || modificationType == MODTYPE_MARKER_SWAP)
{
@ -691,7 +691,7 @@ void HISTORY::registerMarkersChange(int modificationType, int start, int end, co
strcat(snap.description, "<->");
else
strcat(snap.description, "-");
sprintf( framenum, "%i", snap.endFrame);
snprintf( framenum, sizeof(framenum), "%i", snap.endFrame);
strcat(snap.description, framenum);
}
// add comment if there is one specified
@ -718,7 +718,7 @@ void HISTORY::registerBookmarkSet(int slot, BOOKMARK& backupCopy, int oldCurrent
snap.startFrame = snap.endFrame = snap.keyFrame = bookmarks->bookmarksArray[slot].snapshot.keyFrame;
char framenum[16];
strcat(snap.description, " ");
sprintf( framenum, "%i", snap.keyFrame);
snprintf( framenum, sizeof(framenum), "%i", snap.keyFrame);
strcat(snap.description, framenum);
if (taseditorConfig->enableHotChanges)
snap.inputlog.copyHotChanges(&getCurrentSnapshot().inputlog);
@ -823,10 +823,10 @@ void HISTORY::registerRecording(int frameOfChange, uint32 joypadDifferenceBits)
}
// add upper and lower frame to description
strcat(snap->description, " ");
sprintf( framenum, "%i", snap->startFrame);
snprintf( framenum, sizeof(framenum), "%i", snap->startFrame);
strcat(snap->description, framenum);
strcat(snap->description, "-");
sprintf( framenum, "%i", snap->endFrame);
snprintf( framenum, sizeof(framenum), "%i", snap->endFrame);
strcat(snap->description, framenum);
// truncate history here
historyTotalItems = historyCursorPos+1;
@ -860,7 +860,7 @@ void HISTORY::registerRecording(int frameOfChange, uint32 joypadDifferenceBits)
}
// add upper frame to description
strcat(snap.description, " ");
sprintf( framenum, "%i", frameOfChange);
snprintf( framenum, sizeof(framenum), "%i", frameOfChange);
strcat(snap.description, framenum);
// set hotchanges
if (taseditorConfig->enableHotChanges)
@ -942,7 +942,7 @@ int HISTORY::registerLuaChanges(const char* name, int start, bool insertionOrDel
// add upper frame to description
char framenum[16];
strcat(snap.description, " ");
sprintf( framenum, "%i", first_changes);
snprintf( framenum, sizeof(framenum), "%i", first_changes);
strcat(snap.description, framenum);
// set hotchanges
if (taseditorConfig->enableHotChanges)

View File

@ -390,7 +390,7 @@ void MARKERS_MANAGER::updateEditedMarkerNote()
{
len = MAX_NOTE_LEN-1;
}
strncpy( new_text, tasWin->upperMarkerNote->text().toStdString().c_str(), MAX_NOTE_LEN-1 );
strncpy( new_text, tasWin->upperMarkerNote->text().toLocal8Bit().constData(), MAX_NOTE_LEN-1 );
new_text[len] = 0;
// check changes
if (strcmp(getNoteCopy(playback->displayedMarkerNumber).c_str(), new_text))
@ -416,7 +416,7 @@ void MARKERS_MANAGER::updateEditedMarkerNote()
{
len = MAX_NOTE_LEN-1;
}
strncpy( new_text, tasWin->lowerMarkerNote->text().toStdString().c_str(), MAX_NOTE_LEN-1 );
strncpy( new_text, tasWin->lowerMarkerNote->text().toLocal8Bit().constData(), MAX_NOTE_LEN-1 );
new_text[len] = 0;
// check changes

View File

@ -447,7 +447,7 @@ void PLAYBACK::redrawMarkerData()
strcpy(new_text, upperMarkerText);
}
char num[16];
sprintf( num, "%i", displayedMarkerNumber);
snprintf( num, sizeof(num), "%i", displayedMarkerNumber);
strcat(new_text, num);
strcat(new_text, " ");
tasWin->upperMarkerLabel->setText( QObject::tr(new_text) );

View File

@ -193,7 +193,7 @@ void SELECTION::redrawMarkerData()
strcpy(new_text, lowerMarkerText);
}
char num[16];
sprintf( num, "%i", displayedMarkerNumber);
snprintf( num, sizeof(num), "%i", displayedMarkerNumber);
strcat(new_text, num);
strcat(new_text, " ");
tasWin->lowerMarkerLabel->setText( QObject::tr(new_text) );

View File

@ -73,7 +73,7 @@ void SPLICER::update(void)
// rows
if (size > 1)
{
sprintf( num, "%i", size);
snprintf( num, sizeof(num), "%i", size);
strcat(new_text, num);
strcat(new_text, numTextRows);
}
@ -85,7 +85,7 @@ void SPLICER::update(void)
int columns = NUM_JOYPAD_BUTTONS * joysticksPerFrame[getInputType(currMovieData)]; // in future the number of columns will depend on selected columns
if (columns > 1)
{
sprintf( num, "%i", columns);
snprintf( num, sizeof(num), "%i", columns);
strcat(new_text, num);
strcat(new_text, numTextColumns);
}
@ -497,7 +497,7 @@ bool SPLICER::pasteInputFromClipboard()
int num_joypads = joysticksPerFrame[getInputType(currMovieData)];
int pos = *(current_selection->begin());
std::string stmp = tasWin->clipboard->text().toStdString();
std::string stmp = tasWin->clipboard->text().toLocal8Bit().constData();
const char *pGlobal = stmp.c_str();
// TAS recording info starts with "TAS "
@ -622,7 +622,7 @@ bool SPLICER::pasteInsertInputFromClipboard(void)
int num_joypads = joysticksPerFrame[getInputType(currMovieData)];
bool markers_changed = false;
int pos = *current_selection_begin;
std::string stmp = tasWin->clipboard->text().toStdString();
std::string stmp = tasWin->clipboard->text().toLocal8Bit().constData();
const char *pGlobal = stmp.c_str();
// TAS recording info starts with "TAS "
@ -743,7 +743,7 @@ void SPLICER::checkClipboardContents(void)
// check if clipboard contains TAS Editor Input data
clipboardSelection.clear();
int current_pos = -1;
std::string stmp = tasWin->clipboard->text().toStdString();
std::string stmp = tasWin->clipboard->text().toLocal8Bit().constData();
const char *pGlobal = stmp.c_str();
// TAS recording info starts with "TAS "
if (pGlobal[0]=='T' && pGlobal[1]=='A' && pGlobal[2]=='S')
@ -787,7 +787,7 @@ void SPLICER::redrawInfoAboutClipboard(void)
// rows
if (clipboardSelection.size() > 1)
{
sprintf( num, "%zi", clipboardSelection.size());
snprintf( num, sizeof(num), "%zi", clipboardSelection.size());
strcat(new_text, num);
strcat(new_text, numTextRows);
}
@ -799,7 +799,7 @@ void SPLICER::redrawInfoAboutClipboard(void)
int columns = NUM_JOYPAD_BUTTONS * joysticksPerFrame[getInputType(currMovieData)]; // in future the number of columns will depend on selected columns
if (columns > 1)
{
sprintf( num, "%i", columns);
snprintf( num, sizeof(num), "%i", columns);
strcat(new_text, num);
strcat(new_text, numTextColumns);
}

View File

@ -279,10 +279,10 @@ bool TASEDITOR_PROJECT::load(const char* fullName)
message.assign("This project was saved using different version of TAS Editor!\n\n");
message.append("Original version: ");
char versionNum[16];
sprintf( versionNum, "%u", projectFileVersion);
snprintf( versionNum, sizeof(versionNum), "%u", projectFileVersion);
message.append(versionNum);
message.append("\nCurrent version: ");
sprintf( versionNum, "%i", PROJECT_FILE_CURRENT_VERSION);
snprintf( versionNum, sizeof(versionNum), "%i", PROJECT_FILE_CURRENT_VERSION);
message.append(versionNum);
message.append("\n\nClick Yes to try loading all data from the file (may crash).\n");
message.append("Click No to only load movie data.\n");

View File

@ -329,6 +329,20 @@ void TimingConfDialog_t::saveValues(void)
#endif
}
//----------------------------------------------------------------------------
QString TimingConfDialog_t::getSchedPrioErrorMsg(const char* funcName, int errorCode)
{
QString msg = QString("Error: system call setPriority Failed\nReason: ") + QString(strerror(errorCode)) + QString("\n");
#ifdef __linux__
msg += "Ensure that your system has the proper resource permissions set in the file:\n\n";
msg += " /etc/security/limits.conf \n\n";
msg += "Adding the following lines to that file and rebooting will usually fix the issue:\n\n";
msg += "* - priority 99 \n";
msg += "* - rtprio 99 \n";
msg += "* - nice -20 \n";
#endif
return msg;
}
//----------------------------------------------------------------------------
void TimingConfDialog_t::emuSchedNiceChange(int val)
{
#ifndef WIN32
@ -339,19 +353,9 @@ void TimingConfDialog_t::emuSchedNiceChange(int val)
FCEU_WRAPPER_LOCK();
if (consoleWindow->emulatorThread->setNicePriority(-val))
{
char msg[1024];
sprintf(msg, "Error: system call setPriority Failed\nReason: %s\n", strerror(errno));
#ifdef __linux__
strcat(msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
strcat(msg, " /etc/security/limits.conf \n\n");
strcat(msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
strcat(msg, "* - priority 99 \n");
strcat(msg, "* - rtprio 99 \n");
strcat(msg, "* - nice -20 \n");
#endif
printf("%s\n", msg);
consoleWindow->QueueErrorMsgWindow(msg);
QString msg = getSchedPrioErrorMsg("setPriority", errno);
printf("%s\n", msg.toLocal8Bit().constData());
consoleWindow->QueueErrorMsgWindow(msg.toLocal8Bit().constData());
updateSliderValues();
}
FCEU_WRAPPER_UNLOCK();
@ -377,19 +381,9 @@ void TimingConfDialog_t::emuSchedPrioChange(int val)
if (consoleWindow->emulatorThread->setSchedParam(policy, val))
{
char msg[1024];
sprintf(msg, "Error: system call pthread_setschedparam Failed\nReason: %s\n", strerror(errno));
#ifdef __linux__
strcat(msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
strcat(msg, " /etc/security/limits.conf \n\n");
strcat(msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
strcat(msg, "* - priority 99 \n");
strcat(msg, "* - rtprio 99 \n");
strcat(msg, "* - nice -20 \n");
#endif
printf("%s\n", msg);
consoleWindow->QueueErrorMsgWindow(msg);
QString msg = getSchedPrioErrorMsg("pthread_setschedparam", errno);
printf("%s\n", msg.toLocal8Bit().constData());
consoleWindow->QueueErrorMsgWindow(msg.toLocal8Bit().constData());
updateSliderValues();
}
FCEU_WRAPPER_UNLOCK();
@ -412,19 +406,9 @@ void TimingConfDialog_t::emuSchedPolicyChange(int index)
if (consoleWindow->emulatorThread->setSchedParam(policy, prio))
{
char msg[1024];
sprintf(msg, "Error: system call pthread_setschedparam Failed\nReason: %s\n", strerror(errno));
#ifdef __linux__
strcat(msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
strcat(msg, " /etc/security/limits.conf \n\n");
strcat(msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
strcat(msg, "* - priority 99 \n");
strcat(msg, "* - rtprio 99 \n");
strcat(msg, "* - nice -20 \n");
#endif
printf("%s\n", msg);
consoleWindow->QueueErrorMsgWindow(msg);
QString msg = getSchedPrioErrorMsg("pthread_setschedparam", errno);
printf("%s\n", msg.toLocal8Bit().constData());
consoleWindow->QueueErrorMsgWindow(msg.toLocal8Bit().constData());
}
updatePolicyBox();
@ -444,19 +428,9 @@ void TimingConfDialog_t::guiSchedNiceChange(int val)
FCEU_WRAPPER_LOCK();
if (consoleWindow->setNicePriority(-val))
{
char msg[1024];
sprintf(msg, "Error: system call setPriority Failed\nReason: %s\n", strerror(errno));
#ifdef __linux__
strcat(msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
strcat(msg, " /etc/security/limits.conf \n\n");
strcat(msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
strcat(msg, "* - priority 99 \n");
strcat(msg, "* - rtprio 99 \n");
strcat(msg, "* - nice -20 \n");
#endif
printf("%s\n", msg);
consoleWindow->QueueErrorMsgWindow(msg);
QString msg = getSchedPrioErrorMsg("setPriority", errno);
printf("%s\n", msg.toLocal8Bit().constData());
consoleWindow->QueueErrorMsgWindow(msg.toLocal8Bit().constData());
updateSliderValues();
}
FCEU_WRAPPER_UNLOCK();
@ -480,19 +454,9 @@ void TimingConfDialog_t::guiSchedPrioChange(int val)
if (consoleWindow->setSchedParam(policy, val))
{
char msg[1024];
sprintf(msg, "Error: system call pthread_setschedparam Failed\nReason: %s\n", strerror(errno));
#ifdef __linux__
strcat(msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
strcat(msg, " /etc/security/limits.conf \n\n");
strcat(msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
strcat(msg, "* - priority 99 \n");
strcat(msg, "* - rtprio 99 \n");
strcat(msg, "* - nice -20 \n");
#endif
printf("%s\n", msg);
consoleWindow->QueueErrorMsgWindow(msg);
QString msg = getSchedPrioErrorMsg("pthread_setschedparam", errno);
printf("%s\n", msg.toLocal8Bit().constData());
consoleWindow->QueueErrorMsgWindow(msg.toLocal8Bit().constData());
updateSliderValues();
}
FCEU_WRAPPER_UNLOCK();
@ -515,19 +479,9 @@ void TimingConfDialog_t::guiSchedPolicyChange(int index)
if (consoleWindow->setSchedParam(policy, prio))
{
char msg[1024];
sprintf(msg, "Error: system call pthread_setschedparam Failed\nReason: %s\n", strerror(errno));
#ifdef __linux__
strcat(msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
strcat(msg, " /etc/security/limits.conf \n\n");
strcat(msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
strcat(msg, "* - priority 99 \n");
strcat(msg, "* - rtprio 99 \n");
strcat(msg, "* - nice -20 \n");
#endif
printf("%s\n", msg);
consoleWindow->QueueErrorMsgWindow(msg);
QString msg = getSchedPrioErrorMsg("pthread_setschedparam", errno);
printf("%s\n", msg.toLocal8Bit().constData());
consoleWindow->QueueErrorMsgWindow(msg.toLocal8Bit().constData());
}
updatePolicyBox();

View File

@ -63,6 +63,7 @@ private:
void updateTimingMech(void);
void updateOverclocking(void);
void saveValues(void);
QString getSchedPrioErrorMsg(const char* funcName, int errorCode);
public slots:
void closeWindow(void);

View File

@ -25,6 +25,7 @@
#ifdef WIN32
#include <windows.h>
#include "../win/TraceFileWriter.h"
#else
#include <unistd.h>
#include <sys/types.h>
@ -56,7 +57,9 @@
#include "../../movie.h"
#include "common/os_utils.h"
#include "utils/StringBuilder.h"
#include "Qt/NetPlay.h"
#include "Qt/ConsoleDebugger.h"
#include "Qt/ConsoleWindow.h"
#include "Qt/ConsoleUtilities.h"
@ -128,6 +131,7 @@ static HANDLE logFile = INVALID_HANDLE_VALUE;
static int logFile = -1;
#endif
static std::string logFilePath;
static void* traceRegistrationHandle = nullptr;
//----------------------------------------------------
static void initLogOption( const char *name, int bitmask )
{
@ -521,6 +525,16 @@ void TraceLoggerDialog_t::toggleLoggingOnOff(void)
diskThread->quit();
diskThread->wait(1000);
FCEU_WRAPPER_LOCK();
if (traceRegistrationHandle != nullptr)
{
if ( !FCEUI_TraceInstructionUnregisterHandle( traceRegistrationHandle ) )
{
printf("Unregister Trace Callback Error\n");
}
traceRegistrationHandle = nullptr;
}
FCEU_WRAPPER_UNLOCK();
traceView->update();
}
else
@ -537,7 +551,14 @@ void TraceLoggerDialog_t::toggleLoggingOnOff(void)
pushMsgToLogBuffer("Log Start");
startStopButton->setText(tr("Stop Logging"));
startStopButton->setIcon( style()->standardIcon( QStyle::SP_MediaStop ) );
FCEU_WRAPPER_LOCK();
if (traceRegistrationHandle == nullptr)
{
traceRegistrationHandle = FCEUI_TraceInstructionRegister( FCEUD_TraceInstruction );
}
logging = 1;
FCEU_WRAPPER_UNLOCK();
}
}
//----------------------------------------------------
@ -612,9 +633,9 @@ void TraceLoggerDialog_t::openLogFile(void)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
logFilePath = filename.toStdString();
logFilePath = filename.toLocal8Bit().constData();
g_config->setOption("SDL.TraceLogSaveFilePath", logFilePath);
@ -914,38 +935,17 @@ traceRecord_t::traceRecord_t(void)
//----------------------------------------------------
int traceRecord_t::appendAsmText(const char *txt)
{
int i = 0;
size_t len = strlen(txt);
memcpy(asmTxt + asmTxtSize, txt, len + 1);
while (txt[i] != 0)
{
asmTxt[asmTxtSize] = txt[i];
i++;
asmTxtSize++;
}
asmTxt[asmTxtSize] = 0;
asmTxtSize += len;
return 0;
}
//----------------------------------------------------
static int convToXchar(int i)
{
int c = 0;
if ((i >= 0) && (i < 10))
{
c = i + '0';
}
else if (i < 16)
{
c = (i - 10) + 'A';
}
return c;
}
//----------------------------------------------------
int traceRecord_t::convToText(char *txt, int *len)
{
int i = 0, j = 0;
char stmp[128];
char str_axystate[32], str_procstatus[32];
str_axystate[0] = 0;
@ -954,112 +954,56 @@ int traceRecord_t::convToText(char *txt, int *len)
txt[0] = 0;
if (opSize == 0)
{
j = 0;
while (asmTxt[j] != 0)
{
txt[i] = asmTxt[j];
i++;
j++;
}
txt[i] = 0;
strcpy(txt, asmTxt);
return -1;
}
StringBuilder sb(txt + i);
if (skippedLines > 0)
{
sprintf(stmp, "(%d lines skipped) ", skippedLines);
j = 0;
while (stmp[j] != 0)
{
txt[i] = stmp[j];
i++;
j++;
}
}
sb << '(' << sb_dec(skippedLines) << " lines skipped) ";
// Start filling the str_temp line: Frame count, Cycles count, Instructions count, AXYS state, Processor status, Tabs, Address, Data, Disassembly
if (logging_options & LOG_FRAMES_COUNT)
{
sprintf(stmp, "f%-6llu ", (long long unsigned int)frameCount);
j = 0;
while (stmp[j] != 0)
{
txt[i] = stmp[j];
i++;
j++;
}
}
sb << 'f' << sb_dec(frameCount, -6);
if (logging_options & LOG_CYCLES_COUNT)
{
sprintf(stmp, "c%-11llu ", (long long unsigned int)cycleCount);
j = 0;
while (stmp[j] != 0)
{
txt[i] = stmp[j];
i++;
j++;
}
}
sb << 'c' << sb_dec(cycleCount, -11);
if (logging_options & LOG_INSTRUCTIONS_COUNT)
{
sprintf(stmp, "i%-11llu ", (long long unsigned int)instrCount);
j = 0;
while (stmp[j] != 0)
{
txt[i] = stmp[j];
i++;
j++;
}
}
sb << 'i' << sb_dec(instrCount, -11);
if (logging_options & LOG_REGISTERS)
{
sprintf(str_axystate, "A:%02X X:%02X Y:%02X S:%02X ", (cpu.A), (cpu.X), (cpu.Y), (cpu.S));
StringBuilder sb(str_axystate);
sb << "A:" << sb_hex(cpu.A, 2)
<< " X:" << sb_hex(cpu.X, 2)
<< " Y:" << sb_hex(cpu.Y, 2)
<< " S:" << sb_hex(cpu.S, 2)
<< ' ';
}
if (logging_options & LOG_PROCESSOR_STATUS)
{
int tmp = cpu.P ^ 0xFF;
sprintf(str_procstatus, "P:%c%c%c%c%c%c%c%c ",
'N' | (tmp & 0x80) >> 2,
'V' | (tmp & 0x40) >> 1,
'U' | (tmp & 0x20),
'B' | (tmp & 0x10) << 1,
'D' | (tmp & 0x08) << 2,
'I' | (tmp & 0x04) << 3,
'Z' | (tmp & 0x02) << 4,
'C' | (tmp & 0x01) << 5);
char *s = str_procstatus;
*(s++) = cpu.P & 0x80 ? 'N' : 'n';
*(s++) = cpu.P & 0x40 ? 'V' : 'v';
*(s++) = cpu.P & 0x20 ? 'U' : 'u';
*(s++) = cpu.P & 0x10 ? 'B' : 'b';
*(s++) = cpu.P & 0x08 ? 'D' : 'd';
*(s++) = cpu.P & 0x04 ? 'I' : 'i';
*(s++) = cpu.P & 0x02 ? 'Z' : 'z';
*(s++) = cpu.P & 0x01 ? 'C' : 'c';
*(s++) = ' ';
*(s++) = '\0';
}
if (logging_options & LOG_TO_THE_LEFT)
{
if (logging_options & LOG_REGISTERS)
{
j = 0;
while (str_axystate[j] != 0)
{
txt[i] = str_axystate[j];
i++;
j++;
}
}
sb << str_axystate;
if (logging_options & LOG_PROCESSOR_STATUS)
{
j = 0;
while (str_procstatus[j] != 0)
{
txt[i] = str_procstatus[j];
i++;
j++;
}
}
sb << str_procstatus;
}
if (logging_options & LOG_CODE_TABBING)
@ -1067,106 +1011,44 @@ int traceRecord_t::convToText(char *txt, int *len)
// add spaces at the beginning of the line according to stack pointer
int spaces = (0xFF - cpu.S) & LOG_TABS_MASK;
while (spaces > 0)
{
txt[i] = ' ';
i++;
spaces--;
}
for (; spaces > 0; spaces--)
sb << ' ';
}
else if (logging_options & LOG_TO_THE_LEFT)
{
txt[i] = ' ';
i++;
}
sb << ' ';
if (logging_options & LOG_BANK_NUMBER)
{
if (cpu.PC >= 0x8000)
{
sprintf(stmp, "$%02X:%04X: ", bank, cpu.PC);
}
sb << sb_addr((uint8_t)bank, 2) << ':';
else
{
sprintf(stmp, " $%04X: ", cpu.PC);
}
sb << " $";
}
else
{
sprintf(stmp, "$%04X: ", cpu.PC);
}
j = 0;
while (stmp[j] != 0)
{
txt[i] = stmp[j];
i++;
j++;
}
sb << '$';
sb << sb_hex(cpu.PC, 4) << ": ";
for (j = 0; j < opSize; j++)
{
txt[i] = convToXchar((opCode[j] >> 4) & 0x0F);
i++;
txt[i] = convToXchar(opCode[j] & 0x0F);
i++;
txt[i] = ' ';
i++;
}
while (j < 3)
{
txt[i] = ' ';
i++;
txt[i] = ' ';
i++;
txt[i] = ' ';
i++;
j++;
}
j = 0;
while (asmTxt[j] != 0)
{
txt[i] = asmTxt[j];
i++;
j++;
}
if (callAddr >= 0)
{
sprintf(stmp, " (from $%04X)", callAddr);
sb << sb_hex(opCode[j], 2) << ' ';
for (; j < 3; j++)
sb << " ";
j = 0;
while (stmp[j] != 0)
{
txt[i] = stmp[j];
i++;
j++;
}
}
sb << asmTxt;
if (callAddr >= 0)
sb << " (from " << sb_addr((uint16_t)callAddr) << ')';
if (!(logging_options & LOG_TO_THE_LEFT))
{
if (logging_options & LOG_REGISTERS)
{
j = 0;
while (str_axystate[j] != 0)
{
txt[i] = str_axystate[j];
i++;
j++;
}
}
sb << str_axystate;
if (logging_options & LOG_PROCESSOR_STATUS)
{
j = 0;
while (str_procstatus[j] != 0)
{
txt[i] = str_procstatus[j];
i++;
j++;
}
}
sb << str_procstatus;
}
txt[i] = 0;
i = int(sb.str() + sb.size() - txt);
txt[i] = '\0';
if (len)
{
@ -1249,12 +1131,15 @@ static void pushToLogBuffer(traceRecord_t &rec)
break;
}
}
bool overrun = nextHead == logBufTail;
logBufHead = nextHead;
if ( overrunWarningArmed )
{ // Don't spam with buffer overrun warning messages,
// we will print once if this happens.
if (logBufHead == logBufTail)
if (overrun)
{
if ( traceLogWindow )
{
@ -1286,7 +1171,13 @@ int FCEUD_TraceLoggerStart(void)
{
initTraceLogBuffer(1000000);
}
FCEU_WRAPPER_LOCK();
if (traceRegistrationHandle == nullptr)
{
traceRegistrationHandle = FCEUI_TraceInstructionRegister( FCEUD_TraceInstruction );
}
logging = 1;
FCEU_WRAPPER_UNLOCK();
}
return logging;
}
@ -1307,6 +1198,17 @@ int FCEUD_TraceLoggerStop(void)
msleep(1);
pushMsgToLogBuffer("Logging Finished");
}
FCEU_WRAPPER_LOCK();
if (traceRegistrationHandle != nullptr)
{
if ( !FCEUI_TraceInstructionUnregisterHandle( traceRegistrationHandle ) )
{
printf("Unregister Trace Callback Error\n");
}
traceRegistrationHandle = nullptr;
}
FCEU_WRAPPER_UNLOCK();
return logging;
}
//----------------------------------------------------
@ -1322,9 +1224,13 @@ void FCEUD_FlushTrace()
}
//----------------------------------------------------
//todo: really speed this up
void FCEUD_TraceInstruction(uint8 *opcode, int size)
{
if (NetPlayActive())
{
NetPlayTraceInstruction(opcode, size);
}
if (!logging)
return;
@ -1378,7 +1284,7 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
olddatacount = datacount;
if (unloggedlines > 0)
{
//sprintf(str_result, "(%d lines skipped)", unloggedlines);
//snprintf(str_result, "(%d lines skipped)", unloggedlines);
rec.skippedLines = unloggedlines;
unloggedlines = 0;
}
@ -1399,8 +1305,8 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
if ((addr + size) > 0xFFFF)
{
//sprintf(str_data, "%02X ", opcode[0]);
//sprintf(str_disassembly, "OVERFLOW");
//snprintf(str_data, "%02X ", opcode[0]);
//snprintf(str_disassembly, "OVERFLOW");
rec.flags |= 0x01;
}
else
@ -1409,7 +1315,7 @@ void FCEUD_TraceInstruction(uint8 *opcode, int size)
switch (size)
{
case 0:
//sprintf(str_disassembly,"UNDEFINED");
//snprintf(str_disassembly,"UNDEFINED");
rec.flags |= 0x02;
break;
case 1:
@ -2046,13 +1952,13 @@ void QTraceLogView::openBpEditWindow(int editIdx, watchpointinfo *wp, traceRecor
sprite_radio->setChecked(true);
}
sprintf(stmp, "%04X", wp->address);
snprintf(stmp, sizeof(stmp), "%04X", wp->address);
addr1->setText(tr(stmp));
if (wp->endaddress > 0)
{
sprintf(stmp, "%04X", wp->endaddress);
snprintf(stmp, sizeof(stmp), "%04X", wp->endaddress);
addr2->setText(tr(stmp));
}
@ -2092,11 +1998,11 @@ void QTraceLogView::openBpEditWindow(int editIdx, watchpointinfo *wp, traceRecor
char str[64];
if ((wp->address == recp->cpu.PC) && (recp->bank >= 0))
{
sprintf(str, "K==#%02X", recp->bank);
snprintf(str, sizeof(str), "K==#%02X", recp->bank);
}
else
{
sprintf(str, "K==#%02X", getBank(wp->address));
snprintf(str, sizeof(str), "K==#%02X", getBank(wp->address));
}
cond->setText(tr(str));
}
@ -2133,14 +2039,14 @@ void QTraceLogView::openBpEditWindow(int editIdx, watchpointinfo *wp, traceRecor
type |= BT_S;
}
s = addr1->text().toStdString();
s = addr1->text().toLocal8Bit().constData();
if (s.size() > 0)
{
start_addr = offsetStringToInt(type, s.c_str());
}
s = addr2->text().toStdString();
s = addr2->text().toLocal8Bit().constData();
if (s.size() > 0)
{
@ -2172,8 +2078,8 @@ void QTraceLogView::openBpEditWindow(int editIdx, watchpointinfo *wp, traceRecor
unsigned int retval;
std::string nameString, condString;
nameString = name->text().toStdString();
condString = cond->text().toStdString();
nameString = name->text().toLocal8Bit().constData();
condString = cond->text().toLocal8Bit().constData();
retval = NewBreak(nameString.c_str(), start_addr, end_addr, type, condString.c_str(), slot, enable);
@ -2536,9 +2442,7 @@ TraceLogDiskThread_t::~TraceLogDiskThread_t(void)
void TraceLogDiskThread_t::run(void)
{
char line[256];
char buf[8192];
int i,idx=0;
int blockSize = 4 * 1024;
const unsigned blockSize = 4 * 1024;
bool dataNeedsFlush = true;
bool isPaused = false;
@ -2547,24 +2451,27 @@ void TraceLogDiskThread_t::run(void)
setPriority( QThread::HighestPriority );
#ifdef WIN32
logFile = CreateFileA( logFilePath.c_str(), GENERIC_WRITE,
0, NULL, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL );
if ( logFile == INVALID_HANDLE_VALUE )
TraceFileWriter tracer;
if (!tracer.open(logFilePath.c_str(), (bool)FCEUI_EmulationPaused()))
{
char stmp[1024];
sprintf( stmp, "Error: Failed to open log file for writing: %s", logFilePath.c_str() );
snprintf( stmp, sizeof(stmp), "Error: Failed to open log file for writing: %s", logFilePath.c_str() );
consoleWindow->QueueErrorMsgWindow(stmp);
return;
}
#else
const unsigned bufSize = blockSize * 2;
const unsigned flushSize = blockSize;
char buf[bufSize];
unsigned int i, idx=0;
logFile = open( logFilePath.c_str(), O_CREAT | O_WRONLY | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
if ( logFile == -1 )
{
char stmp[1024];
sprintf( stmp, "Error: Failed to open log file for writing: %s", logFilePath.c_str() );
snprintf( stmp, sizeof(stmp), "Error: Failed to open log file for writing: %s", logFilePath.c_str() );
consoleWindow->QueueErrorMsgWindow(stmp);
return;
}
@ -2579,7 +2486,6 @@ void TraceLogDiskThread_t::run(void)
logBuf = (traceRecord_t *)malloc(size);
}
idx = 0;
while ( !isInterruptionRequested() )
{
@ -2588,7 +2494,13 @@ void TraceLogDiskThread_t::run(void)
while (logBufHead != logBufTail)
{
logBuf[logBufTail].convToText(line);
logBufTail = (logBufTail + 1) % logBufMax;
#ifdef WIN32
bool success = tracer.writeLine(line);
/// TODO: Do something on error
#else
i=0;
while ( line[i] != 0 )
{
@ -2596,24 +2508,23 @@ void TraceLogDiskThread_t::run(void)
}
buf[idx] = '\n'; idx++;
logBufTail = (logBufTail + 1) % logBufMax;
if ( idx >= blockSize )
if ( idx >= flushSize )
{
#ifdef WIN32
DWORD bytesWritten;
WriteFile( logFile, buf, idx, &bytesWritten, NULL ); idx = 0;
#else
if ( write( logFile, buf, idx ) < 0 )
{
// HANDLE ERROR TODO
}
idx = 0;
#endif
dataNeedsFlush = true;
}
#endif
}
#ifdef WIN32
bool success = tracer.setPause(isPaused);
/// TODO: Do something on error
#else
if (isPaused)
{
// If paused, the user might be at a breakpoint or doing some
@ -2621,55 +2532,40 @@ void TraceLogDiskThread_t::run(void)
// Only flush data when paused, to keep write efficiency up.
if ( idx > 0 )
{
#ifdef WIN32
DWORD bytesWritten;
WriteFile( logFile, buf, idx, &bytesWritten, NULL ); idx = 0;
#else
if ( write( logFile, buf, idx ) < 0 )
{
// HANDLE ERROR TODO
}
idx = 0;
#endif
dataNeedsFlush = true;
}
if (dataNeedsFlush)
{
//printf("Flushing Trace Log Disk Buffers\n");
#ifdef WIN32
FlushFileBuffers( logFile );
#else
if ( fsync( logFile ) )
{
printf("Trace Log fsync error\n");
}
#endif
dataNeedsFlush = false;
}
}
#endif
SDL_Delay(1);
}
#ifdef WIN32
tracer.close();
#else
if ( idx > 0 )
{
#ifdef WIN32
DWORD bytesWritten;
WriteFile( logFile, buf, idx, &bytesWritten, NULL ); idx = 0;
#else
if ( write( logFile, buf, idx ) < 0 )
{
// HANDLE ERROR TODO
}
idx = 0;
#endif
}
#ifdef WIN32
if ( logFile != INVALID_HANDLE_VALUE )
{
CloseHandle( logFile ); logFile = INVALID_HANDLE_VALUE;
}
#else
if ( logFile != -1 )
{
close(logFile); logFile = -1;

View File

@ -35,6 +35,7 @@
#include "Qt/sdl-video.h"
#include "Qt/AviRecord.h"
#include "Qt/unix-netplay.h"
#include "Qt/NetPlay.h"
#include "Qt/TasEditor/taseditor_config.h"
#ifdef WIN32
@ -214,6 +215,27 @@ int getHotKeyConfig( int i, const char **nameOut, const char **keySeqOut, const
case HK_TURBO:
name = "Turbo"; keySeq = "Tab"; group = "Speed";
break;
case HK_SPEED_NORMAL:
name = "Normal Speed"; keySeq = ""; group = "Speed";
break;
case HK_SPEED_QUARTER:
name = "1/4x Speed"; keySeq = ""; group = "Speed";
break;
case HK_SPEED_HALF:
name = "1/2x Speed"; keySeq = ""; group = "Speed";
break;
case HK_SPEED_2X:
name = "2x Speed"; keySeq = ""; group = "Speed";
break;
case HK_SPEED_4X:
name = "4x Speed"; keySeq = ""; group = "Speed";
break;
case HK_SPEED_8X:
name = "8x Speed"; keySeq = ""; group = "Speed";
break;
case HK_SPEED_16X:
name = "16x Speed"; keySeq = ""; group = "Speed";
break;
case HK_TOGGLE_INPUT_DISPLAY:
name = "ToggleInputDisplay"; keySeq = ","; group = "Misc";
break;
@ -593,15 +615,27 @@ InitConfig()
config->addOption("SDL.SpecialFilter", 0);
config->addOption("SDL.SpecialFX", 0);
config->addOption("SDL.Vsync", 1);
#ifdef WIN32
config->addOption("SDL.winFullScreenBorder", 0);
#endif
QString userName = qgetenv("USER");
if (userName.isEmpty())
{
userName = qgetenv("USERNAME");
}
// network play options - netplay is broken
config->addOption("server", "SDL.NetworkIsServer", 0);
config->addOption('n', "net", "SDL.NetworkIP", "");
config->addOption('u', "user", "SDL.NetworkUsername", "");
config->addOption('n', "net", "SDL.NetworkIP", "localhost");
config->addOption('u', "user", "SDL.NetworkUsername", userName.toLocal8Bit().constData());
config->addOption('w', "pass", "SDL.NetworkPassword", "");
config->addOption('k', "netkey", "SDL.NetworkGameKey", "");
config->addOption("port", "SDL.NetworkPort", 4046);
config->addOption("port", "SDL.NetworkPort", NetPlayServer::DefaultPort);
config->addOption("players", "SDL.NetworkPlayers", 1);
config->addOption("SDL.NetPlayHostAllowClientRomLoadReq", 0);
config->addOption("SDL.NetPlayHostAllowClientStateLoadReq", 0);
config->addOption("SDL.NetPlayHostEnforceAppVersionChk", 1);
// input configuration options
config->addOption("input1", "SDL.Input.0", "GamePad.0");
@ -614,6 +648,7 @@ InitConfig()
config->addOption("SDL.AutofireOffFrames", 1);
config->addOption("SDL.AutofireCustomOnFrames" , 1);
config->addOption("SDL.AutofireCustomOffFrames", 1);
config->addOption("SDL.NewInputDeviceBehavior", 1);
// display input
config->addOption("inputdisplay", "SDL.InputDisplay", 0);
@ -777,6 +812,7 @@ InitConfig()
config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", savPath );
config->addOption("_lastopenmovie", "SDL.LastOpenMovie", movPath);
config->addOption("_lastloadlua", "SDL.LastLoadLua", "");
config->addOption("_lastloadjs", "SDL.LastLoadJs", "");
config->addOption("SDL.HelpFilePath", "");
config->addOption("SDL.AviFilePath", "");
config->addOption("SDL.WavFilePath", "");
@ -784,7 +820,7 @@ InitConfig()
for (unsigned int i=0; i<10; i++)
{
char buf[128];
sprintf(buf, "SDL.RecentRom%02u", i);
snprintf(buf, sizeof(buf), "SDL.RecentRom%02u", i);
config->addOption( buf, "");
}
@ -792,7 +828,7 @@ InitConfig()
for (unsigned int i=0; i<10; i++)
{
char buf[128];
sprintf(buf, "SDL.RecentTasProject%02u", i);
snprintf(buf, sizeof(buf), "SDL.RecentTasProject%02u", i);
config->addOption( buf, "");
}
@ -1051,7 +1087,7 @@ InitConfig()
//keyText.assign(" mod=");
//sprintf( buf, " key=%s", SDL_GetKeyName( Hotkeys[i] ) );
//snprintf( buf, sizeof(buf), " key=%s", SDL_GetKeyName( Hotkeys[i] ) );
if ( hotKeyName[0] != 0 )
{

View File

@ -18,6 +18,8 @@ enum HOTKEY {
// Emulation Execution Control
HK_FRAME_ADVANCE, HK_DECREASE_SPEED, HK_INCREASE_SPEED, HK_TURBO,
HK_SPEED_QUARTER, HK_SPEED_HALF, HK_SPEED_NORMAL,
HK_SPEED_2X, HK_SPEED_4X, HK_SPEED_8X, HK_SPEED_16X,
// Save States
HK_SAVE_STATE,

View File

@ -1,3 +1,5 @@
#pragma once
#include <stdint.h>
#include "common/args.h"
#include "common/config.h"
@ -9,10 +11,10 @@ extern ARGPSTRUCT DriverArgs[];
void DoDriverArgs(void);
int InitSound();
void WriteSound(int32 *Buffer, int Count);
void WriteSound(int32_t *Buffer, int Count);
int KillSound(void);
uint32 GetMaxSound(void);
uint32 GetWriteSound(void);
uint32_t GetMaxSound(void);
uint32_t GetWriteSound(void);
bool FCEUD_SoundIsMuted(void);
void FCEUD_MuteSoundOutput(bool value);
void FCEUD_MuteSoundWindow(bool value);
@ -24,18 +26,19 @@ int KillJoysticks(void);
int AddJoystick( int which );
int RemoveJoystick( int which );
int FindJoystickByInstanceID( int which );
uint32 *GetJSOr(void);
uint32_t *GetJSOr(void);
struct FCEUGI;
int InitVideo(FCEUGI *gi);
int KillVideo(void);
void CalcVideoDimensions(void);
void BlitScreen(uint8 *XBuf);
void BlitScreen(uint8_t *XBuf);
void LockConsole(void);
void UnlockConsole(void);
void ToggleFS(); /* SDL */
int LoadGame(const char *path, bool silent);
//int CloseGame(void);
int LoadGame(const char *path, bool silent = false, bool netPlayRequested = false);
int CloseGame(void);
void Giggles(int);
void DoFun(void);

View File

@ -37,11 +37,13 @@
#include "Qt/sdl-video.h"
#include "Qt/nes_shm.h"
#include "Qt/unix-netplay.h"
#include "Qt/NetPlay.h"
#include "Qt/AviRecord.h"
#include "Qt/HexEditor.h"
#include "Qt/CheatsConf.h"
#include "Qt/SymbolicDebug.h"
#include "Qt/CodeDataLogger.h"
#include "Qt/QtScriptManager.h"
#include "Qt/ConsoleDebugger.h"
#include "Qt/ConsoleWindow.h"
#include "Qt/ConsoleUtilities.h"
@ -63,6 +65,7 @@
#include "common/os_utils.h"
#include "common/configSys.h"
#include "utils/timeStamp.h"
#include "utils/StringUtils.h"
#include "../../oldmovie.h"
#include "../../types.h"
@ -107,6 +110,7 @@ static int mutexLocks = 0;
static int mutexPending = 0;
static bool emulatorHasMutex = 0;
unsigned int emulatorCycleCount = 0;
static int archiveFileLoadIndex = -1;
extern double g_fpsScale;
@ -306,11 +310,22 @@ int reloadLastGame(void)
* provides data necessary for the driver code(number of scanlines to
* render, what virtual input devices to use, etc.).
*/
int LoadGame(const char *path, bool silent)
int LoadGame(const char *path, bool silent, bool netPlayRequested)
{
std::string fullpath;
int gg_enabled, autoLoadDebug, autoOpenDebugger, autoInputPreset;
// Check if this application instance has joined a net play session,
// NetPlay clients can only load ROMs retrieved from the host server.
// However, clients can request that a host load their ROM for all players.
auto* netPlayClient = NetPlayClient::GetInstance();
if (!netPlayRequested && (netPlayClient != nullptr))
{
netPlayClient->requestRomLoad( path );
return 0;
}
if (isloaded){
CloseGame();
}
@ -320,24 +335,14 @@ int LoadGame(const char *path, bool silent)
// Resolve absolute path to file
if ( fi.exists() )
{
//printf("FI: '%s'\n", fi.absoluteFilePath().toStdString().c_str() );
//printf("FI: '%s'\n", fi.canonicalFilePath().toStdString().c_str() );
fullpath = fi.canonicalFilePath().toStdString();
//printf("FI: '%s'\n", fi.absoluteFilePath().toLocal8Bit().constData() );
//printf("FI: '%s'\n", fi.canonicalFilePath().toLocal8Bit().constData() );
fullpath = fi.canonicalFilePath().toLocal8Bit().constData();
}
else
{
fullpath.assign( path );
}
//#if defined(__linux__) || defined(__APPLE__) || defined(__unix__)
//
// // Resolve absolute path to file
// if ( realpath( path, fullpath ) == NULL )
// {
// strcpy( fullpath, path );
// }
//#else
// strcpy( fullpath, path );
//#endif
//printf("Fullpath: %zi '%s'\n", sizeof(fullpath), fullpath );
@ -465,7 +470,11 @@ int LoadGame(const char *path, bool silent)
//}
isloaded = 1;
//FCEUD_NetworkConnect();
// Signal to listeners that a new ROM was loaded
if ( consoleWindow )
{
emit consoleWindow->romLoaded();
}
return 1;
}
@ -487,6 +496,12 @@ CloseGame(void)
return(0);
}
// Signal to listeners that current ROM is being unloaded
if ( consoleWindow )
{
emit consoleWindow->romUnload();
}
// If the emulation thread is stuck hanging at a breakpoint,
// disable breakpoint debugging and wait for the thread to
// complete its frame. So that it is idle with a minimal call
@ -558,6 +573,11 @@ int fceuWrapperSoftReset(void)
if ( isloaded )
{
ResetNES();
if (consoleWindow != nullptr)
{
emit consoleWindow->nesResetOccurred();
}
}
return 0;
}
@ -572,12 +592,13 @@ int fceuWrapperHardReset(void)
if ( GameInfo->archiveFilename )
{
strcpy( romPath, GameInfo->archiveFilename );
Strlcpy( romPath, GameInfo->archiveFilename, sizeof(romPath) );
}
else if ( GameInfo->filename )
{
strcpy( romPath, GameInfo->filename );
Strlcpy( romPath, GameInfo->filename, sizeof(romPath) );
}
fceuWrapperSetArchiveFileLoadIndex( GameInfo->archiveIndex );
if ( romPath[0] != 0 )
{
@ -585,6 +606,7 @@ int fceuWrapperHardReset(void)
//printf("Loading: '%s'\n", romPath );
LoadGame ( romPath );
}
fceuWrapperClearArchiveFileLoadIndex();
}
return 0;
}
@ -688,7 +710,7 @@ static void ShowUsage(const char *prog)
j=0;
for (i=0; i<styleList.size(); i++)
{
printf(" %16s ", styleList[i].toStdString().c_str() ); j++;
printf(" %16s ", styleList[i].toLocal8Bit().constData() ); j++;
if ( j >= 4 )
{
@ -1043,7 +1065,7 @@ int fceuWrapperInit( int argc, char *argv[] )
// Resolve absolute path to file
if ( fi.exists() )
{
std::string fullpath = fi.canonicalFilePath().toStdString().c_str();
std::string fullpath = fi.canonicalFilePath().toLocal8Bit().constData();
error = LoadGame( fullpath.c_str() );
@ -1116,9 +1138,9 @@ int fceuWrapperInit( int argc, char *argv[] )
// Resolve absolute path to file
if ( fi.exists() )
{
//printf("FI: '%s'\n", fi.absoluteFilePath().toStdString().c_str() );
//printf("FI: '%s'\n", fi.canonicalFilePath().toStdString().c_str() );
s = fi.canonicalFilePath().toStdString();
//printf("FI: '%s'\n", fi.absoluteFilePath().toLocal8Bit().constData() );
//printf("FI: '%s'\n", fi.canonicalFilePath().toLocal8Bit().constData() );
s = fi.canonicalFilePath().toLocal8Bit().constData();
}
//#if defined(__linux__) || defined(__APPLE__) || defined(__unix__)
//
@ -1369,7 +1391,7 @@ void fceuWrapperLock(const char *filename, int line, const char *func)
printf("Already Locked By: %s\n", lockFile.c_str() );
printf("Requested By: %s:%i - %s\n", filename, line, func );
}
sprintf( txt, ":%i - ", line );
snprintf( txt, sizeof(txt), ":%i - ", line );
lockFile.assign(filename);
lockFile.append(txt);
lockFile.append(func);
@ -1381,7 +1403,7 @@ void fceuWrapperLock(void)
mutexPending++;
if ( consoleWindow != NULL )
{
consoleWindow->mutex->lock();
consoleWindow->emulatorMutex.lock();
}
mutexPending--;
mutexLocks++;
@ -1396,7 +1418,7 @@ bool fceuWrapperTryLock(const char *filename, int line, const char *func, int ti
if ( lockAcq && debugMutexLock)
{
char txt[32];
sprintf( txt, ":%i - ", line );
snprintf( txt, sizeof(txt), ":%i - ", line );
lockFile.assign(filename);
lockFile.append(txt);
lockFile.append(func);
@ -1411,7 +1433,7 @@ bool fceuWrapperTryLock(int timeout)
mutexPending++;
if ( consoleWindow != NULL )
{
lockAcq = consoleWindow->mutex->tryLock( timeout );
lockAcq = consoleWindow->emulatorMutex.tryLock( timeout );
}
mutexPending--;
@ -1429,7 +1451,7 @@ void fceuWrapperUnLock(void)
mutexLocks--;
if ( consoleWindow != NULL )
{
consoleWindow->mutex->unlock();
consoleWindow->emulatorMutex.unlock();
}
}
else
@ -1474,20 +1496,56 @@ int fceuWrapperUpdate( void )
}
mutexLockFail = false;
emulatorHasMutex = 1;
// For netplay, set pause if we do not have input ready for all players
if (NetPlayActive())
{
if (NetPlayFrameWait())
{
FCEUI_SetNetPlayPause(true);
}
else
{
FCEUI_SetNetPlayPause(false);
}
}
else
{
FCEUI_SetNetPlayPause(false);
}
if ( GameInfo )
{
#ifdef __FCEU_QSCRIPT_ENABLE__
auto* qscriptMgr = QtScriptManager::getInstance();
bool scriptsLoaded = (qscriptMgr != nullptr) && (qscriptMgr->numScriptsLoaded() > 0);
if (scriptsLoaded)
{
qscriptMgr->frameBeginUpdate();
}
#endif
DoFun(frameskip, periodic_saves);
#ifdef __FCEU_QSCRIPT_ENABLE__
if (scriptsLoaded)
{
qscriptMgr->frameFinishedUpdate();
}
#endif
hexEditorUpdateMemoryValues();
fceuWrapperUnLock();
emulatorHasMutex = 0;
if ( consoleWindow )
{
consoleWindow->emulatorThread->signalFrameFinished();
}
fceuWrapperUnLock();
emulatorHasMutex = 0;
#ifdef __FCEU_PROFILER_ENABLE__
FCEU_profiler_log_thread_activity();
@ -1675,7 +1733,7 @@ static FCEUFILE* minizip_OpenArchive(ArchiveScanRecord& asr, std::string &fname,
//printf("Filename: %u '%s' \n", fi.uncompressed_size, filename );
if (searchFile)
if ( (searchFile != nullptr) && !searchFile->empty())
{
if ( strcmp( searchFile->c_str(), filename ) == 0 )
{
@ -1794,7 +1852,8 @@ static FCEUFILE* libarchive_OpenArchive( ArchiveScanRecord& asr, std::string& fn
filename = archive_entry_pathname(entry);
fileSize = archive_entry_size(entry);
if (searchFile)
//printf("ArchiveFile:%i %s\n", idx, filename);
if ( (searchFile != nullptr) && !searchFile->empty())
{
if (strcmp( filename, searchFile->c_str() ) == 0)
{
@ -1859,6 +1918,16 @@ static FCEUFILE* libarchive_OpenArchive( ArchiveScanRecord& asr, std::string& fn
#endif
void fceuWrapperSetArchiveFileLoadIndex(int idx)
{
archiveFileLoadIndex = idx;
}
void fceuWrapperClearArchiveFileLoadIndex()
{
archiveFileLoadIndex = -1;
}
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename, int* userCancel)
{
FCEUFILE* fp = nullptr;
@ -1876,6 +1945,7 @@ FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::str
{
char base[512], suffix[128];
//printf("File:%zi %s\n", i, asr.files[i].name.c_str() );
getFileBaseName( asr.files[i].name.c_str(), base, suffix );
if ( (strcasecmp( suffix, ".nes" ) == 0) ||
@ -1890,7 +1960,11 @@ FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::str
if ( fileList.size() > 1 )
{
if ( consoleWindow != NULL )
if ( (archiveFileLoadIndex >= 0) && (static_cast<size_t>(archiveFileLoadIndex) < asr.files.size()))
{
searchFile.clear();
}
else if ( consoleWindow != NULL )
{
int sel = consoleWindow->showListSelectDialog( "Select ROM From Archive", fileList );
@ -1909,16 +1983,18 @@ FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::str
{
searchFile = fileList[0];
}
//printf("Archive Search File: %s\n", searchFile.c_str());
}
#ifdef _USE_LIBARCHIVE
fp = libarchive_OpenArchive(asr, fname, &searchFile, -1 );
fp = libarchive_OpenArchive(asr, fname, &searchFile, archiveFileLoadIndex );
#endif
if (fp == nullptr)
{
fp = minizip_OpenArchive(asr, fname, &searchFile, -1 );
fp = minizip_OpenArchive(asr, fname, &searchFile, archiveFileLoadIndex );
}
//printf("Archive File Index: %i\n", fp->archiveIndex);
return fp;
}
@ -1960,10 +2036,6 @@ FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string &fname, int
}
DUMMY(FCEUD_HideMenuToggle)
DUMMY(FCEUD_MovieReplayFrom)
//DUMMY(FCEUD_AviRecordTo)
//DUMMY(FCEUD_AviStop)
//void FCEUI_AviVideoUpdate(const unsigned char* buffer) { }
//bool FCEUI_AviIsRecording(void) {return false;}
void FCEUI_UseInputPreset(int preset) { }
bool FCEUD_PauseAfterPlayback() { return pauseAfterPlayback; }

View File

@ -1,6 +1,7 @@
// fceuWrapper.h
//
#include "Qt/config.h"
#include "Qt/dface.h"
//*****************************************************************
// Define Global Variables to be shared with FCEU Core
@ -26,7 +27,7 @@ extern unsigned int emulatorCycleCount;
// global configuration object
extern Config *g_config;
int LoadGame(const char *path, bool silent = false);
//int LoadGame(const char *path, bool silent = false, bool netPlayRequested = false);
int CloseGame(void);
int reloadLastGame(void);
int LoadGameFromLua( const char *path );
@ -47,6 +48,8 @@ int fceuWrapperHardReset(void);
int fceuWrapperTogglePause(void);
bool fceuWrapperGameLoaded(void);
void fceuWrapperRequestAppExit(void);
void fceuWrapperClearArchiveFileLoadIndex(void);
void fceuWrapperSetArchiveFileLoadIndex(int idx);
class fceuCriticalSection
{

View File

@ -238,7 +238,7 @@ iNesHeaderEditor_t::iNesHeaderEditor_t(QWidget *parent)
for (i = 0; bmap[i].init; ++i)
{
sprintf(stmp, "%d %s", bmap[i].number, bmap[i].name);
snprintf(stmp, sizeof(stmp), "%d %s", bmap[i].number, bmap[i].name);
mapperComboBox->addItem( tr(stmp), bmap[i].number );
}
@ -307,25 +307,25 @@ iNesHeaderEditor_t::iNesHeaderEditor_t(QWidget *parent)
if (size >= 1024 << 3)
{
// The size of CHR ROM must be multiple of 8KB
sprintf( stmp, "%d KB", size / 1024);
snprintf( stmp, sizeof(stmp), "%d KB", size / 1024);
chrRomBox->addItem( tr(stmp), size );
// The size of PRG ROM must be multiple of 16KB
if (size >= 1024 * 16)
{
// PRG ROM
sprintf(stmp, "%d KB", size / 1024);
snprintf(stmp, sizeof(stmp), "%d KB", size / 1024);
prgRomBox->addItem( tr(stmp), size );
}
}
if (size >= 1024)
{
sprintf( stmp, "%d KB", size / 1024);
snprintf( stmp, sizeof(stmp), "%d KB", size / 1024);
}
else
{
sprintf( stmp, "%d B", size);
snprintf( stmp, sizeof(stmp), "%d B", size);
}
prgRamBox->addItem( tr(stmp), size );
@ -823,11 +823,11 @@ bool iNesHeaderEditor_t::openFile(void)
{
return false;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
if ( GameInfo == NULL )
{
strncpy( LoadedRomFName, filename.toStdString().c_str(), sizeof(LoadedRomFName)-1 );
strncpy( LoadedRomFName, filename.toLocal8Bit().constData(), sizeof(LoadedRomFName)-1 );
LoadedRomFName[sizeof(LoadedRomFName)-1] = 0;
}
@ -877,11 +877,11 @@ void iNesHeaderEditor_t::saveFileAs(void)
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
qDebug() << "selected file path : " << filename.toLocal8Bit();
WriteHeaderData( iNesHdr );
if ( SaveINESFile( filename.toStdString().c_str(), iNesHdr ) )
if ( SaveINESFile( filename.toLocal8Bit().constData(), iNesHdr ) )
{
// Error
}
@ -911,7 +911,7 @@ void iNesHeaderEditor_t::setHeaderData(iNES_HEADER* header)
{
if ( mapperComboBox->itemData(i).toInt() > mapper )
{
sprintf( buf, "%i Unknown/unsupported", i);
snprintf( buf, sizeof(buf), "%i Unknown/unsupported", i);
mapperComboBox->insertItem( i, tr(buf), mapper);
mapperComboBox->setCurrentIndex(i);
break;
@ -924,7 +924,7 @@ void iNesHeaderEditor_t::setHeaderData(iNES_HEADER* header)
}
// Sub Mapper
sprintf(buf, "%d", ines20 ? header->ROM_type3 >> 4 : 0);
snprintf(buf, sizeof(buf), "%d", ines20 ? header->ROM_type3 >> 4 : 0);
mapperSubEdit->setText( tr(buf) );
@ -1210,7 +1210,7 @@ void iNesHeaderEditor_t::setHeaderData(iNES_HEADER* header)
}
// Miscellaneous ROM Area(s)
sprintf(buf, "%d", header->misc_roms & 3);
snprintf(buf, sizeof(buf), "%d", header->misc_roms & 3);
miscRomsEdit->setText( tr(buf) );
// Trainer
@ -1398,7 +1398,7 @@ bool iNesHeaderEditor_t::WriteHeaderData(iNES_HEADER* header)
}
else
{
sprintf(buf, "Error: Mapper# should be less than %d in iNES %d.0 format.", 256, 1);
snprintf(buf, sizeof(buf), "Error: Mapper# should be less than %d in iNES %d.0 format.", 256, 1);
showErrorMsgWindow(buf);
return false;
}
@ -1406,7 +1406,7 @@ bool iNesHeaderEditor_t::WriteHeaderData(iNES_HEADER* header)
}
else
{
sprintf(buf, "Mapper# should be less than %d in iNES %d.0 format.", 4096, 2);
snprintf(buf, sizeof(buf), "Mapper# should be less than %d in iNES %d.0 format.", 4096, 2);
showErrorMsgWindow(buf);
return false;
}
@ -1414,7 +1414,7 @@ bool iNesHeaderEditor_t::WriteHeaderData(iNES_HEADER* header)
// Sub mapper
if (ines20)
{
strcpy( buf, mapperSubEdit->text().toStdString().c_str() );
strcpy( buf, mapperSubEdit->text().toLocal8Bit().constData() );
int submapper;
if (sscanf(buf, "%d", &submapper) > 0)
{
@ -1483,13 +1483,13 @@ bool iNesHeaderEditor_t::WriteHeaderData(iNES_HEADER* header)
char buf2[64];
if (result % 1024 != 0)
{
sprintf(buf2, "%dB", result);
snprintf(buf2, sizeof(buf2), "%dB", result);
}
else
{
sprintf(buf2, "%dKB", result / 1024);
snprintf(buf2, sizeof(buf2), "%dKB", result / 1024);
}
sprintf(buf, "PRG ROM size you entered is invalid in iNES 2.0, do you want to set to its nearest value %s?", buf2);
snprintf(buf, sizeof(buf), "PRG ROM size you entered is invalid in iNES 2.0, do you want to set to its nearest value %s?", buf2);
showErrorMsgWindow(buf);
//if (MessageBox(hwnd, buf, "Error", MB_YESNO | MB_ICONERROR) == IDYES)
//{
@ -1691,13 +1691,13 @@ bool iNesHeaderEditor_t::WriteHeaderData(iNES_HEADER* header)
char buf2[64];
if (result % 1024 != 0)
{
sprintf(buf2, "%dB", result);
snprintf(buf2, sizeof(buf2), "%dB", result);
}
else
{
sprintf(buf2, "%dKB", result / 1024);
snprintf(buf2, sizeof(buf2), "%dKB", result / 1024);
}
sprintf(buf, "CHR ROM size you entered is invalid in iNES 2.0, do you want to set to its nearest value %s?", buf2);
snprintf(buf, sizeof(buf), "CHR ROM size you entered is invalid in iNES 2.0, do you want to set to its nearest value %s?", buf2);
showErrorMsgWindow(buf);
//if (MessageBox(hwnd, buf, "Error", MB_YESNO | MB_ICONERROR) == IDYES)
// SetDlgItemText(hwnd, IDC_CHRROM_COMBO, buf2);
@ -1935,7 +1935,7 @@ bool iNesHeaderEditor_t::WriteHeaderData(iNES_HEADER* header)
// Miscellanous ROM(s)
if (ines20)
{
strcpy( buf, miscRomsEdit->text().toStdString().c_str() );
strcpy( buf, miscRomsEdit->text().toLocal8Bit().constData() );
int misc_roms = 0;
if (sscanf(buf, "%d", &misc_roms) < 1)
{
@ -1986,7 +1986,7 @@ bool iNesHeaderEditor_t::WriteHeaderData(iNES_HEADER* header)
int ret;
QMessageBox msgBox(this);
sprintf(buf, "FCEUX doesn't support iNES Mapper# %d, this is not a serious problem, but the ROM will not be run in FCEUX properly.\nDo you want to continue?", mapper);
snprintf(buf, sizeof(buf), "FCEUX doesn't support iNES Mapper# %d, this is not a serious problem, but the ROM will not be run in FCEUX properly.\nDo you want to continue?", mapper);
msgBox.setIcon( QMessageBox::Warning );
msgBox.setText( tr(buf) );

View File

@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <QMessageBox>
#include <QFileDialog>
#include <QInputDialog>
#include <QApplication>
@ -238,7 +239,7 @@ int hotkey_t::init(QWidget *parent)
shortcut = new QShortcut(QKeySequence(QString::fromStdString(keyText)), parent);
//printf("ShortCut: '%s' = '%s'\n", configName, shortcut->key().toString().toStdString().c_str() );
//printf("ShortCut: '%s' = '%s'\n", configName, shortcut->key().toString().toLocal8Bit().constData() );
conv2SDL();
return 0;
@ -258,7 +259,7 @@ int hotkey_t::readConfig(void)
{
shortcut->setKey(QString::fromStdString(keyText));
//printf("ShortCut: '%s' = '%s'\n", configName, shortcut->key().toString().toStdString().c_str() );
//printf("ShortCut: '%s' = '%s'\n", configName, shortcut->key().toString().toLocal8Bit().constData() );
if (act)
{
@ -289,7 +290,7 @@ void hotkey_t::conv2SDL(void)
SDL_Keymod m = convQtKey2SDLModifier((Qt::KeyboardModifier)(shortcut->key()[0] & 0xFE000000));
#endif
//printf("Key: '%s' 0x%08x\n", shortcut->key().toString().toStdString().c_str(), shortcut->key()[0] );
//printf("Key: '%s' 0x%08x\n", shortcut->key().toString().toLocal8Bit().constData(), shortcut->key()[0] );
sdl.value = k;
sdl.modifier = m;
@ -327,7 +328,7 @@ int hotkey_t::getString(char *s)
if (shortcut)
{
strcpy(s, shortcut->key().toString().toStdString().c_str());
strcpy(s, shortcut->key().toString().toLocal8Bit().constData());
}
//if ( sdl.modifier != 0 )
//{
@ -670,7 +671,7 @@ static std::string GetFilename(const char *title, int mode, const char *filter)
if (fileList.size() > 0)
{
fname = fileList[0].toStdString();
fname = fileList[0].toLocal8Bit().constData();
}
}
@ -690,7 +691,7 @@ void FCEUD_MovieRecordTo(void)
// return; // no filename selected, quit the whole thing
//}
//std::string s = QInputDialog::getText( consoleWindow, QObject::tr("Movie Recording"),
// QObject::tr("Enter Author Name"), QLineEdit::Normal, QObject::tr(""), &ok ).toStdString();
// QObject::tr("Enter Author Name"), QLineEdit::Normal, QObject::tr(""), &ok ).toLocal8Bit().constData();
//std::wstring author (s.begin (), s.end ());
@ -1288,8 +1289,8 @@ void GetMouseRelative(int32 (&d)[3])
/**
* Handles outstanding SDL events.
*/
static void
UpdatePhysicalInput()
void
pollEventsSDL()
{
SDL_Event event;
@ -1362,7 +1363,51 @@ UpdatePhysicalInput()
break;
case SDL_JOYDEVICEADDED:
AddJoystick(event.jdevice.which);
{
int devIdx = AddJoystick(event.jdevice.which);
if (devIdx >= 0)
{
int newDeviceBehavior = 0;
g_config->getOption("SDL.NewInputDeviceBehavior", &newDeviceBehavior);
if (newDeviceBehavior == 1)
{
bool wasPaused = FCEUI_EmulationPaused() ? true : false;
jsDev_t* jsDev = getJoystickDevice(devIdx);
QString msg = "A new joystick/gamepad device has been detected.\n";
if (jsDev != nullptr)
{
msg += QString("\nDevice ") + QString::number(devIdx) + QString(": ");
msg += QString(jsDev->getName()) + "\n";
}
msg += "\nDo you wish to reload button bindings?";
QMessageBox msgBox(QMessageBox::Question, QObject::tr("New Device Detected"), msg,
QMessageBox::No | QMessageBox::Yes, consoleWindow);
msgBox.setDefaultButton( QMessageBox::Yes );
FCEUI_SetEmulationPaused( EMULATIONPAUSED_PAUSED );
int answer = msgBox.exec();
if ( answer == QMessageBox::Yes )
{
initGamepadBindings();
}
if (!wasPaused)
{
FCEUI_SetEmulationPaused(0);
}
}
else if (newDeviceBehavior == 2)
{
initGamepadBindings();
}
}
}
break;
case SDL_JOYDEVICEREMOVED:
RemoveJoystick(event.jdevice.which);
@ -1646,7 +1691,7 @@ void FCEUD_UpdateInput(void)
updateGamePadKeyMappings();
UpdatePhysicalInput();
pollEventsSDL();
KeyboardCommands();
for (x = 0; x < 2; x++)
@ -2093,7 +2138,7 @@ const char *ButtonName(const ButtConfig *bc)
inputNum = bc->ButtonNum;
inputDirection = "";
}
sprintf(name, "js%i:%s%i%s", joyNum, inputType, inputNum, inputDirection);
snprintf(name, sizeof(name), "js%i:%s%i%s", joyNum, inputType, inputNum, inputDirection);
}
break;
}
@ -2598,7 +2643,7 @@ int loadInputSettingsFromFile(const char *filename)
void UpdateInput(Config *config)
{
char buf[64];
std::string device, prefix, guid, mapping;
std::string device, prefix;
InitJoysticks();
@ -2686,19 +2731,20 @@ void UpdateInput(Config *config)
// input device key.
int type, devnum, button;
// This is now done in InitJoysticks
// gamepad 0 - 3
for (unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++)
{
char buf[64];
snprintf(buf, sizeof(buf) - 1, "SDL.Input.GamePad.%u.", i);
prefix = buf;
//for (unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++)
//{
// char buf[64];
// snprintf(buf, sizeof(buf) - 1, "SDL.Input.GamePad.%u.", i);
// prefix = buf;
config->getOption(prefix + "DeviceType", &device);
config->getOption(prefix + "DeviceGUID", &guid);
config->getOption(prefix + "Profile", &mapping);
// config->getOption(prefix + "DeviceType", &device);
// config->getOption(prefix + "DeviceGUID", &guid);
// config->getOption(prefix + "Profile", &mapping);
GamePad[i].init(i, guid.c_str(), mapping.c_str());
}
// GamePad[i].init(i, guid.c_str(), mapping.c_str());
//}
// PowerPad 0 - 1
for (unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++)

View File

@ -10,6 +10,7 @@
#include <QAction>
#include "common/configSys.h"
#include "Qt/main.h"
//#define MAXBUTTCONFIG 4
@ -26,6 +27,7 @@ struct ButtConfig
int state;
};
struct FCEUGI;
extern int NoWaiting;
extern CFGSTRUCT InputConfig[];
extern ARGPSTRUCT InputArgs[];
@ -143,6 +145,8 @@ void UpdateInput(Config *config);
const char* ButtonName(const ButtConfig* bc);
void pollEventsSDL();
uint32_t GetGamepadPressedImmediate(void);
int getInputSelection( int port, int *cur, int *usr );
int saveInputSettingsToFile( const char *fileBase = NULL );
int loadInputSettingsFromFile( const char *filename = NULL );

View File

@ -27,8 +27,9 @@
#include "Qt/ConsoleWindow.h"
#include "Qt/fceuWrapper.h"
#include "Qt/SplashScreen.h"
#include "Qt/QtScriptManager.h"
#ifdef WIN32
#if defined(WIN32) && (QT_VERSION_MAJOR < 6)
#include <QtPlatformHeaders/QWindowsWindowFunctions>
#endif
@ -65,6 +66,10 @@ static void MessageOutput(QtMsgType type, const QMessageLogContext &context, con
}
cmsg[sizeof(cmsg)-1] = 0;
fprintf(stderr, "%s", cmsg );
#ifdef __FCEU_QSCRIPT_ENABLE__
QtScriptManager::logMessageQt(type, msg);
#endif
}
@ -154,11 +159,13 @@ int main( int argc, char *argv[] )
// Need to wait for window to initialize before video init can be called.
//consoleWindow->videoInit();
#ifdef WIN32
#if defined(WIN32) && (QT_VERSION_MAJOR < 6)
// This function is needed to fix the issue referenced below. It adds a 1-pixel border
// around the fullscreen window due to some limitation in windows.
// https://doc.qt.io/qt-5/windows-issues.html#fullscreen-opengl-based-windows
QWindowsWindowFunctions::setHasBorderInFullScreen( consoleWindow->windowHandle(), true);
bool fullScreenBorderOpt = false;
g_config->getOption("SDL.winFullScreenBorder", &fullScreenBorderOpt );
QWindowsWindowFunctions::setHasBorderInFullScreen( consoleWindow->windowHandle(), fullScreenBorderOpt);
#endif
if ( splash )

View File

@ -887,7 +887,7 @@ void ppuPatternView_t::updateSelTileLabel(void)
char stmp[32];
if ( (selTile.y() >= 0) && (selTile.x() >= 0) )
{
sprintf( stmp, "Tile: $%X%X", selTile.y(), selTile.x() );
snprintf( stmp, sizeof(stmp), "Tile: $%X%X", selTile.y(), selTile.x() );
}
else
{
@ -949,7 +949,7 @@ void ppuPatternView_t::contextMenuEvent(QContextMenuEvent *event)
if ( mode )
{
sprintf( stmp, "Exit Tile &View: %X%X", selTile.y(), selTile.x() );
snprintf( stmp, sizeof(stmp), "Exit Tile &View: %X%X", selTile.y(), selTile.x() );
act = new QAction(tr(stmp), &menu);
act->setShortcut( QKeySequence(tr("Z")));
@ -958,7 +958,7 @@ void ppuPatternView_t::contextMenuEvent(QContextMenuEvent *event)
}
else
{
sprintf( stmp, "&View Tile: %X%X", selTile.y(), selTile.x() );
snprintf( stmp, sizeof(stmp), "&View Tile: %X%X", selTile.y(), selTile.x() );
act = new QAction(tr(stmp), &menu);
act->setShortcut( QKeySequence(tr("Z")));
@ -987,7 +987,7 @@ void ppuPatternView_t::contextMenuEvent(QContextMenuEvent *event)
{
char stmp[8];
sprintf( stmp, "&%i", i+1 );
snprintf( stmp, sizeof(stmp), "&%i", i+1 );
paletteAct[i] = new QAction(tr(stmp), &menu);
paletteAct[i]->setCheckable(true);
@ -1787,13 +1787,13 @@ void tilePaletteView_t::contextMenuEvent(QContextMenuEvent *event)
subMenu = menu.addMenu( tr("Copy Color to Clipboard") );
sprintf( stmp, "Hex #%02X%02X%02X", palo[i].r, palo[i].g, palo[i].b );
snprintf( stmp, sizeof(stmp), "Hex #%02X%02X%02X", palo[i].r, palo[i].g, palo[i].b );
act = new QAction(tr(stmp), &menu);
//act->setShortcut( QKeySequence(tr("G")));
connect( act, SIGNAL(triggered(void)), this, SLOT(copyColor2ClipBoardHex(void)) );
subMenu->addAction( act );
sprintf( stmp, "rgb(%3i,%3i,%3i)", palo[i].r, palo[i].g, palo[i].b );
snprintf( stmp, sizeof(stmp), "rgb(%3i,%3i,%3i)", palo[i].r, palo[i].g, palo[i].b );
act = new QAction(tr(stmp), &menu);
//act->setShortcut( QKeySequence(tr("G")));
connect( act, SIGNAL(triggered(void)), this, SLOT(copyColor2ClipBoardRGB(void)) );
@ -1815,7 +1815,7 @@ void tilePaletteView_t::copyColor2ClipBoardHex(void)
}
p = palcache[ (palIdx << 2) | selBox ];
sprintf( txt, "#%02X%02X%02X", palo[p].r, palo[p].g, palo[p].b );
snprintf( txt, sizeof(txt), "#%02X%02X%02X", palo[p].r, palo[p].g, palo[p].b );
clipboard->setText( tr(txt), QClipboard::Clipboard );
@ -1837,7 +1837,7 @@ void tilePaletteView_t::copyColor2ClipBoardRGB(void)
}
p = palcache[ (palIdx << 2) | selBox ];
sprintf( txt, "rgb(%3i,%3i,%3i)", palo[p].r, palo[p].g, palo[p].b );
snprintf( txt, sizeof(txt), "rgb(%3i,%3i,%3i)", palo[p].r, palo[p].g, palo[p].b );
clipboard->setText( tr(txt), QClipboard::Clipboard );
@ -1892,9 +1892,9 @@ void tilePaletteView_t::exportPaletteFileDialog(void)
{
return;
}
//qDebug() << "selected file path : " << filename.toUtf8();
//qDebug() << "selected file path : " << filename.toLocal8Bit();
exportActivePaletteACT( filename.toStdString().c_str() );
exportActivePaletteACT( filename.toLocal8Bit().constData() );
}
//----------------------------------------------------
void tilePaletteView_t::openColorPicker(void)
@ -2164,7 +2164,7 @@ void ppuTileEditor_t::setTile( QPoint *t )
addr = addr + ( t->y() * 0x0100 );
addr = addr + ( t->x() * 0x0010 );
sprintf( stmp, "Tile Index: $%X%X Address: $%04X", t->y(), t->x(), addr );
snprintf( stmp, sizeof(stmp), "Tile Index: $%X%X Address: $%04X", t->y(), t->x(), addr );
tileIdxLbl->setText( tr(stmp) );
tileView->setTile( t );
@ -2490,7 +2490,7 @@ void ppuTileView_t::contextMenuEvent(QContextMenuEvent *event)
//
// if ( mode )
// {
// sprintf( stmp, "Exit Tile View: %X%X", selTile.y(), selTile.x() );
// snprintf( stmp, sizeof(stmp), "Exit Tile View: %X%X", selTile.y(), selTile.x() );
//
// act = new QAction(tr(stmp), &menu);
// act->setShortcut( QKeySequence(tr("Z")));
@ -2506,7 +2506,7 @@ void ppuTileView_t::contextMenuEvent(QContextMenuEvent *event)
// }
// else
// {
// sprintf( stmp, "View Tile: %X%X", selTile.y(), selTile.x() );
// snprintf( stmp, sizeof(stmp), "View Tile: %X%X", selTile.y(), selTile.x() );
//
// act = new QAction(tr(stmp), &menu);
// act->setShortcut( QKeySequence(tr("Z")));
@ -2533,7 +2533,7 @@ void ppuTileView_t::contextMenuEvent(QContextMenuEvent *event)
// {
// char stmp[8];
//
// sprintf( stmp, "%i", i+1 );
// snprintf( stmp, sizeof(stmp), "%i", i+1 );
//
// paletteAct[i] = new QAction(tr(stmp), &menu);
// paletteAct[i]->setCheckable(true);
@ -2728,7 +2728,7 @@ void ppuTileEditColorPicker_t::mouseMoveEvent(QMouseEvent *event)
// char stmp[64];
// int ix = (tile.y()<<4)|tile.x();
// sprintf( stmp, "Palette: $%02X", palcache[ix]);
// snprintf( stmp, sizeof(stmp), "Palette: $%02X", palcache[ix]);
// frame->setTitle( tr(stmp) );
//}
@ -3192,25 +3192,25 @@ void spriteViewerDialog_t::periodicUpdate(void)
idx = oamView->getSpriteIndex();
sprintf( stmp, "$%02X", idx );
snprintf( stmp, sizeof(stmp), "$%02X", idx );
spriteIndexBox->setText( tr(stmp) );
sprintf( stmp, "$%02X", oamPattern.sprite[idx].tNum );
snprintf( stmp, sizeof(stmp), "$%02X", oamPattern.sprite[idx].tNum );
tileIndexBox->setText( tr(stmp) );
sprintf( stmp, "$%04X", oamPattern.sprite[idx].chrAddr );
snprintf( stmp, sizeof(stmp), "$%04X", oamPattern.sprite[idx].chrAddr );
tileAddrBox->setText( tr(stmp) );
sprintf( stmp, "$%04X", 0x3F00 + (oamPattern.sprite[idx].pal*4) );
snprintf( stmp, sizeof(stmp), "$%04X", 0x3F00 + (oamPattern.sprite[idx].pal*4) );
palAddrBox->setText( tr(stmp) );
if ( showPosHex->isChecked() )
{
sprintf( stmp, "$%02X, $%02X", oamPattern.sprite[idx].x, oamPattern.sprite[idx].y );
snprintf( stmp, sizeof(stmp), "$%02X, $%02X", oamPattern.sprite[idx].x, oamPattern.sprite[idx].y );
}
else
{
sprintf( stmp, "%3i, %3i", oamPattern.sprite[idx].x, oamPattern.sprite[idx].y );
snprintf( stmp, sizeof(stmp), "%3i, %3i", oamPattern.sprite[idx].x, oamPattern.sprite[idx].y );
}
posBox->setText( tr(stmp) );

View File

@ -50,6 +50,7 @@ static const char *buttonNames[GAMEPAD_NUM_BUTTONS] =
"dpup", "dpdown", "dpleft", "dpright",
"turboA", "turboB"};
extern Config* g_config;
//********************************************************************************
// Joystick Device
jsDev_t::jsDev_t(void)
@ -155,6 +156,8 @@ void jsDev_t::init(int idx)
guidStr.assign(stmp);
FCEU_printf("Added Joystick: devIdx:%i name:'%s' GUID:'%s'\n", idx, name.c_str(), guidStr.c_str() );
// If game controller, save default mapping if it does not already exist.
if (gc)
{
@ -360,7 +363,7 @@ int GamePad_t::init(int port, const char *guid, const char *profile)
portNum = port;
//printf("Init: %i %s %s \n", port, guid, profile );
FCEU_printf("GamePad[%i].init Requested: GUID:'%s' Profile:'%s' \n", port, guid, profile );
// First look for a controller that matches the specific GUID
// that is not already in use by another port.
@ -381,9 +384,12 @@ int GamePad_t::init(int port, const char *guid, const char *profile)
if (strcmp(jsDev[i].getGUID(), guid) == 0)
{
FCEU_printf("GamePad[%i].init Matched GUID to JS device %i \n", port, i );
setDeviceIndex(i);
if (loadProfile(profile, guid))
{
FCEU_printf("GamePad[%i].init Using default profile.\n", port );
loadDefaults();
}
break;
@ -407,9 +413,12 @@ int GamePad_t::init(int port, const char *guid, const char *profile)
if (jsDev[i].isGameController())
{
FCEU_printf("GamePad[%i].init Using JS device %i \n", port, i );
setDeviceIndex(i);
if (loadProfile(profile))
{
FCEU_printf("GamePad[%i].init Using default profile.\n", port );
loadDefaults();
}
break;
@ -421,8 +430,10 @@ int GamePad_t::init(int port, const char *guid, const char *profile)
// game controller, then load default keyboard.
if ((portNum == 0 || strnlen(profile, 1) > 0) && (devIdx < 0))
{
FCEU_printf("GamePad[%i].init Using keyboard device\n", port );
if (loadProfile(profile))
{
FCEU_printf("GamePad[%i].init Using default profile.\n", port );
loadDefaults();
}
}
@ -603,10 +614,16 @@ int GamePad_t::getMapFromFile(const char *filename, nesGamePadMap_t *gpm)
FILE *fp;
char line[256];
bool fileExists = QFile::exists( QString(filename) );
fp = ::fopen(filename, "r");
if (fp == NULL)
{
if (fileExists)
{
FCEU_printf("GamePad[%i]: Failed to open binding map from file: %s\n", portNum, filename);
}
return -1;
}
while (fgets(line, sizeof(line), fp) != 0)
@ -634,6 +651,8 @@ int GamePad_t::getMapFromFile(const char *filename, nesGamePadMap_t *gpm)
::fclose(fp);
FCEU_printf("GamePad[%i]: Loaded Button Binding Map from File: %s\n", portNum, filename);
return 0;
}
//********************************************************************************
@ -665,6 +684,7 @@ int GamePad_t::loadHotkeyMapFromFile(const char *filename)
if (fp == NULL)
{
FCEU_printf("Gamepad[%i]: Error: Failed to Load HotKey Map From File: %s\n", portNum, filename );
return -1;
}
deleteHotKeyMappings();
@ -775,6 +795,7 @@ int GamePad_t::loadHotkeyMapFromFile(const char *filename)
}
::fclose(fp);
FCEU_printf("Gamepad[%i]: Loaded HotKey Map From File: %s NumBindings:%zi\n", portNum, filename, gpKeySeqList.size() );
return 0;
}
//********************************************************************************
@ -925,7 +946,7 @@ int GamePad_t::saveCurrentMapToFile(const char *name)
output.append(name);
output.append(",");
output.append("config:");
sprintf( stmp, "%i,", c );
snprintf( stmp, sizeof(stmp), "%i,", c );
output.append(stmp);
for (i = 0; i < GAMEPAD_NUM_BUTTONS; i++)
@ -949,26 +970,26 @@ int GamePad_t::saveCurrentMapToFile(const char *name)
}
stmp[k] = 0;
//sprintf(stmp, "k%s", SDL_GetKeyName(bmap[c][i].ButtonNum));
//snprintf(stmp, sizeof(stmp), "k%s", SDL_GetKeyName(bmap[c][i].ButtonNum));
}
else
{
if (bmap[c][i].ButtonNum & 0x2000)
{
/* Hat "button" */
sprintf(stmp, "h%i.%i",
snprintf(stmp, sizeof(stmp), "h%i.%i",
(bmap[c][i].ButtonNum >> 8) & 0x1F, bmap[c][i].ButtonNum & 0xFF);
}
else if (bmap[c][i].ButtonNum & 0x8000)
{
/* Axis "button" */
sprintf(stmp, "%ca%i",
snprintf(stmp, sizeof(stmp), "%ca%i",
(bmap[c][i].ButtonNum & 0x4000) ? '-' : '+', bmap[c][i].ButtonNum & 0x3FFF);
}
else
{
/* Button */
sprintf(stmp, "b%i", bmap[c][i].ButtonNum);
snprintf(stmp, sizeof(stmp), "b%i", bmap[c][i].ButtonNum);
}
}
output.append(buttonNames[i]);
@ -1013,26 +1034,26 @@ int GamePad_t::saveCurrentMapToFile(const char *name)
stmp[k] = keyName[j]; k++; j++;
}
stmp[k] = 0;
//sprintf(stmp, "k%s", SDL_GetKeyName(fk->bmap[i].ButtonNum));
//snprintf(stmp, sizeof(stmp), "k%s", SDL_GetKeyName(fk->bmap[i].ButtonNum));
}
else
{
if (fk->bmap[i].ButtonNum & 0x2000)
{
/* Hat "button" */
sprintf(stmp, "h%i.%i",
snprintf(stmp, sizeof(stmp), "h%i.%i",
(fk->bmap[i].ButtonNum >> 8) & 0x1F, fk->bmap[i].ButtonNum & 0xFF);
}
else if (fk->bmap[i].ButtonNum & 0x8000)
{
/* Axis "button" */
sprintf(stmp, "%ca%i",
snprintf(stmp, sizeof(stmp), "%ca%i",
(fk->bmap[i].ButtonNum & 0x4000) ? '-' : '+', fk->bmap[i].ButtonNum & 0x3FFF);
}
else
{
/* Button */
sprintf(stmp, "b%i", fk->bmap[i].ButtonNum);
snprintf(stmp, sizeof(stmp), "b%i", fk->bmap[i].ButtonNum);
}
}
if ( i == 0 )
@ -1268,24 +1289,48 @@ int KillJoysticks(void)
return -1;
}
for (unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++)
{
GamePad[i].setDeviceIndex(-1);
}
for (n = 0; n < MAX_JOYSTICKS; n++)
{
jsDev[n].close();
}
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
FCEU_printf("Shutting down SDL joystick/gamepad subsystem\n");
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
s_jinited = 0;
return 0;
}
//********************************************************************************
void initGamepadBindings()
{
std::string device, prefix, guid, mapping;
for (unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++)
{
char buf[64];
snprintf(buf, sizeof(buf) - 1, "SDL.Input.GamePad.%u.", i);
prefix = buf;
g_config->getOption(prefix + "DeviceType", &device);
g_config->getOption(prefix + "DeviceGUID", &guid);
g_config->getOption(prefix + "Profile", &mapping);
GamePad[i].init(i, guid.c_str(), mapping.c_str());
}
}
//********************************************************************************
int AddJoystick(int which)
{
//printf("Add Joystick: %i \n", which );
if (jsDev[which].isConnected())
{
//printf("Error: Joystick already exists at device index %i \n", which );
//FCEU_printf("Error: Joystick already exists at device index %i \n", which );
return -1;
}
else
@ -1296,12 +1341,12 @@ int AddJoystick(int which)
if (jsDev[which].gc == NULL)
{
printf("Could not open game controller %d: %s.\n",
FCEU_printf("Could not open game controller %d: %s.\n",
which, SDL_GetError());
}
else
{
//printf("Added Joystick: %i \n", which );
//FCEU_printf("Added Joystick: %i \n", which );
jsDev[which].init(which);
//jsDev[which].print();
//printJoystick( s_Joysticks[which] );
@ -1313,12 +1358,12 @@ int AddJoystick(int which)
if (jsDev[which].js == NULL)
{
printf("Could not open joystick %d: %s.\n",
FCEU_printf("Could not open joystick %d: %s.\n",
which, SDL_GetError());
}
else
{
//printf("Added Joystick: %i \n", which );
//FCEU_printf("Added Joystick: %i \n", which );
jsDev[which].init(which);
//jsDev[which].print();
//printJoystick( s_Joysticks[which] );
@ -1339,7 +1384,7 @@ int RemoveJoystick(int which)
{
if (SDL_JoystickInstanceID(jsDev[i].getJS()) == which)
{
printf("Remove Joystick: %i \n", which);
FCEU_printf("Remove Joystick: %i \n", which);
jsDev[i].close();
return 0;
}
@ -1376,7 +1421,8 @@ int InitJoysticks(void)
{
return 1;
}
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
FCEU_printf("Initializing SDL joystick/gamepad subsystem\n");
SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
total = SDL_NumJoysticks();
if (total > MAX_JOYSTICKS)
@ -1390,6 +1436,10 @@ int InitJoysticks(void)
AddJoystick(n);
}
pollEventsSDL(); // Run event processing here to ensure that all joystick add events are processed.
initGamepadBindings();
s_jinited = 1;
return 1;
}

View File

@ -98,4 +98,6 @@ extern GamePad_t GamePad[4];
jsDev_t *getJoystickDevice(int devNum);
void initGamepadBindings();
#endif

View File

@ -21,6 +21,7 @@
/// \brief Handles emulation speed throttling using the SDL timing functions.
#include "Qt/sdl.h"
#include "Qt/NetPlay.h"
#include "Qt/throttle.h"
#include "utils/timeStamp.h"
@ -39,6 +40,7 @@ static const double Normal = 1.0; // 1x speed (around 60 fps on NTSC)
static uint32 frameLateCounter = 0;
static FCEU::timeStampRecord Lasttime, Nexttime, Latetime;
static FCEU::timeStampRecord DesiredFrameTime, HalfFrameTime, QuarterFrameTime, DoubleFrameTime;
static FCEU::timeStampRecord emuSignalTx, guiSignalRx, emuSignalLatency;
static double desired_frametime = (1.0 / 60.099823);
static double desired_frameRate = (60.099823);
static double baseframeRate = (60.099823);
@ -52,6 +54,9 @@ static double videoLastTs = 0.0;
static double videoPeriodCur = 0.0;
static double videoPeriodMin = 1.0;
static double videoPeriodMax = 0.0;
static double emuLatencyCur = 0.0;
static double emuLatencyMin = 1.0;
static double emuLatencyMax = 0.0;
static bool keepFrameTimeStats = false;
static int InFrame = 0;
double g_fpsScale = Normal; // used by sdl.cpp
@ -60,6 +65,8 @@ bool useIntFrameRate = false;
static double frmRateAdjRatio = 1.000000f; // Frame Rate Adjustment Ratio
extern bool turbo;
int NetPlayThrottleControl();
double getHighPrecTimeStamp(void)
{
double t;
@ -193,6 +200,11 @@ int getFrameTimingStats( struct frameTimingStat_t *stats )
stats->videoTimeDel.min = videoPeriodMin;
stats->videoTimeDel.max = videoPeriodMax;
stats->emuSignalDelay.tgt = 0.0;
stats->emuSignalDelay.cur = emuLatencyCur;
stats->emuSignalDelay.min = emuLatencyMin;
stats->emuSignalDelay.max = emuLatencyMax;
return 0;
}
@ -216,6 +228,34 @@ void videoBufferSwapMark(void)
}
}
void emuSignalSendMark(void)
{
if ( keepFrameTimeStats )
{
emuSignalTx.readNew();
}
}
void guiSignalRecvMark(void)
{
if ( keepFrameTimeStats )
{
guiSignalRx.readNew();
emuSignalLatency = guiSignalRx - emuSignalTx;
emuLatencyCur = emuSignalLatency.toSeconds();
if ( emuLatencyCur < emuLatencyMin )
{
emuLatencyMin = emuLatencyCur;
}
if ( emuLatencyCur > emuLatencyMax )
{
emuLatencyMax = emuLatencyCur;
}
}
}
void resetFrameTiming(void)
{
frameLateCounter = 0;
@ -225,6 +265,8 @@ void resetFrameTiming(void)
frameIdleMin = 1.0;
videoPeriodMin = 1.0;
videoPeriodMax = 0.0;
emuLatencyMin = 1.0;
emuLatencyMax = 0.0;
}
/* LOGMUL = exp(log(2) / 3)
@ -326,8 +368,14 @@ static int highPrecSleep( FCEU::timeStampRecord &ts )
int
SpeedThrottle(void)
{
if ( (g_fpsScale >= 32) || (NoWaiting & 0x01) || turbo )
bool isEmuPaused = FCEUI_EmulationPaused() ? true : false;
bool noWaitActive = (NoWaiting & 0x01) ? true : false;
bool turboActive = (turbo || noWaitActive || NetPlaySkipWait());
// If Emulator is paused, don't waste CPU cycles spinning on nothing.
if ( !isEmuPaused && ((g_fpsScale >= 32) || turboActive) )
{
//printf("Skip Wait\n");
return 0; /* Done waiting */
}
FCEU::timeStampRecord cur_time, idleStart, time_left;
@ -358,6 +406,16 @@ SpeedThrottle(void)
time_left = Nexttime - cur_time;
}
// If Emulator is paused, ensure that sleep time cannot be zero
// we don't want to waste a full CPU core on nothing.
if (isEmuPaused)
{
if (time_left.toMilliSeconds() < 1)
{
time_left.fromMilliSeconds(1);
}
}
if (time_left.toMilliSeconds() > 50)
{
time_left.fromMilliSeconds(50);
@ -368,7 +426,7 @@ SpeedThrottle(void)
{
InFrame = 0;
}
//fprintf(stderr, "attempting to sleep %Ld ms, frame complete=%s\n",
// time_left, InFrame?"no":"yes");
@ -447,6 +505,8 @@ SpeedThrottle(void)
//printf("Frame Delta: %f us min:%f max:%f \n", frameDelta * 1e6, frameDeltaMin * 1e6, frameDeltaMax * 1e6 );
//printf("Frame Sleep Time: %f Target Error: %f us\n", time_left * 1e6, (cur_time - Nexttime) * 1e6 );
}
NetPlayThrottleControl();
Lasttime = Nexttime;
Nexttime = Lasttime + DesiredFrameTime;
Latetime = Nexttime + HalfFrameTime;
@ -457,6 +517,7 @@ SpeedThrottle(void)
Nexttime = Lasttime + DesiredFrameTime;
Latetime = Nexttime + HalfFrameTime;
}
return 0; /* Done waiting */
}
@ -515,6 +576,64 @@ int CustomEmulationSpeed(int spdPercent)
return 0;
}
int NetPlayThrottleControl()
{
NetPlayClient *client = NetPlayClient::GetInstance();
if (client)
{
uint32_t inputAvailCount = client->inputAvailableCount();
const uint32_t tailTarget = client->tailTarget;
double targetDelta = static_cast<double>( static_cast<intptr_t>(inputAvailCount) - static_cast<intptr_t>(tailTarget) );
// Simple linear FPS scaling adjustment based on target error.
constexpr double speedUpSlope = (0.05) / (10.0);
double newScale = 1.0 + (targetDelta * speedUpSlope);
if (newScale != g_fpsScale)
{
double hz;
int32_t fps = FCEUI_GetDesiredFPS(); // Do >> 24 to get in Hz
int32_t T;
g_fpsScale = newScale;
hz = ( ((double)fps) / 16777216.0 );
desired_frametime = 1.0 / ( hz * g_fpsScale );
if ( useIntFrameRate )
{
hz = (double)( (int)(hz) );
frmRateAdjRatio = (1.0 / ( hz * g_fpsScale )) / desired_frametime;
//printf("frameAdjRatio:%f \n", frmRateAdjRatio );
}
else
{
frmRateAdjRatio = 1.000000f;
}
desired_frametime = 1.0 / ( hz * g_fpsScale );
desired_frameRate = ( hz * g_fpsScale );
baseframeRate = hz;
T = (int32_t)( desired_frametime * 1000.0 );
if ( T < 0 ) T = 1;
DesiredFrameTime.fromSeconds( desired_frametime );
HalfFrameTime = DesiredFrameTime / 2;
QuarterFrameTime = DesiredFrameTime / 4;
DoubleFrameTime = DesiredFrameTime * 2;
}
//printf("NetPlayCPUThrottle: %f %f %f Target:%u InputAvail:%u\n", newScale, desired_frameRate, targetDelta, tailTarget, inputAvailCount);
}
return 0;
}
/**
* Set the emulation speed throttling to a specific value.

View File

@ -62,8 +62,10 @@ static int s_fullscreen = 0;
static int noframe = 0;
static int initBlitToHighDone = 0;
#define NWIDTH (256 - (s_clipSides ? 16 : 0))
#define NOFFSET (s_clipSides ? 8 : 0)
#define NWIDTH (256 - (s_clipSides ? 16 : 0))
#define NOFFSET (s_clipSides ? 8 : 0)
#define NTSCWIDTH (301 - (s_clipSides ? 19 : 0))
static int s_paletterefresh = 1;
@ -168,7 +170,7 @@ void CalcVideoDimensions(void)
int iScale = nes_shm->video.xscale;
if ( s_sponge == 3 )
{
nes_shm->video.ncol = iScale*301;
nes_shm->video.ncol = iScale*NTSCWIDTH;
}
else
{
@ -264,7 +266,7 @@ int InitVideo(FCEUGI *gi)
int iScale = nes_shm->video.xscale;
if ( s_sponge == 3 )
{
nes_shm->video.ncol = iScale*301;
nes_shm->video.ncol = iScale*NTSCWIDTH;
}
else
{
@ -446,7 +448,7 @@ doBlitScreen(uint8_t *XBuf, uint8_t *dest)
if ( s_sponge == 3 )
{
w = ixScale*301;
w = ixScale*NTSCWIDTH;
bw = 256;
}
else
@ -494,8 +496,6 @@ doBlitScreen(uint8_t *XBuf, uint8_t *dest)
void
BlitScreen(uint8 *XBuf)
{
int i = nes_shm->pixBufIdx;
if (usePaletteForVideoBg)
{
unsigned char r, g, b;
@ -509,11 +509,18 @@ BlitScreen(uint8 *XBuf)
}
}
doBlitScreen(XBuf, (uint8_t*)nes_shm->pixbuf[i]);
if (consoleWindow != nullptr)
{
FCEU::autoScopedLock lock(consoleWindow->videoBufferMutex);
nes_shm->pixBufIdx = (i+1) % NES_VIDEO_BUFLEN;
nes_shm->blit_count++;
nes_shm->blitUpdated = 1;
int i = nes_shm->pixBufIdx;
doBlitScreen(XBuf, (uint8_t*)nes_shm->pixbuf[i]);
nes_shm->pixBufIdx = (i+1) % NES_VIDEO_BUFLEN;
nes_shm->blit_count++;
nes_shm->blitUpdated = 1;
}
}
void FCEUI_AviVideoUpdate(const unsigned char* buffer)

View File

@ -24,8 +24,6 @@ extern int dendy;
extern int pal_emulation;
extern bool swapDuty;
int LoadGame(const char *path, bool silent);
int CloseGame(void);
void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count);
uint64 FCEUD_GetTime();

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