2021-04-19 08:23:44 +02:00
# include <SDL.h>
2021-09-13 06:39:07 +02:00
# include "Constants.h"
2020-07-19 21:43:29 +02:00
# include "Credits.h"
2021-02-20 08:19:09 +01:00
# include "CustomLevels.h"
2021-02-21 00:40:11 +01:00
# include "Editor.h"
2020-01-01 21:29:24 +01:00
# include "Entity.h"
2020-07-19 21:43:29 +02:00
# include "FileSystemUtils.h"
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
# include "GlitchrunnerMode.h"
2020-07-19 21:43:29 +02:00
# include "Graphics.h"
2021-06-13 00:19:15 +02:00
# include "GraphicsUtil.h"
2020-11-13 02:16:18 +01:00
# include "KeyPoll.h"
2020-07-19 21:43:29 +02:00
# include "MakeAndPlay.h"
2020-01-01 21:29:24 +01:00
# include "Map.h"
2020-07-19 21:43:29 +02:00
# include "Maths.h"
2020-07-19 21:05:41 +02:00
# include "Music.h"
Extern `gameScreen`, remove `screenbuffer`
I know earlier I removed the gameScreen extern in favor of using
screenbuffer, but that was only to be consistent. After further
consideration, I have found that it's actually really stupid.
There's no reason to be accessing it through screenbuffer, and it's
probably an artifact of 2.0-2.2 passing stack-allocated otherwise-global
classes everywhere through function arguments. Also, it leads to stupid
bugs where screenbuffer could potentially be NULL, which has already
resulted in various annoying crashes in the past. Although those could
be fixed by simply initializing screenbuffer at the very top of main(),
but, why not just scrap the whole thing anyway?
So that's what I'm doing.
As a nice side effect, I've removed the transitive include of Screen.h
from Graphics.h. This could've been done already since it only includes
it for the pointer anyway, but it's still good to do it now.
2021-12-25 08:56:47 +01:00
# include "Screen.h"
2020-01-01 21:29:24 +01:00
# include "Script.h"
2020-07-19 21:43:29 +02:00
# include "UtilityClass.h"
Don't recompile all files when the commit hash is changed
The previous implementation of showing the commit hash on the title
screen used a preprocessor definition added at CMake time to pass the
hash and date. This was passed for every file compiled, so if the date
or hash changed, then every file would be recompiled. This is especially
annoying if you're working on the game and switching branches all the
time - the game has at least 50 source files to recompile!
To fix this, we'll switch to using a generated file, named
Version.h.out, that only gets included by the necessary files (which
there is only one of - Render.cpp). It will be autogenerated by CMake
(by using CONFIGURE_FILE(), which takes a templated file and does a
find-and-replace on it, not unlike C macros), and since there's only one
file that includes it, only one file will need to be recompiled when it
changes.
And also to prevent Version.h.out being a required file, it will only be
included if necessary (i.e. OFFICIAL_BUILD is off). Since the C
preprocessor can't ignore non-existing include files and will always
error on them, I wrapped the #include in an #ifdef VERSION_H_EXISTS, and
CMake will add the VERSION_H_OUT_EXISTS define when generating
Version.h.out. The wrapper is named Version.h, so any file
that #includes the commit hash and date should #include Version.h
instead of Version.h.out.
As an added bonus, I've also made it so CMake will print "This is
interim commit [HASH] (committed [DATE])" at configure time if the game
is going to be compiled with an interim commit hash.
Now, there is also the issue that the commit hash change will only be
noticed in the first place if CMake needs to be re-ran for anything, but
that's a less severe issue than requiring recompilation of 50(!) or so
files.
2020-12-26 00:24:48 +01:00
# include "Version.h"
2020-01-01 21:29:24 +01:00
2021-01-10 18:14:37 +01:00
static int tr ;
static int tg ;
static int tb ;
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
static inline void drawslowdowntext ( void )
2020-11-13 02:05:18 +01:00
{
switch ( game . slowdown )
{
case 30 :
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 85 , " Game speed is normal. " , tr / 2 , tg / 2 , tb / 2 , true ) ;
2020-11-13 02:05:18 +01:00
break ;
case 24 :
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 85 , " Game speed is at 80% " , tr , tg , tb , true ) ;
2020-11-13 02:05:18 +01:00
break ;
case 18 :
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 85 , " Game speed is at 60% " , tr , tg , tb , true ) ;
2020-11-13 02:05:18 +01:00
break ;
case 12 :
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 85 , " Game speed is at 40% " , tr , tg , tb , true ) ;
2020-11-13 02:05:18 +01:00
break ;
}
}
2021-04-12 02:43:17 +02:00
static void volumesliderrender ( void )
{
char buffer [ 40 + 1 ] ;
char slider [ 20 + 1 ] ;
int slider_length ;
const char symbol [ ] = " [] " ;
int symbol_length ;
int offset ;
int num_positions ;
const int * volume_ptr ;
switch ( game . currentmenuoption )
{
case 0 :
volume_ptr = & music . user_music_volume ;
break ;
case 1 :
volume_ptr = & music . user_sound_volume ;
break ;
default :
SDL_assert ( 0 & & " Unhandled volume slider menu option! " ) ;
return ;
}
VVV_fillstring ( slider , sizeof ( slider ) , ' . ' ) ;
slider_length = sizeof ( slider ) - 1 ;
symbol_length = sizeof ( symbol ) - 1 ;
num_positions = slider_length - symbol_length + 1 ;
offset = num_positions * ( * volume_ptr ) / USER_VOLUME_MAX ;
offset = clamp ( offset , 0 , slider_length - symbol_length ) ;
/* SDL_strlcpy null-terminates, which would end the string in the middle of
* it , which we don ' t want !
*/
SDL_memcpy ( & slider [ offset ] , symbol , symbol_length ) ;
if ( game . slidermode = = SLIDER_NONE )
{
SDL_strlcpy ( buffer , slider , sizeof ( buffer ) ) ;
}
else
{
/* Draw selection brackets. */
SDL_snprintf ( buffer , sizeof ( buffer ) , " [ %s ] " , slider ) ;
}
graphics . Print ( - 1 , 85 , buffer , tr , tg , tb , true ) ;
}
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
static void inline drawglitchrunnertext ( void )
{
int tempr = tr ;
int tempg = tg ;
int tempb = tb ;
2021-09-13 06:39:07 +02:00
char buffer [ SCREEN_WIDTH_CHARS + 1 ] ;
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
const char * mode_string ;
const enum GlitchrunnerMode mode = GlitchrunnerMode_get ( ) ;
if ( mode = = GlitchrunnerNone )
{
tempr / = 2 ;
tempg / = 2 ;
tempb / = 2 ;
mode_string = " OFF " ;
}
else
{
mode_string = GlitchrunnerMode_enum_to_string ( mode ) ;
}
SDL_snprintf ( buffer , sizeof ( buffer ) , " Glitchrunner mode is %s " , mode_string ) ;
graphics . Print ( - 1 , 95 , buffer , tempr , tempg , tempb , true ) ;
}
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
static void menurender ( void )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
int temp = 50 ;
2020-01-01 21:29:24 +01:00
2020-04-17 00:19:17 +02:00
switch ( game . currentmenuname )
2020-01-01 21:29:24 +01:00
{
2020-04-17 00:19:17 +02:00
case Menu : : mainmenu :
2020-04-01 23:59:19 +02:00
graphics . drawsprite ( ( 160 - 96 ) + 0 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 1 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 2 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 3 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 4 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 5 * 32 , temp , 23 , tr , tg , tb ) ;
2020-04-02 23:19:15 +02:00
# if defined(MAKEANDPLAY)
graphics . Print ( - 1 , temp + 35 , " MAKE AND PLAY EDITION " , tr , tg , tb , true ) ;
2020-11-21 02:58:28 +01:00
# endif
# ifdef COMMIT_DATE
graphics . Print ( 310 - ( 10 * 8 ) , 210 , COMMIT_DATE , tr / 2 , tg / 2 , tb / 2 ) ;
# endif
# ifdef INTERIM_COMMIT
2020-12-26 06:45:24 +01:00
graphics . Print ( 310 - ( SDL_arraysize ( INTERIM_COMMIT ) - 1 ) * 8 , 220 , INTERIM_COMMIT , tr / 2 , tg / 2 , tb / 2 ) ;
2020-04-02 23:19:15 +02:00
# endif
2021-08-31 19:25:29 +02:00
graphics . Print ( 310 - ( 4 * 8 ) , 230 , " v2.4 " , tr / 2 , tg / 2 , tb / 2 ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
if ( music . mmmmmm ) {
graphics . Print ( 10 , 230 , " [MMMMMM Mod Installed] " , tr / 2 , tg / 2 , tb / 2 ) ;
}
2020-04-17 00:19:17 +02:00
break ;
2020-04-16 01:29:54 +02:00
# if !defined(NO_CUSTOM_LEVELS)
2020-04-17 00:19:17 +02:00
case Menu : : levellist :
2020-01-01 21:29:24 +01:00
{
2021-02-21 00:40:11 +01:00
if ( cl . ListOfMetaData . size ( ) = = 0 ) {
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 100 , " ERROR: No levels found. " , tr , tg , tb , true ) ;
}
int tmp = game . currentmenuoption + ( game . levelpage * 8 ) ;
2021-02-21 00:40:11 +01:00
if ( INBOUNDS_VEC ( tmp , cl . ListOfMetaData ) ) {
const bool nextlastoptions = cl . ListOfMetaData . size ( ) > 8 ;
2020-04-17 08:05:49 +02:00
//Don't show next/previous page or return to menu options here!
2021-08-12 04:48:40 +02:00
if ( nextlastoptions & & game . menuoptions . size ( ) - game . currentmenuoption < = 3 ) {
2020-04-16 01:29:54 +02:00
} else {
2021-02-21 00:40:11 +01:00
graphics . bigprint ( - 1 , 15 , cl . ListOfMetaData [ tmp ] . title , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 40 , " by " + cl . ListOfMetaData [ tmp ] . creator , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 50 , cl . ListOfMetaData [ tmp ] . website , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 70 , cl . ListOfMetaData [ tmp ] . Desc1 , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 80 , cl . ListOfMetaData [ tmp ] . Desc2 , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 90 , cl . ListOfMetaData [ tmp ] . Desc3 , tr , tg , tb , true ) ;
2020-04-16 01:29:54 +02:00
}
}
2020-04-17 00:19:17 +02:00
break ;
2020-04-16 01:29:54 +02:00
}
2020-04-02 23:19:15 +02:00
# endif
2020-04-17 00:19:17 +02:00
case Menu : : errornostart :
2021-04-09 17:53:55 +02:00
graphics . Print ( - 1 , 65 , " ERROR: This level has " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " no start point! " , tr , tg , tb , true ) ;
break ;
case Menu : : gameplayoptions :
{
int gameplayoptionsoffset = 0 ;
2021-04-09 12:09:12 +02:00
# if !defined(MAKEANDPLAY)
2021-04-09 17:53:55 +02:00
if ( game . ingame_titlemode & & game . unlock [ 18 ] )
2021-04-09 12:09:12 +02:00
# endif
2021-04-09 17:53:55 +02:00
{
gameplayoptionsoffset = 1 ;
if ( game . currentmenuoption = = 0 ) {
graphics . bigprint ( - 1 , 30 , " Flip Mode " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Flip the entire game vertically. " , tr , tg , tb , true ) ;
if ( graphics . setflipmode )
{
graphics . Print ( - 1 , 85 , " Currently ENABLED! " , tr , tg , tb , true ) ;
}
else
{
graphics . Print ( - 1 , 85 , " Currently Disabled. " , tr / 2 , tg / 2 , tb / 2 , true ) ;
}
}
}
if ( game . currentmenuoption = = gameplayoptionsoffset + 0 )
{
//Toggle FPS
graphics . bigprint ( - 1 , 30 , " Toggle 30+ FPS " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Change whether the game " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " runs at 30 or over 30 FPS. " , tr , tg , tb , true ) ;
if ( ! game . over30mode )
{
graphics . Print ( - 1 , 95 , " Current mode: 30 FPS " , tr / 2 , tg / 2 , tb / 2 , true ) ;
}
else
{
graphics . Print ( - 1 , 95 , " Current mode: Over 30 FPS " , tr , tg , tb , true ) ;
}
break ;
}
else if ( game . currentmenuoption = = gameplayoptionsoffset + 1 )
{
//Speedrunner options
graphics . bigprint ( - 1 , 30 , " Speedrunner Options " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Access some advanced settings that " , tr , tg , tb , true ) ;
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 75 , " might be of interest to speedrunners. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
}
else if ( game . currentmenuoption = = gameplayoptionsoffset + 2 )
{
//Advanced options
graphics . bigprint ( - 1 , 30 , " Advanced Options " , tr , tg , tb , true ) ;
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 65 , " All other gameplay settings. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
}
else if ( game . currentmenuoption = = gameplayoptionsoffset + 3 )
{
//Clear Data
graphics . bigprint ( - 1 , 30 , " Clear Data " , tr , tg , tb , true ) ;
2021-08-12 05:54:02 +02:00
graphics . Print ( - 1 , 65 , " Delete your main game save data " , tr , tg , tb , true ) ;
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 75 , " and unlocked play modes. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
}
2021-08-12 05:54:02 +02:00
else if ( game . currentmenuoption = = gameplayoptionsoffset + 4 )
{
graphics . bigprint ( - 1 , 30 , " Clear Data " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Delete your custom level save data " , tr , tg , tb , true ) ;
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 75 , " and completion stars. " , tr , tg , tb , true ) ;
2021-08-12 05:54:02 +02:00
}
2021-04-09 17:53:55 +02:00
break ;
}
2020-04-17 00:19:17 +02:00
case Menu : : options :
2021-04-09 17:53:55 +02:00
switch ( game . currentmenuoption )
{
case 0 :
graphics . bigprint ( - 1 , 30 , " Gameplay Options " , tr , tg , tb , true ) ;
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 65 , " Adjust various gameplay settings. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
break ;
case 1 :
graphics . bigprint ( - 1 , 30 , " Graphics Options " , tr , tg , tb , true ) ;
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 65 , " Adjust screen settings. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
break ;
case 2 :
2021-08-20 02:17:36 +02:00
const char * str ;
2021-04-12 00:18:35 +02:00
graphics . bigprint ( - 1 , 30 , " Audio Options " , tr , tg , tb , true ) ;
if ( music . mmmmmm )
{
2021-08-20 02:17:36 +02:00
str = " Adjust volume settings and soundtrack. " ;
2021-04-12 00:18:35 +02:00
}
2021-08-20 02:17:36 +02:00
else
{
str = " Adjust volume settings. " ;
}
graphics . PrintWrap ( - 1 , 65 , str , tr , tg , tb , true , 10 , 304 ) ;
2021-04-12 00:18:35 +02:00
break ;
case 3 :
2021-04-09 17:53:55 +02:00
graphics . bigprint ( - 1 , 30 , " Game Pad Options " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Rebind your controller's buttons " , tr , tg , tb , true ) ;
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 75 , " and adjust sensitivity. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
break ;
2021-04-12 00:18:35 +02:00
case 4 :
2021-04-09 17:53:55 +02:00
graphics . bigprint ( - 1 , 30 , " Accessibility " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Disable screen effects, enable " , tr , tg , tb , true ) ;
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 75 , " slowdown modes or invincibility. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
break ;
}
break ;
2020-04-17 00:19:17 +02:00
case Menu : : graphicoptions :
2021-12-26 07:55:55 +01:00
{
int offset = 0 ;
if ( game . currentmenuoption = = offset + 0 & & ! gameScreen . isForcedFullscreen ( ) )
2020-04-16 04:52:49 +02:00
{
graphics . bigprint ( - 1 , 30 , " Toggle Fullscreen " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Change to fullscreen/windowed mode. " , tr , tg , tb , true ) ;
Extern `gameScreen`, remove `screenbuffer`
I know earlier I removed the gameScreen extern in favor of using
screenbuffer, but that was only to be consistent. After further
consideration, I have found that it's actually really stupid.
There's no reason to be accessing it through screenbuffer, and it's
probably an artifact of 2.0-2.2 passing stack-allocated otherwise-global
classes everywhere through function arguments. Also, it leads to stupid
bugs where screenbuffer could potentially be NULL, which has already
resulted in various annoying crashes in the past. Although those could
be fixed by simply initializing screenbuffer at the very top of main(),
but, why not just scrap the whole thing anyway?
So that's what I'm doing.
As a nice side effect, I've removed the transitive include of Screen.h
from Graphics.h. This could've been done already since it only includes
it for the pointer anyway, but it's still good to do it now.
2021-12-25 08:56:47 +01:00
if ( gameScreen . isWindowed )
2020-11-13 01:45:51 +01:00
{
graphics . Print ( - 1 , 85 , " Current mode: WINDOWED " , tr , tg , tb , true ) ;
}
else
{
graphics . Print ( - 1 , 85 , " Current mode: FULLSCREEN " , tr , tg , tb , true ) ;
2020-04-02 23:19:15 +02:00
}
2021-12-26 07:55:55 +01:00
}
2020-04-16 04:52:49 +02:00
2021-12-26 07:55:55 +01:00
if ( gameScreen . isForcedFullscreen ( ) )
{
- - offset ;
}
if ( game . currentmenuoption = = offset + 1 )
{
2020-06-30 22:36:57 +02:00
graphics . bigprint ( - 1 , 30 , " Scaling Mode " , tr , tg , tb , true ) ;
2020-04-16 04:52:49 +02:00
graphics . Print ( - 1 , 65 , " Choose letterbox/stretch/integer mode. " , tr , tg , tb , true ) ;
Extern `gameScreen`, remove `screenbuffer`
I know earlier I removed the gameScreen extern in favor of using
screenbuffer, but that was only to be consistent. After further
consideration, I have found that it's actually really stupid.
There's no reason to be accessing it through screenbuffer, and it's
probably an artifact of 2.0-2.2 passing stack-allocated otherwise-global
classes everywhere through function arguments. Also, it leads to stupid
bugs where screenbuffer could potentially be NULL, which has already
resulted in various annoying crashes in the past. Although those could
be fixed by simply initializing screenbuffer at the very top of main(),
but, why not just scrap the whole thing anyway?
So that's what I'm doing.
As a nice side effect, I've removed the transitive include of Screen.h
from Graphics.h. This could've been done already since it only includes
it for the pointer anyway, but it's still good to do it now.
2021-12-25 08:56:47 +01:00
switch ( gameScreen . scalingMode )
2020-11-13 01:45:51 +01:00
{
2021-12-26 08:05:14 +01:00
case SCALING_INTEGER :
2020-11-13 01:45:51 +01:00
graphics . Print ( - 1 , 85 , " Current mode: INTEGER " , tr , tg , tb , true ) ;
break ;
2021-12-26 08:05:14 +01:00
case SCALING_STRETCH :
2020-11-13 01:45:51 +01:00
graphics . Print ( - 1 , 85 , " Current mode: STRETCH " , tr , tg , tb , true ) ;
break ;
2021-12-26 08:05:14 +01:00
case SCALING_LETTERBOX :
2020-11-13 01:45:51 +01:00
default :
graphics . Print ( - 1 , 85 , " Current mode: LETTERBOX " , tr , tg , tb , true ) ;
break ;
2020-04-16 04:52:49 +02:00
}
2021-12-26 07:55:55 +01:00
}
if ( game . currentmenuoption = = offset + 2 & & ! gameScreen . isForcedFullscreen ( ) )
{
2020-06-30 22:30:59 +02:00
graphics . bigprint ( - 1 , 30 , " Resize to Nearest " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Resize to the nearest window size " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " that is of an integer multiple. " , tr , tg , tb , true ) ;
Extern `gameScreen`, remove `screenbuffer`
I know earlier I removed the gameScreen extern in favor of using
screenbuffer, but that was only to be consistent. After further
consideration, I have found that it's actually really stupid.
There's no reason to be accessing it through screenbuffer, and it's
probably an artifact of 2.0-2.2 passing stack-allocated otherwise-global
classes everywhere through function arguments. Also, it leads to stupid
bugs where screenbuffer could potentially be NULL, which has already
resulted in various annoying crashes in the past. Although those could
be fixed by simply initializing screenbuffer at the very top of main(),
but, why not just scrap the whole thing anyway?
So that's what I'm doing.
As a nice side effect, I've removed the transitive include of Screen.h
from Graphics.h. This could've been done already since it only includes
it for the pointer anyway, but it's still good to do it now.
2021-12-25 08:56:47 +01:00
if ( ! gameScreen . isWindowed )
2020-06-30 22:30:59 +02:00
{
graphics . Print ( - 1 , 95 , " You must be in windowed mode " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 105 , " to use this option. " , tr , tg , tb , true ) ;
}
2021-12-26 07:55:55 +01:00
}
if ( gameScreen . isForcedFullscreen ( ) )
{
- - offset ;
}
if ( game . currentmenuoption = = offset + 3 )
{
2020-04-16 04:52:49 +02:00
graphics . bigprint ( - 1 , 30 , " Toggle Filter " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Change to nearest/linear filter. " , tr , tg , tb , true ) ;
Extern `gameScreen`, remove `screenbuffer`
I know earlier I removed the gameScreen extern in favor of using
screenbuffer, but that was only to be consistent. After further
consideration, I have found that it's actually really stupid.
There's no reason to be accessing it through screenbuffer, and it's
probably an artifact of 2.0-2.2 passing stack-allocated otherwise-global
classes everywhere through function arguments. Also, it leads to stupid
bugs where screenbuffer could potentially be NULL, which has already
resulted in various annoying crashes in the past. Although those could
be fixed by simply initializing screenbuffer at the very top of main(),
but, why not just scrap the whole thing anyway?
So that's what I'm doing.
As a nice side effect, I've removed the transitive include of Screen.h
from Graphics.h. This could've been done already since it only includes
it for the pointer anyway, but it's still good to do it now.
2021-12-25 08:56:47 +01:00
if ( gameScreen . isFiltered )
2020-11-13 01:45:51 +01:00
{
graphics . Print ( - 1 , 85 , " Current mode: LINEAR " , tr , tg , tb , true ) ;
}
else
{
graphics . Print ( - 1 , 85 , " Current mode: NEAREST " , tr , tg , tb , true ) ;
2020-04-16 04:52:49 +02:00
}
2021-12-26 07:55:55 +01:00
}
2020-04-16 04:52:49 +02:00
2021-12-26 07:55:55 +01:00
if ( game . currentmenuoption = = offset + 4 )
{
2020-04-16 04:52:49 +02:00
graphics . bigprint ( - 1 , 30 , " Analogue Mode " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " There is nothing wrong with your " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " television set. Do not attempt to " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " adjust the picture. " , tr , tg , tb , true ) ;
2021-12-26 07:55:55 +01:00
}
if ( game . currentmenuoption = = offset + 5 )
{
2020-05-04 22:19:47 +02:00
graphics . bigprint ( - 1 , 30 , " Toggle VSync " , tr , tg , tb , true ) ;
2021-09-15 05:23:22 +02:00
/* FIXME: Upgrade to SDL 2.0.18 and remove this ifdef when it releases! */
# if SDL_VERSION_ATLEAST(2, 0, 17)
2020-05-04 22:19:47 +02:00
graphics . Print ( - 1 , 65 , " Turn VSync on or off. " , tr , tg , tb , true ) ;
2021-09-15 05:23:22 +02:00
# else
graphics . Print ( - 1 , 65 , " Your SDL version is too old! " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " Edit the config file. " , tr , tg , tb , true ) ;
2020-07-08 20:43:04 +02:00
# endif
2020-05-04 22:19:47 +02:00
Extern `gameScreen`, remove `screenbuffer`
I know earlier I removed the gameScreen extern in favor of using
screenbuffer, but that was only to be consistent. After further
consideration, I have found that it's actually really stupid.
There's no reason to be accessing it through screenbuffer, and it's
probably an artifact of 2.0-2.2 passing stack-allocated otherwise-global
classes everywhere through function arguments. Also, it leads to stupid
bugs where screenbuffer could potentially be NULL, which has already
resulted in various annoying crashes in the past. Although those could
be fixed by simply initializing screenbuffer at the very top of main(),
but, why not just scrap the whole thing anyway?
So that's what I'm doing.
As a nice side effect, I've removed the transitive include of Screen.h
from Graphics.h. This could've been done already since it only includes
it for the pointer anyway, but it's still good to do it now.
2021-12-25 08:56:47 +01:00
if ( ! gameScreen . vsync )
2020-05-04 22:19:47 +02:00
{
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 85 , " Current mode: VSYNC OFF " , tr / 2 , tg / 2 , tb / 2 , true ) ;
2020-05-04 22:19:47 +02:00
}
else
{
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 85 , " Current mode: VSYNC ON " , tr , tg , tb , true ) ;
2020-05-04 22:19:47 +02:00
}
2020-04-16 04:52:49 +02:00
}
2020-04-17 00:19:17 +02:00
break ;
2021-12-26 07:55:55 +01:00
}
2021-04-12 00:18:35 +02:00
case Menu : : audiooptions :
switch ( game . currentmenuoption )
{
case 0 :
2021-04-12 02:43:17 +02:00
graphics . bigprint ( - 1 , 30 , " Music Volume " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Change the volume of the music. " , tr , tg , tb , true ) ;
volumesliderrender ( ) ;
2021-04-12 00:18:35 +02:00
break ;
case 1 :
2021-04-12 02:43:17 +02:00
graphics . bigprint ( - 1 , 30 , " Sound Volume " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Change the volume of sound effects. " , tr , tg , tb , true ) ;
volumesliderrender ( ) ;
2021-04-12 00:18:35 +02:00
break ;
case 2 :
if ( ! music . mmmmmm )
{
break ;
}
{
2021-09-13 06:39:07 +02:00
char buffer [ SCREEN_WIDTH_CHARS + 1 ] ;
2021-04-12 00:18:35 +02:00
char soundtrack [ 6 + 1 ] ;
char letter ;
if ( music . usingmmmmmm )
{
letter = ' M ' ;
}
else
{
letter = ' P ' ;
}
VVV_fillstring ( soundtrack , sizeof ( soundtrack ) , letter ) ;
SDL_snprintf ( buffer , sizeof ( buffer ) , " Current soundtrack: %s " , soundtrack ) ;
graphics . bigprint ( - 1 , 30 , " Soundtrack " , tr , tg , tb , true ) ;
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 65 , " Toggle between MMMMMM and PPPPPP. " , tr , tg , tb , true ) ;
2021-04-12 00:18:35 +02:00
graphics . Print ( - 1 , 85 , buffer , tr , tg , tb , true ) ;
break ;
}
}
break ;
2020-04-17 00:19:17 +02:00
case Menu : : credits :
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 50 , " VVVVVV is a game by " , tr , tg , tb , true ) ;
graphics . bigprint ( 40 , 65 , " Terry Cavanagh " , tr , tg , tb , true , 2 ) ;
2020-01-01 21:29:24 +01:00
2021-09-11 11:12:03 +02:00
graphics . drawimagecol ( 7 , - 1 , 86 , true ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 120 , " and features music by " , tr , tg , tb , true ) ;
graphics . bigprint ( 40 , 135 , " Magnus P~lsson " , tr , tg , tb , true , 2 ) ;
2021-09-11 11:12:03 +02:00
graphics . drawimagecol ( 8 , - 1 , 156 , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : credits2 :
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 50 , " Roomnames are by " , tr , tg , tb , true ) ;
graphics . bigprint ( 40 , 65 , " Bennett Foddy " , tr , tg , tb , true ) ;
2021-09-11 11:12:03 +02:00
graphics . drawimagecol ( 9 , - 1 , 86 , true ) ;
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 110 , " C++ version by " , tr , tg , tb , true ) ;
graphics . bigprint ( 40 , 125 , " Simon Roth " , tr , tg , tb , true ) ;
graphics . bigprint ( 40 , 145 , " Ethan Lee " , tr , tg , tb , true ) ;
2021-09-01 08:19:25 +02:00
graphics . bigprint ( 40 , 165 , " Misa Kai " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : credits25 :
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 40 , " Beta Testing by " , tr , tg , tb , true ) ;
graphics . bigprint ( 40 , 55 , " Sam Kaplan " , tr , tg , tb , true ) ;
graphics . bigprint ( 40 , 75 , " Pauli Kohberger " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 130 , " Ending Picture by " , tr , tg , tb , true ) ;
graphics . bigprint ( 40 , 145 , " Pauli Kohberger " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : credits3 :
2020-04-16 01:29:54 +02:00
{
graphics . Print ( - 1 , 20 , " VVVVVV is supported by " , tr , tg , tb , true ) ;
graphics . Print ( 40 , 30 , " the following patrons " , tr , tg , tb , true ) ;
int startidx = game . current_credits_list_index ;
Remove `VVV_min/max` in favor of `SDL_min/max`
VVV_min/max are functions that only operate on ints, and SDL_min/max are
macros that operate on any type but double-evaluate everything.
I know I more-or-less said earlier that SDL_min/max were dumb but I've
changed my mind and think it's better to use them, taking care to make
sure you don't double-evaluate, rather than trying to generate your own
litany of functions with either your own hand-rolled generation macros,
C++ templates, C11 generics, or GCC extensions (that last one you'd
technically use in a macro but it doesn't really matter), all of which
have more downsides than just not double-evaluating.
And the upside of not double-evaluating is that you're disencouraged
from having really complicated single-line min/max expressions and
encouraged to precompute the values beforehand anyway so the final
min/max is more readable. And furthermore you'll notice when you
yourself end up doing double-evaluations anyway. I removed a couple
instances of Graphics::len() being double-evaluated in this commit (as
well as cleaned up some other min/max-using code). Although the only
downside to those double-evaluations was unnecessary computation,
rather than checking the wrong result or having multiple side effects,
thankfully, it's still good to minimize double-evaluations where
possible.
2021-12-23 01:43:31 +01:00
int endidx = SDL_min ( startidx + 9 , ( int ) SDL_arraysize ( Credits : : superpatrons ) ) ;
2020-04-16 01:29:54 +02:00
int xofs = 80 - 16 ;
int yofs = 40 + 20 ;
for ( int i = startidx ; i < endidx ; + + i )
2020-01-01 21:29:24 +01:00
{
Turn (super)patrons/githubfriends into arrays & move them to new file
So, originally, I wanted to keep them on Game, but it turns out that if
I initialize it in Game.cpp, the compiler will complain that other files
won't know what's actually inside the array. To do that, I'd have to
initialize it in Game.h. But I don't want to initialize it in Game.h
because that'd mean recompiling a lot of unnecessary files whenever
someone gets added to the credits.
So, I moved all the patrons, superpatrons, and GitHub contributors to a
new file, Credits.h, which only contains the list (and the credits max
position calculation). That way, whenever someone gets added, only the
minimal amount of files need to be recompiled.
2020-07-03 12:13:15 +02:00
graphics . Print ( xofs , yofs , Credits : : superpatrons [ i ] , tr , tg , tb ) ;
2020-04-16 01:29:54 +02:00
xofs + = 4 ;
yofs + = 14 ;
2020-01-01 21:29:24 +01:00
}
2020-04-17 00:19:17 +02:00
break ;
2020-04-16 01:29:54 +02:00
}
2020-04-17 00:19:17 +02:00
case Menu : : credits4 :
2020-04-16 01:29:54 +02:00
{
graphics . Print ( - 1 , 20 , " and also by " , tr , tg , tb , true ) ;
int startidx = game . current_credits_list_index ;
Remove `VVV_min/max` in favor of `SDL_min/max`
VVV_min/max are functions that only operate on ints, and SDL_min/max are
macros that operate on any type but double-evaluate everything.
I know I more-or-less said earlier that SDL_min/max were dumb but I've
changed my mind and think it's better to use them, taking care to make
sure you don't double-evaluate, rather than trying to generate your own
litany of functions with either your own hand-rolled generation macros,
C++ templates, C11 generics, or GCC extensions (that last one you'd
technically use in a macro but it doesn't really matter), all of which
have more downsides than just not double-evaluating.
And the upside of not double-evaluating is that you're disencouraged
from having really complicated single-line min/max expressions and
encouraged to precompute the values beforehand anyway so the final
min/max is more readable. And furthermore you'll notice when you
yourself end up doing double-evaluations anyway. I removed a couple
instances of Graphics::len() being double-evaluated in this commit (as
well as cleaned up some other min/max-using code). Although the only
downside to those double-evaluations was unnecessary computation,
rather than checking the wrong result or having multiple side effects,
thankfully, it's still good to minimize double-evaluations where
possible.
2021-12-23 01:43:31 +01:00
int endidx = SDL_min ( startidx + 14 , ( int ) SDL_arraysize ( Credits : : patrons ) ) ;
2020-04-16 01:29:54 +02:00
int maxheight = 10 * 14 ;
int totalheight = ( endidx - startidx ) * 10 ;
int emptyspace = maxheight - totalheight ;
int yofs = 40 + ( emptyspace / 2 ) ;
for ( int i = startidx ; i < endidx ; + + i )
2020-01-01 21:29:24 +01:00
{
Turn (super)patrons/githubfriends into arrays & move them to new file
So, originally, I wanted to keep them on Game, but it turns out that if
I initialize it in Game.cpp, the compiler will complain that other files
won't know what's actually inside the array. To do that, I'd have to
initialize it in Game.h. But I don't want to initialize it in Game.h
because that'd mean recompiling a lot of unnecessary files whenever
someone gets added to the credits.
So, I moved all the patrons, superpatrons, and GitHub contributors to a
new file, Credits.h, which only contains the list (and the credits max
position calculation). That way, whenever someone gets added, only the
minimal amount of files need to be recompiled.
2020-07-03 12:13:15 +02:00
graphics . Print ( 80 , yofs , Credits : : patrons [ i ] , tr , tg , tb ) ;
2020-04-16 01:29:54 +02:00
yofs + = 10 ;
2020-01-01 21:29:24 +01:00
}
2020-04-17 00:19:17 +02:00
break ;
2020-04-16 01:29:54 +02:00
}
2020-04-17 00:19:17 +02:00
case Menu : : credits5 :
2020-04-16 01:29:54 +02:00
{
graphics . Print ( - 1 , 20 , " With contributions on " , tr , tg , tb , true ) ;
graphics . Print ( 40 , 30 , " GitHub from " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
int startidx = game . current_credits_list_index ;
Remove `VVV_min/max` in favor of `SDL_min/max`
VVV_min/max are functions that only operate on ints, and SDL_min/max are
macros that operate on any type but double-evaluate everything.
I know I more-or-less said earlier that SDL_min/max were dumb but I've
changed my mind and think it's better to use them, taking care to make
sure you don't double-evaluate, rather than trying to generate your own
litany of functions with either your own hand-rolled generation macros,
C++ templates, C11 generics, or GCC extensions (that last one you'd
technically use in a macro but it doesn't really matter), all of which
have more downsides than just not double-evaluating.
And the upside of not double-evaluating is that you're disencouraged
from having really complicated single-line min/max expressions and
encouraged to precompute the values beforehand anyway so the final
min/max is more readable. And furthermore you'll notice when you
yourself end up doing double-evaluations anyway. I removed a couple
instances of Graphics::len() being double-evaluated in this commit (as
well as cleaned up some other min/max-using code). Although the only
downside to those double-evaluations was unnecessary computation,
rather than checking the wrong result or having multiple side effects,
thankfully, it's still good to minimize double-evaluations where
possible.
2021-12-23 01:43:31 +01:00
int endidx = SDL_min ( startidx + 9 , ( int ) SDL_arraysize ( Credits : : githubfriends ) ) ;
2020-02-12 05:45:58 +01:00
2020-04-16 01:29:54 +02:00
int maxheight = 14 * 9 ;
int totalheight = ( endidx - startidx ) * 14 ;
int emptyspace = maxheight - totalheight ;
2020-02-12 05:45:58 +01:00
2021-03-31 08:43:05 +02:00
int xofs , yofs ;
2021-09-01 08:19:25 +02:00
xofs = 80 - 16 ;
yofs = 40 + 20 + ( emptyspace / 2 ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
for ( int i = startidx ; i < endidx ; + + i )
{
Turn (super)patrons/githubfriends into arrays & move them to new file
So, originally, I wanted to keep them on Game, but it turns out that if
I initialize it in Game.cpp, the compiler will complain that other files
won't know what's actually inside the array. To do that, I'd have to
initialize it in Game.h. But I don't want to initialize it in Game.h
because that'd mean recompiling a lot of unnecessary files whenever
someone gets added to the credits.
So, I moved all the patrons, superpatrons, and GitHub contributors to a
new file, Credits.h, which only contains the list (and the credits max
position calculation). That way, whenever someone gets added, only the
minimal amount of files need to be recompiled.
2020-07-03 12:13:15 +02:00
graphics . Print ( xofs , yofs , Credits : : githubfriends [ i ] , tr , tg , tb ) ;
2020-04-16 01:29:54 +02:00
xofs + = 4 ;
yofs + = 14 ;
}
2020-04-17 00:19:17 +02:00
break ;
2020-04-16 01:29:54 +02:00
}
2020-04-17 00:19:17 +02:00
case Menu : : credits6 :
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 20 , " and thanks also to: " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . bigprint ( 80 , 60 , " You! " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( 80 , 100 , " Your support makes it possible " , tr , tg , tb , true ) ;
graphics . Print ( 80 , 110 , " for me to continue making the " , tr , tg , tb , true ) ;
graphics . Print ( 80 , 120 , " games I want to make, now " , tr , tg , tb , true ) ;
graphics . Print ( 80 , 130 , " and into the future. " , tr , tg , tb , true ) ;
2020-02-12 05:45:58 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( 80 , 150 , " Thank you! " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : setinvincibility :
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 100 , " Are you sure you want to " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 110 , " enable invincibility? " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
2020-04-17 01:02:01 +02:00
case Menu : : setslowdown :
2021-08-20 02:17:36 +02:00
graphics . bigprint ( - 1 , 30 , " Game Speed " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Select a new game speed below. " , tr , tg , tb , true ) ;
2020-11-13 02:05:18 +01:00
drawslowdowntext ( ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : newgamewarning :
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 100 , " Are you sure? This will " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 110 , " delete your current saves... " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : cleardatamenu :
2021-08-12 05:54:02 +02:00
case Menu : : clearcustomdatamenu :
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 100 , " Are you sure you want to " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 110 , " delete all your saved data? " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
2021-08-12 05:26:58 +02:00
case Menu : : deletequicklevel :
graphics . Print ( - 1 , 100 , " Are you sure you want to " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 110 , " delete your quicksave? " , tr , tg , tb , true ) ;
break ;
2020-04-17 00:19:17 +02:00
case Menu : : startnodeathmode :
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 45 , " Good luck! " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 80 , " You cannot save in this mode. " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 100 , " Would you like to disable the " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 112 , " cutscenes during the game? " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : controller :
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " Game Pad " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 55 , " Change controller options. " , tr , tg , tb , true ) ;
2020-04-16 05:10:11 +02:00
switch ( game . currentmenuoption )
2020-04-16 01:29:54 +02:00
{
2020-04-16 05:10:11 +02:00
case 0 :
2020-11-13 02:16:18 +01:00
switch ( key . sensitivity )
2020-02-12 05:45:58 +01:00
{
2020-04-16 01:29:54 +02:00
case 0 :
2021-04-19 08:23:44 +02:00
graphics . Print ( - 1 , 75 , " Low Medium High " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " [].................. " , tr , tg , tb , true ) ;
2020-04-16 01:29:54 +02:00
break ;
case 1 :
2021-04-19 08:23:44 +02:00
graphics . Print ( - 1 , 75 , " Low Medium High " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " .....[]............. " , tr , tg , tb , true ) ;
2020-04-16 01:29:54 +02:00
break ;
case 2 :
2021-04-19 08:23:44 +02:00
graphics . Print ( - 1 , 75 , " Low Medium High " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " .........[]......... " , tr , tg , tb , true ) ;
2020-04-16 01:29:54 +02:00
break ;
case 3 :
2021-04-19 08:23:44 +02:00
graphics . Print ( - 1 , 75 , " Low Medium High " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " .............[]..... " , tr , tg , tb , true ) ;
2020-04-16 01:29:54 +02:00
break ;
case 4 :
2021-04-19 08:23:44 +02:00
graphics . Print ( - 1 , 75 , " Low Medium High " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " ..................[] " , tr , tg , tb , true ) ;
2020-04-16 01:29:54 +02:00
break ;
2020-02-12 05:45:58 +01:00
}
2020-04-16 05:10:11 +02:00
break ;
case 1 :
case 2 :
case 3 :
2020-08-09 00:41:59 +02:00
case 4 :
2021-04-19 08:23:44 +02:00
case 5 :
graphics . Print ( - 1 , 75 , " Flip is bound to: " + std : : string ( help . GCString ( game . controllerButton_flip ) ) , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " Enter is bound to: " + std : : string ( help . GCString ( game . controllerButton_map ) ) , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 95 , " Menu is bound to: " + std : : string ( help . GCString ( game . controllerButton_esc ) ) , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 105 , " Restart is bound to: " + std : : string ( help . GCString ( game . controllerButton_restart ) ) , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 115 , " Interact is bound to: " + std : : string ( help . GCString ( game . controllerButton_interact ) ) , tr , tg , tb , true ) ;
2020-04-16 05:10:11 +02:00
break ;
2020-04-16 01:29:54 +02:00
}
2020-01-01 21:29:24 +01:00
2020-02-12 05:45:58 +01:00
2020-06-30 22:06:19 +02:00
break ;
2021-04-09 17:53:55 +02:00
case Menu : : speedrunneroptions :
switch ( game . currentmenuoption )
{
case 0 :
graphics . bigprint ( - 1 , 30 , " Glitchrunner Mode " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Re-enable glitches that existed " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " in previous versions of the game. " , tr , tg , tb , true ) ;
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
drawglitchrunnertext ( ) ;
2021-04-09 17:53:55 +02:00
break ;
case 1 :
graphics . bigprint ( - 1 , 30 , " Input Delay " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Re-enable the 1-frame input delay " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " from previous versions of the game. " , tr , tg , tb , true ) ;
if ( game . inputdelay )
{
graphics . Print ( - 1 , 95 , " Input delay is ON " , tr , tg , tb , true ) ;
}
else
{
graphics . Print ( - 1 , 95 , " Input delay is OFF " , tr / 2 , tg / 2 , tb / 2 , true ) ;
}
break ;
case 2 :
2021-04-19 08:23:44 +02:00
{
2021-09-13 06:39:07 +02:00
char buffer [ SCREEN_WIDTH_CHARS + 1 ] ;
2021-04-19 08:23:44 +02:00
const char * button ;
graphics . bigprint ( - 1 , 30 , " Interact Button " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Toggle whether you interact " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " with prompts using ENTER or E. " , tr , tg , tb , true ) ;
if ( game . separate_interact )
{
button = " E " ;
}
else
{
button = " ENTER " ;
}
SDL_snprintf ( buffer , sizeof ( buffer ) , " Interact button: %s " , button ) ;
graphics . Print ( - 1 , 95 , buffer , tr , tg , tb , true ) ;
break ;
}
case 3 :
2021-04-09 17:53:55 +02:00
graphics . bigprint ( - 1 , 30 , " Fake Load Screen " , tr , tg , tb , true ) ;
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 65 , " Disable the fake loading screen " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " which appears on game launch. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
if ( game . skipfakeload )
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 95 , " Fake loading screen is OFF " , tr / 2 , tg / 2 , tb / 2 , true ) ;
2021-04-09 17:53:55 +02:00
else
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 95 , " Fake loading screen is ON " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
break ;
2021-08-05 23:31:20 +02:00
case 4 :
2021-08-20 02:17:36 +02:00
graphics . bigprint ( - 1 , 30 , " In-Game Timer " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Toggle the in-game timer " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " outside of time trials. " , tr , tg , tb , true ) ;
2021-08-05 23:31:20 +02:00
if ( game . showingametimer )
{
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 95 , " In-Game Timer is ON " , tr , tg , tb , true ) ;
2021-08-06 00:04:18 +02:00
}
else
2021-08-05 23:31:20 +02:00
{
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 95 , " In-Game Timer is OFF " , tr / 2 , tg / 2 , tb / 2 , true ) ;
2021-08-05 23:31:20 +02:00
}
break ;
2021-04-09 17:53:55 +02:00
}
break ;
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
case Menu : : setglitchrunner :
graphics . bigprint ( - 1 , 30 , " Glitchrunner Mode " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Select a new glitchrunner " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " version below. " , tr , tg , tb , true ) ;
drawglitchrunnertext ( ) ;
break ;
2020-06-30 22:06:19 +02:00
case Menu : : advancedoptions :
switch ( game . currentmenuoption )
{
case 0 :
graphics . bigprint ( - 1 , 30 , " Unfocus Pause " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Toggle if the game will pause " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " when the window is unfocused. " , tr , tg , tb , true ) ;
if ( game . disablepause )
{
graphics . Print ( - 1 , 95 , " Unfocus pause is OFF " , tr / 2 , tg / 2 , tb / 2 , true ) ;
}
else
{
graphics . Print ( - 1 , 95 , " Unfocus pause is ON " , tr , tg , tb , true ) ;
}
break ;
2021-04-17 07:00:33 +02:00
case 1 :
2021-08-05 21:20:05 +02:00
graphics . bigprint ( - 1 , 30 , " Unfocus Audio " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Toggle if the audio will pause " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " when the window is unfocused. " , tr , tg , tb , true ) ;
if ( game . disableaudiopause )
{
graphics . Print ( - 1 , 95 , " Unfocus audio pause is OFF " , tr / 2 , tg / 2 , tb / 2 , true ) ;
}
else
{
graphics . Print ( - 1 , 95 , " Unfocus audio pause is ON " , tr , tg , tb , true ) ;
}
break ;
case 2 :
2020-06-30 22:06:19 +02:00
graphics . bigprint ( - 1 , 30 , " Room Name BG " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Lets you see through what is behind " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " the name at the bottom of the screen. " , tr , tg , tb , true ) ;
if ( graphics . translucentroomname )
graphics . Print ( - 1 , 95 , " Room name background is TRANSLUCENT " , tr / 2 , tg / 2 , tb / 2 , true ) ;
else
graphics . Print ( - 1 , 95 , " Room name background is OPAQUE " , tr , tg , tb , true ) ;
break ;
}
2020-04-17 00:19:17 +02:00
break ;
case Menu : : accessibility :
2021-04-09 17:53:55 +02:00
{
2021-04-09 18:00:52 +02:00
# ifdef MAKEANDPLAY
# define OFFSET 0
# else
# define OFFSET 1
# endif
switch ( game . currentmenuoption )
{
2021-04-09 12:09:12 +02:00
# if !defined(MAKEANDPLAY)
2021-04-09 18:00:52 +02:00
case 0 :
2021-04-09 17:53:55 +02:00
graphics . bigprint ( - 1 , 30 , " Unlock Play Modes " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Unlock parts of the game normally " , tr , tg , tb , true ) ;
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 75 , " unlocked as you progress. " , tr , tg , tb , true ) ;
2021-04-09 18:00:52 +02:00
break ;
2021-04-09 12:09:12 +02:00
# endif
2021-04-09 18:00:52 +02:00
case OFFSET + 0 :
2021-08-20 02:17:36 +02:00
graphics . bigprint ( - 1 , 30 , " Invincibility " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Explore the game freely without " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " dying. (Can cause glitches.) " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
if ( map . invincibility )
{
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 95 , " Invincibility is ON. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
}
else
{
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 95 , " Invincibility is OFF. " , tr / 2 , tg / 2 , tb / 2 , true ) ;
2021-04-09 17:53:55 +02:00
}
2021-04-09 18:00:52 +02:00
break ;
case OFFSET + 1 :
2021-08-20 02:17:36 +02:00
graphics . bigprint ( - 1 , 30 , " Slowdown " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Reduce the game speed. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
drawslowdowntext ( ) ;
2021-04-09 18:00:52 +02:00
break ;
case OFFSET + 2 :
2021-08-20 02:17:36 +02:00
graphics . bigprint ( - 1 , 30 , " Backgrounds " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Disable animated backgrounds in menus " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " and during gameplay. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
if ( ! game . colourblindmode )
{
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 95 , " Backgrounds are ON. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
}
else
{
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 95 , " Backgrounds are OFF. " , tr / 2 , tg / 2 , tb / 2 , true ) ;
2021-04-09 17:53:55 +02:00
}
2021-04-09 18:00:52 +02:00
break ;
case OFFSET + 3 :
2021-08-20 02:17:36 +02:00
graphics . bigprint ( - 1 , 30 , " Screen Effects " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Disables screen shakes and flashes. " , tr , tg , tb , true ) ;
2021-04-09 17:53:55 +02:00
if ( ! game . noflashingmode )
{
graphics . Print ( - 1 , 85 , " Screen Effects are ON. " , tr , tg , tb , true ) ;
}
else
{
graphics . Print ( - 1 , 85 , " Screen Effects are OFF. " , tr / 2 , tg / 2 , tb / 2 , true ) ;
}
2021-04-09 18:00:52 +02:00
break ;
case OFFSET + 4 :
2021-06-13 00:19:15 +02:00
{
const char * text ;
2021-08-20 02:17:36 +02:00
graphics . bigprint ( - 1 , 30 , " Text Outline " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Disables outline on game text. " , tr , tg , tb , true ) ;
2021-06-13 00:19:15 +02:00
FillRect ( graphics . backBuffer , 0 , 84 , 320 , 10 , tr , tg , tb ) ;
2021-04-09 17:53:55 +02:00
if ( ! graphics . notextoutline )
{
2021-06-13 00:19:15 +02:00
text = " Text outlines are ON. " ;
2021-04-09 17:53:55 +02:00
}
else
{
2021-06-13 00:19:15 +02:00
text = " Text outlines are OFF. " ;
2021-04-09 17:53:55 +02:00
}
2021-06-13 00:19:15 +02:00
graphics . bprint ( - 1 , 85 , text , 255 , 255 , 255 , true ) ;
2021-04-09 18:00:52 +02:00
break ;
2021-04-09 17:53:55 +02:00
}
2021-06-13 00:19:15 +02:00
}
2021-04-09 17:53:55 +02:00
break ;
2021-04-09 18:00:52 +02:00
# undef OFFSET
2021-04-09 17:53:55 +02:00
}
2020-04-17 00:19:17 +02:00
case Menu : : playint1 :
case Menu : : playint2 :
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 65 , " Who do you want to play " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " the level with? " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : playmodes :
2020-04-16 05:10:11 +02:00
switch ( game . currentmenuoption )
2020-04-02 23:19:15 +02:00
{
2020-04-16 05:10:11 +02:00
case 0 :
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " Time Trials " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Replay any level in the game in " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " a competitive time trial mode. " , tr , tg , tb , true ) ;
2021-05-04 03:29:23 +02:00
if ( game . nocompetitive ( ) )
2020-04-02 23:19:15 +02:00
{
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 105 , " Time Trials are not available " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 115 , " with slowdown or invincibility. " , tr , tg , tb , true ) ;
2020-04-02 23:19:15 +02:00
}
2020-04-16 05:10:11 +02:00
break ;
case 1 :
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " Intermissions " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Replay the intermission levels. " , tr , tg , tb , true ) ;
if ( ! game . unlock [ 15 ] & & ! game . unlock [ 16 ] )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 95 , " TO UNLOCK: Complete the " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 105 , " intermission levels in-game. " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-16 05:10:11 +02:00
break ;
case 2 :
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " No Death Mode " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Play the entire game " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " without dying once. " , tr , tg , tb , true ) ;
2021-05-04 03:29:23 +02:00
if ( game . nocompetitive ( ) )
2020-01-01 21:29:24 +01:00
{
2020-04-16 05:45:43 +02:00
graphics . Print ( - 1 , 105 , " No Death Mode is not available " , tr , tg , tb , true ) ;
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 115 , " with slowdown or invincibility. " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-16 01:29:54 +02:00
else if ( ! game . unlock [ 17 ] )
2020-01-17 18:37:53 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 105 , " TO UNLOCK: Achieve an S-rank or " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 115 , " above in at least 4 time trials. " , tr , tg , tb , true ) ;
2020-01-17 18:37:53 +01:00
}
2020-04-16 05:10:11 +02:00
break ;
case 3 :
2020-06-30 05:45:57 +02:00
// WARNING: Partially duplicated in Menu::options
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " Flip Mode " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " Flip the entire game vertically. " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " Compatible with other game modes. " , tr , tg , tb , true ) ;
if ( game . unlock [ 18 ] )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
if ( graphics . setflipmode )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 105 , " Currently ENABLED! " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 105 , " Currently Disabled. " , tr / 2 , tg / 2 , tb / 2 , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-01-13 02:45:44 +01:00
}
2020-04-16 01:29:54 +02:00
else
2020-01-25 05:43:04 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 105 , " TO UNLOCK: Complete the game. " , tr , tg , tb , true ) ;
2020-01-25 05:43:04 +01:00
}
2020-04-16 05:10:11 +02:00
break ;
2020-01-01 21:29:24 +01:00
}
2020-04-17 00:19:17 +02:00
break ;
case Menu : : youwannaquit :
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 75 , " Are you sure you want to quit? " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : continuemenu :
2020-04-16 05:10:11 +02:00
switch ( game . currentmenuoption )
2020-01-01 21:29:24 +01:00
{
2020-04-16 05:10:11 +02:00
case 0 :
2020-08-03 00:11:58 +02:00
{
2020-04-16 01:29:54 +02:00
//Show teleporter save info
2021-09-04 00:26:57 +02:00
graphics . drawpixeltextbox ( 17 , 65 - 20 , 286 , 90 , 65 , 185 , 207 ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 20 , " Tele Save " , tr , tg , tb , true ) ;
graphics . Print ( 0 , 80 - 20 , game . tele_currentarea , 25 , 255 - ( help . glow / 2 ) , 255 - ( help . glow / 2 ) , true ) ;
for ( int i = 0 ; i < 6 ; i + + )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . drawcrewman ( 169 - ( 3 * 42 ) + ( i * 42 ) , 95 - 20 , i , game . tele_crewstats [ i ] , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-08-03 00:11:58 +02:00
graphics . Print ( 59 , 132 - 20 , game . tele_gametime , 255 - ( help . glow / 2 ) , 255 - ( help . glow / 2 ) , 255 - ( help . glow / 2 ) ) ;
2021-09-26 00:08:13 +02:00
const std : : string & trinketcount = help . number_words ( game . tele_trinkets ) ;
2020-08-03 00:11:58 +02:00
graphics . Print ( 262 - graphics . len ( trinketcount ) , 132 - 20 , trinketcount , 255 - ( help . glow / 2 ) , 255 - ( help . glow / 2 ) , 255 - ( help . glow / 2 ) ) ;
2020-01-01 21:29:24 +01:00
2020-08-03 00:11:58 +02:00
graphics . drawsprite ( 34 , 126 - 20 , 50 , graphics . col_clock ) ;
graphics . drawsprite ( 270 , 126 - 20 , 22 , graphics . col_trinket ) ;
2020-04-16 05:10:11 +02:00
break ;
2020-08-03 00:11:58 +02:00
}
2020-04-16 05:10:11 +02:00
case 1 :
2020-08-03 00:11:58 +02:00
{
2020-04-16 01:29:54 +02:00
//Show quick save info
2021-09-04 00:26:57 +02:00
graphics . drawpixeltextbox ( 17 , 65 - 20 , 286 , 90 , 65 , 185 , 207 ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 20 , " Quick Save " , tr , tg , tb , true ) ;
graphics . Print ( 0 , 80 - 20 , game . quick_currentarea , 25 , 255 - ( help . glow / 2 ) , 255 - ( help . glow / 2 ) , true ) ;
for ( int i = 0 ; i < 6 ; i + + )
{
graphics . drawcrewman ( 169 - ( 3 * 42 ) + ( i * 42 ) , 95 - 20 , i , game . quick_crewstats [ i ] , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-08-03 00:11:58 +02:00
graphics . Print ( 59 , 132 - 20 , game . quick_gametime , 255 - ( help . glow / 2 ) , 255 - ( help . glow / 2 ) , 255 - ( help . glow / 2 ) ) ;
2021-09-26 00:08:13 +02:00
const std : : string & trinketcount = help . number_words ( game . quick_trinkets ) ;
2020-08-03 00:11:58 +02:00
graphics . Print ( 262 - graphics . len ( trinketcount ) , 132 - 20 , trinketcount , 255 - ( help . glow / 2 ) , 255 - ( help . glow / 2 ) , 255 - ( help . glow / 2 ) ) ;
2020-04-16 01:29:54 +02:00
2020-08-03 00:11:58 +02:00
graphics . drawsprite ( 34 , 126 - 20 , 50 , graphics . col_clock ) ;
graphics . drawsprite ( 270 , 126 - 20 , 22 , graphics . col_trinket ) ;
2020-04-16 05:10:11 +02:00
break ;
2020-01-01 21:29:24 +01:00
}
2020-08-03 00:11:58 +02:00
}
2020-04-17 00:19:17 +02:00
break ;
case Menu : : gameover :
case Menu : : gameover2 :
2020-04-16 01:29:54 +02:00
{
graphics . bigprint ( - 1 , 25 , " GAME OVER " , tr , tg , tb , true , 3 ) ;
2021-01-08 01:18:07 +01:00
for ( size_t i = 0 ; i < SDL_arraysize ( game . ndmresultcrewstats ) ; i + + )
2020-01-01 21:29:24 +01:00
{
2021-01-08 01:18:07 +01:00
graphics . drawcrewman ( 169 - ( 3 * 42 ) + ( i * 42 ) , 68 , i , game . ndmresultcrewstats [ i ] , true ) ;
2020-04-16 01:29:54 +02:00
}
std : : string tempstring ;
2021-09-26 00:08:13 +02:00
tempstring = " You rescued " + help . number_words ( game . ndmresultcrewrescued ) + ( game . ndmresultcrewrescued = = 1 ? " crewmate " : " crewmates " ) ;
2020-04-16 01:29:54 +02:00
graphics . Print ( 0 , 100 , tempstring , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
2021-09-26 00:08:13 +02:00
tempstring = " and found " + help . number_words ( game . ndmresulttrinkets ) + ( game . ndmresulttrinkets = = 1 ? " trinket. " : " trinkets. " ) ;
2020-04-16 01:29:54 +02:00
graphics . Print ( 0 , 110 , tempstring , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
tempstring = " You managed to reach: " ;
graphics . Print ( 0 , 145 , tempstring , tr , tg , tb , true ) ;
2021-01-08 01:18:07 +01:00
graphics . Print ( 0 , 155 , game . ndmresulthardestroom , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
2021-01-08 01:18:07 +01:00
switch ( game . ndmresultcrewrescued )
2020-04-16 01:29:54 +02:00
{
2020-04-16 05:10:11 +02:00
case 1 :
2020-04-16 01:29:54 +02:00
tempstring = " Keep trying! You'll get there! " ;
2020-04-16 05:10:11 +02:00
break ;
case 2 :
2020-04-16 01:29:54 +02:00
tempstring = " Nice one! " ;
2020-04-16 05:10:11 +02:00
break ;
case 3 :
2020-04-16 01:29:54 +02:00
tempstring = " Wow! Congratulations! " ;
2020-04-16 05:10:11 +02:00
break ;
case 4 :
2020-04-16 01:29:54 +02:00
tempstring = " Incredible! " ;
2020-04-16 05:10:11 +02:00
break ;
case 5 :
2020-04-16 01:29:54 +02:00
tempstring = " Unbelievable! Well done! " ;
2020-04-16 05:10:11 +02:00
break ;
case 6 :
2020-04-16 01:29:54 +02:00
tempstring = " Er, how did you do that? " ;
2020-04-16 05:10:11 +02:00
break ;
2020-04-16 01:29:54 +02:00
}
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( 0 , 190 , tempstring , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
2020-04-16 01:29:54 +02:00
}
2020-04-17 00:19:17 +02:00
case Menu : : nodeathmodecomplete :
case Menu : : nodeathmodecomplete2 :
2020-04-16 01:29:54 +02:00
{
graphics . bigprint ( - 1 , 8 , " WOW " , tr , tg , tb , true , 4 ) ;
2021-01-08 01:18:07 +01:00
for ( size_t i = 0 ; i < SDL_arraysize ( game . ndmresultcrewstats ) ; i + + )
2020-01-01 21:29:24 +01:00
{
2021-01-08 01:18:07 +01:00
graphics . drawcrewman ( 169 - ( 3 * 42 ) + ( i * 42 ) , 68 , i , game . ndmresultcrewstats [ i ] , true ) ;
2020-04-16 01:29:54 +02:00
}
std : : string tempstring = " You rescued all the crewmates! " ;
graphics . Print ( 0 , 100 , tempstring , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
2021-09-26 02:06:59 +02:00
tempstring = " And you found " + help . number_words ( game . ndmresulttrinkets ) + " trinket " + ( game . ndmresulttrinkets = = 1 ? " " : " s " ) + " . " ;
2020-04-16 01:29:54 +02:00
graphics . Print ( 0 , 110 , tempstring , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( 0 , 160 , " A new trophy has been awarded and " , tr , tg , tb , true ) ;
graphics . Print ( 0 , 170 , " placed in the secret lab to " , tr , tg , tb , true ) ;
graphics . Print ( 0 , 180 , " acknowledge your achievement! " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
2020-04-16 01:29:54 +02:00
}
2020-04-17 00:19:17 +02:00
case Menu : : timetrialcomplete :
case Menu : : timetrialcomplete2 :
case Menu : : timetrialcomplete3 :
2020-04-16 01:29:54 +02:00
{
graphics . bigprint ( - 1 , 20 , " Results " , tr , tg , tb , true , 3 ) ;
2020-01-01 21:29:24 +01:00
2021-01-08 01:02:45 +01:00
std : : string tempstring = game . resulttimestring ( ) + " / " + game . timetstring ( game . timetrialresultpar ) + " .99 " ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . drawspritesetcol ( 30 , 80 - 15 , 50 , 22 ) ;
graphics . Print ( 65 , 80 - 15 , " TIME TAKEN: " , 255 , 255 , 255 ) ;
graphics . Print ( 65 , 90 - 15 , tempstring , tr , tg , tb ) ;
2021-01-08 01:02:45 +01:00
if ( game . timetrialresulttime < = game . timetrialresultpar )
2020-04-16 01:29:54 +02:00
{
graphics . Print ( 220 , 85 - 15 , " +1 Rank! " , 255 , 255 , 255 ) ;
}
2020-01-01 21:29:24 +01:00
2021-01-08 01:02:45 +01:00
tempstring = help . String ( game . timetrialresultdeaths ) ;
2020-04-16 01:29:54 +02:00
graphics . drawspritesetcol ( 30 - 4 , 80 + 20 - 4 , 12 , 22 ) ;
graphics . Print ( 65 , 80 + 20 , " NUMBER OF DEATHS: " , 255 , 255 , 255 ) ;
graphics . Print ( 65 , 90 + 20 , tempstring , tr , tg , tb ) ;
2021-01-08 01:02:45 +01:00
if ( game . timetrialresultdeaths = = 0 )
2020-04-16 01:29:54 +02:00
{
graphics . Print ( 220 , 85 + 20 , " +1 Rank! " , 255 , 255 , 255 ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-16 01:29:54 +02:00
2021-01-08 01:02:45 +01:00
tempstring = help . String ( game . timetrialresulttrinkets ) + " of " + help . String ( game . timetrialresultshinytarget ) ;
2020-04-16 01:29:54 +02:00
graphics . drawspritesetcol ( 30 , 80 + 55 , 22 , 22 ) ;
graphics . Print ( 65 , 80 + 55 , " SHINY TRINKETS: " , 255 , 255 , 255 ) ;
graphics . Print ( 65 , 90 + 55 , tempstring , tr , tg , tb ) ;
2021-01-08 01:02:45 +01:00
if ( game . timetrialresulttrinkets > = game . timetrialresultshinytarget )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . Print ( 220 , 85 + 55 , " +1 Rank! " , 255 , 255 , 255 ) ;
}
2020-01-01 21:29:24 +01:00
2020-04-16 06:53:36 +02:00
if ( game . currentmenuname = = Menu : : timetrialcomplete2 | | game . currentmenuname = = Menu : : timetrialcomplete3 )
2020-04-16 01:29:54 +02:00
{
graphics . bigprint ( 100 , 175 , " Rank: " , tr , tg , tb , false , 2 ) ;
}
2020-04-16 06:53:36 +02:00
if ( game . currentmenuname = = Menu : : timetrialcomplete3 )
2020-04-16 01:29:54 +02:00
{
switch ( game . timetrialrank )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
case 0 :
graphics . bigprint ( 195 , 165 , " B " , 255 , 255 , 255 , false , 4 ) ;
break ;
case 1 :
graphics . bigprint ( 195 , 165 , " A " , 255 , 255 , 255 , false , 4 ) ;
break ;
case 2 :
graphics . bigprint ( 195 , 165 , " S " , 255 , 255 , 255 , false , 4 ) ;
break ;
case 3 :
graphics . bigprint ( 195 , 165 , " V " , 255 , 255 , 255 , false , 4 ) ;
break ;
2020-01-01 21:29:24 +01:00
}
}
2020-04-17 00:19:17 +02:00
break ;
2020-04-16 01:29:54 +02:00
}
2020-04-17 00:19:17 +02:00
case Menu : : unlockmenutrials :
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " Unlock Time Trials " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 65 , " You can unlock each time " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " trial separately. " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : timetrials :
2020-04-16 05:10:11 +02:00
switch ( game . currentmenuoption )
2020-01-01 21:29:24 +01:00
{
2020-04-16 05:10:11 +02:00
case 0 :
2020-04-16 01:29:54 +02:00
if ( game . unlock [ 9 ] )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " Space Station 1 " , tr , tg , tb , true ) ;
if ( game . besttimes [ 0 ] = = - 1 )
{
graphics . Print ( - 1 , 75 , " Not yet attempted " , tr , tg , tb , true ) ;
}
else
{
graphics . Print ( 16 , 65 , " BEST TIME " , tr , tg , tb ) ;
graphics . Print ( 16 , 75 , " BEST SHINY " , tr , tg , tb ) ;
graphics . Print ( 16 , 85 , " BEST LIVES " , tr , tg , tb ) ;
graphics . Print ( 110 , 65 , game . timetstring ( game . besttimes [ 0 ] ) , tr , tg , tb ) ;
graphics . Print ( 110 , 75 , help . String ( game . besttrinkets [ 0 ] ) + " /2 " , tr , tg , tb ) ;
graphics . Print ( 110 , 85 , help . String ( game . bestlives [ 0 ] ) , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( 170 , 65 , " PAR TIME 1:15 " , tr , tg , tb ) ;
graphics . Print ( 170 , 85 , " Best Rank " , tr , tg , tb ) ;
switch ( game . bestrank [ 0 ] )
{
case 0 :
graphics . bigprint ( 275 , 82 , " B " , 225 , 225 , 225 ) ;
break ;
case 1 :
graphics . bigprint ( 275 , 82 , " A " , 225 , 225 , 225 ) ;
break ;
case 2 :
graphics . bigprint ( 275 , 82 , " S " , 225 , 225 , 225 ) ;
break ;
case 3 :
graphics . bigprint ( 275 , 82 , " V " , 225 , 225 , 225 ) ;
break ;
}
}
2020-01-01 21:29:24 +01:00
}
2020-04-16 01:29:54 +02:00
else
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " ??? " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 60 , " TO UNLOCK: " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " Rescue Violet " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " Find three trinkets " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-16 05:10:11 +02:00
break ;
case 1 :
2020-04-16 01:29:54 +02:00
if ( game . unlock [ 10 ] )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " The Laboratory " , tr , tg , tb , true ) ;
if ( game . besttimes [ 1 ] = = - 1 )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 75 , " Not yet attempted " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-16 01:29:54 +02:00
graphics . Print ( 16 , 65 , " BEST TIME " , tr , tg , tb ) ;
graphics . Print ( 16 , 75 , " BEST SHINY " , tr , tg , tb ) ;
graphics . Print ( 16 , 85 , " BEST LIVES " , tr , tg , tb ) ;
graphics . Print ( 110 , 65 , game . timetstring ( game . besttimes [ 1 ] ) , tr , tg , tb ) ;
graphics . Print ( 110 , 75 , help . String ( game . besttrinkets [ 1 ] ) + " /4 " , tr , tg , tb ) ;
graphics . Print ( 110 , 85 , help . String ( game . bestlives [ 1 ] ) , tr , tg , tb ) ;
graphics . Print ( 170 , 65 , " PAR TIME 2:45 " , tr , tg , tb ) ;
graphics . Print ( 170 , 85 , " Best Rank " , tr , tg , tb ) ;
switch ( game . bestrank [ 1 ] )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
case 0 :
graphics . bigprint ( 275 , 82 , " B " , 225 , 225 , 225 ) ;
break ;
case 1 :
graphics . bigprint ( 275 , 82 , " A " , 225 , 225 , 225 ) ;
break ;
case 2 :
graphics . bigprint ( 275 , 82 , " S " , 225 , 225 , 225 ) ;
break ;
case 3 :
graphics . bigprint ( 275 , 82 , " V " , 225 , 225 , 225 ) ;
break ;
2020-01-01 21:29:24 +01:00
}
}
2020-04-16 01:29:54 +02:00
2020-01-01 21:29:24 +01:00
}
2020-04-16 01:29:54 +02:00
else
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " ??? " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 60 , " TO UNLOCK: " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " Rescue Victoria " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " Find six trinkets " , tr , tg , tb , true ) ;
}
2020-04-16 05:10:11 +02:00
break ;
case 2 :
2020-04-16 01:29:54 +02:00
if ( game . unlock [ 11 ] )
{
graphics . bigprint ( - 1 , 30 , " The Tower " , tr , tg , tb , true ) ;
if ( game . besttimes [ 2 ] = = - 1 )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 75 , " Not yet attempted " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-16 01:29:54 +02:00
graphics . Print ( 16 , 65 , " BEST TIME " , tr , tg , tb ) ;
graphics . Print ( 16 , 75 , " BEST SHINY " , tr , tg , tb ) ;
graphics . Print ( 16 , 85 , " BEST LIVES " , tr , tg , tb ) ;
graphics . Print ( 110 , 65 , game . timetstring ( game . besttimes [ 2 ] ) , tr , tg , tb ) ;
graphics . Print ( 110 , 75 , help . String ( game . besttrinkets [ 2 ] ) + " /2 " , tr , tg , tb ) ;
graphics . Print ( 110 , 85 , help . String ( game . bestlives [ 2 ] ) , tr , tg , tb ) ;
graphics . Print ( 170 , 65 , " PAR TIME 1:45 " , tr , tg , tb ) ;
graphics . Print ( 170 , 85 , " Best Rank " , tr , tg , tb ) ;
switch ( game . bestrank [ 2 ] )
{
case 0 :
graphics . bigprint ( 275 , 82 , " B " , 225 , 225 , 225 ) ;
break ;
case 1 :
graphics . bigprint ( 275 , 82 , " A " , 225 , 225 , 225 ) ;
break ;
case 2 :
graphics . bigprint ( 275 , 82 , " S " , 225 , 225 , 225 ) ;
break ;
case 3 :
graphics . bigprint ( 275 , 82 , " V " , 225 , 225 , 225 ) ;
break ;
}
2020-01-01 21:29:24 +01:00
}
2020-04-16 01:29:54 +02:00
}
else
{
graphics . bigprint ( - 1 , 30 , " ??? " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 60 , " TO UNLOCK: " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " Rescue Vermilion " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " Find nine trinkets " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-16 05:10:11 +02:00
break ;
case 3 :
2020-04-16 01:29:54 +02:00
if ( game . unlock [ 12 ] )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " Space Station 2 " , tr , tg , tb , true ) ;
if ( game . besttimes [ 3 ] = = - 1 )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 75 , " Not yet attempted " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-16 01:29:54 +02:00
graphics . Print ( 16 , 65 , " BEST TIME " , tr , tg , tb ) ;
graphics . Print ( 16 , 75 , " BEST SHINY " , tr , tg , tb ) ;
graphics . Print ( 16 , 85 , " BEST LIVES " , tr , tg , tb ) ;
graphics . Print ( 110 , 65 , game . timetstring ( game . besttimes [ 3 ] ) , tr , tg , tb ) ;
graphics . Print ( 110 , 75 , help . String ( game . besttrinkets [ 3 ] ) + " /5 " , tr , tg , tb ) ;
graphics . Print ( 110 , 85 , help . String ( game . bestlives [ 3 ] ) , tr , tg , tb ) ;
graphics . Print ( 170 , 65 , " PAR TIME 3:20 " , tr , tg , tb ) ;
graphics . Print ( 170 , 85 , " Best Rank " , tr , tg , tb ) ;
switch ( game . bestrank [ 3 ] )
{
case 0 :
graphics . bigprint ( 275 , 82 , " B " , 225 , 225 , 225 ) ;
break ;
case 1 :
graphics . bigprint ( 275 , 82 , " A " , 225 , 225 , 225 ) ;
break ;
case 2 :
graphics . bigprint ( 275 , 82 , " S " , 225 , 225 , 225 ) ;
break ;
case 3 :
graphics . bigprint ( 275 , 82 , " V " , 225 , 225 , 225 ) ;
break ;
}
2020-01-01 21:29:24 +01:00
}
2020-04-16 01:29:54 +02:00
}
else
{
graphics . bigprint ( - 1 , 30 , " ??? " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 60 , " TO UNLOCK: " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " Rescue Vitellary " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " Find twelve trinkets " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-16 05:10:11 +02:00
break ;
case 4 :
2020-04-16 01:29:54 +02:00
if ( game . unlock [ 13 ] )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " The Warp Zone " , tr , tg , tb , true ) ;
if ( game . besttimes [ 4 ] = = - 1 )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 75 , " Not yet attempted " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-16 01:29:54 +02:00
graphics . Print ( 16 , 65 , " BEST TIME " , tr , tg , tb ) ;
graphics . Print ( 16 , 75 , " BEST SHINY " , tr , tg , tb ) ;
graphics . Print ( 16 , 85 , " BEST LIVES " , tr , tg , tb ) ;
graphics . Print ( 110 , 65 , game . timetstring ( game . besttimes [ 4 ] ) , tr , tg , tb ) ;
graphics . Print ( 110 , 75 , help . String ( game . besttrinkets [ 4 ] ) + " /1 " , tr , tg , tb ) ;
graphics . Print ( 110 , 85 , help . String ( game . bestlives [ 4 ] ) , tr , tg , tb ) ;
graphics . Print ( 170 , 65 , " PAR TIME 2:00 " , tr , tg , tb ) ;
graphics . Print ( 170 , 85 , " Best Rank " , tr , tg , tb ) ;
switch ( game . bestrank [ 4 ] )
{
case 0 :
graphics . bigprint ( 275 , 82 , " B " , 225 , 225 , 225 ) ;
break ;
case 1 :
graphics . bigprint ( 275 , 82 , " A " , 225 , 225 , 225 ) ;
break ;
case 2 :
graphics . bigprint ( 275 , 82 , " S " , 225 , 225 , 225 ) ;
break ;
case 3 :
graphics . bigprint ( 275 , 82 , " V " , 225 , 225 , 225 ) ;
break ;
}
2020-01-01 21:29:24 +01:00
}
2020-04-16 01:29:54 +02:00
}
else
{
graphics . bigprint ( - 1 , 30 , " ??? " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 60 , " TO UNLOCK: " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " Rescue Verdigris " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " Find fifteen trinkets " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-16 05:10:11 +02:00
break ;
case 5 :
2020-04-16 01:29:54 +02:00
if ( game . unlock [ 14 ] )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 30 , " The Final Level " , tr , tg , tb , true ) ;
if ( game . besttimes [ 5 ] = = - 1 )
2020-01-01 21:29:24 +01:00
{
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 75 , " Not yet attempted " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-16 01:29:54 +02:00
graphics . Print ( 16 , 65 , " BEST TIME " , tr , tg , tb ) ;
graphics . Print ( 16 , 75 , " BEST SHINY " , tr , tg , tb ) ;
graphics . Print ( 16 , 85 , " BEST LIVES " , tr , tg , tb ) ;
graphics . Print ( 110 , 65 , game . timetstring ( game . besttimes [ 5 ] ) , tr , tg , tb ) ;
graphics . Print ( 110 , 75 , help . String ( game . besttrinkets [ 5 ] ) + " /1 " , tr , tg , tb ) ;
graphics . Print ( 110 , 85 , help . String ( game . bestlives [ 5 ] ) , tr , tg , tb ) ;
graphics . Print ( 170 , 65 , " PAR TIME 2:15 " , tr , tg , tb ) ;
graphics . Print ( 170 , 85 , " Best Rank " , tr , tg , tb ) ;
switch ( game . bestrank [ 5 ] )
{
case 0 :
graphics . bigprint ( 275 , 82 , " B " , 225 , 225 , 225 ) ;
break ;
case 1 :
graphics . bigprint ( 275 , 82 , " A " , 225 , 225 , 225 ) ;
break ;
case 2 :
graphics . bigprint ( 275 , 82 , " S " , 225 , 225 , 225 ) ;
break ;
case 3 :
graphics . bigprint ( 275 , 82 , " V " , 225 , 225 , 225 ) ;
break ;
}
2020-01-01 21:29:24 +01:00
}
2020-04-16 01:29:54 +02:00
}
else
{
graphics . bigprint ( - 1 , 30 , " ??? " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 60 , " TO UNLOCK: " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " Complete the game " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " Find eighteen trinkets " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-16 05:10:11 +02:00
break ;
2020-01-01 21:29:24 +01:00
}
2020-04-17 00:19:17 +02:00
break ;
case Menu : : gamecompletecontinue :
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 25 , " Congratulations! " , tr , tg , tb , true , 2 ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 45 , " Your save files have been updated. " , tr , tg , tb , true ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 110 , " If you want to keep exploring " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 120 , " the game, select CONTINUE " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 130 , " from the play menu. " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : unlockmenu :
2021-08-20 02:17:36 +02:00
graphics . bigprint ( - 1 , 30 , " Unlock Play Modes " , tr , tg , tb , true , 2 ) ;
2020-01-01 21:29:24 +01:00
2021-08-20 02:17:36 +02:00
graphics . Print ( - 1 , 65 , " From here, you may unlock parts " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 75 , " of the game that are normally " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 85 , " unlocked as you play. " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : unlocktimetrial :
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 45 , " Congratulations! " , tr , tg , tb , true , 2 ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 125 , " You have unlocked " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 135 , " a new Time Trial. " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : unlocktimetrials :
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 45 , " Congratulations! " , tr , tg , tb , true , 2 ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 125 , " You have unlocked some " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 135 , " new Time Trials. " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : unlocknodeathmode :
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 45 , " Congratulations! " , tr , tg , tb , true , 2 ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 125 , " You have unlocked " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 135 , " No Death Mode. " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : unlockflipmode :
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 45 , " Congratulations! " , tr , tg , tb , true , 2 ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 125 , " You have unlocked " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 135 , " Flip Mode. " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : unlockintermission :
2020-04-16 01:29:54 +02:00
graphics . bigprint ( - 1 , 45 , " Congratulations! " , tr , tg , tb , true , 2 ) ;
2020-01-01 21:29:24 +01:00
2020-04-16 01:29:54 +02:00
graphics . Print ( - 1 , 125 , " You have unlocked " , tr , tg , tb , true ) ;
graphics . Print ( - 1 , 135 , " the intermission levels. " , tr , tg , tb , true ) ;
2020-04-17 00:19:17 +02:00
break ;
case Menu : : playerworlds :
2021-12-22 09:58:27 +01:00
graphics . PrintWrap ( - 1 , 180 , " To install new player levels, copy the .vvvvvv files to the levels folder. " , tr , tg , tb , true , 10 , 304 ) ;
break ;
case Menu : : confirmshowlevelspath :
graphics . PrintWrap ( - 1 , 80 , " Are you sure you want to show the levels path? This may reveal sensitive information if you are streaming. " , tr , tg , tb , true , 10 , 304 ) ;
break ;
case Menu : : showlevelspath :
graphics . Print ( - 1 , 40 , " The levels path is: " , tr , tg , tb , true ) ;
graphics . PrintWrap ( 0 , 60 , FILESYSTEM_getUserLevelDirectory ( ) , tr , tg , tb , false , 10 , 320 ) ;
2020-04-17 00:19:17 +02:00
break ;
2020-11-22 03:10:26 +01:00
case Menu : : errorsavingsettings :
2020-11-22 04:14:52 +01:00
graphics . Print ( - 1 , 95 , " ERROR: Could not save settings file! " , tr , tg , tb , true ) ;
break ;
2021-08-07 05:57:34 +02:00
case Menu : : errorloadinglevel :
2021-08-18 19:02:06 +02:00
{
const char * str ;
if ( FILESYSTEM_levelDirHasError ( ) )
{
str = FILESYSTEM_getLevelDirError ( ) ;
}
else
{
str = graphics . error ;
}
2021-08-07 05:57:34 +02:00
graphics . bigprint ( - 1 , 45 , " ERROR " , tr , tg , tb , true ) ;
2021-08-18 19:02:06 +02:00
graphics . PrintWrap ( - 1 , 65 , str , tr , tg , tb , true , 10 , 304 ) ;
2021-08-07 05:57:34 +02:00
break ;
2021-08-18 19:02:06 +02:00
}
2021-08-07 07:26:48 +02:00
case Menu : : warninglevellist :
graphics . bigprint ( - 1 , 45 , " WARNING " , tr , tg , tb , true ) ;
graphics . PrintWrap ( - 1 , 65 , FILESYSTEM_getLevelDirError ( ) , tr , tg , tb , true , 10 , 304 ) ;
break ;
2020-04-17 00:19:17 +02:00
default :
break ;
2020-04-16 01:29:54 +02:00
}
}
2021-03-19 05:20:05 +01:00
void titlerender ( void )
2020-04-16 01:29:54 +02:00
{
2021-02-26 00:37:03 +01:00
ClearSurface ( graphics . backBuffer ) ;
2020-04-16 01:29:54 +02:00
if ( ! game . menustart )
{
2020-05-02 01:40:35 +02:00
tr = graphics . col_tr ;
tg = graphics . col_tg ;
tb = graphics . col_tb ;
2020-04-16 01:29:54 +02:00
int temp = 50 ;
graphics . drawsprite ( ( 160 - 96 ) + 0 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 1 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 2 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 3 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 4 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 5 * 32 , temp , 23 , tr , tg , tb ) ;
# if defined(MAKEANDPLAY)
graphics . Print ( - 1 , temp + 35 , " MAKE AND PLAY EDITION " , tr , tg , tb , true ) ;
# endif
graphics . Print ( 5 , 175 , " [ Press ACTION to Start ] " , tr , tg , tb , true ) ;
graphics . Print ( 5 , 195 , " ACTION = Space, Z, or V " , int ( tr * 0.5f ) , int ( tg * 0.5f ) , int ( tb * 0.5f ) , true ) ;
}
else
{
2020-11-03 00:23:53 +01:00
if ( ! game . colourblindmode ) graphics . drawtowerbackground ( graphics . titlebg ) ;
2020-04-16 01:29:54 +02:00
2020-05-02 01:40:35 +02:00
tr = graphics . col_tr ;
tg = graphics . col_tg ;
tb = graphics . col_tb ;
2020-04-16 01:29:54 +02:00
menurender ( ) ;
2020-01-01 21:29:24 +01:00
tr = int ( tr * .8f ) ;
tg = int ( tg * .8f ) ;
tb = int ( tb * .8f ) ;
if ( tr < 0 ) tr = 0 ;
if ( tr > 255 ) tr = 255 ;
if ( tg < 0 ) tg = 0 ;
if ( tg > 255 ) tg = 255 ;
if ( tb < 0 ) tb = 0 ;
if ( tb > 255 ) tb = 255 ;
2020-07-04 23:53:05 +02:00
graphics . drawmenu ( tr , tg , tb , game . currentmenuname = = Menu : : levellist ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-01 23:59:19 +02:00
graphics . drawfade ( ) ;
2020-01-01 21:29:24 +01:00
2020-04-27 04:24:50 +02:00
graphics . renderwithscreeneffects ( ) ;
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 gamecompleterender ( void )
2020-01-01 21:29:24 +01:00
{
2021-02-26 00:37:03 +01:00
ClearSurface ( graphics . backBuffer ) ;
2020-01-01 21:29:24 +01:00
2020-11-03 00:23:53 +01:00
if ( ! game . colourblindmode ) graphics . drawtowerbackground ( graphics . titlebg ) ;
2020-01-01 21:29:24 +01:00
2020-05-02 01:40:35 +02:00
tr = graphics . col_tr ;
tg = graphics . col_tg ;
tb = graphics . col_tb ;
2020-01-01 21:29:24 +01:00
//rendering starts... here!
2020-04-30 19:56:27 +02:00
int position = graphics . lerp ( game . oldcreditposition , game . creditposition ) ;
if ( graphics . onscreen ( 220 + position ) )
2020-01-01 21:29:24 +01:00
{
2020-04-30 19:56:27 +02:00
int temp = 220 + position ;
2020-04-01 23:59:19 +02:00
graphics . drawsprite ( ( 160 - 96 ) + 0 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 1 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 2 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 3 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 4 * 32 , temp , 23 , tr , tg , tb ) ;
graphics . drawsprite ( ( 160 - 96 ) + 5 * 32 , temp , 23 , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( 290 + position ) ) graphics . bigprint ( - 1 , 290 + position , " Starring " , tr , tg , tb , true , 2 ) ;
2020-01-01 21:29:24 +01:00
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( 320 + position ) )
2020-01-01 21:29:24 +01:00
{
2020-04-30 19:56:27 +02:00
graphics . drawcrewman ( 70 , 320 + position , 0 , true ) ;
graphics . Print ( 100 , 330 + position , " Captain Viridian " , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( 350 + position ) )
2020-01-01 21:29:24 +01:00
{
2020-04-30 19:56:27 +02:00
graphics . drawcrewman ( 70 , 350 + position , 1 , true ) ;
graphics . Print ( 100 , 360 + position , " Doctor Violet " , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( 380 + position ) )
2020-01-01 21:29:24 +01:00
{
2020-04-30 19:56:27 +02:00
graphics . drawcrewman ( 70 , 380 + position , 2 , true ) ;
graphics . Print ( 100 , 390 + position , " Professor Vitellary " , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( 410 + position ) )
2020-01-01 21:29:24 +01:00
{
2020-04-30 19:56:27 +02:00
graphics . drawcrewman ( 70 , 410 + position , 3 , true ) ;
graphics . Print ( 100 , 420 + position , " Officer Vermilion " , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( 440 + position ) )
2020-01-01 21:29:24 +01:00
{
2020-04-30 19:56:27 +02:00
graphics . drawcrewman ( 70 , 440 + position , 4 , true ) ;
graphics . Print ( 100 , 450 + position , " Chief Verdigris " , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( 470 + position ) )
2020-01-01 21:29:24 +01:00
{
2020-04-30 19:56:27 +02:00
graphics . drawcrewman ( 70 , 470 + position , 5 , true ) ;
graphics . Print ( 100 , 480 + position , " Doctor Victoria " , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( 520 + position ) ) graphics . bigprint ( - 1 , 520 + position , " Credits " , tr , tg , tb , true , 3 ) ;
2020-01-01 21:29:24 +01:00
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( 560 + position ) )
2020-01-01 21:29:24 +01:00
{
2020-04-30 19:56:27 +02:00
graphics . Print ( 40 , 560 + position , " Created by " , tr , tg , tb ) ;
graphics . bigprint ( 60 , 570 + position , " Terry Cavanagh " , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( 600 + position ) )
2020-01-01 21:29:24 +01:00
{
2020-04-30 19:56:27 +02:00
graphics . Print ( 40 , 600 + position , " With Music by " , tr , tg , tb ) ;
graphics . bigprint ( 60 , 610 + position , " Magnus P~lsson " , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( 640 + position ) )
2020-01-01 21:29:24 +01:00
{
2020-04-30 19:56:27 +02:00
graphics . Print ( 40 , 640 + position , " Rooms Named by " , tr , tg , tb ) ;
graphics . bigprint ( 60 , 650 + position , " Bennett Foddy " , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2021-09-01 08:19:25 +02:00
if ( graphics . onscreen ( 710 + position ) )
2020-01-01 21:29:24 +01:00
{
2020-04-30 19:56:27 +02:00
graphics . Print ( 40 , 680 + position , " C++ Port by " , tr , tg , tb ) ;
graphics . bigprint ( 60 , 690 + position , " Simon Roth " , tr , tg , tb ) ;
graphics . bigprint ( 60 , 710 + position , " Ethan Lee " , tr , tg , tb ) ;
2021-09-01 08:19:25 +02:00
graphics . bigprint ( 60 , 730 + position , " Misa Kai " , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2021-09-01 08:23:27 +02:00
if ( graphics . onscreen ( 770 + position ) )
2020-01-01 21:29:24 +01:00
{
2021-09-01 08:19:25 +02:00
graphics . Print ( 40 , 760 + position , " Beta Testing by " , tr , tg , tb ) ;
graphics . bigprint ( 60 , 770 + position , " Sam Kaplan " , tr , tg , tb ) ;
graphics . bigprint ( 60 , 790 + position , " Pauli Kohberger " , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2021-09-01 08:19:25 +02:00
if ( graphics . onscreen ( 820 + position ) )
2020-01-01 21:29:24 +01:00
{
2021-09-01 08:19:25 +02:00
graphics . Print ( 40 , 820 + position , " Ending Picture by " , tr , tg , tb ) ;
graphics . bigprint ( 60 , 830 + position , " Pauli Kohberger " , tr , tg , tb ) ;
2020-01-01 21:29:24 +01:00
}
2021-09-01 08:19:25 +02:00
if ( graphics . onscreen ( 910 + position ) ) graphics . bigprint ( - 1 , 890 + position , " Patrons " , tr , tg , tb , true , 3 ) ;
2020-01-17 02:14:56 +01:00
2021-09-01 08:19:25 +02:00
int creditOffset = 950 ;
2020-01-17 02:14:56 +01:00
Turn (super)patrons/githubfriends into arrays & move them to new file
So, originally, I wanted to keep them on Game, but it turns out that if
I initialize it in Game.cpp, the compiler will complain that other files
won't know what's actually inside the array. To do that, I'd have to
initialize it in Game.h. But I don't want to initialize it in Game.h
because that'd mean recompiling a lot of unnecessary files whenever
someone gets added to the credits.
So, I moved all the patrons, superpatrons, and GitHub contributors to a
new file, Credits.h, which only contains the list (and the credits max
position calculation). That way, whenever someone gets added, only the
minimal amount of files need to be recompiled.
2020-07-03 12:13:15 +02:00
for ( size_t i = 0 ; i < SDL_arraysize ( Credits : : superpatrons ) ; i + = 1 )
2020-01-17 02:14:56 +01:00
{
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( creditOffset + position ) )
2020-01-17 02:14:56 +01:00
{
Turn (super)patrons/githubfriends into arrays & move them to new file
So, originally, I wanted to keep them on Game, but it turns out that if
I initialize it in Game.cpp, the compiler will complain that other files
won't know what's actually inside the array. To do that, I'd have to
initialize it in Game.h. But I don't want to initialize it in Game.h
because that'd mean recompiling a lot of unnecessary files whenever
someone gets added to the credits.
So, I moved all the patrons, superpatrons, and GitHub contributors to a
new file, Credits.h, which only contains the list (and the credits max
position calculation). That way, whenever someone gets added, only the
minimal amount of files need to be recompiled.
2020-07-03 12:13:15 +02:00
graphics . Print ( - 1 , creditOffset + position , Credits : : superpatrons [ i ] , tr , tg , tb , true ) ;
2020-01-17 02:14:56 +01:00
}
creditOffset + = 10 ;
}
creditOffset + = 10 ;
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( creditOffset + position ) ) graphics . Print ( - 1 , creditOffset + position , " and " , tr , tg , tb , true ) ;
2020-01-17 02:14:56 +01:00
creditOffset + = 20 ;
Turn (super)patrons/githubfriends into arrays & move them to new file
So, originally, I wanted to keep them on Game, but it turns out that if
I initialize it in Game.cpp, the compiler will complain that other files
won't know what's actually inside the array. To do that, I'd have to
initialize it in Game.h. But I don't want to initialize it in Game.h
because that'd mean recompiling a lot of unnecessary files whenever
someone gets added to the credits.
So, I moved all the patrons, superpatrons, and GitHub contributors to a
new file, Credits.h, which only contains the list (and the credits max
position calculation). That way, whenever someone gets added, only the
minimal amount of files need to be recompiled.
2020-07-03 12:13:15 +02:00
for ( size_t i = 0 ; i < SDL_arraysize ( Credits : : patrons ) ; i + = 1 )
2020-01-17 02:14:56 +01:00
{
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( creditOffset + position ) )
2020-01-17 02:14:56 +01:00
{
Turn (super)patrons/githubfriends into arrays & move them to new file
So, originally, I wanted to keep them on Game, but it turns out that if
I initialize it in Game.cpp, the compiler will complain that other files
won't know what's actually inside the array. To do that, I'd have to
initialize it in Game.h. But I don't want to initialize it in Game.h
because that'd mean recompiling a lot of unnecessary files whenever
someone gets added to the credits.
So, I moved all the patrons, superpatrons, and GitHub contributors to a
new file, Credits.h, which only contains the list (and the credits max
position calculation). That way, whenever someone gets added, only the
minimal amount of files need to be recompiled.
2020-07-03 12:13:15 +02:00
graphics . Print ( - 1 , creditOffset + position , Credits : : patrons [ i ] , tr , tg , tb , true ) ;
2020-01-17 02:14:56 +01:00
}
creditOffset + = 10 ;
}
creditOffset + = 20 ;
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( creditOffset + position ) ) graphics . bigprint ( 40 , creditOffset + position , " GitHub Contributors " , tr , tg , tb , true ) ;
2020-01-17 02:14:56 +01:00
creditOffset + = 30 ;
Turn (super)patrons/githubfriends into arrays & move them to new file
So, originally, I wanted to keep them on Game, but it turns out that if
I initialize it in Game.cpp, the compiler will complain that other files
won't know what's actually inside the array. To do that, I'd have to
initialize it in Game.h. But I don't want to initialize it in Game.h
because that'd mean recompiling a lot of unnecessary files whenever
someone gets added to the credits.
So, I moved all the patrons, superpatrons, and GitHub contributors to a
new file, Credits.h, which only contains the list (and the credits max
position calculation). That way, whenever someone gets added, only the
minimal amount of files need to be recompiled.
2020-07-03 12:13:15 +02:00
for ( size_t i = 0 ; i < SDL_arraysize ( Credits : : githubfriends ) ; i + = 1 )
2020-01-17 02:14:56 +01:00
{
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( creditOffset + position ) )
2020-01-17 02:14:56 +01:00
{
Turn (super)patrons/githubfriends into arrays & move them to new file
So, originally, I wanted to keep them on Game, but it turns out that if
I initialize it in Game.cpp, the compiler will complain that other files
won't know what's actually inside the array. To do that, I'd have to
initialize it in Game.h. But I don't want to initialize it in Game.h
because that'd mean recompiling a lot of unnecessary files whenever
someone gets added to the credits.
So, I moved all the patrons, superpatrons, and GitHub contributors to a
new file, Credits.h, which only contains the list (and the credits max
position calculation). That way, whenever someone gets added, only the
minimal amount of files need to be recompiled.
2020-07-03 12:13:15 +02:00
graphics . Print ( - 1 , creditOffset + position , Credits : : githubfriends [ i ] , tr , tg , tb , true ) ;
2020-01-17 02:14:56 +01:00
}
creditOffset + = 10 ;
}
creditOffset + = 140 ;
2020-04-30 19:56:27 +02:00
if ( graphics . onscreen ( creditOffset + position ) ) graphics . bigprint ( - 1 , creditOffset + position , " Thanks for playing! " , tr , tg , tb , true , 2 ) ;
2020-01-01 21:29:24 +01:00
2020-04-01 23:59:19 +02:00
graphics . drawfade ( ) ;
2020-01-01 21:29:24 +01:00
2020-04-27 04:29:40 +02:00
graphics . render ( ) ;
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 gamecompleterender2 ( void )
2020-01-01 21:29:24 +01:00
{
2021-02-26 00:37:03 +01:00
ClearSurface ( graphics . backBuffer ) ;
2020-01-01 21:29:24 +01:00
2020-04-01 23:59:19 +02:00
graphics . drawimage ( 10 , 0 , 0 ) ;
2020-01-01 21:29:24 +01:00
for ( int j = 0 ; j < 30 ; j + + )
{
for ( int i = 0 ; i < 40 ; i + + )
{
if ( j = = game . creditposy )
{
if ( i > game . creditposx )
{
2020-04-01 23:59:19 +02:00
FillRect ( graphics . backBuffer , i * 8 , j * 8 , 8 , 8 , 0 , 0 , 0 ) ;
2020-01-01 21:29:24 +01:00
}
}
if ( j > game . creditposy )
{
2020-04-01 23:59:19 +02:00
FillRect ( graphics . backBuffer , i * 8 , j * 8 , 8 , 8 , 0 , 0 , 0 ) ;
2020-01-01 21:29:24 +01:00
}
}
}
2020-05-02 03:23:52 +02:00
FillRect ( graphics . backBuffer , graphics . lerp ( game . oldcreditposx * 8 , game . creditposx * 8 ) + 8 , game . creditposy * 8 , 8 , 8 , 0 , 0 , 0 ) ;
2020-04-01 23:59:19 +02:00
graphics . drawfade ( ) ;
2020-01-01 21:29:24 +01:00
2020-04-27 04:29:40 +02:00
graphics . render ( ) ;
2020-01-01 21:29:24 +01:00
}
2021-04-19 08:23:44 +02:00
static const char * interact_prompt (
char * buffer ,
const size_t buffer_size ,
const char * raw
) {
const char * string_fmt_loc = SDL_strstr ( raw , " %s " ) ;
const char * button ;
if ( string_fmt_loc = = NULL /* No "%s". */
| | string_fmt_loc ! = SDL_strchr ( raw , ' % ' ) /* First "%" found is not "%s". */
| | SDL_strchr ( & string_fmt_loc [ 1 ] , ' % ' ) ! = NULL ) /* Other "%" after "%s". */
{
return raw ;
}
if ( game . separate_interact )
{
button = " E " ;
}
else
{
button = " ENTER " ;
}
SDL_snprintf ( buffer , buffer_size , raw , button ) ;
return buffer ;
}
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 gamerender ( void )
2020-01-01 21:29:24 +01:00
{
if ( ! game . blackout )
{
2020-04-27 00:16:35 +02:00
if ( map . towermode )
2020-04-02 23:19:15 +02:00
{
2020-04-27 00:16:35 +02:00
if ( ! game . colourblindmode )
{
2020-11-03 00:05:24 +01:00
graphics . drawtowerbackground ( graphics . towerbg ) ;
2020-04-27 00:16:35 +02:00
}
else
{
2021-02-26 00:37:03 +01:00
ClearSurface ( graphics . backBuffer ) ;
2020-04-27 00:16:35 +02:00
}
2020-06-30 20:10:00 +02:00
graphics . drawtowermap ( ) ;
2020-01-01 21:29:24 +01:00
}
else
2020-04-02 23:19:15 +02:00
{
2020-04-27 00:16:35 +02:00
if ( ! game . colourblindmode )
{
graphics . drawbackground ( map . background ) ;
}
else
{
2021-02-26 00:37:03 +01:00
ClearSurface ( graphics . backBuffer ) ;
2020-04-27 00:16:35 +02:00
}
2021-03-26 01:40:50 +01:00
if ( ( map . finalmode | | map . custommode ) & & map . final_colormode )
2020-04-27 00:16:35 +02:00
{
graphics . drawfinalmap ( ) ;
}
else
{
graphics . drawmap ( ) ;
}
2020-01-01 21:29:24 +01:00
}
2020-04-01 23:59:19 +02:00
graphics . drawentities ( ) ;
2020-04-27 00:16:35 +02:00
if ( map . towermode )
{
graphics . drawtowerspikes ( ) ;
}
2020-01-01 21:29:24 +01:00
}
2021-12-21 02:44:34 +01:00
if ( graphics . fademode = = 0 & & ! game . intimetrial & & ! game . isingamecompletescreen ( ) & & ( ! game . swnmode | | game . swngame ! = 1 ) & & game . showingametimer )
2021-08-05 23:31:20 +02:00
{
Simplify time formatting functions
Here's my notes on all the existing functions and what kind of time
formats they output:
- Game::giventimestring(int hrs, int min, int sec)
H:MM:SS
MM:SS
- Game::timestring()
// uses game.hours/minutes/seconds
H:MM:SS
MM:SS
- Game::partimestring()
// uses game.timetrialpar (seconds)
MM:SS
- Game::resulttimestring()
// uses game.timetrialresulttime (sec) + timetrialresultframes (1/30s)
MM:SS.CC
- Game::timetstring(int t)
// t = seconds
MM:SS
- Game::timestringcenti(char* buffer, const size_t buffer_size)
// uses game.hours/minutes/seconds/frames
H:MM:SS.CC
MM:SS.CC
- UtilityClass::timestring(int t)
// t = frames, 30 frames = 1 second
S:CC
M:SS:CC
This is kind of a mess, and there's a lot of functions that do the same
thing except using different variables. For localization, I also want
translators to be able to localize all these time formats - many
languages use the decimal comma instead of the decimal point (12:34,56)
maybe some languages really prefer something like 1時02分11秒44瞬...
Which I don't know to be correct, but it's good to be prepared for it
and not restrict translators arbitrarily to only changing ":" and "."
when we can start making the system better in the first place.
I added a new function, UtilityClass::format_time. This is the place
where all time formats come together, given the number of seconds and
optionally frames. I have simplified the above-mentioned functions
somewhat, but I haven't given them a complete refactor or renaming -
I mainly made sure that they all use the same backend so I can make the
formats consistent and properly localizable.
(And before we start shoving more temporary char buffers everywhere
just to get rid of the std::string's, maybe we need to think of a
globally used working buffer of size SCREEN_WIDTH_CHARS+1, as a
register of sorts, for when any line of text needs to be made or
processed, then printed, and then goes unused. Maybe help.textrow,
or something like that.)
As for this commit, the available time formats are now more consistent
and changed a little in some places. Leading zeroes for the first unit
are now no longer included, time trial results and the Super Gravitron
can now display hours when they went to 60 minutes before, and we now
always use .CC instead of :CC. These are the formats:
- H:MM:SS
- H:MM:SS.CC
- M:SS
- M:SS.CC
- S.CC (only used when always_minutes=false, for the Gravitrons)
Here's what changes to the current functions:
- Game::partimestring() is removed - it was used in two places, and
could be replaced by game.timetstring(game.timetrialpar)
- Game::giventimestring(h,m,s) and Game::timestring() are now wrappers
for the other functions
- The four remaining functions (Game::resulttimestring(),
Game::timetstring(t), Game::timestringcenti(buffer, buffer_size)
and UtilityClass::timestring(t)) are now wrappers for the "central
function", UtilityClass::format_time.
- UtilityClass::twodigits(int t) is now unused so it's also removed.
- I also added int UtilityClass::hms_to_seconds(int h, int m, int s)
2021-12-25 17:13:46 +01:00
char buffer [ SCREEN_WIDTH_CHARS + 1 ] ;
2021-08-05 23:31:20 +02:00
graphics . bprint ( 6 , 6 , " TIME: " , 255 , 255 , 255 ) ;
2021-12-21 02:32:12 +01:00
game . timestringcenti ( buffer , sizeof ( buffer ) ) ;
graphics . bprint ( 46 , 6 , buffer , 196 , 196 , 196 ) ;
2021-08-05 23:31:20 +02:00
}
2021-09-13 06:54:47 +02:00
if ( map . extrarow = = 0 | | ( map . custommode & & map . roomname [ 0 ] ! = ' \0 ' ) )
2020-01-01 21:29:24 +01:00
{
2021-12-26 09:03:18 +01:00
const char * roomname ;
2021-12-26 08:54:43 +01:00
void ( Graphics : : * printfunc ) ( int , int , const std : : string & , int , int , int , bool ) ;
2021-12-26 09:03:18 +01:00
2020-04-01 23:59:19 +02:00
graphics . footerrect . y = 230 ;
if ( graphics . translucentroomname )
2020-01-25 05:43:04 +01:00
{
2020-04-01 23:59:19 +02:00
SDL_BlitSurface ( graphics . footerbuffer , NULL , graphics . backBuffer , & graphics . footerrect ) ;
2021-12-26 08:54:43 +01:00
printfunc = & Graphics : : bprint ;
2020-01-25 05:43:04 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
FillRect ( graphics . backBuffer , graphics . footerrect , 0 ) ;
2021-12-26 08:54:43 +01:00
printfunc = & Graphics : : Print ;
2020-01-25 05:43:04 +01:00
}
2020-01-01 21:29:24 +01:00
if ( map . finalmode )
{
2021-12-26 09:03:18 +01:00
roomname = map . glitchname ;
}
else
{
roomname = map . roomname ;
2020-01-01 21:29:24 +01:00
}
2021-12-26 09:03:18 +01:00
2021-12-26 08:54:43 +01:00
( graphics . * printfunc ) ( 5 , 231 , roomname , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
if ( map . roomtexton )
{
//Draw room text!
Refactor roomtext to not use ad-hoc objects / separate length trackers
This refactors the roomtext code to (1) not use ad-hoc objects and (2)
not use a separate length-tracking variable to keep track of the actual
amount of roomtext in a room.
What I mean by ad-hoc object is, instead of formally creating a
fully-fledged struct or class and storing one vector containing that
object, this game instead hacks together an object by storing each
attribute of an object in different vectors.
In the case of roomtext, instead of making a Roomtext object that has
attributes 'x', 'y', and 'text', the 'text' attribute of each is stored
in the vector 'roomtext', the 'x' attribute of each is stored in the
vector 'roomtextx', and the 'y' attribute of each is stored in the
vector 'roomtexty'. It's only an object in the sense that you can grab
the attributes of each roomtext by using the same index across all three
vectors.
This makes it somewhat annoying to maintain and deal with, like when I
wanted add sub-tile positions to roomtext in VVVVVV: Community Edition.
Instead of being able to add attributes to an already-existing
formalized Roomtext object, I would instead have to add two more
vectors, which is inelegant. Or I could refactor the whole system, which
is what I decided to do instead.
Furthermore, this removes the separate length-tracking variable
'roomtextnumlines', which makes the code much more easy to maintain and
deal with, as the amount of roomtext is naturally tracked by C++ instead
of us having to keep track of the actual amount of roomtext manually.
2020-03-01 03:26:12 +01:00
for ( size_t i = 0 ; i < map . roomtext . size ( ) ; i + + )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . Print ( map . roomtext [ i ] . x * 8 , ( map . roomtext [ i ] . y * 8 ) , map . roomtext [ i ] . text , 196 , 196 , 255 - help . glow ) ;
2020-01-01 21:29:24 +01:00
}
}
2021-02-21 00:40:11 +01:00
# if !defined(NO_CUSTOM_LEVELS) && !defined(NO_EDITOR)
2020-01-17 08:33:12 +01:00
if ( map . custommode & & ! map . custommodeforreal & & ! game . advancetext ) {
2020-01-01 21:29:24 +01:00
//Return to level editor
2020-05-02 19:49:41 +02:00
int alpha = graphics . lerp ( ed . oldreturneditoralpha , ed . returneditoralpha ) ;
graphics . bprintalpha ( 5 , 5 , " [Press ENTER to return to editor] " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , alpha , false ) ;
2020-01-01 21:29:24 +01:00
}
2020-02-11 05:52:08 +01:00
# endif
2020-01-01 21:29:24 +01:00
2020-04-01 23:59:19 +02:00
graphics . cutscenebars ( ) ;
graphics . drawfade ( ) ;
2020-04-02 23:19:15 +02:00
BlitSurfaceStandard ( graphics . backBuffer , NULL , graphics . tempBuffer , NULL ) ;
2020-01-01 21:29:24 +01:00
2020-04-01 23:59:19 +02:00
graphics . drawgui ( ) ;
if ( graphics . flipmode )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
if ( game . advancetext ) graphics . bprint ( 5 , 228 , " - Press ACTION to advance text - " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
if ( game . advancetext ) graphics . bprint ( 5 , 5 , " - Press ACTION to advance text - " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-08-03 06:02:27 +02:00
if ( game . readytotele > 100 | | game . oldreadytotele > 100 )
2020-01-01 21:29:24 +01:00
{
2021-09-13 06:39:07 +02:00
char buffer [ SCREEN_WIDTH_CHARS + 1 ] ;
2021-10-13 01:59:36 +02:00
static const char raw [ ] = " - Press %s to Teleport - " ;
2021-04-19 08:23:44 +02:00
const char * final_string = interact_prompt (
buffer ,
sizeof ( buffer ) ,
raw
) ;
2020-04-30 02:04:25 +02:00
int alpha = graphics . lerp ( game . oldreadytotele , game . readytotele ) ;
2021-04-19 08:23:44 +02:00
graphics . bprint ( 5 , graphics . flipmode ? 20 : 210 , final_string , alpha - 20 - ( help . glow / 2 ) , alpha - 20 - ( help . glow / 2 ) , alpha , true ) ;
2020-01-01 21:29:24 +01:00
}
if ( game . swnmode )
{
if ( game . swngame = = 0 )
{
2020-04-03 00:05:41 +02:00
std : : string tempstring = help . timestring ( game . swntimer ) ;
2021-03-19 22:29:03 +01:00
graphics . bigbprint ( - 1 , 20 , tempstring , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true , 2 ) ;
2020-01-01 21:29:24 +01:00
}
else if ( game . swngame = = 1 )
{
if ( game . swnmessage = = 0 )
{
2020-04-03 00:05:41 +02:00
std : : string tempstring = help . timestring ( game . swntimer ) ;
2021-03-19 22:29:03 +01:00
graphics . bprint ( 10 , 10 , " Current Time " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , false ) ;
graphics . bigbprint ( 25 , 24 , tempstring , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , false , 2 ) ;
2020-01-01 21:29:24 +01:00
tempstring = help . timestring ( game . swnrecord ) ;
2021-03-19 22:29:03 +01:00
graphics . bprint ( 240 , 10 , " Best Time " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , false ) ;
graphics . bigbrprint ( 300 , 24 , tempstring , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , false , 2 ) ;
2020-01-01 21:29:24 +01:00
switch ( game . swnbestrank )
{
case 0 :
2021-03-19 22:29:03 +01:00
graphics . bprint ( - 1 , 204 , " Next Trophy at 5 seconds " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 1 :
2021-03-19 22:29:03 +01:00
graphics . bprint ( - 1 , 204 , " Next Trophy at 10 seconds " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 2 :
2021-03-19 22:29:03 +01:00
graphics . bprint ( - 1 , 204 , " Next Trophy at 15 seconds " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 3 :
2021-03-19 22:29:03 +01:00
graphics . bprint ( - 1 , 204 , " Next Trophy at 20 seconds " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 4 :
2021-03-19 22:29:03 +01:00
graphics . bprint ( - 1 , 204 , " Next Trophy at 30 seconds " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 5 :
2021-03-19 22:29:03 +01:00
graphics . bprint ( - 1 , 204 , " Next Trophy at 1 minute " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 6 :
2021-03-19 22:29:03 +01:00
graphics . bprint ( - 1 , 204 , " All Trophies collected! " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
break ;
}
}
else if ( game . swnmessage = = 1 )
{
2020-04-03 00:05:41 +02:00
std : : string tempstring = help . timestring ( game . swntimer ) ;
2021-03-19 22:29:03 +01:00
graphics . bprint ( 10 , 10 , " Current Time " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , false ) ;
graphics . bigbprint ( 25 , 24 , tempstring , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , false , 2 ) ;
2020-01-01 21:29:24 +01:00
tempstring = help . timestring ( game . swnrecord ) ;
if ( int ( game . deathseq / 5 ) % 2 = = 1 )
{
2021-03-19 22:29:03 +01:00
graphics . bprint ( 240 , 10 , " Best Time " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , false ) ;
graphics . bigbrprint ( 300 , 24 , tempstring , 128 - ( help . glow ) , 220 - ( help . glow ) , 128 - ( help . glow / 2 ) , false , 2 ) ;
2020-01-01 21:29:24 +01:00
2021-03-19 22:29:03 +01:00
graphics . bigbprint ( - 1 , 200 , " New Record! " , 128 - ( help . glow ) , 220 - ( help . glow ) , 128 - ( help . glow / 2 ) , true , 2 ) ;
2020-01-01 21:29:24 +01:00
}
}
else if ( game . swnmessage > = 2 )
{
game . swnmessage - - ;
if ( game . swnmessage = = 2 ) game . swnmessage = 0 ;
2020-04-03 00:05:41 +02:00
std : : string tempstring = help . timestring ( game . swntimer ) ;
2021-03-19 22:29:03 +01:00
graphics . bprint ( 10 , 10 , " Current Time " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , false ) ;
graphics . bigbprint ( 25 , 24 , tempstring , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , false , 2 ) ;
2020-01-01 21:29:24 +01:00
tempstring = help . timestring ( game . swnrecord ) ;
2021-03-19 22:29:03 +01:00
graphics . bprint ( 240 , 10 , " Best Time " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , false ) ;
graphics . bigbrprint ( 300 , 24 , tempstring , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , false , 2 ) ;
2020-01-01 21:29:24 +01:00
if ( int ( game . swnmessage / 5 ) % 2 = = 1 )
{
2021-03-19 22:29:03 +01:00
graphics . bigbprint ( - 1 , 200 , " New Trophy! " , 220 - ( help . glow ) , 128 - ( help . glow ) , 128 - ( help . glow / 2 ) , true , 2 ) ;
2020-01-01 21:29:24 +01:00
}
}
2021-03-19 22:29:03 +01:00
graphics . bprint ( 20 , 228 , " [Press ENTER to stop] " , 160 - ( help . glow / 2 ) , 160 - ( help . glow / 2 ) , 160 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
}
else if ( game . swngame = = 2 )
{
if ( int ( game . swndelay / 15 ) % 2 = = 1 | | game . swndelay > = 120 )
{
2021-03-19 21:57:05 +01:00
int y1 ;
int y2 ;
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode )
2020-01-01 21:29:24 +01:00
{
2021-03-19 21:57:05 +01:00
y1 = 30 ;
y2 = 10 ;
2020-01-01 21:29:24 +01:00
}
else
{
2021-03-19 21:57:05 +01:00
y1 = 10 ;
y2 = 30 ;
2020-01-01 21:29:24 +01:00
}
2021-03-19 22:29:03 +01:00
graphics . bigbprint ( - 1 , y1 , " Survive for " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true , 2 ) ;
graphics . bigbprint ( - 1 , y2 , " 60 seconds! " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true , 2 ) ;
2020-01-01 21:29:24 +01:00
}
}
else if ( game . swngame = = 7 )
{
if ( game . swndelay > = 60 )
{
2021-03-19 22:29:03 +01:00
graphics . bigbprint ( - 1 , 20 , " SUPER GRAVITRON " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true , 2 ) ;
2020-01-01 21:29:24 +01:00
2020-04-03 00:05:41 +02:00
std : : string tempstring = help . timestring ( game . swnrecord ) ;
2021-03-19 22:29:03 +01:00
graphics . bprint ( 240 , 190 , " Best Time " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
graphics . bigbrprint ( 300 , 205 , tempstring , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true , 2 ) ;
2020-01-01 21:29:24 +01:00
}
2021-09-07 03:56:39 +02:00
else if ( int ( game . swndelay / 10 ) % 2 = = 1 )
2020-01-01 21:29:24 +01:00
{
2021-03-19 22:29:03 +01:00
graphics . bigbprint ( - 1 , 20 , " SUPER GRAVITRON " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true , 2 ) ;
graphics . bigbprint ( - 1 , 200 , " GO! " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true , 3 ) ;
2020-01-01 21:29:24 +01:00
}
}
}
2020-04-01 23:59:19 +02:00
if ( game . intimetrial & & graphics . fademode = = 0 )
2020-01-01 21:29:24 +01:00
{
//Draw countdown!
if ( game . timetrialcountdown > 0 )
{
if ( game . timetrialcountdown < 30 )
{
2021-06-12 08:56:33 +02:00
if ( int ( game . timetrialcountdown / 4 ) % 2 = = 0 ) graphics . bigbprint ( - 1 , 100 , " Go! " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true , 4 ) ;
2020-01-01 21:29:24 +01:00
}
else if ( game . timetrialcountdown < 60 )
{
2021-06-12 08:56:33 +02:00
graphics . bigbprint ( - 1 , 100 , " 1 " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true , 4 ) ;
2020-01-01 21:29:24 +01:00
}
else if ( game . timetrialcountdown < 90 )
{
2021-06-12 08:56:33 +02:00
graphics . bigbprint ( - 1 , 100 , " 2 " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true , 4 ) ;
2020-01-01 21:29:24 +01:00
}
else if ( game . timetrialcountdown < 120 )
{
2021-06-12 08:56:33 +02:00
graphics . bigbprint ( - 1 , 100 , " 3 " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true , 4 ) ;
2020-01-01 21:29:24 +01:00
}
}
else
{
Simplify time formatting functions
Here's my notes on all the existing functions and what kind of time
formats they output:
- Game::giventimestring(int hrs, int min, int sec)
H:MM:SS
MM:SS
- Game::timestring()
// uses game.hours/minutes/seconds
H:MM:SS
MM:SS
- Game::partimestring()
// uses game.timetrialpar (seconds)
MM:SS
- Game::resulttimestring()
// uses game.timetrialresulttime (sec) + timetrialresultframes (1/30s)
MM:SS.CC
- Game::timetstring(int t)
// t = seconds
MM:SS
- Game::timestringcenti(char* buffer, const size_t buffer_size)
// uses game.hours/minutes/seconds/frames
H:MM:SS.CC
MM:SS.CC
- UtilityClass::timestring(int t)
// t = frames, 30 frames = 1 second
S:CC
M:SS:CC
This is kind of a mess, and there's a lot of functions that do the same
thing except using different variables. For localization, I also want
translators to be able to localize all these time formats - many
languages use the decimal comma instead of the decimal point (12:34,56)
maybe some languages really prefer something like 1時02分11秒44瞬...
Which I don't know to be correct, but it's good to be prepared for it
and not restrict translators arbitrarily to only changing ":" and "."
when we can start making the system better in the first place.
I added a new function, UtilityClass::format_time. This is the place
where all time formats come together, given the number of seconds and
optionally frames. I have simplified the above-mentioned functions
somewhat, but I haven't given them a complete refactor or renaming -
I mainly made sure that they all use the same backend so I can make the
formats consistent and properly localizable.
(And before we start shoving more temporary char buffers everywhere
just to get rid of the std::string's, maybe we need to think of a
globally used working buffer of size SCREEN_WIDTH_CHARS+1, as a
register of sorts, for when any line of text needs to be made or
processed, then printed, and then goes unused. Maybe help.textrow,
or something like that.)
As for this commit, the available time formats are now more consistent
and changed a little in some places. Leading zeroes for the first unit
are now no longer included, time trial results and the Super Gravitron
can now display hours when they went to 60 minutes before, and we now
always use .CC instead of :CC. These are the formats:
- H:MM:SS
- H:MM:SS.CC
- M:SS
- M:SS.CC
- S.CC (only used when always_minutes=false, for the Gravitrons)
Here's what changes to the current functions:
- Game::partimestring() is removed - it was used in two places, and
could be replaced by game.timetstring(game.timetrialpar)
- Game::giventimestring(h,m,s) and Game::timestring() are now wrappers
for the other functions
- The four remaining functions (Game::resulttimestring(),
Game::timetstring(t), Game::timestringcenti(buffer, buffer_size)
and UtilityClass::timestring(t)) are now wrappers for the "central
function", UtilityClass::format_time.
- UtilityClass::twodigits(int t) is now unused so it's also removed.
- I also added int UtilityClass::hms_to_seconds(int h, int m, int s)
2021-12-25 17:13:46 +01:00
char buffer [ SCREEN_WIDTH_CHARS + 1 ] ;
2021-12-21 02:32:12 +01:00
game . timestringcenti ( buffer , sizeof ( buffer ) ) ;
2020-01-01 21:29:24 +01:00
//Draw OSD stuff
2020-04-01 23:59:19 +02:00
graphics . bprint ( 6 , 18 , " TIME : " , 255 , 255 , 255 ) ;
graphics . bprint ( 6 , 30 , " DEATH: " , 255 , 255 , 255 ) ;
graphics . bprint ( 6 , 42 , " SHINY: " , 255 , 255 , 255 ) ;
2020-01-01 21:29:24 +01:00
if ( game . timetrialparlost )
{
2021-12-21 02:32:12 +01:00
graphics . bprint ( 56 , 18 , buffer , 196 , 80 , 80 ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2021-12-21 02:32:12 +01:00
graphics . bprint ( 56 , 18 , buffer , 196 , 196 , 196 ) ;
2020-01-01 21:29:24 +01:00
}
if ( game . deathcounts > 0 )
{
2020-04-01 23:59:19 +02:00
graphics . bprint ( 56 , 30 , help . String ( game . deathcounts ) , 196 , 80 , 80 ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . bprint ( 56 , 30 , help . String ( game . deathcounts ) , 196 , 196 , 196 ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-07 08:46:27 +02:00
if ( game . trinkets ( ) < game . timetrialshinytarget )
2020-01-01 21:29:24 +01:00
{
2020-04-07 08:46:27 +02:00
graphics . bprint ( 56 , 42 , help . String ( game . trinkets ( ) ) + " of " + help . String ( game . timetrialshinytarget ) , 196 , 80 , 80 ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-07 08:46:27 +02:00
graphics . bprint ( 56 , 42 , help . String ( game . trinkets ( ) ) + " of " + help . String ( game . timetrialshinytarget ) , 196 , 196 , 196 ) ;
2020-01-01 21:29:24 +01:00
}
if ( game . timetrialparlost )
{
2020-04-01 23:59:19 +02:00
graphics . bprint ( 195 , 214 , " PAR TIME: " , 80 , 80 , 80 ) ;
Simplify time formatting functions
Here's my notes on all the existing functions and what kind of time
formats they output:
- Game::giventimestring(int hrs, int min, int sec)
H:MM:SS
MM:SS
- Game::timestring()
// uses game.hours/minutes/seconds
H:MM:SS
MM:SS
- Game::partimestring()
// uses game.timetrialpar (seconds)
MM:SS
- Game::resulttimestring()
// uses game.timetrialresulttime (sec) + timetrialresultframes (1/30s)
MM:SS.CC
- Game::timetstring(int t)
// t = seconds
MM:SS
- Game::timestringcenti(char* buffer, const size_t buffer_size)
// uses game.hours/minutes/seconds/frames
H:MM:SS.CC
MM:SS.CC
- UtilityClass::timestring(int t)
// t = frames, 30 frames = 1 second
S:CC
M:SS:CC
This is kind of a mess, and there's a lot of functions that do the same
thing except using different variables. For localization, I also want
translators to be able to localize all these time formats - many
languages use the decimal comma instead of the decimal point (12:34,56)
maybe some languages really prefer something like 1時02分11秒44瞬...
Which I don't know to be correct, but it's good to be prepared for it
and not restrict translators arbitrarily to only changing ":" and "."
when we can start making the system better in the first place.
I added a new function, UtilityClass::format_time. This is the place
where all time formats come together, given the number of seconds and
optionally frames. I have simplified the above-mentioned functions
somewhat, but I haven't given them a complete refactor or renaming -
I mainly made sure that they all use the same backend so I can make the
formats consistent and properly localizable.
(And before we start shoving more temporary char buffers everywhere
just to get rid of the std::string's, maybe we need to think of a
globally used working buffer of size SCREEN_WIDTH_CHARS+1, as a
register of sorts, for when any line of text needs to be made or
processed, then printed, and then goes unused. Maybe help.textrow,
or something like that.)
As for this commit, the available time formats are now more consistent
and changed a little in some places. Leading zeroes for the first unit
are now no longer included, time trial results and the Super Gravitron
can now display hours when they went to 60 minutes before, and we now
always use .CC instead of :CC. These are the formats:
- H:MM:SS
- H:MM:SS.CC
- M:SS
- M:SS.CC
- S.CC (only used when always_minutes=false, for the Gravitrons)
Here's what changes to the current functions:
- Game::partimestring() is removed - it was used in two places, and
could be replaced by game.timetstring(game.timetrialpar)
- Game::giventimestring(h,m,s) and Game::timestring() are now wrappers
for the other functions
- The four remaining functions (Game::resulttimestring(),
Game::timetstring(t), Game::timestringcenti(buffer, buffer_size)
and UtilityClass::timestring(t)) are now wrappers for the "central
function", UtilityClass::format_time.
- UtilityClass::twodigits(int t) is now unused so it's also removed.
- I also added int UtilityClass::hms_to_seconds(int h, int m, int s)
2021-12-25 17:13:46 +01:00
graphics . bprint ( 275 , 214 , game . timetstring ( game . timetrialpar ) , 80 , 80 , 80 ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . bprint ( 195 , 214 , " PAR TIME: " , 255 , 255 , 255 ) ;
Simplify time formatting functions
Here's my notes on all the existing functions and what kind of time
formats they output:
- Game::giventimestring(int hrs, int min, int sec)
H:MM:SS
MM:SS
- Game::timestring()
// uses game.hours/minutes/seconds
H:MM:SS
MM:SS
- Game::partimestring()
// uses game.timetrialpar (seconds)
MM:SS
- Game::resulttimestring()
// uses game.timetrialresulttime (sec) + timetrialresultframes (1/30s)
MM:SS.CC
- Game::timetstring(int t)
// t = seconds
MM:SS
- Game::timestringcenti(char* buffer, const size_t buffer_size)
// uses game.hours/minutes/seconds/frames
H:MM:SS.CC
MM:SS.CC
- UtilityClass::timestring(int t)
// t = frames, 30 frames = 1 second
S:CC
M:SS:CC
This is kind of a mess, and there's a lot of functions that do the same
thing except using different variables. For localization, I also want
translators to be able to localize all these time formats - many
languages use the decimal comma instead of the decimal point (12:34,56)
maybe some languages really prefer something like 1時02分11秒44瞬...
Which I don't know to be correct, but it's good to be prepared for it
and not restrict translators arbitrarily to only changing ":" and "."
when we can start making the system better in the first place.
I added a new function, UtilityClass::format_time. This is the place
where all time formats come together, given the number of seconds and
optionally frames. I have simplified the above-mentioned functions
somewhat, but I haven't given them a complete refactor or renaming -
I mainly made sure that they all use the same backend so I can make the
formats consistent and properly localizable.
(And before we start shoving more temporary char buffers everywhere
just to get rid of the std::string's, maybe we need to think of a
globally used working buffer of size SCREEN_WIDTH_CHARS+1, as a
register of sorts, for when any line of text needs to be made or
processed, then printed, and then goes unused. Maybe help.textrow,
or something like that.)
As for this commit, the available time formats are now more consistent
and changed a little in some places. Leading zeroes for the first unit
are now no longer included, time trial results and the Super Gravitron
can now display hours when they went to 60 minutes before, and we now
always use .CC instead of :CC. These are the formats:
- H:MM:SS
- H:MM:SS.CC
- M:SS
- M:SS.CC
- S.CC (only used when always_minutes=false, for the Gravitrons)
Here's what changes to the current functions:
- Game::partimestring() is removed - it was used in two places, and
could be replaced by game.timetstring(game.timetrialpar)
- Game::giventimestring(h,m,s) and Game::timestring() are now wrappers
for the other functions
- The four remaining functions (Game::resulttimestring(),
Game::timetstring(t), Game::timestringcenti(buffer, buffer_size)
and UtilityClass::timestring(t)) are now wrappers for the "central
function", UtilityClass::format_time.
- UtilityClass::twodigits(int t) is now unused so it's also removed.
- I also added int UtilityClass::hms_to_seconds(int h, int m, int s)
2021-12-25 17:13:46 +01:00
graphics . bprint ( 275 , 214 , game . timetstring ( game . timetrialpar ) , 196 , 196 , 196 ) ;
2020-01-01 21:29:24 +01:00
}
}
}
2020-04-29 06:58:19 +02:00
float act_alpha = graphics . lerp ( game . prev_act_fade , game . act_fade ) / 10.0f ;
2020-08-25 03:13:57 +02:00
if ( game . act_fade > 5 | | game . prev_act_fade > 5 )
2020-01-01 21:29:24 +01:00
{
2021-09-13 06:39:07 +02:00
char buffer [ SCREEN_WIDTH_CHARS + 1 ] ;
2021-04-19 08:23:44 +02:00
const char * final_string = interact_prompt (
buffer ,
sizeof ( buffer ) ,
game . activity_lastprompt . c_str ( )
) ;
Add `setactivityposition(x,y)`, add new textbox color `transparent` (#847)
* Add `setactivityposition(x,y)`, add new textbox color `transparent`
This commit adds a new internal command as a part of the visual activity zone changes I've been making.
This one allows the user to reposition the activity zone to anywhere on the screen.
In addition, this commit adds the textbox color `transparent`, which just sets r, g and b to 0.
rgb(0, 0, 0) normally creates the color black, however in VVVVVV textboxes, it makes the background
of them invisible, and makes the text the off-white color which the game uses elsewhere.
* add new variables to hardreset
* Fix unwanted text centering; offset position by 16, 4
It makes sense for `setactivityposition(0, 0)` to place the activity zone in the default position,
so the x has been offset by 16, and the y has been offset by 4.
Text was being automatically centered, meaning any activity zone which wasn't centered had misplaced text.
This has been fixed by calculating the center manually, and offsetting it by the passed value.
2021-10-14 00:38:51 +02:00
int centered_x = ( ( 160 ) - ( ( graphics . len ( final_string ) ) / 2 ) ) ;
if ( game . activity_r = = 0 & & game . activity_g = = 0 & & game . activity_b = = 0 )
{
graphics . bprint ( centered_x + game . activity_x , game . activity_y + 12 , final_string , 196 * act_alpha , 196 * act_alpha , ( 255 - help . glow ) * act_alpha ) ;
}
else
{
graphics . drawtextbox ( game . activity_x + 16 , game . activity_y + 4 , 36 , 3 , game . activity_r * act_alpha , game . activity_g * act_alpha , game . activity_b * act_alpha ) ;
graphics . Print ( centered_x + game . activity_x , game . activity_y + 12 , final_string , game . activity_r * act_alpha , game . activity_g * act_alpha , game . activity_b * act_alpha ) ;
}
2020-01-01 21:29:24 +01:00
}
2020-08-03 06:02:27 +02:00
if ( obj . trophytext > 0 | | obj . oldtrophytext > 0 )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . drawtrophytext ( ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-27 04:24:50 +02:00
graphics . renderwithscreeneffects ( ) ;
2020-01-01 21:29:24 +01:00
}
2021-10-02 03:29:55 +02:00
/* Used to keep some graphics positions on the map screen
* the same in Flip Mode . */
# define FLIP(y, h) (graphics.flipmode ? 220 - (y) - (h) : (y))
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 maprender ( void )
2020-01-01 21:29:24 +01:00
{
2021-02-26 00:37:03 +01:00
ClearSurface ( graphics . backBuffer ) ;
2020-05-02 21:18:54 +02:00
2020-01-01 21:29:24 +01:00
//draw screen alliteration
//Roomname:
2021-09-13 06:54:47 +02:00
if ( map . hiddenname [ 0 ] ! = ' \0 ' )
2020-01-01 21:29:24 +01:00
{
Refactor how "hidden names" work
By "hidden names", I'm referring to "Dimension VVVVVV" and "The Ship"
popping up on the quit/pause/teleporter screens, even though those rooms
don't have any roomnames.
Apparently my commit to fix roomname re-draw bleed on the
quit/pause/teleporter screens exposed yet another hardreset()-caused
bug. The issue here is that since hardreset() sets game.roomx and
game.roomy to 0, map.area() will no longer work properly, and since the
hidden roomname check is based on map.area(), it will no longer display
"Dimension VVVVVV" or "The Ship" once you press ACTION to quit. It used
to do this due to the re-draw bleed, but now it doesn't.
I saw that roomnames didn't get reset in hardreset(), so the solution
here is to re-factor hidden names to be an actual variable, instead of
being implicit. map.hiddenname is a variable that's set in
mapclass::loadlevel(), and if isn't empty, it will be drawn on the
quit/pause/teleporter screens. That way it will still display "Dimension
VVVVVV" and "The Ship" when you press ACTION to quit to the menu.
EDIT: Since PR #230 got merged, this commit is no longer strictly
necessary, but it's still good to refactor hidden names like this.
2020-05-02 23:10:22 +02:00
graphics . Print ( 5 , 2 , map . hiddenname , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
if ( map . finalmode ) {
2020-04-01 23:59:19 +02:00
graphics . Print ( 5 , 2 , map . glitchname , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
} else {
2020-04-01 23:59:19 +02:00
graphics . Print ( 5 , 2 , map . roomname , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
}
//Background color
2020-04-01 23:59:19 +02:00
FillRect ( graphics . backBuffer , 0 , 12 , 320 , 240 , 10 , 24 , 26 ) ;
2020-01-01 21:29:24 +01:00
//Menubar:
2021-06-12 00:07:08 +02:00
graphics . drawtextbox ( - 10 , 212 , 43 , 3 , 65 , 185 , 207 ) ;
2020-06-21 03:47:25 +02:00
// Draw the selected page name at the bottom
// menupage 0 - 3 is the pause screen
2020-11-16 03:12:28 +01:00
if ( script . running & & game . menupage = = 3 )
{
// While in a cutscene, you can only save
graphics . Print ( - 1 , 220 , " [SAVE] " , 196 , 196 , 255 - help . glow , true ) ;
}
else if ( game . menupage < = 3 )
2020-01-01 21:29:24 +01:00
{
2020-06-21 03:47:25 +02:00
std : : string tab1 ;
2020-01-01 21:29:24 +01:00
if ( game . insecretlab )
{
2020-06-21 03:47:25 +02:00
tab1 = " GRAV " ;
2020-01-01 21:29:24 +01:00
}
2020-04-09 08:34:26 +02:00
else if ( obj . flags [ 67 ] & & ! map . custommode )
2020-01-01 21:29:24 +01:00
{
2020-06-21 03:47:25 +02:00
tab1 = " SHIP " ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-06-21 03:47:25 +02:00
tab1 = " CREW " ;
2020-01-01 21:29:24 +01:00
}
2020-06-21 03:47:25 +02:00
# define TAB(opt, text) graphics.map_tab(opt, text, game.menupage == opt)
TAB ( 0 , " MAP " ) ;
TAB ( 1 , tab1 ) ;
TAB ( 2 , " STATS " ) ;
TAB ( 3 , " SAVE " ) ;
# undef TAB
}
2020-01-01 21:29:24 +01:00
2020-06-23 00:24:18 +02:00
// Draw menu header
switch ( game . menupage )
{
case 30 :
case 31 :
case 32 :
case 33 :
graphics . Print ( - 1 , 220 , " [ PAUSE ] " , 196 , 196 , 255 - help . glow , true ) ;
}
// Draw menu options
if ( game . menupage > = 30 & & game . menupage < = 33 )
{
# define OPTION(opt, text) graphics.map_option(opt, 4, text, game.menupage - 30 == opt)
OPTION ( 0 , " return to game " ) ;
2021-04-09 17:53:55 +02:00
OPTION ( 1 , " options " ) ;
OPTION ( 2 , " quit to menu " ) ;
2020-06-23 00:24:18 +02:00
# undef OPTION
}
2020-06-21 03:47:25 +02:00
// Draw the actual menu
switch ( game . menupage )
{
case 0 :
2020-01-01 21:29:24 +01:00
if ( map . finalmode | | ( map . custommode & & ! map . customshowmm ) )
{
//draw the map image
2021-09-04 00:26:57 +02:00
graphics . drawpixeltextbox ( 35 , 16 , 250 , 190 , 65 , 185 , 207 ) ;
2020-04-01 23:59:19 +02:00
graphics . drawimage ( 1 , 40 , 21 , false ) ;
2020-01-01 21:29:24 +01:00
for ( int j = 0 ; j < 20 ; j + + )
{
for ( int i = 0 ; i < 20 ; i + + )
{
2020-04-01 23:59:19 +02:00
graphics . drawimage ( 2 , 40 + ( i * 12 ) , 21 + ( j * 9 ) , false ) ;
2020-01-01 21:29:24 +01:00
}
}
2021-12-21 05:07:38 +01:00
graphics . bprint ( - 1 , 105 , " NO SIGNAL " , 245 , 245 , 245 , true ) ;
2020-01-01 21:29:24 +01:00
}
2021-04-19 08:39:10 +02:00
# ifndef NO_CUSTOM_LEVELS
2020-01-01 21:29:24 +01:00
else if ( map . custommode )
{
//draw the map image
2021-09-04 00:26:57 +02:00
graphics . drawpixeltextbox ( 35 + map . custommmxoff , 16 + map . custommmyoff , map . custommmxsize + 10 , map . custommmysize + 10 , 65 , 185 , 207 ) ;
2021-04-19 08:39:10 +02:00
if ( graphics . minimap_mounted )
{
graphics . drawpartimage ( 1 , 40 + map . custommmxoff , 21 + map . custommmyoff , map . custommmxsize , map . custommmysize ) ;
}
else
{
graphics . drawpartimage ( 12 , 40 + map . custommmxoff , 21 + map . custommmyoff , map . custommmxsize , map . custommmysize ) ;
}
2020-01-01 21:29:24 +01:00
//Black out here
if ( map . customzoom = = 4 ) {
for ( int j = 0 ; j < map . customheight ; j + + ) {
for ( int i = 0 ; i < map . customwidth ; i + + ) {
2021-03-24 20:12:39 +01:00
if ( ! map . isexplored ( i , j ) ) {
2020-01-01 21:29:24 +01:00
//Draw the fog of war on the map
2020-04-01 23:59:19 +02:00
graphics . drawimage ( 2 , map . custommmxoff + 40 + ( i * 48 ) , map . custommmyoff + 21 + ( j * 36 ) , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + 12 + ( i * 48 ) , map . custommmyoff + 21 + ( j * 36 ) , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + ( i * 48 ) , map . custommmyoff + 21 + 9 + ( j * 36 ) , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + 12 + ( i * 48 ) , map . custommmyoff + 21 + 9 + ( j * 36 ) , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + ( i * 48 ) + 24 , map . custommmyoff + 21 + ( j * 36 ) , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + 12 + ( i * 48 ) + 24 , map . custommmyoff + 21 + ( j * 36 ) , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + ( i * 48 ) + 24 , map . custommmyoff + 21 + 9 + ( j * 36 ) , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + 12 + ( i * 48 ) + 24 , map . custommmyoff + 21 + 9 + ( j * 36 ) , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + ( i * 48 ) , map . custommmyoff + 21 + ( j * 36 ) + 18 , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + 12 + ( i * 48 ) , map . custommmyoff + 21 + ( j * 36 ) + 18 , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + ( i * 48 ) , map . custommmyoff + 21 + 9 + ( j * 36 ) + 18 , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + 12 + ( i * 48 ) , map . custommmyoff + 21 + 9 + ( j * 36 ) + 18 , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + ( i * 48 ) + 24 , map . custommmyoff + 21 + ( j * 36 ) + 18 , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + 12 + ( i * 48 ) + 24 , map . custommmyoff + 21 + ( j * 36 ) + 18 , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + ( i * 48 ) + 24 , map . custommmyoff + 21 + 9 + ( j * 36 ) + 18 , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + 12 + ( i * 48 ) + 24 , map . custommmyoff + 21 + 9 + ( j * 36 ) + 18 , false ) ;
2020-01-01 21:29:24 +01:00
}
}
}
} else if ( map . customzoom = = 2 ) {
for ( int j = 0 ; j < map . customheight ; j + + ) {
for ( int i = 0 ; i < map . customwidth ; i + + ) {
2021-03-24 20:12:39 +01:00
if ( ! map . isexplored ( i , j ) ) {
2020-01-01 21:29:24 +01:00
//Draw the fog of war on the map
2020-04-01 23:59:19 +02:00
graphics . drawimage ( 2 , map . custommmxoff + 40 + ( i * 24 ) , map . custommmyoff + 21 + ( j * 18 ) , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + 12 + ( i * 24 ) , map . custommmyoff + 21 + ( j * 18 ) , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + ( i * 24 ) , map . custommmyoff + 21 + 9 + ( j * 18 ) , false ) ;
graphics . drawimage ( 2 , map . custommmxoff + 40 + 12 + ( i * 24 ) , map . custommmyoff + 21 + 9 + ( j * 18 ) , false ) ;
2020-01-01 21:29:24 +01:00
}
}
}
} else {
for ( int j = 0 ; j < map . customheight ; j + + ) {
for ( int i = 0 ; i < map . customwidth ; i + + ) {
2021-03-24 20:12:39 +01:00
if ( ! map . isexplored ( i , j ) ) {
2020-01-01 21:29:24 +01:00
//Draw the fog of war on the map
2020-04-01 23:59:19 +02:00
graphics . drawimage ( 2 , map . custommmxoff + 40 + ( i * 12 ) , map . custommmyoff + 21 + ( j * 9 ) , false ) ;
2020-01-01 21:29:24 +01:00
}
}
}
}
//normal size maps
if ( map . customzoom = = 4 ) {
if ( map . cursorstate = = 1 ) {
if ( int ( map . cursordelay / 4 ) % 2 = = 0 ) {
2020-04-01 23:59:19 +02:00
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 48 ) + map . custommmxoff , 21 + ( ( game . roomy - 100 ) * 36 ) + map . custommmyoff , 48 , 36 , 255 , 255 , 255 ) ;
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 48 ) + 2 + map . custommmxoff , 21 + ( ( game . roomy - 100 ) * 36 ) + 2 + map . custommmyoff , 48 - 4 , 36 - 4 , 255 , 255 , 255 ) ;
2020-01-01 21:29:24 +01:00
}
} else if ( map . cursorstate = = 2 ) {
if ( int ( map . cursordelay / 15 ) % 2 = = 0 ) {
2020-04-01 23:59:19 +02:00
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 48 ) + 2 + map . custommmxoff , 21 + ( ( game . roomy - 100 ) * 36 ) + 2 + map . custommmyoff , 48 - 4 , 36 - 4 , 16 , 245 - ( help . glow ) , 245 - ( help . glow ) ) ;
2020-01-01 21:29:24 +01:00
}
}
} else if ( map . customzoom = = 2 ) {
if ( map . cursorstate = = 1 ) {
if ( int ( map . cursordelay / 4 ) % 2 = = 0 ) {
2020-04-01 23:59:19 +02:00
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 24 ) + map . custommmxoff , 21 + ( ( game . roomy - 100 ) * 18 ) + map . custommmyoff , 24 , 18 , 255 , 255 , 255 ) ;
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 24 ) + 2 + map . custommmxoff , 21 + ( ( game . roomy - 100 ) * 18 ) + 2 + map . custommmyoff , 24 - 4 , 18 - 4 , 255 , 255 , 255 ) ;
2020-01-01 21:29:24 +01:00
}
} else if ( map . cursorstate = = 2 ) {
if ( int ( map . cursordelay / 15 ) % 2 = = 0 ) {
2020-04-01 23:59:19 +02:00
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 24 ) + 2 + map . custommmxoff , 21 + ( ( game . roomy - 100 ) * 18 ) + 2 + map . custommmyoff , 24 - 4 , 18 - 4 , 16 , 245 - ( help . glow ) , 245 - ( help . glow ) ) ;
2020-01-01 21:29:24 +01:00
}
}
} else {
if ( map . cursorstate = = 1 ) {
if ( int ( map . cursordelay / 4 ) % 2 = = 0 ) {
2020-04-01 23:59:19 +02:00
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 12 ) + map . custommmxoff , 21 + ( ( game . roomy - 100 ) * 9 ) + map . custommmyoff , 12 , 9 , 255 , 255 , 255 ) ;
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 12 ) + 2 + map . custommmxoff , 21 + ( ( game . roomy - 100 ) * 9 ) + 2 + map . custommmyoff , 12 - 4 , 9 - 4 , 255 , 255 , 255 ) ;
2020-01-01 21:29:24 +01:00
}
} else if ( map . cursorstate = = 2 ) {
if ( int ( map . cursordelay / 15 ) % 2 = = 0 ) {
2020-04-01 23:59:19 +02:00
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 12 ) + 2 + map . custommmxoff , 21 + ( ( game . roomy - 100 ) * 9 ) + 2 + map . custommmyoff , 12 - 4 , 9 - 4 , 16 , 245 - ( help . glow ) , 245 - ( help . glow ) ) ;
2020-01-01 21:29:24 +01:00
}
}
}
2020-06-30 22:19:56 +02:00
if ( map . showtrinkets ) {
for ( size_t i = 0 ; i < map . shinytrinkets . size ( ) ; i + + ) {
if ( ! obj . collect [ i ] ) {
int temp = 1086 ;
if ( graphics . flipmode ) temp + = 3 ;
if ( map . customzoom = = 4 ) {
graphics . drawtile ( 40 + ( map . shinytrinkets [ i ] . x * 48 ) + 20 + map . custommmxoff , 21 + ( map . shinytrinkets [ i ] . y * 36 ) + 14 + map . custommmyoff , temp ) ;
} else if ( map . customzoom = = 2 ) {
graphics . drawtile ( 40 + ( map . shinytrinkets [ i ] . x * 24 ) + 8 + map . custommmxoff , 21 + ( map . shinytrinkets [ i ] . y * 18 ) + 5 + map . custommmyoff , temp ) ;
} else {
graphics . drawtile ( 40 + 3 + ( map . shinytrinkets [ i ] . x * 12 ) + map . custommmxoff , 22 + ( map . shinytrinkets [ i ] . y * 9 ) + map . custommmyoff , temp ) ;
}
}
}
}
2020-01-01 21:29:24 +01:00
}
2021-04-19 08:39:10 +02:00
# endif /* NO_CUSTOM_LEVELS */
2020-01-01 21:29:24 +01:00
else
{
//draw the map image
2021-09-04 00:26:57 +02:00
graphics . drawpixeltextbox ( 35 , 16 , 250 , 190 , 65 , 185 , 207 ) ;
2020-04-01 23:59:19 +02:00
graphics . drawimage ( 1 , 40 , 21 , false ) ;
2020-01-01 21:29:24 +01:00
//black out areas we can't see yet
for ( int j = 0 ; j < 20 ; j + + )
{
for ( int i = 0 ; i < 20 ; i + + )
{
2021-03-24 20:12:39 +01:00
if ( ! map . isexplored ( i , j ) )
2020-01-01 21:29:24 +01:00
{
//Draw the fog of war on the map
2020-04-01 23:59:19 +02:00
graphics . drawimage ( 2 , 40 + ( i * 12 ) , 21 + ( j * 9 ) , false ) ;
2020-01-01 21:29:24 +01:00
}
}
}
//draw the coordinates
if ( game . roomx = = 109 )
{
//tower!instead of room y, scale map.ypos
2020-04-29 06:32:53 +02:00
if ( map . cursorstate = = 1 )
2020-01-01 21:29:24 +01:00
{
if ( int ( map . cursordelay / 4 ) % 2 = = 0 )
{
2020-04-01 23:59:19 +02:00
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 12 ) , 21 , 12 , 180 , 255 , 255 , 255 ) ;
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 12 ) + 2 , 21 + 2 , 12 - 4 , 180 - 4 , 255 , 255 , 255 ) ;
2020-01-01 21:29:24 +01:00
}
if ( map . cursordelay > 30 ) map . cursorstate = 2 ;
}
else if ( map . cursorstate = = 2 )
{
if ( int ( map . cursordelay / 15 ) % 2 = = 0 )
{
2020-04-01 23:59:19 +02:00
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 12 ) + 2 , 21 + 2 , 12 - 4 , 180 - 4 , 16 , 245 - ( help . glow ) , 245 - ( help . glow ) ) ;
2020-01-01 21:29:24 +01:00
}
}
}
else
{
2020-04-29 06:32:53 +02:00
if ( map . cursorstate = = 1 )
2020-01-01 21:29:24 +01:00
{
if ( int ( map . cursordelay / 4 ) % 2 = = 0 )
{
2020-04-01 23:59:19 +02:00
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 12 ) , 21 + ( ( game . roomy - 100 ) * 9 ) , 12 , 9 , 255 , 255 , 255 ) ;
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 12 ) + 2 , 21 + ( ( game . roomy - 100 ) * 9 ) + 2 , 12 - 4 , 9 - 4 , 255 , 255 , 255 ) ;
2020-01-01 21:29:24 +01:00
}
}
else if ( map . cursorstate = = 2 )
{
if ( int ( map . cursordelay / 15 ) % 2 = = 0 )
{
2020-04-01 23:59:19 +02:00
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 12 ) + 2 , 21 + ( ( game . roomy - 100 ) * 9 ) + 2 , 12 - 4 , 9 - 4 , 16 , 245 - ( help . glow ) , 245 - ( help . glow ) ) ;
2020-01-01 21:29:24 +01:00
}
}
}
//draw legend details
2020-04-15 04:32:30 +02:00
for ( size_t i = 0 ; i < map . teleporters . size ( ) ; i + + )
2020-01-01 21:29:24 +01:00
{
2021-03-24 20:12:39 +01:00
if ( map . showteleporters & & map . isexplored ( map . teleporters [ i ] . x , map . teleporters [ i ] . y ) )
2020-01-01 21:29:24 +01:00
{
2021-03-24 20:12:39 +01:00
int temp = 1126 + ( int ) map . isexplored ( map . teleporters [ i ] . x , map . teleporters [ i ] . y ) ;
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode ) temp + = 3 ;
graphics . drawtile ( 40 + 3 + ( map . teleporters [ i ] . x * 12 ) , 22 + ( map . teleporters [ i ] . y * 9 ) , temp ) ;
2020-01-01 21:29:24 +01:00
}
2021-03-26 04:37:42 +01:00
else if ( map . showtargets & & ! map . isexplored ( map . teleporters [ i ] . x , map . teleporters [ i ] . y ) )
2020-01-01 21:29:24 +01:00
{
2021-03-24 20:12:39 +01:00
int temp = 1126 + ( int ) map . isexplored ( map . teleporters [ i ] . x , map . teleporters [ i ] . y ) ;
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode ) temp + = 3 ;
graphics . drawtile ( 40 + 3 + ( map . teleporters [ i ] . x * 12 ) , 22 + ( map . teleporters [ i ] . y * 9 ) , temp ) ;
2020-01-01 21:29:24 +01:00
}
}
if ( map . showtrinkets )
{
2020-04-15 04:39:08 +02:00
for ( size_t i = 0 ; i < map . shinytrinkets . size ( ) ; i + + )
2020-01-01 21:29:24 +01:00
{
2020-04-09 08:56:36 +02:00
if ( ! obj . collect [ i ] )
2020-01-01 21:29:24 +01:00
{
2020-04-03 03:50:37 +02:00
int temp = 1086 ;
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode ) temp + = 3 ;
2021-09-07 03:56:39 +02:00
graphics . drawtile ( 40 + 3 + ( map . shinytrinkets [ i ] . x * 12 ) , 22 + ( map . shinytrinkets [ i ] . y * 9 ) , temp ) ;
2020-01-01 21:29:24 +01:00
}
}
}
}
break ;
case 1 :
if ( game . insecretlab )
{
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 174 , " SUPER GRAVITRON HIGHSCORE " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
2020-04-03 00:05:41 +02:00
std : : string tempstring = help . timestring ( game . swnrecord ) ;
2020-04-01 23:59:19 +02:00
graphics . Print ( 240 , 124 , " Best Time " , 196 , 196 , 255 - help . glow , true ) ;
graphics . bigrprint ( 300 , 94 , tempstring , 196 , 196 , 255 - help . glow , true , 2 ) ;
2020-01-01 21:29:24 +01:00
switch ( game . swnbestrank )
{
case 0 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 40 , " Next Trophy at 5 seconds " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 1 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 40 , " Next Trophy at 10 seconds " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 2 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 40 , " Next Trophy at 15 seconds " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 3 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 40 , " Next Trophy at 20 seconds " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 4 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 40 , " Next Trophy at 30 seconds " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 5 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 40 , " Next Trophy at 1 minute " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 6 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 40 , " All Trophies collected! " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
}
}
else
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 40 , " SUPER GRAVITRON HIGHSCORE " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
2020-04-03 00:05:41 +02:00
std : : string tempstring = help . timestring ( game . swnrecord ) ;
2020-04-01 23:59:19 +02:00
graphics . Print ( 240 , 90 , " Best Time " , 196 , 196 , 255 - help . glow , true ) ;
graphics . bigrprint ( 300 , 104 , tempstring , 196 , 196 , 255 - help . glow , true , 2 ) ;
2020-01-01 21:29:24 +01:00
switch ( game . swnbestrank )
{
case 0 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 174 , " Next Trophy at 5 seconds " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 1 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 174 , " Next Trophy at 10 seconds " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 2 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 174 , " Next Trophy at 15 seconds " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 3 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 174 , " Next Trophy at 20 seconds " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 4 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 174 , " Next Trophy at 30 seconds " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 5 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 174 , " Next Trophy at 1 minute " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
case 6 :
2020-04-01 23:59:19 +02:00
graphics . Print ( - 1 , 174 , " All Trophies collected! " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
break ;
}
}
}
2020-04-09 08:34:26 +02:00
else if ( obj . flags [ 67 ] & & ! map . custommode )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 105 , " Press ACTION to warp to the ship. " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-02 23:19:15 +02:00
# if !defined(NO_CUSTOM_LEVELS)
2020-01-01 21:29:24 +01:00
else if ( map . custommode ) {
2021-02-21 00:40:11 +01:00
LevelMetaData & meta = cl . ListOfMetaData [ game . playcustomlevel ] ;
2020-06-21 04:27:32 +02:00
2021-10-02 03:29:55 +02:00
graphics . bigprint ( - 1 , FLIP ( 45 , 8 ) , meta . title , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( - 1 , FLIP ( 70 , 8 ) , " by " + meta . creator , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( - 1 , FLIP ( 80 , 8 ) , meta . website , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( - 1 , FLIP ( 100 , 8 ) , meta . Desc1 , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( - 1 , FLIP ( 110 , 8 ) , meta . Desc2 , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( - 1 , FLIP ( 120 , 8 ) , meta . Desc3 , 196 , 196 , 255 - help . glow , true ) ;
2020-06-21 04:14:40 +02:00
2021-02-21 00:40:11 +01:00
int remaining = cl . numcrewmates ( ) - game . crewmates ( ) ;
2020-06-21 04:29:50 +02:00
if ( remaining = = 1 ) {
2021-10-02 03:29:55 +02:00
graphics . Print ( 1 , FLIP ( 165 , 8 ) , help . number_words ( remaining ) + " crewmate remains " , 196 , 196 , 255 - help . glow , true ) ;
2020-06-21 04:29:50 +02:00
} else if ( remaining > 0 ) {
2021-10-02 03:29:55 +02:00
graphics . Print ( 1 , FLIP ( 165 , 8 ) , help . number_words ( remaining ) + " crewmates remain " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
}
2020-04-02 23:19:15 +02:00
# endif
2020-01-01 21:29:24 +01:00
else
{
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode )
2020-01-01 21:29:24 +01:00
{
for ( int i = 0 ; i < 3 ; i + + )
{
2020-04-01 23:59:19 +02:00
graphics . drawcrewman ( 16 , 32 + ( i * 64 ) , 2 - i , game . crewstats [ 2 - i ] ) ;
2020-01-01 21:29:24 +01:00
if ( game . crewstats [ ( 2 - i ) ] )
{
2020-04-01 23:59:19 +02:00
graphics . printcrewname ( 44 , 32 + ( i * 64 ) + 4 + 10 , 2 - i ) ;
graphics . printcrewnamestatus ( 44 , 32 + ( i * 64 ) + 4 , 2 - i ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . printcrewnamedark ( 44 , 32 + ( i * 64 ) + 4 + 10 , 2 - i ) ;
graphics . Print ( 44 , 32 + ( i * 64 ) + 4 , " Missing... " , 64 , 64 , 64 ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-01 23:59:19 +02:00
graphics . drawcrewman ( 16 + 160 , 32 + ( i * 64 ) , ( 2 - i ) + 3 , game . crewstats [ ( 2 - i ) + 3 ] ) ;
2020-01-01 21:29:24 +01:00
if ( game . crewstats [ ( 2 - i ) + 3 ] )
{
2020-04-01 23:59:19 +02:00
graphics . printcrewname ( 44 + 160 , 32 + ( i * 64 ) + 4 + 10 , ( 2 - i ) + 3 ) ;
graphics . printcrewnamestatus ( 44 + 160 , 32 + ( i * 64 ) + 4 , ( 2 - i ) + 3 ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . printcrewnamedark ( 44 + 160 , 32 + ( i * 64 ) + 4 + 10 , ( 2 - i ) + 3 ) ;
graphics . Print ( 44 + 160 , 32 + ( i * 64 ) + 4 , " Missing... " , 64 , 64 , 64 ) ;
2020-01-01 21:29:24 +01:00
}
}
}
else
{
for ( int i = 0 ; i < 3 ; i + + )
{
2020-04-01 23:59:19 +02:00
graphics . drawcrewman ( 16 , 32 + ( i * 64 ) , i , game . crewstats [ i ] ) ;
2020-01-01 21:29:24 +01:00
if ( game . crewstats [ i ] )
{
2020-04-01 23:59:19 +02:00
graphics . printcrewname ( 44 , 32 + ( i * 64 ) + 4 , i ) ;
graphics . printcrewnamestatus ( 44 , 32 + ( i * 64 ) + 4 + 10 , i ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . printcrewnamedark ( 44 , 32 + ( i * 64 ) + 4 , i ) ;
graphics . Print ( 44 , 32 + ( i * 64 ) + 4 + 10 , " Missing... " , 64 , 64 , 64 ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-01 23:59:19 +02:00
graphics . drawcrewman ( 16 + 160 , 32 + ( i * 64 ) , i + 3 , game . crewstats [ i + 3 ] ) ;
2020-01-01 21:29:24 +01:00
if ( game . crewstats [ i + 3 ] )
{
2020-04-01 23:59:19 +02:00
graphics . printcrewname ( 44 + 160 , 32 + ( i * 64 ) + 4 , i + 3 ) ;
graphics . printcrewnamestatus ( 44 + 160 , 32 + ( i * 64 ) + 4 + 10 , i + 3 ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . printcrewnamedark ( 44 + 160 , 32 + ( i * 64 ) + 4 , i + 3 ) ;
graphics . Print ( 44 + 160 , 32 + ( i * 64 ) + 4 + 10 , " Missing... " , 64 , 64 , 64 ) ;
2020-01-01 21:29:24 +01:00
}
}
}
}
break ;
case 2 :
2021-09-26 02:16:52 +02:00
{
int total ;
# ifndef NO_CUSTOM_LEVELS
if ( map . custommode )
2020-04-09 06:56:47 +02:00
{
2021-09-26 02:16:52 +02:00
total = cl . numtrinkets ( ) ;
2020-04-09 06:56:47 +02:00
}
else
# endif
{
2021-09-26 02:16:52 +02:00
total = 20 ;
}
2020-01-01 21:29:24 +01:00
2021-09-26 02:16:52 +02:00
/* Stats. */
2021-10-02 03:29:55 +02:00
graphics . Print ( 0 , FLIP ( 52 , 8 ) , " [Trinkets found] " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 0 , FLIP ( 64 , 8 ) , help . number_words ( game . trinkets ( ) ) + " out of " + help . number_words ( total ) , 96 , 96 , 96 , true ) ;
2020-01-01 21:29:24 +01:00
2021-10-02 03:29:55 +02:00
graphics . Print ( 0 , FLIP ( 102 , 8 ) , " [Number of Deaths] " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 0 , FLIP ( 114 , 8 ) , help . String ( game . deathcounts ) , 96 , 96 , 96 , true ) ;
2020-01-01 21:29:24 +01:00
2021-10-02 03:29:55 +02:00
graphics . Print ( 0 , FLIP ( 152 , 8 ) , " [Time Taken] " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 0 , FLIP ( 164 , 8 ) , game . timestring ( ) , 96 , 96 , 96 , true ) ;
2020-01-01 21:29:24 +01:00
break ;
2021-09-26 02:16:52 +02:00
}
2020-01-01 21:29:24 +01:00
case 3 :
2021-10-02 06:06:31 +02:00
{
2020-01-01 21:29:24 +01:00
if ( game . inintermission )
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 115 , " Cannot Save in Level Replay " , 146 , 146 , 180 , true ) ;
2021-10-02 06:06:31 +02:00
break ;
2020-01-01 21:29:24 +01:00
}
2021-10-02 06:06:31 +02:00
if ( game . nodeathmode )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 115 , " Cannot Save in No Death Mode " , 146 , 146 , 180 , true ) ;
2021-10-02 06:06:31 +02:00
break ;
2020-01-01 21:29:24 +01:00
}
2021-10-02 06:06:31 +02:00
if ( game . intimetrial )
2020-01-01 21:29:24 +01:00
{
2021-10-02 18:24:44 +02:00
graphics . Print ( 0 , 115 , " How'd you get here? " , 146 , 146 , 180 , true ) ;
2021-10-02 06:06:31 +02:00
break ;
2020-01-01 21:29:24 +01:00
}
2021-10-02 06:06:31 +02:00
if ( game . insecretlab )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 115 , " Cannot Save in Secret Lab " , 146 , 146 , 180 , true ) ;
2021-10-02 06:06:31 +02:00
break ;
2020-01-01 21:29:24 +01:00
}
2021-10-02 06:06:31 +02:00
if ( game . gamesavefailed )
2020-11-04 03:45:33 +01:00
{
graphics . Print ( 0 , 115 , " ERROR: Could not save game! " , 146 , 146 , 180 , true ) ;
2021-10-02 06:06:31 +02:00
break ;
2020-11-04 03:45:33 +01:00
}
2020-01-01 21:29:24 +01:00
2021-10-02 06:06:31 +02:00
/* We are not in a special case, so draw the save screen now... */
2020-01-01 21:29:24 +01:00
2021-10-02 06:06:31 +02:00
if ( ! map . custommode )
{
/* FIXME: The text here should be automatically "balance-wrapped" instead of hardcoding the width. */
graphics . PrintWrap ( 0 , 174 , " (Note: The game is autosaved at every teleporter.) " , 146 , 146 , 180 , true , 12 , 240 ) ;
2020-01-01 21:29:24 +01:00
}
2021-10-02 06:06:31 +02:00
if ( ! game . gamesaved )
2020-01-01 21:29:24 +01:00
{
2021-10-02 06:06:31 +02:00
graphics . Print ( 0 , 80 , " [Press ACTION to save your game] " , 255 - help . glow * 2 , 255 - help . glow * 2 , 255 - help . glow , true ) ;
if ( map . custommode | | game . quicksummary = = " " )
2020-01-01 21:29:24 +01:00
{
2021-10-02 06:06:31 +02:00
break ;
2020-01-01 21:29:24 +01:00
}
2021-10-02 06:06:31 +02:00
graphics . Print ( 0 , FLIP ( 100 , 8 ) , " Last Save: " , 164 - help . glow / 4 , 164 - help . glow / 4 , 164 , true ) ;
graphics . Print ( 0 , FLIP ( 110 , 8 ) , game . quicksummary , 164 - help . glow / 4 , 164 - help . glow / 4 , 164 , true ) ;
break ;
}
2020-01-01 21:29:24 +01:00
2021-10-02 06:06:31 +02:00
/* We are only still here if the game has been quicksaved... */
2020-01-01 21:29:24 +01:00
2021-10-02 06:06:31 +02:00
graphics . Print ( 0 , 36 , " Game saved ok! " , 255 - help . glow / 2 , 255 - help . glow / 2 , 255 - help . glow / 2 , true ) ;
2020-01-01 21:29:24 +01:00
2021-10-02 06:06:31 +02:00
graphics . drawpixeltextbox ( 17 , 65 , 286 , 90 , 65 , 185 , 207 ) ;
2020-01-01 21:29:24 +01:00
2021-10-02 06:06:31 +02:00
if ( map . custommode )
{
graphics . Print ( 0 , FLIP ( 90 , 8 ) , game . customleveltitle , 25 , 255 - help . glow / 2 , 255 - help . glow / 2 , true ) ;
}
else
{
size_t i ;
graphics . Print ( 0 , FLIP ( 80 , 8 ) , game . savearea , 25 , 255 - help . glow / 2 , 255 - help . glow / 2 , true ) ;
for ( i = 0 ; i < SDL_arraysize ( game . crewstats ) ; + + i )
2020-01-01 21:29:24 +01:00
{
2021-10-02 06:06:31 +02:00
/* Crewmates are annoying. Their height is 21 pixels, but to flip them,
* we also have to account for their 2 - pixel y - offset ( and multiply it by 2 ) . */
graphics . drawcrewman ( 169 - 3 * 42 + i * 42 , FLIP ( 95 , 21 + 2 * 2 ) , i , game . crewstats [ i ] , true ) ;
2020-01-01 21:29:24 +01:00
}
}
2021-10-02 06:06:31 +02:00
graphics . Print ( 59 , FLIP ( 132 , 8 ) , game . savetime , 255 - help . glow / 2 , 255 - help . glow / 2 , 255 - help . glow / 2 ) ;
const std : : string & trinketcount = help . number_words ( game . savetrinkets ) ;
graphics . Print ( 262 - graphics . len ( trinketcount ) , FLIP ( 132 , 8 ) , trinketcount , 255 - help . glow / 2 , 255 - help . glow / 2 , 255 - help . glow / 2 ) ;
graphics . drawsprite ( 34 , FLIP ( 126 , 17 ) , 50 , graphics . col_clock ) ;
graphics . drawsprite ( 270 , FLIP ( 126 , 17 ) , 22 , graphics . col_trinket ) ;
2020-01-01 21:29:24 +01:00
break ;
2021-10-02 06:06:31 +02:00
}
2020-01-01 21:29:24 +01:00
case 10 :
2020-04-01 23:59:19 +02:00
graphics . Print ( 128 , 220 , " [ QUIT ] " , 196 , 196 , 255 - help . glow ) ;
2020-01-01 21:29:24 +01:00
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode )
2020-01-01 21:29:24 +01:00
{
2020-06-22 23:40:12 +02:00
if ( game . inspecial ( ) )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 135 , " Return to main menu? " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 142 , " Do you want to quit? You will " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 0 , 130 , " lose any unsaved progress. " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-01 23:59:19 +02:00
graphics . Print ( 80 - 16 , 88 , " [ NO, KEEP PLAYING ] " , 196 , 196 , 255 - help . glow ) ;
graphics . Print ( 80 + 32 , 76 , " yes, quit to menu " , 96 , 96 , 96 ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-06-22 23:40:12 +02:00
if ( game . inspecial ( ) )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 80 , " Return to main menu? " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 76 , " Do you want to quit? You will " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 0 , 88 , " lose any unsaved progress. " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-01 23:59:19 +02:00
graphics . Print ( 80 - 16 , 130 , " [ NO, KEEP PLAYING ] " , 196 , 196 , 255 - help . glow ) ;
graphics . Print ( 80 + 32 , 142 , " yes, quit to menu " , 96 , 96 , 96 ) ;
2020-01-01 21:29:24 +01:00
}
break ;
case 11 :
2020-04-01 23:59:19 +02:00
graphics . Print ( 128 , 220 , " [ QUIT ] " , 196 , 196 , 255 - help . glow ) ;
2020-01-01 21:29:24 +01:00
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode )
2020-01-01 21:29:24 +01:00
{
2020-06-22 23:40:12 +02:00
if ( game . inspecial ( ) )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 135 , " Return to main menu? " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 142 , " Do you want to quit? You will " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 0 , 130 , " lose any unsaved progress. " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-01 23:59:19 +02:00
graphics . Print ( 80 , 88 , " no, keep playing " , 96 , 96 , 96 ) ;
graphics . Print ( 80 + 32 - 16 , 76 , " [ YES, QUIT TO MENU ] " , 196 , 196 , 255 - help . glow ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-06-22 23:40:12 +02:00
if ( game . inspecial ( ) )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 80 , " Return to main menu? " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 76 , " Do you want to quit? You will " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 0 , 88 , " lose any unsaved progress. " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-01 23:59:19 +02:00
graphics . Print ( 80 , 130 , " no, keep playing " , 96 , 96 , 96 ) ;
graphics . Print ( 80 + 32 - 16 , 142 , " [ YES, QUIT TO MENU ] " , 196 , 196 , 255 - help . glow ) ;
2020-01-01 21:29:24 +01:00
}
break ;
case 20 :
2020-04-01 23:59:19 +02:00
graphics . Print ( 128 , 220 , " [ GRAVITRON ] " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 76 , " the secret laboratory? " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 0 , 88 , " Do you want to return to " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 80 - 16 , 142 , " [ NO, KEEP PLAYING ] " , 196 , 196 , 255 - help . glow ) ;
graphics . Print ( 80 + 32 , 130 , " yes, return " , 96 , 96 , 96 ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 76 , " Do you want to return to " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 0 , 88 , " the secret laboratory? " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 80 - 16 , 130 , " [ NO, KEEP PLAYING ] " , 196 , 196 , 255 - help . glow ) ;
graphics . Print ( 80 + 32 , 142 , " yes, return " , 96 , 96 , 96 ) ;
2020-01-01 21:29:24 +01:00
}
break ;
case 21 :
2020-04-01 23:59:19 +02:00
graphics . Print ( 128 , 220 , " [ GRAVITRON ] " , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 76 , " the secret laboratory? " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 0 , 88 , " Do you want to return to " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 80 , 142 , " no, keep playing " , 96 , 96 , 96 ) ;
graphics . Print ( 80 + 32 - 16 , 130 , " [ YES, RETURN ] " , 196 , 196 , 255 - help . glow ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 0 , 76 , " Do you want to return to " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 0 , 88 , " the secret laboratory? " , 196 , 196 , 255 - help . glow , true ) ;
graphics . Print ( 80 , 130 , " no, keep playing " , 96 , 96 , 96 ) ;
graphics . Print ( 80 + 32 - 16 , 142 , " [ YES, RETURN ] " , 196 , 196 , 255 - help . glow ) ;
2020-01-01 21:29:24 +01:00
}
}
2020-06-25 23:41:44 +02:00
// We need to draw the black screen above the menu in order to disguise it
// being jankily brought down in glitchrunner mode when exiting to the title
// Otherwise, there's no reason to obscure the menu
2021-08-06 00:05:14 +02:00
if ( GlitchrunnerMode_less_than_or_equal ( Glitchrunner2_2 )
| | graphics . fademode = = 3
| | graphics . fademode = = 5
| | game . fadetomenu
| | game . fadetolab )
2020-05-08 00:53:12 +02:00
{
graphics . drawfade ( ) ;
}
2020-01-01 21:29:24 +01:00
2020-05-02 01:49:10 +02:00
if ( graphics . resumegamemode | | graphics . menuoffset > 0 | | graphics . oldmenuoffset > 0 )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . menuoffrender ( ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-30 01:02:17 +02:00
graphics . renderwithscreeneffects ( ) ;
2020-01-01 21:29:24 +01:00
}
}
2021-10-02 06:06:31 +02:00
# undef FLIP
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 teleporterrender ( void )
2020-01-01 21:29:24 +01:00
{
2021-02-26 00:37:03 +01:00
ClearSurface ( graphics . backBuffer ) ;
2020-01-01 21:29:24 +01:00
int tempx ;
int tempy ;
//draw screen alliteration
//Roomname:
2020-04-03 03:50:37 +02:00
int temp = map . area ( game . roomx , game . roomy ) ;
2020-04-01 23:59:19 +02:00
if ( temp < 2 & & ! map . custommode & & graphics . fademode = = 0 )
2020-01-01 21:29:24 +01:00
{
Refactor how "hidden names" work
By "hidden names", I'm referring to "Dimension VVVVVV" and "The Ship"
popping up on the quit/pause/teleporter screens, even though those rooms
don't have any roomnames.
Apparently my commit to fix roomname re-draw bleed on the
quit/pause/teleporter screens exposed yet another hardreset()-caused
bug. The issue here is that since hardreset() sets game.roomx and
game.roomy to 0, map.area() will no longer work properly, and since the
hidden roomname check is based on map.area(), it will no longer display
"Dimension VVVVVV" or "The Ship" once you press ACTION to quit. It used
to do this due to the re-draw bleed, but now it doesn't.
I saw that roomnames didn't get reset in hardreset(), so the solution
here is to re-factor hidden names to be an actual variable, instead of
being implicit. map.hiddenname is a variable that's set in
mapclass::loadlevel(), and if isn't empty, it will be drawn on the
quit/pause/teleporter screens. That way it will still display "Dimension
VVVVVV" and "The Ship" when you press ACTION to quit to the menu.
EDIT: Since PR #230 got merged, this commit is no longer strictly
necessary, but it's still good to refactor hidden names like this.
2020-05-02 23:10:22 +02:00
graphics . Print ( 5 , 2 , map . hiddenname , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . Print ( 5 , 2 , map . roomname , 196 , 196 , 255 - help . glow , true ) ;
2020-01-01 21:29:24 +01:00
}
//Background color
2020-04-01 23:59:19 +02:00
FillRect ( graphics . backBuffer , 0 , 12 , 320 , 240 , 10 , 24 , 26 ) ;
2020-01-01 21:29:24 +01:00
//draw the map image
2021-09-04 00:26:57 +02:00
graphics . drawpixeltextbox ( 35 , 16 , 250 , 190 , 65 , 185 , 207 ) ;
2020-04-01 23:59:19 +02:00
graphics . drawimage ( 1 , 40 , 21 , false ) ;
2020-01-01 21:29:24 +01:00
//black out areas we can't see yet
for ( int j = 0 ; j < 20 ; j + + )
{
for ( int i = 0 ; i < 20 ; i + + )
{
2021-03-24 20:12:39 +01:00
if ( ! map . isexplored ( i , j ) )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . drawimage ( 2 , 40 + ( i * 12 ) , 21 + ( j * 9 ) , false ) ;
2020-01-01 21:29:24 +01:00
}
}
}
//draw the coordinates //current
if ( game . roomx = = 109 )
{
//tower!instead of room y, scale map.ypos
2020-04-01 23:59:19 +02:00
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 12 ) + 2 , 21 + 2 , 12 - 4 , 180 - 4 , 16 , 245 - ( help . glow * 2 ) , 245 - ( help . glow * 2 ) ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
graphics . drawrect ( 40 + ( ( game . roomx - 100 ) * 12 ) + 2 , 21 + ( ( game . roomy - 100 ) * 9 ) + 2 , 12 - 4 , 9 - 4 , 16 , 245 - ( help . glow * 2 ) , 245 - ( help . glow * 2 ) ) ;
2020-01-01 21:29:24 +01:00
}
if ( game . useteleporter )
{
//Draw the chosen destination coordinate!
2020-04-02 23:19:15 +02:00
//TODO
2020-01-01 21:29:24 +01:00
//draw the coordinates //destination
Fix variables shadowing other variables
In C++, when you have two variables in different scopes with the same
name, the inner scope wins. Except you have to be really careful because
sometimes they're not (#507). So it's better to just always have unique
variable names and make sure to never clash a name with a variable in an
outer scope - after all, the C++ compiler and standard might be fine
with it, but that doesn't mean humans can't make mistakes reading or
writing it.
Usually I just renamed the inner variables, but for tx/ty in editor.cpp,
I just got rid of the ridiculous overcomplicated modulo calculations and
replaced them with actual simple modulo calculations, because the
existing ones were just ridiculous. Actually, somebody ought to find
every instance of the overcomplicated modulos and replace them with the
actual good ones, because it's really stupid, quite frankly...
2020-11-04 09:37:46 +01:00
int tempx_ = map . teleporters [ game . teleport_to_teleporter ] . x ;
int tempy_ = map . teleporters [ game . teleport_to_teleporter ] . y ;
graphics . drawrect ( 40 + ( tempx_ * 12 ) + 1 , 21 + ( tempy_ * 9 ) + 1 , 12 - 2 , 9 - 2 , 245 - ( help . glow * 2 ) , 16 , 16 ) ;
graphics . drawrect ( 40 + ( tempx_ * 12 ) + 3 , 21 + ( tempy_ * 9 ) + 3 , 12 - 6 , 9 - 6 , 245 - ( help . glow * 2 ) , 16 , 16 ) ;
2020-01-01 21:29:24 +01:00
}
//draw legend details
2020-04-15 04:32:30 +02:00
for ( size_t i = 0 ; i < map . teleporters . size ( ) ; i + + )
2020-01-01 21:29:24 +01:00
{
2021-03-24 20:12:39 +01:00
if ( map . showteleporters & & map . isexplored ( map . teleporters [ i ] . x , map . teleporters [ i ] . y ) )
2020-01-01 21:29:24 +01:00
{
2021-03-24 20:12:39 +01:00
temp = 1126 + ( int ) map . isexplored ( map . teleporters [ i ] . x , map . teleporters [ i ] . y ) ;
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode ) temp + = 3 ;
graphics . drawtile ( 40 + 3 + ( map . teleporters [ i ] . x * 12 ) , 22 + ( map . teleporters [ i ] . y * 9 ) , temp ) ;
2020-01-01 21:29:24 +01:00
}
2021-03-26 04:37:42 +01:00
else if ( map . showtargets & & ! map . isexplored ( map . teleporters [ i ] . x , map . teleporters [ i ] . y ) )
2020-01-01 21:29:24 +01:00
{
2021-03-24 20:12:39 +01:00
temp = 1126 + ( int ) map . isexplored ( map . teleporters [ i ] . x , map . teleporters [ i ] . y ) ;
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode ) temp + = 3 ;
graphics . drawtile ( 40 + 3 + ( map . teleporters [ i ] . x * 12 ) , 22 + ( map . teleporters [ i ] . y * 9 ) , temp ) ;
2020-01-01 21:29:24 +01:00
}
}
if ( map . showtrinkets )
{
2020-04-15 04:39:08 +02:00
for ( size_t i = 0 ; i < map . shinytrinkets . size ( ) ; i + + )
2020-01-01 21:29:24 +01:00
{
2020-04-09 08:56:36 +02:00
if ( ! obj . collect [ i ] )
2020-01-01 21:29:24 +01:00
{
temp = 1086 ;
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode ) temp + = 3 ;
2021-09-07 03:56:39 +02:00
graphics . drawtile ( 40 + 3 + ( map . shinytrinkets [ i ] . x * 12 ) , 22 + ( map . shinytrinkets [ i ] . y * 9 ) , temp ) ;
2020-01-01 21:29:24 +01:00
}
}
}
2020-04-02 23:19:15 +02:00
tempx = map . teleporters [ game . teleport_to_teleporter ] . x ;
tempy = map . teleporters [ game . teleport_to_teleporter ] . y ;
2020-01-01 21:29:24 +01:00
if ( game . useteleporter & & ( ( help . slowsine % 16 ) > 8 ) )
{
//colour in the legend
temp = 1128 ;
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode ) temp + = 3 ;
graphics . drawtile ( 40 + 3 + ( tempx * 12 ) , 22 + ( tempy * 9 ) , temp ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-01 23:59:19 +02:00
graphics . cutscenebars ( ) ;
2020-01-01 21:29:24 +01:00
if ( game . useteleporter )
{
2021-09-13 06:39:07 +02:00
char buffer [ SCREEN_WIDTH_CHARS + 1 ] ;
2021-04-19 08:23:44 +02:00
static const char raw [ ] = " Press %s to Teleport " ;
const char * final_string = interact_prompt (
buffer ,
sizeof ( buffer ) ,
raw
) ;
2020-01-01 21:29:24 +01:00
//Instructions!
2020-04-01 23:59:19 +02:00
graphics . Print ( 5 , 210 , " Press Left/Right to choose a Teleporter " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2021-04-19 08:23:44 +02:00
graphics . Print ( 5 , 225 , final_string , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-04-01 23:59:19 +02:00
graphics . drawgui ( ) ;
2020-01-01 21:29:24 +01:00
2020-04-01 23:59:19 +02:00
if ( graphics . flipmode )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
if ( game . advancetext ) graphics . bprint ( 5 , 228 , " - Press ACTION to advance text - " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-01 23:59:19 +02:00
if ( game . advancetext ) graphics . bprint ( 5 , 5 , " - Press ACTION to advance text - " , 220 - ( help . glow ) , 220 - ( help . glow ) , 255 - ( help . glow / 2 ) , true ) ;
2020-01-01 21:29:24 +01:00
}
2020-05-02 01:49:10 +02:00
if ( graphics . resumegamemode | | graphics . menuoffset > 0 | | graphics . oldmenuoffset > 0 )
2020-01-01 21:29:24 +01:00
{
2020-04-01 23:59:19 +02:00
graphics . menuoffrender ( ) ;
2020-01-01 21:29:24 +01:00
}
else
{
2020-04-27 04:29:40 +02:00
graphics . render ( ) ;
2020-01-01 21:29:24 +01:00
}
}