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