/* Write a den header and skip the mapping table. */ void AG_DenWriteHeader(AG_Den *den, int nmemb) { Uint32 i; AG_WriteString(den->buf, den->hint); AG_WriteString(den->buf, den->name); AG_WriteString(den->buf, den->author); AG_WriteString(den->buf, den->copyright); AG_WriteString(den->buf, den->descr); AG_WriteString(den->buf, den->keywords); /* Initialize the mapping table. */ den->members = Malloc(nmemb*sizeof(AG_DenMember)); den->nmembers = (Uint32)nmemb; for (i = 0; i < den->nmembers; i++) { AG_DenMember *memb = &den->members[i]; memset(memb->name, '\0', sizeof(memb->name)); memset(memb->lang, '\0', sizeof(memb->lang)); } AG_WriteUint32(den->buf, den->nmembers); /* Skip the mappings. */ den->mapoffs = AG_Tell(den->buf); AG_Seek(den->buf, den->nmembers*AG_DEN_MAPPING_SIZE, AG_SEEK_CUR); }
static int Load(void *p, AG_DataSource *ds, const AG_Version *ver) { #ifdef AG_DEBUG agDebugLvl = AG_ReadUint8(ds); #else (void)AG_ReadUint8(ds); #endif /* For backward compatibility with <9.5 (pre-1.4.2) saves. */ if (ver->minor < 2) { AG_ReadUint8(ds); } (void)AG_ReadUint8(ds); if (ver->minor >= 3) { AG_ReadUint8(ds); } if (ver->minor >= 4) { AG_ReadUint32(ds); } AG_Seek(ds, 22, AG_SEEK_CUR); if (ver->minor >= 1) { AG_ReadUint8(ds); } (void)AG_ReadUint8(ds); /* agRcsMode */ AG_SkipString(ds); /* agRcsHostname */ (void)AG_ReadUint16(ds); /* agRcsPort */ AG_SkipString(ds); /* agRcsUsername */ AG_SkipString(ds); /* agRcsPassword */ return (0); }
/* Write the den mappings. */ void AG_DenWriteMappings(AG_Den *den) { Uint32 i; AG_Seek(den->buf, den->mapoffs, AG_SEEK_SET); for (i = 0; i < den->nmembers; i++) { AG_DenMember *memb = &den->members[i]; AG_WriteUint32(den->buf, (Uint32)sizeof(memb->name)); if (AG_Write(den->buf, memb->name, sizeof(memb->name), 1) != 0) AG_FatalError(NULL); AG_WriteUint32(den->buf, (Uint32)sizeof(memb->lang)); if (AG_Write(den->buf, memb->lang, sizeof(memb->lang), 1) != 0) AG_FatalError(NULL); AG_WriteUint32(den->buf, (Uint32)memb->offs); AG_WriteUint32(den->buf, (Uint32)memb->size); } }
int main(int argc, char *argv[]) { char *file, *s; extern char *optarg; extern int optind; int i, c; AG_DataSource *ds = NULL; AG_ObjectHeader oh; Uint32 pos, sLen; size_t len; Uint8 *buf, *p; int asis = 0; if (AG_InitCore("agar-disasm", 0) == -1) { return (0); } while ((c = getopt(argc, argv, "?")) != -1) { switch (c) { case '?': default: printusage(); return (1); } } if (argc < 2) { printusage(); return (1); } file = argv[1]; if ((ds = AG_OpenFile(file, "r")) == NULL) { goto fail; } if (AG_ObjectReadHeader(ds, &oh) == -1) { goto fail; } printf("Class:\t\t%s\n", oh.cs.hier); if (oh.cs.libs[0] != '\0') { printf("Modules:\t%s\n", oh.cs.libs); } printf("Dataset at:\t%lx\n", (unsigned long)oh.dataOffs); printf("Version:\t%u.%u\n", oh.ver.major, oh.ver.minor); printf("Flags:\t\t0x%x\n", oh.flags); printf("\n"); if (AG_Seek(ds, 0, AG_SEEK_END) == -1) { goto fail; } len = AG_Tell(ds) - oh.dataOffs; if (AG_Seek(ds, (off_t)oh.dataOffs, AG_SEEK_SET) == -1) { goto fail; } pos = 0; if ((buf = malloc(len)) == NULL) { AG_SetError("Out of memory for dataset (%lu)", (unsigned long)len); goto fail; } if (AG_Read(ds, buf, len) == -1) goto fail; for (p = buf; ;) { for (i = 0; i < nTypes; i++) { if (AG_SwapBE32(*(Uint32 *)p) == types[i].type) { if (asis) { printf("\n"); } asis = 0; break; } } if (i == nTypes) { if (!asis) { printf("[%8s] ", "???"); asis = 1; } if (isprint(*(Uint8 *)p)) { fputc(*(Uint8 *)p, stdout); } else { printf("\\%x", *(Uint8 *)p); } FORWARD(1); continue; } FORWARD(4); printf("[%8s] ", types[i].name); switch (types[i].type) { case AG_SOURCE_UINT8: printf("%u\n", *(Uint8 *)p); FORWARD(1); break; case AG_SOURCE_UINT16: { Uint16 v = AG_SwapBE16(*(Uint16 *)p); printf("%u\n", (unsigned)v); FORWARD(2); } break; case AG_SOURCE_UINT32: { Uint32 v = AG_SwapBE32(*(Uint32 *)p); printf("%lu\n", (unsigned long)v); FORWARD(4); } break; #ifdef HAVE_64BIT case AG_SOURCE_UINT64: { Uint64 v = AG_SwapBE64(*(Uint64 *)p); printf("%llu\n", (unsigned long long)v); FORWARD(8); } break; #endif case AG_SOURCE_FLOAT: { float f = AG_SwapBEFLT(*(float *)p); printf("%f\n", f); FORWARD(4); } break; case AG_SOURCE_DOUBLE: { double f = AG_SwapBEDBL(*(double *)p); printf("%f\n", f); FORWARD(8); } break; #ifdef HAVE_LONG_DOUBLE case AG_SOURCE_LONG_DOUBLE: { long double f=AG_SwapBELDBL(*(long double *)p); printf("%Lf\n", f); FORWARD(16); } break; #endif case AG_SOURCE_STRING: if (AG_SwapBE32(*(Uint32 *)p) != AG_SOURCE_UINT32) { printf("Bad string length!\n"); break; } FORWARD(4); sLen = AG_SwapBE32(*(Uint32 *)p); FORWARD(4); if ((s = malloc(sLen+1)) == NULL) { printf("Out of memory for string!\n"); break; } memcpy(s, p, sLen); s[sLen] = '\0'; printf("\"%s\"\n", s); free(s); FORWARD(sLen); break; default: printf("(skipping)\n"); break; } } out: AG_CloseFile(ds); return (0); fail: fprintf(stderr, "%s\n", AG_GetError()); if (ds != NULL) { AG_CloseFile(ds); } AG_Destroy(); return (1); }
/* * Load surface contents from a Windows BMP file. * * Code for expanding 1bpp and 4bpp to 8bpp depth was shamefully * stolen from SDL. */ AG_Surface * AG_ReadSurfaceFromBMP(AG_DataSource *ds) { struct ag_bmp_header bh; struct ag_bmp_info_header bi; Uint32 Rmask = 0, Gmask = 0, Bmask = 0, Amask = 0; AG_Surface *s; off_t offs; Uint8 *pStart, *pEnd, *pDst; int i, bmpPitch, expandBpp, bmpPad, topDown; offs = AG_Tell(ds); bh.magic[0] = '?'; bh.magic[1] = '?'; if (AG_Read(ds, bh.magic, 2) != 0 || bh.magic[0] != 'B' || bh.magic[1] != 'M') { AG_SetError("Not a Windows BMP file (`%c%c')", bh.magic[0], bh.magic[1]); return (NULL); } /* Uses little-endian byte order */ AG_SetByteOrder(ds, AG_BYTEORDER_LE); bh.size = AG_ReadUint32(ds); bh.resv[0] = AG_ReadUint16(ds); bh.resv[1] = AG_ReadUint16(ds); bh.offBits = AG_ReadUint32(ds); bi.size = AG_ReadUint32(ds); if (bi.size == 12) { bi.w = (Uint32)AG_ReadUint16(ds); bi.h = (Uint32)AG_ReadUint16(ds); bi.planes = AG_ReadUint16(ds); bi.bitCount = AG_ReadUint16(ds); bi.encoding = AG_BMP_RGB; bi.sizeImage = 0; bi.XPelsPerMeter = 0; bi.YPelsPerMeter = 0; bi.clrUsed = 0; bi.clrImportant = 0; } else { bi.w = AG_ReadSint32(ds); bi.h = AG_ReadSint32(ds); bi.planes = AG_ReadUint16(ds); bi.bitCount = AG_ReadUint16(ds); bi.encoding = AG_ReadUint32(ds); bi.sizeImage = AG_ReadUint32(ds); bi.XPelsPerMeter = AG_ReadUint32(ds); bi.YPelsPerMeter = AG_ReadUint32(ds); bi.clrUsed = AG_ReadUint32(ds); bi.clrImportant = AG_ReadUint32(ds); } if (bi.h < 0) { topDown = 1; bi.h = -bi.h; } else { topDown = 0; } /* Will convert 1bpp/4bpp to 8bpp */ if (bi.bitCount == 1 || bi.bitCount == 4) { expandBpp = bi.bitCount; bi.bitCount = 8; } else { expandBpp = 0; } switch (bi.encoding) { case AG_BMP_RGB: if (bh.offBits == (14 + bi.size)) { switch (bi.bitCount) { case 15: case 16: Rmask = 0x7C00; Gmask = 0x03E0; Bmask = 0x001F; break; case 24: #if AG_BYTEORDER == AG_BIG_ENDIAN Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; break; #endif case 32: Rmask = 0x00FF0000; Gmask = 0x0000FF00; Bmask = 0x000000FF; break; } break; } /* FALLTHROUGH */ case AG_BMP_BITFIELDS: switch (bi.bitCount) { case 15: case 16: Rmask = AG_ReadUint32(ds); Gmask = AG_ReadUint32(ds); Bmask = AG_ReadUint32(ds); break; case 32: Rmask = AG_ReadUint32(ds); Gmask = AG_ReadUint32(ds); Bmask = AG_ReadUint32(ds); Amask = AG_ReadUint32(ds); break; } break; default: AG_SetError("BMP compression unimplemented"); return (NULL); } if ((s = AG_SurfaceRGBA(bi.w, bi.h, bi.bitCount, (Amask != 0) ? AG_SRCALPHA : 0, Rmask, Gmask, Bmask, Amask)) == NULL) { return (NULL); } if (s->format->palette != NULL) { if (bi.clrUsed == 0) { bi.clrUsed = (1 << bi.bitCount); } if (bi.size == 12) { for (i = 0; i < bi.clrUsed; i++) { s->format->palette->colors[i].b = AG_ReadUint8(ds); s->format->palette->colors[i].g = AG_ReadUint8(ds); s->format->palette->colors[i].r = AG_ReadUint8(ds); } } else { for (i = 0; i < bi.clrUsed; i++) { s->format->palette->colors[i].b = AG_ReadUint8(ds); s->format->palette->colors[i].g = AG_ReadUint8(ds); s->format->palette->colors[i].r = AG_ReadUint8(ds); (void)AG_ReadUint8(ds); /* unused */ } } s->format->palette->nColors = bi.clrUsed; } if (AG_Seek(ds, offs+bh.offBits, AG_SEEK_SET) == -1) goto fail; pStart = (Uint8 *)s->pixels; pEnd = (Uint8 *)s->pixels + (s->h*s->pitch); switch (expandBpp) { case 1: bmpPitch = (bi.w + 7) >> 3; bmpPad = ((bmpPitch % 4) ? (4 - (bmpPitch % 4)) : 0); break; case 4: bmpPitch = (bi.w + 1) >> 1; bmpPad = ((bmpPitch % 4) ? (4 - (bmpPitch % 4)) : 0); break; default: bmpPad = ((s->pitch % 4) ? (4 - (s->pitch % 4)) : 0); break; } pDst = topDown ? pStart : (pEnd - s->pitch); while (pDst >= pStart && pDst < pEnd) { switch (expandBpp) { case 1: case 4: { Uint8 px = 0; int shift = (8 - expandBpp); for (i = 0; i < s->w; i++) { if (i % (8/expandBpp) == 0) { px = AG_ReadUint8(ds); } *(pDst + i) = (px >> shift); px <<= expandBpp; } } break; default: if (AG_Read(ds, pDst, s->pitch) != 0) { goto fail; } #if AG_BYTEORDER == AG_BIG_ENDIAN switch (bi.bitCount) { case 15: case 16: { Uint16 *px = (Uint16 *)pDst; for (i = 0; i < s->w; i++) { px[i] = AG_Swap16(px[i]); } break; } case 32: { Uint32 *px = (Uint32 *)pDst; for (i = 0; i < s->w; i++) { px[i] = AG_Swap32(px[i]); } break; } } #endif /* AG_BYTEORDER == AG_BIG_ENDIAN */ break; } if (bmpPad != 0) { if (AG_Seek(ds, bmpPad, AG_SEEK_CUR) == -1) goto fail; } if (topDown) { pDst += s->pitch; } else { pDst -= s->pitch; } } return (s); fail: AG_SurfaceFree(s); return (NULL); }