// Copyright 2003 Jeremy Sawicki // // This file is part of OxydLib. // // OxydLib 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. // // OxydLib 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 OxydLib; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include #include "OxydVersion.h" #include #include "VecUtils.h" #include "FileUtils.h" #include "DatFile.h" #include "Level.h" using namespace std; void usage() { printf("Usage:\n"); printf(" printstats [options] \n"); printf("\n"); printf("Description:\n"); printf(" The printstats program parses the Oxyd data file specified by \n"); printf(" and displays statistics about the contents of the levels. For each\n"); printf(" type of surface, piece, or object, printstats displays the level\n"); printf(" numbers where it is used, as well as the leel numbers where it is used\n"); printf(" as a signal sender or recipient (pieces and objects only).\n"); printf("\n"); printf("Options:\n"); printf(" -v1 Oxyd 1\n"); printf(" -vm Oxyd Magnum\n"); printf(" -vp PerOxyd (default)\n"); printf(" -ve Oxyd Extra\n"); printf("\n"); } int main(int argc, char *argv[]) { OxydVersion ver = OxydVersion_PerOxyd; bool bGotDatFile = false; string strDatFile; int nArg = 1; while (nArg < argc) { string strArg(argv[nArg]); nArg++; if (strArg.compare("-v1") == 0) { ver = OxydVersion_Oxyd1; } else if (strArg.compare("-vm") == 0) { ver = OxydVersion_OxydMagnum; } else if (strArg.compare("-vp") == 0) { ver = OxydVersion_PerOxyd; } else if (strArg.compare("-ve") == 0) { ver = OxydVersion_OxydExtra; } else if (!bGotDatFile) { strDatFile = strArg; bGotDatFile = true; } else { usage(); exit(1); } } if (!bGotDatFile) { usage(); exit(1); } ByteVec fileData; bool success = readFile(strDatFile, &fileData); if (!success) { printf("Error reading DAT file.\n"); exit(1); } DatFile datFile; string msg; success = parseDatFile(fileData, ver, &datFile, &msg); if (!success) { printf("Error parsing DAT file:\n"); printf("%s\n", msg.c_str()); exit(1); } set used[GridType_Count][256]; set usedAsSender[GridType_Count][256]; set usedAsRecipient[GridType_Count][256]; for (int nLevel = 0; nLevel < 200; nLevel++) { Level level; success = parseLevel(datFile.getLevel(nLevel), &level, &msg); if (!success) { printf("Error parsing level %d:\n", nLevel + 1); printf("%s\n", msg.c_str()); exit(1); } if (level.isEmpty()) { continue; } { for (int gridTypeInt = GridType_First; gridTypeInt <= GridType_Last; gridTypeInt++) { GridType gridType = GridType(gridTypeInt); for (unsigned int y = 0; y < level.getHeight(); y++) { for (unsigned int x = 0; x < level.getWidth(); x++) { unsigned char byteVal = level.getGrid(gridType).get(x, y); used[gridType][byteVal].insert(nLevel); } } if (gridType == GridType_Surfaces) { continue; } } } { set senders; level.getSenders(&senders); set::const_iterator senderIter = senders.begin(); set::const_iterator senderEnd = senders.end(); for (; senderIter != senderEnd; ++senderIter) { const SignalLocation &sender = *senderIter; unsigned char senderByteVal = level.getGrid(sender.getGridType()).get(sender.getX(), sender.getY()); usedAsSender[sender.getGridType()][senderByteVal].insert(nLevel); int numRecipients = level.getNumRecipients(sender); for (int nRecipient = 0; nRecipient < numRecipients; nRecipient++) { const SignalLocation &recipient = level.getRecipient(sender, nRecipient); unsigned char recipientByteVal = level.getGrid(recipient.getGridType()).get(recipient.getX(), recipient.getY()); usedAsRecipient[recipient.getGridType()][recipientByteVal] .insert(nLevel); } } } } { for (int gridTypeInt = GridType_First; gridTypeInt <= GridType_Last; gridTypeInt++) { GridType gridType = GridType(gridTypeInt); switch (gridType) { case GridType_Surfaces: printf("Surfaces:\n"); break; case GridType_Pieces: printf("Pieces:\n"); break; case GridType_Objects: printf("Objects:\n"); break; default: exit(1); } for (int byteValInt = 0; byteValInt < 256; byteValInt++) { printf("%02x:", byteValInt); const set &intSet = used[gridType][byteValInt]; set::const_iterator iter = intSet.begin(); set::const_iterator end = intSet.end(); for (; iter != end; ++iter) { int nLevel = *iter; printf(" %d", nLevel + 1); } printf("\n"); } printf("\n"); } } { for (int gridTypeInt = GridType_First; gridTypeInt <= GridType_Last; gridTypeInt++) { GridType gridType = GridType(gridTypeInt); if (gridType == GridType_Surfaces) { continue; } for (int useType = 1; useType <= 2; useType++) { switch (gridType) { case GridType_Pieces: printf("Pieces ("); break; case GridType_Objects: printf("Objects ("); break; default: exit(1); } switch (useType) { case 1: printf("senders"); break; case 2: printf("recipients"); break; default: exit(1); } printf("):\n"); for (int byteValInt = 0; byteValInt < 256; byteValInt++) { printf("%02x:", byteValInt); const set &intSet = (useType == 1 ? usedAsSender : usedAsRecipient) [gridType][byteValInt]; set::const_iterator iter = intSet.begin(); set::const_iterator end = intSet.end(); for (; iter != end; ++iter) { int nLevel = *iter; printf(" %d", nLevel + 1); } printf("\n"); } printf("\n"); } } } return 0; }