OS2 World Community Forum

OS/2, eCS & ArcaOS - Technical => Programming => Topic started by: Jochen Schäfer on April 18, 2024, 08:24:42 am

Title: ClassiCube porting thread
Post by: Jochen Schäfer on April 18, 2024, 08:24:42 am
I'm trying to use pure OS/2 for ClassiCube instead the much unsupported SDL2 window system (it even has a big #error Don't use it sign at the entry).
So I'm trying to use DIVE, but all I get is the frame window and the background in it. When I move the window around, the background stays in it, i.e. nothing gets drawn.
I looked at the SDL implementation and the Toolkit samples, but I can't understand, what's wrong with my code.

If somebody please can take a look at the attached code give me some hints. I think the ClassiCube code is well structured and understandable, but if you have questions about ask me.

Thanks
Title: Re: Dive: Why does not this work
Post by: Flashback on April 18, 2024, 06:28:12 pm
I seem to remember, that DIVE doesn't like 'BGR4'. Try to set up your source buffer as 'BGR3'. Also I don't see, where 'fccColorFormat' is initialized.
Title: Re: Dive: Why does not this work
Post by: Jochen Schäfer on April 19, 2024, 12:55:32 am
Actually, BGR4 was what the driver was given me as screen color scheme. Also it's only the color scheme for the frame buffer, which gets blitted to the screen color scheme.
Title: Re: Dive: Why does not this work
Post by: Flashback on April 19, 2024, 08:03:56 pm
Take a look here (https://www.os2world.com/forum/index.php/topic,3324.msg40105.html#msg40105). It seems that DIVE doesn't support blitting from 32bit source buffers. No matter what colour depth the screen is using. You may also want to check the return values of DiveSetupBlitter and DiveBlitImage.
Title: Re: Dive: Why does not this work
Post by: Jochen Schäfer on April 19, 2024, 11:10:24 pm
Ok, then I have to look how I get that to work.
Title: Re: Dive: Why does not this work
Post by: Jochen Schäfer on April 20, 2024, 09:52:13 am
Well, using BGR3 or RGB3 as draw buffer doesn't change anything.
I still have only frame with the desktop background in it.
Title: Re: Dive: Why does not this work
Post by: Lars on April 20, 2024, 12:39:55 pm
Look at the OS/2 toolkit, in the "beehive" sample code (in that code you can ignore everything that centers around sprite creation. You can also ignore everything that centers around full screen DIVE unless you really want to do that, that includes loading GAMESVR [deprecated since Warp 4] or PMMERGE  Dive Fullscreen Init procedure).

I think you will need to support the WM_VRNDISABLED and WM_VRNENABLED window messages and use DiveAllocImageBuffer,DiveBlitImage,DivFreeImageBuffer. Note that the sample does the blitting from a secondary thread.

Also note that you cannot do "direct mode" when you are using Panorama with "Shadow Buffer Enabled". Since that is the setting that about 95% of all remaining OS/2 users will use, you should honour that.

Title: Re: Dive: Why does not this work
Post by: Jochen Schäfer on April 20, 2024, 02:52:58 pm
Look at the OS/2 toolkit, in the "beehive" sample code (in that code you can ignore everything that centers around sprite creation. You can also ignore everything that centers around full screen DIVE unless you really want to do that, that includes loading GAMESVR [deprecated since Warp 4] or PMMERGE  Dive Fullscreen Init procedure).

I think you will need to support the WM_VRNDISABLED and WM_VRNENABLED window messages and use DiveAllocImageBuffer,DiveBlitImage,DivFreeImageBuffer. Note that the sample does the blitting from a secondary thread.
Yes, I do use the Dive functions, but WM_VRNDISABLED AND WM_VRNENABLED are not much use for me, since Classicube gives me the rectangles it wants to paint to, anyway. Moreover, SDL2 works without using the window messages, so it seems optional.

Also note that you cannot do "direct mode" when you are using Panorama with "Shadow Buffer Enabled". Since that is the setting that about 95% of all remaining OS/2 users will use, you should honour that.
How can I get the option?
Title: Re: Dive: Why does not this work
Post by: Dave Yeo on April 20, 2024, 04:35:29 pm
Code from Mozilla (widget\os2\nswindow.cpp #405), for querying whether the shadow buffer is enabled
Code: [Select]
  // Don't use DIVE if the Panorama video driver is in use
  // unless its shadow buffer is turned off.
  HMODULE hmod;
  if (!DosQueryModuleHandle("PANOGREX", &hmod)) {
    char      str[8];
    if (PrfQueryProfileString(HINI_USERPROFILE, "PANORAMA", "VBEShadowBuffer",
                              0, str, sizeof(str)) && !strcmp(str, "0")) {
      sUseDive = TRUE;
      printf("Video driver is Panorama - shadow-buffer is disabled\n");
    }
    else
      printf("DIVE is disabled - Panorama's shadow-buffer is enabled\n");

    return;
  }

  sUseDive = TRUE;
Title: Re: Dive: Why does not this work
Post by: Flashback on April 21, 2024, 12:15:55 am
Yes, I do use the Dive functions, but WM_VRNDISABLED AND WM_VRNENABLED are not much use for me, since Classicube gives me the rectangles it wants to paint to, anyway. Moreover, SDL2 works without using the window messages, so it seems optional.
Really? Does it correctly handle the situation when the application window is partly obscured by another desktop window?
Title: Re: Dive: Why does not this work
Post by: Jochen Schäfer on April 21, 2024, 03:22:49 am
Code from Mozilla (widget\os2\nswindow.cpp #405), for querying whether the shadow buffer is enabled
Code: [Select]
  // Don't use DIVE if the Panorama video driver is in use
  // unless its shadow buffer is turned off.
  HMODULE hmod;
  if (!DosQueryModuleHandle("PANOGREX", &hmod)) {
    char      str[8];
    if (PrfQueryProfileString(HINI_USERPROFILE, "PANORAMA", "VBEShadowBuffer",
                              0, str, sizeof(str)) && !strcmp(str, "0")) {
      sUseDive = TRUE;
      printf("Video driver is Panorama - shadow-buffer is disabled\n");
    }
    else
      printf("DIVE is disabled - Panorama's shadow-buffer is enabled\n");

    return;
  }

  sUseDive = TRUE;
Thanks.
Title: Re: Dive: Why does not this work
Post by: Jochen Schäfer on April 21, 2024, 03:24:28 am
Yes, I do use the Dive functions, but WM_VRNDISABLED AND WM_VRNENABLED are not much use for me, since Classicube gives me the rectangles it wants to paint to, anyway. Moreover, SDL2 works without using the window messages, so it seems optional.
Really? Does it correctly handle the situation when the application window is partly obscured by another desktop window?
No need to get snarky. I don’t get anything, so I‘m really not interested in obscured windows in the first place.
Title: Re: Dive: Why does not this work
Post by: Lars on April 21, 2024, 11:45:27 am
I don't think that checking for shadow buffer is worth the effort. Todays systems with the video memory addressable as write combined memory are more than fast enough for your purposes. Just always use DiveBlitImage, following the beehive sample. That sample works perfectly well with the shadow buffer enabled.
Title: Re: Dive: Why does not this work
Post by: Lars on April 22, 2024, 11:23:35 am
Look at the OS/2 toolkit, in the "beehive" sample code (in that code you can ignore everything that centers around sprite creation. You can also ignore everything that centers around full screen DIVE unless you really want to do that, that includes loading GAMESVR [deprecated since Warp 4] or PMMERGE  Dive Fullscreen Init procedure).

I think you will need to support the WM_VRNDISABLED and WM_VRNENABLED window messages and use DiveAllocImageBuffer,DiveBlitImage,DivFreeImageBuffer. Note that the sample does the blitting from a secondary thread.
Yes, I do use the Dive functions, but WM_VRNDISABLED AND WM_VRNENABLED are not much use for me, since Classicube gives me the rectangles it wants to paint to, anyway. Moreover, SDL2 works without using the window messages, so it seems optional.

Look at the help for the "DiveSetupBlitter" function. You need to support WM_VRNDISABLED and WM_VRNENABLED in order to notify the Dive Blitter via "DiveSetupBlitter" that changes to the visible regions will start or end to occur.
On a reception of WM_VRNDISABLED you need to disable the blitter, on a reception of WM_VRNENABLED you will need to set up again the blitter with the proper values.
Title: Re: Dive: Why does not this work
Post by: Jochen Schäfer on April 22, 2024, 11:33:25 am
I understand that, but Classicube calls the draw buffer function with a rectangle to paint, so I setup the blitter in the draw function. This should work I would think.
Title: Re: Dive: Why does not this work
Post by: Lars on April 22, 2024, 12:27:08 pm
The samples seem to indicate that you are forbidden to drive screen updates in between calls WM_VRNDISABLED and WM_VRNENABLED. That is, there is a timespan where you are not allowed to blit anything to the screen, that means, the Classicube draw buffer function should do nothing during that timespan.
That in turn means, the proper point in time to call DiveSetupBlitter are WM_VRNDISABLED and WM_VRNENABLED. The "Remarks" section for DiveSetupBlitter even states that DiveSetupBlitter is "not intended to be called at high frequency".

This would be even more relevant for direct screen updates (that is, if you used DiveAcquireFrameBuffer / DiveDeacquireFrameBuffer / DiveSwitchBank / DiveCalcFrameBufferAddress and direct writes to the video aperture "ppFrameBuffer" as returned by DiveOpen) but for already mentioned reasons you should not do that anyways.

Still, it looks as if DIVE still needs to be notified via DiveSetupBlitter when WM_VRNDISABLED and WM_VRNENABLED are called for a specific window even if you do not do direct screen updates.
Title: Re: Dive: Why does not this work
Post by: Jochen Schäfer on April 22, 2024, 12:35:44 pm
I wonder then, how SDL work then. There is not one mention of WM_VRN*. It just blits the whole SDL surface to the buffer (no direct VRAM access).
Title: Re: Dive: Why does not this work
Post by: Dave Yeo on April 22, 2024, 05:26:38 pm
I wonder then, how SDL work then. There is not one mention of WM_VRN*. It just blits the whole SDL surface to the buffer (no direct VRAM access).

Cairo does the same. A comment in the code,
Code: [Select]
* This function uses DIVE to write those portions of the surface identified
* by @rect directly to the screen buffer.  It only supports 32- or 24-bit
* full-color video modes.  To avoid painting overlapping or child windows,
* it must perform all of the visible-region calculations that GPI normally
* handles.  Despite this, it provides a significant improvement in speed
* compared to using GPI functions.
Title: Re: Dive: Why does not this work
Post by: Jochen Schäfer on April 25, 2024, 08:23:02 am
Update: I got it working by setting up the RECTL in SETUP_BLITTER::pVisDstRects correctly.
Now, a picture is shown.
Title: Re: Dive: Why does not this work
Post by: Lars on April 25, 2024, 02:28:43 pm
I suppose it should be:

 rect.xLeft = 0;
 rect.yTop = r.Height;
 rect.xRight = r.Width;
 rect.yBottom = 0;

because I assume that the coordinate system to be used is still the OS/2 PM coordinate system [bottom left is (0,0)], correct ?

By the way:
setupBlitter.lDstPosX          = 0;
setupBlitter.lDstPosY          = 0;

You would only ever set these to anything else if you blitted into a memory buffer (also allocated via DiveAllocImageBuffer) instead of to the screen. But maybe DIVE ignores this anyway if you specify DIVE_BUFFER_SCREEN as the destination blit buffer in "DiveBlitImage".
Title: Re: Dive: Why does not this work
Post by: Jochen Schäfer on April 25, 2024, 05:15:48 pm
I now do a
Code: [Select]
WinGetWindowRect(hwndClient, &rect); and it works.
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on April 25, 2024, 11:22:22 pm
For the sound support, I open an audio device and created a Dart mixer.
As I understand it, I can only open one mixer and then have to mix different sound myself. Is this understanding correct, or is there a way to let OS/2 do the mixing.
Title: Re: ClassiCube porting thread
Post by: KO Myung-Hun on April 27, 2024, 10:07:17 am
Hi/2.

libkai can mixer multiple audio streams. How about consider it ?

KO Myung-Hun
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on April 27, 2024, 09:57:10 pm
Sure, I could use that. But I just wanted to understand DART.
Title: Re: ClassiCube porting thread
Post by: KO Myung-Hun on April 29, 2024, 04:00:40 am
DART itself support multiple streams with sharable mode if an audio driver supports it like SBLive!. Unfortunately, however, Uniaud does not support multiple streams. I'm not sure USB audio driver by Lars support it.
Title: Re: ClassiCube porting thread
Post by: Lars on April 29, 2024, 08:33:31 am
USB audio does not support multiple streams in general as far as the standard goes.Effectively, it only has one isochronous streaming input pipe (and potentially an additional streaming output pipe for recording) and its capability is adjustable to the necessary bandwidth.
At least I have never seen an USB audio sound device that would provide more than one streaming input pipe.
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on April 29, 2024, 09:46:12 am
Thanks for explanations.

Another question: I assume, that sound buffers want its data in Little Endian layout. Am I correct?
Title: Re: ClassiCube porting thread
Post by: Lars on April 29, 2024, 11:51:24 am
DART was IBM's half-baked effort to provide some sophsticated sound processing. What it ended up with is the ability to control streaming to an audio device largely by the application (instead of trusting the streaming manager). That's about it.

yes, you are correct, sound data always is in little endian format.
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 03, 2024, 09:37:16 am
So I'm getting along, but I noticed some behaviour, I can't explain and I haven't find any clue in the Toolkit help.
While in the Launcher window or while in Game window with the menu open, the pointer isn't captured, so ALT+F4 works.
But in Game window with the menu closed, the pointer is captured, and then ALT+F4 will not work, while other keypresses are sending WM_CHARs.
Has someone a hint, what is happpening here?
Title: Re: ClassiCube porting thread
Post by: Lars on May 03, 2024, 09:28:47 pm
I can just guess but Alt+F4 is a special key combination (to close a window) that might not be passed on verbatim to the Window Procedure in the WM_CHAR message.

Maybe you have to catch the WM_TRANSLATEACCEL message and handle that special key combination there.

Or, reading the help for WM_CHAR, Alt-F4 might be translated into a WM_COMMAND or WM_SYSCOMMAND message (likely a WM_SYSCOMMAND message with uscmd = SC_CLOSE).
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 04, 2024, 07:15:49 pm
Sure, I read the WM_CHAR help, but there is no clue, why this happens only for captured windows.
While captured, I still see that F4 is released with ALT pressed. Weird.
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 04, 2024, 07:24:44 pm
Another problem, I can't solve, is that the eCosoft Runtime's file dialog crash with the following code
Code: [Select]
FILEDLG fileDialog;
HWND hDialog;

memset(&fileDialog, 0, sizeof(FILEDLG));
fileDialog.cbSize = sizeof(FILEDLG);
fileDialog.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_OPEN_DIALOG;
fileDialog.pszTitle = (PSZ)args->description;

memcpy(fileDialog.szFullFile, *(args->filters), CCHMAXPATH);
hDialog = WinFileDlg(HWND_DESKTOP, hwndFrame, &fileDialog);
if (fileDialog.lReturn == DID_OK) {
}
I uninstalled the runtimes. Nothing crashes, everything is fine. I reinstalled the newest runtime. The apps crashes again.
Other apps, like EPM, have no problems. I also replicated the example for WinFileDlg, but it's all the same.
My popup log is attached.
Title: Re: ClassiCube porting thread
Post by: Steven Levine on May 05, 2024, 03:17:28 am
This looks like stack overflow in a secondary thread (TID 0xa).  If possible, try rebuilding with larger thread stacks.

Steven
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 05, 2024, 10:57:26 am
This looks like stack overflow in a secondary thread (TID 0xa).  If possible, try rebuilding with larger thread stacks.

Steven
Thanks for the hint, but even with a stacksize of 81920000 the dialog crashes the app (and also the IBM debugger, BTW).
There must be something else be going on.

BTW, do you know where to find this SYSxxxx code?
Title: Re: ClassiCube porting thread
Post by: Dave Yeo on May 05, 2024, 05:26:24 pm
There's %LIBC_THREAD_MIN_STACK_SIZE% to specify the minimum stack size for new threads. Default is 4096 bytes.
Seems there's a flag too but can't remember it.
Title: Re: ClassiCube porting thread
Post by: Steven Levine on May 06, 2024, 02:30:18 am
Exception codes are documented in the OS/2 Debugging Handbook (sg244640.inf) and the Control Program Guide and Reference (GPG&R)

Both annotate the value differently.  Given c0000005, you need to search for 0c0000005h in the Debugging Handbook and for 0xc0000005 in the CPG&R.

As Dave noted, you need to expand the per thread stack for TID 0xa.  You can use LIBC_THREAD_MIN_STACK_SIZE to set the minimum at runtime or, assuming that ClassiCube is using pthreads, you can adjust the compile time values by modifying the code that eventually invokes pthread_attr_setstacksize()

Note that while you can get stack overflow if the stack is too small, you can also get stack overflow if the code recurses unexpectedly.  A popuplog is typically not going to tell why the stack overflow happened.  This requires an exceptq report or a process dump file.

BTW, are your sources available anywhere?
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 06, 2024, 09:33:57 am
Exception codes are documented in the OS/2 Debugging Handbook (sg244640.inf) and the Control Program Guide and Reference (GPG&R)

Both annotate the value differently.  Given c0000005, you need to search for 0c0000005h in the Debugging Handbook and for 0xc0000005 in the CPG&R.

As Dave noted, you need to expand the per thread stack for TID 0xa.  You can use LIBC_THREAD_MIN_STACK_SIZE to set the minimum at runtime or, assuming that ClassiCube is using pthreads, you can adjust the compile time values by modifying the code that eventually invokes pthread_attr_setstacksize()

Note that while you can get stack overflow if the stack is too small, you can also get stack overflow if the code recurses unexpectedly.  A popuplog is typically not going to tell why the stack overflow happened.  This requires an exceptq report or a process dump file.

BTW, are your sources available anywhere?
Well, here we go. I knew, I was missing something, like that app stack is not thread stack.
Yes, I use pthreads at the moment, and I saw that ClassiCubes implementation will use some constant values. I will have to #ifdef them, I suppose.


My code is here, but it's not the most recent: https://github.com/josch1710/ClassiCube/tree/os2 (https://github.com/josch1710/ClassiCube/tree/os2).

EDIT: I let the code run in IDEBUG until WinFileDlg is called. The function gets called from the main thread (i.e. main() is in the call stack). In the call stack is the window procedure reacting to a mouse button click.I suppose, this is should not be an issue, because in the end, everything gets called from the window procedure. At the time, the code is about to call WinFileDlg there is about 1M of stack memory left. This should enough, shouldn't it.
Also the dialog box flashes on the screen, and I can see a lot of dialog messages being processed, until the dialog crashes the app.
Title: Re: ClassiCube porting thread
Post by: Lars on May 06, 2024, 12:57:49 pm
Another problem, I can't solve, is that the eCosoft Runtime's file dialog crash with the following code
Code: [Select]
FILEDLG fileDialog;
HWND hDialog;

memset(&fileDialog, 0, sizeof(FILEDLG));
fileDialog.cbSize = sizeof(FILEDLG);
fileDialog.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_OPEN_DIALOG;
fileDialog.pszTitle = (PSZ)args->description;

memcpy(fileDialog.szFullFile, *(args->filters), CCHMAXPATH);
hDialog = WinFileDlg(HWND_DESKTOP, hwndFrame, &fileDialog);
if (fileDialog.lReturn == DID_OK) {
}
I uninstalled the runtimes. Nothing crashes, everything is fine. I reinstalled the newest runtime. The apps crashes again.
Other apps, like EPM, have no problems. I also replicated the example for WinFileDlg, but it's all the same.
My popup log is attached.

1) are you sure that args->description will be a valid address across the call to WinFileDlg ?
2) What did you set fileDialog.pszOKButton to ?
3) What did you set fileDialog.pszlDrive to ?

