Well in my continued quest to get Civilization 2 working on Linux
and Wine, I thought I'd ask some questions on the latest debug output
I've got.

I've noticed that Civ2 as its dieing is trying to post an error
message box and I also noticed that at around the point where all
goes wrong, the ds get changed from 0x0897 to 0x0000.  While I
don't understand this all 100%, it seems to be a part of the problem.
A CreateWindow16 call is made but the two strings at the start or the
args have the addresses 0x1e02 and 0x1e01 but these addresses look to
be too low.  I can find a previous CreateWindow16 call that has the
addresses that look right of 0x08971e02 and 0x08971e01 and this is what
got me looking at just what was set to 0x897 and when it gets changed.

The change happens in a call to SetErrorMode and I think thats the
whole problem.  Civ2 is using SetErrorMode(SEM_FAILCRITICALERRORS)
which from what I understand it supposed to stop Windows from
handling critical errors and instead to send them directly to the
application.  In looking around in Wine, this doesn't seem to be
supported.  While the call to SetErrorMode will set the error_mode
in the task and/or process structures, nothing uses it.

Is there any hope of SetErrorMode functioning properly?

Anyway - here is a bit of the debug output that I hope illuminates the
problem enough to make sense to someone else so that I can either get
pointed in the right direction or given a clue as to what could be
wrong.

Here is where I think things are starting to go wrong.  Of course it
could be that something earlier has trashed some memory or something
but this is where ds suddenly changes to 0x0000 and there is a bogus
CreateWindow16 call followed immediately by the MessageBoxA with an
exception.  Any clues as to why ds would suddenly change?

Ret  USER.53: DESTROYWINDOW() retval=0x0001 ret=03bf:0fe9 ds=0897
Call KERNEL.107: SETERRORMODE(0x0000) ret=03bf:0ff1 ds=0897
Ret  KERNEL.107: SETERRORMODE() retval=0x0001 ret=03bf:0ff1 ds=0897
Call KERNEL.107: SETERRORMODE(0x0001) ret=03bf:0e75 ds=0000
Ret  KERNEL.107: SETERRORMODE() retval=0x0000 ret=03bf:0e75 ds=0000
Call USER.133: GETWINDOWWORD(0x01b4,0xfffa) ret=03bf:0eb3 ds=0000
Ret  USER.133: GETWINDOWWORD() retval=0x0896 ret=03bf:0eb3 ds=0000
Call USER.41: CREATEWINDOW(0x00001e02 #1e02,0x00001e01
#1e01,0x40a00003,0x0000,0x0000,0x0000,0x0000,0x01b4,0x0064,0x0896,0x00000000)
ret=03bf:0ebc ds=0000
Ret  USER.41: CREATEWINDOW() retval=0x0000 ret=03bf:0ebc ds=0000
Call user32.391: MessageBoxA(00000000,40be4aac "Unhandled exception
0xc0000096 at address 0x00000fbb.\nDo you wish to debug it ?",40281fea
"Error",00000014) ret=40158a48 fs=024f

Here is the previous call to CreateWindow16 where things seem to be more
normal and the first two string addresses correct.  Notice that at this
point a SetErrorMode(1) is called which is still in effect at the later
failing point as shown above.

Call KERNEL.107: SETERRORMODE(0x0001) ret=03bf:0e75 ds=0897
Ret  KERNEL.107: SETERRORMODE() retval=0x0000 ret=03bf:0e75 ds=0897
Call USER.133: GETWINDOWWORD(0x01b4,0xfffa) ret=03bf:0eb3 ds=0897
Ret  USER.133: GETWINDOWWORD() retval=0x0896 ret=03bf:0eb3 ds=0897
Call USER.41: CREATEWINDOW(0x08971e02 "LISTBOX",0x08971e01
"",0x40a00003,0x0000,0x0000,0x0000,0x0000,0x01b4,0x0064,0x0896,0x00000000)
ret=03bf:0ebc ds=0897
trace:relay:WINPROC_CallWndProc
(wndproc=0x40079e98,hwnd=0000028c,msg=WM_NCCREATE,wp=00000000,lp=40d06d14)
trace:relay:WINPROC_CallWndProc
(wndproc=0x40079e98,hwnd=0000028c,msg=WM_NCCALCSIZE,wp=00000000,lp=40d06b00)
trace:relay:WINPROC_CallWndProc
(wndproc=0x40079e98,hwnd=0000028c,msg=WM_CREATE,wp=00000000,lp=40d06d14)
trace:relay:WINPROC_CallWndProc
(wndproc=0x40079e98,hwnd=0000028c,msg=WM_WINDOWPOSCHANGING,wp=00000000,lp=40d06788)
trace:relay:WINPROC_CallWndProc
(wndproc=0x40079e98,hwnd=0000028c,msg=WM_NCCALCSIZE,wp=00000001,lp=40d06630)
trace:relay:WINPROC_CallWndProc
(wndproc=0x40079e98,hwnd=0000028c,msg=WM_WINDOWPOSCHANGED,wp=00000000,lp=40d06788)
trace:relay:WINPROC_CallWndProc
(wndproc=0x40079e98,hwnd=0000028c,msg=WM_SIZE,wp=00000000,lp=00000000)
trace:relay:WINPROC_CallWndProc
(wndproc=0x40079e98,hwnd=0000028c,msg=WM_MOVE,wp=00000000,lp=00000000)
CallTo16(func=0467:70a4,ds=0897,0x01b4,0x0210,0x0001,0x0064,0x028c)
ss:sp=0897:9a2a
     AX=0896 BX=0000 CX=0000 DX=0000 SI=0000 DI=0000 BP=9a54 ES=0897
FS=0000
Call USER.135: GETWINDOWLONG(0x01b4,0x0004) ret=0467:70be ds=0897
Ret  USER.135: GETWINDOWLONG() retval=0x04e7904c ret=0467:70be ds=0897
Call USER.107: DEFWINDOWPROC(0x01b4,0x0210,0x0001,0x0064028c)
ret=046f:1be9 ds=0897
Ret  USER.107: DEFWINDOWPROC() retval=0x00000000 ret=046f:1be9 ds=0897
CallTo16() ss:sp=0897:9a2a retval=0x00000000
Ret  USER.41: CREATEWINDOW() retval=0x028c ret=03bf:0ebc ds=0897

I've tried making SetErrorMode16 a NOP but it still fails.  I think
Civ2 is planning to fail and trying to capture the critical error
message it knows it will get and since capturing it is not working,
the whole thing falls apart.  I don't know though why this causes
ds to get set to 0x0000.

Is there a similar tool on Windows to the --debugmsg +relay that I
could use on Civ2 there and see if its doing similar things and how
it handles it?

So does this make any sense to anyone?  Thanks for any help given!

--
Brad Pepers
[EMAIL PROTECTED]

Reply via email to