VOGONS

Common searches


Help me fix interstate '76 gold?

Topic actions

  • This topic is locked. You cannot reply or edit posts.

First post, by Serious Callers Only

User metadata
Rank Member
Rank
Member

If you ever played I76 patched to gold you should know there is a absolutely horrendous problem with it on the transition of mission 12-13. It always crashes except if you exchange a dll (I76shell.dll) for a older version from a earlier patch. (and then you must change it back, because of unspecified "problems").

Normally i would just play the previous patch, but gold is the only version that has glide support (much nicer with dgvoodoo).

I've been looking at the original exe file with olly debugger a little.
It crashes at a function that starts at 0x00467470. Setting a breakpoint there before it crashes, reveals that it seems to be part of the memory filesystem of the game, since many resource names pass there before the one that crashes. That happens because the argument to it is apparently a null pointer (and is interpreted as a zero when reading the memory, with predictable results).

This is the function:

CPU Disasm
Address Command Comments

00467470 MOV EAX,DWORD PTR SS:[ARG.1] ; i76_without_cd_music.00467470(guessed Arg1)
00467474 MOV ECX,DWORD PTR DS:[EAX+3BC]
0046747A MOV EAX,DWORD PTR DS:[ECX+70]
0046747D RETN

Ignore the name of the exe that is other hacking i made - but the problem is in the original exe too.

The problem appears to happen tenth time or 11th that the function is run after clicking next mission. I think that the caller function is the earliest one in the executable. Obviously the problem comes from outside

I wonder if anyone more experienced than i can help me fix this.

