/*********************************************/ /* you just keep on pushing my luck over the */ /* BOULDER DASH */ /* */ /* Jeroen Houttuin, ETH Zurich, 1990 */ /* */ /* */ /* PC-VGA version from : */ /* */ /* Herve SOULARD, Paris, 1990 */ /* */ /*********************************************/ #include #include #include #include #include #include "xbd.h" #define HEIGHT 16 #define WIDTH 16 #define MAXPGM 23 extern char *getenv(); char *bitmap[MAXPGM]; struct videoconfig config; int size; char *makegc(char pgm[]) { char *ptr,c; int i,j; unsigned r1,r2,r3,r4; unsigned *uptr; ptr = (char *)malloc(size); uptr = (unsigned *)ptr; if (ptr == NULL) { printf ("Erreur allocation (pgms)\n"); exit(1); } *ptr = WIDTH; *(ptr+2) = HEIGHT; *(ptr+1) = *(ptr+3) = 0; for (i=0; i < HEIGHT;i++) { r1 = r2 = r3 = r4 = 0; for (j=0; j < WIDTH; j++) { c = pgm[(i*WIDTH)+j]; if (c & 0x01) r1 |= (1 << ((WIDTH-1)-j)); if (c & 0x02) r2 |= (1 << ((WIDTH-1)-j)); if (c & 0x04) r3 |= (1 << ((WIDTH-1)-j)); if (c & 0x08) r4 |= (1 << ((WIDTH-1)-j)); } /* For compatibility with _putimage from Microsoft *(uptr+2+(i*4)) = r1; *(uptr+2+(i*4)+1) = r2; *(uptr+2+(i*4)+2) = r3; *(uptr+2+(i*4)+3) = r4; */ /* Using my own _putimage (drawPgm) */ *(uptr+2+i) = r1; *(uptr+2+i+16) = r2; *(uptr+2+i+32) = r3; *(uptr+2+i+48) = r4; } for (i=4; i< size; i+=2) { c = *(ptr+i); *(ptr+i) = *(ptr+i+1); *(ptr+i+1) = c; } return (ptr); } void make_gcs() { pgc = pgc1 = makegc(bitmap[0]); /* player_pgms */ pgc2 = makegc(bitmap[1]); /* player2_pgms */ wgc = Wgc = makegc(bitmap[2]); /* wall_pgms */ Wgc2 = makegc(bitmap[3]); /* wall2_pgms */ sgc = makegc(bitmap[4]); /* space_pgms */ ggc = makegc(bitmap[5]); /* grass_pgms */ dgc = dgc1 = makegc(bitmap[6]); /* diamond_pgms */ dgc2 = makegc(bitmap[7]); /* diamond2_pgms */ Sgc = makegc(bitmap[8]); /* steel_pgms */ bgc = makegc(bitmap[9]); /* boulder_pgms */ xgc = makegc(bitmap[10]); /* explosion_pgms */ lgc = lgc1 = makegc(bitmap[11]); /* lmonster_pgms */ lgc2 = makegc(bitmap[12]); /* lmonster2_pgms */ rgc = rgc1 = makegc(bitmap[13]); /* rmonster_pgms */ rgc2 = makegc(bitmap[14]); /* rmonster2_pgms */ egc = egc1 = makegc(bitmap[15]); /* eater_pgms */ egc2 = makegc(bitmap[16]); /* eater2_pgms */ Egc = Egc1 = makegc(bitmap[8]); /* steel_pgms */ Egc2 = makegc(bitmap[17]); /* exit2_pgms */ ngc = makegc(bitmap[18]); /* nucbal_pgms */ Bgc = Bgc1 = makegc(bitmap[19]); /* blob_pgms */ Bgc2 = makegc(bitmap[20]); /* blob2_pgms */ tgc = tgc1 = makegc(bitmap[2]); /* wall_pgms */ tgc2 = makegc(bitmap[21]); /* tinkle1_pgms */ tgc3 = makegc(bitmap[22]); /* tinkle2_pgms */ } void load() { FILE *map; int i,j,k; char buf[300]; int *ptr; char *aux; int color[WIDTH]; if (aux = getenv("XBDLIB")) strcpy(buf, aux); else strcpy(buf, LIB); strcat(buf, "\\"); strcat(buf,"bitmaps.dat"); map = fopen(buf,"r"); if (map == 0) { printf("Error opening bitmap file %s\n",buf); exit(-1); } else { for (i = 0;i < MAXPGM;i++) { fgets(buf,300,map); bitmap[i] = (char *)malloc(HEIGHT * WIDTH); for (j = 0;j < HEIGHT;j++) { ptr = color; fgets(buf,300,map); sscanf(buf,"%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", ptr++,ptr++,ptr++,ptr++,ptr++,ptr++,ptr++,ptr++,ptr++, ptr++,ptr++,ptr++,ptr++,ptr++,ptr++,ptr); for (k = 0; k < WIDTH;k++) bitmap[i][(j*WIDTH)+k] = (char)color[k]; } fgets(buf,300,map); } fclose(map); } } void init_level(levelnum) int levelnum; { FILE *levelfile; char buf[300], *ptr; Egc = Egc1; /* don't blink EXIT */ blobcollapse = FALSE; blobcells = 0; scoreobs = TRUE; tinkact = FALSE; levincreased = FALSE; strcpy(levname, "No_name_for_this_level_yet"); /* Manufaction the file name by starting with the world name and */ /* appending the level number to it. */ if (ptr = getenv("XBDLIB")) strcpy(filename, ptr); else strcpy(filename, LIB); strcat(filename, "\\"); strcat(filename, LEVELPREFIX); sprintf(filename + strlen(filename), "%03d", levelnum); /* Open level file for reading */ levelfile = fopen(filename, "r"); /* If level file does not exist, use the default level file. */ if (levelfile == NULL) { /* Build the default level name */ if (ptr = getenv("XBDLIB")) strcpy(buf, ptr); else strcpy(buf, LIB); strcat(buf, "\\"); strcat(buf, "\\default"); /* Open default level file for reading */ levelfile = fopen(buf, "r"); if (levelfile == NULL) { perror(LEVELPREFIX); exit(1); } } /* Load the first line of the level file */ if (fgets(buf, 300, levelfile) == NULL) { x = w; y = h; speed = 15; diareq = 12; diapoints = 0; extradiapoints = 0; blobbreak = 200; curtime = 1000; } else { /* Extract the level parameters */ sscanf(buf, "%d %d %d %d %d %d %d %d %d %s", &y, &x, &speed, &diareq, &diapoints, &extradiapoints, &blobbreak, &tinkdur, &curtime, levname); } if (xin && yin) { x = xin; y = yin; } /* read in from editor command line */ /* * if (x > w) x = w; if (y > h) y = h; if (x < 2) x = 2; if (y < 1) y = 1; * * * Iterate through each horizontal line */ for (i = 0; i < y; ++i) { /* Load the next line from the file */ if (fgets(buf, 300, levelfile) != NULL) { /* Go through each horizontal position and copy the data */ /* into the level array. */ for (j = 0; j < x; ++j) { /* Break out if line ends prematurely */ if (buf[j] == '\n' || buf[j] == '\0') field[i][j].content = STEEL; /* break; */ field[i][j].content = buf[j]; field[i][j].changed = TRUE; field[i][j].dir = N; field[i][j].speed = 0; field[i][j].stage = 0; field[i][j].caught = TRUE; field[i][j].checked = FALSE; } } else j = 0; for (; j < x; ++j) field[i][j].content = STEEL; } /* Close the level file */ fclose(levelfile); } /* Draw the score and level number */ void draw_score() { char buf[200]; /* Build the output string */ sprintf(buf, "sc:%d lv:%d ls:%d ds:%d dp:%d ti:%d %s", score, levelnum, lives, diareq, diapoints, curtime / 10, levname); strncat(buf," ", 80-strlen(buf)); _settextposition(y+2,0); _outtext(buf); scoreobs = FALSE; } void xstart() { _setvideomode(_MAXRESMODE); _getvideoconfig(&config); size = (unsigned int)_imagesize(0,0,WIDTH-1,HEIGHT-1); } void xend() { gamestop = TRUE; _setvideomode(_DEFAULTMODE); } void draw_field(redrawall) Bool redrawall; { char c; /* Iterate through each horizontal line */ for (i = y - 1; i >= 0; --i) { for (j = 0; j < x; ++j) { if (field[i][j].changed || redrawall) { c = field[i][j].content; switch (c) { case GRASS: drawPgm((j << 1), (i << 4), ggc, _GPSET); break; case SPACE: drawPgm((j << 1), (i << 4), sgc, _GPSET); break; case PLAYER: drawPgm((j << 1), (i << 4), pgc, _GPSET); break; case WALL: drawPgm((j << 1), (i << 4), wgc, _GPSET); break; case MAGICWALL: drawPgm((j << 1), (i << 4), Wgc, _GPSET); break; case DIAMOND: drawPgm((j << 1), (i << 4), dgc, _GPSET); break; case BOULDER: drawPgm((j << 1), (i << 4), bgc, _GPSET); break; case EXPLOSION: drawPgm((j << 1), (i << 4), xgc, _GAND); break; case LMONSTER: drawPgm((j << 1), (i << 4), lgc, _GPSET); break; case RMONSTER: drawPgm((j << 1), (i << 4), rgc, _GPSET); break; case NUCBAL: drawPgm((j << 1), (i << 4), ngc, _GPSET); break; case BLOB: drawPgm((j << 1), (i << 4), Bgc, _GPSET); break; case TINKLE: drawPgm((j << 1), (i << 4), tgc, _GPSET); break; case EATER: drawPgm((j << 1), (i << 4), egc, _GPSET); break; case EXIT: drawPgm((j << 1), (i << 4), Egc, _GPSET); break; case STEEL: default: field[i][j].content = STEEL; drawPgm((j << 1), (i << 4), Sgc, _GPSET); break; } field[i][j].changed = FALSE; } } } if (scoreobs) draw_score(); } void set_cell(i, j, content) int i, j; char content; { field[i][j].content = content; field[i][j].speed = 0; field[i][j].changed = TRUE; field[i][j].stage = 0; field[i][j].caught = TRUE; field[i][j].checked = FALSE; }