In particular for the latter, the doc does not say that you can set it to a NULL pointer. Even if the code example implies differently. And even if the default dialog procedure gracefully handles NULL pointers for certain arguments, then the eCosoft runtime dialog procedure override might not.
Title: Re: ClassiCube porting thread
Post by: Lars on May 06, 2024, 01:14:23 pm
In addition, in your latest checkin you also do this (without telling us):

fileDialog.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_PRELOAD_VOLINFO | FDS_OPEN_DIALOG;
fileDialog.pfnDlgProc = WinDefFileDlgProc;

The latter is completely unnecessary as you are not providing your own file dialog window procedure anyway.

But what's more, if you use FDS_PRELOAD_VOLINFO, it is your responsibility to allocate and also manage memory for
fileDialog.papszIDriveList (read further info of how the table needs to look like in the explanation for this field).

At least that is what I would try out to check if it makes a difference.
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 06, 2024, 03:09:28 pm
Sure, I didn't tell you, because it's not used anymore. You quoted the code snippet, that's what I'm working with.
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 06, 2024, 03:20:16 pm
Another problem, I can't solve, is that the eCosoft Runtime's file dialog crash with the following code
Code: [Select]
FILEDLG fileDialog;
HWND hDialog;

memset(&fileDialog, 0, sizeof(FILEDLG));
fileDialog.cbSize = sizeof(FILEDLG);
fileDialog.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_OPEN_DIALOG;
fileDialog.pszTitle = (PSZ)args->description;

