home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser-CD 1999 January / STC_CD_01_1999.iso / wdr / anip_202 / prog / sync_cpx / synchro.c < prev    next >
Text File  |  2000-01-08  |  29KB  |  1,123 lines

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