home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / xgalaga-2_0_tar.gz / xgalaga-2_0_tar / xgalaga-2.0 / pathfile.c < prev    next >
C/C++ Source or Header  |  1998-04-30  |  8KB  |  404 lines

  1. /* $Id: pathfile.c,v 1.3 1998/04/30 05:11:56 mrogre Exp $ */
  2. /* Copyright (c) 1998 Joe Rumsey (mrogre@mediaone.net) */
  3. #include "copyright.h"
  4. #include <config.h>
  5.  
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #ifdef HAVE_STRINGS_H
  10. # include <strings.h>
  11. #endif
  12. #include <sys/stat.h>
  13. #include <ctype.h>
  14. #include <stdlib.h>
  15.  
  16. #include "paths.h"
  17. #include "pathfile.h"
  18. #include "data.h"
  19. #include "defs.h"
  20.  
  21. #define MAXFILENAME 1024
  22.  
  23. #define MAXPATHLEN 50
  24. #define MAXLINE 1024
  25.  
  26. typedef enum {
  27.     PF_PATHDEF,
  28.     PF_PATHS,
  29.     PF_SHAPES,
  30.     PF_DELAYS
  31. } PathfileToken;
  32.  
  33. struct path_entry
  34. {
  35.     int dir, duration;
  36. };
  37.  
  38. struct path_info
  39. {
  40.     int startx, starty, len;
  41. };
  42.  
  43. struct path_entry epaths[NUMPATHS][MAXPATHLEN];
  44. struct path_info  pathinfo[NUMPATHS];
  45.  
  46. int al_shapes[MAXALIENS];
  47. int al_delays[MAXALIENS];
  48. int al_paths[MAXALIENS];
  49.  
  50. int
  51. get_line(FILE* file, char* buf)
  52. {
  53.     int done = 0;
  54.     char nextline[MAXLINE];
  55.  
  56.     buf[0] = 0;
  57.     while(!done)
  58.     {
  59.     if(!fgets(nextline, MAXLINE, file))
  60.         return 0;
  61.  
  62.     /* remove newline */
  63.     nextline[strlen(nextline) - 1] = 0;
  64.  
  65.     if(strlen(nextline) + strlen(buf) >= MAXLINE) {
  66.         fprintf(stderr, "get_line: Line too long\n");
  67.         return -1;
  68.     }
  69.     
  70.     strcpy(buf + strlen(buf), nextline);
  71.  
  72.     if(nextline[strlen(nextline) -1] != '\\')
  73.         done = 1;
  74.     else {
  75.         buf[strlen(buf) -1] = ' ';
  76.     }
  77.     }
  78.     return 1;
  79. }
  80.  
  81. PathfileToken
  82. get_token(char* line, int* elem, char** data)
  83. {
  84.     PathfileToken pt;
  85.     char *datastart;
  86.  
  87.     *elem = -1;
  88.     
  89.     if(strncmp(line, "paths:", 6) == 0) {    
  90.     pt = PF_PATHS;
  91.     } else if (strncmp(line, "path.", 5) == 0) {
  92.     if(line[5] >= '0' && line[5] <= '9')
  93.         *elem = line[5] - '0';
  94.     else if(line[5] >= 'a' && line[5] <= 'z')
  95.         *elem = line[5] - 'a' + 10;
  96.     else if(line[5] >= 'A' && line[5] <= 'Z')
  97.         *elem = line[5] - 'A' + 36;
  98.     else {
  99.         fprintf(stderr, "%c is not a valid path identifier\n", line[5]);
  100.         return -1;
  101.     }
  102.     pt = PF_PATHDEF;
  103.     } else if (strncmp(line, "delays:", 7) == 0) {
  104.     pt = PF_DELAYS;
  105.     } else if (strncmp(line, "shapes:", 7) == 0) {
  106.     pt = PF_SHAPES;
  107.     } else {
  108.     return -1;
  109.     }
  110.  
  111.     datastart = strchr(line, ':');
  112.     if(!datastart)
  113.     return -1;
  114.     datastart++;
  115.  
  116.     while(isspace(*datastart))
  117.     datastart++;
  118.  
  119.     if(!(*datastart))
  120.     return -1;
  121.  
  122.     *data = datastart;
  123.     return pt;
  124.  
  125. }
  126.  
  127. #define iscompass(c) (((c) == 'n') || ((c) == 'e') || ((c) == 's') || ((c) == 'w'))
  128. #define CHKDIR(x) \
  129.   curdir++; if(strcmp(x, dir) == 0) { gotdir = curdir; }
  130.  
  131. static void
  132. parse_path(int pnum, char* pstr)
  133. {
  134.     char *fnd;
  135.     char dir[40];
  136.     int dp;
  137.     int curdir = -1, gotdir;
  138.     int duration;
  139.     int curentry;
  140.     int sx, sy;
  141.     char *comma;
  142.  
  143.     curentry = 0;
  144.  
  145.     comma = strchr(pstr, ',');
  146.     sx = atoi(pstr);
  147.     sy = atoi(comma+1);
  148.     fnd = strchr(pstr, ':');
  149.     while(!iscompass(*fnd) && *fnd)
  150.     fnd++;
  151.  
  152.     if(!(*fnd))
  153.     fprintf(stderr, "No path info for path %d\n", pnum);
  154.  
  155.     while(*fnd) {
  156.     dp = 0;
  157.     while(iscompass(*fnd) && dp < 3) {
  158.         dir[dp] = *fnd;
  159.         fnd++;
  160.         dp++;
  161.     }
  162.     if(!isdigit(*fnd)) {
  163.         fprintf(stderr, "Error parsing path: %s\n", pstr);
  164.         return;
  165.     }
  166.     dir[dp] = 0;
  167.     curdir = -1;
  168.     gotdir = -1;
  169.  
  170.     CHKDIR("n");
  171.     CHKDIR("nne");
  172.     CHKDIR("ne");
  173.     CHKDIR("ene");
  174.     CHKDIR("e");
  175.     CHKDIR("ese");
  176.     CHKDIR("se");
  177.     CHKDIR("sse");
  178.     CHKDIR("s");
  179.     CHKDIR("ssw");
  180.     CHKDIR("sw");
  181.     CHKDIR("wsw");
  182.     CHKDIR("w");
  183.     CHKDIR("wnw");
  184.     CHKDIR("nw");
  185.     CHKDIR("nnw");
  186.  
  187.     if(gotdir < 0) {
  188.         fprintf(stderr, "direction %s in path %d is not valid\n",
  189.             dir, pnum);
  190.     }
  191.  
  192.     duration = atoi(fnd);
  193.     
  194.     epaths[pnum][curentry].dir = gotdir;
  195.     epaths[pnum][curentry].duration = duration;
  196.     curentry++;
  197.     while(isdigit(*fnd) || isspace(*fnd))
  198.         fnd++;
  199.     }
  200.     epaths[pnum][curentry].dir = -1;
  201.     epaths[pnum][curentry].duration = -1;
  202.  
  203.     pathinfo[pnum].len = curentry;
  204.     pathinfo[pnum].startx = sx;
  205.     pathinfo[pnum].starty = sy;
  206. }
  207.  
  208. static int
  209. parse_shapes(char* data)
  210. {
  211.     char* chk;
  212.     int i;
  213.  
  214.     for(i = 0, chk = data; i < MAXALIENS; i++)
  215.     {
  216.     while(isspace(*chk)) chk++;
  217.     if(!(*chk))
  218.         return 0;
  219.  
  220.     if(*chk >= '0' && *chk <= '9')
  221.         al_shapes[i] = *chk - '0';
  222.     else if(*chk >= 'a' && *chk <= 'z')
  223.         al_shapes[i] = *chk - 'a' + 10;
  224.     else if(*chk >= 'A' && *chk <= 'Z')
  225.         al_shapes[i] = *chk - 'A' + 10 + 26;
  226.     else if(*chk == '-')
  227.         al_shapes[i] = -1;
  228.     else {
  229.         fprintf(stderr, "'%c' is not a valid shape character\n", *chk);
  230.         al_shapes[i] = 0;
  231.     }
  232.  
  233.     chk++;
  234.     }
  235.  
  236.     return 1;
  237. }
  238.  
  239. static int
  240. parse_paths(char* data)
  241. {
  242.     char* chk;
  243.     int i;
  244.  
  245.     for(i = 0, chk = data; i < MAXALIENS; i++)
  246.     {
  247.     while(isspace(*chk)) chk++;
  248.     if(!(*chk))
  249.         return 0;
  250.  
  251.     if(*chk >= '0' && *chk <= '9')
  252.         al_paths[i] = *chk - '0';
  253.     else if(*chk >= 'a' && *chk <= 'z')
  254.         al_paths[i] = *chk - 'a' + 10;
  255.     else if(*chk >= 'A' && *chk <= 'Z')
  256.         al_paths[i] = *chk - 'A' + 10 + 26;
  257.     else if(*chk == '-')
  258.         al_paths[i] = -1;
  259.     else {
  260.         fprintf(stderr, "'%c' is not a valid shape character\n", *chk);
  261.         al_paths[i] = 0;
  262.     }
  263.  
  264.     chk++;
  265.     }
  266.  
  267.     return 1;
  268. }
  269.  
  270. static int
  271. parse_delays(char* data)
  272. {
  273.     char* chk;
  274.     int i;
  275.  
  276.     for(i = 0, chk = data; i < MAXALIENS; i++)
  277.     {
  278.     while(isspace(*chk)) chk++;
  279.     if(!(*chk))
  280.         return 0;
  281.  
  282.     al_delays[i] = atoi(chk);
  283.     while(!isspace(*chk) && *chk) chk++;
  284.     }
  285.  
  286.     return 1;
  287. }
  288.  
  289. int
  290. read_level(int lev)
  291. {
  292.     char filename[MAXFILENAME];
  293.     char readline[MAXLINE];
  294.     char *data;
  295.     int  gotPaths = 0, gotShapes = 0, gotDelays = 0;
  296.     int rlen;
  297.     int elem;
  298.     FILE* lf;
  299.     PathfileToken tok;
  300.     static int maxLevel = 1;
  301.     static char *real_level_path = 0;
  302.     struct stat statbuf;
  303.  
  304.     if(!real_level_path)
  305.     {
  306.     sprintf(filename, "%s", LEVELDIR);
  307.     if(stat(filename, &statbuf) != 0 || !(statbuf.st_mode & S_IFDIR)) {
  308.         sprintf(filename, "./levels");
  309.         if(stat(filename, &statbuf) != 0 || !(statbuf.st_mode & S_IFDIR)) {
  310.         fprintf(stderr, "Can't find level directory %s OR ./levels\n",
  311.             XGALAGADIR);
  312.         return -1;
  313.         }
  314.     }
  315.     real_level_path = malloc(strlen(filename) + 1);
  316.     strcpy(real_level_path, filename);
  317.     }
  318.  
  319.     sprintf(filename, "%s/level%d.xgl", real_level_path, lev);
  320.     lf = fopen(filename, "r");
  321.     if(!lf) {
  322.         //fprintf(stderr, "Can't open level file %s\n", filename);
  323.     metaLevel++;
  324.     return read_level(lev - maxLevel);
  325.     }
  326.  
  327.     if(lev > maxLevel)
  328.     maxLevel = lev;
  329.  
  330.     while(!feof(lf)) {
  331.     if((rlen = get_line(lf, readline)) <= 0) {
  332.         if(gotShapes && gotPaths && gotDelays) {
  333.         return 1;
  334.         }
  335.         fprintf(stderr, "Error reading level file %s:\n", filename);
  336.         if(!gotShapes)
  337.         fprintf(stderr, "  Missing shapes\n");
  338.         if(!gotPaths)
  339.         fprintf(stderr, "  Missing paths\n");
  340.         if(!gotDelays)
  341.         fprintf(stderr, "  Missing delays\n");
  342.  
  343.         fclose(lf);
  344.         return 0;
  345.     }
  346.     
  347.     switch((tok = get_token(readline, &elem, &data))) {
  348.     case PF_PATHDEF:
  349.         parse_path(elem, data);
  350.         break;
  351.     case PF_SHAPES:
  352.         gotShapes = parse_shapes(data);
  353.         break;
  354.     case PF_PATHS:
  355.         gotPaths = parse_paths(data);
  356.         break;
  357.     case PF_DELAYS:
  358.         gotDelays = parse_delays(data);
  359.         break;
  360.     default:
  361.         break;
  362.     }
  363.     }
  364.  
  365.     fclose(lf);
  366.     
  367.     if(gotShapes && gotPaths && gotDelays) {
  368.     return 1;
  369.     }
  370.  
  371.     return 0;
  372. }
  373.  
  374. int get_path(int anum)
  375. {
  376.     return al_paths[anum];
  377. }
  378.  
  379. void get_xy(int anum, int* x, int* y)
  380. {
  381.     *x = pathinfo[al_paths[anum]].startx;
  382.     *y = pathinfo[al_paths[anum]].starty;
  383. }
  384.  
  385. int get_delay(int anum)
  386. {
  387.     return al_delays[anum];
  388. }
  389.  
  390. int get_dir(int pnum, int pos)
  391. {
  392.     return epaths[pnum][pos].dir;
  393. }
  394.  
  395. int get_duration(int pnum, int pos)
  396. {
  397.     return epaths[pnum][pos].duration;
  398. }
  399.  
  400. int get_shape(int anum)
  401. {
  402.     return al_shapes[anum];
  403. }
  404.