memcpy(fileDialog.szFullFile, *(args->filters), CCHMAXPATH);
hDialog = WinFileDlg(HWND_DESKTOP, hwndFrame, &fileDialog);
if (fileDialog.lReturn == DID_OK) {
}
I uninstalled the runtimes. Nothing crashes, everything is fine. I reinstalled the newest runtime. The apps crashes again.
Other apps, like EPM, have no problems. I also replicated the example for WinFileDlg, but it's all the same.
My popup log is attached.

1) are you sure that args->description will be a valid address across the call to WinFileDlg ?
2) What did you set fileDialog.pszOKButton to ?
3) What did you set fileDialog.pszlDrive to ?

In particular for the latter, the doc does not say that you can set it to a NULL pointer. Even if the code example implies differently. And even if the default dialog procedure gracefully handles NULL pointers for certain arguments, then the eCosoft runtime dialog procedure override might not.
1.) Yes, because WinFileDlg does not return, until you close the dialog. All samples would not work with local variables. Also, I tested that code with a local variable in a different script program and there it works, even without explicitely setting 2.) + 3.)
Title: Re: ClassiCube porting thread
Post by: Lars on May 06, 2024, 06:56:38 pm
1) Are you making sure that you are passing a fully qualified filename to fileDialog.szFullFile ?
2) is *(args->filters) the correct pointer or rather (args->filters) ? Shouldn't you copy with strcpy rather than memcpy ?


