Mesen - NES Emulator

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Sour
Posts: 891
Joined: Sun Feb 07, 2016 6:16 pm

Re: Mesen - NES Emulator

Post by Sour »

So, a shiny new macOS VM and a lot of "I have no idea what I'm doing on macOS" moments later, I got this:
mesenmacos.png
(this is mono 32-bit on macOS, running a native macOS build of Mesen)

Now, as a screenshot, it looks kinda nice. But in reality it's mostly unusable, and I don't think I can hope to fix it.

First off, Mono Winforms on macOS runs on Carbon, which is 32-bit only, so even if I were to make it work now, it will stop working in a year or 2 once macOS drops 32-bit support. So aside having to make a few small modifications to the code (2 files) to get it to build, I also had to manually build SDL2 to get the 32-bit version, and manually install mono (because brew only installed the 64-bit stuff, it looks like).

Beyond that, SDL currently crashes if I try to use the Mono window to display the video (which is why there's an extra window in the screenshot for video output). Mono WinForms in general appears to be pretty buggy (crashes that don't occur in Linux/Windows, a lot of refresh issues, esp. in the debugger window, etc.) - I'm not convinced that there are ways to fix all of these. A Cocoa port of the WinForms code is kind of being worked on, from what I could gather, which could potentially make WinForms work a lot better (and in 64-bits). But I'm not holding my breath on that one - it might be a long time before it's done (if ever), and even if it gets done, it might not fix the myriad of winforms issues.


