2011-06-24 10:43:29 +00:00
|
|
|
//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)
|
|
|
|
|
2011-06-26 12:51:37 +00:00
|
|
|
//It is obviously not possible to perfectly simulate an IR light detecting
|
|
|
|
//a CRT beam cannon, hence this class will read the PPU raster counters.
|
|
|
|
|
2011-06-24 10:43:29 +00:00
|
|
|
//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.
|
|
|
|
|
2015-10-10 02:16:12 +00:00
|
|
|
SuperScope::SuperScope(bool port) : Controller(port) {
|
|
|
|
create(Controller::Enter, 21477272);
|
|
|
|
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;
|
|
|
|
|
2016-02-09 11:51:12 +00:00
|
|
|
prev = 0;
|
|
|
|
}
|
2011-06-26 12:51:37 +00:00
|
|
|
|
2016-02-09 11:51:12 +00:00
|
|
|
auto SuperScope::main() -> void {
|
|
|
|
unsigned next = cpu.vcounter() * 1364 + cpu.hcounter();
|
Update to v079r06 release.
byuu says:
It does add some more code to the CPU::step() function, so performance
probably went down actually, by about 1%. Removing the input.tick() call
didn't compensate as much as I'd hoped.
Hooked up Super Scope and Justifier support. The good news is that the
Justifier alignment doesn't get fucked up anymore when you go
off-screen. Never could fix that in the old version.
The bad news is that it takes a major speed hit for the time being.
I need to figure out how to run the CPU and input threads out of order.
Every time I try, the input gets thrown off by most of a scanline.
Right now, I'm forced to sync constantly to get the latching position
really accurate. But worst case, I can cut the syncs down by skipping
large chunks around the cursor position, +/-40 clock cycles. So it's
only temporarily slow.
Lastly, killed the old Input class, merged Controllers class into it.
I actually like Controllers as a name better, but it doesn't jive with
video/audio/input, so oh well.
2011-06-25 12:56:32 +00:00
|
|
|
|
2016-02-09 11:51:12 +00:00
|
|
|
if(offscreen == false) {
|
|
|
|
unsigned target = y * 1364 + (x + 24) * 4;
|
|
|
|
if(next >= target && prev < target) {
|
|
|
|
//CRT raster detected, toggle iobit to latch counters
|
|
|
|
iobit(0);
|
|
|
|
iobit(1);
|
Update to v079r06 release.
byuu says:
It does add some more code to the CPU::step() function, so performance
probably went down actually, by about 1%. Removing the input.tick() call
didn't compensate as much as I'd hoped.
Hooked up Super Scope and Justifier support. The good news is that the
Justifier alignment doesn't get fucked up anymore when you go
off-screen. Never could fix that in the old version.
The bad news is that it takes a major speed hit for the time being.
I need to figure out how to run the CPU and input threads out of order.
Every time I try, the input gets thrown off by most of a scanline.
Right now, I'm forced to sync constantly to get the latching position
really accurate. But worst case, I can cut the syncs down by skipping
large chunks around the cursor position, +/-40 clock cycles. So it's
only temporarily slow.
Lastly, killed the old Input class, merged Controllers class into it.
I actually like Controllers as a name better, but it doesn't jive with
video/audio/input, so oh well.
2011-06-25 12:56:32 +00:00
|
|
|
}
|
2016-02-09 11:51:12 +00:00
|
|
|
}
|
Update to v079r06 release.
byuu says:
It does add some more code to the CPU::step() function, so performance
probably went down actually, by about 1%. Removing the input.tick() call
didn't compensate as much as I'd hoped.
Hooked up Super Scope and Justifier support. The good news is that the
Justifier alignment doesn't get fucked up anymore when you go
off-screen. Never could fix that in the old version.
The bad news is that it takes a major speed hit for the time being.
I need to figure out how to run the CPU and input threads out of order.
Every time I try, the input gets thrown off by most of a scanline.
Right now, I'm forced to sync constantly to get the latching position
really accurate. But worst case, I can cut the syncs down by skipping
large chunks around the cursor position, +/-40 clock cycles. So it's
only temporarily slow.
Lastly, killed the old Input class, merged Controllers class into it.
I actually like Controllers as a name better, but it doesn't jive with
video/audio/input, so oh well.
2011-06-25 12:56:32 +00:00
|
|
|
|
2016-02-09 11:51:12 +00:00
|
|
|
if(next < prev) {
|
|
|
|
//Vcounter wrapped back to zero; update cursor coordinates for start of new frame
|
|
|
|
int nx = interface->inputPoll(port, (unsigned)Device::ID::SuperScope, X);
|
|
|
|
int ny = interface->inputPoll(port, (unsigned)Device::ID::SuperScope, Y);
|
|
|
|
nx += x;
|
|
|
|
ny += y;
|
|
|
|
x = max(-16, min(256 + 16, nx));
|
|
|
|
y = max(-16, min(240 + 16, ny));
|
|
|
|
offscreen = (x < 0 || y < 0 || x >= 256 || y >= (ppu.overscan() ? 240 : 225));
|
Update to v079r06 release.
byuu says:
It does add some more code to the CPU::step() function, so performance
probably went down actually, by about 1%. Removing the input.tick() call
didn't compensate as much as I'd hoped.
Hooked up Super Scope and Justifier support. The good news is that the
Justifier alignment doesn't get fucked up anymore when you go
off-screen. Never could fix that in the old version.
The bad news is that it takes a major speed hit for the time being.
I need to figure out how to run the CPU and input threads out of order.
Every time I try, the input gets thrown off by most of a scanline.
Right now, I'm forced to sync constantly to get the latching position
really accurate. But worst case, I can cut the syncs down by skipping
large chunks around the cursor position, +/-40 clock cycles. So it's
only temporarily slow.
Lastly, killed the old Input class, merged Controllers class into it.
I actually like Controllers as a name better, but it doesn't jive with
video/audio/input, so oh well.
2011-06-25 12:56:32 +00:00
|
|
|
}
|
2016-02-09 11:51:12 +00:00
|
|
|
|
|
|
|
prev = next;
|
|
|
|
step(2);
|
Update to v079r06 release.
byuu says:
It does add some more code to the CPU::step() function, so performance
probably went down actually, by about 1%. Removing the input.tick() call
didn't compensate as much as I'd hoped.
Hooked up Super Scope and Justifier support. The good news is that the
Justifier alignment doesn't get fucked up anymore when you go
off-screen. Never could fix that in the old version.
The bad news is that it takes a major speed hit for the time being.
I need to figure out how to run the CPU and input threads out of order.
Every time I try, the input gets thrown off by most of a scanline.
Right now, I'm forced to sync constantly to get the latching position
really accurate. But worst case, I can cut the syncs down by skipping
large chunks around the cursor position, +/-40 clock cycles. So it's
only temporarily slow.
Lastly, killed the old Input class, merged Controllers class into it.
I actually like Controllers as a name better, but it doesn't jive with
video/audio/input, so oh well.
2011-06-25 12:56:32 +00:00
|
|
|
}
|
|
|
|
|
2015-10-10 02:16:12 +00:00
|
|
|
auto SuperScope::data() -> uint2 {
|
2011-06-24 10:43:29 +00:00
|
|
|
if(counter >= 8) return 1;
|
|
|
|
|
|
|
|
if(counter == 0) {
|
|
|
|
//turbo is a switch; toggle is edge sensitive
|
2015-11-10 11:02:29 +00:00
|
|
|
bool newturbo = interface->inputPoll(port, (unsigned)Device::ID::SuperScope, Turbo);
|
2011-06-24 10:43:29 +00:00
|
|
|
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;
|
2015-11-10 11:02:29 +00:00
|
|
|
bool newtrigger = interface->inputPoll(port, (unsigned)Device::ID::SuperScope, Trigger);
|
2011-06-24 10:43:29 +00:00
|
|
|
if(newtrigger && (turbo || !triggerlock)) {
|
|
|
|
trigger = true;
|
|
|
|
triggerlock = true;
|
|
|
|
} else if(!newtrigger) {
|
|
|
|
triggerlock = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//cursor is a button; it is always level sensitive
|
2015-11-10 11:02:29 +00:00
|
|
|
cursor = interface->inputPoll(port, (unsigned)Device::ID::SuperScope, Cursor);
|
2011-06-24 10:43:29 +00:00
|
|
|
|
|
|
|
//pause is a button; it is always edge sensitive
|
|
|
|
pause = false;
|
2015-11-10 11:02:29 +00:00
|
|
|
bool newpause = interface->inputPoll(port, (unsigned)Device::ID::SuperScope, Pause);
|
2011-06-24 10:43:29 +00:00
|
|
|
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++) {
|
Update to v079r06 release.
byuu says:
It does add some more code to the CPU::step() function, so performance
probably went down actually, by about 1%. Removing the input.tick() call
didn't compensate as much as I'd hoped.
Hooked up Super Scope and Justifier support. The good news is that the
Justifier alignment doesn't get fucked up anymore when you go
off-screen. Never could fix that in the old version.
The bad news is that it takes a major speed hit for the time being.
I need to figure out how to run the CPU and input threads out of order.
Every time I try, the input gets thrown off by most of a scanline.
Right now, I'm forced to sync constantly to get the latching position
really accurate. But worst case, I can cut the syncs down by skipping
large chunks around the cursor position, +/-40 clock cycles. So it's
only temporarily slow.
Lastly, killed the old Input class, merged Controllers class into it.
I actually like Controllers as a name better, but it doesn't jive with
video/audio/input, so oh well.
2011-06-25 12:56:32 +00:00
|
|
|
case 0: return offscreen ? 0 : trigger;
|
2011-06-24 10:43:29 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-10 02:16:12 +00:00
|
|
|
auto SuperScope::latch(bool data) -> void {
|
2011-06-24 10:43:29 +00:00
|
|
|
if(latched == data) return;
|
|
|
|
latched = data;
|
|
|
|
counter = 0;
|
|
|
|
}
|