1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-29 13:09:44 +01:00
Commit graph

2717 commits

Author SHA1 Message Date
Misa
1f5835c985 Fix fade volume durations being incorrect
The previous fade system used only one variable, the amount of volume to
fade per frame. However, this variable was an integer, meaning any
decimal portion would be truncated, and would lead to a longer fade
duration than intended.

The fade per volume is calculated by doing MIX_MAX_VOLUME / (fade_ms /
game.get_timestep()). MIX_MAX_VOLUME is 128, and game.get_timestep() is
usually 34, so a 3000 millisecond fade would be calculated as 128 /
(3000 / 34). 3000 / 34 is 88.235..., but that gets truncated to 88, and
then 128 / 88 becomes 1.454545..., which then gets truncated to 1. This
essentially means 1 is added to or subtracted from the volume every
frame, and given that the max volume is 128, this means that the fade
lasts for 128 frames. Now, instead of the fade duration lasting 3
seconds, the fade now lasts for 128 frames, which is 128 * 34 / 1000 =
4.352 seconds long.

This could be fixed using floats, but when you introduce floats, you now
have 1.9999998 problems. For instance, I'm concerned about
floating-point determinism issues.

What I've done instead is switch the system to use four different
variables instead: the start volume, the end volume, the total duration,
and the duration completed so far (called the "step"). For every frame,
the game interpolates which value should be used based on the step, the
total duration, and the start and end volumes, and then adds the
timestep to the step. This way, fades will be correctly timed, and we
don't have potential determinism issues.

Doing this also fixes inaccuracies with the game timestep changing
during the fade, since the timestep is only used in the calculation
once at the beginning in the previous system.
2021-04-27 20:33:44 -04:00
Misa
801ac995e2 Fix VVVVVV-Man not warping horizontally
To exclude gravitron squares, the game excluded all entities whose
`size` was 12 or higher. The `size` of the player when they transform
into VVVVVV-Man is 13.

We have already inadvertently fixed VVVVVV-Man not warping vertically in
2.2. This was done with the previous room transition/warping code
refactors; the gravitron square conditionals were simply excluded from
the vertical warp code, because there's no situation where there would
ever be a gravitron square outside the screen vertically.

As with making rescuable crewmates warpable, I have yet to ever see
people use VVVVVV-Man in a custom level. It's not like they would want
to use it anyway; VVVVVV-Man is really, really buggy. And it's probably
better to make it less buggy, starting with this commit.

That being said, VVVVVV-Man's collision when warping horizontally is
really janky, so I still wouldn't use it.
2021-04-27 02:46:33 -04:00
Misa
78c319c34d Fix rescuable crewmates not warping
The game excluded every entity whose `type` was 50 or higher. The `type`
of rescuable crewmates is 55.

Could some levels be broken by this behavior? Unlikely; without warping,
the crewmates would end up falling out of the room and would become
unrescuable. So this is more likely to fix than to break.

But more importantly, *no one knows that rescuable crewmates don't
warp*. If anyone would know, it would be me, because I've been in the
custom levels community for over 7 years - and yet, during that time, I
have not seen anyone run into this corner case. If they did, I would
remember! This implies that people simply have never thought about
putting rescuable crewmates in places where they would warp - or they
have, ran into this issue, and worked around it.

With those two reasons, I'm comfortable fixing this inconsistency.
2021-04-27 02:46:33 -04:00
Misa
0e167a27d1 Unindent room wrap for-loops from previous commit
Unindenting is done in a separate commit due to diff noise.
2021-04-27 02:46:33 -04:00
Misa
29ff47cacb Invert and use continue in room wrap for-loops
This saves one indentation level. I also fixed the comments a bit
(multiline instead of single-line, "gravitron squares" instead of "SWN
enemies", also commented the player exclusion from horizontal wrapping
in vertically-wrapping rooms).
2021-04-27 02:46:33 -04:00
Misa
285fc24513 Clean up style of room wrap for-loops
They no longer mix code and declarations and now use a pre-increment.
2021-04-27 02:46:33 -04:00
Misa
53b3811a4d Move graphic options menu update to toggleFullScreen
This fixes a bug where using the fullscreen toggle keybind (Alt+Enter,
Alt+F, or F11) wouldn't update the color of the "resize to nearest" menu
option. The color doesn't functionally change anything - the option
still won't work, and will still have the message telling you that you
need to be in windowed mode when you move your menu selection to it -
but it's an easy inconsistency to fix; just move the menu recreation in
to Screen::toggleFullScreen() itself.
2021-04-22 19:42:32 -04:00
Misa
960bd4a519 Add NULL checks and asserts to graphic options
The game dereferences graphics.screenbuffer without checking it first...
it's unlikely to happen, but the least we can to do be safe is to add a
check and assert here.
2021-04-22 19:42:32 -04:00
Misa
0fc17ec277 Fix only removing duplicate script names from script name list
If there were two scripts with the same name, removing one of them would
only remove the other script from the script name list, and not also
remove the contents of said script - leading to a desync in state, which
is probably bad.

