1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-11-16 16:09:42 +01:00
Commit graph

230 commits

Author SHA1 Message Date
Misa
db8e0cd70a De-duplicate map menu quicksave screen
As is typical, the code was copy-pasted to account for Flip Mode, and
then copy-pasted again to account for custom levels, leading to four
instances of the same code.

I clean this up while also improving code style. This is where the new
FLIP macro and the fixed PrintWrap help a lot - otherwise the "Game
saved ok!" screen would look really wrong without the height
corrections.
2021-10-01 21:06:31 -07:00
Misa
517e20cecb Account for heights in the FLIP macro
Flipping objects in Flip Mode needs to account for the heights of those
objects (that's why flipme text boxes in Flip Mode in 2.2 were
positioned wrongly).

Also, turn it into a macro instead of an inline function.

This changes the positions of all existing de-duplicated map menu text
in Flip Mode, but it'll be more correct.
2021-10-01 20:39:24 -07:00
Misa
c3dfd4a4b1 De-duplicate map menu stats screen rendering code
Between accounting for Flip Mode and custom levels, this code was
copy-pasted three times, leading to _four_ instances of one code!

Anyways, I've cleaned it up. The position of the text in Flip Mode is
going to differ by 4 pixels from how it was previously, but that really
shouldn't matter.
2021-09-25 17:16:52 -07:00
Misa
e9351b4a00 Fix winning in No Death Mode saying "One trinkets"
While dying in No Death Mode was fixed to no longer say "One trinkets"
in 2.3, if you win in No Death Mode with one trinket, the game would say
"One trinkets".

