mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-26 03:37:53 +00:00
07a7800ebd
svn-id: r30963
291 lines
7.2 KiB
C++
291 lines
7.2 KiB
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$
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
// 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;
|
|
}
|