Since I have zero problems using the eCosoft runtime functions, regardless of application:

3) have you installed the latest version of the eCo Software "Win" and "Base" runtime ? I have version 2017.11.15.0 and 2018.11.8.0 installed, respectively. I think these should be the newest versions.
Title: Re: ClassiCube porting thread
Post by: TeLLie on May 06, 2024, 07:54:21 pm
Hi all
Moest are from 26-01-2024
Look @ https://ecsoft2.org/eco-software-runtime
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 06, 2024, 08:13:56 pm
Yes, installed the newest runtimes.
szFullFile can be *.ext, and yes
Code: [Select]
*(args->filters) is correct.
strcpy vs memcpy doesn’t matter. I tried alle combinations. I also tried
Code: [Select]
char filter[CCHMAXPATJ]=„*.*“, but it doesn’t matter.
Title: Re: ClassiCube porting thread
Post by: Lars on May 07, 2024, 08:57:46 am
As Steve has already mentioned, the trap is due to a stack error.
Your app is trying to push a DWORD to mem address 0x0464fffc but the lower limit for the stack obviously is 0x04650000 (that is where ESP points to on occurence of the trap). It also does not look like your code (at least the invocation of the function in PMMERGE.DLL which is the "Win32RequestMutexSem" function I seem to remember) is being called from the main thread because TID=000a (it should be TID=0001 for the main thread).

You say that the provided stack is big enough.
The only remaining thing I can think of is that you are overwriting your stack (with EBP being overwritten with a bogus value before it is being popped or assigned to ESP). Or some recursion happens.

You will need to create a process dump and have a look at that. That should allow you to detect a recursion.
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 07, 2024, 09:35:17 am
@Lars: Thank you for your persistence.
I don't why it's crashinh in a thread. CC spins of some threads for the background music and the resource HTTP fetch, but the WinFileDlg call happens in the main game loop, which runs on the main thread. IDebug tells me that, too.
I pushed the most recent changes to Github, so if somebody wants to look at the thing...
I will try to create a process dump, and post it.
Title: Re: ClassiCube porting thread
Post by: Lars on May 07, 2024, 05:25:08 pm
1) Since the trap occurs in "WinRequestMutexSem" (which you are apparently not directly calling from anywhere), I suspect it has something to do with calling "WinSetVisibleRegionNotify" before calling "WinFileDlg" and after calling "WinFileDlg". My gut feeling is that it is a problem surrounding the call to "WinFileDlg" with these calls. As a test, I'd remove that

2) "args->filters" is effectively a PAPSZ pointer, that is, a pointer to an array of pointers where the last pointer in the variable array is a NULL pointer, see the example code for the Windows implementation:
Code: [Select]
const char* const* fileExts = args->filters;
...
for (i = 0; fileExts[i]; i++)
{
if (i) String_Append(&filters, ';');
String_Format1(&filters, "*%c", fileExts[i]);
}

