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.

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:

// 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"

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);



}

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))


return FALSE;


brew3_DrawScreen(pApp);


return(TRUE);



      case EVT_APP_STOP:


return TRUE;

      default:


break;



   }



   return FALSE;



}

static boolean
brew3_InitObjects(CIbrew3* pApp) {



            int nRet=0;


// 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

Stay connected with us through our social media channels for the latest updates and news!

Follow us: