1
0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-07-01 08:58:31 +02:00
Commit Graph

2201 Commits

Author SHA1 Message Date
Misa
9a87d23719 Style: Fixup instances of void arguments
The style we have here is that functions with no arguments are to have
explicit `void` arguments, even though this doesn't apply in C++,
because it does apply in C.

Unfortunately, some have slipped through the cracks. This commit fixes
them.
2023-03-18 15:28:33 -07:00
Misa
63bc71b796 Always add null terminator when loading files
This removes the `addnull` argument from `FILESYSTEM_loadFileToMemory`
and `FILESYSTEM_loadAssetToMemory`, and makes it so a null terminator is
always appended no matter what.

This simplifies things and removes the need for callers to make the
decision about null termination and what its implications are. Then you
get cases where null termination might not happen when it should be,
such as the one df577c59ef (#947) fixed.

When FIQ added the `addnull` argument in
5862af4445 (#117), I'm guessing he did it
because he wanted to be cautious about adding the null terminator to
every file, so he only did it for XML files, which was the only case
needed at the time. But really, there's no downsides to always appending
a null terminator. In fact, it's already always done whenever the STDIN
buffer is loaded.
2023-03-18 15:12:24 -07:00
AllyTally
fb15a0b515 Fix the game texture clearing during menu shaking
Because of how `blackout` works, screen shaking must clear the gameplay
buffer. `blackout` simply pauses rendering, so if the gameplay buffer
gets cleared, then the screen will just be black, otherwise it'll look
like the game is "frozen". VVVVVV only uses `blackout` during screen
shaking, so it works as intended. However, when reimplementing this
behavior in the move to using the SDL_Renderer system, I failed to
notice that since my implementation always clears the gameplay buffer
when shaking, if you open the menu during a shake, instead of seeing
gameplay during the transition animation, you only see black. This has
been fixed with a simple `game.blackout` check before clearing the
gameplay buffer.
2023-03-18 13:53:36 -07:00
Misa
acfa085fd1 Remove reference from customlevelclass::load arg
For some reason, originally, this function mutated the std::string
passed into it by reference. So calling the function could potentially
mutate whatever got passed in, and callers potentially could have relied
on that behavior.

Now that the surrounding callsites have all been cleaned up, though
(especially scriptclass::startgamemode), it's clear that it's only used
in two places: Loading the level in the editor, and loading the level in
live gameplay. In both cases, the passed-in string isn't used ever again
afterwards.

So, it's safe to delete the mutable reference without any undesirable
effects, making the code cleaner and easier to understand. The function
now mutates a copy instead of mutating whatever the caller has.
2023-03-16 21:09:41 -07:00
Dav999-v
79f5e7a05c Fix loading font .txt files that contain null bytes
An example is Maximally Misleading Miserable Misadventure, which has a
font.txt which includes all ASCII characters starting with a 0x00 byte.
This would accidentally null-terminate the string too early.

Instead, we now use the total length of the file again, and keep
getting the next UTF-8 codepoint until the file ends. We still need to
null-terminate it - it protects against incomplete sequences getting
the UTF-8 decoder to read out of bounds.
2023-03-16 14:01:31 -07:00
Dav999-v
df577c59ef Fix font .txt files not being null-terminated
This was an oversight when we migrated to the new UTF-8 system - it
expects a null-terminated string, but the utfcpp implementation worked
with a pointer to the end of the file instead.

I also added an assert in FILESYSTEM_loadFileToMemory() so this is less
likely to happen again - because there should be no valid reason to
have a NULL pointer for the total file size, as well as not wanting a
null terminator to be added at the end of the file.
2023-03-16 12:42:54 -07:00
Dav999-v
310f3489d2 Remove key casts from hashmap function calls
We don't need the (char*) or (void*) casts anymore. You may need to
`git submodule update --init`.
2023-03-05 13:21:43 -08:00
AllyTally
188fc996bd Fix hardestroom not being translated
`hardestroom` currently stores the current roomname, but it was missing
a call to get the translated string. This has been added, fixing the
hardest room appearing as untranslated.
2023-03-05 11:33:16 -08:00
Dav999-v
d112dee72c Change font::len text argument from std::string to const char*
See the previous two commits, a lot of the time we don't need
std::string objects to be passed to these functions because we already
have C strings.

   Commit 1/3: font::print_wrap
   Commit 2/3: font::print
-> Commit 3/3: font::len
2023-03-04 16:10:17 -08:00
Dav999-v
5e3a4e69ce Overload font::print text argument for both std::string and const char*
Turns out I was overplaying my hand a little when changing font::print
from std::string to const char*, so instead, I'll overload the
function: it can take either a const char* (the main function) or a
std::string (a wrapper). This means any C string that's printed
everywhere else (which is common, especially because loc::gettext gives
them) no longer needs to be converted to a std::string object each call.

   Commit 1/3: font::print_wrap
-> Commit 2/3: font::print
   Commit 3/3: font::len
2023-03-04 16:10:17 -08:00
Dav999-v
264b6474be Change font::print_wrap text argument from std::string to const char*
We no longer need to pass a std::string object to the print and len
functions - in fact, we often only have a C string that we want to
print or get the visual width of (that C string most often comes from
loc::gettext), and it's a bit wasteful to wrap it in a new std::string
object on every print/len call.

This does mean adding a few more .c_str()s, but there's not many places
where a std::string is being passed to these functions, and we already
use .c_str() sometimes.

-> Commit 1/3: font::print_wrap
   Commit 2/3: font::print
   Commit 3/3: font::len
2023-03-04 16:10:17 -08:00
Misa
58d21e956b Fix analogue filter allocating/freeing surfaces every frame
This removes memory churn caused by using analogue mode.

The surfaces are only allocated if analogue mode is turned on, and kept
after they are initialized. Otherwise, if analogue mode is never turned
on (which will be the case for the vast majority of the time the game is
played), then no extra memory is used.
2023-03-04 14:02:47 -08:00
Misa
5eecc2a21d Don't draw texture onto itself for scrolling
Drawing a texture onto itself seems to produce issues on Metal.

To fix this, use a temporary texture instead, that then gets drawn onto
the original texture.

Fixes #927.
2023-03-03 20:21:53 -08:00
Misa
33fa0750be Destroy gameScreen after all other graphics are destroyed
This is because destroying the renderer causes use-after-frees since the
renderer destroys all textures when it gets destroyed.

This fixes a Valgrind error where an invalid read occurs because the
font textures get destroyed again after the renderer is destroyed.
2023-03-03 16:46:15 -08:00
Dav999-v
faff8bba5f Fix possible dangling pointers in FontContainer.map_name_idx
The hashmap would get populated with the name of each font, as each
font was being added. Unfortunately, adding a font would also realloc
the storage for fonts, in which the names are also stored... Possibly
invalidating the pointers to the names. This is now fixed by populating
the hashmap after all the fonts are added.
2023-03-03 16:38:53 -08:00
Misa
04743abe91 Destroy towerbg and titlebg textures in destroy_buffers
For consistency, since they are created in create_buffers as well. I
checked with Valgrind (which is very noisy on Wayland, it turns out),
but I didn't see anything about them not being freed. It doesn't hurt to
use VVV_freefunc here anyway, though, since it does a NULL check and
nulls the pointer afterwards, which should prevent double-freeing and
use-after-frees.
2023-03-03 15:34:13 -08:00
Misa
d1e9bdc284 Rename tempTexture to menuoffTexture
I'm going to soon be creating an actually temporary texture, so having
two textures named "temp" would get confusing. This is also a good
chance to correct the name of this texture, because it's not really
temporary, but it's used for map menu animation rendering.
2023-03-03 15:25:15 -08:00
Misa
e31344c68c Remove trailing whitespace in create_buffers
This was added in by AllyTally in
19b2a317f1.
2023-03-03 15:23:55 -08:00
AllyTally
5beaf973ce Strip out old special roomname system
This commit replaces the old system with the new one, making it much
easier to edit the transforming and glitchy roomnames. Additionally,
this syncs flag 72 to finalstretch.

Co-authored-by: Misa Elizabeth Kai <infoteddy@infoteddy.info>
2023-03-02 22:58:12 -08:00
AllyTally
dd108a035f Animated roomnames, setroomname command
This commit adds a better system for animated roomnames.

The old system, like many other systems, were very hardcoded, and can be
described as mostly else-if chains, with some fun string comparisons.
The new system uses lists of text for transformations and glitchy names,
making it much easier to add new cases if needeed.

This commit implements the system but does not replace the old system,
where that is done in the next commit.

The settings for special roomnames can be read from level XML, and
`setroomname()` can be used from commands to set a new, static name.
2023-03-02 22:58:12 -08:00
Dav999-v
368b9f1b3d Replace use of PHYSFS UTF-8 functions by UTF8.h
This is a massive simplification of the UTF-8 work there, lol
2023-02-27 23:00:41 -08:00
Dav999-v
a91c85d92e Fix UTF-8 handling in next_wrap
Finally this FIXME can be removed!
2023-02-27 23:00:41 -08:00
Dav999-v
f34aa65faa Replace utfcpp by UTF8.h in Font.cpp
I'm also planning to change the argument types of font::len,
font::print and font::print_wrap from const std::string&s to
const char*s, but I'll do that separately.
2023-02-27 23:00:41 -08:00
Dav999-v
8a011c3061 Replace utfcpp by UTF8.h in Textbox.cpp 2023-02-27 23:00:41 -08:00
Dav999-v
736ce3ecbf Replace utfcpp by UTF8.h in Localization.cpp 2023-02-27 23:00:41 -08:00
Dav999-v
a545384677 Replace utfcpp by UTF8.h in KeyPoll.cpp 2023-02-27 23:00:41 -08:00
Dav999-v
c5a48776c9 Replace utfcpp by UTF8.h in Editor.cpp 2023-02-27 23:00:41 -08:00
Dav999-v
393c5ac4fe Replace utfcpp by UTF8.h in CustomLevels.cpp 2023-02-27 23:00:41 -08:00
Dav999-v
2474623b59 Remove #include <utf8/unchecked.h> from Graphics.cpp
Turns out the last utfcpp function had already been removed from this
file, so the include can simply be removed.
2023-02-27 23:00:41 -08:00
Dav999-v
3ce4735d50 Add UTF8.c
This is a small library I wrote to handle UTF-8.

Usage is meant to be as simple as possible - see for example decoding
a UTF-8 string:

  const char* str = "asdf";
  uint32_t codepoint;
  while ((codepoint = UTF8_next(&str)))
  {
      // you have a codepoint congrats
  }

Or encoding a single codepoint to add it to a string:

  std::string result;
  result.append(UTF8_encode(0x1234).bytes);

There are some other functions (UTF8_total_codepoints() to get the
total number of codepoints in a string, UTF8_backspace() to get the
length of a string after backspacing one character, and
UTF8_peek_next() as a slightly less fancy version of UTF8_next()), but
more functions could always be added if we need them.

This will allow us to replace utfcpp (utf8::unchecked) and also fix
some less-than-ideal code:

- Some places have to resort to ignoring UTF-8 (next_wrap) or using
  UCS-4→UTF-8 functions (VFormat had to use PHYSFS ones, and one other
  place has four lines of code including a std::back_inserter just for
  one character)

- The iterator stuff is kinda confusing and verbose anyway
2023-02-27 23:00:41 -08:00
Dav999-v
32e14755dd Fix centering of translated "Level Complete!" and "Game Complete!"
Operator precedence meant that `sc == 2 ? PR_2X : PR_1X | PR_CEN`
didn't work how I expected it to. So I added some parentheses.
2023-02-24 18:48:24 -08:00
Fussmatte
00279c0e04 Fix minor visual issue in int1yellow_5
Originally the changedir command was used here, making
Vitellary look left and then immediately snap back to
looking right. Now the changeai command is used instead
to make him actually look left, and then look back to
the right on his last textbox.
2023-02-24 17:54:29 -08:00
Misa
ede52ccc48 Add Jules de Sartiges to Credits.h
I noticed this name was present in CONTRIBUTORS.txt but missing in
Credits.h. Their contribution was PR #782.
2023-02-21 12:28:57 -08:00
Misa
abab6864d7 Add iliana etaoin to contributor list
PR #931 was merged, so this adds xer to CONTRIBUTORS.txt and Credits.h.
2023-02-21 12:27:50 -08:00
iliana etaoin
5d719d3e90 Add magic string to the start of the game global
The `-addresses` command-line option added in 64be99d4 helps
autosplitters on platforms where VVVVVV is not built as a
position-independent executable. macOS has made it increasingly
difficult, or impossible, to build binaries without PIE.

Adding an obvious string to search for will help tools that need to deal
with versions of VVVVVV built with PIE. The bytestring to search for is
`[vVvVvV]game`, followed by four null bytes (to avoid finding it in the
program code section). This identifies the beginning of the game object;
addresses to other objects can be figured out by relative offsets
printed by `-addresses`, since ASLR can only change where the globals
begin.

Partially fixes #928; it may still be advisable to figure out how to
explicitly disable PIE on Windows/Linux.
2023-02-21 12:24:20 -08:00
Dav999-v
086b157152 Allow multiple lines and wordwrapping in activity zone prompts
Activity zone prompts have always been limited to a single line,
because the text box had a hardcoded size. A translator requested for
the possibility to add a subtitle under music names for the jukebox,
and the easiest solution is to make it possible to translate a prompt
with multiple lines. This is possible now, and the textbox even
wordwraps automatically.

(I wouldn't really like to see translations using multiple lines for
stuff like "Press ENTER to talk to Vitellary", especially if it wraps
with one name and not with another, but if a string is too long,
wordwrapping will look better than text running out of the box.)
2023-02-20 19:43:39 -08:00
Dav999-v
a320ee3b4d Deduplicate font::print for activity zone prompts
There were two print calls, one for the transparent case, and one for
a regular textbox. The print calls were nearly the same except for the
color, and for some reason the transparent case didn't have PR_CJK_LOW
(that one is on me).
2023-02-20 19:43:39 -08:00
Dav999-v
28e9df7f47 Move line width addition in next_wrap to be after switch block
There is no overlap in side effects between this line and the switch
statement after it, but it did result in adding the width of a final
null terminator or newline to the width of the current line, which is
a waste because those widths both 1) require trying to find
non-existent characters in the font and 2) will not be used.

