Author Topic: Hacking Lemmings Revolution  (Read 47594 times)

0 Members and 1 Guest are viewing this topic.

Offline GuyPerfect

  • Posts: 363
    • View Profile
Hacking Lemmings Revolution
« on: April 13, 2012, 12:54:51 AM »
Investigation into the problems with Lemmings Revolution on Windows 7 turned up some unfortunate results regarding how the game was designed to work with DirectX 7. The short description is that as DirectX continued to change and be updated, specific behaviors of DirectX 7 were either deprecated or fixed, resulting in a Lemmings game that has been falling apart over time.

Since we're basically looking at a program that relies on a deprecated specification, fixing it will be a time-consuming endeavor. Basically what's required is that we create our own versions of the DirectX DLLs that behave in the way DirectX 7 did back in the day, then feed them to the Lemmings Revolution EXE in place of the modern DLL files.

Lemmings Revolution fortunately has a fairly rudimentary construction, so it's not necessary to re-implement the entire DirectX API. It doesn't even use Direct3D proper (instead deferring to DirectDraw's basic 3D functionality), so the subset of DirectX that needs to be replaced for Lemmings Revolution to function properly is pretty much this:
If we can produce a couple of replacement DLLs, say ldraw.dll and lsound.dll, we can circumvent the problems cropping up due to DirectX's updates and pull Lemmings Revolution back into the realm of things that will continue to work according to current API specs.

Such an initiative I would refer to as DirectL. (-:

EDIT: Renaming thread

Offline GuyPerfect

  • Posts: 363
    • View Profile
Re: DirectL
« Reply #1 on: April 13, 2012, 03:10:56 AM »
After some research, I was able to determine that the IUnknown interface's QueryInterface() method is all sorts of handy for getting pointers to things without needing to import DLL functions directly. When used on an IDirectDraw (which inherits IUnknown) with IID_IDirect3D as the GUID, an IDirect3D is returned. From there, we can make or get an IDirect3DDevice, which is where the 3D stuff comes from. All without loading direct3d.dll.

There's a good dozen or so ways that all end up at the same place. So in order to properly determine exactly what Lemmings Revolution does to get to where it needs to be, we'd need to just let it link against a custom DLL and see what it tries to do. Once all of the features the game actually uses are implemented, the rest of it can be left unimplemented.

Offline mobius

  • Posts: 2752
  • relax.
    • View Profile
Re: DirectL
« Reply #2 on: April 13, 2012, 06:50:06 PM »
later today, I'm gonna have a look at this again. I'll play the game and mess around and see if I can figure anything out. (I need to read over your posts again first)
everything by me: https://www.lemmingsforums.net/index.php?topic=5982.msg96035#msg96035

"Not knowing how near the truth is, we seek it far away."
-Hakuin Ekaku

"I have seen a heap of trouble in my life, and most of it has never come to pass" - Mark Twain


Offline ccexplore

  • Posts: 5311
    • View Profile
Re: DirectL
« Reply #3 on: April 13, 2012, 08:01:39 PM »
The fact is, the game is not completely toast on Win7, at least when I tried on my Win7 laptop.  The main issues I recall running into is no sound and music, and text display problems where the text is invisible.

So rather than trying to fix everything (and given the game's release history, there are probably some bugs that happen even on the original OS [Win95/Win98] the game was released for), one could focus first on the sound/music issue and then the text display problem, and finally deal with the rest later if ever.

Offline GuyPerfect

  • Posts: 363
    • View Profile
Re: DirectL
« Reply #4 on: April 13, 2012, 09:07:19 PM »
Precisely what I was thinking. With a replacement for the old DirectSound bindings, the game would be back up into the "pretty good" state, since the menu elements seem to come back after you've played a level.

I really doubt the game is any fancier than simple stereo. There isn't a lot to audio that would have to be implemented.

Offline GuyPerfect

  • Posts: 363
    • View Profile
Re: DirectL
« Reply #5 on: April 15, 2012, 06:30:54 PM »
Image-heavy post alert! Dial-up users beware! *Snicker* Yeah, dial-up. Anyway...

Here's what the title screen is supposed to look like:



It looks this way in the original release, on Windows XP, in Wine and even on Windows 7 after you've played a level.

Before playing a level, none of the alpha channels on Windows 7 seem to be activated. This is what the title screen looks like:




Proceeding into the level select screen, this is what we see:



This is how it looks in the original release and in Wine.

In XP, we get this:



And in Windows 7, before playing a level:



Aaaand after playing a level:



By the looks of it, XP is somehow sending the wrong color instructions to DirectX for the text shadow, while Windows 7 just isn't sending any at all.


Within the game, Windows XP, Windows 7 and Wine all render *something* incorrectly. After trying for two days to get Windows 98 with DirectX 7 up and running on something, I had to resort to a Google Images search to get an idea of how the game was supposed to look in the original release:



Wine does it pretty good, but the icons on the right-hand side of the screen have funky colors, and the texture filtering on "Let's Go!" is set to point resize:



XP begins to degrade even further, with different funky icon colors and all of the foreground elements turned cyan, although the "Let's Go" is blinear:



Lastly, Windows 7 just doesn't even try anymore and renders all the foreground elements (except the animated Lemming icons) in pure black:




After completing a level, you get a summary of how you did:



That's how it looks in the original release and in Wine.



XP's is kinda hard to read. It's real dark.



7's, unsurprisingly, is even harder to read because it's the same color as the background.

Offline Mr. K

  • Posts: 793
  • Former admin, always Lemmings fan
    • View Profile
    • Wafflenet
Re: DirectL
« Reply #6 on: April 17, 2012, 12:12:57 AM »
Heh, those screenshots took me back many years.  I got Lemmings Revolution at Christmas once and my PC ran it with similar graphical problems (the blank results screen, and the level selection icons didn't appear at all) because the Riva TNT card it had was too old.  Took about a year until I upgraded to a Radeon 7500 to play it without randomly clicking on the level select trying to hit the right icon by chance.

Offline mobius

  • Posts: 2752
  • relax.
    • View Profile
Re: DirectL
« Reply #7 on: April 17, 2012, 03:10:36 AM »
have you played it recently? We're trying to get it running on Windows 7 properly (with little luck so far)

could graphics and/or sound cards be a key?
everything by me: https://www.lemmingsforums.net/index.php?topic=5982.msg96035#msg96035

"Not knowing how near the truth is, we seek it far away."
-Hakuin Ekaku

"I have seen a heap of trouble in my life, and most of it has never come to pass" - Mark Twain


Offline GuyPerfect

  • Posts: 363
    • View Profile
Re: DirectL
« Reply #8 on: April 17, 2012, 04:30:36 AM »
*Looks at the first post of the thread*

The problem lies mainly in the driver architecture of Windows XP and Windows 7, which is different from the one in Windows 98. There are probably also some changes that came about in DirectX 8, so the game wouldn't have worked properly for very long.

I don't know exactly what Revolution is trying to do at this point, but I know I can fill in the blanks and do something else to make it look and sound right.

Offline Mr. K

  • Posts: 793
  • Former admin, always Lemmings fan
    • View Profile
    • Wafflenet
Re: DirectL
« Reply #9 on: April 17, 2012, 01:10:54 PM »
have you played it recently? We're trying to get it running on Windows 7 properly (with little luck so far)

could graphics and/or sound cards be a key?
I haven't tried playing it in a very long time, in fact, last time I did I was using a Pentium II with Windows 98 (my aforementioned system).  However, perhaps the similarities can be notable.  Lemmings Revolution says it needs a DX7-compatible card.  Perhaps just as my old Riva TNT didn't implement some DX7 features (it is a DX5-level card), neither does DX9 or Windows 7's version, DX9Ex.  I haven't yet had time to go deep into looking at what features might have been deprecated between DX7 and 9, but my first guess would be DirectDraw since we seem to mostly have issues with the 2D portions of the game (menus, UI, etc).  As far as I can tell, DirectDraw has been deprecated since DX8 and was merged into Direct3D, which might be what's causing headaches.

Offline ccexplore

  • Posts: 5311
    • View Profile
Re: DirectL
« Reply #10 on: April 19, 2012, 11:20:14 AM »
Okay, with regards to sound in Lemmings Revolution, I have some good news.  I think I've figured out the problem (or one of the problems anyway) some people might have with sound on Win7 (and probably Vista), and it can be fixed yourself without having to patch or change the program in any way! 8)

(Please refer to attached screenshots.)

Step 1:  find the sound icon at bottom right of your screen (circled orange in screenshot).  Click on icon with your right mouse button (ie. "right-click"), then select "Playback Devices" from the popup menu.

Step 2:  a popup window appears, showing a list of all "devices" you can play audio to on your computer.  You might think your computer only has one output device you can play sounds to, but apparently on Vista and Win7, a lot of computers might have this "high-definition audio device" support that provides two or more outputs for sound, like my screenshot.

The irony however is that other than the (presumably working) audio device you are currently using (shown with green checkmark in the popup), the other ones listed probably won't work for you.  For example, in my screenshot, the other one listed as "Digital Audio (S/PDIF)", I have never gotten sound to work playing out of that device.  (I later looked up Wikipedia and S/PDIF seems to be some fancy connector to connect to Hi-Fi equipment, so maybe I just don't have such a fancy setup to take advantage.)

Now the problem turns out to be that, rather than using the working device that the system has selected for playback (ie. the one with green checkmark in the popup), Lemmings Revolution apparently has its own way of picking which audio device to use to play sound, and unfortunately its choice is often the wrong one (eg. the S/PDIF on my computer which I can't get sound out of).  This turns out to be the reason for no sound. :XD:

The solution?  Just disable all the other audio devices on the computer that you aren't using anyway.  Thus the final step.

Step 3:  For each device other than the working one with green checkmark, right-click on the device entry.  A popup menu appears, select "Disable".  Just as depicted in screenshot.

The device entry should either go away in the list, or become grayed out with accompanying "disabled" in the text next to the device icon.  Repeat this until you are left with just the one device with the green checkmark (ie. the one currently in use that actually plays sound).  Now click OK to dismiss the popup.

[note: if you make a mistake, or somehow need to re-enable those secondary devices at a later time, you can right-click on a blank space in the list and select menu option "show disabled devices", and then use the right-click menu to re-enable any device you previously disabled.  The right-click menu also lets you specify which device to use by default for playback (ie. where the green checkmark goes), in case you messed that up.]

===============

After I did that on my computer (leaving only the "Speakers" device enabled), sound now works on Lemmings Revolution!  Hurray! :thumbsup:  [disclaimer: obviously your mileage may vary, but no harm trying at least!]

Of course the graphics are still messed up.  I'm afraid that won't have any easy solutions. :(

Offline GuyPerfect

  • Posts: 363
    • View Profile
Re: DirectL
« Reply #11 on: April 19, 2012, 08:45:06 PM »
Very nice find, ccexplore!

I loaded Revolution in a debugger and stuck a breakpoint on DirectSoundCreate(). This told me where in the EXE that function was being called, and I had a friend tell me exactly how the stdcall calling convention passes its parameters. What I landed on was this:



That's Lemmings Revolution.exe in a hex editor. That 8B 00 highlighted is the instruction responsible for selecting the pointer of the sound driver passed to DirectSoundCreate():
Code: [Select]
8B 00    MOV EAX, DWORD PTR [EAX]
What I did was change it to 31 C0, which is an XOR instruction on EAX with itself, aka setting it to zero:
Code: [Select]
31 C0    XOR EAX, EAX
Loading up the game in Windows 7 works like a charm now, at least as far as audio is concerned.

An edited EXE file is attached to this post with this fix.

Offline GuyPerfect

  • Posts: 363
    • View Profile
Re: DirectL
« Reply #12 on: April 19, 2012, 11:00:45 PM »
So I said to myself, "Self, most of the graphics work. Really the only problems are the alpha thing, the colors, and that the 5-4-3-2-1 don't appear. Why implement the entire DirectX API when I could just override the parts of it necessary to get it working correctly again?"

With that, I started development on an LDRAW.DLL to replace DDRAW.DLL, and told the EXE to load from that. It's currently just a passthrough, but the game works just fine with it and I can do some investigating to nail down exactly what Lemmings is doing wrong and reinterpret it on the way through to the graphics hardware.

DirectDrawEnumerate() does not actually use the DirectX API function of the same name. Instead, it simply returns a fake video device called "Lemmings Forum Compatibility Hack" that slyly returns a driver GUID of NULL, meaning when the game uses it, it will always use the default display driver. At some point I want to test this in a VM to see if it works now.

DirectDrawCreate() currently just calls the DirectX function, but the beauty here is that I can do some processing on the IDirectDraw that comes back--redirecting some of its methods to functions of my own design so I can intercept the faulty commands as they head toward DirectX from the application.

Both functions produce console output, just so I could make sure they were working correctly. When I reconfigured the EXE file's subsystem, I found that Take 2 had some debug messages of their own in there too. O-:


Offline GuyPerfect

  • Posts: 363
    • View Profile
Re: DirectL
« Reply #13 on: April 20, 2012, 05:41:14 AM »
Okay, about to turn in for the night, but progress is coming along. After much fidgeting with the internal workings of the COM interface, I was able to set up a system to plug my own functions into DirectX so I can process the parameters as a pass-through. QueryInterface() is a curious beast indeed, but I've got it trapped in my little web too. (-:<

Just before posting this, I got the game to successfully boot while trapping the IDirectDraw4 objects that the game ultimately uses for drawing... I think. I'll have to look up some of the GUIDs, but here's the latest console output:

Code: [Select]
DirectL - DirectDrawEnumerate()
DirectL - DirectDrawCreate() -- Created IDirectDraw 0x006A4668
DirectL - IUnknown::QueryInterface(0x006A4668,
    9C59509A-39BD-11D1-8C4A-00C04FD930C5) -- Created IDirectDraw4 0x006A4688
DirectL - IUnknown::Release(0x006A4668)
DirectL - IUnknown::QueryInterface(0x006A4688,
    BB223240-E72B-11D0-A9B4-00AA00C0993E)
DirectL - IUnknown::QueryInterface(0x006A4688,
    6C14DB80-A733-11CE-A521-0020AF0BE560)
DirectL - IUnknown::QueryInterface(0x006A4688,
    9C59509A-39BD-11D1-8C4A-00C04FD930C5)
DirectL - IUnknown::Release(0x006A4688)
DirectL - DirectDrawCreate() -- Created IDirectDraw 0x006BC288
DirectL - IUnknown::QueryInterface(0x006BC288,
    9C59509A-39BD-11D1-8C4A-00C04FD930C5) -- Created IDirectDraw4 0x006BC2A8
DirectL - IUnknown::Release(0x006BC288)
DirectL - IDirectDraw4::SetDisplayMode(0x006BC2A8, 640, 480, 16, 0, 0x00000000)
DirectL - IUnknown::QueryInterface(0x006BC2A8,
    BB223240-E72B-11D0-A9B4-00AA00C0993E)
DirectL - IUnknown::QueryInterface(0x006BC2A8,
    6C14DB80-A733-11CE-A521-0020AF0BE560)
DirectL - IUnknown::QueryInterface(0x006BC2A8,
    9C59509A-39BD-11D1-8C4A-00C04FD930C5)
DirectL - IUnknown::Release(0x006BC2A8)
Initialising Memory Card311,15339, Allocated at 023A5298
10661,558577, Allocated at 05880020
311,15339, Allocated at 023A8E90
10661,558577, Allocated at 05DD0020
10661,558577, Allocated at 05E60020

EDIT:
The GUIDs in the snippet above correspond with the following interfaces:

9C59509A-39BD-11D1-8C4A-00C04FD930C5 = IID_IDirectDraw4
BB223240-E72B-11D0-A9B4-00AA00C0993E = IID_IDirect3D3
6C14DB80-A733-11CE-A521-0020AF0BE560 = IID_IDirectDraw

Offline mobius

  • Posts: 2752
  • relax.
    • View Profile
Re: DirectL
« Reply #14 on: April 20, 2012, 09:01:31 PM »
great work on this so far. I hope you can solve the graphics issues :thumbsup:

here's something else I forgot to mention earlier;
(taken from GameFAQs to prove I'm not the only one experiencing this problem):

** Level 058 ("The high dive") is unplayable due to a glitch in the program
      that causes Lemmings Revolution to shut down immediately when you try to
      load it. A patch on the Internet is supposed to fix this, but it doesn't
      work either. Fortunately, thanks to the way you open up two levels for
      every one level you beat, you can easily play around this one and beat
      all the others.

http://www.gamefaqs.com/pc/914154-lemmings-revolution/faqs/30084

the exact message that comes up is:
fatal error:
textures\Cylinder\el4_kf_l\OUT_el4_kf_l_7_0Hi.bmp


(note: there's no 'missing this file' or anything just the above) I hope that helps

I can't verify if that patch actually works or not, I can't find it. But I think this is only Windows 7 because I could always play that level before

---
also, thought I'd mention that curiously, the bomber count down numbers are not black like the rest of the text, but rather it doesn't show up at all. you can see a "graphic" above the lemming in certain situations (example: when it's in front of other text like the save number (I think))
everything by me: https://www.lemmingsforums.net/index.php?topic=5982.msg96035#msg96035

"Not knowing how near the truth is, we seek it far away."
-Hakuin Ekaku

"I have seen a heap of trouble in my life, and most of it has never come to pass" - Mark Twain