That might help in properly setting up the "papszITypeList" of "WinFileDlg". In fact, you should be able to do a:
fileDialog.papszITypeList = (PAPSZ)args->filters;
Title: Re: ClassiCube porting thread
Post by: Rich Walsh on May 07, 2024, 09:25:58 pm
2) "args->filters" is effectively a PAPSZ pointer, that is, a pointer to an array of pointers where the last pointer in the variable array is a NULL pointer

This is not correct. There is absolutely no indication anywhere in the *OS/2* docs that that 'fileDialog.szFullFile' is anything other than a simple string. If you wanted to filter based on multiple extensions, you do it like this: "*.exe;*.cmd" using a semicolon, not a null, to separate the filters.

Regardless, the most appropriate way to determine whether this is the source of the problem (and I doubt it is) is to make the assignment as simple as possible:  strcpy(fileDialog.szFullFile, "*.*");

Quote
see the example code for the Windows implementation

Not helpful.
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 08, 2024, 07:06:23 am
1) Since the trap occurs in "WinRequestMutexSem" (which you are apparently not directly calling from anywhere), I suspect it has something to do with calling "WinSetVisibleRegionNotify" before calling "WinFileDlg" and after calling "WinFileDlg". My gut feeling is that it is a problem surrounding the call to "WinFileDlg" with these calls. As a test, I'd remove that
I added these calls just recently. With or without them the app crashes.

2) "args->filters" is effectively a PAPSZ pointer, that is, a pointer to an array of pointers where the last pointer in the variable array is a NULL pointer, see the example code for the Windows implementation:
[..]
You are correct, but that's why I did '*(args->filter)' which let's me copy the first string to fileDialog.szFullFile. Also, I have used 'char szFullFile[CCHMAXATH] = "*.*"', and copied it to fileDialog.szFullFile. The app still crashes.

I suspect, that thread 0a from the popuplog is spinned up by the dialog, since it's always the last one, as per process dump.
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 08, 2024, 07:14:57 am
This is not correct.
Actually, Lars is correct. 'args' is the setup struct from ClassiCube, and filters is an array of pointers (more acurate a pointer to pointer ;))

@Rich: Thanks all the same, anyone thinking about the problem could be bringing us nearer to the problem. And yes, you are correct, copying a simple string to fileDialog.szFullFile is a better solution, but I verified this already ;)
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 08, 2024, 08:47:43 am
I have attached a new executablewith my most recent version.
Can somebody with the eCoSoft runtime installed, please test it.
Please start a single player game, then press ESC. In the menu, please click on "Load Map", and then on "Load File".
If everything works, and you exit, the application will put up a crash message. I don't have investigated that.
Title: Re: ClassiCube porting thread
Post by: David McKenna on May 08, 2024, 12:01:20 pm
Hi Jochen,

  I gave the new build a try and it looks a lot better than the last! Sound works too. I have the eCoSoft runtimes installed, so did as you asked and when I clicked on 'load file' a file choosing dialog briefly appears, then disappears and the game window disappears too. Get a popuplog, but no message. The initial Classicube window stays up though and can start a new game right away. Popuplog attached - thanks!

Regards,

EDIT: I added 'classicube-dev.exe' to the FOC 'do not use' list and now it doesn't crash until I hit 'Quit', then I get a message dialog saying:

Crash time: 08/05/2024 06:17:37
ClassiCube crashed.
Reason: Unhandled signal SIGSEGV (code -2147471358) at 05830000


Title: Re: ClassiCube porting thread
Post by: Lars on May 08, 2024, 12:23:07 pm
Actually, there are 3 traps in Davids POPUPLOG.TXT file. And the last two trap screens seem to stem from the very same execution.

Anyway, the file tells us that now we experience traps at 2 different places in PMMERGE.DLL (I'll have to look up the second place). I think that "WinFileDlg" in isolation is not the problem but the interchange with other threads executing (like for example the thread that DIVE spins off, I seem to remember).

On all occasions, the trap does not happen in the main thread. I suspect some problem with the File Dialog obscuring part of the window drawn to by DIVE and the DIVE thread trapping rather than "WinFileDlg". In all cases, it is running out of stack.
Title: Re: ClassiCube porting thread
Post by: Lars on May 08, 2024, 12:27:33 pm
2) "args->filters" is effectively a PAPSZ pointer, that is, a pointer to an array of pointers where the last pointer in the variable array is a NULL pointer

This is not correct. There is absolutely no indication anywhere in the *OS/2* docs that that 'fileDialog.szFullFile' is anything other than a simple string. If you wanted to filter based on multiple extensions, you do it like this: "*.exe;*.cmd" using a semicolon, not a null, to separate the filters.

Regardless, the most appropriate way to determine whether this is the source of the problem (and I doubt it is) is to make the assignment as simple as possible:  strcpy(fileDialog.szFullFile, "*.*");

Quote
see the example code for the Windows implementation

Not helpful.

I talked about "fileDialog.papszITypeList" and not "fileDialog.szFullFile". Maybe you should first read what I have written before answering.
Anyways, I also doubt that that is a problem.
Title: Re: ClassiCube porting thread
Post by: David McKenna on May 08, 2024, 12:45:06 pm
Hey Lars,

  I think I might have tried running ClassiCube several times, so the multiple traps in POPUPLOG may be one for each attempt. But in any case, it can be avoided by putting 'classicube-dev.exe' in the FOC 'do not use' list...

