i want to Blt a welcome bitmap at the beginning of my snake game. this bitmap would be very big, so i decided to use exagone's giflib to load the welcome image as a gif. i created a procedure to do that job. but the problem is, that no matter how much gifs i load, and no matter which i want to display on the screen, there is ALWAYS displayed the one that i loaded first. i don't know if i forgot to clean something up or anything else. Following you have the Gif-loading-procedure and the other necessary procedures.



LoadAGIF proc uses edi esi ebx edx gifnr:DWORD,ptr_Bitmapinfo:DWORD,ptr_Surface:DWORD,bmpwidth:DWORD,bmpheight:DWORD

invoke GIFLoadResource, ADDR logogif, hInstance,gifnr
invoke GIFLoadHeader, ADDR logogif
invoke GIFInitalizeDecoder, ADDR logogif
invoke GIFGetMinimumColorType, ADDR logogif
mov logogif.dwImageFormat, eax
invoke GIFFillBitmapInfoStruct, ADDR logogif, ADDR BitmapInfo
invoke GIFGetColorTable, ADDR logogif, ADDR ColorTable



_ZeroMemory ddsd,sizeof(DDSURFACEDESC2)
mov ddsd.dwSize,sizeof(DDSURFACEDESC2)
mov ddsd.dwFlags,DDSD_CAPS OR DDSD_HEIGHT OR DDSD_WIDTH
mov ddsd.ddsCaps.dwCaps,DDSCAPS_OFFSCREENPLAIN
mov eax,bmpwidth
mov ddsd.dwWidth,eax
mov eax,bmpheight
mov ddsd.dwHeight,eax
mcall [LPDD],IDirectDraw7_CreateSurface,addr ddsd,ptr_Surface,NULL
.if eax==DD_OK
; Load bitmap to surface
mov edi,[ptr_Surface]
assume edi:ptr LPDIRECTDRAWSURFACE7
mcall [[edi]],IDirectDrawSurface7_GetDC,addr hdc
.if eax!=DD_OK
FATAL "GetDC failed!"
.endif
invoke CreateCompatibleDC,hdc
mov hbmpdc,eax
invoke CreateDIBSection, hdc, ADDR BitmapInfo, DIB_RGB_COLORS,\
addr bitptr, NULL, NULL
mov hbitmap, eax
push bitptr
pop logogif.lpImageData
invoke GIFDecompress, ADDR logogif
invoke GIFCleanup, addr logogif

invoke SelectObject,hbmpdc,hbitmap
invoke GetObject,hbitmap,sizeof(BITMAP),ptr_Bitmapinfo

invoke BitBlt,hdc,0,0,bmpwidth,bmpheight,hbmpdc,0,0,SRCCOPY
.if eax==0
FATAL "BitBlt failed!"
.endif
invoke DeleteDC,hbmpdc
mcall [[edi]],IDirectDrawSurface7_ReleaseDC,hdc

assume edi:nothing
xor eax,eax
ret
.endif

mov eax,-1
ret

LoadAGIF endp


here is the call to that procedure:



invoke LoadAGIF,2011,addr bmp_welcomemask_info,offset surface_welcomemask,480,300
invoke LoadAGIF,2012,addr bmp_welcomesprite_info,offset surface_welcomesprite,480,300


and although i loaded "welcomesprite" too, the following call paints the "welcomemask":



invoke DrawSimpleBitmap,50,50,offset surface_welcomesprite,offset bmp_welcomesprite_info


here is the "DrawSimpleBitmap" procedure:


DrawSimpleBitmap proc uses edi esi x:DWORD,y:DWORD,ptr_surface:DWORD,ptr_Bitmapinfo:DWORD
LOCAL rc : RECT
mov esi,[ptr_Bitmapinfo]
assume esi:ptr BITMAP
mov eax,x
mov rc.left,eax
mov rc.right,eax
mov eax,y
mov rc.top,eax
mov rc.bottom,eax
mov eax,[esi].bmWidth
add rc.right,eax
mov eax,[esi].bmHeight
add rc.bottom,eax
invoke RtlZeroMemory,addr ddbltfx,sizeof(DDBLTFX)
mov ddbltfx.dwSize,sizeof(DDBLTFX)
assume esi:nothing
mov esi,[ptr_surface]
assume esi:ptr LPDIRECTDRAWSURFACE7
mcall [dds_back],IDirectDrawSurface7_Blt,addr rc,[esi],NULL,DDBLT_WAIT,addr ddbltfx
assume esi:nothing
.if eax!=DD_OK
FATAL "Bliting the bitmap failed!"
.endif


ret
DrawSimpleBitmap endp


and here you have my rc-file:


2008 BITMAP "Bitmaps\body2_sprite.bmp"
2009 BITMAP "Bitmaps\snakefood_mask.bmp"
2010 BITMAP "Bitmaps\snakefood_sprite.bmp"
2011 RCDATA "Bitmaps\welcome_mask.gif"
2012 RCDATA "Bitmaps\welcome_sprite.gif"
2013 RCDATA "Bitmaps\welcome.gif"


