Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load and display bitmaps at runtime #82

Open
uklatt opened this issue Dec 6, 2023 · 5 comments
Open

Load and display bitmaps at runtime #82

uklatt opened this issue Dec 6, 2023 · 5 comments

Comments

@uklatt
Copy link

uklatt commented Dec 6, 2023

Hello Greg,

what is the "best" solution to load and display a BMP bitmap file with actual 0.94 version?
The following code doesn't work.

  image = GdLoadImageFromFile( filename, 0 );
  hdcMem = CreateCompatibleDC( hdc );
  hbmp = CreateCompatibleBitmap( hdcMem, SCREENX, SCREENY );
  hbmpOrg = SelectObject( hdcMem, hbmp );
  DrawDIB( hdcMem, 0, 0, image );
  StretchBlt( hdc, x, y, dx, dy, hdcMem, 0, 0, image->width, image->height, MWROP_SRC_OVER );
  DeleteObject(SelectObject(hdcMem, hbmpOrg));
  DeleteDC(hdcMem);

I got the following error:

/home/root/microwindows-0.94pre/src/drivers/genmem.c:144: gen_allocatememgc: Assertion `psd == &scrdev' failed.

When I display the bitmap file (8 bit palette image) with
GdDrawImageFromFile(hdc->psd, x,y,dx,dy, filename,0);
only the top half of the bitmap is displayed.

@ghaerr
Copy link
Owner

ghaerr commented Dec 6, 2023

Hello @uklatt,

hdcMem = CreateCompatibleDC( hdc );

Where is hdc initialized? Is this code part of something large in a window procedure callback function?

When I display the bitmap file (8 bit palette image) with
GdDrawImageFromFile(hdc->psd, x,y,dx,dy, filename,0);
only the top half of the bitmap is displayed.

In general, it isn't recommended to call Gdxxx routines directly from another (Win32 or Nano-X) API. What API are you writing programs in generally?

That said, the above GdDrawImageFromFile could be being clipped to the output window, depending on the API being used.

You might grep/look through the various demo programs in src/bin as well as demos/mwin and demos/nanox, there are a number which draw images.

Thank you!

@uklatt
Copy link
Author

uklatt commented Dec 7, 2023

Hi Greg,
hdc comes from BeginPaint() in WM_PAINT of the window.

If I use the image_penguine:

extern MWIMAGEHDR image_penguin;
PMWIMAGEHDR image = &image_penguin;

the following code works.

    case WM_PAINT:
      hdc = BeginPaint(hwnd, &ps);
      GetClientRect(hwnd, &rc);
      hdcMem = CreateCompatibleDC(hdc);
      hbmp = CreateCompatibleBitmap(hdcMem, image->width, image->height);
      hbmpOrg = SelectObject(hdcMem, hbmp);
      DrawDIB(hdcMem, 0, 0, image);
      StretchBlt(ps.hdc, 0, 0, rc.right, rc.bottom, hdcMem, 0, 0, image->width, image->height, MWROP_COPY);
      DeleteObject(SelectObject(hdcMem, hbmpOrg));
      DeleteDC(hdcMem);
      EndPaint(hwnd, &ps);
      break;

But when I try to load the same bitmap it doesn't work:

    case WM_PAINT:
      hdc = BeginPaint(hwnd, &ps);
      GetClientRect(hwnd, &rc);
      image = (PMWIMAGEHDR)GdLoadImageFromFile( "./penguin.bmp", 0 );
      hdcMem = CreateCompatibleDC(hdc);
      hbmp = CreateCompatibleBitmap(hdcMem, image->width, image->height);
      hbmpOrg = SelectObject(hdcMem, hbmp);
      DrawDIB(hdcMem, 0, 0, image);
      StretchBlt(ps.hdc, 0, 0, rc.right, rc.bottom, hdcMem, 0, 0, image->width, image->height, MWROP_COPY);
      DeleteObject(SelectObject(hdcMem, hbmpOrg));
      DeleteDC(hdcMem);
      EndPaint(hwnd, &ps);
      break;

gdb-output:

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
1920x1080x32bpp pitch 7680 type 0 visual 2 colors 16777216 pixtype 8
Program received signal SIGSEGV, Segmentation fault.
0x0000aaaaaaaa10c4 in wproc (hwnd=0xaaaaaaac19e0, message=15, wParam=0, lParam=0) at main.c:65
65                              hbmp = CreateCompatibleBitmap(hdcMem, image->width, image->height);
(gdb) print image
$1 = (PMWIMAGEHDR) 0xffffffffaaac6f80
(gdb) print image->width
Cannot access memory at address 0xffffffffaaac6f84

This looks like a 32Bit/64Bit pointer problem...

==========================

I found the reason!

I missed the declaration of GdLoadImageFromFile().
Without the declaration the return value of GdLoadImageFromFile() ist truncated to int (32 bits).

@uklatt
Copy link
Author

uklatt commented Dec 7, 2023

One small thing:

I use copy from memory device context to another memory device context.
This triggers the assert in gen_allocatememgc
I must disable this check.

PSD gen_allocatememgc(PSD psd)
{
	PSD	mempsd;
	// assert(psd == &scrdev);  // triggers when copy from one memory device context to another one
...
}

@ghaerr
Copy link
Owner

ghaerr commented Dec 8, 2023

image = (PMWIMAGEHDR)GdLoadImageFromFile( "./penguin.bmp", 0 );

In general, one can't call Gdxxx functions from the WIN32 API. The reason your program is crashing is that GdLoadImageFromtFile returns a PSD, where as a PMWIMAGEHDR is an entirely different structure. Casting from one structure pointer to another won't work.

For WIN32 API, generally you'll have to convert the image to a .c file, which the demos/mwin/mwdemo.c program does, or, you can convert the image to BMP format, then store load it from a .res resource file using resLoadBitmap. Look at demos/mwin/mwmine.c for how that can be done.

@uklatt
Copy link
Author

uklatt commented Dec 8, 2023

Hi Greg,
I compile the code on Linux x64 and it works ;-)
Thank you for your help
Uwe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants