Skip to content

Commit ab9569b

Browse files
jetrotalGhabry
authored andcommitted
AnimateVars - Major Refactor, everything works!
Update game_interpreter.cpp
1 parent 58fc18c commit ab9569b

File tree

1 file changed

+107
-180
lines changed

1 file changed

+107
-180
lines changed

src/game_interpreter.cpp

+107-180
Original file line numberDiff line numberDiff line change
@@ -5098,129 +5098,65 @@ int Game_Interpreter::ManiacBitmask(int value, int mask) const {
50985098

50995099
return value;
51005100
}
5101-
std::vector<double> parseBezier(const std::string& bezierParams) {
5102-
std::vector<double> params;
5103-
std::string temp;
5104-
size_t startPos = bezierParams.find("(") + 1;
5105-
size_t endPos = bezierParams.find(")");
5106-
std::string valuesString = bezierParams.substr(startPos, endPos - startPos);
51075101

5108-
size_t commaPos = valuesString.find(",");
5109-
while (commaPos != std::string::npos) {
5110-
temp = valuesString.substr(0, commaPos);
5111-
params.push_back(std::stod(temp));
5112-
valuesString = valuesString.substr(commaPos + 1);
5113-
commaPos = valuesString.find(",");
5114-
}
5115-
// Push the last value into the vector
5116-
params.push_back(std::stod(valuesString));
5117-
5118-
return params;
5119-
}
5120-
5121-
//FIXME: cubicBezier is completely Broken
5122-
// references to how it should work:
5102+
// references for cubic bezier:
51235103
// https://matthewlein.com/tools/ceaser
51245104
// https://cubic-bezier.com/
5105+
double cubicBezier(float t, const double& p0,const double& p1, const double& p2, const double& p3) {
51255106

5126-
double cubicBezier(double t, double p0, double p1, double p2, double p3) {
5127-
double u = 1 - t;
5128-
double tt = t * t;
5129-
double uu = u * u;
5130-
double uuu = uu * u;
5131-
double ttt = tt * t;
5107+
float u = 1 - t;
5108+
float tt = t * t;
5109+
float uu = u * u;
5110+
float uuu = uu * u;
5111+
float ttt = tt * t;
51325112

5133-
double p = uuu * p0; // (1-t)^3
5134-
double q = 3 * uu * t * p1; // 3t(1-t)^2
5135-
double r = 3 * u * tt * p2; // 3(1-t)t^2
5136-
double s = ttt * p3; // t^3
5113+
//Point2d p = {0,0};
5114+
//p.x = uuu * 0 + 3 * uu * t * p0 + 3 * u * tt * p2 + ttt * 1;
5115+
return uuu * 0 + 3 * uu * t * p1 + 3 * u * tt * p3 + ttt * 1;
51375116

5138-
return p + q + r + s;
5117+
//return p.y;
51395118
}
51405119

5141-
double getEasedT(const std::string& easingType, double t, double b, double c, double d) {
5142-
if (easingType == "linear") {
5143-
return c * t / d + b;
5144-
}
5145-
else if (easingType == "quadIn") {
5146-
t /= d;
5147-
return c * t * t + b;
5148-
}
5149-
else if (easingType == "quadOut") {
5150-
t /= d;
5151-
return -c * t * (t - 2) + b;
5152-
}
5153-
else if (easingType == "quadInOut") {
5154-
t /= d / 2;
5155-
if (t < 1) {
5156-
return c / 2 * t * t + b;
5157-
}
5158-
else {
5159-
t -= 1;
5160-
return -c / 2 * (t * (t - 2) - 1) + b;
5161-
}
5162-
}
5163-
else if (easingType == "cubicIn") {
5164-
t /= d;
5165-
return c * t * t * t + b;
5166-
}
5167-
else if (easingType == "cubicOut") {
5168-
t = (t / d) - 1;
5169-
return c * (t * t * t + 1) + b;
5170-
}
5171-
else if (easingType == "cubicInOut") {
5172-
t /= d / 2;
5173-
if (t < 1) {
5174-
return c / 2 * t * t * t + b;
5175-
}
5176-
else {
5177-
t -= 2;
5178-
return c / 2 * (t * t * t + 2) + b;
5179-
}
5180-
}
5181-
else if (easingType == "sinIn") {
5182-
return -c * cos(t / d * (M_PI / 2)) + c + b;
5183-
}
5184-
else if (easingType == "sinOut") {
5185-
return c * sin(t / d * (M_PI / 2)) + b;
5186-
}
5187-
else if (easingType == "sinInOut") {
5188-
return -c / 2 * (cos(M_PI * t / d) - 1) + b;
5189-
}
5190-
else if (easingType == "expoIn") {
5191-
return c * pow(2, 10 * (t / d - 1)) + b;
5192-
}
5193-
else if (easingType == "expoOut") {
5194-
return c * (-pow(2, -10 * t / d) + 1) + b;
5195-
}
5196-
else if (easingType == "expoInOut") {
5197-
t /= d / 2;
5198-
if (t < 1) {
5199-
return c / 2 * pow(2, 10 * (t - 1)) + b;
5200-
}
5201-
else {
5202-
t -= 1;
5203-
return c / 2 * (-pow(2, -10 * t) + 2) + b;
5204-
}
5205-
}
5206-
else if (easingType == "circIn") {
5207-
t /= d;
5208-
return -c * (sqrt(1 - t * t) - 1) + b;
5209-
}
5210-
else if (easingType == "circOut") {
5211-
t = (t / d) - 1;
5212-
return c * sqrt(1 - t * t) + b;
5213-
}
5214-
else if (easingType == "circInOut") {
5215-
t /= d / 2;
5216-
if (t < 1) {
5217-
return -c / 2 * (sqrt(1 - t * t) - 1) + b;
5218-
}
5219-
else {
5220-
t -= 2;
5221-
return c / 2 * (sqrt(1 - t * t) + 1) + b;
5222-
}
5223-
}
5120+
double getEasedTime(const std::string& easingType, double t, double b, double c, double d) {
5121+
if (easingType == "linear") return cubicBezier(t, 0.250, 0.250, 0.750, 0.750);
5122+
5123+
else if (easingType == "ease") return cubicBezier(t, 0.250, 0.100, 0.250, 1.000);
5124+
else if (easingType == "easeIn") return cubicBezier(t, 0.420, 0.000, 1.000, 1.000);
5125+
else if (easingType == "easeOut") return cubicBezier(t, 0.000, 0.000, 0.580, 1.000);
5126+
else if (easingType == "easeInOut") return cubicBezier(t, 0.420, 0.000, 0.580, 1.000);
5127+
5128+
else if (easingType == "quadIn") return cubicBezier(t, 0.550, 0.085, 0.680, 0.530);
5129+
else if (easingType == "quadOut") return cubicBezier(t, 0.250, 0.460, 0.450, 0.940);
5130+
else if (easingType == "quadInOut") return cubicBezier(t, 0.455, 0.030, 0.515, 0.955);
5131+
5132+
else if (easingType == "cubicIn") return cubicBezier(t, 0.550, 0.055, 0.675, 0.190);
5133+
else if (easingType == "cubicOut") return cubicBezier(t, 0.215, 0.610, 0.355, 1.000);
5134+
else if (easingType == "cubicInOut") return cubicBezier(t, 0.645, 0.045, 0.355, 1.000);
5135+
5136+
else if (easingType == "quartIn") return cubicBezier(t, 0.895, 0.030, 0.685, 0.220);
5137+
else if (easingType == "quartOut") return cubicBezier(t, 0.165, 0.840, 0.440, 1.000);
5138+
else if (easingType == "quartInOut") return cubicBezier(t, 0.770, 0.000, 0.175, 1.000);
5139+
5140+
else if (easingType == "quintIn") return cubicBezier(t, 0.755, 0.050, 0.855, 0.060);
5141+
else if (easingType == "quintOut") return cubicBezier(t, 0.230, 1.000, 0.320, 1.000);
5142+
else if (easingType == "quintInOut") return cubicBezier(t, 0.860, 0.000, 0.070, 1.000);
5143+
5144+
else if (easingType == "sineIn") return cubicBezier(t, 0.470, 0.000, 0.745, 0.715);
5145+
else if (easingType == "sineOut") return cubicBezier(t, 0.390, 0.575, 0.565, 1.000);
5146+
else if (easingType == "sineInOut") return cubicBezier(t, 0.445, 0.050, 0.550, 0.950);
5147+
5148+
else if (easingType == "ExpoIn") return cubicBezier(t, 0.950, 0.050, 0.795, 0.035);
5149+
else if (easingType == "expoOut") return cubicBezier(t, 0.190, 1.000, 0.220, 1.000);
5150+
else if (easingType == "expoInOut") return cubicBezier(t, 1.000, 0.000, 0.000, 1.000);
5151+
5152+
else if (easingType == "circIn") return cubicBezier(t, 0.600, 0.040, 0.980, 0.335);
5153+
else if (easingType == "circOut") return cubicBezier(t, 0.075, 0.820, 0.165, 1.000);
5154+
else if (easingType == "circInOut") return cubicBezier(t, 0.785, 0.135, 0.150, 0.860);
5155+
5156+
else if (easingType == "backIn") return cubicBezier(t, 0.600, -0.280, 0.735, 0.045);
5157+
else if (easingType == "backOut") return cubicBezier(t, 0.175, 0.885, 0.320, 1.275);
5158+
else if (easingType == "backInOut") return cubicBezier(t, 0.680, -0.550, 0.265, 1.550);
5159+
52245160
else if (easingType == "elasticIn") {
52255161
if (t == 0) {
52265162
return b;
@@ -5270,8 +5206,9 @@ double getEasedT(const std::string& easingType, double t, double b, double c, do
52705206
double postFix = a * pow(2, -10 * (t -= 1)); // this is a fix, again, with post-increment operators
52715207
return postFix * sin((t * d - s) * (2 * M_PI) / p) * 0.5 + c + b;
52725208
}
5209+
52735210
else if (easingType == "bounceIn") {
5274-
return c - getEasedT("bounceOut", d - t, 0, c, d) + b;
5211+
return c - getEasedTime("bounceOut", d - t, 0, c, d) + b;
52755212
}
52765213
else if (easingType == "bounceOut") {
52775214
if ((t /= d) < (1 / 2.75)) {
@@ -5292,65 +5229,30 @@ double getEasedT(const std::string& easingType, double t, double b, double c, do
52925229
}
52935230
else if (easingType == "bounceInOut") {
52945231
if (t < d / 2) {
5295-
return getEasedT("bounceIn", t * 2, 0, c, d) * 0.5 + b;
5232+
return getEasedTime("bounceIn", t * 2, 0, c, d) * 0.5 + b;
52965233
}
52975234
else {
5298-
return getEasedT("bounceOut", t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;
5299-
}
5300-
}
5301-
if (easingType.substr(0, 6) == "bezier") {
5302-
std::vector < double > bezierParams = parseBezier(easingType.substr(7));
5303-
if (bezierParams.size() == 4) {
5304-
return cubicBezier(t / d, bezierParams[0], bezierParams[1], bezierParams[2], bezierParams[3]);
5235+
return getEasedTime("bounceOut", t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;
53055236
}
53065237
}
53075238

5308-
return c * t / d + b; // Default to linear easing if the easing type is not recognized
5309-
}
5310-
5311-
std::vector<double> interpolate(double start, double end, double duration, const std::string& easingTypeAtStart, const std::string& easingTypeAtEnd) {
5312-
std::vector<double> interpolatedValues;
5313-
interpolatedValues.push_back(start);
5239+
if (easingType.substr(0, 6) == "bezier") {
5240+
std::vector<double> bezierParams;
53145241

5315-
// Calculate the number of steps based on the duration
5316-
int numSteps = static_cast<int>(duration); // Convert duration to an integer
5317-
double stepSize = 1.0 / numSteps;
5242+
size_t startPos = easingType.find("(") + 1;
5243+
size_t endPos = easingType.find(")");
5244+
std::string valuesString = easingType.substr(startPos, endPos - startPos);
53185245

5319-
// Calculate the halfway point
5320-
double halfway = start + (end - start) * 0.5;
5246+
std::istringstream iss(valuesString);
5247+
double value;
53215248

5322-
if (easingTypeAtEnd == "null") {
5323-
// Use easingTypeAtStart for the entire animation
5324-
for (int step = 1; step <= numSteps; ++step) {
5325-
double t = step * stepSize;
5326-
double easedT = getEasedT(easingTypeAtStart, t, 0, 1, 1); // Call getEasedT with appropriate parameters
5327-
double interpolatedValue = start + easedT * (end - start);
5328-
interpolatedValues.push_back(interpolatedValue);
5329-
}
5330-
}
5331-
else {
5332-
// Generate the first half of the interpolation
5333-
for (int step = 1; step <= numSteps / 2; ++step) {
5334-
double t = step * stepSize;
5335-
double normalizedT = t / 0.5; // Normalize the time for the first half
5336-
double easedT = getEasedT(easingTypeAtStart, normalizedT, 0, 1, 1); // Call getEasedT with appropriate parameters
5337-
double interpolatedValue = start + easedT * (halfway - start);
5338-
interpolatedValues.push_back(interpolatedValue);
5339-
}
5249+
while (iss >> value) bezierParams.push_back(value), iss.ignore();
53405250

5341-
// Generate the second half of the interpolation
5342-
for (int step = numSteps / 2 + 1; step <= numSteps; ++step) {
5343-
double t = step * stepSize;
5344-
double normalizedT = (t - 0.5) / 0.5; // Normalize the time for the second half
5345-
double easedT = getEasedT(easingTypeAtEnd, normalizedT, 0, 1, 1); // Call getEasedT with appropriate parameters
5346-
double interpolatedValue = halfway + easedT * (end - halfway);
5347-
interpolatedValues.push_back(interpolatedValue);
5348-
}
5251+
if (bezierParams.size() == 4)
5252+
return cubicBezier(t, bezierParams[0], bezierParams[1], bezierParams[2], bezierParams[3]);
53495253
}
53505254

5351-
interpolatedValues.push_back(end);
5352-
5353-
return interpolatedValues;
5255+
return c * t / d + b; // Default to linear easing if the easing type is not recognized
53545256
}
53555257

53565258
bool Game_Interpreter::CommandEasyRpgAnimateVariable(lcf::rpg::EventCommand const& com) {
@@ -5361,42 +5263,67 @@ bool Game_Interpreter::CommandEasyRpgAnimateVariable(lcf::rpg::EventCommand cons
53615263
int32_t end = ValueOrVariable(com.parameters[4], com.parameters[5]);
53625264
int32_t duration = ValueOrVariable(com.parameters[6], com.parameters[7]);
53635265

5266+
// Extract easing information
5267+
std::string easingTypeAtStart = ToString(com.string);
5268+
std::string easingTypeAtEnd = "null";
5269+
5270+
std::size_t pos = easingTypeAtStart.find('/');
5271+
5272+
if (pos != std::string::npos) {
5273+
easingTypeAtEnd = easingTypeAtStart.substr(pos + 1);
5274+
easingTypeAtStart = easingTypeAtStart.substr(0, pos);
5275+
}
5276+
53645277
// Prepare animation-related commands
53655278
lcf::rpg::EventCommand waitCom;
53665279
waitCom.code = int(Cmd::Wait);
53675280

53685281
lcf::rpg::EventCommand animatedCom;
53695282
animatedCom.code = int(Cmd::ControlVars);
53705283
std::vector<int32_t> animatedVarParams = { 0, static_cast<int32_t>(target), 0, 0, 0, static_cast<int32_t>(end) };
5371-
animatedCom.parameters = lcf::DBArray<int32_t>(animatedVarParams.begin(), animatedVarParams.end());
53725284

53735285
std::vector<lcf::rpg::EventCommand> cmdList;
53745286

5375-
// Extract easing information
5376-
std::string easeStart = ToString(com.string);
5377-
std::string easeEnd = "null";
5287+
int numSteps = static_cast<int>(duration);
5288+
double stepSize = 1.0 / numSteps;
53785289

5379-
std::size_t pos = easeStart.find('/');
5290+
for (int step = 1; step <= numSteps; ++step) {
5291+
double normalizedTime;
5292+
double currentTime = step * stepSize;
5293+
double halfway;
53805294

5381-
if (pos != std::string::npos) {
5382-
easeEnd = easeStart.substr(pos + 1);
5383-
easeStart = easeStart.substr(0, pos);
5384-
}
5295+
std::string easingType;
5296+
5297+
if (easingTypeAtEnd == "null") { // use a single interpolation.
5298+
normalizedTime = currentTime;
5299+
easingType = easingTypeAtStart;
5300+
halfway = (step <= numSteps / 2) ? end : start;
5301+
}
5302+
else {
5303+
if (step <= numSteps / 2) { // use 2 interpolations: start and end.
5304+
normalizedTime = currentTime / 0.5;
5305+
easingType = easingTypeAtStart;
5306+
}
5307+
else {
5308+
normalizedTime = (currentTime - 0.5) / 0.5;
5309+
easingType = easingTypeAtEnd;
5310+
}
5311+
halfway = start + 0.5 * (end - start);
5312+
}
5313+
5314+
double easedTime = getEasedTime(easingType, normalizedTime, 0, 1, 1);
53855315

5386-
// Insert animation commands
5387-
std::vector<double> interpolatedValues = interpolate(start, end, duration, easeStart, easeEnd);
5316+
double startValue = (step <= numSteps / 2) ? start : halfway;
5317+
double endValue = (step <= numSteps / 2) ? halfway : end;
5318+
double interpolatedValue = startValue + easedTime * (endValue - startValue);
53885319

5389-
// Insert animatedCom and waitCom commands for each interpolated value
5390-
for (int value : interpolatedValues) {
5391-
animatedVarParams.back() = value;
5320+
animatedVarParams.back() = interpolatedValue;
53925321
animatedCom.parameters = lcf::DBArray<int32_t>(animatedVarParams.begin(), animatedVarParams.end());
5393-
animatedCom.indent = com.indent + 1;
53945322

53955323
cmdList.push_back(animatedCom);
53965324
cmdList.push_back(waitCom);
53975325
}
53985326

5399-
// Update current_command index and return true to indicate success
54005327
Push(cmdList, 0, false);
54015328
return true;
54025329
}

0 commit comments

Comments
 (0)