Release Diablo 2


In other words, pluging in a real mouse is the best option yet. :D   Especialy in cases where nubs are broken like on my Pandora, sadly. I also can't imagine to play D2 well with touch screen since you need alot of buttons sometimes, which are hard to reach with only one hand on the Pandora.  I wonder if there is a "direct input" hack for D2 where you play the char directly (with the D-Pad for example) like the Diablo 1 PSX port did... ^^
 
captured a crash in the PND out file... this was a level 20 character in episode 2.

 

Code:
d2common.asm:167162: unresolved_call 40FF0C4C (no sym)
d2common.asm:167162: unresolved_call 40E1D604 (no sym)
d2common.asm:167162: unresolved_call 40FF0A5C (no sym)
d2common.asm:167162: unresolved_call 40E1D604 (no sym)
d2common.asm:167162: unresolved_call 40FF0A5C (no sym)
d2common.asm:167162: unresolved_call 40FF0C4C (no sym)
trace:seh:raise_exception code=c0000005 flags=0 addr=0x4103d4f8 pc=4103d4f8 tid=0026
trace:seh:raise_exception  info[0]=00000000
trace:seh:raise_exception  info[1]=6ebfeae4
trace:seh:raise_exception  r0=4344007c r1=412365a4 r2=00000001 r3=413beae4 r4=4344007c r5=00000001
trace:seh:raise_exception  r6=45163700 r7=412365a4 r8=00000000 r9=45163700 r10=4344007c fp=43cb0004
trace:seh:raise_exception  ip=00006688 sp=415cf410 lr=cb610000 pc=4103d4f8 cpsr=60000010
trace:seh:call_stack_handlers calling handler at 0x4048a818 code=c0000005 flags=0
wine: Unhandled page fault on read access to 0x6ebfeae4 at address 0x4103d4f8 (thread 0026), starting debugger...
trace:seh:start_debugger Starting debugger "winedbg --auto 37 1372"
trace:seh:call_stack_handlers handler at 0x4048a818 returned 1
err:seh:segv_handler Got unexpected trap 0
Terminated
 
Last edited by a moderator:
thanks for the effort notaz!


I have had another crash that has already been reported. the game crashes when entering the burial grounds for me. haven't tried again yet.
 
@notaz could you confirm if my understanding is correct: any calls within the same module do not suffer from any problems with calling convention; however the problem you are seeing is when inter modular calls are made wrong the wrong parameters are being passed? If this is the case, is the destination of the calls either the Win32 API or MSVC runtime? The reason I ask is the header files (on the Win32 side) for those API/runtimes will obviously specify the calling convention - I wasn't sure if they simply do not provide any easy method for you to extract this information? If this is the case and you have a list of the intermodular calls that are made, if you post it I could look them up (on MSDN presuming that specifies the calling convention, if not perhaps the headers) and make a note of any which aren't stdcall. If this isn't describing the problem accurately, would you perhaps be able to give an example that describes the issue (an example function being called, how the parameters are wrong, etc.) I only ask this purely for technical curiosity as I'd like to understand the problem fully as I find it interesting.
 
Last edited by a moderator:
As mentioned, the problem is with indirect calls, where you don't know what it's trying to call, so no amount of MSDN or headers is going to help until you actually run that code and see where that pointer is pointing. It has little to do with runtime or if it's inter-modular or not, it might be calling the next function after the one that does the call, but until the codepath is exercised it's unknown.


Here is an example (simplified code from the real game), I hope you know a bit of x86 asm:

Code:
                mov     edi, [esi+8]
                mov     eax, [edi]
                push    1
                call    dword ptr [eax]

Which can be translated to:


int (__stdcall *i_f)(int);
// ...
edi = *(u32 *)(esi+8);
eax = *(u32 *)(edi);
i_f = (void *)*(u32 *)(eax);
i_f(1);


but it may also be


int (__thiscall *i_f)(int, int);
// ...
edi = *(u32 *)(esi+8);
eax = *(u32 *)(edi);
i_f = (void *)*(u32 *)(eax);
i_f(ecx, 1); // ecx is "this" pointer


