diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 7e71519f..1c01c7d7 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -12,7 +12,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "102.20"; + static const string Version = "102.21"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/gba/ppu/io.cpp b/higan/gba/ppu/io.cpp index e3173e9f..b3ace9ee 100644 --- a/higan/gba/ppu/io.cpp +++ b/higan/gba/ppu/io.cpp @@ -68,7 +68,7 @@ auto PPU::readIO(uint32 addr) -> uint8 { case 0x0400'004a: return window3.io.active[BG0] << 0 | window3.io.active[BG1] << 1 | window3.io.active[BG2] << 2 | window3.io.active[BG3] << 3 | window3.io.active[OBJ] << 4 | window3.io.active[SFX] << 5; //WININ2 - case 0x0400'004b: return window2.io.active[BG0] << 0 | window2.io.active[BG1] << 1 | window2.io.active[BG2] << 3 | window2.io.active[BG3] << 3 | window2.io.active[OBJ] << 4 | window2.io.active[SFX] << 5; + case 0x0400'004b: return window2.io.active[BG0] << 0 | window2.io.active[BG1] << 1 | window2.io.active[BG2] << 2 | window2.io.active[BG3] << 3 | window2.io.active[OBJ] << 4 | window2.io.active[SFX] << 5; //MOSAIC (write-only) @@ -266,7 +266,7 @@ auto PPU::writeIO(uint32 addr, uint8 data) -> void { //BG3PB case 0x0400'0032: bg3.io.pb.byte(0) = data; return; - case 0x0400'0033: bg3.io.pb.byte(0) = data; return; + case 0x0400'0033: bg3.io.pb.byte(1) = data; return; //BG3PC case 0x0400'0034: bg3.io.pc.byte(0) = data; return; diff --git a/higan/processor/r65816/instructions-misc.cpp b/higan/processor/r65816/instructions-misc.cpp index 58b383f4..ab45999b 100644 --- a/higan/processor/r65816/instructions-misc.cpp +++ b/higan/processor/r65816/instructions-misc.cpp @@ -53,15 +53,16 @@ L r.pc.h = readLong(vector + 1); r.pc.b = 0x00; } -auto R65816::op_stp() { - while(r.wai = true) { +auto R65816::op_stp() -> void { + r.stp = true; + while(r.stp && !synchronizing()) { L idle(); } } -auto R65816::op_wai() { +auto R65816::op_wai() -> void { r.wai = true; - while(r.wai) { + while(r.wai && !synchronizing()) { L idle(); } idle(); diff --git a/higan/processor/r65816/r65816.hpp b/higan/processor/r65816/r65816.hpp index c1827a69..d3eb2868 100644 --- a/higan/processor/r65816/r65816.hpp +++ b/higan/processor/r65816/r65816.hpp @@ -19,6 +19,7 @@ struct R65816 { virtual auto lastCycle() -> void = 0; virtual auto interruptPending() const -> bool = 0; virtual auto interrupt() -> void; + virtual auto synchronizing() const -> bool = 0; virtual auto readDisassembler(uint24 addr) -> uint8 { return 0; } @@ -174,8 +175,8 @@ struct R65816 { auto op_move_b(int adjust); auto op_move_w(int adjust); auto op_interrupt(uint16); - auto op_stp(); - auto op_wai(); + auto op_stp() -> void; + auto op_wai() -> void; auto op_xce(); auto op_set_flag(uint bit); auto op_clear_flag(uint bit); diff --git a/higan/processor/r65816/registers.hpp b/higan/processor/r65816/registers.hpp index 2d9baff8..369e0101 100644 --- a/higan/processor/r65816/registers.hpp +++ b/higan/processor/r65816/registers.hpp @@ -75,6 +75,7 @@ struct Registers { bool irq = false; //IRQ pin (0 = low, 1 = trigger) bool wai = false; //raised during wai, cleared after interrupt triggered + bool stp = false; //raised during stp, never cleared uint8 mdr = 0; //memory data register uint16 vector = 0; //interrupt vector address }; diff --git a/higan/processor/r65816/serialization.cpp b/higan/processor/r65816/serialization.cpp index d3f20a92..fd2d1730 100644 --- a/higan/processor/r65816/serialization.cpp +++ b/higan/processor/r65816/serialization.cpp @@ -14,6 +14,7 @@ auto R65816::serialize(serializer& s) -> void { s.integer(r.e); s.integer(r.irq); s.integer(r.wai); + s.integer(r.stp); s.integer(r.mdr); s.integer(r.vector); diff --git a/higan/sfc/coprocessor/sa1/sa1.cpp b/higan/sfc/coprocessor/sa1/sa1.cpp index 0593862f..44599c07 100644 --- a/higan/sfc/coprocessor/sa1/sa1.cpp +++ b/higan/sfc/coprocessor/sa1/sa1.cpp @@ -14,6 +14,9 @@ auto SA1::Enter() -> void { } auto SA1::main() -> void { + if(r.wai) return op_wai(); + if(r.stp) return op_stp(); + if(mmio.sa1_rdyb || mmio.sa1_resb) { //SA-1 co-processor is asleep tick(); @@ -75,6 +78,10 @@ auto SA1::interruptPending() const -> bool { return status.interruptPending; } +auto SA1::synchronizing() const -> bool { + return scheduler.synchronizing(); +} + auto SA1::tick() -> void { step(2); if(++status.counter == 0) synchronize(cpu); @@ -142,6 +149,7 @@ auto SA1::power() -> void { r.e = 1; r.mdr = 0x00; r.wai = false; + r.stp = false; r.vector = 0x0000; status.counter = 0; diff --git a/higan/sfc/coprocessor/sa1/sa1.hpp b/higan/sfc/coprocessor/sa1/sa1.hpp index a056b9be..45683641 100644 --- a/higan/sfc/coprocessor/sa1/sa1.hpp +++ b/higan/sfc/coprocessor/sa1/sa1.hpp @@ -8,6 +8,7 @@ struct SA1 : Processor::R65816, Thread { alwaysinline auto triggerIRQ() -> void; alwaysinline auto lastCycle() -> void override; alwaysinline auto interruptPending() const -> bool override; + auto synchronizing() const -> bool override; auto init() -> void; auto load() -> void; diff --git a/higan/sfc/cpu/cpu.cpp b/higan/sfc/cpu/cpu.cpp index 60bdd169..4a592702 100644 --- a/higan/sfc/cpu/cpu.cpp +++ b/higan/sfc/cpu/cpu.cpp @@ -13,6 +13,7 @@ CPU cpu; auto CPU::interruptPending() const -> bool { return status.interruptPending; } auto CPU::pio() const -> uint8 { return io.pio; } auto CPU::joylatch() const -> bool { return io.joypadStrobeLatch; } +auto CPU::synchronizing() const -> bool { return scheduler.synchronizing(); } CPU::CPU() { PPUcounter::scanline = {&CPU::scanline, this}; @@ -23,6 +24,9 @@ auto CPU::Enter() -> void { } auto CPU::main() -> void { + if(r.wai) return op_wai(); + if(r.stp) return op_stp(); + if(status.interruptPending) { status.interruptPending = false; if(status.nmiPending) { @@ -93,6 +97,7 @@ auto CPU::power() -> void { r.e = 1; r.mdr = 0x00; r.wai = false; + r.stp = false; r.vector = 0xfffc; //reset vector address //DMA @@ -209,7 +214,6 @@ auto CPU::power() -> void { status.interruptPending = true; status.dmaActive = false; - status.dmaCounter = 0; status.dmaClocks = 0; status.dmaPending = false; status.hdmaPending = false; diff --git a/higan/sfc/cpu/cpu.hpp b/higan/sfc/cpu/cpu.hpp index 49859488..4ed0424e 100644 --- a/higan/sfc/cpu/cpu.hpp +++ b/higan/sfc/cpu/cpu.hpp @@ -2,6 +2,7 @@ struct CPU : Processor::R65816, Thread, PPUcounter { auto interruptPending() const -> bool override; auto pio() const -> uint8; auto joylatch() const -> bool; + auto synchronizing() const -> bool override; CPU(); @@ -122,7 +123,6 @@ private: //DMA bool dmaActive; - uint dmaCounter; uint dmaClocks; bool dmaPending; bool hdmaPending; diff --git a/higan/sfc/cpu/serialization.cpp b/higan/sfc/cpu/serialization.cpp index 27e84ea4..c3814482 100644 --- a/higan/sfc/cpu/serialization.cpp +++ b/higan/sfc/cpu/serialization.cpp @@ -40,7 +40,6 @@ auto CPU::serialize(serializer& s) -> void { s.integer(status.resetPending); s.integer(status.dmaActive); - s.integer(status.dmaCounter); s.integer(status.dmaClocks); s.integer(status.dmaPending); s.integer(status.hdmaPending); diff --git a/higan/sfc/cpu/timing.cpp b/higan/sfc/cpu/timing.cpp index 6449d8a2..2676802c 100644 --- a/higan/sfc/cpu/timing.cpp +++ b/higan/sfc/cpu/timing.cpp @@ -1,19 +1,13 @@ -auto CPU::dmaCounter() const -> uint { - return clockCounter & 7; -//return (status.dmaCounter + hcounter()) & 7; -} - -auto CPU::joypadCounter() const -> uint { - return clockCounter & 255; -} +auto CPU::dmaCounter() const -> uint { return clockCounter & 7; } +auto CPU::joypadCounter() const -> uint { return clockCounter & 255; } auto CPU::step(uint clocks) -> void { status.irqLock = false; uint ticks = clocks >> 1; while(ticks--) { + clockCounter += 2; tick(); if(hcounter() & 2) pollInterrupts(); - clockCounter += 2; if(joypadCounter() == 0) joypadEdge(); } @@ -37,7 +31,6 @@ auto CPU::step(uint clocks) -> void { //called by ppu.tick() when Hcounter=0 auto CPU::scanline() -> void { - status.dmaCounter = (status.dmaCounter + status.lineClocks) & 7; status.lineClocks = lineclocks(); //forcefully sync S-CPU to other processors, in case chips are not communicating diff --git a/higan/sfc/ppu/counter/counter-inline.hpp b/higan/sfc/ppu/counter/counter-inline.hpp index 711bf89b..bf43cca1 100644 --- a/higan/sfc/ppu/counter/counter-inline.hpp +++ b/higan/sfc/ppu/counter/counter-inline.hpp @@ -2,7 +2,7 @@ //keeps track of previous counter positions in history table auto PPUcounter::tick() -> void { status.hcounter += 2; //increment by smallest unit of time - if(status.hcounter >= 1360 && status.hcounter == lineclocks()) { + if(status.hcounter == lineclocks()) { status.hcounter = 0; vcounterTick(); } @@ -27,12 +27,12 @@ auto PPUcounter::tick(uint clocks) -> void { auto PPUcounter::vcounterTick() -> void { if(++status.vcounter == 128) status.interlace = ppu.interlace(); - if((system.region() == System::Region::NTSC && status.interlace == false && status.vcounter == 262) - || (system.region() == System::Region::NTSC && status.interlace == true && status.vcounter == 263) - || (system.region() == System::Region::NTSC && status.interlace == true && status.vcounter == 262 && status.field == 1) - || (system.region() == System::Region::PAL && status.interlace == false && status.vcounter == 312) - || (system.region() == System::Region::PAL && status.interlace == true && status.vcounter == 313) - || (system.region() == System::Region::PAL && status.interlace == true && status.vcounter == 312 && status.field == 1) + if((system.region() == System::Region::NTSC && status.interlace == 0 && status.vcounter == 262) + || (system.region() == System::Region::NTSC && status.interlace == 1 && status.vcounter == 263) + || (system.region() == System::Region::NTSC && status.interlace == 1 && status.vcounter == 262 && status.field == 1) + || (system.region() == System::Region::PAL && status.interlace == 0 && status.vcounter == 312) + || (system.region() == System::Region::PAL && status.interlace == 1 && status.vcounter == 313) + || (system.region() == System::Region::PAL && status.interlace == 1 && status.vcounter == 312 && status.field == 1) ) { status.vcounter = 0; status.field = !status.field; @@ -58,7 +58,7 @@ auto PPUcounter::hcounter(uint offset) const -> uint16 { return history.hcounter //dot 327 range = {1310, 1312, 1314} auto PPUcounter::hdot() const -> uint16 { - if(system.region() == System::Region::NTSC && status.interlace == false && vcounter() == 240 && field() == 1) { + if(system.region() == System::Region::NTSC && status.interlace == 0 && vcounter() == 240 && field() == 1) { return (hcounter() >> 2); } else { return (hcounter() - ((hcounter() > 1292) << 1) - ((hcounter() > 1310) << 1)) >> 2; @@ -66,12 +66,12 @@ auto PPUcounter::hdot() const -> uint16 { } auto PPUcounter::lineclocks() const -> uint16 { - if(system.region() == System::Region::NTSC && status.interlace == false && vcounter() == 240 && field() == 1) return 1360; + if(system.region() == System::Region::NTSC && status.interlace == 0 && vcounter() == 240 && field() == 1) return 1360; return 1364; } auto PPUcounter::reset() -> void { - status.interlace = false; + status.interlace = 0; status.field = 0; status.vcounter = 0; status.hcounter = 0; diff --git a/higan/target-tomoko/input/input.cpp b/higan/target-tomoko/input/input.cpp index b8fcb68b..eb0a339a 100644 --- a/higan/target-tomoko/input/input.cpp +++ b/higan/target-tomoko/input/input.cpp @@ -2,30 +2,56 @@ #include "hotkeys.cpp" unique_pointer inputManager; +//build mappings list from assignment string auto InputMapping::bind() -> void { - auto token = assignment.split("/"); - if(token.size() < 3) return unbind(); - uint64 id = token[0].natural(); - uint group = token[1].natural(); - uint input = token[2].natural(); - string qualifier = token(3, "None"); + mappings.reset(); - for(auto& device : inputManager->devices) { - if(id != device->id()) continue; + auto list = assignment.split(logic() == Logic::AND ? "&" : "|"); + for(auto& item : list) { + auto token = item.split("/"); + if(token.size() < 3) continue; //skip invalid mappings - this->device = device; - this->group = group; - this->input = input; - this->qualifier = Qualifier::None; - if(qualifier == "Lo") this->qualifier = Qualifier::Lo; - if(qualifier == "Hi") this->qualifier = Qualifier::Hi; - if(qualifier == "Rumble") this->qualifier = Qualifier::Rumble; - break; + uint64 id = token[0].natural(); + uint group = token[1].natural(); + uint input = token[2].natural(); + string qualifier = token(3, "None"); + + Mapping mapping; + for(auto& device : inputManager->devices) { + if(id != device->id()) continue; + + mapping.device = device; + mapping.group = group; + mapping.input = input; + mapping.qualifier = Qualifier::None; + if(qualifier == "Lo") mapping.qualifier = Qualifier::Lo; + if(qualifier == "Hi") mapping.qualifier = Qualifier::Hi; + if(qualifier == "Rumble") mapping.qualifier = Qualifier::Rumble; + break; + } + + if(!mapping.device) continue; + mappings.append(mapping); } settings[path].setValue(assignment); } +//append new mapping to mappings list +auto InputMapping::bind(string mapping) -> void { + auto list = assignment.split(logic() == Logic::AND ? "&" : "|"); + if(list.find(mapping)) return; //already in the mappings list + if(!assignment || assignment == "None") { + //create new mapping + assignment = mapping; + } else { + //add additional mapping + assignment.append(logic() == Logic::AND ? "&" : "|"); + assignment.append(mapping); + } + bind(); +} + auto InputMapping::bind(shared_pointer device, uint group, uint input, int16 oldValue, int16 newValue) -> bool { if(device->isNull() || (device->isKeyboard() && device->group(group).input(input).name() == "Escape")) { return unbind(), true; @@ -38,8 +64,7 @@ auto InputMapping::bind(shared_pointer device, uint group, uint inp || (device->isMouse() && group == HID::Mouse::GroupID::Button) || (device->isJoypad() && group == HID::Joypad::GroupID::Button)) { if(newValue) { - this->assignment = encoding; - return bind(), true; + return bind(encoding), true; } } @@ -47,13 +72,11 @@ auto InputMapping::bind(shared_pointer device, uint group, uint inp || (device->isJoypad() && group == HID::Joypad::GroupID::Hat) || (device->isJoypad() && group == HID::Joypad::GroupID::Trigger)) { if(newValue < -16384 && group != HID::Joypad::GroupID::Trigger) { //triggers are always hi - this->assignment = {encoding, "/Lo"}; - return bind(), true; + return bind({encoding, "/Lo"}), true; } if(newValue > +16384) { - this->assignment = {encoding, "/Hi"}; - return bind(), true; + return bind({encoding, "/Hi"}), true; } } } @@ -63,8 +86,7 @@ auto InputMapping::bind(shared_pointer device, uint group, uint inp || (device->isJoypad() && group == HID::Joypad::GroupID::Axis) || (device->isJoypad() && group == HID::Joypad::GroupID::Hat)) { if(newValue < -16384 || newValue > +16384) { - this->assignment = encoding; - return bind(), true; + return bind(encoding), true; } } } @@ -72,8 +94,7 @@ auto InputMapping::bind(shared_pointer device, uint group, uint inp if(isRumble()) { if(device->isJoypad() && group == HID::Joypad::GroupID::Button) { if(newValue) { - this->assignment = {encoding, "/Rumble"}; - return bind(), true; + return bind({encoding, "/Rumble"}), true; } } } @@ -82,62 +103,86 @@ auto InputMapping::bind(shared_pointer device, uint group, uint inp } auto InputMapping::poll() -> int16 { - if(!device) return 0; - auto value = device->group(group).input(input).value(); + if(!mappings) return 0; if(isDigital()) { - if(device->isKeyboard() && group == HID::Keyboard::GroupID::Button) return value != 0; - if(device->isMouse() && group == HID::Mouse::GroupID::Button) return value != 0; - if(device->isJoypad() && group == HID::Joypad::GroupID::Button) return value != 0; - if((device->isJoypad() && group == HID::Joypad::GroupID::Axis) - || (device->isJoypad() && group == HID::Joypad::GroupID::Hat) - || (device->isJoypad() && group == HID::Joypad::GroupID::Trigger)) { - if(qualifier == Qualifier::Lo) return value < -16384; - if(qualifier == Qualifier::Hi) return value > +16384; + bool result = logic() == Logic::AND ? 1 : 0; + + for(auto& mapping : mappings) { + auto value = mapping.device->group(mapping.group).input(mapping.input).value(); + bool output = logic() == Logic::AND ? 0 : 1; + + if(mapping.device->isKeyboard() && mapping.group == HID::Keyboard::GroupID::Button) output = value != 0; + if(mapping.device->isMouse() && mapping.group == HID::Mouse::GroupID::Button) output = value != 0; + if(mapping.device->isJoypad() && mapping.group == HID::Joypad::GroupID::Button) output = value != 0; + if((mapping.device->isJoypad() && mapping.group == HID::Joypad::GroupID::Axis) + || (mapping.device->isJoypad() && mapping.group == HID::Joypad::GroupID::Hat) + || (mapping.device->isJoypad() && mapping.group == HID::Joypad::GroupID::Trigger)) { + if(mapping.qualifier == Qualifier::Lo) output = value < -16384; + if(mapping.qualifier == Qualifier::Hi) output = value > +16384; + } + + if(logic() == Logic::AND) result &= output; + if(logic() == Logic::OR ) result |= output; } + + return result; } if(isAnalog()) { - if(device->isMouse() && group == HID::Mouse::GroupID::Axis) return value; - if(device->isJoypad() && group == HID::Joypad::GroupID::Axis) return value >> 8; - if(device->isJoypad() && group == HID::Joypad::GroupID::Hat) return value < 0 ? -1 : value > 0 ? +1 : 0; + int16 result = 0; + + for(auto& mapping : mappings) { + auto value = mapping.device->group(mapping.group).input(mapping.input).value(); + + //logic does not apply to analog inputs ... always combinatorial + if(mapping.device->isMouse() && mapping.group == HID::Mouse::GroupID::Axis) result += value; + if(mapping.device->isJoypad() && mapping.group == HID::Joypad::GroupID::Axis) result += value >> 8; + if(mapping.device->isJoypad() && mapping.group == HID::Joypad::GroupID::Hat) result += value < 0 ? -1 : value > 0 ? +1 : 0; + } + + return result; } return 0; } auto InputMapping::rumble(bool enable) -> void { - if(!device) return; - ::input->rumble(device->id(), enable); + if(!mappings) return; + for(auto& mapping : mappings) { + ::input->rumble(mapping.device->id(), enable); + } } auto InputMapping::unbind() -> void { + mappings.reset(); assignment = "None"; - device = nullptr; - group = 0; - input = 0; - qualifier = Qualifier::None; settings[path].setValue(assignment); } -auto InputMapping::assignmentName() -> string { - if(!device) return "None"; - string path; - path.append(device->name()); - if(device->name() != "Keyboard") { - //keyboards only have one group; no need to append group name - path.append(".", device->group(group).name()); - } - path.append(".", device->group(group).input(input).name()); - if(qualifier == Qualifier::Lo) path.append(".Lo"); - if(qualifier == Qualifier::Hi) path.append(".Hi"); - if(qualifier == Qualifier::Rumble) path.append(".Rumble"); - return path; -} +//create a human-readable string from mappings list for display in the user interface +auto InputMapping::displayName() -> string { + if(!mappings) return "None"; -auto InputMapping::deviceName() -> string { - if(!device) return ""; - return hex(device->id()); + string path; + for(auto& mapping : mappings) { + path.append(mapping.device->name()); + if(mapping.device->name() != "Keyboard" && mapping.device->name() != "Mouse") { + //show device IDs to distinguish between multiple joypads + path.append("(", hex(mapping.device->id()), ")"); + } + if(mapping.device->name() != "Keyboard") { + //keyboards only have one group; no need to append group name + path.append(".", mapping.device->group(mapping.group).name()); + } + path.append(".", mapping.device->group(mapping.group).input(mapping.input).name()); + if(mapping.qualifier == Qualifier::Lo) path.append(".Lo"); + if(mapping.qualifier == Qualifier::Hi) path.append(".Hi"); + if(mapping.qualifier == Qualifier::Rumble) path.append(".Rumble"); + path.append(logic() == Logic::AND ? " and " : " or "); + } + + return path.trimRight(logic() == Logic::AND ? " and " : " or ", 1L); } // diff --git a/higan/target-tomoko/input/input.hpp b/higan/target-tomoko/input/input.hpp index da44abd4..4a61d258 100644 --- a/higan/target-tomoko/input/input.hpp +++ b/higan/target-tomoko/input/input.hpp @@ -1,5 +1,6 @@ struct InputMapping { auto bind() -> void; + auto bind(string mapping) -> void; auto bind(shared_pointer device, uint group, uint input, int16 oldValue, int16 newValue) -> bool; auto poll() -> int16; auto rumble(bool enable) -> void; @@ -9,20 +10,28 @@ struct InputMapping { auto isAnalog() const -> bool { return type == 1; } auto isRumble() const -> bool { return type == 2; } - auto assignmentName() -> string; - auto deviceName() -> string; + auto displayName() -> string; string path; //configuration file key path string name; //input name (human readable) uint type = 0; string assignment = "None"; - shared_pointer device; - uint group = 0; - uint input = 0; - enum class Qualifier : uint { None, Lo, Hi, Rumble } qualifier = Qualifier::None; + + enum class Logic : uint { AND, OR }; + enum class Qualifier : uint { None, Lo, Hi, Rumble }; + virtual auto logic() const -> Logic { return Logic::OR; } + struct Mapping { + shared_pointer device; + uint group = 0; + uint input = 0; + Qualifier qualifier = Qualifier::None; + }; + vector mappings; }; struct InputHotkey : InputMapping { + auto logic() const -> Logic override { return Logic::AND; } + function void> press; function void> release; diff --git a/higan/target-tomoko/settings/hotkeys.cpp b/higan/target-tomoko/settings/hotkeys.cpp index fc585a29..ef29f247 100644 --- a/higan/target-tomoko/settings/hotkeys.cpp +++ b/higan/target-tomoko/settings/hotkeys.cpp @@ -29,13 +29,11 @@ auto HotkeySettings::reloadMappings() -> void { mappingList.append(TableViewHeader().setVisible() .append(TableViewColumn().setText("Name")) .append(TableViewColumn().setText("Mapping").setExpandable()) - .append(TableViewColumn().setText("Device").setAlignment(1.0).setForegroundColor({0, 128, 0})) ); for(auto& hotkey : inputManager->hotkeys) { mappingList.append(TableViewItem() .append(TableViewCell().setText(hotkey->name)) .append(TableViewCell()) - .append(TableViewCell()) ); } mappingList.resizeColumns(); @@ -44,8 +42,7 @@ auto HotkeySettings::reloadMappings() -> void { auto HotkeySettings::refreshMappings() -> void { uint position = 0; for(auto& hotkey : inputManager->hotkeys) { - mappingList.item(position).cell(1).setText(hotkey->assignmentName()); - mappingList.item(position).cell(2).setText(hotkey->deviceName()); + mappingList.item(position).cell(1).setText(hotkey->displayName()); position++; } mappingList.resizeColumns(); diff --git a/higan/target-tomoko/settings/input.cpp b/higan/target-tomoko/settings/input.cpp index 038de2c1..b32b87b3 100644 --- a/higan/target-tomoko/settings/input.cpp +++ b/higan/target-tomoko/settings/input.cpp @@ -95,13 +95,11 @@ auto InputSettings::reloadMappings() -> void { mappingList.append(TableViewHeader().setVisible() .append(TableViewColumn().setText("Name")) .append(TableViewColumn().setText("Mapping").setExpandable()) - .append(TableViewColumn().setText("Device").setAlignment(1.0).setForegroundColor({0, 128, 0})) ); for(auto& mapping : activeDevice().mappings) { mappingList.append(TableViewItem() .append(TableViewCell().setText(mapping.name)) .append(TableViewCell()) - .append(TableViewCell()) ); } refreshMappings(); @@ -110,8 +108,7 @@ auto InputSettings::reloadMappings() -> void { auto InputSettings::refreshMappings() -> void { uint position = 0; for(auto& mapping : activeDevice().mappings) { - mappingList.item(position).cell(1).setText(mapping.assignmentName()); - mappingList.item(position).cell(2).setText(mapping.deviceName()); + mappingList.item(position).cell(1).setText(mapping.displayName()); position++; } mappingList.resizeColumns(); diff --git a/nall/arithmetic/natural.hpp b/nall/arithmetic/natural.hpp index a49527f4..98797653 100644 --- a/nall/arithmetic/natural.hpp +++ b/nall/arithmetic/natural.hpp @@ -24,7 +24,7 @@ struct Pair { auto operator!() const -> bool { return !(hi || lo); } auto operator++() -> Pair& { lo++; hi += lo == 0; return *this; } - auto operator--() -> Pair& { hi -= lo == 0; lo--; } + auto operator--() -> Pair& { hi -= lo == 0; lo--; return *this; } auto operator++(int) -> Pair { Pair r = *this; lo++; hi += lo == 0; return r; } auto operator--(int) -> Pair { Pair r = *this; hi -= lo == 0; lo--; return r; }