So to fix this, just slot a ternary in there. The code is already kind
of bad anyways and is going to be refactored/de-STLed in the future
regardless, so I'm not feeling too badly about shoving a ternary in
there like that.
2021-09-25 17:06:59 -07:00
Misa
38b2213745 Rename number to number_words
This is to clarify that it returns the word forms of numbers, not
numbers themselves.
2021-09-25 15:08:13 -07:00
Misa
6ba7058a0e Fix VSync renderer workaround
SDL just got an API to toggle VSync without having to tear down the
renderer ( libsdl-org/SDL#4157 ). We can remove the workaround and use
that instead. For now, we are putting it behind an ifdef until SDL
2.0.18 officially releases in November.

Fixes #831.
2021-09-14 20:23:22 -07:00
Misa
8d0a90a588 Avoid function call to check empty room name
Instead, a simple comparison of the first element will do.
2021-09-12 21:54:47 -07:00
Misa
ddff461a6c Replace hardcoded temp buffer sizes with a named constant
Constants.h will house constants like the screen size and others. But
basically only the screen size for now.

Now we don't have to type that "4 bytes per 40 chars (whole screen)"
comment everywhere...
2021-09-12 21:40:20 -07:00
Misa
a50e8ecf48 Replace roomnames/hiddennames/glitchnames with const char*
Since those are all downstream recipients of either static storage or
memory that doesn't move for the duration of the custom level, it's okay
to make these be `const char*`s without having to redo any of the RAII
memory management.

mapclass::currentarea() is included in this as well. I also cleaned up
Tower.cpp's headers to fix some transitive includes because I was
removing UtilityClass.h includes from all other level files too.

The "Untitled room" names no longer show any coordinates, because doing
so would require complicated memory management that's completely
unneeded. No one will ever see them, and if they do they already know
they have a problem anyway. The only time they might be able to see them
is if they corrupted the areamap, but this was only possible in 2.2 and
previous by dying outside the room deaths array in Outside Dimension
VVVVVV, which has since been patched out. Besides, sometimes the
"Untitled room" gets overwritten by something else anyway (especially in
Finalclass.cpp), so it really, really doesn't matter.
2021-09-12 21:06:26 -07:00
Misa
f237f41d8e Remove useless arguments from drawimagecol()
Turns out, the r, g, and b arguments don't actually do anything!

There was a call to RGBf() in the function. RGBf() is just getRGB() but
first adds 128 and then divides by 3 to each of the color channels
beforehand. Unfortunately, RGBf() does not have any side effects, and
the function threw away the return value. Bravo.

This also reveals that the website images drawn in the credits in the
main menu are only recolored because of a stale `ct` set by the previous
graphics.bigprint(), and not because any color values were passed in to
drawimagecol()... What fun surprises the game has in store for me every
day.
2021-09-11 02:12:03 -07:00
Misa
c64fd89325 Untabify every single file
YOLO.

This is a repeat of #642. As before, I just did

    rg -l '\t' | xargs -n 1 sed -i -e 's/\t/    /g'

inside the desktop_version/ folder.
2021-09-06 18:56:39 -07:00
Misa
9767eb91f4 drawpixeltextbox: Remove now-unused parameters
They go bye-bye.

This is a friendly reminder that the map menu rendering code is heavily
copy-pasted, dear god...
2021-09-06 00:56:49 -07:00
Misa
31844eabc6 Axe drawcustompixeltextbox in favor of drawpixeltextbox
I'm honestly not too sure why drawcustompixeltextbox ever existed? All
it seemed to do was draw even more horizontal/vertical tiles to finish
any gaps in the tiling... which was all completely unnecessary and
wasteful, because even the previous drawpixeltextbox implementation
covered all gaps in all custom level map sizes that I tried.

Anyway, that at least gets rid of one copy-pasted function.
2021-09-06 00:56:48 -07:00
Misa
a23014350f Move all editor-specific attributes to a new editorclass
This is a pretty hefty commit! But essentially, I made a new editorclass
object, and moved all functions and variables that only get used in the
in-game level editor to that class. This cleanly demarcates which things
are in the editor and which things are just general custom level stuff.

Then I fixed up all the callers. I also fixed up some NO_CUSTOM_LEVELS
and NO_EDITOR ifdefs, too, in several places.
2021-09-01 15:30:02 -07:00
Misa
3e380e23fb Rename editor.h to CustomLevels.h
This accompanies the editor.cpp -> CustomLevels.cpp change; I'll be
splitting out the editor functions in the next commit. The name of the
include guard has been changed as well, but not anything else.
2021-09-01 15:30:02 -07:00
Misa
5abe615507 Fix Pauli Kohberger's name stopping being drawn too early
This is because the y-position of the graphics.onscreen() check was a
little too high. Then their name (under Beta Testing) would suddenly
disappear too early. You'd have to look real close to spot it, but it
does happen. It's cuz the credits are all kinda hardcoded, which is
probably bad, but fixing that would have to come later...
2021-08-31 23:23:27 -07:00
Misa
4c69281738 Move Misa to C++ credits
I talked with Ethan earlier about this. For 2.3, he wanted me in GitHub
contributors (well, still separate from the rest), to really highlight
the source-code-release community-driven nature of 2.3, but he said it'd
be fine to put me in C++ credits in 2.4.
2021-08-31 23:22:22 -07:00
Misa
62cff254b7 Bump version to 2.4 2021-08-31 10:25:29 -07:00
mothbeanie
1ec06c6f5c Standardize punctuation and style for the new options menu 2021-08-19 17:17:36 -07:00
Misa
a13d26d866 Add option to delete all custom level save data
To match the option to nuke all main game save data, there is also now
an option to nuke all custom level save data separately (which is just
all custom level quicksaves, along with stars for level completion). It
has its own confirmation menu too. It does not delete any levels from
the levels folder.
2021-08-18 16:02:11 -07:00
Misa
3a2265ef0d Add being able to delete a custom level quicksave
Custom level quicksaves are NOT affected by the clear data menu, so the
player should be able to delete quicksaves this way. The quicksave
confirmation menu now has an extra option to delete the save (and that
option also has its own confirmation menu before deleting).
2021-08-18 16:02:11 -07:00
Misa
bc47b86645 If loaded level assets fail to mount, print message to non-console users
This error case can happen, but if it does, non-console users get an
ERROR page with no further information. So use setLevelDirError if this
failure mode happens. And Menu::errorloadinglevel needs to be changed to
accomodate that.
2021-08-18 10:08:39 -07:00
Misa
28e4a155d4 Don't show next/previous page options if only one page
It's possible to get one page of levels by removing all the built-ins,
either by removing them directly from data.zip or by putting files with
the same filenames as them in your level folder that don't contain
nothing.

And hey, there's already a check for if no levels exist at all, so why
not check for this too?
2021-08-12 00:15:21 -04:00
Misa
7699f5aaf1 Display improper zip structure message to non-console users
If a zip file is improperly structured, a message will be displayed when
the player loads the level list.

This will only display the last-displayed improper zip, because there
only needs to be one displayed at a time. Also because doing anything
more would most likely require heap allocation, and I don't want to do
that.
2021-08-10 16:33:52 -04:00
Misa
8dc5d69ef3 Do not close game if custom level has assets issues
It's quite rude to close the game entirely if there is trouble with
assets. Instead, just unload the assets and gracefully return to the
title screen.
2021-08-10 16:33:52 -04:00
Misa
3095871683 Add unfocus audio pause option
Some people prefer the 2.2 behavior where unfocusing pauses the game,
but the music still plays. One such person is Trinket9 on the VVVVVV
Discord server, who wanted it that way.

The reason audio pausing was added in the first place was to prevent
desyncing music in levels with cutscenes that synced to music. Rather
than reverting it, let's add this option instead.
2021-08-10 15:26:44 -04:00
Misa
b9202dee8b Fix frame flickers when fading during loads/exits
This is because the fade delay did not last long enough.

I was under the mistaken impression that the fade animation lasts for 15
frames. However, this does not account for the fact that the offset of
each fade bar is dependent on RNG, and the worst case scenario is that
they have an offset of 96 pixels (in the opposite direction of the
fade).

The actual fade animation timer accounts for the worst case scenario, so
the fade animation actually lasts for (320 pixels plus 96 pixels is 416
pixels, 416 pixels divided by 24 pixels per frame equals 17.333...
frames, but since the actual timer keeps adding/subtracting 24 pixels
per frame until it passes the 416-pixel threshold, that gets rounded up
to...) 18 frames.

And an extra frame to make it so deltaframe interpolation doesn't
suddenly stop on the last deltaframes before the screen is completely
black.

I also need to draw the screen black on the map screen when glitchrunner
mode is off, if there's a fadeout going on. Else that would introduce
yet another frame flicker.
2021-08-05 19:12:23 -04:00
Misa
90660d67a7 Fix trailing whitespace introduced by lssa
No comment.
2021-08-05 19:12:23 -04:00
lsaa
6c66f7248d
Add in-game timer option (#790) 2021-08-05 17:31:20 -04:00
Misa
243f9b92f8 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 13:35:21 -04:00
Misa
c02bd9235f Outline text outline text and draw backing
In order to help players spot the difference between outlined text and
non-outlined text, we now outline the text outline text itself (if text
outline is enabled, of course). But drawing the outline alone doesn't
stand out enough, so we have to draw a solid backing against the text as
well, in order to properly show the contrast.
2021-06-12 19:02:14 -04:00
Terry Cavanagh
1d66cfccab
Merge pull request #777 from InfoTeddy/general-improvements
Outline time trial countdown
2021-06-12 22:35:31 +10:30
Misa
f205147eaa Outline time trial countdown
This makes the text much more readable against certain backgrounds (if
you have text outline enabled), especially against the Warp Zone
background (when you start in "This is how it is").
2021-06-11 23:56:33 -07:00
Misa
47460143e2 Fix being able to see box corners on map screen with custom graphics
The text box drawn at the bottom of the map screen isn't wide enough, so
it's possible to see the corners on the right side of the text box if
you have custom graphics like I do.

The solution is to increase the width of the text box by one tile.
2021-06-11 15:07:08 -07:00
Misa
4fa435f784 Separate pressing Enter to open map from pressing Enter to interact
This is a lot of copy-pasted code, but a little bit of copy-pasting
never hurt anyone...

The keybind to interact with activity zones and teleporters is now
separate from the keybind to open the map, or return to the editor from
in-editor playtesting, or restart a time trial. The keybind is now E,
and the default controller bind is X. No controller button prompts, but
the game didn't have controller button prompts anyways, so whatever.

Doing this now because if people's muscle memory are going to be broken
by not being able to spam the map keybind anymore, at least we can help
a bit by changing the keybind so they can keep spamming it - their
muscle memory is going to be broken anyways.

This option has to be enabled by going to the speedrunner menu options
and selecting "interact button". It is disabled by default.

All prompt text needs to be string-interpolated every time they are
drawn, because it is possible for people to change which interact button
they use in the middle of gameplay, via the in-game options.

Closes #736.
2021-05-19 00:04:00 -07:00
Misa
3c5ee78e8a Add finalmode check to drawfinalmap call
This fixes the finalstretch tile shifting persisting if you return to
the main dimension and final_colormode isn't reset properly.

It's possible to do so in the main game by using a teleporter in
finalmode while having the Intermission 1 or 2 companion active.

For custom levels, level makers can make a setup that automatically
turns on finalstretch, goes to finalmode, and then returns to the main
dimension. The only thing being... as a level maker myself, this tile
shifting REALLY doesn't seem useful (and no one has ever used it because
the setup to do so hadn't really been found or documented until this
year). For one, the exact shift is randomized every time (there's an
fRandom() call to cycle the colors). For two, it goes away after the
player saves and reloads the level. And for three, it doesn't animate
like it does in finalmode (this is the biggest reason IMO).

Nevertheless, I've decided to keep support for this in custom levels, in
case someone in the future does want to use it and is okay with the
limitations.
2021-05-03 19:40:15 -07:00
Misa
b3c2f56c79 Factor out slowdown/invincibility conds to function
This factors out the slowdown and invincibility conditionals to a
function. This means less copy-pasted code, and it also conveys intent
(that we don't want to allow competitive options if we have either of
these cheats enabled).

This function isn't implemented in the header because then we would have
to include Map.h for map.invincibility, and transitive includes are
evil. Although, map.invincibility ought to be on Game instead (it was
only mapclass due to 2.2-and-previous argument passing), but that's a
bunch of variable reshuffling that can be done later.
2021-05-03 22:32:06 -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
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
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
01ba834086 Don't tick timer if in time trial countdown
In 2.2 and previous, the game would call resetgameclock() every frame
for the last 30 frames of the time trial countdown in order to make sure
it gets reset. This was in a render function, and didn't get brought out
in 2.3, so 2.3 resets the game clock *while rendering*, which is kinda
bad and is an oversight on my part for not noticing.

Instead of doing that, just add a conditional to the timer so that it
won't tick during the time trial countdown. This fixes #699 even further
by making it so the time trial par can't even be lost during the
countdown, because the timer won't tick up - so you can never get a sad
squeak to play by pausing the game or unfocus-pausing it during the
countdown.
2021-04-13 17:51:24 -04:00
Misa
e8316c7e9a Implement music and sound volume sliders
This adds music and volume sliders to the audio options. To use the
sliders, you navigate to the given option, then press ACTION, and your
selection will be transferred to the slider. Pressing left or right will
move the slider accordingly. Then you can press ACTION to confirm the
volume is what you want and deselect it, or you can press Esc to cancel
the volume change, and it will revert to the previous volume; both
actions will write your settings to disk.

Most of this commit is just adding infrastructure to support having
sliders in menus (without copy-pasting code), which is a totally
completely new user interface that has never been used before in this
game. If we're going to be adding something new, I want to make sure
that it at least is done the RIGHT way.

Closes #706.
2021-04-11 20:56:16 -04:00
Misa
2a3f17f1f7 Add audio category to options menu
The audio category contains the MMMMMM soundtrack option, as well as
stubs for the soon-to-be-implemented volume slider options.
2021-04-11 20:56:16 -04:00
Misa
0f0e218cf6 Use macros to calculate accessibility offset
This means the offset is calculated at compile-time, and we can use a
proper case-switch here instead of an else-if chain.
2021-04-09 17:42:58 -04:00
Misa
b5f1cbb2d1 Clean up unused vars/funcs from eee98b0e07
eee98b0e07 made some functions and
variables unused, which generate compiler warnings. So I've removed
them.
2021-04-09 17:42:58 -04:00
Misa
8e4b904f57 Fix whitespace from eee98b0e07
eee98b0e07 introduced mixed indentation
and one trailing whitespace, which I've cleaned up.
2021-04-09 17:42:58 -04:00
TerryCavanagh
eee98b0e07 Clean up of options menus for v2.3 (fixes #696) 2021-04-09 20:39:12 +10:30
TerryCavanagh
d9d5cbbab2 Changed the wording on "Invincibility" and "Game Speed" accessibility options
I've wanted to do this one for a very long time
2021-04-09 17:53:15 +10:30
Misa
f8f6f3b96e Add option to re-enable 1-frame input delay
This is an option for speedrunners whose muscle memory is precisely
trained and used to the 1-frame input delay that existed in 2.2 and
below. It is located in Game Options -> Advanced Options, and is off by
default.

To re-add the 1-frame input delay, we simply move the key.Poll() to the
start of the frame, instead of before an input function gets ran -
undoing what #535 did.

There is a frame ordering-sensitive issue here, where toggling
game.inputdelay at the wrong time could cause double-polling. However,
we only toggle it in an input function, which regardless is always
guaranteed to be ran after key.Poll() (it either happened at the start
of the frame or just before the input function got ran), so this is not
an issue. But, in case we ever need to toggle this variable in the
future, we can just use the defer callbacks system to defer the toggle
to the end of the frame - also added by #535.

Added at the request of Habeechee on the VVVVVV speedrunning Discord
server.
2021-04-02 11:18:32 -04:00
Misa
cd2f5ccde9 Add period to glitchrunner mode description text
This is to be consistent with the other options in the Advanced Options
menu.
2021-04-02 11:15:53 -04:00
Misa
ef091de23e Outline all gravitron text
This includes all text from the Gravitron and Super Gravitron.

This is to make the text more readable if they are placed in weird
situations - for example, in custom levels, where the background these
texts get placed on could be anything (custom level makers are crazy!).
2021-03-30 23:57:00 -07:00
Ethan Lee
b99abaf1d5 Put Misa at the top of GitHub Friends 2021-03-31 02:43:15 -04:00
Misa
367e77fb59 Fix targets (question marks) not showing up on minimap
Followup to #635: I had misread the original '==0' comparisons as being
truthy comparisons instead of being falsy comparisons. Whoops.
2021-03-26 00:02:26 -04:00
Misa
c5e999c1d5 Refactor explored rooms to use setters and getters
This makes it easier to add bounds checks to all accesses of
map.explored. Also, all manually-written existing bounds checks have
been removed, because they're going to go into the new getters and
setters.

The getter is mapclass::isexplored() and the setter is
mapclass::setexplored().
2021-03-24 15:55:34 -04:00
Misa
0da9b5069a Capitalize "OFF" when invincibility is off
All other settings capitalize "ON" and "OFF", so this one should, too.
2021-03-21 20:53:40 -04:00
Misa
9ab61af1da Add period to text outline description
This is to be consistent with all other option descriptions, which all
end in a period as well.
2021-03-21 20:53:40 -04:00
Misa
5f2b9409b2 De-duplicate Gravitron initial message
Since the only difference is the y-positions, I've decided to remove the
copy-pasted code. A better solution would be to have a function that
draws multiline text and handles it accordingly in Flip Mode, but that
could be done later.
2021-03-21 02:06:39 -04:00
Misa
9e2716b253 Fix a few missing implicit void arg declarations
While working on #535, I noticed that editormenuactionpress() still
didn't do the explicit void declaration. Then I ran `rg 'void.*\(\)'`
and found three other functions that I somehow missed in #628. Whoops.
Well, now they no longer are missed.
2021-03-19 10:27:54 -04:00
Misa
9f69506acf Move activity prompt render updating to gamerenderfixed()
This probably should've been moved to RenderFixed a while ago, because
it's unnecessary to run this on every single deltaframe.

The only minor wrinkle here is that this means rendering of activity
zone fades will be delayed for 1 frame, but #535 will fix that.
2021-03-05 18:00:20 -05:00
Misa
38d5664601 Change all surface-clearing FillRect()s to use ClearSurface()
ClearSurface() is less verbose than doing it the old way, and also
conveys intent clearer. Plus, some of these FillRect()s had hardcoded
width and height values, whereas ClearSurface() doesn't - meaning this
change also has better future-proofing, in case the widths and heights
of the surfaces involved change in the future.
2021-02-25 19:38:25 -05:00
Misa
6a3a1fe147
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 17:23:59 -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
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
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
3eb3c30817 Use SDL_arraysize() - 1 to take length of INTERIM_COMMIT
Since INTERIM_COMMIT is a char array whose size we know for sure at
compile time, and which we also know is an array (instead of being a
pointer), we can take the SDL_arraysize() of it. However,
SDL_arraysize() doesn't account for the null terminator unlike
SDL_strlen(), so we'll have to do it ourselves. But at least we are
guaranteed to get a constant value at compile time, unlike if we use
SDL_strlen(), which would be repeatedly evaluating a constant value at
runtime.

To my knowledge, there's no equivalent SDL_arraysize() for constant
strings, and a quick `rg` (ripgrep) for "sizeof" in the SDL include/
folder doesn't show anything like that. So we'll just have to use the
SDL_arraysize() - 1 and deal with it.
2020-12-26 00:57:51 -05:00
Misa
02a45f9cbc 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-25 20:17:01 -05:00
Dav999-v
09986c90f7 Make indentation in settings saving error consistent with rest of cases 2020-12-18 14:16:53 -05:00
Dav999-v
444074a931 Add error messages for failed writes to disk of settings
Changing settings would most of the time attempt to save unlock.vvv and
now also settings.vvv, but there would be no feedback whether the files
have been saved successfully or not. Now, if saving fails when changing
settings in the menu, a warning message will be shown. The setting will
still be applied of course, but the user will be informed it couldn't
be saved. This message can be silenced until the game is restarted,
because I can imagine this could get very annoying when someone already
knows their settings aren't writeable.

Also, some options didn't even save settings in the first place. These
are turning off invincibility, and by coincidence precisely all the
options in the advanced options menu. I made sure these options now do
so.
2020-12-18 14:16:53 -05:00
Dav999-v
db0c38711c Visually remove all other tabs in SAVE-only enter screen
This commit does this:
> Yeah, it'd be better if all the other options were gone, and "[SAVE]"
> would be re-centered in the middle of the screen.
2020-12-18 10:03:10 -05:00
Misa
fb19787489 Remove duplicate game.controllerSensitivity proxy
It wasn't a direct duplicate of key.sensitivity, but it was still
basically the same thing. Although to be fair, at least the case-switch
conversion didn't get duplicated everywhere unlike game.slowdown.

So now key.sensitivity functions the same as game.controllerSensitivity,
and it only gets converted to its actual value whenever a joystick input
happens in key.Poll(), unlike previously where it got converted every
single frame on the title screen (there was even a comment that said
"TODO bit wasteful doing this every poll").
2020-12-18 10:02:18 -05:00
Misa
bc9dff8c2a Remove game.gameframerate as duplicate of game.slowdown
game.gameframerate seems to exist for converting the value of
game.slowdown into an actual timestep value, when really the timestep
value should just use game.slowdown directly with a fast lookup table.
Otherwise, there's a bunch of duplicated game.slowdown case-switches
everywhere, which adds up to a large, annoying pile should the values be
changed in the future. But now the duplicate variable has been removed,
and with it, all the copy-pasted case-switches.

Also, the game speed text rendering in Menu::accessibility and
Menu::setslowdown has been factored out to a function and de-duplicated
as well.
2020-12-18 10:02:18 -05:00
Misa
40b7ddda05 Remove duplicate screen configuration variables
There were some duplicate Screen configuration variables that were on
Game, when there didn't need to be.

 - game.fullScreenEffect_badSignal is a duplicate of
   graphics.screenbuffer->badSignalEffect
 - game.fullscreen is a duplicate of !graphics.screenbuffer->isWindowed
 - game.stretchMode is a duplicate of graphics.screenbuffer->stretchMode
 - game.useLinearFilter is a duplicate of
   graphics.screenbuffer->isFiltered

These duplicate variables have been removed now.

I put indentation when handling the ScreenSettings struct in main() so
the local doesn't live for the entirety of main() (which is the entirety
of the program).
2020-12-18 10:02:18 -05:00
Misa
ce203812ad Don't hardcode offset of interim commit print
Apparently, the amount of digits in a commit hash that git will output
varies depending on how many objects are in the repository that the hash
gets pulled from. The more objects, the more digits needed to avoid a
hash collision.

Sources:
    https://stackoverflow.com/q/18134627/#comment26560283_18134919
    https://stackoverflow.com/a/21015031/

So that means we'll have to dynamically account for the length of the
commit hash in order to get it properly right-aligned with the rest of
the text.
2020-11-20 22:18:59 -05:00
Misa
ebe074e308 Add commit hash and date to title screen
The commit hash and date are now shown above the version number in the
bottom-right of the title screen. They both automatically go away when
compiled in release mode.

https://cdn.discordapp.com/attachments/717089363896434719/779525976689213480/vvvvvv_with_interim_commit_and_date.png

This is useful to easily figure out which commit someone is on whenever
they report an issue, without having to ask them to do `git show` or
whatever.
2020-11-20 21:18:29 -05:00
Misa
3434ad8777 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 08:38:19 -05:00
Dav999-v
4ebf89e844 Add error message if quicksave fails 2020-11-03 22:05:26 -05:00
Misa
70f3d457dd Move title usages of towerbg to titlebg
With the previous commit in place, we can now simply move some usages of
the previous towerbg to use a separate object instead. That way, we
don't have to mess with a monolithic state, or some better way to phrase
what I just said, and we instead have two separate objects that can
coexist side-by-side.
2020-11-03 13:25:03 -05:00
Misa
72c048d71e Refactor tower background to use a separate object instead
Previously, the tower background was controlled by a disparate set of
attributes on Graphics and mapclass, and wasn't really encapsulated. (If
that's what that word means, I don't particularly care about
object-oriented lingo.) But now, all relevant things that a tower
background has has been put into a TowerBG struct, so it will be easy to
make multiple copies without having to duplicate the code that handles
it.
2020-11-03 13:25:03 -05:00
Misa
7b20d90446 Don't manually write out INBOUNDS_VEC() checks
This is because if they are manually written out, they are more likely
to contain mistakes.

In fact, after further review, there are several functions with
incorrect manually-written bounds checks:
 * entityclass::entitycollide()
 * entityclass::removeentity()
 * entityclass::removeblock()
 * entityclass::copylinecross()
 * entityclass::revertlinecross()

All of those functions forgot to do 'greater than or equal to' instead
of 'greater than' when comparing against the size of the vector. So they
were erroneous. But they are now fixed.
2020-09-25 13:51:47 -04:00
Misa
b34be3f1ac Use explicit INBOUNDS_VEC() instead of checking sentinel -1
It's better to do INBOUNDS_VEC(i, obj.entities) instead of 'i > -1'.

'i > -1' is used in cases like obj.getplayer(), which COULD return a
sentinel value of -1 and so correct code will have to check that value.
However, I am now of the opinion that INBOUNDS_VEC() should be used and
isn't unnecessary.

Consider the case of the face() script command: it's not enough to check
i > -1, you should read the routine carefully. Because if you look
closely, you'll see that it's not guaranteed that 'i' will be initialized
at all in that command. Indeed, if you call face() with invalid
arguments, it won't be. And so, 'i' could be something like 215, and
that would index out-of-bounds, and that wouldn't be good. Therefore,
it's better to have the full bounds check instead of checking only one
bounds. Many commands are like this, after some searching I can also
name position(), changemood(), changetile(), changegravity(), etc.

