190 lines
4.7 KiB
C++
190 lines
4.7 KiB
C++
#include "stdafx.h"
|
|
#include "BizhawkMovie.h"
|
|
#include "VsControlManager.h"
|
|
#include "FDS.h"
|
|
#include "PPU.h"
|
|
|
|
BizhawkMovie::BizhawkMovie()
|
|
{
|
|
_originalPowerOnState = EmulationSettings::GetRamPowerOnState();
|
|
MessageManager::RegisterNotificationListener(this);
|
|
}
|
|
|
|
BizhawkMovie::~BizhawkMovie()
|
|
{
|
|
MessageManager::UnregisterNotificationListener(this);
|
|
EmulationSettings::SetRamPowerOnState(_originalPowerOnState);
|
|
}
|
|
|
|
void BizhawkMovie::ProcessNotification(ConsoleNotificationType type, void* parameter)
|
|
{
|
|
if(type == ConsoleNotificationType::PpuFrameDone) {
|
|
int32_t frameNumber = PPU::GetFrameCount() - 1;
|
|
if(frameNumber < (int32_t)_systemActionByFrame.size()) {
|
|
uint32_t systemAction = _systemActionByFrame[frameNumber];
|
|
if(systemAction & 0x01) {
|
|
//Power, not implemented yet
|
|
}
|
|
if(systemAction & 0x02) {
|
|
//Reset, not implemented yet
|
|
}
|
|
|
|
if(FDS::GetSideCount()) {
|
|
//FDS timings between NesHawk & Mesen are currently significantly different
|
|
//So FDS games will always go out of sync
|
|
if(systemAction & 0x04) {
|
|
FDS::EjectDisk();
|
|
} else if(systemAction >= 8) {
|
|
systemAction >>= 3;
|
|
uint32_t diskNumber = 0;
|
|
while(!(systemAction & 0x01)) {
|
|
systemAction >>= 1;
|
|
diskNumber++;
|
|
}
|
|
FDS::InsertDisk(diskNumber);
|
|
}
|
|
} else if(VsControlManager::GetInstance()) {
|
|
if(VsControlManager::GetInstance()) {
|
|
if(systemAction & 0x04) {
|
|
VsControlManager::GetInstance()->InsertCoin(0);
|
|
}
|
|
if(systemAction & 0x08) {
|
|
VsControlManager::GetInstance()->InsertCoin(1);
|
|
}
|
|
VsControlManager::GetInstance()->SetServiceButtonState(systemAction & 0x10 ? true : false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
uint8_t BizhawkMovie::GetState(uint8_t port)
|
|
{
|
|
int32_t frameNumber = PPU::GetFrameCount() - 1;
|
|
if(frameNumber < (int32_t)_dataByFrame[0].size()) {
|
|
return _dataByFrame[port][frameNumber];
|
|
} else {
|
|
EndMovie();
|
|
EmulationSettings::SetRamPowerOnState(_originalPowerOnState);
|
|
_isPlaying = false;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
bool BizhawkMovie::InitializeGameData(ZipReader & reader)
|
|
{
|
|
std::stringstream ss = reader.GetStream("Header.txt");
|
|
|
|
bool result = false;
|
|
while(!ss.eof()) {
|
|
string line;
|
|
std::getline(ss, line);
|
|
if(line.compare(0, 4, "SHA1", 4) == 0) {
|
|
if(line.size() >= 45) {
|
|
string sha1 = line.substr(5, 40);
|
|
if(Console::LoadROM("", sha1)) {
|
|
result = 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)) {
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool BizhawkMovie::InitializeInputData(ZipReader & reader)
|
|
{
|
|
const uint8_t orValues[8] = { 0x10, 0x20, 0x40, 0x80, 0x08, 0x04, 0x02, 0x01 };
|
|
std::stringstream ss = reader.GetStream("Input Log.txt");
|
|
|
|
int systemActionCount = 2;
|
|
if(FDS::GetSideCount() > 0) {
|
|
//Eject disk + Insert Disk #XX
|
|
systemActionCount += FDS::GetSideCount() + 1;
|
|
} else if(VsControlManager::GetInstance()) {
|
|
//Insert coin 1, 2 + service button
|
|
systemActionCount += 3;
|
|
}
|
|
|
|
while(!ss.eof()) {
|
|
string line;
|
|
std::getline(ss, 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);
|
|
|
|
//Only supports regular controllers (up to 4 of them)
|
|
for(int i = 0; i < 8*4; i++) {
|
|
uint8_t port = i / 8;
|
|
|
|
if(port <= 3) {
|
|
uint8_t portValue = 0;
|
|
for(int j = 0; j < 8 && i + j + systemActionCount < (int)line.size(); j++) {
|
|
if(line[i+j+systemActionCount] != '.') {
|
|
portValue |= orValues[j];
|
|
}
|
|
}
|
|
i += 7;
|
|
_dataByFrame[port].push_back(portValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return _dataByFrame[0].size() > 0;
|
|
}
|
|
|
|
bool BizhawkMovie::Play(stringstream & filestream, bool autoLoadRom)
|
|
{
|
|
Console::Pause();
|
|
ZipReader reader;
|
|
reader.LoadArchive(filestream);
|
|
if(InitializeGameData(reader)) {
|
|
if(InitializeInputData(reader)) {
|
|
//NesHawk initializes memory to 1s
|
|
EmulationSettings::SetRamPowerOnState(RamPowerOnState::AllOnes);
|
|
Console::Reset(false);
|
|
_isPlaying = true;
|
|
}
|
|
}
|
|
Console::Resume();
|
|
return _isPlaying;
|
|
}
|
|
|
|
bool BizhawkMovie::IsRecording()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool BizhawkMovie::IsPlaying()
|
|
{
|
|
return _isPlaying;
|
|
}
|
|
|
|
void BizhawkMovie::RecordState(uint8_t port, uint8_t value)
|
|
{
|
|
//Not implemented
|
|
}
|
|
|
|
void BizhawkMovie::Record(string filename, bool reset)
|
|
{
|
|
//Not implemented
|
|
}
|