aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorBorja Lorente2016-06-23 23:21:24 +0200
committerBorja Lorente2016-08-14 18:37:46 +0200
commitba5ed7fc88a69da782f3df18698837a67a59eb6b (patch)
tree998728703466844f22fa1ac109efa6315c1572ac /engines
parentec7eb7cb5bec5174f7fd3446824280ab44050f5e (diff)
downloadscummvm-rg350-ba5ed7fc88a69da782f3df18698837a67a59eb6b.tar.gz
scummvm-rg350-ba5ed7fc88a69da782f3df18698837a67a59eb6b.tar.bz2
scummvm-rg350-ba5ed7fc88a69da782f3df18698837a67a59eb6b.zip
MACVENTURE: Major push in functionality and rendering
Diffstat (limited to 'engines')
-rw-r--r--engines/macventure/gui.cpp401
-rw-r--r--engines/macventure/gui.h30
-rw-r--r--engines/macventure/image.cpp84
-rw-r--r--engines/macventure/image.h2
-rw-r--r--engines/macventure/macventure.cpp132
-rw-r--r--engines/macventure/macventure.h9
-rw-r--r--engines/macventure/script.cpp55
7 files changed, 478 insertions, 235 deletions
diff --git a/engines/macventure/gui.cpp b/engines/macventure/gui.cpp
index f1eb8b63e6..d4fd337557 100644
--- a/engines/macventure/gui.cpp
+++ b/engines/macventure/gui.cpp
@@ -106,6 +106,8 @@ void Gui::draw() {
drawWindows();
_wm.draw();
+
+ //drawWindowTitle(kMainGameWindow, _mainGameWindow->getSurface());
}
void Gui::drawMenu() {
@@ -117,7 +119,17 @@ void Gui::drawTitle() {
}
void Gui::drawExit(ObjID id) {
- warning("Unimplemented method: drawExit");
+ findWindowData(kExitsWindow).children.push_back(DrawableObject(id, kBlitDirect));
+}
+
+void Gui::clearControls() {
+ if (!_controlData)
+ return;
+
+ Common::List<CommandButton>::iterator it = _controlData->begin();
+ for (; it != _controlData->end(); ++it) {
+ it->unselect();
+ }
}
const WindowData& Gui::getWindowData(WindowReference reference) {
@@ -234,44 +246,65 @@ void Gui::initWindows() {
_mainGameWindow->setDimensions(getWindowData(kMainGameWindow).bounds);
_mainGameWindow->setActive(false);
_mainGameWindow->setCallback(mainGameWindowCallback, this);
- loadBorder(_mainGameWindow, "border_command.bmp", false);
- loadBorder(_mainGameWindow, "border_command.bmp", true);
+ loadBorder(_mainGameWindow, "border_no_scroll_inac.bmp", false);
+ loadBorder(_mainGameWindow, "border_no_scroll_act.bmp", true);
// In-game Output Console
_outConsoleWindow = _wm.addWindow(false, true, true);
_outConsoleWindow->setDimensions(Common::Rect(20, 20, 120, 120));
_outConsoleWindow->setActive(false);
_outConsoleWindow->setCallback(outConsoleWindowCallback, this);
- loadBorder(_outConsoleWindow, "border_command.bmp", false);
+ loadBorder(_outConsoleWindow, "border_left_scroll_inac.bmp", false);
+ loadBorder(_outConsoleWindow, "border_left_scroll_inac.bmp", true);
// Self Window
_selfWindow = _wm.addWindow(false, true, true);
_selfWindow->setDimensions(getWindowData(kSelfWindow).bounds);
_selfWindow->setActive(false);
_selfWindow->setCallback(selfWindowCallback, this);
- loadBorder(_selfWindow, "border_self_inac.bmp", false);
- loadBorder(_selfWindow, "border_self_act.bmp", true);
- findWindowData(kSelfWindow).children.push_back(DrawableObject(1, kBlitDirect));
+ loadBorder(_selfWindow, "border_no_scroll_inac.bmp", false);
+ loadBorder(_selfWindow, "border_no_scroll_inac.bmp", true);
// Exits Window
_exitsWindow = _wm.addWindow(false, true, true);
_exitsWindow->setDimensions(getWindowData(kExitsWindow).bounds);
_exitsWindow->setActive(false);
_exitsWindow->setCallback(exitsWindowCallback, this);
- loadBorder(_exitsWindow, "border_title_inac.bmp", false);
- loadBorder(_exitsWindow, "border_title_inac.bmp", true);
+ loadBorder(_exitsWindow, "border_no_scroll_inac.bmp", false);
+ loadBorder(_exitsWindow, "border_no_scroll_act.bmp", true);
+
+}
+
+WindowReference Gui::createInventoryWindow() {
+ Graphics::MacWindow *newWindow = _wm.addWindow(true, true, true);
+ WindowData newData;
+ GlobalSettings settings = _engine->getGlobalSettings();
+ newData.refcon = (WindowReference)ABS(_inventoryWindows.size()); // This is a hack
+
+ if (_windowData->back().refcon < 0x80) { // There is already another inventory window
+ newData.bounds = _windowData->back().bounds; // Inventory windows are always last
+ newData.bounds.translate(newData.bounds.left + settings.invOffsetX, newData.bounds.top + settings.invOffsetY);
+ }
+ else {
+ newData.bounds = Common::Rect(
+ settings.invLeft,
+ settings.invTop,
+ settings.invLeft + settings.invWidth,
+ settings.invTop + settings.invHeight);
+ }
+ newData.type = kZoomDoc;
+ newData.hasCloseBox = true;
+ newData.visible = true;
+ _windowData->push_back(newData);
- // Diploma Window (we can go without it for now)
- /*
- _diplomaWindow = _wm.addWindow(false, true, true);
- _diplomaWindow->setDimensions(getWindowData(kDiplomaWindow).bounds);
- _diplomaWindow->setActive(false);
- _diplomaWindow->setCallback(diplomaWindowCallback, this);
- loadBorder(_diplomaWindow, "border_command.bmp", false);
- // Render invisible for now
- _diplomaWindow->getSurface()->fillRect(_diplomaWindow->getSurface()->getBounds(), kColorGreen2);
- */
+ newWindow->setDimensions(newData.bounds);
+ newWindow->setCallback(inventoryWindowCallback, this);
+ loadBorder(newWindow, "border_no_scroll_inac.bmp", false);
+ loadBorder(newWindow, "border_no_scroll_act.bmp", true);
+ _inventoryWindows.push_back(newWindow);
+ debug("Create new inventory window. Reference: %d", newData.refcon);
+ return newData.refcon;
}
void Gui::loadBorder(Graphics::MacWindow * target, Common::String filename, bool active) {
@@ -464,11 +497,14 @@ void Gui::drawWindows() {
drawCommandsWindow();
drawMainGameWindow();
+ drawSelfWindow();
+ drawInventories();
+ drawExitsWindow();
}
void Gui::drawCommandsWindow() {
- if (_engine->isPaused()) {
+ if (_engine->needsClickToContinue()) {
Graphics::ManagedSurface *srf = _controlsWindow->getSurface();
WindowData data = getWindowData(kCommandsWindow);
uint16 border = borderBounds(data.type).topOffset;
@@ -493,51 +529,113 @@ void Gui::drawCommandsWindow() {
void Gui::drawMainGameWindow() {
Graphics::ManagedSurface *srf = _mainGameWindow->getSurface();
- BorderBounds border = borderBounds(getWindowData(kMainGameWindow).type);
+ const WindowData &data = getWindowData(kMainGameWindow);
+ BorderBounds border = borderBounds(data.type);
_mainGameWindow->setDirty(true);
+ //if (data.titleLength > 0)
+ // drawWindowTitle(kMainGameWindow, srf);
+
if (!_assets.contains(3)) {
_assets[3] = new ImageAsset(3, _graphics);
}
_assets[3]->blitInto(
_mainGameWindow->getSurface(),
- border.leftOffset * 2,
- border.topOffset * 2,
+ border.leftOffset,
+ border.topOffset,
kBlitDirect);
drawObjectsInWindow(kMainGameWindow, _mainGameWindow->getSurface());
-
}
void Gui::drawSelfWindow() {
- Graphics::ManagedSurface *srf = _selfWindow->getSurface();
- BorderBounds border = borderBounds(getWindowData(kSelfWindow).type);
+ drawObjectsInWindow(kSelfWindow, _selfWindow->getSurface());
+ if (_engine->isObjSelected(1)) invertWindowColors(kSelfWindow);
+}
+
+void Gui::drawInventories() {
+ Common::List<WindowData>::const_iterator it = _windowData->begin();
+ while (it != _windowData->end() && (*it).refcon >= 0x80) {
+ it++;
+ }
+ Graphics::ManagedSurface *srf;
+ while (it != _windowData->end()) {
+ srf = _inventoryWindows[(*it).refcon]->getSurface();
+ BorderBounds border = borderBounds((*it).type);
+ srf->fillRect(Common::Rect(
+ border.leftOffset,
+ border.topOffset,
+ srf->w + border.rightOffset,
+ srf->h + border.bottomOffset), kColorWhite);
+ drawObjectsInWindow((*it).refcon, _inventoryWindows[(*it).refcon]->getSurface());
+ it++;
+ }
+}
+
+void Gui::drawExitsWindow() {
+ WindowData &data = findWindowData(kExitsWindow);
+ BorderBounds border = borderBounds(data.type);
+ Graphics::ManagedSurface *srf = _exitsWindow->getSurface();
+ srf->fillRect(Common::Rect(
+ border.leftOffset,
+ border.topOffset,
+ srf->w + border.rightOffset,
+ srf->h + border.bottomOffset), kColorWhite);
+
+ drawObjectsInWindow(kExitsWindow, _exitsWindow->getSurface());
}
void Gui::drawObjectsInWindow(WindowReference target, Graphics::ManagedSurface * surface) {
- WindowData &data = findWindowData(kMainGameWindow);
+ WindowData &data = findWindowData(target);
BorderBounds border = borderBounds(data.type);
Common::Point pos;
ObjID child;
BlitMode mode;
- for (Common::Array<DrawableObject>::const_iterator it = data.children.begin(); it != data.children.end(); it++) {
- child = (*it).obj;
- mode = (BlitMode)(*it).mode;
+
+ if (data.children.size() == 0) return;
+
+ Common::Point forbidden(0, 0);
+ for (uint i = 0; i < data.children.size(); i++) {
+ child = data.children[i].obj;
+ mode = (BlitMode)data.children[i].mode;
pos = _engine->getObjPosition(child);
- if (!_assets.contains(child)) {
- _assets[child] = new ImageAsset(child, _graphics);
+
+ if (pos != forbidden || child < 600) { // Small HACK until I figre out where the last garbage child in main game window comes from
+ if (!_assets.contains(child)) {
+ _assets[child] = new ImageAsset(child, _graphics);
+ }
+
+ _assets[child]->blitInto(
+ surface,
+ border.leftOffset + pos.x,
+ border.topOffset + pos.y,
+ mode);
}
- _assets[child]->blitInto(
- surface,
- border.leftOffset * 2 + pos.x,
- border.topOffset * 2 + pos.y,
- mode);
-
- // To be deleted, this is a big hack, but it doesn't work without it.
- _wm.draw();
+
}
+
+ findWindow(data.refcon)->setDirty(true);
+
+}
+
+void Gui::drawWindowTitle(WindowReference target, Graphics::ManagedSurface * surface) {
+ WindowData &data = findWindowData(target);
+ BorderBounds border = borderBounds(data.type);
+
+ uint left = 10;//getCurrentFont().getStringWidth(data.title) - 10;
+ uint right = 30;//getCurrentFont().getStringWidth(data.title) + 10;
+
+ surface->fillRect(Common::Rect(left, 0, right, border.topOffset - 1), kColorGray);
+ getCurrentFont().drawString(
+ surface,
+ data.title,
+ 0,
+ right,
+ right - left,
+ kColorBlack,
+ Graphics::kTextAlignCenter);
}
WindowData & Gui::findWindowData(WindowReference reference) {
@@ -554,56 +652,29 @@ WindowData & Gui::findWindowData(WindowReference reference) {
error("Could not locate the desired window data");
}
-
-/* CALLBACKS */
-
-bool commandsWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
- Gui *g = (Gui*)gui;
-
- return g->processCommandEvents(click, event);
-}
-
-bool mainGameWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
- Gui *g = (Gui*)gui;
-
- return g->processMainGameEvents(click, event);
-}
-
-bool outConsoleWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
- Gui *g = (Gui*)gui;
-
- return g->processOutConsoleEvents(click, event);
-}
-
-bool selfWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
- Gui *g = (Gui*)gui;
-
- return g->processSelfEvents(click, event);
-}
-
-bool exitsWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
- Gui *g = (Gui*)gui;
-
- return g->processExitsEvents(click, event);
-}
-
-bool diplomaWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
- Gui *g = (Gui*)gui;
-
- return g->processDiplomaEvents(click, event);
-}
-
-bool inventoryWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
- Gui *g = (Gui*)gui;
-
- return g->processInventoryEvents(click, event);
+Graphics::MacWindow * Gui::findWindow(WindowReference reference) {
+ if (reference < 0x80) { // It's an inventory window
+ return _inventoryWindows[reference];
+ }
+ switch (reference) {
+ case MacVenture::kNoWindow:
+ return nullptr;
+ case MacVenture::kCommandsWindow:
+ return _controlsWindow;
+ case MacVenture::kMainGameWindow:
+ return _mainGameWindow;
+ case MacVenture::kOutConsoleWindow:
+ return _outConsoleWindow;
+ case MacVenture::kSelfWindow:
+ return _selfWindow;
+ case MacVenture::kExitsWindow:
+ return _exitsWindow;
+ case MacVenture::kDiplomaWindow:
+ return _diplomaWindow;
+ }
+ return nullptr;
}
-void menuCommandsCallback(int action, Common::String &text, void *data) {
- Gui *g = (Gui *)data;
-
- g->handleMenuAction((MenuAction)action);
-}
/* HANDLERS */
void Gui::handleMenuAction(MenuAction action) {
@@ -655,15 +726,66 @@ void Gui::handleMenuAction(MenuAction action) {
}
}
+/* CALLBACKS */
+
+bool commandsWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+ return g->processCommandEvents(click, event);
+}
+
+bool mainGameWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+ return g->processMainGameEvents(click, event);
+}
+
+bool outConsoleWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+ return g->processOutConsoleEvents(click, event);
+}
+
+bool selfWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+
+ return g->processSelfEvents(click, event);
+}
+
+bool exitsWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+
+ return g->processExitsEvents(click, event);
+}
+
+bool diplomaWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+
+ return g->processDiplomaEvents(click, event);
+}
+
+bool inventoryWindowCallback(Graphics::WindowClick click, Common::Event &event, void *gui) {
+ Gui *g = (Gui*)gui;
+
+ return g->processInventoryEvents(click, event);
+}
+
+void menuCommandsCallback(int action, Common::String &text, void *data) {
+ Gui *g = (Gui *)data;
+
+ g->handleMenuAction((MenuAction)action);
+}
+
void Gui::updateWindow(WindowReference winID, bool containerOpen) {
- if (winID > 0x90 || winID == kNoWindow) return;
+ if (winID == kNoWindow) return;
if (winID == kSelfWindow || containerOpen) {
- if (winID == kMainGameWindow) {
- drawMainGameWindow();
+ WindowData &data = findWindowData(winID);
+ if (winID == kCommandsWindow) {
+ Common::List<CommandButton>::iterator it = _controlData->begin();
+ for (; it != _controlData->end(); ++it) {
+ it->unselect();
+ }
} else {
- warning("Unimplemented: fill window with background");
+ Graphics::MacWindow *winRef = findWindow(winID);
+ winRef->getSurface()->fillRect(data.bounds, kColorGray);
}
- WindowData &data = findWindowData(winID);
Common::Array<DrawableObject> &children = data.children;
for (uint i = 0; i < children.size(); i++) {
uint flag = 0;
@@ -680,41 +802,24 @@ void Gui::updateWindow(WindowReference winID, bool containerOpen) {
children[i] = DrawableObject(child, mode);
}
}
+ if (winID == kMainGameWindow) {
+ drawMainGameWindow();
+ }
if (data.type == kZoomDoc && data.updateScroll) {
warning("Unimplemented: update scroll");
}
}
}
-WindowReference Gui::createInventoryWindow() {
- Graphics::MacWindow *newWindow = _wm.addWindow(true, true, true);
- WindowData newData;
- GlobalSettings settings = _engine->getGlobalSettings();
- newData.refcon = (WindowReference)ABS(_inventoryWindows.size()); // This is a hack
-
- if (_windowData->back().refcon < 0x80) { // There is already another inventory window
- newData.bounds = _windowData->back().bounds; // Inventory windows are always last
- newData.bounds.translate(newData.bounds.left + settings.invOffsetX, newData.bounds.top + settings.invOffsetY);
- } else {
- newData.bounds = Common::Rect(
- settings.invLeft,
- settings.invTop,
- settings.invLeft + settings.invWidth,
- settings.invTop + settings.invHeight);
+void Gui::invertWindowColors(WindowReference winID) {
+ Graphics::ManagedSurface *srf = findWindow(winID)->getSurface();
+ for (uint y = 0; y < srf->h; y++) {
+ for (uint x = 0; x < srf->w; x++) {
+ byte p = *(byte *)srf->getBasePtr(x, y);
+ *(byte *)srf->getBasePtr(x, y) =
+ (p == kColorWhite) ? kColorBlack : kColorGray;
+ }
}
- newData.type = kZoomDoc;
- newData.hasCloseBox = true;
- newData.visible = true;
- _windowData->push_back(newData);
-
- newWindow->setDimensions(newData.bounds);
- newWindow->setCallback(inventoryWindowCallback, this);
- loadBorder(newWindow, "border_self_inac.bmp", false);
- loadBorder(newWindow, "border_self_act.bmp", true);
- _inventoryWindows.push_back(newWindow);
-
- debug(3, "Create new inventory window. Reference: %d", newData.refcon);
- return newData.refcon;
}
bool Gui::tryCloseWindow(WindowReference winID) {
@@ -729,30 +834,41 @@ bool Gui::tryCloseWindow(WindowReference winID) {
bool Gui::processEvent(Common::Event &event) {
bool processed = false;
- if (event.type == Common::EVENT_LBUTTONDOWN) {
- debug("Click on the ui");
+ if (event.type == Common::EVENT_LBUTTONDOWN || event.type == Common::EVENT_LBUTTONUP) {
+ _engine->updateDelta(event.mouse);
+ processed = true;
}
- return (processed || _wm.processEvent(event));
+ processed |= _wm.processEvent(event);
+ return (processed);
}
bool Gui::processCommandEvents(WindowClick click, Common::Event &event) {
if (event.type == Common::EVENT_LBUTTONUP) {
- if (_engine->isPaused())
+ if (_engine->needsClickToContinue()) {
+ _engine->activateCommand(kControlClickToContinue);
return true;
+ }
Common::Point position(
event.mouse.x - _controlsWindow->getDimensions().left,
event.mouse.y - _controlsWindow->getDimensions().top);
CommandButton data;
- Common::List<CommandButton>::const_iterator it = _controlData->begin();
+ if (!_controlData)
+ return false;
+
+ Common::List<CommandButton>::iterator it = _controlData->begin();
for (; it != _controlData->end(); ++it) {
if (it->isInsideBounds(position)) {
- debug(4, "Command active: %s", it->getData().title);
+ it->select();
data = *it;
}
+ else {
+ it->unselect();
+ }
}
+
_engine->selectControl((ControlReference)data.getData().refcon);
_engine->activateCommand((ControlReference)data.getData().refcon);
_engine->refreshReady();
@@ -762,6 +878,9 @@ bool Gui::processCommandEvents(WindowClick click, Common::Event &event) {
}
bool MacVenture::Gui::processMainGameEvents(WindowClick click, Common::Event & event) {
+ if (_engine->needsClickToContinue())
+ return true;
+
if (click == kBorderInner && event.type == Common::EVENT_LBUTTONUP) {
WindowData &data = findWindowData(kMainGameWindow);
ObjID child;
@@ -769,36 +888,52 @@ bool MacVenture::Gui::processMainGameEvents(WindowClick click, Common::Event & e
Common::Point pos;
for (Common::Array<DrawableObject>::const_iterator it = data.children.begin(); it != data.children.end(); it++) {
child = (*it).obj;
- mode = (BlitMode)(*it).mode;
pos = _engine->getObjPosition(child);
- pos.x += data.bounds.left;
- pos.y += data.bounds.top;
- if (_assets[child]->isPointInside(pos, event.mouse)) {
+ pos.x += _mainGameWindow->getDimensions().left;
+ pos.y += _mainGameWindow->getDimensions().top;
+ pos = event.mouse - pos;
+ if (_assets.contains(child) && _assets[child]->isPointInside(pos)) {
// select the first object clicked
_engine->selectObject(child);
- return true;
}
}
}
return false;
}
bool MacVenture::Gui::processOutConsoleEvents(WindowClick click, Common::Event & event) {
+ if (_engine->needsClickToContinue())
+ return true;
+
return getWindowData(kOutConsoleWindow).visible;
}
bool MacVenture::Gui::processSelfEvents(WindowClick click, Common::Event & event) {
- return getWindowData(kSelfWindow).visible;
+ if (_engine->needsClickToContinue())
+ return true;
+
+ if (event.type == Common::EVENT_LBUTTONUP) {
+ _engine->selectObject(1);
+ }
+ return true;
}
bool MacVenture::Gui::processExitsEvents(WindowClick click, Common::Event & event) {
+ if (_engine->needsClickToContinue())
+ return true;
return getWindowData(kExitsWindow).visible;
}
bool MacVenture::Gui::processDiplomaEvents(WindowClick click, Common::Event & event) {
+ if (_engine->needsClickToContinue())
+ return true;
+
return getWindowData(kDiplomaWindow).visible;
}
bool Gui::processInventoryEvents(WindowClick click, Common::Event & event) {
+ if (_engine->needsClickToContinue())
+ return true;
+
return false;
}
diff --git a/engines/macventure/gui.h b/engines/macventure/gui.h
index 2e8b6e20a2..b7d5d52b83 100644
--- a/engines/macventure/gui.h
+++ b/engines/macventure/gui.h
@@ -117,7 +117,8 @@ enum ControlReference {
kControlOperate = 5,
kControlGo = 6,
kControlHit = 7,
- kControlConsume = 8
+ kControlConsume = 8,
+ kControlClickToContinue = 9
};
struct ControlData {
@@ -153,9 +154,11 @@ public:
void drawMenu();
void drawTitle();
void drawExit(ObjID id);
+ void clearControls();
bool processEvent(Common::Event &event);
void handleMenuAction(MenuAction action);
void updateWindow(WindowReference winID, bool containerOpen);
+ void invertWindowColors(WindowReference winID);
WindowReference createInventoryWindow();
bool tryCloseWindow(WindowReference winID);
@@ -225,11 +228,15 @@ private: // Methods
void drawCommandsWindow();
void drawMainGameWindow();
void drawSelfWindow();
+ void drawInventories();
+ void drawExitsWindow();
void drawObjectsInWindow(WindowReference target, Graphics::ManagedSurface *surface);
+ void drawWindowTitle(WindowReference target, Graphics::ManagedSurface *surface);
// Finders
WindowData& findWindowData(WindowReference reference);
+ Graphics::MacWindow *findWindow(WindowReference reference);
};
@@ -249,12 +256,16 @@ public:
CommandButton(ControlData data, Gui *g) {
_data = data;
_gui = g;
+ _selected = false;
}
~CommandButton() {}
void draw(Graphics::ManagedSurface &surface) const {
- surface.fillRect(_data.bounds, kColorWhite);
+ uint colorFill = _selected ? kColorBlack : kColorWhite;
+ uint colorText = _selected ? kColorWhite : kColorBlack;
+
+ surface.fillRect(_data.bounds, colorFill);
surface.frameRect(_data.bounds, kColorBlack);
const Graphics::Font &font = _gui->getCurrentFont();
@@ -265,7 +276,7 @@ public:
_data.bounds.left,
_data.bounds.top,
_data.bounds.right - _data.bounds.left,
- kColorBlack,
+ colorText,
Graphics::kTextAlignCenter);
}
@@ -277,7 +288,20 @@ public:
return _data;
}
+ void select() {
+ _selected = true;
+ }
+
+ void unselect() {
+ _selected = false;
+ }
+
+ bool isSelected() {
+ return _selected;
+ }
+
private:
+ bool _selected;
ControlData _data;
Gui *_gui;
};
diff --git a/engines/macventure/image.cpp b/engines/macventure/image.cpp
index de4e3ba12e..54d19c9fd2 100644
--- a/engines/macventure/image.cpp
+++ b/engines/macventure/image.cpp
@@ -311,40 +311,47 @@ byte ImageAsset::walkHuff(const PPICHuff & huff, Common::BitStream & stream) {
void ImageAsset::blitInto(Graphics::ManagedSurface *target, uint32 x, uint32 y, BlitMode mode) {
if (mode == kBlitDirect) {
blitDirect(target, x, y, _imgData);
- return;
- }
-
- if (_container->getItemByteSize(_mask)) { // Has mask
- switch (mode) {
- case MacVenture::kBlitBIC:
- blitBIC(target, x, y, _maskData);
- break;
- case MacVenture::kBlitOR:
- blitOR(target, x, y, _maskData);
- break;
- }
- } else if (_container->getItemByteSize(_id)) {
- switch (mode) {
- case MacVenture::kBlitBIC:
- target->fillRect(Common::Rect(x, y, x + _bitWidth, y + _bitHeight * 2), kColorWhite);
- break;
- case MacVenture::kBlitOR:
- target->fillRect(Common::Rect(x, y, x + _bitWidth, y + _bitHeight * 2), kColorBlack);
- break;
+ } else if (mode < kBlitXOR){
+ if (_container->getItemByteSize(_mask)) { // Has mask
+ switch (mode) {
+ case MacVenture::kBlitBIC:
+ blitBIC(target, x, y, _maskData);
+ break;
+ case MacVenture::kBlitOR:
+ blitOR(target, x, y, _maskData);
+ break;
+ default:
+ break;
+ }
+ } else if (_container->getItemByteSize(_id)) {
+ switch (mode) {
+ case MacVenture::kBlitBIC:
+ target->fillRect(Common::Rect(x, y, x + _bitWidth, y + _bitHeight * 2), kColorWhite);
+ break;
+ case MacVenture::kBlitOR:
+ target->fillRect(Common::Rect(x, y, x + _bitWidth, y + _bitHeight * 2), kColorBlack);
+ break;
+ default:
+ break;
+ }
}
- }
- if (_container->getItemByteSize(_id) && mode > 0) {
- blitXOR(target, x, y, _imgData);
- }
+ if (_container->getItemByteSize(_id) && mode > 0) {
+ blitXOR(target, x, y, _imgData);
+ }
+ }
}
-bool ImageAsset::isPointInside(Common::Point myPos, Common::Point click) {
- Common::Rect bounds(myPos.x, myPos.y, myPos.x + _bitWidth, myPos.y + _bitHeight);
- return bounds.contains(click);
+bool ImageAsset::isPointInside(Common::Point point) {
+ if (point.x >= _bitWidth || point.y >= _bitHeight) return false;
+ if (_maskData.empty()) return false;
+ // We see if the point lands on the mask.
+ uint pix = _maskData[(point.y * _rowBytes) + (point.x >> 3)] & (1 << (7 - (point.x & 7)));
+ return pix != 0;
}
void ImageAsset::blitDirect(Graphics::ManagedSurface * target, uint32 ox, uint32 oy, const Common::Array<byte>& data) {
+ /*
if (_bitWidth == 0 || _bitHeight == 0) return;
uint w = _bitWidth;
uint h = _bitHeight;
@@ -355,19 +362,21 @@ void ImageAsset::blitDirect(Graphics::ManagedSurface * target, uint32 ox, uint32
if (w + ox >= target->w) w = target->w - ox;
if (h + oy >= target->h) h = target->h - oy;
if (w == 0 || h == 0) return;
+ */
- for (uint y = 0;y < _bitHeight; y++) {
+ for (uint y = 0; y < _bitHeight; y++) {
uint bmpofs = y * _rowBytes;
byte pix = 0;
for (uint x = 0; x < _bitWidth; x++) {
pix = data[bmpofs + (x >> 3)] & (1 << (7 - (x & 7)));
pix = pix ? kColorBlack : kColorWhite;
- if (pix) *((byte *)target->getBasePtr(ox + x, oy + y)) = pix;
+ *((byte *)target->getBasePtr(ox + x, oy + y)) = pix;
}
}
}
void ImageAsset::blitBIC(Graphics::ManagedSurface * target, uint32 ox, uint32 oy, const Common::Array<byte> &data) {
+ /*
if (_bitWidth == 0 || _bitHeight == 0) return;
uint w = _bitWidth;
uint h = _bitHeight;
@@ -378,19 +387,19 @@ void ImageAsset::blitBIC(Graphics::ManagedSurface * target, uint32 ox, uint32 oy
if (w + ox >= target->w) w = target->w - ox;
if (h + oy >= target->h) h = target->h - oy;
if (w == 0 || h == 0) return;
-
- for (uint y = 0;y < h; y++) {
+ */
+ for (uint y = 0; y < _bitHeight; y++) {
uint bmpofs = y * _rowBytes;
byte pix = 0;
- for (uint x = 0; x < w; x++) {
- pix = data[bmpofs + (x >> 3)] & (1 << (7 - (x & 7)));
-
+ for (uint x = 0; x < _bitWidth; x++) {
+ pix = data[bmpofs + (x >> 3)] & (1 << (7 - (x & 7)));
if (pix) *((byte *)target->getBasePtr(ox + x, oy + y)) = kColorWhite;
}
}
}
void ImageAsset::blitOR(Graphics::ManagedSurface * target, uint32 ox, uint32 oy, const Common::Array<byte> &data) {
+ /*
if (_bitWidth == 0 || _bitHeight == 0) return;
uint w = _bitWidth;
uint h = _bitHeight;
@@ -401,8 +410,8 @@ void ImageAsset::blitOR(Graphics::ManagedSurface * target, uint32 ox, uint32 oy,
if (w + ox >= target->w) w = target->w - ox;
if (h + oy >= target->h) h = target->h - oy;
if (w == 0 || h == 0) return;
-
- for (uint y = 0;y < _bitHeight; y++) {
+ */
+ for (uint y = 0; y < _bitHeight; y++) {
uint bmpofs = y * _rowBytes;
byte pix = 0;
for (uint x = 0; x < _bitWidth; x++) {
@@ -414,6 +423,7 @@ void ImageAsset::blitOR(Graphics::ManagedSurface * target, uint32 ox, uint32 oy,
}
void ImageAsset::blitXOR(Graphics::ManagedSurface * target, uint32 ox, uint32 oy, const Common::Array<byte> &data) {
+ /*
if (_bitWidth == 0 || _bitHeight == 0) return;
uint w = _bitWidth;
uint h = _bitHeight;
@@ -424,7 +434,7 @@ void ImageAsset::blitXOR(Graphics::ManagedSurface * target, uint32 ox, uint32 oy
if (w + ox >= target->w) w = target->w - ox;
if (h + oy >= target->h) h = target->h - oy;
if (w == 0 || h == 0) return;
-
+ */
for (uint y = 0;y < _bitHeight; y++) {
uint bmpofs = y * _rowBytes;
byte pix = 0;
diff --git a/engines/macventure/image.h b/engines/macventure/image.h
index 0a3ea50ef1..adce9a54a2 100644
--- a/engines/macventure/image.h
+++ b/engines/macventure/image.h
@@ -59,7 +59,7 @@ public:
void blitInto(Graphics::ManagedSurface *target, uint32 x, uint32 y, BlitMode mode);
- bool isPointInside(Common::Point myPos, Common::Point click);
+ bool isPointInside(Common::Point point);
private:
void decodePPIC(ObjID id, Common::Array<byte> &data);
diff --git a/engines/macventure/macventure.cpp b/engines/macventure/macventure.cpp
index 8d367c7174..572677a7f6 100644
--- a/engines/macventure/macventure.cpp
+++ b/engines/macventure/macventure.cpp
@@ -100,45 +100,55 @@ Common::Error MacVentureEngine::run() {
_cmdReady = false;
_haltedAtEnd = false;
_haltedInSelection = false;
+ _clickToContinue = true;
+ _gameState = kGameStateInit;
+ _destObject = 0;
+ _prepared = true;
//if !savegame
_cmdReady = true;
_selectedControl = kStartOrResume;
ObjID playerParent = _world->getObjAttr(1, kAttrParentObject);
_currentSelection.push_back(playerParent);// Push the parent of the player
- _world->setObjAttr(playerParent, 6, 1);
+ _world->setObjAttr(playerParent, kAttrContainerOpen, 1);
- _prepared = true;
- while (!(_gameState == kGameStateQuitting)) {
+ _gui->addChild(kSelfWindow, 1);
+ _gui->updateWindow(kSelfWindow, false);
+
+ while (_gameState != kGameStateQuitting) {
processEvents();
- if (_prepared) {
- _prepared = false;
-
- if (!_halted)
- updateState();
-
- if (_cmdReady || _halted) {
- _halted = false;
- if (runScriptEngine()) {
- _halted = true;
- _paused = true;
- } else {
- _paused = false;
- if (!updateState()) {
- updateControls();
+ if (_gameState != kGameStateQuitting) {
+
+ if (_prepared) {
+ _prepared = false;
+
+ if (!_halted)
+ updateState();
+
+ if (_cmdReady || _halted) {
+ _halted = false;
+ if (runScriptEngine()) {
+ _halted = true;
+ _paused = true;
}
+ else {
+ _paused = false;
+ if (!updateState()) {
+ updateControls();
+ }
+ }
+ }
+
+ if (_gameState == kGameStateWinnig || _gameState == kGameStateLosing) {
+ endGame();
}
}
+ _gui->draw();
- if (_gameState == kGameStateWinnig || _gameState == kGameStateLosing) {
- endGame();
- }
+ g_system->updateScreen();
+ g_system->delayMillis(50);
}
- _gui->draw();
-
- g_system->updateScreen();
- g_system->delayMillis(50);
}
return Common::kNoError;
@@ -161,6 +171,11 @@ void MacVentureEngine::selectControl(ControlReference id) {
}
void MacVentureEngine::activateCommand(ControlReference id) {
+ if (id == kControlClickToContinue) {
+ _clickToContinue = false;
+ _paused = true;
+ return;
+ }
ControlAction action = referenceToAction(id);
if (action != _activeControl) {
if (_activeControl)
@@ -168,6 +183,7 @@ void MacVentureEngine::activateCommand(ControlReference id) {
_activeControl = action;
}
debug(4, "Activating Command %x... Command %x is active", action, _activeControl);
+ refreshReady();
}
void MacVentureEngine::refreshReady() {
@@ -201,9 +217,16 @@ void MacVentureEngine::loseGame() {
_gameState = kGameStateLosing;
}
-void MacVentureEngine::enqueueObject(ObjectQueueID type, ObjID objID) {
+void MacVentureEngine::clickToContinue() {
+ _clickToContinue = true;
+}
+
+void MacVentureEngine::enqueueObject(ObjectQueueID type, ObjID objID, ObjID target) {
QueuedObject obj;
obj.id = type;
+
+ if (type == kUpdateWindow) { obj.target = target; }
+
if (type != kHightlightExits) {
obj.object = objID;
obj.parent = _world->getObjAttr(objID, kAttrParentObject);
@@ -257,7 +280,12 @@ void MacVentureEngine::selectObject(ObjID objID) {
else i++;
}
- if (!found) _currentSelection.push_back(objID);
+ if (!found) {
+ _currentSelection.push_back(objID);
+ debug("Object %d selected", objID);
+ } else {
+ debug("Object %d already selected", objID);
+ }
found = false;
i = 0;
@@ -266,7 +294,15 @@ void MacVentureEngine::selectObject(ObjID objID) {
else i++;
}
- if (!found) _selectedObjs.push_back(objID);
+ if (!found) _selectedObjs.push_back(objID);
+}
+
+void MacVentureEngine::updateDelta(Common::Point newPos) {
+ Common::Point newDelta = newPos - _deltaPoint;
+ debug(4, "Update delta: Old(%d, %d), New(%d, %d)",
+ _deltaPoint.x, _deltaPoint.y,
+ newDelta.x, newDelta.y);
+ _deltaPoint = newDelta;
}
void MacVentureEngine::focusObjWin(ObjID objID) {
@@ -357,11 +393,11 @@ bool MacVentureEngine::updateState() {
}
void MacVentureEngine::revert() {
- warning("revert: unimplemented");
+ _gui->invertWindowColors(kMainGameWindow);
+ preparedToRun();
}
void MacVentureEngine::runObjQueue() {
- warning("runObjQueue: not fully implemented");
while (!_objQueue.empty()) {
uint32 biggest = 0;
uint32 index = 0;
@@ -389,7 +425,7 @@ void MacVentureEngine::runObjQueue() {
checkObject(obj);
break;
case 0x8:
- reflectSwap(obj.object);
+ reflectSwap(obj.object, obj.target);
break;
case 0xc:
_world->setObjAttr(_gui->getWindowData(kMainGameWindow).refcon, kAttrContainerOpen, 0);
@@ -408,6 +444,7 @@ void MacVentureEngine::runObjQueue() {
void MacVentureEngine::updateControls() {
if (_activeControl)
_activeControl = kNoCommand;
+ _gui->clearControls();
toggleExits();
resetVars();
}
@@ -434,7 +471,7 @@ void MacVentureEngine::openObject(ObjID objID) {
debug("openObject: %d", objID);
if (getObjWindow(objID)) return;
if (objID == _world->getObjAttr(1, kAttrParentObject)) {
- _gui->updateWindowInfo(kMainGameWindow, objID, _world->getChildren(objID, true)); // FIXME: Find better name
+ _gui->updateWindowInfo(kMainGameWindow, objID, _world->getChildren(objID, true));
_gui->updateWindow(kMainGameWindow, _world->getObjAttr(objID, kAttrContainerOpen));
//_gui->drawExits();
_gui->setWindowTitle(kMainGameWindow, _world->getText(objID));
@@ -522,12 +559,30 @@ void MacVentureEngine::checkObject(QueuedObject old) {
}
}
-void MacVentureEngine::reflectSwap(ObjID objID) {
- warning("reflectSwap: unimplemented");
+void MacVentureEngine::reflectSwap(ObjID fromID, ObjID toID) {
+ warning("reflectSwap: untested");
+ WindowReference from = getObjWindow(fromID);
+ WindowReference to = getObjWindow(toID);
+ WindowReference tmp = to;
+ if (!to) {
+ tmp = from;
+ }
+ if (tmp) {
+ Common::String newTitle = _world->getText(toID);
+ _gui->setWindowTitle(tmp, newTitle);
+ _gui->updateWindowInfo(tmp, toID, _world->getChildren(toID, true));
+ updateWindow(tmp);
+ }
}
void MacVentureEngine::toggleExits() {
warning("toggleExits: unimplemented");
+ while (!_selectedObjs.empty()) {
+ ObjID obj = _selectedObjs.front();
+ _selectedObjs.remove_at(0);
+ // Todo: highlight exit
+ updateWindow(findParentWindow(obj));
+ }
}
void MacVentureEngine::zoomObject(ObjID objID) {
@@ -565,6 +620,10 @@ bool MacVentureEngine::isPaused() {
return _paused;
}
+bool MacVentureEngine::needsClickToContinue() {
+ return _clickToContinue;
+}
+
Common::String MacVentureEngine::getCommandsPausedString() const {
return Common::String("Click to continue");
}
@@ -607,7 +666,10 @@ bool MacVentureEngine::isObjClickable(ObjID objID) {
}
bool MacVentureEngine::isObjSelected(ObjID objID) {
- warning("Unimplemented: isObjSelected");
+ Common::Array<ObjID>::const_iterator it;
+ for (it = _currentSelection.begin(); it != _currentSelection.end(); it++) {
+ if (*it == objID) return true;
+ }
return false;
}
diff --git a/engines/macventure/macventure.h b/engines/macventure/macventure.h
index c45069c06c..c19021d4c5 100644
--- a/engines/macventure/macventure.h
+++ b/engines/macventure/macventure.h
@@ -135,6 +135,7 @@ struct QueuedObject {
bool hidden;
bool offscreen;
bool invisible;
+ ObjID target; // For swapping
};
enum TextQueueID {
@@ -167,22 +168,25 @@ public:
void gameChanged();
void winGame();
void loseGame();
+ void clickToContinue();
bool updateState();
void revert();
- void enqueueObject(ObjectQueueID type, ObjID objID);
+ void enqueueObject(ObjectQueueID type, ObjID objID, ObjID target = 0);
void enqueueText(TextQueueID type, ObjID target, ObjID source, ObjID text);
void runObjQueue();
bool printTexts();
void selectObject(ObjID objID);
+ void updateDelta(Common::Point newPos);
void focusObjWin(ObjID objID);
void updateWindow(WindowReference winID);
// Data retrieval
bool isPaused();
+ bool needsClickToContinue();
Common::String getCommandsPausedString() const;
const GlobalSettings& getGlobalSettings() const;
Common::String getFilePath(FilePathID id) const;
@@ -218,7 +222,7 @@ private:
void openObject(ObjID objID);
void closeObject(ObjID objID);
void checkObject(QueuedObject objID);
- void reflectSwap(ObjID objID);
+ void reflectSwap(ObjID fromID, ObjID toID);
void toggleExits();
void zoomObject(ObjID objID);
@@ -255,6 +259,7 @@ private: // Attributes
bool _paused, _halted, _cmdReady, _prepared;
bool _haltedAtEnd, _haltedInSelection;
bool _gameChanged;
+ bool _clickToContinue;
Common::Array<QueuedObject> _objQueue;
Common::Array<QueuedObject> _inQueue;
diff --git a/engines/macventure/script.cpp b/engines/macventure/script.cpp
index f7550360c8..bf9339fe76 100644
--- a/engines/macventure/script.cpp
+++ b/engines/macventure/script.cpp
@@ -41,9 +41,6 @@ ScriptEngine::~ScriptEngine() {
}
bool ScriptEngine::runControl(ControlAction action, ObjID source, ObjID destination, Common::Point delta) {
- //debug(7, "SCRIPT: Running control %d from obj %d into obj %d, at delta (%d, %d)",
- // action, source, destination, delta.x, delta.y);
-
EngineFrame frame;
frame.action = action;
frame.src = source;
@@ -108,24 +105,37 @@ bool ScriptEngine::execFrame(bool execAll) {
}
doFamily = true;
}
- }
-
- //Handle saves
- /*
+ }
- uint highest;
- uint high;
+ // Halted in saves
if (frame->haltedInSaves) {
- frame->haltedInSaves = false;
- }
-
-
- do {
- highest = 0;
- for (uint i = 0; i < frame->haltedInSaves.size)
+ frame->haltedInSaves = false;
+ if (resumeFunc(frame)) {
+ frame->haltedInSaves = true;
+ return true;
+ }
}
- */
+ uint highest = 0;
+ uint localHigh = 0;
+ do { // Saved function calls
+ highest = 0;
+ for (uint i = 0; i <frame->saves.size(); i++)
+ {
+ if (highest < frame->saves[i].rank) {
+ highest = frame->saves[i].rank;
+ localHigh = i;
+ }
+ }
+ if (highest) {
+ frame->saves[localHigh].rank = 0;
+ if (loadScript(frame, frame->saves[localHigh].func)) {
+ frame->haltedInSaves = true;
+ return true;
+ }
+ }
+ } while (highest);
+
_frames.remove_at(0);
return false;
}
@@ -907,7 +917,7 @@ void ScriptEngine::opbdFOOB(EngineState * state, EngineFrame * frame) {
void ScriptEngine::opbeSWOB(EngineState * state, EngineFrame * frame) {
ObjID from = state->pop();
ObjID to = state->pop();
- _engine->enqueueObject(kUpdateWindow, to);
+ _engine->enqueueObject(kUpdateWindow, from, to);
_world->setObjAttr(to, kAttrContainerOpen, _world->getObjAttr(from, 6));
_world->setObjAttr(from, kAttrContainerOpen, 0);
Common::Array<ObjID> children = _world->getChildren(from, true);
@@ -1057,7 +1067,7 @@ void ScriptEngine::opd9SLEEP(EngineState * state, EngineFrame * frame) {
void ScriptEngine::opdaCLICK(EngineState * state, EngineFrame * frame) {
_engine->updateState();
- //_engine->clickToContinue();
+ _engine->clickToContinue();
}
void ScriptEngine::opdbROBQ(EngineState * state, EngineFrame * frame) {
@@ -1083,13 +1093,11 @@ void ScriptEngine::opdfFMAI(EngineState * state, EngineFrame * frame) {
}
void ScriptEngine::ope0CHGR(EngineState * state, EngineFrame * frame) {
- word txt = state->pop();
- op00NOOP(0xe0);
+ state->pop();
}
void ScriptEngine::ope1CHSO(EngineState * state, EngineFrame * frame) {
- word txt = state->pop();
- op00NOOP(0xe1);
+ state->pop();
}
void ScriptEngine::ope2MDIV(EngineState * state, EngineFrame * frame) {
@@ -1108,7 +1116,6 @@ void ScriptEngine::ope3UPOB(EngineState * state, EngineFrame * frame) {
void ScriptEngine::ope4PLEV(EngineState * state, EngineFrame * frame) {
state->push(0);
- op00NOOP(0xe4);
}
void ScriptEngine::ope5WEV(EngineState * state, EngineFrame * frame) {