It also makes the code more explicit. Now you don't have to wonder what
-1 means or why it's being checked, you can just read the 'INBOUNDS' and
go "oh, that checks if it's actually inbounds or not".
2020-09-25 13:51:47 -04:00
Misa
c29d7c7d14 De-duplicate activity zone rendering, don't ignore act_fade
This is a follow-up to #421.

The game would draw the activity zone if there was one active at all,
and would ignore game.act_fade. Normally this wouldn't be a problem, but
since #421, it's possible that there could be an active activity zone
but game.act_fade would still be 5. This would happen if you entered a
new activity zone while a cutscene was running.

To fix this, just make it so that the prompt gets drawn on its own and
only depends on the state of game.act_fade (or game.prev_act_fade), and
won't be unconditionally drawn if there's an active activity zone. As a
bonus, this de-duplicates the drawing of the activity prompt, so it's no
longer copy-pasted.
2020-08-24 22:02:58 -04:00
Nichole Mattera
1376e65b5d Added ability to bind restart to a controller. 2020-08-08 19:02:14 -04:00
Misa
f07a8d2143 Move tele/activity/trophytext conds to collision detection
This moves the teleporter, activity prompt, and trophy text "don't draw"
conditionals to the part where the game checks collision with them,
instead of whenever the game draws them.

