mirror of https://github.com/bsnes-emu/bsnes.git
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:
parent
177e222ca7
commit
75dab443b4
|
@ -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/";
|
||||
|
|
|
@ -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) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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') :
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)...);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();) {
|
||||
|
|
|
@ -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) {}
|
||||
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -50,6 +50,7 @@ void pMenu::constructor() {
|
|||
void pMenu::destructor() {
|
||||
if(action.state.menu) action.state.menu->remove(menu);
|
||||
delete qtMenu;
|
||||
qtMenu = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -8,6 +8,7 @@ void pSeparator::constructor() {
|
|||
void pSeparator::destructor() {
|
||||
if(action.state.menu) action.state.menu->remove(separator);
|
||||
delete qtAction;
|
||||
qtAction = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -41,7 +41,7 @@ void pButton::constructor() {
|
|||
|
||||
void pButton::destructor() {
|
||||
delete qtButton;
|
||||
qtWidget = qtButton = 0;
|
||||
qtWidget = qtButton = nullptr;
|
||||
}
|
||||
|
||||
void pButton::orphan() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -31,7 +31,7 @@ void pHorizontalSlider::constructor() {
|
|||
|
||||
void pHorizontalSlider::destructor() {
|
||||
delete qtSlider;
|
||||
qtWidget = qtSlider = 0;
|
||||
qtWidget = qtSlider = nullptr;
|
||||
}
|
||||
|
||||
void pHorizontalSlider::orphan() {
|
||||
|
|
|
@ -18,7 +18,7 @@ void pLabel::constructor() {
|
|||
|
||||
void pLabel::destructor() {
|
||||
delete qtLabel;
|
||||
qtWidget = qtLabel = 0;
|
||||
qtWidget = qtLabel = nullptr;
|
||||
}
|
||||
|
||||
void pLabel::orphan() {
|
||||
|
|
|
@ -29,7 +29,7 @@ void pLineEdit::constructor() {
|
|||
|
||||
void pLineEdit::destructor() {
|
||||
delete qtLineEdit;
|
||||
qtWidget = qtLineEdit = 0;
|
||||
qtWidget = qtLineEdit = nullptr;
|
||||
}
|
||||
|
||||
void pLineEdit::orphan() {
|
||||
|
|
|
@ -138,7 +138,7 @@ void pListView::constructor() {
|
|||
|
||||
void pListView::destructor() {
|
||||
delete qtListView;
|
||||
qtWidget = qtListView = 0;
|
||||
qtWidget = qtListView = nullptr;
|
||||
}
|
||||
|
||||
void pListView::orphan() {
|
||||
|
|
|
@ -19,7 +19,7 @@ void pProgressBar::constructor() {
|
|||
|
||||
void pProgressBar::destructor() {
|
||||
delete qtProgressBar;
|
||||
qtWidget = qtProgressBar = 0;
|
||||
qtWidget = qtProgressBar = nullptr;
|
||||
}
|
||||
|
||||
void pProgressBar::orphan() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -31,7 +31,7 @@ void pVerticalSlider::constructor() {
|
|||
|
||||
void pVerticalSlider::destructor() {
|
||||
delete qtSlider;
|
||||
qtWidget = qtSlider = 0;
|
||||
qtWidget = qtSlider = nullptr;
|
||||
}
|
||||
|
||||
void pVerticalSlider::orphan() {
|
||||
|
|
|
@ -48,7 +48,7 @@ void pWidget::synchronizeState() {
|
|||
void pWidget::destructor() {
|
||||
if(widget.state.abstract) {
|
||||
delete qtWidget;
|
||||
qtWidget = 0;
|
||||
qtWidget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue