mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-02-23 22:52:34 +01:00
byuu says: This release refines HSU1 support as a bidirectional protocol, nests SFC manifests as "release/cartridge" and "release/information" (but release/ is not guaranteed to be finalized just yet), removes the database integration, and adds support for ananke. ananke represents inevitability. It's a library that, when installed, higan can use to load files from the command-line, and also from a new File -> Load Game menu option. I need to change the build rules a bit for it to work on Windows (need to make phoenix a DLL, basically), but it works now on Linux. Right now, it only takes *.sfc file names, looks them up in the included database, converts them to game folders, and returns the game folder path for higan to load. The idea is to continue expanding it to support everything we can that I don't want in the higan core: - load *.sfc, *.smc, *.swc, *.fig files - remove SNES copier headers - split apart merged firmware files - pull in external firmware files (eg dsp1b.rom - these are staying merged, just as SPC7110 prg+dat are merged) - load *.zip and *.7z archives - prompt for selection on multi-file archives - generate manifest files based on heuristics - apply BPS patches The "Load" menu option has been renamed to "Library", to represent games in your library. I'm going to add some sort of suffix to indicate unverified games, and use a different folder icon for those (eg manifests built on heuristics rather than from the database.) So basically, to future end users: File -> Load Game will be how they play games. Library -> (specific system) can be thought of as an infinitely-sized recent games list. purify will likely become a simple stub that invokes ananke's functions. No reason to duplicate all that code.
121 lines
3.8 KiB
C++
Executable File
121 lines
3.8 KiB
C++
Executable File
#ifndef EMULATOR_INTERFACE_HPP
|
|
#define EMULATOR_INTERFACE_HPP
|
|
|
|
namespace Emulator {
|
|
|
|
struct Interface {
|
|
struct Information {
|
|
string name;
|
|
unsigned width;
|
|
unsigned height;
|
|
bool overscan;
|
|
double aspectRatio;
|
|
bool resettable;
|
|
struct Capability {
|
|
bool states;
|
|
bool cheats;
|
|
} capability;
|
|
} information;
|
|
|
|
struct Media {
|
|
unsigned id;
|
|
string name;
|
|
string type;
|
|
string load;
|
|
};
|
|
|
|
vector<Media> media;
|
|
|
|
struct Device {
|
|
unsigned id;
|
|
unsigned portmask;
|
|
string name;
|
|
struct Input {
|
|
unsigned id;
|
|
unsigned type; //0 = digital, 1 = analog (relative), 2 = analog (absolute)
|
|
string name;
|
|
unsigned guid;
|
|
};
|
|
vector<Input> input;
|
|
vector<unsigned> order;
|
|
};
|
|
|
|
struct Port {
|
|
unsigned id;
|
|
string name;
|
|
vector<Device> device;
|
|
};
|
|
vector<Port> port;
|
|
|
|
struct Bind {
|
|
virtual void loadRequest(unsigned, const string&, const string&) {}
|
|
virtual void loadRequest(unsigned, const string&) {}
|
|
virtual void saveRequest(unsigned, const string&) {}
|
|
virtual uint32_t videoColor(unsigned, uint16_t, uint16_t, uint16_t) { return 0u; }
|
|
virtual void videoRefresh(const uint32_t*, unsigned, unsigned, unsigned) {}
|
|
virtual void audioSample(int16_t, int16_t) {}
|
|
virtual int16_t inputPoll(unsigned, unsigned, unsigned) { return 0; }
|
|
virtual unsigned dipSettings(const Markup::Node&) { return 0; }
|
|
virtual string path(unsigned) { return ""; }
|
|
virtual string server() { return ""; }
|
|
virtual void notify(const string &text) { print(text, "\n"); }
|
|
} *bind;
|
|
|
|
//callback bindings (provided by user interface)
|
|
void loadRequest(unsigned id, const string &name, const string &type) { return bind->loadRequest(id, name, type); }
|
|
void loadRequest(unsigned id, const string &path) { return bind->loadRequest(id, path); }
|
|
void saveRequest(unsigned id, const string &path) { return bind->saveRequest(id, path); }
|
|
uint32_t videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue) { return bind->videoColor(source, red, green, blue); }
|
|
void videoRefresh(const uint32_t *data, unsigned pitch, unsigned width, unsigned height) { return bind->videoRefresh(data, pitch, width, height); }
|
|
void audioSample(int16_t lsample, int16_t rsample) { return bind->audioSample(lsample, rsample); }
|
|
int16_t inputPoll(unsigned port, unsigned device, unsigned input) { return bind->inputPoll(port, device, input); }
|
|
unsigned dipSettings(const Markup::Node &node) { return bind->dipSettings(node); }
|
|
string path(unsigned group) { return bind->path(group); }
|
|
string server() { return bind->server(); }
|
|
template<typename... Args> void notify(Args&... args) { return bind->notify({std::forward<Args>(args)...}); }
|
|
|
|
//information
|
|
virtual double videoFrequency() = 0;
|
|
virtual double audioFrequency() = 0;
|
|
|
|
//media interface
|
|
virtual bool loaded() { return false; }
|
|
virtual string sha256() { return ""; }
|
|
virtual unsigned group(unsigned id) = 0;
|
|
virtual void load(unsigned id, const string &manifest) {}
|
|
virtual void save() {}
|
|
virtual void load(unsigned id, const stream &memory, const string &markup = "") {}
|
|
virtual void save(unsigned id, const stream &memory) {}
|
|
virtual void unload() {}
|
|
|
|
//system interface
|
|
virtual void connect(unsigned port, unsigned device) {}
|
|
virtual void power() {}
|
|
virtual void reset() {}
|
|
virtual void run() {}
|
|
|
|
//time functions
|
|
virtual bool rtc() { return false; }
|
|
virtual void rtcsync() {}
|
|
|
|
//state functions
|
|
virtual serializer serialize() = 0;
|
|
virtual bool unserialize(serializer&) = 0;
|
|
|
|
//cheat functions
|
|
virtual void cheatSet(const lstring& = lstring{}) {}
|
|
|
|
//utility functions
|
|
virtual void paletteUpdate() {}
|
|
|
|
//debugger functions
|
|
virtual bool tracerEnable(bool) { return false; }
|
|
virtual void exportMemory() {}
|
|
|
|
Interface() : bind(nullptr) {}
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|