I give a link to the save games in hope that is so(the error is in save 2 - mission 13 when you click next mission. If you follow the normal procedure of replacing the i76shell.dll for the older version, save one works if you finish the mission with it, but not on save 2 - that doesn't need to finish a mission).

BTW on wine i had to provide arguments -glide (maybe -d3d works too?) to be able to debug. Software mode appears to paint over everything, or maybe it's dgVoodoo fixing this?

Anyway would be really nice to make this work without immersion breaking hacks.

http://www.megaupload.com/?d=DA0BLC4W
(has the save before the error (2) using original gold dll, and the save without the error (3) using the 1.083 dll).

Last edited by Serious Callers Only on 2010-08-22, 09:57. Edited 4 times in total.

Reply 2 of 29, by Serious Callers Only

User metadata
Rank Member
Rank
Member

It's a virtual file system i think - even if it was that - how could i know where the error is?
I put a breakpoint on all callers of the function. In this particular case all were invoked by the earliest offset possible (in the exe).
0040F90E
It crashed on the 11th call. All calls had valid arguments except the last. As you can see on the function it follows the pattern
arg.1 + 0x3bc + 0x70, and returns on eax. This is all valid in all calls except for the last. Returns:
1: 0C1B11B8 wauto_3a
2: 0C1B4910 wauto_6a
3: 0C1B77C8 wauto_3a (Strange)
4: 0C1B98D8 wauto_3a (maybe it's the opponents model?)
5: 0C1BC060 wauto_0a
6: 0C1BF700 wauto_1a
7: 0C1C2898 wauto_9a
8: 0C1C5978 wauto_4a
9: 0C1C89A0 wauto_4a
10: 0C1CC548 wauto_1a
11: 00000070 ????

To see what the other dll file does different, i'm going to try to play the mission with it, save (since i can't use the other save with the dll file) and repeat the procedure. Maybe it won't help much, the dll files appear significantly different on diff.

Any way to set a condition on olly - ie break on 11th pass?

Reply 3 of 29, by Serious Callers Only

User metadata
Rank Member
Rank
Member

BTW the alternative dll file is in the 1.083 patch - it is unzippable, so you don't need to install it.

Both the gold and that are here:
http://www.howgeek.com/2009/08/20/interstate- … feedback-patch/

Last edited by Serious Callers Only on 2010-08-21, 23:35. Edited 2 times in total.

Reply 4 of 29, by Serious Callers Only

User metadata
Rank Member
Rank
Member

The exe didn't change, only the associated dll.
With I76SHELL.DLL 2 output:
1: 0C6F11B8 wauto_3a
2: 0C6F4910 wauto_6a
3: 0C6F77C8 wauto_3a
4: 0C6F98D8 wauto_3a
5: 0C6FC060 wauto_0a
6: 0C6FF700 wauto_1a
7: 0C702898 wauto_9a
8: 0C705978 wauto_4a
9: 0C7089A0 wauto_4a
10: 0C70C548 wauto_1a
11: 0C70FF80 wauto_1d

(none else, game continues).

Last edited by Serious Callers Only on 2010-08-21, 23:52. Edited 1 time in total.

Reply 6 of 29, by Serious Callers Only

User metadata
Rank Member
Rank
Member

I want to find out now what is the code that is supposed to write those references to memory. It should be what is wrong right? Problem is setting a memory breakpoint at the start of the program doesn't work (says there is no such offset yet, logical i guess). Going to try to way for the first call before seeing the next references, but i'm not hopeful. If i did that i would load all needed resources at once, before setting them up.

Reply 7 of 29, by Serious Callers Only

User metadata
Rank Member
Rank
Member

Here is something i don't understand:
On the crashing call ESI is pushed as the argument of the function. It has the adress
0C2C2D98
The function above copies this value to EAX. All ok by now. But then when it tries to do:
MOV ECX,DWORD PTR DS:[EAX+3BC]

0C2C2D98+3BC turn out to be == 00000000
I don't understand the problem here.

Reply 10 of 29, by Serious Callers Only

User metadata
Rank Member
Rank
Member

Returning to the main executable for a moment searching for "wauto" finds only one string :
wauto_0, nothing else similar.
I'm going to attempt to modify the failing function (jump to a empty space, replicate it there), by testing for the "wrong" value and returning a another one. Is it safe to treat this values as absolute?

Reply 13 of 29, by Serious Callers Only

User metadata
Rank Member
Rank
Member

I need to use CMP right?

I just did and damn. The game crashes later with another similar function. Seems that that data wasn't the only one being accessed. Maybe i should modify the caller function instead.

Last edited by Serious Callers Only on 2010-08-22, 13:27. Edited 1 time in total.

Reply 16 of 29, by Serious Callers Only

User metadata
Rank Member
Rank
Member

Too messy. There are other larger subfunctions in the caller's code that use the same pointers. It's not a "real" fix anyway.
Here is the parent, there is only one jump so i only give the offset of that:

MOV EAX,DWORD PTR SS:[ARG.1]     ; ASCII "t13pp02" (edit: at the time)
PUSH EBX
PUSH ESI
PUSH EDI
PUSH EAX ; /Arg1 => [ARG.1]
CALL 00467440
ADD ESP,4
MOV ESI,EAX
PUSH ESI ; /Arg1
CALL 00466E20
ADD ESP,4
MOV EDI,EAX
PUSH ESI ; /Arg1
CALL 00467470
ADD ESP,4
MOV EBX,EAX
PUSH ESI ; /Arg1
CALL 00467480
FLD DWORD PTR DS:[EBX+0C]
FADD DWORD PTR DS:[EAX+0C]
ADD ESP,4
PUSH ESI ; /Arg1
FSTP DWORD PTR SS:[ARG.1]
CALL 00467450
FLD DWORD PTR SS:[ARG.1]
FADD DWORD PTR DS:[EAX+0C]
ADD ESP,4
PUSH ESI ; /Arg1
FSTP DWORD PTR SS:[ARG.1]
CALL 00467460
FLD DWORD PTR SS:[ARG.1]
FADD DWORD PTR DS:[EAX+0C]
ADD ESP,4
FMUL DWORD PTR DS:[4BC738] ; FLOAT 7.840000
FCOM DWORD PTR DS:[4BC710] ; FLOAT 0.0
FSTSW AX
TEST AH,01
JE SHORT 0040F972
FSTP ST
MOV DWORD PTR DS:[EDI+0A994],3F800000
POP EDI
POP ESI
POP EBX
RETN
0040F972 | FDIV DWORD PTR DS:[ESI+110]
FSQRT
D99F 94A90000 FSTP DWORD PTR DS:[EDI+0A994]
POP EDI
POP ESI
POP EBX
RETN

It seems ESI is the argument of the functions that crash. ESI is copied from the return of the first call there, that itself takes the function argument. What i'm worried about changing the argument itself, is that if this is a important game part, not just textures, but voice voice something. If it is from generic enemy nº 5 ok, but that doesn't seem likely since there is only one on that list. I'm going to try it anyway.

Last edited by Serious Callers Only on 2010-08-22, 14:49. Edited 1 time in total.

Reply 18 of 29, by Serious Callers Only

User metadata
Rank Member
Rank
Member

BTW the function that gets EAX for the ESI parameter basically does:
ARG.1 offset + 70.

The argument that fails with the normal dll is "vehscn".

There are two files named vehscn in the game dir:
vehscn.vcf and vehscn.vsf
(maybe the old dll version can deal with these files and not the new? - maybe they are in the wrong dir for the gold patch?!?)

If i modify the argument pointer to refer to the previous "t13pp02" location (not edit the memory, edit the register), it crashes on the same place (still inside the function, just stepping).
The return of the first call supports this:
02BF6438 -> 02CEE2C0 (previous invocation)
02BF6438 -> 02CEED98 (altered register invocation)
The value of the memory location the first function fetches the result changed.
(Edit: this can't be relevant, since the 02BF6438) would change anyway since it is based on the first argument - non-sequitur. However i learned the memory locations didn't change, at least once, so i'm going to try to set a breakpoint like i say bellow).

Possibly a memory write breakpoint there can find the real (probably dll) bug.

Or maybe it's just the files in the wrong location. Going to test that now.

Last edited by Serious Callers Only on 2010-08-22, 15:43. Edited 2 times in total.

Reply 19 of 29, by Serious Callers Only

User metadata
Rank Member
Rank
Member

grep -a -o -z -b -r 'vehscn' .
finds me this:

./i76shell.dll:268768:vehscn ./i76shell.dll:268780:vehscn ./i76shell.dll:270850:vehscn ./i76shell.dll:270870:vehscn ./i76shell.d […]
Show full quote

./i76shell.dll:268768:vehscn
./i76shell.dll:268780:vehscn
./i76shell.dll:270850:vehscn
./i76shell.dll:270870:vehscn
./i76shell.dll:270884:vehscn
./i76shell.dll:284418:vehscn
./i76shell.dll:284438:vehscn
./i76shell.dll:284452:vehscn
./i76shell.dll:286866:vehscn
./i76shell.dll:286886:vehscn
./i76shell.dll:286908:vehscn
./i76shell.dll:286938:vehscn
./i76shell.dll:286958:vehscn
./i76shell.dll:286972:vehscn
./i76shell.dll:297490:vehscn
./i76shell.dll:297510:vehscn
./i76shell.dll:297524:vehscn
./i76shell.dll:301306:vehscn
./i76shell.dll:301326:vehscn
./i76shell.dll:301340:vehscn
./i76shell.dll:301382:vehscn
./i76shell.dll:301402:vehscn
./i76shell.dll:301416:vehscn
./i76shell.dll:301450:vehscn
./i76shell.dll:301470:vehscn
./i76shell.dll:301484:vehscn
./i76shell.dll:305370:vehscn
./i76shell.dll:305390:vehscn
./i76shell.dll:305404:vehscn
./i76shell.dll:305422:vehscn
./i76shell.dll:305442:vehscn
./i76shell.dll:305456:vehscn
./i76shell.dll:308896:vehscn
./i76.exe:790360:vehscn
./ADDON/vehscn.vsf:28:vehscn
./I76SHELL2.DLL:401610:vehscn
./I76SHELL2.DLL:401630:vehscn
./I76SHELL2.DLL:401644:vehscn
./I76SHELL2.DLL:411354:vehscn
./I76SHELL2.DLL:411374:vehscn
./I76SHELL2.DLL:411396:vehscn
./I76SHELL2.DLL:411426:vehscn
./I76SHELL2.DLL:411446:vehscn
./I76SHELL2.DLL:411460:vehscn
./I76SHELL2.DLL:420070:vehscn
./I76SHELL2.DLL:420090:vehscn
./I76SHELL2.DLL:420104:vehscn
./I76SHELL2.DLL:420442:vehscn
./I76SHELL2.DLL:420462:vehscn
./I76SHELL2.DLL:420476:vehscn
./I76SHELL2.DLL:427226:vehscn
./I76SHELL2.DLL:427246:vehscn
./I76SHELL2.DLL:427260:vehscn
./I76SHELL2.DLL:427278:vehscn
./I76SHELL2.DLL:427298:vehscn
./I76SHELL2.DLL:427312:vehscn
./I76SHELL2.DLL:430340:vehscn
./I76SHELL2.DLL:431408:vehscn
./I76SHELL2.DLL:431420:vehscn
./I76SHELL2.DLL:443046:vehscn
./I76SHELL2.DLL:443066:vehscn
./I76SHELL2.DLL:443080:vehscn
./I76SHELL2.DLL:443122:vehscn
./I76SHELL2.DLL:443142:vehscn
./I76SHELL2.DLL:443156:vehscn
./I76SHELL2.DLL:443190:vehscn
./I76SHELL2.DLL:443210:vehscn
./I76SHELL2.DLL:443224:vehscn

Sigh.
Dll 2 is the patch one.