Skip to content

Commit

Permalink
Re-implemented old behavior for overlapping stops
Browse files Browse the repository at this point in the history
  • Loading branch information
123jimin committed Dec 1, 2021
1 parent 633771b commit 3ddcfa3
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 7 deletions.
3 changes: 3 additions & 0 deletions Beatmap/include/Beatmap/LineGraph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ class LineGraph {
void Insert(MapTime time, const Point& point);
void Insert(MapTime time, const std::string& point);

void RangeSet(MapTime begin, MapTime end, double value);
void RangeAdd(MapTime begin, MapTime end, double delta);

/// Returns the value being extended.
double Extend(MapTime time);

Expand Down
44 changes: 37 additions & 7 deletions Beatmap/src/BeatmapFromKSH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,10 @@ bool Beatmap::m_ProcessKShootMap(BinaryStream &input, bool metadataOnly)
float laserRanges[2] = {1.0f, 1.0f};
MapTime lastLaserPointTime[2] = {0, 0};

// Stops will be applied after the scroll speed graph is constructed.
// Tuple of (stopBegin, stopEnd, isOverlappingStop)
Vector<std::tuple<MapTime, MapTime, bool>> stops;

MapTime lastMapTime = 0;
uint32 currentTick = 0;

Expand Down Expand Up @@ -925,14 +929,17 @@ bool Beatmap::m_ProcessKShootMap(BinaryStream &input, bool metadataOnly)
}
else if (p.first == "stop")
{
MapTime stopDuration = Math::RoundToInt((atol(*p.second) / 192.0f) * (currTimingPoint->beatDuration) * 4);
// Stops will be applied after the scroll speed graph is constructed.
const MapTime stopDuration = Math::RoundToInt((atol(*p.second) / 192.0f) * (currTimingPoint->beatDuration) * 4);
bool isOverlappingStop = false;

LineGraph& scrollSpeedGraph = m_effects.GetGraph(EffectTimeline::GraphType::SCROLL_SPEED);
if (!stops.empty() && mapTime < std::get<1>(*stops.rbegin()))
{
isOverlappingStop = true;
std::get<2>(*stops.rbegin()) = true;
}

const double endValue = scrollSpeedGraph.ValueAt(mapTime + stopDuration);
scrollSpeedGraph.Extend(mapTime);
scrollSpeedGraph.Insert(mapTime, 0.0);
scrollSpeedGraph.Insert(mapTime + stopDuration, LineGraph::Point{0.0, endValue});
stops.Add(std::make_tuple(mapTime, mapTime + stopDuration, isOverlappingStop));
}
else if (p.first == "scroll_speed")
{
Expand Down Expand Up @@ -1340,7 +1347,30 @@ bool Beatmap::m_ProcessKShootMap(BinaryStream &input, bool metadataOnly)
currentTick += static_cast<uint32>((tickResolution * 4 * currTimingPoint->numerator / currTimingPoint->denominator) / block.ticks.size());
}

//Add chart end event
// Apply stops
for (const auto& stop : stops)
{
const MapTime stopBegin = std::get<0>(stop);
const MapTime stopEnd = std::get<1>(stop);
const bool isOverlapping = std::get<2>(stop);

LineGraph& scrollSpeedGraph = m_effects.GetGraph(EffectTimeline::GraphType::SCROLL_SPEED);

// In older versions of USC there was a bug where overlapping stop regions made notes scrolling backwards.
// This bug was utilized as gimmicks for several charts, so for backwards compatibility this bug is reimplemented.
// (i.e. the chart would simply not move)

if (isOverlapping)
{
scrollSpeedGraph.RangeAdd(stopBegin, stopEnd, -1.0);
}
else
{
scrollSpeedGraph.RangeSet(stopBegin, stopEnd, 0.0);
}
}

// Add chart end event
EventObjectState *evt = new EventObjectState();
evt->time = lastMapTime + 2000;
evt->key = EventKey::ChartEnd;
Expand Down
43 changes: 43 additions & 0 deletions Beatmap/src/LineGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,49 @@ void LineGraph::Insert(MapTime mapTime, const std::string& point)
}
}

void LineGraph::RangeSet(MapTime begin, MapTime end, double value)
{
if (begin >= end) return;

const double beginValue = ValueAt(begin);
const double endValue = ValueAt(end);

const auto beginIt = m_points.lower_bound(begin);
const auto endIt = m_points.upper_bound(end);

for (auto it = beginIt; it != endIt; it = m_points.erase(it));

Insert(begin, LineGraph::Point{beginValue, value});
Insert(end, LineGraph::Point{value, endValue});
}

void LineGraph::RangeAdd(MapTime begin, MapTime end, double delta)
{
if (begin >= end) return;

const double beginValue = ValueAt(begin);
const double endValue = ValueAt(end);

const auto beginIt = m_points.upper_bound(begin);
const auto endIt = m_points.lower_bound(end);

for (auto it = beginIt; it != endIt; ++it)
{
it->second.value.first += delta;
it->second.value.second += delta;
}

Insert(begin, LineGraph::Point{beginValue, beginValue + delta});

if (endIt != m_points.end() && endIt->first == end)
{
endIt->second.value.first += delta;
} else
{
Insert(end, LineGraph::Point{endValue + delta, endValue});
}
}

double LineGraph::Extend(MapTime time)
{
if (m_points.empty())
Expand Down

0 comments on commit 3ddcfa3

Please sign in to comment.