Commandos – Behind Enemy Lines Resolution Fix
Unofficial STEAM support:
Scroll to the bottom and find the comment by Tonelotto with instructions on how to get it going.
You can also use this patch to carry out the Locale hack described here.
Skip straight to the bottom of this post if you just want the application!
An Introduction to the game
A friend and I recently stumbled across the Commandos Ammo Pack ('Behind Enemy Lines' and it's expansion pack 'Beyond The Call Of Duty') at Good Old Games.com and we just couldn't resist downloading it. It did cost US$5.99, but that's absolutely chicken feed when compared to the awesomness of this game.
It's an old game, created in 1999, and could handle resolutions up to 1024x768 for single player; but for multiplayer the resolution was fixed at 640x480. I google'd around a little and saw that one person on a forum had created the Mysoft - Commandos Loader v0.8 which seemed to hoist the application in to memory and then hacked around with variables. I wasn't sure this was the best method and had the main Commandos EXE in IDA Free before too long.
I'd read that it used DirectDraw/3D and started searching for the appropriate functions. Before long I had the AdjustWindowRectEx, DirectDrawCreate and other functions under the microscope. I then opened the EXE up in OllyDbg and started slapping breakpoints everywhere. Before long I'd noticed the pattern:
push 10h push 1E0h push 280h
This seemed to be popping up everywhere and co-incidently 280h x 1E0h = 640x480 pixels... the default for the game. I then found code that set the resolution based on those shown in the video settings menu and then the game was doing what I told it.
After a little more google'ing I found that someone else had already gotten to this point. Ferdinand had the hacks there to change the resolutions, but did not have the final piece to ensure that re-loading the game brought the resolution back.
After a little more disassembling I found that the resolution was being loaded at startup from a file on disk... this turned out to be "COMANDOS.CFG" in My Documents. The exact line from the config was:
.SIZE [ .INITSIZE 2 ]
From the config it was obvious that the game was using 'index 2' from the resolution list. Of course, it also meant that it knew how to decipher that '2' to a real resolution from the list in the code. After a little forward and reverse searching from the file loading to the resolution setting I came to the switch statement in the code which had the values hard-coded. I now had 3 points per resolution setting in the code that needed to be changed if I was to write my own utility.
Commandos Resolution Hack Alpha 1
I hadn't liked anything that was already available to do this and so I chose to wrote my own. The application loaded the EXE into memory, read out the resolutions stored, audited that they were all in sync and then allowed the user to select a new resolution per slot. If the resolutions weren't the same then you would get a warning, but this would have been corrected on the next resolution hack.
This worked fine, but I found it pointless to specify four separate resolutions when you only really needed to specify one. I was more in for the challenge of allowing all four to change, rather than the practicality.
Testing and more bugs
So, it all worked... I then closed the game, re-opened it and found that it loaded up at 1024x768 instead of the 1680x1050 resolution I had set. I closed it again and looked at the configuration file; the setting had indeed changed back to '2' instead of '4'... but I hadn't touched it! I then loaded the game again and it was back to 1680x1050... closing and opening brought it back to 1024x768... the flip-flop continued.
So... what did this seem to mean? I had overlooked the storage of the resolution configuration. If the indexed resolution was read from the file, then it would have to be written back as an index. I went back in to the disassembler and searched for anything relating to writing 'SIZE' into the configuration file. The logic in the game was then obvious: it carried out an "if less than X but greater than Y" across the 'stock' resolutions and then stored the relevant index. This complicated my approach and confirmed that I really should only bother adjusting the 'fourth' resolution in the list. There was no point allowing the user to re-order the resolutions as this code then wouldn't work. The fourth resolution would need to be the only one customisable and the value must be greater than the third resolution at 800x600.
Commandos Resolution Hack Alpha 2
So, with this in mind, I wound the application down to just editing one resolution that had to be higher than 800x600. This meant that the internal configuration saving would work and the user would just have to select the final resolution in the list. Note that this only affected single player... the multi player resolution would still be a separate setting.
Everything was now working great... except the drawing issues above 1024 resolutions...
Drawing bugs
So, the game obviously wasn't meant to be played with a horizontal resolution greater than 1024 pixels; rendering artifacts started appearing when higher resolutions were used. Fortunately, the game is quite dynamic when it comes to rendering the screen and menus. Trawling through the code I could see that it was trying to find a BMP that matched the resolution, even using the resolution as the file name. Ferdinand had also worked this out and even has a list of assets downloadable for higher resolutions.
Commandos stores all of its graphical assets in a file named 'WARGAME.DIR' and references this when the game loads. I started looking into modifying this file via my program but realised it would be wuite a task to decipher and re-pack. Fortunately, some clever fellows across the world have created the necessary tools to extract these files. DirExtractor allows us to expand the DIR files and, once in the Commandos directory, the game itself will actually use the extracted versions if you remove the WARGAME.DIR file. This then meant that I could use my app to call DirExtractor, extract the files and then modify them where required to ease the majority of graphical glitches.
Required Graphical Modifications
- A single change to the fourth resolution string in DATOS\MISIONES\GLOBAL.STR to whatever the custom resolution has been set to. This can be found by searching for the token OVI4 and then replacing the string following.
- The creation of the menu background. This has to be a Bitmap file named MENU####.BMP where the #### is the horizontal resolution of the screen.
- Build a WAD file for the game-play interface. This WAD is named via the resolution (i.e. 1024X768.WAD) and contains values that tell the game how to render the interface. I created a one-size-fits-all file that ensures that the graphics are wide/long enough for the screen resolutions (max 1920x1920) and the application simply renames the file and ensures that it is available to the game.
A final glitch
There was only one drawing issue remaining after this... any resolution over 1400 meant that maps thinner than the overall monitor width would not re-draw the areas that they could not cover. You can see this in the following screen shots.
Fortunately you can press '+' and '-' in-game to zoom in and out. What this meant was that the user could stop the map from clipping by adjusting the zoom. I took this as a suitable workaround at the time.
Smeared resolution?
It seems that some laptop resolutions are a little out-of-whack. I previously had a Samsung Ultranote with resolution of 1366x768, but windows reported that it could also run at a resolution of 1360x768.
It turns out that if you choose the wrong one (although it may seem the right one if that's your current windows resolution) that you'll get the following display:
Simple fix: Try another resolution... it'll work eventually!
And you thought it was going to be this easy?
So, I had the app working great for the modification of the GOG version of the EXE. It turns out that there are many more versions in the wild. It also gets worse as there is another patch here that fixes up a whole lot of other issues in the game. Fortunately it seems that the EXE from the above link is the exact same as the EXE from GOG? Either way, I've tested it and my hack works on it perfectly.
Due to the above, I started a list of EXEs for the game and then began deciphering them (as I knew the basic items to change) to allow my application to work with them.
Items in bold are those that come from GOG.com.
Game | Version | File Size | Supported |
---|---|---|---|
Commandos - BEL Demo | 2,452,992 bytes | Works.. | |
Commandos - BEL German | v1.0 | 2,469,376 bytes | Works, Asks for CD (Language issues, I'd imagine) |
Commandos - BEL Spanish | v1.0 | 2,469,376 bytes | Works? |
Commandos - BEL Spanish | v1.05 | 2,469,888 bytes | Works? |
Commandos - BTCOD Spanish | ? | 2,696,600 bytes | Works? |
'Sold Out' | v1.1 | 2,479,104 bytes | Works fine. Speed issues with game (known issue) |
GOG.com Ammo Pack | v1.1 | 3,715,072 bytes | Works perfectly! |
Commandos Ultimate Fix | v1.1 | 3,715,072 bytes | Works perfectly! |
Commandos - Beyond the call of duty | ? | 3,133,440 bytes | Works perfectly! |
Commandos - BEL Russian | ? | 2,470,400 bytes | Works fine. Speed issues with game (known issue) |
Commandos - BTCOD Russian | ? | 2,968,576 bytes | Works fine. Speed issues with game (known issue) |
Commandos - SINP | v2.3 | 2,482,688 bytes | Works perfectly. |
Commandos - SINP Chinese | v2.3 | 2,313,216 bytes | Does not write out chosen resolution to configuration file. You should only change the resolution via this hack! |
My application was then built to determine the EXE via file size (of course, this isn't fool-proof) and then hack appropriately.
Commandos - Beyond The Call Of Duty
So, this was just an update to the main game... turns out the code was slightly different, but still workable with my current program structure. After about 6 hours debugging all was working! Enjoy!
Commandos Hack v1.2
The final release contains the following features:
- Support for all versions known above. (Note that the Demo and German versions don't actually save their configs to disk; we therefore hack the initial startup resolution.)
- Resolution list options based on monitor capabilities.
- Both EXE and WARGAME.DIR are backed up.
- A one-size-fits-all menu background has been included.
- German file encoding is preserved when the text is changed.
- Resolution menu text shows the selected resolution.
- Compatibility mode now checked to allow proper resolution and disable scaling.
- The Locale hack from here has also been added.
Download the application here.
And you can also download the .NET source code here.
Meanwhile, if you got a lot out of this app, then feel free to donate!
And that's a wrap... go use every pixel your monitor can produce and play the game!
Creating two more MAME Controllers
I've since realised that, after building the original two MAME Arcade Controllers, I've needed two more to really re-live the old classic games. I suppose one more would've been OK for games like Rampage, but TMNT, Simpsons Arcade and Sunset Riders need all four players... so... the following lists the relevant information to build controllers 3 and 4.
Sunset Riders
It turns out F12 saves snapshots of MAME games... so I couldn't resist...
Key Mapping
Below lists the mapping for the two new controllers to be created. I went ahead and used the default keys from MAME plus whatever else was free...
NOTE: Out-of-the-box MAME does not specify buttons 4,5,6 for Players 3 and 4! You can set these very easily in the 'default' config by using the basic MAME GUI (run mame.exe without any command line options)...
Button | Player 3 | Pins | Player 4 | Pins |
---|---|---|---|---|
Joy UP | I | 6, 22 | Numpad 8 | 8, 22 |
Joy LEFT | J | 7, 21 | Numpad 4 | 4, 23 |
Joy DOWN | K | 6, 21 | Numpad 2 | 8, 21 |
Joy RIGHT | L | 5, 21 | Numpad 6 | 14, 23 |
Button 1 | R-CTRL | 13, 20 | Numpad 0 | 8, 24 |
Button 2 | R-SHIFT | 10, 20 | Numpad . | 14, 24 |
Button 3 | ENTER | 1, 20 | Numpad ENTER | 12, 21 |
Button 4 | / | 3, 26 | Numpad + | 12, 22 |
Button 5 | . | 5, 20 | Numpad - | 12, 26 |
Button 6 | , | 6, 20 | Numpad * | 12, 20 |
Player Button | 3 | 16, 19 | 4 | 11, 19 |
Insert Coin | 7 | 7, 19 | 8 | 6, 19 |
Building the other two controllers
I bought cheaper controls for these two... but to no real benefit. I did save AUD$10, but I don't really like the button microswitches. The buttons aren't as tall and they do look cheaper. They're also a lot less 'clickier'. On the positive side: the short-stick joysticks feel nicer during game-play and are a lot more sensitive.
The build of these two followed the exact same path as the previous two (see the previous post) using cheap Microsoft Keyboards. It turns out that they were now a different colour (White vs. Black) and I decided to replace my current keyboards on other computers with the new ones. I therefore used a standard black MS Keyboard for Player 3 and a 'Microsoft Comfort Curve' for Player 4.
The MS Comfort Curve had a completely different matrix and the circuit board inside was much easier to solder to. Either way, the process was still the same in determining the pins and then wiring everything up. Testing was made a lot easier as well as I found the below testing applications to work out exactly what I'd messed up :)
After running out of solder and then later butane I got them together and we gave them a go. All went well until Players 1 and 4 hit magical key combinations... It seems that, although the keyboards are separate devices, you can still produce an ALT-ENTER or CTRL-ALT-DEL by having each player pressing each of the keys separately. This has since been remedied in the final section of this post!
Testing your new creation
I found out that Windows 7 (and possibly Windows Vista?) but not Windows XP has the mskey.exe keyboard test application (I have since found out that you can Download the Intellisense Software here which contains this application.) It came in very handy until I plugged 12v into a USB hub and cooked the HDD in my TV-pc (luckily only the HD, the PSU managed to protect everything else!) and lost my Windows 7 install. For Windows XP systems (of which all my computers are now back to) I downloaded and used the PassMark KeyboardTest application. At first, the Google search result made the application look like a typing tutor, but after downloading I realised it was exactly what I needed.
MAME Configuration
So, as previously mentioned, MAME doesn't specify Buttons 4,5,6 for Players 3 and 4 by default. I suppose there aren't many games that have more than 3 buttons for all four players? I can't think of any... but my memory is quite hazy as to what 4-player games Combat Zone had back at Tuggeranong Hyperdome.
Either way, we've specified them above and we also need to make sure they map to the correct player/keys in MAME. Here's a snippet for Player 4 in my default.cfg:
<input> <port type="P4_JOYSTICKRIGHT_UP"> <newseq type="standard">KEYCODE_6PAD KEYCODE_8PAD</newseq> </port> <port type="P4_JOYSTICKRIGHT_DOWN"> <newseq type="standard">KEYCODE_2PAD KEYCODE_6PAD</newseq> </port> <port type="P4_JOYSTICKLEFT_UP"> <newseq type="standard">KEYCODE_4PAD KEYCODE_8PAD</newseq> </port> <port type="P4_JOYSTICKLEFT_DOWN"> <newseq type="standard">KEYCODE_2PAD KEYCODE_4PAD</newseq> </port> <port type="P4_BUTTON4"> <newseq type="standard">KEYCODE_PLUSPAD</newseq> </port> <port type="P4_BUTTON5"> <newseq type="standard">KEYCODE_MINUSPAD</newseq> </port> <port type="P4_BUTTON6"> <newseq type="standard">KEYCODE_ASTERISK</newseq> </port> </input>
As you can see, the default.cfg only adds in controls we have overridden... the others must be hard-coded into mame.exe. Drop the configuration file in to your mame/cfg directory (note that you may want to check your file first as you could have other customisations!) and then you'll have the appropriate settings ready to go!
Diagonals and 4-Way Joysticks
Right, I couldn't work out why I couldn't get 'Steve' in 'Sunset Riders' to shoot on the diagonal... usually this was carried out by holding down the Up and Left (or Right) keys on the Keyboard, but it wasn't working. I scoured the internet and initially thought it was an issue with the way I'd wired up the joysticks.
It turns out that MAME has added in the ability to assign a separate key for the diagonal movements. This is great if you have an 8-way Joystick with actual individual microswitches on the diagonals, but I have a 4-way and I cannot, without logic circuits, wire up another key to activate when two of the direction microswitches are closed. I did actually start thinking of logical OR/AND gates to fire the specific keys when the direction goes diagonal, but this would require re-work on the sealed controllers. :)
So, I went in to MAME and then mashed the keyboard on the configuration screen. It turns out that you can assign multiple keys to a direction. This then made life easy... I would make Player 1's "Up/Left" key 'Up' + 'Left' instead of the 'I' key on the keyboard.
After testing this new configuration I realised it wasn't actually MAME that was the problem! It turns out that there was an actual physical issue with the initial two joysticks I bought when compared to the second two...
Arcade Joystick differences
So, the diagonals worked on the new joysticks I bought... they seemed to be a lot happier at pressing two directions at once. Unfortunately, the original joysticks only really wanted to go one way at once... After a little investigation it turns out that the plastic spacer/washer that slides onto the joystick stem was not wide enough (circumference-wise) to actually activate two microswitches at once. I'd also misplaced the original 'extra' components from the intial build and therefore didn't know if wider spacers existed? Either way, I had to make the spacers fatter to ensure that diagonal movements could be easily made.
In the end I cheated and used duct tape around the spacer at the bottom of the stick to make it's circumference wider. This meant it was more keen to press two microswitches at once and the world was a happier place!
The sticky-tape-fix was then tested for Player 1 and worked. I then did the same for Player 2 but had the controller back open in seconds after playing Bomberman as it turns out it was now too happy to go diagonal instead of 4-Way. Removing just over one layer of tape from the spacer on the joystick balanced out the circumference vs. microswitch equation and made the joystick much more responsive. Your mileage will vary with how much tape is required based on the sensitivity of the microswitches and how much travel/space you have between them and the center stick.
The verdict: Windows short-cut keys kill gameplay
The next step was to reconfigure any keys on the controllers to not use any modifier key (CTRL,ALT,SHIFT,ENTER) so as to not activate shortcuts during gameplay. When Player 1 and Player 4 pressed certain buttons (specifically ALT-ENTER) the MAME window would restore and, of course, it was possible that all four players could do a perfectly orchestrated CTRL-ALT-DEL and throw Windows XP to the Task Manager.
To do this I had to re-solder buttons on Controllers 1, 2, 3 and 4 to the nearest free keyboard button. Fortunately the Numpad had more than enough nearby keys free and there are still letters of the alphabet unused near Player 1's keys. The layout of buttons on the keyboard did not have to make sense to a human user and so any free buttons were used if the wiring was easier.
The Final Re-Mapping
So, in the end I re-mapped the modifier keys and also removed the duplicates between Players 2 and 3. Edits are in bold... NOTE: You must UNMAP 'T' from the 'Other Controls' area otherwise when Player 1 hits Button 2 you may receive a 'Tilt' message and game restart.
Button | Player 1 | Pins | Player 2 | Pins |
---|---|---|---|---|
Joy UP | UP | 12, 24 | R | 11, 22 |
Joy LEFT | LEFT | 12, 26 | D | 16, 21 |
Joy DOWN | DOWN | 4, 26 | F | 11, 21 |
Joy RIGHT | RIGHT | 8, 26 | G | 11, 24 |
Button 1 | E | 16, 22 | A | 18, 21 |
Button 2 | T | 11, 23 | S | 17, 24 |
Button 3 | C | 16, 20 | Q | 18, 22 |
Button 4 | V | 11, 20 | W | 17, 23 |
Button 5 | Z | 18, 20 | U | 7, 22 |
Button 6 | X | 17, 20 | O | 5, 22 |
Player Button | 1 | 18, 19 | 2 | 17, 19 |
Insert Coin | 5 | 11, 25 | 6 | 7, 25 |
Button | Player 3 | Pins | Player 4 | Pins |
Joy UP | I | 6, 22 | Numpad 8 | 8, 22 |
Joy LEFT | K | 6, 21 | Numpad 4 | 4, 23 |
Joy DOWN | J | 7, 21 | Numpad 2 | 8, 21 |
Joy RIGHT | L | 5, 21 | Numpad 6 | 14, 23 |
Button 1 | B | 11, 26 | Numpad 0 | 8, 24 |
Button 2 | N | 7, 26 | Numpad . | 14, 24 |
Button 3 | M | 7, 20 | Numpad / | 8, 20 |
Button 4 | / | 3, 26 | Numpad + | 12, 22 |
Button 5 | . | 5, 20 | Numpad - | 12, 26 |
Button 6 | , | 6, 20 | Numpad * | 12, 20 |
Player Button | 3 | 16, 19 | 4 | 11, 19 |
Insert Coin | 7 | 7, 19 | 8 | 6, 19 |
This configuration overwrites the diagonals for Player 1 and adds/corrects all of the other mappings listed above.
And this is now to be tested in gameplay... I've done the re-wiring and have tested individually but have done no actual thrashing with MAME.
The End
And that's that... it was enough fun playing with Player 1 and 4 making sure not to mash the same buttons at the same time... but it should be a lot better now once I organise the beer and the people to play... will see how we go!
Usual suspects: DERM58
May 7th saw the Diesel Electric Rail Motor Preservation Association of Victoria Inc run another tour with their prized DERM58. This time it was out on the freight BG to Seymour with a return trip via the passenger line through Essendon. I woke up at sparrows-fart on Saturday to see it on the viaduct over the Maribyrnong river near McIntyre Loop.
The weather, as per Melbourne, was playing hard-to-get and it was bloody freezing before the sun came up. There was a lovely pink sunrise which I tried to capture before realising I'd remembered the XPT arrival times wrong... I heard it coming and just managed to get a dodgy shot.
The next train wasn't for an hour... so I entertained myself by finding a good location where I could use the tele-lens and the available sunlight. It turns out that on the high-way side there is a nice incline where you can get above track-level with a great view of the viaduct. You can also see the signals in both directions to know when something is approaching.
After being entertained by quite a few noisy birds...
...I was greeted by howling NRs on a superfreighter heading north...
The XPT was to return next... it did and it wasn't hanging around. Fortunately the sun came out to ensure I could match a shutter speed with the train's speed.
It was then about a 40minute wait for the DERM to arrive... during this time there were multiple acts of stupidity by various forms of wildlife.
And then the DERM arrived...
The next train was to be a southbound superfreighter in an hour. I decided that the weather wasn't getting any better and so started making my way back to the car. Of course, if anyone had looked in the long shots of the DERM58, you'd have seen that the southbound signal was at clear... these things are completely hard to trust, but it turns out that if you see a green in this area then you should hang around.
I'd made it half-way back to the car when I heard a very nice howl from the north... as I turned around QR came hurtling across the bridge with an awesome lashup of LDP-009 + 6005 + 6002 + LDP-008.
Supposedly it held pace all the way into Sunshine and scared a track gang working around the corner... I'm not surprised.
I headed to Kensington in the afternoon to see the DERM return via the passenger lines. There's a nice spot near the Allied Mills where you can see the lines off to the West as well.
And that was that... it was cold and wet and any further chasing would have been futile. I'm still learning the correct approach with photographing under low light conditions, but am pretty happy with how the above shots came out.
Playart HO Scale Series 0 Shinkansen (4-Car Set)
As luck would have it, I managed to stumble across this set a model train/toy swap meet over the weekend. I'd never seen anything by Playart before and was not expecting to see a HO Scale Shinkansen. I purchased a bit of track with it as I had only had N Scale on hand.
I gave it a quick run on some flex-track with a 12v supply I had lying around. It was noisy, but for something of its age, moved quite well.
Both end cars pick up power through their front bogie and both have internal lighting. It seems to be a standard incandescent light bulb and it actually lights up the entire nose of the train... makes it look very toy-ish... I would actually stop this from happening if I was to run these full-time, but I have no HO layout.
Either way, this is a cool set... and I was very impressed to find out that some company (I believe they are French?) made this back in the 70s/80s. As written underneath, they were made in Hong Kong.
It turns out that the company also made a Series 485 EMU which reminds me of the Kita Kinki in Kansai.
There was also an Endou Vista 3-Car EMU in N Scale which I couldn't recognise (looked like something Kintetsu or Meitetsu...) which I'll try and pick up next time... information on it is here, here, here and here. And yes, it's Kintetsu.