Now, as for Wine on macOS:
-The DX11 build doesn't display anything, but it runs (Wine 3.0.2, installed with brew, with dotnet45 installed with winetricks).
-The 32-bit SDL build seems to work (the frame rate says 60 fps, but I'm only getting like 0.5fps, I'm hoping this is because it's a VM running without hardware acceleration for graphics, etc.)

The main debugger window is still slow, but the rest (trace logger, ppu viewer, etc.) seems to be working decently well. There is likely a specific thing about the debugger window that's causing it to be so slow under Wine, I'll have to try and figure that part out. Overall, it's much better than trying to run WinForms on Mono.
winemacos.png
(this is a windows build of Mesen running on Wine 3.0)

So, TLDR:
At the moment, I think the best way to run Mesen on macOS is probably Wine 3.0 (32-bit)+Windows build of Mesen that uses SDL instead of DirectX. There's probably something broken with your Wine 3 setup if the SDL build from yesterday doesn't launch properly on macOS.

I'm unsure why Mesen's DX11 usage doesn't seem to work properly in Wine - Mesen doesn't exactly do any advanced stuff, I'm essentially just displaying a texture on the screen and that's it. But I'm using the DirectX Toolkit for some stuff (for no good reason other than it was simpler that way when I first implemented this 4 years ago), so maybe there's something in there that Wine doesn't like. It might be simpler to just scrap the DX11 code and always use SDL, but I'm not sure SDL performs better than just using DX11/DirectSound directly on Windows (e.g in terms of audio latency, etc.)
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Mesen - NES Emulator

Post by Banshaku »

I kind of had a feeling that my wine 3.0 was not working as expected when I had issues with Winetricks not installing anything with the GUI but was working fine on linux. Now that completely confirms that I need to reinstall it. Sorry for all the troubles you went through. I will see if I can reinstall it tonight and figure out the cause. Usually I don't have any issues with brew so something must have gone wrong during the installation. I will try to re-install it.

As for DX11, I don't think that it's your code that is the issue, but more what lidnariq said about the state of DX11 inside wine 3. If you look at the logs when using wine 3, there are so many of them that seems like some quick workaround to make apps work that I'm not surprised about it :lol:

As for SDL, other emulators uses it and it's a pretty standard framework so if you can make it work then it would be a plus to be "free" of directx :) Or maybe there is an older version of the DirectX Toolkit that uses a older version of directx?

Thanks again for the test, we are getting closer to a workable version of mesen on mac. Once wine3 works fine on my computer I will let you know how is the performance compared to linux.

Edit:

answering my own question, there is no DirectX Toolkit for DX10. It was done for DX11 and now there seems to be one for DX12.

I don't know how much work it would requires but if we could select the rendender/sound as a setting then you could keep the DX11 version for people that prefer it on windows and other people could use the SDL one for mac, linux etc. But since I do not know your code base, it's hard to judge the effort to do so.

edit2:

I re-installed wine3 with brew and I have the same results. I rebooted the computer, just in case, but it did make a difference. So there is something wrong my current computer I don't know the cause. I will the investigate it later. The last one I tested is the one you built with SDL and linked to this thread. How I launched it:

Code: Select all

WINEARCH=win32 wine Mesen.exe
The current prefix is 32 bit and dotnet45 was installed in it.
Sour
Posts: 891
Joined: Sun Feb 07, 2016 6:16 pm

Re: Mesen - NES Emulator

Post by Sour »

Supporting both DirectX & SDL wouldn't be overly hard (though doing it properly, e.g by delay loading the DLLs, is something I have never done) - their use is limited to just 2 files. It's mostly having to embed the SDL DLL twice (32-bit & 64-bit) in the .exe that's a bit annoying, since it'll probably add another 1+mb to the filesize.

That's essentially how I run it on wine, too, though I only had a 32-bit prefix and nothing else installed. The VM I was using is macOS Sierra (not High Sierra), in case that could potentially be a factor. What error/crash do you get when trying to run it? Is there any sort of callback, or does wine just refuse to start the application at all?
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Mesen - NES Emulator

Post by Banshaku »

I was able to take the information just before going to work.

I'm using the latest version of macOS, which means High Sierra 10.13.6. There is a probability that something changed between them that could cause the error since I had issues like that in the past but for now unless I retry it on another partition with 10.13 and 10.12 I cannot say it is the cause.

I included the screenshots of the error and the backtrace. I will try to search if wine 3 has some issues with high sierra today.
Program_error.png
progam_error_details.png
Attachments
backtrace.txt
(20.74 KiB) Downloaded 85 times
Sour
Posts: 891
Joined: Sun Feb 07, 2016 6:16 pm

Re: Mesen - NES Emulator

Post by Sour »

Just spent some time trying to get Wine to load MSVC's PDB files, with no luck.
It would have made it far easier to figure this out if I could have known what function is causing an exception. As it is, it looks like Mesen's C++ core is throwing an exception somehow, but that's about all I can gather from the trace.

Not quite sure what else to suggest at this point - it could potentially be a real issue in my code that's only causing a crash in your particular setup (but it could very well be a Wine issue, too.)
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Mesen - NES Emulator

Post by Banshaku »

I did some quick research this morning and last year there was some issue with 10.13 with AFPS, the new file system. It was causing wine to fail but I do not know if this is still an issue.

One thing I could try would be to create another partition, re-install high sierra then test. If doesn't work, try sierra and test. If it only work in sierra then something is wrong with high sierra. But I don't think that I will have time to do those kind of tests for a while since I will be away for a week from home soon so maybe I will be able to test it next month, on my way back.
User avatar
B00daW
Posts: 586
Joined: Thu Jan 03, 2008 1:48 pm

Re: Mesen - NES Emulator

Post by B00daW »

Hey Sour,

Did some experimentation with the ultrasonic frequencies of the low timers for 2a03 and MMC5. Seems that your emulation of MMC5 ultrasonic frequencies is inaccurate and mimics the method that the 2a03 does by halting generation at 0x07. MMC5 generates tone until it reaches 0x00 and then it halts. You can hear the click shutting the generation off in the recorded example from hardware by ImATrackMan.

Linked is a test that starts generation of pulses for 2a0x (both channels) and MMC5 (both channels) at 0x0D and decreases the low timer values of the channels down to 0x00.

Seems a bit obscure, but I thought you might be interested. :) Also, I don't think the proper frequencies in other emulators for MMC5 ultrasonics are emulated properly. Hopefully the attached render helps with proper frequencies.

https://cdn.discordapp.com/attachments/ ... _tests.zip

(I attached this in the NESdev Discord channel.)
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Mesen - NES Emulator

Post by Pokun »

I just realized that the muting of the pulse channels under periods of $8 has to do with the sweep unit's behaviour. And as the MMC5 do not have a sweep unit it does work below $8 I guess? I don't know if emulating that behaviour is suitable for Mesen though.
User avatar
B00daW
Posts: 586
Joined: Thu Jan 03, 2008 1:48 pm

