Update to v082r24 release.

byuu says:

Upgraded to GCC 4.6.1.
Removed nall/foreach and nall/concept, upgraded iterator support on all
of my containers, and replaced everything with range-for.
Fixed up Qt geometry a good bit, should at least create windows now without bouncing around.
Added some initial nullptr / constexpr changes.
Some other minor cleanups ... removing foreach() took about 6-8 hours
alone.
This commit is contained in:
Tim Allen 2011-09-27 21:55:02 +10:00
parent 875ed46d79
commit 1d4f778176
113 changed files with 524 additions and 582 deletions

View File

@ -29,12 +29,14 @@ endif
# platform
ifeq ($(platform),x)
# tree vectorization causes code generation errors with GCC 4.6.1
flags += -fno-tree-vectorize
link += -s -ldl -lX11 -lXext
else ifeq ($(platform),osx)
else ifeq ($(platform),win)
link += $(if $(findstring console,$(options)),-mconsole,-mwindows)
link += -mthreads -s -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 -lole32
link += -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
link += -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
else
unknown_platform: help;
endif

View File

@ -55,7 +55,7 @@ void APU::power() {
create(Main, 4194304);
for(unsigned n = 0xff10; n <= 0xff3f; n++) bus.mmio[n] = this;
foreach(n, mmio_data) n = 0x00;
for(auto &n : mmio_data) n = 0x00;
sequencer_base = 0;
sequencer_step = 0;

View File

@ -71,7 +71,7 @@ void APU::Wave::power() {
counter = 0;
random_lfsr r;
foreach(n, pattern) n = r() & 15;
for(auto &n : pattern) n = r() & 15;
output = 0;
length = 0;

View File

@ -34,9 +34,9 @@ void Cartridge::load(const string &xml, const uint8_t *data, unsigned size) {
info.ramsize = 0;
xml_element document = xml_parse(xml);
foreach(head, document.element) {
for(auto &head : document.element) {
if(head.name == "cartridge") {
foreach(attr, head.attribute) {
for(auto &attr : head.attribute) {
if(attr.name == "mapper") {
if(attr.content == "none") info.mapper = Mapper::MBC0;
if(attr.content == "MBC1") info.mapper = Mapper::MBC1;
@ -52,16 +52,16 @@ void Cartridge::load(const string &xml, const uint8_t *data, unsigned size) {
if(attr.name == "rumble") info.rumble = (attr.content == "true" ? true : false);
}
foreach(elem, head.element) {
for(auto &elem : head.element) {
if(elem.name == "rom") {
foreach(attr, elem.attribute) {
for(auto &attr : elem.attribute) {
if(attr.name == "size") info.romsize = hex(attr.content);
}
}
if(elem.name == "ram") {
info.ram = true;
foreach(attr, elem.attribute) {
for(auto &attr : elem.attribute) {
if(attr.name == "size") info.ramsize = hex(attr.content);
if(attr.name == "battery") info.battery = (attr.content == "true" ? true : false);
}

View File

@ -11,13 +11,13 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
if(initialize == false) {
initialize = true;
foreach(n, mapProActionReplay) n = ~0;
for(auto &n : mapProActionReplay) n = ~0;
mapProActionReplay['0'] = 0; mapProActionReplay['1'] = 1; mapProActionReplay['2'] = 2; mapProActionReplay['3'] = 3;
mapProActionReplay['4'] = 4; mapProActionReplay['5'] = 5; mapProActionReplay['6'] = 6; mapProActionReplay['7'] = 7;
mapProActionReplay['8'] = 8; mapProActionReplay['9'] = 9; mapProActionReplay['A'] = 10; mapProActionReplay['B'] = 11;
mapProActionReplay['C'] = 12; mapProActionReplay['D'] = 13; mapProActionReplay['E'] = 14; mapProActionReplay['F'] = 15;
foreach(n, mapGameGenie) n = ~0;
for(auto &n : mapGameGenie) n = ~0;
mapGameGenie['0'] = 0; mapGameGenie['1'] = 1; mapGameGenie['2'] = 2; mapGameGenie['3'] = 3;
mapGameGenie['4'] = 4; mapGameGenie['5'] = 5; mapGameGenie['6'] = 6; mapGameGenie['7'] = 7;
mapGameGenie['8'] = 8; mapGameGenie['9'] = 9; mapGameGenie['A'] = 10; mapGameGenie['B'] = 11;
@ -81,7 +81,7 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
}
void Cheat::synchronize() {
foreach(n, override) n = false;
for(auto &n : override) n = false;
for(unsigned n = 0; n < size(); n++) {
override[operator[](n).addr] = true;

View File

@ -17,7 +17,6 @@ namespace GameBoy {
#include <libco/libco.h>
#include <nall/foreach.hpp>
#include <nall/platform.hpp>
#include <nall/property.hpp>
#include <nall/random.hpp>

View File

@ -69,10 +69,10 @@ bool Interface::unserialize(serializer &s) {
void Interface::setCheats(const lstring &list) {
cheat.reset();
foreach(code, list) {
for(auto &code : list) {
lstring codelist;
codelist.split("+", code);
foreach(part, codelist) {
for(auto &part : codelist) {
unsigned addr, data, comp;
if(Cheat::decode(part, addr, data, comp)) {
cheat.append({ addr, data, comp });

View File

@ -32,9 +32,9 @@ ifeq ($(compiler),)
ifeq ($(platform),win)
compiler := gcc
else ifeq ($(platform),osx)
compiler := gcc-mp-4.5
compiler := gcc-mp-4.6
else
compiler := gcc-4.5
compiler := gcc-4.6
endif
endif

View File

@ -2,13 +2,12 @@
#define NALL_ARRAY_HPP
#include <stdlib.h>
#include <algorithm>
#include <initializer_list>
#include <type_traits>
#include <utility>
#include <nall/algorithm.hpp>
#include <nall/bit.hpp>
#include <nall/concept.hpp>
#include <nall/foreach.hpp>
#include <nall/utility.hpp>
namespace nall {
@ -62,7 +61,7 @@ namespace nall {
unsigned listsize = container_size(list);
resize(buffersize + listsize);
memmove(pool + index + listsize, pool + index, (buffersize - index) * sizeof(T));
foreach(item, list) pool[index++] = item;
for(auto &item : list) pool[index++] = item;
}
void insert(unsigned index, const T item) {
@ -144,8 +143,6 @@ namespace nall {
const T* begin() const { return &pool[0]; }
const T* end() const { return &pool[buffersize]; }
};
template<typename T> struct has_size<array<T>> { enum { value = true }; };
}
#endif

View File

@ -2,39 +2,43 @@
#define NALL_BIT_HPP
namespace nall {
template<int bits> inline unsigned uclamp(const unsigned x) {
constexpr inline unsigned binary(const char *s, unsigned sum = 0) {
return s[0] == 0 ? sum : binary(s + 1, (sum << 1) | s[0] == '1');
}
template<int bits> constexpr inline unsigned uclamp(const unsigned x) {
enum { y = (1U << (bits - 1)) + ((1U << (bits - 1)) - 1) };
return y + ((x - y) & -(x < y)); //min(x, y);
}
template<int bits> inline unsigned uclip(const unsigned x) {
template<int bits> constexpr inline unsigned uclip(const unsigned x) {
enum { m = (1U << (bits - 1)) + ((1U << (bits - 1)) - 1) };
return (x & m);
}
template<int bits> inline signed sclamp(const signed x) {
template<int bits> constexpr inline signed sclamp(const signed x) {
enum { b = 1U << (bits - 1), m = (1U << (bits - 1)) - 1 };
return (x > m) ? m : (x < -b) ? -b : x;
}
template<int bits> inline signed sclip(const signed x) {
template<int bits> constexpr inline signed sclip(const signed x) {
enum { b = 1U << (bits - 1), m = (1U << bits) - 1 };
return ((x & m) ^ b) - b;
}
namespace bit {
//lowest(0b1110) == 0b0010
template<typename T> inline T lowest(const T x) {
template<typename T> constexpr inline T lowest(const T x) {
return x & -x;
}
//clear_lowest(0b1110) == 0b1100
template<typename T> inline T clear_lowest(const T x) {
template<typename T> constexpr inline T clear_lowest(const T x) {
return x & (x - 1);
}
//set_lowest(0b0101) == 0b0111
template<typename T> inline T set_lowest(const T x) {
template<typename T> constexpr inline T set_lowest(const T x) {
return x | (x + 1);
}

View File

@ -1,34 +0,0 @@
#ifndef NALL_CONCEPT_HPP
#define NALL_CONCEPT_HPP
#include <nall/static.hpp>
#include <nall/utility.hpp>
namespace nall {
//unsigned count() const;
template<typename T> struct has_count { enum { value = false }; };
//unsigned length() const;
template<typename T> struct has_length { enum { value = false }; };
//unsigned size() const;
template<typename T> struct has_size { enum { value = false }; };
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<has_count<T>>::type = 0) {
return object.count();
}
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<has_length<T>>::type = 0) {
return object.length();
}
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<has_size<T>>::type = 0) {
return object.size();
}
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<std::is_array<T>>::type = 0) {
return sizeof(T) / sizeof(typename std::remove_extent<T>::type);
}
}
#endif

View File

@ -1,9 +1,9 @@
#ifndef NALL_DIRECTORY_HPP
#define NALL_DIRECTORY_HPP
#include <nall/foreach.hpp>
#include <nall/sort.hpp>
#include <nall/string.hpp>
#include <nall/vector.hpp>
#if defined(_WIN32)
#include <nall/windows/utf8.hpp>
@ -56,7 +56,7 @@ struct directory {
FindClose(handle);
}
if(list.size() > 0) sort(&list[0], list.size());
foreach(name, list) name.append("/"); //must append after sorting
for(auto &name : list) name.append("/"); //must append after sorting
return list;
}
@ -89,7 +89,7 @@ struct directory {
inline lstring directory::contents(const string &pathname, const string &pattern) {
lstring folders = directory::folders(pathname); //pattern search of contents() should only filter files
lstring files = directory::files(pathname, pattern);
foreach(file, files) folders.append(file);
for(auto &file : files) folders.append(file);
return folders;
}
#else
@ -116,7 +116,7 @@ struct directory {
closedir(dp);
}
if(list.size() > 0) sort(&list[0], list.size());
foreach(name, list) name.append("/"); //must append after sorting
for(auto &name : list) name.append("/"); //must append after sorting
return list;
}
@ -142,7 +142,7 @@ struct directory {
inline lstring directory::contents(const string &pathname, const string &pattern) {
lstring folders = directory::folders(pathname); //pattern search of contents() should only filter files
lstring files = directory::files(pathname, pattern);
foreach(file, files) folders.append(file);
for(auto &file : files) folders.append(file);
return folders;
}
#endif

View File

@ -1,18 +0,0 @@
#ifndef NALL_FOREACH_HPP
#define NALL_FOREACH_HPP
#include <type_traits>
#include <nall/concept.hpp>
#undef foreach
#define foreach2(iter, object) foreach3(iter, object, foreach_counter)
#define foreach3(iter, object, foreach_counter) \
for(unsigned foreach_counter = 0, foreach_limit = container_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)
#define foreach_impl(...) foreach_decl(__VA_ARGS__, foreach3(__VA_ARGS__), foreach2(__VA_ARGS__), foreach_too_few_arguments)
#define foreach_decl(_1, _2, _3, N, ...) N
#define foreach(...) foreach_impl(__VA_ARGS__)
#endif

View File

@ -96,6 +96,8 @@
_wfullpath(fn, nall::utf16_t(filename), _MAX_PATH);
strcpy(resolvedname, nall::utf8_t(fn));
for(unsigned n = 0; resolvedname[n]; n++) if(resolvedname[n] == '\\') resolvedname[n] = '/';
unsigned length = strlen(resolvedname);
if(resolvedname[length] != '/') strcpy(resolvedname + length, "/");
return resolvedname;
}
@ -104,6 +106,8 @@
SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, fp);
strcpy(path, nall::utf8_t(fp));
for(unsigned n = 0; path[n]; n++) if(path[n] == '\\') path[n] = '/';
unsigned length = strlen(path);
if(path[length] != '/') strcpy(path + length, "/");
return path;
}
@ -112,6 +116,8 @@
_wgetcwd(fp, _MAX_PATH);
strcpy(path, nall::utf8_t(fp));
for(unsigned n = 0; path[n]; n++) if(path[n] == '\\') path[n] = '/';
unsigned length = strlen(path);
if(path[length] != '/') strcpy(path + length, "/");
return path;
}
#else

View File

@ -1,9 +1,9 @@
#ifndef NALL_REFERENCE_ARRAY_HPP
#define NALL_REFERENCE_ARRAY_HPP
#include <algorithm>
#include <type_traits>
#include <nall/bit.hpp>
#include <nall/concept.hpp>
namespace nall {
template<typename T> struct reference_array {
@ -95,6 +95,22 @@ namespace nall {
return *pool[index];
}
//iteration
struct iterator {
bool operator!=(const iterator &source) const { return index != source.index; }
T& operator*() { return array.operator[](index); }
iterator& operator++() { index++; return *this; }
iterator(const reference_array &array, unsigned index) : array(array), index(index) {}
private:
const reference_array &array;
unsigned index;
};
iterator begin() { return iterator(*this, 0); }
iterator end() { return iterator(*this, buffersize); }
const iterator begin() const { return iterator(*this, 0); }
const iterator end() const { return iterator(*this, buffersize); }
private:
void construct() {
}
@ -112,8 +128,6 @@ namespace nall {
construct(args...);
}
};
template<typename T> struct has_size<reference_array<T>> { enum { value = true }; };
}
#endif

View File

@ -1,7 +1,6 @@
#ifndef NALL_STACK_HPP
#define NALL_STACK_HPP
#include <nall/concept.hpp>
#include <nall/vector.hpp>
namespace nall {
@ -22,8 +21,6 @@ namespace nall {
return linear_vector<T>::operator[](linear_vector<T>::size() - 1);
}
};
template<typename T> struct has_size<stack<T>> { enum { value = true }; };
}
#endif

View File

@ -1,11 +1,23 @@
#ifndef NALL_STRING_HPP
#define NALL_STRING_HPP
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <initializer_list>
#include <nall/array.hpp>
#include <nall/function.hpp>
#include <nall/platform.hpp>
#include <nall/sha256.hpp>
#include <nall/stdint.hpp>
#include <nall/utility.hpp>
#include <nall/vector.hpp>
#include <nall/windows/utf8.hpp>
#include <nall/string/base.hpp>
#include <nall/string/bsv.hpp>
@ -26,9 +38,4 @@
#include <nall/string/wrapper.hpp>
#include <nall/string/xml.hpp>
namespace nall {
template<> struct has_length<string> { enum { value = true }; };
template<> struct has_size<lstring> { enum { value = true }; };
}
#endif

View File

@ -1,16 +1,6 @@
#ifndef NALL_STRING_BASE_HPP
#define NALL_STRING_BASE_HPP
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <nall/concept.hpp>
#include <nall/function.hpp>
#include <nall/stdint.hpp>
#include <nall/vector.hpp>
#include <nall/windows/utf8.hpp>
namespace nall {
class string;
class lstring;
@ -77,6 +67,11 @@ namespace nall {
inline string(string&&);
inline ~string();
inline char* begin() { return &data[0]; }
inline char* end() { return &data[length()]; }
inline const char* begin() const { return &data[0]; }
inline const char* end() const { return &data[length()]; }
//internal functions
inline string& assign_(const char*);
inline string& append_(const char*);
@ -106,8 +101,8 @@ namespace nall {
inline bool operator==(const lstring&) const;
inline bool operator!=(const lstring&) const;
lstring();
lstring(std::initializer_list<string>);
inline lstring();
inline lstring(std::initializer_list<string>);
protected:
template<unsigned Limit, bool Insensitive, bool Quoted> inline lstring& usplit(const char*, const char*);
@ -133,7 +128,7 @@ namespace nall {
inline uintmax_t hex(const char *str);
inline intmax_t integer(const char *str);
inline uintmax_t decimal(const char *str);
inline uintmax_t binary(const char *str);
inline uintmax_t bin(const char *str);
inline double fp(const char *str);
//math.hpp
@ -175,7 +170,7 @@ namespace nall {
template<unsigned length = 0, char padding = ' '> inline string decimal(uintmax_t value);
template<unsigned length = 0, char padding = ' '> inline string ldecimal(uintmax_t value);
template<unsigned length = 0, char padding = '0'> inline string hex(uintmax_t value);
template<unsigned length = 0, char padding = '0'> inline string binary(uintmax_t value);
template<unsigned length = 0, char padding = '0'> inline string bin(uintmax_t value);
inline unsigned fp(char *str, double value);
inline string fp(double value);

View File

@ -118,7 +118,7 @@ uintmax_t decimal(const char *str) {
return result;
}
uintmax_t binary(const char *str) {
uintmax_t bin(const char *str) {
if(!str) return 0;
uintmax_t result = 0;

View File

@ -65,7 +65,7 @@ string sha256(const uint8_t *data, unsigned size) {
sha256_final(&sha);
sha256_hash(&sha, hash);
string result;
foreach(byte, hash) result.append(hex<2>(byte));
for(auto &byte : hash) result.append(hex<2>(byte));
return result;
}
@ -193,7 +193,7 @@ template<unsigned length_, char padding> string hex(uintmax_t value) {
return (const char*)result;
}
template<unsigned length_, char padding> string binary(uintmax_t value) {
template<unsigned length_, char padding> string bin(uintmax_t value) {
char buffer[256];
unsigned size = 0;

View File

@ -1,14 +1,13 @@
#ifndef NALL_VECTOR_HPP
#define NALL_VECTOR_HPP
#include <algorithm>
#include <initializer_list>
#include <new>
#include <type_traits>
#include <utility>
#include <nall/algorithm.hpp>
#include <nall/bit.hpp>
#include <nall/concept.hpp>
#include <nall/foreach.hpp>
#include <nall/utility.hpp>
namespace nall {
@ -77,7 +76,7 @@ namespace nall {
template<typename U> void insert(unsigned index, const U list) {
linear_vector<T> merged;
for(unsigned i = 0; i < index; i++) merged.append(pool[i]);
foreach(item, list) merged.append(item);
for(auto &item : list) merged.append(item);
for(unsigned i = index; i < objectsize; i++) merged.append(pool[i]);
operator=(merged);
}
@ -211,7 +210,7 @@ namespace nall {
template<typename U> void insert(unsigned index, const U list) {
pointer_vector<T> merged;
for(unsigned i = 0; i < index; i++) merged.append(*pool[i]);
foreach(item, list) merged.append(item);
for(auto &item : list) merged.append(item);
for(unsigned i = index; i < objectsize; i++) merged.append(*pool[i]);
operator=(merged);
}
@ -284,18 +283,17 @@ namespace nall {
bool operator!=(const iterator &source) const { return index != source.index; }
T& operator*() { return vector.operator[](index); }
iterator& operator++() { index++; return *this; }
iterator(pointer_vector &vector, unsigned index) : vector(vector), index(index) {}
iterator(const pointer_vector &vector, unsigned index) : vector(vector), index(index) {}
private:
pointer_vector &vector;
const pointer_vector &vector;
unsigned index;
};
iterator begin() { return iterator(*this, 0); }
iterator end() { return iterator(*this, objectsize); }
const iterator begin() const { return iterator(*this, 0); }
const iterator end() const { return iterator(*this, objectsize); }
};
template<typename T> struct has_size<linear_vector<T>> { enum { value = true }; };
template<typename T> struct has_size<pointer_vector<T>> { enum { value = true }; };
}
#endif

View File

@ -290,12 +290,11 @@ void APU::write(uint16 addr, uint8 data) {
if((data & 0x02) == 0) rectangle[1].length_counter = 0;
if((data & 0x04) == 0) triangle.length_counter = 0;
if((data & 0x08) == 0) noise.length_counter = 0;
if((data & 0x10) == 0) dmc.length_counter = 0;
if((data & 0x10) && dmc.length_counter == 0) dmc.start();
(data & 0x10) ? dmc.start() : dmc.stop();
dmc.irq_pending = false;
set_irq_line();
set_irq_line();
enabled_channels = data & 0x1f;
break;
@ -456,8 +455,17 @@ uint8 APU::Noise::clock() {
}
void APU::DMC::start() {
read_addr = 0x4000 + (addr_latch << 6);
length_counter = (length_latch << 4) + 1;
if(length_counter == 0) {
read_addr = 0x4000 + (addr_latch << 6);
length_counter = (length_latch << 4) + 1;
}
}
void APU::DMC::stop() {
length_counter = 0;
dma_delay_counter = 0;
cpu.set_rdy_line(1);
cpu.set_rdy_addr({ false, 0u });
}
uint8 APU::DMC::clock() {

View File

@ -133,6 +133,7 @@ struct APU : Processor {
uint8 sample;
void start();
void stop();
uint8 clock();
void serialize(serializer&);
} dmc;

View File

@ -11,13 +11,13 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
if(initialize == false) {
initialize = true;
foreach(n, mapProActionReplay) n = ~0;
for(auto &n : mapProActionReplay) n = ~0;
mapProActionReplay['0'] = 0; mapProActionReplay['1'] = 1; mapProActionReplay['2'] = 2; mapProActionReplay['3'] = 3;
mapProActionReplay['4'] = 4; mapProActionReplay['5'] = 5; mapProActionReplay['6'] = 6; mapProActionReplay['7'] = 7;
mapProActionReplay['8'] = 8; mapProActionReplay['9'] = 9; mapProActionReplay['A'] = 10; mapProActionReplay['B'] = 11;
mapProActionReplay['C'] = 12; mapProActionReplay['D'] = 13; mapProActionReplay['E'] = 14; mapProActionReplay['F'] = 15;
foreach(n, mapGameGenie) n = ~0;
for(auto &n : mapGameGenie) n = ~0;
mapGameGenie['A'] = 0; mapGameGenie['P'] = 1; mapGameGenie['Z'] = 2; mapGameGenie['L'] = 3;
mapGameGenie['G'] = 4; mapGameGenie['I'] = 5; mapGameGenie['T'] = 6; mapGameGenie['Y'] = 7;
mapGameGenie['E'] = 8; mapGameGenie['O'] = 9; mapGameGenie['X'] = 10; mapGameGenie['U'] = 11;
@ -78,7 +78,7 @@ bool Cheat::decode(const string &code_, unsigned &addr, unsigned &data, unsigned
}
void Cheat::synchronize() {
foreach(n, override) n = false;
for(auto &n : override) n = false;
for(unsigned n = 0; n < size(); n++) {
override[operator[](n).addr] = true;

View File

@ -69,10 +69,10 @@ bool Interface::unserialize(serializer &s) {
void Interface::setCheats(const lstring &list) {
cheat.reset();
foreach(code, list) {
for(auto &code : list) {
lstring codelist;
codelist.split("+", code);
foreach(part, codelist) {
for(auto &part : codelist) {
unsigned addr, data, comp;
if(Cheat::decode(part, addr, data, comp)) {
cheat.append({ addr, data, comp });

View File

@ -218,7 +218,7 @@ void VRC6::power() {
}
void VRC6::reset() {
foreach(n, prg_ram) n = 0xff;
for(auto &n : prg_ram) n = 0xff;
prg_bank[0] = 0;
prg_bank[1] = 0;

View File

@ -23,7 +23,6 @@ namespace NES {
#include <nall/dl.hpp>
#include <nall/endian.hpp>
#include <nall/file.hpp>
#include <nall/foreach.hpp>
#include <nall/function.hpp>
#include <nall/platform.hpp>
#include <nall/property.hpp>

View File

@ -448,7 +448,7 @@ CheckItem::~CheckItem() {
//=========
void RadioItem::group(const reference_array<RadioItem&> &list) {
foreach(item, list) item.p.setGroup(item.state.group = list);
for(auto &item : list) item.p.setGroup(item.state.group = list);
if(list.size()) list[0].setChecked();
}
@ -457,7 +457,7 @@ bool RadioItem::checked() {
}
void RadioItem::setChecked() {
foreach(item, state.group) item.state.checked = false;
for(auto &item : state.group) item.state.checked = false;
state.checked = true;
return p.setChecked();
}
@ -476,7 +476,7 @@ p(base_from_member<pRadioItem&>::value) {
}
RadioItem::~RadioItem() {
foreach(item, state.group) {
for(auto &item : state.group) {
if(&item != this) item.state.group.remove(*this);
}
p.destructor();
@ -1003,7 +1003,7 @@ ProgressBar::~ProgressBar() {
//========
void RadioBox::group(const reference_array<RadioBox&> &list) {
foreach(item, list) item.p.setGroup(item.state.group = list);
for(auto &item : list) item.p.setGroup(item.state.group = list);
if(list.size()) list[0].setChecked();
}
@ -1012,7 +1012,7 @@ bool RadioBox::checked() {
}
void RadioBox::setChecked() {
foreach(item, state.group) item.state.checked = false;
for(auto &item : state.group) item.state.checked = false;
state.checked = true;
return p.setChecked();
}
@ -1031,7 +1031,7 @@ p(base_from_member<pRadioBox&>::value) {
}
RadioBox::~RadioBox() {
foreach(item, state.group) {
for(auto &item : state.group) {
if(&item != this) item.state.group.remove(*this);
}
p.destructor();

View File

@ -4,7 +4,7 @@ void FixedLayout::append(Sizable &sizable, const Geometry &geometry) {
}
void FixedLayout::append(Sizable &sizable) {
foreach(child, children) if(child.sizable == &sizable) return;
for(auto &child : children) if(child.sizable == &sizable) return;
Layout::append(sizable);
}
@ -15,7 +15,7 @@ bool FixedLayout::enabled() {
Geometry FixedLayout::minimumGeometry() {
unsigned width = MinimumSize, height = MinimumSize;
foreach(child, children) {
for(auto &child : children) {
width = max(width, child.sizable->minimumGeometry().width);
height = max(height, child.sizable->minimumGeometry().height);
}
@ -33,14 +33,14 @@ void FixedLayout::remove(Sizable &sizable) {
}
void FixedLayout::reset() {
foreach(child, children) {
for(auto &child : children) {
if(window() && dynamic_cast<Widget*>(child.sizable)) window()->remove((Widget&)*child.sizable);
}
}
void FixedLayout::setEnabled(bool enabled) {
state.enabled = enabled;
foreach(child, children) {
for(auto &child : children) {
child.sizable->setVisible(dynamic_cast<Widget*>(child.sizable) ? child.sizable->enabled() : enabled);
}
}
@ -50,13 +50,13 @@ void FixedLayout::setGeometry(const Geometry &geometry) {
void FixedLayout::setVisible(bool visible) {
state.visible = visible;
foreach(child, children) {
for(auto &child : children) {
child.sizable->setVisible(dynamic_cast<Widget*>(child.sizable) ? child.sizable->visible() : visible);
}
}
void FixedLayout::synchronizeLayout() {
foreach(child, children) {
for(auto &child : children) {
Layout::append(*child.sizable);
child.sizable->setGeometry(child.geometry);
}

View File

@ -1,11 +1,11 @@
void HorizontalLayout::append(Sizable &sizable, unsigned width, unsigned height, unsigned spacing) {
foreach(child, children) if(child.sizable == &sizable) return;
for(auto &child : children) if(child.sizable == &sizable) return;
children.append({ &sizable, width, height, spacing });
synchronizeLayout();
}
void HorizontalLayout::append(Sizable &sizable) {
foreach(child, children) if(child.sizable == &sizable) return;
for(auto &child : children) if(child.sizable == &sizable) return;
Layout::append(sizable);
if(window()) window()->synchronizeLayout();
}
@ -18,7 +18,7 @@ bool HorizontalLayout::enabled() {
Geometry HorizontalLayout::minimumGeometry() {
unsigned width = 0, height = 0;
foreach(child, children) {
for(auto &child : children) {
width += child.spacing;
if(child.width == MinimumSize || child.width == MaximumSize) {
width += child.sizable->minimumGeometry().width;
@ -27,7 +27,7 @@ Geometry HorizontalLayout::minimumGeometry() {
width += child.width;
}
foreach(child, children) {
for(auto &child : children) {
if(child.height == MinimumSize || child.height == MaximumSize) {
height = max(height, child.sizable->minimumGeometry().height);
continue;
@ -53,7 +53,7 @@ void HorizontalLayout::remove(Sizable &sizable) {
}
void HorizontalLayout::reset() {
foreach(child, children) {
for(auto &child : children) {
if(window() && dynamic_cast<Layout*>(child.sizable)) ((Layout*)child.sizable)->reset();
if(window() && dynamic_cast<Widget*>(child.sizable)) window()->remove((Widget&)*child.sizable);
}
@ -65,14 +65,14 @@ void HorizontalLayout::setAlignment(double alignment) {
void HorizontalLayout::setEnabled(bool enabled) {
state.enabled = enabled;
foreach(child, children) {
for(auto &child : children) {
child.sizable->setEnabled(dynamic_cast<Widget*>(child.sizable) ? child.sizable->enabled() : enabled);
}
}
void HorizontalLayout::setGeometry(const Geometry &containerGeometry) {
auto children = this->children;
foreach(child, children) {
for(auto &child : children) {
if(child.width == MinimumSize) child.width = child.sizable->minimumGeometry().width;
if(child.height == MinimumSize) child.height = child.sizable->minimumGeometry().height;
}
@ -84,21 +84,21 @@ void HorizontalLayout::setGeometry(const Geometry &containerGeometry) {
geometry.height -= state.margin * 2;
unsigned minimumWidth = 0, maximumWidthCounter = 0;
foreach(child, children) {
for(auto &child : children) {
if(child.width == MaximumSize) maximumWidthCounter++;
if(child.width != MaximumSize) minimumWidth += child.width;
minimumWidth += child.spacing;
}
foreach(child, children) {
for(auto &child : children) {
if(child.width == MaximumSize) child.width = (geometry.width - minimumWidth) / maximumWidthCounter;
if(child.height == MaximumSize) child.height = geometry.height;
}
unsigned maximumHeight = 0;
foreach(child, children) maximumHeight = max(maximumHeight, child.height);
for(auto &child : children) maximumHeight = max(maximumHeight, child.height);
foreach(child, children) {
for(auto &child : children) {
unsigned pivot = (maximumHeight - child.height) * state.alignment;
Geometry childGeometry = { geometry.x, geometry.y + pivot, child.width, child.height };
child.sizable->setGeometry(childGeometry);
@ -114,13 +114,13 @@ void HorizontalLayout::setMargin(unsigned margin) {
void HorizontalLayout::setVisible(bool visible) {
state.visible = visible;
foreach(child, children) {
for(auto &child : children) {
child.sizable->setVisible(dynamic_cast<Widget*>(child.sizable) ? child.sizable->visible() : visible);
}
}
void HorizontalLayout::synchronizeLayout() {
foreach(child, children) Layout::append(*child.sizable);
for(auto &child : children) Layout::append(*child.sizable);
}
bool HorizontalLayout::visible() {

View File

@ -1,11 +1,11 @@
void VerticalLayout::append(Sizable &sizable, unsigned width, unsigned height, unsigned spacing) {
foreach(child, children) if(child.sizable == &sizable) return;
for(auto &child : children) if(child.sizable == &sizable) return;
children.append({ &sizable, width, height, spacing });
synchronizeLayout();
}
void VerticalLayout::append(Sizable &sizable) {
foreach(child, children) if(child.sizable == &sizable) return;
for(auto &child : children) if(child.sizable == &sizable) return;
Layout::append(sizable);
if(window()) window()->synchronizeLayout();
}
@ -18,7 +18,7 @@ bool VerticalLayout::enabled() {
Geometry VerticalLayout::minimumGeometry() {
unsigned width = 0, height = 0;
foreach(child, children) {
for(auto &child : children) {
if(child.width == MinimumSize || child.width == MaximumSize) {
width = max(width, child.sizable->minimumGeometry().width);
continue;
@ -26,7 +26,7 @@ Geometry VerticalLayout::minimumGeometry() {
width = max(width, child.width);
}
foreach(child, children) {
for(auto &child : children) {
height += child.spacing;
if(child.height == MinimumSize || child.height == MaximumSize) {
height += child.sizable->minimumGeometry().height;
@ -53,7 +53,7 @@ void VerticalLayout::remove(Sizable &sizable) {
}
void VerticalLayout::reset() {
foreach(child, children) {
for(auto &child : children) {
if(window() && dynamic_cast<Layout*>(child.sizable)) ((Layout*)child.sizable)->reset();
if(window() && dynamic_cast<Widget*>(child.sizable)) window()->remove((Widget&)*child.sizable);
}
@ -65,14 +65,14 @@ void VerticalLayout::setAlignment(double alignment) {
void VerticalLayout::setEnabled(bool enabled) {
state.enabled = enabled;
foreach(child, children) {
for(auto &child : children) {
child.sizable->setEnabled(dynamic_cast<Widget*>(child.sizable) ? child.sizable->enabled() : enabled);
}
}
void VerticalLayout::setGeometry(const Geometry &containerGeometry) {
auto children = this->children;
foreach(child, children) {
for(auto &child : children) {
if(child.width == MinimumSize) child.width = child.sizable->minimumGeometry().width;
if(child.height == MinimumSize) child.height = child.sizable->minimumGeometry().height;
}
@ -84,21 +84,21 @@ void VerticalLayout::setGeometry(const Geometry &containerGeometry) {
geometry.height -= state.margin * 2;
unsigned minimumHeight = 0, maximumHeightCounter = 0;
foreach(child, children) {
for(auto &child : children) {
if(child.height == MaximumSize) maximumHeightCounter++;
if(child.height != MaximumSize) minimumHeight += child.height;
minimumHeight += child.spacing;
}
foreach(child, children) {
for(auto &child : children) {
if(child.width == MaximumSize) child.width = geometry.width;
if(child.height == MaximumSize) child.height = (geometry.height - minimumHeight) / maximumHeightCounter;
}
unsigned maximumWidth = 0;
foreach(child, children) maximumWidth = max(maximumWidth, child.width);
for(auto &child : children) maximumWidth = max(maximumWidth, child.width);
foreach(child, children) {
for(auto &child : children) {
unsigned pivot = (maximumWidth - child.width) * state.alignment;
Geometry childGeometry = { geometry.x + pivot, geometry.y, child.width, child.height };
child.sizable->setGeometry(childGeometry);
@ -114,13 +114,13 @@ void VerticalLayout::setMargin(unsigned margin) {
void VerticalLayout::setVisible(bool visible) {
state.visible = visible;
foreach(child, children) {
for(auto &child : children) {
child.sizable->setVisible(dynamic_cast<Widget*>(child.sizable) ? child.sizable->visible() : visible);
}
}
void VerticalLayout::synchronizeLayout() {
foreach(child, children) Layout::append(*child.sizable);
for(auto &child : children) Layout::append(*child.sizable);
}
bool VerticalLayout::visible() {

View File

@ -29,13 +29,13 @@ void pMenu::destructor() {
}
void pMenu::orphan() {
foreach(action, menu.state.action) action.p.orphan();
for(auto &action : menu.state.action) action.p.orphan();
destructor();
constructor();
foreach(action, menu.state.action) append(action);
for(auto &action : menu.state.action) append(action);
}
void pMenu::setFont(const string &font) {
pAction::setFont(font);
foreach(item, menu.state.action) item.p.setFont(font);
for(auto &item : menu.state.action) item.p.setFont(font);
}

View File

@ -1,5 +1,5 @@
static void RadioItem_tick(RadioItem *self) {
foreach(item, self->state.group) item.state.checked = (&item == self);
for(auto &item : self->state.group) item.state.checked = (&item == self);
if(self->p.locked == false && self->checked() && self->onTick) self->onTick();
}
@ -9,17 +9,17 @@ bool pRadioItem::checked() {
void pRadioItem::setChecked() {
locked = true;
foreach(item, radioItem.state.group) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item.p.widget), false);
for(auto &item : radioItem.state.group) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item.p.widget), false);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), true);
locked = false;
}
void pRadioItem::setGroup(const reference_array<RadioItem&> &group) {
foreach(item, group, n) {
for(unsigned n = 0; n < group.size(); n++) {
if(n == 0) continue;
GSList *currentGroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(group[0].p.widget));
if(currentGroup != gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item.p.widget))) {
gtk_radio_menu_item_set_group(GTK_RADIO_MENU_ITEM(item.p.widget), currentGroup);
if(currentGroup != gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(group[n].p.widget))) {
gtk_radio_menu_item_set_group(GTK_RADIO_MENU_ITEM(group[n].p.widget), currentGroup);
}
}
}
@ -31,7 +31,7 @@ void pRadioItem::setText(const string &text) {
void pRadioItem::constructor() {
widget = gtk_radio_menu_item_new_with_label(0, radioItem.state.text);
setGroup(radioItem.state.group);
foreach(item, radioItem.state.group, n) {
for(auto &item : radioItem.state.group) {
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item.p.widget), item.state.checked);
}
g_signal_connect_swapped(G_OBJECT(widget), "toggled", G_CALLBACK(RadioItem_tick), (gpointer)&radioItem);

View File

@ -8,7 +8,7 @@ Geometry pFont::geometry(const string &description, const string &text) {
PangoFontDescription* pFont::create(const string &description) {
lstring part;
part.split(",", description);
foreach(item, part) item.trim(" ");
for(auto &item : part) item.trim(" ");
string family = part[0];
unsigned size = decimal(part[1]);

View File

@ -81,7 +81,7 @@ static string pOS_fileDialog(bool save, Window &parent, const string &path, cons
if(path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
foreach(filterItem, filter) {
for(auto &filterItem : filter) {
GtkFileFilter *gtkFilter = gtk_file_filter_new();
gtk_file_filter_set_name(gtkFilter, filterItem);
lstring part;
@ -89,7 +89,7 @@ static string pOS_fileDialog(bool save, Window &parent, const string &path, cons
part[1].rtrim<1>(")");
lstring list;
list.split(",", part[1]);
foreach(pattern, list) gtk_file_filter_add_pattern(gtkFilter, pattern);
for(auto &pattern : list) gtk_file_filter_add_pattern(gtkFilter, pattern);
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), gtkFilter);
}
@ -150,12 +150,14 @@ void pOS::processEvents() {
}
void pOS::quit() {
settings.save();
settings->save();
gtk_main_quit();
}
void pOS::initialize() {
settings.load();
settings = new Settings;
settings->load();
int argc = 1;
char *argv[2];

View File

@ -1,4 +1,4 @@
static Settings settings;
static Settings *settings = nullptr;
void Settings::load() {
string path = { userpath(), ".config/phoenix/gtk.cfg" };

View File

@ -12,7 +12,7 @@ void pComboBox::append(const string &text) {
Geometry pComboBox::minimumGeometry() {
unsigned maximumWidth = 0;
foreach(item, comboBox.state.text) maximumWidth = max(maximumWidth, pFont::geometry(widget.state.font, item).width);
for(auto &item : comboBox.state.text) maximumWidth = max(maximumWidth, pFont::geometry(widget.state.font, item).width);
Geometry geometry = pFont::geometry(widget.state.font, " ");
return { 0, 0, maximumWidth + 44, geometry.height + 12 };
@ -41,7 +41,7 @@ void pComboBox::constructor() {
g_signal_connect_swapped(G_OBJECT(gtkWidget), "changed", G_CALLBACK(ComboBox_change), (gpointer)&comboBox);
locked = true;
foreach(text, comboBox.state.text) append(text);
for(auto &text : comboBox.state.text) append(text);
locked = false;
setSelection(comboBox.state.selection);
}

View File

@ -19,7 +19,7 @@ static void ListView_tick(GtkCellRendererToggle *cell, gchar *path_string, ListV
void pListView::append(const lstring &text) {
GtkTreeIter iter;
gtk_list_store_append(store, &iter);
foreach(item, text, n) gtk_list_store_set(store, &iter, 1 + n, (const char*)item, -1);
for(unsigned n = 0; n < text.size(); n++) gtk_list_store_set(store, &iter, 1 + n, (const char*)text[n], -1);
}
void pListView::autoSizeColumns() {
@ -44,7 +44,7 @@ void pListView::modify(unsigned row, const lstring &text) {
if(i == 0) gtk_tree_model_get_iter_first(model, &iter);
else gtk_tree_model_iter_next(model, &iter);
}
foreach(item, text, n) gtk_list_store_set(store, &iter, 1 + n, (const char*)item, -1);
for(unsigned n = 0; n < text.size(); n++) gtk_list_store_set(store, &iter, 1 + n, (const char*)text[n], -1);
}
void pListView::reset() {
@ -148,11 +148,11 @@ void pListView::constructor() {
lstring headerText;
headerText.append(""); //checkbox column
foreach(headerItem, listView.state.headerText) headerText.append(headerItem);
for(auto &headerItem : listView.state.headerText) headerText.append(headerItem);
if(headerText.size() == 1) headerText.append("");
GType *v = (GType*)malloc(headerText.size() * sizeof(GType));
foreach(header, headerText, n) v[n] = (n == 0 ? G_TYPE_BOOLEAN : G_TYPE_STRING);
for(unsigned n = 0; n < headerText.size(); n++) v[n] = (n == 0 ? G_TYPE_BOOLEAN : G_TYPE_STRING);
store = gtk_list_store_newv(headerText.size(), v);
free(v);
@ -160,7 +160,7 @@ void pListView::constructor() {
gtk_container_add(GTK_CONTAINER(gtkWidget), subWidget);
g_object_unref(G_OBJECT(store));
foreach(header, headerText, n) {
for(unsigned n = 0; n < headerText.size(); n++) {
if(n == 0) {
column[n].renderer = gtk_cell_renderer_toggle_new();
column[n].column = gtk_tree_view_column_new_with_attributes("", column[n].renderer, "active", n, (void*)0);
@ -172,7 +172,7 @@ void pListView::constructor() {
column[n].column = gtk_tree_view_column_new_with_attributes("", column[n].renderer, "text", n, (void*)0);
gtk_tree_view_column_set_resizable(column[n].column, true);
}
column[n].label = gtk_label_new(header);
column[n].label = gtk_label_new(headerText[n]);
gtk_tree_view_column_set_widget(GTK_TREE_VIEW_COLUMN(column[n].column), column[n].label);
gtk_tree_view_append_column(GTK_TREE_VIEW(subWidget), column[n].column);
gtk_widget_show(column[n].label);
@ -188,8 +188,8 @@ void pListView::constructor() {
setHeaderVisible(listView.state.headerVisible);
setCheckable(listView.state.checkable);
foreach(text, listView.state.text) append(text);
foreach(checked, listView.state.checked, n) setChecked(n, checked);
for(auto &text : listView.state.text) append(text);
for(unsigned n = 0; n < listView.state.checked.size(); n++) setChecked(n, listView.state.checked[n]);
if(listView.state.selected) setSelection(listView.state.selection);
autoSizeColumns();
}

View File

@ -20,7 +20,7 @@ void pRadioBox::setChecked() {
}
void pRadioBox::setGroup(const reference_array<RadioBox&> &group) {
foreach(item, group, n) {
for(unsigned n = 0; n < group.size(); n++) {
if(n == 0) continue;
GSList *currentGroup = gtk_radio_button_get_group(GTK_RADIO_BUTTON(group[0].p.gtkWidget));
if(currentGroup != gtk_radio_button_get_group(GTK_RADIO_BUTTON(gtkWidget))) {

View File

@ -38,10 +38,10 @@ static gboolean Window_configure(GtkWidget *widget, GdkEvent *event, Window *win
if(window->state.fullScreen == false) {
//update geometry settings
settings.frameGeometryX = client.x - border.x;
settings.frameGeometryY = client.y - border.y;
settings.frameGeometryWidth = border.width - client.width;
settings.frameGeometryHeight = border.height - client.height;
settings->frameGeometryX = client.x - border.x;
settings->frameGeometryY = client.y - border.y;
settings->frameGeometryWidth = border.width - client.width;
settings->frameGeometryHeight = border.height - client.height;
}
//move
@ -64,7 +64,7 @@ static gboolean Window_configure(GtkWidget *widget, GdkEvent *event, Window *win
window->state.geometry.height = client.height - window->p.menuHeight() - window->p.statusHeight();
}
foreach(layout, window->state.layout) {
for(auto &layout : window->state.layout) {
Geometry geometry = window->geometry();
geometry.x = geometry.y = 0;
layout.setGeometry(geometry);
@ -107,10 +107,10 @@ Color pWindow::backgroundColor() {
Geometry pWindow::frameMargin() {
if(window.state.fullScreen) return { 0, menuHeight(), 0, menuHeight() + statusHeight() };
return {
settings.frameGeometryX,
settings.frameGeometryY + menuHeight(),
settings.frameGeometryWidth,
settings.frameGeometryHeight + menuHeight() + statusHeight()
settings->frameGeometryX,
settings->frameGeometryY + menuHeight(),
settings->frameGeometryWidth,
settings->frameGeometryHeight + menuHeight() + statusHeight()
};
}
@ -183,7 +183,7 @@ void pWindow::setGeometry(const Geometry &geometry) {
gtk_widget_set_size_request(formContainer, geometry.width, geometry.height);
gtk_window_resize(GTK_WINDOW(widget), geometry.width + margin.width, geometry.height + margin.height);
foreach(layout, window.state.layout) {
for(auto &layout : window.state.layout) {
Geometry geometry = this->geometry();
geometry.x = geometry.y = 0;
layout.setGeometry(geometry);
@ -191,7 +191,7 @@ void pWindow::setGeometry(const Geometry &geometry) {
}
void pWindow::setMenuFont(const string &font) {
foreach(item, window.state.menu) item.p.setFont(font);
for(auto &item : window.state.menu) item.p.setFont(font);
}
void pWindow::setMenuVisible(bool visible) {
@ -225,7 +225,7 @@ void pWindow::setVisible(bool visible) {
}
void pWindow::setWidgetFont(const string &font) {
foreach(item, window.state.widget) {
for(auto &item : window.state.widget) {
if(item.state.font == "") item.setFont(font);
}
}
@ -273,9 +273,9 @@ void pWindow::constructor() {
}
unsigned pWindow::menuHeight() {
return window.state.menuVisible ? settings.menuGeometryHeight : 0;
return window.state.menuVisible ? settings->menuGeometryHeight : 0;
}
unsigned pWindow::statusHeight() {
return window.state.statusVisible ? settings.statusGeometryHeight : 0;
return window.state.statusVisible ? settings->statusGeometryHeight : 0;
}

View File

@ -3,7 +3,6 @@
#include <nall/array.hpp>
#include <nall/config.hpp>
#include <nall/foreach.hpp>
#include <nall/function.hpp>
#include <nall/reference_array.hpp>
#include <nall/stdint.hpp>

View File

@ -16,7 +16,7 @@ void pMenu::remove(Action &action) {
if(dynamic_cast<Menu*>(&action)) {
//QMenu::removeMenu() does not exist
qtMenu->clear();
foreach(action, menu.state.action) append(action);
for(auto &action : menu.state.action) append(action);
} else if(dynamic_cast<Separator*>(&action)) {
qtMenu->removeAction(((Separator&)action).p.qtAction);
} else if(dynamic_cast<Item*>(&action)) {
@ -30,7 +30,7 @@ void pMenu::remove(Action &action) {
void pMenu::setFont(const string &font) {
qtMenu->setFont(pFont::create(font));
foreach(item, menu.state.action) item.p.setFont(font);
for(auto &item : menu.state.action) item.p.setFont(font);
}
void pMenu::setText(const string &text) {

View File

@ -4,7 +4,7 @@ bool pRadioItem::checked() {
void pRadioItem::setChecked() {
locked = true;
foreach(item, radioItem.state.group) {
for(auto &item : radioItem.state.group) {
bool checkState = item.p.qtAction == qtAction;
item.state.checked = checkState;
item.p.qtAction->setChecked(checkState);

View File

@ -5,7 +5,7 @@ Geometry pFont::geometry(const string &description, const string &text) {
QFont pFont::create(const string &description) {
lstring part;
part.split(",", description);
foreach(item, part) item.trim(" ");
for(auto &item : part) item.trim(" ");
string name = part[0] != "" ? part[0] : "Sans";
unsigned size = part.size() >= 2 ? decimal(part[1]) : 8u;
@ -27,7 +27,7 @@ Geometry pFont::geometry(const QFont &qtFont, const string &text) {
lines.split("\n", text);
unsigned maxWidth = 0;
foreach(line, lines) {
for(auto &line : lines) {
maxWidth = max(maxWidth, metrics.width(line));
}

View File

@ -44,7 +44,7 @@ Geometry pOS::desktopGeometry() {
string pOS::fileLoad(Window &parent, const string &path, const lstring &filter) {
string filterList;
foreach(item, filter) {
for(auto &item : filter) {
filterList.append(item);
filterList.append(";;");
}
@ -53,7 +53,7 @@ string pOS::fileLoad(Window &parent, const string &path, const lstring &filter)
//convert filter list from phoenix to Qt format, example:
//"Text, XML files (*.txt,*.xml)" -> "Text, XML files (*.txt *.xml)"
signed parenthesis = 0;
foreach(n, filterList) {
for(auto &n : filterList) {
if(n == '(') parenthesis++;
if(n == ')') parenthesis--;
if(n == ',' && parenthesis) n = ' ';
@ -68,7 +68,7 @@ string pOS::fileLoad(Window &parent, const string &path, const lstring &filter)
string pOS::fileSave(Window &parent, const string &path, const lstring &filter) {
string filterList;
foreach(item, filter) {
for(auto &item : filter) {
filterList.append(item);
filterList.append(";;");
}
@ -77,7 +77,7 @@ string pOS::fileSave(Window &parent, const string &path, const lstring &filter)
//convert filter list from phoenix to Qt format, example:
//"Text, XML files (*.txt,*.xml)" -> "Text, XML files (*.txt *.xml)"
signed parenthesis = 0;
foreach(n, filterList) {
for(auto &n : filterList) {
if(n == '(') parenthesis++;
if(n == ')') parenthesis--;
if(n == ',' && parenthesis) n = ' ';
@ -113,14 +113,16 @@ void pOS::processEvents() {
}
void pOS::quit() {
settings.save();
settings->save();
QApplication::quit();
//note: QApplication cannot be deleted; or libQtGui will crash
qtApplication = 0;
}
void pOS::initialize() {
settings.load();
settings = new Settings;
settings->load();
static int argc = 1;
static char *argv[2];

View File

@ -1,7 +1,7 @@
/****************************************************************************
** Meta object code from reading C++ file 'platform.moc.hpp'
**
** Created: Mon Sep 19 18:14:48 2011
** Created: Tue Sep 27 01:00:52 2011
** by: The Qt Meta Object Compiler version 62 (Qt 4.7.0)
**
** WARNING! All changes made in this file will be lost!

View File

@ -5,6 +5,8 @@ struct Settings : public configuration {
unsigned frameGeometryY;
unsigned frameGeometryWidth;
unsigned frameGeometryHeight;
unsigned menuGeometryHeight;
unsigned statusGeometryHeight;
void load();
void save();

View File

@ -1,4 +1,4 @@
static Settings settings;
static Settings *settings = nullptr;
void Settings::load() {
string path = { userpath(), ".config/phoenix/qt.cfg" };
@ -15,8 +15,10 @@ void Settings::save() {
}
Settings::Settings() {
attach(frameGeometryX = 0, "frameGeometryX");
attach(frameGeometryY = 0, "frameGeometryY");
attach(frameGeometryWidth = 0, "frameGeometryWidth");
attach(frameGeometryHeight = 0, "frameGeometryHeight");
attach(frameGeometryX = 4, "frameGeometryX");
attach(frameGeometryY = 24, "frameGeometryY");
attach(frameGeometryWidth = 8, "frameGeometryWidth");
attach(frameGeometryHeight = 28, "frameGeometryHeight");
attach(menuGeometryHeight = 20, "menuGeometryHeight");
attach(statusGeometryHeight = 20, "statusGeometryHeight");
}

View File

@ -6,7 +6,7 @@ void pComboBox::append(const string &text) {
Geometry pComboBox::minimumGeometry() {
unsigned maximumWidth = 0;
foreach(text, comboBox.state.text) maximumWidth = max(maximumWidth, pFont::geometry(qtWidget->font(), text).width);
for(auto &text : comboBox.state.text) maximumWidth = max(maximumWidth, pFont::geometry(qtWidget->font(), text).width);
Geometry geometry = pFont::geometry(qtWidget->font(), " ");
return { 0, 0, maximumWidth + 32, geometry.height + 12 };
}
@ -35,7 +35,7 @@ void pComboBox::constructor() {
pWidget::synchronizeState();
unsigned selection = comboBox.state.selection;
locked = true;
foreach(text, comboBox.state.text) append(text);
for(auto &text : comboBox.state.text) append(text);
locked = false;
setSelection(selection);
}

View File

@ -60,7 +60,7 @@ void pListView::setChecked(unsigned row, bool checked) {
void pListView::setHeaderText(const lstring &text) {
QStringList labels;
foreach(column, text) labels << QString::fromUtf8(column);
for(auto &column : text) labels << QString::fromUtf8(column);
qtListView->setColumnCount(text.size());
qtListView->setAlternatingRowColors(text.size() >= 2);
@ -106,7 +106,7 @@ void pListView::constructor() {
setCheckable(listView.state.checkable);
setHeaderText(listView.state.headerText.size() ? listView.state.headerText : lstring{ " " });
setHeaderVisible(listView.state.headerVisible);
foreach(row, listView.state.text) append(row);
for(auto &row : listView.state.text) append(row);
if(listView.state.checkable) {
for(unsigned n = 0; n < listView.state.checked.size(); n++) {
setChecked(n, listView.state.checked[n]);

View File

@ -9,7 +9,7 @@ Geometry pRadioBox::minimumGeometry() {
void pRadioBox::setChecked() {
locked = true;
foreach(item, radioBox.state.group) {
for(auto &item : radioBox.state.group) {
bool checkState = item.p.qtRadioBox == qtRadioBox;
item.state.checked = checkState;
item.p.qtRadioBox->setChecked(checkState);
@ -25,7 +25,7 @@ void pRadioBox::setGroup(const reference_array<RadioBox&> &group) {
}
if(group.size() > 0 && qtRadioBox == group[0].p.qtRadioBox) {
qtGroup = new QButtonGroup;
foreach(item, group) qtGroup->addButton(item.p.qtRadioBox);
for(auto &item : group) qtGroup->addButton(item.p.qtRadioBox);
setChecked();
}
locked = false;

View File

@ -26,14 +26,14 @@ Color pWindow::backgroundColor() {
}
Geometry pWindow::frameMargin() {
unsigned menuHeight = window.state.menuVisible ? qtMenu->height() : 0;
unsigned statusHeight = window.state.statusVisible ? qtStatus->height() : 0;
unsigned menuHeight = window.state.menuVisible ? settings->menuGeometryHeight : 0;
unsigned statusHeight = window.state.statusVisible ? settings->statusGeometryHeight : 0;
if(window.state.fullScreen) return { 0, menuHeight, 0, menuHeight + statusHeight };
return {
settings.frameGeometryX,
settings.frameGeometryY + menuHeight,
settings.frameGeometryWidth,
settings.frameGeometryHeight + menuHeight + statusHeight
settings->frameGeometryX,
settings->frameGeometryY + menuHeight,
settings->frameGeometryWidth,
settings->frameGeometryHeight + menuHeight + statusHeight
};
}
@ -56,7 +56,7 @@ void pWindow::remove(Layout &layout) {
void pWindow::remove(Menu &menu) {
//QMenuBar::removeMenu() does not exist
qtMenu->clear();
foreach(menu, window.state.menu) append(menu);
for(auto &menu : window.state.menu) append(menu);
}
void pWindow::remove(Widget &widget) {
@ -95,12 +95,13 @@ void pWindow::setGeometry(const Geometry &geometry_) {
Geometry geometry = geometry_, margin = frameMargin();
setResizable(window.state.resizable);
qtWindow->move(geometry.x - margin.x, geometry.y - margin.y);
qtWindow->adjustSize();
qtWindow->setMinimumSize(1u, 1u);
qtContainer->setMinimumSize(1u, 1u);
qtWindow->move(geometry.x, geometry.y);
//qtWindow->adjustSize() fails if larger than 2/3rds screen size
qtWindow->resize(qtWindow->sizeHint());
qtWindow->setMinimumSize(1, 1);
qtContainer->setMinimumSize(1, 1);
foreach(layout, window.state.layout) {
for(auto &layout : window.state.layout) {
geometry = geometry_;
geometry.x = geometry.y = 0;
layout.setGeometry(geometry);
@ -110,7 +111,7 @@ void pWindow::setGeometry(const Geometry &geometry_) {
void pWindow::setMenuFont(const string &font) {
qtMenu->setFont(pFont::create(font));
foreach(item, window.state.menu) item.p.setFont(font);
for(auto &item : window.state.menu) item.p.setFont(font);
}
void pWindow::setMenuVisible(bool visible) {
@ -157,7 +158,7 @@ void pWindow::setVisible(bool visible) {
}
void pWindow::setWidgetFont(const string &font) {
foreach(item, window.state.widget) {
for(auto &item : window.state.widget) {
if(!item.state.font) item.setFont(font);
}
}
@ -204,13 +205,24 @@ void pWindow::updateFrameGeometry() {
usleep(100);
QApplication::processEvents();
}
QRect border = qtWindow->frameGeometry();
QRect client = qtWindow->geometry();
settings.frameGeometryX = client.x() - border.x();
settings.frameGeometryY = client.y() - border.y();
settings.frameGeometryWidth = border.width() - client.width();
settings.frameGeometryHeight = border.height() - client.height();
settings->frameGeometryX = client.x() - border.x();
settings->frameGeometryY = client.y() - border.y();
settings->frameGeometryWidth = border.width() - client.width();
settings->frameGeometryHeight = border.height() - client.height();
if(window.state.menuVisible) {
for(unsigned n = 0; n < 10; n++) { usleep(100); QApplication::processEvents(); }
settings->menuGeometryHeight = qtMenu->height();
}
if(window.state.statusVisible) {
for(unsigned n = 0; n < 10; n++) { usleep(100); QApplication::processEvents(); }
settings->statusGeometryHeight = qtStatus->height();
}
}
void pWindow::QtWindow::closeEvent(QCloseEvent *event) {
@ -237,7 +249,7 @@ void pWindow::QtWindow::resizeEvent(QResizeEvent*) {
self.window.state.geometry.height = self.qtContainer->geometry().height();
}
foreach(layout, self.window.state.layout) {
for(auto &layout : self.window.state.layout) {
Geometry geometry = self.geometry();
geometry.x = geometry.y = 0;
layout.setGeometry(geometry);
@ -251,7 +263,7 @@ void pWindow::QtWindow::resizeEvent(QResizeEvent*) {
QSize pWindow::QtWindow::sizeHint() const {
unsigned width = self.window.state.geometry.width;
unsigned height = self.window.state.geometry.height;
if(self.window.state.menuVisible) height += self.qtMenu->height();
if(self.window.state.statusVisible) height += self.qtStatus->height();
if(self.window.state.menuVisible) height += settings->menuGeometryHeight;
if(self.window.state.statusVisible) height += settings->statusGeometryHeight;
return QSize(width, height);
}

View File

@ -25,7 +25,7 @@ void pMenu::update(Window &parentWindow, Menu *parentMenu) {
if(hmenu) DestroyMenu(hmenu);
hmenu = CreatePopupMenu();
foreach(action, menu.state.action) {
for(auto &action : menu.state.action) {
action.p.parentMenu = &menu;
action.p.parentWindow = &parentWindow;

View File

@ -3,7 +3,7 @@ bool pRadioItem::checked() {
}
void pRadioItem::setChecked() {
foreach(item, radioItem.state.group) {
for(auto &item : radioItem.state.group) {
//CheckMenuRadioItem takes: lo, hi, id; checking only id when lo <= id <= hi
//phoenix does not force IDs to be linear, so to uncheck id, we use: lo == hi == id + 1 (out of range)
//to check id, we use: lo == hi == id (only ID, but in range)

View File

@ -8,7 +8,7 @@ Geometry pFont::geometry(const string &description, const string &text) {
HFONT pFont::create(const string &description) {
lstring part;
part.split(",", description);
foreach(item, part) item.trim(" ");
for(auto &item : part) item.trim(" ");
string family = part[0];
unsigned size = decimal(part[1]);

View File

@ -8,6 +8,6 @@ pObject::pObject(Object &object) : object(object) {
}
pObject* pObject::find(unsigned id) {
foreach(item, objects) if(item->id == id) return item;
for(auto &item : objects) if(item->id == id) return item;
return 0;
}

View File

@ -50,7 +50,7 @@ static string pOS_fileDialog(bool save, Window &parent, const string &path, cons
dir.replace("/", "\\");
string filterList;
foreach(filterItem, filter) {
for(auto &filterItem : filter) {
lstring part;
part.split("(", filterItem);
if(part.size() != 2) { print("--", filterItem, "\n"); continue; }
@ -284,7 +284,7 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
window.state.geometry.width = geometry.width;
window.state.geometry.height = geometry.height;
foreach(layout, window.state.layout) {
for(auto &layout : window.state.layout) {
Geometry geom = window.geometry();
geom.x = geom.y = 0;
layout.setGeometry(geom);

View File

@ -1,7 +1,7 @@
static linear_vector<pTimer*> timers;
static void CALLBACK Timer_timeoutProc(HWND hwnd, UINT msg, UINT_PTR timerID, DWORD time) {
foreach(timer, timers) {
for(auto &timer : timers) {
if(timer->htimer == timerID) {
if(timer->timer.onTimeout) timer->timer.onTimeout();
return;

View File

@ -5,7 +5,7 @@ void pComboBox::append(const string &text) {
Geometry pComboBox::minimumGeometry() {
unsigned maximumWidth = 0;
foreach(text, comboBox.state.text) maximumWidth = max(maximumWidth, pFont::geometry(hfont, text).width);
for(auto &text : comboBox.state.text) maximumWidth = max(maximumWidth, pFont::geometry(hfont, text).width);
return { 0, 0, maximumWidth + 24, pFont::geometry(hfont, " ").height + 10 };
}
@ -30,7 +30,7 @@ void pComboBox::constructor() {
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&comboBox);
setDefaultFont();
foreach(text, comboBox.state.text) append(text);
for(auto &text : comboBox.state.text) append(text);
setSelection(comboBox.state.selection);
synchronize();
}

View File

@ -9,8 +9,8 @@ void pListView::append(const lstring &list) {
locked = true;
ListView_InsertItem(hwnd, &item);
locked = false;
foreach(text, list, n) {
utf16_t wtext(text);
for(unsigned n = 0; n < list.size(); n++) {
utf16_t wtext(list[n]);
ListView_SetItemText(hwnd, row, n, wtext);
}
}
@ -26,8 +26,8 @@ bool pListView::checked(unsigned row) {
}
void pListView::modify(unsigned row, const lstring &list) {
foreach(text, list, n) {
utf16_t wtext(text);
for(unsigned n = 0; n < list.size(); n++) {
utf16_t wtext(list[n]);
ListView_SetItemText(hwnd, row, n, wtext);
}
}
@ -68,12 +68,12 @@ void pListView::setHeaderText(const lstring &list) {
lstring headers = list;
if(headers.size() == 0) headers.append(""); //must have at least one column
foreach(text, headers, n) {
for(unsigned n = 0; n < headers.size(); n++) {
LVCOLUMN column;
column.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM;
column.fmt = LVCFMT_LEFT;
column.iSubItem = n;
utf16_t headerText(text);
utf16_t headerText(headers[n]);
column.pszText = headerText;
ListView_InsertColumn(hwnd, n, &column);
}
@ -116,8 +116,8 @@ void pListView::constructor() {
setHeaderText(listView.state.headerText);
setHeaderVisible(listView.state.headerVisible);
setCheckable(listView.state.checkable);
foreach(text, listView.state.text) append(text);
foreach(checked, listView.state.checked, n) setChecked(n, checked);
for(auto &text : listView.state.text) append(text);
for(unsigned n = 0; n < listView.state.checked.size(); n++) setChecked(n, listView.state.checked[n]);
if(listView.state.selected) setSelection(listView.state.selection);
autoSizeColumns();
synchronize();

View File

@ -8,7 +8,7 @@ Geometry pRadioBox::minimumGeometry() {
}
void pRadioBox::setChecked() {
foreach(item, radioBox.state.group) {
for(auto &item : radioBox.state.group) {
SendMessage(item.p.hwnd, BM_SETCHECK, (WPARAM)(&item == &radioBox), 0);
}
}

View File

@ -110,7 +110,7 @@ void pWindow::setGeometry(const Geometry &geometry) {
SWP_NOZORDER | SWP_FRAMECHANGED
);
SetWindowPos(hstatus, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_FRAMECHANGED);
foreach(layout, window.state.layout) {
for(auto &layout : window.state.layout) {
Geometry geom = this->geometry();
geom.x = geom.y = 0;
layout.setGeometry(geom);
@ -159,7 +159,7 @@ void pWindow::setVisible(bool visible) {
}
void pWindow::setWidgetFont(const string &font) {
foreach(widget, window.state.widget) {
for(auto &widget : window.state.widget) {
if(widget.state.font == "") widget.setFont(font);
}
}
@ -191,7 +191,7 @@ void pWindow::updateMenu() {
if(hmenu) DestroyMenu(hmenu);
hmenu = CreateMenu();
foreach(menu, window.state.menu) {
for(auto &menu : window.state.menu) {
menu.p.update(window);
if(menu.visible()) {
AppendMenu(hmenu, MF_STRING | MF_POPUP, (UINT_PTR)menu.p.hmenu, utf16_t(menu.state.text));

View File

@ -145,7 +145,7 @@ bool VideoInterface::init() {
void VideoInterface::term() {
if(p) {
delete p;
p = 0;
p = nullptr;
}
}
@ -156,7 +156,7 @@ bool VideoInterface::lock(uint32_t *&data, unsigned &pitch, unsigned width, unsi
void VideoInterface::unlock() { if(p) p->unlock(); }
void VideoInterface::clear() { if(p) p->clear(); }
void VideoInterface::refresh() { if(p) p->refresh(); }
VideoInterface::VideoInterface() : p(0) {}
VideoInterface::VideoInterface() : p(nullptr) {}
VideoInterface::~VideoInterface() { term(); }
/* AudioInterface */
@ -282,7 +282,7 @@ bool AudioInterface::init() {
void AudioInterface::term() {
if(p) {
delete p;
p = 0;
p = nullptr;
}
}
@ -291,7 +291,7 @@ any AudioInterface::get(const string& name) { return p ? p->get(name) : false; }
bool AudioInterface::set(const string& name, const any& value) { return p ? p->set(name, value) : false; }
void AudioInterface::sample(uint16_t left, uint16_t right) { if(p) p->sample(left, right); }
void AudioInterface::clear() { if(p) p->clear(); }
AudioInterface::AudioInterface() : p(0) {}
AudioInterface::AudioInterface() : p(nullptr) {}
AudioInterface::~AudioInterface() { term(); }
/* InputInterface */
@ -388,7 +388,7 @@ bool InputInterface::init() {
void InputInterface::term() {
if(p) {
delete p;
p = 0;
p = nullptr;
}
}
@ -399,7 +399,7 @@ bool InputInterface::acquire() { return p ? p->acquire() : false; }
bool InputInterface::unacquire() { return p ? p->unacquire() : false; }
bool InputInterface::acquired() { return p ? p->acquired() : false; }
bool InputInterface::poll(int16_t *table) { return p ? p->poll(table) : false; }
InputInterface::InputInterface() : p(0) {}
InputInterface::InputInterface() : p(nullptr) {}
InputInterface::~InputInterface() { term(); }
};

View File

@ -344,12 +344,12 @@ public:
bool is_hlsl = false;
string shader_source;
xml_element document = xml_parse(shader_source_xml);
foreach(head, document.element) {
for(auto &head : document.element) {
if(head.name == "shader") {
foreach(attribute, head.attribute) {
for(auto &attribute : head.attribute) {
if(attribute.name == "language" && attribute.content == "HLSL") is_hlsl = true;
}
foreach(element, head.element) {
for(auto &element : head.element) {
if(element.name == "source") {
if(is_hlsl) shader_source = element.parse();
}

View File

@ -142,14 +142,14 @@ public:
string vertex_source;
xml_element document = xml_parse(source);
foreach(head, document.element) {
for(auto &head : document.element) {
if(head.name == "shader") {
foreach(attribute, head.attribute) {
for(auto &attribute : head.attribute) {
if(attribute.name == "language" && attribute.content == "GLSL") is_glsl = true;
}
foreach(element, head.element) {
for(auto &element : head.element) {
if(element.name == "fragment") {
foreach(attribute, element.attribute) {
for(auto &attribute : element.attribute) {
if(attribute.name == "filter") fragmentfilter = attribute.content == "linear" ? 1 : 0;
}
fragment_source = element.parse();

View File

@ -67,12 +67,14 @@ void CPU::enter() {
if(status.nmi_pending) {
status.nmi_pending = false;
op_irq(regs.e == false ? 0xffea : 0xfffa);
regs.vector = (regs.e == false ? 0xffea : 0xfffa);
op_irq();
}
if(status.irq_pending) {
status.irq_pending = false;
op_irq(regs.e == false ? 0xffee : 0xfffe);
regs.vector = (regs.e == false ? 0xffee : 0xfffe);
op_irq();
}
op_step();
@ -83,21 +85,6 @@ alwaysinline void CPU::op_step() {
(this->*opcode_table[op_readpc()])();
}
void CPU::op_irq(uint16 vector) {
op_read(regs.pc.d);
op_io();
if(!regs.e) op_writestack(regs.pc.b);
op_writestack(regs.pc.h);
op_writestack(regs.pc.l);
op_writestack(regs.e ? (regs.p & ~0x10) : regs.p);
rd.l = op_read(vector + 0);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
rd.h = op_read(vector + 1);
regs.pc.w = rd.w;
}
void CPU::enable() {
function<uint8 (unsigned)> read = { &CPU::mmio_read, (CPU*)&cpu };
function<void (unsigned, uint8)> write = { &CPU::mmio_write, (CPU*)&cpu };

View File

@ -35,7 +35,6 @@ private:
//cpu
static void Enter();
debugvirtual void op_step();
void op_irq(uint16 vector);
//timing
struct QueueEvent {

View File

@ -134,9 +134,9 @@ void PPU::power() {
ppu1_version = config.ppu1.version;
ppu2_version = config.ppu2.version;
foreach(n, vram) n = 0x00;
foreach(n, oam) n = 0x00;
foreach(n, cgram) n = 0x00;
for(auto &n : vram) n = 0x00;
for(auto &n : oam) n = 0x00;
for(auto &n : cgram) n = 0x00;
flush_tiledata_cache();
region = (system.region() == System::Region::NTSC ? 0 : 1); //0 = NTSC, 1 = PAL

View File

@ -95,9 +95,9 @@ void PPU::enable() {
}
void PPU::power() {
foreach(n, vram) n = 0;
foreach(n, oam) n = 0;
foreach(n, cgram) n = 0;
for(auto &n : vram) n = 0;
for(auto &n : oam) n = 0;
for(auto &n : cgram) n = 0;
reset();
}

View File

@ -17,15 +17,13 @@ void Audio::coprocessor_frequency(double input_frequency) {
dspaudio.setResamplerFrequency(system.apu_frequency() / 768.0);
}
void Audio::sample(int16 left, int16 right) {
if(coprocessor == false) {
interface->audioSample(left, right);
} else {
dsp_buffer[dsp_wroffset] = ((uint16)left << 0) + ((uint16)right << 16);
dsp_wroffset = (dsp_wroffset + 1) & buffer_mask;
dsp_length = (dsp_length + 1) & buffer_mask;
flush();
}
void Audio::sample(int16 lsample, int16 rsample) {
if(coprocessor == false) return interface->audioSample(lsample, rsample);
dsp_buffer[dsp_wroffset] = ((uint16)lsample << 0) + ((uint16)rsample << 16);
dsp_wroffset = (dsp_wroffset + 1) & buffer_mask;
dsp_length = (dsp_length + 1) & buffer_mask;
flush();
}
void Audio::coprocessor_sample(int16 lsample, int16 rsample) {
@ -55,11 +53,11 @@ void Audio::flush() {
dsp_length--;
cop_length--;
int dsp_left = (int16)(dsp_sample >> 0);
int dsp_right = (int16)(dsp_sample >> 16);
signed dsp_left = (int16)(dsp_sample >> 0);
signed dsp_right = (int16)(dsp_sample >> 16);
int cop_left = (int16)(cop_sample >> 0);
int cop_right = (int16)(cop_sample >> 16);
signed cop_left = (int16)(cop_sample >> 0);
signed cop_right = (int16)(cop_sample >> 16);
interface->audioSample(
sclamp<16>((dsp_left + cop_left ) / 2),

View File

@ -1,14 +1,13 @@
class Audio {
public:
struct Audio {
void coprocessor_enable(bool state);
void coprocessor_frequency(double frequency);
void sample(int16 left, int16 right);
void coprocessor_sample(int16 left, int16 right);
void sample(int16 lsample, int16 rsample);
void coprocessor_sample(int16 lsample, int16 rsample);
void init();
private:
bool coprocessor;
nall::DSP dspaudio;
bool coprocessor;
enum : unsigned { buffer_size = 256, buffer_mask = buffer_size - 1 };
uint32 dsp_buffer[buffer_size], cop_buffer[buffer_size];
unsigned dsp_rdoffset, cop_rdoffset;

View File

@ -45,17 +45,7 @@ void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) {
ram.write_protect(false);
crc32 = crc32_calculate(rom.data(), rom.size());
sha256_ctx sha;
uint8_t shahash[32];
sha256_init(&sha);
sha256_chunk(&sha, rom.data(), rom.size());
sha256_final(&sha);
sha256_hash(&sha, shahash);
string hash;
foreach(n, shahash) hash.append(hex<2>(n));
sha256 = hash;
sha256 = nall::sha256(rom.data(), rom.size());
system.load();
loaded = true;

View File

@ -1,5 +1,4 @@
class Cartridge : property<Cartridge> {
public:
struct Cartridge : property<Cartridge> {
enum class Mode : unsigned {
Normal,
BsxSlotted,

View File

@ -1,7 +1,9 @@
#ifdef CARTRIDGE_CPP
void Cartridge::serialize(serializer &s) {
if(ram.data()) s.array(ram.data(), ram.size());
for(auto &ram : nvram) {
if(ram.size) s.array(ram.data, ram.size);
}
}
#endif

View File

@ -23,16 +23,16 @@ void Cartridge::parse_xml_cartridge(const char *data) {
xml_element document = xml_parse(data);
if(document.element.size() == 0) return;
foreach(head, document.element) {
for(auto &head : document.element) {
if(head.name == "cartridge") {
foreach(attr, head.attribute) {
for(auto &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) {
for(auto &node : head.element) {
if(node.name == "rom") xml_parse_rom(node);
if(node.name == "ram") xml_parse_ram(node);
if(node.name == "nss") xml_parse_nss(node);
@ -66,10 +66,10 @@ void Cartridge::parse_xml_gameboy(const char *data) {
}
void Cartridge::xml_parse_rom(xml_element &root) {
foreach(leaf, root.element) {
for(auto &leaf : root.element) {
if(leaf.name == "map") {
Mapping m(rom);
foreach(attr, leaf.attribute) {
for(auto &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 = xml_parse_hex(attr.content);
@ -82,14 +82,14 @@ void Cartridge::xml_parse_rom(xml_element &root) {
}
void Cartridge::xml_parse_ram(xml_element &root) {
foreach(attr, root.attribute) {
for(auto &attr : root.attribute) {
if(attr.name == "size") ram_size = xml_parse_hex(attr.content);
}
foreach(leaf, root.element) {
for(auto &leaf : root.element) {
if(leaf.name == "map") {
Mapping m(ram);
foreach(attr, leaf.attribute) {
for(auto &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 = xml_parse_hex(attr.content);
@ -104,21 +104,21 @@ void Cartridge::xml_parse_ram(xml_element &root) {
void Cartridge::xml_parse_nss(xml_element &root) {
has_nss_dip = true;
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "setting") {
unsigned number = information.nss.setting.size();
if(number >= 16) break; //more than 16 DIP switches is not possible
information.nss.option[number].reset();
foreach(attr, node.attribute) {
for(auto &attr : node.attribute) {
if(attr.name == "name") {
information.nss.setting[number] = attr.parse();
}
}
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
string name;
unsigned value = 0x0000;
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "name") name = attr.parse();
if(attr.name == "value") value = (uint16)xml_parse_hex(attr.content);
}
@ -132,17 +132,17 @@ void Cartridge::xml_parse_icd2(xml_element &root) {
if(mode != Mode::SuperGameBoy) return;
icd2.revision = 1;
foreach(attr, root.attribute) {
for(auto &attr : root.attribute) {
if(attr.name == "revision") {
if(attr.content == "1") icd2.revision = 1;
if(attr.content == "2") icd2.revision = 2;
}
}
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "map") {
Mapping m({ &ICD2::read, &icd2 }, { &ICD2::write, &icd2 });
foreach(attr, node.attribute) {
for(auto &attr : node.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -153,12 +153,12 @@ void Cartridge::xml_parse_icd2(xml_element &root) {
void Cartridge::xml_parse_superfx(xml_element &root) {
has_superfx = true;
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "rom") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m(superfx.rom);
foreach(attr, leaf.attribute) {
for(auto &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 = xml_parse_hex(attr.content);
@ -168,14 +168,14 @@ void Cartridge::xml_parse_superfx(xml_element &root) {
}
}
} else if(node.name == "ram") {
foreach(attr, node.attribute) {
for(auto &attr : node.attribute) {
if(attr.name == "size") ram_size = xml_parse_hex(attr.content);
}
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m(superfx.ram);
foreach(attr, leaf.attribute) {
for(auto &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 = xml_parse_hex(attr.content);
@ -186,10 +186,10 @@ void Cartridge::xml_parse_superfx(xml_element &root) {
}
}
} else if(node.name == "mmio") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &SuperFX::mmio_read, &superfx }, { &SuperFX::mmio_write, &superfx });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -202,14 +202,14 @@ void Cartridge::xml_parse_superfx(xml_element &root) {
void Cartridge::xml_parse_sa1(xml_element &root) {
has_sa1 = true;
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "mcu") {
foreach(subnode, node.element) {
for(auto &subnode : node.element) {
if(subnode.name == "rom") {
foreach(leaf, subnode.element) {
for(auto &leaf : subnode.element) {
if(leaf.name == "map") {
Mapping m({ &SA1::mmc_read, &sa1 }, { &SA1::mmc_write, &sa1 });
foreach(attr, leaf.attribute) {
for(auto &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 = xml_parse_hex(attr.content);
@ -219,10 +219,10 @@ void Cartridge::xml_parse_sa1(xml_element &root) {
}
}
} else if(subnode.name == "ram") {
foreach(leaf, subnode.element) {
for(auto &leaf : subnode.element) {
if(leaf.name == "map") {
Mapping m({ &SA1::mmc_cpu_read, &sa1 }, { &SA1::mmc_cpu_write, &sa1 });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -231,10 +231,10 @@ void Cartridge::xml_parse_sa1(xml_element &root) {
}
}
} else if(node.name == "iram") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m(sa1.cpuiram);
foreach(attr, leaf.attribute) {
for(auto &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 = xml_parse_hex(attr.content);
@ -245,14 +245,14 @@ void Cartridge::xml_parse_sa1(xml_element &root) {
}
}
} else if(node.name == "bwram") {
foreach(attr, node.attribute) {
for(auto &attr : node.attribute) {
if(attr.name == "size") ram_size = xml_parse_hex(attr.content);
}
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m(sa1.cpubwram);
foreach(attr, leaf.attribute) {
for(auto &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 = xml_parse_hex(attr.content);
@ -263,10 +263,10 @@ void Cartridge::xml_parse_sa1(xml_element &root) {
}
}
} else if(node.name == "mmio") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &SA1::mmio_read, &sa1 }, { &SA1::mmio_write, &sa1 });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -286,7 +286,7 @@ void Cartridge::xml_parse_necdsp(xml_element &root) {
string firmware, sha256;
foreach(attr, root.attribute) {
for(auto &attr : root.attribute) {
if(attr.name == "model") {
if(attr.content == "uPD7725" ) necdsp.revision = NECDSP::Revision::uPD7725;
if(attr.content == "uPD96050") necdsp.revision = NECDSP::Revision::uPD96050;
@ -328,32 +328,32 @@ void Cartridge::xml_parse_necdsp(xml_element &root) {
fp.close();
}
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "dr") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &NECDSP::dr_read, &necdsp }, { &NECDSP::dr_write, &necdsp });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
}
}
} else if(node.name == "sr") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &NECDSP::sr_read, &necdsp }, { &NECDSP::sr_write, &necdsp });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
}
}
} else if(node.name == "dp") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &NECDSP::dp_read, &necdsp }, { &NECDSP::dp_write, &necdsp });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -371,7 +371,7 @@ void Cartridge::xml_parse_hitachidsp(xml_element &root) {
string firmware, sha256;
foreach(attr, root.attribute) {
for(auto &attr : root.attribute) {
if(attr.name == "frequency") {
hitachidsp.frequency = xml_parse_unsigned(attr.content);
} else if(attr.name == "firmware") {
@ -405,12 +405,12 @@ void Cartridge::xml_parse_hitachidsp(xml_element &root) {
fp.close();
}
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "rom") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &HitachiDSP::rom_read, &hitachidsp }, { &HitachiDSP::rom_write, &hitachidsp });
foreach(attr, leaf.attribute) {
for(auto &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 = xml_parse_hex(attr.content);
@ -421,9 +421,9 @@ void Cartridge::xml_parse_hitachidsp(xml_element &root) {
}
}
if(node.name == "mmio") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
Mapping m({ &HitachiDSP::dsp_read, &hitachidsp }, { &HitachiDSP::dsp_write, &hitachidsp });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -435,12 +435,12 @@ void Cartridge::xml_parse_hitachidsp(xml_element &root) {
void Cartridge::xml_parse_bsx(xml_element &root) {
if(mode != Mode::BsxSlotted && mode != Mode::Bsx) return;
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "slot") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m(bsxflash.memory);
foreach(attr, leaf.attribute) {
for(auto &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 = xml_parse_hex(attr.content);
@ -450,20 +450,20 @@ void Cartridge::xml_parse_bsx(xml_element &root) {
}
}
} else if(node.name == "mcu") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &BSXCartridge::mcu_read, &bsxcartridge }, { &BSXCartridge::mcu_write, &bsxcartridge });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
}
}
} else if(node.name == "mmio") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &BSXCartridge::mmio_read, &bsxcartridge }, { &BSXCartridge::mmio_write, &bsxcartridge });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -476,23 +476,23 @@ void Cartridge::xml_parse_bsx(xml_element &root) {
void Cartridge::xml_parse_sufamiturbo(xml_element &root) {
if(mode != Mode::SufamiTurbo) return;
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "slot") {
bool slotid = 0;
foreach(attr, node.attribute) {
for(auto &attr : node.attribute) {
if(attr.name == "id") {
if(attr.content == "A") slotid = 0;
if(attr.content == "B") slotid = 1;
}
}
foreach(slot, node.element) {
for(auto &slot : node.element) {
if(slot.name == "rom") {
foreach(leaf, slot.element) {
for(auto &leaf : slot.element) {
if(leaf.name == "map") {
Memory &memory = slotid == 0 ? sufamiturbo.slotA.rom : sufamiturbo.slotB.rom;
Mapping m(memory);
foreach(attr, leaf.attribute) {
for(auto &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 = xml_parse_hex(attr.content);
@ -505,15 +505,15 @@ void Cartridge::xml_parse_sufamiturbo(xml_element &root) {
} else if(slot.name == "ram") {
unsigned ram_size = 0;
foreach(attr, slot.attribute) {
for(auto &attr : slot.attribute) {
if(attr.name == "size") ram_size = xml_parse_hex(attr.content);
}
foreach(leaf, slot.element) {
for(auto &leaf : slot.element) {
if(leaf.name == "map") {
Memory &memory = slotid == 0 ? sufamiturbo.slotA.ram : sufamiturbo.slotB.ram;
Mapping m(memory);
foreach(attr, leaf.attribute) {
for(auto &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 = xml_parse_hex(attr.content);
@ -532,10 +532,10 @@ void Cartridge::xml_parse_sufamiturbo(xml_element &root) {
void Cartridge::xml_parse_srtc(xml_element &root) {
has_srtc = true;
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "map") {
Mapping m({ &SRTC::read, &srtc }, { &SRTC::write, &srtc });
foreach(attr, node.attribute) {
for(auto &attr : node.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -546,22 +546,22 @@ void Cartridge::xml_parse_srtc(xml_element &root) {
void Cartridge::xml_parse_sdd1(xml_element &root) {
has_sdd1 = true;
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "mcu") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &SDD1::mcu_read, &sdd1 }, { &SDD1::mcu_write, &sdd1 });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
}
}
} else if(node.name == "mmio") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -575,22 +575,22 @@ void Cartridge::xml_parse_spc7110(xml_element &root) {
has_spc7110 = true;
spc7110.data_rom_offset = 0x100000;
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "dcu") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &SPC7110::dcu_read, &spc7110 }, { &SPC7110::dcu_write, &spc7110 });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
}
}
} else if(node.name == "mcu") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &SPC7110::mcu_read, &spc7110 }, { &SPC7110::mcu_write, &spc7110 });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
if(attr.name == "offset") spc7110.data_rom_offset = xml_parse_hex(attr.content);
}
@ -598,24 +598,24 @@ void Cartridge::xml_parse_spc7110(xml_element &root) {
}
}
} else if(node.name == "mmio") {
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &SPC7110::mmio_read, &spc7110 }, { &SPC7110::mmio_write, &spc7110 });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
}
}
} else if(node.name == "ram") {
foreach(attr, node.attribute) {
for(auto &attr : node.attribute) {
if(attr.name == "size") ram_size = xml_parse_hex(attr.content);
}
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &SPC7110::ram_read, &spc7110 }, { &SPC7110::ram_write, &spc7110 });
foreach(attr, leaf.attribute) {
for(auto &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 = xml_parse_hex(attr.content);
@ -627,10 +627,10 @@ void Cartridge::xml_parse_spc7110(xml_element &root) {
} else if(node.name == "rtc") {
has_spc7110rtc = true;
foreach(leaf, node.element) {
for(auto &leaf : node.element) {
if(leaf.name == "map") {
Mapping m({ &SPC7110::mmio_read, &spc7110 }, { &SPC7110::mmio_write, &spc7110 });
foreach(attr, leaf.attribute) {
for(auto &attr : leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -643,10 +643,10 @@ void Cartridge::xml_parse_spc7110(xml_element &root) {
void Cartridge::xml_parse_obc1(xml_element &root) {
has_obc1 = true;
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "map") {
Mapping m({ &OBC1::read, &obc1 }, { &OBC1::write, &obc1 });
foreach(attr, node.attribute) {
for(auto &attr : node.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -657,10 +657,10 @@ void Cartridge::xml_parse_obc1(xml_element &root) {
void Cartridge::xml_parse_setarisc(xml_element &root) {
has_st0018 = true;
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "map") {
Mapping m({ &ST0018::mmio_read, &st0018 }, { &ST0018::mmio_write, &st0018 });
foreach(attr, node.attribute) {
for(auto &attr : node.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -671,10 +671,10 @@ void Cartridge::xml_parse_setarisc(xml_element &root) {
void Cartridge::xml_parse_msu1(xml_element &root) {
has_msu1 = true;
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "map") {
Mapping m({ &MSU1::mmio_read, &msu1 }, { &MSU1::mmio_write, &msu1 });
foreach(attr, node.attribute) {
for(auto &attr : node.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);
@ -687,15 +687,15 @@ void Cartridge::xml_parse_link(xml_element &root) {
link.frequency = 1;
link.program = "";
foreach(attr, root.attribute) {
for(auto &attr : root.attribute) {
if(attr.name == "frequency") link.frequency = xml_parse_unsigned(attr.content);
if(attr.name == "program") link.program = attr.content;
}
foreach(node, root.element) {
for(auto &node : root.element) {
if(node.name == "map") {
Mapping m({ &Link::read, &link }, { &Link::write, &link });
foreach(attr, node.attribute) {
for(auto &attr : node.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
mapping.append(m);

View File

@ -72,7 +72,7 @@ bool Cheat::decode(const string &code, unsigned &addr, unsigned &data) {
#define ischr(n) ((n >= '0' && n <= '9') || (n >= 'a' && n <= 'f'))
if(t.wildcard("??????:??")) {
//Pro Action Replay
//Direct
t = { substr(t, 0, 6), substr(t, 7, 2) };
for(unsigned n = 0; n < 8; n++) if(!ischr(t[n])) return false; //validate input
unsigned r = hex(t);

View File

@ -3,8 +3,7 @@ struct CheatCode {
unsigned data;
};
class Cheat : public linear_vector<CheatCode> {
public:
struct Cheat : public linear_vector<CheatCode> {
uint8 *override;
bool enabled() const;

View File

@ -4,7 +4,7 @@ void HitachiDSP::serialize(serializer &s) {
Processor::serialize(s);
s.array(dataRAM);
foreach(n, stack) s.integer(n);
for(auto &n : stack) s.integer(n);
s.integer(opcode);
s.integer((unsigned&)state);
@ -22,7 +22,7 @@ void HitachiDSP::serialize(serializer &s) {
s.integer(regs.ramdata);
s.integer(regs.busaddr);
s.integer(regs.ramaddr);
foreach(n, regs.gpr) s.integer(n);
for(auto &n : regs.gpr) s.integer(n);
s.integer(regs.dma_source);
s.integer(regs.dma_length);

View File

@ -59,8 +59,8 @@ void ICD2::reset() {
r7800 = 0x0000;
mlt_req = 0;
foreach(byte, lcd.buffer) byte = 0;
foreach(byte, lcd.output) byte = 0;
for(auto &byte : lcd.buffer) byte = 0;
for(auto &byte : lcd.output) byte = 0;
lcd.row = 0;
packetsize = 0;

View File

@ -28,7 +28,8 @@ void SA1::enter() {
if(status.interrupt_pending) {
status.interrupt_pending = false;
interrupt(status.interrupt_vector);
op_irq();
continue;
}
(this->*opcode_table[op_readpc()])();
@ -38,43 +39,30 @@ void SA1::enter() {
void SA1::last_cycle() {
if(mmio.sa1_nmi && !mmio.sa1_nmicl) {
status.interrupt_pending = true;
status.interrupt_vector = mmio.cnv;
regs.vector = mmio.cnv;
mmio.sa1_nmifl = true;
mmio.sa1_nmicl = 1;
regs.wai = false;
} else if(!regs.p.i) {
if(mmio.timer_irqen && !mmio.timer_irqcl) {
status.interrupt_pending = true;
status.interrupt_vector = mmio.civ;
regs.vector = mmio.civ;
mmio.timer_irqfl = true;
regs.wai = false;
} else if(mmio.dma_irqen && !mmio.dma_irqcl) {
status.interrupt_pending = true;
status.interrupt_vector = mmio.civ;
regs.vector = mmio.civ;
mmio.dma_irqfl = true;
regs.wai = false;
} else if(mmio.sa1_irq && !mmio.sa1_irqcl) {
status.interrupt_pending = true;
status.interrupt_vector = mmio.civ;
regs.vector = mmio.civ;
mmio.sa1_irqfl = true;
regs.wai = false;
}
}
}
void SA1::interrupt(uint16 vector) {
SA1::op_read(regs.pc.d);
SA1::op_io();
if(!regs.e) op_writestack(regs.pc.b);
op_writestack(regs.pc.h);
op_writestack(regs.pc.l);
op_writestack(regs.e ? (regs.p & ~0x10) : regs.p);
regs.pc.w = vector;
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
}
bool SA1::interrupt_pending() {
return status.interrupt_pending;
}
@ -138,22 +126,22 @@ void SA1::reset() {
iram.write(addr, 0x00);
}
regs.pc.d = 0x000000;
regs.x.h = 0x00;
regs.y.h = 0x00;
regs.s.h = 0x01;
regs.d = 0x0000;
regs.db = 0x00;
regs.p = 0x34;
regs.e = 1;
regs.mdr = 0x00;
regs.wai = false;
regs.pc.d = 0x000000;
regs.x.h = 0x00;
regs.y.h = 0x00;
regs.s.h = 0x01;
regs.d = 0x0000;
regs.db = 0x00;
regs.p = 0x34;
regs.e = 1;
regs.mdr = 0x00;
regs.wai = false;
regs.vector = 0x0000;
CPUcore::update_table();
status.tick_counter = 0;
status.interrupt_pending = false;
status.interrupt_vector = 0x0000;
status.scanlines = (system.region() == System::Region::NTSC ? 262 : 312);
status.vcounter = 0;

View File

@ -9,7 +9,6 @@ public:
uint8 tick_counter;
bool interrupt_pending;
uint16 interrupt_vector;
uint16 scanlines;
uint16 vcounter;
@ -18,7 +17,6 @@ public:
static void Enter();
void enter();
void interrupt(uint16 vector);
void tick();
alwaysinline void trigger_irq();

View File

@ -8,7 +8,6 @@ void SA1::serialize(serializer &s) {
s.integer(status.tick_counter);
s.integer(status.interrupt_pending);
s.integer(status.interrupt_vector);
s.integer(status.scanlines);
s.integer(status.vcounter);

View File

@ -67,6 +67,21 @@ alwaysinline void CPUcore::op_io_cond6(uint16 addr) {
}
}
void CPUcore::op_irq() {
op_read(regs.pc.d);
op_io();
if(!regs.e) op_writestack(regs.pc.b);
op_writestack(regs.pc.h);
op_writestack(regs.pc.l);
op_writestack(regs.e ? (regs.p & ~0x10) : regs.p);
rd.l = op_read(regs.vector + 0);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
rd.h = op_read(regs.vector + 1);
regs.pc.w = rd.w;
}
CPUcore::CPUcore() {
initialize_opcode_table();
}

View File

@ -1,5 +1,4 @@
class CPUcore {
public:
struct CPUcore {
#include "registers.hpp"
#include "memory.hpp"
#include "disassembler/disassembler.hpp"
@ -19,6 +18,8 @@ public:
void op_io_cond4(uint16 x, uint16 y);
void op_io_cond6(uint16 addr);
void op_irq();
void op_adc_b();
void op_adc_w();
void op_and_b();

View File

@ -71,11 +71,13 @@ struct regs_t {
uint8 db;
bool e;
bool irq; //IRQ pin (0 = low, 1 = trigger)
bool wai; //raised during wai, cleared after interrupt triggered
uint8 mdr; //memory data register
bool irq; //IRQ pin (0 = low, 1 = trigger)
bool wai; //raised during wai, cleared after interrupt triggered
uint8 mdr; //memory data register
uint16 vector; //interrupt vector address
regs_t() : a(r[0]), x(r[1]), y(r[2]), z(r[3]), s(r[4]), d(r[5]), db(0), e(false), irq(false), wai(false), mdr(0) {
regs_t():
a(r[0]), x(r[1]), y(r[2]), z(r[3]), s(r[4]), d(r[5]), db(0), e(false), irq(false), wai(false), mdr(0), vector(0) {
z = 0;
}
};

View File

@ -24,6 +24,7 @@ void CPUcore::core_serialize(serializer &s) {
s.integer(regs.irq);
s.integer(regs.wai);
s.integer(regs.mdr);
s.integer(regs.vector);
s.integer(aa.d);
s.integer(rd.d);

View File

@ -69,11 +69,11 @@ void CPU::enter() {
status.interrupt_pending = false;
if(status.nmi_pending) {
status.nmi_pending = false;
status.interrupt_vector = (regs.e == false ? 0xffea : 0xfffa);
regs.vector = (regs.e == false ? 0xffea : 0xfffa);
op_irq();
} else if(status.irq_pending) {
status.irq_pending = false;
status.interrupt_vector = (regs.e == false ? 0xffee : 0xfffe);
regs.vector = (regs.e == false ? 0xffee : 0xfffe);
op_irq();
} else if(status.reset_pending) {
status.reset_pending = false;
@ -91,21 +91,6 @@ void CPU::op_step() {
(this->*opcode_table[op_readpc()])();
}
void CPU::op_irq() {
op_read(regs.pc.d);
op_io();
if(!regs.e) op_writestack(regs.pc.b);
op_writestack(regs.pc.h);
op_writestack(regs.pc.l);
op_writestack(regs.e ? (regs.p & ~0x10) : regs.p);
rd.l = op_read(status.interrupt_vector + 0);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
rd.h = op_read(status.interrupt_vector + 1);
regs.pc.w = rd.w;
}
void CPU::enable() {
function<uint8 (unsigned)> read = { &CPU::mmio_read, (CPU*)&cpu };
function<void (unsigned, uint8)> write = { &CPU::mmio_write, (CPU*)&cpu };
@ -132,7 +117,7 @@ void CPU::enable() {
void CPU::power() {
cpu_version = config.cpu.version;
foreach(n, wram) n = random(config.cpu.wram_init_value);
for(auto &n : wram) n = random(config.cpu.wram_init_value);
regs.a = regs.x = regs.y = 0x0000;
regs.s = 0x01ff;
@ -150,16 +135,17 @@ void CPU::reset() {
PPUcounter::reset();
//note: some registers are not fully reset by SNES
regs.pc = 0x000000;
regs.x.h = 0x00;
regs.y.h = 0x00;
regs.s.h = 0x01;
regs.d = 0x0000;
regs.db = 0x00;
regs.p = 0x34;
regs.e = 1;
regs.mdr = 0x00;
regs.wai = false;
regs.pc = 0x000000;
regs.x.h = 0x00;
regs.y.h = 0x00;
regs.s.h = 0x01;
regs.d = 0x0000;
regs.db = 0x00;
regs.p = 0x34;
regs.e = 1;
regs.mdr = 0x00;
regs.wai = false;
regs.vector = 0xfffc; //reset vector address
update_table();
mmio_reset();

View File

@ -1,5 +1,4 @@
class CPU : public Processor, public CPUcore, public PPUcounter {
public:
struct CPU : public Processor, public CPUcore, public PPUcounter {
uint8 wram[128 * 1024];
enum : bool { Threaded = true };
@ -36,7 +35,6 @@ private:
struct Status {
bool interrupt_pending;
uint16 interrupt_vector;
unsigned clock_count;
unsigned line_clocks;
@ -133,7 +131,6 @@ private:
} alu;
static void Enter();
void op_irq();
debugvirtual void op_step();
friend class CPUDebugger;

View File

@ -352,7 +352,7 @@ void CPU::mmio_power() {
void CPU::mmio_reset() {
//$2140-217f
foreach(port, status.port) port = 0x00;
for(auto &port : status.port) port = 0x00;
//$2181-$2183
status.wram_addr = 0x000000;

View File

@ -10,7 +10,6 @@ void CPU::serialize(serializer &s) {
s.integer(cpu_version);
s.integer(status.interrupt_pending);
s.integer(status.interrupt_vector);
s.integer(status.clock_count);
s.integer(status.line_clocks);

View File

@ -182,7 +182,6 @@ void CPU::timing_reset() {
status.reset_pending = true;
status.interrupt_pending = true;
status.interrupt_vector = 0xfffc; //reset vector address
status.dma_active = false;
status.dma_counter = 0;

View File

@ -1,5 +1,4 @@
class Debugger {
public:
struct Debugger {
enum class BreakEvent : unsigned {
None,
BreakpointHit,

View File

@ -1,5 +1,4 @@
class DSP : public Processor {
public:
struct DSP : public Processor {
enum : bool { Threaded = true };
alwaysinline void step(unsigned clocks);
alwaysinline void synchronize_smp();

View File

@ -6,7 +6,7 @@ void Input::connect(bool port, Input::Device id) {
Controller *&controller = (port == Controller::Port1 ? port1 : port2);
if(controller) {
delete controller;
controller = 0;
controller = nullptr;
}
switch(id) { default:
@ -26,7 +26,7 @@ void Input::connect(bool port, Input::Device id) {
}
}
Input::Input() {
Input::Input() : port1(nullptr), port2(nullptr) {
connect(Controller::Port1, Input::Device::Joypad);
connect(Controller::Port2, Input::Device::Joypad);
}

View File

@ -101,10 +101,10 @@ void Interface::setCheats(const lstring &list) {
}
cheat.reset();
foreach(code, list) {
for(auto &code : list) {
lstring codelist;
codelist.split("+", code);
foreach(part, codelist) {
for(auto &part : codelist) {
unsigned addr, data;
if(Cheat::decode(part, addr, data)) {
cheat.append({ addr, data });

View File

@ -1,5 +1,4 @@
class Interface {
public:
struct Interface {
virtual void videoRefresh(const uint32_t *data, bool hires, bool interlace, bool overscan);
virtual void audioSample(int16_t lsample, int16_t rsample);
virtual int16_t inputPoll(bool port, Input::Device device, unsigned index, unsigned id);

View File

@ -61,7 +61,7 @@ void Bus::map_reset() {
}
void Bus::map_xml() {
foreach(m, cartridge.mapping) {
for(auto &m : cartridge.mapping) {
map(m.mode, m.banklo, m.bankhi, m.addrlo, m.addrhi, m.read, m.write, m.offset, m.size);
}
}

View File

@ -95,9 +95,9 @@ void PPU::power() {
ppu1_version = config.ppu1.version;
ppu2_version = config.ppu2.version;
foreach(n, vram) n = random(0x00);
foreach(n, oam) n = random(0x00);
foreach(n, cgram) n = random(0x00);
for(auto &n : vram) n = random(0x00);
for(auto &n : oam) n = random(0x00);
for(auto &n : cgram) n = random(0x00);
reset();
}

View File

@ -1,5 +1,4 @@
class PPU : public Processor, public PPUcounter {
public:
struct PPU : public Processor, public PPUcounter {
uint8 vram[64 * 1024];
uint8 oam[544];
uint8 cgram[512];

View File

@ -1,5 +1,4 @@
class SMPcore {
public:
struct SMPcore {
#include "registers.hpp"
#include "memory.hpp"
#include "disassembler/disassembler.hpp"

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