Forums | developer.brewmp.com Forums | developer.brewmp.com

Developer

Forums

Forums:

I just spent a few days at the BREW labs at Qualcomm, and I learned several things (the hard way) about games and graphics in BREW. Here are the key points:
1. NEVER use any of the IGRAPHICS_xxx methods inside a game loop. One would expect that IDISPLAY_ClearScreen() and IGRAPHICS_ClearRect would operate at roughly the same speed, but it turns out that IGRAPHICS_ClearRect takes a whopping 150 msec to clear the screen! Poof, there goes your frame rate right there. IDISPLAY_ClearScreen() takes almost zero time by comparison.
2. Avoid image transparency at (almost) all cost. If you have any large transparent images, they will take forever to draw. It is much better to break up an image like this into several non-transparent images. Also note that BREW is not smart enough to figure out by itself whether the image is transparent. If you set the raster operation for IIMAGE_Draw() as IPARM_ROP=AEE_RO_TRANSPARENT, BREW will draw the image by checking each pixel for transparency, regardless of whether the image actually has transparent pixels. So only use this raster op for images that actually do have transparency.
In my game I have some transparent images representing game sprites, so transparency here could not be avoided. Typically it takes 10-30 msec to do transparent drawing of each sprite on the T720.
3. The timer implementation on the T720 is really screwed up. Just because you asked for a timer event 100 msec from now does not mean you will get one. In my original code that worked fine on the emulator, I would wait until the end of the timer callback to call SetTimer to ask for another timer callback for the next game frame. I asked for an amount of time equal to the frame rate (100 msec) minus the amount of time already spent executing the current game loop. This logic should give me a constant 100 msec frame rate, and in fact does just that in the emulator. But on the T720 device, this didn't work at all. I had to restructure my code so that I always called SetTimer again at the very begining of my timer callback. For some strange reason I still have not figured out (and the BREW labs engineers haven't figure out either), you cannot wait until the end of a timer callback to call SetTimer again. This works fine for animations without user input, but any user input ends up firing a whole bunch of EVT_KEY and EVT_KEY_HELD events that somehow block timer execution until the events are handled. This means that when you press a key, the game loop won't fire again until you release the key, ie the whole game freezes! I spent a good deal of time discussing this with the BREW lab people, who discussed it with Motorola who agreed that this was an issue with their (Motorola's) implementation of BREW on the T720. The timer issue was a nightmare to debug and to work around. What seemed to help get around the problem (in addition to moving SetTimer to the beginning of the timer callback rather than the end) was to check each EVT_KEY_HELD event and fire the timer callback anyway if 100 msec has passed since the last time the game timer callback was called. In other words, you can't always rely on the timer itself - sometimes you need to take advantage of a user event (like EVT_KEY_HELD) to check independently of the timer to see if it is now time to execute the callback.
4. As a general rule of thumb, the speed of running one game loop in the emulator running on a standard PC seems to be approximately twice the speed that you get on a real device. So if the emulator looks like it slow, the app on the phone (the T720) will run twice as slow as that. So a game loop on the emulator should only take 40-60msec worst case - otherwise the frame rate you get on the real phone will not be acceptable.

After working through all these issues in a series of nightmarish debugging sessions, I was finally able to get my game working on the T720. I could only get about 8 frames per second - specifically a frame rate of 120 msec was the best I could do. As a point of comparison, the J2ME game runs just fine on a Cingular (GSM) T720 at 10 frames per second (100 msec frame rate). J2ME of course was much easier to use to create the game, and unlike BREW all the J2ME APIs worked as advertised.

Hopefully this advice is useful to other game developers and will help you avoid BREW's undocumented pitfalls that result in many hours or days of wasted debugging. If anyone has any additional tips, I would certainly be interested in hearing about them.

Thanks for the info, much appreciated! Looks like BREW and Motorola have a lot of work to do to make their platform attractive to game developers.

Thanks for the info, much appreciated! Looks like BREW and Motorola have a lot of work to do to make their platform attractive to game developers.

I wish Qualcomm would post informative information like this. I'm wracking my brains trying to get a Toshiba phone to display a simple bitmap image.
And of course it works fine in the simulator. :P

I wish Qualcomm would post informative information like this. I'm wracking my brains trying to get a Toshiba phone to display a simple bitmap image.
And of course it works fine in the simulator. :P

Yes, it would be nice if they would, eh?
3.0 should be better, I'm hoping. Of course, handsets are like a year away?

Yes, it would be nice if they would, eh?
3.0 should be better, I'm hoping. Of course, handsets are like a year away?

Well, I would like some experiences here as well. I was struggling for quite a long of time fith my fps ratio. I also noticed that most of BREW API functions are quite slow, so I ended up using just two IDISPLAY_BitBlt() and IDISPLAY_Update(). I am just preparing every frame as a bitmap manually and then copying it to the screen. Also I have done a few tests with ARM7TDMI processor used by BREW phones. It's quite slow, but a lot of things can be done. For example I have rewritten a few critical functions directly in ARM assembly language and I have achieved significant improvement. Also, any floating point calculations are not recommended. For example floating point multiplication may be 18 times slower than integer multiplication. After all I believe it should be possible to implement even a game with 3D graphics on Motorola T720, though it's not very easy task.

Well, I would like some experiences here as well. I was struggling for quite a long of time fith my fps ratio. I also noticed that most of BREW API functions are quite slow, so I ended up using just two IDISPLAY_BitBlt() and IDISPLAY_Update(). I am just preparing every frame as a bitmap manually and then copying it to the screen. Also I have done a few tests with ARM7TDMI processor used by BREW phones. It's quite slow, but a lot of things can be done. For example I have rewritten a few critical functions directly in ARM assembly language and I have achieved significant improvement. Also, any floating point calculations are not recommended. For example floating point multiplication may be 18 times slower than integer multiplication. After all I believe it should be possible to implement even a game with 3D graphics on Motorola T720, though it's not very easy task.

Can you give more information what is going wrong on Toshiba phone? I will have access to Toshiba in a few days so it might be useful to know what problems I can encounter before...
Quote:Originally posted by warpig
I wish Qualcomm would post informative information like this. I'm wracking my brains trying to get a Toshiba phone to display a simple bitmap image.
And of course it works fine in the simulator. :P

Can you give more information what is going wrong on Toshiba phone? I will have access to Toshiba in a few days so it might be useful to know what problems I can encounter before...
Quote:Originally posted by warpig
I wish Qualcomm would post informative information like this. I'm wracking my brains trying to get a Toshiba phone to display a simple bitmap image.
And of course it works fine in the simulator. :P

Zemowit,
Interesting idea, only using the bitblit and update funcs.
What critical functions did you retool in ARM asm?
Thanks,
meta4m

Zemowit,
Interesting idea, only using the bitblit and update funcs.
What critical functions did you retool in ARM asm?
Thanks,
meta4m

Well, I was doing some 3D animation, and I was implementing a function mapping 3D triangles from source bitmap into the destination bitmap. Obviously I did all improvements in C++ and then I decided to see how good is compiler's output. Apparently some things can be improved in assembly language and I achieved about 30% improvement so far. I don't know. But it was worth it. You can use -S (and also you may add -fs) flag with ARM compiler. It will then produce assembler output which can be modified and compiled again.

Well, I was doing some 3D animation, and I was implementing a function mapping 3D triangles from source bitmap into the destination bitmap. Obviously I did all improvements in C++ and then I decided to see how good is compiler's output. Apparently some things can be improved in assembly language and I achieved about 30% improvement so far. I don't know. But it was worth it. You can use -S (and also you may add -fs) flag with ARM compiler. It will then produce assembler output which can be modified and compiled again.

