1
// Copyright 2003 Jeremy Sawicki
3
// This file is part of OxydLib.
5
// OxydLib is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; either version 2 of the License, or
8
// (at your option) any later version.
10
// OxydLib is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with OxydLib; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
#include "OxydVersion.h"
24
#include "FileUtils.h"
28
#include "EnigmaNames.cpp"
31
using namespace OxydLib;
32
using namespace enigma_names;
37
printf(" printstats [options] <datfile>\n");
39
printf("Description:\n");
40
printf(" The printstats program parses the Oxyd data file specified by <datfile>\n");
41
printf(" and displays statistics about the contents of the levels. For each\n");
42
printf(" type of surface, piece, or object, printstats displays the level\n");
43
printf(" numbers where it is used, as well as the level numbers where it is used\n");
44
printf(" as a signal sender or recipient (pieces and objects only).\n");
47
printf(" -v1 Oxyd 1\n");
48
printf(" -vm Oxyd Magnum\n");
49
printf(" -vg Oxyd Magnum Gold\n");
50
printf(" -vp PerOxyd (default)\n");
51
printf(" -ve Oxyd Extra\n");
52
printf(" -n Use enigma names for objects\n");
56
void printObjectValue(int num, Mapping *m, GridType type) {
58
static int max_length[GridType_Count] = { -1, -1, -1 };
60
if (max_length[type]<0) {
61
for (int t = GridType_First; t <= GridType_Last; ++t) {
62
const char *(Mapping::*getName)(int) const = 0;
65
case GridType_Surfaces: getName = &Mapping::floorName; break;
66
case GridType_Pieces: getName = &Mapping::stoneName; break;
67
case GridType_Objects: getName = &Mapping::itemName; break;
68
default : assert(0); break;
72
for (int i = 0; i<256; ++i) {
73
const char *name = (m->*getName)(i);
75
int len = strlen(name);
76
if (len>max) max = len;
86
case GridType_Surfaces: name = m->floorName(num); break;
87
case GridType_Pieces: name = m->stoneName(num); break;
88
case GridType_Objects: name = m->itemName(num); break;
89
default : assert(0); break;
91
printf("%-*s ", max_length[type], name ? name : "");
96
int main(int argc, char *argv[])
98
OxydVersion ver = OxydVersion_PerOxyd;
99
bool bGotDatFile = false;
100
bool useEnigmaNames = false;
104
while (nArg < argc) {
105
string strArg(argv[nArg]);
108
if (strArg.compare("-v1") == 0) {
109
ver = OxydVersion_Oxyd1;
110
} else if (strArg.compare("-vm") == 0) {
111
ver = OxydVersion_OxydMagnum;
112
} else if (strArg.compare("-vg") == 0) {
113
ver = OxydVersion_OxydMagnumGold;
114
} else if (strArg.compare("-vp") == 0) {
115
ver = OxydVersion_PerOxyd;
116
} else if (strArg.compare("-ve") == 0) {
117
ver = OxydVersion_OxydExtra;
118
} else if (strArg.compare("-n") == 0) {
119
useEnigmaNames = true;
120
} else if (!bGotDatFile) {
134
Mapping *enigmaMapping = 0;
135
if (useEnigmaNames) enigmaMapping = new Mapping(ver);
137
OxydLib::ByteVec fileData;
138
bool success = readFile(strDatFile, &fileData);
140
printf("Error reading DAT file.\n");
146
success = parseDatFile(fileData, ver, &datFile, &msg);
148
printf("Error parsing DAT file:\n");
149
printf("%s\n", msg.c_str());
153
set<int> used[GridType_Count][256];
154
set<int> usedAsSender[GridType_Count][256];
155
set<int> usedAsRecipient[GridType_Count][256];
157
for (int nLevel = 0; nLevel < 200; nLevel++) {
158
OxydLib::Level level;
159
success = parseLevel(datFile.getLevel(nLevel), &level, &msg);
161
printf("Error parsing level %d:\n", nLevel + 1);
162
printf("%s\n", msg.c_str());
167
if (level.isEmpty()) {
172
for (int gridTypeInt = GridType_First;
173
gridTypeInt <= GridType_Last;
175
GridType gridType = GridType(gridTypeInt);
177
for (unsigned int y = 0; y < level.getHeight(); y++) {
178
for (unsigned int x = 0; x < level.getWidth(); x++) {
179
unsigned char byteVal = level.getGrid(gridType).get(x, y);
180
used[gridType][byteVal].insert(nLevel);
184
if (gridType == GridType_Surfaces) {
191
set<SignalLocation> senders;
192
level.getSenders(&senders);
193
set<SignalLocation>::const_iterator senderIter = senders.begin();
194
set<SignalLocation>::const_iterator senderEnd = senders.end();
195
for (; senderIter != senderEnd; ++senderIter) {
196
const SignalLocation &sender = *senderIter;
198
unsigned char senderByteVal =
199
level.getGrid(sender.getGridType()).get(sender.getX(),
201
usedAsSender[sender.getGridType()][senderByteVal].insert(nLevel);
203
int numRecipients = level.getNumRecipients(sender);
204
for (int nRecipient = 0;
205
nRecipient < numRecipients;
207
const SignalLocation &recipient =
208
level.getRecipient(sender, nRecipient);
210
unsigned char recipientByteVal =
211
level.getGrid(recipient.getGridType()).get(recipient.getX(),
213
usedAsRecipient[recipient.getGridType()][recipientByteVal]
221
for (int gridTypeInt = GridType_First;
222
gridTypeInt <= GridType_Last;
224
GridType gridType = GridType(gridTypeInt);
227
case GridType_Surfaces: printf("Surfaces:\n"); break;
228
case GridType_Pieces: printf("Pieces:\n"); break;
229
case GridType_Objects: printf("Objects:\n"); break;
233
for (int byteValInt = 0; byteValInt < 256; byteValInt++) {
234
printObjectValue(byteValInt, enigmaMapping, gridType);
235
// printf("%02x:", byteValInt);
237
const set<int> &intSet = used[gridType][byteValInt];
238
set<int>::const_iterator iter = intSet.begin();
239
set<int>::const_iterator end = intSet.end();
240
for (; iter != end; ++iter) {
242
printf(" %d", nLevel + 1);
253
for (int gridTypeInt = GridType_First;
254
gridTypeInt <= GridType_Last;
256
GridType gridType = GridType(gridTypeInt);
258
if (gridType == GridType_Surfaces) {
262
for (int useType = 1; useType <= 2; useType++) {
264
case GridType_Pieces: printf("Pieces ("); break;
265
case GridType_Objects: printf("Objects ("); break;
270
case 1: printf("senders"); break;
271
case 2: printf("recipients"); break;
277
for (int byteValInt = 0; byteValInt < 256; byteValInt++) {
278
printObjectValue(byteValInt, enigmaMapping, gridType);
279
// printf("%02x:", byteValInt);
281
const set<int> &intSet =
282
(useType == 1 ? usedAsSender : usedAsRecipient)
283
[gridType][byteValInt];
284
set<int>::const_iterator iter = intSet.begin();
285
set<int>::const_iterator end = intSet.end();
286
for (; iter != end; ++iter) {
288
printf(" %d", nLevel + 1);
299
delete enigmaMapping;