I found this out because I added a debug print in find_glyphinfo(), and
something was requesting lots of codepoint 0 from the font.
2023-02-20 17:00:06 -08:00
Dav999-v
d883ff6938 Add support for button glyph fallback fonts
In a button glyph font (like buttons_8x8.fontmeta) you can now specify
<type>buttons</type> to indicate that it's a button glyphs font. In a
normal font, you can specify <fallback>buttons_8x8</fallback>. This
will make it such that if a character is not found in the main font,
it will instead be looked for in buttons_8x8. If not found there
either, the main font's U+FFFD or '?' will be used as before.
2023-02-20 17:00:06 -08:00
Dav999-v
7a06b61f5d Add name->idx hashmap in FontContainer
This makes find_font_by_name() not O(n). It's not really a big deal,
because there won't be many fonts, but it'd make a function in the next
commit (finding the given fallback font for each font by name) O(n^2).
It's easy enough to add the hashmap.
2023-02-20 17:00:06 -08:00
Misa
2ac85e6929 Fix editor selection box not showing up
Whoops.

Also outlined the text for page 2 too.
2023-02-19 12:31:58 -08:00
Misa
6e6cf1bfc3 Draw text outline on editor hotkeys
This makes them stand out more.

The border around the tool has also been moved to be drawn first.
Otherwise, it would be drawn on top of the outline of the text, which
would look bad.
2023-02-19 12:12:02 -08:00
Misa
64be99d496 Add -addresses command-line argument
This prints the address of every global class to the console, and then
exits.

