mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-04-02 10:42:14 -04:00
byuu says: Most notably, this release adds Nintendo DS emulation. The Nintendo DS module was written entirely by Cydrak, so please give him all of the credit for it. I for one am extremely grateful to be allowed to use his module in bsnes. The Nintendo DS emulator's standalone name is dasShiny. You will need the Nintendo DS firmware, which I cannot provide, in order to use it. It also cannot (currently?) detect the save type used by NDS games. As such, manifest.xml files must be created manually for this purpose. The long-term plan is to create a database of save types for each game. Also, you will need an analog input device for the touch screen for now (joypad axes work well.) There have also been a lot of changes from my end: a unified manifest.xml format across all systems, major improvements to SPC7110 emulation, enhancements to RTC emulation, MSU1 enhancements, icons in the file browser list, improvements to SNES coprocessor memory mapping, cleanups and improvements in the libraries used to build bsnes, etc. I've also included kaijuu (which allows launching game folders directly with bsnes) and purify (which allows opening images that are compressed, have copier headers, and have wrong extensions); both of which are fully GUI-based. This release only loads game folders, not files. Use purify to load ROM files in bsnes. Note that this will likely be the last release for a long time, and that I will probably rename the emulator for the next release, due to how many additional systems it now supports.
146 lines
3.5 KiB
C++
146 lines
3.5 KiB
C++
#ifndef NALL_SERIALIZER_HPP
|
|
#define NALL_SERIALIZER_HPP
|
|
|
|
#include <type_traits>
|
|
#include <utility>
|
|
#include <nall/stdint.hpp>
|
|
#include <nall/utility.hpp>
|
|
|
|
namespace nall {
|
|
//serializer: a class designed to save and restore the state of classes.
|
|
//
|
|
//benefits:
|
|
//- data() will be portable in size (it is not necessary to specify type sizes.)
|
|
//- data() will be portable in endianness (always stored internally as little-endian.)
|
|
//- one serialize function can both save and restore class states.
|
|
//
|
|
//caveats:
|
|
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
|
|
//- floating-point usage is not portable across platforms
|
|
|
|
class serializer {
|
|
public:
|
|
enum mode_t { Load, Save, Size };
|
|
|
|
mode_t mode() const {
|
|
return imode;
|
|
}
|
|
|
|
const uint8_t* data() const {
|
|
return idata;
|
|
}
|
|
|
|
unsigned size() const {
|
|
return isize;
|
|
}
|
|
|
|
unsigned capacity() const {
|
|
return icapacity;
|
|
}
|
|
|
|
template<typename T> void floatingpoint(T &value) {
|
|
enum { size = sizeof(T) };
|
|
//this is rather dangerous, and not cross-platform safe;
|
|
//but there is no standardized way to export FP-values
|
|
uint8_t *p = (uint8_t*)&value;
|
|
if(imode == Save) {
|
|
for(unsigned n = 0; n < size; n++) idata[isize++] = p[n];
|
|
} else if(imode == Load) {
|
|
for(unsigned n = 0; n < size; n++) p[n] = idata[isize++];
|
|
} else {
|
|
isize += size;
|
|
}
|
|
}
|
|
|
|
template<typename T> void integer(T &value) {
|
|
enum { size = std::is_same<bool, T>::value ? 1 : sizeof(T) };
|
|
if(imode == Save) {
|
|
for(unsigned n = 0; n < size; n++) idata[isize++] = (uintmax_t)value >> (n << 3);
|
|
} else if(imode == Load) {
|
|
value = 0;
|
|
for(unsigned n = 0; n < size; n++) value |= (uintmax_t)idata[isize++] << (n << 3);
|
|
} else if(imode == Size) {
|
|
isize += size;
|
|
}
|
|
}
|
|
|
|
template<typename T> void array(T &array) {
|
|
enum { size = sizeof(T) / sizeof(typename std::remove_extent<T>::type) };
|
|
for(unsigned n = 0; n < size; n++) integer(array[n]);
|
|
}
|
|
|
|
template<typename T> void array(T array, unsigned size) {
|
|
for(unsigned n = 0; n < size; n++) integer(array[n]);
|
|
}
|
|
|
|
//copy
|
|
serializer& operator=(const serializer &s) {
|
|
if(idata) delete[] idata;
|
|
|
|
imode = s.imode;
|
|
idata = new uint8_t[s.icapacity];
|
|
isize = s.isize;
|
|
icapacity = s.icapacity;
|
|
|
|
memcpy(idata, s.idata, s.icapacity);
|
|
return *this;
|
|
}
|
|
|
|
serializer(const serializer &s) : idata(0) {
|
|
operator=(s);
|
|
}
|
|
|
|
//move
|
|
serializer& operator=(serializer &&s) {
|
|
if(idata) delete[] idata;
|
|
|
|
imode = s.imode;
|
|
idata = s.idata;
|
|
isize = s.isize;
|
|
icapacity = s.icapacity;
|
|
|
|
s.idata = 0;
|
|
return *this;
|
|
}
|
|
|
|
serializer(serializer &&s) {
|
|
operator=(std::move(s));
|
|
}
|
|
|
|
//construction
|
|
serializer() {
|
|
imode = Size;
|
|
idata = 0;
|
|
isize = 0;
|
|
icapacity = 0;
|
|
}
|
|
|
|
serializer(unsigned capacity) {
|
|
imode = Save;
|
|
idata = new uint8_t[capacity]();
|
|
isize = 0;
|
|
icapacity = capacity;
|
|
}
|
|
|
|
serializer(const uint8_t *data, unsigned capacity) {
|
|
imode = Load;
|
|
idata = new uint8_t[capacity];
|
|
isize = 0;
|
|
icapacity = capacity;
|
|
memcpy(idata, data, capacity);
|
|
}
|
|
|
|
~serializer() {
|
|
if(idata) delete[] idata;
|
|
}
|
|
|
|
private:
|
|
mode_t imode;
|
|
uint8_t *idata;
|
|
unsigned isize;
|
|
unsigned icapacity;
|
|
};
|
|
|
|
};
|
|
|
|
#endif
|