Initial commit
This commit is contained in:
178
engines/ultima/ultima8/usecode/uc_list.h
Normal file
178
engines/ultima/ultima8/usecode/uc_list.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/* 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 ULTIMA8_USECODE_UCLIST_H
|
||||
#define ULTIMA8_USECODE_UCLIST_H
|
||||
|
||||
#include "ultima/shared/std/containers.h"
|
||||
#include "ultima/shared/std/string.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
// stringlists: _elementSize = 2, each element is actually a stringref
|
||||
// see for example the 0x0E opcode: there is no way to see if the
|
||||
// created list is a stringlist or not
|
||||
// the opcodes which do need a distinction have a operand for this.
|
||||
|
||||
// Question: how are unionList/subtractList supposed to know what to do?
|
||||
// their behaviour differs if this is a stringlist
|
||||
|
||||
// Question: does subtractList remove _all_ occurrences of elements or only 1?
|
||||
|
||||
class UCList {
|
||||
Std::vector<uint8> _elements;
|
||||
unsigned int _elementSize;
|
||||
unsigned int _size;
|
||||
|
||||
public:
|
||||
UCList(unsigned int elementSize, unsigned int capacity = 0) :
|
||||
_elementSize(elementSize), _size(0) {
|
||||
if (capacity > 0)
|
||||
_elements.reserve(_elementSize * capacity);
|
||||
}
|
||||
|
||||
~UCList() {
|
||||
// Slight problem: we don't know if we're a stringlist.
|
||||
// So we need to hope something else has ensured any strings
|
||||
// are already freed.
|
||||
free();
|
||||
}
|
||||
|
||||
const uint8 *operator[](uint32 index) const {
|
||||
// check that index isn't out of bounds...
|
||||
return &(_elements[index * _elementSize]);
|
||||
}
|
||||
|
||||
uint16 getuint16(uint32 index) const {
|
||||
assert(_elementSize == 2);
|
||||
uint16 t = _elements[index * _elementSize];
|
||||
t += _elements[index * _elementSize + 1] << 8;
|
||||
return t;
|
||||
}
|
||||
|
||||
void append(const uint8 *e) {
|
||||
_elements.resize((_size + 1) * _elementSize);
|
||||
for (unsigned int i = 0; i < _elementSize; i++)
|
||||
_elements[_size * _elementSize + i] = e[i];
|
||||
_size++;
|
||||
}
|
||||
|
||||
void appenduint16(uint16 val) {
|
||||
assert(_elementSize == 2);
|
||||
uint8 buf[2];
|
||||
buf[0] = static_cast<uint8>(val);
|
||||
buf[1] = static_cast<uint8>(val >> 8);
|
||||
append(buf);
|
||||
}
|
||||
|
||||
void remove(const uint8 *e) {
|
||||
// do we need to erase all occurrences of e or just the first one?
|
||||
// (deleting all, currently)
|
||||
for (unsigned int i = 0; i < _size; i++) {
|
||||
bool equal = true;
|
||||
for (unsigned int j = 0; j < _elementSize && equal; j++)
|
||||
equal = equal && (_elements[i * _elementSize + j] == e[j]);
|
||||
if (equal) {
|
||||
_elements.erase(_elements.begin() + i * _elementSize,
|
||||
_elements.begin() + (i + 1)*_elementSize);
|
||||
_size--;
|
||||
i--; // back up a bit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool inList(const uint8 *e) const {
|
||||
for (unsigned int i = 0; i < _size; i++) {
|
||||
bool equal = true;
|
||||
for (unsigned int j = 0; j < _elementSize && equal; j++)
|
||||
equal = (_elements[i * _elementSize + j] == e[j]);
|
||||
if (equal)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void appendList(const UCList &l) {
|
||||
// elementsizes should match...
|
||||
assert(_elementSize == l.getElementSize());
|
||||
_elements.reserve(_elementSize * (_size + l._size));
|
||||
for (unsigned int i = 0; i < l._size; i++)
|
||||
append(l[i]);
|
||||
}
|
||||
void unionList(const UCList &l) { // like append, but remove duplicates
|
||||
// elementsizes should match...
|
||||
assert(_elementSize == l.getElementSize());
|
||||
_elements.reserve(_elementSize * (_size + l._size));
|
||||
for (unsigned int i = 0; i < l._size; i++)
|
||||
if (!inList(l[i]))
|
||||
append(l[i]);
|
||||
}
|
||||
void subtractList(const UCList &l) {
|
||||
// elementsizes should match...
|
||||
assert(_elementSize == l.getElementSize());
|
||||
for (unsigned int i = 0; i < l._size; i++)
|
||||
remove(l[i]);
|
||||
}
|
||||
|
||||
void free() {
|
||||
_elements.clear();
|
||||
_size = 0;
|
||||
}
|
||||
uint32 getSize() const {
|
||||
return _size;
|
||||
}
|
||||
unsigned int getElementSize() const {
|
||||
return _elementSize;
|
||||
}
|
||||
|
||||
void assign(uint32 index, const uint8 *e) {
|
||||
// need to check that index isn't out-of-bounds? (or grow list?)
|
||||
for (unsigned int i = 0; i < _elementSize; i++)
|
||||
_elements[index * _elementSize + i] = e[i];
|
||||
}
|
||||
|
||||
void copyList(const UCList &l) { // deep copy for list
|
||||
free();
|
||||
appendList(l);
|
||||
}
|
||||
|
||||
void freeStrings();
|
||||
void copyStringList(const UCList &l) ;
|
||||
void unionStringList(UCList &l);
|
||||
void subtractStringList(const UCList &l);
|
||||
bool stringInList(uint16 str) const;
|
||||
void assignString(uint32 index, uint16 str);
|
||||
void removeString(uint16 str, bool nodel = false);
|
||||
|
||||
uint16 getStringIndex(uint32 index) const;
|
||||
|
||||
void save(Common::WriteStream *ws) const;
|
||||
bool load(Common::ReadStream *rs, uint32 version);
|
||||
|
||||
private:
|
||||
const Std::string &getString(uint32 index) const;
|
||||
};
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user