This is useful for autosplitters, which read memory addresses directly.
Any time a new version of the game is shipped, this makes updating the
autosplitters much easier as people don't have to find the addresses of
the global classes themselves.
2023-02-17 20:47:32 -08:00
Misa
acca4747f7 Remove x-position from setactivityposition
After discussing with Ally and Dav, we came to the agreement that this
is basically useless since the prompt will always be centered and take
up most of the horizontal space of the screen.

And the x-position was only added as an offset because at some point,
there was a missing space from the side of the "- Press ENTER to
Teleport -" prompt, and the offset was there so people could mimic the
prompt accordingly. But that was fixed at some point, so it's useless
now.
2023-02-17 20:47:32 -08:00
AllyTally
3d5ba95b96 custom textbox colors
Co-authored-by: Misa Elizabeth Kai <infoteddy@infoteddy.info>
2023-02-15 10:39:20 -08:00
AllyTally
de43005676 Fix screen shake during flip mode not flipping the screen
This fixes a regression introduced by #923 where flip mode no longer flips the screen while the screen is shaking.
2023-02-14 15:33:29 -08:00
Ally
73a80a9b4f Apply suggestions from code review
Co-authored-by: Misa Elizabeth Kai <infoteddy@infoteddy.info>
2023-02-14 14:56:27 -08:00
AllyTally
1183083355 Allow a maximum of 26 lines, with L suffix 2023-02-14 14:56:27 -08:00
Misa
299ed90493 static-qualify mount_pre_datazip
This function is used nowhere else, so it should be made static and
unable to be linked to from other files.
2023-02-14 09:44:31 -08:00
Dav999-v
4b34602eec Improve ordering of font charset loading
Even though it would be a bizarre combination, declaring no character
set (neither via <chars> nor via font.txt) meant that <special>
couldn't be used because the ASCII fallback charset would be loaded
after special ranges were processed. Now, all the methods of loading
the charset are attempted sequentially, and only afterwards, the
special ranges are loaded.
2023-02-13 23:27:00 -08:00
Dav999-v
716a241b79 Replace PR_COLORGLYPH_BRI(a) and PR_ALPHA(a) with PR_BRIGHTNESS(a)
There used to be two ways of fading in/out text in VVVVVV:
- Local code that modifies the R, G and B values of the text
- Keeping the RGB values the same and using the alpha channel

The latter approach is only used once, for [Press ENTER to return to
editor]. The former approach causes problems with colored (button)
glyphs: there's no way for the print function to tell from the RGB
values whether a color is "full Viridian-cyan" or "Viridian-cyan faded
out 50%", so I added the flag PR_COLORGLYPH_BRI(value) to tell the
print function that the color brightness is reduced to match the
brightness of colored glyphs to the brightness of the rest of the text.

However, there were already plans to make the single use of alpha
consistent with the rest of the game and the style, so PR_ALPHA(value)
could be removed, as well as the bit signifying whether the brightness
or alpha value is used. For the editor text, I simply copied the "Press
{button} to teleport" behavior of hiding the text completely if it
becomes darker than 100/255.

Another simplification is to make the print function handle not just
the brightness of the color glyphs while local code handled the
brightness of the normal text color, but to make the print function
handle both. That way, the callsite can simply pass in the full colors
and the brightness flag, and the flag name can be made a lot simpler as
well: PR_BRIGHTNESS(value).
2023-02-13 23:27:00 -08:00
Dav999-v
d1f6c1adf2 Replace "by" for level authors with happy face
"by {author}" is a string that will cause a lot of localization-related
problems, which then become much worse when different languages and
levels can also need different fonts:

- If the author name is set to something in English instead of a name,
  then it'll come out a bit weird if your VVVVVV is set to a different
  language: "de various people", "por various people", etc. It's the
  same problem with Discord bots completing "playing" or "watching" in
  their statuses.

- Translators can't always fit "by" in two letters, and level creators
  have understandably always assumed, and will continue to assume, that
  "by" is two letters. So if you have your VVVVVV set to a language that
  translates "by" as something long, then:
  | by Various People and Others |
  ...may suddenly show up as something like:
  |thorer Various People and Othe|

- "by" and author may need mutually incompatible fonts. For example, a
  Japanese level in a Korean VVVVVV needs to be displayed with "by" in
  Korean characters and the author name with Japanese characters, which
  would need some very special code since languages may want to add
  text both before and after the name.

- It's very possible that some languages can't translate "by" without
  knowing the gender of the name, and I know some languages even
  inflect names in really interesting ways (adding and even replacing
  letters in first names, surnames, and anything in between, depending
  on gender and what else is in the sentence).

So to solve all of this, the "by" is now replaced by a 10x10 face from
sprites.png, like a :viridian: emote. See it as a kind of avatar next
to a username, to clarify and assert that this line is for the author's
name. It should be a fairly obvious/recognizable icon, it fixes all the
above problems, and it's a bonus that we now have more happy faces in
VVVVVV.
2023-02-13 23:27:00 -08:00
Dav999-v
ed7379c41b Position CJK room name correctly in editor 2023-02-13 23:27:00 -08:00
Dav999-v
17d3c756c7 Write max_local to language files during sync
If your language has a bigger font, the max attribute isn't really
helpful to you as a translator, so the sync feature adds a special
max_local attribute which is accurate to the font size. This was
already documented in advance.

If used, we now also write an attribute in the root tag of strings.xml
and strings_plural.xml, that looks like max_local_for="12x12". I
decided to add this attribute after finding out the Excel macros would
be really hard to change to only show a max_local column if it is ever
used (it'd need to look ahead through the strings until it finds a
string with a max, or remove the column if no string has used it), but
it's also a convenience for translators.
2023-02-13 23:27:00 -08:00
Dav999-v
11b372c741 Harden next_wrap against getting stuck on a single character
If, somehow, a single character is wider than the limit, next_wrap
would get you stuck in an infinite loop by refusing to update the start
index and giving a line length of 0. Now, it just gives you a line with
that single character.

I also made some small readability improvements: I renamed next_wrap_s
to next_wrap_buf, and added comments at the top of both functions
explaining what they do.
2023-02-13 23:27:00 -08:00
Dav999-v
9747843c18 Add menu for selecting the level font
By default, when you open the level editor to start a new level, the
level font will now match your VVVVVV language; so if you're, say,
Japanese, then you can make Japanese levels from the get-go. If you
want to make levels for a different target audience, you can change the
font via a new menu (map settings > change description > change font).
The game will remember this choice and it will become the new initial
level font.
2023-02-13 23:27:00 -08:00
Dav999-v
b030ce568f Make main game content use interface font instead of 8x8 font
If a custom level doesn't specify a font, it should be the 8x8 font.
But the main game can't specify a font, it's just the interface font
because that's for the language that the game is in.
2023-02-13 23:27:00 -08:00
Dav999-v
25feb9dbb5 Make wordwrapping functions take font arguments
They need to know how wide the text is going to be in a particular
font, so font::string_wordwrap and font::string_wordwrap_balanced now
take a flags argument like all the printing and dimensions-getting
functions. next_wrap and next_wrap_s take a Font* now, they're internal
to Font.cpp so they can take a Font and avoid double flag-parsing. But
if any non-Font.cpp code needs next_wrap/next_wrap_s in the future, I'd
just make a public wrapper that takes a uint32_t flags and passes the
Font* to the internal functions.
2023-02-13 23:27:00 -08:00
Dav999-v
0eaceed0a2 Completely remove Graphics::PrintWrap
All print calls are font:: ones now and all the old Graphics:: print
functions have been removed, the migration is complete!
2023-02-13 23:27:00 -08:00
Dav999-v
0e30087f3b Fix indentation style of case Menu::levellist in menurender
This is one of the few places still using 2-space indentation instead
of 4 spaces, and it makes it very annoying to work with when your tab
key inserts four spaces - so I could either just mimic it for the time
being, or I could just fix it while I was at it.
2023-02-13 23:27:00 -08:00
Dav999-v
7ecff42e0e Completely remove Graphics::Print, make many CJK positioning fixes
Only Graphics::PrintWrap is left of the old print functions!
2023-02-13 23:27:00 -08:00
Dav999-v
cc6b00a711 Add setfont scripting command
The <font> in the level file is basically the starting font, but it can
be changed at any time via scripting.
2023-02-13 23:27:00 -08:00
Dav999-v
7db0e73109 Allow levels to select a font via XML, show correct font in levels list
There still needs to be a menu for selecting a font, but it can now be
loaded and saved correctly in the XML!
2023-02-13 23:27:00 -08:00
Dav999-v
8d5e3b1a8a Improve level metadata display and font handling
- If the level font is higher than 10 pixels, the third description
  line (Desc3) is disabled and unavailable. CJK languages require less
  characters to convey the same message (140 characters caused people
  to cram tweets in all languages except CJK) and this gives us enough
  room in the levels list without having to cram the metadata even more
  than it already was or showing less levels per page.
- The "Untitled Level" and "by Unknown" now selectively show up in the
  interface font instead of the level font.
2023-02-13 23:27:00 -08:00
Dav999-v
653eee505b Clean up Font.h, move structs into Font.cpp
None of the structs in the new font system ended up being "publicly"
accessible, they were all treated as implementation details for
Font.cpp to use, so these structs are now fully defined in Font.cpp
only.
2023-02-13 23:27:00 -08:00
Dav999-v
d2461c90ce Completely remove Graphics::bigprint
The last two deprecated functions are:
- Graphics::Print
- Graphics::PrintWrap

These are used a lot, but they're relatively easy to replace, since the
only flag I probably have to immediately worry about is PR_CEN. I do
often need to add PR_FONT_* flags but I don't need to add any
PR_2X/PR_3X/PR_4X anymore.
2023-02-13 23:27:00 -08:00
Dav999-v
ddaabb3efe Completely remove Graphics::bprint
Only three deprecated functions remain:
- Graphics::Print
- Graphics::PrintWrap
- Graphics::bigprint

I also fixed multiline transparent textboxes having their outlines
overlap the text itself, and fixed textboxclass::padtowidth assuming
glyph widths of 8 (it made the hints at the start of intermission 1
run offscreen for example)
2023-02-13 23:27:00 -08:00
Dav999-v
d784f7f61a Completely remove Graphics::PrintAlpha and Graphics::bprintalpha
Only four deprecated functions remain:
- Graphics::Print
- Graphics::PrintWrap
- Graphics::bigprint
- Graphics::bprint

Graphics::bprint is the least-used one of them, and after that, the
other functions are used a LOT, but it'll be a lot faster to go through
them, since I have less and less flags to worry about. I'll probably
start using Vim macros again like I did for loc::gettext()ing strings,
or maybe I'll automate this completely.
2023-02-13 23:27:00 -08:00
Dav999-v
9749858365 Completely remove Graphics::bigbprint, bigrprint and bigbrprint
I migrated all of them to font::print, so they can now be removed.
Six deprecated print functions left! (Of which some are used a whole
lot, it's simpler if the lesser-used ones are gone first.)
2023-02-13 23:27:00 -08:00
Dav999-v
c82e1f2902 Use PR_RIGHT for interim version info in main menu
This used some constants counting numbers of characters
(LEN_INTERIM_COMMIT and LEN_BRANCH_NAME) and even an SDL_arraysize,
all multiplied by 8, to get the length of the displayed text.
Now it just uses the new PR_RIGHT flag of font::print.

I did also force the 8x8 font for all the interim information, since
the date kinda overlapped with the menu options... And all of these
lines only show up in interim versions anyway, except for the version
number - which is left in the interface font for consistency with the
rest of the menu in non-interim versions. The inconsistency in interim
versions doesn't really matter all that much I think, it's just some
technical/debug info.
2023-02-13 23:27:00 -08:00
Dav999-v
da6be09993 Completely remove Graphics::len
I migrated all graphics.len calls over to font::len (and also migrated
prints mainly surrounding those graphics.len's) so the old len function
is now completely removed.
2023-02-13 23:27:00 -08:00
Dav999-v
a706fb249a Migrate more prints and graphics.len calls to font::
I especially focused on graphics.len and the print calls around them,
because graphics.len calls appear a bit less often, might be overlooked
when migrating print calls (thus possibly using different fonts by
accident) and are often used for some kind of right-alignment or
centering which can be changed into PR_RIGHT or PR_CEN with a different
X anyway.

Notably, I also added a new function to generate these kinds of
sliders: ....[]............

Different languages means that the slider for analogue stick
sensitivity needs to be longer to fit possibly long words for
Low/Medium/High, and then different font sizes means that the longer
slider won't fit onscreen in a language that needs a 12-wide font. So
slider_get() can take a "target width", which dynamically changes the
number of characters depending on the width of them in the interface
font.

I kinda forgot that I could force the 8x8 font instead of adapting the
characters in the slider to the font, and other ideas (like using
different characters or a more graphical progress bar) have been
brought up on Discord, so this might all change again sooner or later.
2023-02-13 23:27:00 -08:00
Dav999-v
7c55ea7832 Fix pause screen font on language screen with other language selected
If you for example have your VVVVVV set to English, have the option for
Chinese selected, and then the window loses focus, the English pause
screen would show up in the Chinese font. This is now fixed.
2023-02-13 23:27:00 -08:00
Dav999-v
df4e351b30 Use languages' fonts for options on language screen 2023-02-13 23:27:00 -08:00
Dav999-v
5dad6b38be Add language-specific font configuration
meta.xml can now have a <font> tag, which gives the name of the font
that the language needs. This will directly control the interface font
when the language is active, and will soon also control the font used
for each option on the language screen.
2023-02-13 23:27:00 -08:00
Dav999-v
dadb7f2623 Complete font::print_wrap flag handling
Also added some borders to more of the text in room name translator
mode, fixed a positioning issue if the interface font is not 8x8, and
migrated the trophy texts to font::print_wrap (including
PR_COLORGLYPH_BRI that still needed to be done)
2023-02-13 23:27:00 -08:00
Dav999-v
689d6e3e97 Print activity zone text in correct font, remove Graphics::drawtextbox
Activity zones need to be in the interface font if the message is from
the system (like Press ENTER to activate terminal, which may be in a
different language) and in the level font if it's a customized message
(setactivitytext).

Graphics::drawtextbox was counting the textbox width and height in
8x8 characters, even including the borders as characters, so it'd need
to be told what the font for the textbox is, and then probably only the
height needs to be adapted to the font and not the width because that's
adapted to the screen width... So just call Graphics::drawpixeltextbox
directly instead. It was already weird enough how actual cutscene
textboxes called Graphics::drawtextbox with x/8, y/8 before the
previous commit, (when you already have the pixel width and height!)
only to have that be a wrapper for drawpixeltextbox by doing x*8, y*8.
2023-02-13 23:27:00 -08:00
Dav999-v
48a4e19635 Migrate more prints to font::, determine font for most textboxes
Some textboxes need to be in the level font (like room names, cutscene
dialogue, etc - even in the main game), and some need to be in the
interface font (like when you collect a shiny trinket or crewmate). So
most of these textboxes now have graphics.textboxprintflags(font_flag)
as appropriate.

RoomnameTranslator.cpp is now also migrated to the new print system -
in room name translator mode, the room name is now displayed in the 8x8
font if it's untranslated and the level font if it is.
2023-02-13 23:27:00 -08:00
Dav999-v
6ca83114bc Start using level-specific font where needed, make CJK tweaks
Level text such as room names, text box content, and the contents of
the script editor need to be displayed in the level-specific font, and
tweaked to look right. This involves displaying less lines in the
script editor, making text boxes bigger, displaying some text higher
and some text lower. This is still unfinished, but it's the real start
of a migration to font::print functions!
2023-02-13 23:27:00 -08:00
Dav999-v
29a3789dec Add some more preparation for multi-font support and proper unloading
find_font_by_name() just finds the index of a given font name. This
index is supposed to be stored and reused, because the font (for a
language/level) won't be changed very often. So this function would
only run when getting the language metadata, when loading a level, etc.
2023-02-13 23:27:00 -08:00
Dav999-v
83d645c8e3 Add font containers for global and custom fonts
All global fonts and all custom fonts in a level are now loaded, and
added to their respective "vectors". The selected font is still always
as the global font.png, and the custom level font also isn't selected
yet, but it's now easier to implement that.

Also, I added FILESYSTEM_enumerateAssets, which #902 already has but I
needed it now. I also rewrote it to not use std::vector<std::string>.
That was my idea, it's also how FILESYSTEM_getLanguageCodes worked,
so for symmetry, that function is getting changed as well.
2023-02-13 23:27:00 -08:00
Dav999-v
22dcc29d45 Handle more flags in print and len functions
The font::len function now handles the printing scale, so it can
immediately return the scaled length instead of having the caller
calculate it. The print function now handles CJK low/high flags and
vertically centers CJK text by default (instead of letting it stick
out on the bottom).
2023-02-13 23:27:00 -08:00
Dav999-v
159c70dade Move wordwrapping functions and len to Font.cpp/font:: namespace
The following functions were moved directly:
- next_wrap
- next_wrap_s
- string_wordwrap
- string_wordwrap_balanced
- string_unwordwrap

These ones will probably still need get a flags argument, except for
string_unwordwrap (since they need to know what font we're talking
about.

The implementation of graphics.len has also been moved to Font.cpp,
but graphics.len still exists for now and is deprecated.
2023-02-13 23:27:00 -08:00
Dav999-v
1d8494db8d Add initial version of font::print_wrap
graphics.PrintWrap is now also deprecated. An advantage of the new
version (with flags) is that it'll be possible to do things like put
a border around wrapped text, wrap text at larger scales, etc, but
these things don't work perfectly yet.

This commit also has some other fixes, like the default advance of
6 pixels for characters 0x00-0x1F in 8x8 fonts.
2023-02-13 23:27:00 -08:00
Dav999-v
0475539075 Implement first font::print function, fix most fading of colored glyphs
There has always been a mess of different print functions that all had
slightly different specifics and called each other:

Print(x, y, text, r, g, b, cen)
    nothing special here, just does what the arguments say

PrintAlpha(x, y, text, r, g, b, a, cen)
    just Print but with an alpha argument

PrintWrap(x, y, text, r, g, b, cen, linespacing, maxwidth)
    added for wordwrapping, heavily used now

bprint(x, y, text, r, g, b, cen)
    prints an outline, then just PrintAlpha

bprintalpha(x, y, text, r, g, b, a, cen)
    just bprint but with an alpha argument

bigprint(x, y, text, r, g, b, cen, sc)
    nothing special here, just does what the arguments say

bigbprint(x, y, text, r, g, b, cen, sc)
    prints an outline, then just bigprint

bigrprint(x, y, text, r, g, b, cen, sc)
    right-aligns text, unless cen is given in which case it just
    centers text like other functions already do?

bigbrprint(x, y, text, r, g, b, cen, sc)
    prints an outline, then just bigrprint

We need even more specifics with the new font system: we need to be
able to specify whether CJK characters should be vertically centered or
stick out on the top/bottom, and we sometimes need to pass in
brightness variables for colored glyphs. And text printing functions
now fit better in Font.cpp anyway. So there's now a big overhaul of
print functions: all these functions will be replaced by font::print
and font::print_wrap (the former of which now exists). These take flags
as their first argument, which can be 0 for a basic left-aligned print,
PR_CEN for centered text (set X to -1!!!) PR_BOR for a border (instead
of functions like bprint and bigbprint), PR_2X, PR_3X etc for scaling,
and these can be combined with |.

Some text, for example [Press ESC to return to editor], fades in/out
using the alpha value, which is passed to the print function. In some
other places (like Press ENTER to teleport, textboxes, trophy text...)
text can fade in or out by direct changes to the RGB values. This means
regular color-adjusted white text can change color, but colored button
glyphs can't, since there's no way to know in the print system what the
maximum RGB values of a specific textbox are supposed to be, so the
only thing it can do is draw the button glyphs at full brightness,
which looks bad. Therefore, you can now also pass in the brightness
value via the flags, with PR_COLORGLYPH_BRI(255).
2023-02-13 23:27:00 -08:00
Dav999-v
9879fb2809 Draw outlines for colored characters correctly
If we try to draw a colored character, and the color is fully black,
it means we're drawing the outline.
2023-02-13 23:27:00 -08:00
Dav999-v
794f081530 Start rewrite of font system
This is still a work in progress, but the existing font system has been
removed and replaced by a new one, in Font.cpp.

Design goals of the new font system include supporting colored button
glyphs, different fonts for different languages, and larger fonts than
8x8 for Chinese, Japanese and Korean, while being able to support their
30000+ characters without hiccups, slowdowns or high memory usage. And
to have more flexibility with fonts in general. Plus, Graphics.cpp was
long enough as-is, so it's good to have a dedicated file for font
storage.

The old font system worked with a std::vector<SDL_Surface*> to store
8x8 surfaces for each character, and a std::map<int,int> to store
mappings between codepoints and vector indexes.

The new system has a per-font collection of pages for every block of
0x1000 (4096) codepoints, that may be allocated as needed. A glyph on
a page contains the index of the glyph in the image (giving its
coordinates), the advance (how much the cursor should advance, so the
width of that glyph) and some flags which would be at least whether the
glyph exists and whether it is colored.

Most of the *new* features aren't implemented yet; it's currently
hardcoded to the regular 8x8 font.png, but it should be functionally
equivalent to the previous behavior. The only thing that doesn't really
work yet is level-specific font.png, but that'll be supported again
soon enough.

This commit also adds fontmeta (xml) support.

Since the fonts folder is mounted at graphics/, there are two main
options for recognizing non-font.png fonts: the font files have to be
prefixed with font (or font_) or some special file extension is
involved to signal what files are fonts. I always had a font.xml in
mind (so font_cn.xml, font_ja.xml, etc) but if there's ever gonna be
a need for further xml files inside the graphics folder, we have a
problem. So I named them .fontmeta instead.

A .fontmeta file looks somewhat like this:

<?xml version="1.0" encoding="UTF-8"?>
<font_metadata>
    <width>12</width>
    <height>12</height>
    <white_teeth>1</white_teeth>
    <chars>
        <range start="0x20" end="0x7E"/>
        <range start="0x80" end="0x80"/>
        <range start="0xA0" end="0xDF"/>
        <range start="0x250" end="0x2A8"/>
        <range start="0x2AD" end="0x2AD"/>
        <range start="0x2C7" end="0x2C7"/>
        <range start="0x2C9" end="0x2CB"/>
        ...
    </chars>
    <special>
        <range start="0x00" end="0x1F" advance="6"/>
        <range start="0x61" end="0x66" color="1"/>
        <range start="0x63" end="0x63" color="0"/>
    </special>
</font_metadata>

The <chars> tag can be used to specify characters instead of in a .txt.
The original idea was to just always use the existing .txt system for
specifying the font charset, and only use the XML for the other stuff
that the .txt doesn't cover. However, it's probably better to keep it
simple if possible - having to only have a .png and a .fontmeta seems
simpler than having the data spread out over three files. And a major
advantage: Chinese fonts can have about 30000 characters! It's more
efficient to be able to have a tag saying "now there's 20902 characters
starting at U+4E00" than to include them all in a text file and having
to UTF-8 decode every single one of them.

If a font.txt exists, it takes priority over the <chars> tag, and in
that case, there's no reason to include the <chars> tag in the XML.
But font.txt has to be in the same directory as font.png, otherwise it
is rejected. Same for font.fontmeta. If neither font.txt nor <chars>
exist, then the font is seen as a 2.2-and-below-style ASCII font.

In <special>: advance is the number of pixels the cursor advances after
drawing the character (so the width of the character, without affecting
the grid in the source image), color is whether the character should
have its original colors retained when printed (for button glyphs).

As for <white_teeth>:

The renderer PR has replaced draw-time whitening of sprites/etc
(using BlitSurfaceColoured) by load-time whitening of entire images
(using LoadImage with TEX_WHITE as an argument).

This means we have a problem: fonts have always had their glyphs
whitened at printing time, and since I'm adding support for colored
button glyphs, I changed it so glyphs would sometimes not be whitened.
But if we can't whiten at print time, then we'd need to whiten at load
time, and if we whiten the entire font, any colored glyphs will get
destroyed too. If you whiten the image selectively, well, we need more
code to target specific squares in the image, and it's kind of a waste
when you need to whiten 30000 12x12 Chinese characters when you're only
going to need a handful, but you don't know which ones.

The solution: Whitening fonts is useless if all the non-colored glyphs
are already white, so we don't need to do it anyway! However, any
existing fonts that have non-white glyphs (and I know of at least one
level like that) will still need to be whitened. So there is now a
font property <white_teeth> that can be specified in the fontmeta,
which indicates that the font is already pre-whitened. If not
specified, traditional whitening behavior will be used, and the font
cannot use colored glyphs.
2023-02-13 23:27:00 -08:00
Misa
b29f3e2fae Silence various warnings in builds removing content
The MAKEANDPLAY, NO_CUSTOM_LEVELS, and NO_EDITOR defines remove content
or features. However, they then raise several warnings because of some
cases, functions, or variables that end up not being used.

This silences them by using the UNUSED macro, or by adding a default
catch-all case if the define is defined (so unhandled cases will still
raise warnings in a build that doesn't have these defines).
2023-02-04 00:14:04 -08:00
Misa
113fbb0fdb Add build type to -version
This adds the build type in brackets in `-version` output after e.g.
"VVVVVV v2.4". The build type is MAKEANDPLAY, NO_CUSTOM_LEVELS, or
NO_EDITOR (which are not necessarily mutually exclusive).

This is appended on to the end of the first line so as to not break
Ved's existing `-version` check which only checks if the beginning of
STDOUT is "VVVVVV" followed by any version number.
2023-02-02 13:10:25 -08:00
Misa
6665f4f8f6 Prioritize loading processed script names
This makes it so that whenever the game loads a script as directed by a
script command, it will first try to load the script from the processed
argument, and if that fails only then will it try to load the script
from the raw argument.

This fixes a regression reported by Dav999 in the custom level "Vungeon"
created by Dynaboom, where a script `ifflag`s to `aselectP1.1` even
though the actual script name is `aselectp1.1`. In 2.3, it would
lowercase `aselectP1.1` and load the script properly, but previous to
this commit it would try to load the script with a capital name and then
fail.
2023-01-31 20:09:44 -08:00
Misa
fbe613ce5c Abort and print error if window/renderer cannot be created
This aborts and prints the error from SDL_GetError() if
SDL_CreateWindow() or SDL_CreateRenderer() fails.

We abort because there's not much point in continuing if the window or
renderer can't be created. There might be a use case for running the
game in headless mode, but let's code that in explicitly if we ever want
it.
2023-01-28 23:44:07 -08:00
Misa
2525017990 Set minimum window size (to 320 x 240)
This sets the minimum window size (to 320 x 240), so that the window
cannot be resized to lower than that.

This is because there's no utility in having a game window smaller than
that, and it provides a bonus convenience of being able to resize the
game to exactly 320x240 without needing to be exactly precise about it.

This idea was suggested by Dav999.
2023-01-28 23:37:24 -08:00
Misa
fbc9b3ddd7 Use SDL_Point instead of rolling our own point struct
The `point` struct was a relic of ActionScript and was added because of
the Flash 'point' object. However, it seems like Simon Roth didn't
realize that SDL has its own point struct.

With this, `Maths.h` can be un-included from a couple headers, which
exposes the fact that `preloader.cpp` was relying on `Maths.h` being
transitively included from `Graphics.h`.
2023-01-28 23:32:14 -08:00
Misa
c7098f84e5 Fix alphabetical ordering of includes in preloader.cpp
Dav999 added `#include "Localization.h"` before `#include "KeyPoll.h"`,
when it should go after instead, because the letter L comes after the
letter K in the English alphabet.
2023-01-28 23:29:04 -08:00
AllyTally
d9859d4a98 Fix screenshake not clearing the gameplay cache 2023-01-28 17:48:15 -08:00
AllyTally
19b2a317f1 Move from surfaces to the SDL render system
Ever since VVVVVV was initially ported to C++ in 2.0, it has used surfaces from SDL. The downside is, that's all software rendering. This commit moves most things off of surfaces, and all into GPU, by using textures and SDL_Renderer.

Pixel-perfect collision has been kept by keeping a copy of sprites as surfaces. There's plans for pixel-perfect collision to use masks instead of reading pixel data directly, but that's out of scope for this commit.

- `graphics.reloadresources()` is now called later in `main`, because textures cannot be created without a renderer.

- This commit also removes a bunch of surface functions which are no longer needed.

- This also recaches target textures in certain places for d3d9.

- graphics.images was converted to a fixed-size array.

- fillbox and fillboxabs use SDL_RenderDrawRect instead of drawing an outline using four filled rectangles

- Update my name in the credits
2023-01-28 14:36:28 -08:00
AllyTally
556e3a110a Fix small bug with map being off in custom levels
The pixel border around the map fits to map size normally. However, when
the map is off, it's always the dimensions of the full size map, and the
border didn't reflect that, so if the custom minimap was off, and the
map wasn't the full size, it wouldn't fit correctly.

This bug was introduced in PR #898.
2023-01-26 12:23:23 -08:00
Misa
172e3a8985 Add branch name to window title in brackets
The branch name will be added to the window title if it is an interim
version, e.g. "VVVVVV [master]".

This makes it easier for developers to tell at a glance which build of
the game they're running.
2023-01-16 12:59:48 -08:00
Misa
19a83853b8 Default width and height settings to 640x480
While the window is initialized with 640x480, the screen settings
defaulted to 320x240, which is a tiny window. The screen settings take
priority over the initialized window, so people with no previous
settings file will get 320x240. This makes it so they get 640x480
instead.

The window is still initialized to 640x480 (constants used for clarity)
just in case there's some weirdness if it's initialized to a potentially
odd resolution from the user's settings file.
2023-01-16 12:45:40 -08:00
Misa
d2b6fb2d06 Add branch name to interim version information
This is useful for developers who may have multiple builds of the game
from various different branches and may easily forget which build of the
game is what.

This shows up in the bottom-right corner of the title screen and also
with the `-version` command-line option, and in the status message
printed when building the game.
2023-01-07 19:18:28 -08:00