Quote:Originally posted by ziemowit
Can you give more information what is going wrong on Toshiba phone? I will have access to Toshiba in a few days so it might be useful to know what problems I can encounter before...
Sure, I've tried displaying the bitmap via the LoadShell() function passed into IImage giving it a filename and then using the IImage_BitBlt on an image stream that's been converted using CONVERTBMP.
For all intents and purposes, the Toshiba phone thinks it is displaying the bitmap. The AEEInfo structure is correctly filled out, however nothing is actually displayed on the phone itself. If I display controls before and after the bitmap, those show up, it's just the bitmap itself.
I can display bitmaps from a resource file, just not from the filesystem.

Quote:Originally posted by ziemowit
Can you give more information what is going wrong on Toshiba phone? I will have access to Toshiba in a few days so it might be useful to know what problems I can encounter before...
Sure, I've tried displaying the bitmap via the LoadShell() function passed into IImage giving it a filename and then using the IImage_BitBlt on an image stream that's been converted using CONVERTBMP.
For all intents and purposes, the Toshiba phone thinks it is displaying the bitmap. The AEEInfo structure is correctly filled out, however nothing is actually displayed on the phone itself. If I display controls before and after the bitmap, those show up, it's just the bitmap itself.
I can display bitmaps from a resource file, just not from the filesystem.

Well, I don't really understand. There is no such function like IIMAGE_BitBlt(). I guess you mean IIMAGE_Draw(). And I am not also sure if you are using CONVERTBMP correctly. As far as I am concerned CONVERTBMP() takes memory buffer containing bitmap in BMP file and returns a pointer to a buffer with an internal bitmap format. You should use IDISPLAY_BitBlt() to display a buffer returned by CONVERTBMP().
BTW, I would be grateful if you could check exactly how CONVERTBMP works on Toshiba phone. Does it actually make any convertion or just returns the same buffer? What happens to pbRealloc parameter?

Well, I don't really understand. There is no such function like IIMAGE_BitBlt(). I guess you mean IIMAGE_Draw(). And I am not also sure if you are using CONVERTBMP correctly. As far as I am concerned CONVERTBMP() takes memory buffer containing bitmap in BMP file and returns a pointer to a buffer with an internal bitmap format. You should use IDISPLAY_BitBlt() to display a buffer returned by CONVERTBMP().
BTW, I would be grateful if you could check exactly how CONVERTBMP works on Toshiba phone. Does it actually make any convertion or just returns the same buffer? What happens to pbRealloc parameter?

Here's the code itself:
Quote:
if(pConvertedBuffer == NULL) // Needs to be converted
{
pConvertedBuffer = CONVERTBMP(pBuffer, &aii, &bRealloc);
if(pConvertedBuffer == NULL) // Failed
return;
}
int16 my = -1;
// We have a valid buffer.
IDISPLAY_BitBlt(APP->Display(), x, y, cx, my, pConvertedBuffer, 0, 0, AEE_RO_COPY);
// Update the display
IDISPLAY_Update(APP->Display());
y += aii.cy;
return;
I posted IImage when I meant IDisplay.
Some notes. The structure contained in aii is properly filled with correct values when CONVERTBMP returns and also for the record, the allocation bit is set when CONVERTBMP returns.

Here's the code itself:
Quote:
if(pConvertedBuffer == NULL) // Needs to be converted
{
pConvertedBuffer = CONVERTBMP(pBuffer, &aii, &bRealloc);
if(pConvertedBuffer == NULL) // Failed
return;
}
int16 my = -1;
// We have a valid buffer.
IDISPLAY_BitBlt(APP->Display(), x, y, cx, my, pConvertedBuffer, 0, 0, AEE_RO_COPY);
// Update the display
IDISPLAY_Update(APP->Display());
y += aii.cy;
return;
I posted IImage when I meant IDisplay.
Some notes. The structure contained in aii is properly filled with correct values when CONVERTBMP returns and also for the record, the allocation bit is set when CONVERTBMP returns.

Also, I've tried some of the different raster ops including AEE_RO_OR which is suggested in the online knowledgebase and I get the same results despite the fact that it works on the emulator.

Also, I've tried some of the different raster ops including AEE_RO_OR which is suggested in the online knowledgebase and I get the same results despite the fact that it works on the emulator.

Your code looks fine. I can't see anything wrong there. I hope I will be able to test my application on Toshiba this Friday and then I will see if I can display bitmap properly. BTW, have you tried to display different bitmap sizes? Does your bitmap fit into the screen? I had a few problems with Motorola T720, as I was not able to draw some bitmaps. Apparently this behavior depended on bitmap size. I had no time to investigate this properly, but I have the impression there may be something wrong with IDISPLAY_BitBlt()

Your code looks fine. I can't see anything wrong there. I hope I will be able to test my application on Toshiba this Friday and then I will see if I can display bitmap properly. BTW, have you tried to display different bitmap sizes? Does your bitmap fit into the screen? I had a few problems with Motorola T720, as I was not able to draw some bitmaps. Apparently this behavior depended on bitmap size. I had no time to investigate this properly, but I have the impression there may be something wrong with IDISPLAY_BitBlt()

Yes I've tried different display sizes (smaller) with the same results.
Of course now (as of this morning) I have a test enabled T720 and I'm getting the exact same thing on it so now I have to wonder if there is a problem with my code after all despite the fact that it works on an emulator.

Yes I've tried different display sizes (smaller) with the same results.
Of course now (as of this morning) I have a test enabled T720 and I'm getting the exact same thing on it so now I have to wonder if there is a problem with my code after all despite the fact that it works on an emulator.

I got it to work. Even though I had tried it with smaller displays I still left the Y size parameter at -1. By decreasing the display height by a single pixel and then setting the Y size parameter to the actual pixel size it displayed correctly on both the Toshiba and the T-720.
Much thanks ziemowit for pointing me in the right direction by playing with the image size. It's a problem that's been plaguing me for a week now.

I got it to work. Even though I had tried it with smaller displays I still left the Y size parameter at -1. By decreasing the display height by a single pixel and then setting the Y size parameter to the actual pixel size it displayed correctly on both the Toshiba and the T-720.
Much thanks ziemowit for pointing me in the right direction by playing with the image size. It's a problem that's been plaguing me for a week now.

marcilgen mentioned that the timer is screwed up on the T720, I was wondering what was done to get around it.
I am setting the timer at the beginning of the loop, and have been trying various lengths.. and have noticed that device can actually handle a pretty decent framerate (15fps) of course this is a simple test application with a single transparent image... The problem is there are occasional hiccups or lags where the is a delay in the next execution of the loop, for example I usually can get 100ms timers, but occasionally they are 150ms. My main problem, is even if i set the delay fairly large (say 200ms) I still get occasional lag, Even though there is nothing different happening in my code. I have 3 questions relating to this
- Have other game developers been experiencing these lags as well?
- if so, are they just being accepted as something that cannot be worked around?
- Is this (timer probelm) only on the T720 device, or does this occur on other devices (ie Z800) as well?
as a small side note.. I have tried marcilgen's suggestions for avoiding IGraphics, and Transparency as well, but have not noticed much if any difference with or without either. (I tested this in a nearly-complete game application as well as my simple test application)
Thanks in advance,
-Tyndal