Regards,
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 08, 2024, 02:01:34 pm
[..]
On all occasions, the trap does not happen in the main thread. I suspect some problem with the File Dialog obscuring part of the window drawn to by DIVE and the DIVE thread trapping rather than "WinFileDlg". In all cases, it is running out of stack.
Do you mean, Dive itself spins up thread. I myself wait for CC to call me for an update without doing the blit in a thread.

One more data point, I could get, was, that when call WinFileDlg directly after WinCreateMsgQueue, the dialog stays up (without showing any files), but after that CC can't create any (p)threads, and so stops.
Something is really screwing up the memory.

FOC DNU list is less than ideal, but could be a solution.
Title: Re: ClassiCube porting thread
Post by: Lars on May 08, 2024, 02:33:48 pm
[..]
On all occasions, the trap does not happen in the main thread. I suspect some problem with the File Dialog obscuring part of the window drawn to by DIVE and the DIVE thread trapping rather than "WinFileDlg". In all cases, it is running out of stack.
Do you mean, Dive itself spins up thread. I myself wait for CC to call me for an update without doing the blit in a thread.

I will need to run the DIVE samples provided with the OS/2 toolkit but I seem to remember that they are running with 3 threads where the app itself only creates 2 threads (the main thread and an additional thread for blitting). If that is true, DIVE itself seemingly is creating its own thread. And I don't know what that additional thread does and what it accesses. Looks like it is calling "WinRequestMutexSem" ...
Title: Re: ClassiCube porting thread
Post by: Lars on May 08, 2024, 06:48:55 pm
Yes, DIVE seems to create an additional thread on its own.
On my system, with FOC enabled, nothing crashes. Since I seem to use an outdated version of the eCo Runtime, maybe that is the cure ?

I am still using eCS 2.2 beta. Where do you configure FOC ?
Title: Re: ClassiCube porting thread
Post by: David McKenna on May 08, 2024, 11:34:50 pm
Lars,

 On ArcaOS, 'Computer'-> 'System Setup' -> 'Workplace Shell' -> FOC tab to setup FOC. Page 2 has the exception list. Don't remember if eCS has that or not...

Regards,
Title: Re: ClassiCube porting thread
Post by: Lars on May 09, 2024, 09:01:12 am
Hi Dave,

eCS does not have that "FOC" tab in the Workplace Shell Object ...

By the way: FOC has nothing to do with eCosoft Runtime.
What FOC does is to change PMCTLS.DLL to forward the entry points of these functions:
WinFileDlg
WinDefFileDlgProc
WinFreeFileDlgList

to these functions in PMEX.DLL:
WinExFileDlg (directly replacing WinFileDlg)
WinExDefFileDlgProc (directly replacing WinDefFileDlgProc)
WinExFreeFileDlgList (directly replacing WinFreeFileDlgList)

My PMEX.DLL has this size and file date:
13.04.11   9.31          13.114      0  PMEX.DLL
Unfortunately, it has no buildlevel string and I have no clue where this DLL came from or if it was part of the original eCS installation.

So, my buest guess is that PMEX.DLL has received an update with ArcaOS (apparently, as FOC now offers configuration) and that that update broke the file selection dialog functionality.
I just checked and yes, PMEX.DLL has been updated with ArcaOS.
Title: Re: ClassiCube porting thread
Post by: Lars on May 09, 2024, 09:30:23 am
What you can also try: deregister class "WPFOCSystem". For that you will need to have full XWorkplace installed. This is the configuration class that adds the "FOC" page to the Workplace Shell configuration object, not the real file dialog replacement.

You can always reregister this class via REXX. For that, have a look at \system\install\foc\filedlgtofocdlg.cmd.
Look for "FOCRegisterWPClass".

