Initial commit
This commit is contained in:
39
engines/ultima/nuvie/misc/actor_list.h
Normal file
39
engines/ultima/nuvie/misc/actor_list.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_MISC_ACTOR_LIST_H
|
||||
#define NUVIE_MISC_ACTOR_LIST_H
|
||||
|
||||
// include this if using ActorList
|
||||
#include "ultima/shared/std/containers.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Actor;
|
||||
|
||||
typedef Std::vector<Actor *> ActorList;
|
||||
typedef Std::vector<Actor *>::iterator ActorIterator;
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
87
engines/ultima/nuvie/misc/call_back.h
Normal file
87
engines/ultima/nuvie/misc/call_back.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_MISC_CALLBACK_H
|
||||
#define NUVIE_MISC_CALLBACK_H
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class CallBack;
|
||||
|
||||
// general messages
|
||||
typedef enum {
|
||||
CB_TIMED, /* timer fired (data=uint32:time) */
|
||||
|
||||
ANIM_CB_DONE, /* animation has finished */
|
||||
ANIM_CB_HIT, /* animation hit a MapEntity (data=MapEntity) */
|
||||
ANIM_CB_HIT_WORLD, /* animation hit some other tile on the map (data=MapCoord) */
|
||||
|
||||
EFFECT_CB_COMPLETE, /* effect has finished */
|
||||
|
||||
CB_DATA_READY, /* some data is ready to be retrieved (data=char)*/
|
||||
MSGSCROLL_CB_TEXT_READY, /* text is ready to be retrieved (data=Std::string)*/
|
||||
CB_INPUT_CANCELED /* input canceled by user */
|
||||
} CallbackMessage;
|
||||
|
||||
|
||||
/* Classes inheriting this can send & receive callback messages.
|
||||
*/
|
||||
class CallBack {
|
||||
protected:
|
||||
char *callback_user_data; // data set by Caller
|
||||
CallBack *callback_target; // Caller: default CallBack that message() sends to
|
||||
|
||||
public:
|
||||
CallBack() {
|
||||
callback_user_data = nullptr;
|
||||
callback_target = nullptr;
|
||||
}
|
||||
virtual ~CallBack() { }
|
||||
|
||||
// receive message
|
||||
virtual uint16 callback(uint16 msg, CallBack *caller, void *data = nullptr) {
|
||||
DEBUG(0, LEVEL_WARNING, "Unhandled callback. msg (%x)\n", msg);
|
||||
return 0;
|
||||
}
|
||||
// send message
|
||||
uint16 message(uint16 msg, void *msg_data = nullptr, void *my_data = nullptr) {
|
||||
if (my_data)
|
||||
set_user_data(my_data);
|
||||
callback_target->set_user_data(callback_user_data);
|
||||
|
||||
return (callback_target->callback(msg, this, msg_data));
|
||||
}
|
||||
|
||||
void set_user_data(void *user_data) {
|
||||
callback_user_data = (char *)user_data;
|
||||
}
|
||||
void set_target(CallBack *t) {
|
||||
callback_target = t;
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
459
engines/ultima/nuvie/misc/iavl_tree.cpp
Normal file
459
engines/ultima/nuvie/misc/iavl_tree.cpp
Normal file
@@ -0,0 +1,459 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/misc/iavl_tree.h"
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static iAVLNode *iAVLCloseSearchNode(iAVLTree const *avltree, iAVLKey key);
|
||||
static void iAVLRebalanceNode(iAVLTree *avltree, iAVLNode *avlnode);
|
||||
static void iAVLFreeBranch(iAVLNode *avlnode, void (freeitem)(void *item));
|
||||
static void iAVLFillVacancy(iAVLTree *avltree,
|
||||
iAVLNode *origparent, iAVLNode **superparent,
|
||||
iAVLNode *left, iAVLNode *right);
|
||||
|
||||
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define L_DEPTH(n) ((n)->left ? (n)->left->depth : 0)
|
||||
#define R_DEPTH(n) ((n)->right ? (n)->right->depth : 0)
|
||||
#define CALC_DEPTH(n) (MAX(L_DEPTH(n), R_DEPTH(n)) + 1)
|
||||
|
||||
|
||||
/*
|
||||
* AVLAllocTree:
|
||||
* Allocate memory for a new AVL tree and set the getkey function for
|
||||
* that tree. The getkey function should take an item and return an
|
||||
* AVLKey that is to be used for indexing this object in the AVL tree.
|
||||
* On success, a pointer to the malloced AVLTree is returned. If there
|
||||
* was a malloc failure, then nullptr is returned.
|
||||
*/
|
||||
iAVLTree *iAVLAllocTree(iAVLKey(*getkey)(void const *item)) {
|
||||
iAVLTree *rc;
|
||||
|
||||
rc = (iAVLTree *)malloc(sizeof(iAVLTree));
|
||||
if (rc == nullptr)
|
||||
return nullptr;
|
||||
|
||||
rc->top = nullptr;
|
||||
rc->count = 0;
|
||||
rc->getkey = getkey;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* AVLFreeTree:
|
||||
* Free all memory used by this AVL tree. If freeitem is not nullptr, then
|
||||
* it is assumed to be a destructor for the items reference in the AVL
|
||||
* tree, and they are deleted as well.
|
||||
*/
|
||||
void iAVLFreeTree(iAVLTree *avltree, void (freeitem)(void *item)) {
|
||||
iAVLCleanTree(avltree, freeitem);
|
||||
free(avltree);
|
||||
}
|
||||
|
||||
void iAVLCleanTree(iAVLTree *avltree, void (freeitem)(void *item)) {
|
||||
if (avltree->top)
|
||||
iAVLFreeBranch(avltree->top, freeitem);
|
||||
|
||||
avltree->top = nullptr;
|
||||
avltree->count = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* AVLInsert:
|
||||
* Create a new node and insert an item there.
|
||||
*
|
||||
* Returns 0 on success,
|
||||
* -1 on malloc failure,
|
||||
* 3 if duplicate key.
|
||||
*/
|
||||
int iAVLInsert(iAVLTree *avltree, void *item) {
|
||||
iAVLNode *newnode;
|
||||
iAVLNode *node;
|
||||
iAVLNode *balnode;
|
||||
iAVLNode *nextbalnode;
|
||||
|
||||
newnode = (iAVLNode *)malloc(sizeof(iAVLNode));
|
||||
if (newnode == nullptr)
|
||||
return -1;
|
||||
|
||||
newnode->key = avltree->getkey(item);
|
||||
newnode->item = item;
|
||||
newnode->depth = 1;
|
||||
newnode->left = nullptr;
|
||||
newnode->right = nullptr;
|
||||
newnode->parent = nullptr;
|
||||
|
||||
if (avltree->top != nullptr) {
|
||||
node = iAVLCloseSearchNode(avltree, newnode->key);
|
||||
|
||||
if (!iAVLKey_cmp(avltree, node->key, newnode->key)) {
|
||||
free(newnode);
|
||||
return 3;
|
||||
}
|
||||
|
||||
newnode->parent = node;
|
||||
|
||||
if (iAVLKey_cmp(avltree, newnode->key, node->key) < 0) {
|
||||
node->left = newnode;
|
||||
node->depth = CALC_DEPTH(node);
|
||||
}
|
||||
|
||||
else {
|
||||
node->right = newnode;
|
||||
node->depth = CALC_DEPTH(node);
|
||||
}
|
||||
|
||||
for (balnode = node->parent; balnode; balnode = nextbalnode) {
|
||||
nextbalnode = balnode->parent;
|
||||
iAVLRebalanceNode(avltree, balnode);
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
avltree->top = newnode;
|
||||
}
|
||||
|
||||
avltree->count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* iAVLSearch:
|
||||
* Return a pointer to the item with the given key in the AVL tree. If
|
||||
* no such item is in the tree, then nullptr is returned.
|
||||
*/
|
||||
void *iAVLSearch(iAVLTree const *avltree, iAVLKey key) {
|
||||
iAVLNode *node;
|
||||
|
||||
node = iAVLCloseSearchNode(avltree, key);
|
||||
|
||||
if (node && !iAVLKey_cmp(avltree, node->key, key))
|
||||
return node->item;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* iAVLDelete:
|
||||
* Deletes the node with the given key. Does not delete the item at
|
||||
* that key. Returns 0 on success and -1 if a node with the given key
|
||||
* does not exist.
|
||||
*/
|
||||
int iAVLDelete(iAVLTree *avltree, iAVLKey key) {
|
||||
iAVLNode *avlnode;
|
||||
iAVLNode *origparent;
|
||||
iAVLNode **superparent;
|
||||
|
||||
avlnode = iAVLCloseSearchNode(avltree, key);
|
||||
if (avlnode == nullptr || iAVLKey_cmp(avltree, avlnode->key, key))
|
||||
return -1;
|
||||
|
||||
origparent = avlnode->parent;
|
||||
|
||||
if (origparent) {
|
||||
if (iAVLKey_cmp(avltree, avlnode->key, avlnode->parent->key) < 0)
|
||||
superparent = &(avlnode->parent->left);
|
||||
else
|
||||
superparent = &(avlnode->parent->right);
|
||||
} else
|
||||
superparent = &(avltree->top);
|
||||
|
||||
iAVLFillVacancy(avltree, origparent, superparent,
|
||||
avlnode->left, avlnode->right);
|
||||
free(avlnode);
|
||||
avltree->count--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* iAVLFirst:
|
||||
* Initializes an iAVLCursor object and returns the item with the lowest
|
||||
* key in the iAVLTree.
|
||||
*/
|
||||
void *iAVLFirst(iAVLCursor *avlcursor, iAVLTree const *avltree) {
|
||||
const iAVLNode *avlnode;
|
||||
|
||||
avlcursor->avltree = avltree;
|
||||
|
||||
if (avltree->top == nullptr) {
|
||||
avlcursor->curnode = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (avlnode = avltree->top;
|
||||
avlnode->left != nullptr;
|
||||
avlnode = avlnode->left);
|
||||
avlcursor->curnode = avlnode;
|
||||
return avlnode->item;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* iAVLNext:
|
||||
* Called after an iAVLFirst() call, this returns the item with the least
|
||||
* key that is greater than the last item returned either by iAVLFirst()
|
||||
* or a previous invokation of this function.
|
||||
*/
|
||||
void *iAVLNext(iAVLCursor *avlcursor) {
|
||||
const iAVLNode *avlnode;
|
||||
|
||||
avlnode = avlcursor->curnode;
|
||||
|
||||
if (avlnode->right != nullptr) {
|
||||
for (avlnode = avlnode->right;
|
||||
avlnode->left != nullptr;
|
||||
avlnode = avlnode->left);
|
||||
avlcursor->curnode = avlnode;
|
||||
return avlnode->item;
|
||||
}
|
||||
|
||||
while (avlnode->parent && avlnode->parent->left != avlnode) {
|
||||
avlnode = avlnode->parent;
|
||||
}
|
||||
|
||||
if (avlnode->parent == nullptr) {
|
||||
avlcursor->curnode = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
avlcursor->curnode = avlnode->parent;
|
||||
return avlnode->parent->item;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* iAVLCloseSearchNode:
|
||||
* Return a pointer to the node closest to the given key.
|
||||
* Returns nullptr if the AVL tree is empty.
|
||||
*/
|
||||
iAVLNode *iAVLCloseSearchNode(iAVLTree const *avltree, iAVLKey key) {
|
||||
iAVLNode *node;
|
||||
|
||||
node = avltree->top;
|
||||
|
||||
if (!node)
|
||||
return nullptr;
|
||||
|
||||
for (;;) {
|
||||
if (!iAVLKey_cmp(avltree, node->key, key))
|
||||
return node;
|
||||
|
||||
if (iAVLKey_cmp(avltree, node->key, key) < 0) {
|
||||
if (node->right)
|
||||
node = node->right;
|
||||
else
|
||||
return node;
|
||||
}
|
||||
|
||||
else {
|
||||
if (node->left)
|
||||
node = node->left;
|
||||
else
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* iAVLRebalanceNode:
|
||||
* Rebalances the AVL tree if one side becomes too heavy. This function
|
||||
* assumes that both subtrees are AVL trees with consistent data. This
|
||||
* function has the additional side effect of recalculating the depth of
|
||||
* the tree at this node. It should be noted that at the return of this
|
||||
* function, if a rebalance takes place, the top of this subtree is no
|
||||
* longer going to be the same node.
|
||||
*/
|
||||
void iAVLRebalanceNode(iAVLTree *avltree, iAVLNode *avlnode) {
|
||||
long depthdiff;
|
||||
iAVLNode *child;
|
||||
iAVLNode *gchild;
|
||||
iAVLNode *origparent;
|
||||
iAVLNode **superparent;
|
||||
|
||||
origparent = avlnode->parent;
|
||||
|
||||
if (origparent) {
|
||||
if (iAVLKey_cmp(avltree, avlnode->key, avlnode->parent->key) < 0)
|
||||
superparent = &(avlnode->parent->left);
|
||||
else
|
||||
superparent = &(avlnode->parent->right);
|
||||
} else
|
||||
superparent = &(avltree->top);
|
||||
|
||||
depthdiff = R_DEPTH(avlnode) - L_DEPTH(avlnode);
|
||||
|
||||
if (depthdiff <= -2) {
|
||||
child = avlnode->left;
|
||||
|
||||
if (L_DEPTH(child) >= R_DEPTH(child)) {
|
||||
avlnode->left = child->right;
|
||||
if (avlnode->left != nullptr)
|
||||
avlnode->left->parent = avlnode;
|
||||
avlnode->depth = CALC_DEPTH(avlnode);
|
||||
child->right = avlnode;
|
||||
if (child->right != nullptr)
|
||||
child->right->parent = child;
|
||||
child->depth = CALC_DEPTH(child);
|
||||
*superparent = child;
|
||||
child->parent = origparent;
|
||||
}
|
||||
|
||||
else {
|
||||
gchild = child->right;
|
||||
avlnode->left = gchild->right;
|
||||
if (avlnode->left != nullptr)
|
||||
avlnode->left->parent = avlnode;
|
||||
avlnode->depth = CALC_DEPTH(avlnode);
|
||||
child->right = gchild->left;
|
||||
if (child->right != nullptr)
|
||||
child->right->parent = child;
|
||||
child->depth = CALC_DEPTH(child);
|
||||
gchild->right = avlnode;
|
||||
if (gchild->right != nullptr)
|
||||
gchild->right->parent = gchild;
|
||||
gchild->left = child;
|
||||
if (gchild->left != nullptr)
|
||||
gchild->left->parent = gchild;
|
||||
gchild->depth = CALC_DEPTH(gchild);
|
||||
*superparent = gchild;
|
||||
gchild->parent = origparent;
|
||||
}
|
||||
}
|
||||
|
||||
else if (depthdiff >= 2) {
|
||||
child = avlnode->right;
|
||||
|
||||
if (R_DEPTH(child) >= L_DEPTH(child)) {
|
||||
avlnode->right = child->left;
|
||||
if (avlnode->right != nullptr)
|
||||
avlnode->right->parent = avlnode;
|
||||
avlnode->depth = CALC_DEPTH(avlnode);
|
||||
child->left = avlnode;
|
||||
if (child->left != nullptr)
|
||||
child->left->parent = child;
|
||||
child->depth = CALC_DEPTH(child);
|
||||
*superparent = child;
|
||||
child->parent = origparent;
|
||||
}
|
||||
|
||||
else {
|
||||
gchild = child->left;
|
||||
avlnode->right = gchild->left;
|
||||
if (avlnode->right != nullptr)
|
||||
avlnode->right->parent = avlnode;
|
||||
avlnode->depth = CALC_DEPTH(avlnode);
|
||||
child->left = gchild->right;
|
||||
if (child->left != nullptr)
|
||||
child->left->parent = child;
|
||||
child->depth = CALC_DEPTH(child);
|
||||
gchild->left = avlnode;
|
||||
if (gchild->left != nullptr)
|
||||
gchild->left->parent = gchild;
|
||||
gchild->right = child;
|
||||
if (gchild->right != nullptr)
|
||||
gchild->right->parent = gchild;
|
||||
gchild->depth = CALC_DEPTH(gchild);
|
||||
*superparent = gchild;
|
||||
gchild->parent = origparent;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
avlnode->depth = CALC_DEPTH(avlnode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* iAVLFreeBranch:
|
||||
* Free memory used by this node and its item. If the freeitem argument
|
||||
* is not nullptr, then that function is called on the items to free their
|
||||
* memory as well. In other words, the freeitem function is a
|
||||
* destructor for the items in the tree.
|
||||
*/
|
||||
void iAVLFreeBranch(iAVLNode *avlnode, void (freeitem)(void *item)) {
|
||||
if (avlnode->left)
|
||||
iAVLFreeBranch(avlnode->left, freeitem);
|
||||
if (avlnode->right)
|
||||
iAVLFreeBranch(avlnode->right, freeitem);
|
||||
if (freeitem != nullptr)
|
||||
freeitem(avlnode->item);
|
||||
free(avlnode);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* iAVLFillVacancy:
|
||||
* Given a vacancy in the AVL tree by it's parent, children, and parent
|
||||
* component pointer, fill that vacancy.
|
||||
*/
|
||||
void iAVLFillVacancy(iAVLTree *avltree,
|
||||
iAVLNode *origparent, iAVLNode **superparent,
|
||||
iAVLNode *left, iAVLNode *right) {
|
||||
iAVLNode *avlnode;
|
||||
iAVLNode *balnode;
|
||||
iAVLNode *nextbalnode;
|
||||
|
||||
if (left == nullptr) {
|
||||
if (right)
|
||||
right->parent = origparent;
|
||||
|
||||
*superparent = right;
|
||||
balnode = origparent;
|
||||
}
|
||||
|
||||
else {
|
||||
for (avlnode = left; avlnode->right != nullptr; avlnode = avlnode->right);
|
||||
|
||||
if (avlnode == left) {
|
||||
balnode = avlnode;
|
||||
} else {
|
||||
balnode = avlnode->parent;
|
||||
balnode->right = avlnode->left;
|
||||
if (balnode->right != nullptr)
|
||||
balnode->right->parent = balnode;
|
||||
avlnode->left = left;
|
||||
left->parent = avlnode;
|
||||
}
|
||||
|
||||
avlnode->right = right;
|
||||
if (right != nullptr)
|
||||
right->parent = avlnode;
|
||||
*superparent = avlnode;
|
||||
avlnode->parent = origparent;
|
||||
}
|
||||
|
||||
for (; balnode; balnode = nextbalnode) {
|
||||
nextbalnode = balnode->parent;
|
||||
iAVLRebalanceNode(avltree, balnode);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
75
engines/ultima/nuvie/misc/iavl_tree.h
Normal file
75
engines/ultima/nuvie/misc/iavl_tree.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_MISC_IAVL_TREE_H
|
||||
#define NUVIE_MISC_IAVL_TREE_H
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
/* typedef the keytype */
|
||||
// TODO: Clean up object manager so it isn't intermixing pointers and ints
|
||||
//typedef long iAVLKey;
|
||||
union iAVLKey {
|
||||
void *_ptr;
|
||||
long _int;
|
||||
};
|
||||
|
||||
/* Comparison function for integers is subtraction. */
|
||||
#define iAVLKey_cmp(tree, a, b) ((a._int) - (b._int))
|
||||
|
||||
|
||||
typedef struct _iAVLNode {
|
||||
iAVLKey key;
|
||||
long depth;
|
||||
void *item;
|
||||
struct _iAVLNode *parent;
|
||||
struct _iAVLNode *left;
|
||||
struct _iAVLNode *right;
|
||||
} iAVLNode;
|
||||
|
||||
|
||||
typedef struct {
|
||||
iAVLNode *top;
|
||||
long count;
|
||||
iAVLKey(*getkey)(const void *item);
|
||||
} iAVLTree;
|
||||
|
||||
|
||||
typedef struct {
|
||||
const iAVLTree *avltree;
|
||||
const iAVLNode *curnode;
|
||||
} iAVLCursor;
|
||||
|
||||
|
||||
extern iAVLTree *iAVLAllocTree(iAVLKey(*getkey)(void const *item));
|
||||
extern void iAVLFreeTree(iAVLTree *avltree, void (freeitem)(void *item));
|
||||
extern void iAVLCleanTree(iAVLTree *avltree, void (freeitem)(void *item));
|
||||
extern int iAVLInsert(iAVLTree *avltree, void *item);
|
||||
extern void *iAVLSearch(iAVLTree const *avltree, iAVLKey key);
|
||||
extern int iAVLDelete(iAVLTree *avltree, iAVLKey key);
|
||||
extern void *iAVLFirst(iAVLCursor *avlcursor, iAVLTree const *avltree);
|
||||
extern void *iAVLNext(iAVLCursor *avlcursor);
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
74
engines/ultima/nuvie/misc/map_entity.h
Normal file
74
engines/ultima/nuvie/misc/map_entity.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_MISC_MAP_ENTITY_H
|
||||
#define NUVIE_MISC_MAP_ENTITY_H
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Actor;
|
||||
class MapCoord;
|
||||
class NuvieAnim;
|
||||
class Obj;
|
||||
|
||||
typedef enum {
|
||||
ENT_NOTHING = 0,
|
||||
ENT_ACTOR,
|
||||
ENT_OBJ,
|
||||
ENT_ANIM
|
||||
} EntityType;
|
||||
|
||||
/* Any object on the map ("in the world") that isn't part of the map.
|
||||
* WARNING: It just points to another object, and doesn't copy it.
|
||||
*/
|
||||
typedef struct MapEntity_s {
|
||||
EntityType entity_type;
|
||||
union {
|
||||
char *data;
|
||||
Actor *actor;
|
||||
Obj *obj;
|
||||
NuvieAnim *anim;
|
||||
};
|
||||
MapEntity_s() {
|
||||
entity_type = ENT_NOTHING;
|
||||
data = nullptr;
|
||||
}
|
||||
MapEntity_s(Actor *a) {
|
||||
entity_type = ENT_ACTOR;
|
||||
actor = a;
|
||||
}
|
||||
MapEntity_s(Obj *o) {
|
||||
entity_type = ENT_OBJ;
|
||||
obj = o;
|
||||
}
|
||||
MapEntity_s(NuvieAnim *a) {
|
||||
entity_type = ENT_ANIM;
|
||||
anim = a;
|
||||
}
|
||||
} MapEntity;
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
81
engines/ultima/nuvie/misc/sdl_compat.cpp
Normal file
81
engines/ultima/nuvie/misc/sdl_compat.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/misc/sdl_compat.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "common/system.h"
|
||||
#include "common/events.h"
|
||||
#include "common/file.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "graphics/palette.h"
|
||||
#include "image/bmp.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
uint32 SDL_GetTicks() {
|
||||
return g_system->getMillis();
|
||||
}
|
||||
|
||||
int SDL_BlitSurface(const Graphics::ManagedSurface *src, const Common::Rect *srcrect,
|
||||
Graphics::ManagedSurface *dst, Common::Rect *dstrect) {
|
||||
Common::Rect srcRect = srcrect ? *srcrect : Common::Rect(0, 0, src->w, src->h);
|
||||
Common::Point destPos = dstrect ? Common::Point(dstrect->left, dstrect->top) : Common::Point();
|
||||
|
||||
dst->transBlitFrom(*src, srcRect, destPos, (uint)-1);
|
||||
|
||||
if (dstrect) {
|
||||
dstrect->setWidth(srcRect.width());
|
||||
dstrect->setHeight(srcRect.height());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_FillRect(Graphics::ManagedSurface *surf, const Common::Rect *rect, uint color) {
|
||||
surf->fillRect(rect ? *rect : Common::Rect(0, 0, surf->w, surf->h), color);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *SDL_LoadBMP(const Common::Path &filename) {
|
||||
Common::File f;
|
||||
Image::BitmapDecoder decoder;
|
||||
|
||||
if (!f.open(filename))
|
||||
error("Could not open file - %s", filename.toString().c_str());
|
||||
if (!decoder.loadStream(f))
|
||||
error("Could not load bitmap - %s", filename.toString().c_str());
|
||||
|
||||
const Graphics::Surface *src = decoder.getSurface();
|
||||
Screen *const screen = Game::get_game()->get_screen();
|
||||
assert(screen);
|
||||
Graphics::ManagedSurface *const screenSurface = screen->get_sdl_surface();
|
||||
assert(screenSurface);
|
||||
Graphics::ManagedSurface *dest = new Graphics::ManagedSurface(src->w, src->h, screenSurface->format);
|
||||
dest->blitFrom(*src, &decoder.getPalette());
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
44
engines/ultima/nuvie/misc/sdl_compat.h
Normal file
44
engines/ultima/nuvie/misc/sdl_compat.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_MISC_SDL_COMPAT_H
|
||||
#define NUVIE_MISC_SDL_COMPAT_H
|
||||
|
||||
#include "common/events.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
#define SDL_TRUE 1
|
||||
|
||||
#define SDL_SWSURFACE 0
|
||||
|
||||
extern uint32 SDL_GetTicks();
|
||||
extern int SDL_BlitSurface(const Graphics::ManagedSurface *src, const Common::Rect *srcrect,
|
||||
Graphics::ManagedSurface *dst, Common::Rect *dstrect);
|
||||
extern int SDL_FillRect(Graphics::ManagedSurface *surf, const Common::Rect *rect, uint color);
|
||||
extern Graphics::ManagedSurface *SDL_LoadBMP(const Common::Path &filename);
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
95
engines/ultima/nuvie/misc/u6_line_walker.cpp
Normal file
95
engines/ultima/nuvie/misc/u6_line_walker.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/misc/u6_line_walker.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
U6LineWalker::U6LineWalker(uint32 sx, uint32 sy, uint32 ex, uint32 ey)
|
||||
: start_x(sx), start_y(sy), end_x(ex), end_y(ey), cur_x(sx), cur_y(sy), cur_step(0) {
|
||||
sint32 delta_x = end_x - start_x;
|
||||
sint32 delta_y = end_y - start_y;
|
||||
|
||||
yoffset[0] = 0;
|
||||
if (delta_x >= 0) {
|
||||
xoffset[0] = 1;
|
||||
xoffset[1] = 1;
|
||||
} else {
|
||||
delta_x = -delta_x;
|
||||
xoffset[0] = -1;
|
||||
xoffset[1] = -1;
|
||||
}
|
||||
|
||||
if (delta_y >= 0) {
|
||||
yoffset[1] = 1;
|
||||
} else {
|
||||
delta_y = -delta_y;
|
||||
yoffset[1] = -1;
|
||||
}
|
||||
|
||||
if (delta_x < delta_y) {
|
||||
sint32 tmp_var = delta_x;
|
||||
delta_x = delta_y;
|
||||
delta_y = tmp_var;
|
||||
yoffset[0] = yoffset[1];
|
||||
xoffset[1] = xoffset[0];
|
||||
xoffset[0] = 0;
|
||||
}
|
||||
|
||||
max_length = delta_x;
|
||||
|
||||
line_counter = delta_y + delta_y - delta_x;
|
||||
line_inc[0] = delta_y + delta_y;
|
||||
line_inc[1] = (delta_y - delta_x) * 2;
|
||||
}
|
||||
|
||||
U6LineWalker::~U6LineWalker() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
|
||||
bool U6LineWalker::step() {
|
||||
if (cur_step >= max_length)
|
||||
return false;
|
||||
|
||||
uint8 idx = line_counter < 0 ? 0 : 1;
|
||||
|
||||
line_counter += line_inc[idx];
|
||||
cur_x += xoffset[idx];
|
||||
cur_y += yoffset[idx];
|
||||
|
||||
cur_step++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool U6LineWalker::next(uint32 *x, uint32 *y) {
|
||||
bool ret = step();
|
||||
|
||||
*x = cur_x;
|
||||
*y = cur_y;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
56
engines/ultima/nuvie/misc/u6_line_walker.h
Normal file
56
engines/ultima/nuvie/misc/u6_line_walker.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_MISC_U6_LINE_WALKER_H
|
||||
#define NUVIE_MISC_U6_LINE_WALKER_H
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class U6LineWalker {
|
||||
protected:
|
||||
uint32 start_x, start_y;
|
||||
uint32 end_x, end_y;
|
||||
|
||||
sint32 xoffset[2], yoffset[2];
|
||||
sint32 line_inc[2];
|
||||
sint32 line_counter;
|
||||
|
||||
uint32 cur_x, cur_y;
|
||||
uint32 max_length;
|
||||
|
||||
uint32 cur_step;
|
||||
|
||||
public:
|
||||
U6LineWalker(uint32 sx, uint32 sy, uint32 ex, uint32 ey);
|
||||
virtual ~U6LineWalker();
|
||||
|
||||
bool step();
|
||||
bool next(uint32 *x, uint32 *y);
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
244
engines/ultima/nuvie/misc/u6_list.cpp
Normal file
244
engines/ultima/nuvie/misc/u6_list.cpp
Normal file
@@ -0,0 +1,244 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_llist.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
void retainU6Link(U6Link *link) {
|
||||
if (link)
|
||||
link->ref_count++;
|
||||
}
|
||||
|
||||
void releaseU6Link(U6Link *link) {
|
||||
if (link) {
|
||||
link->ref_count--;
|
||||
if (link->ref_count == 0)
|
||||
delete link;
|
||||
}
|
||||
}
|
||||
|
||||
//use locally to cleanup the pointers when unlinking from list.
|
||||
inline void deleteU6Link(U6Link *link) {
|
||||
|
||||
if (link->ref_count == 1)
|
||||
delete link;
|
||||
else {
|
||||
link->ref_count--;
|
||||
link->data = nullptr;
|
||||
link->prev = link->next = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
U6LList::U6LList() : head(nullptr), tail(nullptr) {
|
||||
}
|
||||
|
||||
U6LList::~U6LList() {
|
||||
removeAll();
|
||||
}
|
||||
|
||||
bool U6LList::add(void *data) {
|
||||
U6Link *link;
|
||||
|
||||
link = new U6Link;
|
||||
if (link == nullptr)
|
||||
return false;
|
||||
|
||||
if (tail == nullptr)
|
||||
head = tail = link;
|
||||
else {
|
||||
link->prev = tail;
|
||||
tail->next = link;
|
||||
tail = link;
|
||||
}
|
||||
|
||||
link->data = data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool U6LList::addAtPos(uint32 pos, void *data) {
|
||||
uint32 i;
|
||||
U6Link *link, *prev, *new_link;
|
||||
|
||||
new_link = new U6Link;
|
||||
if (new_link == nullptr)
|
||||
return false;
|
||||
|
||||
new_link->data = data;
|
||||
|
||||
if (pos == 0 || head == nullptr) { // pos at head or list empty
|
||||
if (head != nullptr)
|
||||
head->prev = new_link;
|
||||
new_link->next = head;
|
||||
head = new_link;
|
||||
if (tail == nullptr)
|
||||
tail = head;
|
||||
} else {
|
||||
prev = nullptr;
|
||||
for (link = head, i = 0; link != nullptr && i < pos; i++) {
|
||||
prev = link;
|
||||
link = link->next;
|
||||
}
|
||||
|
||||
if (prev == tail) {
|
||||
new_link->prev = tail;
|
||||
tail->next = new_link;
|
||||
tail = new_link;
|
||||
} else {
|
||||
new_link->prev = prev;
|
||||
new_link->next = prev->next;
|
||||
prev->next = new_link;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 U6LList::findPos(void *data) {
|
||||
U6Link *link;
|
||||
uint32 pos;
|
||||
|
||||
for (pos = 0, link = start(); link != nullptr; link = link->next, pos++) {
|
||||
if (link->data == data)
|
||||
return pos;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//replace the first instance of old with new.
|
||||
bool U6LList::replace(void *old_data, void *new_data) {
|
||||
U6Link *link;
|
||||
|
||||
for (link = start(); link != nullptr; link = link->next) {
|
||||
if (link->data == old_data) {
|
||||
link->data = new_data;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool U6LList::remove(void *data) {
|
||||
U6Link *link;
|
||||
U6Link *prev;
|
||||
|
||||
if (head == nullptr)
|
||||
return false;
|
||||
|
||||
if (head->data == data) { // remove head
|
||||
link = head;
|
||||
head = head->next;
|
||||
if (head == nullptr) // empty list
|
||||
tail = nullptr;
|
||||
else
|
||||
head->prev = nullptr;
|
||||
|
||||
deleteU6Link(link);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
for (link = prev = head; link != nullptr;) {
|
||||
if (link->data == data) {
|
||||
prev->next = link->next;
|
||||
|
||||
if (link == tail)
|
||||
tail = prev;
|
||||
|
||||
deleteU6Link(link);
|
||||
|
||||
if (link != prev && prev->next) {
|
||||
link = prev->next;
|
||||
link->prev = prev;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
prev = link;
|
||||
link = link->next;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool U6LList::removeAll() {
|
||||
U6Link *tmp_link, *link;
|
||||
|
||||
for (link = head; link != nullptr;) {
|
||||
tmp_link = link;
|
||||
link = link->next;
|
||||
|
||||
deleteU6Link(tmp_link);
|
||||
}
|
||||
|
||||
head = nullptr;
|
||||
tail = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32 U6LList::count() const {
|
||||
uint32 i;
|
||||
U6Link *link;
|
||||
|
||||
for (i = 0, link = head; link != nullptr; link = link->next) {
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
U6Link *U6LList::start() {
|
||||
return head;
|
||||
}
|
||||
|
||||
U6Link *U6LList::end() {
|
||||
return tail;
|
||||
}
|
||||
|
||||
const U6Link *U6LList::start() const {
|
||||
return head;
|
||||
}
|
||||
|
||||
const U6Link *U6LList::end() const {
|
||||
return tail;
|
||||
}
|
||||
|
||||
U6Link *U6LList::gotoPos(uint32 pos) {
|
||||
U6Link *link;
|
||||
uint32 i;
|
||||
|
||||
for (link = head, i = 0; link != nullptr && i < pos; i++)
|
||||
link = link->next;
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
77
engines/ultima/nuvie/misc/u6_llist.h
Normal file
77
engines/ultima/nuvie/misc/u6_llist.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_MISC_U6_LIST_H
|
||||
#define NUVIE_MISC_U6_LIST_H
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
#define U6LLIST_FREE_DATA true
|
||||
|
||||
struct U6Link {
|
||||
U6Link *next;
|
||||
U6Link *prev;
|
||||
void *data;
|
||||
uint8 ref_count;
|
||||
U6Link() {
|
||||
next = nullptr;
|
||||
prev = nullptr;
|
||||
data = nullptr;
|
||||
ref_count = 1;
|
||||
}
|
||||
};
|
||||
|
||||
void retainU6Link(U6Link *link);
|
||||
void releaseU6Link(U6Link *link);
|
||||
|
||||
class U6LList {
|
||||
U6Link *head;
|
||||
U6Link *tail;
|
||||
|
||||
public:
|
||||
|
||||
U6LList();
|
||||
~U6LList();
|
||||
|
||||
bool add(void *data);
|
||||
bool addAtPos(uint32 pos, void *data);
|
||||
|
||||
uint32 findPos(void *data);
|
||||
bool replace(void *old_data, void *new_data);
|
||||
|
||||
bool remove(void *data);
|
||||
bool removeAll();
|
||||
|
||||
uint32 count() const;
|
||||
|
||||
U6Link *start();
|
||||
U6Link *end();
|
||||
const U6Link *start() const;
|
||||
const U6Link *end() const;
|
||||
|
||||
U6Link *gotoPos(uint32 pos);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
726
engines/ultima/nuvie/misc/u6_misc.cpp
Normal file
726
engines/ultima/nuvie/misc/u6_misc.cpp
Normal file
@@ -0,0 +1,726 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/shared/std/containers.h"
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/file.h"
|
||||
#include "common/fs.h"
|
||||
#include "common/str.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
using namespace Std;
|
||||
|
||||
void Tokenise(const Std::string &str, Std::vector<Std::string> &tokens, char delimiter = ' ') {
|
||||
Std::string delimiters(delimiter);
|
||||
|
||||
// Skip delimiters at beginning.
|
||||
string::size_type lastPos = str.findFirstNotOf(delimiters, 0);
|
||||
|
||||
for (string::size_type pos = str.findFirstOf(delimiters, lastPos) ;
|
||||
string::npos != pos || string::npos != lastPos ;
|
||||
pos = str.findFirstOf(delimiters, lastPos)) {
|
||||
// Found a token, add it to the vector.
|
||||
tokens.push_back(str.substr(lastPos, pos - lastPos));
|
||||
// Skip delimiters. Note the "not_of"
|
||||
lastPos = str.findFirstNotOf(delimiters, pos);
|
||||
}
|
||||
}
|
||||
|
||||
Std::string config_get_game_key(const Configuration *config) {
|
||||
Std::string game_key, game_name;
|
||||
|
||||
config->value("config/GameName", game_name);
|
||||
|
||||
game_key.assign("config/");
|
||||
game_key.append(game_name);
|
||||
|
||||
return game_key;
|
||||
}
|
||||
|
||||
const char *get_game_tag(int game_type) {
|
||||
switch (game_type) {
|
||||
case NUVIE_GAME_U6 :
|
||||
return "U6";
|
||||
case NUVIE_GAME_MD :
|
||||
return "MD";
|
||||
case NUVIE_GAME_SE :
|
||||
return "SE";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void config_get_path(const Configuration *config, const Std::string &filename, Common::Path &path) {
|
||||
Std::string key, game_name;
|
||||
Common::Path game_dir, tmp_path;
|
||||
|
||||
config->value("config/GameName", game_name);
|
||||
|
||||
key.assign("config/");
|
||||
key.append(game_name);
|
||||
key.append("/gamedir");
|
||||
|
||||
config->pathFromValue(key, "", game_dir);
|
||||
|
||||
tmp_path = game_dir.appendComponent(filename);
|
||||
|
||||
path = tmp_path;
|
||||
}
|
||||
|
||||
int mkdir_recursive(const Common::Path &path, int mode) {
|
||||
#ifdef TODO
|
||||
vector<string> directories;
|
||||
string tmp_path;
|
||||
|
||||
Tokenise(path, directories, U6PATH_DELIMITER);
|
||||
|
||||
if (path.find(U6PATH_DELIMITER) == 0)
|
||||
tmp_path += U6PATH_DELIMITER;
|
||||
|
||||
for (const auto &dir : directories) {
|
||||
debug("%s, ", dir.c_str());
|
||||
|
||||
tmp_path += dir;
|
||||
tmp_path += U6PATH_DELIMITER;
|
||||
if (!directory_exists(tmp_path.c_str())) {
|
||||
#if defined(WIN32)
|
||||
int ret = mkdir(tmp_path.c_str());
|
||||
#else
|
||||
int ret = mkdir(tmp_path.c_str(), mode);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
error("TODO");
|
||||
#endif
|
||||
}
|
||||
|
||||
//return the uint8 game_type from a char string
|
||||
uint8 get_game_type(const char *string) {
|
||||
if (string != nullptr && strlen(string) >= 2) {
|
||||
if (strcmp("md", string) == 0 || strcmp("martian", string) == 0)
|
||||
return NUVIE_GAME_MD;
|
||||
if (strcmp("se", string) == 0 || strcmp("savage", string) == 0)
|
||||
return NUVIE_GAME_SE;
|
||||
if (strcmp("u6", string) == 0 || strcmp("ultima6", string) == 0)
|
||||
return NUVIE_GAME_U6;
|
||||
}
|
||||
|
||||
return NUVIE_GAME_NONE;
|
||||
}
|
||||
|
||||
nuvie_game_t get_game_type(const Configuration *config) {
|
||||
int game_type;
|
||||
config->value("config/GameType", game_type);
|
||||
|
||||
return (nuvie_game_t)game_type;
|
||||
}
|
||||
|
||||
void build_path(const Common::Path &path, const Std::string &filename, Common::Path &full_path) {
|
||||
full_path = path.appendComponent(filename);
|
||||
}
|
||||
|
||||
bool has_fmtowns_support(const Configuration *config) {
|
||||
Std::string townsdir;
|
||||
config->value("config/townsdir", townsdir, "");
|
||||
if (townsdir != "" && directory_exists(townsdir.c_str()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool directory_exists(const Common::Path &directory) {
|
||||
return Common::FSNode(directory).exists() ||
|
||||
Common::FSNode(ConfMan.getPath("path").joinInPlace(directory)).exists();
|
||||
}
|
||||
|
||||
bool file_exists(const Common::Path &path) {
|
||||
return Common::File::exists(path);
|
||||
}
|
||||
|
||||
void print_b(DebugLevelType level, uint8 num) {
|
||||
sint8 i;
|
||||
|
||||
for (i = 7; i >= 0; i--) {
|
||||
if (num & (1 << i))
|
||||
DEBUG(1, level, "1");
|
||||
else
|
||||
DEBUG(1, level, "0");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void print_b16(DebugLevelType level, uint16 num) {
|
||||
sint8 i;
|
||||
|
||||
for (i = 15; i >= 0; i--) {
|
||||
if (num & (1 << i))
|
||||
DEBUG(1, level, "1");
|
||||
else
|
||||
DEBUG(1, level, "0");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void print_indent(DebugLevelType level, uint8 indent) {
|
||||
uint16 i;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
DEBUG(1, level, " ");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void print_bool(DebugLevelType level, bool state, const char *yes, const char *no) {
|
||||
DEBUG(1, level, "%s", state ? yes : no);
|
||||
}
|
||||
|
||||
|
||||
void print_flags(DebugLevelType level, uint8 num, const char *f[8]) {
|
||||
Std::string complete_flags = "";
|
||||
print_b(level, num);
|
||||
if (num != 0)
|
||||
complete_flags += "(";
|
||||
for (uint32 i = 0; i < 8; i++)
|
||||
if ((num & (1 << i)) && f[i])
|
||||
complete_flags += f[i];
|
||||
if (num != 0)
|
||||
complete_flags += ")";
|
||||
DEBUG(1, level, "%s", complete_flags.c_str());
|
||||
}
|
||||
|
||||
|
||||
/* Where rect1 and rect2 merge, subtract and copy that rect to sub_rect.
|
||||
* Returns false if the rectangles don't intersect.
|
||||
*/
|
||||
bool subtract_rect(const Common::Rect *rect1, const Common::Rect *rect2, Common::Rect *sub_rect) {
|
||||
uint16 rect1_x2 = rect1->right, rect1_y2 = rect1->bottom;
|
||||
uint16 rect2_x2 = rect2->right, rect2_y2 = rect2->bottom;
|
||||
uint16 x1, x2, y1, y2;
|
||||
|
||||
if (line_in_rect(rect1->left, rect1->top, rect1_x2, rect1->top, rect2)
|
||||
|| line_in_rect(rect1_x2, rect1->top, rect1_x2, rect1_y2, rect2)
|
||||
|| line_in_rect(rect1->left, rect1->top, rect1->left, rect1_y2, rect2)
|
||||
|| line_in_rect(rect1->left, rect1_y2, rect1_x2, rect1_y2, rect2)) {
|
||||
x1 = rect2->left >= rect1->left ? rect2->left : rect1->left;
|
||||
y1 = rect2->top >= rect1->top ? rect2->top : rect1->top;
|
||||
x2 = rect2_x2 <= rect1_x2 ? rect2_x2 : rect1_x2;
|
||||
y2 = rect2_y2 <= rect1_y2 ? rect2_y2 : rect1_y2;
|
||||
} else
|
||||
return false;
|
||||
if (sub_rect) { // you can perform test without returning a subtraction
|
||||
sub_rect->left = x1;
|
||||
sub_rect->top = y1;
|
||||
sub_rect->setWidth(x2 - x1);
|
||||
sub_rect->setHeight(y2 - y1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *get_direction_name(NuvieDir dir) {
|
||||
switch (dir) {
|
||||
case NUVIE_DIR_N:
|
||||
return "north";
|
||||
case NUVIE_DIR_NE:
|
||||
return "Northeast";
|
||||
case NUVIE_DIR_E:
|
||||
return "East";
|
||||
case NUVIE_DIR_SE:
|
||||
return "Southeast";
|
||||
case NUVIE_DIR_S:
|
||||
return "South";
|
||||
case NUVIE_DIR_SW:
|
||||
return "Southwest";
|
||||
case NUVIE_DIR_W:
|
||||
return "West";
|
||||
case NUVIE_DIR_NW:
|
||||
return "Northwest";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "nowhere";
|
||||
}
|
||||
|
||||
/* Returns name of relative direction. 0,0 prints "nowhere".
|
||||
*/
|
||||
const char *get_direction_name(sint16 rel_x, sint16 rel_y) {
|
||||
return get_direction_name(get_direction_code(rel_x, rel_y));
|
||||
}
|
||||
|
||||
/* Gets the nuvie direction code from the original u6 direction code. */
|
||||
NuvieDir get_nuvie_dir_code(uint8 original_dir_code) {
|
||||
NuvieDir dir = NUVIE_DIR_NONE;
|
||||
//convert original direction into nuvie direction.
|
||||
//original
|
||||
// 701
|
||||
// 6 2
|
||||
// 543
|
||||
//
|
||||
// nuvie
|
||||
// 704
|
||||
// 3 1
|
||||
// 625
|
||||
switch (original_dir_code) {
|
||||
case 0:
|
||||
dir = NUVIE_DIR_N;
|
||||
break;
|
||||
case 1:
|
||||
dir = NUVIE_DIR_NE;
|
||||
break;
|
||||
case 2:
|
||||
dir = NUVIE_DIR_E;
|
||||
break;
|
||||
case 3:
|
||||
dir = NUVIE_DIR_SE;
|
||||
break;
|
||||
case 4:
|
||||
dir = NUVIE_DIR_S;
|
||||
break;
|
||||
case 5:
|
||||
dir = NUVIE_DIR_SW;
|
||||
break;
|
||||
case 6:
|
||||
dir = NUVIE_DIR_W;
|
||||
break;
|
||||
case 7:
|
||||
dir = NUVIE_DIR_NW;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
sint8 get_original_dir_code(NuvieDir nuvie_dir_code) {
|
||||
sint8 dir = -1;
|
||||
//convert nuvie direction into original direction.
|
||||
switch (nuvie_dir_code) {
|
||||
case NUVIE_DIR_N:
|
||||
dir = 0;
|
||||
break;
|
||||
case NUVIE_DIR_NE:
|
||||
dir = 1;
|
||||
break;
|
||||
case NUVIE_DIR_E:
|
||||
dir = 2;
|
||||
break;
|
||||
case NUVIE_DIR_SE:
|
||||
dir = 3;
|
||||
break;
|
||||
case NUVIE_DIR_S:
|
||||
dir = 4;
|
||||
break;
|
||||
case NUVIE_DIR_SW:
|
||||
dir = 5;
|
||||
break;
|
||||
case NUVIE_DIR_W:
|
||||
dir = 6;
|
||||
break;
|
||||
case NUVIE_DIR_NW:
|
||||
dir = 7;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
/* Returns direction code of relative direction.
|
||||
*/
|
||||
NuvieDir get_direction_code(sint16 rel_x, sint16 rel_y) {
|
||||
if (rel_x == 0 && rel_y < 0)
|
||||
return NUVIE_DIR_N;
|
||||
else if (rel_x > 0 && rel_y < 0)
|
||||
return NUVIE_DIR_NE;
|
||||
else if (rel_x > 0 && rel_y == 0)
|
||||
return NUVIE_DIR_E;
|
||||
else if (rel_x > 0 && rel_y > 0)
|
||||
return NUVIE_DIR_SE;
|
||||
else if (rel_x == 0 && rel_y > 0)
|
||||
return NUVIE_DIR_S;
|
||||
else if (rel_x < 0 && rel_y > 0)
|
||||
return NUVIE_DIR_SW;
|
||||
else if (rel_x < 0 && rel_y == 0)
|
||||
return NUVIE_DIR_W;
|
||||
else if (rel_x < 0 && rel_y < 0)
|
||||
return NUVIE_DIR_NW;
|
||||
|
||||
return NUVIE_DIR_NONE;
|
||||
}
|
||||
|
||||
NuvieDir get_reverse_direction(NuvieDir dir) {
|
||||
switch (dir) {
|
||||
case NUVIE_DIR_N :
|
||||
return NUVIE_DIR_S;
|
||||
case NUVIE_DIR_E :
|
||||
return NUVIE_DIR_W;
|
||||
case NUVIE_DIR_S :
|
||||
return NUVIE_DIR_N;
|
||||
case NUVIE_DIR_W :
|
||||
return NUVIE_DIR_E;
|
||||
|
||||
case NUVIE_DIR_NE :
|
||||
return NUVIE_DIR_SW;
|
||||
case NUVIE_DIR_SE :
|
||||
return NUVIE_DIR_NW;
|
||||
case NUVIE_DIR_SW :
|
||||
return NUVIE_DIR_NE;
|
||||
case NUVIE_DIR_NW :
|
||||
return NUVIE_DIR_SE;
|
||||
|
||||
case NUVIE_DIR_NONE :
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
return NUVIE_DIR_NONE;
|
||||
}
|
||||
|
||||
void get_relative_dir(NuvieDir dir, sint16 *rel_x, sint16 *rel_y) {
|
||||
switch (dir) {
|
||||
case NUVIE_DIR_N :
|
||||
*rel_x = 0;
|
||||
*rel_y = -1;
|
||||
break;
|
||||
case NUVIE_DIR_E :
|
||||
*rel_x = 1;
|
||||
*rel_y = 0;
|
||||
break;
|
||||
case NUVIE_DIR_S :
|
||||
*rel_x = 0;
|
||||
*rel_y = 1;
|
||||
break;
|
||||
case NUVIE_DIR_W :
|
||||
*rel_x = -1;
|
||||
*rel_y = 0;
|
||||
break;
|
||||
|
||||
case NUVIE_DIR_NE :
|
||||
*rel_x = 1;
|
||||
*rel_y = -1;
|
||||
break;
|
||||
case NUVIE_DIR_SE :
|
||||
*rel_x = 1;
|
||||
*rel_y = 1;
|
||||
break;
|
||||
case NUVIE_DIR_SW :
|
||||
*rel_x = -1;
|
||||
*rel_y = 1;
|
||||
break;
|
||||
case NUVIE_DIR_NW :
|
||||
*rel_x = -1;
|
||||
*rel_y = -1;
|
||||
break;
|
||||
|
||||
case NUVIE_DIR_NONE :
|
||||
default :
|
||||
*rel_x = 0;
|
||||
*rel_y = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int str_bsearch(const char *const str[], int max, const char *value) {
|
||||
int position;
|
||||
int begin = 0;
|
||||
int end = max - 1;
|
||||
int cond = 0;
|
||||
|
||||
while (begin <= end) {
|
||||
position = (begin + end) / 2;
|
||||
if ((cond = strcmp(str[position], value)) == 0)
|
||||
return position;
|
||||
else if (cond < 0)
|
||||
begin = position + 1;
|
||||
else
|
||||
end = position - 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define LINE_FRACTION 65536L
|
||||
|
||||
void draw_line_8bit(int sx, int sy, int ex, int ey, uint8 col, uint8 *pixels, uint16 w, uint16 h) {
|
||||
uint16 pitch = w;
|
||||
int xinc = 1;
|
||||
int yinc = 1;
|
||||
|
||||
if (sx == ex) {
|
||||
sx --;
|
||||
if (sy > ey) {
|
||||
yinc = -1;
|
||||
sy--;
|
||||
}
|
||||
} else {
|
||||
if (sx > ex) {
|
||||
sx--;
|
||||
xinc = -1;
|
||||
} else {
|
||||
ex--;
|
||||
}
|
||||
|
||||
if (sy > ey) {
|
||||
yinc = -1;
|
||||
sy--;
|
||||
ey--;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 *pixptr = (uint8 *)(pixels + pitch * sy + sx);
|
||||
uint8 *pixend = (uint8 *)(pixels + pitch * ey + ex);
|
||||
pitch = pitch * yinc;
|
||||
|
||||
int cury = sy;
|
||||
int curx = sx;
|
||||
int width = w;
|
||||
int height = h;
|
||||
bool no_clip = true;
|
||||
|
||||
if (sx >= width && ex >= width) return;
|
||||
if (sy >= height && ey >= height) return;
|
||||
if (sx < 0 && ex < 0) return;
|
||||
if (sy < 0 && ey < 0) return;
|
||||
|
||||
if (sy < 0 || sy >= height || sx < 0 || sx >= width) no_clip = false;
|
||||
if (ey < 0 || ey >= height || ex < 0 || ex >= width) no_clip = false;
|
||||
|
||||
// vertical
|
||||
if (sx == ex) {
|
||||
//Std::cout << "Vertical" << Std::endl;
|
||||
// start is below end
|
||||
while (pixptr != pixend) {
|
||||
if (no_clip || (cury >= 0 && cury < height)) *pixptr = col;
|
||||
pixptr += pitch;
|
||||
cury += yinc;
|
||||
}
|
||||
}
|
||||
// Horizontal
|
||||
else if (sy == ey) {
|
||||
//Std::cout << "Horizontal" << Std::endl;
|
||||
while (pixptr != pixend) {
|
||||
if (no_clip || (curx >= 0 && curx < width)) *pixptr = col;
|
||||
pixptr += xinc;
|
||||
curx += xinc;
|
||||
}
|
||||
}
|
||||
// Diagonal xdiff >= ydiff
|
||||
else if (ABS(sx - ex) >= ABS(sy - ey)) {
|
||||
//Std::cout << "Diagonal 1" << Std::endl;
|
||||
uint32 fraction = ABS((LINE_FRACTION * (sy - ey)) / (sx - ex));
|
||||
uint32 ycounter = 0;
|
||||
|
||||
for (; ;) {
|
||||
if ((no_clip || (cury >= 0 && cury < height && curx >= 0 && curx < width)))
|
||||
*pixptr = col;
|
||||
pixptr += xinc;
|
||||
if (curx == ex) break;
|
||||
curx += xinc;
|
||||
ycounter += fraction;
|
||||
|
||||
// Need to work out if we need to change line
|
||||
if (ycounter > LINE_FRACTION) {
|
||||
ycounter -= LINE_FRACTION;
|
||||
pixptr += pitch;
|
||||
cury += yinc;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Diagonal ydiff > xdiff
|
||||
else {
|
||||
//Std::cout << "Diagonal 2" << Std::endl;
|
||||
uint32 fraction = ABS((LINE_FRACTION * (sx - ex)) / (sy - ey));
|
||||
uint32 xcounter = 0;
|
||||
|
||||
for (; ;) {
|
||||
if ((no_clip || (cury >= 0 && cury < height && curx >= 0 && curx < width)))
|
||||
*pixptr = col;
|
||||
pixptr += pitch;
|
||||
if (cury == ey) break;
|
||||
cury += yinc;
|
||||
xcounter += fraction;
|
||||
|
||||
// Need to work out if we need to change line
|
||||
if (xcounter > LINE_FRACTION) {
|
||||
xcounter -= LINE_FRACTION;
|
||||
pixptr += xinc;
|
||||
curx += xinc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool string_i_compare(const Std::string &s1, const Std::string &s2) {
|
||||
return scumm_stricmp(s1.c_str(), s2.c_str()) == 0;
|
||||
}
|
||||
|
||||
void *nuvie_realloc(void *ptr, size_t size) {
|
||||
void *new_ptr = realloc(ptr, size);
|
||||
if (!new_ptr)
|
||||
free(ptr);
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
|
||||
uint32 sdl_getpixel(const Graphics::ManagedSurface *surface, int x, int y) {
|
||||
int bpp = surface->format.bytesPerPixel;
|
||||
/* Here p is the address to the pixel we want to retrieve */
|
||||
const byte *p = (const byte *)surface->getBasePtr(x, y);
|
||||
|
||||
switch (bpp) {
|
||||
case 1:
|
||||
return *p;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
return *(const uint16 *)p;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
error("TODO: RGB24 unsupported");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
return *(const uint32 *)p;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0; /* shouldn't happen, but avoids warnings */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void scaleLine8Bit(unsigned char *Target, const unsigned char *Source, int SrcWidth, int TgtWidth) {
|
||||
int NumPixels = TgtWidth;
|
||||
int IntPart = SrcWidth / TgtWidth;
|
||||
int FractPart = SrcWidth % TgtWidth;
|
||||
int E = 0;
|
||||
|
||||
while (NumPixels-- > 0) {
|
||||
*Target++ = *Source;
|
||||
Source += IntPart;
|
||||
E += FractPart;
|
||||
if (E >= TgtWidth) {
|
||||
E -= TgtWidth;
|
||||
Source++;
|
||||
} /* if */
|
||||
} /* while */
|
||||
}
|
||||
|
||||
// Coarse 2D scaling from https://web.archive.org/web/20111011173251/http://www.compuphase.com/graphic/scale.htm
|
||||
void scale_rect_8bit(const unsigned char *Source, unsigned char *Target, int SrcWidth, int SrcHeight,
|
||||
int TgtWidth, int TgtHeight) {
|
||||
int NumPixels = TgtHeight;
|
||||
int IntPart = (SrcHeight / TgtHeight) * SrcWidth;
|
||||
int FractPart = SrcHeight % TgtHeight;
|
||||
int E = 0;
|
||||
const unsigned char *PrevSource = nullptr;
|
||||
|
||||
while (NumPixels-- > 0) {
|
||||
if (Source == PrevSource) {
|
||||
memcpy(Target, Target - TgtWidth, TgtWidth * sizeof(*Target));
|
||||
} else {
|
||||
scaleLine8Bit(Target, Source, SrcWidth, TgtWidth);
|
||||
PrevSource = Source;
|
||||
} /* if */
|
||||
Target += TgtWidth;
|
||||
Source += IntPart;
|
||||
E += FractPart;
|
||||
if (E >= TgtHeight) {
|
||||
E -= TgtHeight;
|
||||
Source += SrcWidth;
|
||||
} /* if */
|
||||
} /* while */
|
||||
}
|
||||
|
||||
bool has_file_extension(const char *filename, const char *extension) {
|
||||
if (strlen(filename) > strlen(extension) &&
|
||||
scumm_stricmp((const char *)&filename[strlen(filename) - 4], extension) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16 wrap_signed_coord(sint16 coord, uint8 level) {
|
||||
uint16 width = MAP_SIDE_LENGTH(level);
|
||||
if (coord < 0) {
|
||||
return (uint16)(width + coord);
|
||||
}
|
||||
|
||||
return (uint16)coord % width;
|
||||
}
|
||||
|
||||
sint8 get_wrapped_rel_dir(sint16 p1, sint16 p2, uint8 level) {
|
||||
uint16 stride = MAP_SIDE_LENGTH(level);
|
||||
|
||||
sint16 ret = clamp(p1 - p2, -1, 1);
|
||||
|
||||
if (abs(p1 - p2) > stride / 2) {
|
||||
return -ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Std::string encode_xml_entity(const Std::string &s) {
|
||||
string ret;
|
||||
|
||||
for (const auto &c : s) {
|
||||
switch (c) {
|
||||
case '<':
|
||||
ret += "<";
|
||||
break;
|
||||
case '>':
|
||||
ret += ">";
|
||||
break;
|
||||
case '"':
|
||||
ret += """;
|
||||
break;
|
||||
case '\'':
|
||||
ret += "'";
|
||||
break;
|
||||
case '&':
|
||||
ret += "&";
|
||||
break;
|
||||
default:
|
||||
ret += c;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
117
engines/ultima/nuvie/misc/u6_misc.h
Normal file
117
engines/ultima/nuvie/misc/u6_misc.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_MISC_U6_MISC_H
|
||||
#define NUVIE_MISC_U6_MISC_H
|
||||
|
||||
/*
|
||||
* ultima/nuvie/misc/u6_misc.h
|
||||
* Nuvie
|
||||
*
|
||||
* Created by Eric Fry on Sat Jun 14 2003.
|
||||
* Copyright (c) 2003. All rights reserved.
|
||||
*
|
||||
*/
|
||||
#include "ultima/shared/std/string.h"
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "common/rect.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
|
||||
typedef enum {
|
||||
BLOCKED,
|
||||
CAN_MOVE,
|
||||
FORCE_MOVE
|
||||
} MovementStatus;
|
||||
|
||||
Std::string config_get_game_key(const Configuration *config);
|
||||
const char *get_game_tag(int game_type);
|
||||
void config_get_path(const Configuration *config, const Std::string &filename, Common::Path &path);
|
||||
uint8 get_game_type(const char *string);
|
||||
nuvie_game_t get_game_type(const Configuration *config);
|
||||
void build_path(const Common::Path &path, const Std::string &filename, Common::Path &full_path);
|
||||
bool directory_exists(const Common::Path &directory);
|
||||
bool file_exists(const Common::Path &path);
|
||||
void print_b(DebugLevelType level, uint8 num);
|
||||
void print_b16(DebugLevelType level, uint16 num);
|
||||
void print_indent(DebugLevelType level, uint8 indent);
|
||||
void print_bool(DebugLevelType level, bool state, const char *yes = "true", const char *no = "false");
|
||||
void print_flags(DebugLevelType level, uint8 num, const char *f[8]);
|
||||
bool subtract_rect(const Common::Rect *rect1, const Common::Rect *rect2, Common::Rect *sub_rect);
|
||||
NuvieDir get_nuvie_dir_code(uint8 original_dir_code);
|
||||
sint8 get_original_dir_code(NuvieDir nuvie_dir_code);
|
||||
NuvieDir get_direction_code(sint16 rel_x, sint16 rel_y);
|
||||
NuvieDir get_reverse_direction(NuvieDir dir);
|
||||
void get_relative_dir(NuvieDir dir, sint16 *rel_x, sint16 *rel_y);
|
||||
const char *get_direction_name(NuvieDir dir);
|
||||
const char *get_direction_name(sint16 rel_x, sint16 rel_y);
|
||||
int str_bsearch(const char *const str[], int max, const char *value);
|
||||
|
||||
/* Does line xy->x2y2 cross rect, to any extent?
|
||||
*/
|
||||
inline bool line_in_rect(uint16 x1, uint16 y1, uint16 x2, uint16 y2, const Common::Rect *rect) {
|
||||
uint16 rx2 = rect->right, ry2 = rect->bottom;
|
||||
return (((y1 >= rect->top && y1 <= ry2 && x1 <= rx2 && x2 >= rect->left)
|
||||
|| (x1 >= rect->left && x1 <= rx2 && y1 <= ry2 && y2 >= rect->top)));
|
||||
}
|
||||
|
||||
|
||||
/* Measure a timeslice for a single function-call. (last_time must be static)
|
||||
* Returns fraction of a second between this_time and last_time.
|
||||
*/
|
||||
inline uint32 divide_time(uint32 this_time, uint32 &last_time, uint32 *passed_time = nullptr) {
|
||||
uint32 ms_passed = (this_time - last_time) > 0 ? (this_time - last_time) : 1;
|
||||
uint32 fraction = 1000 / ms_passed; // % of second
|
||||
last_time = this_time;
|
||||
if (passed_time)
|
||||
*passed_time = ms_passed;
|
||||
return (fraction);
|
||||
}
|
||||
|
||||
int mkdir_recursive(const Common::Path &path, int mode);
|
||||
|
||||
void draw_line_8bit(int sx, int sy, int ex, int ey, uint8 col, uint8 *pixels, uint16 w, uint16 h);
|
||||
|
||||
bool string_i_compare(const Std::string &s1, const Std::string &s2);
|
||||
|
||||
void *nuvie_realloc(void *ptr, size_t size);
|
||||
|
||||
uint32 sdl_getpixel(const Graphics::ManagedSurface *surface, int x, int y);
|
||||
|
||||
void scale_rect_8bit(const unsigned char *Source, unsigned char *Target, int SrcWidth, int SrcHeight, int TgtWidth, int TgtHeight);
|
||||
|
||||
bool has_file_extension(const char *filename, const char *extension);
|
||||
|
||||
bool has_fmtowns_support(const Configuration *config);
|
||||
|
||||
uint16 wrap_signed_coord(sint16 coord, uint8 level);
|
||||
sint8 get_wrapped_rel_dir(sint16 p1, sint16 p2, uint8 level);
|
||||
|
||||
Std::string encode_xml_entity(const Std::string &s);
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user