marcilgen mentioned that the timer is screwed up on the T720, I was wondering what was done to get around it.
I am setting the timer at the beginning of the loop, and have been trying various lengths.. and have noticed that device can actually handle a pretty decent framerate (15fps) of course this is a simple test application with a single transparent image... The problem is there are occasional hiccups or lags where the is a delay in the next execution of the loop, for example I usually can get 100ms timers, but occasionally they are 150ms. My main problem, is even if i set the delay fairly large (say 200ms) I still get occasional lag, Even though there is nothing different happening in my code. I have 3 questions relating to this
- Have other game developers been experiencing these lags as well?
- if so, are they just being accepted as something that cannot be worked around?
- Is this (timer probelm) only on the T720 device, or does this occur on other devices (ie Z800) as well?
as a small side note.. I have tried marcilgen's suggestions for avoiding IGraphics, and Transparency as well, but have not noticed much if any difference with or without either. (I tested this in a nearly-complete game application as well as my simple test application)
Thanks in advance,
-Tyndal

I'm dealing with this issue right now. Could somebody post some psuedo (or actual) code for the SetTimer workaround? My stuff is pretty similar to this, and I want to test a few things, but I'm not sure I understand what marcligen meant by "calling SetTimer at the beginning of the callback."
Thanks in advance for any help the crew here can offer!
m4m

I'm dealing with this issue right now. Could somebody post some psuedo (or actual) code for the SetTimer workaround? My stuff is pretty similar to this, and I want to test a few things, but I'm not sure I understand what marcligen meant by "calling SetTimer at the beginning of the callback."
Thanks in advance for any help the crew here can offer!
m4m

