mirror of
https://github.com/libretro/Mesen.git
synced 2024-12-14 12:58:56 +00:00
205 lines
5.3 KiB
C++
205 lines
5.3 KiB
C++
#include "stdafx.h"
|
|
#include "ControlManager.h"
|
|
#include "SystemActionManager.h"
|
|
#include "FdsSystemActionManager.h"
|
|
#include "VsSystemActionManager.h"
|
|
#include "BizhawkMovie.h"
|
|
#include "VsControlManager.h"
|
|
#include "FDS.h"
|
|
|
|
BizhawkMovie::BizhawkMovie()
|
|
{
|
|
_originalPowerOnState = EmulationSettings::GetRamPowerOnState();
|
|
}
|
|
|
|
BizhawkMovie::~BizhawkMovie()
|
|
{
|
|
Stop();
|
|
}
|
|
|
|
void BizhawkMovie::Stop()
|
|
{
|
|
if(_isPlaying) {
|
|
EndMovie();
|
|
EmulationSettings::SetRamPowerOnState(_originalPowerOnState);
|
|
_isPlaying = false;
|
|
}
|
|
ControlManager::UnregisterInputProvider(this);
|
|
}
|
|
|
|
bool BizhawkMovie::SetInput(BaseControlDevice *device)
|
|
{
|
|
SystemActionManager* actionManager = dynamic_cast<SystemActionManager*>(device);
|
|
int32_t pollCounter = ControlManager::GetPollCounter();
|
|
if(actionManager) {
|
|
if(pollCounter < (int32_t)_systemActionByFrame.size()) {
|
|
uint32_t systemAction = _systemActionByFrame[pollCounter];
|
|
if(systemAction & 0x01) {
|
|
actionManager->SetBit(SystemActionManager::Buttons::PowerButton);
|
|
}
|
|
if(systemAction & 0x02) {
|
|
actionManager->SetBit(SystemActionManager::Buttons::ResetButton);
|
|
}
|
|
|
|
VsSystemActionManager* vsActionManager = dynamic_cast<VsSystemActionManager*>(device);
|
|
if(vsActionManager) {
|
|
if(systemAction & 0x04) {
|
|
actionManager->SetBit(VsSystemActionManager::VsButtons::InsertCoin1);
|
|
}
|
|
if(systemAction & 0x08) {
|
|
actionManager->SetBit(VsSystemActionManager::VsButtons::InsertCoin2);
|
|
}
|
|
if(systemAction & 0x10) {
|
|
actionManager->SetBit(VsSystemActionManager::VsButtons::ServiceButton);
|
|
}
|
|
}
|
|
|
|
FdsSystemActionManager* fdsActionManager = dynamic_cast<FdsSystemActionManager*>(device);
|
|
if(fdsActionManager) {
|
|
//FDS timings between NesHawk & Mesen are currently significantly different
|
|
//So FDS games will always go out of sync
|
|
if(systemAction & 0x04) {
|
|
fdsActionManager->SetBit(FdsSystemActionManager::FdsButtons::EjectDiskButton);
|
|
}
|
|
|
|
if(systemAction >= 8) {
|
|
systemAction >>= 3;
|
|
uint32_t diskNumber = 0;
|
|
while(!(systemAction & 0x01)) {
|
|
systemAction >>= 1;
|
|
diskNumber++;
|
|
}
|
|
|
|
fdsActionManager->SetBit(FdsSystemActionManager::FdsButtons::InsertDisk1 + diskNumber);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
int port = device->GetPort();
|
|
StandardController* controller = dynamic_cast<StandardController*>(device);
|
|
if(controller) {
|
|
if(pollCounter < (int32_t)_dataByFrame[port].size()) {
|
|
controller->SetTextState(_dataByFrame[port][pollCounter]);
|
|
} else {
|
|
Stop();
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool BizhawkMovie::InitializeGameData(ZipReader &reader)
|
|
{
|
|
stringstream fileData;
|
|
if(!reader.GetStream("Header.txt", fileData)) {
|
|
return false;
|
|
}
|
|
|
|
ControlManager::ResetPollCounter();
|
|
|
|
while(!fileData.eof()) {
|
|
string line;
|
|
std::getline(fileData, line);
|
|
if(line.compare(0, 4, "SHA1", 4) == 0) {
|
|
if(line.size() >= 45) {
|
|
HashInfo hashInfo;
|
|
hashInfo.Sha1Hash = line.substr(5, 40);
|
|
if(Console::LoadROM("", hashInfo)) {
|
|
return true;
|
|
}
|
|
}
|
|
} else if(line.compare(0, 3, "MD5", 3) == 0) {
|
|
if(line.size() >= 36) {
|
|
HashInfo hashInfo;
|
|
hashInfo.PrgChrMd5Hash = line.substr(4, 32);
|
|
std::transform(hashInfo.PrgChrMd5Hash.begin(), hashInfo.PrgChrMd5Hash.end(), hashInfo.PrgChrMd5Hash.begin(), ::toupper);
|
|
if(Console::LoadROM("", hashInfo)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool BizhawkMovie::InitializeInputData(ZipReader &reader)
|
|
{
|
|
stringstream inputData;
|
|
if(!reader.GetStream("Input Log.txt", inputData)) {
|
|
return false;
|
|
}
|
|
|
|
int systemActionCount = 2;
|
|
shared_ptr<FdsSystemActionManager> fdsActionManager = Console::GetInstance()->GetSystemActionManager<FdsSystemActionManager>();
|
|
if(fdsActionManager) {
|
|
//Eject disk + Insert Disk #XX
|
|
systemActionCount += fdsActionManager->GetSideCount() + 1;
|
|
} else {
|
|
shared_ptr<VsSystemActionManager> vsActionManager = Console::GetInstance()->GetSystemActionManager<VsSystemActionManager>();
|
|
if(vsActionManager) {
|
|
//Insert coin 1, 2 + service button
|
|
systemActionCount += 3;
|
|
}
|
|
}
|
|
|
|
while(!inputData.eof()) {
|
|
string line;
|
|
std::getline(inputData, line);
|
|
|
|
if(line.size() > 0 && line[0] == '|') {
|
|
line.erase(std::remove(line.begin(), line.end(), '|'), line.end());
|
|
line = line.substr(0, line.size() - 1);
|
|
|
|
//Read power/reset/FDS/VS/etc. commands
|
|
uint32_t systemAction = 0;
|
|
for(int i = 0; i < systemActionCount; i++) {
|
|
if(line[i] != '.') {
|
|
systemAction |= (1 << i);
|
|
}
|
|
}
|
|
_systemActionByFrame.push_back(systemAction);
|
|
|
|
line = line.substr(systemActionCount);
|
|
int port = 0;
|
|
while(line.size() >= 8) {
|
|
_dataByFrame[port].push_back(line.substr(0, 8));
|
|
line = line.substr(8);
|
|
port++;
|
|
}
|
|
while(port < 4) {
|
|
_dataByFrame[port].push_back("........");
|
|
port++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return _dataByFrame[0].size() > 0;
|
|
}
|
|
|
|
bool BizhawkMovie::Play(VirtualFile &file)
|
|
{
|
|
Console::Pause();
|
|
ZipReader reader;
|
|
|
|
std::stringstream ss;
|
|
file.ReadFile(ss);
|
|
|
|
reader.LoadArchive(ss);
|
|
ControlManager::RegisterInputProvider(this);
|
|
if(InitializeInputData(reader) && InitializeGameData(reader)) {
|
|
//NesHawk initializes memory to 1s
|
|
EmulationSettings::SetRamPowerOnState(RamPowerOnState::AllOnes);
|
|
_isPlaying = true;
|
|
} else {
|
|
ControlManager::UnregisterInputProvider(this);
|
|
}
|
|
Console::Resume();
|
|
return _isPlaying;
|
|
}
|
|
|
|
bool BizhawkMovie::IsPlaying()
|
|
{
|
|
return _isPlaying;
|
|
}
|