void loadmap(void) { FILE *handle; int c; if (!strlen(mapname)) return; handle = fopen(mapname, "rb"); if (!handle) return; /* Load map header */ fread(&map, sizeof(MAPHEADER), 1, handle); /* Load each layer */ for (c = 0; c < MAX_LAYERS; c++) { layer[c].xsize = freadle32(handle); layer[c].ysize = freadle32(handle); layer[c].xdivisor = fread8(handle); layer[c].ydivisor = fread8(handle); layer[c].xwrap = fread8(handle); layer[c].ywrap = fread8(handle); if ((layer[c].xsize) && (layer[c].ysize)) { int d; for (d = 0; d < layer[c].xsize * layer[c].ysize; d++) { layerdataptr[c][d] = freadle16(handle); } } } fclose(handle); /* Load correct blocks & palette */ gfx_loadblocks((char *)map.blocksname); minxsize = (gfx_virtualxsize + (gfx_blockxsize-1)) / gfx_blockxsize; minysize = (gfx_virtualysize + (gfx_blockysize-1)) / gfx_blockysize; gfx_loadpalette((char *)map.palettename); gfx_calcpalette(64, 0, 0, 0); gfx_setpalette(); }
int load_pic(char *name) { FILE *fd = fopen(name, "rb"); Uint32 type; /* Couldn't open */ if (!fd) return 0; type = read_header(fd); /* Not an IFF file */ if (!type) { fclose(fd); return 0; } switch(type) { case PBM: { if (find_chunk(fd, BMHD)) { Uint16 sizex = freadhe16(fd); Uint16 sizey = freadhe16(fd); Uint8 compression; int colors = 256; Uint32 bodylength; /* * Hop over the "hotspot", planes & masking (stencil pictures are * always saved as ILBMs! */ fseek(fd, 6, SEEK_CUR); compression = fread8(fd); fread8(fd); fread8(fd); fread8(fd); /* * That was all we needed of the BMHD, now the CMAP (optional hehe!) */ if (find_chunk(fd, CMAP)) { int count; for (count = 0; count < colors; count++) { sc.red[count] = fread8(fd) >> 2; sc.green[count] = fread8(fd) >> 2; sc.blue[count] = fread8(fd) >> 2; } } /* * Now the BODY chunk, this is important! */ bodylength = find_chunk(fd, BODY); if (bodylength) { sc.sizex = sizex; sc.sizey = sizey; sc.data = malloc(sc.sizex * sc.sizey); if (!sc.data) { fclose(fd); return 0; } if (!compression) { int ycount; for (ycount = 0; ycount < sizey; ycount++) { fread(&sc.data[sc.sizex * ycount], sizex, 1, fd); } } else { int ycount; char *ptr = malloc(bodylength); char *origptr = ptr; if (!ptr) { fclose(fd); return 0; } fread(ptr, bodylength, 1, fd); /* Run-length encoding */ for (ycount = 0; ycount < sizey; ycount++) { int total = 0; while (total < sizex) { signed char decision = *ptr++; if (decision >= 0) { memcpy(&sc.data[sc.sizex * ycount + total], ptr, decision + 1); ptr += decision + 1; total += decision + 1; } if ((decision < 0) && (decision != -128)) { memset(&sc.data[sc.sizex * ycount + total], *ptr++, -decision + 1); total += -decision + 1; } } } free(origptr); } } } } break; case ILBM: { if (find_chunk(fd, BMHD)) { Uint16 sizex = freadhe16(fd); Uint16 sizey = freadhe16(fd); Uint8 compression; Uint8 planes; Uint8 mask; int colors; Uint32 bodylength; /* * Hop over the "hotspot" */ fseek(fd, 4, SEEK_CUR); planes = fread8(fd); mask = fread8(fd); compression = fread8(fd); fread8(fd); fread8(fd); fread8(fd); colors = poweroftwo[planes]; if (mask > 1) mask = 0; /* * That was all we needed of the BMHD, now the CMAP (optional hehe!) */ if (find_chunk(fd, CMAP)) { int count; for (count = 0; count < 256; count++) { sc.red[count] = 0; sc.green[count] = 0; sc.blue[count] = 0; } sc.red[255] = 255; sc.green[255] = 255; sc.blue[255] = 255; for (count = 0; count < colors; count++) { sc.red[count] = fread8(fd) >> 2; sc.green[count] = fread8(fd) >> 2; sc.blue[count] = fread8(fd) >> 2; } } /* * Now the BODY chunk, this is important! */ bodylength = find_chunk(fd, BODY); if (bodylength) { char *ptr; char *origptr; char *unpackedptr; char *workptr; int ycount, plane; int bytes, dbytes; sc.sizex = sizex; sc.sizey = sizey; sc.data = malloc(sc.sizex * sc.sizey); memset(sc.data, 0, sc.sizex * sc.sizey); if (!sc.data) { fclose(fd); return 0; } origptr = malloc(bodylength * 2); ptr = origptr; if (!origptr) { fclose(fd); return 0; } fread(origptr, bodylength, 1, fd); if (compression) { dbytes = sizey * (planes + mask) * ((sizex + 7) / 8); unpackedptr = malloc(dbytes); workptr = unpackedptr; if (!unpackedptr) { fclose(fd); return 0; } bytes = 0; while (bytes < dbytes) { signed char decision = *ptr++; if (decision >= 0) { memcpy(workptr, ptr, decision + 1); workptr += decision + 1; ptr += decision + 1; bytes += decision + 1; } if ((decision < 0) && (decision != -128)) { memset(workptr, *ptr++, -decision + 1); workptr += -decision + 1; bytes += -decision + 1; } } free(origptr); origptr = unpackedptr; ptr = unpackedptr; } for (ycount = 0; ycount < sizey; ycount++) { for (plane = 0; plane < planes; plane++) { int xcount = (sizex + 7) / 8; int xcoord = 0; while (xcount) { if (*ptr & 128) sc.data[sc.sizex * ycount + xcoord + 0] |= poweroftwo[plane]; if (*ptr & 64 ) sc.data[sc.sizex * ycount + xcoord + 1] |= poweroftwo[plane]; if (*ptr & 32 ) sc.data[sc.sizex * ycount + xcoord + 2] |= poweroftwo[plane]; if (*ptr & 16 ) sc.data[sc.sizex * ycount + xcoord + 3] |= poweroftwo[plane]; if (*ptr & 8 ) sc.data[sc.sizex * ycount + xcoord + 4] |= poweroftwo[plane]; if (*ptr & 4 ) sc.data[sc.sizex * ycount + xcoord + 5] |= poweroftwo[plane]; if (*ptr & 2 ) sc.data[sc.sizex * ycount + xcoord + 6] |= poweroftwo[plane]; if (*ptr & 1 ) sc.data[sc.sizex * ycount + xcoord + 7] |= poweroftwo[plane]; ptr++; xcoord += 8; xcount--; } } if (mask) { ptr += (sizex + 7) / 8; } } free(origptr); } } } break; } fclose(fd); return 1; }
int main(int argc, char** argv) { int c,d; int actuallevels = 0; int offset = 0; int screens = 0; int blocks = 0; for (c = 0; c < MAX_LEVELS; c++) { int length; int numact; int numobj; int actualnumobj; int numpersistentobj; char namebuf[256]; sprintf(namebuf, "bg/level%02d.lva", c); FILE* in = fopen(namebuf, "rb"); if (!in) break; fseek(in, 0, SEEK_END); length = ftell(in); fseek(in, 0, SEEK_SET); numact = length / 5; memset(lvlactt, 0, sizeof lvlactt); fread(&lvlactx[0], numact, 1, in); fread(&lvlacty[0], numact, 1, in); fread(&lvlactf[0], numact, 1, in); fread(&lvlactt[0], numact, 1, in); fread(&lvlactw[0], numact, 1, in); fclose(in); for (d = MAX_LVLACT-1; d >= 0; d--) { if (lvlactt[d]) break; } printf("Level %d has %d actors\n", c, d+1); if (d < 0) d = 0; // Always have some data per level numlvlact[c] = d+1; numbytes[c] = (numlvlact[c] + 7) / 8; bitareasize += numbytes[c]; sprintf(namebuf, "bg/level%02d.lvo", c); in = fopen(namebuf, "rb"); if (!in) break; fseek(in, 0, SEEK_END); length = ftell(in); fseek(in, 0, SEEK_SET); numobj = length / 4; memset(lvlobjx, 0, sizeof lvlobjx); memset(lvlobjy, 0, sizeof lvlobjy); fread(&lvlobjx[0], numobj, 1, in); fread(&lvlobjy[0], numobj, 1, in); fread(&lvlobjb[0], numobj, 1, in); fread(&lvlobjd[0], numobj, 1, in); fclose(in); numpersistentobj = 0; actualnumobj = 0; for (d = 0; d < MAX_LVLOBJ; d++) { if ((lvlobjx[d] || lvlobjy[d]) && (lvlobjx[d] != 0xff)) { actualnumobj++; // If object is animated without auto-deactivation, // it needs to be persisted. Note: game must obey exact same criteria // for decoding the object indices if ((lvlobjb[d] & 0x20) == 0x00 && (lvlobjy[d] & 0x80)) numpersistentobj++; } } printf("Level %d has %d objects, %d persistent\n", c, actualnumobj, numpersistentobj); // Always have some data per level if (!numpersistentobj) numpersistentobj++; numlvlobj[c] = numpersistentobj; numlvlobjbytes[c] = (numlvlobj[c] + 7) / 8; lvlobjbitareasize += numlvlobjbytes[c]; sprintf(namebuf, "bg/level%02d.map", c); in = fopen(namebuf, "rb"); if (!in) break; { int datasize = freadle16(in); int activezones = fread8(in); int zoneoffsets[MAX_ZONES]; int y,x; for (d = 0; d < activezones; d++) { zoneoffsets[d] = freadle16(in) + 3; } for (d = 0; d < activezones; d++) { int zonel, zoner, zoneu, zoned, x, y; fseek(in, zoneoffsets[d], SEEK_SET); zonel = fread8(in); zoner = fread8(in); zoneu = fread8(in); zoned = fread8(in); blocks += (zoner-zonel)*(zoned-zoneu); } close(in); } actuallevels++; } screens = blocks*16 / (22*40); printf("Total actor bitarea size is %d\n", bitareasize); printf("Total levelobject bitarea size is %d\n", lvlobjbitareasize); printf("Total gameworld size %d blocks %d screens\n", blocks, screens); FILE* out = fopen("levelactors.s", "wt"); fprintf(out, "LVLDATAACTTOTALSIZE = %d\n\n", bitareasize); fprintf(out, "LVLOBJTOTALSIZE = %d\n\n", lvlobjbitareasize); fprintf(out, "lvlDataActBitsStart:\n"); for (c = 0; c < actuallevels; c++) { fprintf(out, " dc.b %d\n", offset); offset += numbytes[c]; } fprintf(out, "lvlDataActBitsLen:\n"); for (c = 0; c < actuallevels; c++) { fprintf(out, " dc.b %d\n", numbytes[c]); } offset = 0; fprintf(out, "lvlObjBitsStart:\n"); for (c = 0; c < actuallevels; c++) { fprintf(out, " dc.b %d\n", offset); offset += numlvlobjbytes[c]; } fprintf(out, "lvlObjBitsLen:\n"); for (c = 0; c < actuallevels; c++) { fprintf(out, " dc.b %d\n", numlvlobjbytes[c]); } fclose(out); }