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

Don't re-draw credits scroll background every frame

While I was working on my over-30-FPS patch, I found out that the tower
background in the credits scroll was being completely re-drawn every
single frame, which was a bit wasteful and expensive. It's also harder
to interpolate for my over-30-FPS patch. I'm guessing this constant
re-draw was done because the math to get the surface scroll properly
working is a bit subtle, but I've figured the precise math out!

The first changes of this patch is just removing the unconditional
`map.tdrawback = true;`, and having to set `map.scrolldir` everywhere to
get the credits scrolling in the right direction but make sure the title
screen doesn't start scrolling like a descending tower, too.

After that, the first problem is that it looks like the ACTION press to
speed up the credits scrolling doesn't speed up the background, too. No
problem, just shove a `!game.press_action` check in
`gamecompletelogic()`.

However, this introduces a mini-problem, which is that NOW when you hold
down ACTION, the background appears to be slowly getting out of sync
with the credits text by a one-pixel-per-second difference. This is
actually due to the fact that, as a result of me adding the conditional,
`map.bscroll` is no longer always unconditionally getting set to 1,
while `game.creditposition` IS always unconditionally getting
decremented by 1. And when you hold down ACTION, `game.creditposition`
gets decremented by 6.

Thus, I need to set `map.bscroll` when holding down ACTION to be 7,
which is 6 plus 1.

Then we have another problem, which is that the incoming textures desync
when you press ACTION, and when you release ACTION. They desync by
precisely 6 pixels, which should be a familiar number. I (eventually)
tracked this down to `map.bypos` being updated at the same time
`map.bscroll` is, even though `map.bypos` should be updated a frame
later AFTER updating `map.bscroll`.

So I had to change the `map.bypos` update in `gamecompleteinput()` and
`gamecompletelogic()` to be `map.bypos += map.bscroll;` and then place
it before any `map.bscroll` update, thus ensuring that `map.bscroll`
updates exactly one frame before `map.ypos` does. I had to move the
`map.bypos += map.bscroll;` to be in `gamecompleteinput()`, because
`gamecompleteinput()` comes first before `gamecompletelogic()` in the
`main.cpp` game loop, otherwise the `map.bypos` update won't be delayed
by one frame for when you press ACTION to make it go faster, and thus
cause a desync when you press ACTION.

Oh and then after that, I had to make the descending tower background
draw a THIRD row of incoming tiles, otherwise you could see some black
flickering at the bottom of the screen when you held down ACTION.

All of this took me way too long to figure out, but now the credits
scroll works perfectly while being more optimized.
This commit is contained in:
Misa 2020-04-29 20:52:33 -07:00 committed by Ethan Lee
parent 1fd20e5e99
commit 192b2f2dba
3 changed files with 10 additions and 6 deletions

View file

@ -2244,6 +2244,8 @@ void Graphics::drawtowerbackground()
drawtowertile3(i * 8, 29*8 - (map.bypos % 8) - map.bscroll, temp, map.colstate);
temp = map.tower.backat(i, 30, map.bypos);
drawtowertile3(i * 8, 30*8 - (map.bypos % 8) - map.bscroll, temp, map.colstate);
temp = map.tower.backat(i, 31, map.bypos);
drawtowertile3(i * 8, 31*8 - (map.bypos % 8) - map.bscroll, temp, map.colstate);
}
}

View file

@ -2118,6 +2118,9 @@ void gamecompleteinput()
game.press_action = false;
game.press_map = false;
//Do this here because input comes first
map.bypos += map.bscroll;
if (key.isDown(KEYBOARD_z) || key.isDown(KEYBOARD_SPACE) || key.isDown(KEYBOARD_v) || key.isDown(game.controllerButton_flip))
{
game.creditposition -= 6;
@ -2131,8 +2134,7 @@ void gamecompleteinput()
}
else
{
map.bypos += 6;
map.bscroll = +6;
map.bscroll = +7;
}
game.press_action = true;
}

View file

@ -48,8 +48,7 @@ void gamecompletelogic()
map.updatetowerglow();
help.updateglow();
graphics.crewframe = 0;
map.tdrawback = true;
map.scrolldir = 1;
game.creditposition--;
if (game.creditposition <= -game.creditmaxposition)
@ -57,9 +56,8 @@ void gamecompletelogic()
game.creditposition = -game.creditmaxposition;
map.bscroll = 0;
}
else
else if (!game.press_action)
{
map.bypos += 1;
map.bscroll = +1;
}
@ -68,6 +66,8 @@ void gamecompletelogic()
//Fix some graphical things
graphics.showcutscenebars = false;
graphics.cutscenebarspos = 0;
map.scrolldir = 0;
map.bypos = 0;
//Return to game
game.gamestate = GAMECOMPLETE2;
graphics.fademode = 4;