MACVENTURE: Complete text decoding
This commit is contained in:
parent
499ebc0b54
commit
8dd52b6cce
10 changed files with 167 additions and 74 deletions
|
@ -174,6 +174,7 @@ void Gui::setWindowTitle(WindowReference winID, Common::String string) {
|
||||||
void Gui::updateWindowInfo(WindowReference ref, ObjID objID, const Common::Array<ObjID> &children) {
|
void Gui::updateWindowInfo(WindowReference ref, ObjID objID, const Common::Array<ObjID> &children) {
|
||||||
WindowData &data = findWindowData(ref);
|
WindowData &data = findWindowData(ref);
|
||||||
data.children.clear();
|
data.children.clear();
|
||||||
|
data.objRef = objID;
|
||||||
uint32 originx = 0x7fff;
|
uint32 originx = 0x7fff;
|
||||||
uint32 originy = 0x7fff;
|
uint32 originy = 0x7fff;
|
||||||
for (uint i = 0; i < children.size(); i++) {
|
for (uint i = 0; i < children.size(); i++) {
|
||||||
|
@ -224,6 +225,8 @@ void Gui::initGUI() {
|
||||||
|
|
||||||
initWindows();
|
initWindows();
|
||||||
|
|
||||||
|
assignObjReferences();
|
||||||
|
|
||||||
if (!loadControls())
|
if (!loadControls())
|
||||||
error("Could not load controls");
|
error("Could not load controls");
|
||||||
|
|
||||||
|
@ -238,51 +241,55 @@ void Gui::initWindows() {
|
||||||
_controlsWindow->setDimensions(getWindowData(kCommandsWindow).bounds);
|
_controlsWindow->setDimensions(getWindowData(kCommandsWindow).bounds);
|
||||||
_controlsWindow->setActive(false);
|
_controlsWindow->setActive(false);
|
||||||
_controlsWindow->setCallback(commandsWindowCallback, this);
|
_controlsWindow->setCallback(commandsWindowCallback, this);
|
||||||
loadBorder(_controlsWindow, "border_command.bmp", false);
|
//loadBorder(_controlsWindow, "border_command.bmp", false);
|
||||||
loadBorder(_controlsWindow, "border_command.bmp", true);
|
//loadBorder(_controlsWindow, "border_command.bmp", true);
|
||||||
|
|
||||||
// Main Game Window
|
// Main Game Window
|
||||||
_mainGameWindow = _wm.addWindow(false, false, false);
|
_mainGameWindow = _wm.addWindow(false, false, false);
|
||||||
_mainGameWindow->setDimensions(getWindowData(kMainGameWindow).bounds);
|
_mainGameWindow->setDimensions(getWindowData(kMainGameWindow).bounds);
|
||||||
_mainGameWindow->setActive(false);
|
_mainGameWindow->setActive(false);
|
||||||
_mainGameWindow->setCallback(mainGameWindowCallback, this);
|
_mainGameWindow->setCallback(mainGameWindowCallback, this);
|
||||||
loadBorder(_mainGameWindow, "border_no_scroll_inac.bmp", false);
|
//loadBorder(_mainGameWindow, "border_no_scroll_inac.bmp", false);
|
||||||
loadBorder(_mainGameWindow, "border_no_scroll_act.bmp", true);
|
//loadBorder(_mainGameWindow, "border_no_scroll_act.bmp", true);
|
||||||
findWindowData(kMainGameWindow).objRef = 3;
|
|
||||||
|
|
||||||
// In-game Output Console
|
// In-game Output Console
|
||||||
_outConsoleWindow = _wm.addWindow(false, true, true);
|
_outConsoleWindow = _wm.addWindow(false, true, true);
|
||||||
_outConsoleWindow->setDimensions(Common::Rect(20, 20, 120, 120));
|
_outConsoleWindow->setDimensions(Common::Rect(20, 20, 120, 120));
|
||||||
_outConsoleWindow->setActive(false);
|
_outConsoleWindow->setActive(false);
|
||||||
_outConsoleWindow->setCallback(outConsoleWindowCallback, this);
|
_outConsoleWindow->setCallback(outConsoleWindowCallback, this);
|
||||||
loadBorder(_outConsoleWindow, "border_left_scroll_inac.bmp", false);
|
//loadBorder(_outConsoleWindow, "border_left_scroll_inac.bmp", false);
|
||||||
loadBorder(_outConsoleWindow, "border_left_scroll_inac.bmp", true);
|
//loadBorder(_outConsoleWindow, "border_left_scroll_inac.bmp", true);
|
||||||
|
|
||||||
// Self Window
|
// Self Window
|
||||||
_selfWindow = _wm.addWindow(false, true, true);
|
_selfWindow = _wm.addWindow(false, true, true);
|
||||||
_selfWindow->setDimensions(getWindowData(kSelfWindow).bounds);
|
_selfWindow->setDimensions(getWindowData(kSelfWindow).bounds);
|
||||||
_selfWindow->setActive(false);
|
_selfWindow->setActive(false);
|
||||||
_selfWindow->setCallback(selfWindowCallback, this);
|
_selfWindow->setCallback(selfWindowCallback, this);
|
||||||
loadBorder(_selfWindow, "border_no_scroll_inac.bmp", false);
|
//loadBorder(_selfWindow, "border_no_scroll_inac.bmp", false);
|
||||||
loadBorder(_selfWindow, "border_no_scroll_inac.bmp", true);
|
//loadBorder(_selfWindow, "border_no_scroll_inac.bmp", true);
|
||||||
findWindowData(kMainGameWindow).objRef = 0;
|
|
||||||
|
|
||||||
// Exits Window
|
// Exits Window
|
||||||
_exitsWindow = _wm.addWindow(false, true, true);
|
_exitsWindow = _wm.addWindow(false, true, true);
|
||||||
_exitsWindow->setDimensions(getWindowData(kExitsWindow).bounds);
|
_exitsWindow->setDimensions(getWindowData(kExitsWindow).bounds);
|
||||||
_exitsWindow->setActive(false);
|
_exitsWindow->setActive(false);
|
||||||
_exitsWindow->setCallback(exitsWindowCallback, this);
|
_exitsWindow->setCallback(exitsWindowCallback, this);
|
||||||
loadBorder(_exitsWindow, "border_no_scroll_inac.bmp", false);
|
//loadBorder(_exitsWindow, "border_no_scroll_inac.bmp", false);
|
||||||
loadBorder(_exitsWindow, "border_no_scroll_act.bmp", true);
|
//loadBorder(_exitsWindow, "border_no_scroll_act.bmp", true);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gui::assignObjReferences() {
|
||||||
|
|
||||||
|
findWindowData(kSelfWindow).objRef = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
WindowReference Gui::createInventoryWindow(ObjID objRef) {
|
WindowReference Gui::createInventoryWindow(ObjID objRef) {
|
||||||
Graphics::MacWindow *newWindow = _wm.addWindow(true, true, true);
|
Graphics::MacWindow *newWindow = _wm.addWindow(true, true, true);
|
||||||
WindowData newData;
|
WindowData newData;
|
||||||
GlobalSettings settings = _engine->getGlobalSettings();
|
GlobalSettings settings = _engine->getGlobalSettings();
|
||||||
newData.refcon = (WindowReference)ABS(_inventoryWindows.size()); // This is a hack
|
newData.refcon = (WindowReference)ABS(_inventoryWindows.size()); // This is a HACK
|
||||||
|
|
||||||
if (_windowData->back().refcon < 0x80) { // There is already another inventory window
|
if (_windowData->back().refcon < 0x80) { // There is already another inventory window
|
||||||
newData.bounds = _windowData->back().bounds; // Inventory windows are always last
|
newData.bounds = _windowData->back().bounds; // Inventory windows are always last
|
||||||
|
@ -303,8 +310,8 @@ WindowReference Gui::createInventoryWindow(ObjID objRef) {
|
||||||
|
|
||||||
newWindow->setDimensions(newData.bounds);
|
newWindow->setDimensions(newData.bounds);
|
||||||
newWindow->setCallback(inventoryWindowCallback, this);
|
newWindow->setCallback(inventoryWindowCallback, this);
|
||||||
loadBorder(newWindow, "border_no_scroll_inac.bmp", false);
|
//loadBorder(newWindow, "border_no_scroll_inac.bmp", false);
|
||||||
loadBorder(newWindow, "border_no_scroll_act.bmp", true);
|
//loadBorder(newWindow, "border_no_scroll_act.bmp", true);
|
||||||
_inventoryWindows.push_back(newWindow);
|
_inventoryWindows.push_back(newWindow);
|
||||||
|
|
||||||
debug("Create new inventory window. Reference: %d", newData.refcon);
|
debug("Create new inventory window. Reference: %d", newData.refcon);
|
||||||
|
@ -587,7 +594,7 @@ void Gui::drawExitsWindow() {
|
||||||
srf->w + border.rightOffset,
|
srf->w + border.rightOffset,
|
||||||
srf->h + border.bottomOffset), kColorWhite);
|
srf->h + border.bottomOffset), kColorWhite);
|
||||||
|
|
||||||
drawObjectsInWindow(kExitsWindow, _exitsWindow->getSurface());
|
drawObjectsInWindow(kMainGameWindow, _exitsWindow->getSurface());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gui::drawObjectsInWindow(WindowReference target, Graphics::ManagedSurface * surface) {
|
void Gui::drawObjectsInWindow(WindowReference target, Graphics::ManagedSurface * surface) {
|
||||||
|
@ -792,12 +799,6 @@ void Gui::updateWindow(WindowReference winID, bool containerOpen) {
|
||||||
it->unselect();
|
it->unselect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (winID == kMainGameWindow) {
|
|
||||||
drawMainGameWindow();
|
|
||||||
} else {
|
|
||||||
Graphics::MacWindow *winRef = findWindow(winID);
|
|
||||||
winRef->getSurface()->fillRect(data.bounds, kColorGray);
|
|
||||||
}
|
|
||||||
Common::Array<DrawableObject> &children = data.children;
|
Common::Array<DrawableObject> &children = data.children;
|
||||||
for (uint i = 0; i < children.size(); i++) {
|
for (uint i = 0; i < children.size(); i++) {
|
||||||
uint flag = 0;
|
uint flag = 0;
|
||||||
|
@ -812,8 +813,17 @@ void Gui::updateWindow(WindowReference winID, bool containerOpen) {
|
||||||
mode = kBlitOR;
|
mode = kBlitOR;
|
||||||
}
|
}
|
||||||
children[i] = DrawableObject(child, mode);
|
children[i] = DrawableObject(child, mode);
|
||||||
|
} else {
|
||||||
|
children[i] = DrawableObject(child, kBlitXOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (winID == kMainGameWindow) {
|
||||||
|
drawMainGameWindow();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Graphics::MacWindow *winRef = findWindow(winID);
|
||||||
|
winRef->getSurface()->fillRect(data.bounds, kColorGray);
|
||||||
|
}
|
||||||
if (data.type == kZoomDoc && data.updateScroll) {
|
if (data.type == kZoomDoc && data.updateScroll) {
|
||||||
warning("Unimplemented: update scroll");
|
warning("Unimplemented: update scroll");
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,6 +221,7 @@ private: // Methods
|
||||||
// Initializers
|
// Initializers
|
||||||
void initGUI();
|
void initGUI();
|
||||||
void initWindows();
|
void initWindows();
|
||||||
|
void assignObjReferences(); // Mainly guesswork
|
||||||
|
|
||||||
// Loaders
|
// Loaders
|
||||||
bool loadMenus();
|
bool loadMenus();
|
||||||
|
|
|
@ -37,6 +37,7 @@ enum BlitMode {
|
||||||
kBlitBIC = 1,
|
kBlitBIC = 1,
|
||||||
kBlitOR = 2,
|
kBlitOR = 2,
|
||||||
kBlitXOR = 3
|
kBlitXOR = 3
|
||||||
|
//kBlitNONE = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GraphicsEncoding {
|
enum GraphicsEncoding {
|
||||||
|
|
|
@ -59,8 +59,14 @@ MacVentureEngine::~MacVentureEngine() {
|
||||||
if (_filenames)
|
if (_filenames)
|
||||||
delete _filenames;
|
delete _filenames;
|
||||||
|
|
||||||
if (_decodingArticles)
|
if (_decodingDirectArticles)
|
||||||
delete _decodingArticles;
|
delete _decodingDirectArticles;
|
||||||
|
|
||||||
|
if (_decodingNamingArticles)
|
||||||
|
delete _decodingNamingArticles;
|
||||||
|
|
||||||
|
if (_decodingIndirectArticles)
|
||||||
|
delete _decodingIndirectArticles;
|
||||||
|
|
||||||
if (_textHuffman)
|
if (_textHuffman)
|
||||||
delete _textHuffman;
|
delete _textHuffman;
|
||||||
|
@ -88,7 +94,9 @@ Common::Error MacVentureEngine::run() {
|
||||||
_oldTextEncoding = !loadTextHuffman();
|
_oldTextEncoding = !loadTextHuffman();
|
||||||
|
|
||||||
_filenames = new StringTable(this, _resourceManager, kFilenamesStringTableID);
|
_filenames = new StringTable(this, _resourceManager, kFilenamesStringTableID);
|
||||||
_decodingArticles = new StringTable(this, _resourceManager, kCommonArticlesStringTableID);
|
_decodingDirectArticles = new StringTable(this, _resourceManager, kCommonArticlesStringTableID);
|
||||||
|
_decodingNamingArticles = new StringTable(this, _resourceManager, kNamingArticlesStringTableID);
|
||||||
|
_decodingDirectArticles = new StringTable(this, _resourceManager, kIndirectArticlesStringTableID);
|
||||||
|
|
||||||
// Big class instantiation
|
// Big class instantiation
|
||||||
_gui = new Gui(this, _resourceManager);
|
_gui = new Gui(this, _resourceManager);
|
||||||
|
@ -251,7 +259,6 @@ void MacVentureEngine::enqueueText(TextQueueID type, ObjID target, ObjID source,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacVentureEngine::printTexts() {
|
bool MacVentureEngine::printTexts() {
|
||||||
warning("printTexts: unimplemented");
|
|
||||||
for (uint i = 0; i < _textQueue.size(); i++) {
|
for (uint i = 0; i < _textQueue.size(); i++) {
|
||||||
QueuedText text = _textQueue.front();
|
QueuedText text = _textQueue.front();
|
||||||
_textQueue.remove_at(0);
|
_textQueue.remove_at(0);
|
||||||
|
@ -265,7 +272,7 @@ bool MacVentureEngine::printTexts() {
|
||||||
gameChanged();
|
gameChanged();
|
||||||
break;
|
break;
|
||||||
case kTextPlain:
|
case kTextPlain:
|
||||||
debug("Print Plain Text: %s", _world->getText(text.asset).c_str());
|
debug("Print Plain Text: %s", _world->getText(text.asset, text.source, text.destination).c_str());
|
||||||
gameChanged();
|
gameChanged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -401,11 +408,7 @@ bool MacVenture::MacVentureEngine::runScriptEngine() {
|
||||||
if (_selectedControl == 1)
|
if (_selectedControl == 1)
|
||||||
_gameChanged = false;
|
_gameChanged = false;
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
else if (_gameState == kGameStateInit || _gameState == kGameStatePlaying){
|
|
||||||
=======
|
|
||||||
else if (_gameState == kGameStateInit || _gameState == kGameStatePlaying) {
|
else if (_gameState == kGameStateInit || _gameState == kGameStatePlaying) {
|
||||||
>>>>>>> 088fc4d... MACVENTURE: Script engine fixes
|
|
||||||
if (_scriptEngine->runControl(kTick, _selectedControl, _destObject, _deltaPoint)) {
|
if (_scriptEngine->runControl(kTick, _selectedControl, _destObject, _deltaPoint)) {
|
||||||
_haltedAtEnd = true;
|
_haltedAtEnd = true;
|
||||||
return true;
|
return true;
|
||||||
|
@ -493,7 +496,6 @@ void MacVentureEngine::resetVars() {
|
||||||
void MacVentureEngine::unselectAll() {
|
void MacVentureEngine::unselectAll() {
|
||||||
while (!_currentSelection.empty()) {
|
while (!_currentSelection.empty()) {
|
||||||
unselectObject(_currentSelection.front());
|
unselectObject(_currentSelection.front());
|
||||||
//_currentSelection.remove_at(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,6 +534,22 @@ int MacVentureEngine::findObjectInArray(ObjID objID, const Common::Array<ObjID>
|
||||||
return found ? i : -1;
|
return found ? i : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint MacVentureEngine::getPrefixNdx(ObjID obj) {
|
||||||
|
return _world->getObjAttr(obj, kAttrPrefixes);
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::String MacVentureEngine::getPrefixString(uint flag, ObjID obj) {
|
||||||
|
uint ndx = _world->getObjAttr(obj, kAttrPrefixes); // HACK should check the type of that one
|
||||||
|
ndx = ((ndx) >> flag) & 3;
|
||||||
|
if (ndx) {
|
||||||
|
return (*_decodingNamingArticles->getStrings())[ndx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::String MacVentureEngine::getNoun(ObjID ndx) {
|
||||||
|
return (*_decodingIndirectArticles->getStrings())[ndx];
|
||||||
|
}
|
||||||
|
|
||||||
void MacVentureEngine::highlightExit(ObjID objID) {
|
void MacVentureEngine::highlightExit(ObjID objID) {
|
||||||
warning("highlightExit: unimplemented");
|
warning("highlightExit: unimplemented");
|
||||||
}
|
}
|
||||||
|
@ -541,7 +559,7 @@ void MacVentureEngine::selectPrimaryObject(ObjID objID) {
|
||||||
int idx;
|
int idx;
|
||||||
if (_destObject > 0 &&
|
if (_destObject > 0 &&
|
||||||
(idx = findObjectInArray(_destObject, _selectedObjs)) != -1 &&
|
(idx = findObjectInArray(_destObject, _selectedObjs)) != -1 &&
|
||||||
findObjectInArray(_destObject, _currentSelection) == -1)
|
findObjectInArray(_destObject, _currentSelection) == -1)
|
||||||
{
|
{
|
||||||
_selectedObjs.remove_at(idx);
|
_selectedObjs.remove_at(idx);
|
||||||
highlightExit(_destObject);
|
highlightExit(_destObject);
|
||||||
|
@ -570,13 +588,13 @@ void MacVentureEngine::openObject(ObjID objID) {
|
||||||
_gui->updateWindowInfo(kMainGameWindow, objID, _world->getChildren(objID, true));
|
_gui->updateWindowInfo(kMainGameWindow, objID, _world->getChildren(objID, true));
|
||||||
_gui->updateWindow(kMainGameWindow, _world->getObjAttr(objID, kAttrContainerOpen));
|
_gui->updateWindow(kMainGameWindow, _world->getObjAttr(objID, kAttrContainerOpen));
|
||||||
//_gui->drawExits();
|
//_gui->drawExits();
|
||||||
_gui->setWindowTitle(kMainGameWindow, _world->getText(objID));
|
_gui->setWindowTitle(kMainGameWindow, _world->getText(objID, objID, objID)); // it ignores source and target in the original
|
||||||
} else { // Open inventory window
|
} else { // Open inventory window
|
||||||
Common::Point p(_world->getObjAttr(objID, kAttrPosX), _world->getObjAttr(objID, kAttrPosY));
|
Common::Point p(_world->getObjAttr(objID, kAttrPosX), _world->getObjAttr(objID, kAttrPosY));
|
||||||
//getParentWin(obj).localToGlobal(p);
|
//getParentWin(obj).localToGlobal(p);
|
||||||
//globalToDesktop(p);
|
//globalToDesktop(p);
|
||||||
WindowReference invID = _gui->createInventoryWindow(objID);
|
WindowReference invID = _gui->createInventoryWindow(objID);
|
||||||
_gui->setWindowTitle(invID, _world->getText(objID));
|
_gui->setWindowTitle(invID, _world->getText(objID, objID, objID));
|
||||||
_gui->updateWindowInfo(invID, objID, _world->getChildren(objID, true));
|
_gui->updateWindowInfo(invID, objID, _world->getChildren(objID, true));
|
||||||
_gui->updateWindow(invID, _world->getObjAttr(objID, kAttrContainerOpen));
|
_gui->updateWindow(invID, _world->getObjAttr(objID, kAttrContainerOpen));
|
||||||
}
|
}
|
||||||
|
@ -664,7 +682,7 @@ void MacVentureEngine::reflectSwap(ObjID fromID, ObjID toID) {
|
||||||
tmp = from;
|
tmp = from;
|
||||||
}
|
}
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
Common::String newTitle = _world->getText(toID);
|
Common::String newTitle = _world->getText(toID, 0, 0); // Ignores src and targ in the original
|
||||||
_gui->setWindowTitle(tmp, newTitle);
|
_gui->setWindowTitle(tmp, newTitle);
|
||||||
_gui->updateWindowInfo(tmp, toID, _world->getChildren(toID, true));
|
_gui->updateWindowInfo(tmp, toID, _world->getChildren(toID, true));
|
||||||
updateWindow(tmp);
|
updateWindow(tmp);
|
||||||
|
@ -677,7 +695,7 @@ void MacVentureEngine::toggleExits() {
|
||||||
_selectedObjs.remove_at(0);
|
_selectedObjs.remove_at(0);
|
||||||
highlightExit(obj);
|
highlightExit(obj);
|
||||||
updateWindow(findParentWindow(obj));
|
updateWindow(findParentWindow(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacVentureEngine::zoomObject(ObjID objID) {
|
void MacVentureEngine::zoomObject(ObjID objID) {
|
||||||
|
@ -775,13 +793,13 @@ Common::Rect MacVentureEngine::getObjBounds(ObjID objID) {
|
||||||
uint MacVentureEngine::getOverlapPercent(ObjID one, ObjID other) {
|
uint MacVentureEngine::getOverlapPercent(ObjID one, ObjID other) {
|
||||||
//not the same parent? 0 overlap
|
//not the same parent? 0 overlap
|
||||||
if (_world->getObjAttr(one, kAttrParentObject) !=
|
if (_world->getObjAttr(one, kAttrParentObject) !=
|
||||||
_world->getObjAttr(other, kAttrParentObject))
|
_world->getObjAttr(other, kAttrParentObject))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Common::Rect oneBounds = getObjBounds(one);
|
Common::Rect oneBounds = getObjBounds(one);
|
||||||
Common::Rect otherBounds = getObjBounds(other);
|
Common::Rect otherBounds = getObjBounds(other);
|
||||||
if (otherBounds.intersects(oneBounds) ||
|
if (otherBounds.intersects(oneBounds) ||
|
||||||
oneBounds.intersects(otherBounds))
|
oneBounds.intersects(otherBounds))
|
||||||
{
|
{
|
||||||
uint areaOne = oneBounds.width() * oneBounds.height();
|
uint areaOne = oneBounds.width() * oneBounds.height();
|
||||||
uint areaOther = otherBounds.width() * otherBounds.height();
|
uint areaOther = otherBounds.width() * otherBounds.height();
|
||||||
|
@ -805,7 +823,7 @@ WindowReference MacVentureEngine::findObjWindow(ObjID objID) {
|
||||||
// This is a bit of a hack, we take advantage of the consecutive nature of references
|
// This is a bit of a hack, we take advantage of the consecutive nature of references
|
||||||
for (uint i = kCommandsWindow; i <= kDiplomaWindow; i++) {
|
for (uint i = kCommandsWindow; i <= kDiplomaWindow; i++) {
|
||||||
const WindowData &data = _gui->getWindowData((WindowReference)i);
|
const WindowData &data = _gui->getWindowData((WindowReference)i);
|
||||||
if (data.refcon == objID) { return data.refcon; }
|
if (data.objRef == objID) { return data.refcon; }
|
||||||
}
|
}
|
||||||
return kNoWindow;
|
return kNoWindow;
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,6 +194,10 @@ public:
|
||||||
const HuffmanLists *getDecodingHuffman() const;
|
const HuffmanLists *getDecodingHuffman() const;
|
||||||
uint32 randBetween(uint32 min, uint32 max);
|
uint32 randBetween(uint32 min, uint32 max);
|
||||||
uint32 getInvolvedObjects();
|
uint32 getInvolvedObjects();
|
||||||
|
int findObjectInArray(ObjID objID, const Common::Array<ObjID> &list);
|
||||||
|
uint getPrefixNdx(ObjID obj);
|
||||||
|
Common::String getPrefixString(uint flag, ObjID obj);
|
||||||
|
Common::String getNoun(ObjID ndx);
|
||||||
|
|
||||||
// Attributes consult
|
// Attributes consult
|
||||||
Common::Point getObjPosition(ObjID objID);
|
Common::Point getObjPosition(ObjID objID);
|
||||||
|
@ -224,7 +228,6 @@ private:
|
||||||
void unselectAll();
|
void unselectAll();
|
||||||
void selectObject(ObjID objID);
|
void selectObject(ObjID objID);
|
||||||
void unselectObject(ObjID objID);
|
void unselectObject(ObjID objID);
|
||||||
int findObjectInArray(ObjID objID, const Common::Array<ObjID> &list);
|
|
||||||
void highlightExit(ObjID objID);
|
void highlightExit(ObjID objID);
|
||||||
void selectPrimaryObject(ObjID objID);
|
void selectPrimaryObject(ObjID objID);
|
||||||
|
|
||||||
|
@ -261,7 +264,9 @@ private: // Attributes
|
||||||
|
|
||||||
// String tables
|
// String tables
|
||||||
StringTable *_filenames;
|
StringTable *_filenames;
|
||||||
StringTable *_decodingArticles;
|
StringTable *_decodingDirectArticles;
|
||||||
|
StringTable *_decodingNamingArticles;
|
||||||
|
StringTable *_decodingIndirectArticles;
|
||||||
|
|
||||||
// Engine state
|
// Engine state
|
||||||
GameState _gameState;
|
GameState _gameState;
|
||||||
|
|
|
@ -794,21 +794,21 @@ void ScriptEngine::opacEQ(EngineState * state, EngineFrame * frame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::opadEQS(EngineState * state, EngineFrame * frame) {
|
void ScriptEngine::opadEQS(EngineState * state, EngineFrame * frame) {
|
||||||
Common::String b = _world->getText(state->pop());
|
Common::String b = _world->getText(state->pop(), 0, 0); // HACK, these destinations might be wrong
|
||||||
Common::String a = _world->getText(state->pop());
|
Common::String a = _world->getText(state->pop(), 0, 0);
|
||||||
state->push((a == b) ? 1 : 0);
|
state->push((a == b) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::opaeCONT(EngineState * state, EngineFrame * frame) {
|
void ScriptEngine::opaeCONT(EngineState * state, EngineFrame * frame) {
|
||||||
Common::String needle = _world->getText(state->pop());
|
Common::String needle = _world->getText(state->pop(), 0, 0);
|
||||||
Common::String haystack = _world->getText(state->pop());
|
Common::String haystack = _world->getText(state->pop(), 0, 0);
|
||||||
haystack.toLowercase();
|
haystack.toLowercase();
|
||||||
state->push(haystack.contains(needle) ? 1 : 0);
|
state->push(haystack.contains(needle) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::opafCONTW(EngineState * state, EngineFrame * frame) {
|
void ScriptEngine::opafCONTW(EngineState * state, EngineFrame * frame) {
|
||||||
Common::String needle = _world->getText(state->pop());
|
Common::String needle = _world->getText(state->pop(), 0, 0);
|
||||||
Common::String haystack = _world->getText(state->pop());
|
Common::String haystack = _world->getText(state->pop(), 0, 0);
|
||||||
haystack.toLowercase();
|
haystack.toLowercase();
|
||||||
state->push(haystack.contains(needle) ? 1 : 0);
|
state->push(haystack.contains(needle) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,14 @@
|
||||||
#include "macventure/text.h"
|
#include "macventure/text.h"
|
||||||
|
|
||||||
namespace MacVenture {
|
namespace MacVenture {
|
||||||
TextAsset::TextAsset(ObjID objid, Container *container, bool isOld, const HuffmanLists *huffman) {
|
TextAsset::TextAsset(MacVentureEngine *engine, ObjID objid, ObjID source, ObjID target, Container *container, bool isOld, const HuffmanLists *huffman) {
|
||||||
_id = objid;
|
_id = objid;
|
||||||
|
_sourceObj = source;
|
||||||
|
_targetObj = target;
|
||||||
_container = container;
|
_container = container;
|
||||||
_huffman = huffman;
|
_huffman = huffman;
|
||||||
_isOld = isOld;
|
_isOld = isOld;
|
||||||
|
_engine = engine;
|
||||||
|
|
||||||
if (_isOld) {
|
if (_isOld) {
|
||||||
decodeOld();
|
decodeOld();
|
||||||
|
@ -77,8 +80,20 @@ void TextAsset::decodeOld() {
|
||||||
lowercase = true;
|
lowercase = true;
|
||||||
}
|
}
|
||||||
else if (val == 0x1D) { // Composite
|
else if (val == 0x1D) { // Composite
|
||||||
warning("Composite strings not implemented");
|
ObjID subval = stream.getBits(16);
|
||||||
stream.getBits(16);
|
Common::String child;
|
||||||
|
if (subval & 0x8000) {
|
||||||
|
// Composite object id
|
||||||
|
subval ^= 0xFFFF;
|
||||||
|
child = getNoun(subval);
|
||||||
|
} else {
|
||||||
|
// Just another id
|
||||||
|
// HACK, see below in getNoun()
|
||||||
|
child = *TextAsset(_engine, subval, _sourceObj, _targetObj, _container, _isOld, _huffman).decode();
|
||||||
|
}
|
||||||
|
if (child.size() > 0) {
|
||||||
|
c = '?'; // HACK Will fix later, should append
|
||||||
|
}
|
||||||
lowercase = true;
|
lowercase = true;
|
||||||
}
|
}
|
||||||
else if (val == 0x1E) {
|
else if (val == 0x1E) {
|
||||||
|
@ -102,7 +117,7 @@ void TextAsset::decodeOld() {
|
||||||
void TextAsset::decodeHuffman() {
|
void TextAsset::decodeHuffman() {
|
||||||
_decoded = Common::String("");
|
_decoded = Common::String("");
|
||||||
Common::SeekableReadStream *res = _container->getItem(_id);
|
Common::SeekableReadStream *res = _container->getItem(_id);
|
||||||
Common::BitStream32BEMSB stream(res);
|
Common::BitStream8MSB stream(res);
|
||||||
uint16 strLen = 0;
|
uint16 strLen = 0;
|
||||||
if (stream.getBit()) {
|
if (stream.getBit()) {
|
||||||
strLen = stream.getBits(15);
|
strLen = stream.getBits(15);
|
||||||
|
@ -110,12 +125,13 @@ void TextAsset::decodeHuffman() {
|
||||||
else {
|
else {
|
||||||
strLen = stream.getBits(7);
|
strLen = stream.getBits(7);
|
||||||
}
|
}
|
||||||
|
// OK up to here
|
||||||
uint32 mask = 0;
|
uint32 mask = 0;
|
||||||
uint32 symbol = 0;
|
uint32 symbol = 0;
|
||||||
char c;
|
char c;
|
||||||
for (uint16 i = 0; i < strLen; i++) {
|
for (uint16 i = 0; i < strLen; i++) {
|
||||||
mask = stream.peekBits(16); // The mask is OK, so it means that I don't know how to use the huffman
|
mask = stream.peekBits(16); // The mask is OK
|
||||||
|
|
||||||
uint32 entry;
|
uint32 entry;
|
||||||
// Find the length index
|
// Find the length index
|
||||||
for (entry = 0; entry < _huffman->getNumEntries(); entry++) {
|
for (entry = 0; entry < _huffman->getNumEntries(); entry++) {
|
||||||
|
@ -128,24 +144,63 @@ void TextAsset::decodeHuffman() {
|
||||||
|
|
||||||
if (symbol == 1) { // 7-bit ascii
|
if (symbol == 1) { // 7-bit ascii
|
||||||
c = stream.getBits(7);
|
c = stream.getBits(7);
|
||||||
}
|
_decoded += c;
|
||||||
else if (symbol == 2) { // Composite
|
} else if (symbol == 2) { // Composite
|
||||||
warning("Composite huffman strings not tested");
|
|
||||||
if (stream.getBit()) { // TextID
|
if (stream.getBit()) { // TextID
|
||||||
ObjID embedId = stream.getBits(15);
|
ObjID embedId = stream.getBits(15);
|
||||||
TextAsset embedded(embedId, _container, _isOld, _huffman);
|
uint pos = stream.pos(); // HACK, part 1
|
||||||
_decoded += *embedded.decode();
|
TextAsset embedded(_engine, embedId, _sourceObj, _targetObj, _container, _isOld, _huffman);
|
||||||
} else { //Composite obj string
|
stream.rewind();// HACK, part 2
|
||||||
_decoded += Common::String("Unimplemented");
|
stream.skip(pos);
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // Plain ascii
|
|
||||||
c = symbol & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
_decoded += c;
|
_decoded.replace(_decoded.end(), _decoded.end(), *embedded.decode());
|
||||||
|
|
||||||
|
// Another HACK, to get around that EOS char I insert at the end
|
||||||
|
_decoded.replace(_decoded.end() - 1, _decoded.end(), "");
|
||||||
|
} else { //Composite obj string
|
||||||
|
ObjID embedId = stream.getBits(8);
|
||||||
|
_decoded.replace(_decoded.end(), _decoded.end(), getNoun(embedId));
|
||||||
|
// Another HACK, to get around that EOS char I insert at the end
|
||||||
|
_decoded.replace(_decoded.end() - 1, _decoded.end(), "");
|
||||||
|
}
|
||||||
|
} else { // Plain ascii
|
||||||
|
c = symbol & 0xFF;
|
||||||
|
_decoded.replace(_decoded.end(), _decoded.end(), Common::String(c));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_decoded += '\0';
|
_decoded += '\0';
|
||||||
debug(7, "Decoded %d'th string (new): %s", _id, _decoded.c_str());
|
debug(7, "Decoded %d'th string (new): %s", _id, _decoded.c_str());
|
||||||
}
|
}
|
||||||
|
Common::String TextAsset::getNoun(ObjID subval) {
|
||||||
|
ObjID obj;
|
||||||
|
Common::String name;
|
||||||
|
if (subval & 8)
|
||||||
|
obj = _targetObj;
|
||||||
|
else
|
||||||
|
obj = _sourceObj;
|
||||||
|
if ((subval & 3) == 1)
|
||||||
|
{
|
||||||
|
uint idx = _engine->getPrefixNdx(obj);
|
||||||
|
idx = ((idx >> 4) & 3) + 1;
|
||||||
|
name = _engine->getNoun(idx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// HACK, there should be a pool of assets or something like in the GUI
|
||||||
|
name = *TextAsset(_engine, obj, _sourceObj, _targetObj, _container, _isOld, _huffman).decode();
|
||||||
|
switch (subval & 3)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
name = _engine->getPrefixString(0, obj) + name;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
name = _engine->getPrefixString(2, obj) + name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name.size() && (subval & 4))
|
||||||
|
name.toUppercase(); // HACK, should only capitalize first char?
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace MacVenture
|
} // End of namespace MacVenture
|
|
@ -31,7 +31,7 @@ typedef uint32 ObjID;
|
||||||
|
|
||||||
class TextAsset {
|
class TextAsset {
|
||||||
public:
|
public:
|
||||||
TextAsset(ObjID objid, Container *container, bool isOld, const HuffmanLists *huffman);
|
TextAsset(MacVentureEngine *engine, ObjID objid, ObjID source, ObjID target, Container *container, bool isOld, const HuffmanLists *huffman);
|
||||||
~TextAsset() {}
|
~TextAsset() {}
|
||||||
|
|
||||||
const Common::String *decode() {
|
const Common::String *decode() {
|
||||||
|
@ -42,9 +42,15 @@ private:
|
||||||
void decodeOld();
|
void decodeOld();
|
||||||
void decodeHuffman();
|
void decodeHuffman();
|
||||||
|
|
||||||
|
Common::String getNoun(ObjID id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
MacVentureEngine *_engine;
|
||||||
|
|
||||||
Container *_container;
|
Container *_container;
|
||||||
ObjID _id;
|
ObjID _id;
|
||||||
|
ObjID _targetObj;
|
||||||
|
ObjID _sourceObj;
|
||||||
const HuffmanLists *_huffman;
|
const HuffmanLists *_huffman;
|
||||||
bool _isOld;
|
bool _isOld;
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,6 @@ World::World(MacVentureEngine *engine, Common::MacResManager *resMan) {
|
||||||
|
|
||||||
warning("Test functions about to happen");
|
warning("Test functions about to happen");
|
||||||
_gameText = new Container("Shadowgate II/Shadow Text");
|
_gameText = new Container("Shadowgate II/Shadow Text");
|
||||||
|
|
||||||
ObjID tid = (ObjID)1;
|
|
||||||
TextAsset test = TextAsset(tid, _gameText, _engine->isOldText(), _engine->getDecodingHuffman());
|
|
||||||
|
|
||||||
delete saveGameRes;
|
delete saveGameRes;
|
||||||
saveGameFile.close();
|
saveGameFile.close();
|
||||||
|
@ -153,8 +150,8 @@ void World::captureChildren(ObjID objID) {
|
||||||
void World::releaseChildren(ObjID objID) {
|
void World::releaseChildren(ObjID objID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::String World::getText(ObjID objID) {
|
Common::String World::getText(ObjID objID, ObjID source, ObjID target) {
|
||||||
TextAsset text = TextAsset(objID, _gameText, _engine->isOldText(), _engine->getDecodingHuffman());
|
TextAsset text = TextAsset(_engine, objID, source, target, _gameText, _engine->isOldText(), _engine->getDecodingHuffman());
|
||||||
|
|
||||||
return *text.decode();
|
return *text.decode();
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ public:
|
||||||
|
|
||||||
uint32 getObjAttr(ObjID objID, uint32 attrID);
|
uint32 getObjAttr(ObjID objID, uint32 attrID);
|
||||||
Attribute getGlobal(uint32 attrID);
|
Attribute getGlobal(uint32 attrID);
|
||||||
Common::String getText(ObjID objID);
|
Common::String getText(ObjID objID, ObjID source, ObjID target);
|
||||||
|
|
||||||
bool isObjActive(ObjID objID);
|
bool isObjActive(ObjID objID);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue