Commit Graph

1310 Commits

Author SHA1 Message Date
leo60228 46d8599f62 Use SDL_GetRendererOutputSize instead of SDL_GetWindowSize
SDL_GetRendererOutputSize will always return the actual size, even in
some obscure HiDPI/macOS cases.
2021-01-18 13:10:06 -05:00
leo60228 d9fff2a8c3 Set SDL window as DPI-aware
This works on macOS, Wayland, and a few more esoteric platforms. X11
doesn't have a concept of DPI-awareness. Note that with this flag
SDL_GetWindowSize() isn't guaranteed to return the actual window size.
2021-01-18 13:09:47 -05:00
Misa a32fc4a307 Improve support for retextured checkpoints and terminals in the editor
Retextured checkpoints have always been in the game, but clicking on
them in the editor would lead to them losing their retextured-ness. So,
checkpoints should be left alone if their p1 isn't either 0 or 1. Also,
they don't show up properly in the editor, so that's fixed, too.

Retextured and flipped terminals were added in 2.3, and show up properly
in-game, but don't properly show up in the editor, either. So now they
show up in the editor. Additionally, clicking on them will flip the
terminal as well, but only if its p1 is 0 or 1, just like checkpoints
now do.
2021-01-18 13:07:32 -05:00
Misa afba320083 Remove duplicate graphics.Makebfont() in main()
This call to Makebfont() always existed, but ever since 2.3's per-level
custom assets were added, graphics.reloadresources() also calls
graphics.Makebfont(), meaning this call is unnecessary. Calling it twice
results in graphics.bfont and graphics.flipbfont having twice the number
of elements, until custom assets get mounted (or unmounted, technically).
2021-01-18 13:06:59 -05:00
Misa adbab6355b Free data upon failure in LoadImage()
Otherwise, if SDL_CreateRGBSurfaceFrom() returned NULL, then this memory
would be leaked.
2021-01-18 13:06:43 -05:00
Misa 626aac59fb Fix No Death Mode results being reset before being shown
This does the same thing as the last commit, but for No Death Mode
instead of Time Trials. Whenever you die in No Death Mode, or complete
it, all the relevant variables get copied to variables prefixed with
'ndmresult' that never get reset by script.hardreset(), and these
variables are what titlerender() use, instead of the "live" ones.
2021-01-18 13:06:15 -05:00
Misa 4d7baa9e9e Fix Time Trial results being reset before being shown
This makes it so when a Time Trial gets completed, all the relevant
variables get copied onto variables prefixed with 'timetrialresult',
which never get reset by script.hardreset(). Then titlerender() will use
those variables accordingly.
2021-01-18 13:06:15 -05:00
Misa ee0ba8a723 Clean up all exit paths to the menu to use common code
There are multiple different exit paths to the main menu. In 2.2, they
all had a bunch of copy-pasted code. In 2.3 currently, most of them use
game.quittomenu(), but there are some stragglers that still use
hand-copied code.

This is a bit of a problem, because all exit paths should consistently
have FILESYSTEM_unmountassets(), as part of the 2.3 feature of per-level
custom assets. Furthermore, most (but not all) of the paths call
script.hardreset() too, and some of the stragglers don't. So there could
be something persisting through to the title screen (like a really long
flash/shake timer) that could only persist if exiting to the title
screen through those paths.

But, actually, it seems like there's a good reason for some of those to
not call script.hardreset() - namely, dying or completing No Death Mode
and completing a Time Trial presents some information onscreen that
would get reset by script.hardreset(), so I'll fix that in a later
commit.

So what I've done for this commit is found every exit path that didn't
already use game.quittomenu(), and made them use game.quittomenu(). As
well, some of them had special handling that existed on top of them
already having a corresponding entry in game.quittomenu() (but the path
would take the special handling because it never did game.quittomenu()),
so I removed that special handling as well (e.g. exiting from a custom
level used returntomenu(Menu::levellist) when quittomenu() already had
that same returntomenu()).

The menu that exiting from the level editor returns to is now handled in
game.quittomenu() as well, where the map.custommode branch now also
checks for map.custommodeforreal. Unfortunately, it seems like entering
the level editor doesn't properly initialize map.custommode, so entering
the level editor now initializes map.custommode, too.

I've also taken the music.play(6) out of game.quittomenu(), because not
all exit paths immediately play Presenting VVVVVV, so all exit paths
that DO immediately play Presenting VVVVVV now have music.play(6)
special-cased for them, which is fine enough for me.

Here is the list of all exit paths to the menu:
- Exiting through the pause menu (without glitchrunner mode)
- Exiting through the pause menu (with glitchrunner mode)
- Completing a custom level
- Completing a Time Trial
- Dying in No Death Mode
- Completing No Death Mode
- Completing an Intermission replay
- Exiting from the level editor
- Completing the main game
2021-01-18 13:06:15 -05:00
Misa 07cc5f68ac Remove commented-out code from gamestates 3101 and 3500
Comments in general don't get verified by the compiler, but
commented-out code is even worse. Especially since this looks to be
outdated code.

As always, if we need some of this code, then we can just look back in
the Git history.
2021-01-18 13:06:15 -05:00
Misa f06701ff90 Fix wrong function being used for musicclass::play() check
Whoops.
2021-01-16 15:37:22 -05:00
Misa 74740c5a21 Remove LODEPNG_NO_COMPILE_ZLIB
This fixes a segfault, because we would then pass compressed image data
to SDL_ConvertSurfaceFormat() in LoadImage(). I didn't test my previous
PR. Whoops.
2021-01-14 06:31:30 -05:00
Misa 9c9433d21a Disable MSVC warnings about implicit conversion
Implicit conversion warnings happen all over the codebase, but there's
no reason to warn on all of them, and adding casts everywhere is
annoying to read and patently unnecessary.

MSVC is the only compiler that has this warning (GCC even on -Wall
-Wextra doesn't warn about implicit conversions), so disable it for
MSVC.
2021-01-14 06:30:22 -05:00
Misa fad3bab2d0 Initialize bcol and bcol2 in Graphics::drawbackground()
While compiling in release mode, GCC warns about these two potentially
being used uninitialized further down. The only way this could happen is
if the case-switches below didn't match up with a case, which would
require the game to be in an invalid state (and have invalid values for
rcol and spcol), but it's better to be safe than sorry.
2021-01-13 22:47:12 -05:00
Misa 2a781083e9 Disable unneeded LodePNG features
The only thing we need LodePNG for is to decode a PNG that we've already
loaded into memory. We handle the filesystem part ourselves, so we don't
need LodePNG's filesystem functions; we don't encode images, and we
don't use the zlib functions. So disable all of those.
2021-01-13 22:44:52 -05:00
Misa 769f99f590 Reduce dependency on libc functions
During 2.3 development, there's been a gradual shift to using SDL stdlib
functions instead of libc functions, but there are still some libc
functions (or the same libc function but from the STL) in the code.

Well, this patch replaces all the rest of them in one fell swoop.

SDL's stdlib can replace most of these, but its SDL_min() and SDL_max()
are inadequate - they aren't really functions, they're more like macros
with a nasty penchant for double-evaluation. So I just made my own
VVV_min() and VVV_max() functions and placed them in Maths.h instead,
then replaced all the previous usages of min(), max(), std::min(),
std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max().

Additionally, there's no SDL_isxdigit(), so I just implemented my own
VVV_isxdigit().

SDL has SDL_malloc() and SDL_free(), but they have some refcounting
built in to them, so in order to use them with LodePNG, I have to
replace the malloc() and free() that LodePNG uses. Which isn't too hard,
I did it in a new file called ThirdPartyDeps.c, and LodePNG is now
compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition.

Lastly, I also refactored the awful strcpy() and strcat() usages in
PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save
migration is getting axed in 2.4, but it still bothers me to have
something like that in the codebase otherwise.

Without further ado, here is the full list of functions that the
codebase now uses:

- SDL_strlcpy() instead of strcpy()
- SDL_strlcat() instead of strcat()
- SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above)
- VVV_min() instead of min(), std::min(), or SDL_min()
- VVV_max() instead of max(), std::max(), or SDL_max()
- VVV_isxdigit() instead of isxdigit()
- SDL_strcmp() instead of strcmp()
- SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi()
- SDL_strstr() instead of strstr()
- SDL_strlen() instead of strlen()
- SDL_sscanf() instead of sscanf()
- SDL_getenv() instead of getenv()
- SDL_malloc() instead of malloc() (replacing in LodePNG as well)
- SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 14:02:31 -05:00
Misa b944d2d847 Fix editor tool menu inconsistencies
This patch de-duplicates the tool drawing code a bit in the menu that
gets brought up when you press Space in the level editor, as well as
fixes several bugs related to the fact that the original author(s) of
the code decided to copy-paste everything. (It was most likely Terry,
judging by the distinct lack of whitespace between tokens in the code.)

