Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add launcher options to INI? #5

Closed
emoose opened this issue Oct 26, 2023 · 8 comments
Closed

Add launcher options to INI? #5

emoose opened this issue Oct 26, 2023 · 8 comments

Comments

@emoose
Copy link
Contributor

emoose commented Oct 26, 2023

There's some ways to launch the game EXE directly, but usually results in wrong buttons/game language being used, looks like launcher passes those along as arguments to the game EXE, might be nice if some defaults for them could be setup in the INI instead.

eg. some params procmon shows game launching with:

"METAL GEAR SOLID3.exe" -region us -lan en -selfregion EU -launcherpath launcher.exe -ctrltype KBD

For launching game EXE directly it looks like creating steam_appid.txt file with 2131650 inside is enough, not sure if it's steamstub or the games steamworks stuff that needs that in place, if it's just steamworks side maybe setting SteamAppId environment variable with SetEnvironmentVariableW before game code is ran could help.

Alternately could just create the steam_appid.txt file in game folder when it doesn't exist already, to enable the next game launch to be ran directly, iirc re4_tweaks does something like that to allow direct launching too.

E: looks like in MGS3, the values for these get stored inside:

  • lan: 141D41E80
  • region: 141D41E88
  • selfregion: 141D41E8C
  • ctrltype: 140ADD430

Seems the lan/region are passed to COsContext::InitializeSKUandLang, and ctrltype is passed to NHT_COsContext_SetControllerID, both exported from Engine.dll, maybe could hook those exports and override them from INI values if default value was passed to them (so that exe args would still work) (eh that could have issues if user tried certain selections from launcher while INI options were set - probably better to scan for the args and only override if they weren't specified instead)

Doesn't look like selfregion is actually used in MGS3, could have missed something about that though, code that sets up these args is a little weird.

@emoose
Copy link
Contributor Author

emoose commented Oct 28, 2023

Started on something for this at emoose@b730839, that should be able to override the defaults game uses when no config is provided, and if game is launched through the launcher then the config launcher passes over will be used instead of the INI settings.

Seems to work fine for changing the default button style, but unsure about region/language, didn't seem to have much effect for me when I changed that, need to do some testing with the launcher itself and see what values it passes over.

E:

setting SteamAppId environment variable with SetEnvironmentVariableW before game code is ran could help.

Didn't have any luck with this, seems it's something in steamstub .bind that checks SteamAppId env var / .txt file, looks like ASI loader lets .bind run first before it loads in ASI plugins too, so can't really do much about it on .asi side...

Creating steam_appid.txt when it doesn't exist so that EXE could run directly in future could still be an option though.

@ninjabean645
Copy link

How would you use this exactly? Just setting the controller type is all I need. Apologies if it's a dumb question.

@emoose
Copy link
Contributor Author

emoose commented Nov 5, 2023

Made a new branch for this at https://github.com/emoose/MGSHDFix/tree/direct-launch, also included some code to try creating steam_appid.txt there.

Unfortunately the std::filesystem stuff I used seems to have issues with ICC, something to do with wmemcmp external not being located, tried some solutions online but didn't have much luck, only fix I found for it was changing /MD (multi-threaded DLL) to /MT (multi-threaded).

AFAIK that changes it so that C runtime is linked in statically instead of dynamically, noticed the ASI size does jump up 500KB or so with that.

Seems linking it dynamically is meant to help when you have multiple DLLs sharing the same C runtime, I think we might be the only one using this version of runtime though, so maybe linking statically would be fine? @Lyall do you think this is fine to change?

How would you use this exactly? Just setting the controller type is all I need. Apologies if it's a dumb question.

There's no build with it included atm, but once it's added you can just change it from the INI, then when you run game exe directly it'll use your INI choice instead.

@Lyall
Copy link
Owner

Lyall commented Nov 5, 2023

Seems linking it dynamically is meant to help when you have multiple DLLs sharing the same C runtime, I think we might be the only one using this version of runtime though, so maybe linking statically would be fine? @Lyall do you think this is fine to change?

I think it'd be fine to change. Seems like the primary benefit of using /MD is the optimisation aspect which in our case is pretty trivial given the scope of MGSHDFix. Perhaps there might even be a benefit with the runtime being consistent on every platform.

@emoose
Copy link
Contributor Author

emoose commented Nov 5, 2023

Nice, was thinking the same about runtime staying consistent too, will look into making a PR for it soon.

Also just realized our ASI does seem to get loaded in for launcher.exe too, maybe there's a way to get it to just launch game exe & then exit for us, hm...

@emoose
Copy link
Contributor Author

emoose commented Nov 6, 2023

Hm, found out why region/language hook didn't take effect before, seems game already called those functions before we had a chance to hook them :/

Since our Main is in a separate thread the games WinMain is also running at same time, I had issues with SWUSF on this before too, for that I got around it by just changing their code to call their main func from DllMain directly instead of creating a thread.

Changing it the same seems to work fine here too, guess we aren't doing much that touches the loader lock, maybe we can just switch it to that, haven't tested all our patches/hooks with it yet though.

Safer way could be to have our DllMain hook one of the kernel32 IATs that the games WinMain calls early on, then once game calls it we could apply everything before rest of game has a chance to run - unfortunately seems ultimate ASI loader is also doing the same and doesn't restore IATs before loading our plugin though, so haven't had any success with it yet.

@samuskay
Copy link

I made a little project to try and automate launch options here if you want more of the possible arguments: https://github.com/samuskay/Metal-gear-Solid-2-and-3-launcher-skip .

But was wondering is it possible to intercept the launchers call to game exe and start it with different arguments are offered in the mod ini file?
But assuming if that was possible its probably what would've been tried first..

It's worth mentioning that using a .bat file to launch the game direct with arguments seems to work great and steam integration continues to work, so there may be a similar solution there.

Also yes self region doesn't seem to be needed, it only refers to the version of the collection you own and can be ignored.

for mgs 2 you need the -lan -launcherpass and -ctrltype variables

for mgs 3 you need the above plus the -region variable to specify whether its the eu, us or jp version of the game that loads, this isn't needed in mgs 3 as its dictated by the language menu.

@samuskay
Copy link

well gosh darn it you just went and did it, much respect :).

@Lyall Lyall closed this as completed Jan 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants