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

248 commits

Author SHA1 Message Date
Misa
8fa916c55d Make the toggle fullscreen conditional more readable
Each check has been put in its own variable, so the final conditional is
more readable, and the ifdef is no longer right smack in the middle of
an if-statement.

Also the control flow has been changed (the "else" has been removed from
the shortcut-checking conditional) so I could put the variables closer
to the actual conditional itself. I don't think it affects anything,
though.
2020-03-12 21:20:25 -04:00
Misa
e23682615d Allow using F11 and (on macOS) RCmd+Enter/F to toggle fullscreen
This patch allows the use of pressing F11 to toggle fullscreen, as well as
allowing the use of Right Command when using the Command+Enter/F shortcut on
macOS. Apparently Alt+Enter isn't the only shortcut to toggle fullscreen,
Alt+F also works, which I didn't know before.

I'm adding F11 as a shortcut because it's a far more natural shortcut to
toggle fullscreen than this Alt+Enter or Alt+F business, which seems to be a
relic mimicking some other games and some Microsoft stuff?

I'm also adding RCommand+Enter/F because I see no reason not to. If you can
use RAlt on non-macOS, why can't you use RCommand on macOS, too?

I also cleaned up the formatting relating to the shortcut code, and made sure
the closing parenthesis was outside the ifdef so my text editor wouldn't
highlight the parenthesis inside the non-macOS ifdef-branch as a dangling
closing parenthesis, because it assumes the one in the branch above is the
actual closing parenthesis and doesn't parse macros.
2020-03-12 21:20:25 -04:00
AlexApps99
aff0c06458 Fixes #112: Backbuffer is always 32bpp 2020-03-12 10:06:23 -04:00
Misa
c322ae131e Fix unfocusing the game while in fullscreen mode
If you Alt+Tabbed while in fullscreen mode, the game would stay in
fullscreen instead of switching to windowed, but there was a chance it
would EITHER use the same internal resolution which would mismatch the
window resolution (don't know when exactly this happens, but still) and
stay being in an actual windowed mode, OR switch between
fullscreen/windowed every other time you re-focused the window, which is
annoying.

Now, whenever you Alt+Tab in fullscreen, the game will be in windowed
mode, and then when you re-focus it will go back to fullscreen.
Consistently.
2020-03-05 00:22:18 -05:00
Misa
a46d5b126c Write unlock.vvv when pressing Alt+F4
Previously, the only way to guarantee that the game actually saved your
unlock.vvv after changing an option, was to ensure you pressed ACTION on
the "quit game" menu option.

This makes Alt+F4 graceful in that pressing it will also save
unlock.vvv, as it should. Now truly UN-graceful ways of exiting the
game, such as SIGSEGV, SIGABRT, or pkill -9 or pkill -15 will not save
unlock.vvv, as should be the case.
2020-03-04 17:20:42 -05:00
Misa
5a25cad74b Don't draw text outline for roomtext in the editor
Text outline is not drawn on roomtext when you're actually playing the
game, so don't draw the outline in the editor, either.

FIQ mistakenly added text outline to roomtext in
ca9f577fc4.
2020-03-04 15:50:52 -05:00
Misa
b82a8a0925 Fix undefined behavior with left-click logic in editor
There's an if-else chain that first deals with figuring out if there's
an entity where your left-click happened, and to do this it uses
edentat(), which returns a sentinel value of -1 if there is NOT an
entity where your cursor is.

It's very important to check that the value returned ISN'T -1 before you
start indexing the 'edentity' vector, since if you DO index it with that
-1, it'll result in Undefined Behavior because you're doing an
out-of-bounds array access.

Now, here's what the if-else chain looked like before:

    if(tmp==-1 && ed.free(ed.tilex,ed.tiley)==0)
    {
        ...
    }
    else if(edentity[tmp].t==1)

The bug here is very subtle but it was an easy oversight. Basically, if
'ed.free' ended up not being zero, control flow would jump to the next
"else if" over, which then ends up asking for the -1th index of
'edentity', which is Undefined Behavior.

This undefined behavior has now resulted in a crash on my system after
TerryCavanagh/VVVVVV#172, due it shuffling things around juuuuust enough
such that this UB would end up resulting in a segfault instead of
chugging along and working fine. For me and my system, this meant that
if my first left-click in the editor upon opening the game was me
placing down a tile and not placing down an entity, the game would
crash. But, it would be fine if I first placed down an entity and then
afterwards placed down tiles, because it's UB.

And I'm almost certain this was the cause of the very strange bug where
you couldn't hold down left-click for the foreground-placing tool (but
you COULD for the background-placing tool) that seemed to occur most
often on Windows (TerryCavanagh/VVVVVV#25).

The solution to this is to stick in another conditional in the tree
before any indexing occurs, such that there's no way any other
conditionals with the indexing in the conditional tree could end up
being hit. In summary, the if-else chain looks like this now:

    if(tmp==-1 && ed.free(ed.tilex,ed.tiley)==0)
    {
        ...
    }
    else if(tmp == -1)
    {
        //Important! Do nothing, or else Undefined Behavior will happen
    }
    else if(edentity[tmp].t==1)
2020-03-02 08:22:08 -05:00
Misa
8d44d9387b Refactor edentities to not use separate length-trackers
This turns the array 'edentity' into a proper vector, and removes the need to
use a separate length-tracking variable and manually keep track of the actual
amount of edentities in the level by using the long-winded
'EditorData::GetInstance().numedentities'. This manual tracking was more
error-prone and much less maintainable.

editorclass::naddedentity() has been removed due to now functionally being the
same as editorclass::addedentity() (there's no more
'EditorData::GetInstance().numedentities' to not increment) and for also being
unused in the first place.

editorclass::copyedentity() has been removed because it was only used to shift
the rest of the edentities up manually, but now that we let C++ do all the
hard work it's no longer necessary.
2020-03-01 15:47:01 -05:00
Misa
a4d7fc017c Refactor roomtext to not use ad-hoc objects / separate length trackers
This refactors the roomtext code to (1) not use ad-hoc objects and (2)
not use a separate length-tracking variable to keep track of the actual
amount of roomtext in a room.

What I mean by ad-hoc object is, instead of formally creating a
fully-fledged struct or class and storing one vector containing that
object, this game instead hacks together an object by storing each
attribute of an object in different vectors.

In the case of roomtext, instead of making a Roomtext object that has
attributes 'x', 'y', and 'text', the 'text' attribute of each is stored
in the vector 'roomtext', the 'x' attribute of each is stored in the
vector 'roomtextx', and the 'y' attribute of each is stored in the
vector 'roomtexty'. It's only an object in the sense that you can grab
the attributes of each roomtext by using the same index across all three
vectors.

This makes it somewhat annoying to maintain and deal with, like when I
wanted add sub-tile positions to roomtext in VVVVVV: Community Edition.
Instead of being able to add attributes to an already-existing
formalized Roomtext object, I would instead have to add two more
vectors, which is inelegant. Or I could refactor the whole system, which
is what I decided to do instead.

Furthermore, this removes the separate length-tracking variable
'roomtextnumlines', which makes the code much more easy to maintain and
deal with, as the amount of roomtext is naturally tracked by C++ instead
of us having to keep track of the actual amount of roomtext manually.
2020-02-29 23:02:52 -05:00
Misa
f7e71bd668 Fix left-clicking on script boxes
You can now left-click on script boxes in order to change their script.
2020-02-21 18:15:26 -05:00
Misa
ea8053303d Initialize x to 0 in ss_toi()
This fixes a source of undefined behavior, where the int returned by
ss_toi() would be random garbage memory if the string passed into it
would be empty. That's because if the string is empty, there are no
characters to parse, so nothing simply gets put into x.

The easiest way to pass an empty string in to ss_toi() would be to use
script commands with empty arguments.
2020-02-20 00:05:55 -05:00
Ethan Lee
0531ee9b19 SDL_Init after FILESYSTEM_init, for gamecontrollerdb.txt 2020-02-19 12:44:36 -05:00
Misa
e18dd195ba Fix typo: "quiting" (one T) to "quitting" (two Ts) 2020-02-17 13:17:36 -05:00
Misa
1b04cb5dd6 Fix crewmate-found text boxes overlapping in flip mode
The problem was that the code seemed to be wrongly copy-pasted from the
code for generating the trinket-found text boxes (to the point where
even the comment for the crewmate-found text boxes didn't get changed
from "//Found a trinket!").

For the trinket-found text boxes, they use y-positions 85 and 135 if not
in flip mode, and y-positions 105 and 65 if the game IS in flip mode.
These text boxes are positioned correctly in flip mode.

However, for the crewmate-found text boxes, they use y-positions 85 and
135 if not in flip mode, as usual, but they use y-positions 105 and 135
if the game IS in flip mode. Looks like someone forgot to change the
second y-position when copy-pasting code around.

Which is actually a bit funny, because I can conclude from this that it
seems like the code to position these text boxes in flip mode was
bolted-on AFTER the initial code of these text boxes was written.

I can also conclude (hot take incoming) that basically no one actually
ever tested this game in flip mode (but that was already evident, given
TerryCavanagh/VVVVVV#140, less strongly TerryCavanagh/VVVVVV#141, and
TerryCavanagh/VVVVVV#142 is another flip-mode-related bug which I guess
sorta kinda doesn't really count since text outline wasn't enabled until
2.3?).

So I fixed the second y-position to be 65, just like the y-position the
trinket text boxes use. I even took the opportunity to fix the comment
to say "//Found a crewmate!" instead of "//Found a trinket!".
2020-02-16 09:30:00 -05:00
Stelpjo
c665d5b8c8 Fixed some music bugs
Previously, when MMMMMM is installed but the user is using PPPPPP, niceplay would still restart the song even if it's the same. That has been fixed. In addition, Plenary and Path Complete no longer loop when MMMMMM is installed but PPPPPP is in use.
2020-02-12 21:52:25 -05:00
Matt Penny
df1c1303bf
Use dynamic credits lists for main menu credits screens (and add GitHub contributors) (#160)
Also added GitHub contributors to the credits on the main menu
(previously they were only present in the credits at the end of the
game)
2020-02-11 23:45:58 -05:00
Matt Penny
4ccb48f440 Use uint32_t instead of char32_t 2020-02-11 06:02:35 -05:00
Matt Penny
e7252888b6 Support pre-C++11 compilers 2020-02-11 06:02:35 -05:00
Matt Penny
9adcbaed6c Fix NO_CUSTOM_LEVELS compile after #158
ifdef out the code that draws the "return to editor" text in
NO_CUSTOM_LEVELS builds now that it accesses variables in the
editor class (PR #158)
2020-02-11 05:59:28 -05:00
Misa
9b125ad8df Prevent removing line if there is only one line
This fixes another way you could end up typing on a non-existent line in
the script editor.

In a script with only 1 line, which is empty, the game would let you
press backspace on it, removing the line. This results in you typing on
a non-existent line.

You will keep typing on it until you either close the script or press
Up. If you press Up, you will be unable to get back to the non-existent
line, for it doesn't exist - but the text you typed on the non-existent
line will still be there, until you close the script and re-open it.
2020-02-10 22:57:00 -05:00
Terry Cavanagh
172ab9195d
Merge pull request #158 from AllyTally/entertoreturn
Make "[Press ENTER to return to editor]" fade out after a bit
2020-02-10 18:41:13 +01:00
Matt Penny
1b00d12600 Add option to allow custom levels when the editor is disabled 2020-02-09 23:31:44 -05:00
Matt Penny
7d35c5ce4e Add option to compile without the level editor 2020-02-09 23:31:44 -05:00
AllyTally
6b1a7ebce6 Make "[Press ENTER to return to editor]" fade out after a bit
This makes the "[Press ENTER to return to editor]" fade out after a few frames, allowing screenshots of custom levels to be cleaner and to make sure nothing is obscured while the user is editing their level.
This commit also adds alpha support in BlitSurfaceColoured, where it takes into account the alpha of the pixel *and* the alpha of the color.
`graphics::getRGBA(r,g,b,a)` was added to help with this.
2020-02-09 22:31:33 -04:00
Info Teddy
3273b4ab55 Re-comment out #define MAKEANDPLAY
Silly me forgot to remove it after testing the MAKEANDPLAY define.
2020-02-09 10:42:03 -05:00
Info Teddy
9642921a64 Initialize level data with 0s in M&P
Following discussion on TerryCavanagh/VVVVVV#153, I suggested that
instead of reverting my M&P guards from TerryCavanagh/VVVVVV#124 (which
would only revert it for The Final Level, The Lab, Overworld, and The
Tower, leaving Space Station 1 & 2 and The Warp Zone alone which could
potentially cause the same problem that motivated
TerryCavanagh/VVVVVV#153), we should initialize the map data with 0s
instead.
2020-02-08 23:54:20 -05:00
Matt Penny
dd7170dc59
Add -basedir option to specify base user directory (#154)
Useful for maintaining multiple save files or for debugging
2020-02-08 18:49:03 -05:00
AllyTally
93ec5783d5 Fix undefined behavior when activating scripts
It turns out that the line `tstring=tstring[tstring.size()-1];` also appears once in Scripts.cpp.
This causes the game to segfault after activating a terminal with an empty line at the end of it.
I added a quick `if` around this line, and set `tstring` to an empty string when needed.
2020-02-08 00:10:56 -05:00
AllyTally
19de5ec59d Add self to CONTRIBTORS.txt and githubfriends 2020-02-07 23:30:49 -05:00
AllyTally
ca0bfcfa80 Fix undefined behavior while loading scripts
In `editor.cpp`, there's a few sections of code that try and index stuff using `string.length()-1`.
This causes issues where if the string is empty, the result is -1, causing undefined behavior.
Flibit fixed a few of these cases, like on line `375` of editor.cpp:
`if((int) tstring.length() - 1 >= 0) // FIXME: This is sketchy. -flibit`
It turns out that one of these weren't caught, over at line `471`.
`tstring=tstring[tstring.length()-1];`
This causes builds compiled on Windows to segfault if you load more than one level in the editor.
I added a quick `if` around it, setting `tstring` to an empty string, which seems to fix the problem.
2020-02-07 23:30:49 -05:00
Info Teddy
e3025a6b27 Render screen shaking in towers
It's really obvious that screen shaking is not processed in towers if
you bring up the pause menu then quickly quicksave and bring it back
down. The screen won't shake, but it will suddenly start shaking if you
exit the tower, finishing off the stalled screenshake timer.
2020-02-06 16:34:43 -05:00
Terry Cavanagh
4e378b6057
Merge pull request #147 from InfoTeddy/general-bug-fixes-5
Make hardest room "Dimension VVVVVV" if it has no room name
2020-02-06 16:37:37 +01:00
Terry Cavanagh
3d8c84bbbf
Merge pull request #149 from FredrIQ/master
Make tiles in tower mode consistent with tower tileset elsewhere
2020-02-06 16:36:21 +01:00
Info Teddy
6e1197ad64 Fix wrong tiling in top-left corner of Do Try To Keep Up
This commit changes one down-edge tile to be a down-left corner edge
tile.
2020-02-06 10:14:49 -05:00
Info Teddy
d61d4f6120 Draw entities backwards in towermode like non-towermode entities
This fixes a bug where the player was going behind checkpoints in towers
and it looked very weird and cursed.
2020-02-06 10:12:44 -05:00
Info Teddy
a08e731a39 Fix Prize for the Reckless moving platform kludge happening in customs
If you died in (11,7) and a moving platform was to the left of the line
x=152, even if it was moving vertically it would get snapped to x=152,
in custom levels.

Surprised nobody has ran into this before (although people have ran into
the other kludge, which is placing tile 59 at [18,9] if you're in a room
on either the line x=11 or y=7).
2020-02-06 10:12:24 -05:00
Fredrik Ljungdahl
1062113f73 Make tiles in tower mode behave consistently with tower tileset elsewhere
Previously, in tower mode, being inside walls would just kill you, unlike
being inside walls outside tower mode, which was somewhat confusing.

Also, spikes behaved differently with regards to invincibility, being
unsolid in towers but solid outside them.

This does not change the behaviour of the "edge" spikes in towers.
2020-02-05 22:08:48 +01:00
Info Teddy
8ead9db39f Make hardest room "Dimension VVVVVV" if it has no room name
The only places where you can die in a room without a room name is the
Overworld, and I feel that calling it Dimension VVVVVV is appropriate.

You can't naturally die in The Ship nor the Secret Lab, and you can only
do it by pressing R, so I didn't feel it appropriate to add checks to
make the hardest room be "The Ship" or "The Secret Lab" if you managed
to get your hardest room to be a room in either of those areas.
2020-02-03 19:27:49 -08:00
Info Teddy
cefc95d324 Fix centered texts' outline rendering upside-down in flip mode
If you looked at the "- Press ENTER to Teleport -" text in flip mode,
you might have noticed that the outline looked pretty strange and
glitched-out for some reason. It's just the outline rendering
upside-down. To fix this, make PrintOff() use flipbfont instead of
bfont.
2020-02-02 20:52:59 -05:00
Info Teddy
a2ab8e82e1 Account for height of textbox in flipme()
The problem with flipme() was that it WAS properly reflecting
("reflecting" as in mirroring over a given line) the text box over the
line y=120, BUT it forgot to account for the height of the text box.
Thus, the text box position would be off by the length of its own
height. And when the text box got taller, this offset would worsen and
worsen.
2020-02-02 20:41:41 -05:00
Info Teddy
4bc76416f5 Fix discoloration when entities warp in flip mode
In flip mode, warping entities would appear to change color for a brief
moment. This is actually them defaulting to the actual color used in
flipsprites.png, instead of first being whited-out and then re-colored
using graphics.setcol().

To fix this, use BlitSurfaceColoured() and pass `ct` along instead of
using BlitSurfaceStandard().
2020-02-02 18:29:00 -05:00
leo60228
45491a03f3
Add -assets option to specify data.zip (#139)
This is useful for distributions, which may not want to put data.zip in
the same directory as the binary. This can't be distribution-specific
due to the license ("Altered source/binary versions must be plainly
marked as such, and must not be misrepresented as being the original
software.").
2020-02-02 18:28:26 -05:00
Info Teddy
8260bb2696 Fix Prize for the Reckless quicksand fix kludge
If you died in Prize for the Reckless, which is at (11,7), and respawned
in the same room, tile 59 (a solid invisible tile) would be placed at
[18,9] to prevent the moving platform from going back through the
quicksand.

Unfortunately, the way that this kludge was added is poor.

First, the conditional makes it so that it doesn't happen in ONLY
(11,7). Instead of being behind a positive conditional, the tile is
placed in the else-branch of an if-conditional that checks for the
normal case, i.e. if the current room is NOT (11,7), thus being a
negative conditional.

In other words, the positive conditional is "game.roomx == 111 &&
game.roomy == 107". To negate it, all you would have to do is
"!(game.roomx == 111 && game.roomy == 107)".

However, whoever wrote this decided to go one step further, and actually
DISTRIBUTE the negative into both statements. This would be fine, except
if they actually got it right. You see, according to De Morgan's laws,
when you distribute a negative across multiple statements you not only
have to negate the statements themselves, but you have to negate all the
CONJUNCTIONS, too. In other words, you have to change all "and"s into
"or"s and all "or"s into "and"s.

Instead of making the conditional "game.roomx != 111 || game.roomy !=
107", the person who wrote this forgot to replace the "and" with an
"or". Thus, it is "game.roomx != 111 && game.roomy != 107" instead. As a
result, if we re-negate this and take a look at the positive
conditional, i.e. the conditional that results in the else-branch
executing, it turns out to be "game.roomx == 111 || game.roomy == 107".
This ends up forming a cross-shape of rooms where this kludge happens.
As long as your room is either on the line x=11 or on the line y=7, this
kludge will execute.

You can see this if you go to Boldly To Go, since it is (11,13), which
is on the line x=11. Checkpoint in that room, then touch a disappearing
platform, wait for it to fully disappear, then die. Then an invisible
tile will be placed to the left of the spikes on the ceiling.

Anyway, to fix this, it's simple. Just change the "and" in the negative
conditional to an "or".

The second problem was that this kludge was happening in custom levels.
So I've added a map.custommode check to it. I made sure not to make the
same mistake originally made, i.e. I made sure to use an "or" instead of
an "and". Thus, when you re-negate the negative conditional and turn it
into the positive conditional, it reads: "game.roomx == 111 &&
game.roomy == 107 && !map.custommode".
2020-02-02 08:46:14 -05:00
Info Teddy
1e460721bb Fix hardcoded (19,8) all-sides warp happening in custom levels
(19,8) is hardcoded to warp on all-sides no matter what. This is fine,
except for the fact that it was doing this in custom levels, too, even
despite the fact that the warp background and color would be overridden
anyway. The only workaround was to add a warp line to the room in custom
levels. I've added a check for custommode so that this won't happen.
2020-02-02 08:43:28 -05:00
Info Teddy
867e8ff0fe Make obj accessible from everywhere
Looks like in my original pull request I forgot to do this. Oh well.
2020-01-31 15:53:29 -08:00
Info Teddy
4fa62ca0aa Fix text() centering with x=-1
The game uses magic values x=-500 and y=-500 to indicate when a text box
should be centered horizontally or vertically. It does this for x=-1
too, but it's buggy because it only looks at the first line of the text
box to center it. In this commit I fix it so that it will look at all of
the lines of the text box to center it instead.
2020-01-31 13:36:36 -08:00
leo60228
6a17625727
Add support for Unicode rendering (#47)
This uses utfcpp combined with a custom font, in the form of a PNG and text file. By default, the game acts exactly as it did before; custom fonts can be provided by third parties.
2020-01-31 13:25:37 -05:00
Info Teddy
98ac1fdb53 Set customwarpmode when createentitying warp lines
This fixes a bug where warp lines created through createentity wouldn't
work without there already being a warp line present in the room as an
edentity.
2020-01-30 23:17:30 -05:00
Info Teddy
4be6d58b82 Reset warp directions when exiting playtesting
This fixes a bug where if warpdir() was used during in-editor
playtesting, the changed warp direction would persist even when leaving
playtesting.

This would be very annoying to correct back every time you playtested
and warpdir() was used, so I've added some kludge to store the actual
warp direction of each room when entering playtesting, and then set the
warp directions back when leaving playtesting.
2020-01-30 22:15:45 -05:00
Terry Cavanagh
98151b4c2f
Merge pull request #126 from FredrIQ/master
Fix and improve handling of cancelling roomtext/scripttext input
2020-01-30 15:36:18 +01:00
Info Teddy
5a316d65e6 Allow using help/graphics/music/game/key/map/obj everywhere
This commit makes `help`, `graphics`, `music`, `game`, `key`, `map`, and
`obj` essentially static global objects that can be used everywhere.
This is useful in case we ever need to add a new function in the future,
so we don't have to bother with passing a new argument in which means we
have to pass a new argument in to the function that calls that function
which means having to pass a new argument into the function that calls
THAT function, etc. which is a real headache when working on fan mods of
the source code.

Note that this changes NONE of the existing function signatures, it
merely just makes those variables accessible everywhere in the same way
`script` and `ed` are.

Also note that some classes had to be initialized after the filesystem
was initialized, but C++ would keep initializing them before the
filesystem got initialized, because I *had* to put them at the top of
`main.cpp`, or else they wouldn't be global variables.

The only way to work around this was to use entityclass's initialization
style (which I'm pretty sure entityclass of all things doesn't need to
be initialized this way), where you actually initialize the class in an
`init()` function, and so then you do `graphics.init()` after the
filesystem initialization, AFTER doing `Graphics graphics` up at the
top.

I've had to do this for `graphics` (but only because its child
GraphicsResources `grphx` needs to be initialized this way), `music`,
and `game`. I don't think this will affect anything. Other than that,
`help`, `key`, and `map` are still using the C++-intended method of
having ClassName::ClassName() functions.
2020-01-29 07:58:23 -05:00
Allison Fleischer
906e35244b Display menu text darker if mouse cursor is off 2020-01-29 07:55:50 -05:00
Allison Fleischer
03a4c3362a Add graphics option to toggle mouse cursor
Adds an option to show or hide the system mouse cursor over the game window.
2020-01-29 07:55:50 -05:00
Info Teddy
47ebbf15ab Don't redraw H/V warp BG if gotorooming to same room in customs
This has two benefits:
 (1) The game uses less resources when it is asked to gotoroom to the
     same room because it is no longer redrawing the warp background
     every single frame, which is very wasteful.
 (2) The warp background no longer freezes or flickers if the player is
     standing inside a gotoroom script box (which calls gotoroom every
     frame or every other frame, because every time the gotoroom happens
     the script box gets reloaded).
2020-01-27 14:46:11 -08:00
Fredrik Ljungdahl
3cfa7b0c60 Fix and improve handling of cancelling roomtext/scripttext input
First, two bug fixes. Room text input mode wasn't properly unset
upon pressing Esc, making the prompt get stuck, requiring you to
add roomtext again and finish it to make it go away. Secondly,
escaping script text input would remove the wrong entity.

I also tweaked the handling slightly so that instead of deleting
the entity if it already existed if escaping from text input,
it merely reverts the change in script name/roomtext to what it
was previously.

I considered refactoring the editor text input handler entirely,
but figured such a change would be a bit too extensive for the
purpose of this repository.
2020-01-27 11:15:25 +01:00
Fredrik Ljungdahl
757fd49283 Draw editor entities according to ingame order
Ingame entities are drawn backwards, probably to draw the player on top,
being entity 0 (usually, at least). Make the level editor draw entities
in the same order.
2020-01-26 22:22:10 -05:00
Info Teddy
7f3d16801c Remove from M&P the room data of Final Level/Lab/Overworld/Tower
This is to make sure that the room data of those areas are not
distributed with the M&P binary, even if they are already inaccessible
because of other M&P ifdefs (I tested).
2020-01-26 12:29:20 -05:00
Fredrik Ljungdahl
3697487f47 Fix minor issue with respawning into a tower
When the game enter towermode, it adjusts player amd camera x/y depending
on what screen the player entered it from (The Tower) or the loadlevel
mode ("minitowers"; Panic Room and The Final Challenge). This code didn't
account for respawning to checkpoints. This is unlikely to matter in most
circumstances, but can cause problems in some corner cases, or with R abuse.
This could cause a player to die, respawn outside camera edges and then
immediately die again due to the edge spikes, repositioning the camera
properly. Invincibility would cause further issues, but that's Invincibility
Mode for you -- if this was the only problem I wouldn't bother.

I added a check that repositions the tower camera appropriately if a player
enter a tower as part of the respawn process.
2020-01-25 23:30:29 -05:00
Info Teddy
b79f0daa5f Move y-position assignment into its most intended branch
This is a code style fix.
2020-01-25 23:29:37 -05:00
Info Teddy
2709de9cf0 Make fast path using FillRect() when opaque
FillRect() is similar enough to memset when blending isn't used, so the
game will take a fast path drawing the roomname background when the
background is opaque.
2020-01-25 23:29:37 -05:00
Info Teddy
2f85c2a8dc Draw room names with text outline
This makes it easier to see if you have a translucent room name
background.
2020-01-25 23:29:37 -05:00
Info Teddy
df83c2d494 Add an accessibility option to be able to see through the roomname
This is the variable dwgfx.translucentroomname and <translucentroomname>
in unlock.vvv.

This lets you see through the black background of the roomname at the
bottom of the screen, i.e. it makes the roomname background translucent.
So you can see if someone decides to hide pesky spikes there.
2020-01-25 23:29:37 -05:00
Info Teddy
c49ae404af Convert roomname background to a surface, then draw that
The roomname background used to just be a simple SDL_Rect that was drawn
using SDL_FillRect with a color of 0. Unfortunately, it seems that you
cannot use transparent colors with SDL_FillRect, it just defaults to
being fully opaque. However, you CAN draw surfaces with translucency,
which seems like the easiest thing to do. But the first step is to
convert the roomname background to an SDL_Surface.

This replaces the FillRect()s with SDL_BlitSurface() in the three places
roomnames are drawn: in towerrender, in gamerender, and in editorrender.
2020-01-25 23:29:37 -05:00
Info Teddy
f6fa8dd84c De-duplicate the roomname printing code in the editor
For some reason, there are two lines that have been copy-pasted the
exact same way and in the exact same place, namely being at the end of
each branch of the if-else conditional, which makes them be executed no
matter what. If they're going to be executed no matter what, we might as
well make it clearer and take those two lines out of each branch.
2020-01-25 23:29:37 -05:00
Fredrik Ljungdahl
4ea4a1e615 Move skipblocks default setting to obj.init() 2020-01-24 20:28:15 -05:00
Fredrik Ljungdahl
9296547feb Fix tower quicksave bug (only appeared in some builds)
I ran the game through Valgrind to catch various issues.
One thing caught my attention -- map.resumedelay. This is
used by The Tower/etc to add a delay before the game is
resumed (probably for camera controls delaying it) for
spawning the player. This variable was uninitialized. Notably,
if I explicitly set it to 592851 or similar, it reproduces the
bug, even if I cannot reproduce it with my typical compilation
flags. So fixing this by initializing it to 0, alongside some
other Valgrind warnings, should fix the problem entirely.
2020-01-24 20:28:15 -05:00
Fredrik Ljungdahl
2ec1106741 Fix level editor not using LoadTiXmlDocument 2020-01-24 16:45:18 -05:00
Fredrik Ljungdahl
5862af4445 Add a null terminator to loaded TinyXML files (#117)
* Add a null terminator to loaded TinyXML files

The TinyXML parse() function expect a C-like string, including terminator.
When xml loading was changed, it loaded the file, but included no such thing.
Thus, we load the file, then reallocate the memory so that we can insert a
null terminator to it, before passing it to parse().

* Tweak TinyXML file loading

Instead of first loading the file content into memory, then reallocate it
to add a null pointer, add an argument to the file load function for whether
to append a null terminator or not, defaulting to false. It still returns the
length without the null pointer in case a length ptr is passed.
2020-01-24 15:35:46 -05:00
Dav999-v
3dee27db7b Remove superfluous whitespace in entity XML data in level files (#119)
An earlier change caused TinyXml to prettyprint specifically the
contents of entities (script names and roomtext) a bit more than
before in level files, and added an unusually high amount of whitespace
(particularly, it added an empty line to every entity). This happens
because, for some reason, an empty string is explicitly being added
when creating an entity XML element. The line is so mysterious it feels
like it probably somehow solved a nasty bug long ago and shouldn't be
touched, but it was probably just a mistake, and with all that
whitespace it doesn't look good.
2020-01-24 14:25:21 -05:00
Stelpjo
9cf5112f0d Added myself to CONTRIBUTORS.txt 2020-01-24 12:26:21 -05:00
Stelpjo
09af7c2b5f Added an apostrophe to 'controllers' in game options 2020-01-24 12:26:21 -05:00
Info Teddy
a02d776b00 Make foundtrinket() be accurate in custommode
Previously, if it was called in a custom level, it would say "out of
Twenty" no matter what, even if the level had zero trinkets. This commit
fixes that.
2020-01-23 10:00:26 -05:00
Info Teddy
37507c147f Abstract UtilityClass::number() to be more generic
Previously, it was a hardcoded list going up to fifty.

This time, it's less hardcoded. Most of the time, it will take a number,
find out its tens-place word, find out its ones-place word, and combine
the two together. There are special cases for the teens, and the numbers
zero through nine, and one hundred.

Also, now if it is given a negative value, it will just return "???"
instead.

If there are more than one hundred it will still say "Lots".
2020-01-23 10:00:26 -05:00
Info Teddy
cd7cc317b5 Up the trinkets/crewmates limit to 100
2.2 will handle this just fine, because there are 100 slots allocated
for trinkets and crewmates, and it will save and load all 100 slots just
fine. Except, it only resets the first 20 slots when starting a level
from the beginning, but that's minor and already fixed in 2.3 anyway.

This commit makes it so you can now place up to one hundred trinkets and
crewmates in the editor.
2020-01-23 10:00:26 -05:00
Terry Cavanagh
782ce95d11
Merge pull request #115 from FredrIQ/master
Make the level editor use font outlines
2020-01-23 14:59:53 +01:00
Fredrik Ljungdahl
76792e652a Don't outline entity directions (looks odd and can never be hard to see) 2020-01-23 14:53:35 +01:00
Info Teddy
e8fd134a43 Fix X and Y coordinates getting reversed in editorclass::reset()
When editorclass::reset() was resetting the contents of the level
previously, it was mixing up the X and Y bounds. The Y bound was
supposed to be 30*maxheight, and the X bound was supposed to be
40*maxwidth. Instead, it took 30*maxwidth as its Y bound and
40*maxheight as its X bound.

Then, when it actually indexes the contents vector to set each tile to
0, it used 30*maxwidth instead of 40*maxwidth.

The difference between width and height is a bit hard to spot, but one
thing you can do to remember the difference is to remember the fact that
X corresponds with width, and Y corresponds with height. Also, rooms are
40 by 30 tiles, and so X (and therefore width) should correspond with
40, and Y (and therefore height) should correspond with 30.

As a result of mixing up the variables, whenever you played a 20x20 map,
quit the level and then started making a new 20x20 map, the tiles of the
last four rows of the previous map would persist, from y=16 (1-indexed)
all the way to y=20 (1-indexed).

I don't recall anyone ever running into this bug before, which is a bit
strange. But if no one truly has ever ran into this bug before, then I'm
genuinely surprised.

While working on the patch to fix the enemy type room property of each
room not getting reset, and testing the fix, I noticed that for some
reason some contents of the previous level I played in order to test the
enemy type property persisting was ALSO persisting alongside the enemy
type property.

Then I read the code and when I realized that the X and Y bounds were
getting mixed up I groaned. Very loudly.
2020-01-23 08:42:35 -05:00
Info Teddy
8e9970d619 Reset enemy type in editorclass::reset()
This fixes a bug where if you loaded a level, then started making a new
level in the editor, the enemy types from the previous level would
persist.

While working on VVVVVV: Community Edition and adding a new room
property for enemy speed, I noticed that enemy type was not getting
reset at all. After some testing, I confirmed that this was the case. So
this bug is fixed now.
2020-01-23 08:39:55 -05:00
Fredrik Ljungdahl
48c71c158d Add myself to CONTRIBUTORS.txt 2020-01-23 14:24:54 +01:00
Fredrik Ljungdahl
ca9f577fc4 Make the level editor use font outlines for text appropriately 2020-01-23 14:23:56 +01:00
Info Teddy
f9525020bb Call nexttowercolour() when exiting to menu
This fixes a bug where you could get mismatched text and background
colors on the menu screen by being in the Tower and exiting at a certain
time. The background when mismatched will always be red, which seems to
have something to do with the fact that when you enter the Tower the
game always sets the background to be red. I could get a quick repro
setup going by starting in the checkpoint in Teleporter Divot, then
quickly entering the Tower, exiting, then re-entering, then pressing Esc
and quitting - all done very quickly.

The important thing about this mismatch is that it's only temporary, and
will be corrected when you press ACTION and the color of the text and
background in the menu both change at the same time, which is what
map.nexttowercolour() does. So all I do is simply call that function
when exiting to the menu, and it will fix the color mismatch.
2020-01-22 20:26:54 -05:00
Info Teddy
cb642ec506 Don't quick fade when using niceplay()
Earlier in 53950e14de65a54d9369c5183a16337782d3dc4e, I made playing a
song while a song was already fading quickly fade out the current song,
but then added an exception for if the fade came from the musicfadeout()
command. This commit adds another exception for if the fade came from
niceplay(), since otherwise the music transitions between areas in the
game would go too quick.
2020-01-22 20:26:16 -05:00
Info Teddy
bff9b850b7 Reset game.pausescript in hardreset()
This fixes an issue where you could softlock the game if you exited
playtesting mode by pressing Esc while a "- Press ACTION to advance text
-" prompt was onscreen, then re-entered playtesting and then started any
script.

The "- Press ACTION to advance text -" prompt is most directly
controlled by game.advancetext, but when it appears game.pausescript is
usually set as well. You need to have both variables on at the same time
in order to press ACTION. If only advancetext is on, then you won't be
able to flip but can still move around, but if only pausescript is on,
then the game softlocks because the only way you can turn pausescript
off is by pressing ACTION, but the game will only let you press ACTION
if *both* advancetext and pausescript are on.
2020-01-22 20:25:54 -05:00
Info Teddy
90cab340f1 Copy the backBuffer to the tempBuffer in towerrender()
This fixes a bug where bringing up the pause screen while in a tower
would draw the room you entered BEFORE the tower during the time it took
for the pause screen to be brought up or down.
2020-01-22 09:56:19 -05:00
Info Teddy
9f6a60c298 Reset cutscene bar position in hardreset()
This fixes a bug in the editor where if you had cutscene bars active
while exiting playtesting, when you re-entered playtesting, the bars
would do their closing animation even though they should be already
gone.
2020-01-22 07:47:15 -05:00
Info Teddy
31efc9b3ce Fix out-of-bounds array access in findstartpoint()
Out-of-bounds array access is Undefined Behavior, which means Bad
Things.

In this particular case, it was indexing an array by using the
`testeditor` variable. Which is fine, except it was indexing that array
*in a conditional that only happens if `testeditor` is -1*. So it was
indexing an array at position -1, which is Out of Bounds and is Not
Good.
2020-01-22 07:46:46 -05:00
Info Teddy
794ef29638 Fix bug with displaying translucent pixels incorrectly
For a long time, VVVVVV has had an issue where if you used custom
graphics with translucent pixels (i.e. pixels whose opacity was neither
0% nor 100%, but somewhere between 0% and 100%), those pixels would end
up looking very ugly. They seemed to be overlaid on top of some weird
blue color, instead of actually being translucent.

This bug only occurred when in-game and not in towermode. So, most of
the time, basically. The translucent pixels only displayed properly
inside the Tower, both minitowers, and the editor (when not
playtesting).

I traced this down to the use of the magic number 0xDEADBEEF in
Graphics::drawmap() and Graphics::drawfinalmap(). Looks like someone had
fun finding a color. Was it you, simoroth? Anyway, I've changed it so it
simply uses 0 instead. Note that this magic number needs to be changed
for BOTH FillRect() and OverlaySurfaceKeyed(), or else the game's
background will be some random solid color instead of actually being
drawn properly.
2020-01-21 23:33:33 -05:00
Info Teddy
14ba07f22c Don't play squeak twice when entering quickloadlevel 2020-01-20 15:33:31 -05:00
Info Teddy
2c2acc93e6 Reset Direct Mode in editorclass::reset()
There's a long-standing issue where the Direct Mode status of the loaded
custom map in memory never resets properly. So if you load a level with
a certain layout of Direct Mode rooms, that same layout will be
preserved if you start making a new level in the editor. This commit
fixes that issue.
2020-01-19 21:46:52 -08:00
Info Teddy
916f182ce6 Set ed.keydelay when backspacing an empty line
Similar to 2ebccbc3e9, there's also a
long-standing bug where if you backspace an empty line (and this time,
the line IS actually already empty, not merely
emptied-earlier-in-the-frame), the game will quickly delete more blank
lines if there are any above the blank line you deleted. Again, this is
annoying too, if you so happen to need to use lots of blank lines.

To fix this, it's simple - just set ed.keydelay to 6 when the game
backspaces an empty line. Then it won't be so trigger-happy in deleting
blank lines.
2020-01-19 08:37:14 -05:00
Info Teddy
2687090ac2 Fix frame-ordering backspacing empty line bug in script editor
There is a long-standing bug with the script editor where if you delete
the last character of a line, it IMMEDIATELY deletes the line you're on,
and then moves your cursor back to the previous line. This is annoying,
to say the least.

The reason for this is that, in the sequence of events that happens in
one frame (known as frame ordering), the code that backspaces one
character from the line when you press Backspace is ran BEFORE the code
to remove an empty line if you backspace it is ran. The former is
located in key.Poll(), and the latter is located in editorinput().

Thus, when you press Backspace, the game first runs key.Poll(), sees
that you've pressed Backspace, and dutifully removes the last character
from a line. The line is now empty. Then, when the game gets around to
the "Are you pressing Backspace on an empty line?" check in
editorinput(), it thinks that you're pressing Backspace on an empty
line, and then does the usual line-removing stuff.

And actually, when it does the check in editorinput(), it ACTUALLY asks
"Are you pressing Backspace on THIS frame and was the line empty LAST
frame?" because it's checking against its own copy of the input buffer,
before copying the input buffer to its own local copy. So the problem
only happens if you press and hold Backspace for more than 1 frame.
It's a small consolation prize for this annoyance, getting to
tap-tap-tap Backspace in the hopes that you only press it for 1 frame,
while in the middle of something more important to do like, oh I don't
know, writing a script.

So there are two potential solutions here:

 (1) Just change the frame ordering around.

     This is risky to say the least, because I'm not sure what behavior
     depends on exactly which frame order. It's not like it's key.Poll()
     and then IMMEDIATELY afterwards editorinput() is run, it's more
     like key.Poll(), some things that obviously depend on key.Poll()
     running before them, and THEN editorinput(). Also, editorinput() is
     only one possible thing that could be ran afterwards, on the next
     frame we could be running something else entirely instead.

 (2) Add a kludge variable to signal when the line is ALREADY empty so
     the game doesn't re-check the already-empty line and conclude that
     you're already immediately backspacing an empty line.

I went with (2) for this commit, and I've added the kludge variable
key.linealreadyemptykludge.

However, that by itself isn't enough to fix it. It only adds about a
frame or so of delay before the game goes right back to saying "Oh,
you're ALREADY somehow pressing backspace again? I'll just delete this
line real quick" and the behavior is basically the same as before,
except now you have to hit Backspace for TWO frames or less instead of
one in order to not have it happen.

What we need is to have a delay set as well, when the game deletes the
last line of a char. So I set ed.keydelay to 6 as well if editorinput()
sses that key.linealreadyemptykludge is on.
2020-01-19 08:37:14 -05:00
Info Teddy
b1d6b7f395 Fix off-by-one in script editor letting you type on a nonexistent line
For a long time, the script editor has had a bug where it would let you
put the cursor on a nonexistent script line, which would APPEAR to be
the last line of the script... but in reality, it WASN'T the last line
of the script, and in fact, the ACTUAL last line was the line ABOVE the
script.

So, if you typed anything on this nonexistent line, it would appear to
get erased when exiting the script. Thus, people have (erroneously)
misdiagnosed this as the script editor somehow being trigger-happy and
erasing lines when it shouldn't be, when in reality it should've have
let you gone onto that line in the first place!
2020-01-19 00:33:20 -05:00
Ethan Lee
134a0f1070 Fix invincibility/slowdown cursor positions when exiting those menus 2020-01-17 22:14:29 -05:00
Ethan Lee
9eebbc542e Load gamecontrollerdb.txt if available 2020-01-17 12:43:42 -05:00
Ethan Lee
6e9712f113 Add text outline as an accessibility option 2020-01-17 12:37:53 -05:00
Terry Cavanagh
4fb9bfbd7e
Merge pull request #92 from InfoTeddy/general-bug-fixes
Don't render "[Press ENTER to return to editor]" if "- Press ACTION to advance text -" is also being rendered
2020-01-17 14:18:47 +01:00
TerryCavanagh
b3bc8d565c Found another dumb comment, removed
see b0ffdf0153
2020-01-17 13:47:34 +01:00
Info Teddy
a6d427501c Don't render press ENTER to return to editor if advancetext is on
This prevents a visual clash that can happen if both are on and there
are no cutscene bars.
2020-01-16 23:33:12 -08:00
Ethan Lee
2aa4aa5f8a Integrate dynamic list sizes for credited patrons, add CONTRIBUTORS to credits
(Also added myself to the credits, only took 6 years to not be lazy about it)
2020-01-16 20:14:56 -05:00
Thomas Sänger
73335c347c add myself to CONTRIBUTORS.txt (with LC_COLLATE=C ordering) 2020-01-16 09:48:58 -05:00