Here are some code snippets to show what I mean. Note that the very first thing I do in the callback function, before I run a agme loop, is to set the timer again so that I get another execution of the callback in FRAME_DELAY msec from now.
For some reason that I never figured out, this is the only way I could ever get the game timer to execute every FRAME_DELAY msec. If I waited until the end of gameTimerCB to set the timer again, it wouldn't work. Yes, I subtracted the actual execution time of running a single game loop and it still didn't work. In any case, doing it this way will work.
To set the game timer and request callback:
static void setGameTimer(void *p, UInt32 currtime, Int32 dt)
{
CSnowballApp * pMe = (CSnowballApp *)p;
ISHELL_SetTimer(pMe->a.m_pIShell, dt, gameTimerCB, (void *)pMe);
pMe->nextTimerTime=currtime+dt;

A portion of the callback:
void gameTimerCB(void *p)
{
Int16 lpdt=0;
CSnowballApp * pMe = (CSnowballApp *)p;
// get start time of loop
uint32 startTime=GETUPTIMEMS();
if (pMe->gamePaused) return;
if (pMe->displayState!=DISPLAY_GAME && pMe->displayState!=DISPLAY_GAMEOVER) return;
// NEW! set game timer from start time. No need to check for paused
// since check is done above
setGameTimer(pMe, startTime, FRAME_DELAY);
pMe->gameTimerCBisRunning=1;
// run one game loop here
if (pMe->displayState==DISPLAY_GAME) {
pMe->canvas->runOneLoop();
} else if (pMe->displayState==DISPLAY_GAMEOVER) {
pMe->canvas->runGameOver();
}
// do other things here ...

Here are some code snippets to show what I mean. Note that the very first thing I do in the callback function, before I run a agme loop, is to set the timer again so that I get another execution of the callback in FRAME_DELAY msec from now.
For some reason that I never figured out, this is the only way I could ever get the game timer to execute every FRAME_DELAY msec. If I waited until the end of gameTimerCB to set the timer again, it wouldn't work. Yes, I subtracted the actual execution time of running a single game loop and it still didn't work. In any case, doing it this way will work.
To set the game timer and request callback:
static void setGameTimer(void *p, UInt32 currtime, Int32 dt)
{
CSnowballApp * pMe = (CSnowballApp *)p;
ISHELL_SetTimer(pMe->a.m_pIShell, dt, gameTimerCB, (void *)pMe);
pMe->nextTimerTime=currtime+dt;

A portion of the callback:
void gameTimerCB(void *p)
{
Int16 lpdt=0;
CSnowballApp * pMe = (CSnowballApp *)p;
// get start time of loop
uint32 startTime=GETUPTIMEMS();
if (pMe->gamePaused) return;
if (pMe->displayState!=DISPLAY_GAME && pMe->displayState!=DISPLAY_GAMEOVER) return;
// NEW! set game timer from start time. No need to check for paused
// since check is done above
setGameTimer(pMe, startTime, FRAME_DELAY);
pMe->gameTimerCBisRunning=1;
// run one game loop here
if (pMe->displayState==DISPLAY_GAME) {
pMe->canvas->runOneLoop();
} else if (pMe->displayState==DISPLAY_GAMEOVER) {
pMe->canvas->runGameOver();
}
// do other things here ...

marcligen,
Thanks!
Where does nextTimerTime come in?
I'm also curious about how you handled the EVT_KEY_PRESSED issue. I am handling it, but it doesn't seem to be having much of an effect in the emulator. I'm wondering if this is still a bug in the 2.0 emulator?
Thanks again! You rock.

marcligen,
Thanks!
Where does nextTimerTime come in?
I'm also curious about how you handled the EVT_KEY_PRESSED issue. I am handling it, but it doesn't seem to be having much of an effect in the emulator. I'm wondering if this is still a bug in the 2.0 emulator?
Thanks again! You rock.

I use the function setGameTimer() to set the game timer. When I startup the app, I call setGameTimer() once, and this requests the callback gameTimerCB() be called at FRAME_RATE msec from now. As I discussed before, once in gameTimerCB() I call setGameTimerCB() yet again to request another call of gameTimerCB() another FRAME_RATE msec from now.
I found that even this approach would sometimes result in delays in calling the gameTimerCB. I don't really know why - I'm just guesing it had to do with the zillion of EVT_KEY_HELD events that get launched on the actual phone. To get around this problem, I decided to use a variable called nextTimerTime, which stores the actual time at which I want the next gameTimerCB to execute. Then in my mainevent handler, if the actual game loop is running and if I receive an EVT_KEY_HELD, I call a function called checkRunGameTimerCB(). This function just checks to see if it is now time to run gameTimerCB() even though the BREW timer hasn't called it yet. This enables me to get a slightly more regular framerate.
Here's the function:
static boolean checkRunGameTimerCB(void *p)
{
CSnowballApp * pMe = (CSnowballApp *)p;
UInt32 currtime=GETUPTIMEMS();
if (currtime >= pMe->nextTimerTime) {
ISHELL_CancelTimer(pMe->a.m_pIShell,gameTimerCB,(void *)pMe);
gameTimerCB(pMe);
return TRUE;
}
return FALSE;

Doing all this gave me 8 frames per second reliably. Of course on the J2ME version of the T720, I can get 10 frames per second in J2ME. Go figure.

I use the function setGameTimer() to set the game timer. When I startup the app, I call setGameTimer() once, and this requests the callback gameTimerCB() be called at FRAME_RATE msec from now. As I discussed before, once in gameTimerCB() I call setGameTimerCB() yet again to request another call of gameTimerCB() another FRAME_RATE msec from now.
I found that even this approach would sometimes result in delays in calling the gameTimerCB. I don't really know why - I'm just guesing it had to do with the zillion of EVT_KEY_HELD events that get launched on the actual phone. To get around this problem, I decided to use a variable called nextTimerTime, which stores the actual time at which I want the next gameTimerCB to execute. Then in my mainevent handler, if the actual game loop is running and if I receive an EVT_KEY_HELD, I call a function called checkRunGameTimerCB(). This function just checks to see if it is now time to run gameTimerCB() even though the BREW timer hasn't called it yet. This enables me to get a slightly more regular framerate.
Here's the function:
static boolean checkRunGameTimerCB(void *p)
{
CSnowballApp * pMe = (CSnowballApp *)p;
UInt32 currtime=GETUPTIMEMS();
if (currtime >= pMe->nextTimerTime) {
ISHELL_CancelTimer(pMe->a.m_pIShell,gameTimerCB,(void *)pMe);
gameTimerCB(pMe);
return TRUE;
}
return FALSE;

Doing all this gave me 8 frames per second reliably. Of course on the J2ME version of the T720, I can get 10 frames per second in J2ME. Go figure.

How did you get a transparent image?
I understand about setting the raster op to TRANSPARENT,
but Bitmap doesn't have a alpha value (to my knowledge), so how do you tell BREW that a pixel is transparent, or do you use a different file format?
Also, the resource editor allows you to have .gifs and other file formats, but I haven't been able to get any formats other than .bmp to show up! I'm just using ISHELL_LoadResImage and then IDISPLAY_DRAW. Is it possible to display other formats other than .bmp?
Thanks in advance!
Justin

How did you get a transparent image?
I understand about setting the raster op to TRANSPARENT,
but Bitmap doesn't have a alpha value (to my knowledge), so how do you tell BREW that a pixel is transparent, or do you use a different file format?
Also, the resource editor allows you to have .gifs and other file formats, but I haven't been able to get any formats other than .bmp to show up! I'm just using ISHELL_LoadResImage and then IDISPLAY_DRAW. Is it possible to display other formats other than .bmp?
Thanks in advance!
Justin

You need to set the "transparent" parts of your bitmap image to the color #ff00ff (magenta). Then use IDISPLAY_BitBlt() to display the image after converting it using CONVERTBMP. Transparent images are a real pain.
displayImage(myApp * pApp, int16 x, int16 y)
{
boolean realloc;
AEEImageInfo info;
AEEBmp* bmp;
void * pBmpData;
void * data;
bmp = ISHELL_LoadResData( pApp->pShell, MYAPP_RES_FILE, MYBMP_IMAGE , RESTYPE_IMAGE);
pBmpData=(byte *)(bmp) + *((byte *)(bmp));
data=CONVERTBMP(pBmpData,&info,&realloc);
IDISPLAY_BitBlt (pApp->pDisplay,x, y, info.cx,info.cy, data, 0, 0, AEE_RO_TRANSPARENT);
IDISPLAY_Update(pApp->pDisplay);
if(realloc==TRUE)
{
SYSFREE(data);
}
ISHELL_FreeResData(pApp->pShell,bmp);
}

You need to set the "transparent" parts of your bitmap image to the color #ff00ff (magenta). Then use IDISPLAY_BitBlt() to display the image after converting it using CONVERTBMP. Transparent images are a real pain.
displayImage(myApp * pApp, int16 x, int16 y)
{
boolean realloc;
AEEImageInfo info;
AEEBmp* bmp;
void * pBmpData;
void * data;
bmp = ISHELL_LoadResData( pApp->pShell, MYAPP_RES_FILE, MYBMP_IMAGE , RESTYPE_IMAGE);
pBmpData=(byte *)(bmp) + *((byte *)(bmp));
data=CONVERTBMP(pBmpData,&info,&realloc);
IDISPLAY_BitBlt (pApp->pDisplay,x, y, info.cx,info.cy, data, 0, 0, AEE_RO_TRANSPARENT);
IDISPLAY_Update(pApp->pDisplay);
if(realloc==TRUE)
{
SYSFREE(data);
}
ISHELL_FreeResData(pApp->pShell,bmp);
}

tyndal,
You can still use the Image API to handle transparent bitmaps. Just set its "transparent" parameter to true:
IIMAGE_SetParm(m_pIImage, IPARM_ROP, AEE_RO_TRANSPARENT, 0);

tyndal,
You can still use the Image API to handle transparent bitmaps. Just set its "transparent" parameter to true:
IIMAGE_SetParm(m_pIImage, IPARM_ROP, AEE_RO_TRANSPARENT, 0);

such a good and informative post should be on top!!

such a good and informative post should be on top!!