This makes it so that the game smoothly does the fade-in/fade-out
animation instead of suddenly stopping rendering them whenever their
"don't draw" conditions apply. Now, the "Press ENTER to activate
terminal" prompt will no longer suddenly disappear whenever you activate
one, and the "- Press ENTER to Teleport -" prompt will smoothly fade
back in after teleporting, instead of suddenly popping in on screen.
2020-08-03 00:12:15 -04:00
Misa
cec1a99d3b Don't draw activity zone or trophy text when cutscene is running
This fixes a possible graphical issue where the "Press ENTER to activate
terminal" prompt gets drawn on top of the "- Press ACTION to advance
text -" prompt, which looks bad. Trophy text gets drawn on top, too, so
there's a check there as well.

I've also made it so the activity prompt doesn't get drawn if the player
doesn't have control. After all, what use is it to say "press ENTER" if
the player isn't allowed to?
2020-08-02 22:48:06 -04:00
Dav999-v
4adcf7013c Reposition game time and trinket count in game save box
The game time is moved a little to the left, and the trinket count a
little to the right. To fix #376 for real, the trinket count is now
positioned automatically based on its length. The trinket icon is now
also displayed at the far right (instead of to the left of the count)
for better symmetry, and so that switching between tele save and quick
save doesn't make the trinket icon move if the trinket counts have
different lengths.
2020-08-02 20:22:23 -04:00
Dav999-v
6c02095d99 Make game save box 16 pixels wider
While I'm going to fix #376 anyway to make longer numbers (like Seventy
Eight) fit, I decided to also make the box a little wider in advance of
the game being localized, those extra chars could be a lifesaver, while
you wouldn't really notice the difference if you play the game in
English.
2020-08-02 20:22:23 -04:00
tzann
e2321f84b9 Add check for singular trinkets and crewmates in NDM game over screen 2020-07-28 21:54:35 -04:00
Misa
52f7a587fe Separate includes into sections and alphabetize them
Okay, so basically here's the include layout that this game now
consistently uses:

