mirror of
https://github.com/libretro/bsnes-libretro.git
synced 2024-11-23 08:59:40 +00:00
Update to v099r15 release.
byuu says: Changelog: - nall::lstring -> nall::string_vector - added IntegerBitField<type, lo, hi> -- hopefully it works correctly... - Multitap 1-4 -> Super Multitap 2-5 - fixed SFC PPU CGRAM read regression - huge amounts of SFC PPU IO register cleanups -- .bits really is lovely - re-added the read/write(VRAM,OAM,CGRAM) helpers for the SFC PPU - but they're now optimized to the realities of the PPU (16-bit data sizes / no address parameter / where appropriate) - basically used to get the active-display overrides in a unified place; but also reduces duplicate code in (read,write)IO
This commit is contained in:
parent
82293c95ae
commit
8d5cc0c35e
@ -11,7 +11,7 @@ using namespace nall;
|
||||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "099.14";
|
||||
static const string Version = "099.15";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
@ -99,7 +99,7 @@ struct Interface {
|
||||
virtual auto unserialize(serializer&) -> bool = 0;
|
||||
|
||||
//cheat functions
|
||||
virtual auto cheatSet(const lstring& = lstring{}) -> void {}
|
||||
virtual auto cheatSet(const string_vector& = {}) -> void {}
|
||||
|
||||
//settings
|
||||
virtual auto cap(const string& name) -> bool { return false; }
|
||||
|
@ -163,12 +163,12 @@ auto Interface::unserialize(serializer& s) -> bool {
|
||||
return system.unserialize(s);
|
||||
}
|
||||
|
||||
auto Interface::cheatSet(const lstring& list) -> void {
|
||||
auto Interface::cheatSet(const string_vector& list) -> void {
|
||||
cheat.reset();
|
||||
for(auto& codeset : list) {
|
||||
lstring codes = codeset.split("+");
|
||||
auto codes = codeset.split("+");
|
||||
for(auto& code : codes) {
|
||||
lstring part = code.split("/");
|
||||
auto part = code.split("/");
|
||||
if(part.size() == 2) cheat.append(part[0].hex(), part[1].hex());
|
||||
if(part.size() == 3) cheat.append(part[0].hex(), part[1].hex(), part[2].hex());
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ struct Interface : Emulator::Interface {
|
||||
auto serialize() -> serializer override;
|
||||
auto unserialize(serializer&) -> bool override;
|
||||
|
||||
auto cheatSet(const lstring&) -> void override;
|
||||
auto cheatSet(const string_vector&) -> void override;
|
||||
|
||||
auto cap(const string& name) -> bool override;
|
||||
auto get(const string& name) -> any override;
|
||||
|
@ -162,12 +162,12 @@ auto Interface::unserialize(serializer& s) -> bool {
|
||||
return system.unserialize(s);
|
||||
}
|
||||
|
||||
auto Interface::cheatSet(const lstring& list) -> void {
|
||||
auto Interface::cheatSet(const string_vector& list) -> void {
|
||||
cheat.reset();
|
||||
for(auto& codeset : list) {
|
||||
lstring codes = codeset.split("+");
|
||||
auto codes = codeset.split("+");
|
||||
for(auto& code : codes) {
|
||||
lstring part = code.split("/");
|
||||
auto part = code.split("/");
|
||||
if(part.size() == 2) cheat.append(part[0].hex(), part[1].hex());
|
||||
if(part.size() == 3) cheat.append(part[0].hex(), part[1].hex(), part[2].hex());
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ struct Interface : Emulator::Interface {
|
||||
auto serialize() -> serializer override;
|
||||
auto unserialize(serializer&) -> bool override;
|
||||
|
||||
auto cheatSet(const lstring&) -> void override;
|
||||
auto cheatSet(const string_vector&) -> void override;
|
||||
|
||||
auto cap(const string& name) -> bool override;
|
||||
auto get(const string& name) -> any override;
|
||||
|
@ -3,9 +3,9 @@
|
||||
namespace SuperFamicom {
|
||||
|
||||
#include "gamepad/gamepad.cpp"
|
||||
#include "multitap/multitap.cpp"
|
||||
#include "mouse/mouse.cpp"
|
||||
#include "superscope/superscope.cpp"
|
||||
#include "super-multitap/super-multitap.cpp"
|
||||
#include "super-scope/super-scope.cpp"
|
||||
#include "justifier/justifier.cpp"
|
||||
|
||||
Controller::Controller(bool port) : port(port) {
|
||||
|
@ -28,7 +28,7 @@ struct Controller : Cothread {
|
||||
};
|
||||
|
||||
#include "gamepad/gamepad.hpp"
|
||||
#include "multitap/multitap.hpp"
|
||||
#include "mouse/mouse.hpp"
|
||||
#include "superscope/superscope.hpp"
|
||||
#include "super-multitap/super-multitap.hpp"
|
||||
#include "super-scope/super-scope.hpp"
|
||||
#include "justifier/justifier.hpp"
|
||||
|
@ -1,70 +0,0 @@
|
||||
Multitap::Multitap(bool port) : Controller(port) {
|
||||
latched = 0;
|
||||
counter1 = 0;
|
||||
counter2 = 0;
|
||||
}
|
||||
|
||||
auto Multitap::data() -> uint2 {
|
||||
if(latched) return 2; //multitap detection
|
||||
uint counter, a, b;
|
||||
|
||||
if(iobit()) {
|
||||
counter = counter1;
|
||||
if(counter >= 16) return 3;
|
||||
counter1++;
|
||||
if(counter >= 12) return 0;
|
||||
a = 0; //controller 1
|
||||
b = 1; //controller 2
|
||||
} else {
|
||||
counter = counter2;
|
||||
if(counter >= 16) return 3;
|
||||
counter2++;
|
||||
if(counter >= 12) return 0;
|
||||
a = 2; //controller 3
|
||||
b = 3; //controller 4
|
||||
}
|
||||
|
||||
auto& A = gamepads[a];
|
||||
auto& B = gamepads[b];
|
||||
|
||||
switch(counter) {
|
||||
case 0: return A.b << 0 | B.b << 1;
|
||||
case 1: return A.y << 0 | B.y << 1;
|
||||
case 2: return A.select << 0 | B.select << 1;
|
||||
case 3: return A.start << 0 | B.start << 1;
|
||||
case 4: return (A.up & !A.down) << 0 | (B.up & !B.down) << 1;
|
||||
case 5: return (A.down & !A.up) << 0 | (B.down & !B.up) << 1;
|
||||
case 6: return (A.left & !A.right) << 0 | (B.left & !B.right) << 1;
|
||||
case 7: return (A.right & !A.left) << 0 | (B.right & !B.left) << 1;
|
||||
case 8: return A.a << 0 | B.a << 1;
|
||||
case 9: return A.x << 0 | B.x << 1;
|
||||
case 10: return A.l << 0 | B.l << 1;
|
||||
case 11: return A.r << 0 | B.r << 1;
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
|
||||
auto Multitap::latch(bool data) -> void {
|
||||
if(latched == data) return;
|
||||
latched = data;
|
||||
counter1 = 0;
|
||||
counter2 = 0;
|
||||
|
||||
if(latched == 0) {
|
||||
for(uint id : range(4)) {
|
||||
auto& gamepad = gamepads[id];
|
||||
gamepad.b = interface->inputPoll(port, ID::Device::Multitap, id * 12 + B);
|
||||
gamepad.y = interface->inputPoll(port, ID::Device::Multitap, id * 12 + Y);
|
||||
gamepad.select = interface->inputPoll(port, ID::Device::Multitap, id * 12 + Select);
|
||||
gamepad.start = interface->inputPoll(port, ID::Device::Multitap, id * 12 + Start);
|
||||
gamepad.up = interface->inputPoll(port, ID::Device::Multitap, id * 12 + Up);
|
||||
gamepad.down = interface->inputPoll(port, ID::Device::Multitap, id * 12 + Down);
|
||||
gamepad.left = interface->inputPoll(port, ID::Device::Multitap, id * 12 + Left);
|
||||
gamepad.right = interface->inputPoll(port, ID::Device::Multitap, id * 12 + Right);
|
||||
gamepad.a = interface->inputPoll(port, ID::Device::Multitap, id * 12 + A);
|
||||
gamepad.x = interface->inputPoll(port, ID::Device::Multitap, id * 12 + X);
|
||||
gamepad.l = interface->inputPoll(port, ID::Device::Multitap, id * 12 + L);
|
||||
gamepad.r = interface->inputPoll(port, ID::Device::Multitap, id * 12 + R);
|
||||
}
|
||||
}
|
||||
}
|
70
higan/sfc/controller/super-multitap/super-multitap.cpp
Normal file
70
higan/sfc/controller/super-multitap/super-multitap.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
SuperMultitap::SuperMultitap(bool port) : Controller(port) {
|
||||
latched = 0;
|
||||
counter1 = 0;
|
||||
counter2 = 0;
|
||||
}
|
||||
|
||||
auto SuperMultitap::data() -> uint2 {
|
||||
if(latched) return 2; //device detection
|
||||
uint counter, a, b;
|
||||
|
||||
if(iobit()) {
|
||||
counter = counter1;
|
||||
if(counter >= 16) return 3;
|
||||
counter1++;
|
||||
if(counter >= 12) return 0;
|
||||
a = 0; //controller 2
|
||||
b = 1; //controller 3
|
||||
} else {
|
||||
counter = counter2;
|
||||
if(counter >= 16) return 3;
|
||||
counter2++;
|
||||
if(counter >= 12) return 0;
|
||||
a = 2; //controller 4
|
||||
b = 3; //controller 5
|
||||
}
|
||||
|
||||
auto& A = gamepads[a];
|
||||
auto& B = gamepads[b];
|
||||
|
||||
switch(counter) {
|
||||
case 0: return A.b << 0 | B.b << 1;
|
||||
case 1: return A.y << 0 | B.y << 1;
|
||||
case 2: return A.select << 0 | B.select << 1;
|
||||
case 3: return A.start << 0 | B.start << 1;
|
||||
case 4: return (A.up & !A.down) << 0 | (B.up & !B.down) << 1;
|
||||
case 5: return (A.down & !A.up) << 0 | (B.down & !B.up) << 1;
|
||||
case 6: return (A.left & !A.right) << 0 | (B.left & !B.right) << 1;
|
||||
case 7: return (A.right & !A.left) << 0 | (B.right & !B.left) << 1;
|
||||
case 8: return A.a << 0 | B.a << 1;
|
||||
case 9: return A.x << 0 | B.x << 1;
|
||||
case 10: return A.l << 0 | B.l << 1;
|
||||
case 11: return A.r << 0 | B.r << 1;
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
|
||||
auto SuperMultitap::latch(bool data) -> void {
|
||||
if(latched == data) return;
|
||||
latched = data;
|
||||
counter1 = 0;
|
||||
counter2 = 0;
|
||||
|
||||
if(latched == 0) {
|
||||
for(uint id : range(4)) {
|
||||
auto& gamepad = gamepads[id];
|
||||
gamepad.b = interface->inputPoll(port, ID::Device::SuperMultitap, id * 12 + B);
|
||||
gamepad.y = interface->inputPoll(port, ID::Device::SuperMultitap, id * 12 + Y);
|
||||
gamepad.select = interface->inputPoll(port, ID::Device::SuperMultitap, id * 12 + Select);
|
||||
gamepad.start = interface->inputPoll(port, ID::Device::SuperMultitap, id * 12 + Start);
|
||||
gamepad.up = interface->inputPoll(port, ID::Device::SuperMultitap, id * 12 + Up);
|
||||
gamepad.down = interface->inputPoll(port, ID::Device::SuperMultitap, id * 12 + Down);
|
||||
gamepad.left = interface->inputPoll(port, ID::Device::SuperMultitap, id * 12 + Left);
|
||||
gamepad.right = interface->inputPoll(port, ID::Device::SuperMultitap, id * 12 + Right);
|
||||
gamepad.a = interface->inputPoll(port, ID::Device::SuperMultitap, id * 12 + A);
|
||||
gamepad.x = interface->inputPoll(port, ID::Device::SuperMultitap, id * 12 + X);
|
||||
gamepad.l = interface->inputPoll(port, ID::Device::SuperMultitap, id * 12 + L);
|
||||
gamepad.r = interface->inputPoll(port, ID::Device::SuperMultitap, id * 12 + R);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
struct Multitap : Controller {
|
||||
struct SuperMultitap : Controller {
|
||||
enum : uint {
|
||||
Up, Down, Left, Right, B, A, Y, X, L, R, Select, Start,
|
||||
};
|
||||
|
||||
Multitap(bool port);
|
||||
SuperMultitap(bool port);
|
||||
|
||||
auto data() -> uint2;
|
||||
auto latch(bool data) -> void;
|
@ -29,7 +29,7 @@ private:
|
||||
function<uint8 ()>, //read
|
||||
function<void (uint8)> //write
|
||||
)> linkInit;
|
||||
function<void (lstring)> linkMain;
|
||||
function<void (string_vector)> linkMain;
|
||||
|
||||
vector<uint8> snesBuffer; //SNES -> Link
|
||||
vector<uint8> linkBuffer; //Link -> SNES
|
||||
|
@ -49,8 +49,17 @@ Interface::Interface() {
|
||||
controllerPort2.devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{ID::Device::Multitap, "Multitap"};
|
||||
for(uint p = 1; p <= 4; p++) {
|
||||
{ Device device{ID::Device::Mouse, "Mouse"};
|
||||
device.inputs.append({1, "X-axis"});
|
||||
device.inputs.append({1, "Y-axis"});
|
||||
device.inputs.append({0, "Left" });
|
||||
device.inputs.append({0, "Right" });
|
||||
controllerPort1.devices.append(device);
|
||||
controllerPort2.devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{ID::Device::SuperMultitap, "Super Multitap"};
|
||||
for(uint p = 2; p <= 5; p++) {
|
||||
device.inputs.append({0, {"Port ", p, " - ", "Up" }});
|
||||
device.inputs.append({0, {"Port ", p, " - ", "Down" }});
|
||||
device.inputs.append({0, {"Port ", p, " - ", "Left" }});
|
||||
@ -64,16 +73,6 @@ Interface::Interface() {
|
||||
device.inputs.append({0, {"Port ", p, " - ", "Select"}});
|
||||
device.inputs.append({0, {"Port ", p, " - ", "Start" }});
|
||||
}
|
||||
//controllerPort1.devices.append(device); //not used by any commercial software (only homebrew)
|
||||
controllerPort2.devices.append(device);
|
||||
}
|
||||
|
||||
{ Device device{ID::Device::Mouse, "Mouse"};
|
||||
device.inputs.append({1, "X-axis"});
|
||||
device.inputs.append({1, "Y-axis"});
|
||||
device.inputs.append({0, "Left" });
|
||||
device.inputs.append({0, "Right" });
|
||||
controllerPort1.devices.append(device);
|
||||
controllerPort2.devices.append(device);
|
||||
}
|
||||
|
||||
@ -234,16 +233,16 @@ auto Interface::unserialize(serializer& s) -> bool {
|
||||
return system.unserialize(s);
|
||||
}
|
||||
|
||||
auto Interface::cheatSet(const lstring& list) -> void {
|
||||
auto Interface::cheatSet(const string_vector& list) -> void {
|
||||
cheat.reset();
|
||||
|
||||
#if defined(SFC_SUPERGAMEBOY)
|
||||
if(cartridge.has.ICD2) {
|
||||
GameBoy::cheat.reset();
|
||||
for(auto& codeset : list) {
|
||||
lstring codes = codeset.split("+");
|
||||
auto codes = codeset.split("+");
|
||||
for(auto& code : codes) {
|
||||
lstring part = code.split("/");
|
||||
auto part = code.split("/");
|
||||
if(part.size() == 2) GameBoy::cheat.append(part[0].hex(), part[1].hex());
|
||||
if(part.size() == 3) GameBoy::cheat.append(part[0].hex(), part[1].hex(), part[2].hex());
|
||||
}
|
||||
@ -253,9 +252,9 @@ auto Interface::cheatSet(const lstring& list) -> void {
|
||||
#endif
|
||||
|
||||
for(auto& codeset : list) {
|
||||
lstring codes = codeset.split("+");
|
||||
auto codes = codeset.split("+");
|
||||
for(auto& code : codes) {
|
||||
lstring part = code.split("/");
|
||||
auto part = code.split("/");
|
||||
if(part.size() == 2) cheat.append(part[0].hex(), part[1].hex());
|
||||
if(part.size() == 3) cheat.append(part[0].hex(), part[1].hex(), part[2].hex());
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ struct ID {
|
||||
struct Device { enum : uint {
|
||||
None,
|
||||
Gamepad,
|
||||
Multitap,
|
||||
Mouse,
|
||||
SuperMultitap,
|
||||
SuperScope,
|
||||
Justifier,
|
||||
Justifiers,
|
||||
@ -60,7 +60,7 @@ struct Interface : Emulator::Interface {
|
||||
auto serialize() -> serializer override;
|
||||
auto unserialize(serializer&) -> bool override;
|
||||
|
||||
auto cheatSet(const lstring&) -> void override;
|
||||
auto cheatSet(const string_vector&) -> void override;
|
||||
|
||||
auto cap(const string& name) -> bool override;
|
||||
auto get(const string& name) -> any override;
|
||||
|
@ -1,4 +1,4 @@
|
||||
auto PPU::getVramAddress() -> uint16 {
|
||||
auto PPU::addressVRAM() const -> uint16 {
|
||||
uint16 address = io.vramAddress;
|
||||
switch(io.vramMapping) {
|
||||
case 0: return (address);
|
||||
@ -9,14 +9,42 @@ auto PPU::getVramAddress() -> uint16 {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
auto PPU::vramAccessible() const -> bool {
|
||||
return io.displayDisable || vcounter() >= vdisp();
|
||||
auto PPU::readVRAM() -> uint16 {
|
||||
if(!io.displayDisable && vcounter() < vdisp()) return 0x0000;
|
||||
return vram[addressVRAM()];
|
||||
}
|
||||
|
||||
auto PPU::oamWrite(uint addr, uint8 data) -> void {
|
||||
auto PPU::writeVRAM(bool byte, uint8 data) -> void {
|
||||
if(!io.displayDisable && vcounter() < vdisp()) return;
|
||||
vram[addressVRAM()].byte(byte) = data;
|
||||
}
|
||||
|
||||
auto PPU::readOAM(uint10 addr) -> uint8 {
|
||||
if(!io.displayDisable && vcounter() < vdisp()) addr = latch.oamAddress;
|
||||
return obj.oam.read(addr);
|
||||
}
|
||||
|
||||
auto PPU::writeOAM(uint10 addr, uint8 data) -> void {
|
||||
if(!io.displayDisable && vcounter() < vdisp()) addr = latch.oamAddress;
|
||||
obj.oam.write(addr, data);
|
||||
}
|
||||
|
||||
auto PPU::readCGRAM(bool byte, uint8 addr) -> uint8 {
|
||||
if(!io.displayDisable
|
||||
&& vcounter() > 0 && vcounter() < vdisp()
|
||||
&& hcounter() >= 88 && hcounter() < 1096
|
||||
) addr = latch.cgramAddress;
|
||||
return screen.cgram[addr].byte(byte);
|
||||
}
|
||||
|
||||
auto PPU::writeCGRAM(uint8 addr, uint16 data) -> void {
|
||||
if(!io.displayDisable
|
||||
&& vcounter() > 0 && vcounter() < vdisp()
|
||||
&& hcounter() >= 88 && hcounter() < 1096
|
||||
) addr = latch.cgramAddress;
|
||||
screen.cgram[addr] = data;
|
||||
}
|
||||
|
||||
auto PPU::readIO(uint24 addr, uint8 data) -> uint8 {
|
||||
cpu.synchronizePPU();
|
||||
|
||||
@ -32,47 +60,40 @@ auto PPU::readIO(uint24 addr, uint8 data) -> uint8 {
|
||||
|
||||
//MPYL
|
||||
case 0x2134: {
|
||||
uint result = (int16)io.m7a * (int8)(io.m7b >> 8);
|
||||
ppu1.mdr = (result >> 0);
|
||||
return ppu1.mdr;
|
||||
uint24 result = (int16)io.m7a * (int8)(io.m7b >> 8);
|
||||
return ppu1.mdr = result.byte(0);
|
||||
}
|
||||
|
||||
//MPYM
|
||||
case 0x2135: {
|
||||
uint result = (int16)io.m7a * (int8)(io.m7b >> 8);
|
||||
ppu1.mdr = (result >> 8);
|
||||
return ppu1.mdr;
|
||||
uint24 result = (int16)io.m7a * (int8)(io.m7b >> 8);
|
||||
return ppu1.mdr = result.byte(1);
|
||||
}
|
||||
|
||||
//MPYH
|
||||
case 0x2136: {
|
||||
uint result = (int16)io.m7a * (int8)(io.m7b >> 8);
|
||||
ppu1.mdr = (result >> 16);
|
||||
return ppu1.mdr;
|
||||
uint24 result = (int16)io.m7a * (int8)(io.m7b >> 8);
|
||||
return ppu1.mdr = result.byte(2);
|
||||
}
|
||||
|
||||
//SLHV
|
||||
case 0x2137: {
|
||||
if(cpu.pio() & 0x80) latchCounters();
|
||||
if(cpu.pio().bit(7)) latchCounters();
|
||||
return data; //CPU MDR
|
||||
}
|
||||
|
||||
//OAMDATAREAD
|
||||
case 0x2138: {
|
||||
uint10 address = io.oamAddress++;
|
||||
if(!io.displayDisable && vcounter() < vdisp()) address = latch.oamAddress;
|
||||
if(address & 0x0200) address &= 0x021f;
|
||||
|
||||
ppu1.mdr = obj.oam.read(address);
|
||||
ppu1.mdr = readOAM(io.oamAddress++);
|
||||
obj.setFirstSprite();
|
||||
return ppu1.mdr;
|
||||
}
|
||||
|
||||
//VMDATALREAD
|
||||
case 0x2139: {
|
||||
ppu1.mdr = latch.vram >> 0;
|
||||
ppu1.mdr = latch.vram.byte(0);
|
||||
if(io.vramIncrementMode == 0) {
|
||||
latch.vram = vramAccessible() ? vram[getVramAddress()] : (uint16)0;
|
||||
latch.vram = readVRAM();
|
||||
io.vramAddress += io.vramIncrementSize;
|
||||
}
|
||||
return ppu1.mdr;
|
||||
@ -80,9 +101,9 @@ auto PPU::readIO(uint24 addr, uint8 data) -> uint8 {
|
||||
|
||||
//VMDATAHREAD
|
||||
case 0x213a: {
|
||||
ppu1.mdr = latch.vram >> 8;
|
||||
ppu1.mdr = latch.vram.byte(1);
|
||||
if(io.vramIncrementMode == 1) {
|
||||
latch.vram = vramAccessible() ? vram[getVramAddress()] : (uint16)0;
|
||||
latch.vram = readVRAM();
|
||||
io.vramAddress += io.vramIncrementSize;
|
||||
}
|
||||
return ppu1.mdr;
|
||||
@ -90,51 +111,40 @@ auto PPU::readIO(uint24 addr, uint8 data) -> uint8 {
|
||||
|
||||
//CGDATAREAD
|
||||
case 0x213b: {
|
||||
auto address = io.cgramAddress;
|
||||
if(!io.displayDisable
|
||||
&& vcounter() > 0 && vcounter() < vdisp()
|
||||
&& hcounter() >= 88 && hcounter() < 1096
|
||||
) address = latch.cgramAddress;
|
||||
|
||||
if(io.cgramAddressLatch++) {
|
||||
ppu2.mdr = screen.cgram[address].byte(0);
|
||||
if(io.cgramAddressLatch++ == 0) {
|
||||
ppu2.mdr.bits(0,7) = readCGRAM(0, io.cgramAddress);
|
||||
} else {
|
||||
ppu2.mdr &= 0x80;
|
||||
ppu2.mdr |= screen.cgram[address].byte(1);
|
||||
ppu2.mdr.bits(0,6) = readCGRAM(1, io.cgramAddress++);
|
||||
}
|
||||
return ppu2.mdr;
|
||||
}
|
||||
|
||||
//OPHCT
|
||||
case 0x213c: {
|
||||
if(latch.hcounter == 0) {
|
||||
ppu2.mdr = (io.hcounter >> 0);
|
||||
if(latch.hcounter++ == 0) {
|
||||
ppu2.mdr.bits(0,7) = io.hcounter.bits(0,7);
|
||||
} else {
|
||||
ppu2.mdr &= 0xfe;
|
||||
ppu2.mdr |= (io.hcounter >> 8) & 1;
|
||||
ppu2.mdr.bit (0 ) = io.hcounter.bit ( 8);
|
||||
}
|
||||
latch.hcounter ^= 1;
|
||||
return ppu2.mdr;
|
||||
}
|
||||
|
||||
//OPVCT
|
||||
case 0x213d: {
|
||||
if(latch.vcounter == 0) {
|
||||
ppu2.mdr = (io.vcounter >> 0);
|
||||
if(latch.vcounter++ == 0) {
|
||||
ppu2.mdr.bits(0,7) = io.vcounter.bits(0,7);
|
||||
} else {
|
||||
ppu2.mdr &= 0xfe;
|
||||
ppu2.mdr |= (io.vcounter >> 8) & 1;
|
||||
ppu2.mdr.bit (0 ) = io.vcounter.bit ( 8);
|
||||
}
|
||||
latch.vcounter ^= 1;
|
||||
return ppu2.mdr;
|
||||
}
|
||||
|
||||
//STAT77
|
||||
case 0x213e: {
|
||||
ppu1.mdr &= 0x10;
|
||||
ppu1.mdr |= obj.io.timeOver << 7;
|
||||
ppu1.mdr |= obj.io.rangeOver << 6;
|
||||
ppu1.mdr |= ppu1.version & 0x0f;
|
||||
ppu1.mdr.bits(0,3) = ppu1.version;
|
||||
ppu1.mdr.bit ( 5) = 0;
|
||||
ppu1.mdr.bit ( 6) = obj.io.rangeOver;
|
||||
ppu1.mdr.bit ( 7) = obj.io.timeOver;
|
||||
return ppu1.mdr;
|
||||
}
|
||||
|
||||
@ -143,16 +153,15 @@ auto PPU::readIO(uint24 addr, uint8 data) -> uint8 {
|
||||
latch.hcounter = 0;
|
||||
latch.vcounter = 0;
|
||||
|
||||
ppu2.mdr &= 0x20;
|
||||
ppu2.mdr |= field() << 7;
|
||||
if((cpu.pio() & 0x80) == 0) {
|
||||
ppu2.mdr |= 0x40;
|
||||
} else if(latch.counters) {
|
||||
ppu2.mdr |= 0x40;
|
||||
latch.counters = false;
|
||||
ppu2.mdr.bits(0,3) = ppu2.version;
|
||||
ppu2.mdr.bit ( 4) = system.region() == System::Region::PAL; //0 = NTSC
|
||||
if(!cpu.pio().bit(7)) {
|
||||
ppu2.mdr.bit( 6) = 1;
|
||||
} else {
|
||||
ppu2.mdr.bit( 6) = latch.counters;
|
||||
latch.counters = 0;
|
||||
}
|
||||
ppu2.mdr |= (system.region() == System::Region::NTSC ? 0 : 1) << 4;
|
||||
ppu2.mdr |= ppu2.version & 0x0f;
|
||||
ppu2.mdr.bit ( 7) = field();
|
||||
return ppu2.mdr;
|
||||
}
|
||||
|
||||
@ -191,25 +200,23 @@ auto PPU::writeIO(uint24 addr, uint8 data) -> void {
|
||||
|
||||
//OAMADDH
|
||||
case 0x2103: {
|
||||
io.oamPriority = data & 0x80;
|
||||
io.oamBaseAddress = ((data & 0x01) << 9) | (io.oamBaseAddress & 0x01fe);
|
||||
io.oamBaseAddress = data.bit(0) << 9 | (io.oamBaseAddress & 0x01fe);
|
||||
io.oamPriority = data.bit(7);
|
||||
obj.addressReset();
|
||||
return;
|
||||
}
|
||||
|
||||
//OAMDATA
|
||||
case 0x2104: {
|
||||
bool l = io.oamAddress & 1;
|
||||
bool latchBit = io.oamAddress & 1;
|
||||
uint10 address = io.oamAddress++;
|
||||
if(!io.displayDisable && vcounter() < vdisp()) address = latch.oamAddress;
|
||||
if(address & 0x0200) address &= 0x021f;
|
||||
|
||||
if(l == 0) latch.oam = data;
|
||||
if(address & 0x0200) {
|
||||
oamWrite(address, data);
|
||||
} else if(l == 1) {
|
||||
oamWrite((address & ~1) + 0, latch.oam);
|
||||
oamWrite((address & ~1) + 1, data);
|
||||
if(latchBit == 0) latch.oam = data;
|
||||
if(address.bit(9)) {
|
||||
writeOAM(address, data);
|
||||
} else if(latchBit == 1) {
|
||||
writeOAM((address & ~1) + 0, latch.oam);
|
||||
writeOAM((address & ~1) + 1, data);
|
||||
}
|
||||
obj.setFirstSprite();
|
||||
return;
|
||||
@ -218,11 +225,11 @@ auto PPU::writeIO(uint24 addr, uint8 data) -> void {
|
||||
//BGMODE
|
||||
case 0x2105: {
|
||||
io.bgMode = data.bits(0,2);
|
||||
io.bgPriority = data.bit (3);
|
||||
bg1.io.tileSize = data.bit (4);
|
||||
bg2.io.tileSize = data.bit (5);
|
||||
bg3.io.tileSize = data.bit (6);
|
||||
bg4.io.tileSize = data.bit (7);
|
||||
io.bgPriority = data.bit ( 3);
|
||||
bg1.io.tileSize = data.bit ( 4);
|
||||
bg2.io.tileSize = data.bit ( 5);
|
||||
bg3.io.tileSize = data.bit ( 6);
|
||||
bg4.io.tileSize = data.bit ( 7);
|
||||
updateVideoMode();
|
||||
return;
|
||||
}
|
||||
@ -281,62 +288,62 @@ auto PPU::writeIO(uint24 addr, uint8 data) -> void {
|
||||
|
||||
//BG1HOFS
|
||||
case 0x210d: {
|
||||
io.hoffsetMode7 = (data << 8) | latch.mode7;
|
||||
io.hoffsetMode7 = data << 8 | latch.mode7;
|
||||
latch.mode7 = data;
|
||||
|
||||
bg1.io.hoffset = (data << 8) | (latch.bgofs & ~7) | ((bg1.io.hoffset >> 8) & 7);
|
||||
bg1.io.hoffset = data << 8 | (latch.bgofs & ~7) | (bg1.io.hoffset >> 8 & 7);
|
||||
latch.bgofs = data;
|
||||
return;
|
||||
}
|
||||
|
||||
//BG1VOFS
|
||||
case 0x210e: {
|
||||
io.voffsetMode7 = (data << 8) | latch.mode7;
|
||||
io.voffsetMode7 = data << 8 | latch.mode7;
|
||||
latch.mode7 = data;
|
||||
|
||||
bg1.io.voffset = (data << 8) | latch.bgofs;
|
||||
bg1.io.voffset = data << 8 | latch.bgofs;
|
||||
latch.bgofs = data;
|
||||
return;
|
||||
}
|
||||
|
||||
//BG2HOFS
|
||||
case 0x210f: {
|
||||
bg2.io.hoffset = (data << 8) | (latch.bgofs & ~7) | ((bg2.io.hoffset >> 8) & 7);
|
||||
bg2.io.hoffset = data << 8 | (latch.bgofs & ~7) | (bg2.io.hoffset >> 8 & 7);
|
||||
latch.bgofs = data;
|
||||
return;
|
||||
}
|
||||
|
||||
//BG2VOFS
|
||||
case 0x2110: {
|
||||
bg2.io.voffset = (data << 8) | latch.bgofs;
|
||||
bg2.io.voffset = data << 8 | latch.bgofs;
|
||||
latch.bgofs = data;
|
||||
return;
|
||||
}
|
||||
|
||||
//BG3HOFS
|
||||
case 0x2111: {
|
||||
bg3.io.hoffset = (data << 8) | (latch.bgofs & ~7) | ((bg3.io.hoffset >> 8) & 7);
|
||||
bg3.io.hoffset = data << 8 | (latch.bgofs & ~7) | (bg3.io.hoffset >> 8 & 7);
|
||||
latch.bgofs = data;
|
||||
return;
|
||||
}
|
||||
|
||||
//BG3VOFS
|
||||
case 0x2112: {
|
||||
bg3.io.voffset = (data << 8) | latch.bgofs;
|
||||
bg3.io.voffset = data << 8 | latch.bgofs;
|
||||
latch.bgofs = data;
|
||||
return;
|
||||
}
|
||||
|
||||
//BG4HOFS
|
||||
case 0x2113: {
|
||||
bg4.io.hoffset = (data << 8) | (latch.bgofs & ~7) | ((bg4.io.hoffset >> 8) & 7);
|
||||
bg4.io.hoffset = data << 8 | (latch.bgofs & ~7) | (bg4.io.hoffset >> 8 & 7);
|
||||
latch.bgofs = data;
|
||||
return;
|
||||
}
|
||||
|
||||
//BG4VOFS
|
||||
case 0x2114: {
|
||||
bg4.io.voffset = (data << 8) | latch.bgofs;
|
||||
bg4.io.voffset = data << 8 | latch.bgofs;
|
||||
latch.bgofs = data;
|
||||
return;
|
||||
}
|
||||
@ -346,42 +353,42 @@ auto PPU::writeIO(uint24 addr, uint8 data) -> void {
|
||||
static const uint size[4] = {1, 32, 128, 128};
|
||||
io.vramIncrementSize = size[data.bits(0,1)];
|
||||
io.vramMapping = data.bits(2,3);
|
||||
io.vramIncrementMode = data.bit (7);
|
||||
io.vramIncrementMode = data.bit ( 7);
|
||||
return;
|
||||
}
|
||||
|
||||
//VMADDL
|
||||
case 0x2116: {
|
||||
io.vramAddress.byte(0) = data;
|
||||
latch.vram = vramAccessible() ? vram[getVramAddress()] : (uint16)0;
|
||||
latch.vram = readVRAM();
|
||||
return;
|
||||
}
|
||||
|
||||
//VMADDH
|
||||
case 0x2117: {
|
||||
io.vramAddress.byte(1) = data;
|
||||
latch.vram = vramAccessible() ? vram[getVramAddress()] : (uint16)0;
|
||||
latch.vram = readVRAM();
|
||||
return;
|
||||
}
|
||||
|
||||
//VMDATAL
|
||||
case 0x2118: {
|
||||
if(vramAccessible()) vram[getVramAddress()].byte(0) = data;
|
||||
writeVRAM(0, data);
|
||||
if(io.vramIncrementMode == 0) io.vramAddress += io.vramIncrementSize;
|
||||
return;
|
||||
}
|
||||
|
||||
//VMDATAH
|
||||
case 0x2119: {
|
||||
if(vramAccessible()) vram[getVramAddress()].byte(1) = data;
|
||||
writeVRAM(1, data);
|
||||
if(io.vramIncrementMode == 1) io.vramAddress += io.vramIncrementSize;
|
||||
return;
|
||||
}
|
||||
|
||||
//M7SEL
|
||||
case 0x211a: {
|
||||
io.hflipMode7 = data.bit (0);
|
||||
io.vflipMode7 = data.bit (1);
|
||||
io.hflipMode7 = data.bit ( 0);
|
||||
io.vflipMode7 = data.bit ( 1);
|
||||
io.repeatMode7 = data.bits(6,7);
|
||||
return;
|
||||
}
|
||||
@ -437,17 +444,10 @@ auto PPU::writeIO(uint24 addr, uint8 data) -> void {
|
||||
|
||||
//CGDATA
|
||||
case 0x2122: {
|
||||
auto address = io.cgramAddress;
|
||||
if(!io.displayDisable
|
||||
&& vcounter() > 0 && vcounter() < vdisp()
|
||||
&& hcounter() >= 88 && hcounter() < 1096
|
||||
) address = latch.cgramAddress;
|
||||
|
||||
if(io.cgramAddressLatch++ == 0) {
|
||||
latch.cgram = data;
|
||||
} else {
|
||||
screen.cgram[address] = data.bits(0,6) << 8 | latch.cgram;
|
||||
io.cgramAddress++;
|
||||
writeCGRAM(io.cgramAddress++, data.bits(0,6) << 8 | latch.cgram);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -573,8 +573,8 @@ auto PPU::writeIO(uint24 addr, uint8 data) -> void {
|
||||
|
||||
//CGWSEL
|
||||
case 0x2130: {
|
||||
screen.io.directColor = data.bit (0);
|
||||
screen.io.blendMode = data.bit (1);
|
||||
screen.io.directColor = data.bit ( 0);
|
||||
screen.io.blendMode = data.bit ( 1);
|
||||
window.io.col.belowMask = data.bits(4,5);
|
||||
window.io.col.aboveMask = data.bits(6,7);
|
||||
return;
|
||||
@ -619,7 +619,7 @@ auto PPU::latchCounters() -> void {
|
||||
cpu.synchronizePPU();
|
||||
io.hcounter = hdot();
|
||||
io.vcounter = vcounter();
|
||||
latch.counters = true;
|
||||
latch.counters = 1;
|
||||
}
|
||||
|
||||
auto PPU::updateVideoMode() -> void {
|
||||
|
@ -18,9 +18,13 @@ struct PPU : Thread, PPUcounter {
|
||||
auto serialize(serializer&) -> void;
|
||||
|
||||
//io.cpp
|
||||
alwaysinline auto getVramAddress() -> uint16;
|
||||
alwaysinline auto vramAccessible() const -> bool;
|
||||
alwaysinline auto oamWrite(uint addr, uint8 data) -> void;
|
||||
alwaysinline auto addressVRAM() const -> uint16;
|
||||
alwaysinline auto readVRAM() -> uint16;
|
||||
alwaysinline auto writeVRAM(bool byte, uint8 data) -> void;
|
||||
alwaysinline auto readOAM(uint10 addr) -> uint8;
|
||||
alwaysinline auto writeOAM(uint10 addr, uint8 data) -> void;
|
||||
alwaysinline auto readCGRAM(bool byte, uint8 addr) -> uint8;
|
||||
alwaysinline auto writeCGRAM(uint8 addr, uint16 data) -> void;
|
||||
auto readIO(uint24 addr, uint8 data) -> uint8;
|
||||
auto writeIO(uint24 addr, uint8 data) -> void;
|
||||
auto latchCounters() -> void;
|
||||
@ -28,7 +32,7 @@ struct PPU : Thread, PPUcounter {
|
||||
|
||||
privileged:
|
||||
struct VRAM {
|
||||
auto& operator[](uint offset) { return data[offset & mask]; }
|
||||
auto& operator[](uint addr) { return data[addr & mask]; }
|
||||
uint16 data[64 * 1024];
|
||||
uint mask = 0x7fff;
|
||||
} vram;
|
||||
@ -55,9 +59,9 @@ privileged:
|
||||
uint8 cgram;
|
||||
uint8 bgofs;
|
||||
uint8 mode7;
|
||||
bool counters;
|
||||
bool hcounter;
|
||||
bool vcounter;
|
||||
uint1 counters;
|
||||
uint1 hcounter;
|
||||
uint1 vcounter;
|
||||
|
||||
uint10 oamAddress;
|
||||
uint8 cgramAddress;
|
||||
|
@ -22,10 +22,9 @@ auto Peripherals::connect(uint port, uint device) -> void {
|
||||
|
||||
delete controllerPort1;
|
||||
switch(device) { default:
|
||||
case ID::Device::None: controllerPort1 = new Controller(0); break;
|
||||
case ID::Device::Gamepad: controllerPort1 = new Gamepad(0); break;
|
||||
case ID::Device::Multitap: controllerPort1 = new Multitap(0); break;
|
||||
case ID::Device::Mouse: controllerPort1 = new Mouse(0); break;
|
||||
case ID::Device::None: controllerPort1 = new Controller(0); break;
|
||||
case ID::Device::Gamepad: controllerPort1 = new Gamepad(0); break;
|
||||
case ID::Device::Mouse: controllerPort1 = new Mouse(0); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,13 +34,13 @@ auto Peripherals::connect(uint port, uint device) -> void {
|
||||
|
||||
delete controllerPort2;
|
||||
switch(device) { default:
|
||||
case ID::Device::None: controllerPort2 = new Controller(1); break;
|
||||
case ID::Device::Gamepad: controllerPort2 = new Gamepad(1); break;
|
||||
case ID::Device::Multitap: controllerPort2 = new Multitap(1); break;
|
||||
case ID::Device::Mouse: controllerPort2 = new Mouse(1); break;
|
||||
case ID::Device::SuperScope: controllerPort2 = new SuperScope(1); break;
|
||||
case ID::Device::Justifier: controllerPort2 = new Justifier(1, false); break;
|
||||
case ID::Device::Justifiers: controllerPort2 = new Justifier(1, true); break;
|
||||
case ID::Device::None: controllerPort2 = new Controller(1); break;
|
||||
case ID::Device::Gamepad: controllerPort2 = new Gamepad(1); break;
|
||||
case ID::Device::Mouse: controllerPort2 = new Mouse(1); break;
|
||||
case ID::Device::SuperMultitap: controllerPort2 = new SuperMultitap(1); break;
|
||||
case ID::Device::SuperScope: controllerPort2 = new SuperScope(1); break;
|
||||
case ID::Device::Justifier: controllerPort2 = new Justifier(1, false); break;
|
||||
case ID::Device::Justifiers: controllerPort2 = new Justifier(1, true); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ Presentation::Presentation() {
|
||||
});
|
||||
about.setText("About ...").onActivate([&] {
|
||||
MessageDialog().setParent(*this).setTitle("About higan ...").setText({
|
||||
Emulator::Name, "/tomoko v", Emulator::Version, "\n\n",
|
||||
Emulator::Name, " v", Emulator::Version, "\n\n",
|
||||
"Author: ", Emulator::Author, "\n",
|
||||
"License: ", Emulator::License, "\n",
|
||||
"Website: ", Emulator::Website
|
||||
|
@ -26,8 +26,7 @@ auto Program::open(uint id, string name, vfs::file::mode mode, bool required) ->
|
||||
auto Program::load(uint id, string name, string type) -> maybe<uint> {
|
||||
string location;
|
||||
if(mediumQueue) {
|
||||
location = mediumQueue.takeLeft().transform("\\", "/");
|
||||
if(!location.endsWith("/")) location.append("/");
|
||||
location = mediumQueue.takeLeft();
|
||||
} else {
|
||||
location = BrowserDialog()
|
||||
.setTitle({"Load ", name})
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "utility.cpp"
|
||||
unique_pointer<Program> program;
|
||||
|
||||
Program::Program(lstring args) {
|
||||
Program::Program(string_vector args) {
|
||||
program = this;
|
||||
Application::onMain({&Program::main, this});
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
struct Program : Emulator::Interface::Bind {
|
||||
//program.cpp
|
||||
Program(lstring args);
|
||||
Program(string_vector args);
|
||||
auto main() -> void;
|
||||
auto quit() -> void;
|
||||
|
||||
|
@ -16,7 +16,7 @@ auto locate(string name) -> string {
|
||||
}
|
||||
|
||||
#include <nall/main.hpp>
|
||||
auto nall::main(lstring args) -> void {
|
||||
auto nall::main(string_vector args) -> void {
|
||||
Application::setName("higan");
|
||||
new Program(args);
|
||||
Application::run();
|
||||
|
@ -56,7 +56,7 @@ auto CheatEditor::doRefresh() -> void {
|
||||
for(auto slot : range(Slots)) {
|
||||
auto& cheat = cheats[slot];
|
||||
if(cheat.code || cheat.description) {
|
||||
lstring codes = cheat.code.split("+");
|
||||
auto codes = cheat.code.split("+");
|
||||
if(codes.size() > 1) codes[0].append("+...");
|
||||
cheatList.item(slot).cell(0).setChecked(cheat.enabled);
|
||||
cheatList.item(slot).cell(1).setText(codes[0]);
|
||||
@ -103,7 +103,7 @@ auto CheatEditor::doErase() -> void {
|
||||
auto CheatEditor::synchronizeCodes() -> void {
|
||||
if(!emulator) return;
|
||||
|
||||
lstring codes;
|
||||
string_vector codes;
|
||||
for(auto& cheat : cheats) {
|
||||
if(!cheat.enabled || !cheat.code) continue;
|
||||
codes.append(cheat.code);
|
||||
|
@ -140,12 +140,12 @@ auto Interface::unserialize(serializer& s) -> bool {
|
||||
return system.unserialize(s);
|
||||
}
|
||||
|
||||
auto Interface::cheatSet(const lstring& list) -> void {
|
||||
auto Interface::cheatSet(const string_vector& list) -> void {
|
||||
cheat.reset();
|
||||
for(auto& codeset : list) {
|
||||
lstring codes = codeset.split("+");
|
||||
auto codes = codeset.split("+");
|
||||
for(auto& code : codes) {
|
||||
lstring part = code.split("/");
|
||||
auto part = code.split("/");
|
||||
if(part.size() == 2) cheat.append(part[0].hex(), part[1].hex());
|
||||
if(part.size() == 3) cheat.append(part[0].hex(), part[1].hex(), part[2].hex());
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ struct Interface : Emulator::Interface {
|
||||
auto serialize() -> serializer override;
|
||||
auto unserialize(serializer&) -> bool override;
|
||||
|
||||
auto cheatSet(const lstring&) -> void override;
|
||||
auto cheatSet(const string_vector&) -> void override;
|
||||
|
||||
auto cap(const string& name) -> bool override;
|
||||
auto get(const string& name) -> any override;
|
||||
|
@ -33,8 +33,8 @@ auto DropPathsOperation(id<NSDraggingInfo> sender) -> NSDragOperation {
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
auto DropPaths(id<NSDraggingInfo> sender) -> lstring {
|
||||
lstring paths;
|
||||
auto DropPaths(id<NSDraggingInfo> sender) -> string_vector {
|
||||
string_vector paths;
|
||||
NSPasteboard* pboard = [sender draggingPasteboard];
|
||||
if([[pboard types] containsObject:NSFilenamesPboardType]) {
|
||||
NSArray* files = [pboard propertyListForType:NSFilenamesPboardType];
|
||||
|
@ -20,7 +20,7 @@
|
||||
}
|
||||
|
||||
-(BOOL) performDragOperation:(id<NSDraggingInfo>)sender {
|
||||
lstring paths = DropPaths(sender);
|
||||
auto paths = DropPaths(sender);
|
||||
if(!paths) return NO;
|
||||
canvas->doDrop(paths);
|
||||
return YES;
|
||||
|
@ -23,7 +23,7 @@
|
||||
}
|
||||
|
||||
-(BOOL) performDragOperation:(id<NSDraggingInfo>)sender {
|
||||
lstring paths = DropPaths(sender);
|
||||
auto paths = DropPaths(sender);
|
||||
if(!paths) return NO;
|
||||
viewport->doDrop(paths);
|
||||
return YES;
|
||||
|
@ -121,7 +121,7 @@
|
||||
}
|
||||
|
||||
-(BOOL) performDragOperation:(id<NSDraggingInfo>)sender {
|
||||
lstring paths = DropPaths(sender);
|
||||
auto paths = DropPaths(sender);
|
||||
if(!paths) return NO;
|
||||
window->doDrop(paths);
|
||||
return YES;
|
||||
|
@ -12,7 +12,7 @@ auto BrowserWindow::save() -> string {
|
||||
return pBrowserWindow::save(state);
|
||||
}
|
||||
|
||||
auto BrowserWindow::setFilters(const lstring& filters) -> type& {
|
||||
auto BrowserWindow::setFilters(const string_vector& filters) -> type& {
|
||||
state.filters = filters;
|
||||
return *this;
|
||||
}
|
||||
|
@ -16,13 +16,13 @@
|
||||
|
||||
using nall::function;
|
||||
using nall::image;
|
||||
using nall::lstring;
|
||||
using nall::maybe;
|
||||
using nall::nothing;
|
||||
using nall::set;
|
||||
using nall::shared_pointer;
|
||||
using nall::shared_pointer_weak;
|
||||
using nall::string;
|
||||
using nall::string_vector;
|
||||
using nall::vector;
|
||||
|
||||
namespace hiro {
|
||||
@ -477,14 +477,14 @@ struct BrowserWindow {
|
||||
auto directory() -> string;
|
||||
auto open() -> string;
|
||||
auto save() -> string;
|
||||
auto setFilters(const lstring& filters = {"*"}) -> type&;
|
||||
auto setFilters(const string_vector& filters = {"*"}) -> type&;
|
||||
auto setParent(sWindow parent) -> type&;
|
||||
auto setPath(const string& path = "") -> type&;
|
||||
auto setTitle(const string& title = "") -> type&;
|
||||
|
||||
//private:
|
||||
struct State {
|
||||
lstring filters;
|
||||
string_vector filters;
|
||||
sWindow parent;
|
||||
string path;
|
||||
string title;
|
||||
@ -667,7 +667,7 @@ struct mWindow : mObject {
|
||||
auto append(sStatusBar statusBar) -> type&;
|
||||
auto backgroundColor() const -> Color;
|
||||
auto doClose() const -> void;
|
||||
auto doDrop(lstring) const -> void;
|
||||
auto doDrop(string_vector) const -> void;
|
||||
auto doKeyPress(signed) const -> void;
|
||||
auto doKeyRelease(signed) const -> void;
|
||||
auto doMove() const -> void;
|
||||
@ -680,7 +680,7 @@ struct mWindow : mObject {
|
||||
auto menuBar() const -> MenuBar;
|
||||
auto modal() const -> bool;
|
||||
auto onClose(const function<void ()>& callback = {}) -> type&;
|
||||
auto onDrop(const function<void (lstring)>& callback = {}) -> type&;
|
||||
auto onDrop(const function<void (string_vector)>& callback = {}) -> type&;
|
||||
auto onKeyPress(const function<void (signed)>& callback = {}) -> type&;
|
||||
auto onKeyRelease(const function<void (signed)>& callback = {}) -> type&;
|
||||
auto onMove(const function<void ()>& callback = {}) -> type&;
|
||||
@ -717,7 +717,7 @@ struct mWindow : mObject {
|
||||
sMenuBar menuBar;
|
||||
bool modal = false;
|
||||
function<void ()> onClose;
|
||||
function<void (lstring)> onDrop;
|
||||
function<void (string_vector)> onDrop;
|
||||
function<void (signed)> onKeyPress;
|
||||
function<void (signed)> onKeyRelease;
|
||||
function<void ()> onMove;
|
||||
@ -989,14 +989,14 @@ struct mCanvas : mWidget {
|
||||
auto color() const -> Color;
|
||||
auto data() -> uint32_t*;
|
||||
auto droppable() const -> bool;
|
||||
auto doDrop(lstring names) const -> void;
|
||||
auto doDrop(string_vector names) const -> void;
|
||||
auto doMouseLeave() const -> void;
|
||||
auto doMouseMove(Position position) const -> void;
|
||||
auto doMousePress(Mouse::Button button) const -> void;
|
||||
auto doMouseRelease(Mouse::Button button) const -> void;
|
||||
auto gradient() const -> Gradient;
|
||||
auto icon() const -> image;
|
||||
auto onDrop(const function<void (lstring)>& callback = {}) -> type&;
|
||||
auto onDrop(const function<void (string_vector)>& callback = {}) -> type&;
|
||||
auto onMouseLeave(const function<void ()>& callback = {}) -> type&;
|
||||
auto onMouseMove(const function<void (Position)>& callback = {}) -> type&;
|
||||
auto onMousePress(const function<void (Mouse::Button)>& callback = {}) -> type&;
|
||||
@ -1015,7 +1015,7 @@ struct mCanvas : mWidget {
|
||||
bool droppable = false;
|
||||
Gradient gradient;
|
||||
image icon;
|
||||
function<void (lstring)> onDrop;
|
||||
function<void (string_vector)> onDrop;
|
||||
function<void ()> onMouseLeave;
|
||||
function<void (Position)> onMouseMove;
|
||||
function<void (Mouse::Button)> onMousePress;
|
||||
@ -1944,14 +1944,14 @@ struct mVerticalSlider : mWidget {
|
||||
struct mViewport : mWidget {
|
||||
Declare(Viewport)
|
||||
|
||||
auto doDrop(lstring names) const -> void;
|
||||
auto doDrop(string_vector names) const -> void;
|
||||
auto doMouseLeave() const -> void;
|
||||
auto doMouseMove(Position position) const -> void;
|
||||
auto doMousePress(Mouse::Button button) const -> void;
|
||||
auto doMouseRelease(Mouse::Button button) const -> void;
|
||||
auto droppable() const -> bool;
|
||||
auto handle() const -> uintptr_t;
|
||||
auto onDrop(const function<void (lstring)>& callback = {}) -> type&;
|
||||
auto onDrop(const function<void (string_vector)>& callback = {}) -> type&;
|
||||
auto onMouseLeave(const function<void ()>& callback = {}) -> type&;
|
||||
auto onMouseMove(const function<void (Position position)>& callback = {}) -> type&;
|
||||
auto onMousePress(const function<void (Mouse::Button)>& callback = {}) -> type&;
|
||||
@ -1961,7 +1961,7 @@ struct mViewport : mWidget {
|
||||
//private:
|
||||
struct State {
|
||||
bool droppable = false;
|
||||
function<void (lstring)> onDrop;
|
||||
function<void (string_vector)> onDrop;
|
||||
function<void ()> onMouseLeave;
|
||||
function<void (Position)> onMouseMove;
|
||||
function<void (Mouse::Button)> onMousePress;
|
||||
|
@ -234,14 +234,14 @@ struct Canvas : sCanvas {
|
||||
auto color() const { return self().color(); }
|
||||
auto data() { return self().data(); }
|
||||
auto droppable() const { return self().droppable(); }
|
||||
auto doDrop(lstring names) { return self().doDrop(names); }
|
||||
auto doDrop(string_vector names) { return self().doDrop(names); }
|
||||
auto doMouseLeave() const { return self().doMouseLeave(); }
|
||||
auto doMouseMove(Position position) const { return self().doMouseMove(position); }
|
||||
auto doMousePress(Mouse::Button button) const { return self().doMousePress(button); }
|
||||
auto doMouseRelease(Mouse::Button button) const { return self().doMouseRelease(button); }
|
||||
auto gradient() const { return self().gradient(); }
|
||||
auto icon() const { return self().icon(); }
|
||||
auto onDrop(const function<void (lstring)>& callback = {}) { return self().onDrop(callback), *this; }
|
||||
auto onDrop(const function<void (string_vector)>& callback = {}) { return self().onDrop(callback), *this; }
|
||||
auto onMouseLeave(const function<void ()>& callback = {}) { return self().onMouseLeave(callback), *this; }
|
||||
auto onMouseMove(const function<void (Position)>& callback = {}) { return self().onMouseMove(callback), *this; }
|
||||
auto onMousePress(const function<void (Mouse::Button)>& callback = {}) { return self().onMousePress(callback), *this; }
|
||||
@ -873,14 +873,14 @@ struct Viewport : sViewport {
|
||||
DeclareSharedWidget(Viewport)
|
||||
using internalType = mViewport;
|
||||
|
||||
auto doDrop(lstring names) const { return self().doDrop(names); }
|
||||
auto doDrop(string_vector names) const { return self().doDrop(names); }
|
||||
auto doMouseLeave() const { return self().doMouseLeave(); }
|
||||
auto doMouseMove(Position position) const { return self().doMouseMove(position); }
|
||||
auto doMousePress(Mouse::Button button) const { return self().doMousePress(button); }
|
||||
auto doMouseRelease(Mouse::Button button) const { return self().doMouseRelease(button); }
|
||||
auto droppable() const { return self().droppable(); }
|
||||
auto handle() const { return self().handle(); }
|
||||
auto onDrop(const function<void (lstring)>& callback = {}) { return self().onDrop(callback), *this; }
|
||||
auto onDrop(const function<void (string_vector)>& callback = {}) { return self().onDrop(callback), *this; }
|
||||
auto onMouseLeave(const function<void ()>& callback = {}) { return self().onMouseLeave(callback), *this; }
|
||||
auto onMouseMove(const function<void (Position)>& callback = {}) { return self().onMouseMove(callback), *this; }
|
||||
auto onMousePress(const function<void (Mouse::Button)>& callback = {}) { return self().onMousePress(callback), *this; }
|
||||
@ -937,7 +937,7 @@ struct Window : sWindow {
|
||||
auto append(sStatusBar statusBar) { return self().append(statusBar), *this; }
|
||||
auto backgroundColor() const { return self().backgroundColor(); }
|
||||
auto doClose() const { return self().doClose(); }
|
||||
auto doDrop(lstring names) const { return self().doDrop(names); }
|
||||
auto doDrop(string_vector names) const { return self().doDrop(names); }
|
||||
auto doKeyPress(signed key) const { return self().doKeyPress(key); }
|
||||
auto doKeyRelease(signed key) const { return self().doKeyRelease(key); }
|
||||
auto doMove() const { return self().doMove(); }
|
||||
@ -950,7 +950,7 @@ struct Window : sWindow {
|
||||
auto menuBar() const { return self().menuBar(); }
|
||||
auto modal() const { return self().modal(); }
|
||||
auto onClose(const function<void ()>& callback = {}) { return self().onClose(callback), *this; }
|
||||
auto onDrop(const function<void (lstring)>& callback = {}) { return self().onDrop(callback), *this; }
|
||||
auto onDrop(const function<void (string_vector)>& callback = {}) { return self().onDrop(callback), *this; }
|
||||
auto onKeyPress(const function<void (signed)>& callback = {}) { return self().onKeyPress(callback), *this; }
|
||||
auto onKeyRelease(const function<void (signed)>& callback = {}) { return self().onKeyRelease(callback), *this; }
|
||||
auto onMove(const function<void ()>& callback = {}) { return self().onMove(callback), *this; }
|
||||
|
@ -18,7 +18,7 @@ auto mCanvas::droppable() const -> bool {
|
||||
return state.droppable;
|
||||
}
|
||||
|
||||
auto mCanvas::doDrop(lstring names) const -> void {
|
||||
auto mCanvas::doDrop(string_vector names) const -> void {
|
||||
if(state.onDrop) return state.onDrop(names);
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ auto mCanvas::icon() const -> image {
|
||||
return state.icon;
|
||||
}
|
||||
|
||||
auto mCanvas::onDrop(const function<void (lstring)>& callback) -> type& {
|
||||
auto mCanvas::onDrop(const function<void (string_vector)>& callback) -> type& {
|
||||
state.onDrop = callback;
|
||||
return *this;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ auto mViewport::allocate() -> pObject* {
|
||||
|
||||
//
|
||||
|
||||
auto mViewport::doDrop(lstring names) const -> void {
|
||||
auto mViewport::doDrop(string_vector names) const -> void {
|
||||
if(state.onDrop) return state.onDrop(names);
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ auto mViewport::handle() const -> uintptr_t {
|
||||
return signal(handle);
|
||||
}
|
||||
|
||||
auto mViewport::onDrop(const function<void (lstring)>& callback) -> type& {
|
||||
auto mViewport::onDrop(const function<void (string_vector)>& callback) -> type& {
|
||||
state.onDrop = callback;
|
||||
return *this;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ auto mWindow::doClose() const -> void {
|
||||
if(state.onClose) return state.onClose();
|
||||
}
|
||||
|
||||
auto mWindow::doDrop(lstring names) const -> void {
|
||||
auto mWindow::doDrop(string_vector names) const -> void {
|
||||
if(state.onDrop) return state.onDrop(names);
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ auto mWindow::onClose(const function<void ()>& callback) -> type& {
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mWindow::onDrop(const function<void (lstring)>& callback) -> type& {
|
||||
auto mWindow::onDrop(const function<void (string_vector)>& callback) -> type& {
|
||||
state.onDrop = callback;
|
||||
return *this;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ struct BrowserDialogWindow {
|
||||
auto change() -> void;
|
||||
auto isFolder(const string& name) -> bool;
|
||||
auto isMatch(const string& name) -> bool;
|
||||
auto run() -> lstring;
|
||||
auto run() -> string_vector;
|
||||
auto setPath(string path) -> void;
|
||||
|
||||
private:
|
||||
@ -26,7 +26,7 @@ private:
|
||||
Button cancelButton{&controlLayout, Size{80, 0}, 5};
|
||||
|
||||
BrowserDialog::State& state;
|
||||
vector<lstring> filters;
|
||||
vector<string_vector> filters;
|
||||
};
|
||||
|
||||
//accept button clicked, or enter pressed on file name line edit
|
||||
@ -113,7 +113,7 @@ auto BrowserDialogWindow::isMatch(const string& name) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto BrowserDialogWindow::run() -> lstring {
|
||||
auto BrowserDialogWindow::run() -> string_vector {
|
||||
state.response.reset();
|
||||
|
||||
layout.setMargin(5);
|
||||
@ -197,7 +197,7 @@ auto BrowserDialog::openFile() -> string {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto BrowserDialog::openFiles() -> lstring {
|
||||
auto BrowserDialog::openFiles() -> string_vector {
|
||||
state.action = "openFiles";
|
||||
if(!state.title) state.title = "Open Files";
|
||||
if(auto result = _run()) return result;
|
||||
@ -225,7 +225,7 @@ auto BrowserDialog::selectFolder() -> string {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto BrowserDialog::setFilters(const lstring& filters) -> type& {
|
||||
auto BrowserDialog::setFilters(const string_vector& filters) -> type& {
|
||||
state.filters = filters;
|
||||
return *this;
|
||||
}
|
||||
@ -245,7 +245,7 @@ auto BrowserDialog::setTitle(const string& title) -> type& {
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto BrowserDialog::_run() -> lstring {
|
||||
auto BrowserDialog::_run() -> string_vector {
|
||||
if(!state.path) state.path = Path::user();
|
||||
return BrowserDialogWindow(state).run();
|
||||
}
|
||||
|
@ -6,12 +6,12 @@ struct BrowserDialog {
|
||||
using type = BrowserDialog;
|
||||
|
||||
BrowserDialog();
|
||||
auto openFile() -> string; //one existing file
|
||||
auto openFiles() -> lstring; //any existing files or folders
|
||||
auto openFolder() -> string; //one existing folder
|
||||
auto saveFile() -> string; //one file
|
||||
auto selectFolder() -> string; //one existing folder
|
||||
auto setFilters(const lstring& filters = {}) -> type&;
|
||||
auto openFile() -> string; //one existing file
|
||||
auto openFiles() -> string_vector; //any existing files or folders
|
||||
auto openFolder() -> string; //one existing folder
|
||||
auto saveFile() -> string; //one file
|
||||
auto selectFolder() -> string; //one existing folder
|
||||
auto setFilters(const string_vector& filters = {}) -> type&;
|
||||
auto setParent(const sWindow& parent) -> type&;
|
||||
auto setPath(const string& path = "") -> type&;
|
||||
auto setTitle(const string& title = "") -> type&;
|
||||
@ -19,14 +19,14 @@ struct BrowserDialog {
|
||||
private:
|
||||
struct State {
|
||||
string action;
|
||||
lstring filters = {"*"};
|
||||
string_vector filters = {"*"};
|
||||
sWindow parent;
|
||||
string path;
|
||||
lstring response;
|
||||
string_vector response;
|
||||
string title;
|
||||
} state;
|
||||
|
||||
auto _run() -> lstring;
|
||||
auto _run() -> string_vector;
|
||||
|
||||
friend class BrowserDialogWindow;
|
||||
};
|
||||
|
@ -4,19 +4,19 @@ MessageDialog::MessageDialog(const string& text) {
|
||||
state.text = text;
|
||||
}
|
||||
|
||||
auto MessageDialog::error(const lstring& buttons) -> string {
|
||||
auto MessageDialog::error(const string_vector& buttons) -> string {
|
||||
state.buttons = buttons;
|
||||
state.icon = Icon::Prompt::Error;
|
||||
return _run();
|
||||
}
|
||||
|
||||
auto MessageDialog::information(const lstring& buttons) -> string {
|
||||
auto MessageDialog::information(const string_vector& buttons) -> string {
|
||||
state.buttons = buttons;
|
||||
state.icon = Icon::Prompt::Information;
|
||||
return _run();
|
||||
}
|
||||
|
||||
auto MessageDialog::question(const lstring& buttons) -> string {
|
||||
auto MessageDialog::question(const string_vector& buttons) -> string {
|
||||
state.buttons = buttons;
|
||||
state.icon = Icon::Prompt::Question;
|
||||
return _run();
|
||||
@ -37,7 +37,7 @@ auto MessageDialog::setTitle(const string& title) -> type& {
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto MessageDialog::warning(const lstring& buttons) -> string {
|
||||
auto MessageDialog::warning(const string_vector& buttons) -> string {
|
||||
state.buttons = buttons;
|
||||
state.icon = Icon::Prompt::Warning;
|
||||
return _run();
|
||||
|
@ -4,17 +4,17 @@ struct MessageDialog {
|
||||
using type = MessageDialog;
|
||||
|
||||
MessageDialog(const string& text = "");
|
||||
auto error(const lstring& buttons = {"Ok"}) -> string;
|
||||
auto information(const lstring& buttons = {"Ok"}) -> string;
|
||||
auto question(const lstring& buttons = {"Yes", "No"}) -> string;
|
||||
auto error(const string_vector& buttons = {"Ok"}) -> string;
|
||||
auto information(const string_vector& buttons = {"Ok"}) -> string;
|
||||
auto question(const string_vector& buttons = {"Yes", "No"}) -> string;
|
||||
auto setParent(sWindow parent = {}) -> type&;
|
||||
auto setText(const string& text = "") -> type&;
|
||||
auto setTitle(const string& title = "") -> type&;
|
||||
auto warning(const lstring& buttons = {"Ok"}) -> string;
|
||||
auto warning(const string_vector& buttons = {"Ok"}) -> string;
|
||||
|
||||
private:
|
||||
struct State {
|
||||
lstring buttons;
|
||||
string_vector buttons;
|
||||
vector<uint8_t> icon;
|
||||
sWindow parent;
|
||||
string response;
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
namespace hiro {
|
||||
|
||||
static auto BrowserWindow_addFilters(GtkWidget* dialog, lstring filters) -> void {
|
||||
static auto BrowserWindow_addFilters(GtkWidget* dialog, string_vector filters) -> void {
|
||||
for(auto& filter : filters) {
|
||||
GtkFileFilter* gtkFilter = gtk_file_filter_new();
|
||||
gtk_file_filter_set_name(gtkFilter, filter);
|
||||
lstring patterns = filter.split("(", 1L)(1).trimRight(")", 1L).split(",").strip();
|
||||
auto patterns = filter.split("(", 1L)(1).trimRight(")", 1L).split(",").strip();
|
||||
for(auto& pattern : patterns) gtk_file_filter_add_pattern(gtkFilter, pattern);
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), gtkFilter);
|
||||
}
|
||||
|
@ -36,11 +36,11 @@ static auto CreateImage(const image& icon, bool scale = false) -> GtkImage* {
|
||||
return gtkIcon;
|
||||
}
|
||||
|
||||
static auto DropPaths(GtkSelectionData* data) -> lstring {
|
||||
static auto DropPaths(GtkSelectionData* data) -> string_vector {
|
||||
gchar** uris = gtk_selection_data_get_uris(data);
|
||||
if(uris == nullptr) return {};
|
||||
|
||||
lstring paths;
|
||||
string_vector paths;
|
||||
for(unsigned n = 0; uris[n] != nullptr; n++) {
|
||||
gchar* pathname = g_filename_from_uri(uris[n], nullptr, nullptr);
|
||||
if(pathname == nullptr) continue;
|
||||
|
@ -5,7 +5,7 @@ namespace hiro {
|
||||
static auto Canvas_drop(GtkWidget* widget, GdkDragContext* context, signed x, signed y,
|
||||
GtkSelectionData* data, unsigned type, unsigned timestamp, pCanvas* p) -> void {
|
||||
if(!p->state().droppable) return;
|
||||
lstring paths = DropPaths(data);
|
||||
auto paths = DropPaths(data);
|
||||
if(!paths) return;
|
||||
p->self().doDrop(paths);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ struct pConsole : pWidget {
|
||||
GtkWidget* subWidget = nullptr;
|
||||
GtkTextBuffer* textBuffer = nullptr;
|
||||
string previousPrompt;
|
||||
lstring history;
|
||||
string_vector history;
|
||||
unsigned historyOffset = 0;
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,7 @@ namespace hiro {
|
||||
static auto Viewport_dropEvent(GtkWidget* widget, GdkDragContext* context, signed x, signed y,
|
||||
GtkSelectionData* data, unsigned type, unsigned timestamp, pViewport* p) -> void {
|
||||
if(!p->state().droppable) return;
|
||||
lstring paths = DropPaths(data);
|
||||
auto paths = DropPaths(data);
|
||||
if(!paths) return;
|
||||
p->self().doDrop(paths);
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ static auto Window_configure(GtkWidget* widget, GdkEvent* event, pWindow* p) ->
|
||||
static auto Window_drop(GtkWidget* widget, GdkDragContext* context, signed x, signed y,
|
||||
GtkSelectionData* data, unsigned type, unsigned timestamp, pWindow* p) -> void {
|
||||
if(!p->state().droppable) return;
|
||||
lstring paths = DropPaths(data);
|
||||
auto paths = DropPaths(data);
|
||||
if(!paths) return;
|
||||
p->self().doDrop(paths);
|
||||
}
|
||||
|
@ -24,11 +24,11 @@ static auto CreateIcon(const image& icon, bool scale = false) -> QIcon {
|
||||
return QIcon(QPixmap::fromImage(qtImage));
|
||||
}
|
||||
|
||||
static auto DropPaths(QDropEvent* event) -> lstring {
|
||||
static auto DropPaths(QDropEvent* event) -> string_vector {
|
||||
QList<QUrl> urls = event->mimeData()->urls();
|
||||
if(urls.size() == 0) return {};
|
||||
|
||||
lstring paths;
|
||||
string_vector paths;
|
||||
for(auto n : range(urls.size())) {
|
||||
string path{urls[n].path().toUtf8().constData()};
|
||||
if(!path) continue;
|
||||
|
@ -33,7 +33,7 @@ void pListView::setCheckedNone() {
|
||||
void pListView::setForegroundColor(Color color) {
|
||||
}
|
||||
|
||||
void pListView::setHeaderText(const lstring& text) {
|
||||
void pListView::setHeaderText(const string_vector& text) {
|
||||
}
|
||||
|
||||
void pListView::setHeaderVisible(bool visible) {
|
||||
|
@ -19,7 +19,7 @@ static auto BrowserWindow_fileDialog(bool save, BrowserWindow::State& state) ->
|
||||
|
||||
string filters;
|
||||
for(auto& filter : state.filters) {
|
||||
lstring part = filter.split("(");
|
||||
auto part = filter.split("(");
|
||||
if(part.size() != 2) continue;
|
||||
part[1].trimRight(")", 1L);
|
||||
part[1].replace(" ", "");
|
||||
|
@ -38,11 +38,11 @@ static auto CreateRGB(const Color& color) -> COLORREF {
|
||||
return RGB(color.red(), color.green(), color.blue());
|
||||
}
|
||||
|
||||
static auto DropPaths(WPARAM wparam) -> lstring {
|
||||
static auto DropPaths(WPARAM wparam) -> string_vector {
|
||||
auto dropList = HDROP(wparam);
|
||||
auto fileCount = DragQueryFile(dropList, ~0u, nullptr, 0);
|
||||
|
||||
lstring paths;
|
||||
string_vector paths;
|
||||
for(auto n : range(fileCount)) {
|
||||
auto length = DragQueryFile(dropList, n, nullptr, 0);
|
||||
auto buffer = new wchar_t[length + 1];
|
||||
|
@ -176,7 +176,7 @@ auto pWindow::onClose() -> void {
|
||||
}
|
||||
|
||||
auto pWindow::onDrop(WPARAM wparam) -> void {
|
||||
lstring paths = DropPaths(wparam);
|
||||
auto paths = DropPaths(wparam);
|
||||
if(paths) self().doDrop(paths);
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ GameBoyAdvanceCartridge::GameBoyAdvanceCartridge(const uint8_t* data, unsigned s
|
||||
idlist.append({"FLASH512_V", 10});
|
||||
idlist.append({"FLASH1M_V", 9});
|
||||
|
||||
lstring list;
|
||||
string_vector list;
|
||||
for(auto& id : idlist) {
|
||||
for(signed n = 0; n < size - 16; n++) {
|
||||
if(!memcmp(data + n, (const char*)id.name, id.size)) {
|
||||
|
@ -46,7 +46,7 @@ Icarus icarus;
|
||||
#include "ui/error-dialog.cpp"
|
||||
|
||||
#include <nall/main.hpp>
|
||||
auto nall::main(lstring args) -> void {
|
||||
auto nall::main(string_vector args) -> void {
|
||||
if(args.size() == 2 && args[1] == "--name") {
|
||||
return print("icarus");
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ ImportDialog::ImportDialog() {
|
||||
setCentered();
|
||||
}
|
||||
|
||||
auto ImportDialog::run(lstring locations) -> void {
|
||||
auto ImportDialog::run(string_vector locations) -> void {
|
||||
abort = false;
|
||||
errors.reset();
|
||||
unsigned position = 0;
|
||||
|
@ -82,7 +82,7 @@ auto ScanDialog::activate() -> void {
|
||||
}
|
||||
|
||||
auto ScanDialog::import() -> void {
|
||||
lstring filenames;
|
||||
string_vector filenames;
|
||||
for(auto& item : scanList.items()) {
|
||||
if(item.checked()) {
|
||||
filenames.append(string{settings["icarus/Path"].text(), item.text()});
|
||||
|
@ -38,10 +38,10 @@ struct SettingsDialog : Window {
|
||||
|
||||
struct ImportDialog : Window {
|
||||
ImportDialog();
|
||||
auto run(lstring locations) -> void;
|
||||
auto run(string_vector locations) -> void;
|
||||
|
||||
bool abort;
|
||||
lstring errors;
|
||||
string_vector errors;
|
||||
|
||||
VerticalLayout layout{this};
|
||||
Label statusLabel{&layout, Size{~0, 0}};
|
||||
|
@ -10,7 +10,7 @@ struct Archive {
|
||||
static auto extract(const string& beatname, const string& pathname) -> vector<uint8_t>;
|
||||
|
||||
private:
|
||||
static auto scan(lstring& result, const string& basename, const string& pathname) -> void;
|
||||
static auto scan(string_vector& result, const string& basename, const string& pathname) -> void;
|
||||
};
|
||||
|
||||
auto Archive::create(const string& beatname, const string& pathname, const string& metadata) -> bool {
|
||||
@ -23,7 +23,7 @@ auto Archive::create(const string& beatname, const string& pathname, const strin
|
||||
beat.writevu(metadata.size());
|
||||
beat.writes(metadata);
|
||||
|
||||
lstring contents;
|
||||
string_vector contents;
|
||||
scan(contents, pathname, pathname);
|
||||
|
||||
for(auto& name : contents) {
|
||||
@ -121,7 +121,7 @@ auto Archive::extract(const string& beatname, const string& filename) -> vector<
|
||||
return {};
|
||||
}
|
||||
|
||||
auto Archive::scan(lstring& result, const string& basename, const string& pathname) -> void {
|
||||
auto Archive::scan(string_vector& result, const string& basename, const string& pathname) -> void {
|
||||
for(auto& name : directory::contents(pathname)) {
|
||||
result.append(string{pathname, name}.trimLeft(basename, 1L));
|
||||
if(name.endsWith("/")) scan(result, basename, {pathname, name});
|
||||
|
@ -28,7 +28,7 @@ struct bpsmulti {
|
||||
writeNumber(metadata.length());
|
||||
writeString(metadata);
|
||||
|
||||
lstring sourceList, targetList;
|
||||
string_vector sourceList, targetList;
|
||||
ls(sourceList, sourcePath, sourcePath);
|
||||
ls(targetList, targetPath, targetPath);
|
||||
|
||||
@ -156,14 +156,14 @@ protected:
|
||||
Hash::CRC32 checksum;
|
||||
|
||||
//create() functions
|
||||
auto ls(lstring& list, const string& path, const string& basepath) -> void {
|
||||
lstring paths = directory::folders(path);
|
||||
auto ls(string_vector& list, const string& path, const string& basepath) -> void {
|
||||
auto paths = directory::folders(path);
|
||||
for(auto& pathname : paths) {
|
||||
list.append(string{path, pathname}.trimLeft(basepath, 1L));
|
||||
ls(list, {path, pathname}, basepath);
|
||||
}
|
||||
|
||||
lstring files = directory::files(path);
|
||||
auto files = directory::files(path);
|
||||
for(auto& filename : files) {
|
||||
list.append(string{path, filename}.trimLeft(basepath, 1L));
|
||||
}
|
||||
|
@ -2,55 +2,11 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
template<typename type, uint Lo, uint Hi> struct NaturalBitField {
|
||||
enum : uint { lo = Lo <= Hi ? Lo : Hi };
|
||||
enum : uint { hi = Hi >= Lo ? Hi : Lo };
|
||||
enum : uint { bits = hi - lo + 1 };
|
||||
enum : uint { mask = (~0ull >> (64 - bits)) << lo };
|
||||
static_assert(hi < sizeof(type) * 8, "");
|
||||
|
||||
inline NaturalBitField() = default;
|
||||
inline NaturalBitField(const NaturalBitField& value) { set(value.data); }
|
||||
template<typename T> inline NaturalBitField(const T& value) { set(value << lo); }
|
||||
|
||||
inline explicit operator bool() const { return data & mask; }
|
||||
inline operator type() const { return get(); }
|
||||
|
||||
inline auto& operator=(const NaturalBitField& value) { return set(value.data); }
|
||||
template<typename T> inline auto& operator=(const T& value) { return set(value << lo); }
|
||||
|
||||
inline auto operator++(int) { type value = get(); set(data + (1 << lo)); return value; }
|
||||
inline auto operator--(int) { type value = get(); set(data - (1 << lo)); return value; }
|
||||
|
||||
inline auto& operator++() { return set(data + (1 << lo)); }
|
||||
inline auto& operator--() { return set(data - (1 << lo)); }
|
||||
|
||||
inline auto& operator &=(const type value) { return set(data & (value << lo)); }
|
||||
inline auto& operator |=(const type value) { return set(data | (value << lo)); }
|
||||
inline auto& operator ^=(const type value) { return set(data ^ (value << lo)); }
|
||||
inline auto& operator<<=(const type value) { return set((data & mask) << value); }
|
||||
inline auto& operator>>=(const type value) { return set((data & mask) >> value); }
|
||||
inline auto& operator +=(const type value) { return set(data + (value << lo)); }
|
||||
inline auto& operator -=(const type value) { return set(data - (value << lo)); }
|
||||
inline auto& operator *=(const type value) { return set((get() * value) << lo); }
|
||||
inline auto& operator /=(const type value) { return set((get() / value) << lo); }
|
||||
inline auto& operator %=(const type value) { return set((get() % value) << lo); }
|
||||
|
||||
private:
|
||||
type data;
|
||||
|
||||
inline auto get() const -> type {
|
||||
return (data & mask) >> lo;
|
||||
}
|
||||
|
||||
inline auto set(type value) -> NaturalBitField& {
|
||||
return data = (data & ~mask) | (value & mask), *this;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename type, uint Bit> struct BooleanBitField {
|
||||
template<typename Type, uint Bit> struct BooleanBitField {
|
||||
enum : uint { bit = Bit };
|
||||
enum : uint { mask = 1ull << bit };
|
||||
using type = Type;
|
||||
using utype = typename std::make_unsigned<type>::type;
|
||||
static_assert(bit < sizeof(type) * 8, "");
|
||||
|
||||
inline BooleanBitField() = default;
|
||||
@ -71,7 +27,7 @@ template<typename type, uint Bit> struct BooleanBitField {
|
||||
inline auto& invert() { return set(get() ^ 1); }
|
||||
|
||||
private:
|
||||
type data;
|
||||
utype data;
|
||||
|
||||
inline auto get() const -> bool {
|
||||
return data & mask;
|
||||
@ -82,4 +38,103 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Type, uint Lo, uint Hi> struct NaturalBitField {
|
||||
enum : uint { lo = Lo <= Hi ? Lo : Hi };
|
||||
enum : uint { hi = Hi >= Lo ? Hi : Lo };
|
||||
enum : uint { bits = hi - lo + 1 };
|
||||
enum : uint { mask = (~0ull >> (64 - bits)) << lo };
|
||||
using type = Type;
|
||||
using utype = typename std::make_unsigned<type>::type;
|
||||
static_assert(hi < sizeof(type) * 8, "");
|
||||
|
||||
inline NaturalBitField() = default;
|
||||
inline NaturalBitField(const NaturalBitField& value) { set(value.data); }
|
||||
template<typename T> inline NaturalBitField(const T& value) { set(value << lo); }
|
||||
|
||||
inline explicit operator bool() const { return data & mask; }
|
||||
inline operator utype() const { return get(); }
|
||||
|
||||
inline auto& operator=(const NaturalBitField& value) { return set(value.data); }
|
||||
template<typename T> inline auto& operator=(const T& value) { return set(value << lo); }
|
||||
|
||||
inline auto operator++(int) { utype value = get(); set(data + (1 << lo)); return value; }
|
||||
inline auto operator--(int) { utype value = get(); set(data - (1 << lo)); return value; }
|
||||
|
||||
inline auto& operator++() { return set(data + (1 << lo)); }
|
||||
inline auto& operator--() { return set(data - (1 << lo)); }
|
||||
|
||||
inline auto& operator &=(const utype value) { return set(data & (value << lo)); }
|
||||
inline auto& operator |=(const utype value) { return set(data | (value << lo)); }
|
||||
inline auto& operator ^=(const utype value) { return set(data ^ (value << lo)); }
|
||||
inline auto& operator<<=(const utype value) { return set((data & mask) << value); }
|
||||
inline auto& operator>>=(const utype value) { return set((data & mask) >> value); }
|
||||
inline auto& operator +=(const utype value) { return set(data + (value << lo)); }
|
||||
inline auto& operator -=(const utype value) { return set(data - (value << lo)); }
|
||||
inline auto& operator *=(const utype value) { return set((get() * value) << lo); }
|
||||
inline auto& operator /=(const utype value) { return set((get() / value) << lo); }
|
||||
inline auto& operator %=(const utype value) { return set((get() % value) << lo); }
|
||||
|
||||
private:
|
||||
utype data;
|
||||
|
||||
inline auto get() const -> utype {
|
||||
return (data & mask) >> lo;
|
||||
}
|
||||
|
||||
inline auto set(utype value) -> NaturalBitField& {
|
||||
return data = (data & ~mask) | (value & mask), *this;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Type, uint Lo, uint Hi> struct IntegerBitField {
|
||||
enum : uint { lo = Lo <= Hi ? Lo : Hi };
|
||||
enum : uint { hi = Hi >= Lo ? Hi : Lo };
|
||||
enum : uint { bits = hi - lo + 1 };
|
||||
enum : uint { mask = (~0ull >> (64 - bits)) << lo };
|
||||
using type = Type;
|
||||
using stype = typename std::make_signed<type>::type;
|
||||
using utype = typename std::make_unsigned<type>::type;
|
||||
static_assert(hi < sizeof(type) * 8, "");
|
||||
|
||||
inline IntegerBitField() = default;
|
||||
inline IntegerBitField(const IntegerBitField& value) { set(value.get()); }
|
||||
template<typename T> inline IntegerBitField(const T& value) { set(value); }
|
||||
|
||||
inline explicit operator bool() const { return data & mask; }
|
||||
inline operator stype() const { return get(); }
|
||||
|
||||
inline auto& operator=(const IntegerBitField& value) { return set(value.get()); }
|
||||
template<typename T> inline auto& operator=(const T& value) { return set(value); }
|
||||
|
||||
inline auto operator++(int) { stype value = get(); set(value + 1); return value; }
|
||||
inline auto operator--(int) { stype value = get(); set(value - 1); return value; }
|
||||
|
||||
inline auto& operator++() { return set(get() + 1); }
|
||||
inline auto& operator--() { return set(get() - 1); }
|
||||
|
||||
inline auto& operator &=(const stype value) { return set(get() & value); }
|
||||
inline auto& operator |=(const stype value) { return set(get() | value); }
|
||||
inline auto& operator ^=(const stype value) { return set(get() ^ value); }
|
||||
inline auto& operator<<=(const stype value) { return set(get() << value); }
|
||||
inline auto& operator>>=(const stype value) { return set(get() >> value); }
|
||||
inline auto& operator +=(const stype value) { return set(get() + value); }
|
||||
inline auto& operator -=(const stype value) { return set(get() - value); }
|
||||
inline auto& operator *=(const stype value) { return set(get() * value); }
|
||||
inline auto& operator /=(const stype value) { return set(get() / value); }
|
||||
inline auto& operator %=(const stype value) { return set(get() % value); }
|
||||
|
||||
private:
|
||||
utype data;
|
||||
|
||||
inline auto get() const -> stype {
|
||||
enum : utype { b = 1ull << (bits - 1) };
|
||||
enum : utype { m = b * 2 - 1 };
|
||||
return ((((data & mask) >> lo) & m) ^ b) - b;
|
||||
}
|
||||
|
||||
inline auto set(utype value) -> IntegerBitField& {
|
||||
return data = (data & ~mask) | ((value << lo) & mask), *this;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,46 +18,46 @@
|
||||
namespace nall {
|
||||
|
||||
struct directory : inode {
|
||||
static auto create(const string& pathname, unsigned permissions = 0755) -> bool; //recursive
|
||||
static auto create(const string& pathname, uint permissions = 0755) -> bool; //recursive
|
||||
static auto remove(const string& pathname) -> bool; //recursive
|
||||
static auto exists(const string& pathname) -> bool;
|
||||
|
||||
static auto folders(const string& pathname, const string& pattern = "*") -> lstring {
|
||||
lstring folders = directory::ufolders(pathname, pattern);
|
||||
static auto folders(const string& pathname, const string& pattern = "*") -> string_vector {
|
||||
auto folders = directory::ufolders(pathname, pattern);
|
||||
folders.sort();
|
||||
return folders;
|
||||
}
|
||||
|
||||
static auto files(const string& pathname, const string& pattern = "*") -> lstring {
|
||||
lstring files = directory::ufiles(pathname, pattern);
|
||||
static auto files(const string& pathname, const string& pattern = "*") -> string_vector {
|
||||
auto files = directory::ufiles(pathname, pattern);
|
||||
files.sort();
|
||||
return files;
|
||||
}
|
||||
|
||||
static auto contents(const string& pathname, const string& pattern = "*") -> lstring {
|
||||
lstring folders = directory::ufolders(pathname); //pattern search of contents should only filter files
|
||||
lstring files = directory::ufiles(pathname, pattern);
|
||||
static auto contents(const string& pathname, const string& pattern = "*") -> string_vector {
|
||||
auto folders = directory::ufolders(pathname); //pattern search of contents should only filter files
|
||||
auto files = directory::ufiles(pathname, pattern);
|
||||
folders.sort();
|
||||
files.sort();
|
||||
for(auto& file : files) folders.append(file);
|
||||
return folders;
|
||||
}
|
||||
|
||||
static auto ifolders(const string& pathname, const string& pattern = "*") -> lstring {
|
||||
lstring folders = ufolders(pathname, pattern);
|
||||
static auto ifolders(const string& pathname, const string& pattern = "*") -> string_vector {
|
||||
auto folders = ufolders(pathname, pattern);
|
||||
folders.isort();
|
||||
return folders;
|
||||
}
|
||||
|
||||
static auto ifiles(const string& pathname, const string& pattern = "*") -> lstring {
|
||||
lstring files = ufiles(pathname, pattern);
|
||||
static auto ifiles(const string& pathname, const string& pattern = "*") -> string_vector {
|
||||
auto files = ufiles(pathname, pattern);
|
||||
files.isort();
|
||||
return files;
|
||||
}
|
||||
|
||||
static auto icontents(const string& pathname, const string& pattern = "*") -> lstring {
|
||||
lstring folders = directory::ufolders(pathname); //pattern search of contents should only filter files
|
||||
lstring files = directory::ufiles(pathname, pattern);
|
||||
static auto icontents(const string& pathname, const string& pattern = "*") -> string_vector {
|
||||
auto folders = directory::ufolders(pathname); //pattern search of contents should only filter files
|
||||
auto files = directory::ufiles(pathname, pattern);
|
||||
folders.isort();
|
||||
files.isort();
|
||||
for(auto& file : files) folders.append(file);
|
||||
@ -66,14 +66,14 @@ struct directory : inode {
|
||||
|
||||
private:
|
||||
//internal functions; these return unsorted lists
|
||||
static auto ufolders(const string& pathname, const string& pattern = "*") -> lstring;
|
||||
static auto ufiles(const string& pathname, const string& pattern = "*") -> lstring;
|
||||
static auto ufolders(const string& pathname, const string& pattern = "*") -> string_vector;
|
||||
static auto ufiles(const string& pathname, const string& pattern = "*") -> string_vector;
|
||||
};
|
||||
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
inline auto directory::create(const string& pathname, unsigned permissions) -> bool {
|
||||
inline auto directory::create(const string& pathname, uint permissions) -> bool {
|
||||
string path;
|
||||
lstring list = string{pathname}.transform("\\", "/").trimRight("/").split("/");
|
||||
auto list = string{pathname}.transform("\\", "/").trimRight("/").split("/");
|
||||
bool result = true;
|
||||
for(auto& part : list) {
|
||||
path.append(part, "/");
|
||||
@ -84,7 +84,7 @@ private:
|
||||
}
|
||||
|
||||
inline auto directory::remove(const string& pathname) -> bool {
|
||||
lstring list = directory::contents(pathname);
|
||||
auto list = directory::contents(pathname);
|
||||
for(auto& name : list) {
|
||||
if(name.endsWith("/")) directory::remove({pathname, name});
|
||||
else file::remove({pathname, name});
|
||||
@ -100,8 +100,8 @@ private:
|
||||
return (result & FILE_ATTRIBUTE_DIRECTORY);
|
||||
}
|
||||
|
||||
inline auto directory::ufolders(const string& pathname, const string& pattern) -> lstring {
|
||||
lstring list;
|
||||
inline auto directory::ufolders(const string& pathname, const string& pattern) -> string_vector {
|
||||
auto list;
|
||||
string path = pathname;
|
||||
path.transform("/", "\\");
|
||||
if(!path.endsWith("\\")) path.append("\\");
|
||||
@ -130,8 +130,8 @@ private:
|
||||
return list;
|
||||
}
|
||||
|
||||
inline auto directory::ufiles(const string& pathname, const string& pattern) -> lstring {
|
||||
lstring list;
|
||||
inline auto directory::ufiles(const string& pathname, const string& pattern) -> string_vector {
|
||||
string_vector list;
|
||||
string path = pathname;
|
||||
path.transform("/", "\\");
|
||||
if(!path.endsWith("\\")) path.append("\\");
|
||||
@ -166,9 +166,9 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
inline auto directory::create(const string& pathname, unsigned permissions) -> bool {
|
||||
inline auto directory::create(const string& pathname, uint permissions) -> bool {
|
||||
string path;
|
||||
lstring list = string{pathname}.trimRight("/").split("/");
|
||||
auto list = string{pathname}.trimRight("/").split("/");
|
||||
bool result = true;
|
||||
for(auto& part : list) {
|
||||
path.append(part, "/");
|
||||
@ -179,7 +179,7 @@ private:
|
||||
}
|
||||
|
||||
inline auto directory::remove(const string& pathname) -> bool {
|
||||
lstring list = directory::contents(pathname);
|
||||
auto list = directory::contents(pathname);
|
||||
for(auto& name : list) {
|
||||
if(name.endsWith("/")) directory::remove({pathname, name});
|
||||
else file::remove({pathname, name});
|
||||
@ -188,14 +188,13 @@ private:
|
||||
}
|
||||
|
||||
inline auto directory::exists(const string& pathname) -> bool {
|
||||
DIR* dp = opendir(pathname);
|
||||
if(!dp) return false;
|
||||
closedir(dp);
|
||||
return true;
|
||||
struct stat data;
|
||||
if(stat(pathname, &data) != 0) return false;
|
||||
return S_ISDIR(data.st_mode);
|
||||
}
|
||||
|
||||
inline auto directory::ufolders(const string& pathname, const string& pattern) -> lstring {
|
||||
lstring list;
|
||||
inline auto directory::ufolders(const string& pathname, const string& pattern) -> string_vector {
|
||||
string_vector list;
|
||||
DIR* dp;
|
||||
struct dirent* ep;
|
||||
dp = opendir(pathname);
|
||||
@ -213,8 +212,8 @@ private:
|
||||
return list;
|
||||
}
|
||||
|
||||
inline auto directory::ufiles(const string& pathname, const string& pattern) -> lstring {
|
||||
lstring list;
|
||||
inline auto directory::ufiles(const string& pathname, const string& pattern) -> string_vector {
|
||||
string_vector list;
|
||||
DIR* dp;
|
||||
struct dirent* ep;
|
||||
dp = opendir(pathname);
|
||||
|
@ -5,7 +5,7 @@
|
||||
using namespace nall;
|
||||
|
||||
struct FX {
|
||||
auto open(lstring& args) -> bool;
|
||||
auto open(string_vector& args) -> bool;
|
||||
auto close() -> void;
|
||||
auto readable() -> bool;
|
||||
auto read() -> uint8_t;
|
||||
@ -23,7 +23,7 @@ struct FX {
|
||||
serial device;
|
||||
};
|
||||
|
||||
auto FX::open(lstring& args) -> bool {
|
||||
auto FX::open(string_vector& args) -> bool {
|
||||
//device name override support
|
||||
string name;
|
||||
for(uint n : range(args)) {
|
||||
|
@ -1,95 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <nall/nall.hpp>
|
||||
#include <nall/serial.hpp>
|
||||
using namespace nall;
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
static function<auto () -> bool> usart_quit;
|
||||
static function<auto (uint microseconds) -> void> usart_usleep;
|
||||
static function<auto () -> bool> usart_readable;
|
||||
static function<auto () -> uint8> usart_read;
|
||||
static function<auto () -> bool> usart_writable;
|
||||
static function<auto (uint8 data) -> void> usart_write;
|
||||
|
||||
extern "C" auto usart_init(
|
||||
function<auto () -> bool> quit,
|
||||
function<auto (uint microseconds) -> void> usleep,
|
||||
function<auto () -> bool> readable,
|
||||
function<auto () -> uint8> read,
|
||||
function<auto () -> bool> writable,
|
||||
function<auto (uint8 data) -> void> write
|
||||
) -> void {
|
||||
usart_quit = quit;
|
||||
usart_usleep = usleep;
|
||||
usart_readable = readable;
|
||||
usart_read = read;
|
||||
usart_writable = writable;
|
||||
usart_write = write;
|
||||
}
|
||||
|
||||
extern "C" auto usart_main(nall::lstring) -> void;
|
||||
|
||||
//
|
||||
|
||||
static serial usart;
|
||||
static bool usart_is_virtual = true;
|
||||
static bool usart_sigint = false;
|
||||
|
||||
static auto usart_virtual() -> bool {
|
||||
return usart_is_virtual;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
static auto usarthw_quit() -> bool {
|
||||
return usart_sigint;
|
||||
}
|
||||
|
||||
static auto usarthw_usleep(uint microseconds) -> void {
|
||||
usleep(microseconds);
|
||||
}
|
||||
|
||||
static auto usarthw_readable() -> bool {
|
||||
return usart.readable();
|
||||
}
|
||||
|
||||
static auto usarthw_read() -> uint8 {
|
||||
while(true) {
|
||||
uint8 buffer[1];
|
||||
int length = usart.read((uint8_t*)&buffer, 1);
|
||||
if(length > 0) return buffer[0];
|
||||
}
|
||||
}
|
||||
|
||||
static auto usarthw_writable() -> bool {
|
||||
return usart.writable();
|
||||
}
|
||||
|
||||
static auto usarthw_write(uint8 data) -> void {
|
||||
uint8 buffer[1] = {data};
|
||||
usart.write((uint8*)&buffer, 1);
|
||||
}
|
||||
|
||||
static auto sigint(int) -> void {
|
||||
signal(SIGINT, SIG_DFL);
|
||||
usart_sigint = true;
|
||||
}
|
||||
|
||||
#include <nall/main.hpp>
|
||||
auto nall::main(lstring args) -> void {
|
||||
setpriority(PRIO_PROCESS, 0, -20); //requires superuser privileges; otherwise priority = +0
|
||||
signal(SIGINT, sigint);
|
||||
|
||||
if(!usart.open("/dev/ttyACM0", 57600, true)) {
|
||||
return print("error: unable to open USART hardware device\n");
|
||||
}
|
||||
|
||||
usart_is_virtual = false;
|
||||
usart_init(usarthw_quit, usarthw_usleep, usarthw_readable, usarthw_read, usarthw_writable, usarthw_write);
|
||||
usart_main(args);
|
||||
usart.close();
|
||||
}
|
@ -69,7 +69,7 @@ auto Request::head(const function<bool (const uint8_t*, unsigned)>& callback) co
|
||||
}
|
||||
|
||||
auto Request::setHead() -> bool {
|
||||
lstring headers = _head.split("\n");
|
||||
auto headers = _head.split("\n");
|
||||
string request = headers.takeLeft().trimRight("\r", 1L);
|
||||
string requestHost;
|
||||
|
||||
@ -85,12 +85,12 @@ auto Request::setHead() -> bool {
|
||||
//decode absolute URIs
|
||||
request.strip().itrimLeft("http://", 1L);
|
||||
if(!request.beginsWith("/")) {
|
||||
lstring components = request.split("/", 1L);
|
||||
auto components = request.split("/", 1L);
|
||||
requestHost = components(0);
|
||||
request = {"/", components(1)};
|
||||
}
|
||||
|
||||
lstring components = request.split("?", 1L);
|
||||
auto components = request.split("?", 1L);
|
||||
setPath(components(0));
|
||||
|
||||
if(auto queryString = components(1)) {
|
||||
|
@ -87,7 +87,7 @@ auto Response::head(const function<bool (const uint8_t*, unsigned)>& callback) c
|
||||
}
|
||||
|
||||
auto Response::setHead() -> bool {
|
||||
lstring headers = _head.split("\n");
|
||||
auto headers = _head.split("\n");
|
||||
string response = headers.takeLeft().trimRight("\r");
|
||||
|
||||
if(response.ibeginsWith("HTTP/1.0 ")) response.itrimLeft("HTTP/1.0 ", 1L);
|
||||
@ -98,7 +98,7 @@ auto Response::setHead() -> bool {
|
||||
|
||||
for(auto& header : headers) {
|
||||
if(header.beginsWith(" ") || header.beginsWith("\t")) continue;
|
||||
lstring variable = header.split(":", 1L).strip();
|
||||
auto variable = header.split(":", 1L).strip();
|
||||
if(variable.size() != 2) continue;
|
||||
this->header.append(variable[0], variable[1]);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <nall/string.hpp>
|
||||
|
||||
namespace nall {
|
||||
auto main(lstring arguments) -> void;
|
||||
auto main(string_vector arguments) -> void;
|
||||
|
||||
auto main(int argc, char** argv) -> int {
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
@ -17,8 +17,16 @@ namespace nall {
|
||||
utf8_args(argc, argv);
|
||||
#endif
|
||||
|
||||
lstring arguments;
|
||||
for(auto n : range(argc)) arguments.append(argv[n]);
|
||||
string_vector arguments;
|
||||
for(auto n : range(argc)) {
|
||||
string argument = argv[n];
|
||||
|
||||
//normalize directory and file path arguments
|
||||
if(directory::exists(argument)) argument.transform("\\", "/").trimRight("/").append("/");
|
||||
else if(file::exists(argument)) argument.transform("\\", "/").trimRight("/");
|
||||
|
||||
arguments.append(argument);
|
||||
}
|
||||
|
||||
return main(move(arguments)), EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -65,13 +65,13 @@ struct context {
|
||||
if(c == ',' && function == true) c = ';';
|
||||
}
|
||||
|
||||
lstring list = expression.split(",");
|
||||
auto list = expression.split(",");
|
||||
for(auto& item : list) {
|
||||
item.strip();
|
||||
if(item.match("f(?*) ?*")) {
|
||||
item.trimLeft("f(", 1L);
|
||||
lstring part = item.split(") ", 1L);
|
||||
lstring args = part[0].split(";", 3L).strip();
|
||||
auto part = item.split(") ", 1L);
|
||||
auto args = part[0].split(";", 3L).strip();
|
||||
|
||||
uint length = eval(args(0, "0"));
|
||||
uint offset = eval(args(1, "0"));
|
||||
@ -93,7 +93,7 @@ struct context {
|
||||
item.trimLeft("base64", 1L);
|
||||
if(item.match("(?*) *")) {
|
||||
item.trimLeft("(", 1L);
|
||||
lstring part = item.split(") ", 1L);
|
||||
auto part = item.split(") ", 1L);
|
||||
offset = eval(part[0]);
|
||||
item = part(1, "");
|
||||
}
|
||||
@ -118,9 +118,9 @@ struct context {
|
||||
auto parse(const string& data) -> void {
|
||||
reset();
|
||||
|
||||
lstring lines = data.split("\n");
|
||||
auto lines = data.split("\n");
|
||||
for(auto& line : lines) {
|
||||
lstring part = line.split(":", 1L).strip();
|
||||
auto part = line.split(":", 1L).strip();
|
||||
if(part.size() != 2) continue;
|
||||
|
||||
if(part[0] == "offset") offset = eval(part[1]);
|
||||
|
@ -217,6 +217,7 @@ private:
|
||||
using boolean = nall::Boolean;
|
||||
using integer = nall::Integer<sizeof( int) * 8>;
|
||||
using natural = nall::Natural<sizeof(uint) * 8>;
|
||||
using real = nall::Real<sizeof(double) * 8>;
|
||||
|
||||
using int1 = nall::Integer< 1>;
|
||||
using int2 = nall::Integer< 2>;
|
||||
@ -348,6 +349,6 @@ using uint62 = nall::Natural<62>;
|
||||
using uint63 = nall::Natural<63>;
|
||||
using uint64 = nall::Natural<64>;
|
||||
|
||||
using float32 = nall::Real<32>;
|
||||
using float64 = nall::Real<64>;
|
||||
//using float80 = nall::Real<80>;
|
||||
using real32 = nall::Real<32>;
|
||||
using real64 = nall::Real<64>;
|
||||
//using real80 = nall::Real<80>;
|
||||
|
@ -36,7 +36,7 @@ template<typename... P> inline auto execute(const string& name, P&&... p) -> exe
|
||||
if(pid == 0) {
|
||||
const char* argv[1 + sizeof...(p) + 1];
|
||||
const char** argp = argv;
|
||||
lstring argl(forward<P>(p)...);
|
||||
string_vector argl(forward<P>(p)...);
|
||||
*argp++ = (const char*)name;
|
||||
for(auto& arg : argl) *argp++ = (const char*)arg;
|
||||
*argp++ = nullptr;
|
||||
@ -92,7 +92,7 @@ template<typename... P> inline auto invoke(const string& name, P&&... p) -> void
|
||||
if(pid == 0) {
|
||||
const char* argv[1 + sizeof...(p) + 1];
|
||||
const char** argp = argv;
|
||||
lstring argl(forward<P>(p)...);
|
||||
string_vector argl(forward<P>(p)...);
|
||||
*argp++ = (const char*)name;
|
||||
for(auto& arg : argl) *argp++ = (const char*)arg;
|
||||
*argp++ = nullptr;
|
||||
@ -107,7 +107,7 @@ template<typename... P> inline auto invoke(const string& name, P&&... p) -> void
|
||||
#elif defined(PLATFORM_WINDOWS)
|
||||
|
||||
template<typename... P> inline auto execute(const string& name, P&&... p) -> execute_result_t {
|
||||
lstring argl(name, forward<P>(p)...);
|
||||
string_vector argl(name, forward<P>(p)...);
|
||||
for(auto& arg : argl) if(arg.find(" ")) arg = {"\"", arg, "\""};
|
||||
string arguments = argl.merge(" ");
|
||||
|
||||
@ -189,7 +189,7 @@ template<typename... P> inline auto execute(const string& name, P&&... p) -> exe
|
||||
}
|
||||
|
||||
template<typename... P> inline auto invoke(const string& name, P&&... p) -> void {
|
||||
lstring argl(forward<P>(p)...);
|
||||
string_vector argl(forward<P>(p)...);
|
||||
for(auto& arg : argl) if(arg.find(" ")) arg = {"\"", arg, "\""};
|
||||
string arguments = argl.merge(" ");
|
||||
ShellExecute(nullptr, nullptr, utf16_t(name), utf16_t(arguments), nullptr, SW_SHOWNORMAL);
|
||||
|
@ -28,9 +28,6 @@ struct string_view;
|
||||
struct string_vector;
|
||||
struct string_format;
|
||||
|
||||
//legacy naming convention
|
||||
using lstring = string_vector;
|
||||
|
||||
struct string_view {
|
||||
inline string_view();
|
||||
inline string_view(const string_view& source);
|
||||
@ -66,14 +63,11 @@ template<typename T> struct stringify;
|
||||
template<typename... P> inline auto print(P&&...) -> void;
|
||||
template<typename... P> inline auto print(FILE*, P&&...) -> void;
|
||||
template<typename T> inline auto numeral(T value, long precision = 0, char padchar = '0') -> string;
|
||||
//inline auto integer(intmax_t value, long precision = 0, char padchar = '0') -> string;
|
||||
//inline auto natural(uintmax_t value, long precision = 0, char padchar = '0') -> string;
|
||||
inline auto hex(uintmax_t value, long precision = 0, char padchar = '0') -> string;
|
||||
inline auto octal(uintmax_t value, long precision = 0, char padchar = '0') -> string;
|
||||
inline auto binary(uintmax_t value, long precision = 0, char padchar = '0') -> string;
|
||||
template<typename T> inline auto pointer(const T* value, long precision = 0) -> string;
|
||||
inline auto pointer(uintptr_t value, long precision = 0) -> string;
|
||||
//inline auto real(long double value) -> string;
|
||||
|
||||
//match.hpp
|
||||
inline auto tokenize(const char* s, const char* p) -> bool;
|
||||
|
@ -80,7 +80,7 @@ protected:
|
||||
}
|
||||
|
||||
//read a node and all of its child nodes
|
||||
auto parseNode(const lstring& text, uint& y) -> void {
|
||||
auto parseNode(const string_vector& text, uint& y) -> void {
|
||||
const char* p = text[y++];
|
||||
_metadata = parseDepth(p);
|
||||
parseName(p);
|
||||
@ -166,7 +166,7 @@ inline auto serialize(const Markup::Node& node, uint depth = 0) -> string {
|
||||
padding.resize(depth * 2);
|
||||
for(auto& byte : padding) byte = ' ';
|
||||
|
||||
lstring lines;
|
||||
string_vector lines;
|
||||
if(auto value = node.value()) lines = value.split("\n");
|
||||
|
||||
string result;
|
||||
|
@ -20,7 +20,7 @@ auto ManagedNode::_evaluate(string query) const -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
lstring side;
|
||||
string_vector side;
|
||||
switch(comparator) {
|
||||
case Comparator::EQ: side = rule.split ("=", 1L); break;
|
||||
case Comparator::NE: side = rule.split("!=", 1L); break;
|
||||
@ -55,7 +55,7 @@ auto ManagedNode::_evaluate(string query) const -> bool {
|
||||
auto ManagedNode::_find(const string& query) const -> vector<Node> {
|
||||
vector<Node> result;
|
||||
|
||||
lstring path = query.split("/");
|
||||
auto path = query.split("/");
|
||||
string name = path.take(0), rule;
|
||||
uint lo = 0u, hi = ~0u;
|
||||
|
||||
|
@ -54,8 +54,8 @@ auto CML::parseDocument(const string& filedata, const string& pathname, uint dep
|
||||
};
|
||||
|
||||
for(auto& block : filedata.split("\n\n")) {
|
||||
lstring lines = block.stripRight().split("\n");
|
||||
string name = lines.takeLeft();
|
||||
auto lines = block.stripRight().split("\n");
|
||||
auto name = lines.takeLeft();
|
||||
|
||||
if(name.beginsWith("include ")) {
|
||||
name.trimLeft("include ", 1L);
|
||||
|
@ -24,7 +24,7 @@ namespace nall {
|
||||
|
||||
struct registry {
|
||||
static auto exists(const string& name) -> bool {
|
||||
lstring part = name.split("/");
|
||||
auto part = name.split("/");
|
||||
HKEY handle, rootKey = root(part.takeLeft());
|
||||
string node = part.takeRight();
|
||||
string path = part.merge("\\");
|
||||
@ -39,7 +39,7 @@ struct registry {
|
||||
}
|
||||
|
||||
static auto read(const string& name) -> string {
|
||||
lstring part = name.split("/");
|
||||
auto part = name.split("/");
|
||||
HKEY handle, rootKey = root(part.takeLeft());
|
||||
string node = part.takeRight();
|
||||
string path = part.merge("\\");
|
||||
@ -54,7 +54,7 @@ struct registry {
|
||||
}
|
||||
|
||||
static auto write(const string& name, const string& data = "") -> void {
|
||||
lstring part = name.split("/");
|
||||
auto part = name.split("/");
|
||||
HKEY handle, rootKey = root(part.takeLeft());
|
||||
string node = part.takeRight(), path;
|
||||
DWORD disposition;
|
||||
@ -71,7 +71,7 @@ struct registry {
|
||||
}
|
||||
|
||||
static auto remove(const string& name) -> bool {
|
||||
lstring part = name.split("/");
|
||||
auto part = name.split("/");
|
||||
HKEY rootKey = root(part.takeLeft());
|
||||
string node = part.takeRight();
|
||||
string path = part.merge("\\");
|
||||
@ -79,8 +79,8 @@ struct registry {
|
||||
return SHDeleteValueW(rootKey, utf16_t(path), utf16_t(node)) == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static auto contents(const string& name) -> lstring {
|
||||
lstring part = name.split("/"), result;
|
||||
static auto contents(const string& name) -> string_vector {
|
||||
auto part = name.split("/"), result;
|
||||
HKEY handle, rootKey = root(part.takeLeft());
|
||||
part.removeRight();
|
||||
string path = part.merge("\\");
|
||||
|
@ -172,8 +172,8 @@ struct AudioOpenAL : Audio {
|
||||
}
|
||||
|
||||
private:
|
||||
auto queryDevices() -> lstring {
|
||||
lstring result;
|
||||
auto queryDevices() -> string_vector {
|
||||
string_vector result;
|
||||
|
||||
const char* buffer = alcGetString(nullptr, ALC_DEVICE_SPECIFIER);
|
||||
if(!buffer) return result;
|
||||
|
@ -179,7 +179,7 @@ auto Video::safestDriver() -> string {
|
||||
#endif
|
||||
}
|
||||
|
||||
auto Video::availableDrivers() -> lstring {
|
||||
auto Video::availableDrivers() -> string_vector {
|
||||
return {
|
||||
|
||||
#if defined(VIDEO_WGL)
|
||||
@ -364,7 +364,7 @@ auto Audio::safestDriver() -> string {
|
||||
#endif
|
||||
}
|
||||
|
||||
auto Audio::availableDrivers() -> lstring {
|
||||
auto Audio::availableDrivers() -> string_vector {
|
||||
return {
|
||||
|
||||
#if defined(AUDIO_WASAPI)
|
||||
@ -508,7 +508,7 @@ auto Input::safestDriver() -> string {
|
||||
#endif
|
||||
}
|
||||
|
||||
auto Input::availableDrivers() -> lstring {
|
||||
auto Input::availableDrivers() -> string_vector {
|
||||
return {
|
||||
|
||||
#if defined(INPUT_WINDOWS)
|
||||
|
@ -26,7 +26,7 @@ struct Video {
|
||||
static auto create(const nall::string& driver = "") -> Video*;
|
||||
static auto optimalDriver() -> nall::string;
|
||||
static auto safestDriver() -> nall::string;
|
||||
static auto availableDrivers() -> nall::lstring;
|
||||
static auto availableDrivers() -> nall::string_vector;
|
||||
|
||||
virtual ~Video() = default;
|
||||
|
||||
@ -54,7 +54,7 @@ struct Audio {
|
||||
static auto create(const nall::string& driver = "") -> Audio*;
|
||||
static auto optimalDriver() -> nall::string;
|
||||
static auto safestDriver() -> nall::string;
|
||||
static auto availableDrivers() -> nall::lstring;
|
||||
static auto availableDrivers() -> nall::string_vector;
|
||||
|
||||
virtual ~Audio() = default;
|
||||
|
||||
@ -79,7 +79,7 @@ struct Input {
|
||||
static auto create(const nall::string& driver = "") -> Input*;
|
||||
static auto optimalDriver() -> nall::string;
|
||||
static auto safestDriver() -> nall::string;
|
||||
static auto availableDrivers() -> nall::lstring;
|
||||
static auto availableDrivers() -> nall::string_vector;
|
||||
|
||||
virtual ~Input() = default;
|
||||
|
||||
|
@ -72,7 +72,7 @@ auto OpenGLProgram::bind(OpenGL* instance, const Markup::Node& node, const strin
|
||||
|
||||
//apply manifest settings to shader source #in tags
|
||||
auto OpenGLProgram::parse(OpenGL* instance, string& source) -> void {
|
||||
lstring lines = source.split("\n");
|
||||
auto lines = source.split("\n");
|
||||
for(auto& line : lines) {
|
||||
string s = line;
|
||||
if(auto position = s.find("//")) s.resize(position()); //strip comments
|
||||
|
Loading…
Reference in New Issue
Block a user