mirror of
https://github.com/ares-emulator/ares.git
synced 2026-11-12 11:22:59 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27c24bc8a6 | ||
|
|
fac95dfec5 | ||
|
|
362542924e | ||
|
|
4179282244 | ||
|
|
02820ef2e9 | ||
|
|
0ecce7b93d | ||
|
|
f94fcd6f30 | ||
|
|
57f903630a | ||
|
|
9329de0a8d |
No files matched your search
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -2,8 +2,8 @@
|
||||
#define NALL_ANY_HPP
|
||||
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
class any {
|
||||
@@ -13,8 +13,8 @@ namespace nall {
|
||||
|
||||
template<typename T> any& operator=(const T& value_) {
|
||||
typedef typename static_if<
|
||||
is_array<T>::value,
|
||||
typename remove_extent<typename add_const<T>::type>::type*,
|
||||
std::is_array<T>::value,
|
||||
typename std::remove_extent<typename std::add_const<T>::type>::type*,
|
||||
T
|
||||
>::type auto_t;
|
||||
|
||||
@@ -49,13 +49,13 @@ namespace nall {
|
||||
};
|
||||
|
||||
template<typename T> T any_cast(any &value) {
|
||||
typedef typename remove_reference<T>::type nonref;
|
||||
typedef typename std::remove_reference<T>::type nonref;
|
||||
if(value.type() != typeid(nonref)) throw;
|
||||
return static_cast<any::holder<nonref>*>(value.container)->value;
|
||||
}
|
||||
|
||||
template<typename T> T any_cast(const any &value) {
|
||||
typedef const typename remove_reference<T>::type nonref;
|
||||
typedef const typename std::remove_reference<T>::type nonref;
|
||||
if(value.type() != typeid(nonref)) throw;
|
||||
return static_cast<any::holder<nonref>*>(value.container)->value;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
//dynamic vector array
|
||||
@@ -81,7 +82,7 @@ namespace nall {
|
||||
return *this;
|
||||
}
|
||||
|
||||
array(const array &source) : pool(0) {
|
||||
array(const array &source) : pool(0), poolsize(0), buffersize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -92,11 +93,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
buffersize = source.buffersize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
array(array &&source) {
|
||||
operator=(move(source));
|
||||
array(array &&source) : pool(0), poolsize(0), buffersize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//index
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
for(unsigned foreach_counter = 0, foreach_limit = foreach_size(object), foreach_once = 0, foreach_broken = 0; foreach_counter < foreach_limit && foreach_broken == 0; foreach_counter++, foreach_once = 0) \
|
||||
for(auto &iter = object[foreach_counter]; foreach_once == 0 && (foreach_broken = 1); foreach_once++, foreach_broken = 0)
|
||||
|
||||
#include <type_traits>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<has_count<T>>::type = 0) {
|
||||
@@ -23,8 +23,8 @@ namespace nall {
|
||||
return object.size();
|
||||
}
|
||||
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<is_array<T>>::type = 0) {
|
||||
return sizeof(T) / sizeof(typename remove_extent<T>::type);
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<std::is_array<T>>::type = 0) {
|
||||
return sizeof(T) / sizeof(typename std::remove_extent<T>::type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+68
-156
@@ -1,190 +1,102 @@
|
||||
#ifndef NALL_FUNCTION_HPP
|
||||
#define NALL_FUNCTION_HPP
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
//prologue
|
||||
|
||||
#define TN typename
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> class function;
|
||||
}
|
||||
|
||||
//parameters = 0
|
||||
|
||||
#define cat(n) n
|
||||
#define TL typename R
|
||||
#define PL
|
||||
#define CL
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 1
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1
|
||||
#define PL P1 p1
|
||||
#define CL p1
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 2
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2
|
||||
#define PL P1 p1, P2 p2
|
||||
#define CL p1, p2
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 3
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3
|
||||
#define PL P1 p1, P2 p2, P3 p3
|
||||
#define CL p1, p2, p3
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 4
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4
|
||||
#define CL p1, p2, p3, p4
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 5
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5
|
||||
#define CL p1, p2, p3, p4, p5
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 6
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6
|
||||
#define CL p1, p2, p3, p4, p5, p6
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 7
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6, TN P7
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7
|
||||
#define CL p1, p2, p3, p4, p5, p6, p7
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 8
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6, TN P7, TN P8
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8
|
||||
#define CL p1, p2, p3, p4, p5, p6, p7, p8
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//epilogue
|
||||
|
||||
#undef TN
|
||||
#define NALL_FUNCTION_T
|
||||
|
||||
#elif !defined(NALL_FUNCTION_T)
|
||||
|
||||
//function implementation template class
|
||||
|
||||
namespace nall {
|
||||
template<TL>
|
||||
class function<R (PL)> {
|
||||
template<typename R, typename... P>
|
||||
class function<R (P...)> {
|
||||
private:
|
||||
struct base1 { virtual void func1(PL) {} };
|
||||
struct base2 { virtual void func2(PL) {} };
|
||||
struct base1 { virtual void func1(P...) {} };
|
||||
struct base2 { virtual void func2(P...) {} };
|
||||
struct derived : base1, virtual base2 {};
|
||||
|
||||
struct data_t {
|
||||
R (*fn_call)(const data_t& cat(PL));
|
||||
R (*callback)(const data_t&, P...);
|
||||
union {
|
||||
R (*fn_global)(PL);
|
||||
R (*callback_global)(P...);
|
||||
struct {
|
||||
R (derived::*fn_member)(PL);
|
||||
R (derived::*callback_member)(P...);
|
||||
void *object;
|
||||
};
|
||||
};
|
||||
} data;
|
||||
|
||||
static R fn_call_global(const data_t &d cat(PL)) {
|
||||
return d.fn_global(CL);
|
||||
static R callback_global(const data_t &data, P... p) {
|
||||
return data.callback_global(p...);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static R fn_call_member(const data_t &d cat(PL)) {
|
||||
return (((C*)d.object)->*((R (C::*&)(PL))d.fn_member))(CL);
|
||||
static R callback_member(const data_t &data, P... p) {
|
||||
return (((C*)data.object)->*((R (C::*&)(P...))data.callback_member))(p...);
|
||||
}
|
||||
|
||||
public:
|
||||
R operator()(PL) const { return data.fn_call(data cat(CL)); }
|
||||
operator bool() const { return data.fn_call; }
|
||||
R operator()(P... p) const { return data.callback(data, p...); }
|
||||
operator bool() const { return data.callback; }
|
||||
void reset() { data.callback = 0; }
|
||||
|
||||
function() { data.fn_call = 0; }
|
||||
|
||||
function(void *fn) {
|
||||
data.fn_call = fn ? &fn_call_global : 0;
|
||||
data.fn_global = (R (*)(PL))fn;
|
||||
}
|
||||
|
||||
function(R (*fn)(PL)) {
|
||||
data.fn_call = &fn_call_global;
|
||||
data.fn_global = fn;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
function(R (C::*fn)(PL), C *obj) {
|
||||
data.fn_call = &fn_call_member<C>;
|
||||
(R (C::*&)(PL))data.fn_member = fn;
|
||||
assert(sizeof data.fn_member >= sizeof fn);
|
||||
data.object = obj;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
function(R (C::*fn)(PL) const, C *obj) {
|
||||
data.fn_call = &fn_call_member<C>;
|
||||
(R (C::*&)(PL))data.fn_member = (R (C::*&)(PL))fn;
|
||||
assert(sizeof data.fn_member >= sizeof fn);
|
||||
data.object = obj;
|
||||
}
|
||||
|
||||
function& operator=(void *fn) { return operator=(function(fn)); }
|
||||
function& operator=(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); return *this; }
|
||||
function(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); }
|
||||
function(const function &source) { operator=(source); }
|
||||
|
||||
//no pointer
|
||||
function() {
|
||||
data.callback = 0;
|
||||
}
|
||||
|
||||
//symbolic link pointer (nall/dl.hpp::sym, etc)
|
||||
function(void *callback) {
|
||||
data.callback = callback ? &callback_global : 0;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
|
||||
//global function pointer
|
||||
function(R (*callback)(P...)) {
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = callback;
|
||||
}
|
||||
|
||||
//member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...), C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//const member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...) const, C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = (R (C::*&)(P...))callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//lambda function pointer
|
||||
template<typename T>
|
||||
function(T callback) {
|
||||
static_assert(std::is_same<R, typename std::result_of<T(P...)>::type>::value, "lambda mismatch");
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
};
|
||||
|
||||
template<TL>
|
||||
function<R (PL)> bind(R (*fn)(PL)) {
|
||||
return function<R (PL)>(fn);
|
||||
//bind functions to ease construction and assignment of function() with more than one argument
|
||||
|
||||
template<typename C, typename R, typename... P>
|
||||
function<R (P...)> bind(R (C::*callback)(P...), C *object) {
|
||||
return function<R (P...)>(callback, object);
|
||||
}
|
||||
|
||||
template<typename C, TL>
|
||||
function<R (PL)> bind(R (C::*fn)(PL), C *obj) {
|
||||
return function<R (PL)>(fn, obj);
|
||||
}
|
||||
|
||||
template<typename C, TL>
|
||||
function<R (PL)> bind(R (C::*fn)(PL) const, C *obj) {
|
||||
return function<R (PL)>(fn, obj);
|
||||
template<typename C, typename R, typename... P>
|
||||
function<R (P...)> bind(R (C::*callback)(P...) const, C *object) {
|
||||
return function<R (P...)>(callback, object);
|
||||
}
|
||||
}
|
||||
|
||||
#undef cat
|
||||
#undef TL
|
||||
#undef PL
|
||||
#undef CL
|
||||
|
||||
#endif
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifndef NALL_SERIALIZER_HPP
|
||||
#define NALL_SERIALIZER_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
@@ -16,6 +17,7 @@ namespace nall {
|
||||
//caveats:
|
||||
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
|
||||
//- floating-point usage is not portable across platforms
|
||||
|
||||
class serializer {
|
||||
public:
|
||||
enum mode_t { Load, Save, Size };
|
||||
@@ -51,7 +53,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
template<typename T> void integer(T &value) {
|
||||
enum { size = is_bool<T>::value ? 1 : sizeof(T) };
|
||||
enum { size = std::is_same<bool, T>::value ? 1 : sizeof(T) };
|
||||
if(imode == Save) {
|
||||
for(unsigned n = 0; n < size; n++) idata[isize++] = value >> (n << 3);
|
||||
} else if(imode == Load) {
|
||||
@@ -63,7 +65,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
template<typename T> void array(T &array) {
|
||||
enum { size = sizeof(T) / sizeof(typename remove_extent<T>::type) };
|
||||
enum { size = sizeof(T) / sizeof(typename std::remove_extent<T>::type) };
|
||||
for(unsigned n = 0; n < size; n++) integer(array[n]);
|
||||
}
|
||||
|
||||
@@ -102,7 +104,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
serializer(serializer &&s) {
|
||||
operator=(move(s));
|
||||
operator=(std::move(s));
|
||||
}
|
||||
|
||||
//construction
|
||||
|
||||
@@ -10,42 +10,13 @@
|
||||
#include <nall/utf8.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
|
||||
inline char chrlower(char c);
|
||||
inline char chrupper(char c);
|
||||
inline int stricmp(const char *dest, const char *src);
|
||||
inline int strpos (const char *str, const char *key);
|
||||
inline int qstrpos(const char *str, const char *key);
|
||||
inline bool strbegin (const char *str, const char *key);
|
||||
inline bool stribegin(const char *str, const char *key);
|
||||
inline bool strend (const char *str, const char *key);
|
||||
inline bool striend(const char *str, const char *key);
|
||||
inline char* strlower(char *str);
|
||||
inline char* strupper(char *str);
|
||||
inline char* strtr(char *dest, const char *before, const char *after);
|
||||
inline uintmax_t strhex (const char *str);
|
||||
inline intmax_t strsigned (const char *str);
|
||||
inline uintmax_t strunsigned(const char *str);
|
||||
inline uintmax_t strbin (const char *str);
|
||||
inline double strdouble (const char *str);
|
||||
inline bool match(const char *pattern, const char *str);
|
||||
inline bool strint (const char *str, int &result);
|
||||
inline bool strmath(const char *str, int &result);
|
||||
inline size_t strlcpy(char *dest, const char *src, size_t length);
|
||||
inline size_t strlcat(char *dest, const char *src, size_t length);
|
||||
inline char* ltrim(char *str, const char *key = " ");
|
||||
inline char* rtrim(char *str, const char *key = " ");
|
||||
inline char* trim (char *str, const char *key = " ");
|
||||
inline char* ltrim_once(char *str, const char *key = " ");
|
||||
inline char* rtrim_once(char *str, const char *key = " ");
|
||||
inline char* trim_once (char *str, const char *key = " ");
|
||||
|
||||
namespace nall {
|
||||
class string;
|
||||
template<typename T> inline string to_string(T);
|
||||
|
||||
class string {
|
||||
public:
|
||||
inline void reserve(size_t);
|
||||
inline void reserve(unsigned);
|
||||
inline unsigned length() const;
|
||||
|
||||
inline string& assign(const char*);
|
||||
@@ -78,7 +49,7 @@ namespace nall {
|
||||
|
||||
protected:
|
||||
char *data;
|
||||
size_t size;
|
||||
unsigned size;
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
public:
|
||||
@@ -98,29 +69,69 @@ namespace nall {
|
||||
lstring(std::initializer_list<string>);
|
||||
};
|
||||
|
||||
template<typename... Args> inline string sprint(const char *s, Args... args);
|
||||
template<typename... Args> inline void print(const char *s, Args... args);
|
||||
//compare.hpp
|
||||
inline char chrlower(char c);
|
||||
inline char chrupper(char c);
|
||||
inline int stricmp(const char *dest, const char *src);
|
||||
inline int strpos (const char *str, const char *key);
|
||||
inline int qstrpos(const char *str, const char *key);
|
||||
inline bool strbegin (const char *str, const char *key);
|
||||
inline bool stribegin(const char *str, const char *key);
|
||||
inline bool strend (const char *str, const char *key);
|
||||
inline bool striend(const char *str, const char *key);
|
||||
|
||||
//convert.hpp
|
||||
inline char* strlower(char *str);
|
||||
inline char* strupper(char *str);
|
||||
inline char* strtr(char *dest, const char *before, const char *after);
|
||||
inline uintmax_t strhex (const char *str);
|
||||
inline intmax_t strsigned (const char *str);
|
||||
inline uintmax_t strunsigned(const char *str);
|
||||
inline uintmax_t strbin (const char *str);
|
||||
inline double strdouble (const char *str);
|
||||
|
||||
//match.hpp
|
||||
inline bool match(const char *pattern, const char *str);
|
||||
|
||||
//math.hpp
|
||||
inline bool strint (const char *str, int &result);
|
||||
inline bool strmath(const char *str, int &result);
|
||||
|
||||
//strl.hpp
|
||||
inline unsigned strlcpy(char *dest, const char *src, unsigned length);
|
||||
inline unsigned strlcat(char *dest, const char *src, unsigned length);
|
||||
|
||||
//trim.hpp
|
||||
inline char* ltrim(char *str, const char *key = " ");
|
||||
inline char* rtrim(char *str, const char *key = " ");
|
||||
inline char* trim (char *str, const char *key = " ");
|
||||
inline char* ltrim_once(char *str, const char *key = " ");
|
||||
inline char* rtrim_once(char *str, const char *key = " ");
|
||||
inline char* trim_once (char *str, const char *key = " ");
|
||||
|
||||
//utility.hpp
|
||||
inline unsigned strlcpy(string &dest, const char *src, unsigned length);
|
||||
inline unsigned strlcat(string &dest, const char *src, unsigned length);
|
||||
inline string substr(const char *src, unsigned start = 0, unsigned length = 0);
|
||||
inline string& strlower(string &str);
|
||||
inline string& strupper(string &str);
|
||||
inline string& strtr(string &dest, const char *before, const char *after);
|
||||
inline string& ltrim(string &str, const char *key = " ");
|
||||
inline string& rtrim(string &str, const char *key = " ");
|
||||
inline string& trim (string &str, const char *key = " ");
|
||||
inline string& ltrim_once(string &str, const char *key = " ");
|
||||
inline string& rtrim_once(string &str, const char *key = " ");
|
||||
inline string& trim_once (string &str, const char *key = " ");
|
||||
template<unsigned length = 0, char padding = '0'> inline string strhex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strsigned(intmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strunsigned(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strbin(uintmax_t value);
|
||||
inline unsigned strdouble(char *str, double value);
|
||||
inline string strdouble(double value);
|
||||
|
||||
//variadic.hpp
|
||||
template<typename... Args> inline string sprint(Args... args);
|
||||
template<typename... Args> inline void print(Args... args);
|
||||
};
|
||||
|
||||
inline size_t strlcpy(nall::string &dest, const char *src, size_t length);
|
||||
inline size_t strlcat(nall::string &dest, const char *src, size_t length);
|
||||
|
||||
inline nall::string& strlower(nall::string &str);
|
||||
inline nall::string& strupper(nall::string &str);
|
||||
inline nall::string& strtr(nall::string &dest, const char *before, const char *after);
|
||||
inline nall::string& ltrim(nall::string &str, const char *key = " ");
|
||||
inline nall::string& rtrim(nall::string &str, const char *key = " ");
|
||||
inline nall::string& trim (nall::string &str, const char *key = " ");
|
||||
inline nall::string& ltrim_once(nall::string &str, const char *key = " ");
|
||||
inline nall::string& rtrim_once(nall::string &str, const char *key = " ");
|
||||
inline nall::string& trim_once (nall::string &str, const char *key = " ");
|
||||
|
||||
inline nall::string substr(const char *src, size_t start = 0, size_t length = 0);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strhex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strsigned(intmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strunsigned(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strbin(uintmax_t value);
|
||||
inline size_t strdouble(char *str, double value);
|
||||
inline nall::string strdouble(double value);
|
||||
|
||||
#endif
|
||||
@@ -2,28 +2,31 @@
|
||||
#define NALL_STRING_CAST_HPP
|
||||
|
||||
namespace nall {
|
||||
//this is needed, as C++0x does not support explicit template specialization inside classes
|
||||
template<> inline string to_string<bool> (bool v) { return v ? "true" : "false"; }
|
||||
template<> inline string to_string<signed int> (signed int v) { return strsigned(v); }
|
||||
template<> inline string to_string<unsigned int> (unsigned int v) { return strunsigned(v); }
|
||||
template<> inline string to_string<double> (double v) { return strdouble(v); }
|
||||
template<> inline string to_string<char*> (char *v) { return v; }
|
||||
template<> inline string to_string<const char*> (const char *v) { return v; }
|
||||
template<> inline string to_string<string> (string v) { return v; }
|
||||
template<> inline string to_string<const string&>(const string &v) { return v; }
|
||||
|
||||
template<typename T> string& string::operator= (T value) { return assign(to_string<T>(value)); }
|
||||
template<typename T> string& string::operator<<(T value) { return append(to_string<T>(value)); }
|
||||
//this is needed, as C++0x does not support explicit template specialization inside classes
|
||||
template<> inline string to_string<bool> (bool v) { return v ? "true" : "false"; }
|
||||
template<> inline string to_string<signed int> (signed int v) { return strsigned(v); }
|
||||
template<> inline string to_string<unsigned int> (unsigned int v) { return strunsigned(v); }
|
||||
template<> inline string to_string<double> (double v) { return strdouble(v); }
|
||||
template<> inline string to_string<char*> (char *v) { return v; }
|
||||
template<> inline string to_string<const char*> (const char *v) { return v; }
|
||||
template<> inline string to_string<string> (string v) { return v; }
|
||||
template<> inline string to_string<const string&>(const string &v) { return v; }
|
||||
|
||||
template<typename T> lstring& lstring::operator<<(T value) {
|
||||
operator[](size()).assign(to_string<T>(value));
|
||||
return *this;
|
||||
}
|
||||
template<typename T> string& string::operator= (T value) { return assign(to_string<T>(value)); }
|
||||
template<typename T> string& string::operator<<(T value) { return append(to_string<T>(value)); }
|
||||
|
||||
template<typename T> lstring& lstring::operator<<(T value) {
|
||||
operator[](size()).assign(to_string<T>(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
template<> inline string to_string<QString>(QString v) { return v.toUtf8().constData(); }
|
||||
template<> inline string to_string<const QString&>(const QString &v) { return v.toUtf8().constData(); }
|
||||
string::operator QString() const { return QString::fromUtf8(*this); }
|
||||
#endif
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
template<> inline string to_string<const QString&>(const QString &v) { return v.toUtf8().constData(); }
|
||||
string::operator QString() const { return QString::fromUtf8(*this); }
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_COMPARE_HPP
|
||||
#define NALL_STRING_COMPARE_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char chrlower(char c) {
|
||||
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c;
|
||||
}
|
||||
@@ -97,4 +99,6 @@ bool striend(const char *str, const char *key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_CONVERT_HPP
|
||||
#define NALL_STRING_CONVERT_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char* strlower(char *str) {
|
||||
if(!str) return 0;
|
||||
int i = 0;
|
||||
@@ -146,4 +148,6 @@ double strdouble(const char *str) {
|
||||
return !negate ? result : -result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
void string::reserve(size_t size_) {
|
||||
void string::reserve(unsigned size_) {
|
||||
if(size_ > size) {
|
||||
size = size_;
|
||||
data = (char*)realloc(data, size + 1);
|
||||
@@ -81,6 +81,7 @@ string& string::operator=(string &&source) {
|
||||
size = source.size;
|
||||
data = source.data;
|
||||
source.data = 0;
|
||||
source.size = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -94,12 +95,12 @@ bool string::readfile(const char *filename) {
|
||||
#if !defined(_WIN32)
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
#else
|
||||
FILE *fp = _wfopen(nall::utf16_t(filename), L"rb");
|
||||
FILE *fp = _wfopen(utf16_t(filename), L"rb");
|
||||
#endif
|
||||
if(!fp) return false;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t size = ftell(fp);
|
||||
unsigned size = ftell(fp);
|
||||
rewind(fp);
|
||||
char *fdata = new char[size + 1];
|
||||
unsigned unused = fread(fdata, 1, size, fp);
|
||||
|
||||
@@ -2,59 +2,60 @@
|
||||
#define NALL_FILENAME_HPP
|
||||
|
||||
namespace nall {
|
||||
// "foo/bar.c" -> "foo/", "bar.c" -> "./"
|
||||
inline string dir(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
result[i + 1] = 0;
|
||||
break;
|
||||
}
|
||||
if(i == 0) result = "./";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "bar.c"
|
||||
inline string notdir(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
// "foo/bar.c" -> "foo/", "bar.c" -> "./"
|
||||
inline string dir(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
result[i + 1] = 0;
|
||||
break;
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
if(i == 0) result = "./";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "foo/bar"
|
||||
inline string basename(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
//file has no extension
|
||||
break;
|
||||
}
|
||||
|
||||
if(result[i] == '.') {
|
||||
result[i] = 0;
|
||||
break;
|
||||
}
|
||||
// "foo/bar.c" -> "bar.c"
|
||||
inline string notdir(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "c"
|
||||
inline string extension(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '.') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
// "foo/bar.c" -> "foo/bar"
|
||||
inline string basename(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
//file has no extension
|
||||
break;
|
||||
}
|
||||
if(result[i] == '.') {
|
||||
result[i] = 0;
|
||||
break;
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "c"
|
||||
inline string extension(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '.') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_MATCH_HPP
|
||||
#define NALL_STRING_MATCH_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
bool match(const char *p, const char *s) {
|
||||
const char *p_ = 0, *s_ = 0;
|
||||
|
||||
@@ -69,4 +71,6 @@ bool match(const char *p, const char *s) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_MATH_HPP
|
||||
#define NALL_STRING_MATH_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
static int eval_integer(const char *&s) {
|
||||
if(!*s) throw "unrecognized_integer";
|
||||
int value = 0, x = *s, y = *(s + 1);
|
||||
@@ -157,4 +159,6 @@ bool strmath(const char *s, int &result) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,13 +1,15 @@
|
||||
#ifndef NALL_STRING_STRL_HPP
|
||||
#define NALL_STRING_STRL_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
//strlcpy, strlcat based on OpenBSD implementation by Todd C. Miller
|
||||
|
||||
//return = strlen(src)
|
||||
size_t strlcpy(char *dest, const char *src, size_t length) {
|
||||
unsigned strlcpy(char *dest, const char *src, unsigned length) {
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t n = length;
|
||||
unsigned n = length;
|
||||
|
||||
if(n) {
|
||||
while(--n && (*d++ = *s++)); //copy as many bytes as possible, or until null terminator reached
|
||||
@@ -22,13 +24,13 @@ size_t strlcpy(char *dest, const char *src, size_t length) {
|
||||
}
|
||||
|
||||
//return = strlen(src) + min(length, strlen(dest))
|
||||
size_t strlcat(char *dest, const char *src, size_t length) {
|
||||
unsigned strlcat(char *dest, const char *src, unsigned length) {
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t n = length;
|
||||
unsigned n = length;
|
||||
|
||||
while(n-- && *d) d++; //find end of dest
|
||||
size_t dlength = d - dest;
|
||||
unsigned dlength = d - dest;
|
||||
n = length - dlength; //subtract length of dest from maximum string length
|
||||
|
||||
if(!n) return dlength + strlen(s);
|
||||
@@ -45,4 +47,6 @@ size_t strlcat(char *dest, const char *src, size_t length) {
|
||||
return dlength + (s - src); //return length of resulting string, sans null terminator
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_TRIM_HPP
|
||||
#define NALL_STRING_TRIM_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char* ltrim(char *str, const char *key) {
|
||||
if(!key || !*key) return str;
|
||||
while(strbegin(str, key)) {
|
||||
@@ -47,4 +49,6 @@ char* trim_once(char *str, const char *key) {
|
||||
return ltrim_once(rtrim_once(str, key), key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,18 +1,20 @@
|
||||
#ifndef NALL_STRING_UTILITY_HPP
|
||||
#define NALL_STRING_UTILITY_HPP
|
||||
|
||||
size_t strlcpy(nall::string &dest, const char *src, size_t length) {
|
||||
namespace nall {
|
||||
|
||||
unsigned strlcpy(string &dest, const char *src, unsigned length) {
|
||||
dest.reserve(length);
|
||||
return strlcpy(dest(), src, length);
|
||||
}
|
||||
|
||||
size_t strlcat(nall::string &dest, const char *src, size_t length) {
|
||||
unsigned strlcat(string &dest, const char *src, unsigned length) {
|
||||
dest.reserve(length);
|
||||
return strlcat(dest(), src, length);
|
||||
}
|
||||
|
||||
nall::string substr(const char *src, size_t start, size_t length) {
|
||||
nall::string dest;
|
||||
string substr(const char *src, unsigned start, unsigned length) {
|
||||
string dest;
|
||||
if(length == 0) {
|
||||
//copy entire string
|
||||
dest = src + start;
|
||||
@@ -23,22 +25,22 @@ nall::string substr(const char *src, size_t start, size_t length) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* very simplistic wrappers to return nall::string& instead of char* type */
|
||||
/* very simplistic wrappers to return string& instead of char* type */
|
||||
|
||||
nall::string& strlower(nall::string &str) { strlower(str()); return str; }
|
||||
nall::string& strupper(nall::string &str) { strupper(str()); return str; }
|
||||
nall::string& strtr(nall::string &dest, const char *before, const char *after) { strtr(dest(), before, after); return dest; }
|
||||
nall::string& ltrim(nall::string &str, const char *key) { ltrim(str(), key); return str; }
|
||||
nall::string& rtrim(nall::string &str, const char *key) { rtrim(str(), key); return str; }
|
||||
nall::string& trim (nall::string &str, const char *key) { trim (str(), key); return str; }
|
||||
nall::string& ltrim_once(nall::string &str, const char *key) { ltrim_once(str(), key); return str; }
|
||||
nall::string& rtrim_once(nall::string &str, const char *key) { rtrim_once(str(), key); return str; }
|
||||
nall::string& trim_once (nall::string &str, const char *key) { trim_once (str(), key); return str; }
|
||||
string& strlower(string &str) { strlower(str()); return str; }
|
||||
string& strupper(string &str) { strupper(str()); return str; }
|
||||
string& strtr(string &dest, const char *before, const char *after) { strtr(dest(), before, after); return dest; }
|
||||
string& ltrim(string &str, const char *key) { ltrim(str(), key); return str; }
|
||||
string& rtrim(string &str, const char *key) { rtrim(str(), key); return str; }
|
||||
string& trim (string &str, const char *key) { trim (str(), key); return str; }
|
||||
string& ltrim_once(string &str, const char *key) { ltrim_once(str(), key); return str; }
|
||||
string& rtrim_once(string &str, const char *key) { rtrim_once(str(), key); return str; }
|
||||
string& trim_once (string &str, const char *key) { trim_once (str(), key); return str; }
|
||||
|
||||
/* arithmetic <> string */
|
||||
|
||||
template<unsigned length, char padding> nall::string strhex(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strhex(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
//render string backwards, as we do not know its length yet
|
||||
@@ -61,8 +63,8 @@ template<unsigned length, char padding> nall::string strhex(uintmax_t value) {
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strsigned(intmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strsigned(intmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
bool negative = value < 0;
|
||||
@@ -87,8 +89,8 @@ template<unsigned length, char padding> nall::string strsigned(intmax_t value) {
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strunsigned(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strunsigned(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
do {
|
||||
@@ -109,8 +111,8 @@ template<unsigned length, char padding> nall::string strunsigned(uintmax_t value
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strbin(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strbin(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
do {
|
||||
@@ -134,7 +136,7 @@ template<unsigned length, char padding> nall::string strbin(uintmax_t value) {
|
||||
//using sprintf is certainly not the most ideal method to convert
|
||||
//a double to a string ... but attempting to parse a double by
|
||||
//hand, digit-by-digit, results in subtle rounding errors.
|
||||
size_t strdouble(char *str, double value) {
|
||||
unsigned strdouble(char *str, double value) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "%f", value);
|
||||
|
||||
@@ -155,11 +157,13 @@ size_t strdouble(char *str, double value) {
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
nall::string strdouble(double value) {
|
||||
nall::string temp;
|
||||
string strdouble(double value) {
|
||||
string temp;
|
||||
temp.reserve(strdouble(0, value));
|
||||
strdouble(temp(), value);
|
||||
return temp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,36 +2,26 @@
|
||||
#define NALL_STRING_VARIADIC_HPP
|
||||
|
||||
namespace nall {
|
||||
static void sprint(string &output, unsigned &offset, const char *&s) {
|
||||
while(*s) output[offset++] = *s++;
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static void sprint(string &output, unsigned &offset, const char *&s, T value, Args... args) {
|
||||
while(*s) {
|
||||
if(*s == '$') {
|
||||
string data = to_string<T>(value);
|
||||
unsigned i = 0;
|
||||
while(data[i]) output[offset++] = data[i++];
|
||||
sprint(output, offset, ++s, args...);
|
||||
return;
|
||||
} else {
|
||||
output[offset++] = *s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void isprint(string &output) {
|
||||
}
|
||||
|
||||
template<typename... Args> inline string sprint(const char *s, Args... args) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
sprint(output, offset, s, args...);
|
||||
output[offset] = 0;
|
||||
return output;
|
||||
}
|
||||
template<typename T, typename... Args>
|
||||
static void isprint(string &output, T value, Args... args) {
|
||||
output << to_string<T>(value);
|
||||
isprint(output, args...);
|
||||
}
|
||||
|
||||
template<typename... Args> inline string sprint(Args... args) {
|
||||
string output;
|
||||
isprint(output, args...);
|
||||
return output;
|
||||
}
|
||||
|
||||
template<typename... Args> inline void print(Args... args) {
|
||||
printf("%s", (const char*)sprint(args...));
|
||||
}
|
||||
|
||||
template<typename... Args> inline void print(const char *s, Args... args) {
|
||||
printf("%s", (const char*)sprint(s, args...));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,9 +2,7 @@
|
||||
#define NALL_STRING_XML_HPP
|
||||
|
||||
//XML subset parser
|
||||
//version 0.04
|
||||
|
||||
#include <nall/array.hpp>
|
||||
//version 0.05
|
||||
|
||||
namespace nall {
|
||||
|
||||
@@ -16,15 +14,14 @@ struct xml_attribute {
|
||||
|
||||
struct xml_element : xml_attribute {
|
||||
string parse() const;
|
||||
array<xml_attribute*> attribute;
|
||||
array<xml_element*> element;
|
||||
~xml_element();
|
||||
linear_vector<xml_attribute> attribute;
|
||||
linear_vector<xml_element> element;
|
||||
|
||||
protected:
|
||||
void parse_doctype(const char *&data);
|
||||
bool parse_head(string data);
|
||||
bool parse_body(const char *&data);
|
||||
friend xml_element *xml_parse(const char *data);
|
||||
friend xml_element xml_parse(const char *data);
|
||||
};
|
||||
|
||||
inline string xml_attribute::parse() const {
|
||||
@@ -134,11 +131,11 @@ inline bool xml_element::parse_head(string data) {
|
||||
side.qsplit("=", part[i]);
|
||||
if(side.size() != 2) throw "...";
|
||||
|
||||
xml_attribute *attr = new xml_attribute;
|
||||
attr->name = side[0];
|
||||
attr->content = side[1];
|
||||
if(strbegin(attr->content, "\"") && strend(attr->content, "\"")) trim_once(attr->content, "\"");
|
||||
else if(strbegin(attr->content, "'") && strend(attr->content, "'")) trim_once(attr->content, "'");
|
||||
xml_attribute attr;
|
||||
attr.name = side[0];
|
||||
attr.content = side[1];
|
||||
if(strbegin(attr.content, "\"") && strend(attr.content, "\"")) trim_once(attr.content, "\"");
|
||||
else if(strbegin(attr.content, "'") && strend(attr.content, "'")) trim_once(attr.content, "'");
|
||||
else throw "...";
|
||||
attribute.add(attr);
|
||||
}
|
||||
@@ -191,10 +188,8 @@ inline bool xml_element::parse_body(const char *&data) {
|
||||
|
||||
while(*data) {
|
||||
unsigned index = element.size();
|
||||
xml_element *elem = new xml_element;
|
||||
if(elem->parse_body(data) == false) {
|
||||
delete elem;
|
||||
|
||||
xml_element node;
|
||||
if(node.parse_body(data) == false) {
|
||||
if(*data == '/') {
|
||||
signed length = data - content_begin - 1;
|
||||
if(length > 0) content = substr(content_begin, 0, length);
|
||||
@@ -216,23 +211,18 @@ inline bool xml_element::parse_body(const char *&data) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
element.add(elem);
|
||||
element.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline xml_element::~xml_element() {
|
||||
for(unsigned i = 0; i < attribute.size(); i++) delete attribute[i];
|
||||
for(unsigned i = 0; i < element.size(); i++) delete element[i];
|
||||
}
|
||||
|
||||
//ensure there is only one root element
|
||||
inline bool xml_validate(xml_element *document) {
|
||||
inline bool xml_validate(xml_element &document) {
|
||||
unsigned root_counter = 0;
|
||||
|
||||
for(unsigned i = 0; i < document->element.size(); i++) {
|
||||
string &name = document->element[i]->name;
|
||||
for(unsigned i = 0; i < document.element.size(); i++) {
|
||||
string &name = document.element[i].name;
|
||||
if(strbegin(name, "?")) continue;
|
||||
if(strbegin(name, "!")) continue;
|
||||
if(++root_counter > 1) return false;
|
||||
@@ -241,25 +231,24 @@ inline bool xml_validate(xml_element *document) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline xml_element* xml_parse(const char *data) {
|
||||
xml_element *self = new xml_element;
|
||||
inline xml_element xml_parse(const char *data) {
|
||||
xml_element self;
|
||||
|
||||
try {
|
||||
while(*data) {
|
||||
xml_element *elem = new xml_element;
|
||||
if(elem->parse_body(data) == false) {
|
||||
delete elem;
|
||||
xml_element node;
|
||||
if(node.parse_body(data) == false) {
|
||||
break;
|
||||
} else {
|
||||
self->element.add(elem);
|
||||
self.element.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
if(xml_validate(self) == false) throw "...";
|
||||
return self;
|
||||
} catch(const char*) {
|
||||
delete self;
|
||||
return 0;
|
||||
xml_element empty;
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
#ifndef NALL_TRAITS_HPP
|
||||
#define NALL_TRAITS_HPP
|
||||
|
||||
namespace nall {
|
||||
//==
|
||||
//is
|
||||
//==
|
||||
|
||||
template<typename T> struct is_integral { enum { value = false }; };
|
||||
template<> struct is_integral<bool> { enum { value = true }; };
|
||||
template<> struct is_integral<char> { enum { value = true }; };
|
||||
template<> struct is_integral<signed char> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned char> { enum { value = true }; };
|
||||
template<> struct is_integral<wchar_t> { enum { value = true }; };
|
||||
template<> struct is_integral<short> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned short> { enum { value = true }; };
|
||||
template<> struct is_integral<long> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned long> { enum { value = true }; };
|
||||
template<> struct is_integral<long long> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned long long> { enum { value = true }; };
|
||||
template<> struct is_integral<int> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned int> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_floating_point { enum { value = false }; };
|
||||
template<> struct is_floating_point<float> { enum { value = true }; };
|
||||
template<> struct is_floating_point<double> { enum { value = true }; };
|
||||
template<> struct is_floating_point<long double> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_bool { enum { value = false }; };
|
||||
template<> struct is_bool<bool> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_void { enum { value = false }; };
|
||||
template<> struct is_void<void> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_arithmetic {
|
||||
enum { value = is_integral<T>::value || is_floating_point<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_fundamental {
|
||||
enum { value = is_integral<T>::value || is_floating_point<T>::value || is_void<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_compound {
|
||||
enum { value = !is_fundamental<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_array { enum { value = false }; };
|
||||
template<typename T> struct is_array<T[]> { enum { value = true }; };
|
||||
template<typename T, int N> struct is_array<T[N]> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_const { enum { value = false }; };
|
||||
template<typename T> struct is_const<const T> { enum { value = true }; };
|
||||
template<typename T> struct is_const<const T&> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_pointer { enum { value = false }; };
|
||||
template<typename T> struct is_pointer<T*> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_reference { enum { value = false }; };
|
||||
template<typename T> struct is_reference<T&> { enum { value = true }; };
|
||||
|
||||
template<typename T, typename U> struct is_same { enum { value = false }; };
|
||||
template<typename T> struct is_same<T, T> { enum { value = true }; };
|
||||
|
||||
//===
|
||||
//add
|
||||
//===
|
||||
|
||||
template<typename T> struct add_const { typedef const T type; };
|
||||
template<typename T> struct add_const<const T> { typedef const T type; };
|
||||
template<typename T> struct add_const<const T&> { typedef const T& type; };
|
||||
|
||||
template<typename T> struct add_pointer { typedef T* type; };
|
||||
template<typename T> struct add_pointer<T*> { typedef T** type; };
|
||||
|
||||
template<typename T> struct add_reference { typedef T& type; };
|
||||
template<typename T> struct add_reference<T&> { typedef T& type; };
|
||||
|
||||
//======
|
||||
//remove
|
||||
//======
|
||||
|
||||
template<typename T> struct remove_const { typedef T type; };
|
||||
template<typename T> struct remove_const<const T> { typedef T type; };
|
||||
template<typename T> struct remove_const<const T&> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_extent { typedef T type; };
|
||||
template<typename T> struct remove_extent<T[]> { typedef T type; };
|
||||
template<typename T, int N> struct remove_extent<T[N]> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_pointer { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T*> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_reference { typedef T type; };
|
||||
template<typename T> struct remove_reference<T&> { typedef T type; };
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,29 +1,18 @@
|
||||
#ifndef NALL_UTILITY_HPP
|
||||
#define NALL_UTILITY_HPP
|
||||
|
||||
#include <nall/traits.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> struct identity {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T> typename remove_reference<T>::type&& move(T &&value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T> T&& forward(typename identity<T>::type &&value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template<bool C, typename T = bool> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> {};
|
||||
template<typename C, typename T = bool> struct mp_enable_if : enable_if<C::value, T> {};
|
||||
|
||||
template<typename T> inline void swap(T &x, T &y) {
|
||||
T temp(move(x));
|
||||
x = move(y);
|
||||
y = move(temp);
|
||||
T temp(std::move(x));
|
||||
x = std::move(y);
|
||||
y = std::move(temp);
|
||||
}
|
||||
|
||||
template<typename T> struct base_from_member {
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
#include <initializer_list>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
@@ -86,11 +87,12 @@ namespace nall {
|
||||
inline linear_vector<T>& operator=(const linear_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
for(unsigned i = 0; i < source.size(); i++) add(source[i]);
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(const linear_vector<T> &source) {
|
||||
linear_vector(const linear_vector<T> &source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -101,11 +103,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(linear_vector<T> &&source) {
|
||||
operator=(move(source));
|
||||
linear_vector(linear_vector<T> &&source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//construction
|
||||
@@ -193,11 +196,12 @@ namespace nall {
|
||||
inline pointer_vector<T>& operator=(const pointer_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
for(unsigned i = 0; i < source.size(); i++) add(source[i]);
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(const pointer_vector<T> &source) {
|
||||
pointer_vector(const pointer_vector<T> &source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -208,11 +212,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(pointer_vector<T> &&source) {
|
||||
operator=(move(source));
|
||||
pointer_vector(pointer_vector<T> &&source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//construction
|
||||
|
||||
Binary file not shown.
@@ -59,7 +59,6 @@ $(foreach f,$(moc_objects), \
|
||||
$(eval $f: $(__file)) \
|
||||
)
|
||||
|
||||
|
||||
##################
|
||||
### snesreader ###
|
||||
##################
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#define NALL_ANY_HPP
|
||||
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
class any {
|
||||
@@ -13,8 +13,8 @@ namespace nall {
|
||||
|
||||
template<typename T> any& operator=(const T& value_) {
|
||||
typedef typename static_if<
|
||||
is_array<T>::value,
|
||||
typename remove_extent<typename add_const<T>::type>::type*,
|
||||
std::is_array<T>::value,
|
||||
typename std::remove_extent<typename std::add_const<T>::type>::type*,
|
||||
T
|
||||
>::type auto_t;
|
||||
|
||||
@@ -49,13 +49,13 @@ namespace nall {
|
||||
};
|
||||
|
||||
template<typename T> T any_cast(any &value) {
|
||||
typedef typename remove_reference<T>::type nonref;
|
||||
typedef typename std::remove_reference<T>::type nonref;
|
||||
if(value.type() != typeid(nonref)) throw;
|
||||
return static_cast<any::holder<nonref>*>(value.container)->value;
|
||||
}
|
||||
|
||||
template<typename T> T any_cast(const any &value) {
|
||||
typedef const typename remove_reference<T>::type nonref;
|
||||
typedef const typename std::remove_reference<T>::type nonref;
|
||||
if(value.type() != typeid(nonref)) throw;
|
||||
return static_cast<any::holder<nonref>*>(value.container)->value;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
//dynamic vector array
|
||||
@@ -81,7 +82,7 @@ namespace nall {
|
||||
return *this;
|
||||
}
|
||||
|
||||
array(const array &source) : pool(0) {
|
||||
array(const array &source) : pool(0), poolsize(0), buffersize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -92,11 +93,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
buffersize = source.buffersize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
array(array &&source) {
|
||||
operator=(move(source));
|
||||
array(array &&source) : pool(0), poolsize(0), buffersize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//index
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
for(unsigned foreach_counter = 0, foreach_limit = foreach_size(object), foreach_once = 0, foreach_broken = 0; foreach_counter < foreach_limit && foreach_broken == 0; foreach_counter++, foreach_once = 0) \
|
||||
for(auto &iter = object[foreach_counter]; foreach_once == 0 && (foreach_broken = 1); foreach_once++, foreach_broken = 0)
|
||||
|
||||
#include <type_traits>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<has_count<T>>::type = 0) {
|
||||
@@ -23,8 +23,8 @@ namespace nall {
|
||||
return object.size();
|
||||
}
|
||||
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<is_array<T>>::type = 0) {
|
||||
return sizeof(T) / sizeof(typename remove_extent<T>::type);
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<std::is_array<T>>::type = 0) {
|
||||
return sizeof(T) / sizeof(typename std::remove_extent<T>::type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+68
-156
@@ -1,190 +1,102 @@
|
||||
#ifndef NALL_FUNCTION_HPP
|
||||
#define NALL_FUNCTION_HPP
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
//prologue
|
||||
|
||||
#define TN typename
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> class function;
|
||||
}
|
||||
|
||||
//parameters = 0
|
||||
|
||||
#define cat(n) n
|
||||
#define TL typename R
|
||||
#define PL
|
||||
#define CL
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 1
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1
|
||||
#define PL P1 p1
|
||||
#define CL p1
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 2
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2
|
||||
#define PL P1 p1, P2 p2
|
||||
#define CL p1, p2
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 3
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3
|
||||
#define PL P1 p1, P2 p2, P3 p3
|
||||
#define CL p1, p2, p3
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 4
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4
|
||||
#define CL p1, p2, p3, p4
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 5
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5
|
||||
#define CL p1, p2, p3, p4, p5
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 6
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6
|
||||
#define CL p1, p2, p3, p4, p5, p6
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 7
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6, TN P7
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7
|
||||
#define CL p1, p2, p3, p4, p5, p6, p7
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 8
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6, TN P7, TN P8
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8
|
||||
#define CL p1, p2, p3, p4, p5, p6, p7, p8
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//epilogue
|
||||
|
||||
#undef TN
|
||||
#define NALL_FUNCTION_T
|
||||
|
||||
#elif !defined(NALL_FUNCTION_T)
|
||||
|
||||
//function implementation template class
|
||||
|
||||
namespace nall {
|
||||
template<TL>
|
||||
class function<R (PL)> {
|
||||
template<typename R, typename... P>
|
||||
class function<R (P...)> {
|
||||
private:
|
||||
struct base1 { virtual void func1(PL) {} };
|
||||
struct base2 { virtual void func2(PL) {} };
|
||||
struct base1 { virtual void func1(P...) {} };
|
||||
struct base2 { virtual void func2(P...) {} };
|
||||
struct derived : base1, virtual base2 {};
|
||||
|
||||
struct data_t {
|
||||
R (*fn_call)(const data_t& cat(PL));
|
||||
R (*callback)(const data_t&, P...);
|
||||
union {
|
||||
R (*fn_global)(PL);
|
||||
R (*callback_global)(P...);
|
||||
struct {
|
||||
R (derived::*fn_member)(PL);
|
||||
R (derived::*callback_member)(P...);
|
||||
void *object;
|
||||
};
|
||||
};
|
||||
} data;
|
||||
|
||||
static R fn_call_global(const data_t &d cat(PL)) {
|
||||
return d.fn_global(CL);
|
||||
static R callback_global(const data_t &data, P... p) {
|
||||
return data.callback_global(p...);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static R fn_call_member(const data_t &d cat(PL)) {
|
||||
return (((C*)d.object)->*((R (C::*&)(PL))d.fn_member))(CL);
|
||||
static R callback_member(const data_t &data, P... p) {
|
||||
return (((C*)data.object)->*((R (C::*&)(P...))data.callback_member))(p...);
|
||||
}
|
||||
|
||||
public:
|
||||
R operator()(PL) const { return data.fn_call(data cat(CL)); }
|
||||
operator bool() const { return data.fn_call; }
|
||||
R operator()(P... p) const { return data.callback(data, p...); }
|
||||
operator bool() const { return data.callback; }
|
||||
void reset() { data.callback = 0; }
|
||||
|
||||
function() { data.fn_call = 0; }
|
||||
|
||||
function(void *fn) {
|
||||
data.fn_call = fn ? &fn_call_global : 0;
|
||||
data.fn_global = (R (*)(PL))fn;
|
||||
}
|
||||
|
||||
function(R (*fn)(PL)) {
|
||||
data.fn_call = &fn_call_global;
|
||||
data.fn_global = fn;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
function(R (C::*fn)(PL), C *obj) {
|
||||
data.fn_call = &fn_call_member<C>;
|
||||
(R (C::*&)(PL))data.fn_member = fn;
|
||||
assert(sizeof data.fn_member >= sizeof fn);
|
||||
data.object = obj;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
function(R (C::*fn)(PL) const, C *obj) {
|
||||
data.fn_call = &fn_call_member<C>;
|
||||
(R (C::*&)(PL))data.fn_member = (R (C::*&)(PL))fn;
|
||||
assert(sizeof data.fn_member >= sizeof fn);
|
||||
data.object = obj;
|
||||
}
|
||||
|
||||
function& operator=(void *fn) { return operator=(function(fn)); }
|
||||
function& operator=(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); return *this; }
|
||||
function(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); }
|
||||
function(const function &source) { operator=(source); }
|
||||
|
||||
//no pointer
|
||||
function() {
|
||||
data.callback = 0;
|
||||
}
|
||||
|
||||
//symbolic link pointer (nall/dl.hpp::sym, etc)
|
||||
function(void *callback) {
|
||||
data.callback = callback ? &callback_global : 0;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
|
||||
//global function pointer
|
||||
function(R (*callback)(P...)) {
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = callback;
|
||||
}
|
||||
|
||||
//member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...), C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//const member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...) const, C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = (R (C::*&)(P...))callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//lambda function pointer
|
||||
template<typename T>
|
||||
function(T callback) {
|
||||
static_assert(std::is_same<R, typename std::result_of<T(P...)>::type>::value, "lambda mismatch");
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
};
|
||||
|
||||
template<TL>
|
||||
function<R (PL)> bind(R (*fn)(PL)) {
|
||||
return function<R (PL)>(fn);
|
||||
//bind functions to ease construction and assignment of function() with more than one argument
|
||||
|
||||
template<typename C, typename R, typename... P>
|
||||
function<R (P...)> bind(R (C::*callback)(P...), C *object) {
|
||||
return function<R (P...)>(callback, object);
|
||||
}
|
||||
|
||||
template<typename C, TL>
|
||||
function<R (PL)> bind(R (C::*fn)(PL), C *obj) {
|
||||
return function<R (PL)>(fn, obj);
|
||||
}
|
||||
|
||||
template<typename C, TL>
|
||||
function<R (PL)> bind(R (C::*fn)(PL) const, C *obj) {
|
||||
return function<R (PL)>(fn, obj);
|
||||
template<typename C, typename R, typename... P>
|
||||
function<R (P...)> bind(R (C::*callback)(P...) const, C *object) {
|
||||
return function<R (P...)>(callback, object);
|
||||
}
|
||||
}
|
||||
|
||||
#undef cat
|
||||
#undef TL
|
||||
#undef PL
|
||||
#undef CL
|
||||
|
||||
#endif
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifndef NALL_SERIALIZER_HPP
|
||||
#define NALL_SERIALIZER_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
@@ -16,6 +17,7 @@ namespace nall {
|
||||
//caveats:
|
||||
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
|
||||
//- floating-point usage is not portable across platforms
|
||||
|
||||
class serializer {
|
||||
public:
|
||||
enum mode_t { Load, Save, Size };
|
||||
@@ -51,7 +53,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
template<typename T> void integer(T &value) {
|
||||
enum { size = is_bool<T>::value ? 1 : sizeof(T) };
|
||||
enum { size = std::is_same<bool, T>::value ? 1 : sizeof(T) };
|
||||
if(imode == Save) {
|
||||
for(unsigned n = 0; n < size; n++) idata[isize++] = value >> (n << 3);
|
||||
} else if(imode == Load) {
|
||||
@@ -63,7 +65,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
template<typename T> void array(T &array) {
|
||||
enum { size = sizeof(T) / sizeof(typename remove_extent<T>::type) };
|
||||
enum { size = sizeof(T) / sizeof(typename std::remove_extent<T>::type) };
|
||||
for(unsigned n = 0; n < size; n++) integer(array[n]);
|
||||
}
|
||||
|
||||
@@ -102,7 +104,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
serializer(serializer &&s) {
|
||||
operator=(move(s));
|
||||
operator=(std::move(s));
|
||||
}
|
||||
|
||||
//construction
|
||||
|
||||
@@ -10,42 +10,13 @@
|
||||
#include <nall/utf8.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
|
||||
inline char chrlower(char c);
|
||||
inline char chrupper(char c);
|
||||
inline int stricmp(const char *dest, const char *src);
|
||||
inline int strpos (const char *str, const char *key);
|
||||
inline int qstrpos(const char *str, const char *key);
|
||||
inline bool strbegin (const char *str, const char *key);
|
||||
inline bool stribegin(const char *str, const char *key);
|
||||
inline bool strend (const char *str, const char *key);
|
||||
inline bool striend(const char *str, const char *key);
|
||||
inline char* strlower(char *str);
|
||||
inline char* strupper(char *str);
|
||||
inline char* strtr(char *dest, const char *before, const char *after);
|
||||
inline uintmax_t strhex (const char *str);
|
||||
inline intmax_t strsigned (const char *str);
|
||||
inline uintmax_t strunsigned(const char *str);
|
||||
inline uintmax_t strbin (const char *str);
|
||||
inline double strdouble (const char *str);
|
||||
inline bool match(const char *pattern, const char *str);
|
||||
inline bool strint (const char *str, int &result);
|
||||
inline bool strmath(const char *str, int &result);
|
||||
inline size_t strlcpy(char *dest, const char *src, size_t length);
|
||||
inline size_t strlcat(char *dest, const char *src, size_t length);
|
||||
inline char* ltrim(char *str, const char *key = " ");
|
||||
inline char* rtrim(char *str, const char *key = " ");
|
||||
inline char* trim (char *str, const char *key = " ");
|
||||
inline char* ltrim_once(char *str, const char *key = " ");
|
||||
inline char* rtrim_once(char *str, const char *key = " ");
|
||||
inline char* trim_once (char *str, const char *key = " ");
|
||||
|
||||
namespace nall {
|
||||
class string;
|
||||
template<typename T> inline string to_string(T);
|
||||
|
||||
class string {
|
||||
public:
|
||||
inline void reserve(size_t);
|
||||
inline void reserve(unsigned);
|
||||
inline unsigned length() const;
|
||||
|
||||
inline string& assign(const char*);
|
||||
@@ -78,7 +49,7 @@ namespace nall {
|
||||
|
||||
protected:
|
||||
char *data;
|
||||
size_t size;
|
||||
unsigned size;
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
public:
|
||||
@@ -98,29 +69,69 @@ namespace nall {
|
||||
lstring(std::initializer_list<string>);
|
||||
};
|
||||
|
||||
template<typename... Args> inline string sprint(const char *s, Args... args);
|
||||
template<typename... Args> inline void print(const char *s, Args... args);
|
||||
//compare.hpp
|
||||
inline char chrlower(char c);
|
||||
inline char chrupper(char c);
|
||||
inline int stricmp(const char *dest, const char *src);
|
||||
inline int strpos (const char *str, const char *key);
|
||||
inline int qstrpos(const char *str, const char *key);
|
||||
inline bool strbegin (const char *str, const char *key);
|
||||
inline bool stribegin(const char *str, const char *key);
|
||||
inline bool strend (const char *str, const char *key);
|
||||
inline bool striend(const char *str, const char *key);
|
||||
|
||||
//convert.hpp
|
||||
inline char* strlower(char *str);
|
||||
inline char* strupper(char *str);
|
||||
inline char* strtr(char *dest, const char *before, const char *after);
|
||||
inline uintmax_t strhex (const char *str);
|
||||
inline intmax_t strsigned (const char *str);
|
||||
inline uintmax_t strunsigned(const char *str);
|
||||
inline uintmax_t strbin (const char *str);
|
||||
inline double strdouble (const char *str);
|
||||
|
||||
//match.hpp
|
||||
inline bool match(const char *pattern, const char *str);
|
||||
|
||||
//math.hpp
|
||||
inline bool strint (const char *str, int &result);
|
||||
inline bool strmath(const char *str, int &result);
|
||||
|
||||
//strl.hpp
|
||||
inline unsigned strlcpy(char *dest, const char *src, unsigned length);
|
||||
inline unsigned strlcat(char *dest, const char *src, unsigned length);
|
||||
|
||||
//trim.hpp
|
||||
inline char* ltrim(char *str, const char *key = " ");
|
||||
inline char* rtrim(char *str, const char *key = " ");
|
||||
inline char* trim (char *str, const char *key = " ");
|
||||
inline char* ltrim_once(char *str, const char *key = " ");
|
||||
inline char* rtrim_once(char *str, const char *key = " ");
|
||||
inline char* trim_once (char *str, const char *key = " ");
|
||||
|
||||
//utility.hpp
|
||||
inline unsigned strlcpy(string &dest, const char *src, unsigned length);
|
||||
inline unsigned strlcat(string &dest, const char *src, unsigned length);
|
||||
inline string substr(const char *src, unsigned start = 0, unsigned length = 0);
|
||||
inline string& strlower(string &str);
|
||||
inline string& strupper(string &str);
|
||||
inline string& strtr(string &dest, const char *before, const char *after);
|
||||
inline string& ltrim(string &str, const char *key = " ");
|
||||
inline string& rtrim(string &str, const char *key = " ");
|
||||
inline string& trim (string &str, const char *key = " ");
|
||||
inline string& ltrim_once(string &str, const char *key = " ");
|
||||
inline string& rtrim_once(string &str, const char *key = " ");
|
||||
inline string& trim_once (string &str, const char *key = " ");
|
||||
template<unsigned length = 0, char padding = '0'> inline string strhex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strsigned(intmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strunsigned(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strbin(uintmax_t value);
|
||||
inline unsigned strdouble(char *str, double value);
|
||||
inline string strdouble(double value);
|
||||
|
||||
//variadic.hpp
|
||||
template<typename... Args> inline string sprint(Args... args);
|
||||
template<typename... Args> inline void print(Args... args);
|
||||
};
|
||||
|
||||
inline size_t strlcpy(nall::string &dest, const char *src, size_t length);
|
||||
inline size_t strlcat(nall::string &dest, const char *src, size_t length);
|
||||
|
||||
inline nall::string& strlower(nall::string &str);
|
||||
inline nall::string& strupper(nall::string &str);
|
||||
inline nall::string& strtr(nall::string &dest, const char *before, const char *after);
|
||||
inline nall::string& ltrim(nall::string &str, const char *key = " ");
|
||||
inline nall::string& rtrim(nall::string &str, const char *key = " ");
|
||||
inline nall::string& trim (nall::string &str, const char *key = " ");
|
||||
inline nall::string& ltrim_once(nall::string &str, const char *key = " ");
|
||||
inline nall::string& rtrim_once(nall::string &str, const char *key = " ");
|
||||
inline nall::string& trim_once (nall::string &str, const char *key = " ");
|
||||
|
||||
inline nall::string substr(const char *src, size_t start = 0, size_t length = 0);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strhex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strsigned(intmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strunsigned(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strbin(uintmax_t value);
|
||||
inline size_t strdouble(char *str, double value);
|
||||
inline nall::string strdouble(double value);
|
||||
|
||||
#endif
|
||||
@@ -2,28 +2,31 @@
|
||||
#define NALL_STRING_CAST_HPP
|
||||
|
||||
namespace nall {
|
||||
//this is needed, as C++0x does not support explicit template specialization inside classes
|
||||
template<> inline string to_string<bool> (bool v) { return v ? "true" : "false"; }
|
||||
template<> inline string to_string<signed int> (signed int v) { return strsigned(v); }
|
||||
template<> inline string to_string<unsigned int> (unsigned int v) { return strunsigned(v); }
|
||||
template<> inline string to_string<double> (double v) { return strdouble(v); }
|
||||
template<> inline string to_string<char*> (char *v) { return v; }
|
||||
template<> inline string to_string<const char*> (const char *v) { return v; }
|
||||
template<> inline string to_string<string> (string v) { return v; }
|
||||
template<> inline string to_string<const string&>(const string &v) { return v; }
|
||||
|
||||
template<typename T> string& string::operator= (T value) { return assign(to_string<T>(value)); }
|
||||
template<typename T> string& string::operator<<(T value) { return append(to_string<T>(value)); }
|
||||
//this is needed, as C++0x does not support explicit template specialization inside classes
|
||||
template<> inline string to_string<bool> (bool v) { return v ? "true" : "false"; }
|
||||
template<> inline string to_string<signed int> (signed int v) { return strsigned(v); }
|
||||
template<> inline string to_string<unsigned int> (unsigned int v) { return strunsigned(v); }
|
||||
template<> inline string to_string<double> (double v) { return strdouble(v); }
|
||||
template<> inline string to_string<char*> (char *v) { return v; }
|
||||
template<> inline string to_string<const char*> (const char *v) { return v; }
|
||||
template<> inline string to_string<string> (string v) { return v; }
|
||||
template<> inline string to_string<const string&>(const string &v) { return v; }
|
||||
|
||||
template<typename T> lstring& lstring::operator<<(T value) {
|
||||
operator[](size()).assign(to_string<T>(value));
|
||||
return *this;
|
||||
}
|
||||
template<typename T> string& string::operator= (T value) { return assign(to_string<T>(value)); }
|
||||
template<typename T> string& string::operator<<(T value) { return append(to_string<T>(value)); }
|
||||
|
||||
template<typename T> lstring& lstring::operator<<(T value) {
|
||||
operator[](size()).assign(to_string<T>(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
template<> inline string to_string<QString>(QString v) { return v.toUtf8().constData(); }
|
||||
template<> inline string to_string<const QString&>(const QString &v) { return v.toUtf8().constData(); }
|
||||
string::operator QString() const { return QString::fromUtf8(*this); }
|
||||
#endif
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
template<> inline string to_string<const QString&>(const QString &v) { return v.toUtf8().constData(); }
|
||||
string::operator QString() const { return QString::fromUtf8(*this); }
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_COMPARE_HPP
|
||||
#define NALL_STRING_COMPARE_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char chrlower(char c) {
|
||||
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c;
|
||||
}
|
||||
@@ -97,4 +99,6 @@ bool striend(const char *str, const char *key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_CONVERT_HPP
|
||||
#define NALL_STRING_CONVERT_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char* strlower(char *str) {
|
||||
if(!str) return 0;
|
||||
int i = 0;
|
||||
@@ -146,4 +148,6 @@ double strdouble(const char *str) {
|
||||
return !negate ? result : -result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
void string::reserve(size_t size_) {
|
||||
void string::reserve(unsigned size_) {
|
||||
if(size_ > size) {
|
||||
size = size_;
|
||||
data = (char*)realloc(data, size + 1);
|
||||
@@ -81,6 +81,7 @@ string& string::operator=(string &&source) {
|
||||
size = source.size;
|
||||
data = source.data;
|
||||
source.data = 0;
|
||||
source.size = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -94,12 +95,12 @@ bool string::readfile(const char *filename) {
|
||||
#if !defined(_WIN32)
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
#else
|
||||
FILE *fp = _wfopen(nall::utf16_t(filename), L"rb");
|
||||
FILE *fp = _wfopen(utf16_t(filename), L"rb");
|
||||
#endif
|
||||
if(!fp) return false;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t size = ftell(fp);
|
||||
unsigned size = ftell(fp);
|
||||
rewind(fp);
|
||||
char *fdata = new char[size + 1];
|
||||
unsigned unused = fread(fdata, 1, size, fp);
|
||||
|
||||
@@ -2,59 +2,60 @@
|
||||
#define NALL_FILENAME_HPP
|
||||
|
||||
namespace nall {
|
||||
// "foo/bar.c" -> "foo/", "bar.c" -> "./"
|
||||
inline string dir(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
result[i + 1] = 0;
|
||||
break;
|
||||
}
|
||||
if(i == 0) result = "./";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "bar.c"
|
||||
inline string notdir(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
// "foo/bar.c" -> "foo/", "bar.c" -> "./"
|
||||
inline string dir(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
result[i + 1] = 0;
|
||||
break;
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
if(i == 0) result = "./";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "foo/bar"
|
||||
inline string basename(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
//file has no extension
|
||||
break;
|
||||
}
|
||||
|
||||
if(result[i] == '.') {
|
||||
result[i] = 0;
|
||||
break;
|
||||
}
|
||||
// "foo/bar.c" -> "bar.c"
|
||||
inline string notdir(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "c"
|
||||
inline string extension(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '.') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
// "foo/bar.c" -> "foo/bar"
|
||||
inline string basename(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
//file has no extension
|
||||
break;
|
||||
}
|
||||
if(result[i] == '.') {
|
||||
result[i] = 0;
|
||||
break;
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "c"
|
||||
inline string extension(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '.') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_MATCH_HPP
|
||||
#define NALL_STRING_MATCH_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
bool match(const char *p, const char *s) {
|
||||
const char *p_ = 0, *s_ = 0;
|
||||
|
||||
@@ -69,4 +71,6 @@ bool match(const char *p, const char *s) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_MATH_HPP
|
||||
#define NALL_STRING_MATH_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
static int eval_integer(const char *&s) {
|
||||
if(!*s) throw "unrecognized_integer";
|
||||
int value = 0, x = *s, y = *(s + 1);
|
||||
@@ -157,4 +159,6 @@ bool strmath(const char *s, int &result) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,13 +1,15 @@
|
||||
#ifndef NALL_STRING_STRL_HPP
|
||||
#define NALL_STRING_STRL_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
//strlcpy, strlcat based on OpenBSD implementation by Todd C. Miller
|
||||
|
||||
//return = strlen(src)
|
||||
size_t strlcpy(char *dest, const char *src, size_t length) {
|
||||
unsigned strlcpy(char *dest, const char *src, unsigned length) {
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t n = length;
|
||||
unsigned n = length;
|
||||
|
||||
if(n) {
|
||||
while(--n && (*d++ = *s++)); //copy as many bytes as possible, or until null terminator reached
|
||||
@@ -22,13 +24,13 @@ size_t strlcpy(char *dest, const char *src, size_t length) {
|
||||
}
|
||||
|
||||
//return = strlen(src) + min(length, strlen(dest))
|
||||
size_t strlcat(char *dest, const char *src, size_t length) {
|
||||
unsigned strlcat(char *dest, const char *src, unsigned length) {
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t n = length;
|
||||
unsigned n = length;
|
||||
|
||||
while(n-- && *d) d++; //find end of dest
|
||||
size_t dlength = d - dest;
|
||||
unsigned dlength = d - dest;
|
||||
n = length - dlength; //subtract length of dest from maximum string length
|
||||
|
||||
if(!n) return dlength + strlen(s);
|
||||
@@ -45,4 +47,6 @@ size_t strlcat(char *dest, const char *src, size_t length) {
|
||||
return dlength + (s - src); //return length of resulting string, sans null terminator
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_TRIM_HPP
|
||||
#define NALL_STRING_TRIM_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char* ltrim(char *str, const char *key) {
|
||||
if(!key || !*key) return str;
|
||||
while(strbegin(str, key)) {
|
||||
@@ -47,4 +49,6 @@ char* trim_once(char *str, const char *key) {
|
||||
return ltrim_once(rtrim_once(str, key), key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,18 +1,20 @@
|
||||
#ifndef NALL_STRING_UTILITY_HPP
|
||||
#define NALL_STRING_UTILITY_HPP
|
||||
|
||||
size_t strlcpy(nall::string &dest, const char *src, size_t length) {
|
||||
namespace nall {
|
||||
|
||||
unsigned strlcpy(string &dest, const char *src, unsigned length) {
|
||||
dest.reserve(length);
|
||||
return strlcpy(dest(), src, length);
|
||||
}
|
||||
|
||||
size_t strlcat(nall::string &dest, const char *src, size_t length) {
|
||||
unsigned strlcat(string &dest, const char *src, unsigned length) {
|
||||
dest.reserve(length);
|
||||
return strlcat(dest(), src, length);
|
||||
}
|
||||
|
||||
nall::string substr(const char *src, size_t start, size_t length) {
|
||||
nall::string dest;
|
||||
string substr(const char *src, unsigned start, unsigned length) {
|
||||
string dest;
|
||||
if(length == 0) {
|
||||
//copy entire string
|
||||
dest = src + start;
|
||||
@@ -23,22 +25,22 @@ nall::string substr(const char *src, size_t start, size_t length) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* very simplistic wrappers to return nall::string& instead of char* type */
|
||||
/* very simplistic wrappers to return string& instead of char* type */
|
||||
|
||||
nall::string& strlower(nall::string &str) { strlower(str()); return str; }
|
||||
nall::string& strupper(nall::string &str) { strupper(str()); return str; }
|
||||
nall::string& strtr(nall::string &dest, const char *before, const char *after) { strtr(dest(), before, after); return dest; }
|
||||
nall::string& ltrim(nall::string &str, const char *key) { ltrim(str(), key); return str; }
|
||||
nall::string& rtrim(nall::string &str, const char *key) { rtrim(str(), key); return str; }
|
||||
nall::string& trim (nall::string &str, const char *key) { trim (str(), key); return str; }
|
||||
nall::string& ltrim_once(nall::string &str, const char *key) { ltrim_once(str(), key); return str; }
|
||||
nall::string& rtrim_once(nall::string &str, const char *key) { rtrim_once(str(), key); return str; }
|
||||
nall::string& trim_once (nall::string &str, const char *key) { trim_once (str(), key); return str; }
|
||||
string& strlower(string &str) { strlower(str()); return str; }
|
||||
string& strupper(string &str) { strupper(str()); return str; }
|
||||
string& strtr(string &dest, const char *before, const char *after) { strtr(dest(), before, after); return dest; }
|
||||
string& ltrim(string &str, const char *key) { ltrim(str(), key); return str; }
|
||||
string& rtrim(string &str, const char *key) { rtrim(str(), key); return str; }
|
||||
string& trim (string &str, const char *key) { trim (str(), key); return str; }
|
||||
string& ltrim_once(string &str, const char *key) { ltrim_once(str(), key); return str; }
|
||||
string& rtrim_once(string &str, const char *key) { rtrim_once(str(), key); return str; }
|
||||
string& trim_once (string &str, const char *key) { trim_once (str(), key); return str; }
|
||||
|
||||
/* arithmetic <> string */
|
||||
|
||||
template<unsigned length, char padding> nall::string strhex(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strhex(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
//render string backwards, as we do not know its length yet
|
||||
@@ -61,8 +63,8 @@ template<unsigned length, char padding> nall::string strhex(uintmax_t value) {
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strsigned(intmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strsigned(intmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
bool negative = value < 0;
|
||||
@@ -87,8 +89,8 @@ template<unsigned length, char padding> nall::string strsigned(intmax_t value) {
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strunsigned(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strunsigned(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
do {
|
||||
@@ -109,8 +111,8 @@ template<unsigned length, char padding> nall::string strunsigned(uintmax_t value
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strbin(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strbin(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
do {
|
||||
@@ -134,7 +136,7 @@ template<unsigned length, char padding> nall::string strbin(uintmax_t value) {
|
||||
//using sprintf is certainly not the most ideal method to convert
|
||||
//a double to a string ... but attempting to parse a double by
|
||||
//hand, digit-by-digit, results in subtle rounding errors.
|
||||
size_t strdouble(char *str, double value) {
|
||||
unsigned strdouble(char *str, double value) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "%f", value);
|
||||
|
||||
@@ -155,11 +157,13 @@ size_t strdouble(char *str, double value) {
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
nall::string strdouble(double value) {
|
||||
nall::string temp;
|
||||
string strdouble(double value) {
|
||||
string temp;
|
||||
temp.reserve(strdouble(0, value));
|
||||
strdouble(temp(), value);
|
||||
return temp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,36 +2,26 @@
|
||||
#define NALL_STRING_VARIADIC_HPP
|
||||
|
||||
namespace nall {
|
||||
static void sprint(string &output, unsigned &offset, const char *&s) {
|
||||
while(*s) output[offset++] = *s++;
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static void sprint(string &output, unsigned &offset, const char *&s, T value, Args... args) {
|
||||
while(*s) {
|
||||
if(*s == '$') {
|
||||
string data = to_string<T>(value);
|
||||
unsigned i = 0;
|
||||
while(data[i]) output[offset++] = data[i++];
|
||||
sprint(output, offset, ++s, args...);
|
||||
return;
|
||||
} else {
|
||||
output[offset++] = *s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void isprint(string &output) {
|
||||
}
|
||||
|
||||
template<typename... Args> inline string sprint(const char *s, Args... args) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
sprint(output, offset, s, args...);
|
||||
output[offset] = 0;
|
||||
return output;
|
||||
}
|
||||
template<typename T, typename... Args>
|
||||
static void isprint(string &output, T value, Args... args) {
|
||||
output << to_string<T>(value);
|
||||
isprint(output, args...);
|
||||
}
|
||||
|
||||
template<typename... Args> inline string sprint(Args... args) {
|
||||
string output;
|
||||
isprint(output, args...);
|
||||
return output;
|
||||
}
|
||||
|
||||
template<typename... Args> inline void print(Args... args) {
|
||||
printf("%s", (const char*)sprint(args...));
|
||||
}
|
||||
|
||||
template<typename... Args> inline void print(const char *s, Args... args) {
|
||||
printf("%s", (const char*)sprint(s, args...));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,9 +2,7 @@
|
||||
#define NALL_STRING_XML_HPP
|
||||
|
||||
//XML subset parser
|
||||
//version 0.04
|
||||
|
||||
#include <nall/array.hpp>
|
||||
//version 0.05
|
||||
|
||||
namespace nall {
|
||||
|
||||
@@ -16,15 +14,14 @@ struct xml_attribute {
|
||||
|
||||
struct xml_element : xml_attribute {
|
||||
string parse() const;
|
||||
array<xml_attribute*> attribute;
|
||||
array<xml_element*> element;
|
||||
~xml_element();
|
||||
linear_vector<xml_attribute> attribute;
|
||||
linear_vector<xml_element> element;
|
||||
|
||||
protected:
|
||||
void parse_doctype(const char *&data);
|
||||
bool parse_head(string data);
|
||||
bool parse_body(const char *&data);
|
||||
friend xml_element *xml_parse(const char *data);
|
||||
friend xml_element xml_parse(const char *data);
|
||||
};
|
||||
|
||||
inline string xml_attribute::parse() const {
|
||||
@@ -134,11 +131,11 @@ inline bool xml_element::parse_head(string data) {
|
||||
side.qsplit("=", part[i]);
|
||||
if(side.size() != 2) throw "...";
|
||||
|
||||
xml_attribute *attr = new xml_attribute;
|
||||
attr->name = side[0];
|
||||
attr->content = side[1];
|
||||
if(strbegin(attr->content, "\"") && strend(attr->content, "\"")) trim_once(attr->content, "\"");
|
||||
else if(strbegin(attr->content, "'") && strend(attr->content, "'")) trim_once(attr->content, "'");
|
||||
xml_attribute attr;
|
||||
attr.name = side[0];
|
||||
attr.content = side[1];
|
||||
if(strbegin(attr.content, "\"") && strend(attr.content, "\"")) trim_once(attr.content, "\"");
|
||||
else if(strbegin(attr.content, "'") && strend(attr.content, "'")) trim_once(attr.content, "'");
|
||||
else throw "...";
|
||||
attribute.add(attr);
|
||||
}
|
||||
@@ -191,10 +188,8 @@ inline bool xml_element::parse_body(const char *&data) {
|
||||
|
||||
while(*data) {
|
||||
unsigned index = element.size();
|
||||
xml_element *elem = new xml_element;
|
||||
if(elem->parse_body(data) == false) {
|
||||
delete elem;
|
||||
|
||||
xml_element node;
|
||||
if(node.parse_body(data) == false) {
|
||||
if(*data == '/') {
|
||||
signed length = data - content_begin - 1;
|
||||
if(length > 0) content = substr(content_begin, 0, length);
|
||||
@@ -216,23 +211,18 @@ inline bool xml_element::parse_body(const char *&data) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
element.add(elem);
|
||||
element.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline xml_element::~xml_element() {
|
||||
for(unsigned i = 0; i < attribute.size(); i++) delete attribute[i];
|
||||
for(unsigned i = 0; i < element.size(); i++) delete element[i];
|
||||
}
|
||||
|
||||
//ensure there is only one root element
|
||||
inline bool xml_validate(xml_element *document) {
|
||||
inline bool xml_validate(xml_element &document) {
|
||||
unsigned root_counter = 0;
|
||||
|
||||
for(unsigned i = 0; i < document->element.size(); i++) {
|
||||
string &name = document->element[i]->name;
|
||||
for(unsigned i = 0; i < document.element.size(); i++) {
|
||||
string &name = document.element[i].name;
|
||||
if(strbegin(name, "?")) continue;
|
||||
if(strbegin(name, "!")) continue;
|
||||
if(++root_counter > 1) return false;
|
||||
@@ -241,25 +231,24 @@ inline bool xml_validate(xml_element *document) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline xml_element* xml_parse(const char *data) {
|
||||
xml_element *self = new xml_element;
|
||||
inline xml_element xml_parse(const char *data) {
|
||||
xml_element self;
|
||||
|
||||
try {
|
||||
while(*data) {
|
||||
xml_element *elem = new xml_element;
|
||||
if(elem->parse_body(data) == false) {
|
||||
delete elem;
|
||||
xml_element node;
|
||||
if(node.parse_body(data) == false) {
|
||||
break;
|
||||
} else {
|
||||
self->element.add(elem);
|
||||
self.element.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
if(xml_validate(self) == false) throw "...";
|
||||
return self;
|
||||
} catch(const char*) {
|
||||
delete self;
|
||||
return 0;
|
||||
xml_element empty;
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
#ifndef NALL_TRAITS_HPP
|
||||
#define NALL_TRAITS_HPP
|
||||
|
||||
namespace nall {
|
||||
//==
|
||||
//is
|
||||
//==
|
||||
|
||||
template<typename T> struct is_integral { enum { value = false }; };
|
||||
template<> struct is_integral<bool> { enum { value = true }; };
|
||||
template<> struct is_integral<char> { enum { value = true }; };
|
||||
template<> struct is_integral<signed char> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned char> { enum { value = true }; };
|
||||
template<> struct is_integral<wchar_t> { enum { value = true }; };
|
||||
template<> struct is_integral<short> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned short> { enum { value = true }; };
|
||||
template<> struct is_integral<long> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned long> { enum { value = true }; };
|
||||
template<> struct is_integral<long long> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned long long> { enum { value = true }; };
|
||||
template<> struct is_integral<int> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned int> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_floating_point { enum { value = false }; };
|
||||
template<> struct is_floating_point<float> { enum { value = true }; };
|
||||
template<> struct is_floating_point<double> { enum { value = true }; };
|
||||
template<> struct is_floating_point<long double> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_bool { enum { value = false }; };
|
||||
template<> struct is_bool<bool> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_void { enum { value = false }; };
|
||||
template<> struct is_void<void> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_arithmetic {
|
||||
enum { value = is_integral<T>::value || is_floating_point<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_fundamental {
|
||||
enum { value = is_integral<T>::value || is_floating_point<T>::value || is_void<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_compound {
|
||||
enum { value = !is_fundamental<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_array { enum { value = false }; };
|
||||
template<typename T> struct is_array<T[]> { enum { value = true }; };
|
||||
template<typename T, int N> struct is_array<T[N]> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_const { enum { value = false }; };
|
||||
template<typename T> struct is_const<const T> { enum { value = true }; };
|
||||
template<typename T> struct is_const<const T&> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_pointer { enum { value = false }; };
|
||||
template<typename T> struct is_pointer<T*> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_reference { enum { value = false }; };
|
||||
template<typename T> struct is_reference<T&> { enum { value = true }; };
|
||||
|
||||
template<typename T, typename U> struct is_same { enum { value = false }; };
|
||||
template<typename T> struct is_same<T, T> { enum { value = true }; };
|
||||
|
||||
//===
|
||||
//add
|
||||
//===
|
||||
|
||||
template<typename T> struct add_const { typedef const T type; };
|
||||
template<typename T> struct add_const<const T> { typedef const T type; };
|
||||
template<typename T> struct add_const<const T&> { typedef const T& type; };
|
||||
|
||||
template<typename T> struct add_pointer { typedef T* type; };
|
||||
template<typename T> struct add_pointer<T*> { typedef T** type; };
|
||||
|
||||
template<typename T> struct add_reference { typedef T& type; };
|
||||
template<typename T> struct add_reference<T&> { typedef T& type; };
|
||||
|
||||
//======
|
||||
//remove
|
||||
//======
|
||||
|
||||
template<typename T> struct remove_const { typedef T type; };
|
||||
template<typename T> struct remove_const<const T> { typedef T type; };
|
||||
template<typename T> struct remove_const<const T&> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_extent { typedef T type; };
|
||||
template<typename T> struct remove_extent<T[]> { typedef T type; };
|
||||
template<typename T, int N> struct remove_extent<T[N]> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_pointer { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T*> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_reference { typedef T type; };
|
||||
template<typename T> struct remove_reference<T&> { typedef T type; };
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,29 +1,18 @@
|
||||
#ifndef NALL_UTILITY_HPP
|
||||
#define NALL_UTILITY_HPP
|
||||
|
||||
#include <nall/traits.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> struct identity {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T> typename remove_reference<T>::type&& move(T &&value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T> T&& forward(typename identity<T>::type &&value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template<bool C, typename T = bool> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> {};
|
||||
template<typename C, typename T = bool> struct mp_enable_if : enable_if<C::value, T> {};
|
||||
|
||||
template<typename T> inline void swap(T &x, T &y) {
|
||||
T temp(move(x));
|
||||
x = move(y);
|
||||
y = move(temp);
|
||||
T temp(std::move(x));
|
||||
x = std::move(y);
|
||||
y = std::move(temp);
|
||||
}
|
||||
|
||||
template<typename T> struct base_from_member {
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
#include <initializer_list>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
@@ -86,11 +87,12 @@ namespace nall {
|
||||
inline linear_vector<T>& operator=(const linear_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
for(unsigned i = 0; i < source.size(); i++) add(source[i]);
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(const linear_vector<T> &source) {
|
||||
linear_vector(const linear_vector<T> &source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -101,11 +103,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(linear_vector<T> &&source) {
|
||||
operator=(move(source));
|
||||
linear_vector(linear_vector<T> &&source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//construction
|
||||
@@ -193,11 +196,12 @@ namespace nall {
|
||||
inline pointer_vector<T>& operator=(const pointer_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
for(unsigned i = 0; i < source.size(); i++) add(source[i]);
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(const pointer_vector<T> &source) {
|
||||
pointer_vector(const pointer_vector<T> &source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -208,11 +212,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(pointer_vector<T> &&source) {
|
||||
operator=(move(source));
|
||||
pointer_vector(pointer_vector<T> &&source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//construction
|
||||
|
||||
@@ -194,9 +194,8 @@ bool snesreader_load_jma(const char *filename, uint8_t *&data, unsigned &size) {
|
||||
}
|
||||
}
|
||||
|
||||
dllexport bool snesreader_load(string &filename, string &xmldata, uint8_t *&data, unsigned &size) {
|
||||
dllexport bool snesreader_load(string &filename, uint8_t *&data, unsigned &size) {
|
||||
if(file::exists(filename) == false) return false;
|
||||
xmldata = "";
|
||||
|
||||
bool success = false;
|
||||
if(striend(filename, ".zip")
|
||||
@@ -226,6 +225,11 @@ dllexport bool snesreader_load(string &filename, string &xmldata, uint8_t *&data
|
||||
//remove copier header, if it exists
|
||||
if((size & 0x7fff) == 512) memmove(data, data + 512, size -= 512);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
dllexport bool snesreader_map(string &xmldata, const uint8_t *data, unsigned size) {
|
||||
xmldata = "";
|
||||
xml.generate(xmldata, data, size);
|
||||
return true;
|
||||
}
|
||||
@@ -3,5 +3,6 @@ namespace nall { class string; }
|
||||
|
||||
extern "C" {
|
||||
const char* snesreader_supported();
|
||||
bool snesreader_load(nall::string &filename, nall::string &xml, uint8_t *&data, unsigned &size);
|
||||
bool snesreader_load(nall::string &filename, uint8_t *&data, unsigned &size);
|
||||
bool snesreader_map(nall::string &xml, const uint8_t *data, unsigned size);
|
||||
}
|
||||
+30
-28
@@ -56,30 +56,6 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
xml << " <map address='80-bf:6000-7fff'/>\n";
|
||||
xml << " </mmio>\n";
|
||||
xml << " </supergameboy>\n";
|
||||
} else if(has_sdd1) {
|
||||
xml << " <rom>\n";
|
||||
xml << " <map mode='linear' address='00-3f:8000-ffff'/>\n";
|
||||
xml << " <map mode='linear' address='40-7f:0000-ffff'/>\n";
|
||||
xml << " <map mode='linear' address='80-bf:8000-ffff'/>\n";
|
||||
xml << " </rom>\n";
|
||||
|
||||
if(ram_size > 0) {
|
||||
xml << " <ram size='" << strhex(ram_size) << "'>\n";
|
||||
xml << " <map mode='linear' address='20-3f:6000-7fff'/>\n";
|
||||
xml << " <map mode='linear' address='a0-bf:6000-7fff'/>\n";
|
||||
xml << " <map mode='linear' address='70-7f:0000-7fff'/>\n";
|
||||
xml << " </ram>\n";
|
||||
}
|
||||
|
||||
xml << " <sdd1>\n";
|
||||
xml << " <mcu>\n";
|
||||
xml << " <map address='c0-ff:0000-ffff'/>\n";
|
||||
xml << " </mcu>\n";
|
||||
xml << " <mmio>\n";
|
||||
xml << " <map address='00-3f:4800-4807'/>\n";
|
||||
xml << " <map address='80-bf:4800-4807'/>\n";
|
||||
xml << " </mmio>\n";
|
||||
xml << " </sdd1>\n";
|
||||
} else if(has_spc7110) {
|
||||
xml << " <rom>\n";
|
||||
xml << " <map mode='shadow' address='00-0f:8000-ffff'/>\n";
|
||||
@@ -147,6 +123,20 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
}
|
||||
xml << " </ram>\n";
|
||||
}
|
||||
} else if(mapper == ExLoROM) {
|
||||
xml << " <rom>\n";
|
||||
xml << " <map mode='linear' address='00-3f:8000-ffff'/>\n";
|
||||
xml << " <map mode='linear' address='40-7f:0000-ffff'/>\n";
|
||||
xml << " <map mode='linear' address='80-bf:8000-ffff'/>\n";
|
||||
xml << " </rom>\n";
|
||||
|
||||
if(ram_size > 0) {
|
||||
xml << " <ram size='" << strhex(ram_size) << "'>\n";
|
||||
xml << " <map mode='linear' address='20-3f:6000-7fff'/>\n";
|
||||
xml << " <map mode='linear' address='a0-bf:6000-7fff'/>\n";
|
||||
xml << " <map mode='linear' address='70-7f:0000-7fff'/>\n";
|
||||
xml << " </ram>\n";
|
||||
}
|
||||
} else if(mapper == ExHiROM) {
|
||||
xml << " <rom>\n";
|
||||
xml << " <map mode='shadow' address='00-3f:8000-ffff' offset='400000'/>\n";
|
||||
@@ -290,6 +280,18 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
xml << " </srtc>\n";
|
||||
}
|
||||
|
||||
if(has_sdd1) {
|
||||
xml << " <sdd1>\n";
|
||||
xml << " <mcu>\n";
|
||||
xml << " <map address='c0-ff:0000-ffff'/>\n";
|
||||
xml << " </mcu>\n";
|
||||
xml << " <mmio>\n";
|
||||
xml << " <map address='00-3f:4800-4807'/>\n";
|
||||
xml << " <map address='80-bf:4800-4807'/>\n";
|
||||
xml << " </mmio>\n";
|
||||
xml << " </sdd1>\n";
|
||||
}
|
||||
|
||||
if(has_cx4) {
|
||||
xml << " <cx4>\n";
|
||||
xml << " <mmio>\n";
|
||||
@@ -335,12 +337,12 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
if(has_dsp2) {
|
||||
xml << " <necdsp program='DSP-2'>\n";
|
||||
xml << " <dr>\n";
|
||||
xml << " <map address='20-3f:6000-6fff'/>\n";
|
||||
xml << " <map address='a0-bf:6000-6fff'/>\n";
|
||||
xml << " </dr>\n";
|
||||
xml << " <sr>\n";
|
||||
xml << " <map address='20-3f:8000-bfff'/>\n";
|
||||
xml << " <map address='a0-bf:8000-bfff'/>\n";
|
||||
xml << " </dr>\n";
|
||||
xml << " <sr>\n";
|
||||
xml << " <map address='20-3f:c000-ffff'/>\n";
|
||||
xml << " <map address='a0-bf:c000-ffff'/>\n";
|
||||
xml << " </sr>\n";
|
||||
xml << " </necdsp>\n";
|
||||
}
|
||||
|
||||
+5
-16
@@ -42,7 +42,6 @@ else ifeq ($(platform),win)
|
||||
link += -mwindows -mthreads
|
||||
# link += -mconsole -mthreads
|
||||
link += -s -luuid -lkernel32 -luser32 -lgdi32 -lshell32
|
||||
# statically link Qt for Windows build
|
||||
link += -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
|
||||
|
||||
ruby := video.direct3d video.wgl video.directdraw video.gdi video.qtraster
|
||||
@@ -206,6 +205,11 @@ install:
|
||||
install -D -m 644 data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
|
||||
install -D -m 644 data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
|
||||
|
||||
uninstall:
|
||||
rm $(DESTDIR)$(prefix)/bin/bsnes
|
||||
rm $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
|
||||
rm $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
|
||||
|
||||
clean: ui_clean
|
||||
-@$(call delete,obj/*.o)
|
||||
-@$(call delete,*.res)
|
||||
@@ -214,18 +218,3 @@ clean: ui_clean
|
||||
-@$(call delete,*.ilk)
|
||||
-@$(call delete,*.pdb)
|
||||
-@$(call delete,*.manifest)
|
||||
|
||||
help:
|
||||
@echo "Usage: $(MAKE) platform=(os) compiler=(cc) [options]"
|
||||
@echo ""
|
||||
@echo "Supported platforms:"
|
||||
@echo " x - Linux / BSD (x86, x86-64)"
|
||||
@echo " win - Windows (x86, x86-64)"
|
||||
@echo ""
|
||||
@echo "Supported compilers:"
|
||||
@echo " gcc - GCC compiler"
|
||||
@echo " mingw32-gcc - MinGW compiler"
|
||||
@echo " i586-mingw32-gcc - MinGW cross compiler"
|
||||
@echo ""
|
||||
@echo "Example: $(MAKE) platform=x compiler=gcc"
|
||||
@echo ""
|
||||
+2
-11
@@ -1,6 +1,6 @@
|
||||
static const char bsnesVersion[] = "062";
|
||||
static const char bsnesVersion[] = "063";
|
||||
static const char bsnesTitle[] = "bsnes";
|
||||
static const unsigned bsnesSerializerVersion = 6;
|
||||
static const unsigned bsnesSerializerVersion = 8;
|
||||
|
||||
//S-DSP can be encapsulated into a state machine using #define magic
|
||||
//this avoids ~2.048m co_switch() calls per second (~5% speedup)
|
||||
@@ -35,13 +35,4 @@ static const unsigned bsnesSerializerVersion = 6;
|
||||
#include <nall/vector.hpp>
|
||||
using namespace nall;
|
||||
|
||||
typedef int8_t int8;
|
||||
typedef int16_t int16;
|
||||
typedef int32_t int32;
|
||||
typedef int64_t int64;
|
||||
typedef uint8_t uint8;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
#include "interface.hpp"
|
||||
@@ -19,6 +19,9 @@ namespace memory {
|
||||
Cartridge cartridge;
|
||||
|
||||
void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) {
|
||||
mode = Mode::Normal;
|
||||
region = Region::NTSC;
|
||||
ram_size = 0;
|
||||
spc7110_data_rom_offset = 0x100000;
|
||||
supergameboy_version = SuperGameBoyVersion::Version1;
|
||||
supergameboy_ram_size = 0;
|
||||
|
||||
+16
-16
@@ -79,22 +79,22 @@ private:
|
||||
void parse_xml_sufami_turbo(const char*, bool);
|
||||
void parse_xml_gameboy(const char*);
|
||||
|
||||
void xml_parse_rom(xml_element*);
|
||||
void xml_parse_ram(xml_element*);
|
||||
void xml_parse_superfx(xml_element*);
|
||||
void xml_parse_sa1(xml_element*);
|
||||
void xml_parse_bsx(xml_element*);
|
||||
void xml_parse_sufamiturbo(xml_element*);
|
||||
void xml_parse_supergameboy(xml_element*);
|
||||
void xml_parse_srtc(xml_element*);
|
||||
void xml_parse_sdd1(xml_element*);
|
||||
void xml_parse_spc7110(xml_element*);
|
||||
void xml_parse_cx4(xml_element*);
|
||||
void xml_parse_necdsp(xml_element*);
|
||||
void xml_parse_obc1(xml_element*);
|
||||
void xml_parse_setadsp(xml_element*);
|
||||
void xml_parse_setarisc(xml_element*);
|
||||
void xml_parse_msu1(xml_element*);
|
||||
void xml_parse_rom(xml_element&);
|
||||
void xml_parse_ram(xml_element&);
|
||||
void xml_parse_superfx(xml_element&);
|
||||
void xml_parse_sa1(xml_element&);
|
||||
void xml_parse_bsx(xml_element&);
|
||||
void xml_parse_sufamiturbo(xml_element&);
|
||||
void xml_parse_supergameboy(xml_element&);
|
||||
void xml_parse_srtc(xml_element&);
|
||||
void xml_parse_sdd1(xml_element&);
|
||||
void xml_parse_spc7110(xml_element&);
|
||||
void xml_parse_cx4(xml_element&);
|
||||
void xml_parse_necdsp(xml_element&);
|
||||
void xml_parse_obc1(xml_element&);
|
||||
void xml_parse_setadsp(xml_element&);
|
||||
void xml_parse_setarisc(xml_element&);
|
||||
void xml_parse_msu1(xml_element&);
|
||||
|
||||
void xml_parse_address(Mapping&, const string&);
|
||||
void xml_parse_mode(Mapping&, const string&);
|
||||
|
||||
+277
-279
@@ -17,35 +17,35 @@ void Cartridge::parse_xml(const lstring &list) {
|
||||
}
|
||||
|
||||
void Cartridge::parse_xml_cartridge(const char *data) {
|
||||
xml_element *document = xml_parse(data);
|
||||
if(document == 0) return;
|
||||
xml_element document = xml_parse(data);
|
||||
if(document.element.size() == 0) return;
|
||||
|
||||
foreach(head, document->element) {
|
||||
if(head->name == "cartridge") {
|
||||
foreach(attr, head->attribute) {
|
||||
if(attr->name == "region") {
|
||||
if(attr->content == "NTSC") region = Region::NTSC;
|
||||
if(attr->content == "PAL") region = Region::PAL;
|
||||
foreach(head, document.element) {
|
||||
if(head.name == "cartridge") {
|
||||
foreach(attr, head.attribute) {
|
||||
if(attr.name == "region") {
|
||||
if(attr.content == "NTSC") region = Region::NTSC;
|
||||
if(attr.content == "PAL") region = Region::PAL;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(node, head->element) {
|
||||
if(node->name == "rom") xml_parse_rom(node);
|
||||
if(node->name == "ram") xml_parse_ram(node);
|
||||
if(node->name == "superfx") xml_parse_superfx(node);
|
||||
if(node->name == "sa1") xml_parse_sa1(node);
|
||||
if(node->name == "bsx") xml_parse_bsx(node);
|
||||
if(node->name == "sufamiturbo") xml_parse_sufamiturbo(node);
|
||||
if(node->name == "supergameboy") xml_parse_supergameboy(node);
|
||||
if(node->name == "srtc") xml_parse_srtc(node);
|
||||
if(node->name == "sdd1") xml_parse_sdd1(node);
|
||||
if(node->name == "spc7110") xml_parse_spc7110(node);
|
||||
if(node->name == "cx4") xml_parse_cx4(node);
|
||||
if(node->name == "necdsp") xml_parse_necdsp(node);
|
||||
if(node->name == "obc1") xml_parse_obc1(node);
|
||||
if(node->name == "setadsp") xml_parse_setadsp(node);
|
||||
if(node->name == "setarisc") xml_parse_setarisc(node);
|
||||
if(node->name == "msu1") xml_parse_msu1(node);
|
||||
foreach(node, head.element) {
|
||||
if(node.name == "rom") xml_parse_rom(node);
|
||||
if(node.name == "ram") xml_parse_ram(node);
|
||||
if(node.name == "superfx") xml_parse_superfx(node);
|
||||
if(node.name == "sa1") xml_parse_sa1(node);
|
||||
if(node.name == "bsx") xml_parse_bsx(node);
|
||||
if(node.name == "sufamiturbo") xml_parse_sufamiturbo(node);
|
||||
if(node.name == "supergameboy") xml_parse_supergameboy(node);
|
||||
if(node.name == "srtc") xml_parse_srtc(node);
|
||||
if(node.name == "sdd1") xml_parse_sdd1(node);
|
||||
if(node.name == "spc7110") xml_parse_spc7110(node);
|
||||
if(node.name == "cx4") xml_parse_cx4(node);
|
||||
if(node.name == "necdsp") xml_parse_necdsp(node);
|
||||
if(node.name == "obc1") xml_parse_obc1(node);
|
||||
if(node.name == "setadsp") xml_parse_setadsp(node);
|
||||
if(node.name == "setarisc") xml_parse_setarisc(node);
|
||||
if(node.name == "msu1") xml_parse_msu1(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,106 +58,104 @@ void Cartridge::parse_xml_sufami_turbo(const char *data, bool slot) {
|
||||
}
|
||||
|
||||
void Cartridge::parse_xml_gameboy(const char *data) {
|
||||
xml_element *document = xml_parse(data);
|
||||
if(document == 0) return;
|
||||
xml_element document = xml_parse(data);
|
||||
if(document.element.size() == 0) return;
|
||||
|
||||
foreach(head, document->element) {
|
||||
if(head->name == "cartridge") {
|
||||
foreach(attr, head->attribute) {
|
||||
if(attr->name == "rtc") {
|
||||
supergameboy_rtc_size = (attr->content == "true") ? 4 : 0;
|
||||
foreach(head, document.element) {
|
||||
if(head.name == "cartridge") {
|
||||
foreach(attr, head.attribute) {
|
||||
if(attr.name == "rtc") {
|
||||
supergameboy_rtc_size = (attr.content == "true") ? 4 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(leaf, head->element) {
|
||||
if(leaf->name == "ram") {
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "size") {
|
||||
supergameboy_ram_size = strhex(attr->content);
|
||||
foreach(leaf, head.element) {
|
||||
if(leaf.name == "ram") {
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "size") {
|
||||
supergameboy_ram_size = strhex(attr.content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete document;
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_rom(xml_element *root) {
|
||||
foreach(leaf, root->element) {
|
||||
if(leaf->name == "map") {
|
||||
void Cartridge::xml_parse_rom(xml_element &root) {
|
||||
foreach(leaf, root.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(memory::cartrom);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
if(attr.name == "mode") xml_parse_mode(m, attr.content);
|
||||
if(attr.name == "offset") m.offset = strhex(attr.content);
|
||||
if(attr.name == "size") m.size = strhex(attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_ram(xml_element *root) {
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "size") ram_size = strhex(attr->content);
|
||||
void Cartridge::xml_parse_ram(xml_element &root) {
|
||||
foreach(attr, root.attribute) {
|
||||
if(attr.name == "size") ram_size = strhex(attr.content);
|
||||
}
|
||||
|
||||
foreach(leaf, root->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(leaf, root.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(memory::cartram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
if(attr.name == "mode") xml_parse_mode(m, attr.content);
|
||||
if(attr.name == "offset") m.offset = strhex(attr.content);
|
||||
if(attr.name == "size") m.size = strhex(attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_superfx(xml_element *root) {
|
||||
void Cartridge::xml_parse_superfx(xml_element &root) {
|
||||
has_superfx = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "rom") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "rom") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(memory::fxrom);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
if(attr.name == "mode") xml_parse_mode(m, attr.content);
|
||||
if(attr.name == "offset") m.offset = strhex(attr.content);
|
||||
if(attr.name == "size") m.size = strhex(attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "ram") {
|
||||
foreach(attr, node->attribute) {
|
||||
if(attr->name == "size") ram_size = strhex(attr->content);
|
||||
} else if(node.name == "ram") {
|
||||
foreach(attr, node.attribute) {
|
||||
if(attr.name == "size") ram_size = strhex(attr.content);
|
||||
}
|
||||
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(memory::fxram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
if(attr.name == "mode") xml_parse_mode(m, attr.content);
|
||||
if(attr.name == "offset") m.offset = strhex(attr.content);
|
||||
if(attr.name == "size") m.size = strhex(attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
} else if(node.name == "mmio") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(superfx);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
@@ -166,59 +164,59 @@ void Cartridge::xml_parse_superfx(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_sa1(xml_element *root) {
|
||||
void Cartridge::xml_parse_sa1(xml_element &root) {
|
||||
has_sa1 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "rom") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "rom") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(memory::vsprom);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
if(attr.name == "mode") xml_parse_mode(m, attr.content);
|
||||
if(attr.name == "offset") m.offset = strhex(attr.content);
|
||||
if(attr.name == "size") m.size = strhex(attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "iram") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
} else if(node.name == "iram") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(memory::cpuiram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
if(attr.name == "mode") xml_parse_mode(m, attr.content);
|
||||
if(attr.name == "offset") m.offset = strhex(attr.content);
|
||||
if(attr.name == "size") m.size = strhex(attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "bwram") {
|
||||
foreach(attr, node->attribute) {
|
||||
if(attr->name == "size") ram_size = strhex(attr->content);
|
||||
} else if(node.name == "bwram") {
|
||||
foreach(attr, node.attribute) {
|
||||
if(attr.name == "size") ram_size = strhex(attr.content);
|
||||
}
|
||||
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(memory::cc1bwram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
if(attr.name == "mode") xml_parse_mode(m, attr.content);
|
||||
if(attr.name == "offset") m.offset = strhex(attr.content);
|
||||
if(attr.name == "size") m.size = strhex(attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
} else if(node.name == "mmio") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(sa1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
@@ -227,27 +225,27 @@ void Cartridge::xml_parse_sa1(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_bsx(xml_element *root) {
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "slot") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
void Cartridge::xml_parse_bsx(xml_element &root) {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "slot") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(memory::bsxflash);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
if(attr.name == "mode") xml_parse_mode(m, attr.content);
|
||||
if(attr.name == "offset") m.offset = strhex(attr.content);
|
||||
if(attr.name == "size") m.size = strhex(attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
} else if(node.name == "mmio") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(bsxcart);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
@@ -256,40 +254,40 @@ void Cartridge::xml_parse_bsx(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_sufamiturbo(xml_element *root) {
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "slot") {
|
||||
void Cartridge::xml_parse_sufamiturbo(xml_element &root) {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "slot") {
|
||||
bool slotid = 0;
|
||||
foreach(attr, node->attribute) {
|
||||
if(attr->name == "id") {
|
||||
if(attr->content == "A") slotid = 0;
|
||||
if(attr->content == "B") slotid = 1;
|
||||
foreach(attr, node.attribute) {
|
||||
if(attr.name == "id") {
|
||||
if(attr.content == "A") slotid = 0;
|
||||
if(attr.content == "B") slotid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(slot, node->element) {
|
||||
if(slot->name == "rom") {
|
||||
foreach(leaf, slot->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(slot, node.element) {
|
||||
if(slot.name == "rom") {
|
||||
foreach(leaf, slot.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(slotid == 0 ? memory::stArom : memory::stBrom);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
if(attr.name == "mode") xml_parse_mode(m, attr.content);
|
||||
if(attr.name == "offset") m.offset = strhex(attr.content);
|
||||
if(attr.name == "size") m.size = strhex(attr.content);
|
||||
}
|
||||
if(m.memory->size() > 0) mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(slot->name == "ram") {
|
||||
foreach(leaf, slot->element) {
|
||||
if(leaf->name == "map") {
|
||||
} else if(slot.name == "ram") {
|
||||
foreach(leaf, slot.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(slotid == 0 ? memory::stAram : memory::stBram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
if(attr.name == "mode") xml_parse_mode(m, attr.content);
|
||||
if(attr.name == "offset") m.offset = strhex(attr.content);
|
||||
if(attr.name == "size") m.size = strhex(attr.content);
|
||||
}
|
||||
if(m.memory->size() > 0) mapping.add(m);
|
||||
}
|
||||
@@ -300,21 +298,21 @@ void Cartridge::xml_parse_sufamiturbo(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_supergameboy(xml_element *root) {
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "revision") {
|
||||
if(attr->content == "1") supergameboy_version = SuperGameBoyVersion::Version1;
|
||||
if(attr->content == "2") supergameboy_version = SuperGameBoyVersion::Version2;
|
||||
void Cartridge::xml_parse_supergameboy(xml_element &root) {
|
||||
foreach(attr, root.attribute) {
|
||||
if(attr.name == "revision") {
|
||||
if(attr.content == "1") supergameboy_version = SuperGameBoyVersion::Version1;
|
||||
if(attr.content == "2") supergameboy_version = SuperGameBoyVersion::Version2;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "mmio") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m((Memory&)supergameboy);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
@@ -323,16 +321,16 @@ void Cartridge::xml_parse_supergameboy(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_srtc(xml_element *root) {
|
||||
void Cartridge::xml_parse_srtc(xml_element &root) {
|
||||
has_srtc = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "mmio") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(srtc);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
@@ -341,26 +339,26 @@ void Cartridge::xml_parse_srtc(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_sdd1(xml_element *root) {
|
||||
void Cartridge::xml_parse_sdd1(xml_element &root) {
|
||||
has_sdd1 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mcu") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "mcu") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m((Memory&)sdd1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
} else if(node.name == "mmio") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m((MMIO&)sdd1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
@@ -369,66 +367,66 @@ void Cartridge::xml_parse_sdd1(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_spc7110(xml_element *root) {
|
||||
void Cartridge::xml_parse_spc7110(xml_element &root) {
|
||||
has_spc7110 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "dcu") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "dcu") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(spc7110dcu);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mcu") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
} else if(node.name == "mcu") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(spc7110mcu);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "offset") spc7110_data_rom_offset = strhex(attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
if(attr.name == "offset") spc7110_data_rom_offset = strhex(attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
} else if(node.name == "mmio") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(spc7110);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "ram") {
|
||||
foreach(attr, node->attribute) {
|
||||
if(attr->name == "size") ram_size = strhex(attr->content);
|
||||
} else if(node.name == "ram") {
|
||||
foreach(attr, node.attribute) {
|
||||
if(attr.name == "size") ram_size = strhex(attr.content);
|
||||
}
|
||||
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(spc7110ram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
if(attr.name == "mode") xml_parse_mode(m, attr.content);
|
||||
if(attr.name == "offset") m.offset = strhex(attr.content);
|
||||
if(attr.name == "size") m.size = strhex(attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "rtc") {
|
||||
} else if(node.name == "rtc") {
|
||||
has_spc7110rtc = true;
|
||||
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(spc7110);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
@@ -437,16 +435,16 @@ void Cartridge::xml_parse_spc7110(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_cx4(xml_element *root) {
|
||||
void Cartridge::xml_parse_cx4(xml_element &root) {
|
||||
has_cx4 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "mmio") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(cx4);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
@@ -455,47 +453,47 @@ void Cartridge::xml_parse_cx4(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_necdsp(xml_element *root) {
|
||||
void Cartridge::xml_parse_necdsp(xml_element &root) {
|
||||
unsigned program = 0;
|
||||
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "program") {
|
||||
if(attr->content == "DSP-1" || attr->content == "DSP-1A" || attr->content == "DSP-1B") {
|
||||
foreach(attr, root.attribute) {
|
||||
if(attr.name == "program") {
|
||||
if(attr.content == "DSP-1" || attr.content == "DSP-1A" || attr.content == "DSP-1B") {
|
||||
program = 1;
|
||||
has_dsp1 = true;
|
||||
} else if(attr->content == "DSP-2") {
|
||||
} else if(attr.content == "DSP-2") {
|
||||
program = 2;
|
||||
has_dsp2 = true;
|
||||
} else if(attr->content == "DSP-3") {
|
||||
} else if(attr.content == "DSP-3") {
|
||||
program = 3;
|
||||
has_dsp3 = true;
|
||||
} else if(attr->content == "DSP-4") {
|
||||
} else if(attr.content == "DSP-4") {
|
||||
program = 4;
|
||||
has_dsp4 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Memory *dr[5] = { 0, &dsp1dr, &dsp2, &dsp3, &dsp4 };
|
||||
Memory *sr[5] = { 0, &dsp1sr, &dsp2, &dsp3, &dsp4 };
|
||||
Memory *dr[5] = { 0, &dsp1dr, &dsp2dr, &dsp3, &dsp4 };
|
||||
Memory *sr[5] = { 0, &dsp1sr, &dsp2sr, &dsp3, &dsp4 };
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "dr" && dr[program]) {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "dr" && dr[program]) {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(*dr[program]);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "sr" && sr[program]) {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
} else if(node.name == "sr" && sr[program]) {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(*sr[program]);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
@@ -504,16 +502,16 @@ void Cartridge::xml_parse_necdsp(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_obc1(xml_element *root) {
|
||||
void Cartridge::xml_parse_obc1(xml_element &root) {
|
||||
has_obc1 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "mmio") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(obc1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
@@ -522,15 +520,15 @@ void Cartridge::xml_parse_obc1(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_setadsp(xml_element *root) {
|
||||
void Cartridge::xml_parse_setadsp(xml_element &root) {
|
||||
unsigned program = 0;
|
||||
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "program") {
|
||||
if(attr->content == "ST-0010") {
|
||||
foreach(attr, root.attribute) {
|
||||
if(attr.name == "program") {
|
||||
if(attr.content == "ST-0010") {
|
||||
program = 1;
|
||||
has_st0010 = true;
|
||||
} else if(attr->content == "ST-0011") {
|
||||
} else if(attr.content == "ST-0011") {
|
||||
program = 2;
|
||||
has_st0011 = true;
|
||||
}
|
||||
@@ -539,13 +537,13 @@ void Cartridge::xml_parse_setadsp(xml_element *root) {
|
||||
|
||||
Memory *map[3] = { 0, &st0010, 0 };
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio" && map[program]) {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "mmio" && map[program]) {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(*map[program]);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
@@ -554,12 +552,12 @@ void Cartridge::xml_parse_setadsp(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_setarisc(xml_element *root) {
|
||||
void Cartridge::xml_parse_setarisc(xml_element &root) {
|
||||
unsigned program = 0;
|
||||
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "program") {
|
||||
if(attr->content == "ST-0018") {
|
||||
foreach(attr, root.attribute) {
|
||||
if(attr.name == "program") {
|
||||
if(attr.content == "ST-0018") {
|
||||
program = 1;
|
||||
has_st0018 = true;
|
||||
}
|
||||
@@ -568,13 +566,13 @@ void Cartridge::xml_parse_setarisc(xml_element *root) {
|
||||
|
||||
MMIO *map[2] = { 0, &st0018 };
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio" && map[program]) {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "mmio" && map[program]) {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(*map[program]);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
@@ -583,16 +581,16 @@ void Cartridge::xml_parse_setarisc(xml_element *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_msu1(xml_element *root) {
|
||||
void Cartridge::xml_parse_msu1(xml_element &root) {
|
||||
has_msu1 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
foreach(node, root.element) {
|
||||
if(node.name == "mmio") {
|
||||
foreach(leaf, node.element) {
|
||||
if(leaf.name == "map") {
|
||||
Mapping m(msu1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
foreach(attr, leaf.attribute) {
|
||||
if(attr.name == "address") xml_parse_address(m, attr.content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
|
||||
+2
-2
@@ -125,7 +125,7 @@ bool Cheat::encode(string &s, unsigned addr, uint8 data, Type type) {
|
||||
char t[16];
|
||||
|
||||
if(type == Type::ProActionReplay) {
|
||||
s = sprint("$$", strhex<6>(addr), strhex<2>(data));
|
||||
s = sprint(strhex<6>(addr), strhex<2>(data));
|
||||
return true;
|
||||
} else if(type == Type::GameGenie) {
|
||||
unsigned r = addr;
|
||||
@@ -141,7 +141,7 @@ bool Cheat::encode(string &s, unsigned addr, uint8 data, Type type) {
|
||||
| (!!(r & 0x080000) << 5) | (!!(r & 0x040000) << 4)
|
||||
| (!!(r & 0x020000) << 3) | (!!(r & 0x010000) << 2)
|
||||
| (!!(r & 0x000800) << 1) | (!!(r & 0x000400) << 0);
|
||||
s = sprint("$$-$", strhex<2>(data), strhex<2>(addr >> 16), strhex<4>(addr & 0xffff));
|
||||
s = sprint(strhex<2>(data), strhex<2>(addr >> 16), "-", strhex<4>(addr & 0xffff));
|
||||
strtr(s, "0123456789abcdef", "df4709156bc8a23e");
|
||||
return true;
|
||||
} else {
|
||||
|
||||
@@ -30,4 +30,4 @@ void DSP1DR::write(unsigned addr, uint8 data) { dsp1.dsp1.setDr(data); }
|
||||
uint8 DSP1SR::read(unsigned addr) { return dsp1.dsp1.getSr(); }
|
||||
void DSP1SR::write(unsigned addr, uint8 data) {}
|
||||
|
||||
};
|
||||
}
|
||||
@@ -4,6 +4,8 @@
|
||||
namespace SNES {
|
||||
|
||||
DSP2 dsp2;
|
||||
DSP2DR dsp2dr;
|
||||
DSP2SR dsp2sr;
|
||||
|
||||
#include "serialization.cpp"
|
||||
#include "opcodes.cpp"
|
||||
@@ -141,5 +143,11 @@ void DSP2::write(unsigned addr, uint8 data) {
|
||||
|
||||
DSP2::DSP2() {}
|
||||
DSP2::~DSP2() {}
|
||||
};
|
||||
|
||||
uint8 DSP2DR::read(unsigned addr) { return dsp2.read(addr); }
|
||||
void DSP2DR::write(unsigned addr, uint8 data) { dsp2.write(addr, data); }
|
||||
|
||||
uint8 DSP2SR::read(unsigned addr) { return 0x00; }
|
||||
void DSP2SR::write(unsigned addr, uint8 data) {}
|
||||
|
||||
}
|
||||
+13
-1
@@ -1,4 +1,4 @@
|
||||
class DSP2 : public Memory {
|
||||
class DSP2 {
|
||||
public:
|
||||
struct {
|
||||
bool waiting_for_command;
|
||||
@@ -42,4 +42,16 @@ protected:
|
||||
void op0d();
|
||||
};
|
||||
|
||||
class DSP2DR : public Memory {
|
||||
uint8 read(unsigned addr);
|
||||
void write(unsigned addr, uint8 data);
|
||||
};
|
||||
|
||||
class DSP2SR : public Memory {
|
||||
uint8 read(unsigned addr);
|
||||
void write(unsigned addr, uint8 data);
|
||||
};
|
||||
|
||||
extern DSP2 dsp2;
|
||||
extern DSP2DR dsp2dr;
|
||||
extern DSP2SR dsp2sr;
|
||||
@@ -174,8 +174,6 @@ public:
|
||||
template<int, int> void op_transfer_w();
|
||||
void op_tcs_e();
|
||||
void op_tcs_n();
|
||||
void op_tsc_e();
|
||||
void op_tsc_n();
|
||||
void op_tsx_b();
|
||||
void op_tsx_w();
|
||||
void op_txs_e();
|
||||
|
||||
@@ -153,20 +153,6 @@ L op_io_irq();
|
||||
regs.s.w = regs.a.w;
|
||||
}
|
||||
|
||||
void CPUcore::op_tsc_e() {
|
||||
L op_io_irq();
|
||||
regs.a.w = regs.s.w;
|
||||
regs.p.n = (regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void CPUcore::op_tsc_n() {
|
||||
L op_io_irq();
|
||||
regs.a.w = regs.s.w;
|
||||
regs.p.n = (regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
void CPUcore::op_tsx_b() {
|
||||
L op_io_irq();
|
||||
regs.x.l = regs.s.l;
|
||||
|
||||
@@ -76,7 +76,7 @@ void CPUcore::initialize_opcode_table() {
|
||||
opAII(0x38, flag, 0x01, 0x01)
|
||||
opMF (0x39, read_addry, and)
|
||||
opMII(0x3a, adjust_imm, A, -1)
|
||||
opE (0x3b, tsc)
|
||||
opAII(0x3b, transfer_w, S, A)
|
||||
opMF (0x3c, read_addrx, bit)
|
||||
opMF (0x3d, read_addrx, and)
|
||||
opMF (0x3e, adjust_addrx, rol)
|
||||
|
||||
+18
-18
@@ -4,11 +4,11 @@ bool CPUDebugger::property(unsigned id, string &name, string &value) {
|
||||
unsigned n = 0;
|
||||
|
||||
//internal
|
||||
if(id == n++) { name = "S-CPU MDR"; value = sprint("0x$", strhex<2>(mdr())); return true; }
|
||||
if(id == n++) { name = "S-CPU MDR"; value = sprint("0x", strhex<2>(mdr())); return true; }
|
||||
|
||||
//$2181-2183
|
||||
if(id == n++) { name = "$2181-$2183"; value = ""; return true; }
|
||||
if(id == n++) { name = "WRAM Address"; value = sprint("0x$", strhex<6>(wram_address())); return true; }
|
||||
if(id == n++) { name = "WRAM Address"; value = sprint("0x", strhex<6>(wram_address())); return true; }
|
||||
|
||||
//$4016
|
||||
if(id == n++) { name = "$4016"; value = ""; return true; }
|
||||
@@ -23,39 +23,39 @@ bool CPUDebugger::property(unsigned id, string &name, string &value) {
|
||||
|
||||
//$4201
|
||||
if(id == n++) { name = "$4201"; value = ""; return true; }
|
||||
if(id == n++) { name = "PIO"; value = sprint("0x$", strhex<2>(pio_bits())); return true; }
|
||||
if(id == n++) { name = "PIO"; value = sprint("0x", strhex<2>(pio_bits())); return true; }
|
||||
|
||||
//$4202
|
||||
if(id == n++) { name = "$4202"; value = ""; return true; }
|
||||
if(id == n++) { name = "Multiplicand"; value = sprint("0x$", strhex<2>(multiplicand())); return true; }
|
||||
if(id == n++) { name = "Multiplicand"; value = sprint("0x", strhex<2>(multiplicand())); return true; }
|
||||
|
||||
//$4203
|
||||
if(id == n++) { name = "$4203"; value = ""; return true; }
|
||||
if(id == n++) { name = "Multiplier"; value = sprint("0x$", strhex<2>(multiplier())); return true; }
|
||||
if(id == n++) { name = "Multiplier"; value = sprint("0x", strhex<2>(multiplier())); return true; }
|
||||
|
||||
//$4204-$4205
|
||||
if(id == n++) { name = "$4204-$4205"; value = ""; return true; }
|
||||
if(id == n++) { name = "Dividend"; value = sprint("0x$", strhex<4>(dividend())); return true; }
|
||||
if(id == n++) { name = "Dividend"; value = sprint("0x", strhex<4>(dividend())); return true; }
|
||||
|
||||
//$4206
|
||||
if(id == n++) { name = "$4206"; value = ""; return true; }
|
||||
if(id == n++) { name = "Divisor"; value = sprint("0x$", strhex<2>(divisor())); return true; }
|
||||
if(id == n++) { name = "Divisor"; value = sprint("0x", strhex<2>(divisor())); return true; }
|
||||
|
||||
//$4207-$4208
|
||||
if(id == n++) { name = "$4207-$4208"; value = ""; return true; }
|
||||
if(id == n++) { name = "H-Time"; value = sprint("0x$", strhex<4>(htime())); return true; }
|
||||
if(id == n++) { name = "H-Time"; value = sprint("0x", strhex<4>(htime())); return true; }
|
||||
|
||||
//$4209-$420a
|
||||
if(id == n++) { name = "$4209-$420a"; value = ""; return true; }
|
||||
if(id == n++) { name = "V-Time"; value = sprint("0x$", strhex<4>(vtime())); return true; }
|
||||
if(id == n++) { name = "V-Time"; value = sprint("0x", strhex<4>(vtime())); return true; }
|
||||
|
||||
//$420b
|
||||
if(id == n++) { name = "$420b"; value = ""; return true; }
|
||||
if(id == n++) { name = "DMA Enable"; value = sprint("0x$", strhex<2>(dma_enable())); return true; }
|
||||
if(id == n++) { name = "DMA Enable"; value = sprint("0x", strhex<2>(dma_enable())); return true; }
|
||||
|
||||
//$420c
|
||||
if(id == n++) { name = "$420c"; value = ""; return true; }
|
||||
if(id == n++) { name = "HDMA Enable"; value = sprint("0x$", strhex<2>(hdma_enable())); return true; }
|
||||
if(id == n++) { name = "HDMA Enable"; value = sprint("0x", strhex<2>(hdma_enable())); return true; }
|
||||
|
||||
//$420d
|
||||
if(id == n++) { name = "$420d"; value = ""; return true; }
|
||||
@@ -72,25 +72,25 @@ bool CPUDebugger::property(unsigned id, string &name, string &value) {
|
||||
if(id == n++) { name = "Transfer Mode"; value = dma_transfer_mode(i); return true; }
|
||||
|
||||
//$43x1
|
||||
if(id == n++) { name = "B-Bus Address"; value = sprint("0x$", strhex<4>(dma_bbus_address(i))); return true; }
|
||||
if(id == n++) { name = "B-Bus Address"; value = sprint("0x", strhex<4>(dma_bbus_address(i))); return true; }
|
||||
|
||||
//$43x2-$43x3
|
||||
if(id == n++) { name = "A-Bus Address"; value = sprint("0x$", strhex<4>(dma_abus_address(i))); return true; }
|
||||
if(id == n++) { name = "A-Bus Address"; value = sprint("0x", strhex<4>(dma_abus_address(i))); return true; }
|
||||
|
||||
//$43x4
|
||||
if(id == n++) { name = "A-Bus Bank"; value = sprint("0x$", strhex<2>(dma_abus_bank(i))); return true; }
|
||||
if(id == n++) { name = "A-Bus Bank"; value = sprint("0x", strhex<2>(dma_abus_bank(i))); return true; }
|
||||
|
||||
//$43x5-$43x6
|
||||
if(id == n++) { name = "Transfer Size / Indirect Address"; value = sprint("0x$", strhex<4>(dma_transfer_size(i))); return true; }
|
||||
if(id == n++) { name = "Transfer Size / Indirect Address"; value = sprint("0x", strhex<4>(dma_transfer_size(i))); return true; }
|
||||
|
||||
//$43x7
|
||||
if(id == n++) { name = "Indirect Bank"; value = sprint("0x$", strhex<2>(dma_indirect_bank(i))); return true; }
|
||||
if(id == n++) { name = "Indirect Bank"; value = sprint("0x", strhex<2>(dma_indirect_bank(i))); return true; }
|
||||
|
||||
//$43x8-$43x9
|
||||
if(id == n++) { name = "Table Address"; value = sprint("0x$", strhex<4>(dma_table_address(i))); return true; }
|
||||
if(id == n++) { name = "Table Address"; value = sprint("0x", strhex<4>(dma_table_address(i))); return true; }
|
||||
|
||||
//$43xa
|
||||
if(id == n++) { name = "Line Counter"; value = sprint("0x$", strhex<2>(dma_line_counter(i))); return true; }
|
||||
if(id == n++) { name = "Line Counter"; value = sprint("0x", strhex<2>(dma_line_counter(i))); return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -17,8 +17,8 @@ bool sCPU::dma_addr_valid(uint32 abus) {
|
||||
}
|
||||
|
||||
uint8 sCPU::dma_read(uint32 abus) {
|
||||
if(dma_addr_valid(abus) == false) return 0x00; //does not return S-CPU MDR
|
||||
return bus.read(abus);
|
||||
if(dma_addr_valid(abus) == false) return regs.mdr = 0x00;
|
||||
return regs.mdr = bus.read(abus);
|
||||
}
|
||||
|
||||
void sCPU::dma_transfer(bool direction, uint8 bbus, uint32 abus) {
|
||||
@@ -106,17 +106,17 @@ uint8 sCPU::dma_enabled_channels() {
|
||||
|
||||
void sCPU::dma_run() {
|
||||
dma_add_clocks(8);
|
||||
cycle_edge();
|
||||
dma_edge();
|
||||
|
||||
for(unsigned i = 0; i < 8; i++) {
|
||||
if(channel[i].dma_enabled == false) continue;
|
||||
dma_add_clocks(8);
|
||||
cycle_edge();
|
||||
dma_edge();
|
||||
|
||||
unsigned index = 0;
|
||||
do {
|
||||
dma_transfer(channel[i].direction, dma_bbus(i, index++), dma_addr(i));
|
||||
cycle_edge();
|
||||
dma_edge();
|
||||
} while(channel[i].dma_enabled && --channel[i].xfersize);
|
||||
|
||||
channel[i].dma_enabled = false;
|
||||
|
||||
@@ -2,22 +2,25 @@
|
||||
|
||||
void sCPU::op_io() {
|
||||
status.clock_count = 6;
|
||||
cycle_edge();
|
||||
dma_edge();
|
||||
add_clocks(6);
|
||||
alu_edge();
|
||||
}
|
||||
|
||||
uint8 sCPU::op_read(uint32 addr) {
|
||||
status.clock_count = speed(addr);
|
||||
cycle_edge();
|
||||
dma_edge();
|
||||
add_clocks(status.clock_count - 4);
|
||||
regs.mdr = bus.read(addr);
|
||||
add_clocks(4);
|
||||
alu_edge();
|
||||
return regs.mdr;
|
||||
}
|
||||
|
||||
void sCPU::op_write(uint32 addr, uint8 data) {
|
||||
alu_edge();
|
||||
status.clock_count = speed(addr);
|
||||
cycle_edge();
|
||||
dma_edge();
|
||||
add_clocks(status.clock_count);
|
||||
bus.write(addr, regs.mdr = data);
|
||||
}
|
||||
|
||||
+41
-36
@@ -39,9 +39,11 @@ void sCPU::mmio_w2183(uint8 data) {
|
||||
//strobing $4016.d0 affects both controller port latches.
|
||||
//$4017 bit 0 writes are ignored.
|
||||
void sCPU::mmio_w4016(uint8 data) {
|
||||
status.joypad_strobe_latch = !!(data & 1);
|
||||
bool old_latch = status.joypad_strobe_latch;
|
||||
bool new_latch = data & 1;
|
||||
status.joypad_strobe_latch = new_latch;
|
||||
|
||||
if(status.joypad_strobe_latch == 1) {
|
||||
if(old_latch != new_latch) {
|
||||
input.poll();
|
||||
}
|
||||
}
|
||||
@@ -49,9 +51,6 @@ void sCPU::mmio_w4016(uint8 data) {
|
||||
//JOYSER0
|
||||
//7-2 = MDR
|
||||
//1-0 = Joypad serial data
|
||||
//
|
||||
//TODO: test whether strobe latch of zero returns
|
||||
//realtime or buffered status of joypadN.b
|
||||
uint8 sCPU::mmio_r4016() {
|
||||
uint8 r = regs.mdr & 0xfc;
|
||||
r |= input.port_read(0) & 3;
|
||||
@@ -89,12 +88,14 @@ void sCPU::mmio_w4202(uint8 data) {
|
||||
|
||||
//WRMPYB
|
||||
void sCPU::mmio_w4203(uint8 data) {
|
||||
status.wrmpyb = data;
|
||||
status.r4216 = 0;
|
||||
status.rdmpy = 0;
|
||||
if(alu.mpyctr || alu.divctr) return;
|
||||
|
||||
//perform multiplication over the next 8 cycles (+1 to skip this cycle)
|
||||
status.wrmpyctr = 9;
|
||||
status.wrdivctr = 0;
|
||||
status.wrmpyb = data;
|
||||
status.rddiv = (status.wrmpyb << 8) | status.wrmpya;
|
||||
|
||||
alu.mpyctr = 8; //perform multiplication over the next eight cycles
|
||||
alu.shift = status.wrmpyb;
|
||||
}
|
||||
|
||||
//WRDIVL
|
||||
@@ -109,12 +110,13 @@ void sCPU::mmio_w4205(uint8 data) {
|
||||
|
||||
//WRDIVB
|
||||
void sCPU::mmio_w4206(uint8 data) {
|
||||
status.wrdivb = data;
|
||||
status.r4216 = status.wrdiva;
|
||||
status.rdmpy = status.wrdiva;
|
||||
if(alu.mpyctr || alu.divctr) return;
|
||||
|
||||
//perform division over the next 16 cycles (+1 to skip this cycle)
|
||||
status.wrdivctr = 17;
|
||||
status.wrmpyctr = 0;
|
||||
status.wrdivb = data;
|
||||
|
||||
alu.divctr = 16; //perform division over the next sixteen cycles
|
||||
alu.shift = status.wrdivb << 16;
|
||||
}
|
||||
|
||||
//HTIMEL
|
||||
@@ -209,22 +211,22 @@ uint8 sCPU::mmio_r4213() {
|
||||
|
||||
//RDDIVL
|
||||
uint8 sCPU::mmio_r4214() {
|
||||
return status.r4214;
|
||||
return status.rddiv;
|
||||
}
|
||||
|
||||
//RDDIVH
|
||||
uint8 sCPU::mmio_r4215() {
|
||||
return status.r4214 >> 8;
|
||||
return status.rddiv >> 8;
|
||||
}
|
||||
|
||||
//RDMPYL
|
||||
uint8 sCPU::mmio_r4216() {
|
||||
return status.r4216;
|
||||
return status.rdmpy;
|
||||
}
|
||||
|
||||
//RDMPYH
|
||||
uint8 sCPU::mmio_r4217() {
|
||||
return status.r4216 >> 8;
|
||||
return status.rdmpy >> 8;
|
||||
}
|
||||
|
||||
//TODO: handle reads during joypad polling (v=225-227)
|
||||
@@ -390,12 +392,10 @@ void sCPU::mmio_reset() {
|
||||
//$4202-$4203
|
||||
status.wrmpya = 0xff;
|
||||
status.wrmpyb = 0xff;
|
||||
status.wrmpyctr = 0;
|
||||
|
||||
//$4204-$4206
|
||||
status.wrdiva = 0xffff;
|
||||
status.wrdivb = 0xff;
|
||||
status.wrdivctr = 0;
|
||||
|
||||
//$4207-$420a
|
||||
status.hirq_pos = 0x01ff;
|
||||
@@ -405,8 +405,8 @@ void sCPU::mmio_reset() {
|
||||
status.rom_speed = 8;
|
||||
|
||||
//$4214-$4217
|
||||
status.r4214 = 0x0000;
|
||||
status.r4216 = 0x0000;
|
||||
status.rddiv = 0x0000;
|
||||
status.rdmpy = 0x0000;
|
||||
|
||||
//$4218-$421f
|
||||
status.joy1l = 0x00;
|
||||
@@ -417,19 +417,24 @@ void sCPU::mmio_reset() {
|
||||
status.joy3h = 0x00;
|
||||
status.joy4l = 0x00;
|
||||
status.joy4h = 0x00;
|
||||
|
||||
//ALU
|
||||
alu.mpyctr = 0;
|
||||
alu.divctr = 0;
|
||||
alu.shift = 0;
|
||||
}
|
||||
|
||||
uint8 sCPU::mmio_read(unsigned addr) {
|
||||
addr &= 0xffff;
|
||||
|
||||
//APU
|
||||
if((addr & 0xffc0) == 0x2140) { //$2140-$217f
|
||||
if((addr & 0xffc0) == 0x2140) { //$2140-$217f
|
||||
scheduler.sync_cpusmp();
|
||||
return smp.port_read(addr & 3);
|
||||
}
|
||||
|
||||
//DMA
|
||||
if((addr & 0xff80) == 0x4300) { //$4300-$437f
|
||||
if((addr & 0xff80) == 0x4300) { //$4300-$437f
|
||||
unsigned i = (addr >> 4) & 7;
|
||||
switch(addr & 0xf) {
|
||||
case 0x0: return mmio_r43x0(i);
|
||||
@@ -444,10 +449,10 @@ uint8 sCPU::mmio_read(unsigned addr) {
|
||||
case 0x9: return mmio_r43x9(i);
|
||||
case 0xa: return mmio_r43xa(i);
|
||||
case 0xb: return mmio_r43xb(i);
|
||||
case 0xc: return regs.mdr; //unmapped
|
||||
case 0xd: return regs.mdr; //unmapped
|
||||
case 0xe: return regs.mdr; //unmapped
|
||||
case 0xf: return mmio_r43xb(i); //mirror of $43xb
|
||||
case 0xc: return regs.mdr; //unmapped
|
||||
case 0xd: return regs.mdr; //unmapped
|
||||
case 0xe: return regs.mdr; //unmapped
|
||||
case 0xf: return mmio_r43xb(i); //mirror of $43xb
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,14 +485,14 @@ void sCPU::mmio_write(unsigned addr, uint8 data) {
|
||||
addr &= 0xffff;
|
||||
|
||||
//APU
|
||||
if((addr & 0xffc0) == 0x2140) { //$2140-$217f
|
||||
if((addr & 0xffc0) == 0x2140) { //$2140-$217f
|
||||
scheduler.sync_cpusmp();
|
||||
port_write(addr & 3, data);
|
||||
return;
|
||||
}
|
||||
|
||||
//DMA
|
||||
if((addr & 0xff80) == 0x4300) { //$4300-$437f
|
||||
if((addr & 0xff80) == 0x4300) { //$4300-$437f
|
||||
unsigned i = (addr >> 4) & 7;
|
||||
switch(addr & 0xf) {
|
||||
case 0x0: mmio_w43x0(i, data); return;
|
||||
@@ -502,10 +507,10 @@ void sCPU::mmio_write(unsigned addr, uint8 data) {
|
||||
case 0x9: mmio_w43x9(i, data); return;
|
||||
case 0xa: mmio_w43xa(i, data); return;
|
||||
case 0xb: mmio_w43xb(i, data); return;
|
||||
case 0xc: return; //unmapped
|
||||
case 0xd: return; //unmapped
|
||||
case 0xe: return; //unmapped
|
||||
case 0xf: mmio_w43xb(i, data); return; //mirror of $43xb
|
||||
case 0xc: return; //unmapped
|
||||
case 0xd: return; //unmapped
|
||||
case 0xe: return; //unmapped
|
||||
case 0xf: mmio_w43xb(i, data); return; //mirror of $43xb
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,7 +520,7 @@ void sCPU::mmio_write(unsigned addr, uint8 data) {
|
||||
case 0x2182: mmio_w2182(data); return;
|
||||
case 0x2183: mmio_w2183(data); return;
|
||||
case 0x4016: mmio_w4016(data); return;
|
||||
case 0x4017: return; //unmapped
|
||||
case 0x4017: return; //unmapped
|
||||
case 0x4200: mmio_w4200(data); return;
|
||||
case 0x4201: mmio_w4201(data); return;
|
||||
case 0x4202: mmio_w4202(data); return;
|
||||
|
||||
+16
-4
@@ -19,7 +19,10 @@ public:
|
||||
unsigned clock_count;
|
||||
unsigned line_clocks;
|
||||
|
||||
//======
|
||||
//timing
|
||||
//======
|
||||
|
||||
bool irq_lock;
|
||||
unsigned dram_refresh_position;
|
||||
|
||||
@@ -37,7 +40,10 @@ public:
|
||||
|
||||
bool reset_pending;
|
||||
|
||||
//===
|
||||
//DMA
|
||||
//===
|
||||
|
||||
bool dma_active;
|
||||
unsigned dma_counter;
|
||||
unsigned dma_clocks;
|
||||
@@ -45,7 +51,9 @@ public:
|
||||
bool hdma_pending;
|
||||
bool hdma_mode; //0 = init, 1 = run
|
||||
|
||||
//====
|
||||
//MMIO
|
||||
//====
|
||||
|
||||
//$2181-$2183
|
||||
uint32 wram_addr;
|
||||
@@ -66,12 +74,10 @@ public:
|
||||
//$4202-$4203
|
||||
uint8 wrmpya;
|
||||
uint8 wrmpyb;
|
||||
unsigned wrmpyctr;
|
||||
|
||||
//$4204-$4206
|
||||
uint16 wrdiva;
|
||||
uint8 wrdivb;
|
||||
unsigned wrdivctr;
|
||||
|
||||
//$4207-$420a
|
||||
uint16 hirq_pos, virq_pos;
|
||||
@@ -80,8 +86,8 @@ public:
|
||||
unsigned rom_speed;
|
||||
|
||||
//$4214-$4217
|
||||
uint16 r4214;
|
||||
uint16 r4216;
|
||||
uint16 rddiv;
|
||||
uint16 rdmpy;
|
||||
|
||||
//$4218-$421f
|
||||
uint8 joy1l, joy1h;
|
||||
@@ -90,6 +96,12 @@ public:
|
||||
uint8 joy4l, joy4h;
|
||||
} status;
|
||||
|
||||
struct ALU {
|
||||
unsigned mpyctr;
|
||||
unsigned divctr;
|
||||
unsigned shift;
|
||||
} alu;
|
||||
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
|
||||
@@ -51,19 +51,17 @@ void sCPU::serialize(serializer &s) {
|
||||
|
||||
s.integer(status.wrmpya);
|
||||
s.integer(status.wrmpyb);
|
||||
s.integer(status.wrmpyctr);
|
||||
|
||||
s.integer(status.wrdiva);
|
||||
s.integer(status.wrdivb);
|
||||
s.integer(status.wrdivctr);
|
||||
|
||||
s.integer(status.hirq_pos);
|
||||
s.integer(status.virq_pos);
|
||||
|
||||
s.integer(status.rom_speed);
|
||||
|
||||
s.integer(status.r4214);
|
||||
s.integer(status.r4216);
|
||||
s.integer(status.rddiv);
|
||||
s.integer(status.rdmpy);
|
||||
|
||||
s.integer(status.joy1l);
|
||||
s.integer(status.joy1h);
|
||||
@@ -74,6 +72,10 @@ void sCPU::serialize(serializer &s) {
|
||||
s.integer(status.joy4l);
|
||||
s.integer(status.joy4h);
|
||||
|
||||
s.integer(alu.mpyctr);
|
||||
s.integer(alu.divctr);
|
||||
s.integer(alu.shift);
|
||||
|
||||
for(unsigned i = 0; i < 8; i++) {
|
||||
s.integer(channel[i].dma_enabled);
|
||||
s.integer(channel[i].hdma_enabled);
|
||||
|
||||
@@ -52,37 +52,26 @@ void sCPU::scanline() {
|
||||
}
|
||||
}
|
||||
|
||||
//used to test for ALU and H/DMA, which can trigger on the edge of every opcode cycle
|
||||
void sCPU::cycle_edge() {
|
||||
//===
|
||||
//ALU
|
||||
//===
|
||||
|
||||
if(status.wrmpyctr) {
|
||||
//MUL performs eight iterations; but because cycle_edge() is called after $4203 write,
|
||||
//a ninth iteration is added and ignored. counter is inverted to indicate shift position
|
||||
if(--status.wrmpyctr < 8) {
|
||||
unsigned shift = 7 - status.wrmpyctr;
|
||||
if((status.wrmpya >> shift) & 1) status.r4216 += status.wrmpyb << shift;
|
||||
}
|
||||
void sCPU::alu_edge() {
|
||||
if(alu.mpyctr) {
|
||||
alu.mpyctr--;
|
||||
if(status.rddiv & 1) status.rdmpy += alu.shift;
|
||||
status.rddiv >>= 1;
|
||||
alu.shift <<= 1;
|
||||
}
|
||||
|
||||
if(status.wrdivctr) {
|
||||
//same as MUL; but with sixteen iterations, and counter is not inverted
|
||||
if(--status.wrdivctr < 16) {
|
||||
unsigned shift = status.wrdivctr;
|
||||
status.r4214 <<= 1;
|
||||
if(status.r4216 >= (status.wrdivb << shift)) {
|
||||
status.r4216 -= (status.wrdivb << shift);
|
||||
status.r4214 |= 1;
|
||||
}
|
||||
if(alu.divctr) {
|
||||
alu.divctr--;
|
||||
status.rddiv <<= 1;
|
||||
alu.shift >>= 1;
|
||||
if(status.rdmpy >= alu.shift) {
|
||||
status.rdmpy -= alu.shift;
|
||||
status.rddiv |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//====
|
||||
//HDMA
|
||||
//====
|
||||
|
||||
void sCPU::dma_edge() {
|
||||
while(cycle_edge_state) {
|
||||
switch(bit::lowest(cycle_edge_state)) {
|
||||
case EventFlagHdmaInit: {
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
void add_clocks(unsigned clocks);
|
||||
void scanline();
|
||||
|
||||
alwaysinline void cycle_edge();
|
||||
alwaysinline void alu_edge();
|
||||
alwaysinline void dma_edge();
|
||||
alwaysinline void last_cycle();
|
||||
|
||||
void timing_power();
|
||||
|
||||
@@ -7,17 +7,17 @@ bool DSPDebugger::property(unsigned id, string &name, string &value) {
|
||||
if(id == n++) { name = "Main Volume - Right"; value = main_volume_right(); return true; }
|
||||
if(id == n++) { name = "Echo Volume - Left"; value = echo_volume_left(); return true; }
|
||||
if(id == n++) { name = "Echo Volume - Right"; value = echo_volume_right(); return true; }
|
||||
if(id == n++) { name = "Key On"; value = sprint("0x$", strhex<2>(key_on())); return true; }
|
||||
if(id == n++) { name = "Key Off"; value = sprint("0x$", strhex<2>(key_off())); return true; }
|
||||
if(id == n++) { name = "Key On"; value = sprint("0x", strhex<2>(key_on())); return true; }
|
||||
if(id == n++) { name = "Key Off"; value = sprint("0x", strhex<2>(key_off())); return true; }
|
||||
if(id == n++) { name = "Flag - Reset"; value = flag_reset(); return true; }
|
||||
if(id == n++) { name = "Flag - Mute"; value = flag_mute(); return true; }
|
||||
if(id == n++) { name = "Flag - Echo Disable"; value = flag_echo_disable(); return true; }
|
||||
if(id == n++) { name = "Flag - Noise Clock"; value = flag_noise_clock(); return true; }
|
||||
if(id == n++) { name = "Source End Block"; value = source_end_block(); return true; }
|
||||
if(id == n++) { name = "Echo Feedback"; value = echo_feedback(); return true; }
|
||||
if(id == n++) { name = "Pitch Modulation Enable"; value = sprint("0x$", strhex<2>(pitch_modulation_enable())); return true; }
|
||||
if(id == n++) { name = "Noise Enable"; value = sprint("0x$", strhex<2>(noise_enable())); return true; }
|
||||
if(id == n++) { name = "Echo Enable"; value = sprint("0x$", strhex<2>(echo_enable())); return true; }
|
||||
if(id == n++) { name = "Pitch Modulation Enable"; value = sprint("0x", strhex<2>(pitch_modulation_enable())); return true; }
|
||||
if(id == n++) { name = "Noise Enable"; value = sprint("0x", strhex<2>(noise_enable())); return true; }
|
||||
if(id == n++) { name = "Echo Enable"; value = sprint("0x", strhex<2>(echo_enable())); return true; }
|
||||
if(id == n++) { name = "Source Directory"; value = source_directory(); return true; }
|
||||
if(id == n++) { name = "Echo Start Address"; value = echo_start_address(); return true; }
|
||||
if(id == n++) { name = "Echo Directory"; value = echo_directory(); return true; }
|
||||
@@ -25,7 +25,7 @@ bool DSPDebugger::property(unsigned id, string &name, string &value) {
|
||||
for(unsigned i = 0; i < 8; i++) {
|
||||
if(id == n++) {
|
||||
name = string() << "Coefficient " << i;
|
||||
value = sprint("0x$", strhex<2>(echo_filter_coefficient(i)));
|
||||
value = sprint("0x", strhex<2>(echo_filter_coefficient(i)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ bool DSPDebugger::property(unsigned id, string &name, string &value) {
|
||||
|
||||
if(id == n++) { name = "Volume - Left"; value = voice_volume_left(i); return true; }
|
||||
if(id == n++) { name = "Volume - Right"; value = voice_volume_right(i); return true; }
|
||||
if(id == n++) { name = "Pitch Height"; value = sprint("0x$", strhex<4>(voice_pitch_height(i))); return true; }
|
||||
if(id == n++) { name = "Pitch Height"; value = sprint("0x", strhex<4>(voice_pitch_height(i))); return true; }
|
||||
if(id == n++) { name = "Source Number"; value = voice_source_number(i); return true; }
|
||||
if(id == n++) { name = "ADSR1"; value = voice_adsr1(i); return true; }
|
||||
if(id == n++) { name = "ADSR2"; value = voice_adsr2(i); return true; }
|
||||
|
||||
@@ -5,6 +5,15 @@
|
||||
#endif
|
||||
|
||||
namespace SNES {
|
||||
typedef int8_t int8;
|
||||
typedef int16_t int16;
|
||||
typedef int32_t int32;
|
||||
typedef int64_t int64;
|
||||
typedef uint8_t uint8;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
struct ChipDebugger {
|
||||
virtual bool property(unsigned id, string &name, string &value) = 0;
|
||||
};
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#define NALL_ANY_HPP
|
||||
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
class any {
|
||||
@@ -13,8 +13,8 @@ namespace nall {
|
||||
|
||||
template<typename T> any& operator=(const T& value_) {
|
||||
typedef typename static_if<
|
||||
is_array<T>::value,
|
||||
typename remove_extent<typename add_const<T>::type>::type*,
|
||||
std::is_array<T>::value,
|
||||
typename std::remove_extent<typename std::add_const<T>::type>::type*,
|
||||
T
|
||||
>::type auto_t;
|
||||
|
||||
@@ -49,13 +49,13 @@ namespace nall {
|
||||
};
|
||||
|
||||
template<typename T> T any_cast(any &value) {
|
||||
typedef typename remove_reference<T>::type nonref;
|
||||
typedef typename std::remove_reference<T>::type nonref;
|
||||
if(value.type() != typeid(nonref)) throw;
|
||||
return static_cast<any::holder<nonref>*>(value.container)->value;
|
||||
}
|
||||
|
||||
template<typename T> T any_cast(const any &value) {
|
||||
typedef const typename remove_reference<T>::type nonref;
|
||||
typedef const typename std::remove_reference<T>::type nonref;
|
||||
if(value.type() != typeid(nonref)) throw;
|
||||
return static_cast<any::holder<nonref>*>(value.container)->value;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
//dynamic vector array
|
||||
@@ -81,7 +82,7 @@ namespace nall {
|
||||
return *this;
|
||||
}
|
||||
|
||||
array(const array &source) : pool(0) {
|
||||
array(const array &source) : pool(0), poolsize(0), buffersize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -92,11 +93,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
buffersize = source.buffersize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
array(array &&source) {
|
||||
operator=(move(source));
|
||||
array(array &&source) : pool(0), poolsize(0), buffersize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//index
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
for(unsigned foreach_counter = 0, foreach_limit = foreach_size(object), foreach_once = 0, foreach_broken = 0; foreach_counter < foreach_limit && foreach_broken == 0; foreach_counter++, foreach_once = 0) \
|
||||
for(auto &iter = object[foreach_counter]; foreach_once == 0 && (foreach_broken = 1); foreach_once++, foreach_broken = 0)
|
||||
|
||||
#include <type_traits>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<has_count<T>>::type = 0) {
|
||||
@@ -23,8 +23,8 @@ namespace nall {
|
||||
return object.size();
|
||||
}
|
||||
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<is_array<T>>::type = 0) {
|
||||
return sizeof(T) / sizeof(typename remove_extent<T>::type);
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<std::is_array<T>>::type = 0) {
|
||||
return sizeof(T) / sizeof(typename std::remove_extent<T>::type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+68
-156
@@ -1,190 +1,102 @@
|
||||
#ifndef NALL_FUNCTION_HPP
|
||||
#define NALL_FUNCTION_HPP
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
//prologue
|
||||
|
||||
#define TN typename
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> class function;
|
||||
}
|
||||
|
||||
//parameters = 0
|
||||
|
||||
#define cat(n) n
|
||||
#define TL typename R
|
||||
#define PL
|
||||
#define CL
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 1
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1
|
||||
#define PL P1 p1
|
||||
#define CL p1
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 2
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2
|
||||
#define PL P1 p1, P2 p2
|
||||
#define CL p1, p2
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 3
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3
|
||||
#define PL P1 p1, P2 p2, P3 p3
|
||||
#define CL p1, p2, p3
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 4
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4
|
||||
#define CL p1, p2, p3, p4
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 5
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5
|
||||
#define CL p1, p2, p3, p4, p5
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 6
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6
|
||||
#define CL p1, p2, p3, p4, p5, p6
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 7
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6, TN P7
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7
|
||||
#define CL p1, p2, p3, p4, p5, p6, p7
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 8
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6, TN P7, TN P8
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8
|
||||
#define CL p1, p2, p3, p4, p5, p6, p7, p8
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//epilogue
|
||||
|
||||
#undef TN
|
||||
#define NALL_FUNCTION_T
|
||||
|
||||
#elif !defined(NALL_FUNCTION_T)
|
||||
|
||||
//function implementation template class
|
||||
|
||||
namespace nall {
|
||||
template<TL>
|
||||
class function<R (PL)> {
|
||||
template<typename R, typename... P>
|
||||
class function<R (P...)> {
|
||||
private:
|
||||
struct base1 { virtual void func1(PL) {} };
|
||||
struct base2 { virtual void func2(PL) {} };
|
||||
struct base1 { virtual void func1(P...) {} };
|
||||
struct base2 { virtual void func2(P...) {} };
|
||||
struct derived : base1, virtual base2 {};
|
||||
|
||||
struct data_t {
|
||||
R (*fn_call)(const data_t& cat(PL));
|
||||
R (*callback)(const data_t&, P...);
|
||||
union {
|
||||
R (*fn_global)(PL);
|
||||
R (*callback_global)(P...);
|
||||
struct {
|
||||
R (derived::*fn_member)(PL);
|
||||
R (derived::*callback_member)(P...);
|
||||
void *object;
|
||||
};
|
||||
};
|
||||
} data;
|
||||
|
||||
static R fn_call_global(const data_t &d cat(PL)) {
|
||||
return d.fn_global(CL);
|
||||
static R callback_global(const data_t &data, P... p) {
|
||||
return data.callback_global(p...);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static R fn_call_member(const data_t &d cat(PL)) {
|
||||
return (((C*)d.object)->*((R (C::*&)(PL))d.fn_member))(CL);
|
||||
static R callback_member(const data_t &data, P... p) {
|
||||
return (((C*)data.object)->*((R (C::*&)(P...))data.callback_member))(p...);
|
||||
}
|
||||
|
||||
public:
|
||||
R operator()(PL) const { return data.fn_call(data cat(CL)); }
|
||||
operator bool() const { return data.fn_call; }
|
||||
R operator()(P... p) const { return data.callback(data, p...); }
|
||||
operator bool() const { return data.callback; }
|
||||
void reset() { data.callback = 0; }
|
||||
|
||||
function() { data.fn_call = 0; }
|
||||
|
||||
function(void *fn) {
|
||||
data.fn_call = fn ? &fn_call_global : 0;
|
||||
data.fn_global = (R (*)(PL))fn;
|
||||
}
|
||||
|
||||
function(R (*fn)(PL)) {
|
||||
data.fn_call = &fn_call_global;
|
||||
data.fn_global = fn;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
function(R (C::*fn)(PL), C *obj) {
|
||||
data.fn_call = &fn_call_member<C>;
|
||||
(R (C::*&)(PL))data.fn_member = fn;
|
||||
assert(sizeof data.fn_member >= sizeof fn);
|
||||
data.object = obj;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
function(R (C::*fn)(PL) const, C *obj) {
|
||||
data.fn_call = &fn_call_member<C>;
|
||||
(R (C::*&)(PL))data.fn_member = (R (C::*&)(PL))fn;
|
||||
assert(sizeof data.fn_member >= sizeof fn);
|
||||
data.object = obj;
|
||||
}
|
||||
|
||||
function& operator=(void *fn) { return operator=(function(fn)); }
|
||||
function& operator=(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); return *this; }
|
||||
function(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); }
|
||||
function(const function &source) { operator=(source); }
|
||||
|
||||
//no pointer
|
||||
function() {
|
||||
data.callback = 0;
|
||||
}
|
||||
|
||||
//symbolic link pointer (nall/dl.hpp::sym, etc)
|
||||
function(void *callback) {
|
||||
data.callback = callback ? &callback_global : 0;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
|
||||
//global function pointer
|
||||
function(R (*callback)(P...)) {
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = callback;
|
||||
}
|
||||
|
||||
//member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...), C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//const member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...) const, C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = (R (C::*&)(P...))callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//lambda function pointer
|
||||
template<typename T>
|
||||
function(T callback) {
|
||||
static_assert(std::is_same<R, typename std::result_of<T(P...)>::type>::value, "lambda mismatch");
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
};
|
||||
|
||||
template<TL>
|
||||
function<R (PL)> bind(R (*fn)(PL)) {
|
||||
return function<R (PL)>(fn);
|
||||
//bind functions to ease construction and assignment of function() with more than one argument
|
||||
|
||||
template<typename C, typename R, typename... P>
|
||||
function<R (P...)> bind(R (C::*callback)(P...), C *object) {
|
||||
return function<R (P...)>(callback, object);
|
||||
}
|
||||
|
||||
template<typename C, TL>
|
||||
function<R (PL)> bind(R (C::*fn)(PL), C *obj) {
|
||||
return function<R (PL)>(fn, obj);
|
||||
}
|
||||
|
||||
template<typename C, TL>
|
||||
function<R (PL)> bind(R (C::*fn)(PL) const, C *obj) {
|
||||
return function<R (PL)>(fn, obj);
|
||||
template<typename C, typename R, typename... P>
|
||||
function<R (P...)> bind(R (C::*callback)(P...) const, C *object) {
|
||||
return function<R (P...)>(callback, object);
|
||||
}
|
||||
}
|
||||
|
||||
#undef cat
|
||||
#undef TL
|
||||
#undef PL
|
||||
#undef CL
|
||||
|
||||
#endif
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifndef NALL_SERIALIZER_HPP
|
||||
#define NALL_SERIALIZER_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
@@ -16,6 +17,7 @@ namespace nall {
|
||||
//caveats:
|
||||
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
|
||||
//- floating-point usage is not portable across platforms
|
||||
|
||||
class serializer {
|
||||
public:
|
||||
enum mode_t { Load, Save, Size };
|
||||
@@ -51,7 +53,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
template<typename T> void integer(T &value) {
|
||||
enum { size = is_bool<T>::value ? 1 : sizeof(T) };
|
||||
enum { size = std::is_same<bool, T>::value ? 1 : sizeof(T) };
|
||||
if(imode == Save) {
|
||||
for(unsigned n = 0; n < size; n++) idata[isize++] = value >> (n << 3);
|
||||
} else if(imode == Load) {
|
||||
@@ -63,7 +65,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
template<typename T> void array(T &array) {
|
||||
enum { size = sizeof(T) / sizeof(typename remove_extent<T>::type) };
|
||||
enum { size = sizeof(T) / sizeof(typename std::remove_extent<T>::type) };
|
||||
for(unsigned n = 0; n < size; n++) integer(array[n]);
|
||||
}
|
||||
|
||||
@@ -102,7 +104,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
serializer(serializer &&s) {
|
||||
operator=(move(s));
|
||||
operator=(std::move(s));
|
||||
}
|
||||
|
||||
//construction
|
||||
|
||||
@@ -10,42 +10,13 @@
|
||||
#include <nall/utf8.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
|
||||
inline char chrlower(char c);
|
||||
inline char chrupper(char c);
|
||||
inline int stricmp(const char *dest, const char *src);
|
||||
inline int strpos (const char *str, const char *key);
|
||||
inline int qstrpos(const char *str, const char *key);
|
||||
inline bool strbegin (const char *str, const char *key);
|
||||
inline bool stribegin(const char *str, const char *key);
|
||||
inline bool strend (const char *str, const char *key);
|
||||
inline bool striend(const char *str, const char *key);
|
||||
inline char* strlower(char *str);
|
||||
inline char* strupper(char *str);
|
||||
inline char* strtr(char *dest, const char *before, const char *after);
|
||||
inline uintmax_t strhex (const char *str);
|
||||
inline intmax_t strsigned (const char *str);
|
||||
inline uintmax_t strunsigned(const char *str);
|
||||
inline uintmax_t strbin (const char *str);
|
||||
inline double strdouble (const char *str);
|
||||
inline bool match(const char *pattern, const char *str);
|
||||
inline bool strint (const char *str, int &result);
|
||||
inline bool strmath(const char *str, int &result);
|
||||
inline size_t strlcpy(char *dest, const char *src, size_t length);
|
||||
inline size_t strlcat(char *dest, const char *src, size_t length);
|
||||
inline char* ltrim(char *str, const char *key = " ");
|
||||
inline char* rtrim(char *str, const char *key = " ");
|
||||
inline char* trim (char *str, const char *key = " ");
|
||||
inline char* ltrim_once(char *str, const char *key = " ");
|
||||
inline char* rtrim_once(char *str, const char *key = " ");
|
||||
inline char* trim_once (char *str, const char *key = " ");
|
||||
|
||||
namespace nall {
|
||||
class string;
|
||||
template<typename T> inline string to_string(T);
|
||||
|
||||
class string {
|
||||
public:
|
||||
inline void reserve(size_t);
|
||||
inline void reserve(unsigned);
|
||||
inline unsigned length() const;
|
||||
|
||||
inline string& assign(const char*);
|
||||
@@ -78,7 +49,7 @@ namespace nall {
|
||||
|
||||
protected:
|
||||
char *data;
|
||||
size_t size;
|
||||
unsigned size;
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
public:
|
||||
@@ -98,29 +69,69 @@ namespace nall {
|
||||
lstring(std::initializer_list<string>);
|
||||
};
|
||||
|
||||
template<typename... Args> inline string sprint(const char *s, Args... args);
|
||||
template<typename... Args> inline void print(const char *s, Args... args);
|
||||
//compare.hpp
|
||||
inline char chrlower(char c);
|
||||
inline char chrupper(char c);
|
||||
inline int stricmp(const char *dest, const char *src);
|
||||
inline int strpos (const char *str, const char *key);
|
||||
inline int qstrpos(const char *str, const char *key);
|
||||
inline bool strbegin (const char *str, const char *key);
|
||||
inline bool stribegin(const char *str, const char *key);
|
||||
inline bool strend (const char *str, const char *key);
|
||||
inline bool striend(const char *str, const char *key);
|
||||
|
||||
//convert.hpp
|
||||
inline char* strlower(char *str);
|
||||
inline char* strupper(char *str);
|
||||
inline char* strtr(char *dest, const char *before, const char *after);
|
||||
inline uintmax_t strhex (const char *str);
|
||||
inline intmax_t strsigned (const char *str);
|
||||
inline uintmax_t strunsigned(const char *str);
|
||||
inline uintmax_t strbin (const char *str);
|
||||
inline double strdouble (const char *str);
|
||||
|
||||
//match.hpp
|
||||
inline bool match(const char *pattern, const char *str);
|
||||
|
||||
//math.hpp
|
||||
inline bool strint (const char *str, int &result);
|
||||
inline bool strmath(const char *str, int &result);
|
||||
|
||||
//strl.hpp
|
||||
inline unsigned strlcpy(char *dest, const char *src, unsigned length);
|
||||
inline unsigned strlcat(char *dest, const char *src, unsigned length);
|
||||
|
||||
//trim.hpp
|
||||
inline char* ltrim(char *str, const char *key = " ");
|
||||
inline char* rtrim(char *str, const char *key = " ");
|
||||
inline char* trim (char *str, const char *key = " ");
|
||||
inline char* ltrim_once(char *str, const char *key = " ");
|
||||
inline char* rtrim_once(char *str, const char *key = " ");
|
||||
inline char* trim_once (char *str, const char *key = " ");
|
||||
|
||||
//utility.hpp
|
||||
inline unsigned strlcpy(string &dest, const char *src, unsigned length);
|
||||
inline unsigned strlcat(string &dest, const char *src, unsigned length);
|
||||
inline string substr(const char *src, unsigned start = 0, unsigned length = 0);
|
||||
inline string& strlower(string &str);
|
||||
inline string& strupper(string &str);
|
||||
inline string& strtr(string &dest, const char *before, const char *after);
|
||||
inline string& ltrim(string &str, const char *key = " ");
|
||||
inline string& rtrim(string &str, const char *key = " ");
|
||||
inline string& trim (string &str, const char *key = " ");
|
||||
inline string& ltrim_once(string &str, const char *key = " ");
|
||||
inline string& rtrim_once(string &str, const char *key = " ");
|
||||
inline string& trim_once (string &str, const char *key = " ");
|
||||
template<unsigned length = 0, char padding = '0'> inline string strhex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strsigned(intmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strunsigned(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strbin(uintmax_t value);
|
||||
inline unsigned strdouble(char *str, double value);
|
||||
inline string strdouble(double value);
|
||||
|
||||
//variadic.hpp
|
||||
template<typename... Args> inline string sprint(Args... args);
|
||||
template<typename... Args> inline void print(Args... args);
|
||||
};
|
||||
|
||||
inline size_t strlcpy(nall::string &dest, const char *src, size_t length);
|
||||
inline size_t strlcat(nall::string &dest, const char *src, size_t length);
|
||||
|
||||
inline nall::string& strlower(nall::string &str);
|
||||
inline nall::string& strupper(nall::string &str);
|
||||
inline nall::string& strtr(nall::string &dest, const char *before, const char *after);
|
||||
inline nall::string& ltrim(nall::string &str, const char *key = " ");
|
||||
inline nall::string& rtrim(nall::string &str, const char *key = " ");
|
||||
inline nall::string& trim (nall::string &str, const char *key = " ");
|
||||
inline nall::string& ltrim_once(nall::string &str, const char *key = " ");
|
||||
inline nall::string& rtrim_once(nall::string &str, const char *key = " ");
|
||||
inline nall::string& trim_once (nall::string &str, const char *key = " ");
|
||||
|
||||
inline nall::string substr(const char *src, size_t start = 0, size_t length = 0);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strhex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strsigned(intmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strunsigned(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strbin(uintmax_t value);
|
||||
inline size_t strdouble(char *str, double value);
|
||||
inline nall::string strdouble(double value);
|
||||
|
||||
#endif
|
||||
@@ -2,28 +2,31 @@
|
||||
#define NALL_STRING_CAST_HPP
|
||||
|
||||
namespace nall {
|
||||
//this is needed, as C++0x does not support explicit template specialization inside classes
|
||||
template<> inline string to_string<bool> (bool v) { return v ? "true" : "false"; }
|
||||
template<> inline string to_string<signed int> (signed int v) { return strsigned(v); }
|
||||
template<> inline string to_string<unsigned int> (unsigned int v) { return strunsigned(v); }
|
||||
template<> inline string to_string<double> (double v) { return strdouble(v); }
|
||||
template<> inline string to_string<char*> (char *v) { return v; }
|
||||
template<> inline string to_string<const char*> (const char *v) { return v; }
|
||||
template<> inline string to_string<string> (string v) { return v; }
|
||||
template<> inline string to_string<const string&>(const string &v) { return v; }
|
||||
|
||||
template<typename T> string& string::operator= (T value) { return assign(to_string<T>(value)); }
|
||||
template<typename T> string& string::operator<<(T value) { return append(to_string<T>(value)); }
|
||||
//this is needed, as C++0x does not support explicit template specialization inside classes
|
||||
template<> inline string to_string<bool> (bool v) { return v ? "true" : "false"; }
|
||||
template<> inline string to_string<signed int> (signed int v) { return strsigned(v); }
|
||||
template<> inline string to_string<unsigned int> (unsigned int v) { return strunsigned(v); }
|
||||
template<> inline string to_string<double> (double v) { return strdouble(v); }
|
||||
template<> inline string to_string<char*> (char *v) { return v; }
|
||||
template<> inline string to_string<const char*> (const char *v) { return v; }
|
||||
template<> inline string to_string<string> (string v) { return v; }
|
||||
template<> inline string to_string<const string&>(const string &v) { return v; }
|
||||
|
||||
template<typename T> lstring& lstring::operator<<(T value) {
|
||||
operator[](size()).assign(to_string<T>(value));
|
||||
return *this;
|
||||
}
|
||||
template<typename T> string& string::operator= (T value) { return assign(to_string<T>(value)); }
|
||||
template<typename T> string& string::operator<<(T value) { return append(to_string<T>(value)); }
|
||||
|
||||
template<typename T> lstring& lstring::operator<<(T value) {
|
||||
operator[](size()).assign(to_string<T>(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
template<> inline string to_string<QString>(QString v) { return v.toUtf8().constData(); }
|
||||
template<> inline string to_string<const QString&>(const QString &v) { return v.toUtf8().constData(); }
|
||||
string::operator QString() const { return QString::fromUtf8(*this); }
|
||||
#endif
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
template<> inline string to_string<const QString&>(const QString &v) { return v.toUtf8().constData(); }
|
||||
string::operator QString() const { return QString::fromUtf8(*this); }
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_COMPARE_HPP
|
||||
#define NALL_STRING_COMPARE_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char chrlower(char c) {
|
||||
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c;
|
||||
}
|
||||
@@ -97,4 +99,6 @@ bool striend(const char *str, const char *key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_CONVERT_HPP
|
||||
#define NALL_STRING_CONVERT_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char* strlower(char *str) {
|
||||
if(!str) return 0;
|
||||
int i = 0;
|
||||
@@ -146,4 +148,6 @@ double strdouble(const char *str) {
|
||||
return !negate ? result : -result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
void string::reserve(size_t size_) {
|
||||
void string::reserve(unsigned size_) {
|
||||
if(size_ > size) {
|
||||
size = size_;
|
||||
data = (char*)realloc(data, size + 1);
|
||||
@@ -81,6 +81,7 @@ string& string::operator=(string &&source) {
|
||||
size = source.size;
|
||||
data = source.data;
|
||||
source.data = 0;
|
||||
source.size = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -94,12 +95,12 @@ bool string::readfile(const char *filename) {
|
||||
#if !defined(_WIN32)
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
#else
|
||||
FILE *fp = _wfopen(nall::utf16_t(filename), L"rb");
|
||||
FILE *fp = _wfopen(utf16_t(filename), L"rb");
|
||||
#endif
|
||||
if(!fp) return false;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t size = ftell(fp);
|
||||
unsigned size = ftell(fp);
|
||||
rewind(fp);
|
||||
char *fdata = new char[size + 1];
|
||||
unsigned unused = fread(fdata, 1, size, fp);
|
||||
|
||||
@@ -2,59 +2,60 @@
|
||||
#define NALL_FILENAME_HPP
|
||||
|
||||
namespace nall {
|
||||
// "foo/bar.c" -> "foo/", "bar.c" -> "./"
|
||||
inline string dir(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
result[i + 1] = 0;
|
||||
break;
|
||||
}
|
||||
if(i == 0) result = "./";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "bar.c"
|
||||
inline string notdir(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
// "foo/bar.c" -> "foo/", "bar.c" -> "./"
|
||||
inline string dir(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
result[i + 1] = 0;
|
||||
break;
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
if(i == 0) result = "./";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "foo/bar"
|
||||
inline string basename(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
//file has no extension
|
||||
break;
|
||||
}
|
||||
|
||||
if(result[i] == '.') {
|
||||
result[i] = 0;
|
||||
break;
|
||||
}
|
||||
// "foo/bar.c" -> "bar.c"
|
||||
inline string notdir(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "c"
|
||||
inline string extension(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '.') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
// "foo/bar.c" -> "foo/bar"
|
||||
inline string basename(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
//file has no extension
|
||||
break;
|
||||
}
|
||||
if(result[i] == '.') {
|
||||
result[i] = 0;
|
||||
break;
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "c"
|
||||
inline string extension(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '.') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_MATCH_HPP
|
||||
#define NALL_STRING_MATCH_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
bool match(const char *p, const char *s) {
|
||||
const char *p_ = 0, *s_ = 0;
|
||||
|
||||
@@ -69,4 +71,6 @@ bool match(const char *p, const char *s) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_MATH_HPP
|
||||
#define NALL_STRING_MATH_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
static int eval_integer(const char *&s) {
|
||||
if(!*s) throw "unrecognized_integer";
|
||||
int value = 0, x = *s, y = *(s + 1);
|
||||
@@ -157,4 +159,6 @@ bool strmath(const char *s, int &result) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,13 +1,15 @@
|
||||
#ifndef NALL_STRING_STRL_HPP
|
||||
#define NALL_STRING_STRL_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
//strlcpy, strlcat based on OpenBSD implementation by Todd C. Miller
|
||||
|
||||
//return = strlen(src)
|
||||
size_t strlcpy(char *dest, const char *src, size_t length) {
|
||||
unsigned strlcpy(char *dest, const char *src, unsigned length) {
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t n = length;
|
||||
unsigned n = length;
|
||||
|
||||
if(n) {
|
||||
while(--n && (*d++ = *s++)); //copy as many bytes as possible, or until null terminator reached
|
||||
@@ -22,13 +24,13 @@ size_t strlcpy(char *dest, const char *src, size_t length) {
|
||||
}
|
||||
|
||||
//return = strlen(src) + min(length, strlen(dest))
|
||||
size_t strlcat(char *dest, const char *src, size_t length) {
|
||||
unsigned strlcat(char *dest, const char *src, unsigned length) {
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t n = length;
|
||||
unsigned n = length;
|
||||
|
||||
while(n-- && *d) d++; //find end of dest
|
||||
size_t dlength = d - dest;
|
||||
unsigned dlength = d - dest;
|
||||
n = length - dlength; //subtract length of dest from maximum string length
|
||||
|
||||
if(!n) return dlength + strlen(s);
|
||||
@@ -45,4 +47,6 @@ size_t strlcat(char *dest, const char *src, size_t length) {
|
||||
return dlength + (s - src); //return length of resulting string, sans null terminator
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_TRIM_HPP
|
||||
#define NALL_STRING_TRIM_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char* ltrim(char *str, const char *key) {
|
||||
if(!key || !*key) return str;
|
||||
while(strbegin(str, key)) {
|
||||
@@ -47,4 +49,6 @@ char* trim_once(char *str, const char *key) {
|
||||
return ltrim_once(rtrim_once(str, key), key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,18 +1,20 @@
|
||||
#ifndef NALL_STRING_UTILITY_HPP
|
||||
#define NALL_STRING_UTILITY_HPP
|
||||
|
||||
size_t strlcpy(nall::string &dest, const char *src, size_t length) {
|
||||
namespace nall {
|
||||
|
||||
unsigned strlcpy(string &dest, const char *src, unsigned length) {
|
||||
dest.reserve(length);
|
||||
return strlcpy(dest(), src, length);
|
||||
}
|
||||
|
||||
size_t strlcat(nall::string &dest, const char *src, size_t length) {
|
||||
unsigned strlcat(string &dest, const char *src, unsigned length) {
|
||||
dest.reserve(length);
|
||||
return strlcat(dest(), src, length);
|
||||
}
|
||||
|
||||
nall::string substr(const char *src, size_t start, size_t length) {
|
||||
nall::string dest;
|
||||
string substr(const char *src, unsigned start, unsigned length) {
|
||||
string dest;
|
||||
if(length == 0) {
|
||||
//copy entire string
|
||||
dest = src + start;
|
||||
@@ -23,22 +25,22 @@ nall::string substr(const char *src, size_t start, size_t length) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* very simplistic wrappers to return nall::string& instead of char* type */
|
||||
/* very simplistic wrappers to return string& instead of char* type */
|
||||
|
||||
nall::string& strlower(nall::string &str) { strlower(str()); return str; }
|
||||
nall::string& strupper(nall::string &str) { strupper(str()); return str; }
|
||||
nall::string& strtr(nall::string &dest, const char *before, const char *after) { strtr(dest(), before, after); return dest; }
|
||||
nall::string& ltrim(nall::string &str, const char *key) { ltrim(str(), key); return str; }
|
||||
nall::string& rtrim(nall::string &str, const char *key) { rtrim(str(), key); return str; }
|
||||
nall::string& trim (nall::string &str, const char *key) { trim (str(), key); return str; }
|
||||
nall::string& ltrim_once(nall::string &str, const char *key) { ltrim_once(str(), key); return str; }
|
||||
nall::string& rtrim_once(nall::string &str, const char *key) { rtrim_once(str(), key); return str; }
|
||||
nall::string& trim_once (nall::string &str, const char *key) { trim_once (str(), key); return str; }
|
||||
string& strlower(string &str) { strlower(str()); return str; }
|
||||
string& strupper(string &str) { strupper(str()); return str; }
|
||||
string& strtr(string &dest, const char *before, const char *after) { strtr(dest(), before, after); return dest; }
|
||||
string& ltrim(string &str, const char *key) { ltrim(str(), key); return str; }
|
||||
string& rtrim(string &str, const char *key) { rtrim(str(), key); return str; }
|
||||
string& trim (string &str, const char *key) { trim (str(), key); return str; }
|
||||
string& ltrim_once(string &str, const char *key) { ltrim_once(str(), key); return str; }
|
||||
string& rtrim_once(string &str, const char *key) { rtrim_once(str(), key); return str; }
|
||||
string& trim_once (string &str, const char *key) { trim_once (str(), key); return str; }
|
||||
|
||||
/* arithmetic <> string */
|
||||
|
||||
template<unsigned length, char padding> nall::string strhex(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strhex(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
//render string backwards, as we do not know its length yet
|
||||
@@ -61,8 +63,8 @@ template<unsigned length, char padding> nall::string strhex(uintmax_t value) {
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strsigned(intmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strsigned(intmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
bool negative = value < 0;
|
||||
@@ -87,8 +89,8 @@ template<unsigned length, char padding> nall::string strsigned(intmax_t value) {
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strunsigned(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strunsigned(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
do {
|
||||
@@ -109,8 +111,8 @@ template<unsigned length, char padding> nall::string strunsigned(uintmax_t value
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strbin(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strbin(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
do {
|
||||
@@ -134,7 +136,7 @@ template<unsigned length, char padding> nall::string strbin(uintmax_t value) {
|
||||
//using sprintf is certainly not the most ideal method to convert
|
||||
//a double to a string ... but attempting to parse a double by
|
||||
//hand, digit-by-digit, results in subtle rounding errors.
|
||||
size_t strdouble(char *str, double value) {
|
||||
unsigned strdouble(char *str, double value) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "%f", value);
|
||||
|
||||
@@ -155,11 +157,13 @@ size_t strdouble(char *str, double value) {
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
nall::string strdouble(double value) {
|
||||
nall::string temp;
|
||||
string strdouble(double value) {
|
||||
string temp;
|
||||
temp.reserve(strdouble(0, value));
|
||||
strdouble(temp(), value);
|
||||
return temp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,36 +2,26 @@
|
||||
#define NALL_STRING_VARIADIC_HPP
|
||||
|
||||
namespace nall {
|
||||
static void sprint(string &output, unsigned &offset, const char *&s) {
|
||||
while(*s) output[offset++] = *s++;
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static void sprint(string &output, unsigned &offset, const char *&s, T value, Args... args) {
|
||||
while(*s) {
|
||||
if(*s == '$') {
|
||||
string data = to_string<T>(value);
|
||||
unsigned i = 0;
|
||||
while(data[i]) output[offset++] = data[i++];
|
||||
sprint(output, offset, ++s, args...);
|
||||
return;
|
||||
} else {
|
||||
output[offset++] = *s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void isprint(string &output) {
|
||||
}
|
||||
|
||||
template<typename... Args> inline string sprint(const char *s, Args... args) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
sprint(output, offset, s, args...);
|
||||
output[offset] = 0;
|
||||
return output;
|
||||
}
|
||||
template<typename T, typename... Args>
|
||||
static void isprint(string &output, T value, Args... args) {
|
||||
output << to_string<T>(value);
|
||||
isprint(output, args...);
|
||||
}
|
||||
|
||||
template<typename... Args> inline string sprint(Args... args) {
|
||||
string output;
|
||||
isprint(output, args...);
|
||||
return output;
|
||||
}
|
||||
|
||||
template<typename... Args> inline void print(Args... args) {
|
||||
printf("%s", (const char*)sprint(args...));
|
||||
}
|
||||
|
||||
template<typename... Args> inline void print(const char *s, Args... args) {
|
||||
printf("%s", (const char*)sprint(s, args...));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+22
-33
@@ -2,9 +2,7 @@
|
||||
#define NALL_STRING_XML_HPP
|
||||
|
||||
//XML subset parser
|
||||
//version 0.04
|
||||
|
||||
#include <nall/array.hpp>
|
||||
//version 0.05
|
||||
|
||||
namespace nall {
|
||||
|
||||
@@ -16,15 +14,14 @@ struct xml_attribute {
|
||||
|
||||
struct xml_element : xml_attribute {
|
||||
string parse() const;
|
||||
array<xml_attribute*> attribute;
|
||||
array<xml_element*> element;
|
||||
~xml_element();
|
||||
linear_vector<xml_attribute> attribute;
|
||||
linear_vector<xml_element> element;
|
||||
|
||||
protected:
|
||||
void parse_doctype(const char *&data);
|
||||
bool parse_head(string data);
|
||||
bool parse_body(const char *&data);
|
||||
friend xml_element *xml_parse(const char *data);
|
||||
friend xml_element xml_parse(const char *data);
|
||||
};
|
||||
|
||||
inline string xml_attribute::parse() const {
|
||||
@@ -134,11 +131,11 @@ inline bool xml_element::parse_head(string data) {
|
||||
side.qsplit("=", part[i]);
|
||||
if(side.size() != 2) throw "...";
|
||||
|
||||
xml_attribute *attr = new xml_attribute;
|
||||
attr->name = side[0];
|
||||
attr->content = side[1];
|
||||
if(strbegin(attr->content, "\"") && strend(attr->content, "\"")) trim_once(attr->content, "\"");
|
||||
else if(strbegin(attr->content, "'") && strend(attr->content, "'")) trim_once(attr->content, "'");
|
||||
xml_attribute attr;
|
||||
attr.name = side[0];
|
||||
attr.content = side[1];
|
||||
if(strbegin(attr.content, "\"") && strend(attr.content, "\"")) trim_once(attr.content, "\"");
|
||||
else if(strbegin(attr.content, "'") && strend(attr.content, "'")) trim_once(attr.content, "'");
|
||||
else throw "...";
|
||||
attribute.add(attr);
|
||||
}
|
||||
@@ -191,10 +188,8 @@ inline bool xml_element::parse_body(const char *&data) {
|
||||
|
||||
while(*data) {
|
||||
unsigned index = element.size();
|
||||
xml_element *elem = new xml_element;
|
||||
if(elem->parse_body(data) == false) {
|
||||
delete elem;
|
||||
|
||||
xml_element node;
|
||||
if(node.parse_body(data) == false) {
|
||||
if(*data == '/') {
|
||||
signed length = data - content_begin - 1;
|
||||
if(length > 0) content = substr(content_begin, 0, length);
|
||||
@@ -216,23 +211,18 @@ inline bool xml_element::parse_body(const char *&data) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
element.add(elem);
|
||||
element.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline xml_element::~xml_element() {
|
||||
for(unsigned i = 0; i < attribute.size(); i++) delete attribute[i];
|
||||
for(unsigned i = 0; i < element.size(); i++) delete element[i];
|
||||
}
|
||||
|
||||
//ensure there is only one root element
|
||||
inline bool xml_validate(xml_element *document) {
|
||||
inline bool xml_validate(xml_element &document) {
|
||||
unsigned root_counter = 0;
|
||||
|
||||
for(unsigned i = 0; i < document->element.size(); i++) {
|
||||
string &name = document->element[i]->name;
|
||||
for(unsigned i = 0; i < document.element.size(); i++) {
|
||||
string &name = document.element[i].name;
|
||||
if(strbegin(name, "?")) continue;
|
||||
if(strbegin(name, "!")) continue;
|
||||
if(++root_counter > 1) return false;
|
||||
@@ -241,25 +231,24 @@ inline bool xml_validate(xml_element *document) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline xml_element* xml_parse(const char *data) {
|
||||
xml_element *self = new xml_element;
|
||||
inline xml_element xml_parse(const char *data) {
|
||||
xml_element self;
|
||||
|
||||
try {
|
||||
while(*data) {
|
||||
xml_element *elem = new xml_element;
|
||||
if(elem->parse_body(data) == false) {
|
||||
delete elem;
|
||||
xml_element node;
|
||||
if(node.parse_body(data) == false) {
|
||||
break;
|
||||
} else {
|
||||
self->element.add(elem);
|
||||
self.element.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
if(xml_validate(self) == false) throw "...";
|
||||
return self;
|
||||
} catch(const char*) {
|
||||
delete self;
|
||||
return 0;
|
||||
xml_element empty;
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
#ifndef NALL_TRAITS_HPP
|
||||
#define NALL_TRAITS_HPP
|
||||
|
||||
namespace nall {
|
||||
//==
|
||||
//is
|
||||
//==
|
||||
|
||||
template<typename T> struct is_integral { enum { value = false }; };
|
||||
template<> struct is_integral<bool> { enum { value = true }; };
|
||||
template<> struct is_integral<char> { enum { value = true }; };
|
||||
template<> struct is_integral<signed char> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned char> { enum { value = true }; };
|
||||
template<> struct is_integral<wchar_t> { enum { value = true }; };
|
||||
template<> struct is_integral<short> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned short> { enum { value = true }; };
|
||||
template<> struct is_integral<long> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned long> { enum { value = true }; };
|
||||
template<> struct is_integral<long long> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned long long> { enum { value = true }; };
|
||||
template<> struct is_integral<int> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned int> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_floating_point { enum { value = false }; };
|
||||
template<> struct is_floating_point<float> { enum { value = true }; };
|
||||
template<> struct is_floating_point<double> { enum { value = true }; };
|
||||
template<> struct is_floating_point<long double> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_bool { enum { value = false }; };
|
||||
template<> struct is_bool<bool> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_void { enum { value = false }; };
|
||||
template<> struct is_void<void> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_arithmetic {
|
||||
enum { value = is_integral<T>::value || is_floating_point<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_fundamental {
|
||||
enum { value = is_integral<T>::value || is_floating_point<T>::value || is_void<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_compound {
|
||||
enum { value = !is_fundamental<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_array { enum { value = false }; };
|
||||
template<typename T> struct is_array<T[]> { enum { value = true }; };
|
||||
template<typename T, int N> struct is_array<T[N]> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_const { enum { value = false }; };
|
||||
template<typename T> struct is_const<const T> { enum { value = true }; };
|
||||
template<typename T> struct is_const<const T&> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_pointer { enum { value = false }; };
|
||||
template<typename T> struct is_pointer<T*> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_reference { enum { value = false }; };
|
||||
template<typename T> struct is_reference<T&> { enum { value = true }; };
|
||||
|
||||
template<typename T, typename U> struct is_same { enum { value = false }; };
|
||||
template<typename T> struct is_same<T, T> { enum { value = true }; };
|
||||
|
||||
//===
|
||||
//add
|
||||
//===
|
||||
|
||||
template<typename T> struct add_const { typedef const T type; };
|
||||
template<typename T> struct add_const<const T> { typedef const T type; };
|
||||
template<typename T> struct add_const<const T&> { typedef const T& type; };
|
||||
|
||||
template<typename T> struct add_pointer { typedef T* type; };
|
||||
template<typename T> struct add_pointer<T*> { typedef T** type; };
|
||||
|
||||
template<typename T> struct add_reference { typedef T& type; };
|
||||
template<typename T> struct add_reference<T&> { typedef T& type; };
|
||||
|
||||
//======
|
||||
//remove
|
||||
//======
|
||||
|
||||
template<typename T> struct remove_const { typedef T type; };
|
||||
template<typename T> struct remove_const<const T> { typedef T type; };
|
||||
template<typename T> struct remove_const<const T&> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_extent { typedef T type; };
|
||||
template<typename T> struct remove_extent<T[]> { typedef T type; };
|
||||
template<typename T, int N> struct remove_extent<T[N]> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_pointer { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T*> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_reference { typedef T type; };
|
||||
template<typename T> struct remove_reference<T&> { typedef T type; };
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,29 +1,18 @@
|
||||
#ifndef NALL_UTILITY_HPP
|
||||
#define NALL_UTILITY_HPP
|
||||
|
||||
#include <nall/traits.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> struct identity {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T> typename remove_reference<T>::type&& move(T &&value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T> T&& forward(typename identity<T>::type &&value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template<bool C, typename T = bool> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> {};
|
||||
template<typename C, typename T = bool> struct mp_enable_if : enable_if<C::value, T> {};
|
||||
|
||||
template<typename T> inline void swap(T &x, T &y) {
|
||||
T temp(move(x));
|
||||
x = move(y);
|
||||
y = move(temp);
|
||||
T temp(std::move(x));
|
||||
x = std::move(y);
|
||||
y = std::move(temp);
|
||||
}
|
||||
|
||||
template<typename T> struct base_from_member {
|
||||
|
||||
+14
-9
@@ -3,10 +3,11 @@
|
||||
|
||||
#include <initializer_list>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
@@ -86,11 +87,12 @@ namespace nall {
|
||||
inline linear_vector<T>& operator=(const linear_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
for(unsigned i = 0; i < source.size(); i++) add(source[i]);
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(const linear_vector<T> &source) {
|
||||
linear_vector(const linear_vector<T> &source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -101,11 +103,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(linear_vector<T> &&source) {
|
||||
operator=(move(source));
|
||||
linear_vector(linear_vector<T> &&source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//construction
|
||||
@@ -193,11 +196,12 @@ namespace nall {
|
||||
inline pointer_vector<T>& operator=(const pointer_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
for(unsigned i = 0; i < source.size(); i++) add(source[i]);
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(const pointer_vector<T> &source) {
|
||||
pointer_vector(const pointer_vector<T> &source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -208,11 +212,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(pointer_vector<T> &&source) {
|
||||
operator=(move(source));
|
||||
pointer_vector(pointer_vector<T> &&source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//construction
|
||||
|
||||
@@ -46,7 +46,7 @@ unsigned MappedRAM::size() const { return size_; }
|
||||
|
||||
uint8 MappedRAM::read(unsigned addr) { return data_[addr]; }
|
||||
void MappedRAM::write(unsigned addr, uint8 n) { if(!write_protect_) data_[addr] = n; }
|
||||
const uint8 MappedRAM::operator[](unsigned addr) const { return data_[addr]; }
|
||||
const uint8& MappedRAM::operator[](unsigned addr) const { return data_[addr]; }
|
||||
MappedRAM::MappedRAM() : data_(0), size_(-1U), write_protect_(false) {}
|
||||
|
||||
//Bus
|
||||
|
||||
@@ -48,7 +48,7 @@ struct MappedRAM : Memory {
|
||||
|
||||
inline uint8 read(unsigned addr);
|
||||
inline void write(unsigned addr, uint8 n);
|
||||
inline const uint8 operator[](unsigned addr) const;
|
||||
inline const uint8& operator[](unsigned addr) const;
|
||||
inline MappedRAM();
|
||||
|
||||
private:
|
||||
|
||||
Loaded 100 of 149 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user