mirror of https://github.com/bsnes-emu/bsnes.git
Update to v099r05 release.
byuu says: Changelog: - added nall/vfs - converted Famicom core to use nall/vfs interface instead of nall/stream interface
This commit is contained in:
parent
40abcfc4a5
commit
f04d9d58f5
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <nall/nall.hpp>
|
#include <nall/nall.hpp>
|
||||||
|
#include <nall/vfs.hpp>
|
||||||
using namespace nall;
|
using namespace nall;
|
||||||
|
|
||||||
#include <audio/audio.hpp>
|
#include <audio/audio.hpp>
|
||||||
|
@ -9,7 +10,7 @@ using namespace nall;
|
||||||
|
|
||||||
namespace Emulator {
|
namespace Emulator {
|
||||||
static const string Name = "higan";
|
static const string Name = "higan";
|
||||||
static const string Version = "099.04";
|
static const string Version = "099.05";
|
||||||
static const string Author = "byuu";
|
static const string Author = "byuu";
|
||||||
static const string License = "GPLv3";
|
static const string License = "GPLv3";
|
||||||
static const string Website = "http://byuu.org/";
|
static const string Website = "http://byuu.org/";
|
||||||
|
|
|
@ -46,6 +46,8 @@ struct Interface {
|
||||||
vector<Port> ports;
|
vector<Port> ports;
|
||||||
|
|
||||||
struct Bind {
|
struct Bind {
|
||||||
|
virtual auto path(uint) -> string { return ""; }
|
||||||
|
virtual auto open(uint, string, vfs::file::mode, bool) -> vfs::shared::file { return {}; }
|
||||||
virtual auto loadRequest(uint, string, string, bool) -> void {}
|
virtual auto loadRequest(uint, string, string, bool) -> void {}
|
||||||
virtual auto loadRequest(uint, string, bool) -> void {}
|
virtual auto loadRequest(uint, string, bool) -> void {}
|
||||||
virtual auto saveRequest(uint, string) -> void {}
|
virtual auto saveRequest(uint, string) -> void {}
|
||||||
|
@ -54,12 +56,13 @@ struct Interface {
|
||||||
virtual auto inputPoll(uint, uint, uint) -> int16 { return 0; }
|
virtual auto inputPoll(uint, uint, uint) -> int16 { return 0; }
|
||||||
virtual auto inputRumble(uint, uint, uint, bool) -> void {}
|
virtual auto inputRumble(uint, uint, uint, bool) -> void {}
|
||||||
virtual auto dipSettings(const Markup::Node&) -> uint { return 0; }
|
virtual auto dipSettings(const Markup::Node&) -> uint { return 0; }
|
||||||
virtual auto path(uint) -> string { return ""; }
|
|
||||||
virtual auto notify(string text) -> void { print(text, "\n"); }
|
virtual auto notify(string text) -> void { print(text, "\n"); }
|
||||||
};
|
};
|
||||||
Bind* bind = nullptr;
|
Bind* bind = nullptr;
|
||||||
|
|
||||||
//callback bindings (provided by user interface)
|
//callback bindings (provided by user interface)
|
||||||
|
auto path(uint id) -> string { return bind->path(id); }
|
||||||
|
auto open(uint id, string name, vfs::file::mode mode, bool required = false) -> vfs::shared::file { return bind->open(id, name, mode, required); }
|
||||||
auto loadRequest(uint id, string name, string type, bool required) -> void { return bind->loadRequest(id, name, type, required); }
|
auto loadRequest(uint id, string name, string type, bool required) -> void { return bind->loadRequest(id, name, type, required); }
|
||||||
auto loadRequest(uint id, string path, bool required) -> void { return bind->loadRequest(id, path, required); }
|
auto loadRequest(uint id, string path, bool required) -> void { return bind->loadRequest(id, path, required); }
|
||||||
auto saveRequest(uint id, string path) -> void { return bind->saveRequest(id, path); }
|
auto saveRequest(uint id, string path) -> void { return bind->saveRequest(id, path); }
|
||||||
|
@ -68,7 +71,6 @@ struct Interface {
|
||||||
auto inputPoll(uint port, uint device, uint input) -> int16 { return bind->inputPoll(port, device, input); }
|
auto inputPoll(uint port, uint device, uint input) -> int16 { return bind->inputPoll(port, device, input); }
|
||||||
auto inputRumble(uint port, uint device, uint input, bool enable) -> void { return bind->inputRumble(port, device, input, enable); }
|
auto inputRumble(uint port, uint device, uint input, bool enable) -> void { return bind->inputRumble(port, device, input, enable); }
|
||||||
auto dipSettings(const Markup::Node& node) -> uint { return bind->dipSettings(node); }
|
auto dipSettings(const Markup::Node& node) -> uint { return bind->dipSettings(node); }
|
||||||
auto path(uint group) -> string { return bind->path(group); }
|
|
||||||
template<typename... P> auto notify(P&&... p) -> void { return bind->notify({forward<P>(p)...}); }
|
template<typename... P> auto notify(P&&... p) -> void { return bind->notify({forward<P>(p)...}); }
|
||||||
|
|
||||||
//information
|
//information
|
||||||
|
@ -86,7 +88,7 @@ struct Interface {
|
||||||
//media interface
|
//media interface
|
||||||
virtual auto loaded() -> bool { return false; }
|
virtual auto loaded() -> bool { return false; }
|
||||||
virtual auto sha256() -> string { return ""; }
|
virtual auto sha256() -> string { return ""; }
|
||||||
virtual auto group(uint id) -> uint = 0;
|
virtual auto group(uint id) -> uint { return 0; }
|
||||||
virtual auto load(uint id) -> void {}
|
virtual auto load(uint id) -> void {}
|
||||||
virtual auto save() -> void {}
|
virtual auto save() -> void {}
|
||||||
virtual auto load(uint id, const stream& memory) -> void {}
|
virtual auto load(uint id, const stream& memory) -> void {}
|
||||||
|
|
|
@ -41,18 +41,45 @@ Board::Board(Markup::Node& document) {
|
||||||
if(chrrom.size) chrrom.data = new uint8_t[chrrom.size]();
|
if(chrrom.size) chrrom.data = new uint8_t[chrrom.size]();
|
||||||
if(chrram.size) chrram.data = new uint8_t[chrram.size]();
|
if(chrram.size) chrram.data = new uint8_t[chrram.size]();
|
||||||
|
|
||||||
if(auto name = prom["name"].text()) interface->loadRequest(ID::ProgramROM, name, true);
|
if(prgrom.name = prom["name"].text()) {
|
||||||
if(auto name = pram["name"].text()) interface->loadRequest(ID::ProgramRAM, name, false);
|
if(auto fp = interface->open(ID::Famicom, prgrom.name, vfs::file::mode::read, true)) {
|
||||||
if(auto name = crom["name"].text()) interface->loadRequest(ID::CharacterROM, name, true);
|
fp->read(prgrom.data, min(prgrom.size, fp->size()));
|
||||||
if(auto name = cram["name"].text()) interface->loadRequest(ID::CharacterRAM, name, false);
|
}
|
||||||
|
}
|
||||||
if(auto name = pram["name"].text()) Famicom::cartridge.memory.append({ID::ProgramRAM, name});
|
if(prgram.name = pram["name"].text()) {
|
||||||
if(auto name = cram["name"].text()) Famicom::cartridge.memory.append({ID::CharacterRAM, name});
|
if(auto fp = interface->open(ID::Famicom, prgram.name, vfs::file::mode::read)) {
|
||||||
|
fp->read(prgram.data, min(prgram.size, fp->size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(chrrom.name = crom["name"].text()) {
|
||||||
|
if(auto fp = interface->open(ID::Famicom, chrrom.name, vfs::file::mode::read, true)) {
|
||||||
|
fp->read(chrrom.data, min(chrrom.size, fp->size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(chrram.name = cram["name"].text()) {
|
||||||
|
if(auto fp = interface->open(ID::Famicom, chrram.name, vfs::file::mode::read)) {
|
||||||
|
fp->read(chrram.data, min(chrram.size, fp->size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
prgram.writable = true;
|
prgram.writable = true;
|
||||||
chrram.writable = true;
|
chrram.writable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Board::save() -> void {
|
||||||
|
if(auto name = prgram.name) {
|
||||||
|
if(auto fp = interface->open(ID::Famicom, name, vfs::file::mode::write)) {
|
||||||
|
fp->write(prgram.data, prgram.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(auto name = chrram.name) {
|
||||||
|
if(auto fp = interface->open(ID::Famicom, name, vfs::file::mode::write)) {
|
||||||
|
fp->write(chrram.data, chrram.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto Board::Memory::read(uint addr) const -> uint8 {
|
auto Board::Memory::read(uint addr) const -> uint8 {
|
||||||
return data[mirror(addr, size)];
|
return data[mirror(addr, size)];
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,16 +7,19 @@ struct Board {
|
||||||
inline auto read(uint addr) const -> uint8;
|
inline auto read(uint addr) const -> uint8;
|
||||||
inline auto write(uint addr, uint8 data) -> void;
|
inline auto write(uint addr, uint8 data) -> void;
|
||||||
|
|
||||||
uint8_t* data;
|
string name;
|
||||||
uint size;
|
uint8_t* data = nullptr;
|
||||||
bool writable;
|
uint size = 0;
|
||||||
|
bool writable = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
Board(Markup::Node& document);
|
|
||||||
virtual ~Board() = default;
|
virtual ~Board() = default;
|
||||||
|
|
||||||
static auto mirror(uint addr, uint size) -> uint;
|
static auto mirror(uint addr, uint size) -> uint;
|
||||||
|
|
||||||
|
Board(Markup::Node& document);
|
||||||
|
auto save() -> void;
|
||||||
|
|
||||||
virtual auto main() -> void;
|
virtual auto main() -> void;
|
||||||
virtual auto tick() -> void;
|
virtual auto tick() -> void;
|
||||||
|
|
||||||
|
|
|
@ -26,20 +26,30 @@ auto Cartridge::main() -> void {
|
||||||
board->main();
|
board->main();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Cartridge::load() -> void {
|
auto Cartridge::load() -> bool {
|
||||||
interface->loadRequest(ID::Manifest, "manifest.bml", true);
|
if(auto fp = interface->open(ID::Famicom, "manifest.bml", vfs::file::mode::read, true)) {
|
||||||
|
fp->reads(information.markup);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Board::load(information.markup); //this call will set Cartridge::board if successful
|
Board::load(information.markup); //this call will set Cartridge::board if successful
|
||||||
if(!board) return;
|
if(!board) return false;
|
||||||
|
|
||||||
Hash::SHA256 sha;
|
Hash::SHA256 sha;
|
||||||
sha.data(board->prgrom.data, board->prgrom.size);
|
sha.data(board->prgrom.data, board->prgrom.size);
|
||||||
sha.data(board->chrrom.data, board->chrrom.size);
|
sha.data(board->chrrom.data, board->chrrom.size);
|
||||||
_sha256 = sha.digest();
|
_sha256 = sha.digest();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Cartridge::save() -> void {
|
||||||
|
board->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Cartridge::unload() -> void {
|
auto Cartridge::unload() -> void {
|
||||||
memory.reset();
|
delete board;
|
||||||
|
board = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Cartridge::power() -> void {
|
auto Cartridge::power() -> void {
|
||||||
|
|
|
@ -9,7 +9,8 @@ struct Cartridge : Thread {
|
||||||
auto manifest() const -> string;
|
auto manifest() const -> string;
|
||||||
auto title() const -> string;
|
auto title() const -> string;
|
||||||
|
|
||||||
auto load() -> void;
|
auto load() -> bool;
|
||||||
|
auto save() -> void;
|
||||||
auto unload() -> void;
|
auto unload() -> void;
|
||||||
|
|
||||||
auto power() -> void;
|
auto power() -> void;
|
||||||
|
@ -22,12 +23,6 @@ struct Cartridge : Thread {
|
||||||
string title;
|
string title;
|
||||||
} information;
|
} information;
|
||||||
|
|
||||||
struct Memory {
|
|
||||||
unsigned id;
|
|
||||||
string name;
|
|
||||||
};
|
|
||||||
vector<Memory> memory;
|
|
||||||
|
|
||||||
//privileged:
|
//privileged:
|
||||||
Board* board = nullptr;
|
Board* board = nullptr;
|
||||||
string _sha256;
|
string _sha256;
|
||||||
|
|
|
@ -128,65 +128,12 @@ auto Interface::sha256() -> string {
|
||||||
return cartridge.sha256();
|
return cartridge.sha256();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Interface::group(uint id) -> uint {
|
|
||||||
switch(id) {
|
|
||||||
case ID::SystemManifest:
|
|
||||||
return 0;
|
|
||||||
case ID::Manifest:
|
|
||||||
case ID::ProgramROM:
|
|
||||||
case ID::ProgramRAM:
|
|
||||||
case ID::CharacterROM:
|
|
||||||
case ID::CharacterRAM:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Interface::load(uint id) -> void {
|
auto Interface::load(uint id) -> void {
|
||||||
system.load();
|
system.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Interface::save() -> void {
|
auto Interface::save() -> void {
|
||||||
for(auto& memory : cartridge.memory) {
|
system.save();
|
||||||
saveRequest(memory.id, memory.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Interface::load(uint id, const stream& stream) -> void {
|
|
||||||
if(id == ID::SystemManifest) {
|
|
||||||
system.information.manifest = stream.text();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == ID::Manifest) {
|
|
||||||
cartridge.information.markup = stream.text();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == ID::ProgramROM) {
|
|
||||||
stream.read(cartridge.board->prgrom.data, min(cartridge.board->prgrom.size, stream.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == ID::ProgramRAM) {
|
|
||||||
stream.read(cartridge.board->prgram.data, min(cartridge.board->prgram.size, stream.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == ID::CharacterROM) {
|
|
||||||
stream.read(cartridge.board->chrrom.data, min(cartridge.board->chrrom.size, stream.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == ID::CharacterRAM) {
|
|
||||||
stream.read(cartridge.board->chrram.data, min(cartridge.board->chrram.size, stream.size()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Interface::save(uint id, const stream& stream) -> void {
|
|
||||||
if(id == ID::ProgramRAM) {
|
|
||||||
stream.write(cartridge.board->prgram.data, cartridge.board->prgram.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == ID::CharacterRAM) {
|
|
||||||
stream.write(cartridge.board->chrram.data, cartridge.board->chrram.size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Interface::unload() -> void {
|
auto Interface::unload() -> void {
|
||||||
|
|
|
@ -1,21 +1,11 @@
|
||||||
namespace Famicom {
|
namespace Famicom {
|
||||||
|
|
||||||
struct ID {
|
struct ID {
|
||||||
enum : uint {
|
enum : uint { //paths
|
||||||
System,
|
System,
|
||||||
Famicom,
|
Famicom,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum : uint {
|
|
||||||
SystemManifest,
|
|
||||||
|
|
||||||
Manifest,
|
|
||||||
ProgramROM,
|
|
||||||
ProgramRAM,
|
|
||||||
CharacterROM,
|
|
||||||
CharacterRAM,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum : uint { //bitmasks
|
enum : uint { //bitmasks
|
||||||
ControllerPort1 = 1,
|
ControllerPort1 = 1,
|
||||||
ControllerPort2 = 2,
|
ControllerPort2 = 2,
|
||||||
|
@ -35,11 +25,8 @@ struct Interface : Emulator::Interface {
|
||||||
|
|
||||||
auto loaded() -> bool;
|
auto loaded() -> bool;
|
||||||
auto sha256() -> string;
|
auto sha256() -> string;
|
||||||
auto group(uint id) -> uint;
|
|
||||||
auto load(uint id) -> void;
|
auto load(uint id) -> void;
|
||||||
auto save() -> void;
|
auto save() -> void;
|
||||||
auto load(uint id, const stream& stream) -> void;
|
|
||||||
auto save(uint id, const stream& stream) -> void;
|
|
||||||
auto unload() -> void;
|
auto unload() -> void;
|
||||||
|
|
||||||
auto connect(uint port, uint device) -> void;
|
auto connect(uint port, uint device) -> void;
|
||||||
|
|
|
@ -21,12 +21,20 @@ auto System::runToSave() -> void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto System::load() -> void {
|
auto System::load() -> bool {
|
||||||
interface->loadRequest(ID::SystemManifest, "manifest.bml", true);
|
if(auto fp = interface->open(ID::System, "manifest.bml", vfs::file::mode::read, true)) {
|
||||||
|
fp->reads(information.manifest);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
auto document = BML::unserialize(information.manifest);
|
auto document = BML::unserialize(information.manifest);
|
||||||
cartridge.load();
|
cartridge.load();
|
||||||
serializeInit();
|
serializeInit();
|
||||||
_loaded = true;
|
return _loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto System::save() -> void {
|
||||||
|
cartridge.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto System::unload() -> void {
|
auto System::unload() -> void {
|
||||||
|
|
|
@ -6,7 +6,8 @@ struct System {
|
||||||
auto run() -> void;
|
auto run() -> void;
|
||||||
auto runToSave() -> void;
|
auto runToSave() -> void;
|
||||||
|
|
||||||
auto load() -> void;
|
auto load() -> bool;
|
||||||
|
auto save() -> void;
|
||||||
auto unload() -> void;
|
auto unload() -> void;
|
||||||
auto power() -> void;
|
auto power() -> void;
|
||||||
auto reset() -> void;
|
auto reset() -> void;
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
auto Program::path(uint id) -> string {
|
||||||
|
return mediumPaths(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Program::open(uint id, string name, vfs::file::mode mode, bool required) -> vfs::shared::file {
|
||||||
|
if(auto result = vfs::fs::file::open({path(id), name}, mode)) return result;
|
||||||
|
if(name == "manifest.bml") {
|
||||||
|
if(auto manifest = execute("icarus", "--manifest", path(id))) {
|
||||||
|
return vfs::memory::file::open(manifest.output.data<uint8_t>(), manifest.output.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
//request from emulation core to load non-volatile media folder
|
//request from emulation core to load non-volatile media folder
|
||||||
auto Program::loadRequest(uint id, string name, string type, bool required) -> void {
|
auto Program::loadRequest(uint id, string name, string type, bool required) -> void {
|
||||||
string location = BrowserDialog()
|
string location = BrowserDialog()
|
||||||
|
@ -116,9 +130,5 @@ auto Program::dipSettings(const Markup::Node& node) -> uint {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Program::path(uint group) -> string {
|
|
||||||
return mediumPaths(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Program::notify(string text) -> void {
|
auto Program::notify(string text) -> void {
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ struct Program : Emulator::Interface::Bind {
|
||||||
auto quit() -> void;
|
auto quit() -> void;
|
||||||
|
|
||||||
//interface.cpp
|
//interface.cpp
|
||||||
|
auto path(uint id) -> string override;
|
||||||
|
auto open(uint id, string name, vfs::file::mode mode, bool required) -> vfs::shared::file override;
|
||||||
auto loadRequest(uint id, string name, string type, bool required) -> void override;
|
auto loadRequest(uint id, string name, string type, bool required) -> void override;
|
||||||
auto loadRequest(uint id, string path, bool required) -> void override;
|
auto loadRequest(uint id, string path, bool required) -> void override;
|
||||||
auto saveRequest(uint id, string path) -> void override;
|
auto saveRequest(uint id, string path) -> void override;
|
||||||
|
@ -14,7 +16,6 @@ struct Program : Emulator::Interface::Bind {
|
||||||
auto inputPoll(uint port, uint device, uint input) -> int16 override;
|
auto inputPoll(uint port, uint device, uint input) -> int16 override;
|
||||||
auto inputRumble(uint port, uint device, uint input, bool enable) -> void override;
|
auto inputRumble(uint port, uint device, uint input, bool enable) -> void override;
|
||||||
auto dipSettings(const Markup::Node& node) -> uint override;
|
auto dipSettings(const Markup::Node& node) -> uint override;
|
||||||
auto path(uint group) -> string override;
|
|
||||||
auto notify(string text) -> void override;
|
auto notify(string text) -> void override;
|
||||||
|
|
||||||
//medium.cpp
|
//medium.cpp
|
||||||
|
|
|
@ -239,7 +239,7 @@ struct file : inode, varint {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
auto end() -> bool {
|
auto end() const -> bool {
|
||||||
if(!fp) return true; //file not open
|
if(!fp) return true; //file not open
|
||||||
return file_offset >= file_size;
|
return file_offset >= file_size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <nall/vfs/vfs.hpp>
|
|
@ -0,0 +1,51 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <nall/file.hpp>
|
||||||
|
|
||||||
|
namespace nall { namespace vfs { namespace fs {
|
||||||
|
|
||||||
|
struct file : vfs::file {
|
||||||
|
static auto open(string location_, mode mode_) -> vfs::shared::file {
|
||||||
|
auto instance = shared_pointer<file>{new file};
|
||||||
|
if(!instance->_open(location_, mode_)) return {};
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto size() const -> uintmax override {
|
||||||
|
return _fp.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto offset() const -> uintmax override {
|
||||||
|
return _fp.offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto seek(intmax offset_, index index_) -> void override {
|
||||||
|
_fp.seek(offset_, (nall::file::index)index_);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto read() -> uint8_t override {
|
||||||
|
return _fp.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto write(uint8_t data_) -> void override {
|
||||||
|
_fp.write(data_);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto flush() -> void override {
|
||||||
|
_fp.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
file() = default;
|
||||||
|
file(const file&) = delete;
|
||||||
|
auto operator=(const file&) -> file& = delete;
|
||||||
|
|
||||||
|
auto _open(string location_, mode mode_) -> bool {
|
||||||
|
if(!_fp.open(location_, (nall::file::mode)mode_)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nall::file _fp;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}
|
|
@ -0,0 +1,48 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace nall { namespace vfs { namespace memory {
|
||||||
|
|
||||||
|
struct file : vfs::file {
|
||||||
|
~file() { delete[] _data; }
|
||||||
|
|
||||||
|
static auto open(const uint8_t* data, uintmax size) -> vfs::shared::file {
|
||||||
|
auto instance = shared_pointer<file>{new file};
|
||||||
|
instance->_open(data, size);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto size() const -> uintmax override { return _size; }
|
||||||
|
auto offset() const -> uintmax override { return _offset; }
|
||||||
|
|
||||||
|
auto seek(intmax offset, index mode) -> void override {
|
||||||
|
if(mode == index::absolute) _offset = (uintmax)offset;
|
||||||
|
if(mode == index::relative) _offset += (intmax)offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto read() -> uint8_t override {
|
||||||
|
if(_offset >= _size) return 0x00;
|
||||||
|
return _data[_offset++];
|
||||||
|
}
|
||||||
|
|
||||||
|
auto write(uint8_t data) -> void override {
|
||||||
|
if(_offset >= _size) return;
|
||||||
|
_data[_offset++] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
file() = default;
|
||||||
|
file(const file&) = delete;
|
||||||
|
auto operator=(const file&) -> file& = delete;
|
||||||
|
|
||||||
|
auto _open(const uint8_t* data, uintmax size) -> void {
|
||||||
|
_size = size;
|
||||||
|
_data = new uint8_t[size];
|
||||||
|
nall::memory::copy(_data, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* _data = nullptr;
|
||||||
|
uintmax _size = 0;
|
||||||
|
uintmax _offset = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}
|
|
@ -0,0 +1,71 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <nall/range.hpp>
|
||||||
|
#include <nall/shared-pointer.hpp>
|
||||||
|
|
||||||
|
namespace nall { namespace vfs {
|
||||||
|
|
||||||
|
struct file {
|
||||||
|
enum class mode : uint { read, write, modify, create };
|
||||||
|
enum class index : uint { absolute, relative };
|
||||||
|
|
||||||
|
virtual ~file() = default;
|
||||||
|
|
||||||
|
virtual auto size() const -> uintmax = 0;
|
||||||
|
virtual auto offset() const -> uintmax = 0;
|
||||||
|
|
||||||
|
virtual auto seek(intmax offset, index = index::absolute) -> void = 0;
|
||||||
|
virtual auto read() -> uint8_t = 0;
|
||||||
|
virtual auto write(uint8_t data) -> void = 0;
|
||||||
|
virtual auto flush() -> void {}
|
||||||
|
|
||||||
|
auto end() const -> bool {
|
||||||
|
return offset() >= size();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto read(uint8_t* data, uintmax bytes) -> void {
|
||||||
|
while(bytes--) *data++ = read();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto readl(uint bytes) -> uintmax {
|
||||||
|
uintmax data = 0;
|
||||||
|
for(auto n : range(bytes)) data |= (uintmax)read() << n * 8;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto readm(uint bytes) -> uintmax {
|
||||||
|
uintmax data = 0;
|
||||||
|
for(auto n : range(bytes)) data = data << 8 | read();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto reads(string& s) -> void {
|
||||||
|
s.resize(size());
|
||||||
|
read(s.get<uint8_t>(), s.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto write(const uint8_t* data, uintmax bytes) -> void {
|
||||||
|
while(bytes--) write(*data++);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto writel(uintmax data, uint bytes) -> void {
|
||||||
|
for(auto n : range(bytes)) write(data), data >>= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto writem(uintmax data, uint bytes) -> void {
|
||||||
|
for(auto n : rrange(bytes)) write(data >> n * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto writes(const string& s) -> void {
|
||||||
|
write(s.data<uint8_t>(), s.size());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
namespace nall { namespace vfs { namespace shared {
|
||||||
|
using file = shared_pointer<vfs::file>;
|
||||||
|
}}}
|
||||||
|
|
||||||
|
#include <nall/vfs/fs/file.hpp>
|
||||||
|
#include <nall/vfs/memory/file.hpp>
|
Loading…
Reference in New Issue