Compare commits

...

364 Commits

Author SHA1 Message Date
rogerman 4ca5101f52 Cocoa Port: Fix a performance bug where OpenGL display views weren't fully DMA'ing the video frames directly from app to GPU as intended.
- This bug fix may improve video performance with certain configurations by up to 10%. (OpenGL display views only.)
2025-08-04 09:57:49 -07:00
rogerman 6715015cb6 Cocoa Port: Try to fix some potential issues with UI updates happening off the main thread. 2025-07-31 21:12:50 -07:00
rogerman 5cc55d60bd Cocoa Port: Correct the usage of the GL_UNPACK_CLIENT_STORAGE_APPLE switch in OpenGL display views. 2025-07-31 21:09:42 -07:00
rogerman cf5153d02d Cocoa Port: Fix building with "DeSmuME (Latest).xcodeproj" on older Xcode. (Regression from commit 445060a.) 2025-07-27 15:45:04 -07:00
rogerman e52e3963d0 GPU: Add AltiVec-accelerated functions for 2D layer compositing. (For PowerPC CPUs only.)
- This improves GPU performance by up to 25% on a PowerPC 970MP.
2025-07-25 17:37:55 -07:00
rogerman 2c4ff5fea6 GPU: CopyLineExpand() and CopyLineReduce() now respect the NEEDENDIANSWAP flag for 32-bit elements. 2025-07-25 13:24:45 -07:00
rogerman ff7ad435d6 Texture Handler: Fix incorrect alpha masking on 16-bit direct textures for AltiVec. 2025-07-24 17:41:21 -07:00
rogerman 40c035f986 GPU: Fix remaining issues with display capture giving incorrect colors on big-endian systems.
- This commit effectively reverts commit 6bcf70d, since this commit fixes the problem in the correct location this time.
2025-07-22 17:59:49 -07:00
rogerman f28dbbb5b3 GPU: Fix building for ARM NEON. (Regression from commit b6467fb.) 2025-07-22 15:44:28 -07:00
rogerman b6467fbd13 GPU: Begin transitioning 16-bit colors from the plain old u16 data type to the new Color5551 data type. 2025-07-22 15:00:20 -07:00
rogerman 12b4802a03 Refactor the union "COLOR" from GPU.h into types.h and rename it to "Color5551". This allows the union to be used in more places where appropriate. 2025-07-22 09:53:47 -07:00
rogerman 08394d33f9 GPU: Fix various graphical glitches on big-endian systems.
- Fix a bug where max bright down would display a red screen instead of a black screen when running in 18-bit or 24-bit color mode.
- Fix incorrect colors for various display capture scenarios.
- 15-bit to 18-bit and 15-bit to 24-bit color conversions now assume byte swapping. This improves 2D graphics performance by up to 5%.
2025-07-19 22:29:29 -07:00
rogerman 6bcf70dc6d Colorspace Handler: Fix RGBA8888 to RGBA5551 color conversions in AltiVec. 2025-07-19 18:53:07 -07:00
rogerman f03f8943a0 Cocoa Port: Fix HUD input coordinate colors on big-endian systems. (Regression from commit deef974.) 2025-07-19 18:28:30 -07:00
rogerman 39973c52bc matrix.h: AltiVec accelerated functions buffer_copy_or_constant_*() and buffer_copy_or_constant_*_fast() now respect the NEEDENDIANSWAP switch.
- Also do some code cleanup where appropriate.
2025-07-19 11:38:06 -07:00
rogerman e75b67043b Partially revert commit 0367d14. Looks like the algorithm for converting RGBA6665 to RGBA5551 colors in AltiVec doesn't need to be THAT accurate, so resimplify the algorithm again to pick up the speed. 2025-07-18 16:21:29 -07:00
rogerman 0367d1469d Colorspace Handler: Improve the accuracy of RGBA6665 to RGBA5551 color conversions in AltiVec.
- Also do some code cleanup where appropriate.
2025-07-15 16:40:27 -07:00
rogerman 66b525b8dc Video Filters: Separate all xBRZ custom texture upscaling code from the standard xBRZ code. 2025-07-15 14:06:00 -07:00
rogerman deef974c85 Cocoa Port: Fix a bug where HUD colors would fail to work when running on macOS Leopard or Snow Leopard.
- Also fix a bug on big-endian systems where HUD colors were being stored in the user defaults file in big-endian byte order instead of little-endian byte order.
2025-07-14 14:47:12 -07:00
rogerman 63114d0aa2 Fix texture upscaling on big-endian systems. 2025-07-12 20:25:09 -07:00
rogerman b962b925f5 Cocoa Port: Update CheatDatabaseViewer.xib to a file format that is compatible with Xcode 16. 2025-07-11 02:01:49 -07:00
rogerman 445060a0cc Cocoa Port: Update Xcode project files to reflect better build procedures.
- The main Xcode project disables Metal API Validation for Debug builds, since this seems to cause runtime issues on Xcode 16.
- The Xcode 3 project removes the git lookup build script for the PowerPC LLVM-Clang build, since the typical use case for this particular build won't have git commands available.
2025-07-11 01:43:54 -07:00
rogerman 557176faa3 Cocoa Port: Silence a compiler warning when building on older Xcode. 2025-07-11 00:45:08 -07:00
rogerman 266301a13a GPU: Vectorized mosaic rendering now uses an aligned working buffer, improving performance for SSE2 and AVX2. 2025-07-04 15:15:32 -07:00
rogerman e6500f2010 Silence even more compiler warnings. (Related to commits 2b40a2f and 22a833b.) 2025-07-04 15:00:20 -07:00
rogerman b23b8e7e6c Cocoa Port: Fix a bug where running OpenGL display views on modern macOS would fail. (Regression from commit a98c319.) 2025-07-04 14:46:30 -07:00
rogerman 22a833b52e Silence some more compiler warnings. (Related to commit 2b40a2f.) 2025-06-27 11:20:32 -07:00
rogerman d3ee4eaabb OpenGL Renderer: Fix rendering when a non-standard viewport is used. (Regression from commit 3db6d56. Fixes #902.) 2025-06-25 16:03:43 -07:00
rogerman 2b40a2f12c Take another pass at silencing a bunch of compiler warnings where appropriate.
Most warnings are related to the following:
- Integer precision loss from implicit conversion
- Non-virtual destructors for classes with virtual methods
- Replace the unsafe sprintf() function with the safer snprintf()
- Local variables shadowing
- Extraneous commas and semicolons

Not all of these warnings have been fixed yet,, since fixing the remaining warnings requires a deeper review of the code for a proper fix.
2025-06-24 19:33:17 -07:00
rogerman a98c319cdf Cocoa Port: Give OpenGL display windows more chances to acquire a hardware-accelerated context before falling back to Apple Software Renderer. 2025-06-24 17:23:30 -07:00
rogerman 81afd288cc Cocoa Port: Silence a whole bunch of compiler warnings. 2025-06-24 17:18:53 -07:00
rofl0r bd6a421c0c agg: don't leak non-const reference to const private member.
patch taken from NetBSD.
2025-06-24 12:23:15 +00:00
rofl0r 4ba1d73e22 CI: add mingw action 2025-06-24 12:23:15 +00:00
rofl0r c02fbdfd00 mingw Makefile: explicitly add C++ std
latest ubuntu's mingw defaults to C++17 which breaks things.
2025-06-24 12:23:15 +00:00
rofl0r b63741f24f fix crash in CommandLine constructor 2025-06-24 11:25:38 +00:00
rogerman 3a3531acd9 Oops! Forgot to commit a couple files for commit fe84b11. (Also related to commit 1754ab9.) 2025-06-24 04:13:51 -07:00
rofl0r 1754ab9181 fix build of mingw port (MicMode enum) 2025-06-24 11:07:59 +00:00
rofl0r e589cfef5c types.h: let mingw use regparm(3) calling convention for jit
this, together with the renaming done in the previous commit, fixes
the jit from crashing when compiled with mingw for x86.
2025-06-24 12:41:15 +02:00
rofl0r 6f5b0596c1 rename FASTCALL to DESMUME_FASTCALL
mingw's winnt.h uses FASTCALL for its own purposes, so depending on
the include order the code uses either mingw's definition, or the
one from types.h. that makes it almost impossible to reason which
definition ends up being used, even though it's of utmost importance
to have the jit perform correctly.
2025-06-24 12:41:15 +02:00
rofl0r 493c655478 asmjit: remove unused calling convention defines 2025-06-24 12:41:15 +02:00
rofl0r 48d4330b7d windows: add Makefile for mingw 2025-06-24 12:41:15 +02:00
rofl0r 687340d776 aviout.cpp: fix constructor use gcc dislikes
gcc chokes on this with:
aviout.cpp: In constructor 'NDSCaptureObject::NDSCaptureObject(size_t, size_t, const WAVEFORMATEX*)':
aviout.cpp:564:26: error: cannot call constructor 'NDSCaptureObject::NDSCaptureObject' directly
  this->NDSCaptureObject::NDSCaptureObject();
2025-06-24 12:41:15 +02:00
rofl0r 0bb15e2df8 inputdx.h: make compatible with mingw
we need to use the mingw-provided headers, otherwise we'll run into
linker errors later on.
2025-06-24 12:41:15 +02:00
rofl0r a44a1fcedb XAudio2.h: make compatible with mingw
mingw doesn't ship this header, so to make it compatible we have
to create the uuid symbols, otherwise we get the following link
errors:

sndxa2.o:sndxa2.cpp:(.text+0x35f): undefined reference to `_GUID const& __mingw_uuidof<IXAudio2>()'
sndxa2.o:sndxa2.cpp:(.text+0x366): undefined reference to `_GUID const& __mingw_uuidof<XAudio2>()'
2025-06-24 12:41:15 +02:00
rofl0r aaf73a711d snddx.cpp: use mingw-provided directx headers if applicable
otherwise we get link errors like:
snddx.o:snddx.cpp:(.text+0x556): undefined reference to `DXGetErrorDescription8A(long)@4'
snddx.o:snddx.cpp:(.text+0x563): undefined reference to `DXGetErrorString8A(long)@4'

this also gets rid of the previous workaround.
2025-06-24 12:41:15 +02:00
rofl0r 1e640464ee gdbstub_internal.h: fix build error with mingw
../../gdbstub/gdbstub_internal.h:36:25: fatal error: sys/socket.h: No such file or directory
2025-06-24 12:41:15 +02:00
rofl0r 763d42a4cb fatdir: fix build error with mingw
../../utils/libfat/fatdir.cpp:37:21: fatal error: sys/dir.h: No such file or directory
 #include <sys/dir.h>
                     ^
2025-06-24 12:41:15 +02:00
rofl0r 6727a633b8 ROMReader: fix build error with mingw
../../ROMReader.cpp: In function 'void* STDROMReaderInit(const char*)':
../../ROMReader.cpp:31:36: error: cannot convert 'stat*' to '_stat32*' for argument '2' to 'int _stat32(const char*, _stat32*)'
 #define stat(...) _stat(__VA_ARGS__)
                                    ^
2025-06-24 12:41:15 +02:00
rofl0r 5e5cd8971c resources.rc: use unix-style path names
mingw's windres chokes on backslashed path names, a CI run will show
whether MSVC's rc builder can deal with forward slashes, but typically
windows tools support both styles.
2025-06-24 12:41:15 +02:00
rofl0r bdea57936f resources.rc: fix build error with mingw-windres
i686-w64-mingw32-windres: resources.rc:2140: syntax error
i686-w64-mingw32-windres: preprocessing failed.
2025-06-24 12:41:15 +02:00
rofl0r ed4bed3899 unrar/strfn.cpp: fix build error with mingw
File_Extractor/unrar/strfn.cpp: In function 'wchar etoupperw(wchar)':
File_Extractor/unrar/strfn.cpp:135:21: error: 'toupperw' was not declared in this scope
   return(toupperw(ch));
                     ^
File_Extractor/unrar/strfn.cpp: In function 'int wcsicompc(const wchar*, const wchar*)':
File_Extractor/unrar/strfn.cpp:240:28: error: 'wcsicomp' was not declared in this scope
   return wcsicomp(Str1,Str2);
                            ^
2025-06-24 12:41:15 +02:00
rofl0r 5f9817a387 lua-engine.cpp: fix build error with mingw
../../lua-engine.cpp:1552:31: error: 'vscprintf' was not declared in this scope
  int len = vscprintf(fmt, list);
                               ^
2025-06-24 12:41:15 +02:00
rofl0r 34712c4faf ImageOut.cpp: add missing header
../../frontend/modules/ImageOut.cpp:30:56: error: 'malloc' was not declared in this scope
2025-06-24 12:41:15 +02:00
rofl0r 200590b8dc XAudio2.h: likewise 2025-06-24 12:41:15 +02:00
rofl0r 73c903f17e xma2defs.h: macro hack for mingw's lack of __out etc
directx/xma2defs.h:406:5: error: '__out' has not been declared

note that we have to undef the macros on leaving the header,
as these names are also used for some arguments in stdlibc++
headers.
2025-06-24 12:41:15 +02:00
rofl0r 5293890772 replay: fix use of anonymous struct members
this apparently is an extension of MSVC, and gcc disallows it.

replay.cpp: In function 'INT_PTR RecordDialogProc(HWND, UINT, WPARAM, LPARAM)':
replay.cpp:285:4: error: anonymous struct not inside named type
    };
    ^
In file included from /opt/mingw-w64/libexec/i686-w64-mingw32/include/minwindef.h:163:0,
                 from /opt/mingw-w64/libexec/i686-w64-mingw32/include/windef.h:,
                 from /opt/mingw-w64/libexec/i686-w64-mingw32/include/windows.h:69,
                 from replay.cpp:20:
replay.cpp:286:16: error: 'rtcMin' was not declared in this scope
    ZeroMemory(&rtcMin, sizeof(SYSTEMTIME));
                ^
replay.cpp:287:16: error: 'rtcMax' was not declared in this scope
    ZeroMemory(&rtcMax, sizeof(SYSTEMTIME));
                ^
2025-06-24 12:41:15 +02:00
rofl0r 2fe5ec51ef types.h: don't undef WINAPI for mingw
the undef leads to the __stdcall attribute being stripped from all
functions, which in turn causes the symbols to not be found at link
time, as stdcall symbols have different name mangling.
2025-06-24 12:41:15 +02:00
rofl0r 62f43c01b1 path.h: add mkdir macro for mingw
mingw only supports the one-argument form of old windows.

fsnitroView.cpp: In function 'BOOL ViewFSNitroProc(HWND, UINT, WPARAM, LPARAM)':
fsnitroView.cpp:285:31: error: too many arguments to function 'int mkdir(const char*)'
         mkdir(tmp.c_str(),0777);
                               ^
2025-06-24 12:41:15 +02:00
rofl0r 0706a32138 CWindow.h: fix build error with gcc
In file included from CWindow.cpp:19:0:
CWindow.h:288:33: error: invalid pure specifier (only '= 0' is allowed) before ' token
  virtual DWORD ThreadFunc()=NULL;
                                 ^
2025-06-24 12:41:15 +02:00
rogerman fe84b11d51 Fix building on Windows. (Regression from commit 03cca3a.) 2025-06-24 02:29:22 -07:00
rogerman 03cca3a800 Move initialization code and method body code out of the headers and into the cpp files where appropriate. (Related to commits 39bd7fa, bf208df, and 665cd2a.)
- Not only does this clean up the headers and (marginally) improve compile times, it also gets rid of any C++11 requirements.
- Update the copyright template in metaspu.cpp to match that of metaspu.h.
- Also silence a few compiler warnings here and there.
2025-06-24 01:56:38 -07:00
Link Mauve 665cd2a3bf Fix one more -Wreorder warning 2025-06-24 03:59:38 +02:00
Link Mauve bf208df81f Fix MSVC build in _ShowGpu initializers
“A default member initializer is not allowed for a member of an
anonymous struct within a union.”
2025-06-24 03:39:26 +02:00
rogerman 472fe89165 Fix building for the Cocoa port. (Regression from commit 38f6313.) 2025-06-23 17:19:10 -07:00
rogerman a9e86e68be Partially revert commit ecd4c16. types.h has never assumed the presence of cstdint. Let's remove this dependency to ensure compatibility regardless of compiler. 2025-06-23 17:16:45 -07:00
Link Mauve 39bd7fac68 Fix some -Wreorder warnings
Use C++11 member initialization, to avoid having to pointlessly reorder
initializations in the constructor.
2025-06-24 01:59:09 +02:00
rogerman 36ad64c79b Revert "AsmJit: Remove unused/standard features"
This reverts commit 56a8801575.

Let’s avoid modifying our vendored libraries unless absolutely necessary.

Signed-off-by: rogerman <rogerman@users.noreply.github.com>
2025-06-23 16:45:10 -07:00
Link Mauve ff5113f5ac Remove executable bit from source files 2025-06-24 01:27:20 +02:00
Link Mauve 02f3c32974 GTK frontend: Remove OSX support
The cocoa frontend is apparently much better, and the GTK one obviously
hasn’t even been built on maxOS in years.
2025-06-24 00:55:04 +02:00
Link Mauve ecd4c1642c Simplify integer type aliases
Always alias them from cstdint, as all compilers should support them.
2025-06-24 00:50:49 +02:00
Link Mauve 56a8801575 AsmJit: Remove unused/standard features
The casts through union were undefined behaviour (memcpy() should be
used instead), but they were unused so nothing bad happened.

_min() and _max() could be replaced with std::min() and std::max(),
whereas maxValue() could be replaced with std::numeric_limits<T>::max().

Once we migrate to C++20, bitCount() could also be replaced with
std::popcount() from <bits>.
2025-06-23 23:50:50 +02:00
Link Mauve 38f63130e2 Use explicit std:: prefix
Using `using std::*` made me wonder whether these types and functions
were from std, libc symbols, or custom ones.
2025-06-23 23:15:23 +02:00
zeromus 96805d7c27 winport - fix mojibake bug in configured path usage (mainly screenshots, fixes #910) 2025-05-28 00:35:27 -04:00
zeromus cdb9acdc4d fflush after printing ideas and nocash messages 2025-05-11 17:42:07 -04:00
zeromus 48fcb850de winport: fiddle with stdio redirection buffering 2025-05-11 17:40:24 -04:00
Link Mauve 1754c1851b Remove unused automake files
No idea why it hadn’t been removed yet.
2025-05-10 15:02:00 +02:00
Link Mauve ca272488c2 Remove the last remnants of the glade frontend
This one has never been full-fledged, but was still referenced in the
autotools build system.
2025-05-10 13:54:39 +02:00
thesource 8a26c971f2 Make enum for joystick input type for convenience 2025-04-21 13:27:47 +02:00
thesource e706f0a4de Fix windows build 2025-04-21 13:27:47 +02:00
thesource d2627ffbe5 Fix coords on finger touch/lift 2025-04-21 13:27:47 +02:00
thesource 07c444eb0c Linux/GTK: add support for gamepad touchpad -> touch screen input
translation
2025-04-21 13:27:47 +02:00
rogerman 6f1a63fe89 Cocoa Port: Support Automatic Graphics Switching, allowing the use of the integrated GPU to run video display windows. (Requires a dual-GPU MacBook Pro with Metal-capable GPUs.)
- While this results in a 20% performance loss for video display window functions (like video filters), this also dramatically extends battery life. To return to the old way of using the discrete GPU for video display windows, the user must disable Automatic Graphics Switching in their System Preferences.
- The Troubleshooting Window now correctly reports the emulated 3D renderer that is currently active, rather than the one that is selected in the GUI.
- Also fix a bug where creating a OpenGL 3D renderer's context would immediately fall back to Apple Software Renderer if context creation failed. Now, context creation falls back to Apple Software Renderer as the last resort, only after all other Core Profile contexts have failed.
2025-03-26 16:55:25 -07:00
rogerman 25356b70f1 GPU: Add some more optimizations hints in CopyLineExpand() for SSSE3. 2025-03-26 13:26:42 -07:00
rogerman 75766495f9 Cocoa Port: Add some missing file references to the Xcode 3 project. 2025-03-20 22:55:40 -07:00
rogerman 1091e69726 Cocoa Port: Fix a bunch of bugs related to moving windows between Retina and non-Retina displays. (Related to commit 2bc5b0d.) 2025-03-19 03:11:16 -07:00
rogerman f6e0feb13e Cocoa Port: Report which OpenGL renderer is actually selected for 3D rendering. (Debug mode only.) 2025-03-18 15:55:01 -07:00
rogerman 33754b706e Cocoa Port: Add support for performing OpenGL 3D rendering on the 2013 Mac Pro's second GPU.
- For OpenGL 3D rendering, this yields a performance improvement of 2% - 4%.
2025-03-17 17:03:35 -07:00
rogerman 50e39989f7 GPU: Do some small optimizations to SSE2 and AVX2. 2025-03-16 23:15:46 -07:00
rogerman c73a7ffe53 GPU: Add NEON-accelerated functions for 2D layer compositing. (For 64-bit ARM CPUs only.)
- This improves GPU performance by up to 20% on the Raspberry Pi 5, and up to 50% on Apple Silicon CPUs.
2025-03-16 16:23:21 -07:00
rogerman e2379a66d6 matrix.h: Fix const-correctness for some *_fast function parameters.
- In practice, this only affected compiling for NEON on certain compilers. Other SIMD ISAs should remain unaffected.
2025-03-16 16:13:12 -07:00
zeromus 5cd9d36bba
Merge pull request #888 from Morilli/fix-movie-commands
fix movie command flags not actually being OR'd together
2025-02-14 03:16:42 -05:00
Morilli b756ffb1e6 fix movie command flags not actually being OR'd together 2025-02-14 08:57:30 +01:00
zeromus bec2329653
Merge pull request #886 from Anonym271/master
Bugfix: MemROMReaderWrite not working for size=1
2025-02-11 16:55:35 -05:00
Anonym271 06bef8b560 Bugfix: MemROMReaderWrite was not working for 1 byte length because it
would copy the current mem's byte into the source buffer instead of the
opposite way.
2025-02-11 22:49:20 +01:00
rofl0r dfcd482933 fix couple of header names to work on case-sensitive file systems 2024-12-06 02:37:38 +01:00
rofl0r 8a4fd0a9cb arm_jit: fix build when LOG_JIT_LEVEL != 0 2024-12-06 02:37:38 +01:00
zeromus b022181a05
Merge pull request #867 from lifehackerhansol/libnds-v2
Minor fixes for libnds v2.0.0 release
2024-11-14 23:54:53 -05:00
lifehackerhansol ee39a36f20
cp15: add support for process ID 2024-11-14 20:47:47 -08:00
lifehackerhansol c1624b2b33
MMU: support 8-bit write to REG_IPCSYNC 2024-11-14 20:47:47 -08:00
Max Fedotov 1192bf6f2c
EGL: use eglGetPlatformDisplay if available (#865)
POSIX Ports: When acquiring an EGL context, try calling the client-specific eglGetPlatformDisplay() before falling back to the more generic eglGetDisplay(). Hopefully fixes #864.
2024-11-12 22:50:35 -08:00
thesource 2c7fac57ff port 0.5 GPU scaling increments/window sizes to GTK3 2024-11-06 22:43:22 +01:00
Max Fedotov 3b1989a9d9
GTK*: add gamepad hotplug support (#855)
* add gamepad hotplug support
* Get rid of nbr_joy
2024-11-04 19:32:07 +01:00
zeromus f51e19b19b
Merge pull request #860 from En-En-Code/oglgetdriverversion-fix
fix: null-terminate versionSubstring in OGLGetDriverVersion
2024-11-02 22:24:35 -04:00
En-En 6f1d4e1d5c fix: null-terminate versionSubstring in OGLGetDriverVersion 2024-11-02 18:09:49 +00:00
rogerman 6690a8cedd posix: Update the Code::Blocks project file to include the new files that commit efdd938 added. 2024-10-28 14:39:17 -07:00
rofl0r 7d6f0982c8 gtk2: add some more presets to winsize menu 2024-10-28 19:16:45 +00:00
rofl0r 0ec9d74c39 gtk2: allow 0.5 increments on gpu scale
since the window size menu offers those as presets, and at least a 0.5
fraction on the scale doesn't seem to cause any problems in my testing.
2024-10-28 19:14:08 +00:00
rofl0r 76a6935dc8 gtk2: backport GPU scaling feature
feature was originally added via PR #764 to the gtk3 frontend.

this makes it possible to run the scaling on the GPU, avoiding the
incredibly slow software scaling that's otherwise done via cairo
when view->window size is set to anything > 1.0.
note that the window size "scale" needs to be identical to the
chosen GPU scale factor, otherwise software scaling kicks in again.

unlike the scale setting in the CLI port, which simply upscales the
native NDS framebuffer in hardware, this setting scales up even
the actual 3D textures, resulting in a sharper image, at the cost
of higher CPU/GPU usage. a game using demanding 3D scenes, like
zelda phantom hourglass' intro scene, may be able to still trash
the FPS.

the original PR also reported issues when setting the GPU scale to
a fraction, therefore the increments are currently locked to 1.0.
2024-10-28 13:50:27 +01:00
rofl0r 3ddb2669a9 cli: fix boost input detection
until now, the boost key was hardcoded to 'o' even when the config
said otherwise, and not treated in case of a joypad at all.
when triggered with the o key, it even behaved differently than
the gtk ui - the boost wasn't released together with the key,
but only when pressed again, so it was more like a shortcut for
"disable fps limiter".

this change implements the desired outcome of the second part of PR #822,
but without introducing more hacks and relying on magic values.

closes #822
2024-10-28 11:32:43 +01:00
rofl0r 58bbe693e1 cli: fix joypad and keyboard config retrieval
because the GTK frontends use GDK keysyms, not SDL ones, - the former
are being stored in the config file and used by the GTK ui) -  a temporary
workaround was put into place 14 years ago: the loaded config values
were simply being overwritten with the hardcoded defaults.

this commit removes the overriding of the config, and introduces
a cli frontend specific section "SDLKEYS", which is written by the
GTK2 frontend upon a configuration change.
it tries to convert the GDK keycodes into SDL2 ones while doing so.

an alternative solution (involving less code changes) would have been
to do the conversion in the cli frontend, but that would require having
the gdk header available for compilation, which may not be the case
if the user only wants the cli frontend. such a user could now create
the config file on another machine with the GTK frontend, or simply
manually take the desired values from the SDL_keycode.h header.

this change is instigated by one of the changes in PR #822, which simply
removed the workaround and kept parsing on error, which mitigated the
problem for some keys, but not all.
2024-10-28 11:32:43 +01:00
rofl0r 0a36e96f66
Merge pull request #845 from thesourcehim/master
[GTK*] Some gamepad input rework

- Unbind gamepad keys by default. The default bindings may fit one gamepad model but work weirdly with another causing issues like [LINUX/GTK3] Whitescreen freeze when pressing square on ds4 #834
- Use non-blocking method to obtain gamepad keys/axes during configuration to avoid visible emulator freeze and possible deadlock (see [linux] editing controlls sometimes (often) freezes the emulator #843)

closes #834
closes #843
2024-10-27 11:51:24 +01:00
thesource 5d498a97c4 Port previous two changes to gtk2 frontend. Add meson option to build
gtk2 frontend (disabled by default). Fix meson.build dependency for
gtk2.
2024-10-26 13:29:48 +03:00
zeromus fff5659879
Merge pull request #851 from dlbuhtig4096/master
Fix ensata sound register emulation.
2024-10-26 02:27:43 -04:00
En-En efdd938dc3
GTK*: Action Replay cheat menu (+ other cheat improvements) (#847)
* GTK cheats UI inputs/displays hex for address (offset)

* Added range bound to keep internal cheat data within specified size
The decision to change the value column to store G_TYPE_UINT is purely pragmatic--having all data be treated and displayed as unsized is simpler than writing a custom display to handle signedness and cleaner than 1-3 byte ints appearing unsigned and 4 byte int appearing signed.

* Added index and cheat type data to ListStore
My implementation plan is to use a GtkTreeModelFilter to create separate section for internal and ActionReplay cheats, but I was not convinced the indices in the tree path would correspond to the indices in , hence the additional column.

* Filter raw and AR cheats, display both filters in UI, patch up raw update/delete

* Action Replay UI elements [GTK]

* Memory leak fixes
+ some additional clean-up comments and small bug patches

* Backport to GTK2
2024-10-25 20:32:03 +02:00
dlbuhtig4096 ff84815acb Improve console allocation. 2024-10-24 19:20:24 +08:00
dlbuhtig4096 28f5c76035 Proper ensata handshake on reconnection. 2024-10-20 21:27:03 +08:00
dlbuhtig4096 7984eae357 Fix ensata sound register emulation. 2024-10-20 13:03:03 +08:00
Roger Manuel 2bc5b0d86b
Merge pull request #846 from BayLee4/fix_retina
Cocoa Port: Fix mixed retina/non-retina display touchscreen bug
2024-10-10 12:48:59 -07:00
BayLee4 a0386e535c Cocoa Port: Fix mixed retina/non-retina displays bug 2024-10-10 17:57:21 +02:00
thesource 72315fa339 Make gamepad key configuration non-blocking 2024-10-10 11:42:27 +03:00
thesource 1cf7c37896 Unbind joypad keys by default 2024-10-10 09:44:09 +03:00
zeromus 8fa0affab1
Merge pull request #839 from intra0/master
Update org.desmume.DeSmuME.metainfo.xml
2024-10-04 21:31:38 -04:00
zeromus e7442cc999
Merge pull request #841 from lifehackerhansol/cmdline-misleading-indentation
commandline: avoid misleading indentation
2024-10-01 05:43:24 -04:00
lifehackerhansol fa1879f9a7
commandline: avoid misleading indentation 2024-09-29 13:45:34 -07:00
intra0 bb1b6a1c80
Update org.desmume.DeSmuME.metainfo.xml
the current flatpack version is commit 640a1fdd93

was 2 years ago but is a 9.14 version
2024-09-25 21:54:14 -05:00
zeromus 91196788eb fix more screw-ups in unicode support. fixes #828 2024-08-31 22:34:38 -04:00
rogerman 8f9c6892d5 OpenGL Renderer: Fix an initialization issue with the clear image shader program when running the 3.2 Core Profile renderer for a driver that only supports OpenGL v3.2. (Regression from commit e2a25e2. Fixes #827.) 2024-08-28 10:33:27 -07:00
zeromus 42667020d8 fix ensata emulation? (re: #184) 2024-08-27 04:15:00 -04:00
rogerman 64132f765a OpenGL Renderer: Fix a bug where having Edge Mark enabled could cause fragments to disappear. (Regression from commit f910c61.) 2024-08-22 19:26:39 -07:00
rogerman 00b8df1b00 OpenGL Renderer: Add entry point for glClientWaitSync, fixing compiling on Windows. (Regression from commit f910c61.) 2024-08-15 17:50:53 -07:00
rogerman f910c6197c OpenGL Renderer: Add new rendering resource classes, and do some misc. refactoring.
- Using the new OpenGLGeometryResource and OpenGLRenderStatesResource classes, the 3.2 Core Profile and ES renderers now use triple-buffering for all geometry rendering resources and framebuffer constants.
- Delete the InitFinalRenderStates() method, which has been obsoleted over the years. Its functionality has been rolled into the InitExtensions() and _RenderGeometryLoopBegin() methods.
2024-08-15 16:49:42 -07:00
rogerman f84a804499 OpenGL Renderer: Fix bug where clear images were Y-flipped. (Regression from commit 3db6d56.) 2024-08-13 19:49:34 -07:00
rogerman 8197174d69 OpenGL ES Renderer: Fix a bug where the final output framebuffer is Y-flipped. (Regression from commit 3db6d56.) 2024-08-12 13:44:58 -07:00
rogerman 3db6d5676c OpenGL Renderer: Do some more code cleanup and tune-ups.
- In the 3.2 Core Profile and ES renderers, synchronization of vertex info uploads now occurs at a more reasonable time.
- Geometry rendering is now Y-flipped by default, eliminating the need to Y-flip the final output framebuffer under all conditions.
- Legacy OpenGL no longer needs to perform any color conversion of the final output framebuffer if FBOs are supported.
- Rename some functions and variables to better describe what things are doing now.
2024-08-12 11:23:23 -07:00
rogerman 9bbfca527a Remove redundant and currently unused Makefile. 2024-08-10 15:53:25 -07:00
rogerman 04f97d5755 OpenGL ES Renderer: Fix a major performance bug on many ARM-based mobile devices with integrated GPUs. 2024-08-10 15:06:30 -07:00
rogerman ea648f7110 OpenGL Renderer: Do some minor tune-ups.
- Remove some methods in OpenGLRenderer_2_0 and OpenGLRenderer_2_1 that have negligible contribution to either performance or code simplicity.
- OpenGLRenderer_1_2, OpenGLRenderer_2_0, and OpenGLRenderer_2_1 are now instantiated with their specific variant IDs.
- Calls to malloc_alignedCacheLine() have been replaced with the more appropriate malloc_alignedPage().
- Do some misc. code cleanup.
2024-08-10 13:48:13 -07:00
rogerman c75c1ce2c3 Linux Ports (All): Update Autotools and Meson scripts to add JIT support for ARM targets.
- Also fixes build errors related to explicitly building SIMD files for colorspacehandler. Don't do it! The proper way is to simply include "colorspacehandler.cpp" alone and let the compiler's preprocessor macros determine which SIMD file to use.
2024-08-09 12:55:13 -07:00
rogerman 2e01c0a840 Linux Ports (All): Update the Code::Blocks project file to add build targets for AArch64. Also do some other misc. updates.
- Release builds now use -Ofast optimization instead of -O3.
- Release builds no longer strip their symbols. This will be needed for profiling and debugging.
2024-08-08 17:34:26 -07:00
rogerman b799d94762 Colorspace Handler: Fix compiling for strict NEON.
- We could always use -flax-vector-conversions, but let's try to stay disciplined for now.
2024-08-08 12:11:20 -07:00
rogerman 176e38ce2f OpenGL Renderer: Simplify the code by removing the references to multiple output shaders, since commit 0c7cb99 has obsoleted them. 2024-08-07 12:20:35 -07:00
rogerman c5ab8a6ef6 OpenGL ES Renderer: Fix a bug where RGBA6665 color output would fail. (Regression from commit de9fc5a.)
- Also update some comments.
2024-08-06 23:48:54 -07:00
rogerman de9fc5ab75 OpenGL Renderer: Remove the additional FBOs that were introduced in commits 60385bd, 8b5ac56, and 3ef9271 in an attempt to fix rendering on old GPUs like the Intel HD 4000. (Fixes #820.) 2024-08-06 21:54:39 -07:00
rogerman 5baeb02754 Cocoa Port: Fix OpenGL context creation on older macOS. 2024-08-03 16:15:02 -07:00
rogerman d7dcc85d87 GTK / GTK2 Ports: EGL contexts running legacy OpenGL no longer require the EGL_KHR_surfaceless_context extension. 2024-08-03 11:14:55 -07:00
rogerman 79f3f94099 GTK2 Port: Set the audio volume in the same way as the GTK port so that the audio volume is consistent between the two ports. 2024-08-03 10:13:41 -07:00
rogerman 9aa2ddfc88 Linux Port (GTK/GTK2): Remove the requirement for libGLX.so when requesting a GLX context since libGL.so is all we need here.
- Also do some minor code cleanup in glx_3Demu.cpp
2024-08-02 12:10:21 -07:00
rogerman 4427b863ad Linux Port (GTK/GTK2): Fix compiling in glx_3Demu.cpp.
- Also fix a typo in egl_3Demu.cpp
2024-08-01 23:02:58 -07:00
rogerman 15f5b169cc Video Filters: Improve performance of Deposterize and XBRZ CPU-based filters. (Based on PR #631.)
- Special thanks to @m42a for the inspiration on this code!
2024-08-01 21:07:24 -07:00
rogerman be51e41c04 Ugh, let's try fixing the last stubborn Meson build script... 2024-08-01 18:00:54 -07:00
rogerman 46990f2d85 Fix some issues with Meson build scripts. (Regression from commit ca566eb.) 2024-08-01 17:51:12 -07:00
rogerman ca566eb11b OpenGL Renderer: Finalize all renderer-client integration to "just work".
- These changes now presume that standard OpenGL and OpenGL ES are mutually exclusive. We will NOT support running a standard OpenGL context and an OpenGL ES context in the same process.
- Clients must explicitly request supporting the OpenGL 3D renderer in their build configuration. Build configurations must define ENABLE_OPENGL_STANDARD (replacing the HAVE_OPENGL macro) or ENABLE_OPENGL_ES. If neither macro is defined, then the OpenGL 3D renderer will be assumed unavailable.
- Meson and Autotools now use better header/library checks for OpenGL functionality with their associated context type.
- Add a new Code::Blocks project file that can make builds for CLI, GTK, and GTK2.
- GTK and GTK2 ports now have the option to run a legacy OpenGL context, a 3.2 Core Profile context, or simply choosing the best context automatically like before.
- GTK and GTK2 ports have GLX and EGL as new context types. OSMesa and SDL have been updated to the latest design pattern.
- GTK and GTK2 ports can now be configured (via Meson or Autotools) to use a GLX, OSMesa, EGL, or SDL context.
- OSMesa contexts are now marked as deprecated. I don't know of anyone who still uses them, and I've never been able to get it to work correctly for years. Now that we have GLX contexts for compatibility purposes, OSMesa contexts are now completely redundant.
- Fix a bug with the GTK port where ancient GPUs without FBO support can still run framebuffers at custom sizes.
- For POSIX ports, move all "avout" and context creation files to the "shared" directory for better file organization.
2024-08-01 17:08:01 -07:00
rogerman 0a78fa2a2b OpenGL Renderer: Fix a few bugs here and there.
- Fix a compiling bug for ES due to missing tokens.
- Fix Fog and Edge Mark feature availability when running legacy OpenGL. (Regressions from commit 0c7cb99 and commit 8b5ac56.)
- glDrawBuffer() now determines its own algorithm at runtime instead of at compile time. This change is being done to be consistent with all of the other Standard vs ES changes.
2024-08-01 00:11:05 -07:00
rogerman 2f177d19a2 Cocoa Port: Update OpenGL renderer integration code to reflect current design patterns. 2024-07-26 14:56:36 -07:00
rogerman 4c90c2d9ee OpenGL ES Renderer: Finalize the last remaining bug fixes so that the ES renderer can work "out of the box".
- Respect the draw buffers ordering rules that are unique to ES.
- Report the actual OpenGL variant being requested when initializing the renderer.
- Add oglrender_deinit() function pointer so that clients can properly handle the destruction of their associated context resources at the correct time.
- Certain internal OpenGL info is now assigned at run time instead of at compile time. This change now allows any of the OpenGL renderers to run side-by-side.
2024-07-26 11:10:50 -07:00
rogerman d6532b9e91 OpenGL ES Renderer: Fix TBO-based polygon state uploading. 2024-07-24 15:28:56 -07:00
rogerman d58c0e9331 OpenGL Renderer: Oops! Fix a compiling issue introduced in commit e2a25e2. 2024-07-23 21:39:07 -07:00
rogerman e2a25e2412 OpenGL Renderer: Fix various rendering bugs.
- Fix a potential unaligned access crashing bug in ES when clear images are to be rendered.
- Fix an ES bug where clear images would fail to render when MSAA is enabled.
- Fix a legacy OpenGL bug where toon table colors were not ignoring their alpha bit, according to GBATEK.
2024-07-23 21:28:15 -07:00
rogerman f323dc464f Windows Port: Fix bug where the OpenGL 3D renderer would fail to initialize at program startup. (Regression from commit 76fe5f7. Fixes #815.) 2024-07-22 22:47:29 -07:00
zeromus 8e77a8d9f1
Merge pull request #818 from cyanea-bt/windows_paths
Windows Port: Fix empty defaults for path settings
2024-07-22 19:43:37 -05:00
cyanea-bt 5754425458 Windows Port: Fix empty defaults for path settings.
(Regression from commit 3511e14. Fixes #817.)
2024-07-23 01:57:59 +02:00
rogerman 12ed7dd054 Colorspace Handler: Fix alpha detection logic in ColorspaceConvert5551To8888_*() and ColorspaceConvert5551To6665_*(). 2024-07-21 21:02:50 -07:00
rogerman 368cd49fb6 OpenGL Renderer: Tighten up some code related to clear image. 2024-07-20 22:54:44 -07:00
rogerman 3ef927100b OpenGL Renderer: Fix some longstanding graphical glitches related to running Edge Mark and Fog with MSAA.
- These graphical glitches are resolved only when running 3.2 Core Profile with the GL_ARB_sample_shading extension, available on all modern GPUs.
- Do some minor optimizations to the Edge Mark and Fog shaders.
- Also fix an FBO attachment bug in legacy OpenGL that was introduced in commit 8b5ac56.
2024-07-20 20:49:44 -07:00
rogerman 8b5ac56d66 OpenGL Renderer: More FBO rework. 2024-07-19 14:38:05 -07:00
rogerman 60385bd099 OpenGL Renderer: Rework how the output framebuffers work.
- The output framebuffers now bind their own FBOs rather than changing draw targets with glDrawBuffer().
- Rework the general FBO management.
- Legacy OpenGL now outputs native RGBA color if FBOs are supported. This should give a minor performance increase on older GPUs.
- The fixed-function pipeline can now flip the framebuffer on GPU. This greatly reduces the CPU usage when doing the final color conversion and gives a significant performance increase on ancient GPUs.
2024-07-18 21:45:00 -07:00
rogerman 811e1de45e OpenGL Renderer: Oops! Roll back some internal test code that accidentally slipped into commit 0c7cb99. 2024-07-18 12:46:11 -07:00
rogerman 3e650f2f73 OpenGL Renderer: Add entry point for glBlendColor, fixing compiling on Windows. (Regression from commit 0c7cb99.) 2024-07-18 12:26:53 -07:00
rogerman 0c7cb99d78 OpenGL Renderer: Greatly simplify the fog rendering pass.
- There is no more need to switch to the working texture as the destination for the fog output. This change will be essential for future commits.
- The dual-source blending method has been obsoleted and removed.
- FBOs are no longer required for the fog feature, easing requirements for ancient GPUs.
- Ancient GPUs may see a small performance benefit due to shader simplification.
2024-07-18 12:17:25 -07:00
rogerman 70fef83ded OpenGL Renderer: Fix bug when the screen wasn't being cleared properly when no polygons are being sent to the renderer. (Regression from commit 241ca96.) 2024-07-16 16:15:47 -07:00
rogerman ff9231bb34 OpenGL Renderer: 16-bit texture data that is converted to 32-bit is now byte-swapped correctly on big endian systems. 2024-07-15 23:09:53 -07:00
rogerman ab1d37a44f Colorspace Handler: Fix compiling on AltiVec systems. (Regression from commit 586aea5.) 2024-07-15 23:07:24 -07:00
rogerman cc0b3ed00d Cocoa Port: Update the OpenGL blitter code to reflect the current code pattern in OGLRender.h.
- Centralize all header includes into OGLDisplayOutput.h.
- Update all extension versions of OpenGL functions/tokens that would be core in OpenGL v1.5.
2024-07-15 16:52:43 -07:00
rogerman 80694cd966 OpenGL ES Renderer: More ES fixes.
- Change the remaining FBO attachments that I missed the last time to use RGBA8 internal format.
- Fix picky ancient drivers that won't accept GL_RED as a texture internal format. It has been changed to GL_LUMINANCE.
- Fix picky ES drivers that demand that the external format used in both glTexImage2D() and glTexSubImage2D() are exactly the same.
- OpenGL ES doesn't support GL_UNSIGNED_SHORT_1_5_5_5_REV for texture data, and GL_UNSIGNED_SHORT_5_5_5_1 is incompatible with our data. So instead, all 16-bit data will be converted to 32-bit LE before uploading it via the textures, and such ES textures will now take GL_UNSIGNED_BYTE format.
- Remove the #include for EGL/egl.h in OGLRender.h, since EGL shouldn't exist at this level of the code stack.
2024-07-15 16:45:21 -07:00
rogerman 586aea5310 Colorspace Handler: Add new functions for 16-bit to 18-bit and 32-bit color conversion, now respecting the 16-bit color's alpha bit.
- ColorspaceConvert5551To8888()
- ColorspaceConvert5551To6665()
- ColorspaceConvertBuffer5551To8888()
- ColorspaceConvertBuffer5551To6665()
- Also rename the existing 16-bit color conversion functions to help further distinguish the functions from one another.
2024-07-15 16:24:02 -07:00
Roger Manuel 4b0805e139
Windows Port: Fix yet another compiling issue related to the OpenGL context. (Fixes #811.) 2024-07-15 10:00:38 -07:00
rogerman 15a6e51739 OpenGL Renderer: Add support for Fog, Edge Mark, and on-GPU framebuffer color conversion for ancient GPUs that have support for shaders and FBOs, but lack support for GL_EXT_framebuffer_blit. 2024-07-14 19:38:29 -07:00
rogerman de62116cc8 Windows Port: Fix OpenGL renderer init failure. (Regression from commit 76fe5f7. Fixes #810.) 2024-07-14 17:22:47 -07:00
rogerman 241ca96cf1 OpenGL Renderer: Fix issues that would throw a GL error.
- glTexParameteri() with GL_TEXTURE_2D_MULTISAMPLE throws INVALID_ENUM when trying to assign a sampler-related state, so these calls have been removed.
- glMapBufferRange() throws GL_INVALID_OPERATION if the buffer size is 0, so check for this condition first.
2024-07-13 10:43:04 -07:00
rogerman aaf88d9f14 OpenGL ES Renderer: More ES tune-ups.
- Any ES-specific error messages are now reported as "OpenGL ES" instead of "OpenGL".
- Explicitly declare the internal format of all textures and RBOs used as FBO attachments as "GL_RGBA8" instead of the generic "GL_RGBA". This may fix some extremely picky ES drivers that would throw GL_INVALID_ENUM if we don't use a sized internal format.
- Hard code the read pixels format as GL_RGBA and the read data type as GL_UNSIGNED_BYTE. It is meaningless to rely on GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE since we are reading from our own FBOs that are hard coded to GL_RGBA8 format.
- Require that OpenGL ES contexts support the GL_OES_surfaceless_context extension, since we are doing offscreen rendering strictly on FBOs only. This extension has been around for a very long time, and so this serves as a kind of compatibility check.
2024-07-12 15:41:09 -07:00
rogerman d480f95d79 Cocoa Port: Fix yet another crash-on-exit bug that could happen when running on an older system. 2024-07-12 12:00:49 -07:00
SimonAfek dd88556d53
CI: update github workflows (#809)
* Update macOS version in build_interface.yml

* Typo fixes in build_interface.yml

* build.yml: Update runner images

* build.yml: Update deprecated actions

* build_interface.yml: Update runner images

* build_interface.yml: Update deprecated actions

* build_interface.yml: Remove unnecessary packages from macOS "brew install" line to address warnings

* build_win.yml: Update runner image + remove vs-version parameter from setup-msbuild action

* build_win.yml: Update deprecated actions
2024-07-11 17:38:52 +02:00
rogerman 00dd6fb97a OpenGL ES Renderer: Use the proper ES extension header, and also avoid double #defining some of the tokens. 2024-07-10 21:53:49 -07:00
rogerman bb3011c262 OpenGL Renderer: Return to a more traditional method of doing texture reads in shaders, effectively removing dependent texture reads where appropriate.
- This change won't affect standard OpenGL on a desktop PC, but may improve performance on lesser GPUs trying to run OpenGL ES.
2024-07-10 16:01:13 -07:00
rogerman 86a29d768a OpenGL ES Renderer: Do some minor changes/fixes.
- Fix a bug where _isShaderFixedLocationSupported wasn't being set to true, causing shaders to fail.
- OpenGL version checks now account for non-compliant ES drivers that contain text before the version number.
- Manually set the default read/draw buffers for all FBOs upon creation. We shouldn't need to do this, since they should always be set later, but just in case...
- Add missing GL_BGRA macro.
- Tidy up the OpenGL naming in some error strings.
2024-07-10 13:59:02 -07:00
rogerman 3a6f2f6dc5 OpenGL ES Renderer: Add a new OpenGL ES 3.0 renderer. 2024-07-09 23:00:27 -07:00
rogerman 0e88f9aa94 OpenGL Renderer: Final changes for OpenGL ES compatibility. 2024-07-09 22:03:33 -07:00
rogerman 384854f6e7 OpenGL Renderer: More updates to the 3.2 Core Profile renderer to be more cross-compatible with OpenGL ES 3.0.
- Add support for fixed locations in shaders for OpenGL 3.3 and later.
- The fog density table texture is now a 2D texture instead of a 1D texture.
- Fix a memory leak where the polygon state texture wasn't being deleted upon the destruction of the OpenGLRenderer object.
2024-07-09 01:18:50 -07:00
rogerman 7dbece1082 OpenGL: Do some minor changes to the 3.2 Core Profile renderer to make it more cross-compatible with OpenGL ES 3.0.
- PBO handling now works via glMapBufferRange() instead of glMapBuffer().
- Polygon states can now be uploaded using plain integer textures. 64k UBOs and TBOs are no longer required.
2024-07-06 16:20:53 -07:00
rogerman 09090e93f9 GFX3D: Change POLYLIST_SIZE to 16384 to ensure proper memory alignment with buffers based on CLIPPED_POLYLIST_SIZE and VERTLIST_SIZE. 2024-07-06 13:58:05 -07:00
rogerman c962c550e7 OpenGL: Handle legacy functions and tokens more gracefully for OpenGL variants that may not have them. 2024-07-05 18:13:43 -07:00
rogerman 76fe5f758c OpenGL: More changes in preparation of OpenGL ES.
- Slightly change the names of attachment defines so that they can be distinguished from the native OpenGL attachment defines.
- The minimum version driver check now accounts for OpenGL ES.
- OpenGLRendererCreate() can now handle any possible OpenGL variant, as declared in the OpenGLVariantID enum.
- Framebuffer read backs may now assigned their format and data type. (Legacy OpenGL assigns the format as GL_BGRA, while 3.2 Core Profile assigns the format as GL_RGBA.)
2024-07-03 16:55:47 -07:00
rogerman ba56bbc7c2 OGLRender_3_2.cpp... try again... 2024-07-03 13:05:43 -07:00
rogerman 3ec0b0c2e1 OpenGL: Continue preparation for adding OpenGL ES. (Related to commit 086980d.) 2024-07-03 13:01:17 -07:00
rogerman fc6ff8edbd GPU: Fix a bug on big-endian systems where setting the backdrop color could cause a crash. 2024-07-02 01:35:10 -07:00
rogerman fe0ae83c40 Cocoa Port: Fix a longstanding, yet rare, crash that may occur when quitting the app. 2024-07-02 00:16:46 -07:00
rogerman d4163a1893 OpenGL: Fix building on Windows and Linux. (Regression from commit 086980d.) 2024-07-01 16:26:46 -07:00
rogerman 086980deaf OpenGL: Start reorganizing stuff in preparation for adding new OpenGL variants, such as OpenGL ES.
- All platform-specific header includes are now centralized in OGLRender.h.
- Remove all ARB and EXT versions of legacy functions (everything pre 3.0). Legacy functions now only reference their core versions.
- Do a some minor code cleanup.
2024-07-01 16:19:05 -07:00
rogerman 76bd1a5e35 Change line-ending style in OGLRender.h from Windows-style CRLF to Unix-style LF. 2024-06-29 14:50:47 -07:00
rogerman 6309a9c6a7 libretro: So apparently, _XOPEN_SOURCE has to be at the top of the file. Hopefully this makes both GCC14 users and Mac users happy. (Related to commit 779606e. Based on PR #793.) 2024-06-07 17:16:53 -07:00
rogerman 779606ec2f libretro: Fix building on Mach-based operating systems, otherwise known as Mac OS X and modern macOS (regression from commit 90d0abd). Based on PR #793. 2024-06-07 16:33:13 -07:00
zeromus ffb8666a8f winport - plumb S9X_JOY_NEUTRAL through inifile:
[Controls]
DigitalizationThreshold=50
2024-06-07 00:24:55 -04:00
zeromus ff6c33a8d6 winport - reduce joystick digitalization threshold from 60% to a more normal 50%. With a too-high threshold, it's impossible to specify diagonals. This is preferable for games without diagonals (else you accidentally crouch when you just meant to walk to the side) instead of 8-way games, so we have to be pretty aggressive about the threshold. But 50 is the more normal choice. 2024-06-07 00:18:09 -04:00
zeromus 90d0abdae0
Merge pull request #792 from atsampson/xopen-strdup
libretro-common: fix implicit declarations
2024-05-13 07:59:48 -05:00
Adam Sampson 738298a9e8 libretro-common: fix implicit declarations
strdup and realpath are only declared by glibc's headers if
_XOPEN_SOURCE >= 500.
2024-05-13 12:47:10 +01:00
zeromus 4a53a30b91 winport - fix bug where desmume would create working directory using some wrong locale encoding and produce a Pok魯n directory instead of using the Pokémon that was already there (fixes #791) 2024-05-12 21:33:49 -04:00
rofl0r 9515af82b2
add an issue template for github (#784) 2024-04-12 21:39:12 +02:00
rogerman bae67e2d0c GPU: Implement the DISPCNT register's ForceBlank bit by clearing the line to white if the ForceBlank bit is set. (Fixes #775.) 2024-03-02 15:18:51 -08:00
Max Fedotov 0a6eca6dce
GTK: hybrid layout support (#773)
* GTK: hybrid layout support
* Fix HUD with new layouts
* Simplify rotoscaled_hudedit logic a bit
2024-02-26 19:12:50 +00:00
Max Fedotov 45738beb88
GTK: make OSD scalable (#769)
* gtk: make OSD scalable

* Scale save slot indicator (oops), make text outlines look smoother, use
larger font when not scaling

* Save and load HUD layout, prefer raster font on low resolution, select
vector font size close to raster one, make OSDCLASS::scale floating point

* Build fix

* Add reset HUD layout action, only require fontconfig if libagg is found.

* Try another font in case we could not locate monospace

* Detect screen bytes per pixel instead of hardcoding it, define
AGG2D_USE_VECTORFONTS if fontconfig is found.

* Different pixel formats are handled by different draw target
implementations
2024-02-14 08:20:57 +00:00
zeromus 6508c2b115 placate -Werror=format-security (probably) (re: #768) 2024-02-01 04:26:38 -05:00
Max Fedotov f2cfd23ef2
gtk: implement GPU scale factor feature (#764)
* [WIP] gtk: implement GPU scale factor feature

* Replace combobox with spin button, fix taking screenshot

* Fix distorted image, add some checks for scale factor value

* Make OSD at least properly visible
2024-01-25 14:28:46 +00:00
rogerman b06537cf51 Cocoa Port: Fix building on Cocoa port related to new files being added in commit 8be30fe.
- Note that this commit ONLY fixes building, but DOES NOT actually add barcode reader support to the Cocoa port just yet.
2023-10-10 13:45:07 -07:00
zeromus 0b027d8cc0
Merge pull request #735 from windwakr/hcv1000-fixes
Slot2: Sega Card Reader fixes
2023-10-07 11:04:03 -05:00
windwakr 8be30fe971 Slot2: Sega Card Reader fixes 2023-10-07 00:35:48 -04:00
zeromus f3dee5d7ac
Merge pull request #733 from windwakr/hcv1000
Slot2: Add Sega Card Reader(HCV-1000)
2023-10-04 20:04:39 -04:00
windwakr 0a34ef8e0b Slot2: Add Sega Card Reader(HCV-1000) 2023-10-04 17:05:01 -04:00
Roger Manuel 7a3b748d77
Fix erroneous copyright date in slot1_retail_auto.cpp (related to commit 8fefb4f) 2023-10-04 09:45:02 -07:00
zeromus 25cbcd255e fix buffer overflow (by one value only) in spu that happened basically 100% of the time a sample ended. whether it corrupted the heap or not is a matter of luck. should fix #717 2023-09-03 06:00:41 -04:00
zeromus 3955480674
Merge pull request #720 from mjunix/master-1
Fix potential index out of bounds
2023-08-05 15:46:28 -07:00
Johan Mattsson ca799e60b7
Fix potential index out of bounds 2023-08-06 00:35:40 +02:00
Johan Mattsson 357ff8a2c5
Fix potential index out of bounds 2023-08-06 00:20:22 +02:00
rogerman 402e9f0a31 Cocoa Port: Add two new Cheat Manager actions, "Enable All Cheats" and "Disable All Cheats", which do exactly as their descriptions would suggest. 2023-08-02 13:50:41 -07:00
rogerman 41e3401765 Cocoa Port: In the Cheat Database Viewer, add the option to ignore any game compatibility checks when adding new cheats.
- At their own risk, this option allows the user to add any cheat from the database to any game that they want, regardless of any potential dangers that may arise from doing so. Use this option responsibly.
2023-08-02 13:23:18 -07:00
rogerman 751ab0255b Cocoa Port: The Cheat Database Viewer now displays the current game's serial and CRC to help users verify the existence of a game in the database file. 2023-08-02 10:53:58 -07:00
rogerman 6c5941689f Cocoa Port: In the Cheat Manager, the "Remove All Cheats" button has been moved into an Actions pop-up menu.
- This change is to help avoid misclicks on the button that may instantly wipe out the user's cheat list.
- The new Actions pop-up menu also exists to incorporate some new cheat list operations that will be coming very soon.
2023-08-02 10:51:00 -07:00
rogerman 35976edb5f Cocoa Port: Conversions between Internal cheats and Action Replay cheats now respect the value length. 2023-08-01 15:18:44 -07:00
rogerman 586c7ee199 Cocoa Port: In the cheat database viewer, make the current game entry's font slightly larger to further differentiate it from the other games. 2023-08-01 10:03:48 -07:00
rogerman e3167110b2 Cocoa Port: Completely redesign the cheat database viewing system with a whole slew of new features!
- Multiple cheat database files may now be opened simultaneously, each in their own individual windows.
- Cheat database files are now fully browsable.
- Game entries are now searchable by game title, serial, and CRC.
- Cheat entries are now viewed in a hierarchical layout, better representing the FAT format of the database entries.
- All cheats within a directory can now be selected or deselected in just a single click.
- Error handling is now more robust, informative, and nicer looking.
- Cheat database files are no longer assigned in DeSmuME Preferences; they are now opened through the "File > Open Cheat Database File" menu.
- Recent cheat database files are now saved, and can be quickly accessed through the "File > Open Recent Cheat Database File" menu.
- It is now possible to remove all cheats at once from the Cheat Manager's cheat list.
2023-08-01 01:41:15 -07:00
rogerman 4e6a7f0424 Cheat System: Fix a couple bugs with CheatDBFile::LoadGameList() when reading the entire database's game list.
- Fix a bug where loading all database game entries from an encrypted database would result in reading gobbledygook.
- Fix a bug where calling CheatDBFile::LoadGameList() for all database game entries would always return 0 entries rather than the actual number of found entries.
2023-07-24 13:46:05 -07:00
rogerman 9bf090b309 Cheat System: Fix a bug where the underlying cheat data would get deallocated earlier than intended. (Regression from commit 0c90e8f.)
- In CheatDBGame, also differentiate between actual entry size vs. working entry size.
2023-07-19 12:22:06 -07:00
rogerman d08a5dc56c Cocoa Port: Update build optimization profiles in Xcode project. 2023-07-18 16:43:15 -07:00
rogerman 6ee942ca5f types.h: Remove an extraneous file inclusion. 2023-07-18 12:10:55 -07:00
rogerman 0c90e8f4e3 Cheat System: Rearchitect the system for loading cheat database files in preparation for adding new features to the database file presentation. Also do a bunch of code cleanup and fix multiple bugs.
- The file description is no longer limited to 16 characters.
- Folder notes are now included in the description strings of exported cheat items. These can be important for cheats that include operating instructions in their associated folder notes.
- Fix a bug where reading the last game entry of the database file would fail.
- Fix a potential bug where reading a game entry from an encrypted database file would fail if the initial entry data resides very close to a 512-byte boundary.
- Fix a bug where deleting a CHEATSEXPORT object without calling CHEATSEXPORT.close() would result in its associated file remaining open.
- Fix a bug where deleting a CHEATSEXPORT object without calling CHEATSEXPORT.close() would result in CHEATSEXPORT.cheats leaking memory.
2023-07-18 11:13:42 -07:00
SimonAfek 50f02ae172
Fix broken macOS interface build (#679)
* Update macOS version in build_interface.yml
* Typo fixes in build_interface.yml
2023-07-12 08:49:01 +00:00
rogerman 0fc3306bfc Cocoa Port: Standardize all Internal cheat direct memory writes (clicking the 'Write Once' button) to write to NDS memory before NDS_exec() is called. 2023-07-08 20:28:01 -07:00
rogerman f240472f5e Cheat System: Standardize memory writes for all cheat types. Most notably, Internal cheats now reset the JIT in the same way as Action Replay cheats do. 2023-07-08 19:52:10 -07:00
rogerman 12347c7cd9 Cocoa Port: Continue refactoring the cheat system code, Part IV.
- Add the following C++ classes: ClientCheatSearcher, ClientCheatDatabase
- Remove the following Obj-C classes: CocoaDSCheatSearch, CocoaDSCheatSearchParams
- Remove duplicate GUI code from EmuControllerDelegate.mm and preferencesWindowDelegate.mm
- All basic functionality for managing game session cheat items, the cheat database list, and cheat search are now managed through CocoaDSCheatManager.
2023-07-07 19:31:26 -07:00
rogerman d00e6355da Cocoa Port: Continue refactoring the cheat system code.
- Add ClientCheatManager C++ class, further reducing dependence on Objective-C code.
2023-07-02 22:54:13 -07:00
rogerman 946f7df9bc Cocoa Port: Continue refactoring the cheat system code.
- Add new ClientCheatList C++ class, further reducing dependence on Objective-C code.
- Making any changes to the cheat list or to any cheat items no longer requires the acquisition of an R/W lock.
2023-06-30 20:04:19 -07:00
rogerman 4e7926eaa1 Windows Port: Fix compiling issue that prevented building. (Regression from commit 7fb5a58.) 2023-06-30 15:58:22 -07:00
rogerman 7fb5a5871b Cheat System: Minor code cleanup and robustness improvements. 2023-06-30 15:13:35 -07:00
zeromus f48aee928c fix bug from 9767f79346 that made the cheat search results list produce strange cheats without 0x02xxxxxx prefix that don't work 2023-06-25 18:24:53 -04:00
rogerman ba83b68b7f Cocoa Port: Begin work on cleaning up and refactoring the cheat system. Also add some quality-of-life improvements to the GUI while I'm at it.
- Add new ClientCheatItem C++ class to handle cheat items, greatly reducing dependence on Objective-C code.
- Remove a bunch of methods from CocoaDSCheatItem and CocoaDSCheatManager that were never used and are no longer planned to ever be used in the new code refactor.
- The Cheat Manager window may now be resized.
- The Action Replay code editor now uses Monaco 13 font instead of the system default font.
- The command for "Enable/Disable Cheats" has been renamed to "Enable/Disable Cheat System" to help clarify that the command affects the entire cheat system as a whole, as opposed to enabling/disabling individual cheat items.
2023-06-23 14:18:02 -07:00
rogerman aeefd86f57 Cocoa Port: In the cheat system code, remove Obj-C dot syntax for object properties to avoid ambiguity with features from other languages. 2023-06-21 14:53:49 -07:00
rogerman b468aee01a Linux GTK Port: Fix compiling issues that prevented building. (Regression from commit aa21454.) 2023-06-20 17:12:53 -07:00
rogerman aa21454373 Cheat System: Do some code cleanup and silence all of the compiler warnings (on Windows and Cocoa ports only).
- Some minor API changes were made, but only Windows and Cocoa were actually tested. Tried to make sure that Linux ports were updated to the new API, but haven't tested it.
2023-06-20 16:44:30 -07:00
rogerman cedc1c9f38 Cocoa Port: Add option for Catmull-Rom sound interpolation in the GUI. Also update tooltips for all interpolation methods to better reflect how they compare to one another. 2023-06-20 14:06:04 -07:00
rogerman 8bba9dc955 Cocoa Port: Due to commit fac70ce fixing FBO issues with older GPUs, OpenGL rendering is now returning to PowerPC Macs. This change effectively reverts commit 4708404. 2023-06-19 18:44:14 -07:00
rogerman 5c805b2de0 Cocoa Port: Fix some compiler warnings. 2023-06-14 13:57:30 -07:00
zeromus 7c2f281d25
Merge pull request #674 from oheikk/fix-audio-volume-resetting
Fix audio volume resetting on posix/gtk
2023-06-08 16:46:43 -04:00
Oskari Heikkinen 941c2e39be Fix audio volume resetting on posix/gtk 2023-06-08 22:47:26 +03:00
zeromus 1bde1c28ac fix non-windows compilation, maybe. could be bugged, didnt test 2023-05-28 14:31:50 -04:00
zeromus 3511e14ac6 winport: path settings support unicode now (fixes #669). old ini files may malfunction since they're now expected to be written with unicode. old ones can't be effectively upgraded (consequence of using obsolete ini file apis). 2023-05-28 14:22:09 -04:00
SimonAfek 3cefa5d78e
Update deprecated GitHub actions v2 (#666)
* Windows CI: Update deprecated github actions

* build_interface.yml: Update actions

* release_tarball.yml: Update checkout action

* build.yml: Update actions
2023-05-20 16:33:23 +01:00
SimonAfek fadd3b6e63 Windows CI: Update deprecated github actions 2023-05-10 13:56:54 +01:00
rogerman bf344e9a3e SoftRasterizer: Perform all calculations using fixed-point math instead of float-based math.
- CommonSettings.GFX3D_TXTHack has been repurposed to switch between fixed-point math and float-based math.
- Fix various rendering bugs that were caused by a loss of Z precision introduced in commit 7751b59.
- In Pokemon Diamond/Pearl, the bug that caused random black dots to appear on the ground has been fixed.
2023-05-04 12:36:49 -07:00
zeromus 1dbbeba3a7 add another mic sample 2023-04-24 15:21:45 -04:00
zeromus 65ec088918 add mic samples. we're gonna start distributing these eventually. 2023-04-23 16:18:51 -04:00
zeromus 6b7559c71b fix alignment of tempMultiplyMatrix and currentMatrix[4] in GeometryEngineLegacySave. Fixes #657. It would be better to fix this perhaps by making NDSMatrix a type that has the alignas(16) put on it while inheriting from std::array<u32,16> perhaps, so this mistake is not possible? 2023-04-21 15:18:32 -04:00
zeromus c97ba8fb16 fix spurious RRX variant selection in several disassembly macros (fixes #652 maybe) 2023-04-10 11:43:46 -04:00
rogerman ab17945377 GFX3D: Obsolete and remove the VERT struct, since OpenGL, and SoftRasterizer are now both receiving their vertex data in fixed-point.
- Also remove the unused NDSVertexf struct. There shall be only one representation of the NDS vertex data, and that shall be the fixed-point values of NDSVertex.
2023-03-06 22:19:09 -08:00
rogerman 952585eaae SoftRasterizer: Read in vertex data data as fixed-point instead of as floating-point. 2023-03-06 21:39:57 -08:00
rogerman be88a0b4c3 Remove superfluous x/y/z names from Vector2s16, Vector2s32, Vector2s64, and Vector2f32 union data types, since it is extremely unlikely that these extra names will ever be used. Just use names "x" and "y", which are the most likely to be used for these kinds of 2-element vectors. 2023-03-06 21:27:47 -08:00
rogerman 4e1ce23982 SoftRasterizer: Do some minor refactoring and code cleanup, and also prepare SoftRasterizer to accept fixed-point vertex data. 2023-03-06 14:35:47 -08:00
rogerman 56251cafd1 GFX3D: Clean up the big-endian compatibility code. 2023-03-03 13:58:37 -08:00
rogerman 111292ff15 GFX3D / SoftRasterizer: Small refactor to use some of the new data types introduced in commit cda8cb5.
- Also make SoftRasterizer's framebuffer out-of-bounds width check more robust.
2023-03-03 13:02:04 -08:00
rogerman 90c8411cbf GFX3D: Fix clear color on big-endian systems. (Regression from commit 97848fc.) 2023-02-28 01:34:27 -08:00
rofl0r dcd1072800 CI: limit autoconf build to 8 processes
hopefully will prevent the OOM killer from kicking in.
2023-02-28 03:07:43 +00:00
rogerman 1daebcd670 Silence some compiler warnings. 2023-02-27 16:36:08 -08:00
rogerman cda8cb5686 Core: Move low-level vector, vertex coordinate, and color data type declarations into types.h so that they can be used universally. Also update the data type names to be more descriptive and have better consistency.
- Add SIMD-float32 data types, and also add macros to track SIMD data-type availability.
- Also fix some bugs where 3D would fail to render on big-endian systems. (Regression from commit a67e040.)
2023-02-27 15:39:17 -08:00
rogerman d9be9c6bf6 Cocoa Port: Silence some compiler warnings. 2023-02-25 12:11:22 -08:00
rogerman a7bdd1e3a9 GFX3D: Remove the mistaken addition of color clamping when converting fixed-point vertex colors into floating-point. Fixes the proper coloring of Princess Peach in the opening sequence of Super Mario 64 DS. (Regression from commit 7751b59.) 2023-02-24 16:01:14 -08:00
rogerman fac70ce98b OpenGL Renderer: Use the fixed-point vertex list data instead of the floating-point based one, alongside other tune-ups.
- To determine polygon facing, use GFX3D's CPoly.isPolyBackFacing instead of using GLSL's gl_FrontFacing. This eases OpenGL version requirements and improves older GPU compatibility a little.
- Also fix a bug where GPUs that support FBOs, but not shaders, were unable to read out their framebuffers properly.
2023-02-24 13:49:07 -08:00
rogerman 37683a708e GFX3D: Y-sorting and writing out vertices to a save state are now handled using fixed-point instead of floating-point, where appropriate. 2023-02-23 13:12:13 -08:00
rogerman 7751b59882 GFX3D: Polygon clipping, viewport transformation, perspective correction, and face calculations are now done in fixed-point instead of floating point. 2023-02-22 22:07:37 -08:00
rogerman e1969c470b GFX3D: Vertex post-processing has been moved from the 3D renderers to GFX3D.
- Specifically, viewport transformation, face calculation, and face culling are now handled in GFX3D, and are now standard behaviors for all 3D renderers. This reorganization makes more sense since the 3D renderers are primarily responsible for rasterization and framebuffer post-processing, rather than for processing geometry.
- As a positive side-effect, the OpenGL renderer gains a small performance improvement as well as better accuracy in face culling.
2023-02-19 20:23:44 -08:00
rogerman 5457932d75 OpenGL Renderer: Fix bug where the Depth L-Equal Polygon Facing option would fail to become enabled when running OpenGL 3.2 or later. (Regression from commit ab38d17. Note that this bug does affect the 0.9.13 release build.) 2023-02-18 16:31:38 -08:00
rogerman cf75e26353 OpenGL Renderer: Silence compiler warnings. 2023-02-18 16:21:44 -08:00
rogerman 97848fce8c GFX3D: Move some last bits of static data floating around in gfx3d.cpp into the GFX3D struct, and then make the instantiation of the struct itself static. 2023-02-18 13:37:17 -08:00
rogerman 92d662cb71 GFX3D: Fix longstanding potential overflows related to polygon lists by reducing POLYLIST_SIZE from 20000 to 16383.
- Historically (ever since commit b1e4934 and commit d5bb6fd), VERTLIST_SIZE (based on POLYLIST_SIZE) could reference an index over 66535, but POLY.vertIndexes has always been an unsigned 16-bit value with a max value of 66535, making for a potential overflow. In practice, an overflow has never happened in the past 15 years because a hardware NDS has a limit of 6144 polygons (or 24576 vertices), and that even a VERTLIST_SIZE of 80000 is way more than plenty to accommodate that. Rather than increasing POLY.vertIndexes to 32-bit, it makes more sense to reduce POLYLIST_SIZE to 16383 to keep VERTLIST_SIZE below 66536. Even with this change, POLYLIST_SIZE and VERTLIST_SIZE should be more than plenty in practice.
- Also, now that we're performing polygon clipping for all client 3D renderers (ever since commit e06d11f), we're finally accounting for the fact that the clipped polygon list size is larger than POLYLIST_SIZE. Client 3D renderers have been updated to now reflect this change and avoid theoretical overflow issues that have never actually happened in practice.
2023-02-18 10:54:02 -08:00
rogerman 86b990f68a GFX3D: The shininess table is no longer a part of SWAP_BUFFERS.
- Since the shininess table is only ever used for vertex generation, it makes no sense for the table to included for the rasterization step. The shininess table has been moved to the NDSGeometryEngine class, which is a class dedicated to just vertex and polygon generation. This reorganization seems more sensible.
2023-02-17 18:32:42 -08:00
rogerman 4a95e9b8d1 GFX3D: Reorder members of the GeometryEngineLegacySave struct to better reflect the actual order of data in the existing save state format.
- Also rename some matrix-related members for better clarity.
2023-02-17 14:01:24 -08:00
rogerman d0d23cce7e GFX3D: Attempt to fix an MSVC compiling issue. (Related to commit 5d6e866.) 2023-02-17 12:00:27 -08:00
rogerman 5d6e8663c4 GFX3D: Finish refactoring geometry engine related stuff into the new NDSGeometryEngine class.
- Also, the vector test has been changed so that the result vector accounts for the 4 sign bits and proper sign expansion on overflow.
2023-02-16 21:58:28 -08:00
rogerman db365e849f GFX3D: Clean up some lighting-related code. 2023-02-16 02:59:05 -08:00
rogerman 79aa5b558e GFX3D: Continue encapsulating stuff into the new NDSGeometryEngine class, mostly focusing on matrix-related things.
- There are two significant behavior changes in this commit that will require further testing.
- Behavior change: Before, MTX_LOAD_4x4 and MTX_LOAD_4x3 commands would update the individual values in the current matrix for each command. Now, these commands will batch the values into a temporary matrix until the temp matrix is complete, and then copy the temp matrix into the current matrix. This now matches the batching behavior that the other matrix commands already do.
- Behavior change: Before, there was a single shared temporary multiplication matrix used to batch the values of incoming MTX_MULT_4x4, MTX_MULT_4x3, and MTX_MULT_3x3 commands, theoretically allowing these commands to be used interchangeably and overwrite values from previous commands until the last command made a completed multiplier matrix. Now, there are 3 separate temporary multiplier matrices, one for each of the MTX_MULT_* commands, which means that each command type must now complete its own multiplier matrix before it can perform a matrix multiply.
2023-02-15 19:59:59 -08:00
rogerman 669f1b05f5 GFX3D: Begin encapsulating stuff into the new NDSGeometryEngine() class.
- Also do some minor misc. code cleanup.
2023-02-15 00:52:23 -08:00
rogerman d03e4a6886 Cocoa Port: In the OpenGL blitter, prevent FBO-related GL calls if FBOs are not available.
- Also silence some compiler warnings.
2023-02-14 23:30:22 -08:00
zeromus d0ed57d1b3 fixed: EMUFILE_FILE eof() on textmode failed on windows (caused .dct files from mac systems freeze process while loading) 2023-02-11 15:59:40 -05:00
rogerman 5831099ebc GFX3D: The Box Test is now performed with integer operations instead of with floating point.
- The integer-based Box Test should be just as good as the old float-based one, as tested by "American Girl: Julie Finds a Way". Of course, there are still bugs compared to a hardware NDS, but we haven't transitioned to rendering with integer-based vertices yet to make a meaningful test possible.
2023-02-10 19:01:16 -08:00
rogerman 624f649acb Oops! Forgot a file. (Related to commit a67e040.) 2023-02-10 18:38:21 -08:00
rogerman a67e040a57 GFX3D: Do some major code cleanup.
- Rename a bunch of variables to better reflect their intended usage.
- Add new data types for organizing 3D vectors and coordinates.
- C functions that are called in response to 3D commands now follow the exact same pattern: “static void gfx3d_glFuncName(const u32 param)”
- Be super explicit about the usage of numeric data types and their typecasts to improve their code visibility.
- Remove implementation-specific ambiguity of right bit-shifting signed numerics (Logical-Shift-Right vs Arithmetic-Shift-Right) in the following functions: gfx3d_glLightDirection_cache(), gfx3d_glNormal(), gfx3d_glTexCoord(), gfx3d_glVertex16b(), gfx3d_glVertex10b(), gfx3d_glVertex3_cord(), gfx3d_glVertex_rel(), gfx3d_glVecTest().
2023-02-10 18:25:21 -08:00
rogerman 242cb63327 GFX3D: Remove POLY struct members that don't need to be swapped. This results in less buffer copying for all POLY lists.
- Also remove Viewer3D_State.indexList. This member is obsolete since Viewer3D_State.gList.clippedPolyList is generated in the same order described by indexList.
- Encapsulate and rename some more lists to make their intended purpose more descriptive.
2023-02-09 00:27:45 -08:00
zeromus 23400431a1
Merge pull request #632 from hjung4/fix/strchr-oob-check
Fix out-of-bounds index access
2023-02-08 12:25:41 -06:00
Henry Jung 0e538b0931 fix: strchr check 2023-02-08 07:54:08 -05:00
rogerman d8ee3480df GFX3D: Clipping functions now take VERT parameters as non-nullable references instead of as nullable pointers where appropriate.
- GFX3D_ClipPoint() (formerly named clipPoint()) now writes directly to the target VERT rather than copying a return value back to the target.
2023-02-06 23:20:46 -08:00
rogerman 9554595948 GFX3D: Various minor tweaks and optimizations, plus code cleanup.
- Most importantly, refactor the GFX3D_Clipper::ClipPoly() method into the standalone GFX3D_GenerateClippedPoly() function, which drops all class member dependencies and is much more straightforward to use.
- Remove the GFX3D_Clipper class. It has been slowly gutted over the years, but the loss of the ClipPoly() method makes the class obsolete, putting the final nail in its coffin.
- Using the new GFX3D_GenerateClippedPoly() function, gfx3d_PerformClipping() operates on the unsorted clipped polygon list directly. This means that the polygon clipping step requires one less buffer copy.
- Clipped polygons no longer retain direct pointers to POLY structs, instead using their index member to reference a POLY struct at a POLY array location. All 3D renderers have been updated to reflect this change.
- Rename a bunch of variables that reference POLY, CPoly, and VERT structs to clearly differentiate them between raw NDS data and our own internally processed data.
- Fix a potential bug in GFX3D_GenerateRenderLists() where sorting clipped polygons would reorder their polygon indices without reordering their other data members along with the indices, causing the data members to desync. OpenGL rendering was immune to this bug, but SoftRasterizer might have possibly seen it. In any case, this fix is the correct behavior.
2023-02-06 17:50:42 -08:00
rogerman 628eb6596a Cocoa Port: Fix some random compiling issues. 2023-02-04 19:33:35 -08:00
rogerman cbbacdbf59 GFX3D: The POLY and VERT structs have been converted to POD-style structs for better data consistency. 2023-02-02 02:19:49 -08:00
rogerman 9273c9ab13 GFX3D: Encapsulate some data into the GFX3D struct, and also do some minor code cleanup. 2023-02-01 16:54:04 -08:00
rogerman a3e84e28c2 Save States: Oops! Fix a bug where 3D vertices were getting double-loaded, causing save state file reads to desync. Fixes #629. (Regression from commit 5426509e.)
- Problems only occurred when LOADING a save state. However, SAVING a save state on commit 5426509e should be okay, so such save states should not be broken.
2023-02-01 15:17:20 -08:00
zeromus 5bcfd2f022
Merge pull request #628 from radioactiveman/master
Fix a few compiler warnings
2023-01-30 16:53:26 -06:00
Thomas Lange ef3f285f95
Fix a few compiler warnings
warning: use of bitwise '&' with boolean operands [-Wbitwise-instead-of-logical]

Reported by clang 15.
2023-01-30 23:40:50 +01:00
rogerman c9a4d9c4b8 SoftRasterizer: Fix compiling issue for non-SSE2 systems. (Regression from commit 5426509e.) 2023-01-25 19:09:21 -08:00
rogerman 5426509ede GFX3D: Render states and geometry lists are now copied/swapped more consistently on flush. (Related to commit 8438a5a6.)
- Viewports are now processed on VIEWPORT register write instead of being processed at render time.
- CLEAR_DEPTH, CLRIMAGE_OFFSET, EDGE_COLOR, FOG_TABLE, and TOON_TABLE register writes are now handled more consistently.
- The fogDensityTable check for force-drawing clear images in gfx3d_VBlankEndSignal() has been removed. Changes done in commit 8438a5a6 will always causes this check to fail, and this commit will always cause this check to fail. Therefore, this check is now obsolete.
- Change a bunch of GFX3D-related structs from C++ style constructed structs into C-style POD structs.
2023-01-25 18:52:45 -08:00
zeromus be287de623
Merge pull request #627 from RainingChain/fwSettingsMacAddress
Add mac address setting
2023-01-21 16:59:18 -06:00
Raining Chain 9d2ddfa648 Add mac address setting 2023-01-21 17:32:05 -05:00
rogerman f0b0afe18b Colorspace Handler: FragmentColor may now be accessed through a 4-element array, in which elements 0-1-2-3 represent color components R-G-B-A, respectively. 2023-01-19 14:24:35 -08:00
rogerman 2b66e756da Add support for page-aligned variables/arrays.
- Better account for UltraSPARC's unique memory page size.
- malloc_alignedCacheLine() no longer returns 16-byte aligned memory if the architecture is neither 32-bit or 64-bit. Now, the function only returns 64-byte alignment for 64-bit architectures OR 32-byte alignment for 32-bit architectures.
2023-01-19 14:18:58 -08:00
zeromus 8438a5a647 crude hack to fix problem where loadstate could crash if the GPU hasn't ever booted up. see TODO TODO TODO TODO in gfx3d.cpp -- somebody needs to revise the tables so they arent memory mapped but so that they work rather like shininess tables. if they aren't truly latched when the gpu is flushed, then put them in a table anyway and simply reference the live values instead of the latched ones. How to keep from accidentally referencing the latched ones? perhaps the 3d state could be divided into a latched part and an unlatched part via base classes. Could also be done by embedding a "latched" and "unlatched" struct in the gpu but that would involve touching every line of code that used something from it. 2023-01-17 23:32:47 -06:00
zeromus 29c077c165 winport - fix issues with save/load state to japanese filename (fixes #615) 2022-12-05 15:54:38 -05:00
zeromus 91efef9346
Merge pull request #602 from KellanClark/master
Fix division edge cases and prevent crash
2022-10-23 21:07:41 -04:00
Kellan Clark b5b7f29255 Fix division edge cases and prevent crash 2022-10-23 20:22:21 -04:00
rogerman 739f3162d5 Cocoa Port: Fix HUD rendering on the OpenGL blitter for GPUs that don't support shaders. 2022-09-15 15:42:12 -07:00
rogerman 698139ed8e saves.cpp: Fix compiling issue for all non-Windows platforms. (Regression from commit 3a6c8cf9.) 2022-08-04 21:26:55 -07:00
zeromus 3a6c8cf9f8
Merge pull request #523 from Keppl/backup_saves_max_patch
Limit maximum number of backups files for load state backup
2022-08-04 17:33:43 -04:00
zeromus 3614b45a6c
Merge pull request #575 from janisozaur/update-default-joystick-size
Update default joystick cofiguration size in line with #567
2022-08-04 17:32:25 -04:00
Michał Janiszewski 83396a88c0 Update default joystick cofiguration size in line with #567 2022-08-04 20:52:15 +02:00
zeromus 35d7561fd7 make hud editor actually save position (fixes #572) 2022-07-30 16:47:43 -04:00
rogerman 5ab59eac86 FIFO.cpp: Code cleanup; remove AltiVec-specific code from display FIFO, as it is no longer needed.
- The new code works by pre-swapping big-endian words on disp_fifo.buf write, rather than swapping the big-endian words during disp_fifo.buf read.
- There is a behavior change here. Before, 8-bit and 16-bit writes to disp_fifo.buf would increment disp_fifo.tail. Now, 8-bit and 16-bit writes only increment disp_fifo.tail when the most significant bit within the FIFO value's 32-bit boundary is written to.
- Behavior is unchanged when doing 32-bit writes. In practice, the rare games that use display FIFO have only ever done 32-bit writes, so this scenario is well tested.
2022-07-21 15:31:40 -07:00
zeromus f8a7723e86
Merge pull request #569 from janisozaur/patch-3
Remove self-reference in variable declaration
2022-07-21 15:30:04 -04:00
Michał Janiszewski f07cd5bae2
Remove self-reference in variable declaration 2022-07-21 12:57:49 +02:00
rofl0r b7dadd1797 CI: also upload linux cli/gtk2 build artifact 2022-07-20 21:09:45 +01:00
rofl0r 2664b03d93 CI: add build job for linux/GTK2 2022-07-20 21:09:45 +01:00
rofl0r b27b31c57d posix: properly fix size mismatch of keyboard/joystick_cfg arrays
fixes #563

unlike #566, this also fixes the gtk2 frontend automatically.
2022-07-20 21:09:11 +01:00
zeromus 22fd8b231d
Merge pull request #566 from janisozaur/patch-1
Fix #563: mismatched buffer sizes for memcpy
2022-07-20 12:04:19 -04:00
zeromus 16e7c126e2
Merge pull request #564 from janisozaur/fix-use-of-internal-buffer
Fix use of internal storage of temporary buffer
2022-07-20 12:03:52 -04:00
Michał Janiszewski a84a48dc75 Fix #563: mismatched buffer sizes for memcpy 2022-07-20 14:53:55 +02:00
Michał Janiszewski d107562a16 Fix use of internal storage of temporary buffer
The entry index gets converted to a (temporary) string, from which a
pointer to internal data is taken and only consumed outside the loop,
where parent variable no longer exists.
2022-07-19 13:43:53 +02:00
rofl0r 677c6bb907 gtk3/gtk2: fix mismatched types for keyboard config temp storage
fallout from c68cc14, closes #558
2022-06-28 22:16:13 +00:00
rogerman 146a6ac655 Preemptively fix a compiling issue for AltiVec systems when using GCC without running keyword-and-predefine mode. 2022-06-27 12:10:56 -07:00
rogerman 640a1fdd93 Fix yet another compiling issue on GCC for AArch64. Fixes #556. 2022-06-25 15:01:21 -07:00
rogerman d4afd4977c libretro-common: Compiling tune-up for ARM architectures.
- Fixes a mismatched register warning in arm_enable_runfast_mode() when compiling for AArch64.
- Fix compiling check_arm_cpu_feature() on non-ARM architectures by being super explicit and pedantic about checking for __ARM_ARCH; none of this compiler-assumes-a-macro-equals-zero-if-undefined stuff.
2022-06-20 11:22:26 -07:00
rogerman a95e4c57c6 Remove AltiVec compiling for ppcle and ppc64le architectures, since our AltiVec code only works on big-endian systems anyways. Fixes #550. 2022-06-19 20:36:50 -07:00
rogerman 24eb5ed95c Fix compiling on GCC for AArch64. Fixes #548. 2022-06-18 21:56:25 -07:00
zeromus a3499803ac
Merge pull request #532 from Aikku93/patch-3
Check `gameCode==####` for homebrew
2022-06-17 14:28:27 -04:00
zeromus 1ccbf52246
Merge pull request #546 from Aikku93/spu-enhanced-interpolation
Enhanced interpolation, and fixed-point sample positions
2022-06-16 15:16:25 -04:00
Aikku93 09f7ab13c7 fix overflow problems
Catmull-Rom can give outputs greater than 16bit, so we must use 15bit precision. Also, ensure to use floor() to force a round-down regardless of host rounding behaviour.
2022-06-13 16:44:24 +10:00
Aikku93 aa25e1dd54 tighter bounds on interpolation accuracy 2022-06-13 15:14:54 +10:00
Aikku93 589084ec74 Split 64bit counters into 2x32bit
This appears to generate slightly saner code
2022-06-13 14:28:44 +10:00
Aikku93 41edf7be5e fix broken adpcm 2022-06-12 20:10:26 +10:00
Aikku93 235d9efea7 attempt to fix for macos 2022-06-12 19:33:09 +10:00
Aikku93 b2c4d449ca fix PSG square wave
Was reading the wrong part of GBATek
2022-06-12 19:03:48 +10:00
Aikku93 6215418dc7 sampcnt/sampinc as .32fxp, add catmull-spline interpolation 2022-06-12 18:36:37 +10:00
zeromus 48f5a8289d attempt to fix some problems caused by users running desmume out of directories with non-english characters (could manifest as "could not get read/write access to the battery save file") 2022-06-04 20:35:53 -04:00
Lino5000 b2ad722473 CLI: Re-work KEYDOWN handling to allow both shift keys as control inputs
Right Shift is the default for Select key.
2022-05-31 11:37:54 +00:00
Lino5000 c68cc14f16 Fix Linux CLI keyboard input bug due to mismatched types 2022-05-31 11:37:48 +00:00
rogerman ba05516b7d Cocoa Port: When dealing with file paths, replace instances of [NSString cStringUsingEncoding:NSUTF8StringEncoding] with [NSString fileSystemRepresentation] and [NSFileManager stringWithFileSystemRepresentation:].
- This commit doesn't actually do anything, but it is the "proper" way for Apple OSes to deal with file paths that interact with lower-level C file functions.
2022-05-30 13:25:20 -07:00
zeromus 416b08d6f7
Merge pull request #537 from colton5007/patch-1
Fixed GBA SRAMPath in posix CLI
2022-05-29 02:45:25 -04:00
colton5007 bc85e0b165 Fixed GBA SRAMPath in posix CLI 2022-05-29 01:04:42 -05:00
rogerman b82c3d7bce GFX3D: The box test now partially works in fixed-point.
- Specifically, the vertex calculations are performed using fixed-point. However, clipping still occurs using floating-point.
2022-05-24 12:02:27 -07:00
rogerman 3632142547 JIT (ARM): Make the code a little more portable, and also silence a couple compiler warnings. 2022-05-23 16:08:06 -07:00
rogerman 356fe47df7 GFX3D: GEM_TransformVertex() now uses the SIMD-optimized generic matrix functions instead of using its own scalar-only version.
- This change results in a small, yet measurable, performance improvement.
- Note that this change has the side-effect of enabling saturation logic for the following functions: MatrixMultVec3x3(), MatrixTranslate(), MatrixScale(). This is a change in their behavior, since these functions did not perform saturation logic before. This will need additional testing.
2022-05-23 15:53:05 -07:00
rogerman d757d83b3d GFX3D: The position test and the vector test are now performed using fixed-point instead of floating-point. 2022-05-23 15:29:57 -07:00
rogerman 95b824b541 Cocoa Port: Update version number to support version bump from commit 60714f6d. 2022-05-23 15:19:55 -07:00
zeromus 60714f6d22 bump version to 0.9.14 for future interim builds. 2022-05-23 18:10:07 -04:00
zeromus d9479cd6d3 update make_scmrev.h.js for modern times by searching for 64bit git on 32bit msbuild/devenv 2022-05-23 18:03:42 -04:00
zeromus 75230bfe0a fix support link in help menu 2022-05-23 18:03:18 -04:00
Aikku93 aa2a5f2a34 check `gameCode==####` for homebrew 2022-05-23 18:35:25 +10:00
Keppl 631f2a265e Added check that index file was actually openned for writing.
If not, skip creating backup part of loading.
2022-04-12 19:07:06 -04:00
Keppl dec93fecfa Added configuration option to define number of max number of backups. Windows only at the moment. 2022-04-11 22:26:16 -04:00
Keppl 970663bf71 Fixed bug when writing index, set default max to 200 2022-04-11 17:59:17 -04:00
Keppl 53be5f6968 Changed loadstate_slot function to keep only 5 latest backups when saving curring state before loading.
Once more than 5 exist, oldest one will be overwritten.
2022-04-10 22:36:10 -04:00
350 changed files with 130861 additions and 106059 deletions

View File

@ -0,0 +1,19 @@
---
name: New Issue, Bug report, Question
about: New Issue, Bug report, Question
title: ''
labels: ''
assignees: ''
---
## State your operating system:
Windows/Mac/Linux. in case of linux, whether you use CLI, gtk2, or gtk3 version.
## DesMuME version
e.g. 0.9.13 or git master
## Isse
type here what's bothering you, in a detailed manner.

View File

@ -7,11 +7,11 @@ on:
jobs: jobs:
build: build:
name: Build DeSmuME (Linux) name: Build DeSmuME (Linux)
runs-on: ubuntu-20.04 runs-on: ubuntu-24.04
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: install dependencies - name: install dependencies
run: sudo apt update && sudo apt install meson libsdl2-dev libpcap-dev libgtk-3-dev run: sudo apt update && sudo apt install meson libsdl2-dev libpcap-dev libgtk-3-dev
@ -24,13 +24,73 @@ jobs:
- name: ninja - name: ninja
run: ninja -C desmume/src/frontend/posix/build run: ninja -C desmume/src/frontend/posix/build
build_macos: build_gtk2:
name: Build DeSmuME (macOS) name: Build DeSmuME (Linux/GTK+2)
runs-on: macOS-11 runs-on: ubuntu-24.04
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: install dependencies
run: sudo apt update && sudo apt install autoconf libglu1-mesa-dev libsdl2-dev libpcap-dev libgtk2.0-dev
- name: buildit
run: |
cd desmume/src/frontend/posix/
autoreconf -i
./configure --prefix=/usr --enable-gdb-stub --enable-wifi
make -j8
make DESTDIR=/tmp/DeSmuME install
- name: Pack artifact
run: |
cd /tmp
tar cJf DeSmuME.tar.xz DeSmuME/
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: desmume-linux-gtk2-cli-x86_64
path: /tmp/DeSmuME.tar.xz
build_mingw:
name: Build DeSmuME (mingw/i686)
runs-on: ubuntu-24.04
steps:
- name: checkout
uses: actions/checkout@v4
- name: install dependencies
run: sudo apt update && sudo apt install mingw-w64 mingw-w64-i686-dev
- name: buildit
run: |
cd desmume/src/frontend/windows/
echo "OPT=-fstrength-reduce -fthread-jumps -fcse-follow-jumps -fcse-skip-blocks -frerun-cse-after-loop -fexpensive-optimizations -fforce-addr -fomit-frame-pointer -ffast-math -march=pentium4 -mtune=pentium4 -mmmx -msse2" > config.mak
make -j8
mkdir /tmp/DeSmuME
cp desmume.exe /tmp/DeSmuME
- name: Pack artifact
run: |
cd /tmp
tar cJf DeSmuME.tar.xz DeSmuME/
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: desmume-mingw-win32
path: /tmp/DeSmuME.tar.xz
build_macos:
name: Build DeSmuME (macOS)
runs-on: macos-14
steps:
- name: checkout
uses: actions/checkout@v4
- name: xcodebuild - name: xcodebuild
run: | run: |
@ -43,7 +103,7 @@ jobs:
7z a DeSmuME.app.zip DeSmuME.app 7z a DeSmuME.app.zip DeSmuME.app
- name: Upload artifict - name: Upload artifict
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: macos name: macos
path: desmume/src/frontend/cocoa/desmume.xcarchive/Products/Applications/DeSmuME.app.zip path: desmume/src/frontend/cocoa/desmume.xcarchive/Products/Applications/DeSmuME.app.zip

View File

@ -6,11 +6,11 @@ on:
jobs: jobs:
build_linux: build_linux:
runs-on: ubuntu-20.04 runs-on: ubuntu-24.04
name: Build Linux name: Build Linux
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Install dependencies - name: Install dependencies
run: sudo apt update && sudo apt install meson libsdl2-dev libpcap-dev run: sudo apt update && sudo apt install meson libsdl2-dev libpcap-dev
@ -23,21 +23,21 @@ jobs:
- name: Build - ninja - name: Build - ninja
run: ninja -C desmume/src/frontend/interface/build run: ninja -C desmume/src/frontend/interface/build
- name: Upload artificat - name: Upload artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: linux name: linux
path: desmume/src/frontend/interface/build/libdesmume.so path: desmume/src/frontend/interface/build/libdesmume.so
build_macos: build_macos:
runs-on: macos-10.15 runs-on: macos-14
name: Build MacOS name: Build MacOS
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Install MacOS build deps - name: Install MacOS build deps
run: brew install coreutils gcc sdl2 meson glib run: brew install coreutils sdl2 meson
- name: Build - Meson - name: Build - Meson
run: | run: |
@ -53,14 +53,14 @@ jobs:
CC: clang CC: clang
CXX: clang++ CXX: clang++
- name: Upload artificat - name: Upload artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: macos name: macos
path: desmume/src/frontend/interface/build/libdesmume.dylib path: desmume/src/frontend/interface/build/libdesmume.dylib
build_windows: build_windows:
runs-on: windows-2019 runs-on: windows-2022
name: Build Windows name: Build Windows
strategy: strategy:
fail-fast: false fail-fast: false
@ -68,18 +68,20 @@ jobs:
arch: [ 'x64', 'x86' ] arch: [ 'x64', 'x86' ]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v4
- name: Add msbuild to PATH - name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.2 uses: microsoft/setup-msbuild@v2
with:
msbuild-architecture: ${{ matrix.arch }}
- name: Build - name: Build
run: | run: |
cd desmume\src\frontend\interface\windows cd desmume\src\frontend\interface\windows
MSBuild.exe DeSmuME_Interface.vcxproj /p:configuration="Release Fastbuild" /p:Platform=${{ matrix.arch }} MSBuild.exe DeSmuME_Interface.vcxproj /p:configuration="Release Fastbuild" /p:Platform=${{ matrix.arch }}
- name: Upload artificat - name: Upload artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: win-${{ matrix.arch }} name: win-${{ matrix.arch }}
path: desmume/src/frontend/interface/windows/__bins/*.dll path: desmume/src/frontend/interface/windows/__bins/*.dll

View File

@ -6,16 +6,15 @@ on:
jobs: jobs:
build-sln: build-sln:
runs-on: windows-2019 runs-on: windows-2022
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Setup MSBuild.exe - name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.1 uses: microsoft/setup-msbuild@v2
with: with:
msbuild-architecture: x64 msbuild-architecture: x64
vs-version: 16.1
- name: Build solution - name: Build solution
run: | run: |
@ -24,7 +23,7 @@ jobs:
cmd /c desmume\src\frontend\windows\ci_postbuild.bat cmd /c desmume\src\frontend\windows\ci_postbuild.bat
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: desmume-win-x64 name: desmume-win-x64
path: desmume/src/frontend/windows/__bins/*.exe path: desmume/src/frontend/windows/__bins/*.exe

View File

@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
with: with:
submodules: recursive submodules: recursive

View File

@ -18,11 +18,6 @@ autoreconf -i (or alternatively: ./autogen.sh)
make -jN (where N is the number of CPU cores to use). make -jN (where N is the number of CPU cores to use).
DeSmuME provides another interface based on libglade, to use
, you'll need glade:
* http://glade.gnome.org/
To build, first cd to src/frontend/posix and run To build, first cd to src/frontend/posix and run
`meson build --buildtype=release` `meson build --buildtype=release`
@ -32,11 +27,6 @@ It will generate three programs:
1) "desmume" in the "build/gtk" directory; 1) "desmume" in the "build/gtk" directory;
2) "desmume-cli" in the "build/cli" directory. 2) "desmume-cli" in the "build/cli" directory.
If glade is installed on your system, you'll get a third
binary:
3) "desmume-glade" in the "build/gtk-glade" directory.
You can even type "ninja -C build install" to install those programs on You can even type "ninja -C build install" to install those programs on
your system (in /usr/local/ by default); then uninstalling is your system (in /usr/local/ by default); then uninstalling is
done by typing "ninja -C build uninstall". done by typing "ninja -C build uninstall".

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,8 @@
Tips:
* Set hotkeys for "Mic Prev Sample" and "Mic Next Sample" in the "Main" section of hotkey configuration (suggest [ and ])
* This will rotate through all the provided desmume_N.wav. You can add your own in the series, just pick the next number.
* Keep the microphone hotkey held down for as long as you want the noise to play! Just tapping it will make a very short sound indeed.
desmume_0.wav was formerly "PERFECT BLOW FOR DS EMULATORS.wav"
desmume_1.wav was formerly "noise_loud.wav"
desmume_4.wav came to us as "pcm0822m.wav"; these are alleged to work well for Giant Bowser fights in Bowser's Inside Story.

Binary file not shown.

View File

@ -374,7 +374,7 @@ namespace Database
size_t regions_num = ARRAY_SIZE(regions); size_t regions_num = ARRAY_SIZE(regions);
const char* found = strchr(regions_index,code); const char* found = strchr(regions_index,code);
if(found) return regions[found-regions_index]; if(found && found-regions_index < strlen(regions_index)) return regions[found-regions_index];
else return unknownAsString ? "???" : NULL; else return unknownAsString ? "???" : NULL;
} }

210
desmume/src/FIFO.cpp Executable file → Normal file
View File

@ -1,7 +1,7 @@
/* /*
Copyright 2006 yopyop Copyright 2006 yopyop
Copyright 2007 shash Copyright 2007 shash
Copyright 2007-2022 DeSmuME team Copyright 2007-2024 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -44,7 +44,6 @@
#elif defined(ENABLE_ALTIVEC) #elif defined(ENABLE_ALTIVEC)
#define USEVECTORSIZE_128 #define USEVECTORSIZE_128
#define VECTORSIZE 16 #define VECTORSIZE 16
#include "./utils/colorspacehandler/colorspacehandler_AltiVec.h"
#endif #endif
#if defined(USEVECTORSIZE_512) || defined(USEVECTORSIZE_256) || defined(USEVECTORSIZE_128) #if defined(USEVECTORSIZE_512) || defined(USEVECTORSIZE_256) || defined(USEVECTORSIZE_128)
@ -340,12 +339,96 @@ void DISP_FIFOinit()
memset(&disp_fifo, 0, sizeof(DISP_FIFO)); memset(&disp_fifo, 0, sizeof(DISP_FIFO));
} }
void DISP_FIFOsend_u32(u32 val) template <typename T, size_t ADDROFFSET>
void DISP_FIFOsend(const T val)
{ {
//INFO("DISP_FIFO send value 0x%08X (head 0x%06X, tail 0x%06X)\n", val, disp_fifo.head, disp_fifo.tail); //INFO("DISP_FIFO send value 0x%08X (head 0x%06X, tail 0x%06X)\n", val, disp_fifo.head, disp_fifo.tail);
disp_fifo.buf[disp_fifo.tail] = val;
disp_fifo.tail++; const size_t numBytes = sizeof(T);
const size_t baseWriteAddress = disp_fifo.tail * sizeof(u32);
const size_t finalWriteAddress = baseWriteAddress + ADDROFFSET;
switch (numBytes)
{
case 1:
{
#ifndef MSB_FIRST
HostWriteByte((u8 *)disp_fifo.buf, (u32)finalWriteAddress, val);
#else
switch (ADDROFFSET)
{
case 0:
HostWriteByte((u8 *)disp_fifo.buf, (u32)baseWriteAddress + 2, val);
break;
case 1:
HostWriteByte((u8 *)disp_fifo.buf, (u32)baseWriteAddress + 3, val);
break;
case 2:
HostWriteByte((u8 *)disp_fifo.buf, (u32)baseWriteAddress + 0, val);
break;
case 3:
HostWriteByte((u8 *)disp_fifo.buf, (u32)baseWriteAddress + 1, val);
break;
default:
break;
}
#endif
#ifndef MSB_FIRST
if (ADDROFFSET == 3)
#else
if (ADDROFFSET == 1)
#endif
{
disp_fifo.tail++;
}
break;
}
case 2:
{
#ifndef MSB_FIRST
HostWriteWord((u8 *)disp_fifo.buf, (u32)finalWriteAddress, val);
#else
switch (ADDROFFSET)
{
case 0:
HostWriteWord((u8 *)disp_fifo.buf, (u32)baseWriteAddress + 2, val);
break;
case 2:
HostWriteWord((u8 *)disp_fifo.buf, (u32)baseWriteAddress + 0, val);
break;
default:
break;
}
#endif
#ifndef MSB_FIRST
if (ADDROFFSET == 2)
#else
if (ADDROFFSET == 0)
#endif
{
disp_fifo.tail++;
}
break;
}
case 4:
HostWriteTwoWords((u8 *)disp_fifo.buf, (u32)finalWriteAddress, val);
disp_fifo.tail++;
break;
default:
break;
}
if (disp_fifo.tail >= 0x6000) if (disp_fifo.tail >= 0x6000)
{ {
disp_fifo.tail = 0; disp_fifo.tail = 0;
@ -380,19 +463,7 @@ void DISP_FIFOrecv_Line16(u16 *__restrict dst)
#ifdef USEMANUALVECTORIZATION #ifdef USEMANUALVECTORIZATION
if ( (disp_fifo.head + (GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16)) / sizeof(u32) <= 0x6000) && (disp_fifo.head == (disp_fifo.head & ~(VECTORSIZE - 1))) ) if ( (disp_fifo.head + (GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16)) / sizeof(u32) <= 0x6000) && (disp_fifo.head == (disp_fifo.head & ~(VECTORSIZE - 1))) )
{ {
#ifdef ENABLE_ALTIVEC
// Big-endian systems read the pixels in their correct bit order, but swap 16-bit chunks
// within 32-bit lanes, and so we can't use a standard buffer copy function here.
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16); i+=sizeof(v128u16))
{
v128u16 fifoColor = vec_ld(i, disp_fifo.buf + disp_fifo.head);
fifoColor = vec_perm( (v128u8)fifoColor, (v128u8)fifoColor, ((v128u8){2,3, 0,1, 6,7, 4,5, 10,11, 8,9, 14,15, 12,13}) );
vec_st(fifoColor, i, dst);
}
#else
buffer_copy_fast<GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16)>(dst, disp_fifo.buf + disp_fifo.head); buffer_copy_fast<GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16)>(dst, disp_fifo.buf + disp_fifo.head);
#endif // ENABLE_ALTIVEC
_DISP_FIFOrecv_LineAdvance(); _DISP_FIFOrecv_LineAdvance();
} }
else else
@ -401,82 +472,11 @@ void DISP_FIFOrecv_Line16(u16 *__restrict dst)
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(u32); i++) for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(u32); i++)
{ {
const u32 src = DISP_FIFOrecv_u32(); const u32 src = DISP_FIFOrecv_u32();
#ifdef MSB_FIRST
((u32 *)dst)[i] = (src >> 16) | (src << 16);
#else
((u32 *)dst)[i] = src; ((u32 *)dst)[i] = src;
#endif
} }
} }
} }
#ifdef USEMANUALVECTORIZATION
template <NDSColorFormat OUTPUTFORMAT>
void _DISP_FIFOrecv_LineOpaque16_vec(u32 *__restrict dst)
{
#ifdef ENABLE_ALTIVEC
// Big-endian systems read the pixels in their correct bit order, but swap 16-bit chunks
// within 32-bit lanes, and so we can't use a standard buffer copy function here.
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16); i+=sizeof(v128u16))
{
v128u16 fifoColor = vec_ld(i, disp_fifo.buf + disp_fifo.head);
fifoColor = vec_perm( (v128u8)fifoColor, (v128u8)fifoColor, ((v128u8){2,3, 0,1, 6,7, 4,5, 10,11, 8,9, 14,15, 12,13}) );
fifoColor = vec_or(fifoColor, ((v128u16){0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000}));
vec_st(fifoColor, i, dst);
}
#else
buffer_copy_or_constant_s16_fast<GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16), false>(dst, disp_fifo.buf + disp_fifo.head, 0x8000);
#endif // ENABLE_ALTIVEC
_DISP_FIFOrecv_LineAdvance();
}
template <NDSColorFormat OUTPUTFORMAT>
void _DISP_FIFOrecv_LineOpaque32_vec(u32 *__restrict dst)
{
#ifdef ENABLE_ALTIVEC
for (size_t i = 0, d = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16); i+=16, d+=32)
{
v128u16 fifoColor = vec_ld(0, disp_fifo.buf + disp_fifo.head);
disp_fifo.head += (sizeof(v128u16)/sizeof(u32));
if (disp_fifo.head >= 0x6000)
{
disp_fifo.head -= 0x6000;
}
v128u32 dstLo = ((v128u32){0,0,0,0});
v128u32 dstHi = ((v128u32){0,0,0,0});
fifoColor = vec_perm( (v128u8)fifoColor, (v128u8)fifoColor, ((v128u8){10,11, 8,9, 14,15, 12,13, 2,3, 0,1, 6,7, 4,5}) );
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{
ColorspaceConvert555To6665Opaque_AltiVec<false, BESwapDst>(fifoColor, dstLo, dstHi);
}
else if (OUTPUTFORMAT == NDSColorFormat_BGR888_Rev)
{
ColorspaceConvert555To8888Opaque_AltiVec<false, BESwapDst>(fifoColor, dstLo, dstHi);
}
vec_st(dstLo, d + 0, dst);
vec_st(dstHi, d + 16, dst);
}
#else
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{
ColorspaceConvertBuffer555To6665Opaque<false, false, BESwapDst>((u16 *)(disp_fifo.buf + disp_fifo.head), dst, GPU_FRAMEBUFFER_NATIVE_WIDTH);
}
else if (OUTPUTFORMAT == NDSColorFormat_BGR888_Rev)
{
ColorspaceConvertBuffer555To8888Opaque<false, false, BESwapDst>((u16 *)(disp_fifo.buf + disp_fifo.head), dst, GPU_FRAMEBUFFER_NATIVE_WIDTH);
}
_DISP_FIFOrecv_LineAdvance();
#endif // ENABLE_ALTIVEC
}
#endif // USEMANUALVECTORIZATION
template <NDSColorFormat OUTPUTFORMAT> template <NDSColorFormat OUTPUTFORMAT>
void DISP_FIFOrecv_LineOpaque(u32 *__restrict dst) void DISP_FIFOrecv_LineOpaque(u32 *__restrict dst)
{ {
@ -485,26 +485,28 @@ void DISP_FIFOrecv_LineOpaque(u32 *__restrict dst)
{ {
if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev)
{ {
_DISP_FIFOrecv_LineOpaque16_vec<OUTPUTFORMAT>(dst); buffer_copy_or_constant_s16_fast<GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16), false>(dst, disp_fifo.buf + disp_fifo.head, 0x8000);
} }
else else if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
_DISP_FIFOrecv_LineOpaque32_vec<OUTPUTFORMAT>(dst); ColorspaceConvertBuffer555xTo6665Opaque<false, false, BESwapDst>((u16 *)(disp_fifo.buf + disp_fifo.head), dst, GPU_FRAMEBUFFER_NATIVE_WIDTH);
} }
else if (OUTPUTFORMAT == NDSColorFormat_BGR888_Rev)
{
ColorspaceConvertBuffer555xTo8888Opaque<false, false, BESwapDst>((u16 *)(disp_fifo.buf + disp_fifo.head), dst, GPU_FRAMEBUFFER_NATIVE_WIDTH);
}
_DISP_FIFOrecv_LineAdvance();
} }
else else
#endif #endif // USEMANUALVECTORIZATION
{ {
if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev)
{ {
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(u32); i++) for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(u32); i++)
{ {
const u32 src = DISP_FIFOrecv_u32(); const u32 src = DISP_FIFOrecv_u32();
#ifdef MSB_FIRST
dst[i] = (src >> 16) | (src << 16) | 0x80008000;
#else
dst[i] = src | 0x80008000; dst[i] = src | 0x80008000;
#endif
} }
} }
else else
@ -515,13 +517,13 @@ void DISP_FIFOrecv_LineOpaque(u32 *__restrict dst)
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
dst[i+0] = LE_TO_LOCAL_32( ColorspaceConvert555To6665Opaque<false>((src >> 0) & 0x7FFF) ); dst[i+0] = ColorspaceConvert555To6665Opaque<false>(src >> 0);
dst[i+1] = LE_TO_LOCAL_32( ColorspaceConvert555To6665Opaque<false>((src >> 16) & 0x7FFF) ); dst[i+1] = ColorspaceConvert555To6665Opaque<false>(src >> 16);
} }
else if (OUTPUTFORMAT == NDSColorFormat_BGR888_Rev) else if (OUTPUTFORMAT == NDSColorFormat_BGR888_Rev)
{ {
dst[i+0] = LE_TO_LOCAL_32( ColorspaceConvert555To8888Opaque<false>((src >> 0) & 0x7FFF) ); dst[i+0] = ColorspaceConvert555To8888Opaque<false>(src >> 0);
dst[i+1] = LE_TO_LOCAL_32( ColorspaceConvert555To8888Opaque<false>((src >> 16) & 0x7FFF) ); dst[i+1] = ColorspaceConvert555To8888Opaque<false>(src >> 16);
} }
} }
} }
@ -534,6 +536,14 @@ void DISP_FIFOreset()
disp_fifo.tail = 0; disp_fifo.tail = 0;
} }
template void DISP_FIFOsend< u8, 0>(const u8 val);
template void DISP_FIFOsend< u8, 1>(const u8 val);
template void DISP_FIFOsend< u8, 2>(const u8 val);
template void DISP_FIFOsend< u8, 3>(const u8 val);
template void DISP_FIFOsend<u16, 0>(const u16 val);
template void DISP_FIFOsend<u16, 2>(const u16 val);
template void DISP_FIFOsend<u32, 0>(const u32 val);
template void DISP_FIFOrecv_LineOpaque<NDSColorFormat_BGR555_Rev>(u32 *__restrict dst); template void DISP_FIFOrecv_LineOpaque<NDSColorFormat_BGR555_Rev>(u32 *__restrict dst);
template void DISP_FIFOrecv_LineOpaque<NDSColorFormat_BGR666_Rev>(u32 *__restrict dst); template void DISP_FIFOrecv_LineOpaque<NDSColorFormat_BGR666_Rev>(u32 *__restrict dst);
template void DISP_FIFOrecv_LineOpaque<NDSColorFormat_BGR888_Rev>(u32 *__restrict dst); template void DISP_FIFOrecv_LineOpaque<NDSColorFormat_BGR888_Rev>(u32 *__restrict dst);

View File

@ -1,7 +1,7 @@
/* /*
Copyright 2006 yopyop Copyright 2006 yopyop
Copyright 2007 shash Copyright 2007 shash
Copyright 2007-2021 DeSmuME team Copyright 2007-2022 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -87,7 +87,7 @@ typedef struct
extern DISP_FIFO disp_fifo; extern DISP_FIFO disp_fifo;
void DISP_FIFOinit(); void DISP_FIFOinit();
void DISP_FIFOsend_u32(u32 val); template<typename T, size_t ADDROFFSET> void DISP_FIFOsend(const T val);
u32 DISP_FIFOrecv_u32(); u32 DISP_FIFOrecv_u32();
void DISP_FIFOrecv_Line16(u16 *__restrict dst); void DISP_FIFOrecv_Line16(u16 *__restrict dst);

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
Copyright (C) 2006 yopyop Copyright (C) 2006 yopyop
Copyright (C) 2006-2007 Theo Berkau Copyright (C) 2006-2007 Theo Berkau
Copyright (C) 2007 shash Copyright (C) 2007 shash
Copyright (C) 2009-2022 DeSmuME team Copyright (C) 2009-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -102,7 +102,7 @@ enum DisplayCaptureSize
DisplayCaptureSize_128x128 = 0, DisplayCaptureSize_128x128 = 0,
DisplayCaptureSize_256x64 = 1, DisplayCaptureSize_256x64 = 1,
DisplayCaptureSize_256x128 = 2, DisplayCaptureSize_256x128 = 2,
DisplayCaptureSize_256x192 = 3, DisplayCaptureSize_256x192 = 3
}; };
typedef union typedef union
@ -117,7 +117,7 @@ typedef union
u8 OBJ_Tile_mapping:1; // 4: A+B; 0=2D (32KB), 1=1D (32..256KB) u8 OBJ_Tile_mapping:1; // 4: A+B; 0=2D (32KB), 1=1D (32..256KB)
u8 OBJ_BMP_2D_dim:1; // 5: A+B; 0=128x512, 1=256x256 pixels u8 OBJ_BMP_2D_dim:1; // 5: A+B; 0=128x512, 1=256x256 pixels
u8 OBJ_BMP_mapping:1; // 6: A+B; 0=2D (128KB), 1=1D (128..256KB) u8 OBJ_BMP_mapping:1; // 6: A+B; 0=2D (128KB), 1=1D (128..256KB)
u8 ForceBlank:1; // 7: A+B; u8 ForceBlank:1; // 7: A+B; 0=Disable, 1=Enable (causes the line to render all white)
u8 BG0_Enable:1; // 8: A+B; 0=Disable, 1=Enable u8 BG0_Enable:1; // 8: A+B; 0=Disable, 1=Enable
u8 BG1_Enable:1; // 9: A+B; 0=Disable, 1=Enable u8 BG1_Enable:1; // 9: A+B; 0=Disable, 1=Enable
@ -143,7 +143,7 @@ typedef union
u8 ExBGxPalette_Enable:1; // 30: A+B; 0=Disable, 1=Enable BG extended Palette u8 ExBGxPalette_Enable:1; // 30: A+B; 0=Disable, 1=Enable BG extended Palette
u8 ExOBJPalette_Enable:1; // 31: A+B; 0=Disable, 1=Enable OBJ extended Palette u8 ExOBJPalette_Enable:1; // 31: A+B; 0=Disable, 1=Enable OBJ extended Palette
#else #else
u8 ForceBlank:1; // 7: A+B; u8 ForceBlank:1; // 7: A+B; 0=Disable, 1=Enable (causes the line to render all white)
u8 OBJ_BMP_mapping:1; // 6: A+B; 0=2D (128KB), 1=1D (128..256KB) u8 OBJ_BMP_mapping:1; // 6: A+B; 0=2D (128KB), 1=1D (128..256KB)
u8 OBJ_BMP_2D_dim:1; // 5: A+B; 0=128x512, 1=256x256 pixels u8 OBJ_BMP_2D_dim:1; // 5: A+B; 0=128x512, 1=256x256 pixels
u8 OBJ_Tile_mapping:1; // 4: A+B; 0=2D (32KB), 1=1D (32..256KB) u8 OBJ_Tile_mapping:1; // 4: A+B; 0=2D (32KB), 1=1D (32..256KB)
@ -581,7 +581,7 @@ typedef union
u8 PolygonShading:1; // 1: Polygon shading mode, interacts with POLYGON_ATTR (0x40004A4); 0=Toon Shading, 1=Highlight Shading u8 PolygonShading:1; // 1: Polygon shading mode, interacts with POLYGON_ATTR (0x40004A4); 0=Toon Shading, 1=Highlight Shading
u8 EnableAlphaTest:1; // 2: Perform alpha test, interacts with ALPHA_TEST_REF (0x4000340); 0=Disable, 1=Enable u8 EnableAlphaTest:1; // 2: Perform alpha test, interacts with ALPHA_TEST_REF (0x4000340); 0=Disable, 1=Enable
u8 EnableAlphaBlending:1; // 3: Perform alpha blending, interacts with POLYGON_ATTR (0x40004A4); 0=Disable, 1=Enable u8 EnableAlphaBlending:1; // 3: Perform alpha blending, interacts with POLYGON_ATTR (0x40004A4); 0=Disable, 1=Enable
u8 EnableAntiAliasing:1; // 4: Render polygon edges with antialiasing; 0=Disable, 1=Enable u8 EnableAntialiasing:1; // 4: Render polygon edges with antialiasing; 0=Disable, 1=Enable
u8 EnableEdgeMarking:1; // 5: Perform polygon edge marking, interacts with EDGE_COLOR (0x4000330); 0=Disable, 1=Enable u8 EnableEdgeMarking:1; // 5: Perform polygon edge marking, interacts with EDGE_COLOR (0x4000330); 0=Disable, 1=Enable
u8 FogOnlyAlpha:1; // 6: Apply fog to the alpha channel only, interacts with FOG_COLOR (0x4000358) / FOG_TABLE (0x4000360); 0=Color+Alpha, 1=Alpha u8 FogOnlyAlpha:1; // 6: Apply fog to the alpha channel only, interacts with FOG_COLOR (0x4000358) / FOG_TABLE (0x4000360); 0=Color+Alpha, 1=Alpha
u8 EnableFog:1; // 7: Perform fog rendering, interacts with FOG_COLOR (0x4000358) / FOG_OFFSET (0x400035C) / FOG_TABLE (0x4000360); u8 EnableFog:1; // 7: Perform fog rendering, interacts with FOG_COLOR (0x4000358) / FOG_OFFSET (0x400035C) / FOG_TABLE (0x4000360);
@ -600,7 +600,7 @@ typedef union
// 0=Disable, 1=Enable // 0=Disable, 1=Enable
u8 FogOnlyAlpha:1; // 6: Apply fog to the alpha channel only, interacts with FOG_COLOR (0x4000358) / FOG_TABLE (0x4000360); 0=Color+Alpha, 1=Alpha u8 FogOnlyAlpha:1; // 6: Apply fog to the alpha channel only, interacts with FOG_COLOR (0x4000358) / FOG_TABLE (0x4000360); 0=Color+Alpha, 1=Alpha
u8 EnableEdgeMarking:1; // 5: Perform polygon edge marking, interacts with EDGE_COLOR (0x4000330); 0=Disable, 1=Enable u8 EnableEdgeMarking:1; // 5: Perform polygon edge marking, interacts with EDGE_COLOR (0x4000330); 0=Disable, 1=Enable
u8 EnableAntiAliasing:1; // 4: Render polygon edges with antialiasing; 0=Disable, 1=Enable u8 EnableAntialiasing:1; // 4: Render polygon edges with antialiasing; 0=Disable, 1=Enable
u8 EnableAlphaBlending:1; // 3: Perform alpha blending, interacts with POLYGON_ATTR (0x40004A4); 0=Disable, 1=Enable u8 EnableAlphaBlending:1; // 3: Perform alpha blending, interacts with POLYGON_ATTR (0x40004A4); 0=Disable, 1=Enable
u8 EnableAlphaTest:1; // 2: Perform alpha test, interacts with ALPHA_TEST_REF (0x4000340); 0=Disable, 1=Enable u8 EnableAlphaTest:1; // 2: Perform alpha test, interacts with ALPHA_TEST_REF (0x4000340); 0=Disable, 1=Enable
u8 PolygonShading:1; // 1: Polygon shading mode, interacts with POLYGON_ATTR (0x40004A4); 0=Toon Shading, 1=Highlight Shading u8 PolygonShading:1; // 1: Polygon shading mode, interacts with POLYGON_ATTR (0x40004A4); 0=Toon Shading, 1=Highlight Shading
@ -929,45 +929,6 @@ typedef union
u16 val; u16 val;
} TILEENTRY; } TILEENTRY;
/*
this structure is for color representation,
it holds 5 meaningful bits per color channel (red,green,blue)
and 1 meaningful bit for alpha representation
this bit can be unused or used for special FX
*/
struct _COLOR { // abgr x555
#ifdef MSB_FIRST
unsigned alpha:1; // sometimes it is unused (pad)
unsigned blue:5;
unsigned green:5;
unsigned red:5;
#else
unsigned red:5;
unsigned green:5;
unsigned blue:5;
unsigned alpha:1; // sometimes it is unused (pad)
#endif
};
struct _COLORx { // abgr x555
unsigned bgr:15;
unsigned alpha:1; // sometimes it is unused (pad)
};
typedef union
{
struct _COLOR bits;
struct _COLORx bitx;
u16 val;
} COLOR;
#define COLOR_16_32(w,i) \
/* doesnt matter who's 16bit who's 32bit */ \
i.bits.red = w.bits.red; \
i.bits.green = w.bits.green; \
i.bits.blue = w.bits.blue; \
i.bits.alpha = w.bits.alpha;
typedef union typedef union
{ {
u16 attr[4]; u16 attr[4];
@ -1330,7 +1291,7 @@ typedef struct
GPUDisplayMode displayOutputMode; GPUDisplayMode displayOutputMode;
u16 backdropColor16; u16 backdropColor16;
u16 workingBackdropColor16; u16 workingBackdropColor16;
FragmentColor workingBackdropColor32; Color4u8 workingBackdropColor32;
ColorEffect colorEffect; ColorEffect colorEffect;
u8 blendEVA; u8 blendEVA;
u8 blendEVB; u8 blendEVB;
@ -1341,12 +1302,12 @@ typedef struct
bool masterBrightnessIsMaxOrMin; bool masterBrightnessIsMaxOrMin;
TBlendTable *blendTable555; TBlendTable *blendTable555;
u16 *brightnessUpTable555; Color5551 *brightnessUpTable555;
FragmentColor *brightnessUpTable666; Color4u8 *brightnessUpTable666;
FragmentColor *brightnessUpTable888; Color4u8 *brightnessUpTable888;
u16 *brightnessDownTable555; Color5551 *brightnessDownTable555;
FragmentColor *brightnessDownTable666; Color4u8 *brightnessDownTable666;
FragmentColor *brightnessDownTable888; Color4u8 *brightnessDownTable888;
u8 WIN0_enable[6]; u8 WIN0_enable[6];
u8 WIN1_enable[6]; u8 WIN1_enable[6];
@ -1386,8 +1347,8 @@ typedef struct
size_t xNative; size_t xNative;
size_t xCustom; size_t xCustom;
void **lineColor; void **lineColor;
u16 *lineColor16; Color5551 *lineColor16;
FragmentColor *lineColor32; Color4u8 *lineColor32;
u8 *lineLayerID; u8 *lineLayerID;
} GPUEngineTargetState; } GPUEngineTargetState;
@ -1464,7 +1425,7 @@ protected:
itemsForPriority_t _itemsForPriority[NB_PRIORITIES]; itemsForPriority_t _itemsForPriority[NB_PRIORITIES];
struct MosaicColor { struct MosaicColor {
CACHE_ALIGN u16 bg[4][GPU_FRAMEBUFFER_NATIVE_WIDTH + sizeof(u32)]; // Pad this buffer a little bit to avoid buffer overruns with vectorized gather instructions. CACHE_ALIGN u16 bg[4][GPU_FRAMEBUFFER_NATIVE_WIDTH + 64]; // Pad this buffer a little bit to avoid buffer overruns with vectorized gather instructions.
struct Obj { struct Obj {
u16 color; u16 color;
u8 alpha; u8 alpha;
@ -1503,7 +1464,7 @@ protected:
volatile s32 _asyncClearLineCustom; volatile s32 _asyncClearLineCustom;
volatile s32 _asyncClearInterrupt; volatile s32 _asyncClearInterrupt;
u16 _asyncClearBackdropColor16; // Do not modify this variable directly. u16 _asyncClearBackdropColor16; // Do not modify this variable directly.
FragmentColor _asyncClearBackdropColor32; // Do not modify this variable directly. Color4u8 _asyncClearBackdropColor32; // Do not modify this variable directly.
bool _asyncClearUseInternalCustomBuffer; // Do not modify this variable directly. bool _asyncClearUseInternalCustomBuffer; // Do not modify this variable directly.
void _ResortBGLayers(); void _ResortBGLayers();
@ -1523,11 +1484,11 @@ protected:
template<bool MOSAIC> void _PrecompositeNativeToCustomLineBG(GPUEngineCompositorInfo &compInfo); template<bool MOSAIC> void _PrecompositeNativeToCustomLineBG(GPUEngineCompositorInfo &compInfo);
template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> void _CompositeNativeLineOBJ(GPUEngineCompositorInfo &compInfo, const u16 *__restrict srcColorNative16, const FragmentColor *__restrict srcColorNative32); template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> void _CompositeNativeLineOBJ(GPUEngineCompositorInfo &compInfo, const u16 *__restrict srcColorNative16, const Color4u8 *__restrict srcColorNative32);
template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST> void _CompositeLineDeferred(GPUEngineCompositorInfo &compInfo, const u16 *__restrict srcColorCustom16, const u8 *__restrict srcIndexCustom); template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST> void _CompositeLineDeferred(GPUEngineCompositorInfo &compInfo, const u16 *__restrict srcColorCustom16, const u8 *__restrict srcIndexCustom);
template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST> void _CompositeVRAMLineDeferred(GPUEngineCompositorInfo &compInfo, const void *__restrict vramColorPtr); template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST> void _CompositeVRAMLineDeferred(GPUEngineCompositorInfo &compInfo, const void *__restrict vramColorPtr);
template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> void _CompositeNativeLineOBJ_LoopOp(GPUEngineCompositorInfo &compInfo, const u16 *__restrict srcColorNative16, const FragmentColor *__restrict srcColorNative32); template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> void _CompositeNativeLineOBJ_LoopOp(GPUEngineCompositorInfo &compInfo, const u16 *__restrict srcColorNative16, const Color4u8 *__restrict srcColorNative32);
template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST> size_t _CompositeLineDeferred_LoopOp(GPUEngineCompositorInfo &compInfo, const u8 *__restrict windowTestPtr, const u8 *__restrict colorEffectEnablePtr, const u16 *__restrict srcColorCustom16, const u8 *__restrict srcIndexCustom); template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST> size_t _CompositeLineDeferred_LoopOp(GPUEngineCompositorInfo &compInfo, const u8 *__restrict windowTestPtr, const u8 *__restrict colorEffectEnablePtr, const u16 *__restrict srcColorCustom16, const u8 *__restrict srcIndexCustom);
template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST> size_t _CompositeVRAMLineDeferred_LoopOp(GPUEngineCompositorInfo &compInfo, const u8 *__restrict windowTestPtr, const u8 *__restrict colorEffectEnablePtr, const void *__restrict vramColorPtr); template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST> size_t _CompositeVRAMLineDeferred_LoopOp(GPUEngineCompositorInfo &compInfo, const u8 *__restrict windowTestPtr, const u8 *__restrict colorEffectEnablePtr, const void *__restrict vramColorPtr);
@ -1543,6 +1504,8 @@ protected:
void _RenderLine_SetupSprites(GPUEngineCompositorInfo &compInfo); void _RenderLine_SetupSprites(GPUEngineCompositorInfo &compInfo);
template<NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> void _RenderLine_Layers(GPUEngineCompositorInfo &compInfo); template<NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> void _RenderLine_Layers(GPUEngineCompositorInfo &compInfo);
void _RenderLineBlank(const size_t l);
void _HandleDisplayModeOff(const size_t l); void _HandleDisplayModeOff(const size_t l);
void _HandleDisplayModeNormal(const size_t l); void _HandleDisplayModeNormal(const size_t l);
@ -1609,6 +1572,7 @@ public:
const GPU_IOREG& GetIORegisterMap() const; const GPU_IOREG& GetIORegisterMap() const;
bool IsForceBlankSet() const;
bool IsMasterBrightMaxOrMin() const; bool IsMasterBrightMaxOrMin() const;
bool GetEnableState(); bool GetEnableState();
@ -1620,9 +1584,9 @@ public:
void ApplySettings(); void ApplySettings();
void RenderLineClearAsync(); void RenderLineClearAsync();
void RenderLineClearAsyncStart(bool willClearInternalCustomBuffer, s32 startLineIndex, u16 clearColor16, FragmentColor clearColor32); void RenderLineClearAsyncStart(bool willClearInternalCustomBuffer, size_t startLineIndex, u16 clearColor16, Color4u8 clearColor32);
void RenderLineClearAsyncFinish(); void RenderLineClearAsyncFinish();
void RenderLineClearAsyncWaitForCustomLine(const s32 l); void RenderLineClearAsyncWaitForCustomLine(const size_t l);
void TransitionRenderStatesToDisplayInfo(NDSDisplayInfo &mutableInfo); void TransitionRenderStatesToDisplayInfo(NDSDisplayInfo &mutableInfo);
@ -1651,12 +1615,12 @@ private:
protected: protected:
CACHE_ALIGN u16 _fifoLine16[GPU_FRAMEBUFFER_NATIVE_WIDTH]; CACHE_ALIGN u16 _fifoLine16[GPU_FRAMEBUFFER_NATIVE_WIDTH];
CACHE_ALIGN FragmentColor _fifoLine32[GPU_FRAMEBUFFER_NATIVE_WIDTH]; CACHE_ALIGN Color4u8 _fifoLine32[GPU_FRAMEBUFFER_NATIVE_WIDTH];
CACHE_ALIGN u16 _VRAMNativeBlockCaptureCopy[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_VRAM_BLOCK_LINES * 4]; CACHE_ALIGN u16 _VRAMNativeBlockCaptureCopy[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_VRAM_BLOCK_LINES * 4];
u16 *_VRAMNativeBlockCaptureCopyPtr[4]; u16 *_VRAMNativeBlockCaptureCopyPtr[4];
FragmentColor *_3DFramebufferMain; Color4u8 *_3DFramebufferMain;
u16 *_3DFramebuffer16; u16 *_3DFramebuffer16;
u16 *_VRAMNativeBlockPtr[4]; u16 *_VRAMNativeBlockPtr[4];
@ -1668,8 +1632,8 @@ protected:
u16 *_captureWorkingDisplay16; u16 *_captureWorkingDisplay16;
u16 *_captureWorkingA16; u16 *_captureWorkingA16;
u16 *_captureWorkingB16; u16 *_captureWorkingB16;
FragmentColor *_captureWorkingA32; Color4u8 *_captureWorkingA32;
FragmentColor *_captureWorkingB32; Color4u8 *_captureWorkingB32;
DISPCAPCNT_parsed _dispCapCnt; DISPCAPCNT_parsed _dispCapCnt;
bool _displayCaptureEnable; bool _displayCaptureEnable;
@ -1692,10 +1656,10 @@ protected:
void _RenderLine_DispCapture_Copy(const GPUEngineLineInfo &lineInfo, const void *src, void *dst, const size_t captureLengthExt); // Do not use restrict pointers, since src and dst can be the same void _RenderLine_DispCapture_Copy(const GPUEngineLineInfo &lineInfo, const void *src, void *dst, const size_t captureLengthExt); // Do not use restrict pointers, since src and dst can be the same
u16 _RenderLine_DispCapture_BlendFunc(const u16 srcA, const u16 srcB, const u8 blendEVA, const u8 blendEVB); u16 _RenderLine_DispCapture_BlendFunc(const u16 srcA, const u16 srcB, const u8 blendEVA, const u8 blendEVB);
template<NDSColorFormat COLORFORMAT> FragmentColor _RenderLine_DispCapture_BlendFunc(const FragmentColor srcA, const FragmentColor srcB, const u8 blendEVA, const u8 blendEVB); template<NDSColorFormat COLORFORMAT> Color4u8 _RenderLine_DispCapture_BlendFunc(const Color4u8 srcA, const Color4u8 srcB, const u8 blendEVA, const u8 blendEVB);
template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> template<GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST>
size_t _RenderLine_Layer3D_LoopOp(GPUEngineCompositorInfo &compInfo, const u8 *__restrict windowTestPtr, const u8 *__restrict colorEffectEnablePtr, const FragmentColor *__restrict srcLinePtr); size_t _RenderLine_Layer3D_LoopOp(GPUEngineCompositorInfo &compInfo, const u8 *__restrict windowTestPtr, const u8 *__restrict colorEffectEnablePtr, const Color4u8 *__restrict srcLinePtr);
template<NDSColorFormat OUTPUTFORMAT> template<NDSColorFormat OUTPUTFORMAT>
void _RenderLine_DispCapture_Blend_Buffer(const void *srcA, const void *srcB, void *dst, const u8 blendEVA, const u8 blendEVB, const size_t pixCount); // Do not use restrict pointers, since srcB and dst can be the same void _RenderLine_DispCapture_Blend_Buffer(const void *srcA, const void *srcB, void *dst, const u8 blendEVA, const u8 blendEVB, const size_t pixCount); // Do not use restrict pointers, since srcB and dst can be the same
@ -1716,7 +1680,7 @@ public:
void ParseReg_DISPCAPCNT(); void ParseReg_DISPCAPCNT();
bool IsLineCaptureNative(const size_t blockID, const size_t blockLine); bool IsLineCaptureNative(const size_t blockID, const size_t blockLine);
void* GetCustomVRAMBlockPtr(const size_t blockID); void* GetCustomVRAMBlockPtr(const size_t blockID);
FragmentColor* Get3DFramebufferMain() const; Color4u8* Get3DFramebufferMain() const;
u16* Get3DFramebuffer16() const; u16* Get3DFramebuffer16() const;
virtual void AllocateWorkingBuffers(NDSColorFormat requestedColorFormat, size_t w, size_t h); virtual void AllocateWorkingBuffers(NDSColorFormat requestedColorFormat, size_t w, size_t h);
@ -1819,8 +1783,8 @@ public:
bool IsCustomSizeRequested() const; bool IsCustomSizeRequested() const;
void* GetRenderedBuffer() const; void* GetRenderedBuffer() const;
size_t GetRenderedWidth() const; size_t GetRenderedWidth() const;
size_t GetRenderedHeight() const; size_t GetRenderedHeight() const;
bool IsEnabled() const; bool IsEnabled() const;
void SetIsEnabled(bool stateIsEnabled); void SetIsEnabled(bool stateIsEnabled);
@ -1840,6 +1804,8 @@ public:
class GPUEventHandler class GPUEventHandler
{ {
public: public:
virtual ~GPUEventHandler() {};
virtual void DidFrameBegin(const size_t line, const bool isFrameSkipRequested, const size_t pageCount, u8 &selectedBufferIndexInOut) = 0; virtual void DidFrameBegin(const size_t line, const bool isFrameSkipRequested, const size_t pageCount, u8 &selectedBufferIndexInOut) = 0;
virtual void DidFrameEnd(bool isFrameSkipped, const NDSDisplayInfo &latestDisplayInfo) = 0; virtual void DidFrameEnd(bool isFrameSkipped, const NDSDisplayInfo &latestDisplayInfo) = 0;
virtual void DidRender3DBegin() = 0; virtual void DidRender3DBegin() = 0;
@ -1856,6 +1822,8 @@ public:
class GPUEventHandlerDefault : public GPUEventHandler class GPUEventHandlerDefault : public GPUEventHandler
{ {
public: public:
virtual ~GPUEventHandlerDefault() {};
virtual void DidFrameBegin(const size_t line, const bool isFrameSkipRequested, const size_t pageCount, u8 &selectedBufferIndexInOut); virtual void DidFrameBegin(const size_t line, const bool isFrameSkipRequested, const size_t pageCount, u8 &selectedBufferIndexInOut);
virtual void DidFrameEnd(bool isFrameSkipped, const NDSDisplayInfo &latestDisplayInfo) {}; virtual void DidFrameEnd(bool isFrameSkipped, const NDSDisplayInfo &latestDisplayInfo) {};
virtual void DidRender3DBegin() {}; virtual void DidRender3DBegin() {};

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2021 DeSmuME team Copyright (C) 2021-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -31,177 +31,160 @@ static CACHE_ALIGN u32 _gpuDstPitchCount[GPU_FRAMEBUFFER_NATIVE_WIDTH]; // Key:
static CACHE_ALIGN u32 _gpuDstPitchIndex[GPU_FRAMEBUFFER_NATIVE_WIDTH]; // Key: Source pixel index in x-dimension / Value: First destination pixel that maps to the source pixel static CACHE_ALIGN u32 _gpuDstPitchIndex[GPU_FRAMEBUFFER_NATIVE_WIDTH]; // Key: Source pixel index in x-dimension / Value: First destination pixel that maps to the source pixel
u8 PixelOperation::BlendTable555[17][17][32][32]; u8 PixelOperation::BlendTable555[17][17][32][32];
u16 PixelOperation::BrightnessUpTable555[17][0x8000]; Color5551 PixelOperation::BrightnessUpTable555[17][0x8000];
FragmentColor PixelOperation::BrightnessUpTable666[17][0x8000]; Color4u8 PixelOperation::BrightnessUpTable666[17][0x8000];
FragmentColor PixelOperation::BrightnessUpTable888[17][0x8000]; Color4u8 PixelOperation::BrightnessUpTable888[17][0x8000];
u16 PixelOperation::BrightnessDownTable555[17][0x8000]; Color5551 PixelOperation::BrightnessDownTable555[17][0x8000];
FragmentColor PixelOperation::BrightnessDownTable666[17][0x8000]; Color4u8 PixelOperation::BrightnessDownTable666[17][0x8000];
FragmentColor PixelOperation::BrightnessDownTable888[17][0x8000]; Color4u8 PixelOperation::BrightnessDownTable888[17][0x8000];
static CACHE_ALIGN ColorOperation colorop; static CACHE_ALIGN ColorOperation colorop;
static CACHE_ALIGN PixelOperation pixelop; static CACHE_ALIGN PixelOperation pixelop;
FORCEINLINE u16 ColorOperation::blend(const u16 colA, const u16 colB, const u16 blendEVA, const u16 blendEVB) const FORCEINLINE Color5551 ColorOperation::blend(const Color5551 colA, const Color5551 colB, const u16 blendEVA, const u16 blendEVB) const
{ {
u16 ra = colA & 0x001F; const u16 r = ( (colA.r * blendEVA) + (colB.r * blendEVB) ) / 16;
u16 ga = (colA >> 5) & 0x001F; const u16 g = ( (colA.g * blendEVA) + (colB.g * blendEVB) ) / 16;
u16 ba = (colA >> 10) & 0x001F; const u16 b = ( (colA.b * blendEVA) + (colB.b * blendEVB) ) / 16;
u16 rb = colB & 0x001F;
u16 gb = (colB >> 5) & 0x001F;
u16 bb = (colB >> 10) & 0x001F;
ra = ( (ra * blendEVA) + (rb * blendEVB) ) / 16; Color5551 outColor;
ga = ( (ga * blendEVA) + (gb * blendEVB) ) / 16; outColor.r = (r > 31) ? 31 : r;
ba = ( (ba * blendEVA) + (bb * blendEVB) ) / 16; outColor.g = (g > 31) ? 31 : g;
outColor.b = (b > 31) ? 31 : b;
outColor.a = 0;
ra = (ra > 31) ? 31 : ra; return outColor;
ga = (ga > 31) ? 31 : ga;
ba = (ba > 31) ? 31 : ba;
return ra | (ga << 5) | (ba << 10);
} }
FORCEINLINE u16 ColorOperation::blend(const u16 colA, const u16 colB, const TBlendTable *blendTable) const FORCEINLINE Color5551 ColorOperation::blend(const Color5551 colA, const Color5551 colB, const TBlendTable *blendTable) const
{ {
const u8 r = (*blendTable)[ colA & 0x1F][ colB & 0x1F]; Color5551 outColor;
const u8 g = (*blendTable)[(colA >> 5) & 0x1F][(colB >> 5) & 0x1F]; outColor.r = (*blendTable)[colA.r][colB.r];
const u8 b = (*blendTable)[(colA >> 10) & 0x1F][(colB >> 10) & 0x1F]; outColor.g = (*blendTable)[colA.g][colB.g];
outColor.b = (*blendTable)[colA.b][colB.b];
outColor.a = 0;
return r | (g << 5) | (b << 10); return outColor;
} }
template <NDSColorFormat COLORFORMAT> template <NDSColorFormat COLORFORMAT>
FORCEINLINE FragmentColor ColorOperation::blend(const FragmentColor colA, const FragmentColor colB, const u16 blendEVA, const u16 blendEVB) const FORCEINLINE Color4u8 ColorOperation::blend(const Color4u8 colA, const Color4u8 colB, const u16 blendEVA, const u16 blendEVB) const
{ {
FragmentColor outColor; Color4u8 outColor;
const u16 r = ( ((u16)colA.r * blendEVA) + ((u16)colB.r * blendEVB) ) / 16;
u16 r16 = ( (colA.r * blendEVA) + (colB.r * blendEVB) ) / 16; const u16 g = ( ((u16)colA.g * blendEVA) + ((u16)colB.g * blendEVB) ) / 16;
u16 g16 = ( (colA.g * blendEVA) + (colB.g * blendEVB) ) / 16; const u16 b = ( ((u16)colA.b * blendEVA) + ((u16)colB.b * blendEVB) ) / 16;
u16 b16 = ( (colA.b * blendEVA) + (colB.b * blendEVB) ) / 16;
if (COLORFORMAT == NDSColorFormat_BGR666_Rev) if (COLORFORMAT == NDSColorFormat_BGR666_Rev)
{ {
outColor.r = (r16 > 63) ? 63 : r16; outColor.r = (u8)( (r > 63) ? 63 : r );
outColor.g = (g16 > 63) ? 63 : g16; outColor.g = (u8)( (g > 63) ? 63 : g );
outColor.b = (b16 > 63) ? 63 : b16; outColor.b = (u8)( (b > 63) ? 63 : b );
} }
else if (COLORFORMAT == NDSColorFormat_BGR888_Rev) else if (COLORFORMAT == NDSColorFormat_BGR888_Rev)
{ {
outColor.r = (r16 > 255) ? 255 : r16; outColor.r = (u8)( (r > 255) ? 255 : r );
outColor.g = (g16 > 255) ? 255 : g16; outColor.g = (u8)( (g > 255) ? 255 : g );
outColor.b = (b16 > 255) ? 255 : b16; outColor.b = (u8)( (b > 255) ? 255 : b );
} }
outColor.a = 0; outColor.a = 0;
return outColor; return outColor;
} }
FORCEINLINE u16 ColorOperation::blend3D(const FragmentColor colA, const u16 colB) const FORCEINLINE Color5551 ColorOperation::blend3D(const Color4u8 colA, const Color5551 colB) const
{ {
const u16 alpha = colA.a + 1; const u16 alpha = colA.a + 1;
COLOR c2; const u16 minusAlpha = 32 - alpha;
COLOR cfinal;
c2.val = colB; Color5551 outColor;
outColor.r = (u8)( (((u16)colA.r * alpha) + ((colB.r << 1) * minusAlpha)) >> 6 );
outColor.g = (u8)( (((u16)colA.g * alpha) + ((colB.g << 1) * minusAlpha)) >> 6 );
outColor.b = (u8)( (((u16)colA.b * alpha) + ((colB.b << 1) * minusAlpha)) >> 6 );
outColor.a = 0;
cfinal.bits.red = ((colA.r * alpha) + ((c2.bits.red << 1) * (32 - alpha))) >> 6; return outColor;
cfinal.bits.green = ((colA.g * alpha) + ((c2.bits.green << 1) * (32 - alpha))) >> 6;
cfinal.bits.blue = ((colA.b * alpha) + ((c2.bits.blue << 1) * (32 - alpha))) >> 6;
cfinal.bits.alpha = 0;
return cfinal.val;
} }
template <NDSColorFormat COLORFORMAT> template <NDSColorFormat COLORFORMAT>
FORCEINLINE FragmentColor ColorOperation::blend3D(const FragmentColor colA, const FragmentColor colB) const FORCEINLINE Color4u8 ColorOperation::blend3D(const Color4u8 colA, const Color4u8 colB) const
{ {
FragmentColor blendedColor; Color4u8 outColor;
const u16 alpha = colA.a + 1; const u16 alpha = colA.a + 1;
if (COLORFORMAT == NDSColorFormat_BGR666_Rev) if (COLORFORMAT == NDSColorFormat_BGR666_Rev)
{ {
blendedColor.r = ((colA.r * alpha) + (colB.r * (32 - alpha))) >> 5; const u16 minusAlpha = 32 - alpha;
blendedColor.g = ((colA.g * alpha) + (colB.g * (32 - alpha))) >> 5; outColor.r = (u8)( (((u16)colA.r * alpha) + ((u16)colB.r * minusAlpha)) >> 5 );
blendedColor.b = ((colA.b * alpha) + (colB.b * (32 - alpha))) >> 5; outColor.g = (u8)( (((u16)colA.g * alpha) + ((u16)colB.g * minusAlpha)) >> 5 );
outColor.b = (u8)( (((u16)colA.b * alpha) + ((u16)colB.b * minusAlpha)) >> 5 );
} }
else if (COLORFORMAT == NDSColorFormat_BGR888_Rev) else if (COLORFORMAT == NDSColorFormat_BGR888_Rev)
{ {
blendedColor.r = ((colA.r * alpha) + (colB.r * (256 - alpha))) >> 8; const u16 minusAlpha = 256 - alpha;
blendedColor.g = ((colA.g * alpha) + (colB.g * (256 - alpha))) >> 8; outColor.r = (u8)( (((u16)colA.r * alpha) + ((u16)colB.r * minusAlpha)) >> 8 );
blendedColor.b = ((colA.b * alpha) + (colB.b * (256 - alpha))) >> 8; outColor.g = (u8)( (((u16)colA.g * alpha) + ((u16)colB.g * minusAlpha)) >> 8 );
outColor.b = (u8)( (((u16)colA.b * alpha) + ((u16)colB.b * minusAlpha)) >> 8 );
} }
blendedColor.a = 0; outColor.a = 0;
return blendedColor; return outColor;
} }
FORCEINLINE u16 ColorOperation::increase(const u16 col, const u16 blendEVY) const FORCEINLINE Color5551 ColorOperation::increase(const Color5551 col, const u16 blendEVY) const
{ {
u16 r = col & 0x001F; Color5551 outColor;
u16 g = (col >> 5) & 0x001F; outColor.r = (col.r + ((31 - col.r) * blendEVY / 16));
u16 b = (col >> 10) & 0x001F; outColor.g = (col.g + ((31 - col.g) * blendEVY / 16));
outColor.b = (col.b + ((31 - col.b) * blendEVY / 16));
outColor.a = 0;
r = (r + ((31 - r) * blendEVY / 16)); return outColor;
g = (g + ((31 - g) * blendEVY / 16));
b = (b + ((31 - b) * blendEVY / 16));
return r | (g << 5) | (b << 10);
} }
template <NDSColorFormat COLORFORMAT> template <NDSColorFormat COLORFORMAT>
FORCEINLINE FragmentColor ColorOperation::increase(const FragmentColor col, const u16 blendEVY) const FORCEINLINE Color4u8 ColorOperation::increase(const Color4u8 col, const u16 blendEVY) const
{ {
FragmentColor newColor; Color4u8 outColor;
newColor.color = 0;
u32 r = col.r;
u32 g = col.g;
u32 b = col.b;
if (COLORFORMAT == NDSColorFormat_BGR666_Rev) if (COLORFORMAT == NDSColorFormat_BGR666_Rev)
{ {
newColor.r = (r + ((63 - r) * blendEVY / 16)); outColor.r = (u8)( (u16)col.r + ((63 - (u16)col.r) * blendEVY / 16) );
newColor.g = (g + ((63 - g) * blendEVY / 16)); outColor.g = (u8)( (u16)col.g + ((63 - (u16)col.g) * blendEVY / 16) );
newColor.b = (b + ((63 - b) * blendEVY / 16)); outColor.b = (u8)( (u16)col.b + ((63 - (u16)col.b) * blendEVY / 16) );
} }
else if (COLORFORMAT == NDSColorFormat_BGR888_Rev) else if (COLORFORMAT == NDSColorFormat_BGR888_Rev)
{ {
newColor.r = (r + ((255 - r) * blendEVY / 16)); outColor.r = (u8)( (u16)col.r + ((255 - (u16)col.r) * blendEVY / 16) );
newColor.g = (g + ((255 - g) * blendEVY / 16)); outColor.g = (u8)( (u16)col.g + ((255 - (u16)col.g) * blendEVY / 16) );
newColor.b = (b + ((255 - b) * blendEVY / 16)); outColor.b = (u8)( (u16)col.b + ((255 - (u16)col.b) * blendEVY / 16) );
} }
return newColor; outColor.a = 0;
return outColor;
} }
FORCEINLINE u16 ColorOperation::decrease(const u16 col, const u16 blendEVY) const FORCEINLINE Color5551 ColorOperation::decrease(const Color5551 col, const u16 blendEVY) const
{ {
u16 r = col & 0x001F; Color5551 outColor;
u16 g = (col >> 5) & 0x001F; outColor.r = (col.r - (col.r * blendEVY / 16));
u16 b = (col >> 10) & 0x001F; outColor.g = (col.g - (col.g * blendEVY / 16));
outColor.b = (col.b - (col.b * blendEVY / 16));
outColor.a = 0;
r = (r - (r * blendEVY / 16)); return outColor;
g = (g - (g * blendEVY / 16));
b = (b - (b * blendEVY / 16));
return r | (g << 5) | (b << 10);
} }
template <NDSColorFormat COLORFORMAT> template <NDSColorFormat COLORFORMAT>
FORCEINLINE FragmentColor ColorOperation::decrease(const FragmentColor col, const u16 blendEVY) const FORCEINLINE Color4u8 ColorOperation::decrease(const Color4u8 col, const u16 blendEVY) const
{ {
FragmentColor newColor; Color4u8 outColor;
newColor.color = 0; outColor.r = (u8)( (u16)col.r - ((u16)col.r * blendEVY / 16) );
outColor.g = (u8)( (u16)col.g - ((u16)col.g * blendEVY / 16) );
outColor.b = (u8)( (u16)col.b - ((u16)col.b * blendEVY / 16) );
outColor.a = 0;
u32 r = col.r; return outColor;
u32 g = col.g;
u32 b = col.b;
newColor.r = (r - (r * blendEVY / 16));
newColor.g = (g - (g * blendEVY / 16));
newColor.b = (b - (b * blendEVY / 16));
return newColor;
} }
void PixelOperation::InitLUTs() void PixelOperation::InitLUTs()
@ -234,25 +217,25 @@ void PixelOperation::InitLUTs()
{ {
for (u16 j = 0x0000; j < 0x8000; j++) for (u16 j = 0x0000; j < 0x8000; j++)
{ {
COLOR cur; Color5551 cur;
cur.val = j; cur.value = j;
cur.bits.red = (cur.bits.red + ((31 - cur.bits.red) * i / 16)); cur.r = ( cur.r + ((31 - cur.r) * i / 16) );
cur.bits.green = (cur.bits.green + ((31 - cur.bits.green) * i / 16)); cur.g = ( cur.g + ((31 - cur.g) * i / 16) );
cur.bits.blue = (cur.bits.blue + ((31 - cur.bits.blue) * i / 16)); cur.b = ( cur.b + ((31 - cur.b) * i / 16) );
cur.bits.alpha = 0; cur.a = 0;
PixelOperation::BrightnessUpTable555[i][j] = cur.val; PixelOperation::BrightnessUpTable555[i][j] = cur;
PixelOperation::BrightnessUpTable666[i][j].color = LOCAL_TO_LE_32( COLOR555TO666(cur.val) ); PixelOperation::BrightnessUpTable666[i][j].value = COLOR555TO666(cur.value);
PixelOperation::BrightnessUpTable888[i][j].color = LOCAL_TO_LE_32( COLOR555TO888(cur.val) ); PixelOperation::BrightnessUpTable888[i][j].value = COLOR555TO888(cur.value);
cur.val = j; cur.value = j;
cur.bits.red = (cur.bits.red - (cur.bits.red * i / 16)); cur.r = ( cur.r - (cur.r * i / 16) );
cur.bits.green = (cur.bits.green - (cur.bits.green * i / 16)); cur.g = ( cur.g - (cur.g * i / 16) );
cur.bits.blue = (cur.bits.blue - (cur.bits.blue * i / 16)); cur.b = ( cur.b - (cur.b * i / 16) );
cur.bits.alpha = 0; cur.a = 0;
PixelOperation::BrightnessDownTable555[i][j] = cur.val; PixelOperation::BrightnessDownTable555[i][j] = cur;
PixelOperation::BrightnessDownTable666[i][j].color = LOCAL_TO_LE_32( COLOR555TO666(cur.val) ); PixelOperation::BrightnessDownTable666[i][j].value = COLOR555TO666(cur.value);
PixelOperation::BrightnessDownTable888[i][j].color = LOCAL_TO_LE_32( COLOR555TO888(cur.val) ); PixelOperation::BrightnessDownTable888[i][j].value = COLOR555TO888(cur.value);
} }
} }
@ -276,24 +259,25 @@ void PixelOperation::InitLUTs()
} }
template <NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> template <NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER>
FORCEINLINE void PixelOperation::_copy16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16) const FORCEINLINE void PixelOperation::_copy16(GPUEngineCompositorInfo &compInfo, const Color5551 srcColor16) const
{ {
u16 &dstColor16 = *compInfo.target.lineColor16; Color5551 &dstColor16 = *compInfo.target.lineColor16;
FragmentColor &dstColor32 = *compInfo.target.lineColor32; Color4u8 &dstColor32 = *compInfo.target.lineColor32;
u8 &dstLayerID = *compInfo.target.lineLayerID; u8 &dstLayerID = *compInfo.target.lineLayerID;
switch (OUTPUTFORMAT) switch (OUTPUTFORMAT)
{ {
case NDSColorFormat_BGR555_Rev: case NDSColorFormat_BGR555_Rev:
dstColor16 = srcColor16 | 0x8000; dstColor16 = srcColor16;
dstColor16.a = 1;
break; break;
case NDSColorFormat_BGR666_Rev: case NDSColorFormat_BGR666_Rev:
dstColor32.color = LE_TO_LOCAL_32( ColorspaceConvert555To6665Opaque<false>(srcColor16) ); dstColor32.value = ColorspaceConvert555To6665Opaque<false>(srcColor16.value);
break; break;
case NDSColorFormat_BGR888_Rev: case NDSColorFormat_BGR888_Rev:
dstColor32.color = LE_TO_LOCAL_32( ColorspaceConvert555To8888Opaque<false>(srcColor16) ); dstColor32.value = ColorspaceConvert555To8888Opaque<false>(srcColor16.value);
break; break;
} }
@ -304,17 +288,17 @@ FORCEINLINE void PixelOperation::_copy16(GPUEngineCompositorInfo &compInfo, cons
} }
template <NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> template <NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER>
FORCEINLINE void PixelOperation::_copy32(GPUEngineCompositorInfo &compInfo, const FragmentColor srcColor32) const FORCEINLINE void PixelOperation::_copy32(GPUEngineCompositorInfo &compInfo, const Color4u8 srcColor32) const
{ {
u16 &dstColor16 = *compInfo.target.lineColor16; Color5551 &dstColor16 = *compInfo.target.lineColor16;
FragmentColor &dstColor32 = *compInfo.target.lineColor32; Color4u8 &dstColor32 = *compInfo.target.lineColor32;
u8 &dstLayerID = *compInfo.target.lineLayerID; u8 &dstLayerID = *compInfo.target.lineLayerID;
switch (OUTPUTFORMAT) switch (OUTPUTFORMAT)
{ {
case NDSColorFormat_BGR555_Rev: case NDSColorFormat_BGR555_Rev:
dstColor16 = ColorspaceConvert6665To5551<false>(srcColor32); dstColor16.value = ColorspaceConvert6665To5551<false>(srcColor32);
dstColor16 = dstColor16 | 0x8000; dstColor16.a = 1;
break; break;
case NDSColorFormat_BGR666_Rev: case NDSColorFormat_BGR666_Rev:
@ -338,25 +322,26 @@ FORCEINLINE void PixelOperation::_copy32(GPUEngineCompositorInfo &compInfo, cons
} }
template <NDSColorFormat OUTPUTFORMAT> template <NDSColorFormat OUTPUTFORMAT>
FORCEINLINE void PixelOperation::_brightnessUp16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16) const FORCEINLINE void PixelOperation::_brightnessUp16(GPUEngineCompositorInfo &compInfo, const Color5551 srcColor16) const
{ {
u16 &dstColor16 = *compInfo.target.lineColor16; Color5551 &dstColor16 = *compInfo.target.lineColor16;
FragmentColor &dstColor32 = *compInfo.target.lineColor32; Color4u8 &dstColor32 = *compInfo.target.lineColor32;
u8 &dstLayerID = *compInfo.target.lineLayerID; u8 &dstLayerID = *compInfo.target.lineLayerID;
switch (OUTPUTFORMAT) switch (OUTPUTFORMAT)
{ {
case NDSColorFormat_BGR555_Rev: case NDSColorFormat_BGR555_Rev:
dstColor16 = compInfo.renderState.brightnessUpTable555[srcColor16 & 0x7FFF] | 0x8000; dstColor16 = compInfo.renderState.brightnessUpTable555[srcColor16.value & 0x7FFF];
dstColor16.a = 1;
break; break;
case NDSColorFormat_BGR666_Rev: case NDSColorFormat_BGR666_Rev:
dstColor32 = compInfo.renderState.brightnessUpTable666[srcColor16 & 0x7FFF]; dstColor32 = compInfo.renderState.brightnessUpTable666[srcColor16.value & 0x7FFF];
dstColor32.a = 0x1F; dstColor32.a = 0x1F;
break; break;
case NDSColorFormat_BGR888_Rev: case NDSColorFormat_BGR888_Rev:
dstColor32 = compInfo.renderState.brightnessUpTable888[srcColor16 & 0x7FFF]; dstColor32 = compInfo.renderState.brightnessUpTable888[srcColor16.value & 0x7FFF];
dstColor32.a = 0xFF; dstColor32.a = 0xFF;
break; break;
} }
@ -365,17 +350,17 @@ FORCEINLINE void PixelOperation::_brightnessUp16(GPUEngineCompositorInfo &compIn
} }
template <NDSColorFormat OUTPUTFORMAT> template <NDSColorFormat OUTPUTFORMAT>
FORCEINLINE void PixelOperation::_brightnessUp32(GPUEngineCompositorInfo &compInfo, const FragmentColor srcColor32) const FORCEINLINE void PixelOperation::_brightnessUp32(GPUEngineCompositorInfo &compInfo, const Color4u8 srcColor32) const
{ {
u16 &dstColor16 = *compInfo.target.lineColor16; Color5551 &dstColor16 = *compInfo.target.lineColor16;
FragmentColor &dstColor32 = *compInfo.target.lineColor32; Color4u8 &dstColor32 = *compInfo.target.lineColor32;
u8 &dstLayerID = *compInfo.target.lineLayerID; u8 &dstLayerID = *compInfo.target.lineLayerID;
if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev)
{ {
const u16 srcColor16 = ColorspaceConvert6665To5551<false>(srcColor32); const u16 srcColor16 = ColorspaceConvert6665To5551<false>(srcColor32);
dstColor16 = compInfo.renderState.brightnessUpTable555[srcColor16 & 0x7FFF]; dstColor16 = compInfo.renderState.brightnessUpTable555[srcColor16 & 0x7FFF];
dstColor16 = dstColor16 | 0x8000; dstColor16.a = 1;
} }
else else
{ {
@ -387,25 +372,26 @@ FORCEINLINE void PixelOperation::_brightnessUp32(GPUEngineCompositorInfo &compIn
} }
template <NDSColorFormat OUTPUTFORMAT> template <NDSColorFormat OUTPUTFORMAT>
FORCEINLINE void PixelOperation::_brightnessDown16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16) const FORCEINLINE void PixelOperation::_brightnessDown16(GPUEngineCompositorInfo &compInfo, const Color5551 srcColor16) const
{ {
u16 &dstColor16 = *compInfo.target.lineColor16; Color5551 &dstColor16 = *compInfo.target.lineColor16;
FragmentColor &dstColor32 = *compInfo.target.lineColor32; Color4u8 &dstColor32 = *compInfo.target.lineColor32;
u8 &dstLayerID = *compInfo.target.lineLayerID; u8 &dstLayerID = *compInfo.target.lineLayerID;
switch (OUTPUTFORMAT) switch (OUTPUTFORMAT)
{ {
case NDSColorFormat_BGR555_Rev: case NDSColorFormat_BGR555_Rev:
dstColor16 = compInfo.renderState.brightnessDownTable555[srcColor16 & 0x7FFF] | 0x8000; dstColor16 = compInfo.renderState.brightnessDownTable555[srcColor16.value & 0x7FFF];
dstColor16.a = 1;
break; break;
case NDSColorFormat_BGR666_Rev: case NDSColorFormat_BGR666_Rev:
dstColor32 = compInfo.renderState.brightnessDownTable666[srcColor16 & 0x7FFF]; dstColor32 = compInfo.renderState.brightnessDownTable666[srcColor16.value & 0x7FFF];
dstColor32.a = 0x1F; dstColor32.a = 0x1F;
break; break;
case NDSColorFormat_BGR888_Rev: case NDSColorFormat_BGR888_Rev:
dstColor32 = compInfo.renderState.brightnessDownTable888[srcColor16 & 0x7FFF]; dstColor32 = compInfo.renderState.brightnessDownTable888[srcColor16.value & 0x7FFF];
dstColor32.a = 0xFF; dstColor32.a = 0xFF;
break; break;
} }
@ -414,17 +400,17 @@ FORCEINLINE void PixelOperation::_brightnessDown16(GPUEngineCompositorInfo &comp
} }
template <NDSColorFormat OUTPUTFORMAT> template <NDSColorFormat OUTPUTFORMAT>
FORCEINLINE void PixelOperation::_brightnessDown32(GPUEngineCompositorInfo &compInfo, const FragmentColor srcColor32) const FORCEINLINE void PixelOperation::_brightnessDown32(GPUEngineCompositorInfo &compInfo, const Color4u8 srcColor32) const
{ {
u16 &dstColor16 = *compInfo.target.lineColor16; Color5551 &dstColor16 = *compInfo.target.lineColor16;
FragmentColor &dstColor32 = *compInfo.target.lineColor32; Color4u8 &dstColor32 = *compInfo.target.lineColor32;
u8 &dstLayerID = *compInfo.target.lineLayerID; u8 &dstLayerID = *compInfo.target.lineLayerID;
if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev)
{ {
const u16 srcColor16 = ColorspaceConvert6665To5551<false>(srcColor32); const u16 srcColor16 = ColorspaceConvert6665To5551<false>(srcColor32);
dstColor16 = compInfo.renderState.brightnessDownTable555[srcColor16 & 0x7FFF]; dstColor16 = compInfo.renderState.brightnessDownTable555[srcColor16 & 0x7FFF];
dstColor16 = dstColor16 | 0x8000; dstColor16.a = 1;
} }
else else
{ {
@ -504,7 +490,7 @@ FORCEINLINE void PixelOperation::__selectedEffect(const GPUEngineCompositorInfo
} }
template <NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> template <NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void PixelOperation::_unknownEffect16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode) const FORCEINLINE void PixelOperation::_unknownEffect16(GPUEngineCompositorInfo &compInfo, const Color5551 srcColor16, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode) const
{ {
u8 &dstLayerID = *compInfo.target.lineLayerID; u8 &dstLayerID = *compInfo.target.lineLayerID;
TBlendTable *selectedBlendTable = compInfo.renderState.blendTable555; TBlendTable *selectedBlendTable = compInfo.renderState.blendTable555;
@ -519,7 +505,7 @@ FORCEINLINE void PixelOperation::_unknownEffect16(GPUEngineCompositorInfo &compI
if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev)
{ {
u16 &dstColor16 = *compInfo.target.lineColor16; Color5551 &dstColor16 = *compInfo.target.lineColor16;
switch (selectedEffect) switch (selectedEffect)
{ {
@ -528,11 +514,11 @@ FORCEINLINE void PixelOperation::_unknownEffect16(GPUEngineCompositorInfo &compI
break; break;
case ColorEffect_IncreaseBrightness: case ColorEffect_IncreaseBrightness:
dstColor16 = compInfo.renderState.brightnessUpTable555[srcColor16 & 0x7FFF]; dstColor16 = compInfo.renderState.brightnessUpTable555[srcColor16.value & 0x7FFF];
break; break;
case ColorEffect_DecreaseBrightness: case ColorEffect_DecreaseBrightness:
dstColor16 = compInfo.renderState.brightnessDownTable555[srcColor16 & 0x7FFF]; dstColor16 = compInfo.renderState.brightnessDownTable555[srcColor16.value & 0x7FFF];
break; break;
case ColorEffect_Blend: case ColorEffect_Blend:
@ -551,32 +537,32 @@ FORCEINLINE void PixelOperation::_unknownEffect16(GPUEngineCompositorInfo &compI
} }
} }
dstColor16 |= 0x8000; dstColor16.a = 1;
} }
else else
{ {
FragmentColor &dstColor32 = *compInfo.target.lineColor32; Color4u8 &dstColor32 = *compInfo.target.lineColor32;
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
switch (selectedEffect) switch (selectedEffect)
{ {
case ColorEffect_Disable: case ColorEffect_Disable:
dstColor32.color = LE_TO_LOCAL_32( ColorspaceConvert555To6665Opaque<false>(srcColor16) ); dstColor32.value = ColorspaceConvert555To6665Opaque<false>(srcColor16.value);
break; break;
case ColorEffect_IncreaseBrightness: case ColorEffect_IncreaseBrightness:
dstColor32 = compInfo.renderState.brightnessUpTable666[srcColor16 & 0x7FFF]; dstColor32 = compInfo.renderState.brightnessUpTable666[srcColor16.value & 0x7FFF];
break; break;
case ColorEffect_DecreaseBrightness: case ColorEffect_DecreaseBrightness:
dstColor32 = compInfo.renderState.brightnessDownTable666[srcColor16 & 0x7FFF]; dstColor32 = compInfo.renderState.brightnessDownTable666[srcColor16.value & 0x7FFF];
break; break;
case ColorEffect_Blend: case ColorEffect_Blend:
{ {
FragmentColor srcColor32; Color4u8 srcColor32;
srcColor32.color = LE_TO_LOCAL_32( ColorspaceConvert555To6665Opaque<false>(srcColor16) ); srcColor32.value = ColorspaceConvert555To6665Opaque<false>(srcColor16.value);
dstColor32 = (LAYERTYPE == GPULayerType_3D) ? colorop.blend3D<OUTPUTFORMAT>(srcColor32, dstColor32) : colorop.blend<OUTPUTFORMAT>(srcColor32, dstColor32, blendEVA, blendEVB); dstColor32 = (LAYERTYPE == GPULayerType_3D) ? colorop.blend3D<OUTPUTFORMAT>(srcColor32, dstColor32) : colorop.blend<OUTPUTFORMAT>(srcColor32, dstColor32, blendEVA, blendEVB);
break; break;
} }
@ -587,21 +573,21 @@ FORCEINLINE void PixelOperation::_unknownEffect16(GPUEngineCompositorInfo &compI
switch (selectedEffect) switch (selectedEffect)
{ {
case ColorEffect_Disable: case ColorEffect_Disable:
dstColor32.color = LE_TO_LOCAL_32( ColorspaceConvert555To8888Opaque<false>(srcColor16) ); dstColor32.value = ColorspaceConvert555To8888Opaque<false>(srcColor16.value);
break; break;
case ColorEffect_IncreaseBrightness: case ColorEffect_IncreaseBrightness:
dstColor32 = compInfo.renderState.brightnessUpTable888[srcColor16 & 0x7FFF]; dstColor32 = compInfo.renderState.brightnessUpTable888[srcColor16.value & 0x7FFF];
break; break;
case ColorEffect_DecreaseBrightness: case ColorEffect_DecreaseBrightness:
dstColor32 = compInfo.renderState.brightnessDownTable888[srcColor16 & 0x7FFF]; dstColor32 = compInfo.renderState.brightnessDownTable888[srcColor16.value & 0x7FFF];
break; break;
case ColorEffect_Blend: case ColorEffect_Blend:
{ {
FragmentColor srcColor32; Color4u8 srcColor32;
srcColor32.color = LE_TO_LOCAL_32( ColorspaceConvert555To8888Opaque<false>(srcColor16) ); srcColor32.value = ColorspaceConvert555To8888Opaque<false>(srcColor16.value);
dstColor32 = (LAYERTYPE == GPULayerType_3D) ? colorop.blend3D<OUTPUTFORMAT>(srcColor32, dstColor32) : colorop.blend<OUTPUTFORMAT>(srcColor32, dstColor32, blendEVA, blendEVB); dstColor32 = (LAYERTYPE == GPULayerType_3D) ? colorop.blend3D<OUTPUTFORMAT>(srcColor32, dstColor32) : colorop.blend<OUTPUTFORMAT>(srcColor32, dstColor32, blendEVA, blendEVB);
break; break;
} }
@ -613,7 +599,7 @@ FORCEINLINE void PixelOperation::_unknownEffect16(GPUEngineCompositorInfo &compI
} }
template <NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> template <NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void PixelOperation::_unknownEffect32(GPUEngineCompositorInfo &compInfo, const FragmentColor srcColor32, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode) const FORCEINLINE void PixelOperation::_unknownEffect32(GPUEngineCompositorInfo &compInfo, const Color4u8 srcColor32, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode) const
{ {
u8 &dstLayerID = *compInfo.target.lineLayerID; u8 &dstLayerID = *compInfo.target.lineLayerID;
TBlendTable *selectedBlendTable = compInfo.renderState.blendTable555; TBlendTable *selectedBlendTable = compInfo.renderState.blendTable555;
@ -628,8 +614,10 @@ FORCEINLINE void PixelOperation::_unknownEffect32(GPUEngineCompositorInfo &compI
if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR555_Rev)
{ {
const u16 srcColor16 = ColorspaceConvert6665To5551<false>(srcColor32); Color5551 srcColor16;
u16 &dstColor16 = *compInfo.target.lineColor16; srcColor16.value = ColorspaceConvert6665To5551<false>(srcColor32);
Color5551 &dstColor16 = *compInfo.target.lineColor16;
switch (selectedEffect) switch (selectedEffect)
{ {
@ -638,11 +626,11 @@ FORCEINLINE void PixelOperation::_unknownEffect32(GPUEngineCompositorInfo &compI
break; break;
case ColorEffect_IncreaseBrightness: case ColorEffect_IncreaseBrightness:
dstColor16 = compInfo.renderState.brightnessUpTable555[srcColor16 & 0x7FFF]; dstColor16 = compInfo.renderState.brightnessUpTable555[srcColor16.value & 0x7FFF];
break; break;
case ColorEffect_DecreaseBrightness: case ColorEffect_DecreaseBrightness:
dstColor16 = compInfo.renderState.brightnessDownTable555[srcColor16 & 0x7FFF]; dstColor16 = compInfo.renderState.brightnessDownTable555[srcColor16.value & 0x7FFF];
break; break;
case ColorEffect_Blend: case ColorEffect_Blend:
@ -659,11 +647,11 @@ FORCEINLINE void PixelOperation::_unknownEffect32(GPUEngineCompositorInfo &compI
} }
} }
dstColor16 |= 0x8000; dstColor16.a = 1;
} }
else else
{ {
FragmentColor &dstColor32 = *compInfo.target.lineColor32; Color4u8 &dstColor32 = *compInfo.target.lineColor32;
switch (selectedEffect) switch (selectedEffect)
{ {
@ -691,32 +679,35 @@ FORCEINLINE void PixelOperation::_unknownEffect32(GPUEngineCompositorInfo &compI
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void PixelOperation::Composite16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16, const bool enableColorEffect, const u8 spriteAlpha, const u8 spriteMode) const FORCEINLINE void PixelOperation::Composite16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16, const bool enableColorEffect, const u8 spriteAlpha, const u8 spriteMode) const
{ {
Color5551 srcColor5551;
srcColor5551.value = srcColor16;
switch (COMPOSITORMODE) switch (COMPOSITORMODE)
{ {
case GPUCompositorMode_Debug: case GPUCompositorMode_Debug:
this->_copy16<OUTPUTFORMAT, true>(compInfo, srcColor16); this->_copy16<OUTPUTFORMAT, true>(compInfo, srcColor5551);
break; break;
case GPUCompositorMode_Copy: case GPUCompositorMode_Copy:
this->_copy16<OUTPUTFORMAT, false>(compInfo, srcColor16); this->_copy16<OUTPUTFORMAT, false>(compInfo, srcColor5551);
break; break;
case GPUCompositorMode_BrightUp: case GPUCompositorMode_BrightUp:
this->_brightnessUp16<OUTPUTFORMAT>(compInfo, srcColor16); this->_brightnessUp16<OUTPUTFORMAT>(compInfo, srcColor5551);
break; break;
case GPUCompositorMode_BrightDown: case GPUCompositorMode_BrightDown:
this->_brightnessDown16<OUTPUTFORMAT>(compInfo, srcColor16); this->_brightnessDown16<OUTPUTFORMAT>(compInfo, srcColor5551);
break; break;
default: default:
this->_unknownEffect16<OUTPUTFORMAT, LAYERTYPE>(compInfo, srcColor16, enableColorEffect, spriteAlpha, (OBJMode)spriteMode); this->_unknownEffect16<OUTPUTFORMAT, LAYERTYPE>(compInfo, srcColor5551, enableColorEffect, spriteAlpha, (OBJMode)spriteMode);
break; break;
} }
} }
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void PixelOperation::Composite32(GPUEngineCompositorInfo &compInfo, FragmentColor srcColor32, const bool enableColorEffect, const u8 spriteAlpha, const u8 spriteMode) const FORCEINLINE void PixelOperation::Composite32(GPUEngineCompositorInfo &compInfo, Color4u8 srcColor32, const bool enableColorEffect, const u8 spriteAlpha, const u8 spriteMode) const
{ {
switch (COMPOSITORMODE) switch (COMPOSITORMODE)
{ {
@ -758,8 +749,80 @@ static FORCEINLINE void CopyLinesForVerticalCount(void *__restrict dstLineHead,
#include "GPU_Operations_AVX2.cpp" #include "GPU_Operations_AVX2.cpp"
#elif defined(ENABLE_SSE2) #elif defined(ENABLE_SSE2)
#include "GPU_Operations_SSE2.cpp" #include "GPU_Operations_SSE2.cpp"
#elif defined(ENABLE_NEON_A64)
#include "GPU_Operations_NEON.cpp"
#elif defined(ENABLE_ALTIVEC)
#include "GPU_Operations_AltiVec.cpp"
#else #else
template <bool NEEDENDIANSWAP, size_t ELEMENTSIZE>
static FORCEINLINE void __CopyLineSingleUnlimited(void *__restrict dst, const void *__restrict src, size_t pixCount)
{
#if defined(MSB_FIRST)
if (NEEDENDIANSWAP && (ELEMENTSIZE > 1))
{
if (ELEMENTSIZE == 2)
{
const u16 *__restrict srcPtr16 = (const u16 *__restrict)src;
u16 *__restrict dstPtr16 = (u16 *__restrict)dst;
for (size_t i = 0; i < pixCount; i++)
{
dstPtr16[i] = LE_TO_LOCAL_16(srcPtr16[i]);
}
}
else if (ELEMENTSIZE == 4)
{
const u32 *__restrict srcPtr32 = (const u32 *__restrict)src;
u32 *__restrict dstPtr32 = (u32 *__restrict)dst;
for (size_t i = 0; i < pixCount; i++)
{
dstPtr32[i] = LE_TO_LOCAL_32(srcPtr32[i]);
}
}
}
else
#endif
{
memcpy(dst, src, pixCount * ELEMENTSIZE);
}
}
template <bool NEEDENDIANSWAP, size_t ELEMENTSIZE>
static FORCEINLINE void __CopyLineSingle(void *__restrict dst, const void *__restrict src)
{
#if defined(MSB_FIRST)
if (NEEDENDIANSWAP && (ELEMENTSIZE > 1))
{
if (ELEMENTSIZE == 2)
{
const u16 *__restrict srcPtr16 = (const u16 *__restrict)src;
u16 *__restrict dstPtr16 = (u16 *__restrict)dst;
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH; i++)
{
dstPtr16[i] = LE_TO_LOCAL_16(srcPtr16[i]);
}
}
else if (ELEMENTSIZE == 4)
{
const u32 *__restrict srcPtr32 = (const u32 *__restrict)src;
u32 *__restrict dstPtr32 = (u32 *__restrict)dst;
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH; i++)
{
dstPtr32[i] = LE_TO_LOCAL_32(srcPtr32[i]);
}
}
}
else
#endif
{
memcpy(dst, src, GPU_FRAMEBUFFER_NATIVE_WIDTH * ELEMENTSIZE);
}
}
template <s32 INTEGERSCALEHINT, bool SCALEVERTICAL, bool NEEDENDIANSWAP, size_t ELEMENTSIZE> template <s32 INTEGERSCALEHINT, bool SCALEVERTICAL, bool NEEDENDIANSWAP, size_t ELEMENTSIZE>
static FORCEINLINE void CopyLineExpand(void *__restrict dst, const void *__restrict src, size_t dstWidth, size_t dstLineCount) static FORCEINLINE void CopyLineExpand(void *__restrict dst, const void *__restrict src, size_t dstWidth, size_t dstLineCount)
{ {
@ -780,49 +843,11 @@ static FORCEINLINE void CopyLineExpand(void *__restrict dst, const void *__restr
if (INTEGERSCALEHINT == 0) if (INTEGERSCALEHINT == 0)
{ {
#if defined(MSB_FIRST) __CopyLineSingleUnlimited<NEEDENDIANSWAP, ELEMENTSIZE>(dst, src, dstWidth);
if (NEEDENDIANSWAP && (ELEMENTSIZE != 1))
{
for (size_t i = 0; i < dstWidth; i++)
{
if (ELEMENTSIZE == 2)
{
((u16 *)dst)[i] = LE_TO_LOCAL_16( ((u16 *)src)[i] );
}
else if (ELEMENTSIZE == 4)
{
((u32 *)dst)[i] = LE_TO_LOCAL_32( ((u32 *)src)[i] );
}
}
}
else
#endif
{
memcpy(dst, src, dstWidth * ELEMENTSIZE);
}
} }
else if (INTEGERSCALEHINT == 1) else if (INTEGERSCALEHINT == 1)
{ {
#if defined(MSB_FIRST) __CopyLineSingle<NEEDENDIANSWAP, ELEMENTSIZE>(dst, src);
if (NEEDENDIANSWAP && (ELEMENTSIZE != 1))
{
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH; i++)
{
if (ELEMENTSIZE == 2)
{
((u16 *)dst)[i] = LE_TO_LOCAL_16( ((u16 *)src)[i] );
}
else if (ELEMENTSIZE == 4)
{
((u32 *)dst)[i] = LE_TO_LOCAL_32( ((u32 *)src)[i] );
}
}
}
else
#endif
{
memcpy(dst, src, GPU_FRAMEBUFFER_NATIVE_WIDTH * ELEMENTSIZE);
}
} }
else if (INTEGERSCALEHINT > 1) else if (INTEGERSCALEHINT > 1)
{ {
@ -900,49 +925,11 @@ static FORCEINLINE void CopyLineReduce(void *__restrict dst, const void *__restr
if (INTEGERSCALEHINT == 0) if (INTEGERSCALEHINT == 0)
{ {
#if defined(MSB_FIRST) __CopyLineSingleUnlimited<NEEDENDIANSWAP, ELEMENTSIZE>(dst, src, srcWidth);
if (NEEDENDIANSWAP && (ELEMENTSIZE != 1))
{
for (size_t i = 0; i < srcWidth; i++)
{
if (ELEMENTSIZE == 2)
{
((u16 *)dst)[i] = LE_TO_LOCAL_16( ((u16 *)src)[i] );
}
else if (ELEMENTSIZE == 4)
{
((u32 *)dst)[i] = LE_TO_LOCAL_32( ((u32 *)src)[i] );
}
}
}
else
#endif
{
memcpy(dst, src, srcWidth * ELEMENTSIZE);
}
} }
else if (INTEGERSCALEHINT == 1) else if (INTEGERSCALEHINT == 1)
{ {
#if defined(MSB_FIRST) __CopyLineSingle<NEEDENDIANSWAP, ELEMENTSIZE>(dst, src);
if (NEEDENDIANSWAP && (ELEMENTSIZE != 1))
{
for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH; i++)
{
if (ELEMENTSIZE == 2)
{
((u16 *)dst)[i] = LE_TO_LOCAL_16( ((u16 *)src)[i] );
}
else if (ELEMENTSIZE == 4)
{
((u32 *)dst)[i] = LE_TO_LOCAL_32( ((u32 *)src)[i] );
}
}
}
else
#endif
{
memcpy(dst, src, GPU_FRAMEBUFFER_NATIVE_WIDTH * ELEMENTSIZE);
}
} }
else if (INTEGERSCALEHINT > 1) else if (INTEGERSCALEHINT > 1)
{ {
@ -956,11 +943,11 @@ static FORCEINLINE void CopyLineReduce(void *__restrict dst, const void *__restr
} }
else if (ELEMENTSIZE == 2) else if (ELEMENTSIZE == 2)
{ {
((u16 *)dst)[x] = ((u16 *)src)[x * scale]; ((u16 *)dst)[x] = (NEEDENDIANSWAP) ? LE_TO_LOCAL_16( ((u16 *)src)[x * scale] ) : ((u16 *)src)[x * scale];
} }
else if (ELEMENTSIZE == 4) else if (ELEMENTSIZE == 4)
{ {
((u32 *)dst)[x] = ((u32 *)src)[x * scale]; ((u32 *)dst)[x] = (NEEDENDIANSWAP) ? LE_TO_LOCAL_32( ((u32 *)src)[x * scale] ) : ((u32 *)src)[x * scale];
} }
} }
} }
@ -1002,9 +989,9 @@ void GPUEngineBase::_MosaicLine(GPUEngineCompositorInfo &compInfo)
else else
{ {
outColor16 = mosaicColorBG[compInfo.renderState.mosaicWidthBG->trunc[x]]; outColor16 = mosaicColorBG[compInfo.renderState.mosaicWidthBG->trunc[x]];
isOpaque = (outColor16 != 0xFFFF);
} }
isOpaque = (outColor16 != 0xFFFF);
if (isOpaque) if (isOpaque)
{ {
this->_deferredColorNative[x] = outColor16; this->_deferredColorNative[x] = outColor16;
@ -1013,7 +1000,7 @@ void GPUEngineBase::_MosaicLine(GPUEngineCompositorInfo &compInfo)
} }
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST>
void GPUEngineBase::_CompositeNativeLineOBJ_LoopOp(GPUEngineCompositorInfo &compInfo, const u16 *__restrict srcColorNative16, const FragmentColor *__restrict srcColorNative32) void GPUEngineBase::_CompositeNativeLineOBJ_LoopOp(GPUEngineCompositorInfo &compInfo, const u16 *__restrict srcColorNative16, const Color4u8 *__restrict srcColorNative32)
{ {
// Do nothing. This is a placeholder for a manually vectorized version of this method. // Do nothing. This is a placeholder for a manually vectorized version of this method.
} }
@ -1086,7 +1073,7 @@ void GPUEngineBase::_PerformWindowTestingNative(GPUEngineCompositorInfo &compInf
} }
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST>
size_t GPUEngineA::_RenderLine_Layer3D_LoopOp(GPUEngineCompositorInfo &compInfo, const u8 *__restrict windowTestPtr, const u8 *__restrict colorEffectEnablePtr, const FragmentColor *__restrict srcLinePtr) size_t GPUEngineA::_RenderLine_Layer3D_LoopOp(GPUEngineCompositorInfo &compInfo, const u8 *__restrict windowTestPtr, const u8 *__restrict colorEffectEnablePtr, const Color4u8 *__restrict srcLinePtr)
{ {
// Do nothing. This is a placeholder for a manually vectorized version of this method. // Do nothing. This is a placeholder for a manually vectorized version of this method.
return 0; return 0;
@ -1315,5 +1302,5 @@ void CopyLineReduceHinted(const GPUEngineLineInfo &lineInfo, const void *__restr
} }
// These functions are used in gfx3d.cpp // These functions are used in gfx3d.cpp
template void CopyLineExpandHinted<0x3FFF, true, false, true, 4>(const GPUEngineLineInfo &lineInfo, const void *__restrict srcBuffer, void *__restrict dstBuffer); template void CopyLineExpandHinted<0x3FFF, true, false, false, 4>(const GPUEngineLineInfo &lineInfo, const void *__restrict srcBuffer, void *__restrict dstBuffer);
template void CopyLineReduceHinted<0x3FFF, false, true, 4>(const GPUEngineLineInfo &lineInfo, const void *__restrict srcBuffer, void *__restrict dstBuffer); template void CopyLineReduceHinted<0x3FFF, false, false, 4>(const GPUEngineLineInfo &lineInfo, const void *__restrict srcBuffer, void *__restrict dstBuffer);

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2021 DeSmuME team Copyright (C) 2021-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -45,18 +45,18 @@ class ColorOperation
public: public:
ColorOperation() {}; ColorOperation() {};
FORCEINLINE u16 blend(const u16 colA, const u16 colB, const u16 blendEVA, const u16 blendEVB) const; FORCEINLINE Color5551 blend(const Color5551 colA, const Color5551 colB, const u16 blendEVA, const u16 blendEVB) const;
FORCEINLINE u16 blend(const u16 colA, const u16 colB, const TBlendTable *blendTable) const; FORCEINLINE Color5551 blend(const Color5551 colA, const Color5551 colB, const TBlendTable *blendTable) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE FragmentColor blend(const FragmentColor colA, const FragmentColor colB, const u16 blendEVA, const u16 blendEVB) const; template<NDSColorFormat COLORFORMAT> FORCEINLINE Color4u8 blend(const Color4u8 colA, const Color4u8 colB, const u16 blendEVA, const u16 blendEVB) const;
FORCEINLINE u16 blend3D(const FragmentColor colA, const u16 colB) const; FORCEINLINE Color5551 blend3D(const Color4u8 colA, const Color5551 colB) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE FragmentColor blend3D(const FragmentColor colA, const FragmentColor colB) const; template<NDSColorFormat COLORFORMAT> FORCEINLINE Color4u8 blend3D(const Color4u8 colA, const Color4u8 colB) const;
FORCEINLINE u16 increase(const u16 col, const u16 blendEVY) const; FORCEINLINE Color5551 increase(const Color5551 col, const u16 blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE FragmentColor increase(const FragmentColor col, const u16 blendEVY) const; template<NDSColorFormat COLORFORMAT> FORCEINLINE Color4u8 increase(const Color4u8 col, const u16 blendEVY) const;
FORCEINLINE u16 decrease(const u16 col, const u16 blendEVY) const; FORCEINLINE Color5551 decrease(const Color5551 col, const u16 blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE FragmentColor decrease(const FragmentColor col, const u16 blendEVY) const; template<NDSColorFormat COLORFORMAT> FORCEINLINE Color4u8 decrease(const Color4u8 col, const u16 blendEVY) const;
}; };
class PixelOperation class PixelOperation
@ -65,32 +65,32 @@ private:
template<GPULayerType LAYERTYPE> FORCEINLINE void __selectedEffect(const GPUEngineCompositorInfo &compInfo, const u8 &dstLayerID, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode, ColorEffect &selectedEffect, TBlendTable **selectedBlendTable, u8 &blendEVA, u8 &blendEVB) const; template<GPULayerType LAYERTYPE> FORCEINLINE void __selectedEffect(const GPUEngineCompositorInfo &compInfo, const u8 &dstLayerID, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode, ColorEffect &selectedEffect, TBlendTable **selectedBlendTable, u8 &blendEVA, u8 &blendEVB) const;
protected: protected:
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16) const; template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy16(GPUEngineCompositorInfo &compInfo, const Color5551 srcColor16) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy32(GPUEngineCompositorInfo &compInfo, const FragmentColor srcColor32) const; template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy32(GPUEngineCompositorInfo &compInfo, const Color4u8 srcColor32) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16) const; template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp16(GPUEngineCompositorInfo &compInfo, const Color5551 srcColor16) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp32(GPUEngineCompositorInfo &compInfo, const FragmentColor srcColor32) const; template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp32(GPUEngineCompositorInfo &compInfo, const Color4u8 srcColor32) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16) const; template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown16(GPUEngineCompositorInfo &compInfo, const Color5551 srcColor16) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown32(GPUEngineCompositorInfo &compInfo, const FragmentColor srcColor32) const; template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown32(GPUEngineCompositorInfo &compInfo, const Color4u8 srcColor32) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> FORCEINLINE void _unknownEffect16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode) const; template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> FORCEINLINE void _unknownEffect16(GPUEngineCompositorInfo &compInfo, const Color5551 srcColor16, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> FORCEINLINE void _unknownEffect32(GPUEngineCompositorInfo &compInfo, const FragmentColor srcColor32, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode) const; template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> FORCEINLINE void _unknownEffect32(GPUEngineCompositorInfo &compInfo, const Color4u8 srcColor32, const bool enableColorEffect, const u8 spriteAlpha, const OBJMode spriteMode) const;
public: public:
static CACHE_ALIGN u8 BlendTable555[17][17][32][32]; static CACHE_ALIGN u8 BlendTable555[17][17][32][32];
static CACHE_ALIGN u16 BrightnessUpTable555[17][0x8000]; static CACHE_ALIGN Color5551 BrightnessUpTable555[17][0x8000];
static CACHE_ALIGN FragmentColor BrightnessUpTable666[17][0x8000]; static CACHE_ALIGN Color4u8 BrightnessUpTable666[17][0x8000];
static CACHE_ALIGN FragmentColor BrightnessUpTable888[17][0x8000]; static CACHE_ALIGN Color4u8 BrightnessUpTable888[17][0x8000];
static CACHE_ALIGN u16 BrightnessDownTable555[17][0x8000]; static CACHE_ALIGN Color5551 BrightnessDownTable555[17][0x8000];
static CACHE_ALIGN FragmentColor BrightnessDownTable666[17][0x8000]; static CACHE_ALIGN Color4u8 BrightnessDownTable666[17][0x8000];
static CACHE_ALIGN FragmentColor BrightnessDownTable888[17][0x8000]; static CACHE_ALIGN Color4u8 BrightnessDownTable888[17][0x8000];
static void InitLUTs(); static void InitLUTs();
PixelOperation() {}; PixelOperation() {};
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> FORCEINLINE void Composite16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16, const bool enableColorEffect, const u8 spriteAlpha, const u8 spriteMode) const; template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> FORCEINLINE void Composite16(GPUEngineCompositorInfo &compInfo, const u16 srcColor16, const bool enableColorEffect, const u8 spriteAlpha, const u8 spriteMode) const;
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> FORCEINLINE void Composite32(GPUEngineCompositorInfo &compInfo, FragmentColor srcColor32, const bool enableColorEffect, const u8 spriteAlpha, const u8 spriteMode) const; template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE> FORCEINLINE void Composite32(GPUEngineCompositorInfo &compInfo, Color4u8 srcColor32, const bool enableColorEffect, const u8 spriteAlpha, const u8 spriteMode) const;
}; };
#endif // GPU_OPERATIONS_H #endif // GPU_OPERATIONS_H

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2021-2022 DeSmuME team Copyright (C) 2021-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -950,15 +950,17 @@ FORCEINLINE v256u16 ColorOperation_AVX2::blend3D(const v256u32 &colA_Lo, const v
{ {
// If the color format of B is 555, then the colA_Hi parameter is required. // If the color format of B is 555, then the colA_Hi parameter is required.
// The color format of A is assumed to be RGB666. // The color format of A is assumed to be RGB666.
v256u32 ra_lo = _mm256_and_si256( colA_Lo, _mm256_set1_epi32(0x000000FF) ); static const u8 X = 0x80;
v256u32 ga_lo = _mm256_and_si256( _mm256_srli_epi32(colA_Lo, 8), _mm256_set1_epi32(0x000000FF) );
v256u32 ba_lo = _mm256_and_si256( _mm256_srli_epi32(colA_Lo, 16), _mm256_set1_epi32(0x000000FF) );
v256u32 aa_lo = _mm256_srli_epi32(colA_Lo, 24);
v256u32 ra_hi = _mm256_and_si256( colA_Hi, _mm256_set1_epi32(0x000000FF) ); const v256u32 ra_lo = _mm256_shuffle_epi8( colA_Lo, _mm256_set_epi8( X, X, X,12, X, X, X, 8, X, X, X, 4, X, X, X, 0, X, X, X,12, X, X, X, 8, X, X, X, 4, X, X, X, 0) );
v256u32 ga_hi = _mm256_and_si256( _mm256_srli_epi32(colA_Hi, 8), _mm256_set1_epi32(0x000000FF) ); const v256u32 ga_lo = _mm256_shuffle_epi8( colA_Lo, _mm256_set_epi8( X, X, X,13, X, X, X, 9, X, X, X, 5, X, X, X, 1, X, X, X,13, X, X, X, 9, X, X, X, 5, X, X, X, 1) );
v256u32 ba_hi = _mm256_and_si256( _mm256_srli_epi32(colA_Hi, 16), _mm256_set1_epi32(0x000000FF) ); const v256u32 ba_lo = _mm256_shuffle_epi8( colA_Lo, _mm256_set_epi8( X, X, X,14, X, X, X,10, X, X, X, 6, X, X, X, 2, X, X, X,14, X, X, X,10, X, X, X, 6, X, X, X, 2) );
v256u32 aa_hi = _mm256_srli_epi32(colA_Hi, 24); const v256u32 aa_lo = _mm256_shuffle_epi8( colA_Lo, _mm256_set_epi8( X, X, X,15, X, X, X,11, X, X, X, 7, X, X, X, 3, X, X, X,15, X, X, X,11, X, X, X, 7, X, X, X, 3) );
const v256u32 ra_hi = _mm256_shuffle_epi8( colA_Hi, _mm256_set_epi8( X, X, X,12, X, X, X, 8, X, X, X, 4, X, X, X, 0, X, X, X,12, X, X, X, 8, X, X, X, 4, X, X, X, 0) );
const v256u32 ga_hi = _mm256_shuffle_epi8( colA_Hi, _mm256_set_epi8( X, X, X,13, X, X, X, 9, X, X, X, 5, X, X, X, 1, X, X, X,13, X, X, X, 9, X, X, X, 5, X, X, X, 1) );
const v256u32 ba_hi = _mm256_shuffle_epi8( colA_Hi, _mm256_set_epi8( X, X, X,14, X, X, X,10, X, X, X, 6, X, X, X, 2, X, X, X,14, X, X, X,10, X, X, X, 6, X, X, X, 2) );
const v256u32 aa_hi = _mm256_shuffle_epi8( colA_Hi, _mm256_set_epi8( X, X, X,15, X, X, X,11, X, X, X, 7, X, X, X, 3, X, X, X,15, X, X, X,11, X, X, X, 7, X, X, X, 3) );
v256u16 ra = _mm256_packus_epi32(ra_lo, ra_hi); v256u16 ra = _mm256_packus_epi32(ra_lo, ra_hi);
v256u16 ga = _mm256_packus_epi32(ga_lo, ga_hi); v256u16 ga = _mm256_packus_epi32(ga_lo, ga_hi);
@ -991,9 +993,11 @@ FORCEINLINE v256u16 ColorOperation_AVX2::blend3D(const v256u32 &colA_Lo, const v
template <NDSColorFormat COLORFORMAT> template <NDSColorFormat COLORFORMAT>
FORCEINLINE v256u32 ColorOperation_AVX2::blend3D(const v256u32 &colA, const v256u32 &colB) const FORCEINLINE v256u32 ColorOperation_AVX2::blend3D(const v256u32 &colA, const v256u32 &colB) const
{ {
static const u8 X = 0x80;
// If the color format of B is 666 or 888, then the colA_Hi parameter is ignored. // If the color format of B is 666 or 888, then the colA_Hi parameter is ignored.
// The color format of A is assumed to match the color format of B. // The color format of A is assumed to match the color format of B.
v256u32 alpha; v256u8 alpha;
v256u16 alphaLo; v256u16 alphaLo;
v256u16 alphaHi; v256u16 alphaHi;
@ -1015,8 +1019,7 @@ FORCEINLINE v256u32 ColorOperation_AVX2::blend3D(const v256u32 &colA, const v256
v256u16 tempColorLo = _mm256_unpacklo_epi8(tempColor[0], tempColor[1]); v256u16 tempColorLo = _mm256_unpacklo_epi8(tempColor[0], tempColor[1]);
v256u16 tempColorHi = _mm256_unpackhi_epi8(tempColor[0], tempColor[1]); v256u16 tempColorHi = _mm256_unpackhi_epi8(tempColor[0], tempColor[1]);
alpha = _mm256_and_si256( _mm256_srli_epi32(colA, 24), _mm256_set1_epi32(0x0000001F) ); alpha = _mm256_shuffle_epi8( colA, _mm256_set_epi8( X,15,15,15, X,11,11,11, X, 7, 7, 7, X, 3, 3, 3, X,15,15,15, X,11,11,11, X, 7, 7, 7, X, 3, 3, 3) );
alpha = _mm256_or_si256( alpha, _mm256_or_si256(_mm256_slli_epi32(alpha, 8), _mm256_slli_epi32(alpha, 16)) );
alpha = _mm256_adds_epu8(alpha, _mm256_set1_epi8(1)); alpha = _mm256_adds_epu8(alpha, _mm256_set1_epi8(1));
v256u32 invAlpha = _mm256_subs_epu8(_mm256_set1_epi8(32), alpha); v256u32 invAlpha = _mm256_subs_epu8(_mm256_set1_epi8(32), alpha);
@ -1039,8 +1042,7 @@ FORCEINLINE v256u32 ColorOperation_AVX2::blend3D(const v256u32 &colA, const v256
v256u16 rgbBLo = _mm256_unpacklo_epi8(tempColor[1], _mm256_setzero_si256()); v256u16 rgbBLo = _mm256_unpacklo_epi8(tempColor[1], _mm256_setzero_si256());
v256u16 rgbBHi = _mm256_unpackhi_epi8(tempColor[1], _mm256_setzero_si256()); v256u16 rgbBHi = _mm256_unpackhi_epi8(tempColor[1], _mm256_setzero_si256());
alpha = _mm256_and_si256( _mm256_srli_epi32(colA, 24), _mm256_set1_epi32(0x000000FF) ); alpha = _mm256_shuffle_epi8( colA, _mm256_set_epi8( X,15,15,15, X,11,11,11, X, 7, 7, 7, X, 3, 3, 3, X,15,15,15, X,11,11,11, X, 7, 7, 7, X, 3, 3, 3) );
alpha = _mm256_or_si256( alpha, _mm256_or_si256(_mm256_slli_epi32(alpha, 8), _mm256_slli_epi32(alpha, 16)) );
alpha = _mm256_permute4x64_epi64(alpha, 0xD8); alpha = _mm256_permute4x64_epi64(alpha, 0xD8);
alphaLo = _mm256_unpacklo_epi8(alpha, _mm256_setzero_si256()); alphaLo = _mm256_unpacklo_epi8(alpha, _mm256_setzero_si256());
@ -1128,13 +1130,13 @@ FORCEINLINE void PixelOperation_AVX2::_copy16(GPUEngineCompositorInfo &compInfo,
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555To6665Opaque_AVX2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo6665Opaque_AVX2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555To6665Opaque_AVX2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo6665Opaque_AVX2<false>(src1, src32[2], src32[3]);
} }
else else
{ {
ColorspaceConvert555To8888Opaque_AVX2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo8888Opaque_AVX2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555To8888Opaque_AVX2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo8888Opaque_AVX2<false>(src1, src32[2], src32[3]);
} }
_mm256_store_si256( (v256u32 *)compInfo.target.lineColor32 + 0, src32[0] ); _mm256_store_si256( (v256u32 *)compInfo.target.lineColor32 + 0, src32[0] );
@ -1205,13 +1207,13 @@ FORCEINLINE void PixelOperation_AVX2::_copyMask16(GPUEngineCompositorInfo &compI
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555To6665Opaque_AVX2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo6665Opaque_AVX2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555To6665Opaque_AVX2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo6665Opaque_AVX2<false>(src1, src32[2], src32[3]);
} }
else else
{ {
ColorspaceConvert555To8888Opaque_AVX2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo8888Opaque_AVX2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555To8888Opaque_AVX2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo8888Opaque_AVX2<false>(src1, src32[2], src32[3]);
} }
passMask16[0] = _mm256_permute4x64_epi64(passMask16[0], 0xD8); passMask16[0] = _mm256_permute4x64_epi64(passMask16[0], 0xD8);
@ -1304,13 +1306,13 @@ FORCEINLINE void PixelOperation_AVX2::_brightnessUp16(GPUEngineCompositorInfo &c
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555XTo666X_AVX2<false>(src0, dst[0], dst[1]); ColorspaceConvert555xTo666x_AVX2<false>(src0, dst[0], dst[1]);
ColorspaceConvert555XTo666X_AVX2<false>(src1, dst[2], dst[3]); ColorspaceConvert555xTo666x_AVX2<false>(src1, dst[2], dst[3]);
} }
else else
{ {
ColorspaceConvert555XTo888X_AVX2<false>(src0, dst[0], dst[1]); ColorspaceConvert555xTo888x_AVX2<false>(src0, dst[0], dst[1]);
ColorspaceConvert555XTo888X_AVX2<false>(src1, dst[2], dst[3]); ColorspaceConvert555xTo888x_AVX2<false>(src1, dst[2], dst[3]);
} }
const v256u32 alphaBits = (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? _mm256_set1_epi32(0x1F000000) : _mm256_set1_epi32(0xFF000000); const v256u32 alphaBits = (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? _mm256_set1_epi32(0x1F000000) : _mm256_set1_epi32(0xFF000000);
@ -1377,13 +1379,13 @@ FORCEINLINE void PixelOperation_AVX2::_brightnessUpMask16(GPUEngineCompositorInf
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555XTo666X_AVX2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo666x_AVX2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555XTo666X_AVX2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo666x_AVX2<false>(src1, src32[2], src32[3]);
} }
else else
{ {
ColorspaceConvert555XTo888X_AVX2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo888x_AVX2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555XTo888X_AVX2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo888x_AVX2<false>(src1, src32[2], src32[3]);
} }
passMask16[0] = _mm256_permute4x64_epi64(passMask16[0], 0xD8); passMask16[0] = _mm256_permute4x64_epi64(passMask16[0], 0xD8);
@ -1471,13 +1473,13 @@ FORCEINLINE void PixelOperation_AVX2::_brightnessDown16(GPUEngineCompositorInfo
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555XTo666X_AVX2<false>(src0, dst[0], dst[1]); ColorspaceConvert555xTo666x_AVX2<false>(src0, dst[0], dst[1]);
ColorspaceConvert555XTo666X_AVX2<false>(src1, dst[2], dst[3]); ColorspaceConvert555xTo666x_AVX2<false>(src1, dst[2], dst[3]);
} }
else else
{ {
ColorspaceConvert555XTo888X_AVX2<false>(src0, dst[0], dst[1]); ColorspaceConvert555xTo888x_AVX2<false>(src0, dst[0], dst[1]);
ColorspaceConvert555XTo888X_AVX2<false>(src1, dst[2], dst[3]); ColorspaceConvert555xTo888x_AVX2<false>(src1, dst[2], dst[3]);
} }
const v256u32 alphaBits = _mm256_set1_epi32((OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? 0x1F000000 : 0xFF000000); const v256u32 alphaBits = _mm256_set1_epi32((OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? 0x1F000000 : 0xFF000000);
@ -1544,13 +1546,13 @@ FORCEINLINE void PixelOperation_AVX2::_brightnessDownMask16(GPUEngineCompositorI
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555XTo666X_AVX2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo666x_AVX2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555XTo666X_AVX2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo666x_AVX2<false>(src1, src32[2], src32[3]);
} }
else else
{ {
ColorspaceConvert555XTo888X_AVX2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo888x_AVX2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555XTo888X_AVX2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo888x_AVX2<false>(src1, src32[2], src32[3]);
} }
passMask16[0] = _mm256_permute4x64_epi64(passMask16[0], 0xD8); passMask16[0] = _mm256_permute4x64_epi64(passMask16[0], 0xD8);
@ -1674,13 +1676,13 @@ FORCEINLINE void PixelOperation_AVX2::_unknownEffectMask16(GPUEngineCompositorIn
} }
else if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) else if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555XTo666X_AVX2<false>(src0, tmpSrc[0], tmpSrc[1]); ColorspaceConvert555xTo666x_AVX2<false>(src0, tmpSrc[0], tmpSrc[1]);
ColorspaceConvert555XTo666X_AVX2<false>(src1, tmpSrc[2], tmpSrc[3]); ColorspaceConvert555xTo666x_AVX2<false>(src1, tmpSrc[2], tmpSrc[3]);
} }
else else
{ {
ColorspaceConvert555XTo888X_AVX2<false>(src0, tmpSrc[0], tmpSrc[1]); ColorspaceConvert555xTo888x_AVX2<false>(src0, tmpSrc[0], tmpSrc[1]);
ColorspaceConvert555XTo888X_AVX2<false>(src1, tmpSrc[2], tmpSrc[3]); ColorspaceConvert555xTo888x_AVX2<false>(src1, tmpSrc[2], tmpSrc[3]);
} }
switch (compInfo.renderState.colorEffect) switch (compInfo.renderState.colorEffect)
@ -2179,7 +2181,7 @@ FORCEINLINE void PixelOperation_AVX2::_unknownEffectMask32(GPUEngineCompositorIn
_mm256_load_si256((v256u32 *)compInfo.target.lineColor32 + 0), _mm256_load_si256((v256u32 *)compInfo.target.lineColor32 + 0),
_mm256_load_si256((v256u32 *)compInfo.target.lineColor32 + 1), _mm256_load_si256((v256u32 *)compInfo.target.lineColor32 + 1),
_mm256_load_si256((v256u32 *)compInfo.target.lineColor32 + 2), _mm256_load_si256((v256u32 *)compInfo.target.lineColor32 + 2),
_mm256_load_si256((v256u32 *)compInfo.target.lineColor32 + 3), _mm256_load_si256((v256u32 *)compInfo.target.lineColor32 + 3)
}; };
v256u32 blendSrc32[4]; v256u32 blendSrc32[4];
@ -2460,25 +2462,25 @@ void GPUEngineBase::_MosaicLine(GPUEngineCompositorInfo &compInfo)
_mm256_blendv_epi8(_mm256_and_si256(dstColor16[1], _mm256_set1_epi16(0x7FFF)), _mm256_set1_epi16(0xFFFF), idxMask16[1]) _mm256_blendv_epi8(_mm256_and_si256(dstColor16[1], _mm256_set1_epi16(0x7FFF)), _mm256_set1_epi16(0xFFFF), idxMask16[1])
}; };
const v256u16 mosaicSetColorMask8 = _mm256_permute4x64_epi64( _mm256_cmpeq_epi16(_mm256_loadu_si256((v256u8 *)(compInfo.renderState.mosaicWidthBG->begin + x)), _mm256_setzero_si256()), 0xD8 ); const v256u16 mosaicSetColorMask8 = _mm256_permute4x64_epi64( _mm256_cmpeq_epi16(_mm256_load_si256((v256u8 *)(compInfo.renderState.mosaicWidthBG->begin + x)), _mm256_setzero_si256()), 0xD8 );
const v256u16 mosaicSetColorMask16[2] = { const v256u16 mosaicSetColorMask16[2] = {
_mm256_unpacklo_epi8(mosaicSetColorMask8, mosaicSetColorMask8), _mm256_unpacklo_epi8(mosaicSetColorMask8, mosaicSetColorMask8),
_mm256_unpackhi_epi8(mosaicSetColorMask8, mosaicSetColorMask8) _mm256_unpackhi_epi8(mosaicSetColorMask8, mosaicSetColorMask8)
}; };
__m256i mosaicColorOut[2]; __m256i mosaicColorOut[2];
mosaicColorOut[0] = _mm256_blendv_epi8(mosaicColor16[0], _mm256_loadu_si256((v256u16 *)(mosaicColorBG + x) + 0), mosaicSetColorMask16[0]); mosaicColorOut[0] = _mm256_blendv_epi8(mosaicColor16[0], _mm256_load_si256((v256u16 *)(mosaicColorBG + x) + 0), mosaicSetColorMask16[0]);
mosaicColorOut[1] = _mm256_blendv_epi8(mosaicColor16[1], _mm256_loadu_si256((v256u16 *)(mosaicColorBG + x) + 1), mosaicSetColorMask16[1]); mosaicColorOut[1] = _mm256_blendv_epi8(mosaicColor16[1], _mm256_load_si256((v256u16 *)(mosaicColorBG + x) + 1), mosaicSetColorMask16[1]);
_mm256_storeu_si256((v256u16 *)(mosaicColorBG + x) + 0, mosaicColorOut[0]); _mm256_store_si256((v256u16 *)(mosaicColorBG + x) + 0, mosaicColorOut[0]);
_mm256_storeu_si256((v256u16 *)(mosaicColorBG + x) + 1, mosaicColorOut[1]); _mm256_store_si256((v256u16 *)(mosaicColorBG + x) + 1, mosaicColorOut[1]);
} }
const v256u32 outColor32idx[4] = { const v256u32 outColor32idx[4] = {
_mm256_loadu_si256((v256u32 *)(compInfo.renderState.mosaicWidthBG->trunc32 + x) + 0), _mm256_load_si256((v256u32 *)(compInfo.renderState.mosaicWidthBG->trunc32 + x) + 0),
_mm256_loadu_si256((v256u32 *)(compInfo.renderState.mosaicWidthBG->trunc32 + x) + 1), _mm256_load_si256((v256u32 *)(compInfo.renderState.mosaicWidthBG->trunc32 + x) + 1),
_mm256_loadu_si256((v256u32 *)(compInfo.renderState.mosaicWidthBG->trunc32 + x) + 2), _mm256_load_si256((v256u32 *)(compInfo.renderState.mosaicWidthBG->trunc32 + x) + 2),
_mm256_loadu_si256((v256u32 *)(compInfo.renderState.mosaicWidthBG->trunc32 + x) + 3) _mm256_load_si256((v256u32 *)(compInfo.renderState.mosaicWidthBG->trunc32 + x) + 3)
}; };
const v256u16 outColor32[4] = { const v256u16 outColor32[4] = {
@ -2505,7 +2507,7 @@ void GPUEngineBase::_MosaicLine(GPUEngineCompositorInfo &compInfo)
} }
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST>
void GPUEngineBase::_CompositeNativeLineOBJ_LoopOp(GPUEngineCompositorInfo &compInfo, const u16 *__restrict srcColorNative16, const FragmentColor *__restrict srcColorNative32) void GPUEngineBase::_CompositeNativeLineOBJ_LoopOp(GPUEngineCompositorInfo &compInfo, const u16 *__restrict srcColorNative16, const Color4u8 *__restrict srcColorNative32)
{ {
static const size_t step = sizeof(v256u8); static const size_t step = sizeof(v256u8);
@ -2749,10 +2751,10 @@ size_t GPUEngineBase::_CompositeVRAMLineDeferred_LoopOp(GPUEngineCompositorInfo
case NDSColorFormat_BGR888_Rev: case NDSColorFormat_BGR888_Rev:
{ {
const v256u32 src32[4] = { const v256u32 src32[4] = {
_mm256_load_si256((v256u32 *)((FragmentColor *)vramColorPtr + i) + 0), _mm256_load_si256((v256u32 *)((Color4u8 *)vramColorPtr + i) + 0),
_mm256_load_si256((v256u32 *)((FragmentColor *)vramColorPtr + i) + 1), _mm256_load_si256((v256u32 *)((Color4u8 *)vramColorPtr + i) + 1),
_mm256_load_si256((v256u32 *)((FragmentColor *)vramColorPtr + i) + 2), _mm256_load_si256((v256u32 *)((Color4u8 *)vramColorPtr + i) + 2),
_mm256_load_si256((v256u32 *)((FragmentColor *)vramColorPtr + i) + 3) _mm256_load_si256((v256u32 *)((Color4u8 *)vramColorPtr + i) + 3)
}; };
if (LAYERTYPE != GPULayerType_OBJ) if (LAYERTYPE != GPULayerType_OBJ)
@ -2906,7 +2908,7 @@ void GPUEngineBase::_PerformWindowTestingNative(GPUEngineCompositorInfo &compInf
} }
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST>
size_t GPUEngineA::_RenderLine_Layer3D_LoopOp(GPUEngineCompositorInfo &compInfo, const u8 *__restrict windowTestPtr, const u8 *__restrict colorEffectEnablePtr, const FragmentColor *__restrict srcLinePtr) size_t GPUEngineA::_RenderLine_Layer3D_LoopOp(GPUEngineCompositorInfo &compInfo, const u8 *__restrict windowTestPtr, const u8 *__restrict colorEffectEnablePtr, const Color4u8 *__restrict srcLinePtr)
{ {
static const size_t step = sizeof(v256u32); static const size_t step = sizeof(v256u32);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,122 @@
/*
Copyright (C) 2025 DeSmuME team
This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GPU_OPERATIONS_ALTIVEC_H
#define GPU_OPERATIONS_ALTIVEC_H
#include "GPU_Operations.h"
#ifndef ENABLE_ALTIVEC
#warning This header requires PowerPC AltiVec support.
#else
class ColorOperation_AltiVec
{
public:
ColorOperation_AltiVec() {};
FORCEINLINE v128u16 blend(const v128u16 &colA, const v128u16 &colB, const v128u16 &blendEVA, const v128u16 &blendEVB) const;
template<NDSColorFormat COLORFORMAT, bool USECONSTANTBLENDVALUESHINT> FORCEINLINE v128u32 blend(const v128u32 &colA, const v128u32 &colB, const v128u16 &blendEVA, const v128u16 &blendEVB) const;
FORCEINLINE v128u16 blend3D(const v128u32 &colA_Lo, const v128u32 &colA_Hi, const v128u16 &colB) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v128u32 blend3D(const v128u32 &colA, const v128u32 &colB) const;
FORCEINLINE v128u16 increase(const v128u16 &col, const v128u16 &blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v128u32 increase(const v128u32 &col, const v128u16 &blendEVY) const;
FORCEINLINE v128u16 decrease(const v128u16 &col, const v128u16 &blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v128u32 decrease(const v128u32 &col, const v128u16 &blendEVY) const;
};
class PixelOperation_AltiVec
{
protected:
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy16(GPUEngineCompositorInfo &compInfo, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy32(GPUEngineCompositorInfo &compInfo, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copyMask16(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copyMask32(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp16(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp32(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUpMask16(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUpMask32(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown16(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown32(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDownMask16(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDownMask32(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void _unknownEffectMask16(GPUEngineCompositorInfo &compInfo,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u16 &src1, const v128u16 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const v128u8 &enableColorEffectMask,
const v128u8 &spriteAlpha,
const v128u8 &spriteMode) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void _unknownEffectMask32(GPUEngineCompositorInfo &compInfo,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const v128u8 &enableColorEffectMask,
const v128u8 &spriteAlpha,
const v128u8 &spriteMode) const;
public:
PixelOperation_AltiVec() {};
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST>
FORCEINLINE void Composite16(GPUEngineCompositorInfo &compInfo,
const bool didAllPixelsPass,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u16 &src1, const v128u16 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const u8 *__restrict enableColorEffectPtr,
const u8 *__restrict sprAlphaPtr,
const u8 *__restrict sprModePtr) const;
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST>
FORCEINLINE void Composite32(GPUEngineCompositorInfo &compInfo,
const bool didAllPixelsPass,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const u8 *__restrict enableColorEffectPtr,
const u8 *__restrict sprAlphaPtr,
const u8 *__restrict sprModePtr) const;
};
#endif // ENABLE_ALTIVEC
#endif // GPU_OPERATIONS_ALTIVEC_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,122 @@
/*
Copyright (C) 2025 DeSmuME team
This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GPU_OPERATIONS_NEON_H
#define GPU_OPERATIONS_NEON_H
#include "GPU_Operations.h"
#ifndef ENABLE_NEON_A64
#warning This header requires ARM64 NEON support.
#else
class ColorOperation_NEON
{
public:
ColorOperation_NEON() {};
FORCEINLINE v128u16 blend(const v128u16 &colA, const v128u16 &colB, const v128u16 &blendEVA, const v128u16 &blendEVB) const;
template<NDSColorFormat COLORFORMAT, bool USECONSTANTBLENDVALUESHINT> FORCEINLINE v128u32 blend(const v128u32 &colA, const v128u32 &colB, const v128u16 &blendEVA, const v128u16 &blendEVB) const;
FORCEINLINE v128u16 blend3D(const v128u32 &colA_Lo, const v128u32 &colA_Hi, const v128u16 &colB) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v128u32 blend3D(const v128u32 &colA, const v128u32 &colB) const;
FORCEINLINE v128u16 increase(const v128u16 &col, const v128u16 &blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v128u32 increase(const v128u32 &col, const v128u16 &blendEVY) const;
FORCEINLINE v128u16 decrease(const v128u16 &col, const v128u16 &blendEVY) const;
template<NDSColorFormat COLORFORMAT> FORCEINLINE v128u32 decrease(const v128u32 &col, const v128u16 &blendEVY) const;
};
class PixelOperation_NEON
{
protected:
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy16(GPUEngineCompositorInfo &compInfo, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copy32(GPUEngineCompositorInfo &compInfo, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copyMask16(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, bool ISDEBUGRENDER> FORCEINLINE void _copyMask32(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp16(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUp32(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUpMask16(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessUpMask32(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown16(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDown32(GPUEngineCompositorInfo &compInfo, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDownMask16(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u16 &src1, const v128u16 &src0) const;
template<NDSColorFormat OUTPUTFORMAT> FORCEINLINE void _brightnessDownMask32(GPUEngineCompositorInfo &compInfo, const v128u8 &passMask8, const v128u16 &evy16, const v128u8 &srcLayerID, const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void _unknownEffectMask16(GPUEngineCompositorInfo &compInfo,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u16 &src1, const v128u16 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const v128u8 &enableColorEffectMask,
const v128u8 &spriteAlpha,
const v128u8 &spriteMode) const;
template<NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE>
FORCEINLINE void _unknownEffectMask32(GPUEngineCompositorInfo &compInfo,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const v128u8 &enableColorEffectMask,
const v128u8 &spriteAlpha,
const v128u8 &spriteMode) const;
public:
PixelOperation_NEON() {};
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST>
FORCEINLINE void Composite16(GPUEngineCompositorInfo &compInfo,
const bool didAllPixelsPass,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u16 &src1, const v128u16 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const u8 *__restrict enableColorEffectPtr,
const u8 *__restrict sprAlphaPtr,
const u8 *__restrict sprModePtr) const;
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, GPULayerType LAYERTYPE, bool WILLPERFORMWINDOWTEST>
FORCEINLINE void Composite32(GPUEngineCompositorInfo &compInfo,
const bool didAllPixelsPass,
const v128u8 &passMask8,
const v128u16 &evy16,
const v128u8 &srcLayerID,
const v128u32 &src3, const v128u32 &src2, const v128u32 &src1, const v128u32 &src0,
const v128u8 &srcEffectEnableMask,
const v128u8 &dstBlendEnableMaskLUT,
const u8 *__restrict enableColorEffectPtr,
const u8 *__restrict sprAlphaPtr,
const u8 *__restrict sprModePtr) const;
};
#endif // ENABLE_NEON_A64
#endif // GPU_OPERATIONS_NEON_H

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2021-2022 DeSmuME team Copyright (C) 2021-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -279,6 +279,378 @@ static FORCEINLINE void CopyLineExpand(void *__restrict dst, const void *__restr
} }
} }
#ifdef ENABLE_SSSE3 #ifdef ENABLE_SSSE3
else if (INTEGERSCALEHINT == 5)
{
__m128i srcPixOut[5];
for (size_t srcX = 0, dstX = 0; srcX < GPU_FRAMEBUFFER_NATIVE_WIDTH / (sizeof(__m128i) / ELEMENTSIZE); srcX++, dstX+=INTEGERSCALEHINT)
{
const __m128i srcVec = _mm_load_si128((__m128i *)src + srcX);
if (ELEMENTSIZE == 1)
{
srcPixOut[0] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3));
srcPixOut[1] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6));
srcPixOut[2] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9));
srcPixOut[3] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 9, 9,10,10,10,10,10,11,11,11,11,11,12,12,12,12));
srcPixOut[4] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(12,13,13,13,13,13,14,14,14,14,14,15,15,15,15,15));
}
else if (ELEMENTSIZE == 2)
{
srcPixOut[0] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3));
srcPixOut[1] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 2, 3, 2, 3, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 7));
srcPixOut[2] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 6, 7, 6, 7, 6, 7, 6, 7, 8, 9, 8, 9, 8, 9, 8, 9));
srcPixOut[3] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 8, 9,10,11,10,11,10,11,10,11,10,11,12,13,12,13));
srcPixOut[4] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(12,13,12,13,12,13,14,15,14,15,14,15,14,15,14,15));
}
else if (ELEMENTSIZE == 4)
{
srcPixOut[0] = _mm_shuffle_epi32(srcVec, 0x00);
srcPixOut[1] = _mm_shuffle_epi32(srcVec, 0x54);
srcPixOut[2] = _mm_shuffle_epi32(srcVec, 0xA5);
srcPixOut[3] = _mm_shuffle_epi32(srcVec, 0xEA);
srcPixOut[4] = _mm_shuffle_epi32(srcVec, 0xFF);
}
for (size_t lx = 0; lx < (size_t)INTEGERSCALEHINT; lx++)
{
_mm_store_si128((__m128i *)dst + dstX + lx, srcPixOut[lx]);
}
if (SCALEVERTICAL)
{
for (size_t ly = 1; ly < (size_t)INTEGERSCALEHINT; ly++)
{
for (size_t lx = 0; lx < (size_t)INTEGERSCALEHINT; lx++)
{
_mm_store_si128((__m128i *)dst + dstX + ((GPU_FRAMEBUFFER_NATIVE_WIDTH / (sizeof(__m128i) / ELEMENTSIZE) * INTEGERSCALEHINT) * ly) + lx, srcPixOut[lx]);
}
}
}
}
}
else if (INTEGERSCALEHINT == 6)
{
__m128i srcPixOut[6];
for (size_t srcX = 0, dstX = 0; srcX < GPU_FRAMEBUFFER_NATIVE_WIDTH / (sizeof(__m128i) / ELEMENTSIZE); srcX++, dstX+=INTEGERSCALEHINT)
{
const __m128i srcVec = _mm_load_si128((__m128i *)src + srcX);
if (ELEMENTSIZE == 1)
{
srcPixOut[0] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2));
srcPixOut[1] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5));
srcPixOut[2] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7));
srcPixOut[3] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10,10));
srcPixOut[4] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(10,10,11,11,11,11,11,11,12,12,12,12,12,12,13,13));
srcPixOut[5] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(13,13,13,13,14,14,14,14,14,14,15,15,15,15,15,15));
}
else if (ELEMENTSIZE == 2)
{
srcPixOut[0] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3));
srcPixOut[1] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 2, 3, 2, 3, 2, 3, 2, 3, 4, 5, 4, 5, 4, 5, 4, 5));
srcPixOut[2] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 4, 5, 4, 5, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7));
srcPixOut[3] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9,10,11,10,11));
srcPixOut[4] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(10,11,10,11,10,11,10,11,12,13,12,13,12,13,12,13));
srcPixOut[5] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(12,13,12,13,14,15,14,15,14,15,14,15,14,15,14,15));
}
else if (ELEMENTSIZE == 4)
{
srcPixOut[0] = _mm_shuffle_epi32(srcVec, 0x00);
srcPixOut[1] = _mm_shuffle_epi32(srcVec, 0x50);
srcPixOut[2] = _mm_shuffle_epi32(srcVec, 0x55);
srcPixOut[3] = _mm_shuffle_epi32(srcVec, 0xAA);
srcPixOut[4] = _mm_shuffle_epi32(srcVec, 0xFA);
srcPixOut[5] = _mm_shuffle_epi32(srcVec, 0xFF);
}
for (size_t lx = 0; lx < (size_t)INTEGERSCALEHINT; lx++)
{
_mm_store_si128((__m128i *)dst + dstX + lx, srcPixOut[lx]);
}
if (SCALEVERTICAL)
{
for (size_t ly = 1; ly < (size_t)INTEGERSCALEHINT; ly++)
{
for (size_t lx = 0; lx < (size_t)INTEGERSCALEHINT; lx++)
{
_mm_store_si128((__m128i *)dst + dstX + ((GPU_FRAMEBUFFER_NATIVE_WIDTH / (sizeof(__m128i) / ELEMENTSIZE) * INTEGERSCALEHINT) * ly) + lx, srcPixOut[lx]);
}
}
}
}
}
else if (INTEGERSCALEHINT == 7)
{
__m128i srcPixOut[7];
for (size_t srcX = 0, dstX = 0; srcX < GPU_FRAMEBUFFER_NATIVE_WIDTH / (sizeof(__m128i) / ELEMENTSIZE); srcX++, dstX+=INTEGERSCALEHINT)
{
const __m128i srcVec = _mm_load_si128((__m128i *)src + srcX);
if (ELEMENTSIZE == 1)
{
srcPixOut[0] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2));
srcPixOut[1] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4));
srcPixOut[2] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6));
srcPixOut[3] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9));
srcPixOut[4] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,11,11,11));
srcPixOut[5] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(11,11,11,11,12,12,12,12,12,12,12,13,13,13,13,13));
srcPixOut[6] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(13,13,14,14,14,14,14,14,14,15,15,15,15,15,15,15));
}
else if (ELEMENTSIZE == 2)
{
srcPixOut[0] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3));
srcPixOut[1] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 4, 5, 4, 5));
srcPixOut[2] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 7, 6, 7, 6, 7));
srcPixOut[3] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 6, 7, 6, 7, 6, 7, 6, 7, 8, 9, 8, 9, 8, 9, 8, 9));
srcPixOut[4] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 8, 9, 8, 9, 8, 9,10,11,10,11,10,11,10,11,10,11));
srcPixOut[5] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(10,11,10,11,12,13,12,13,12,13,12,13,12,13,12,13));
srcPixOut[6] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(12,13,14,15,14,15,14,15,14,15,14,15,14,15,14,15));
}
else if (ELEMENTSIZE == 4)
{
srcPixOut[0] = _mm_shuffle_epi32(srcVec, 0x00);
srcPixOut[1] = _mm_shuffle_epi32(srcVec, 0x40);
srcPixOut[2] = _mm_shuffle_epi32(srcVec, 0x55);
srcPixOut[3] = _mm_shuffle_epi32(srcVec, 0xA5);
srcPixOut[4] = _mm_shuffle_epi32(srcVec, 0xAA);
srcPixOut[5] = _mm_shuffle_epi32(srcVec, 0xFE);
srcPixOut[6] = _mm_shuffle_epi32(srcVec, 0xFF);
}
for (size_t lx = 0; lx < (size_t)INTEGERSCALEHINT; lx++)
{
_mm_store_si128((__m128i *)dst + dstX + lx, srcPixOut[lx]);
}
if (SCALEVERTICAL)
{
for (size_t ly = 1; ly < (size_t)INTEGERSCALEHINT; ly++)
{
for (size_t lx = 0; lx < (size_t)INTEGERSCALEHINT; lx++)
{
_mm_store_si128((__m128i *)dst + dstX + ((GPU_FRAMEBUFFER_NATIVE_WIDTH / (sizeof(__m128i) / ELEMENTSIZE) * INTEGERSCALEHINT) * ly) + lx, srcPixOut[lx]);
}
}
}
}
}
else if (INTEGERSCALEHINT == 8)
{
__m128i srcPixOut[8];
for (size_t srcX = 0, dstX = 0; srcX < GPU_FRAMEBUFFER_NATIVE_WIDTH / (sizeof(__m128i) / ELEMENTSIZE); srcX++, dstX+=INTEGERSCALEHINT)
{
const __m128i srcVec = _mm_load_si128((__m128i *)src + srcX);
if (ELEMENTSIZE == 1)
{
srcPixOut[0] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1));
srcPixOut[1] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3));
srcPixOut[2] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5));
srcPixOut[3] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7));
srcPixOut[4] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9));
srcPixOut[5] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11));
srcPixOut[6] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13));
srcPixOut[7] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15));
}
else if (ELEMENTSIZE == 2)
{
srcPixOut[0] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1));
srcPixOut[1] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3));
srcPixOut[2] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5));
srcPixOut[3] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7));
srcPixOut[4] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9));
srcPixOut[5] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11));
srcPixOut[6] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13));
srcPixOut[7] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15));
}
else if (ELEMENTSIZE == 4)
{
srcPixOut[0] = _mm_shuffle_epi32(srcVec, 0x00);
srcPixOut[1] = _mm_shuffle_epi32(srcVec, 0x00);
srcPixOut[2] = _mm_shuffle_epi32(srcVec, 0x55);
srcPixOut[3] = _mm_shuffle_epi32(srcVec, 0x55);
srcPixOut[4] = _mm_shuffle_epi32(srcVec, 0xAA);
srcPixOut[5] = _mm_shuffle_epi32(srcVec, 0xAA);
srcPixOut[6] = _mm_shuffle_epi32(srcVec, 0xFF);
srcPixOut[7] = _mm_shuffle_epi32(srcVec, 0xFF);
}
for (size_t lx = 0; lx < (size_t)INTEGERSCALEHINT; lx++)
{
_mm_store_si128((__m128i *)dst + dstX + lx, srcPixOut[lx]);
}
if (SCALEVERTICAL)
{
for (size_t ly = 1; ly < (size_t)INTEGERSCALEHINT; ly++)
{
for (size_t lx = 0; lx < (size_t)INTEGERSCALEHINT; lx++)
{
_mm_store_si128((__m128i *)dst + dstX + ((GPU_FRAMEBUFFER_NATIVE_WIDTH / (sizeof(__m128i) / ELEMENTSIZE) * INTEGERSCALEHINT) * ly) + lx, srcPixOut[lx]);
}
}
}
}
}
else if (INTEGERSCALEHINT == 12)
{
__m128i srcPixOut[12];
for (size_t srcX = 0, dstX = 0; srcX < GPU_FRAMEBUFFER_NATIVE_WIDTH / (sizeof(__m128i) / ELEMENTSIZE); srcX++, dstX+=INTEGERSCALEHINT)
{
const __m128i srcVec = _mm_load_si128((__m128i *)src + srcX);
if (ELEMENTSIZE == 1)
{
srcPixOut[ 0] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1));
srcPixOut[ 1] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2));
srcPixOut[ 2] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3));
srcPixOut[ 3] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5));
srcPixOut[ 4] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6));
srcPixOut[ 5] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7));
srcPixOut[ 6] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9));
srcPixOut[ 7] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10));
srcPixOut[ 8] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11));
srcPixOut[ 9] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13));
srcPixOut[10] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14));
srcPixOut[11] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15));
}
else if (ELEMENTSIZE == 2)
{
srcPixOut[ 0] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1));
srcPixOut[ 1] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3));
srcPixOut[ 2] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3));
srcPixOut[ 3] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5));
srcPixOut[ 4] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 4, 5, 4, 5, 4, 5, 4, 5, 6, 7, 6, 7, 6, 7, 6, 7));
srcPixOut[ 5] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7));
srcPixOut[ 6] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9));
srcPixOut[ 7] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 8, 9, 8, 9, 8, 9, 8, 9,10,11,10,11,10,11,10,11));
srcPixOut[ 8] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11));
srcPixOut[ 9] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13));
srcPixOut[10] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(12,13,12,13,12,13,12,13,14,15,14,15,14,15,14,15));
srcPixOut[11] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15));
}
else if (ELEMENTSIZE == 4)
{
srcPixOut[ 0] = _mm_shuffle_epi32(srcVec, 0x00);
srcPixOut[ 1] = _mm_shuffle_epi32(srcVec, 0x00);
srcPixOut[ 2] = _mm_shuffle_epi32(srcVec, 0x00);
srcPixOut[ 3] = _mm_shuffle_epi32(srcVec, 0x55);
srcPixOut[ 4] = _mm_shuffle_epi32(srcVec, 0x55);
srcPixOut[ 5] = _mm_shuffle_epi32(srcVec, 0x55);
srcPixOut[ 6] = _mm_shuffle_epi32(srcVec, 0xAA);
srcPixOut[ 7] = _mm_shuffle_epi32(srcVec, 0xAA);
srcPixOut[ 8] = _mm_shuffle_epi32(srcVec, 0xAA);
srcPixOut[ 9] = _mm_shuffle_epi32(srcVec, 0xFF);
srcPixOut[10] = _mm_shuffle_epi32(srcVec, 0xFF);
srcPixOut[11] = _mm_shuffle_epi32(srcVec, 0xFF);
}
for (size_t lx = 0; lx < (size_t)INTEGERSCALEHINT; lx++)
{
_mm_store_si128((__m128i *)dst + dstX + lx, srcPixOut[lx]);
}
if (SCALEVERTICAL)
{
for (size_t ly = 1; ly < (size_t)INTEGERSCALEHINT; ly++)
{
for (size_t lx = 0; lx < (size_t)INTEGERSCALEHINT; lx++)
{
_mm_store_si128((__m128i *)dst + dstX + ((GPU_FRAMEBUFFER_NATIVE_WIDTH / (sizeof(__m128i) / ELEMENTSIZE) * INTEGERSCALEHINT) * ly) + lx, srcPixOut[lx]);
}
}
}
}
}
else if (INTEGERSCALEHINT == 16)
{
__m128i srcPixOut[16];
for (size_t srcX = 0, dstX = 0; srcX < GPU_FRAMEBUFFER_NATIVE_WIDTH / (sizeof(__m128i) / ELEMENTSIZE); srcX++, dstX+=INTEGERSCALEHINT)
{
const __m128i srcVec = _mm_load_si128((__m128i *)src + srcX);
if (ELEMENTSIZE == 1)
{
srcPixOut[ 0] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
srcPixOut[ 1] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1));
srcPixOut[ 2] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2));
srcPixOut[ 3] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3));
srcPixOut[ 4] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4));
srcPixOut[ 5] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5));
srcPixOut[ 6] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6));
srcPixOut[ 7] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7));
srcPixOut[ 8] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8));
srcPixOut[ 9] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9));
srcPixOut[10] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10));
srcPixOut[11] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11));
srcPixOut[12] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12));
srcPixOut[13] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13));
srcPixOut[14] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14));
srcPixOut[15] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15));
}
else if (ELEMENTSIZE == 2)
{
srcPixOut[ 0] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1));
srcPixOut[ 1] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1));
srcPixOut[ 2] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3));
srcPixOut[ 3] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3));
srcPixOut[ 4] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5));
srcPixOut[ 5] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5));
srcPixOut[ 6] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7));
srcPixOut[ 7] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7));
srcPixOut[ 8] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9));
srcPixOut[ 9] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8( 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9));
srcPixOut[10] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11));
srcPixOut[11] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11));
srcPixOut[12] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13));
srcPixOut[13] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13));
srcPixOut[14] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15));
srcPixOut[15] = _mm_shuffle_epi8(srcVec, _mm_setr_epi8(14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15));
}
else if (ELEMENTSIZE == 4)
{
srcPixOut[ 0] = _mm_shuffle_epi32(srcVec, 0x00);
srcPixOut[ 1] = _mm_shuffle_epi32(srcVec, 0x00);
srcPixOut[ 2] = _mm_shuffle_epi32(srcVec, 0x00);
srcPixOut[ 3] = _mm_shuffle_epi32(srcVec, 0x00);
srcPixOut[ 4] = _mm_shuffle_epi32(srcVec, 0x55);
srcPixOut[ 5] = _mm_shuffle_epi32(srcVec, 0x55);
srcPixOut[ 6] = _mm_shuffle_epi32(srcVec, 0x55);
srcPixOut[ 7] = _mm_shuffle_epi32(srcVec, 0x55);
srcPixOut[ 8] = _mm_shuffle_epi32(srcVec, 0xAA);
srcPixOut[ 9] = _mm_shuffle_epi32(srcVec, 0xAA);
srcPixOut[10] = _mm_shuffle_epi32(srcVec, 0xAA);
srcPixOut[11] = _mm_shuffle_epi32(srcVec, 0xAA);
srcPixOut[12] = _mm_shuffle_epi32(srcVec, 0xFF);
srcPixOut[13] = _mm_shuffle_epi32(srcVec, 0xFF);
srcPixOut[14] = _mm_shuffle_epi32(srcVec, 0xFF);
srcPixOut[15] = _mm_shuffle_epi32(srcVec, 0xFF);
}
for (size_t lx = 0; lx < (size_t)INTEGERSCALEHINT; lx++)
{
_mm_store_si128((__m128i *)dst + dstX + lx, srcPixOut[lx]);
}
if (SCALEVERTICAL)
{
for (size_t ly = 1; ly < (size_t)INTEGERSCALEHINT; ly++)
{
for (size_t lx = 0; lx < (size_t)INTEGERSCALEHINT; lx++)
{
_mm_store_si128((__m128i *)dst + dstX + ((GPU_FRAMEBUFFER_NATIVE_WIDTH / (sizeof(__m128i) / ELEMENTSIZE) * INTEGERSCALEHINT) * ly) + lx, srcPixOut[lx]);
}
}
}
}
}
else if (INTEGERSCALEHINT > 1) else if (INTEGERSCALEHINT > 1)
{ {
const size_t scale = dstWidth / GPU_FRAMEBUFFER_NATIVE_WIDTH; const size_t scale = dstWidth / GPU_FRAMEBUFFER_NATIVE_WIDTH;
@ -737,6 +1109,36 @@ FORCEINLINE v128u16 ColorOperation_SSE2::blend3D(const v128u32 &colA_Lo, const v
{ {
// If the color format of B is 555, then the colA_Hi parameter is required. // If the color format of B is 555, then the colA_Hi parameter is required.
// The color format of A is assumed to be RGB666. // The color format of A is assumed to be RGB666.
#ifdef ENABLE_SSSE3
static const u8 X = 0x80;
const v128u32 ra_lo = _mm_shuffle_epi8( colA_Lo, _mm_set_epi8( X, X, X,12, X, X, X, 8, X, X, X, 4, X, X, X, 0) );
const v128u32 ga_lo = _mm_shuffle_epi8( colA_Lo, _mm_set_epi8( X, X, X,13, X, X, X, 9, X, X, X, 5, X, X, X, 1) );
const v128u32 ba_lo = _mm_shuffle_epi8( colA_Lo, _mm_set_epi8( X, X, X,14, X, X, X,10, X, X, X, 6, X, X, X, 2) );
const v128u32 aa_lo = _mm_shuffle_epi8( colA_Lo, _mm_set_epi8( X, X, X,15, X, X, X,11, X, X, X, 7, X, X, X, 3) );
const v128u32 ra_hi = _mm_shuffle_epi8( colA_Hi, _mm_set_epi8( X, X, X,12, X, X, X, 8, X, X, X, 4, X, X, X, 0) );
const v128u32 ga_hi = _mm_shuffle_epi8( colA_Hi, _mm_set_epi8( X, X, X,13, X, X, X, 9, X, X, X, 5, X, X, X, 1) );
const v128u32 ba_hi = _mm_shuffle_epi8( colA_Hi, _mm_set_epi8( X, X, X,14, X, X, X,10, X, X, X, 6, X, X, X, 2) );
const v128u32 aa_hi = _mm_shuffle_epi8( colA_Hi, _mm_set_epi8( X, X, X,15, X, X, X,11, X, X, X, 7, X, X, X, 3) );
v128u16 ra = _mm_packs_epi32(ra_lo, ra_hi);
v128u16 ga = _mm_packs_epi32(ga_lo, ga_hi);
v128u16 ba = _mm_packs_epi32(ba_lo, ba_hi);
v128u16 aa = _mm_packs_epi32(aa_lo, aa_hi);
ra = _mm_or_si128( ra, _mm_and_si128(_mm_slli_epi16(colB, 9), _mm_set1_epi16(0x3E00)) );
ga = _mm_or_si128( ga, _mm_and_si128(_mm_slli_epi16(colB, 4), _mm_set1_epi16(0x3E00)) );
ba = _mm_or_si128( ba, _mm_and_si128(_mm_srli_epi16(colB, 1), _mm_set1_epi16(0x3E00)) );
aa = _mm_adds_epu8(aa, _mm_set1_epi16(1));
aa = _mm_or_si128( aa, _mm_slli_epi16(_mm_subs_epu16(_mm_set1_epi8(32), aa), 8) );
ra = _mm_maddubs_epi16(ra, aa);
ga = _mm_maddubs_epi16(ga, aa);
ba = _mm_maddubs_epi16(ba, aa);
#else
v128u32 ra_lo = _mm_and_si128( colA_Lo, _mm_set1_epi32(0x000000FF) ); v128u32 ra_lo = _mm_and_si128( colA_Lo, _mm_set1_epi32(0x000000FF) );
v128u32 ga_lo = _mm_and_si128( _mm_srli_epi32(colA_Lo, 8), _mm_set1_epi32(0x000000FF) ); v128u32 ga_lo = _mm_and_si128( _mm_srli_epi32(colA_Lo, 8), _mm_set1_epi32(0x000000FF) );
v128u32 ba_lo = _mm_and_si128( _mm_srli_epi32(colA_Lo, 16), _mm_set1_epi32(0x000000FF) ); v128u32 ba_lo = _mm_and_si128( _mm_srli_epi32(colA_Lo, 16), _mm_set1_epi32(0x000000FF) );
@ -752,18 +1154,6 @@ FORCEINLINE v128u16 ColorOperation_SSE2::blend3D(const v128u32 &colA_Lo, const v
v128u16 ba = _mm_packs_epi32(ba_lo, ba_hi); v128u16 ba = _mm_packs_epi32(ba_lo, ba_hi);
v128u16 aa = _mm_packs_epi32(aa_lo, aa_hi); v128u16 aa = _mm_packs_epi32(aa_lo, aa_hi);
#ifdef ENABLE_SSSE3
ra = _mm_or_si128( ra, _mm_and_si128(_mm_slli_epi16(colB, 9), _mm_set1_epi16(0x3E00)) );
ga = _mm_or_si128( ga, _mm_and_si128(_mm_slli_epi16(colB, 4), _mm_set1_epi16(0x3E00)) );
ba = _mm_or_si128( ba, _mm_and_si128(_mm_srli_epi16(colB, 1), _mm_set1_epi16(0x3E00)) );
aa = _mm_adds_epu8(aa, _mm_set1_epi16(1));
aa = _mm_or_si128( aa, _mm_slli_epi16(_mm_subs_epu16(_mm_set1_epi8(32), aa), 8) );
ra = _mm_maddubs_epi16(ra, aa);
ga = _mm_maddubs_epi16(ga, aa);
ba = _mm_maddubs_epi16(ba, aa);
#else
aa = _mm_adds_epu16(aa, _mm_set1_epi16(1)); aa = _mm_adds_epu16(aa, _mm_set1_epi16(1));
v128u16 rb = _mm_and_si128( _mm_slli_epi16(colB, 1), _mm_set1_epi16(0x003E) ); v128u16 rb = _mm_and_si128( _mm_slli_epi16(colB, 1), _mm_set1_epi16(0x003E) );
v128u16 gb = _mm_and_si128( _mm_srli_epi16(colB, 4), _mm_set1_epi16(0x003E) ); v128u16 gb = _mm_and_si128( _mm_srli_epi16(colB, 4), _mm_set1_epi16(0x003E) );
@ -785,6 +1175,9 @@ FORCEINLINE v128u16 ColorOperation_SSE2::blend3D(const v128u32 &colA_Lo, const v
template <NDSColorFormat COLORFORMAT> template <NDSColorFormat COLORFORMAT>
FORCEINLINE v128u32 ColorOperation_SSE2::blend3D(const v128u32 &colA, const v128u32 &colB) const FORCEINLINE v128u32 ColorOperation_SSE2::blend3D(const v128u32 &colA, const v128u32 &colB) const
{ {
#ifdef ENABLE_SSSE3
static const u8 X = 0x80;
#endif
// If the color format of B is 666 or 888, then the colA_Hi parameter is ignored. // If the color format of B is 666 or 888, then the colA_Hi parameter is ignored.
// The color format of A is assumed to match the color format of B. // The color format of A is assumed to match the color format of B.
v128u16 rgbALo; v128u16 rgbALo;
@ -804,13 +1197,12 @@ FORCEINLINE v128u32 ColorOperation_SSE2::blend3D(const v128u32 &colA, const v128
rgbALo = _mm_unpacklo_epi8(colA, colB); rgbALo = _mm_unpacklo_epi8(colA, colB);
rgbAHi = _mm_unpackhi_epi8(colA, colB); rgbAHi = _mm_unpackhi_epi8(colA, colB);
v128u32 alpha = _mm_and_si128( _mm_srli_epi32(colA, 24), _mm_set1_epi32(0x0000001F) ); v128u8 alpha = _mm_shuffle_epi8( colA, _mm_set_epi8( X,15,15,15, X,11,11,11, X, 7, 7, 7, X, 3, 3, 3) );
alpha = _mm_or_si128( alpha, _mm_or_si128(_mm_slli_epi32(alpha, 8), _mm_slli_epi32(alpha, 16)) );
alpha = _mm_adds_epu8(alpha, _mm_set1_epi8(1)); alpha = _mm_adds_epu8(alpha, _mm_set1_epi8(1));
v128u32 invAlpha = _mm_subs_epu8(_mm_set1_epi8(32), alpha); const v128u8 invAlpha = _mm_subs_epu8(_mm_set1_epi8(32), alpha);
v128u16 alphaLo = _mm_unpacklo_epi8(alpha, invAlpha); const v128u16 alphaLo = _mm_unpacklo_epi8(alpha, invAlpha);
v128u16 alphaHi = _mm_unpackhi_epi8(alpha, invAlpha); const v128u16 alphaHi = _mm_unpackhi_epi8(alpha, invAlpha);
rgbALo = _mm_maddubs_epi16(rgbALo, alphaLo); rgbALo = _mm_maddubs_epi16(rgbALo, alphaLo);
rgbAHi = _mm_maddubs_epi16(rgbAHi, alphaHi); rgbAHi = _mm_maddubs_epi16(rgbAHi, alphaHi);
@ -823,9 +1215,12 @@ FORCEINLINE v128u32 ColorOperation_SSE2::blend3D(const v128u32 &colA, const v128
v128u16 rgbBLo = _mm_unpacklo_epi8(colB, _mm_setzero_si128()); v128u16 rgbBLo = _mm_unpacklo_epi8(colB, _mm_setzero_si128());
v128u16 rgbBHi = _mm_unpackhi_epi8(colB, _mm_setzero_si128()); v128u16 rgbBHi = _mm_unpackhi_epi8(colB, _mm_setzero_si128());
v128u32 alpha = _mm_and_si128( _mm_srli_epi32(colA, 24), _mm_set1_epi32(0x000000FF) ); #ifdef ENABLE_SSSE3
v128u8 alpha = _mm_shuffle_epi8( colA, _mm_set_epi8( X,15,15,15, X,11,11,11, X, 7, 7, 7, X, 3, 3, 3) );
#else
v128u8 alpha = _mm_and_si128( _mm_srli_epi32(colA, 24), _mm_set1_epi32(0x000000FF) );
alpha = _mm_or_si128( alpha, _mm_or_si128(_mm_slli_epi32(alpha, 8), _mm_slli_epi32(alpha, 16)) ); alpha = _mm_or_si128( alpha, _mm_or_si128(_mm_slli_epi32(alpha, 8), _mm_slli_epi32(alpha, 16)) );
#endif
v128u16 alphaLo = _mm_unpacklo_epi8(alpha, _mm_setzero_si128()); v128u16 alphaLo = _mm_unpacklo_epi8(alpha, _mm_setzero_si128());
v128u16 alphaHi = _mm_unpackhi_epi8(alpha, _mm_setzero_si128()); v128u16 alphaHi = _mm_unpackhi_epi8(alpha, _mm_setzero_si128());
alphaLo = _mm_add_epi16(alphaLo, _mm_set1_epi16(1)); alphaLo = _mm_add_epi16(alphaLo, _mm_set1_epi16(1));
@ -922,13 +1317,13 @@ FORCEINLINE void PixelOperation_SSE2::_copy16(GPUEngineCompositorInfo &compInfo,
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555To6665Opaque_SSE2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo6665Opaque_SSE2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555To6665Opaque_SSE2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo6665Opaque_SSE2<false>(src1, src32[2], src32[3]);
} }
else else
{ {
ColorspaceConvert555To8888Opaque_SSE2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo8888Opaque_SSE2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555To8888Opaque_SSE2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo8888Opaque_SSE2<false>(src1, src32[2], src32[3]);
} }
_mm_store_si128( (v128u32 *)compInfo.target.lineColor32 + 0, src32[0] ); _mm_store_si128( (v128u32 *)compInfo.target.lineColor32 + 0, src32[0] );
@ -999,20 +1394,20 @@ FORCEINLINE void PixelOperation_SSE2::_copyMask16(GPUEngineCompositorInfo &compI
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555To6665Opaque_SSE2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo6665Opaque_SSE2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555To6665Opaque_SSE2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo6665Opaque_SSE2<false>(src1, src32[2], src32[3]);
} }
else else
{ {
ColorspaceConvert555To8888Opaque_SSE2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo8888Opaque_SSE2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555To8888Opaque_SSE2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo8888Opaque_SSE2<false>(src1, src32[2], src32[3]);
} }
const v128u32 dst32[4] = { const v128u32 dst32[4] = {
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3)
}; };
const v128u32 passMask32[4] = { const v128u32 passMask32[4] = {
@ -1072,7 +1467,7 @@ FORCEINLINE void PixelOperation_SSE2::_copyMask32(GPUEngineCompositorInfo &compI
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3)
}; };
const v128u32 alphaBits = _mm_set1_epi32((OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? 0x1F000000 : 0xFF000000); const v128u32 alphaBits = _mm_set1_epi32((OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? 0x1F000000 : 0xFF000000);
@ -1104,13 +1499,13 @@ FORCEINLINE void PixelOperation_SSE2::_brightnessUp16(GPUEngineCompositorInfo &c
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555XTo666X_SSE2<false>(src0, dst[0], dst[1]); ColorspaceConvert555xTo666x_SSE2<false>(src0, dst[0], dst[1]);
ColorspaceConvert555XTo666X_SSE2<false>(src1, dst[2], dst[3]); ColorspaceConvert555xTo666x_SSE2<false>(src1, dst[2], dst[3]);
} }
else else
{ {
ColorspaceConvert555XTo888X_SSE2<false>(src0, dst[0], dst[1]); ColorspaceConvert555xTo888x_SSE2<false>(src0, dst[0], dst[1]);
ColorspaceConvert555XTo888X_SSE2<false>(src1, dst[2], dst[3]); ColorspaceConvert555xTo888x_SSE2<false>(src1, dst[2], dst[3]);
} }
const v128u32 alphaBits = (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? _mm_set1_epi32(0x1F000000) : _mm_set1_epi32(0xFF000000); const v128u32 alphaBits = (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? _mm_set1_epi32(0x1F000000) : _mm_set1_epi32(0xFF000000);
@ -1182,20 +1577,20 @@ FORCEINLINE void PixelOperation_SSE2::_brightnessUpMask16(GPUEngineCompositorInf
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555XTo666X_SSE2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo666x_SSE2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555XTo666X_SSE2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo666x_SSE2<false>(src1, src32[2], src32[3]);
} }
else else
{ {
ColorspaceConvert555XTo888X_SSE2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo888x_SSE2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555XTo888X_SSE2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo888x_SSE2<false>(src1, src32[2], src32[3]);
} }
const v128u32 dst32[4] = { const v128u32 dst32[4] = {
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3)
}; };
const v128u32 alphaBits = _mm_set1_epi32((OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? 0x1F000000 : 0xFF000000); const v128u32 alphaBits = _mm_set1_epi32((OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? 0x1F000000 : 0xFF000000);
@ -1246,7 +1641,7 @@ FORCEINLINE void PixelOperation_SSE2::_brightnessUpMask32(GPUEngineCompositorInf
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3)
}; };
const v128u32 alphaBits = _mm_set1_epi32((OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? 0x1F000000 : 0xFF000000); const v128u32 alphaBits = _mm_set1_epi32((OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? 0x1F000000 : 0xFF000000);
@ -1275,13 +1670,13 @@ FORCEINLINE void PixelOperation_SSE2::_brightnessDown16(GPUEngineCompositorInfo
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555XTo666X_SSE2<false>(src0, dst[0], dst[1]); ColorspaceConvert555xTo666x_SSE2<false>(src0, dst[0], dst[1]);
ColorspaceConvert555XTo666X_SSE2<false>(src1, dst[2], dst[3]); ColorspaceConvert555xTo666x_SSE2<false>(src1, dst[2], dst[3]);
} }
else else
{ {
ColorspaceConvert555XTo888X_SSE2<false>(src0, dst[0], dst[1]); ColorspaceConvert555xTo888x_SSE2<false>(src0, dst[0], dst[1]);
ColorspaceConvert555XTo888X_SSE2<false>(src1, dst[2], dst[3]); ColorspaceConvert555xTo888x_SSE2<false>(src1, dst[2], dst[3]);
} }
const v128u32 alphaBits = (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? _mm_set1_epi32(0x1F000000) : _mm_set1_epi32(0xFF000000); const v128u32 alphaBits = (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? _mm_set1_epi32(0x1F000000) : _mm_set1_epi32(0xFF000000);
@ -1353,20 +1748,20 @@ FORCEINLINE void PixelOperation_SSE2::_brightnessDownMask16(GPUEngineCompositorI
if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555XTo666X_SSE2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo666x_SSE2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555XTo666X_SSE2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo666x_SSE2<false>(src1, src32[2], src32[3]);
} }
else else
{ {
ColorspaceConvert555XTo888X_SSE2<false>(src0, src32[0], src32[1]); ColorspaceConvert555xTo888x_SSE2<false>(src0, src32[0], src32[1]);
ColorspaceConvert555XTo888X_SSE2<false>(src1, src32[2], src32[3]); ColorspaceConvert555xTo888x_SSE2<false>(src1, src32[2], src32[3]);
} }
const v128u32 dst32[4] = { const v128u32 dst32[4] = {
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3)
}; };
const v128u32 alphaBits = _mm_set1_epi32((OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? 0x1F000000 : 0xFF000000); const v128u32 alphaBits = _mm_set1_epi32((OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? 0x1F000000 : 0xFF000000);
@ -1417,7 +1812,7 @@ FORCEINLINE void PixelOperation_SSE2::_brightnessDownMask32(GPUEngineCompositorI
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3)
}; };
const v128u32 alphaBits = _mm_set1_epi32((OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? 0x1F000000 : 0xFF000000); const v128u32 alphaBits = _mm_set1_epi32((OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) ? 0x1F000000 : 0xFF000000);
@ -1494,13 +1889,13 @@ FORCEINLINE void PixelOperation_SSE2::_unknownEffectMask16(GPUEngineCompositorIn
} }
else if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev) else if (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev)
{ {
ColorspaceConvert555XTo666X_SSE2<false>(src0, tmpSrc[0], tmpSrc[1]); ColorspaceConvert555xTo666x_SSE2<false>(src0, tmpSrc[0], tmpSrc[1]);
ColorspaceConvert555XTo666X_SSE2<false>(src1, tmpSrc[2], tmpSrc[3]); ColorspaceConvert555xTo666x_SSE2<false>(src1, tmpSrc[2], tmpSrc[3]);
} }
else else
{ {
ColorspaceConvert555XTo888X_SSE2<false>(src0, tmpSrc[0], tmpSrc[1]); ColorspaceConvert555xTo888x_SSE2<false>(src0, tmpSrc[0], tmpSrc[1]);
ColorspaceConvert555XTo888X_SSE2<false>(src1, tmpSrc[2], tmpSrc[3]); ColorspaceConvert555xTo888x_SSE2<false>(src1, tmpSrc[2], tmpSrc[3]);
} }
switch (compInfo.renderState.colorEffect) switch (compInfo.renderState.colorEffect)
@ -1656,7 +2051,7 @@ FORCEINLINE void PixelOperation_SSE2::_unknownEffectMask16(GPUEngineCompositorIn
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3)
}; };
if (blendMaskValue != 0x00000000) if (blendMaskValue != 0x00000000)
@ -1965,7 +2360,7 @@ FORCEINLINE void PixelOperation_SSE2::_unknownEffectMask32(GPUEngineCompositorIn
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 0),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 1),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 2),
_mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3), _mm_load_si128((v128u32 *)compInfo.target.lineColor32 + 3)
}; };
if (blendMaskValue != 0x00000000) if (blendMaskValue != 0x00000000)
@ -2246,14 +2641,14 @@ void GPUEngineBase::_MosaicLine(GPUEngineCompositorInfo &compInfo)
_mm_blendv_epi8(_mm_and_si128(dstColor16[1], _mm_set1_epi16(0x7FFF)), _mm_set1_epi16(0xFFFF), idxMask16[1]) _mm_blendv_epi8(_mm_and_si128(dstColor16[1], _mm_set1_epi16(0x7FFF)), _mm_set1_epi16(0xFFFF), idxMask16[1])
}; };
const v128u16 mosaicSetColorMask8 = _mm_cmpeq_epi16( _mm_loadu_si128((v128u8 *)(compInfo.renderState.mosaicWidthBG->begin + x)), _mm_setzero_si128() ); const v128u16 mosaicSetColorMask8 = _mm_cmpeq_epi16( _mm_load_si128((v128u8 *)(compInfo.renderState.mosaicWidthBG->begin + x)), _mm_setzero_si128() );
const v128u16 mosaicSetColorMask16[2] = { const v128u16 mosaicSetColorMask16[2] = {
_mm_unpacklo_epi8(mosaicSetColorMask8, mosaicSetColorMask8), _mm_unpacklo_epi8(mosaicSetColorMask8, mosaicSetColorMask8),
_mm_unpackhi_epi8(mosaicSetColorMask8, mosaicSetColorMask8) _mm_unpackhi_epi8(mosaicSetColorMask8, mosaicSetColorMask8)
}; };
_mm_storeu_si128( (v128u16 *)(mosaicColorBG + x) + 0, _mm_blendv_epi8(mosaicColor16[0], _mm_loadu_si128((v128u16 *)(mosaicColorBG + x) + 0), mosaicSetColorMask16[0]) ); _mm_store_si128( (v128u16 *)(mosaicColorBG + x) + 0, _mm_blendv_epi8(mosaicColor16[0], _mm_load_si128((v128u16 *)(mosaicColorBG + x) + 0), mosaicSetColorMask16[0]) );
_mm_storeu_si128( (v128u16 *)(mosaicColorBG + x) + 1, _mm_blendv_epi8(mosaicColor16[1], _mm_loadu_si128((v128u16 *)(mosaicColorBG + x) + 1), mosaicSetColorMask16[1]) ); _mm_store_si128( (v128u16 *)(mosaicColorBG + x) + 1, _mm_blendv_epi8(mosaicColor16[1], _mm_load_si128((v128u16 *)(mosaicColorBG + x) + 1), mosaicSetColorMask16[1]) );
} }
const v128u16 outColor16[2] = { const v128u16 outColor16[2] = {
@ -2287,7 +2682,7 @@ void GPUEngineBase::_MosaicLine(GPUEngineCompositorInfo &compInfo)
} }
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST>
void GPUEngineBase::_CompositeNativeLineOBJ_LoopOp(GPUEngineCompositorInfo &compInfo, const u16 *__restrict srcColorNative16, const FragmentColor *__restrict srcColorNative32) void GPUEngineBase::_CompositeNativeLineOBJ_LoopOp(GPUEngineCompositorInfo &compInfo, const u16 *__restrict srcColorNative16, const Color4u8 *__restrict srcColorNative32)
{ {
static const size_t step = sizeof(v128u8); static const size_t step = sizeof(v128u8);
@ -2530,10 +2925,10 @@ size_t GPUEngineBase::_CompositeVRAMLineDeferred_LoopOp(GPUEngineCompositorInfo
case NDSColorFormat_BGR888_Rev: case NDSColorFormat_BGR888_Rev:
{ {
const v128u32 src32[4] = { const v128u32 src32[4] = {
_mm_load_si128((v128u32 *)((FragmentColor *)vramColorPtr + i) + 0), _mm_load_si128((v128u32 *)((Color4u8 *)vramColorPtr + i) + 0),
_mm_load_si128((v128u32 *)((FragmentColor *)vramColorPtr + i) + 1), _mm_load_si128((v128u32 *)((Color4u8 *)vramColorPtr + i) + 1),
_mm_load_si128((v128u32 *)((FragmentColor *)vramColorPtr + i) + 2), _mm_load_si128((v128u32 *)((Color4u8 *)vramColorPtr + i) + 2),
_mm_load_si128((v128u32 *)((FragmentColor *)vramColorPtr + i) + 3) _mm_load_si128((v128u32 *)((Color4u8 *)vramColorPtr + i) + 3)
}; };
if (LAYERTYPE != GPULayerType_OBJ) if (LAYERTYPE != GPULayerType_OBJ)
@ -2688,7 +3083,7 @@ void GPUEngineBase::_PerformWindowTestingNative(GPUEngineCompositorInfo &compInf
} }
template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST> template <GPUCompositorMode COMPOSITORMODE, NDSColorFormat OUTPUTFORMAT, bool WILLPERFORMWINDOWTEST>
size_t GPUEngineA::_RenderLine_Layer3D_LoopOp(GPUEngineCompositorInfo &compInfo, const u8 *__restrict windowTestPtr, const u8 *__restrict colorEffectEnablePtr, const FragmentColor *__restrict srcLinePtr) size_t GPUEngineA::_RenderLine_Layer3D_LoopOp(GPUEngineCompositorInfo &compInfo, const u8 *__restrict windowTestPtr, const u8 *__restrict colorEffectEnablePtr, const Color4u8 *__restrict srcLinePtr)
{ {
static const size_t step = sizeof(v128u8); static const size_t step = sizeof(v128u8);

View File

@ -1,7 +1,7 @@
/* /*
Copyright (C) 2006 yopyop Copyright (C) 2006 yopyop
Copyright (C) 2007 shash Copyright (C) 2007 shash
Copyright (C) 2007-2022 DeSmuME team Copyright (C) 2007-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -1068,7 +1068,6 @@ static void execsqrt() {
} }
static void execdiv() { static void execdiv() {
s64 num,den; s64 num,den;
s64 res,mod; s64 res,mod;
u8 mode = MMU_new.div.mode; u8 mode = MMU_new.div.mode;
@ -1096,15 +1095,29 @@ static void execdiv() {
break; break;
} }
if(den==0) if(den == 0)
{ {
res = ((num < 0) ? 1 : -1); res = ((num < 0) ? 1 : -1);
mod = num; mod = num;
// when the result is 32bits, the upper 32bits of the sign-extended result are inverted
if (mode == 0)
res ^= 0xFFFFFFFF00000000LL;
// the DIV0 flag in DIVCNT is set only if the full 64bit DIV_DENOM value is zero, even in 32bit mode // the DIV0 flag in DIVCNT is set only if the full 64bit DIV_DENOM value is zero, even in 32bit mode
if ((u64)T1ReadQuad(MMU.ARM9_REG, 0x298) == 0) if ((u64)T1ReadQuad(MMU.ARM9_REG, 0x298) == 0)
MMU_new.div.div0 = 1; MMU_new.div.div0 = 1;
} }
else if((mode != 0) && (num == 0x8000000000000000LL) && (den == -1))
{
res = 0x8000000000000000LL;
mod = 0;
}
else if((mode == 0) && (num == (s64) (s32) 0x80000000) && (den == -1))
{
res = 0x80000000;
mod = 0;
}
else else
{ {
res = num / den; res = num / den;
@ -1280,7 +1293,7 @@ void GC_Command::fromCryptoBuffer(u32 buf[2])
} }
template<int PROCNUM> template<int PROCNUM>
void FASTCALL MMU_writeToGCControl(u32 val) void DESMUME_FASTCALL MMU_writeToGCControl(u32 val)
{ {
int dbsize = (val>>24)&7; int dbsize = (val>>24)&7;
@ -1361,7 +1374,7 @@ void FASTCALL MMU_writeToGCControl(u32 val)
} }
/*template<int PROCNUM> /*template<int PROCNUM>
u32 FASTCALL MMU_readFromGCControl() u32 DESMUME_FASTCALL MMU_readFromGCControl()
{ {
return T1ReadLong(MMU.MMU_MEM[0][0x40], 0x1A4); return T1ReadLong(MMU.MMU_MEM[0][0x40], 0x1A4);
}*/ }*/
@ -1439,16 +1452,16 @@ static void CalculateTouchPressure(int pressurePercent, u16 &z1, u16& z2)
} }
void FASTCALL MMU_writeToSPIData(u16 val) void DESMUME_FASTCALL MMU_writeToSPIData(u16 val)
{ {
enum PM_Bits //from libnds enum PM_Bits //from libnds
{ {
PM_SOUND_AMP = BIT(0) , /*!< \brief Power the sound hardware (needed to hear stuff in GBA mode too) */ PM_SOUND_AMP = BIT(0), /*!< \brief Power the sound hardware (needed to hear stuff in GBA mode too) */
PM_SOUND_MUTE = BIT(1), /*!< \brief Mute the main speakers, headphone output will still work. */ PM_SOUND_MUTE = BIT(1), /*!< \brief Mute the main speakers, headphone output will still work. */
PM_BACKLIGHT_BOTTOM = BIT(2), /*!< \brief Enable the top backlight if set */ PM_BACKLIGHT_BOTTOM = BIT(2), /*!< \brief Enable the top backlight if set */
PM_BACKLIGHT_TOP = BIT(3) , /*!< \brief Enable the bottom backlight if set */ PM_BACKLIGHT_TOP = BIT(3), /*!< \brief Enable the bottom backlight if set */
PM_SYSTEM_PWR = BIT(6) , /*!< \brief Turn the power *off* if set */ PM_SYSTEM_PWR = BIT(6) /*!< \brief Turn the power *off* if set */
}; };
if (val !=0) if (val !=0)
@ -1816,44 +1829,46 @@ static void writereg_POWCNT1(const int size, const u32 adr, const u32 val)
bool isGeomEnabled = !!nds.power1.gfx3d_geometry; bool isGeomEnabled = !!nds.power1.gfx3d_geometry;
if(wasGeomEnabled && !isGeomEnabled) if(wasGeomEnabled && !isGeomEnabled)
{ {
//kill the geometry data when the power goes off GFX3D_HandleGeometryPowerOff();
//but save these tables, first. they shouldnt be cleared.
//so, so bad. we need to model this with hardware-like operations instead of c++ code
GFX3D_State prior = gfx3d.state;
reconstruct(&gfx3d.state);
memcpy(gfx3d.state.u16ToonTable, prior.u16ToonTable, sizeof(prior.u16ToonTable));
//dont think we should save this one: it's sent with 3d commands, not random bonus immediate register writes like the toon table
//memcpy(gfx3d.state.shininessTable, prior.shininessTable, sizeof(prior.shininessTable));
} }
} }
static INLINE void MMU_IPCSync(u8 proc, u32 val) static INLINE void MMU_IPCSync(u8 proc, u32 val)
{ {
//INFO("IPC%s sync 0x%04X (0x%02X|%02X)\n", proc?"7":"9", val, val >> 8, val & 0xFF);
u32 sync_l = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x180) & 0xFFFF; u32 sync_l = T1ReadLong(MMU.MMU_MEM[proc][0x40], 0x180) & 0xFFFF;
u32 sync_r = T1ReadLong(MMU.MMU_MEM[proc^1][0x40], 0x180) & 0xFFFF; u32 sync_r = T1ReadLong(MMU.MMU_MEM[proc^1][0x40], 0x180) & 0xFFFF;
u32 iter = (val & 0x0F00) >> 8;
sync_l = ( sync_l & 0x000F ) | ( val & 0x0F00 ); sync_l = ( sync_l & 0x000F ) | ( val & 0x6F00 );
sync_r = ( sync_r & 0x6F00 ) | ( (val >> 8) & 0x000F ); sync_r = ( sync_r & 0x6F00 ) | ( iter );
sync_l |= val & 0x6000; // For some reason, the arm9 doesn't handshake when ensata is detected.
// So we complete the protocol here, which is to mirror the values 8..0 back to
// The arm7 as they are written by the arm7
if (nds.ensataEmulation) {
if(nds.ensataEmulation && proc==1 && nds.ensataIpcSyncCounter<9) { if (proc) {
u32 iteration = (val&0x0F00)>>8; // However this hack would break soft reset because it also syncs through ipcsync.
// So we have to add some additional checks to ensure that it's handshake instead of reset.
if(iteration==8-nds.ensataIpcSyncCounter) if ((iter & 8) || (nds.ensataIpcSyncCounter)) {
nds.ensataIpcSyncCounter++; // sync_r = (sync_r & 0xF0FF) | (iter << 8); // This is not necessary.
else printf("ERROR: ENSATA IPC SYNC HACK FAILED; BAD THINGS MAY HAPPEN\n"); sync_l = (sync_l & 0xFFF0) | iter;
nds.ensataIpcSyncCounter = iter;
//for some reason, the arm9 doesn't handshake when ensata is detected. }
//so we complete the protocol here, which is to mirror the values 8..0 back to }
//the arm7 as they are written by the arm7 else {
sync_r &= 0xF0FF; // After ensata handshake, arm9 will write 0x100 as a signal if Ensata is detected.
sync_r |= (iteration<<8); // This will prevent reset from working, so we have to ignore this.
sync_l &= 0xFFF0; if (nds.ensataHandshake == ENSATA_HANDSHAKE_complete) {
sync_l |= iteration; nds.ensataHandshake = ENSATA_HANDSHAKE_none;
return;
}
}
} }
// printf("IPCSync(%d, %04x): %04x %04x %d\n", proc, val, sync_l, sync_r, nds.ensataIpcSyncCounter);
T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x180, sync_l); T1WriteLong(MMU.MMU_MEM[proc][0x40], 0x180, sync_l);
T1WriteLong(MMU.MMU_MEM[proc^1][0x40], 0x180, sync_r); T1WriteLong(MMU.MMU_MEM[proc^1][0x40], 0x180, sync_r);
@ -1947,8 +1962,8 @@ u32 TGXSTAT::read32()
// stack position always equal zero. possible timings is wrong // stack position always equal zero. possible timings is wrong
// using in "The Wild West" // using in "The Wild West"
int proj_level = mtxStackIndex[MATRIXMODE_PROJECTION] & 1; u32 proj_level = (u32)GFX3D_GetMatrixStackIndex(MATRIXMODE_PROJECTION);
int mv_level = mtxStackIndex[MATRIXMODE_POSITION] & 31; u32 mv_level = (u32)GFX3D_GetMatrixStackIndex(MATRIXMODE_POSITION);
ret |= ((proj_level << 13) | (mv_level << 8)); ret |= ((proj_level << 13) | (mv_level << 8));
ret |= sb<<14; //stack busy ret |= sb<<14; //stack busy
@ -1959,7 +1974,7 @@ u32 TGXSTAT::read32()
if(gxFIFO.size==0) ret |= BIT(26); //fifo empty if(gxFIFO.size==0) ret |= BIT(26); //fifo empty
//determine busy flag. //determine busy flag.
//if we're waiting for a flush, we're busy //if we're waiting for a flush, we're busy
if(isSwapBuffers) ret |= BIT(27); if(GFX3D_IsSwapBuffersPending()) ret |= BIT(27);
//if fifo is nonempty, we're busy //if fifo is nonempty, we're busy
if(gxFIFO.size!=0) ret |= BIT(27); if(gxFIFO.size!=0) ret |= BIT(27);
@ -1968,7 +1983,7 @@ u32 TGXSTAT::read32()
ret |= ((gxfifo_irq & 0x3) << 30); //user's irq flags ret |= ((gxfifo_irq & 0x3) << 30); //user's irq flags
//printf("vc=%03d Returning gxstat read: %08X (isSwapBuffers=%d)\n",nds.VCount,ret,isSwapBuffers); //printf("vc=%03d Returning gxstat read: %08X (isSwapBuffers=%d)\n", nds.VCount, ret, (GFX3D_IsSwapBuffersPending()) ? 1 : 0);
//ret = (2 << 8); //ret = (2 << 8);
//INFO("gxSTAT 0x%08X (proj %i, pos %i)\n", ret, _hack_getMatrixStackLevel(1), _hack_getMatrixStackLevel(2)); //INFO("gxSTAT 0x%08X (proj %i, pos %i)\n", ret, _hack_getMatrixStackLevel(1), _hack_getMatrixStackLevel(2));
@ -1983,7 +1998,7 @@ void TGXSTAT::write32(const u32 val)
// Writing "1" to Bit15 does reset the Error Flag (Bit15), // Writing "1" to Bit15 does reset the Error Flag (Bit15),
// and additionally resets the Projection Stack Pointer (Bit13) // and additionally resets the Projection Stack Pointer (Bit13)
// (and probably (?) also the Texture Stack Pointer)?? // (and probably (?) also the Texture Stack Pointer)??
mtxStackIndex[MATRIXMODE_PROJECTION] = 0; GFX3D_ResetMatrixStackPointer();
se = 0; //clear stack error flag se = 0; //clear stack error flag
} }
//printf("gxstat write: %08X while gxfifo.size=%d\n",val,gxFIFO.size); //printf("gxstat write: %08X while gxfifo.size=%d\n",val,gxFIFO.size);
@ -2462,7 +2477,17 @@ bool validateIORegsWrite(u32 addr, u8 size, u32 val)
{ {
if (PROCNUM == ARMCPU_ARM9) if (PROCNUM == ARMCPU_ARM9)
{ {
switch (addr & 0x0FFFFFFC) u32 addrMasked = addr & 0x0FFFFFFC;
if(nds.ensataEmulation)
{
if(addrMasked == eng_3D_CLIPMTX_RESULT) return true;
if(addrMasked == 0x04FFF000) return true;
if(addrMasked == 0x04FFF010) return true;
if(addrMasked == 0x04FFF200) return true;
}
switch (addrMasked)
{ {
// Display Engine A // Display Engine A
case REG_DISPA_DISPCNT: case REG_DISPA_DISPCNT:
@ -3210,11 +3235,104 @@ bool validateIORegsRead(u32 addr, u8 size)
#define VALIDATE_IO_REGS_READ(PROC, SIZE) ; #define VALIDATE_IO_REGS_READ(PROC, SIZE) ;
#endif #endif
template <typename T, size_t LENGTH>
bool MMU_WriteFromExternal(const int targetProc, const u32 targetAddress, T newValue)
{
u32 oldValue32;
switch (LENGTH)
{
case 1:
if (sizeof(T) > LENGTH)
newValue &= 0x000000FF;
break;
case 2:
if (sizeof(T) > LENGTH)
newValue &= 0x0000FFFF;
break;
case 3:
oldValue32 = _MMU_read32(targetProc, MMU_AT_DEBUG, targetAddress);
if (sizeof(T) > LENGTH)
newValue = (oldValue32 & 0xFF000000) | (newValue & 0x00FFFFFF);
break;
case 4:
oldValue32 = _MMU_read32(targetProc, MMU_AT_DEBUG, targetAddress);
if (sizeof(T) > LENGTH)
newValue &= 0xFFFFFFFF;
break;
default:
break;
}
bool needsJitReset = ( (targetAddress >= 0x02000000) && (targetAddress < 0x02400000) );
if (needsJitReset)
{
bool willValueChange = false;
switch (LENGTH)
{
case 1:
willValueChange = (_MMU_read08(targetProc, MMU_AT_DEBUG, targetAddress) != (u8)newValue);
break;
case 2:
willValueChange = (_MMU_read16(targetProc, MMU_AT_DEBUG, targetAddress) != (u16)newValue);
break;
case 3:
case 4:
willValueChange = (oldValue32 != (u32)newValue);
break;
default:
break;
}
if (!willValueChange)
{
needsJitReset = false;
return needsJitReset;
}
}
switch (LENGTH)
{
case 1:
_MMU_write08(targetProc, MMU_AT_DEBUG, targetAddress, (u8)newValue);
break;
case 2:
_MMU_write16(targetProc, MMU_AT_DEBUG, targetAddress, (u16)newValue);
break;
case 3:
case 4:
_MMU_write32(targetProc, MMU_AT_DEBUG, targetAddress, (u32)newValue);
break;
default:
break;
}
return needsJitReset;
}
template bool MMU_WriteFromExternal< u8, 1>(const int targetProc, const u32 targetAddress, u8 newValue);
template bool MMU_WriteFromExternal<u16, 2>(const int targetProc, const u32 targetAddress, u16 newValue);
template bool MMU_WriteFromExternal<u32, 1>(const int targetProc, const u32 targetAddress, u32 newValue);
template bool MMU_WriteFromExternal<u32, 2>(const int targetProc, const u32 targetAddress, u32 newValue);
template bool MMU_WriteFromExternal<u32, 3>(const int targetProc, const u32 targetAddress, u32 newValue);
template bool MMU_WriteFromExternal<u32, 4>(const int targetProc, const u32 targetAddress, u32 newValue);
//================================================================================================== ARM9 * //================================================================================================== ARM9 *
//========================================================================================================= //=========================================================================================================
//========================================================================================================= //=========================================================================================================
//================================================= MMU write 08 //================================================= MMU write 08
void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val) void DESMUME_FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
{ {
adr &= 0x0FFFFFFF; adr &= 0x0FFFFFFF;
const u32 adrBank = (adr >> 24); const u32 adrBank = (adr >> 24);
@ -3258,6 +3376,28 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
return; return;
} }
switch (adr >> 4)
{
case 0x400033: // Edge Mark Color Table
MMU.ARM9_REG[adr & 0xFFF] = val;
gfx3d_UpdateEdgeMarkColorTable<u8>((u8)(adr & 0x0000000F), val);
return;
case 0x400036:
case 0x400037: // Fog Table
MMU.ARM9_REG[adr & 0xFFF] = val & 0x7F;
gfx3d_UpdateFogTable<u8>((u8)(adr & 0x0000001F), val & 0x7F); // Drop the highest bit of each 8-bit value to limit the range to [0...127]
return;
case 0x400038:
case 0x400039:
case 0x40003A:
case 0x40003B: // Toon Table
MMU.ARM9_REG[adr & 0xFFF] = val;
gfx3d_UpdateToonTable<u8>((u8)(adr & 0x0000003F), val);
return;
}
GPUEngineA *mainEngine = GPU->GetEngineMain(); GPUEngineA *mainEngine = GPU->GetEngineMain();
GPUEngineB *subEngine = GPU->GetEngineSub(); GPUEngineB *subEngine = GPU->GetEngineSub();
@ -3425,7 +3565,19 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
return; return;
case REG_DISPA_DISPMMEMFIFO: case REG_DISPA_DISPMMEMFIFO:
DISP_FIFOsend_u32(val); DISP_FIFOsend<u8, 0>(val);
return;
case REG_DISPA_DISPMMEMFIFO+1:
DISP_FIFOsend<u8, 1>(val);
return;
case REG_DISPA_DISPMMEMFIFO+2:
DISP_FIFOsend<u8, 2>(val);
return;
case REG_DISPA_DISPMMEMFIFO+3:
DISP_FIFOsend<u8, 3>(val);
return; return;
case REG_DISPB_BG0HOFS: case REG_DISPB_BG0HOFS:
@ -3590,18 +3742,6 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
case REG_DIVCNT+3: printf("ERROR 8bit DIVCNT+3 WRITE\n"); return; case REG_DIVCNT+3: printf("ERROR 8bit DIVCNT+3 WRITE\n"); return;
#endif #endif
//fog table: only write bottom 7 bits
case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x01: case eng_3D_FOG_TABLE+0x02: case eng_3D_FOG_TABLE+0x03:
case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x05: case eng_3D_FOG_TABLE+0x06: case eng_3D_FOG_TABLE+0x07:
case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x09: case eng_3D_FOG_TABLE+0x0A: case eng_3D_FOG_TABLE+0x0B:
case eng_3D_FOG_TABLE+0x0C: case eng_3D_FOG_TABLE+0x0D: case eng_3D_FOG_TABLE+0x0E: case eng_3D_FOG_TABLE+0x0F:
case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x11: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x13:
case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x15: case eng_3D_FOG_TABLE+0x16: case eng_3D_FOG_TABLE+0x17:
case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x19: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1B:
case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1D: case eng_3D_FOG_TABLE+0x1E: case eng_3D_FOG_TABLE+0x1F:
val &= 0x7F;
break;
//ensata putchar port //ensata putchar port
case 0x04FFF000: case 0x04FFF000:
if(nds.ensataEmulation) if(nds.ensataEmulation)
@ -3614,7 +3754,21 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
case eng_3D_GXSTAT: case eng_3D_GXSTAT:
MMU_new.gxstat.write(8,adr,val); MMU_new.gxstat.write(8,adr,val);
break; break;
case REG_IPCSYNC:
{
u16 ipcsync = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x180);
ipcsync &= 0xFF00;
ipcsync |= (val & 0xFF);
MMU_IPCSync(ARMCPU_ARM9, ipcsync);
}
case REG_IPCSYNC+1:
{
u16 ipcsync = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x180);
ipcsync &= 0x00FF;
ipcsync |= ((val & 0xFF) << 8);
MMU_IPCSync(ARMCPU_ARM9, ipcsync);
}
case REG_AUXSPICNT: case REG_AUXSPICNT:
case REG_AUXSPICNT+1: case REG_AUXSPICNT+1:
write_auxspicnt(ARMCPU_ARM9, 8, adr & 1, val); write_auxspicnt(ARMCPU_ARM9, 8, adr & 1, val);
@ -3636,10 +3790,45 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
case REG_IF+2: REG_IF_WriteByte<ARMCPU_ARM9>(2,val); break; case REG_IF+2: REG_IF_WriteByte<ARMCPU_ARM9>(2,val); break;
case REG_IF+3: REG_IF_WriteByte<ARMCPU_ARM9>(3,val); break; case REG_IF+3: REG_IF_WriteByte<ARMCPU_ARM9>(3,val); break;
case eng_3D_CLEAR_COLOR+0: case eng_3D_CLEAR_COLOR+1: case eng_3D_CLEAR_COLOR:
case eng_3D_CLEAR_COLOR+2: case eng_3D_CLEAR_COLOR+3: T1WriteByte(MMU.ARM9_REG, 0x0350, val);
T1WriteByte((u8*)&gfx3d.state.clearColor,adr-eng_3D_CLEAR_COLOR,val); gfx3d_glClearColor<u8>(0, val);
break; return;
case eng_3D_CLEAR_COLOR+1:
T1WriteByte(MMU.ARM9_REG, 0x0351, val);
gfx3d_glClearColor<u8>(1, val);
return;
case eng_3D_CLEAR_COLOR+2:
T1WriteByte(MMU.ARM9_REG, 0x0352, val);
gfx3d_glClearColor<u8>(2, val);
return;
case eng_3D_CLEAR_COLOR+3:
T1WriteByte(MMU.ARM9_REG, 0x0353, val);
gfx3d_glClearColor<u8>(3, val);
return;
case eng_3D_CLEAR_DEPTH:
HostWriteByte(MMU.ARM9_REG, 0x0354, val);
gfx3d_glClearDepth<u8, 0>(val);
return;
case eng_3D_CLEAR_DEPTH+1:
HostWriteByte(MMU.ARM9_REG, 0x0355, val);
gfx3d_glClearDepth<u8, 1>(val);
return;
case eng_3D_CLRIMAGE_OFFSET:
HostWriteByte(MMU.ARM9_REG, 0x0356, val);
gfx3d_glClearImageOffset<u8, 0>(val);
return;
case eng_3D_CLRIMAGE_OFFSET+1:
HostWriteByte(MMU.ARM9_REG, 0x0357, val);
gfx3d_glClearImageOffset<u8, 1>(val);
return;
case REG_VRAMCNTA: case REG_VRAMCNTA:
case REG_VRAMCNTB: case REG_VRAMCNTB:
@ -3653,6 +3842,11 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
case REG_VRAMCNTI: case REG_VRAMCNTI:
MMU_VRAMmapControl(adr-REG_VRAMCNTA, val); MMU_VRAMmapControl(adr-REG_VRAMCNTA, val);
break; break;
// ensata sound register
case 0x04FFF200:
break;
#ifdef LOG_CARD #ifdef LOG_CARD
case 0x040001A0 : /* TODO (clear): ??? */ case 0x040001A0 : /* TODO (clear): ??? */
@ -3694,7 +3888,7 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
} }
//================================================= MMU ARM9 write 16 //================================================= MMU ARM9 write 16
void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) void DESMUME_FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
{ {
adr &= 0x0FFFFFFE; adr &= 0x0FFFFFFE;
const u32 adrBank = (adr >> 24); const u32 adrBank = (adr >> 24);
@ -3736,13 +3930,23 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
switch (adr >> 4) switch (adr >> 4)
{ {
//toon table case 0x400033: // Edge Mark Color Table
case 0x0400038: ((u16 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> (sizeof(u16) >> 1)] = val;
case 0x0400039: gfx3d_UpdateEdgeMarkColorTable<u16>((u8)(adr & 0x0000000F), val);
case 0x040003A: return;
case 0x040003B:
((u16 *)(MMU.ARM9_REG))[(adr & 0xFFF)>>1] = val; case 0x400036:
gfx3d_UpdateToonTable((adr & 0x3F) >> 1, val); case 0x400037: // Fog Table
((u16 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> (sizeof(u16) >> 1)] = val & 0x7F7F;
gfx3d_UpdateFogTable<u16>((u8)(adr & 0x0000001F), val & 0x7F7F); // Drop the highest bit of each 8-bit value to limit the range to [0...127]
return;
case 0x400038:
case 0x400039:
case 0x40003A:
case 0x40003B: // Toon Table
((u16 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> (sizeof(u16) >> 1)] = val;
gfx3d_UpdateToonTable<u16>((u8)(adr & 0x0000003F), val);
return; return;
} }
@ -3992,7 +4196,11 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
return; return;
case REG_DISPA_DISPMMEMFIFO: case REG_DISPA_DISPMMEMFIFO:
DISP_FIFOsend_u32(val); DISP_FIFOsend<u16, 0>(val);
return;
case REG_DISPA_DISPMMEMFIFO+2:
DISP_FIFOsend<u16, 2>(val);
return; return;
case REG_DISPA_MASTERBRIGHT: case REG_DISPA_MASTERBRIGHT:
@ -4233,14 +4441,6 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
MMU_new.gxstat.write(16,adr,val); MMU_new.gxstat.write(16,adr,val);
break; break;
//fog table: only write bottom 7 bits
case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x02: case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x06:
case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x0A: case eng_3D_FOG_TABLE+0x0C: case eng_3D_FOG_TABLE+0x0E:
case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x16:
case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1E:
val &= 0x7F7F;
break;
// Alpha test reference value - Parameters:1 // Alpha test reference value - Parameters:1
case eng_3D_ALPHA_TEST_REF: case eng_3D_ALPHA_TEST_REF:
HostWriteWord(MMU.ARM9_REG, 0x0340, val); HostWriteWord(MMU.ARM9_REG, 0x0340, val);
@ -4248,14 +4448,24 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
return; return;
case eng_3D_CLEAR_COLOR: case eng_3D_CLEAR_COLOR:
T1WriteWord(MMU.ARM9_REG, 0x0350, val);
gfx3d_glClearColor<u16>(0, val);
return;
case eng_3D_CLEAR_COLOR+2: case eng_3D_CLEAR_COLOR+2:
T1WriteWord((u8*)&gfx3d.state.clearColor,adr-eng_3D_CLEAR_COLOR,val); T1WriteWord(MMU.ARM9_REG, 0x0352, val);
break; gfx3d_glClearColor<u16>(2, val);
return;
// Clear background depth setup - Parameters:2 // Clear background depth setup - Parameters:2
case eng_3D_CLEAR_DEPTH: case eng_3D_CLEAR_DEPTH:
HostWriteWord(MMU.ARM9_REG, 0x0354, val); HostWriteWord(MMU.ARM9_REG, 0x0354, val);
gfx3d_glClearDepth(val); gfx3d_glClearDepth<u16, 0>(val);
return;
case eng_3D_CLRIMAGE_OFFSET:
HostWriteWord(MMU.ARM9_REG, 0x0356, val);
gfx3d_glClearImageOffset<u16, 0>(val);
return; return;
// Fog Color - Parameters:4b // Fog Color - Parameters:4b
@ -4394,7 +4604,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
} }
//================================================= MMU ARM9 write 32 //================================================= MMU ARM9 write 32
void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) void DESMUME_FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
{ {
adr &= 0x0FFFFFFC; adr &= 0x0FFFFFFC;
const u32 adrBank = (adr >> 24); const u32 adrBank = (adr >> 24);
@ -4448,16 +4658,23 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
// lookups by the compiler // lookups by the compiler
switch (adr >> 4) switch (adr >> 4)
{ {
case 0x400033: //edge color table case 0x400033: // Edge Mark Color Table
((u32 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> 2] = val; ((u32 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> (sizeof(u32) >> 1)] = val;
gfx3d_UpdateEdgeMarkColorTable<u32>((u8)(adr & 0x0000000F), val);
return;
case 0x400036:
case 0x400037: // Fog Table
((u32 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> (sizeof(u32) >> 1)] = val & 0x7F7F7F7F;
gfx3d_UpdateFogTable<u32>((u8)(adr & 0x0000001F), val & 0x7F7F7F7F); // Drop the highest bit of each 8-bit value to limit the range to [0...127]
return; return;
case 0x400038: case 0x400038:
case 0x400039: case 0x400039:
case 0x40003A: case 0x40003A:
case 0x40003B: //toon table case 0x40003B: // Toon Table
((u32 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> 2] = val; ((u32 *)(MMU.ARM9_REG))[(adr & 0xFFF) >> (sizeof(u32) >> 1)] = val;
gfx3d_UpdateToonTable((adr & 0x3F) >> 1, val); gfx3d_UpdateToonTable<u32>((u8)(adr & 0x0000003F), val);
return; return;
case 0x400040: case 0x400040:
@ -4635,7 +4852,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
return; return;
case REG_DISPA_DISPMMEMFIFO: case REG_DISPA_DISPMMEMFIFO:
DISP_FIFOsend_u32(val); DISP_FIFOsend<u32, 0>(val);
return; return;
case REG_DISPA_MASTERBRIGHT: case REG_DISPA_MASTERBRIGHT:
@ -4761,12 +4978,6 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
case REG_POWCNT1: writereg_POWCNT1(32,adr,val); break; case REG_POWCNT1: writereg_POWCNT1(32,adr,val); break;
//fog table: only write bottom 7 bits
case eng_3D_FOG_TABLE+0x00: case eng_3D_FOG_TABLE+0x04: case eng_3D_FOG_TABLE+0x08: case eng_3D_FOG_TABLE+0x0C:
case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1C:
val &= 0x7F7F7F7F;
break;
//ensata handshaking port? //ensata handshaking port?
case 0x04FFF010: case 0x04FFF010:
if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_ack && val == 0x13579bdf) if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_ack && val == 0x13579bdf)
@ -4781,7 +4992,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
//todo - these are usually write only regs (these and 1000 more) //todo - these are usually write only regs (these and 1000 more)
//shouldnt we block them from getting written? ugh //shouldnt we block them from getting written? ugh
case eng_3D_CLIPMTX_RESULT: case eng_3D_CLIPMTX_RESULT:
if(nds.ensataEmulation && nds.ensataHandshake == ENSATA_HANDSHAKE_none && val==0x2468ace0) if(nds.ensataEmulation /* && nds.ensataHandshake == ENSATA_HANDSHAKE_none */&& val==0x2468ace0)
{ {
printf("ENSATA HANDSHAKE BEGIN\n"); printf("ENSATA HANDSHAKE BEGIN\n");
nds.ensataHandshake = ENSATA_HANDSHAKE_query; nds.ensataHandshake = ENSATA_HANDSHAKE_query;
@ -4799,13 +5010,15 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
return; return;
case eng_3D_CLEAR_COLOR: case eng_3D_CLEAR_COLOR:
T1WriteLong((u8*)&gfx3d.state.clearColor,0,val); T1WriteLong(MMU.ARM9_REG, 0x0350, val);
break; gfx3d_glClearColor<u32>(0, val);
return;
// Clear background depth setup - Parameters:2 // Clear background depth setup - Parameters:2
case eng_3D_CLEAR_DEPTH: case eng_3D_CLEAR_DEPTH:
HostWriteLong(MMU.ARM9_REG, 0x0354, val); HostWriteLong(MMU.ARM9_REG, 0x0354, val);
gfx3d_glClearDepth(val); gfx3d_glClearDepth<u16, 0>((u16)(val & 0x0000FFFF));
gfx3d_glClearImageOffset<u16, 0>((u16)(val >> 16));
return; return;
// Fog Color - Parameters:4b // Fog Color - Parameters:4b
@ -4934,7 +5147,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
} }
//================================================= MMU ARM9 read 08 //================================================= MMU ARM9 read 08
u8 FASTCALL _MMU_ARM9_read08(u32 adr) u8 DESMUME_FASTCALL _MMU_ARM9_read08(u32 adr)
{ {
adr &= 0x0FFFFFFF; adr &= 0x0FFFFFFF;
@ -5057,7 +5270,7 @@ u8 FASTCALL _MMU_ARM9_read08(u32 adr)
} }
//================================================= MMU ARM9 read 16 //================================================= MMU ARM9 read 16
u16 FASTCALL _MMU_ARM9_read16(u32 adr) u16 DESMUME_FASTCALL _MMU_ARM9_read16(u32 adr)
{ {
adr &= 0x0FFFFFFE; adr &= 0x0FFFFFFE;
@ -5167,7 +5380,7 @@ u16 FASTCALL _MMU_ARM9_read16(u32 adr)
} }
//================================================= MMU ARM9 read 32 //================================================= MMU ARM9 read 32
u32 FASTCALL _MMU_ARM9_read32(u32 adr) u32 DESMUME_FASTCALL _MMU_ARM9_read32(u32 adr)
{ {
adr &= 0x0FFFFFFC; adr &= 0x0FFFFFFC;
@ -5298,6 +5511,10 @@ u32 FASTCALL _MMU_ARM9_read32(u32 adr)
case REG_KEYINPUT: case REG_KEYINPUT:
LagFrameFlag=0; LagFrameFlag=0;
break; break;
// Ensata sound register
case 0x04FFF200:
return 1;
} }
return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]); return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]);
} }
@ -5313,7 +5530,7 @@ u32 FASTCALL _MMU_ARM9_read32(u32 adr)
//========================================================================================================= //=========================================================================================================
//========================================================================================================= //=========================================================================================================
//================================================= MMU ARM7 write 08 //================================================= MMU ARM7 write 08
void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val) void DESMUME_FASTCALL _MMU_ARM7_write08(u32 adr, u8 val)
{ {
adr &= 0x0FFFFFFF; adr &= 0x0FFFFFFF;
@ -5393,6 +5610,21 @@ void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val)
printf("Unsupported 8bit write to timer registers"); printf("Unsupported 8bit write to timer registers");
return; return;
case REG_IPCSYNC:
{
u16 ipcsync = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x180);
ipcsync &= 0xFF00;
ipcsync |= (val & 0xFF);
MMU_IPCSync(ARMCPU_ARM7, ipcsync);
}
case REG_IPCSYNC+1:
{
u16 ipcsync = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x180);
ipcsync &= 0x00FF;
ipcsync |= ((val & 0xFF) << 8);
MMU_IPCSync(ARMCPU_ARM7, ipcsync);
}
case REG_AUXSPIDATA: case REG_AUXSPIDATA:
{ {
//if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF; //zero 20-aug-2013 - this seems pointless //if(val!=0) MMU.AUX_SPI_CMD = val & 0xFF; //zero 20-aug-2013 - this seems pointless
@ -5426,7 +5658,7 @@ void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val)
} }
//================================================= MMU ARM7 write 16 //================================================= MMU ARM7 write 16
void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) void DESMUME_FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
{ {
adr &= 0x0FFFFFFE; adr &= 0x0FFFFFFE;
@ -5611,7 +5843,7 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val); T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val);
} }
//================================================= MMU ARM7 write 32 //================================================= MMU ARM7 write 32
void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val) void DESMUME_FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
{ {
adr &= 0x0FFFFFFC; adr &= 0x0FFFFFFC;
@ -5714,7 +5946,7 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
} }
//================================================= MMU ARM7 read 08 //================================================= MMU ARM7 read 08
u8 FASTCALL _MMU_ARM7_read08(u32 adr) u8 DESMUME_FASTCALL _MMU_ARM7_read08(u32 adr)
{ {
adr &= 0x0FFFFFFF; adr &= 0x0FFFFFFF;
@ -5796,7 +6028,7 @@ u8 FASTCALL _MMU_ARM7_read08(u32 adr)
return MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]]; return MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]];
} }
//================================================= MMU ARM7 read 16 //================================================= MMU ARM7 read 16
u16 FASTCALL _MMU_ARM7_read16(u32 adr) u16 DESMUME_FASTCALL _MMU_ARM7_read16(u32 adr)
{ {
adr &= 0x0FFFFFFE; adr &= 0x0FFFFFFE;
@ -5882,7 +6114,7 @@ u16 FASTCALL _MMU_ARM7_read16(u32 adr)
return T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]); return T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]);
} }
//================================================= MMU ARM7 read 32 //================================================= MMU ARM7 read 32
u32 FASTCALL _MMU_ARM7_read32(u32 adr) u32 DESMUME_FASTCALL _MMU_ARM7_read32(u32 adr)
{ {
adr &= 0x0FFFFFFC; adr &= 0x0FFFFFFC;
@ -5966,7 +6198,7 @@ u32 FASTCALL _MMU_ARM7_read32(u32 adr)
//========================================================================================================= //=========================================================================================================
u32 FASTCALL MMU_read32(u32 proc, u32 adr) u32 DESMUME_FASTCALL MMU_read32(u32 proc, u32 adr)
{ {
ASSERT_UNALIGNED((adr&3)==0); ASSERT_UNALIGNED((adr&3)==0);
@ -5976,7 +6208,7 @@ u32 FASTCALL MMU_read32(u32 proc, u32 adr)
return _MMU_ARM7_read32(adr); return _MMU_ARM7_read32(adr);
} }
u16 FASTCALL MMU_read16(u32 proc, u32 adr) u16 DESMUME_FASTCALL MMU_read16(u32 proc, u32 adr)
{ {
ASSERT_UNALIGNED((adr&1)==0); ASSERT_UNALIGNED((adr&1)==0);
@ -5986,7 +6218,7 @@ u16 FASTCALL MMU_read16(u32 proc, u32 adr)
return _MMU_ARM7_read16(adr); return _MMU_ARM7_read16(adr);
} }
u8 FASTCALL MMU_read8(u32 proc, u32 adr) u8 DESMUME_FASTCALL MMU_read8(u32 proc, u32 adr)
{ {
if(proc==0) if(proc==0)
return _MMU_ARM9_read08(adr); return _MMU_ARM9_read08(adr);
@ -5994,7 +6226,7 @@ u8 FASTCALL MMU_read8(u32 proc, u32 adr)
return _MMU_ARM7_read08(adr); return _MMU_ARM7_read08(adr);
} }
void FASTCALL MMU_write32(u32 proc, u32 adr, u32 val) void DESMUME_FASTCALL MMU_write32(u32 proc, u32 adr, u32 val)
{ {
ASSERT_UNALIGNED((adr&3)==0); ASSERT_UNALIGNED((adr&3)==0);
@ -6004,7 +6236,7 @@ void FASTCALL MMU_write32(u32 proc, u32 adr, u32 val)
_MMU_ARM7_write32(adr,val); _MMU_ARM7_write32(adr,val);
} }
void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val) void DESMUME_FASTCALL MMU_write16(u32 proc, u32 adr, u16 val)
{ {
ASSERT_UNALIGNED((adr&1)==0); ASSERT_UNALIGNED((adr&1)==0);
@ -6014,7 +6246,7 @@ void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val)
_MMU_ARM7_write16(adr,val); _MMU_ARM7_write16(adr,val);
} }
void FASTCALL MMU_write8(u32 proc, u32 adr, u8 val) void DESMUME_FASTCALL MMU_write8(u32 proc, u32 adr, u8 val)
{ {
if(proc==0) if(proc==0)
_MMU_ARM9_write08(adr, val); _MMU_ARM9_write08(adr, val);
@ -6022,7 +6254,7 @@ void FASTCALL MMU_write8(u32 proc, u32 adr, u8 val)
_MMU_ARM7_write08(adr,val); _MMU_ARM7_write08(adr,val);
} }
void FASTCALL MMU_DumpMemBlock(u8 proc, u32 address, u32 size, u8 *buffer) void DESMUME_FASTCALL MMU_DumpMemBlock(u8 proc, u32 address, u32 size, u8 *buffer)
{ {
u32 i; u32 i;
u32 curaddr; u32 curaddr;
@ -6041,67 +6273,67 @@ template u32 MMU_struct::gen_IF<ARMCPU_ARM7>();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//function pointer handlers for gdb stub stuff //function pointer handlers for gdb stub stuff
static u16 FASTCALL arm9_prefetch16( void *data, u32 adr) { static u16 DESMUME_FASTCALL arm9_prefetch16( void *data, u32 adr) {
return _MMU_read16<ARMCPU_ARM9,MMU_AT_CODE>(adr); return _MMU_read16<ARMCPU_ARM9,MMU_AT_CODE>(adr);
} }
static u32 FASTCALL arm9_prefetch32( void *data, u32 adr) { static u32 DESMUME_FASTCALL arm9_prefetch32( void *data, u32 adr) {
return _MMU_read32<ARMCPU_ARM9,MMU_AT_CODE>(adr); return _MMU_read32<ARMCPU_ARM9,MMU_AT_CODE>(adr);
} }
static u8 FASTCALL arm9_read8( void *data, u32 adr) { static u8 DESMUME_FASTCALL arm9_read8( void *data, u32 adr) {
return _MMU_read08<ARMCPU_ARM9>(adr); return _MMU_read08<ARMCPU_ARM9>(adr);
} }
static u16 FASTCALL arm9_read16( void *data, u32 adr) { static u16 DESMUME_FASTCALL arm9_read16( void *data, u32 adr) {
return _MMU_read16<ARMCPU_ARM9>(adr); return _MMU_read16<ARMCPU_ARM9>(adr);
} }
static u32 FASTCALL arm9_read32( void *data, u32 adr) { static u32 DESMUME_FASTCALL arm9_read32( void *data, u32 adr) {
return _MMU_read32<ARMCPU_ARM9>(adr); return _MMU_read32<ARMCPU_ARM9>(adr);
} }
static void FASTCALL arm9_write8(void *data, u32 adr, u8 val) { static void DESMUME_FASTCALL arm9_write8(void *data, u32 adr, u8 val) {
_MMU_write08<ARMCPU_ARM9>(adr, val); _MMU_write08<ARMCPU_ARM9>(adr, val);
} }
static void FASTCALL arm9_write16(void *data, u32 adr, u16 val) { static void DESMUME_FASTCALL arm9_write16(void *data, u32 adr, u16 val) {
_MMU_write16<ARMCPU_ARM9>(adr, val); _MMU_write16<ARMCPU_ARM9>(adr, val);
} }
static void FASTCALL arm9_write32(void *data, u32 adr, u32 val) { static void DESMUME_FASTCALL arm9_write32(void *data, u32 adr, u32 val) {
_MMU_write32<ARMCPU_ARM9>(adr, val); _MMU_write32<ARMCPU_ARM9>(adr, val);
} }
static u16 FASTCALL arm7_prefetch16( void *data, u32 adr) { static u16 DESMUME_FASTCALL arm7_prefetch16( void *data, u32 adr) {
return _MMU_read16<ARMCPU_ARM7,MMU_AT_CODE>(adr); return _MMU_read16<ARMCPU_ARM7,MMU_AT_CODE>(adr);
} }
static u32 FASTCALL arm7_prefetch32( void *data, u32 adr) { static u32 DESMUME_FASTCALL arm7_prefetch32( void *data, u32 adr) {
return _MMU_read32<ARMCPU_ARM7,MMU_AT_CODE>(adr); return _MMU_read32<ARMCPU_ARM7,MMU_AT_CODE>(adr);
} }
static u8 FASTCALL arm7_read8( void *data, u32 adr) { static u8 DESMUME_FASTCALL arm7_read8( void *data, u32 adr) {
return _MMU_read08<ARMCPU_ARM7>(adr); return _MMU_read08<ARMCPU_ARM7>(adr);
} }
static u16 FASTCALL arm7_read16( void *data, u32 adr) { static u16 DESMUME_FASTCALL arm7_read16( void *data, u32 adr) {
return _MMU_read16<ARMCPU_ARM7>(adr); return _MMU_read16<ARMCPU_ARM7>(adr);
} }
static u32 FASTCALL arm7_read32( void *data, u32 adr) { static u32 DESMUME_FASTCALL arm7_read32( void *data, u32 adr) {
return _MMU_read32<ARMCPU_ARM7>(adr); return _MMU_read32<ARMCPU_ARM7>(adr);
} }
static void FASTCALL arm7_write8(void *data, u32 adr, u8 val) { static void DESMUME_FASTCALL arm7_write8(void *data, u32 adr, u8 val) {
_MMU_write08<ARMCPU_ARM7>(adr, val); _MMU_write08<ARMCPU_ARM7>(adr, val);
} }
static void FASTCALL arm7_write16(void *data, u32 adr, u16 val) { static void DESMUME_FASTCALL arm7_write16(void *data, u32 adr, u16 val) {
_MMU_write16<ARMCPU_ARM7>(adr, val); _MMU_write16<ARMCPU_ARM7>(adr, val);
} }
static void FASTCALL arm7_write32(void *data, u32 adr, u32 val) { static void DESMUME_FASTCALL arm7_write32(void *data, u32 adr, u32 val) {
_MMU_write32<ARMCPU_ARM7>(adr, val); _MMU_write32<ARMCPU_ARM7>(adr, val);
} }

View File

@ -1,7 +1,7 @@
/* /*
Copyright (C) 2006 yopyop Copyright (C) 2006 yopyop
Copyright (C) 2007 shash Copyright (C) 2007 shash
Copyright (C) 2007-2017 DeSmuME team Copyright (C) 2007-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -88,6 +88,8 @@ enum EDMADestinationUpdate
class TRegister_32 class TRegister_32
{ {
public: public:
virtual ~TRegister_32() {}
virtual u32 read32() = 0; virtual u32 read32() = 0;
virtual void write32(const u32 val) = 0; virtual void write32(const u32 val) = 0;
void write(const int size, const u32 adr, const u32 val) { void write(const int size, const u32 adr, const u32 val) {
@ -124,6 +126,9 @@ struct TGXSTAT : public TRegister_32
fifo_empty = true; fifo_empty = true;
fifo_low = false; fifo_low = false;
} }
virtual ~TGXSTAT() {}
u8 tb; //test busy u8 tb; //test busy
u8 tr; //test result u8 tr; //test result
u8 se; //stack error u8 se; //stack error
@ -246,7 +251,10 @@ public:
AddressRegister(u32* _ptr) AddressRegister(u32* _ptr)
: ptr(_ptr) : ptr(_ptr)
{} {}
virtual u32 read32() {
virtual ~AddressRegister() {}
virtual u32 read32() {
return *ptr; return *ptr;
} }
virtual void write32(const u32 val) { virtual void write32(const u32 val) {
@ -259,7 +267,9 @@ public:
//we pass in a pointer to the controller here so we can alert it if anything changes //we pass in a pointer to the controller here so we can alert it if anything changes
DmaController* controller; DmaController* controller;
ControlRegister() {} ControlRegister() {}
virtual u32 read32() { virtual ~ControlRegister() {}
virtual u32 read32() {
return controller->read32(); return controller->read32();
} }
virtual void write32(const u32 val) { virtual void write32(const u32 val) {
@ -514,24 +524,24 @@ extern MMU_struct_new MMU_new;
struct armcpu_memory_iface struct armcpu_memory_iface
{ {
/** the 32 bit instruction prefetch */ /** the 32 bit instruction prefetch */
u32 FASTCALL (*prefetch32)( void *data, u32 adr); u32 DESMUME_FASTCALL (*prefetch32)( void *data, u32 adr);
/** the 16 bit instruction prefetch */ /** the 16 bit instruction prefetch */
u16 FASTCALL (*prefetch16)( void *data, u32 adr); u16 DESMUME_FASTCALL (*prefetch16)( void *data, u32 adr);
/** read 8 bit data value */ /** read 8 bit data value */
u8 FASTCALL (*read8)( void *data, u32 adr); u8 DESMUME_FASTCALL (*read8)( void *data, u32 adr);
/** read 16 bit data value */ /** read 16 bit data value */
u16 FASTCALL (*read16)( void *data, u32 adr); u16 DESMUME_FASTCALL (*read16)( void *data, u32 adr);
/** read 32 bit data value */ /** read 32 bit data value */
u32 FASTCALL (*read32)( void *data, u32 adr); u32 DESMUME_FASTCALL (*read32)( void *data, u32 adr);
/** write 8 bit data value */ /** write 8 bit data value */
void FASTCALL (*write8)( void *data, u32 adr, u8 val); void DESMUME_FASTCALL (*write8)( void *data, u32 adr, u8 val);
/** write 16 bit data value */ /** write 16 bit data value */
void FASTCALL (*write16)( void *data, u32 adr, u16 val); void DESMUME_FASTCALL (*write16)( void *data, u32 adr, u16 val);
/** write 32 bit data value */ /** write 32 bit data value */
void FASTCALL (*write32)( void *data, u32 adr, u32 val); void DESMUME_FASTCALL (*write32)( void *data, u32 adr, u32 val);
void *data; void *data;
}; };
@ -545,14 +555,14 @@ void MMU_Reset( void);
void print_memory_profiling( void); void print_memory_profiling( void);
// Memory reading/writing (old) // Memory reading/writing (old)
u8 FASTCALL MMU_read8(u32 proc, u32 adr); u8 DESMUME_FASTCALL MMU_read8(u32 proc, u32 adr);
u16 FASTCALL MMU_read16(u32 proc, u32 adr); u16 DESMUME_FASTCALL MMU_read16(u32 proc, u32 adr);
u32 FASTCALL MMU_read32(u32 proc, u32 adr); u32 DESMUME_FASTCALL MMU_read32(u32 proc, u32 adr);
void FASTCALL MMU_write8(u32 proc, u32 adr, u8 val); void DESMUME_FASTCALL MMU_write8(u32 proc, u32 adr, u8 val);
void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val); void DESMUME_FASTCALL MMU_write16(u32 proc, u32 adr, u16 val);
void FASTCALL MMU_write32(u32 proc, u32 adr, u32 val); void DESMUME_FASTCALL MMU_write32(u32 proc, u32 adr, u32 val);
//template<int PROCNUM> void FASTCALL MMU_doDMA(u32 num); //template<int PROCNUM> void DESMUME_FASTCALL MMU_doDMA(u32 num);
//The base ARM memory interfaces //The base ARM memory interfaces
extern const armcpu_memory_iface arm9_base_memory_iface; extern const armcpu_memory_iface arm9_base_memory_iface;
@ -626,6 +636,10 @@ FORCEINLINE void* MMU_gpu_map(const u32 vram_addr)
return MMU.ARM9_LCD + (vram_page << 14) + ofs; return MMU.ARM9_LCD + (vram_page << 14) + ofs;
} }
// Call MMU_WriteFromExternal() when modifying memory outside of the normal execution process, such
// as when using cheats or when the client wants to write to memory directly. This function returns
// true if memory is modified in such a way that requires the JIT execution be reset.
template<typename T, size_t LENGTH> bool MMU_WriteFromExternal(const int targetProc, const u32 targetAddress, T newValue);
template<int PROCNUM, MMU_ACCESS_TYPE AT> u8 _MMU_read08(u32 addr); template<int PROCNUM, MMU_ACCESS_TYPE AT> u8 _MMU_read08(u32 addr);
template<int PROCNUM, MMU_ACCESS_TYPE AT> u16 _MMU_read16(u32 addr); template<int PROCNUM, MMU_ACCESS_TYPE AT> u16 _MMU_read16(u32 addr);
@ -641,19 +655,19 @@ template<int PROCNUM> FORCEINLINE void _MMU_write08(u32 addr, u8 val) { _MMU_wri
template<int PROCNUM> FORCEINLINE void _MMU_write16(u32 addr, u16 val) { _MMU_write16<PROCNUM, MMU_AT_DATA>(addr,val); } template<int PROCNUM> FORCEINLINE void _MMU_write16(u32 addr, u16 val) { _MMU_write16<PROCNUM, MMU_AT_DATA>(addr,val); }
template<int PROCNUM> FORCEINLINE void _MMU_write32(u32 addr, u32 val) { _MMU_write32<PROCNUM, MMU_AT_DATA>(addr,val); } template<int PROCNUM> FORCEINLINE void _MMU_write32(u32 addr, u32 val) { _MMU_write32<PROCNUM, MMU_AT_DATA>(addr,val); }
void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val); void DESMUME_FASTCALL _MMU_ARM9_write08(u32 adr, u8 val);
void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val); void DESMUME_FASTCALL _MMU_ARM9_write16(u32 adr, u16 val);
void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val); void DESMUME_FASTCALL _MMU_ARM9_write32(u32 adr, u32 val);
u8 FASTCALL _MMU_ARM9_read08(u32 adr); u8 DESMUME_FASTCALL _MMU_ARM9_read08(u32 adr);
u16 FASTCALL _MMU_ARM9_read16(u32 adr); u16 DESMUME_FASTCALL _MMU_ARM9_read16(u32 adr);
u32 FASTCALL _MMU_ARM9_read32(u32 adr); u32 DESMUME_FASTCALL _MMU_ARM9_read32(u32 adr);
void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val); void DESMUME_FASTCALL _MMU_ARM7_write08(u32 adr, u8 val);
void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val); void DESMUME_FASTCALL _MMU_ARM7_write16(u32 adr, u16 val);
void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val); void DESMUME_FASTCALL _MMU_ARM7_write32(u32 adr, u32 val);
u8 FASTCALL _MMU_ARM7_read08(u32 adr); u8 DESMUME_FASTCALL _MMU_ARM7_read08(u32 adr);
u16 FASTCALL _MMU_ARM7_read16(u32 adr); u16 DESMUME_FASTCALL _MMU_ARM7_read16(u32 adr);
u32 FASTCALL _MMU_ARM7_read32(u32 adr); u32 DESMUME_FASTCALL _MMU_ARM7_read32(u32 adr);
extern u32 partie; extern u32 partie;
@ -1043,12 +1057,12 @@ FORCEINLINE void _MMU_write32(const int PROCNUM, const MMU_ACCESS_TYPE AT, const
//#ifdef MMU_ENABLE_ACL //#ifdef MMU_ENABLE_ACL
// void FASTCALL MMU_write8_acl(u32 proc, u32 adr, u8 val); // void DESMUME_FASTCALL MMU_write8_acl(u32 proc, u32 adr, u8 val);
// void FASTCALL MMU_write16_acl(u32 proc, u32 adr, u16 val); // void DESMUME_FASTCALL MMU_write16_acl(u32 proc, u32 adr, u16 val);
// void FASTCALL MMU_write32_acl(u32 proc, u32 adr, u32 val); // void DESMUME_FASTCALL MMU_write32_acl(u32 proc, u32 adr, u32 val);
// u8 FASTCALL MMU_read8_acl(u32 proc, u32 adr, u32 access); // u8 DESMUME_FASTCALL MMU_read8_acl(u32 proc, u32 adr, u32 access);
// u16 FASTCALL MMU_read16_acl(u32 proc, u32 adr, u32 access); // u16 DESMUME_FASTCALL MMU_read16_acl(u32 proc, u32 adr, u32 access);
// u32 FASTCALL MMU_read32_acl(u32 proc, u32 adr, u32 access); // u32 DESMUME_FASTCALL MMU_read32_acl(u32 proc, u32 adr, u32 access);
//#else //#else
// #define MMU_write8_acl(proc, adr, val) _MMU_write08<proc>(adr, val) // #define MMU_write8_acl(proc, adr, val) _MMU_write08<proc>(adr, val)
// #define MMU_write16_acl(proc, adr, val) _MMU_write16<proc>(adr, val) // #define MMU_write16_acl(proc, adr, val) _MMU_write16<proc>(adr, val)
@ -1093,6 +1107,6 @@ FORCEINLINE void _MMU_write16(u32 addr, u16 val) { _MMU_write16(PROCNUM, AT, add
template<int PROCNUM, MMU_ACCESS_TYPE AT> template<int PROCNUM, MMU_ACCESS_TYPE AT>
FORCEINLINE void _MMU_write32(u32 addr, u32 val) { _MMU_write32(PROCNUM, AT, addr, val); } FORCEINLINE void _MMU_write32(u32 addr, u32 val) { _MMU_write32(PROCNUM, AT, addr, val); }
void FASTCALL MMU_DumpMemBlock(u8 proc, u32 address, u32 size, u8 *buffer); void DESMUME_FASTCALL MMU_DumpMemBlock(u8 proc, u32 address, u32 size, u8 *buffer);
#endif #endif

View File

@ -1,258 +0,0 @@
include desmume.mk
AM_CPPFLAGS += $(SDL_CFLAGS) $(GTHREAD_CFLAGS) $(X_CFLAGS) $(ALSA_CFLAGS) $(LIBAGG_CFLAGS) $(LIBSOUNDTOUCH_CFLAGS)
EXTRA_DIST = instruction_tabdef.inc thumb_tabdef.inc cocoa
if HAVE_GDB_STUB
SUBDIRS = . gdbstub $(UI_DIR)
else
SUBDIRS = . $(UI_DIR)
endif
#DIST_SUBDIRS = . gdbstub cli gtk gtk-glade
noinst_LIBRARIES = libdesmume.a
libdesmume_a_SOURCES = \
armcpu.cpp armcpu.h \
arm_instructions.cpp \
agg2d.h agg2d.inl \
bios.cpp bios.h bits.h cp15.cpp cp15.h \
commandline.h commandline.cpp \
common.cpp common.h \
debug.cpp debug.h \
Database.cpp Database.h Disassembler.cpp Disassembler.h \
emufile.h emufile.cpp encrypt.h encrypt.cpp FIFO.cpp FIFO.h \
firmware.cpp firmware.h GPU.cpp GPU.h \
GPU_osd.h \
instructions.h \
mem.h mc.cpp mc.h \
path.cpp path.h \
readwrite.cpp readwrite.h \
wifi.cpp wifi.h \
mic.h \
MMU.cpp MMU.h MMU_timing.h NDSSystem.cpp NDSSystem.h registers.h \
OGLRender.h OGLRender_3_2.h \
ROMReader.cpp ROMReader.h \
render3D.cpp render3D.h \
rtc.cpp rtc.h \
saves.cpp saves.h \
slot1.cpp slot1.h \
slot2.cpp slot2.h \
SPU.cpp SPU.h \
matrix.cpp matrix.h \
gfx3d.cpp gfx3d.h \
thumb_instructions.cpp types.h \
movie.cpp movie.h \
PACKED.h PACKED_END.h \
utils/advanscene.cpp utils/advanscene.h \
utils/datetime.cpp utils/datetime.h \
utils/ConvertUTF.c utils/ConvertUTF.h utils/guid.cpp utils/guid.h \
utils/emufat.cpp utils/emufat.h utils/emufat_types.h \
utils/fsnitro.cpp utils/fsnitro.h \
utils/md5.cpp utils/md5.h utils/valuearray.h utils/xstring.cpp utils/xstring.h \
utils/decrypt/crc.cpp utils/decrypt/crc.h utils/decrypt/decrypt.cpp \
utils/decrypt/decrypt.h utils/decrypt/header.cpp utils/decrypt/header.h \
utils/task.cpp utils/task.h \
utils/vfat.h utils/vfat.cpp \
utils/colorspacehandler/colorspacehandler.cpp \
utils/dlditool.cpp \
utils/libfat/bit_ops.h \
utils/libfat/cache.cpp \
utils/libfat/cache.h \
utils/libfat/common.h \
utils/libfat/directory.cpp \
utils/libfat/directory.h \
utils/libfat/disc.cpp \
utils/libfat/disc.h \
utils/libfat/disc_io.h \
utils/libfat/fat.h \
utils/libfat/fatdir.cpp \
utils/libfat/fatdir.h \
utils/libfat/fatfile.cpp \
utils/libfat/fatfile.h \
utils/libfat/filetime.cpp \
utils/libfat/filetime.h \
utils/libfat/file_allocation_table.cpp \
utils/libfat/file_allocation_table.h \
utils/libfat/libfat.cpp \
utils/libfat/libfat_pc.h \
utils/libfat/libfat_public_api.cpp \
utils/libfat/libfat_public_api.h \
utils/libfat/lock.cpp \
utils/libfat/lock.h \
utils/libfat/mem_allocate.h \
utils/libfat/partition.cpp \
utils/libfat/partition.h \
utils/tinyxml/tinystr.cpp \
utils/tinyxml/tinystr.h \
utils/tinyxml/tinyxml.cpp \
utils/tinyxml/tinyxml.h \
utils/tinyxml/tinyxmlerror.cpp \
utils/tinyxml/tinyxmlparser.cpp \
utils/glcorearb.h \
addons/slot2_auto.cpp \
addons/slot2_mpcf.cpp \
addons/slot2_paddle.cpp \
addons/slot2_gbagame.cpp \
addons/slot2_none.cpp \
addons/slot2_rumblepak.cpp \
addons/slot2_guitarGrip.cpp \
addons/slot2_expMemory.cpp \
addons/slot2_piano.cpp \
addons/slot2_passme.cpp \
addons/slot1_none.cpp \
addons/slot1_r4.cpp \
addons/slot1_retail_nand.cpp \
addons/slot1_retail_auto.cpp \
addons/slot1_retail_mcrom.cpp \
addons/slot1_retail_mcrom_debug.cpp \
addons/slot1comp_mc.cpp \
addons/slot1comp_mc.h \
addons/slot1comp_rom.h \
addons/slot1comp_rom.cpp \
addons/slot1comp_protocol.h \
addons/slot1comp_protocol.cpp \
cheatSystem.cpp cheatSystem.h \
texcache.cpp texcache.h rasterize.cpp rasterize.h \
metaspu/metaspu.cpp metaspu/metaspu.h \
filter/2xsai.cpp \
filter/bilinear.cpp \
filter/deposterize.cpp \
filter/epx.cpp \
filter/filter.h \
filter/hq2x.cpp \
filter/hq2x.h \
filter/hq3x.cpp \
filter/hq3x.dat \
filter/hq4x.cpp \
filter/hq4x.dat \
filter/interp.h \
filter/lq2x.cpp filter/lq2x.h \
filter/scanline.cpp \
filter/videofilter.cpp filter/videofilter.h \
filter/xbrz.cpp filter/xbrz.h \
version.cpp version.h \
desmume_config.cpp desmume_config.h \
libretro-common/compat/compat_getopt.c \
libretro-common/file/file_path.c \
libretro-common/compat/compat_strl.c \
libretro-common/features/features_cpu.c \
libretro-common/file/retro_dirent.c \
libretro-common/file/retro_stat.c \
libretro-common/rthreads/async_job.c \
libretro-common/rthreads/rsemaphore.c \
libretro-common/rthreads/rthreads.c
if SUPPORT_SSE2
libdesmume_a_SOURCES += \
utils/colorspacehandler/colorspacehandler_SSE2.cpp
endif
if SUPPORT_AVX2
libdesmume_a_SOURCES += \
utils/colorspacehandler/colorspacehandler_AVX2.cpp
endif
if SUPPORT_ALTIVEC
libdesmume_a_SOURCES += \
utils/colorspacehandler/colorspacehandler_AltiVec.cpp
endif
if HAVE_JIT
libdesmume_a_SOURCES += \
arm_jit.cpp arm_jit.h instruction_attributes.h \
utils/AsmJit/AsmJit.h \
utils/AsmJit/Config.h \
utils/AsmJit/core.h \
utils/AsmJit/x86.h \
utils/AsmJit/core/apibegin.h \
utils/AsmJit/core/apiend.h \
utils/AsmJit/core/assembler.cpp \
utils/AsmJit/core/assembler.h \
utils/AsmJit/core/assert.cpp \
utils/AsmJit/core/assert.h \
utils/AsmJit/core/buffer.cpp \
utils/AsmJit/core/buffer.h \
utils/AsmJit/core/build.h \
utils/AsmJit/core/compiler.cpp \
utils/AsmJit/core/compiler.h \
utils/AsmJit/core/compilercontext.cpp \
utils/AsmJit/core/compilercontext.h \
utils/AsmJit/core/compilerfunc.cpp \
utils/AsmJit/core/compilerfunc.h \
utils/AsmJit/core/compileritem.cpp \
utils/AsmJit/core/compileritem.h \
utils/AsmJit/core/context.cpp \
utils/AsmJit/core/context.h \
utils/AsmJit/core/cpuinfo.cpp \
utils/AsmJit/core/cpuinfo.h \
utils/AsmJit/core/defs.cpp \
utils/AsmJit/core/defs.h \
utils/AsmJit/core/func.cpp \
utils/AsmJit/core/func.h \
utils/AsmJit/core/intutil.h \
utils/AsmJit/core/lock.h \
utils/AsmJit/core/logger.cpp \
utils/AsmJit/core/logger.h \
utils/AsmJit/core/memorymanager.cpp \
utils/AsmJit/core/memorymanager.h \
utils/AsmJit/core/memorymarker.cpp \
utils/AsmJit/core/memorymarker.h \
utils/AsmJit/core/operand.cpp \
utils/AsmJit/core/operand.h \
utils/AsmJit/core/podvector.h \
utils/AsmJit/core/stringbuilder.cpp \
utils/AsmJit/core/stringbuilder.h \
utils/AsmJit/core/stringutil.cpp \
utils/AsmJit/core/stringutil.h \
utils/AsmJit/core/virtualmemory.cpp \
utils/AsmJit/core/virtualmemory.h \
utils/AsmJit/core/zonememory.cpp \
utils/AsmJit/core/zonememory.h \
utils/AsmJit/x86/x86assembler.cpp \
utils/AsmJit/x86/x86assembler.h \
utils/AsmJit/x86/x86compiler.cpp \
utils/AsmJit/x86/x86compiler.h \
utils/AsmJit/x86/x86compilercontext.cpp \
utils/AsmJit/x86/x86compilercontext.h \
utils/AsmJit/x86/x86compilerfunc.cpp \
utils/AsmJit/x86/x86compilerfunc.h \
utils/AsmJit/x86/x86compileritem.cpp \
utils/AsmJit/x86/x86compileritem.h \
utils/AsmJit/x86/x86cpuinfo.cpp \
utils/AsmJit/x86/x86cpuinfo.h \
utils/AsmJit/x86/x86defs.cpp \
utils/AsmJit/x86/x86defs.h \
utils/AsmJit/x86/x86func.cpp \
utils/AsmJit/x86/x86func.h \
utils/AsmJit/x86/x86operand.cpp \
utils/AsmJit/x86/x86operand.h \
utils/AsmJit/x86/x86util.cpp \
utils/AsmJit/x86/x86util.h
endif
if HAVE_GL
libdesmume_a_SOURCES += OGLRender.cpp OGLRender_3_2.cpp
endif
if HAVE_OPENAL
libdesmume_a_SOURCES += mic_openal.cpp
else
if HAVE_ALSA
libdesmume_a_SOURCES += mic_alsa.cpp
else
libdesmume_a_SOURCES += mic.cpp
endif
endif
if HAVE_LIBSOUNDTOUCH
libdesmume_a_SOURCES += metaspu/SndOut.cpp metaspu/SndOut.h metaspu/Timestretcher.cpp
endif
if HAVE_LIBAGG
libdesmume_a_SOURCES += aggdraw.cpp aggdraw.h GPU_osd.cpp
else
libdesmume_a_SOURCES += GPU_osd_stub.cpp
endif
if HAVE_LUA
AM_CPPFLAGS += $(LUA_CFLAGS)
libdesmume_a_SOURCES += lua-engine.cpp
endif

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2006 yopyop Copyright (C) 2006 yopyop
Copyright (C) 2008-2021 DeSmuME team Copyright (C) 2008-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -104,9 +104,6 @@ CFIRMWARE *extFirmwareObj = NULL;
std::vector<u32> memReadBreakPoints; std::vector<u32> memReadBreakPoints;
std::vector<u32> memWriteBreakPoints; std::vector<u32> memWriteBreakPoints;
using std::min;
using std::max;
bool singleStep; bool singleStep;
bool nds_debug_continuing[2]; bool nds_debug_continuing[2];
int lagframecounter; int lagframecounter;
@ -317,6 +314,36 @@ RomBanner::RomBanner(bool defaultInit)
memset(end0xFF,0,sizeof(end0xFF)); memset(end0xFF,0,sizeof(end0xFF));
} }
GameInfo::GameInfo()
{
fROM = NULL;
reader = NULL;
romdataForReader = NULL;
romsize = 0;
cardSize = 0;
mask = 0;
crc = 0;
crcForCheatsDb = 0;
chipID = 0x00000FC2;
romType = ROM_NDS;
headerOffset = 0;
memset(&ROMserial[0], 0, sizeof(ROMserial));
memset(&ROMname[0], 0, sizeof(ROMname));
_isDSiEnhanced = false;
memset(&header, 0, sizeof(header));
memset(secureArea, 0, sizeof(secureArea));
memset(&banner, 0, sizeof(banner));
}
GameInfo::~GameInfo()
{
closeROM();
}
bool GameInfo::hasRomBanner() bool GameInfo::hasRomBanner()
{ {
if(header.IconOff + sizeof(RomBanner) > romsize) if(header.IconOff + sizeof(RomBanner) > romsize)
@ -635,7 +662,8 @@ bool GameInfo::isDSiEnhanced()
bool GameInfo::isHomebrew() bool GameInfo::isHomebrew()
{ {
return ((header.ARM9src < 0x4000) && (T1ReadLong(header.logo, 0) != 0x51AEFF24) && (T1ReadLong(header.logo, 4) != 0x699AA221)); return ((header.ARM9src < 0x4000) && (T1ReadLong(header.logo, 0) != 0x51AEFF24) && (T1ReadLong(header.logo, 4) != 0x699AA221)) ||
(!memcmp(header.gameCode, "####", 4)); // <- ndstool default signature
} }
static int rom_init_path(const char *filename, const char *physicalName, const char *logicalFilename) static int rom_init_path(const char *filename, const char *physicalName, const char *logicalFilename)
@ -720,9 +748,9 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
int read = gameInfo.reader->Read(gameInfo.fROM,fROMBuffer,4096); int read = gameInfo.reader->Read(gameInfo.fROM,fROMBuffer,4096);
if(read == 0) break; if(read == 0) break;
if(first && read >= 512) if(first && read >= 512)
gameInfo.crcForCheatsDb = ~crc32(0, fROMBuffer, 512); gameInfo.crcForCheatsDb = (u32)~crc32(0, fROMBuffer, 512);
first = false; first = false;
gameInfo.crc = crc32(gameInfo.crc, fROMBuffer, read); gameInfo.crc = (u32)crc32(gameInfo.crc, fROMBuffer, read);
} }
gameInfo.chipID = 0xC2; // The Manufacturer ID is defined by JEDEC (C2h = Macronix) gameInfo.chipID = 0xC2; // The Manufacturer ID is defined by JEDEC (C2h = Macronix)
@ -778,7 +806,7 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
else else
{ {
printf("%s", save_types[sv + 1].descr); printf("%s", save_types[sv + 1].descr);
if (CommonSettings.autodetectBackupMethod == 1) if (CommonSettings.autodetectBackupMethod == BackupDeviceAutodetectMethod_Advanscene)
backup_setManualBackupType(sv + 1); backup_setManualBackupType(sv + 1);
} }
printf("\n\t* ROM crc:\t\t%08X\n", advsc.getCRC32()); printf("\n\t* ROM crc:\t\t%08X\n", advsc.getCRC32());
@ -939,6 +967,8 @@ static const u64 kNever = 0xFFFFFFFFFFFFFFFFULL;
struct TSequenceItem struct TSequenceItem
{ {
virtual ~TSequenceItem() {}
u64 timestamp; u64 timestamp;
u32 param; u32 param;
bool enabled; bool enabled;
@ -971,6 +1001,8 @@ struct TSequenceItem
struct TSequenceItem_GXFIFO : public TSequenceItem struct TSequenceItem_GXFIFO : public TSequenceItem
{ {
virtual ~TSequenceItem_GXFIFO() {}
FORCEINLINE bool isTriggered() FORCEINLINE bool isTriggered()
{ {
return enabled && nds_timer >= MMU.gfx3dCycles; return enabled && nds_timer >= MMU.gfx3dCycles;
@ -994,6 +1026,8 @@ struct TSequenceItem_GXFIFO : public TSequenceItem
template<int procnum, int num> struct TSequenceItem_Timer : public TSequenceItem template<int procnum, int num> struct TSequenceItem_Timer : public TSequenceItem
{ {
virtual ~TSequenceItem_Timer() {}
FORCEINLINE bool isTriggered() FORCEINLINE bool isTriggered()
{ {
return enabled && nds_timer >= nds.timerCycle[procnum][num]; return enabled && nds_timer >= nds.timerCycle[procnum][num];
@ -1062,6 +1096,8 @@ template<int procnum, int num> struct TSequenceItem_Timer : public TSequenceItem
template<int procnum, int chan> struct TSequenceItem_DMA : public TSequenceItem template<int procnum, int chan> struct TSequenceItem_DMA : public TSequenceItem
{ {
DmaController* controller; DmaController* controller;
virtual ~TSequenceItem_DMA() {}
FORCEINLINE bool isTriggered() FORCEINLINE bool isTriggered()
{ {
@ -1121,6 +1157,8 @@ template<int procnum, int chan> struct TSequenceItem_DMA : public TSequenceItem
struct TSequenceItem_ReadSlot1 : public TSequenceItem struct TSequenceItem_ReadSlot1 : public TSequenceItem
{ {
virtual ~TSequenceItem_ReadSlot1() {}
FORCEINLINE bool isTriggered() FORCEINLINE bool isTriggered()
{ {
return enabled && nds_timer >= timestamp; return enabled && nds_timer >= timestamp;
@ -1147,6 +1185,8 @@ struct TSequenceItem_ReadSlot1 : public TSequenceItem
struct TSequenceItem_divider : public TSequenceItem struct TSequenceItem_divider : public TSequenceItem
{ {
virtual ~TSequenceItem_divider() {}
FORCEINLINE bool isTriggered() FORCEINLINE bool isTriggered()
{ {
return MMU.divRunning && nds_timer >= MMU.divCycles; return MMU.divRunning && nds_timer >= MMU.divCycles;
@ -1179,6 +1219,8 @@ struct TSequenceItem_divider : public TSequenceItem
struct TSequenceItem_sqrtunit : public TSequenceItem struct TSequenceItem_sqrtunit : public TSequenceItem
{ {
virtual ~TSequenceItem_sqrtunit() {}
FORCEINLINE bool isTriggered() FORCEINLINE bool isTriggered()
{ {
return MMU.sqrtRunning && nds_timer >= MMU.sqrtCycles; return MMU.sqrtRunning && nds_timer >= MMU.sqrtCycles;
@ -1453,8 +1495,11 @@ static void execHardware_hstart_vblankStart()
//for ARM7, cheats process when a vblank IRQ fires. necessary for AR compatibility and to stop cheats from breaking game boot-ups. //for ARM7, cheats process when a vblank IRQ fires. necessary for AR compatibility and to stop cheats from breaking game boot-ups.
//note that how we process raw cheats is up to us. so we'll do it the same way we used to, elsewhere //note that how we process raw cheats is up to us. so we'll do it the same way we used to, elsewhere
if (i==1 && cheats) if ( (i == 1) && (cheats != NULL) )
{
cheats->process(CHEAT_TYPE_AR); cheats->process(CHEAT_TYPE_AR);
CHEATS::ResetJitIfNeeded();
}
} }
} }
@ -1653,7 +1698,7 @@ FORCEINLINE u64 _fast_min(u64 a, u64 b)
//you might find that this is faster on a 64bit system; someone should try it //you might find that this is faster on a 64bit system; someone should try it
//http://aggregate.org/MAGIC/#Integer%20Selection //http://aggregate.org/MAGIC/#Integer%20Selection
//u64 ret = (((((s64)(a-b)) >> (64-1)) & (a^b)) ^ b); //u64 ret = (((((s64)(a-b)) >> (64-1)) & (a^b)) ^ b);
//assert(ret==min(a,b)); //assert(ret==std::min(a,b));
//return ret; //return ret;
//but this ends up being the fastest on 32bits //but this ends up being the fastest on 32bits
@ -1895,7 +1940,7 @@ static FORCEINLINE s32 minarmtime(s32 arm9, s32 arm7)
{ {
if(doarm9) if(doarm9)
if(doarm7) if(doarm7)
return min(arm9,arm7); return std::min(arm9,arm7);
else else
return arm9; return arm9;
else else
@ -1959,7 +2004,7 @@ static /*donotinline*/ std::pair<s32,s32> armInnerLoop(
else else
{ {
s32 temp = arm9; s32 temp = arm9;
arm9 = min(s32next, arm9 + kIrqWait); arm9 = std::min(s32next, arm9 + kIrqWait);
nds.idleCycles[0] += arm9-temp; nds.idleCycles[0] += arm9-temp;
if (gxFIFO.size < 255) nds.freezeBus &= ~1; if (gxFIFO.size < 255) nds.freezeBus &= ~1;
} }
@ -2000,7 +2045,7 @@ static /*donotinline*/ std::pair<s32,s32> armInnerLoop(
else else
{ {
s32 temp = arm7; s32 temp = arm7;
arm7 = min(s32next, arm7 + kIrqWait); arm7 = std::min(s32next, arm7 + kIrqWait);
nds.idleCycles[1] += arm7-temp; nds.idleCycles[1] += arm7-temp;
if(arm7 == s32next) if(arm7 == s32next)
{ {
@ -2120,7 +2165,7 @@ void NDS_exec(s32 nb)
//find next work unit: //find next work unit:
u64 next = sequencer.findNext(); u64 next = sequencer.findNext();
next = min(next,nds_timer+kMaxWork); //lets set an upper limit for now next = std::min(next,nds_timer+kMaxWork); //lets set an upper limit for now
//printf("%d\n",(next-nds_timer)); //printf("%d\n",(next-nds_timer));
@ -2196,7 +2241,11 @@ void NDS_exec(s32 nb)
} }
currFrameCounter++; currFrameCounter++;
DEBUG_Notify.NextFrame(); DEBUG_Notify.NextFrame();
if(cheats) cheats->process(CHEAT_TYPE_INTERNAL); if (cheats != NULL)
{
cheats->process(CHEAT_TYPE_INTERNAL);
CHEATS::ResetJitIfNeeded();
}
GDBSTUB_MUTEX_UNLOCK(); GDBSTUB_MUTEX_UNLOCK();
} }
@ -2607,12 +2656,12 @@ bool NDS_FakeBoot()
//perhaps we could automatically boot homebrew to an R4-like device. //perhaps we could automatically boot homebrew to an R4-like device.
_MMU_write32<ARMCPU_ARM9>(0x02FFFE70, 0x5f617267); _MMU_write32<ARMCPU_ARM9>(0x02FFFE70, 0x5f617267);
_MMU_write32<ARMCPU_ARM9>(0x02FFFE74, kCommandline); //(commandline starts here) _MMU_write32<ARMCPU_ARM9>(0x02FFFE74, kCommandline); //(commandline starts here)
_MMU_write32<ARMCPU_ARM9>(0x02FFFE78, rompath.size()+1); _MMU_write32<ARMCPU_ARM9>(0x02FFFE78, (u32)(rompath.size()+1));
//0x027FFF7C (argc) //0x027FFF7C (argc)
//0x027FFF80 (argv) //0x027FFF80 (argv)
for(size_t i=0;i<rompath.size();i++) for (size_t i = 0; i < rompath.size(); i++)
_MMU_write08<ARMCPU_ARM9>(kCommandline+i, rompath[i]); _MMU_write08<ARMCPU_ARM9>((u32)(kCommandline+i), rompath[i]);
_MMU_write08<ARMCPU_ARM9>(kCommandline+rompath.size(), 0); _MMU_write08<ARMCPU_ARM9>((u32)(kCommandline+rompath.size()), 0);
//-------------------------------- //--------------------------------
//Call the card post_fakeboot hook to perform additional initialization //Call the card post_fakeboot hook to perform additional initialization
@ -2845,14 +2894,14 @@ u16 NDS_getADCTouchPosX(int scrX_lsl4)
{ {
scrX_lsl4 >>= 4; scrX_lsl4 >>= 4;
int rv = ((scrX_lsl4 - TSCal.scr.x1 + 1) * TSCal.adc.width) / TSCal.scr.width + TSCal.adc.x1; int rv = ((scrX_lsl4 - TSCal.scr.x1 + 1) * TSCal.adc.width) / TSCal.scr.width + TSCal.adc.x1;
rv = min(0xFFF, max(0, rv)); rv = std::min(0xFFF, std::max(0, rv));
return (u16)(rv); return (u16)(rv);
} }
u16 NDS_getADCTouchPosY(int scrY_lsl4) u16 NDS_getADCTouchPosY(int scrY_lsl4)
{ {
scrY_lsl4 >>= 4; scrY_lsl4 >>= 4;
int rv = ((scrY_lsl4 - TSCal.scr.y1 + 1) * TSCal.adc.height) / TSCal.scr.height + TSCal.adc.y1; int rv = ((scrY_lsl4 - TSCal.scr.y1 + 1) * TSCal.adc.height) / TSCal.scr.height + TSCal.adc.y1;
rv = min(0xFFF, max(0, rv)); rv = std::min(0xFFF, std::max(0, rv));
return (u16)(rv); return (u16)(rv);
} }
@ -3290,6 +3339,129 @@ void NDS_GetCPULoadAverage(u32 &outLoadAvgARM9, u32 &outLoadAvgARM7)
template void NDS_exec<FALSE>(s32 nb); template void NDS_exec<FALSE>(s32 nb);
template void NDS_exec<TRUE>(s32 nb); template void NDS_exec<TRUE>(s32 nb);
TCommonSettings::TCommonSettings()
{
GFX3D_HighResolutionInterpolateColor = true;
GFX3D_EdgeMark = true;
GFX3D_Fog = true;
GFX3D_Texture = true;
GFX3D_LineHack = true;
GFX3D_Renderer_MultisampleSize = 0;
GFX3D_Renderer_TextureScalingFactor = 1;
GFX3D_Renderer_TextureDeposterize = false;
GFX3D_Renderer_TextureSmoothing = false;
GFX3D_TXTHack = false;
OpenGL_Emulation_ShadowPolygon = true;
OpenGL_Emulation_SpecialZeroAlphaBlending = true;
OpenGL_Emulation_NDSDepthCalculation = true;
OpenGL_Emulation_DepthLEqualPolygonFacing = false;
loadToMemory = false;
UseExtBIOS = false;
strncpy(ARM9BIOS, "biosnds9.bin", MAX_PATH);
strncpy(ARM7BIOS, "biosnds7.bin", MAX_PATH);
SWIFromBIOS = false;
PatchSWI3 = false;
RetailCardProtection8000 = true;
UseExtFirmware = false;
UseExtFirmwareSettings = false;
strncpy(ExtFirmwarePath, "firmware.bin", MAX_PATH);
memset(ExtFirmwareUserSettingsPath, 0, sizeof(ExtFirmwareUserSettingsPath));
BootFromFirmware = false;
ConsoleType = NDS_CONSOLE_TYPE_FAT;
DebugConsole = false;
EnsataEmulation = false;
cheatsDisable = false;
num_cores = NDS_GetCPUCoreCount();
rigorous_timing = false;
gamehacks.en = true;
gamehacks.clear();
StylusPressure = 50;
dispLayers[0][0] = true;
dispLayers[0][1] = true;
dispLayers[0][2] = true;
dispLayers[0][3] = true;
dispLayers[0][4] = true;
dispLayers[1][0] = true;
dispLayers[1][1] = true;
dispLayers[1][2] = true;
dispLayers[1][3] = true;
dispLayers[1][4] = true;
advanced_timing = true;
#ifdef HAVE_JIT
//zero 06-sep-2012 - shouldnt be defaulting this to true for now, since the jit is buggy.
//id rather have people discover a bonus speedhack than discover new bugs in a new version
use_jit = false;
#else
use_jit = false;
#endif
jit_max_block_size = 12;
WifiBridgeDeviceID = 0;
micMode = MicMode_InternalNoise;
spuInterpolationMode = SPUInterpolation_Cosine;
autodetectBackupMethod = BackupDeviceAutodetectMethod_Desmume;
manualBackupType = MC_TYPE_AUTODETECT;
backupSave = false;
SPU_sync_mode = ESynchMode_Synchronous;
SPU_sync_method = ESynchMethod_N;
spu_muteChannels[ 0] = false;
spu_muteChannels[ 1] = false;
spu_muteChannels[ 2] = false;
spu_muteChannels[ 3] = false;
spu_muteChannels[ 4] = false;
spu_muteChannels[ 5] = false;
spu_muteChannels[ 6] = false;
spu_muteChannels[ 7] = false;
spu_muteChannels[ 8] = false;
spu_muteChannels[ 9] = false;
spu_muteChannels[10] = false;
spu_muteChannels[11] = false;
spu_muteChannels[12] = false;
spu_muteChannels[13] = false;
spu_muteChannels[14] = false;
spu_muteChannels[15] = false;
spu_captureMuted = false;
spu_advanced = true;
showGpu.main = true;
showGpu.sub = true;
hud.ShowInputDisplay = false;
hud.ShowGraphicalInputDisplay = false;
hud.FpsDisplay = false;
hud.FrameCounterDisplay = false;
hud.ShowLagFrameCounter = false;
hud.ShowMicrophone = false;
hud.ShowRTC = false;
run_advanscene_import = "";
NDS_SetupDefaultFirmware();
}
bool TCommonSettings::single_core()
{
return (num_cores == 1);
}
void TCommonSettings::GameHacks::apply() void TCommonSettings::GameHacks::apply()
{ {
clear(); clear();

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2006 yopyop Copyright (C) 2006 yopyop
Copyright (C) 2008-2022 DeSmuME team Copyright (C) 2008-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -112,7 +112,7 @@ enum NDSErrorTag
NDSErrorTag_None = 0, NDSErrorTag_None = 0,
NDSErrorTag_ARM9 = 1, NDSErrorTag_ARM9 = 1,
NDSErrorTag_ARM7 = 2, NDSErrorTag_ARM7 = 2,
NDSErrorTag_BothCPUs = 3, NDSErrorTag_BothCPUs = 3
}; };
struct NDSError struct NDSError
@ -346,26 +346,11 @@ struct GameInfo
NDS_header header; NDS_header header;
//a copy of the pristine secure area from the rom //a copy of the pristine secure area from the rom
u8 secureArea[0x4000]; u8 secureArea[0x4000];
RomBanner banner; RomBanner banner;
const RomBanner& getRomBanner(); const RomBanner& getRomBanner();
GameInfo() : fROM(NULL), GameInfo();
romdataForReader(NULL), ~GameInfo();
crc(0),
chipID(0x00000FC2),
romsize(0),
cardSize(0),
mask(0),
romType(ROM_NDS),
headerOffset(0),
_isDSiEnhanced(false)
{
memset(&header, 0, sizeof(header));
memset(&ROMserial[0], 0, sizeof(ROMserial));
memset(&ROMname[0], 0, sizeof(ROMname));
}
~GameInfo() { closeROM(); }
bool IsCode(const char* code) const; bool IsCode(const char* code) const;
@ -377,7 +362,6 @@ struct GameInfo
bool isDSiEnhanced(); bool isDSiEnhanced();
bool isHomebrew(); bool isHomebrew();
bool hasRomBanner(); bool hasRomBanner();
}; };
typedef struct TSCalInfo typedef struct TSCalInfo
@ -495,71 +479,16 @@ template<bool FORCE> void NDS_exec(s32 nb = 560190<<1);
extern int lagframecounter; extern int lagframecounter;
enum MicMode
{
MicMode_InternalNoise = 0,
MicMode_Sample = 1,
MicMode_Random = 2,
MicMode_Physical = 3
};
extern struct TCommonSettings extern struct TCommonSettings
{ {
TCommonSettings()
: GFX3D_HighResolutionInterpolateColor(true)
, GFX3D_EdgeMark(true)
, GFX3D_Fog(true)
, GFX3D_Texture(true)
, GFX3D_LineHack(true)
, GFX3D_Renderer_MultisampleSize(0)
, GFX3D_Renderer_TextureScalingFactor(1) // Possible values: 1, 2, 4
, GFX3D_Renderer_TextureDeposterize(false)
, GFX3D_Renderer_TextureSmoothing(false)
, GFX3D_TXTHack(false)
, OpenGL_Emulation_ShadowPolygon(true)
, OpenGL_Emulation_SpecialZeroAlphaBlending(true)
, OpenGL_Emulation_NDSDepthCalculation(true)
, OpenGL_Emulation_DepthLEqualPolygonFacing(false)
, jit_max_block_size(12)
, loadToMemory(false)
, UseExtBIOS(false)
, SWIFromBIOS(false)
, PatchSWI3(false)
, UseExtFirmware(false)
, UseExtFirmwareSettings(false)
, RetailCardProtection8000(true)
, BootFromFirmware(false)
, DebugConsole(false)
, EnsataEmulation(false)
, cheatsDisable(false)
, rigorous_timing(false)
, advanced_timing(true)
, micMode(InternalNoise)
, spuInterpolationMode(2)
, manualBackupType(0)
, autodetectBackupMethod(0)
, spu_captureMuted(false)
, spu_advanced(true)
, StylusPressure(50)
, ConsoleType(NDS_CONSOLE_TYPE_FAT)
, backupSave(false)
, SPU_sync_mode(1)
, SPU_sync_method(0)
, WifiBridgeDeviceID(0)
{
strcpy(ARM9BIOS, "biosnds9.bin");
strcpy(ARM7BIOS, "biosnds7.bin");
strcpy(ExtFirmwarePath, "firmware.bin");
for(int i=0;i<16;i++)
spu_muteChannels[i] = false;
for(int g=0;g<2;g++)
for(int x=0;x<5;x++)
dispLayers[g][x]=true;
#ifdef HAVE_JIT
//zero 06-sep-2012 - shouldnt be defaulting this to true for now, since the jit is buggy.
//id rather have people discover a bonus speedhack than discover new bugs in a new version
use_jit = false;
#else
use_jit = false;
#endif
num_cores = NDS_GetCPUCoreCount();
NDS_SetupDefaultFirmware();
}
bool GFX3D_HighResolutionInterpolateColor; bool GFX3D_HighResolutionInterpolateColor;
bool GFX3D_EdgeMark; bool GFX3D_EdgeMark;
bool GFX3D_Fog; bool GFX3D_Fog;
@ -599,18 +528,14 @@ extern struct TCommonSettings
bool cheatsDisable; bool cheatsDisable;
int num_cores; int num_cores;
bool single_core() { return num_cores==1; }
bool rigorous_timing; bool rigorous_timing;
struct GameHacks { struct GameHacks
GameHacks() {
: en(true)
{
clear();
}
bool en; bool en;
struct { struct
{
bool overclock; bool overclock;
bool stylusjitter; bool stylusjitter;
} flags; } flags;
@ -630,15 +555,7 @@ extern struct TCommonSettings
int WifiBridgeDeviceID; int WifiBridgeDeviceID;
enum MicMode MicMode micMode;
{
InternalNoise = 0,
Sample = 1,
Random = 2,
Physical = 3
} micMode;
int spuInterpolationMode; int spuInterpolationMode;
//this is a temporary hack until we straighten out the flushing logic and/or gxfifo //this is a temporary hack until we straighten out the flushing logic and/or gxfifo
@ -656,29 +573,27 @@ extern struct TCommonSettings
bool spu_captureMuted; bool spu_captureMuted;
bool spu_advanced; bool spu_advanced;
struct _ShowGpu { union
_ShowGpu() : main(true), sub(true) {} {
union { struct { bool main, sub; };
struct { bool main,sub; }; bool screens[2];
bool screens[2];
};
} showGpu; } showGpu;
struct _Hud { struct _Hud
_Hud() {
: ShowInputDisplay(false) bool ShowInputDisplay;
, ShowGraphicalInputDisplay(false) bool ShowGraphicalInputDisplay;
, FpsDisplay(false) bool FpsDisplay;
, FrameCounterDisplay(false) bool FrameCounterDisplay;
, ShowLagFrameCounter(false) bool ShowLagFrameCounter;
, ShowMicrophone(false) bool ShowMicrophone;
, ShowRTC(false) bool ShowRTC;
{}
bool ShowInputDisplay, ShowGraphicalInputDisplay, FpsDisplay, FrameCounterDisplay, ShowLagFrameCounter, ShowMicrophone, ShowRTC;
} hud; } hud;
std::string run_advanscene_import; std::string run_advanscene_import;
TCommonSettings();
bool single_core();
} CommonSettings; } CommonSettings;
void NDS_RunAdvansceneAutoImport(); void NDS_RunAdvansceneAutoImport();

3314
desmume/src/OGLRender.cpp Executable file → Normal file

File diff suppressed because it is too large Load Diff

2043
desmume/src/OGLRender.h Executable file → Normal file

File diff suppressed because it is too large Load Diff

3009
desmume/src/OGLRender_3_2.cpp Executable file → Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* /*
Copyright (C) 2006 yopyop Copyright (C) 2006 yopyop
Copyright (C) 2006-2007 shash Copyright (C) 2006-2007 shash
Copyright (C) 2008-2019 DeSmuME team Copyright (C) 2008-2024 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -20,61 +20,106 @@
#ifndef OGLRENDER_3_2_H #ifndef OGLRENDER_3_2_H
#define OGLRENDER_3_2_H #define OGLRENDER_3_2_H
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glcorearb.h>
#define OGLEXT(procPtr, func) procPtr func = NULL;
#define INITOGLEXT(procPtr, func) func = (procPtr)wglGetProcAddress(#func);
#define EXTERNOGLEXT(procPtr, func) extern procPtr func;
#elif defined(__APPLE__)
#include <OpenGL/gl3.h>
#include <OpenGL/gl3ext.h>
// Ignore dynamic linking on Apple OS
#define OGLEXT(procPtr, func)
#define INITOGLEXT(procPtr, func)
#define EXTERNOGLEXT(procPtr, func)
#else
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glx.h>
#include "utils/glcorearb.h"
#define OGLEXT(procPtr, func) procPtr func = NULL;
#define INITOGLEXT(procPtr, func) func = (procPtr)glXGetProcAddress((const GLubyte *) #func);
#define EXTERNOGLEXT(procPtr, func) extern procPtr func;
#endif
// Check minimum OpenGL header version
#if !defined(GL_VERSION_3_2)
#error OpenGL requires v3.2 headers or later.
#endif
#include "OGLRender.h" #include "OGLRender.h"
#define MAX_CLIPPED_POLY_COUNT_FOR_UBO 16384 #define MAX_CLIPPED_POLY_COUNT_FOR_UBO 16384
extern const char *GeometryVtxShader_150;
extern const char *GeometryFragShader_150;
extern const char *GeometryZeroDstAlphaPixelMaskVtxShader_150;
extern const char *GeometryZeroDstAlphaPixelMaskFragShader_150;
extern const char *MSGeometryZeroDstAlphaPixelMaskFragShader_150;
extern const char *ClearImageVtxShader_150;
extern const char *ClearImageFragShader_150;
extern const char *EdgeMarkVtxShader_150;
extern const char *EdgeMarkFragShader_150;
extern const char *FogVtxShader_150;
extern const char *FogFragShader_150;
extern const char *FramebufferOutputVtxShader_150;
extern const char *FramebufferOutput6665FragShader_150;
// A port that wants to use the OpenGL 3.2 renderer must assign the two following functions
// to OGLLoadEntryPoints_3_2_Func and OGLCreateRenderer_3_2_Func, respectively.
//
// In addition, the port must add the following GPU3DInterface objects to core3DList:
// - gpu3Dgl: Automatically selects the most fully featured version of standard OpenGL that
// is available on the host system, prefering OpenGL 3.2 Core Profile.
// - gpu3Dgl_3_2: Selects the OpenGL 3.2 Core Profile renderer, and returns an error if it
// is not available on the host system.
//
// Finally, the port must call GPU->Set3DRendererByID() and pass in the index where
// gpu3Dgl_3_2 exists in core3DList so that the emulator can create the appropriate
// OpenGLRenderer object.
//
// Example code:
// OGLLoadEntryPoints_3_2_Func = &OGLLoadEntryPoints_3_2;
// OGLCreateRenderer_3_2_Func = &OGLCreateRenderer_3_2;
// GPU3DInterface *core3DList[] = { &gpu3DNull, &gpu3DRasterize, &gpu3Dgl_3_2, NULL };
// GPU->Set3DRendererByID(2);
void OGLLoadEntryPoints_3_2(); void OGLLoadEntryPoints_3_2();
void OGLCreateRenderer_3_2(OpenGLRenderer **rendererPtr); void OGLCreateRenderer_3_2(OpenGLRenderer **rendererPtr);
class OpenGLGeometryResource : public Render3DResourceGeometry
{
protected:
GLuint _vboID[3];
GLuint _eboID[3];
GLuint _vaoID[3];
GLuint _uboPolyStatesID[3];
GLuint _tboPolyStatesID[3];
GLuint _texPolyStatesID[3];
GLsync _syncGeometryRender[3];
u16 *_indexBuffer[3];
OGLPolyStates *_polyStatesBuffer[3];
public:
OpenGLGeometryResource(const OpenGLVariantID variantID);
~OpenGLGeometryResource();
size_t BindWrite(const size_t rawVtxCount, const size_t clippedPolyCount);
size_t BindUsage();
size_t UnbindUsage();
size_t RebindUsage();
u16* GetIndexBuffer(const size_t index);
OGLPolyStates* GetPolyStatesBuffer(const size_t index);
bool IsPolyStatesBufferUBO();
bool IsPolyStatesBufferTBO();
};
class OpenGLRenderStatesResource : public Render3DResource
{
protected:
GLsync _sync[3];
GLuint _uboRenderStatesID[3];
OGLRenderStates *_buffer[3];
public:
OpenGLRenderStatesResource();
~OpenGLRenderStatesResource();
size_t BindWrite();
size_t BindUsage();
size_t UnbindUsage();
OGLRenderStates* GetRenderStatesBuffer(const size_t index);
};
class OpenGLRenderer_3_2 : public OpenGLRenderer_2_1 class OpenGLRenderer_3_2 : public OpenGLRenderer_2_1
{ {
protected: protected:
bool _is64kUBOSupported; bool _isShaderFixedLocationSupported;
bool _isDualSourceBlendingSupported;
bool _isSampleShadingSupported;
bool _isConservativeDepthSupported; bool _isConservativeDepthSupported;
bool _isConservativeDepthAMDSupported; bool _isConservativeDepthAMDSupported;
GLsync _syncBufferSetup; OpenGLGeometryResource *_gResource;
CACHE_ALIGN OGLPolyStates _pendingPolyStates[POLYLIST_SIZE]; OpenGLRenderStatesResource *_rsResource;
virtual Render3DError InitExtensions();
virtual Render3DError CreateVBOs();
virtual Render3DError CreatePBOs();
virtual Render3DError CreateFBOs(); virtual Render3DError CreateFBOs();
virtual void DestroyFBOs(); virtual void DestroyFBOs();
virtual Render3DError CreateMultisampledFBO(GLsizei numSamples); virtual Render3DError CreateMultisampledFBO(GLsizei numSamples);
@ -84,40 +129,48 @@ protected:
virtual void DestroyVAOs(); virtual void DestroyVAOs();
virtual Render3DError CreateGeometryPrograms(); virtual Render3DError CreateGeometryPrograms();
virtual void DestroyGeometryPrograms(); virtual Render3DError CreateClearImageProgram(const char *vsCString, const char *fsCString);
virtual void DestroyClearImageProgram();
virtual Render3DError CreateGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString); virtual Render3DError CreateGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateMSGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString); virtual Render3DError CreateMSGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString);
virtual void DestroyMSGeometryZeroDstAlphaProgram(); virtual void DestroyMSGeometryZeroDstAlphaProgram();
virtual Render3DError CreateEdgeMarkProgram(const char *vtxShaderCString, const char *fragShaderCString); virtual Render3DError CreateEdgeMarkProgram(const bool isMultisample, const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateFogProgram(const OGLFogProgramKey fogProgramKey, const char *vtxShaderCString, const char *fragShaderCString); virtual Render3DError CreateFogProgram(const OGLFogProgramKey fogProgramKey, const bool isMultisample, const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateFramebufferOutput6665Program(const size_t outColorIndex, const char *vtxShaderCString, const char *fragShaderCString); virtual Render3DError CreateFramebufferOutput6665Program(const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateFramebufferOutput8888Program(const size_t outColorIndex, const char *vtxShaderCString, const char *fragShaderCString); virtual Render3DError CreateFramebufferOutput8888Program(const char *vtxShaderCString, const char *fragShaderCString);
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet); virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
virtual void _SetupGeometryShaders(const OGLGeometryFlags flags); virtual void _SetupGeometryShaders(const OGLGeometryFlags flags);
virtual Render3DError EnableVertexAttributes(); virtual void _RenderGeometryVertexAttribEnable();
virtual Render3DError DisableVertexAttributes(); virtual void _RenderGeometryVertexAttribDisable();
virtual Render3DError ZeroDstAlphaPass(const CPoly *clippedPolyList, const size_t clippedPolyCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr); virtual Render3DError ZeroDstAlphaPass(const POLY *rawPolyList, const CPoly *clippedPolyList, const size_t clippedPolyCount, const size_t clippedPolyOpaqueCount, bool enableAlphaBlending, size_t indexOffset, POLYGON_ATTR lastPolyAttr);
virtual void _RenderGeometryLoopBegin();
virtual void _RenderGeometryLoopEnd();
virtual void _ResolveWorkingBackFacing(); virtual void _ResolveWorkingBackFacing();
virtual void _ResolveGeometry(); virtual void _ResolveGeometry();
virtual Render3DError ReadBackPixels(); virtual void _ResolveFinalFramebuffer();
virtual Render3DError BeginRender(const GFX3D &engine); virtual void _FramebufferProcessVertexAttribEnable();
virtual void _FramebufferProcessVertexAttribDisable();
virtual Render3DError _FramebufferConvertColorFormat();
virtual Render3DError BeginRender(const GFX3D_State &renderState, const GFX3D_GeometryList &renderGList);
virtual Render3DError PostprocessFramebuffer(); virtual Render3DError PostprocessFramebuffer();
virtual Render3DError ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const u8 *__restrict fogBuffer, const u8 opaquePolyID); virtual Render3DError ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const u8 *__restrict fogBuffer, const u8 opaquePolyID);
virtual Render3DError ClearUsingValues(const FragmentColor &clearColor6665, const FragmentAttributes &clearAttributes); virtual Render3DError ClearUsingValues(const Color4u8 &clearColor6665, const FragmentAttributes &clearAttributes);
virtual void SetPolygonIndex(const size_t index); virtual void SetPolygonIndex(const size_t index);
virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer); virtual Render3DError SetupPolygon(const POLY &thePoly, bool treatAsTranslucent, bool willChangeStencilBuffer, bool isBackFacing);
virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex); virtual Render3DError SetupTexture(const POLY &thePoly, size_t polyRenderIndex);
virtual Render3DError SetFramebufferSize(size_t w, size_t h);
public: public:
OpenGLRenderer_3_2(); OpenGLRenderer_3_2();
~OpenGLRenderer_3_2(); ~OpenGLRenderer_3_2();
virtual Render3DError InitExtensions();
virtual Render3DError RenderFinish();
virtual Render3DError RenderPowerOff(); virtual Render3DError RenderPowerOff();
virtual Render3DError SetFramebufferSize(size_t w, size_t h);
}; };
#endif #endif

View File

@ -0,0 +1,963 @@
/*
Copyright (C) 2024 DeSmuME team
This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "OGLRender_ES3.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <sstream>
#include "utils/bits.h"
#include "common.h"
#include "debug.h"
#include "NDSSystem.h"
static const GLenum GeometryDrawBuffersEnumES[8][4] = {
{ OGL_COLOROUT_ATTACHMENT_ID, GL_NONE, GL_NONE, GL_NONE },
{ OGL_COLOROUT_ATTACHMENT_ID, GL_NONE, GL_NONE, OGL_FOGATTRIBUTES_ATTACHMENT_ID },
{ OGL_COLOROUT_ATTACHMENT_ID, GL_NONE, OGL_POLYID_ATTACHMENT_ID, GL_NONE },
{ OGL_COLOROUT_ATTACHMENT_ID, GL_NONE, OGL_POLYID_ATTACHMENT_ID, OGL_FOGATTRIBUTES_ATTACHMENT_ID },
{ OGL_COLOROUT_ATTACHMENT_ID, OGL_WORKING_ATTACHMENT_ID, GL_NONE, GL_NONE },
{ OGL_COLOROUT_ATTACHMENT_ID, OGL_WORKING_ATTACHMENT_ID, GL_NONE, OGL_FOGATTRIBUTES_ATTACHMENT_ID },
{ OGL_COLOROUT_ATTACHMENT_ID, OGL_WORKING_ATTACHMENT_ID, OGL_POLYID_ATTACHMENT_ID, GL_NONE },
{ OGL_COLOROUT_ATTACHMENT_ID, OGL_WORKING_ATTACHMENT_ID, OGL_POLYID_ATTACHMENT_ID, OGL_FOGATTRIBUTES_ATTACHMENT_ID }
};
static const GLint GeometryAttachmentWorkingBufferES[8] = { 1,1,1,1,1,1,1,1 };
static const GLint GeometryAttachmentPolyIDES[8] = { 2,2,2,2,2,2,2,2 };
static const GLint GeometryAttachmentFogAttributesES[8] = { 3,3,3,3,3,3,3,3 };
// Vertex shader for geometry, GLSL ES 3.00
static const char *GeometryVtxShader_ES300 = {"\
IN_VTX_POSITION vec4 inPosition;\n\
IN_VTX_TEXCOORD0 vec2 inTexCoord0;\n\
IN_VTX_COLOR vec3 inColor; \n\
\n\
#if IS_USING_UBO_POLY_STATES\n\
layout (std140) uniform PolyStates\n\
{\n\
ivec4 value[4096];\n\
} polyState;\n\
#elif IS_USING_TBO_POLY_STATES\n\
uniform highp isamplerBuffer PolyStates;\n\
#else\n\
uniform highp isampler2D PolyStates;\n\
#endif\n\
uniform mediump int polyIndex;\n\
uniform bool polyDrawShadow;\n\
\n\
out vec2 vtxTexCoord;\n\
out vec4 vtxColor;\n\
flat out lowp int polyID;\n\
flat out lowp int polyMode;\n\
flat out lowp int polyIsWireframe;\n\
flat out lowp int polyEnableFog;\n\
flat out lowp int polySetNewDepthForTranslucent;\n\
flat out lowp int polyEnableTexture;\n\
flat out lowp int texSingleBitAlpha;\n\
flat out lowp int polyIsBackFacing;\n\
flat out lowp int isPolyDrawable;\n\
\n\
void main()\n\
{\n\
#if IS_USING_UBO_POLY_STATES\n\
ivec4 polyStateVec = polyState.value[polyIndex >> 2];\n\
int polyStateBits = polyStateVec[polyIndex & 0x03];\n\
#elif IS_USING_TBO_POLY_STATES\n\
int polyStateBits = texelFetch(PolyStates, polyIndex).r;\n\
#else\n\
int polyStateBits = texelFetch(PolyStates, ivec2(polyIndex & 0x00FF, (polyIndex >> 8) & 0x007F), 0).r;\n\
#endif\n\
int texSizeShiftS = (polyStateBits >> 18) & 0x07;\n\
int texSizeShiftT = (polyStateBits >> 21) & 0x07;\n\
\n\
float polyAlpha = float((polyStateBits >> 8) & 0x1F) / 31.0;\n\
vec2 polyTexScale = vec2(1.0 / float(8 << texSizeShiftS), 1.0 / float(8 << texSizeShiftT));\n\
\n\
polyID = (polyStateBits >> 0) & 0x3F;\n\
polyMode = (polyStateBits >> 6) & 0x03;\n\
polyIsWireframe = (polyStateBits >> 13) & 0x01;\n\
polyEnableFog = (polyStateBits >> 14) & 0x01;\n\
polySetNewDepthForTranslucent = (polyStateBits >> 15) & 0x01;\n\
polyEnableTexture = (polyStateBits >> 16) & 0x01;\n\
texSingleBitAlpha = (polyStateBits >> 17) & 0x01;\n\
polyIsBackFacing = (polyStateBits >> 24) & 0x01;\n\
\n\
isPolyDrawable = int((polyMode != 3) || polyDrawShadow);\n\
\n\
mat2 texScaleMtx = mat2( vec2(polyTexScale.x, 0.0), \n\
vec2( 0.0, polyTexScale.y)); \n\
\n\
vtxTexCoord = (texScaleMtx * inTexCoord0) / 16.0;\n\
vtxColor = vec4(inColor / 63.0, polyAlpha);\n\
gl_Position = vec4(inPosition.x, -inPosition.y, inPosition.z, inPosition.w) / 4096.0;\n\
}\n\
"};
// Fragment shader for geometry, GLSL ES 3.00
static const char *GeometryFragShader_ES300 = {"\
in vec2 vtxTexCoord;\n\
in vec4 vtxColor;\n\
flat in lowp int polyID;\n\
flat in lowp int polyMode;\n\
flat in lowp int polyIsWireframe;\n\
flat in lowp int polyEnableFog;\n\
flat in lowp int polySetNewDepthForTranslucent;\n\
flat in lowp int polyEnableTexture;\n\
flat in lowp int texSingleBitAlpha;\n\
flat in lowp int polyIsBackFacing;\n\
flat in lowp int isPolyDrawable;\n\
\n\
layout (std140) uniform RenderStates\n\
{\n\
bool enableAntialiasing;\n\
bool enableFogAlphaOnly;\n\
int clearPolyID;\n\
float clearDepth;\n\
float alphaTestRef;\n\
float fogOffset;\n\
float fogStep;\n\
float pad_0;\n\
vec4 fogColor;\n\
vec4 edgeColor[8];\n\
vec4 toonColor[32];\n\
} state;\n\
\n\
uniform sampler2D texRenderObject;\n\
uniform bool texDrawOpaque;\n\
uniform bool drawModeDepthEqualsTest;\n\
uniform bool polyDrawShadow;\n\
uniform float polyDepthOffset;\n\
\n\
OUT_COLOR vec4 outFragColor;\n\
\n\
#if DRAW_MODE_OPAQUE\n\
OUT_WORKING_BUFFER vec4 outDstBackFacing;\n\
#elif USE_DEPTH_LEQUAL_POLYGON_FACING\n\
uniform sampler2D inDstBackFacing;\n\
#endif\n\
\n\
#if ENABLE_EDGE_MARK\n\
OUT_POLY_ID vec4 outPolyID;\n\
#endif\n\
#if ENABLE_FOG\n\
OUT_FOG_ATTRIBUTES vec4 outFogAttributes;\n\
#endif\n\
\n\
void main()\n\
{\n\
#if USE_DEPTH_LEQUAL_POLYGON_FACING && !DRAW_MODE_OPAQUE\n\
bool isOpaqueDstBackFacing = bool( texelFetch(inDstBackFacing, ivec2(gl_FragCoord.xy), 0).r );\n\
if ( drawModeDepthEqualsTest && (bool(polyIsBackFacing) || !isOpaqueDstBackFacing) )\n\
{\n\
discard;\n\
}\n\
#endif\n\
\n\
vec4 mainTexColor = (ENABLE_TEXTURE_SAMPLING && bool(polyEnableTexture)) ? texture(texRenderObject, vtxTexCoord) : vec4(1.0, 1.0, 1.0, 1.0);\n\
\n\
if (!bool(texSingleBitAlpha))\n\
{\n\
if (texDrawOpaque)\n\
{\n\
if ( (polyMode != 1) && (mainTexColor.a <= 0.999) )\n\
{\n\
discard;\n\
}\n\
}\n\
else\n\
{\n\
if ( ((polyMode != 1) && (mainTexColor.a * vtxColor.a > 0.999)) || ((polyMode == 1) && (vtxColor.a > 0.999)) )\n\
{\n\
discard;\n\
}\n\
}\n\
}\n\
#if USE_TEXTURE_SMOOTHING\n\
else\n\
{\n\
if (mainTexColor.a < 0.500)\n\
{\n\
mainTexColor.a = 0.0;\n\
}\n\
else\n\
{\n\
mainTexColor.rgb = mainTexColor.rgb / mainTexColor.a;\n\
mainTexColor.a = 1.0;\n\
}\n\
}\n\
#endif\n\
\n\
outFragColor = mainTexColor * vtxColor;\n\
\n\
if (polyMode == 1)\n\
{\n\
outFragColor.rgb = (ENABLE_TEXTURE_SAMPLING && bool(polyEnableTexture)) ? mix(vtxColor.rgb, mainTexColor.rgb, mainTexColor.a) : vtxColor.rgb;\n\
outFragColor.a = vtxColor.a;\n\
}\n\
else if (polyMode == 2)\n\
{\n\
vec3 newToonColor = state.toonColor[int((vtxColor.r * 31.0) + 0.5)].rgb;\n\
#if TOON_SHADING_MODE\n\
outFragColor.rgb = min((mainTexColor.rgb * vtxColor.r) + newToonColor.rgb, 1.0);\n\
#else\n\
outFragColor.rgb = mainTexColor.rgb * newToonColor.rgb;\n\
#endif\n\
}\n\
else if ((polyMode == 3) && polyDrawShadow)\n\
{\n\
outFragColor = vtxColor;\n\
}\n\
\n\
if ( (isPolyDrawable != 0) && ((outFragColor.a < 0.001) || (ENABLE_ALPHA_TEST && outFragColor.a < state.alphaTestRef)) )\n\
{\n\
discard;\n\
}\n\
#if ENABLE_EDGE_MARK\n\
outPolyID = (isPolyDrawable != 0) ? vec4( float(polyID)/63.0, float(polyIsWireframe == 1), 0.0, float(outFragColor.a > 0.999) ) : vec4(0.0, 0.0, 0.0, 0.0);\n\
#endif\n\
#if ENABLE_FOG\n\
outFogAttributes = (isPolyDrawable != 0) ? vec4( float(polyEnableFog), 0.0, 0.0, float((outFragColor.a > 0.999) ? 1.0 : 0.5) ) : vec4(0.0, 0.0, 0.0, 0.0);\n\
#endif\n\
#if DRAW_MODE_OPAQUE\n\
outDstBackFacing = vec4(float(polyIsBackFacing), 0.0, 0.0, 1.0);\n\
#endif\n\
\n\
#if USE_NDS_DEPTH_CALCULATION || ENABLE_FOG\n\
// It is tempting to perform the NDS depth calculation in the vertex shader rather than in the fragment shader.\n\
// Resist this temptation! It is much more reliable to do the depth calculation in the fragment shader due to\n\
// subtle interpolation differences between various GPUs and/or drivers. If the depth calculation is not done\n\
// here, then it is very possible for the user to experience Z-fighting in certain rendering situations.\n\
\n\
#if ENABLE_W_DEPTH\n\
gl_FragDepth = clamp( ((1.0/gl_FragCoord.w) * (4096.0/16777215.0)) + polyDepthOffset, 0.0, 1.0 );\n\
#else\n\
// hack: when using z-depth, drop some LSBs so that the overworld map in Dragon Quest IV shows up correctly\n\
gl_FragDepth = clamp( (floor(gl_FragCoord.z * 4194303.0) * (4.0/16777215.0)) + polyDepthOffset, 0.0, 1.0 );\n\
#endif\n\
#endif\n\
}\n\
"};
void OGLLoadEntryPoints_ES_3_0()
{
OGLLoadEntryPoints_3_2();
}
void OGLCreateRenderer_ES_3_0(OpenGLRenderer **rendererPtr)
{
if (IsOpenGLDriverVersionSupported(3, 0, 0))
{
*rendererPtr = new OpenGLESRenderer_3_0;
(*rendererPtr)->SetVersion(3, 0, 0);
}
}
OpenGLESRenderer_3_0::OpenGLESRenderer_3_0()
{
_variantID = OpenGLVariantID_ES3_3_0;
_geometryDrawBuffersEnum = GeometryDrawBuffersEnumES;
_geometryAttachmentWorkingBuffer = GeometryAttachmentWorkingBufferES;
_geometryAttachmentPolyID = GeometryAttachmentPolyIDES;
_geometryAttachmentFogAttributes = GeometryAttachmentFogAttributesES;
ref->textureSrcTypeCIColor = GL_UNSIGNED_BYTE;
ref->textureSrcTypeCIFog = GL_UNSIGNED_BYTE;
ref->textureSrcTypeEdgeColor = GL_UNSIGNED_BYTE;
ref->textureSrcTypeToonTable = GL_UNSIGNED_BYTE;
}
Render3DError OpenGLESRenderer_3_0::InitExtensions()
{
OGLRenderRef &OGLRef = *this->ref;
Render3DError error = OGLERROR_NOERR;
// Get OpenGL extensions
std::set<std::string> oglExtensionSet;
this->GetExtensionSet(&oglExtensionSet);
// OpenGL ES 3.0 should fully support FBOs, so we don't need the default framebuffer.
// However, OpenGL ES has traditionally required some kind of surface buffer attached
// to the context before using it. We don't want it, nor would we ever use it here.
// Therefore, check if our context supports being surfaceless before doing anything else,
// as this works as a kind of compatibility check.
if (!this->IsExtensionPresent(&oglExtensionSet, "GL_OES_surfaceless_context"))
{
INFO("OpenGL ES: Client contexts are not expected to have any surfaces attached\n");
INFO(" to the default framebuffer. The fact that the context does not\n");
INFO(" work surfaceless may indicate an error in the context creation,\n");
INFO(" or that your platform's context creation is too old.\n");
error = OGLERROR_FEATURE_UNSUPPORTED;
return error;
}
// Mirrored Repeat Mode Support
OGLRef.stateTexMirroredRepeat = GL_MIRRORED_REPEAT;
// Blending Support
this->_isBlendFuncSeparateSupported = true;
this->_isBlendEquationSeparateSupported = true;
// Fixed locations in shaders are supported in ES 3.0 by default.
this->_isShaderFixedLocationSupported = true;
GLfloat maxAnisotropyOGL = 1.0f;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyOGL);
this->_deviceInfo.maxAnisotropy = (float)maxAnisotropyOGL;
// OpenGL ES 3.0 should be able to handle the GL_RGBA format in glReadPixels without any performance penalty.
OGLRef.readPixelsBestFormat = GL_RGBA;
OGLRef.readPixelsBestDataType = GL_UNSIGNED_BYTE;
this->_deviceInfo.isEdgeMarkSupported = true;
this->_deviceInfo.isFogSupported = true;
// Need to generate this texture first because FBO creation needs it.
// This texture is only required by shaders, and so if shader creation
// fails, then we can immediately delete this texture if an error occurs.
glGenTextures(1, &OGLRef.texFinalColorID);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FinalColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texFinalColorID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glActiveTexture(GL_TEXTURE0);
// OpenGL ES 3.0 should have all the necessary features to be able to flip and convert the framebuffer.
this->_willConvertFramebufferOnGPU = true;
this->_enableTextureSmoothing = CommonSettings.GFX3D_Renderer_TextureSmoothing;
this->_emulateShadowPolygon = CommonSettings.OpenGL_Emulation_ShadowPolygon;
this->_emulateSpecialZeroAlphaBlending = CommonSettings.OpenGL_Emulation_SpecialZeroAlphaBlending;
this->_emulateNDSDepthCalculation = CommonSettings.OpenGL_Emulation_NDSDepthCalculation;
this->_emulateDepthLEqualPolygonFacing = CommonSettings.OpenGL_Emulation_DepthLEqualPolygonFacing;
// Load and create shaders. Return on any error, since ES 3.0 makes shaders mandatory.
this->isShaderSupported = true;
this->_rsResource = new OpenGLRenderStatesResource();
if (IsOpenGLDriverVersionSupported(3, 2, 0))
{
this->_gResource = new OpenGLGeometryResource(OpenGLVariantID_ES3_3_2);
}
else if (IsOpenGLDriverVersionSupported(3, 1, 0))
{
this->_gResource = new OpenGLGeometryResource(OpenGLVariantID_ES3_3_1);
}
else
{
this->_gResource = new OpenGLGeometryResource(OpenGLVariantID_ES3_3_0);
}
error = this->CreateGeometryPrograms();
if (error != OGLERROR_NOERR)
{
glUseProgram(0);
this->DestroyGeometryPrograms();
this->isShaderSupported = false;
return error;
}
error = this->CreateClearImageProgram(ClearImageVtxShader_150, ClearImageFragShader_150);
if (error != OGLERROR_NOERR)
{
glUseProgram(0);
this->DestroyGeometryPrograms();
this->isShaderSupported = false;
return error;
}
error = this->CreateGeometryZeroDstAlphaProgram(GeometryZeroDstAlphaPixelMaskVtxShader_150, GeometryZeroDstAlphaPixelMaskFragShader_150);
if (error != OGLERROR_NOERR)
{
glUseProgram(0);
this->DestroyGeometryPrograms();
this->DestroyClearImageProgram();
this->isShaderSupported = false;
return error;
}
INFO("OpenGL ES: Successfully created geometry shaders.\n");
error = this->InitPostprocessingPrograms(EdgeMarkVtxShader_150,
EdgeMarkFragShader_150,
FramebufferOutputVtxShader_150,
FramebufferOutput6665FragShader_150,
NULL);
if (error != OGLERROR_NOERR)
{
glUseProgram(0);
this->DestroyGeometryPrograms();
this->DestroyClearImageProgram();
this->DestroyGeometryZeroDstAlphaProgram();
this->isShaderSupported = false;
return error;
}
this->isVBOSupported = true;
this->CreateVBOs();
// PBOs are only used when reading back the rendered framebuffer for the emulated
// BG0 layer. For desktop-class GPUs, doing an asynchronous glReadPixels() call
// is always advantageous since such devices are expected to have their GPUs
// connected to a data bus.
//
// However, many ARM-based mobile devices use integrated GPUs of varying degrees
// of memory latency and implementation quality. This means that the performance
// of an asynchronous glReadPixels() call is NOT guaranteed on such devices.
//
// In fact, many ARM-based devices suffer devastating performance drops when trying
// to do asynchronous framebuffer reads. Therefore, since most OpenGL ES users will
// be running an ARM-based iGPU, we will disable PBOs for OpenGL ES and stick with
// a traditional synchronous glReadPixels() call instead.
this->isPBOSupported = false;
this->isVAOSupported = true;
this->CreateVAOs();
// Load and create FBOs. Return on any error, since OpenGL ES 3.0 includes FBOs as core functionality.
this->isFBOSupported = true;
error = this->CreateFBOs();
if (error != OGLERROR_NOERR)
{
this->isFBOSupported = false;
return error;
}
this->_isFBOBlitSupported = true;
this->isMultisampledFBOSupported = true;
this->_selectedMultisampleSize = CommonSettings.GFX3D_Renderer_MultisampleSize;
GLint maxSamplesOGL = 0;
glGetIntegerv(GL_MAX_SAMPLES, &maxSamplesOGL);
this->_deviceInfo.maxSamples = (u8)maxSamplesOGL;
if (this->_deviceInfo.maxSamples >= 2)
{
// Try and initialize the multisampled FBOs with the GFX3D_Renderer_MultisampleSize.
// However, if the client has this set to 0, then set sampleSize to 2 in order to
// force the generation and the attachments of the buffers at a meaningful sample
// size. If GFX3D_Renderer_MultisampleSize is 0, then we can deallocate the buffer
// memory afterwards.
GLsizei sampleSize = this->GetLimitedMultisampleSize();
if (sampleSize == 0)
{
sampleSize = 2;
}
error = this->CreateMultisampledFBO(sampleSize);
if (error != OGLERROR_NOERR)
{
this->isMultisampledFBOSupported = false;
}
// If GFX3D_Renderer_MultisampleSize is 0, then we can deallocate the buffers now
// in order to save some memory.
if (this->_selectedMultisampleSize == 0)
{
this->ResizeMultisampledFBOs(0);
}
}
else
{
this->isMultisampledFBOSupported = false;
INFO("OpenGL ES: Driver does not support at least 2x multisampled FBOs.\n");
}
this->_isDepthLEqualPolygonFacingSupported = true;
this->_enableMultisampledRendering = ((this->_selectedMultisampleSize >= 2) && this->isMultisampledFBOSupported);
return OGLERROR_NOERR;
}
Render3DError OpenGLESRenderer_3_0::CreateGeometryPrograms()
{
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
// Create shader resources.
glGenTextures(1, &OGLRef.texFogDensityTableID);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_LookupTable);
glBindTexture(GL_TEXTURE_2D, OGLRef.texFogDensityTableID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 32, 1, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
glActiveTexture(GL_TEXTURE0);
OGLGeometryFlags programFlags;
programFlags.value = 0;
std::stringstream shaderHeader;
shaderHeader << "#version 300 es\n";
shaderHeader << "precision highp float;\n";
shaderHeader << "precision highp int;\n";
shaderHeader << "\n";
std::stringstream vsHeader;
vsHeader << "#define IN_VTX_POSITION layout (location = " << OGLVertexAttributeID_Position << ") in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
vsHeader << "#define IN_VTX_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
vsHeader << "\n";
vsHeader << "#define IS_USING_UBO_POLY_STATES " << ((this->_gResource->IsPolyStatesBufferUBO()) ? 1 : 0) << "\n";
vsHeader << "#define IS_USING_TBO_POLY_STATES " << ((this->_gResource->IsPolyStatesBufferTBO()) ? 1 : 0) << "\n";
vsHeader << "#define DEPTH_EQUALS_TEST_TOLERANCE " << DEPTH_EQUALS_TEST_TOLERANCE << ".0\n";
vsHeader << "\n";
std::string vtxShaderCode = shaderHeader.str() + vsHeader.str() + std::string(GeometryVtxShader_ES300);
for (size_t flagsValue = 0; flagsValue < 128; flagsValue++, programFlags.value++)
{
std::stringstream shaderFlags;
shaderFlags << "#define OUT_COLOR layout (location = 0) out\n";
shaderFlags << "#define OUT_WORKING_BUFFER layout (location = " << (OGL_WORKING_ATTACHMENT_ID - GL_COLOR_ATTACHMENT0) << ") out\n";
shaderFlags << "#define OUT_POLY_ID layout (location = " << (OGL_POLYID_ATTACHMENT_ID - GL_COLOR_ATTACHMENT0) << ") out\n";
shaderFlags << "#define OUT_FOG_ATTRIBUTES layout (location = " << (OGL_FOGATTRIBUTES_ATTACHMENT_ID - GL_COLOR_ATTACHMENT0) << ") out\n";
shaderFlags << "\n";
shaderFlags << "#define USE_TEXTURE_SMOOTHING " << ((this->_enableTextureSmoothing) ? 1 : 0) << "\n";
shaderFlags << "#define USE_NDS_DEPTH_CALCULATION " << ((this->_emulateNDSDepthCalculation) ? 1 : 0) << "\n";
shaderFlags << "#define USE_DEPTH_LEQUAL_POLYGON_FACING " << ((this->_emulateDepthLEqualPolygonFacing) ? 1 : 0) << "\n";
shaderFlags << "\n";
shaderFlags << "#define ENABLE_W_DEPTH " << ((programFlags.EnableWDepth) ? 1 : 0) << "\n";
shaderFlags << "#define ENABLE_ALPHA_TEST " << ((programFlags.EnableAlphaTest) ? "true\n" : "false\n");
shaderFlags << "#define ENABLE_TEXTURE_SAMPLING " << ((programFlags.EnableTextureSampling) ? "true\n" : "false\n");
shaderFlags << "#define TOON_SHADING_MODE " << ((programFlags.ToonShadingMode) ? 1 : 0) << "\n";
shaderFlags << "#define ENABLE_FOG " << ((programFlags.EnableFog) ? 1 : 0) << "\n";
shaderFlags << "#define ENABLE_EDGE_MARK " << ((programFlags.EnableEdgeMark) ? 1 : 0) << "\n";
shaderFlags << "#define DRAW_MODE_OPAQUE " << ((programFlags.OpaqueDrawMode) ? 1 : 0) << "\n";
shaderFlags << "\n";
std::string fragShaderCode = shaderHeader.str() + shaderFlags.str() + std::string(GeometryFragShader_ES300);
error = this->ShaderProgramCreate(OGLRef.vertexGeometryShaderID,
OGLRef.fragmentGeometryShaderID[flagsValue],
OGLRef.programGeometryID[flagsValue],
vtxShaderCode.c_str(),
fragShaderCode.c_str());
if (error != OGLERROR_NOERR)
{
INFO("OpenGL ES: Failed to create the GEOMETRY shader program.\n");
glUseProgram(0);
this->DestroyGeometryPrograms();
return error;
}
glLinkProgram(OGLRef.programGeometryID[flagsValue]);
if (!this->ValidateShaderProgramLink(OGLRef.programGeometryID[flagsValue]))
{
INFO("OpenGL ES: Failed to link the GEOMETRY shader program.\n");
glUseProgram(0);
this->DestroyGeometryPrograms();
return OGLERROR_SHADER_CREATE_ERROR;
}
glValidateProgram(OGLRef.programGeometryID[flagsValue]);
glUseProgram(OGLRef.programGeometryID[flagsValue]);
// Set up render states UBO
const GLuint uniformBlockRenderStates = glGetUniformBlockIndex(OGLRef.programGeometryID[flagsValue], "RenderStates");
glUniformBlockBinding(OGLRef.programGeometryID[flagsValue], uniformBlockRenderStates, OGLBindingPointID_RenderStates);
GLint uboSize = 0;
glGetActiveUniformBlockiv(OGLRef.programGeometryID[flagsValue], uniformBlockRenderStates, GL_UNIFORM_BLOCK_DATA_SIZE, &uboSize);
assert(uboSize == sizeof(OGLRenderStates));
const GLint uniformTexRenderObject = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "texRenderObject");
glUniform1i(uniformTexRenderObject, 0);
if (this->_gResource->IsPolyStatesBufferUBO())
{
const GLuint uniformBlockPolyStates = glGetUniformBlockIndex(OGLRef.programGeometryID[flagsValue], "PolyStates");
glUniformBlockBinding(OGLRef.programGeometryID[flagsValue], uniformBlockPolyStates, OGLBindingPointID_PolyStates);
}
else
{
const GLint uniformTexBufferPolyStates = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "PolyStates");
glUniform1i(uniformTexBufferPolyStates, OGLTextureUnitID_PolyStates);
}
if (this->_emulateDepthLEqualPolygonFacing && !programFlags.OpaqueDrawMode)
{
const GLint uniformTexBackfacing = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "inDstBackFacing");
glUniform1i(uniformTexBackfacing, OGLTextureUnitID_FinalColor);
}
OGLRef.uniformTexDrawOpaque[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "texDrawOpaque");
OGLRef.uniformDrawModeDepthEqualsTest[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "drawModeDepthEqualsTest");
OGLRef.uniformPolyDrawShadow[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "polyDrawShadow");
OGLRef.uniformPolyStateIndex[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "polyIndex");
OGLRef.uniformPolyDepthOffset[flagsValue] = glGetUniformLocation(OGLRef.programGeometryID[flagsValue], "polyDepthOffset");
}
return error;
}
Render3DError OpenGLESRenderer_3_0::CreateClearImageProgram(const char *vsCString, const char *fsCString)
{
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
std::stringstream shaderHeader;
shaderHeader << "#version 300 es\n";
shaderHeader << "precision highp float;\n";
shaderHeader << "precision highp int;\n";
shaderHeader << "\n";
std::stringstream vsHeader;
if (this->_isShaderFixedLocationSupported)
{
vsHeader << "#define IN_VTX_POSITION layout (location = " << OGLVertexAttributeID_Position << ") in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
}
else
{
vsHeader << "#define IN_VTX_POSITION in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 in\n";
}
vsHeader << "\n";
std::string vtxShaderCode = shaderHeader.str() + vsHeader.str() + std::string(vsCString);
std::stringstream fsHeader;
if (this->_isShaderFixedLocationSupported)
{
fsHeader << "#define OUT_COLOR layout (location = 0) out\n";
fsHeader << "#define OUT_FOGATTR layout (location = 1) out\n";
}
else
{
fsHeader << "#define OUT_COLOR out\n";
fsHeader << "#define OUT_FOGATTR out\n";
}
fsHeader << "\n";
std::string fragShaderCodeFogColor = shaderHeader.str() + fsHeader.str() + std::string(fsCString);
error = this->ShaderProgramCreate(OGLRef.vsClearImageID,
OGLRef.fsClearImageID,
OGLRef.pgClearImageID,
vtxShaderCode.c_str(),
fragShaderCodeFogColor.c_str());
if (error != OGLERROR_NOERR)
{
INFO("OpenGL ES: Failed to create the CLEAR_IMAGE shader program.\n");
glUseProgram(0);
this->DestroyClearImageProgram();
return error;
}
glLinkProgram(OGLRef.pgClearImageID);
if (!this->ValidateShaderProgramLink(OGLRef.pgClearImageID))
{
INFO("OpenGL ES: Failed to link the CLEAR_IMAGE shader color/fog program.\n");
glUseProgram(0);
this->DestroyClearImageProgram();
return OGLERROR_SHADER_CREATE_ERROR;
}
glValidateProgram(OGLRef.pgClearImageID);
glUseProgram(OGLRef.pgClearImageID);
const GLint uniformTexCIColor = glGetUniformLocation(OGLRef.pgClearImageID, "texCIColor");
const GLint uniformTexCIFogAttr = glGetUniformLocation(OGLRef.pgClearImageID, "texCIFogAttr");
const GLint uniformTexCIDepthCF = glGetUniformLocation(OGLRef.pgClearImageID, "texCIDepth");
glUniform1i(uniformTexCIColor, OGLTextureUnitID_CIColor);
glUniform1i(uniformTexCIFogAttr, OGLTextureUnitID_CIFogAttr);
glUniform1i(uniformTexCIDepthCF, OGLTextureUnitID_CIDepth);
return error;
}
Render3DError OpenGLESRenderer_3_0::CreateGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString)
{
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
if ( (vtxShaderCString == NULL) || (fragShaderCString == NULL) )
{
return error;
}
std::stringstream shaderHeader;
shaderHeader << "#version 300 es\n";
shaderHeader << "precision highp float;\n";
shaderHeader << "precision highp int;\n";
shaderHeader << "\n";
std::stringstream vsHeader;
vsHeader << "#define IN_VTX_POSITION layout (location = " << OGLVertexAttributeID_Position << ") in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
vsHeader << "#define IN_VTX_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
std::string vtxShaderCode = shaderHeader.str() + vsHeader.str() + std::string(vtxShaderCString);
std::string fragShaderCode = shaderHeader.str() + std::string(fragShaderCString);
error = this->ShaderProgramCreate(OGLRef.vtxShaderGeometryZeroDstAlphaID,
OGLRef.fragShaderGeometryZeroDstAlphaID,
OGLRef.programGeometryZeroDstAlphaID,
vtxShaderCode.c_str(),
fragShaderCode.c_str());
if (error != OGLERROR_NOERR)
{
INFO("OpenGL ES: Failed to create the GEOMETRY ZERO DST ALPHA shader program.\n");
glUseProgram(0);
this->DestroyGeometryZeroDstAlphaProgram();
return error;
}
glLinkProgram(OGLRef.programGeometryZeroDstAlphaID);
if (!this->ValidateShaderProgramLink(OGLRef.programGeometryZeroDstAlphaID))
{
INFO("OpenGL ES: Failed to link the GEOMETRY ZERO DST ALPHA shader program.\n");
glUseProgram(0);
this->DestroyGeometryZeroDstAlphaProgram();
return OGLERROR_SHADER_CREATE_ERROR;
}
glValidateProgram(OGLRef.programGeometryZeroDstAlphaID);
glUseProgram(OGLRef.programGeometryZeroDstAlphaID);
const GLint uniformTexGColor = glGetUniformLocation(OGLRef.programGeometryZeroDstAlphaID, "texInFragColor");
glUniform1i(uniformTexGColor, OGLTextureUnitID_GColor);
return OGLERROR_NOERR;
}
Render3DError OpenGLESRenderer_3_0::CreateEdgeMarkProgram(const bool isMultisample, const char *vtxShaderCString, const char *fragShaderCString)
{
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
if ( (vtxShaderCString == NULL) || (fragShaderCString == NULL) )
{
return error;
}
std::stringstream shaderHeader;
shaderHeader << "#version 300 es\n";
shaderHeader << "precision highp float;\n";
shaderHeader << "precision highp int;\n";
shaderHeader << "\n";
shaderHeader << "#define FRAMEBUFFER_SIZE_X " << this->_framebufferWidth << ".0 \n";
shaderHeader << "#define FRAMEBUFFER_SIZE_Y " << this->_framebufferHeight << ".0 \n";
shaderHeader << "\n";
std::stringstream vsHeader;
vsHeader << "#define IN_VTX_POSITION layout (location = " << OGLVertexAttributeID_Position << ") in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
vsHeader << "#define IN_VTX_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
std::stringstream fsHeader;
fsHeader << "#define OUT_COLOR layout (location = 0) out\n";
std::string vtxShaderCode = shaderHeader.str() + vsHeader.str() + std::string(vtxShaderCString);
std::string fragShaderCode = shaderHeader.str() + fsHeader.str() + std::string(fragShaderCString);
error = this->ShaderProgramCreate(OGLRef.vertexEdgeMarkShaderID,
OGLRef.fragmentEdgeMarkShaderID,
OGLRef.programEdgeMarkID,
vtxShaderCode.c_str(),
fragShaderCode.c_str());
if (error != OGLERROR_NOERR)
{
INFO("OpenGL ES: Failed to create the EDGE MARK shader program.\n");
glUseProgram(0);
this->DestroyEdgeMarkProgram();
return error;
}
glLinkProgram(OGLRef.programEdgeMarkID);
if (!this->ValidateShaderProgramLink(OGLRef.programEdgeMarkID))
{
INFO("OpenGL ES: Failed to link the EDGE MARK shader program.\n");
glUseProgram(0);
this->DestroyEdgeMarkProgram();
return OGLERROR_SHADER_CREATE_ERROR;
}
glValidateProgram(OGLRef.programEdgeMarkID);
glUseProgram(OGLRef.programEdgeMarkID);
const GLuint uniformBlockRenderStates = glGetUniformBlockIndex(OGLRef.programEdgeMarkID, "RenderStates");
glUniformBlockBinding(OGLRef.programEdgeMarkID, uniformBlockRenderStates, OGLBindingPointID_RenderStates);
const GLint uniformTexGDepth = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInFragDepth");
const GLint uniformTexGPolyID = glGetUniformLocation(OGLRef.programEdgeMarkID, "texInPolyID");
glUniform1i(uniformTexGDepth, OGLTextureUnitID_DepthStencil);
glUniform1i(uniformTexGPolyID, OGLTextureUnitID_GPolyID);
return OGLERROR_NOERR;
}
Render3DError OpenGLESRenderer_3_0::CreateFogProgram(const OGLFogProgramKey fogProgramKey, const bool isMultisample, const char *vtxShaderCString, const char *fragShaderCString)
{
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
if (vtxShaderCString == NULL)
{
INFO("OpenGL ES: The FOG vertex shader is unavailable.\n");
error = OGLERROR_VERTEX_SHADER_PROGRAM_LOAD_ERROR;
return error;
}
else if (fragShaderCString == NULL)
{
INFO("OpenGL ES: The FOG fragment shader is unavailable.\n");
error = OGLERROR_FRAGMENT_SHADER_PROGRAM_LOAD_ERROR;
return error;
}
const s32 fogOffset = fogProgramKey.offset;
const GLfloat fogOffsetf = (GLfloat)fogOffset / 32767.0f;
const s32 fogStep = 0x0400 >> fogProgramKey.shift;
std::stringstream shaderHeader;
shaderHeader << "#version 300 es\n";
shaderHeader << "precision highp float;\n";
shaderHeader << "precision highp int;\n";
shaderHeader << "\n";
std::stringstream vsHeader;
vsHeader << "#define IN_VTX_POSITION layout (location = " << OGLVertexAttributeID_Position << ") in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
vsHeader << "#define IN_VTX_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
std::stringstream fsHeader;
fsHeader << "#define FOG_OFFSET " << fogOffset << "\n";
fsHeader << "#define FOG_OFFSETF " << fogOffsetf << (((fogOffsetf == 0.0f) || (fogOffsetf == 1.0f)) ? ".0" : "") << "\n";
fsHeader << "#define FOG_STEP " << fogStep << "\n";
fsHeader << "\n";
fsHeader << "#define OUT_COLOR layout (location = 0) out\n";
std::string vtxShaderCode = shaderHeader.str() + vsHeader.str() + std::string(vtxShaderCString);
std::string fragShaderCode = shaderHeader.str() + fsHeader.str() + std::string(fragShaderCString);
OGLFogShaderID shaderID;
shaderID.program = 0;
shaderID.fragShader = 0;
error = this->ShaderProgramCreate(OGLRef.vertexFogShaderID,
shaderID.fragShader,
shaderID.program,
vtxShaderCode.c_str(),
fragShaderCode.c_str());
this->_fogProgramMap[fogProgramKey.key] = shaderID;
if (error != OGLERROR_NOERR)
{
INFO("OpenGL ES: Failed to create the FOG shader program.\n");
glUseProgram(0);
this->DestroyFogProgram(fogProgramKey);
return error;
}
glLinkProgram(shaderID.program);
if (!this->ValidateShaderProgramLink(shaderID.program))
{
INFO("OpenGL ES: Failed to link the FOG shader program.\n");
glUseProgram(0);
this->DestroyFogProgram(fogProgramKey);
return OGLERROR_SHADER_CREATE_ERROR;
}
glValidateProgram(shaderID.program);
glUseProgram(shaderID.program);
const GLuint uniformBlockRenderStates = glGetUniformBlockIndex(shaderID.program, "RenderStates");
glUniformBlockBinding(shaderID.program, uniformBlockRenderStates, OGLBindingPointID_RenderStates);
const GLint uniformTexGDepth = glGetUniformLocation(shaderID.program, "texInFragDepth");
const GLint uniformTexGFog = glGetUniformLocation(shaderID.program, "texInFogAttributes");
const GLint uniformTexFogDensityTable = glGetUniformLocation(shaderID.program, "texFogDensityTable");
glUniform1i(uniformTexGDepth, OGLTextureUnitID_DepthStencil);
glUniform1i(uniformTexGFog, OGLTextureUnitID_FogAttr);
glUniform1i(uniformTexFogDensityTable, OGLTextureUnitID_LookupTable);
return OGLERROR_NOERR;
}
Render3DError OpenGLESRenderer_3_0::CreateFramebufferOutput6665Program(const char *vtxShaderCString, const char *fragShaderCString)
{
Render3DError error = OGLERROR_NOERR;
OGLRenderRef &OGLRef = *this->ref;
if ( (vtxShaderCString == NULL) || (fragShaderCString == NULL) )
{
return error;
}
std::stringstream shaderHeader;
shaderHeader << "#version 300 es\n";
shaderHeader << "precision highp float;\n";
shaderHeader << "precision highp int;\n";
shaderHeader << "\n";
shaderHeader << "#define FRAMEBUFFER_SIZE_X " << this->_framebufferWidth << ".0 \n";
shaderHeader << "#define FRAMEBUFFER_SIZE_Y " << this->_framebufferHeight << ".0 \n";
shaderHeader << "\n";
std::stringstream vsHeader;
vsHeader << "#define IN_VTX_POSITION layout (location = " << OGLVertexAttributeID_Position << ") in\n";
vsHeader << "#define IN_VTX_TEXCOORD0 layout (location = " << OGLVertexAttributeID_TexCoord0 << ") in\n";
vsHeader << "#define IN_VTX_COLOR layout (location = " << OGLVertexAttributeID_Color << ") in\n";
std::stringstream fsHeader;
fsHeader << "#define OUT_COLOR layout (location = " << (OGL_WORKING_ATTACHMENT_ID - GL_COLOR_ATTACHMENT0) << ") out\n";
std::string vtxShaderCode = shaderHeader.str() + vsHeader.str() + std::string(vtxShaderCString);
std::string fragShaderCode = shaderHeader.str() + fsHeader.str() + std::string(fragShaderCString);
error = this->ShaderProgramCreate(OGLRef.vertexFramebufferOutput6665ShaderID,
OGLRef.fragmentFramebufferRGBA6665OutputShaderID,
OGLRef.programFramebufferRGBA6665OutputID,
vtxShaderCode.c_str(),
fragShaderCode.c_str());
if (error != OGLERROR_NOERR)
{
INFO("OpenGL ES: Failed to create the FRAMEBUFFER OUTPUT RGBA6665 shader program.\n");
glUseProgram(0);
this->DestroyFramebufferOutput6665Programs();
return error;
}
glLinkProgram(OGLRef.programFramebufferRGBA6665OutputID);
if (!this->ValidateShaderProgramLink(OGLRef.programFramebufferRGBA6665OutputID))
{
INFO("OpenGL ES: Failed to link the FRAMEBUFFER OUTPUT RGBA6665 shader program.\n");
glUseProgram(0);
this->DestroyFramebufferOutput6665Programs();
return OGLERROR_SHADER_CREATE_ERROR;
}
glValidateProgram(OGLRef.programFramebufferRGBA6665OutputID);
glUseProgram(OGLRef.programFramebufferRGBA6665OutputID);
const GLint uniformTexGColor = glGetUniformLocation(OGLRef.programFramebufferRGBA6665OutputID, "texInFragColor");
glUniform1i(uniformTexGColor, OGLTextureUnitID_GColor);
return OGLERROR_NOERR;
}

View File

@ -0,0 +1,59 @@
/*
Copyright (C) 2024 DeSmuME team
This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OGLRENDER_ES3_H
#define OGLRENDER_ES3_H
#include "OGLRender_3_2.h"
// A port that wants to use the OpenGL ES renderer must assign the two following functions
// to OGLLoadEntryPoints_ES_3_0_Func and OGLCreateRenderer_ES_3_0_Func, respectively.
//
// In addition, the port must add the following GPU3DInterface objects to core3DList:
// - gpu3Dgl_ES_3_0: Selects the OpenGL ES 3.0 renderer, and returns an error if it is
// not available on the host system.
//
// Finally, the port must call GPU->Set3DRendererByID() and pass in the index where
// gpu3Dgl_ES_3_0 exists in core3DList so that the emulator can create the appropriate
// OpenGLRenderer object.
//
// Example code:
// OGLLoadEntryPoints_ES_3_0_Func = &OGLLoadEntryPoints_ES_3_0;
// OGLCreateRenderer_ES_3_0_Func = &OGLCreateRenderer_ES_3_0;
// GPU3DInterface *core3DList[] = { &gpu3DNull, &gpu3DRasterize, &gpu3Dgl_ES_3_0, NULL };
// GPU->Set3DRendererByID(2);
void OGLLoadEntryPoints_ES_3_0();
void OGLCreateRenderer_ES_3_0(OpenGLRenderer **rendererPtr);
class OpenGLESRenderer_3_0 : public OpenGLRenderer_3_2
{
protected:
virtual Render3DError CreateGeometryPrograms();
virtual Render3DError CreateClearImageProgram(const char *vsCString, const char *fsCString);
virtual Render3DError CreateGeometryZeroDstAlphaProgram(const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateEdgeMarkProgram(const bool isMultisample, const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateFogProgram(const OGLFogProgramKey fogProgramKey, const bool isMultisample, const char *vtxShaderCString, const char *fragShaderCString);
virtual Render3DError CreateFramebufferOutput6665Program(const char *vtxShaderCString, const char *fragShaderCString);
public:
OpenGLESRenderer_3_0();
virtual Render3DError InitExtensions();
};
#endif // OGLRENDER_ES3_H

View File

@ -79,7 +79,7 @@ struct STDROMReaderData
void* STDROMReaderInit(const char* filename) void* STDROMReaderInit(const char* filename)
{ {
#ifndef _MSC_VER #if !defined(_MSC_VER) && !defined(__MINGW32__)
struct stat sb; struct stat sb;
if (stat(filename, &sb) == -1) if (stat(filename, &sb) == -1)
return 0; return 0;
@ -348,7 +348,7 @@ int MemROMReaderWrite(void * file, void * buffer, u32 size)
if(remain<todo) if(remain<todo)
todo = remain; todo = remain;
if(todo==1) *(u8*)buffer = ((u8*)mem.buf)[mem.pos]; if (todo == 1) ((u8*)mem.buf)[mem.pos] = *(u8*)buffer;
else memcpy((u8*)mem.buf + mem.pos,buffer, todo); else memcpy((u8*)mem.buf + mem.pos,buffer, todo);
mem.pos += todo; mem.pos += todo;
return todo; return todo;

View File

@ -1,7 +1,7 @@
/* /*
Copyright (C) 2006 yopyop Copyright (C) 2006 yopyop
Copyright (C) 2006 Theo Berkau Copyright (C) 2006 Theo Berkau
Copyright (C) 2008-2021 DeSmuME team Copyright (C) 2008-2025 DeSmuME team
Ideas borrowed from Stephane Dallongeville's SCSP core Ideas borrowed from Stephane Dallongeville's SCSP core
@ -49,7 +49,14 @@ static inline u8 read08(u32 addr) { return _MMU_read08<ARMCPU_ARM7,MMU_AT_DEBUG>
static inline s8 read_s8(u32 addr) { return (s8)_MMU_read08<ARMCPU_ARM7,MMU_AT_DEBUG>(addr); } static inline s8 read_s8(u32 addr) { return (s8)_MMU_read08<ARMCPU_ARM7,MMU_AT_DEBUG>(addr); }
#define K_ADPCM_LOOPING_RECOVERY_INDEX 99999 #define K_ADPCM_LOOPING_RECOVERY_INDEX 99999
#define COSINE_INTERPOLATION_RESOLUTION 8192
#define CATMULLROM_INTERPOLATION_RESOLUTION_BITS 11
#define CATMULLROM_INTERPOLATION_RESOLUTION (1<<CATMULLROM_INTERPOLATION_RESOLUTION_BITS)
#define COSINE_INTERPOLATION_RESOLUTION_BITS 13
#define COSINE_INTERPOLATION_RESOLUTION (1<<COSINE_INTERPOLATION_RESOLUTION_BITS)
#define SPUCHAN_PCM16B_AT(x) ((u32)(x) % SPUINTERPOLATION_TAPS)
//#ifdef FASTBUILD //#ifdef FASTBUILD
#undef FORCEINLINE #undef FORCEINLINE
@ -96,20 +103,10 @@ static const u16 adpcmtbl[89] =
0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF 0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF
}; };
static const s16 wavedutytbl[8][8] = {
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF },
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF },
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
{ -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
{ -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
{ -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF }
};
static s32 precalcdifftbl[89][16]; static s32 precalcdifftbl[89][16];
static u8 precalcindextbl[89][8]; static u8 precalcindextbl[89][8];
static double cos_lut[COSINE_INTERPOLATION_RESOLUTION]; static u16 catmullrom_lut[CATMULLROM_INTERPOLATION_RESOLUTION][4];
static u16 cos_lut[COSINE_INTERPOLATION_RESOLUTION];
static const double ARM7_CLOCK = 33513982; static const double ARM7_CLOCK = 33513982;
@ -129,6 +126,14 @@ static FORCEINLINE T MinMax(T val, T min, T max)
return val; return val;
} }
// T must be unsigned type
template<typename T>
static FORCEINLINE T AddAndReturnCarry(T *a, T b) {
T c = (*a >= (-b));
*a += b;
return c;
}
//--------------external spu interface--------------- //--------------external spu interface---------------
int SPU_ChangeSoundCore(int coreid, int newBufferSizeBytes) int SPU_ChangeSoundCore(int coreid, int newBufferSizeBytes)
@ -171,7 +176,7 @@ int SPU_ChangeSoundCore(int coreid, int newBufferSizeBytes)
return -1; return -1;
// Since it failed, instead of it being fatal, disable the user spu // Since it failed, instead of it being fatal, disable the user spu
if (_currentSNDCore->Init(_currentBufferSize * 2) == -1) if (_currentSNDCore->Init((int)(_currentBufferSize * 2)) == -1)
{ {
_currentSNDCore = 0; _currentSNDCore = 0;
return -1; return -1;
@ -191,7 +196,7 @@ SoundInterface_struct *SPU_SoundCore()
void SPU_ReInit(bool fakeBoot) void SPU_ReInit(bool fakeBoot)
{ {
SPU_Init(_currentSNDCoreId, _currentBufferSize); SPU_Init(_currentSNDCoreId, (int)_currentBufferSize);
// Firmware set BIAS to 0x200 // Firmware set BIAS to 0x200
if (fakeBoot) if (fakeBoot)
@ -200,9 +205,23 @@ void SPU_ReInit(bool fakeBoot)
int SPU_Init(int coreid, int newBufferSizeBytes) int SPU_Init(int coreid, int newBufferSizeBytes)
{ {
// Build the cosine interpolation LUT // Build the interpolation LUTs
for (size_t i = 0; i < CATMULLROM_INTERPOLATION_RESOLUTION; i++) {
// This is the Catmull-Rom spline, refactored into a FIR filter
// If we wanted to, we could stick entirely to integer maths
// here, but I doubt it's worth the hassle.
double x = i / (double)CATMULLROM_INTERPOLATION_RESOLUTION;
double a = x*(x*(-x + 2) - 1);
double b = x*x*(3*x - 5) + 2;
double c = x*(x*(-3*x + 4) + 1);
double d = x*x*(x - 1);
catmullrom_lut[i][0] = (u16)floor((1u<<15) * -0.5*a);
catmullrom_lut[i][1] = (u16)floor((1u<<15) * 0.5*b);
catmullrom_lut[i][2] = (u16)floor((1u<<15) * 0.5*c);
catmullrom_lut[i][3] = (u16)floor((1u<<15) * -0.5*d);
}
for (size_t i = 0; i < COSINE_INTERPOLATION_RESOLUTION; i++) for (size_t i = 0; i < COSINE_INTERPOLATION_RESOLUTION; i++)
cos_lut[i] = (1.0 - cos(((double)i/(double)COSINE_INTERPOLATION_RESOLUTION) * M_PI)) * 0.5; cos_lut[i] = (u16)floor((1u<<16) * ((1.0 - cos(((double)i/(double)COSINE_INTERPOLATION_RESOLUTION) * M_PI)) * 0.5));
SPU_core = new SPU_struct((int)ceil(samples_per_hline)); SPU_core = new SPU_struct((int)ceil(samples_per_hline));
SPU_Reset(); SPU_Reset();
@ -266,7 +285,7 @@ void SPU_SetSynchMode(int mode, int method)
if (_currentSynchMode == ESynchMode_DualSynchAsynch) if (_currentSynchMode == ESynchMode_DualSynchAsynch)
{ {
SPU_user = new SPU_struct(_currentBufferSize); SPU_user = new SPU_struct((int)_currentBufferSize);
SPU_CloneUser(); SPU_CloneUser();
} }
} }
@ -366,7 +385,11 @@ void SPU_struct::ShutUp()
static FORCEINLINE void adjust_channel_timer(channel_struct *chan) static FORCEINLINE void adjust_channel_timer(channel_struct *chan)
{ {
chan->sampinc = (((double)ARM7_CLOCK) / (DESMUME_SAMPLE_RATE * 2)) / (double)(0x10000 - chan->timer); // ARM7_CLOCK / (DESMUME_SAMPLE_RATE*2) / (2^16 - Timer)
// = ARM7_CLOCK / (DESMUME_SAMPLE_RATE*2 * (2^16 - Timer))
// ... and then round up for good measure
u64 sampinc = ((u32)ARM7_CLOCK*(1ull << 32) - 1) / (DESMUME_SAMPLE_RATE * 2ull * (0x10000 - chan->timer)) + 1;
chan->sampincInt = (u32)(sampinc >> 32), chan->sampincFrac = (u32)sampinc;
} }
void SPU_struct::KeyProbe(int chan_num) void SPU_struct::KeyProbe(int chan_num)
@ -399,6 +422,12 @@ void SPU_struct::KeyOn(int channel)
thischan.totlength = thischan.length + thischan.loopstart; thischan.totlength = thischan.length + thischan.loopstart;
adjust_channel_timer(&thischan); adjust_channel_timer(&thischan);
thischan.pcm16bOffs = 0;
for(int i=0;i<SPUINTERPOLATION_TAPS;i++)
{
thischan.pcm16b[i] = 0;
}
//printf("keyon %d totlength:%d\n",channel,thischan.totlength); //printf("keyon %d totlength:%d\n",channel,thischan.totlength);
@ -411,39 +440,33 @@ void SPU_struct::KeyOn(int channel)
case 0: // 8-bit case 0: // 8-bit
// thischan.loopstart = thischan.loopstart << 2; // thischan.loopstart = thischan.loopstart << 2;
// thischan.length = (thischan.length << 2) + thischan.loopstart; // thischan.length = (thischan.length << 2) + thischan.loopstart;
thischan.sampcnt = -3; thischan.sampcntFrac = 0, thischan.sampcntInt = -3;
break; break;
case 1: // 16-bit case 1: // 16-bit
// thischan.loopstart = thischan.loopstart << 1; // thischan.loopstart = thischan.loopstart << 1;
// thischan.length = (thischan.length << 1) + thischan.loopstart; // thischan.length = (thischan.length << 1) + thischan.loopstart;
thischan.sampcnt = -3; thischan.sampcntFrac = 0, thischan.sampcntInt = -3;
break; break;
case 2: // ADPCM case 2: // ADPCM
{ thischan.pcm16b[0] = (s16)read16(thischan.addr);
thischan.pcm16b = (s16)read16(thischan.addr); thischan.index = read08(thischan.addr + 2) & 0x7F;
thischan.pcm16b_last = thischan.pcm16b; thischan.sampcntFrac = 0, thischan.sampcntInt = -3;
thischan.index = read08(thischan.addr + 2) & 0x7F;; thischan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX;
thischan.lastsampcnt = 7; // thischan.loopstart = thischan.loopstart << 3;
thischan.sampcnt = -3; // thischan.length = (thischan.length << 3) + thischan.loopstart;
thischan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX; break;
// thischan.loopstart = thischan.loopstart << 3;
// thischan.length = (thischan.length << 3) + thischan.loopstart;
break;
}
case 3: // PSG case 3: // PSG
{ thischan.sampcntFrac = 0, thischan.sampcntInt = -1;
thischan.sampcnt = -1; thischan.x = 0x7FFF;
thischan.x = 0x7FFF; break;
break;
}
default: break; default: break;
} }
thischan.double_totlength_shifted = (double)(thischan.totlength << format_shift[thischan.format]); thischan.totlength_shifted = thischan.totlength << format_shift[thischan.format];
if(thischan.format != 3) if(thischan.format != 3)
{ {
if(thischan.double_totlength_shifted == 0) if(thischan.totlength_shifted == 0)
{ {
printf("INFO: Stopping channel %d due to zero length\n",channel); printf("INFO: Stopping channel %d due to zero length\n",channel);
thischan.status = CHANSTAT_STOPPED; thischan.status = CHANSTAT_STOPPED;
@ -493,7 +516,7 @@ u8 SPU_struct::ReadByte(u32 addr)
//SOUNDBIAS //SOUNDBIAS
case 0x504: return regs.soundbias >> 0; case 0x504: return regs.soundbias >> 0;
case 0x505: return regs.soundbias >> 8; case 0x505: return regs.soundbias >> 8;
//SNDCAP0CNT/SNDCAP1CNT //SNDCAP0CNT/SNDCAP1CNT
case 0x508: case 0x508:
case 0x509: case 0x509:
@ -742,7 +765,7 @@ void SPU_struct::ProbeCapture(int which)
u32 len = cap.len; u32 len = cap.len;
if(len==0) len=1; if(len==0) len=1;
cap.runtime.maxdad = cap.dad + len*4; cap.runtime.maxdad = cap.dad + len*4;
cap.runtime.sampcnt = 0; cap.runtime.sampcntFrac = cap.runtime.sampcntInt = 0;
cap.runtime.fifo.reset(); cap.runtime.fifo.reset();
} }
@ -1018,161 +1041,109 @@ void SPU_struct::WriteLong(u32 addr, u32 val)
} //switch on address } //switch on address
} }
template<SPUInterpolationMode INTERPOLATE_MODE> static FORCEINLINE s32 Interpolate(s32 a, s32 b, double ratio) //////////////////////////////////////////////////////////////////////////////
template<SPUInterpolationMode INTERPOLATE_MODE> static FORCEINLINE s32 Interpolate(const s16 *pcm16b, u8 pcm16bOffs, u32 subPos)
{ {
double sampleA = (double)a;
double sampleB = (double)b;
ratio = ratio - sputrunc(ratio);
switch (INTERPOLATE_MODE) switch (INTERPOLATE_MODE)
{ {
case SPUInterpolation_CatmullRom:
{
// Catmull-Rom spline
// Delay: 2 samples, Maximum gain: 1.25
s32 a = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 3)];
s32 b = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 2)];
s32 c = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 1)];
s32 d = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 0)];
const u16 *w = catmullrom_lut[subPos >> (32 - CATMULLROM_INTERPOLATION_RESOLUTION_BITS)];
return (-a*(s32)w[0] + b*(s32)w[1] + c*(s32)w[2] - d*(s32)w[3]) >> 15;
}
case SPUInterpolation_Cosine: case SPUInterpolation_Cosine:
{
// Cosine Interpolation Formula: // Cosine Interpolation Formula:
// ratio2 = (1 - cos(ratio * M_PI)) / 2 // ratio2 = (1 - cos(ratio * M_PI)) / 2
// sampleI = sampleA * (1 - ratio2) + sampleB * ratio2 // sampleI = sampleA * (1 - ratio2) + sampleB * ratio2
return s32floor((cos_lut[(unsigned int)(ratio * (double)COSINE_INTERPOLATION_RESOLUTION)] * (sampleB - sampleA)) + sampleA); // Delay: 1 sample, Maximum gain: 1.0
break; s32 a = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 1)];
s32 b = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 0)];
s32 subPos16 = (s32)cos_lut[subPos >> (32 - COSINE_INTERPOLATION_RESOLUTION_BITS)];
return a + ((b - a)*subPos16 >> 16);
}
case SPUInterpolation_Linear: case SPUInterpolation_Linear:
{
// Linear Interpolation Formula: // Linear Interpolation Formula:
// sampleI = sampleA * (1 - ratio) + sampleB * ratio // sampleI = sampleA * (1 - ratio) + sampleB * ratio
return s32floor((ratio * (sampleB - sampleA)) + sampleA); // Delay: 1 sample, Maximum gain: 1.0
break; s32 a = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 1)];
s32 b = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 0)];
s32 subPos16 = subPos >> (32 - 16);
return a + ((b - a)*subPos16 >> 16);
}
default: default:
break; // Delay: 0 samples, Maximum gain: 1.0
return pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs)];
}
}
static FORCEINLINE s32 Fetch8BitData(channel_struct *chan, s32 pos)
{
if(pos < 0) return 0;
return read_s8(chan->addr + pos*1) << 8;
}
static FORCEINLINE s32 Fetch16BitData(channel_struct *chan, s32 pos)
{
if(pos < 0) return 0;
return read16(chan->addr + pos*2);
}
static FORCEINLINE s32 FetchADPCMData(channel_struct *chan, s32 pos)
{
if(pos < 8) return 0;
s16 last = chan->pcm16b[SPUCHAN_PCM16B_AT(chan->pcm16bOffs)];
if(pos == (chan->loopstart<<3)) {
//if(chan->loop_index != K_ADPCM_LOOPING_RECOVERY_INDEX) printf("over-snagging\n");
chan->loop_pcm16b = last;
chan->loop_index = chan->index;
} }
return a; const u32 shift = (pos&1) * 4;
const u32 data4bit = ((u32)read08(chan->addr + (pos>>1))) >> shift;
const s32 diff = precalcdifftbl [chan->index][data4bit & 0xF];
chan->index = precalcindextbl[chan->index][data4bit & 0x7];
return MinMax(last + diff, -0x8000, 0x7FFF);
} }
////////////////////////////////////////////////////////////////////////////// static FORCEINLINE s32 FetchPSGData(channel_struct *chan, s32 pos)
template<SPUInterpolationMode INTERPOLATE_MODE> static FORCEINLINE void Fetch8BitData(channel_struct *chan, s32 *data)
{ {
if (chan->sampcnt < 0) if(pos < 0 || chan->num < 8) return 0;
{
*data = 0;
return;
}
u32 loc = sputrunc(chan->sampcnt); // Chan 8..13: Square wave, Chan 14..15: Noise
if(INTERPOLATE_MODE != SPUInterpolation_None) if(chan->num < 14)
{ {
s32 a = (s32)(read_s8(chan->addr + loc) << 8), b = a; // Doing this avoids using a LUT
if(loc < (chan->totlength << 2) - 1) return ((pos%8u) > chan->waveduty) ? (-0x7FFF) : (+0x7FFF);
b = (s32)(read_s8(chan->addr + loc + 1) << 8);
else if(chan->repeat == 1)
b = (s32)(read_s8(chan->addr + chan->loopstart*4) << 8);
*data = Interpolate<INTERPOLATE_MODE>(a, b, chan->sampcnt);
} }
else else
*data = (s32)read_s8(chan->addr + loc)<< 8;
}
template<SPUInterpolationMode INTERPOLATE_MODE> static FORCEINLINE void Fetch16BitData(const channel_struct * const chan, s32 *data)
{
if (chan->sampcnt < 0)
{ {
*data = 0; if(chan->x & 0x1)
return;
}
u32 loc = sputrunc(chan->sampcnt);
if(INTERPOLATE_MODE != SPUInterpolation_None)
{
s32 a = (s32)read16(loc*2 + chan->addr), b = a;
if(loc < (chan->totlength << 1) - 1)
b = (s32)read16(chan->addr + loc*2 + 2);
else if(chan->repeat == 1)
b = (s32)read16(chan->addr + chan->loopstart*2);
*data = Interpolate<INTERPOLATE_MODE>(a, b, chan->sampcnt);
}
else
*data = read16(chan->addr + loc*2);
}
template<SPUInterpolationMode INTERPOLATE_MODE> static FORCEINLINE void FetchADPCMData(channel_struct * const chan, s32 * const data)
{
if (chan->sampcnt < 8)
{
*data = 0;
return;
}
// No sense decoding, just return the last sample
if (chan->lastsampcnt != sputrunc(chan->sampcnt)){
const u32 endExclusive = sputrunc(chan->sampcnt+1);
for (u32 i = chan->lastsampcnt+1; i < endExclusive; i++)
{ {
const u32 shift = (i&1)<<2; chan->x = (chan->x >> 1) ^ 0x6000;
const u32 data4bit = ((u32)read08(chan->addr + (i>>1))) >> shift; return -0x7FFF;
const s32 diff = precalcdifftbl[chan->index][data4bit & 0xF];
chan->index = precalcindextbl[chan->index][data4bit & 0x7];
chan->pcm16b_last = chan->pcm16b;
chan->pcm16b = MinMax(chan->pcm16b+diff, -0x8000, 0x7FFF);
if(i == (chan->loopstart<<3)) {
if(chan->loop_index != K_ADPCM_LOOPING_RECOVERY_INDEX) printf("over-snagging\n");
chan->loop_pcm16b = chan->pcm16b;
chan->loop_index = chan->index;
}
} }
else
chan->lastsampcnt = sputrunc(chan->sampcnt);
}
if(INTERPOLATE_MODE != SPUInterpolation_None)
*data = Interpolate<INTERPOLATE_MODE>((s32)chan->pcm16b_last,(s32)chan->pcm16b,chan->sampcnt);
else
*data = (s32)chan->pcm16b;
}
static FORCEINLINE void FetchPSGData(channel_struct *chan, s32 *data)
{
if (chan->sampcnt < 0)
{
*data = 0;
return;
}
if(chan->num < 8)
{
*data = 0;
}
else if(chan->num < 14)
{
*data = (s32)wavedutytbl[chan->waveduty][(sputrunc(chan->sampcnt)) & 0x7];
}
else
{
if(chan->lastsampcnt == sputrunc(chan->sampcnt))
{ {
*data = (s32)chan->psgnoise_last; chan->x >>= 1;
return; return +0x7FFF;
} }
u32 max = sputrunc(chan->sampcnt);
for(u32 i = chan->lastsampcnt; i < max; i++)
{
if(chan->x & 0x1)
{
chan->x = (chan->x >> 1) ^ 0x6000;
chan->psgnoise_last = -0x7FFF;
}
else
{
chan->x >>= 1;
chan->psgnoise_last = 0x7FFF;
}
}
chan->lastsampcnt = sputrunc(chan->sampcnt);
*data = (s32)chan->psgnoise_last;
} }
} }
@ -1201,66 +1172,41 @@ static FORCEINLINE void MixLR(SPU_struct* SPU, channel_struct *chan, s32 data)
template<int FORMAT> static FORCEINLINE void TestForLoop(SPU_struct *SPU, channel_struct *chan) template<int FORMAT> static FORCEINLINE void TestForLoop(SPU_struct *SPU, channel_struct *chan)
{ {
const int shift = (FORMAT == 0 ? 2 : 1); // Do nothing if we haven't reached the end
if(chan->sampcntInt < chan->totlength_shifted) return;
chan->sampcnt += chan->sampinc; // Kill the channel if we don't repeat
if(chan->repeat != 1)
if (chan->sampcnt > chan->double_totlength_shifted)
{ {
// Do we loop? Or are we done? SPU->KeyOff(chan->num);
if (chan->repeat == 1) return;
}
// ADPCM needs special handling
if(FORMAT == 2)
{
// Minimum length (the sum of PNT+LEN) is 4 words (16 bytes),
// smaller values (0..3 words) are causing hang-ups
// (busy bit remains set infinite, but no sound output occurs).
// fix: 7th Dragon (JP) - http://sourceforge.net/p/desmume/bugs/1357/
if (chan->totlength < 4) return;
// Stash loop sample and index
if(chan->loop_index == K_ADPCM_LOOPING_RECOVERY_INDEX)
{ {
while (chan->sampcnt > chan->double_totlength_shifted) chan->pcm16b[SPUCHAN_PCM16B_AT(chan->pcm16bOffs)] = (s16)read16(chan->addr);
chan->sampcnt -= chan->double_totlength_shifted - (double)(chan->loopstart << shift); chan->index = read08(chan->addr+2) & 0x7F;
//chan->sampcnt = (double)(chan->loopstart << shift);
} }
else else
{ {
SPU->KeyOff(chan->num); chan->pcm16b[SPUCHAN_PCM16B_AT(chan->pcm16bOffs)] = chan->loop_pcm16b;
SPU->bufpos = SPU->buflength; chan->index = chan->loop_index;
} }
} }
}
static FORCEINLINE void TestForLoop2(SPU_struct *SPU, channel_struct *chan) // Wrap sampcnt
{ u32 step = chan->totlength_shifted - (chan->loopstart << format_shift[FORMAT]);
// Minimum length (the sum of PNT+LEN) is 4 words (16 bytes), while (chan->sampcntInt >= chan->totlength_shifted) chan->sampcntInt -= step;
// smaller values (0..3 words) are causing hang-ups
// (busy bit remains set infinite, but no sound output occurs).
// fix: 7th Dragon (JP) - http://sourceforge.net/p/desmume/bugs/1357/
if (chan->totlength < 4) return;
chan->sampcnt += chan->sampinc;
if (chan->sampcnt > chan->double_totlength_shifted)
{
// Do we loop? Or are we done?
if (chan->repeat == 1)
{
double step = (chan->double_totlength_shifted - (double)(chan->loopstart << 3));
while (chan->sampcnt > chan->double_totlength_shifted) chan->sampcnt -= step;
if(chan->loop_index == K_ADPCM_LOOPING_RECOVERY_INDEX)
{
chan->pcm16b = (s16)read16(chan->addr);
chan->index = read08(chan->addr+2) & 0x7F;
chan->lastsampcnt = 7;
}
else
{
chan->pcm16b = chan->loop_pcm16b;
chan->index = chan->loop_index;
chan->lastsampcnt = (chan->loopstart << 3);
}
}
else
{
chan->status = CHANSTAT_STOPPED;
SPU->KeyOff(chan->num);
SPU->bufpos = SPU->buflength;
}
}
} }
template<int CHANNELS> FORCEINLINE static void SPU_Mix(SPU_struct* SPU, channel_struct *chan, s32 data) template<int CHANNELS> FORCEINLINE static void SPU_Mix(SPU_struct* SPU, channel_struct *chan, s32 data)
@ -1281,25 +1227,35 @@ template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, int CHANNELS>
{ {
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++) for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
{ {
if(CHANNELS != -1) // Advance sampcnt one sample at a time. This is
// needed to keep pcm16b[] filled for interpolation.
u32 nSamplesToSkip = chan->sampincInt + AddAndReturnCarry(&chan->sampcntFrac, chan->sampincFrac);
while(nSamplesToSkip--)
{ {
s32 data; s16 data = 0;
switch(FORMAT) s32 pos = chan->sampcntInt;
if(chan->status != CHANSTAT_STOPPED)
{ {
case 0: Fetch8BitData<INTERPOLATE_MODE>(chan, &data); break; switch(FORMAT)
case 1: Fetch16BitData<INTERPOLATE_MODE>(chan, &data); break; {
case 2: FetchADPCMData<INTERPOLATE_MODE>(chan, &data); break; case 0: data = Fetch8BitData (chan, pos); break;
case 3: FetchPSGData(chan, &data); break; case 1: data = Fetch16BitData(chan, pos); break;
default: break; case 2: data = FetchADPCMData(chan, pos); break;
case 3: data = FetchPSGData (chan, pos); break;
default: break;
}
} }
SPU_Mix<CHANNELS>(SPU, chan, data); chan->pcm16bOffs++;
chan->pcm16b[SPUCHAN_PCM16B_AT(chan->pcm16bOffs)] = data;
chan->sampcntInt++;
if (FORMAT != 3) TestForLoop<FORMAT>(SPU, chan);
} }
switch(FORMAT) { if(CHANNELS != -1)
case 0: case 1: TestForLoop<FORMAT>(SPU, chan); break; {
case 2: TestForLoop2(SPU, chan); break; s32 data = Interpolate<INTERPOLATE_MODE>(chan->pcm16b, chan->pcm16bOffs, chan->sampcntFrac);
case 3: chan->sampcnt += chan->sampinc; break; SPU_Mix<CHANNELS>(SPU, chan, data);
default: break;
} }
} }
} }
@ -1320,12 +1276,14 @@ template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE>
template<SPUInterpolationMode INTERPOLATE_MODE> template<SPUInterpolationMode INTERPOLATE_MODE>
FORCEINLINE static void __SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan) FORCEINLINE static void __SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan)
{ {
// NOTE: PSG doesn't use interpolation, or it would try to
// interpolate between the raw sample points (very bad)
switch(chan->format) switch(chan->format)
{ {
case 0: ___SPU_ChanUpdate<0,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break; case 0: ___SPU_ChanUpdate<0,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
case 1: ___SPU_ChanUpdate<1,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break; case 1: ___SPU_ChanUpdate<1,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
case 2: ___SPU_ChanUpdate<2,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break; case 2: ___SPU_ChanUpdate<2,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
case 3: ___SPU_ChanUpdate<3,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break; case 3: ___SPU_ChanUpdate<3,SPUInterpolation_None>(actuallyMix, SPU, chan); break;
default: assert(false); default: assert(false);
} }
} }
@ -1334,9 +1292,10 @@ FORCEINLINE static void _SPU_ChanUpdate(const bool actuallyMix, SPU_struct* cons
{ {
switch(CommonSettings.spuInterpolationMode) switch(CommonSettings.spuInterpolationMode)
{ {
case SPUInterpolation_None: __SPU_ChanUpdate<SPUInterpolation_None>(actuallyMix, SPU, chan); break; case SPUInterpolation_None: __SPU_ChanUpdate<SPUInterpolation_None>(actuallyMix, SPU, chan); break;
case SPUInterpolation_Linear: __SPU_ChanUpdate<SPUInterpolation_Linear>(actuallyMix, SPU, chan); break; case SPUInterpolation_Linear: __SPU_ChanUpdate<SPUInterpolation_Linear>(actuallyMix, SPU, chan); break;
case SPUInterpolation_Cosine: __SPU_ChanUpdate<SPUInterpolation_Cosine>(actuallyMix, SPU, chan); break; case SPUInterpolation_Cosine: __SPU_ChanUpdate<SPUInterpolation_Cosine>(actuallyMix, SPU, chan); break;
case SPUInterpolation_CatmullRom: __SPU_ChanUpdate<SPUInterpolation_CatmullRom>(actuallyMix, SPU, chan); break;
default: assert(false); default: assert(false);
} }
} }
@ -1487,13 +1446,13 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
for (int capchan = 0; capchan < 2; capchan++) for (int capchan = 0; capchan < 2; capchan++)
{ {
SPU_struct::REGS::CAP& cap = SPU->regs.cap[capchan];
channel_struct& srcChan = SPU->channels[1 + 2 * capchan];
if (SPU->regs.cap[capchan].runtime.running) if (SPU->regs.cap[capchan].runtime.running)
{ {
SPU_struct::REGS::CAP& cap = SPU->regs.cap[capchan]; u32 nSamplesToProcess = srcChan.sampincInt + AddAndReturnCarry(&cap.runtime.sampcntFrac, srcChan.sampincFrac);
u32 last = sputrunc(cap.runtime.sampcnt); cap.runtime.sampcntInt += nSamplesToProcess;
cap.runtime.sampcnt += SPU->channels[1+2*capchan].sampinc; while(nSamplesToProcess--)
u32 curr = sputrunc(cap.runtime.sampcnt);
for (u32 j = last; j < curr; j++)
{ {
//so, this is a little strange. why go through a fifo? //so, this is a little strange. why go through a fifo?
//it seems that some games will set up a reverb effect by capturing //it seems that some games will set up a reverb effect by capturing
@ -1544,7 +1503,7 @@ static void SPU_MixAudio_Advanced(bool actuallyMix, SPU_struct *SPU, int length)
if (cap.runtime.curdad >= cap.runtime.maxdad) if (cap.runtime.curdad >= cap.runtime.maxdad)
{ {
cap.runtime.curdad = cap.dad; cap.runtime.curdad = cap.dad;
cap.runtime.sampcnt -= cap.len*multiplier; cap.runtime.sampcntInt -= cap.len*multiplier;
} }
} //sampinc loop } //sampinc loop
} //if capchan running } //if capchan running
@ -1604,14 +1563,14 @@ static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length)
for (int capchan = 0; capchan < 2; capchan++) for (int capchan = 0; capchan < 2; capchan++)
{ {
SPU_struct::REGS::CAP& cap = SPU->regs.cap[capchan]; SPU_struct::REGS::CAP& cap = SPU->regs.cap[capchan];
channel_struct& srcChan = SPU->channels[1 + 2 * capchan];
if (cap.runtime.running) if (cap.runtime.running)
{ {
for (int samp = 0; samp < length; samp++) for (int samp = 0; samp < length; samp++)
{ {
u32 last = sputrunc(cap.runtime.sampcnt); u32 nSamplesToProcess = srcChan.sampincInt + AddAndReturnCarry(&cap.runtime.sampcntFrac, srcChan.sampincFrac);
cap.runtime.sampcnt += SPU->channels[1+2*capchan].sampinc; cap.runtime.sampcntInt += nSamplesToProcess;
u32 curr = sputrunc(cap.runtime.sampcnt); while (nSamplesToProcess--)
for (u32 j = last; j < curr; j++)
{ {
if (cap.bits8) if (cap.bits8)
{ {
@ -1627,7 +1586,7 @@ static void SPU_MixAudio(bool actuallyMix, SPU_struct *SPU, int length)
if (cap.runtime.curdad >= cap.runtime.maxdad) if (cap.runtime.curdad >= cap.runtime.maxdad)
{ {
cap.runtime.curdad = cap.dad; cap.runtime.curdad = cap.dad;
cap.runtime.sampcnt -= cap.len*(cap.bits8?4:2); cap.runtime.sampcntInt -= cap.len*(cap.bits8?4:2);
} }
} }
} }
@ -1733,7 +1692,7 @@ void SPU_Emulate_user(bool mix)
postProcessBufferSize = freeSampleCount * 2 * sizeof(s16); postProcessBufferSize = freeSampleCount * 2 * sizeof(s16);
postProcessBuffer = (s16 *)realloc(postProcessBuffer, postProcessBufferSize); postProcessBuffer = (s16 *)realloc(postProcessBuffer, postProcessBufferSize);
} }
if (soundProcessor->PostProcessSamples != NULL) if (soundProcessor->PostProcessSamples != NULL)
{ {
processedSampleCount = soundProcessor->PostProcessSamples(postProcessBuffer, freeSampleCount, _currentSynchMode, _currentSynchronizer); processedSampleCount = soundProcessor->PostProcessSamples(postProcessBuffer, freeSampleCount, _currentSynchMode, _currentSynchronizer);
@ -1743,15 +1702,15 @@ void SPU_Emulate_user(bool mix)
processedSampleCount = SPU_DefaultPostProcessSamples(postProcessBuffer, freeSampleCount, _currentSynchMode, _currentSynchronizer); processedSampleCount = SPU_DefaultPostProcessSamples(postProcessBuffer, freeSampleCount, _currentSynchMode, _currentSynchronizer);
} }
soundProcessor->UpdateAudio(postProcessBuffer, processedSampleCount); soundProcessor->UpdateAudio(postProcessBuffer, (u32)processedSampleCount);
WAV_WavSoundUpdate(postProcessBuffer, processedSampleCount, WAVMODE_USER); WAV_WavSoundUpdate(postProcessBuffer, (int)processedSampleCount, WAVMODE_USER);
} }
void SPU_DefaultFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer) void SPU_DefaultFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer)
{ {
if (synchMode == ESynchMode_Synchronous) if (synchMode == ESynchMode_Synchronous)
{ {
theSynchronizer->enqueue_samples(sampleBuffer, sampleCount); theSynchronizer->enqueue_samples(sampleBuffer, (int)sampleCount);
} }
} }
@ -1764,14 +1723,14 @@ size_t SPU_DefaultPostProcessSamples(s16 *postProcessBuffer, size_t requestedSam
case ESynchMode_DualSynchAsynch: case ESynchMode_DualSynchAsynch:
if(SPU_user != NULL) if(SPU_user != NULL)
{ {
SPU_MixAudio(true, SPU_user, requestedSampleCount); SPU_MixAudio(true, SPU_user, (int)requestedSampleCount);
memcpy(postProcessBuffer, SPU_user->outbuf, requestedSampleCount * 2 * sizeof(s16)); memcpy(postProcessBuffer, SPU_user->outbuf, requestedSampleCount * 2 * sizeof(s16));
processedSampleCount = requestedSampleCount; processedSampleCount = requestedSampleCount;
} }
break; break;
case ESynchMode_Synchronous: case ESynchMode_Synchronous:
processedSampleCount = theSynchronizer->output_samples(postProcessBuffer, requestedSampleCount); processedSampleCount = theSynchronizer->output_samples(postProcessBuffer, (int)requestedSampleCount);
break; break;
default: default:
@ -1905,7 +1864,7 @@ void WavWriter::update(void* soundData, int numSamples)
{ {
if(!spufp) return; if(!spufp) return;
//TODO - big endian for the s16 samples?? //TODO - big endian for the s16 samples??
size_t elems_written = fwrite(soundData, numSamples*2, 2, spufp); fwrite(soundData, (size_t)(numSamples*2), 2, spufp);
} }
bool WavWriter::isRecording() const bool WavWriter::isRecording() const
@ -1913,7 +1872,6 @@ bool WavWriter::isRecording() const
return spufp != NULL; return spufp != NULL;
} }
static WavWriter wavWriter; static WavWriter wavWriter;
void WAV_End() void WAV_End()
@ -1957,7 +1915,7 @@ void WAV_WavSoundUpdate(void* soundData, int numSamples, WAVMode mode)
void spu_savestate(EMUFILE &os) void spu_savestate(EMUFILE &os)
{ {
//version //version
os.write_32LE(6); os.write_32LE(7);
SPU_struct *spu = SPU_core; SPU_struct *spu = SPU_core;
@ -1973,18 +1931,18 @@ void spu_savestate(EMUFILE &os)
os.write_u8(chan.repeat); os.write_u8(chan.repeat);
os.write_u8(chan.format); os.write_u8(chan.format);
os.write_u8(chan.status); os.write_u8(chan.status);
os.write_u8(chan.pcm16bOffs);
os.write_32LE(chan.addr); os.write_32LE(chan.addr);
os.write_16LE(chan.timer); os.write_16LE(chan.timer);
os.write_16LE(chan.loopstart); os.write_16LE(chan.loopstart);
os.write_32LE(chan.length); os.write_32LE(chan.length);
os.write_doubleLE(chan.sampcnt); os.write_32LE(chan.sampcntFrac);
os.write_doubleLE(chan.sampinc); os.write_32LE(chan.sampcntInt);
os.write_32LE(chan.lastsampcnt); os.write_32LE(chan.sampincFrac);
os.write_16LE(chan.pcm16b); os.write_32LE(chan.sampincInt);
os.write_16LE(chan.pcm16b_last); for (int i = 0; i < SPUINTERPOLATION_TAPS; i++) os.write_16LE(chan.pcm16b[i]);
os.write_32LE(chan.index); os.write_32LE(chan.index);
os.write_16LE(chan.x); os.write_16LE(chan.x);
os.write_16LE(chan.psgnoise_last);
os.write_u8(chan.keyon); os.write_u8(chan.keyon);
} }
@ -2010,7 +1968,8 @@ void spu_savestate(EMUFILE &os)
os.write_u8(spu->regs.cap[i].runtime.running); os.write_u8(spu->regs.cap[i].runtime.running);
os.write_32LE(spu->regs.cap[i].runtime.curdad); os.write_32LE(spu->regs.cap[i].runtime.curdad);
os.write_32LE(spu->regs.cap[i].runtime.maxdad); os.write_32LE(spu->regs.cap[i].runtime.maxdad);
os.write_doubleLE(spu->regs.cap[i].runtime.sampcnt); os.write_32LE(spu->regs.cap[i].runtime.sampcntFrac);
os.write_32LE(spu->regs.cap[i].runtime.sampcntInt);
} }
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
@ -2044,29 +2003,53 @@ bool spu_loadstate(EMUFILE &is, int size)
is.read_u8(chan.repeat); is.read_u8(chan.repeat);
is.read_u8(chan.format); is.read_u8(chan.format);
is.read_u8(chan.status); is.read_u8(chan.status);
if (version >= 7) is.read_u8(chan.pcm16bOffs); else chan.pcm16bOffs = 0;
is.read_32LE(chan.addr); is.read_32LE(chan.addr);
is.read_16LE(chan.timer); is.read_16LE(chan.timer);
is.read_16LE(chan.loopstart); is.read_16LE(chan.loopstart);
is.read_32LE(chan.length); is.read_32LE(chan.length);
chan.totlength = chan.length + chan.loopstart; chan.totlength = chan.length + chan.loopstart;
chan.double_totlength_shifted = (double)(chan.totlength << format_shift[chan.format]); chan.totlength_shifted = chan.totlength << format_shift[chan.format];
//printf("%f\n",chan.double_totlength_shifted); if(version >= 7) {
if (version >= 2) is.read_32LE(chan.sampcntFrac);
is.read_32LE(chan.sampcntInt);
is.read_32LE(chan.sampincFrac);
is.read_32LE(chan.sampincInt);
}
else if (version >= 2)
{ {
is.read_doubleLE(chan.sampcnt); double temp;
is.read_doubleLE(chan.sampinc); s64 temp2;
is.read_doubleLE(temp); temp2 = (s64)(temp * (1ll << 32));
chan.sampcntFrac = (u32)temp2;
chan.sampcntInt = (s32)(temp2 >> 32);
is.read_doubleLE(temp); temp2 = (u64)(temp * (1ull << 32)); // Intentionally unsigned
chan.sampincFrac = (u32)temp2;
chan.sampincInt = (u32)(temp2 >> 32);
} }
else else
{ {
is.read_32LE(*(u32 *)&chan.sampcnt); // FIXME
is.read_32LE(*(u32 *)&chan.sampinc); // What even is supposed to be happening here?
// sampcnt and sampinc were double type before
// I even made any changes, so this is broken.
chan.sampcntFrac = 0;
is.read_32LE(chan.sampcntInt);
chan.sampincFrac = 0;
is.read_32LE(chan.sampincInt);
}
if (version >= 7) {
for (int i = 0; i < SPUINTERPOLATION_TAPS; i++) is.read_16LE(chan.pcm16b[i]);
}
else
{
is.fseek(4, SEEK_CUR); // chan.lastsampcnt (LE32)
is.read_16LE(chan.pcm16b[0]); // chan.pcm16b
is.fseek(2, SEEK_CUR); // chan.pcm16b_last
} }
is.read_32LE(chan.lastsampcnt);
is.read_16LE(chan.pcm16b);
is.read_16LE(chan.pcm16b_last);
is.read_32LE(chan.index); is.read_32LE(chan.index);
is.read_16LE(chan.x); is.read_16LE(chan.x);
is.read_16LE(chan.psgnoise_last); if (version < 7) is.fseek(2, SEEK_CUR); // chan.psgnoise_last (LE16)
if (version >= 4) if (version >= 4)
is.read_u8(chan.keyon); is.read_u8(chan.keyon);
@ -2105,7 +2088,18 @@ bool spu_loadstate(EMUFILE &is, int size)
is.read_u8(spu->regs.cap[i].runtime.running); is.read_u8(spu->regs.cap[i].runtime.running);
is.read_32LE(spu->regs.cap[i].runtime.curdad); is.read_32LE(spu->regs.cap[i].runtime.curdad);
is.read_32LE(spu->regs.cap[i].runtime.maxdad); is.read_32LE(spu->regs.cap[i].runtime.maxdad);
is.read_doubleLE(spu->regs.cap[i].runtime.sampcnt); if (version >= 7) {
is.read_32LE(spu->regs.cap[i].runtime.sampcntFrac);
is.read_32LE(spu->regs.cap[i].runtime.sampcntInt);
}
else
{
double temp;
u64 temp2;
is.read_doubleLE(temp); temp2 = (u64)(temp * (1ull << 32));
spu->regs.cap[i].runtime.sampcntFrac = (u32)temp2;
spu->regs.cap[i].runtime.sampcntInt = (u32)(temp2 >> 32);
}
} }
} }

View File

@ -36,10 +36,9 @@ class EMUFILE;
#define CHANSTAT_STOPPED 0 #define CHANSTAT_STOPPED 0
#define CHANSTAT_PLAY 1 #define CHANSTAT_PLAY 1
#define SPUINTERPOLATION_TAPS 4 // Must be at least 4 for Catmull-Rom interpolation
//who made these static? theyre used in multiple places. //who made these static? theyre used in multiple places.
FORCEINLINE u32 sputrunc(float f) { return u32floor(f); }
FORCEINLINE u32 sputrunc(double d) { return u32floor(d); }
FORCEINLINE s32 spumuldiv7(s32 val, u8 multiplier) { FORCEINLINE s32 spumuldiv7(s32 val, u8 multiplier) {
assert(multiplier <= 127); assert(multiplier <= 127);
return (multiplier == 127) ? val : ((val * multiplier) >> 7); return (multiplier == 127) ? val : ((val * multiplier) >> 7);
@ -49,7 +48,8 @@ enum SPUInterpolationMode
{ {
SPUInterpolation_None = 0, SPUInterpolation_None = 0,
SPUInterpolation_Linear = 1, SPUInterpolation_Linear = 1,
SPUInterpolation_Cosine = 2 SPUInterpolation_Cosine = 2,
SPUInterpolation_CatmullRom = 3
}; };
struct SoundInterface_struct struct SoundInterface_struct
@ -84,22 +84,21 @@ struct channel_struct
format(0), format(0),
keyon(0), keyon(0),
status(0), status(0),
pcm16bOffs(0),
addr(0), addr(0),
timer(0), timer(0),
loopstart(0), loopstart(0),
length(0), length(0),
totlength(0), totlength(0),
double_totlength_shifted(0.0), totlength_shifted(0),
sampcnt(0.0), sampcntFrac(0),
sampinc(0.0), sampcntInt(0),
lastsampcnt(0), sampincFrac(0),
pcm16b(0), sampincInt(0),
pcm16b_last(0),
loop_pcm16b(0), loop_pcm16b(0),
index(0), index(0),
loop_index(0), loop_index(0),
x(0), x(0)
psgnoise_last(0)
{} {}
u32 num; u32 num;
u8 vol; u8 vol;
@ -111,22 +110,24 @@ struct channel_struct
u8 format; u8 format;
u8 keyon; u8 keyon;
u8 status; u8 status;
u8 pcm16bOffs;
u32 addr; u32 addr;
u16 timer; u16 timer;
u16 loopstart; u16 loopstart;
u32 length; u32 length;
u32 totlength; u32 totlength;
double double_totlength_shifted; s32 totlength_shifted;
double sampcnt; u32 sampcntFrac;
double sampinc; s32 sampcntInt;
u32 sampincFrac;
u32 sampincInt;
s16 pcm16b[SPUINTERPOLATION_TAPS];
// ADPCM specific // ADPCM specific
u32 lastsampcnt;
s16 pcm16b, pcm16b_last;
s16 loop_pcm16b; s16 loop_pcm16b;
s32 index; s32 index;
int loop_index; int loop_index;
// PSG noise
u16 x; u16 x;
s16 psgnoise_last;
}; };
class SPUFifo class SPUFifo
@ -196,7 +197,8 @@ public:
u8 running; u8 running;
u32 curdad; u32 curdad;
u32 maxdad; u32 maxdad;
double sampcnt; u32 sampcntFrac;
u32 sampcntInt;
SPUFifo fifo; SPUFifo fifo;
} runtime; } runtime;
} cap[2]; } cap[2];

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2013-2105 DeSmuME team Copyright (C) 2013-2015 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2013-2021 DeSmuME team Copyright (C) 2013-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -193,7 +193,7 @@ private:
if (fpROM) if (fpROM)
{ {
u32 data = 0; u32 data = 0;
u32 readed = fread(&data, 1, 4, fpROM); u32 readed = (u32)fread(&data, 1, 4, fpROM);
if (readed) if (readed)
{ {
rom.incAddress(); rom.incAddress();

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2013-2021 DeSmuME team Copyright (C) 2013-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -59,6 +59,8 @@ enum eSlot1Operation
class ISlot1Comp_Protocol_Client class ISlot1Comp_Protocol_Client
{ {
public: public:
virtual ~ISlot1Comp_Protocol_Client() {}
virtual void slot1client_startOperation(eSlot1Operation theOperation) {} virtual void slot1client_startOperation(eSlot1Operation theOperation) {}
virtual u32 slot1client_read_GCDATAIN(eSlot1Operation theOperation) = 0; virtual u32 slot1client_read_GCDATAIN(eSlot1Operation theOperation) = 0;
virtual void slot1client_write_GCDATAIN(eSlot1Operation theOperation, u32 val) {} virtual void slot1client_write_GCDATAIN(eSlot1Operation theOperation, u32 val) {}

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2009 CrazyMax Copyright (C) 2009 CrazyMax
Copyright (C) 2009-2021 DeSmuME team Copyright (C) 2009-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -65,7 +65,7 @@ private:
fROM->fseek(pos, SEEK_SET); fROM->fseek(pos, SEEK_SET);
u32 data = 0xFFFFFFFF; u32 data = 0xFFFFFFFF;
u32 readed = fROM->fread(&data, size); u32 readed = (u32)fROM->fread(&data, size);
return data; return data;
} }
@ -77,7 +77,7 @@ private:
fSRAM->fseek(pos, SEEK_SET); fSRAM->fseek(pos, SEEK_SET);
u32 data = 0xFFFFFFFF; u32 data = 0xFFFFFFFF;
u32 readed = fSRAM->fread(&data, size); u32 readed = (u32)fSRAM->fread(&data, size);
return data; return data;
} }
@ -107,7 +107,7 @@ private:
for(;;) for(;;)
{ {
u32 romType = 0; u32 romType = 0;
u32 readed = fROM->fread(&romType, 4); u32 readed = (u32)fROM->fread(&romType, 4);
int pos = fROM->ftell(); int pos = fROM->ftell();
int currPct = pos*100/(size-1); int currPct = pos*100/(size-1);

View File

@ -0,0 +1,87 @@
//HCV-1000 emulation code adapted from GBE+: https://github.com/shonumi/gbe-plus
/*
Modifications Copyright (C) 2023 DeSmuME team
This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "../slot2.h"
u8 hcv1000_cnt;
char hcv1000_data[16];
class Slot2_HCV1000 : public ISlot2Interface
{
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("Sega Card Reader", "Sega Card Reader(HCV-1000) add-on", 0x09);
return &info;
}
virtual bool init()
{
hcv1000_cnt = 0;
memset(hcv1000_data, 0x5F, 16);
return TRUE;
}
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val)
{
if (addr == 0xA000000) { hcv1000_cnt = (val & 0x83); }
}
virtual u8 readByte(u8 PROCNUM, u32 addr)
{
u8 slot_byte = 0xFF;
//Reading these cart addresses is for detection
if (addr < 0x8020000)
{
u8 data = 0xF0 | ((addr & 0x1F) >> 1);
slot_byte = (addr & 0x1) ? 0xFD : data;
}
//HCV_CNT
else if (addr == 0xA000000) { slot_byte = hcv1000_cnt; }
//HCV_DATA
else if ((addr >= 0xA000010) && (addr <= 0xA00001F))
{
slot_byte = (u8)hcv1000_data[addr & 0xF];
}
return slot_byte;
}
virtual u16 readWord(u8 PROCNUM, u32 addr) { return 0xFDFD; };
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xFDFDFDFD; };
};
ISlot2Interface* construct_Slot2_HCV1000() { return new Slot2_HCV1000(); }
void HCV1000_setReady()
{
hcv1000_cnt &= ~0x80;
}
void HCV1000_setBarcode(std::string barcode)
{
barcode.resize(16, '_');
memcpy(hcv1000_data, barcode.c_str(), barcode.length());
}

File diff suppressed because it is too large Load Diff

View File

@ -60,6 +60,7 @@
using namespace AsmJit; using namespace AsmJit;
#if (LOG_JIT_LEVEL > 0) #if (LOG_JIT_LEVEL > 0)
#include "../modules/Disassembler.h"
#define LOG_JIT 1 #define LOG_JIT 1
#define JIT_COMMENT(...) c.comment(__VA_ARGS__) #define JIT_COMMENT(...) c.comment(__VA_ARGS__)
#define printJIT(buf, val) { \ #define printJIT(buf, val) { \
@ -1529,7 +1530,7 @@ static int OP_MSR_SPSR_IMM_VAL(const u32 i) { OP_MSR_(SPSR, IMM_VAL, 0); }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// LDR // LDR
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
typedef u32 (FASTCALL* OpLDR)(u32, u32*); typedef u32 (DESMUME_FASTCALL* OpLDR)(u32, u32*);
// 98% of all memory accesses land in the same region as the first execution of // 98% of all memory accesses land in the same region as the first execution of
// that instruction, so keep multiple copies with different fastpaths. // that instruction, so keep multiple copies with different fastpaths.
@ -1560,7 +1561,7 @@ static u32 classify_adr(u32 adr, bool store)
} }
template<int PROCNUM, int memtype> template<int PROCNUM, int memtype>
static u32 FASTCALL OP_LDR(u32 adr, u32 *dstreg) static u32 DESMUME_FASTCALL OP_LDR(u32 adr, u32 *dstreg)
{ {
u32 data = READ32(cpu->mem_if->data, adr); u32 data = READ32(cpu->mem_if->data, adr);
if(adr&3) if(adr&3)
@ -1570,28 +1571,28 @@ static u32 FASTCALL OP_LDR(u32 adr, u32 *dstreg)
} }
template<int PROCNUM, int memtype> template<int PROCNUM, int memtype>
static u32 FASTCALL OP_LDRH(u32 adr, u32 *dstreg) static u32 DESMUME_FASTCALL OP_LDRH(u32 adr, u32 *dstreg)
{ {
*dstreg = READ16(cpu->mem_if->data, adr); *dstreg = READ16(cpu->mem_if->data, adr);
return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_READ>(3,adr); return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_READ>(3,adr);
} }
template<int PROCNUM, int memtype> template<int PROCNUM, int memtype>
static u32 FASTCALL OP_LDRSH(u32 adr, u32 *dstreg) static u32 DESMUME_FASTCALL OP_LDRSH(u32 adr, u32 *dstreg)
{ {
*dstreg = (s16)READ16(cpu->mem_if->data, adr); *dstreg = (s16)READ16(cpu->mem_if->data, adr);
return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_READ>(3,adr); return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_READ>(3,adr);
} }
template<int PROCNUM, int memtype> template<int PROCNUM, int memtype>
static u32 FASTCALL OP_LDRB(u32 adr, u32 *dstreg) static u32 DESMUME_FASTCALL OP_LDRB(u32 adr, u32 *dstreg)
{ {
*dstreg = READ8(cpu->mem_if->data, adr); *dstreg = READ8(cpu->mem_if->data, adr);
return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_READ>(3,adr); return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_READ>(3,adr);
} }
template<int PROCNUM, int memtype> template<int PROCNUM, int memtype>
static u32 FASTCALL OP_LDRSB(u32 adr, u32 *dstreg) static u32 DESMUME_FASTCALL OP_LDRSB(u32 adr, u32 *dstreg)
{ {
*dstreg = (s8)READ8(cpu->mem_if->data, adr); *dstreg = (s8)READ8(cpu->mem_if->data, adr);
return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_READ>(3,adr); return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_READ>(3,adr);
@ -1773,27 +1774,27 @@ static int OP_LDRSB_POS_INDE_M_REG_OFF(const u32 i) { OP_LDR_(LDRSB, REG_OFF, su
// STR // STR
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template<int PROCNUM, int memtype> template<int PROCNUM, int memtype>
static u32 FASTCALL OP_STR(u32 adr, u32 data) static u32 DESMUME_FASTCALL OP_STR(u32 adr, u32 data)
{ {
WRITE32(cpu->mem_if->data, adr, data); WRITE32(cpu->mem_if->data, adr, data);
return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_WRITE>(2,adr); return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_WRITE>(2,adr);
} }
template<int PROCNUM, int memtype> template<int PROCNUM, int memtype>
static u32 FASTCALL OP_STRH(u32 adr, u32 data) static u32 DESMUME_FASTCALL OP_STRH(u32 adr, u32 data)
{ {
WRITE16(cpu->mem_if->data, adr, data); WRITE16(cpu->mem_if->data, adr, data);
return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_WRITE>(2,adr); return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_WRITE>(2,adr);
} }
template<int PROCNUM, int memtype> template<int PROCNUM, int memtype>
static u32 FASTCALL OP_STRB(u32 adr, u32 data) static u32 DESMUME_FASTCALL OP_STRB(u32 adr, u32 data)
{ {
WRITE8(cpu->mem_if->data, adr, data); WRITE8(cpu->mem_if->data, adr, data);
return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_WRITE>(2,adr); return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_WRITE>(2,adr);
} }
typedef u32 (FASTCALL* OpSTR)(u32, u32); typedef u32 (DESMUME_FASTCALL* OpSTR)(u32, u32);
#define T(op) op<0,0>, op<0,1>, op<0,2>, op<1,0>, op<1,1>, NULL #define T(op) op<0,0>, op<0,1>, op<0,2>, op<1,0>, op<1,1>, NULL
static const OpSTR STR_tab[2][3] = { T(OP_STR) }; static const OpSTR STR_tab[2][3] = { T(OP_STR) };
static const OpSTR STRH_tab[2][3] = { T(OP_STRH) }; static const OpSTR STRH_tab[2][3] = { T(OP_STRH) };
@ -1912,9 +1913,9 @@ static int OP_STRB_M_ROR_IMM_OFF_POSTIND(const u32 i) { OP_STR_(STRB, ROR_IMM, s
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// LDRD / STRD // LDRD / STRD
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
typedef u32 FASTCALL (*LDRD_STRD_REG)(u32); typedef u32 DESMUME_FASTCALL (*LDRD_STRD_REG)(u32);
template<int PROCNUM, u8 Rnum> template<int PROCNUM, u8 Rnum>
static u32 FASTCALL OP_LDRD_REG(u32 adr) static u32 DESMUME_FASTCALL OP_LDRD_REG(u32 adr)
{ {
cpu->R[Rnum] = READ32(cpu->mem_if->data, adr); cpu->R[Rnum] = READ32(cpu->mem_if->data, adr);
@ -1928,7 +1929,7 @@ static u32 FASTCALL OP_LDRD_REG(u32 adr)
return MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(adr); return MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(adr);
} }
template<int PROCNUM, u8 Rnum> template<int PROCNUM, u8 Rnum>
static u32 FASTCALL OP_STRD_REG(u32 adr) static u32 DESMUME_FASTCALL OP_STRD_REG(u32 adr)
{ {
WRITE32(cpu->mem_if->data, adr, cpu->R[Rnum]); WRITE32(cpu->mem_if->data, adr, cpu->R[Rnum]);
@ -2043,7 +2044,7 @@ static int OP_LDRD_STRD_OFFSET_PRE_INDEX(const u32 i)
// SWP/SWPB // SWP/SWPB
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template<int PROCNUM> template<int PROCNUM>
static u32 FASTCALL op_swp(u32 adr, u32 *Rd, u32 Rs) static u32 DESMUME_FASTCALL op_swp(u32 adr, u32 *Rd, u32 Rs)
{ {
u32 tmp = ROR(READ32(cpu->mem_if->data, adr), (adr & 3)<<3); u32 tmp = ROR(READ32(cpu->mem_if->data, adr), (adr & 3)<<3);
WRITE32(cpu->mem_if->data, adr, Rs); WRITE32(cpu->mem_if->data, adr, Rs);
@ -2051,7 +2052,7 @@ static u32 FASTCALL op_swp(u32 adr, u32 *Rd, u32 Rs)
return (MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(adr) + MMU_memAccessCycles<PROCNUM,32,MMU_AD_WRITE>(adr)); return (MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(adr) + MMU_memAccessCycles<PROCNUM,32,MMU_AD_WRITE>(adr));
} }
template<int PROCNUM> template<int PROCNUM>
static u32 FASTCALL op_swpb(u32 adr, u32 *Rd, u32 Rs) static u32 DESMUME_FASTCALL op_swpb(u32 adr, u32 *Rd, u32 Rs)
{ {
u32 tmp = READ8(cpu->mem_if->data, adr); u32 tmp = READ8(cpu->mem_if->data, adr);
WRITE8(cpu->mem_if->data, adr, Rs); WRITE8(cpu->mem_if->data, adr, Rs);
@ -2059,7 +2060,7 @@ static u32 FASTCALL op_swpb(u32 adr, u32 *Rd, u32 Rs)
return (MMU_memAccessCycles<PROCNUM,8,MMU_AD_READ>(adr) + MMU_memAccessCycles<PROCNUM,8,MMU_AD_WRITE>(adr)); return (MMU_memAccessCycles<PROCNUM,8,MMU_AD_READ>(adr) + MMU_memAccessCycles<PROCNUM,8,MMU_AD_WRITE>(adr));
} }
typedef u32 FASTCALL (*OP_SWP_SWPB)(u32, u32*, u32); typedef u32 DESMUME_FASTCALL (*OP_SWP_SWPB)(u32, u32*, u32);
static const OP_SWP_SWPB op_swp_tab[2][2] = {{ op_swp<0>, op_swp<1> }, { op_swpb<0>, op_swpb<1> }}; static const OP_SWP_SWPB op_swp_tab[2][2] = {{ op_swp<0>, op_swp<1> }, { op_swpb<0>, op_swpb<1> }};
static int op_swp_(const u32 i, int b) static int op_swp_(const u32 i, int b)
@ -2118,7 +2119,7 @@ static u64 get_reg_list(u32 reg_mask, int dir)
#endif #endif
template <int PROCNUM, bool store, int dir> template <int PROCNUM, bool store, int dir>
static LDM_INLINE FASTCALL u32 OP_LDM_STM_generic(u32 adr, u64 regs, int n) static LDM_INLINE DESMUME_FASTCALL u32 OP_LDM_STM_generic(u32 adr, u64 regs, int n)
{ {
u32 cycles = 0; u32 cycles = 0;
adr &= ~3; adr &= ~3;
@ -2139,7 +2140,7 @@ static LDM_INLINE FASTCALL u32 OP_LDM_STM_generic(u32 adr, u64 regs, int n)
#endif #endif
template <int PROCNUM, bool store, int dir> template <int PROCNUM, bool store, int dir>
static LDM_INLINE FASTCALL u32 OP_LDM_STM_other(u32 adr, u64 regs, int n) static LDM_INLINE DESMUME_FASTCALL u32 OP_LDM_STM_other(u32 adr, u64 regs, int n)
{ {
u32 cycles = 0; u32 cycles = 0;
adr &= ~3; adr &= ~3;
@ -2161,7 +2162,7 @@ static LDM_INLINE FASTCALL u32 OP_LDM_STM_other(u32 adr, u64 regs, int n)
} }
template <int PROCNUM, bool store, int dir, bool null_compiled> template <int PROCNUM, bool store, int dir, bool null_compiled>
static FORCEINLINE FASTCALL u32 OP_LDM_STM_main(u32 adr, u64 regs, int n, u8 *ptr, u32 cycles) static FORCEINLINE DESMUME_FASTCALL u32 OP_LDM_STM_main(u32 adr, u64 regs, int n, u8 *ptr, u32 cycles)
{ {
#ifdef ENABLE_ADVANCED_TIMING #ifdef ENABLE_ADVANCED_TIMING
cycles = 0; cycles = 0;
@ -2200,7 +2201,7 @@ static FORCEINLINE FASTCALL u32 OP_LDM_STM_main(u32 adr, u64 regs, int n, u8 *pt
} }
template <int PROCNUM, bool store, int dir> template <int PROCNUM, bool store, int dir>
static u32 FASTCALL OP_LDM_STM(u32 adr, u64 regs, int n) static u32 DESMUME_FASTCALL OP_LDM_STM(u32 adr, u64 regs, int n)
{ {
// TODO use classify_adr? // TODO use classify_adr?
u32 cycles; u32 cycles;
@ -2241,7 +2242,7 @@ static u32 FASTCALL OP_LDM_STM(u32 adr, u64 regs, int n)
return OP_LDM_STM_main<PROCNUM, store, dir, store>(adr, regs, n, ptr, cycles); return OP_LDM_STM_main<PROCNUM, store, dir, store>(adr, regs, n, ptr, cycles);
} }
typedef u32 FASTCALL (*LDMOpFunc)(u32,u64,int); typedef u32 DESMUME_FASTCALL (*LDMOpFunc)(u32,u64,int);
static const LDMOpFunc op_ldm_stm_tab[2][2][2] = {{ static const LDMOpFunc op_ldm_stm_tab[2][2][2] = {{
{ OP_LDM_STM<0,0,-1>, OP_LDM_STM<0,0,+1> }, { OP_LDM_STM<0,0,-1>, OP_LDM_STM<0,0,+1> },
{ OP_LDM_STM<0,1,-1>, OP_LDM_STM<0,1,+1> }, { OP_LDM_STM<0,1,-1>, OP_LDM_STM<0,1,+1> },
@ -3848,7 +3849,7 @@ static const ArmOpCompiler thumb_instruction_compilers[1024] = {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template<int PROCNUM, int thumb> template<int PROCNUM, int thumb>
static u32 FASTCALL OP_DECODE() static u32 DESMUME_FASTCALL OP_DECODE()
{ {
u32 cycles; u32 cycles;
u32 adr = cpu->instruct_adr; u32 adr = cpu->instruct_adr;

View File

@ -24,7 +24,7 @@
#include <stdint.h> #include <stdint.h>
#endif #endif
typedef u32 (FASTCALL* ArmOpCompiled)(); typedef u32 (DESMUME_FASTCALL* ArmOpCompiled)();
void arm_jit_reset(bool enable, bool suppress_msg = false); void arm_jit_reset(bool enable, bool suppress_msg = false);
void arm_jit_close(); void arm_jit_close();

View File

@ -460,23 +460,23 @@ FORCEINLINE static u32 armcpu_prefetch()
} }
#if 0 /* not used */ #if 0 /* not used */
static BOOL FASTCALL test_EQ(Status_Reg CPSR) { return ( CPSR.bits.Z); } static BOOL DESMUME_FASTCALL test_EQ(Status_Reg CPSR) { return ( CPSR.bits.Z); }
static BOOL FASTCALL test_NE(Status_Reg CPSR) { return (!CPSR.bits.Z); } static BOOL DESMUME_FASTCALL test_NE(Status_Reg CPSR) { return (!CPSR.bits.Z); }
static BOOL FASTCALL test_CS(Status_Reg CPSR) { return ( CPSR.bits.C); } static BOOL DESMUME_FASTCALL test_CS(Status_Reg CPSR) { return ( CPSR.bits.C); }
static BOOL FASTCALL test_CC(Status_Reg CPSR) { return (!CPSR.bits.C); } static BOOL DESMUME_FASTCALL test_CC(Status_Reg CPSR) { return (!CPSR.bits.C); }
static BOOL FASTCALL test_MI(Status_Reg CPSR) { return ( CPSR.bits.N); } static BOOL DESMUME_FASTCALL test_MI(Status_Reg CPSR) { return ( CPSR.bits.N); }
static BOOL FASTCALL test_PL(Status_Reg CPSR) { return (!CPSR.bits.N); } static BOOL DESMUME_FASTCALL test_PL(Status_Reg CPSR) { return (!CPSR.bits.N); }
static BOOL FASTCALL test_VS(Status_Reg CPSR) { return ( CPSR.bits.V); } static BOOL DESMUME_FASTCALL test_VS(Status_Reg CPSR) { return ( CPSR.bits.V); }
static BOOL FASTCALL test_VC(Status_Reg CPSR) { return (!CPSR.bits.V); } static BOOL DESMUME_FASTCALL test_VC(Status_Reg CPSR) { return (!CPSR.bits.V); }
static BOOL FASTCALL test_HI(Status_Reg CPSR) { return (CPSR.bits.C) && (!CPSR.bits.Z); } static BOOL DESMUME_FASTCALL test_HI(Status_Reg CPSR) { return (CPSR.bits.C) && (!CPSR.bits.Z); }
static BOOL FASTCALL test_LS(Status_Reg CPSR) { return (CPSR.bits.Z) || (!CPSR.bits.C); } static BOOL DESMUME_FASTCALL test_LS(Status_Reg CPSR) { return (CPSR.bits.Z) || (!CPSR.bits.C); }
static BOOL FASTCALL test_GE(Status_Reg CPSR) { return (CPSR.bits.N==CPSR.bits.V); } static BOOL DESMUME_FASTCALL test_GE(Status_Reg CPSR) { return (CPSR.bits.N==CPSR.bits.V); }
static BOOL FASTCALL test_LT(Status_Reg CPSR) { return (CPSR.bits.N!=CPSR.bits.V); } static BOOL DESMUME_FASTCALL test_LT(Status_Reg CPSR) { return (CPSR.bits.N!=CPSR.bits.V); }
static BOOL FASTCALL test_GT(Status_Reg CPSR) { return (!CPSR.bits.Z) && (CPSR.bits.N==CPSR.bits.V); } static BOOL DESMUME_FASTCALL test_GT(Status_Reg CPSR) { return (!CPSR.bits.Z) && (CPSR.bits.N==CPSR.bits.V); }
static BOOL FASTCALL test_LE(Status_Reg CPSR) { return ( CPSR.bits.Z) || (CPSR.bits.N!=CPSR.bits.V); } static BOOL DESMUME_FASTCALL test_LE(Status_Reg CPSR) { return ( CPSR.bits.Z) || (CPSR.bits.N!=CPSR.bits.V); }
static BOOL FASTCALL test_AL(Status_Reg CPSR) { return 1; } static BOOL DESMUME_FASTCALL test_AL(Status_Reg CPSR) { return 1; }
static BOOL (FASTCALL* test_conditions[])(Status_Reg CPSR)= { static BOOL (DESMUME_FASTCALL* test_conditions[])(Status_Reg CPSR)= {
test_EQ , test_NE , test_EQ , test_NE ,
test_CS , test_CC , test_CS , test_CC ,
test_MI , test_PL , test_MI , test_PL ,

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2009-2021 DeSmuME team Copyright (C) 2009-2024 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -24,31 +24,51 @@
#define CHEAT_VERSION_MAJOR 2 #define CHEAT_VERSION_MAJOR 2
#define CHEAT_VERSION_MINOR 0 #define CHEAT_VERSION_MINOR 0
#define MAX_CHEAT_LIST 100
#define MAX_XX_CODE 1024 #define MAX_XX_CODE 1024
#define CHEAT_FILE_MIN_FGETS_BUFFER 32768 #define CHEAT_FILE_MIN_FGETS_BUFFER 32768
#define CHEAT_DB_GAME_TITLE_SIZE 256
#define CHEAT_TYPE_EMPTY 0xFF #define CHEAT_TYPE_EMPTY 0xFF
#define CHEAT_TYPE_INTERNAL 0 #define CHEAT_TYPE_INTERNAL 0
#define CHEAT_TYPE_AR 1 #define CHEAT_TYPE_AR 1
#define CHEAT_TYPE_CODEBREAKER 2 #define CHEAT_TYPE_CODEBREAKER 2
enum CheatSystemError
{
CheatSystemError_NoError = 0,
CheatSystemError_FileOpenFailed = 1,
CheatSystemError_FileFormatInvalid = 2,
CheatSystemError_GameNotFound = 3,
CheatSystemError_LoadEntryError = 4,
CheatSystemError_FileSaveFailed = 5,
CheatSystemError_FileDoesNotExist = 6
};
struct CHEATS_LIST struct CHEATS_LIST
{ {
CHEATS_LIST() CHEATS_LIST()
{ {
memset(this,0,sizeof(*this)); memset(this,0,sizeof(*this));
type = 0xFF; type = CHEAT_TYPE_EMPTY;
} }
u8 type; u8 type;
BOOL enabled; u8 enabled;
// TODO // TODO
u8 freezeType; // 0 - normal freeze u8 freezeType; // 0 - normal freeze
// 1 - can decrease // 1 - can decrease
// 2 - can increase // 2 - can increase
u32 code[MAX_XX_CODE][2]; u32 code[MAX_XX_CODE][2];
char description[1024];
union
{
char description[1024];
struct
{
char descriptionMajor[512];
char descriptionMinor[512];
};
};
u32 num; u32 num;
u8 size; u8 size;
}; };
@ -56,56 +76,85 @@ struct CHEATS_LIST
class CHEATS class CHEATS
{ {
private: private:
std::vector<CHEATS_LIST> list; std::vector<CHEATS_LIST> _list;
u8 filename[MAX_PATH]; u8 _filename[MAX_PATH];
u32 currentGet; size_t _currentGet;
void clear();
void ARparser(CHEATS_LIST& cheat);
char *clearCode(char *s); char *clearCode(char *s);
public: public:
CHEATS() CHEATS()
: currentGet(0) : _currentGet(0)
{ {
memset(filename, 0, sizeof(filename)); memset(_filename, 0, sizeof(_filename));
} }
~CHEATS() {} ~CHEATS() {}
void init(char *path); void clear();
BOOL add(u8 size, u32 address, u32 val, char *description, BOOL enabled); void init(const char *thePath);
BOOL update(u8 size, u32 address, u32 val, char *description, BOOL enabled, u32 pos); const char* getFilePath() const;
BOOL move(u32 srcPos, u32 dstPos); void setFilePath(const char *thePath);
BOOL add_AR(char *code, char *description, BOOL enabled);
BOOL update_AR(char *code, char *description, BOOL enabled, u32 pos);
BOOL add_AR_Direct(CHEATS_LIST cheat);
BOOL add_CB(char *code, char *description, BOOL enabled);
BOOL update_CB(char *code, char *description, BOOL enabled, u32 pos);
BOOL remove(u32 pos);
void getListReset();
BOOL getList(CHEATS_LIST *cheat);
CHEATS_LIST* getListPtr();
BOOL get(CHEATS_LIST *cheat, u32 pos);
CHEATS_LIST* getItemByIndex(const u32 pos);
u32 getSize();
size_t getActiveCount();
void setDescription(const char *description, u32 pos);
BOOL save();
BOOL load();
void process(int targetType);
void getXXcodeString(CHEATS_LIST theList, char *res_buf);
static BOOL XXCodeFromString(CHEATS_LIST *cheatItem, const std::string codeString); size_t addItem(const CHEATS_LIST &srcCheat);
static BOOL XXCodeFromString(CHEATS_LIST *cheatItem, const char *codeString); bool add(u8 size, u32 address, u32 val, char *description, bool enabled);
bool add(u8 size, u32 address, u32 val, char *description, u8 enabled);
bool updateItemAtIndex(const CHEATS_LIST &srcCheat, const size_t pos);
bool update(u8 size, u32 address, u32 val, char *description, bool enabled, const size_t pos);
bool update(u8 size, u32 address, u32 val, char *description, u8 enabled, const size_t pos);
bool move(size_t srcPos, size_t dstPos);
size_t add_AR_Direct(const CHEATS_LIST &srcCheat);
bool add_AR(char *code, char *description, bool enabled);
bool add_AR(char *code, char *description, u8 enabled);
bool update_AR(char *code, char *description, bool enabled, const size_t pos);
bool update_AR(char *code, char *description, u8 enabled, const size_t pos);
bool add_CB(char *code, char *description, bool enabled);
bool add_CB(char *code, char *description, u8 enabled);
bool update_CB(char *code, char *description, bool enabled, const size_t pos);
bool update_CB(char *code, char *description, u8 enabled, const size_t pos);
bool remove(const size_t pos);
void toggle(bool enabled, const size_t pos);
void toggle(u8 enablbed, const size_t pos);
void getListReset();
bool getList(CHEATS_LIST *cheat);
CHEATS_LIST* getListPtr();
bool copyItemFromIndex(const size_t pos, CHEATS_LIST &outCheatItem);
CHEATS_LIST* getItemPtrAtIndex(const size_t pos) const;
size_t getListSize() const;
size_t getActiveCount() const;
void setDescription(const char *description, const size_t pos);
bool save();
bool load();
bool process(int targetType) const;
static void JitNeedsReset();
static bool ResetJitIfNeeded();
template<size_t LENGTH> static bool DirectWrite(const int targetProc, const u32 targetAddress, u32 newValue);
static bool DirectWrite(const size_t newValueLength, const int targetProc, const u32 targetAddress, u32 newValue);
static bool ARparser(const CHEATS_LIST &cheat);
static void StringFromXXCode(const CHEATS_LIST &srcCheatItem, char *outCStringBuffer);
static bool XXCodeFromString(const std::string codeString, CHEATS_LIST &outCheatItem);
static bool XXCodeFromString(const char *codeString, CHEATS_LIST &outCheatItem);
}; };
class CHEATSEARCH class CHEATSEARCH
{ {
private: private:
u8 *statMem; u8 *_statMem;
u8 *mem; u8 *_mem;
u32 amount; u32 _amount;
u32 lastRecord; u32 _lastRecord;
u32 _type; u32 _type;
u32 _size; u32 _size;
@ -113,90 +162,168 @@ private:
public: public:
CHEATSEARCH() CHEATSEARCH()
: statMem(0), mem(0), amount(0), lastRecord(0), _type(0), _size(0), _sign(0) : _statMem(0), _mem(0), _amount(0), _lastRecord(0), _type(0), _size(0), _sign(0)
{} {}
~CHEATSEARCH() { close(); } ~CHEATSEARCH() { this->close(); }
BOOL start(u8 type, u8 size, u8 sign); bool start(u8 type, u8 size, u8 sign);
BOOL close(); void close();
u32 search(u32 val); u32 search(u32 val);
u32 search(u8 comp); u32 search(u8 comp);
u32 getAmount(); u32 getAmount();
BOOL getList(u32 *address, u32 *curVal); bool getList(u32 *address, u32 *curVal);
void getListReset(); void getListReset();
}; };
enum CHEATS_DB_TYPE #define CHEATDB_OFFSET_FILE_DESCRIPTION 0x00000010
#define CHEATDB_FILEOFFSET_FIRST_FAT_ENTRY 0x00000100
enum CheatDBFileFormat
{ {
CHEATS_DB_R4 = 0 CheatDBFileFormat_Undefined = 0,
CheatDBFileFormat_R4 = 1,
CheatDBFileFormat_Unknown = 65535
}; };
// This struct maps to the FAT entries in the R4 cheat database file.
#pragma pack(push) #pragma pack(push)
#pragma pack(1) #pragma pack(1)
typedef struct FAT_R4 typedef struct FAT_R4
{ {
u8 serial[4]; u8 serial[4];
u32 CRC; u32 CRC;
u64 addr; u64 addr;
} FAT_R4; } FAT_R4;
#pragma pack(pop) #pragma pack(pop)
// Wrapper for a single entry in a memory block that contains data read from a cheat database file.
// This struct also maintains the hierarchical relationships between entries.
struct CheatDBEntry
{
u8 *base; // Pointer to the entry's base location in memory.
char *name; // Pointer to the entry's name string.
char *note; // Pointer to the entry's note string.
u32 *codeLength; // Pointer to the entry's 32-bit code length in bytes. This value is NULL if the entry is a directory.
u32 *codeData; // Pointer to the entry's code data, provided in pairs of 32-bit values. This value is NULL if the entry is a directory.
CheatDBEntry *parent;
std::vector<CheatDBEntry> child;
};
typedef struct CheatDBEntry CheatDBEntry;
class CheatDBGame
{
protected:
u32 _baseOffset; // This offset is relative to the file head.
u32 _firstEntryOffset; // This offset is relative to the file head.
u32 _encryptOffset; // This offset is relative to the memory address of this->_entryDataRawPtr.
u32 _rawDataSize;
u32 _workingDataSize;
u32 _crc;
u32 _entryCount;
std::string _title;
char _serial[4 + 1];
u8 *_entryDataRawPtr;
u8 *_entryData;
CheatDBEntry _entryRoot;
u32 _cheatItemCount;
void _UpdateDirectoryParents(CheatDBEntry &directory);
bool _CreateCheatItemFromCheatEntry(const CheatDBEntry &inEntry, const bool isHierarchical, CHEATS_LIST &outCheatItem);
size_t _DirectoryAddCheatsFlat(const CheatDBEntry &directory, const bool isHierarchical, size_t cheatIndex, CHEATS_LIST *outCheatsList);
public:
CheatDBGame();
CheatDBGame(const u32 encryptOffset, const FAT_R4 &fat, const u32 rawDataSize);
CheatDBGame(FILE *fp, const bool isEncrypted, const u32 encryptOffset, const FAT_R4 &fat, const u32 rawDataSize, u8 (&workingBuffer)[1024]);
~CheatDBGame();
void SetInitialProperties(const u32 rawDataSize, const u32 encryptOffset, const FAT_R4 &fat);
void LoadPropertiesFromFile(FILE *fp, const bool isEncrypted, u8 (&workingBuffer)[1024]);
u32 GetBaseOffset() const;
u32 GetFirstEntryOffset() const;
u32 GetEncryptOffset() const;
u32 GetRawDataSize() const;
u32 GetWorkingDataSize() const;
u32 GetCRC() const;
u32 GetEntryCount() const;
u32 GetCheatItemCount() const;
const char* GetTitle() const;
const char* GetSerial() const;
const CheatDBEntry& GetEntryRoot() const;
const u8* GetEntryRawData() const;
bool IsEntryDataLoaded() const;
u8* LoadEntryData(FILE *fp, const bool isEncrypted);
size_t ParseEntriesToCheatsListFlat(CHEATS_LIST *outCheatsList);
};
typedef std::vector<CheatDBGame> CheatDBGameList;
class CheatDBFile
{
protected:
std::string _path;
std::string _description;
std::string _formatString;
CheatDBFileFormat _format;
bool _isEncrypted;
size_t _size;
FILE *_fp;
CheatDBGame _ReadGame(const u32 encryptOffset, const FAT_R4 &fat, const u32 gameDataSize, u8 (&workingBuffer)[1024]);
public:
CheatDBFile();
~CheatDBFile();
static void R4Decrypt(u8 *buf, const size_t len, u64 n);
static bool ReadToBuffer(FILE *fp, const size_t fileOffset, const bool isEncrypted, const size_t encryptOffset, const size_t requestedSize, u8 *outBuffer);
FILE* GetFilePtr() const;
bool IsEncrypted() const;
const char* GetDescription() const;
CheatDBFileFormat GetFormat() const;
const char* GetFormatString() const;
CheatSystemError OpenFile(const char *filePath);
void CloseFile();
u32 LoadGameList(const char *gameCode, const u32 gameDatabaseCRC, CheatDBGameList &outList);
};
class CHEATSEXPORT class CHEATSEXPORT
{ {
private: private:
CHEATS_DB_TYPE type; CheatDBFile _dbFile;
bool encrypted; CheatDBGameList _tempGameList;
FILE *fp; CheatDBGame *_selectedDbGame;
u32 fsize; CHEATS_LIST *_cheats;
u32 dataSize; CheatSystemError _lastError;
u32 encOffset;
FAT_R4 fat;
bool search();
bool getCodes();
void R4decrypt(u8 *buf, u32 len, u32 n);
u32 numCheats;
CHEATS_LIST *cheats;
u8 error; // 0 - no errors
// 1 - open failed/file not found
// 2 - file format is wrong (no valid header ID)
// 3 - cheat not found in database
// 4 - export error from database
public: public:
CHEATSEXPORT() : CHEATSEXPORT();
fp(NULL), ~CHEATSEXPORT();
fsize(0),
dataSize(0), bool load(const char *path);
encOffset(0), void close();
type(CHEATS_DB_R4),
encrypted(false), CHEATS_LIST *getCheats() const;
numCheats(0), size_t getCheatsNum() const;
cheats(0), const char* getGameTitle() const;
CRC(0), const char* getDescription() const;
error(0) CheatSystemError getErrorCode() const;
{
memset(date, 0, sizeof(date));
gametitle = (u8 *)malloc(CHEAT_DB_GAME_TITLE_SIZE);
memset(gametitle, 0, CHEAT_DB_GAME_TITLE_SIZE);
}
~CHEATSEXPORT()
{
free(gametitle);
gametitle = NULL;
}
u8 *gametitle;
u8 date[17];
u32 CRC;
bool load(char *path);
void close();
CHEATS_LIST *getCheats();
u32 getCheatsNum();
u8 getErrorCode() { return error; }
}; };
CheatDBGame* GetCheatDBGameEntryFromList(const CheatDBGameList &gameList, const char *gameCode, const u32 gameDatabaseCRC);
void CheatItemGenerateDescriptionHierarchical(const char *itemName, const char *itemNote, CHEATS_LIST &outCheatItem);
void CheatItemGenerateDescriptionFlat(const char *folderName, const char *folderNote, const char *itemName, const char *itemNote, CHEATS_LIST &outCheatItem);
extern CHEATS *cheats; extern CHEATS *cheats;
extern CHEATSEARCH *cheatSearch; extern CHEATSEARCH *cheatSearch;

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2009-2017 DeSmuME team Copyright (C) 2009-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -36,62 +36,6 @@
int _scanline_filter_a = 0, _scanline_filter_b = 2, _scanline_filter_c = 2, _scanline_filter_d = 4; int _scanline_filter_a = 0, _scanline_filter_b = 2, _scanline_filter_c = 2, _scanline_filter_d = 4;
int _commandline_linux_nojoy = 0; int _commandline_linux_nojoy = 0;
CommandLine::CommandLine()
: is_cflash_configured(false)
, _load_to_memory(-1)
, _play_movie_file(0)
, _record_movie_file(0)
, _cflash_image(0)
, _cflash_path(0)
, _gbaslot_rom(0)
, _bios_arm9(NULL)
, _bios_arm7(NULL)
, _bios_swi(0)
, _fw_path(NULL)
, _fw_boot(0)
, _spu_sync_mode(-1)
, _spu_sync_method(-1)
, _spu_advanced(0)
, _num_cores(-1)
, _rigorous_timing(0)
, _advanced_timing(-1)
, _gamehacks(-1)
, _texture_deposterize(-1)
, _texture_smooth(-1)
, _slot1(NULL)
, _slot1_fat_dir(NULL)
, _slot1_fat_dir_type(false)
, _slot1_no8000prot(0)
#ifdef HAVE_JIT
, _cpu_mode(-1)
, _jit_size(-1)
#endif
, _console_type(NULL)
, _advanscene_import(NULL)
, load_slot(-1)
, arm9_gdb_port(0)
, arm7_gdb_port(0)
, start_paused(FALSE)
, autodetect_method(-1)
, render3d(COMMANDLINE_RENDER3D_DEFAULT)
, texture_upscale(-1)
, gpu_resolution_multiplier(-1)
, language(1) //english by default
, disable_sound(0)
, disable_limiter(0)
, windowed_fullscreen(0)
, frameskip(0)
, horizontal(0)
, scale(1.0)
, _rtc_day(-1)
, _rtc_hour(-1)
{
}
CommandLine::~CommandLine()
{
}
static char mytoupper(char c) { return ::toupper(c); } static char mytoupper(char c) { return ::toupper(c); }
static std::string strtoupper(const std::string& str) static std::string strtoupper(const std::string& str)
@ -236,6 +180,71 @@ ENDL
#define OPT_ADVANSCENE 900 #define OPT_ADVANSCENE 900
CommandLine::CommandLine()
{
// private
_play_movie_file = NULL;
_record_movie_file = NULL;
_cflash_image = NULL;
_cflash_path = NULL;
_gbaslot_rom = NULL;
_bios_arm9 = NULL;
_bios_arm7 = NULL;
_fw_path = NULL;
_fw_boot = 0;
_load_to_memory = -1;
_bios_swi = 0;
_spu_advanced = 0;
_num_cores = -1;
_rigorous_timing = 0;
_advanced_timing = -1;
_gamehacks = -1;
_texture_deposterize = -1;
_texture_smooth = -1;
#ifdef HAVE_JIT
_cpu_mode = -1;
_jit_size = -1;
#endif
_slot1 = NULL;
_slot1_fat_dir = NULL;
_console_type = NULL;
_advanscene_import = NULL;
_rtc_day = -1;
_rtc_hour = -1;
// public
load_slot = -1;
autodetect_method = -1;
render3d = COMMANDLINE_RENDER3D_DEFAULT;
texture_upscale = -1;
gpu_resolution_multiplier = -1;
language = 1; //english by default
scale = 1.0;
nds_file = "";
play_movie_file = "";
record_movie_file = "";
arm9_gdb_port = 0;
arm7_gdb_port = 0;
start_paused = 0;
cflash_image = "";
cflash_path = "";
gbaslot_rom = "";
slot1 = "";
console_type = "";
slot1_fat_dir = "";
_slot1_fat_dir_type = false;
_slot1_no8000prot = 0;
disable_sound = 0;
disable_limiter = 0;
windowed_fullscreen = 0;
frameskip = 0;
horizontal = 0;
is_cflash_configured = false;
_spu_sync_mode = -1;
_spu_sync_method = -1;
}
bool CommandLine::parse(int argc,char **argv) bool CommandLine::parse(int argc,char **argv)
{ {
//closest thing to a portable main() we have, I guess. //closest thing to a portable main() we have, I guess.
@ -397,7 +406,7 @@ bool CommandLine::parse(int argc,char **argv)
if(opt_help) if(opt_help)
{ {
printf(help_string); printf("%s",help_string);
exit(1); exit(1);
} }
@ -571,7 +580,7 @@ bool CommandLine::validate()
void CommandLine::errorHelp(const char* binName) void CommandLine::errorHelp(const char* binName)
{ {
printerror(help_string); printerror("%s",help_string);
} }
void CommandLine::process_movieCommands() void CommandLine::process_movieCommands()
@ -612,23 +621,23 @@ void CommandLine::process_addonCommands()
slot1_Change(NDS_SLOT1_R4); slot1_Change(NDS_SLOT1_R4);
else if(slot1 == "RETAILNAND") else if(slot1 == "RETAILNAND")
slot1_Change(NDS_SLOT1_RETAIL_NAND); slot1_Change(NDS_SLOT1_RETAIL_NAND);
else if(slot1 == "RETAILMCROM") else if(slot1 == "RETAILMCROM")
slot1_Change(NDS_SLOT1_RETAIL_MCROM); slot1_Change(NDS_SLOT1_RETAIL_MCROM);
else if(slot1 == "RETAILDEBUG") else if(slot1 == "RETAILDEBUG")
slot1_Change(NDS_SLOT1_RETAIL_DEBUG); slot1_Change(NDS_SLOT1_RETAIL_DEBUG);
if (_rtc_day != -1 || _rtc_hour != -1) { if (_rtc_day != -1 || _rtc_hour != -1) {
DateTime now = DateTime::get_Now(); DateTime now = DateTime::get_Now();
int cur_day = now.get_DayOfWeek(); int cur_day = now.get_DayOfWeek();
int cur_hour = now.get_Hour(); int cur_hour = now.get_Hour();
int cur_total = cur_day * 24 + cur_hour; int cur_total = cur_day * 24 + cur_hour;
int day = (_rtc_day != -1 ? _rtc_day : cur_day); int day = (_rtc_day != -1 ? _rtc_day : cur_day);
int hour = (_rtc_hour != -1 ? _rtc_hour : cur_hour); int hour = (_rtc_hour != -1 ? _rtc_hour : cur_hour);
int total = day * 24 + hour; int total = day * 24 + hour;
int diff = total - cur_total; int diff = total - cur_total;
if (diff < 0) if (diff < 0)
diff += 24 * 7; diff += 24 * 7;
rtcHourOverride = diff; rtcHourOverride = diff;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2009-2017 DeSmuME team Copyright (C) 2009-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -41,61 +41,15 @@ extern int _commandline_linux_nojoy;
class CommandLine class CommandLine
{ {
public:
//actual options: these may move to another struct
int load_slot;
int autodetect_method;
int render3d;
int texture_upscale;
int gpu_resolution_multiplier;
int language;
float scale;
std::string nds_file;
std::string play_movie_file;
std::string record_movie_file;
int arm9_gdb_port, arm7_gdb_port;
int start_paused;
std::string cflash_image;
std::string cflash_path;
std::string gbaslot_rom;
std::string slot1;
std::string console_type;
std::string slot1_fat_dir;
bool _slot1_fat_dir_type;
int _slot1_no8000prot;
int disable_sound;
int disable_limiter;
int windowed_fullscreen;
int frameskip;
int horizontal;
bool parse(int argc,char **argv);
//validate the common commandline options
bool validate();
//process movie play/record commands
void process_movieCommands();
//etc.
void process_addonCommands();
bool is_cflash_configured;
//print a little help message for cases when erroneous commandlines are entered
void errorHelp(const char* binName);
CommandLine();
~CommandLine();
int _spu_sync_mode;
int _spu_sync_method;
private: private:
char* _play_movie_file; char *_play_movie_file;
char* _record_movie_file; char *_record_movie_file;
char* _cflash_image; char *_cflash_image;
char* _cflash_path; char *_cflash_path;
char* _gbaslot_rom; char *_gbaslot_rom;
char* _bios_arm9, *_bios_arm7; char *_bios_arm9;
char* _fw_path; char *_bios_arm7;
char *_fw_path;
int _fw_boot; int _fw_boot;
int _load_to_memory; int _load_to_memory;
int _bios_swi; int _bios_swi;
@ -110,12 +64,59 @@ private:
int _cpu_mode; int _cpu_mode;
int _jit_size; int _jit_size;
#endif #endif
char* _slot1; char *_slot1;
char *_slot1_fat_dir; char *_slot1_fat_dir;
char* _console_type; char *_console_type;
char* _advanscene_import; char *_advanscene_import;
int _rtc_day; int _rtc_day;
int _rtc_hour; int _rtc_hour;
public:
//actual options: these may move to another struct
int load_slot;
int autodetect_method;
int render3d;
int texture_upscale;
int gpu_resolution_multiplier;
int language;
float scale;
std::string nds_file;
std::string play_movie_file;
std::string record_movie_file;
int arm9_gdb_port;
int arm7_gdb_port;
int start_paused;
std::string cflash_image;
std::string cflash_path;
std::string gbaslot_rom;
std::string slot1;
std::string console_type;
std::string slot1_fat_dir;
bool _slot1_fat_dir_type;
int _slot1_no8000prot;
int disable_sound;
int disable_limiter;
int windowed_fullscreen;
int frameskip;
int horizontal;
bool is_cflash_configured;
int _spu_sync_mode;
int _spu_sync_method;
CommandLine();
bool parse(int argc,char **argv);
//validate the common commandline options
bool validate();
//process movie play/record commands
void process_movieCommands();
//etc.
void process_addonCommands();
//print a little help message for cases when erroneous commandlines are entered
void errorHelp(const char* binName);
}; };
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2008-2017 DeSmuME team Copyright (C) 2008-2023 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -105,22 +105,12 @@ void* malloc_aligned64(size_t length)
void* malloc_alignedCacheLine(size_t length) void* malloc_alignedCacheLine(size_t length)
{ {
#if defined(HOST_32) return malloc_aligned(length, CACHE_ALIGN_SIZE);
return malloc_aligned32(length);
#elif defined(HOST_64)
return malloc_aligned64(length);
#else
return malloc_aligned16(length);
#endif
} }
void* malloc_alignedPage(size_t length) void* malloc_alignedPage(size_t length)
{ {
// WARNING! return malloc_aligned(length, PAGE_ALIGN_SIZE);
//
// This may fail for SPARC users, which have a page size
// of 8KB instead of the more typical 4KB.
return malloc_aligned(length, 4096);
} }
void free_aligned(void *ptr) void free_aligned(void *ptr)

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2006 yopyop Copyright (C) 2006 yopyop
Copyright (C) 2006-2021 DeSmuME team Copyright (C) 2006-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -175,7 +175,7 @@ void armcp15_setSingleRegionAccess(armcp15_t *armcp15, u8 num, u32 mask, u32 set
armcp15->regionExecuteSet_SYS[num] = set ; armcp15->regionExecuteSet_SYS[num] = set ;
break ; break ;
} }
} ; }
/* precalculate region masks/sets from cp15 register */ /* precalculate region masks/sets from cp15 register */
void armcp15_maskPrecalc(armcp15_t *armcp15) void armcp15_maskPrecalc(armcp15_t *armcp15)
@ -366,6 +366,13 @@ BOOL armcp15_moveCP2ARM(armcp15_t *armcp15, u32 * R, u8 CRn, u8 CRm, u8 opcode1,
} }
} }
return FALSE; return FALSE;
case 13:
if(opcode1 == 0 && opcode2 == 1)
{
*R = armcp15->processID;
return TRUE;
}
return FALSE;
default: default:
LOG("Unsupported CP15 operation : MRC\n"); LOG("Unsupported CP15 operation : MRC\n");
return FALSE; return FALSE;
@ -488,6 +495,13 @@ BOOL armcp15_moveARM2CP(armcp15_t *armcp15, u32 val, u8 CRn, u8 CRm, u8 opcode1,
} }
} }
return FALSE; return FALSE;
case 13:
if(opcode1 == 0 && opcode2 == 1)
{
armcp15->processID = val;
return TRUE;
}
return FALSE;
default: default:
return FALSE; return FALSE;
} }

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2006 Guillaume Duhamel Copyright (C) 2006 Guillaume Duhamel
Copyright (C) 2006-2021 DeSmuME team Copyright (C) 2006-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -388,7 +388,10 @@ void IdeasLog(armcpu_t* cpu)
if(!c) break; if(!c) break;
printf("%c",c); printf("%c",c);
} }
//don't emit a newline. that is a pain in the butt. //don't emit a newline. that is a pain in the butt.
fflush(stdout);
} }
void NocashMessage(armcpu_t* cpu, int offset) void NocashMessage(armcpu_t* cpu, int offset)
@ -413,30 +416,31 @@ void NocashMessage(armcpu_t* cpu, int offset)
//this is very inefficiently coded! //this is very inefficiently coded!
char tmp[100]; char tmp[100];
todo = mass_replace(todo,"%sp%","%r13%"); todo = mass_replace(todo, "%sp%", "%r13%");
todo = mass_replace(todo,"%lr%","%r14%"); todo = mass_replace(todo, "%lr%", "%r14%");
todo = mass_replace(todo,"%pc%","%r15%"); todo = mass_replace(todo, "%pc%", "%r15%");
sprintf(tmp,"%08X",cpu->R[0]); todo = mass_replace(todo,"%r0%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[ 0]); todo = mass_replace(todo, "%r0%", tmp);
sprintf(tmp,"%08X",cpu->R[1]); todo = mass_replace(todo,"%r1%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[ 1]); todo = mass_replace(todo, "%r1%", tmp);
sprintf(tmp,"%08X",cpu->R[2]); todo = mass_replace(todo,"%r2%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[ 2]); todo = mass_replace(todo, "%r2%", tmp);
sprintf(tmp,"%08X",cpu->R[3]); todo = mass_replace(todo,"%r3%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[ 3]); todo = mass_replace(todo, "%r3%", tmp);
sprintf(tmp,"%08X",cpu->R[4]); todo = mass_replace(todo,"%r4%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[ 4]); todo = mass_replace(todo, "%r4%", tmp);
sprintf(tmp,"%08X",cpu->R[5]); todo = mass_replace(todo,"%r5%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[ 5]); todo = mass_replace(todo, "%r5%", tmp);
sprintf(tmp,"%08X",cpu->R[6]); todo = mass_replace(todo,"%r6%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[ 6]); todo = mass_replace(todo, "%r6%", tmp);
sprintf(tmp,"%08X",cpu->R[7]); todo = mass_replace(todo,"%r7%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[ 7]); todo = mass_replace(todo, "%r7%", tmp);
sprintf(tmp,"%08X",cpu->R[8]); todo = mass_replace(todo,"%r8%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[ 8]); todo = mass_replace(todo, "%r8%", tmp);
sprintf(tmp,"%08X",cpu->R[9]); todo = mass_replace(todo,"%r9%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[ 9]); todo = mass_replace(todo, "%r9%", tmp);
sprintf(tmp,"%08X",cpu->R[10]); todo = mass_replace(todo,"%r10%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[10]); todo = mass_replace(todo, "%r10%", tmp);
sprintf(tmp,"%08X",cpu->R[11]); todo = mass_replace(todo,"%r11%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[11]); todo = mass_replace(todo, "%r11%", tmp);
sprintf(tmp,"%08X",cpu->R[12]); todo = mass_replace(todo,"%r12%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[12]); todo = mass_replace(todo, "%r12%", tmp);
sprintf(tmp,"%08X",cpu->R[13]); todo = mass_replace(todo,"%r13%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[13]); todo = mass_replace(todo, "%r13%", tmp);
sprintf(tmp,"%08X",cpu->R[14]); todo = mass_replace(todo,"%r14%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[14]); todo = mass_replace(todo, "%r14%", tmp);
sprintf(tmp,"%08X",cpu->R[15]); todo = mass_replace(todo,"%r15%",tmp); snprintf(tmp, sizeof(tmp), "%08X", cpu->R[15]); todo = mass_replace(todo, "%r15%", tmp);
sprintf(tmp,"%d",nds.VCount); todo = mass_replace(todo,"%scanline%",tmp); snprintf(tmp, sizeof(tmp), "%d", nds.VCount); todo = mass_replace(todo, "%scanline%", tmp);
sprintf(tmp,"%d",currFrameCounter); todo = mass_replace(todo,"%frame%",tmp); snprintf(tmp, sizeof(tmp), "%d", currFrameCounter); todo = mass_replace(todo, "%frame%", tmp);
sprintf(tmp,"%lld",nds_timer); todo = mass_replace(todo,"%totalclks%",tmp); snprintf(tmp, sizeof(tmp), "%lld", nds_timer); todo = mass_replace(todo, "%totalclks%", tmp);
printf("%s",todo.c_str()); printf("%s",todo.c_str());
fflush(stdout);
} }
//------- //-------

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2006 Guillaume Duhamel Copyright (C) 2006 Guillaume Duhamel
Copyright (C) 2006-2015 DeSmuME team Copyright (C) 2006-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -149,7 +149,7 @@ enum EDEBUG_EVENT
DEBUG_EVENT_WRITE=2, //write on arm9 or arm7 bus DEBUG_EVENT_WRITE=2, //write on arm9 or arm7 bus
DEBUG_EVENT_EXECUTE=3, //prefetch on arm9 or arm7, triggered after the read event DEBUG_EVENT_EXECUTE=3, //prefetch on arm9 or arm7, triggered after the read event
DEBUG_EVENT_ACL_EXCEPTION=4, //acl exception on arm9 DEBUG_EVENT_ACL_EXCEPTION=4, //acl exception on arm9
DEBUG_EVENT_CACHE_MISS=5, //cache miss on arm9 DEBUG_EVENT_CACHE_MISS=5 //cache miss on arm9
}; };
enum EDEBUG_NOTIFY enum EDEBUG_NOTIFY

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2009-2018 DeSmuME team Copyright (C) 2009-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -26,6 +26,8 @@
class VIEW3D_Driver class VIEW3D_Driver
{ {
public: public:
virtual ~VIEW3D_Driver() {}
virtual void Launch() {} virtual void Launch() {}
virtual void NewFrame() {} virtual void NewFrame() {}
virtual bool IsRunning() { return false; } virtual bool IsRunning() { return false; }
@ -35,7 +37,7 @@ public:
class BaseDriver { class BaseDriver {
public: public:
BaseDriver(); BaseDriver();
~BaseDriver(); virtual ~BaseDriver();
virtual void AVI_SoundUpdate(void* soundData, int soundLen) {} virtual void AVI_SoundUpdate(void* soundData, int soundLen) {}
virtual bool AVI_IsRecording() { return FALSE; } virtual bool AVI_IsRecording() { return FALSE; }

View File

@ -65,7 +65,7 @@ public:
bool fail(bool unset=false) { bool ret = this->_failbit; if(unset) unfail(); return ret; } bool fail(bool unset=false) { bool ret = this->_failbit; if(unset) unfail(); return ret; }
void unfail() { this->_failbit = false; } void unfail() { this->_failbit = false; }
bool eof() { return size()==ftell(); } virtual bool eof() { return size()==ftell(); }
size_t fread(const void *ptr, size_t bytes){ size_t fread(const void *ptr, size_t bytes){
return _fread(ptr,bytes); return _fread(ptr,bytes);
@ -327,6 +327,8 @@ public:
virtual void truncate(s32 length); virtual void truncate(s32 length);
virtual bool eof() { return !!::feof(this->_fp); }
virtual int fprintf(const char *format, ...) { virtual int fprintf(const char *format, ...) {
va_list argptr; va_list argptr;
va_start(argptr, format); va_start(argptr, format);

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2016-2017 DeSmuME team Copyright (C) 2016-2024 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -21,83 +21,125 @@
#define DEPOSTERIZE_THRESHOLD 23 // Possible values are [0-255], where lower a value prevents blending and a higher value allows for more blending #define DEPOSTERIZE_THRESHOLD 23 // Possible values are [0-255], where lower a value prevents blending and a higher value allows for more blending
static u32 Deposterize_InterpLTE(const u32 pixA, const u32 pixB) namespace
{ {
const u32 aB = (pixB & 0xFF000000) >> 24; template <u32 DEN>
if (aB == 0) struct UnpackedPixel
{ {
return pixA; u32 r;
} u32 g;
u32 b;
const u32 rA = (pixA & 0x000000FF); u32 a;
const u32 gA = (pixA & 0x0000FF00) >> 8;
const u32 bA = (pixA & 0x00FF0000) >> 16;
const u32 aA = (pixA & 0xFF000000) >> 24;
const u32 rB = (pixB & 0x000000FF);
const u32 gB = (pixB & 0x0000FF00) >> 8;
const u32 bB = (pixB & 0x00FF0000) >> 16;
const u32 rC = ( (rB - rA <= DEPOSTERIZE_THRESHOLD) || (rA - rB <= DEPOSTERIZE_THRESHOLD) ) ? ((rA+rB)>>1) : rA;
const u32 gC = ( (gB - gA <= DEPOSTERIZE_THRESHOLD) || (gA - gB <= DEPOSTERIZE_THRESHOLD) ) ? ((gA+gB)>>1) : gA;
const u32 bC = ( (bB - bA <= DEPOSTERIZE_THRESHOLD) || (bA - bB <= DEPOSTERIZE_THRESHOLD) ) ? ((bA+bB)>>1) : bA;
const u32 aC = ( (aB - aA <= DEPOSTERIZE_THRESHOLD) || (aA - aB <= DEPOSTERIZE_THRESHOLD) ) ? ((aA+aB)>>1) : aA;
return (rC | (gC << 8) | (bC << 16) | (aC << 24)); u32 pack() const
} {
return ( ((r/DEN) << 0) |
static u32 Deposterize_Blend(const u32 pixA, const u32 pixB, const u32 weightA, const u32 weightB) ((g/DEN) << 8) |
{ ((b/DEN) << 16) |
const u32 aB = (pixB & 0xFF000000) >> 24; ((a/DEN) << 24) );
if (aB == 0) }
{
return pixA;
}
const u32 rbA = pixA & 0x00FF00FF;
const u32 gA = pixA & 0x0000FF00;
const u32 aA = (pixA & 0xFF000000) >> 24;
const u32 rbB = pixB & 0x00FF00FF;
const u32 gB = pixB & 0x0000FF00;
// Note: The sum of weightA and weightB must equal 16.
const u32 rbC = ( ((rbA * weightA) + (rbB * weightB)) / 16 ) & 0x00FF00FF;
const u32 gC = ( (( gA * weightA) + ( gB * weightB)) / 16 ) & 0x0000FF00;
const u32 aC = ( (( aA * weightA) + ( aB * weightB)) / 16 ) << 24;
return (rbC | gC | aC);
}
static u32 Deposterize_BlendPixel(const u32 color[9])
{
const u32 blend[9] = {
color[0],
Deposterize_InterpLTE(color[0], color[1]),
Deposterize_InterpLTE(color[0], color[2]),
Deposterize_InterpLTE(color[0], color[3]),
Deposterize_InterpLTE(color[0], color[4]),
Deposterize_InterpLTE(color[0], color[5]),
Deposterize_InterpLTE(color[0], color[6]),
Deposterize_InterpLTE(color[0], color[7]),
Deposterize_InterpLTE(color[0], color[8])
}; };
return Deposterize_Blend(Deposterize_Blend(Deposterize_Blend(Deposterize_Blend(blend[0], blend[5], 2, 14), static FORCEINLINE UnpackedPixel<2> Deposterize_InterpLTE(const UnpackedPixel<1> &pixA, const UnpackedPixel<1> &pixB)
Deposterize_Blend(blend[0], blend[1], 2, 14), {
8, 8), UnpackedPixel<2> pixOut = {
Deposterize_Blend(Deposterize_Blend(blend[0], blend[7], 2, 14), pixA.r,
Deposterize_Blend(blend[0], blend[3], 2, 14), pixA.g,
8, 8), pixA.b,
8, 8), pixA.a
Deposterize_Blend(Deposterize_Blend(Deposterize_Blend(blend[0], blend[6], 7, 9), };
Deposterize_Blend(blend[0], blend[2], 7, 9),
8, 8), if (pixB.a == 0)
Deposterize_Blend(Deposterize_Blend(blend[0], blend[8], 7, 9), {
Deposterize_Blend(blend[0], blend[4], 7, 9), pixOut.r = pixOut.r << 1;
8, 8), pixOut.g = pixOut.g << 1;
8, 8), pixOut.b = pixOut.b << 1;
12, 4); pixOut.a = pixOut.a << 1;
return pixOut;
}
const s32 rDiff = pixA.r - pixB.r;
const s32 gDiff = pixA.g - pixB.g;
const s32 bDiff = pixA.b - pixB.b;
const s32 aDiff = pixA.a - pixB.a;
pixOut.r = ( (-DEPOSTERIZE_THRESHOLD <= rDiff) && (rDiff <= DEPOSTERIZE_THRESHOLD) ) ? (pixOut.r + pixB.r) : (pixOut.r << 1);
pixOut.g = ( (-DEPOSTERIZE_THRESHOLD <= gDiff) && (gDiff <= DEPOSTERIZE_THRESHOLD) ) ? (pixOut.g + pixB.g) : (pixOut.g << 1);
pixOut.b = ( (-DEPOSTERIZE_THRESHOLD <= bDiff) && (bDiff <= DEPOSTERIZE_THRESHOLD) ) ? (pixOut.b + pixB.b) : (pixOut.b << 1);
pixOut.a = ( (-DEPOSTERIZE_THRESHOLD <= aDiff) && (aDiff <= DEPOSTERIZE_THRESHOLD) ) ? (pixOut.a + pixB.a) : (pixOut.a << 1);
return pixOut;
}
static FORCEINLINE UnpackedPixel<2> Deposterize_InterpLTE(const UnpackedPixel<1> &pixA, const u32 color32B)
{
const UnpackedPixel<1> pixB = {
(color32B >> 0) & 0x000000FF,
(color32B >> 8) & 0x000000FF,
(color32B >> 16) & 0x000000FF,
(color32B >> 24) & 0x000000FF
};
return Deposterize_InterpLTE(pixA, pixB);
}
template <u32 WEIGHTA, u32 WEIGHTB, u32 DEN>
static FORCEINLINE UnpackedPixel<DEN*(WEIGHTA+WEIGHTB)> Deposterize_Blend(const UnpackedPixel<DEN> &pixA, const UnpackedPixel<DEN> &pixB)
{
UnpackedPixel<DEN*(WEIGHTA+WEIGHTB)> ret;
ret.r = (pixA.r * WEIGHTA) + (pixB.r * WEIGHTB);
ret.g = (pixA.g * WEIGHTA) + (pixB.g * WEIGHTB);
ret.b = (pixA.b * WEIGHTA) + (pixB.b * WEIGHTB);
ret.a = (pixA.a * WEIGHTA) + (pixB.a * WEIGHTB);
return ret;
}
static u32 Deposterize_BlendPixel(const u32 color32[9])
{
const UnpackedPixel<1> center = {
(color32[0] >> 0) & 0x000000FF,
(color32[0] >> 8) & 0x000000FF,
(color32[0] >> 16) & 0x000000FF,
(color32[0] >> 24) & 0x000000FF
};
const UnpackedPixel<2> center2 = {
center.r << 1,
center.g << 1,
center.b << 1,
center.a << 1
};
#define DF_INTERP(i) Deposterize_InterpLTE(center, color32[i])
UnpackedPixel<512> pixOut = Deposterize_Blend<3, 1>(
Deposterize_Blend<1, 1>(
Deposterize_Blend<1, 1>(
Deposterize_Blend<2, 14>(center2, DF_INTERP(5)),
Deposterize_Blend<2, 14>(center2, DF_INTERP(1))
),
Deposterize_Blend<1, 1>(
Deposterize_Blend<2, 14>(center2, DF_INTERP(7)),
Deposterize_Blend<2, 14>(center2, DF_INTERP(3))
)
),
Deposterize_Blend<1, 1>(
Deposterize_Blend<1, 1>(
Deposterize_Blend<7, 9>(center2, DF_INTERP(6)),
Deposterize_Blend<7, 9>(center2, DF_INTERP(2))
),
Deposterize_Blend<1, 1>(
Deposterize_Blend<7, 9>(center2, DF_INTERP(8)),
Deposterize_Blend<7, 9>(center2, DF_INTERP(4))
)
)
);
#undef DF_INTERP
return pixOut.pack();
}
} }
void RenderDeposterize(SSurface Src, SSurface Dst) void RenderDeposterize(SSurface Src, SSurface Dst)
@ -127,15 +169,15 @@ void RenderDeposterize(SSurface Src, SSurface Dst)
continue; continue;
} }
color[0] = src[i]; color[0] = src[i];
color[1] = (x < w-1) ? src[i+1] : src[i]; color[1] = (x < w-1) ? src[i+1] : src[i];
color[2] = (x < w-1) ? src[i+w+1] : src[i]; color[2] = (x < w-1) ? src[i+w+1] : src[i];
color[3] = src[i]; color[3] = src[i];
color[4] = (x > 0) ? src[i+w-1] : src[i]; color[4] = (x > 0) ? src[i+w-1] : src[i];
color[5] = (x > 0) ? src[i-1] : src[i]; color[5] = (x > 0) ? src[i-1] : src[i];
color[6] = src[i]; color[6] = src[i];
color[7] = src[i]; color[7] = src[i];
color[8] = src[i]; color[8] = src[i];
workingDst[i] = Deposterize_BlendPixel(color); workingDst[i] = Deposterize_BlendPixel(color);
} }
@ -150,15 +192,15 @@ void RenderDeposterize(SSurface Src, SSurface Dst)
continue; continue;
} }
color[0] = src[i]; color[0] = src[i];
color[1] = (x < w-1) ? src[i+1] : src[i]; color[1] = (x < w-1) ? src[i+1] : src[i];
color[2] = (x < w-1) ? src[i+w+1] : src[i]; color[2] = (x < w-1) ? src[i+w+1] : src[i];
color[3] = src[i+w]; color[3] = src[i+w];
color[4] = (x > 0) ? src[i+w-1] : src[i]; color[4] = (x > 0) ? src[i+w-1] : src[i];
color[5] = (x > 0) ? src[i-1] : src[i]; color[5] = (x > 0) ? src[i-1] : src[i];
color[6] = (x > 0) ? src[i-w-1] : src[i]; color[6] = (x > 0) ? src[i-w-1] : src[i];
color[7] = src[i-w]; color[7] = src[i-w];
color[8] = (x < w-1) ? src[i-w+1] : src[i]; color[8] = (x < w-1) ? src[i-w+1] : src[i];
workingDst[i] = Deposterize_BlendPixel(color); workingDst[i] = Deposterize_BlendPixel(color);
} }
@ -172,15 +214,15 @@ void RenderDeposterize(SSurface Src, SSurface Dst)
continue; continue;
} }
color[0] = src[i]; color[0] = src[i];
color[1] = (x < w-1) ? src[i+1] : src[i]; color[1] = (x < w-1) ? src[i+1] : src[i];
color[2] = src[i]; color[2] = src[i];
color[3] = src[i]; color[3] = src[i];
color[4] = src[i]; color[4] = src[i];
color[5] = (x > 0) ? src[i-1] : src[i]; color[5] = (x > 0) ? src[i-1] : src[i];
color[6] = (x > 0) ? src[i-w-1] : src[i]; color[6] = (x > 0) ? src[i-w-1] : src[i];
color[7] = src[i]; color[7] = src[i];
color[8] = (x < w-1) ? src[i-w+1] : src[i]; color[8] = (x < w-1) ? src[i-w+1] : src[i];
workingDst[i] = Deposterize_BlendPixel(color); workingDst[i] = Deposterize_BlendPixel(color);
} }
@ -195,15 +237,15 @@ void RenderDeposterize(SSurface Src, SSurface Dst)
continue; continue;
} }
color[0] = workingDst[i]; color[0] = workingDst[i];
color[1] = (x < w-1) ? workingDst[i+1] : workingDst[i]; color[1] = (x < w-1) ? workingDst[i+1] : workingDst[i];
color[2] = (x < w-1) ? workingDst[i+w+1] : workingDst[i]; color[2] = (x < w-1) ? workingDst[i+w+1] : workingDst[i];
color[3] = workingDst[i]; color[3] = workingDst[i];
color[4] = (x > 0) ? workingDst[i+w-1] : workingDst[i]; color[4] = (x > 0) ? workingDst[i+w-1] : workingDst[i];
color[5] = (x > 0) ? workingDst[i-1] : workingDst[i]; color[5] = (x > 0) ? workingDst[i-1] : workingDst[i];
color[6] = workingDst[i]; color[6] = workingDst[i];
color[7] = workingDst[i]; color[7] = workingDst[i];
color[8] = workingDst[i]; color[8] = workingDst[i];
finalDst[i] = Deposterize_BlendPixel(color); finalDst[i] = Deposterize_BlendPixel(color);
} }
@ -218,15 +260,15 @@ void RenderDeposterize(SSurface Src, SSurface Dst)
continue; continue;
} }
color[0] = workingDst[i]; color[0] = workingDst[i];
color[1] = (x < w-1) ? workingDst[i+1] : workingDst[i]; color[1] = (x < w-1) ? workingDst[i+1] : workingDst[i];
color[2] = (x < w-1) ? workingDst[i+w+1] : workingDst[i]; color[2] = (x < w-1) ? workingDst[i+w+1] : workingDst[i];
color[3] = workingDst[i+w]; color[3] = workingDst[i+w];
color[4] = (x > 0) ? workingDst[i+w-1] : workingDst[i]; color[4] = (x > 0) ? workingDst[i+w-1] : workingDst[i];
color[5] = (x > 0) ? workingDst[i-1] : workingDst[i]; color[5] = (x > 0) ? workingDst[i-1] : workingDst[i];
color[6] = (x > 0) ? workingDst[i-w-1] : workingDst[i]; color[6] = (x > 0) ? workingDst[i-w-1] : workingDst[i];
color[7] = workingDst[i-w]; color[7] = workingDst[i-w];
color[8] = (x < w-1) ? workingDst[i-w+1] : workingDst[i]; color[8] = (x < w-1) ? workingDst[i-w+1] : workingDst[i];
finalDst[i] = Deposterize_BlendPixel(color); finalDst[i] = Deposterize_BlendPixel(color);
} }
@ -240,15 +282,15 @@ void RenderDeposterize(SSurface Src, SSurface Dst)
continue; continue;
} }
color[0] = workingDst[i]; color[0] = workingDst[i];
color[1] = (x < w-1) ? workingDst[i+1] : workingDst[i]; color[1] = (x < w-1) ? workingDst[i+1] : workingDst[i];
color[2] = workingDst[i]; color[2] = workingDst[i];
color[3] = workingDst[i]; color[3] = workingDst[i];
color[4] = workingDst[i]; color[4] = workingDst[i];
color[5] = (x > 0) ? workingDst[i-1] : workingDst[i]; color[5] = (x > 0) ? workingDst[i-1] : workingDst[i];
color[6] = (x > 0) ? workingDst[i-w-1] : workingDst[i]; color[6] = (x > 0) ? workingDst[i-w-1] : workingDst[i];
color[7] = workingDst[i]; color[7] = workingDst[i];
color[8] = (x < w-1) ? workingDst[i-w+1] : workingDst[i]; color[8] = (x < w-1) ? workingDst[i-w+1] : workingDst[i];
finalDst[i] = Deposterize_BlendPixel(color); finalDst[i] = Deposterize_BlendPixel(color);
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2009-2016 DeSmuME team Copyright (C) 2009-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -20,15 +20,18 @@
#define FILTER_MAX_WORKING_SURFACE_COUNT 8 #define FILTER_MAX_WORKING_SURFACE_COUNT 8
typedef struct { struct SSurface
{
unsigned char *Surface; unsigned char *Surface;
unsigned int Pitch; int Pitch;
unsigned int Width, Height; int Width;
int Height;
unsigned char *workingSurface[FILTER_MAX_WORKING_SURFACE_COUNT]; unsigned char *workingSurface[FILTER_MAX_WORKING_SURFACE_COUNT];
void *userData; void *userData;
} SSurface; };
typedef struct SSurface SSurface;
void RenderDeposterize(SSurface Src, SSurface Dst); void RenderDeposterize(SSurface Src, SSurface Dst);

View File

@ -149,9 +149,9 @@
// } // }
//} //}
static void hq2x_32_def(u32 *__restrict dst0, u32 *__restrict dst1, const u32 *src0, const u32 *src1, const u32 *src2, unsigned count) static void hq2x_32_def(u32 *__restrict dst0, u32 *__restrict dst1, const u32 *src0, const u32 *src1, const u32 *src2, size_t count)
{ {
for (unsigned i = 0; i < count; ++i) for (size_t i = 0; i < count; ++i)
{ {
u8 mask = 0; u8 mask = 0;
u32 c[9]; u32 c[9];
@ -407,9 +407,9 @@ static void hq2x_32_def(u32 *__restrict dst0, u32 *__restrict dst1, const u32 *s
// } // }
//} //}
static void hq2xS_32_def(u32 *__restrict dst0, u32 *__restrict dst1, const u32 *src0, const u32 *src1, const u32 *src2, unsigned count) static void hq2xS_32_def(u32 *__restrict dst0, u32 *__restrict dst1, const u32 *src0, const u32 *src1, const u32 *src2, size_t count)
{ {
for (unsigned i = 0; i < count; ++i) for (size_t i = 0; i < count; ++i)
{ {
u8 mask = 0; u8 mask = 0;
u32 c[9]; u32 c[9];
@ -460,7 +460,7 @@ static void hq2xS_32_def(u32 *__restrict dst0, u32 *__restrict dst1, const u32 *
brightArray[j] = bright; brightArray[j] = bright;
} }
int diffBright = ((maxBright - minBright) * 7) >> 4; u32 diffBright = ((u32)(maxBright - minBright) * 7) >> 4;
if(diffBright > 7) if(diffBright > 7)
{ {
const int centerBright = brightArray[4]; const int centerBright = brightArray[4];

View File

@ -39,9 +39,9 @@
* This effect is a rewritten implementation of the hq3x effect made by Maxim Stepin * This effect is a rewritten implementation of the hq3x effect made by Maxim Stepin
*/ */
void hq3x_32_def(u32 *__restrict dst0, u32 *__restrict dst1, u32 *__restrict dst2, const u32 *src0, const u32 *src1, const u32 *src2, int count) void hq3x_32_def(u32 *__restrict dst0, u32 *__restrict dst1, u32 *__restrict dst2, const u32 *src0, const u32 *src1, const u32 *src2, size_t count)
{ {
for (int i = 0; i < count; ++i) for (size_t i = 0; i < count; ++i)
{ {
u8 mask = 0; u8 mask = 0;
u32 c[9]; u32 c[9];
@ -125,9 +125,9 @@ void hq3x_32_def(u32 *__restrict dst0, u32 *__restrict dst1, u32 *__restrict dst
} }
} }
void hq3xS_32_def(u32 *__restrict dst0, u32 *__restrict dst1, u32 *__restrict dst2, const u32 *src0, const u32 *src1, const u32 *src2, int count) void hq3xS_32_def(u32 *__restrict dst0, u32 *__restrict dst1, u32 *__restrict dst2, const u32 *src0, const u32 *src1, const u32 *src2, size_t count)
{ {
for (int i = 0; i < count; ++i) for (size_t i = 0; i < count; ++i)
{ {
u8 mask = 0; u8 mask = 0;
u32 c[9]; u32 c[9];
@ -178,7 +178,7 @@ void hq3xS_32_def(u32 *__restrict dst0, u32 *__restrict dst1, u32 *__restrict ds
brightArray[j] = bright; brightArray[j] = bright;
} }
unsigned int diffBright = ((maxBright - minBright) * 7) >> 4; u32 diffBright = ((u32)(maxBright - minBright) * 7) >> 4;
if(diffBright > 7) if(diffBright > 7)
{ {
const int centerBright = brightArray[4]; const int centerBright = brightArray[4];

View File

@ -41,9 +41,9 @@
void hq4x_32_def(u32 *__restrict dst0, u32 *__restrict dst1, u32 *__restrict dst2, u32 *__restrict dst3, void hq4x_32_def(u32 *__restrict dst0, u32 *__restrict dst1, u32 *__restrict dst2, u32 *__restrict dst3,
const u32 *src0, const u32 *src1, const u32 *src2, const u32 *src0, const u32 *src1, const u32 *src2,
unsigned count, unsigned flag) size_t count, unsigned flag)
{ {
for (unsigned i = 0; i < count; ++i) for (size_t i = 0; i < count; ++i)
{ {
u8 mask = 0; u8 mask = 0;
u32 c[9]; u32 c[9];
@ -130,9 +130,9 @@ void hq4x_32_def(u32 *__restrict dst0, u32 *__restrict dst1, u32 *__restrict dst
void hq4xS_32_def(u32 *__restrict dst0, u32 *__restrict dst1, u32 *__restrict dst2, u32 *__restrict dst3, void hq4xS_32_def(u32 *__restrict dst0, u32 *__restrict dst1, u32 *__restrict dst2, u32 *__restrict dst3,
const u32 *src0, const u32 *src1, const u32 *src2, const u32 *src0, const u32 *src1, const u32 *src2,
unsigned count, unsigned flag) size_t count, unsigned flag)
{ {
for (unsigned i = 0; i < count; ++i) for (size_t i = 0; i < count; ++i)
{ {
u8 mask = 0; u8 mask = 0;
u32 c[9]; u32 c[9];
@ -183,7 +183,7 @@ void hq4xS_32_def(u32 *__restrict dst0, u32 *__restrict dst1, u32 *__restrict ds
brightArray[j] = bright; brightArray[j] = bright;
} }
unsigned int diffBright = ((maxBright - minBright) * 7) >> 4; u32 diffBright = ((u32)(maxBright - minBright) * 7) >> 4;
if(diffBright > 7) if(diffBright > 7)
{ {
const int centerBright = brightArray[4]; const int centerBright = brightArray[4];

View File

@ -270,13 +270,11 @@
// } // }
//} //}
static void lq2x_32_def(u32* dst0, u32* dst1, const u32* src0, const u32* src1, const u32* src2, unsigned count) static void lq2x_32_def(u32* dst0, u32* dst1, const u32* src0, const u32* src1, const u32* src2, size_t count)
{ {
unsigned i; for (size_t i = 0; i < count; ++i)
{
for(i=0;i<count;++i) { u8 mask = 0;
unsigned char mask;
u32 c[9]; u32 c[9];
c[1] = src0[0]; c[1] = src0[0];
@ -303,8 +301,6 @@ static void lq2x_32_def(u32* dst0, u32* dst1, const u32* src0, const u32* src1,
c[8] = c[7]; c[8] = c[7];
} }
mask = 0;
if (c[0] != c[4]) if (c[0] != c[4])
mask |= 1 << 0; mask |= 1 << 0;
if (c[1] != c[4]) if (c[1] != c[4])
@ -380,14 +376,12 @@ static void lq2x_32_def(u32* dst0, u32* dst1, const u32* src0, const u32* src1,
} }
} }
static void lq2xS_32_def(u32* dst0, u32* dst1, const u32* src0, const u32* src1, const u32* src2, unsigned count) static void lq2xS_32_def(u32* dst0, u32* dst1, const u32* src0, const u32* src1, const u32* src2, size_t count)
{ {
unsigned i; for (size_t i = 0; i < count; ++i)
{
for(i=0;i<count;++i) { u8 mask = 0;
unsigned char mask = 0; u32 c[9];
u32 c[9];
c[1] = src0[0]; c[1] = src0[0];
c[4] = src1[0]; c[4] = src1[0];
@ -429,7 +423,7 @@ static void lq2xS_32_def(u32* dst0, u32* dst1, const u32* src0, const u32* src1,
brightArray[j] = bright; brightArray[j] = bright;
} }
int diffBright = (maxBright - minBright) >> 4; u32 diffBright = (u32)(maxBright - minBright) >> 4;
if(diffBright > 1) if(diffBright > 1)
{ {
const int centerBright = brightArray[4]; const int centerBright = brightArray[4];

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2011-2012 Roger Manuel Copyright (C) 2011-2012 Roger Manuel
Copyright (C) 2013-2022 DeSmuME team Copyright (C) 2013-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -144,10 +144,10 @@ VideoFilter::~VideoFilter()
void VideoFilter::__InstanceInit(size_t srcWidth, size_t srcHeight, VideoFilterTypeID typeID, size_t threadCount) void VideoFilter::__InstanceInit(size_t srcWidth, size_t srcHeight, VideoFilterTypeID typeID, size_t threadCount)
{ {
SSurface newSurface; SSurface newSurface;
newSurface.Surface = NULL; newSurface.Surface = NULL;
newSurface.Pitch = srcWidth*2; newSurface.Pitch = (int)(srcWidth * 2);
newSurface.Width = srcWidth; newSurface.Width = (int)srcWidth;
newSurface.Height = srcHeight; newSurface.Height = (int)srcHeight;
newSurface.userData = NULL; newSurface.userData = NULL;
for (size_t i = 0; i < FILTER_MAX_WORKING_SURFACE_COUNT; i++) for (size_t i = 0; i < FILTER_MAX_WORKING_SURFACE_COUNT; i++)
@ -228,9 +228,9 @@ bool VideoFilter::__AllocateDstBuffer(const size_t dstWidth, const size_t dstHei
} }
// Set up SSurface structure. // Set up SSurface structure.
this->__vfDstSurface.Width = dstWidth; this->__vfDstSurface.Width = (int)dstWidth;
this->__vfDstSurface.Height = dstHeight; this->__vfDstSurface.Height = (int)dstHeight;
this->__vfDstSurface.Pitch = dstWidth * 2; this->__vfDstSurface.Pitch = (int)(dstWidth * 2);
if (_useInternalDstBuffer) if (_useInternalDstBuffer)
{ {
@ -241,8 +241,8 @@ bool VideoFilter::__AllocateDstBuffer(const size_t dstWidth, const size_t dstHei
// Update the surfaces on threads. // Update the surfaces on threads.
const size_t threadCount = this->__vfThread.size(); const size_t threadCount = this->__vfThread.size();
const unsigned int linesPerThread = (threadCount > 1) ? dstHeight/threadCount : dstHeight; const int linesPerThread = (threadCount > 1) ? (int)(dstHeight/threadCount) : (int)dstHeight;
unsigned int remainingLines = dstHeight; int remainingLines = (int)dstHeight;
for (size_t i = 0; i < threadCount; i++) for (size_t i = 0; i < threadCount; i++)
{ {
@ -306,14 +306,14 @@ bool VideoFilter::SetSourceSize(const size_t width, const size_t height)
} }
memset(newPixBuffer, 0, width * (height + 8) * sizeof(uint32_t)); memset(newPixBuffer, 0, width * (height + 8) * sizeof(uint32_t));
if (this->__vfSrcSurface.Surface == NULL || this->__vfSrcSurface.Width != width || this->__vfSrcSurface.Height != height) if ( (this->__vfSrcSurface.Surface == NULL) || ((size_t)this->__vfSrcSurface.Width != width) || ((size_t)this->__vfSrcSurface.Height != height) )
{ {
sizeChanged = true; sizeChanged = true;
} }
this->__vfSrcSurface.Width = width; this->__vfSrcSurface.Width = (int)width;
this->__vfSrcSurface.Height = height; this->__vfSrcSurface.Height = (int)height;
this->__vfSrcSurface.Pitch = width * 2; this->__vfSrcSurface.Pitch = (int)(width * 2);
// Set the working source buffer pointer so that the working memory block is padded // Set the working source buffer pointer so that the working memory block is padded
// with 4 pixel rows worth of memory on both sides. // with 4 pixel rows worth of memory on both sides.
this->__vfSrcSurface.Surface = (unsigned char *)(newPixBuffer + (width * 4)); this->__vfSrcSurface.Surface = (unsigned char *)(newPixBuffer + (width * 4));
@ -323,8 +323,8 @@ bool VideoFilter::SetSourceSize(const size_t width, const size_t height)
// Update the surfaces on threads. // Update the surfaces on threads.
size_t threadCount = this->__vfThread.size(); size_t threadCount = this->__vfThread.size();
const unsigned int linesPerThread = (threadCount > 1) ? this->__vfSrcSurface.Height/threadCount : this->__vfSrcSurface.Height; const int linesPerThread = (threadCount > 1) ? this->__vfSrcSurface.Height/(int)threadCount : this->__vfSrcSurface.Height;
unsigned int remainingLines = this->__vfSrcSurface.Height; int remainingLines = this->__vfSrcSurface.Height;
for (size_t i = 0; i < threadCount; i++) for (size_t i = 0; i < threadCount; i++)
{ {
@ -351,7 +351,7 @@ bool VideoFilter::SetSourceSize(const size_t width, const size_t height)
if (sizeChanged) if (sizeChanged)
{ {
const VideoFilterAttributes vfAttr = this->GetAttributes(); const VideoFilterAttributes vfAttr = this->GetAttributes();
const size_t dstWidth = width * vfAttr.scaleMultiply / vfAttr.scaleDivide; const size_t dstWidth = width * vfAttr.scaleMultiply / vfAttr.scaleDivide;
const size_t dstHeight = height * vfAttr.scaleMultiply / vfAttr.scaleDivide; const size_t dstHeight = height * vfAttr.scaleMultiply / vfAttr.scaleDivide;
this->_pixelScale = (float)vfAttr.scaleMultiply / (float)vfAttr.scaleDivide; this->_pixelScale = (float)vfAttr.scaleMultiply / (float)vfAttr.scaleDivide;
@ -625,16 +625,16 @@ void VideoFilter::RunFilterCustomByAttributes(const uint32_t *__restrict srcBuff
SSurface srcSurface; SSurface srcSurface;
memset(&srcSurface, 0, sizeof(srcSurface)); memset(&srcSurface, 0, sizeof(srcSurface));
srcSurface.Surface = (unsigned char *)srcBuffer; srcSurface.Surface = (unsigned char *)srcBuffer;
srcSurface.Pitch = srcWidth*2; srcSurface.Pitch = (int)(srcWidth * 2);
srcSurface.Width = srcWidth; srcSurface.Width = (int)srcWidth;
srcSurface.Height = srcHeight; srcSurface.Height = (int)srcHeight;
SSurface dstSurface; SSurface dstSurface;
memset(&dstSurface, 0, sizeof(dstSurface)); memset(&dstSurface, 0, sizeof(dstSurface));
dstSurface.Surface = (unsigned char *)dstBuffer; dstSurface.Surface = (unsigned char *)dstBuffer;
dstSurface.Pitch = dstWidth*2; dstSurface.Pitch = (int)(dstWidth * 2);
dstSurface.Width = dstWidth; dstSurface.Width = (int)dstWidth;
dstSurface.Height = dstHeight; dstSurface.Height = (int)dstHeight;
if (filterFunction == NULL) if (filterFunction == NULL)
{ {

View File

@ -16,12 +16,16 @@
// * do so, delete this exception statement from your version. * // * do so, delete this exception statement from your version. *
// **************************************************************************** // ****************************************************************************
// 2025-07-15 (rogerman): Add support for big-endian byte order.
// 2024-08-01 (rogerman): Small performance optimization to
// ColorDistanceARGB::dist(). (Special thanks to m42a
// for this.)
// 2016-03-04 (rogerman): Update to XBRZ 1.4. // 2016-03-04 (rogerman): Update to XBRZ 1.4.
// //
// 2014-11-18 (rogerman): Update to XBRZ 1.1. // 2014-11-18 (rogerman): Update to XBRZ 1.1.
// //
// 2014-02-06 (rogerman): Modified for use in DeSmuME by removing C++11 code. // 2014-02-06 (rogerman): Modified for use in DeSmuME by removing C++11 code.
// Also add render functions compatible with filter.h. // Also add render functions compatible with filter.h.
#include "xbrz.h" #include "xbrz.h"
#include "filter.h" #include "filter.h"
@ -38,10 +42,17 @@
#define FORCE_INLINE inline #define FORCE_INLINE inline
#endif #endif
#define COLOR_MASK_A 0xFF000000 #if defined(MSB_FIRST)
#define COLOR_MASK_R 0x00FF0000 #define COLOR_MASK_A 0x000000FF
#define COLOR_MASK_G 0x0000FF00 #define COLOR_MASK_R 0x0000FF00
#define COLOR_MASK_B 0x000000FF #define COLOR_MASK_G 0x00FF0000
#define COLOR_MASK_B 0xFF000000
#else
#define COLOR_MASK_A 0xFF000000
#define COLOR_MASK_R 0x00FF0000
#define COLOR_MASK_G 0x0000FF00
#define COLOR_MASK_B 0x000000FF
#endif
namespace namespace
{ {
@ -56,6 +67,24 @@ inline unsigned char getBlue (uint32_t pix) { return getByte<0>(pix); }
inline uint32_t makePixel( unsigned char r, unsigned char g, unsigned char b) { return (r << 16) | (g << 8) | b; } inline uint32_t makePixel( unsigned char r, unsigned char g, unsigned char b) { return (r << 16) | (g << 8) | b; }
inline uint32_t makePixel(unsigned char a, unsigned char r, unsigned char g, unsigned char b) { return (a << 24) | (r << 16) | (g << 8) | b; } inline uint32_t makePixel(unsigned char a, unsigned char r, unsigned char g, unsigned char b) { return (a << 24) | (r << 16) | (g << 8) | b; }
#if defined(MSB_FIRST)
inline unsigned char getAlpha_DesmumeTexture(uint32_t pix) { return getByte<0>(pix); }
inline unsigned char getRed_DesmumeTexture (uint32_t pix) { return getByte<1>(pix); }
inline unsigned char getGreen_DesmumeTexture(uint32_t pix) { return getByte<2>(pix); }
inline unsigned char getBlue_DesmumeTexture (uint32_t pix) { return getByte<3>(pix); }
inline uint32_t makePixel_DesmumeTexture( unsigned char r, unsigned char g, unsigned char b) { return (b << 24) | (g << 16) | (r << 8) ; }
inline uint32_t makePixel_DesmumeTexture(unsigned char a, unsigned char r, unsigned char g, unsigned char b) { return (b << 24) | (g << 16) | (r << 8) | a; }
#else
inline unsigned char getAlpha_DesmumeTexture(uint32_t pix) { return getAlpha(pix); }
inline unsigned char getRed_DesmumeTexture (uint32_t pix) { return getRed (pix); }
inline unsigned char getGreen_DesmumeTexture(uint32_t pix) { return getGreen(pix); }
inline unsigned char getBlue_DesmumeTexture (uint32_t pix) { return getBlue (pix); }
inline uint32_t makePixel_DesmumeTexture( unsigned char r, unsigned char g, unsigned char b) { return makePixel( r,g,b); }
inline uint32_t makePixel_DesmumeTexture(unsigned char a, unsigned char r, unsigned char g, unsigned char b) { return makePixel(a,r,g,b); }
#endif
template <unsigned int M, unsigned int N> FORCE_INLINE template <unsigned int M, unsigned int N> FORCE_INLINE
unsigned char gradientRGB_calcColor(unsigned char colFront, unsigned char colBack) unsigned char gradientRGB_calcColor(unsigned char colFront, unsigned char colBack)
{ {
@ -107,13 +136,17 @@ uint32_t gradientARGB(uint32_t pixFront, uint32_t pixBack) //find intermediate c
template <unsigned int M, unsigned int N> inline template <unsigned int M, unsigned int N> inline
uint32_t gradientARGB_1bitAlpha(uint32_t pixFront, uint32_t pixBack) //special blending mode for NDS textures -- assumes that the alpha component value is either 0x00 or 0xFF uint32_t gradientARGB_1bitAlpha(uint32_t pixFront, uint32_t pixBack) //special blending mode for NDS textures -- assumes that the alpha component value is either 0x00 or 0xFF
{ {
const unsigned int weightFront = getAlpha(pixFront) * M; const unsigned int weightFront = getAlpha_DesmumeTexture(pixFront) * M;
const unsigned int weightBack = getAlpha(pixBack) * (N - M); const unsigned int weightBack = getAlpha_DesmumeTexture(pixBack) * (N - M);
const unsigned int weightSum = weightFront + weightBack; const unsigned int weightSum = weightFront + weightBack;
if (weightSum == 0) if (weightSum == 0)
{ {
#if defined(MSB_FIRST)
return (pixFront & 0xFFFFFF00);
#else
return (pixFront & 0x00FFFFFF); return (pixFront & 0x00FFFFFF);
#endif
} }
else if (weightFront == 0) else if (weightFront == 0)
{ {
@ -125,10 +158,10 @@ uint32_t gradientARGB_1bitAlpha(uint32_t pixFront, uint32_t pixBack) //special b
} }
// At this point, we know that both pixels must be opaque, so treat them as such. // At this point, we know that both pixels must be opaque, so treat them as such.
return makePixel(0xFF, return makePixel_DesmumeTexture(0xFF,
gradientRGB_calcColor<M, N>(getRed (pixFront), getRed (pixBack)), gradientRGB_calcColor<M, N>(getRed_DesmumeTexture (pixFront), getRed_DesmumeTexture (pixBack)),
gradientRGB_calcColor<M, N>(getGreen(pixFront), getGreen(pixBack)), gradientRGB_calcColor<M, N>(getGreen_DesmumeTexture(pixFront), getGreen_DesmumeTexture(pixBack)),
gradientRGB_calcColor<M, N>(getBlue (pixFront), getBlue (pixBack))); gradientRGB_calcColor<M, N>(getBlue_DesmumeTexture (pixFront), getBlue_DesmumeTexture (pixBack)));
} }
//inline //inline
@ -1152,28 +1185,65 @@ struct ColorDistanceARGB
{ {
static double dist(uint32_t pix1, uint32_t pix2, double luminanceWeight) static double dist(uint32_t pix1, uint32_t pix2, double luminanceWeight)
{ {
const double a1 = getAlpha(pix1) / 255.0 ; const int a1 = getAlpha(pix1);
const double a2 = getAlpha(pix2) / 255.0 ; const int a2 = getAlpha(pix2);
/*
Requirements for a color distance handling alpha channel: with a1, a2 in [0, 1] // Requirements for a color distance handling alpha channel: with a1, a2 in [0, 1]
1. if a1 = a2, distance should be: a1 * distYCbCr() // 1. if a1 = a2, distance should be: a1 * distYCbCr()
2. if a1 = 0, distance should be: a2 * distYCbCr(black, white) = a2 * 255 // 2. if a1 = 0, distance should be: a2 * distYCbCr(black, white) = a2 * 255
3. if a1 = 1, ??? maybe: 255 * (1 - a2) + a2 * distYCbCr() // 3. if a1 = 1, ??? maybe: 255 * (1 - a2) + a2 * distYCbCr()
*/
if (a1 == 0)
return a2;
if (a2 == 0)
return a1;
//return std::min(a1, a2) * DistYCbCrBuffer::dist(pix1, pix2) + 255 * abs(a1 - a2); //return std::min(a1, a2) * DistYCbCrBuffer::dist(pix1, pix2) + 255 * abs(a1 - a2);
//=> following code is 15% faster: //=> following code is 15% faster:
const double d = DistYCbCrBuffer::dist(pix1, pix2); const double d = DistYCbCrBuffer::dist(pix1, pix2);
if (a1 == 255 && a2 == 255)
return d;
if (a1 == a2)
return a1 * d / 255.0;
if (a1 < a2) if (a1 < a2)
return a1 * d + 255 * (a2 - a1); return a1 * d / 255.0 + (a2 - a1);
else else
return a2 * d + 255 * (a1 - a2); return a2 * d / 255.0 + (a1 - a2);
//alternative? return std::sqrt(a1 * a2 * square(DistYCbCrBuffer::dist(pix1, pix2)) + square(255 * (a1 - a2))); //alternative? return std::sqrt(a1 * a2 * square(DistYCbCrBuffer::dist(pix1, pix2)) + square(255 * (a1 - a2)));
} }
}; };
struct ColorDistanceARGB_DesmumeTexture
{
static double dist(uint32_t pix1, uint32_t pix2, double luminanceWeight)
{
const int a1 = getAlpha_DesmumeTexture(pix1);
const int a2 = getAlpha_DesmumeTexture(pix2);
if (a1 == 0)
return a2;
if (a2 == 0)
return a1;
#if defined(MSB_FIRST)
const uint32_t pix1Swapped = ((pix1 & 0x000000FF) << 24) | ((pix1 & 0x0000FF00) << 8) | ((pix1 >> 8) & 0x0000FF00) | ((pix1 >> 24) & 0x000000FF);
const uint32_t pix2Swapped = ((pix2 & 0x000000FF) << 24) | ((pix2 & 0x0000FF00) << 8) | ((pix2 >> 8) & 0x0000FF00) | ((pix2 >> 24) & 0x000000FF);
const double d = DistYCbCrBuffer::dist(pix1Swapped, pix2Swapped);
#else
const double d = DistYCbCrBuffer::dist(pix1, pix2);
#endif
if (a1 == 255 && a2 == 255)
return d;
if (a1 == a2)
return a1 * d / 255.0;
if (a1 < a2)
return a1 * d / 255.0 + (a2 - a1);
else
return a2 * d / 255.0 + (a1 - a2);
}
};
struct ColorGradientRGB struct ColorGradientRGB
{ {
@ -1212,15 +1282,15 @@ void xbrz::scale(const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight
switch (SCALEFACTOR) switch (SCALEFACTOR)
{ {
case 2: case 2:
return scaleImage<Scaler2x<ColorGradientARGB_1bitAlpha>, ColorDistanceARGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); return scaleImage<Scaler2x<ColorGradientARGB_1bitAlpha>, ColorDistanceARGB_DesmumeTexture>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
case 3: case 3:
return scaleImage<Scaler3x<ColorGradientARGB_1bitAlpha>, ColorDistanceARGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); return scaleImage<Scaler3x<ColorGradientARGB_1bitAlpha>, ColorDistanceARGB_DesmumeTexture>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
case 4: case 4:
return scaleImage<Scaler4x<ColorGradientARGB_1bitAlpha>, ColorDistanceARGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); return scaleImage<Scaler4x<ColorGradientARGB_1bitAlpha>, ColorDistanceARGB_DesmumeTexture>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
case 5: case 5:
return scaleImage<Scaler5x<ColorGradientARGB_1bitAlpha>, ColorDistanceARGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); return scaleImage<Scaler5x<ColorGradientARGB_1bitAlpha>, ColorDistanceARGB_DesmumeTexture>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
case 6: case 6:
return scaleImage<Scaler6x<ColorGradientARGB_1bitAlpha>, ColorDistanceARGB>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast); return scaleImage<Scaler6x<ColorGradientARGB_1bitAlpha>, ColorDistanceARGB_DesmumeTexture>(src, trg, srcWidth, srcHeight, cfg, yFirst, yLast);
} }
break; break;

View File

@ -13,12 +13,15 @@
// * do so, delete this exception statement from your version. * // * do so, delete this exception statement from your version. *
// **************************************************************************** // ****************************************************************************
// 2024-08-01 (rogerman): Small performance optimization to
// ColorDistanceARGB::dist(). (Special thanks to m42a
// for this.)
// 2016-03-04 (rogerman): Update to XBRZ 1.4. // 2016-03-04 (rogerman): Update to XBRZ 1.4.
// //
// 2014-11-18 (rogerman): Update to XBRZ 1.1. // 2014-11-18 (rogerman): Update to XBRZ 1.1.
// //
// 2014-02-06 (rogerman): Modified for use in DeSmuME by removing C++11 code. // 2014-02-06 (rogerman): Modified for use in DeSmuME by removing C++11 code.
// Also integrate xbrz's config.h file into this one. // Also integrate xbrz's config.h file into this one.
#ifndef XBRZ_HEADER_3847894708239054 #ifndef XBRZ_HEADER_3847894708239054
#define XBRZ_HEADER_3847894708239054 #define XBRZ_HEADER_3847894708239054

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2009-2022 DeSmuME Team Copyright (C) 2009-2025 DeSmuME Team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -34,6 +34,16 @@
static _KEY1 enc(&MMU.ARM7_BIOS[0x0030]); static _KEY1 enc(&MMU.ARM7_BIOS[0x0030]);
const char *defaultNickname = DESMUME_NAME; const char *defaultNickname = DESMUME_NAME;
const char *defaultMessage = DESMUME_NAME " makes you happy!"; const char *defaultMessage = DESMUME_NAME " makes you happy!";
const char *defaultMacAddressStr = "0009BF123456";
CFIRMWARE::CFIRMWARE()
{
memset(&_header, 0, sizeof(_header));
_fwFilePath = "";
_isLoaded = false;
_userDataAddr = 0x0003FE00;
}
u16 CFIRMWARE::_getBootCodeCRC16(const u8 *arm9Data, const u32 arm9Size, const u8 *arm7Data, const u32 arm7Size) u16 CFIRMWARE::_getBootCodeCRC16(const u8 *arm9Data, const u32 arm9Size, const u8 *arm7Data, const u32 arm7Size)
{ {
@ -261,7 +271,7 @@ bool CFIRMWARE::load(const char *firmwareFilePath)
this->_header = newFirmwareData->header; this->_header = newFirmwareData->header;
if (MMU.fw.size != fileSize) // reallocate if (MMU.fw.size != fileSize) // reallocate
mc_alloc(&MMU.fw, fileSize); mc_alloc(&MMU.fw, (u32)fileSize);
this->_userDataAddr = LE_TO_LOCAL_16(newFirmwareData->header.userSettingsOffset) * 8; this->_userDataAddr = LE_TO_LOCAL_16(newFirmwareData->header.userSettingsOffset) * 8;
@ -675,6 +685,47 @@ int copy_firmware_user_data( u8 *dest_buffer, const u8 *fw_data)
return copy_good; return copy_good;
} }
void NDS_GetFirmwareMACAddressAsStr(const FirmwareConfig& config, char outMacStr[13])
{
for (u8 i = 0; i < 6; i++) {
for (u8 j = 0; j < 2; j++) {
u8 u4Bits = j == 0 ? config.MACAddress[i] / 16 : config.MACAddress[i] % 16;
outMacStr[i * 2 + j] = u4Bits >= 10 ? 'A' + (u4Bits - 10) : '0' + u4Bits;
}
}
outMacStr[12] = '\0';
}
void NDS_SetFirmwareMACAddressFromStr(FirmwareConfig& config, const char* macStr)
{
for (size_t i = 0; i < sizeof(config.MACAddress); i++)
config.MACAddress[i] = 0;
// Each letter in macStr represents a 4-bits value (u4) of the mac address.
size_t macStrLen = strlen(macStr);
if (macStrLen > 12)
macStrLen = 12;
const size_t missingLetterCount = 12 - macStrLen;
for (size_t i = 0; i < macStrLen; i++) {
char letter = macStr[i];
u8 macU4Val = 0;
if (letter >= '0' && letter <= '9')
macU4Val = letter - '0';
else if (letter >= 'A' && letter <= 'F')
macU4Val = letter - 'A' + 10;
else if (letter >= 'a' && letter <= 'f')
macU4Val = letter - 'a' + 10;
// Invalid letters are treated as 0.
const size_t u4Idx = i + missingLetterCount; // u4Idx is between 0-12
const size_t u8Idx = u4Idx / 2;
const bool isHighBits = u4Idx % 2 == 0;
config.MACAddress[u8Idx] += isHighBits ? macU4Val << 4 : macU4Val;
}
}
void NDS_GetDefaultFirmwareConfig(FirmwareConfig &outConfig) void NDS_GetDefaultFirmwareConfig(FirmwareConfig &outConfig)
{ {
memset(&outConfig, 0, sizeof(FirmwareConfig)); memset(&outConfig, 0, sizeof(FirmwareConfig));

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2009-2022 DeSmuME Team Copyright (C) 2009-2025 DeSmuME Team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -35,6 +35,7 @@
extern const char *defaultNickname; extern const char *defaultNickname;
extern const char *defaultMessage; extern const char *defaultMessage;
extern const char* defaultMacAddressStr;
struct FirmwareConfig struct FirmwareConfig
{ {
@ -427,12 +428,12 @@ private:
bool _isLoaded; bool _isLoaded;
u32 _userDataAddr; u32 _userDataAddr;
u16 _getBootCodeCRC16(const u8 *arm9Data, const u32 arm9Size, const u8 *arm7Data, const u32 arm7Size); u16 _getBootCodeCRC16(const u8 *arm9Data, const u32 arm9Size, const u8 *arm7Data, const u32 arm7Size);
u32 _decrypt(const u8 *in, u8* &out); u32 _decrypt(const u8 *in, u8* &out);
u32 _decompress(const u8 *in, u8* &out); u32 _decompress(const u8 *in, u8* &out);
public: public:
CFIRMWARE(): _userDataAddr(0x3FE00), _isLoaded(false) {}; CFIRMWARE();
bool load(const char *firmwareFilePath); bool load(const char *firmwareFilePath);
bool unpack(); bool unpack();
@ -447,6 +448,8 @@ public:
int copy_firmware_user_data( u8 *dest_buffer, const u8 *fw_data); int copy_firmware_user_data( u8 *dest_buffer, const u8 *fw_data);
void NDS_GetFirmwareMACAddressAsStr(const FirmwareConfig& config, char outMacStr[13]);
void NDS_SetFirmwareMACAddressFromStr(FirmwareConfig& config, const char* MacStr);
void NDS_GetDefaultFirmwareConfig(FirmwareConfig &outConfig); void NDS_GetDefaultFirmwareConfig(FirmwareConfig &outConfig);
void NDS_GetCurrentWFCUserID(u8 *outMAC, u8 *outUserID); void NDS_GetCurrentWFCUserID(u8 *outMAC, u8 *outUserID);
void NDS_ApplyFirmwareSettings(NDSFirmwareData *outFirmware, void NDS_ApplyFirmwareSettings(NDSFirmwareData *outFirmware,

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2018 DeSmuME team Copyright (C) 2018-2023 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -134,7 +134,7 @@ void ClientAVCaptureFileStream::InitBaseProperties(const AVFileTypeID fileTypeID
this->_expectedMaxFrameSize = videoFrameSize + audioFrameSize; this->_expectedMaxFrameSize = videoFrameSize + audioFrameSize;
_semQueue = ssem_new(pendingFrameCount); _semQueue = ssem_new((int)pendingFrameCount);
} }
AVFileTypeVideoCodecID ClientAVCaptureFileStream::GetVideoCodecID() AVFileTypeVideoCodecID ClientAVCaptureFileStream::GetVideoCodecID()
@ -484,7 +484,7 @@ void ClientAVCaptureObject::ConvertVideoSlice555Xto888(const VideoConvertParam &
const u16 *__restrict src = (const u16 *__restrict)param.src; const u16 *__restrict src = (const u16 *__restrict)param.src;
u8 *__restrict dst = param.dst; u8 *__restrict dst = param.dst;
ColorspaceConvertBuffer555XTo888<false, false>(src, dst, param.frameWidth * lineCount); ColorspaceConvertBuffer555xTo888<false, false>(src, dst, param.frameWidth * lineCount);
} }
//converts 32bpp to 24bpp and flips //converts 32bpp to 24bpp and flips
@ -494,7 +494,7 @@ void ClientAVCaptureObject::ConvertVideoSlice888Xto888(const VideoConvertParam &
const u32 *__restrict src = (const u32 *__restrict)param.src; const u32 *__restrict src = (const u32 *__restrict)param.src;
u8 *__restrict dst = param.dst; u8 *__restrict dst = param.dst;
ColorspaceConvertBuffer888XTo888<false, false>(src, dst, param.frameWidth * lineCount); ColorspaceConvertBuffer888xTo888<false, false>(src, dst, param.frameWidth * lineCount);
} }
void ClientAVCaptureObject::CaptureVideoFrame(const void *srcVideoFrame, const size_t inFrameWidth, const size_t inFrameHeight, const NDSColorFormat colorFormat) void ClientAVCaptureObject::CaptureVideoFrame(const void *srcVideoFrame, const size_t inFrameWidth, const size_t inFrameHeight, const NDSColorFormat colorFormat)

View File

@ -88,7 +88,7 @@ enum AVFileTypeID
AVFileTypeID_m4a_ALAC = (AVFileTypeContainerID_m4a | AVFileTypeVideoCodecID_None | AVFileTypeAudioCodecID_ALAC), // dec = 8453936 AVFileTypeID_m4a_ALAC = (AVFileTypeContainerID_m4a | AVFileTypeVideoCodecID_None | AVFileTypeAudioCodecID_ALAC), // dec = 8453936
AVFileTypeID_aiff_PCMs16BE = (AVFileTypeContainerID_aiff | AVFileTypeVideoCodecID_None | AVFileTypeAudioCodecID_PCMs16BE), // dec = 8519456 AVFileTypeID_aiff_PCMs16BE = (AVFileTypeContainerID_aiff | AVFileTypeVideoCodecID_None | AVFileTypeAudioCodecID_PCMs16BE), // dec = 8519456
AVFileTypeID_flac_FLAC = (AVFileTypeContainerID_flac | AVFileTypeVideoCodecID_None | AVFileTypeAudioCodecID_FLAC), // dec = 8585024 AVFileTypeID_flac_FLAC = (AVFileTypeContainerID_flac | AVFileTypeVideoCodecID_None | AVFileTypeAudioCodecID_FLAC), // dec = 8585024
AVFileTypeID_wav_PCMs16LE = (AVFileTypeContainerID_wav | AVFileTypeVideoCodecID_None | AVFileTypeAudioCodecID_PCMs16LE), // dec = 8650512 AVFileTypeID_wav_PCMs16LE = (AVFileTypeContainerID_wav | AVFileTypeVideoCodecID_None | AVFileTypeAudioCodecID_PCMs16LE) // dec = 8650512
}; };
enum enum

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2017-2018 DeSmuME team Copyright (C) 2017-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -101,16 +101,16 @@ void ClientDisplayPresenter::__InstanceInit(const ClientDisplayPresenterProperti
_showRTC = false; _showRTC = false;
_showInputs = false; _showInputs = false;
_hudColorExecutionSpeed = LE_TO_LOCAL_32(0xFFFFFFFF); _hudColorExecutionSpeed = 0xFFFFFFFF;
_hudColorVideoFPS = LE_TO_LOCAL_32(0xFFFFFFFF); _hudColorVideoFPS = 0xFFFFFFFF;
_hudColorRender3DFPS = LE_TO_LOCAL_32(0xFFFFFFFF); _hudColorRender3DFPS = 0xFFFFFFFF;
_hudColorFrameIndex = LE_TO_LOCAL_32(0xFFFFFFFF); _hudColorFrameIndex = 0xFFFFFFFF;
_hudColorLagFrameCount = LE_TO_LOCAL_32(0xFFFFFFFF); _hudColorLagFrameCount = 0xFFFFFFFF;
_hudColorCPULoadAverage = LE_TO_LOCAL_32(0xFFFFFFFF); _hudColorCPULoadAverage = 0xFFFFFFFF;
_hudColorRTC = LE_TO_LOCAL_32(0xFFFFFFFF); _hudColorRTC = 0xFFFFFFFF;
_hudColorInputAppliedAndPending = LE_TO_LOCAL_32(0xFFFFFFFF); _hudColorInputAppliedAndPending = 0xFFFFFFFF;
_hudColorInputAppliedOnly = LE_TO_LOCAL_32(0xFF3030FF); _hudColorInputAppliedOnly = 0xFF3030FF;
_hudColorInputPendingOnly = LE_TO_LOCAL_32(0xFF00C000); _hudColorInputPendingOnly = 0xFF00C000;
_clientFrameInfo.videoFPS = 0; _clientFrameInfo.videoFPS = 0;
_ndsFrameInfo.clear(); _ndsFrameInfo.clear();
@ -256,15 +256,18 @@ double ClientDisplayPresenter::GetScaleFactor() const
void ClientDisplayPresenter::SetScaleFactor(const double scaleFactor) void ClientDisplayPresenter::SetScaleFactor(const double scaleFactor)
{ {
const bool willChangeScaleFactor = (this->_scaleFactor != scaleFactor); const bool willChangeScaleFactor = (this->_scaleFactor != scaleFactor);
this->_scaleFactor = scaleFactor;
if (willChangeScaleFactor) if (!willChangeScaleFactor)
{ {
this->_glyphTileSize = (double)HUD_TEXTBOX_BASEGLYPHSIZE * scaleFactor; return;
this->_glyphSize = (double)this->_glyphTileSize * 0.75;
this->LoadHUDFont();
} }
this->_scaleFactor = scaleFactor;
this->_glyphTileSize = (double)HUD_TEXTBOX_BASEGLYPHSIZE * scaleFactor;
this->_glyphSize = (double)this->_glyphTileSize * 0.75;
this->LoadHUDFont();
this->_UpdateViewScale();
} }
void ClientDisplayPresenter::_UpdateClientSize() void ClientDisplayPresenter::_UpdateClientSize()
@ -292,6 +295,10 @@ void ClientDisplayPresenter::_UpdateViewScale()
} }
this->_hudObjectScale *= this->_scaleFactor; this->_hudObjectScale *= this->_scaleFactor;
pthread_mutex_lock(&this->_mutexHUDString);
this->_hudNeedsUpdate = true;
pthread_mutex_unlock(&this->_mutexHUDString);
} }
// NDS screen layout // NDS screen layout
@ -2006,10 +2013,10 @@ void ClientDisplay3DPresenter::SetHUDColorVertices(uint32_t *vtxColorBufferPtr)
continue; continue;
} }
vtxColorBufferPtr[j+0] = currentColor; // Top Left vtxColorBufferPtr[j+0] = LE_TO_LOCAL_32(currentColor); // Top Left
vtxColorBufferPtr[j+1] = currentColor; // Top Right vtxColorBufferPtr[j+1] = LE_TO_LOCAL_32(currentColor); // Top Right
vtxColorBufferPtr[j+2] = currentColor; // Bottom Right vtxColorBufferPtr[j+2] = LE_TO_LOCAL_32(currentColor); // Bottom Right
vtxColorBufferPtr[j+3] = currentColor; // Bottom Left vtxColorBufferPtr[j+3] = LE_TO_LOCAL_32(currentColor); // Bottom Left
} }
// Fill in the vertices for the inputs. // Fill in the vertices for the inputs.
@ -2041,20 +2048,20 @@ void ClientDisplay3DPresenter::SetHUDColorVertices(uint32_t *vtxColorBufferPtr)
for (size_t k = 0; k < HUD_INPUT_ELEMENT_LENGTH; i++, j+=4, k++) for (size_t k = 0; k < HUD_INPUT_ELEMENT_LENGTH; i++, j+=4, k++)
{ {
vtxColorBufferPtr[j+0] = inputColors[k]; // Top Left vtxColorBufferPtr[j+0] = LE_TO_LOCAL_32(inputColors[k]); // Top Left
vtxColorBufferPtr[j+1] = inputColors[k]; // Top Right vtxColorBufferPtr[j+1] = LE_TO_LOCAL_32(inputColors[k]); // Top Right
vtxColorBufferPtr[j+2] = inputColors[k]; // Bottom Right vtxColorBufferPtr[j+2] = LE_TO_LOCAL_32(inputColors[k]); // Bottom Right
vtxColorBufferPtr[j+3] = inputColors[k]; // Bottom Left vtxColorBufferPtr[j+3] = LE_TO_LOCAL_32(inputColors[k]); // Bottom Left
} }
touchColor = ((this->_ndsFrameInfo.inputStatesPending.Touch != 0) && (this->_ndsFrameInfo.inputStatesApplied.Touch != 0)) ? 0x00000000 : (touchColor & LE_TO_LOCAL_32(0x00FFFFFF)) | LE_TO_LOCAL_32(0x60000000); touchColor = ((this->_ndsFrameInfo.inputStatesPending.Touch != 0) && (this->_ndsFrameInfo.inputStatesApplied.Touch != 0)) ? 0x00000000 : LE_TO_LOCAL_32((touchColor & 0x00FFFFFF) | 0x60000000);
for (size_t k = 0; k < HUD_INPUT_TOUCH_LINE_ELEMENTS; i++, j+=4, k++) for (size_t k = 0; k < HUD_INPUT_TOUCH_LINE_ELEMENTS; i++, j+=4, k++)
{ {
vtxColorBufferPtr[j+0] = touchColor; // Top Left vtxColorBufferPtr[j+0] = touchColor; // Top Left
vtxColorBufferPtr[j+1] = touchColor; // Top Right vtxColorBufferPtr[j+1] = touchColor; // Top Right
vtxColorBufferPtr[j+2] = touchColor; // Bottom Right vtxColorBufferPtr[j+2] = touchColor; // Bottom Right
vtxColorBufferPtr[j+3] = touchColor; // Bottom Left vtxColorBufferPtr[j+3] = touchColor; // Bottom Left
} }
} }

View File

@ -245,7 +245,7 @@ protected:
public: public:
ClientExecutionControl(); ClientExecutionControl();
~ClientExecutionControl(); virtual ~ClientExecutionControl();
ClientAVCaptureObject* GetClientAVCaptureObject(); ClientAVCaptureObject* GetClientAVCaptureObject();
ClientAVCaptureObject* GetClientAVCaptureObjectApplied(); ClientAVCaptureObject* GetClientAVCaptureObjectApplied();

View File

@ -331,6 +331,7 @@ typedef std::vector<ClientInputDeviceProperties> ClientInputDevicePropertiesList
class ClientInputDevicePropertiesEncoder class ClientInputDevicePropertiesEncoder
{ {
public: public:
virtual ~ClientInputDevicePropertiesEncoder() {}
virtual ClientInputDeviceProperties EncodeKeyboardInput(const int32_t keyCode, bool keyPressed); virtual ClientInputDeviceProperties EncodeKeyboardInput(const int32_t keyCode, bool keyPressed);
virtual ClientInputDeviceProperties EncodeMouseInput(const int32_t buttonNumber, float touchLocX, float touchLocY, bool buttonPressed); virtual ClientInputDeviceProperties EncodeMouseInput(const int32_t buttonNumber, float touchLocX, float touchLocY, bool buttonPressed);
}; };
@ -389,7 +390,7 @@ protected:
public: public:
ClientInputHandler(); ClientInputHandler();
~ClientInputHandler(); virtual ~ClientInputHandler();
ClientExecutionControl* GetClientExecutionController(); ClientExecutionControl* GetClientExecutionController();
void SetClientExecutionController(ClientExecutionControl *execControl); void SetClientExecutionController(ClientExecutionControl *execControl);

View File

@ -1543,6 +1543,27 @@
AB681025187D4AEF0049F2C2 /* Icon_PaddleKnob_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = AB681018187D4AEF0049F2C2 /* Icon_PaddleKnob_256x256.png */; }; AB681025187D4AEF0049F2C2 /* Icon_PaddleKnob_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = AB681018187D4AEF0049F2C2 /* Icon_PaddleKnob_256x256.png */; };
AB681027187D4AEF0049F2C2 /* Icon_Piano_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = AB681019187D4AEF0049F2C2 /* Icon_Piano_256x256.png */; }; AB681027187D4AEF0049F2C2 /* Icon_Piano_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = AB681019187D4AEF0049F2C2 /* Icon_Piano_256x256.png */; };
AB68A0DD16B139BC00DE0546 /* OGLRender_3_2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB68A0DA16B139BC00DE0546 /* OGLRender_3_2.cpp */; }; AB68A0DD16B139BC00DE0546 /* OGLRender_3_2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB68A0DA16B139BC00DE0546 /* OGLRender_3_2.cpp */; };
AB6E17F52A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB6E17F42A675BF1003A564D /* CheatDatabaseWindowController.mm */; };
AB6E17F62A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB6E17F42A675BF1003A564D /* CheatDatabaseWindowController.mm */; };
AB6E17F72A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB6E17F42A675BF1003A564D /* CheatDatabaseWindowController.mm */; };
AB6E17F82A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB6E17F42A675BF1003A564D /* CheatDatabaseWindowController.mm */; };
AB6E17F92A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB6E17F42A675BF1003A564D /* CheatDatabaseWindowController.mm */; };
AB6E17FA2A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB6E17F42A675BF1003A564D /* CheatDatabaseWindowController.mm */; };
AB6E17FB2A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB6E17F42A675BF1003A564D /* CheatDatabaseWindowController.mm */; };
AB6E17FC2A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB6E17F42A675BF1003A564D /* CheatDatabaseWindowController.mm */; };
AB6E17FD2A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB6E17F42A675BF1003A564D /* CheatDatabaseWindowController.mm */; };
AB6E17FE2A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB6E17F42A675BF1003A564D /* CheatDatabaseWindowController.mm */; };
AB6E18012A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */; };
AB6E18022A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */; };
AB6E18032A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */; };
AB6E18042A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */; };
AB6E18052A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */; };
AB6E18062A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */; };
AB6E18072A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */; };
AB6E18082A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */; };
AB6E18092A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */; };
AB6E180A2A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */; };
AB6E180B2A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */; };
AB74EC8A1738499C0026C41E /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB74EC891738499C0026C41E /* Carbon.framework */; }; AB74EC8A1738499C0026C41E /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB74EC891738499C0026C41E /* Carbon.framework */; };
AB78B5C11E384F2100297FED /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB3BF4401E262943003E2B24 /* Metal.framework */; settings = {ATTRIBUTES = (Required, ); }; }; AB78B5C11E384F2100297FED /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB3BF4401E262943003E2B24 /* Metal.framework */; settings = {ATTRIBUTES = (Required, ); }; };
AB78B5C21E384F2200297FED /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB3BF4401E262943003E2B24 /* Metal.framework */; settings = {ATTRIBUTES = (Required, ); }; }; AB78B5C21E384F2200297FED /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB3BF4401E262943003E2B24 /* Metal.framework */; settings = {ATTRIBUTES = (Required, ); }; };
@ -2425,6 +2446,17 @@
AB8493C01B4E614D00CD1C73 /* Icon_VolumeOneThird_16x16@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AB8493AD1B4E614D00CD1C73 /* Icon_VolumeOneThird_16x16@2x.png */; }; AB8493C01B4E614D00CD1C73 /* Icon_VolumeOneThird_16x16@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AB8493AD1B4E614D00CD1C73 /* Icon_VolumeOneThird_16x16@2x.png */; };
AB8493C11B4E614D00CD1C73 /* Icon_VolumeTwoThird_16x16@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AB8493AE1B4E614D00CD1C73 /* Icon_VolumeTwoThird_16x16@2x.png */; }; AB8493C11B4E614D00CD1C73 /* Icon_VolumeTwoThird_16x16@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AB8493AE1B4E614D00CD1C73 /* Icon_VolumeTwoThird_16x16@2x.png */; };
AB8493C31B4E614D00CD1C73 /* Icon_VolumeTwoThird_16x16@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AB8493AE1B4E614D00CD1C73 /* Icon_VolumeTwoThird_16x16@2x.png */; }; AB8493C31B4E614D00CD1C73 /* Icon_VolumeTwoThird_16x16@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AB8493AE1B4E614D00CD1C73 /* Icon_VolumeTwoThird_16x16@2x.png */; };
AB8800542AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */; };
AB8800552AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */; };
AB8800562AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */; };
AB8800572AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */; };
AB8800582AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */; };
AB8800592AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */; };
AB88005A2AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */; };
AB88005B2AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */; };
AB88005C2AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */; };
AB88005D2AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */; };
AB88005E2AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */; };
AB8967D916D2ED0700F826F1 /* DisplayWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB8967D816D2ED0700F826F1 /* DisplayWindowController.mm */; }; AB8967D916D2ED0700F826F1 /* DisplayWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB8967D816D2ED0700F826F1 /* DisplayWindowController.mm */; };
AB8967DD16D2ED2700F826F1 /* DisplayWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB8967DB16D2ED2700F826F1 /* DisplayWindow.xib */; }; AB8967DD16D2ED2700F826F1 /* DisplayWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB8967DB16D2ED2700F826F1 /* DisplayWindow.xib */; };
AB8B7AAC17CE8C440051CEBF /* slot1comp_protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8B7AAB17CE8C440051CEBF /* slot1comp_protocol.cpp */; }; AB8B7AAC17CE8C440051CEBF /* slot1comp_protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB8B7AAB17CE8C440051CEBF /* slot1comp_protocol.cpp */; };
@ -4012,6 +4044,9 @@
AB681018187D4AEF0049F2C2 /* Icon_PaddleKnob_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_PaddleKnob_256x256.png; path = images/Icon_PaddleKnob_256x256.png; sourceTree = "<group>"; }; AB681018187D4AEF0049F2C2 /* Icon_PaddleKnob_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_PaddleKnob_256x256.png; path = images/Icon_PaddleKnob_256x256.png; sourceTree = "<group>"; };
AB681019187D4AEF0049F2C2 /* Icon_Piano_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_Piano_256x256.png; path = images/Icon_Piano_256x256.png; sourceTree = "<group>"; }; AB681019187D4AEF0049F2C2 /* Icon_Piano_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_Piano_256x256.png; path = images/Icon_Piano_256x256.png; sourceTree = "<group>"; };
AB68A0DA16B139BC00DE0546 /* OGLRender_3_2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OGLRender_3_2.cpp; sourceTree = "<group>"; }; AB68A0DA16B139BC00DE0546 /* OGLRender_3_2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OGLRender_3_2.cpp; sourceTree = "<group>"; };
AB6E17F32A675BF1003A564D /* CheatDatabaseWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CheatDatabaseWindowController.h; sourceTree = "<group>"; };
AB6E17F42A675BF1003A564D /* CheatDatabaseWindowController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CheatDatabaseWindowController.mm; sourceTree = "<group>"; };
AB6E18002A6B218D003A564D /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = translations/English.lproj/CheatDatabaseViewer.xib; sourceTree = "<group>"; };
AB6FBEF5139B6258007BB045 /* slot1_retail_nand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = slot1_retail_nand.cpp; sourceTree = "<group>"; }; AB6FBEF5139B6258007BB045 /* slot1_retail_nand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = slot1_retail_nand.cpp; sourceTree = "<group>"; };
AB74EC891738499C0026C41E /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; AB74EC891738499C0026C41E /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
AB75226D14C7BB51009B97B3 /* AppIcon_FirmwareConfig.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_FirmwareConfig.icns; sourceTree = "<group>"; }; AB75226D14C7BB51009B97B3 /* AppIcon_FirmwareConfig.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_FirmwareConfig.icns; sourceTree = "<group>"; };
@ -4022,6 +4057,7 @@
AB796CA215CDCB6B00C59155 /* instruction_attributes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = instruction_attributes.h; sourceTree = "<group>"; }; AB796CA215CDCB6B00C59155 /* instruction_attributes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = instruction_attributes.h; sourceTree = "<group>"; };
AB796CA315CDCB6B00C59155 /* instructions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = instructions.h; sourceTree = "<group>"; }; AB796CA315CDCB6B00C59155 /* instructions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = instructions.h; sourceTree = "<group>"; };
AB796D7015CDCBA200C59155 /* DeSmuME (Debug).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (Debug).app"; sourceTree = BUILT_PRODUCTS_DIR; }; AB796D7015CDCBA200C59155 /* DeSmuME (Debug).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (Debug).app"; sourceTree = BUILT_PRODUCTS_DIR; };
AB7DA2432833EEBA001E9A9E /* DeSmuME_arm64.profdata */ = {isa = PBXFileReference; lastKnownFileType = file; path = DeSmuME_arm64.profdata; sourceTree = "<group>"; };
AB7EC7F2189B2B92009D198A /* Icon_AutoholdClear_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_AutoholdClear_420x420.png; path = images/Icon_AutoholdClear_420x420.png; sourceTree = "<group>"; }; AB7EC7F2189B2B92009D198A /* Icon_AutoholdClear_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_AutoholdClear_420x420.png; path = images/Icon_AutoholdClear_420x420.png; sourceTree = "<group>"; };
AB7EC7F3189B2B92009D198A /* Icon_AutoholdSet_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_AutoholdSet_420x420.png; path = images/Icon_AutoholdSet_420x420.png; sourceTree = "<group>"; }; AB7EC7F3189B2B92009D198A /* Icon_AutoholdSet_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_AutoholdSet_420x420.png; path = images/Icon_AutoholdSet_420x420.png; sourceTree = "<group>"; };
AB80E04C142BC4A800A52038 /* cocoa_util.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_util.mm; sourceTree = "<group>"; }; AB80E04C142BC4A800A52038 /* cocoa_util.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_util.mm; sourceTree = "<group>"; };
@ -4037,6 +4073,7 @@
AB8493AC1B4E614D00CD1C73 /* Icon_VolumeMute_16x16@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon_VolumeMute_16x16@2x.png"; path = "images/Icon_VolumeMute_16x16@2x.png"; sourceTree = "<group>"; }; AB8493AC1B4E614D00CD1C73 /* Icon_VolumeMute_16x16@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon_VolumeMute_16x16@2x.png"; path = "images/Icon_VolumeMute_16x16@2x.png"; sourceTree = "<group>"; };
AB8493AD1B4E614D00CD1C73 /* Icon_VolumeOneThird_16x16@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon_VolumeOneThird_16x16@2x.png"; path = "images/Icon_VolumeOneThird_16x16@2x.png"; sourceTree = "<group>"; }; AB8493AD1B4E614D00CD1C73 /* Icon_VolumeOneThird_16x16@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon_VolumeOneThird_16x16@2x.png"; path = "images/Icon_VolumeOneThird_16x16@2x.png"; sourceTree = "<group>"; };
AB8493AE1B4E614D00CD1C73 /* Icon_VolumeTwoThird_16x16@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon_VolumeTwoThird_16x16@2x.png"; path = "images/Icon_VolumeTwoThird_16x16@2x.png"; sourceTree = "<group>"; }; AB8493AE1B4E614D00CD1C73 /* Icon_VolumeTwoThird_16x16@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon_VolumeTwoThird_16x16@2x.png"; path = "images/Icon_VolumeTwoThird_16x16@2x.png"; sourceTree = "<group>"; };
AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = slot2_hcv1000.cpp; sourceTree = "<group>"; };
AB8967D716D2ED0700F826F1 /* DisplayWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplayWindowController.h; sourceTree = "<group>"; }; AB8967D716D2ED0700F826F1 /* DisplayWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplayWindowController.h; sourceTree = "<group>"; };
AB8967D816D2ED0700F826F1 /* DisplayWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DisplayWindowController.mm; sourceTree = "<group>"; }; AB8967D816D2ED0700F826F1 /* DisplayWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DisplayWindowController.mm; sourceTree = "<group>"; };
AB8967DC16D2ED2700F826F1 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = translations/English.lproj/DisplayWindow.xib; sourceTree = "<group>"; }; AB8967DC16D2ED2700F826F1 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = translations/English.lproj/DisplayWindow.xib; sourceTree = "<group>"; };
@ -4107,6 +4144,7 @@
AB9971CE134EDA0800531BA7 /* cocoa_globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_globals.h; sourceTree = "<group>"; }; AB9971CE134EDA0800531BA7 /* cocoa_globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_globals.h; sourceTree = "<group>"; };
ABA48DF527F95C2E00D961FB /* colorspacehandler_NEON.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = colorspacehandler_NEON.h; sourceTree = "<group>"; }; ABA48DF527F95C2E00D961FB /* colorspacehandler_NEON.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = colorspacehandler_NEON.h; sourceTree = "<group>"; };
ABA48DF627F95C2E00D961FB /* colorspacehandler_NEON.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = colorspacehandler_NEON.cpp; sourceTree = "<group>"; }; ABA48DF627F95C2E00D961FB /* colorspacehandler_NEON.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = colorspacehandler_NEON.cpp; sourceTree = "<group>"; };
ABA5AB11282E63E20005F25D /* DeSmuME_x86_64.profdata */ = {isa = PBXFileReference; lastKnownFileType = file; path = DeSmuME_x86_64.profdata; sourceTree = "<group>"; };
ABA6574914511EC90077E5E9 /* cocoa_cheat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_cheat.h; sourceTree = "<group>"; }; ABA6574914511EC90077E5E9 /* cocoa_cheat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_cheat.h; sourceTree = "<group>"; };
ABA6574A14511EC90077E5E9 /* cocoa_cheat.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_cheat.mm; sourceTree = "<group>"; }; ABA6574A14511EC90077E5E9 /* cocoa_cheat.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_cheat.mm; sourceTree = "<group>"; };
ABA67CA52808B8D000B5208D /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; ABA67CA52808B8D000B5208D /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
@ -4212,6 +4250,7 @@
ABC570D4134431DA00E7B0B1 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; ABC570D4134431DA00E7B0B1 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
ABC719E1138CB25E002827A9 /* DefaultKeyMappings.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = DefaultKeyMappings.plist; sourceTree = "<group>"; }; ABC719E1138CB25E002827A9 /* DefaultKeyMappings.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = DefaultKeyMappings.plist; sourceTree = "<group>"; };
ABC8599028273FEE00A03EA9 /* DeSmuME (x86_64).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (x86_64).app"; sourceTree = BUILT_PRODUCTS_DIR; }; ABC8599028273FEE00A03EA9 /* DeSmuME (x86_64).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (x86_64).app"; sourceTree = BUILT_PRODUCTS_DIR; };
ABCC191C2831F3E100B795C4 /* DeSmuME_x86_64h.profdata */ = {isa = PBXFileReference; lastKnownFileType = file; path = DeSmuME_x86_64h.profdata; sourceTree = "<group>"; };
ABCC19332287879000DFA471 /* colorspacehandler_AVX512.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = colorspacehandler_AVX512.cpp; sourceTree = "<group>"; }; ABCC19332287879000DFA471 /* colorspacehandler_AVX512.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = colorspacehandler_AVX512.cpp; sourceTree = "<group>"; };
ABCC19342287879000DFA471 /* colorspacehandler_AVX512.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = colorspacehandler_AVX512.h; sourceTree = "<group>"; }; ABCC19342287879000DFA471 /* colorspacehandler_AVX512.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = colorspacehandler_AVX512.h; sourceTree = "<group>"; };
ABCFA9F2178BDE920030C8BA /* encrypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = encrypt.h; sourceTree = "<group>"; }; ABCFA9F2178BDE920030C8BA /* encrypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = encrypt.h; sourceTree = "<group>"; };
@ -4377,10 +4416,15 @@
ABD2CE4426E05CB000FB15F7 /* DeSmuME (x86_64h).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (x86_64h).app"; sourceTree = BUILT_PRODUCTS_DIR; }; ABD2CE4426E05CB000FB15F7 /* DeSmuME (x86_64h).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (x86_64h).app"; sourceTree = BUILT_PRODUCTS_DIR; };
ABD42045172319D1006A9B46 /* FileMigrationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileMigrationDelegate.h; sourceTree = "<group>"; }; ABD42045172319D1006A9B46 /* FileMigrationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileMigrationDelegate.h; sourceTree = "<group>"; };
ABD42046172319D1006A9B46 /* FileMigrationDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FileMigrationDelegate.mm; sourceTree = "<group>"; }; ABD42046172319D1006A9B46 /* FileMigrationDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FileMigrationDelegate.mm; sourceTree = "<group>"; };
ABD86C832D83E20500505422 /* GPU_Operations_NEON.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPU_Operations_NEON.h; sourceTree = "<group>"; };
ABD86C842D83E20500505422 /* GPU_Operations_NEON.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GPU_Operations_NEON.cpp; sourceTree = "<group>"; };
ABDD89EF2C30BE97003482B7 /* OGLRender_ES3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OGLRender_ES3.h; sourceTree = "<group>"; };
ABDD89F02C30BE97003482B7 /* OGLRender_ES3.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = OGLRender_ES3.cpp; sourceTree = "<group>"; };
ABDDF7C41898F024007583C1 /* Icon_DisplayToggle_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_DisplayToggle_420x420.png; path = images/Icon_DisplayToggle_420x420.png; sourceTree = "<group>"; }; ABDDF7C41898F024007583C1 /* Icon_DisplayToggle_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_DisplayToggle_420x420.png; path = images/Icon_DisplayToggle_420x420.png; sourceTree = "<group>"; };
ABDDF7C71898F032007583C1 /* Icon_FrameAdvance_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_FrameAdvance_420x420.png; path = images/Icon_FrameAdvance_420x420.png; sourceTree = "<group>"; }; ABDDF7C71898F032007583C1 /* Icon_FrameAdvance_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_FrameAdvance_420x420.png; path = images/Icon_FrameAdvance_420x420.png; sourceTree = "<group>"; };
ABDDF7C81898F032007583C1 /* Icon_FrameJump_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_FrameJump_420x420.png; path = images/Icon_FrameJump_420x420.png; sourceTree = "<group>"; }; ABDDF7C81898F032007583C1 /* Icon_FrameJump_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_FrameJump_420x420.png; path = images/Icon_FrameJump_420x420.png; sourceTree = "<group>"; };
ABE187E928274F0100B68164 /* DeSmuME_i386.profdata */ = {isa = PBXFileReference; lastKnownFileType = file; path = DeSmuME_i386.profdata; sourceTree = "<group>"; }; ABDE648E2E21068500C03E0B /* GPU_Operations_AltiVec.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPU_Operations_AltiVec.h; sourceTree = "<group>"; };
ABDE648F2E21068500C03E0B /* GPU_Operations_AltiVec.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GPU_Operations_AltiVec.cpp; sourceTree = "<group>"; };
ABE5DFE3143FB1DA00835AD8 /* cocoa_videofilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_videofilter.h; sourceTree = "<group>"; }; ABE5DFE3143FB1DA00835AD8 /* cocoa_videofilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_videofilter.h; sourceTree = "<group>"; };
ABE5DFE4143FB1DA00835AD8 /* cocoa_videofilter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_videofilter.mm; sourceTree = "<group>"; }; ABE5DFE4143FB1DA00835AD8 /* cocoa_videofilter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_videofilter.mm; sourceTree = "<group>"; };
ABE670251415DE6C00E8E4C9 /* tinystr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinystr.cpp; sourceTree = "<group>"; }; ABE670251415DE6C00E8E4C9 /* tinystr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinystr.cpp; sourceTree = "<group>"; };
@ -4393,6 +4437,7 @@
ABE6840E189E33D5007FD69C /* OGLDisplayOutput.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OGLDisplayOutput.h; sourceTree = "<group>"; }; ABE6840E189E33D5007FD69C /* OGLDisplayOutput.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OGLDisplayOutput.h; sourceTree = "<group>"; };
ABE7F53C13EE1C7900FD3A71 /* cocoa_firmware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_firmware.h; sourceTree = "<group>"; }; ABE7F53C13EE1C7900FD3A71 /* cocoa_firmware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_firmware.h; sourceTree = "<group>"; };
ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_firmware.mm; sourceTree = "<group>"; }; ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_firmware.mm; sourceTree = "<group>"; };
ABECD444282DF23100AA6C0C /* DeSmuME_i386.profdata */ = {isa = PBXFileReference; lastKnownFileType = file; path = DeSmuME_i386.profdata; sourceTree = "<group>"; };
ABEFCF5D141AB82A000CC0CD /* AppIcon_ROMSave.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_ROMSave.icns; sourceTree = "<group>"; }; ABEFCF5D141AB82A000CC0CD /* AppIcon_ROMSave.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_ROMSave.icns; sourceTree = "<group>"; };
ABEFCF5E141AB82A000CC0CD /* AppIcon_DeSmuME.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_DeSmuME.icns; sourceTree = "<group>"; }; ABEFCF5E141AB82A000CC0CD /* AppIcon_DeSmuME.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_DeSmuME.icns; sourceTree = "<group>"; };
ABEFCF5F141AB82A000CC0CD /* AppIcon_NintendoDS_ROM.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_NintendoDS_ROM.icns; sourceTree = "<group>"; }; ABEFCF5F141AB82A000CC0CD /* AppIcon_NintendoDS_ROM.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_NintendoDS_ROM.icns; sourceTree = "<group>"; };
@ -4932,6 +4977,7 @@
ABC2ECD613B1C87000FAAA2A /* Images */, ABC2ECD613B1C87000FAAA2A /* Images */,
AB00E87C14205EBC00DE561F /* MainMenu.xib */, AB00E87C14205EBC00DE561F /* MainMenu.xib */,
AB8967DB16D2ED2700F826F1 /* DisplayWindow.xib */, AB8967DB16D2ED2700F826F1 /* DisplayWindow.xib */,
AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */,
AB350D3A147A1D93007165AC /* HID_usage_strings.plist */, AB350D3A147A1D93007165AC /* HID_usage_strings.plist */,
8D1107310486CEB800E47090 /* Info.plist */, 8D1107310486CEB800E47090 /* Info.plist */,
AB02791814415E4C0075E58C /* Info (Debug).plist */, AB02791814415E4C0075E58C /* Info (Debug).plist */,
@ -5224,6 +5270,7 @@
children = ( children = (
AB3ACB6614C2361100D7D192 /* appDelegate.h */, AB3ACB6614C2361100D7D192 /* appDelegate.h */,
AB3ACB6814C2361100D7D192 /* cheatWindowDelegate.h */, AB3ACB6814C2361100D7D192 /* cheatWindowDelegate.h */,
AB6E17F32A675BF1003A564D /* CheatDatabaseWindowController.h */,
AB3BF4361E25D6B4003E2B24 /* DisplayViewCALayer.h */, AB3BF4361E25D6B4003E2B24 /* DisplayViewCALayer.h */,
AB8967D716D2ED0700F826F1 /* DisplayWindowController.h */, AB8967D716D2ED0700F826F1 /* DisplayWindowController.h */,
AB3A655C16CC5416001F5D4A /* EmuControllerDelegate.h */, AB3A655C16CC5416001F5D4A /* EmuControllerDelegate.h */,
@ -5243,6 +5290,7 @@
AB3FBD7E2176DE95005722D0 /* WifiSettingsPanel.h */, AB3FBD7E2176DE95005722D0 /* WifiSettingsPanel.h */,
AB54718A1E27610500508C5C /* MacMetalDisplayViewShaders.metal */, AB54718A1E27610500508C5C /* MacMetalDisplayViewShaders.metal */,
AB3ACB6714C2361100D7D192 /* appDelegate.mm */, AB3ACB6714C2361100D7D192 /* appDelegate.mm */,
AB6E17F42A675BF1003A564D /* CheatDatabaseWindowController.mm */,
AB3ACB6914C2361100D7D192 /* cheatWindowDelegate.mm */, AB3ACB6914C2361100D7D192 /* cheatWindowDelegate.mm */,
AB3BF4371E25D9AE003E2B24 /* DisplayViewCALayer.mm */, AB3BF4371E25D9AE003E2B24 /* DisplayViewCALayer.mm */,
AB8967D816D2ED0700F826F1 /* DisplayWindowController.mm */, AB8967D816D2ED0700F826F1 /* DisplayWindowController.mm */,
@ -5346,7 +5394,10 @@
AB407F381A620D6E00313213 /* OptimizationProfiles */ = { AB407F381A620D6E00313213 /* OptimizationProfiles */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
ABE187E928274F0100B68164 /* DeSmuME_i386.profdata */, ABECD444282DF23100AA6C0C /* DeSmuME_i386.profdata */,
ABA5AB11282E63E20005F25D /* DeSmuME_x86_64.profdata */,
ABCC191C2831F3E100B795C4 /* DeSmuME_x86_64h.profdata */,
AB7DA2432833EEBA001E9A9E /* DeSmuME_arm64.profdata */,
); );
path = OptimizationProfiles; path = OptimizationProfiles;
sourceTree = "<group>"; sourceTree = "<group>";
@ -5638,6 +5689,8 @@
AB1D4BB126E6F8D700A9AE42 /* GPU_Operations.cpp */, AB1D4BB126E6F8D700A9AE42 /* GPU_Operations.cpp */,
AB1D4BB426E6F8D700A9AE42 /* GPU_Operations_SSE2.cpp */, AB1D4BB426E6F8D700A9AE42 /* GPU_Operations_SSE2.cpp */,
AB1D4BAF26E6F8D700A9AE42 /* GPU_Operations_AVX2.cpp */, AB1D4BAF26E6F8D700A9AE42 /* GPU_Operations_AVX2.cpp */,
ABD86C842D83E20500505422 /* GPU_Operations_NEON.cpp */,
ABDE648F2E21068500C03E0B /* GPU_Operations_AltiVec.cpp */,
ABD1FEB81345AC8400AF11D1 /* lua-engine.cpp */, ABD1FEB81345AC8400AF11D1 /* lua-engine.cpp */,
ABD1FEB91345AC8400AF11D1 /* matrix.cpp */, ABD1FEB91345AC8400AF11D1 /* matrix.cpp */,
ABD1FEBA1345AC8400AF11D1 /* mc.cpp */, ABD1FEBA1345AC8400AF11D1 /* mc.cpp */,
@ -5647,6 +5700,7 @@
ABD1FEC01345AC8400AF11D1 /* NDSSystem.cpp */, ABD1FEC01345AC8400AF11D1 /* NDSSystem.cpp */,
ABD1FEC11345AC8400AF11D1 /* OGLRender.cpp */, ABD1FEC11345AC8400AF11D1 /* OGLRender.cpp */,
AB68A0DA16B139BC00DE0546 /* OGLRender_3_2.cpp */, AB68A0DA16B139BC00DE0546 /* OGLRender_3_2.cpp */,
ABDD89F02C30BE97003482B7 /* OGLRender_ES3.cpp */,
ABD1FEC21345AC8400AF11D1 /* path.cpp */, ABD1FEC21345AC8400AF11D1 /* path.cpp */,
ABD1FEC31345AC8400AF11D1 /* rasterize.cpp */, ABD1FEC31345AC8400AF11D1 /* rasterize.cpp */,
ABD1FEC41345AC8400AF11D1 /* readwrite.cpp */, ABD1FEC41345AC8400AF11D1 /* readwrite.cpp */,
@ -5681,6 +5735,8 @@
AB1D4BB326E6F8D700A9AE42 /* GPU_Operations.h */, AB1D4BB326E6F8D700A9AE42 /* GPU_Operations.h */,
AB1D4BB226E6F8D700A9AE42 /* GPU_Operations_SSE2.h */, AB1D4BB226E6F8D700A9AE42 /* GPU_Operations_SSE2.h */,
AB1D4BB026E6F8D700A9AE42 /* GPU_Operations_AVX2.h */, AB1D4BB026E6F8D700A9AE42 /* GPU_Operations_AVX2.h */,
ABD86C832D83E20500505422 /* GPU_Operations_NEON.h */,
ABDE648E2E21068500C03E0B /* GPU_Operations_AltiVec.h */,
AB796CA215CDCB6B00C59155 /* instruction_attributes.h */, AB796CA215CDCB6B00C59155 /* instruction_attributes.h */,
AB796CA315CDCB6B00C59155 /* instructions.h */, AB796CA315CDCB6B00C59155 /* instructions.h */,
ABD1FE841345AC8400AF11D1 /* lua-engine.h */, ABD1FE841345AC8400AF11D1 /* lua-engine.h */,
@ -5694,6 +5750,7 @@
ABD1FE8C1345AC8400AF11D1 /* NDSSystem.h */, ABD1FE8C1345AC8400AF11D1 /* NDSSystem.h */,
ABD1FE8D1345AC8400AF11D1 /* OGLRender.h */, ABD1FE8D1345AC8400AF11D1 /* OGLRender.h */,
ABBB421516B4A5F30012E5AB /* OGLRender_3_2.h */, ABBB421516B4A5F30012E5AB /* OGLRender_3_2.h */,
ABDD89EF2C30BE97003482B7 /* OGLRender_ES3.h */,
ABD1FE8F1345AC8400AF11D1 /* PACKED.h */, ABD1FE8F1345AC8400AF11D1 /* PACKED.h */,
ABD1FE8E1345AC8400AF11D1 /* PACKED_END.h */, ABD1FE8E1345AC8400AF11D1 /* PACKED_END.h */,
ABD1FE901345AC8400AF11D1 /* path.h */, ABD1FE901345AC8400AF11D1 /* path.h */,
@ -5732,6 +5789,7 @@
ABD1FF031345AC9B00AF11D1 /* slot2_expMemory.cpp */, ABD1FF031345AC9B00AF11D1 /* slot2_expMemory.cpp */,
ABD1FF041345AC9B00AF11D1 /* slot2_gbagame.cpp */, ABD1FF041345AC9B00AF11D1 /* slot2_gbagame.cpp */,
ABD1FF051345AC9B00AF11D1 /* slot2_guitarGrip.cpp */, ABD1FF051345AC9B00AF11D1 /* slot2_guitarGrip.cpp */,
AB8800532AD5EC4F0090D47F /* slot2_hcv1000.cpp */,
ABD1FF061345AC9B00AF11D1 /* slot2_mpcf.cpp */, ABD1FF061345AC9B00AF11D1 /* slot2_mpcf.cpp */,
ABD1FF071345AC9C00AF11D1 /* slot2_none.cpp */, ABD1FF071345AC9C00AF11D1 /* slot2_none.cpp */,
ABD1FF081345AC9C00AF11D1 /* slot2_paddle.cpp */, ABD1FF081345AC9C00AF11D1 /* slot2_paddle.cpp */,
@ -6445,6 +6503,7 @@
8C43E79727E3CD0100A35F65 /* Icon_Input_420x420.png in Resources */, 8C43E79727E3CD0100A35F65 /* Icon_Input_420x420.png in Resources */,
8C43E79827E3CD0100A35F65 /* Icon_AutoholdSet_420x420.png in Resources */, 8C43E79827E3CD0100A35F65 /* Icon_AutoholdSet_420x420.png in Resources */,
8C43E79927E3CD0100A35F65 /* Icon_MicrophoneBlack_256x256.png in Resources */, 8C43E79927E3CD0100A35F65 /* Icon_MicrophoneBlack_256x256.png in Resources */,
AB6E18032A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */,
8C43E79A27E3CD0100A35F65 /* Icon_OpenROM_420x420.png in Resources */, 8C43E79A27E3CD0100A35F65 /* Icon_OpenROM_420x420.png in Resources */,
8C43E79B27E3CD0100A35F65 /* Icon_Reset_420x420.png in Resources */, 8C43E79B27E3CD0100A35F65 /* Icon_Reset_420x420.png in Resources */,
8C43E79C27E3CD0100A35F65 /* Icon_RotateCCW_420x420.png in Resources */, 8C43E79C27E3CD0100A35F65 /* Icon_RotateCCW_420x420.png in Resources */,
@ -6564,6 +6623,7 @@
8C43E8F527E3CD4C00A35F65 /* Icon_Input_420x420.png in Resources */, 8C43E8F527E3CD4C00A35F65 /* Icon_Input_420x420.png in Resources */,
8C43E8F627E3CD4C00A35F65 /* Icon_AutoholdSet_420x420.png in Resources */, 8C43E8F627E3CD4C00A35F65 /* Icon_AutoholdSet_420x420.png in Resources */,
8C43E8F727E3CD4C00A35F65 /* Icon_MicrophoneBlack_256x256.png in Resources */, 8C43E8F727E3CD4C00A35F65 /* Icon_MicrophoneBlack_256x256.png in Resources */,
AB6E18042A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */,
8C43E8F827E3CD4C00A35F65 /* Icon_OpenROM_420x420.png in Resources */, 8C43E8F827E3CD4C00A35F65 /* Icon_OpenROM_420x420.png in Resources */,
8C43E8F927E3CD4C00A35F65 /* Icon_Reset_420x420.png in Resources */, 8C43E8F927E3CD4C00A35F65 /* Icon_Reset_420x420.png in Resources */,
8C43E8FA27E3CD4C00A35F65 /* Icon_RotateCCW_420x420.png in Resources */, 8C43E8FA27E3CD4C00A35F65 /* Icon_RotateCCW_420x420.png in Resources */,
@ -6683,6 +6743,7 @@
8CCD840827E40B730024BDD5 /* Icon_Input_420x420.png in Resources */, 8CCD840827E40B730024BDD5 /* Icon_Input_420x420.png in Resources */,
8CCD840927E40B730024BDD5 /* Icon_AutoholdSet_420x420.png in Resources */, 8CCD840927E40B730024BDD5 /* Icon_AutoholdSet_420x420.png in Resources */,
8CCD840A27E40B730024BDD5 /* Icon_MicrophoneBlack_256x256.png in Resources */, 8CCD840A27E40B730024BDD5 /* Icon_MicrophoneBlack_256x256.png in Resources */,
AB6E180B2A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */,
8CCD840B27E40B730024BDD5 /* Icon_OpenROM_420x420.png in Resources */, 8CCD840B27E40B730024BDD5 /* Icon_OpenROM_420x420.png in Resources */,
8CCD840C27E40B730024BDD5 /* Icon_Reset_420x420.png in Resources */, 8CCD840C27E40B730024BDD5 /* Icon_Reset_420x420.png in Resources */,
8CCD840D27E40B730024BDD5 /* Icon_RotateCCW_420x420.png in Resources */, 8CCD840D27E40B730024BDD5 /* Icon_RotateCCW_420x420.png in Resources */,
@ -6802,6 +6863,7 @@
AB36C78827F2C8AE00C763C8 /* Icon_Input_420x420.png in Resources */, AB36C78827F2C8AE00C763C8 /* Icon_Input_420x420.png in Resources */,
AB36C78927F2C8AE00C763C8 /* Icon_AutoholdSet_420x420.png in Resources */, AB36C78927F2C8AE00C763C8 /* Icon_AutoholdSet_420x420.png in Resources */,
AB36C78A27F2C8AE00C763C8 /* Icon_MicrophoneBlack_256x256.png in Resources */, AB36C78A27F2C8AE00C763C8 /* Icon_MicrophoneBlack_256x256.png in Resources */,
AB6E18082A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */,
AB36C78B27F2C8AE00C763C8 /* Icon_OpenROM_420x420.png in Resources */, AB36C78B27F2C8AE00C763C8 /* Icon_OpenROM_420x420.png in Resources */,
AB36C78C27F2C8AE00C763C8 /* Icon_Reset_420x420.png in Resources */, AB36C78C27F2C8AE00C763C8 /* Icon_Reset_420x420.png in Resources */,
AB36C78D27F2C8AE00C763C8 /* Icon_RotateCCW_420x420.png in Resources */, AB36C78D27F2C8AE00C763C8 /* Icon_RotateCCW_420x420.png in Resources */,
@ -6921,6 +6983,7 @@
AB497A0E27F2E97A00E8A244 /* Icon_Input_420x420.png in Resources */, AB497A0E27F2E97A00E8A244 /* Icon_Input_420x420.png in Resources */,
AB497A0F27F2E97A00E8A244 /* Icon_AutoholdSet_420x420.png in Resources */, AB497A0F27F2E97A00E8A244 /* Icon_AutoholdSet_420x420.png in Resources */,
AB497A1027F2E97A00E8A244 /* Icon_MicrophoneBlack_256x256.png in Resources */, AB497A1027F2E97A00E8A244 /* Icon_MicrophoneBlack_256x256.png in Resources */,
AB6E18072A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */,
AB497A1127F2E97A00E8A244 /* Icon_OpenROM_420x420.png in Resources */, AB497A1127F2E97A00E8A244 /* Icon_OpenROM_420x420.png in Resources */,
AB497A1227F2E97A00E8A244 /* Icon_Reset_420x420.png in Resources */, AB497A1227F2E97A00E8A244 /* Icon_Reset_420x420.png in Resources */,
AB497A1327F2E97A00E8A244 /* Icon_RotateCCW_420x420.png in Resources */, AB497A1327F2E97A00E8A244 /* Icon_RotateCCW_420x420.png in Resources */,
@ -7040,6 +7103,7 @@
AB790193215B84F20082AE82 /* Icon_Input_420x420.png in Resources */, AB790193215B84F20082AE82 /* Icon_Input_420x420.png in Resources */,
AB790194215B84F20082AE82 /* Icon_AutoholdSet_420x420.png in Resources */, AB790194215B84F20082AE82 /* Icon_AutoholdSet_420x420.png in Resources */,
AB790195215B84F20082AE82 /* Icon_MicrophoneBlack_256x256.png in Resources */, AB790195215B84F20082AE82 /* Icon_MicrophoneBlack_256x256.png in Resources */,
AB6E18062A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */,
AB790196215B84F20082AE82 /* Icon_OpenROM_420x420.png in Resources */, AB790196215B84F20082AE82 /* Icon_OpenROM_420x420.png in Resources */,
AB790197215B84F20082AE82 /* Icon_Reset_420x420.png in Resources */, AB790197215B84F20082AE82 /* Icon_Reset_420x420.png in Resources */,
AB790198215B84F20082AE82 /* Icon_RotateCCW_420x420.png in Resources */, AB790198215B84F20082AE82 /* Icon_RotateCCW_420x420.png in Resources */,
@ -7159,6 +7223,7 @@
AB796CE015CDCBA200C59155 /* Icon_Input_420x420.png in Resources */, AB796CE015CDCBA200C59155 /* Icon_Input_420x420.png in Resources */,
AB7EC7F6189B2B92009D198A /* Icon_AutoholdSet_420x420.png in Resources */, AB7EC7F6189B2B92009D198A /* Icon_AutoholdSet_420x420.png in Resources */,
ABB0FBCC1A9EED350060C55A /* Icon_MicrophoneBlack_256x256.png in Resources */, ABB0FBCC1A9EED350060C55A /* Icon_MicrophoneBlack_256x256.png in Resources */,
AB6E18012A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */,
AB796CE215CDCBA200C59155 /* Icon_OpenROM_420x420.png in Resources */, AB796CE215CDCBA200C59155 /* Icon_OpenROM_420x420.png in Resources */,
AB796CE315CDCBA200C59155 /* Icon_Reset_420x420.png in Resources */, AB796CE315CDCBA200C59155 /* Icon_Reset_420x420.png in Resources */,
AB796CE415CDCBA200C59155 /* Icon_RotateCCW_420x420.png in Resources */, AB796CE415CDCBA200C59155 /* Icon_RotateCCW_420x420.png in Resources */,
@ -7278,6 +7343,7 @@
AB790036215B84E50082AE82 /* Icon_Input_420x420.png in Resources */, AB790036215B84E50082AE82 /* Icon_Input_420x420.png in Resources */,
AB790037215B84E50082AE82 /* Icon_AutoholdSet_420x420.png in Resources */, AB790037215B84E50082AE82 /* Icon_AutoholdSet_420x420.png in Resources */,
AB790038215B84E50082AE82 /* Icon_MicrophoneBlack_256x256.png in Resources */, AB790038215B84E50082AE82 /* Icon_MicrophoneBlack_256x256.png in Resources */,
AB6E18052A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */,
AB790039215B84E50082AE82 /* Icon_OpenROM_420x420.png in Resources */, AB790039215B84E50082AE82 /* Icon_OpenROM_420x420.png in Resources */,
AB79003A215B84E50082AE82 /* Icon_Reset_420x420.png in Resources */, AB79003A215B84E50082AE82 /* Icon_Reset_420x420.png in Resources */,
AB79003B215B84E50082AE82 /* Icon_RotateCCW_420x420.png in Resources */, AB79003B215B84E50082AE82 /* Icon_RotateCCW_420x420.png in Resources */,
@ -7397,6 +7463,7 @@
AB8F3C5F1A53AC2600A80BF6 /* Icon_Input_420x420.png in Resources */, AB8F3C5F1A53AC2600A80BF6 /* Icon_Input_420x420.png in Resources */,
AB8F3C601A53AC2600A80BF6 /* Icon_AutoholdSet_420x420.png in Resources */, AB8F3C601A53AC2600A80BF6 /* Icon_AutoholdSet_420x420.png in Resources */,
ABB0FBCE1A9EED350060C55A /* Icon_MicrophoneBlack_256x256.png in Resources */, ABB0FBCE1A9EED350060C55A /* Icon_MicrophoneBlack_256x256.png in Resources */,
AB6E18022A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */,
AB8F3C621A53AC2600A80BF6 /* Icon_OpenROM_420x420.png in Resources */, AB8F3C621A53AC2600A80BF6 /* Icon_OpenROM_420x420.png in Resources */,
AB8F3C631A53AC2600A80BF6 /* Icon_Reset_420x420.png in Resources */, AB8F3C631A53AC2600A80BF6 /* Icon_Reset_420x420.png in Resources */,
AB8F3C641A53AC2600A80BF6 /* Icon_RotateCCW_420x420.png in Resources */, AB8F3C641A53AC2600A80BF6 /* Icon_RotateCCW_420x420.png in Resources */,
@ -7526,6 +7593,7 @@
ABC8588628273FEE00A03EA9 /* Icon_Input_420x420.png in Resources */, ABC8588628273FEE00A03EA9 /* Icon_Input_420x420.png in Resources */,
ABC8588728273FEE00A03EA9 /* Icon_AutoholdSet_420x420.png in Resources */, ABC8588728273FEE00A03EA9 /* Icon_AutoholdSet_420x420.png in Resources */,
ABC8588828273FEE00A03EA9 /* Icon_MicrophoneBlack_256x256.png in Resources */, ABC8588828273FEE00A03EA9 /* Icon_MicrophoneBlack_256x256.png in Resources */,
AB6E18092A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */,
ABC8588928273FEE00A03EA9 /* Icon_OpenROM_420x420.png in Resources */, ABC8588928273FEE00A03EA9 /* Icon_OpenROM_420x420.png in Resources */,
ABC8588A28273FEE00A03EA9 /* Icon_Reset_420x420.png in Resources */, ABC8588A28273FEE00A03EA9 /* Icon_Reset_420x420.png in Resources */,
ABC8588B28273FEE00A03EA9 /* Icon_RotateCCW_420x420.png in Resources */, ABC8588B28273FEE00A03EA9 /* Icon_RotateCCW_420x420.png in Resources */,
@ -7645,6 +7713,7 @@
ABD2CD3C26E05CB000FB15F7 /* Icon_Input_420x420.png in Resources */, ABD2CD3C26E05CB000FB15F7 /* Icon_Input_420x420.png in Resources */,
ABD2CD3D26E05CB000FB15F7 /* Icon_AutoholdSet_420x420.png in Resources */, ABD2CD3D26E05CB000FB15F7 /* Icon_AutoholdSet_420x420.png in Resources */,
ABD2CD3E26E05CB000FB15F7 /* Icon_MicrophoneBlack_256x256.png in Resources */, ABD2CD3E26E05CB000FB15F7 /* Icon_MicrophoneBlack_256x256.png in Resources */,
AB6E180A2A6B218D003A564D /* CheatDatabaseViewer.xib in Resources */,
ABD2CD3F26E05CB000FB15F7 /* Icon_OpenROM_420x420.png in Resources */, ABD2CD3F26E05CB000FB15F7 /* Icon_OpenROM_420x420.png in Resources */,
ABD2CD4026E05CB000FB15F7 /* Icon_Reset_420x420.png in Resources */, ABD2CD4026E05CB000FB15F7 /* Icon_Reset_420x420.png in Resources */,
ABD2CD4126E05CB000FB15F7 /* Icon_RotateCCW_420x420.png in Resources */, ABD2CD4126E05CB000FB15F7 /* Icon_RotateCCW_420x420.png in Resources */,
@ -7672,6 +7741,7 @@
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
8C43E7AC27E3CD0100A35F65 /* ShellScript */ = { 8C43E7AC27E3CD0100A35F65 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -7686,6 +7756,7 @@
}; };
8C43E90A27E3CD4C00A35F65 /* ShellScript */ = { 8C43E90A27E3CD4C00A35F65 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -7700,6 +7771,7 @@
}; };
8C74E9BE27F39EDE00BF29F4 /* ShellScript */ = { 8C74E9BE27F39EDE00BF29F4 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -7714,6 +7786,7 @@
}; };
8C74E9BF27F39F2C00BF29F4 /* ShellScript */ = { 8C74E9BF27F39F2C00BF29F4 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -7728,6 +7801,7 @@
}; };
8C74E9C027F39F5300BF29F4 /* ShellScript */ = { 8C74E9C027F39F5300BF29F4 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -7742,6 +7816,7 @@
}; };
AB2DF23215E0834E00B4D0BC /* ShellScript */ = { AB2DF23215E0834E00B4D0BC /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -7756,6 +7831,7 @@
}; };
AB2DF23515E0839D00B4D0BC /* ShellScript */ = { AB2DF23515E0839D00B4D0BC /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -7770,6 +7846,7 @@
}; };
AB497A2327F2E97A00E8A244 /* ShellScript */ = { AB497A2327F2E97A00E8A244 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -7784,6 +7861,7 @@
}; };
AB79004B215B84E50082AE82 /* ShellScript */ = { AB79004B215B84E50082AE82 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -7798,6 +7876,7 @@
}; };
AB7901A8215B84F20082AE82 /* ShellScript */ = { AB7901A8215B84F20082AE82 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -7812,6 +7891,7 @@
}; };
AB8F3C721A53AC2600A80BF6 /* ShellScript */ = { AB8F3C721A53AC2600A80BF6 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -7826,6 +7906,7 @@
}; };
ABC8589C28273FEE00A03EA9 /* ShellScript */ = { ABC8589C28273FEE00A03EA9 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
@ -7914,6 +7995,7 @@
8C43E7F027E3CD0100A35F65 /* ClientExecutionControl.cpp in Sources */, 8C43E7F027E3CD0100A35F65 /* ClientExecutionControl.cpp in Sources */,
8C43E7F127E3CD0100A35F65 /* rsemaphore.c in Sources */, 8C43E7F127E3CD0100A35F65 /* rsemaphore.c in Sources */,
8C43E7F227E3CD0100A35F65 /* movie.cpp in Sources */, 8C43E7F227E3CD0100A35F65 /* movie.cpp in Sources */,
AB6E17F72A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */,
8C43E7F327E3CD0100A35F65 /* slot1comp_rom.cpp in Sources */, 8C43E7F327E3CD0100A35F65 /* slot1comp_rom.cpp in Sources */,
8C43E7F427E3CD0100A35F65 /* NDSSystem.cpp in Sources */, 8C43E7F427E3CD0100A35F65 /* NDSSystem.cpp in Sources */,
8C43E7F527E3CD0100A35F65 /* MacBaseCaptureTool.mm in Sources */, 8C43E7F527E3CD0100A35F65 /* MacBaseCaptureTool.mm in Sources */,
@ -8019,6 +8101,7 @@
8C43E86627E3CD0100A35F65 /* ftfstype.c in Sources */, 8C43E86627E3CD0100A35F65 /* ftfstype.c in Sources */,
8C43E86B27E3CD0100A35F65 /* macosx_10_5_compat.cpp in Sources */, 8C43E86B27E3CD0100A35F65 /* macosx_10_5_compat.cpp in Sources */,
8C43E86C27E3CD0100A35F65 /* retro_dirent.c in Sources */, 8C43E86C27E3CD0100A35F65 /* retro_dirent.c in Sources */,
AB8800562AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */,
8C43E87427E3CD0100A35F65 /* slot2_passme.cpp in Sources */, 8C43E87427E3CD0100A35F65 /* slot2_passme.cpp in Sources */,
8C43E87727E3CD0100A35F65 /* psnames.c in Sources */, 8C43E87727E3CD0100A35F65 /* psnames.c in Sources */,
8C43E87827E3CD0100A35F65 /* ftotval.c in Sources */, 8C43E87827E3CD0100A35F65 /* ftotval.c in Sources */,
@ -8083,6 +8166,7 @@
8C43E92F27E3CD4C00A35F65 /* common.cpp in Sources */, 8C43E92F27E3CD4C00A35F65 /* common.cpp in Sources */,
8C43E93027E3CD4C00A35F65 /* cp15.cpp in Sources */, 8C43E93027E3CD4C00A35F65 /* cp15.cpp in Sources */,
8C43E93127E3CD4C00A35F65 /* psaux.c in Sources */, 8C43E93127E3CD4C00A35F65 /* psaux.c in Sources */,
AB8800572AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */,
8C43E93227E3CD4C00A35F65 /* cpu_detect_x86_gcc.cpp in Sources */, 8C43E93227E3CD4C00A35F65 /* cpu_detect_x86_gcc.cpp in Sources */,
8C43E93327E3CD4C00A35F65 /* crc.cpp in Sources */, 8C43E93327E3CD4C00A35F65 /* crc.cpp in Sources */,
8C43E93427E3CD4C00A35F65 /* MacOGLDisplayView.mm in Sources */, 8C43E93427E3CD4C00A35F65 /* MacOGLDisplayView.mm in Sources */,
@ -8156,6 +8240,7 @@
8C43E97827E3CD4C00A35F65 /* slot2_rumblepak.cpp in Sources */, 8C43E97827E3CD4C00A35F65 /* slot2_rumblepak.cpp in Sources */,
8C43E97927E3CD4C00A35F65 /* sndOSX.cpp in Sources */, 8C43E97927E3CD4C00A35F65 /* sndOSX.cpp in Sources */,
8C43E97A27E3CD4C00A35F65 /* SndOut.cpp in Sources */, 8C43E97A27E3CD4C00A35F65 /* SndOut.cpp in Sources */,
AB6E17F82A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */,
8C43E97B27E3CD4C00A35F65 /* psnames.c in Sources */, 8C43E97B27E3CD4C00A35F65 /* psnames.c in Sources */,
8C43E97C27E3CD4C00A35F65 /* Slot2WindowDelegate.mm in Sources */, 8C43E97C27E3CD4C00A35F65 /* Slot2WindowDelegate.mm in Sources */,
8C43E97D27E3CD4C00A35F65 /* truetype.c in Sources */, 8C43E97D27E3CD4C00A35F65 /* truetype.c in Sources */,
@ -8313,6 +8398,7 @@
8CCD846127E40B730024BDD5 /* ClientExecutionControl.cpp in Sources */, 8CCD846127E40B730024BDD5 /* ClientExecutionControl.cpp in Sources */,
8CCD846227E40B730024BDD5 /* slot1.cpp in Sources */, 8CCD846227E40B730024BDD5 /* slot1.cpp in Sources */,
8CCD846327E40B730024BDD5 /* slot1_none.cpp in Sources */, 8CCD846327E40B730024BDD5 /* slot1_none.cpp in Sources */,
AB6E17FE2A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */,
8CCD846427E40B730024BDD5 /* slot1_r4.cpp in Sources */, 8CCD846427E40B730024BDD5 /* slot1_r4.cpp in Sources */,
8CCD846527E40B730024BDD5 /* cff.c in Sources */, 8CCD846527E40B730024BDD5 /* cff.c in Sources */,
8CCD846627E40B730024BDD5 /* MacBaseCaptureTool.mm in Sources */, 8CCD846627E40B730024BDD5 /* MacBaseCaptureTool.mm in Sources */,
@ -8418,6 +8504,7 @@
8CCD84DF27E40B730024BDD5 /* type1cid.c in Sources */, 8CCD84DF27E40B730024BDD5 /* type1cid.c in Sources */,
8CCD84E427E40B730024BDD5 /* cocoa_slot2.mm in Sources */, 8CCD84E427E40B730024BDD5 /* cocoa_slot2.mm in Sources */,
8CCD84E627E40B730024BDD5 /* ftbase.c in Sources */, 8CCD84E627E40B730024BDD5 /* ftbase.c in Sources */,
AB88005D2AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */,
8CCD84EA27E40B730024BDD5 /* fsnitro.cpp in Sources */, 8CCD84EA27E40B730024BDD5 /* fsnitro.cpp in Sources */,
8CCD84EB27E40B730024BDD5 /* macosx_10_5_compat.cpp in Sources */, 8CCD84EB27E40B730024BDD5 /* macosx_10_5_compat.cpp in Sources */,
8CCD84EC27E40B730024BDD5 /* OGLRender_3_2.cpp in Sources */, 8CCD84EC27E40B730024BDD5 /* OGLRender_3_2.cpp in Sources */,
@ -8462,6 +8549,7 @@
AB36C7AF27F2C8AE00C763C8 /* decrypt.cpp in Sources */, AB36C7AF27F2C8AE00C763C8 /* decrypt.cpp in Sources */,
AB36C7B027F2C8AE00C763C8 /* directory.cpp in Sources */, AB36C7B027F2C8AE00C763C8 /* directory.cpp in Sources */,
AB36C7B127F2C8AE00C763C8 /* Disassembler.cpp in Sources */, AB36C7B127F2C8AE00C763C8 /* Disassembler.cpp in Sources */,
AB88005A2AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */,
AB36C7B227F2C8AE00C763C8 /* disc.cpp in Sources */, AB36C7B227F2C8AE00C763C8 /* disc.cpp in Sources */,
AB36C7B327F2C8AE00C763C8 /* dlditool.cpp in Sources */, AB36C7B327F2C8AE00C763C8 /* dlditool.cpp in Sources */,
AB36C7B427F2C8AE00C763C8 /* driver.cpp in Sources */, AB36C7B427F2C8AE00C763C8 /* driver.cpp in Sources */,
@ -8647,6 +8735,7 @@
AB36C86B27F2C8AE00C763C8 /* macosx_10_5_compat.cpp in Sources */, AB36C86B27F2C8AE00C763C8 /* macosx_10_5_compat.cpp in Sources */,
AB36C86C27F2C8AE00C763C8 /* OGLRender_3_2.cpp in Sources */, AB36C86C27F2C8AE00C763C8 /* OGLRender_3_2.cpp in Sources */,
AB36C86D27F2C8AE00C763C8 /* ftfntfmt.c in Sources */, AB36C86D27F2C8AE00C763C8 /* ftfntfmt.c in Sources */,
AB6E17FB2A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */,
AB36C86E27F2C8AE00C763C8 /* EmuControllerDelegate.mm in Sources */, AB36C86E27F2C8AE00C763C8 /* EmuControllerDelegate.mm in Sources */,
AB36C86F27F2C8AE00C763C8 /* ClientAVCaptureObject.cpp in Sources */, AB36C86F27F2C8AE00C763C8 /* ClientAVCaptureObject.cpp in Sources */,
AB36C87027F2C8AE00C763C8 /* cocoa_GPU.mm in Sources */, AB36C87027F2C8AE00C763C8 /* cocoa_GPU.mm in Sources */,
@ -8704,6 +8793,7 @@
AB79006E215B84E50082AE82 /* emufile.cpp in Sources */, AB79006E215B84E50082AE82 /* emufile.cpp in Sources */,
AB79006F215B84E50082AE82 /* fatdir.cpp in Sources */, AB79006F215B84E50082AE82 /* fatdir.cpp in Sources */,
AB790070215B84E50082AE82 /* ftbase.c in Sources */, AB790070215B84E50082AE82 /* ftbase.c in Sources */,
AB6E17F92A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */,
AB790071215B84E50082AE82 /* fatfile.cpp in Sources */, AB790071215B84E50082AE82 /* fatfile.cpp in Sources */,
AB790072215B84E50082AE82 /* FIFO.cpp in Sources */, AB790072215B84E50082AE82 /* FIFO.cpp in Sources */,
AB790073215B84E50082AE82 /* sfnt.c in Sources */, AB790073215B84E50082AE82 /* sfnt.c in Sources */,
@ -8835,6 +8925,7 @@
AB7900EF215B84E50082AE82 /* coreaudiosound.cpp in Sources */, AB7900EF215B84E50082AE82 /* coreaudiosound.cpp in Sources */,
AB7900F0215B84E50082AE82 /* ringbuffer.cpp in Sources */, AB7900F0215B84E50082AE82 /* ringbuffer.cpp in Sources */,
AB7900F1215B84E50082AE82 /* arm_jit.cpp in Sources */, AB7900F1215B84E50082AE82 /* arm_jit.cpp in Sources */,
AB8800582AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */,
AB7900F2215B84E50082AE82 /* smooth.c in Sources */, AB7900F2215B84E50082AE82 /* smooth.c in Sources */,
AB7900F3215B84E50082AE82 /* troubleshootingWindowDelegate.mm in Sources */, AB7900F3215B84E50082AE82 /* troubleshootingWindowDelegate.mm in Sources */,
AB7900F4215B84E50082AE82 /* macOS_driver.cpp in Sources */, AB7900F4215B84E50082AE82 /* macOS_driver.cpp in Sources */,
@ -8951,6 +9042,7 @@
AB7901DD215B84F20082AE82 /* driver.cpp in Sources */, AB7901DD215B84F20082AE82 /* driver.cpp in Sources */,
AB7901DE215B84F20082AE82 /* emufat.cpp in Sources */, AB7901DE215B84F20082AE82 /* emufat.cpp in Sources */,
AB7901DF215B84F20082AE82 /* type1cid.c in Sources */, AB7901DF215B84F20082AE82 /* type1cid.c in Sources */,
AB8800592AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */,
AB7901E0215B84F20082AE82 /* emufile.cpp in Sources */, AB7901E0215B84F20082AE82 /* emufile.cpp in Sources */,
AB7901E1215B84F20082AE82 /* fatdir.cpp in Sources */, AB7901E1215B84F20082AE82 /* fatdir.cpp in Sources */,
AB7901E2215B84F20082AE82 /* fatfile.cpp in Sources */, AB7901E2215B84F20082AE82 /* fatfile.cpp in Sources */,
@ -9004,6 +9096,7 @@
AB790211215B84F20082AE82 /* type1.c in Sources */, AB790211215B84F20082AE82 /* type1.c in Sources */,
AB790212215B84F20082AE82 /* slot2_paddle.cpp in Sources */, AB790212215B84F20082AE82 /* slot2_paddle.cpp in Sources */,
AB790213215B84F20082AE82 /* slot2_piano.cpp in Sources */, AB790213215B84F20082AE82 /* slot2_piano.cpp in Sources */,
AB6E17FA2A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */,
AB790214215B84F20082AE82 /* slot2_rumblepak.cpp in Sources */, AB790214215B84F20082AE82 /* slot2_rumblepak.cpp in Sources */,
AB790215215B84F20082AE82 /* sndOSX.cpp in Sources */, AB790215215B84F20082AE82 /* sndOSX.cpp in Sources */,
AB790216215B84F20082AE82 /* SndOut.cpp in Sources */, AB790216215B84F20082AE82 /* SndOut.cpp in Sources */,
@ -9161,6 +9254,7 @@
AB796D0415CDCBA200C59155 /* emufile.cpp in Sources */, AB796D0415CDCBA200C59155 /* emufile.cpp in Sources */,
AB796D0515CDCBA200C59155 /* fatdir.cpp in Sources */, AB796D0515CDCBA200C59155 /* fatdir.cpp in Sources */,
ABFEA8011BB4EC1000B08C25 /* ftbase.c in Sources */, ABFEA8011BB4EC1000B08C25 /* ftbase.c in Sources */,
AB6E17F52A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */,
AB796D0615CDCBA200C59155 /* fatfile.cpp in Sources */, AB796D0615CDCBA200C59155 /* fatfile.cpp in Sources */,
AB796D0715CDCBA200C59155 /* FIFO.cpp in Sources */, AB796D0715CDCBA200C59155 /* FIFO.cpp in Sources */,
ABFEA8A31BB4EC1100B08C25 /* sfnt.c in Sources */, ABFEA8A31BB4EC1100B08C25 /* sfnt.c in Sources */,
@ -9292,6 +9386,7 @@
AB796D6215CDCBA200C59155 /* coreaudiosound.cpp in Sources */, AB796D6215CDCBA200C59155 /* coreaudiosound.cpp in Sources */,
AB796D6315CDCBA200C59155 /* ringbuffer.cpp in Sources */, AB796D6315CDCBA200C59155 /* ringbuffer.cpp in Sources */,
AB796D6415CDCBA200C59155 /* arm_jit.cpp in Sources */, AB796D6415CDCBA200C59155 /* arm_jit.cpp in Sources */,
AB8800542AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */,
ABFEA8CA1BB4EC1100B08C25 /* smooth.c in Sources */, ABFEA8CA1BB4EC1100B08C25 /* smooth.c in Sources */,
ABF2B9FB16904133000FF7C0 /* troubleshootingWindowDelegate.mm in Sources */, ABF2B9FB16904133000FF7C0 /* troubleshootingWindowDelegate.mm in Sources */,
AB28625920AE3E9F00EAED43 /* macOS_driver.cpp in Sources */, AB28625920AE3E9F00EAED43 /* macOS_driver.cpp in Sources */,
@ -9408,6 +9503,7 @@
AB8F3C871A53AC2600A80BF6 /* driver.cpp in Sources */, AB8F3C871A53AC2600A80BF6 /* driver.cpp in Sources */,
AB8F3C881A53AC2600A80BF6 /* emufat.cpp in Sources */, AB8F3C881A53AC2600A80BF6 /* emufat.cpp in Sources */,
ABA7316A1BB51FDC00B26147 /* type1cid.c in Sources */, ABA7316A1BB51FDC00B26147 /* type1cid.c in Sources */,
AB8800552AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */,
AB8F3C891A53AC2600A80BF6 /* emufile.cpp in Sources */, AB8F3C891A53AC2600A80BF6 /* emufile.cpp in Sources */,
AB8F3C8A1A53AC2600A80BF6 /* fatdir.cpp in Sources */, AB8F3C8A1A53AC2600A80BF6 /* fatdir.cpp in Sources */,
AB8F3C8B1A53AC2600A80BF6 /* fatfile.cpp in Sources */, AB8F3C8B1A53AC2600A80BF6 /* fatfile.cpp in Sources */,
@ -9461,6 +9557,7 @@
ABA731701BB51FDC00B26147 /* type1.c in Sources */, ABA731701BB51FDC00B26147 /* type1.c in Sources */,
AB8F3CBA1A53AC2600A80BF6 /* slot2_paddle.cpp in Sources */, AB8F3CBA1A53AC2600A80BF6 /* slot2_paddle.cpp in Sources */,
AB8F3CBB1A53AC2600A80BF6 /* slot2_piano.cpp in Sources */, AB8F3CBB1A53AC2600A80BF6 /* slot2_piano.cpp in Sources */,
AB6E17F62A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */,
AB8F3CBC1A53AC2600A80BF6 /* slot2_rumblepak.cpp in Sources */, AB8F3CBC1A53AC2600A80BF6 /* slot2_rumblepak.cpp in Sources */,
AB8F3CBD1A53AC2600A80BF6 /* sndOSX.cpp in Sources */, AB8F3CBD1A53AC2600A80BF6 /* sndOSX.cpp in Sources */,
AB8F3CBE1A53AC2600A80BF6 /* SndOut.cpp in Sources */, AB8F3CBE1A53AC2600A80BF6 /* SndOut.cpp in Sources */,
@ -9711,6 +9808,7 @@
AB2ABA461C9F9CFA00173B15 /* rthreads.c in Sources */, AB2ABA461C9F9CFA00173B15 /* rthreads.c in Sources */,
ABB3C6CB1501C04F00E0C22E /* rasterize.cpp in Sources */, ABB3C6CB1501C04F00E0C22E /* rasterize.cpp in Sources */,
ABB3C6CC1501C04F00E0C22E /* readwrite.cpp in Sources */, ABB3C6CC1501C04F00E0C22E /* readwrite.cpp in Sources */,
AB88005E2AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */,
AB49B553281687B90069F1D7 /* truetype.c in Sources */, AB49B553281687B90069F1D7 /* truetype.c in Sources */,
ABB3C6CD1501C04F00E0C22E /* render3D.cpp in Sources */, ABB3C6CD1501C04F00E0C22E /* render3D.cpp in Sources */,
ABB3C6CE1501C04F00E0C22E /* ROMReader.cpp in Sources */, ABB3C6CE1501C04F00E0C22E /* ROMReader.cpp in Sources */,
@ -9790,6 +9888,7 @@
ABC858BF28273FEE00A03EA9 /* filetime.cpp in Sources */, ABC858BF28273FEE00A03EA9 /* filetime.cpp in Sources */,
ABC858C028273FEE00A03EA9 /* FIRFilter.cpp in Sources */, ABC858C028273FEE00A03EA9 /* FIRFilter.cpp in Sources */,
ABC858C128273FEE00A03EA9 /* firmware.cpp in Sources */, ABC858C128273FEE00A03EA9 /* firmware.cpp in Sources */,
AB6E17FC2A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */,
ABC858C228273FEE00A03EA9 /* async_job.c in Sources */, ABC858C228273FEE00A03EA9 /* async_job.c in Sources */,
ABC858C328273FEE00A03EA9 /* gfx3d.cpp in Sources */, ABC858C328273FEE00A03EA9 /* gfx3d.cpp in Sources */,
ABC858C428273FEE00A03EA9 /* DisplayViewCALayer.mm in Sources */, ABC858C428273FEE00A03EA9 /* DisplayViewCALayer.mm in Sources */,
@ -9921,6 +10020,7 @@
ABC8594228273FEE00A03EA9 /* buffer.cpp in Sources */, ABC8594228273FEE00A03EA9 /* buffer.cpp in Sources */,
ABC8594328273FEE00A03EA9 /* ftotval.c in Sources */, ABC8594328273FEE00A03EA9 /* ftotval.c in Sources */,
ABC8594428273FEE00A03EA9 /* compiler.cpp in Sources */, ABC8594428273FEE00A03EA9 /* compiler.cpp in Sources */,
AB88005B2AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */,
ABC8594528273FEE00A03EA9 /* compilercontext.cpp in Sources */, ABC8594528273FEE00A03EA9 /* compilercontext.cpp in Sources */,
ABC8594628273FEE00A03EA9 /* rthreads.c in Sources */, ABC8594628273FEE00A03EA9 /* rthreads.c in Sources */,
ABC8594728273FEE00A03EA9 /* macOS_driver.cpp in Sources */, ABC8594728273FEE00A03EA9 /* macOS_driver.cpp in Sources */,
@ -10018,6 +10118,7 @@
ABD2CD7326E05CB000FB15F7 /* filetime.cpp in Sources */, ABD2CD7326E05CB000FB15F7 /* filetime.cpp in Sources */,
ABD2CD7426E05CB000FB15F7 /* FIRFilter.cpp in Sources */, ABD2CD7426E05CB000FB15F7 /* FIRFilter.cpp in Sources */,
ABD2CD7526E05CB000FB15F7 /* firmware.cpp in Sources */, ABD2CD7526E05CB000FB15F7 /* firmware.cpp in Sources */,
AB6E17FD2A675BF1003A564D /* CheatDatabaseWindowController.mm in Sources */,
ABD2CD7626E05CB000FB15F7 /* async_job.c in Sources */, ABD2CD7626E05CB000FB15F7 /* async_job.c in Sources */,
ABD2CD7726E05CB000FB15F7 /* gfx3d.cpp in Sources */, ABD2CD7726E05CB000FB15F7 /* gfx3d.cpp in Sources */,
ABD2CD7826E05CB000FB15F7 /* DisplayViewCALayer.mm in Sources */, ABD2CD7826E05CB000FB15F7 /* DisplayViewCALayer.mm in Sources */,
@ -10149,6 +10250,7 @@
ABD2CDF626E05CB000FB15F7 /* buffer.cpp in Sources */, ABD2CDF626E05CB000FB15F7 /* buffer.cpp in Sources */,
ABD2CDF726E05CB000FB15F7 /* ftotval.c in Sources */, ABD2CDF726E05CB000FB15F7 /* ftotval.c in Sources */,
ABD2CDF826E05CB000FB15F7 /* compiler.cpp in Sources */, ABD2CDF826E05CB000FB15F7 /* compiler.cpp in Sources */,
AB88005C2AD5EC500090D47F /* slot2_hcv1000.cpp in Sources */,
ABD2CDF926E05CB000FB15F7 /* compilercontext.cpp in Sources */, ABD2CDF926E05CB000FB15F7 /* compilercontext.cpp in Sources */,
ABD2CDFA26E05CB000FB15F7 /* rthreads.c in Sources */, ABD2CDFA26E05CB000FB15F7 /* rthreads.c in Sources */,
ABD2CDFB26E05CB000FB15F7 /* macOS_driver.cpp in Sources */, ABD2CDFB26E05CB000FB15F7 /* macOS_driver.cpp in Sources */,
@ -10233,6 +10335,14 @@
name = HID_usage_strings.plist; name = HID_usage_strings.plist;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
AB6E17FF2A6B218D003A564D /* CheatDatabaseViewer.xib */ = {
isa = PBXVariantGroup;
children = (
AB6E18002A6B218D003A564D /* English */,
);
name = CheatDatabaseViewer.xib;
sourceTree = "<group>";
};
AB8967DB16D2ED2700F826F1 /* DisplayWindow.xib */ = { AB8967DB16D2ED2700F826F1 /* DisplayWindow.xib */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (
@ -10333,7 +10443,6 @@
buildSettings = { buildSettings = {
ARCHS = arm64; ARCHS = arm64;
CLANG_OPTIMIZATION_PROFILE_FILE = "$(SRCROOT)/OptimizationProfiles/DeSmuME_arm64.profdata"; CLANG_OPTIMIZATION_PROFILE_FILE = "$(SRCROOT)/OptimizationProfiles/DeSmuME_arm64.profdata";
CLANG_USE_OPTIMIZATION_PROFILE = YES;
GCC_FAST_OBJC_DISPATCH = YES; GCC_FAST_OBJC_DISPATCH = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_OPTIMIZATION_LEVEL = fast; GCC_OPTIMIZATION_LEVEL = fast;
@ -10666,7 +10775,6 @@
ARCHS = x86_64; ARCHS = x86_64;
CLANG_CXX_LIBRARY = "libstdc++"; CLANG_CXX_LIBRARY = "libstdc++";
CLANG_OPTIMIZATION_PROFILE_FILE = "$(SRCROOT)/OptimizationProfiles/DeSmuME_x86_64.profdata"; CLANG_OPTIMIZATION_PROFILE_FILE = "$(SRCROOT)/OptimizationProfiles/DeSmuME_x86_64.profdata";
CLANG_USE_OPTIMIZATION_PROFILE = YES;
GCC_FAST_OBJC_DISPATCH = YES; GCC_FAST_OBJC_DISPATCH = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_OPTIMIZATION_LEVEL = fast; GCC_OPTIMIZATION_LEVEL = fast;
@ -10715,7 +10823,6 @@
buildSettings = { buildSettings = {
ARCHS = x86_64h; ARCHS = x86_64h;
CLANG_OPTIMIZATION_PROFILE_FILE = "$(SRCROOT)/OptimizationProfiles/DeSmuME_x86_64h.profdata"; CLANG_OPTIMIZATION_PROFILE_FILE = "$(SRCROOT)/OptimizationProfiles/DeSmuME_x86_64h.profdata";
CLANG_USE_OPTIMIZATION_PROFILE = YES;
GCC_FAST_OBJC_DISPATCH = YES; GCC_FAST_OBJC_DISPATCH = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_OPTIMIZATION_LEVEL = fast; GCC_OPTIMIZATION_LEVEL = fast;

View File

@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "self:DeSmuME (Latest).xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>

View File

@ -27,8 +27,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion> <MacroExpansion>
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
@ -38,8 +36,8 @@
ReferencedContainer = "container:DeSmuME (Latest).xcodeproj"> ReferencedContainer = "container:DeSmuME (Latest).xcodeproj">
</BuildableReference> </BuildableReference>
</MacroExpansion> </MacroExpansion>
<AdditionalOptions> <Testables>
</AdditionalOptions> </Testables>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Debug" buildConfiguration = "Debug"
@ -50,6 +48,7 @@
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES" debugDocumentVersioning = "YES"
debugServiceExtension = "internal" debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES"> allowLocationSimulation = "YES">
<BuildableProductRunnable <BuildableProductRunnable
runnableDebuggingMode = "0"> runnableDebuggingMode = "0">
@ -61,8 +60,6 @@
ReferencedContainer = "container:DeSmuME (Latest).xcodeproj"> ReferencedContainer = "container:DeSmuME (Latest).xcodeproj">
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction> </LaunchAction>
<ProfileAction <ProfileAction
buildConfiguration = "Release" buildConfiguration = "Release"

View File

@ -48,6 +48,7 @@
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES" debugDocumentVersioning = "YES"
debugServiceExtension = "internal" debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES"> allowLocationSimulation = "YES">
<BuildableProductRunnable <BuildableProductRunnable
runnableDebuggingMode = "0"> runnableDebuggingMode = "0">

View File

@ -266,6 +266,11 @@
AB142028186E2CD80015D52F /* Image_MemoryExpansionPak.png in Resources */ = {isa = PBXBuildFile; fileRef = AB142025186E2CD80015D52F /* Image_MemoryExpansionPak.png */; }; AB142028186E2CD80015D52F /* Image_MemoryExpansionPak.png in Resources */ = {isa = PBXBuildFile; fileRef = AB142025186E2CD80015D52F /* Image_MemoryExpansionPak.png */; };
AB142029186E2CD80015D52F /* Image_MemoryExpansionPak.png in Resources */ = {isa = PBXBuildFile; fileRef = AB142025186E2CD80015D52F /* Image_MemoryExpansionPak.png */; }; AB142029186E2CD80015D52F /* Image_MemoryExpansionPak.png in Resources */ = {isa = PBXBuildFile; fileRef = AB142025186E2CD80015D52F /* Image_MemoryExpansionPak.png */; };
AB14202A186E2CD80015D52F /* Image_MemoryExpansionPak.png in Resources */ = {isa = PBXBuildFile; fileRef = AB142025186E2CD80015D52F /* Image_MemoryExpansionPak.png */; }; AB14202A186E2CD80015D52F /* Image_MemoryExpansionPak.png in Resources */ = {isa = PBXBuildFile; fileRef = AB142025186E2CD80015D52F /* Image_MemoryExpansionPak.png */; };
AB1B20AC2AD5ED59007CA7EB /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB1B20AB2AD5ED59007CA7EB /* slot2_hcv1000.cpp */; };
AB1B20AD2AD5ED59007CA7EB /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB1B20AB2AD5ED59007CA7EB /* slot2_hcv1000.cpp */; };
AB1B20AE2AD5ED59007CA7EB /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB1B20AB2AD5ED59007CA7EB /* slot2_hcv1000.cpp */; };
AB1B20AF2AD5ED59007CA7EB /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB1B20AB2AD5ED59007CA7EB /* slot2_hcv1000.cpp */; };
AB1B20B02AD5ED59007CA7EB /* slot2_hcv1000.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB1B20AB2AD5ED59007CA7EB /* slot2_hcv1000.cpp */; };
AB1CC8001AA509C2008B0A16 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB1CC7FF1AA509C2008B0A16 /* CoreAudio.framework */; }; AB1CC8001AA509C2008B0A16 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB1CC7FF1AA509C2008B0A16 /* CoreAudio.framework */; };
AB1CC80A1AA509DF008B0A16 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB1CC7FF1AA509C2008B0A16 /* CoreAudio.framework */; }; AB1CC80A1AA509DF008B0A16 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB1CC7FF1AA509C2008B0A16 /* CoreAudio.framework */; };
AB1CC80B1AA509E0008B0A16 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB1CC7FF1AA509C2008B0A16 /* CoreAudio.framework */; }; AB1CC80B1AA509E0008B0A16 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB1CC7FF1AA509C2008B0A16 /* CoreAudio.framework */; };
@ -1558,6 +1563,11 @@
ABD59849187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = ABD59846187D4A6C00069403 /* Icon_PaddleKnob_256x256.png */; }; ABD59849187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = ABD59846187D4A6C00069403 /* Icon_PaddleKnob_256x256.png */; };
ABD5984A187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = ABD59846187D4A6C00069403 /* Icon_PaddleKnob_256x256.png */; }; ABD5984A187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = ABD59846187D4A6C00069403 /* Icon_PaddleKnob_256x256.png */; };
ABD5984B187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = ABD59846187D4A6C00069403 /* Icon_PaddleKnob_256x256.png */; }; ABD5984B187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = ABD59846187D4A6C00069403 /* Icon_PaddleKnob_256x256.png */; };
ABEBCE372A703E260028CE8A /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABEBCE362A703E260028CE8A /* CheatDatabaseWindowController.mm */; };
ABEBCE382A703E260028CE8A /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABEBCE362A703E260028CE8A /* CheatDatabaseWindowController.mm */; };
ABEBCE392A703E260028CE8A /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABEBCE362A703E260028CE8A /* CheatDatabaseWindowController.mm */; };
ABEBCE3A2A703E260028CE8A /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABEBCE362A703E260028CE8A /* CheatDatabaseWindowController.mm */; };
ABEBCE3B2A703E260028CE8A /* CheatDatabaseWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABEBCE362A703E260028CE8A /* CheatDatabaseWindowController.mm */; };
ABECB50918A460710052D52A /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB50818A460710052D52A /* xbrz.cpp */; }; ABECB50918A460710052D52A /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB50818A460710052D52A /* xbrz.cpp */; };
ABECB50A18A460710052D52A /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB50818A460710052D52A /* xbrz.cpp */; }; ABECB50A18A460710052D52A /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB50818A460710052D52A /* xbrz.cpp */; };
ABECB50B18A460710052D52A /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB50818A460710052D52A /* xbrz.cpp */; }; ABECB50B18A460710052D52A /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB50818A460710052D52A /* xbrz.cpp */; };
@ -1572,6 +1582,11 @@
ABEF84831873578F00E99ADC /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB8C6E56186CD07E00E3EC64 /* ForceFeedback.framework */; }; ABEF84831873578F00E99ADC /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB8C6E56186CD07E00E3EC64 /* ForceFeedback.framework */; };
ABEF84841873579400E99ADC /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB8C6E56186CD07E00E3EC64 /* ForceFeedback.framework */; }; ABEF84841873579400E99ADC /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB8C6E56186CD07E00E3EC64 /* ForceFeedback.framework */; };
ABEF84851873579700E99ADC /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB8C6E56186CD07E00E3EC64 /* ForceFeedback.framework */; }; ABEF84851873579700E99ADC /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB8C6E56186CD07E00E3EC64 /* ForceFeedback.framework */; };
ABEFFDDE2A78CB67009C3A2D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = ABEFFDDC2A78CB67009C3A2D /* CheatDatabaseViewer.xib */; };
ABEFFDDF2A78CB67009C3A2D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = ABEFFDDC2A78CB67009C3A2D /* CheatDatabaseViewer.xib */; };
ABEFFDE02A78CB67009C3A2D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = ABEFFDDC2A78CB67009C3A2D /* CheatDatabaseViewer.xib */; };
ABEFFDE12A78CB67009C3A2D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = ABEFFDDC2A78CB67009C3A2D /* CheatDatabaseViewer.xib */; };
ABEFFDE22A78CB67009C3A2D /* CheatDatabaseViewer.xib in Resources */ = {isa = PBXBuildFile; fileRef = ABEFFDDC2A78CB67009C3A2D /* CheatDatabaseViewer.xib */; };
ABF50ABA169F5FDA0018C08D /* assembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABF50A7B169F5FDA0018C08D /* assembler.cpp */; }; ABF50ABA169F5FDA0018C08D /* assembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABF50A7B169F5FDA0018C08D /* assembler.cpp */; };
ABF50ABB169F5FDA0018C08D /* assert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABF50A7D169F5FDA0018C08D /* assert.cpp */; }; ABF50ABB169F5FDA0018C08D /* assert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABF50A7D169F5FDA0018C08D /* assert.cpp */; };
ABF50ABC169F5FDA0018C08D /* buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABF50A7F169F5FDA0018C08D /* buffer.cpp */; }; ABF50ABC169F5FDA0018C08D /* buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABF50A7F169F5FDA0018C08D /* buffer.cpp */; };
@ -1903,8 +1918,11 @@
AB0F29A314BE7213009ABC6F /* Icon_RotateCW_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_RotateCW_420x420.png; path = images/Icon_RotateCW_420x420.png; sourceTree = "<group>"; }; AB0F29A314BE7213009ABC6F /* Icon_RotateCW_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_RotateCW_420x420.png; path = images/Icon_RotateCW_420x420.png; sourceTree = "<group>"; };
AB0F29A414BE7213009ABC6F /* Icon_ShowHUD_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_ShowHUD_420x420.png; path = images/Icon_ShowHUD_420x420.png; sourceTree = "<group>"; }; AB0F29A414BE7213009ABC6F /* Icon_ShowHUD_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_ShowHUD_420x420.png; path = images/Icon_ShowHUD_420x420.png; sourceTree = "<group>"; };
AB0F29A514BE7213009ABC6F /* Icon_Speaker_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_Speaker_420x420.png; path = images/Icon_Speaker_420x420.png; sourceTree = "<group>"; }; AB0F29A514BE7213009ABC6F /* Icon_Speaker_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_Speaker_420x420.png; path = images/Icon_Speaker_420x420.png; sourceTree = "<group>"; };
AB11AE8E2E210BB400E8A516 /* GPU_Operations_AltiVec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GPU_Operations_AltiVec.cpp; sourceTree = "<group>"; };
AB11AE8F2E210BB400E8A516 /* GPU_Operations_AltiVec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPU_Operations_AltiVec.h; sourceTree = "<group>"; };
AB126D06182ECB9500EBCF22 /* slot2_passme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = slot2_passme.cpp; sourceTree = "<group>"; }; AB126D06182ECB9500EBCF22 /* slot2_passme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = slot2_passme.cpp; sourceTree = "<group>"; };
AB142025186E2CD80015D52F /* Image_MemoryExpansionPak.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Image_MemoryExpansionPak.png; path = images/Image_MemoryExpansionPak.png; sourceTree = "<group>"; }; AB142025186E2CD80015D52F /* Image_MemoryExpansionPak.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Image_MemoryExpansionPak.png; path = images/Image_MemoryExpansionPak.png; sourceTree = "<group>"; };
AB1B20AB2AD5ED59007CA7EB /* slot2_hcv1000.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = slot2_hcv1000.cpp; sourceTree = "<group>"; };
AB1CC7FF1AA509C2008B0A16 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; AB1CC7FF1AA509C2008B0A16 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
AB1CC8161AA50C8D008B0A16 /* Icon_MicrophoneBlack_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_MicrophoneBlack_256x256.png; path = images/Icon_MicrophoneBlack_256x256.png; sourceTree = "<group>"; }; AB1CC8161AA50C8D008B0A16 /* Icon_MicrophoneBlack_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_MicrophoneBlack_256x256.png; path = images/Icon_MicrophoneBlack_256x256.png; sourceTree = "<group>"; };
AB1CC8171AA50C8D008B0A16 /* Icon_MicrophoneBlueGlow_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_MicrophoneBlueGlow_256x256.png; path = images/Icon_MicrophoneBlueGlow_256x256.png; sourceTree = "<group>"; }; AB1CC8171AA50C8D008B0A16 /* Icon_MicrophoneBlueGlow_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_MicrophoneBlueGlow_256x256.png; path = images/Icon_MicrophoneBlueGlow_256x256.png; sourceTree = "<group>"; };
@ -1995,6 +2013,14 @@
AB3ACC3A14C24D5400D7D192 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYING; path = ../../../COPYING; sourceTree = SOURCE_ROOT; }; AB3ACC3A14C24D5400D7D192 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYING; path = ../../../COPYING; sourceTree = SOURCE_ROOT; };
AB3ACC3B14C24D5400D7D192 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README; path = ../../../README; sourceTree = SOURCE_ROOT; }; AB3ACC3B14C24D5400D7D192 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README; path = ../../../README; sourceTree = SOURCE_ROOT; };
AB3ACC3D14C24D5400D7D192 /* README.MAC */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.MAC; path = ../../../README.MAC; sourceTree = SOURCE_ROOT; }; AB3ACC3D14C24D5400D7D192 /* README.MAC */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.MAC; path = ../../../README.MAC; sourceTree = SOURCE_ROOT; };
AB3B8DC62D8A35A000C9CBFD /* GPU_Operations_NEON.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GPU_Operations_NEON.cpp; sourceTree = "<group>"; };
AB3B8DC72D8A35A000C9CBFD /* GPU_Operations_NEON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPU_Operations_NEON.h; sourceTree = "<group>"; };
AB3B8DC82D8A35A000C9CBFD /* OGLRender_ES3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OGLRender_ES3.cpp; sourceTree = "<group>"; };
AB3B8DC92D8A35A000C9CBFD /* OGLRender_ES3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OGLRender_ES3.h; sourceTree = "<group>"; };
AB3B8DCA2D8A35D900C9CBFD /* OGLDisplayOutput_3_2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OGLDisplayOutput_3_2.cpp; sourceTree = "<group>"; };
AB3B8DCB2D8A35D900C9CBFD /* OGLDisplayOutput_3_2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OGLDisplayOutput_3_2.h; sourceTree = "<group>"; };
AB3B8DCC2D8A35FE00C9CBFD /* colorspacehandler_NEON.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = colorspacehandler_NEON.cpp; sourceTree = "<group>"; };
AB3B8DCD2D8A35FE00C9CBFD /* colorspacehandler_NEON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = colorspacehandler_NEON.h; sourceTree = "<group>"; };
AB3E34C7134AF4500056477A /* cocoa_output.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_output.h; sourceTree = "<group>"; }; AB3E34C7134AF4500056477A /* cocoa_output.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_output.h; sourceTree = "<group>"; };
AB3E34C8134AF4500056477A /* cocoa_output.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_output.mm; sourceTree = "<group>"; }; AB3E34C8134AF4500056477A /* cocoa_output.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_output.mm; sourceTree = "<group>"; };
AB3E690E1E231E9900D4CC75 /* MacOGLDisplayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacOGLDisplayView.h; sourceTree = "<group>"; }; AB3E690E1E231E9900D4CC75 /* MacOGLDisplayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacOGLDisplayView.h; sourceTree = "<group>"; };
@ -2326,6 +2352,8 @@
ABE6702A1415DE6C00E8E4C9 /* tinyxmlparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxmlparser.cpp; sourceTree = "<group>"; }; ABE6702A1415DE6C00E8E4C9 /* tinyxmlparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxmlparser.cpp; sourceTree = "<group>"; };
ABE7F53C13EE1C7900FD3A71 /* cocoa_firmware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_firmware.h; sourceTree = "<group>"; }; ABE7F53C13EE1C7900FD3A71 /* cocoa_firmware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_firmware.h; sourceTree = "<group>"; };
ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_firmware.mm; sourceTree = "<group>"; }; ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_firmware.mm; sourceTree = "<group>"; };
ABEBCE352A703E260028CE8A /* CheatDatabaseWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CheatDatabaseWindowController.h; sourceTree = "<group>"; };
ABEBCE362A703E260028CE8A /* CheatDatabaseWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CheatDatabaseWindowController.mm; sourceTree = "<group>"; };
ABECB50718A460710052D52A /* xbrz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbrz.h; sourceTree = "<group>"; }; ABECB50718A460710052D52A /* xbrz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbrz.h; sourceTree = "<group>"; };
ABECB50818A460710052D52A /* xbrz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xbrz.cpp; sourceTree = "<group>"; }; ABECB50818A460710052D52A /* xbrz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xbrz.cpp; sourceTree = "<group>"; };
ABECB51218A460910052D52A /* OGLDisplayOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OGLDisplayOutput.h; sourceTree = "<group>"; }; ABECB51218A460910052D52A /* OGLDisplayOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OGLDisplayOutput.h; sourceTree = "<group>"; };
@ -2334,6 +2362,7 @@
ABEFCF5E141AB82A000CC0CD /* AppIcon_DeSmuME.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_DeSmuME.icns; sourceTree = "<group>"; }; ABEFCF5E141AB82A000CC0CD /* AppIcon_DeSmuME.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_DeSmuME.icns; sourceTree = "<group>"; };
ABEFCF5F141AB82A000CC0CD /* AppIcon_NintendoDS_ROM.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_NintendoDS_ROM.icns; sourceTree = "<group>"; }; ABEFCF5F141AB82A000CC0CD /* AppIcon_NintendoDS_ROM.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_NintendoDS_ROM.icns; sourceTree = "<group>"; };
ABEFCF60141AB82A000CC0CD /* AppIcon_SaveState.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_SaveState.icns; sourceTree = "<group>"; }; ABEFCF60141AB82A000CC0CD /* AppIcon_SaveState.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_SaveState.icns; sourceTree = "<group>"; };
ABEFFDDD2A78CB67009C3A2D /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = translations/English.lproj/CheatDatabaseViewer.xib; sourceTree = "<group>"; };
ABF50A74169F5FDA0018C08D /* AsmJit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsmJit.h; sourceTree = "<group>"; }; ABF50A74169F5FDA0018C08D /* AsmJit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsmJit.h; sourceTree = "<group>"; };
ABF50A75169F5FDA0018C08D /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = "<group>"; }; ABF50A75169F5FDA0018C08D /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = "<group>"; };
ABF50A76169F5FDA0018C08D /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = core.h; sourceTree = "<group>"; }; ABF50A76169F5FDA0018C08D /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = core.h; sourceTree = "<group>"; };
@ -2544,6 +2573,7 @@
ABC04DC91F67A2AC00EA6ED7 /* macosx_10_5_compat.cpp */, ABC04DC91F67A2AC00EA6ED7 /* macosx_10_5_compat.cpp */,
ABD9A46413DB99B300777194 /* mic_ext.cpp */, ABD9A46413DB99B300777194 /* mic_ext.cpp */,
ABECB51318A460910052D52A /* OGLDisplayOutput.cpp */, ABECB51318A460910052D52A /* OGLDisplayOutput.cpp */,
AB3B8DCA2D8A35D900C9CBFD /* OGLDisplayOutput_3_2.cpp */,
ABD0A5351501AA5A0074A094 /* ringbuffer.cpp */, ABD0A5351501AA5A0074A094 /* ringbuffer.cpp */,
ABD104141346652500AF11D1 /* sndOSX.cpp */, ABD104141346652500AF11D1 /* sndOSX.cpp */,
AB2145211714DFF4006DDB0F /* audiosamplegenerator.h */, AB2145211714DFF4006DDB0F /* audiosamplegenerator.h */,
@ -2567,6 +2597,7 @@
ABD1267420AE812900EFE1B2 /* macOS_driver.h */, ABD1267420AE812900EFE1B2 /* macOS_driver.h */,
ABD9A46313DB99B300777194 /* mic_ext.h */, ABD9A46313DB99B300777194 /* mic_ext.h */,
ABECB51218A460910052D52A /* OGLDisplayOutput.h */, ABECB51218A460910052D52A /* OGLDisplayOutput.h */,
AB3B8DCB2D8A35D900C9CBFD /* OGLDisplayOutput_3_2.h */,
ABD0A5371501AA5A0074A094 /* ringbuffer.h */, ABD0A5371501AA5A0074A094 /* ringbuffer.h */,
ABD104011346652500AF11D1 /* sndOSX.h */, ABD104011346652500AF11D1 /* sndOSX.h */,
AB2F56EE1704C86900E28885 /* utilities.h */, AB2F56EE1704C86900E28885 /* utilities.h */,
@ -2657,6 +2688,7 @@
AB05E8201BBFD41200065D18 /* source-sans-pro */, AB05E8201BBFD41200065D18 /* source-sans-pro */,
ABC2ECD613B1C87000FAAA2A /* Images */, ABC2ECD613B1C87000FAAA2A /* Images */,
AB00E87C14205EBC00DE561F /* MainMenu.xib */, AB00E87C14205EBC00DE561F /* MainMenu.xib */,
ABEFFDDC2A78CB67009C3A2D /* CheatDatabaseViewer.xib */,
AB700DB816CDDBC400FBD336 /* DisplayWindow.xib */, AB700DB816CDDBC400FBD336 /* DisplayWindow.xib */,
AB350D3A147A1D93007165AC /* HID_usage_strings.plist */, AB350D3A147A1D93007165AC /* HID_usage_strings.plist */,
8D1107310486CEB800E47090 /* Info.plist */, 8D1107310486CEB800E47090 /* Info.plist */,
@ -3185,11 +3217,13 @@
AB37E3721D6188BC004A2C0D /* colorspacehandler_SSE2.cpp */, AB37E3721D6188BC004A2C0D /* colorspacehandler_SSE2.cpp */,
AB6FE67226E6F815002B2106 /* colorspacehandler_AVX2.cpp */, AB6FE67226E6F815002B2106 /* colorspacehandler_AVX2.cpp */,
AB6FE67426E6F815002B2106 /* colorspacehandler_AVX512.cpp */, AB6FE67426E6F815002B2106 /* colorspacehandler_AVX512.cpp */,
AB3B8DCC2D8A35FE00C9CBFD /* colorspacehandler_NEON.cpp */,
AB37E36E1D6188BC004A2C0D /* colorspacehandler_AltiVec.cpp */, AB37E36E1D6188BC004A2C0D /* colorspacehandler_AltiVec.cpp */,
AB37E36D1D6188BC004A2C0D /* colorspacehandler.h */, AB37E36D1D6188BC004A2C0D /* colorspacehandler.h */,
AB37E3731D6188BC004A2C0D /* colorspacehandler_SSE2.h */, AB37E3731D6188BC004A2C0D /* colorspacehandler_SSE2.h */,
AB6FE67326E6F815002B2106 /* colorspacehandler_AVX2.h */, AB6FE67326E6F815002B2106 /* colorspacehandler_AVX2.h */,
AB6FE67526E6F815002B2106 /* colorspacehandler_AVX512.h */, AB6FE67526E6F815002B2106 /* colorspacehandler_AVX512.h */,
AB3B8DCD2D8A35FE00C9CBFD /* colorspacehandler_NEON.h */,
AB37E36F1D6188BC004A2C0D /* colorspacehandler_AltiVec.h */, AB37E36F1D6188BC004A2C0D /* colorspacehandler_AltiVec.h */,
); );
path = colorspacehandler; path = colorspacehandler;
@ -3199,6 +3233,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
AB3ACB6614C2361100D7D192 /* appDelegate.h */, AB3ACB6614C2361100D7D192 /* appDelegate.h */,
ABEBCE352A703E260028CE8A /* CheatDatabaseWindowController.h */,
AB3ACB6814C2361100D7D192 /* cheatWindowDelegate.h */, AB3ACB6814C2361100D7D192 /* cheatWindowDelegate.h */,
AB3E69811E25FBBF00D4CC75 /* DisplayViewCALayer.h */, AB3E69811E25FBBF00D4CC75 /* DisplayViewCALayer.h */,
AB700DDC16CDE4C300FBD336 /* DisplayWindowController.h */, AB700DDC16CDE4C300FBD336 /* DisplayWindowController.h */,
@ -3217,6 +3252,7 @@
ABA0356E169127BB00817C69 /* troubleshootingWindowDelegate.h */, ABA0356E169127BB00817C69 /* troubleshootingWindowDelegate.h */,
AB4B5A1F217E47E400381363 /* WifiSettingsPanel.h */, AB4B5A1F217E47E400381363 /* WifiSettingsPanel.h */,
AB3ACB6714C2361100D7D192 /* appDelegate.mm */, AB3ACB6714C2361100D7D192 /* appDelegate.mm */,
ABEBCE362A703E260028CE8A /* CheatDatabaseWindowController.mm */,
AB3ACB6914C2361100D7D192 /* cheatWindowDelegate.mm */, AB3ACB6914C2361100D7D192 /* cheatWindowDelegate.mm */,
AB3E69821E25FBBF00D4CC75 /* DisplayViewCALayer.mm */, AB3E69821E25FBBF00D4CC75 /* DisplayViewCALayer.mm */,
AB700DDD16CDE4C300FBD336 /* DisplayWindowController.mm */, AB700DDD16CDE4C300FBD336 /* DisplayWindowController.mm */,
@ -3401,6 +3437,8 @@
AB6FE66E26E6F7C2002B2106 /* GPU_Operations.cpp */, AB6FE66E26E6F7C2002B2106 /* GPU_Operations.cpp */,
AB6FE66C26E6F7C2002B2106 /* GPU_Operations_SSE2.cpp */, AB6FE66C26E6F7C2002B2106 /* GPU_Operations_SSE2.cpp */,
AB6FE66A26E6F7C2002B2106 /* GPU_Operations_AVX2.cpp */, AB6FE66A26E6F7C2002B2106 /* GPU_Operations_AVX2.cpp */,
AB3B8DC62D8A35A000C9CBFD /* GPU_Operations_NEON.cpp */,
AB11AE8E2E210BB400E8A516 /* GPU_Operations_AltiVec.cpp */,
ABD1FEB81345AC8400AF11D1 /* lua-engine.cpp */, ABD1FEB81345AC8400AF11D1 /* lua-engine.cpp */,
ABD1FEB91345AC8400AF11D1 /* matrix.cpp */, ABD1FEB91345AC8400AF11D1 /* matrix.cpp */,
ABD1FEBA1345AC8400AF11D1 /* mc.cpp */, ABD1FEBA1345AC8400AF11D1 /* mc.cpp */,
@ -3410,6 +3448,7 @@
ABD1FEC01345AC8400AF11D1 /* NDSSystem.cpp */, ABD1FEC01345AC8400AF11D1 /* NDSSystem.cpp */,
ABD1FEC11345AC8400AF11D1 /* OGLRender.cpp */, ABD1FEC11345AC8400AF11D1 /* OGLRender.cpp */,
AB6FE67026E6F7C2002B2106 /* OGLRender_3_2.cpp */, AB6FE67026E6F7C2002B2106 /* OGLRender_3_2.cpp */,
AB3B8DC82D8A35A000C9CBFD /* OGLRender_ES3.cpp */,
ABD1FEC21345AC8400AF11D1 /* path.cpp */, ABD1FEC21345AC8400AF11D1 /* path.cpp */,
ABD1FEC31345AC8400AF11D1 /* rasterize.cpp */, ABD1FEC31345AC8400AF11D1 /* rasterize.cpp */,
ABD1FEC41345AC8400AF11D1 /* readwrite.cpp */, ABD1FEC41345AC8400AF11D1 /* readwrite.cpp */,
@ -3444,6 +3483,8 @@
AB6FE66F26E6F7C2002B2106 /* GPU_Operations.h */, AB6FE66F26E6F7C2002B2106 /* GPU_Operations.h */,
AB6FE66D26E6F7C2002B2106 /* GPU_Operations_SSE2.h */, AB6FE66D26E6F7C2002B2106 /* GPU_Operations_SSE2.h */,
AB6FE66B26E6F7C2002B2106 /* GPU_Operations_AVX2.h */, AB6FE66B26E6F7C2002B2106 /* GPU_Operations_AVX2.h */,
AB3B8DC72D8A35A000C9CBFD /* GPU_Operations_NEON.h */,
AB11AE8F2E210BB400E8A516 /* GPU_Operations_AltiVec.h */,
ABBCE29D15ACB26100A2C965 /* instruction_attributes.h */, ABBCE29D15ACB26100A2C965 /* instruction_attributes.h */,
ABBCE29E15ACB26100A2C965 /* instructions.h */, ABBCE29E15ACB26100A2C965 /* instructions.h */,
ABD1FE841345AC8400AF11D1 /* lua-engine.h */, ABD1FE841345AC8400AF11D1 /* lua-engine.h */,
@ -3457,6 +3498,7 @@
ABD1FE8C1345AC8400AF11D1 /* NDSSystem.h */, ABD1FE8C1345AC8400AF11D1 /* NDSSystem.h */,
ABD1FE8D1345AC8400AF11D1 /* OGLRender.h */, ABD1FE8D1345AC8400AF11D1 /* OGLRender.h */,
AB6FE67126E6F7C2002B2106 /* OGLRender_3_2.h */, AB6FE67126E6F7C2002B2106 /* OGLRender_3_2.h */,
AB3B8DC92D8A35A000C9CBFD /* OGLRender_ES3.h */,
ABD1FE8F1345AC8400AF11D1 /* PACKED.h */, ABD1FE8F1345AC8400AF11D1 /* PACKED.h */,
ABD1FE8E1345AC8400AF11D1 /* PACKED_END.h */, ABD1FE8E1345AC8400AF11D1 /* PACKED_END.h */,
ABD1FE901345AC8400AF11D1 /* path.h */, ABD1FE901345AC8400AF11D1 /* path.h */,
@ -3495,6 +3537,7 @@
ABD1FF031345AC9B00AF11D1 /* slot2_expMemory.cpp */, ABD1FF031345AC9B00AF11D1 /* slot2_expMemory.cpp */,
ABD1FF041345AC9B00AF11D1 /* slot2_gbagame.cpp */, ABD1FF041345AC9B00AF11D1 /* slot2_gbagame.cpp */,
ABD1FF051345AC9B00AF11D1 /* slot2_guitarGrip.cpp */, ABD1FF051345AC9B00AF11D1 /* slot2_guitarGrip.cpp */,
AB1B20AB2AD5ED59007CA7EB /* slot2_hcv1000.cpp */,
ABD1FF061345AC9B00AF11D1 /* slot2_mpcf.cpp */, ABD1FF061345AC9B00AF11D1 /* slot2_mpcf.cpp */,
ABD1FF071345AC9C00AF11D1 /* slot2_none.cpp */, ABD1FF071345AC9C00AF11D1 /* slot2_none.cpp */,
ABD1FF081345AC9C00AF11D1 /* slot2_paddle.cpp */, ABD1FF081345AC9C00AF11D1 /* slot2_paddle.cpp */,
@ -3788,7 +3831,6 @@
buildPhases = ( buildPhases = (
AB2F3B7B15CF9C6000858373 /* ShellScript */, AB2F3B7B15CF9C6000858373 /* ShellScript */,
AB2F3B7C15CF9C6000858373 /* Resources */, AB2F3B7C15CF9C6000858373 /* Resources */,
ABE76A8015E0904E00F458AE /* ShellScript */,
AB2F3BC415CF9C6000858373 /* Sources */, AB2F3BC415CF9C6000858373 /* Sources */,
AB2F3C3A15CF9C6000858373 /* Frameworks */, AB2F3C3A15CF9C6000858373 /* Frameworks */,
); );
@ -3870,7 +3912,7 @@
attributes = { attributes = {
ORGANIZATIONNAME = "DeSmuME Team"; ORGANIZATIONNAME = "DeSmuME Team";
}; };
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DeSmuME (XCode 3)" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DeSmuME (Xcode 3)" */;
compatibilityVersion = "Xcode 3.1"; compatibilityVersion = "Xcode 3.1";
developmentRegion = English; developmentRegion = English;
hasScannedForEncodings = 1; hasScannedForEncodings = 1;
@ -4014,6 +4056,7 @@
ABA1659B2808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16.png in Resources */, ABA1659B2808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16.png in Resources */,
ABA1659C2808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16@2x.png in Resources */, ABA1659C2808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16@2x.png in Resources */,
AB6D78942809FA43007C6B0A /* Icon_MicrophoneIdleNoHardware_256x256.png in Resources */, AB6D78942809FA43007C6B0A /* Icon_MicrophoneIdleNoHardware_256x256.png in Resources */,
ABEFFDDF2A78CB67009C3A2D /* CheatDatabaseViewer.xib in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -4133,6 +4176,7 @@
ABA165A92808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16.png in Resources */, ABA165A92808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16.png in Resources */,
ABA165AA2808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16@2x.png in Resources */, ABA165AA2808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16@2x.png in Resources */,
AB6D78952809FA43007C6B0A /* Icon_MicrophoneIdleNoHardware_256x256.png in Resources */, AB6D78952809FA43007C6B0A /* Icon_MicrophoneIdleNoHardware_256x256.png in Resources */,
ABEFFDE02A78CB67009C3A2D /* CheatDatabaseViewer.xib in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -4252,6 +4296,7 @@
ABA165D32808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16.png in Resources */, ABA165D32808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16.png in Resources */,
ABA165D42808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16@2x.png in Resources */, ABA165D42808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16@2x.png in Resources */,
AB6D78982809FA43007C6B0A /* Icon_MicrophoneIdleNoHardware_256x256.png in Resources */, AB6D78982809FA43007C6B0A /* Icon_MicrophoneIdleNoHardware_256x256.png in Resources */,
ABEFFDDE2A78CB67009C3A2D /* CheatDatabaseViewer.xib in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -4371,6 +4416,7 @@
ABA165C52808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16.png in Resources */, ABA165C52808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16.png in Resources */,
ABA165C62808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16@2x.png in Resources */, ABA165C62808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16@2x.png in Resources */,
AB6D78972809FA43007C6B0A /* Icon_MicrophoneIdleNoHardware_256x256.png in Resources */, AB6D78972809FA43007C6B0A /* Icon_MicrophoneIdleNoHardware_256x256.png in Resources */,
ABEFFDE22A78CB67009C3A2D /* CheatDatabaseViewer.xib in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -4490,6 +4536,7 @@
ABA165B72808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16.png in Resources */, ABA165B72808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16.png in Resources */,
ABA165B82808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16@2x.png in Resources */, ABA165B82808BD6A00C8CFF5 /* Icon_VolumeTwoThird_DarkMode_16x16@2x.png in Resources */,
AB6D78962809FA43007C6B0A /* Icon_MicrophoneIdleNoHardware_256x256.png in Resources */, AB6D78962809FA43007C6B0A /* Icon_MicrophoneIdleNoHardware_256x256.png in Resources */,
ABEFFDE12A78CB67009C3A2D /* CheatDatabaseViewer.xib in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -4627,20 +4674,6 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "cd \"${SRCROOT}\"\nsh \"git-scmrev.sh\""; shellScript = "cd \"${SRCROOT}\"\nsh \"git-scmrev.sh\"";
}; };
ABE76A8015E0904E00F458AE /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"$(SRCROOT)/../svnrev.h",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cd \"${SRCROOT}\"\nsh \"git-scmrev.sh\"";
};
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
@ -4835,6 +4868,8 @@
ABD1267720AE812900EFE1B2 /* ClientAVCaptureObject.cpp in Sources */, ABD1267720AE812900EFE1B2 /* ClientAVCaptureObject.cpp in Sources */,
ABD1267820AE812900EFE1B2 /* macOS_driver.cpp in Sources */, ABD1267820AE812900EFE1B2 /* macOS_driver.cpp in Sources */,
AB4B5A22217E47E400381363 /* WifiSettingsPanel.mm in Sources */, AB4B5A22217E47E400381363 /* WifiSettingsPanel.mm in Sources */,
ABEBCE382A703E260028CE8A /* CheatDatabaseWindowController.mm in Sources */,
AB1B20AD2AD5ED59007CA7EB /* slot2_hcv1000.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -5029,6 +5064,8 @@
ABD1267920AE812900EFE1B2 /* ClientAVCaptureObject.cpp in Sources */, ABD1267920AE812900EFE1B2 /* ClientAVCaptureObject.cpp in Sources */,
ABD1267A20AE812900EFE1B2 /* macOS_driver.cpp in Sources */, ABD1267A20AE812900EFE1B2 /* macOS_driver.cpp in Sources */,
AB4B5A23217E47E400381363 /* WifiSettingsPanel.mm in Sources */, AB4B5A23217E47E400381363 /* WifiSettingsPanel.mm in Sources */,
ABEBCE392A703E260028CE8A /* CheatDatabaseWindowController.mm in Sources */,
AB1B20AE2AD5ED59007CA7EB /* slot2_hcv1000.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -5253,6 +5290,8 @@
ABD1267520AE812900EFE1B2 /* ClientAVCaptureObject.cpp in Sources */, ABD1267520AE812900EFE1B2 /* ClientAVCaptureObject.cpp in Sources */,
ABD1267620AE812900EFE1B2 /* macOS_driver.cpp in Sources */, ABD1267620AE812900EFE1B2 /* macOS_driver.cpp in Sources */,
AB4B5A21217E47E400381363 /* WifiSettingsPanel.mm in Sources */, AB4B5A21217E47E400381363 /* WifiSettingsPanel.mm in Sources */,
ABEBCE372A703E260028CE8A /* CheatDatabaseWindowController.mm in Sources */,
AB1B20AC2AD5ED59007CA7EB /* slot2_hcv1000.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -5477,6 +5516,8 @@
ABD1267D20AE812900EFE1B2 /* ClientAVCaptureObject.cpp in Sources */, ABD1267D20AE812900EFE1B2 /* ClientAVCaptureObject.cpp in Sources */,
ABD1267E20AE812900EFE1B2 /* macOS_driver.cpp in Sources */, ABD1267E20AE812900EFE1B2 /* macOS_driver.cpp in Sources */,
AB4B5A25217E47E400381363 /* WifiSettingsPanel.mm in Sources */, AB4B5A25217E47E400381363 /* WifiSettingsPanel.mm in Sources */,
ABEBCE3B2A703E260028CE8A /* CheatDatabaseWindowController.mm in Sources */,
AB1B20B02AD5ED59007CA7EB /* slot2_hcv1000.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -5671,6 +5712,8 @@
ABD1267B20AE812900EFE1B2 /* ClientAVCaptureObject.cpp in Sources */, ABD1267B20AE812900EFE1B2 /* ClientAVCaptureObject.cpp in Sources */,
ABD1267C20AE812900EFE1B2 /* macOS_driver.cpp in Sources */, ABD1267C20AE812900EFE1B2 /* macOS_driver.cpp in Sources */,
AB4B5A24217E47E400381363 /* WifiSettingsPanel.mm in Sources */, AB4B5A24217E47E400381363 /* WifiSettingsPanel.mm in Sources */,
ABEBCE3A2A703E260028CE8A /* CheatDatabaseWindowController.mm in Sources */,
AB1B20AF2AD5ED59007CA7EB /* slot2_hcv1000.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -5717,6 +5760,14 @@
name = Localizable.strings; name = Localizable.strings;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
ABEFFDDC2A78CB67009C3A2D /* CheatDatabaseViewer.xib */ = {
isa = PBXVariantGroup;
children = (
ABEFFDDD2A78CB67009C3A2D /* English */,
);
name = CheatDatabaseViewer.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */ /* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
@ -6007,7 +6058,7 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DeSmuME (XCode 3)" */ = { C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DeSmuME (Xcode 3)" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
C01FCF4F08A954540054247B /* Debug */, C01FCF4F08A954540054247B /* Debug */,

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2011 Roger Manuel Copyright (C) 2011 Roger Manuel
Copyright (C) 2012-2021 DeSmuME team Copyright (C) 2012-2024 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -22,7 +22,7 @@
#define HOST_DARWIN #define HOST_DARWIN
#define DESMUME_COCOA #define DESMUME_COCOA
#define HAVE_OPENGL #define ENABLE_OPENGL_STANDARD
#define HAVE_LIBZ #define HAVE_LIBZ
//#define HAVE_LUA //#define HAVE_LUA
//#define HAVE_AV_CONFIG_H //#define HAVE_AV_CONFIG_H

View File

@ -54,7 +54,7 @@
<string>Set Speed</string> <string>Set Speed</string>
<string>Enable/Disable Speed Limiter</string> <string>Enable/Disable Speed Limiter</string>
<string>Enable/Disable Auto Frame Skip</string> <string>Enable/Disable Auto Frame Skip</string>
<string>Enable/Disable Cheats</string> <string>Enable/Disable Cheat System</string>
<string>Enable/Disable GPU State</string> <string>Enable/Disable GPU State</string>
</array> </array>
<key>DefaultInputProfiles</key> <key>DefaultInputProfiles</key>
@ -805,7 +805,7 @@
<array/> <array/>
<key>Enable/Disable Auto Frame Skip</key> <key>Enable/Disable Auto Frame Skip</key>
<array/> <array/>
<key>Enable/Disable Cheats</key> <key>Enable/Disable Cheat System</key>
<array/> <array/>
<key>Enable/Disable GPU State</key> <key>Enable/Disable GPU State</key>
<array/> <array/>

View File

@ -4,6 +4,8 @@
<dict> <dict>
<key>Advanscene_AutoDetectRomSaveType</key> <key>Advanscene_AutoDetectRomSaveType</key>
<true/> <true/>
<key>CheatDatabase_RecentFilePath</key>
<array/>
<key>CoreControl_EnableAutoFrameSkip</key> <key>CoreControl_EnableAutoFrameSkip</key>
<true/> <true/>
<key>CoreControl_FramesToSkipSetting</key> <key>CoreControl_FramesToSkipSetting</key>
@ -829,7 +831,7 @@
<array/> <array/>
<key>Enable/Disable Auto Frame Skip</key> <key>Enable/Disable Auto Frame Skip</key>
<array/> <array/>
<key>Enable/Disable Cheats</key> <key>Enable/Disable Cheat System</key>
<array/> <array/>
<key>Enable/Disable GPU State</key> <key>Enable/Disable GPU State</key>
<array/> <array/>

View File

@ -53,6 +53,11 @@
<string>Cocoa</string> <string>Cocoa</string>
<string>OpenEmu</string> <string>OpenEmu</string>
</array> </array>
<key>0.9.14</key>
<array>
<string>Cocoa</string>
<string>OpenEmu</string>
</array>
</dict> </dict>
<key>DefaultPaths</key> <key>DefaultPaths</key>
<dict> <dict>
@ -204,6 +209,27 @@
<string>${OPENEMU}</string> <string>${OPENEMU}</string>
</dict> </dict>
</dict> </dict>
<key>0.9.14</key>
<dict>
<key>Cocoa</key>
<dict>
<key>ROM Save</key>
<string>${APPSUPPORT}</string>
<key>Cheat</key>
<string>${APPSUPPORT}</string>
<key>Firmware Configuration</key>
<string>${APPSUPPORT}</string>
<key>Save State</key>
<string>${APPSUPPORT}</string>
</dict>
<key>OpenEmu</key>
<dict>
<key>ROM Save</key>
<string>${OPENEMU}</string>
<key>Save State</key>
<string>${OPENEMU}</string>
</dict>
</dict>
</dict> </dict>
<key>DirectoryNames</key> <key>DirectoryNames</key>
<dict> <dict>
@ -415,6 +441,32 @@
<string>SoundSamples</string> <string>SoundSamples</string>
</dict> </dict>
</dict> </dict>
<key>0.9.14</key>
<dict>
<key>Cocoa</key>
<dict>
<key>ROM Save</key>
<string>Battery</string>
<key>Cheat</key>
<string>Cheats</string>
<key>Firmware Configuration</key>
<string>Battery</string>
<key>Lua Script</key>
<string>Lua</string>
<key>Video</key>
<string>AviFiles</string>
<key>R4 Format</key>
<string>R4format</string>
<key>ROM</key>
<string>Roms</string>
<key>Save State</key>
<string>States</string>
<key>Screenshot</key>
<string>Screenshots</string>
<key>Sound Sample</key>
<string>SoundSamples</string>
</dict>
</dict>
</dict> </dict>
<key>FileExtensionByTypes</key> <key>FileExtensionByTypes</key>
<dict> <dict>
@ -562,6 +614,24 @@
<string>nds</string> <string>nds</string>
</dict> </dict>
</dict> </dict>
<key>0.9.14</key>
<dict>
<key>Cocoa</key>
<dict>
<key>ROM Save</key>
<string>dsv</string>
<key>Cheat</key>
<string>dct</string>
<key>Firmware Configuration</key>
<string>dfc</string>
<key>Lua Script</key>
<string>lua</string>
<key>Save State</key>
<string>dst</string>
<key>ROM</key>
<string>nds</string>
</dict>
</dict>
</dict> </dict>
<key>FileTypeByExtensions</key> <key>FileTypeByExtensions</key>
<dict> <dict>
@ -709,6 +779,24 @@
<string>ROM</string> <string>ROM</string>
</dict> </dict>
</dict> </dict>
<key>0.9.14</key>
<dict>
<key>Cocoa</key>
<dict>
<key>dsv</key>
<string>ROM Save</string>
<key>dct</key>
<string>Cheat</string>
<key>dfc</key>
<string>Firmware Configuration</string>
<key>lua</key>
<string>Lua Script</string>
<key>dst</key>
<string>Save State</string>
<key>nds</key>
<string>ROM</string>
</dict>
</dict>
</dict> </dict>
</dict> </dict>
</plist> </plist>

View File

@ -4,6 +4,8 @@
<dict> <dict>
<key>NSRequiresAquaSystemAppearance</key> <key>NSRequiresAquaSystemAppearance</key>
<false/> <false/>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>DeSmuME requires your host microphone to emulate the NDS microphone.</string> <string>DeSmuME requires your host microphone to emulate the NDS microphone.</string>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
@ -244,11 +246,11 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>v0.9.13 (Debug)</string> <string>v0.9.14 (Debug)</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>DSmM</string> <string>DSmM</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>0.9.13</string> <string>0.9.14</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.games</string> <string>public.app-category.games</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

View File

@ -4,6 +4,8 @@
<dict> <dict>
<key>NSRequiresAquaSystemAppearance</key> <key>NSRequiresAquaSystemAppearance</key>
<false/> <false/>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>DeSmuME requires your host microphone to emulate the NDS microphone.</string> <string>DeSmuME requires your host microphone to emulate the NDS microphone.</string>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
@ -244,11 +246,11 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>v0.9.13</string> <string>v0.9.14</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>DSmM</string> <string>DSmM</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>0.9.13</string> <string>0.9.14</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.games</string> <string>public.app-category.games</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2014-2022 DeSmuME team Copyright (C) 2014-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -18,16 +18,18 @@
#ifndef _OGLDISPLAYOUTPUT_H_ #ifndef _OGLDISPLAYOUTPUT_H_
#define _OGLDISPLAYOUTPUT_H_ #define _OGLDISPLAYOUTPUT_H_
#ifndef _OGLDISPLAYOUTPUT_3_2_H_
#if defined(__APPLE__) #if defined(__APPLE__)
#include <OpenGL/gl.h> #ifdef _OGLDISPLAYOUTPUT_3_2_H_
#include <OpenGL/glext.h> #include <OpenGL/gl3.h>
#include <OpenGL/gl3ext.h>
#else
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#endif
#include <OpenGL/OpenGL.h> #include <OpenGL/OpenGL.h>
#endif #endif
#endif // _OGLDISPLAYOUTPUT_3_2_H_
#include <set> #include <set>
#include <string> #include <string>
#include <pthread.h> #include <pthread.h>
@ -35,7 +37,7 @@
#include "ClientDisplayView.h" #include "ClientDisplayView.h"
#define OPENGL_FETCH_BUFFER_COUNT 2 #define OPENGL_FETCH_BUFFER_COUNT 3
class OGLVideoOutput; class OGLVideoOutput;
@ -47,7 +49,7 @@ enum ShaderSupportTier
ShaderSupport_MidTier = 3, ShaderSupport_MidTier = 3,
ShaderSupport_HighTier = 4, ShaderSupport_HighTier = 4,
ShaderSupport_TopTier = 5, ShaderSupport_TopTier = 5,
ShaderSupport_FutureTier = 6, ShaderSupport_FutureTier = 6
}; };
struct OGLProcessedFrameInfo struct OGLProcessedFrameInfo
@ -389,9 +391,6 @@ public:
void CopyFromSrcClone(uint32_t *dstBufferPtr, const NDSDisplayID displayID, const u8 bufferIndex); void CopyFromSrcClone(uint32_t *dstBufferPtr, const NDSDisplayID displayID, const u8 bufferIndex);
void FetchNativeDisplayToSrcClone(const NDSDisplayInfo *displayInfoList, const NDSDisplayID displayID, const u8 bufferIndex, bool needsLock); void FetchNativeDisplayToSrcClone(const NDSDisplayInfo *displayInfoList, const NDSDisplayID displayID, const u8 bufferIndex, bool needsLock);
void FetchCustomDisplayToSrcClone(const NDSDisplayInfo *displayInfoList, const NDSDisplayID displayID, const u8 bufferIndex, bool needsLock); void FetchCustomDisplayToSrcClone(const NDSDisplayInfo *displayInfoList, const NDSDisplayID displayID, const u8 bufferIndex, bool needsLock);
void FetchTextureWriteLock(const NDSDisplayID displayID);
void FetchTextureReadLock(const NDSDisplayID displayID);
void FetchTextureUnlock(const NDSDisplayID displayID);
// OpenGL-specific functions that must be called in response to their // OpenGL-specific functions that must be called in response to their
// corresponding GPUClientFetchObject methods. // corresponding GPUClientFetchObject methods.

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2015 DeSmuME team Copyright (C) 2015-2024 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -18,12 +18,6 @@
#ifndef _OGLDISPLAYOUTPUT_3_2_H_ #ifndef _OGLDISPLAYOUTPUT_3_2_H_
#define _OGLDISPLAYOUTPUT_3_2_H_ #define _OGLDISPLAYOUTPUT_3_2_H_
#if defined(__APPLE__)
#include <OpenGL/gl3.h>
#include <OpenGL/gl3ext.h>
#include <OpenGL/OpenGL.h>
#endif
#include "OGLDisplayOutput.h" #include "OGLDisplayOutput.h"
class OGLContextInfo_3_2 : public OGLContextInfo class OGLContextInfo_3_2 : public OGLContextInfo

View File

@ -157,7 +157,7 @@ SineWaveGenerator::SineWaveGenerator()
_frequency = 250.0; _frequency = 250.0;
_sampleRate = MIC_SAMPLE_RATE; _sampleRate = MIC_SAMPLE_RATE;
_cyclePosition = 0.0; _cyclePosition = 0.0;
}; }
SineWaveGenerator::SineWaveGenerator(const double freq, const double sampleRate) SineWaveGenerator::SineWaveGenerator(const double freq, const double sampleRate)
{ {

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2013-2022 DeSmuME team Copyright (C) 2013-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -238,6 +238,9 @@ public:
@property (assign) BOOL layerSubOBJ; @property (assign) BOOL layerSubOBJ;
@property (assign) NSInteger render3DRenderingEngine; @property (assign) NSInteger render3DRenderingEngine;
@property (readonly) NSInteger render3DRenderingEngineApplied;
@property (readonly) NSInteger render3DRenderingEngineAppliedHostRendererID;
@property (readonly) NSString *render3DRenderingEngineAppliedHostRendererName;
@property (assign) BOOL render3DHighPrecisionColorInterpolation; @property (assign) BOOL render3DHighPrecisionColorInterpolation;
@property (assign) BOOL render3DEdgeMarking; @property (assign) BOOL render3DEdgeMarking;
@property (assign) BOOL render3DFog; @property (assign) BOOL render3DFog;
@ -261,7 +264,6 @@ public:
#endif #endif
- (BOOL) gpuStateByBit:(const UInt32)stateBit; - (BOOL) gpuStateByBit:(const UInt32)stateBit;
- (NSString *) render3DRenderingEngineString;
- (void) clearWithColor:(const uint16_t)colorBGRA5551; - (void) clearWithColor:(const uint16_t)colorBGRA5551;
- (void) respondToPauseState:(BOOL)isPaused; - (void) respondToPauseState:(BOOL)isPaused;
@ -272,18 +274,14 @@ extern "C"
{ {
#endif #endif
bool OSXOpenGLRendererInit(); bool cgl_initOpenGL_StandardAuto();
bool OSXOpenGLRendererBegin(); bool cgl_initOpenGL_LegacyAuto();
void OSXOpenGLRendererEnd(); bool cgl_initOpenGL_3_2_CoreProfile();
bool OSXOpenGLRendererFramebufferDidResize(const bool isFBOSupported, size_t w, size_t h);
bool CreateOpenGLRenderer(); void cgl_deinitOpenGL();
void DestroyOpenGLRenderer(); bool cgl_beginOpenGL();
void RequestOpenGLRenderer_3_2(bool request_3_2); void cgl_endOpenGL();
void SetOpenGLRendererFunctions(bool (*initFunction)(), bool cgl_framebufferDidResizeCallback(const bool isFBOSupported, size_t w, size_t h);
bool (*beginOGLFunction)(),
void (*endOGLFunction)(),
bool (*resizeOGLFunction)(const bool isFBOSupported, size_t w, size_t h));
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2013-2022 DeSmuME team Copyright (C) 2013-2025 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -16,6 +16,10 @@
*/ */
#import "cocoa_GPU.h" #import "cocoa_GPU.h"
#include <sys/types.h>
#include <sys/sysctl.h>
#import "cocoa_output.h" #import "cocoa_output.h"
#import "cocoa_globals.h" #import "cocoa_globals.h"
#include "utilities.h" #include "utilities.h"
@ -51,6 +55,9 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
NULL NULL
}; };
int __hostRendererID = -1;
char __hostRendererString[256] = {0};
@implementation CocoaDSGPU @implementation CocoaDSGPU
@dynamic gpuStateFlags; @dynamic gpuStateFlags;
@ -74,6 +81,9 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
@dynamic layerSubOBJ; @dynamic layerSubOBJ;
@dynamic render3DRenderingEngine; @dynamic render3DRenderingEngine;
@dynamic render3DRenderingEngineApplied;
@dynamic render3DRenderingEngineAppliedHostRendererID;
@dynamic render3DRenderingEngineAppliedHostRendererName;
@dynamic render3DHighPrecisionColorInterpolation; @dynamic render3DHighPrecisionColorInterpolation;
@dynamic render3DEdgeMarking; @dynamic render3DEdgeMarking;
@dynamic render3DFog; @dynamic render3DFog;
@ -118,11 +128,17 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
isCPUCoreCountAuto = NO; isCPUCoreCountAuto = NO;
_needRestoreRender3DLock = NO; _needRestoreRender3DLock = NO;
SetOpenGLRendererFunctions(&OSXOpenGLRendererInit, oglrender_init = &cgl_initOpenGL_StandardAuto;
&OSXOpenGLRendererBegin, oglrender_deinit = &cgl_deinitOpenGL;
&OSXOpenGLRendererEnd, oglrender_beginOpenGL = &cgl_beginOpenGL;
&OSXOpenGLRendererFramebufferDidResize); oglrender_endOpenGL = &cgl_endOpenGL;
oglrender_framebufferDidResizeCallback = &cgl_framebufferDidResizeCallback;
#ifdef OGLRENDER_3_2_H
OGLLoadEntryPoints_3_2_Func = &OGLLoadEntryPoints_3_2;
OGLCreateRenderer_3_2_Func = &OGLCreateRenderer_3_2;
#endif
#ifdef PORT_VERSION_OS_X_APP #ifdef PORT_VERSION_OS_X_APP
gpuEvent = new GPUEventHandlerAsync; gpuEvent = new GPUEventHandlerAsync;
@ -169,10 +185,10 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
openglDeviceMaxMultisamples = 0; openglDeviceMaxMultisamples = 0;
render3DMultisampleSizeString = @"Off"; render3DMultisampleSizeString = @"Off";
bool isTempContextCreated = OSXOpenGLRendererInit(); bool isTempContextCreated = cgl_initOpenGL_StandardAuto();
if (isTempContextCreated) if (isTempContextCreated)
{ {
OSXOpenGLRendererBegin(); cgl_beginOpenGL();
GLint maxSamplesOGL = 0; GLint maxSamplesOGL = 0;
@ -184,8 +200,8 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
openglDeviceMaxMultisamples = maxSamplesOGL; openglDeviceMaxMultisamples = maxSamplesOGL;
OSXOpenGLRendererEnd(); cgl_endOpenGL();
DestroyOpenGLRenderer(); cgl_deinitOpenGL();
} }
return self; return self;
@ -193,7 +209,7 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
- (void)dealloc - (void)dealloc
{ {
DestroyOpenGLRenderer(); GPU->SetEventHandler(NULL); // Unassigned our event handler before we delete it.
delete fetchObject; delete fetchObject;
delete gpuEvent; delete gpuEvent;
@ -371,17 +387,13 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
puts("DeSmuME: Invalid 3D renderer chosen; falling back to SoftRasterizer."); puts("DeSmuME: Invalid 3D renderer chosen; falling back to SoftRasterizer.");
rendererID = CORE3DLIST_SWRASTERIZE; rendererID = CORE3DLIST_SWRASTERIZE;
} }
else if (rendererID == CORE3DLIST_OPENGL)
#if defined(__ppc__) || defined(__ppc64__)
if ( (rendererID != CORE3DLIST_NULL) && (rendererID != CORE3DLIST_SWRASTERIZE) )
{ {
puts("DeSmuME: PowerPC Macs only support SoftRasterizer; falling back to SoftRasterizer."); oglrender_init = &cgl_initOpenGL_StandardAuto;
rendererID = CORE3DLIST_SWRASTERIZE;
} }
#endif
gpuEvent->ApplyRender3DSettingsLock(); gpuEvent->ApplyRender3DSettingsLock();
GPU->Set3DRendererByID(rendererID); GPU->Set3DRendererByID((int)rendererID);
gpuEvent->ApplyRender3DSettingsUnlock(); gpuEvent->ApplyRender3DSettingsUnlock();
} }
@ -394,6 +406,88 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
return rendererID; return rendererID;
} }
- (NSInteger) render3DRenderingEngineApplied
{
gpuEvent->ApplyRender3DSettingsLock();
if ( (gpu3D == NULL) || (CurrentRenderer == NULL) )
{
gpuEvent->ApplyRender3DSettingsUnlock();
return 0;
}
const NSInteger rendererID = (NSInteger)CurrentRenderer->GetRenderID();
gpuEvent->ApplyRender3DSettingsUnlock();
return rendererID;
}
- (NSInteger) render3DRenderingEngineAppliedHostRendererID
{
NSInteger hostID = 0;
gpuEvent->ApplyRender3DSettingsLock();
if ( (gpu3D == NULL) || (CurrentRenderer == NULL) )
{
gpuEvent->ApplyRender3DSettingsUnlock();
return hostID;
}
switch (CurrentRenderer->GetRenderID())
{
case RENDERID_OPENGL_AUTO:
case RENDERID_OPENGL_LEGACY:
case RENDERID_OPENGL_3_2:
hostID = (NSInteger)__hostRendererID;
break;
case RENDERID_NULL:
case RENDERID_SOFTRASTERIZER:
default:
break;
}
gpuEvent->ApplyRender3DSettingsUnlock();
return hostID;
}
- (NSString *) render3DRenderingEngineAppliedHostRendererName
{
NSString *theString = @"Uninitialized";
gpuEvent->ApplyRender3DSettingsLock();
if ( (gpu3D == NULL) || (CurrentRenderer == NULL) )
{
gpuEvent->ApplyRender3DSettingsUnlock();
return theString;
}
std::string theName;
switch (CurrentRenderer->GetRenderID())
{
case RENDERID_OPENGL_AUTO:
case RENDERID_OPENGL_LEGACY:
case RENDERID_OPENGL_3_2:
theName = std::string((const char *)__hostRendererString);
break;
case RENDERID_NULL:
case RENDERID_SOFTRASTERIZER:
default:
theName = CurrentRenderer->GetName();
break;
}
theString = [NSString stringWithCString:theName.c_str() encoding:NSUTF8StringEncoding];
gpuEvent->ApplyRender3DSettingsUnlock();
return theString;
}
- (void) setRender3DHighPrecisionColorInterpolation:(BOOL)state - (void) setRender3DHighPrecisionColorInterpolation:(BOOL)state
{ {
gpuEvent->ApplyRender3DSettingsLock(); gpuEvent->ApplyRender3DSettingsLock();
@ -484,7 +578,7 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
gpuEvent->ApplyRender3DSettingsLock(); gpuEvent->ApplyRender3DSettingsLock();
CommonSettings.num_cores = numberCores; CommonSettings.num_cores = (int)numberCores;
if (renderingEngineID == RENDERID_SOFTRASTERIZER) if (renderingEngineID == RENDERID_SOFTRASTERIZER)
{ {
@ -1018,26 +1112,6 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
return ([self gpuStateFlags] & (1 << stateBit)) ? YES : NO; return ([self gpuStateFlags] & (1 << stateBit)) ? YES : NO;
} }
- (NSString *) render3DRenderingEngineString
{
NSString *theString = @"Uninitialized";
gpuEvent->ApplyRender3DSettingsLock();
if (gpu3D == NULL)
{
gpuEvent->ApplyRender3DSettingsUnlock();
return theString;
}
const char *theName = gpu3D->name;
theString = [NSString stringWithCString:theName encoding:NSUTF8StringEncoding];
gpuEvent->ApplyRender3DSettingsUnlock();
return theString;
}
- (void) clearWithColor:(const uint16_t)colorBGRA5551 - (void) clearWithColor:(const uint16_t)colorBGRA5551
{ {
gpuEvent->FramebufferLock(); gpuEvent->FramebufferLock();
@ -1819,22 +1893,494 @@ bool GPUEventHandlerAsync::GetRender3DNeedsFinish()
#pragma mark - #pragma mark -
#if !defined(MAC_OS_X_VERSION_10_7)
#define kCGLPFAOpenGLProfile (CGLPixelFormatAttribute)99
#define kCGLOGLPVersion_Legacy 0x1000
#define kCGLOGLPVersion_3_2_Core 0x3200
#define kCGLOGLPVersion_GL3_Core 0x3200
#define kCGLRPVideoMemoryMegabytes (CGLRendererProperty)131
#define kCGLRPTextureMemoryMegabytes (CGLRendererProperty)132
#endif
#if !defined(MAC_OS_X_VERSION_10_9)
#define kCGLOGLPVersion_GL4_Core 0x4100
#endif
#if !defined(MAC_OS_X_VERSION_10_13)
#define kCGLRPRemovable (CGLRendererProperty)142
#endif
CGLContextObj OSXOpenGLRendererContext = NULL; CGLContextObj OSXOpenGLRendererContext = NULL;
CGLContextObj OSXOpenGLRendererContextPrev = NULL; CGLContextObj OSXOpenGLRendererContextPrev = NULL;
SILENCE_DEPRECATION_MACOS_10_7( CGLPBufferObj OSXOpenGLRendererPBuffer = NULL ); SILENCE_DEPRECATION_MACOS_10_7( CGLPBufferObj OSXOpenGLRendererPBuffer = NULL )
bool OSXOpenGLRendererInit() // Struct to hold renderer info
struct HostRendererInfo
{ {
bool isContextCreated = (OSXOpenGLRendererContext != NULL); int32_t rendererID; // Renderer ID, used to associate a renderer with a display device or virtual screen
int32_t accelerated; // Hardware acceleration flag, 0 = Software only, 1 = Has hardware acceleration
int32_t displayID; // Display ID, used to associate a display device with a renderer
int32_t online; // Online flag, 0 = No display device associated, 1 = Display device associated
int32_t removable; // Removable flag, used to indicate if the renderer is removable (like an eGPU), 0 = Fixed, 1 = Removable
int32_t virtualScreen; // Virtual screen index, used to associate a virtual screen with a renderer
int32_t videoMemoryMB; // The total amount of VRAM available to this renderer
int32_t textureMemoryMB; // The amount of VRAM available to this renderer for texture usage
char vendor[256]; // C-string copy of the host renderer's vendor
char name[256]; // C-string copy of the host renderer's name
const void *vendorStr; // Pointer to host renderer's vendor string (parsing this is implementation dependent)
const void *nameStr; // Pointer to host renderer's name string (parsing this is implementation dependent)
};
typedef struct HostRendererInfo HostRendererInfo;
static bool __cgl_initOpenGL(const int requestedProfile)
{
bool result = false;
CACHE_ALIGN char ctxString[16] = {0};
if (requestedProfile == kCGLOGLPVersion_GL4_Core)
{
strncpy(ctxString, "CGL 4.1", sizeof(ctxString));
}
else if (requestedProfile == kCGLOGLPVersion_3_2_Core)
{
strncpy(ctxString, "CGL 3.2", sizeof(ctxString));
}
else
{
strncpy(ctxString, "CGL Legacy", sizeof(ctxString));
}
if (OSXOpenGLRendererContext != NULL)
{
result = true;
return result;
}
const bool isHighSierraSupported = IsOSXVersionSupported(10, 13, 0);
const bool isMavericksSupported = (isHighSierraSupported || IsOSXVersionSupported(10, 9, 0));
const bool isMountainLionSupported = (isMavericksSupported || IsOSXVersionSupported(10, 8, 0));
const bool isLionSupported = (isMountainLionSupported || IsOSXVersionSupported(10, 7, 0));
const bool isLeopardSupported = (isLionSupported || IsOSXVersionSupported(10, 5, 0));
CGLPixelFormatAttribute attrs[] = {
kCGLPFAColorSize, (CGLPixelFormatAttribute)24,
kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8,
kCGLPFADepthSize, (CGLPixelFormatAttribute)24,
kCGLPFAStencilSize, (CGLPixelFormatAttribute)8,
kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)0,
kCGLPFAAllowOfflineRenderers,
kCGLPFAAccelerated,
kCGLPFANoRecovery,
(CGLPixelFormatAttribute)0
};
if (requestedProfile == kCGLOGLPVersion_GL4_Core)
{
if (isMavericksSupported)
{
attrs[5] = (CGLPixelFormatAttribute)0; // We'll be using FBOs instead of the default framebuffer.
attrs[7] = (CGLPixelFormatAttribute)0; // We'll be using FBOs instead of the default framebuffer.
attrs[9] = (CGLPixelFormatAttribute)requestedProfile;
}
else
{
fprintf(stderr, "%s: Your version of OS X is too old to support 4.1 Core Profile.\n", ctxString);
return result;
}
}
else if (requestedProfile == kCGLOGLPVersion_3_2_Core)
{
// As of 2021/09/03, testing has shown that macOS v10.7's OpenGL 3.2 shader
// compiler isn't very reliable, and so we're going to require macOS v10.8
// instead, which at least has a working shader compiler for OpenGL 3.2.
if (isMountainLionSupported)
{
attrs[5] = (CGLPixelFormatAttribute)0; // We'll be using FBOs instead of the default framebuffer.
attrs[7] = (CGLPixelFormatAttribute)0; // We'll be using FBOs instead of the default framebuffer.
attrs[9] = (CGLPixelFormatAttribute)requestedProfile;
}
else
{
fprintf(stderr, "%s: Your version of OS X is too old to support 3.2 Core Profile.\n", ctxString);
return result;
}
}
else if (isLionSupported)
{
attrs[9] = (CGLPixelFormatAttribute)kCGLOGLPVersion_Legacy;
}
else
{
attrs[8] = (CGLPixelFormatAttribute)kCGLPFAAccelerated;
attrs[9] = (CGLPixelFormatAttribute)kCGLPFANoRecovery;
attrs[11] = (CGLPixelFormatAttribute)0;
attrs[12] = (CGLPixelFormatAttribute)0;
}
CGLError error = kCGLNoError;
CGLPixelFormatObj cglPixFormat = NULL;
CGLContextObj newContext = NULL;
GLint virtualScreenCount = 0;
CGLChoosePixelFormat(attrs, &cglPixFormat, &virtualScreenCount);
if (cglPixFormat == NULL)
{
if (requestedProfile == kCGLOGLPVersion_GL4_Core)
{
// OpenGL 4.1 Core Profile requires hardware acceleration. Bail if we can't find a renderer that supports both.
fprintf(stderr, "%s: This system has no HW-accelerated renderers that support 4.1 Core Profile.\n", ctxString);
return result;
}
else if (requestedProfile == kCGLOGLPVersion_3_2_Core)
{
// OpenGL 3.2 Core Profile requires hardware acceleration. Bail if we can't find a renderer that supports both.
fprintf(stderr, "%s: This system has no HW-accelerated renderers that support 3.2 Core Profile.\n", ctxString);
return result;
}
// For Legacy OpenGL, we'll allow fallback to the Apple Software Renderer.
// However, doing this will result in a substantial performance loss.
if (attrs[8] == kCGLPFAAccelerated)
{
attrs[8] = (CGLPixelFormatAttribute)0;
attrs[9] = (CGLPixelFormatAttribute)0;
attrs[10] = (CGLPixelFormatAttribute)0;
}
else
{
attrs[10] = (CGLPixelFormatAttribute)0;
attrs[11] = (CGLPixelFormatAttribute)0;
attrs[12] = (CGLPixelFormatAttribute)0;
}
error = CGLChoosePixelFormat(attrs, &cglPixFormat, &virtualScreenCount);
if (error != kCGLNoError)
{
// We shouldn't fail at this point, but we're including this to account for all code paths.
fprintf(stderr, "%s: Failed to create the pixel format structure: %i\n", ctxString, (int)error);
return result;
}
else
{
printf("WARNING: No HW-accelerated renderers were found -- falling back to Apple Software Renderer.\n This will result in a substantial performance loss.");
}
}
// Create the OpenGL context using our pixel format, and then save the default assigned virtual screen.
error = CGLCreateContext(cglPixFormat, NULL, &newContext);
CGLReleasePixelFormat(cglPixFormat);
cglPixFormat = NULL;
if (error != kCGLNoError)
{
fprintf(stderr, "%s: Failed to create an OpenGL context: %i\n", ctxString, (int)error);
return result;
}
OSXOpenGLRendererContext = newContext;
GLint defaultVirtualScreen = 0;
CGLGetVirtualScreen(newContext, &defaultVirtualScreen);
// Retrieve the properties of every renderer available on the system.
CGLRendererInfoObj cglRendererInfo = NULL;
GLint rendererCount = 0;
CGLQueryRendererInfo(0xFFFFFFFF, &cglRendererInfo, &rendererCount);
HostRendererInfo *rendererInfo = (HostRendererInfo *)malloc(sizeof(HostRendererInfo) * rendererCount);
memset(rendererInfo, 0, sizeof(HostRendererInfo) * rendererCount);
if (isLeopardSupported)
{
for (GLint i = 0; i < rendererCount; i++)
{
HostRendererInfo &info = rendererInfo[i];
CGLDescribeRenderer(cglRendererInfo, i, kCGLRPOnline, &(info.online));
CGLDescribeRenderer(cglRendererInfo, i, kCGLRPDisplayMask, &(info.displayID));
info.displayID = (GLint)CGOpenGLDisplayMaskToDisplayID(info.displayID);
CGLDescribeRenderer(cglRendererInfo, i, kCGLRPAccelerated, &(info.accelerated));
CGLDescribeRenderer(cglRendererInfo, i, kCGLRPRendererID, &(info.rendererID));
if (isLionSupported)
{
CGLDescribeRenderer(cglRendererInfo, i, kCGLRPVideoMemoryMegabytes, &(info.videoMemoryMB));
CGLDescribeRenderer(cglRendererInfo, i, kCGLRPTextureMemoryMegabytes, &(info.textureMemoryMB));
}
else
{
CGLDescribeRenderer(cglRendererInfo, i, kCGLRPVideoMemory, &(info.videoMemoryMB));
info.videoMemoryMB = (GLint)(((uint32_t)info.videoMemoryMB + 1) >> 20);
CGLDescribeRenderer(cglRendererInfo, i, kCGLRPTextureMemory, &(info.textureMemoryMB));
info.textureMemoryMB = (GLint)(((uint32_t)info.textureMemoryMB + 1) >> 20);
}
if (isHighSierraSupported)
{
CGLDescribeRenderer(cglRendererInfo, i, kCGLRPRemovable, &(info.removable));
}
}
}
else
{
CGLDestroyRendererInfo(cglRendererInfo);
free(rendererInfo);
fprintf(stderr, "%s: Failed to retrieve renderer info - requires Mac OS X v10.5 or later.\n", ctxString);
return result;
}
CGLDestroyRendererInfo(cglRendererInfo);
cglRendererInfo = NULL;
// Retrieve the vendor and renderer info from OpenGL.
cgl_beginOpenGL();
for (GLint i = 0; i < virtualScreenCount; i++)
{
CGLSetVirtualScreen(newContext, i);
GLint r;
CGLGetParameter(newContext, kCGLCPCurrentRendererID, &r);
for (int j = 0; j < rendererCount; j++)
{
HostRendererInfo &info = rendererInfo[j];
if (r == info.rendererID)
{
info.virtualScreen = i;
info.vendorStr = (const char *)glGetString(GL_VENDOR);
if (info.vendorStr != NULL)
{
strncpy(info.vendor, (const char *)info.vendorStr, sizeof(info.vendor));
}
else if (info.accelerated == 0)
{
strncpy(info.vendor, "Apple Inc.", sizeof(info.vendor));
}
else
{
strncpy(info.vendor, "UNKNOWN", sizeof(info.vendor));
}
info.nameStr = (const char *)glGetString(GL_RENDERER);
if (info.nameStr != NULL)
{
strncpy(info.name, (const char *)info.nameStr, sizeof(info.name));
}
else if (info.accelerated == 0)
{
strncpy(info.name, "Apple Software Renderer", sizeof(info.name));
}
else
{
strncpy(info.name, "UNKNOWN", sizeof(info.name));
}
}
}
}
cgl_endOpenGL();
// Get the default virtual screen.
strncpy(__hostRendererString, "UNKNOWN", sizeof(__hostRendererString));
__hostRendererID = -1;
HostRendererInfo defaultRendererInfo = rendererInfo[0];
for (int i = 0; i < rendererCount; i++)
{
if (defaultVirtualScreen == rendererInfo[i].virtualScreen)
{
defaultRendererInfo = rendererInfo[i];
__hostRendererID = defaultRendererInfo.rendererID;
strncpy(__hostRendererString, (const char *)defaultRendererInfo.name, sizeof(__hostRendererString));
if ( (defaultRendererInfo.online == 1) && (defaultRendererInfo.vendorStr != NULL) && (defaultRendererInfo.nameStr != NULL) )
{
break;
}
}
}
printf("Default OpenGL Renderer: [0x%08X] %s\n", __hostRendererID, __hostRendererString);
/*
bool isDefaultRunningIntegratedGPU = false;
if ( (defaultRendererInfo.online == 1) && (defaultRendererInfo.vendorStr != NULL) && (defaultRendererInfo.nameStr != NULL) )
{
const HostRendererInfo &d = defaultRendererInfo;
isDefaultRunningIntegratedGPU = (strstr(d.name, "GMA 950") != NULL) ||
(strstr(d.name, "GMA X3100") != NULL) ||
(strstr(d.name, "GeForce 9400M") != NULL) ||
(strstr(d.name, "GeForce 320M") != NULL) ||
(strstr(d.name, "HD Graphics") != NULL) ||
(strstr(d.name, "Iris 5100") != NULL) ||
(strstr(d.name, "Iris Plus") != NULL) ||
(strstr(d.name, "Iris Pro") != NULL) ||
(strstr(d.name, "Iris Graphics") != NULL) ||
(strstr(d.name, "UHD Graphics") != NULL);
}
*/
#if defined(DEBUG) && (DEBUG == 1)
// Report information on every renderer.
if (!isLionSupported)
{
printf("WARNING: You are running a macOS version earlier than v10.7.\n Video Memory and Texture Memory reporting is capped\n at 2048 MB on older macOS.\n");
}
printf("CGL Renderer Count: %i\n", rendererCount);
printf(" Virtual Screen Count: %i\n\n", virtualScreenCount);
for (int i = 0; i < rendererCount; i++)
{
const HostRendererInfo &info = rendererInfo[i];
printf("Renderer Index: %i\n", i);
printf("Virtual Screen: %i\n", info.virtualScreen);
printf("Vendor: %s\n", info.vendor);
printf("Renderer: %s\n", info.name);
printf("Renderer ID: 0x%08X\n", info.rendererID);
printf("Accelerated: %s\n", (info.accelerated == 1) ? "YES" : "NO");
printf("Online: %s\n", (info.online == 1) ? "YES" : "NO");
if (isHighSierraSupported)
{
printf("Removable: %s\n", (info.removable == 1) ? "YES" : "NO");
}
else
{
printf("Removable: UNSUPPORTED, Requires High Sierra\n");
}
printf("Display ID: 0x%08X\n", info.displayID);
printf("Video Memory: %i MB\n", info.videoMemoryMB);
printf("Texture Memory: %i MB\n\n", info.textureMemoryMB);
}
#endif
// Search for a better virtual screen that will suit our offscreen rendering better.
//
// At the moment, we are not supporting removable renderers such as eGPUs. Attempting
// to support removable renderers would require a lot more code to handle dynamically
// changing display<-->renderer associations. - rogerman 2025/03/25
bool wasBetterVirtualScreenFound = false;
char *modelCString = NULL;
size_t modelStringLen = 0;
sysctlbyname("hw.model", NULL, &modelStringLen, NULL, 0);
if (modelStringLen > 0)
{
modelCString = (char *)malloc(modelStringLen * sizeof(char));
sysctlbyname("hw.model", modelCString, &modelStringLen, NULL, 0);
}
for (int i = 0; i < rendererCount; i++)
{
const HostRendererInfo &info = rendererInfo[i];
if ( (defaultRendererInfo.vendorStr == NULL) || (defaultRendererInfo.nameStr == NULL) || (info.vendorStr == NULL) || (info.nameStr == NULL) )
{
continue;
}
wasBetterVirtualScreenFound = (info.accelerated == 1) &&
( ( (modelCString != NULL) && (strstr((const char *)modelCString, "MacBookPro") != NULL) &&
( ( (strstr(defaultRendererInfo.name, "GeForce 9400M") != NULL) &&
(strstr(info.name, "GeForce 9600M GT") != NULL) ) ||
( (strstr(defaultRendererInfo.name, "HD Graphics") != NULL) &&
((strstr(info.name, "GeForce GT 330M") != NULL) ||
(strstr(info.name, "Radeon HD 6490M") != NULL) ||
(strstr(info.name, "Radeon HD 6750M") != NULL) ||
(strstr(info.name, "Radeon HD 6770M") != NULL) ||
(strstr(info.name, "GeForce GT 650M") != NULL) ||
(strstr(info.name, "Radeon Pro 450") != NULL) ||
(strstr(info.name, "Radeon Pro 455") != NULL) ||
(strstr(info.name, "Radeon Pro 555") != NULL) ||
(strstr(info.name, "Radeon Pro 560") != NULL)) ) ||
( (strstr(defaultRendererInfo.name, "Iris Pro") != NULL) &&
((strstr(info.name, "GeForce GT 750M") != NULL) ||
(strstr(info.name, "Radeon R9 M370X") != NULL)) ) ||
( (strstr(defaultRendererInfo.name, "UHD Graphics") != NULL) &&
((strstr(info.name, "Radeon Pro 555X") != NULL) ||
(strstr(info.name, "Radeon Pro 560X") != NULL) ||
(strstr(info.name, "Radeon Pro Vega 16") != NULL) ||
(strstr(info.name, "Radeon Pro Vega 20") != NULL) ||
(strstr(info.name, "Radeon Pro 5300M") != NULL) ||
(strstr(info.name, "Radeon Pro 5500M") != NULL) ||
(strstr(info.name, "Radeon Pro 5600M") != NULL)) ) ) ) ||
( (modelCString != NULL) && (strstr((const char *)modelCString, "MacPro6,1") != NULL) && (info.online == 0) &&
((strstr(info.name, "FirePro D300") != NULL) ||
(strstr(info.name, "FirePro D500") != NULL) ||
(strstr(info.name, "FirePro D700") != NULL)) ) );
if (wasBetterVirtualScreenFound)
{
CGLSetVirtualScreen(newContext, info.virtualScreen);
__hostRendererID = info.rendererID;
strncpy(__hostRendererString, (const char *)info.name, sizeof(__hostRendererString));
printf("Found Better OpenGL Renderer: [0x%08X] %s\n", __hostRendererID, __hostRendererString);
break;
}
}
// If we couldn't find a better virtual screen for our rendering, then just revert to the default one.
if (!wasBetterVirtualScreenFound)
{
CGLSetVirtualScreen(newContext, defaultVirtualScreen);
}
// We're done! Report success and return.
printf("%s: OpenGL context creation successful.\n\n", ctxString);
free(rendererInfo);
free(modelCString);
result = true;
return result;
}
bool cgl_initOpenGL_StandardAuto()
{
bool isContextCreated = __cgl_initOpenGL(kCGLOGLPVersion_GL4_Core);
if (!isContextCreated) if (!isContextCreated)
{ {
isContextCreated = CreateOpenGLRenderer(); isContextCreated = __cgl_initOpenGL(kCGLOGLPVersion_3_2_Core);
}
if (!isContextCreated)
{
isContextCreated = __cgl_initOpenGL(kCGLOGLPVersion_Legacy);
} }
return isContextCreated; return isContextCreated;
} }
bool OSXOpenGLRendererBegin() bool cgl_initOpenGL_LegacyAuto()
{
return __cgl_initOpenGL(kCGLOGLPVersion_Legacy);
}
bool cgl_initOpenGL_3_2_CoreProfile()
{
return __cgl_initOpenGL(kCGLOGLPVersion_3_2_Core);
}
void cgl_deinitOpenGL()
{
if (OSXOpenGLRendererContext == NULL)
{
return;
}
CGLSetCurrentContext(NULL);
SILENCE_DEPRECATION_MACOS_10_7( CGLReleasePBuffer(OSXOpenGLRendererPBuffer) );
OSXOpenGLRendererPBuffer = NULL;
CGLReleaseContext(OSXOpenGLRendererContext);
OSXOpenGLRendererContext = NULL;
OSXOpenGLRendererContextPrev = NULL;
}
bool cgl_beginOpenGL()
{ {
OSXOpenGLRendererContextPrev = CGLGetCurrentContext(); OSXOpenGLRendererContextPrev = CGLGetCurrentContext();
CGLSetCurrentContext(OSXOpenGLRendererContext); CGLSetCurrentContext(OSXOpenGLRendererContext);
@ -1842,7 +2388,7 @@ bool OSXOpenGLRendererBegin()
return true; return true;
} }
void OSXOpenGLRendererEnd() void cgl_endOpenGL()
{ {
#ifndef PORT_VERSION_OS_X_APP #ifndef PORT_VERSION_OS_X_APP
// The OpenEmu plug-in needs the context reset after 3D rendering since OpenEmu's context // The OpenEmu plug-in needs the context reset after 3D rendering since OpenEmu's context
@ -1853,7 +2399,7 @@ void OSXOpenGLRendererEnd()
#endif #endif
} }
bool OSXOpenGLRendererFramebufferDidResize(const bool isFBOSupported, size_t w, size_t h) bool cgl_framebufferDidResizeCallback(const bool isFBOSupported, size_t w, size_t h)
{ {
bool result = false; bool result = false;
@ -1871,7 +2417,7 @@ bool OSXOpenGLRendererFramebufferDidResize(const bool isFBOSupported, size_t w,
// Create a PBuffer if FBOs are not supported. // Create a PBuffer if FBOs are not supported.
SILENCE_DEPRECATION_MACOS_10_7( CGLPBufferObj newPBuffer = NULL ); SILENCE_DEPRECATION_MACOS_10_7( CGLPBufferObj newPBuffer = NULL );
SILENCE_DEPRECATION_MACOS_10_7( CGLError error = CGLCreatePBuffer(w, h, GL_TEXTURE_2D, GL_RGBA, 0, &newPBuffer) ); SILENCE_DEPRECATION_MACOS_10_7( CGLError error = CGLCreatePBuffer((GLsizei)w, (GLsizei)h, GL_TEXTURE_2D, GL_RGBA, 0, &newPBuffer) );
if ( (newPBuffer == NULL) || (error != kCGLNoError) ) if ( (newPBuffer == NULL) || (error != kCGLNoError) )
{ {
@ -1892,100 +2438,3 @@ bool OSXOpenGLRendererFramebufferDidResize(const bool isFBOSupported, size_t w,
result = true; result = true;
return result; return result;
} }
bool CreateOpenGLRenderer()
{
bool result = false;
bool useContext_3_2 = false;
CGLPixelFormatObj cglPixFormat = NULL;
CGLContextObj newContext = NULL;
GLint virtualScreenCount = 0;
CGLPixelFormatAttribute attrs[] = {
kCGLPFAColorSize, (CGLPixelFormatAttribute)24,
kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8,
kCGLPFADepthSize, (CGLPixelFormatAttribute)24,
kCGLPFAStencilSize, (CGLPixelFormatAttribute)8,
kCGLPFAAccelerated,
(CGLPixelFormatAttribute)0, (CGLPixelFormatAttribute)0,
(CGLPixelFormatAttribute)0
};
// If we can support a 3.2 Core Profile context, then request that in our
// pixel format attributes.
#ifdef MAC_OS_X_VERSION_10_7
// As of 2021/09/03, testing has shown that macOS v10.7's OpenGL 3.2 shader
// compiler isn't very reliable, and so we're going to require macOS v10.8
// instead, which at least has a working shader compiler for OpenGL 3.2.
useContext_3_2 = IsOSXVersionSupported(10, 8, 0);
if (useContext_3_2)
{
attrs[9] = kCGLPFAOpenGLProfile;
attrs[10] = (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core;
}
#endif
CGLChoosePixelFormat(attrs, &cglPixFormat, &virtualScreenCount);
if (cglPixFormat == NULL)
{
// Remove the HW rendering requirement and try again. Note that this will
// result in SW rendering, which will cause a substantial speed hit.
attrs[8] = (CGLPixelFormatAttribute)0;
CGLChoosePixelFormat(attrs, &cglPixFormat, &virtualScreenCount);
if (cglPixFormat == NULL)
{
return result;
}
}
CGLCreateContext(cglPixFormat, NULL, &newContext);
CGLReleasePixelFormat(cglPixFormat);
RequestOpenGLRenderer_3_2(useContext_3_2);
OSXOpenGLRendererContext = newContext;
result = true;
return result;
}
void DestroyOpenGLRenderer()
{
if (OSXOpenGLRendererContext == NULL)
{
return;
}
OSXOpenGLRendererEnd();
SILENCE_DEPRECATION_MACOS_10_7( CGLReleasePBuffer(OSXOpenGLRendererPBuffer) );
OSXOpenGLRendererPBuffer = NULL;
CGLReleaseContext(OSXOpenGLRendererContext);
OSXOpenGLRendererContext = NULL;
OSXOpenGLRendererContextPrev = NULL;
}
void RequestOpenGLRenderer_3_2(bool request_3_2)
{
#ifdef OGLRENDER_3_2_H
if (request_3_2)
{
OGLLoadEntryPoints_3_2_Func = &OGLLoadEntryPoints_3_2;
OGLCreateRenderer_3_2_Func = &OGLCreateRenderer_3_2;
return;
}
#endif
OGLLoadEntryPoints_3_2_Func = NULL;
OGLCreateRenderer_3_2_Func = NULL;
}
void SetOpenGLRendererFunctions(bool (*initFunction)(),
bool (*beginOGLFunction)(),
void (*endOGLFunction)(),
bool (*resizeOGLFunction)(const bool isFBOSupported, size_t w, size_t h))
{
oglrender_init = initFunction;
oglrender_beginOpenGL = beginOGLFunction;
oglrender_endOpenGL = endOGLFunction;
oglrender_framebufferDidResizeCallback = resizeOGLFunction;
}

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2011 Roger Manuel Copyright (C) 2011 Roger Manuel
Copyright (C) 2011-2015 DeSmuME team Copyright (C) 2011-2023 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -16,37 +16,305 @@
along with the this software. If not, see <http://www.gnu.org/licenses/>. along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/ */
#import <Cocoa/Cocoa.h> #include <string>
#include <vector>
#include "../../cheatSystem.h"
#undef BOOL #undef BOOL
#import <Cocoa/Cocoa.h>
class CHEATS; class CHEATS;
class CHEATS_LIST; class CHEATS_LIST;
class CHEATSEARCH; class CHEATSEARCH;
class ClientCheatManager;
enum CheatType
{
CheatType_Internal = 0,
CheatType_ActionReplay = 1,
CheatType_CodeBreaker = 2
};
/******************************************************************************************** enum CheatFreezeType
CocoaDSCheatItem - OBJECTIVE-C CLASS {
CheatFreezeType_Normal = 0,
CheatFreezeType_CanDecrease = 1,
CheatFreezeType_CanIncrease = 2
};
This is an Objective-C wrapper class for DeSmuME's cheat item struct. enum CheatSearchStyle
{
The cheat item data is not freed upon release of this object. This is by design. CheatSearchStyle_ExactValue = 0,
CheatSearchStyle_Comparative = 1
};
enum CheatSearchCompareStyle
{
CheatSearchCompareStyle_GreaterThan = 0,
CheatSearchCompareStyle_LesserThan = 1,
CheatSearchCompareStyle_Equals = 2,
CheatSearchCompareStyle_NotEquals = 3
};
union DesmumeCheatSearchItem
{
uint64_t data;
struct
{
uint32_t address;
uint32_t value;
};
};
typedef union DesmumeCheatSearchItem DesmumeCheatSearchItem;
typedef std::vector<DesmumeCheatSearchItem> DesmumeCheatSearchResultsList;
struct InternalCheatParam
{
uint32_t address;
uint32_t value;
uint8_t valueLength;
};
typedef struct InternalCheatParam InternalCheatParam;
class ClientCheatItem
{
protected:
ClientCheatManager *_cheatManager;
bool _isEnabled;
bool _willAddFromDB;
CheatType _cheatType;
std::string _nameString;
std::string _commentString;
// Internal cheat type parameters
CheatFreezeType _freezeType;
char _addressString[10+1];
uint32_t _address;
uint32_t _value;
uint8_t _valueLength;
// Action Replay parameters
uint32_t _codeCount;
std::string _rawCodeString;
std::string _cleanCodeString;
void _ConvertInternalToActionReplay();
void _ConvertActionReplayToInternal();
public:
ClientCheatItem();
~ClientCheatItem();
void Init(const CHEATS_LIST &inCheatItem);
void Init(const ClientCheatItem &inCheatItem);
void SetCheatManager(ClientCheatManager *cheatManager);
ClientCheatManager* GetCheatManager() const;
void SetEnabled(bool theState);
bool IsEnabled() const;
void SetWillAddFromDB(bool theState);
bool WillAddFromDB() const;
CheatType GetType() const;
void SetType(CheatType requestedType);
bool IsSupportedType() const;
const char* GetName() const;
void SetName(const char *nameString);
const char* GetComments() const;
void SetComments(const char *commentString);
CheatFreezeType GetFreezeType() const;
void SetFreezeType(CheatFreezeType theFreezeType);
uint32_t GetAddress() const;
void SetAddress(uint32_t theAddress);
const char* GetAddressString() const;
const char* GetAddressSixDigitString() const;
void SetAddressSixDigitString(const char *sixDigitString);
uint32_t GetValue() const;
void SetValue(uint32_t theValue);
uint8_t GetValueLength() const;
void SetValueLength(uint8_t byteLength);
void SetRawCodeString(const char *rawString, const bool willSaveValidatedRawString);
const char* GetRawCodeString() const;
const char* GetCleanCodeString() const;
const std::string& GetCleanCodeCppString() const;
uint32_t GetCodeCount() const;
void ClientToDesmumeCheatItem(CHEATS_LIST *outCheatItem) const;
};
class ClientCheatList
{
private:
ClientCheatItem* __AddItem(const ClientCheatItem *srcItem, const bool willCopy, const bool allowDuplicates);
protected:
std::vector<ClientCheatItem *> *_list;
public:
ClientCheatList();
~ClientCheatList();
CheatSystemError LoadFromFile(const char *filePath);
CheatSystemError SaveToFile(const char *filePath);
bool IsItemDuplicate(const ClientCheatItem *srcItem);
ClientCheatItem* AddNew();
ClientCheatItem* AddNewItemCopy(const ClientCheatItem *srcItem);
ClientCheatItem* AddNewItemCopyNoDuplicate(const ClientCheatItem *srcItem);
ClientCheatItem* AddExistingItemNoDuplicate(const ClientCheatItem *srcItem);
bool Remove(ClientCheatItem *targetItem);
bool RemoveAtIndex(size_t index);
void RemoveAll();
bool Update(const ClientCheatItem &srcItem, ClientCheatItem *targetItem);
bool UpdateAtIndex(const ClientCheatItem &srcItem, size_t index);
size_t GetTotalCheatCount() const;
size_t GetActiveCheatCount() const;
std::vector<ClientCheatItem *>* GetCheatList() const;
size_t GetIndexOfItem(const ClientCheatItem *cheatItem) const;
ClientCheatItem* GetItemAtIndex(size_t index) const;
void ReplaceFromEngine(const CHEATS *engineCheatList);
void CopyListToEngine(const bool willApplyOnlyEnabledItems, CHEATS *engineCheatList);
};
class ClientCheatSearcher
{
protected:
CHEATSEARCH *_desmumeSearcher;
uint8_t _searchValueLength;
size_t _resultsCount;
bool _didSearchStart;
DesmumeCheatSearchResultsList _resultsList;
public:
ClientCheatSearcher();
~ClientCheatSearcher();
bool DidStart() const;
void Reset();
size_t SearchExactValue(uint32_t value, uint8_t valueLength, bool performSignedSearch);
size_t SearchComparative(CheatSearchCompareStyle compareStyle, uint8_t valueLength, bool performSignedSearch);
const DesmumeCheatSearchResultsList& RefreshResults();
const DesmumeCheatSearchResultsList& GetResults();
size_t GetResultCount() const;
};
class ClientCheatDatabase
{
protected:
ClientCheatList *_list;
std::string _title;
std::string _description;
std::string _lastFilePath;
public:
ClientCheatDatabase();
~ClientCheatDatabase();
ClientCheatList* GetList() const;
ClientCheatList* LoadFromFile(const char *dbFilePath);
const char* GetTitle() const;
const char* GetDescription() const;
};
class ClientCheatManager
{
protected:
ClientCheatList *_currentSessionList;
ClientCheatDatabase *_currentDatabase;
ClientCheatSearcher *_currentSearcher;
ClientCheatItem *_selectedItem;
size_t _selectedItemIndex;
uint32_t _untitledCount;
std::string _currentSessionLastFilePath;
std::vector<InternalCheatParam> _pendingInternalCheatWriteList;
bool _masterNeedsUpdate;
public:
ClientCheatManager();
virtual ~ClientCheatManager();
static CHEATS* GetMaster();
static void SetMaster(const CHEATS *masterCheats);
ClientCheatList* GetSessionList() const;
const char* GetSessionListLastFilePath() const;
virtual CheatSystemError SessionListLoadFromFile(const char *filePath);
virtual CheatSystemError SessionListSaveToFile(const char *filePath);
ClientCheatItem* SetSelectedItemByIndex(size_t index);
ClientCheatItem* NewItem();
ClientCheatItem* AddExistingItemNoDuplicate(const ClientCheatItem *theItem);
void RemoveItem(ClientCheatItem *theItem);
void RemoveItemAtIndex(size_t index);
void RemoveSelectedItem();
void ModifyItem(const ClientCheatItem *srcItem, ClientCheatItem *targetItem);
void ModifyItemAtIndex(const ClientCheatItem *srcItem, size_t index);
size_t GetTotalCheatCount() const;
size_t GetActiveCheatCount() const;
void LoadFromMaster();
void ApplyToMaster();
void MasterNeedsUpdate();
ClientCheatList* GetDatabaseList() const;
ClientCheatList* DatabaseListLoadFromFile(const char *dbFilePath);
const char* GetDatabaseTitle() const;
const char* GetDatabaseDescription() const;
bool SearchDidStart() const;
void SearchReset();
size_t SearchExactValue(uint32_t value, uint8_t valueLength, bool performSignedSearch);
size_t SearchComparative(CheatSearchCompareStyle compareStyle, uint8_t valueLength, bool performSignedSearch);
const DesmumeCheatSearchResultsList& SearchResultsRefresh();
const DesmumeCheatSearchResultsList& GetSearchResults();
size_t GetSearchResultCount() const;
void DirectWriteInternalCheatAtIndex(size_t index);
void DirectWriteInternalCheatItem(const ClientCheatItem *cheatItem);
void DirectWriteInternalCheat(uint32_t targetAddress, uint32_t newValue32, size_t newValueLength);
void ApplyPendingInternalCheatWrites();
};
Thread Safety:
Assume that all methods are not thread-safe. This was done for performance
reasons. The caller of this class' methods is expected to handle thread safety.
********************************************************************************************/
@interface CocoaDSCheatItem : NSObject @interface CocoaDSCheatItem : NSObject
{ {
CHEATS_LIST *data; ClientCheatItem *_internalData;
CHEATS_LIST *internalData; BOOL _didAllocateInternalData;
BOOL _disableWorkingCopyUpdate;
BOOL willAdd; BOOL willAdd;
pthread_mutex_t mutexData;
CocoaDSCheatItem *workingCopy; CocoaDSCheatItem *workingCopy;
CocoaDSCheatItem *parent; CocoaDSCheatItem *parent;
BOOL _isMemAddressAlreadyUpdating;
} }
@property (assign) CHEATS_LIST *data; @property (readonly, nonatomic, getter=clientData) ClientCheatItem *_internalData;
@property (assign) BOOL willAdd; @property (assign) BOOL willAdd;
@property (assign, nonatomic) BOOL enabled; @property (assign, nonatomic) BOOL enabled;
@property (assign, nonatomic) NSInteger cheatType; @property (assign, nonatomic) NSInteger cheatType;
@ -64,17 +332,17 @@ class CHEATSEARCH;
@property (readonly) CocoaDSCheatItem *workingCopy; @property (readonly) CocoaDSCheatItem *workingCopy;
@property (assign) CocoaDSCheatItem *parent; @property (assign) CocoaDSCheatItem *parent;
- (id) initWithCheatData:(CHEATS_LIST *)cheatData; - (id) initWithCocoaCheatItem:(CocoaDSCheatItem *)cdsCheatItem;
- (BOOL) retainData; - (id) initWithCheatItem:(ClientCheatItem *)cheatItem;
- (id) initWithCheatData:(const CHEATS_LIST *)cheatData;
- (char *) descriptionCString; - (char *) descriptionCString;
- (void) update; - (void) update;
- (CocoaDSCheatItem *) createWorkingCopy; - (CocoaDSCheatItem *) createWorkingCopy;
- (void) destroyWorkingCopy; - (void) destroyWorkingCopy;
- (void) mergeFromWorkingCopy;
- (void) mergeToParent; - (void) mergeToParent;
- (void) setDataWithDictionary:(NSDictionary *)dataDict;
- (NSDictionary *) dataDictionary;
+ (void) setIconDirectory:(NSImage *)iconImage;
+ (NSImage *) iconDirectory;
+ (void) setIconInternalCheat:(NSImage *)iconImage; + (void) setIconInternalCheat:(NSImage *)iconImage;
+ (NSImage *) iconInternalCheat; + (NSImage *) iconInternalCheat;
+ (void) setIconActionReplay:(NSImage *)iconImage; + (void) setIconActionReplay:(NSImage *)iconImage;
@ -84,92 +352,116 @@ class CHEATSEARCH;
@end @end
/******************************************************************************************** @interface CocoaDSCheatDBEntry : NSObject
CocoaDSCheatManager - OBJECTIVE-C CLASS {
CheatDBEntry *_dbEntry;
CocoaDSCheatDBEntry *parent;
NSMutableArray *child;
NSInteger willAdd;
NSString *codeString;
BOOL needSetMixedState;
}
This is an Objective-C wrapper class for DeSmuME's cheat list class. @property (readonly, nonatomic) NSString *name;
@property (readonly, nonatomic) NSString *comment;
@property (readonly, nonatomic) NSImage *icon;
@property (readonly, nonatomic) NSInteger entryCount;
@property (readonly, nonatomic) NSString *codeString;
@property (readonly, nonatomic) BOOL isDirectory;
@property (readonly, nonatomic) BOOL isCheatItem;
@property (assign) NSInteger willAdd;
@property (assign) BOOL needSetMixedState;
@property (assign) CocoaDSCheatDBEntry *parent;
@property (readonly, nonatomic) NSMutableArray *child;
- (id) initWithDBEntry:(const CheatDBEntry *)dbEntry;
- (ClientCheatItem *) newClientItem;
@end
@interface CocoaDSCheatDBGame : NSObject
{
CheatDBGame *_dbGame;
CocoaDSCheatDBEntry *entryRoot;
NSUInteger index;
}
@property (assign) NSUInteger index;
@property (readonly, nonatomic) NSString *title;
@property (readonly, nonatomic) NSString *serial;
@property (readonly, nonatomic) NSUInteger crc;
@property (readonly, nonatomic) NSString *crcString;
@property (readonly, nonatomic) NSInteger dataSize;
@property (readonly, nonatomic) NSString *dataSizeString;
@property (readonly, nonatomic) BOOL isDataLoaded;
@property (readonly, nonatomic) NSInteger cheatItemCount;
@property (readonly, nonatomic) CocoaDSCheatDBEntry *entryRoot;
- (id) initWithGameEntry:(const CheatDBGame *)gameEntry;
- (CocoaDSCheatDBEntry *) loadEntryDataFromFilePtr:(FILE *)fp isEncrypted:(BOOL)isEncrypted;
@end
@interface CocoaDSCheatDatabase : NSObject
{
CheatDBFile *_dbFile;
CheatDBGameList *_dbGameList;
NSMutableArray *gameList;
NSURL *lastFileURL;
}
@property (readonly) NSURL *lastFileURL;
@property (readonly, nonatomic) NSString *description;
@property (readonly, nonatomic) NSString *formatString;
@property (readonly, nonatomic) BOOL isEncrypted;
@property (readonly) NSMutableArray *gameList;
- (id) initWithFileURL:(NSURL *)fileURL error:(CheatSystemError *)errorCode;
- (CocoaDSCheatDBGame *) getGameEntryUsingCode:(const char *)gameCode crc:(NSUInteger)crc;
- (CocoaDSCheatDBEntry *) loadGameEntry:(CocoaDSCheatDBGame *)dbGame;
@end
Thread Safety:
All methods are thread-safe.
********************************************************************************************/
@interface CocoaDSCheatManager : NSObject @interface CocoaDSCheatManager : NSObject
{ {
CHEATS *listData; ClientCheatManager *_internalCheatManager;
NSMutableArray *list; NSMutableArray *sessionList;
NSMutableArray *searchResultsList;
pthread_rwlock_t *rwlockCoreExecute; pthread_rwlock_t *rwlockCoreExecute;
BOOL isUsingDummyRWlock;
NSUInteger untitledCount;
NSString *dbTitle;
NSString *dbDate;
} }
@property (readonly) CHEATS *listData; @property (readonly, nonatomic, getter=internalManager) ClientCheatManager *_internalCheatManager;
@property (readonly) NSMutableArray *list; @property (readonly) NSMutableArray *sessionList;
@property (assign) pthread_rwlock_t *rwlockCoreExecute; @property (readonly, nonatomic) NSString *currentGameCode;
@property (assign) NSUInteger untitledCount; @property (readonly, nonatomic) NSUInteger currentGameCRC;
@property (copy) NSString *dbTitle; @property (readonly, nonatomic) NSUInteger itemTotalCount;
@property (copy) NSString *dbDate; @property (readonly, nonatomic) NSUInteger itemActiveCount;
@property (readonly) NSMutableArray *searchResultsList;
@property (readonly, nonatomic) BOOL searchDidStart;
@property (readonly, nonatomic) NSUInteger searchCount;
@property (assign, nonatomic) pthread_rwlock_t *rwlockCoreExecute;
- (id) initWithFileURL:(NSURL *)fileURL; - (id) initWithFileURL:(NSURL *)fileURL;
- (id) initWithListData:(CHEATS *)cheatList;
- (id) initWithFileURL:(NSURL *)fileURL listData:(CHEATS *)cheatList;
- (BOOL) add:(CocoaDSCheatItem *)cheatItem; - (CocoaDSCheatItem *) newItem;
- (void) remove:(CocoaDSCheatItem *)cheatItem; - (CocoaDSCheatItem *) addExistingItem:(ClientCheatItem *)cheatItem;
- (BOOL) update:(CocoaDSCheatItem *)cheatItem; - (CocoaDSCheatItem *) addExistingCocoaItem:(CocoaDSCheatItem *)cocoaCheatItem;
- (void) remove:(CocoaDSCheatItem *)cocoaCheatItem;
- (void) removeAtIndex:(NSUInteger)itemIndex;
- (BOOL) update:(CocoaDSCheatItem *)cocoaCheatItem;
- (BOOL) save; - (BOOL) save;
- (NSUInteger) activeCount; - (void) directWriteInternalCheat:(CocoaDSCheatItem *)cocoaCheatItem;
- (NSMutableArray *) cheatListFromDatabase:(NSURL *)fileURL errorCode:(NSInteger *)error; - (void) loadFromMaster;
- (void) applyInternalCheat:(CocoaDSCheatItem *)cheatItem; - (void) applyToMaster;
+ (void) setMasterCheatList:(CocoaDSCheatManager *)cheatListManager; - (NSUInteger) databaseAddSelectedInEntry:(CocoaDSCheatDBEntry *)theEntry;
+ (void) applyInternalCheatWithItem:(CocoaDSCheatItem *)cheatItem;
+ (void) applyInternalCheatWithAddress:(UInt32)address value:(UInt32)value bytes:(NSUInteger)bytes;
+ (NSMutableArray *) cheatListWithListObject:(CHEATS *)cheatList;
+ (NSMutableArray *) cheatListWithItemStructArray:(CHEATS_LIST *)cheatItemArray count:(NSUInteger)itemCount;
+ (NSMutableDictionary *) cheatItemWithType:(NSInteger)cheatTypeID description:(NSString *)description;
@end
@interface CocoaDSCheatSearch : NSObject
{
CHEATSEARCH *listData;
NSMutableArray *addressList;
pthread_rwlock_t *rwlockCoreExecute;
BOOL isUsingDummyRWlock;
NSUInteger searchCount;
}
@property (readonly) CHEATSEARCH *listData;
@property (readonly) NSMutableArray *addressList;
@property (assign) pthread_rwlock_t *rwlockCoreExecute;
@property (readonly) NSUInteger searchCount;
- (NSUInteger) runExactValueSearch:(NSInteger)value byteSize:(UInt8)byteSize signType:(NSInteger)signType; - (NSUInteger) runExactValueSearch:(NSInteger)value byteSize:(UInt8)byteSize signType:(NSInteger)signType;
- (void) runExactValueSearchOnThread:(id)object;
- (NSUInteger) runComparativeSearch:(NSInteger)typeID byteSize:(UInt8)byteSize signType:(NSInteger)signType; - (NSUInteger) runComparativeSearch:(NSInteger)typeID byteSize:(UInt8)byteSize signType:(NSInteger)signType;
- (void) runComparativeSearchOnThread:(id)object; - (void) searchReset;
- (void) reset;
+ (NSMutableArray *) addressListWithListObject:(CHEATSEARCH *)addressList maxItems:(NSUInteger)maxItemCount;
@end
@interface CocoaDSCheatSearchParams : NSObject
{
NSInteger comparativeSearchType;
NSInteger value;
UInt8 byteSize;
NSInteger signType;
}
@property (assign) NSInteger comparativeSearchType;
@property (assign) NSInteger value;
@property (assign) UInt8 byteSize;
@property (assign) NSInteger signType;
@end @end

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@ class ClientExecutionControl;
@class CocoaDSFirmware; @class CocoaDSFirmware;
@class CocoaDSGPU; @class CocoaDSGPU;
@class CocoaDSOutput; @class CocoaDSOutput;
@class CocoaDSCheatManager;
typedef struct typedef struct
{ {
@ -48,6 +49,7 @@ typedef struct
CocoaDSController *cdsController; CocoaDSController *cdsController;
CocoaDSFirmware *cdsFirmware; CocoaDSFirmware *cdsFirmware;
CocoaDSGPU *cdsGPU; CocoaDSGPU *cdsGPU;
CocoaDSCheatManager *cdsCheatManager;
NSMutableArray *cdsOutputList; NSMutableArray *cdsOutputList;
pthread_t coreThread; pthread_t coreThread;
@ -72,6 +74,7 @@ typedef struct
@property (retain) CocoaDSFirmware *cdsFirmware; @property (retain) CocoaDSFirmware *cdsFirmware;
@property (readonly) CocoaDSController *cdsController; @property (readonly) CocoaDSController *cdsController;
@property (readonly) CocoaDSGPU *cdsGPU; @property (readonly) CocoaDSGPU *cdsGPU;
@property (readonly) CocoaDSCheatManager *cdsCheatManager;
@property (readonly) NSMutableArray *cdsOutputList; @property (readonly) NSMutableArray *cdsOutputList;
@property (assign) BOOL masterExecute; @property (assign) BOOL masterExecute;

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2011 Roger Manuel Copyright (C) 2011 Roger Manuel
Copyright (C) 2011-2022 DeSmuME team Copyright (C) 2011-2023 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -20,6 +20,7 @@
#import "cocoa_input.h" #import "cocoa_input.h"
#import "cocoa_firmware.h" #import "cocoa_firmware.h"
#import "cocoa_GPU.h" #import "cocoa_GPU.h"
#import "cocoa_cheat.h"
#import "cocoa_globals.h" #import "cocoa_globals.h"
#import "cocoa_output.h" #import "cocoa_output.h"
#import "cocoa_rom.h" #import "cocoa_rom.h"
@ -48,6 +49,7 @@ volatile bool execute = true;
@synthesize cdsFirmware; @synthesize cdsFirmware;
@synthesize cdsController; @synthesize cdsController;
@synthesize cdsGPU; @synthesize cdsGPU;
@synthesize cdsCheatManager;
@synthesize cdsOutputList; @synthesize cdsOutputList;
@dynamic masterExecute; @dynamic masterExecute;
@ -122,6 +124,7 @@ volatile bool execute = true;
cdsFirmware = nil; cdsFirmware = nil;
cdsController = [[CocoaDSController alloc] init]; cdsController = [[CocoaDSController alloc] init];
cdsGPU = [[CocoaDSGPU alloc] init]; cdsGPU = [[CocoaDSGPU alloc] init];
cdsCheatManager = [[CocoaDSCheatManager alloc] init];
cdsOutputList = [[NSMutableArray alloc] initWithCapacity:32]; cdsOutputList = [[NSMutableArray alloc] initWithCapacity:32];
ClientInputHandler *inputHandler = [cdsController inputHandler]; ClientInputHandler *inputHandler = [cdsController inputHandler];
@ -164,10 +167,11 @@ volatile bool execute = true;
pthread_attr_destroy(&threadAttr); pthread_attr_destroy(&threadAttr);
[cdsGPU setOutputList:cdsOutputList rwlock:&threadParam.rwlockOutputList]; [cdsGPU setOutputList:cdsOutputList rwlock:&threadParam.rwlockOutputList];
[cdsCheatManager setRwlockCoreExecute:&threadParam.rwlockCoreExecute];
macOS_driver *newDriver = new macOS_driver; macOS_driver *newDriver = new macOS_driver;
newDriver->SetCoreThreadMutexLock(&threadParam.mutexThreadExecute); newDriver->SetCoreThreadMutexLock(&threadParam.mutexThreadExecute);
newDriver->SetCoreExecuteRWLock(self.rwlockCoreExecute); newDriver->SetCoreExecuteRWLock(&threadParam.rwlockCoreExecute);
newDriver->SetExecutionControl(execControl); newDriver->SetExecutionControl(execControl);
driver = newDriver; driver = newDriver;
@ -603,7 +607,7 @@ volatile bool execute = true;
execControl->SetExecutionBehavior((ExecutionBehavior)coreState); execControl->SetExecutionBehavior((ExecutionBehavior)coreState);
pthread_rwlock_rdlock(&threadParam.rwlockOutputList); pthread_rwlock_rdlock(&threadParam.rwlockOutputList);
char frameStatusCStr[128] = {0}; char frameStatusCStr[64] = {0};
switch ((ExecutionBehavior)coreState) switch ((ExecutionBehavior)coreState)
{ {
@ -614,7 +618,7 @@ volatile bool execute = true;
[cdsOutput setIdle:YES]; [cdsOutput setIdle:YES];
} }
sprintf(frameStatusCStr, "%llu", (unsigned long long)[self frameNumber]); snprintf(frameStatusCStr, sizeof(frameStatusCStr), "%llu", (unsigned long long)[self frameNumber]);
[_fpsTimer invalidate]; [_fpsTimer invalidate];
_fpsTimer = nil; _fpsTimer = nil;
@ -628,7 +632,7 @@ volatile bool execute = true;
[cdsOutput setIdle:NO]; [cdsOutput setIdle:NO];
} }
sprintf(frameStatusCStr, "%llu", (unsigned long long)[self frameNumber]); snprintf(frameStatusCStr, sizeof(frameStatusCStr), "%llu", (unsigned long long)[self frameNumber]);
[_fpsTimer invalidate]; [_fpsTimer invalidate];
_fpsTimer = nil; _fpsTimer = nil;
@ -642,7 +646,7 @@ volatile bool execute = true;
[cdsOutput setIdle:NO]; [cdsOutput setIdle:NO];
} }
sprintf(frameStatusCStr, "%s", "Executing..."); snprintf(frameStatusCStr, sizeof(frameStatusCStr), "%s", "Executing...");
if (_fpsTimer == nil) if (_fpsTimer == nil)
{ {
@ -668,7 +672,7 @@ volatile bool execute = true;
} }
} }
sprintf(frameStatusCStr, "Jumping to frame %llu.", (unsigned long long)execControl->GetFrameJumpTarget()); snprintf(frameStatusCStr, sizeof(frameStatusCStr), "Jumping to frame %llu.", (unsigned long long)execControl->GetFrameJumpTarget());
[_fpsTimer invalidate]; [_fpsTimer invalidate];
_fpsTimer = nil; _fpsTimer = nil;
@ -724,50 +728,42 @@ volatile bool execute = true;
- (void) setArm9ImageURL:(NSURL *)fileURL - (void) setArm9ImageURL:(NSURL *)fileURL
{ {
const char *filePath = (fileURL != NULL) ? [[fileURL path] cStringUsingEncoding:NSUTF8StringEncoding] : NULL; execControl->SetARM9ImagePath([CocoaDSUtil cPathFromFileURL:fileURL]);
execControl->SetARM9ImagePath(filePath);
} }
- (NSURL *) arm9ImageURL - (NSURL *) arm9ImageURL
{ {
const char *filePath = execControl->GetARM9ImagePath(); return [CocoaDSUtil fileURLFromCPath:execControl->GetARM9ImagePath()];
return [NSURL fileURLWithPath:[NSString stringWithCString:filePath encoding:NSUTF8StringEncoding]];
} }
- (void) setArm7ImageURL:(NSURL *)fileURL - (void) setArm7ImageURL:(NSURL *)fileURL
{ {
const char *filePath = (fileURL != NULL) ? [[fileURL path] cStringUsingEncoding:NSUTF8StringEncoding] : NULL; execControl->SetARM7ImagePath([CocoaDSUtil cPathFromFileURL:fileURL]);
execControl->SetARM7ImagePath(filePath);
} }
- (NSURL *) arm7ImageURL - (NSURL *) arm7ImageURL
{ {
const char *filePath = execControl->GetARM7ImagePath(); return [CocoaDSUtil fileURLFromCPath:execControl->GetARM7ImagePath()];
return [NSURL fileURLWithPath:[NSString stringWithCString:filePath encoding:NSUTF8StringEncoding]];
} }
- (void) setFirmwareImageURL:(NSURL *)fileURL - (void) setFirmwareImageURL:(NSURL *)fileURL
{ {
const char *filePath = (fileURL != NULL) ? [[fileURL path] cStringUsingEncoding:NSUTF8StringEncoding] : NULL; execControl->SetFirmwareImagePath([CocoaDSUtil cPathFromFileURL:fileURL]);
execControl->SetFirmwareImagePath(filePath);
} }
- (NSURL *) firmwareImageURL - (NSURL *) firmwareImageURL
{ {
const char *filePath = execControl->GetFirmwareImagePath(); return [CocoaDSUtil fileURLFromCPath:execControl->GetFirmwareImagePath()];
return [NSURL fileURLWithPath:[NSString stringWithCString:filePath encoding:NSUTF8StringEncoding]];
} }
- (void) setSlot1R4URL:(NSURL *)fileURL - (void) setSlot1R4URL:(NSURL *)fileURL
{ {
const char *filePath = (fileURL != NULL) ? [[fileURL path] cStringUsingEncoding:NSUTF8StringEncoding] : NULL; execControl->SetSlot1R4Path([CocoaDSUtil cPathFromFileURL:fileURL]);
execControl->SetSlot1R4Path(filePath);
} }
- (NSURL *) slot1R4URL - (NSURL *) slot1R4URL
{ {
const char *filePath = execControl->GetSlot1R4Path(); return [CocoaDSUtil fileURLFromCPath:execControl->GetSlot1R4Path()];
return [NSURL fileURLWithPath:[NSString stringWithCString:filePath encoding:NSUTF8StringEncoding]];
} }
- (void) updateFirmwareMACAddressString - (void) updateFirmwareMACAddressString
@ -996,8 +992,9 @@ volatile bool execute = true;
return NO; return NO;
} }
std::string sramPath = (sramURL != nil) ? [[sramURL path] cStringUsingEncoding:NSUTF8StringEncoding] : ""; const char *cSramPath = [CocoaDSUtil cPathFromFileURL:sramURL];
const char *fileName = [[fileURL path] cStringUsingEncoding:NSUTF8StringEncoding]; std::string sramPath = (cSramPath != NULL) ? std::string(cSramPath) : "";
const char *fileName = [CocoaDSUtil cPathFromFileURL:fileURL];
NSDateFormatter *df = [[NSDateFormatter alloc] init]; NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"Y M d H m s SSS"]; [df setDateFormat:@"Y M d H m s SSS"];
@ -1155,6 +1152,7 @@ static void* RunCoreThread(void *arg)
CoreThreadParam *param = (CoreThreadParam *)arg; CoreThreadParam *param = (CoreThreadParam *)arg;
CocoaDSCore *cdsCore = (CocoaDSCore *)param->cdsCore; CocoaDSCore *cdsCore = (CocoaDSCore *)param->cdsCore;
CocoaDSGPU *cdsGPU = [cdsCore cdsGPU]; CocoaDSGPU *cdsGPU = [cdsCore cdsGPU];
ClientCheatManager *cheatManager = [[cdsCore cdsCheatManager] internalManager];
ClientExecutionControl *execControl = [cdsCore execControl]; ClientExecutionControl *execControl = [cdsCore execControl];
ClientInputHandler *inputHandler = execControl->GetClientInputHandler(); ClientInputHandler *inputHandler = execControl->GetClientInputHandler();
NSMutableArray *cdsOutputList = [cdsCore cdsOutputList]; NSMutableArray *cdsOutputList = [cdsCore cdsOutputList];
@ -1235,6 +1233,8 @@ static void* RunCoreThread(void *arg)
// Execute the frame and increment the frame counter. // Execute the frame and increment the frame counter.
pthread_rwlock_wrlock(&param->rwlockCoreExecute); pthread_rwlock_wrlock(&param->rwlockCoreExecute);
cheatManager->ApplyToMaster();
cheatManager->ApplyPendingInternalCheatWrites();
NDS_exec<false>(); NDS_exec<false>();
SPU_Emulate_user(); SPU_Emulate_user();
execControl->FetchOutputPostNDSExec(); execControl->FetchOutputPostNDSExec();

View File

@ -142,7 +142,7 @@ static NSMutableDictionary *_gURLDictionary = nil;
return result; return result;
} }
const char *statePath = [[saveStateURL path] cStringUsingEncoding:NSUTF8StringEncoding]; const char *statePath = [CocoaDSUtil cPathFromFileURL:saveStateURL];
bool cResult = savestate_load(statePath); bool cResult = savestate_load(statePath);
if(cResult) if(cResult)
{ {
@ -161,7 +161,7 @@ static NSMutableDictionary *_gURLDictionary = nil;
return result; return result;
} }
const char *statePath = [[saveStateURL path] cStringUsingEncoding:NSUTF8StringEncoding]; const char *statePath = [CocoaDSUtil cPathFromFileURL:saveStateURL];
bool cResult = savestate_save(statePath); bool cResult = savestate_save(statePath);
if(cResult) if(cResult)
{ {
@ -180,7 +180,7 @@ static NSMutableDictionary *_gURLDictionary = nil;
return result; return result;
} }
const char *romPath = [[romURL path] cStringUsingEncoding:NSUTF8StringEncoding]; const char *romPath = [CocoaDSUtil cPathFromFileURL:romURL];
NSInteger resultCode = NDS_LoadROM(romPath, NULL, NULL); NSInteger resultCode = NDS_LoadROM(romPath, NULL, NULL);
if (resultCode > 0) if (resultCode > 0)
{ {
@ -199,7 +199,7 @@ static NSMutableDictionary *_gURLDictionary = nil;
return result; return result;
} }
const char *replayPath = [[replayURL path] cStringUsingEncoding:NSUTF8StringEncoding]; const char *replayPath = [CocoaDSUtil cPathFromFileURL:replayURL];
const char *resultCode = FCEUI_LoadMovie(replayPath, true, false, -1); const char *resultCode = FCEUI_LoadMovie(replayPath, true, false, -1);
if (resultCode == NULL) if (resultCode == NULL)
{ {
@ -212,7 +212,7 @@ static NSMutableDictionary *_gURLDictionary = nil;
+ (BOOL) importRomSave:(NSURL *)romSaveURL + (BOOL) importRomSave:(NSURL *)romSaveURL
{ {
BOOL result = NO; BOOL result = NO;
const char *romSavePath = [[romSaveURL path] cStringUsingEncoding:NSUTF8StringEncoding]; const char *romSavePath = [CocoaDSUtil cPathFromFileURL:romSaveURL];
NSInteger resultCode = MMU_new.backupDevice.importData(romSavePath, 0); NSInteger resultCode = MMU_new.backupDevice.importData(romSavePath, 0);
if (resultCode == 0) if (resultCode == 0)
@ -243,7 +243,7 @@ static NSMutableDictionary *_gURLDictionary = nil;
#endif #endif
case ROMSAVEFORMAT_NOGBA: case ROMSAVEFORMAT_NOGBA:
{ {
const char *destinationPath = [[[destinationURL path] stringByAppendingPathExtension:@FILE_EXT_ROM_SAVE_NOGBA] cStringUsingEncoding:NSUTF8StringEncoding]; const char *destinationPath = [CocoaDSUtil cPathFromFilePath:[[destinationURL path] stringByAppendingPathExtension:@FILE_EXT_ROM_SAVE_NOGBA]];
bool resultCode = MMU_new.backupDevice.exportData(destinationPath); bool resultCode = MMU_new.backupDevice.exportData(destinationPath);
if (resultCode) if (resultCode)
{ {
@ -254,7 +254,7 @@ static NSMutableDictionary *_gURLDictionary = nil;
case ROMSAVEFORMAT_RAW: case ROMSAVEFORMAT_RAW:
{ {
const char *destinationPath = [[[destinationURL path] stringByAppendingPathExtension:@FILE_EXT_ROM_SAVE_RAW] cStringUsingEncoding:NSUTF8StringEncoding]; const char *destinationPath = [CocoaDSUtil cPathFromFilePath:[[destinationURL path] stringByAppendingPathExtension:@FILE_EXT_ROM_SAVE_RAW]];
bool resultCode = MMU_new.backupDevice.exportData(destinationPath); bool resultCode = MMU_new.backupDevice.exportData(destinationPath);
if (resultCode) if (resultCode)
{ {
@ -358,55 +358,55 @@ static NSMutableDictionary *_gURLDictionary = nil;
NSURL *romURL = [CocoaDSFile directoryURLByKind:@"ROM" version:versionString port:portString]; NSURL *romURL = [CocoaDSFile directoryURLByKind:@"ROM" version:versionString port:portString];
if (romURL != nil) if (romURL != nil)
{ {
strlcpy(path.pathToRoms, [[romURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToRoms, [CocoaDSUtil cPathFromFileURL:romURL], MAX_PATH);
} }
NSURL *romSaveURL = [CocoaDSFile directoryURLByKind:@"ROM Save" version:versionString port:portString]; NSURL *romSaveURL = [CocoaDSFile directoryURLByKind:@"ROM Save" version:versionString port:portString];
if (romSaveURL != nil) if (romSaveURL != nil)
{ {
strlcpy(path.pathToBattery, [[romSaveURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToBattery, [CocoaDSUtil cPathFromFileURL:romSaveURL], MAX_PATH);
} }
NSURL *saveStateURL = [CocoaDSFile directoryURLByKind:@"Save State" version:versionString port:portString]; NSURL *saveStateURL = [CocoaDSFile directoryURLByKind:@"Save State" version:versionString port:portString];
if (saveStateURL != nil) if (saveStateURL != nil)
{ {
strlcpy(path.pathToStates, [[saveStateURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToStates, [CocoaDSUtil cPathFromFileURL:saveStateURL], MAX_PATH);
} }
NSURL *screenshotURL = [CocoaDSFile directoryURLByKind:@"Screenshot" version:versionString port:portString]; NSURL *screenshotURL = [CocoaDSFile directoryURLByKind:@"Screenshot" version:versionString port:portString];
if (screenshotURL != nil) if (screenshotURL != nil)
{ {
strlcpy(path.pathToScreenshots, [[screenshotURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToScreenshots, [CocoaDSUtil cPathFromFileURL:screenshotURL], MAX_PATH);
} }
NSURL *aviURL = [CocoaDSFile directoryURLByKind:@"Video" version:versionString port:portString]; NSURL *aviURL = [CocoaDSFile directoryURLByKind:@"Video" version:versionString port:portString];
if (aviURL != nil) if (aviURL != nil)
{ {
strlcpy(path.pathToAviFiles, [[aviURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToAviFiles, [CocoaDSUtil cPathFromFileURL:aviURL], MAX_PATH);
} }
NSURL *cheatURL = [CocoaDSFile directoryURLByKind:@"Cheat" version:versionString port:portString]; NSURL *cheatURL = [CocoaDSFile directoryURLByKind:@"Cheat" version:versionString port:portString];
if (cheatURL != nil) if (cheatURL != nil)
{ {
strlcpy(path.pathToCheats, [[cheatURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToCheats, [CocoaDSUtil cPathFromFileURL:cheatURL], MAX_PATH);
} }
NSURL *soundSamplesURL = [CocoaDSFile directoryURLByKind:@"Sound Sample" version:versionString port:portString]; NSURL *soundSamplesURL = [CocoaDSFile directoryURLByKind:@"Sound Sample" version:versionString port:portString];
if (soundSamplesURL != nil) if (soundSamplesURL != nil)
{ {
strlcpy(path.pathToSounds, [[soundSamplesURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToSounds, [CocoaDSUtil cPathFromFileURL:soundSamplesURL], MAX_PATH);
} }
NSURL *firmwareURL = [CocoaDSFile directoryURLByKind:@"Firmware Configuration" version:versionString port:portString]; NSURL *firmwareURL = [CocoaDSFile directoryURLByKind:@"Firmware Configuration" version:versionString port:portString];
if (firmwareURL != nil) if (firmwareURL != nil)
{ {
strlcpy(path.pathToFirmware, [[firmwareURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToFirmware, [CocoaDSUtil cPathFromFileURL:firmwareURL], MAX_PATH);
} }
NSURL *luaURL = [CocoaDSFile directoryURLByKind:@"Lua Script" version:versionString port:portString]; NSURL *luaURL = [CocoaDSFile directoryURLByKind:@"Lua Script" version:versionString port:portString];
if (luaURL != nil) if (luaURL != nil)
{ {
strlcpy(path.pathToLua, [[luaURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToLua, [CocoaDSUtil cPathFromFileURL:luaURL], MAX_PATH);
} }
} }
@ -438,55 +438,55 @@ static NSMutableDictionary *_gURLDictionary = nil;
NSURL *romURL = (NSURL *)[URLDictionary valueForKey:@"ROM"]; NSURL *romURL = (NSURL *)[URLDictionary valueForKey:@"ROM"];
if (romURL != nil) if (romURL != nil)
{ {
strlcpy(path.pathToRoms, [[romURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToRoms, [CocoaDSUtil cPathFromFileURL:romURL], MAX_PATH);
} }
NSURL *romSaveURL = (NSURL *)[URLDictionary valueForKey:@"ROM Save"]; NSURL *romSaveURL = (NSURL *)[URLDictionary valueForKey:@"ROM Save"];
if (romSaveURL != nil) if (romSaveURL != nil)
{ {
strlcpy(path.pathToBattery, [[romSaveURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToBattery, [CocoaDSUtil cPathFromFileURL:romSaveURL], MAX_PATH);
} }
NSURL *saveStateURL = (NSURL *)[URLDictionary valueForKey:@"Save State"]; NSURL *saveStateURL = (NSURL *)[URLDictionary valueForKey:@"Save State"];
if (saveStateURL != nil) if (saveStateURL != nil)
{ {
strlcpy(path.pathToStates, [[saveStateURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToStates, [CocoaDSUtil cPathFromFileURL:saveStateURL], MAX_PATH);
} }
NSURL *screenshotURL = (NSURL *)[URLDictionary valueForKey:@"Screenshot"]; NSURL *screenshotURL = (NSURL *)[URLDictionary valueForKey:@"Screenshot"];
if (screenshotURL != nil) if (screenshotURL != nil)
{ {
strlcpy(path.pathToScreenshots, [[screenshotURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToScreenshots, [CocoaDSUtil cPathFromFileURL:screenshotURL], MAX_PATH);
} }
NSURL *aviURL = (NSURL *)[URLDictionary valueForKey:@"Video"]; NSURL *aviURL = (NSURL *)[URLDictionary valueForKey:@"Video"];
if (aviURL != nil) if (aviURL != nil)
{ {
strlcpy(path.pathToAviFiles, [[aviURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToAviFiles, [CocoaDSUtil cPathFromFileURL:aviURL], MAX_PATH);
} }
NSURL *cheatURL = (NSURL *)[URLDictionary valueForKey:@"Cheat"]; NSURL *cheatURL = (NSURL *)[URLDictionary valueForKey:@"Cheat"];
if (cheatURL != nil) if (cheatURL != nil)
{ {
strlcpy(path.pathToCheats, [[cheatURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToCheats, [CocoaDSUtil cPathFromFileURL:cheatURL], MAX_PATH);
} }
NSURL *soundSamplesURL = (NSURL *)[URLDictionary valueForKey:@"Sound Sample"]; NSURL *soundSamplesURL = (NSURL *)[URLDictionary valueForKey:@"Sound Sample"];
if (soundSamplesURL != nil) if (soundSamplesURL != nil)
{ {
strlcpy(path.pathToSounds, [[soundSamplesURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToSounds, [CocoaDSUtil cPathFromFileURL:soundSamplesURL], MAX_PATH);
} }
NSURL *firmwareURL = (NSURL *)[URLDictionary valueForKey:@"Firmware Configuration"]; NSURL *firmwareURL = (NSURL *)[URLDictionary valueForKey:@"Firmware Configuration"];
if (firmwareURL != nil) if (firmwareURL != nil)
{ {
strlcpy(path.pathToFirmware, [[firmwareURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToFirmware, [CocoaDSUtil cPathFromFileURL:firmwareURL], MAX_PATH);
} }
NSURL *luaURL = (NSURL *)[URLDictionary valueForKey:@"Lua Script"]; NSURL *luaURL = (NSURL *)[URLDictionary valueForKey:@"Lua Script"];
if (luaURL != nil) if (luaURL != nil)
{ {
strlcpy(path.pathToLua, [[luaURL path] cStringUsingEncoding:NSUTF8StringEncoding], MAX_PATH); strlcpy(path.pathToLua, [CocoaDSUtil cPathFromFileURL:luaURL], MAX_PATH);
} }
} }
@ -738,6 +738,14 @@ static NSMutableDictionary *_gURLDictionary = nil;
portStr = @"Cocoa"; portStr = @"Cocoa";
} }
versionURL = [CocoaDSFile userAppSupportURL:nil version:@"0.9.14"];
versionPath = [versionURL path];
if (versionPath != nil && [[[filePath stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] isEqualToString:versionPath])
{
versionStr = @"0.9.14";
portStr = @"Cocoa";
}
fileVersion = [[versionStr stringByAppendingString:@" "] stringByAppendingString:portStr]; fileVersion = [[versionStr stringByAppendingString:@" "] stringByAppendingString:portStr];
return fileVersion; return fileVersion;

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2011 Roger Manuel Copyright (C) 2011 Roger Manuel
Copyright (C) 2012-2022 DeSmuME team Copyright (C) 2012-2023 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -990,7 +990,7 @@ FirmwareConfigInterface::FirmwareConfigInterface()
_internalData = (FirmwareConfig *)malloc(sizeof(FirmwareConfig)); _internalData = (FirmwareConfig *)malloc(sizeof(FirmwareConfig));
NDS_GetDefaultFirmwareConfig(*_internalData); NDS_GetDefaultFirmwareConfig(*_internalData);
srand(time(NULL)); srand((uint32_t)time(NULL));
// Generate a random firmware MAC address and its associated string. // Generate a random firmware MAC address and its associated string.
const uint32_t defaultFirmwareMACAddressValue = (uint32_t)_internalData->MACAddress[2] | ((uint32_t)_internalData->MACAddress[3] << 8) | ((uint32_t)_internalData->MACAddress[4] << 16) | ((uint32_t)_internalData->MACAddress[5] << 24); const uint32_t defaultFirmwareMACAddressValue = (uint32_t)_internalData->MACAddress[2] | ((uint32_t)_internalData->MACAddress[3] << 8) | ((uint32_t)_internalData->MACAddress[4] << 16) | ((uint32_t)_internalData->MACAddress[5] << 24);

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2011 Roger Manuel Copyright (C) 2011 Roger Manuel
Copyright (C) 2012-2022 DeSmuME Team Copyright (C) 2012-2023 DeSmuME Team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -30,7 +30,7 @@
#define NSSTRING_TITLE_EXPORT_ROM_SAVE_PANEL NSLocalizedString(@"Export ROM Save File", nil) #define NSSTRING_TITLE_EXPORT_ROM_SAVE_PANEL NSLocalizedString(@"Export ROM Save File", nil)
#define NSSTRING_TITLE_SELECT_ROM_PANEL NSLocalizedString(@"Select ROM", nil) #define NSSTRING_TITLE_SELECT_ROM_PANEL NSLocalizedString(@"Select ROM", nil)
#define NSSTRING_TITLE_SELECT_ADVANSCENE_DB_PANEL NSLocalizedString(@"Select ADVANsCEne Database", nil) #define NSSTRING_TITLE_SELECT_ADVANSCENE_DB_PANEL NSLocalizedString(@"Select ADVANsCEne Database", nil)
#define NSSTRING_TITLE_SELECT_R4_CHEAT_DB_PANEL NSLocalizedString(@"Select R4 Cheat Database", nil) #define NSSTRING_TITLE_OPEN_CHEAT_DB_PANEL NSLocalizedString(@"Open Cheat Database", nil)
#define NSSTRING_TITLE_SELECT_ARM7_IMAGE_PANEL NSLocalizedString(@"Select ARM7 BIOS Image", nil) #define NSSTRING_TITLE_SELECT_ARM7_IMAGE_PANEL NSLocalizedString(@"Select ARM7 BIOS Image", nil)
#define NSSTRING_TITLE_SELECT_ARM9_IMAGE_PANEL NSLocalizedString(@"Select ARM9 BIOS Image", nil) #define NSSTRING_TITLE_SELECT_ARM9_IMAGE_PANEL NSLocalizedString(@"Select ARM9 BIOS Image", nil)
#define NSSTRING_TITLE_SELECT_FIRMWARE_IMAGE_PANEL NSLocalizedString(@"Select Firmware Image", nil) #define NSSTRING_TITLE_SELECT_FIRMWARE_IMAGE_PANEL NSLocalizedString(@"Select Firmware Image", nil)
@ -46,8 +46,8 @@
#define NSSTRING_TITLE_ENABLE_SPEED_LIMIT NSLocalizedString(@"Enable Speed Limit", nil) #define NSSTRING_TITLE_ENABLE_SPEED_LIMIT NSLocalizedString(@"Enable Speed Limit", nil)
#define NSSTRING_TITLE_DISABLE_AUTO_FRAME_SKIP NSLocalizedString(@"Disable Auto Frame Skip", nil) #define NSSTRING_TITLE_DISABLE_AUTO_FRAME_SKIP NSLocalizedString(@"Disable Auto Frame Skip", nil)
#define NSSTRING_TITLE_ENABLE_AUTO_FRAME_SKIP NSLocalizedString(@"Enable Auto Frame Skip", nil) #define NSSTRING_TITLE_ENABLE_AUTO_FRAME_SKIP NSLocalizedString(@"Enable Auto Frame Skip", nil)
#define NSSTRING_TITLE_DISABLE_CHEATS NSLocalizedString(@"Disable Cheats", nil) #define NSSTRING_TITLE_DISABLE_CHEATS NSLocalizedString(@"Disable Cheat System", nil)
#define NSSTRING_TITLE_ENABLE_CHEATS NSLocalizedString(@"Enable Cheats", nil) #define NSSTRING_TITLE_ENABLE_CHEATS NSLocalizedString(@"Enable Cheat System", nil)
#define NSSTRING_TITLE_DISABLE_HUD NSLocalizedString(@"Disable HUD", nil) #define NSSTRING_TITLE_DISABLE_HUD NSLocalizedString(@"Disable HUD", nil)
#define NSSTRING_TITLE_ENABLE_HUD NSLocalizedString(@"Enable HUD", nil) #define NSSTRING_TITLE_ENABLE_HUD NSLocalizedString(@"Enable HUD", nil)
#define NSSTRING_TITLE_EXIT_FULL_SCREEN NSLocalizedString(@"Exit Full Screen", nil) #define NSSTRING_TITLE_EXIT_FULL_SCREEN NSLocalizedString(@"Exit Full Screen", nil)
@ -303,41 +303,12 @@ enum
SPU_SYNC_METHOD_P = 2 SPU_SYNC_METHOD_P = 2
}; };
enum
{
CHEAT_TYPE_INTERNAL = 0,
CHEAT_TYPE_ACTION_REPLAY = 1,
CHEAT_TYPE_CODE_BREAKER = 2
};
enum
{
CHEATSEARCH_SEARCHSTYLE_EXACT_VALUE = 0,
CHEATSEARCH_SEARCHSTYLE_COMPARATIVE = 1
};
enum
{
CHEATSEARCH_COMPARETYPE_GREATER_THAN = 0,
CHEATSEARCH_COMPARETYPE_LESSER_THAN = 1,
CHEATSEARCH_COMPARETYPE_EQUALS_TO = 2,
CHEATSEARCH_COMPARETYPE_NOT_EQUALS_TO = 3
};
enum enum
{ {
CHEATSEARCH_UNSIGNED = 0, CHEATSEARCH_UNSIGNED = 0,
CHEATSEARCH_SIGNED = 1 CHEATSEARCH_SIGNED = 1
}; };
enum
{
CHEATEXPORT_ERROR_FILE_NOT_FOUND = 1,
CHEATEXPORT_ERROR_WRONG_FILE_FORMAT = 2,
CHEATEXPORT_ERROR_SERIAL_NOT_FOUND = 3,
CHEATEXPORT_ERROR_EXPORT_FAILED = 4
};
/* /*
PORT MESSAGES PORT MESSAGES
*/ */

View File

@ -97,7 +97,7 @@ private:
public: public:
MacInputHandler(); MacInputHandler();
~MacInputHandler(); virtual ~MacInputHandler();
CocoaDSController* GetCocoaController(); CocoaDSController* GetCocoaController();
void SetCocoaController(CocoaDSController *theController); void SetCocoaController(CocoaDSController *theController);

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