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