SAGA2: Kill DList

This commit is contained in:
a/
2021-07-03 10:54:53 +09:00
parent e1a430c801
commit 4dbfeb6ea4
8 changed files with 68 additions and 323 deletions
-122
View File
@@ -1,122 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 2
* 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
* aint32 with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
* Based on the original sources
* Faery Tale II -- The Halls of the Dead
* (c) 1993-1996 The Wyrmkeep Entertainment Co.
*/
#include "saga2/saga2.h"
#include "saga2/dlist.h"
namespace Saga2 {
DNode *DNode::remove(void) {
succ->pred = pred;
pred->succ = succ;
return this;
}
void DList::addHead(DNode &d) {
head->pred = &d;
d.succ = head;
head = &d;
d.pred = (DNode *)&head;
}
void DList::addTail(DNode &d) {
tail->succ = &d;
d.pred = tail;
tail = &d;
d.succ = (DNode *)&overlap;
}
DNode *DList::remHead(void) {
DNode *n = head;
if (n == nullptr)
return nullptr;
if (n->succ) {
head = n->succ;
head->pred = (DNode *)&head;
return n;
}
return 0;
}
DNode *DList::remTail(void) {
DNode *n = tail;
if (n->pred) {
tail = n->pred;
tail->succ = (DNode *)&overlap;
return n;
}
return 0;
}
// Insert a node before another one
void DList::insert(DNode &d, DNode &before) {
d.succ = &before;
d.pred = before.pred;
before.pred = &d;
d.pred->succ = &d;
}
void DList::insert(DNode &d, void *extra, int (*compare)(DNode &d1, DNode &d2, void *extra)) {
DNode *search;
for (search = head;
search->succ != NULL && (*compare)(*search, d, extra) < 0;
search = search->succ)
;
insert(d, *search);
}
int DList::count(void) const {
int ct; // count
DNode *d;
for (d = head, ct = -1; // scan list
d;
d = d->succ, ++ct) ; // bunp count
return ct;
}
DNode *DList::select(int number) const {
if (number < 0) {
for (DNode *d = tail; d->succ; d = d->succ, ++number) {
if (number >= -1) return d;
}
return 0;
}
for (DNode *d = head; d->succ; d = d->succ, --number) {
if (number <= 0) return d;
}
return 0;
}
} // end of namespace Saga2
-130
View File
@@ -1,130 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
* Based on the original sources
* Faery Tale II -- The Halls of the Dead
* (c) 1993-1996 The Wyrmkeep Entertainment Co.
*/
#ifndef SAGA2_DLIST_H
#define SAGA2_DLIST_H
namespace Saga2 {
// A doubly-linked list node
class DNode {
DNode *succ, // ptr to next in list
*pred; // ptr to prev in list
friend class DList;
friend class DList_iter;
public:
DNode *next(void) const {
return succ->succ ? succ : 0; // Next in list
}
DNode *prev(void) const {
return pred->pred ? pred : 0; // Previous in list
}
DNode *remove(void);
};
// A doubly-linked list (with dummy pointer to resolve end cases)
class DList {
DNode *head, // ptr to next in list
*overlap, // dummy pointer
*tail; // ptr to prev in list
friend class DList_iter;
public:
// constructor
DList(void) {
head = (DNode *)&overlap;
tail = (DNode *)&head;
overlap = 0;
}
// Return pointer to first/last node in list
DNode *first(void) const {
return head->succ ? head : NULL;
}
DNode *last(void) const {
return tail->pred ? tail : NULL;
}
// Add node to head/tail of list
void addHead(DNode &d);
void addTail(DNode &d);
// Remove head/tail
DNode *remHead(void);
DNode *remTail(void);
// Test if list is empty
bool empty(void) {
return head == (DNode *)&overlap;
}
// Insert a node before another one
void insert(DNode &d, DNode &before);
// Insert a node in a specific order
void insert(DNode &d, void *extra, int (*compare)(DNode &d1, DNode &d2, void *extra));
// Count number of nodes in the list
int count(void) const;
// Select the Nth node in the list
DNode *select(int number) const;
};
class DList_iter {
DNode *current;
public:
// Constructor, initializes the iterator to the head of the list
DList_iter(DList &dl) {
current = dl.head;
}
DNode *next(void) {
return current->succ ? (current = current->succ) : 0;
}
DNode *prev(void) {
return current->pred ? (current = current->pred) : 0;
}
#if 0
DNode *remove(void) {
if (current->succ && current->pred) {
current.remove();
current = current->succ;
}
}
#endif
};
} // end of namespace Saga2
#endif
+4 -9
View File
@@ -612,7 +612,6 @@ bool checkTileAreaPort(void);
extern bool userControlsSetup;
void updateWindowSection(const Rect16 &r) {
DecoratedWindow *dw;
gPixelMap tempMap;
gPort tempPort;
Point16 offset(r.x, r.y);
@@ -681,11 +680,8 @@ void updateWindowSection(const Rect16 &r) {
// For each window, both background and float, that overlaps
// the clip, draw the window's imagery
if (userControlsSetup) {
for (dw = (DecoratedWindow *)G_BASE.bottomWindow();
dw;
dw = (DecoratedWindow *)dw->prev()) {
dw->drawClipped(tempPort, offset, clip);
}
for (Common::List<gWindow *>::iterator it = G_BASE.bottomWindowIterator(); it != G_BASE.topWindowIterator(); --it)
(*it)->drawClipped(tempPort, offset, clip);
}
// Now, blit the temporary bitmap to the main screen.
@@ -735,9 +731,8 @@ void drawFloatingWindows(gPort &port, const Point16 &offset, const Rect16 &clip)
}
}
for (dw = (DecoratedWindow *)G_BASE.bottomWindow();
dw;
dw = (DecoratedWindow *)dw->prev()) {
for (Common::List<gWindow *>::iterator it = G_BASE.bottomWindowIterator(); it != G_BASE.topWindowIterator(); --it) {
dw = (DecoratedWindow *)(*it);
if (!dw->isBackdrop())
dw->drawClipped(port, offset, clip);
}
-1
View File
@@ -15,7 +15,6 @@ MODULE_OBJS := \
detection.o \
display.o \
dispnode.o \
dlist.o \
document.o \
effects.o \
enchant.o \
+47 -49
View File
@@ -266,20 +266,23 @@ gPanelList::gPanelList(gWindow &win, const Rect16 &box, char *newTitle,
gPanelList::gPanelList(gPanelList &list)
: gPanel(list, list.window.getExtent(), NULL, 0, NULL) {
window.contents.addTail(*this);
window.contents.push_back(this);
}
gPanelList::~gPanelList() {
removeControls();
remove();
window.contents.remove(this);
}
void gPanelList::removeControls(void) {
gControl *ctl;
gPanel *ctl;
// Delete all sub-panels.
while ((ctl = (gControl *)contents.first()) != nullptr)
while (contents.size()) {
ctl = contents.front();
contents.remove(ctl);
delete ctl;
}
}
// enable/disable gPanelList and all it's children
@@ -288,36 +291,33 @@ void gPanelList::enable(bool abled) {
}
void gPanelList::invalidate(Rect16 *) {
gControl *ctl;
Rect16 invArea;
gPanel *ctl;
Rect16 invArea;
assert(displayEnabled());
if (displayEnabled())
if ((ctl = (gControl *)contents.last())) {
if (contents.size()) {
ctl = contents.back();
invArea = ctl->getExtent();
for (ctl = (gControl *)ctl->prev();
ctl;
ctl = (gControl *)ctl->prev()) {
for (Common::List<gPanel *>::iterator it = contents.reverse_begin(); it != contents.end(); --it) {
ctl = *it;
invArea = bound(invArea, ctl->getExtent());
}
window.update(invArea);
}
}
void gPanelList::draw(void) {
gControl *ctl;
gPanel *ctl;
if (displayEnabled())
if (enabled) {
for (ctl = (gControl *)contents.last();
ctl;
ctl = (gControl *)ctl->prev()) {
if (ctl->getEnabled()) {
for (Common::List<gPanel *>::iterator it = contents.reverse_begin(); it != contents.end(); --it) {
ctl = *it;
if (ctl->getEnabled())
ctl->draw();
}
}
}
}
@@ -326,47 +326,46 @@ void gPanelList::drawClipped(
gPort &port,
const Point16 &offset,
const Rect16 &r) {
gControl *ctl;
gPanel *ctl;
Point16 tmpOffset = offset - Point16(extent.x, extent.y);
Rect16 tmpR = r - Point16(extent.x, extent.y);
if (displayEnabled())
if (enabled) {
for (ctl = (gControl *)contents.last();
ctl;
ctl = (gControl *)ctl->prev()) {
if (ctl->getEnabled()) {
for (Common::List<gPanel *>::iterator it = contents.reverse_begin(); it != contents.end(); --it) {
ctl = *it;
if (ctl->getEnabled())
ctl->drawClipped(port, tmpOffset, tmpR);
}
}
}
}
gPanel *gPanelList::hitTest(const Point16 &p) {
gControl *ctl;
gPanel *result;
gPanel *ctl;
gPanel *result;
if (enabled && !ghosted) {
for (ctl = (gControl *)contents.first();
ctl;
ctl = (gControl *)ctl->next()) {
if ((result = ctl->hitTest(p)) != NULL) return result;
for (Common::List<gPanel *>::iterator it = contents.begin(); it != contents.end(); ++it) {
ctl = *it;
if ((result = ctl->hitTest(p)) != NULL)
return result;
}
}
return NULL;
}
gPanel *gPanelList::keyTest(int16 key) {
gControl *ctl;
gPanel *ctl;
gPanel *result;
if (enabled && !ghosted) {
for (ctl = (gControl *)contents.last();
ctl;
ctl = (gControl *)ctl->prev()) {
if ((result = ctl->keyTest(key)) != NULL) return result;
for (Common::List<gPanel *>::iterator it = contents.reverse_begin(); it != contents.end(); --it) {
ctl = *it;
if ((result = ctl->keyTest(key)) != NULL)
return result;
}
}
return NULL;
}
@@ -429,7 +428,7 @@ bool gWindow::open(void) {
// Send a "pointer-leave" message to mouse panel.
G_BASE.leavePanel();
G_BASE.windowList.addHead(*this);
G_BASE.windowList.push_front(this);
G_BASE.activeWindow = this;
G_BASE.setActive(NULL);
@@ -461,9 +460,9 @@ void gWindow::close(void) {
// remove this window from the window list.
remove();
G_BASE.windowList.remove(this);
G_BASE.mouseWindow = G_BASE.activeWindow = (gWindow *)G_BASE.windowList.first();
G_BASE.mouseWindow = G_BASE.activeWindow = G_BASE.windowList.front();
G_BASE.mousePanel = G_BASE.activePanel = NULL;
}
@@ -472,8 +471,8 @@ void gWindow::close(void) {
void gWindow::toFront(void) { // re-order the windows
if (!isOpen()) return;
remove();
G_BASE.windowList.addHead(*this);
G_BASE.windowList.remove(this);
G_BASE.windowList.push_front(this);
G_BASE.activePanel = NULL;
G_BASE.activeWindow = this;
@@ -519,7 +518,7 @@ void gWindow::setExtent(const Rect16 &r) {
// insert window into window list
void gWindow::insert(void) {
G_BASE.windowList.addHead(*this);
G_BASE.windowList.push_front(this);
}
@@ -609,7 +608,7 @@ gControl::gControl(gPanelList &list, const Rect16 &box, const char *title_, uint
// Add control to the window's control list.
list.contents.addTail(*this);
list.contents.push_back(this);
}
gControl::gControl(gPanelList &list, const Rect16 &box, gPixelMap &img, uint16 ident,
@@ -618,11 +617,11 @@ gControl::gControl(gPanelList &list, const Rect16 &box, gPixelMap &img, uint16 i
// Add control to the window's control list.
list.contents.addTail(*this);
list.contents.push_back(this);
}
gControl::~gControl() {
remove();
window.contents.remove(this);
}
gControl::gControl(gPanelList &list, const StaticRect &box, const char *title_, uint16 ident,
@@ -631,7 +630,7 @@ gControl::gControl(gPanelList &list, const StaticRect &box, const char *title_,
// Add control to the window's control list.
list.contents.addTail(*this);
list.contents.push_back(this);
}
void gControl::enable(bool abled) {
@@ -838,9 +837,8 @@ void gToolBase::handleMouse(Common::Event &event, uint32 time) {
if (!activePanel /* && !ms.right */) {
// If the point is within the window
for (w = (gWindow *)windowList.first();
w;
w = (gWindow *)w->next()) {
for (Common::List<gWindow *>::iterator it = windowList.begin(); it != windowList.end(); ++it) {
w = *it;
if (w->extent.ptInside(_curMouseState.pos) || w->isModal()) {
// Set up the pick position relative to the window
@@ -998,7 +996,7 @@ void gToolBase::leavePanel(void) {
void gToolBase::handleKeyStroke(Common::Event &event) {
gWindow *w = activeWindow;
gControl *ctl;
gPanel *ctl;
uint16 key = event.kbd.ascii; // FIXME
uint16 qualifier = 0;
@@ -1035,7 +1033,7 @@ void gToolBase::handleKeyStroke(Common::Event &event) {
if (k != 0) {
k = toupper(k);
if ((ctl = (gControl *)w->keyTest(k)) != NULL) {
if ((ctl = w->keyTest(k)) != NULL) {
if (activePanel == ctl) return;
if (activePanel) activePanel->deactivate();
if (ctl->activate(gEventKeyDown)) {
+17 -10
View File
@@ -27,7 +27,6 @@
#ifndef SAGA2_PANEL_H
#define SAGA2_PANEL_H
#include "saga2/dlist.h"
#include "saga2/input.h"
#include "saga2/vdraw.h"
@@ -124,7 +123,7 @@ typedef void AppFunc(gEvent &);
gPanel class: The basic user interface element
* ===================================================================== */
class gPanel : public DNode {
class gPanel {
friend class gToolBase;
friend class gWindow;
@@ -247,6 +246,8 @@ public:
gPanelList class: A list of panels
* ===================================================================== */
class gControl;
class gPanelList : public gPanel {
friend class gControl;
@@ -257,7 +258,7 @@ class gPanelList : public gPanel {
protected:
DList contents; // list of panels
Common::List<gPanel *> contents; // list of panels
gPanelList(gWindow &, const Rect16 &, char *, uint16, AppFunc *cmd = NULL);
@@ -283,13 +284,13 @@ public:
};
inline void gPanel::moveToFront(gPanelList &l) {
remove();
l.contents.addHead(*this);
l.contents.remove(this);
l.contents.push_front(this);
}
inline void gPanel::moveToBack(gPanelList &l) {
remove();
l.contents.addTail(*this);
l.contents.remove(this);
l.contents.push_back(this);
}
/* ===================================================================== *
@@ -470,7 +471,7 @@ class gToolBase {
// windows
DList windowList; // list of windows
Common::List<gWindow *> windowList; // list of windows
gWindow *mouseWindow, // window mouse is in
*activeWindow; // current active window
gPanel *mousePanel, // panel that mouse is in
@@ -514,11 +515,17 @@ public:
void handleMouse(Common::Event &event, uint32 time);
void handleKeyStroke(Common::Event &event);
void handleTimerTick(int32 tick);
Common::List<gWindow *>::iterator topWindowIterator(void) {
return windowList.end();
}
Common::List<gWindow *>::iterator bottomWindowIterator(void) {
return windowList.reverse_begin();
}
gWindow *topWindow(void) {
return (gWindow *)windowList.first();
return windowList.front();
}
gWindow *bottomWindow(void) {
return (gWindow *)windowList.last();
return windowList.back();
}
bool isMousePanel(gPanel *p) {
return (mousePanel != NULL) ? (p == mousePanel) : (p == topWindow());
-1
View File
@@ -28,7 +28,6 @@
#define SAGA2_SPEECH_H
#include "saga2/objects.h"
#include "saga2/dlist.h"
namespace Saga2 {
-1
View File
@@ -28,7 +28,6 @@
#define SAGA2_TIMERS_H
#include "saga2/idtypes.h"
#include "saga2/dlist.h"
#include "saga2/calender.h"
#include "saga2/objects.h"