From 192b2f2dba06a3a9d9a1f12095e001a97e0c730f Mon Sep 17 00:00:00 2001 From: Misa Date: Wed, 29 Apr 2020 20:52:33 -0700 Subject: [PATCH] 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. --- desktop_version/src/Graphics.cpp | 2 ++ desktop_version/src/Input.cpp | 6 ++++-- desktop_version/src/Logic.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/desktop_version/src/Graphics.cpp b/desktop_version/src/Graphics.cpp index f33fc231..14116b39 100644 --- a/desktop_version/src/Graphics.cpp +++ b/desktop_version/src/Graphics.cpp @@ -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); } } diff --git a/desktop_version/src/Input.cpp b/desktop_version/src/Input.cpp index e49d75e5..02f5dbd7 100644 --- a/desktop_version/src/Input.cpp +++ b/desktop_version/src/Input.cpp @@ -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; } diff --git a/desktop_version/src/Logic.cpp b/desktop_version/src/Logic.cpp index e87d291a..de9fe1cb 100644 --- a/desktop_version/src/Logic.cpp +++ b/desktop_version/src/Logic.cpp @@ -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;