1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-23 01:59:43 +01:00

Fix the two-frame-delay when entering a room with an "init" script

This patch is very kludge-y, but at least it fixes a semi-noticeable
visual issue in custom levels that use internal scripts to spawn
entities when loading a room.

Basically, the problem here is that when the game checks for script
boxes and sets newscript, newscript has already been processed for that
frame, and when the game does load a script, script.run() has already
been processed for that frame.

That issue can be fixed, but it turns out that due to my over-30-FPS
game loop changes, there's now ANOTHER visible frame of delay between
room load and entity creation, because the render function gets called
in between the script being loaded at the end of gamelogic() and the
script actually getting run.

So... I have to temporary move script.run() to the end of gamelogic()
(in map.twoframedelayfix()), and make sure it doesn't get run next
frame, because double-evaluations are bad. To do that, I have to
introduce the kludge variable script.dontrunnextframe, which does
exactly as it says.

And with all that work, the two-frame (now three-frame) delay is fixed.
This commit is contained in:
Misa 2020-06-27 17:08:57 -07:00 committed by Ethan Lee
parent baf879d9fd
commit ebd381c228
8 changed files with 52 additions and 2 deletions

View file

@ -4780,6 +4780,7 @@ void entityclass::entitycollisioncheck()
}
}
// WARNING: If updating this code, don't forget to update Map.cpp mapclass::twoframedelayfix()
activetrigger = -1;
if (checktrigger() > -1)
{

View file

@ -1753,6 +1753,7 @@ void Game::updatestate()
break;
// WARNING: If updating this code, make sure to update Map.cpp mapclass::twoframedelayfix()
case 300:
startscript = true;
newscript="custom_"+customscript[0];

View file

@ -1117,6 +1117,8 @@ void gamelogic()
}
}
bool screen_transition = false;
if (!map.warpy && !map.towermode)
{
//Normal! Just change room
@ -1125,11 +1127,13 @@ void gamelogic()
{
obj.entities[player].yp -= 240;
map.gotoroom(game.roomx, game.roomy + 1);
screen_transition = true;
}
if (player > -1 && game.door_up > -2 && obj.entities[player].yp < -2)
{
obj.entities[player].yp += 240;
map.gotoroom(game.roomx, game.roomy - 1);
screen_transition = true;
}
}
@ -1141,11 +1145,13 @@ void gamelogic()
{
obj.entities[player].xp += 320;
map.gotoroom(game.roomx - 1, game.roomy);
screen_transition = true;
}
if (player > -1 && game.door_right > -2 && obj.entities[player].xp >= 308)
{
obj.entities[player].xp -= 320;
map.gotoroom(game.roomx + 1, game.roomy);
screen_transition = true;
}
}
@ -1364,6 +1370,11 @@ void gamelogic()
}
}
}
if (screen_transition)
{
map.twoframedelayfix();
}
}
//Update colour cycling for final level

View file

@ -1980,3 +1980,30 @@ void mapclass::loadlevel(int rx, int ry)
}
}
}
void mapclass::twoframedelayfix()
{
// Fixes the two-frame delay in custom levels that use scripts to spawn an entity upon room load.
// Because when the room loads and newscript is set to run, newscript has already ran for that frame,
// and when the script gets loaded script.run() has already ran for that frame, too.
// A bit kludge-y, but it's the least we can do without changing the frame ordering.
if (game.deathseq != -1
// obj.checktrigger() sets obj.activetrigger
|| obj.checktrigger() <= -1
|| obj.activetrigger < 300)
{
return;
}
game.newscript = "custom_" + game.customscript[obj.activetrigger - 300];
obj.removetrigger(obj.activetrigger);
game.state = 0;
game.statedelay = 0;
script.load(game.newscript);
if (script.running)
{
script.run();
script.dontrunnextframe = true;
}
}

View file

@ -75,6 +75,8 @@ public:
void loadlevel(int rx, int ry);
void twoframedelayfix();
std::vector <int> roomdeaths;
std::vector <int> roomdeathsfinal;

View file

@ -16,6 +16,7 @@ scriptclass::scriptclass()
position = 0;
scriptdelay = 0;
running = false;
dontrunnextframe = false;
b = 0;
g = 0;

View file

@ -56,7 +56,7 @@ public:
int looppoint, loopcount;
int scriptdelay;
bool running;
bool running, dontrunnextframe;
std::string tempword;
std::string currentletter;

View file

@ -542,7 +542,14 @@ void inline fixedloop()
titlelogic();
break;
case GAMEMODE:
if (script.running)
// WARNING: If updating this code, don't forget to update Map.cpp mapclass::twoframedelayfix()
// Ugh, I hate this kludge variable but it's the only way to do it
if (script.dontrunnextframe)
{
script.dontrunnextframe = false;
}
else if (script.running)
{
script.run();
}