HD Packs: Added ppuMemoryCheck/ppuMemoryCheckConstant conditions

This commit is contained in:
Sour 2018-03-14 23:25:06 -04:00
parent 41ed9d57ed
commit b9e771c405
4 changed files with 43 additions and 15 deletions

View file

@ -1,5 +1,6 @@
#pragma once
#include "stdafx.h"
#include <unordered_set>
#include "PPU.h"
#include "../Utilities/HexUtilities.h"
@ -342,7 +343,7 @@ struct HdPackData
vector<unique_ptr<HdBackgroundFileData>> BackgroundFileData;
vector<unique_ptr<HdPackTileInfo>> Tiles;
vector<unique_ptr<HdPackCondition>> Conditions;
vector<uint16_t> WatchedMemoryAddresses;
std::unordered_set<uint32_t> WatchedMemoryAddresses;
std::unordered_map<HdTileKey, vector<HdPackTileInfo*>> TileByKey;
std::unordered_map<string, string> PatchesByHash;
std::unordered_map<int, string> BgmFilesById;

View file

@ -56,6 +56,7 @@ enum class HdPackConditionOperator
struct HdPackBaseMemoryCondition : public HdPackCondition
{
static const uint32_t PpuMemoryMarker = 0x80000000;
uint32_t OperandA;
HdPackConditionOperator Operator;
uint32_t OperandB;
@ -67,11 +68,16 @@ struct HdPackBaseMemoryCondition : public HdPackCondition
OperandB = operandB;
}
bool IsPpuCondition()
{
return (OperandA & HdPackBaseMemoryCondition::PpuMemoryMarker) != 0;
}
string ToString() override
{
stringstream out;
out << "<condition>" << Name << "," << GetConditionName() << ",";
out << OperandA << ",";
out << HexUtilities::ToHex(OperandA & 0xFFFF) << ",";
switch(Operator) {
case HdPackConditionOperator::Equal: out << "=="; break;
case HdPackConditionOperator::NotEqual: out << "!="; break;
@ -79,7 +85,7 @@ struct HdPackBaseMemoryCondition : public HdPackCondition
case HdPackConditionOperator::LowerThan: out << "<"; break;
}
out << ",";
out << OperandB;
out << HexUtilities::ToHex(OperandB);
return out.str();
}
@ -124,7 +130,7 @@ struct HdPackBgPriorityCondition : public HdPackCondition
struct HdPackMemoryCheckCondition : public HdPackBaseMemoryCondition
{
HdPackMemoryCheckCondition() { _useCache = true; }
string GetConditionName() override { return "memoryCheck"; }
string GetConditionName() override { return IsPpuCondition() ? "ppuMemoryCheck" : "memoryCheck"; }
bool InternalCheckCondition(HdScreenInfo *screenInfo, int x, int y, HdPpuTileInfo* tile) override
{
@ -141,7 +147,7 @@ struct HdPackMemoryCheckCondition : public HdPackBaseMemoryCondition
struct HdPackMemoryCheckConstantCondition : public HdPackBaseMemoryCondition
{
HdPackMemoryCheckConstantCondition() { _useCache = true; }
string GetConditionName() override { return "memoryCheckConstant"; }
string GetConditionName() override { return IsPpuCondition() ? "ppuMemoryCheckConstant" : "memoryCheckConstant"; }
bool InternalCheckCondition(HdScreenInfo *screenInfo, int x, int y, HdPpuTileInfo* tile) override
{

View file

@ -394,9 +394,9 @@ void HdPackLoader::ProcessConditionTag(vector<string> &tokens, bool createInvert
condition.reset(new HdPackSpriteAtPositionCondition());
} else if(tokens[1] == "spriteNearby") {
condition.reset(new HdPackSpriteNearbyCondition());
} else if(tokens[1] == "memoryCheck") {
} else if(tokens[1] == "memoryCheck" || tokens[1] == "ppuMemoryCheck") {
condition.reset(new HdPackMemoryCheckCondition());
} else if(tokens[1] == "memoryCheckConstant") {
} else if(tokens[1] == "memoryCheckConstant" || tokens[1] == "ppuMemoryCheckConstant") {
condition.reset(new HdPackMemoryCheckConstantCondition());
} else if(tokens[1] == "frameRange") {
condition.reset(new HdPackFrameRangeCondition());
@ -433,8 +433,15 @@ void HdPackLoader::ProcessConditionTag(vector<string> &tokens, bool createInvert
checkConstraint(_data->Version >= 101, "[HDPack] This feature requires version 101+ of HD Packs");
checkConstraint(tokens.size() >= 5, "[HDPack] Condition tag should contain at least 5 parameters");
int operandA = HexUtilities::FromHex(tokens[index++]);
checkConstraint(operandA >= 0 && operandA <= 0xFFFF, "[HDPack] Out of range memoryCheck operand");
bool usePpuMemory = tokens[1].substr(0, 3) == "ppu";
uint32_t operandA = HexUtilities::FromHex(tokens[index++]);
if(usePpuMemory) {
checkConstraint(operandA >= 0 && operandA <= 0x3FFF, "[HDPack] Out of range memoryCheck operand");
operandA |= HdPackBaseMemoryCondition::PpuMemoryMarker;
} else {
checkConstraint(operandA >= 0 && operandA <= 0xFFFF, "[HDPack] Out of range memoryCheck operand");
}
HdPackConditionOperator op;
string opString = tokens[index++];
@ -448,15 +455,20 @@ void HdPackLoader::ProcessConditionTag(vector<string> &tokens, bool createInvert
op = HdPackConditionOperator::LowerThan;
}
int operandB = HexUtilities::FromHex(tokens[index++]);
uint32_t operandB = HexUtilities::FromHex(tokens[index++]);
if(dynamic_cast<HdPackMemoryCheckCondition*>(condition.get())) {
checkConstraint(operandB >= 0 && operandB <= 0xFFFF, "[HDPack] Out of range memoryCheck operand");
_data->WatchedMemoryAddresses.push_back(operandB);
if(usePpuMemory) {
checkConstraint(operandB >= 0 && operandB <= 0x3FFF, "[HDPack] Out of range memoryCheck operand");
operandB |= HdPackBaseMemoryCondition::PpuMemoryMarker;
} else {
checkConstraint(operandB >= 0 && operandB <= 0xFFFF, "[HDPack] Out of range memoryCheck operand");
}
_data->WatchedMemoryAddresses.emplace(operandB);
} else if(dynamic_cast<HdPackMemoryCheckConstantCondition*>(condition.get())) {
checkConstraint(operandB >= 0 && operandB <= 0xFF, "[HDPack] Out of range memoryCheckConstant operand");
}
_data->WatchedMemoryAddresses.push_back(operandA);
_data->WatchedMemoryAddresses.emplace(operandA);
((HdPackBaseMemoryCondition*)condition.get())->Initialize(operandA, op, operandB);
} else if(dynamic_cast<HdPackFrameRangeCondition*>(condition.get())) {
checkConstraint(_data->Version >= 101, "[HDPack] This feature requires version 101+ of HD Packs");

View file

@ -5,6 +5,7 @@
#include "HdNesPack.h"
#include "VideoDecoder.h"
#include "RewindManager.h"
#include "HdPackConditions.h"
class ControlManager;
@ -150,8 +151,16 @@ public:
_info->FrameNumber = _frameCount;
_info->WatchedAddressValues.clear();
for(uint16_t address : _hdData->WatchedMemoryAddresses) {
_info->WatchedAddressValues[address] = CPU::DebugReadByte(address);
for(uint32_t address : _hdData->WatchedMemoryAddresses) {
if(address & HdPackBaseMemoryCondition::PpuMemoryMarker) {
if((address & 0x3FFF) >= 0x3F00) {
_info->WatchedAddressValues[address] = ReadPaletteRAM(address);
} else {
_info->WatchedAddressValues[address] = _mapper->DebugReadVRAM(address & 0x3FFF, true);
}
} else {
_info->WatchedAddressValues[address] = CPU::DebugReadByte(address);
}
}
#ifdef LIBRETRO