I guess one of the first things to address is abstracting functionality. As is commonplace with C coders who later pick up C++, de Vries creates run-on functions incorporating copious functionality all within the same scope, with not a lot of focus on either code-reasoning, composability or maintenance. (Not that's he's all that bad at it actually, at the least he does break some code out into separated functions. Heh, I've seen C software that literally has the entire program--thousands of lines--all inside main()!.) I'm not really sure why C devs tend to do this, since sub-routines were a thing literally at the very beginning of computer science (eg, Edsac), and sub-functions were stressed all the way back in Algol60, as well as K&R.
So the very first order of business seems to me to be breaking down a very simple interface to the entire system inside the program's entry point. This is a general approach I follow that makes code not only simpler to compose (possibly in new ways), but also far easier to reason about in general.
Basically 3 simple sections are used here: prelims, game-loop, and cleanup.
>mrs_main.cpp
int main()
{
const unsigned w{1024}, h{576};
mrs::init_win(w, h, "Muh Robowaifu Simulator");
mrs::init_scene();
cout << "Begin game loop..." << std::endl;
const auto start_time{glfwGetTime()};
while (!glfwWindowShouldClose(mwin)) {
glfwPollEvents();
if (pause::paused)
mrs::do_pause();
else {
mrs::time_n_draw();
glfwSwapBuffers(mwin);
}
}
const auto end_time{glfwGetTime()};
cout << "Clean exit from game loop\n";
mrs::clean_up();
mrs::prt_frm_stats(start_time, end_time);
}