Advertisment

Advanced Cellphone Programs in BREW

author-image
PCQ Bureau
New Update

In the previous two parts of the series, we have covered

how to set up the BREW environment, write basic applications and test them on

the cellphone. This time we will cover more advanced topics, and see how to draw

graphics, use sounds and set up timers and such for applications that require

it.

Advertisment
Direct Hit!
Applies to:

Cellphone app developers
USP:

Learn about the various functions used in BREW to do graphics programming, set timers and play sounds
Primary Link:

http://brew.qualcomm.com/brew/en/
Google keywords:

qualcomm brew

Setting up the basic code



The first thing that we need to do before we start writing the code for

drawing the graphics is to set up the application structure. This is needed

because, for example, all drawing functions in BREW will require a pointer to

the display device. This pointer, and several others are included in the

application structure and put in a header file, usually to be initialized on the

start of the application and destroyed when the application closes.

Here is the code for the header file that we will use for

our brew3 project:

Advertisment

// brew3.h



/* Application structure */







typedef struct _CIbrew3  {







            AEEApplet
a;







            AEEDeviceInfo
m_deviceInfo;







            IGraphics*
m_pIGraphics;



} CIbrew3;




This is a small header file, but will serve our purpose

well for now. Remember that for complex applications, you will mostly end up

keeping persistent data in this structure as well. Below is the code for brew3.c

that contains all our actual functions.

/* FILE: brew3.c */







#include "AEEModGen.h"
// Module interface definitions







#include "AEEAppGen.h"
// Applet interface definitions







#include "AEEShell.h"
// Shell interface definitions







#include "AEEStdLib.h"
// Standard libray







#include "AEEGraphics.h"
// Graphics interface definitions







#include "brew3.bid"     // Binary class id







#include "brew3.h"








Advertisment

static boolean

brew3_HandleEvent(IApplet * pi, AEEEvent eCode, uint16 wParam, uint32 dwParam);







static boolean brew3_InitObjects(CIbrew3* pApp);







static void brew3_CleanObjects(CIbrew3* pApp);







static void brew3_DrawScreen(CIbrew3* pApp);



int

AEEClsCreateInstance(AEECLSID ClsId,IShell * pIShell,IModule * po,void ** ppObj)







{







   *ppObj = NULL;







   if(ClsId == AEECLSID_BREW3){







      if(AEEApplet_New(sizeof(CIbrew3), ClsId,
pIShell,po,(IApplet**)ppObj, (AEEHANDLER)brew3_HandleEvent,



(PFNFREEAPPDATA)brew3_CleanObjects)  == TRUE)






return(AEE_SUCCESS);







   }







            return (EFAILED);







}



Advertisment

static boolean

brew3_HandleEvent(IApplet * pi, AEEEvent eCode, uint16 wParam, uint32 dwParam)











            CIbrew3* pApp
= NULL;  // Applet pointer







            pApp =
(CIbrew3*)pi;







            if (pApp ==
NULL)




return FALSE;







            switch (eCode)








            {







      case EVT_APP_START:


if (!brew3_InitObjects(pApp))





Advertisment

return FALSE;





brew3_DrawScreen(pApp);





return(TRUE);







      case EVT_APP_STOP:





Advertisment

return TRUE;



      default:





break;







   }







   return FALSE;







}



static boolean

brew3_InitObjects(CIbrew3* pApp) {







            int nRet=0;



Advertisment



// Create graphics object







            nRet =
ISHELL_CreateInstance(pApp->a.m_pIShell, AEECLSID_GRAPHICS, (void **)&pApp->m_pIGraphics);







            if (nRet !=
SUCCESS)







return FALSE;





// Get device info





ISHELL_GetDeviceInfo(pApp->a.m_pIShell,





&pApp->m_deviceInfo);







            return TRUE;







}



static void

brew3_CleanObjects(CIbrew3* pApp) {







            // Release
graphics object







            if (pApp->m_pIGraphics
!= NULL) {







IGRAPHICS_Release(pApp->m_pIGraphics);





pApp->m_pIGraphics = NULL;







            }







}



static void

brew3_DrawScreen(CIbrew3* pApp) {







            AEERect Rect;





IDISPLAY_ClearScreen(pApp->a.m_pIDisplay);







            Rect.x = 5;







            Rect.y = 5;







            Rect.dx =
pApp->m_deviceInfo.cxScreen - 10;







            Rect.dy =
pApp->m_deviceInfo.cyScreen - 10;







IDISPLAY_DrawRect(pApp->a.m_pIDisplay, &Rect,







MAKE_RGB(0,0,255), 0, IDF_RECT_FRAME);





IDISPLAY_Update(pApp->a.m_pIDisplay);







}

Long as it is, all it does is draw a blue border along the

border of the screen of the cellphone. Most of the code that we have put here is

necessary for the functioning of the simplest of applications, and you can build

functionality on top of this quite easily. If you trace the code, you will see

that it is the 'brew3_DrawScreen()' function that is doing the drawing. To

make our program draw other objects, we only need to modify this code. We have

initialized the pointer to the graphics interface, but haven't used it. The

rectangle function we have used does not need it, but many other graphics

functions require it. Following is a list of useful graphics functions.

IGRAPHICS_SetBackground: Sets the screen background

color



IGRAPHICS_SetClip: Sets the clipping rectangle. Any graphic updates
outside this rectangle do not take effect.







IGRAPHICS_StretchBlt: Draws an image by stretching it to fit a rectangle







IDISPLAY_BitBlt: Same as IGRAPHICS_StretchBlt, but with no stretching,
but faster



IDISPLAY_ClearScreen: Clears the screen


IDISPLAY_Update: Updates the screen after a graphics call. 


Otherwise there is big a chance that the screen will remain in its previous
state



IDISPLAY_FillRect: Fills a rectangle with color






Setting up timers



Threads do not exist in BREW. This is faked using timers. Timers set up a time
delay after which a function is automatically called. For instance, consider

that you have a ball bouncing around the screen and a score running of how many

bounces it has had.  After drawing the screen, you would call the function

that updates the ball position after a short delay by setting up a timer, and

meanwhile update the score if necessary. The function used to set timers is 'ISHELL_SetTimer'.

As arguments, it will take a pointer to the shell, the time delay in

milliseconds, name of the function to call, and the data that needs to be passed

to the function. 'ISHELL_CancelTimer' can be used to cancel any or all

timers in an application.


Using sound



Sound plays an important role in games and applications on cellphones. The

sound interface is also used for vibration, but that is something which is

ill-advised, since most BREW implementations of vibration differ from each other

and is difficult to standardize for. To play sounds, use the

'ISOUNDPLAYER_SetInfo' function to set the source and other settings. You

need to register a callback function (which periodically gets the status of

sound playback) using “ISOUNDPLAYER_RegisterNotify' and then actually play

using 'ISOUNDPLAYER_Play'.

Anuj Jain

Advertisment