Overview -------- With film functions you can put together a lot of graphics, put them into different graphical sequences and give all out step by step as a film. ***** A film is not needed while playing actively a game, but only for non-interactive sequences (e.g. for introducing). ***** You can imagine a film as a matrix of pictures. E.g. when you have 3 sequences, then your film might look as following: seq 1: <picture 1> <picture 2> <picture 3> ... seq 2: <picture 1> <picture 2> <picture 3> ... seq 3: <picture 1> <picture 2> <picture 3> ... Each picture (bild) has additional information: how long to be seen, relative coordinates, sound Each sequence is independed of other sequences. E.g. one sequence is a dog running from left to right, another sequence a flying bird, sometimes whistling. Each picture is an image of the dog/bird with info, where to be put, how many loops staying, and whether playing a sound. For extended use you can declare and use a "film subcall" (see below). The functions ------------- film * create_film(int arg1): create a new film Arguments: - arg1: number of sequences Return value: pointer to created film NULL=error Example: film * flm; // create a film with 3 sequences if ((flm=create_film(3))==NULL) { [...error...] } void free_film(film * arg1): destroy a film and free memory Arguments: - arg1: created film Example: film * flm; if ((flm=create_film(3))==NULL) { [...error...] } free_film(flm); int add_bild_to_film(film * arg1,film_bild * arg2,int arg3): append a picture (bild) to a film at a certain sequence (graphics are duplicated, see argument pic at SET_FILM_BILD) Arguments: - arg1: created film - arg2: picture filled with SET_FILM_BILD() - arg3: sequence number Return value: position of picture in the sequence -1=error Example: film * flm; film_bild bld; if ((flm=create_film(3))==NULL) { [...error...] } [ ... ] add_bild_to_film(flm,&bld,1) /* append at sequence number 1 */ [ ... ] add_bild_to_film(flm,&bld,1) /* append at sequence number 1 */ void reset_film(film * arg1,void * arg2,int arg3): rewind a film Arguments: - arg1: created film - arg2: a pointer of your choice (only used by a "film subcall") or NULL - arg3: a number other than 0 (only used by a "film subcall") Example: film * flm; if ((flm=create_film(3))==NULL) { [...error...] } [ ... ] reset_film(flm,NULL,1); unsigned long copy_film(grafik * arg1,film * arg2,void * arg3): give out the next step of a film to a graphic or backbuffer Arguments: - arg1: output to graphic or NULL=backbuffer - arg2: created film - arg3: a pointer of your choice (only used by a "film subcall") or NULL Return value: current step number of film Example: film * flm; unsigned long l1; if ((flm=create_film(3))==NULL) { [...error...] } [ ... ] reset_film(flm,NULL,1); // give out 320 steps do { CLEAR_BOX(NULL,RGB_BLACK); l1=copy_film(NULL,flm,NULL); /* next step */ flush_window(); wait_time(40); } while (l1<320UL); void SET_FILM(film * flm,int id,int x,int y,void (*func)(film *,void *,int)): Macro to set global values of a film Arguments: - flm: created film - id: ID of the film, what you want - x,y: absolute x/y coordinates to put film out to graphic - func: "film subcall" or NULL The "film subcall" must be declared as void function(film *,void *,int); Every time you call copy_film(), this function is called, too. See below for more details. Example: film * flm; if ((flm=create_film(3))==NULL) { [...error...] } SET_FILM(flm,1,0,0,NULL); void SET_FILM_BILD(film_bild * bld,grafik * pic,int x,int y,int ft,int count_to,int wnr,int wch,short wvol): Macro to set a picture of a sequence of a film Arguments: - bld: address to picture (bild) - pic: graphic of this picture or NULL=no graphic this graphic is as a copy duplicated, so you can free it after call to add_bild_to_film() - x,y: relative x/y coordinates to them to the film (see SET_FILM()) - ft: graphic output: RGB_FULL or RGB_TRANS - count_to: steps how long graphic is shown - wnr: wave number got with load_wave() or 0=no sound or -1=stop sound - wch: channel(s) to play/stop sound (see arg2 of play_wave()) or 0 - wvol: time to in/decrease volume (see arg4 of play_wave()) or 0 Example: film_bild bld; grafik * grf=load_grafik("test.vga"); // set picture: graphic is "test.vga", // coordinates are +10/+10 relative to film coordinates // graphic shall be shown 5 steps SET_FILM_BILD(&bld,grf,10,10,RGB_TRANS,5,0,0,0); Short example ------------- We want to show a clock which makes to one side "tick" and to the other "tack" Our graphics: - a clock: +----+ | \_ | | | | | +----+ - a pendulum right and left: / \ / \ O O to get: +----+ and +----+ | \_ | | \_ | | / | | \ | |/ | | \| O----+ +----O program: film * flm; film_bild bld; grafik * grf; int wv[2]; unsigned long l1; [ ... ] // initialization wv[0]=load_wave("tick.wav",TYP_IS_WAVE); wv[1]=load_wave("tack.wav",TYP_IS_WAVE); // we need 2 seqences, 1 for the clock, 1 for the two pendulums if ((flm=create_film(2))==NULL) { [...error...] } SET_FILM(flm,1,0,0,NULL); /* put the clock to coordinates 0/0 */ // set the 1. sequence only with the clock grf=load_grafik("clock.vga"); // step value 100, but could be any other, because in 1.seq is only 1 picture // and after sequence is over it begins again SET_FILM_BILD(&bld,grf,0,0,RGB_FULL,100,0,0,0); add_bild_to_film(flm,&bld,1); /* to 1.seq */ free_grafik(grf); // set the 2. sequence with the two pendulums grf=load_grafik("tick.vga"); // we assume relative coordinates to be at 0,20 // and want to show "tick" 10 steps // and want to play sound "tick.wav" at channel 1 SET_FILM_BILD(&bld,grf,0,20,RGB_TRANS,10,wv[0],CN_(1),0); add_bild_to_film(flm,&bld,2); /* to 2.seq */ free_grafik(grf); grf=load_grafik("tack.vga"); // we assume relative coordinates to be at 30,20 // and want to show "tack" 10 steps // and want to play sound "tack.wav" at channel 1 SET_FILM_BILD(&bld,grf,30,20,RGB_TRANS,10,wv[1],CN_(1),0); add_bild_to_film(flm,&bld,2); /* again to 2.seq */ free_grafik(grf); // film is ready, now output reset_film(flm,NULL,1); /* here not needed */ // give out 1000 steps: that is 50 x tick and 50 x tack do { CLEAR_BOX(NULL,RGB_BLACK); l1=copy_film(NULL,flm,NULL); /* next step out to backbuffer */ flush_window(); wait_time(50); } while (l1<1000UL); // free film free_film(flm); Example with a "film subcall" ----------------------------- We want the same as in the short example above, but after 10 "tacks" (200 steps), the pendulum shall be twice as fast. And after 400 steps we don't want to show the clock any more, only the pendulum. From the program above we have to change: SET_FILM(flm,1,0,0,filmfunc); Then we have to write the "film subcall": void filmfunc(film * flm,void * data,int flag) { if (flag==1) { /* reset_film() called, we had set arg3 to 1 */ // now we have to set the struct (see vgagames.h) manually // 2.sequence - 1.picture: flm->bild[2][1] flm->bild[2][1]->count_to=10; // 2.sequence - 2.picture: flm->bild[2][2] flm->bild[2][2]->count_to=10; } else if (flag==0) { /* always 0 when called from copy_film() */ if (flm->step==200UL) { /* 200 steps gone */ // increase the pendulum at 2.sequence flm->bild[2][1]->count_to/=2; // 1.picture flm->bild[2][2]->count_to/=2; // 2.picture } else if (flm->step==400UL) { /* 400 steps gone */ // don't show the clock any more // we have to set the element "aktiv" to another value: // 1.sequence: flm->aktiv[1] flm->aktiv[1]=FILM_ACT_DEAD; // now reset 1.sequence (only for demonstration purpose) flm->bildnr[1]=1; // set pointer of 1.sequence to 1.picture flm->bild[1][1]->count=0; // 1.sequence + 1.picture: count=0 } } } Note: Each copy_film(): - increments the step of a film (flm->step) - increments the count value of the current picture in each sequence (flm->bild[<sequence>-1][<picture>-1]->count), (unless a sequence is set inactive (flm->aktiv[<sequence>-1]!=FILM_ACT_OK)) - if the count value is equal to the maximum count value (count_to), the next picture is taken (flm->bildnr[<sequence>-1]++), but if it was the last picture of this sequence, again the first picture is taken - now all values are set, but now at first the "film subcall" ist called, you may change these values (be careful!) - then the pictures of the current values are drawn: at first of the 1.sequence, then of the 2.sequence and so on (unless a sequence is set dead (flm->aktiv[<sequence>-1]=FILM_ACT_DEAD))
Home | Previous: Color functions | Next: Key and mouse functions