The State Table
An app is generally run through events passed in to it. These events are controlled by a series of state tables which indicate which events are to put the app into what state and how long to process that app for. A state table consists of a single byte followed by a series of three byte entries with a EVENT_END terminator byte after the last entry. Each entry has three parts to it:
The initial byte is the state to enter if an event is encountered which does not match any entry in the table.
Special State Tables
State table 0 is always entered first for an app. It will almost always have an EVT_ENTER entry in it so that you can know when an application is first called.
If an app supports nesting (all WristApps might), then it will be entered by a call to State Table 1 with an EVT_NEST event. All other state tables are completely defined by the application and may be used in any way that you want. Often a separate state is used for each mode that the app might have (such as a set mode). In order to switch between states, either you code the new state with the event, such as with the EVT_SET operation OR you can post a user event which has an associated entry in the state table that has the new state for that event.
There are two special state values associated with an event. $FF is used to indicate that the app wishes to exit and go to the next app. For WristApps, this means go back to the time app. $FE is a special value used to handle returning from a EVT_NEST nesting. If all of the nested app processing occurs in state 1, then this value would appear for an entry in the state1 table. For all others, it is assumed to be the new state table to select. No error checking is done on any of these values.
One very nice thing that can be done with the events is posting a timer to go off if no other event occurs after the current event. There are two timers although only one can be active at a time. The reason for this is to allow the app to quickly distinguish between which event timed out without having to save some global variable. These timer values are fixed in the ROM and you select which timer interval you want through the value you set. For a strange happenstance, all of the intervals of the second timer are also available for the first time (but I would be careful not to count on that).
One important event that an application should handle is the EVT_RESUME which occurs after a nested app terminates. This allows your application to pick up after an alarm or appointment has gone off. When you get this event, it is a pretty good idea to refresh the display since you don't know what state the other app left it in. You should also use this time to restore any system flags that you may have set. You should also be aware that before your app is suspended, the system will call your suspend function at WRIST_SUSPEND ($0113). That will be your chance to save any variables that you expect to have trashed.
For the events, there are three forms of the button events. The EVT_NEXT, EVT_MODE, EVT_SET, EVT_PREV, and EVT_GLOW events allow you to see when the corresponding button is pressed. When you get one of these events, you will not get notification of when the button was released. There is a set of events EVT_DNNEXT, EVT_DNMODE, EVT_DNSET, EVT_DNPREV and EVT_DNGLOW which give you the down transition for those buttons and the corresponding set of events EVT_UPNEXT, EVT_UPMODE, EVT_UPSET (I like that name), EVT_UPPREV, and EVT_UPGLOW which tell you when the button has been released. It is the case that the UP event can be handled by a different state than the DN event.
If you want to get any of those buttons, you can look for EVT_ANY (and EVT_DNANY, EVT_UPANY) which will call when any of the 5 buttons have been pressed. In order to figure out which button was pressed, your code will need to look at BTN_PRESSED ($04c3) which will contain one of the EVT_NEXT, EVT_MODE, EVT_SET, EVT_PREV, and EVT_GLOW values. Often an application does not have an interest in the Indiglo button but cares about the other 4 buttons. For this, you can use EVT_ANY4 (and EVT_DNANY4, EVT_UPANY4) just the same way as the EVT_ANY events.
The EVT_TIMER1 and EVT_TIMER2 events come in when the timer associated with a particular event has elapsed without another event being posted. There is no requirement of using a particular timer for a given event other than to allow you to distinguish between which event occurred. The two timers have slightly different values for when they go off and that might slightly affect your choice of timers (but that is rare). From experimentation, it appears that the time cycle for the TIMER1 is a bit slower than that for Timer2. I recommend that you use Timer2 for any of the fast actions and timer1 for the slower ones (like timing out the display).
The EVT_USER0, EVT_USER1, EVT_USER2, and EVT_USER3 events are for an application to use for anything it wants to. Most of the time, these are useful for transitioning to a different state. You can post an event by calling POSTEVENT.
The only other event is EVT_IDLE. This event is sent only to the TIME app when another app has been suspended because it was idle for more than three minutes. Since a wristapp could never get this event, it is probably worth ignoring.
Here are the constants which you would find useful in creating your app:
Note that the second part of this table is happen-stance since it is really a rollover of the second table on top of the first one. But it might be useful to someone...