Wing Loader (KS/WCDX) Loader & Voice Over Mod

Time flies when you're having fun I guess, seems only yesterday that I saw the front page post about someone playing with this, and it turns out that it's 3 years later and now there is a working port of the sega-cd speech into Kilrathi Saga!

First up, this is incredible - I've only played a little bit, but I love it! Inspired and curious about how it was working - I decided to take a look at how hard a similar scripting exercise would be for WC2 (I know that EmuMusicFan did some sterling analysis on doing this the 'proper' way by modding the game files). I've managed to identify the memory address where onscreen text is printed during cutscenes and where the game stores the playercharacter names (oddly it stores them twice, once for the savegame, and once for the cutscenes, which will be relevant later...)

From that, I managed to whip up a quick prototype WC2 script file that does what I need here, but identified a couple of issues with the engine/scripting logic (at least as I understand it) as it stands:

Firstly, WC2 uses the same memory address for the cutscene text, as it uses for the 'distance to target' during flight. That means that the console gets spammed during flight, and that the script will be parsed to some degree almost continually during gameplay (which seems to be causing performance impacts).
Logically, I can use the HasWord function in Destro's scripting to check for this - if the string contains ' km' then we can skip the rest of the script - but that doesn't help for the ' m' case. Destro, would it be possible to have an 'EndsWith' string test (without the code I can't be sure, but I don't think there is one)?

Secondly, in the scripting I had real issues with the string replacement - specifically in wanting to check for the below example from the 1st mission debriefing:
If|String|[String.Buffer1]|=|No, I'm not. That patrol scared me, s{[String.Name]}

For those curious, these are the memory addresses I have found so far:
0x0049345E - Mission Series (1-12) - updated during flight and on game-load - indicates Last (current) Mission flown
0x00493460 - Mission Number (0-3) - updated during flight and on game-load - indicates Last (current) Mission flown
0x00499EF8 - Player callsign
0x00499F10 - Player surname
0x00499F28 - Player firstname
0x005D1C41 - Cutscene text - Technically the address is 0x005D1C40 but both CheatEngine and the peek seem to fail to spot this as a string most of the time - using 0x005D1C41 just means that you chop off the first character. This is also the distance to current target counter address during spaceflight.
0x005D3C10 - Mission Letter (e.g. A/B/C/D) - updated during flight - updated during flight (not on game load) - indicates last (current) mission flown
0x005D3C41 - Mission Series Name (e.g. Gwynedd/Niven/Ghorah Khar)- updated during flight - updated during flight (not on game load) - indicates last (current) mission flown



0x0A33A1C1 - During spoken cutscenes this address, or one near it gets the original dos text - it can move though.
Also, I forgot to mention, in terms of the KM issue. I've noticed that there are two buffers that hold the onscreen text in WC1 as well. Buffer1 is mostly used but Buffer2 is used randomly for in-flight coms and some other things. Then reused for flight speed.

I remedied this a bit by creating a string state check.. This checks the data and compares it to the data previously in the string. If the data is the same, the String state is 0. If there is a change to the content, it's a 1.

//|Check the Buffers|
Peek|[Peek.WC1]|PeekAtString|[PEEK_ADDRESS_1]|[String.Buffer1]|
Peek|[Peek.WC1]|PeekAtString|[PEEK_ADDRESS_2]|[String.Buffer2]|

//|Check the string states for a change in data|
String|[String.Buffer1]|State|[Num.CheckState1]|
String|[String.Buffer2]|State|[Num.CheckState2]|

//|Add the two numbers together (Into [Num.CheckState1])|
Num|[Num.CheckState1]|N+|[Num.CheckState2]|

//|If they both equal 0. No change in the text. Break current script and script 0|
If|Num|[Num.CheckState1]|=|0|
BreakScriptZero|
BreakScriptCurrent|
EndIf|

This helps a lot so you are not reading and comparing every singe cycle. If there is no change to the string, it breaks the loop. Having an EndsWith will improve things a lot, but the above helps. At least with WC1 it only updates every few seconds rather than every millisecond. Again, I'm not sure how often WC2 updates the speed so this might not be that helpful.

Cheers.
 
Thanks for the detailed replies!

I'm doing everything in textpad, and copying the text straight from the peeked text in the console, so hopefully there's no codebase issues with ' or spacing, but I'll double check.

