home *** CD-ROM | disk | FTP | other *** search
/ Dream 44 / Amiga_Dream_44.iso / Linux / Apps / xanim.tgz / xanim / xanim27064 / xanim.c < prev    next >
C/C++ Source or Header  |  1997-01-26  |  106KB  |  3,565 lines

  1.  
  2. /*
  3.  * xanim.c
  4.  *
  5.  * Copyright (C) 1990,1991,1992,1993,1994,1995,1996,1997 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed without
  9.  * fee for non-commerical purposes provided that this copyright notice is
  10.  * preserved intact on all copies and modified copies.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18. /****************
  19.  * Rev History
  20.  *
  21.  * 04Aug94 - fixed bug where xa_cmap was re-assigned to a cmap during
  22.  *           a cmap install. This was bad because when xa_cmap was being
  23.  *         free'd, it was freeing something else that got freed later.
  24.  *         This would cause core dumps on some systems.
  25.  * 05Aug94 - Modified audio/video sync code to account for XtAppAddTimeOut
  26.  *         calls.
  27.  * 09Aug94 - Removed XSync's when audio is enabled. This was causing stalls
  28.  *           in both audio and video whenever ANY window was moved or 
  29.  *         resized.
  30.  *       - Added XA_Time_Reset function to bring audio and video streams
  31.  *         up to date after a pause.
  32.  *       - Added XA_Audio_Pause routine, for those stops/starts since
  33.  *         Sparc Audio supports pausing.
  34.  *       - Audio should now properly resync itself after single stepping
  35.  *         in either direction(UNLESS YOU ACTUALLY RAN BACKWARDS).
  36.  * 12Aug94 - Setup X11 error handler to detec XShmAttach failures when Disp
  37.  *         is remote so I can backoff Shm support and continue on. 
  38.  * 12Sep94 - Now freeing up Actions. Before was accidently only freeing up
  39.  *         memory associated with Actions and not the actually Actions
  40.  *         themselves.
  41.  * 15Sep94 - Redid Audio and Video Timing to simply the synchronization
  42.  *         process and allow more features.
  43.  * 19Sep94 - Now free'ing up cmap_cache in TheEnd() if it was allocated.
  44.  *
  45.  * 16Mar95 - redid audio/video syncing routine to handle higher cpu
  46.  *           loads and more cpu intensive frames.
  47.  * 10Apr95 - Fixed bug where movies without sound would turn off sound
  48.  *         is movies listed later on the command line.
  49.  *
  50.  *******************************/
  51.  
  52. #define DA_REV 2.70
  53. #define DA_MINOR_REV 6
  54. #define DA_BETA_REV 4
  55.  
  56. /*
  57.  * Any problems, suggestions, solutions, anims to show off, etc contact:
  58.  *
  59.  * podlipec@wellfleet.com  or podlipec@shell.portal.com
  60.  *
  61.  */
  62.  
  63. #include "xanim.h"
  64. #include <Intrinsic.h>
  65. #include <StringDefs.h>
  66. #include <Shell.h>
  67.  
  68. #include <sys/types.h>
  69. #include <sys/ipc.h>
  70. #include <sys/msg.h>
  71.  
  72.  
  73. #ifdef __QNX__
  74. #include <signal.h>
  75. #else
  76. #include <sys/signal.h>
  77. #endif
  78.  
  79. #ifdef MSDOS
  80. #include <sys/resource.h>
  81. #else /* not MSDOS */
  82. #ifndef VMS   /* NOT MSDOS and NOT VMS ie Unix */
  83. #include <sys/time.h>
  84. #else   /* VMS systems */
  85. #include <lib$routines.h>
  86. #include <starlet.h>
  87. #ifdef R3_INTRINSICS
  88. typedef void *XtPointer;
  89. #endif
  90. #endif
  91. #endif
  92. #include <ctype.h>
  93.  
  94. #ifdef XSHM
  95. #include <sys/ipc.h>
  96. #include <sys/shm.h>
  97. #include <X11/extensions/XShm.h>
  98. extern Visual        *theVisual;
  99. #endif /*XSHM*/
  100.  
  101. #ifdef XA_REMOTE_CONTROL
  102. extern void XA_Create_Remote();
  103. extern void XA_Remote_Pause();
  104. extern void XA_Remote_Adj_Volume();
  105. extern void XA_Remote_Free();
  106.  
  107. #ifdef XA_PETUNIA
  108. extern void XA_Remote_ColorUpdate();
  109. #endif
  110. #endif
  111.  
  112. #include "xa_x11.h"
  113. #include "xa_ipc.h"
  114.  
  115. #ifdef XA_AUDIO
  116. void XA_Video_BOFL();
  117. void XA_Setup_BOFL();
  118. #endif
  119.  
  120. /* POD TEMP */
  121. XA_AUD_FLAGS *vaudiof;
  122. xaULONG xa_has_audio;
  123.  
  124. /*KLUDGES*/
  125. extern jpg_free_stuff();
  126.  
  127.  
  128. /************************************************** Fork Audio Defines *******/
  129.  
  130. #include "xa_ipc_cmds.h"
  131.  
  132.  
  133. xaULONG xa_forkit;
  134. xaULONG xa_vaudio_present;
  135. xaULONG xa_vaudio_enable;
  136. xaULONG xa_vaudio_status;
  137. xaULONG xa_vaudio_merge;
  138. xaULONG xa_vaudio_merge_scale;
  139.  
  140. XA_SND *xa_snd_cur;
  141.  
  142. xaULONG XA_Audio_Speaker(); 
  143. void XA_Read_Audio_Delta();
  144.  
  145. /* POD: NEED TO HAVE THIS INFO SENT ACROSS TO AUDIO CHILD IF CHANGED! */
  146. char *xa_audio_device = DEFAULT_AUDIO_DEVICE_NAME;
  147.  
  148.  
  149.  
  150. extern Widget theWG;
  151.  
  152. /* POD TESTING */
  153. xaULONG xa_kludge1_fli;
  154. xaULONG xa_kludge2_dvi;
  155. xaULONG xa_kludge900_aud;
  156.  
  157. void TheEnd();
  158. void TheEnd1();
  159. void Hard_Death();
  160. void Usage();
  161. void Usage_Quick();
  162. void XA_Lets_Get_Looped();
  163. void XAnim_Looped();
  164. extern XA_Open_And_ID_File();
  165. void XA_Audio_Wait();
  166. void XA_Cycle_Wait();
  167. void XA_Cycle_It();
  168. void Step_File_Next();
  169. void Step_File_Prev();
  170. void Step_Frame_Next();
  171. void Step_Frame_Prev();
  172. void Step_Action_Next();
  173. void Free_Actions();
  174. void ACT_Free_Act();
  175. XA_ANIM_HDR *Get_Anim_Hdr();
  176. XA_ANIM_HDR *Return_Anim_Hdr();
  177. void Step_Action_Prev();
  178. xaLONG XA_Time_Read();
  179. xaLONG XA_Time_Init();
  180. void XA_Time_Check();
  181. void XA_Reset_AV_Time();
  182. xaLONG XA_Read_AV_Time();
  183. void XA_Reset_Speed_Time();
  184. void XA_Install_CMAP();
  185. xaULONG XA_Mapped_To_Display();
  186. xaULONG XA_Read_Int();
  187. float XA_Read_Float();
  188. xaLONG XA_Get_Class();
  189. void XA_Add_Pause();
  190. void XA_Store_Title();
  191. void XA_Resize_Window();
  192. XA_ANIM_SETUP *XA_Get_Anim_Setup();
  193. void XA_Free_Anim_Setup();
  194. XA_FUNC_CHAIN *XA_Get_Func_Chain();
  195. void XA_Add_Func_To_Free_Chain();
  196. void XA_Walk_The_Chain();
  197. void XA_Store_Title();
  198. void XA_Adjust_Video_Timing();
  199.  
  200. extern void X11_Setup_Window();
  201. extern void X11_Map_Window();
  202. extern void X11_Init_Image_Struct();
  203. extern void X11_Init();
  204. extern void X11_Pre_Setup();
  205. extern void ACT_Make_Images();
  206. extern void XA_Show_Action();
  207. extern void XA_Free_CMAP();
  208.  
  209. extern xaULONG XA_Alloc_Input_Methods();
  210. extern xaULONG XA_Setup_Input_Methods();
  211.  
  212. void CMAP_Manipulate_CHDRS();
  213. void CMAP_Expand_Maps();
  214. xaULONG CMAP_Gamma_Adjust();
  215.  
  216. xaULONG DUM_Read_File();
  217.  
  218.  
  219. xaULONG shm = 0;
  220. #ifdef XSHM
  221. XShmSegmentInfo im0_shminfo;
  222. XShmSegmentInfo im1_shminfo;
  223. XShmSegmentInfo im2_shminfo;
  224. XImage *im0_Image = 0;
  225. XImage *im1_Image = 0;
  226. XImage *im2_Image = 0;
  227. XImage *sh_Image = 0;
  228. #endif
  229. xaULONG XA_Setup_Them_Buffers();
  230.  
  231. xaULONG mbuf = 0;
  232.  
  233. #ifdef VMS
  234. /*      
  235.  *      Provide the UNIX gettimeofday() function for VMS C.
  236.  *      The timezone is currently unsupported.
  237.  */
  238.  
  239. struct timeval {
  240.     long tv_sec;
  241.     long tv_usec;
  242. };
  243.  
  244. struct timezone {
  245.     int tz_minuteswest;
  246.     int tz_dsttime;
  247. };
  248.  
  249. int gettimeofday( tp, tzp)
  250. struct timeval *tp;
  251. struct timezone *tzp;
  252. {
  253.    long curr_time[2];   /* Eight byte VAX time variable */
  254.    long jan_01_1970[2] = { 0x4BEB4000,0x7C9567} ;
  255.    long diff[2];
  256.    long result;
  257.    long vax_sec_conv = 10000000;
  258.  
  259.    result = sys$gettim( &curr_time );
  260.  
  261.    result = lib$subx( &curr_time, &jan_01_1970, &diff);
  262.  
  263.    if ( tp != 0) {
  264.        result = lib$ediv( &vax_sec_conv, &diff,
  265.                           &(tp->tv_sec), &(tp->tv_usec) );
  266.        tp->tv_usec = tp->tv_usec / 10;  /* convert 1.e-7 to 1.e-6 */
  267.    }
  268.    if ( tzp !=0) { tzp->tz_minuteswest = 0; tzp->tz_dsttime=0;}
  269.  
  270.    return ( 0);
  271. }
  272. #endif
  273.  
  274.  
  275. /*
  276.  * Global X11 display configuation variables
  277.  *
  278.  * These are set by X11_Pre_Setup();
  279.  *
  280.  */
  281.  
  282. xaLONG x11_error_possible = 0; /* -1 err occured. 0 no error. 1 err expected */
  283. xaLONG x11_depth;
  284. xaLONG x11_class;
  285. xaLONG x11_bytes_pixel;
  286. xaLONG x11_byte_order;
  287. xaLONG x11_bits_per_pixel;
  288. xaLONG x11_bitmap_pad;
  289. xaLONG x11_pack_flag;
  290. xaLONG x11_bitmap_unit;
  291. xaLONG x11_bit_order;
  292. xaLONG x11_cmap_flag;
  293. xaLONG x11_cmap_size;
  294. xaLONG x11_cmap_installed = xaFALSE;
  295. xaLONG x11_disp_bits;
  296. xaLONG x11_cmap_type;
  297. xaLONG x11_depth_mask;
  298. xaLONG x11_display_type;
  299. xaLONG x11_red_mask;
  300. xaLONG x11_green_mask;
  301. xaLONG x11_blue_mask;
  302. xaLONG x11_red_shift;
  303. xaLONG x11_green_shift;
  304. xaLONG x11_blue_shift;
  305. xaLONG x11_red_bits;
  306. xaLONG x11_green_bits;
  307. xaLONG x11_blue_bits;
  308. xaLONG x11_black;
  309. xaLONG x11_white;
  310. xaLONG x11_verbose_flag;
  311. xaLONG pod_max_colors;
  312. xaLONG xa_user_visual;
  313. xaLONG xa_user_class;
  314. xaULONG x11_kludge_1;
  315. /*POD TEST */
  316. xaULONG pod = 0;
  317.  
  318. /* SMR 1 */
  319. /* variables used when playing into another app's window */
  320. xaLONG xa_window_x;
  321. xaLONG xa_window_y;
  322. xaULONG xa_window_id;
  323. char *xa_window_propname;
  324. xaULONG xa_window_center_flag;
  325. xaULONG xa_window_prepare_flag;
  326. xaULONG xa_window_refresh_flag;
  327. /* end SMR 1 */
  328.  
  329.  
  330. /*
  331.  * Each animation is broken up into a series of individual actions.
  332.  * For example, a gif image would become two actions, 1 to setup the
  333.  * colormap and 1 to display the image.
  334.  *
  335.  * XA_ACTION is defined in xanim.h. 
  336.  *
  337.  * action_cnt is a global variable that points to the next unused action.
  338.  * Currently, individual routines access this. This will change.
  339.  *
  340.  * action_start is a variable passed to the Read_Animation routines, It
  341.  * keeps track of the 1st action available to routine.
  342.  *
  343.  */
  344.  
  345. /*
  346.  * anim_type is one of IFF_,FLI_,GIF_,TXT_,FADE_ANIM. 
  347.  *
  348.  * merged_anim_flags is the or of all anims read in. FLI's anims need
  349.  * only 1 buffer. IFF anims need two. This allows software to allocate
  350.  * for the worst case.
  351.  *
  352.  */
  353. xaULONG xa_anim_type;
  354. xaULONG xa_merged_anim_flags;
  355.  
  356.  
  357. /*
  358.  * cmap keeps track of the current colors to the screen.
  359.  *
  360.  */
  361. xaLONG cmap_true_to_332;
  362. xaLONG cmap_true_to_gray;
  363. xaLONG cmap_true_to_1st;
  364. xaLONG cmap_true_to_all;
  365. xaLONG cmap_true_map_flag;
  366. xaLONG cmap_luma_sort;
  367. xaLONG cmap_map_to_1st_flag;
  368. xaLONG cmap_map_to_one_flag;
  369. xaLONG cmap_play_nice;
  370. xaLONG xa_allow_nice;
  371. xaLONG cmap_hist_flag;
  372. xaLONG cmap_dither_type;
  373. xaLONG cmap_median_type;
  374. xaLONG cmap_median_bits;
  375. xaLONG cmap_use_combsort;
  376. double xa_disp_gamma;
  377. double xa_anim_gamma;
  378. xaULONG xa_gamma_flag;
  379. xaUSHORT xa_gamma_adj[256];
  380. XA_CHDR *xa_chdr_start;
  381. XA_CHDR *xa_chdr_cur = 0;
  382. XA_CHDR *xa_chdr_now = 0;
  383. XA_CHDR *xa_chdr_first = 0;
  384. xaUSHORT *cmap_cache,*cmap_cache2;
  385. xaULONG cmap_cache_size;
  386. xaULONG cmap_cache_bits;
  387. xaULONG cmap_cache_rmask;
  388. xaULONG cmap_cache_gmask;
  389. xaULONG cmap_cache_bmask;
  390. XA_CHDR *cmap_cache_chdr;
  391. xaSHORT cmap_floyd_error;
  392.  
  393. xaULONG cmap_color_func;
  394. xaULONG cmap_sample_cnt;   /* sample anim every X many frames for colors */
  395.  
  396. /*
  397.  * These are variables for HAM images
  398.  *
  399.  */
  400. xaULONG xa_ham_map_size;
  401. xaULONG *xa_ham_map;
  402. XA_CHDR *xa_ham_chdr;
  403. xaULONG xa_ham_init;
  404. /*
  405.  * These are for converting xaTRUE images to PSEUDO
  406.  *
  407.  */
  408. xaULONG xa_r_shift,xa_g_shift,xa_b_shift;
  409. xaULONG xa_r_mask,xa_g_mask,xa_b_mask;
  410. xaULONG xa_gray_bits,xa_gray_shift;
  411.  
  412. ColorReg *xa_cmap = 0;
  413. xaULONG  xa_cmap_size,xa_cmap_off;
  414. xaULONG  *xa_map;
  415. xaULONG  xa_map_size,xa_map_off;
  416.  
  417. /*
  418.  * Global variable to keep track of Anim type
  419.  */
  420. xaLONG filetype;
  421. xaULONG xa_title_flag;
  422.  
  423.  
  424. /*
  425.  * Global variables to keep track of current width, height, num of colors and
  426.  * number of bit planes respectively. 
  427.  *
  428.  * the max_ variable are used for worst case allocation. Are useful for Anims
  429.  * that have multiple image sizes.
  430.  *
  431.  * image_size and max_image_size are imagex * imagey, etc.
  432.  */
  433. xaULONG xa_image_size;
  434. xaULONG xa_max_image_size;
  435. xaULONG xa_imagex,xa_max_imagex;
  436. xaULONG xa_imagey,xa_max_imagey;
  437. xaULONG xa_imaged;
  438.  
  439. /*
  440.  * Scaling Variable
  441.  *
  442.  */
  443.  
  444. xaULONG xa_need_to_scale_b;
  445. xaULONG xa_need_to_scale_u;
  446. float xa_scalex, xa_scaley;
  447. float xa_bscalex, xa_bscaley;
  448. xaULONG xa_buff_x,xa_buff_y;        /* anim buffering size */
  449. xaULONG xa_allow_lace;
  450. xaULONG xa_allow_resizing;         /* allow window resizing */
  451. xaULONG xa_disp_y, xa_max_disp_y;
  452. xaULONG xa_disp_x, xa_max_disp_x;
  453. xaULONG xa_disp_size;
  454. xaULONG xa_max_disp_size;
  455. xaULONG x11_display_x, x11_display_y;    /* max display size */
  456. xaULONG x11_window_x, x11_window_y;    /* current window size */
  457. xaULONG *xa_scale_row_buff;
  458. xaULONG xa_scale_row_size;
  459. xaULONG x11_expose_flag;
  460.  
  461. /* 
  462.  * These variable keep track of where we are in the animation.
  463.  * cur_file  ptr to the header of the current anim file. 
  464.  * cur_floop keeps track of how many times we've looped a file.
  465.  * cur_frame keeps track of which frame(action) we're on.
  466.  *
  467.  * xa_now_cycling and cycle_cnt are used for color cycling.
  468.  *
  469.  * file_is_started indicates whether this is the 1st time we've looped a file
  470.  * or not. Is used to initialize variables and resize window if necessary.
  471.  * 
  472.  */
  473. XA_ANIM_HDR *cur_file   = 0;
  474. XA_ANIM_HDR *first_file = 0;
  475. xaLONG xa_file_num;
  476. xaLONG cur_floop,cur_frame;
  477. xaLONG xa_cycle_cnt;      /* keeps track of number of cycling actions called */
  478. xaLONG xa_now_cycling;    /* indicates that cycling is now in progress */
  479. xaLONG xa_anim_cycling;   /* if set, allows cycling for animations */
  480. xaLONG file_is_started;
  481.  
  482. int xa_vid_fd;        /* Used if anim is being read from a file */
  483. xaUBYTE *xa_vidcodec_buf;
  484. xaULONG xa_vidcodec_maxsize; 
  485.  
  486. int xa_aud_fd;        /* Used if anim is being read from a file */
  487. xaUBYTE *xa_audcodec_buf;
  488. xaULONG xa_audcodec_maxsize;
  489.  
  490. /*
  491.  * Image buffers.
  492.  * im_buff1 is used for double buffered anims(IFF).
  493.  * xa_disp_buff is needed when the display is of a different format than the
  494.  * double buffered images. (like HAM or xaTRUE_COLOR).
  495.  *
  496.  * xa_pic is a pointer to im_buff0 or im_buff1 during double buffering.
  497.  * im_buff2 is used for dithered or HAM images
  498.  */
  499. char *im_buff0,*im_buff1,*im_buff2,*im_buff3;
  500. char *xa_pic,*xa_disp_buff,*xa_scale_buff;
  501. xaULONG xa_disp_buff_size,xa_scale_buff_size;
  502.  
  503. /*
  504.  * Variables for statistics
  505.  *
  506.  */
  507. xaLONG xa_time_now;
  508. xaLONG xa_time_video,xa_time_audio,xa_ptime_video;
  509. xaULONG xa_timelo_audio;
  510. xaLONG xa_audio_start;
  511. xaLONG xa_time_reset;
  512. xaLONG xa_av_time_off;
  513. xaLONG xa_skip_flag;    /* enables skipping */
  514. xaLONG xa_skip_diff;    /* keeps track of how far behind in frames */
  515. xaLONG xa_skip_video;    /* flag to Decoder  0 no 1 fallback/skip 2 skip */
  516. xaLONG xa_skip_cnt;    /* keeps track of how many we skip */
  517. xaLONG xa_time_start;
  518. xaLONG xa_time_end;
  519. xaLONG xa_time_off;
  520. xaLONG xa_no_disp;
  521. xaLONG xa_time_flag;
  522. xaLONG xa_time_av;
  523. xaLONG xa_frames_skipd, xa_frames_Sskipd;
  524. xaLONG xa_time_num;
  525. struct timeval tv;
  526.  
  527.  
  528. /* 
  529.  * Global flags that are set on command line.
  530.  */
  531. xaLONG xa_buffer_flag;
  532. xaLONG x11_shared_flag;
  533. xaLONG x11_multibuf_flag;
  534. xaLONG xa_file_flag;
  535. xaLONG fade_flag,fade_time;
  536. xaLONG xa_noresize_flag;
  537. xaLONG xa_optimize_flag;
  538. xaLONG xa_pixmap_flag;
  539. xaLONG xa_dither_flag;
  540. xaLONG xa_pack_flag;
  541. xaLONG xa_debug;
  542. xaLONG xa_verbose;
  543. xaLONG xa_quiet;
  544.  
  545. xaLONG xa_loop_each_flag;
  546. xaLONG xa_pingpong_flag;
  547. xaLONG xa_jiffy_flag;
  548. xaULONG xa_speed_scale,xa_speed_change;
  549.  
  550. xaLONG xa_anim_flags;
  551. xaLONG xa_anim_holdoff;
  552. xaLONG xa_anim_status,xa_old_status;
  553. xaLONG xa_anim_ready = xaFALSE;
  554. xaLONG xa_remote_ready = xaFALSE;
  555. xaLONG xa_use_depth_flag;
  556.  
  557. xaLONG xa_exit_flag;
  558. xaLONG xa_exit_early_flag;
  559. xaLONG xa_remote_flag;
  560.  
  561. XA_PAUSE *xa_pause_hdr=0;
  562. xaLONG xa_pause_last;
  563.  
  564.  
  565. /*
  566.  * act is a global pointer to the current action.
  567.  *
  568.  */
  569. XA_ACTION *act;
  570.  
  571. void
  572. Usage_Quick()
  573. {
  574.   fprintf(stdout,"Usage:\n");
  575.   fprintf(stdout,"   XAnim [options] anim [ [options] anim ... ]\n");
  576.   fprintf(stdout,"   -h  lists some common options, but may be out of date.\n");
  577.   fprintf(stdout,"   See xanim.readme or the man page for detailed help.\n");
  578.   TheEnd();
  579. }
  580. void
  581. Usage_Default_TF(flag,justify)
  582. xaULONG flag,justify;
  583. {
  584.   if (justify == 1) fprintf(stdout,"            ");
  585.   if (flag == xaTRUE) fprintf(stdout," default is on.\n");
  586.   else fprintf(stdout," default is off.\n");
  587. }
  588.  
  589. void
  590. Usage_Default_Num(num,justify)
  591. xaULONG num,justify;
  592. {
  593.   if (justify == 1) fprintf(stdout,"            ");
  594.   fprintf(stdout," default is %d.\n",num);
  595. }
  596.  
  597. /*
  598.  * This function attempts to expain XAnim's usage if the command line
  599.  * wasn't correct.
  600.  */
  601. void Usage()
  602. {
  603.  fprintf(stdout,"Usage:\n\n");
  604.  fprintf(stdout,"xanim [+V#] [ [+|-]opts ...] animfile [ [ [+|-opts] animfile] ... ]\n");
  605.  fprintf(stdout,"\n");
  606. #ifdef VMS
  607.  fprintf(stdout,"VMS users need to enclose opts in double qotes: \"+Cn\".\n");
  608.  fprintf(stdout,"\n");
  609. #endif
  610.  if (DEFAULT_PLUS_IS_ON == xaTRUE) 
  611.       fprintf(stdout,"A + turns an option on and a - turns it off.\n");
  612.  else fprintf(stdout,"A - turns an option on and a + turns it off.\n");
  613.  fprintf(stdout,"\n");
  614.  fprintf(stdout,"Options:\n");
  615.  fprintf(stdout,"\n  A[aopts]  Audio SubMenu\n");
  616.  fprintf(stdout,"      ADdev AIX Audio only.  dev  is audio device.\n");
  617.  fprintf(stdout,"      Ae    ENABLE Audio.\n");
  618.  fprintf(stdout,"      Ak    Enables video frame skipping to keep in sync with audio.\n");
  619.  fprintf(stdout,"      Ap#   Play Audio from output port #(Sparc only).\n");
  620. /* fprintf(stdout,"      As#   Scale Audio playback speed by #.\n"); */
  621.  fprintf(stdout,"      Av#   Set Audio volume to #. range 0 to 100.\n");
  622.  fprintf(stdout,"\n  C[copts]  Color SubMenu\n");
  623.  fprintf(stdout,"      C1    Create cmap from 1st TrueColor frame. Map\n");
  624.  fprintf(stdout,"            the rest to this first cmap.(Could be SLOW)\n");
  625.  fprintf(stdout,"      Ca    Remap  all images to single new cmap.\n");
  626.  Usage_Default_TF(DEFAULT_CMAP_MAP_TO_ONE,1);
  627.  fprintf(stdout,"      Cd    Use floyd-steinberg dithering(buffered only).\n");
  628.  Usage_Default_TF((DEFAULT_CMAP_DITHER_TYPE==CMAP_DITHER_FLOYD),1);
  629.  fprintf(stdout,"      CF4   Better(?) Color mapping for TrueColor anims.\n");
  630.  Usage_Default_TF(xaFALSE,1);
  631.  fprintf(stdout,"      Cg    Convert TrueColor anims to gray scale.\n");
  632.  Usage_Default_TF(DEFAULT_TRUE_TO_GRAY,1);
  633.  fprintf(stdout,"      Cn    Be Nice: allocate colors from Default cmap.\n");
  634.  Usage_Default_TF(DEFAULT_CMAP_PLAY_NICE,1);
  635.  fprintf(stdout,"\n  G[gopts]  Gamma SubMenu\n");
  636.  fprintf(stdout,"      Ga#   Set gamma of animation. Default %f\n",
  637.                             (DEFAULT_ANIM_GAMMA));
  638.  fprintf(stdout,"      Gd#   Set gamma of display. Default %f\n",
  639.                             (DEFAULT_DISP_GAMMA));
  640.  fprintf(stdout,"\n  S[sopts]  Scaling and Sizing SubMenu\n");
  641.  fprintf(stdout,"      Si    Half the height of IFF anims if Interlaced.\n");
  642.  Usage_Default_TF(DEFAULT_ALLOW_LACE_FLAG,1);
  643.  fprintf(stdout,"      Sn    Prevents X11 window from resizing to match anim's size.\n"); 
  644.  Usage_Default_TF(DEFAULT_NORESIZE_FLAG,1);
  645.  fprintf(stdout,"      Sr    Allow user to resize anim on the fly.\n");
  646.  Usage_Default_TF(DEFAULT_ALLOW_RESIZING,1);
  647.  fprintf(stdout,"      Ss#   Scale size of anim by # before displaying.\n");
  648.  fprintf(stdout,"      Sh#   Scale width of anim by # before displaying.\n");
  649.  fprintf(stdout,"      Sv#   Scale height of anim by # before displaying.\n");
  650.  fprintf(stdout,"      Sx#   Scale anim to have width # before displaying.\n");
  651.  fprintf(stdout,"      Sy#   Scale anim to have height # before displaying.\n");
  652.  fprintf(stdout,"      Sc    Copy display scaling factors to buffer scaling factors\n");
  653.  fprintf(stdout,"      SS#   Scale size of anim by # before buffering.\n");
  654.  fprintf(stdout,"      SH#   Scale width of anim by # before buffering.\n");
  655.  fprintf(stdout,"      SV#   Scale height of anim by # before buffering.\n");
  656.  fprintf(stdout,"      SX#   Scale anim to have width # before buffering.\n");
  657.  fprintf(stdout,"      SY#   Scale anim to have height # before buffering.\n");
  658.  fprintf(stdout,"      SC    Copy buffer scaling factors to display scaling factors\n");
  659. /* SMR 2 */
  660.  fprintf(stdout,"\n  W[wopts]  Window SubMenu\n");
  661.  fprintf(stdout,"      W#    X11 Window ID of window to draw into.\n");
  662.  fprintf(stdout,"      Wd    Don't refresh window at end of anim.\n");
  663.  fprintf(stdout,"      Wnx   Use property x for communication.\n");
  664.  fprintf(stdout,"      Wp    Prepare anim, but don't start playing it.\n");
  665.  fprintf(stdout,"      Wr    Resize X11 Window to fit anim.\n");
  666.  fprintf(stdout,"      Wx#   Position anim at x coordinate #.\n");
  667.  fprintf(stdout,"      Wy#   Position anim at y coordinate #.\n");
  668.  fprintf(stdout,"      Wc    Position relative to center of anim.\n");
  669. /* end SMR 2 */
  670.  fprintf(stdout,"\n  Normal Options\n");
  671.  fprintf(stdout,"       b    Uncompress and buffer images ahead of time.\n"); 
  672.  Usage_Default_TF(DEFAULT_BUFF_FLAG,1);
  673. #ifdef XSHM
  674.  fprintf(stdout,"       B    Use X11 Shared Memory Extention if supported.\n"); 
  675.  Usage_Default_TF(xaFALSE,1);
  676. #endif
  677.  fprintf(stdout,"       c    disable looping for nonlooping IFF anims.\n"); 
  678.  Usage_Default_TF(DEFAULT_IFF_LOOP_OFF,1);
  679.  fprintf(stdout,"       d#   debug. 0(off) to 5(most) for level of detail.\n"); 
  680.  Usage_Default_Num(DEFAULT_DEBUG,1);
  681.  fprintf(stdout,"       F    Enable dithering for certain Video Codecs only. see readme\n");
  682.  fprintf(stdout,"             or for Monochrome displays.\n");
  683.  Usage_Default_TF(DEFAULT_DITHER_FLAG,1);
  684.  fprintf(stdout,"       f    Don't load anims into memory, but read from file as needed\n"); 
  685.  Usage_Default_TF(DEFAULT_BUFF_FLAG,1);
  686.  fprintf(stdout,"       j#   # is number of milliseconds between frames.\n");
  687.  fprintf(stdout,"         if 0 then default depends on the animation.\n");
  688.  Usage_Default_Num(DEFAULT_JIFFY_FLAG,1);
  689.  fprintf(stdout,"       l#   loop anim # times before moving on.\n");
  690.  Usage_Default_Num(DEFAULT_LOOPEACH_FLAG,1);
  691.  fprintf(stdout,"       lp#  ping-pong anim # times before moving on.\n");
  692.  Usage_Default_Num(DEFAULT_PINGPONG_FLAG,1);
  693.  fprintf(stdout,"       N    No display. Useful for benchmarking.\n");
  694.  fprintf(stdout,"       o    turns on certain optimizations. See readme.\n"); 
  695.  Usage_Default_TF(DEFAULT_OPTIMIZE_FLAG,1);
  696.  fprintf(stdout,"       p    Use Pixmap instead of Image in X11(buffered only).\n"); 
  697.  Usage_Default_TF(DEFAULT_PIXMAP_FLAG,1);
  698.  fprintf(stdout,"       q    quiet mode.\n"); 
  699.  fprintf(stdout,"       r    Allow color cycling for IFF single images.\n");
  700.  Usage_Default_TF(DEFAULT_CYCLE_IMAGE_FLAG,1);
  701.  fprintf(stdout,"       R    Allow color cycling for IFF anims.\n");
  702.  Usage_Default_TF(DEFAULT_CYCLE_ANIM_FLAG,1);
  703.  fprintf(stdout,"       T#   Title Option. See readme.\n");
  704.  fprintf(stdout,"       v    verbose mode.\n"); 
  705.  Usage_Default_TF(DEFAULT_VERBOSE,1);
  706.  fprintf(stdout,"       V#   Use Visual #. # is obtained by +X option.\n"); 
  707.  fprintf(stdout,"       X    X11 verbose mode. Display Visual information.\n");
  708.  fprintf(stdout,"       Ze   Have XAnim exit after playing cmd line.\n");
  709.  fprintf(stdout,"       Zp#  Pause at specified frame number.\n");
  710.  fprintf(stdout,"       Zpe  Pause at end of animation.\n");
  711.  fprintf(stdout,"\n");
  712.  fprintf(stdout,"Window commands.\n");
  713.  fprintf(stdout,"\n");
  714.  fprintf(stdout,"        q    quit.\n");
  715.  fprintf(stdout,"        Q    Quit.\n");
  716.  fprintf(stdout,"        g    Stop color cycling.\n");
  717.  fprintf(stdout,"        r    Restore original Colors(useful after g).\n");
  718.  fprintf(stdout,"    <space>  Toggle. Starts/Stops animation.\n");
  719.  fprintf(stdout,"        ,    Single step back one frame.\n");
  720.  fprintf(stdout,"        .    Single step forward one frame.\n");
  721.  fprintf(stdout,"        <    Go back to start of previous anim.\n");
  722.  fprintf(stdout,"        >    Go forward to start of next anim.\n");
  723.  fprintf(stdout,"        m    Single step back one frame staying within anim.\n");
  724.  fprintf(stdout,"        /    Single step forward one frame staying within anim.\n");
  725.  fprintf(stdout,"        -    Increase animation playback speed.\n");
  726.  fprintf(stdout,"        =    Decrease animation playback speed.\n");
  727.  fprintf(stdout,"        0    Reset animation playback speed to original values.\n");
  728.  fprintf(stdout,"        1    Decrease audio volume by 5 percent.\n");
  729.  fprintf(stdout,"        2    Decrease audio volume by 1 percent.\n");
  730.  fprintf(stdout,"        3    Increase audio volume by 1 percent.\n");
  731.  fprintf(stdout,"        4    Increase audio volume by 5 percent.\n");
  732.  fprintf(stdout,"        8    Send audio to headphones.\n");
  733.  fprintf(stdout,"        9    Send audio to speakers.\n");
  734.  fprintf(stdout,"        s    Mute audio.\n");
  735.  fprintf(stdout,"\n");
  736.  fprintf(stdout,"Mouse Buttons.\n");
  737.  fprintf(stdout,"\n");
  738.  fprintf(stdout,"      <Left> Single step back one frame.\n");
  739.  fprintf(stdout,"    <Middle> Toggle. Starts/Stops animation.\n");
  740.  fprintf(stdout,"     <Right> Single step forward one frame.\n");
  741.  fprintf(stdout,"\n");
  742. #ifndef XA_IS_PLUGIN
  743.  exit(0);
  744. #endif
  745. }
  746.  
  747. int main(argc, argv)
  748. int argc;
  749. char *argv[];
  750. {
  751.   char *filename,*in;
  752.   xaLONG i,j;
  753.  
  754.   vaudiof = 0;
  755. /* 
  756.  * Initialize global variables.
  757.  */
  758.   theDisp = NULL;
  759.  
  760.   xa_av_time_off = XA_Time_Init();
  761.   xa_forkit = xaFALSE;
  762.  
  763.   xa_time_now        = 0;
  764.   xa_time_video        = xa_ptime_video    =  0;
  765.   xa_time_audio        = -1;
  766.   xa_timelo_audio    = 0;
  767.   xa_vid_fd        = xa_aud_fd        = -1;
  768.   xa_vidcodec_buf    = xa_audcodec_buf    =  0;
  769.   xa_vidcodec_maxsize    = xa_audcodec_maxsize    =  0;
  770.   xa_kludge2_dvi    = xaFALSE;
  771.   xa_kludge900_aud    = 0;
  772.  
  773. #ifdef XA_AUDIO
  774.   xa_vaudio_present    = XA_AUDIO_UNK;
  775.   xa_vaudio_enable    = DEFAULT_XA_AUDIO_ENABLE;
  776.   xa_vaudio_status    = XA_AUDIO_NICHTDA;
  777.   xa_vaudio_merge    = xaFALSE;
  778.   xa_vaudio_merge_scale = xaFALSE;
  779.  
  780.     /*** POD FOR FORK TESTING PURPOSES ONLY */
  781.   if ( strcmp( argv[0], "xad\0") == 0) XA_IPC_Set_Debug(xaTRUE);
  782.  
  783.   xa_forkit = XA_Give_Birth();  /* FireUp the Audio Child */
  784.  
  785.     /*** Wait for first XA_IPC_OK Acknowlege */
  786.   if (xa_forkit == xaTRUE)    xa_forkit = XA_Video_Receive_Ack(5000);
  787.  
  788.   if (xa_forkit == xaTRUE)
  789.     xa_forkit = XA_Video_Send2_Audio(XA_IPC_HELLO,NULL,0,0,2000,0);
  790.  
  791. #else  /* NO AUDIO */
  792.  xa_vaudio_present    = XA_AUDIO_NONE;
  793.  xa_vaudio_enable    = xaFALSE;
  794.  xa_vaudio_status    = XA_AUDIO_NICHTDA;
  795. #endif
  796.  
  797.  vaudiof = (XA_AUD_FLAGS *)malloc( sizeof(XA_AUD_FLAGS) );
  798.  if (vaudiof==0) TheEnd1("vaudiof failure\n");
  799.  
  800.  cmap_color_func = 0;
  801.  cmap_sample_cnt = 5; /* default value */
  802.  
  803.  xa_has_audio    = xaFALSE;
  804. #ifdef XSHM
  805.  im0_shminfo.shmaddr = 0;
  806.  im1_shminfo.shmaddr = 0;
  807.  im2_shminfo.shmaddr = 0;
  808. #endif
  809.  im_buff0 = im_buff1 = im_buff2 = im_buff3 = 0;
  810.  xa_disp_buff = 0;
  811.  xa_disp_buff_size = 0;
  812.  xa_scale_row_buff = 0;
  813.  xa_scale_row_size = 0;
  814.  xa_scale_buff    = 0;
  815.  xa_scale_buff_size = 0;
  816.  xa_imagex    = 0;
  817.  xa_imagey    = 0;
  818.  xa_disp_x    = 0;
  819.  xa_disp_y    = 0;
  820.  xa_scalex    = 1.0;
  821.  xa_scaley    = 1.0;
  822.  xa_buff_x    = 0;
  823.  xa_buff_y    = 0;
  824.  xa_bscalex    = 1.0;
  825.  xa_bscaley    = 1.0;
  826.  xa_need_to_scale_b = 0;
  827.  xa_need_to_scale_u = 0;
  828.  xa_max_imagex    = 0;
  829.  xa_max_imagey    = 0;
  830.  xa_max_disp_x    = 0;
  831.  xa_max_disp_y    = 0;
  832.  xa_anim_flags        = 0;
  833.  xa_merged_anim_flags    = 0;
  834.  x11_pack_flag    = xaFALSE;
  835.  x11_expose_flag = xaFALSE;
  836.  x11_error_possible = 0;
  837.  
  838.  first_file = cur_file = 0;
  839.  xa_file_num = -1;
  840.  
  841.  xa_anim_holdoff    = xaTRUE;
  842.  xa_anim_status        = XA_UNSTARTED;
  843.  xa_old_status        = XA_UNSTARTED;
  844.  xa_anim_ready        = xaFALSE;
  845.  xa_remote_ready    = xaFALSE;
  846.  
  847.  xa_audio_start        = 0;
  848.  xa_time_reset        = 0;
  849.  
  850.  vaudiof->device        = DEFAULT_AUDIO_DEVICE_NAME;
  851.  vaudiof->scale        = 1.0;
  852.  vaudiof->mute        = xaFALSE;
  853.  vaudiof->volume        = DEFAULT_XA_AUDIO_VOLUME;
  854.  if (vaudiof->volume > XA_AUDIO_MAXVOL) vaudiof->volume = XA_AUDIO_MAXVOL;
  855.  vaudiof->newvol    = xaTRUE;
  856.  vaudiof->playrate    = 0;
  857.  vaudiof->port         = XA_Audio_Speaker("SPEAKER");
  858.  /* if DEFAULT_XA_AUDIO_PORT is 0, then XAnim doesn't reset it */
  859.  if (vaudiof->port == 0) vaudiof->port = DEFAULT_XA_AUDIO_PORT;
  860.  vaudiof->divtest    = 2;
  861.  vaudiof->fromfile    = xaFALSE;
  862.  vaudiof->bufferit    = xaFALSE;
  863.  XA_AUDIO_SET_VOLUME(vaudiof->volume);
  864.  XA_AUDIO_SET_MUTE(vaudiof->mute);
  865.  XA_AUDIO_SET_RATE(vaudiof->playrate);
  866.  
  867.  xa_skip_flag        = xaTRUE;
  868.  xa_skip_video        = 0;
  869.  xa_skip_diff        = 0;
  870.  xa_skip_cnt        = 0;
  871.  
  872.  xa_buffer_flag        = DEFAULT_BUFF_FLAG;
  873.  if (xa_buffer_flag == xaTRUE) xa_file_flag = xaFALSE;
  874.  else xa_file_flag    = DEFAULT_FILE_FLAG;
  875.  x11_shared_flag    = xaTRUE;
  876.  x11_multibuf_flag    = xaTRUE;
  877.  xa_pack_flag        = DEFAULT_PACK_FLAG;
  878.  xa_noresize_flag    = DEFAULT_NORESIZE_FLAG;
  879.  xa_verbose        = DEFAULT_VERBOSE;
  880.  xa_quiet        = DEFAULT_QUIET;
  881.  xa_debug        = DEFAULT_DEBUG;
  882.  xa_anim_cycling    = DEFAULT_CYCLE_ANIM_FLAG;
  883.  xa_allow_lace        = DEFAULT_ALLOW_LACE_FLAG;
  884.  xa_allow_resizing    = DEFAULT_ALLOW_RESIZING;
  885.  xa_optimize_flag    = DEFAULT_OPTIMIZE_FLAG;
  886.  xa_pixmap_flag        = DEFAULT_PIXMAP_FLAG;
  887.  xa_dither_flag        = DEFAULT_DITHER_FLAG;
  888.  xa_loop_each_flag    = DEFAULT_LOOPEACH_FLAG;
  889.  xa_pingpong_flag    = DEFAULT_PINGPONG_FLAG;
  890.  xa_jiffy_flag        = DEFAULT_JIFFY_FLAG;
  891.  xa_speed_scale        = XA_SPEED_NORM;
  892.  xa_speed_change    = 0;
  893.  x11_verbose_flag    = DEFAULT_X11_VERBOSE_FLAG;
  894.  x11_kludge_1        = xaFALSE;
  895.  cmap_luma_sort        = DEFAULT_CMAP_LUMA_SORT;
  896.  cmap_map_to_1st_flag    = DEFAULT_CMAP_MAP_TO_1ST;
  897.  cmap_map_to_one_flag    = DEFAULT_CMAP_MAP_TO_ONE;
  898.  cmap_play_nice        = DEFAULT_CMAP_PLAY_NICE;
  899.  xa_allow_nice        = xaTRUE;
  900.  cmap_hist_flag        = DEFAULT_CMAP_HIST_FLAG;
  901.  cmap_dither_type    = DEFAULT_CMAP_DITHER_TYPE;
  902.  
  903.  cmap_median_type    = DEFAULT_CMAP_MEDIAN_TYPE;
  904.  cmap_median_bits    = 6;
  905.  cmap_use_combsort    = xaTRUE;
  906.  cmap_floyd_error    = 256; 
  907.  cmap_cache        = cmap_cache2        = 0;
  908.  cmap_cache_size    = 0;
  909.  cmap_cache_bits    = 0;
  910.  cmap_cache_rmask    = 0;
  911.  cmap_cache_gmask    = 0;
  912.  cmap_cache_bmask    = 0;
  913.  cmap_cache_chdr    = 0;
  914.  xa_disp_gamma        = DEFAULT_DISP_GAMMA;
  915.  xa_anim_gamma        = DEFAULT_ANIM_GAMMA;
  916.  xa_gamma_flag        = xaFALSE;
  917.  
  918.  xa_title_flag        = DEFAULT_XA_TITLE_FLAG;
  919.  xa_exit_flag        = DEFAULT_XA_EXIT_FLAG;
  920.  xa_exit_early_flag    = xaFALSE;
  921.  xa_remote_flag        = DEFAULT_XA_REMOTE_FLAG;
  922.  
  923.  xa_chdr_start        = 0;
  924.  xa_chdr_cur        = 0;
  925.  xa_chdr_now        = 0;
  926.  xa_chdr_first        = 0;
  927.  xa_cmap        = 0;
  928.  xa_cmap_size        = 0;
  929.  xa_cmap_off        = 0;
  930.  xa_map            = 0;
  931.  xa_map_size        = 0;
  932.  xa_map_off        = 0;
  933.  xa_time_start        = 0;
  934.  xa_time_end        = 0;
  935.  xa_time_av         = 0;
  936.  xa_frames_skipd    = xa_frames_Sskipd    = 0;
  937.  xa_time_num        = 0;
  938.  xa_no_disp        = xaFALSE;
  939.  xa_time_flag        = xaFALSE;
  940.  pod_max_colors        = 0;
  941.  xa_r_shift = xa_g_shift = xa_b_shift = 0;
  942.  xa_r_mask = xa_g_mask = xa_b_mask = 0;
  943.  xa_gray_bits = xa_gray_shift = 0;
  944.  xa_ham_map_size = 0;
  945.  xa_ham_map = 0;
  946.  xa_ham_chdr = 0;
  947.  xa_ham_init = 0;
  948.  xa_kludge1_fli = xaFALSE;
  949.  xa_pause_hdr = 0;
  950.  xa_pause_last = xaFALSE;
  951.  
  952. /* SMR 3 */
  953.   xa_window_x = 0;
  954.   xa_window_y = 0;
  955.   xa_window_id = 0;
  956.   xa_window_propname = "XANIM_PROPERTY";
  957.   xa_window_center_flag = xaFALSE;
  958.   xa_window_prepare_flag = xaFALSE;
  959.   xa_window_refresh_flag = xaTRUE;
  960. /* end SMR 3 */
  961.  
  962.  xa_gamma_flag = CMAP_Gamma_Adjust(xa_gamma_adj,xa_disp_gamma,xa_anim_gamma);
  963.  
  964.  if (DEFAULT_IFF_LOOP_OFF  == xaTRUE) xa_anim_flags |= ANIM_NOLOOP;
  965.  if (DEFAULT_CYCLE_IMAGE_FLAG == xaTRUE) xa_anim_flags |= ANIM_CYCLE;
  966.  
  967. /* setup for dying time.
  968.  */
  969.  signal(SIGINT,Hard_Death);
  970.  
  971.  /* pre-check for user visual */
  972.  /* Note -- we also have to pre-check for the d option, since we could
  973.   * run through a good deal of code before we even set xa_debug!!!
  974.   */
  975.  xa_user_visual = -1;
  976.  xa_user_class  = -1;
  977.  for(i=1;i<argc;i++)
  978.  {
  979.    in = argv[i];
  980.  
  981. /* SMR 4 */
  982. /* Get the other applications window id.  Required to properly init
  983.    visual and colormap */
  984.    if ( (in[0]=='+') && (in[1]=='W') && (in[2] >= '0') && (in[2] <= '9') )
  985.    {
  986.      xa_window_id = strtol(&in[2], NULL, 0);
  987.      xa_noresize_flag = xaTRUE;
  988.    }
  989. /* end SMR 4 */
  990.    else if ( ((in[0]=='-') || (in[0]=='+')) && (in[1]=='V') )
  991.    {
  992.      if ( (in[2] >= '0') && (in[2] <= '9') )  /* number */
  993.         xa_user_visual = atoi(&in[2]);
  994.      else    xa_user_class = XA_Get_Class( &in[2] );
  995.    }
  996.    else if ( (in[0]=='-') && (in[1]=='X') ) x11_verbose_flag = xaFALSE;
  997.    else if ( (in[0]=='+') && (in[1]=='X') ) x11_verbose_flag = xaTRUE;
  998.    else if ( (in[0]=='+') && (in[1]=='B') ) x11_shared_flag = xaTRUE;
  999.    else if ( (in[0]=='-') && (in[1]=='B') ) x11_shared_flag = xaFALSE;
  1000.    else if ( (in[0]=='+') && (in[1]=='D') ) x11_multibuf_flag = xaTRUE;
  1001.    else if ( (in[0]=='-') && (in[1]=='D') ) x11_multibuf_flag = xaFALSE;
  1002.    else if ( (in[0]=='+') && (in[1]=='q') ) xa_quiet = xaTRUE;
  1003.    else if ( (in[0]=='-') && (in[1]=='q') ) xa_quiet = xaFALSE;
  1004.    else if ( ( (in[0]=='-') && (in[1]=='d') )   ||
  1005.              ( (in[0]=='+') && (in[1]=='d') ) ){
  1006.      if ( (in[2] >= '0') && (in[2] <= '9') )  /* number */
  1007.                 xa_debug = atoi(&in[2]);
  1008.      if (xa_debug <= 0) xa_debug = 0;
  1009.    }
  1010.    else if ( (in[0]=='+') && (in[1]=='P') )
  1011.    {
  1012.      pod_max_colors = atoi(&in[2]); /* POD Testing only */
  1013.    }
  1014.    else if ( ((in[0]=='-') || (in[0]=='+')) && (in[1]=='h') ) Usage();
  1015.  }
  1016.  
  1017. /* What REV are we running
  1018.  */
  1019.  if ( (xa_quiet==xaFALSE) || (xa_verbose==xaTRUE) || (xa_debug >= 1) )
  1020. /* 
  1021.     fprintf(stdout,"XAnim Rev %2.2f.%d by Mark Podlipec (c) 1991-1997\n",DA_REV,DA_MINOR_REV);
  1022. */
  1023.     fprintf(stdout,"XAnim Rev %2.2f.%d.%d by Mark Podlipec (c) 1991-1997\n",DA_REV,DA_MINOR_REV,DA_BETA_REV);
  1024.  
  1025. /* quick command line check.
  1026.  */
  1027.  if (argc<2) Usage_Quick();
  1028.  
  1029.  
  1030.  /* PreSet of X11 Display to find out what we're dealing with
  1031.   */
  1032.  DEBUG_LEVEL5 (void)fprintf(stdout,"Calling X11_Pre_Setup()\n");
  1033.  X11_Init(&argc, argv);
  1034.  X11_Pre_Setup(xa_user_visual, xa_user_class);
  1035.  
  1036. #ifdef XA_AUDIO
  1037.  if (xa_forkit == xaTRUE)    XA_Setup_BOFL();
  1038. #endif
  1039.  
  1040.  if (xa_allow_nice == xaFALSE) cmap_play_nice = xaFALSE;
  1041.  if ( (x11_bits_per_pixel == 2) || (x11_bits_per_pixel == 4) )
  1042.                         x11_pack_flag = xaTRUE;
  1043.   if (x11_display_type == XA_MONOCHROME) xa_dither_flag = DEFAULT_DITHER_FLAG;
  1044.   else if (   (x11_display_type == XA_PSEUDOCOLOR)
  1045.        || (x11_display_type == XA_STATICCOLOR) )
  1046.   {
  1047.     if (cmap_color_func == 4) xa_dither_flag = xaFALSE;
  1048.     else if (cmap_color_func == 5) xa_dither_flag = xaTRUE;
  1049.     else xa_dither_flag = DEFAULT_DITHER_FLAG;
  1050.   }
  1051.   else xa_dither_flag = xaFALSE;
  1052.  
  1053.  /* Audio Setup */
  1054.  DEBUG_LEVEL5 (void)fprintf(stdout,"Calling XA_Audio_Setup()\n");
  1055.  XA_AUDIO_SETUP;
  1056.  
  1057.  /* Visual Dependent switches and flags */
  1058.  if (x11_display_type & XA_X11_TRUE)
  1059.  {
  1060.    cmap_true_to_332  = xaFALSE; cmap_true_to_gray = xaFALSE;
  1061.    cmap_true_to_1st  = xaFALSE; cmap_true_to_all  = xaFALSE;
  1062.    cmap_true_map_flag = xaFALSE;
  1063.  }
  1064.  else if (x11_display_type & XA_X11_COLOR)
  1065.  {
  1066.    cmap_true_to_332  = DEFAULT_TRUE_TO_332;
  1067.    cmap_true_to_gray = DEFAULT_TRUE_TO_GRAY;
  1068.    cmap_true_to_1st  = DEFAULT_TRUE_TO_1ST;
  1069.    cmap_true_to_all  = DEFAULT_TRUE_TO_ALL;
  1070.    if (cmap_true_to_1st || cmap_true_to_all) cmap_true_map_flag = xaTRUE;
  1071.    else cmap_true_map_flag = DEFAULT_TRUE_MAP_FLAG;
  1072.  }
  1073.  else { cmap_true_to_332  = xaFALSE; cmap_true_to_gray = xaTRUE; 
  1074.         cmap_true_to_1st  = xaFALSE; cmap_true_to_all  = xaFALSE;
  1075.         cmap_true_map_flag = xaFALSE;  }
  1076.  
  1077.  xa_time_start = XA_Time_Read();
  1078.  
  1079. /* Parse command line.
  1080.  */
  1081.  for(i=1; i < argc; i++)
  1082.  {
  1083.    in = argv[i];
  1084.    if ( ((in[0] == '-') || (in[0] == '+')) && (in[1] != '\0'))
  1085.    {
  1086.      xaLONG len,opt_on;
  1087.  
  1088.      if (in[0] == '-') opt_on = xaFALSE;
  1089.      else opt_on = xaTRUE;
  1090.      /* if + turns off then reverse opt_on */
  1091.      if (DEFAULT_PLUS_IS_ON == xaFALSE) opt_on = (opt_on==xaTRUE)?xaFALSE:xaTRUE;
  1092.  
  1093.      len = strlen(argv[i]);
  1094.      j = 1;
  1095.      while( (j < len) && (in[j] != 0) )
  1096.      {
  1097.        switch(in[j])
  1098.        {
  1099.         case 'A':   /* audio options sub menu */
  1100.     {
  1101.       xaULONG exit_flag = xaFALSE;
  1102.       j++;
  1103.       while( (exit_flag == xaFALSE) && (j<len) )
  1104.       {
  1105.         switch(in[j])
  1106.         {
  1107.           case 'b':   /* snd buffer on/off */
  1108.         j++; vaudiof->bufferit = opt_on;
  1109.         break;
  1110.           case 'e':   /* snd enable on/off */
  1111.         j++; xa_vaudio_enable = opt_on;
  1112.         break;
  1113.           case 'k':   /* toggle skip video */
  1114.         j++; xa_skip_flag = opt_on;
  1115.         break;
  1116.           case 'p':   /* select audio port */
  1117.         { xaULONG t,val;
  1118.           j++; t = XA_Read_Int(in,&j);
  1119.           switch(t)
  1120.           {
  1121.             case 0: val = XA_AUDIO_PORT_INT; break;
  1122.             case 1: val = XA_AUDIO_PORT_HEAD; break;
  1123.             case 2: val = XA_AUDIO_PORT_EXT; break;
  1124.             default: val = 0;
  1125.           }
  1126.           if (opt_on == xaTRUE) vaudiof->port |= val;
  1127.           else vaudiof->port &= ~(val);
  1128.         }
  1129.         break;
  1130.           case 'm':  /* Merge audio into previous */
  1131.         j++; xa_vaudio_merge = opt_on;
  1132.         break;
  1133.           case 'M':  /* Merge audio into previous and scale timing */
  1134.         j++; xa_vaudio_merge_scale = opt_on;
  1135.         break;
  1136.           case 'd':   /* POD TEST */
  1137.         j++; vaudiof->divtest = XA_Read_Int(in,&j);
  1138.         if (vaudiof->divtest==0) vaudiof->divtest = 2;
  1139.         break;
  1140.           case 'D':   /* s/6000 audio device name */
  1141.           {
  1142.         j++; vaudiof->device = &in[j];
  1143.         j = len;
  1144.           }
  1145.           break;
  1146.           case 'r':   /* POD TEST */
  1147.         j++; vaudiof->playrate = XA_Read_Int(in,&j);
  1148.         if (vaudiof->playrate==0) vaudiof->playrate = 8000;
  1149.         XA_AUDIO_SET_RATE(vaudiof->playrate);
  1150.         break;
  1151.           case 's':   /* snd scale */
  1152.         j++; vaudiof->scale = XA_Read_Float(in,&j);
  1153.         fprintf(stdout,"XAnim: +As# temporarily disabled.\n");
  1154.         if (vaudiof->scale < 0.125) vaudiof->scale = 0.125;
  1155.         if (vaudiof->scale > 8.000) vaudiof->scale = 8.000;
  1156.         break;
  1157.           case 'v':
  1158.         j++; vaudiof->volume = XA_Read_Int(in,&j);
  1159.         if (vaudiof->volume > XA_AUDIO_MAXVOL) 
  1160.                     vaudiof->volume = XA_AUDIO_MAXVOL;
  1161.         XA_AUDIO_SET_VOLUME(vaudiof->volume);
  1162.         break;
  1163.           default: exit_flag = xaTRUE;
  1164.         }
  1165.       }
  1166.     }
  1167.     break;
  1168.         case 'C':   /* colormap options sub menu */
  1169.       {
  1170.         xaULONG exit_flag = xaFALSE;
  1171.         j++;
  1172.         while( (exit_flag == xaFALSE) && (j<len) )
  1173.         {
  1174.         switch(in[j])
  1175.         {
  1176.           case 's':
  1177.             j++; cmap_sample_cnt = XA_Read_Int(in,&j);
  1178.             break;
  1179.           case 'F':
  1180.             j++; cmap_color_func = XA_Read_Int(in,&j);
  1181.             if (cmap_color_func==4) xa_dither_flag = xaFALSE;
  1182.             else if (cmap_color_func==5)
  1183.             { xa_dither_flag = xaTRUE;
  1184.               cmap_color_func = 4;
  1185.             }
  1186.             break;
  1187.           case '1':
  1188.              if (   (x11_display_type & XA_X11_TRUE)
  1189.                  || (x11_display_type == XA_MONOCHROME) ) 
  1190.                             opt_on = xaFALSE;
  1191.             cmap_true_to_1st  = opt_on;
  1192.             if (cmap_true_to_1st == xaTRUE)
  1193.             {
  1194.               cmap_true_to_gray = xaFALSE; cmap_true_to_332  = xaFALSE;
  1195.               cmap_true_to_all  = xaFALSE; cmap_true_map_flag = xaTRUE;
  1196.             }
  1197.             j++; break;
  1198.           case 'A':
  1199.              if (   (x11_display_type & XA_X11_TRUE)
  1200.                  || (x11_display_type == XA_MONOCHROME) ) 
  1201.                             opt_on = xaFALSE;
  1202.             cmap_true_to_all  = opt_on;
  1203.             if (cmap_true_to_all == xaTRUE)
  1204.             {
  1205.               cmap_true_to_gray = xaFALSE; cmap_true_to_332  = xaFALSE;
  1206.               cmap_true_to_1st  = xaFALSE; cmap_true_map_flag = xaTRUE;
  1207.             }
  1208.             j++; break;
  1209.           case '3':
  1210.              if (   (x11_display_type & XA_X11_TRUE)
  1211.                  || (!(x11_display_type & XA_X11_COLOR))
  1212.                  || (x11_display_type == XA_MONOCHROME) ) 
  1213.                             opt_on = xaFALSE;
  1214.             cmap_true_to_332  = opt_on;
  1215.             if (opt_on == xaTRUE)
  1216.             {
  1217.               cmap_true_to_gray = xaFALSE; cmap_true_to_1st  = xaFALSE;
  1218.               cmap_true_to_all  = xaFALSE;
  1219.             }
  1220.             j++; break;
  1221.           case 'g':
  1222.              if (x11_display_type & XA_X11_TRUE) opt_on = xaFALSE;
  1223.             cmap_true_to_gray  = opt_on;
  1224.             if (opt_on == xaTRUE)
  1225.             {
  1226.               cmap_true_to_332 = xaFALSE; cmap_true_to_1st = xaFALSE;
  1227.               cmap_true_to_all = xaFALSE;
  1228.             }
  1229.             j++; break;
  1230.           case 'a': cmap_map_to_one_flag = opt_on; j++; break;
  1231.           case 'd': cmap_dither_type = CMAP_DITHER_FLOYD; j++; break;
  1232.           case 'l': cmap_luma_sort  = opt_on; j++; break;
  1233.           case 'f': cmap_map_to_1st_flag = opt_on; j++; break;
  1234.           case 'm': cmap_true_map_flag = opt_on; j++; break;
  1235.           case 'n': j++;
  1236.             if (xa_allow_nice == xaTRUE) cmap_play_nice  = opt_on;
  1237.             break;
  1238.           case 'h': cmap_hist_flag  = opt_on; j++; break;
  1239.           default: exit_flag = xaTRUE;
  1240.         }
  1241.         }
  1242.       }
  1243.           break;
  1244.     case 'G': /* gamma options sub-menu */ 
  1245.       {
  1246.         xaULONG exit_flag = xaFALSE;
  1247.         j++;
  1248.         while( (exit_flag == xaFALSE) && (j<len) )
  1249.         {
  1250.         switch(in[j])
  1251.         {
  1252.           case 'a': /* set anim gamma */
  1253.             j++;
  1254.             xa_anim_gamma = XA_Read_Float(in,&j);
  1255.             if (xa_anim_gamma <= 0.0001) xa_anim_gamma = 0.0;
  1256.             xa_gamma_flag = CMAP_Gamma_Adjust(xa_gamma_adj,
  1257.                         xa_disp_gamma,xa_anim_gamma);
  1258.             break;
  1259.           case 'd': /* set display gamma */
  1260.             j++;
  1261.             xa_disp_gamma = XA_Read_Float(in,&j);
  1262.             if (xa_disp_gamma <= 0.0001) xa_disp_gamma = 0.0;
  1263.             xa_gamma_flag = CMAP_Gamma_Adjust(xa_gamma_adj,
  1264.                         xa_disp_gamma,xa_anim_gamma);
  1265.             break;
  1266.           default: exit_flag = xaTRUE;
  1267.         }
  1268.         }
  1269.       }
  1270.           break;
  1271.  
  1272.     case 'M': /* median cut options sub-menu */ 
  1273.       {
  1274.         xaULONG exit_flag = xaFALSE;
  1275.         j++;
  1276.         while( (exit_flag == xaFALSE) && (j<len) )
  1277.         {
  1278.         switch(in[j])
  1279.         {
  1280.           case 'a': cmap_median_type = CMAP_MEDIAN_SUM; j++; break;
  1281.           case 'c': cmap_median_type = CMAP_MEDIAN_CENTER; j++; break;
  1282.           /* POD Testing only */
  1283.           case 'e':
  1284.             j++; cmap_floyd_error = XA_Read_Int(in,&j);
  1285.             if (cmap_floyd_error <= 0) cmap_floyd_error = 0;
  1286.             break;
  1287.           case 'b':
  1288.             j++; cmap_median_bits = XA_Read_Int(in,&j);
  1289.             if (cmap_median_bits <= 5) cmap_median_bits = 5;
  1290.             if (cmap_median_bits >  8) cmap_median_bits = 8;
  1291.             break;
  1292.           /* POD benchmark only */
  1293.           case 'q': if (opt_on == xaTRUE) cmap_use_combsort = xaFALSE;
  1294.                 else cmap_use_combsort = xaTRUE;
  1295.                 j++; break;
  1296.           default: exit_flag = xaTRUE;
  1297.         }
  1298.         }
  1299.       }
  1300.           break;
  1301.         case 'B':
  1302.                 x11_shared_flag = opt_on;    j++;
  1303.                 break;
  1304.         case 'D':
  1305.                 x11_multibuf_flag = opt_on;    j++;
  1306.                 break;
  1307.         case 'b':
  1308.                 xa_buffer_flag = opt_on;    j++;
  1309.         if (xa_buffer_flag==xaTRUE) xa_file_flag = xaFALSE;
  1310.                 break;
  1311.         case 'c':
  1312.                 if (opt_on==xaTRUE) xa_anim_flags |= ANIM_NOLOOP;
  1313.                 else xa_anim_flags &= (~ANIM_NOLOOP);
  1314.                 j++; break;
  1315.         case 'd':
  1316.                 j++; xa_debug = XA_Read_Int(in,&j);
  1317.                 if (xa_debug <= 0) xa_debug = 0;
  1318.         break;
  1319.         case 'f':
  1320.                 xa_file_flag = opt_on;    j++;
  1321.         if (xa_file_flag==xaTRUE) xa_buffer_flag = xaFALSE;
  1322.         break;
  1323.         case 'F':
  1324.                 xa_dither_flag = opt_on;    j++;
  1325.         if (x11_display_type & XA_X11_TRUE) xa_dither_flag = xaFALSE;
  1326.         break;
  1327.         case 'h':
  1328.                 Usage(); break;
  1329.     case 'J':  /*PODNOTE: make into defines */
  1330.         j++; xa_speed_scale = XA_Read_Int(in,&j);
  1331.         if (xa_speed_scale == 0) xa_speed_scale = 1;
  1332.         if (xa_speed_scale > 16) xa_speed_scale = 16;
  1333.         if (opt_on == xaTRUE) xa_speed_scale <<= 4;
  1334.         else    xa_speed_scale = (1<<4) / xa_speed_scale;
  1335.         break;
  1336.         case 'j':
  1337.                 j++;
  1338.         if ( (in[j] >= '0') && (in[j] <= '9') )
  1339.         { xa_jiffy_flag = XA_Read_Int(in,&j);
  1340.                   if (xa_jiffy_flag <= 0) xa_jiffy_flag = 1;
  1341.         }
  1342.         else xa_jiffy_flag = 0; /* off */
  1343.                 break;
  1344.         case 'k':
  1345.         { xaULONG tmp;
  1346.                   j++;
  1347.           if ( (in[j] >= '0') && (in[j] <= '9') )
  1348.           { tmp = XA_Read_Int(in,&j);
  1349.                     if (tmp==1) xa_kludge1_fli = opt_on;
  1350.                     if (tmp==2) 
  1351.             {    xa_kludge2_dvi = opt_on;
  1352.             XA_AUDIO_SET_KLUDGE2(xa_kludge2_dvi);
  1353.             }
  1354.                     if (tmp >= 900) 
  1355.             {    xa_kludge900_aud = tmp;
  1356.             XA_AUDIO_SET_KLUDGE900(xa_kludge900_aud);
  1357.             }
  1358.           }
  1359.         }
  1360.                 break;
  1361.         case 'l':
  1362.         j++; 
  1363.         if (in[j] == 'p') { xa_pingpong_flag = opt_on; j++; }
  1364.         else xa_pingpong_flag = xaFALSE;
  1365.                 xa_loop_each_flag = XA_Read_Int(in,&j);
  1366.                 if (xa_loop_each_flag<=0) xa_loop_each_flag = 1;
  1367.         break;
  1368.         case 'N':
  1369.         xa_no_disp = opt_on;
  1370.                 xa_time_flag = opt_on;    j++;    break;
  1371.         case 'o':
  1372.                 xa_optimize_flag = opt_on; j++;    break;
  1373.         case 'p':
  1374.                 xa_pixmap_flag = opt_on; j++;
  1375.         if (opt_on==xaTRUE) xa_anim_flags |= ANIM_PIXMAP;
  1376.         else xa_anim_flags &= ~ANIM_PIXMAP;
  1377.                 break;
  1378.         case 'P':
  1379.                 j++; pod_max_colors = XA_Read_Int(in,&j);
  1380.                 if (pod_max_colors <= 0) pod_max_colors = 0;
  1381.         break;
  1382.         case 'r':
  1383.                 if (opt_on == xaTRUE)    xa_anim_flags |= ANIM_CYCLE;
  1384.                 else            xa_anim_flags &= (~ANIM_CYCLE);
  1385.                 j++;
  1386.                 break;
  1387.         case 'R':
  1388.                 xa_anim_cycling = opt_on; j++;    break;
  1389.         case 'S':
  1390.       {
  1391.         xaULONG exit_flag = xaFALSE;
  1392.         j++;
  1393.         while( (exit_flag==xaFALSE) && (j<len) )
  1394.         {
  1395.         switch(in[j])
  1396.         {
  1397.           case 'i': xa_allow_lace = opt_on;  j++; break;
  1398.           case 'n': xa_noresize_flag = opt_on;  j++; break;
  1399.           case 'r': xa_allow_resizing = opt_on; j++; break;
  1400.           case 'c': /* copy display scaling to buffer scaling */
  1401.             j++;
  1402.             xa_bscalex = xa_scalex; xa_bscaley = xa_scaley;
  1403.             xa_buff_x = xa_disp_x; xa_buff_y = xa_disp_y;
  1404.             break;
  1405.           case 's': /* scale anim display size */
  1406.             j++;
  1407.                     xa_scalex = XA_Read_Float(in,&j);
  1408.             if (xa_scalex == 0.0) xa_scalex = 1.0;
  1409.             xa_scaley = xa_scalex;
  1410.             xa_disp_x = xa_disp_y = 0; break;
  1411.           case 'x':  /* set anim display x size */
  1412.             j++; xa_scalex = 1.0;
  1413.                     xa_disp_x = XA_Read_Int(in,&j);
  1414.             break;
  1415.           case 'y':  /* set anim display y size */
  1416.             j++; xa_scaley = 1.0;
  1417.                     xa_disp_y = XA_Read_Int(in,&j);
  1418.             break;
  1419.           case 'h':  /* scale anim display horizontally */
  1420.             j++;
  1421.                     xa_scalex = XA_Read_Float(in,&j);
  1422.             if (xa_scalex == 0.0) xa_scalex = 1.0;
  1423.             xa_disp_x = 0; break;
  1424.           case 'v':  /* scale anim display vertically */
  1425.             j++;
  1426.                     xa_scaley = XA_Read_Float(in,&j);
  1427.             if (xa_scaley == 0.0) xa_scaley = 1.0;
  1428.             xa_disp_y = 0; break;
  1429.           case 'C': /* copy buffer scaling to display scaling */
  1430.             j++;
  1431.             xa_scalex = xa_bscalex; xa_scaley = xa_bscaley;
  1432.             xa_disp_x = xa_buff_x; xa_disp_y = xa_buff_y;
  1433.             break;
  1434.           case 'S': /* scale anim buffering size */
  1435.             j++;
  1436.                     xa_bscalex = XA_Read_Float(in,&j);
  1437.             if (xa_bscalex == 0.0) xa_bscalex = 1.0;
  1438.             xa_bscaley = xa_bscalex;
  1439.             xa_buff_x = xa_buff_y = 0; break;
  1440.           case 'X':  /* set anim buffering x size */
  1441.             j++; xa_bscalex = 1.0;
  1442.                     xa_buff_x = XA_Read_Int(in,&j);
  1443.             break;
  1444.           case 'Y':  /* set anim buffering y size */
  1445.             j++; xa_bscaley = 1.0;
  1446.                     xa_buff_y = XA_Read_Int(in,&j);
  1447.             break;
  1448.           case 'H':  /* scale anim buffering horizontally */
  1449.             j++;
  1450.                     xa_bscalex = XA_Read_Float(in,&j);
  1451.             if (xa_bscalex == 0.0) xa_bscalex = 1.0;
  1452.             xa_buff_x = 0; break;
  1453.           case 'V':  /* scale anim buffering vertically */
  1454.             j++;
  1455.                     xa_bscaley = XA_Read_Float(in,&j);
  1456.             if (xa_bscaley == 0.0) xa_bscaley = 1.0;
  1457.             xa_buff_y = 0; break;
  1458.           default: exit_flag = xaTRUE;
  1459.         }
  1460.         }
  1461.       }
  1462.       break;
  1463.         case 't':
  1464.                 xa_time_flag = opt_on;    j++;    break;
  1465.         case 'T':
  1466.                 j++; xa_title_flag = XA_Read_Int(in,&j);
  1467.                 if (xa_title_flag > 2) xa_title_flag = 2;
  1468.         break;
  1469.         case 'q':
  1470.                 xa_quiet = opt_on;    j++;    break;
  1471.         case 'v':
  1472.                 xa_verbose = opt_on;    j++;    break;
  1473.         case 'X':
  1474.         X11_Show_Visuals();    j++;    break;
  1475.         case 'V':
  1476.         j += len; break;   /* ignore reset and move on */
  1477. /* SMR 5 */
  1478.         case 'W':
  1479.           {
  1480.             xaULONG exit_flag = xaFALSE;
  1481.             j++;
  1482.             while( (exit_flag==xaFALSE) && (j<len) )
  1483.             {
  1484.                 switch(in[j])
  1485.                 {
  1486.                   case 'c':
  1487.                     j++;
  1488.                     xa_window_center_flag = xaTRUE;
  1489.                     break;
  1490.                   case 'd':
  1491.                     j++;
  1492.                     xa_window_refresh_flag = xaFALSE;
  1493.                     break;
  1494.                   case 'n':
  1495.                     j++;
  1496.                     xa_window_propname = &in[j];
  1497.                       j = len;
  1498.                     break;
  1499.                   case 'p':
  1500.                     j++;
  1501.                     xa_window_prepare_flag = xaTRUE;
  1502.                     break;
  1503.                   case 'r':
  1504.                     j++;
  1505.                     xa_noresize_flag = xaFALSE;
  1506.                     xa_allow_resizing = xaTRUE;
  1507.                     break;
  1508.                   case 'x':
  1509.                     j++;
  1510.                     xa_window_x = XA_Read_Int(in,&j);
  1511.                     break;
  1512.                   case 'y':
  1513.                     j++;
  1514.                     xa_window_y = XA_Read_Int(in,&j);
  1515.                     break;
  1516.                   default:
  1517.                     if ( (in[j] >= '0') && (in[j] <= '9') ) j = len;
  1518.                     else exit_flag = xaTRUE;
  1519.                 }
  1520.               }
  1521.           }
  1522.            break;
  1523. /* end SMR 5 */
  1524.         case 'Z':
  1525.       {
  1526.         xaULONG exit_flag = xaFALSE;
  1527.         j++;
  1528.         while( (exit_flag==xaFALSE) && (j<len) )
  1529.         { xaULONG tmp;
  1530.         switch(in[j])
  1531.         {
  1532.           case 'e': xa_exit_flag = opt_on;    j++;    break;
  1533.           case 'p':
  1534.             j++;
  1535.             if (in[j] == 'e') {xa_pause_last = opt_on; j++; }
  1536.             else { tmp = XA_Read_Int(in,&j); XA_Add_Pause(tmp); }
  1537.             break;
  1538.           case 'r': xa_remote_flag = opt_on;    j++;    break;
  1539.           case 'v': xa_exit_early_flag = opt_on; j++;    break;
  1540.           case 'z': /* POD TEST SWITCH FOR TRY DIFFERENT THINGS */
  1541.             j++; pod = XA_Read_Int(in,&j);
  1542.             break;
  1543.           default: exit_flag = xaTRUE;
  1544.         }
  1545.         }
  1546.       }
  1547.       break;
  1548.         case '-':
  1549.                 opt_on = (DEFAULT_PLUS_IS_ON==xaTRUE)?xaFALSE:xaTRUE; j++;    break;
  1550.         case '+':
  1551.                 opt_on = (DEFAULT_PLUS_IS_ON==xaTRUE)?xaTRUE:xaFALSE; j++;    break;
  1552.         default:
  1553.                 Usage_Quick();
  1554.        } /* end of option switch */
  1555.      } /* end of loop through options */
  1556.    } /* end of if - */
  1557.    else 
  1558.    /* If no hyphen in front of argument, assume it's a file.
  1559.     */
  1560.    { xaULONG result,audio_attempt;
  1561.      filename = argv[i];
  1562.  
  1563.      /* Visual Dependent switches and flags */
  1564.      if (x11_display_type & XA_X11_TRUE)
  1565.      {
  1566.        cmap_true_to_332  = cmap_true_to_gray = xaFALSE;
  1567.        cmap_true_to_1st  = cmap_true_to_all  = cmap_true_map_flag = xaFALSE;
  1568.      }
  1569.      else if (!(x11_display_type & XA_X11_COLOR))
  1570.      { cmap_true_to_gray = xaTRUE; cmap_true_to_332  = xaFALSE;
  1571.        cmap_true_to_1st  = cmap_true_to_all  = cmap_true_map_flag = xaFALSE;
  1572.      }
  1573.     
  1574.        /* disable audio if timing is forced */
  1575.        /* pass audio flag to routines */
  1576.      if ( (xa_vaudio_enable == xaTRUE) && (!xa_jiffy_flag) &&
  1577.          ((xa_vaudio_present==XA_AUDIO_UNK) || (xa_vaudio_present==XA_AUDIO_OK))
  1578.         ) audio_attempt = xaTRUE;
  1579.      else audio_attempt = xaFALSE;
  1580.  
  1581.      XA_AUDIO_SET_ENABLE(audio_attempt);
  1582.      XA_AUDIO_SET_FFLAG(xa_file_flag);
  1583.      XA_AUDIO_SET_BFLAG(vaudiof->bufferit);
  1584.  
  1585.  
  1586.      if ( (x11_display_type == XA_MONOCHROME) || (xa_pack_flag == xaTRUE) )
  1587.        xa_use_depth_flag = xaFALSE;
  1588.      else
  1589.        xa_use_depth_flag = xaTRUE;
  1590.      cur_file = Get_Anim_Hdr(cur_file,filename);
  1591.     /* POD why the voids? */
  1592.      (void)XA_Alloc_Input_Methods(cur_file);
  1593.      (void)XA_Setup_Input_Methods(cur_file->xin,cur_file->name);
  1594.  
  1595.      xa_anim_type = XA_Open_And_ID_File(cur_file);
  1596.      cur_file->anim_type = xa_anim_type;
  1597.      cur_file->anim_flags = xa_anim_flags;
  1598.      if (x11_display_type == XA_MONOCHROME) xa_optimize_flag = xaFALSE;
  1599.      switch(xa_anim_type)
  1600.      {
  1601.         case QT_ANIM:    /* potentially multiple files */
  1602.     case JFIF_ANIM: /* cnvrt'd but not sequential */
  1603.     case MPG_ANIM:  /* cnvrt'd but not sequential */
  1604.         case ARM_ANIM:  /* cnvrt'd but not sequential */
  1605.         case SGI_ANIM:    /* cnvrt'd but not sequential */
  1606.         case TXT_ANIM:    /* used fscanf */
  1607.         case JMOV_ANIM:    /* cnvrt'd but not sequential */
  1608.         case AU_ANIM:
  1609.     /* New Style that does NOT support Sequential */
  1610.       if (xa_buffer_flag)     cur_file->xin->load_flag = XA_IN_LOAD_BUF;
  1611.       else if (xa_file_flag) cur_file->xin->load_flag = XA_IN_LOAD_FILE;
  1612.       else             cur_file->xin->load_flag = XA_IN_LOAD_MEM;
  1613.  
  1614. /* POD FIX: this random stuff should be automatically done in Open_And_ID */
  1615.       if (cur_file->xin->type_flag & XA_IN_TYPE_RANDOM)
  1616.        { cur_file->xin->Seek_FPos(cur_file->xin,0,0);
  1617.         cur_file->xin->buf_cnt = 0;
  1618.         cur_file->xin->fpos = 0;
  1619.         if (xa_verbose) fprintf(stdout,"Reading %s File %s\n",
  1620.                         cur_file->desc, filename);
  1621.         result = cur_file->Read_File(filename,cur_file,audio_attempt);
  1622.       }
  1623.       else
  1624.       { fprintf(stdout,
  1625.         "%s Files not yet supported for Sequential input\n",
  1626.                             cur_file->desc);
  1627.         result = xaFALSE;
  1628.       }
  1629.       break;
  1630.  
  1631.     /* New Style that supports Sequential */
  1632.         case SET_ANIM:    /* potentially multiple files */
  1633.         case RLE_ANIM:
  1634.         case IFF_ANIM:
  1635.         case DL_ANIM:
  1636.         case GIF_ANIM:
  1637.         case FLI_ANIM:
  1638.         case AVI_ANIM:
  1639.         case WAV_ANIM:
  1640.       if (xa_buffer_flag)     cur_file->xin->load_flag = XA_IN_LOAD_BUF;
  1641.       else if (xa_file_flag) cur_file->xin->load_flag = XA_IN_LOAD_FILE;
  1642.       else             cur_file->xin->load_flag = XA_IN_LOAD_MEM;
  1643.       if (cur_file->xin->type_flag & XA_IN_TYPE_RANDOM)
  1644.        { cur_file->xin->Seek_FPos(cur_file->xin,0,0);
  1645.         cur_file->xin->buf_cnt = 0;
  1646.         cur_file->xin->fpos = 0;
  1647.       }
  1648.       else  
  1649.           { if (xa_file_flag)
  1650.         { fprintf(stdout,
  1651.         "You can't use \"+f\" option with sequential streams(stdin,ftp,etc).\n");
  1652.           result = xaFALSE;
  1653.           break;
  1654.         }
  1655.       }
  1656.       if (xa_verbose) fprintf(stdout,"Reading %s File %s\n",
  1657.                         cur_file->desc, filename);
  1658.       result = cur_file->Read_File(filename,cur_file,audio_attempt);
  1659.       break;
  1660.  
  1661.         case PFX_ANIM:
  1662.       fprintf(stdout,"%s not currently supported\n",cur_file->desc);
  1663.       result = xaFALSE;
  1664.       break;
  1665.         case NOFILE_ANIM:
  1666.       fprintf(stdout,"Unable to open/read animation: %s\n",filename);
  1667.       result = xaFALSE;
  1668.       break;
  1669.         default:
  1670.       fprintf(stdout,"Unknown or unsupported animation type: %s\n",
  1671.                                 filename);
  1672.       result = xaFALSE;
  1673.       break;
  1674.       } 
  1675.     /* not supported OR no video or audio */
  1676.       if (result == xaFALSE) 
  1677.       {
  1678.     XA_AUDIO_UNFILE(cur_file->file_num);
  1679.     cur_file = Return_Anim_Hdr(cur_file);
  1680.       }
  1681.       else if (cur_file->frame_lst == 0)  /* No Video but with audio */
  1682.       { 
  1683.     /* If no previous file, add dummy video and move on */
  1684.     if (   (cur_file->prev_file == 0)
  1685.         || (cur_file->prev_file == cur_file)
  1686.            )
  1687.         { DUM_Read_File(filename,cur_file);
  1688.           goto XA_MERGE_NOGO;
  1689.         }
  1690.  
  1691.     /* only add if previous file has no audio unless overridden
  1692.       * by vaudio_merge flags */
  1693.     { int f_ret;
  1694.           XA_AUDIO_N_FILE(cur_file->prev_file->file_num,f_ret);
  1695.           if (   (xa_forkit==xaTRUE) && (f_ret == xaTRUE)
  1696.           && (xa_vaudio_merge == xaFALSE)
  1697.           && (xa_vaudio_merge_scale == xaFALSE)
  1698.         )
  1699.           { DUM_Read_File(filename,cur_file); 
  1700.         goto XA_MERGE_NOGO;
  1701.       }
  1702.     }
  1703.     /* Now we're free to merge audio */
  1704.  
  1705.     /* Set current file name to previous file name for Audio only */
  1706.     /* NOTE: this'll set AudioChild's cur_audio_hdr to prev_file */
  1707.     if (cur_file->fname)
  1708.     { xaULONG length = strlen( cur_file->fname ) + 1;
  1709.       XA_AUDIO_FNAME(cur_file->fname, length, 
  1710.                     cur_file->prev_file->file_num);
  1711.     }
  1712.     XA_AUDIO_MERGEFILE(cur_file->file_num);
  1713.     if (xa_vaudio_merge_scale==xaTRUE)
  1714.        XA_Adjust_Video_Timing(cur_file->prev_file,cur_file->total_time);
  1715.     /* these are one shot options */
  1716.     xa_vaudio_merge_scale = xa_vaudio_merge = xaFALSE;
  1717.     cur_file = Return_Anim_Hdr(cur_file);
  1718.     
  1719. /* what's this here for??? */
  1720.     if (cur_file->max_faud_size > xa_audcodec_maxsize)
  1721.             xa_audcodec_maxsize = cur_file->max_faud_size;
  1722.       }
  1723.       else
  1724.       { xaULONG tmpx,tmpy;
  1725.  
  1726. XA_MERGE_NOGO:
  1727.  
  1728.         /* Setup up anim header.  */
  1729.         cur_file->loop_num = xa_loop_each_flag;
  1730.  
  1731.         if (xa_pause_last == xaTRUE)
  1732.         { if ( (xa_anim_type == FLI_ANIM) && (cur_file->last_frame > 1))
  1733.                     XA_Add_Pause(cur_file->last_frame-2);
  1734.           else XA_Add_Pause(cur_file->last_frame);
  1735.           xa_pause_last = xaFALSE;
  1736.         }
  1737.     cur_file->pause_lst = xa_pause_hdr;
  1738.     xa_pause_hdr = 0;
  1739.  
  1740.     xa_imagex = cur_file->imagex;
  1741.     xa_imagey = cur_file->imagey;
  1742.     if (xa_imagex > xa_max_imagex) xa_max_imagex = xa_imagex;
  1743.     if (xa_imagey > xa_max_imagey) xa_max_imagey = xa_imagey;
  1744.  
  1745.     if (cur_file->max_fvid_size > xa_vidcodec_maxsize)
  1746.             xa_vidcodec_maxsize = cur_file->max_fvid_size;
  1747.     if ((cur_file->fname) && (xa_file_flag == xaTRUE))
  1748.     { xaULONG length = strlen( cur_file->fname ) + 1;
  1749.       XA_AUDIO_FNAME( (cur_file->fname), length, (cur_file->file_num) );
  1750.     }
  1751.     XA_AUDIO_SET_AUD_BUFF( (cur_file->max_faud_size) );
  1752.     if (cur_file->max_faud_size > xa_audcodec_maxsize)
  1753.             xa_audcodec_maxsize = cur_file->max_faud_size;
  1754.  
  1755.     /* Handle Buffer Scaling Here */
  1756.     if ( (xa_buff_x != 0) && (xa_buff_y != 0) )
  1757.         {tmpx = xa_buff_x; tmpy = xa_buff_y;}
  1758.     else if (xa_buff_x != 0) /* if just x, then adjust y */
  1759.         {tmpx = xa_buff_x; tmpy = (xa_imagey * xa_buff_x) / xa_imagex;}
  1760.     else if (xa_buff_y != 0) /* if just y, then adjust x */
  1761.         {tmpy = xa_buff_y; tmpx = (xa_imagex * xa_buff_y) / xa_imagey;}
  1762.     else
  1763.     {
  1764.         /* handle any scaling */
  1765.       tmpx = (xaULONG)((float)(xa_imagex) * xa_bscalex);
  1766.       if (tmpx == 0) tmpx = xa_imagex;
  1767.       tmpy = (xaULONG)((float)(xa_imagey) * xa_bscaley);
  1768.       if (tmpy == 0) tmpy = xa_imagey;
  1769.     }
  1770.     cur_file->buffx = tmpx;
  1771.     cur_file->buffy = tmpy;
  1772.  
  1773.         /* Handle Display Scaling Here */
  1774.     if ( (xa_disp_x != 0) && (xa_disp_y != 0) ) 
  1775.         {tmpx = xa_disp_x; tmpy = xa_disp_y;}
  1776.     else if (xa_disp_x != 0) /* if just x, then adjust y */
  1777.         {tmpx = xa_disp_x; tmpy = (xa_imagey * xa_disp_x) / xa_imagex;}
  1778.     else if (xa_disp_y != 0) /* if just y, then adjust x */
  1779.         {tmpy = xa_disp_y; tmpx = (xa_imagex * xa_disp_y) / xa_imagey;}
  1780.     else
  1781.     {
  1782.         /* handle any scaling */
  1783.       tmpx = (xaULONG)((float)(xa_imagex) * xa_scalex);
  1784.       if (tmpx == 0) tmpx = xa_imagex;
  1785.       tmpy = (xaULONG)((float)(xa_imagey) * xa_scaley);
  1786.       if (tmpy == 0) tmpy = xa_imagey;
  1787.     }
  1788.     /* handle any IFF laced images */
  1789.     if ( (xa_allow_lace==xaTRUE) && (cur_file->anim_flags & ANIM_LACE))
  1790.         tmpy >>= 1;
  1791.     else    cur_file->anim_flags &= ~ANIM_LACE;
  1792.     cur_file->dispx = tmpx;
  1793.     cur_file->dispy = tmpy;
  1794.     if (tmpx > xa_max_disp_x) xa_max_disp_x = tmpx;
  1795.     if (tmpy > xa_max_disp_y) xa_max_disp_y = tmpy;
  1796.  
  1797.     if ((cmap_dither_type == CMAP_DITHER_FLOYD) && (xa_buffer_flag==xaFALSE))
  1798.             cur_file->anim_flags |= ANIM_3RD_BUF;
  1799.     xa_merged_anim_flags |= cur_file->anim_flags;
  1800.  
  1801.     /* NOTE: removed fade, remember to readd eventually */
  1802.  
  1803.     if (xa_time_flag == xaTRUE)
  1804.     {
  1805.       xaLONG time_int;
  1806.       xa_time_end = XA_Time_Read();
  1807.       time_int = xa_time_end - xa_time_start;
  1808.       fprintf(stdout,"time = %d\n",time_int);
  1809.       xa_time_start = XA_Time_Read();
  1810.     }
  1811.       } /* valid animation file */
  1812.     } /* end of read in file */
  1813.  } /* end of loopin through arguments */
  1814.  
  1815.  /* No anims listed
  1816.   */
  1817.  if (first_file == 0) Usage_Quick();
  1818.  
  1819.  if (xa_exit_early_flag == xaTRUE) TheEnd();
  1820.  
  1821.  /* If No Audio then Kill Audio Child
  1822.   */
  1823.   if (   (xa_vaudio_present==XA_AUDIO_NONE) 
  1824.       || (xa_vaudio_present==XA_AUDIO_ERR) ) XA_AUDIO_EXIT();
  1825.  
  1826.  /* Set up X11 Display
  1827.   */
  1828.  
  1829.  if (xa_noresize_flag==xaTRUE) X11_Setup_Window(xa_max_disp_x,xa_max_disp_y,
  1830.         xa_max_disp_x,xa_max_disp_y);
  1831.  else X11_Setup_Window(xa_max_disp_x,xa_max_disp_y,
  1832.         first_file->dispx, first_file->dispy);
  1833.  if (x11_display_type == XA_MONOCHROME) xa_optimize_flag = xaFALSE;
  1834.  
  1835.  /* color map manipulation */
  1836.  CMAP_Manipulate_CHDRS();
  1837.  
  1838.  /* Kludge for some X11 displays */
  1839.  if (x11_kludge_1 == xaTRUE) CMAP_Expand_Maps();
  1840.  
  1841.  xa_time_start = XA_Time_Read();
  1842.  cur_file = first_file;
  1843.  while(cur_file)
  1844.  {
  1845.    ACT_Make_Images(cur_file->acts);
  1846.    cur_file = cur_file->next_file;
  1847.    if (cur_file == first_file) cur_file = 0;
  1848.  }
  1849.  if (xa_time_flag == xaTRUE)
  1850.  {
  1851.    xaLONG time_int;
  1852.    xa_time_end = XA_Time_Read();
  1853.    time_int = xa_time_end - xa_time_start;
  1854.    fprintf(stdout,"ACT_Make_Images: time = %d\n",time_int);
  1855.    xa_time_start = XA_Time_Read();
  1856.  }
  1857.  
  1858.  /* Set Audio Ports */
  1859. #ifdef XA_AUDIO
  1860.   if (xa_vaudio_present == XA_AUDIO_OK)
  1861.   {
  1862. #ifdef XA_SPARC_AUDIO
  1863.     if (vaudiof->port) XA_SET_OUTPUT_PORT(vaudiof->port);
  1864. #else
  1865.     if (vaudiof->port & XA_AUDIO_PORT_INT) XA_SPEAKER_TOG(1)
  1866.     else XA_SPEAKER_TOG(0)
  1867.     /*** POD NOTE: HEADPHONES AND LINEOUT MUST BE DIFFERENT */
  1868.     if (vaudiof->port & XA_AUDIO_PORT_HEAD) XA_HEADPHONE_TOG(1)
  1869.     else XA_HEADPHONE_TOG(0)
  1870.     if (vaudiof->port & XA_AUDIO_PORT_EXT) XA_LINEOUT_TOG(1)
  1871.     else XA_LINEOUT_TOG(0)
  1872. #endif
  1873.   }
  1874. #endif
  1875.  
  1876.  /* Start off Animation.
  1877.   */
  1878.   XA_Lets_Get_Looped();
  1879.  /* Map window and then Wait for user input.
  1880.   */
  1881.   X11_Map_Window();
  1882. #ifdef XA_REMOTE_CONTROL
  1883.   XA_Create_Remote(theWG,xa_remote_flag);
  1884. #else
  1885.   xa_remote_ready = xaTRUE;
  1886. #endif
  1887.   xanim_events();
  1888.  
  1889.   XSync(theDisp,False);
  1890.  
  1891.  
  1892.  /* Self-Explanatory
  1893.   */
  1894.   TheEnd();
  1895.   return(0);
  1896. }
  1897.  
  1898.  
  1899. /*
  1900.  * XA_Lets_Get_Looped allocates and sets up required image buffers and
  1901.  * initializes animation variables.
  1902.  * It then kicks off the animation. Hey, the snow is melting today!
  1903.  */
  1904. void XA_Lets_Get_Looped()
  1905. { /* POD TEMPORARY PARTIAL KLUDGE UNTIL REAL FIX IS IMPLEMENTED */
  1906.   if (xa_max_imagex & 0x03) shm = 0;
  1907.  
  1908.   xa_max_image_size = xa_max_imagex * xa_max_imagey;
  1909.   xa_max_disp_size = xa_max_disp_x * xa_max_disp_y;
  1910.  
  1911.  
  1912.   if (   (xa_merged_anim_flags & ANIM_SNG_BUF)
  1913.       || (xa_merged_anim_flags & ANIM_DBL_BUF)
  1914.      )
  1915.   { 
  1916. #ifdef XSHM
  1917.     if (XA_Setup_Them_Buffers(&im0_Image,&im0_shminfo,&im_buff0)==xaFALSE)
  1918. #else
  1919.     if (XA_Setup_Them_Buffers(&im_buff0)==xaFALSE)
  1920. #endif
  1921.                 TheEnd1("Them_Buffers: im_buff0 malloc err");
  1922.   }
  1923.   if (xa_merged_anim_flags & ANIM_DBL_BUF)
  1924.   {
  1925. #ifdef XSHM
  1926.     if (XA_Setup_Them_Buffers(&im1_Image,&im1_shminfo,&im_buff1)==xaFALSE)
  1927. #else
  1928.     if (XA_Setup_Them_Buffers(&im_buff1)==xaFALSE)
  1929. #endif
  1930.                 TheEnd1("Them_Buffers: im_buff1 malloc err");
  1931.   }
  1932.   if (xa_merged_anim_flags & ANIM_3RD_BUF)
  1933.   {
  1934. #ifdef XSHM
  1935.     if (XA_Setup_Them_Buffers(&im2_Image,&im2_shminfo,&im_buff2)==xaFALSE)
  1936. #else
  1937.     if (XA_Setup_Them_Buffers(&im_buff2)==xaFALSE)
  1938. #endif
  1939.                 TheEnd1("Them_Buffers: im_buff2 malloc err");
  1940.   }
  1941.  
  1942.   if (x11_pack_flag == xaTRUE)
  1943.   {
  1944.     xaULONG tsize;
  1945.     xaULONG pbb = (8 / x11_bits_per_pixel);
  1946.     tsize = (xa_max_imagex + pbb - 1) / pbb;
  1947.     im_buff3 = (char *) malloc(xa_max_disp_y * tsize);
  1948.     if (im_buff3 == 0) TheEnd1("XAnim_Start_Loop: im_buff3 malloc err1");
  1949.   }
  1950.   xa_pic = im_buff0;
  1951.   cur_file = first_file;
  1952.   cur_floop = 0;
  1953.   cur_frame = -1;  /* since we step first */
  1954.   xa_audio_start = 0;
  1955.   xa_time_reset = 1;
  1956.   file_is_started = xaFALSE;
  1957.   xa_cycle_cnt = 0;
  1958.   xa_now_cycling = xaFALSE;
  1959.  
  1960.   xa_anim_ready = xaTRUE; /* allow expose event to start animation */
  1961. }
  1962.  
  1963. /*
  1964.  * This is the heart of this program. It does each action and then calls
  1965.  * itself with a timeout via the XtAppAddTimeOut call.
  1966.  */
  1967. void XAnim_Looped(dptr,id)
  1968. XtPointer dptr;
  1969. XtIntervalId *id;
  1970. { xaULONG command = (xaULONG)dptr;
  1971.   xaLONG t_time_delta = 0;
  1972.   xaLONG snd_speed_now_ok = xaFALSE;
  1973.  
  1974. XAnim_Looped_Sneak_Entry:
  1975.  
  1976.  DEBUG_LEVEL2 fprintf(stdout,"SHOWACTION\n");
  1977.  
  1978.  if (command == XA_SHOW_NORM)
  1979.  {
  1980.   switch (xa_anim_status)
  1981.   {
  1982.     case XA_BEGINNING:  
  1983.     if ((xa_anim_ready == xaFALSE) || (xa_remote_ready == xaFALSE))
  1984.     { /* try again 10ms later */
  1985.       XtAppAddTimeOut(theContext,10, (XtTimerCallbackProc)XAnim_Looped,
  1986.                         (XtPointer)(XA_SHOW_NORM));
  1987.       return;
  1988.     }
  1989.     xa_anim_status = XA_RUN_NEXT; /* drop through */
  1990.     case XA_STEP_NEXT: 
  1991.     case XA_RUN_NEXT:   
  1992.     Step_Action_Next();
  1993.     break;
  1994.     case XA_STEP_PREV:
  1995.     case XA_RUN_PREV:   
  1996.     Step_Action_Prev();
  1997.     if (xa_old_status == XA_RUN_NEXT)
  1998.     {
  1999. #ifdef XA_AUDIO
  2000.       XA_AUDIO_OFF(0);    xa_audio_start = 0;
  2001. #endif
  2002.     }
  2003.     break;
  2004.     case XA_ISTP_NEXT: 
  2005. #ifdef XA_AUDIO
  2006.     XA_AUDIO_OFF(0);    xa_audio_start = 0;
  2007. #endif
  2008.     Step_Frame_Next();
  2009.     break;
  2010.     case XA_ISTP_PREV: 
  2011. #ifdef XA_AUDIO
  2012.     XA_AUDIO_OFF(0);    xa_audio_start = 0;
  2013. #endif
  2014.     Step_Frame_Prev();
  2015.     break;
  2016.     case XA_FILE_NEXT:
  2017. #ifdef XA_AUDIO
  2018.     XA_AUDIO_OFF(0);    xa_audio_start = 0;
  2019. #endif
  2020.     Step_File_Next();
  2021.     xa_anim_status = XA_STEP_NEXT;
  2022.     break;
  2023.     case XA_FILE_PREV:
  2024. #ifdef XA_AUDIO
  2025.     XA_AUDIO_OFF(0);    xa_audio_start = 0;
  2026. #endif
  2027.     Step_File_Prev();
  2028.     xa_anim_status = XA_STEP_PREV;
  2029.     break;
  2030.     case XA_UNSTARTED:  
  2031.     case XA_STOP_NEXT:  
  2032.     case XA_STOP_PREV:  
  2033. #ifdef XA_AUDIO
  2034.     XA_AUDIO_OFF(0);    xa_audio_start = 0;
  2035. #endif
  2036.     if (xa_title_flag != XA_TITLE_NONE)
  2037.             XA_Store_Title(cur_file,cur_frame,XA_TITLE_FRAME);
  2038.     xa_anim_holdoff = xaFALSE;
  2039.     xa_old_status = xa_anim_status;
  2040.     return;
  2041.     break;
  2042.     default:
  2043. #ifdef XA_AUDIO
  2044.     XA_AUDIO_OFF(0);    xa_audio_start = 0;
  2045. #endif
  2046.     xa_anim_holdoff = xaFALSE;
  2047.     xa_old_status = xa_anim_status;
  2048.     return;
  2049.     break;
  2050.   } /* end of case */
  2051.  } /* end of command SHOW_NORM */
  2052.  
  2053.   DEBUG_LEVEL1 fprintf(stdout,"frame = %d\n",cur_frame);
  2054.  
  2055.  /* 1st throught this particular file.
  2056.   * Resize if necessary and init required variables.
  2057.   */
  2058.   if (file_is_started == xaFALSE)
  2059.   {
  2060. #ifdef XA_AUDIO
  2061.  
  2062.     XA_AUDIO_GET_STATUS( xa_vaudio_status );
  2063.     if (xa_vaudio_status == XA_AUDIO_STARTED)
  2064.     { XtAppAddTimeOut(theContext, 50, (XtTimerCallbackProc)XA_Audio_Wait,
  2065.                             (XtPointer)(NULL) );
  2066.       return;
  2067.     }
  2068. #endif
  2069.      /* If previous anim is still cycling, wait for it to stop */
  2070.     if (xa_now_cycling == xaTRUE)
  2071.     { /*PODNOTE: This check might want to be before above switch */
  2072.       xa_anim_flags &= ~(ANIM_CYCLE);
  2073.       XtAppAddTimeOut(theContext, 50, (XtTimerCallbackProc)XA_Cycle_Wait,
  2074.                             (XtPointer)(NULL) );
  2075.       return; 
  2076.     }
  2077.  
  2078.     file_is_started = xaTRUE;
  2079.     xa_anim_flags = cur_file->anim_flags;
  2080.     if (xa_anim_flags & ANIM_PIXMAP) xa_pixmap_flag = xaTRUE;
  2081.     else xa_pixmap_flag = xaFALSE;
  2082.  
  2083.     /* Resize Window if Needed */
  2084.     if (     (xa_allow_resizing == xaFALSE)
  2085.          || ( (xa_allow_resizing == xaTRUE) && (x11_window_x==0)))
  2086.           XA_Resize_Window(cur_file,xa_noresize_flag,xa_disp_x,xa_disp_y);
  2087.  
  2088.     /* Change Title of Window */
  2089.     XA_Store_Title(cur_file,cur_frame,xa_title_flag);
  2090.  
  2091.  
  2092.     /* Initialize variables
  2093.      */
  2094. #ifdef XSHM
  2095.     if (xa_anim_flags & ANIM_SNG_BUF) sh_Image = im0_Image;
  2096. #endif
  2097.     if (xa_anim_flags & ANIM_SNG_BUF) xa_pic = im_buff0; 
  2098.     xa_imagex = cur_file->imagex;
  2099.     xa_imagey = cur_file->imagey;
  2100.     xa_disp_x = cur_file->dispx;
  2101.     xa_disp_y = cur_file->dispy;
  2102.     xa_buff_x = cur_file->buffx;
  2103.     xa_buff_y = cur_file->buffy;
  2104.     xa_imaged = cur_file->imaged;
  2105.     xa_cmap_size = cur_file->imagec;
  2106.     xa_image_size = xa_imagex * xa_imagey;
  2107.     X11_Init_Image_Struct(theImage,xa_disp_x,xa_disp_y);
  2108.     if (xa_anim_flags & ANIM_USE_FILE)
  2109.     { /* Close old video file and open new one */
  2110.       if (xa_vid_fd>=0) { close(xa_vid_fd); xa_vid_fd = -1; }
  2111.       if ( (xa_vid_fd=open(cur_file->fname,O_RDONLY,NULL)) < 0)
  2112.       { 
  2113.         fprintf(stdout,"Open file %s for video err\n",cur_file->fname); 
  2114.         TheEnd();
  2115.       }
  2116.       /* Allocate video buffer if not done already */
  2117.       if ((cur_file->max_fvid_size) && (xa_vidcodec_buf==0))
  2118.       {
  2119.     xa_vidcodec_buf = (xaUBYTE *)malloc( xa_vidcodec_maxsize );
  2120.     if (xa_vidcodec_buf==0) TheEnd1("XAnim: malloc vidcodec_buf err");
  2121.       }
  2122.     }
  2123.  
  2124.     xa_pause_hdr = cur_file->pause_lst;
  2125.     xa_skip_cnt = xa_skip_video = xa_skip_diff = 0;
  2126.     /*** Call any Initializing routines needed by Audio/Video Codecs */
  2127.     if (cur_file->init_vid) cur_file->init_vid();
  2128.     /* is this still needed ?? */
  2129.     xa_time_start = XA_Time_Read();
  2130.  
  2131.     /* Is Audio Valid for this animations */
  2132. /* FORK NOTE: */
  2133.    { int f_ret = xaFALSE;
  2134.  
  2135.      XA_AUDIO_PLAY_FILE(cur_file->file_num,f_ret);
  2136.      if ( (xa_forkit==xaTRUE) && (f_ret == xaTRUE) )
  2137.      { xa_has_audio = xaTRUE;
  2138.        xa_vaudio_enable = xaTRUE;
  2139.        xa_vaudio_status = XA_AUDIO_STOPPED;
  2140.        XA_AUDIO_INIT_SND;
  2141.        xa_time_audio = 0;
  2142.      }
  2143.      else
  2144.      { xa_has_audio = xaFALSE;
  2145.        xa_time_audio = -1;
  2146.        xa_vaudio_enable = xaFALSE;
  2147.        xa_vaudio_status = XA_AUDIO_NICHTDA;
  2148.      }
  2149.    }
  2150.     xa_ptime_video = xa_time_video = 0;
  2151.     xa_av_time_off = XA_Time_Read();  /* for initial control frames if any */
  2152.  
  2153.     xa_old_status = XA_STOP_NEXT;
  2154.   } /* end of file is not started */
  2155.  
  2156.  
  2157.  /* OK. A quick sanity check and then we
  2158.   * initialize act and inc frame time and go to it.
  2159.   */
  2160.  if ( (act = cur_file->frame_lst[cur_frame].act) != 0)
  2161.  { xaULONG passed_go_flag = xaFALSE;
  2162.  
  2163.        /*** Time Adjustments */
  2164.     if (cur_file->frame_lst[cur_frame].zztime >= 0)
  2165.     xa_time_video = cur_file->frame_lst[cur_frame].zztime;
  2166.  
  2167.     if (!(xa_anim_status & XA_NEXT_MASK)) /* backwards */
  2168.     {
  2169.       xa_time_video += cur_file->frame_lst[cur_frame].time_dur;
  2170.       xa_time_video = cur_file->total_time - xa_time_video;
  2171.       if (xa_ptime_video > xa_time_video) passed_go_flag = xaTRUE;
  2172.     }
  2173.     else if (xa_ptime_video > xa_time_video) passed_go_flag = xaTRUE; 
  2174.     xa_ptime_video = xa_time_video;
  2175.  
  2176.     /* Adjust Timing if there's been a change in the speed scale */
  2177.     if (xa_speed_change) 
  2178.     {
  2179.       xa_speed_change = 0;
  2180.       XA_Reset_Speed_Time(xa_time_video,xa_speed_scale);
  2181. #ifdef XA_AUDIO
  2182.       if (xa_speed_scale == XA_SPEED_NORM) snd_speed_now_ok = xaTRUE;
  2183.       else
  2184.       {  snd_speed_now_ok = xaFALSE;
  2185.          if (xa_vaudio_status == XA_AUDIO_STARTED) 
  2186.             { XA_AUDIO_OFF(1); xa_audio_start = 0; }
  2187.       }
  2188. #endif
  2189.     }
  2190.  
  2191. #ifdef XA_AUDIO
  2192.     if (passed_go_flag == xaTRUE) XA_AUDIO_GET_STATUS( xa_vaudio_status );
  2193.     if (xa_vaudio_status == XA_AUDIO_STARTED) 
  2194.     {
  2195.       if (passed_go_flag == xaTRUE)  /* Hitting 1st frame */
  2196.       { /* wait til audio is finished */
  2197.         XtAppAddTimeOut(theContext, 50, (XtTimerCallbackProc)XA_Audio_Wait,
  2198.                             (XtPointer)(NULL) );
  2199.         return;
  2200.       }
  2201.       else if (    (xa_anim_status != XA_RUN_NEXT)
  2202.         || (xa_speed_scale != XA_SPEED_NORM)  ) 
  2203.                 { XA_AUDIO_OFF(0); xa_audio_start = 0; }
  2204.     }
  2205.     else if (xa_vaudio_status == XA_AUDIO_STOPPED)
  2206.     {
  2207.       if   (    (xa_anim_status == XA_RUN_NEXT) 
  2208.         &&  (xa_speed_scale == XA_SPEED_NORM)
  2209.             &&  ( (xa_old_status != XA_RUN_NEXT) || (snd_speed_now_ok==xaTRUE))
  2210.        ) 
  2211.       {
  2212.  
  2213.     xa_audio_start = 1;
  2214.     xa_time_reset = 1;
  2215.       }
  2216.       else if (   (   (xa_old_status != XA_RUN_PREV)
  2217.                    && (xa_anim_status == XA_RUN_PREV))
  2218.         || (passed_go_flag == xaTRUE)  )
  2219.       {
  2220.     xa_time_reset = 1;
  2221.         xa_time_audio = -1;
  2222.       }
  2223.     }
  2224.     else  /* DROP THROUGH CASE WHERE NO AUDIO IS PRESENT */
  2225. #endif
  2226.     /**** Readjust Timing if Run is New */
  2227.     if (   ((xa_old_status != XA_RUN_PREV)&&(xa_anim_status==XA_RUN_PREV))
  2228.         || ((xa_old_status != XA_RUN_NEXT)&&(xa_anim_status==XA_RUN_NEXT))
  2229.         || (passed_go_flag == xaTRUE) )
  2230.     { 
  2231.        xa_time_reset = 1;
  2232.        xa_time_audio = -1;
  2233.     }
  2234.  
  2235.      /* Don't skip unless we are running */
  2236.     if (xa_anim_status != XA_RUN_NEXT)
  2237.         xa_skip_cnt = xa_skip_video = xa_skip_diff = 0;
  2238.     
  2239.     if ( (xa_allow_resizing == xaTRUE) && (x11_window_x != 0) )
  2240.         { xa_disp_x = x11_window_x; xa_disp_y = x11_window_y; }
  2241.  
  2242.     if ((xa_disp_x != xa_buff_x) || (xa_disp_y != xa_buff_y))
  2243.      xa_need_to_scale_b = 1;
  2244.     else xa_need_to_scale_b = 0;
  2245.     if ((xa_disp_x != xa_imagex) || (xa_disp_y != xa_imagey))
  2246.      xa_need_to_scale_u = 1;
  2247.     else xa_need_to_scale_u = 0;
  2248.  
  2249.  
  2250.     XA_Show_Action( act );
  2251.  
  2252.  } /* end of action valid */
  2253.  else
  2254.  {
  2255.    fprintf(stdout,"PODNOTE: CONTROL FRAME MADE IT THROUGH\n");
  2256.  }
  2257.  
  2258.  /* Reset time if needed */
  2259.  if (xa_time_reset)
  2260.  { XA_Reset_AV_Time(xa_time_video,xa_speed_scale);
  2261.    xa_time_reset = 0;
  2262.  }
  2263.  
  2264.  /* Start Audio is needed */
  2265.  if (xa_audio_start)
  2266.  { int f_ret = xaFALSE;
  2267.    XA_AUDIO_N_FILE(cur_file->file_num,f_ret);
  2268.    if (xa_forkit==xaFALSE)
  2269.    { xa_vaudio_status = XA_AUDIO_NICHTDA;
  2270.      xa_has_audio = xaFALSE;
  2271.    }
  2272.    else if (xa_forkit==xaTRUE)
  2273.    {
  2274.      if (f_ret == xaTRUE)
  2275.      { XA_AUDIO_RST_TIME(xa_time_video);
  2276.        xa_has_audio = xaTRUE;
  2277.        xa_time_audio = 0;
  2278. #ifdef XA_REMOTE_CONTROL
  2279.        XA_Remote_Adj_Volume(vaudiof->volume,XA_AUDIO_MAXVOL);
  2280. #endif
  2281.        XA_AUDIO_ON();
  2282.        xa_audio_start = 0;
  2283.      }
  2284.      else xa_has_audio = xaFALSE;
  2285.    }
  2286.  }
  2287.  
  2288.   if (xa_pause_hdr)
  2289.   { if ( (cur_frame==xa_pause_hdr->frame) && (xa_anim_status & XA_RUN_MASK))
  2290.     { xa_pause_hdr = xa_pause_hdr->next;
  2291.       XA_AUDIO_OFF(0); xa_audio_start = 0;
  2292. #ifdef XA_REMOTE_CONTROL
  2293.       XA_Remote_Pause();
  2294. #endif
  2295.       goto XA_PAUSE_ENTRY_POINT; /* reuse single step code */
  2296.     }
  2297.   }
  2298.  
  2299.  if (xa_anim_status & XA_STEP_MASK) /* Single step if in that mode */
  2300.  {
  2301.    XA_PAUSE_ENTRY_POINT:
  2302.    if ( (xa_no_disp == xaFALSE) & (xa_title_flag != XA_TITLE_NONE) )
  2303.             XA_Store_Title(cur_file,cur_frame,XA_TITLE_FRAME);
  2304.    xa_anim_status &= XA_CLEAR_MASK; /* preserve direction and stop */
  2305.    xa_anim_status |= XA_STOP_MASK;
  2306.    xa_anim_holdoff = xaFALSE;
  2307.    xa_old_status = xa_anim_status;
  2308.    return;
  2309.  }
  2310.  
  2311.  if ( (xa_no_disp == xaFALSE) & (xa_title_flag == XA_TITLE_FRAME) )
  2312.             XA_Store_Title(cur_file,cur_frame,XA_TITLE_FRAME);
  2313.  
  2314.   /* Harry, what time is it? and how much left? default to 1 ms */
  2315.  xa_time_video += cur_file->frame_lst[cur_frame].time_dur;
  2316.  xa_time_video = XA_SPEED_ADJ(xa_time_video,xa_speed_scale);
  2317.  xa_time_now = XA_Read_AV_Time();
  2318.  
  2319. #ifdef XA_AUDIO
  2320.  if ((xa_time_audio >= 0) && (xa_has_audio == xaTRUE))
  2321.  { 
  2322.    DEBUG_LEVEL1 fprintf(stdout,"cav %d %d %d d: %d %d\n",
  2323.     xa_time_now,xa_time_audio,xa_time_video,
  2324.     cur_file->frame_lst[cur_frame].zztime,
  2325.     cur_file->frame_lst[cur_frame].time_dur);
  2326. #ifdef NEVERNEVER
  2327.    if (xa_time_video > xa_time_audio) /* this is bad, but for now we kludge*/
  2328.    {
  2329.      t_time_delta = xa_time_video - xa_time_audio;
  2330.    }
  2331.    else 
  2332. #endif
  2333.    if (xa_time_video > xa_time_now) /* video ahead, slow down video */
  2334.    { 
  2335.      t_time_delta = xa_time_video - xa_time_now;
  2336.      xa_skip_video = 0;
  2337.    }
  2338.    else    
  2339.    { xaLONG diff = xa_time_now - xa_time_video;
  2340.      xaLONG f_time = cur_file->frame_lst[cur_frame].time_dur;
  2341.      if (diff > f_time)
  2342.      { /* potentially skip video at this point */
  2343.     if ((f_time > 0) && (xa_skip_flag==xaTRUE))
  2344.     { xaULONG cnt = diff / f_time;  /* frame behind */
  2345.           if ((xa_skip_diff) && (cnt)) /* if skip & skipped last time */
  2346.       {  if (cnt < 2) xa_skip_video = 0;
  2347.          else if (cnt < 3) xa_skip_video = 1;
  2348.          else xa_skip_video = 2;
  2349.       }
  2350.       else xa_skip_video = 0;  /* last wasn't skip, don't skip this */
  2351.       xa_skip_diff = cnt;
  2352.     }
  2353.     else xa_skip_video = 0;
  2354. DEBUG_LEVEL1 fprintf(stdout,"vid behind dif %d skp %d\n",diff,xa_skip_video);
  2355.      }
  2356.      else xa_skip_video = 0;
  2357.      t_time_delta = 1;      /* audio ahead  speed up video */
  2358.    }
  2359.  }
  2360.  else
  2361. #endif
  2362.  {
  2363.    xa_skip_video = 0;
  2364.    DEBUG_LEVEL1 fprintf(stdout,"cv %d %d  d: %d %d scal %x\n",
  2365.     xa_time_now,xa_time_video,cur_file->frame_lst[cur_frame].zztime,
  2366.     cur_file->frame_lst[cur_frame].time_dur,xa_speed_scale);
  2367.    if (xa_time_video > xa_time_now)
  2368.         t_time_delta = xa_time_video - xa_time_now;
  2369.    else        t_time_delta = 1;
  2370.  }
  2371.  
  2372.  DEBUG_LEVEL1 fprintf(stdout,"t_time_delta %d\n",t_time_delta);
  2373.  if ( !(xa_anim_status & XA_STOP_MASK) )
  2374.  {
  2375. /*
  2376.    if (   (t_time_delta < 10) 
  2377.        && (looped < XA_ALLOWABLE_LOOPS)) 
  2378.         { looped++; goto XAnim_Looped_Sneak_Entry; }
  2379. */
  2380. /* if time is short and no events take a short cut */
  2381. /* 10 is chosen because on most systems 10ms is the time slice */
  2382.    if (   (t_time_delta < 10) 
  2383.        && (!XtAppPending(theContext)) ) goto XAnim_Looped_Sneak_Entry;
  2384.  
  2385.    else XtAppAddTimeOut(theContext,t_time_delta,
  2386.         (XtTimerCallbackProc)XAnim_Looped,(XtPointer)(XA_SHOW_NORM));
  2387.  }
  2388.  else xa_anim_holdoff = xaFALSE;
  2389.  xa_old_status = xa_anim_status;
  2390. }
  2391.  
  2392. /*
  2393.  *
  2394.  */
  2395. void Step_Action_Next()
  2396. {
  2397.   XA_FRAME *frame;
  2398.  
  2399.   cur_frame++; frame = &cur_file->frame_lst[cur_frame];
  2400.   do
  2401.   { xaULONG jmp2end_flag = 0;
  2402.     if ( (frame->zztime == -1) && (frame->act != 0) ) /* check for loops */
  2403.     {
  2404.       XA_ACTION *lp_act = frame->act;
  2405.       if (lp_act->type == ACT_BEG_LP)
  2406.       {
  2407.         ACT_BEG_LP_HDR *beg_lp = (ACT_BEG_LP_HDR *)lp_act->data;
  2408.         beg_lp->cnt_var = beg_lp->count;
  2409.         cur_frame++; /* move on */
  2410.       }
  2411.       else if (lp_act->type == ACT_END_LP)
  2412.       {
  2413.         ACT_END_LP_HDR *end_lp = (ACT_END_LP_HDR *)lp_act->data;
  2414.         *end_lp->cnt_var = *end_lp->cnt_var - 1;
  2415.         if (*end_lp->cnt_var > 0) cur_frame = end_lp->begin_frame;
  2416.         else cur_frame++;
  2417.       }
  2418.       else if (lp_act->type == ACT_JMP2END)
  2419.       { 
  2420.     if (xa_pingpong_flag==xaFALSE)
  2421.     {
  2422.       if ( (cur_floop+1) >= cur_file->loop_num) /* done with this file */
  2423.       {
  2424.              if (first_file->next_file != first_file) /* more to go */
  2425.          {
  2426.            cur_frame = cur_file->last_frame + 1; /* jmp to end */
  2427.          }
  2428.          else if (xa_exit_flag == xaTRUE) TheEnd(); /* we're outta here */
  2429.          else cur_frame++;  /* step to beg */
  2430.           }  else cur_frame++; /* step to beg */
  2431.         } else jmp2end_flag = 1;
  2432.       }
  2433.       frame = &cur_file->frame_lst[cur_frame];
  2434.     }
  2435.  
  2436.     if ( (frame->act == 0) /* Are we at the end of an anim? */
  2437.         || (jmp2end_flag) )
  2438.     {
  2439.       if (xa_pingpong_flag == xaTRUE)
  2440.       { jmp2end_flag = 0;
  2441.         xa_anim_status &= ~(XA_NEXT_MASK);  /* change dir to prev */
  2442.         cur_frame--; 
  2443.         Step_Action_Prev();
  2444.         return;
  2445.       }
  2446.       cur_frame = cur_file->loop_frame;
  2447.  
  2448.       cur_floop++;
  2449.       DEBUG_LEVEL1 fprintf(stdout,"  loop = %d\n",cur_floop);
  2450.  
  2451.       /* Done looping animation. Move on to next file if present */
  2452.       if (   (cur_floop >= cur_file->loop_num)
  2453.       || (xa_anim_status & XA_STEP_MASK)   ) /* or if single stepping */
  2454.       {
  2455.         cur_floop = 0;             /* Reset Loop Count */
  2456.  
  2457.     /* Are we on the last file and do we need to exit? */
  2458.     if (   (cur_file->next_file == first_file)
  2459.         && (xa_exit_flag == xaTRUE) )   TheEnd(); /* later */
  2460.  
  2461.         /* This is a special case check.
  2462.          * If more that one file, reset file_is_started, otherwise
  2463.          * if we're only displaying 1 animation jump to the loop_frame
  2464.          * which has already been set up above.
  2465.      * If cur_file has audio then we always restart.
  2466.          */
  2467.         if (   (first_file->next_file != first_file)
  2468.             || (xa_has_audio==xaTRUE) )
  2469.         {
  2470.           file_is_started = xaFALSE;
  2471.           cur_file = cur_file->next_file;
  2472.           cur_frame = 0;
  2473.         }
  2474.         DEBUG_LEVEL1 fprintf(stdout,"  file = %d\n",cur_file->file_num);
  2475.         if (xa_time_flag == xaTRUE) XA_Time_Check();
  2476.       } /* end done looping file */
  2477.     } /* end done with frames in file */
  2478.     frame = &cur_file->frame_lst[cur_frame];
  2479.   } while( (frame->zztime == -1) || (frame->act == 0) );
  2480. }
  2481.  
  2482. /*
  2483.  *
  2484.  */
  2485. void Step_Action_Prev()
  2486. {
  2487.   XA_FRAME *frame;
  2488.   cur_frame--; if (cur_frame < 0) goto XA_Step_Action_Prev_0;
  2489.   frame = &cur_file->frame_lst[cur_frame];
  2490.  
  2491.   do
  2492.   {
  2493.     if ( (frame->zztime == -1) && (frame->act != 0) ) /* check for loops */
  2494.     {
  2495.       XA_ACTION *lp_act = frame->act;
  2496.       if (lp_act->type == ACT_BEG_LP)
  2497.       {
  2498.         ACT_BEG_LP_HDR *beg_lp = (ACT_BEG_LP_HDR *)lp_act->data;
  2499.         beg_lp->cnt_var++;
  2500.         if (beg_lp->cnt_var < beg_lp->count) cur_frame = beg_lp->end_frame;
  2501.         else cur_frame--;
  2502.       }
  2503.       else if (lp_act->type == ACT_END_LP)
  2504.       {
  2505.         ACT_END_LP_HDR *end_lp = (ACT_END_LP_HDR *)lp_act->data;
  2506.         *end_lp->cnt_var = 0;
  2507.         cur_frame--;
  2508.       }
  2509.       else if (lp_act->type == ACT_JMP2END)
  2510.       { /* not valid in this direction so just skip over it */
  2511.         cur_frame--;
  2512.       }
  2513.       if (cur_frame < 0) goto XA_Step_Action_Prev_0;
  2514.       frame = &cur_file->frame_lst[cur_frame];
  2515.     }
  2516.  
  2517.     /* Are we at the beginning of an anim? */
  2518.     if (cur_frame < 0)        goto XA_Step_Action_Prev_0;
  2519.     if (frame->act == 0)    goto XA_Step_Action_Prev_0;
  2520.     if ((cur_frame < cur_file->loop_frame) && (xa_pingpong_flag == xaFALSE))
  2521.     {
  2522.       XA_Step_Action_Prev_0:  /* skip indexing with -1 */
  2523.  
  2524.       if (xa_pingpong_flag == xaTRUE)
  2525.       {
  2526.         xa_anim_status |= XA_NEXT_MASK;  /* change dir to forward */
  2527.         cur_floop++;
  2528.  
  2529.     /* Are we on the last file and do we need to exit? */
  2530.     if (   (cur_file->next_file == first_file)
  2531.         && (xa_exit_flag == xaTRUE) )   TheEnd(); /* later */
  2532.  
  2533.          /* do we move to next file? */
  2534.         if (  (first_file->next_file != first_file)  /* more than 1 file */
  2535.         && (   (cur_floop >= cur_file->loop_num)
  2536.                 || (xa_anim_status & XA_STEP_MASK)  ) )
  2537.         {
  2538.           cur_floop = 0;
  2539.           file_is_started = xaFALSE;
  2540.           cur_file = cur_file->next_file;
  2541.           cur_frame = 0;
  2542.           break;
  2543.         }
  2544.  
  2545.         if (cur_floop >= cur_file->loop_num) 
  2546.         {
  2547.           cur_floop = 0;
  2548.           if (xa_time_flag == xaTRUE) XA_Time_Check();
  2549.         }
  2550.         cur_frame++;
  2551.         Step_Action_Next();
  2552.         return;
  2553.       } /* end of pingpong stuff */
  2554.  
  2555.       cur_frame = cur_file->last_frame;
  2556.       cur_floop--;
  2557.       DEBUG_LEVEL1 fprintf(stdout,"  loop = %d\n",cur_floop);
  2558.        /* Done looping animation. Move on to next file if present */
  2559.       if (   (cur_floop <= 0)
  2560.       || (xa_anim_status & XA_STEP_MASK) ) /* or if single stepping */
  2561.       {
  2562.         cur_floop = cur_file->loop_num; /* Reset Loop Count */
  2563.  
  2564.         /* If more that one file, go to next file */
  2565.         if (first_file->next_file != first_file )
  2566.         {
  2567.           file_is_started = xaFALSE;
  2568.           cur_file = cur_file->prev_file;
  2569.           cur_frame = cur_file->last_frame;
  2570.           cur_floop = cur_file->loop_num; /* Reset Loop Count */
  2571.         }
  2572.  
  2573.         if (xa_time_flag == xaTRUE) XA_Time_Check();
  2574.         DEBUG_LEVEL1 fprintf(stdout,"  file = %d\n",cur_file->file_num);
  2575.       } /* end done looping file */
  2576.     } /* end done with frames in file */
  2577.     frame = &cur_file->frame_lst[cur_frame];
  2578.   } while( (frame->zztime == -1) || (frame->act == 0) );
  2579. }
  2580.  
  2581.  
  2582. /*
  2583.  *
  2584.  */
  2585. void Step_Frame_Next()
  2586. {
  2587.   cur_frame++;
  2588.   do
  2589.   {
  2590.       /* skip over loops */
  2591.     if (   (cur_file->frame_lst[cur_frame].zztime == -1)
  2592.         && (cur_file->frame_lst[cur_frame].act != 0) ) cur_frame++;
  2593.  
  2594.       /* Are we at the end of an anim? */
  2595.     if (cur_file->frame_lst[cur_frame].act == 0)
  2596.     {
  2597.       cur_frame = cur_file->loop_frame;
  2598.     }
  2599.   } while(   (cur_file->frame_lst[cur_frame].zztime == -1)
  2600.           || (cur_file->frame_lst[cur_frame].act == 0)  );
  2601. }
  2602.  
  2603. /*
  2604.  *
  2605.  */
  2606. void Step_Frame_Prev()
  2607. {
  2608.   cur_frame--;
  2609.  
  2610.   do
  2611.   {
  2612.       /* skip over loops */
  2613.     if (cur_frame < 0) goto XA_Step_Frame_Prev_0;
  2614.     if (   (cur_file->frame_lst[cur_frame].zztime == -1)
  2615.         && (cur_file->frame_lst[cur_frame].act != 0) ) cur_frame--;
  2616.  
  2617.     /* Are we at the beginning of an anim? */
  2618.     if (cur_frame < 0) goto XA_Step_Frame_Prev_0;
  2619.     if (   (cur_file->frame_lst[cur_frame].act == 0)
  2620.         || (cur_frame < cur_file->loop_frame)        )
  2621.     {
  2622.       XA_Step_Frame_Prev_0: /* prevent indexing with -1 */
  2623.       cur_frame = cur_file->last_frame;
  2624.     }
  2625.   } while(   (cur_file->frame_lst[cur_frame].zztime == -1)
  2626.           || (cur_file->frame_lst[cur_frame].act == 0)  );
  2627. }
  2628.  
  2629. /*
  2630.  *
  2631.  */
  2632. void Step_File_Next()
  2633. {
  2634.   file_is_started = xaFALSE;
  2635.   cur_frame = 0;
  2636.   cur_file = cur_file->next_file;
  2637.   cur_floop = 0; /* used if things start up again */
  2638.  
  2639.   DEBUG_LEVEL1 fprintf(stdout,"  file = %d\n",cur_file->file_num);
  2640. }
  2641.  
  2642. /*
  2643.  *
  2644.  */
  2645. void Step_File_Prev()
  2646. {
  2647.   file_is_started = xaFALSE;
  2648.   cur_frame = 0;
  2649.   cur_file = cur_file->prev_file;
  2650.   cur_floop = 0; /* used if things start up again */
  2651.  
  2652.   DEBUG_LEVEL1 fprintf(stdout,"  file = %d\n",cur_file->file_num);
  2653. }
  2654.  
  2655.  
  2656. /*********** XA_Cycle_Wait *********************************************
  2657.  * This function waits until all the color cycling processes have halted.
  2658.  * Then it fires up XAnim_Looped with the XA_SHOW_SKIP command to cause
  2659.  * XAnim_Looped to skip the frame movement.
  2660.  ***********************************************************************/
  2661. void XA_Cycle_Wait(nothing, id)
  2662. char *nothing;
  2663. XtIntervalId *id;
  2664. {
  2665.  
  2666.   if (xa_cycle_cnt) /* wait until cycles are done */
  2667.   {
  2668.     XtAppAddTimeOut(theContext, 50, (XtTimerCallbackProc)XA_Cycle_Wait,
  2669.                             (XtPointer)(NULL));
  2670.     return;
  2671.   }
  2672.   else /* then move on */
  2673.   {
  2674.     xa_now_cycling = xaFALSE;
  2675.     XtAppAddTimeOut(theContext, 1, (XtTimerCallbackProc)XAnim_Looped, 
  2676.                         (XtPointer)(XA_SHOW_SKIP));
  2677.   }
  2678. }
  2679.  
  2680. /*********** XA_Audio_Wait *********************************************
  2681.  * This function waits until the audio from the previous animation is
  2682.  * finished before starting up the next animation.
  2683.  * Then it fires up XAnim_Looped with the XA_SHOW_SKIP command to cause
  2684.  * XAnim_Looped to skip the frame movement.
  2685.  ***********************************************************************/
  2686. void XA_Audio_Wait(nothing, id)
  2687. char *nothing;
  2688. XtIntervalId *id;
  2689. { DEBUG_LEVEL1 fprintf(stdout,"XA_Audio_Wait\n");
  2690.   XA_AUDIO_GET_STATUS( xa_vaudio_status );
  2691.   if (xa_vaudio_status == XA_AUDIO_STARTED) /* continue waiting */
  2692.   { if (xa_anim_status & XA_RUN_MASK)
  2693.     { XtAppAddTimeOut(theContext, 50, (XtTimerCallbackProc)XA_Audio_Wait,
  2694.                             (XtPointer)(NULL));
  2695.       return;
  2696.     }
  2697.     XA_AUDIO_OFF(0);        xa_audio_start = 0;
  2698.   }
  2699.   XtAppAddTimeOut(theContext, 1, (XtTimerCallbackProc)XAnim_Looped, 
  2700.                         (XtPointer)(XA_SHOW_SKIP));
  2701. }
  2702.  
  2703. /*
  2704.  *
  2705.  */
  2706. void XA_Cycle_It(act_cycle, id)
  2707. ACT_CYCLE_HDR   *act_cycle;
  2708. XtIntervalId *id;
  2709. {
  2710.   xaULONG i,*i_ptr,size,curpos;
  2711.  
  2712.   if (xa_anim_flags & ANIM_CYCLE) XtAppAddTimeOut(theContext,
  2713.         (int)(act_cycle->rate),(XtTimerCallbackProc)XA_Cycle_It,
  2714.                             (XtPointer)(act_cycle));
  2715.   else
  2716.   {
  2717.     xa_cycle_cnt--;
  2718.     act_cycle->flags &= ~ACT_CYCLE_STARTED;
  2719.     return;
  2720.   }
  2721.  
  2722.   size = act_cycle->size;
  2723.   curpos = act_cycle->curpos;
  2724.  
  2725.   /* increment or decrement curpos */
  2726.   if (act_cycle->flags & ACT_CYCLE_REVERSE) 
  2727.       curpos = (curpos)?(curpos - 1):(size - 1); 
  2728.   else
  2729.       curpos = (curpos >= (size - 1))?(0):(curpos + 1); 
  2730.   act_cycle->curpos = curpos;
  2731.  
  2732.   i_ptr = (xaULONG *)act_cycle->data;
  2733.   for(i=0;i<size;i++)
  2734.   {
  2735.     xaULONG j;
  2736.  
  2737.     j = i_ptr[i] - xa_cmap_off;
  2738.     defs[i].pixel = i_ptr[curpos];
  2739.     defs[i].flags = DoRed | DoGreen | DoBlue;
  2740.     if (x11_display_type & XA_X11_GRAY)
  2741.     {
  2742.       defs[i].red = defs[i].green = defs[i].blue = xa_cmap[j].gray;
  2743.     }
  2744.     else
  2745.     {
  2746.       defs[i].red   = xa_cmap[j].red;
  2747.       defs[i].green = xa_cmap[j].green;
  2748.       defs[i].blue  = xa_cmap[j].blue;
  2749.     }
  2750.     if (act_cycle->flags & ACT_CYCLE_REVERSE) 
  2751.       curpos = (curpos)?(curpos - 1):(size - 1); 
  2752.     else
  2753.       curpos = (curpos >= (size - 1))?(0):(curpos + 1); 
  2754.   }
  2755.   XStoreColors(theDisp,theCmap,defs,act_cycle->size);
  2756.   if (xa_vaudio_enable != xaTRUE) XSync(theDisp,False);
  2757. }
  2758.  
  2759. /*
  2760.  *
  2761.  */
  2762. void Free_Actions(acts)
  2763. XA_ACTION *acts;
  2764. {
  2765.   XA_ACTION *act;
  2766.   act = acts;
  2767.   while(act != 0)
  2768.   { XA_ACTION *tmp = act;
  2769.     act = act->next;
  2770.     ACT_Free_Act(tmp);
  2771.     FREE(tmp,0x01);
  2772.   }
  2773. }
  2774.  
  2775. /***************************************
  2776.  *
  2777.  **************/
  2778. XA_ANIM_HDR *Return_Anim_Hdr(file_hdr)
  2779. XA_ANIM_HDR *file_hdr;
  2780. {
  2781.   XA_ANIM_HDR *tmp_hdr;
  2782.   if ((file_hdr==0) || (first_file==0)) TheEnd1("Return_Anim_Hdr err");
  2783.   xa_file_num--;
  2784.   if (first_file == file_hdr)
  2785.   {
  2786.     first_file = 0;
  2787.     tmp_hdr = 0;
  2788.   }
  2789.   else /* removed file_hdr from the loop */
  2790.   {
  2791.     tmp_hdr = file_hdr->prev_file;
  2792.     tmp_hdr->next_file = file_hdr->next_file;
  2793.     file_hdr->next_file->prev_file = tmp_hdr;
  2794.   }
  2795.   if (file_hdr->name) free(file_hdr->name);  /* POD ADD */
  2796.  
  2797.   FREE(file_hdr,0x02);
  2798.   return(tmp_hdr);
  2799. }
  2800.  
  2801. /***************************************
  2802.  *
  2803.  **************/
  2804. XA_ANIM_HDR *Get_Anim_Hdr(file_hdr,file_name)
  2805. XA_ANIM_HDR *file_hdr;
  2806. char *file_name;
  2807. {
  2808.   XA_ANIM_HDR *temp_hdr;
  2809.   xaLONG length;
  2810.  
  2811.   temp_hdr = (XA_ANIM_HDR *)malloc( sizeof(XA_ANIM_HDR) );
  2812.   if (temp_hdr == 0) TheEnd1("Get_Anim_Hdr: malloc failed\n");
  2813.  
  2814.   if (first_file == 0) first_file = temp_hdr;
  2815.   if (file_hdr == 0)
  2816.   {
  2817.     xa_file_num = 0;
  2818.     temp_hdr->next_file = temp_hdr;
  2819.     temp_hdr->prev_file = temp_hdr;
  2820.   }
  2821.   else
  2822.   {
  2823.     temp_hdr->prev_file = file_hdr;
  2824.     temp_hdr->next_file = file_hdr->next_file;
  2825.     file_hdr->next_file = temp_hdr;
  2826.     first_file->prev_file = temp_hdr;
  2827.   }
  2828.  
  2829.   temp_hdr->anim_type = 0;
  2830.   temp_hdr->imagex = 0;
  2831.   temp_hdr->imagey = 0;
  2832.   temp_hdr->imagec = 0;
  2833.   temp_hdr->imaged = 0;
  2834.   temp_hdr->anim_flags    = 0;
  2835.   temp_hdr->loop_num    = 0;
  2836.   temp_hdr->loop_frame    = 0;
  2837.   temp_hdr->last_frame    = 0;
  2838.   temp_hdr->total_time    = 0;
  2839.   temp_hdr->frame_lst    = 0;
  2840.   temp_hdr->acts    = 0;
  2841.   temp_hdr->first_snd    = 0;
  2842.   temp_hdr->last_snd    = 0;
  2843.   temp_hdr->file_num    = xa_file_num;
  2844.   temp_hdr->fname    = 0;
  2845.   temp_hdr->max_fvid_size    = 0;
  2846.   temp_hdr->max_faud_size    = 0;
  2847.   temp_hdr->init_vid    = 0;
  2848.   temp_hdr->init_aud    = 0;
  2849.   temp_hdr->free_chain    = 0;
  2850.   temp_hdr->xin        = 0;
  2851.  
  2852.   length = strlen(file_name) + 1;
  2853.   temp_hdr->name = (char *)malloc(length);
  2854.   strcpy(temp_hdr->name,file_name);
  2855.   XA_AUDIO_FILE(xa_file_num);
  2856.   xa_file_num++;
  2857.   return(temp_hdr);
  2858. }
  2859.   
  2860.  
  2861. void XA_Install_CMAP(chdr)
  2862. XA_CHDR *chdr;
  2863. { ColorReg *tcmap;
  2864.   xaLONG j;
  2865.  
  2866.   tcmap        = chdr->cmap;
  2867.   xa_cmap_size    = chdr->csize;
  2868.   if (xa_cmap_size > x11_cmap_size) xa_cmap_size = x11_cmap_size;
  2869.   xa_cmap_off    = chdr->coff;
  2870.   xa_map    = chdr->map;
  2871.   xa_map_size    = chdr->msize;
  2872.   xa_map_off    = chdr->moff;
  2873.   for(j=0; j<xa_cmap_size;j++)
  2874.   {
  2875.     xa_cmap[j].red   = tcmap[j].red;
  2876.     xa_cmap[j].green = tcmap[j].green;
  2877.     xa_cmap[j].blue  = tcmap[j].blue;
  2878.     xa_cmap[j].gray  = tcmap[j].gray;
  2879.   }
  2880.  
  2881.   DEBUG_LEVEL1 fprintf(stdout,"  Install CMAP %x old was %x\n",
  2882.                     (xaULONG)chdr,(xaULONG)xa_chdr_now);
  2883.  
  2884.   if ( x11_cmap_flag == xaFALSE )
  2885.   {
  2886.     DEBUG_LEVEL1 fprintf(stdout,"  Fake Install since cmap not writable\n");
  2887.     xa_chdr_now = chdr;
  2888.     return;
  2889.   }
  2890.   else /* install the cmap */
  2891.   {
  2892.     DEBUG_LEVEL2 fprintf(stdout,"CMAP: size=%d off=%d\n",
  2893.         xa_cmap_size,xa_cmap_off);
  2894.     if (xa_cmap_size > x11_cmap_size)
  2895.     {
  2896.       fprintf(stdout,"Install CMAP: Error csize(%d) > x11 cmap(%d)\n",
  2897.         xa_cmap_size,x11_cmap_size);
  2898.       return;
  2899.     }
  2900.     if (x11_display_type & XA_X11_GRAY)
  2901.     {
  2902.       for(j=0;j<xa_cmap_size;j++)
  2903.       {
  2904.         defs[j].pixel = xa_cmap_off + j;
  2905.         defs[j].red   = xa_cmap[j].gray;
  2906.         defs[j].green = xa_cmap[j].gray;
  2907.         defs[j].blue  = xa_cmap[j].gray;
  2908.         defs[j].flags = DoRed | DoGreen | DoBlue;
  2909.         DEBUG_LEVEL3 fprintf(stdout," g %d) %x %x %x <%x>\n",
  2910.              j,xa_cmap[j].red,xa_cmap[j].green,xa_cmap[j].blue,xa_cmap[j].gray);
  2911.         
  2912.       }
  2913.     }
  2914.     else
  2915.     {
  2916.       for(j=0; j<xa_cmap_size;j++)
  2917.       {
  2918.         defs[j].pixel = xa_cmap_off + j;
  2919.         defs[j].red   = xa_cmap[j].red;
  2920.         defs[j].green = xa_cmap[j].green;
  2921.         defs[j].blue  = xa_cmap[j].blue;
  2922.         defs[j].flags = DoRed | DoGreen | DoBlue;
  2923.         DEBUG_LEVEL3 fprintf(stdout," %d) %x %x %x <%x>\n",
  2924.              j,xa_cmap[j].red,xa_cmap[j].green,xa_cmap[j].blue,xa_cmap[j].gray);
  2925.         
  2926.       }
  2927.     }
  2928.     if (x11_cmap_installed)
  2929.     { x11_cmap_installed = xaTRUE;
  2930. #ifndef NO_INSTALL_CMAP
  2931.       XInstallColormap(theDisp,theCmap);
  2932. #endif
  2933.     }
  2934.     XStoreColors(theDisp,theCmap,defs,xa_cmap_size);
  2935.     xa_chdr_now = chdr;
  2936. #ifdef XA_PETUNIA
  2937.     XA_Remote_ColorUpdate(chdr);
  2938. #endif
  2939.   }
  2940. }
  2941.  
  2942.  
  2943. /********************************
  2944.  * Initialize the global variable xa_time_off.
  2945.  *
  2946.  ***************/
  2947. xaLONG XA_Time_Init()
  2948. {
  2949.   gettimeofday(&tv, 0);
  2950.   xa_time_off = tv.tv_sec;
  2951.   return( xa_time_off );
  2952. }
  2953.  
  2954. /********************************
  2955.  * return time from start in milliseconds
  2956.  ***************/
  2957. xaLONG XA_Time_Read()
  2958. {
  2959.   xaLONG t;
  2960.   gettimeofday(&tv, 0);
  2961.   t = (tv.tv_sec - xa_time_off) * 1000 + (tv.tv_usec / 1000);
  2962.   return(t);
  2963. }
  2964.  
  2965.  
  2966. /*
  2967.  *
  2968.  */
  2969. void XA_Time_Check()
  2970. {
  2971.   xaLONG time_int;
  2972.  
  2973.   xa_time_end = XA_Time_Read();
  2974.   time_int = xa_time_end - xa_time_start;
  2975.   xa_time_av = (xa_time_av * xa_time_num) + time_int;
  2976.   xa_time_num++;
  2977.   xa_time_av /= xa_time_num;
  2978.   fprintf(stdout,"l_time = %d  av %d  skipd %d Sskipd %d\n",
  2979.         time_int,xa_time_av,xa_frames_skipd,xa_frames_Sskipd);
  2980.   xa_frames_skipd = xa_frames_Sskipd = 0;
  2981.   xa_time_start = XA_Time_Read();
  2982.  
  2983. }
  2984.  
  2985. xaULONG XA_Read_Int(s,j)
  2986. xaUBYTE *s;
  2987. xaULONG *j;
  2988. {
  2989.   xaULONG i,num;
  2990.   i = *j; num = 0;
  2991.   while( (s[i] >= '0') && (s[i] <= '9') )
  2992.     { num *= 10; num += (xaULONG)(s[i]) - (xaULONG)('0'); i++; }
  2993.   *j = i;   
  2994.   return(num);
  2995. }
  2996.  
  2997. float XA_Read_Float(s,j)
  2998. xaUBYTE *s;
  2999. xaULONG *j;
  3000. {
  3001.   xaULONG i;
  3002.   float num;
  3003.   i = *j; num = 0.0;
  3004.   while( (s[i] >= '0') && (s[i] <= '9') )
  3005.     { num *= 10; num += (float)(s[i]) - (float)('0'); i++; }
  3006.   if (s[i] == '.')
  3007.   {
  3008.     float pos = 10.0;
  3009.     i++; 
  3010.     while( (s[i] >= '0') && (s[i] <= '9') )
  3011.     { 
  3012.       num += ((float)(s[i]) - (float)('0')) / pos;
  3013.       pos *= 10.0; i++;
  3014.     }
  3015.   }
  3016.   *j = i;   
  3017.   return(num);
  3018. }
  3019.  
  3020. xaLONG XA_Get_Class(p)
  3021. char *p;
  3022. {
  3023.   xaULONG i,len;
  3024.   char tmp[16];
  3025.   
  3026.   /* copy and convert to lower case */
  3027.   len = strlen(p); if (len > 16) return( -1 );
  3028.   for(i=0; i < len; i++) tmp[i] = (char)tolower( (int)(p[i]) );
  3029.   tmp[i] = 0;
  3030.   if      (strcmp(tmp,"staticgray\0" ) == 0)    return( StaticGray );
  3031.   else if (strcmp(tmp,"grayscale\0"  ) == 0)    return( GrayScale );
  3032.   else if (strcmp(tmp,"staticcolor\0") == 0)    return( StaticColor );
  3033.   else if (strcmp(tmp,"pseudocolor\0") == 0)    return( PseudoColor );
  3034.   else if (strcmp(tmp,"truecolor\0"  ) == 0)    return( TrueColor );
  3035.   else if (strcmp(tmp,"directcolor\0") == 0)    return( DirectColor );
  3036.   else return( -1 );
  3037. }
  3038.  
  3039. /**********************
  3040.  * Add frame to current pause list
  3041.  */
  3042. void XA_Add_Pause(frame)
  3043. xaULONG frame;        /* frame at which to pause */
  3044. { XA_PAUSE *new_phdr;
  3045.  
  3046.   new_phdr = (XA_PAUSE *)malloc(sizeof(XA_PAUSE));
  3047.   if (new_phdr==0) TheEnd1("XA_Add_Pause: malloc err\n");
  3048.   new_phdr->frame = frame;
  3049.   new_phdr->next = 0;
  3050.   if (xa_pause_hdr==0) xa_pause_hdr = new_phdr;
  3051.   else
  3052.   { XA_PAUSE *t_phdr = xa_pause_hdr;
  3053.     while(t_phdr->next != 0) t_phdr = t_phdr->next;
  3054.     t_phdr->next = new_phdr;
  3055.   }
  3056. }
  3057.  
  3058. /***************************************************************************
  3059.  *  Function to return Time since Start of Animation.
  3060.  */ 
  3061. xaLONG XA_Read_AV_Time()
  3062. {
  3063.   return( (XA_Time_Read() - xa_av_time_off) );
  3064. }
  3065.  
  3066. /***************************************************************************
  3067.  *
  3068.  */
  3069. void XA_Reset_Speed_Time(vid_time,speed_scale)
  3070. xaLONG vid_time; xaULONG speed_scale;
  3071. { xaLONG scaled_vid_time = XA_SPEED_ADJ(vid_time,speed_scale);
  3072.   xa_av_time_off = XA_Time_Read() - scaled_vid_time;
  3073. }
  3074.  
  3075. /***************************************************************************
  3076.  * This Function accepts current video time and if Audio is enabled, it
  3077.  * adjusts the audio stream to sync with the video. Whether or not audio
  3078.  * is enabled, it adjusts animation start time to be now.
  3079.  */
  3080. void XA_Reset_AV_Time(vid_time,speed_scale)
  3081. xaLONG vid_time; xaULONG speed_scale;
  3082. { xaLONG scaled_vid_time = XA_SPEED_ADJ(vid_time,speed_scale);
  3083.   DEBUG_LEVEL1 fprintf(stdout,"RESET_AV %d\n",vid_time);
  3084.   xa_av_time_off = XA_Time_Read() - scaled_vid_time;
  3085.   XA_AUDIO_VID_TIME(xa_av_time_off);
  3086. }
  3087.  
  3088. /***************************************************************************
  3089.  * Look at environmental variable and look for
  3090.  * INTERNAL
  3091.  * EXTERNAL
  3092.  * HEADPHONES
  3093.  * NONE
  3094.  ***************************************************************************/
  3095.  
  3096. xaULONG XA_Audio_Speaker(env_v)
  3097. char *env_v;
  3098. {
  3099.   char *env_d;
  3100.  
  3101.   env_d = getenv(env_v);
  3102.   if (env_d)
  3103.   {
  3104.     if ((*env_d == 'i') || (*env_d == 'I')) return(XA_AUDIO_PORT_INT);
  3105.     else if ((*env_d == 'h') || (*env_d == 'H')) return(XA_AUDIO_PORT_HEAD);
  3106.     else if ((*env_d == 'e') || (*env_d == 'E')) return(XA_AUDIO_PORT_EXT);
  3107.     else if ((*env_d == 'n') || (*env_d == 'N')) return(XA_AUDIO_PORT_NONE);
  3108.   }
  3109.   return(0);
  3110. }
  3111.  
  3112.  
  3113. /****************************************************************
  3114.  *
  3115.  ********************************/
  3116. #ifdef XSHM
  3117. xaULONG XA_Setup_Them_Buffers(im_Image,im_shminfo,im_buff)
  3118. XImage **im_Image;
  3119. XShmSegmentInfo *im_shminfo;
  3120. #else
  3121. xaULONG XA_Setup_Them_Buffers(im_buff)
  3122. #endif
  3123. char **im_buff;
  3124. { xaULONG buf_size = xa_max_image_size * x11_bytes_pixel;
  3125. #ifdef XSHM
  3126.   if (shm)
  3127.   { *im_Image = XShmCreateImage(theDisp,theVisual,x11_depth,
  3128.                 ZPixmap, 0, im_shminfo, xa_max_imagex, xa_max_imagey );
  3129.     if (*im_Image == 0) 
  3130.         { shm = 0; x11_error_possible = 0; goto XA_SHM_FAILURE; }
  3131.     im_shminfo->shmid = shmget(IPC_PRIVATE, buf_size, (IPC_CREAT | 0777 ));
  3132.     if (im_shminfo->shmid < 0) 
  3133.     { perror("shmget"); 
  3134.     shm = 0; x11_error_possible = 0;
  3135.         if (*im_Image) 
  3136.     { (*im_Image)->data = 0;
  3137.       XDestroyImage(*im_Image); *im_Image = 0;
  3138.     }
  3139.     goto XA_SHM_FAILURE;
  3140.     }
  3141.     im_shminfo->shmaddr = (char *) shmat(im_shminfo->shmid, 0, 0);
  3142.     XSync(theDisp, False);
  3143.     x11_error_possible = 1;  /* if remote display. following will fail */
  3144.     XShmAttach(theDisp, im_shminfo);
  3145.     XSync(theDisp, False);
  3146.     if (x11_error_possible == -1) /* above failed - back off */
  3147.     { shm = 0;
  3148.     x11_error_possible = 0;
  3149.         if (xa_verbose) fprintf(stdout,"SHM Attach failed: backing off\n");
  3150.     shmdt(im_shminfo->shmaddr);    im_shminfo->shmaddr = 0;
  3151.     (*im_Image)->data = 0;
  3152.         if (*im_Image) { XDestroyImage(*im_Image); *im_Image = 0; }
  3153.     goto XA_SHM_FAILURE;
  3154.     }
  3155.     else
  3156.     { shmctl(im_shminfo->shmid, IPC_RMID, 0 );
  3157.     (*im_Image)->data = *im_buff = im_shminfo->shmaddr;
  3158.     sh_Image = *im_Image;
  3159.       DEBUG_LEVEL2 fprintf(stdout, "Using Shared Memory Extension\n");
  3160.     }
  3161.   } else
  3162. #endif /* XSHM */
  3163.   {
  3164. XA_SHM_FAILURE:
  3165.     *im_buff = (char *) malloc(buf_size);
  3166.     if (*im_buff == 0) return(xaFALSE);
  3167.   }
  3168.   memset(*im_buff,0x00,buf_size);  
  3169.   return(xaTRUE);
  3170. }
  3171.  
  3172.  
  3173. void XA_Store_Title(cur_file,cur_frame,xa_title_flag)
  3174. XA_ANIM_HDR *cur_file;
  3175. xaLONG    cur_frame;
  3176. xaULONG    xa_title_flag;
  3177. { char xa_title[256];
  3178.   switch(xa_title_flag)
  3179.   { case XA_TITLE_FILE:
  3180.     sprintf(xa_title,"XAnim: %s",cur_file->name);
  3181.     break;
  3182.     case XA_TITLE_FRAME:
  3183.     if (cur_frame >= 0)
  3184.     sprintf(xa_title,"XAnim: %s %d",cur_file->name,cur_frame);
  3185.     else sprintf(xa_title,"XAnim: %s",cur_file->name);
  3186.     break;
  3187.     default:
  3188.     sprintf(xa_title,"XAnim");
  3189.     break;
  3190.   }
  3191. /* SMR 6 */
  3192.   if (xa_window_id == 0) XStoreName(theDisp,mainW,xa_title);
  3193.   else xa_title_flag = XA_TITLE_NONE;
  3194. /* end SMR 6 */
  3195.  
  3196. }
  3197.  
  3198.  
  3199. void XA_Resize_Window(cur_file,xa_noresize_flag,xa_disp_x,xa_disp_y)
  3200. XA_ANIM_HDR *cur_file;
  3201. xaULONG xa_disp_x, xa_disp_y;
  3202. xaLONG xa_noresize_flag;
  3203.  
  3204. {
  3205.   if (xa_noresize_flag == xaFALSE)
  3206.   {
  3207.     if ((xa_disp_x != cur_file->dispx) || (xa_disp_y != cur_file->dispy))
  3208.     {
  3209.     DEBUG_LEVEL1 fprintf(stdout,"resizing to <%d,%d>\n",
  3210.                     cur_file->dispx,cur_file->dispy);
  3211.       XSync(theDisp,False);
  3212.       XResizeWindow(theDisp,mainW,cur_file->dispx,cur_file->dispy);
  3213.       x11_window_x = cur_file->dispx; x11_window_y = cur_file->dispy;
  3214.       XSync(theDisp,False);
  3215.     }
  3216.   }
  3217.   else /* fixed window size */
  3218.   {
  3219.     XSync(theDisp,False);
  3220.     if (xa_disp_x > cur_file->dispx)
  3221.                 XClearArea(theDisp,mainW,cur_file->dispx,0, 0,0,False);
  3222.     if (xa_disp_y > cur_file->dispy)
  3223.                 XClearArea(theDisp,mainW,0,cur_file->dispy, 0,0,False);
  3224.     XSync(theDisp,False);
  3225.   }
  3226. }
  3227.  
  3228. /* NEW CODE GOES HERE */
  3229.  
  3230. /***********************************************************************
  3231.  * 
  3232.  ***************/
  3233. void Hard_Death()
  3234. {
  3235.   if (xa_vaudio_present==XA_AUDIO_OK) XA_AUDIO_KILL();
  3236.   if (xa_vid_fd >= 0) { close(xa_vid_fd); xa_vid_fd = -1; }
  3237.   if (xa_aud_fd >= 0) { close(xa_aud_fd); xa_aud_fd = -1; }
  3238.   if (xa_vidcodec_buf) { FREE(xa_vidcodec_buf,0x05); xa_vidcodec_buf=0;}
  3239.   if (xa_audcodec_buf) { FREE(xa_audcodec_buf,0x99); xa_audcodec_buf=0;}
  3240.  
  3241. #ifdef XA_AUDIO
  3242.   XA_AUDIO_EXIT();
  3243.   XA_IPC_Close_Pipes();
  3244. #endif
  3245.  
  3246.   cur_file = first_file;
  3247.   if (cur_file)
  3248.   {
  3249.     first_file->prev_file->next_file = 0;  /* last file's next ptr to 0 */
  3250.   }
  3251.   while(cur_file)
  3252.   { XA_ANIM_HDR *tmp_hdr = cur_file->next_file;
  3253.     Free_Actions(cur_file->acts);
  3254.     if (cur_file->name) { FREE(cur_file->name,0x15); cur_file->name = 0; }
  3255.     XA_Walk_The_Chain(cur_file,xaTRUE);  /* Walk and Free functions */
  3256.     FREE(cur_file,0x16);
  3257.     cur_file = tmp_hdr;
  3258.   }
  3259.  
  3260.   if (!shm)  /* otherwise it's free'd below as imX_shminfo.shmaddr */
  3261.   {
  3262.     if (im_buff0) { FREE(im_buff0,0x08); im_buff0=0; }
  3263.     if (im_buff1) { FREE(im_buff1,0x09); im_buff1=0; }
  3264.     if (im_buff2) { FREE(im_buff2,0x0a); im_buff2=0; }
  3265.   }
  3266.   if (im_buff3) { FREE(im_buff3,0x0b); im_buff3=0; }
  3267.   if (xa_disp_buff) { FREE(xa_disp_buff,0x0c); xa_disp_buff=0; }
  3268.   if (xa_scale_buff) { FREE(xa_scale_buff,0x0d); xa_scale_buff=0; }
  3269.   if (xa_scale_row_buff) { FREE(xa_scale_row_buff,0x0e); xa_scale_row_buff=0;}
  3270.   if (xa_cmap) { FREE(xa_cmap,0x0f); xa_cmap=0; }
  3271.   if (xa_ham_map) { FREE(xa_ham_map,0x10); xa_ham_map=0;}
  3272.   if (cmap_cache != 0) { FREE(cmap_cache,0x23); }
  3273.   if (cmap_cache2 != 0) { FREE(cmap_cache2,0x99); }
  3274.   while(xa_chdr_start)
  3275.   {
  3276.     XA_CHDR *tmp;
  3277.     tmp = xa_chdr_start;
  3278.     xa_chdr_start = xa_chdr_start->next;
  3279.     if (tmp->cmap) { FREE(tmp->cmap,0x11); tmp->cmap=0; }
  3280.     if (tmp->map) { FREE(tmp->map,0x12); tmp->map=0; }
  3281.     FREE(tmp,0x13);
  3282.   }
  3283. #ifdef XSHM
  3284.   if (shm)
  3285.   {
  3286.     if (im0_shminfo.shmaddr) { XShmDetach(theDisp,&im0_shminfo);
  3287.              shmdt(im0_shminfo.shmaddr); }
  3288.     if (im1_shminfo.shmaddr) { XShmDetach(theDisp,&im1_shminfo);
  3289.              shmdt(im1_shminfo.shmaddr); }
  3290.     if (im2_shminfo.shmaddr) { XShmDetach(theDisp,&im2_shminfo);
  3291.              shmdt(im2_shminfo.shmaddr); }
  3292.     if (im0_Image)
  3293.     {
  3294.       im0_Image->data = 0;
  3295.       XDestroyImage(im0_Image);
  3296.     }
  3297.     if (im1_Image)
  3298.     {
  3299.       im1_Image->data = 0;
  3300.       XDestroyImage(im1_Image);
  3301.     }
  3302.     if (im2_Image)
  3303.     {
  3304.       im2_Image->data = 0;
  3305.       XDestroyImage(im2_Image);
  3306.     }
  3307.   }
  3308. #endif
  3309. #ifndef XA_IS_PLUGIN
  3310.   exit(0);
  3311. #endif
  3312. }
  3313.  
  3314. /***********************************************
  3315.  * This function (hopefully) provides a clean exit from our code.
  3316.  *******************************/
  3317. void TheEnd()
  3318. {
  3319. /* SMR 7 */
  3320. /* force the other window to be redrawn */
  3321.   if (theDisp)
  3322.   { if (xa_window_id != 0 && xa_window_refresh_flag == xaTRUE)
  3323.             XClearArea(theDisp, mainW, 0, 0, 0, 0, True);
  3324.     XFlush(theDisp);
  3325.   }
  3326. /* end SMR 7 */
  3327.  
  3328. /*POD TEMP eventually move into free chain*/
  3329.   jpg_free_stuff();
  3330.  
  3331.   if (xa_vaudio_present==XA_AUDIO_OK)  XA_AUDIO_KILL();
  3332.   if (xa_vid_fd >= 0) { close(xa_vid_fd); xa_vid_fd = -1; }
  3333.   if (xa_aud_fd >= 0) { close(xa_aud_fd); xa_aud_fd = -1; }
  3334.   if (xa_vidcodec_buf) { FREE(xa_vidcodec_buf,0x14); xa_vidcodec_buf=0;}
  3335.   if (xa_audcodec_buf) { FREE(xa_audcodec_buf,0x99); xa_audcodec_buf=0;}
  3336.  
  3337. #ifdef XA_AUDIO
  3338.   XA_AUDIO_EXIT();
  3339.   XA_IPC_Close_Pipes();
  3340. #endif
  3341.  
  3342.   cur_file = first_file;
  3343.   if (cur_file)
  3344.   {
  3345.     first_file->prev_file->next_file = 0;  /* last file's next ptr to 0 */
  3346.   } 
  3347.   while(cur_file)
  3348.   { XA_ANIM_HDR *tmp_hdr = cur_file->next_file;
  3349.     Free_Actions(cur_file->acts);
  3350.     if (cur_file->name) { FREE(cur_file->name,0x15); cur_file->name = 0; }
  3351.     XA_Walk_The_Chain(cur_file,xaTRUE);  /* Walk and Free functions */
  3352.     FREE(cur_file,0x16);
  3353.     cur_file = tmp_hdr;
  3354.   }
  3355.   if (!shm)  /* otherwise it's free'd below as imX_shminfo.shmaddr */
  3356.   {
  3357.     if (im_buff0) { FREE(im_buff0,0x17); im_buff0=0; }
  3358.     if (im_buff1) { FREE(im_buff1,0x18); im_buff1=0; }
  3359.     if (im_buff2) { FREE(im_buff2,0x19); im_buff2=0; }
  3360.   }
  3361.   if (im_buff3) { FREE(im_buff3,0x1a); im_buff3=0; }
  3362.   if (xa_disp_buff) { FREE(xa_disp_buff,0x1b); xa_disp_buff=0; }
  3363.   if (xa_scale_buff) { FREE(xa_scale_buff,0x1c); xa_scale_buff=0; }
  3364.   if (xa_scale_row_buff) { FREE(xa_scale_row_buff,0x1d); xa_scale_row_buff=0;}
  3365.   if (xa_cmap) { FREE(xa_cmap,0x1e); xa_cmap=0; }
  3366.   if (xa_ham_map) { FREE(xa_ham_map,0x1f); xa_ham_map=0;}
  3367.   if (cmap_cache != 0) { FREE(cmap_cache,0x23); }
  3368.   if (cmap_cache2 != 0) { FREE(cmap_cache2,0x99); }
  3369.   while(xa_chdr_start)
  3370.   {
  3371.     XA_CHDR *tmp;
  3372.     tmp = xa_chdr_start;
  3373.     xa_chdr_start = xa_chdr_start->next;
  3374.     if (tmp->cmap) { FREE(tmp->cmap,0x20); tmp->cmap=0; }
  3375.     if (tmp->map) { FREE(tmp->map,0x21); tmp->map=0; }
  3376.     FREE(tmp,0x22);
  3377.   }
  3378. #ifdef XSHM
  3379.   if (shm)
  3380.   {
  3381.     if (im0_shminfo.shmaddr) { XShmDetach(theDisp,&im0_shminfo);
  3382.              shmdt(im0_shminfo.shmaddr); }
  3383.     if (im1_shminfo.shmaddr) { XShmDetach(theDisp,&im1_shminfo);
  3384.              shmdt(im1_shminfo.shmaddr); }
  3385.     if (im2_shminfo.shmaddr) { XShmDetach(theDisp,&im2_shminfo);
  3386.              shmdt(im2_shminfo.shmaddr); }
  3387.     if (im0_Image)
  3388.     {
  3389.       im0_Image->data = 0;
  3390.       XDestroyImage(im0_Image);
  3391.     }
  3392.     if (im1_Image)
  3393.     {
  3394.       im1_Image->data = 0;
  3395.       XDestroyImage(im1_Image);
  3396.     }
  3397.     if (im2_Image)
  3398.     {
  3399.       im2_Image->data = 0;
  3400.       XDestroyImage(im2_Image);
  3401.     }
  3402.   }
  3403. #endif
  3404.   if (theImage) 
  3405.   {
  3406.     theImage->data = 0;
  3407.     XDestroyImage(theImage);
  3408.   }
  3409. #ifdef XA_REMOTE_CONTROL
  3410.   XA_Remote_Free();
  3411. #endif
  3412.   XA_Free_CMAP();
  3413.   if (theDisp) XtCloseDisplay(theDisp);
  3414.  
  3415.  
  3416. #ifndef XA_IS_PLUGIN
  3417.   exit(0);
  3418. #endif
  3419. }
  3420.  
  3421. /***********************************************
  3422.  * just prints a message before calling TheEnd()
  3423.  *******************************/
  3424. void TheEnd1(err_mess)
  3425. char *err_mess;
  3426. {
  3427.  fprintf(stdout,"%s\n",err_mess);
  3428.  TheEnd();
  3429. }
  3430.  
  3431. /***********************************************
  3432.  *
  3433.  *******************************/
  3434. XA_ANIM_SETUP *XA_Get_Anim_Setup()
  3435. { int i;
  3436.   XA_ANIM_SETUP *setup = (XA_ANIM_SETUP *)malloc(sizeof(XA_ANIM_SETUP));
  3437.   if (setup==0) TheEnd1("XA_ANIM_SETUP: malloc err\n");
  3438.   setup->imagex        = setup->max_imagex    = 0;
  3439.   setup->imagey        = setup->max_imagey    = 0;
  3440.   setup->imagec        = setup->depth        = 0;
  3441.   setup->compression    = 0;
  3442.   setup->pic        = 0;
  3443.   setup->pic_size    = 0;
  3444.   setup->max_fvid_size    = setup->max_faud_size    = 0;
  3445.   setup->vid_time    = setup->vid_timelo    = 0;
  3446.   setup->aud_time    = setup->aud_timelo    = 0;
  3447.   setup->chdr        = 0;
  3448.   setup->cmap_flag    = 0;
  3449.   setup->cmap_cnt    = 0;
  3450.   setup->color_retries    = 0;
  3451.   setup->color_cnt    = 0;
  3452.   setup->cmap_frame_num    = 0;
  3453.   for(i=0; i< 256; i++)
  3454.     setup->cmap[i].red = setup->cmap[i].green = setup->cmap[i].blue = 0;
  3455.   return(setup);
  3456. }
  3457.  
  3458. /***********************************************
  3459.  *
  3460.  *******************************/
  3461. void XA_Free_Anim_Setup(setup)
  3462. XA_ANIM_SETUP *setup;
  3463. {
  3464.   if (setup) free(setup);
  3465. }
  3466.  
  3467. /***********************************************
  3468.  * Allocate and init a Fuction Chain Structure.
  3469.  *
  3470.  *******************************/
  3471. XA_FUNC_CHAIN *XA_Get_Func_Chain(anim_hdr,function)
  3472. XA_ANIM_HDR *anim_hdr;
  3473. void (*function)();
  3474. { XA_FUNC_CHAIN *f_chain = (XA_FUNC_CHAIN *)malloc(sizeof(XA_FUNC_CHAIN));
  3475.   if (f_chain==0) TheEnd1("XA_FUNC_CHAIN: malloc err\n");
  3476.   f_chain->function = function;
  3477.   f_chain->next     = 0;
  3478.   return(f_chain);
  3479. }
  3480.  
  3481. /***********************************************
  3482.  * Add Function to List of functions to be called at Dying Time.
  3483.  *
  3484.  *******************************/
  3485. void XA_Add_Func_To_Free_Chain(anim_hdr,function)
  3486. XA_ANIM_HDR *anim_hdr;
  3487. void (*function)();
  3488. { XA_FUNC_CHAIN *f_chain = XA_Get_Func_Chain(anim_hdr,function);
  3489.   f_chain->next = anim_hdr->free_chain;
  3490.   anim_hdr->free_chain = f_chain;
  3491. }
  3492.  
  3493. /***********************************************
  3494.  * 
  3495.  *
  3496.  *******************************/
  3497. void XA_Walk_The_Chain(anim_hdr,free_flag)
  3498. XA_ANIM_HDR *anim_hdr;
  3499. xaULONG free_flag;        /* xaTRUE free structs. xaFALSE don't free */
  3500. { XA_FUNC_CHAIN *f_chain = anim_hdr->free_chain;
  3501.  
  3502.   while(f_chain)
  3503.   { XA_FUNC_CHAIN *tmp = f_chain;
  3504.     f_chain->function();
  3505.     f_chain = f_chain->next;
  3506.     if (free_flag == xaTRUE) free(tmp);
  3507.   }
  3508.   if (free_flag == xaTRUE) anim_hdr->free_chain = 0;
  3509. }
  3510.  
  3511.  
  3512. /**************** Send BOFL's to the Audio Child every 5 seconds(5000 ms) */
  3513.  
  3514. #ifdef XA_AUDIO
  3515.  
  3516. void XA_Setup_BOFL()
  3517. {
  3518.   XtAppAddTimeOut(theContext,5000, (XtTimerCallbackProc)XA_Video_BOFL,
  3519.                                                         (XtPointer)(NULL));
  3520. }
  3521.  
  3522. void XA_Video_BOFL()
  3523. {
  3524.   if (xa_forkit == xaTRUE)
  3525.     xa_forkit = XA_Video_Send2_Audio(XA_IPC_BOFL,NULL,0,0,0,0);
  3526.   if (xa_forkit == xaTRUE)
  3527.     XtAppAddTimeOut(theContext,5000, 
  3528.         (XtTimerCallbackProc)XA_Video_BOFL,(XtPointer)(NULL));
  3529. }
  3530.  
  3531. #endif
  3532.  
  3533.  
  3534. void XA_Adjust_Video_Timing(anim_hdr,total_time)
  3535. XA_ANIM_HDR *anim_hdr;
  3536. xaULONG total_time;
  3537. { double ftime = (double)(total_time);
  3538.   xaULONG i,vid_time,t_time;
  3539.   xaLONG vid_timelo,t_timelo;
  3540.  
  3541.   if (total_time == 0) return;
  3542.   if (anim_hdr->last_frame == 0) return;
  3543.  
  3544.   /* this isn't perfect but it'll be close 90% of the time */
  3545.   ftime /= (double)(anim_hdr->last_frame);
  3546.   vid_time =  (xaULONG)(ftime);
  3547.   ftime -= (double)(vid_time);
  3548.   vid_timelo = (xaLONG)(ftime * (double)(1<<24));
  3549.   
  3550.   t_time = 0;
  3551.   t_timelo = 0;
  3552.   i = 0;
  3553.   while( anim_hdr->frame_lst[i].act )
  3554.   {
  3555.     if ( anim_hdr->frame_lst[i].zztime < 0) continue;
  3556.     anim_hdr->frame_lst[i].time_dur = vid_time;
  3557.     anim_hdr->frame_lst[i].zztime = t_time;
  3558.     t_time += vid_time;
  3559.     t_timelo += vid_timelo;
  3560.     while(t_timelo > (1<<24)) {t_time++; t_timelo -= (1<<24);}
  3561.     i++;
  3562.   }
  3563. }
  3564.  
  3565.