mirror of
https://github.com/libretro/MesenCE.git
synced 2026-11-10 17:25:07 -10:00
-ProcessCpuClock was used to check for events that don't need to be checked that often (auto-switch disk + auto fast-forward options). This has been moved to an EndFrame callback. -This was even slower than intended because of the call to _emu->GetFrameCount() which was, relatively speaking, fairly slow. To improve its performance (since it's used rarely for some things like turbo button processing), a separate GetFrameCount function was added on all console classes, and Emulator::GetFrameCount was also optimized to be faster when called from the emulation thread. When the auto-switch disk option is enabled, this can improve performance by about 25-30%. When the option is not enabled, this still improves performance by 4-5%.
71 lines
1.9 KiB
C++
71 lines
1.9 KiB
C++
#include "pch.h"
|
|
#include "SNES/Input/SnesRumbleController.h"
|
|
#include "SNES/SnesConsole.h"
|
|
#include "SNES/InternalRegisters.h"
|
|
#include "Shared/Emulator.h"
|
|
#include "Shared/KeyManager.h"
|
|
|
|
SnesRumbleController::SnesRumbleController(Emulator* emu, SnesConsole* console, uint8_t port, KeyMappingSet keyMappings) : SnesController(emu, port, keyMappings)
|
|
{
|
|
_console = console;
|
|
_type = ControllerType::SnesRumbleController;
|
|
}
|
|
|
|
SnesRumbleController::~SnesRumbleController()
|
|
{
|
|
KeyManager::SetForceFeedback(0, 0);
|
|
}
|
|
|
|
void SnesRumbleController::Serialize(Serializer& s)
|
|
{
|
|
SnesController::Serialize(s);
|
|
SV(_rumbleData);
|
|
SV(_rumbleActive);
|
|
SV(_lastRumbleFrame);
|
|
}
|
|
|
|
void SnesRumbleController::RefreshStateBuffer()
|
|
{
|
|
_rumbleData = 0;
|
|
|
|
//The LRG rumble controller stops rumbling shortly after the last rumble command.
|
|
//Not accurate, assumes the game regularly latches the controller.
|
|
if(_rumbleActive) {
|
|
if(_console->GetFrameCount() - _lastRumbleFrame > 2) {
|
|
KeyManager::SetForceFeedback(0, 0);
|
|
_rumbleActive = false;
|
|
}
|
|
}
|
|
|
|
SnesController::RefreshStateBuffer();
|
|
}
|
|
|
|
uint8_t SnesRumbleController::ReadRam(uint16_t addr)
|
|
{
|
|
if(IsCurrentPort(addr)) {
|
|
uint8_t ioPort = _console->GetInternalRegisters()->GetIoPortOutput();
|
|
|
|
//Technically, when plugged into port 2, this uses bit 7, but activating the rumble
|
|
//in both ports at the same time could potentially draw too much current, so the
|
|
//UI current prevents picking a rumble controller for P2
|
|
uint8_t ioBit = (GetPort() == 0 ? (ioPort >> 6) : (ioPort >> 7)) & 0x01;
|
|
|
|
_rumbleData = (_rumbleData << 1) | ioBit;
|
|
|
|
if((_rumbleData & 0xFF00) == 0x7200) {
|
|
uint8_t rumble = _rumbleData & 0xFF;
|
|
|
|
//Multiply by 4369 to use all values from 0 to 65535
|
|
uint16_t rightRumble = (rumble >> 4) * 4369;
|
|
uint16_t leftRumble = (rumble & 0x0F) * 4369;
|
|
|
|
KeyManager::SetForceFeedback(rightRumble, leftRumble);
|
|
|
|
_rumbleActive = true;
|
|
_lastRumbleFrame = _console->GetFrameCount();
|
|
}
|
|
}
|
|
|
|
return SnesController::ReadRam(addr);
|
|
}
|