Update to v092r08 release.

byuu says:

Changelog:
- fixed cartridge load window focus on Windows
- lots of updates to nall, ruby and phoenix
- ethos and Emulator::Interface updated from "foo &bar" to "foo& bar"
  syntax (work-in-progress)

Before I had mixed the two ways to declare variables/arguments all over
the place, so the goal is to unify them all for consistency. So the
changelog for this release will be massive (750KB >.>) due to the syntax
change. Yeah, that's what I spent the last three days working on ...
This commit is contained in:
Tim Allen 2013-05-02 21:25:45 +10:00
parent 177e222ca7
commit 75dab443b4
394 changed files with 4989 additions and 4745 deletions

View File

@ -3,7 +3,7 @@
namespace Emulator {
static const char Name[] = "higan";
static const char Version[] = "092.07";
static const char Version[] = "092.08";
static const char Author[] = "byuu";
static const char License[] = "GPLv3";
static const char Website[] = "http://byuu.org/";

View File

@ -23,7 +23,6 @@ struct Interface {
string type;
bool bootable; //false for cartridge slots (eg Sufami Turbo cartridges)
};
vector<Media> media;
struct Device {
@ -59,7 +58,8 @@ struct Interface {
virtual string path(unsigned) { return ""; }
virtual string server() { return ""; }
virtual void notify(const string& text) { print(text, "\n"); }
} *bind;
};
Bind* bind = nullptr;
//callback bindings (provided by user interface)
void loadRequest(unsigned id, const string& name, const string& type) { return bind->loadRequest(id, name, type); }
@ -72,7 +72,7 @@ struct Interface {
unsigned dipSettings(const Markup::Node& node) { return bind->dipSettings(node); }
string path(unsigned group) { return bind->path(group); }
string server() { return bind->server(); }
template<typename... Args> void notify(Args&... args) { return bind->notify({std::forward<Args>(args)...}); }
template<typename... Args> void notify(Args&&... args) { return bind->notify({std::forward<Args>(args)...}); }
//information
virtual string title() = 0;
@ -112,8 +112,6 @@ struct Interface {
//debugger functions
virtual bool tracerEnable(bool) { return false; }
virtual void exportMemory() {}
Interface() : bind(nullptr) {}
};
}

View File

@ -11,8 +11,12 @@ void CPU::serialize(serializer &s) {
s.integer(status.irq_apu_line);
s.integer(status.rdy_line);
s.integer(status.rdy_addr.valid);
s.integer(status.rdy_addr.value);
bool rdy_addr_valid = status.rdy_addr;
unsigned rdy_addr_value = 0;
if(rdy_addr_valid) rdy_addr_value = status.rdy_addr();
s.integer(rdy_addr_valid);
s.integer(rdy_addr_value);
if(rdy_addr_valid) status.rdy_addr = rdy_addr_value;
s.integer(status.oam_dma_pending);
s.integer(status.oam_dma_page);

View File

@ -30,7 +30,8 @@ struct Interface : Emulator::Interface {
struct Hook {
virtual void lcdScanline() {}
virtual void joypWrite(bool p15, bool p14) {}
} *hook;
};
Hook* hook = nullptr;
void lcdScanline();
void joypWrite(bool p15, bool p14);

View File

@ -5,6 +5,7 @@
#undef max
namespace nall {
template<typename T, typename U> T min(const T& t, const U& u) {
return t < u ? t : u;
}
@ -12,6 +13,7 @@ namespace nall {
template<typename T, typename U> T max(const T& t, const U& u) {
return t > u ? t : u;
}
}
#endif

View File

@ -5,11 +5,12 @@
#include <nall/traits.hpp>
namespace nall {
struct any {
bool empty() const { return container; }
const std::type_info& type() const { return container ? container->type() : typeid(void); }
template<typename T> any& operator=(const T& value_) {
template<typename T> any& operator=(const T& value) {
typedef typename type_if<
std::is_array<T>::value,
typename std::remove_extent<typename std::add_const<T>::type>::type*,
@ -17,28 +18,30 @@ namespace nall {
>::type auto_t;
if(type() == typeid(auto_t)) {
static_cast<holder<auto_t>*>(container)->value = (auto_t)value_;
static_cast<holder<auto_t>*>(container)->value = (auto_t)value;
} else {
if(container) delete container;
container = new holder<auto_t>((auto_t)value_);
container = new holder<auto_t>((auto_t)value);
}
return *this;
}
any() : container(nullptr) {}
any() = default;
template<typename T> any(const T& value) { operator=(value); }
~any() { if(container) delete container; }
template<typename T> any(const T& value_) : container(nullptr) { operator=(value_); }
private:
struct placeholder {
virtual const std::type_info& type() const = 0;
} *container;
};
placeholder* container = nullptr;
template<typename T> struct holder : placeholder {
T value;
const std::type_info& type() const { return typeid(T); }
holder(const T& value_) : value(value_) {}
holder(const T& value) : value(value) {}
};
template<typename T> friend T any_cast(any&);
@ -68,6 +71,7 @@ namespace nall {
if(!value || value->type() != typeid(T)) return nullptr;
return &static_cast<any::holder<T>*>(value->container)->value;
}
}
#endif

View File

@ -5,12 +5,6 @@
namespace nall {
//note: this header is intended to form the base for user-defined literals;
//once they are supported by GCC. eg:
//unsigned operator "" b(const char *s) { return binary(s); }
//-> signed data = 1001b;
//(0b1001 is nicer, but is not part of the C++ standard)
constexpr inline uintmax_t binary_(const char* s, uintmax_t sum = 0) {
return (
*s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | *s - '0') :

View File

@ -5,6 +5,7 @@
#include <nall/string.hpp>
namespace nall {
struct base64 {
static bool encode(char*& output, const uint8_t* input, unsigned inlength) {
output = new char[inlength * 8 / 6 + 8]();
@ -113,6 +114,7 @@ namespace nall {
return 0;
}
};
}
#endif

View File

@ -22,10 +22,10 @@ protected:
enum : unsigned { Granularity = 1 };
struct Node {
unsigned offset;
Node *next;
inline Node() : offset(0), next(nullptr) {}
inline ~Node() { if(next) delete next; }
unsigned offset = 0;
Node* next = nullptr;
Node() = default;
~Node() { if(next) delete next; }
};
filemap sourceFile;
@ -96,7 +96,8 @@ bool bpsdelta::create(const string &filename, const string &metadata) {
encode(markupSize);
for(unsigned n = 0; n < markupSize; n++) write(metadata[n]);
Node *sourceTree[65536], *targetTree[65536];
Node* sourceTree[65536];
Node* targetTree[65536];
for(unsigned n = 0; n < 65536; n++) sourceTree[n] = nullptr, targetTree[n] = nullptr;
//source tree creation

View File

@ -4,26 +4,23 @@
#include <nall/stdint.hpp>
namespace nall {
template<unsigned bits>
inline uintmax_t uclamp(const uintmax_t x) {
template<unsigned bits> inline uintmax_t uclamp(const uintmax_t x) {
enum : uintmax_t { b = 1ull << (bits - 1), y = b * 2 - 1 };
return y + ((x - y) & -(x < y)); //min(x, y);
}
template<unsigned bits>
inline uintmax_t uclip(const uintmax_t x) {
template<unsigned bits> inline uintmax_t uclip(const uintmax_t x) {
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 };
return (x & m);
}
template<unsigned bits>
inline intmax_t sclamp(const intmax_t x) {
template<unsigned bits> inline intmax_t sclamp(const intmax_t x) {
enum : intmax_t { b = 1ull << (bits - 1), m = b - 1 };
return (x > m) ? m : (x < -b) ? -b : x;
}
template<unsigned bits>
inline intmax_t sclip(const intmax_t x) {
template<unsigned bits> inline intmax_t sclip(const intmax_t x) {
enum : uintmax_t { b = 1ull << (bits - 1), m = b * 2 - 1 };
return ((x & m) ^ b) - b;
}
@ -77,6 +74,7 @@ namespace nall {
return x << 1;
}
}
}
#endif

View File

@ -4,6 +4,7 @@
#include <nall/stdint.hpp>
namespace nall {
inline uint16_t crc16_adjust(uint16_t crc16, uint8_t data) {
for(unsigned n = 0; n < 8; n++) {
if((crc16 & 1) ^ (data & 1)) crc16 = (crc16 >> 1) ^ 0x8408;
@ -20,6 +21,7 @@ namespace nall {
}
return ~crc16;
}
}
#endif

View File

@ -4,6 +4,7 @@
#include <nall/stdint.hpp>
namespace nall {
const uint32_t crc32_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
@ -61,6 +62,7 @@ namespace nall {
}
return ~crc32;
}
}
#endif

View File

@ -16,39 +16,40 @@
#endif
namespace nall {
struct library {
explicit operator bool() const { return open(); }
bool open() const { return handle; }
bool open(const char*, const char* = "");
bool open_absolute(const char*);
void* sym(const char*);
bool open(const string&, const string& = "");
bool open_absolute(const string&);
void* sym(const string&);
void close();
library() : handle(0) {}
library() = default;
~library() { close(); }
library& operator=(const library&) = delete;
library(const library&) = delete;
private:
uintptr_t handle;
uintptr_t handle = 0;
};
#if defined(PLATFORM_X)
inline bool library::open(const char *name, const char *path) {
inline bool library::open(const string& name, const string& path) {
if(handle) close();
handle = (uintptr_t)dlopen(string(path, *path && !strend(path, "/") ? "/" : "", "lib", name, ".so"), RTLD_LAZY);
handle = (uintptr_t)dlopen(string(path, !path.empty() && !path.endswith("/") ? "/" : "", "lib", name, ".so"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".so"), RTLD_LAZY);
return handle;
}
inline bool library::open_absolute(const char *name) {
inline bool library::open_absolute(const string& name) {
if(handle) close();
handle = (uintptr_t)dlopen(name, RTLD_LAZY);
return handle;
}
inline void* library::sym(const char *name) {
inline void* library::sym(const string& name) {
if(!handle) return nullptr;
return dlsym((void*)handle, name);
}
@ -59,20 +60,20 @@ namespace nall {
handle = 0;
}
#elif defined(PLATFORM_OSX)
inline bool library::open(const char *name, const char *path) {
inline bool library::open(const string& name, const string& path) {
if(handle) close();
handle = (uintptr_t)dlopen(string(path, *path && !strend(path, "/") ? "/" : "", "lib", name, ".dylib"), RTLD_LAZY);
handle = (uintptr_t)dlopen(string(path, !path.empty() && !path.endswith("/") ? "/" : "", "lib", name, ".dylib"), RTLD_LAZY);
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".dylib"), RTLD_LAZY);
return handle;
}
inline bool library::open_absolute(const char *name) {
inline bool library::open_absolute(const string& name) {
if(handle) close();
handle = (uintptr_t)dlopen(name, RTLD_LAZY);
return handle;
}
inline void* library::sym(const char *name) {
inline void* library::sym(const string& name) {
if(!handle) return nullptr;
return dlsym((void*)handle, name);
}
@ -83,20 +84,20 @@ namespace nall {
handle = 0;
}
#elif defined(PLATFORM_WINDOWS)
inline bool library::open(const char *name, const char *path) {
inline bool library::open(const string& name, const string& path) {
if(handle) close();
string filepath(path, *path && !strend(path, "/") && !strend(path, "\\") ? "\\" : "", name, ".dll");
string filepath(path, !path.empty() && !path.endswith("/") && !path.endswith("\\") ? "/" : "", name, ".dll");
handle = (uintptr_t)LoadLibraryW(utf16_t(filepath));
return handle;
}
inline bool library::open_absolute(const char *name) {
inline bool library::open_absolute(const string& name) {
if(handle) close();
handle = (uintptr_t)LoadLibraryW(utf16_t(name));
return handle;
}
inline void* library::sym(const char *name) {
inline void* library::sym(const string& name) {
if(!handle) return nullptr;
return (void*)GetProcAddress((HMODULE)handle, name);
}
@ -107,11 +108,12 @@ namespace nall {
handle = 0;
}
#else
inline bool library::open(const char*, const char*) { return false; }
inline bool library::open_absolute(const char*) { return false; }
inline void* library::sym(const char*) { return nullptr; }
inline bool library::open(const string&, const string&) { return false; }
inline bool library::open_absolute(const string&) { return false; }
inline void* library::sym(const string&) { return nullptr; }
inline void library::close() {}
#endif
};
}
#endif

View File

@ -9,11 +9,12 @@
#include <nall/stream/memory.hpp>
namespace nall {
inline FILE* fopen_utf8(const string &utf8_filename, const char *mode) {
inline FILE* fopen_utf8(const string& filename, const string& mode) {
#if !defined(_WIN32)
return fopen(utf8_filename, mode);
return fopen(filename, mode);
#else
return _wfopen(utf16_t(utf8_filename), utf16_t(mode));
return _wfopen(utf16_t(filename), utf16_t(mode));
#endif
}
@ -349,6 +350,7 @@ namespace nall {
buffer_dirty = false;
}
};
}
#endif

View File

@ -18,24 +18,24 @@
#endif
namespace nall {
class filemap {
public:
struct filemap {
enum class mode : unsigned { read, write, readwrite, writeread };
explicit operator bool() const { return open(); }
bool open() const { return p_open(); }
bool open(const char *filename, mode mode_) { return p_open(filename, mode_); }
bool open(const string& filename, mode mode_) { return p_open(filename, mode_); }
void close() { return p_close(); }
unsigned size() const { return p_size; }
uint8_t* data() { return p_handle; }
const uint8_t* data() const { return p_handle; }
filemap() : p_size(0), p_handle(nullptr) { p_ctor(); }
filemap(const char *filename, mode mode_) : p_size(0), p_handle(nullptr) { p_ctor(); p_open(filename, mode_); }
filemap() { p_ctor(); }
filemap(const string& filename, mode mode_) { p_ctor(); p_open(filename, mode_); }
~filemap() { p_dtor(); }
private:
unsigned p_size;
uint8_t *p_handle;
uint8_t *p_handle = nullptr;
unsigned p_size = 0;
#if defined(_WIN32)
//=============
@ -48,7 +48,7 @@ namespace nall {
return p_handle;
}
bool p_open(const char *filename, mode mode_) {
bool p_open(const string& filename, mode mode_) {
if(file::exists(filename) && file::size(filename) == 0) {
p_handle = nullptr;
p_size = 0;
@ -140,7 +140,7 @@ namespace nall {
return p_handle;
}
bool p_open(const char *filename, mode mode_) {
bool p_open(const string& filename, mode mode_) {
if(file::exists(filename) && file::size(filename) == 0) {
p_handle = nullptr;
p_size = 0;
@ -209,6 +209,7 @@ namespace nall {
#endif
};
}
#endif

View File

@ -2,6 +2,7 @@
#define NALL_FUNCTION_HPP
namespace nall {
template<typename T> class function;
template<typename R, typename... P> class function<R (P...)> {
@ -9,7 +10,9 @@ namespace nall {
virtual R operator()(P... p) const = 0;
virtual container* copy() const = 0;
virtual ~container() {}
} *callback;
};
container* callback = nullptr;
struct global : container {
R (*function)(P...);
@ -46,15 +49,16 @@ namespace nall {
return *this;
}
function(const function &source) : callback(nullptr) { operator=(source); }
function() : callback(nullptr) {}
function(void *function) : callback(nullptr) { if(function) callback = new global((R (*)(P...))function); }
function() = default;
function(const function &source) { operator=(source); }
function(void* function) { if(function) callback = new global((R (*)(P...))function); }
function(R (*function)(P...)) { callback = new global(function); }
template<typename C> function(R (C::*function)(P...), C* object) { callback = new member<C>(function, object); }
template<typename C> function(R (C::*function)(P...) const, C* object) { callback = new member<C>((R (C::*)(P...))function, object); }
template<typename L> function(const L& object) { callback = new lambda<L>(object); }
~function() { if(callback) delete callback; }
};
}
#endif

View File

@ -1,132 +1,62 @@
#ifndef NALL_GROUP_HPP
#define NALL_GROUP_HPP
//group: a vector of unique references
//group
//vector of unique references
#include <stdlib.h>
#include <algorithm>
#include <initializer_list>
#include <utility>
#include <nall/bit.hpp>
#include <nall/traits.hpp>
#include <nall/vector.hpp>
namespace nall {
template<typename TR> struct group {
struct exception_out_of_bounds{};
typedef typename std::remove_reference<TR>::type T;
template<typename T> struct group : protected vector<T*> {
group& operator=(const group& source) { vector<T*>::operator=(source); return *this; }
group& operator=(group&& source) { vector<T*>::operator=(std::move(source)); return *this; }
template<typename... Args> group(Args&&... args) { construct(std::forward<Args>(args)...); }
protected:
T** pool = nullptr;
unsigned poolsize = 0;
unsigned objectsize = 0;
bool empty() const { return vector<T*>::empty(); }
unsigned size() const { return vector<T*>::size(); }
void reset() { vector<T*>::reset(); }
public:
unsigned size() const { return objectsize; }
unsigned capacity() const { return poolsize; }
T& first() const { return *vector<T*>::operator[](0); }
void reset() {
if(pool) free(pool);
pool = nullptr;
poolsize = 0;
objectsize = 0;
//return true if at least one item was appended
template<typename... Args> bool append(T& value, Args&&... args) {
bool result = append(value);
return append(std::forward<Args>(args)...) | result;
}
void reserve(unsigned size) {
if(size == poolsize) return;
pool = (T**)realloc(pool, sizeof(T*) * size);
poolsize = size;
objectsize = min(objectsize, size);
bool append(T& value) {
if(vector<T*>::find(&value)) return false;
return vector<T*>::append(&value), true;
}
void resize(unsigned size) {
if(size > poolsize) reserve(bit::round(size)); //amortize growth
objectsize = size;
//return true if at least one item was removed
template<typename... Args> bool remove(T& value, Args&&... args) {
bool result = remove(value);
return remove(std::forward<Args>(args)...) | result;
}
bool append(T& data) {
if(find(data)) return false;
unsigned offset = objectsize++;
if(offset >= poolsize) resize(offset + 1);
pool[offset] = &data;
return true;
}
template<typename... Args>
bool append(T& data, Args&&... args) {
bool result = append(data);
append(std::forward<Args>(args)...);
return result;
}
bool remove(T& data) {
if(auto position = find(data)) {
for(signed i = position(); i < objectsize - 1; i++) pool[i] = pool[i + 1];
resize(objectsize - 1);
return true;
}
bool remove(T& value) {
if(auto position = vector<T*>::find(&value)) return vector<T*>::remove(position()), true;
return false;
}
optional<unsigned> find(const T& data) {
for(unsigned n = 0; n < objectsize; n++) if(pool[n] == &data) return {true, n};
return {false, 0u};
}
template<typename... Args> group(Args&&... args) {
construct(std::forward<Args>(args)...);
}
~group() {
reset();
}
group& operator=(const group& source) {
if(&source == this) return *this;
reset();
reserve(source.poolsize);
resize(source.objectsize);
memcpy(pool, source.pool, sizeof(T*) * objectsize);
return *this;
}
group& operator=(const group&& source) {
if(&source == this) return *this;
reset();
pool = source.pool;
poolsize = source.poolsize;
objectsize = source.objectsize;
source.pool = nullptr;
source.reset();
return *this;
}
T& operator[](unsigned position) const {
if(position >= objectsize) throw exception_out_of_bounds();
return *pool[position];
}
struct iterator {
bool operator!=(const iterator& source) const { return position != source.position; }
T& operator*() { return source.operator[](position); }
iterator& operator++() { position++; return *this; }
iterator(const group& source, unsigned position) : source(source), position(position) {}
private:
const group& source;
unsigned position;
struct iterator : protected vector<T*>::const_iterator {
T& operator*() const { return *vector<T*>::const_iterator::operator*(); }
bool operator!=(const iterator& source) const { return vector<T*>::const_iterator::operator!=(source); }
iterator& operator++() { vector<T*>::const_iterator::operator++(); return *this; }
iterator(const group& source, unsigned position) : vector<T*>::const_iterator(source, position) {}
};
iterator begin() { return iterator(*this, 0); }
iterator end() { return iterator(*this, objectsize); }
const iterator begin() const { return iterator(*this, 0); }
const iterator end() const { return iterator(*this, objectsize); }
const iterator end() const { return iterator(*this, size()); }
private:
void construct() {}
void construct(const group& source) { operator=(source); }
void construct(const group&& source) { operator=(std::move(source)); }
template<typename... Args> void construct(T& data, Args&&... args) {
append(data);
void construct(const group& source) { vector<T*>::operator=(source); }
void construct(group&& source) { vector<T*>::operator=(std::move(source)); }
template<typename... Args> void construct(T& value, Args&&... args) {
append(value);
construct(std::forward<Args>(args)...);
}
};

View File

@ -8,8 +8,8 @@ namespace nall {
struct gzip {
string filename;
uint8_t *data;
unsigned size;
uint8_t* data = nullptr;
unsigned size = 0;
inline bool decompress(const string& filename);
inline bool decompress(const uint8_t* data, unsigned size);
@ -73,7 +73,7 @@ bool gzip::decompress(const uint8_t *data, unsigned size) {
return inflate(this->data, this->size, data + p, size - p - 8);
}
gzip::gzip() : data(nullptr) {
gzip::gzip() {
}
gzip::~gzip() {

View File

@ -11,14 +11,14 @@
namespace nall {
struct image {
uint8_t *data;
unsigned width;
unsigned height;
unsigned pitch;
uint8_t* data = nullptr;
unsigned width = 0;
unsigned height = 0;
unsigned pitch = 0;
bool endian; //0 = little, 1 = big
unsigned depth;
unsigned stride;
bool endian = 0;
unsigned depth = 32;
unsigned stride = 4;
struct Channel {
uint64_t mask;
@ -32,7 +32,12 @@ struct image {
inline bool operator!=(const Channel& source) {
return !operator==(source);
}
} alpha, red, green, blue;
};
Channel alpha = {255u << 24, 8u, 24};
Channel red = {255u << 16, 8u, 16};
Channel green = {255u << 8, 8u, 8};
Channel blue = {255u << 0, 8u, 0};
typedef double (*interpolation)(double, double, double, double, double);
static inline unsigned bitDepth(uint64_t color);
@ -160,72 +165,34 @@ image& image::operator=(image &&source) {
return *this;
}
image::image(const image &source) : data(nullptr) {
image::image(const image& source) {
operator=(source);
}
image::image(image &&source) : data(nullptr) {
image::image(image&& source) {
operator=(std::forward<image>(source));
}
image::image(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask) : data(nullptr) {
width = 0, height = 0, pitch = 0;
image::image(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask) {
this->endian = endian;
this->depth = depth;
this->stride = (depth / 8) + ((depth & 7) > 0);
alpha.mask = alphaMask, red.mask = redMask, green.mask = greenMask, blue.mask = blueMask;
alpha.depth = bitDepth(alpha.mask), alpha.shift = bitShift(alpha.mask);
red.depth = bitDepth(red.mask), red.shift = bitShift(red.mask);
green.depth = bitDepth(green.mask), green.shift = bitShift(green.mask);
blue.depth = bitDepth(blue.mask), blue.shift = bitShift(blue.mask);
alpha = {alphaMask, bitDepth(alphaMask), bitShift(alphaMask)};
red = {redMask, bitDepth(redMask), bitShift(redMask)};
green = {greenMask, bitDepth(greenMask), bitShift(greenMask)};
blue = {blueMask, bitDepth(blueMask), bitShift(blueMask)};
}
image::image(const string &filename) : data(nullptr) {
width = 0, height = 0, pitch = 0;
this->endian = 0;
this->depth = 32;
this->stride = 4;
alpha.mask = 255u << 24, red.mask = 255u << 16, green.mask = 255u << 8, blue.mask = 255u << 0;
alpha.depth = bitDepth(alpha.mask), alpha.shift = bitShift(alpha.mask);
red.depth = bitDepth(red.mask), red.shift = bitShift(red.mask);
green.depth = bitDepth(green.mask), green.shift = bitShift(green.mask);
blue.depth = bitDepth(blue.mask), blue.shift = bitShift(blue.mask);
image::image(const string& filename) {
load(filename);
}
image::image(const uint8_t *data, unsigned size) : data(nullptr) {
width = 0, height = 0, pitch = 0;
this->endian = 0;
this->depth = 32;
this->stride = 4;
alpha.mask = 255u << 24, red.mask = 255u << 16, green.mask = 255u << 8, blue.mask = 255u << 0;
alpha.depth = bitDepth(alpha.mask), alpha.shift = bitShift(alpha.mask);
red.depth = bitDepth(red.mask), red.shift = bitShift(red.mask);
green.depth = bitDepth(green.mask), green.shift = bitShift(green.mask);
blue.depth = bitDepth(blue.mask), blue.shift = bitShift(blue.mask);
image::image(const uint8_t* data, unsigned size) {
loadPNG(data, size);
}
image::image() : data(nullptr) {
width = 0, height = 0, pitch = 0;
this->endian = 0;
this->depth = 32;
this->stride = 4;
alpha.mask = 255u << 24, red.mask = 255u << 16, green.mask = 255u << 8, blue.mask = 255u << 0;
alpha.depth = bitDepth(alpha.mask), alpha.shift = bitShift(alpha.mask);
red.depth = bitDepth(red.mask), red.shift = bitShift(red.mask);
green.depth = bitDepth(green.mask), green.shift = bitShift(green.mask);
blue.depth = bitDepth(blue.mask), blue.shift = bitShift(blue.mask);
image::image() {
}
image::~image() {

View File

@ -23,15 +23,6 @@ inline bool inflate(
namespace puff {
//zlib/contrib/puff.c
//version 2.1*
//author: Mark Adler
//license: zlib
//ported by: byuu
//* I have corrected a bug in fixed(), where it was accessing uninitialized
// memory: calling construct() with lencode prior to initializing lencode.count
enum {
MAXBITS = 15,
MAXLCODES = 286,

View File

@ -1,6 +1,8 @@
#ifndef NALL_INTRINSICS_HPP
#define NALL_INTRINSICS_HPP
namespace nall {
struct Intrinsics {
enum class Compiler : unsigned { Clang, GCC, VisualC, Unknown };
enum class Platform : unsigned { X, OSX, Windows, Unknown };
@ -63,4 +65,6 @@ struct Intrinsics {
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::Unknown; }
#endif
}
#endif

View File

@ -20,8 +20,7 @@ namespace nall {
#if defined(PLATFORM_WINDOWS)
template<typename... Args>
inline void invoke(const string &name, Args&&... args) {
template<typename... Args> inline void invoke(const string& name, Args&&... args) {
lstring argl(std::forward<Args>(args)...);
for(auto& arg : argl) if(arg.position(" ")) arg = {"\"", arg, "\""};
string arguments = argl.concatenate(" ");
@ -30,11 +29,11 @@ inline void invoke(const string &name, Args&&... args) {
#elif defined(PLATFORM_X)
template<typename... Args>
inline void invoke(const string &name, Args&&... args) {
template<typename... Args> inline void invoke(const string& name, Args&&... args) {
pid_t pid = fork();
if(pid == 0) {
const char *argv[1 + sizeof...(args) + 1], **argp = argv;
const char* argv[1 + sizeof...(args) + 1];
const char** argp = argv;
lstring argl(std::forward<Args>(args)...);
*argp++ = (const char*)name;
for(auto &arg : argl) *argp++ = (const char*)arg;
@ -49,8 +48,7 @@ inline void invoke(const string &name, Args&&... args) {
#else
template<typename... Args>
inline void invoke(const string &name, Args&&... args) {
template<typename... Args> inline void invoke(const string& name, Args&&... args) {
}
#endif

View File

@ -14,12 +14,12 @@ struct ips {
inline ips();
inline ~ips();
uint8_t *data;
unsigned size;
const uint8_t *sourceData;
unsigned sourceSize;
const uint8_t *modifyData;
unsigned modifySize;
uint8_t* data = nullptr;
unsigned size = 0;
const uint8_t* sourceData = nullptr;
unsigned sourceSize = 0;
const uint8_t* modifyData = nullptr;
unsigned modifySize = 0;
};
bool ips::apply() {
@ -86,7 +86,7 @@ void ips::modify(const uint8_t *data, unsigned size) {
modifyData = data, modifySize = size;
}
ips::ips() : data(nullptr), sourceData(nullptr), modifyData(nullptr) {
ips::ips() {
}
ips::~ips() {

View File

@ -1,115 +1,57 @@
#ifndef NALL_MAP_HPP
#define NALL_MAP_HPP
#include <nall/vector.hpp>
#include <nall/set.hpp>
namespace nall {
template<typename LHS, typename RHS>
struct map {
struct pair {
LHS name;
RHS data;
template<typename T, typename U> struct map {
struct node_t {
T key;
U value;
bool operator< (const node_t& source) const { return key < source.key; }
bool operator==(const node_t& source) const { return key == source.key; }
node_t() = default;
node_t(const T& key) : key(key) {}
node_t(const T& key, const U& value) : key(key), value(value) {}
};
inline void reset() {
list.reset();
optional<U> find(const T& key) const {
if(auto node = root.find({key})) return {true, node().value};
return false;
}
inline unsigned size() const {
return list.size();
}
void insert(const T& key, const U& value) { root.insert({key, value}); }
void remove(const T& key) { root.remove({key}); }
unsigned size() const { return root.size(); }
void reset() { root.reset(); }
//O(log n) find
inline optional<unsigned> find(const LHS &name) const {
signed first = 0, last = size() - 1;
while(first <= last) {
signed middle = (first + last) / 2;
if(name < list[middle].name) last = middle - 1; //search lower half
else if(list[middle].name < name) first = middle + 1; //search upper half
else return { true, (unsigned)middle }; //match found
}
return { false, 0u };
}
//O(n) insert + O(log n) find
inline RHS& insert(const LHS &name, const RHS &data) {
if(auto position = find(name)) {
list[position()].data = data;
return list[position()].data;
}
signed offset = size();
for(unsigned n = 0; n < size(); n++) {
if(name < list[n].name) { offset = n; break; }
}
list.insert(offset, { name, data });
return list[offset].data;
}
//O(log n) find
inline void modify(const LHS &name, const RHS &data) {
if(auto position = find(name)) list[position()].data = data;
}
//O(n) remove + O(log n) find
inline void remove(const LHS &name) {
if(auto position = find(name)) list.remove(position());
}
//O(log n) find
inline RHS& operator[](const LHS &name) {
if(auto position = find(name)) return list[position()].data;
throw;
}
inline const RHS& operator[](const LHS &name) const {
if(auto position = find(name)) return list[position()].data;
throw;
}
inline RHS& operator()(const LHS &name) {
if(auto position = find(name)) return list[position()].data;
return insert(name, RHS());
}
inline const RHS& operator()(const LHS &name, const RHS &data) const {
if(auto position = find(name)) return list[position()].data;
return data;
}
inline pair* begin() { return list.begin(); }
inline pair* end() { return list.end(); }
inline const pair* begin() const { return list.begin(); }
inline const pair* end() const { return list.end(); }
typename set<node_t>::iterator begin() { return root.begin(); }
typename set<node_t>::iterator end() { return root.end(); }
const typename set<node_t>::iterator begin() const { return root.begin(); }
const typename set<node_t>::iterator end() const { return root.end(); }
protected:
vector<pair> list;
set<node_t> root;
};
template<typename LHS, typename RHS>
struct bidirectional_map {
const map<LHS, RHS> &lhs;
const map<RHS, LHS> &rhs;
template<typename T, typename U> struct bimap {
optional<U> find(const T& key) const { return tmap.find(key); }
optional<T> find(const U& key) const { return umap.find(key); }
void insert(const T& key, const U& value) { tmap.insert(key, value); umap.insert(value, key); }
void remove(const T& key) { if(auto p = tmap.find(key)) { umap.remove(p().value); tmap.remove(key); } }
void remove(const U& key) { if(auto p = umap.find(key)) { tmap.remove(p().value); umap.remove(key); } }
unsigned size() const { return tmap.size(); }
void reset() { tmap.reset(); umap.reset(); }
inline void reset() {
llist.reset();
rlist.reset();
}
inline unsigned size() const {
return llist.size();
}
inline void insert(const LHS &ldata, const RHS &rdata) {
llist.insert(ldata, rdata);
rlist.insert(rdata, ldata);
}
inline bidirectional_map() : lhs(llist), rhs(rlist) {}
typename set<typename map<T, U>::node_t>::iterator begin() { return tmap.begin(); }
typename set<typename map<T, U>::node_t>::iterator end() { return tmap.end(); }
const typename set<typename map<T, U>::node_t>::iterator begin() const { return tmap.begin(); }
const typename set<typename map<T, U>::node_t>::iterator end() const { return tmap.end(); }
protected:
map<LHS, RHS> llist;
map<RHS, LHS> rlist;
map<T, U> tmap;
map<U, T> umap;
};
}

View File

@ -5,8 +5,7 @@ namespace nall {
namespace Matrix {
template<typename T>
inline void Multiply(T *output, const T *xdata, unsigned xrows, unsigned xcols, const T *ydata, unsigned yrows, unsigned ycols) {
template<typename T> inline void Multiply(T* output, const T* xdata, unsigned xrows, unsigned xcols, const T* ydata, unsigned yrows, unsigned ycols) {
if(xcols != yrows) return;
for(unsigned y = 0; y < xrows; y++) {
@ -20,8 +19,7 @@ inline void Multiply(T *output, const T *xdata, unsigned xrows, unsigned xcols,
}
}
template<typename T>
inline vector<T> Multiply(const T *xdata, unsigned xrows, unsigned xcols, const T *ydata, unsigned yrows, unsigned ycols) {
template<typename T> inline vector<T> Multiply(const T* xdata, unsigned xrows, unsigned xcols, const T* ydata, unsigned yrows, unsigned ycols) {
vector<T> output;
output.resize(xrows * ycols);
Multiply(output.data(), xdata, xrows, xcols, ydata, yrows, ycols);

View File

@ -5,25 +5,25 @@ namespace mosaic {
struct bitstream {
filemap fp;
uint8_t *data;
unsigned size;
bool readonly;
bool endian;
uint8_t* data = nullptr;
unsigned size = 0;
bool readonly = false;
bool endian = 1;
inline bool read(uint64_t addr) const {
bool read(uint64_t addr) const {
if(data == nullptr || (addr >> 3) >= size) return 0;
unsigned mask = endian == 0 ? (0x01 << (addr & 7)) : (0x80 >> (addr & 7));
return data[addr >> 3] & mask;
}
inline void write(uint64_t addr, bool value) {
void write(uint64_t addr, bool value) {
if(data == nullptr || readonly == true || (addr >> 3) >= size) return;
unsigned mask = endian == 0 ? (0x01 << (addr & 7)) : (0x80 >> (addr & 7));
if(value == 0) data[addr >> 3] &= ~mask;
if(value == 1) data[addr >> 3] |= mask;
}
inline bool open(const string &filename) {
bool open(const string& filename) {
readonly = false;
if(fp.open(filename, filemap::mode::readwrite) == false) {
readonly = true;
@ -36,15 +36,15 @@ struct bitstream {
return true;
}
inline void close() {
void close() {
fp.close();
data = nullptr;
}
inline bitstream() : data(nullptr), endian(1) {
bitstream() {
}
inline ~bitstream() {
~bitstream() {
close();
}
};

View File

@ -36,9 +36,9 @@ struct context {
unsigned paddingColor;
vector<unsigned> palette;
inline unsigned objectWidth() const { return blockWidth * tileWidth * mosaicWidth + paddingWidth; }
inline unsigned objectHeight() const { return blockHeight * tileHeight * mosaicHeight + paddingHeight; }
inline unsigned objectSize() const {
unsigned objectWidth() const { return blockWidth * tileWidth * mosaicWidth + paddingWidth; }
unsigned objectHeight() const { return blockHeight * tileHeight * mosaicHeight + paddingHeight; }
unsigned objectSize() const {
unsigned size = blockStride * tileWidth * tileHeight * mosaicWidth * mosaicHeight
+ blockOffset * tileHeight * mosaicWidth * mosaicHeight
+ tileStride * mosaicWidth * mosaicHeight
@ -46,13 +46,13 @@ struct context {
return max(1u, size);
}
inline unsigned eval(const string &expression) {
unsigned eval(const string& expression) {
intmax_t result;
if(fixedpoint::eval(expression, result) == false) return 0u;
return result;
}
inline void eval(vector<unsigned> &buffer, const string &expression_) {
void eval(vector<unsigned>& buffer, const string& expression_) {
string expression = expression_;
bool function = false;
for(auto& c : expression) {
@ -112,7 +112,7 @@ struct context {
}
}
inline void parse(const string &data) {
void parse(const string& data) {
reset();
lstring lines = data.split("\n");
@ -158,14 +158,14 @@ struct context {
sanitize();
}
inline bool load(const string &filename) {
bool load(const string& filename) {
string filedata;
if(filedata.readfile(filename) == false) return false;
parse(filedata);
return true;
}
inline void sanitize() {
void sanitize() {
if(depth < 1) depth = 1;
if(depth > 24) depth = 24;
@ -179,7 +179,7 @@ struct context {
if(mosaicHeight < 1) mosaicHeight = 1;
}
inline void reset() {
void reset() {
offset = 0;
width = 0;
height = 0;
@ -213,7 +213,7 @@ struct context {
palette.reset();
}
inline context() {
context() {
reset();
}
};

View File

@ -7,14 +7,14 @@ struct parser {
image canvas;
//export from bitstream to canvas
inline void load(bitstream &stream, uint64_t offset, context &ctx, unsigned width, unsigned height) {
void load(bitstream& stream, uint64_t offset, context& ctx, unsigned width, unsigned height) {
canvas.allocate(width, height);
canvas.clear(ctx.paddingColor);
parse(1, stream, offset, ctx, width, height);
}
//import from canvas to bitstream
inline bool save(bitstream &stream, uint64_t offset, context &ctx) {
bool save(bitstream& stream, uint64_t offset, context& ctx) {
if(stream.readonly) return false;
parse(0, stream, offset, ctx, canvas.width, canvas.height);
return true;
@ -24,21 +24,21 @@ struct parser {
}
private:
inline uint32_t read(unsigned x, unsigned y) const {
uint32_t read(unsigned x, unsigned y) const {
unsigned addr = y * canvas.width + x;
if(addr >= canvas.width * canvas.height) return 0u;
uint32_t *buffer = (uint32_t*)canvas.data;
return buffer[addr];
}
inline void write(unsigned x, unsigned y, uint32_t data) {
void write(unsigned x, unsigned y, uint32_t data) {
unsigned addr = y * canvas.width + x;
if(addr >= canvas.width * canvas.height) return;
uint32_t *buffer = (uint32_t*)canvas.data;
buffer[addr] = data;
}
inline void parse(bool load, bitstream &stream, uint64_t offset, context &ctx, unsigned width, unsigned height) {
void parse(bool load, bitstream& stream, uint64_t offset, context& ctx, unsigned width, unsigned height) {
stream.endian = ctx.endian;
unsigned canvasWidth = width / (ctx.mosaicWidth * ctx.tileWidth * ctx.blockWidth + ctx.paddingWidth);
unsigned canvasHeight = height / (ctx.mosaicHeight * ctx.tileHeight * ctx.blockHeight + ctx.paddingHeight);

View File

@ -35,6 +35,7 @@
#include <nall/property.hpp>
#include <nall/random.hpp>
#include <nall/serializer.hpp>
#include <nall/set.hpp>
#include <nall/sha256.hpp>
#include <nall/sort.hpp>
#include <nall/stdint.hpp>

View File

@ -10,16 +10,16 @@
namespace nall {
struct png {
//colorType:
//0 = L
//2 = R,G,B
//3 = P
//4 = L,A
//6 = R,G,B,A
struct Info {
unsigned width;
unsigned height;
unsigned bitDepth;
//colorType:
//0 = L (luma)
//2 = R,G,B
//3 = P (palette)
//4 = L,A
//6 = R,G,B,A
unsigned colorType;
unsigned compressionMethod;
unsigned filterType;
@ -31,13 +31,13 @@ struct png {
uint8_t palette[256][3];
} info;
uint8_t *data;
unsigned size;
uint8_t* data = nullptr;
unsigned size = 0;
inline bool decode(const string& filename);
inline bool decode(const uint8_t* sourceData, unsigned sourceSize);
inline unsigned readbits(const uint8_t*& data);
unsigned bitpos;
unsigned bitpos = 0;
inline png();
inline ~png();
@ -102,8 +102,9 @@ bool png::decode(const uint8_t *sourceData, unsigned sourceSize) {
default: return false;
}
if(info.colorType == 2 || info.colorType == 4 || info.colorType == 6)
if(info.colorType == 2 || info.colorType == 4 || info.colorType == 6) {
if(info.bitDepth != 8 && info.bitDepth != 16) return false;
}
if(info.colorType == 3 && info.bitDepth == 16) return false;
info.bytesPerPixel = (info.bytesPerPixel + 7) / 8;
@ -324,8 +325,7 @@ unsigned png::readbits(const uint8_t *&data) {
return result;
}
png::png() : data(nullptr) {
bitpos = 0;
png::png() {
}
png::~png() {

View File

@ -7,6 +7,7 @@
#include <nall/utility.hpp>
namespace nall {
template<typename type_t> void priority_queue_nocallback(type_t) {}
//priority queue implementation using binary min-heap array;
@ -14,8 +15,7 @@ namespace nall {
//O(1) find (tick)
//O(log n) append (enqueue)
//O(log n) remove (dequeue)
template<typename type_t> class priority_queue {
public:
template<typename type_t> struct priority_queue {
inline void tick(unsigned ticks) {
basecounter += ticks;
while(heapsize && gte(basecounter, heap[0].counter)) callback(dequeue());
@ -75,8 +75,8 @@ namespace nall {
}
}
priority_queue(unsigned size, function<void (type_t)> callback_ = &priority_queue_nocallback<type_t>)
: callback(callback_) {
priority_queue(unsigned size, function<void (type_t)> callback = &priority_queue_nocallback<type_t>)
: callback(callback) {
heap = new heap_t[size];
heapcapacity = size;
reset();
@ -104,6 +104,7 @@ namespace nall {
return x - y < (std::numeric_limits<unsigned>::max() >> 1);
}
};
}
#endif

View File

@ -1,48 +1,8 @@
#ifndef NALL_PROPERTY_HPP
#define NALL_PROPERTY_HPP
//nall::property implements ownership semantics into container classes
//example: property<owner>::readonly<type> implies that only owner has full
//access to type; and all other code has readonly access.
//
//property can be used either of two ways:
//struct foo {
// property<foo>::readonly<bool> x;
// property<foo>::readwrite<int> y;
//};
//-or-
//struct foo : property<foo> {
// readonly<bool> x;
// readwrite<int> y;
//};
//return types are const T& (byref) instead of T (byval) to avoid major speed
//penalties for objects with expensive copy constructors
//operator-> provides access to underlying object type:
//readonly<Object> foo;
//foo->bar();
//... will call Object::bar();
//operator='s reference is constant so as to avoid leaking a reference handle
//that could bypass access restrictions
//both constant and non-constant operators are provided, though it may be
//necessary to cast first, for instance:
//struct foo : property<foo> { readonly<int> bar; } object;
//int main() { int value = const_cast<const foo&>(object); }
//writeonly is useful for objects that have non-const reads, but const writes.
//however, to avoid leaking handles, the interface is very restricted. the only
//way to write is via operator=, which requires conversion via eg copy
//constructor. example:
//struct foo {
// foo(bool value) { ... }
//};
//writeonly<foo> bar;
//bar = true;
namespace nall {
template<typename C> struct property {
template<typename T> struct readonly {
const T* operator->() const { return &value; }
@ -78,6 +38,7 @@ namespace nall {
T value;
};
};
}
#endif

View File

@ -14,6 +14,7 @@
//Class::Reference may be a function, object or variable
namespace nall {
template<typename T, typename T::type... P> struct public_cast;
template<typename T> struct public_cast<T> {
@ -27,6 +28,7 @@ namespace nall {
};
template<typename T, typename T::type P> typename T::type public_cast<T, P>::value = public_cast<T>::value = P;
}
#endif

View File

@ -1,8 +1,11 @@
#ifndef NALL_RANDOM_HPP
#define NALL_RANDOM_HPP
namespace nall {
//pseudo-random number generator
//very low-quality, but very fast (based on CRC32 polynomial)
namespace nall {
inline unsigned prng() {
static unsigned n = 0;
return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320);
@ -23,6 +26,7 @@ namespace nall {
private:
unsigned seed_;
};
}
#endif

View File

@ -1,14 +1,21 @@
#ifndef NALL_SERIAL_HPP
#define NALL_SERIAL_HPP
#include <nall/intrinsics.hpp>
#include <nall/stdint.hpp>
#include <nall/string.hpp>
#if !defined(PLATFORM_X) && !defined(PLATFORM_OSX)
#error "nall/serial: unsupported platform"
#endif
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <nall/stdint.hpp>
namespace nall {
struct serial {
bool readable() {
if(port_open == false) return false;
@ -48,7 +55,7 @@ namespace nall {
return ::write(port, (void*)data, length);
}
bool open(const char *portname, unsigned rate, bool flowcontrol) {
bool open(const string& portname, unsigned rate, bool flowcontrol) {
close();
port = ::open(portname, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
@ -105,6 +112,7 @@ namespace nall {
bool port_open;
termios original_attr;
};
}
#endif

View File

@ -1,12 +1,6 @@
#ifndef NALL_SERIALIZER_HPP
#define NALL_SERIALIZER_HPP
#include <type_traits>
#include <utility>
#include <nall/stdint.hpp>
#include <nall/utility.hpp>
namespace nall {
//serializer: a class designed to save and restore the state of classes.
//
//benefits:
@ -18,8 +12,14 @@ namespace nall {
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
//- floating-point usage is not portable across platforms
class serializer {
public:
#include <type_traits>
#include <utility>
#include <nall/stdint.hpp>
#include <nall/utility.hpp>
namespace nall {
struct serializer {
enum mode_t { Load, Save, Size };
mode_t mode() const {
@ -86,7 +86,7 @@ namespace nall {
return *this;
}
serializer(const serializer &s) : idata(nullptr) {
serializer(const serializer& s) {
operator=(s);
}
@ -108,12 +108,7 @@ namespace nall {
}
//construction
serializer() {
imode = Size;
idata = nullptr;
isize = 0;
icapacity = 0;
}
serializer() = default;
serializer(unsigned capacity) {
imode = Save;
@ -130,15 +125,16 @@ namespace nall {
memcpy(idata, data, capacity);
}
//destruction
~serializer() {
if(idata) delete[] idata;
}
private:
mode_t imode;
uint8_t *idata;
unsigned isize;
unsigned icapacity;
mode_t imode = Size;
uint8_t* idata = nullptr;
unsigned isize = 0;
unsigned icapacity = 0;
};
};

258
higan/nall/set.hpp Normal file
View File

@ -0,0 +1,258 @@
#ifndef NALL_SET_HPP
#define NALL_SET_HPP
//set
//implementation: red-black tree
//search: O(log n) average; O(log n) worst
//insert: O(log n) average; O(log n) worst
//remove: O(log n) average; O(log n) worst
#include <nall/utility.hpp>
#include <nall/vector.hpp>
namespace nall {
template<typename T> struct set {
struct node_t {
T value;
bool red = 1;
node_t* link[2] = {nullptr, nullptr};
node_t() = default;
node_t(const T& value) : value(value) {}
};
node_t* root = nullptr;
unsigned nodes = 0;
set& operator=(const set& source) { copy(source); return *this; }
set& operator=(set&& source) { move(std::move(source)); return *this; }
set(const set& source) { operator=(source); }
set(set&& source) { operator=(std::move(source)); }
set(std::initializer_list<T> list) { for(auto& value : list) insert(value); }
set() = default;
~set() { reset(); }
unsigned size() const { return nodes; }
bool empty() const { return nodes == 0; }
void reset() {
reset(root);
nodes = 0;
}
optional<T&> find(const T& value) {
if(node_t* node = find(root, value)) return node->value;
return false;
}
optional<const T&> find(const T& value) const {
if(node_t* node = find(root, value)) return node->value;
return false;
}
bool insert(const T& value) {
unsigned count = size();
insert(root, value);
root->red = 0;
return size() > count;
}
template<typename... Args> bool insert(const T& value, Args&&... args) {
bool result = insert(value);
return insert(std::forward<Args>(args)...) | result;
}
bool remove(const T& value) {
unsigned count = size();
bool done = 0;
remove(root, &value, done);
if(root) root->red = 0;
return size() < count;
}
template<typename... Args> bool remove(const T& value, Args&&... args) {
bool result = remove(value);
return remove(std::forward<Args>(args)...) | result;
}
struct base_iterator {
bool operator!=(const base_iterator& source) const { return position != source.position; }
base_iterator& operator++() {
if(++position >= source.size()) { position = source.size(); return *this; }
if(stack.last()->link[1]) {
stack.append(stack.last()->link[1]);
while(stack.last()->link[0]) stack.append(stack.last()->link[0]);
} else {
node_t* child;
do child = stack.take();
while(child == stack.last()->link[1]);
}
return *this;
}
base_iterator(const set& source, unsigned position) : source(source), position(position) {
node_t* node = source.root;
while(node) {
stack.append(node);
node = node->link[0];
}
}
protected:
const set& source;
unsigned position;
vector<node_t*> stack;
};
struct iterator : base_iterator {
T& operator*() const { return base_iterator::stack.last()->value; }
iterator(const set& source, unsigned position) : base_iterator(source, position) {}
};
iterator begin() { return iterator(*this, 0); }
iterator end() { return iterator(*this, size()); }
struct const_iterator : base_iterator {
const T& operator*() const { return base_iterator::stack.last()->value; }
const_iterator(const set& source, unsigned position) : base_iterator(source, position) {}
};
const const_iterator begin() const { return const_iterator(*this, 0); }
const const_iterator end() const { return const_iterator(*this, size()); }
private:
void reset(node_t*& node) {
if(!node) return;
if(node->link[0]) reset(node->link[0]);
if(node->link[1]) reset(node->link[1]);
delete node;
node = nullptr;
}
void copy(const set& source) {
reset();
copy(root, source.root);
nodes = source.nodes;
}
void copy(node_t*& target, const node_t* source) {
if(!source) return;
target = new node_t(source->value);
target->red = source->red;
copy(target->link[0], source->link[0]);
copy(target->link[1], source->link[1]);
}
void move(set&& source) {
root = source.root;
nodes = source.nodes;
source.root = nullptr;
source.nodes = 0;
}
node_t* find(node_t* node, const T& value) const {
if(node == nullptr) return nullptr;
if(node->value == value) return node;
return find(node->link[node->value < value], value);
}
bool red(node_t* node) const { return node && node->red; }
bool black(node_t* node) const { return !red(node); }
void rotate(node_t*& a, bool dir) {
node_t*& b = a->link[!dir];
node_t*& c = b->link[dir];
a->red = 1, b->red = 0;
std::swap(a, b);
std::swap(b, c);
}
void rotateTwice(node_t*& node, bool dir) {
rotate(node->link[!dir], !dir);
rotate(node, dir);
}
void insert(node_t*& node, const T& value) {
if(!node) { nodes++; node = new node_t(value); return; }
if(node->value == value) { node->value = value; return; } //prevent duplicate entries
bool dir = node->value < value;
insert(node->link[dir], value);
if(black(node->link[dir])) return;
if(red(node->link[!dir])) {
node->red = 1;
node->link[0]->red = 0;
node->link[1]->red = 0;
} else if(red(node->link[dir]->link[dir])) {
rotate(node, !dir);
} else if(red(node->link[dir]->link[!dir])) {
rotateTwice(node, !dir);
}
}
void balance(node_t*& node, bool dir, bool& done) {
node_t* p = node;
node_t* s = node->link[!dir];
if(!s) return;
if(red(s)) {
rotate(node, dir);
s = p->link[!dir];
}
if(black(s->link[0]) && black(s->link[1])) {
if(red(p)) done = 1;
p->red = 0, s->red = 1;
} else {
bool save = p->red;
bool head = node == p;
if(red(s->link[!dir])) rotate(p, dir);
else rotateTwice(p, dir);
p->red = save;
p->link[0]->red = 0;
p->link[1]->red = 0;
if(head) node = p;
else node->link[dir] = p;
done = 1;
}
}
void remove(node_t*& node, const T* value, bool& done) {
if(!node) { done = 1; return; }
if(node->value == *value) {
if(!node->link[0] || !node->link[1]) {
node_t* save = node->link[!node->link[0]];
if(red(node)) done = 1;
else if(red(save)) save->red = 0, done = 1;
nodes--;
delete node;
node = save;
return;
} else {
node_t* heir = node->link[0];
while(heir->link[1]) heir = heir->link[1];
node->value = heir->value;
value = &heir->value;
}
}
bool dir = node->value < *value;
remove(node->link[dir], value, done);
if(!done) balance(node, dir, done);
}
};
}
#endif

View File

@ -6,6 +6,7 @@
#include <nall/stdint.hpp>
namespace nall {
#define PTR(t, a) ((t*)(a))
#define SWAP32(x) ((uint32_t)( \
@ -140,6 +141,7 @@ namespace nall {
#undef LSL32
#undef LSR32
#undef ROR32
}
#endif

View File

@ -19,8 +19,8 @@
//#define NALL_SORT_SELECTION
namespace nall {
template<typename T, typename Comparator>
void sort(T list[], unsigned size, const Comparator &lessthan) {
template<typename T, typename Comparator> void sort(T list[], unsigned size, const Comparator& lessthan) {
if(size <= 1) return; //nothing to sort
//use insertion sort to quickly sort smaller blocks
@ -68,10 +68,10 @@ namespace nall {
delete[] buffer;
}
template<typename T>
void sort(T list[], unsigned size) {
template<typename T> void sort(T list[], unsigned size) {
return sort(list, size, [](const T& l, const T& r) { return l < r; });
}
}
#endif

View File

@ -28,6 +28,7 @@
#endif
namespace nall {
static_assert(sizeof(int8_t) == 1, "int8_t is not of the correct size" );
static_assert(sizeof(int16_t) == 2, "int16_t is not of the correct size");
static_assert(sizeof(int32_t) == 4, "int32_t is not of the correct size");
@ -37,6 +38,7 @@ namespace nall {
static_assert(sizeof(uint16_t) == 2, "int16_t is not of the correct size");
static_assert(sizeof(uint32_t) == 4, "int32_t is not of the correct size");
static_assert(sizeof(uint64_t) == 8, "int64_t is not of the correct size");
}
#endif

View File

@ -22,7 +22,6 @@ namespace nall {
};
struct string {
//deprecated: use string text = file::read(filename);
inline static string read(const string& filename);
inline static string date();
@ -125,8 +124,9 @@ namespace nall {
struct lstring : vector<string> {
inline optional<unsigned> find(const char*) const;
inline string concatenate(const char*) const;
inline lstring& isort();
inline lstring& strip();
inline void append() {}
inline void isort();
template<typename... Args> inline void append(const string&, Args&&...);
template<unsigned Limit = 0> inline lstring& split(const char*, const char*);

View File

@ -162,15 +162,23 @@ string lstring::concatenate(const char *separator) const {
return output;
}
template<typename... Args> void lstring::append(const string &data, Args&&... args) {
vector::append(data);
append(std::forward<Args>(args)...);
}
void lstring::isort() {
lstring& lstring::isort() {
nall::sort(pool, objectsize, [](const string& x, const string& y) {
return istrcmp(x, y) < 0;
});
return *this;
}
lstring& lstring::strip() {
for(unsigned n = 0; n < size(); n++) {
operator[](n).strip();
}
return *this;
}
template<typename... Args> void lstring::append(const string& data, Args&&... args) {
vector::append(data);
append(std::forward<Args>(args)...);
}
bool lstring::operator==(const lstring& source) const {

View File

@ -103,7 +103,7 @@ protected:
//read top-level nodes
void parse(const string& document) {
lstring text = document.split("\n");
lstring text = string{document}.replace("\r", "").split("\n");
//remove empty lines and comment lines
for(unsigned y = 0; y < text.size();) {

View File

@ -128,10 +128,11 @@ struct Node {
return result(0);
}
Node* begin() { return children.begin(); }
Node* end() { return children.end(); }
const Node* begin() const { return children.begin(); }
const Node* end() const { return children.end(); }
vector<Node>::iterator begin() { return children.begin(); }
vector<Node>::iterator end() { return children.end(); }
const vector<Node>::const_iterator begin() const { return children.begin(); }
const vector<Node>::const_iterator end() const { return children.end(); }
Node() : attribute(false), level(0) {}

View File

@ -177,7 +177,8 @@ protected:
//parse contents of an element
inline void parse(const char*& p) {
const char *dataStart = p, *dataEnd = p;
const char* dataStart = p;
const char* dataEnd = p;
while(*p) {
while(*p && *p != '<') p++;

View File

@ -137,7 +137,7 @@ static bool eval(const char *s, double &result) {
try {
result = eval(s);
return true;
} catch(const char*e) {
} catch(const char*) {
result = 0;
return false;
}

View File

@ -20,7 +20,8 @@ string& string::ureplace(const char *key, const char *token) {
if(counter == 0) return *this;
if(Limit) counter = min(counter, Limit);
char *t = data, *base;
char* t = data;
char* base;
unsigned tokenLength = strlen(token);
if(tokenLength > keyLength) {
t = base = strdup(data);

View File

@ -2,10 +2,6 @@
namespace nall {
//
//strmcpy, strmcat created by byuu
//
//return = strlen(target)
unsigned strmcpy(char* target, const char* source, unsigned length) {
const char* origin = target;

View File

@ -14,13 +14,13 @@ optional<unsigned> ustrpos(const char *str, const char *key) {
if(quoteskip<Quoted>(str)) continue;
for(unsigned n = 0;; n++) {
if(key[n] == 0) return {true, (unsigned)(str - base)};
if(str[n] == 0) return { false, 0 };
if(str[n] == 0) return false;
if(!chrequal<Insensitive>(str[n], key[n])) break;
}
str++;
}
return { false, 0 };
return false;
}
optional<unsigned> strpos(const char* str, const char* key) { return ustrpos<false, false>(str, key); }

View File

@ -7,7 +7,8 @@ template<unsigned Limit> char* ltrim(char *str, const char *key) {
unsigned limit = Limit;
if(!key || !*key) return str;
while(strbegin(str, key)) {
char *dest = str, *src = str + strlen(key);
char* dest = str;
char* src = str + strlen(key);
while(true) {
*dest = *src++;
if(!*dest) break;

View File

@ -3,7 +3,8 @@
namespace nall {
bool wildcard(const char* s, const char* p) {
const char *cp = nullptr, *mp = nullptr;
const char* cp = nullptr;
const char* mp = nullptr;
while(*s && *p != '*') {
if(*p != '?' && *s != *p) return false;
p++, s++;
@ -23,7 +24,8 @@ bool wildcard(const char *s, const char *p) {
}
bool iwildcard(const char* s, const char* p) {
const char *cp = nullptr, *mp = nullptr;
const char* cp = nullptr;
const char* mp = nullptr;
while(*s && *p != '*') {
if(*p != '?' && chrlower(*s) != chrlower(*p)) return false;
p++, s++;

View File

@ -9,6 +9,7 @@
#include <pthread.h>
namespace nall {
inline void* thread_entry_point(void*);
struct thread {
@ -61,9 +62,11 @@ namespace nall {
context->completed = true;
pthread_exit(nullptr);
}
}
#elif defined(PLATFORM_WIN)
namespace nall {
inline DWORD WINAPI thread_entry_point(LPVOID);
struct thread {
@ -117,6 +120,7 @@ namespace nall {
context->completed = true;
return 0;
}
}
#endif

View File

@ -7,6 +7,7 @@
#include <type_traits>
namespace nall {
constexpr inline uintmax_t operator"" _b(const char *n) { return binary(n); }
//convert to bytes
@ -23,6 +24,7 @@ namespace nall {
constexpr inline uintmax_t operator"" _khz(long double n) { return n * 1000; }
constexpr inline uintmax_t operator"" _mhz(long double n) { return n * 1000000; }
constexpr inline uintmax_t operator"" _ghz(long double n) { return n * 1000000000; }
}
#endif

View File

@ -141,7 +141,9 @@ struct ups {
}
private:
uint8_t *patch_data, *source_data, *target_data;
uint8_t* patch_data = nullptr;
uint8_t* source_data = nullptr;
uint8_t* target_data = nullptr;
unsigned patch_length, source_length, target_length;
unsigned patch_offset, source_offset, target_offset;
unsigned patch_checksum, source_checksum, target_checksum;

View File

@ -5,21 +5,98 @@
#include <utility>
namespace nall {
template<typename T> struct base_from_member {
T value;
base_from_member(T value_) : value(value_) {}
base_from_member(T value) : value(value) {}
};
template<typename T> class optional {
public:
bool valid;
T value;
public:
inline operator bool() const { return valid; }
inline const T& operator()() const { if(!valid) throw; return value; }
inline optional<T>& operator=(const optional<T> &source) { valid = source.valid; value = source.value; return *this; }
inline optional() : valid(false) {}
inline optional(bool valid, const T &value) : valid(valid), value(value) {}
template<typename TT> struct optional {
typedef typename std::remove_reference<TT>::type T;
static const bool isConst = std::is_const<TT>::value;
static const bool isReference = std::is_reference<TT>::value;
struct optional_value_not_valid{};
bool valid = false;
T* value = nullptr;
operator bool() const { return valid; }
void reset() {
valid = false;
if(value) {
if(!isReference) delete value;
value = nullptr;
}
}
template<typename = typename std::enable_if<!isConst>::type>
T& operator()() {
if(!valid) throw optional_value_not_valid{};
return *value;
}
const T& operator()() const {
if(!valid) throw optional_value_not_valid{};
return *value;
}
const T& operator()(const T& alternate) const {
if(!valid) return alternate;
return *value;
}
const bool operator==(const optional& source) const {
if(valid && source.valid) return *value == *source.value;
if(!valid && !source.valid) return true;
return false;
}
const bool operator!=(const optional& source) const {
return !operator==(source);
}
optional& operator=(const T& source) {
reset();
valid = true;
if(isReference) value = (T*)&source;
else value = new T(source);
return *this;
}
optional& operator=(T&& source) {
reset();
valid = true;
if(isReference) value = &source;
else value = new T(std::move(source));
return *this;
}
optional& operator=(const optional& source) {
reset();
valid = source.valid;
if(valid) operator=(source);
return *this;
}
optional& operator=(optional&& source) {
reset();
valid = source.valid;
value = source.value;
source.valid = false;
source.value = nullptr;
return *this;
}
optional() = default;
optional(bool valid) : valid(valid) {}
optional(const T& value) { operator=(value); }
optional(T&& value) { operator=(std::move(value)); }
optional(bool valid, const T& value) : valid(valid) { if(valid) operator=(value); }
optional(bool valid, T&& value) : valid(valid) { if(valid) operator=(std::move(value)); }
optional(const optional& source) { operator=(source); }
optional(optional&& source) { operator=(std::move(source)); }
~optional() { reset(); }
};
template<typename T> inline T* allocate(unsigned size, const T& value) {
@ -27,6 +104,7 @@ namespace nall {
for(unsigned i = 0; i < size; i++) array[i] = value;
return array;
}
}
#endif

View File

@ -5,6 +5,7 @@
#include <nall/traits.hpp>
namespace nall {
template<unsigned bits> struct uint_t {
private:
typedef typename type_if<bits <= 8 * sizeof(unsigned), unsigned, uintmax_t>::type type_t;
@ -92,6 +93,7 @@ namespace nall {
inline varuint_t() : data(0ull), mask((type_t)~0ull) {}
inline varuint_t(const type_t i) : data(i), mask((type_t)~0ull) {}
};
}
//typedefs

View File

@ -4,7 +4,6 @@
#include <algorithm>
#include <initializer_list>
#include <new>
#include <type_traits>
#include <utility>
#include <nall/algorithm.hpp>
#include <nall/bit.hpp>
@ -12,26 +11,29 @@
#include <nall/utility.hpp>
namespace nall {
template<typename T> struct vector {
struct exception_out_of_bounds{};
protected:
T *pool;
unsigned poolsize;
unsigned objectsize;
T* pool = nullptr;
unsigned poolbase = 0;
unsigned poolsize = 0;
unsigned objectsize = 0;
public:
explicit operator bool() const { return pool; }
T* data() { return pool; }
const T* data() const { return pool; }
T* data() { return pool + poolbase; }
const T* data() const { return pool + poolbase; }
bool empty() const { return objectsize == 0; }
unsigned size() const { return objectsize; }
unsigned capacity() const { return poolsize; }
T* move() {
T *result = pool;
T* result = pool + poolbase;
pool = nullptr;
poolbase = 0;
poolsize = 0;
objectsize = 0;
return result;
@ -39,168 +41,227 @@ namespace nall {
void reset() {
if(pool) {
for(unsigned n = 0; n < objectsize; n++) pool[n].~T();
for(unsigned n = 0; n < objectsize; n++) pool[poolbase + n].~T();
free(pool);
}
pool = nullptr;
poolbase = 0;
poolsize = 0;
objectsize = 0;
}
void reserve(unsigned size) {
unsigned outputsize = min(size, objectsize);
if(size <= poolsize) return;
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();
for(unsigned n = 0; n < objectsize; n++) new(copy + n) T(std::move(pool[poolbase + n]));
free(pool);
pool = copy;
poolbase = 0;
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());
T* copy = (T*)calloc(size, sizeof(T));
for(unsigned n = 0; n < size && n < objectsize; n++) new(copy + n) T(std::move(pool[poolbase + n]));
reset();
pool = copy;
poolbase = 0;
poolsize = size;
objectsize = size;
}
template<typename... Args>
void append(const T& data, Args&&... args) {
template<typename... Args> void prepend(const T& data, Args&&... args) {
prepend(std::forward<Args>(args)...);
prepend(data);
}
void prepend(const T& data) {
reserve(objectsize + 1);
if(poolbase == 0) {
unsigned available = poolsize - objectsize;
poolbase = max(1u, available >> 1);
for(signed n = objectsize - 1; n >= 0; n--) {
pool[poolbase + n] = std::move(pool[n]);
}
}
new(pool + --poolbase) T(data);
objectsize++;
}
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);
reserve(poolbase + objectsize + 1);
new(pool + poolbase + objectsize++) T(data);
}
bool appendonce(const T& data) {
if(find(data) == true) return false;
append(data);
return true;
if(find(data)) return false;
return append(data), true;
}
void insert(unsigned position, const T& data) {
if(position == 0) return prepend(data);
append(data);
for(signed n = size() - 1; n > position; n--) pool[n] = pool[n - 1];
pool[position] = data;
if(position == ~0u) return;
for(signed n = objectsize - 1; n > position; n--) {
pool[poolbase + n] = std::move(pool[poolbase + n - 1]);
}
pool[poolbase + position] = data;
}
void prepend(const T& data) {
insert(0, data);
void remove(unsigned position = ~0u, unsigned length = 1) {
if(position == ~0u) position = objectsize - 1;
if(position + length > objectsize) throw exception_out_of_bounds{};
if(position == 0) {
for(unsigned n = 0; n < length; n++) pool[poolbase + n].~T();
poolbase += length;
} else {
for(unsigned n = position; n < objectsize; n++) {
if(n + length < objectsize) {
pool[poolbase + n] = std::move(pool[poolbase + n + length]);
} else {
pool[poolbase + n].~T();
}
}
}
objectsize -= length;
}
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;
T take(unsigned position = ~0u) {
if(position == ~0u) position = objectsize - 1;
T object = pool[poolbase + position];
remove(position);
return object;
}
void reverse() {
unsigned pivot = size() / 2;
for(unsigned l = 0, r = size() - 1; l < pivot; l++, r--) {
std::swap(pool[l], pool[r]);
std::swap(pool[poolbase + l], pool[poolbase + r]);
}
}
void sort() {
nall::sort(pool, objectsize);
nall::sort(pool + poolbase, objectsize);
}
template<typename Comparator> void sort(const Comparator &lessthan) {
nall::sort(pool, objectsize, lessthan);
nall::sort(pool + poolbase, 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};
for(unsigned n = 0; n < objectsize; n++) if(pool[poolbase + n] == data) return {true, n};
return false;
}
T& first() {
if(objectsize == 0) throw exception_out_of_bounds();
return pool[0];
return pool[poolbase];
}
const T& first() const {
if(objectsize == 0) throw exception_out_of_bounds();
return pool[poolbase];
}
T& last() {
if(objectsize == 0) throw exception_out_of_bounds();
return pool[objectsize - 1];
return pool[poolbase + objectsize - 1];
}
const T& last() const {
if(objectsize == 0) throw exception_out_of_bounds();
return pool[poolbase + objectsize - 1];
}
//access
inline T& operator[](unsigned position) {
if(position >= objectsize) throw exception_out_of_bounds();
return pool[position];
return pool[poolbase + position];
}
inline const T& operator[](unsigned position) const {
if(position >= objectsize) throw exception_out_of_bounds();
return pool[position];
return pool[poolbase + position];
}
inline T& operator()(unsigned position) {
if(position >= poolsize) reserve(position + 1);
while(position >= objectsize) append(T());
return pool[position];
return pool[poolbase + position];
}
inline const T& operator()(unsigned position, const T& data) const {
if(position >= objectsize) return data;
return pool[position];
return pool[poolbase + 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]; }
struct iterator {
T& operator*() { return source.operator[](position); }
bool operator!=(const iterator& source) const { return position != source.position; }
iterator& operator++() { position++; return *this; }
iterator(vector& source, unsigned position) : source(source), position(position) {}
private:
vector& source;
unsigned position;
};
iterator begin() { return iterator(*this, 0); }
iterator end() { return iterator(*this, size()); }
struct const_iterator {
const T& operator*() const { return source.operator[](position); }
bool operator!=(const const_iterator& source) const { return position != source.position; }
const_iterator& operator++() { position++; return *this; }
const_iterator(const vector& source, unsigned position) : source(source), position(position) {}
private:
const vector& source;
unsigned position;
};
const const_iterator begin() const { return const_iterator(*this, 0); }
const const_iterator end() const { return const_iterator(*this, size()); }
//copy
inline vector& operator=(const vector& source) {
reset();
reserve(source.capacity());
reserve(source.size());
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;
pool = source.pool;
poolbase = source.poolbase;
poolsize = source.poolsize;
objectsize = source.objectsize;
source.pool = nullptr;
source.poolbase = 0;
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();
}
//construction and destruction
vector() = default;
vector(std::initializer_list<T> list) { for(auto& data : list) append(data); }
vector(const vector& source) { operator=(source); }
vector(vector&& source) { operator=(std::move(source)); }
~vector() { reset(); }
};
}
#endif

View File

@ -18,8 +18,7 @@
namespace nall {
//UTF-8 to UTF-16
class utf16_t {
public:
struct utf16_t {
operator wchar_t*() {
return buffer;
}
@ -44,8 +43,7 @@ namespace nall {
};
//UTF-16 to UTF-8
class utf8_t {
public:
struct utf8_t {
operator char*() {
return buffer;
}

View File

@ -34,7 +34,7 @@ void pRadioItem::setChecked() {
}
}
void pRadioItem::setGroup(const group<RadioItem&> &group) {
void pRadioItem::setGroup(const group<RadioItem>& group) {
}
void pRadioItem::setText(const string& text) {

View File

@ -14,7 +14,7 @@ struct pRadioItem : public pAction {
bool checked();
void setChecked();
void setGroup(const group<RadioItem&> &group);
void setGroup(const group<RadioItem>& group);
void setText(const string& text);
pRadioItem(RadioItem& radioItem) : pAction(radioItem), radioItem(radioItem) {}

View File

@ -47,7 +47,7 @@ void pRadioButton::setGeometry(const Geometry &geometry) {
});
}
void pRadioButton::setGroup(const group<RadioButton&> &group) {
void pRadioButton::setGroup(const group<RadioButton>& group) {
}
void pRadioButton::setText(const string& text) {

View File

@ -16,7 +16,7 @@ struct pRadioButton : public pWidget {
Size minimumSize();
void setChecked();
void setGeometry(const Geometry& geometry);
void setGroup(const group<RadioButton&> &group);
void setGroup(const group<RadioButton>& group);
void setText(const string& text);
pRadioButton(RadioButton& radioButton) : pWidget(radioButton), radioButton(radioButton) {}

View File

@ -525,7 +525,7 @@ Action::~Action() {
//Menu
//====
void Menu::append(const group<Action&> &list) {
void Menu::append(const group<Action>& list) {
for(auto& action : list) {
if(state.action.append(action)) {
action.state.menu = this;
@ -534,7 +534,7 @@ void Menu::append(const group<Action&> &list) {
}
}
void Menu::remove(const group<Action&> &list) {
void Menu::remove(const group<Action>& list) {
for(auto& action : list) {
if(state.action.remove(action)) {
action.state.menu = nullptr;
@ -639,9 +639,9 @@ CheckItem::~CheckItem() {
//RadioItem
//=========
void RadioItem::group(const nall::group<RadioItem&> &list) {
void RadioItem::group(const nall::group<RadioItem>& list) {
for(auto& item : list) item.p.setGroup(item.state.group = list);
if(list.size()) list[0].setChecked();
if(list.size()) list.first().setChecked();
}
bool RadioItem::checked() {
@ -1261,9 +1261,9 @@ ProgressBar::~ProgressBar() {
//RadioButton
//===========
void RadioButton::group(const nall::group<RadioButton&> &list) {
void RadioButton::group(const nall::group<RadioButton>& list) {
for(auto& item : list) item.p.setGroup(item.state.group = list);
if(list.size()) list[0].setChecked();
if(list.size()) list.first().setChecked();
}
bool RadioButton::checked() {

View File

@ -144,7 +144,7 @@ struct Mouse {
};
struct BrowserWindow {
template<typename... Args> BrowserWindow& setFilters(const Args&... args) { return setFilters_({args...}); }
template<typename... Args> BrowserWindow& setFilters(Args&&... args) { return setFilters_({args...}); }
nall::string directory();
nall::string open();
@ -221,8 +221,8 @@ struct Window : private nall::base_from_member<pWindow&>, Object {
inline void append() {}
inline void remove() {}
template<typename T, typename... Args> void append(T &arg, Args&... args) { append_(arg); append(args...); }
template<typename T, typename... Args> void remove(T &arg, Args&... args) { remove_(arg); remove(args...); }
template<typename T, typename... Args> void append(T& arg, Args&&... args) { append_(arg); append(args...); }
template<typename T, typename... Args> void remove(T& arg, Args&&... args) { remove_(arg); remove(args...); }
void append_(Layout& layout);
void append_(Menu& menu);
@ -277,11 +277,11 @@ struct Action : Object {
};
struct Menu : private nall::base_from_member<pMenu&>, Action {
template<typename... Args> void append(Args&... args) { append({args...}); }
template<typename... Args> void remove(Args&... args) { remove({args...}); }
template<typename... Args> void append(Args&&... args) { append({std::forward<Args>(args)...}); }
template<typename... Args> void remove(Args&&... args) { remove({std::forward<Args>(args)...}); }
void append(const nall::group<Action&> &list);
void remove(const nall::group<Action&> &list);
void append(const nall::group<Action>& list);
void remove(const nall::group<Action>& list);
void setImage(const nall::image& image = nall::image{});
void setText(const nall::string& text);
@ -326,8 +326,8 @@ struct CheckItem : private nall::base_from_member<pCheckItem&>, Action {
};
struct RadioItem : private nall::base_from_member<pRadioItem&>, Action {
template<typename... Args> static void group(Args&... args) { group({args...}); }
static void group(const nall::group<RadioItem&> &list);
template<typename... Args> static void group(Args&&... args) { group({std::forward<Args>(args)...}); }
static void group(const nall::group<RadioItem>& list);
nall::function<void ()> onActivate;
@ -444,7 +444,7 @@ struct CheckButton : private nall::base_from_member<pCheckButton&>, Widget {
struct ComboButton : private nall::base_from_member<pComboButton&>, Widget {
nall::function<void ()> onChange;
template<typename... Args> void append(const Args&... args) { append_({args...}); }
template<typename... Args> void append(Args&&... args) { append_({args...}); }
void append_(const nall::lstring& list);
void modify(unsigned row, const nall::string& text);
@ -539,9 +539,9 @@ struct ListView : private nall::base_from_member<pListView&>, Widget {
nall::function<void ()> onChange;
nall::function<void (unsigned)> onToggle;
template<typename... Args> void append(const Args&... args) { append_({args...}); }
template<typename... Args> void modify(unsigned row, const Args&... args) { modify_(row, {args...}); }
template<typename... Args> void setHeaderText(const Args&... args) { setHeaderText_({args...}); }
template<typename... Args> void append(Args&&... args) { append_({args...}); }
template<typename... Args> void modify(unsigned row, Args&&... args) { modify_(row, {args...}); }
template<typename... Args> void setHeaderText(Args&&... args) { setHeaderText_({args...}); }
void append_(const nall::lstring& list);
void autoSizeColumns();
@ -577,8 +577,8 @@ struct ProgressBar : private nall::base_from_member<pProgressBar&>, Widget {
};
struct RadioButton : private nall::base_from_member<pRadioButton&>, Widget {
template<typename... Args> static void group(Args&... args) { group({args...}); }
static void group(const nall::group<RadioButton&> &list);
template<typename... Args> static void group(Args&&... args) { group({std::forward<Args>(args)...}); }
static void group(const nall::group<RadioButton>& list);
nall::function<void ()> onActivate;

View File

@ -27,8 +27,8 @@ struct Window::State {
Color backgroundColor = {0, 0, 0, 255};
bool fullScreen = false;
Geometry geometry = {128, 128, 256, 256};
group<Layout&> layout;
group<Menu&> menu;
group<Layout> layout;
group<Menu> menu;
string menuFont;
bool menuVisible = false;
bool modal = false;
@ -38,7 +38,7 @@ struct Window::State {
bool statusVisible = false;
string title;
bool visible = false;
group<Widget&> widget;
group<Widget> widget;
string widgetFont;
};
@ -50,7 +50,7 @@ struct Action::State {
};
struct Menu::State {
group<Action&> action;
group<Action> action;
nall::image image = {0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0};
string text;
};
@ -67,7 +67,7 @@ struct CheckItem::State {
struct RadioItem::State {
bool checked = true;
nall::group<RadioItem&> group;
nall::group<RadioItem> group;
string text;
};
@ -152,7 +152,7 @@ struct ProgressBar::State {
struct RadioButton::State {
bool checked = true;
nall::group<RadioButton&> group;
nall::group<RadioButton> group;
string text;
};

View File

@ -16,12 +16,12 @@ void pRadioItem::setChecked() {
locked = false;
}
void pRadioItem::setGroup(const group<RadioItem&> &group) {
for(unsigned n = 0; n < group.size(); n++) {
if(n == 0) continue;
GSList *currentGroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(group[0].p.widget));
if(currentGroup != gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(group[n].p.widget))) {
gtk_radio_menu_item_set_group(GTK_RADIO_MENU_ITEM(group[n].p.widget), currentGroup);
void pRadioItem::setGroup(const group<RadioItem>& group) {
for(auto& item : group) {
if(&item == &group.first()) continue;
GSList* currentGroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(group.first().p.widget));
if(currentGroup != gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item.p.widget))) {
gtk_radio_menu_item_set_group(GTK_RADIO_MENU_ITEM(item.p.widget), currentGroup);
}
}
}

View File

@ -33,9 +33,7 @@ void pApplication::initialize() {
settings->load();
int argc = 1;
char *argv[2];
argv[0] = new char[8];
argv[1] = nullptr;
char* argv[] = {new char[8], nullptr};
strcpy(argv[0], "phoenix");
char** argvp = argv;
gtk_init(&argc, &argvp);

View File

@ -123,9 +123,12 @@ void pKeyboard::initialize() {
bool pKeyboard::pressed(Keyboard::Scancode scancode) {
char state[256];
XQueryKeymap(pApplication::display, state);
unsigned id = settings->keymap.lhs[scancode];
if(auto result = settings->keymap.find(scancode)) {
unsigned id = result();
return state[id >> 3] & (1 << (id & 7));
}
return false;
}
vector<bool> pKeyboard::state() {
vector<bool> output;
@ -134,9 +137,9 @@ vector<bool> pKeyboard::state() {
char state[256];
XQueryKeymap(pApplication::display, state);
for(auto &n : settings->keymap.rhs) {
if(state[n.name >> 3] & (1 << (n.name & 7))) {
output[(unsigned)n.data] = true;
for(auto node : settings->keymap) {
if(state[node.value >> 3] & (1 << (node.value & 7))) {
output[(unsigned)node.key] = true;
}
}

View File

@ -12,7 +12,7 @@ struct pApplication {
};
struct Settings : Configuration::Document {
bidirectional_map<Keyboard::Scancode, unsigned> keymap;
bimap<Keyboard::Scancode, unsigned> keymap;
struct Geometry : Configuration::Node {
unsigned frameX;
@ -214,7 +214,7 @@ struct pRadioItem : public pAction {
bool checked();
void setChecked();
void setGroup(const group<RadioItem&> &group);
void setGroup(const group<RadioItem>& group);
void setText(const string& text);
pRadioItem(RadioItem& radioItem) : pAction(radioItem), radioItem(radioItem) {}
@ -399,7 +399,9 @@ struct pListView : public pWidget {
GtkListStore* store;
struct GtkColumn {
GtkTreeViewColumn* column;
GtkCellRenderer *checkbutton, *icon, *text;
GtkCellRenderer* checkbutton;
GtkCellRenderer* icon;
GtkCellRenderer* text;
GtkWidget *label;
};
vector<GtkColumn> column;
@ -447,7 +449,7 @@ struct pRadioButton : public pWidget {
bool checked();
Size minimumSize();
void setChecked();
void setGroup(const group<RadioButton&> &group);
void setGroup(const group<RadioButton>& group);
void setText(const string& text);
pRadioButton(RadioButton& radioButton) : pWidget(radioButton), radioButton(radioButton) {}

View File

@ -3,15 +3,14 @@ namespace phoenix {
static Settings* settings = nullptr;
void Settings::load() {
string path = {userpath(), ".config/phoenix/gtk.bml"};
Configuration::Document::load(path);
string path = {userpath(), ".config/phoenix/"};
Configuration::Document::load({path, "gtk.bml"});
}
void Settings::save() {
string path = {userpath(), ".config/phoenix/"};
directory::create(path, 0755);
path.append("gtk.bml");
Configuration::Document::save(path);
Configuration::Document::save({path, "gtk.bml"});
}
Settings::Settings() {

View File

@ -20,12 +20,12 @@ void pRadioButton::setChecked() {
parent().locked = false;
}
void pRadioButton::setGroup(const group<RadioButton&> &group) {
void pRadioButton::setGroup(const group<RadioButton>& group) {
if(&parent() == this) return;
parent().locked = true;
if(radioButton.state.group.size() == 0 || &radioButton.state.group[0].p == this) return;
gtk_radio_button_set_group(
GTK_RADIO_BUTTON(gtkWidget),
gtk_radio_button_get_group(GTK_RADIO_BUTTON(radioButton.state.group[0].p.gtkWidget))
gtk_radio_button_get_group(GTK_RADIO_BUTTON(parent().gtkWidget))
);
for(auto& item : radioButton.state.group) {
if(item.state.checked) {
@ -51,7 +51,7 @@ void pRadioButton::onActivate() {
}
pRadioButton& pRadioButton::parent() {
if(radioButton.state.group.size()) return radioButton.state.group[0].p;
if(radioButton.state.group.size()) return radioButton.state.group.first().p;
return *this;
}

View File

@ -21,6 +21,7 @@ void pCheckItem::constructor() {
void pCheckItem::destructor() {
if(action.state.menu) action.state.menu->remove(checkItem);
delete qtAction;
qtAction = nullptr;
}
void pCheckItem::onToggle() {

View File

@ -16,6 +16,7 @@ void pItem::constructor() {
void pItem::destructor() {
if(action.state.menu) action.state.menu->remove(item);
delete qtAction;
qtAction = nullptr;
}
void pItem::onActivate() {

View File

@ -50,6 +50,7 @@ void pMenu::constructor() {
void pMenu::destructor() {
if(action.state.menu) action.state.menu->remove(menu);
delete qtMenu;
qtMenu = nullptr;
}
}

View File

@ -14,7 +14,7 @@ void pRadioItem::setChecked() {
locked = false;
}
void pRadioItem::setGroup(const group<RadioItem&> &group) {
void pRadioItem::setGroup(const group<RadioItem>& group) {
}
void pRadioItem::setText(const string& text) {
@ -33,6 +33,7 @@ void pRadioItem::constructor() {
void pRadioItem::destructor() {
if(action.state.menu) action.state.menu->remove(radioItem);
delete qtAction;
qtAction = nullptr;
}
void pRadioItem::onActivate() {

View File

@ -8,6 +8,7 @@ void pSeparator::constructor() {
void pSeparator::destructor() {
if(action.state.menu) action.state.menu->remove(separator);
delete qtAction;
qtAction = nullptr;
}
}

View File

@ -42,9 +42,7 @@ void pApplication::initialize() {
settings->load();
static int argc = 1;
static char *argv[2];
argv[0] = new char[8];
argv[1] = 0;
static char* argv[] = {new char[8], nullptr};
strcpy(argv[0], "phoenix");
char** argvp = argv;

View File

@ -123,9 +123,12 @@ void pKeyboard::initialize() {
bool pKeyboard::pressed(Keyboard::Scancode scancode) {
char state[256];
XQueryKeymap(pApplication::display, state);
unsigned id = settings->keymap.lhs[scancode];
if(auto result = settings->keymap.find(scancode)) {
unsigned id = result();
return state[id >> 3] & (1 << (id & 7));
}
return false;
}
vector<bool> pKeyboard::state() {
vector<bool> output;
@ -134,9 +137,9 @@ vector<bool> pKeyboard::state() {
char state[256];
XQueryKeymap(pApplication::display, state);
for(auto &n : settings->keymap.rhs) {
if(state[n.name >> 3] & (1 << (n.name & 7))) {
output[(unsigned)n.data] = true;
for(auto node : settings->keymap) {
if(state[node.value >> 3] & (1 << (node.value & 7))) {
output[(unsigned)node.key] = true;
}
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
** Meta object code from reading C++ file 'platform.moc.hpp'
**
** Created: Wed Apr 10 03:33:04 2013
** Created: Mon Apr 29 08:08:05 2013
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.3)
**
** WARNING! All changes made in this file will be lost!

View File

@ -15,7 +15,7 @@ struct pApplication {
static QApplication* qtApplication = nullptr;
struct Settings : Configuration::Document {
bidirectional_map<Keyboard::Scancode, unsigned> keymap;
bimap<Keyboard::Scancode, unsigned> keymap;
struct Geometry : Configuration::Node {
unsigned frameX;
@ -118,7 +118,8 @@ public:
void resizeEvent(QResizeEvent*);
QSize sizeHint() const;
QtWindow(pWindow& self) : self(self) {}
} *qtWindow;
};
QtWindow* qtWindow;
QVBoxLayout* qtLayout;
QMenuBar* qtMenu;
QStatusBar* qtStatus;
@ -240,7 +241,7 @@ public:
bool checked();
void setChecked();
void setGroup(const group<RadioItem&> &group);
void setGroup(const group<RadioItem>& group);
void setText(const string& text);
pRadioItem(RadioItem& radioItem) : pAction(radioItem), radioItem(radioItem) {}
@ -322,7 +323,8 @@ public:
void mouseReleaseEvent(QMouseEvent*);
void paintEvent(QPaintEvent*);
QtCanvas(pCanvas& self);
} *qtCanvas;
};
QtCanvas* qtCanvas;
void setSize(const Size& size);
void update();
@ -390,7 +392,8 @@ public:
void keyPressEvent(QKeyEvent*);
void keyPressEventAcknowledge(QKeyEvent*);
QtHexEdit(pHexEdit& self) : self(self) {}
} *qtHexEdit;
};
QtHexEdit* qtHexEdit;
QHBoxLayout* qtLayout;
QScrollBar* qtScroll;
@ -544,7 +547,7 @@ public:
bool checked();
Size minimumSize();
void setChecked();
void setGroup(const group<RadioButton&> &group);
void setGroup(const group<RadioButton>& group);
void setText(const string& text);
pRadioButton(RadioButton& radioButton) : pWidget(radioButton), radioButton(radioButton) {}
@ -630,7 +633,8 @@ struct pViewport : public pWidget {
void mousePressEvent(QMouseEvent*);
void mouseReleaseEvent(QMouseEvent*);
QtViewport(pViewport& self);
} *qtViewport;
};
QtViewport* qtViewport;
uintptr_t handle();

View File

@ -3,15 +3,14 @@ namespace phoenix {
static Settings *settings = nullptr;
void Settings::load() {
string path = {userpath(), ".config/phoenix/qt.bml"};
Configuration::Document::load(path);
string path = {userpath(), ".config/phoenix/"};
Configuration::Document::load({path, "qt.bml"});
}
void Settings::save() {
string path = {userpath(), ".config/phoenix/"};
directory::create(path, 0755);
path.append("qt.bml");
Configuration::Document::save(path);
Configuration::Document::save({path, "qt.bml"});
}
Settings::Settings() {

View File

@ -41,7 +41,7 @@ void pButton::constructor() {
void pButton::destructor() {
delete qtButton;
qtWidget = qtButton = 0;
qtWidget = qtButton = nullptr;
}
void pButton::orphan() {

View File

@ -95,9 +95,9 @@ void pHexEdit::destructor() {
delete qtScroll;
delete qtLayout;
delete qtHexEdit;
qtWidget = qtHexEdit = 0;
qtLayout = 0;
qtScroll = 0;
qtWidget = qtHexEdit = nullptr;
qtLayout = nullptr;
qtScroll = nullptr;
}
void pHexEdit::orphan() {

View File

@ -31,7 +31,7 @@ void pHorizontalSlider::constructor() {
void pHorizontalSlider::destructor() {
delete qtSlider;
qtWidget = qtSlider = 0;
qtWidget = qtSlider = nullptr;
}
void pHorizontalSlider::orphan() {

View File

@ -18,7 +18,7 @@ void pLabel::constructor() {
void pLabel::destructor() {
delete qtLabel;
qtWidget = qtLabel = 0;
qtWidget = qtLabel = nullptr;
}
void pLabel::orphan() {

View File

@ -29,7 +29,7 @@ void pLineEdit::constructor() {
void pLineEdit::destructor() {
delete qtLineEdit;
qtWidget = qtLineEdit = 0;
qtWidget = qtLineEdit = nullptr;
}
void pLineEdit::orphan() {

View File

@ -138,7 +138,7 @@ void pListView::constructor() {
void pListView::destructor() {
delete qtListView;
qtWidget = qtListView = 0;
qtWidget = qtListView = nullptr;
}
void pListView::orphan() {

View File

@ -19,7 +19,7 @@ void pProgressBar::constructor() {
void pProgressBar::destructor() {
delete qtProgressBar;
qtWidget = qtProgressBar = 0;
qtWidget = qtProgressBar = nullptr;
}
void pProgressBar::orphan() {

View File

@ -18,7 +18,7 @@ void pRadioButton::setChecked() {
parent().locked = false;
}
void pRadioButton::setGroup(const group<RadioButton&> &group) {
void pRadioButton::setGroup(const group<RadioButton>& group) {
parent().locked = true;
for(auto& item : radioButton.state.group) {
item.p.qtRadioButton->setChecked(item.state.checked);
@ -31,7 +31,7 @@ void pRadioButton::setText(const string &text) {
}
pRadioButton& pRadioButton::parent() {
if(radioButton.state.group.size()) return radioButton.state.group[0].p;
if(radioButton.state.group.size()) return radioButton.state.group.first().p;
return *this;
}

View File

@ -38,7 +38,7 @@ void pTextEdit::constructor() {
void pTextEdit::destructor() {
if(sizable.state.layout) sizable.state.layout->remove(textEdit);
delete qtTextEdit;
qtWidget = qtTextEdit = 0;
qtWidget = qtTextEdit = nullptr;
}
void pTextEdit::orphan() {

View File

@ -31,7 +31,7 @@ void pVerticalSlider::constructor() {
void pVerticalSlider::destructor() {
delete qtSlider;
qtWidget = qtSlider = 0;
qtWidget = qtSlider = nullptr;
}
void pVerticalSlider::orphan() {

View File

@ -48,7 +48,7 @@ void pWidget::synchronizeState() {
void pWidget::destructor() {
if(widget.state.abstract) {
delete qtWidget;
qtWidget = 0;
qtWidget = nullptr;
}
}

View File

@ -7,7 +7,7 @@ bool pRadioItem::checked() {
void pRadioItem::setChecked() {
}
void pRadioItem::setGroup(const group<RadioItem&> &group) {
void pRadioItem::setGroup(const group<RadioItem>& group) {
}
void pRadioItem::setText(const string& text) {

View File

@ -5,7 +5,7 @@ struct pRadioItem : public pAction {
bool checked();
void setChecked();
void setGroup(const group<RadioItem&> &group);
void setGroup(const group<RadioItem>& group);
void setText(const string& text);
pRadioItem(RadioItem& radioItem) : pAction(radioItem), radioItem(radioItem) {}

View File

@ -7,7 +7,7 @@ bool pRadioButton::checked() {
void pRadioButton::setChecked() {
}
void pRadioButton::setGroup(const group<RadioButton&> &group) {
void pRadioButton::setGroup(const group<RadioButton>& group) {
}
void pRadioButton::setText(const string& text) {

View File

@ -5,7 +5,7 @@ struct pRadioButton : public pWidget {
bool checked();
void setChecked();
void setGroup(const group<RadioButton&> &group);
void setGroup(const group<RadioButton>& group);
void setText(const string& text);
pRadioButton(RadioButton& radioButton) : pWidget(radioButton), radioButton(radioButton) {}

View File

@ -13,7 +13,7 @@ void pRadioItem::setChecked() {
}
}
void pRadioItem::setGroup(const group<RadioItem&> &group) {
void pRadioItem::setGroup(const group<RadioItem>& group) {
}
void pRadioItem::setText(const string& text) {

View File

@ -325,7 +325,7 @@ static LRESULT CALLBACK Application_windowProc(HWND hwnd, UINT msg, WPARAM wpara
HWND control = GetDlgItem(window.p.hwnd, id);
if(control == 0) break;
Object* object = (Object*)GetWindowLongPtr(control, GWLP_USERDATA);
if(object == 0) break;
if(object == nullptr) break;
if(dynamic_cast<ListView*>(object)) {
ListView& listView = (ListView&)*object;
LPNMHDR nmhdr = (LPNMHDR)lparam;
@ -371,7 +371,7 @@ static LRESULT CALLBACK Application_windowProc(HWND hwnd, UINT msg, WPARAM wpara
case WM_HSCROLL:
case WM_VSCROLL: {
Object *object = 0;
Object* object = nullptr;
if(lparam) {
object = (Object*)GetWindowLongPtr((HWND)lparam, GWLP_USERDATA);
} else {
@ -380,7 +380,7 @@ static LRESULT CALLBACK Application_windowProc(HWND hwnd, UINT msg, WPARAM wpara
if(control == 0) break;
object = (Object*)GetWindowLongPtr(control, GWLP_USERDATA);
}
if(object == 0) break;
if(object == nullptr) break;
if(dynamic_cast<HorizontalScroller*>(object)
|| dynamic_cast<VerticalScroller*>(object)) {

View File

@ -121,7 +121,10 @@ void pKeyboard::initialize() {
}
bool pKeyboard::pressed(Keyboard::Scancode scancode) {
return GetAsyncKeyState(settings->keymap.lhs[scancode]) & 0x8000;
if(auto result = settings->keymap.find(scancode)) {
return GetAsyncKeyState(result()) & 0x8000;
}
return false;
}
vector<bool> pKeyboard::state() {
@ -129,9 +132,9 @@ vector<bool> pKeyboard::state() {
output.resize((unsigned)Keyboard::Scancode::Limit);
for(auto& n : output) n = false;
for(auto &n : settings->keymap.rhs) {
if(GetAsyncKeyState(n.name) & 0x8000) {
output[(unsigned)n.data] = true;
for(auto node : settings->keymap) {
if(GetAsyncKeyState(node.value) & 0x8000) {
output[(unsigned)node.key] = true;
}
}

View File

@ -10,7 +10,7 @@ struct pApplication {
};
struct Settings {
bidirectional_map<Keyboard::Scancode, unsigned> keymap;
bimap<Keyboard::Scancode, unsigned> keymap;
};
struct pFont;
@ -158,7 +158,7 @@ struct pMenu : public pAction {
void constructor();
void destructor();
void createBitmap();
void update(Window &parentWindow, Menu *parentMenu = 0);
void update(Window& parentWindow, Menu* parentMenu = nullptr);
};
struct pSeparator : public pAction {
@ -199,7 +199,7 @@ struct pRadioItem : public pAction {
bool checked();
void setChecked();
void setGroup(const group<RadioItem&> &group);
void setGroup(const group<RadioItem>& group);
void setText(const string& text);
pRadioItem(RadioItem& radioItem) : pAction(radioItem), radioItem(radioItem) {}
@ -423,7 +423,7 @@ struct pRadioButton : public pWidget {
bool checked();
Size minimumSize();
void setChecked();
void setGroup(const group<RadioButton&> &group);
void setGroup(const group<RadioButton>& group);
void setText(const string& text);
pRadioButton(RadioButton& radioButton) : pWidget(radioButton), radioButton(radioButton) {}

Some files were not shown because too many files have changed in this diff Show More