Fixing this isn't as simple as removing the break statement - I either
also have to decrement the loop variable when removing the script, or
iterate backwards. I chose to iterate backwards here because it
relocates less memory than iterating forwards.
2021-04-20 17:34:49 -04:00
Misa
779a48dbb4 Remove use of <algorithm> from editor.cpp
No need to use it when good ol' loops work just fine.

Iterating backwards is correct here, in case there happen to be more
than one of the item in the vectors, and also to minimize the amount of
memory that needs to be relocated.
2021-04-20 17:34:49 -04:00
Misa
b2c6c08621 Quote CMAKE_CXX_FLAGS
Otherwise this would result in multiple input arguments to the regex
instead of just one. Similar to shell scripting.
2021-04-20 14:22:53 -04:00
Misa
370e53f4d3 Draw minimap.png if it is mounted
This is a simple change - we draw minimap.png, instead of the generated
custom map, if it is a per-level mounted custom asset.

Custom levels have already been able to utilize minimap.png, but it was
limited - they could do gamemode(teleporter) in a script, and that would
show their customized minimap.png, but it's not like the player could
look at it during gameplay.

I would have done this earlier if I had figured out how to check if a
specific asset was mounted or not.
2021-04-19 10:08:38 -04:00
Misa
186f36beea Add error checking to base path setup
Previously, if the game couldn't set the write dir to the base
directory, or couldn't make the base directory, or couldn't calculate
the base directory, it would probably dereference NULL or read from
uninitialized memory or murder your family or something. But now, I've
eliminated the potential Undefined Behavior from the code dealing with
the base path.
2021-04-18 18:14:03 -04:00
Misa
2b4f3ab19e Pass size of output through instead of hardcoding it
Previously, this function had a bug due to failing to account for array
decay. My solution was to just repeat the MAX_PATH again. But in
hindsight I realize that's bad because it hardcodes it, and introduces
the opportunity for an error where we update the size of the original
path but not the size in the function.

So instead, just pass the size through to the function.
2021-04-18 18:14:03 -04:00
Misa
3102cac9d9 Add asserts for missing images and sound effects
I don't want to add too many asserts, because sometimes it's okay if a
file is missing (mmmmmm.vvv). But currently, the game basically expects
all images and sound effects to be present. That might change in the
future, but for now, these asserts are okay.
2021-04-18 15:01:43 -04:00
Misa
9f11438dcc Fix dereferencing NULL if image fails to load
If LoadImage() returned NULL, the game would dereference it and
segfault. So I've added NULL checks to dereferencing the pointers.
2021-04-18 15:01:43 -04:00
Misa
8956b04d67 Fix missing return statements in drawsprite()
Whoops. Otherwise the game would end up indexing out-of-bounds despite
checking for it anyways.
2021-04-18 15:01:43 -04:00
Misa
1191f425b3 Add NULL checks to FILESYSTEM_loadFileToMemory()
FILESYSTEM_loadFileToMemory() dereferenced pointers without checking if
they were valid... I don't know of any cases where they could have been
NULL, but better safe than sorry.
2021-04-18 15:01:43 -04:00
Misa
3ebdc1da89 Transfer param init responsibility to loadFileToMemory
So, the codebase was kind of undecided about who is responsible for
initializing the parameters passed to FILESYSTEM_loadFileToMemory() - is
it the caller? Is it FILESYSTEM_loadFileToMemory()? Sometimes callers
would initialize one variable but not the other, and it was always a
toss-up whether or not FILESYSTEM_loadFileToMemory() would end up
initializing everything in the end.

All of this is to say that the game dereferences an uninitialized
pointer if it can't load a sound effect. Which is bad. Now, I could
either fix that single case, or fix every case. Judging by the title of
this commit, you can infer that I decided to fix every case - fixing
every case means not just all cases that currently exist (which, as far
as I know, is only the sound effect one), but all cases that could exist
in the future.

So, FILESYSTEM_loadFileToMemory() is now guaranteed to initialize its
parameters even if the file fails to be loaded. This is better than
passing the responsibility to the caller anyway, because if the caller
initialized it, then that would be wasted work if the file succeeds
anyway because FILESYSTEM_loadFileToMemory() will overwrite it, and if
the file fails to load, well that's when the variables get initialized
anyway.
2021-04-18 15:01:43 -04:00
Misa
8c8118e43f Don't mix code and decls in loadFileToMemory()
My next commit will involve using goto to jump to the end of a function
to initialize the variables to NULL, but that results in a compiler
error if we have initializations in the middle of the function. We might
as well put all declarations at the top of each block anyway, to help
the move to C, so I'm doing this now.

Since the length variable in the STDIN block now overshadows the length
variable in the outer block, I've renamed the length variable in the
block to stdin_length.
2021-04-18 15:01:43 -04:00
Misa
120bb7288b Don't mix code and decls in SoundTrack constructor
Minor style fix.
2021-04-18 15:01:43 -04:00
Misa
b02cf00ce6 Remove unnecessary Sint16 casts
These casts are sprinkled all throughout the graphics code when creating
and initializing an SDL_Rect on the same line. Unfortunately, most of
these are unnecessary, and at worst are wasteful because they result in
narrowing a 4-byte integer into a 2-byte one when they don't need to
(SDL_Rects are made up of 4-byte integers).

