bsnes/snes/input/input.hpp

89 lines
1.9 KiB
C++
Executable File

class Input {
public:
enum class Device : unsigned {
None,
Joypad,
Multitap,
Mouse,
SuperScope,
Justifier,
Justifiers,
};
enum class JoypadID : unsigned {
B = 0, Y = 1, Select = 2, Start = 3,
Up = 4, Down = 5, Left = 6, Right = 7,
A = 8, X = 9, L = 10, R = 11,
};
enum class MouseID : unsigned {
X = 0, Y = 1, Left = 2, Right = 3,
};
enum class SuperScopeID : unsigned {
X = 0, Y = 1, Trigger = 2, Cursor = 3, Turbo = 4, Pause = 5,
};
enum class JustifierID : unsigned {
X = 0, Y = 1, Trigger = 2, Start = 3,
};
uint8 port_read(bool port);
void port_set_device(bool port, Device device);
void init();
void poll();
void update();
//light guns (Super Scope, Justifier(s)) strobe IOBit whenever the CRT
//beam cannon is detected. this needs to be tested at the cycle level
//(hence inlining here for speed) to avoid 'dead space' during DRAM refresh.
//iobit is updated during port_set_device(),
//latchx, latchy are updated during update() (once per frame)
alwaysinline void tick() {
//only test if Super Scope or Justifier is connected
if(iobit && cpu.vcounter() == latchy && cpu.hcounter() == latchx) {
ppu.latch_counters();
}
}
private:
bool iobit;
int16_t latchx, latchy;
struct port_t {
Device device;
unsigned counter0; //read counters
unsigned counter1;
struct superscope_t {
int x, y;
bool trigger;
bool cursor;
bool turbo;
bool pause;
bool offscreen;
bool turbolock;
bool triggerlock;
bool pauselock;
} superscope;
struct justifier_t {
bool active;
int x1, x2;
int y1, y2;
bool trigger1, trigger2;
bool start1, start2;
} justifier;
} port[2];
friend class System;
friend class Video;
friend class CPU;
};
extern Input input;