]> 4ch.mooo.com Git - 16.git/blobdiff - 16/v2/source/UTIL/CHRMAK/CHRMAK.CC
attempted font system added
[16.git] / 16 / v2 / source / UTIL / CHRMAK / CHRMAK.CC
diff --git a/16/v2/source/UTIL/CHRMAK/CHRMAK.CC b/16/v2/source/UTIL/CHRMAK/CHRMAK.CC
new file mode 100644 (file)
index 0000000..d3ebd7e
--- /dev/null
@@ -0,0 +1,653 @@
+/*\r
+Copyright (C) 1998 BJ Eirich (aka vecna)\r
+This program is free software; you can redistribute it and/or\r
+modify it under the terms of the GNU General Public License\r
+as published by the Free Software Foundation; either version 2\r
+of the License, or (at your option) any later version.\r
+This program is distributed in the hope that it will be useful,\r
+but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
+See the GNU General Public Lic\r
+See the GNU General Public License for more details.\r
+You should have received a copy of the GNU General Public License\r
+along with this program; if not, write to the Free Software\r
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+*/\r
+\r
+// CHRMAK.CC\r
+// V2 PCX to CHR converter w/ makefiles\r
+//\r
+// coded by aen\r
+// aen@verge-rpg.com\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+#include <ctype.h>\r
+#include <string.h>\r
+#include <sys/stat.h>\r
+\r
+#include <conio.h>\r
+\r
+////////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////////\r
+\r
+typedef unsigned char byte;\r
+typedef unsigned short word;\r
+typedef unsigned long quad;\r
+\r
+static void fputw(word w, FILE *fp) { fwrite(&w,1,2,fp); }\r
+static void fputd(quad d, FILE *fp) { fwrite(&d,1,4,fp); }\r
+static word fgetw(FILE *fp) { word w; fread(&w,1,2,fp); return w; }\r
+quad fgetd(FILE *fp) { quad d; fread(&d,1,4,fp); return d; }\r
+\r
+// skips the number of bytes in the file; just seeks past them\r
+static void fskip(int bytes, FILE *fp)\r
+  { fseek(fp,bytes,SEEK_CUR); }\r
+\r
+static void fputraw(char *raw, int bytes, FILE *fp)\r
+  { fwrite(raw, 1,bytes, fp); }\r
+\r
+// writes a null-terminated string to the file\r
+void fputstrz(char *str, FILE *fp)\r
+  { fputraw(str, strlen(str)+1, fp); }\r
+\r
+// writes a string to the file (without the null-terminator), preceeded by\r
+// a quad length marker\r
+static void fputstrn(char *str, FILE *fp)\r
+  { int n=strlen(str)+1; fputd(n,fp); fputraw(str,n,fp); }\r
+\r
+////////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////////\r
+\r
+#define CHRMAK_VER_MAJ 0\r
+#define CHRMAK_VER_MIN 1\r
+#define CHRMAK_VER_STR "0.1b"\r
+#define CHRMAK_AUTHORS "aen"\r
+\r
+// parsing vars\r
+static char *mak_base=0;\r
+static char *makp=0;\r
+static int mak_bytes=0;\r
+static char mak_tok_ident[256];\r
+static char mak_tok_val[256];\r
+static int mak_tok_valn=0;          // numeric val of mak_tok\r
+static int mak_line=0;\r
+\r
+// makefile vars\r
+static char chrmak_makefile[256];\r
+\r
+static char pcx_name[256];      static int got_pcx_name=0;\r
+static char chr_name[256];      static int got_chr_name=0;\r
+static int frame_w=0;           static int got_frame_w=0;\r
+static int frame_h=0;           static int got_frame_h=0;\r
+static int hot_x=0;             static int got_hot_x=0;\r
+static int hot_y=0;             static int got_hot_y=0;\r
+static int hot_w=0;             static int got_hot_w=0;\r
+static int hot_h=0;             static int got_hot_h=0;\r
+static int per_row=0;           static int got_per_row=0;\r
+static int total_frames=0;      static int got_total_frames=0;\r
+static int lidle=0;             static int got_lidle=0;\r
+static int ridle=0;             static int got_ridle=0;\r
+static int uidle=0;             static int got_uidle=0;\r
+static int didle=0;             static int got_didle=0;\r
+static char lscript[256];       static int got_lscript=0;\r
+static char rscript[256];       static int got_rscript=0;\r
+static char uscript[256];       static int got_uscript=0;\r
+static char dscript[256];       static int got_dscript=0;\r
+\r
+void warning(char *message, ...)\r
+{\r
+  static char buffer[256];\r
+  va_list args;\r
+\r
+  va_start(args, message);\r
+  vsprintf(buffer, message, args);\r
+  va_end(args);\r
+\r
+  printf("%s \n", buffer);\r
+}\r
+\r
+static void fatal(char *message, ...)\r
+{\r
+  static char buffer[256];\r
+  va_list args;\r
+\r
+  va_start(args, message);\r
+  vsprintf(buffer, message, args);\r
+  va_end(args);\r
+\r
+  printf("%s \n", buffer);\r
+\r
+  exit(0);\r
+}\r
+\r
+//#ifdef __DJGPP__\r
+// Watcom has one of these\r
+static int filelength(int handle)\r
+{\r
+  struct stat fileinfo;\r
+  if (-1 == fstat(handle, &fileinfo))\r
+    fatal("error fstating");\r
+  return fileinfo.st_size;\r
+}\r
+//#endif\r
+\r
+static int streq(char *a, char *b)\r
+{\r
+  while (*a)\r
+  {\r
+    if (*a++ != *b++)\r
+      return 0;\r
+  }\r
+  return !*b;\r
+}\r
+\r
+static void usage()\r
+{\r
+  printf("usage: chrmak <makefile> \n");\r
+  exit(0);\r
+}\r
+\r
+static void banner()\r
+{\r
+  printf("chrmak v%s \1e by %s \n", CHRMAK_VER_STR, CHRMAK_AUTHORS);\r
+}\r
+\r
+static void parse_args(int argc, char *argv[])\r
+{\r
+  if (argc != 2)\r
+    usage();\r
+\r
+  strcpy(chrmak_makefile, argv[1]);\r
+}\r
+\r
+static void skip_cpp_comment()\r
+{\r
+  makp+=2;\r
+  while (*makp && '\n'!=*makp)\r
+    makp++;\r
+  if (*makp)\r
+    makp++;\r
+}\r
+\r
+static void skip_c_comment()\r
+{\r
+  makp+=2;\r
+  while (*makp && ('*'!=makp[0] || '/'!=makp[1]))\r
+  {\r
+    if ('\n'==*makp)\r
+      mak_line++;\r
+    if ('/'==makp[0] && '*'==makp[1])\r
+      skip_c_comment();\r
+    else makp++;\r
+  }\r
+  if (*makp)\r
+    makp+=2;\r
+}\r
+\r
+static void parse_whitespace()\r
+{\r
+  do {\r
+    if (!*makp)\r
+      return;\r
+    if (isspace(*makp))\r
+    {\r
+      while (*makp && isspace(*makp))\r
+      {\r
+        if ('\n'==*makp)\r
+          mak_line++;\r
+        makp++;\r
+      }\r
+      continue;\r
+    }\r
+    if ('/'==makp[0] && '/'==makp[1])\r
+      { skip_cpp_comment(); continue; }\r
+    if ('/'==makp[0] && '*'==makp[1])\r
+      { skip_c_comment(); continue; }\r
+    break;\r
+  } while (1);\r
+}\r
+\r
+static void grab_ident()\r
+{\r
+  char *t=mak_tok_ident;\r
+  while (isalnum(*makp) || '_'==*makp)\r
+    *t++=*makp++;\r
+  *t=0;\r
+  strlwr(mak_tok_ident);\r
+}\r
+\r
+static void grab_val()\r
+{\r
+  char *t=mak_tok_val;\r
+  while (isalnum(*makp) || '_'==*makp)\r
+    *t++=*makp++;\r
+  *t=0;\r
+  mak_tok_valn=atoi(mak_tok_val);\r
+}\r
+\r
+static int ident_is(char *id) { return streq(mak_tok_ident,id); }\r
+\r
+static void do_assign()\r
+{\r
+  if (ident_is("pcx_name"))\r
+    { strcpy(pcx_name, mak_tok_val); got_pcx_name=1;            return; }\r
+  else if (ident_is("chr_name"))\r
+    { strcpy(chr_name, mak_tok_val); got_chr_name=1;            return; }\r
+  else if (ident_is("frame_w"))\r
+    { frame_w=mak_tok_valn;          got_frame_w=1;             return; }\r
+  else if (ident_is("frame_h"))\r
+    { frame_h=mak_tok_valn;          got_frame_h=1;             return; }\r
+  else if (ident_is("hot_x"))\r
+    { hot_x=mak_tok_valn;            got_hot_x=1;               return; }\r
+  else if (ident_is("hot_y"))\r
+    { hot_y=mak_tok_valn;            got_hot_y=1;               return; }\r
+  else if (ident_is("hot_w"))\r
+    { hot_w=mak_tok_valn;            got_hot_w=1;               return; }\r
+  else if (ident_is("hot_h"))\r
+    { hot_h=mak_tok_valn;            got_hot_h=1;               return; }\r
+  else if (ident_is("per_row"))\r
+    { per_row=mak_tok_valn;          got_per_row=1;             return; }\r
+  else if (ident_is("total_frames"))\r
+    { total_frames=mak_tok_valn;     got_total_frames=1;        return; }\r
+  else if (ident_is("lidle"))\r
+    { lidle=mak_tok_valn;            got_lidle=1;               return; }\r
+  else if (ident_is("ridle"))\r
+    { ridle=mak_tok_valn;            got_ridle=1;               return; }\r
+  else if (ident_is("uidle"))\r
+    { uidle=mak_tok_valn;            got_uidle=1;               return; }\r
+  else if (ident_is("didle"))\r
+    { didle=mak_tok_valn;            got_didle=1;               return; }\r
+  else if (ident_is("lscript"))\r
+    { strcpy(lscript, mak_tok_val);  got_lscript=1;             return; }\r
+  else if (ident_is("rscript"))\r
+    { strcpy(rscript, mak_tok_val);  got_rscript=1;             return; }\r
+  else if (ident_is("uscript"))\r
+    { strcpy(uscript, mak_tok_val);  got_uscript=1;             return; }\r
+  else if (ident_is("dscript"))\r
+    { strcpy(dscript, mak_tok_val);  got_dscript=1;             return; }\r
+\r
+  fatal("%s: unknown ident '%s' on line %i",\r
+    chrmak_makefile, mak_tok_ident, mak_line);\r
+}\r
+\r
+static int parse_assign()\r
+{\r
+  int last_line=0; // helper for error detection\r
+\r
+  parse_whitespace();\r
+  if (!*makp)\r
+    return 1;\r
+  else if (isalpha(*makp))\r
+  {\r
+    grab_ident();      // get ident\r
+    last_line=mak_line;\r
+\r
+    parse_whitespace(); // expect\r
+    if ('=' != *makp++)\r
+      fatal("%s: expected = on line %i", chrmak_makefile, last_line);\r
+\r
+    parse_whitespace(); // get val\r
+    grab_val();\r
+    last_line=mak_line;\r
+\r
+    do_assign();\r
+\r
+    parse_whitespace(); // expect\r
+    if (';' != *makp++)\r
+      fatal("%s: expected ; on line %i", chrmak_makefile, last_line);\r
+    else while (';'==*makp) makp++;\r
+\r
+    return 0;\r
+  }\r
+  fatal("%s: expected ident, got '%c' on line %i",\r
+    chrmak_makefile, *makp, mak_line);\r
+  return 1;\r
+}\r
+\r
+static void check_needs()\r
+{\r
+  if (!got_pcx_name)     fatal("%s: pcx_name missing", chrmak_makefile);\r
+  if (!got_chr_name)     fatal("%s: chr_name missing", chrmak_makefile);\r
+  if (!got_frame_w)      fatal("%s: frame_w missing", chrmak_makefile);\r
+  if (!got_frame_h)      fatal("%s: frame_h missing", chrmak_makefile);\r
+  if (!got_hot_x)        fatal("%s: hot_x missing", chrmak_makefile);\r
+  if (!got_hot_y)        fatal("%s: hot_y missing", chrmak_makefile);\r
+  if (!got_hot_w)        fatal("%s: hot_w missing", chrmak_makefile);\r
+  if (!got_hot_h)        fatal("%s: hot_h missing", chrmak_makefile);\r
+  if (!got_per_row)      fatal("%s: per_row missing", chrmak_makefile);\r
+  if (!got_total_frames) fatal("%s: total_frames missing", chrmak_makefile);\r
+  if (!got_lidle)        fatal("%s: lidle missing", chrmak_makefile);\r
+  if (!got_ridle)        fatal("%s: ridle missing", chrmak_makefile);\r
+  if (!got_uidle)        fatal("%s: uidle missing", chrmak_makefile);\r
+  if (!got_didle)        fatal("%s: didle missing", chrmak_makefile);\r
+  if (!got_lscript)      fatal("%s: lscript missing", chrmak_makefile);\r
+  if (!got_rscript)      fatal("%s: rscript missing", chrmak_makefile);\r
+  if (!got_uscript)      fatal("%s: uscript missing", chrmak_makefile);\r
+  if (!got_dscript)      fatal("%s: dscript missing", chrmak_makefile);\r
+}\r
+\r
+static void parse_makefile()\r
+{\r
+  FILE *fp=0;\r
+\r
+  printf("ú parsing %s \r", chrmak_makefile);\r
+  fflush(stdout);\r
+\r
+  fp=fopen(chrmak_makefile, "rb");\r
+  if (!fp) fatal("unable to open %s", chrmak_makefile);\r
+\r
+  mak_bytes=filelength(fileno(fp));     // calc bytes\r
+  mak_base=new char [mak_bytes+1];      // alloc room\r
+  fread(mak_base,1,mak_bytes,fp);       // read bytes\r
+  mak_base[mak_bytes]=0;                // null-term\r
+  makp=mak_base;                        // setup cur byte ptr\r
+  mak_line=1;\r
+\r
+  while (!parse_assign())\r
+    ;\r
+\r
+  // got everything we need?\r
+  check_needs();\r
+\r
+  delete[]mak_base; mak_base=0;\r
+  makp=0;\r
+\r
+  fclose(fp);\r
+\r
+  printf("û \n");\r
+  fflush(stdout);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////////\r
+// PCX & COMPRESS STUFF ////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////////\r
+\r
+static FILE *chrfp=0;\r
+static FILE *pcxfp=0;\r
+static byte *virscr=0;\r
+\r
+int manufacturer=0;                     // pcx header\r
+int version=0;\r
+int encoding=0;\r
+int bpp=0;\r
+int xmin=0,ymin=0;\r
+int xmax=0,ymax=0;\r
+int hres=0,vres=0;\r
+char palette[48];\r
+int reserved=0;\r
+int color_planes=0;\r
+int bpl=0;\r
+int palette_type=0;\r
+char filler[58];\r
+byte pal[768];\r
+\r
+int image_width=0,image_depth=0;\r
+quad vidoffset=0;\r
+\r
+void LoadPCXHeader()\r
+{\r
+  manufacturer  = fgetc(pcxfp); // always 10\r
+  version       = fgetc(pcxfp); // should be 5?\r
+  encoding      = fgetc(pcxfp); // always 1\r
+  bpp           = fgetc(pcxfp); // bits per pixel\r
+\r
+  xmin          = fgetw(pcxfp); // grab window\r
+  ymin          = fgetw(pcxfp);\r
+  xmax          = fgetw(pcxfp);\r
+  ymax          = fgetw(pcxfp);\r
+  image_width   = xmax-xmin+1;  // calc dims\r
+  image_depth   = ymax-ymin+1;\r
+\r
+  hres          = fgetw(pcxfp);\r
+  vres          = fgetw(pcxfp);\r
+\r
+  fread(palette,1,48,pcxfp);    // ega color map\r
+\r
+  reserved      = fgetc(pcxfp);\r
+  color_planes  = fgetc(pcxfp); // should be 1\r
+\r
+  bpl           = fgetw(pcxfp); // bytes per line\r
+  palette_type  = fgetw(pcxfp);\r
+\r
+  fread(filler,1,58,pcxfp);     // nothing important here\r
+}\r
+\r
+void ReadPCXLine(byte *dest)\r
+{\r
+  int i=0,c=0,n=0,run=0;\r
+\r
+  // decode a row\r
+  for (n=0; n<image_width; n+=run)\r
+  {\r
+    // assume single pixel\r
+    run=1;\r
+    c=fgetc(pcxfp);\r
+    // is this a run?\r
+    if ((c&192)==192)\r
+    {\r
+      // calc run and grab color\r
+      run=c&63;\r
+      c=fgetc(pcxfp);\r
+    }\r
+    // now replicate run bytes\r
+    for (i=0; i<run; i++)\r
+      dest[vidoffset+n+i]=(byte)c;\r
+  }\r
+  // skip row padding, if any\r
+  fskip(bpl-image_width,pcxfp);\r
+}\r
+\r
+void LoadPCX(char *filename)\r
+{\r
+  int i=0;\r
+\r
+  // open file\r
+  if (pcxfp) fclose(pcxfp);\r
+  pcxfp=fopen(filename,"rb");\r
+  if (!pcxfp)\r
+  { printf("unable to open %s", filename);\r
+    exit(0);\r
+  }\r
+\r
+  // get info\r
+  LoadPCXHeader();\r
+\r
+  // allocate image data\r
+  if (virscr) { free(virscr); virscr=0; }\r
+  virscr=(byte *)malloc(image_width*image_depth);\r
+\r
+  // decompress image data\r
+  for (i=0; i<image_depth; i++)\r
+  { vidoffset=i*image_width;\r
+    ReadPCXLine(virscr);\r
+  }\r
+\r
+  // pal exists?\r
+  if (fgetc(pcxfp) == 12)\r
+    fread(pal,1,768,pcxfp);\r
+\r
+  // done\r
+  fclose(pcxfp);\r
+}\r
+\r
+static int bufsize=0;\r
+static byte *csrc=0, *cb=0;\r
+\r
+static void emitc(byte b) { *csrc++=b, bufsize++; }\r
+\r
+static void Compress(byte *p, int len)\r
+{\r
+  int i=0;\r
+  byte byt=0,samect=0;\r
+\r
+  csrc=cb;\r
+  i=0; bufsize=0;\r
+  do\r
+  {\r
+    byt=p[i++];\r
+    samect=1;\r
+    while (samect<254 && i<len && byt==p[i])\r
+      { samect++; i++; }\r
+\r
+    if (samect==2 && byt != 0xFF) { emitc(byt); }\r
+    if (samect==3 && byt != 0xFF) { emitc(byt); emitc(byt); }\r
+    if (samect>3 || byt == 0xFF)\r
+    {\r
+      emitc(0xFF);\r
+      emitc(samect);\r
+    }\r
+    emitc(byt);\r
+\r
+  } while (i<len);\r
+}\r
+\r
+static byte *raw=0,*r=0;\r
+\r
+static void dumpframe(int x, int y)\r
+{\r
+  byte *src=&virscr[(y*image_width)+x];\r
+\r
+  for (y=0; y<frame_h; y++)\r
+  {\r
+    for (x=0; x<frame_w; x++)\r
+      *r++=src[x];\r
+    src+=image_width;\r
+  }\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////////\r
+\r
+static void WriteFrames(char *filename, FILE *dump)\r
+{\r
+  int i=0,j=0;\r
+  int raw_bytes=0;\r
+\r
+  printf("  ú reading image %s \r", pcx_name);\r
+  fflush(stdout);\r
+\r
+  LoadPCX(filename);\r
+\r
+  printf("  û \n");\r
+  fflush(stdout);\r
+\r
+  printf("  ú collecting frames \r");\r
+  fflush(stdout);\r
+\r
+  // setup bufs for raw data/compression\r
+  raw_bytes = total_frames * (frame_w*frame_h);\r
+  cb  = (byte *)malloc(raw_bytes);\r
+  raw = (byte *)malloc(raw_bytes); r=raw;\r
+\r
+  // dump all frames in row major byte order into 'raw'\r
+  for (i=0; i<10; i++)\r
+    for (j=0; j<per_row; j++)\r
+    {\r
+      if ((i*per_row)+j<total_frames)\r
+        dumpframe(1+(j*(frame_w+1)), 1+(i*(frame_h+1)));\r
+    }\r
+\r
+  printf("  û \n");\r
+  fflush(stdout);\r
+\r
+  printf("  ú compressing \r");\r
+  fflush(stdout);\r
+\r
+  // smush the sucker\r
+  Compress(raw, raw_bytes);\r
+\r
+  fputd(bufsize,dump);           // compressed data bytes\r
+  fputraw((char *)cb,bufsize,dump);      // compressed data\r
+\r
+  printf("  û \n");\r
+  fflush(stdout);\r
+\r
+  // cleanup bufs\r
+  free(raw);\r
+  free(cb);\r
+}\r
+\r
+static void WriteInfo(FILE *dump)\r
+{\r
+  fputc(2,  dump);              // version\r
+  fputw((word)frame_w, dump);         // frame dims\r
+  fputw((word)frame_h, dump);\r
+  fputw((word)hot_x, dump);           // hotspot coords\r
+  fputw((word)hot_y, dump);\r
+  fputw((word)hot_w, dump);           // hotspot dims\r
+  fputw((word)hot_h, dump);\r
+  fputw((word)total_frames, dump);    // total frames\r
+}\r
+\r
+static void WriteScripts(FILE *fp)\r
+{\r
+  fputd(lidle,fp);\r
+  fputd(ridle,fp);\r
+  fputd(uidle,fp);\r
+  fputd(didle,fp);\r
+\r
+  fputstrn(lscript,fp);\r
+  fputstrn(rscript,fp);\r
+  fputstrn(uscript,fp);\r
+  fputstrn(dscript,fp);\r
+}\r
+\r
+static void write_chr()\r
+{\r
+  strcat(pcx_name, ".pcx");\r
+  strcat(chr_name, ".chr");\r
+\r
+  /*\r
+  // DEBUG\r
+  printf(" \n");\r
+  printf("pcx_name: %s \n", pcx_name);\r
+  printf("chr_name: %s \n", chr_name);\r
+  printf("frame_w: %i \n", frame_w);\r
+  printf("frame_h: %i \n", frame_h);\r
+  printf("hot_x: %i \n", hot_x);\r
+  printf("hot_y: %i \n", hot_y);\r
+  printf("hot_w: %i \n", hot_w);\r
+  printf("hot_h: %i \n", hot_h);\r
+  printf("per_row: %i \n", per_row);\r
+  printf("total_frames: %i \n", total_frames);\r
+  printf("lidle: %i \n", lidle);\r
+  printf("ridle: %i \n", ridle);\r
+  printf("uidle: %i \n", uidle);\r
+  printf("didle: %i \n", didle);\r
+  printf("lscript: %s \n", lscript);\r
+  printf("rscript: %s \n", rscript);\r
+  printf("uscript: %s \n", uscript);\r
+  printf("dscript: %s \n", dscript);\r
+  fflush(stdout);\r
+  getch();\r
+  */\r
+\r
+  printf("> dumping %s \n", chr_name);\r
+  fflush(stdout);\r
+\r
+  chrfp=fopen(chr_name, "wb");\r
+  if (!chrfp) fatal("unable to open %s", chr_name);\r
+\r
+  WriteInfo(chrfp);\r
+  WriteFrames(pcx_name,chrfp);\r
+  WriteScripts(chrfp);\r
+\r
+  fclose(chrfp);\r
+\r
+  printf("complete! \n");\r
+  fflush(stdout);\r
+}\r
+\r
+int main(int argc, char *argv[])\r
+{\r
+  banner();\r
+\r
+  parse_args(argc, argv);\r
+  parse_makefile();\r
+\r
+  write_chr();\r
+\r
+  return 0;\r
+}\r