Another thought: configure FOC to only scan "local drives" and not "all" (if you haven't done that anyway).
Title: Re: ClassiCube porting thread
Post by: Lars on May 09, 2024, 11:37:51 am
Actually, "PMEX.DLL" is dynamically binding to and calling into "FOC.DLL" to do its job and that is part of the "Win" eCosoft runtime.

I am beginning to believe that eCoSoft "win","base","net" runtime has been broken in later versions.

I have 2018.11.8.0 installed for "Net" and "Win" and 2017.11.15.0 for "Base". I do not experience crashes but (after registering the WPS class for FOC configuration, gleaned that from the ArcaOS installation), after setting exception in the FOC exception list, it has no effect/is ignored.

You can find older versions here:
https://en.ecomstation.ru/projects/developer/toolkit/?action=runtime-old

Title: Re: ClassiCube porting thread
Post by: David McKenna on May 09, 2024, 12:30:53 pm
Lars,

 I do have FOC set to scan only local drives. Tried backlevelling the 3 eCoSoft runtimes to the 2017 versions - rebooted - but no change. Classicube still crashes when a file dialog appears, but if I add it to the FOC exception list, it works. Maybe the newer PMEX.DLL is at fault? It does have a build level string:

[C:\os2\dll]bldlevel pmex.dll
Build Level Display Facility Version 6.12.675 Sep 25 2001
(C) Copyright IBM Corporation 1993-2001
Signature:       @#eCo Software:1.9.0#@##1## 05/10/16 14:41:04        GLASSMAN::
::::@@Presentation Manager Extension Library
Vendor:          eCo Software
Revision:        1.09.0
Date/Time:       05/10/16 14:41:04
Build Machine:   GLASSMAN
File Version:    1.9
Description:     Presentation Manager Extension Library

 FOC was an add-on from eCoSoft: http://en.ecomstation.ru/projects/foc, eventually installed from eCS 2.1 and higher...

Regards,
Title: Re: ClassiCube porting thread
Post by: Lars on May 09, 2024, 03:20:15 pm
As a quick test, back up and replace the files as contained in the ZIP file.
Explanation to follow.
Title: Re: ClassiCube porting thread
Post by: David McKenna on May 09, 2024, 11:40:52 pm
Lars,

 Tried these files, but ClassiCube still crashes when I try to open a file dialog in it. I can confirm that the exception list does not work with these - even with classicube-dev.exe in the exception list it crashes. I tried with both the 2017 and 2024 versions of all eCoSoft run time files.

 The fact an exception list was added kinda implies this problem was known, but not fixed for some reason. Maybe you could contact the author to find out why?

Regards,
Title: Re: ClassiCube porting thread
Post by: Martin Iturbide on May 10, 2024, 03:43:07 am
Hello

If it was demonstrated that a piece of code running with the eCo Runtimes FOC (included in ArcaOS) installed crashes, and the same works if eCo Runtimes are uninstalled, I think it will be good to create a ticket on the Arca Noae mantis. (https://mantis.arcanoae.com/).

I would be desirable to post the piece of code and executable if possible for the developer to try out.

Reards
Title: Re: ClassiCube porting thread
Post by: Lars on May 10, 2024, 11:38:25 am
AN will answer you that it is not their SW.
The author is Sergey (glassman). The best you can do is find his email address or contact Eugene Gorbunoff who would know how to contact Sergey.
Title: Re: ClassiCube porting thread
Post by: Martin Iturbide on May 10, 2024, 02:28:41 pm
AN will answer you that it is not their SW.
The author is Sergey (glassman). The best you can do is find his email address or contact Eugene Gorbunoff who would know how to contact Sergey.
Hello Lars.

FOC is being included in ArcaOS, I think that opening a ticket will make they forward the issue to Glassman and Eugene. Both parties (Arca Noae and eCo Software) should be aware of this.

Regards
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on May 10, 2024, 02:39:02 pm
I will create a ticket next week, as I'm away doing other retro stuff.
Title: Re: ClassiCube porting thread
Post by: Lars on May 11, 2024, 09:45:52 am
AN will answer you that it is not their SW.
The author is Sergey (glassman). The best you can do is find his email address or contact Eugene Gorbunoff who would know how to contact Sergey.

Sorry, meant to say Dmitry (Steklenev) and not Sergey.

Anyway, he has a webpage that also allows contacting him directly, maybe that is easier and also more efficient: https://5nets.ru/

There is a feedback link: https://5nets.ru/feedback/


The difference I found between the initial version of FOC contained in eCS (where it does not crash) and that in ArcaOS (where it crashes):

The install script of eCS forwards the functions "WinFileDlg","WinDefFildDlgProc","WinFreeDlgFileDlgList" from PMCTLS.DLL to PMEX.DLL but it does not "clone" them, so the original routines in PMCTLS.DLL are not accessible anymore. PMEX.DLL in turns calls into FOC.DLL.

ArcaOS on the other hand does not only forward the original functions from PMCTLS.DLL to PMEX.DLL but it also "clones" them to another ordinal so that the original procedures can be called from foc.dll, for example.

That seems to be the difference that makes FOC crash under ArcaOS but work ok under eCS. As I said, I have no probs under eCS and even regedit2.exe works just fine with FOC even though AN puts it on the exclusion list.
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on November 08, 2024, 03:22:49 pm
I have just compiling the newest ClassiCube version.
It now has sound and music. I use libkai (a static version for now, so no installation needed.).
What I observed on my T480 with uniaud, is that music and sound will hang after some time, and I can resume sound by playing something else like a system sound.
Anyone has an idea, what to do about it? Can somebody without Uniaud please test the sound?
Title: Re: ClassiCube porting thread
Post by: Pete on November 09, 2024, 01:51:53 am
Hi Jochen

I tried starting ClassicCube and was rewarded with this message

"Some required resources weren't found
OK to download?"


What are the "required resources"?


Regards

Pete
Title: Re: ClassiCube porting thread
Post by: Dave Yeo on November 09, 2024, 02:08:30 am
A couple of jar files and bunch of sound files
Title: Re: ClassiCube porting thread
Post by: Martin Iturbide on November 09, 2024, 02:17:56 pm
Hello Jochen

Sorry I can not answer your question I only use Uniaud here. I experience your same issue with the sound. This version render the image better than the last one I use. In the VM I was able to wakl very slowly, but on the Think pad T14s, I don't know why it does not get the WASD and Space to move. But I can click to break the squares and hear the sound.

Regards
Title: Re: ClassiCube porting thread
Post by: Jochen Schäfer on November 10, 2024, 01:04:55 pm
Hi Jochen

I tried starting ClassicCube and was rewarded with this message

"Some required resources weren't found
OK to download?"


What are the "required resources"?


Regards

Pete
Classicube will download all the files it needs to the executable's directory.