Mercurial > hg > dmlib
view dmpack.c @ 526:f7df57cafdd9
Add support for Interpaint (unpacked) and Doodle (unpacked) hires formats.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 22 Nov 2012 01:07:45 +0200 |
parents | 32250b436bca |
children | 324374ced543 bb14d7907eb2 |
line wrap: on
line source
/* * DMLib * -- PACK-file handling * Programmed and designed by Matti 'ccr' Hamalainen * (C) Copyright 2011 Tecnic Software productions (TNSP) */ #include "dmpack.h" #include "dmfile.h" #include <zlib.h> DMPackEntry *dm_pack_entry_new() { return (DMPackEntry *) dmMalloc0(sizeof(DMPackEntry)); } void dm_pack_entry_free(DMPackEntry * node) { dmFree(node); } void dm_pack_entry_insert(DMPackEntry ** packDir, DMPackEntry * node) { if (*packDir != NULL) { node->prev = (*packDir)->prev; (*packDir)->prev->next = node; (*packDir)->prev = node; } else { *packDir = node->prev = node; } node->next = NULL; } void dm_pack_entry_delete(DMPackEntry ** packDir, DMPackEntry * node) { if (node->prev) node->prev->next = node->next; if (node->next) node->next->prev = node->prev; else (*packDir)->prev = node->prev; node->prev = node->next = NULL; } DMPackEntry *dm_pack_find(DMPackEntry *list, const char *filename) { DMPackEntry *node; for (node = list; node != NULL; node = node->next) { if (strcmp(node->filename, filename) == 0) return node; } return NULL; } /* * OPEN a packfile */ int dm_pack_open(const char *filename, DMPackFile ** ppPack, BOOL readOnly) { unsigned int i; DMPackFile *pack; DMPackFileHeader hdr; *ppPack = NULL; // Allocate packfile-structure pack = (DMPackFile *) dmMalloc0(sizeof(DMPackFile)); if (pack == NULL) return DMERR_MALLOC; // Open the file pack->file = fopen(filename, (readOnly) ? "rb" : "r+b"); if (pack->file == NULL) { dmFree(pack); return DMERR_FOPEN; } pack->filename = dm_strdup(filename); // Read PACK header fseek(pack->file, 0L, SEEK_SET); if (!dm_fread_str(pack->file, (Uint8 *) &hdr.ident, sizeof(hdr.ident)) || !dm_fread_le16(pack->file, &hdr.version) || !dm_fread_le32(pack->file, &hdr.dirEntries) || !dm_fread_le32(pack->file, &hdr.dirOffset)) { dm_pack_close(pack); return DMERR_FREAD; } // Check information if (memcmp(&hdr.ident, DPACK_IDENT, sizeof(hdr.ident)) != 0) { dm_pack_close(pack); return DMERR_NOTPACK; } if (hdr.version != DPACK_VERSION) { dm_pack_close(pack); return DMERR_VERSION; } // Read directory if (fseek(pack->file, hdr.dirOffset, SEEK_SET) != 0) { dm_pack_close(pack); return DMERR_INVALID; } for (i = 0; i < hdr.dirEntries; i++) { // Allocate and read directory entry DMPackEntry *entry = dm_pack_entry_new(); if (entry == NULL) { dm_pack_close(pack); return DMERR_MALLOC; } if (!dm_fread_str(pack->file, (Uint8 *) &entry->filename, sizeof(entry->filename)) || !dm_fread_le32(pack->file, &entry->size) || !dm_fread_le32(pack->file, &entry->offset) || !dm_fread_le32(pack->file, &entry->length) || !dm_fread_le32(pack->file, &entry->resFlags)) { *ppPack = pack; return DMERR_FREAD; } // Insert into list dm_pack_entry_insert(&pack->entries, entry); } // Set the result *ppPack = pack; return DMERR_OK; } /* * CLOSE the packfile */ int dm_pack_close(DMPackFile * pack) { DMPackEntry *node, *next; if (pack == NULL) return DMERR_OK; // Write the directory node = pack->entries; while (node != NULL) { next = node->next; dm_pack_entry_free(node); node = next; } // Close the file if (pack->file != NULL) { fclose(pack->file); pack->file = NULL; } // Free structures dmFree(pack->filename); pack->filename = NULL; // Free packfile pack->entries = NULL; dmFree(pack); return DMERR_OK; }