- Joined
- Apr 29, 2011
- Messages
- 31,284
- Trophies
- 2
- Age
- 38
- Location
- Dr. Wahwee's castle
- XP
- 18,969
- Country
Oh, is RCM considered as a hardmod?
I guess no, so sorry for being wrong.
Oh, is RCM considered as a hardmod?
Oh wow!For what it’s worth, I’ve looked into implementing a libnx-based Retroarch driver. It doesn’t seem that difficult and I’ve written a first-go at it but I’m stuck in Makefile hell. I’m able to get all of the code to compile but the linking process fails. Libtransistor uses ar to link the library and uses the flag —allow-multiple-definitions (or something along those lines). Libnx uses gcc which lags that flag :/ I haven’t looked into it in a few days but I’ll at least try to get around to pushing the rough libnx driver. Also, I don’t think I got around to the audio section of the code iirc.
It’s a shame my C skills are hella rough; a libnx port doesn’t seem too difficult. The APIs for libtransistor and libnx are sort of similar, though libtransistor is more low-level. Plus, RetroArch is architected beautifully so that really helps a bunch I’m mostly posting this so people don’t falsely assume a libnx driver is impossible.
(Sorry if there are typos; I’m on the train lol)
Well, someone needs to port RetroArch using the latest version of LibNX ASAP (if possible).LibNX was updated an hour ago. Not sure if any of the changes would help?
https://github.com/switchbrew/libnx/releases
Well, someone needs to port RetroArch using the latest version of LibNX ASAP (if possible).
It would really save a lot for people using Fusée Gelée/RCM homebrew methods on 4.x and 5.x, like me (once again).
LibNX was updated an hour ago. Not sure if any of the changes would help?
https://github.com/switchbrew/libnx/releases
Alright, my verrryyyyy WIP branch with Retroarch-libnx is up. See here for a comparison between master and my branch.
Notes:
- Audio is commented out. Didn't even try to look into it lol.
- Joypad support is added but will most likely not map the buttons properly. This is something I was planning on working on once/if it compiled. Sorry it's half done.
- The joypad stuff was pretty simple because of this. The only thing to note is that I'm pretty sure we don't have to tear down the joystick HID controllers in libnx? Would love to hear input.
- The graphics driver is seemingly there. Barring any weird pointer stuff. (shakes fist in the air at C)
- The graphics driver changes are as follows: I removed the handler to vsync because I don't think libnx exposes that, though I could be wrong. I added a u32 address to the framebuffer which is returned from gfxGetFramebuffer(). Libtransistor's port used the framebuffer and a temporary buffer when updating the frame. It would point the temp buffer to the surface, check if it should wait for vsync and then wait for the vsync svc, sleep the thread for 10000 nano seconds (I assume), copy the stored "image" to the temp buffer, then refresh the framebuffer to use the newly-updated surface. I, in a very terrible implementation that's more or less copied from example code, use breadth first search to grab the pixels of the framebuffer and set them to the pixels from the image. I then call gfxFlushBuffers() and then gfxSwapBuffers(). If the vsync flag is on I wait for vsync using gfxWaitForVsync() and then sleep the thread. I wonder how close that is in replicating the logic from libtransistor.
- This all compiles (though I'm not sure if the attached Makefile will compile; it's been a bit since I worked on it). As in, all of the code properly generates object files. Linking is an issue, though. I generally hate dealing with Makefiles (cmake especially is the devil) so this was bound to be my hurdle. It's pretty simple to get libtransistor-snes9x2010 to compile using libnx (it's just a Makefile change that is not attached) but I wasn't able to verify if the generated .a file worked. Upon linking the retroarch nro, I ran into issues regarding methods being defined in multiple places. I believe this has to do with how RetroArch is structured (moving things into static libraries and calling those methods from the RA app). I also believe the libtransistor port is able to get around this using "--allow-multiple-definition" when linking because it used (IIRC) ld to link the binary. Libnx's makefiles use gcc for the linking and gcc lacks that flag, though a cursory stack overflow search says "-Wl,-b,svr4,-z,multidefs" might help.
Hope this helps someone, somewhere!
Can you compile some downloadable cores so people can test them please?Alright, my verrryyyyy WIP branch with Retroarch-libnx is up. See here for a comparison between master and my branch.
Notes:
- Audio is commented out. Didn't even try to look into it lol.
- Joypad support is added but will most likely not map the buttons properly. This is something I was planning on working on once/if it compiled. Sorry it's half done.
- The joypad stuff was pretty simple because of this. The only thing to note is that I'm pretty sure we don't have to tear down the joystick HID controllers in libnx? Would love to hear input.
- The graphics driver is seemingly there. Barring any weird pointer stuff. (shakes fist in the air at C)
- The graphics driver changes are as follows: I removed the handler to vsync because I don't think libnx exposes that, though I could be wrong. I added a u32 address to the framebuffer which is returned from gfxGetFramebuffer(). Libtransistor's port used the framebuffer and a temporary buffer when updating the frame. It would point the temp buffer to the surface, check if it should wait for vsync and then wait for the vsync svc, sleep the thread for 10000 nano seconds (I assume), copy the stored "image" to the temp buffer, then refresh the framebuffer to use the newly-updated surface. I, in a very terrible implementation that's more or less copied from example code, use breadth first search to grab the pixels of the framebuffer and set them to the pixels from the image. I then call gfxFlushBuffers() and then gfxSwapBuffers(). If the vsync flag is on I wait for vsync using gfxWaitForVsync() and then sleep the thread. I wonder how close that is in replicating the logic from libtransistor.
- This all compiles (though I'm not sure if the attached Makefile will compile; it's been a bit since I worked on it). As in, all of the code properly generates object files. Linking is an issue, though. I generally hate dealing with Makefiles (cmake especially is the devil) so this was bound to be my hurdle. It's pretty simple to get libtransistor-snes9x2010 to compile using libnx (it's just a Makefile change that is not attached) but I wasn't able to verify if the generated .a file worked. Upon linking the retroarch nro, I ran into issues regarding methods being defined in multiple places. I believe this has to do with how RetroArch is structured (moving things into static libraries and calling those methods from the RA app). I also believe the libtransistor port is able to get around this using "--allow-multiple-definition" when linking because it used (IIRC) ld to link the binary. Libnx's makefiles use gcc for the linking and gcc lacks that flag, though a cursory stack overflow search says "-Wl,-b,svr4,-z,multidefs" might help.
Hope this helps someone, somewhere!
Can you compile some downloadable cores so people can test them please?
I'm in a very similar boat. I started tackling libretro/mgba last night. I got all of the object files to compile with libnx & generated the .a file but I'm not well versed in the libretro ecosystem so I don't exactly know what to do with it yet haha. Taking a quick look at your branch, it seems like it might be helpful to me. Thanks!
Can you compile some downloadable cores so people can test them please?
Any chance of PS1 games ever running at full speed with Beetle? I can only find one video of Crash and it runs pretty badly. Would PCSX perform better?
I had a similar problem when porting VBA-next(I wrote a bit about it here: https://github.com/RSDuck/vba-next-switch#speed-hack). It would probably be a good idea to further investigate this and then create an issue on the libnx repository.The graphics driver changes are as follows: I removed the handler to vsync because I don't think libnx exposes that, though I could be wrong. I added a u32 address to the framebuffer which is returned from gfxGetFramebuffer(). Libtransistor's port used the framebuffer and a temporary buffer when updating the frame. It would point the temp buffer to the surface, check if it should wait for vsync and then wait for the vsync svc, sleep the thread for 10000 nano seconds (I assume), copy the stored "image" to the temp buffer, then refresh the framebuffer to use the newly-updated surface. I, in a very terrible implementation that's more or less copied from example code, use breadth first search to grab the pixels of the framebuffer and set them to the pixels from the image. I then call gfxFlushBuffers() and then gfxSwapBuffers(). If the vsync flag is on I wait for vsync using gfxWaitForVsync() and then sleep the thread. I wonder how close that is in replicating the logic from libtransistor.
Glad I could help in some way! It sounds like you compiled a core lib which is the first step to getting RetroArch to run on the Switch! Take the .a file, move it to the root directory of the retroarch project, rename it to "retroarch_switch.a" (if I remember correctly), then run make -f Makefile.switch. Those are the required steps for the libtransistor build, at least. Good luck!
$ /opt/devkitpro/devkitA64/bin/aarch64-none-elf-gcc -specs=/opt/devkitpro/libnx/switch.specs -g -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE -finline -L/opt/devkitpro/portlibs/switch/lib -L/opt/devkitpro/libnx/lib -L/developer -lm -lSDL2 -lnx -lm -lstdc++ -lc -lretro_switch -o /developer/retroarch_switch.elf
/opt/devkitpro/libnx/lib/libnx.a(switch_crt0.o): In function `bss_loop':
/home/fincs/pacman-packages/libnx/src/source/runtime/switch_crt0.s:60: undefined reference to `main'
collect2: error: ld returned 1 exit status
Thanks for the info! I've been trying to get retroarch to build with your modifications but I'm encountering an odd issue when linking that seems different from what you were seeing:
Code:$ /opt/devkitpro/devkitA64/bin/aarch64-none-elf-gcc -specs=/opt/devkitpro/libnx/switch.specs -g -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE -finline -L/opt/devkitpro/portlibs/switch/lib -L/opt/devkitpro/libnx/lib -L/developer -lm -lSDL2 -lnx -lm -lstdc++ -lc -lretro_switch -o /developer/retroarch_switch.elf /opt/devkitpro/libnx/lib/libnx.a(switch_crt0.o): In function `bss_loop': /home/fincs/pacman-packages/libnx/src/source/runtime/switch_crt0.s:60: undefined reference to `main' collect2: error: ld returned 1 exit status
Did you happen to see this issue or have any insight?
I had a similar problem when porting VBA-next(I wrote a bit about it here: https://github.com/RSDuck/vba-next-switch#speed-hack). It would probably be a good idea to further investigate this and then create an issue on the libnx repository.