bsnes/higan/sfc/cpu/joypad.cpp

28 lines
1.0 KiB
C++
Raw Normal View History

//called every 256 clocks; see CPU::addClocks()
auto CPU::stepAutoJoypadPoll() -> void {
if(vcounter() >= ppu.vdisp()) {
//cache enable state at first iteration
Update to v099r14 release. byuu says: Changelog: - (u)int(max,ptr) abbreviations removed; use _t suffix now [didn't feel like they were contributing enough to be worth it] - cleaned up nall::integer,natural,real functionality - toInteger, toNatural, toReal for parsing strings to numbers - fromInteger, fromNatural, fromReal for creating strings from numbers - (string,Markup::Node,SQL-based-classes)::(integer,natural,real) left unchanged - template<typename T> numeral(T value, long padding, char padchar) -> string for print() formatting - deduces integer,natural,real based on T ... cast the value if you want to override - there still exists binary,octal,hex,pointer for explicit print() formatting - lstring -> string_vector [but using lstring = string_vector; is declared] - would be nice to remove the using lstring eventually ... but that'd probably require 10,000 lines of changes >_> - format -> string_format [no using here; format was too ambiguous] - using integer = Integer<sizeof(int)*8>; and using natural = Natural<sizeof(uint)*8>; declared - for consistency with boolean. These three are meant for creating zero-initialized values implicitly (various uses) - R65816::io() -> idle() and SPC700::io() -> idle() [more clear; frees up struct IO {} io; naming] - SFC CPU, PPU, SMP use struct IO {} io; over struct (Status,Registers) {} (status,registers); now - still some CPU::Status status values ... they didn't really fit into IO functionality ... will have to think about this more - SFC CPU, PPU, SMP now use step() exclusively instead of addClocks() calling into step() - SFC CPU joypad1_bits, joypad2_bits were unused; killed them - SFC PPU CGRAM moved into PPU::Screen; since nothing else uses it - SFC PPU OAM moved into PPU::Object; since nothing else uses it - the raw uint8[544] array is gone. OAM::read() constructs values from the OAM::Object[512] table now - this avoids having to determine how we want to sub-divide the two OAM memory sections - this also eliminates the OAM::synchronize() functionality - probably more I'm forgetting The FPS fluctuations are driving me insane. This WIP went from 128fps to 137fps. Settled on 133.5fps for the final build. But nothing I changed should have affected performance at all. This level of fluctuation makes it damn near impossible to know whether I'm speeding things up or slowing things down with changes.
2016-07-01 11:50:32 +00:00
if(status.autoJoypadCounter == 0) status.autoJoypadLatch = io.autoJoypadPoll;
status.autoJoypadActive = status.autoJoypadCounter <= 15;
if(status.autoJoypadActive && status.autoJoypadLatch) {
if(status.autoJoypadCounter == 0) {
Update to v098r03 release. byuu says: It took several hours, but I've rebuilt much of the SNES' bus memory mapping architecture. The new design unifies the cartridge string-based mapping ("00-3f,80-bf:8000-ffff") and internal bus.map calls. The map() function now has an accompanying unmap() function, and instead of a fixed 256 callbacks, it'll scan to find the first available slot. unmap() will free slots up when zero addresses reference a given slot. The controllers and expansion port are now both entirely dynamic. Instead of load/unload/power/reset, they only have the constructor (power/reset/load) and destructor (unload). What this means is you can now dynamically change even expansion port devices after the system is loaded. Note that this is incredibly dangerous and stupid, but ... oh well. The whole point of this was for 21fx. There's no way to change the expansion port device prior to loading a game, but if the 21fx isn't active, then the reset vector hijack won't work. Now you can load a 21fx game, change the expansion port device, and simply reset the system to active the device. The unification of design between controller port devices and expansion port devices is nice, and overall this results in a reduction of code (all of the Mapping stuff in Cartridge is gone, replaced with direct bus mapping.) And there's always the potential to expand this system more in the future now. The big missing feature right now is the ability to push/pop mappings. So if you look at how the 21fx does the reset vector, you might vomit a little bit. But ... it works. Also changed exit(0) to _exit(0) in the POSIX version of nall::execute. [The _exit(0) thing is an attempt to make higan not crash when it tries to launch icarus and it's not on $PATH. The theory is that higan forks, then the child tries to exec icarus and fails, so it exits, all the unique_ptrs clean up their resources and tell the X server to free things the parent process is still using. Calling _exit() prevents destructors from running, and seems to prevent the problem. -Ed.]
2016-04-09 10:21:18 +00:00
SuperFamicom::peripherals.controllerPort1->latch(1);
SuperFamicom::peripherals.controllerPort2->latch(1);
SuperFamicom::peripherals.controllerPort1->latch(0);
SuperFamicom::peripherals.controllerPort2->latch(0);
}
Update to v098r03 release. byuu says: It took several hours, but I've rebuilt much of the SNES' bus memory mapping architecture. The new design unifies the cartridge string-based mapping ("00-3f,80-bf:8000-ffff") and internal bus.map calls. The map() function now has an accompanying unmap() function, and instead of a fixed 256 callbacks, it'll scan to find the first available slot. unmap() will free slots up when zero addresses reference a given slot. The controllers and expansion port are now both entirely dynamic. Instead of load/unload/power/reset, they only have the constructor (power/reset/load) and destructor (unload). What this means is you can now dynamically change even expansion port devices after the system is loaded. Note that this is incredibly dangerous and stupid, but ... oh well. The whole point of this was for 21fx. There's no way to change the expansion port device prior to loading a game, but if the 21fx isn't active, then the reset vector hijack won't work. Now you can load a 21fx game, change the expansion port device, and simply reset the system to active the device. The unification of design between controller port devices and expansion port devices is nice, and overall this results in a reduction of code (all of the Mapping stuff in Cartridge is gone, replaced with direct bus mapping.) And there's always the potential to expand this system more in the future now. The big missing feature right now is the ability to push/pop mappings. So if you look at how the 21fx does the reset vector, you might vomit a little bit. But ... it works. Also changed exit(0) to _exit(0) in the POSIX version of nall::execute. [The _exit(0) thing is an attempt to make higan not crash when it tries to launch icarus and it's not on $PATH. The theory is that higan forks, then the child tries to exec icarus and fails, so it exits, all the unique_ptrs clean up their resources and tell the X server to free things the parent process is still using. Calling _exit() prevents destructors from running, and seems to prevent the problem. -Ed.]
2016-04-09 10:21:18 +00:00
uint2 port0 = SuperFamicom::peripherals.controllerPort1->data();
uint2 port1 = SuperFamicom::peripherals.controllerPort2->data();
Update to v099r14 release. byuu says: Changelog: - (u)int(max,ptr) abbreviations removed; use _t suffix now [didn't feel like they were contributing enough to be worth it] - cleaned up nall::integer,natural,real functionality - toInteger, toNatural, toReal for parsing strings to numbers - fromInteger, fromNatural, fromReal for creating strings from numbers - (string,Markup::Node,SQL-based-classes)::(integer,natural,real) left unchanged - template<typename T> numeral(T value, long padding, char padchar) -> string for print() formatting - deduces integer,natural,real based on T ... cast the value if you want to override - there still exists binary,octal,hex,pointer for explicit print() formatting - lstring -> string_vector [but using lstring = string_vector; is declared] - would be nice to remove the using lstring eventually ... but that'd probably require 10,000 lines of changes >_> - format -> string_format [no using here; format was too ambiguous] - using integer = Integer<sizeof(int)*8>; and using natural = Natural<sizeof(uint)*8>; declared - for consistency with boolean. These three are meant for creating zero-initialized values implicitly (various uses) - R65816::io() -> idle() and SPC700::io() -> idle() [more clear; frees up struct IO {} io; naming] - SFC CPU, PPU, SMP use struct IO {} io; over struct (Status,Registers) {} (status,registers); now - still some CPU::Status status values ... they didn't really fit into IO functionality ... will have to think about this more - SFC CPU, PPU, SMP now use step() exclusively instead of addClocks() calling into step() - SFC CPU joypad1_bits, joypad2_bits were unused; killed them - SFC PPU CGRAM moved into PPU::Screen; since nothing else uses it - SFC PPU OAM moved into PPU::Object; since nothing else uses it - the raw uint8[544] array is gone. OAM::read() constructs values from the OAM::Object[512] table now - this avoids having to determine how we want to sub-divide the two OAM memory sections - this also eliminates the OAM::synchronize() functionality - probably more I'm forgetting The FPS fluctuations are driving me insane. This WIP went from 128fps to 137fps. Settled on 133.5fps for the final build. But nothing I changed should have affected performance at all. This level of fluctuation makes it damn near impossible to know whether I'm speeding things up or slowing things down with changes.
2016-07-01 11:50:32 +00:00
io.joy1 = io.joy1 << 1 | port0.bit(0);
io.joy2 = io.joy2 << 1 | port1.bit(0);
io.joy3 = io.joy3 << 1 | port0.bit(1);
io.joy4 = io.joy4 << 1 | port1.bit(1);
Update to v073r01 release. byuu says: While perhaps not perfect, pretty good is better than nothing ... I've added emulation of auto-joypad poll timing. Going off ikari_01's confirmation of what we suspected, that the strobe happens every 256 clocks, I've set up emulation as follows: Upon reset, our clock counter is reset to zero. At the start of each frame, our poll counter is reset to zero. Every 256 clocks, we call the step_auto_joypad_poll() function. If we are at V=225/240+ (based on overscan setting), we check the poll counter. At zero, we poll the actual controller and set the joypad polling flag in $4212.d0 to 1. From zero through fifteen, we read in one bit for each controller and shift it into the register. At sixteen, we turn off the joypad polling flag. The 256-clock divider allows the start point of polling for each frame to fluctuate wildly like real hardware. I count regardless of auto joypad enable, as per $4212.d0's behavior; but only poll when it's actually enabled. I do not consume any actual time from this polling. I honestly don't know if I even should, or if it manages to do it in the background. If it should consume time, then this most likely happens between opcode edges and we'll have to adjust the code a good bit. All commercial games should continue to work fine, but this will likely break some hacks/translations not tested on hardware. Without the timing emulation, reading $4218-421f before V=~228 would basically give you the valid input controller values of the previous frame. Now, like hardware, it should give you a state that is part previous frame, part current frame shifted into it. Button positions won't be reliable and will shift every 256 clocks. I've also removed the Qt GUI, and renamed ui-phoenix to just ui. This removes 400kb of source code (phoenix is a lean 130kb), and drops the archive size from 564KB to 475KB. Combined with the DSP HLE, and we've knocked off ~570KB of source cruft from the entire project. I am looking forward to not having to specify which GUI is included anymore.
2010-12-27 07:29:57 +00:00
}
status.autoJoypadCounter++;
Update to v073r01 release. byuu says: While perhaps not perfect, pretty good is better than nothing ... I've added emulation of auto-joypad poll timing. Going off ikari_01's confirmation of what we suspected, that the strobe happens every 256 clocks, I've set up emulation as follows: Upon reset, our clock counter is reset to zero. At the start of each frame, our poll counter is reset to zero. Every 256 clocks, we call the step_auto_joypad_poll() function. If we are at V=225/240+ (based on overscan setting), we check the poll counter. At zero, we poll the actual controller and set the joypad polling flag in $4212.d0 to 1. From zero through fifteen, we read in one bit for each controller and shift it into the register. At sixteen, we turn off the joypad polling flag. The 256-clock divider allows the start point of polling for each frame to fluctuate wildly like real hardware. I count regardless of auto joypad enable, as per $4212.d0's behavior; but only poll when it's actually enabled. I do not consume any actual time from this polling. I honestly don't know if I even should, or if it manages to do it in the background. If it should consume time, then this most likely happens between opcode edges and we'll have to adjust the code a good bit. All commercial games should continue to work fine, but this will likely break some hacks/translations not tested on hardware. Without the timing emulation, reading $4218-421f before V=~228 would basically give you the valid input controller values of the previous frame. Now, like hardware, it should give you a state that is part previous frame, part current frame shifted into it. Button positions won't be reliable and will shift every 256 clocks. I've also removed the Qt GUI, and renamed ui-phoenix to just ui. This removes 400kb of source code (phoenix is a lean 130kb), and drops the archive size from 564KB to 475KB. Combined with the DSP HLE, and we've knocked off ~570KB of source cruft from the entire project. I am looking forward to not having to specify which GUI is included anymore.
2010-12-27 07:29:57 +00:00
}
}