Now, removing them reveals why they were placed there in the first place
- a warning is raised (-Wnarrowing) that implicit narrowing conversions
are prohibited in initializer lists in C++11. (Notably, if the
conversion wasn't narrowing, or implicit, or done in an initializer
list, it would be fine. This is a really specific prohibition that
doesn't apply if any of its sub-cases are true.)

We don't use C++11, but this warning can be easily vanquished by a
simple explicit cast to int (similar to the error of implicitly
converting void* to any other pointer in C++, which works just fine in
C), and we only need to do it when the warning is raised (not every
single time we make an SDL_Rect), so there we go.
2021-04-18 14:55:33 -04:00
Misa
15b085b326 Fix duplicating ed_settings when opening editor menu second time
This fixes a bug where after loading in to the level editor, pressing
Esc and then switching your option to something other than the first
option, then pressing Esc again to close the menu, then pressing Esc
once more would not keep your menu option.

This is because the code that checks if Menu::ed_settings is already in
the stack doesn't account for if ed_settings is the current menu - the
current menu doesn't get put in to the stack.

In hindsight, maybe I could have designed the new menu system better so
the current menu IS on the stack, and/or should have used a
statically-allocated linked list for each menu name for the stack frames
(instead of an std::vector) and asserted if a menu that already existed
in the stack was created instead... that'll have to be done later,
though.
2021-04-18 13:13:04 -04:00
Misa
90b48887ed Fix missing colon in prompt when placing terminal
All other instances of "Enter script name:" have a colon except for this
one.
2021-04-18 06:53:24 -04:00
Misa
c37eb37b4d Consistently play Viridian squeak for pause menu inputs
Pressing Esc to cancel the confirm quit menu didn't play the squeak, in
contrast to pressing ACTION to cancel it, so now it does; pressing Esc
to close the pause menu or pressing ACTION will also now play the
Viridian squeak too.
2021-04-18 06:52:58 -04:00
Misa
c84d7ebf08 Rename vx/vy createentity args to meta1/meta2
vx/vy mean x-velocity and y-velocity... except here, where it seems like
they're used as extra parameters that do different things depending on
the entity. But it seems like at one point they were actually meant to
be the speed of the entity (this is the case for the unused decorative
particle entities), and then just never got renamed when they weren't.

The custom levels community named these two parameters meta1 and meta2
in the reference list of entities for the createentity() script command,
so that's what I'm naming them here. This will avoid confusion (I know
that some people reading this function have genuinely mistaken the vx/vy
for actually meaning x-velocity and y-velocity, simply because they were
named that way).
2021-04-17 18:29:17 -04:00
Misa
9ba30caeb3 Remove default function args from createentity()
I have spelled out each overloaded version instead, and only the
overloads that are actually used - which just happens to be everything
except the 8-argument one. I don't want to deal with callers right now
(there are too many of them), so I'm not going to change the names that
the callers use, nor do I want to change the amount of arguments any
existing callers use right now - but we will have to deal with them in
one way or another when we move to C.
2021-04-17 18:29:17 -04:00
Misa
7d223db211 Change all createentity args to be ints
The script command createentity() is always an int. But not only that,
every time createentity() is used, its arguments are always treated like
ints. Always. I knew that vx/vy were floats because of the int casts in
the function, but I didn't even realize that xp/yp were floats, too,
until I checked just now! That's how much they're treated like ints.

All int casts in createentity() have also been removed, due to being
unnecessary (either because of us suppressing MSVC implicit conversion
warnings, or because there are now no longer any conversions happening).
2021-04-17 18:29:17 -04:00
Misa
516e71c7da Remove customlevelstatsloaded from Game
This boolean is assigned, and it is checked... but it's never assigned
to true, thus making it useless. I also checked 2.2 source and the same
thing happens there; to prevent any confusion, I'm removing this.
2021-04-17 09:53:17 -04:00
Misa
28c3ec9572 Make map.[old]ypos ints instead of floats
So... I did see that map.ypos was a float when I added over-30-FPS mode,
because map.oldypos wasn't there before... I'm guessing that I kind of
just ignored it at the time. But, c'mon, map.ypos and map.oldypos are
always treated as ints, so there's literally no reason for them to be
actually floats in reality. I didn't even know they were anything other
than ints until I checked Map.h.
2021-04-17 09:52:30 -04:00
Terry Cavanagh
07c425b2f8
Merge pull request #730 from InfoTeddy/general-improvements
Axe mouse cursor config option in favor of automatically toggling mouse
2021-04-17 18:10:57 +10:30
Misa
83ad5e66de Show and hide mouse cursor based on user input
This is quite simple - whenever the user uses their keyboard or
controller, we hide the mouse cursor. Whenever they move the mouse, we
show it again. This makes it so the cursor gets out of the way when they
play the game, but reappears when they need it.

There is also a timeout, to prevent strobing if the user decides to use
the keyboard/controller and mouse at the same time. There is no timeout
from hiding the mouse cursor, but there is a timeout from showing the
mouse cursor - this because it's okay if the mouse lingers for a few
frames when you start using the keyboard, but really annoying if the
mouse doesn't instantly appear when you move it.
2021-04-16 22:58:45 -07:00
Misa
c76c67b125 Axe mouse cursor config option
The config option has been removed. I'm going to implement something
that automatically shows and hides the mouse cursor whenever
appropriate, which is better than a config option.
2021-04-16 22:00:33 -07:00
Misa
390720dacc Disable exceptions and RTTI in CMakeLists
These are two C++ features that we don't need, don't use, and will never
use in the future. Apparently the best way of doing this in CMake is to
fiddle with the CXX_FLAGS using regex.

Now this is one less flag I need to supply myself when I invoke CMake...
2021-04-17 00:50:04 -04:00
Misa
83f438d694 Use booleans for SUPPORTS_IMPLICIT_FALLTHROUGH
CMake has booleans, so why not use them?
2021-04-17 00:50:04 -04:00
Misa
2229c2c6c0 Remove usage of undefined variable PFSP_SRC
This variable is not defined anywhere and never has been since the
source code release (which is when this CMake file was first created).
To make things clearer, I'm cleaning this variable up.
2021-04-17 00:50:04 -04:00
Misa
afae945930 Don't pollute global includes/defines namespace
A function like add_definitions() adds definitions to ALL targets, not
just VVVVVV. This kind of namespace pollution is messy, and could result
in bugs if you pollute with the right kind of pollutant.

So instead of using add_definitions(), use target_compile_definitions().
And instead of using include_directories(), use
target_include_directories().
2021-04-17 00:50:04 -04:00
Misa
78aa3ca715 Switch SDL2 includes to be private
There's no reason for these to be public, and putting it public is
probably going to cause more harm than not.
2021-04-17 00:50:04 -04:00
Misa
ce4dc7e7bc Set C standard to C90 in CMake file
All the C third-party dependencies are C90, and all the C files we have
are also C90 (well, almost, but that's easily sorted). So we have
basically no reason to not go with C90 here.

The only wrinkle is, turning C extensions off for physfs-static results
in linker errors because PhysFS implicitly uses alloca() without
including it properly (on Linux). I am not the only one who has ran into
this - see https://icculus.org/pipermail/physfs/2020-April/001293.html -
and it's a bug with PhysFS. The workaround I've gone with is to enable C
extensions. (There might also be some funkiness with PhysFS's use of the
`inline` keyword, so enabling extensions will paper over that as well.)
2021-04-17 00:50:04 -04:00
Misa
c17ea40866 Use multiline comments in C files
So there were actually only two instances of C99-style end-of-line
comments in C files - and technically one of them was just a C file
including MakeAndPlay.h.
2021-04-17 00:50:04 -04:00
Misa
4c199efbac Add CMake version guard around setting C++ standard
It seems like CMake 3.1.3 introduced the C/C++ standard properties,
while the minimum version of this CMake file is 2.8.12. So we do what
FAudio does, which is print a warning if the CMake version is too old
and otherwise use it if we have the feature.
2021-04-17 00:50:04 -04:00
Misa
575698e715 Change cache bool variables into options
They're the same thing, but using option() better conveys intent.
However this can't be done for anything that isn't a bool, which the
CUSTOM_LEVEL_SUPPORT option is not (it's a tri-state string).
2021-04-17 00:50:04 -04:00
Misa
c060419a47 Remove redundant C++ standard sets from CMakeFiles
These were introduced in 098fb77611 - did
Leo not know that they were already there at the top of the file? This
does the same thing, except it only sets it for VVVVVV instead of
everything (so this wouldn't set it for the third-party dependencies).
2021-04-17 00:50:04 -04:00
Misa
c41ec551f7 Lowercase function calls in CMakeLists
Lowercase names are easier to type and are more distinguishable from the
capital letters that usually go inside the function calls as arguments.
2021-04-17 00:50:04 -04:00
Misa
d2951fb7f4 Remove extra semicolon from end of Credits namespace
-Wpedantic warns about this.
2021-04-17 00:50:04 -04:00
Misa
0dceec8c20 Add -Wpedantic to GCC/Clang in CMakeLists
This adds -Wpedantic so we get warned if our code doesn't strictly
conform to ISO C++98. It doesn't seem like MSVC has it.
2021-04-17 00:50:04 -04:00
Misa
be9a6382ea Fix playing same track after it has faded out
If a track was restarted after it faded out, then it wouldn't play. This
is because currentsong wasn't set to -1 after fading out, and that is
because the fade out calls pause() instead of haltdasmusik() when it
finishes.

Unlike f196fcd896, this fixes the time
trial music while keeping it to the same behavior as 2.2, and fixes
every single possible case that this music bug could have happened.
2021-04-14 13:02:00 -04:00
Misa
75133c74e7 Revert part of "Fix music stopping when restarting time trial"
This reverts only a part of f196fcd896 -
as the original commit author did not do their changes atomically, they
also squashed in a de-duplication within the same commit. So I'm only
reverting the part of the commit that wasn't the de-duplication, which
is simply the changes to the music.fadeout() calls.

This is being (partially) reverted for several reasons:

1. It's not the correct behavior. What this does instead is persist the
   track through after you restart the time trial, instead of fading it
   out, then restarting it again. This is in contrast to behavior in
   2.2, and I see no reason to not keep the same behavior.

2. It's a single-case patch. The time trials are not the only time in
   the game a music track could fade out and then be restarted with the
   same track - custom levels could do the same thing too. Instead of
   fixing only one case, we should strive to fix EVERY case.

The original commit author (trelbutate) also didn't write anything in
the commit description of f196fcd896. What
you should write in the commit description is things like rationale,
analysis, and other good information that would be useful to anyone
looking at your commit to understand why you did what you did. Having no
commit description leaves readers in the dark as to why you did what you
did.

Thus, I don't know why trelbutate went with this solution, or if they
knew that it was only a single-case patching, or if they knew that it
wasn't 2.2 behavior.

By not writing the commit description, they miss a chance for
reflection; speaking from personal experience, I myself have gone back
and improved my commits countless times because I wrote commit
descriptions for every single one of them, and sometimes whenever I
write them, I think to myself "hang on a minute, that doesn't sound
quite right" and end up finding improvements.

If trelbutate wrote a commit description, they might have realized that
it wasn't 2.2 behavior, and gone back and fixed up their commit to be
correct. As it stands, though, they didn't have to think about it in the
first place because they never bothered to write a commit description.
2021-04-14 13:02:00 -04:00
Misa
815d96dd4c Fix bracing of time trial startgamemode
It should be next-line brace, not same-line brace.
2021-04-14 13:02:00 -04:00
Malte Desktop
e0749801ea Add to contributors 2021-04-14 11:09:01 -04:00