Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

create_igortbl.c

/* ScummVM Tools
 * Copyright (C) 2007 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-11-1/tools/create_igortbl/create_igortbl.c $
 * $Id: create_igortbl.c 30944 2008-02-23 22:50:18Z sev $
 *
 */

// HACK to allow building with the SDL backend on MinGW
// see bug #1800764 "TOOLS: MinGW tools building broken"
#ifdef main
#undef main
#endif // main

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "../../engines/igor/resource_ids.h"

/*
      uint32 : 'ITBL'
      uint32 : version/tag
      uint32 : offset to strings table
      uint8  : number of game versions
      repeat (number of game versions) {
            uint32 : borland overlay size
            uint32 : offset to resources table
            uint32 : offset to sounds table
      }
      repeat (number of resources tables) {
            uint16 : number of entries
            repeat (number of entries) {
                  uint16 : id
                  uint32 : offset
                  uint32 : length
            }
      }
      repeat (number of sounds tables) {
            uint16 : number of entries
            repeat (number of entries) {
                  uint32 : offset
            }
      }
      uint16 : number of strings
      repeat (number of strings) {
            uint8 : id
            uint8 : language (0:any, 1:english, 2:spanish)
            uint8 : strlen
            char[] : string
      }
*/

#define MAX_TABLES 10
#define TABLE_SIZE(x) (sizeof(x)/sizeof(x[0]))

typedef unsigned char   uint8;
typedef unsigned short uint16;
typedef unsigned int   uint32;

struct ResourceEntry {
      int id;
      uint32 offs;
      uint32 size;
};

static struct ResourceEntry _resourceEntriesEngDemo100[] = {
#include "resource_en_demo100.h"
};

static struct ResourceEntry _resourceEntriesEngDemo110[] = {
#include "resource_en_demo110.h"
};

static struct ResourceEntry _resourceEntriesSpaCd[] = {
#include "resource_sp_cdrom.h"
};

static struct {
      struct ResourceEntry *p;
      int count;
} _resourceEntriesList[] = {
      { _resourceEntriesEngDemo100, TABLE_SIZE(_resourceEntriesEngDemo100) },
      { _resourceEntriesEngDemo110, TABLE_SIZE(_resourceEntriesEngDemo110) },
      { _resourceEntriesSpaCd,      TABLE_SIZE(_resourceEntriesSpaCd) },
      { 0, 0 }
};

static const uint32 _soundEntriesEngDemo[] = {
#include "fsd_en_demo.h"
};

static const uint32 _soundEntriesSpaCd[] = {
#include "fsd_sp_cdrom.h"
};

static struct {
      const uint32 *p;
      int count;
} _soundEntriesList[] = {
      { _soundEntriesEngDemo, TABLE_SIZE(_soundEntriesEngDemo) },
      { _soundEntriesSpaCd,   TABLE_SIZE(_soundEntriesSpaCd) },
      { 0, 0 }
};

enum {
      STR_LANG_ANY = 0,
      STR_LANG_ENG = 1,
      STR_LANG_SPA = 2
};

struct StringEntry {
      int id;
      uint8 language;
      const char *str;
};

static struct StringEntry _stringEntries[] = {
#include "strings.h"
};

struct GameVersion {
      uint32 borlandOverlaySize;
      struct ResourceEntry *resourceEntries;
      const uint32 *soundEntries;
};

static const struct GameVersion _gameVersions[] = {
      { 4086790, _resourceEntriesEngDemo100, _soundEntriesEngDemo },
      { 4094103, _resourceEntriesEngDemo110, _soundEntriesEngDemo },
      { 9115648, _resourceEntriesSpaCd,      _soundEntriesSpaCd   }
};

static const uint32 ITBL_TAG = 0x4954424C;
static const uint32 CURRENT_VERSION = 4;
static const uint32 DEFAULT_OFFSET = 0x12345678;

struct TablePtrOffset {
      const void *p;
      uint32 offset;
};

static int _tablePtrOffsetCount = 0;
struct TablePtrOffset _tablePtrOffset[MAX_TABLES];

static void addPtrOffset(FILE *fp, const void *p) {
      assert(_tablePtrOffsetCount < MAX_TABLES);
      _tablePtrOffset[_tablePtrOffsetCount].p = p;
      _tablePtrOffset[_tablePtrOffsetCount].offset = ftell(fp);
      ++_tablePtrOffsetCount;
}

