#include #include #include #include #include "rushhour.h" static char buf[1024]; static void consumeline(Biobuf *b) { while(Bgetc(b) != '\n') ; } static char* readline(Biobuf *b) { char *p, *e; int c; p = buf; e = buf + sizeof(buf) - 1; /* -1 for final \n */ while((c = Bgetc(b)) != '\n' ) if (p < e) *(p++) = c; *p = '\0'; return buf; } static void setlevel(int lnum, int x, int y, int e) { levels[lnum].board[x][y] = e; if (levels[lnum].length[e] == 0) levels[lnum].orient[e] = -1 - y; else if (levels[lnum].orient[e] < 0) if (levels[lnum].orient[e] == -1 -y) levels[lnum].orient[e] = OHoriz; else levels[lnum].orient[e] = OVert; levels[lnum].length[e]++; switch(e) { case CarX: if (levels[lnum].us == Empty) levels[lnum].us = e; break; case CarY: if (levels[lnum].us == Empty) levels[lnum].us = e; break; case CarZ: if (levels[lnum].us == Empty || levels[lnum].us == CarX) levels[lnum].us = e; break; } } /* parse a level file */ int loadlevels(char *path) { Biobuf *b; int x, y, lnum, i; char c; if(path == nil) return -1; b = Bopen(path, OREAD); if(b == nil) { fprint(2, "cannot load levels: %r\n"); return -1; } for (i=0; i < numlevels; i++) free(levels[i].name); memset(levels, 0, Maxlevels*sizeof(Level)); x = Off; y = Off; lnum = 0; while((c = Bgetc(b)) > 0) { switch(c) { case ';': consumeline(b); break; case ':': levels[lnum].name = estrdup(readline(b)); /* at most one name for a level */ break; case '\n': levels[lnum].index = lnum; levels[lnum].done = 0; x = Off; y++; levels[lnum].max.y = y; c = Bgetc(b); if(c == '\n' || c == Beof) { /* end of level */ if(++lnum == Maxlevels) goto Done; x = Off; y = Off; levels[lnum].win = Pt(Off,Off); } else Bungetc(b); break; case '#': levels[lnum].board[x][y] = Wall; x++; break; case '.': case '@': /* used to be goal (exit); need no longer be specially marked */ levels[lnum].board[x][y] = Empty; x++; break; case 'x': setlevel(lnum, x, y, CarX); x++; break; case 'y': setlevel(lnum, x, y, CarY); x++; break; case 'z': setlevel(lnum, x, y, CarZ); x++; break; case 'a': setlevel(lnum, x, y, CarA); x++; break; case 'b': setlevel(lnum, x, y, CarB); x++; break; case 'c': setlevel(lnum, x, y, CarC); x++; break; case 'd': setlevel(lnum, x, y, CarD); x++; break; case 'e': setlevel(lnum, x, y, CarE); x++; break; case 'f': setlevel(lnum, x, y, CarF); x++; break; case 'g': setlevel(lnum, x, y, CarG); x++; break; case 'h': setlevel(lnum, x, y, CarH); x++; break; case 'i': setlevel(lnum, x, y, CarI); x++; break; case 'j': setlevel(lnum, x, y, CarJ); x++; break; case 'k': setlevel(lnum, x, y, CarK); x++; break; case 'l': setlevel(lnum, x, y, CarL); x++; break; case 'm': setlevel(lnum, x, y, CarM); x++; break; case 'n': setlevel(lnum, x, y, CarN); x++; break; case 'o': setlevel(lnum, x, y, TruckO); x++; break; case 'p': setlevel(lnum, x, y, TruckP); x++; break; case 'q': setlevel(lnum, x, y, TruckQ); x++; break; case 'r': setlevel(lnum, x, y, TruckR); x++; break; case 's': setlevel(lnum, x, y, TruckS); x++; break; case 't': setlevel(lnum, x, y, TruckT); x++; break; case 'u': setlevel(lnum, x, y, TruckU); x++; break; case 'v': setlevel(lnum, x, y, TruckV); x++; break; default: fprint(2, "impossible character for level %d: %c\n", lnum+1, c); return -1; } if(x > levels[lnum].max.x) levels[lnum].max.x = x; levels[lnum].max.y = y; } Done: Bterm(b); level = levels[0]; numlevels = lnum; return lnum; }