Re: Mesen - NES Emulator

Post by B00daW »

Not certain how it would have to do with the sweep register since the code is using direct writes to the timer. Mesen is emulating the behavior of the 2a0x pulses by stopping generation at >0x08 timer on both 2a0x and MMC5 pulse. MMC5 pulses do not stop generation >0x08. Dunno how emulation accuracy only relates to certain emulators.
Sour
Posts: 891
Joined: Sun Feb 07, 2016 6:16 pm

Re: Mesen - NES Emulator

Post by Sour »

Can't check right now, but if it doesn't work properly, it must be a silly mistake (e.g maybe a bug that was introduced due to refactoring, etc.)

Both the lack of sweep units & the fact that it doesn't get muted when the period is under 8 are supposed to be taken in consideration. There are even comments in the code for both of these: https://github.com/SourMesen/Mesen/blob ... Audio.h#L9

I'll take a look tonight.
Sour
Posts: 891
Joined: Sun Feb 07, 2016 6:16 pm

Re: Mesen - NES Emulator

Post by Sour »

I recorded a wav from your NSF at 96khz sample rate. Comparing the result in audacity, it seems to be working pretty decently, as far as I can tell:
mmc5.png
mmc5.png (10.69 KiB) Viewed 3148 times
(top is your recording, bottom is Mesen)

My guess is that you were probably at 44/48khz, or you had the NSF option to skip to the next track after 3 seconds of silence activated (which caused the track to loop during the portion of your test that doesn't use the MMC5 square channels)
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Mesen - NES Emulator

Post by Pokun »

B00daW wrote:Not certain how it would have to do with the sweep register since the code is using direct writes to the timer. Mesen is emulating the behavior of the 2a0x pulses by stopping generation at >0x08 timer on both 2a0x and MMC5 pulse. MMC5 pulses do not stop generation >0x08.
Me neither but it says so on the sweep page of the wiki:
https://wiki.nesdev.com/w/index.php/APU_Sweep wrote:If the current period is less than 8, the channel is also muted. This avoids sending harmonics in the hundreds of kHz through the audio path. This muting cannot be overridden because it is based on the current period.
It doesn't explicitly say that the channel is muted by the sweep unit, or how it is done though.
Dunno how emulation accuracy only relates to certain emulators.
Well Sour said himself that even though Mesen is aiming to be highly accurate, he still has to balance accuracy and performance.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Mesen - NES Emulator

Post by tepples »

Pokun wrote:it says so on the sweep page of the wiki:
https://wiki.nesdev.com/w/index.php/APU_Sweep wrote:If the current period is less than 8, the channel is also muted. This avoids sending harmonics in the hundreds of kHz through the audio path. This muting cannot be overridden because it is based on the current period.
It doesn't explicitly say that the channel is muted by the sweep unit, or how it is done though.
The first paragraph of the section states that the section is about two conditions that cause the sweep unit to mute the channel by outputting 0 instead of the channel's current volume.
Two conditions cause the '''sweep unit to mute the channel''': 0 is sent to the mixer instead of the current volume.
[...]
If at any time the target period is greater than $7FF, the channel is muted.
[...]
If the current period is less than 8, the channel is also muted.
I thought this would be clear enough to indicate these as the two conditions, but it appears it was not. I have changed it to use more repetitive language ("the sweep unit mutes the channel" in both cases) instead of judicious use of passive voice.
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Mesen - NES Emulator

Post by Pokun »

Thanks, that's what I thought but now there is no doubt. So it doesn't stop generation, it simply ignores the volume setting and sends volume 0 to the mixer.

So I guess the reason MMC5 pulse channels can produce ultrasonic sounds is simply because it has no sweep unit interfering with its volume value.
User avatar
B00daW
Posts: 586
Joined: Thu Jan 03, 2008 1:48 pm

Re: Mesen - NES Emulator

Post by B00daW »

I dunno... It looks like there is a "click" when MMC5 low timer is set to 0x00. That seems like it's stopping generation and doing something with volume?
Post Reply