Re the script checks, I checked WC1 per your suggestion, it's not doing the same - WC1 does seem to fill the text block with 40 then the range to nearest target (wingman perhaps?) While WC2 is just populating it with the text of the range to Nav/Target (i.e. what is displayed on the ships HUD) so the consoles for the two cases look like below. I can't find a second coy of briefing text to compare with, nor can I find a second copy of the target range (perhaps can find a range to objects and check multiple, but that's going to be a lot of logic I think). I'll keep poking though.


WC1
WC1.png

WC2 (ignore that i'm chopping the first character in Buffer1)
WC2.PNG


The Main Script has:

SUBSCRIPT|2|
If|Num|[Num.Selection2]|=|0|//|RUN WING COMMANDER 2|
Debug|Out|WC2 Run|
Audio|Play|[Audio.SNDFX.2]|[Channel.Dummy]|
Destroy|Asset|Games/WingLoader/AssetsWC1.pro|//|Load WC1 Assets|
Destroy|Definitions| //|Destroy all definitions
Load|Definitions|Games/WingLoader/Definitions.pro|//|Reload global definitions|
Load|Definitions|Games/WingLoader/WC1Definitions.pro|//|Load WC1 Definitions|
//|Script needs to be before assets so some reason. it causes first run to not work but only after new menu style.... not sure why.
Load|Asset|Games/WingLoader/AssetsWC1.pro|//|Load WC1 Assets|
Load|Script|100|Games/WingLoader/WC2Script.pro|//|Load WC2 Script|
Run|Exe|\Games\Wing2\Wing2_wcdx.exe|
Debug|Delay|500|
Peek|[Peek.WC1]|Attach|Wing Commander II: Vengeance of the Kilrathi|
Peek|[Peek.WC1]|SetAddress|[PEEK_ADDRESS_1]|0x005D1C41|100|
Peek|[Peek.WC1]|SetAddress|[PEEK_ADDRESS_2]|0x0A33A1C1|100|
Peek|[Peek.WC1]|SetAddress|[PEEK_ADDRESS_NAME]|0x00499F28|20| //|Player FirstName
Peek|[Peek.WC1]|SetAddress|[PEEK_ADDRESS_CALLSIGN]|0x00499F10|20| //|Player SurName
Peek|[Peek.WC1]|SetAddress|[PEEK_ADDRESS_SYSTEM]|0x00499EF8|20| //|Player CallSign
EndIf|

Then WC2Script is:
SCRIPT|100|//|PEEK|
//|Peek to see if the display text has changed.|
Peek|[Peek.WC1]|PeekAtString|[PEEK_ADDRESS_1]|[String.Buffer1]|
Peek|[Peek.WC1]|PeekAtString|[PEEK_ADDRESS_2]|[String.Buffer2]|
Peek|[Peek.WC1]|PeekAtString|[PEEK_ADDRESS_NAME]|[String.Name]| //Not yet renamed...
Peek|[Peek.WC1]|PeekAtString|[PEEK_ADDRESS_CALLSIGN]|[String.Callsign]| //Not yet renamed...
Peek|[Peek.WC1]|PeekAtString|[PEEK_ADDRESS_SYSTEM]|[String.System]| //Not yet renamed...

String|[String.Buffer1]|State|[Num.CheckState1]|
String|[String.Buffer2]|State|[Num.CheckState2]|
Num|[Num.CheckState1]|N+|[Num.CheckState2]|

If|Num|[Num.CheckState1]|=|0| //This is doing nothing useful at present as Buffer2 <> Buffer1 in WC2.
BreakScriptZero|
BreakScriptCurrent|
EndIf|


If|String|[String.Buffer1]|HasWord| km|
BreakScriptZero|
BreakScriptCurrent|
EndIf|

//Note this will break any string containing 'hello maverick'
If|String|[String.Buffer1]|HasWord| m|
//Poke|[Peek.WC1]|PokeAtText|[PEEK_ADDRESS_1]|mBlah| //|TEST|
BreakScriptZero|
BreakScriptCurrent|
EndIf|

Audio|StopChannel|[Channel.Voice]|

If|String|[String.Buffer1]|=|tardate 2665.112|
Load|Audio|[Audio.Buffer]|48000|Games/WingLoader/Voice/Funeral/funpc0009.wav|
Audio|Play|[Audio.Buffer]|[Channel.Voice]|
BreakScriptCurrent|
EndIf|

If|String|[String.Buffer1]|HasWord|ell, it's another exciting day at Action Central.|
Load|Audio|[Audio.Buffer]|48000|Games/WingLoader/Voice/Funeral/funmi1.wav|
Audio|Play|[Audio.Buffer]|[Channel.Voice]|
//Poke|[Peek.WC1]|PokeAtText|[PEEK_ADDRESS_1]|Blah| //|TEST|
BreakScriptCurrent|
EndIf|

//Doesn't seem to work - why not? - using Poke to get a text prompt if the search worked - I forget which string has the firstname in...
If|String|[String.Buffer1]|HasWord|o, I'm not. That patrol scared me, s{[String.Name]}|
Poke|[Peek.WC1]|PokeAtText|[PEEK_ADDRESS_1]|Blah1| //|TEST|
EndIf|
If|String|[String.Buffer1]|HasWord|o, I'm not. That patrol scared me, s{[String.Callsign]}|
Poke|[Peek.WC1]|PokeAtText|[PEEK_ADDRESS_1]|Blah2| //|TEST|
EndIf|
If|String|[String.Buffer1]|HasWord|o, I'm not. That patrol scared me, s{[String.System]}|
Poke|[Peek.WC1]|PokeAtText|[PEEK_ADDRESS_1]|Blah3| //|TEST|
EndIf|

BreakScriptZero|
BreakScriptCurrent|

EndScript|
 
Shoving a framerate limit upon the WC2 cutscenes would be nice, stinger never got time to do that and he left wcdx open for anyone to pick it up
 
Thanks for the detailed replies!

I'm doing everything in textpad, and copying the text straight from the peeked text in the console, so hopefully there's no codebase issues with ' or spacing, but I'll double check.

Re the script checks, I checked WC1 per your suggestion, it's not doing the same - WC1 does seem to fill the text block with 40 then the range to nearest target (wingman perhaps?) While WC2 is just populating it with the text of the range to Nav/Target (i.e. what is displayed on the ships HUD) so the consoles for the two cases look like below. I can't find a second coy of briefing text to compare with, nor can I find a second copy of the target range (perhaps can find a range to objects and check multiple, but that's going to be a lot of logic I think). I'll keep poking though.


WC1
View attachment 13379
WC2 (ignore that i'm chopping the first character in Buffer1)
View attachment 13381

The Main Script has:

SUBSCRIPT|2|
If|Num|[Num.Selection2]|=|0|//|RUN WING COMMANDER 2|
Debug|Out|WC2 Run|
Audio|Play|[Audio.SNDFX.2]|[Channel.Dummy]|
Destroy|Asset|Games/WingLoader/AssetsWC1.pro|//|Load WC1 Assets|
Destroy|Definitions| //|Destroy all definitions
Load|Definitions|Games/WingLoader/Definitions.pro|//|Reload global definitions|
Load|Definitions|Games/WingLoader/WC1Definitions.pro|//|Load WC1 Definitions|
//|Script needs to be before assets so some reason. it causes first run to not work but only after new menu style.... not sure why.
Load|Asset|Games/WingLoader/AssetsWC1.pro|//|Load WC1 Assets|
Load|Script|100|Games/WingLoader/WC2Script.pro|//|Load WC2 Script|
Run|Exe|\Games\Wing2\Wing2_wcdx.exe|
Debug|Delay|500|
Peek|[Peek.WC1]|Attach|Wing Commander II: Vengeance of the Kilrathi|
Peek|[Peek.WC1]|SetAddress|[PEEK_ADDRESS_1]|0x005D1C41|100|
Peek|[Peek.WC1]|SetAddress|[PEEK_ADDRESS_2]|0x0A33A1C1|100|
Peek|[Peek.WC1]|SetAddress|[PEEK_ADDRESS_NAME]|0x00499F28|20| //|Player FirstName
Peek|[Peek.WC1]|SetAddress|[PEEK_ADDRESS_CALLSIGN]|0x00499F10|20| //|Player SurName
Peek|[Peek.WC1]|SetAddress|[PEEK_ADDRESS_SYSTEM]|0x00499EF8|20| //|Player CallSign
EndIf|

Then WC2Script is:
SCRIPT|100|//|PEEK|
//|Peek to see if the display text has changed.|
Peek|[Peek.WC1]|PeekAtString|[PEEK_ADDRESS_1]|[String.Buffer1]|
Peek|[Peek.WC1]|PeekAtString|[PEEK_ADDRESS_2]|[String.Buffer2]|
Peek|[Peek.WC1]|PeekAtString|[PEEK_ADDRESS_NAME]|[String.Name]| //Not yet renamed...
Peek|[Peek.WC1]|PeekAtString|[PEEK_ADDRESS_CALLSIGN]|[String.Callsign]| //Not yet renamed...
Peek|[Peek.WC1]|PeekAtString|[PEEK_ADDRESS_SYSTEM]|[String.System]| //Not yet renamed...

String|[String.Buffer1]|State|[Num.CheckState1]|
String|[String.Buffer2]|State|[Num.CheckState2]|
Num|[Num.CheckState1]|N+|[Num.CheckState2]|

If|Num|[Num.CheckState1]|=|0| //This is doing nothing useful at present as Buffer2 <> Buffer1 in WC2.
BreakScriptZero|
BreakScriptCurrent|
EndIf|


If|String|[String.Buffer1]|HasWord| km|
BreakScriptZero|
BreakScriptCurrent|
EndIf|

//Note this will break any string containing 'hello maverick'
If|String|[String.Buffer1]|HasWord| m|
//Poke|[Peek.WC1]|PokeAtText|[PEEK_ADDRESS_1]|mBlah| //|TEST|
BreakScriptZero|
BreakScriptCurrent|
EndIf|

Audio|StopChannel|[Channel.Voice]|

If|String|[String.Buffer1]|=|tardate 2665.112|
Load|Audio|[Audio.Buffer]|48000|Games/WingLoader/Voice/Funeral/funpc0009.wav|
Audio|Play|[Audio.Buffer]|[Channel.Voice]|
BreakScriptCurrent|
EndIf|

If|String|[String.Buffer1]|HasWord|ell, it's another exciting day at Action Central.|
Load|Audio|[Audio.Buffer]|48000|Games/WingLoader/Voice/Funeral/funmi1.wav|
Audio|Play|[Audio.Buffer]|[Channel.Voice]|
//Poke|[Peek.WC1]|PokeAtText|[PEEK_ADDRESS_1]|Blah| //|TEST|
BreakScriptCurrent|
EndIf|

//Doesn't seem to work - why not? - using Poke to get a text prompt if the search worked - I forget which string has the firstname in...
If|String|[String.Buffer1]|HasWord|o, I'm not. That patrol scared me, s{[String.Name]}|
Poke|[Peek.WC1]|PokeAtText|[PEEK_ADDRESS_1]|Blah1| //|TEST|
EndIf|
If|String|[String.Buffer1]|HasWord|o, I'm not. That patrol scared me, s{[String.Callsign]}|
Poke|[Peek.WC1]|PokeAtText|[PEEK_ADDRESS_1]|Blah2| //|TEST|
EndIf|
If|String|[String.Buffer1]|HasWord|o, I'm not. That patrol scared me, s{[String.System]}|
Poke|[Peek.WC1]|PokeAtText|[PEEK_ADDRESS_1]|Blah3| //|TEST|
EndIf|

BreakScriptZero|
BreakScriptCurrent|

EndScript|

Ok. I think I understand what's up.

The output in the debug console is actually being sent by the PeekAtString functions. I have a std::cout in there so I could confirm the data that was in the Buffer and only update when there was a change to the content of the buffer. It was there to confirm the buffer against my scripting if a line didn't fire due to a spelling error or something like that. So basically, there is no way "currently" to avoid the spamming of km in the debug console as it is hard coded. It was never an issue with WC1 as it only updated every once in a while but it looks like with WC2 it's a bit of an issue. I will change this hard coded function into a script for the next update. That way you can choose what to display to the console via the scripting.

Your HasWord break looks good!

If|String|[String.Buffer1]|HasWord| km|
BreakScriptZero|
BreakScriptCurrent|
EndIf|

It should be working and breaking "your" scripts so it doesn't run through all the If statements unnecessarily. It unfortunately will still output to the console at the moment though as it happens when the buffer is read. :( But you can confirm your function is firing using the following

Debug|Out|Your output comment!|

That should manually print text to the debug console. I use it to find misbehaving code or to confirm a function is called. If it is placed inside your HasWord| function you can confirm that it is triggering as true.

//|This will spam the console even more but will confirm if the function is working.|
If|String|[String.Buffer1]|HasWord| km|
Debug|Out| km has been found. Breaking Scripts!|
BreakScriptZero|
BreakScriptCurrent|
EndIf|

Be careful with HasWord " m" as that will catch anything with " m" in it including things like "too much" or " maniac" etc.. if you're trying to catch the callsign I'd recommend using s{[String.Callsign]} or if I read your scripting correctly s{[String.System]} as you've yet to rename it.

If|String|[String.Buffer1]|HasWord|s{[String.System]}|

Lastly with PokeAtText.... The buffers that we are reading from the game are more like the left overs from the game drawing text on the screen. The game looks at a table, grabs the chuck from the game files and stores it in the buffer then sends it to be rendered. It's all part of the same cycle in the game and doesn't wait for anything so by the time we can read it and can modify it, it has already been sent to be rendered. No amount of Poking can change that unless we can find the render call in the game itself... Maybe someday. You can Poke at the Player Name & Callsign to rename your character but the Dialogue is pretty much untouchable at the moment. You could map a ton of memory address for the location of each line of text and change those before the game reads it but it's easier to just modify the game files themselves... That's what i did using the WC Mission Editor to removed paragraph lines and some double spaces etc... rather than Poke them in. Again not sure how WC2 works as I've not explored that game much.

Hopefully that all makes sense. I've been putting together some documentation about the Scripting but any suggestions for functions I'm happy to hear them. :D
 

Version 0.90 - (Engine Re-Write) Released!


While working on the WC3 Video's I realized I needed to fix a lot of things. For starters, I had poor memory management, leaks and some nesting going on. At the time I was more focused on getting Wing Loader released, I just applied some hacks and patches to get by as I knew the problem was at the core of how the engine worked. So, I began a full engine re-write and it is now ready for release! There are so many under the hood changes it's almost a completely different program, but thanks to my scripting, as the end user you shouldn't notice much of a difference, (Besides ram usage down from 831mb to 98mb!) :p

There is a folder structure changed due to Windows being very angry with folder levels and running executables (Error 267)


I've updated the original post with the latest version and instructions. Enjoy!
https://www.wcnews.com/chatzone/threads/wing-loader-ks-wcdx-loader-voice-over-mod.30387/post-415220

v0.90 (There really are too many fixes and upgrades to mention but here are a few notable changes)
- Lowered OpenGl Requirements from 4.6 to 3.2.
- Core Engine rename to SE_Engine.

- Timers are now threaded!
- Some functions will not play nicely inside threads, for example, stopping and unloading an asset like a video file, while it's still playing on another thread (or Main) will result in a crash. You can get around things like that using Script|Enable so it will then run the script on the next pass. This will setup multi-threading to the scripting which is the plan for the near future.)
- Removed If|Timer as it was not needed anymore due to Threaded Timers.
- Definitions fix as they were not including 0, which is a valid value.
- Fixed an error in my global scripts using an old script context. Scene|Camera|Use|ID| when It should have been Scene|Camera|ID|
- VSync option in pref.ini was not really working and just activating a framelimiter. Disable true VSync for now, it is acting as a FrameLimiter switch.
- Added a FrameLimit option to SE_Pref.ini to set desired FPS.
- Complete engine re-write!
- Dynamic memory resizing without needing to re-compile to adjust or set max size (Which is what the engine was previously doing).
- Resolved a ton of nesting issues. Specifically with If functions.
- Huge improvement to memory usage!
Idle from 214mb to 78mb!
Load from 831mb to 98mb!
- There is still a little bloating when re-loading scripts. I know what the issue is but don't have a fix at the moment. It's pretty small and should cause an I'm able to resolve that.
- Code is now organized much better now and separated into two groups, SE_Wrap & SE_Engine.
- SE_Wrap is for basically doing everything.
- SE_Audio.h & SE_Audio.cpp controls audio
- SE_Texture.h & SE_Texture.cpp controls textures.
etc..
- SE_Engine is how it all gets put together for scripting.
- Working on putting SE_Wrap on GitHub after a bit more cleanup and documentation. Just note that I'm not a professional coder, just a hobbyist messing around. It's still a work in progress but feedback is always welcome.
- Scripts now renamed from .pro to .SE to adhere to new naming structure.
- Modified the folder structure a bit. It now will read the startup.SE script in the Data directory, Data/startup.SE rather then Games/WingLoader/startup.pro. From there startup.SE will point to all the necessary Scripts.
- Camera LookAt had a bad if statement (= not ==) :( Camera movements at now work at high framerates. A little overshoot at extreme framerates but not too bad.

- Thanks to @Madman for the suggesting following fixes.

- Fixed an issue with PokeText. There was a +1 to the address's position.
- Added an EndsWith subfunction to If|String| To identify strings that end in a word to solve WC2 spamming the buffer with " km"

If|String|[String.Buffer1]|EndsWith| km|
BreakScriptZero|
BreakScriptCurrent|
EndIf|

- Added this to all WC1 scripts as well.

- Removed the hard coding buffer output to the debug window. Now scripting can call the output using.
Debug|PeekUpdate|[Peek.WC1]|[PEEK_ADDRESS_1]|[String.Buffer1]|
- Output now begins and ends with | Buffer's often have extra spaces at the beginning and end of lines and this can make matching difficult. You can see this by hovering over the bunks to "Save this campaign ".
 
Out of interest for the WC3 video do you plan to create an external window like WC4 and P DVD patches or to inject the image into the 640*480 window?

Due to the low quality of the source footage full HD doesn't really improve things, infact 640*320 is pretty much the sweet spot where you don't notice the upscaling issues (also the window switching often causes issues for people). I feel like outputting at that resolution; the same pixel density as the game, might make it feel like a more coherent package.
 
Thanks!

Also on another note, I made up a little patch that will upgrade the GOG version of WC3 to the Kilrathi Saga version. Trying to make Wing Loader work with current purchase options available for the games.

https://mega.nz/file/pa4HgbgZ#0ZV-krjG2kyG0bStmcFfUQHyjOfQbAQl9AqghMetHCU
I already made a WC3DOS to win patch over the old KS patch years ago, also DgVoodoo2 works better with WC3 than the old Ddraw hack @Bandit LOAF in fact it works better due to reshade support for crt shaders since guest became the new go2 for it

 
Out of interest for the WC3 video do you plan to create an external window like WC4 and P DVD patches or to inject the image into the 640*480 window?

Due to the low quality of the source footage full HD doesn't really improve things, infact 640*320 is pretty much the sweet spot where you don't notice the upscaling issues (also the window switching often causes issues for people). I feel like outputting at that resolution; the same pixel density as the game, might make it feel like a more coherent package.
Hey Pedro! It is an overlay similar to WC4 and WCP DVD Patches. But so far, it is much more reliable than those patches in terms of stability. (I can't even get WCP DVD videos to work correctly on my GOG install) and let's not forget the WC4 audio and all the codec issues. Currently I'm still trying to get my head around ffmpeg and how to structure the scripting to get WC3 all mapped out effecently.

I might look into injecting into the framebuffer someday but not currently. Though I agree if it was all integrated it would be a much better experience overall.
 
I already made a WC3DOS to win patch over the old KS patch years ago, also DgVoodoo2 works better with WC3 than the old Ddraw hack @Bandit LOAF in fact it works better due to reshade support for crt shaders since guest became the new go2 for it

Nice. I haven't used dgvoodoo2 with WC3 but I have with games like Omikron I think, and was quite impressed. I'll give it a try and see how it works, Thanks.

I made the patch on a whim and didn't really look to see it if already existed or not. I remembered that the Kilrathi Saga came with an WC4 upgrade to windows and it got me thinking if I could do the same for WC1 WC2 and WC3 for the gog editions and just include the required files as a patch as there are no purchase options for the KS versions of the games. I'll give your's a look. Thanks Bitterman!
 
Nice. I haven't used dgvoodoo2 with WC3 but I have with games like Omikron I think, and was quite impressed. I'll give it a try and see how it works, Thanks.

I made the patch on a whim and didn't really look to see it if already existed or not. I remembered that the Kilrathi Saga came with an WC4 upgrade to windows and it got me thinking if I could do the same for WC1 WC2 and WC3 for the gog editions and just include the required files as a patch as there are no purchase options for the KS versions of the games. I'll give your's a look. Thanks Bitterman!
my config
 

Attachments

For some reason in wine, since I updated to .90, WingLoader can't seem to find the Wing1_wcdx.exe and SM1_wcdx.exe executables. It finds everything else just fine but with those two I get this error
SE_Log: SE_Error: SE_EXE Failed to start process at C:\Program Files\WingLoader\WC1\Wing1_wcdx.exe | 267 | Ensure the File Location is correct.
SE_Log: SE_Error: SE_EXE Failed to start process at C:\Program Files\WingLoader\WC1\SM1_wcdx.exe | 267 | Ensure the File Location is correct.

I'm very much at a loss as to why that is. I checked those locations, as far as wine is concerned in the prefix, and the files are indeed there and that they were capitalized in that way (Maybe it was a linux case sensitivity thing, but it never cared before). They even launch with wine when called directly. Again, everything else works. Even the SM1 video. Also it worked before the update to v0.90.

Ive tried different wine versions and proton versions. All had the same issue.
 
Thanks for your work Destro - VERY much appreciated.

Regarding the upgrade-patch (GOG->KS):
I can confirm, that dgVoodoo2 is the much better alternative (ddhack should be marked deprecated).
 
Thanks for your work Destro - VERY much appreciated.

Regarding the upgrade-patch (GOG->KS):
I can confirm, that dgVoodoo2 is the much better alternative (ddhack should be marked deprecated).
You're welcome and thank you!

I have messed around a bit with dgVoodoo2 and WC3, I has some issues with window focus that my WC3 HD Videos mod needs to work correctly. I'm still playing with settings hoping to be able to use it as an option. I also did find that DDraw is in active development and the latest version 6.0 works great with WC3. It even has a GUI to change the settings.
https://github.com/FunkyFr3sh/cnc-ddraw/releases
 
For some reason in wine, since I updated to .90, WingLoader can't seem to find the Wing1_wcdx.exe and SM1_wcdx.exe executables. It finds everything else just fine but with those two I get this error



I'm very much at a loss as to why that is. I checked those locations, as far as wine is concerned in the prefix, and the files are indeed there and that they were capitalized in that way (Maybe it was a linux case sensitivity thing, but it never cared before). They even launch with wine when called directly. Again, everything else works. Even the SM1 video. Also it worked before the update to v0.90.

Ive tried different wine versions and proton versions. All had the same issue.
Damn that 267 error.

I run v0.90 on my steam deck and it works fine with proton but that error can be touchy. I added Wing Commander Prophecy and Secret Ops into the Loader and "Wing Commander Prophecy" is an invalid folder while "Wing Commander Secret Ops" is valid.

I believe it has something to do with converting std::string to LPCSTR and LPCWSTR. The action of reading and coping the string changes some tiny bit somewhere.

That said, v0.91 I'm working on will focus on fixing that issue, among other things. I've got it to read Wing Commander Prophecy's folder without error and running the games in Fullscreen mode. It's still a WIP but... Here is the updated WingLoader.exe give that a try and let me know if that fixes your issue.

https://mega.nz/file/FCw1GQ4L#YJZUxpESaPJTmLL1pRwzvLjBSGDTLIGSjRLHV3djkCc
 
Damn that 267 error.

I run v0.90 on my steam deck and it works fine with proton but that error can be touchy. I added Wing Commander Prophecy and Secret Ops into the Loader and "Wing Commander Prophecy" is an invalid folder while "Wing Commander Secret Ops" is valid.

I believe it has something to do with converting std::string to LPCSTR and LPCWSTR. The action of reading and coping the string changes some tiny bit somewhere.

That said, v0.91 I'm working on will focus on fixing that issue, among other things. I've got it to read Wing Commander Prophecy's folder without error and running the games in Fullscreen mode. It's still a WIP but... Here is the updated WingLoader.exe give that a try and let me know if that fixes your issue.

https://mega.nz/file/FCw1GQ4L#YJZUxpESaPJTmLL1pRwzvLjBSGDTLIGSjRLHV3djkCc
Also I just noticed a second issue you reported.... That I can't spell... I will correct the spelling of "Insure" in v0.91. 😝
 
Thank you! I should be able to give it a try tonight and let you know how it goes. No worries, neither can I! Though while you are at it you can fix the random capitalization of "File Location." We aren't speaking German 😁
 
Thanks! Well that got the excutables to load, but I don't get the CD voices anymore with that version. Everything is in the correct place still. So not sure whats up. Also another thing. when I open up in the wine console, this message keeps flooding the screen. Not sure what it means. Happened in the .90 as well. Not sure about before.
SE_Log: SE_Error: SE_String ID Does Not Exist or is Empty | SE_String_Is(1) | En
sure it was created and not destroied.
 
Back
Top