Update to v079r05 release.

byuu says:

- Fixed GCC-4.6 casting errors in ui/input/input.cpp.
- Fixed some of the opcode mnemonics specified in the HG51B169 core (was
  unable to speed up the code)
- Started on a new core input system: snes/controller. More on that
  here:

    http://board.byuu.org/viewtopic.php?f=16&t=1761

- Have not yet attempted to add threading support to the controllers, so
  serial is still there as a coprocessor.
- I'm going to move the Controllers {} class back to Input {} once all
  individual controllers have been ported over.

Note: Super Scope and Justifier do not have counter latching support
yet, so you can't really use them. The gamepad, multitap and mouse all
work great; and the SS/Justifier cursors work at least. I also colored
the SS cursor red, so that all three (SS, Justifier, chained secondary
Justifier) all have unique R/G/B colors now. Should prevent confusion
between the SS and one Justifier.
This commit is contained in:
Tim Allen 2011-06-24 20:43:29 +10:00
parent 724747ac9e
commit cf09d41669
25 changed files with 586 additions and 60 deletions

View File

@ -1,4 +1,4 @@
snes_objects := snes-system
snes_objects := snes-system snes-controller
snes_objects += snes-cartridge snes-cheat
snes_objects += snes-memory snes-cpucore snes-smpcore
snes_objects += snes-cpu snes-smp snes-dsp snes-ppu
@ -28,7 +28,8 @@ else ifeq ($(profile),performance)
snesppu := $(snes)/alt/ppu-performance
endif
obj/snes-system.o : $(snes)/system/system.cpp $(call rwildcard,$(snes)/system/) $(call rwildcard,$(snes)/video/)
obj/snes-system.o : $(snes)/system/system.cpp $(call rwildcard,$(snes)/system/) $(call rwildcard,$(snes)/video/) $(call rwildcard,$(snes)/audio/) $(call rwildcard,$(snes)/input/)
obj/snes-controller.o: $(snes)/controller/controller.cpp $(call rwildcard,$(snes)/controller/)
obj/snes-memory.o : $(snes)/memory/memory.cpp $(call rwildcard,$(snes)/memory/)
obj/snes-cpucore.o : $(snes)/cpu/core/core.cpp $(call rwildcard,$(snes)/cpu/core/)
obj/snes-smpcore.o : $(snes)/smp/core/core.cpp $(call rwildcard,$(snes)/smp/core/)
@ -36,7 +37,7 @@ obj/snes-cpu.o : $(snescpu)/cpu.cpp $(call rwildcard,$(snescpu)/)
obj/snes-smp.o : $(snessmp)/smp.cpp $(call rwildcard,$(snessmp)/)
obj/snes-dsp.o : $(snesdsp)/dsp.cpp $(call rwildcard,$(snesdsp)/)
obj/snes-ppu.o : $(snesppu)/ppu.cpp $(call rwildcard,$(snesppu)/)
obj/snes-cartridge.o: $(snes)/cartridge/cartridge.cpp $(snes)/cartridge/*
obj/snes-cartridge.o : $(snes)/cartridge/cartridge.cpp $(snes)/cartridge/*
obj/snes-cheat.o : $(snes)/cheat/cheat.cpp $(snes)/cheat/*
obj/snes-nss.o : $(snes)/chip/nss/nss.cpp $(call rwildcard,$(snes)/chip/nss/)

View File

@ -35,7 +35,7 @@ void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) {
nvram.reset();
parse_xml(xml_list);
print(xml_list[0], "\n\n");
//print(xml_list[0], "\n\n");
if(ram_size > 0) {
ram.map(allocate<uint8>(ram_size, 0xff), ram_size);

View File

@ -78,7 +78,7 @@ void HitachiDSP::exec() {
else if((opcode & 0xdd00) == 0x1400) {
//00.1 01.0 .... ....
//jumpmi
//jumpmi i
if(regs.n) {
if(opcode & 0x2000) push();
regs.pc = np();
@ -87,7 +87,7 @@ void HitachiDSP::exec() {
else if((opcode & 0xffff) == 0x1c00) {
//0001 1100 0000 0000
//loop/wait?
//loop?
}
else if((opcode & 0xfffe) == 0x2500) {
@ -110,6 +110,7 @@ void HitachiDSP::exec() {
else if((opcode & 0xffff) == 0x3c00) {
//0011 1100 0000 0000
//ret
pull();
}
@ -121,7 +122,7 @@ void HitachiDSP::exec() {
else if((opcode & 0xf800) == 0x4800) {
//0100 1... .... ....
//rcmp a<<n,ri
//cmpr a<<n,ri
int result = ri() - sa();
regs.n = result & 0x800000;
regs.z = (uint24)result == 0;
@ -195,11 +196,13 @@ void HitachiDSP::exec() {
else if((opcode & 0xff00) == 0x7c00) {
//0111 1100 .... ....
//ld pl,i
regs.p = (regs.p & 0xff00) | ((opcode & 0xff) << 0);
}
else if((opcode & 0xff00) == 0x7d00) {
//0111 1101 .... ....
//ld ph,i
regs.p = (regs.p & 0x00ff) | ((opcode & 0xff) << 8);
}
@ -215,7 +218,7 @@ void HitachiDSP::exec() {
else if((opcode & 0xf800) == 0x8800) {
//1000 1... .... ....
//rsb a<<n,ri
//subr a<<n,ri
int result = ri() - sa();
regs.a = result;
regs.n = regs.a & 0x800000;
@ -247,7 +250,7 @@ void HitachiDSP::exec() {
else if((opcode & 0xf800) == 0xa800) {
//1010 1... .... ....
//xor a,ri
//xor a<<n,ri
regs.a = sa() ^ ri();
regs.n = regs.a & 0x800000;
regs.z = regs.a == 0;

View File

@ -0,0 +1,63 @@
#include <snes/snes.hpp>
#define CONTROLLER_CPP
namespace SNES {
#include "gamepad/gamepad.cpp"
#include "multitap/multitap.cpp"
#include "mouse/mouse.cpp"
#include "superscope/superscope.cpp"
#include "justifier/justifier.cpp"
Controllers controllers;
bool Controller::iobit() {
switch(port) {
case Controller::Port1: return cpu.pio() & 0x40;
case Controller::Port2: return cpu.pio() & 0x80;
}
}
void Controller::iobit(bool data) {
switch(port) {
case Controller::Port1: break;
case Controller::Port2: break;
}
}
Controller::Controller(bool port) : port(port) {
}
void Controllers::connect(bool port, Input::Device id) {
Controller *&controller = (port == Controller::Port1 ? port1 : port2);
if(controller) {
delete controller;
controller = 0;
}
switch(id) { default:
case Input::Device::None: controller = new Controller(port); break;
case Input::Device::Joypad: controller = new Gamepad(port); break;
case Input::Device::Multitap: controller = new Multitap(port); break;
case Input::Device::Mouse: controller = new Mouse(port); break;
case Input::Device::SuperScope: controller = new SuperScope(port); break;
case Input::Device::Justifier: controller = new Justifier(port, false); break;
case Input::Device::Justifiers: controller = new Justifier(port, true); break;
}
switch(port) {
case Controller::Port1: config.controller_port1 = id; break;
case Controller::Port2: config.controller_port2 = id; break;
}
}
Controllers::Controllers() {
connect(Controller::Port1, Input::Device::Joypad);
connect(Controller::Port2, Input::Device::Joypad);
}
Controllers::~Controllers() {
if(port1) delete port1;
if(port2) delete port2;
}
}

View File

@ -0,0 +1,40 @@
// SNES controller port pinout:
// -------------------------------
// | (1) (2) (3) (4) | (5) (6) (7) )
// -------------------------------
// pin name port1 port2
// 1: +5v
// 2: clock $4016 read $4017 read
// 3: latch $4016.d0 write $4016.d0 write
// 4: data1 $4016.d0 read $4017.d0 read
// 5: data2 $4016.d1 read $4017.d1 read
// 6: iobit $4201.d6 write; $4213.d6 read $4201.d7 write; $4213.d7 read
// 7: gnd
struct Controller : Processor {
enum : bool { Port1 = 0, Port2 = 1 };
const bool port;
bool iobit();
void iobit(bool data);
virtual uint2 data() { return 0; }
virtual void latch(bool data) {}
Controller(bool port);
};
struct Controllers {
Controller *port1;
Controller *port2;
void connect(bool port, Input::Device id);
Controllers();
~Controllers();
};
extern Controllers controllers;
#include "gamepad/gamepad.hpp"
#include "multitap/multitap.hpp"
#include "mouse/mouse.hpp"
#include "superscope/superscope.hpp"
#include "justifier/justifier.hpp"

View File

@ -0,0 +1,21 @@
#ifdef CONTROLLER_CPP
uint2 Gamepad::data() {
if(counter >= 16) return 1;
uint2 result = system.interface->input_poll(port, Input::Device::Joypad, 0, counter);
if(latched == 0) counter++;
return result;
}
void Gamepad::latch(bool data) {
if(latched == data) return;
latched = data;
counter = 0;
}
Gamepad::Gamepad(bool port) : Controller(port) {
latched = 0;
counter = 0;
}
#endif

View File

@ -0,0 +1,9 @@
struct Gamepad : Controller {
uint2 data();
void latch(bool data);
Gamepad(bool port);
private:
bool latched;
unsigned counter;
};

View File

@ -0,0 +1,101 @@
#ifdef CONTROLLER_CPP
uint2 Justifier::data() {
if(counter >= 32) return 1;
if(counter == 0) {
trigger1 = system.interface->input_poll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::Trigger);
start1 = system.interface->input_poll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::Start);
if(chained) {
trigger2 = system.interface->input_poll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::Trigger);
start2 = system.interface->input_poll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::Start);
}
}
switch(counter++) {
case 0: return 0;
case 1: return 0;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
case 6: return 0;
case 7: return 0;
case 8: return 0;
case 9: return 0;
case 10: return 0;
case 11: return 0;
case 12: return 1; //signature
case 13: return 1; // ||
case 14: return 1; // ||
case 15: return 0; // ||
case 16: return 0;
case 17: return 1;
case 18: return 0;
case 19: return 1;
case 20: return 0;
case 21: return 1;
case 22: return 0;
case 23: return 1;
case 24: return trigger1;
case 25: return trigger2;
case 26: return start1;
case 27: return start2;
case 28: return active;
case 29: return 0;
case 30: return 0;
case 31: return 0;
}
}
void Justifier::latch(bool data) {
if(latched == data) return;
latched = data;
counter = 0;
if(chained) active = !active; //toggle between both controllers when chained
int nx1 = system.interface->input_poll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::X);
int ny1 = system.interface->input_poll(port, Input::Device::Justifier, 0, (unsigned)Input::JustifierID::Y);
nx1 += x1;
ny1 += y1;
x1 = max(-16, min(256 + 16, nx1));
y1 = max(-16, min(240 + 16, ny1));
if(chained == false) return;
int nx2 = system.interface->input_poll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::X);
int ny2 = system.interface->input_poll(port, Input::Device::Justifiers, 1, (unsigned)Input::JustifierID::Y);
nx2 += x2;
ny2 += y2;
x2 = max(-16, min(256 + 16, nx2));
y2 = max(-16, min(240 + 16, ny2));
}
Justifier::Justifier(bool port, bool chained) : Controller(port), chained(chained) {
latched = 0;
counter = 0;
active = 0;
if(chained == false) {
x1 = 256 / 2;
y1 = 240 / 2;
x2 = -1;
y2 = -1;
} else {
x1 = 256 / 2 - 16;
y1 = 240 / 2;
x2 = 256 / 2 + 16;
y2 = 240 / 2;
}
trigger1 = false;
trigger2 = false;
start1 = false;
start2 = false;
}
#endif

View File

@ -0,0 +1,16 @@
struct Justifier : Controller {
uint2 data();
void latch(bool data);
Justifier(bool port, bool chained);
//private:
const bool chained; //true if the second justifier is attached to the first
bool latched;
unsigned counter;
bool active;
int x1, x2;
int y1, y2;
bool trigger1, trigger2;
bool start1, start2;
};

View File

@ -0,0 +1,69 @@
#ifdef CONTROLLER_CPP
uint2 Mouse::data() {
if(counter >= 32) return 1;
int position_x = system.interface->input_poll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::X); //-n = left, 0 = center, +n = right
int position_y = system.interface->input_poll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Y); //-n = up, 0 = center, +n = down
bool direction_x = position_x < 0; //0 = right, 1 = left
bool direction_y = position_y < 0; //0 = down, 1 = up
if(position_x < 0) position_x = -position_x; //abs(position_x)
if(position_y < 0) position_y = -position_y; //abs(position_y)
position_x = min(127, position_x); //range = 0 - 127
position_y = min(127, position_y);
switch(counter++) { default:
case 0: return 0;
case 1: return 0;
case 2: return 0;
case 3: return 0;
case 4: return 0;
case 5: return 0;
case 6: return 0;
case 7: return 0;
case 8: return system.interface->input_poll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Right);
case 9: return system.interface->input_poll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Left);
case 10: return 0; //speed (0 = slow, 1 = normal, 2 = fast, 3 = unused)
case 11: return 0; // ||
case 12: return 0; //signature
case 13: return 0; // ||
case 14: return 0; // ||
case 15: return 1; // ||
case 16: return (direction_y);
case 17: return (position_y >> 6) & 1;
case 18: return (position_y >> 5) & 1;
case 19: return (position_y >> 4) & 1;
case 20: return (position_y >> 3) & 1;
case 21: return (position_y >> 2) & 1;
case 22: return (position_y >> 1) & 1;
case 23: return (position_y >> 0) & 1;
case 24: return (direction_x);
case 25: return (position_x >> 6) & 1;
case 26: return (position_x >> 5) & 1;
case 27: return (position_x >> 4) & 1;
case 28: return (position_x >> 3) & 1;
case 29: return (position_x >> 2) & 1;
case 30: return (position_x >> 1) & 1;
case 31: return (position_x >> 0) & 1;
}
}
void Mouse::latch(bool data) {
if(latched == data) return;
latched = data;
counter = 0;
}
Mouse::Mouse(bool port) : Controller(port) {
latched = 0;
counter = 0;
}
#endif

View File

@ -0,0 +1,9 @@
struct Mouse : Controller {
uint2 data();
void latch(bool data);
Mouse(bool port);
private:
bool latched;
unsigned counter;
};

View File

@ -0,0 +1,39 @@
#ifdef CONTROLLER_CPP
uint2 Multitap::data() {
if(latched) return 2; //multitap detection
unsigned index, port1, port2;
if(iobit()) {
index = counter1;
if(index >= 16) return 3;
counter1++;
port1 = 0; //controller 1
port2 = 1; //controller 2
} else {
index = counter2;
if(index >= 16) return 3;
counter2++;
port1 = 2; //controller 3
port2 = 3; //controller 4
}
bool data1 = system.interface->input_poll(port, Input::Device::Multitap, port1, index);
bool data2 = system.interface->input_poll(port, Input::Device::Multitap, port2, index);
return (data2 << 1) | (data1 << 0);
}
void Multitap::latch(bool data) {
if(latched == data) return;
latched = data;
counter1 = 0;
counter2 = 0;
}
Multitap::Multitap(bool port) : Controller(port) {
latched = 0;
counter1 = 0;
counter2 = 0;
}
#endif

View File

@ -0,0 +1,10 @@
struct Multitap : Controller {
uint2 data();
void latch(bool data);
Multitap(bool port);
private:
bool latched;
unsigned counter1;
unsigned counter2;
};

View File

@ -0,0 +1,96 @@
#ifdef CONTROLLER_CPP
//The Super Scope is a light-gun: it detects the CRT beam cannon position,
//and latches the counters by toggling iobit. This only works on controller
//port 2, as iobit there is connected to the PPU H/V counter latch.
//(PIO $4201.d7)
//A Super Scope can still technically be used in port 1, however it would
//require manual polling of PIO ($4201.d6) to determine when iobit was written.
//Note that no commercial game ever utilizes a Super Scope in port 1.
uint2 SuperScope::data() {
if(counter >= 8) return 1;
if(counter == 0) {
//turbo is a switch; toggle is edge sensitive
bool newturbo = system.interface->input_poll(port, Input::Device::SuperScope, 0, (unsigned)Input::SuperScopeID::Turbo);
if(newturbo && !turbo) {
turbo = !turbo; //toggle state
turbolock = true;
} else {
turbolock = false;
}
//trigger is a button
//if turbo is active, trigger is level sensitive; otherwise, it is edge sensitive
trigger = false;
bool newtrigger = system.interface->input_poll(port, Input::Device::SuperScope, 0, (unsigned)Input::SuperScopeID::Trigger);
if(newtrigger && (turbo || !triggerlock)) {
trigger = true;
triggerlock = true;
} else if(!newtrigger) {
triggerlock = false;
}
//cursor is a button; it is always level sensitive
cursor = system.interface->input_poll(port, Input::Device::SuperScope, 0, (unsigned)Input::SuperScopeID::Cursor);
//pause is a button; it is always edge sensitive
pause = false;
bool newpause = system.interface->input_poll(port, Input::Device::SuperScope, 0, (unsigned)Input::SuperScopeID::Pause);
if(newpause && !pauselock) {
pause = true;
pauselock = true;
} else if(!newpause) {
pauselock = false;
}
offscreen = (x < 0 || y < 0 || x >= 256 || y >= (ppu.overscan() ? 240 : 225));
}
switch(counter++) {
case 0: return trigger;
case 1: return cursor;
case 2: return turbo;
case 3: return pause;
case 4: return 0;
case 5: return 0;
case 6: return offscreen;
case 7: return 0; //noise (1 = yes)
}
}
void SuperScope::latch(bool data) {
if(latched == data) return;
latched = data;
counter = 0;
int nx = system.interface->input_poll(port, Input::Device::SuperScope, 0, (unsigned)Input::SuperScopeID::X);
int ny = system.interface->input_poll(port, Input::Device::SuperScope, 0, (unsigned)Input::SuperScopeID::Y);
nx += x;
ny += y;
x = max(-16, min(256 + 16, nx));
y = max(-16, min(240 + 16, ny));
}
SuperScope::SuperScope(bool port) : Controller(port) {
latched = 0;
counter = 0;
//center cursor onscreen
x = 256 / 2;
y = 240 / 2;
trigger = false;
cursor = false;
turbo = false;
pause = false;
offscreen = false;
turbolock = false;
triggerlock = false;
pauselock = false;
}
#endif

View File

@ -0,0 +1,21 @@
struct SuperScope : Controller {
uint2 data();
void latch(bool data);
SuperScope(bool port);
//private:
bool latched;
unsigned counter;
int x, y;
bool trigger;
bool cursor;
bool turbo;
bool pause;
bool offscreen;
bool turbolock;
bool triggerlock;
bool pauselock;
};

View File

@ -33,10 +33,13 @@ void CPU::mmio_w2183(uint8 data) {
//strobing $4016.d0 affects both controller port latches.
//$4017 bit 0 writes are ignored.
void CPU::mmio_w4016(uint8 data) {
bool old_latch = status.joypad_strobe_latch;
bool new_latch = data & 1;
status.joypad_strobe_latch = new_latch;
if(old_latch != new_latch) input.poll();
//bool old_latch = status.joypad_strobe_latch;
//bool new_latch = data & 1;
//status.joypad_strobe_latch = new_latch;
//if(old_latch != new_latch) input.poll();
controllers.port1->latch(data & 1);
controllers.port2->latch(data & 1);
}
//JOYSER0
@ -44,7 +47,8 @@ void CPU::mmio_w4016(uint8 data) {
//1-0 = Joypad serial data
uint8 CPU::mmio_r4016() {
uint8 r = regs.mdr & 0xfc;
r |= input.port_read(0) & 3;
//r |= input.port_read(0) & 3;
r |= controllers.port1->data();
return r;
}
@ -54,7 +58,8 @@ uint8 CPU::mmio_r4016() {
//1-0 = Joypad serial data
uint8 CPU::mmio_r4017() {
uint8 r = (regs.mdr & 0xe0) | 0x1c;
r |= input.port_read(1) & 3;
//r |= input.port_read(1) & 3;
r |= controllers.port2->data();
return r;
}

View File

@ -6,10 +6,18 @@ void CPU::step_auto_joypad_poll() {
status.auto_joypad_active = status.auto_joypad_counter <= 15;
if(status.auto_joypad_active && status.auto_joypad_poll) {
if(status.auto_joypad_counter == 0) input.poll();
if(status.auto_joypad_counter == 0) {
//input.poll();
controllers.port1->latch(1);
controllers.port2->latch(1);
controllers.port1->latch(0);
controllers.port2->latch(0);
}
uint8 port0 = input.port_read(0);
uint8 port1 = input.port_read(1);
//uint8 port0 = input.port_read(0);
//uint8 port1 = input.port_read(1);
uint2 port0 = controllers.port1->data();
uint2 port1 = controllers.port2->data();
status.joy1 = (status.joy1 << 1) | (bool)(port0 & 1);
status.joy2 = (status.joy2 << 1) | (bool)(port1 & 1);

View File

@ -13,7 +13,7 @@ void CPU::add_clocks(unsigned clocks) {
while(ticks--) {
tick();
if(hcounter() & 2) {
input.tick();
//input.tick();
poll_interrupts();
}
}

View File

@ -1,6 +1,6 @@
#ifdef SYSTEM_CPP
Input input;
Input input1;
uint8 Input::port_read(bool portnumber) {
if(cartridge.has_serial() && portnumber == 1) {
@ -277,7 +277,7 @@ void Input::update() {
}
}
void Input::port_set_device(bool portnumber, Device device) {
void Input::port_set_device_(bool portnumber, Device device) {
port_t &p = port[portnumber];
p.device = device;

View File

@ -29,7 +29,7 @@ public:
};
uint8 port_read(bool port);
void port_set_device(bool port, Device device);
void port_set_device_(bool port, Device device);
void init();
void poll();
void update();
@ -85,4 +85,4 @@ private:
friend class CPU;
};
extern Input input;
extern Input input1;

View File

@ -1,7 +1,7 @@
namespace SNES {
namespace Info {
static const char Name[] = "bsnes";
static const char Version[] = "079.04";
static const char Version[] = "079.05";
static const unsigned SerializerVersion = 21;
}
}
@ -131,6 +131,7 @@ namespace SNES {
#endif
#include <snes/system/system.hpp>
#include <snes/controller/controller.hpp>
#include <snes/chip/chip.hpp>
#include <snes/cartridge/cartridge.hpp>
#include <snes/cheat/cheat.hpp>

View File

@ -21,7 +21,7 @@ void System::run() {
scheduler.enter();
if(scheduler.exit_reason() == Scheduler::ExitReason::FrameEvent) {
input.update();
//input.update();
video.update();
}
}
@ -59,7 +59,7 @@ void System::runthreadtosave() {
scheduler.enter();
if(scheduler.exit_reason() == Scheduler::ExitReason::SynchronizeEvent) break;
if(scheduler.exit_reason() == Scheduler::ExitReason::FrameEvent) {
input.update();
//input.update();
video.update();
}
}
@ -89,10 +89,10 @@ void System::init(Interface *interface_) {
video.init();
audio.init();
input.init();
//input.init();
input.port_set_device(0, config.controller_port1);
input.port_set_device(1, config.controller_port2);
controllers.connect(0, config.controller_port1);
controllers.connect(1, config.controller_port2);
}
void System::term() {
@ -199,7 +199,9 @@ void System::power() {
if(cartridge.has_link()) cpu.coprocessors.append(&link);
scheduler.init();
input.update();
controllers.connect(0, config.controller_port1);
controllers.connect(1, config.controller_port2);
//input.update();
}
void System::reset() {
@ -238,9 +240,9 @@ void System::reset() {
if(cartridge.has_link()) cpu.coprocessors.append(&link);
scheduler.init();
input.port_set_device(0, config.controller_port1);
input.port_set_device(1, config.controller_port2);
input.update();
controllers.connect(0, config.controller_port1);
controllers.connect(1, config.controller_port2);
//input.update();
}
void System::scanline() {

View File

@ -47,10 +47,22 @@ void Video::draw_cursor(uint16_t color, int x, int y) {
}
void Video::update() {
switch(input.port[1].device) {
case Input::Device::SuperScope: draw_cursor(0x001f, input.port[1].superscope.x, input.port[1].superscope.y); break;
case Input::Device::Justifiers: draw_cursor(0x02e0, input.port[1].justifier.x2, input.port[1].justifier.y2); //fallthrough
case Input::Device::Justifier: draw_cursor(0x001f, input.port[1].justifier.x1, input.port[1].justifier.y1); break;
switch(config.controller_port2) {
case Input::Device::SuperScope:
if(dynamic_cast<SuperScope*>(controllers.port2)) {
SuperScope &device = (SuperScope&)*controllers.port2;
draw_cursor(0x7c00, device.x, device.y);
}
break;
case Input::Device::Justifier:
case Input::Device::Justifiers:
if(dynamic_cast<Justifier*>(controllers.port2)) {
Justifier &device = (Justifier&)*controllers.port2;
draw_cursor(0x001f, device.x1, device.y1);
if(device.chained == false) break;
draw_cursor(0x02e0, device.x2, device.y2);
}
break;
}
uint16_t *data = (uint16_t*)ppu.output;

View File

@ -82,7 +82,7 @@ void InputMapper::Gamepad::create(const char *deviceName, const char *configName
}
int16_t InputMapper::Gamepad::poll(unsigned id) {
switch(id) {
switch((SNES::Input::JoypadID)id) {
case SNES::Input::JoypadID::Up: return up.poll();
case SNES::Input::JoypadID::Down: return down.poll() & !up.poll();
case SNES::Input::JoypadID::Left: return left.poll();
@ -118,7 +118,7 @@ void InputMapper::Mouse::create(const char *deviceName, const char *configName)
}
int16_t InputMapper::Mouse::poll(unsigned id) {
switch(id) {
switch((SNES::Input::MouseID)id) {
case SNES::Input::MouseID::X: return x.poll();
case SNES::Input::MouseID::Y: return y.poll();
case SNES::Input::MouseID::Left: return left.poll();
@ -150,7 +150,7 @@ void InputMapper::SuperScope::create(const char *deviceName, const char *configN
}
int16_t InputMapper::SuperScope::poll(unsigned id) {
switch(id) {
switch((SNES::Input::SuperScopeID)id) {
case SNES::Input::SuperScopeID::X: return x.poll();
case SNES::Input::SuperScopeID::Y: return y.poll();
case SNES::Input::SuperScopeID::Trigger: return trigger.poll();
@ -182,7 +182,7 @@ void InputMapper::Justifier::create(const char *deviceName, const char *configNa
}
int16_t InputMapper::Justifier::poll(unsigned id) {
switch(id) {
switch((SNES::Input::JustifierID)id) {
case SNES::Input::JustifierID::X: return x.poll();
case SNES::Input::JustifierID::Y: return y.poll();
case SNES::Input::JustifierID::Trigger: return trigger.poll();

View File

@ -40,20 +40,20 @@ void Utility::showMessage(const string &text) {
void Utility::setControllers() {
switch(config.controller.port1) {
case 0: SNES::input.port_set_device(0, SNES::Input::Device::None); break;
case 1: SNES::input.port_set_device(0, SNES::Input::Device::Joypad); break;
case 2: SNES::input.port_set_device(0, SNES::Input::Device::Multitap); break;
case 3: SNES::input.port_set_device(0, SNES::Input::Device::Mouse); break;
case 0: SNES::controllers.connect(0, SNES::Input::Device::None); break;
case 1: SNES::controllers.connect(0, SNES::Input::Device::Joypad); break;
case 2: SNES::controllers.connect(0, SNES::Input::Device::Multitap); break;
case 3: SNES::controllers.connect(0, SNES::Input::Device::Mouse); break;
}
switch(config.controller.port2) {
case 0: SNES::input.port_set_device(1, SNES::Input::Device::None); break;
case 1: SNES::input.port_set_device(1, SNES::Input::Device::Joypad); break;
case 2: SNES::input.port_set_device(1, SNES::Input::Device::Multitap); break;
case 3: SNES::input.port_set_device(1, SNES::Input::Device::Mouse); break;
case 4: SNES::input.port_set_device(1, SNES::Input::Device::SuperScope); break;
case 5: SNES::input.port_set_device(1, SNES::Input::Device::Justifier); break;
case 6: SNES::input.port_set_device(1, SNES::Input::Device::Justifiers); break;
case 0: SNES::controllers.connect(1, SNES::Input::Device::None); break;
case 1: SNES::controllers.connect(1, SNES::Input::Device::Joypad); break;
case 2: SNES::controllers.connect(1, SNES::Input::Device::Multitap); break;
case 3: SNES::controllers.connect(1, SNES::Input::Device::Mouse); break;
case 4: SNES::controllers.connect(1, SNES::Input::Device::SuperScope); break;
case 5: SNES::controllers.connect(1, SNES::Input::Device::Justifier); break;
case 6: SNES::controllers.connect(1, SNES::Input::Device::Justifiers); break;
}
}