aboutsummaryrefslogtreecommitdiff
path: root/engines/glk/windows.cpp
diff options
context:
space:
mode:
authorPaul Gilbert2019-01-02 18:18:11 -0800
committerPaul Gilbert2019-01-02 18:18:11 -0800
commitf1d9722f3bd58f7883f3e76c19d4a0133da73489 (patch)
tree26986b085d83e597b10c3851fde9b49574c10586 /engines/glk/windows.cpp
parent3ed48e3de223259dd58f0c613c2d68d69848e5a2 (diff)
downloadscummvm-rg350-f1d9722f3bd58f7883f3e76c19d4a0133da73489.tar.gz
scummvm-rg350-f1d9722f3bd58f7883f3e76c19d4a0133da73489.tar.bz2
scummvm-rg350-f1d9722f3bd58f7883f3e76c19d4a0133da73489.zip
GLK: FROTZ: Add support for pair windows to have more than 2 children
This is primarily for the V6 games, which have up to 8 windows on-screen at the same time in arbitray positions ext
Diffstat (limited to 'engines/glk/windows.cpp')
-rw-r--r--engines/glk/windows.cpp85
1 files changed, 47 insertions, 38 deletions
diff --git a/engines/glk/windows.cpp b/engines/glk/windows.cpp
index de8fa52385..d75ba1f6e5 100644
--- a/engines/glk/windows.cpp
+++ b/engines/glk/windows.cpp
@@ -104,15 +104,22 @@ Window *Windows::windowOpen(Window *splitwin, uint method, uint size,
val = (method & winmethod_DirMask);
if (val != winmethod_Above && val != winmethod_Below && val != winmethod_Left
- && val != winmethod_Right && val != winmethod_OnTop) {
+ && val != winmethod_Right && val != winmethod_Arbitrary) {
warning("window_open: invalid method (bad direction)");
return nullptr;
}
- oldparent = splitwin->_parent;
- if (oldparent && oldparent->_type != wintype_Pair) {
- warning("window_open: parent window is not Pair");
- return nullptr;
+ if (splitwin->_type == wintype_Pair) {
+ if ((method & winmethod_DirMask) != winmethod_Arbitrary) {
+ warning("window_open: Can only add windows to a Pair window in arbitrary mode");
+ return nullptr;
+ }
+ } else {
+ oldparent = splitwin->_parent;
+ if (oldparent && oldparent->_type != wintype_Pair) {
+ warning("window_open: parent window is not Pair");
+ return nullptr;
+ }
}
}
@@ -125,11 +132,16 @@ Window *Windows::windowOpen(Window *splitwin, uint method, uint size,
if (!splitwin) {
_rootWin = newwin;
+ } else if (splitwin->_type == wintype_Pair) {
+ pairWin = static_cast<PairWindow *>(splitwin);
+ pairWin->_dir = winmethod_Arbitrary;
+ pairWin->_children.push_back(newwin);
+ newwin->_parent = pairWin;
} else {
// create pairWin, with newwin as the key
pairWin = newPairWindow(method, newwin, size);
- pairWin->_child1 = splitwin;
- pairWin->_child2 = newwin;
+ pairWin->_children.push_back(splitwin);
+ pairWin->_children.push_back(newwin);
splitwin->_parent = pairWin;
newwin->_parent = pairWin;
@@ -138,10 +150,11 @@ Window *Windows::windowOpen(Window *splitwin, uint method, uint size,
if (oldparent) {
PairWindow *parentWin = dynamic_cast<PairWindow *>(oldparent);
assert(parentWin);
- if (parentWin->_child1 == splitwin)
- parentWin->_child1 = pairWin;
- else
- parentWin->_child2 = pairWin;
+
+ for (uint idx = 0; idx < parentWin->_children.size(); ++idx) {
+ if (parentWin->_children[idx] == splitwin)
+ parentWin->_children[idx] = pairWin;
+ }
} else {
_rootWin = pairWin;
}
@@ -168,24 +181,22 @@ void Windows::windowClose(Window *win, StreamResult *result) {
PairWindow *pairWin = dynamic_cast<PairWindow *>(win->_parent);
PairWindow *grandparWin;
- if (win == pairWin->_child1) {
- sibWin = pairWin->_child2;
- } else if (win == pairWin->_child2) {
- sibWin = pairWin->_child1;
- } else {
+ int index = pairWin->_children.indexOf(win);
+ if (index == -1) {
warning("windowClose: window tree is corrupted");
return;
}
+ sibWin = (index = ((int)pairWin->_children.size() - 1)) ?
+ pairWin->_children.front() : pairWin->_children[index + 1];
+
grandparWin = dynamic_cast<PairWindow *>(pairWin->_parent);
if (!grandparWin) {
_rootWin = sibWin;
sibWin->_parent = nullptr;
} else {
- if (grandparWin->_child1 == pairWin)
- grandparWin->_child1 = sibWin;
- else
- grandparWin->_child2 = sibWin;
+ index = grandparWin->_children.indexOf(pairWin);
+ grandparWin->_children[index] = sibWin;
sibWin->_parent = grandparWin;
}
@@ -197,10 +208,8 @@ void Windows::windowClose(Window *win, StreamResult *result) {
win->close(true);
// This probably isn't necessary, but the child *is* gone, so just in case.
- if (win == pairWin->_child1)
- pairWin->_child1 = nullptr;
- else if (win == pairWin->_child2)
- pairWin->_child2 = nullptr;
+ index = pairWin->_children.indexOf(win);
+ pairWin->_children[index] = nullptr;
// Now we can delete the parent pair.
pairWin->close(false);
@@ -462,21 +471,20 @@ Window *Windows::iterateTreeOrder(Window *win) {
PairWindow *pairWin = dynamic_cast<PairWindow *>(win);
if (pairWin) {
- if (!pairWin->_backward)
- return pairWin->_child1;
- else
- return pairWin->_child2;
+ return pairWin->_backward ? pairWin->_children.back() : pairWin->_children.front();
} else {
while (win->_parent) {
pairWin = dynamic_cast<PairWindow *>(win->_parent);
assert(pairWin);
+ int index = pairWin->_children.indexOf(win);
+ assert(index != -1);
if (!pairWin->_backward) {
- if (win == pairWin->_child1)
- return pairWin->_child2;
+ if (index < ((int)pairWin->_children.size() - 1))
+ return pairWin->_children[index + 1];
} else {
- if (win == pairWin->_child2)
- return pairWin->_child1;
+ if (index > 0)
+ return pairWin->_children[index - 1];
}
win = pairWin;
@@ -515,10 +523,11 @@ Window::~Window() {
// Remove the window from any parent
PairWindow *parent = dynamic_cast<PairWindow *>(_parent);
- if (parent && parent->_child1 == this)
- parent->_child1 = nullptr;
- if (parent && parent->_child2 == this)
- parent->_child2 = nullptr;
+ if (parent) {
+ int index = parent->_children.indexOf(this);
+ if (index != -1)
+ parent->_children[index] = nullptr;
+ }
// Delete any attached window stream
_echoStream = nullptr;
@@ -554,8 +563,8 @@ void Window::close(bool recurse) {
PairWindow *pairWin = dynamic_cast<PairWindow *>(this);
if (pairWin) {
- pairWin->_child1->close(recurse);
- pairWin->_child2->close(recurse);
+ for (uint idx = 0; idx < pairWin->_children.size(); ++idx)
+ pairWin->_children[idx]->close();
}
// Finally, delete the window