i am adding a bit of animation code to my yoda app. i want his eyes to
blink :)
currently, i have the animation code taking place on a nilEvent.
however, everytime i interact with the forms buttons, or hit the
applications button, it seems like a nilEvent is generated because the
eyes blink. this action seriously disrupts the actions the buttons
produce. any tips on how to make this smoother? is there a better way
to do the animation?
i am including the entire source file below if you need to see my code
thanks in advance
pete
beware of line wrapping!!!
#include <Pilot.h>
#include "yoda.h"
#include "Callbacks.h"
static Err StartApplication(void)
{
FrmGotoForm(YodaForm);
SysRandom(TimGetTicks());
return 0;
}
static void StopApplication(void)
{
FrmCloseAllForms();
}
void DrawBitmap(Int x, Int y, Int id)
{
VoidHand h;
BitmapPtr p;
h = DmGet1Resource('Tbmp', id);
if (h != NULL)
{
p = (BitmapPtr) MemHandleLock(h);
WinDrawBitmap(p, x, y);
MemHandleUnlock(h);
}
DmReleaseResource(h);
}
static Int RandInt(Int MaxNo)
{
// returns 0 <= int <= MaxNo-1
return(SysRandom(0) % MaxNo);
}
static FieldPtr SetFieldTextFromStr(Word fieldID, CharPtr strP)
{
VoidHand txtH, oldTxtH;
FormPtr frm = FrmGetActiveForm();
FieldPtr fldP;
// get some space in which to stash the string
txtH = MemHandleNew(StrLen(strP) + 1);
if (!txtH) return NULL;
// copy the string to the locked VoidHand.
StrCopy(MemHandleLock(txtH), strP);
// unlock the string VoidHand
MemHandleUnlock(txtH);
// get the field and the field's current text VoidHand.
fldP = FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, fieldID));
ErrNonFatalDisplayIf(!fldP, "missing field");
oldTxtH = (VoidHand) FldGetTextHandle(fldP);
// set the field's text to the new text
FldSetTextHandle(fldP, (Handle) txtH);
FldDrawField(fldP);
// free the VoidHand AFTER we call FldSetTextHandle.
if (oldTxtH) MemHandleFree(oldTxtH);
return;
}
static Boolean MyFormHandleEvent(EventPtr event)
{
static Int oldrnd = 0;
Boolean handled;
Int rnd;
VoidHand h;
CharPtr s;
CALLBACK_PROLOGUE
handled = false;
switch (event->eType)
{
case ctlSelectEvent: // A control button was pressed and released.
if (event->data.ctlEnter.controlID==WisdomBtn)
{
rnd = 3000+RandInt(34);
while(rnd==oldrnd) rnd = 3000+RandInt(34);
oldrnd=rnd;
h = DmGetResource('tSTR', rnd);
s = MemHandleLock(h);
SetFieldTextFromStr(YodaField, s);
MemHandleUnlock(h);
DmReleaseResource(h);
handled = true;
}
if (event->data.ctlEnter.controlID==QuestionBtn)
{
rnd = 4000+RandInt(11);
while(rnd==oldrnd) rnd = 4000+RandInt(11);
oldrnd=rnd;
h = DmGetResource('tSTR', rnd);
s = MemHandleLock(h);
SetFieldTextFromStr(YodaField, s);
MemHandleUnlock(h);
DmReleaseResource(h);
handled = true;
}
break;
case nilEvent:
if (RandInt(2))
{
DrawBitmap(30, 56, 102+RandInt(2));
SysTaskDelay(SysTicksPerSecond() / 3);
DrawBitmap(30, 56, 101);
handled = true;
}
break;
case frmOpenEvent:
FrmDrawForm(FrmGetActiveForm());
handled = true;
break;
case menuEvent:
if (event->data.menu.itemID==5002)
{
FrmHelp(5000);
handled = true;
}
break;
}
CALLBACK_EPILOGUE
return(handled);
}
static Boolean ApplicationHandleEvent(EventPtr event)
{
FormPtr frm;
Int formId;
Boolean handled = false;
if (event->eType == frmLoadEvent)
{
// Load the form resource specified in the event then activate the
form.
formId = event->data.frmLoad.formID;
frm = FrmInitForm(formId);
FrmSetActiveForm(frm);
// Set the event handler for the form. The handler of the currently
// active form is called by FrmDispatchEvent each time it receives an
event.
switch (formId)
{
case YodaForm:
FrmSetEventHandler(frm, MyFormHandleEvent);
break;
}
handled = true;
}
return handled;
}
static void EventLoop(void)
{
EventType event;
Word error;
do
{
EvtGetEvent(&event, 10*SysTicksPerSecond()); //evtWaitForever);
if (! SysHandleEvent(&event))
if (! MenuHandleEvent(0, &event, &error))
if (! ApplicationHandleEvent(&event))
FrmDispatchEvent(&event);
}
while (event.eType != appStopEvent);
}
DWord PilotMain(Word cmd, Ptr cmdPBP, Word launchFlags)
{
Err err = 0;
if (cmd == sysAppLaunchCmdNormalLaunch)
{
if ((err = StartApplication()) == 0)
{
EventLoop();
StopApplication();
}
}
return err;
}