[comp.sources.atari.st] v01i057: rsctoc -- convert .RSC file to .C file

koreth@ssyx.ucsc.edu (Steven Grimm) (06/15/88)

Submitted-by: uunet!van-bc!resrch!bobs (Robert J. Silliker)
Posting-number: Volume 1, Issue 57
Archive-name: rsctoc

[This takes a resource file and generates the equivalent
 C source file. -sg]

#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#	Run the following text with /bin/sh to create:
#	  MAIN.C
#	  MAKEFILE
#	  README
#	  RSCTOC.DOC
#
sed 's/^X//' << 'SHAR_EOF' > MAIN.C &&
X/***************************************************/
X/*  						   */
X/*  		     RSCTOC  V1.0		   */
X/*  						   */
X/*  Copyright (c) 1988, by Robert Joseph Silliker  */
X/*  		  All Rights Reserved   	   */
X/*  	Permission is granted for unrestricted     */
X/*  		 non-commercial use		   */
X/*  						   */
X/***************************************************/
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <osbind.h>
X#include <gemdefs.h>
X#include <obdefs.h>
X
Xstatic char *copyright[] = "RSCTOC V1.0\nCopyright (c) 1988, by\
X Robert Joseph Silliker\nAll Rights Reserved\n\
X Permission is granted for unrestricted non-commercial use\n";
X
Xlong _stksize = 16000;
X
XRSHDR *rschead;			/* Pointer to the resource file header. */
Xchar *out_path = NULL;		/* Path to output file. */
Xchar *rsc_path = NULL;		/* Path to input file.  */
XFILE *fp = stdout;		/* Default output file. */
Xchar *prefix= "";		/* Prefix to the names of arrays. */
X
X#define MAXTREES 512		/* Maximum number of object trees per file. */
X
XOBJECT *objects;		/* Pointer to the base of the objects. */
XOBJECT *trindex[MAXTREES];	/* One pointer per object tree. */
X
Xchar *progname = "rsctoc.ttp";	/* Program name (no argv[0]) */
X
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X  int i;
X  extern char *rsc_path, *out_path, *prefix;
X  extern FILE *fp;
X  
X  if((argc != 2) && (argc != 4) && (argc != 6))
X    usage("Incorrect number of arguments.");
X
X  rsc_path = argv[1];
X
X  for(i=2; i<argc; i+=2) {	    /* This lets option arguments like */
X    if(!strcmp(argv[i], "-p"))	    /* rsctoc.ttp rsc_file -f file1 -f file2 */
X      prefix = argv[i+1];	    /* rsctoc.ttp rsc_file -p XXXX -p YYYY */
X    else if(!strcmp(argv[i], "-o")) /* without a usage error. */
X      out_path = argv[i+1];
X    else
X      usage("Illegal option.");
X  }
X
X  if(!init_prog()) {
X    put_header();
X    make_tedinfo();
X    make_icon();
X    make_bitblk();
X    make_object();
X    make_index();
X    make_fix();
X  }
X
X  clean_up();
X}
X
X
X/*----------------------------------------*/
X/* Output the usage message and terminate */
X/* the program.                           */
X/*----------------------------------------*/
X
Xusage(s)
Xchar *s;
X{
X  extern char *progname;
X
X  if(s)
X    fprintf(stderr, "%s: %s\n", progname, s);
X
X  fprintf(stderr, "Usage: %s rsc_file [-p prefix] [-o outfile]\n", progname);
X
X  exit(2);
X}
X
X
X/*-------------------------------------------*/
X/* Output an error message and terminate the */
X/* program gracefully if the caller sets the */
X/* terminate flag.  The value of the flag    */
X/* used to terminate is returned by the      */
X/* program.                                  */
X/*-------------------------------------------*/
X
Xmperror(terminate, s)
Xint terminate;
Xchar *s;
X{
X  extern char *progname;
X
X  fprintf(stderr, "%s: %s\n", progname, s);
X
X  if(terminate) {
X    clean_up();
X    exit(terminate);
X  }
X}
X
X
X/*-------------------------*/
X/* Initialize the program. */
X/*-------------------------*/
X
Xint init_prog()
X{
X  int i;
X  extern char *rsc_path, *out_path;
X  extern FILE *fp;
X  extern RSHDR *rschead;
X
X  if(!myrsrc_load(rsc_path))
X    mperror(1, "Error getting resource file.");
X
X  if(out_path != NULL) {
X    if((fp = fopen(out_path, "w")) == NULL)
X      mperror(1, "Can't open output file.");
X  }
X
X  if(rschead->rsh_nobs <= 0)
X    mperror(1, "No object trees to dump.");
X
X  return(0);
X}
X
X
X/*--------------------------------------------*/
X/* Clean up open files, close the workstation */
X/* and close the aes application.             */
X/*--------------------------------------------*/
X
Xclean_up()
X{
X  extern FILE *fp;
X
X  if((fp != stdout) && (fp != NULL))
X    fclose(fp);
X}
X
X
X/*------------------------------*/
X/* Extract tedinfo information. */
X/*------------------------------*/
X
Xmake_tedinfo()
X{
X  int i, first_one;
X  register OBJECT *g;
X  TEDINFO *t;
X  extern char *prefix;
X  extern FILE *fp;
X  extern OBJECT *objects;
X  extern RSHDR *rschead;
X
X  fprintf(fp, "TEDINFO %srs_tedinfo[] = {\n", prefix);
X
X  for(i=0, first_one=1, g=objects; i < rschead->rsh_nobs; i++, g++) {
X    if(g->ob_type == G_FTEXT || g->ob_type == G_FBOXTEXT ||
X       g->ob_type == G_TEXT  || g->ob_type == G_BOXTEXT) {
X
X      if(first_one) {
X  	first_one = 0;
X      }
X      else
X        fprintf(fp, ",\n");
X
X      t = (TEDINFO *)(g->ob_spec);
X
X      if(strlen(t->te_ptext))
X        fprintf(fp, "  {\"%s\", ", t->te_ptext);
X      else
X        fprintf(fp, "  {%sp_to_nul, ", prefix);
X
X      if(strlen(t->te_ptmplt))
X        fprintf(fp, "\"%s\", ", t->te_ptmplt);
X      else
X        fprintf(fp, "%sp_to_nul, ", prefix);
X
X      if(strlen(t->te_pvalid))
X        fprintf(fp, "\"%s\",\n  ", t->te_pvalid);
X      else
X        fprintf(fp, "%sp_to_nul,\n   ", prefix);
X
X      fprintf(fp, "%3d, ", t->te_font);
X      fprintf(fp, "%3d, ", t->te_junk1);
X      fprintf(fp, "%3d, ", t->te_just);
X      fprintf(fp, "%3d, ", t->te_color);
X      fprintf(fp, "%3d, ", t->te_junk2);
X      fprintf(fp, "%3d, ", t->te_thickness);
X      fprintf(fp, "%3d, ", t->te_txtlen);
X      fprintf(fp, "%3d}", t->te_tmplen);
X    }
X  }
X
X  if(!first_one)
X    fprintf(fp, "\n};\n\n");
X  else
X    fprintf(fp, "  0L\n};\n\n");
X}
X
X
X/*---------------------------*/
X/* Extract icon information. */
X/*---------------------------*/
X
Xmake_icon()
X{
X  int i, j, k, numb;
X  int first_one, *p;
X  register OBJECT *g;
X  extern char *prefix;
X  ICONBLK *icon;
X  extern FILE *fp;
X  extern OBJECT *objects;
X  extern RSHDR *rschead;
X
X  for(i=0, numb=0, g=objects; i < rschead->rsh_nobs; i++, g++) {
X    /*----------------------*/
X    /* First do the images. */
X    /*----------------------*/
X
X    if(g->ob_type == G_ICON) {
X      icon = (ICONBLK *)(g->ob_spec);
X
X      fprintf(fp, "int %simask%03d[] = {", prefix, numb);
X      k = icon->ib_hicon * (icon->ib_wicon/16);
X
X      for(j=0, p=icon->ib_pmask; k > 0; j++, p++, k--) {
X        if(!(j % 8))
X          fprintf(fp, "\n  ");
X        fprintf(fp, "0x%04x", *p);
X
X	if(k != 1)
X          fprintf(fp, ",");
X      }
X      fprintf(fp, "\n};\n\n");
X
X      fprintf(fp, "int %sidata%03d[] = {", prefix, numb);
X      k = icon->ib_hicon * (icon->ib_wicon/16);
X
X      for(j=0, p=icon->ib_pdata; k > 0; j++, p++, k--) {
X        if(!(j % 8))
X	  fprintf(fp, "\n   ");
X        fprintf(fp, "0x%04x", *p);
X
X        if(k != 1)
X	  fprintf(fp, ",");
X      }
X
X      fprintf(fp, "\n};\n\n");
X      numb++;
X    }
X  }
X 
X  fprintf(fp, "ICONBLK %srs_iconblk[] = {\n", prefix);
X
X  for(i=0, numb=0, g=objects, first_one=1; i < rschead->rsh_nobs; i++, g++) {
X    /*-----------------------------*/
X    /* Now do the icon structures. */
X    /*-----------------------------*/
X
X    if(g->ob_type == G_ICON) {
X
X      if(first_one)
X        first_one = 0;
X      else
X        fprintf(fp, ",\n");
X
X      icon = (ICONBLK *)(g->ob_spec);
X
X      fprintf(fp, "  {%simask%03d, %sidata%03d, ", prefix, numb, prefix, numb);
X
X      if(strlen(icon->ib_ptext))
X        fprintf(fp, "\"%s\",\n", icon->ib_ptext);
X      else
X        fprintf(fp, "%sp_to_nul, \n", prefix);
X
X      fprintf(fp, "   0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x,\n",
X	          icon->ib_char, icon->ib_xchar, icon->ib_ychar,
X                  icon->ib_xicon, icon->ib_yicon, icon->ib_wicon);
X
X      fprintf(fp, "   0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x}",
X		  icon->ib_hicon, icon->ib_xtext, icon->ib_ytext,
X		  icon->ib_wtext, icon->ib_htext);
X      numb++;
X    }
X  }
X
X  if(!first_one)
X    fprintf(fp, "\n};\n\n");
X  else
X    fprintf(fp, "  0L\n};\n\n");
X}
X
X
X
X/*-----------------------------*/
X/* Extract bitblk information. */
X/*-----------------------------*/
X
Xmake_bitblk()
X{
X  int i, j, k, numb;
X  int first_one, *p;
X  register OBJECT *g;
X  BITBLK *bitblk;
X  extern char *prefix;
X  extern FILE *fp;
X  extern OBJECT *objects;
X  extern RSHDR *rschead;
X
X  for(i=0, numb=0, g=objects; i < rschead->rsh_nobs; i++, g++) {
X    /*----------------------*/
X    /* First do the images. */
X    /*----------------------*/
X
X    if(g->ob_type == G_IMAGE) {
X      bitblk = (BITBLK *)(g->ob_spec);
X
X      fprintf(fp, "int %sbblock%03d[] = {", prefix, numb);
X      k = bitblk->bi_hl * (bitblk->bi_wb/2);
X
X      for(j=0, p=bitblk->bi_pdata; k > 0; j++, p++, k--) {
X        if(!(j % 8))
X          fprintf(fp, "\n  ");
X        fprintf(fp, "0x%04x", *p);
X
X	if(k != 1)
X          fprintf(fp, ",");
X      }
X      fprintf(fp, "\n};\n\n");
X
X      numb++;
X    }
X  }
X
X  fprintf(fp, "BITBLK %srs_bitblk[] = {\n", prefix);
X 
X  for(i=0, numb=0, g=objects, first_one=1; i < rschead->rsh_nobs; i++, g++) {
X    /*-------------------------------*/
X    /* Now do the bitblk structures. */
X    /*-------------------------------*/
X
X    if(g->ob_type == G_IMAGE) {
X
X      if(first_one)
X        first_one = 0;
X      else
X        fprintf(fp, ",\n");
X
X      bitblk = (BITBLK *)(g->ob_spec);
X
X      fprintf(fp, "  {%sbblock%03d, ", prefix, numb);
X
X      fprintf(fp, " 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x}",
X	                    bitblk->bi_wb, bitblk->bi_hl, bitblk->bi_x,
X                            bitblk->bi_y, bitblk->bi_color);
X
X      numb++;
X    }
X  }
X
X  if(!first_one)
X    fprintf(fp, "\n};\n\n");
X  else
X    fprintf(fp, "  0L\n};\n\n");
X}
X
X
X/*-----------------------------------------------*/
X/* Extract object information and change into C. */
X/*-----------------------------------------------*/
X
Xmake_object()
X{
X  int i, ic, bb, ted;
X  int first_one;
X  register OBJECT *g;
X  extern char *prefix;
X  extern FILE *fp;
X  extern OBJECT *objects;
X  extern RSHDR *rschead;
X
X  for(i=0,ic=0,bb=0,ted=0,g=objects,first_one=1; i<rschead->rsh_nobs;i++,g++) {
X    if(first_one) {
X      fprintf(fp, "OBJECT %srs_object[] = {\n", prefix);
X      first_one = 0;
X    }
X    else
X      fprintf(fp, ",\n");
X
X    print_index_comment(g);
X
X    fprintf(fp, "  {%4d,%4d,%4d,0x%04x,0x%04x,0x%04x, ",
X                                g->ob_next, g->ob_head, g->ob_tail,
X                                g->ob_type, g->ob_flags, g->ob_state);
X
X    if(g->ob_type == G_STRING || g->ob_type == G_TITLE
X                              || g->ob_type == G_BUTTON) {
X
X      if(strlen(g->ob_spec))
X        fprintf(fp, "\"%s\",", g->ob_spec);
X      else
X        fprintf(fp, "%sp_to_nul,", prefix);
X    }
X    else if(g->ob_type == G_FTEXT || g->ob_type == G_FBOXTEXT
X                                  || g->ob_type == G_TEXT
X                                  || g->ob_type == G_BOXTEXT) {
X      fprintf(fp, "\&%srs_tedinfo[%d],", prefix, ted);
X      ted++;
X    }
X    else if(g->ob_type == G_ICON) {
X      fprintf(fp, "\&%srs_iconblk[%d],", prefix, ic);
X      ic++;
X    }
X    else if(g->ob_type == G_IMAGE) {
X      fprintf(fp, "\&%srs_bitblk[%d],", prefix, bb);
X      bb++;
X    }
X    else
X      fprintf(fp, "0x%08lxL,", g->ob_spec);
X
X    fprintf(fp, "%4d,%4d,%4d,%4d}",
X		g->ob_x, g->ob_y, g->ob_width, g->ob_height);
X  }
X
X  if(!first_one)
X    fprintf(fp, "\n};\n\n");
X}
X
X
X/*-----------------------------------------------*/
X/* Build the array of tree pointers and generate */
X/* the structure size macros.                    */
X/*-----------------------------------------------*/
X
Xmake_index()
X{
X  int i, index, first_one;
X  extern char *prefix;
X  extern FILE *fp;
X  extern OBJECT *objects, *trindex[];
X  extern RSHDR *rschead;
X
X  for(i=0, first_one=1; i < rschead->rsh_ntree; i++) {
X    if(first_one) {
X      fprintf(fp, "OBJECT *%srs_trindex[] = {\n", prefix);
X      first_one = 0;
X    }
X    else
X      fprintf(fp, ",\n");
X
X    index = (trindex[i] - objects);
X
X    fprintf(fp, "  &%srs_object[%d]", prefix, index);
X  }
X  if(!first_one)
X    fprintf(fp, "\n};\n\n");
X
X  fprintf(fp, "#define %sNUM_TI %d\n", prefix, rschead->rsh_nted);
X  fprintf(fp, "#define %sNUM_IB %d\n", prefix, rschead->rsh_nib);
X  fprintf(fp, "#define %sNUM_BB %d\n", prefix, rschead->rsh_nbb);
X  fprintf(fp, "#define %sNUM_OBS %d\n", prefix, rschead->rsh_nobs);
X  fprintf(fp, "#define %sNUM_TREE %d\n\n\n", prefix, rschead->rsh_ntree);
X}
X
X
X/*------------------------------------------------------*/
X/* Output the include #ifdef for the object definition  */
X/* header file.  Output a single NUL character pointer  */
X/* into the C source.  This will be used as the pointer */
X/* to an empty character string wherever strings have   */
X/* zero length.                                         */
X/*------------------------------------------------------*/
X
Xput_header()
X{
X  extern FILE *fp;
X
X  fprintf(fp, "#ifndef OBJECT\n");
X  fprintf(fp, "#include <obdefs.h>\n");
X  fprintf(fp, "#endif\n\n");
X  fprintf(fp, "static char %sp_to_nul[1] = \"\";\n\n", prefix);
X}
X
X
X/*-------------------------------------------*/
X/* Output code that will fix up the objects. */
X/*-------------------------------------------*/
X
Xmake_fix()
X{
X  extern char *prefix;
X  extern FILE *fp;
X
X  fprintf(fp, "%sfix_objects()\n{\n", prefix);
X  fprintf(fp, "  register int i;\n\n");
X  fprintf(fp, "  for(i=0; i<%sNUM_OBS; i++)\n", prefix);
X  fprintf(fp, "    rsrc_obfix(%srs_object, i);\n", prefix);
X  fprintf(fp, "}\n\n");
X}
X
X
X/*--------------------------------*/
X/* Open and read in the rsc file. */
X/* Then call the routine to fix   */
X/* the object pointers.           */
X/*--------------------------------*/
X
Xchar *pbase;			/* Pointer to base of file in memory */
X#define BLKSIZE 8192		/* Number of bytes per read call */
X				/* Don't make this larger than 32767 */
X
Xmyrsrc_load(path)
Xchar *path;
X{
X  long fsize, lseek();
X  int rsc, size;
X  char *p;
X  extern char *pbase;
X
X  if((rsc = open(path, O_RDONLY | O_BINARY)) < 0) {
X    fprintf(stderr, "%s: Can't open '%s'.\n", progname, path);
X    return(0);
X  }
X
X  if((fsize = lseek(rsc, 0L, 2)) < 0)
X    return(0);
X
X  lseek(rsc, 0L, 0);
X
X  if(fsize < sizeof(RSHDR)) {
X    fprintf(stderr, "%s: Resource file is too small.\n", progname);
X    close(rsc);
X    return(0);
X  }
X
X  p = pbase = (char *)(Malloc(fsize));
X  if(pbase == NULL) {
X    fprintf(stderr, "%s: Not enough memory.\n", progname);
X    close(rsc);
X    return(0);
X  }
X
X  do {
X    size = (fsize >= BLKSIZE) ? BLKSIZE : (int)(fsize);
X    if(read(rsc, p, size) != size) {
X      fprintf(stderr, "%s: Read error on '$s'.\n", progname, path);
X      Mfree(pbase);
X      close(rsc);
X      return(0);
X    }
X    p += size;
X    fsize -= (long)(size);
X  } while(fsize > 0L);
X
X  close(rsc);
X
X  fix_pointers();
X
X  return(1);
X}
X
X
X/*------------------------------------------*/
X/* Routine to fix up the resource pointers. */
X/*------------------------------------------*/
X
Xfix_pointers()
X{
X  int i;
X  long *t;
X  extern char *pbase;
X  extern OBJECT *objects, *trindex[];
X  extern RSHDR *rschead;
X
X  /*----------------------------------------------------*/
X  /* Initialize the pointer to the resource file header */
X  /* and a pointer to the base of the object array.     */
X  /*----------------------------------------------------*/
X
X  rschead = (RSHDR *)(pbase);
X  objects = (OBJECT *)(pbase + rschead->rsh_object);
X
X  t = (long *)(pbase + rschead->rsh_trindex);	/* Get pointer to trindex */
X
X  for(i=0; i<rschead->rsh_ntree; i++)
X    trindex[i] = (OBJECT *)(pbase + *(t+i));	/* Build tree pointer */
X
X  /*---------------------------------------------------*/
X  /* Fix all the objects.  No need to go into the maze */
X  /* of head, tail, next because all objects are in a  */
X  /* nice array of size 'rsh_nobs'.                    */
X  /*---------------------------------------------------*/
X
X  for(i=0; i<rschead->rsh_nobs; i++)
X    fix_one_object(objects + i);
X}
X
X
X/*-------------------------------------*/
X/* Fix up the pointers for one object. */
X/*-------------------------------------*/
X
Xfix_one_object(g)
Xregister OBJECT *g;
X{
X  TEDINFO *t;
X  ICONBLK *icon;
X  BITBLK *bitblk;
X  extern char *pbase;
X
X  switch(g->ob_type) {
X    case(G_STRING):
X    case(G_TITLE):
X    case(G_BUTTON):
X      g->ob_spec = (char *)(pbase + (long)(g->ob_spec));
X      break;
X    case(G_FTEXT):
X    case(G_FBOXTEXT):
X    case(G_TEXT):
X    case(G_BOXTEXT):
X      t = (TEDINFO *)(pbase + (long)(g->ob_spec));
X      g->ob_spec = (char *)(t);
X      t->te_ptext = (char *)(pbase + (long)(t->te_ptext));
X      t->te_ptmplt = (char *)(pbase + (long)(t->te_ptmplt));
X      t->te_pvalid = (char *)(pbase + (long)(t->te_pvalid));
X      break;
X    case(G_ICON):
X      icon = (ICONBLK *)(pbase + (long)(g->ob_spec));
X      g->ob_spec = (char *)(icon);
X      icon->ib_pmask = (int *)(pbase + (long)(icon->ib_pmask));
X      icon->ib_pdata = (int *)(pbase + (long)(icon->ib_pdata));
X      icon->ib_ptext = (char *)(pbase + (long)(icon->ib_ptext));
X      break;
X    case(G_IMAGE):
X      bitblk = (BITBLK *)(pbase + (long)(g->ob_spec));
X      g->ob_spec = (char *)(bitblk);
X      bitblk->bi_pdata = (int *)(pbase + (long)(bitblk->bi_pdata));
X      break;
X  }
X}
X
X
X/*---------------------------------*/
X/* Print the rs_trindex[] comment. */
X/*---------------------------------*/
X
Xprint_index_comment(g)
XOBJECT *g;
X{
X  register int i;
X  extern OBJECT *trindex[];
X  extern FILE *fp;
X  extern RSHDR *rschead;
X
X  for(i=0; i<rschead->rsh_ntree; i++) {
X    if(trindex[i] == g)
X      fprintf(fp, "  /* Tree #%d*/\n", i);
X  }
X}
X
X/* END OF FILE */
X
SHAR_EOF
chmod 0600 MAIN.C || echo "restore of MAIN.C fails"
sed 's/^X//' << 'SHAR_EOF' > MAKEFILE &&
X#----------------------------------------------------------------------------
X#		    Makefile to make the program 'rsctoc.ttp'
X#----------------------------------------------------------------------------
X
XOBJECT = rsctoc.ttp
XFILES1 = main.o
X
X$(OBJECT): $(FILES1)
X	$(CC) $(FILES1) -o $(OBJECT)
X
Xclean:
X	$(RM) $(FILES1)
X	$(RM) $(OBJECT)
X
Xarc:
X	arc a rsctoc main.c makefile rsctoc.doc readme
X
X#----------------------------------------------------------------------------
SHAR_EOF
chmod 0600 MAKEFILE || echo "restore of MAKEFILE fails"
sed 's/^X//' << 'SHAR_EOF' > README &&
X
XRsctoc is a program to generate C code out of a resource file.  It has been
Xwritten to be compiled with the Megamax Laser C compiler.  I do not know
Xhow much work it would be to compile it with another compiler.
X
XThe makefile that I use will not be of much use.  I have provided it only
Xas a guide.
X
XBob Silliker
SHAR_EOF
chmod 0600 README || echo "restore of README fails"
sed 's/^X//' << 'SHAR_EOF' > RSCTOC.DOC &&
X    RSCTOC                        VERSION 1.0                        RSCTOC
X
X
X    NAME
X        rsctoc.ttp - a program to generate C source from a resource file.
X
X    AUTHOR
X        Bob Silliker
X
X    COPYRIGHT
X        Copyright (c) 1988 by Robert Joseph Silliker
X        All Rights Reserved.
X        Permission is granted for unrestricted non-commercial use.
X
X    SYNOPSIS
X        rsctoc.ttp rsc_file [-p prefix] [-o file]
X
X    DESCRIPTION
X        Rsctoc is a program to generate C code from a resource file on an
X        Atari St computer.  It will handle the following types; OBJECT,
X        TEDINFO, ICONBLK and BITBLK.  If the command is executed with only
X        a path to the rsc_file then the C code will be displayed on the
X        screen.  To send the output to a file you can use the '-o file'
X        option or to redirect the output with '>file'.
X
X        The C code that is generated includes a small routine to fixup the
X        objects by calling rsrc_obfix() on each object to convert the
X        object's location size from character coordinates to pixel coordinates. 
X        The routine is that is called to fixup the objects is 'fix_objects()'
X        and should be called once during program initialization (calling it
X        more than once is interesting but not useful).
X
X        The -p prefix option is used to add a short unique prefix to the names
X        of the structures, routine and macros that rsctoc creates.  This is
X        very useful when creating library routines that have trees embedded
X        in them (providing a means of preventing name conflicts).
X
X        If rsctoc is executed in the following way
X
X                   rsctoc rsc_file -p my -o file
X
X        Then the C code generated would have 'my' added to the start of the
X        structures, routine and macros.
X
X                   rs_tedinfo      would be      myrs_tedinfo
X                   NUM_TI          would be      myNUM_TI
X                   fix_objects     would be      myfix_objects
X
X    NOTES
X        The program DOES NOT generate the arrays rs_strings[], rs_frstr[],
X        rsfrimg[], or rs_imdope[] arrays.  The program DOES generate the
X        arrays rs_tedinfo[], rs_object[], rs_trindex[], rs_bitblk[],
X        rs_iconblk[] arrays as well as defines the macros NUM_TI, NUMOBS,
X        NUM_TREE, NUM_BB and NUM_IB (modified by the prefix of course).
X
X        Any names that you assigned to objects, trees, images or icons can
X        still be used in your program to access these elements. The program
X        will only handle 512 trees (not objects, images or icons which are
X        only limited by the resource file structure) in one input resource
X        file.
X
X    BUGS
X        There are no known bugs in V1.0. (:->)
X        If you find one fix it.
SHAR_EOF
chmod 0600 RSCTOC.DOC || echo "restore of RSCTOC.DOC fails"
exit 0