This chapter explains the event structure and specific usage of event management functions.
By using the concept of events, it is possible to describe a program as a combination of program events (each element in the program), which makes it very easy to understand the flow of the entire program. Furthermore, since each program event can be used in common, programs can be simplified.
Figure 10-1 Event image
/* front omitted */ slInitEvent(); /* Initialize the event */ slSetEvent((void*) game_demo ); /* Register event */ slSetEvent((void*) game_play ); slSetEvent((void*) game_over ); slExecuteEvent(); /* Execute event */ void game_demo(EVENT *evptr){ /* Event execution 1(game_demo) */ : } void game_play(EVENT *evptr){ /* Event execution 2(game_play) */ : } void game_over(EVENT *evptr){ /* Event execution 3(game_over) */ : } /* after omitted */ |
Figure 10-2 EVENT Structure
*work: Start address of WORK structure for user area expansion. *next: Start address of the next event to be executed. *before: Start address of the event to be executed immediately before. *exad(): Start address of the area where the function to be executed as an event is stored. user[]: User area for storing variables used by events registered functions. It is also possible to expand the user area using work etc.
Figure 10-3 Event list structure
Note | If you use event processing without initializing the event, it will become inconsistent with uninitialized buffers, event lists, etc., and in the worst case, the CPU may stop. (Detail is |
---|
Figure 10-4 Creating an event list
● Event format ●void function_name(EVENT *evptr){execute_contents} ↑ ↑ ↑ | | Event execution details | Start address of EVENT structure Event name
/* front omitted */ slSetEvent((void *)init_cube); slExecuteEvent(); typedef struct cube{ FIXEDpos[xyz]; ANGLE ang[xyz] ; : Sint16 unset_count; Sint16 unset_i; } CUBE; void init_cube(EVENT *evptr) { CUBE *cubeptr; cubeptr=(CUBE *)evptr -> user; cubeptr-> pos[x]=pos_x; : cubeptr-> unset_count=0; disp_cube(evptr); } /* after omitted */ |
Figure 10-7 Executing an event
Figure 10-8 Adding an event
Figure 10-9 Inserting an event
Figure 10-10 Deleting an event
Figure 10-11 Changing the event list while an event is running
Figure 10-12 WORK structure
*next: Start address of the WORK structures that you want to connect as a chain structure. If there is no work that follows as a chain structure, NULL is assigned. user[]: Extended user area (60 bytes).
Figure 10-13 Connecting workpieces
Figure 10-14 Expanding the user area using event RAM area
The EVENT structure specified by the function “slReturnEvent” is returned to the system.
The EVENT structure continues to exist in the event list because it is not released as an event.
Since the area is system-free, it can be used freely using functions such as "slSetEvent".
Although it is registered in the event list, since the area is free, the contents of the EVENT structure are rewritten, which causes a problem in the chain structure.
The chain structure will become inconsistent, and in the worst case, the CPU will stop.
Figure 10-15 Incorrect event operation
Flow 10-1 Event processing flow
/*------------------------------------------------ ----------------------*/ /* Event Demo */ /*------------------------------------------------ ----------------------*/ #include "sgl.h" void ss_main(void) { slInitSystem(TV_320x224,NULL,1); slPrint("Sample program 10" , slLocate(9,2)) ; set_event(); while(-1) { slExecuteEvent(); slSynch(); } }
Flow 10-2 sample_10: Main loop
#include "sgl.h" extern PDATA PD_CUBE; #define POS_X toFIXED(0.0) #define POS_X_UP 200.0 #define POS_Y toFIXED(20.0) #define POS_Z toFIXED(270.0) #define POS_Z_UP 50.0 #define SET_COUNT 500 static void init_cube2(EVENT*); typedef struct cube { FIXED pos[XYZ]; ANGLE ang[XYZ]; ANGLE angx, angz; ANGLE angx_up , angz_up; PDATA *poly; Sint16 set_count , set_i; Sint16 unset_count , unset_i; } CUBE; static void disp_cube(EVENT *evptr) { CUBE *cubeptr; cubeptr = (CUBE *)evptr-> user; slPushMatrix(); { slTranslate(cubeptr-> pos[X] , cubeptr-> pos[Y] , cubeptr-> pos[Z]); cubeptr-> pos[X] = POS_X + POS_X_UP * slSin(cubeptr-> angx); cubeptr-> pos[Y] = cubeptr-> pos[Y]; cubeptr-> pos[Z] = POS_Z + POS_Z_UP * slCos(cubeptr-> angz); cubeptr-> angx += cubeptr-> angx_up; cubeptr-> angz += cubeptr-> angz_up; slRotY(cubeptr-> ang[Y]); slRotX(cubeptr-> ang[X]); slRotZ(cubeptr-> ang[Z]); cubeptr-> ang[X] += DEGtoANG(5.0); cubeptr-> ang[Y] += DEGtoANG(5.0); cubeptr-> ang[Z] += DEGtoANG(5.0); slPutPolygon(cubeptr-> poly); } slPopMatrix(); cubeptr-> set_count -= cubeptr-> set_i; if(cubeptr-> set_count< 0 ) { slSetEvent( (void *)init_cube2 ); cubeptr-> set_count = SET_COUNT; } cubeptr-> unset_count -= cubeptr-> unset_i; if(cubeptr-> unset_count< 0 ) slCloseEvent(evptr); } static void init_cube1(EVENT *evptr) { CUBE *cubeptr; cubeptr = (CUBE *)evptr-> user; cubeptr-> pos[X] = POS_X; cubeptr-> pos[Y] = POS_Y; cubeptr-> pos[Z] = POS_Z; cubeptr-> ang[X] = cubeptr-> ang[Y] = cubeptr-> ang[Z] = DEGtoANG(0.0); cubeptr-> angx = cubeptr-> angz = DEGtoANG( 0.0); cubeptr-> angx_up = cubeptr-> angz_up = DEGtoANG( 0.0); cubeptr-> set_count = SET_COUNT; cubeptr-> set_i = 1; cubeptr-> unset_count = 0; cubeptr-> unset_i = 0; cubeptr-> poly = &PD_CUBE; evptr-> exad = (void *)disp_cube; disp_cube(evptr); } static void init_cube2(EVENT *evptr) { CUBE *cubeptr; cubeptr = (CUBE *)evptr-> user; cubeptr-> pos[X] = POS_X; cubeptr-> pos[Y] = POS_Y - toFIXED(50); cubeptr-> pos[Z] = POS_Z + POS_Z_UP; cubeptr-> ang[X] = cubeptr-> ang[Y] = cubeptr-> ang[Z] = DEGtoANG(0.0); cubeptr-> angx = cubeptr-> angz = DEGtoANG( 0.0); cubeptr-> angx_up = cubeptr-> angz_up = DEGtoANG( 3.0) * (-1); cubeptr-> set_count = 0; cubeptr-> set_i = 0; cubeptr-> unset_count = SET_COUNT / 2 ; cubeptr-> unset_i = 1; cubeptr-> poly = &PD_CUBE; evptr-> exad = (void *)disp_cube; disp_cube(evptr); } static void init_cube3(EVENT *evptr) { CUBE *cubeptr; cubeptr = (CUBE *)evptr-> user; cubeptr-> pos[X] = POS_X; cubeptr-> pos[Y] = POS_Y + toFIXED(50); cubeptr-> pos[Z] = POS_Z + POS_Z_UP; cubeptr-> ang[X] = cubeptr-> ang[Y] = cubeptr-> ang[Z] = DEGtoANG(0.0); cubeptr-> angx = cubeptr-> angz = DEGtoANG( 0.0); cubeptr-> angx_up = cubeptr-> angz_up = DEGtoANG( 3.0); cubeptr-> set_count = 0; cubeptr-> set_i = 0; cubeptr-> unset_count = 0; cubeptr-> unset_i = 0; cubeptr-> poly = &PD_CUBE; evptr-> exad = (void *)disp_cube; disp_cube(evptr); } void *event_tbl[] = { init_cube1 , init_cube2 , init_cube3 }; void set_event() { EVENT *evptr; void **exptr; Uint16cnt; slInitEvent(); for(exptr = event_tbl , cnt = sizeof(event_tbl) / sizeof(void *); cnt--> 0;) { evptr = slSetEvent(*exptr++); } }
Flow 10-3 samp_10: Event execution details
functional type | Function name | Parameter | function |
---|---|---|---|
void | slInitEvent | void | Initialize the event |
EVENT | *slSetEvent | void(*func)() | Event list Register/add events |
void | slExecuteEvent | void | Execute events registered in the list in order |
EVENT | *slSetEventNext | EVENT *evptr,void(*func)() | Inserts/registers a new event immediately after the specified event |
void | slCloseEvent | EVENT *evptr | Delete the event from the event list and return/release the attached work to the system at the same time. |
WORK | *slGetWork | void | Secure your work area |
void | slReturnWork | WORK *wkptr | Return/release work area |
EVENT | *slGetEvent | void | Reserve a RAM area of the same size as the event in event RAM. |
void | slReturnEvent | EVENT *evptr | Returns and releases the area secured by the function "slGetEvent" to the system. |