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:
Tim Allen 2016-07-01 21:58:12 +10:00
parent 82293c95ae
commit 8d5cc0c35e
78 changed files with 509 additions and 546 deletions

View File

@ -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/";

View File

@ -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; }

View File

@ -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());
}

View File

@ -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;

View File

@ -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());
}

View File

@ -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;

View File

@ -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) {

View File

@ -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"

View File

@ -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);
}
}
}

View 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);
}
}
}

View File

@ -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;

View File

@ -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

View File

@ -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());
}

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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

View File

@ -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})

View File

@ -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});

View File

@ -1,6 +1,6 @@
struct Program : Emulator::Interface::Bind {
//program.cpp
Program(lstring args);
Program(string_vector args);
auto main() -> void;
auto quit() -> void;

View File

@ -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();

View File

@ -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);

View File

@ -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());
}

View File

@ -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;

View File

@ -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];

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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; }

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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;
};

View File

@ -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();

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -18,7 +18,7 @@ struct pConsole : pWidget {
GtkWidget* subWidget = nullptr;
GtkTextBuffer* textBuffer = nullptr;
string previousPrompt;
lstring history;
string_vector history;
unsigned historyOffset = 0;
};

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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) {

View File

@ -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(" ", "");

View File

@ -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];

View File

@ -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);
}

View File

@ -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)) {

View File

@ -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");
}

View File

@ -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;

View File

@ -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()});

View File

@ -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}};

View File

@ -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});

View File

@ -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));
}

View File

@ -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;
}
};
}

View File

@ -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);

View File

@ -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)) {

View File

@ -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();
}

View File

@ -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)) {

View File

@ -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]);
}

View File

@ -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;
}

View File

@ -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]);

View File

@ -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>;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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("\\");

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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