static uint32 getPtrOffset(const void *p) {
      int i;
      uint32 fileOffset = 0;

      for (i = 0; i < _tablePtrOffsetCount; ++i) {
            if (_tablePtrOffset[i].p == p) {
                  fileOffset = _tablePtrOffset[i].offset;
                  break;
            }
      }
      assert(fileOffset != 0);
      return fileOffset;
}

static void writeByte(FILE *fp, uint8 b) {
      fwrite(&b, 1, 1, fp);
}

static void writeUint16BE(FILE *fp, uint16 value) {
      writeByte(fp, (uint8)(value >> 8));
      writeByte(fp, (uint8)(value & 0xFF));
}

static void writeUint32BE(FILE *fp, uint32 value) {
      writeUint16BE(fp, (uint16)(value >> 16));
      writeUint16BE(fp, (uint16)(value & 0xFFFF));
}

int compareResourceEntry(const void *a, const void *b) {
      return ((struct ResourceEntry *)a)->id - ((struct ResourceEntry *)b)->id;
}

static void writeResourceEntriesTable(FILE *fp, struct ResourceEntry *re, int count) {
      int i;

      qsort(re, count, sizeof(struct ResourceEntry), compareResourceEntry);
      writeUint16BE(fp, count);
      for (i = 0; i < count; ++i, ++re) {
            writeUint16BE(fp, re->id);
            writeUint32BE(fp, re->offs);
            writeUint32BE(fp, re->size);
      }
}

static void writeSoundEntriesTable(FILE *fp, const uint32 *fsd, int count) {
      int i;

      writeUint16BE(fp, count);
      for (i = 0; i < count; ++i) {
            writeUint32BE(fp, fsd[i]);
      }
}

int compareStringEntry(const void *a, const void *b) {
      return ((struct StringEntry *)a)->id - ((struct StringEntry *)b)->id;
}

static void writeStringEntriesTable(FILE *fp, struct StringEntry *se, int count) {
      int i, len;

      qsort(se, count, sizeof(struct StringEntry), compareStringEntry);
      writeUint16BE(fp, count);
      for (i = 0; i < count; ++i, ++se) {
            writeUint16BE(fp, se->id);
            writeByte(fp, se->language);
            len = strlen(se->str);
            assert(len < 256);
            writeByte(fp, len);
            fwrite(se->str, 1, len, fp);
      }
}

static void createTableFile(FILE *fp) {
      int i, gameVersionsCount;

      gameVersionsCount = TABLE_SIZE(_gameVersions);

      /* header */
      writeUint32BE(fp, ITBL_TAG);
      writeUint32BE(fp, CURRENT_VERSION);
      writeUint32BE(fp, DEFAULT_OFFSET); /* strings table offset */
      writeByte(fp, gameVersionsCount);

      /* game versions */
      for (i = 0; i < gameVersionsCount; ++i) {
            writeUint32BE(fp, _gameVersions[i].borlandOverlaySize);
            writeUint32BE(fp, DEFAULT_OFFSET); /* resource table offset */
            writeUint32BE(fp, DEFAULT_OFFSET); /* sound table offset */
      }

      /* resources tables */
      for (i = 0; _resourceEntriesList[i].p; ++i) {
            addPtrOffset(fp, _resourceEntriesList[i].p);
            writeResourceEntriesTable(fp, _resourceEntriesList[i].p, _resourceEntriesList[i].count);
      }

      /* sounds tables */
      for (i = 0; _soundEntriesList[i].p; ++i) {
            addPtrOffset(fp, _soundEntriesList[i].p);
            writeSoundEntriesTable(fp, _soundEntriesList[i].p, _soundEntriesList[i].count);
      }

      /* strings table */
      addPtrOffset(fp, _stringEntries);
      writeStringEntriesTable(fp, _stringEntries, TABLE_SIZE(_stringEntries));

      /* fix offsets */
      fseek(fp, 8, SEEK_SET);
      writeUint32BE(fp, getPtrOffset(_stringEntries));
      for (i = 0; i < gameVersionsCount; ++i) {
            fseek(fp, 17 + i * 12, SEEK_SET);
            writeUint32BE(fp, getPtrOffset(_gameVersions[i].resourceEntries));
            writeUint32BE(fp, getPtrOffset(_gameVersions[i].soundEntries));
      }
}

int main(int argc, char *argv[]) {
      FILE *fp = fopen("IGOR.TBL", "wb");
      if (fp) {
            createTableFile(fp);
            fclose(fp);
      }
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index