/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program 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 3 of the License, or
(at your option) any later version.
This program 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 this program. If not, see .
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "hsUtils.h"
#include "hsTimer.h"
#include "../plFile/hsFiles.h"
#include "../plFile/plFileUtils.h"
#include "../plResMgr/plResManager.h"
#include "../plResMgr/plResMgrSettings.h"
#include "../plAgeDescription/plAgeManifest.h"
#include "../plResMgr/plRegistryHelpers.h"
#include "../plResMgr/plRegistryNode.h"
#include "../plAudioCore/plSoundBuffer.h"
#include "hsStream.h"
#include "../pnUtils/pnUtils.h"
#include "../pnProduct/pnProduct.h"
//// Globals /////////////////////////////////////////////////////////////////
plResManager* gResMgr = nil;
bool DumpStats(const char* patchDir);
bool DumpSounds();
//// PrintVersion ///////////////////////////////////////////////////////////////
void PrintVersion()
{
wchar productString[256];
ProductString(productString, arrsize(productString));
_putws(productString);
}
//// PrintHelp ///////////////////////////////////////////////////////////////
int PrintHelp( void )
{
puts("");
PrintVersion();
puts("");
puts("Usage: plPageInfo [-s -i] pageFile");
puts(" plPageInfo -v");
puts("Where:" );
puts(" -v print version and exit.");
puts(" -s dump sounds in page to the console");
puts(" -i dump object size info to .csv files");
puts(" pageFile is the path to the .prp file");
puts("");
return -1;
}
//// main ////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
if (argc >= 1 && hsStrEQ(argv[1], "-v"))
{
PrintVersion();
return 0;
}
if (argc < 3)
return PrintHelp();
bool sounds = false;
bool stats = false;
int arg = 1;
for (arg = 1; arg < argc; arg++)
{
if (hsStrEQ(argv[arg], "-s"))
sounds = true;
else if (hsStrEQ(argv[arg], "-i"))
stats = true;
else
break;
}
// Make sure we have 1 arg left after getting the options
char* pageFile = nil;
if (arg < argc)
pageFile = argv[arg];
else
return PrintHelp();
// Init our special resMgr
plResMgrSettings::Get().SetFilterNewerPageVersions(false);
plResMgrSettings::Get().SetFilterOlderPageVersions(false);
plResMgrSettings::Get().SetLoadPagesOnInit(false);
gResMgr = TRACKED_NEW plResManager;
hsgResMgr::Init(gResMgr);
gResMgr->AddSinglePage(pageFile);
if (sounds)
DumpSounds();
if (stats)
{
char path[256];
strcpy(path, pageFile);
plFileUtils::StripFile(path);
DumpStats(path);
}
hsgResMgr::Shutdown();
return 0;
}
//// plSoundBufferCollector //////////////////////////////////////////////////
// Page iterator that collects all the plSoundBuffers in all of our pages
class plSoundBufferCollector : public plRegistryPageIterator, public plKeyCollector
{
public:
plSoundBufferCollector(hsTArray& keyArray)
: plKeyCollector(keyArray) {}
hsBool EatPage(plRegistryPageNode* page)
{
page->LoadKeys();
return page->IterateKeys(this, plSoundBuffer::Index());
return true;
}
};
bool DumpSounds()
{
hsTArray soundKeys;
plSoundBufferCollector soundCollector(soundKeys);
gResMgr->IterateAllPages(&soundCollector);
for (int i = 0; i < soundKeys.GetCount(); i++)
{
plSoundBuffer* buffer = plSoundBuffer::ConvertNoRef(soundKeys[i]->VerifyLoaded());
if (buffer)
{
// Ref it...
buffer->GetKey()->RefObject();
// Get the filename from it and add that file if necessary
const char* filename = buffer->GetFileName();
if (filename)
{
UInt32 flags = 0;
if (stricmp(plFileUtils::GetFileExt(filename), "wav") != 0)
{
if (buffer->HasFlag(plSoundBuffer::kOnlyLeftChannel) ||
buffer->HasFlag(plSoundBuffer::kOnlyRightChannel))
hsSetBits(flags, plManifestFile::kSndFlagCacheSplit);
else if (buffer->HasFlag(plSoundBuffer::kStreamCompressed))
hsSetBits(flags, plManifestFile::kSndFlagStreamCompressed);
else
hsSetBits(flags, plManifestFile::kSndFlagCacheStereo);
}
printf("%s,%u\n", filename, flags);
}
// Unref the object so it goes away
buffer->GetKey()->UnRefObject();
}
}
soundKeys.Reset();
plIndirectUnloadIterator iter;
gResMgr->IterateAllPages(&iter);
return true;
}
//////////////////////////////////////////////////////////////////////////
#include "../pnKeyedObject/plKeyImp.h"
class plStatDumpIterator : public plRegistryPageIterator, public plRegistryKeyIterator
{
protected:
const char* fOutputDir;
hsUNIXStream fStream;
public:
plStatDumpIterator(const char* outputDir) : fOutputDir(outputDir) {}
hsBool EatKey(const plKey& key)
{
plKeyImp* imp = (plKey)key;
fStream.WriteString(imp->GetName());
fStream.WriteString(",");
fStream.WriteString(plFactory::GetNameOfClass(imp->GetUoid().GetClassType()));
fStream.WriteString(",");
char buf[30];
sprintf(buf, "%u", imp->GetDataLen());
fStream.WriteString(buf);
fStream.WriteString("\n");
return true;
}
hsBool EatPage(plRegistryPageNode* page)
{
const plPageInfo& info = page->GetPageInfo();
char fileName[256];
sprintf(fileName, "%s%s_%s.csv", fOutputDir, info.GetAge(), info.GetPage());
fStream.Open(fileName, "wt");
page->LoadKeys();
page->IterateKeys(this);
fStream.Close();
return true;
}
};
bool DumpStats(const char* patchDir)
{
plStatDumpIterator statDump(patchDir);
gResMgr->IterateAllPages(&statDump);
return true;
}