2020-01-01 21:29:24 +01:00
|
|
|
#ifndef GAME_H
|
|
|
|
#define GAME_H
|
|
|
|
|
2020-07-19 06:21:27 +02:00
|
|
|
#include <SDL.h>
|
2023-10-25 04:05:23 +02:00
|
|
|
#include <map>
|
2020-07-19 21:43:29 +02:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2024-01-03 22:54:20 +01:00
|
|
|
#include "Font.h"
|
2020-11-13 01:45:51 +01:00
|
|
|
#include "ScreenSettings.h"
|
|
|
|
|
2021-12-18 08:57:55 +01:00
|
|
|
/* FIXME: Can't forward declare this enum in C++, unfortunately.
|
|
|
|
* In C, enum sizes are always the same, so you can forward declare them.
|
|
|
|
* In C++ instead, enum sizes are based on how many enums there are.
|
|
|
|
* You cannot specify the underlying type until C++11.
|
|
|
|
* But bumping the standard opens up a can of worms. I'd rather just move to C. -Misa */
|
|
|
|
#include "Enums.h"
|
|
|
|
|
2020-09-14 01:31:02 +02:00
|
|
|
// Forward decl without including all of <tinyxml2.h>
|
Move all settings to settings.vvv
The game previously did this dumb thing where it lumped in all its
settings with its file that tracked your records and unlocks,
`unlock.vvv`. It wasn't really an issue, until 2.3 came along and added
a few settings, suddenly making a problem where 2.3 settings would be
reset by chance if you decided to touch 2.2.
The solution to this is to move all settings to a new file,
`settings.vvv`. However, for compatibility with 2.2, settings will still
be written to `unlock.vvv`.
The game will prioritize reading from `settings.vvv` instead of
`unlock.vvv`, so if there's a setting that's missing from `unlock.vvv`,
no worries there. But if `settings.vvv` is missing, then it'll read
settings from `unlock.vvv`. As well, if `unlock.vvv` is missing, then
`settings.vvv` will be read from instead (I explicitly tested for this,
and found that I had to write special code to handle this case,
otherwise the game would overwrite the existing `settings.vvv` before
reading from it; kids, make sure to always test your code!).
Closes #373 fully.
2020-11-04 08:11:21 +01:00
|
|
|
namespace tinyxml2
|
|
|
|
{
|
|
|
|
class XMLDocument;
|
|
|
|
class XMLElement;
|
|
|
|
}
|
2020-09-14 01:31:02 +02:00
|
|
|
|
2021-03-07 03:14:44 +01:00
|
|
|
/* 40 chars (160 bytes) covers the entire screen, + 1 more for null terminator */
|
|
|
|
#define MENU_TEXT_BYTES 161
|
|
|
|
|
2020-04-15 06:11:10 +02:00
|
|
|
struct MenuOption
|
|
|
|
{
|
2021-03-07 03:14:44 +01:00
|
|
|
char text[MENU_TEXT_BYTES];
|
2020-04-15 06:11:10 +02:00
|
|
|
bool active;
|
2023-01-15 04:06:31 +01:00
|
|
|
uint32_t print_flags;
|
2020-04-15 06:11:10 +02:00
|
|
|
};
|
|
|
|
|
2020-04-16 06:53:36 +02:00
|
|
|
//Menu IDs
|
|
|
|
namespace Menu
|
|
|
|
{
|
|
|
|
enum MenuName
|
|
|
|
{
|
|
|
|
mainmenu,
|
|
|
|
playerworlds,
|
2021-12-22 09:58:27 +01:00
|
|
|
confirmshowlevelspath,
|
|
|
|
showlevelspath,
|
2020-04-16 06:53:36 +02:00
|
|
|
levellist,
|
|
|
|
quickloadlevel,
|
2021-08-12 05:26:58 +02:00
|
|
|
deletequicklevel,
|
2020-04-16 06:53:36 +02:00
|
|
|
youwannaquit,
|
|
|
|
errornostart,
|
2020-11-22 03:10:26 +01:00
|
|
|
errorsavingsettings,
|
2021-08-07 05:57:34 +02:00
|
|
|
errorloadinglevel,
|
2021-08-07 07:26:48 +02:00
|
|
|
warninglevellist,
|
2020-04-16 06:53:36 +02:00
|
|
|
graphicoptions,
|
|
|
|
ed_settings,
|
|
|
|
ed_desc,
|
|
|
|
ed_music,
|
|
|
|
ed_quit,
|
2023-01-21 19:06:30 +01:00
|
|
|
ed_font,
|
2020-04-16 06:53:36 +02:00
|
|
|
options,
|
2021-04-09 17:53:55 +02:00
|
|
|
gameplayoptions,
|
|
|
|
speedrunneroptions,
|
Split glitchrunner mode into multiple versions
Previously, turning glitchrunner mode on essentially locked you to
emulating 2.0, and turning it off just meant normal 2.3 behavior. But
what if you wanted 2.2 behavior instead? Well, that's what I had to ask
when a TAS of mine would desync in 2.3 because of the two-frame delay
fix (glitchrunner off), but would also desync because of 2.0 warp lines
(glitchrunner on).
What I've done is made it so there are three states to glitchrunner mode
now: 2.0 (previously just the "on" state), 2.2 (previously a state you
couldn't use), and "off". Furthermore, I made it an enum, so in case
future versions of the game patch out more glitches, we can add them to
the enum (and the only other thing we have to update is a lookup table
in GlitchrunnerMode.c). Also, 2.2 glitches exist in 2.0, so you'll want
to use GlitchrunnerMode_less_than_or_equal() to check glitchrunner
version.
2021-08-05 02:09:49 +02:00
|
|
|
setglitchrunner,
|
2020-06-30 22:06:19 +02:00
|
|
|
advancedoptions,
|
2021-04-12 00:18:35 +02:00
|
|
|
audiooptions,
|
2020-04-16 06:53:36 +02:00
|
|
|
accessibility,
|
|
|
|
controller,
|
2022-12-30 22:57:24 +01:00
|
|
|
language,
|
|
|
|
translator_main,
|
|
|
|
translator_options,
|
|
|
|
translator_options_limitscheck,
|
|
|
|
translator_options_stats,
|
Add level exploring menu for translators
I would, of course, recommend translators to translate the roomnames
while playing the full game (optionally in invincibility) so they can
immediately get all the context and maybe the most inspiration. And if
you want to go back into a specific level, then there's always the time
trials and intermission replays which will give you full coverage of
all the room names.
However, the time trials weren't really made for room name translation.
They have some annoying features like the instant restart when you
press ENTER at the wrong time, they remove context clues like
teleporters and companions, but the worst problem is that the last room
in a level is often completely untranslatable inside the time trials
because you immediately get sent to the results screen...
So, I added a new menu in the translator options, "explore game", which
gives you access to all the time trials and the two intermissions, from
the same menu. All these time trials (which they're still based off of,
under the hood) are stripped of the annoying features that come with
time trials. These are the changes I made to time trial behavior in
translator exploring mode:
- No 3-2-1-Go! countdown
- No on-screen time/death/shiny/par
- ENTER doesn't restart, and the map menu works. The entire map is also
revealed.
- Prize for the Reckless is in its normal form
- The teleporters in Entanglement Generator, Wheeler's Wormhole and
Level Complete are restored as context for room names (actually, we
should probably restore them in time trials anyway? Their "press to
teleport" prompt is already blocked out in time trials and they do
nothing other than being a checkpoint. I guess the reason they were
removed was to stop people from opening the teleporter menu when that
was not specifically blocked out in time trials yet.)
- The companions are there at the end of levels, and behave like in no
death mode (become happy and follow you to the teleporter). Also for
context.
- At the end of each level, you're not suddenly sent to the menu, but
you can use the teleporter at your leisure just like in the
intermission replays. In the Final Level, you do get sent to the menu
automatically, but after a longer delay.
I made another mark on VVVVVV: don't be startled, I added gamestates.
I wanted all teleporters at the end of levels to behave like the ones
at the end of the intermission replays, and all handling for
teleporting with specific companions is already done in gamestates, so
rather than adding conditional blocks across 5 or so different
gamestates, it made more sense to make a single gamestate for
"teleporting in translator exploring mode" (3090). I also added an
alternative to having to use gamestate 3500 or 82 for the end of the
final level: 3091-3092.
One other thing I want to add to the "explore game" menu: a per-level
count of how many room names are left to translate. That shouldn't be
too difficult, and I'm planning that for the next commit.
2022-11-26 03:33:17 +01:00
|
|
|
translator_options_exploregame,
|
2022-12-24 04:16:56 +01:00
|
|
|
translator_options_cutscenetest,
|
2022-12-30 22:57:24 +01:00
|
|
|
translator_maintenance,
|
|
|
|
translator_maintenance_sync,
|
|
|
|
translator_error_setlangwritedir,
|
2020-04-16 06:53:36 +02:00
|
|
|
cleardatamenu,
|
2021-08-12 05:54:02 +02:00
|
|
|
clearcustomdatamenu,
|
2020-04-16 06:53:36 +02:00
|
|
|
setinvincibility,
|
2020-04-17 01:02:01 +02:00
|
|
|
setslowdown,
|
2020-04-16 06:53:36 +02:00
|
|
|
unlockmenu,
|
|
|
|
credits,
|
|
|
|
credits2,
|
|
|
|
credits25,
|
|
|
|
credits3,
|
|
|
|
credits4,
|
|
|
|
credits5,
|
|
|
|
credits6,
|
2023-12-06 00:34:05 +01:00
|
|
|
credits_localisations_implementation,
|
|
|
|
credits_localisations_translations,
|
2020-04-16 06:53:36 +02:00
|
|
|
play,
|
|
|
|
unlocktimetrial,
|
|
|
|
unlocktimetrials,
|
|
|
|
unlocknodeathmode,
|
|
|
|
unlockintermission,
|
|
|
|
unlockflipmode,
|
|
|
|
newgamewarning,
|
|
|
|
playmodes,
|
|
|
|
intermissionmenu,
|
|
|
|
playint1,
|
|
|
|
playint2,
|
|
|
|
continuemenu,
|
|
|
|
startnodeathmode,
|
|
|
|
gameover,
|
|
|
|
gameover2,
|
|
|
|
unlockmenutrials,
|
|
|
|
timetrials,
|
|
|
|
nodeathmodecomplete,
|
|
|
|
nodeathmodecomplete2,
|
|
|
|
timetrialcomplete,
|
|
|
|
timetrialcomplete2,
|
|
|
|
timetrialcomplete3,
|
2021-04-11 01:59:05 +02:00
|
|
|
gamecompletecontinue
|
2020-04-16 06:53:36 +02:00
|
|
|
};
|
2021-04-11 01:59:05 +02:00
|
|
|
}
|
2020-04-16 06:53:36 +02:00
|
|
|
|
2021-04-12 02:43:17 +02:00
|
|
|
enum SLIDERMODE
|
|
|
|
{
|
|
|
|
SLIDER_NONE,
|
|
|
|
SLIDER_MUSICVOLUME,
|
|
|
|
SLIDER_SOUNDVOLUME
|
|
|
|
};
|
|
|
|
|
2023-06-05 08:24:31 +02:00
|
|
|
/* enums for swngame variable */
|
|
|
|
enum SWNMODE
|
|
|
|
{
|
|
|
|
SWN_GRAVITRON,
|
|
|
|
SWN_SUPERGRAVITRON,
|
|
|
|
SWN_START_GRAVITRON_STEP_3,
|
|
|
|
SWN_START_GRAVITRON_STEP_2,
|
|
|
|
SWN_START_GRAVITRON_STEP_1,
|
|
|
|
SWN_FINISH_GRAVITRON_STEP_1,
|
|
|
|
SWN_START_SUPERGRAVITRON_STEP_1,
|
|
|
|
SWN_START_SUPERGRAVITRON_STEP_2,
|
|
|
|
SWN_FINISH_GRAVITRON_STEP_2,
|
|
|
|
SWN_NONE
|
|
|
|
};
|
|
|
|
|
2023-06-06 02:34:27 +02:00
|
|
|
/* enums for unlock, unlocknotify arrays and unlocknum function */
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
Unlock_SPACESTATION1_COMPLETE = 0,
|
|
|
|
Unlock_LABORATORY_COMPLETE = 1,
|
|
|
|
Unlock_TOWER_COMPLETE = 2,
|
|
|
|
Unlock_SPACESTATION2_COMPLETE = 3,
|
|
|
|
Unlock_WARPZONE_COMPLETE = 4,
|
|
|
|
UnlockTrophy_GAME_COMPLETE = 5,
|
|
|
|
Unlock_INTERMISSION1_COMPLETE = 6,
|
|
|
|
Unlock_INTERMISSION2_COMPLETE = 7,
|
|
|
|
Unlock_SECRETLAB = 8,
|
|
|
|
Unlock_TIMETRIAL_SPACESTATION1 = 9,
|
|
|
|
Unlock_TIMETRIAL_LABORATORY = 10,
|
|
|
|
Unlock_TIMETRIAL_TOWER = 11,
|
|
|
|
Unlock_TIMETRIAL_SPACESTATION2 = 12,
|
|
|
|
Unlock_TIMETRIAL_WARPZONE = 13,
|
|
|
|
Unlock_TIMETRIAL_FINALLEVEL = 14,
|
|
|
|
Unlock_INTERMISSION_UNUSED = 15,
|
|
|
|
Unlock_INTERMISSION_REPLAYS = 16,
|
|
|
|
Unlock_NODEATHMODE = 17,
|
|
|
|
Unlock_FLIPMODE = 18,
|
|
|
|
UnlockTrophy_FLIPMODE_COMPLETE = 19,
|
|
|
|
UnlockTrophy_NODEATHMODE_COMPLETE = 20
|
|
|
|
};
|
|
|
|
|
2023-06-06 02:50:19 +02:00
|
|
|
/* enums for bestrank, bestlives, besttrinkets, besttimes, bestframes arrays
|
|
|
|
* and timetriallevel */
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
TimeTrial_SPACESTATION1 = 0,
|
|
|
|
TimeTrial_LABORATORY = 1,
|
|
|
|
TimeTrial_TOWER = 2,
|
|
|
|
TimeTrial_SPACESTATION2 = 3,
|
|
|
|
TimeTrial_WARPZONE = 4,
|
|
|
|
TimeTrial_FINALLEVEL = 5
|
|
|
|
};
|
|
|
|
|
2020-04-17 01:22:40 +02:00
|
|
|
struct MenuStackFrame
|
|
|
|
{
|
|
|
|
int option;
|
|
|
|
enum Menu::MenuName name;
|
|
|
|
};
|
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
class Game
|
|
|
|
{
|
2023-02-21 21:09:43 +01:00
|
|
|
char magic[16];
|
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
public:
|
Allow using help/graphics/music/game/key/map/obj everywhere
This commit makes `help`, `graphics`, `music`, `game`, `key`, `map`, and
`obj` essentially static global objects that can be used everywhere.
This is useful in case we ever need to add a new function in the future,
so we don't have to bother with passing a new argument in which means we
have to pass a new argument in to the function that calls that function
which means having to pass a new argument into the function that calls
THAT function, etc. which is a real headache when working on fan mods of
the source code.
Note that this changes NONE of the existing function signatures, it
merely just makes those variables accessible everywhere in the same way
`script` and `ed` are.
Also note that some classes had to be initialized after the filesystem
was initialized, but C++ would keep initializing them before the
filesystem got initialized, because I *had* to put them at the top of
`main.cpp`, or else they wouldn't be global variables.
The only way to work around this was to use entityclass's initialization
style (which I'm pretty sure entityclass of all things doesn't need to
be initialized this way), where you actually initialize the class in an
`init()` function, and so then you do `graphics.init()` after the
filesystem initialization, AFTER doing `Graphics graphics` up at the
top.
I've had to do this for `graphics` (but only because its child
GraphicsResources `grphx` needs to be initialized this way), `music`,
and `game`. I don't think this will affect anything. Other than that,
`help`, `key`, and `map` are still using the C++-intended method of
having ClassName::ClassName() functions.
2020-01-29 08:35:03 +01:00
|
|
|
void init(void);
|
Fix regression with controller binds on first launch
I noticed that in 2.3, the game would launch with default controller
binds upon first launch (e.g. no pre-existing unlock.vvv or
settings.vvv), but in 2.4, this wasn't the case, and the default binds
would only be set the next time the game was launched. This would result
in you being essentially unable to use the controller on first launch
save for the analogue stick and D-pad to move between menu selections
and move the player.
Bisecting pointed to commit 3ef5248db93541f399e8220fe0280281881d8bd6 as
the cause of the regression. It turns out returning early upon error or
a file not existing didn't set the default controller binds, because
they were done at the end of Game::deserializesettings(). But the binds
would be set on the next launch because if the file didn't exist, a new
file would be written, not with the default binds, but then the next
launch would read the file, see there were no binds, and then set the
default binds accordingly.
To fix this, I made it so that the default controller binds are set when
Game is initialized. That way, it covers all cases where the game can't
read a settings file.
2023-04-15 20:14:35 +02:00
|
|
|
void setdefaultcontrollerbuttons(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
int crewrescued(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
std::string unrescued(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void resetgameclock(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 00:41:49 +02:00
|
|
|
bool customsavequick(const std::string& savfile);
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
bool savequick(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void gameclock(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-03-31 02:16:02 +02:00
|
|
|
std::string giventimestring(int hrs, int min, int sec);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
std::string timestring(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
std::string resulttimestring(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-03-31 02:16:02 +02:00
|
|
|
std::string timetstring(int t);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-12-21 02:32:12 +01:00
|
|
|
void timestringcenti(char* buffer, size_t buffer_size);
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void returnmenu(void);
|
2020-04-26 02:36:36 +02:00
|
|
|
void returntomenu(enum Menu::MenuName t);
|
2020-04-17 04:04:36 +02:00
|
|
|
void createmenu(enum Menu::MenuName t, bool samemenu = false);
|
Fix delayed notification of NDM unlock
No Death Mode is intended to be unlocked by getting at least S-rank in
at least 4 time trials. Before 2.3, completing a time trial put you at
the main menu, so you would always be notified of having unlocked No
Death Mode once you went to the play menu again. But since 2.3,
completing a time trial puts you back at the Time Trial selection
screen, which isn't the play menu, so you would need to back all the way
out first in order to get the notification. And since you don't actually
unlock No Death Mode until you see the notification, this would be
required to be able to play No Death Mode.
To fix this, I decided to do something a bit kludge-y and just re-use
the code to check and unlock No Death Mode when the player presses
ACTION on the Time Trial complete screen (and there's also another path
by pressing Escape). At least I put it in a function, so it's not a pure
copy-paste, although it might as well be. I don't have time to think of
a proper solution, but it would probably involve disentangling unlock
notifications from Menu::play, for starters. But that's for later.
2024-01-10 10:33:10 +01:00
|
|
|
bool can_unlock_ndm(void);
|
|
|
|
void unlock_ndm(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void lifesequence(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void gethardestroom(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-03-20 03:37:54 +01:00
|
|
|
void levelcomplete_textbox(void);
|
2023-08-11 02:41:39 +02:00
|
|
|
void crewmate_textbox(const int color);
|
2021-03-20 03:37:54 +01:00
|
|
|
void remaining_textbox(void);
|
|
|
|
void actionprompt_textbox(void);
|
2021-03-20 03:40:16 +01:00
|
|
|
void savetele_textbox(void);
|
2021-03-20 03:37:54 +01:00
|
|
|
|
2022-12-07 00:20:48 +01:00
|
|
|
void setstate(int gamestate);
|
|
|
|
|
2023-03-18 23:24:14 +01:00
|
|
|
void incstate(void);
|
2022-12-07 00:20:48 +01:00
|
|
|
|
2022-12-07 00:35:06 +01:00
|
|
|
void setstatedelay(int delay);
|
|
|
|
|
2023-03-18 23:24:14 +01:00
|
|
|
void lockstate(void);
|
2022-12-07 00:20:48 +01:00
|
|
|
|
2023-03-18 23:24:14 +01:00
|
|
|
void unlockstate(void);
|
2022-12-07 00:20:48 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void updatestate(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-03-31 02:16:02 +02:00
|
|
|
void unlocknum(int t);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-12-25 09:18:51 +01:00
|
|
|
void loadstats(struct ScreenSettings* screen_settings);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-12-25 09:18:51 +01:00
|
|
|
bool savestats(const struct ScreenSettings* screen_settings, bool sync = true);
|
2021-09-02 19:19:51 +02:00
|
|
|
bool savestats(bool sync = true);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void deletestats(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-12-25 09:18:51 +01:00
|
|
|
void deserializesettings(tinyxml2::XMLElement* dataNode, struct ScreenSettings* screen_settings);
|
Move all settings to settings.vvv
The game previously did this dumb thing where it lumped in all its
settings with its file that tracked your records and unlocks,
`unlock.vvv`. It wasn't really an issue, until 2.3 came along and added
a few settings, suddenly making a problem where 2.3 settings would be
reset by chance if you decided to touch 2.2.
The solution to this is to move all settings to a new file,
`settings.vvv`. However, for compatibility with 2.2, settings will still
be written to `unlock.vvv`.
The game will prioritize reading from `settings.vvv` instead of
`unlock.vvv`, so if there's a setting that's missing from `unlock.vvv`,
no worries there. But if `settings.vvv` is missing, then it'll read
settings from `unlock.vvv`. As well, if `unlock.vvv` is missing, then
`settings.vvv` will be read from instead (I explicitly tested for this,
and found that I had to write special code to handle this case,
otherwise the game would overwrite the existing `settings.vvv` before
reading from it; kids, make sure to always test your code!).
Closes #373 fully.
2020-11-04 08:11:21 +01:00
|
|
|
|
2021-12-25 09:18:51 +01:00
|
|
|
void serializesettings(tinyxml2::XMLElement* dataNode, const struct ScreenSettings* screen_settings);
|
Move all settings to settings.vvv
The game previously did this dumb thing where it lumped in all its
settings with its file that tracked your records and unlocks,
`unlock.vvv`. It wasn't really an issue, until 2.3 came along and added
a few settings, suddenly making a problem where 2.3 settings would be
reset by chance if you decided to touch 2.2.
The solution to this is to move all settings to a new file,
`settings.vvv`. However, for compatibility with 2.2, settings will still
be written to `unlock.vvv`.
The game will prioritize reading from `settings.vvv` instead of
`unlock.vvv`, so if there's a setting that's missing from `unlock.vvv`,
no worries there. But if `settings.vvv` is missing, then it'll read
settings from `unlock.vvv`. As well, if `unlock.vvv` is missing, then
`settings.vvv` will be read from instead (I explicitly tested for this,
and found that I had to write special code to handle this case,
otherwise the game would overwrite the existing `settings.vvv` before
reading from it; kids, make sure to always test your code!).
Closes #373 fully.
2020-11-04 08:11:21 +01:00
|
|
|
|
2021-12-25 09:18:51 +01:00
|
|
|
void loadsettings(struct ScreenSettings* screen_settings);
|
Move all settings to settings.vvv
The game previously did this dumb thing where it lumped in all its
settings with its file that tracked your records and unlocks,
`unlock.vvv`. It wasn't really an issue, until 2.3 came along and added
a few settings, suddenly making a problem where 2.3 settings would be
reset by chance if you decided to touch 2.2.
The solution to this is to move all settings to a new file,
`settings.vvv`. However, for compatibility with 2.2, settings will still
be written to `unlock.vvv`.
The game will prioritize reading from `settings.vvv` instead of
`unlock.vvv`, so if there's a setting that's missing from `unlock.vvv`,
no worries there. But if `settings.vvv` is missing, then it'll read
settings from `unlock.vvv`. As well, if `unlock.vvv` is missing, then
`settings.vvv` will be read from instead (I explicitly tested for this,
and found that I had to write special code to handle this case,
otherwise the game would overwrite the existing `settings.vvv` before
reading from it; kids, make sure to always test your code!).
Closes #373 fully.
2020-11-04 08:11:21 +01:00
|
|
|
|
2021-12-25 09:18:51 +01:00
|
|
|
bool savesettings(const struct ScreenSettings* screen_settings);
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
bool savesettings(void);
|
Move all settings to settings.vvv
The game previously did this dumb thing where it lumped in all its
settings with its file that tracked your records and unlocks,
`unlock.vvv`. It wasn't really an issue, until 2.3 came along and added
a few settings, suddenly making a problem where 2.3 settings would be
reset by chance if you decided to touch 2.2.
The solution to this is to move all settings to a new file,
`settings.vvv`. However, for compatibility with 2.2, settings will still
be written to `unlock.vvv`.
The game will prioritize reading from `settings.vvv` instead of
`unlock.vvv`, so if there's a setting that's missing from `unlock.vvv`,
no worries there. But if `settings.vvv` is missing, then it'll read
settings from `unlock.vvv`. As well, if `unlock.vvv` is missing, then
`settings.vvv` will be read from instead (I explicitly tested for this,
and found that I had to write special code to handle this case,
otherwise the game would overwrite the existing `settings.vvv` before
reading from it; kids, make sure to always test your code!).
Closes #373 fully.
2020-11-04 08:11:21 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
bool savestatsandsettings(void);
|
Refactor Game::savestats() to not use a default argument
In order to be able to fix the bug #556, I'm planning on adding
ScreenSettings* to the settings.vvv write function. However, that
entails adding another argument to Game::savesettings(), which is going
to be really messy given the default argument of Game::savestats().
That, combined with the fact that the code comment at the site of the
implementation of Game::savestats() being wrong (!!!), leads me to
believe that using default function arguments here isn't worth it.
Instead, what I've done is made it so callers are explicit about whether
or not they're calling savestats(), savesettings(), or both at the same
time. If they are calling both at the same time, then they will be using
a new function named savestatsandsettings().
In short, these are the interface changes:
* bool Game::savestats(bool) has been removed
* bool Game::savestatsandsettings() has been added
* void Game::savestats_menu() has been renamed to
void Game::savestatsandsettings_menu()
* All previous callers of bool Game::savestats() are now using bool
Game::savestatsandsettings()
* The one caller of bool Game::savestats(bool) is now using bool
Game::savestats()
2020-12-22 01:03:19 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void savestatsandsettings_menu(void);
|
Refactor Game::savestats() to not use a default argument
In order to be able to fix the bug #556, I'm planning on adding
ScreenSettings* to the settings.vvv write function. However, that
entails adding another argument to Game::savesettings(), which is going
to be really messy given the default argument of Game::savestats().
That, combined with the fact that the code comment at the site of the
implementation of Game::savestats() being wrong (!!!), leads me to
believe that using default function arguments here isn't worth it.
Instead, what I've done is made it so callers are explicit about whether
or not they're calling savestats(), savesettings(), or both at the same
time. If they are calling both at the same time, then they will be using
a new function named savestatsandsettings().
In short, these are the interface changes:
* bool Game::savestats(bool) has been removed
* bool Game::savestatsandsettings() has been added
* void Game::savestats_menu() has been renamed to
void Game::savestatsandsettings_menu()
* All previous callers of bool Game::savestats() are now using bool
Game::savestatsandsettings()
* The one caller of bool Game::savestats(bool) is now using bool
Game::savestats()
2020-12-22 01:03:19 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void deletesettings(void);
|
Move all settings to settings.vvv
The game previously did this dumb thing where it lumped in all its
settings with its file that tracked your records and unlocks,
`unlock.vvv`. It wasn't really an issue, until 2.3 came along and added
a few settings, suddenly making a problem where 2.3 settings would be
reset by chance if you decided to touch 2.2.
The solution to this is to move all settings to a new file,
`settings.vvv`. However, for compatibility with 2.2, settings will still
be written to `unlock.vvv`.
The game will prioritize reading from `settings.vvv` instead of
`unlock.vvv`, so if there's a setting that's missing from `unlock.vvv`,
no worries there. But if `settings.vvv` is missing, then it'll read
settings from `unlock.vvv`. As well, if `unlock.vvv` is missing, then
`settings.vvv` will be read from instead (I explicitly tested for this,
and found that I had to write special code to handle this case,
otherwise the game would overwrite the existing `settings.vvv` before
reading from it; kids, make sure to always test your code!).
Closes #373 fully.
2020-11-04 08:11:21 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void deletequick(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
bool savetele(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void loadtele(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void deletetele(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void customstart(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void start(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-03-31 02:16:02 +02:00
|
|
|
void startspecial(int t);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-03-31 02:16:02 +02:00
|
|
|
void starttrial(int t);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void swnpenalty(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void deathsequence(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-09-07 00:41:49 +02:00
|
|
|
void customloadquick(const std::string& savfile);
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void loadquick(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-08-12 05:26:58 +02:00
|
|
|
void customdeletequick(const std::string& file);
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void loadsummary(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-09-12 03:04:34 +02:00
|
|
|
static const int numcrew = 6;
|
|
|
|
|
|
|
|
struct Summary
|
|
|
|
{
|
Replace std::string Game::telesummary and Game::quicksummary by Summary
Game::telesummary and Game::quicksummary stored the summary string for
the save files - which is the <summary> tag that says something like
"Space Station, 10:30:59". The game only ever displays the quicksave
variant of these two, for "Last Save:" on the map menu's SAVE tab.
So the telesave has a <summary> too, but it's never displayed anywhere.
(In fact, the area is often set to "nowhere"...)
However, the summary strings have another function: detect that both
the telesave and quicksave exist. If a summary string for a save is
empty, then that save is considered not to exist.
I'm refactoring the summary string system, by making the new variables
Game::last_telesave and Game::last_quicksave of type struct
Game::Summary. This struct should have all data necessary to display
the summary string at runtime, and thus translate it at runtime (so
we don't store a summary in a certain language and then display it in
the wrong font later - the summary can always be in the current
language). It also has an `exists` member, to replace the need to
check for empty strings.
The <summary> tag is now completely unused, but is still written to
for older versions of the game to read.
(This commit does not add the new string to the language files, since
Terry now added it separately in his own branch)
2023-09-12 14:36:58 +02:00
|
|
|
bool exists;
|
2023-09-12 03:04:34 +02:00
|
|
|
int seconds;
|
|
|
|
int minutes;
|
|
|
|
int hours;
|
2023-09-12 03:22:18 +02:00
|
|
|
int saverx;
|
|
|
|
int savery;
|
2023-09-12 03:04:34 +02:00
|
|
|
int trinkets;
|
|
|
|
bool crewstats[numcrew];
|
|
|
|
};
|
|
|
|
|
Replace std::string Game::telesummary and Game::quicksummary by Summary
Game::telesummary and Game::quicksummary stored the summary string for
the save files - which is the <summary> tag that says something like
"Space Station, 10:30:59". The game only ever displays the quicksave
variant of these two, for "Last Save:" on the map menu's SAVE tab.
So the telesave has a <summary> too, but it's never displayed anywhere.
(In fact, the area is often set to "nowhere"...)
However, the summary strings have another function: detect that both
the telesave and quicksave exist. If a summary string for a save is
empty, then that save is considered not to exist.
I'm refactoring the summary string system, by making the new variables
Game::last_telesave and Game::last_quicksave of type struct
Game::Summary. This struct should have all data necessary to display
the summary string at runtime, and thus translate it at runtime (so
we don't store a summary in a certain language and then display it in
the wrong font later - the summary can always be in the current
language). It also has an `exists` member, to replace the need to
check for empty strings.
The <summary> tag is now completely unused, but is still written to
for older versions of the game to read.
(This commit does not add the new string to the language files, since
Terry now added it separately in his own branch)
2023-09-12 14:36:58 +02:00
|
|
|
struct Summary last_telesave, last_quicksave;
|
|
|
|
bool save_exists(void);
|
|
|
|
|
Simplify and print XML errors from TinyXML-2
All XML functions now check the return value of
tinyxml2::XMLDocument::Error() after each document gets loaded in to
TinyXML-2. If there's an error, then all functions return. This isn't
strictly necessary, but printing the error message that TinyXML-2 is the
bare minimum we could do to be useful.
Additionally, I've standardized the error messages of missing or
corrupted XML files.
Also, the way the game went about making the XML handles was... a bit
roundabout. There were two XML handles, one for the document and one for
the root element - although only one XML handle suffices. So I've
cleaned that up too.
I could've gone further and added error checking for a whole bunch of
things (e.g. missing elements, missing attributes), but this is good
enough.
Also, if unlock.vvv or settings.vvv don't exist yet, the game is
guaranteed to no-op instead of continuing with the function. Nothing bad
seems to happen if the function continues, but the return statements
should be there anyway to clearly indicate intent.
2021-03-24 02:44:16 +01:00
|
|
|
void readmaingamesave(const char* savename, tinyxml2::XMLDocument& doc);
|
Replace std::string Game::telesummary and Game::quicksummary by Summary
Game::telesummary and Game::quicksummary stored the summary string for
the save files - which is the <summary> tag that says something like
"Space Station, 10:30:59". The game only ever displays the quicksave
variant of these two, for "Last Save:" on the map menu's SAVE tab.
So the telesave has a <summary> too, but it's never displayed anywhere.
(In fact, the area is often set to "nowhere"...)
However, the summary strings have another function: detect that both
the telesave and quicksave exist. If a summary string for a save is
empty, then that save is considered not to exist.
I'm refactoring the summary string system, by making the new variables
Game::last_telesave and Game::last_quicksave of type struct
Game::Summary. This struct should have all data necessary to display
the summary string at runtime, and thus translate it at runtime (so
we don't store a summary in a certain language and then display it in
the wrong font later - the summary can always be in the current
language). It also has an `exists` member, to replace the need to
check for empty strings.
The <summary> tag is now completely unused, but is still written to
for older versions of the game to read.
(This commit does not add the new string to the language files, since
Terry now added it separately in his own branch)
2023-09-12 14:36:58 +02:00
|
|
|
struct Summary writemaingamesave(tinyxml2::XMLDocument& doc);
|
2020-09-14 01:31:02 +02:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void initteleportermode(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-03-07 00:30:22 +01:00
|
|
|
const char* saveFilePath;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
|
2021-04-17 08:08:27 +02:00
|
|
|
int roomx, roomy;
|
2020-01-27 23:46:11 +01:00
|
|
|
int prevroomx, prevroomy;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
int savex, savey, saverx, savery;
|
|
|
|
int savegc, savedir;
|
2021-09-07 03:28:28 +02:00
|
|
|
int savecolour;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
//Added for port
|
|
|
|
int edsavex, edsavey, edsaverx, edsavery;
|
|
|
|
int edsavegc, edsavedir;
|
|
|
|
|
|
|
|
//State logic stuff
|
|
|
|
int state, statedelay;
|
|
|
|
|
2020-04-02 22:01:55 +02:00
|
|
|
bool glitchrunkludge;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-12-18 08:57:55 +01:00
|
|
|
enum GameGamestate gamestate;
|
|
|
|
enum GameGamestate prevgamestate; //only used sometimes
|
2020-01-01 21:29:24 +01:00
|
|
|
bool hascontrol, jumpheld;
|
|
|
|
int jumppressed;
|
|
|
|
int gravitycontrol;
|
2023-03-18 23:24:14 +01:00
|
|
|
bool isingamecompletescreen(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
bool muted;
|
|
|
|
int mutebutton;
|
2020-04-19 21:40:59 +02:00
|
|
|
bool musicmuted;
|
|
|
|
int musicmutebutton;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
int tapleft, tapright;
|
|
|
|
|
|
|
|
//Menu interaction stuff
|
2021-12-18 08:57:55 +01:00
|
|
|
void mapmenuchange(const enum GameGamestate newgamestate, const bool user_initiated);
|
2020-01-01 21:29:24 +01:00
|
|
|
bool mapheld;
|
|
|
|
int menupage;
|
|
|
|
int lastsaved;
|
|
|
|
int deathcounts;
|
|
|
|
|
2022-11-14 23:10:24 +01:00
|
|
|
int framecounter;
|
|
|
|
bool seed_use_sdl_getticks;
|
2023-08-23 19:51:11 +02:00
|
|
|
bool editor_disabled;
|
2020-01-01 21:29:24 +01:00
|
|
|
int frames, seconds, minutes, hours;
|
|
|
|
bool gamesaved;
|
2020-11-04 03:45:33 +01:00
|
|
|
bool gamesavefailed;
|
2020-01-01 21:29:24 +01:00
|
|
|
std::string savetime;
|
|
|
|
int savetrinkets;
|
|
|
|
bool startscript;
|
|
|
|
std::string newscript;
|
|
|
|
|
|
|
|
bool menustart;
|
|
|
|
|
|
|
|
//Teleporting
|
|
|
|
bool teleport_to_new_area;
|
|
|
|
int teleport_to_x, teleport_to_y;
|
|
|
|
std::string teleportscript;
|
|
|
|
bool useteleporter;
|
|
|
|
int teleport_to_teleporter;
|
|
|
|
|
|
|
|
//Main Menu Variables
|
Refactor menu creation code
Firstly, menu options are no longer ad-hoc objects, and are added by
using Game::option() (this is the biggest change). This removes the
vector Game::menuoptionsactive, and Game::menuoptions is now a vector of
MenuOption instead of std::string.
Secondly, the manual tracker variable of the amount of menu options,
Game::nummenuoptions, has been removed, in favor of using vectors
properly and using Game::menuoptions::size().
As a result, a lot of copy-pasted code has been removed from
Game::createmenu(), mostly due to having to have different versions of
menus depending on whether or not we have certain defines, or having an
mmmmmm.vvv file inside the VVVVVV directory. In the old days, you
couldn't just add or remove a menu option conveniently, you had to
shuffle around the position of every other menu option too, which
resulted in lots of copy-pasted code. But now this copy-pasted code has
been de-duplicated, at least in Game::createmenu().
2020-04-15 06:50:17 +02:00
|
|
|
std::vector<MenuOption> menuoptions;
|
|
|
|
int currentmenuoption ;
|
2022-12-30 22:57:24 +01:00
|
|
|
bool menutestmode;
|
2020-04-17 05:09:22 +02:00
|
|
|
enum Menu::MenuName currentmenuname;
|
2020-06-23 02:23:56 +02:00
|
|
|
enum Menu::MenuName kludge_ingametemp;
|
2021-04-12 02:43:17 +02:00
|
|
|
enum SLIDERMODE slidermode;
|
2020-02-12 05:45:58 +01:00
|
|
|
int current_credits_list_index;
|
2023-12-06 00:34:05 +01:00
|
|
|
int translator_credits_pagenum;
|
2020-01-01 21:29:24 +01:00
|
|
|
int menuxoff, menuyoff;
|
Make menus automatically centered and narrowed
All menus had a hardcoded X position (offset to an arbitrary starting
point of 110) and a hardcoded horizontal spacing for the "staircasing"
(mostly 30 pixels, but for some specific menus hardcoded to 15, 20 or
something else). Not all menus were centered, and seem to have been
manually made narrower (with lower horizontal spacing) whenever text
ran offscreen during development.
This system may already be hard to work with in an English-only menu
system, since you may need to adjust horizontal spacing or positioning
when adding an option. The main reason I made this change is that it's
even less optimal when menu options have to be translated, since
maximum string lengths are hard to determine, and it's easy to have
menu options running offscreen, especially when not all menus are
checked for all languages and when options could be added in the middle
of a menu after translations of that menu are already checked.
Now, menus are automatically centered based on their options, and they
are automatically made narrower if they won't fit with the default
horizontal spacing of 30 pixels (with some padding). The game.menuxoff
variable for the menu X position is now also offset to 0 instead of 110
The _default_ horizontal spacing can be changed on a per-menu basis,
and most menus (not all) which already had a narrower spacing set,
retain that as a maximum spacing, simply because they looked odd with
30 pixels of spacing (especially the main menu). They will be made even
narrower automatically if needed. In the most extreme case, the spacing
can go down to 0 and options will be displayed right below each other.
This isn't in the usual style of the game, but at least we did the best
we could to prevent options running offscreen.
The only exception to automatic menu centering and narrowing is the
list of player levels, because it's a special case and existing
behavior would be better than automatic centering there.
2020-06-29 02:09:52 +02:00
|
|
|
int menuspacing;
|
2020-04-17 03:52:40 +02:00
|
|
|
std::vector<MenuStackFrame> menustack;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2024-01-03 22:54:20 +01:00
|
|
|
void inline option(const char* text, bool active = true, uint32_t print_flags = PR_RTL_XFLIP)
|
2020-04-15 06:12:24 +02:00
|
|
|
{
|
|
|
|
MenuOption menuoption;
|
2020-07-04 06:30:31 +02:00
|
|
|
SDL_strlcpy(menuoption.text, text, sizeof(menuoption.text));
|
2020-04-15 06:12:24 +02:00
|
|
|
menuoption.active = active;
|
2023-01-15 04:06:31 +01:00
|
|
|
menuoption.print_flags = print_flags;
|
2020-04-15 06:12:24 +02:00
|
|
|
menuoptions.push_back(menuoption);
|
|
|
|
}
|
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
int menucountdown;
|
2020-04-16 06:53:36 +02:00
|
|
|
enum Menu::MenuName menudest;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
int creditposx, creditposy, creditposdelay;
|
2020-05-02 03:23:52 +02:00
|
|
|
int oldcreditposx;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-11-22 03:10:26 +01:00
|
|
|
bool silence_settings_error;
|
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
//Sine Wave Ninja Minigame
|
|
|
|
bool swnmode;
|
2023-06-05 08:24:31 +02:00
|
|
|
enum SWNMODE swngame;
|
|
|
|
int swnstate, swnstate2, swnstate3, swnstate4, swndelay, swndeaths;
|
2020-01-01 21:29:24 +01:00
|
|
|
int swntimer, swncolstate, swncoldelay;
|
|
|
|
int swnrecord, swnbestrank, swnrank, swnmessage;
|
|
|
|
|
|
|
|
//SuperCrewMate Stuff
|
Remove `scmmoveme`
So, I ended up breaking supercrewmate spawning with that roomchange
refactor. However, upon investigating how to fix it, I was running into
a weird interpolation issue due to scmmoveme, as well as the companion
spawning in the ground in "Very Good". And I was wondering why I or no
one else ended up running into them.
Well, as it turns out, scmmoveme ends up doing absolutely nothing. There
are only two instances where scmmoveme is used. The first is if you
respawn in "Very Good", and somehow have your scmprogress set to that
room. But that's impossible, because whenever you respawn, your
scmprogress is always set to the one after the room you respawn in. Even
if you respawned in the room previous to "Very Good" (which is "Don't
Get Ahead of Yourself!"), it still wouldn't work, since the logic always
kicks in when a gotoroom happens, and not only when a supercrewmate is
actually spawned. Since the scmprogress doesn't match, that case never
gets triggered, and we get to the second time scmmoveme is used, which
is in the catch-all case that always executes.
This second instance... also does nothing, because since we just
respawned, and our scmprogress got set to the room ahead of us, there is
no supercrewmate on screen. Then getscm() returns 0, and the player is
always indice 0, so the only thing we end up doing is setting the
player's x-position to their own x-position. Brilliant.
Anyway, this code results in interpolation issues and the supercrewmate
spawning in the ground on "Very Good" if you die, when my fix is
applied, because my fix moves this logic around to a different frame
order, and that actually ends up making scmmoveme no longer dead code.
So to recap: we have dead code, which looks like it does something, but
doesn't. But if you move it around in a certain way, it ends up having
harmful effects. One of the joys of working on this game...
It's also hilarious that it gets saved to the save file. Why? The only
time this variable is true, it is for literally less than a frame,
because it always gets set to false, because you always respawn using a
gotoroom whenever the supercrewmate dies, because you never respawn in
the same room as a supercrewmate, because Intermission 1 was
deliberately designed that way (else you'd keep continually dying since
the supercrewmate wouldn't move out of the way).
2021-09-12 07:23:47 +02:00
|
|
|
bool supercrewmate, scmhurt;
|
2020-01-01 21:29:24 +01:00
|
|
|
int scmprogress;
|
|
|
|
|
|
|
|
//Accessibility Options
|
|
|
|
bool colourblindmode;
|
|
|
|
bool noflashingmode;
|
|
|
|
int slowdown;
|
2021-04-02 20:50:30 +02:00
|
|
|
int get_timestep(void);
|
2022-12-30 22:57:24 +01:00
|
|
|
bool physics_frozen(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
bool nodeathmode;
|
|
|
|
int gameoverdelay;
|
|
|
|
bool nocutscenes;
|
2021-01-08 01:18:07 +01:00
|
|
|
int ndmresultcrewrescued;
|
|
|
|
int ndmresulttrinkets;
|
|
|
|
std::string ndmresulthardestroom;
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void copyndmresults(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
//Time Trials
|
|
|
|
bool intimetrial, timetrialparlost;
|
|
|
|
int timetrialcountdown, timetrialshinytarget, timetriallevel;
|
2020-06-30 00:53:19 +02:00
|
|
|
int timetrialpar, timetrialresulttime, timetrialresultframes, timetrialrank;
|
2022-12-30 22:57:24 +01:00
|
|
|
bool timetrialcheater;
|
2021-01-08 01:02:45 +01:00
|
|
|
int timetrialresultshinytarget, timetrialresulttrinkets, timetrialresultpar;
|
|
|
|
int timetrialresultdeaths;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
Add level exploring menu for translators
I would, of course, recommend translators to translate the roomnames
while playing the full game (optionally in invincibility) so they can
immediately get all the context and maybe the most inspiration. And if
you want to go back into a specific level, then there's always the time
trials and intermission replays which will give you full coverage of
all the room names.
However, the time trials weren't really made for room name translation.
They have some annoying features like the instant restart when you
press ENTER at the wrong time, they remove context clues like
teleporters and companions, but the worst problem is that the last room
in a level is often completely untranslatable inside the time trials
because you immediately get sent to the results screen...
So, I added a new menu in the translator options, "explore game", which
gives you access to all the time trials and the two intermissions, from
the same menu. All these time trials (which they're still based off of,
under the hood) are stripped of the annoying features that come with
time trials. These are the changes I made to time trial behavior in
translator exploring mode:
- No 3-2-1-Go! countdown
- No on-screen time/death/shiny/par
- ENTER doesn't restart, and the map menu works. The entire map is also
revealed.
- Prize for the Reckless is in its normal form
- The teleporters in Entanglement Generator, Wheeler's Wormhole and
Level Complete are restored as context for room names (actually, we
should probably restore them in time trials anyway? Their "press to
teleport" prompt is already blocked out in time trials and they do
nothing other than being a checkpoint. I guess the reason they were
removed was to stop people from opening the teleporter menu when that
was not specifically blocked out in time trials yet.)
- The companions are there at the end of levels, and behave like in no
death mode (become happy and follow you to the teleporter). Also for
context.
- At the end of each level, you're not suddenly sent to the menu, but
you can use the teleporter at your leisure just like in the
intermission replays. In the Final Level, you do get sent to the menu
automatically, but after a longer delay.
I made another mark on VVVVVV: don't be startled, I added gamestates.
I wanted all teleporters at the end of levels to behave like the ones
at the end of the intermission replays, and all handling for
teleporting with specific companions is already done in gamestates, so
rather than adding conditional blocks across 5 or so different
gamestates, it made more sense to make a single gamestate for
"teleporting in translator exploring mode" (3090). I also added an
alternative to having to use gamestate 3500 or 82 for the end of the
final level: 3091-3092.
One other thing I want to add to the "explore game" menu: a per-level
count of how many room names are left to translate. That shouldn't be
too difficult, and I'm planning that for the next commit.
2022-11-26 03:33:17 +01:00
|
|
|
bool start_translator_exploring;
|
|
|
|
bool translator_exploring;
|
|
|
|
bool translator_exploring_allowtele;
|
2022-12-24 04:16:56 +01:00
|
|
|
bool translator_cutscene_test;
|
|
|
|
|
|
|
|
size_t cutscenetest_menu_page;
|
|
|
|
std::string cutscenetest_menu_play_id;
|
Add level exploring menu for translators
I would, of course, recommend translators to translate the roomnames
while playing the full game (optionally in invincibility) so they can
immediately get all the context and maybe the most inspiration. And if
you want to go back into a specific level, then there's always the time
trials and intermission replays which will give you full coverage of
all the room names.
However, the time trials weren't really made for room name translation.
They have some annoying features like the instant restart when you
press ENTER at the wrong time, they remove context clues like
teleporters and companions, but the worst problem is that the last room
in a level is often completely untranslatable inside the time trials
because you immediately get sent to the results screen...
So, I added a new menu in the translator options, "explore game", which
gives you access to all the time trials and the two intermissions, from
the same menu. All these time trials (which they're still based off of,
under the hood) are stripped of the annoying features that come with
time trials. These are the changes I made to time trial behavior in
translator exploring mode:
- No 3-2-1-Go! countdown
- No on-screen time/death/shiny/par
- ENTER doesn't restart, and the map menu works. The entire map is also
revealed.
- Prize for the Reckless is in its normal form
- The teleporters in Entanglement Generator, Wheeler's Wormhole and
Level Complete are restored as context for room names (actually, we
should probably restore them in time trials anyway? Their "press to
teleport" prompt is already blocked out in time trials and they do
nothing other than being a checkpoint. I guess the reason they were
removed was to stop people from opening the teleporter menu when that
was not specifically blocked out in time trials yet.)
- The companions are there at the end of levels, and behave like in no
death mode (become happy and follow you to the teleporter). Also for
context.
- At the end of each level, you're not suddenly sent to the menu, but
you can use the teleporter at your leisure just like in the
intermission replays. In the Final Level, you do get sent to the menu
automatically, but after a longer delay.
I made another mark on VVVVVV: don't be startled, I added gamestates.
I wanted all teleporters at the end of levels to behave like the ones
at the end of the intermission replays, and all handling for
teleporting with specific companions is already done in gamestates, so
rather than adding conditional blocks across 5 or so different
gamestates, it made more sense to make a single gamestate for
"teleporting in translator exploring mode" (3090). I also added an
alternative to having to use gamestate 3500 or 82 for the end of the
final level: 3091-3092.
One other thing I want to add to the "explore game" menu: a per-level
count of how many room names are left to translate. That shouldn't be
too difficult, and I'm planning that for the next commit.
2022-11-26 03:33:17 +01:00
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
int creditposition;
|
2020-04-30 19:56:27 +02:00
|
|
|
int oldcreditposition;
|
2020-01-01 21:29:24 +01:00
|
|
|
bool insecretlab;
|
|
|
|
|
|
|
|
bool inintermission;
|
|
|
|
|
2020-07-03 03:10:52 +02:00
|
|
|
bool crewstats[numcrew];
|
2021-01-08 01:18:07 +01:00
|
|
|
bool ndmresultcrewstats[numcrew];
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
bool alarmon;
|
|
|
|
int alarmdelay;
|
|
|
|
bool blackout;
|
|
|
|
|
2020-07-03 01:45:22 +02:00
|
|
|
static const int numunlock = 25;
|
|
|
|
bool unlock[numunlock];
|
|
|
|
bool unlocknotify[numunlock];
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
bool anything_unlocked(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
int stat_trinkets;
|
|
|
|
int bestgamedeaths;
|
|
|
|
|
|
|
|
|
2020-07-03 02:09:30 +02:00
|
|
|
static const int numtrials = 6;
|
|
|
|
int besttimes[numtrials];
|
|
|
|
int bestframes[numtrials];
|
|
|
|
int besttrinkets[numtrials];
|
|
|
|
int bestlives[numtrials];
|
|
|
|
int bestrank[numtrials];
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
int screenshake, flashlight;
|
|
|
|
bool advancetext, pausescript;
|
|
|
|
|
|
|
|
int deathseq, lifeseq;
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
int trinkets(void);
|
|
|
|
int crewmates(void);
|
2020-04-09 07:27:13 +02:00
|
|
|
int savepoint, teleportxpos;
|
|
|
|
bool teleport;
|
2020-01-01 21:29:24 +01:00
|
|
|
int edteleportent;
|
|
|
|
bool completestop;
|
|
|
|
|
|
|
|
float inertia;
|
|
|
|
|
|
|
|
int companion;
|
|
|
|
SDL_Rect teleblock;
|
|
|
|
bool activetele;
|
|
|
|
int readytotele;
|
2020-04-30 02:04:25 +02:00
|
|
|
int oldreadytotele;
|
2023-02-18 05:38:05 +01:00
|
|
|
int activity_r, activity_g, activity_b, activity_y;
|
2020-01-01 21:29:24 +01:00
|
|
|
std::string activity_lastprompt;
|
2023-08-30 20:37:16 +02:00
|
|
|
bool activity_gettext;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
bool backgroundtext;
|
|
|
|
|
|
|
|
int activeactivity, act_fade;
|
2020-04-29 06:58:19 +02:00
|
|
|
int prev_act_fade;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2021-04-19 08:23:44 +02:00
|
|
|
bool press_left, press_right, press_action, press_map, press_interact;
|
|
|
|
bool interactheld;
|
|
|
|
bool separate_interact;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
//Some stats:
|
|
|
|
int totalflips;
|
2023-09-04 15:27:29 +02:00
|
|
|
std::string hardestroom; // don't change to C string unless you wanna handle when this string is loaded from the XML
|
2020-01-01 21:29:24 +01:00
|
|
|
int hardestroomdeaths, currentroomdeaths;
|
2023-09-04 15:27:29 +02:00
|
|
|
int hardestroom_x, hardestroom_y;
|
|
|
|
bool hardestroom_specialname;
|
|
|
|
bool hardestroom_finalstretch;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
|
|
|
|
bool quickrestartkludge;
|
|
|
|
|
|
|
|
//Custom stuff
|
|
|
|
std::string customscript[50];
|
|
|
|
int customcol;
|
|
|
|
int levelpage;
|
|
|
|
int playcustomlevel;
|
|
|
|
std::string customleveltitle;
|
|
|
|
std::string customlevelfilename;
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void clearcustomlevelstats(void);
|
|
|
|
void loadcustomlevelstats(void);
|
|
|
|
void savecustomlevelstats(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
void updatecustomlevelstats(std::string clevel, int cscore);
|
2021-08-12 05:54:02 +02:00
|
|
|
void deletecustomlevelstats(void);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-10-25 04:05:23 +02:00
|
|
|
// name -> score. 0 - not played, 1 - finished, 2 - all trinkets, 3 - finished, all trinkets
|
|
|
|
std::map<std::string, int> customlevelstats;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
|
2020-04-02 22:01:55 +02:00
|
|
|
std::vector<SDL_GameControllerButton> controllerButton_map;
|
|
|
|
std::vector<SDL_GameControllerButton> controllerButton_flip;
|
|
|
|
std::vector<SDL_GameControllerButton> controllerButton_esc;
|
2020-08-09 00:41:59 +02:00
|
|
|
std::vector<SDL_GameControllerButton> controllerButton_restart;
|
2021-04-19 08:23:44 +02:00
|
|
|
std::vector<SDL_GameControllerButton> controllerButton_interact;
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-01-13 02:45:44 +01:00
|
|
|
bool skipfakeload;
|
Add a player trail to the editor (ghosts)
A few months ago, I added ghosts to the VVVVVV: Community Edition editor. I was told recently I should think
about upstreaming it, and with Terry saying go ahead I finally ported them into VVVVVV. There's one slight
difference however--you can choose whether you have them or not in the editor's settings menu. They're off by
default, and this is saved to the save file.
Anyway, when you're playtesting, the game saves the players position, color, room coordinates and sprite every 3
frames. The max is 100, where if it tries to add more, the oldest one gets removed.
When you exit playtesting, the saved positions appear one at a time, and you can use the Z key to speed it up.
[Here's a video of them in action.](https://o.lol-sa.me/4H21zCv.mp4)
2020-06-13 00:04:35 +02:00
|
|
|
bool ghostsenabled;
|
2020-04-09 21:03:24 +02:00
|
|
|
|
|
|
|
bool cliplaytest;
|
|
|
|
int playx;
|
|
|
|
int playy;
|
|
|
|
int playrx;
|
|
|
|
int playry;
|
|
|
|
int playgc;
|
2020-07-11 20:55:26 +02:00
|
|
|
int playmusic;
|
2020-06-22 00:56:31 +02:00
|
|
|
std::string playassets;
|
2020-05-07 23:38:19 +02:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void quittomenu(void);
|
|
|
|
void returntolab(void);
|
2020-05-08 00:23:55 +02:00
|
|
|
bool fadetomenu;
|
|
|
|
int fadetomenudelay;
|
2020-05-08 00:30:26 +02:00
|
|
|
bool fadetolab;
|
|
|
|
int fadetolabdelay;
|
2020-05-09 21:35:17 +02:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void returntoeditor(void);
|
Add a player trail to the editor (ghosts)
A few months ago, I added ghosts to the VVVVVV: Community Edition editor. I was told recently I should think
about upstreaming it, and with Terry saying go ahead I finally ported them into VVVVVV. There's one slight
difference however--you can choose whether you have them or not in the editor's settings menu. They're off by
default, and this is saved to the save file.
Anyway, when you're playtesting, the game saves the players position, color, room coordinates and sprite every 3
frames. The max is 100, where if it tries to add more, the oldest one gets removed.
When you exit playtesting, the saved positions appear one at a time, and you can use the Z key to speed it up.
[Here's a video of them in action.](https://o.lol-sa.me/4H21zCv.mp4)
2020-06-13 00:04:35 +02:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
bool inline inspecial(void)
|
2020-06-14 05:07:52 +02:00
|
|
|
{
|
2022-12-24 04:16:56 +01:00
|
|
|
return inintermission || insecretlab || intimetrial || nodeathmode || translator_exploring;
|
2020-06-14 05:07:52 +02:00
|
|
|
}
|
2020-05-04 21:52:57 +02:00
|
|
|
|
2021-05-04 03:29:23 +02:00
|
|
|
bool incompetitive(void);
|
|
|
|
|
|
|
|
bool nocompetitive(void);
|
2022-12-30 22:57:24 +01:00
|
|
|
bool nocompetitive_unless_translator(void);
|
|
|
|
|
|
|
|
void sabotage_time_trial(void);
|
2021-05-04 03:29:23 +02:00
|
|
|
|
2020-05-04 21:52:57 +02:00
|
|
|
bool over30mode;
|
2021-08-05 23:31:20 +02:00
|
|
|
bool showingametimer;
|
2020-06-23 01:51:16 +02:00
|
|
|
|
|
|
|
bool ingame_titlemode;
|
Add graphic options and game options to editor settings
This is a small quality-of-life tweak that makes it so if you're in the
middle of editing a level, you don't have to save the level, exit to the
menu, change whatever setting you wanted, re-enter the editor, and type
in the level name, just to change one setting. This is the same as
adding Graphic Options and Game Options to the in-game pause menu,
except for the editor, too.
To do this, I'm reusing Game::returntopausemenu() (because all of its
callers are the same callers for returning to editor settings) and
renamed it to returntoingame(), then added a variable named
ingame_editormode to Game. When we're in the options menus but still in
the editor, BOTH ingame_titlemode and ingame_editormode will be true.
2021-03-19 03:52:30 +01:00
|
|
|
bool ingame_editormode;
|
2020-06-23 02:26:45 +02:00
|
|
|
|
Add graphic options and game options to editor settings
This is a small quality-of-life tweak that makes it so if you're in the
middle of editing a level, you don't have to save the level, exit to the
menu, change whatever setting you wanted, re-enter the editor, and type
in the level name, just to change one setting. This is the same as
adding Graphic Options and Game Options to the in-game pause menu,
except for the editor, too.
To do this, I'm reusing Game::returntopausemenu() (because all of its
callers are the same callers for returning to editor settings) and
renamed it to returntoingame(), then added a variable named
ingame_editormode to Game. When we're in the options menus but still in
the editor, BOTH ingame_titlemode and ingame_editormode will be true.
2021-03-19 03:52:30 +01:00
|
|
|
void returntoingame(void);
|
2020-08-01 21:51:11 +02:00
|
|
|
void unlockAchievement(const char *name);
|
2020-06-30 04:49:14 +02:00
|
|
|
|
|
|
|
bool disablepause;
|
2021-08-05 21:20:05 +02:00
|
|
|
bool disableaudiopause;
|
2021-08-12 03:08:32 +02:00
|
|
|
bool disabletemporaryaudiopause;
|
2021-04-02 00:39:56 +02:00
|
|
|
bool inputdelay;
|
2022-12-07 00:20:48 +01:00
|
|
|
|
|
|
|
bool statelocked;
|
2023-05-22 21:18:40 +02:00
|
|
|
|
|
|
|
int old_skip_message_timer;
|
|
|
|
int skip_message_timer;
|
2024-01-07 05:53:51 +01:00
|
|
|
|
|
|
|
int old_mode_indicator_timer;
|
|
|
|
int mode_indicator_timer;
|
2024-01-09 19:55:00 +01:00
|
|
|
|
|
|
|
int old_screenshot_border_timer;
|
|
|
|
int screenshot_border_timer;
|
|
|
|
bool screenshot_saved_success;
|
2020-01-01 21:29:24 +01:00
|
|
|
};
|
|
|
|
|
2020-09-28 04:15:06 +02:00
|
|
|
#ifndef GAME_DEFINITION
|
Allow using help/graphics/music/game/key/map/obj everywhere
This commit makes `help`, `graphics`, `music`, `game`, `key`, `map`, and
`obj` essentially static global objects that can be used everywhere.
This is useful in case we ever need to add a new function in the future,
so we don't have to bother with passing a new argument in which means we
have to pass a new argument in to the function that calls that function
which means having to pass a new argument into the function that calls
THAT function, etc. which is a real headache when working on fan mods of
the source code.
Note that this changes NONE of the existing function signatures, it
merely just makes those variables accessible everywhere in the same way
`script` and `ed` are.
Also note that some classes had to be initialized after the filesystem
was initialized, but C++ would keep initializing them before the
filesystem got initialized, because I *had* to put them at the top of
`main.cpp`, or else they wouldn't be global variables.
The only way to work around this was to use entityclass's initialization
style (which I'm pretty sure entityclass of all things doesn't need to
be initialized this way), where you actually initialize the class in an
`init()` function, and so then you do `graphics.init()` after the
filesystem initialization, AFTER doing `Graphics graphics` up at the
top.
I've had to do this for `graphics` (but only because its child
GraphicsResources `grphx` needs to be initialized this way), `music`,
and `game`. I don't think this will affect anything. Other than that,
`help`, `key`, and `map` are still using the C++-intended method of
having ClassName::ClassName() functions.
2020-01-29 08:35:03 +01:00
|
|
|
extern Game game;
|
2020-09-28 04:15:06 +02:00
|
|
|
#endif
|
Allow using help/graphics/music/game/key/map/obj everywhere
This commit makes `help`, `graphics`, `music`, `game`, `key`, `map`, and
`obj` essentially static global objects that can be used everywhere.
This is useful in case we ever need to add a new function in the future,
so we don't have to bother with passing a new argument in which means we
have to pass a new argument in to the function that calls that function
which means having to pass a new argument into the function that calls
THAT function, etc. which is a real headache when working on fan mods of
the source code.
Note that this changes NONE of the existing function signatures, it
merely just makes those variables accessible everywhere in the same way
`script` and `ed` are.
Also note that some classes had to be initialized after the filesystem
was initialized, but C++ would keep initializing them before the
filesystem got initialized, because I *had* to put them at the top of
`main.cpp`, or else they wouldn't be global variables.
The only way to work around this was to use entityclass's initialization
style (which I'm pretty sure entityclass of all things doesn't need to
be initialized this way), where you actually initialize the class in an
`init()` function, and so then you do `graphics.init()` after the
filesystem initialization, AFTER doing `Graphics graphics` up at the
top.
I've had to do this for `graphics` (but only because its child
GraphicsResources `grphx` needs to be initialized this way), `music`,
and `game`. I don't think this will affect anything. Other than that,
`help`, `key`, and `map` are still using the C++-intended method of
having ClassName::ClassName() functions.
2020-01-29 08:35:03 +01:00
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
#endif /* GAME_H */
|