tomwalters@0: /* tomwalters@0: Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989 tomwalters@0: =========================================================================== tomwalters@0: tomwalters@0: Permission to use, copy, modify, and distribute this software without fee tomwalters@0: is hereby granted for research purposes, provided that this copyright tomwalters@0: notice appears in all copies and in all supporting documentation, and that tomwalters@0: the software is not redistributed for any fee (except for a nominal shipping tomwalters@0: charge). Anyone wanting to incorporate all or part of this software in a tomwalters@0: commercial product must obtain a license from the Medical Research Council. tomwalters@0: tomwalters@0: The MRC makes no representations about the suitability of this tomwalters@0: software for any purpose. It is provided "as is" without express or implied tomwalters@0: warranty. tomwalters@0: tomwalters@0: */ tomwalters@0: tomwalters@0: /* tomwalters@0: gen.c tomwalters@0: ===== tomwalters@0: tomwalters@0: APU, ASP model demonstration program. tomwalters@0: tomwalters@0: tomwalters@0: Copyright (c), 1989 The Medical Research Council, Applied Psychology Unit. tomwalters@0: tomwalters@0: tomwalters@0: Authors : John Holdsworth (1989), Mike Allerhand (1990) tomwalters@0: tomwalters@0: tomwalters@0: Edited : M.Akeroyd 22-1-1993 tomwalters@0: Removed the conditional of `if (centering) Clear (w)' tomwalters@0: (in plot_frame), so that Clear may be called for tomwalters@0: PostScriptWindows that AREN'T centered, so allowing tomwalters@0: showpages to be generated. tomwalters@0: See also edit to ps.c tomwalters@0: tomwalters@0: : M Akeroyd 3-8-1993 tomwalters@0: Added new options: tomwalters@0: erbscale_efb (InputOption) mono_ctn (SilentOption) tomwalters@0: colour_ctn (SilentOption) planemask_ctn (SilentOption) tomwalters@0: Allowed "bitmap=stdout". tomwalters@0: tomwalters@0: : MAA 3rd August 1993 tomwalters@0: Extra options tomwalters@0: framenumber (SilentOption), review (SilentOption) tomwalters@0: tomwalters@0: : MAA 22nd July 1994. tomwalters@0: Extra postscript options ALl silent tomwalters@0: xstart_ps xend_ps ystart_ps yend_ps tomwalters@0: xtitle_ps ytitle_ps tomwalters@0: Extra X options tomwalters@0: fg_col bg_col tomwalters@0: tomwalters@0: : MAA Summer 1984. Lots of postscript options. All silent tomwalters@0: portraitstr, landscapestr; tomwalters@0: fontnamestr, fontsizestr; tomwalters@0: xmajorticksstr, xminorticksstr, ymajorticksstr, yminorticksstr; tomwalters@0: axistop, axisbottom, axisleft, axisright; tomwalters@0: tomwalters@0: : AJD Spring 1995. tomwalters@0: Added a new argument 'nwid' to the function SourceDraw, so that genspl tomwalters@0: can have the necessary information. tomwalters@0: tomwalters@0: : AJD May, 1995. tomwalters@0: Made options overlap, headroom, perspective, bytemax and type silent. tomwalters@0: */ tomwalters@0: tomwalters@0: tomwalters@0: #ifndef lint tomwalters@0: static char *sccs_id = "@(#)gen.c 1.66 John Holdsworth, Mike Allerhand, Roy Patterson, Paul Manson (MRC-APU) 6/6/91" ; tomwalters@0: #endif tomwalters@0: tomwalters@0: tomwalters@0: /**************************************************************************** tomwalters@0: * This module contains: tomwalters@0: * Display option parameter strings. tomwalters@0: * Model option parameter strings. tomwalters@0: * File-format strings. tomwalters@0: * X windows interface, (included from windows.h). tomwalters@0: * Options handler routines, (included from options.h). tomwalters@0: * Option defaults, (application specific). tomwalters@0: * Strings for generic option types, (OnOption etc). tomwalters@0: * Display options table, (displayopts[]). tomwalters@0: * Model option tables, (included from table.c). tomwalters@0: * Model entry-point functions, (included from model.c). tomwalters@0: * Display drawing routines, (included from draw.h and fill.h). tomwalters@0: * Options table construction, (constructOptions(), and mapOptions()). tomwalters@0: * Main. tomwalters@0: ****************************************************************************/ tomwalters@0: tomwalters@0: #include tomwalters@0: #include tomwalters@0: #include tomwalters@0: #include tomwalters@0: tomwalters@0: #if defined(THINK_C) || defined(NeXT) tomwalters@0: #include tomwalters@0: #endif tomwalters@0: tomwalters@0: /********************* Display option parameter strings ********************* tomwalters@0: * The strings defined here are pointers referenced by the "value" field in tomwalters@0: * the display options table, displayopts. They are assigned to space which tomwalters@0: * initially contains defaults in the "defaultValue" field of the display tomwalters@0: * options table. tomwalters@0: ****************************************************************************/ tomwalters@0: tomwalters@0: static char *bmaxstr, *topstr, *botstr, *overstr ; tomwalters@0: static char *headstr, *downcstr, *heightstr, *helpstr ; tomwalters@0: static char *invertstr, *lengthstr, *linstr, *outstr ; tomwalters@0: static char *reusestr, *startstr, *envstr, *typestr ; tomwalters@0: #ifdef X11 tomwalters@0: static char *dispstr, *erasestr, *hiddenstr, *bitmapstr ; tomwalters@0: static char *kludgestr, *magstr, *penstr, *psfilestr ; tomwalters@0: static char *psstr, *animstr, *titlestr, *viewstr ; tomwalters@0: static char *widthstr, *xstr, *ystr ; tomwalters@0: /* All these MAA. */ tomwalters@0: char *monostr, *colourstr, *planemaskstr, *rotateaxesstr; tomwalters@0: char *fgcolourstr, *bgcolourstr; tomwalters@0: char *xstartstr, *ystartstr, *xendstr, *yendstr; tomwalters@0: char *xnewtitlestr, *ynewtitlestr; tomwalters@0: char *portraitstr, *landscapestr; tomwalters@0: char *fontnamestr, *fontsizestr, *titlesizestr; tomwalters@0: char *xticksstr, *yticksstr, *outsidestr; tomwalters@0: char *axistopstr, *axisbottomstr, *axisleftstr, *axisrightstr; tomwalters@0: char *xmajorticksstr, *xminorticksstr, *ymajorticksstr, *yminorticksstr; tomwalters@0: char *axislinewidthstr, *figurelinewidthstr; tomwalters@0: char *boxstr; tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: char *framenumberstr, *reviewstr; /* MAA: 3-8-1993 */ tomwalters@0: tomwalters@0: static char *test1str, *test2str, *test3str, *test4str ; tomwalters@0: tomwalters@0: char headerstr[64] ; tomwalters@0: tomwalters@0: char *filestr ; tomwalters@0: tomwalters@0: /* application display parameters */ tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: static char *tiltstr = "0." ; tomwalters@0: static char *diststr = "0.5" ; tomwalters@0: static char *roomstr = "0%" ; tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: /*************** Included from glib (graphics library) directory ***********/ tomwalters@0: tomwalters@0: #include "options.h" tomwalters@0: #include "defaults.h" tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: #include "windows.h" tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: /******************* Strings for generic option values ********************** tomwalters@0: * Generic option values, (ON_OPTION etc), are defined in options.h. tomwalters@0: * Convenience routines used to test or convert option values are: tomwalters@0: * OptionStringsEqual( str1, str2 ) -(defined in options.c). tomwalters@0: * isON( str ) -(defined in options.h). tomwalters@0: * isOFF( str ) -(defined in options.c). tomwalters@0: * isNULL( str ) -(defined in options.c). tomwalters@0: * OptionInt( str ) -(defined in model.c). tomwalters@0: * OptionDouble( str ) -(defined in model.c). tomwalters@0: * Samples( str ) -(defined in model.c). tomwalters@0: * Cycles( str, cfreq ) -(defined in model.c). tomwalters@0: * Scalar( str ) -(defined in model.c). tomwalters@0: * Freq( str ) -(defined in model.c). tomwalters@0: * tomwalters@0: ****************************************************************************/ tomwalters@0: tomwalters@0: tomwalters@0: static char helpstring[200] = "no help initially" ; tomwalters@0: static char OnOption[] = ON_OPTION ; /* "on" */ tomwalters@0: static char OffOption[] = OFF_OPTION ; /* "off" */ tomwalters@0: static char NullOption[] = NULL_OPTION ; /* "none" */ tomwalters@0: static char CenterStr[] = "center" ; tomwalters@0: static char LengthStr[] = "remainder" ; tomwalters@0: static char LandStr[] = "landscape" ; tomwalters@0: tomwalters@0: static int isEXCITE( str ) tomwalters@0: char *str ; tomwalters@0: { tomwalters@0: return ( strncmp( str, "excitation", strlen( str ) ) == 0 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: static int isWATERFALL( str ) tomwalters@0: char *str ; tomwalters@0: { tomwalters@0: return ( strncmp( str, "waterfall", strlen( str ) ) == 0 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: static int isGREYSCALE( str ) tomwalters@0: char *str ; tomwalters@0: { tomwalters@0: return ( strncmp( str, "greyscale", strlen( str ) ) == 0 || tomwalters@0: strncmp( str, "grayscale", strlen( str ) ) == 0 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /************************* Options table *********************************** tomwalters@0: * The complete options table is built by constructOptions() according to the tomwalters@0: * application. It is composed of the display options, (displayopts[], below), tomwalters@0: * and the model option tables (from table.c) which are appropriate for the tomwalters@0: * application. The sequence of processing stages, (and hence model option tomwalters@0: * tables), for an application is determined by FindStage() in model.c. tomwalters@0: * tomwalters@0: * The complete options table is an array of Option structs. tomwalters@0: * The Option struct is defined in options.h as: tomwalters@0: * tomwalters@0: * typedef struct { tomwalters@0: * char *name ; The name of the option. tomwalters@0: * char *defaultValue ; Default value. tomwalters@0: * char **value ; Address of current value. tomwalters@0: * char *comment ; Something to print when the user types "-help". tomwalters@0: * short classification ; Type of option it is. tomwalters@0: * } Option; tomwalters@0: * tomwalters@0: * The classification of options uses names defined in options.h: tomwalters@0: * InputOption tomwalters@0: * OutputOption tomwalters@0: * InOutOption tomwalters@0: * SilentOption tomwalters@0: * tomwalters@0: * Routines which access the option table: tomwalters@0: * Note: Some routines are called to supply arguments to other routines. tomwalters@0: * Routines which access the option table in some way are denoted (*). tomwalters@0: * Most of these routines are defined in options.c. tomwalters@0: * tomwalters@0: * main() tomwalters@0: * | tomwalters@0: * +-----------------+-----------+----+-------+-----------------+ tomwalters@0: * | | | | | tomwalters@0: * | | | ModeledSource() | tomwalters@0: * | | | | | tomwalters@0: * | | | checkForFile() | tomwalters@0: * helpopts() | | | | tomwalters@0: * | | +---+---+ | tomwalters@0: * | | | | tomwalters@0: * | getopts() readopts() writeopts() tomwalters@0: * | | | | tomwalters@0: * | getnopts(*) readnopts() writenopts(*) tomwalters@0: * | [arg countOptions(*)] [arg countOptions(*)] [arg countOptions(*)] tomwalters@0: * | | | | tomwalters@0: * | +-------+------+ | countBytesToWrite(*) tomwalters@0: * | | | | | tomwalters@0: * | | | +------+------+ tomwalters@0: * | | | | tomwalters@0: * | | | processOptionFile() tomwalters@0: * | | | | tomwalters@0: * | | +------+------+ tomwalters@0: * | | | tomwalters@0: * | | LookUpAndStore(*) tomwalters@0: * | | | tomwalters@0: * | | +---+---+----------+ tomwalters@0: * | | | | | tomwalters@0: * | +-----+----+ LookUp(*) Ambiguity(*) tomwalters@0: * | | | tomwalters@0: * +----+----+ updateOptionsFile(*) tomwalters@0: * | tomwalters@0: * defaultHelpHandler(*) tomwalters@0: * tomwalters@0: * tomwalters@0: * getopts() tomwalters@0: * Operates on the options table given to it as an argument. tomwalters@0: * a) Each "value" field is initialized to its "defaultValue" field. tomwalters@0: * b) The "value" fields are re-initialized by any corresponding values found tomwalters@0: * in the options ("rc") file, (overriding the "defaultValue"). tomwalters@0: * c) The "value" fields are re-initialized again by any corresponding values tomwalters@0: * found in command-line arguments. tomwalters@0: * d) Special arguments are dealt with: tomwalters@0: * "help" calls the onLineHelpHandler() routine, (see below). tomwalters@0: * "update" calls the updateOptionsFile() routine. tomwalters@0: * e) Return the remainder of the command-line (argc and argv) for use in tomwalters@0: * main(). tomwalters@0: * tomwalters@0: * helpopts() tomwalters@0: * Is called to print the help menu if no input file has been found by tomwalters@0: * getopts(), (in the "rc" file), and none remains on the command-line. tomwalters@0: * An alias for the onLineHelpHandler() function, which is in turn an tomwalters@0: * alias for the defaultHelpHandler() routine, (see options.c). tomwalters@0: * tomwalters@0: * readopts() tomwalters@0: * Read any options header which may be at the start of the input file. tomwalters@0: * Interpret the header like an options ("rc") file, and re-initialize any tomwalters@0: * corresponding "value" fields in the given options table, (as in getopts()). tomwalters@0: * Skip to the start of the input data, allowing for any offset (ie startstr). tomwalters@0: * tomwalters@0: * writeopts() tomwalters@0: * Write the given options table as an options header at the start of an o/p tomwalters@0: * file, if the "header" option is "on". tomwalters@0: * tomwalters@0: ****************************************************************************/ tomwalters@0: tomwalters@0: static Option *options; tomwalters@0: tomwalters@0: /******************** Display options table ******************************** tomwalters@0: * Options table for application display parameters. tomwalters@0: ****************************************************************************/ tomwalters@0: tomwalters@0: static Option displayopts[] = { tomwalters@0: tomwalters@0: /* Miscellaneous Silent Parameters (hidden from users) */ tomwalters@0: tomwalters@0: tomwalters@0: { "Version", headerstr, &versionstr, "Version number and date", OutputOption}, tomwalters@0: tomwalters@0: { "test1", "0", &test1str, "Dummy option for test and development", SilentOption}, tomwalters@0: { "test2", "0", &test2str, "Dummy option for test and development", SilentOption}, tomwalters@0: { "test3", "0", &test3str, "Dummy option for test and development", SilentOption}, tomwalters@0: { "test4", "0", &test4str, "Dummy option for test and development", SilentOption}, tomwalters@0: tomwalters@0: { "linear_sgm", OffOption, &linstr, "Linear frequency axis for spectrograms",SilentOption}, tomwalters@0: { "useprevious", OffOption, &reusestr, "Use previously stored output", SilentOption}, tomwalters@0: tomwalters@0: /* MAA: 21-8-1993 tomwalters@0: * These next two options are here, because otherwise "gensgm -use ..." (at least) core dumps. tomwalters@0: */ tomwalters@0: { "framenumber", OffOption, &framenumberstr, "Index of current frame (to stderr)\n", SilentOption}, tomwalters@0: { "review", OffOption, &reviewstr, "Wait for keyboard between frames",SilentOption}, tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: { "pstofile", OffOption, &psfilestr, "Send PostScript output to .ps file", SilentOption}, tomwalters@0: { "invert", OffOption, &invertstr, "Invert axis of sai image", SilentOption}, tomwalters@0: { "fast", OffOption, &kludgestr, "Speed up image generation", SilentOption}, tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: /* ( The order of the "help" option members is strange due to the way */ tomwalters@0: /* it was originally used. See options.c: defaultHelpHandler() and */ tomwalters@0: /* updateOptionsFile() ). */ tomwalters@0: tomwalters@0: /* Input Parameters */ tomwalters@0: tomwalters@0: { "envelope", OffOption, &envstr, "Type of model to use required", SilentOption}, tomwalters@0: { "help", "not used", &helpstr, helpstring, SilentOption}, tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: tomwalters@0: /* Screen Output Parameters */ tomwalters@0: tomwalters@0: { "title", "filename", &titlestr, "Title of picture, or input filename", InputOption}, tomwalters@0: #ifdef THINK_C tomwalters@0: { "x0_win", "10", &xstr, "Left edge of window (pixels)", InOutOption}, tomwalters@0: { "y0_win", "50", &ystr, "Lower edge of window (pixels)", InOutOption}, tomwalters@0: #else tomwalters@0: { "x0_win", CenterStr, &xstr, "Left edge of window (pixels)", InOutOption}, tomwalters@0: { "y0_win", CenterStr, &ystr, "Lower edge of window (pixels)", InOutOption}, tomwalters@0: #endif tomwalters@0: #ifdef PC tomwalters@0: { "width_win", "400", &widthstr, "Window width (pixels)", InOutOption}, tomwalters@0: { "height_win", "300", &heightstr, "Window height (pixels)\n", InOutOption}, tomwalters@0: #else /* UNIX */ tomwalters@0: { "width_win", "540", &widthstr, "Window width (pixels)", InOutOption}, tomwalters@0: { "height_win", "400", &heightstr, "Window height (pixels)\n", InOutOption}, tomwalters@0: #endif tomwalters@0: { "display", OnOption, &dispstr, "Select display of output image", InOutOption}, tomwalters@0: { "view", LandStr, &viewstr, "Select display format", InOutOption}, tomwalters@0: { "top", "1024", &topstr, "Maximum of plotted range", InputOption}, tomwalters@0: { "bottom", "-1024", &botstr, "Minimum of plotted range", InputOption}, tomwalters@0: { "overlap", "50%", &overstr, "Overlap between channels", SilentOption}, /* AJD 16-5-95 */ tomwalters@0: { "headroom", "0%", &roomstr, "Headroom at top of picture", SilentOption}, /* AJD 16-5-95 */ tomwalters@0: { "magnification", "1", &magstr, "Magnification of image in display", InputOption}, tomwalters@0: { "pensize", "1", &penstr, "Size of plotted lines and dots", InputOption}, tomwalters@0: { "hiddenline", OnOption, &hiddenstr, "Hidden line removal\n", InputOption}, tomwalters@0: { "perspective", "0", &tiltstr, "Perspective view of display (degrees)\n", SilentOption}, /* AJD 16-5-95 */ tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: { "downchannel", OffOption, &downcstr, "Average adjacent frequency channels\n", InOutOption}, tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: tomwalters@0: /* Auditory image cartoon parameters */ tomwalters@0: tomwalters@0: { "erase_ctn", OnOption, &erasestr, "Erase display between cartoon frames", InOutOption}, tomwalters@0: { "animate_ctn", OffOption, &animstr, "Animate cartoon", InOutOption}, tomwalters@0: { "bitmap_ctn", OffOption, &bitmapstr, "Produce cartoon output (.ctn)\n", InputOption}, tomwalters@0: { "mono_ctn", OnOption, &monostr, "Force monochrome (single plane) cartoons.", SilentOption}, tomwalters@0: { "colour_ctn", OffOption, &colourstr, "Force colour (multi-plane) cartoons.", SilentOption}, tomwalters@0: {"planemask_ctn", "1", &planemaskstr, "Planemask for creating cartoons.\n", SilentOption}, tomwalters@0: {"fg_col", "black", &fgcolourstr, "Foreground Colour.\n", SilentOption}, tomwalters@0: {"bg_col", "white", &bgcolourstr, "Background Colour.\n", SilentOption}, tomwalters@0: tomwalters@0: tomwalters@0: /* Postscript options */ tomwalters@0: tomwalters@0: { "postscript", OffOption, &psstr, "Produce postscript output", InputOption}, tomwalters@0: { "rotateaxes", OffOption, &rotateaxesstr, "Rotate the axes labels in .ps output", SilentOption}, tomwalters@0: { "xstart_ps", "", &xstartstr, "Postscript x-axis: start point.", SilentOption}, tomwalters@0: { "xend_ps", "", &xendstr, "Postscript x-axis: end point.", SilentOption}, tomwalters@0: { "ystart_ps", "", &ystartstr, "Postscript y-axis: start point.", SilentOption}, tomwalters@0: { "yend_ps", "", ¥dstr, "Postscript y-axis: end point.", SilentOption}, tomwalters@0: { "xtitle_ps", "", &xnewtitlestr, "Postscript x-axis: title.", SilentOption}, tomwalters@0: { "ytitle_ps", "", &ynewtitlestr, "Postscript x-axis: title.", SilentOption}, tomwalters@0: { "portrait_ps", "", &portraitstr, "Use 'portrait' page format", SilentOption}, tomwalters@0: { "landscape_ps", "", &landscapestr, "Use 'landscape' page format (overrides 'portriat)", SilentOption}, tomwalters@0: { "fontname_ps", "Helvetica", &fontnamestr, "Define font", SilentOption}, tomwalters@0: { "fontsize_ps", "12", &fontsizestr, "Define fontsize (points)", SilentOption}, tomwalters@0: { "fonttitlesize_ps", "0", &titlesizestr, "Define fontsize for title (points)", SilentOption}, tomwalters@0: { "axislinewidth_ps", "1", &axislinewidthstr, "Linewidth for axes & tickmarks (points)", SilentOption}, tomwalters@0: { "figurelinewidth_ps", "1", &figurelinewidthstr, "Linewidth for figures (points)", SilentOption}, tomwalters@0: { "xticks_ps", "6", &xticksstr, "Define size of x-axis (big) ticks (points)", SilentOption}, tomwalters@0: { "yticks_ps", "6", &yticksstr, "Define size of y-axis (big) ticks' (points)", SilentOption}, tomwalters@0: { "outsideticks_ps",OnOption, &outsidestr, "Print tick-marks 'outside' figure", SilentOption}, tomwalters@0: { "axistop_ps", OnOption, &axistopstr, "Print tick-marks on top side", SilentOption}, tomwalters@0: { "axisbottom_ps", OnOption, &axisbottomstr, "Print tick-marks on bottom side", SilentOption}, tomwalters@0: { "axisleft_ps", OnOption, &axisleftstr, "Print tick-marks on left side", SilentOption}, tomwalters@0: { "axisright_ps", OnOption, &axisrightstr, "Print tick-marks on right side", SilentOption}, tomwalters@0: { "xmajorticks_ps", "1", &xmajorticksstr, "Relative *spacing* of ticks", SilentOption}, tomwalters@0: { "xminorticks_ps", "1", &xminorticksstr, "Relative *spacing* of ticks", SilentOption}, tomwalters@0: { "ymajorticks_ps", "1", &ymajorticksstr, "Relative *spacing* of ticks", SilentOption}, tomwalters@0: { "yminorticks_ps", "1", &yminorticksstr, "Relative *spacing* of ticks", SilentOption}, tomwalters@0: { "box_ps", OnOption, &boxstr, "Plot a box", SilentOption}, tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: /* File Output Parameters */ tomwalters@0: { "output", OffOption, &outstr, "Produce output file", InputOption}, tomwalters@0: { "header", OnOption, &headstr, "Add a header to the output file\n", InOutOption}, tomwalters@0: { "bytemax", "255", &bmaxstr, "Maximum value in byte output", SilentOption}, /* AJD 16-5-95 */ tomwalters@0: { "type", "short", &typestr, "Output data type\n", SilentOption}, /* AJD 16-5-95 */ tomwalters@0: tomwalters@0: { "input_wave", NullOption, &filestr, "Default input file name", InputOption}, tomwalters@0: { "start_wave", "0ms", &startstr, "Start point in wave (ms)", InputOption}, tomwalters@0: { "length_wave", LengthStr, &lengthstr, "Length of wave to process (ms)", InputOption}, tomwalters@0: tomwalters@0: ( char * ) 0 } ; tomwalters@0: tomwalters@0: tomwalters@0: /*********************** Included from stitch directory ********************/ tomwalters@0: tomwalters@0: /* interfaces to stitch system */ tomwalters@0: tomwalters@0: #include "stitch.h" tomwalters@0: #include "source.h" tomwalters@0: #include "spiral.h" tomwalters@0: #include "image.h" tomwalters@0: #include "model.h" tomwalters@0: #include "units.h" tomwalters@0: #include "calc.h" tomwalters@0: #include "ops.h" tomwalters@0: #include "io.h" tomwalters@0: tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: #include "draw.h" tomwalters@0: #include "fill.h" tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: /**************************************************************************/ tomwalters@0: tomwalters@0: char *AlterSuffix() ; /* alter suffix of file name. */ tomwalters@0: #ifdef X11 tomwalters@0: void save_frame(), plot_frame() ; /* draw callbacks. */ tomwalters@0: void fast_frame() ; tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: extern char *genstate() ; tomwalters@0: static char *gen_state ; tomwalters@0: tomwalters@0: Source DownChannel() ; /* reduce channels by averaging. */ tomwalters@0: #ifdef X11 tomwalters@0: Source PackShorts() ; /* pack output into one byte. */ tomwalters@0: #endif /* X11 */ tomwalters@0: Source checkForFile() ; /* create source from file if present. */ tomwalters@0: tomwalters@0: #define POSTSCRIPT_FILE_SUFFIX ".ps" tomwalters@0: #define CARTOON_FILE_SUFFIX ".ctn" tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: static WindowObject display = 0 ; tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: /***************************************************************************/ tomwalters@0: tomwalters@0: /* Return length of the file in bytes */ tomwalters@0: static long fileLength( fp ) tomwalters@0: FILE *fp ; tomwalters@0: { tomwalters@0: long posn = ftell( fp ) ; tomwalters@0: long length = 0 ; tomwalters@0: tomwalters@0: if( fseek( fp, 0l, 2 ) == 0 ) { tomwalters@0: tomwalters@0: length = ftell( fp ) ; tomwalters@0: tomwalters@0: (void) fseek( fp, posn, 0 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: return ( length ) ; tomwalters@0: } tomwalters@0: tomwalters@0: /* per frame image handling */ tomwalters@0: tomwalters@0: static FILE *inputFilePointer = ( FILE * ) 0 ; tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: tomwalters@0: static FILE *imageFilePointer = ( FILE * ) 0 ; tomwalters@0: static int images = 0 ; tomwalters@0: static void (*frame_drawer)() ; tomwalters@0: tomwalters@0: /***** axis information *****/ tomwalters@0: /* tomwalters@0: "Axis" is defined in windows.h:143 tomwalters@0: The postscript program for drawing axis stuff is in axis.h tomwalters@0: */ tomwalters@0: tomwalters@0: static int Top() tomwalters@0: { tomwalters@0: return ( atof( topstr ) / atof( magstr ) + 0.5 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: static int Bot() tomwalters@0: { tomwalters@0: if( atof( botstr ) < 0 ) tomwalters@0: return ( atof( botstr ) / atof( magstr ) - 0.5 ) ; tomwalters@0: else tomwalters@0: return ( atof( botstr ) / atof( magstr ) + 0.5 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: static struct { tomwalters@0: double min, max ; tomwalters@0: char *label ; tomwalters@0: } xaxis, yaxis ; tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: TimeAxis( min, max, label ) tomwalters@0: double *min, *max ; tomwalters@0: char **label ; tomwalters@0: { tomwalters@0: *min = Samples( startstr, Samplerate() ) / Samplerate() ; tomwalters@0: *max = Samples( startstr, Samplerate() ) / Samplerate() + Frames() * Framestep() / Samplerate() ; tomwalters@0: tomwalters@0: if( *max > 1. ) tomwalters@0: *label = "Time [s]" ; tomwalters@0: else { tomwalters@0: *label = "Time [ms]" ; tomwalters@0: tomwalters@0: *min *= 1000. ; tomwalters@0: *max *= 1000. ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: MagnitudeAxis( min, max, label ) tomwalters@0: double *min, *max ; tomwalters@0: char **label ; tomwalters@0: { tomwalters@0: *min = Bot() ; tomwalters@0: *max = Top() / ( 1. - atof( headstr ) / 100. ) ; tomwalters@0: tomwalters@0: *label = "Magnitude" ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: static void DrawAxes( win ) tomwalters@0: WindowObject win ; tomwalters@0: { tomwalters@0: /* frame window with axes */ tomwalters@0: tomwalters@0: Axes( win, titlestr, xaxis.min, xaxis.max, xaxis.label, tomwalters@0: yaxis.min, yaxis.max, yaxis.label ) ; tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: /******************************* main ************************************** tomwalters@0: * The following tables are used extensively: tomwalters@0: * stage table Arrays of _stage structs, ("envelope", "fine", etc.), defined tomwalters@0: * in routine FindStage() in model.c. tomwalters@0: * option table Array of Option structs built at run-time by tomwalters@0: * constructOptions() from displayopts, (in gen.c), and tables of tomwalters@0: * model options included from table.c. tomwalters@0: * tomwalters@0: * Compiler switches for model versions are: tomwalters@0: * FLOAT For floating point version, (default uses integer arithmetic). tomwalters@0: * Defined in calc.h. tomwalters@0: * tomwalters@0: * The model version number is the sccs . of tomwalters@0: * the file version.c. Refer to that file for incrementing the version number. tomwalters@0: * The version number is stored in versionstr in routine getversion(). tomwalters@0: ****************************************************************************/ tomwalters@0: tomwalters@0: int argc_save ; tomwalters@0: char **argv_save ; tomwalters@0: tomwalters@0: main( argc, argv ) tomwalters@0: int argc ; tomwalters@0: char *argv[] ; tomwalters@0: #ifdef THINK_C tomwalters@0: { tomwalters@0: static char *realargv[] = { "prog", "", 0 }; tomwalters@0: static char *progs = { "\pgenwav;-;\ tomwalters@0: genfbm;genfbr;genfbc;genfbt;genfbd;gensai;genspl;gensas;-;\ tomwalters@0: genbmm;gennap;gensai;-;gensgm;gencgm;gensas;-;genasa;genepn;gensep;-;Quit/Q" } ; tomwalters@0: tomwalters@0: extern char *MacMenu(), *MacFile() ; tomwalters@0: tomwalters@0: MacInit() ; tomwalters@0: tomwalters@0: realargv[0] = MacMenu(progs) ; tomwalters@0: realargv[1] = MacFile() ; tomwalters@0: tomwalters@0: return ( real_main( sizeof( realargv ) / sizeof (*realargv) - 1, realargv ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: real_main( argc, argv ) tomwalters@0: int argc ; tomwalters@0: char *argv[] ; tomwalters@0: #endif tomwalters@0: { tomwalters@0: int i ; tomwalters@0: FILE *ofp = 0 ; tomwalters@0: Source source ; tomwalters@0: char *which, *psfilename ; tomwalters@0: char title[256] ; tomwalters@0: char *programName ; tomwalters@0: int x, y, pixels, image, time ; tomwalters@0: long headerSize, fileFramebytes ; tomwalters@0: double *frequency_scale ; tomwalters@0: #ifdef X11 tomwalters@0: WindowObject psw = 0 ; tomwalters@0: char *imageFileName ; tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: /************************************************************************** tomwalters@0: * Determine which version of the model is required. tomwalters@0: * Set "which" to the last three chars of the program name, (allowing for tomwalters@0: * a ".exe" extension in the case of a PC version). tomwalters@0: **************************************************************************/ tomwalters@0: tomwalters@0: tomwalters@0: programName = argv[0] ; tomwalters@0: tomwalters@0: which = programName + strlen( programName ) - strlen( "xxx" ) ; tomwalters@0: tomwalters@0: #ifdef PC tomwalters@0: lowerArgs( argv, argc ) ; tomwalters@0: tomwalters@0: which -= strlen( ".exe" ) ; tomwalters@0: #endif tomwalters@0: tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * Process arguments, (the model options): tomwalters@0: * Set option defaults (from option table in model.c). tomwalters@0: * Then override these by any options in the options file, tomwalters@0: * (the resource control file, eg .gensairc). tomwalters@0: * Finally, override these by any options given as command-line arguments. tomwalters@0: * tomwalters@0: * offsetOptions() finds the first option, (a ptr to one line of the "res" tomwalters@0: * array), required by the program. This gives a place mark in the options tomwalters@0: * table. (Note that the bottom of the options table, a null, corresponds with tomwalters@0: * the top of the help menu). tomwalters@0: * This first option appropriate to the program is found by looking it up in tomwalters@0: * the stage table (in model.c), and then cross-referencing the option name tomwalters@0: * with the names in the options table. tomwalters@0: * tomwalters@0: * Here is an example of an option, showing the members of the Options struct: tomwalters@0: * name: defaultValue: value: comment: classification: tomwalters@0: * {"length_wave", LengthStr, &lengthstr, "Length of wave", InputOption}, tomwalters@0: * tomwalters@0: * getopts() operates on the options between the given place mark and the tomwalters@0: * bottom of the table. tomwalters@0: * This is the only call to routine getopts(), which is defined in options.c. tomwalters@0: * First, each "value" is set to its corresponding "defaultvalue". tomwalters@0: * Then the options file (the "rc" file) is opened, and any options found there tomwalters@0: * are assigned to the corresponding "value", (overriding the "defaultvalue"). tomwalters@0: * Then the command-line arguments are examined, and any options found there tomwalters@0: * are assigned to the corresponding "value", (overriding again). tomwalters@0: * Special arguments are dealt with: tomwalters@0: * "help" calls the onLineHelpHandler() routine, (see below). tomwalters@0: * "update" calls the updateOptionsFile() routine. tomwalters@0: * tomwalters@0: * Finally, leave the remainder of the command line (argc and argv). tomwalters@0: * Anything left on the command line is interpreted as follows: tomwalters@0: * "filestr" is the input data filename, tomwalters@0: * "startstr" is the start point in the data, tomwalters@0: * "lengthstr" is the amount of data to process, tomwalters@0: * "whichstr" is the last 3 chars of the program name (the program version). tomwalters@0: * tomwalters@0: * Note that if no input file has been found by getopts(), (in the "rc" file), tomwalters@0: * and none remains on the command line, then helpopts() is called. tomwalters@0: * This is an alias for the onLineHelpHandler() function, which is in turn an tomwalters@0: * alias for the defaultHelpHandler() routine, (see options.c). tomwalters@0: * tomwalters@0: * tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: getversion( programName ) ; tomwalters@0: tomwalters@0: /* The helpstring, defined in model.c, is stored as the comment field */ tomwalters@0: /* of the help option (see table.c). It is accessed in options.c in */ tomwalters@0: /* defaultHelpHandler(), using options[help].comment. */ tomwalters@0: tomwalters@0: (void) sprintf( helpstring, " [file_name]\n Generates %s", modelHelp( which ) ) ; tomwalters@0: tomwalters@0: options = constructOptions( which, displayopts ) ; tomwalters@0: tomwalters@0: tomwalters@0: /* Hack to save argc and argv so they don't get mangled by getopts */ tomwalters@0: /* This is so the command line args can override a reused file header */ tomwalters@0: tomwalters@0: argc_save = argc ; tomwalters@0: argv_save = (char **)malloc( ( argc + 1 ) * sizeof( char *) ) ; tomwalters@0: for ( i = 0 ; i < argc ; i++ ) { tomwalters@0: argv_save[i] = (char *)malloc( ( strlen( argv[i] ) + 1 ) * sizeof( char ) ) ; tomwalters@0: strcpy( argv_save[i], argv[i] ) ; tomwalters@0: } tomwalters@0: tomwalters@0: getopts( options, &argc, &argv ) ; tomwalters@0: tomwalters@0: if( argc == 0 && isNULL( filestr ) ) { tomwalters@0: (void) helpopts( options, programName ) ; tomwalters@0: stitch_exit( -1 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: if( argc > 0 && strcmp( *argv, "+" ) != 0 && argc-- > 0 ) tomwalters@0: filestr = *argv++ ; tomwalters@0: tomwalters@0: if( argc > 0 && strcmp( *argv, "+" ) != 0 && argc-- > 0 ) tomwalters@0: startstr = *argv++ ; tomwalters@0: tomwalters@0: if( argc > 0 && strcmp( *argv, "+" ) != 0 && argc-- > 0 ) tomwalters@0: lengthstr = *argv++ ; tomwalters@0: tomwalters@0: if( isNULL( whichstr ) ) tomwalters@0: whichstr = which ; tomwalters@0: tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * horrrrrrrrible hack for now to try out -envelope option tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: if( isON( envstr ) ) tomwalters@0: if( whichstr[1] == 'b' ) tomwalters@0: whichstr[1] = 'e' ; tomwalters@0: else { tomwalters@0: /* map sai to sie and sas to sse */ tomwalters@0: tomwalters@0: whichstr[1] = whichstr[2] ; tomwalters@0: whichstr[2] = 'e' ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * hack test arguments tomwalters@0: ***************************************************************************/ tomwalters@0: #if 00 tomwalters@0: test1 = atof( test1str ) ; tomwalters@0: test2 = atof( test2str ) ; tomwalters@0: test3 = atof( test3str ) ; tomwalters@0: test4 = atof( test4str ) ; tomwalters@0: #endif tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * Open input data file, (use stdin if filename "-" is given). tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: if( strcmp( filestr, "-" ) == 0 ) tomwalters@0: inputFilePointer = stdin ; tomwalters@0: else tomwalters@0: inputFilePointer = fopen( filestr, readBinary ) ; tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * Position input data file pointer correctly: tomwalters@0: * Read any options header at the start of the input file. Set any options. tomwalters@0: * Skip to the start of the input data, allowing for any offset (ie startstr). tomwalters@0: * Set "framesstr" to the number of frames in the input data file, (here this tomwalters@0: * means the number of shorts remaining in the input file). tomwalters@0: * Create a source for the input data file. tomwalters@0: * Re-set "framesstr" to allow for a given "lengthstr", (ie not the whole file). tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: if( inputFilePointer != (FILE *) 0 ) { tomwalters@0: tomwalters@0: readopts( options, inputFilePointer ) ; tomwalters@0: tomwalters@0: headerSize = ftell( inputFilePointer ) ; tomwalters@0: tomwalters@0: setFrames( fileLength( inputFilePointer ) / sizeof ( short ) - (long) Samples( startstr, Samplerate() ) ) ; tomwalters@0: tomwalters@0: (void) fseek( inputFilePointer, (long)( headerSize + (long) Samples( startstr, Samplerate() ) * sizeof ( short ) ), 0 ) ; tomwalters@0: tomwalters@0: source = FileSource( inputFilePointer ) ; tomwalters@0: } tomwalters@0: tomwalters@0: /* If a specific processing amount is specifed (other than "remainder") */ tomwalters@0: /* and this amount is less than the remainder of the input file, then */ tomwalters@0: /* override the amount of data to process, (in framesstr). */ tomwalters@0: tomwalters@0: if ( strncmp( lengthstr, LengthStr, strlen(lengthstr) ) != 0 && tomwalters@0: Samples( lengthstr, Samplerate() ) < Frames() ) tomwalters@0: setFrames( (long) ( Samples( lengthstr, Samplerate() ) ) / Framestep() ) ; tomwalters@0: tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * Create source with data derived from processing file through model. tomwalters@0: * This may involve several stages of callback, and will initialize a chain of tomwalters@0: * objects which will ultimately execute the program, (see SinkSource() below). tomwalters@0: * If reusestr in "on", the "useprevious" option will use a previously tomwalters@0: * generated file, (see checkForFile() routine below). tomwalters@0: * If no input data file is found, report error: "could not open file". tomwalters@0: * tomwalters@0: * The routine ModeledSource() first uses Findstage() to find the appropriate tomwalters@0: * place in the stage table called for by the program, (see model.c). tomwalters@0: * Then it finds the end of the stage table, and works back up the table to tomwalters@0: * the stage called for by the program. Each stage in the table is a process tomwalters@0: * on the way to the program as a whole. The order of the stage table sets the tomwalters@0: * order of processing. tomwalters@0: * Immediately below are the only two calls to routine ModeledSource(). tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: if( isON( reusestr ) ) tomwalters@0: source = ModeledSource( source, checkForFile ) ; tomwalters@0: else tomwalters@0: if( inputFilePointer != (FILE *) 0 ) tomwalters@0: source = ModeledSource( source, (Source ( * )()) 0 ) ; tomwalters@0: tomwalters@0: if( inputFilePointer == (FILE *) 0 ) tomwalters@0: stitch_error( "Could not open file \"%s\" for input\n", filestr ) ; tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * If the "downchannel" option is on, reduce channels by averaging. tomwalters@0: * (See DownChannel() routine below). tomwalters@0: * Then updateFramebytes sets "framebytesstr" to the total number of bytes tomwalters@0: * in each frame, (ie the new width * height). tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: tomwalters@0: for( time=0 ; time 1 ) tomwalters@0: tomwalters@0: pixels = -abs( pixels ) ; tomwalters@0: tomwalters@0: /* Convert arguments for line-drawing. See draw.ch */ tomwalters@0: drawTilt = atof( tiltstr ) ; tomwalters@0: drawDistance = atof( diststr ) ; tomwalters@0: drawHeadroom = atof( roomstr ) ; tomwalters@0: drawOverlap = atof( overstr ) / 100. ; tomwalters@0: #ifdef mips tomwalters@0: if( pixels == 0 ) tomwalters@0: pixels = 1 ; tomwalters@0: #endif tomwalters@0: } tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: /* work out title of output */ tomwalters@0: tomwalters@0: (void) strcpy( title, filestr ) ; tomwalters@0: (void) strcat( title, "." ) ; tomwalters@0: (void) strncat( title, whichstr, strlen( "xxx" )+1 ) ; tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: tomwalters@0: if( strcmp(titlestr,"filename") == 0) /* was: if(isNULL(titlestr)) */ tomwalters@0: titlestr = title ; tomwalters@0: tomwalters@0: /* calculate axis information */ tomwalters@0: tomwalters@0: if( isEXCITE( viewstr ) ) { tomwalters@0: ChannelAxis( &xaxis.min, &xaxis.max, &xaxis.label ) ; tomwalters@0: MagnitudeAxis( &yaxis.min, &yaxis.max, &yaxis.label ) ; tomwalters@0: } tomwalters@0: else if( isWATERFALL( viewstr ) ) { tomwalters@0: ChannelAxis( &xaxis.min, &xaxis.max, &xaxis.label ) ; tomwalters@0: TimeAxis( &yaxis.min, &yaxis.max, &yaxis.label ) ; tomwalters@0: } /* landscape ones */ tomwalters@0: else if( Framewidth() > 1 ) { tomwalters@0: DelayAxis( &xaxis.min, &xaxis.max, &xaxis.label ) ; tomwalters@0: ChannelAxis( &yaxis.min, &yaxis.max, &yaxis.label ) ; tomwalters@0: } tomwalters@0: else { tomwalters@0: TimeAxis( &xaxis.min, &xaxis.max, &xaxis.label ) ; tomwalters@0: tomwalters@0: if( Frameheight() > 1 ) tomwalters@0: ChannelAxis( &yaxis.min, &yaxis.max, &yaxis.label ) ; tomwalters@0: else tomwalters@0: MagnitudeAxis( &yaxis.min, &yaxis.max, &yaxis.label ) ; tomwalters@0: tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* select outputs... */ tomwalters@0: tomwalters@0: tomwalters@0: /* select sai drawing method */ tomwalters@0: tomwalters@0: /* Hack so spiral parameters are independent of stage and option order */ tomwalters@0: /* (Spiral parameters appear late in options list, so are not known */ tomwalters@0: /* when an earlier stage is specified. So don't process unless sai). */ tomwalters@0: tomwalters@0: if( strncmp(whichstr,"spl",strlen("spl")) == 0 ) { tomwalters@0: tomwalters@0: frame_drawer = draw_spiral; tomwalters@0: tomwalters@0: dotthresh_spl = Top() ; tomwalters@0: dotsize_spl = OptionInt( penstr ) ; tomwalters@0: } tomwalters@0: else tomwalters@0: frame_drawer = draw_frame; tomwalters@0: tomwalters@0: /* screen output first */ tomwalters@0: /* (set by option: display=on) */ tomwalters@0: tomwalters@0: if( isON( dispstr ) ) { tomwalters@0: tomwalters@0: display = newDisplayWindow( titlestr, x, y, atoi( widthstr ), atoi( heightstr ), pixels ) ; tomwalters@0: tomwalters@0: if( !isGREYSCALE( viewstr ) /* && OptionInt( penstr ) != 0 */ ) { tomwalters@0: tomwalters@0: if( Top() == Bot() ) tomwalters@0: stitch_error( "error: display top and bottom parameters the same value\n" ); tomwalters@0: tomwalters@0: if( isEXCITE( viewstr ) ) tomwalters@0: source = SourceDraw( source, Bot(), Top(), display, Frameheight(), 1, Nwidth(), Frames(), save_frame, frame_drawer ) ; tomwalters@0: else if( isWATERFALL( viewstr ) ) tomwalters@0: source = SourceDraw( source, Bot(), Top(), display, Frameheight(), Frames(), Nwidth(), 1, save_frame, frame_drawer ) ; tomwalters@0: else if( !isON( kludgestr ) ) tomwalters@0: source = SourceDraw( source, Bot(), Top(), display, Framewidth(), Frameheight(), Nwidth(), Frames(), save_frame, frame_drawer ) ; tomwalters@0: else { /* speed-up for sai */ tomwalters@0: source = SourceDraw( source, Bot(), Top(), display, Framewidth(), Frameheight(), Nwidth(), Frames(), save_frame, fast_frame ) ; tomwalters@0: gen_state = genstate( display, Bot(), Top(), Framewidth(), Frameheight(), Nwidth(), Frames(), pixels ) ; tomwalters@0: frame_drawer=fast_frame ; tomwalters@0: } tomwalters@0: } tomwalters@0: else { tomwalters@0: if( isON( erasestr ) ) tomwalters@0: Clear( display ) ; tomwalters@0: tomwalters@0: DrawAxes( display ) ; tomwalters@0: tomwalters@0: if( isON( linstr ) ) tomwalters@0: frequency_scale = frequencies ; tomwalters@0: else tomwalters@0: frequency_scale = (double *) 0 ; tomwalters@0: tomwalters@0: if( Framewidth() > 1 ) tomwalters@0: source = FillDown( display, source, Top(), Bot(), Framewidth(), Frameheight() ) ; tomwalters@0: else tomwalters@0: source = fillAcross( display, source, Top(), Bot(), Frameheight(),(int)Frames(), frequency_scale ) ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: /* postscript output next */ tomwalters@0: /* (set by option: postscript=on) */ tomwalters@0: tomwalters@0: if( isON( psstr ) ) { tomwalters@0: tomwalters@0: if( isON( psfilestr ) ) tomwalters@0: psfilename = AlterSuffix( filestr, POSTSCRIPT_FILE_SUFFIX ) ; tomwalters@0: else tomwalters@0: psfilename = (char *) 0 ; tomwalters@0: tomwalters@0: /* the extra argument to newPSWindow. MAA> 27-1-1993. */ tomwalters@0: psw = newPSWindow( psfilename, x, y, atoi(widthstr), atoi(heightstr), atoi( penstr ), isON( hiddenstr ) ); tomwalters@0: tomwalters@0: if( !isGREYSCALE( viewstr ) && OptionInt( penstr ) != 0 ) { tomwalters@0: tomwalters@0: if( isEXCITE( viewstr ) ) tomwalters@0: source = SourceDraw( source, Bot(), Top(), psw, Frameheight(), 1, Nwidth(), Frames(), plot_frame, frame_drawer ) ; tomwalters@0: else if( isWATERFALL( viewstr ) ) tomwalters@0: source = SourceDraw( source, Bot(), Top(), psw, Frameheight(), Frames(), Nwidth(), 1, plot_frame, frame_drawer ) ; tomwalters@0: else tomwalters@0: source = SourceDraw( source, Bot(), Top(), psw, Framewidth(), Frameheight(), Nwidth(), Frames(), plot_frame, frame_drawer ) ; tomwalters@0: } tomwalters@0: else { /* greyscale displays */ tomwalters@0: tomwalters@0: if( isON( erasestr ) ) tomwalters@0: Clear( psw ) ; tomwalters@0: tomwalters@0: DrawAxes( psw ) ; tomwalters@0: tomwalters@0: if( isON( linstr ) ) tomwalters@0: frequency_scale = frequencies ; tomwalters@0: else tomwalters@0: frequency_scale = (double *) 0 ; tomwalters@0: tomwalters@0: if( Framewidth() > 1 ) tomwalters@0: source = FillDown( psw, source, Top(), Bot(), Framewidth(), Frameheight() ) ; tomwalters@0: else tomwalters@0: source = fillAcross( psw, source, Top(), Bot(), Frameheight(),(int)Frames(), frequency_scale ) ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: if( strcmp( typestr, "char" ) == 0 ) { tomwalters@0: source = PackShorts( source ) ; tomwalters@0: fileFramebytes = Framebytes() / sizeof ( short ) * sizeof ( char ) ; tomwalters@0: } tomwalters@0: else tomwalters@0: tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: fileFramebytes = Framebytes() ; tomwalters@0: tomwalters@0: /* output to file */ tomwalters@0: tomwalters@0: if( !isOFF( outstr ) ) { tomwalters@0: tomwalters@0: (void) unlink( title ) ; tomwalters@0: tomwalters@0: if( OptionStringsEqual( outstr, OnOption ) ) tomwalters@0: ofp = fopen( title, writeBinary ) ; tomwalters@0: else { tomwalters@0: if( strcmp( outstr, "stdout" ) == 0 ) tomwalters@0: ofp = stdout; tomwalters@0: else tomwalters@0: ofp = fopen( outstr, writeBinary ) ; tomwalters@0: } tomwalters@0: tomwalters@0: if( ofp == (FILE *) 0 ) tomwalters@0: stitch_error( "Unable to open file %s for output\n", title ) ; tomwalters@0: else { tomwalters@0: if( isON( headstr ) ) tomwalters@0: writeopts( options, ofp ) ; tomwalters@0: tomwalters@0: source = FileTap( source, ofp ) ; tomwalters@0: } tomwalters@0: } tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: tomwalters@0: /* output of screen "image" files in display format */ tomwalters@0: if( !isOFF( bitmapstr ) ) { tomwalters@0: imageFileName = AlterSuffix(filestr, CARTOON_FILE_SUFFIX ) ; tomwalters@0: tomwalters@0: if( (strcmp( bitmapstr, "stdout" ) == 0 )){ tomwalters@0: imageFilePointer = stdout; tomwalters@0: writeopts( options, imageFilePointer ) ;} tomwalters@0: else tomwalters@0: if ( ( imageFilePointer = fopen(imageFileName, writeBinary ) ) == (FILE *) 0) tomwalters@0: stitch_error( "Unable to open file %s for image output\n", imageFileName ) ; tomwalters@0: else tomwalters@0: writeopts( options, imageFilePointer ) ;} tomwalters@0: tomwalters@0: if (( ofp == stdout ) && ( imageFilePointer == stdout )) tomwalters@0: stitch_error( "Both 'output' and 'bitmap' set to stdout.\n", title); tomwalters@0: tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * Execute the program by pulling data from the source. tomwalters@0: * This is the only call to routine SinkSource(), which is defined in tomwalters@0: * stitch/source.c as sinkSource(). tomwalters@0: * (SinkSource is an alias, defined in stitch/source.h, to cast the arguments). tomwalters@0: * Routine sinkSource() executes: "(void) Pull( source, fileFramebytes ) ;" tomwalters@0: * for "Frames()" times in succession. tomwalters@0: * A chain of source objects, linked by callback-function pointers, was setup tomwalters@0: * earlier, (see call to ModeledSource() above). tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: tomwalters@0: SinkSource( source, fileFramebytes, Frames() ) ; tomwalters@0: tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * Clean up and close tomwalters@0: ****************************************************************************/ tomwalters@0: tomwalters@0: CloseSource( source ) ; tomwalters@0: tomwalters@0: if( ofp != (FILE *) 0 ) tomwalters@0: (void) fclose( ofp ) ; tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: tomwalters@0: if( psw != (WindowObject) 0 ) tomwalters@0: Close( psw ) ; tomwalters@0: tomwalters@0: if( display != (WindowObject) 0 ) { tomwalters@0: tomwalters@0: /* animate sai's if selected */ tomwalters@0: tomwalters@0: do tomwalters@0: { tomwalters@0: for( image=1 ; image <= images ; image++ ) tomwalters@0: for( time = OptionInt( animstr ) ; time>0 ; time-- ) tomwalters@0: Recall( display, image ) ; tomwalters@0: tomwalters@0: if( Pause( display ) == 'q' ) tomwalters@0: break; tomwalters@0: tomwalters@0: } while( isON( animstr ) ) ; tomwalters@0: tomwalters@0: Close( display ) ; tomwalters@0: } tomwalters@0: tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: stitch_exit( 0 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: /*************************** End main *************************************/ tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * checkForFile() tomwalters@0: * Create source from file if present, to be used if reusestr in "on". tomwalters@0: * This is the "useprevious" option to use previously generated files. tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: Source checkForFile( which ) tomwalters@0: char *which ; tomwalters@0: { tomwalters@0: static Source noSource = { (struct _source *) 0 } ; tomwalters@0: long headerSize, fileFramebytes ; tomwalters@0: char file_name[200] ; tomwalters@0: FILE *tmp ; tomwalters@0: tomwalters@0: (void) strcpy( file_name, filestr ) ; tomwalters@0: (void) strcat( file_name, "." ) ; tomwalters@0: (void) strcat( file_name, which ) ; tomwalters@0: tomwalters@0: if( ( tmp = fopen( file_name, readBinary ) ) != ( FILE * ) 0 ) { tomwalters@0: tomwalters@0: inputFilePointer = tmp ; tomwalters@0: tomwalters@0: (void) fprintf( stderr, "Using existing file \"%s\"\n", file_name ) ; tomwalters@0: tomwalters@0: readopts( options, inputFilePointer ) ; tomwalters@0: tomwalters@0: /* the saved command line overrides options from file header */ tomwalters@0: tomwalters@0: if( isON( reusestr ) ) tomwalters@0: cmd_line_opts( options, &argc_save, &argv_save ) ; tomwalters@0: tomwalters@0: headerSize = ftell( inputFilePointer ) ; tomwalters@0: tomwalters@0: if( strcmp( typestr, "char" ) == 0 ) tomwalters@0: fileFramebytes = Framebytes() / 2 ; tomwalters@0: else tomwalters@0: fileFramebytes = Framebytes() ; tomwalters@0: tomwalters@0: /* tomwalters@0: If length=remainder then use the whole file. tomwalters@0: Otherwise the length of the reused file is that given on the command tomwalters@0: line, or the default length (if no length option is given). tomwalters@0: */ tomwalters@0: tomwalters@0: if ( strncmp( lengthstr, LengthStr, strlen(lengthstr) ) == 0 ) tomwalters@0: setFrames( ( fileLength( inputFilePointer ) - headerSize ) / fileFramebytes - (long) Samples( startstr, Samplerate() ) / Framestep() ) ; tomwalters@0: else tomwalters@0: setFrames( (long) ( Samples( lengthstr, Samplerate() ) ) / Framestep() ) ; tomwalters@0: tomwalters@0: tomwalters@0: (void) fseek( inputFilePointer, headerSize + (long) Samples( startstr, Samplerate() ) / Framestep() * fileFramebytes, 0 ) ; tomwalters@0: tomwalters@0: #ifndef PC tomwalters@0: if( strcmp( typestr, "char" ) == 0 ) tomwalters@0: return( CharShortSource( FileSource( inputFilePointer ) ) ) ; tomwalters@0: else tomwalters@0: #endif tomwalters@0: return( FileSource( inputFilePointer ) ) ; tomwalters@0: } tomwalters@0: else tomwalters@0: return( noSource ) ; tomwalters@0: } tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * AlterSuffix(). tomwalters@0: * Returns its argument fileName with a newSuffix appended in place of tomwalters@0: * any previous suffix it may have had. It should be noted that this tomwalters@0: * suffix must include any DOT it wishes to have appended to the name. tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: /* File Name Suffix Conversion Parameters */ tomwalters@0: tomwalters@0: #define BACKSLASH_CHAR '\\' tomwalters@0: #define SLASH_CHARACTER '/' tomwalters@0: #define NULL_CHARACTER '\000' tomwalters@0: #define DOT_CHARACTER '.' tomwalters@0: tomwalters@0: char *AlterSuffix(fileName, newSuffix) tomwalters@0: char *fileName, *newSuffix; tomwalters@0: { tomwalters@0: char *temp, *temp2, *lastPart; tomwalters@0: #if defined( PC ) tomwalters@0: int i; tomwalters@0: #endif tomwalters@0: tomwalters@0: temp = stitch_malloc((unsigned) (strlen(fileName) + strlen(newSuffix) + 1), "AlterSuffix" ); tomwalters@0: tomwalters@0: temp = strcpy(temp, fileName); tomwalters@0: tomwalters@0: #if defined(PC) tomwalters@0: /* Change all backslashes to forward slashes */ tomwalters@0: for (i = 0; temp[i] != NULL_CHARACTER; i++) tomwalters@0: if (temp[i] == BACKSLASH_CHAR) tomwalters@0: temp[i] = SLASH_CHARACTER; tomwalters@0: #endif tomwalters@0: tomwalters@0: if ((lastPart = strrchr(temp, SLASH_CHARACTER)) == NULL) tomwalters@0: lastPart = temp; tomwalters@0: else tomwalters@0: lastPart++; /* Skip over the actual "/" */ tomwalters@0: tomwalters@0: /* lastPart points to the tail name of the path */ tomwalters@0: tomwalters@0: if ((temp2 = strchr(lastPart, DOT_CHARACTER)) == NULL) tomwalters@0: temp = strcat(temp, newSuffix); tomwalters@0: else tomwalters@0: temp2 = strcpy(temp2, newSuffix); tomwalters@0: tomwalters@0: return (temp); tomwalters@0: } tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * Interceptions for various combinations of drawing. tomwalters@0: * An "interception function" is a function inserted into a chain a functions tomwalters@0: * linked by function pointers. The inserted function "intercepts" the tomwalters@0: * processing, to perform some transformation. tomwalters@0: ****************************************************************************/ tomwalters@0: tomwalters@0: /* intercept draw to store images for animation */ tomwalters@0: tomwalters@0: void save_frame( state, frame, first ) tomwalters@0: struct _draw_state *state ; tomwalters@0: short *frame ; tomwalters@0: int first ; tomwalters@0: { tomwalters@0: if( first ) { tomwalters@0: if( isON( erasestr ) ) tomwalters@0: Clear( state->window ) ; tomwalters@0: tomwalters@0: if( frame_drawer != (void (*)()) draw_spiral && state->framenumber == 1 ) tomwalters@0: DrawAxes( state->window ) ; tomwalters@0: } tomwalters@0: tomwalters@0: frame_drawer( state, frame ) ; tomwalters@0: tomwalters@0: if( isON( animstr ) && isOFF( kludgestr ) ) tomwalters@0: if( Store( state->window ) ) tomwalters@0: ++images ; tomwalters@0: tomwalters@0: if( isON( bitmapstr ) ) tomwalters@0: Write( state->window, imageFilePointer ) ; tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: /* hacky but effective faster frame drawing routine - for sai only! */ tomwalters@0: tomwalters@0: void fast_frame( state, frame, first ) tomwalters@0: struct _draw_state *state ; tomwalters@0: short *frame ; tomwalters@0: int first ; tomwalters@0: { tomwalters@0: if( isON( animstr ) || images == 0 ) tomwalters@0: if( Store( state->window ) ) tomwalters@0: ++images ; tomwalters@0: tomwalters@0: /* generate image in current cleared image */ tomwalters@0: tomwalters@0: generate( gen_state, frame ) ; tomwalters@0: tomwalters@0: /* then recal the window using the modified image */ tomwalters@0: tomwalters@0: Recall( state->window, images ); tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: /* intercept plot to check if page should be output for printing */ tomwalters@0: tomwalters@0: static int plot_wanted( state ) tomwalters@0: struct _draw_state *state ; tomwalters@0: { tomwalters@0: #if !defined(PC) tomwalters@0: if( display != ( WindowObject ) 0 && state->framewidth > 1 && state->frames > 1 ) { tomwalters@0: (void) fprintf(stderr, "Hit \"y\" to include this image in the PostScript file: "); tomwalters@0: tomwalters@0: switch ( Pause( display ) ) { tomwalters@0: tomwalters@0: case 'y' : case 'Y' : tomwalters@0: case 'p' : case 'P' : tomwalters@0: return 1 ; tomwalters@0: tomwalters@0: default : tomwalters@0: return 0 ; tomwalters@0: } tomwalters@0: } tomwalters@0: #endif tomwalters@0: return 1 ; tomwalters@0: } tomwalters@0: tomwalters@0: void plot_frame( state, frame, first ) tomwalters@0: struct _draw_state *state ; tomwalters@0: short *frame ; tomwalters@0: int first ; tomwalters@0: { tomwalters@0: int centering = state->window->entries->x( state->window ) < 0 && tomwalters@0: state->window->entries->y( state->window ) < 0 ; tomwalters@0: tomwalters@0: if( isOFF( erasestr ) || state->framewidth == 1 || plot_wanted( state ) ) { tomwalters@0: tomwalters@0: if( first && ( state->framenumber == 1 || isON( erasestr ) ) ) { tomwalters@0: /* *** if( centering ) *** removed the conditional. M.Akeroyd. 22-1-1993.*/ tomwalters@0: Clear( state->window ) ; tomwalters@0: tomwalters@0: if( frame_drawer != (void (*)()) draw_spiral ) tomwalters@0: DrawAxes( state->window ) ; tomwalters@0: } tomwalters@0: tomwalters@0: frame_drawer( state, frame ) ; tomwalters@0: } tomwalters@0: tomwalters@0: return ; tomwalters@0: } tomwalters@0: tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * downchannel: average across channels for output (with special sai version) tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: struct _down_channel_state { tomwalters@0: struct _fillable_source parent ; tomwalters@0: int channels ; tomwalters@0: Source input ; tomwalters@0: } ; tomwalters@0: tomwalters@0: tomwalters@0: static Pointer down_channel_callback( state, bytes, buffer ) tomwalters@0: struct _down_channel_state *state ; tomwalters@0: ByteCount *bytes ; tomwalters@0: short *buffer ; tomwalters@0: { tomwalters@0: register int last = *bytes == 0 ; tomwalters@0: register int chan, outchans = state->channels >> 1 ; tomwalters@0: long frame, frames = ToPoints( short, *bytes ) / outchans ; tomwalters@0: register short *iptr = PullItems( state->input, frames * state->channels, short ) ; tomwalters@0: register short *bptr = buffer ; tomwalters@0: tomwalters@0: for( frame=0 ; framechannels ) tomwalters@0: iptr++ ; tomwalters@0: } tomwalters@0: tomwalters@0: if( !last ) tomwalters@0: return ( (Pointer) buffer ) ; tomwalters@0: else tomwalters@0: return ( DeleteFillableSource( state ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: static Pointer down_channel_callback_sai( state, bytes, buffer ) tomwalters@0: struct _down_channel_state *state ; tomwalters@0: ByteCount *bytes ; tomwalters@0: short *buffer ; tomwalters@0: { tomwalters@0: register int last = *bytes == 0 ; tomwalters@0: register int chan, outchans = state->channels >> 1 ; tomwalters@0: long frame, frames = ToPoints( short, *bytes ) / outchans ; tomwalters@0: register short *iptr = PullItems( state->input, frames * state->channels, short ) ; tomwalters@0: register short *bptr = buffer ; tomwalters@0: register short *iptr2 ; tomwalters@0: tomwalters@0: iptr2 = iptr + frames ; tomwalters@0: for( chan=0 ; chanchannels = channels ; tomwalters@0: state->input = source ; tomwalters@0: tomwalters@0: tomwalters@0: /* Hack for special-case downchannel routine to handle format of sai and spl frames (mha: 22/6/93) */ tomwalters@0: tomwalters@0: if( strncmp(whichstr,"sai",strlen("sai")) == 0 || tomwalters@0: strncmp(whichstr,"spl",strlen("spl")) == 0 ) tomwalters@0: tomwalters@0: return ( SetFillableSource( state, down_channel_callback_sai, "down channeling sai frames" ) ) ; tomwalters@0: tomwalters@0: return ( SetFillableSource( state, down_channel_callback, "down channeling" ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: #ifdef X11 tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * Pack model output onto a single byte if required, tomwalters@0: * using greyscale Top() from display. tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: typedef struct { struct _fillable_source parent ; Source input ; } *PackSource ; tomwalters@0: tomwalters@0: static Pointer pack_callback( state, bytes, buffer ) tomwalters@0: PackSource state ; tomwalters@0: ByteCount *bytes ; tomwalters@0: Pointer buffer ; tomwalters@0: { tomwalters@0: register int last = *bytes == 0 ; tomwalters@0: register short *iptr = PullShorts( state->input, *bytes ) ; tomwalters@0: register Pointer optr = buffer ; tomwalters@0: register Pointer eptr = buffer + *bytes ; tomwalters@0: register int bytemax = atoi( bmaxstr ) ; tomwalters@0: register int max = Top() ; tomwalters@0: register int min = Bot() ; tomwalters@0: tomwalters@0: while( optr < eptr ) tomwalters@0: if( *iptr > max ) { tomwalters@0: *optr++ = bytemax ; tomwalters@0: iptr++ ; tomwalters@0: } tomwalters@0: else if( *iptr < min ) { tomwalters@0: *optr++ = 0 ; tomwalters@0: iptr++ ; tomwalters@0: } tomwalters@0: else tomwalters@0: *optr++ = ( ( ( *iptr++ - min ) * bytemax + ( bytemax >> 1 ) ) / ( max - min ) ) & 0xff ; tomwalters@0: tomwalters@0: if( !last ) tomwalters@0: return ( buffer ) ; tomwalters@0: else tomwalters@0: return ( DeleteFillableSource( state ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: Source PackShorts( input ) tomwalters@0: Source input ; tomwalters@0: { tomwalters@0: DeclareNew( PackSource, source ) ; tomwalters@0: tomwalters@0: source->input = input ; tomwalters@0: tomwalters@0: return ( SetFillableSource( source, pack_callback, "gen.c packing" ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: #endif /* X11 */ tomwalters@0: tomwalters@0: /***************************************************************************/ tomwalters@0: tomwalters@0: #ifdef PC tomwalters@0: static lowerArgs( argv, argc ) tomwalters@0: char **argv ; tomwalters@0: int argc ; tomwalters@0: { tomwalters@0: register char *ptr ; tomwalters@0: register int arg ; tomwalters@0: tomwalters@0: for( arg=0 ; arg<=argc ; arg++ ) tomwalters@0: for( ptr=argv[arg] ; *ptr != '\000' ; ptr++ ) tomwalters@0: if( isupper( *ptr ) ) tomwalters@0: *ptr = tolower( (int) *ptr ) ; tomwalters@0: return ; tomwalters@0: } tomwalters@0: #endif tomwalters@0: tomwalters@0: tomwalters@0: /*************************************************************************** tomwalters@0: * Set the value of versionstr to the model version number and current time. tomwalters@0: * The version number is the sccs . of the file tomwalters@0: * version.c. The current time is returned by ctime(time(0)). tomwalters@0: * This routine initializes the default version-string (headerstr), which is tomwalters@0: * later copied into the version-string (versionstr) during getopts(). tomwalters@0: * In this way, the version-string is available for output at the head of tomwalters@0: * the help and the options (rc) files, and also output as part of the header, tomwalters@0: * (when output=on). tomwalters@0: * Note, the versionstr has to be quoted, otherwise the routine tomwalters@0: * processOptionFile in options.c will report an error (Detected Trailing...) tomwalters@0: * when it finds blanks within a line. This happens when trying to read an tomwalters@0: * options file, for example when reviewing. The addition of quotes enables tomwalters@0: * a line containing blanks to be read complete by the subroutine getName. tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: #include "version.c" tomwalters@0: tomwalters@0: getversion( name ) tomwalters@0: char *name ; tomwalters@0: { tomwalters@0: char releasestr[8] ; tomwalters@0: char levelstr[8] ; tomwalters@0: char timestr[32] ; tomwalters@0: char *namestr ; tomwalters@0: long int timeval ; tomwalters@0: tomwalters@0: sprintf(releasestr, "%d", atoi( version_Id ) ) ; tomwalters@0: sprintf(levelstr, "%d", atoi( version_Id + strlen(releasestr) + 1 ) ) ; tomwalters@0: tomwalters@0: if ( ( namestr = strrchr( name, '/' ) ) == (char *)0 ) namestr = name ; tomwalters@0: else namestr++ ; tomwalters@0: tomwalters@0: #if defined( PC ) || defined( THINK_C ) tomwalters@0: sprintf(headerstr, "\"AIM MRC-APU Release R%s.%s [%s]\"", releasestr, levelstr, namestr ) ; tomwalters@0: #else tomwalters@0: timeval = time(0); tomwalters@0: sprintf(timestr,"%s", ctime(&timeval) ) ; tomwalters@0: timestr[strlen(timestr) - 1] = '\0'; /* remove newline */ tomwalters@0: sprintf(headerstr, "\"AIM MRC-APU Release R%s.%s [%s] %s\"", releasestr, levelstr, namestr, timestr ) ; tomwalters@0: #endif tomwalters@0: tomwalters@0: }