[The "main" header file, if any (e.g. Graphics.h for Graphics.cpp)]
[blank line]
[All system includes, such as tinyxml2/physfs/utfcpp/SDL]
[blank line]
[All project includes, such as Game.h/Entity.h/etc.]

And if applicable, another blank line, and then some special-case
include screwy stuff (take a look at editor.cpp or FileSystemUtils.cpp,
for example, they have ifdefs and defines with their includes).
2020-07-19 21:37:40 -04:00
Misa
b5ff65c84e Remove unnecessary includes from header files
Including a header file inside another header file means a bunch of
files are going to be unnecessarily recompiled whenever that inner
header file is changed. So I minimized the amount of header files
included in a header file, and only included the ones that were
necessary (system includes don't count, I'm only talking about includes
from within this project). Then the includes are only in the .cpp files
themselves.

This also minimizes problems such as a NO_CUSTOM_LEVELS build failing
because some file depended on an include that got included in editor.h,
which is another benefit of removing unnecessary includes from header
files.
2020-07-19 21:37:40 -04:00
Ethan Lee
2716296a10 Haiku: Keep the option visible, but note the bug 2020-07-08 14:43:04 -04:00
Ethan Lee
86fde7bf99 More VSync Haiku hackery 2020-07-08 14:38:55 -04:00
Misa
fd0dafc16c De-duplicate Graphics::drawmenu() and Graphics::drawlevelmenu()
Graphics::drawmenu() no longer has copy-pasted code for each individual
case. Instead, the individual cases have their own adding on to common
code, which is far easier to maintain.