i would be very glad if i could load the gifs without any problems, cause there is a big difference between loading a 500KB bitmap and a 13KB GIF.....

thanks,

nop
Posted on 2001-12-22 06:28:19 by NOP-erator
i want to Blt a welcome bitmap at the beginning of my snake game

If this is something like a SplashScreen, you may take a look at my SplashScreenLib (uploaded in the Algorithm section): with only 1 instruction you may add the SplashScreen to your Snake Game.

Sincerely,
Daniel

P.S.
The image must be stored ad as a Bitmap in the resources: this may enlarge you executable. Use an exe compressor (maybe UPX?) to shrink it again.
Posted on 2001-12-22 12:22:43 by dguzz
yeah, that would be probably ok, but it would be big in memory after unpacking, know what i mean? that's not that bad, but.....it doesn't solve my real problem.

Thomas/exagone, i thought that you could perhaps help me with that?

thanks,
nop
Posted on 2001-12-23 03:24:35 by NOP-erator
Hmm...
I'm not sure of just a thing: are resources loaded in memory when the application starts or only when they're explicitally loaded by the application?
If they're loaded only when used, my SplashScreen Load the Bitmap and then Destroy it.

Moreover, if your SplshScreen is not very big (300 x 200) and uses only 256 colors, the memory occupied is 60kb. I do not think this is a big memory occupation, working with actual PC where the minimum amount of memory is 64Mb or 128Mb and 256Mb are now common.

Sincerely,
Daniel
Posted on 2001-12-23 04:59:19 by dguzz
NOP-erator: I don't see any problems with the GIFlib code, you are using it correctly..
Try blitting to some window instead of the directx surface DC, to see if the GIF code works...

I think the gif is loaded correctly though. The only other thing I noticed is that the temporary DC (hdc) is destroyed without releasing the bitmap from it.

It should be this:


invoke CreateCompatibleDC,hdc
mov hbmpdc,eax
invoke CreateDIBSection, hdc, ADDR BitmapInfo, DIB_RGB_COLORS,\
addr bitptr, NULL, NULL
mov hbitmap, eax
push bitptr
pop logogif.lpImageData
invoke GIFDecompress, ADDR logogif
invoke GIFCleanup, addr logogif

invoke SelectObject,hbmpdc,hbitmap
push eax ;save old bitmap selected in hbmpdc
invoke GetObject,hbitmap,sizeof(BITMAP),ptr_Bitmapinfo

invoke BitBlt,hdc,0,0,bmpwidth,bmpheight,hbmpdc,0,0,SRCCOPY
pop ecx
.if eax==0
FATAL "BitBlt failed!"
.endif

invoke SelectObject, hbmpdc, ecx
invoke DeleteObject, hbitmap ;don't forget to destroy the bitmap as well
invoke DeleteDC, hbmpdc


Maybe this causes it.

Thomas
Posted on 2001-12-23 05:25:34 by Thomas
hi,

i tried your code without bliting on a dx surface, just on a normal window. then it works.......strange.......i think i have to test some things. is it possible to Blt a GDI-DC to a DX-DC?

nop
Posted on 2001-12-23 11:16:01 by NOP-erator
hi thomas,

as i told you, this deleting of the bitmap was NOT the problem. I tried all things i could to get it to work. i changed the variables for every call of the LoadAGif procedure, i changed the order of the code, i tried everything. finally i decided to use GIFLoadFile instead of GIFLoadResource, and........IT WORKS!!!

conclusion: there is something....no, there MUST be something wrong with your GIFLoadResource procedure. remember another game from me? this monopoly stuff? i had the same problem there, but there it appeared after my .data section became incredibly big.

could you have a look over your GIFLoadResource procedure again, please? i think this is evidence enough that there must be the bug.....

nop
Posted on 2001-12-23 12:09:53 by NOP-erator
Hmm really strange.. the GIFLoadResource function is pretty straight forward:


;===============================================================================
; GIFLoadResource
;===============================================================================
; Loads gif data from a resource (of type RT_RCDATA)
; lpName:pointer to a resource name OR resource ID
GIFLoadResource proc uses esi edi lpGifInfo:DWORD, hInst:DWORD, lpName:DWORD
mov esi, lpGifInfo
assume esi:PTR GIF_INFO

invoke FindResource, hInst, lpName, RT_RCDATA
.IF eax==0
ret
.ENDIF
push eax
invoke LoadResource, hInst, eax
.IF eax==0
pop ecx
ret
.ENDIF
mov [esi].lpGIFData, eax
pop eax
invoke SizeofResource, hInst, eax
.IF eax==0
ret
.ENDIF
mov [esi].dwGIFDataSize, eax
assume esi:nothing
xor eax, eax
inc eax
ret
GIFLoadResource endp


I don't see anything that can go wrong here? What value does it return?
You can also load the gif resource yourself with the code above, and see where it goes wrong.

Thomas
Posted on 2001-12-23 12:19:03 by Thomas
i perhaps have an good idea: how about loading the resource the same way as you do with the file? why don't you get a pointer to the resource data (you can also get the size easily), and then copy this resource to allocated memory (GlobalAlloc).

i don't know how to do that, cause i don't know how to copy the resource to the memory location.......perhaps you can do that?

bye,

nop
Posted on 2001-12-23 12:42:40 by NOP-erator
I don't see any reason to do so but here you go:


invoke GIFLoadResource, ADDR logogif, hInstance,gifnr
invoke GlobalAlloc, GMEM_FIXED, logogif.dwGIFDataSize
mov ecx, logogif.lpGIFData
mov logogif.lpGIFData, eax
invoke MemCopy, eax, ecx, logogif.dwGIFDataSize

(untested code)

Memory should be freeed with GlobalFree too (There is a bug in the file demo, I didn't cleanup memory allocated to load the file. It's in the documentation though).

Thomas
Posted on 2001-12-23 12:57:47 by Thomas
If this doesn't work, rename the procedure I posted (the GIFLoadResource one) to something else, and use that one instead of GIFLoadResource. Add some breakpoints or debug code and tell me if some function fails.

Thomas
Posted on 2001-12-23 12:59:40 by Thomas
ok, my idea did not work. the same result. this is what i found out:

- if i use your GIFLoadResource and try to display the second GIF (welcomesprite), it shows me the first GIF (welcomemask)

- if i insert the code for your GIFLoadResource manually, and then try to display the second gif, i just get a black bitmap.



lea esi, logogif
assume esi:PTR GIF_INFO
invoke FindResource,hInstance,gifnr,RT_RCDATA
push eax
invoke LoadResource,hInstance,eax
mov [esi].lpGIFData, eax
pop eax
invoke SizeofResource,hInstance,eax
mov [esi].dwGIFDataSize, eax
assume esi:nothing


- your code that you postet last, makes the WHOLE screen black, and nothing happens. i changed the code a bit, but the second gif wasn't displayed properly, too. one half was welcomemask, and the other half of black.

- i started debugging the second point (loading the resource manually), and found out, that FindResource returns zero after calling the procedure the second time to load welcomesprite. I used GetLastError to find out which error it is exactly, and got error 56 - The parameter is not correct!

but what does that mean? what parameter is not correct? the resource number of the gif was ok, the hInstance was ok, and RT_RCDATA is a constant, everything was the same, but the resource number (but it was ok, too).

really strange. There is also another strange thing: when i load the two gifs in a "normal" program and Blit them on a "normal" window, it works. reeeeally strange. but why didn't work with my monopoly game? hmm, my monopoly game had a big data section, but......... I'm confused :confused:

nop
Posted on 2001-12-24 04:25:27 by NOP-erator

- i started debugging the second point (loading the resource manually), and found out, that FindResource returns zero after calling the procedure the second time to load welcomesprite. I used GetLastError to find out which error it is exactly, and got error 56 - The parameter is not correct!


Well one of these has to be incorrect:
1. hInstance: although unlikely, you didn't forget to initialize hInstance?
2. resID: should be okay
3. RT_RCDATA: this is the only thing I can think of, what value does this constant have in your include file? Its 10 (dec) for me. If it's wrong in your version that would explain why it didn't work for the monopoly game either.

If all these are correct, is the resource file linked correctly?

Thomas
Posted on 2001-12-24 04:54:42 by Thomas
ok, it works now. you know what i did? i first tried to get a valid handle to all the resources when i use LoadResource one after the other. it worked. then i changed my code into this:



invoke FindResource,hInstance,2011,RT_RCDATA
mov gifarray[0],eax
invoke FindResource,hInstance,2012,RT_RCDATA
mov gifarray[4],eax
invoke LoadAGIF,gifarray[0],addr bmp_welcomemask_info,offset surface_welcomemask,480,300,hWin
invoke LoadAGIF,gifarray[4],addr bmp_welcomesprite_info,offset surface_welcomesprite,480,300,hWin

-----------------------
;this is the gifloading procedure:
lea esi, logogif
assume esi:PTR GIF_INFO
invoke LoadResource,hInstance,gifnr
mov [esi].lpGIFData, eax
invoke SizeofResource,hInstance,gifnr
mov [esi].dwGIFDataSize, eax
assume esi:nothing



that's all. don't ask me, why i don't get a valid handle to the resources, when i don't load them one after the other.....

thanks for your effort,

nop
Posted on 2001-12-24 05:41:13 by NOP-erator
Hmm really strange.. I've never had problems with loading multiple gifs sequentially, but I'm glad it works now.

Thomas
Posted on 2001-12-24 09:41:23 by Thomas