There are two "pages" of tools that get shown when you open the tool
menu, according to your currently-selected tool.

1. On the first page, your currently-selected tool gets a brighter
   outline. However, on the second page, the code to draw the outline over
   your currently-selected tool is missing. So I've fixed that.

2. On the first page, the glyph indicator next to the tool icon also
   gets brighter when you have that tool selected. However, on the
   second page, the code that drew the brighter-colored indicator got
   ran before the code that drew the normal-colored indicator, so this
   was never shown. This is also fixed.

3. The glyph indicator of the gravity line tool didn't get brighter when
   you had it selected, due to its special-cased copy-pasted code
   drawing its brighter color before drawing its normal color. This has
   also been fixed.

4. Lastly, the tool menu no longer draws the brighter-colored glyphs on
   top of the normal-colored glyphs. Instead, the menu will simply draw
   the brighter-colored glyphs and will not draw the normal-colored
   glyphs in the first place. This is because double-drawing text like
   this will look bad if the user has a custom font.png that has
   translucent pixels, like I do.

All of these bugs have been fixed by paying off the technical debt of
copy-pasting code.
2021-01-12 13:42:16 -05:00
leo60228 89886e6c52
Run CI on CentOS 7 (#574) 2021-01-11 00:30:15 -05:00
Misa b1558f574c Remove game.savemystats
This variable seems to have been intended to make sure
game.savestatsandsettings() was called at the end of the frame, or make
sure that it didn't get called more than once per frame. I don't see any
frame ordering-related reason why it needs to be called specifically at
the end of the frame (the function doesn't modify any state), so it's
more plausible that it was added to make sure it didn't get called more
than one per frame.

However, upon further analysis, none of the code paths where
game.savemystats is used ever calls or sets game.savemystats more than
once, and a majority of the code directly calls
game.savestatsandsettings() anyway, so there's no reason for this
variable to exist. If we ever need to make sure it doesn't get called
more than once, and there's no way to change the code paths around to
prevent it otherwise, we can use the defer callbacks system that I added
to #535, when it gets merged.
2021-01-11 00:26:14 -05:00
Misa 17d06f06be Remove map.finalx/y and map.customx/y
These variables basically serve no purpose. map.customx and map.customy
are clearly never used. map.finalx and map.finaly, on the other hand,
are basically always game.roomx and game.roomy respectively if
map.finalmode is on, and if it's off, then they don't matter.

Also, there are some weird and redundant variable assignments going on
with these; most notably in map.gotoroom(), where rx/ry (local
variables) get assigned to finalx/finaly, then finalx/finaly get
assigned to game.roomx/game.roomy, then finalx/finaly get assigned to
rx/ry. If finalx/finaly made a difference, then there'd be no need to
assign finalx/finaly back to rx/ry. So it makes the code clearer to
remove these weird bits of code.
2021-01-11 00:24:59 -05:00
Misa b571fa0919 Add F9 "reload resources" hotkey to list of hotkeys in Shift menu
2.3's per-level assets feature also added a hotkey to reload the custom
assets of the level you're currently editing in the editor, so you
wouldn't have to re-load the level yourself. This hotkey is F9, but
however, it hasn't been documented in the hotkey list brought up by
pressing Shift, until now.
2021-01-11 00:21:50 -05:00
Misa e9c62ea9a3 Clean up unnecessary exports and add static keywords
This patch cleans up unnecessary exports from header files (there were
only a few), as well as adds the static keyword to all symbols that
aren't exported and are specific to a file. This helps the linker out in
not doing any unnecessary work, speeding it up and avoiding silent
symbol conflicts (otherwise two symbols with the same name (and
type/signature in C++) would quietly resolve as okay by the linker).
2021-01-10 12:23:59 -05:00
Misa fdee4007f7 Move gamerenderfixed() in between gameinput() and gamelogic()
Line clipping and second-frame edge-flipping have been broken since #539
was merged (d910c5118d). The cause of this
is moving the onground/onroof code around.

A proper loop order fix is going to come once #535 gets finalized and
merged, so this is a stopgap measure just to make sure people don't
report that line clipping or second-frame edge-flipping are broken in
current builds of 2.3.
2021-01-09 20:16:19 -05:00
Misa 979c5e3aa4 Fix attempts to place enemy/plat bounds & scripts with bad corner order
There is a certain ordering of which corners you click on to place enemy
and platform boundaries, and script boxes. You must first click on the
top-left corner, then click on the bottom-right corner. The visual box
that is drawn after you've first clicked on the top-left corner clearly
shows this intended way of doing things.

However, it seems like despite the visuals, the game didn't properly
prevent you from clicking on the corners in the wrong way. If you placed
it from top-right to bottom-left, or bottom-left to top-right, then the
game would place the boxes accordingly, and they would have a weird
shape where two of its opposite sides would just be missing. But,
placing them from bottom-right to top-left is prevented accordingly.

The bug comes down to a simple use of "or", instead of the correct
"and". This isn't the first time the wrong conjunction was used in a
conditional... (8260bb2696, #136)

Since the code block that the if-statement guards is the code that will
execute if the corners placed were correct, the if-statement thus should
be written in the positive case and use a more restrictive "and",
instead of the negative case, which would use a more looser "or". There
are less cases that are correct than cases which are incorrect - in this
case, there is only 1 correct way of doing things (top-left to
bottom-right), compared to 3 incorrect ways of doing things (top-right
to bottom-left, bottom-left to top-right, bottom-right to top-left) - so
when thinking of positive cases, you should be using "and".

Or, you can always just test it. This bug has been in the game since
2.0, so it seems like no one just tested that incorrect input actually
didn't work.
2021-01-09 11:00:53 -05:00
Terry Cavanagh 261e898267
Merge pull request #547 from InfoTeddy/general-bug-fixes
Fix Secret Lab Time Trial trophies having wrong colors
2021-01-09 19:02:25 +10:30
Misa d271907f8c Fix Secret Lab Time Trial trophies having wrong colors
Ever since 2.0, the colors of some of the Time Trial trophies in the
Secret Lab don't correspond to the crewmate of the given level. The
trophy for the Tower uses Victoria's color, and the Lab trophy uses
Vermilion's color. The Space Station 2 trophy uses Viridian's color, and
the Final Level trophy uses Vitellary's color.

This doesn't appear to be intentional, and it would be odd if it was,
since this game matches the colors everywhere else (each zone on the map
is colored with their respective crewmate in mind, for instance). Also,
the Lab trophy has the sad expression, which is Victoria's trait - it
would be weird if this was intended for Vermilion instead.

But the biggest piece of evidence that this was unintentional is the
corresponding comment for each color in Graphics::setcol(). It mislabels
yellow as cyan, cyan as yellow, blue as red, and red as blue.

To fix this, I simply have to set the correct color for each trophy in
case 25 of entityclass::createentity(). I could fix it in
Graphics::setcol() itself, but custom levels might depend on those
certain colors being the way they are, so it's a safer bet to just fix
it in the trophy creation case itself.

The diff of this might look weird. Even though all I'm doing is changing
some value assignments around, it looks like the "patience" algorithm
thinks I'm moving a whole case of the trophy switch-case around.
2021-01-08 15:17:36 -08:00
Misa 952a130595 Fix Shift+F1 from Space Station tileset not switching to Ship
So... it looks like being able to switch through tilesets backwards has
been in 2.3 for a while, guess no one just uses 2.3 or the level editor
that much. It seems like it's always been broken, too.

If you were on the Space Station tileset (tileset 0), pressing Shift+F1
would keep you on the Space Station tileset instead of switching to the
Ship (tileset 4).

It looks like the problem here was mixing size_t and int together - so
the modulus operation promoted the left-hand side to size_t, which is
unsigned, so the -1 turned into SIZE_MAX, which is 18446744073709551615
on my system. You'll note that that ends in a 5, so the number is
divisible by 5, meaning taking it modulo 5 leads to 0. So the tileset
would be kept at 0.

At least unsigned integer underflow/overflow is properly defined, so
there's no UB here. Just careless type mixing going on.

The solution is to make the modulus an int instead of a size_t. This
introduces an implicit conversion, but I don't care because my compiler
doesn't warn about it, and implicit conversion warnings ought to be
disabled on MSVC anyway.
2021-01-08 18:13:45 -05:00
Misa 3dd1dcc131 Move mapclass r/g/b variables off onto TowerBG
This fixes a bug where if you entered a tower before watching the
credits sequence, the credits sequence would have mismatched text and
background colors.

This bug happened because entering a tower modified the r/g/b attributes
of mapclass, and updated graphics.towerbg, without updating
graphics.titlebg too. Then gamecompleterender() uses the r/g/b
attributes of mapclass.

The solution is to put the r/g/b attributes on TowerBG instead. That
way, entering a tower will only modify the r/g/b attributes used to
render towers, and won't affect the r/g/b attributes used to render the
credits sequence.

Additionally, I also de-duplicated the case-switch that updated the
r/g/b attributes based off of the current colstate, because it got
copy-pasted twice, leading to three instances of one piece of code.
2021-01-07 21:15:34 -05:00
Misa 6b18e3875d Move title screen color initialization to main()
This fixes a bug where if you completed a custom level during
command-line playtesting, when returning to the title screen, the
background would be red and the text would be white.

This is because playtesting skips over the code path of pressing ACTION
to start the game and advance to the title screen, and the code path of
that ACTION press specifically initializes the title screen colors to
cyan.

This is also caused by the fact that completing a custom level doesn't
call map.nexttowercolour(), but my guess is that the intent there was
that the player would select a custom level, complete it, and return to
the title screen on the same screen with the same colors, so I decided
not to add a map.nexttowercolour() there.

Instead, I've moved the cyan color initialization to main(), so that it
is always executed no matter what, and doesn't require you to take a
specific code path to do it.
2021-01-05 21:20:58 -05:00
Misa 5e557ffd1a Fix regression with playing the same track after it fades out
With commit 48313169b6 (PR #453),
AllyTally added a single-case patch for a regression, instead of fixing
it at its root cause.

In fact, that commit only fixes the music if Presenting VVVVVV is
playing while exiting to the menu, not if you enter a level that plays
Presenting VVVVVV - so it only fixes it going one way, and not going the
other way around; neither fixing also all the other cases this could
happen.

It doesn't, say, fix the case where you are exited to the menu
automatically after collecting the last crewmate in the level (or if the
level calls gamestate 1013 itself), which is what happens in my MIRA-VIU
TAS video at the end, and which I noted in the description of that video
( https://www.youtube.com/watch?v=OYQO4ePbYW4&t=111 ).

So, the problem here is that when musicclass::play() is called, it sees
that currentsong is the same as its input, and decides that since the
music is already playing, it shouldn't play the music again. Thus, the
music fades out, and we get silence instead of the music playing again.

But I said this was a regression. Why didn't this happen in 2.2? Well,
it's because of the fact that 2.2 sets currentsong to -1 (no music
playing at all) immediately when starting a fadeout, and not when the
fadeout completes (commit facb079b35,
PR #316). As you can imagine, this discrepancy could lead to bugs, given
that the game would think that music wasn't playing when in actuality it
was, but fixing this bug could also break code that expected this wrong
behavior. And in this case, it has.

So to properly fix the root cause of this, instead of naïvely
single-case patching out every case that comes up randomly, in
musicclass::play(), the function will now ignore if the input given is
the same as currentsong if the music is currently fading out.
2021-01-04 19:16:35 -05:00
Misa d5763640a8 Revert hardcoded check for track 6 when quitting to menu
This reverts commit 48313169b6, "Don't
fade music out when returning to the menu if it's Presenting VVVVVV".

This commit is being reverted because it is only a single-case patch -
that is, it fixes only a single symptom of the bug, and not its
underlying cause.
2021-01-04 19:16:35 -05:00
Misa 8e5714439a Unindent musicclass::play() from previous two commits
As always, the actual unindenting happens in a separate commit in order
to minimize diff noise.
2021-01-04 05:09:23 -05:00
Misa f64cf4f831 Invert t comparison with -1 and un-nest rest of function
This is also another conditional where the rest of the function is
nested. Furthermore, in order to not repeat ourselves, I've also decided
to unconditionally assign currentsong to t, because if t is -1
currentsong gets assigned to -1 anyway - so it's the same thing, but
it's much easier to see and think about.
2021-01-04 05:09:23 -05:00
Misa fe5bacfdc2 Invert currentsong check and un-nest rest of function
This removes an indentation level, and makes it easier to reason about
the function since you essentially now view it as the function returning
right there.
2021-01-04 05:09:23 -05:00
Misa 96c479a11f Fix whitespace inconsistency in musicclass::play()
Spaces are used around operators and keywords accordingly, and blank
lines are used to visually separate lines of code from each other.
2021-01-04 05:09:23 -05:00
Misa ff3e390352 Remove unused function editorclass::warpzonematch()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
Misa a5e5c19913 Remove unused function editorclass::warpzoneedgetile()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
Misa 54ff36da97 Remove unused function Graphics::textboxmove()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
Misa ca904a4d7c Remove unused function Graphics::textboxcenter()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
Misa b3305e4820 Remove unused function SoundSystem::playMusic()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
Misa 945961c1fb Remove unused function editorclass::placetile()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
Misa 916a19c09c Remove unused function KeyPoll::isUp()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
Misa ad34e95128 Remove unused function entityclass::fixfriction()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
Misa a656f4c4d8 Remove unused function edentclear()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
Misa 9b3bf69491 Remove unused function Graphics::drawentcolours()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
Misa 6261fa51e9 Remove unused function Graphics::RPrint()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
Misa 42106cb59a Remove unused function Graphics::PrintOff()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
Misa 0e0f5c47a5 Remove unused function FlipSurfaceHorizontal()
This function was marked as unused by cppcheck.
2021-01-02 09:06:42 -05:00
leo60228 6795856431 Use SDL_fabsf where std::abs was previously used 2021-01-01 22:37:46 -05:00
leo60228 91c3e6cbc5 Revert "Document SDL_abs vs. SDL_fabs"
This reverts commit 8c472ed73d.
2021-01-01 22:37:46 -05:00
leo60228 8c472ed73d Document SDL_abs vs. SDL_fabs 2021-01-01 21:10:16 -05:00