Also, the only difference Graphics::drawlevelmenu() does is in some
y-positioning stuff. There's no reason to make it a whole separate
function and duplicate everything AGAIN. So it's been consolidated into
Graphics::drawmenu() as well, and I've added a boolean to draw a menu
this way if it's the level menu.
2020-07-06 11:19:24 -04:00
Misa
fc03fca838 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-06 11:19:24 -04:00
Ethan Lee
0f450f3e39 Move the VSync work to Screen.
The problem we're running into is entirely contained in the Screen - we need to
either decouple graphics context init from Screen::init or we need to take out
the screenbuffer interaction from loadstats (which I'm more in favor of since we
can just pull the config values and pass them to Screen::init later).
2020-07-02 00:19:40 -04:00
Dav999-v
7adf71a21b Change "toggle letterbox" to "scaling mode"
This change was half-backported from the localization branch, except I
just came up with "scaling mode" as a better term than the more generic
"graphics mode". It doesn't make sense to still have the option be
called "toggle letterbox" because a third option (integer mode) was
added at some point.
2020-06-30 16:53:33 -04:00
Dav999-v
e20c01deed Move "resize to nearest" grouped with other resolution-related options
The options for fullscreen and scaling mode were at the top, then there
were various other graphical options, and then the option to resize to
the nearest window size that is of an integer multiple was all the way
below that. Now that last option is moved to be right below the other
options related to window sizing.
2020-06-30 16:53:33 -04:00
Dav999-v
a2d8e57af0 Move some options to a new menu, "advanced options"
VVVVVV's menus are kind of packed to the brim, so I thought it was time
to recategorize the menus a little bit. There's now a new "advanced
options" menu which holds the following options which were moved out of
graphic options, game options and especially accessibility options:

- toggle mouse
- unfocus pause
- fake load screen
- room name background
- glitchrunner mode

I also made the positioning of the titles and descriptions more
consistent, and made some options which were moved to the new menu not
so abbreviated ("load screen" and "room name bg")
2020-06-30 16:53:33 -04:00
Misa
15e10af08e Display trinkets on the minimap in custommode
I don't really like how copy-pasted the minimap rendering code is, but
whatever. We can refactor it later.
2020-06-30 16:30:09 -04:00
Misa
3f7ed4b94a Don't selectively undraw tiles in towers if backgrounds are off
The game for some reason had this thing where it would not draw the
diagonal background tiles if you had animated backgrounds turned off.
Which is weird, because spikes with that background are still drawn as
spikes with that background. And also, it doesn't do this for any of the
tower hallway rooms, which is inconsistent.

Better to simplify the logic in Render.cpp anyways by removing
graphics.drawtower_nobackground() and making it really clear what
exactly we'll do if backgrounds are turned off. ("Aren't we already not
drawing the background? What's this _nobackground() function for?")
2020-06-30 14:34:42 -04:00