/* rmap - vector based global map generating program * Copyright (C) 2000 Reza Naima * * http://www.reza.net/rmap/ * * * 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 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 */ #include #include #include #include #include #include #include #include #include #include #define SHORTFLAG 0x4000 #define CBD_MAGIC 0x20770002 #define HEADER_MAGIC 0x86460346 //random number #define BIT32 int #define BIT16 short // THE INPUT PARAMS MUST BE IN THE FORM OF // generate Map/*.Map/*.cbd // for the proper continent and type mappings // (i need to pull it fromt he filenames, and // rather than parsing it, i just pull it from // various spots) // struct cbdhead { BIT32 magic; /* Magic number */ BIT32 dictaddr; /* Offset of segment dictionary in file */ BIT32 segcount; /* Number of segments in file */ BIT32 segsize; /* Size of segment dictionary */ BIT32 segmax; /* Size of largest segment's strokes, /2 */ BIT32 fill[(40 / sizeof (BIT32)) - 5]; /* Filler */ }; struct myheader { BIT32 magic; BIT32 segment_index_address; BIT32 segment_index_count; }; int main (int argc, char **argv) { int cat, continent; char string[4]; int Ofile; int my_seg_idx = 0; int my_segment_total = 0; int my_stroke_count = 0; int ret; int Ifile, segcount, idx, idy, segbufsize, olt, oln, j, k, jstroke, iseg; char filename[20][80]; char file[30]; int filenum; BIT32 i32; BIT16 *segbuf; struct my_segment_index { BIT32 maxlat; BIT32 minlat; BIT32 maxlong; BIT32 minlong; BIT32 segment_address; BIT32 continent; BIT32 catagory; BIT32 type; } seg_idx; struct my_segment_header { BIT32 orgx; BIT32 orgy; BIT32 nstrokes; } seg_head; struct my_stroke { BIT32 dx; BIT32 dy; } stroke; struct segdict { BIT32 segid; BIT32 maxlat, minlat, maxlong, minlong; BIT32 absaddr; BIT16 nbytes; BIT16 rank; } *sd, *sdbuf; struct segment { BIT32 orgx, orgy; BIT32 id; BIT16 nstrokes; BIT16 dummy; } sb; struct cbdhead header; struct myheader my_top; // create a file to output my data to Ofile = creat ("output.rez", S_IRWXU); if (Ofile == -1 ) { printf ("couln't open output file\n"); exit (2); } if (Ofile <3 ) { printf("opened fh= %d\n", Ofile); exit(-1); } // initialize some shitz //itterate through this twice.. once to create list of indexes, //and a second time to generate the data //determine the number of segments for (filenum = 1; filenum < argc; filenum++) { strcpy (filename[filenum], argv[filenum]); Ifile = open (filename[filenum], O_RDONLY, 0); if (Ifile == -1) { printf("unable to open file %s", filename[filenum]); continue; } printf ("Reading %s\n", filename[filenum]); read (Ifile, &header, sizeof header); if (header.magic != CBD_MAGIC) { printf ("File has bad magic number %d != %d\n", header.magic, CBD_MAGIC); exit (2); } my_seg_idx += header.segcount; close (Ifile); } printf ("determined that there are %d segments\n", my_seg_idx); my_segment_total = my_seg_idx; my_seg_idx = 0; my_top.magic = HEADER_MAGIC; my_top.segment_index_address = sizeof my_top; my_top.segment_index_count = my_segment_total; ret = write (Ofile, &my_top, sizeof (my_top)); if (ret != sizeof (my_top)) { printf ("error 1\n"); exit (2); } //now generate a list of the segment_indexs printf("Writing Segment Indexes "); for (filenum = 1; filenum < argc; filenum++) { continent=0; cat=0; //init strcpy (filename[filenum], argv[filenum]); strcpy (file, argv[filenum]); Ifile = open (filename[filenum], O_RDONLY, 0); if (Ifile == -1) continue; // problem? // determine the continent and catagory id bzero(string,3); strncpy(string, file+4, 3); string[3]='\0'; if (!strcmp(string, "afr")) continent=1; if (!strcmp(string, "asi")) continent=2; if (!strcmp(string, "eur")) continent=3; if (!strcmp(string, "nam")) continent=4; if (!strcmp(string, "sam")) continent=5; printf("Country -> %s -> %d\n", string, continent); bzero(string,3); strncpy(string, file+(strlen(file)-7), 3); string[3]='\0'; if (!strcmp(string, "pby")) cat=1; if (!strcmp(string, "riv")) cat=2; if (!strcmp(string, "bdy")) cat=3; if (!strcmp(string, "cil")) cat=4; printf("Type -> %s -> %d\n", string, cat); printf ("Reading %s\n", filename[filenum]); read (Ifile, &header, sizeof header); /* allocate space for the segment buffer */ segbufsize = 2 * header.segmax; segbuf = (BIT16 *) malloc (50 + segbufsize); sd = sdbuf = (struct segdict *) malloc (100 + header.segsize); /* Go read in the segment dictionary (it's at the end of the file) */ lseek (Ifile, header.dictaddr, L_SET); j = read (Ifile, sd + 1, header.segsize); if (j < header.segsize) { fprintf (stderr, "File segment dictionary expecting %d got %d\n", header.segsize, j); exit (2); } segcount = header.segcount; for (iseg = 1; iseg <= segcount; iseg++) { sd++; /* next one */ //determine the country and // the catagory using a crude method my_seg_idx++; seg_idx.maxlat = sd->maxlat; seg_idx.minlat = sd->minlat; seg_idx.maxlong = sd->maxlong; seg_idx.minlong = sd->minlong; seg_idx.segment_address = sizeof (my_top) //hader + sizeof (seg_idx) * my_segment_total //the segment index block + sizeof (seg_head) * (my_seg_idx - 1) //the number of past segment headers + sizeof (stroke) * my_stroke_count; seg_idx.continent = 0x00000001 << continent-1; // aka the file num seg_idx.catagory = 0x00000001 << cat-1; // should break this up really.. seg_idx.type = sd->rank; if (my_seg_idx < 10) printf("my_seg_idx = %d, addr = %d\n", my_seg_idx, seg_idx.segment_address); lseek (Ifile, sd->absaddr, L_SET); read (Ifile, &sb, sizeof sb); my_stroke_count += sb.nstrokes; ret = write (Ofile, &seg_idx, sizeof (seg_idx)); if (ret != sizeof (seg_idx)) { printf ("error 1\n"); exit (2); } //printf ("wrote segment_index %d (strokes = %d)\n", my_seg_idx, my_stroke_count); //if (!iseg%(my_segment_total/20)) // printf("."); } printf("\n"); close (Ifile); free (sdbuf); free (segbuf); } //another loop! for (filenum = 1; filenum < argc; filenum++) { strcpy (filename[filenum], argv[filenum]); if ((Ifile = open (filename[filenum], O_RDONLY, 0)) == -1) continue; printf ("Reading %s\n", filename[filenum]); read (Ifile, &header, sizeof header); /* allocate space for the segment buffer */ segbufsize = 2 * header.segmax; segbuf = (BIT16 *) malloc (50 + segbufsize); sd = sdbuf = (struct segdict *) malloc (100 + header.segsize); /* Go read in the segment dictionary (it's at the end of the file) */ lseek (Ifile, header.dictaddr, L_SET); j = read (Ifile, sd + 1, header.segsize); if (j < header.segsize) { fprintf (stderr, "File segment dictionary expecting %d got %d\n", header.segsize, j); exit (2); } segcount = header.segcount; for (iseg = 1; iseg <= segcount; iseg++) { sd++; /* next one */ lseek (Ifile, sd->absaddr, L_SET); read (Ifile, &sb, sizeof sb); if (sd->nbytes > segbufsize) { fprintf (stderr, "Segment %d needs %d bytes; buffer limit is %d.\n", iseg, sd->nbytes, segbufsize); exit (2); } read (Ifile, segbuf, sd->nbytes); k = 0; oln = sb.orgx; olt = sb.orgy; seg_head.orgx = sb.orgx; seg_head.orgy = sb.orgy; seg_head.nstrokes = sb.nstrokes; //ret = lseek(Ofile, 0, SEEK_CUR); //printf("the offset is at %d\n", ret); ret = write (Ofile, &seg_head, sizeof (seg_head)); if (ret != sizeof (seg_head)) { printf ("error 1\n"); exit (2); } //printf ("writing stroke header - total strokes = %d\n", sb.nstrokes); printf("."); fflush(stdout); for (jstroke = 1; jstroke <= sb.nstrokes; jstroke++) { if (segbuf[k] & SHORTFLAG) { /* Flag bit on: unpack a 16-bit field into dx and dy */ i32 = segbuf[k++]; if (i32 > 0) i32 &= ~SHORTFLAG; /* turn off short flag bits */ idy = i32 & 0x000000FF; if (idy & 0x00000080) idy |= ~0x000000FF; /* extend sign */ idx = i32 >> 8; if (idx & 0x00000080) idx |= ~0x000000BF; /* extend sign */ } else { /* Flag bit off: take dx and dy from 32-bit fields. */ idx = segbuf[k++]; if (idx < 0) idx |= SHORTFLAG; idx = (idx << 16) | (unsigned short) segbuf[k]; k++; idy = segbuf[k]; k++; if (idy < 0) idy |= SHORTFLAG; idy = (idy << 16) | segbuf[k]; k++; } stroke.dx = idx; stroke.dy = idy; ret = write (Ofile, &stroke, sizeof (stroke)); if (ret != sizeof (stroke)) { printf ("error 1\n"); exit (2); } } } printf("\n"); close (Ifile); free (sdbuf); free (segbuf); } close (Ofile); return 0; }