or maybe


int (__fastcall *i_f)(int, int, int);
// ...
edi = *(u32 *)(esi+8);
eax = *(u32 *)(edi);
i_f = (void *)*(u32 *)(eax);
i_f(ecx, edx, 1);


From the 'push' instruction it's known that one arg is passed through the stack, but is it one of calling conventions that pass some of the args in the registers directly like __fastcall? There is no way to know. I'm doing some heuristics like where if the function never uses the registers from certain calling conventions, it can be assumed that those conventions are not used there, but it doesn't help much as IA32 is very register starved architecture and most functions use all the available registers.
 
Last edited by a moderator:
Thanks again for the details. Very informative again.


Finding the call convention looks like the most manual (and time consuming) task of the process now, isn't it (other part seems fairly automated now)?
 
@notaz thanks for the extra details, it certainly makes static recompilation sound very tricky to get fully working. Out of interest, are the symbols stripped from the D2 executable that Blizzard distributes? I am guessing so, but I know some studios don't seem to bother.
 
Last edited by a moderator:
Finding the call convention looks like the most manual (and time consuming) task of the process now, isn't it (other part seems fairly automated now)?

Right, although occasionally the tools hit something they can't handle or just produce incorrect code, which then needs to be tracked down.

@notaz thanks for the extra details, it certainly makes static recompilation sound very tricky to get fully working. Out of interest, are the symbols stripped from the D2 executable that Blizzard distributes? I am guessing so, but I know some studios don't seem to bother.

Visual Studio is using .pdb files for debug stuff and nobody distributes those, naturally.


Not stripping the binaries by default is probably one of the only good things Android has (or had at least, haven't checked for a while).
 
Last edited by a moderator:
thanks for the fixes! seems like the burial grounds related crash is no more! hope there won't be anything major for a while!
 
Uploaded another update, there are no more known issues right now (the loading screen glitches are wine related I think, not from the game itself).
 
Last edited by a moderator:
sweet! Thanks a bunch! The loading screen glitch seems like a minor bug anyway and I am not even sure I'd call it a bug, more like a palette change latency issue ^^. I don't think anyone could be annoyed by that.
 
Thanks again notaz.


My CD's of Diablo2+LOD (Italian) are arrived now and after a quick test it run beatifully on my CC Pandora.
 
I've uploaded armhf build: http://notaz.gp2x.de/misc/starec/


As with the other recompiles, patches for either wine of gcc are needed because of bugged gcc that comes with Debian jessie, also special command line as described in .txt


@TrashyMG a comparison against exagear running the original would be interesting, just need to make sure ARM version of wine isn't using mesa to update the screen (a bit hard to do with wine unless you compile it --without-opengl)
 
Last edited by a moderator:
Just out of curiosity, how do you guys control the game on the Pandora? Nubs? Mouse? Touchscreen?

I use the stylus. I have gotten used to the touch screen control with diablo 1 so it felt more natural than using the nubs.
 
I've uploaded armhf build: http://notaz.gp2x.de/misc/starec/


As with the other recompiles, patches for either wine of gcc are needed because of bugged gcc that comes with Debian jessie, also special command line as described in .txt


@TrashyMG a comparison against exagear running the original would be interesting, just need to make sure ARM version of wine isn't using mesa to update the screen (a bit hard to do with wine unless you compile it --without-opengl)

I got the new version of wine 1.8-rc2 compiled with the --without-opengl, it's working well, I'm on a new OS image, this has a semi-working xrandr capable driver which can do scaling, so I don't seem to need to force Diablo 2 to run in a virtual desktop window. hard to say performance wise, but it may be a tad slower that the prior rootfs with fbturbo only Xorg driver, I can switch back to fbturbo for speed comparisons, just don't have the time tonight.  Also unlike Starcraft that maintains a 4:3 aspect ratio even when running fullscreen, Diablo 2 seems to stretch 16:9 is there an environment variable to bring it back to 4:3? 
 
Last edited by a moderator:
Back
Top