home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 375.lha / HAM-E_DEV_PACKAGE / hame.c < prev    next >
C/C++ Source or Header  |  1990-05-02  |  58KB  |  1,971 lines

  1. /*
  2.  * source file - "hame.c" - for public release
  3.  * Written by Ben Williams, AA7AS - January thru April 1990
  4.  * This source code is released into the public domain.
  5.  * Release 1 of example code: April 19th, 1990
  6.  * 
  7.  * This file contains C code that is for handling the HAM-E mode screens.
  8.  * 
  9.  * The HAM-E is a device that is scheduled to become available in June 1990
  10.  * from:
  11.  *                 Black Belt Systems
  12.  *                 398 Johnson Road
  13.  *                 Glasgow, MT, USA
  14.  *                 59230
  15.  * 
  16.  *             US Sales: (800) TK-AMIGA
  17.  *  International Sales: (406) 367-5513
  18.  *    Technical Support: (406) 367-5509
  19.  *        G3 Office FAX: (406) 367-AFAX
  20.  * 
  21.  * This source code should be freely used to develop your own routines
  22.  * in any language that work in conjunction with the HAM-E device.
  23.  * That is the entire intention of publishing this source.
  24.  *
  25.  * Please note that the Save IFF C source was originally written by
  26.  * Matt Dillon; only small changes were done to this at Black Belt to
  27.  * make it work in this context. Essentially, we're saving 640x200 or
  28.  * 640x400 standard IFF images. Because Matt's source uses functions
  29.  * from his personal library of functions, to compile this you need to
  30.  * link using "my.lib" which has been included in this archive. Only
  31.  * for the IFF code do you need to link with this, so if you're using
  32.  * other source and not the IFF source, you do NOT need to link in my.lib
  33.  * at all.
  34.  *
  35.  * This source was written to compile and run under Lattice C v5.04; It
  36.  * was not written to conform to MANX C at all. We do not use MANX C
  37.  * at Black Belt and so cannot answer questions as to compatability
  38.  * issues. In general, we're compiling this way:
  39.  *
  40.  *             lc -v -d -b0 -ohame.o - hame
  41.  *
  42.  * and linking this way:
  43.  *
  44.  *      blink WITH hame_list LIBRARY lib:lcm.lib+lib:lcnb_S.lib+
  45.  *      lib:amiga.lib+lib:my.lib TO 'OutName' MAP nil: VERBOSE NODEBUG
  46.  *
  47.  * Where the file hame_list contains the following:
  48.  *
  49.  *       lib:c.o
  50.  *       hame.o
  51.  *       iff.o
  52.  *
  53.  * If you have specific questions about the source code, call Black
  54.  * Belt Systems technical support line and we will assist you as best
  55.  * we can.
  56.  *
  57.  * Samples of program use as written:
  58.  *
  59.  *  'hame -o -c'                Generates color diagram
  60.  *  'hame -o -s'                Generates multiple mode sample image
  61.  *  'hame -o -c -i ram:test'    Generates color diagram, saves iff to ram:test
  62.  *  'hame ?'                    Lists command switches
  63.  *  'hame -o -l -x 320 -y 400 -n df0:newtek' Shows 320x400 B&W NewTek IP file
  64.  *  'hame -o -x 320 -y 200 -r (address) -g (address) -b (address)'
  65.  *                              Generates picture from buffers located
  66.  *                              at these addresses - expects 6 bits/byte
  67.  *                              right (lsb) justified. Uses 'REG' mode.
  68.  *  'hame -o -h -x 320 -y 200 -r (address) -g (address) -b (address)'
  69.  *                              Generates picture from buffers located
  70.  *                              at these addresses - expects 6 bits/byte
  71.  *                              right (lsb) justified. Uses 'HAM-E' mode.
  72.  *  'hame -o -c -d 500'         Generates color diagram, waits 10 seconds
  73.  *
  74.  * You will note that all of the above examples use the '-o' switch. This
  75.  * causes the software to write to the 640 resolution screen on ODD pixel
  76.  * boundries. This is currently the way that the HAM-E expects to find it's
  77.  * data. We may change this - make sure that your rendering software can
  78.  * cope with it. If the data is not located on the correct boundry, then
  79.  * the image will NOT render in the new modes. Contact Black Belt Systems
  80.  * technical support in June for the final decision on odd/even pixel
  81.  * rendering.
  82.  *
  83.  */
  84.  
  85. /*
  86.  *
  87.  * Includes:
  88.  *
  89.  */
  90.  
  91. #include <libraries/dos.h>
  92. #include <libraries/dosextens.h>
  93. #include <stdio.h>
  94. #include <fcntl.h>
  95.  
  96. #include <exec/types.h> /* all this exec stuff is so I can find MemList */
  97. #include <exec/ports.h>
  98. #include <exec/memory.h>
  99. #include <exec/io.h>
  100. #include <exec/tasks.h>
  101. #include <exec/lists.h>
  102. #include <exec/nodes.h>
  103. #include <exec/libraries.h>
  104. #include <exec/devices.h>
  105.  
  106. #include <intuition/preferences.h>
  107. #include <rexx/storage.h>
  108. #include <intuition/intuition.h>
  109. #include <workbench/startup.h>
  110. #include <workbench/workbench.h>
  111. #include <workbench/icon.h>
  112.  
  113. /*
  114.  *
  115.  * Defines:
  116.  *
  117.  */
  118.  
  119. /* program error codes: */
  120. /*  0 - program is happy       */
  121. #define HAPPY        0
  122. /*  1 - program happy, but suicidal - user probably asked for help */
  123. #define DIE_QUIETLY  1
  124.  
  125. /*  2-20 program warnings      */
  126.  
  127. /* 21-39 program failure       */
  128. #define XDIM_NOGOOD  21
  129. #define YDIM_NOGOOD  22
  130. #define RBUF_NOGOOD  23
  131. #define GBUF_NOGOOD  24
  132. #define BBUF_NOGOOD  25
  133. #define DLY_NOGOOD   26
  134. #define UNKNOWN_OPT  27
  135. #define SHIFT_NOGOOD 28
  136. #define XOFF_NOGOOD  29
  137. #define YOFF_NOGOOD  30
  138. #define IP_NOGOOD    31
  139. #define IF_NOGOOD    32
  140. #define NO_PARAMS    33
  141.  
  142. /* 40... system problem aborts */
  143. #define NO_INTUILIB 40
  144. #define NO_GFXLIB   41
  145. #define NO_EXECLIB  42
  146. #define NO_ICONLIB  43
  147. #define NO_SCREEN   44
  148.  
  149. /*
  150.  *
  151.  * Macros:
  152.  *
  153.  */
  154.  
  155. /*
  156.  *
  157.  * External Casts:
  158.  *
  159.  */
  160.  
  161. struct Library      *OpenLibrary();
  162. struct IntuiMessage *GetMsg();
  163. struct Window       *OpenWindow();
  164. struct Screen       *OpenScreen();
  165.  
  166. /*
  167.  * External definitions:
  168.  */
  169. extern struct WBStartup *WBenchMsg;
  170.  
  171. /*
  172.  * Local structure defs
  173.  */
  174.  
  175. struct Problems
  176.   {
  177.     unsigned char ProbID;
  178.     char         *ProbText;
  179.   };
  180.  
  181. /*
  182.  * Globals:
  183.  */
  184. struct Problems our_problem[] =
  185.   {
  186.     NO_EXECLIB, "exec.library not found",
  187.     NO_SCREEN,  "Unable to open screen",
  188.     NO_GFXLIB,  "graphics.library not found",
  189.     NO_ICONLIB, "icon.library not found",
  190.     NO_INTUILIB,"intuition.library not found",
  191.     UNKNOWN_OPT,"Unknown Option",
  192.     DLY_NOGOOD, "delay time invalid",
  193.     XDIM_NOGOOD,"x dimension no good",
  194.     YDIM_NOGOOD,"y dimension no good",
  195.     RBUF_NOGOOD,"red buffer address no good",
  196.     GBUF_NOGOOD,"green buffer address no good",
  197.     BBUF_NOGOOD,"blue buffer address no good",
  198.     XOFF_NOGOOD,"X offset no good",
  199.     YOFF_NOGOOD,"Y offset no good",
  200.     IF_NOGOOD,  "IFF Filename no good",
  201.     NO_PARAMS,  "no parameters - use 'hame ?' for info",
  202.     0,0         /* end of table of error #/strings */
  203.   };
  204.  
  205. unsigned char from_cli;
  206. struct Library *IntuitionBase;
  207. struct Library *GfxBase;
  208. struct Library *IconBase;
  209. struct Library *ExecBase;
  210. struct Window  *win; /* power windows sample window */
  211. int we_ownit;
  212.  
  213. unsigned short rdm;
  214. int delay_time,hidden,sample,ham_reg,lacer,luma_mode,shifter,chroma,get_ip;
  215. short write_odd,even_steven,iff_flag;
  216. int xdim,ydim,x_offset,y_offset;
  217. unsigned char *red,*green,*blue;
  218. struct Screen *scr;
  219. char ip_file[200];
  220. char iff_file[200];
  221.  
  222. static struct NewScreen NewScreenStructure = {
  223.   0,0,
  224.   640,200,
  225.   4,
  226.   0,1,
  227.   HIRES,
  228.   CUSTOMSCREEN,
  229.   NULL,
  230.   "HAM-E 256 mode",
  231.   NULL,
  232.   NULL
  233. };
  234.  
  235. unsigned char *fp0,*fp1,*fp2,*fp3; /* bitplane pointers - fast ones. */
  236.  
  237. /* pattern of bits within a byte to be used as ~masks and OR sources. */
  238. unsigned char bitpat[] =
  239.   {
  240.     128,64,32,16,8,4,2,1,
  241.   };
  242.  
  243. /* register mode cookie */
  244. unsigned char ham_cookie[] =
  245.   {
  246.     0xA2,0xF5,0x84,0xDC,
  247.     0x6D,0xB0,0x7F,0x18
  248.   };
  249.  
  250. /* ham mode cookie */
  251. unsigned char reg_cookie[] =
  252.   {
  253.     0xA2,0xF5,0x84,0xDC,
  254.     0x6D,0xB0,0x7F,0x14
  255.   };
  256.  
  257. /* format is: string matching option, string describing option */
  258. char *opts[] =
  259.   {
  260.     "?",    "' ...for info",
  261.     "h",    "' ...for info",
  262.     "help", "' ...for info",
  263.     "-x",   " [dimension]' ...set X dimension",
  264.     "-y",   " [dimension]' ...set Y dimension",
  265.     "-r",   " [red buff pointer]' ...hexidecimal address of data buffer",
  266.     "-g",   " [green buff pointer]' ...hexidecimal address of data buffer",
  267.     "-b",   " [blue buff pointer]' ...hexidecimal address of data buffer",
  268.     "-o",   "' ...write starting at ODD pixels instead of even",
  269.     "-d",   " [jiffies]' ... delay time for test screen to persist",
  270.     "-v",   "' ...hide view while creating",
  271.     "-s",   "' ...generate sample screen",
  272.     "-h",   "' ...create HAM'ed image",
  273.     "-p",   "' ...create Palette REG image",
  274.     "-l",   "' ...luma mode",
  275.     "-m",   " [shift]' ...multiply grey level (shift left N bits)",
  276.     "-xo",  " [offset]' ...enter x offset into luma buffer",
  277.     "-yo",  " [offset]' ...enter Y offset into luma buffer",
  278.     "-c",   " ...chromasticity diagram",
  279.     "-n",   " [filename]' ...read NewTek ip file as B&W",
  280.     "-e",   "' ... use EVEN palette in -s sample screen",
  281.     "-i",   " [filename]' ... save IFF file from generated image",
  282.     0,0
  283.   };
  284.  
  285. int do_help();
  286. int do_xdim();
  287. int do_ydim();
  288. int do_rbuf();
  289. int do_gbuf();
  290. int do_bbuf();
  291. int do_wodd();
  292. int do_dt();
  293. int do_hide();
  294. int do_sample();
  295. int do_ham();
  296. int do_reg();
  297. int do_luma();
  298. int do_shift();
  299. int do_xo();
  300. int do_yo();
  301. int do_chroma();
  302. int do_ip();
  303. int do_even();
  304. int do_iff();
  305.  
  306. /* refer to the "opts" table for corresponding CLI/shell options */
  307. int (*opt_name[])() =
  308.   {
  309.     do_help,
  310.     do_help,
  311.     do_help,
  312.     do_xdim,
  313.     do_ydim,
  314.     do_rbuf,
  315.     do_gbuf,
  316.     do_bbuf,
  317.     do_wodd,
  318.     do_dt,
  319.     do_hide,
  320.     do_sample,
  321.     do_ham,
  322.     do_reg,
  323.     do_luma,
  324.     do_shift,
  325.     do_xo,
  326.     do_yo,
  327.     do_chroma,
  328.     do_ip,
  329.     do_even,
  330.     do_iff,
  331.     0
  332.   };
  333.  
  334. /*
  335.  * Code (finally!) :^)
  336.  */
  337.  
  338. /*
  339.  * The "do_xxxxx()" proceedures are called when a command line
  340.  * parameter is encountered. They parse the line, setup variables
  341.  * accordingly, and return to the CLI handler. None of them are
  342.  * directly involved with handling the HAM-E device; only in
  343.  * program initialization.
  344.  */
  345.  
  346. void safe_line(ptr)
  347.   char *ptr;
  348.   {
  349.     if (from_cli)
  350.       {
  351.         printf("%s\n",ptr);
  352.       }
  353.   }
  354.  
  355. rdmgen() /* easy, fast pseudo-rdm number generator (16k sequence) */
  356.   {
  357.     register unsigned short foo;
  358.     foo = rdm;
  359.     foo <<= 2;
  360.     rdm += foo;
  361.     return(rdm >> 8);
  362.   }
  363.  
  364. /* parameter handling... */
  365. int do_even(argv,index_ptr,limit)
  366.   char *argv[];     /* cmd line arguments */
  367.   int *index_ptr;   /* points to this option's position */
  368.   int limit;        /* indicates total number of opts on cmd line */
  369.   {
  370.     even_steven=1;
  371.     return(0);
  372.   }
  373.  
  374. int do_chroma(argv,index_ptr,limit)
  375.   char *argv[];     /* cmd line arguments */
  376.   int *index_ptr;   /* points to this option's position */
  377.   int limit;        /* indicates total number of opts on cmd line */
  378.   {
  379.     chroma=1;
  380.     return(0);
  381.   }
  382.  
  383. int do_wodd(argv,index_ptr,limit)
  384.   char *argv[];     /* cmd line arguments */
  385.   int *index_ptr;   /* points to this option's position */
  386.   int limit;        /* indicates total number of opts on cmd line */
  387.   {
  388.     write_odd=1;
  389.     return(0);
  390.   }
  391.  
  392. int do_luma(argv,index_ptr,limit)
  393.   char *argv[];     /* cmd line arguments */
  394.   int *index_ptr;   /* points to this option's position */
  395.   int limit;        /* indicates total number of opts on cmd line */
  396.   {
  397.     luma_mode=1;
  398.     return(0);
  399.   }
  400.  
  401. int do_sample(argv,index_ptr,limit)
  402.   char *argv[];     /* cmd line arguments */
  403.   int *index_ptr;   /* points to this option's position */
  404.   int limit;        /* indicates total number of opts on cmd line */
  405.   {
  406.     sample=1;
  407.     return(0);
  408.   }
  409.  
  410. int do_ham(argv,index_ptr,limit)
  411.   char *argv[];     /* cmd line arguments */
  412.   int *index_ptr;   /* points to this option's position */
  413.   int limit;        /* indicates total number of opts on cmd line */
  414.   {
  415.     ham_reg=1;
  416.     return(0);
  417.   }
  418.  
  419. int do_reg(argv,index_ptr,limit)
  420.   char *argv[];     /* cmd line arguments */
  421.   int *index_ptr;   /* points to this option's position */
  422.   int limit;        /* indicates total number of opts on cmd line */
  423.   {
  424.     ham_reg=0;
  425.     return(0);
  426.   }
  427.  
  428. /* parameter sucking... */
  429. int do_hide(argv,index_ptr,limit)
  430.   char *argv[];     /* cmd line arguments */
  431.   int *index_ptr;   /* points to this option's position */
  432.   int limit;        /* indicates total number of opts on cmd line */
  433.   {
  434.     hidden=1;
  435.     return(0);
  436.   }
  437.  
  438. int do_iff(argv,index_ptr,limit)
  439.   char *argv[];     /* cmd line arguments */
  440.   int *index_ptr;   /* points to this option's position */
  441.   int limit;        /* indicates total number of opts on cmd line */
  442.   {
  443.     if (++(*index_ptr) > limit) /* index to our keyword after switch */
  444.       {
  445.         return(IF_NOGOOD);
  446.       }
  447.     strcpy(&iff_file[0],argv[*index_ptr++]); /* get incoming parameter */
  448.     iff_flag=1;
  449.  
  450.     return(0); /* we're all happy here... :^) */
  451.   }
  452.  
  453. int do_ip(argv,index_ptr,limit)
  454.   char *argv[];     /* cmd line arguments */
  455.   int *index_ptr;   /* points to this option's position */
  456.   int limit;        /* indicates total number of opts on cmd line */
  457.   {
  458.     if (++(*index_ptr) > limit) /* index to our keyword after switch */
  459.       {
  460.         return(IP_NOGOOD);
  461.       }
  462.     strcpy(&ip_file[0],argv[*index_ptr++]); /* get incoming parameter */
  463.     get_ip=1;
  464.  
  465.     return(0); /* we're all happy here... :^) */
  466.   }
  467.  
  468. int do_xo(argv,index_ptr,limit)
  469.   char *argv[];     /* cmd line arguments */
  470.   int *index_ptr;   /* points to this option's position */
  471.   int limit;        /* indicates total number of opts on cmd line */
  472.   {
  473.   char argbuf[25];
  474.     if (++(*index_ptr) > limit) /* index to our keyword after switch */
  475.       {
  476.         return(XOFF_NOGOOD);
  477.       }
  478.     strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
  479.     sscanf(argbuf,"%d",&x_offset);
  480.     
  481.     return(0); /* we're all happy here... :^) */
  482.   }
  483.  
  484. int do_yo(argv,index_ptr,limit)
  485.   char *argv[];     /* cmd line arguments */
  486.   int *index_ptr;   /* points to this option's position */
  487.   int limit;        /* indicates total number of opts on cmd line */
  488.   {
  489.   char argbuf[25];
  490.     if (++(*index_ptr) > limit) /* index to our keyword after switch */
  491.       {
  492.         return(YOFF_NOGOOD);
  493.       }
  494.     strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
  495.     sscanf(argbuf,"%d",&y_offset);
  496.     
  497.     return(0); /* we're all happy here... :^) */
  498.   }
  499.  
  500. int do_dt(argv,index_ptr,limit)
  501.   char *argv[];     /* cmd line arguments */
  502.   int *index_ptr;   /* points to this option's position */
  503.   int limit;        /* indicates total number of opts on cmd line */
  504.   {
  505.   char argbuf[25];
  506.     if (++(*index_ptr) > limit) /* index to our keyword after switch */
  507.       {
  508.         return(DLY_NOGOOD);
  509.       }
  510.     strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
  511.     sscanf(argbuf,"%d",&delay_time);
  512.     
  513.     return(0); /* we're all happy here... :^) */
  514.   }
  515.  
  516. int do_shift(argv,index_ptr,limit)
  517.   char *argv[];     /* cmd line arguments */
  518.   int *index_ptr;   /* points to this option's position */
  519.   int limit;        /* indicates total number of opts on cmd line */
  520.   {
  521.   char argbuf[25];
  522.     if (++(*index_ptr) > limit) /* index to our keyword after switch */
  523.       {
  524.         return(SHIFT_NOGOOD);
  525.       }
  526.     strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
  527.     sscanf(argbuf,"%d",&shifter);
  528.     
  529.     return(0); /* we're all happy here... :^) */
  530.   }
  531.  
  532. int do_xdim(argv,index_ptr,limit)
  533.   char *argv[];     /* cmd line arguments */
  534.   int *index_ptr;   /* points to this option's position */
  535.   int limit;        /* indicates total number of opts on cmd line */
  536.   {
  537.   char argbuf[25];
  538.     if (++(*index_ptr) > limit) /* index to our keyword after switch */
  539.       {
  540.         return(XDIM_NOGOOD);
  541.       }
  542.     strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
  543.     sscanf(argbuf,"%d",&xdim);
  544.     
  545.     return(0); /* we're all happy here... :^) */
  546.   }
  547.  
  548. int do_ydim(argv,index_ptr,limit)
  549.   char *argv[];     /* cmd line arguments */
  550.   int *index_ptr;   /* points to this option's position */
  551.   int limit;        /* indicates total number of opts on cmd line */
  552.   {
  553.   char argbuf[25];
  554.     if (++(*index_ptr) > limit) /* index to our keyword after switch */
  555.       {
  556.         return(YDIM_NOGOOD);
  557.       }
  558.     strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
  559.     sscanf(argbuf,"%d",&ydim);
  560.     
  561.     return(0); /* we're all happy here... :^) */
  562.   }
  563.  
  564. int do_rbuf(argv,index_ptr,limit)
  565.   char *argv[];     /* cmd line arguments */
  566.   int *index_ptr;   /* points to this option's position */
  567.   int limit;        /* indicates total number of opts on cmd line */
  568.   {
  569.   char argbuf[25];
  570.     if (++(*index_ptr) > limit) /* index to our keyword after switch */
  571.       {
  572.         return(RBUF_NOGOOD);
  573.       }
  574.     strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
  575.     sscanf(argbuf,"%x",((int*)(&red)));
  576.     
  577.     return(0); /* we're all happy here... :^) */
  578.   }
  579.  
  580. int do_gbuf(argv,index_ptr,limit)
  581.   char *argv[];     /* cmd line arguments */
  582.   int *index_ptr;   /* points to this option's position */
  583.   int limit;        /* indicates total number of opts on cmd line */
  584.   {
  585.   char argbuf[25];
  586.     if (++(*index_ptr) > limit) /* index to our keyword after switch */
  587.       {
  588.         return(GBUF_NOGOOD);
  589.       }
  590.     strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
  591.     sscanf(argbuf,"%x",((int*)(&green)));
  592.     
  593.     return(0); /* we're all happy here... :^) */
  594.   }
  595.  
  596. int do_bbuf(argv,index_ptr,limit)
  597.   char *argv[];     /* cmd line arguments */
  598.   int *index_ptr;   /* points to this option's position */
  599.   int limit;        /* indicates total number of opts on cmd line */
  600.   {
  601.   char argbuf[25];
  602.     if (++(*index_ptr) > limit) /* index to our keyword after switch */
  603.       {
  604.         return(BBUF_NOGOOD);
  605.       }
  606.     strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
  607.     sscanf(argbuf,"%x",((int*)(&blue)));
  608.     
  609.     return(0); /* we're all happy here... :^) */
  610.   }
  611.  
  612.  
  613. int do_help(argv,index_ptr,limit)
  614.   char *argv[];     /* cmd line arguments */
  615.   int *index_ptr;   /* points to this options position */
  616.   int limit;        /* indicates total number of opts on cmd line */
  617.   {
  618.   int index;
  619.   char buffer[100];
  620.     sprintf(&buffer[0],"%s. Usage is:",argv[0]);
  621.     safe_line(&buffer[0]);
  622.     for (index=0; opts[index]; index+=2)
  623.       {
  624.         sprintf(&buffer[0],"'1> %s %s%s",argv[0],opts[index],opts[index+1]);
  625.         safe_line(&buffer[0]);
  626.       }
  627.     safe_line("");
  628.     safe_line("(c) Black Belt Systems, 1990 - ALL RIGHTS RESERVED");
  629.     safe_line("Written by Ben Williams, ars:AA7AS");
  630.     return(DIE_QUIETLY);
  631.   }
  632.  
  633. /*
  634.  * do_cli_args()
  635.  *
  636.  * This proceedure parses the command line arguments and calls other
  637.  * proceedures based upon what is encountered in the command line.
  638.  * This is considered an initialization step (many of them). Once all
  639.  * CLI parameters have been handled, error status (or success) is returned
  640.  * to the main() proceedure, which then passes it on to the runner()
  641.  * proceedure. If an error is encountered, runner() returns immediately
  642.  * and cleanup() is called, which will cleanup (obviously) and also
  643.  * report the error.
  644.  */
  645.  
  646. int do_cli_args(argc,argv)
  647.   int argc;
  648.   char *argv[];
  649.   {
  650.   int arg_index,arg_limit,opt_index;
  651.   int parm;
  652.   unsigned char found;
  653.     from_cli=1; /* global info for later printfs and the like */
  654.     parm=0; /* no errors - yet. */
  655.     arg_limit = argc-1; /* argv[0] is the programs NAME */
  656.     arg_index = 1;
  657.     while(arg_index <= arg_limit )
  658.       {
  659.         found=0;
  660.         opt_index=0;
  661.         while((!found) && (opts[opt_index]))
  662.           {
  663.             if (strnicmp(argv[arg_index],opts[opt_index])==0)
  664.               {
  665.                 found=1;
  666.                 /* call FN via table, pass position in parameters */
  667.                 if (parm=(*opt_name[opt_index >> 1])(argv,&arg_index,arg_limit))
  668.                   {
  669.                     return(parm);
  670.                   }
  671.               }
  672.             opt_index += 2;
  673.           }
  674.         if (!found)
  675.           {
  676.             return(UNKNOWN_OPT);
  677.           }
  678.         arg_index++;
  679.       }
  680.     return(0);
  681.   }
  682.  
  683. int init(argc,argv)
  684.   int argc;
  685.   char *argv[];
  686.   {
  687.   int parm;
  688.     iff_flag=0;
  689.     iff_file[0]=0;
  690.     even_steven=0;
  691.     ip_file[0]=0;
  692.     get_ip=0;
  693.     chroma=0;
  694.     x_offset=0;
  695.     y_offset=0;
  696.     shifter=0;
  697.     luma_mode=0;
  698.     lacer=0;
  699.     delay_time=0;
  700.     write_odd=0;
  701.     rdm=1; /* seed! */
  702.     hidden=0;
  703.     red = NULL;
  704.     green = NULL;
  705.     blue = NULL;
  706.     if (!(ExecBase = OpenLibrary("exec.library",0)))
  707.       {
  708.         return(NO_EXECLIB);
  709.       }
  710.     if (!(IntuitionBase = OpenLibrary("intuition.library",0)))
  711.       {
  712.         return(NO_INTUILIB);
  713.       }
  714.     if (!(GfxBase = OpenLibrary("graphics.library",0)))
  715.       {
  716.         return(NO_GFXLIB);
  717.       }
  718.     if (!(IconBase = OpenLibrary(ICONNAME,0)))
  719.       {
  720.         return(NO_ICONLIB);
  721.       }
  722.     /* now we parse the arguments, if any, from the parent environment: */
  723.     parm=NO_PARAMS;
  724.     if (argc)
  725.       {
  726.         parm=do_cli_args(argc,argv);
  727.       }
  728.     return(parm);
  729.   }
  730.  
  731. /*
  732.  * cleanup()
  733.  *
  734.  * This routine close libraries and so on; if there was an error
  735.  * encountered in the program, it is looked up and printed out here.
  736.  */
  737.  
  738. void cleanup(parm)
  739.   int parm;
  740.   {
  741.   char ebuff[80];
  742.   int i;
  743.     if (parm == DIE_QUIETLY) parm=HAPPY; /* no errors generated */
  744.     if (GfxBase)        CloseLibrary(GfxBase);
  745.     if (IconBase)       CloseLibrary(IconBase);
  746.     if (IntuitionBase)  CloseLibrary(IntuitionBase);
  747.     if (ExecBase)       CloseLibrary(ExecBase);
  748.     if (parm) /* get system problem from table up front */
  749.       {
  750.         i=0; /* look up error # linearly */
  751.         while ((parm != our_problem[i].ProbID) && (our_problem[i].ProbID))
  752.           {
  753.             i++;
  754.           }
  755.         if (!our_problem[i].ProbID) /* then error # isn't in the table */
  756.           {
  757.             sprintf(&ebuff[0],"Unknown Internal Error #%d",parm);
  758.             safe_line(&ebuff[0]);
  759.           }
  760.         else /* we found the error, signal it. */
  761.           {
  762.             safe_line(our_problem[i].ProbText);
  763.           }
  764.       }
  765.     exit(parm);
  766.   }
  767.  
  768. /*
  769.  * write_byte() - lowest level routine
  770.  *
  771.  * This routine actually writes bytes to the target screen; all other
  772.  * routines vector thru it. Why? Because we need to control how the
  773.  * bytes are written to the screen; at the current time,
  774.  * a byte must be written to an odd pixel and then an even one,
  775.  * which is a little unusual. We're looking at the hardware to see
  776.  * if we can change this. If not, you'll need a global flag that
  777.  * the user can set (here, it's called "write_odd") for their particular
  778.  * machine... hopefully, this will not be a variable, it could be a pain
  779.  * in the ribs. But for the moment, the variable is needed in case there
  780.  * is variation.
  781.  *
  782.  * This routine (obviously) isn't particularly optomized, it's just very
  783.  * straightforward code. Since it is the bottom level routine, you'll
  784.  * almost certainly want to replace it with in line code or at the
  785.  * very least fast external ASM code. We leave all that fun up to
  786.  * you for now, although we'll try to provide that stuff too, if we
  787.  * get time.
  788.  */
  789.  
  790. void write_byte(x,y,n)
  791.   short x;
  792.   int y;
  793.   unsigned char n;
  794.   {
  795.   int ypos,byte_offset;
  796.   short bit_offset;
  797.     ypos = y * 80; /* index to correct scan line */
  798.     bit_offset = ((x << 1) & 7) | write_odd; /* find base bit position */
  799.     byte_offset = (x >> 2);   /* find base byte offset */
  800.     if (n & 128) *(fp3 + ypos + byte_offset) |= bitpat[bit_offset];
  801.             else *(fp3 + ypos + byte_offset) &= ~bitpat[bit_offset];
  802.     if (n &  64) *(fp2 + ypos + byte_offset) |= bitpat[bit_offset];
  803.             else *(fp2 + ypos + byte_offset) &= ~bitpat[bit_offset];
  804.     if (n &  32) *(fp1 + ypos + byte_offset) |= bitpat[bit_offset];
  805.             else *(fp1 + ypos + byte_offset) &= ~bitpat[bit_offset];
  806.     if (n &  16) *(fp0 + ypos + byte_offset) |= bitpat[bit_offset];
  807.             else *(fp0 + ypos + byte_offset) &= ~bitpat[bit_offset];
  808.     bit_offset++; /* to next nybble */
  809.     if (bit_offset == 8) /* carry into next byte? */
  810.       {
  811.         bit_offset=0;
  812.         byte_offset++;
  813.       }
  814.     if (n & 8) *(fp3 + ypos + byte_offset) |= bitpat[bit_offset];
  815.           else *(fp3 + ypos + byte_offset) &= ~bitpat[bit_offset];
  816.     if (n & 4) *(fp2 + ypos + byte_offset) |= bitpat[bit_offset];
  817.           else *(fp2 + ypos + byte_offset) &= ~bitpat[bit_offset];
  818.     if (n & 2) *(fp1 + ypos + byte_offset) |= bitpat[bit_offset];
  819.           else *(fp1 + ypos + byte_offset) &= ~bitpat[bit_offset];
  820.     if (n & 1) *(fp0 + ypos + byte_offset) |= bitpat[bit_offset];
  821.           else *(fp0 + ypos + byte_offset) &= ~bitpat[bit_offset];
  822.   }
  823.  
  824. /*
  825.  * SetRGB8();
  826.  *
  827.  * This routine is similar to SetRGB4() in the Amiga's "normal" gfx library.
  828.  * You pass it the register number, the RGB value, and a parameter that tells
  829.  * it which line the palette starts on and it will set the register for you.
  830.  * For most screens, the starting line will be ZERO, as that leaves the most
  831.  * room for futzing about with images; however, in the test software, we
  832.  * sometimes reload the palette on the same screen. This means that the
  833.  * second palette will begin on a line other than zero.
  834.  *
  835.  * If the global variable "lacer" is set, this routine will write the color
  836.  * register data in two places - one for each 200 line section of the
  837.  * interlace image. If you need different color registers for each field,
  838.  * then you'll need to modify this routine - that would be an unusual
  839.  * situation, even though it's perfectly feasible.
  840.  */
  841.  
  842. void SetRGB8(reg,rr,gg,bb,base)
  843.   short reg;
  844.   unsigned char rr,gg,bb;
  845.   short base;
  846.   {
  847.   short p_row,p_index;
  848.     p_row = (reg >> 6) + base;           /* palette row 0-3.  */
  849.     p_index = ((reg & 0x3f) * 3) + 8;    /* reg 0-63 in p_row */
  850.     if (lacer) /* then we need both fields! */
  851.       {
  852.         write_byte(p_index,   p_row*2, rr);         /* put RED value     */
  853.         write_byte(p_index+1, p_row*2, gg);         /* put GREEN value   */
  854.         write_byte(p_index+2, p_row*2, bb);         /* put BLUE value    */
  855.         write_byte(p_index,   (p_row*2)+1, rr);     /* put RED value     */
  856.         write_byte(p_index+1, (p_row*2)+1, gg);     /* put GREEN value   */
  857.         write_byte(p_index+2, (p_row*2)+1, bb);     /* put BLUE value    */
  858.       }
  859.     else /* just write to one field */
  860.       {
  861.         write_byte(p_index,   p_row, rr);     /* put RED value     */
  862.         write_byte(p_index+1, p_row, gg);     /* put GREEN value   */
  863.         write_byte(p_index+2, p_row, bb);     /* put BLUE value    */
  864.       }
  865.   }
  866.  
  867. /*
  868.  * gen_even_palette()
  869.  *
  870.  * This routine creates a special palette; it's extremely useful for
  871.  * drawing images of unknown color composition quickly. See the
  872.  * WriteRGB() routine, just following.
  873.  *
  874.  * This palette essentially gives you 6 levels of red, 7 levels of
  875.  * green, and 6 levels of blue. If you were to do a binary distribution,
  876.  * you'd get 8 of red, 8 of green, and 4 of blue, which leaves images
  877.  * with any blue detail at all looking like trash. This distribution
  878.  * and the accompaning write routine evens the score between the colors.
  879.  */
  880.  
  881. void gen_even_palette(base)
  882.   int base;
  883.   {
  884.   int rr,gg,bb,i;
  885.     i=0;
  886.     for (rr=0; rr<252; rr+=42)
  887.       {
  888.         for (gg=0; gg<252; gg+=36)
  889.           {
  890.             for (bb=0; bb<252; bb+=42)
  891.               {
  892.                 SetRGB8(i++,rr,gg,bb,base);
  893.               }
  894.           }
  895.       }
  896.   }
  897.  
  898. /*
  899.  * write_RGB()
  900.  *
  901.  * This routine is used after calling "gen_even_palette()", above.
  902.  * gen_even_palette() sets up 252 color registers such that they are
  903.  * pretty evenly distributed accross the color spectrum. Given a 24
  904.  * bit input, this routine maps the image colors to the palette
  905.  * colors evenly. Very useful as a general "show" routine. Most images
  906.  * look very nice indeed... 256 colors, no fringing.
  907.  */
  908.  
  909. void write_RGB(x,y,rr,gg,bb)
  910.   int x,y,rr,gg,bb;
  911.   {
  912.     write_byte(x,y,((rr/43)*42) + ((gg/37)*6) + (bb/43) );
  913.   }
  914.  
  915. /*
  916.  * write_cookie()
  917.  *
  918.  * This function writes the cookie on a particular line. The variable
  919.  * "brand" is a pointer to an arrary of data that contains the particular
  920.  * cookie for the mode you want. Call as:
  921.  *      write_cookie(ham_cookie,line);
  922.  *                  -or-
  923.  *      write_cookie(reg_cookie,line);
  924.  * If you have a four line palette, you need to call this function for
  925.  * each successive line the palette exists upon.
  926.  *
  927.  * See the next set of proceedures: WriteRegCookie() and WriteHamCookie()
  928.  * for a higher level approach to this.
  929.  *
  930.  * If the global variable "lacer" is set, this function will write the cookie
  931.  * data on TWO lines... sending four lines of cookie to the function with the
  932.  * lines 0,1,2,3 will write cookies on line pairs 0,1 2,3 4,5 and 6,7.
  933.  */
  934.  
  935. void write_cookie(brand,line)
  936.   unsigned char *brand;
  937.   int line;
  938.   {
  939.   int i;
  940.     if (lacer) /* we need double the cookie data! */
  941.       {
  942.         for (i=0; i<8; i++)
  943.           {
  944.             write_byte(i,line*2,brand[i]);
  945.             write_byte(i,(line*2)+1,brand[i]);
  946.           }
  947.       }
  948.     else
  949.       {
  950.         for (i=0; i<8; i++)
  951.           {
  952.             write_byte(i,line,brand[i]);
  953.           }
  954.       }
  955.   }
  956.  
  957. /*
  958.  * WriteHamCookie(), WriteRegCookie()
  959.  *
  960.  * More specific versions of cookie handling...
  961.  */
  962.  
  963. void WriteHamCookie(lines,base)
  964.   int lines,base;
  965.   {
  966.   int i;
  967.     for (i=base; i<(base+lines); i++)
  968.       {
  969.         write_cookie(ham_cookie,i);
  970.       }
  971.   }
  972.  
  973. void WriteRegCookie(lines,base)
  974.   int lines,base;
  975.   {
  976.   int i;
  977.     for (i=base; i<(base+lines); i++)
  978.       {
  979.         write_cookie(reg_cookie,i);
  980.       }
  981.   }
  982.  
  983. /*
  984.  * Sets palette for Amiga side of hardware: The palette here is designed
  985.  * to achieve two independant goals. First, and most importantly, it creates
  986.  * a situation where the IRGB lines at the Amiga's data port will exactly
  987.  * mirror the data in the bitplanes of the screen as each pixel is emitted.
  988.  * Secondly, this palette makes the images visible, if not sensible, on a
  989.  * non HAM-e equipped Amiga... Hopefully this distinctive color palette will
  990.  * quickly cue the user that they are missing something good. :^)
  991.  *
  992.  * IRGB to 12 bit correspondence:
  993.  * 
  994.  * bit 8 - b3 of red
  995.  * bit 4 - b3 of green
  996.  * bit 2 - b3 of blue
  997.  * bit 1 - b0 of blue
  998.  */
  999.  
  1000. void make_hame_palette()
  1001.   {
  1002.   register struct ViewPort *vp;
  1003.   register int rr,gg,bb,i;
  1004.   int col;
  1005.     col=0;
  1006.     vp = &scr->ViewPort;
  1007.     for (i=0; i<16; i++)
  1008.       {
  1009.         rr=0; gg=0; bb=0;
  1010.         if (i & 8) rr  = 8; /* this builds the IRGB bit outputs. */
  1011.         if (i & 4) gg  = 8;
  1012.         if (i & 2) bb  = 8;
  1013.         if (i & 1) bb |= 1;
  1014.         rr += (col & 7); /* build strange colors in there, too... */
  1015.         col += 2;
  1016.         gg += (col & 7); /* ... so "normal view" is interesting */
  1017.         col += 2;
  1018.         bb += (col & 6);
  1019.         col += 2;
  1020.         /* Set_v_RGB4() is in iff.c - almost the same as SetRGB4() */
  1021.         Set_v_RGB4(vp,i,rr,gg,bb); /* actually set the Amiga colors */
  1022.       }
  1023.   }
  1024.  
  1025. /*
  1026.  * grey_palette();
  1027.  *
  1028.  * Writes 256 register palette using the ri, gi, and bi variables as
  1029.  * addends for each register. calling with 1,1,1 creates a palette that
  1030.  * goes from 0:0:0, 1:1:1, 2:2:2.... 255:255:255  Calling with with
  1031.  * the values 1,0,1 would create a palette that goes from 0:0:0, 1:0:1,
  1032.  * 2:0:2... 255:0:255  The function is intended to provide an easy way
  1033.  * to generate linear 256 level palettes of the seven major colors:
  1034.  * R, G, B, RG, RB, GB, RGB.
  1035.  */
  1036.  
  1037. void grey_palette(base,ri,gi,bi)
  1038.   int base;
  1039.   {
  1040.   int i,rv,gv,bv;
  1041.     rv=0; gv=0; bv=0;
  1042.     for (i=0; i<256; i++)
  1043.       {
  1044.         SetRGB8(i,rv,gv,bv,base);
  1045.         rv += ri;
  1046.         gv += gi;
  1047.         bv += bi;
  1048.       }
  1049.   }
  1050.  
  1051. /*
  1052.  * make_luma_palette()
  1053.  *
  1054.  * This routine creates 256 grey levels using the grey_palette routine,
  1055.  * intended for use in register mode.
  1056.  */
  1057.  
  1058. void make_luma_palette()
  1059.   {
  1060.     grey_palette(0,1,1,1);
  1061.   }
  1062.  
  1063. /*
  1064.  * inc_palette();
  1065.  *
  1066.  * Writes 256 register palette, intended for use in register mode...
  1067.  * Creates 256 colors arranged such that there are 8 levels of red,
  1068.  * 8 levels of green, and 4 levels of blue - the typical 8 bit RGB
  1069.  * distribution. A much better choice is "gen_even_palette()", but
  1070.  * this is the "typical" industry way of distributing colors.
  1071.  */
  1072.  
  1073. void inc_palette(base)
  1074.   int base;
  1075.   {
  1076.   int i;
  1077.   unsigned char pred,pgreen,pblue;
  1078.     for (i=0; i<256; i++)
  1079.       {
  1080.         pred   = (i & 0xE0) + ((i & 0xE0)>>3);
  1081.         pgreen = ((i & 0x1C) << 3) + (((i & 0x1C) << 3) >> 3);
  1082.         pblue  = ((i & 0x03) << 6) + ((i & 0x03) << 4) + ((i >> 1)&1);
  1083.         
  1084.         SetRGB8(i,pred,pgreen,pblue,base);
  1085.       }
  1086.   }
  1087.  
  1088. /*
  1089.  * This function simply writes a block of a particular value. Intended
  1090.  * for generating into a REG mode screen. Used in Bugger();
  1091.  */
  1092.  
  1093. void write_block(bx,by,value,base)
  1094.   short bx,by;
  1095.   unsigned char value;
  1096.   short base;
  1097.   {
  1098.   short xbase,ybase,xi,yi;
  1099.     xbase = bx * 10; /* determine starting x,y */
  1100.     ybase = (by * 8)+base;
  1101.     for (yi=ybase; yi<(ybase+8); yi++)
  1102.       {
  1103.         for (xi=xbase; xi<(xbase+10); xi++)
  1104.           {
  1105.             write_byte(xi,yi,value);
  1106.           }
  1107.       }
  1108.   }
  1109.  
  1110. /*
  1111.  * Bugger()
  1112.  *
  1113.  * This function writes a number of different patterns into the screen
  1114.  * that are useful when working with the board (diagnostics). Various
  1115.  * techniques, mostly quick and dirty, are used to create these patterns.
  1116.  * Bugger is not "nice" code - sorry.
  1117.  */
  1118.  
  1119. void bugger(srow)
  1120.   int srow;
  1121.   {
  1122.   int i,vx;
  1123.   int vy;
  1124.     if (hidden) ScreenToBack(scr);
  1125.     WriteHamCookie(4,0);
  1126.     /* write palette at ham cookie starting row */
  1127.     if (even_steven) gen_even_palette(0); /* 6r 7g 6b */
  1128.     else             inc_palette(0);      /* 8r 8g 4b */
  1129.     WriteRegCookie(4,65);
  1130.     grey_palette(65,1,1,1); /* 256 grey levels */
  1131.     WriteRegCookie(4,73);
  1132.     grey_palette(73,1,0,0); /* 256 RED levels */
  1133.     WriteRegCookie(4,81);
  1134.     grey_palette(81,0,1,0); /* 256 GREEN levels */
  1135.     WriteRegCookie(4,89);
  1136.     grey_palette(89,0,0,1); /* 256 BLUE levels */
  1137.     WriteRegCookie(4,100);
  1138.     if (even_steven) gen_even_palette(100); /* 6r 7g 6b */
  1139.     else             inc_palette(100);      /* 8r 8g 4b */
  1140.     for (vx=0; vx<256; vx++)
  1141.       {
  1142.         write_byte(vx,69,vx); /* writes for linear grey scale */
  1143.         write_byte(vx,70,vx);
  1144.         write_byte(vx,71,vx);
  1145.         write_byte(vx,72,vx);
  1146.         
  1147.         write_byte(vx,77,vx); /* red */
  1148.         write_byte(vx,78,vx);
  1149.         write_byte(vx,79,vx);
  1150.         write_byte(vx,80,vx);
  1151.         
  1152.         write_byte(vx,85,vx); /* green */
  1153.         write_byte(vx,86,vx);
  1154.         write_byte(vx,87,vx);
  1155.         write_byte(vx,88,vx);
  1156.         
  1157.         write_byte(vx,93,vx); /* blue */
  1158.         write_byte(vx,94,vx);
  1159.         write_byte(vx,95,vx);
  1160.         write_byte(vx,96,vx);
  1161.       }
  1162.     i=1;
  1163.     vx=1; vy=0;
  1164.     while(i < 60) /* show registers in HAM-E mode */
  1165.       {
  1166.         write_block(vx,vy,i++,24); /* place reg block */
  1167.         vx++;
  1168.         if (vx == 32)
  1169.           {
  1170.             vx=0;
  1171.             vy++;
  1172.           }
  1173.       }
  1174.     i=0;
  1175.     if (even_steven) /* using 6r 7g 6b color distribution */
  1176.       {
  1177.         for (vy=0; vy<9; vy++) /* generates 9 rows of reg loads */
  1178.           {
  1179.             for (vx=0; vx<30; vx++)
  1180.               {
  1181.                 write_block(vx,vy,i,srow);
  1182.                 i++;
  1183.                 if (i == 252)
  1184.                   {
  1185.                     vx=30; vy=9;
  1186.                   }
  1187.               }
  1188.           }
  1189.         i=2;
  1190.         /* write RGB color distribution bar */
  1191.         write_block(i++,10,0,srow); /* black (0) */
  1192.         write_block(i++,10,1,srow); /* blue (5) */
  1193.         write_block(i++,10,2,srow);
  1194.         write_block(i++,10,3,srow);
  1195.         write_block(i++,10,4,srow);
  1196.         write_block(i++,10,5,srow);
  1197.         i++;
  1198.         write_block(i++,10,0,srow); /* black (0) */
  1199.         write_block(i++,10,6,srow);
  1200.         write_block(i++,10,12,srow); /* green (6) */
  1201.         write_block(i++,10,18,srow);
  1202.         write_block(i++,10,24,srow);
  1203.         write_block(i++,10,30,srow);
  1204.         write_block(i++,10,36,srow);
  1205.         i++;
  1206.         write_block(i++,10,0,srow); /* black (0) */
  1207.         write_block(i++,10,42,srow); /* red (5) */
  1208.         write_block(i++,10,84,srow);
  1209.         write_block(i++,10,126,srow);
  1210.         write_block(i++,10,168,srow);
  1211.         write_block(i++,10,210,srow);
  1212.       }
  1213.     else /* using 8r 8g 4b color distribution */
  1214.       {
  1215.         for (vy=0; vy<8; vy++) /* generates 9 rows of reg loads */
  1216.           {
  1217.             for (vx=0; vx<32; vx++)
  1218.               {
  1219.                 write_block(vx,vy,i,srow);
  1220.                 i++;
  1221.               }
  1222.           }
  1223.         /* write RGB color distribution bar */
  1224.         i=3;
  1225.         write_block(i++,9,0,srow); /* black (0) */
  1226.         write_block(i++,9,1,srow); /* blue (3) */
  1227.         write_block(i++,9,2,srow);
  1228.         write_block(i++,9,3,srow);
  1229.         i++;
  1230.         write_block(i++,9,0,srow); /* black (0) */
  1231.         write_block(i++,9,4,srow); /* green (7) */
  1232.         write_block(i++,9,8,srow);
  1233.         write_block(i++,9,12,srow);
  1234.         write_block(i++,9,16,srow);
  1235.         write_block(i++,9,20,srow);
  1236.         write_block(i++,9,24,srow);
  1237.         write_block(i++,9,28,srow);
  1238.         i++;
  1239.         write_block(i++,9,0,srow); /* black (0) */
  1240.         write_block(i++,9,32,srow); /* red (7) */
  1241.         write_block(i++,9,64,srow);
  1242.         write_block(i++,9,96,srow);
  1243.         write_block(i++,9,128,srow);
  1244.         write_block(i++,9,160,srow);
  1245.         write_block(i++,9,192,srow);
  1246.         write_block(i++,9,224,srow);
  1247.       }
  1248.     
  1249.     /* write buncha colors in HAM mode */
  1250.     
  1251.     write_byte(0,50,0x40); /* hamming test - load color reg 0:0 first... */
  1252.     write_byte(0,51,0x40);
  1253.     write_byte(0,52,0x40);
  1254.     
  1255.     write_byte(1,50,0x80); /* hamming test - load color reg 0:0 first... */
  1256.     write_byte(1,51,0x80);
  1257.     write_byte(1,52,0x80);
  1258.  
  1259.     write_byte(2,50,0xC0); /* hamming test - load color reg 0:0 first... */
  1260.     write_byte(2,51,0xC0);
  1261.     write_byte(2,52,0xC0);
  1262.     /* ramp up colors using "pure" RGB ham loads */
  1263.     for (vx=0; vx<256; vx++) /* then build 0-63 each of three ways */
  1264.       {
  1265.         write_byte(vx+3,50,(vx >> 2)+0x80); /* write LOTS of HAM data! */
  1266.         write_byte(vx+3,51,(vx >> 2)+0xC0);
  1267.         write_byte(vx+3,52,(vx >> 2)+0x40);
  1268.       }
  1269.     
  1270.     write_byte(0,55,0x40); /* hamming test - load color reg 0:0 first... */
  1271.     write_byte(0,56,0x40);
  1272.     write_byte(0,57,0x40);
  1273.     
  1274.     write_byte(1,55,0x80); /* hamming test - load color reg 0:0 first... */
  1275.     write_byte(1,56,0x80);
  1276.     write_byte(1,57,0x80);
  1277.  
  1278.     write_byte(2,55,0xC0); /* hamming test - load color reg 0:0 first... */
  1279.     write_byte(2,56,0xC0);
  1280.     write_byte(2,57,0xC0);
  1281.     
  1282.     for (vx=0; vx<256; vx++) /* then build 63-0 each of three ways */
  1283.       {
  1284.         write_byte(vx+3,55,((255-vx) >> 2)+0x80); /* write LOTS of HAM data! */
  1285.         write_byte(vx+3,56,((255-vx) >> 2)+0xC0);
  1286.         write_byte(vx+3,57,((255-vx) >> 2)+0x40);
  1287.       }
  1288.     /* write hammed grey scale... */
  1289.     write_byte(0,60,0x80); /* hamming test - load color reg 0:0 first... */
  1290.     write_byte(1,60,0xC0); /* hamming test - load color reg 0:0 first... */
  1291.     write_byte(2,60,0x40); /* hamming test - load color reg 0:0 first... */
  1292.     i=3;
  1293.     for (vx=0; vx<64; vx++)
  1294.       {
  1295.          write_byte(i++,60,vx+0x80);
  1296.          write_byte(i++,60,vx+0xC0);
  1297.          write_byte(i++,60,vx+0x40);
  1298.       }
  1299.     write_byte(0,63,0x80); /* hamming test - load color reg 0:0 first... */
  1300.     write_byte(1,63,0xC0); /* hamming test - load color reg 0:0 first... */
  1301.     write_byte(2,63,0x40); /* hamming test - load color reg 0:0 first... */
  1302.     i=3;
  1303.     for (vx=63; vx>=0; vx--)
  1304.       {
  1305.          write_byte(i++,63,vx+0x80);
  1306.          write_byte(i++,63,vx+0xC0);
  1307.          write_byte(i++,63,vx+0x40);
  1308.       }
  1309.     if (hidden) ScreenToFront(scr);
  1310.   }
  1311.  
  1312. /*
  1313.  * show_luma_pic()
  1314.  *
  1315.  * Use the GREEN buffer pointer to generate a B&W rendering. Color registers
  1316.  * are set to 256 grey levels in the "runner()" routine.
  1317.  */
  1318.  
  1319. void show_luma_pic()
  1320.   {
  1321.   int h,v,hl,vl,lbase,start;
  1322.     WriteRegCookie(4,0);
  1323.     make_luma_palette();
  1324.     start=4;
  1325.     if (lacer) start=8;
  1326.     hl = xdim; vl = ydim; /* requested dimensions */
  1327.     if (lacer) /* is this an interlace screen? */
  1328.       {
  1329.         if (vl > 400) vl = 400;
  1330.       }
  1331.     else
  1332.       {
  1333.         if (vl > 200) vl = 200;
  1334.       }
  1335.     if (hl > 320) hl = 320;
  1336.     for(v=start; v<vl; v++)
  1337.       {
  1338.         lbase = (v+y_offset)*xdim;
  1339.         write_byte(0,v,0x01); /* this prevents a full like of color zero. */
  1340.         for (h=1; h<hl; h++)
  1341.           {
  1342.             write_byte(h,v,*(green+lbase+h+x_offset) << shifter);
  1343.           }
  1344.       }
  1345.   }
  1346.  
  1347.  
  1348. /*
  1349.  * show_ip_file()
  1350.  *
  1351.  * This routine will show a NewTek format "ip" picture; it's a _very_
  1352.  * simple routine, but serves to show a nice easy application.
  1353.  */
  1354.  
  1355. void show_ip_file()
  1356.   {
  1357.   int h,v,hl,vl,start;
  1358.   char mybyte;
  1359.   FILE *fp;
  1360.     WriteRegCookie(4,0);
  1361.     make_luma_palette();
  1362.     start=4;
  1363.     if (!xdim) hl=320;
  1364.     if (!ydim) vl=200;
  1365.     if (!(fp=fopen(&ip_file[0],"r")))
  1366.       {
  1367.         return;
  1368.       }
  1369.     for(v=start; v<vl; v++)
  1370.       {
  1371.         write_byte(0,v,0x01); /* Dummy pixel to handle turn off problems */
  1372.         if (fread(&mybyte,1,1,fp) != 1)
  1373.           {
  1374.             fclose(fp);
  1375.             return;
  1376.           }
  1377.         for (h=1; h<hl; h++)
  1378.           {
  1379.             if (fread(&mybyte,1,1,fp) != 1)
  1380.               {
  1381.                 fclose(fp);
  1382.                 return;
  1383.               }
  1384.             write_byte(h,v,mybyte);
  1385.           }
  1386.       }
  1387.     fclose(fp);
  1388.     get_ip=0;
  1389.   }
  1390.  
  1391. /*
  1392.  * showregpic6()
  1393.  *
  1394.  * This function will attempt to display buffers that were (presumably)
  1395.  * passed in at the commands startup. See the -r, -g and -b options, as
  1396.  * well as the -x and -y options.
  1397.  *
  1398.  * 18 bit
  1399.  */
  1400.  
  1401. void showregpic6()
  1402.   {
  1403.   int h,v,hl,vl,lbase,start;
  1404.     start=4;
  1405.     WriteRegCookie(4,0);
  1406.     gen_even_palette(0);
  1407.     if (lacer) start=8;
  1408.     hl = xdim; vl = ydim; /* requested dimensions */
  1409.     if (lacer)
  1410.       {
  1411.         if (vl > 400) vl = 400;
  1412.       }
  1413.     else
  1414.       {
  1415.         if (vl > 200) vl = 200;
  1416.       }
  1417.     if (hl > 320) hl = 320;
  1418.     for(v=start; v<vl; v++)
  1419.       {
  1420.         lbase = v*xdim;
  1421.         write_byte(0,v,0x01);
  1422.         for (h=1; h<hl; h++)
  1423.           {
  1424.             write_byte(h,v,((red[lbase+h]/43)*42) +
  1425.                          ((green[lbase+h]/37)*6)  +
  1426.                            (blue[lbase+h]/43) );
  1427.           }
  1428.       }
  1429.   }
  1430.  
  1431. /*
  1432.  * showregpic8()
  1433.  *
  1434.  * This function will attempt to display buffers that were (presumably)
  1435.  * passed in at the commands startup. See the -r, -g and -b options, as
  1436.  * well as the -x and -y options.
  1437.  *
  1438.  * 24 bit
  1439.  */
  1440.  
  1441. void showregpic8()
  1442.   {
  1443.   int h,v,hl,vl,lbase,start;
  1444.     WriteRegCookie(4,0);
  1445.     gen_even_palette(0);
  1446.     start=4;
  1447.     if (lacer) start=8;
  1448.     hl = xdim; vl = ydim; /* requested dimensions */
  1449.     if (lacer)
  1450.       {
  1451.         if (vl > 400) vl = 400;
  1452.       }
  1453.     else
  1454.       {
  1455.         if (vl > 200) vl = 200;
  1456.       }
  1457.     if (hl > 320) hl = 320;
  1458.     for(v=start; v<vl; v++)
  1459.       {
  1460.         lbase = v*xdim;
  1461.         write_byte(0,v,0x01);
  1462.         for (h=1; h<hl; h++)
  1463.           {
  1464.             write_byte(h,v,((red[lbase+h]/43)*42) +
  1465.                          ((green[lbase+h]/37)*6)  +
  1466.                            (blue[lbase+h]/43) );
  1467.           }
  1468.       }
  1469.   }
  1470.  
  1471. /*
  1472.  * showhampic()
  1473.  *
  1474.  * This function is a "pure" ham display routine. It does NOT use the
  1475.  * registers - only hamming techniques. It's also (if only because it's
  1476.  * in 'c') not an optomized display routine by any means. That's up to you.
  1477.  *
  1478.  *        write_byte(h,v,0x80+currr);
  1479.  *        write_byte(h,v,0xC0+currg);
  1480.  *        write_byte(h,v,0x40+currb);
  1481.  *
  1482.  * This routine expects you to have provided the RGB buffer pointers
  1483.  * (the -r -g and -b cmd line switches) and looks at those points
  1484.  * using dimensions gleaned from the -x and -y switches to generate
  1485.  * a complete HAM (no register calls at all) image. This means that
  1486.  * fringing is at a maximum; there are so many ways to allocate
  1487.  * registers for a HAM display, we just wanted to make clear how
  1488.  * HAM displays are handled in general, here. Another piece of
  1489.  * source code will detail register-fixup HAM mode handling all
  1490.  * by itself - it's not the only way, but it will be one way.
  1491.  *
  1492.  * 18 bit buffer data
  1493.  */
  1494.  
  1495. void showhampic6()
  1496.   {
  1497.   int h,v,hl,vl,lbase,start;
  1498.   short last_color,spinner;
  1499.   unsigned char lastr,lastg,lastb;
  1500.   unsigned char currr,currg,currb;
  1501.   unsigned char dr,dg,db;
  1502.     WriteHamCookie(4,0);
  1503.     inc_palette(0);             /* write palette at ham cookie starting row */
  1504.     last_color=0;
  1505.     start=4;
  1506.     if (lacer) start = 8;
  1507.     hl = xdim; vl = ydim; /* requested dimensions */
  1508.     if (lacer)
  1509.       {
  1510.         if (vl > 400) vl = 400;
  1511.       }
  1512.     else
  1513.       {
  1514.         if (vl > 200) vl = 200;
  1515.       }
  1516.     if (hl > 320) hl = 320;
  1517.     spinner=0;
  1518.     for(v=start; v<vl; v++)
  1519.       {
  1520.         lbase = v*xdim;
  1521.         write_byte(0,v,0x80); /* begin as BLACK */
  1522.         write_byte(0,v,0xC0);
  1523.         write_byte(0,v,0x40);
  1524.         lastr=0; lastg=0; lastb=0;
  1525.         for (h=3; h<hl; h++)
  1526.           {
  1527.             currr = red[lbase+h] & 0x3f;
  1528.             currg = green[lbase+h] & 0x3f;
  1529.             currb = blue[lbase+h] & 0x3f;
  1530.             if (currr > lastr) dr = currr-lastr; else dr = lastr - currr;
  1531.             if (currg > lastg) dg = currg-lastg; else dg = lastg - currg;
  1532.             if (currb > lastb) db = currb-lastb; else db = lastb - currb;
  1533.             if ((dr > dg) && (dr > db))
  1534.               {
  1535.                 write_byte(h,v,0x80+currr);
  1536.                 lastr = currr;
  1537.               }
  1538.             else if ((dg > dr) && (dg > db))
  1539.               {
  1540.                 write_byte(h,v,0xC0+currg);
  1541.                 lastg = currg;
  1542.               }
  1543.             else if ((db > dr) && (db > dg))
  1544.               {
  1545.                 write_byte(h,v,0x40+currb);
  1546.                 lastb = currb;
  1547.               }
  1548.             else if ((dr > dg) || (dr > db))
  1549.               {
  1550.                 write_byte(h,v,0x80+currr);
  1551.                 lastr = currr;
  1552.               }
  1553.             else if ((dg > dr) || (dg > db))
  1554.               {
  1555.                 write_byte(h,v,0xC0+currg);
  1556.                 lastg = currg;
  1557.               }
  1558.             else if ((db > dg) || (db > dr))
  1559.               {
  1560.                 write_byte(h,v,0x40+currb);
  1561.                 lastb = currb;
  1562.               }
  1563.             else
  1564.               {
  1565.                  switch(spinner)
  1566.                    {
  1567.                      case 0:
  1568.                        {
  1569.                          spinner=1;
  1570.                          write_byte(h,v,0x80+currr);
  1571.                          lastr = currr;
  1572.                          break;
  1573.                        }
  1574.                      case 1:
  1575.                        {
  1576.                          write_byte(h,v,0xC0+currg);
  1577.                          lastg = currg;
  1578.                          spinner=2;
  1579.                          break;
  1580.                        }
  1581.                      case 2:
  1582.                        {
  1583.                          write_byte(h,v,0x40+currb);
  1584.                          lastg = currb;
  1585.                          spinner=0;
  1586.                          break;
  1587.                        }
  1588.                    }
  1589.               }
  1590.           }
  1591.       }
  1592.   }
  1593.  
  1594. /*
  1595.  * showhampic8()
  1596.  *
  1597.  * This routine expects you to have provided the RGB buffer pointers
  1598.  * (the -r -g and -b cmd line switches) and looks at those points
  1599.  * using dimensions gleaned from the -x and -y switches to generate
  1600.  * complete HAM (no register calls at all) image. This means that
  1601.  * fringing is at a maximum; there are so many ways to allocate
  1602.  * registers for a HAM display, we just wanted to make clear how
  1603.  * HAM displays are handled in general, here. Another piece of
  1604.  * source code will detail register-fixup HAM mode handling all
  1605.  * by itself - it's not the only way, but it will be one way.
  1606.  *
  1607.  * 24 bit buffer data
  1608.  */
  1609.  
  1610. void showhampic8()
  1611.   {
  1612.   int h,v,hl,vl,lbase,start;
  1613.   short last_color,spinner;
  1614.   unsigned char lastr,lastg,lastb;
  1615.   unsigned char currr,currg,currb;
  1616.   unsigned char dr,dg,db;
  1617.     WriteHamCookie(4,0);
  1618.     inc_palette(0);             /* write palette at ham cookie starting row */
  1619.     last_color=0;
  1620.     start=4;
  1621.     if (lacer) start = 8;
  1622.     hl = xdim; vl = ydim; /* requested dimensions */
  1623.     if (lacer)
  1624.       {
  1625.         if (vl > 400) vl = 400;
  1626.       }
  1627.     else
  1628.       {
  1629.         if (vl > 200) vl = 200;
  1630.       }
  1631.     if (hl > 320) hl = 320;
  1632.     spinner=0;
  1633.     for(v=start; v<vl; v++)
  1634.       {
  1635.         lbase = v*xdim;
  1636.         write_byte(0,v,0x80); /* begin as BLACK */
  1637.         write_byte(0,v,0xC0);
  1638.         write_byte(0,v,0x40);
  1639.         lastr=0; lastg=0; lastb=0;
  1640.         for (h=3; h<hl; h++)
  1641.           {
  1642.             currr = (red[lbase+h]>>2) & 0x3f;
  1643.             currg = (green[lbase+h]>>2) & 0x3f;
  1644.             currb = (blue[lbase+h]>>2) & 0x3f;
  1645.             if (currr > lastr) dr = currr-lastr; else dr = lastr - currr;
  1646.             if (currg > lastg) dg = currg-lastg; else dg = lastg - currg;
  1647.             if (currb > lastb) db = currb-lastb; else db = lastb - currb;
  1648.             if ((dr > dg) && (dr > db))
  1649.               {
  1650.                 write_byte(h,v,0x80+currr);
  1651.                 lastr = currr;
  1652.               }
  1653.             else if ((dg > dr) && (dg > db))
  1654.               {
  1655.                 write_byte(h,v,0xC0+currg);
  1656.                 lastg = currg;
  1657.               }
  1658.             else if ((db > dr) && (db > dg))
  1659.               {
  1660.                 write_byte(h,v,0x40+currb);
  1661.                 lastb = currb;
  1662.               }
  1663.             else if ((dr > dg) || (dr > db))
  1664.               {
  1665.                 write_byte(h,v,0x80+currr);
  1666.                 lastr = currr;
  1667.               }
  1668.             else if ((dg > dr) || (dg > db))
  1669.               {
  1670.                 write_byte(h,v,0xC0+currg);
  1671.                 lastg = currg;
  1672.               }
  1673.             else if ((db > dg) || (db > dr))
  1674.               {
  1675.                 write_byte(h,v,0x40+currb);
  1676.                 lastb = currb;
  1677.               }
  1678.             else
  1679.               {
  1680.                  switch(spinner)
  1681.                    {
  1682.                      case 0:
  1683.                        {
  1684.                          spinner=1;
  1685.                          write_byte(h,v,0x80+currr);
  1686.                          lastr = currr;
  1687.                          break;
  1688.                        }
  1689.                      case 1:
  1690.                        {
  1691.                          write_byte(h,v,0xC0+currg);
  1692.                          lastg = currg;
  1693.                          spinner=2;
  1694.                          break;
  1695.                        }
  1696.                      case 2:
  1697.                        {
  1698.                          write_byte(h,v,0x40+currb);
  1699.                          lastg = currb;
  1700.                          spinner=0;
  1701.                          break;
  1702.                        }
  1703.                    }
  1704.               }
  1705.           }
  1706.       }
  1707.   }
  1708.  
  1709. /*
  1710.  * make_cie()
  1711.  *
  1712.  * maps 3-dimensional [(R:G:B)] color map to two dimensional
  1713.  * screen (memory) space. Big hack.. but it sure is pretty!
  1714.  * If the rgb buffer pointers are initialized, it'll write the
  1715.  * image to 6 bits precision to those buffers... this essentially
  1716.  * passes the color map "out" to the calling program IF the -r -g and -b
  1717.  * switches are specifed. If not, it just gets drawn to the screen.
  1718.  */
  1719.  
  1720. void make_cie()
  1721.   {
  1722.   int r_dim, g_dim, b_dim;
  1723.   int px,py,ymul,diag,base;
  1724.   int rd,bd,rv,bv;
  1725.   float gv,gd;
  1726.   int diag_len;
  1727.     WriteRegCookie(4,0);
  1728.     gen_even_palette(0);
  1729.     b_dim=0;
  1730.     for (r_dim=0; r_dim<64; r_dim++)
  1731.       {
  1732.         for (g_dim=0; g_dim<64; g_dim++)
  1733.           {
  1734.             px = 132 + r_dim;
  1735.             py = 132 - g_dim;
  1736.             write_RGB(px,py,r_dim << 2,g_dim << 2, b_dim <<2);
  1737.             ymul = (py*xdim)+px;
  1738.             if (red)   *(red  +ymul) = r_dim;
  1739.             if (green) *(green+ymul) = g_dim;
  1740.             if (blue)  *(blue +ymul) = b_dim;
  1741.           }
  1742.       }
  1743.     g_dim=0;
  1744.     for (r_dim=0; r_dim<64; r_dim++)
  1745.       {
  1746.         for (b_dim=0; b_dim<64; b_dim++)
  1747.           {
  1748.             px = 132 + r_dim;
  1749.             py = 132 + b_dim;
  1750.             write_RGB(px,py,r_dim << 2,g_dim << 2, b_dim <<2);
  1751.             ymul = (py*xdim)+px;
  1752.             if (red)   *(red  +ymul) = r_dim;
  1753.             if (green) *(green+ymul) = g_dim;
  1754.             if (blue)  *(blue +ymul) = b_dim;
  1755.           }
  1756.       }
  1757.     r_dim=0;
  1758.     for (g_dim=0; g_dim<64; g_dim++)
  1759.       {
  1760.         for (b_dim=0; b_dim<64; b_dim++)
  1761.           {
  1762.             px = 132 - g_dim;
  1763.             py = 132 + b_dim;
  1764.             write_RGB(px,py,r_dim << 2,g_dim << 2, b_dim <<2);
  1765.             ymul = (py*xdim)+px;
  1766.             if (red)   *(red  +ymul) = r_dim;
  1767.             if (green) *(green+ymul) = g_dim;
  1768.             if (blue)  *(blue +ymul) = b_dim;
  1769.           }
  1770.       }
  1771.     /* second quadrant: */
  1772.     b_dim=0;
  1773.     for (r_dim=0; r_dim<64; r_dim++)
  1774.       {
  1775.         for (g_dim=0; g_dim<64; g_dim++)
  1776.           {
  1777.             px = 68 + g_dim;
  1778.             py = 68 - r_dim;
  1779.             write_RGB(px,py,(63-r_dim) << 2,(63-g_dim) << 2, (63-b_dim) <<2);
  1780.             ymul = (py*xdim)+px;
  1781.             if (red)   *(red  +ymul) = (63-r_dim);
  1782.             if (green) *(green+ymul) = (63-g_dim);
  1783.             if (blue)  *(blue +ymul) = (63-b_dim);
  1784.           }
  1785.       }
  1786.     g_dim=0;
  1787.     for (r_dim=0; r_dim<64; r_dim++)
  1788.       {
  1789.         for (b_dim=0; b_dim<64; b_dim++)
  1790.           {
  1791.             px = 68 - b_dim;
  1792.             py = 68 - r_dim;
  1793.             write_RGB(px,py,(63-r_dim) << 2,(63-g_dim) << 2, (63-b_dim) <<2);
  1794.             ymul = (py*xdim)+px;
  1795.             if (red)   *(red  +ymul) = (63-r_dim);
  1796.             if (green) *(green+ymul) = (63-g_dim);
  1797.             if (blue)  *(blue +ymul) = (63-b_dim);
  1798.           }
  1799.       }
  1800.     r_dim=0;
  1801.     for (g_dim=0; g_dim<64; g_dim++)
  1802.       {
  1803.         for (b_dim=0; b_dim<64; b_dim++)
  1804.           {
  1805.             px = 68 - b_dim;
  1806.             py = 68 + g_dim;
  1807.             write_RGB(px,py,(63-r_dim) << 2,(63-g_dim) << 2, (63-b_dim) <<2);
  1808.             ymul = (py*xdim)+px;
  1809.             if (red)   *(red  +ymul) = (63-r_dim);
  1810.             if (green) *(green+ymul) = (63-g_dim);
  1811.             if (blue)  *(blue +ymul) = (63-b_dim);
  1812.           }
  1813.       }
  1814.     /* diagonal space! */
  1815.     for (base=0; base<64; base++) /* x diagonals */
  1816.       {
  1817.         diag_len = 64-base; /* <-- note! not base of ZERO */
  1818.         rd = (63/diag_len);
  1819.         gd = ((63-((float)base)) - ((float)base)) / ((float)diag_len);
  1820.         bd = (63/diag_len);
  1821.         rv = 63; gv=63-base; bv=63;
  1822.         px = base+68;
  1823.         py = 68;
  1824.         for (diag=base; diag<64; diag++)
  1825.           {
  1826.             write_RGB(px,py,rv << 2,((int)gv) << 2,bv <<2);
  1827.             ymul = (py*xdim)+px;
  1828.             if (red)   *(red  +ymul) = rv;
  1829.             if (green) *(green+ymul) = gv;
  1830.             if (blue)  *(blue +ymul) = bv;
  1831.             rv -= rd;
  1832.             gv -= gd;
  1833.             bv -= bd;
  1834.             px++; py++;
  1835.           }
  1836.       }
  1837.     for (base=0; base<64; base++) /* x diagonals */
  1838.       {
  1839.         diag_len = 64-base; /* <-- note! not base of ZERO */
  1840.         rd = (63/diag_len);
  1841.         gd = ((63-((float)base)) - ((float)base)) / ((float)diag_len);
  1842.         bd = (63/diag_len);
  1843.         rv = 63; gv=63-base; bv=63;
  1844.         px = 68;
  1845.         py = base+68;
  1846.         for (diag=base; diag<64; diag++)
  1847.           {
  1848.             write_RGB(px,py,rv << 2,((int)gv) << 2,bv <<2);
  1849.             ymul = (py*xdim)+px;
  1850.             if (red)   *(red  +ymul) = rv;
  1851.             if (green) *(green+ymul) = gv;
  1852.             if (blue)  *(blue +ymul) = bv;
  1853.             rv -= rd;
  1854.             gv -= gd;
  1855.             bv -= bd;
  1856.             px++; py++;
  1857.           }
  1858.       }
  1859.     for (base=0; base<64; base++)
  1860.       {
  1861.         write_RGB(base+68,base+68,(63-base) << 2,(63-base) << 2,(63-base) << 2);
  1862.         ymul = ((base+68)*xdim)+base+68;
  1863.         if (red)   *(red  +ymul) = 63-base;
  1864.         if (green) *(green+ymul) = 63-base;
  1865.         if (blue)  *(blue +ymul) = 63-base;
  1866.       }
  1867.   }
  1868.  
  1869. /*
  1870.  * This handles the various options and runs the program.
  1871.  */
  1872.  
  1873. runner(parm)
  1874.   int parm;
  1875.   {
  1876.   int i,j;
  1877.   unsigned char k;
  1878.     if (parm) return(parm);     /* watch for setup/parm errors */
  1879.     if (ydim > 240)
  1880.       {
  1881.         NewScreenStructure.ViewModes |= LACE;
  1882.         NewScreenStructure.Height = 400;
  1883.         lacer=1;
  1884.       }
  1885.     if (!(scr=OpenScreen(&NewScreenStructure))) return(NO_SCREEN);
  1886.     fp0 = (unsigned char*)scr->BitMap.Planes[0]; /* get quick bitplane ptrs */
  1887.     fp1 = (unsigned char*)scr->BitMap.Planes[1];
  1888.     fp2 = (unsigned char*)scr->BitMap.Planes[2];
  1889.     fp3 = (unsigned char*)scr->BitMap.Planes[3];
  1890.     j=16000;
  1891.     k=0x55;
  1892.     if (write_odd) k=0xaa;
  1893.     if (lacer) j=32000;
  1894.     for (i=0; i<j; i++) /* fills a bitplane so no C0 detection */
  1895.       {
  1896.         *(fp0+i) = k;
  1897.       }
  1898.     make_hame_palette();        /* this sets up our AMIGA palette */
  1899.  
  1900.     /*
  1901.      * now we're set up to run in HAM-E _or_ REG mode. what to
  1902.      * do (for this program) depends on the incoming cmd line
  1903.      * options; these set various flags - we test them now, and
  1904.      * call routines as appropriate for the flags.
  1905.      */
  1906.  
  1907.     if (sample) /* this is all a huge hack, here. :^) */
  1908.       {
  1909.         bugger(104);                /* generates data to view of various types */
  1910.       }
  1911.     else if (ham_reg) /* want a ham drawing */
  1912.       {
  1913.         showhampic6();
  1914.       }
  1915.     else if (get_ip) /* want to read in an IP file */
  1916.       {
  1917.         show_ip_file();
  1918.       }
  1919.     else if (luma_mode) /* want a registered, 256 grey level drawing */
  1920.       {
  1921.         show_luma_pic();
  1922.       }
  1923.     else if (chroma)
  1924.       {
  1925.         make_cie();
  1926.       }
  1927.     else /* want a register drawing */
  1928.       {
  1929.         showregpic6();
  1930.       }
  1931.     if (iff_flag) /* user want iff file saved from this??? */
  1932.       {
  1933.         WBenchToFront(); /* get WB for faster saves in chip-only amiga */
  1934.         writeiff(&iff_file[0]);
  1935.         ScreenToFront(scr);
  1936.       }
  1937.     /*
  1938.      * after display, we may want to delay - if you don't want this,
  1939.      * then place a "get_ip=1;" in your new routine.
  1940.      */
  1941.     if (!get_ip)
  1942.       {
  1943.         if (delay_time) /* set by "-d" cmd line switch */
  1944.           {
  1945.             if (delay_time < 50) delay_time=50;
  1946.             Delay(delay_time);
  1947.           }
  1948.         else
  1949.           {
  1950.             Delay(500);                 /* wait 10 seconds to see "stuff" */
  1951.           }
  1952.       }
  1953.     CloseScreen(scr);  /* and bail out. */
  1954.     return(0);
  1955.   }
  1956.  
  1957. /*
  1958.  * main()
  1959.  *
  1960.  * runs the whole show, more or less.
  1961.  */
  1962.  
  1963. void main(argc,argv)
  1964.   int argc;
  1965.   char *argv[];
  1966.   {
  1967.     cleanup(runner(init(argc,argv)));
  1968.   }
  1969.  
  1970.  
  1971.