Jump to content
LaunchBox Community Forums

Lahma

Members
  • Posts

    404
  • Joined

  • Last visited

  • Days Won

    8

Everything posted by Lahma

  1. @Jason Carr Well, I didn't intend to take 6+ weeks to make this post, but I got busy and forgot about it until cammelspit recently reminded me of it. Let me try to briefly explain the reason why the plugin API in its current state can't accomplish what I would like it to be able to accomplish in order to fully realize the goals for my plugin, and then I will suggest some ways that the API could accomplish those goals in a relatively easy-to-implement way. My plugin in its current state simply adds a single item to the bottom of the game context menu, and when clicked, it gathers all of the needed default game/emu/rom/arguments/etc paths for that particular title and then using a custom API I wrote, makes native calls into unexposed functions in the Steam client in order to create a temporary shortcut in Steam and subsequently launch the game through the newly created Steam shortcut. I won't go into any more detail, as I don't really think its relevant, but I will instead explain the problem the plugin currently faces. Since you can only create/implement classes based on IGameMenuItemPlugin at design time, and additionally since any changes made to the properties of one of those classes during runtime are not reflected in LB/BB, it severely limits my ability to do things a dynamic way. The precise problem that I'm facing is that I would like to be able to create a submenu of additional "Launch via Steam" items at runtime based on how many non-default emulators/platforms a particular item has, almost EXACTLY like the "Launch with" menu item you already have implemented. The way the plugin API currently works though, this obviously cannot be done, so I'm forced to include only a single "Launch via Steam" menu item that uses the default emulator/launcher that is assigned to any particular title. One more quick issue that is relevant is that there is currently no way for my plugin to allow LaunchBox to handle the decompression of roms prior to launch, so I would either have to redundantly implement this behavior myself, or simply not support compressed roms that are handled by LaunchBox. In my opinion, there is a simple and elegant way to implement this functionality into the plugin API that would figuratively "kill both of these birds with one stone." By implementing a "LaunchGame" callback/event that can be subscribed to via the plugin API, a plugin could subscribe to this event and receive all of the launch parameters for a specific title (that would change depending on whether the default launch option was selected or one of the non-default 'Launch with' options), including the path to the decompressed rom (if LB was designated to handle that). Handling the event on the plugin side might look like something in my plugin's case: static void launchGameEventHandler(object sender, LaunchGameEventArgs e) { if (!this.LaunchViaSteamByDefault) { e.CancelLaunch = false; return; } IGame game = e.Game; IPlatform platform = e.Platform; string[] launchParams = e.LaunchParams; string appPath = game.ApplicationPath; [...etc and so on...] if (e.IsAppDecompressedByLb) { if (!string.IsNullOrEmpty(e.DecompressedAppPath)) { appPath = e.DecompressedAppPath; } e.DeleteDecompressedAppOnLbExit = true; } e.CancelLaunch = true; this.LaunchGameViaSteam(game, platform, launchParams, [...etc..]); } This is of course an oversimplification designed only to give you an idea of what I had in mind, but does seem like it would not be very difficult to implement. If my plugin had something like this to use, then instead of having a context menu item labeled, "Launch via Steam", I might instead implement a checkbox context menu item labeled, "Use SteamLauncher by Default", and as long as this is checked, all games would by launched through my plugin rather than through LaunchBox itself. I would appreciate any feedback on the idea, and any indication of whether or not its something you might be willing to implement. I think it would make the plugin API much more diverse and capable, and a simple event/callback system like this could be used for a wide variety of things. Thanks for your time!
  2. I'm a total ass for taking so long to post the source code, but its finally uploaded on my GitHub. Sorry about the delay... My OCD/perfectionism gets the best of me at times (though the source code is far from perfect). I did do my best to comment/document the source code in as detailed a manner as possible. Enjoy! https://github.com/lahma69/SteamLauncher
  3. The plugin download page explains how to do this in depth: https://forums.launchbox-app.com/files/file/972-steamlauncher/ Here is the relevant section: Customize Platform Names When roms are launched with the plugin, the title of the game, as Steam sees it, will be in the format of: "Game Title (Platform Name)" Example: Super Mario Bros. (Nintendo Entertainment System) For whatever reason, you may want to keep the long "official" name of the platform in LaunchBox, but use a shortened, abbreviated, or different platform name inside of Steam. The plugin has this functionality available, and it can be enabled by following these instructions: Open the SteamLauncher directory and look for a file named 'config.xml' If you do not see the file, you need to launch at least 1 game with the plugin, and then manually close LaunchBox, and the file should then appear in the directory Open the file with a text editor, and look for the line labeled, '<CustomPlatformNames>' Anywhere under this line, and before the line labeled, '</CustomPlatformNames>', you can add as many new lines as desired in the format of: <Platform Name="Original LaunchBox Platform Name" Custom="Custom Platform Name" /> You may already see a couple of example lines in place with fake platform names which you can copy/paste and modify to add your own custom platform names After making your changes, simply save the file, close it, and then reopen LaunchBox The next time you launch a game, you should see your new custom platform name substituting the real platform name in Steam (an easy place to see the title of the game you're playing is in the Steam overlay) Just to reiterate, here is an example of what the aforementioned lines look like in my config file: <CustomPlatformNames> <Platform Name="Super Nintendo Entertainment System" Custom="SNES" /> <Platform Name="Nintendo Entertainment System" Custom="NES" /> <Platform Name="Nintendo Game Boy Advance" Custom="Nintendo GBA" /> <Platform Name="Nintendo Game Boy Color" Custom="Nintendo GBC" /> </CustomPlatformNames>
  4. @coasterndDid you get a chance to try disabling "Run as Admin" for Star Wars Shadows of the Empire to see if that fixed your problem with the Steam overlay? From some quick research that I did, it sounds like that is the only issue preventing the GOG version of that game from working with the overlay. For that particular title, I think you can just open the properties of the game EXE and disable "Run as Admin" on the Compatibility tab.
  5. @coasternd Let me address a couple of points before talking about the specific games you discussed. The SteamLauncher plugin should work now for any game, so long as that game/launcher works with the Steam overlay under normal circumstances (when not using the plugin.) If you notice the Steam overlay isn't work for a particular game, you can quickly rule out SteamLauncher as the source of the problem by manually adding a non-Steam game to Steam and then running the new shortcut from within Steam to see if the overlay is working properly. If it doesn't work, then its almost certainly a game/launcher specific issue, and usually a quick Google search (such as 'Star Wars Shadows of the Empire GOG steam overlay') will provide the answers you need. One common issue that would prevent the Steam overlay from working with a particular title is that the game/launcher is set to run as an admin (MANY times without any good/valid reason), but Steam and/or LaunchBox are running with normal privileges (NOT run as an admin). If the game is launched/run with higher privileges than Steam is running with, Steam can't hook into the process to attach its overlay. To overcome this problem, I know a lot of people simply choose to set Steam to 'Run as Admin' by default, but this really is not a great thing to do from a security perspective. Its a bad practice for game developers to ship their games this way, especially games that have online functionality, because if an attacker manages to exploit a bug in the game to gain control over the process, they have 100% unrestricted admin access to your machine. If you find yourself in this boat with a particular title, there are a couple of things you can do. First thing would be to check the properties of the game/launcher EXE and see if you can simply disable this behavior by navigating to the "Compatibility" tab and unchecking "Run this program as an administrator" if available. If this option is not available (an executable can request/require admin privileges at runtime), there is another solution you can try: By running the following command, you can force the EXE to run without admin privileges, and with games, this usually won't cause any problems, as they typically do not have a legitimate need for escalated privileges: cmd /min /C "set __COMPAT_LAYER=RUNASINVOKER && cd "C:\ExamplePath\ExampleGame" && start "" "C:\ExamplePath\ExampleGame\game.exe"" To configure your LaunchBox shortcut to do this, you can either configure the command-line parameters for the LaunchBox game yourself, or you can take the much easier route and use a preconfigured batch file I just created: EASY METHOD: MANUAL CONFIGURATION METHOD: If this was the problem preventing the Steam overlay from showing on a particular game, Steam should now be able to successfully show the Steam overlay when launching games with SteamLauncher Moving on... There are other issues which can prevent Steam from showing its overlay, such as is the case with the Origin and UPlay. The problem there is that they are just outright preventing Steam from hooking into their app and therefore blocking the Steam overlay. The Steam overlay used to work with Origin, but in an update (I think sometime last year), they started explicitly blocking it. The only workaround I know of in this case is to use something like GloSC. As for controller profiles, each Steam controller profile will be maintained independently, and each time you load that game/rom, any changes you made to the controller profile when playing that game/rom previously will automatically be loaded on your current gaming session. You do not need to load a controller profile every time you launch a game/rom.
  6. So, no problems/issues/bugs yet? After lunch, or maybe this evening instead, I will work on getting the source code pushed out to GitHub.
  7. The new release (v0.9.0.2) has been uploaded: Added support for PC/Windows games, DOSBox games, and ScummVM games Fixed a bug preventing any games with a non-ASCII character in their file name from being launched Added a workaround for an annoying issue that causes the Steam UI to steal focus and/or move into the foreground in front of LaunchBox/BigBox after exiting certain games Note #1: LaunchBox/BigBox must be run once and then restarted for the config.xml to be updated in order for this new feature to start working Note #2: This workaround can be enabled/disabled by changing the value of 'PreventSteamFocusStealing' in config.xml @The_Keeper86 Make sure to read Note #1 in the changelog above. I was supposed to be on the road like 4 hours ago, so I will upload the source to GitHub when I get to my destination very late tonight. I added/changed quite a bit in this release, so if you experience any problems, please post them here so I can look into them ASAP.
  8. Sorry I haven't gotten it uploaded yet, but I wanted to get the 'Steam taking focus from LaunchBox/BigBox' problem worked out so I wouldn't have to do 2 updates right in a row. I'm happy to say, I just finished implementing a reasonable workaround for the issue. Being that its 6:30 AM, I'm going to get a bit of sleep, but since I finally got everything finished up, I'll get everything uploaded tomorrow. Thanks for your patience everyone.
  9. Just wanted to let y'all know I spent the entire day yesterday working on the plugin, and I got Windows game support working, DOSBox game support working, ScummVM game support working, and got everything fixed with special characters. I'm working on the Steam client taking focus from BPM problem right now. Whether I get that fixed or not, I will be uploading an update today for sure, and uploading the source to GitHub.
  10. I'm sure it could do that, but C# code should be able to accomplish anything that it can. I'm actually going to try to implement a background thread that takes care of that problem. I'm just trying to figure out what would be the best logic to use to handle such a thing... For example I could do something such as: if (BigBox or LaunchBox are currently in focus/foreground) { if (steam comes into foreground/focus) { minimize(steam) } } That would of course prevent you from switching directly to Steam from LaunchBox/BigBox which isn't really desirable... I suppose I could simply prevent the Steam UI from taking focus only while BigBox is running... What do you think?
  11. I'm working on implementing that at this exact moment. I hope to have a new release ready to go here in just a bit.
  12. That makes me really happy to hear! I would probably have created this project even if it was helpful only to myself (and for the fun and experience of learning new things), but I think it makes any programmer happy to hear that other people are getting a lot of use out of a project that they have put a lot of hard work and time into. Although I have not put a lot of time and effort into making full use of my Steam Controller, ever since I learned of the Steam controller configuration utility (in regards to its use with any generic controller), it has radically altered the way I play many games/roms. Its so endlessly customizable, and again, that is the entire reason I built this plugin.. just to make the Steam controller config utility easier and more seamless to use... because there is nothing else like it, and at this point, I couldn't live without it (for my Steam Controller or my other controllers (Xbox One, Switch Pro, and GameSir G4S primarily). By the way, have any of you seen awesome new wireless controller adapters that allow you to use your Xbox One/PS4/Switch controllers wirelessly with other consoles? I wish I would have known that these were coming before I paid $80 for my Switch Pro controller... Brook X One Adapter https://www.focusattack.com/brook-x-one-ps4-switch-pc-adapter-and-rechargeable-battery/ Mcbazel Mayflash MAGIC-NS http://a.co/e4wvXKC
  13. @Nielk1 You are welcome to use the Steam API I wrote from scratch. I literally spent about 3 months researching the ins and outs of the Steam client API and spent much more time reversing the steamapi.dll in IDA than I care to admit. I can name many of the vftable offsets by memory lol. My ultimate goal was to use pattern-matching /signature-scanning (quick explanation: https://wiki.alliedmods.net/Signature_scanning ) for all relevant calls into the Steam API, but for many reasons that I won't bore you with, this didn't end up being an immediately practical goal (though I've not totally abandoned the idea). At this point, I've only implemented the classes I need for my plugin, but by simply copying the pattern/layout of an one of the classes that does exist in mine (such as IClientShortcuts) and providing the appropriate vftable offsets (gotten from SteamWorks/Steam4Net, or I can give you any offsets you need in about 60 sec by opening up IDA), you can easily add any additional classes/interfaces you need. For certain vftable offsets and/or interface version numbers that seem to change constantly, I've added some additional snippets of code to be resilient against future changes (and thus far, has worked on a couple of occasions). I was able to postpone going out of town, so I'm going to try to implement PC game support into the plugin, and as soon as I'm done with that (hopefully here in just a little while), I will push the source to GitHub.
  14. To first address your message Nielk1: I actually wrote my own custom made API for all communications with Steam in an attempt to lessen the effects of the constant vftable offset changes that you are talking about. This is the function that I'm using to convert unmanaged string pointers into managed string objects: protected static string DecodeAnsiString(IntPtr stringPtr) { if (stringPtr == IntPtr.Zero) return null; var unencodedString = Marshal.PtrToStringAnsi(stringPtr); return unencodedString == null ? null : Encoding.UTF8.GetString(Encoding.Default.GetBytes(unencodedString)); } It turns out, by luck, this method actually works correctly and does what its supposed to, but oddly enough, its named incorrectly. Instead of 'DecodeAnsiString', it should be named, 'DecodeUtf8String' (explained below). Even if there was a problem here, this method, like the one from your app that you linked to, are going the 'wrong direction' to fix the issue described by GsMumbo. These functions decode strings being sent from Steam to our apps/plugins, such as in the following example (with fixed function name): public string GetShortcutAppNameByAppId(UInt32 unAppId) => DecodeUtf8String(GetDelegate<GetShortcutAppNameByAppIdDelegate>()(InterfacePtr, unAppId)); The problem reported by GsMumbo is affecting data being sent to Steam, such as when creating a Steam shortcut (and sending string parameters such as app name, path, etc). I really wish the problem would have been something minor such as that, but it turns out it was quite a little adventure fixing the problem. Rest of my post explaining the problem and the fix below: So ya... You wouldn't think looking into a "tiny" issue like a é symbol in "Pokémon" being mangled by Steam would be too big of a deal... Turns out it kinda was. I spent the last 8 hours working on this... As I'm sure you know Nielk1, as well as any other programmer, character encodings can be MADDENING. I did a lot of string encoding/decoding, testing, a lot of looking at shortcuts.vdf in a hex editor, a lot of adding fake games to Steam using 1-4 byte unicode characters, debugging, etc. I'm really sick of it all, so I won't go into THAT much detail, but I will give a quick rundown of my findings. First, Steam stores all of its strings in UTF-8 (which is what all software and operating systems should do in my opinion) and therefore requires any strings passed to its API to be encoded in UTF-8. However, since PInvoke/UnmanagedFunctionPointer in C# converts strings into CharSet.Ansi by default before marshaling them, unless you are using characters outside of the ASCII range (above approximately 0x7F I think), you won't notice any problems if the receiving app is reencoding those bytes as UTF-8. Of course, to make things even more confusing, .NET strings are UTF-16, as well as that being Windows default encoding. So essentially, once you start using special characters outside the ASCII range, your UTF-16 string objects must be converted to UTF-8 prior to passing to Steam, which Steam then stores in UTF-8, but then before passing back to the OS, Steam of course has to reencode its strings back into UTF-16. Quick side note... for anyone wondering here is what the string 'Pokkén' looks like in hex in 3 different encodings: ANSI: 50 6f 6b 6b e9 6e (é = 'e9') UTF8: 50 6f 6b 6b c3 a9 6e (é is 2 bytes, 'c3 a9', unlike the other letters which are a single byte only) UTF16: 00 50 00 6f 00 6b 00 6b 00 e9 00 6e (é = '00 e9') Unfortunately, when using PInvoke/UnmanagedFunctionPointer in C#, there is no automatic way to marshal strings into UTF-8 when passing them to unmanaged functions (only CharSet.Ansi and CharSet.Unicode (UTF-16)). There a few different things you can do to deal with the problem... I ended up doing them all, just to learn and see which way would be the best/cleanest. The 1st option is to write a custom marshaler, but this requires a separate decorator tag for each string parameter, which I think looks pretty messy/ugly. I.e: private delegate UInt32 AddShortcutDelegate(IntPtr thisPtr, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8StringMarshaler))] string szAppName, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8StringMarshaler))] string szExePath, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8StringMarshaler))] string szIconPath, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8StringMarshaler))] string szUnknown1, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8StringMarshaler))] string szCommandLine); The 2nd option is to simply allocate some memory convert each string into a UTF-8 encoded byte array, move it into the memory you allocated, and pass that pointer instead of a string. This is exactly what the custom marshaler is doing, just in a more streamlined manner. The 3rd option is to do a hacky workaround trick, which at this point, appears to be the sanest, cleanest option to me. I will let my code explain it: /// <summary> /// Hackish workaround to get around the fact that the 'UnmanagedFunctionPointer' CharSet decorator does not support CharSet.UTF8. /// This function converts a normal string into a UTF-8 byte array which is then turned back into a normal string using 'Default' /// encoding (ANSI). The end result of this is that when the CLR marshals the string, decoding it into a byte array using ANSI, to /// pass it to a native function, it will actually be a valid UTF-8 string that Steam will read correctly rather than an ANSI string /// which will mangle any non-ASCII special characters. Note: Once converted with this method, the .NET string object will appear /// mangled because its being displayed using the wrong encoding. /// </summary> /// <param name="str">The string to convert to UTF-8.</param> /// <returns>A string that when decoded into bytes using ANSI encoding, can be turned back into a valid string using UTF-8 encoding.</returns> public static string ToUtf8(this string str) { return Encoding.Default.GetString(Encoding.UTF8.GetBytes(str)); } By turning it into an extension method, at least all of my code can still remain fairly tidy. This: public UInt32 AddTemporaryShortcut(string szAppName, string szExePath, string szIconPath) => GetDelegate<AddTemporaryShortcutDelegate>()(InterfacePtr, szAppName, szExePath, szIconPath); Only turns into this slightly longer version: public UInt32 AddTemporaryShortcut(string szAppName, string szExePath, string szIconPath) => GetDelegate<AddTemporaryShortcutDelegate>()(InterfacePtr, szAppName.ToUtf8(), szExePath.ToUtf8(), szIconPath.ToUtf8()); To sum it up, I spent way more time looking into this and fixing it than I probably needed to.. I figured out about half-way in why it was happening, and I could have just converted each string manually before sending it to the relevant functions, but I wanted to look into it a bit deeper. Although I'm still not totally happy with the way I'm dealing with the problem now, I think its a reasonable band-aid until Microsoft implements UTF8 marshaling (which apparently is planned for at some point). I will spare y'all any more details (which I have many more of), because y'all could probably care less, and most importantly, because I want to go play some Quake Champions. If I can put off traveling for another day or 2, I may try implementing PC game support into the plugin, and upload a new version of the plugin with both that and the special characters fix at one time. If it turns out I don't have enough time to get that done, I will upload a new version tomorrow (well.. today... 5/24) with just the special character fix. Additionally, as I've been meaning to do forever, I'm going to try to push the source code out to GitHub as well. Thanks for all the kind words and the help tracking down/fixing bugs, etc! Especially you Nielk1! Although I wrote this plugin from scratch, I likely never would have created it without the experience gained from forking your project first.
  15. Nice! I appreciate you mentioning it. If it turns out to be nuisance, looking at your code will probably be very useful.
  16. Man, I gotta see what the problem is with me not receiving notifications of new messages in this thread. I apologize for not seeing your message sooner. That is very interesting, and I will look into it immediately. I have a suspicion that this might actually be an issue with Steam, but hopefully that isn't the case and it is something that can be fixed easily on my end. I currently have about 40 different windows open on my desktop (literally) and I'm juggling about 5 different tasks at the moment, so give me a bit to finish up with this tangled mess, and then I will start looking into this. If its simply an encoding issue on my end, it should be a quick and easy fix. I'll post back here as soon as I know something. I'm going to do my best to get to it today, but if I don't end up getting to it today, I'm going to be traveling the next few days, so I probably won't be able to look into it until the weekend.
  17. I appreciate the info and your offer to help. If I think of anything, I'll be sure to let you know.
  18. I definitely appreciate your input man. Since I read your review, I too have noticed that the Steam UI popping up after a game exits is seemingly random. One thing I have noticed though is that, at least for me, it only seems to popup when Steam automatically turns off my wireless Xbox One controller. I'm not even sure when or why Steam decides to turn off my controller though, as it seems to only occur on particular emulators or games. For example, it seems to always automatically turn off my Xbox One controller after I exit RetroArch which then causes the Steam UI to pop into the foreground. I think I will have to do a little more testing on this. If you notice any rhyme, rhythm, or pattern yourself, please let me know. Thanks!
  19. Sorry I'm only just now responding to your post The_Keeper86. Somehow I missed the email saying I had replies to this topic. To be totally frank with you, I have done ZERO testing of any non-Steam Windows PC games with my plugin, as I myself do not use LaunchBox to manage those games. I suspect the explanation for why it doesn't work is pretty simple however. My plugin uses emulator/rom specific arguments provided by the LaunchBox plugin API to create and launch temporary hidden Steam shortcuts, so I suspect those same arguments do not apply to native Windows games that do not need an emulator in order to play them. On the other hand, fixing the plugin so that it would work with non-Steam Windows games would probably be pretty straightforward, and I don't imagine it would be too difficult to implement. If this is a feature you would like for me to add, let me know, and I'll see if I can get it implemented in short order. I really have no idea how many LaunchBox users make use of LaunchBox to play native Windows PC games, so if there are any other users who would find this feature useful, please let me know in addition to The_Keeper86. One last thing, I saw the review you posted of the plugin, where you mentioned that using the plugin in BPM would sometimes cause the Steam UI to popup in front of BPM after a game exited. Being that I use BPM very little, I hadn't noticed this behavior until you said something (even though it probably happens in non-BPM too but probably isn't noticed since most people are using a keyboard/mouse in that case). I'm going to have to think about this issue for a bit... I'm not totally sure that there is going to be anything I can do on my end to fix this problem, simply because of the way the plugin API works and the fact that plugins aren't really meant to be a persistent process that could monitor things like window focus and process exits. However, there may not really be anything stopping me from performing such duties even if it would complicate things a bit. Let me investigate this a bit more and I will post my findings in this thread.
  20. I'm glad my explanation helped you figure things out! The whole Steam controller configuration thing took me quite awhile to understand on a fundamental level. The more and more I learned about it, the more I was really blown away by the intricacies, fine-tuning, and endless level of different setups and configurations that were possible. Although I have a Steam Controller, I only use it on a few select titles, so the majority of my use of the Steam controller configurator is for use with Xbox One gamepads and other generic xinput gamepads. The whole reason I created this plugin was because of my belief that the Steam Controller Configurator is an indispensable, unique, and irreplaceable feature of my PC/emulator gaming setup. There simply is nothing else like it and I personally cannot go without it, therefore I needed something that would allow me to use it with anything I launched through LaunchBox.
  21. I have not personally seen any behavior such as this. Maybe the problem is that you're somehow sharing the same controller profile across multiple games? The way I personally setup controller profiles is by creating a "default" starting point config for a particular platform (for example, I have a default RetroArch config that has a radial menu setup on the right analog stick for managing save states and such) and when I'm happy with it, I'll export it as a "Save New Template Binding" and name it something such as "RetroArch Default with Radial Menu". Then, when I launch any new rom for the first time through SteamLauncher, I'll load up that template binding and use it as a starting point. If you want to export (save) any new/updated bindings for any particular room, you can then save those as a "Personal Binding" and name that profile after that particular ROM, but you don't have to do that. Even if you don't export the changes you've made to a new binding profile, they will be automatically retained between gaming sessions of that ROM, and any changes you make won't affect the original template profile you used as a starting point. The only way I can see having the problem you are having is if you are using the same profile between both ROMs/emulators and are re-exporting (overwriting) the profile after you make any changes. If you need any additional help, or you can't figure it out, let me know and we can try to chat on Steam so I can help you figure things out.
×
×
  • Create New...