1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 // Disable symbol overrides so that we can use system headers.
24 #define FORBIDDEN_SYMBOL_ALLOW_ALL
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <assert.h>
29 #include "util.h"
30 #include "create_cryomni3d_dat.h"
31 
32 struct Parts {
33 	size_t (*writeHeader)(FILE *f, uint32 offset, uint32 size);
34 	size_t (*writeData)(FILE *f);
35 	uint32 offset;
36 	uint32 size;
37 };
38 
39 #define DEFINE_GAME_PLATFORM_LANG_FUNCS(game, platform, lang) \
40 	size_t write ## game ## _ ## platform ## _ ## lang ## _Header(FILE *f, \
41 								   uint32 offset, uint32 size); \
42 	size_t write ## game ## _ ## platform ## _ ## lang ## _Data(FILE *f);
43 #define GAME_PLATFORM_LANG_PART(game, platform, lang) { write ## game ## _ ## platform ## _ ## lang ## _Header, \
44 	write ## game ## _ ## platform ## _ ## lang ## _Data, 0, 0 }
45 
46 DEFINE_GAME_PLATFORM_LANG_FUNCS(Versailles, ALL, FR)
47 DEFINE_GAME_PLATFORM_LANG_FUNCS(Versailles, ALL, BR)
48 DEFINE_GAME_PLATFORM_LANG_FUNCS(Versailles, ALL, DE)
49 DEFINE_GAME_PLATFORM_LANG_FUNCS(Versailles, ALL, EN)
50 DEFINE_GAME_PLATFORM_LANG_FUNCS(Versailles, ALL, ES)
51 DEFINE_GAME_PLATFORM_LANG_FUNCS(Versailles, ALL, IT)
52 DEFINE_GAME_PLATFORM_LANG_FUNCS(Versailles, ALL, JA)
53 DEFINE_GAME_PLATFORM_LANG_FUNCS(Versailles, ALL, KO)
54 DEFINE_GAME_PLATFORM_LANG_FUNCS(Versailles, ALL, ZT)
55 
56 static Parts gamesParts[] = {
57 	GAME_PLATFORM_LANG_PART(Versailles, ALL, FR),
58 	GAME_PLATFORM_LANG_PART(Versailles, ALL, BR),
59 	GAME_PLATFORM_LANG_PART(Versailles, ALL, DE),
60 	GAME_PLATFORM_LANG_PART(Versailles, ALL, EN),
61 	GAME_PLATFORM_LANG_PART(Versailles, ALL, ES),
62 	GAME_PLATFORM_LANG_PART(Versailles, ALL, IT),
63 	GAME_PLATFORM_LANG_PART(Versailles, ALL, JA),
64 	GAME_PLATFORM_LANG_PART(Versailles, ALL, KO),
65 	GAME_PLATFORM_LANG_PART(Versailles, ALL, ZT),
66 };
67 
68 #define CRYOMNI3D_DAT_VER 1 // 32-bit integer
69 
writeFileHeader(FILE * f,uint16 games)70 size_t writeFileHeader(FILE *f, uint16 games) {
71 	size_t headerSize = 0;
72 	fwrite("CY3DDATA", 8, 1, f);
73 	headerSize += 8;
74 	headerSize += writeUint16LE(f, CRYOMNI3D_DAT_VER);
75 	headerSize += writeUint16LE(f, games);
76 	// Dummy value to pad to 16 bytes
77 	headerSize += writeUint32LE(f, 0);
78 	assert((headerSize & PADDING_MASK) == 0);
79 	return headerSize;
80 }
81 
writeGameHeader(FILE * f,uint32 gameId,uint16 version,uint16 lang,uint32 platforms,uint32 offset,uint32 size)82 size_t writeGameHeader(FILE *f, uint32 gameId, uint16 version, uint16 lang, uint32 platforms,
83 					   uint32 offset, uint32 size) {
84 	size_t headerSize = 0;
85 	headerSize += writeUint32BE(f, gameId); // BE to keep the tag readable
86 	headerSize += writeUint16LE(f, version);
87 	headerSize += writeUint16BE(f, lang); // BE to keep the tag readable
88 	headerSize += writeUint32LE(f, platforms);
89 	headerSize += writeUint32LE(f, offset);
90 	headerSize += writeUint32LE(f, size);
91 	return headerSize;
92 }
93 
emitData(char * outputFilename)94 static int emitData(char *outputFilename) {
95 	FILE *f = fopen(outputFilename, "w+b");
96 	if (!f) {
97 		printf("ERROR: Unable to create output file %s\n", outputFilename);
98 		return 1;
99 	}
100 
101 	printf("Generating %s...\n", outputFilename);
102 
103 	writeFileHeader(f);
104 
105 	for (unsigned int i = 0; i < ARRAYSIZE(gamesParts); i++) {
106 		gamesParts[i].writeHeader(f, 0xdeadfeed, 0xdeadfeed);
107 	}
108 
109 	// Pad the games list
110 	writePadding(f);
111 
112 	for (unsigned int i = 0; i < ARRAYSIZE(gamesParts); i++) {
113 		gamesParts[i].offset = ftell(f);
114 		gamesParts[i].size = gamesParts[i].writeData(f);
115 	}
116 
117 	fseek(f, 0, SEEK_SET);
118 
119 	writeFileHeader(f, ARRAYSIZE(gamesParts));
120 
121 	for (unsigned int i = 0; i < ARRAYSIZE(gamesParts); i++) {
122 		gamesParts[i].writeHeader(f, gamesParts[i].offset, gamesParts[i].size);
123 	}
124 
125 	fclose(f);
126 
127 	printf("Done!\n");
128 
129 	return 0;
130 }
131 
main(int argc,char ** argv)132 int main(int argc, char **argv) {
133 
134 	if (argc > 1) {
135 		return emitData(argv[1]);
136 	} else {
137 		printf("Usage: %s <output.dat>\n", argv[0]);
138 	}
139 
140 	return 0;
141 }
142