diff --git a/Core/NES/HdPacks/HdData.h b/Core/NES/HdPacks/HdData.h index 4d315f11b..dc6f082d2 100644 --- a/Core/NES/HdPacks/HdData.h +++ b/Core/NES/HdPacks/HdData.h @@ -156,6 +156,8 @@ enum class HdPackConditionType SpritePalette, PositionCheckX, PositionCheckY, + OriginPositionCheckX, + OriginPositionCheckY, }; struct HdPackCondition diff --git a/Core/NES/HdPacks/HdPackConditions.h b/Core/NES/HdPacks/HdPackConditions.h index bb29fcc9f..17980d6c0 100644 --- a/Core/NES/HdPacks/HdPackConditions.h +++ b/Core/NES/HdPacks/HdPackConditions.h @@ -150,7 +150,15 @@ struct HdPackBasePositionCheckCondition : public HdPackCondition HdPackConditionType Type = {}; HdPackBasePositionCheckCondition() { _useCache = false; } - string GetConditionName() override { return GetConditionType() == HdPackConditionType::PositionCheckX ? "positionCheckX" : "positionCheckY"; } + string GetConditionName() override + { + switch(GetConditionType()) { + default: case HdPackConditionType::PositionCheckX: return "positionCheckX"; + case HdPackConditionType::PositionCheckY: return "positionCheckY"; + case HdPackConditionType::OriginPositionCheckX: return "originPositionCheckX"; + case HdPackConditionType::OriginPositionCheckY: return "originPositionCheckY"; + } + } void Initialize(HdPackConditionOperator op, uint32_t operand) { @@ -161,7 +169,14 @@ struct HdPackBasePositionCheckCondition : public HdPackCondition bool InternalCheckCondition(int x, int y, HdPpuTileInfo* tile) override { - uint32_t val = (uint32_t)(Type == HdPackConditionType::PositionCheckX ? x : y); + uint32_t val; + switch(Type) { + default: case HdPackConditionType::PositionCheckX: val = (uint32_t)x; break; + case HdPackConditionType::PositionCheckY: val = (uint32_t)y; break; + case HdPackConditionType::OriginPositionCheckX: val = tile->HorizontalMirroring ? (uint32_t)(x - (7 - tile->OffsetX)) : (uint32_t)(x - tile->OffsetX); break; + case HdPackConditionType::OriginPositionCheckY: val = tile->VerticalMirroring ? (uint32_t)(y - (7 - tile->OffsetY)) : (uint32_t)(y - tile->OffsetY); break; + } + switch(Operator) { case HdPackConditionOperator::Equal: return val == Operand; case HdPackConditionOperator::NotEqual: return val != Operand; @@ -202,6 +217,16 @@ struct HdPackPositionCheckYCondition : public HdPackBasePositionCheckCondition HdPackConditionType GetConditionType() override { return HdPackConditionType::PositionCheckY; } }; +struct HdPackOriginPositionCheckXCondition : public HdPackBasePositionCheckCondition +{ + HdPackConditionType GetConditionType() override { return HdPackConditionType::OriginPositionCheckX; } +}; + +struct HdPackOriginPositionCheckYCondition : public HdPackBasePositionCheckCondition +{ + HdPackConditionType GetConditionType() override { return HdPackConditionType::OriginPositionCheckY; } +}; + struct HdPackMemoryCheckCondition : public HdPackBaseMemoryCondition { HdPackConditionType GetConditionType() override { return HdPackConditionType::MemoryCheck; } diff --git a/Core/NES/HdPacks/HdPackLoader.cpp b/Core/NES/HdPacks/HdPackLoader.cpp index f9336cb4c..ca506b447 100644 --- a/Core/NES/HdPacks/HdPackLoader.cpp +++ b/Core/NES/HdPacks/HdPackLoader.cpp @@ -354,9 +354,14 @@ void HdPackLoader::ProcessTileTag(vector &tokens, vectorGetConditionType(); switch(type){ - case HdPackConditionType::SpriteNearby: tileInfo->ForceDisableCache = true; break; - case HdPackConditionType::PositionCheckX: tileInfo->ForceDisableCache = true; break; - case HdPackConditionType::PositionCheckY: tileInfo->ForceDisableCache = true; break; + case HdPackConditionType::SpriteNearby: + case HdPackConditionType::PositionCheckX: + case HdPackConditionType::PositionCheckY: + case HdPackConditionType::OriginPositionCheckX: + case HdPackConditionType::OriginPositionCheckY: + tileInfo->ForceDisableCache = true; + break; + case HdPackConditionType::TileNearby: HdPackTileNearbyCondition* tileNearby = (HdPackTileNearbyCondition*)condition; if(tileNearby->TileX % 8 > 0 || tileNearby->TileY % 8 > 0) { @@ -451,6 +456,10 @@ void HdPackLoader::ProcessConditionTag(vector &tokens, bool createInvert condition.reset(new HdPackPositionCheckXCondition()); } else if(tokens[1] == "positionCheckY") { condition.reset(new HdPackPositionCheckYCondition()); + } else if(tokens[1] == "originPositionCheckX") { + condition.reset(new HdPackOriginPositionCheckXCondition()); + } else if(tokens[1] == "originPositionCheckY") { + condition.reset(new HdPackOriginPositionCheckYCondition()); } else { MessageManager::Log("[HDPack] Invalid condition type: " + tokens[1]); return; @@ -545,14 +554,16 @@ void HdPackLoader::ProcessConditionTag(vector &tokens, bool createInvert } case HdPackConditionType::PositionCheckX: - case HdPackConditionType::PositionCheckY: { + case HdPackConditionType::PositionCheckY: + case HdPackConditionType::OriginPositionCheckX: + case HdPackConditionType::OriginPositionCheckY: { checkConstraint(_data->Version >= 108, "[HDPack] This feature requires version 109+ of HD Packs"); checkConstraint(tokens.size() >= 4, "[HDPack] Condition tag should contain at least 4 parameters"); HdPackConditionOperator op = ParseConditionOperator(tokens[index++]); checkConstraint(op != HdPackConditionOperator::Invalid, "[HDPack] Invalid operator."); - uint32_t operand = HexUtilities::FromHex(tokens[index++]); + uint32_t operand = std::stoi(tokens[index++]); checkConstraint(operand <= 0xFFFF, "[HDPack] Out of range positionCheck operand"); ((HdPackBasePositionCheckCondition*)condition.get())->Initialize(op, operand);