Apologies for needing some more hand-holding: from Alexander's advice I now have the game linking and beginning to execute. It now gets stuck while executing this piece of C++:
--------------------------------------------------------------------------- void tDirectDrawScreen::destroy() { DDSURFACEDESC ddsd; memset(&ddsd,0,sizeof(DDSURFACEDESC));
ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
HRESULT hr = mp_directDraw->CreateSurface(&ddsd, &mp_primarySurface, NULL); // crashes here ... } ---------------------------------------------------------------------------
This being the segfault that occurs:
--------------------------------------------------------------------------- #0 0x40c92c4c in ?? () #1 0x40f56f5f in User_DirectDraw_EnumDisplayModes (iface=0x403acc00, dwFlags=1086925740, pDDSD=0x808c678, context=0x40c92be8, callback=0x40f55dfc <EnumDisplayModesCallbackThunk>) at ddraw/user.c:373 #2 0x40f55e81 in IDirectDrawImpl_EnumDisplayModes (This=0x40c92be8, dwFlags=1086925900, pDDSD=0x808c678, context=0x40c92a94, cb=0x40c92a94) at ddraw/thunks.c:348 #3 0x4080f9b2 in tDirectDrawScreen::setUpWindowedSurfaces (this=0x808c668) at Source/tDirectDrawScreen.cpp:852 #4 0x4080cf1f in tDirectDrawScreen::initialise (this=0x808c668, fullScreen=false, screenWidth=640, screenHeight=480) at Source/tDirectDrawScreen.cpp:88 #5 0x4080caac in tDirectDrawScreen::tDirectDrawScreen (this=0x808c668, fullScreen=false, screenWidth=640, screenHeight=480) at Source/tDirectDrawScreen.cpp:55 #6 0x4082d76f in InitApp (hInst=0x40620000, nCmdShow=1) at Source/Main.cpp:289 #7 0x4082d8fc in WinMain (hInst=0x40620000, hPrevInst=0x0, lpCmdLine=0x403708ad "", nCmdShow=1) at Source/Main.cpp:322 #8 0x4062509c in __wine_exe_main () from /home/mattbee/Work/Nemesis/LSNClient.exe #9 0x400b3799 in start_process () at ../../scheduler/process.c:564 #10 0x400b76c9 in call_on_thread_stack (func=0x400b3558) at ../../scheduler/sysdeps.c:112 ---------------------------------------------------------------------------
Any ideas why this might be happening?
Apologies for needing some more hand-holding: from Alexander's advice I now have the game linking and beginning to execute. It now gets stuck while executing this piece of C++:
Hmm, according to the backtrace, it is rather crashing when executing 'User_DirectDraw_EnumDisplayModes' (ie something like mp_directDraw->EnumDisplayModes(...)) in the tDirectDrawScreen::setUpWindowedSurfaces method.
From what I see, I wonder if the enum procedure you give to DDraw has the
right protoype (ie is it a STDCALL or a CDECL function) ?
Moreover, a --debugmsg +ddraw trace would be helpful too with the backtrace + the actual code at Source/tDirectDrawScreen.cpp:852
Lionel
On Thursday 31 October 2002 14:32, Lionel Ulmer wrote:
Apologies for needing some more hand-holding: from Alexander's advice I now have the game linking and beginning to execute. It now gets stuck while executing this piece of C++:
Hmm, according to the backtrace, it is rather crashing when executing 'User_DirectDraw_EnumDisplayModes' (ie something like mp_directDraw->EnumDisplayModes(...)) in the tDirectDrawScreen::setUpWindowedSurfaces method.
Sorry, that was the method I posted, I happened to paste the wrong function name; this is the entire function with line 852 marked:
------------------------------------------------------------------------------ void tDirectDrawScreen::setUpWindowedSurfaces() { DDSURFACEDESC ddsd; memset(&ddsd,0,sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(DDSURFACEDESC);
//Set up the caps for the primary ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
//Finally create the primary surface (line 852) HRESULT hr = mp_directDraw->CreateSurface(&ddsd,&mp_primarySurface,NULL); handleErrors(hr,"Failed to create windowed primary surface.");
//Calculate and preserve current screen size setScreenSize();
//Calculate and store current screen position setScreenPosition();
//Create a "backbuffer" surface exactly the same size as primary createBackBuffer(); } ------------------------------------------------------------------------------
the ddraw trace looks like this:
------------------------------------------------------------------------------ trace:ddraw:initialize enabling DirectDraw HAL trace:ddraw:DDRAW_Create ((null),0x808c718,(nil)) trace:ddraw:DDRAW_FindDriver ((null)) trace:ddraw:HAL_DirectDraw_Create trace:ddraw:HAL_DirectDraw_Construct (0x403a9be0) trace:ddraw:User_DirectDraw_Construct (0x403a9be0,0) trace:ddraw:Main_DirectDraw_QueryInterface (0x403a9be0)->({6c14db80-a733-11ce-a521-0020af0be560},0x808c718) trace:ddraw:Main_DirectDraw_AddRef (0x403a9be0)->() incrementing from 1. trace:ddraw:Main_DirectDraw_Release (0x403a9be0)->() decrementing from 2. fixme:ddraw:Main_DirectDraw_WaitForVerticalBlank (0x403a9be0)->(flags=0x00010021,handle=0x8) trace:ddraw:User_DirectDraw_EnumDisplayModes (0x403a9be0)->(0x40c92c4c,0x808c720,0x40c92be8,0x40f55dfc) trace:ddraw:User_DirectDraw_EnumDisplayModes - mode: 512x384 trace:ddraw:User_DirectDraw_EnumDisplayModes - 8 bpp, R=00000000 G=00000000 B=00000000 (bang!) ------------------------------------------------------------------------------
and the backtrace from the exception looks like this:
------------------------------------------------------------------------------ #0 0x40c92c4c in ?? () #1 0x40f56f5f in User_DirectDraw_EnumDisplayModes (iface=0x403a9be0, dwFlags=1086925740, pDDSD=0x808c720, context=0x40c92be8, callback=0x40f55dfc <EnumDisplayModesCallbackThunk>) at ddraw/user.c:373 #2 0x40f55e81 in IDirectDrawImpl_EnumDisplayModes (This=0x40c92be8, dwFlags=1086925900, pDDSD=0x808c720, context=0x40c92a94, cb=0x40c92a94) at ddraw/thunks.c:348 #3 0x4080f9b2 in tDirectDrawScreen::setUpWindowedSurfaces (this=0x808c710) at Source/tDirectDrawScreen.cpp:852 #4 0x4080cf1f in tDirectDrawScreen::initialise (this=0x808c710, fullScreen=false, screenWidth=640, screenHeight=480) at Source/tDirectDrawScreen.cpp:88 #5 0x4080caac in tDirectDrawScreen::tDirectDrawScreen (this=0x808c710, fullScreen=false, screenWidth=640, screenHeight=480) at Source/tDirectDrawScreen.cpp:55 #6 0x4082d76f in InitApp (hInst=0x40620000, nCmdShow=1) at Source/Main.cpp:289 #7 0x4082d8fc in WinMain (hInst=0x40620000, hPrevInst=0x0, lpCmdLine=0x403710dd "", nCmdShow=1) at Source/Main.cpp:322 #8 0x4062509c in __wine_exe_main () from /home/mattbee/Work/Nemesis/LSNClient.exe #9 0x400b3799 in start_process () at ../../scheduler/process.c:564 #10 0x400b76c9 in call_on_thread_stack (func=0x400b3558) at ../../scheduler/sysdeps.c:112 ------------------------------------------------------------------------------
From what I see, I wonder if the enum procedure you give to DDraw has the right protoype (ie is it a STDCALL or a CDECL function) ?
I'm not supplying any procedure to DDraw; could it be that some linking problem has caused EnumDisplayModes to be called instead of CreateSurface? That's what the backtrace implies. I've tried a rebuild of the relevant source files just in case but the same thing happens.
If it helps, this is the function that creates the mp_directDraw variable, called before setUpWindowedSurfaces:
------------------------------------------------------------------------------ void tDirectDrawScreen::createDirectDrawObject() { HRESULT hr = DirectDrawCreate(0,&mp_directDraw,NULL); handleErrors(hr,"Failed to create Direct Draw Object."); } ------------------------------------------------------------------------------
cheers,
Sorry, that was the method I posted, I happened to paste the wrong function name; this is the entire function with line 852 marked:
Care to give me the actual data type of 'mp_directDraw' ? It seems that as you supposed, it does not use the correct function pointer when you use 'mp_directDraw->CreateSurface' and call instead 'EnumDisplayModes' thus, of course, leading to a crash as the callback function is not filled in properly.
The only thing I find strange is that you call CreateSurface with the 3rd argument being NULL and we should see that in the trace for 'EnumDisplayModes'...
Lionel
On Thursday 31 October 2002 18:41, Lionel Ulmer wrote:
Sorry, that was the method I posted, I happened to paste the wrong function name; this is the entire function with line 852 marked:
Care to give me the actual data type of 'mp_directDraw' ? It seems that as you supposed, it does not use the correct function pointer when you use 'mp_directDraw->CreateSurface' and call instead 'EnumDisplayModes' thus, of course, leading to a crash as the callback function is not filled in properly.
Declared in the header as:
IDirectDraw* mp_directDraw;
I'm working from the position of not knowing much about DirectDraw, so this is all new territory.
The only thing I find strange is that you call CreateSurface with the 3rd argument being NULL and we should see that in the trace for 'EnumDisplayModes'...
Yes, to my eye it looks like a linking problem but I'm not sure how to tell. Maybe if I whittle it down to a single .c file which I can post to the list it'll make it easier to diagnose.
Yes, to my eye it looks like a linking problem but I'm not sure how to tell. Maybe if I whittle it down to a single .c file which I can post to the list it'll make it easier to diagnose.
Well, the easier would be that, yes. Basically, just create the DDraw interface (as done in createDirectDrawObject) and call 'CreateSurface' on it. That should be enough to reproduce the problem (now that I think of it, I could do it myself, but well, I have no experience about creating Winelib apps :-) ).
Another thing helpful would be a disassembly of the 'setUpWindowedSurfaces' method (this would show what code is generated for the 'mp_directDraw->CreateSurface' call and thus understand why it choose the wrong method).
Lionel
On Friday 01 November 2002 12:19, Lionel Ulmer wrote:
Yes, to my eye it looks like a linking problem but I'm not sure how to tell. Maybe if I whittle it down to a single .c file which I can post to the list it'll make it easier to diagnose.
Well, the easier would be that, yes. Basically, just create the DDraw interface (as done in createDirectDrawObject) and call 'CreateSurface' on it. That should be enough to reproduce the problem (now that I think of it, I could do it myself, but well, I have no experience about creating Winelib apps :-) ).
Have managed to break my wine build after a cvs update (seem to immediately branch to zero running my program!), so still working on this.
Another thing helpful would be a disassembly of the 'setUpWindowedSurfaces' method (this would show what code is generated for the 'mp_directDraw->CreateSurface' call and thus understand why it choose the wrong method).
Okay, if it'll help you although my knowledge of x86 calling conventions and post-286 instructions etc. (last x86 I wrote was in a BIOS five years ago) is pretty hopeless :-)
00002fac <setUpWindowedSurfaces__17tDirectDrawScreen>: 2fac: 55 push %ebp 2fad: 89 e5 mov %esp,%ebp 2faf: 81 ec 8c 00 00 00 sub $0x8c,%esp 2fb5: 57 push %edi 2fb6: 56 push %esi 2fb7: 53 push %ebx 2fb8: 8b 7d 08 mov 0x8(%ebp),%edi 2fbb: 83 c4 fc add $0xfffffffc,%esp 2fbe: 6a 6c push $0x6c 2fc0: 6a 00 push $0x0 2fc2: 8d 5d 94 lea 0xffffff94(%ebp),%ebx 2fc5: 53 push %ebx 2fc6: e8 fc ff ff ff call 2fc7 <setUpWindowedSurfaces__17tDirectDrawScreen+0x1b> 2fcb: c7 45 94 6c 00 00 00 movl $0x6c,0xffffff94(%ebp) 2fd2: c7 45 98 01 00 00 00 movl $0x1,0xffffff98(%ebp) 2fd9: c7 45 fc 00 02 00 00 movl $0x200,0xfffffffc(%ebp) 2fe0: 8b 57 08 mov 0x8(%edi),%edx 2fe3: 8b 0a mov (%edx),%ecx 2fe5: 6a 00 push $0x0 2fe7: 8d 47 10 lea 0x10(%edi),%eax 2fea: 50 push %eax 2feb: 53 push %ebx 2fec: 52 push %edx 2fed: 8b 41 20 mov 0x20(%ecx),%eax 2ff0: ff d0 call *%eax 2ff2: 89 c6 mov %eax,%esi 2ff4: 83 c4 10 add $0x10,%esp 2ff7: 8d 45 80 lea 0xffffff80(%ebp),%eax 2ffa: 83 c4 fc add $0xfffffffc,%esp 2ffd: 50 push %eax 2ffe: 68 00 02 00 00 push $0x200 3003: 8d 5d 84 lea 0xffffff84(%ebp),%ebx 3006: 53 push %ebx 3007: e8 fc ff ff ff call 3008 <setUpWindowedSurfaces__17tDirectDrawScreen+0x5c> 300c: 83 c4 fc add $0xfffffffc,%esp 300f: 53 push %ebx 3010: 56 push %esi 3011: 57 push %edi 3012: e8 fc ff ff ff call 3013 <setUpWindowedSurfaces__17tDirectDrawScreen+0x67> 3017: 83 c4 20 add $0x20,%esp 301a: eb 09 jmp 3025 <setUpWindowedSurfaces__17tDirectDrawScreen+0x79> 301c: 8d 74 26 00 lea 0x0(%esi,1),%esi 3020: e8 fc ff ff ff call 3021 <setUpWindowedSurfaces__17tDirectDrawScreen+0x75> 3025: 83 c4 f4 add $0xfffffff4,%esp 3028: 57 push %edi 3029: e8 fc ff ff ff call 302a <setUpWindowedSurfaces__17tDirectDrawScreen+0x7e> 302e: 83 c4 f4 add $0xfffffff4,%esp 3031: 57 push %edi 3032: e8 fc ff ff ff call 3033 <setUpWindowedSurfaces__17tDirectDrawScreen+0x87> 3037: 83 c4 20 add $0x20,%esp 303a: 83 c4 f4 add $0xfffffff4,%esp 303d: 57 push %edi 303e: e8 fc ff ff ff call 303f <setUpWindowedSurfaces__17tDirectDrawScreen+0x93> 3043: eb 02 jmp 3047 <setUpWindowedSurfaces__17tDirectDrawScreen+0x9b> 3045: eb d9 jmp 3020 <setUpWindowedSurfaces__17tDirectDrawScreen+0x74> 3047: 8d a5 68 ff ff ff lea 0xffffff68(%ebp),%esp 304d: 5b pop %ebx 304e: 5e pop %esi 304f: 5f pop %edi 3050: c9 leave 3051: c3 ret 3052: 89 f6 mov %esi,%esi
Okay, if it'll help you although my knowledge of x86 calling conventions and post-286 instructions etc. (last x86 I wrote was in a BIOS five years ago) is pretty hopeless :-)
Well, I am not very good at X86 ASM either, but well, the problem lies here :
2fe0: 8b 57 08 mov 0x8(%edi),%edx
%edx is the address of the COM object (IDirectDraw)
2fe3: 8b 0a mov (%edx),%ecx
%ecx is the address of the VTable
2fe5: 6a 00 push $0x0 2fe7: 8d 47 10 lea 0x10(%edi),%eax 2fea: 50 push %eax 2feb: 53 push %ebx 2fec: 52 push %edx
All arguments are pushed on the stack (with the last being the pointer to the COM object itself).
2fed: 8b 41 20 mov 0x20(%ecx),%eax
%eax is the address of the method
2ff0: ff d0 call *%eax
Which is called here.
The problem being that the method at the offset '0x20' in the VTable is NOT CreateSurface (as you want to use in the code) but 'EnumDisplayModes' and thus the crash.
I will now look at how the VTable is built for COM objects in the case of C++ (you are building with g++, no ?) and try to understand why this particular code is generated.
Lionel
On Friday 01 November 2002 12:19, Lionel Ulmer wrote:
Yes, to my eye it looks like a linking problem but I'm not sure how to tell. Maybe if I whittle it down to a single .c file which I can post to the list it'll make it easier to diagnose.
Well, the easier would be that, yes. Basically, just create the DDraw interface (as done in createDirectDrawObject) and call 'CreateSurface' on it. That should be enough to reproduce the problem (now that I think of it, I could do it myself, but well, I have no experience about creating Winelib apps :-) ).
Okay, calling this function as the first statement in my WinMain causes exactly the same crash:
------------------------------------------------------------------------- void dummy(void) { IDirectDraw* dd; IDirectDrawSurface *surface; DDSURFACEDESC ddsd; HRESULT hr; memset(&ddsd, 0, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if (DirectDrawCreate(0, &dd, NULL)) { exit(1); } if (dd->CreateSurface(&ddsd, &surface, NULL)) { exit(2); } printf("created surface okay!\n");
} -------------------------------------------------------------------------
though I'm not sure why it ends up in the environ() function...?
------------------------------------------------------------------------- (gdb) bt #0 0x400114a9 in environ () from /lib/ld-linux.so.2 #1 0x40f49323 in User_DirectDraw_EnumDisplayModes (iface=0x403a7620, dwFlags=1086926012, pDDSD=0x40c92d34, context=0x40c92cf8, callback=0x40f481c0 <EnumDisplayModesCallbackThunk>) at ddraw/user.c:373 #2 0x40f48245 in IDirectDrawImpl_EnumDisplayModes (This=0x40c92cf8, dwFlags=1086926140, pDDSD=0x40c92d34, context=0x40c92ba4, cb=0x40c92ba4) at ddraw/thunks.c:348 #3 0x4082d85e in dummy () at Source/Main.cpp:325 #4 0x4082d891 in WinMain (hInst=0x40620000, hPrevInst=0x0, lpCmdLine=0x403710c5 "", nCmdShow=1) at Source/Main.cpp:340 #5 0x4062509c in __wine_exe_main () from /home/mattbee/Work/Nemesis/LSNClient.exe #6 0x400b37ed in start_process () at ../../scheduler/process.c:564 #7 0x400b771d in call_on_thread_stack (func=0x400b35ac) at ../../scheduler/sysdeps.c:112 -------------------------------------------------------------------------
disassembly looks like this:
------------------------------------------------------------------------- 00000768 <dummy__Fv>: 768: 55 push %ebp 769: 89 e5 mov %esp,%ebp 76b: 81 ec 88 00 00 00 sub $0x88,%esp 771: 83 c4 fc add $0xfffffffc,%esp 774: 6a 6c push $0x6c 776: 6a 00 push $0x0 778: 8d 45 94 lea 0xffffff94(%ebp),%eax 77b: 50 push %eax 77c: e8 fc ff ff ff call 77d <dummy__Fv+0x15> 781: c7 45 94 6c 00 00 00 movl $0x6c,0xffffff94(%ebp) 788: c7 45 98 01 00 00 00 movl $0x1,0xffffff98(%ebp) 78f: c7 45 fc 00 02 00 00 movl $0x200,0xfffffffc(%ebp) 796: 83 c4 fc add $0xfffffffc,%esp 799: 6a 00 push $0x0 79b: 8d 45 90 lea 0xffffff90(%ebp),%eax 79e: 50 push %eax 79f: 6a 00 push $0x0 7a1: e8 fc ff ff ff call 7a2 <dummy__Fv+0x3a> 7a6: 83 c4 14 add $0x14,%esp 7a9: 85 c0 test %eax,%eax 7ab: 74 0a je 7b7 <dummy__Fv+0x4f> 7ad: 83 c4 f4 add $0xfffffff4,%esp 7b0: 6a 01 push $0x1 7b2: e8 fc ff ff ff call 7b3 <dummy__Fv+0x4b> 7b7: 8b 45 90 mov 0xffffff90(%ebp),%eax 7ba: 8b 10 mov (%eax),%edx 7bc: 6a 00 push $0x0 7be: 8d 45 8c lea 0xffffff8c(%ebp),%eax 7c1: 50 push %eax 7c2: 8d 45 94 lea 0xffffff94(%ebp),%eax 7c5: 50 push %eax 7c6: ff 75 90 pushl 0xffffff90(%ebp) 7c9: 8b 42 20 mov 0x20(%edx),%eax 7cc: ff d0 call *%eax 7ce: 85 c0 test %eax,%eax 7d0: 74 0e je 7e0 <dummy__Fv+0x78> 7d2: 83 c4 f4 add $0xfffffff4,%esp 7d5: 6a 02 push $0x2 7d7: e8 fc ff ff ff call 7d8 <dummy__Fv+0x70> 7dc: 8d 74 26 00 lea 0x0(%esi,1),%esi 7e0: 83 c4 f4 add $0xfffffff4,%esp 7e3: 68 50 00 00 00 push $0x50 7e8: e8 fc ff ff ff call 7e9 <dummy__Fv+0x81> 7ed: c9 leave 7ee: c3 ret 7ef: 90 nop -------------------------------------------------------------------------
and the ddraw trace looks like this:
------------------------------------------------------------------------- trace:ddraw:initialize enabling DirectDraw HAL trace:ddraw:DDRAW_Create ((null),0x40c92d38,(nil)) trace:ddraw:DDRAW_FindDriver ((null)) trace:ddraw:HAL_DirectDraw_Create trace:ddraw:HAL_DirectDraw_Construct (0x403a7390) trace:ddraw:User_DirectDraw_Construct (0x403a7390,0) trace:ddraw:Main_DirectDraw_QueryInterface (0x403a7390)->({6c14db80-a733-11ce-a521-0020af0be560},0x40c92d38) trace:ddraw:Main_DirectDraw_AddRef (0x403a7390)->() incrementing from 1. trace:ddraw:Main_DirectDraw_Release (0x403a7390)->() decrementing from 2. trace:ddraw:User_DirectDraw_EnumDisplayModes (0x403a7390)->(0x40c92d3c,0x40c92d34,0x40c92cf8,0x40f481c0) trace:ddraw:User_DirectDraw_EnumDisplayModes - mode: 512x384 trace:ddraw:User_DirectDraw_EnumDisplayModes - 8 bpp, R=00000000 G=00000000 B=00000000 -------------------------------------------------------------------------
Any comments would be appreciated.
Well, the problem seems to come from an incompatibility between g++ and the way Wine defines COM objects. From my experiences, the g++ vtable starts at offset 8 whereas Wine defines COM object vtables as starting at offset 0 (ie vtable[0] == first method whereas for g++ vtable[2] == first method).
Now as this is a purely WineLib problem, I will let people more competent than me solve the issue, it's just not DirectDraw related at all, but COM related... From what I could find out in 'obj_base.h', you should try rebuilding Wine with the 'ICOM_MSVTABLE_COMPAT' define set to 1 (and read the relevant warning in the associated comment of course :-) ).
Lionel
On Friday 01 November 2002 18:27, Lionel Ulmer wrote:
Well, the problem seems to come from an incompatibility between g++ and the way Wine defines COM objects. From my experiences, the g++ vtable starts at offset 8 whereas Wine defines COM object vtables as starting at offset 0 (ie vtable[0] == first method whereas for g++ vtable[2] == first method).
Now as this is a purely WineLib problem, I will let people more competent than me solve the issue, it's just not DirectDraw related at all, but COM related... From what I could find out in 'obj_base.h', you should try rebuilding Wine with the 'ICOM_MSVTABLE_COMPAT' define set to 1 (and read the relevant warning in the associated comment of course :-) ).
Lionel, thanks for your efforts, I understand the problem now. I did a fresh build of both wine and the game with this #define added in, but now I get a similar error in DirectDrawCreate at ddraw/main.c:267; it tries to call IDirectDraw7_QueryInterface but the backtrace clearly shows that it's calling Main_DirectDraw_Release, which is off course two ahead of where it wants to be in the table:
(gdb) bt #0 Main_DirectDraw_Release (iface=0x403d7c70) at ddraw/main.c:121 #1 0x40fc07d7 in DDRAW_Create (lpGUID=0x0, lplpDD=0x40cc2d24, pUnkOuter=0x0, iid=0x40fc816c, ex=0) at main.c:267 #2 0x40fc0895 in DirectDrawCreate (lpGUID=0x0, lplpDD=0x40cc2d24, pUnkOuter=0x0) at main.c:289 #3 0x4085d836 in dummy () at Source/Main.cpp:320 #4 0x4085d891 in WinMain (hInst=0x40650000, hPrevInst=0x0, lpCmdLine=0x403a0e55 "", nCmdShow=1) at Source/Main.cpp:339 #5 0x4065509c in __wine_exe_main () from /home/mattbee/Work/Nemesis/LSNClient.exe #6 0x400ce100 in start_process () at ../../scheduler/process.c:564 #7 0x400d2ed6 in call_on_thread_stack (func=0x400cde56) at ../../scheduler/sysdeps.c:112
So with the ICOM_MSVTABLE_COMPAT flag set I get the "off-by-two" calling error from within Winelib when it's trying to invoke a COM function. When it's not set I get the same bug occurring in my program when it tries to do the same.
I'll keep investigating but I'd be amazed if I was the only person who's tried to build a DirectDraw application against Winelib-- surely someone else must have solved this problem before? Or do most Wine users only use Wine for loading PE executables?
cheers
On Saturday 02 November 2002 10:36, Matthew Bloch wrote: [snip]
Lionel, thanks for your efforts, I understand the problem now. I did a fresh build of both wine and the game with this #define added in, but now I get a similar error in DirectDrawCreate at ddraw/main.c:267;
Sorry, to clarify this should be line 265 as I added some log statements. Line 267 in the unmolested source actually *is* a Release call, but it's definitely an IDirectDraw7_QueryInterface call that this bug happens with.
On Sat, Nov 02, 2002 at 10:36:21AM +0000, Matthew Bloch wrote:
So with the ICOM_MSVTABLE_COMPAT flag set I get the "off-by-two" calling error from within Winelib when it's trying to invoke a COM function. When it's not set I get the same bug occurring in my program when it tries to do the same.
I'll keep investigating but I'd be amazed if I was the only person who's tried to build a DirectDraw application against Winelib-- surely someone else must have solved this problem before? Or do most Wine users only use Wine for loading PE executables?
I'd say that *BY FAR* most people use Wine to run programs. What would you use Winelib for anyway ? IMHO it has somewhat limited use, given that you don't really gain a lot from "porting" programs via Winelib (neither performance, nor code size, nor ...). (maybe I'm mistaken here, but currently I don't know of some significant gains) The only advantage I can think of would be the use of Unix code, but then you could achieve the very same thing by writing the Unix equivalent DLL of a Windows DLL (e.g.: hardware access or so) and using the Unix specific DLL version instead on Wine.
On Saturday 02 November 2002 11:06, Andreas Mohr wrote:
On Sat, Nov 02, 2002 at 10:36:21AM +0000, Matthew Bloch wrote:
So with the ICOM_MSVTABLE_COMPAT flag set I get the "off-by-two" calling error from within Winelib when it's trying to invoke a COM function. When it's not set I get the same bug occurring in my program when it tries to do the same.
I'll keep investigating but I'd be amazed if I was the only person who's tried to build a DirectDraw application against Winelib-- surely someone else must have solved this problem before? Or do most Wine users only use Wine for loading PE executables?
I'd say that *BY FAR* most people use Wine to run programs. What would you use Winelib for anyway ? IMHO it has somewhat limited use, given that you don't really gain a lot from "porting" programs via Winelib (neither performance, nor code size, nor ...).
Yes, I'd discovered this since I started, because I assumed there would be some speed advantage. My motivation to start the port through WINE was being able to use gdb and other familiar UNIX tools to debug a Windows program, and to be able to extract the Windows code piece by piece until I was left without any Win32 dependencies.
Of course if anyone can tell me how to debug a PE executable running under WINE with gdb I'd be interested, but I assumed it would be even more of an uphill struggle than getting a ELF/winelib version working.
cheers,
I'd say that *BY FAR* most people use Wine to run programs. What would you use Winelib for anyway ? IMHO it has somewhat limited use, given that you don't really gain a lot from "porting" programs via Winelib (neither performance, nor code size, nor ...).
Yes, I'd discovered this since I started, because I assumed there would be some speed advantage. My motivation to start the port through WINE was being able to use gdb and other familiar UNIX tools to debug a Windows program, and to be able to extract the Windows code piece by piece until I was left without any Win32 dependencies.
Of course if anyone can tell me how to debug a PE executable running under WINE with gdb I'd be interested, but I assumed it would be even more of an uphill struggle than getting a ELF/winelib version working.
Well, what happens is that someone starts down the Winelib path, runs into some roadblocks (and some of them end up getting fixed), eventually run into too many problems, and switch back to just using Wine.
Which is a crying shame, imnsho.
I think Andi dismisses the power of Winelib far too quickly; the promise of Winelib, in my opinion, is nearly as powerful as Wine. The ability to do conditional compilation, for one. Just the conceptual ability to have 1 source tree that can build for multiple platforms (want to run your game on Solaris? Mac OS X?) is cool. (Largely worthless, but cool :-/).
So, I guess what I'm saying is that most folks just use Wine, winedbg, the wine trace facility, and use only gdb for occassional spots.
But, if you persisted in using Winelib, I, for one would be grateful.
Cheers,
Jer
On Sat, 2 Nov 2002, Andreas Mohr wrote: [...]
The only advantage I can think of would be the use of Unix code, but then you could achieve the very same thing by writing the Unix equivalent DLL of a Windows DLL (e.g.: hardware access or so) and using the Unix specific DLL version instead on Wine.
That's one of the advantages and it allows you to do things you would probably not be able to do by just loading a Winelib dll from a non Winelib application. One such thing is mixing Win32 windows with QT ones in a single application. This is not a pipedream, it has already been been done on a large application at least once.
The other advantage of course is that Winelib makes it possible, at least in theory, to port your application to non x86 platforms like the Sparc or PPC. In fact I think the path to removing the x86 monopoly is: 1. run existing Windows applications using Wine 2. Linux grows market share 3. Wine improves enough on non-Linux x86 Unix platforms (FreeBSD, OpenBSD, Solaris) that you can run Windows apps on them as well as on Linux 4. now that Linux has a significant market share on the desktop ISVs start taking Wine into account when designing applications 5. ISVs use Winelib to migrate off the Win32 API to more cross-platform APIs 6. ISVs use Winelib to port their applications to non x86 platforms or port them directly if they already moved off Win32 using Winelib as a transition
Not saying this will happen, there are too many factors involved: Java, .Net, continued survival of non-x86 processors, etc. But Winelib might play a significant role in the future.
On Sat, Nov 02, 2002 at 07:17:28PM -0800, Francois Gouget wrote:
On Sat, 2 Nov 2002, Andreas Mohr wrote: [...]
The only advantage I can think of would be the use of Unix code, but then you could achieve the very same thing by writing the Unix equivalent DLL of a Windows DLL (e.g.: hardware access or so) and using the Unix specific DLL version instead on Wine.
That's one of the advantages and it allows you to do things you would probably not be able to do by just loading a Winelib dll from a non Winelib application. One such thing is mixing Win32 windows with QT ones in a single application. This is not a pipedream, it has already been been done on a large application at least once.
Umm, that's all fine and dandy, bu I was coming from the other direction ;-) Using a program on *Wine* that loads a DLL built into this customized version of Wine that does the Unix interfacing. The Windows version of the DLL would do the hardware communication on Windows.
But you're right, that certainly sounds impressive.
The other advantage of course is that Winelib makes it possible, at least in theory, to port your application to non x86 platforms like the Sparc or PPC. In fact I think the path to removing the x86 monopoly is:
- run existing Windows applications using Wine
- Linux grows market share
- Wine improves enough on non-Linux x86 Unix platforms (FreeBSD,
OpenBSD, Solaris) that you can run Windows apps on them as well as on Linux 4. now that Linux has a significant market share on the desktop ISVs start taking Wine into account when designing applications 5. ISVs use Winelib to migrate off the Win32 API to more cross-platform APIs 6. ISVs use Winelib to port their applications to non x86 platforms or port them directly if they already moved off Win32 using Winelib as a transition
True.
I guess it might very well happen that Wine gradually becomes a release requirement for applications. Just wait some time until more and more people (application "porters", that is) join the development plate, and you'll see Wine becoming more and more relevant (the fact that Wine is the only *real* Win32 platform on Linux definitely helps, too ;-).
On Sat, 2 Nov 2002, Matthew Bloch wrote:
So with the ICOM_MSVTABLE_COMPAT flag set I get the "off-by-two" calling error from within Winelib when it's trying to invoke a COM function. When it's not set I get the same bug occurring in my program when it tries to do the same.
Don't use ICOM_MSVTABLE_COMPAT with newer g++ versions, it's obsolete. Use ICOM_USE_COM_INTERFACE_ATTRIBUTE.
Ove Kaaven wrote:
On Sat, 2 Nov 2002, Matthew Bloch wrote:
So with the ICOM_MSVTABLE_COMPAT flag set I get the "off-by-two" calling error from within Winelib when it's trying to invoke a COM function. When it's not set I get the same bug occurring in my program when it tries to do the same.
Don't use ICOM_MSVTABLE_COMPAT with newer g++ versions, it's obsolete. Use ICOM_USE_COM_INTERFACE_ATTRIBUTE.
Does ICOM_USE_INTERFACE_ATTRIBUTE prevent g++ to add the 8 bytes offset? From which g++ version this can be used?
On Thu, 28 Nov 2002, Christian Costa wrote:
Does ICOM_USE_INTERFACE_ATTRIBUTE prevent g++ to add the 8 bytes offset?
Yeah.
From which g++ version this can be used?
Not sure, but I'm pretty sure it's been supported in Debian's 2.95.4 stuff (which grabbed lots of stuff from cvs, I think). So I'd guess that it probably works in 3.0.
Ove Kaaven wrote:
On Thu, 28 Nov 2002, Christian Costa wrote:
Does ICOM_USE_INTERFACE_ATTRIBUTE prevent g++ to add the 8 bytes offset?
Yeah.
From which g++ version this can be used?
Not sure, but I'm pretty sure it's been supported in Debian's 2.95.4 stuff (which grabbed lots of stuff from cvs, I think). So I'd guess that it probably works in 3.0.
Thanks! It works fine with the version 2.96 I use.
Do you know RedHat's gcc 2.96 has SERIOUS bugs and that its support has been totally dropped ? It's update time.
Thanks! It works fine with the version 2.96 I use.
===== Sylvain Petreolle spetreolle@users.sourceforge.net Fight against Spam ! http://www.euro.cauce.org/en/index.html ICQ #170597259
"Don't think you are. Know you are." Morpheus in Matrix, chapter 15.
___________________________________________________________ Do You Yahoo!? -- Une adresse @yahoo.fr gratuite et en français ! Yahoo! Mail : http://fr.mail.yahoo.com
Lionel Ulmer wrote:
Well, the problem seems to come from an incompatibility between g++ and the way Wine defines COM objects. From my experiences, the g++ vtable starts at offset 8 whereas Wine defines COM object vtables as starting at offset 0 (ie vtable[0] == first method whereas for g++ vtable[2] == first method).
Now as this is a purely WineLib problem, I will let people more competent than me solve the issue, it's just not DirectDraw related at all, but COM related... From what I could find out in 'obj_base.h', you should try rebuilding Wine with the 'ICOM_MSVTABLE_COMPAT' define set to 1 (and read the relevant warning in the associated comment of course :-) ).
Lionel
I've looked at what's done with ICOM_MSVTABLE_COMPAT and it seems that if you recompile WINE with it, this will break native apps that use COM objects.