aboutsummaryrefslogtreecommitdiff
path: root/tools/create_igortbl/create_igortbl.c
blob: 41bcaa56616cfbaa4ab026cf6ee06ec7a7afb867 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "../../engines/igor/resource_ids.h"

/*
	uint32 : 'ITBL'
	uint32 : version/tag
	uint8  : number of game versions
	repeat (number of game versions) {
		uint32 : borland overlay size
		uint32 : offset to resource table
	}
	repeat (number of game versions) {
		repeat (number of resources tables) {
			uint16 : number of entries
			repeat (number of entries) {
				uint16 : id
				uint32 : offset
				uint32 : length
			}
		}
	}
*/

#define MAX_VERSIONS 2

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

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

static const int _sizeOfResourceEntry = 10;

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

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

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

static const struct GameVersion _gameVersions[] = {
	{ 4086790, &_resourceEntriesEngDemo100[0] },
	{ 4094103, &_resourceEntriesEngDemo110[0] },
	{ 0, 0 }
};

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));
}

static void writeResourceEntry(FILE *fp, const struct ResourceEntry *re) {
	writeUint16BE(fp, re->id);
	writeUint32BE(fp, re->offs);
	writeUint32BE(fp, re->size);
}

static const uint32 ITBL_TAG = 0x4954424C;
static const uint32 CURRENT_VERSION = 1;

static void createTableFile(FILE *fp) {
	int i, j, gameVersionsCount;
	uint32 resourceEntriesTableSize[MAX_VERSIONS];
	uint32 resourceEntriesTableOffs[MAX_VERSIONS];

	/* get resource entries tables size */
	for (i = 0; _gameVersions[i].resourceEntries; ++i) {
		assert(i <= MAX_VERSIONS);
		resourceEntriesTableSize[i] = 0;
		for (j = 0; _gameVersions[i].resourceEntries[j].id != 0;  ++j) {
			++resourceEntriesTableSize[i];
		}
	}
	gameVersionsCount = i;

	/* header */
	writeUint32BE(fp, ITBL_TAG);
	writeUint32BE(fp, CURRENT_VERSION);

	/* game versions header */
	writeByte(fp, gameVersionsCount);
	resourceEntriesTableOffs[0] = 9 + gameVersionsCount * 8;
	for (i = 1; i < gameVersionsCount; ++i) {
		resourceEntriesTableOffs[i] = resourceEntriesTableOffs[i - 1] + 2 + resourceEntriesTableSize[i - 1] * _sizeOfResourceEntry;
	}
	for (i = 0; i < gameVersionsCount; ++i) {
		writeUint32BE(fp, _gameVersions[i].borlandOverlaySize);
		writeUint32BE(fp, resourceEntriesTableOffs[i]);
	}

	/* resource entries tables */
	for (i = 0; _gameVersions[i].resourceEntries; ++i) {
		writeUint16BE(fp, resourceEntriesTableSize[i]);
		for (j = 0; _gameVersions[i].resourceEntries[j].id != 0;  ++j) {
			writeResourceEntry(fp, &_gameVersions[i].resourceEntries[j]);
		}
	}
}

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