home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser 2002 January / STC_CD_01_2002.iso / APP / ANIPL218 / PROG / SYNCHROC / SYNCHRO.C < prev    next >
Text File  |  2001-02-11  |  29KB  |  1,136 lines

  1.  
  2. /* SYNCHRO ANIPLAYER */
  3. /* MEQUIGNON Didier December 1997 */
  4. /* May 2000 version 1.03 */
  5. /* Example with messages VA_START, AV_SENDKEY, and 'AP' */
  6. /* Synchro with another APP or MIDI control */
  7.  
  8. #include <cpx.h>
  9. #include <string.h>
  10. #include <vdi.h>
  11. #include <tos.h>
  12.  
  13. #define ID_CPX (long)'SANI'
  14. #define ITEMPS 100L    /* mS */
  15. #define VA_START 0x4711
  16. #define AV_SENDKEY 0x4710
  17. #define STOP 0
  18. #define PLAY 1
  19. #define PAUSE 2
  20. #define FF 3
  21. #define REW 4
  22.  
  23. #define MIDI_SONG_POS_POINT 0xf2
  24. #define MIDI_TIMING_CLOCK 0xf8
  25. #define MIDI_START 0xfa
  26. #define MIDI_CONTINUE 0xfb
  27. #define MIDI_STOP 0xfc
  28.  
  29. typedef struct
  30. {
  31.     long ident;
  32.     union
  33.     {
  34.         long l;
  35.         int i[2];
  36.         char c[4];
  37.     } v;
  38. } COOKIE;
  39.  
  40. typedef struct
  41. {
  42.     char name[10];
  43.     char play[4];
  44.     char pause[4];
  45.     char stop[4];
  46.     char ff[4];
  47.     char rew[4];
  48.     char cmde[25];
  49.     char cmde_app[25];
  50.     char tempo_midi[3];
  51. } KEYS_PRG;
  52.  
  53. typedef struct
  54. {
  55.     short width;
  56.     short height;
  57.     short planes;
  58.     short frames_second;
  59.     long total_frames;
  60.     long id_picture_compression;    /* cvid for example */
  61.     short quality;    /* B0: mono(0)/stereo(1)  B1: 8 bits(0)/16 bits(1) */
  62.     unsigned short frequency_file;
  63.     unsigned short frequency_machine;
  64.     long total_samples;
  65.     long id_sound_compression;        /* ima4 for example */
  66.     short version_player;            /* version of Aniplayer */
  67.     long count_seconds;
  68.     long num_frame;
  69.     short play;
  70.     short reserve[11];
  71. } INFO_ANIM;
  72.  
  73. /* prototypes */
  74.  
  75. int CDECL cpx_call(GRECT *work);
  76. void CDECL cpx_draw(GRECT *clip);
  77. void CDECL cpx_wmove(GRECT *work);
  78. void CDECL cpx_timer(int *event);
  79. void CDECL cpx_key(int kstate,int key,int *event);
  80. void CDECL cpx_button(MRETS *mrets,int nclicks,int *event);
  81. int CDECL cpx_hook(int event,int *msg,MRETS *mrets,int *key,int *nclicks);
  82. void CDECL cpx_close(int flag);
  83. OBJECT *adr_tree(int no_arbre);
  84. CPXNODE *get_header(long id);
  85. void change_objc(int objc,int state,GRECT *clip);
  86. void aff_objc(int objc,GRECT *clip);
  87. void move_cursor(void);
  88. void wait_end_clic(void);
  89. unsigned long code_key(int status);
  90. unsigned int code_scan_code(char key);
  91. int send_message_app(int type,int key,char *path);
  92. int send_message_start(char *path);
  93. int send_message_key(int key);
  94. int send_message_info(int mode,long val);
  95. void eject(void);
  96. void stop(void);
  97. void play(void);
  98. void pause(void);
  99. void rew(void);
  100. void ff(void);
  101. void conv_digit(char *string,int val);
  102. void conv_hexa(char *string,int val);
  103. unsigned long get_hexa(char *string);
  104.  
  105. /* global variables in the 1st position of DATA segment */
  106.  
  107. KEYS_PRG config={"GEMJING","","","","","","+g+l-p+s-v-k","-r2 -d2 ",120};
  108.  
  109. /* global variables */
  110.  
  111. int vdi_handle,work_in[11]={1,1,1,1,1,1,1,1,1,1,2},work_out[57];
  112. int errno;
  113.  
  114. /* global variables */
  115.  
  116. XCPB *Xcpb;
  117. GRECT *Work;
  118. CPXNODE *head;
  119. CPXINFO    cpxinfo={cpx_call,cpx_draw,cpx_wmove,cpx_timer,cpx_key,cpx_button,0,0,cpx_hook,cpx_close};
  120. int id_app=0,send_info,count_send,ed_objc,new_objc,ed_pos,new_pos,load,first,start,status,old_status=-1;
  121. long seconds;
  122. int message[8];
  123. char path_ani[80],path_app[80],name_ani[12],name_app[12];
  124.  
  125. /* ressource */
  126.  
  127. #define MENUBOX 0
  128. #define MENUCMDE 2
  129. #define MENUTEMPOMIDI 3
  130. #define MENUAPNAME 4
  131. #define MENUPLAY 5
  132. #define MENUPAUSE 6
  133. #define MENUSTOP 7
  134. #define MENUFF 8
  135. #define MENUREW 9
  136. #define MENUCMDEAP 10
  137. #define MENUINFO 11
  138. #define MENUBEJECT 14
  139. #define MENUBSTOP 16
  140. #define MENUBPLAY 18
  141. #define MENUBPAUSE 20
  142. #define MENUBREW 22
  143. #define MENUBFF 24
  144. #define MENUBSAUVE 26
  145. #define MENUBANNULE 27
  146.  
  147. char *rs_strings[] = {
  148.     "SYNCHRO ANIPLAYER v1.03a","","",
  149.     "abcdefghijklmnopqrstuvwx","Opt : ________________________","XXXXXXXXXXXXXXXXXXXXXXXX",
  150.     "cba","Tempo MIDI: ___","999",
  151.     "        ","With: ________","XXXXXXXX",
  152.     "ABCD","Play : ____","XFFF",
  153.     "EFGH","Pause : ____","XFFF",
  154.     "IJKL","Stop : ____","XFFF",
  155.     "HGEF","FF: ____","XFFF",
  156.     "MKJI","REW: ____","XFFF",
  157.     "MNOPQRSTUVWXYZ0123426789","Opt : ________________________","XXXXXXXXXXXXXXXXXXXXXXXX",
  158.     "  MN SEC   ALL MN SEC","","",
  159.     " :     :","","",
  160.     "Save",
  161.     "Cancel" };
  162.  
  163. long rs_frstr[] = {0};
  164.  
  165. BITBLK rs_bitblk[] = {
  166.     (int *)0L,2,16,0,0,1,
  167.     (int *)1L,2,16,0,0,1,
  168.     (int *)2L,2,16,0,0,1,
  169.     (int *)3L,2,16,0,0,1,
  170.     (int *)4L,2,16,0,0,1,
  171.     (int *)5L,2,16,0,0,1 };
  172.     
  173. long rs_frimg[] = {0};
  174. ICONBLK rs_iconblk[] = {0};
  175.  
  176. TEDINFO rs_tedinfo[] = {
  177.     (char *)0L,(char *)1L,(char *)2L,IBM,0,2,0x1180,0,0,32,1,
  178.     (char *)3L,(char *)4L,(char *)5L,IBM,0,0,0x1180,0,0,25,31,
  179.     (char *)6L,(char *)7L,(char *)8L,IBM,0,0,0x1180,0,0,4,16,
  180.     (char *)9L,(char *)10L,(char *)11L,IBM,0,0,0x1180,0,0,9,15,
  181.     (char *)12L,(char *)13L,(char *)14L,IBM,0,0,0x1180,0,0,5,12,
  182.     (char *)15L,(char *)16L,(char *)17L,IBM,0,0,0x1180,0,0,5,13,
  183.     (char *)18L,(char *)19L,(char *)20L,IBM,0,0,0x1180,0,0,5,12,
  184.     (char *)21L,(char *)22L,(char *)23L,IBM,0,0,0x1180,0,0,5,9,
  185.     (char *)24L,(char *)25L,(char *)26L,IBM,0,0,0x1180,0,0,5,10,
  186.     (char *)27L,(char *)28L,(char *)29L,IBM,0,0,0x1180,0,0,25,31,
  187.     (char *)30L,(char *)31L,(char *)32L,SMALL,0,0,0x1600,0,0,22,1,
  188.     (char *)33L,(char *)34L,(char *)35L,IBM,0,0,0x1500,0,0,17,1 };
  189.  
  190. OBJECT rs_object[] = {
  191.     -1,1,27,G_BOX,FL3DBAK,NORMAL,0x1100L,0,0,32,11,
  192.     2,-1,-1,G_TEXT,FL3DBAK,SELECTED,0L,0,0,32,1,
  193.     3,-1,-1,G_FTEXT,EDITABLE|FL3DBAK,NORMAL,1L,1,1,30,1,
  194.     4,-1,-1,G_FTEXT,EDITABLE|FL3DBAK,NORMAL,2L,1,2,15,1,
  195.     5,-1,-1,G_FTEXT,EDITABLE|FL3DBAK,NORMAL,3L,17,2,14,1,
  196.     6,-1,-1,G_FTEXT,EDITABLE|FL3DBAK,NORMAL,4L,1,3,12,1,
  197.     7,-1,-1,G_FTEXT,EDITABLE|FL3DBAK,NORMAL,5L,13,3,13,1,
  198.     8,-1,-1,G_FTEXT,EDITABLE|FL3DBAK,NORMAL,6L,1,4,12,1,
  199.     9,-1,-1,G_FTEXT,EDITABLE|FL3DBAK,NORMAL,7L,13,4,9,1,
  200.     10,-1,-1,G_FTEXT,EDITABLE|FL3DBAK,NORMAL,8L,22,4,10,1,
  201.     11,-1,-1,G_FTEXT,EDITABLE|FL3DBAK,NORMAL,9L,1,5,30,1,
  202.     14,12,13,G_BOX,NONE,NORMAL,0xff10f1L,3,6,17,2,
  203.     13,-1,-1,G_TEXT,FL3DBAK,NORMAL,10L,0,0,17,1,
  204.     11,-1,-1,G_TEXT,NONE,NORMAL,11L,0,1,17,1,                                        /* infos */
  205.     16,15,15,G_BOX,TOUCHEXIT|FL3DIND|FL3DBAK,NORMAL,0xff1100L,3,9,2,1,                /* eject */
  206.     14,-1,-1,G_IMAGE,TOUCHEXIT,NORMAL,0L,0,0,2,1,
  207.     18,17,17,G_BOX,TOUCHEXIT|FL3DIND|FL3DBAK,SELECTED,0xff1100L,6,9,2,1,            /* stop */
  208.     16,-1,-1,G_IMAGE,TOUCHEXIT,NORMAL,1L,0,0,2,1,
  209.     20,19,19,G_BOX,TOUCHEXIT|FL3DIND|FL3DBAK,NORMAL,0xff1100L,9,9,2,1,                /* play */
  210.     18,-1,-1,G_IMAGE,TOUCHEXIT,NORMAL,2L,0,0,2,1,
  211.     22,21,21,G_BOX,TOUCHEXIT|FL3DIND|FL3DBAK,NORMAL,0xff1100L,12,9,2,1,                /* pause */
  212.     20,-1,-1,G_IMAGE,TOUCHEXIT,NORMAL,3L,0,0,2,1,
  213.     24,23,23,G_BOX,TOUCHEXIT|FL3DIND|FL3DBAK,NORMAL,0xff1100L,15,9,2,1,                /* << */
  214.     22,-1,-1,G_IMAGE,TOUCHEXIT,NORMAL,4L,0,0,2,1,
  215.     26,25,25,G_BOX,TOUCHEXIT|FL3DIND|FL3DBAK,NORMAL,0xff1100L,18,9,2,1,                /* >> */
  216.     24,-1,-1,G_IMAGE,TOUCHEXIT,NORMAL,5L,0,0,2,1,
  217.     27,-1,-1,G_BUTTON,SELECTABLE|EXIT|FL3DIND|FL3DBAK,NORMAL,36L,23,7,6,1,            /* Save */
  218.     0,-1,-1,G_BUTTON,SELECTABLE|EXIT|LASTOB|FL3DIND|FL3DBAK,NORMAL,37L,23,9,6,1 };    /* Cancel */
  219.  
  220. long rs_trindex[] = {0};
  221. struct foobar {
  222.     int dummy;
  223.     int *image;
  224.     } rs_imdope[] = {0};
  225.  
  226. unsigned int image_eject[]={
  227.     0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0ff0,0x1ff8,
  228.     0x3ffc,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000 };
  229.  
  230. unsigned int image_stop[]={
  231.     0x0000,0x0000,0x0000,0x0000,0x1ff8,0x1ff8,0x1ff8,0x1ff8,
  232.     0x1ff8,0x1ff8,0x1ff8,0x1ff8,0x0000,0x0000,0x0000,0x0000 };
  233.  
  234. unsigned int image_play[]={
  235.     0x0000,0x0000,0x0000,0x2000,0x3c00,0x3f80,0x3ff0,0x3ffe,
  236.     0x3ffe,0x3ff0,0x3f80,0x3c00,0x2000,0x0000,0x0000,0x0000 };
  237.  
  238. unsigned int image_pause[]={
  239.     0x0000,0x0000,0x0000,0x1e78,0x1e78,0x1e78,0x1e78,0x1e78,
  240.     0x1e78,0x1e78,0x1e78,0x1e78,0x1e78,0x0000,0x0000,0x0000 };
  241.  
  242. unsigned int image_rew[]={
  243.     0x0000,0x0000,0x0000,0x0204,0x060c,0x0e1c,0x1e3c,0x3e7c,
  244.     0x3e7c,0x1e3c,0x0e1c,0x060c,0x0204,0x0000,0x0000,0x0000 };
  245.  
  246. unsigned int image_ff[]={
  247.     0x0000,0x0000,0x0000,0x2040,0x3060,0x3870,0x3c78,0x3e7c,
  248.     0x3e7c,0x3c78,0x3870,0x3060,0x2040,0x0000,0x0000,0x0000 };
  249.  
  250. #define NUM_STRINGS 38    /* nb of strings */
  251. #define NUM_FRSTR 0        /* strings form_alert */
  252. #define NUM_IMAGES 0
  253. #define NUM_BB 6        /* nb of BITBLK */
  254. #define NUM_FRIMG 0
  255. #define NUM_IB 0        /* nb of ICONBLK */
  256. #define NUM_TI 12        /* nb of TEDINFO */
  257. #define NUM_OBS 28        /* nb of objects */
  258. #define NUM_TREE 1        /* nb of tree */ 
  259.  
  260. #define TREE1 0
  261.  
  262. CPXINFO* CDECL cpx_init(XCPB *xcpb)
  263.  
  264. {
  265.     Xcpb=xcpb;
  266.     return(&cpxinfo);
  267. }
  268.  
  269. int CDECL cpx_call(GRECT *work)
  270.  
  271. {
  272.     KEYS_PRG *header;
  273.     OBJECT *dma_tree;
  274.     TEDINFO *t_edinfo;
  275.     BITBLK *b_itblk;
  276.     register char *p;
  277.     if(!(Xcpb->SkipRshFix))
  278.     {
  279.         (*Xcpb->rsh_fix)(NUM_OBS,NUM_FRSTR,NUM_FRIMG,NUM_TREE,rs_object,rs_tedinfo,rs_strings,rs_iconblk,rs_bitblk,rs_frstr,rs_frimg,rs_trindex,rs_imdope);
  280.         rs_object[MENUINFO].ob_y+=4;
  281.         b_itblk=rs_object[MENUBEJECT+1].ob_spec.bitblk;
  282.         b_itblk->bi_pdata=(int *)image_eject;
  283.         b_itblk=rs_object[MENUBSTOP+1].ob_spec.bitblk;
  284.         b_itblk->bi_pdata=(int *)image_stop;
  285.         b_itblk=rs_object[MENUBPLAY+1].ob_spec.bitblk;
  286.         b_itblk->bi_pdata=(int *)image_play;
  287.         b_itblk=rs_object[MENUBPAUSE+1].ob_spec.bitblk;
  288.         b_itblk->bi_pdata=(int *)image_pause;
  289.         b_itblk=rs_object[MENUBREW+1].ob_spec.bitblk;
  290.         b_itblk->bi_pdata=(int *)image_rew;
  291.         b_itblk=rs_object[MENUBFF+1].ob_spec.bitblk;
  292.         b_itblk->bi_pdata=(int *)image_ff;
  293.     }
  294.     if((id_app=appl_find("XCONTROL"))<0
  295.      && (id_app=appl_find("ZCONTROL"))<0
  296.      && (id_app=appl_find("COPS    "))<0
  297.      && (id_app=appl_find("FREEDOM2"))<0)
  298.         return(0);
  299.     if((vdi_handle=Xcpb->handle)>0)
  300.     {
  301.         v_opnvwk(work_in,&vdi_handle,work_out);
  302.         if(vdi_handle<=0 || (head=get_header(ID_CPX))==0)
  303.             return(0);
  304.     }
  305.     else
  306.         return(0);
  307.     if(work_out[13]<16)    /* nb colors */
  308.     {
  309.         t_edinfo=(TEDINFO *)rs_object[MENUINFO+1].ob_spec.tedinfo;
  310.         t_edinfo->te_color=0x1000;
  311.         t_edinfo=(TEDINFO *)rs_object[MENUINFO+2].ob_spec.tedinfo;
  312.         t_edinfo->te_color=0x1000;
  313.     }
  314.     rs_object[MENUBOX].ob_x=work->g_x;
  315.     rs_object[MENUBOX].ob_y=work->g_y;
  316.     rs_object[MENUBOX].ob_width=work->g_w;
  317.     rs_object[MENUBOX].ob_height=work->g_h;
  318.     header=(KEYS_PRG *)head->cpxhead.buffer;
  319.     if(*header->name==0)    /* buffer of header is always to 0 with ZCONTROL */
  320.         *header=config;  
  321.     t_edinfo=(TEDINFO *)rs_object[MENUCMDE].ob_spec.tedinfo;
  322.       strcpy(t_edinfo->te_ptext,header->cmde);
  323.     t_edinfo=(TEDINFO *)rs_object[MENUAPNAME].ob_spec.tedinfo;
  324.       strcpy(t_edinfo->te_ptext,header->name);
  325.     t_edinfo=(TEDINFO *)rs_object[MENUPLAY].ob_spec.tedinfo;
  326.     memcpy(t_edinfo->te_ptext,header->play,4);
  327.     t_edinfo=(TEDINFO *)rs_object[MENUPAUSE].ob_spec.tedinfo;
  328.     memcpy(t_edinfo->te_ptext,header->pause,4);
  329.     t_edinfo=(TEDINFO *)rs_object[MENUSTOP].ob_spec.tedinfo;
  330.     memcpy(t_edinfo->te_ptext,header->stop,4);    
  331.     t_edinfo=(TEDINFO *)rs_object[MENUFF].ob_spec.tedinfo;
  332.     memcpy(t_edinfo->te_ptext,header->ff,4);
  333.     t_edinfo=(TEDINFO *)rs_object[MENUREW].ob_spec.tedinfo;
  334.     memcpy(t_edinfo->te_ptext,header->rew,4);
  335.     t_edinfo=(TEDINFO *)rs_object[MENUCMDEAP].ob_spec.tedinfo;
  336.       strcpy(t_edinfo->te_ptext,header->cmde_app);
  337.     if(!header->tempo_midi[0])
  338.     {
  339.         header->tempo_midi[0]='1'; header->tempo_midi[1]='2'; header->tempo_midi[2]='0';
  340.     }
  341.       t_edinfo=(TEDINFO *)rs_object[MENUTEMPOMIDI].ob_spec.tedinfo;
  342.     memcpy(t_edinfo->te_ptext,header->tempo_midi,3);
  343.     ed_pos=ed_objc=0;
  344.     cpx_draw(work);
  345.     ed_objc=MENUAPNAME;
  346.     status=STOP;
  347.     seconds=0;
  348.     count_send=send_info=load=first=start=0;
  349.     objc_edit(rs_object,ed_objc,0,&ed_pos,ED_INIT);
  350.     new_objc=ed_objc;
  351.     new_pos=ed_pos;
  352.     Work=work;
  353.     (*Xcpb->Set_Evnt_Mask)(MU_KEYBD|MU_BUTTON|MU_TIMER,0L,0L,ITEMPS);
  354.     return(1);                    /* CPX isn't finished */
  355. }
  356.  
  357. void CDECL cpx_draw(GRECT *clip)
  358.  
  359. {
  360.     aff_objc(0,clip);
  361. }
  362.  
  363. void CDECL cpx_wmove(GRECT *work)
  364.  
  365. {
  366.     rs_object[MENUBOX].ob_x=work->g_x;
  367.     rs_object[MENUBOX].ob_y=work->g_y;
  368.     rs_object[MENUBOX].ob_width=work->g_w;
  369.     rs_object[MENUBOX].ob_height=work->g_h;
  370. }
  371.  
  372. int CDECL cpx_hook(int event,int *msg,MRETS *mrets,int *key,int *nclicks)
  373.  
  374. {
  375.     INFO_ANIM *info; 
  376.     register char *p;
  377.     register long total_time;
  378.     register TEDINFO *t_edinfo;
  379.     if(mrets && key && nclicks);
  380.     if(send_info && (event & MU_MESAG) && msg[0]=='AP')
  381.     {
  382.         info=*((INFO_ANIM **)(&msg[3]));
  383.         if(info->play)
  384.             status=PLAY;
  385.         else
  386.             status=PAUSE;
  387.         if(!info->id_picture_compression
  388.          && !info->id_sound_compression)
  389.             status=STOP;
  390.         if(start && status==PLAY)
  391.         {
  392.             send_message_app(VA_START,0,path_app);
  393.             start=0;
  394.         }
  395.         t_edinfo=(TEDINFO *)rs_object[MENUINFO+2].ob_spec.tedinfo;
  396.         p=t_edinfo->te_ptext;
  397.         if(status==STOP)
  398.         {
  399.             conv_digit(&p[1],0);
  400.             conv_digit(&p[4],0);
  401.             conv_digit(&p[11],0);
  402.             conv_digit(&p[14],0);        
  403.             seconds=0;
  404.         }
  405.         else
  406.         {        
  407.             seconds=info->count_seconds;
  408.             if(info->id_sound_compression && info->frequency_file)
  409.                 total_time=info->total_samples/info->frequency_file;
  410.             else            
  411.                 total_time=info->total_frames/info->frames_second;
  412.             conv_digit(&p[1],(int)(info->count_seconds/60L));
  413.             conv_digit(&p[4],(int)(info->count_seconds%60L));
  414.             conv_digit(&p[11],(int)(total_time/60L));
  415.             conv_digit(&p[14],(int)(total_time%60L));
  416.         }
  417.         aff_objc(MENUINFO,Work);
  418.         if(status!=old_status)
  419.         {
  420.             switch(status)
  421.             {
  422.             case PLAY:
  423.                 change_objc(MENUBSTOP,NORMAL,Work);
  424.                 change_objc(MENUBPLAY,SELECTED,Work);
  425.                 change_objc(MENUBPAUSE,NORMAL,Work);
  426.                 break;
  427.             case PAUSE:
  428.                 change_objc(MENUBSTOP,NORMAL,Work);
  429.                 change_objc(MENUBPLAY,NORMAL,Work);
  430.                 change_objc(MENUBPAUSE,SELECTED,Work);
  431.                 break;                
  432.             default:
  433.                 change_objc(MENUBSTOP,SELECTED,Work);
  434.                 change_objc(MENUBPLAY,NORMAL,Work);
  435.                 change_objc(MENUBPAUSE,NORMAL,Work);
  436.             }
  437.         }
  438.         old_status=status;
  439.         send_info=0;
  440.         count_send=0;    
  441.     }
  442.     return(0);
  443. }
  444.  
  445. void CDECL cpx_timer(int *event)
  446.  
  447. {
  448.     static long pos=0;
  449.     static int count_timer=10,clock_sec=48;
  450.     register int tempo_midi;
  451.     register TEDINFO *t_edinfo;
  452.     if(*event);
  453.     count_timer++;
  454.     if(count_timer>9)
  455.     {
  456.         count_timer=0;
  457.         if(!send_info || count_send<5)
  458.         {
  459.             if(send_message_info(0,0L))
  460.             {
  461.                 send_info=1;
  462.                 count_send++;
  463.             }
  464.             else
  465.                 count_send=0;
  466.         }
  467.         t_edinfo=(TEDINFO *)rs_object[MENUTEMPOMIDI].ob_spec.tedinfo;
  468.         tempo_midi=120;
  469.         if(t_edinfo->te_ptext[0]!=0)
  470.         {
  471.             tempo_midi=t_edinfo->te_ptext[0] & 0xf;
  472.             if(t_edinfo->te_ptext[1]!=0)
  473.             {
  474.                 tempo_midi*=10;
  475.                 tempo_midi+=(t_edinfo->te_ptext[1] & 0xf);
  476.                 if(t_edinfo->te_ptext[2]!=0)
  477.                 {
  478.                     tempo_midi*=10;
  479.                     tempo_midi+=(t_edinfo->te_ptext[2] & 0xf);
  480.                 }
  481.             }
  482.         }
  483.         clock_sec=(tempo_midi*48)/120;
  484.     }
  485.     while(Bconstat(3))                        /* MIDI IN */
  486.     {
  487.         switch((int)Bconin(3))
  488.         {
  489.         case MIDI_START:
  490.             play();
  491.             if(seconds && send_message_info(1,0))
  492.                 seconds=pos=0;                /* movie to 0 seconds */
  493.             break;
  494.         case MIDI_CONTINUE:
  495.             play();
  496.             break;
  497.         case MIDI_STOP:
  498.             pause();    
  499.             break;
  500.         case MIDI_TIMING_CLOCK:
  501.             pos++;
  502.             break;
  503.         case MIDI_SONG_POS_POINT:
  504.             pos=(long)(Bconin(3)+(Bconin(3)<<7))*6L;
  505.             seconds=pos/(long)clock_sec;
  506.             send_message_info(1,seconds);    /* seek movie */
  507.             break;
  508.         }
  509.     }
  510. }
  511.  
  512. void CDECL cpx_key(int kstate,int key,int *event)
  513.  
  514. {
  515.     register int i,dial;
  516.     register TEDINFO *t_edinfo;
  517.     if(kstate);
  518.     if(*event);
  519.     dial=form_keybd(rs_object,ed_objc,ed_objc,key,&new_objc,&key);
  520.     if(!key && dial)
  521.     {
  522.         if(new_objc)
  523.         {
  524.             t_edinfo=(TEDINFO *)rs_object[new_objc].ob_spec.tedinfo;
  525.             for(i=0;t_edinfo->te_ptext[i];i++);
  526.             new_pos=i;                /* cursor in end of zone edited */
  527.         }
  528.     }
  529.     else
  530.     {
  531.         if(rs_object[ed_objc].ob_flags & EDITABLE)
  532.         {
  533.             switch(key & 0xff00)
  534.             {
  535.             case 0x7300:            /* ctrl + left */
  536.                 new_objc=ed_objc;    /* same zone */
  537.                 new_pos=0;            /* cursor at left */
  538.                 key=0;
  539.                 break;
  540.             case 0x7400:            /* ctrl + right */
  541.                 new_objc=ed_objc;    /* same zone */
  542.                 key=0;
  543.                 t_edinfo=(TEDINFO *)rs_object[new_objc].ob_spec.tedinfo;
  544.                 for(i=0;t_edinfo->te_ptext[i];i++);
  545.                 new_pos=i;            /* cursor in end of zone */
  546.             }
  547.         }
  548.     }
  549.     if(key>0)
  550.     {
  551.         objc_edit(rs_object,ed_objc,key,&ed_pos,ED_CHAR);    /* text edited in usual zone */
  552.         new_objc=ed_objc;
  553.         new_pos=ed_pos;
  554.     }
  555.     if(dial)                        /* if 0 => new_objc contains object EXIT */
  556.         move_cursor();
  557.     else
  558.     {
  559.         change_objc(new_objc,NORMAL,Work);
  560.         *event=1;                    /* end */
  561.         cpx_close(0);
  562.     }    
  563. }
  564.  
  565. void CDECL cpx_button(MRETS *mrets,int nclicks,int *event)
  566.  
  567. {
  568.     KEYS_PRG *header;
  569.     GRECT menu;
  570.     register TEDINFO *t_edinfo;
  571.     register int i,j,ret,objc_clic,pos_clic;
  572.     int x,y,m,k,xoff,yoff,attrib[10];
  573.     if((objc_clic=objc_find(rs_object,0,2,mrets->x,mrets->y))>=0)
  574.     {
  575.         if(form_button(rs_object,objc_clic,nclicks,&new_objc))
  576.         {
  577.             if(new_objc>0)
  578.             {
  579.                 objc_offset(rs_object,objc_clic,&xoff,&yoff);
  580.                 t_edinfo=(TEDINFO *)rs_object[objc_clic].ob_spec.tedinfo;
  581.                 vqt_attributes(vdi_handle,attrib);
  582.                 /* attrib[8] = largeur du cadre des caractères */
  583.                 for(i=0;t_edinfo->te_ptmplt[i];i++);    /* size of mask string */
  584.                 if((pos_clic=rs_object[objc_clic].ob_width-i*attrib[8])>=0)
  585.                 {
  586.                     switch(t_edinfo->te_just)
  587.                     {
  588.                     case TE_RIGHT:             /* justified to right */
  589.                         pos_clic=mrets->x-xoff-pos_clic;
  590.                         break;
  591.                     case TE_CNTR:            /* centred */
  592.                         pos_clic=mrets->x-xoff-pos_clic/2;
  593.                         break;
  594.                     case TE_LEFT:            /* justified to left */
  595.                     default:
  596.                         pos_clic=mrets->x-xoff;
  597.                     }
  598.                 }
  599.                 else
  600.                     pos_clic=mrets->x-xoff;
  601.                 new_pos=-1;
  602.                 pos_clic/=attrib[8];        /* position character checked */
  603.                 j=-1;
  604.                 do
  605.                 {
  606.                     if(t_edinfo->te_ptmplt[++j]=='_')
  607.                         new_pos++;
  608.                 }
  609.                 while(j<i && j<pos_clic);    /* end if cursor on end of string or position character checked */
  610.                 if(j>=i)
  611.                     new_pos=-1;                        /* cursor in end of string */
  612.                 else
  613.                 {
  614.                     j--;
  615.                     while(t_edinfo->te_ptmplt[++j]!='_' && j<i);
  616.                     if(j>=i)
  617.                         new_pos=-1;                    /* cursor in end of string */
  618.                 }
  619.                 for(i=0;t_edinfo->te_ptext[i];i++);    /* size of string text */
  620.                 if(new_pos<0 || i<new_pos)
  621.                     new_pos=i;
  622.             }
  623.             move_cursor();
  624.         }
  625.         else
  626.         {
  627.             switch(objc_clic)
  628.             {
  629.             case MENUBEJECT:
  630.             case MENUBEJECT+1:
  631.                 eject();
  632.                 break;
  633.             case MENUBSTOP:
  634.             case MENUBSTOP+1:
  635.                 stop();
  636.                 break;
  637.             case MENUBPLAY:
  638.             case MENUBPLAY+1:
  639.                 play();
  640.                 break;
  641.             case MENUBPAUSE:
  642.             case MENUBPAUSE+1:
  643.                 pause();
  644.                 break;
  645.             case MENUBREW:
  646.             case MENUBREW+1:
  647.                 rew();
  648.                 break;
  649.             case MENUBFF:
  650.             case MENUBFF+1:
  651.                 ff();
  652.                 break;
  653.             case MENUBSAUVE:
  654.                 change_objc(MENUBSAUVE,NORMAL,Work);
  655.                 if((*Xcpb->XGen_Alert)(SAVE_DEFAULTS))
  656.                 {
  657.                     header=(KEYS_PRG *)head->cpxhead.buffer;
  658.                     t_edinfo=(TEDINFO *)rs_object[MENUCMDE].ob_spec.tedinfo;
  659.                       strcpy(header->cmde,t_edinfo->te_ptext);
  660.                     t_edinfo=(TEDINFO *)rs_object[MENUAPNAME].ob_spec.tedinfo;
  661.                       strcpy(header->name,t_edinfo->te_ptext);
  662.                     t_edinfo=(TEDINFO *)rs_object[MENUPLAY].ob_spec.tedinfo;
  663.                       memcpy(header->play,t_edinfo->te_ptext,4);
  664.                     t_edinfo=(TEDINFO *)rs_object[MENUPAUSE].ob_spec.tedinfo;
  665.                       memcpy(header->pause,t_edinfo->te_ptext,4);
  666.                     t_edinfo=(TEDINFO *)rs_object[MENUSTOP].ob_spec.tedinfo;
  667.                       memcpy(header->stop,t_edinfo->te_ptext,4);
  668.                     t_edinfo=(TEDINFO *)rs_object[MENUFF].ob_spec.tedinfo;
  669.                       memcpy(header->ff,t_edinfo->te_ptext,4);
  670.                     t_edinfo=(TEDINFO *)rs_object[MENUREW].ob_spec.tedinfo;
  671.                       memcpy(header->rew,t_edinfo->te_ptext,4);
  672.                     t_edinfo=(TEDINFO *)rs_object[MENUCMDEAP].ob_spec.tedinfo;
  673.                       strcpy(header->cmde_app,t_edinfo->te_ptext);                
  674.                     t_edinfo=(TEDINFO *)rs_object[MENUTEMPOMIDI].ob_spec.tedinfo;
  675.                       memcpy(header->tempo_midi,t_edinfo->te_ptext,3);                
  676.                     if(((*Xcpb->Save_Header)(head))==0)
  677.                         (*Xcpb->XGen_Alert)(FILE_ERR);
  678.                     config=*header;
  679.                     if(((*Xcpb->CPX_Save)((void *)&config,sizeof(KEYS_PRG)))==0)
  680.                         (*Xcpb->XGen_Alert)(FILE_ERR);
  681.                 }
  682.                 break;
  683.             case MENUBANNULE:
  684.                 change_objc(MENUBANNULE,NORMAL,Work);
  685.                 *event=1;    /* end */
  686.                 cpx_close(0);
  687.             }
  688.         }
  689.     }
  690. }
  691.  
  692. void CDECL cpx_close(int flag)
  693.  
  694. {
  695.     int x,y,m,k;
  696.     if(flag);
  697.     objc_edit(rs_object,ed_objc,0,&ed_pos,ED_END);
  698.     v_clsvwk(vdi_handle);
  699. }
  700.  
  701. OBJECT *adr_tree(int no_arbre)
  702.  
  703. {
  704.     register int i,arbre;
  705.     if(!no_arbre)
  706.         return(rs_object);
  707.     for(i=arbre=0;i<NUM_OBS;i++)
  708.     {
  709.         if(rs_object[i].ob_flags & LASTOB)
  710.         {
  711.             arbre++;
  712.             if(arbre==no_arbre)
  713.                 return(&rs_object[i+1]);
  714.         }
  715.     }
  716.     return(0L);
  717. }
  718.  
  719. CPXNODE *get_header(long id)
  720.  
  721. {
  722.     register CPXNODE *p;
  723.     p=(CPXNODE *)(*Xcpb->Get_Head_Node)();    /* header for first CPX */
  724.     do
  725.     {
  726.         if(p->cpxhead.cpx_id==id)
  727.             return(p);
  728.     }
  729.     while(p->vacant && (p=p->next)!=0);        /* no more headers */
  730.     return(0L);
  731. }
  732.  
  733. void change_objc(int objc,int state,GRECT *clip)
  734.  
  735. {
  736.     rs_object[objc].ob_state=state;
  737.     aff_objc(objc,clip);
  738. }
  739.  
  740. void aff_objc(int objc,GRECT *clip)
  741.  
  742. {
  743.     register GRECT *rect;
  744.     register int curseur=0;
  745.     wind_update(BEG_UPDATE);
  746.     if(objc==MENUBOX)
  747.     {
  748.         objc_edit(rs_object,ed_objc,0,&ed_pos,ED_END);        /* hide cursor */
  749.         curseur=1;
  750.     }
  751.     rect=(GRECT *)(*Xcpb->GetFirstRect)(clip);
  752.     while(rect)
  753.     {
  754.         objc_draw(rs_object,objc,2,PTRS(rect));
  755.         rect=(GRECT *)(*Xcpb->GetNextRect)();
  756.     }
  757.     if(curseur)
  758.         objc_edit(rs_object,ed_objc,0,&ed_pos,ED_END);        /* showm cursor */
  759.     wind_update(END_UPDATE);
  760. }
  761.  
  762. void move_cursor(void)
  763.  
  764. {
  765.     if(new_objc>0 && (ed_objc!=new_objc || ed_pos!=new_pos))
  766.     {
  767.         objc_edit(rs_object,ed_objc,0,&ed_pos,ED_END);        /* hide cursor */
  768.         ed_pos=new_pos;
  769.         objc_edit(rs_object,new_objc,0,&ed_pos,ED_CHAR);    /* new position of cursor */
  770.         objc_edit(rs_object,new_objc,0,&ed_pos,ED_END);        /* showm cursor */
  771.         ed_objc=new_objc;                                    /* new zone edited */
  772.         ed_pos=new_pos;                                        /* new position cursor */
  773.     }
  774. }
  775.  
  776. void wait_end_clic(void)
  777.  
  778. {
  779.     int x,y,m,k;
  780.     do
  781.         graf_mkstate(&x,&y,&m,&k);
  782.     while(m);
  783. }
  784.  
  785. unsigned long code_key(int status)
  786.  
  787. {
  788.     register TEDINFO *t_edinfo;
  789.     switch(status)
  790.     {
  791.     case PLAY:
  792.         t_edinfo=(TEDINFO *)rs_object[MENUPLAY].ob_spec.tedinfo;
  793.         break;
  794.     case PAUSE:
  795.         t_edinfo=(TEDINFO *)rs_object[MENUPAUSE].ob_spec.tedinfo;
  796.         break;
  797.     case FF:
  798.         t_edinfo=(TEDINFO *)rs_object[MENUFF].ob_spec.tedinfo;
  799.         break;
  800.     case REW:
  801.         t_edinfo=(TEDINFO *)rs_object[MENUREW].ob_spec.tedinfo;
  802.         break;
  803.     default:
  804.         t_edinfo=(TEDINFO *)rs_object[MENUSTOP].ob_spec.tedinfo;
  805.     }
  806.     switch(strlen(t_edinfo->te_ptext))
  807.     {
  808.     case 0:
  809.         return(0);
  810.     case 1:
  811.         return(code_scan_code(t_edinfo->te_ptext[0]));
  812.     default:    
  813.         return(get_hexa(t_edinfo->te_ptext));
  814.     }
  815. }
  816.  
  817. unsigned int code_scan_code(char key)
  818.  
  819. {
  820.     KEYTAB *tab;
  821.     register unsigned int i;
  822.     tab=Keytbl((void *)-1,(void *)-1,(void *)-1);
  823.     for(i=0;i<128;i++)
  824.     {
  825.         if(tab->shift[i]==key)
  826.             break;
  827.         if(tab->unshift[i]==key)
  828.             break;
  829.         if(tab->capslock[i]==key)
  830.             break;
  831.     }
  832.     i<<=8;        /* scan-code */
  833.     return(i | (unsigned int)key);
  834. }
  835.  
  836. int send_message_app(int type,int key,char *path)
  837.  
  838. {
  839.     static char buf[128];
  840.     register int id;
  841.     register TEDINFO *t_edinfo;    
  842.     t_edinfo=(TEDINFO *)rs_object[MENUAPNAME].ob_spec.tedinfo;
  843.     if((key || path) && (id=appl_find(t_edinfo->te_ptext))>0)
  844.     {
  845.         message[0]=type;
  846.         message[1]=id_app;
  847.         message[2]=0;
  848.         if(path==0)
  849.         {
  850.             message[3]=0;
  851.             message[4]=key;
  852.         }
  853.         else
  854.         {
  855.             t_edinfo=(TEDINFO *)rs_object[MENUCMDEAP].ob_spec.tedinfo;
  856.             strcpy(buf,t_edinfo->te_ptext);    
  857.             strcat(buf,path);            
  858.             *((char **)(&message[3]))=buf;
  859.         }
  860.         message[5]=message[6]=message[7]=0;
  861.         appl_write(id,16,message);
  862.         return(1);
  863.     }
  864.     return(0);
  865. }
  866.  
  867. int send_message_start(char *path)
  868.  
  869. {
  870.     static char buf[128];
  871.     register int id;
  872.     register TEDINFO *t_edinfo;    
  873.     if((id=appl_find("ANIPLAY "))>=0)
  874.     {
  875.         t_edinfo=(TEDINFO *)rs_object[MENUCMDE].ob_spec.tedinfo;
  876.         strcpy(buf,t_edinfo->te_ptext);    
  877.         strcat(buf,path);        
  878.         message[0]=VA_START;
  879.         message[1]=id_app;
  880.         message[2]=0;
  881.         *((char **)(&message[3]))=buf;
  882.         message[5]=message[6]=message[7]=0;
  883.         appl_write(id,16,message);
  884.         return(1);
  885.     }
  886.     form_alert(1,"[2][No communication|with ANIPLAY][Cancel]");
  887.     return(0);
  888. }
  889.  
  890. int send_message_key(int key)
  891.  
  892. {
  893.     register int id;
  894.     if((id=appl_find("ANIPLAY "))>=0)
  895.     {
  896.         message[0]=AV_SENDKEY;
  897.         message[1]=id_app;
  898.         message[2]=message[3]=0;
  899.         message[4]=key;
  900.         message[5]=message[6]=message[7]=0;
  901.         appl_write(id,16,message);
  902.         return(1);
  903.     }
  904.     return(0);
  905. }
  906.  
  907. int send_message_info(int mode,long val)
  908.  
  909. {
  910.     register int id;
  911.     if((id=appl_find("ANIPLAY "))>=0)
  912.     {
  913.         message[0]='AP';
  914.         message[1]=id_app;
  915.         message[3]=mode;
  916.         *((char **)(&message[4]))=(char *)val;        
  917.         message[2]=message[6]=message[7]=0;
  918.         appl_write(id,16,message);
  919.         return(1);
  920.     }
  921.     return(0);
  922. }
  923.  
  924. void eject(void)
  925.  
  926. {
  927.     int ret;
  928.     register int car;
  929.     register TEDINFO *t_edinfo;    
  930.     change_objc(MENUBEJECT,SELECTED,Work);
  931.     t_edinfo=(TEDINFO *)rs_object[MENUCMDE].ob_spec.tedinfo;
  932.     if(!(t_edinfo->te_ptext[0]=='+' && t_edinfo->te_ptext[1]=='n'))
  933.     {
  934.         send_message_key(0x6100);    /* UNDO */
  935.         evnt_timer(100,0);
  936.     }
  937.     path_ani[0]=Dgetdrv()+'A';path_ani[1]=':';Dgetpath(path_ani+2,Dgetdrv()+1);
  938.     strcat(path_ani,"\\");strcat(path_ani,"*.*");
  939.     strcpy(path_app,path_ani);
  940.     fsel_exinput(path_ani,name_ani,&ret,"Video for Aniplayer");
  941.     if(path_ani[0]>='A' && path_ani[0]<='Z')
  942.     {
  943.         car=strlen(path_ani)-1;    
  944.         while(path_ani[car]!='\\')
  945.             path_ani[car--]=0;
  946.         Dsetdrv(path_ani[0]-'A');Dsetpath(path_ani+2);
  947.         strcat(path_ani,name_ani);
  948.     }
  949.     if(ret)
  950.     {
  951.         ret=0;
  952.         t_edinfo=(TEDINFO *)rs_object[MENUAPNAME].ob_spec.tedinfo;
  953.         if(appl_find(t_edinfo->te_ptext)>0)
  954.         {
  955.             fsel_exinput(path_app,name_app,&ret,"File for Application");
  956.             if(path_app[0]>='A' && path_app[0]<='Z')
  957.             {
  958.                 car=strlen(path_app)-1;    
  959.                 while(path_app[car]!='\\')
  960.                     path_app[car--]=0;
  961.                 Dsetdrv(path_app[0]-'A');Dsetpath(path_app+2);
  962.                 strcat(path_app,name_app);
  963.             }
  964.         }
  965.         if(ret)
  966.         {
  967.             if(send_message_start(path_ani)
  968.              && send_message_info(0,0L))
  969.             {
  970.                 change_objc(MENUBSTOP,NORMAL,Work);
  971.                 change_objc(MENUBPLAY,SELECTED,Work);
  972.                 change_objc(MENUBPAUSE,NORMAL,Work);
  973.                 send_info=1;
  974.                 count_send++;
  975.                 start=1;
  976.                 status=old_status=PLAY;
  977.             }
  978.         }
  979.         else
  980.         {
  981.             if(send_message_start(path_ani)
  982.              && send_message_key('.'))
  983.             {
  984.                 change_objc(MENUBSTOP,NORMAL,Work);
  985.                 change_objc(MENUBPLAY,NORMAL,Work);
  986.                 change_objc(MENUBPAUSE,SELECTED,Work);
  987.                 *path_app=0;
  988.                 evnt_timer(100,0);
  989.                 if(send_message_key('.'))    /* display first picture and pause */
  990.                     send_message_app(AV_SENDKEY,(int)code_key(PAUSE),0);
  991.                 status=old_status=PAUSE;
  992.             }
  993.         }
  994.         load=first=1;
  995.     }
  996.     else
  997.     {
  998.         change_objc(MENUBSTOP,SELECTED,Work);
  999.         change_objc(MENUBPLAY,NORMAL,Work);
  1000.         change_objc(MENUBPAUSE,NORMAL,Work);    
  1001.         status=old_status=STOP;
  1002.         load=0;
  1003.     }
  1004.     change_objc(MENUBEJECT,NORMAL,Work);
  1005. }
  1006.  
  1007. void stop(void)
  1008.  
  1009. {
  1010.     if(send_message_key(0x6100))     /* UNDO */
  1011.     {
  1012.         change_objc(MENUBSTOP,SELECTED,Work);
  1013.         change_objc(MENUBPLAY,NORMAL,Work);
  1014.         change_objc(MENUBPAUSE,NORMAL,Work);
  1015.         send_message_app(AV_SENDKEY,(int)code_key(STOP),0);
  1016.         status=old_status=STOP;    
  1017.     }
  1018.     wait_end_clic();
  1019. }
  1020.  
  1021. void play(void)
  1022.  
  1023. {
  1024.     if(load && status==STOP)
  1025.     {
  1026.         if(send_message_start(path_ani))
  1027.         {
  1028.             change_objc(MENUBSTOP,NORMAL,Work);
  1029.             change_objc(MENUBPLAY,SELECTED,Work);
  1030.             change_objc(MENUBPAUSE,NORMAL,Work);
  1031.             seconds=0;
  1032.             if(*path_app && send_message_info(0,0L))
  1033.             {
  1034.                 send_info=1;
  1035.                 count_send++;
  1036.                 start=1;
  1037.             }
  1038.             status=old_status=PLAY;
  1039.         }
  1040.     }
  1041.     else
  1042.     {
  1043.         if(send_message_key('P'))
  1044.         {
  1045.             change_objc(MENUBSTOP,NORMAL,Work);
  1046.             change_objc(MENUBPLAY,SELECTED,Work);
  1047.             change_objc(MENUBPAUSE,NORMAL,Work);
  1048.             if(first && send_message_key(0x4b34))    /* SHIFT +   (-10S) */    
  1049.             {
  1050.                 first=0;
  1051.                 seconds=0;
  1052.             }
  1053.             send_message_app(AV_SENDKEY,(int)code_key(PLAY),0);
  1054.             status=old_status=PLAY;
  1055.         }
  1056.     }
  1057.     wait_end_clic();
  1058. }
  1059.  
  1060. void pause(void)
  1061.  
  1062. {
  1063.     if(send_message_key(' '))
  1064.     {
  1065.         change_objc(MENUBSTOP,NORMAL,Work);
  1066.         change_objc(MENUBPLAY,NORMAL,Work);
  1067.         change_objc(MENUBPAUSE,SELECTED,Work);
  1068.         status=old_status=PAUSE;    
  1069.         send_message_app(AV_SENDKEY,(int)code_key(PAUSE),0);
  1070.     }
  1071.     wait_end_clic();
  1072. }
  1073.  
  1074. void rew(void)
  1075.  
  1076. {
  1077.     change_objc(MENUBREW,SELECTED,Work);
  1078.     if(send_message_info(1,seconds-10))    /* or send_message_key(0x4b34)  SHIFT +   (-10S) */
  1079.         send_message_app(AV_SENDKEY,(int)code_key(REW),0);
  1080.     wait_end_clic();    
  1081.     change_objc(MENUBREW,NORMAL,Work);
  1082.  
  1083. }
  1084.  
  1085. void ff(void)
  1086.  
  1087. {
  1088.     change_objc(MENUBFF,SELECTED,Work);
  1089.     if(send_message_info(1,seconds+11))    /* or send_message_key(0x4d36)  SHIFT +   (+10S) */
  1090.         send_message_app(AV_SENDKEY,(int)code_key(FF),0);
  1091.     wait_end_clic();
  1092.     change_objc(MENUBFF,NORMAL,Work);
  1093. }
  1094.  
  1095. void conv_digit(char *string,int val)
  1096.  
  1097. {
  1098.     if(val>99)
  1099.         string[0]=string[1]='?';
  1100.     else
  1101.     {
  1102.         string[0]=(char)(val/10+16);
  1103.         string[1]=(char)(val%10+16);
  1104.     }
  1105. }
  1106.  
  1107. unsigned long get_hexa(char *string)
  1108.  
  1109. {
  1110.     register char *p;
  1111.     register int err,i,j;
  1112.     register long val;
  1113.     p=string;
  1114.     j=strlen(string);
  1115.     for(err=i=0;i<j && p[i];i++)
  1116.     {
  1117.         if(!((p[i]>='0' && p[i]<='9') || (p[i]>='A' && p[i]<='F')))
  1118.             err=1;
  1119.     }
  1120.     if(err || (i & 1) || i<2)
  1121.         return(0);
  1122.     else
  1123.     {
  1124.         val=0;
  1125.         for(i=0;i<j;i++)
  1126.         {
  1127.             val<<=4;
  1128.             if(p[i]>='0' && p[i]<='9')
  1129.                 val |= (p[i] & 0xf);
  1130.             else
  1131.                 val |= (p[i]-'A'+10);
  1132.         }
  1133.     }
  1134.     return(val);
  1135. }
  1136.