Scorr / RetroUnity

Unity frontend for the libretro API.
GNU General Public License v3.0
41 stars 23 forks source link

MGBA Core not working? #10

Open JustMeDaFaq opened 5 years ago

JustMeDaFaq commented 5 years ago

Hi,

its said that the mgba core works, but it doesnt?

Any hint for what needs to be looked into, to make it work? (also other cores?)

ptrvg commented 5 years ago

mgba did not work for me either. I am able to load gba roms with vbam_libretro.dll. The screen flickers though. Snes9x works perfect.

I am mostly interested in getting mame arcade emulation working for my project. Unfortunately I am not able to correctly load a rom because bool ret = Libretro.RetroLoadGame(ref gameInfo); returns false. The rom path is correct so I must be missing something in the environment setup.

As a test to load another core I was able to load stella for atari2600 emulation. The game works, but I need to adapt the framebuffer to output to the screen correctly.

Have you tried to get more cores working?

JustMeDaFaq commented 5 years ago

@ptrvg got snes,gba,nes and gb/gbc working. Im currently debugging whats wrong with the mupen core in unity. Seems like Unity crashes when mupen uses libco to start a coroutine. Right now, im writing an workaround for it.

Can have a look at Mame Arcade Emulation at the weekend if it helps you

EDIT: Sorry for my bad english

ptrvg commented 5 years ago

@JustMeDaFaq I would love it if you could get Mame working. My Unity project is a port of my 3darcade emulator frontend to Unity that I started two weeks ago. So yeah Mame is the one I am after! See: 3darcade Unity , old one 3darcade

There are a few Mame cores. For performance reasons I would like to use mame2000. or mame2003. But any will do. I only succeeded to load a game with the default mame.libretro.dll core. But then it crashes on the first update call.

JustMeDaFaq commented 5 years ago

@JustMeDaFaq I would love it if you could get Mame working. My Unity project is a port of my 3darcade emulator frontend to Unity that I started two weeks ago. So yeah Mame is the one I am after! See: 3darcade Unity , old one 3darcade

@ptrvg Seems my idea for mupen64 core worked out well. At least, it boots the game. Need to test if its stable tho, time for Super Mario 64 ;)

Looks awesome your project, so Mame will be next! :)

ptrvg commented 5 years ago

@JustMeDaFaq Damn you work fast...have fun with Mario!

JustMeDaFaq commented 5 years ago

@JustMeDaFaq Damn you work fast...have fun with Mario!

@ptrvg

Worked the last two days on it, didnt wrote c code for a long time, so it took me a bit to get back into it ;D

Had a quick look at the Mame2003 core. Main issue seems to be also related to the libco library. But the workaround applied to mupen should work for the Mame2003 one too, i guess. And a minor Environment stuff. Hope that i get to work on Mame on Thursday, shouldnt take too long.

ptrvg commented 5 years ago

@JustMeDaFaq Big thanks for doing this! C# and in fact any c language are completely new to me. So figuring out the libretro.h implementation in LibretroWrapper.cs was and is a bit of a challenge for me ;)

Scorr commented 5 years ago

hey sorry bout that, I just checked and mgba doesn't work for me either. like ptrvg said, vbam_libretro does work if you need gba. I just pushed a potential fix for the flickering, let me know if it still happens.

I'd like to make this repo compatible with any libretro core but I haven't gotten to looking into it because I never got sound working properly on the cores that do load. that's been the main blocker and that's why this repo hasn't been updated much.

ptrvg commented 5 years ago

hey sorry bout that, I just checked and mgba doesn't work for me either. like ptrvg said, vbam_libretro does work if you need gba. I just pushed a potential fix for the flickering, let me know if it still happens.

I'd like to make this repo compatible with any libretro core but I haven't gotten to looking into it because I never got sound working properly on the cores that do load. that's been the main blocker and that's why this repo hasn't been updated much.

@Scorr Hi. I tested the new version a bit an for me it still has the flickering with vbam.

Yes it would be great if the repro could support more cores. From what I have read so far getting sound working properly is very difficult with libretro. Unfortunately I dont have the technical skills to be much of a help beside from testing.

JustMeDaFaq commented 5 years ago

@ptrvg @Scorr Which game did you try? 32 or 64bit version of the core? Tried pokemon firered, video isnt flickering for me.

ptrvg commented 5 years ago

@Scorr @JustMeDaFaq I tried super monkyball jr and Herg's Solitaire. That was with an older 32 bit core.

I now tried the latest cores directly downloaded from retroarch: vbam_libretro.dll crashes Unity for me with both games vba_next_libretro.dll works ok on both the old and new version of the repro with no flicker. All cores are 64bit.

So yeah my fault, I should have done more testing before reporting the flicker issue.

JustMeDaFaq commented 5 years ago

@ptrvg Got Mame2003 core working yesterday. Worke fawlessly on android, a bit buggy on windows tho. Il look at it tommorow! :)

ptrvg commented 5 years ago

@JustMeDaFaq Damn that is great news! Looking forwards seeing it in action. I will only be able to test the windows version. I have no android devices.

JustMeDaFaq commented 5 years ago

@ptrvg Had no luck getting it to work reliable. It randomly fails. Seems that nothing is missing but that its related to how unitys native function calling works. Have no idea if theres an solution for it.

Im thinking about to switch to unreal engine

ptrvg commented 5 years ago

@JustMeDaFaq Thanks a lot for trying. You have come much further than I did. Are you willing to share what you have got so far? I still like to see it.

New retro arcade neon uses libretro with the unreal engine. So yes it has been done before, so that should work for you. I don't know much about the unreal engine besides that it uses c++. That is a bit scary compared to Unity's c#. The only modern language I know well is Swift...

Scorr commented 5 years ago

I don't know what the issue could be but I don't think switching engine would be the solution (though maybe it randomly fixes the real issue whatever it is).

Unity does not do anything special for native function calling, and C# native function calling is generally pretty robust.

JustMeDaFaq commented 5 years ago

@ptrvg probably got it working more reliable. Il clean it up and give it to you when im back home later. You should test reliability tho

@Scorr From the information i gathered, theres definetly something in unitys mono runtime/jit compilation... i could be wrong tho. Il be glad if you could prove me wrong, have a look at the vbam core :)

ptrvg commented 5 years ago

Thanks, take your time! Of course, I'll test it inside my app. And if it goes well I'll send it to a few more people to test.

ptrvg commented 5 years ago

@JustMeDaFaq Hi. Have you made any further progress with mame support? I am still very interested in testing what you have so far!

JustMeDaFaq commented 5 years ago

@ptrvg sorry for not getting back to you! Just completetly forgot about IT, after figuring out whats the reason some cores dont work. Trying to get around it, tho, need to learn more about the stuff needed, not experienced enough. Probably takes a few weeks.

Tho, il make sure youre getting the mame one asap. Should work without problems (beside the controls, i was too lazy to include all Buttons, but that shouldnt bee too hard :) )

ptrvg commented 5 years ago

@JustMeDaFaq Dont worry, I forget things all the time ;) Yeah I already added better controller support and retro_unload_game to the wrapper. I also will closely look at the changes you made to learn more how this stuff actually works!

ptrvg commented 5 years ago

@JustMeDaFaq I hardly dare to ask, any updates?

Hokage3211 commented 4 years ago

How did you guys get the mupen64 core working? I seem to get a crash after it polls all the system variables, all the way up to pak4, and then it just crashes the editor. I've got Snes9x, quicknes, and mGBA working well, with stable sound for each, minus some crackling.

humbertodias commented 4 years ago

mgba core https://github.com/Scorr/RetroUnity/pull/20

Hokage3211 commented 3 years ago

@JustMeDaFaq @ptrvg are either of you around to explain why the mupen64 core wasn't working and what you did to get it to work?

JustMeDaFaq commented 3 years ago

@Hokage3211 Basically, the hardware render callback isnt implemented. See the environment function for that, it asks on those cores for RETRO_ENVIRONMENT_SET_HW_RENDER, when that is asked for in the environemnt callback, "data" is a struct of type retro_hw_render_callback, where you need to apply the proper things (added an example of such a function below, but written in c++) Also, the threat youre running it in must have a opengl context for obvious reasons. hwrendercallback environment

humbertodias commented 3 years ago

We are trying to implement the hr_render using GLFW here https://github.com/Skurdt/LibretroUnityFE/issues/5 Contributions are welcome ;) and basically all changes could be used here either.

Hokage3211 commented 3 years ago

@JustMeDaFaq Awesome, that makes sense so far, where and what are those get_current_framebuffers and get_proc_address implemented? Like how do I use what this callback gives me, or how do I set up the stuff to give the callback? This is what I got for my implementation of the hw callback stuff image

JustMeDaFaq commented 3 years ago

@Hokage3211 get_current_framebuffer -> Libretro uses it to get the pointer to the framebuffer you want to render to. That framebuffer has to be generated by yourself. See https://docs.gl/gl3/glGenFramebuffers (need a GL/GLES library for that) . A example for the "callback_get_current_framebuffer" callback is attached :) curFrame

get_proc_address->Helps libretro to make use of the actual opengl api. For egl thats like https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglGetProcAddress.xhtml , its almost completely similiar tho. That should be part of the OpenGL/GLES library of your choice :)

U dont realy use anything from that callback, but since it tells the Libretro Core which framebuffer it should render too, you can do all further things, whatever you want, with the rendered frame on the framebuffer you generated :)

Hokage3211 commented 3 years ago

Hm.. okay.. based on all this stuff including their examples it feels like I'm not gonna be able to contribute much if this isn't working to display to the in-unity screen stuff, I can't make heads or tails of the examples if they aren't already working to display on the in-unity screen. Unless I'm missing something on how to funnel the rendered stuff to the texture data?

JustMeDaFaq commented 3 years ago

@Hokage3211 Getting the texture beeing shown in Unity in the end is all plain OpenGL stuff. So youd definetly need to learn all the basics of it, yeah :)

Hokage3211 commented 3 years ago

