diff --git a/engines/private/decompiler.cpp b/engines/private/decompiler.cpp index 66824686c88..749ab8a2cc0 100644 --- a/engines/private/decompiler.cpp +++ b/engines/private/decompiler.cpp @@ -1,53 +1,49 @@ -#include -#include -#include "decompiler.h" +#include "private/decompiler.h" namespace Private { -Decompiler::~Decompiler() { -} +Decompiler::Decompiler(char *buf, uint32 fileSize, bool mac) { -Decompiler::Decompiler(const std::string &fileName, bool mac) { - std::ifstream infile(fileName); - if (!infile.good()) - throw std::invalid_argument("File does not exist"); - std::ifstream input(fileName, std::ios::binary); - std::vector buffer(std::istreambuf_iterator(input), {}); - decompile(buffer, mac); -} -Decompiler::Decompiler(std::vector &buffer, bool mac) { - decompile(buffer, mac); -} - -void Decompiler::decompile(std::vector &buffer, bool mac) { - std::vector::iterator it = buffer.begin(); - - std::string firstBytes(it, it + kHeader.length()); - if (firstBytes != kHeader) { - throw std::invalid_argument("Not a precompiled game matrix"); + Common::Array array; + uint32 i = 0; + while (i < fileSize) { + array.push_back(buf[i]); + i++; } + decompile(array, mac); +} - std::stringstream ss; +void Decompiler::decompile(Common::Array &buffer, bool mac) { + Common::Array::iterator it = buffer.begin(); + + Common::String firstBytes((const char *) it, (const char *) it + kHeader.size()); + //debug("first bytes \"%s\"", firstBytes.c_str()); + + if (firstBytes != kHeader) { + error("Not a precompiled game matrix"); + } + + Common::String ss; bool inDefineRects = false; - for (it += kHeader.length() ; it != buffer.end() ; ) { + for (it += kHeader.size() ; it != buffer.end() ; ) { unsigned char byte = *it++; if (byte == kCodeString) { unsigned char len = *it++; - std::string s(it,it+len); + Common::String s((const char *)it,(const char *)it+len); it += len; - ss << "\"" << s << "\""; + ss += Common::String::format("\"%s\"", s.c_str()); } else if (byte == kCodeShortLiteral || byte == kCodeShortId) { unsigned char b1 = *it++; unsigned char b2 = *it++; unsigned int number = mac ? b2 + (b1 << 8) : b1 + (b2 << 8); - if (byte == kCodeShortId) ss << "k"; - ss << number; + if (byte == kCodeShortId) ss += "k"; + ss += Common::String::format("%d", number); } else if (byte == kCodeRect && inDefineRects) { - ss << "RECT"; // override CRect - } else if (byte <= kCodeShortId && kCodeTable[byte].length() > 0) { - ss << kCodeTable[byte]; + ss += "RECT"; // override CRect + } else if (byte <= kCodeShortId && strlen(kCodeTable[byte]) > 0) { + ss += kCodeTable[byte]; } else { - throw std::invalid_argument("Unknown byte code"); + error("Unknown byte code"); } if (byte == kCodeRects) { @@ -56,11 +52,11 @@ void Decompiler::decompile(std::vector &buffer, bool mac) { inDefineRects = false; } } - _result = ss.str(); + _result = ss; } -void Decompiler::getResult(std::string &result) const { - result = _result; +Common::String Decompiler::getResult() const { + return _result; } -} +} \ No newline at end of file diff --git a/engines/private/decompiler.h b/engines/private/decompiler.h index 4d8796f07db..ba7e6573442 100644 --- a/engines/private/decompiler.h +++ b/engines/private/decompiler.h @@ -1,9 +1,13 @@ -#include -#include +#ifndef PRIVATE_DECOMPILER_H +#define PRIVATE_DECOMPILER_H + +#include "common/array.h" +#include "common/str.h" +#include "common/debug.h" namespace Private { -const std::string kHeader("Precompiled Game Matrix"); +const Common::String kHeader = "Precompiled Game Matrix"; const unsigned char kCodeString = 0x01; const unsigned char kCodeShortLiteral = 0x02; @@ -12,7 +16,7 @@ const unsigned char kCodeRect = 0x2e; const unsigned char kCodeRects = 0x4f; const unsigned char kCodeShortId = 0x50; -const std::vector kCodeTable = {"", // +const static char *kCodeTable[] = {"", // "", // 0x01 (string) "", // 0x02 (short literal) " {\n", // 0x03 @@ -92,18 +96,19 @@ const std::vector kCodeTable = {"", // "", // "", // "rects", // 0x4f - ""}; // 0x50 (short id) + "" + }; // 0x50 (short id) class Decompiler { public: - Decompiler(const std::string &filename, bool mac = false); - Decompiler(std::vector &buffer, bool mac = false); - virtual ~Decompiler(); - void getResult(std::string &result) const; + Decompiler(char *buf, uint32 fileSize, bool mac = false); + Common::String getResult() const; private: - void decompile(std::vector &buffer, bool mac); - std::string _result; + void decompile(Common::Array &buffer, bool mac); + Common::String _result; }; } + +#endif \ No newline at end of file diff --git a/engines/private/detection.cpp b/engines/private/detection.cpp index 3010f15fe99..da9a0d59dfa 100644 --- a/engines/private/detection.cpp +++ b/engines/private/detection.cpp @@ -65,7 +65,7 @@ static const ADGameDescription gameDescriptions[] = { "bklynlgo.bmp", "1dfb703349a46f8ec183de107992b7f5", 33118), Common::EN_GRB, Common::kPlatformWindows, - ADGF_UNSUPPORTED, + ADGF_UNSTABLE, GUIO1(GUIO_NOMIDI) }, { @@ -75,7 +75,7 @@ static const ADGameDescription gameDescriptions[] = { "bklynlgo.bmp", "1dfb703349a46f8ec183de107992b7f5", 33118), Common::EN_GRB, Common::kPlatformWindows, - ADGF_DEMO | ADGF_TESTING, + ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NOMIDI) }, { @@ -100,32 +100,32 @@ static const ADGameDescription gameDescriptions[] = { }, { "private-eye", // EU release (ES) - "It uses different file format for the assest", + "Demo", AD_ENTRY2s("pvteye.ex_", "f41770550ab717086b2d0c805fef4b8f", 498176, "bklynlgo.bmp", "1dfb703349a46f8ec183de107992b7f5", 33118), Common::ES_ESP, Common::kPlatformWindows, - ADGF_UNSUPPORTED, + ADGF_UNSTABLE, GUIO1(GUIO_NOMIDI) }, { - "private-eye", // Demo from the EU release (ES) - "It uses different file format for the assest", + "private-eye", // Demo from the EU release (ES) + "Demo", AD_ENTRY2s("pvtdemo.ex_", "048f751acd7a0f1a87b20d6dc5229210", 497152, "bklynlgo.bmp", "1dfb703349a46f8ec183de107992b7f5", 33118), Common::ES_ESP, Common::kPlatformWindows, - ADGF_DEMO | ADGF_UNSUPPORTED, + ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NOMIDI) }, { "private-eye", // EU release (FR) - "It uses different file format for the assest", + "Demo", AD_ENTRY2s("pvteye.ex_", "ae0dec43b2f54d45c8a1c93e97092141", 600576, "bklynlgo.bmp", "1dfb703349a46f8ec183de107992b7f5", 33118), Common::FR_FRA, Common::kPlatformWindows, - ADGF_UNSUPPORTED, + ADGF_UNSTABLE, GUIO1(GUIO_NOMIDI) }, { @@ -139,13 +139,13 @@ static const ADGameDescription gameDescriptions[] = { GUIO1(GUIO_NOMIDI) }, { - "private-eye", // Demo from the EU release + "private-eye", // Demo from the EU release (UK) "Demo", AD_ENTRY2s("Private Eye Demo", "", 284129, "bklynlgo.bmp", "1dfb703349a46f8ec183de107992b7f5", 33118), Common::EN_GRB, Common::kPlatformWindows, - ADGF_DEMO | ADGF_UNSUPPORTED, + ADGF_DEMO | ADGF_UNSTABLE, GUIO1(GUIO_NOMIDI) }, /* diff --git a/engines/private/module.mk b/engines/private/module.mk index 43e438a43db..245d7479612 100644 --- a/engines/private/module.mk +++ b/engines/private/module.mk @@ -3,6 +3,7 @@ MODULE := engines/private MODULE_OBJS := \ code.o \ cursors.o \ + decompiler.o \ funcs.o \ grammar.o \ lexer.o \ diff --git a/engines/private/private.cpp b/engines/private/private.cpp index 422433aacc5..1e44248b9a4 100644 --- a/engines/private/private.cpp +++ b/engines/private/private.cpp @@ -39,6 +39,7 @@ #include "private/private.h" #include "private/tokens.h" #include "private/grammar.h" +#include "private/decompiler.h" namespace Private { @@ -122,40 +123,50 @@ void PrivateEngine::initializePath(const Common::FSNode &gamePath) { Common::Error PrivateEngine::run() { - assert(_installerArchive.open("SUPPORT/ASSETS.Z")); + Common::File *test = new Common::File(); Common::SeekableReadStream *file = NULL; - // if the full game is used - if (!isDemo()) { - assert(_installerArchive.hasFile("GAME.DAT")); - file = _installerArchive.createReadStreamForMember("GAME.DAT"); - } else { - // if the demo from archive.org is used - if (_installerArchive.hasFile("GAME.TXT")) - file = _installerArchive.createReadStreamForMember("GAME.TXT"); - // if the demo from the full retail CDROM is used - else if (_installerArchive.hasFile("DEMOGAME.DAT")) - file = _installerArchive.createReadStreamForMember("DEMOGAME.DAT"); - else { - Common::File *f = new Common::File(); - f->open("SUPPORT/GAME.DUMP"); - file = f; + if (isDemo() && test->open("SUPPORT/ASSETS/DEMOGAME.WIN")) { + file = (Common::SeekableReadStream *) test; + } else { + + assert(_installerArchive.open("SUPPORT/ASSETS.Z")); + // if the full game is used + if (!isDemo()) { + assert(_installerArchive.hasFile("GAME.DAT")); + file = _installerArchive.createReadStreamForMember("GAME.DAT"); + } else { + // if the demo from archive.org is used + if (_installerArchive.hasFile("GAME.TXT")) + file = _installerArchive.createReadStreamForMember("GAME.TXT"); + + // if the demo from the full retail CDROM is used + else if (_installerArchive.hasFile("DEMOGAME.DAT")) + file = _installerArchive.createReadStreamForMember("DEMOGAME.DAT"); + else { + debug("unknown version"); + } } } // Read assets file assert(file != NULL); - const int32 fileSize = file->size(); + const uint32 fileSize = file->size(); char *buf = (char *)malloc(fileSize + 1); file->read(buf, fileSize); buf[fileSize] = '\0'; + Decompiler decomp(buf, fileSize, false); + free(buf); + + buf = (char*) decomp.getResult().c_str(); + debug("%s", buf); + // Initialize stuff Gen::g_vm = new Gen::VM(); Settings::g_setts = new Settings::SettingMaps(); initFuncs(); parse(buf); - free(buf); delete file; assert(maps.constants.size() > 0); diff --git a/engines/private/symbol.cpp b/engines/private/symbol.cpp index 26f5bb0e1c1..fcf29409d14 100644 --- a/engines/private/symbol.cpp +++ b/engines/private/symbol.cpp @@ -118,6 +118,14 @@ Symbol *SymbolMaps::lookupRect(Common::String *n) { return lookup(*n, rects); } +Symbol *SymbolMaps::lookupVariable(Common::String *n) { + debug("looking variable up %s", n->c_str()); + + assert(variables.contains(*n)); + return lookup(*n, variables); +} + + /* lookup some name in some symbol table */ Symbol *SymbolMaps::lookupName(const char *n) { debug("looking up %s", n); diff --git a/engines/private/symbol.h b/engines/private/symbol.h index 3e1d98abb2f..1a6ed304f48 100644 --- a/engines/private/symbol.h +++ b/engines/private/symbol.h @@ -71,6 +71,7 @@ public: NameList locationList; Symbol *constant(int t, int d, const char *s); + Symbol *lookupVariable(Common::String *n); Symbol *lookupRect(Common::String *n); Symbol *lookupName(const char *n); void installAll(const char *n);