libretro / supafaust

Unsupported SNES emulator for multicore ARM Cortex A7,A9,A15,A53 Linux platforms.
GNU General Public License v2.0
9 stars 12 forks source link

Core crashes on Windows #20

Closed bslenul closed 1 year ago

bslenul commented 1 year ago

The core crashes RetroArch as soon as you load a game on Windows since bcad5b4dd2c773731add384dd175897ebbf31104

Tried to get a GDB output but I just get "exited with code 03". The last few lines from logs:

[libretro INFO] Using module: snes_faust(Super Nintendo Entertainment System/Super Famicom) [libretro INFO] [libretro INFO] Renderer: Multi-threaded [libretro INFO] PAL: 0 [libretro INFO] PAL PPU Bit: 0 [libretro INFO] FrameBeginVBlank: 1 [libretro INFO] PPUThreadAffinity: 0x1

No crash on my Linux Mint VM however.

crashGG commented 1 year ago

Same as me. test with windows x86_64 build

anzz1 commented 1 year ago

"Unsupported SNES emulator for multicore ARM Cortex A7,A9,A15,A53 Linux platforms."

Correct me if I'm wrong, but I think the x86 version is called just SNES-Faust, while this Supafaust is specifically the ARM port of that. The x86 version of SNES-Faust can be found at the official website: https://mednafen.github.io/

There is also another x86-compatible SNES libretro core from mednafen here : https://github.com/libretro/beetle-bsnes-libretro

anzz1 commented 1 year ago

Regarding Windows in general though (not specific to this core):

Seeing gdb mentioned I assume that you tried to compile the core with GCC aka MinGW? Unfortuntaly GCC blows on Windows, so the first thing to do is to not use it.

MSVC is much more compatible, however the modern iterations insist on adding "stack protectors" and "security checks" all over your functions messing up the emulator code, while also making very hard to turn all of them off to get proper working code. You can confirm this by compiling pretty much anything and then opening that up in the disassembler and see all the added nonsense functions and extra code which wasn't there when you wrote it. This obviously messes up the delicate code and timings of such things like emulators and adds unnecessary performance penalties to any applications where performance is paramount.

/kernel helps, but isn't enough on its' own, as you also need to define your own entrypoint and also add bunch of other flags and configuration options to stop it from messing with your code.

Also they try to force you to link against the new UCRT, which sucks and again messes with the delicate emulator code, forcing you to employ tricks to get it to link against the regular msvcrt.dll. MinGW links to msvcrt.dll by default, no problem there, but on MSVC it's unnecessarily hard (and by the looks of it, intentionally so).

The best way to deal with all this is to throw away the CRT altogether if you can, as in this example project, but then you need to define any C standard functions used yourself which is cumbersome and isn't suitable for any larger codebases which lean heavily on C standard library, which is most of them.

I don't know what Microsoft is actually thinking, they had good products in the Windows 7 era but everything has been downhill after that (specifically talking about the first-party products like the Windows OS, not collaborations or acquisitions like OpenAI and GitHub where they have fared really well). Anyone who is on the business of selling operating systems, should focus on making development easier for their platform, and not harder. It's all ass-backwards.

bslenul commented 1 year ago

I'm way too noob at this stuff, I appreciate the reply but this is almost Chinese to me :D

But that made me want to look at this issue again (I don't really care about the core tbh, I'm just being curious :p ), I put some printf and compared some results between Windows and my Linux VM, I noticed some weird differences int the file path and file basename between the 2 OSes and I think I found the issue: it seems it's simply because of Windows path separators.

If I replace this line: https://github.com/libretro/supafaust/blob/75c658cce454e58ae04ea252f53a31c60d61548e/mednafen/VirtualFS.cpp#L42

with

const size_t final_ds = file_path.find_last_of('\\'); // in file_path

then the game loads properly.

Obviously that would break the core on Linux, etc. so I ended up with this fix: https://github.com/bslenul/supafaust/commit/fc0102481552f11f5b0d7327b173db15b61d5005

It seems to work fine, however I had to prevent the WIN32 define since it will then require win32-common.cpp/.h that were removed a while ago (83be5723a5fdeffdc13f1efebbc984a7ccd8c8d2) and I have no idea if this can cause issues. From my tests it works just fine (Windows 10, tested with a zipped rom, an unzipped one and in a path with symbols and Japanese characters):

image

but I'd like to be sure before submitting a PR...

edit: also tried MSU1 btw, seems to work fine as well:

image

edit2: heh, WIN32 wasn't defined previously when the core was still working on Windows, so I guess this is fine, PR sent.