bsnes/higan/nall/vector.hpp
Tim Allen ef746bbda4 Update to v091r05 release.
[No prior releases were posted to the WIP thread. -Ed.]

byuu says:

Super Famicom mapping system has been reworked as discussed with the
mask= changes. offset becomes base, mode is gone. Also added support for
comma-separated fields in the address fields, to reduce the number of
map lines needed.

    <?xml version="1.0" encoding="UTF-8"?>
    <cartridge region="NTSC">
      <superfx revision="2">
	<rom name="program.rom" size="0x200000"/>
	<ram name="save.rwm" size="0x8000"/>
	<map id="io" address="00-3f,80-bf:3000-32ff"/>
	<map id="rom" address="00-3f:8000-ffff" mask="0x8000"/>
	<map id="rom" address="40-5f:0000-ffff"/>
	<map id="ram" address="00-3f,80-bf:6000-7fff" size="0x2000"/>
	<map id="ram" address="70-71:0000-ffff"/>
      </superfx>
    </cartridge>

Or in BML:

    cartridge region=NTSC
      superfx revision=2
	rom name=program.rom size=0x200000
	ram name=save.rwm size=0x8000
	map id=io address=00-3f,80-bf:3000-32ff
	map id=rom address=00-3f:8000-ffff mask=0x8000
	map id=rom address=40-5f:0000-ffff
	map id=ram address=00-3f,80-bf:6000-7fff size=0x2000
	map id=ram address=70-71:0000-ffff

As a result of the changes, old mappings will no longer work. The above
XML example will run Super Mario World 2: Yoshi's Island. Otherwise,
you'll have to write your own.

All that's left now is to work some sort of database mapping system in,
so I can start dumping carts en masse.

The NES changes that FitzRoy asked for are mostly in as well.

Also, part of the reason I haven't released a WIP ... but fuck it, I'm
not going to wait forever to post a new WIP.

I've added a skeleton driver to emulate Campus Challenge '92 and
Powerfest '94. There's no actual emulation, except for the stuff I can
glean from looking at the pictures of the board. It has a DSP-1 (so
SR/DR registers), four ROMs that map in and out, RAM, etc.

I've also added preliminary mapping to upload high scores to a website,
but obviously I need the ROMs first.
2012-12-26 17:46:57 +11:00

207 lines
5.3 KiB
C++
Executable File

#ifndef NALL_VECTOR_HPP
#define NALL_VECTOR_HPP
#include <algorithm>
#include <initializer_list>
#include <new>
#include <type_traits>
#include <utility>
#include <nall/algorithm.hpp>
#include <nall/bit.hpp>
#include <nall/sort.hpp>
#include <nall/utility.hpp>
namespace nall {
template<typename T> struct vector {
struct exception_out_of_bounds{};
protected:
T *pool;
unsigned poolsize;
unsigned objectsize;
public:
operator bool() const { return pool; }
T* data() { return pool; }
const T* data() const { return pool; }
bool empty() const { return objectsize == 0; }
unsigned size() const { return objectsize; }
unsigned capacity() const { return poolsize; }
T* move() {
T *result = pool;
pool = nullptr;
poolsize = 0;
objectsize = 0;
return result;
}
void reset() {
if(pool) {
for(unsigned n = 0; n < objectsize; n++) pool[n].~T();
free(pool);
}
pool = nullptr;
poolsize = 0;
objectsize = 0;
}
void reserve(unsigned size) {
unsigned outputsize = min(size, objectsize);
size = bit::round(size); //amortize growth
T *copy = (T*)calloc(size, sizeof(T));
for(unsigned n = 0; n < outputsize; n++) new(copy + n) T(pool[n]);
for(unsigned n = 0; n < objectsize; n++) pool[n].~T();
free(pool);
pool = copy;
poolsize = size;
objectsize = outputsize;
}
//requires trivial constructor
void resize(unsigned size) {
if(size == objectsize) return;
if(size < objectsize) return reserve(size);
while(size > objectsize) append(T());
}
template<typename... Args>
void append(const T& data, Args&&... args) {
append(data);
append(std::forward<Args>(args)...);
}
void append(const T& data) {
if(objectsize + 1 > poolsize) reserve(objectsize + 1);
new(pool + objectsize++) T(data);
}
bool appendonce(const T& data) {
if(find(data) == true) return false;
append(data);
return true;
}
void insert(unsigned position, const T& data) {
append(data);
for(signed n = size() - 1; n > position; n--) pool[n] = pool[n - 1];
pool[position] = data;
}
void prepend(const T& data) {
insert(0, data);
}
void remove(unsigned index = ~0u, unsigned count = 1) {
if(index == ~0) index = objectsize ? objectsize - 1 : 0;
for(unsigned n = index; count + n < objectsize; n++) pool[n] = pool[count + n];
objectsize = (count + index >= objectsize) ? index : objectsize - count;
}
T take(unsigned index = ~0u) {
if(index == ~0) index = objectsize ? objectsize - 1 : 0;
if(index >= objectsize) throw exception_out_of_bounds();
T item = pool[index];
remove(index);
return item;
}
void reverse() {
unsigned pivot = size() / 2;
for(unsigned l = 0, r = size() - 1; l < pivot; l++, r--) {
std::swap(pool[l], pool[r]);
}
}
void sort() {
nall::sort(pool, objectsize);
}
template<typename Comparator> void sort(const Comparator &lessthan) {
nall::sort(pool, objectsize, lessthan);
}
optional<unsigned> find(const T& data) {
for(unsigned n = 0; n < size(); n++) if(pool[n] == data) return {true, n};
return {false, 0u};
}
T& first() {
if(objectsize == 0) throw exception_out_of_bounds();
return pool[0];
}
T& last() {
if(objectsize == 0) throw exception_out_of_bounds();
return pool[objectsize - 1];
}
//access
inline T& operator[](unsigned position) {
if(position >= objectsize) throw exception_out_of_bounds();
return pool[position];
}
inline const T& operator[](unsigned position) const {
if(position >= objectsize) throw exception_out_of_bounds();
return pool[position];
}
inline T& operator()(unsigned position) {
if(position >= poolsize) reserve(position + 1);
while(position >= objectsize) append(T());
return pool[position];
}
inline const T& operator()(unsigned position, const T& data) const {
if(position >= objectsize) return data;
return pool[position];
}
//iteration
T* begin() { return &pool[0]; }
T* end() { return &pool[objectsize]; }
const T* begin() const { return &pool[0]; }
const T* end() const { return &pool[objectsize]; }
//copy
inline vector& operator=(const vector &source) {
reset();
reserve(source.capacity());
for(auto &data : source) append(data);
return *this;
}
vector(const vector &source) : pool(nullptr), poolsize(0), objectsize(0) {
operator=(source);
}
//move
inline vector& operator=(vector &&source) {
reset();
pool = source.pool, poolsize = source.poolsize, objectsize = source.objectsize;
source.pool = nullptr, source.poolsize = 0, source.objectsize = 0;
return *this;
}
vector(vector &&source) : pool(nullptr), poolsize(0), objectsize(0) {
operator=(std::move(source));
}
//construction
vector() : pool(nullptr), poolsize(0), objectsize(0) {
}
vector(std::initializer_list<T> list) : pool(nullptr), poolsize(0), objectsize(0) {
for(auto &data : list) append(data);
}
~vector() {
reset();
}
};
}
#endif