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