Hm okay well I calmed down a little and looked over some more, used their example, and got openGL hooked up, and I think I'm properly passing the frame buffer, after making the opengl stuff, but it still crashes on game_load inside of the dll, so I can't see where, only that something was trying to access address 0 I think? They say themselves that they can't get this working, so seems like you remain the only person to get n64 working. I should probably get my version of this pushed as a proper repository so I'm not just rambling and asking for help, but any other ideas?

JustMeDaFaq commented 3 years ago

@Hokage3211 If it's on retro_load_game, it's could be tons of stuff. Switching to the emuthread via co_switch(libco)(that's what it internally does) could be a thing for example.

Otherwise, you not only called genframebuffer but created and initiliazed GL beforehand?

Best is if you could upload your project and I have a look while it's crashing in games load already :) I'm already lying in bed tho, late over here. So that would be tomorrow.

While I got it running, it's a very different approach I believe? Didn't had a look at that other project too much yet to be honest. Tho, i'm creating a separated thread. There everything basic like loading ROMs, retro_run etc gets called. More complicated stuff gets handled by an plugin written in c++. That threat is having a shared gl context, so I can pass things easily between unity and that thread. That's a short version, pretty incomplete, as said, lying in bed right now :)

Hokage3211 commented 3 years ago

Lol seems like we all have our own version of implementations, but yeah I'll work on uploading my thing properly to github, and then let you know in case you're curious on looking it over.

JustMeDaFaq commented 3 years ago

@Hokage3211 Yeah, I'd love to have a look, so feel free to tag me once you uploaded it :) And yeah, I started with that one here too tho, even if it completely changed over time. OpenGL cores where tricky, to be honest, I felt like dying several times while getting it lol. But once you have that stable running, you can run all of those OpenGL cores easily basically :) So that's worth it.

Skurdt commented 3 years ago

@JustMeDaFaq Any chance you could share how you got around the libco issues? The gl stuff seems to mostly work currently, but this lib seems to cause most of the other issues... Thanks

JustMeDaFaq commented 3 years ago

@Skurdt Only running it in main thread is officially supported. For that youd need https://docs.unity3d.com/ScriptReference/GL.IssuePluginEvent.html tho, which is a bit of clunky to run a perfectly timed emulator in it. It works tho. What i did was creating a completely new thread (in c++ tho, never tested creating one in c# and using that one), which only purpose is to run the emulator. That worked too.

I didnt looked at your project in depth, is the emulation process running in one of Unitys Threads? The only that works here is the Main one, as linked above, all other Unity related threads will definetly fail due to libco. Libco is pretty picky :S

Skurdt commented 3 years ago

The project I'm experimenting in is heavily modified from the git repo's source, iteration times are way too long there so I needed to have a more bare bones version ;) Looking at the repo won't really fix anything I think.

As far as I can tell, and I tried a million solutions for probably 10 hours straight this morning...., using a native plugin is the only way to initialize a proper framebuffer in a Unity render thread. So yeah I'm already using this way/function to do just that.

Currently the core and game loading is done in unity, then a call the core's callback->context_reset is performed inside the plugin (which allowed me to go further in the core's code). The core crashes further down the line in a call to co_switch, when trying to switch to the emu_thread (from whatever thread it was previously).

Interestingly (or not...), when not calling retro_run, there doesn't seem to be an error. The core starts, the game starts, then the context_reset succeed, along with all the debug messages. But calling run (even once, and not in a loop) it doesn't outright crash like previously, but just freezes the editor (only the task manager helps here :p). It freezes the editor without even letting it go into play mode (blue play button), which is kinda weird because all of the previous code does run properly but unity seems to just don't give a 💩 apparently. It runs stuff in whatever order it wants...

If I where to guess from there.... it's the co_switch function itself (it's implemented as a const array of hex values in the libretro code, for the path it takes on windows at least). And I'm starting to think Unity doesn't like that at all, but I'm just thinking out loud now.... :/

JustMeDaFaq commented 3 years ago

Could be very reasonable the co_switch. I remembered i debugged that alot back then to make sure its realy that. Tried doing retro_run within that native plugin? Doing it in another unity thread will definetly crash it

Any way off getting my hands on your project to have a look? :) I switched completely to c++ for that, found it to be easier than just trying to do that libretro api stuff in c#. But id like to have a look :)

Hokage3211 commented 3 years ago

@JustMeDaFaq Okay, think I got the project in a good state so people can easily import and check over it, here is the link for it: https://github.com/Hokage3211/RetroUnity/tree/testingN64emu Basically it's all done in the libretroWrapper.cs file, since for now I was going for function rather than form, but it's all there besides the input which is it's own separate file to override or change if a project had a different method. Basically my project you press play, and then press page up on your keyboard, which prompts you for the game rom, and then the core (you'll want these in streaming assets, since it opens up there), g is create save state, h is load save state, and the input is the same as here. J is unload game, which in theory allows you to then test another game without stopping. If you need fast-forward you can click the boolean on the game-manager script in-editor, since I hadn't hooked it up yet, just wanted testing.

Let me know anything you see to improve, as long as it makes it better in the sub-systems I'll accept it, cuz the more done there the more compatible this is with all cores.