Commit Graph
92 Commits
Author SHA1 Message Date
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 4675238fa8 Switch font.txt over to font.fontmeta
Since there's now a new XML-based font metadata file format to obsolete
the .txt file with all the glyphs, this commit switches the built-in
font to that new format.
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
Dav999-v 2f770e9b5a Use setstate(n)/incstate()/setstatedelay(n) in localization changes
This mirrors PR #917.
2022-12-31 20:04:56 -08:00
Dav999-v 2b84384606 Replace all localization SDL_free with VVV_free
This mirrors a926ce9851 upstream, which
replaces all other SDL_free calls.
2022-12-31 20:04:56 -08:00
Dav999-v 7a52dc9586 Update Esperanto and Catalan translations 2022-12-31 20:04:56 -08:00
Dav999-v 3937a12a85 Add cutscene test menu
This allows translators to test all text boxes in the scripts. It
doesn't run the scripts themselves - it only shows the basic appearance
of each text box individually, so context may be lost but it's good to
have a way to see any text boxes that might otherwise not be easily
seen because they require specific circumstances to appear.
2022-12-31 20:04:56 -08:00
Dav999-v 0ed7717dd5 Add Catalan translation by Eduard Ereza Martínez
As Terry said on Discord, this translation is completed now, so it
sounds like it's ready to officially add it to the language folder!
2022-12-31 20:04:56 -08:00
Dav999-v 5eb20aa467 Make some minor changes in the Dutch translation
Did another complete proofread of all the non-roomnames (hadn't looked
through *everything* in a while), and it's just three little things
that I felt would be important enough to tweak.
2022-12-31 20:04:56 -08:00
Dav999-v 7aec2c2242 Remove "COPY TILES" strings
This feature was never implemented, so these strings are making
translators wonder where to find them so they can be tested.
2022-12-31 20:04:56 -08:00
Dav999-v 6a1ddad8f8 Add cases for intermission replay options, button fillers in editor
The strings "Vitellary"/"Vermilion"/"Verdigris"/"Victoria" now have two
cases to support changing them for the intermission replay menu options
(like "with Vitellary").

Also, the string "< and > keys change tool" is now "{button1} and
{button2} keys change tool", so it can be changed dynamically without
having to retranslate the string.
2022-12-31 20:04:56 -08:00
Dav999-v e441d0d312 Complete the Dutch room name translations
Overall, I'm more proud of the Dutch room names than I could've hoped
for.
2022-12-31 20:04:56 -08:00
Dav999-v 489963fdc6 Add line about string cases to README-translators.txt 2022-12-31 20:04:56 -08:00
Dav999-v 795bdf886b Add support for string cases in strings.xml (gendered Rescued/Missing)
I wanted to not complicate the system with different string cases (like
cgettext) if possible, and I have been able to keep the main strings a
simple English=Translation mapping thus far, but apparently strings
like "Rescued!" (which are one string in English), have to be
translated for the correct gender in some languages. So this was a good
time to add support for string cases anyway.

It's a number that can be given to a string to specify the specific
case it's used, to disambiguate identical English keys. In the case of
"Rescued!" and "Missing...", male versions of the string are case 1,
female versions are case 2, and Viridian being missing is case 3. Of
course, if a language doesn't need to use different variants, it can
simply fill in the same string for the different cases.

If any other string needs to switch to different cases: distinguish
them in the English strings.xml with the case="N" attribute (N=1 and
higher), sync language files from the translator menu (existing
translations for the uncased string will simply be copied to all cases)
and change loc::gettext("...") to loc::gettext_case("...", 1),
loc::gettext_case("...", 2), etc.
2022-12-31 20:04:56 -08:00
Dav999-v d147206c54 Split localization README.txt in -translators and -programmers versions
With a single README.txt for both translators and maintainers, both
have to read through info that's not relevant for them, because
translators don't need to worry about the specifics of adding new
English strings and recompiling the game, and programmers don't need to
worry about the specifics of how to translate things. Now it's split
into README-translators.txt and README-programmers.txt.
2022-12-31 20:04:56 -08:00
Dav999-v baf1e6d57f Update font to latest version
This includes the Catalan · and some other Latin-1 supplement
characters.
2022-12-31 20:04:56 -08:00
Dav999-v 88c8ad5a57 Add per-area untranslated roomname counters
This makes it easy from the "explore game" menu to see which levels
still have untranslated room names and how many.
2022-12-31 20:04:56 -08:00
Dav999-v 80b9bcf0dd Add level exploring menu for translators
I would, of course, recommend translators to translate the roomnames
while playing the full game (optionally in invincibility) so they can
immediately get all the context and maybe the most inspiration. And if
you want to go back into a specific level, then there's always the time
trials and intermission replays which will give you full coverage of
all the room names.

However, the time trials weren't really made for room name translation.
They have some annoying features like the instant restart when you
press ENTER at the wrong time, they remove context clues like
teleporters and companions, but the worst problem is that the last room
in a level is often completely untranslatable inside the time trials
because you immediately get sent to the results screen...

So, I added a new menu in the translator options, "explore game", which
gives you access to all the time trials and the two intermissions, from
the same menu. All these time trials (which they're still based off of,
under the hood) are stripped of the annoying features that come with
time trials. These are the changes I made to time trial behavior in
translator exploring mode:

- No 3-2-1-Go! countdown
- No on-screen time/death/shiny/par
- ENTER doesn't restart, and the map menu works. The entire map is also
  revealed.
- Prize for the Reckless is in its normal form
- The teleporters in Entanglement Generator, Wheeler's Wormhole and
  Level Complete are restored as context for room names (actually, we
  should probably restore them in time trials anyway? Their "press to
  teleport" prompt is already blocked out in time trials and they do
  nothing other than being a checkpoint. I guess the reason they were
  removed was to stop people from opening the teleporter menu when that
  was not specifically blocked out in time trials yet.)
- The companions are there at the end of levels, and behave like in no
  death mode (become happy and follow you to the teleporter). Also for
  context.
- At the end of each level, you're not suddenly sent to the menu, but
  you can use the teleporter at your leisure just like in the
  intermission replays. In the Final Level, you do get sent to the menu
  automatically, but after a longer delay.

I made another mark on VVVVVV: don't be startled, I added gamestates.
I wanted all teleporters at the end of levels to behave like the ones
at the end of the intermission replays, and all handling for
teleporting with specific companions is already done in gamestates, so
rather than adding conditional blocks across 5 or so different
gamestates, it made more sense to make a single gamestate for
"teleporting in translator exploring mode" (3090). I also added an
alternative to having to use gamestate 3500 or 82 for the end of the
final level: 3091-3092.

One other thing I want to add to the "explore game" menu: a per-level
count of how many room names are left to translate. That shouldn't be
too difficult, and I'm planning that for the next commit.
2022-12-31 20:04:56 -08:00
Dav999-v 34cb42a19f Add Ctrl+X for roomname translator mode
This is a single block of code so it was easy to split from the
foundation commit.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v df76145314 Make some hardcoded room names (and some special ones) translatable
This involves loc::gettext_roomname and loc::gettext_roomname_special.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v b548783df2 preloader.cpp: make loading screen translatable
This mainly adds loc::gettext calls and replaces SDL_snprintf by
VFormat for the percentage.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 56f812a7e9 main.cpp: make pause screen translatable
This mainly adds loc::gettext calls.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 93a3c40c39 UtilityClass.cpp: make time formats and numbers translatable
This replaces SDL_snprintf by VFormat for the time strings, and makes
number_words get translated numbers.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 70a6cf407c Script.cpp: make whole file translatable (except for a Welcome Aboard)
This mainly adds loc::gettext calls.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 3203f99938 Render.cpp: make remaining strings translatable
This mainly adds loc::gettext calls.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 949f0fa2e2 Render.cpp: make maprender translatable
This mainly adds loc::gettext calls.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 52e847d5c1 Render.cpp: make titlerender and gamecompleterender translatable
This mainly adds loc::gettext calls.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 17c11f7e6c Render.cpp: make gamerender translatable
This mainly adds loc::gettext calls.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 0c9b54f819 Render.cpp: make menurender translatable
This mainly adds loc::gettext calls for all the menu titles and
explanations. It also redesigns the time trial screen.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 45b564b4fb Graphics.cpp: make whole file translatable
This mainly adds loc::gettext calls.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v e90cc86a3c Game.cpp: make remaining strings translatable except gethardestroom
This mainly adds loc::gettext calls.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v e96a0344e7 Game.cpp: Make Game::updatestate translatable
This mainly adds loc::gettext calls.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 713fc00034 Game.cpp: make menu options (in Game::createmenu) translatable
This mainly adds loc::gettext calls for menu option labels.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 1e45e263f5 FileSystemUtils.cpp: make translatable
setLevelDirError was changed from snprintf-style to VFormat, but it's
only used in that file so...

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v c142b3bb3b Entity.cpp: make all activity prompts translatable
This adds loc::gettext for all "Press {button} to explode" and friends,
and also changes the interact_prompt function in Render.cpp to expect
{button} instead of %s.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 2210863e73 Editor.cpp: make remaining strings translatable
The affected functions are:
- editormenuactionpress
- editorinput
- editorclass::switch_tileset
- editorclass::switch_tilecol
- editorclass::switch_enemy
- editorclass::switch_warpdir

This mainly adds loc::gettext calls.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 17f246912d Editor.cpp: make editorrender translatable
This mainly adds loc::gettext calls.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v d09cab2a38 Editor.cpp: make editormenurender translatable
This mainly adds loc::gettext calls.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 1d46e17286 Add textcase(n) commands to scripts
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 1ead8885ba Use loc::toupper_ch instead of SDL_toupper in VFormat
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 7ffbf0b115 Use UTF-8 characters for names in credits instead of {|}~
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v ec611ffa9d Add localization "foundation" (many code changes)
This commit adds most of the code changes necessary for making the game
translatable, but does not yet "unhardcode" nearly all of the strings
(except in a few cases where it was hard to separate added
loc::gettexts from foundational code changes, or all the localization-
related menus which were also added by this commit.)

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 35d92e8e64 Add RoomnameTranslator.cpp/h (not compiled yet)
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 97d905e8bf Add LocalizationMaint.cpp/h (not compiled yet)
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 8e33815c97 Add LocalizationStorage.cpp/h (not compiled yet)
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 98742ed852 Add Localization.cpp/h (not compiled yet)
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 72f030fd8e Support underscore (_) in VFormat arg name
This is needed for the limits check in the translator menu.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v f8fd51fc95 Indicate what special roomnames are in the levels
This just adds booleans roomname_special to the level classes in
preparation for the localization system to use them.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 0ed2cb1bc0 Add Textbook
A relevant paragraph copied from the original commit history:

The idea is that we store all strings somewhere managed, and then the
hashmap only needs pointers to those strings. For storing strings, I
created a `Textbook` structure, which consists of one or more 50 KB
"pages" (allocated as needed) on which you can simply write strings in
both languages back-to-back with `textbook_store(textbook, text)` and
get pointers to each of them. (I was originally going to just use one
big buffer and realloc to double the size when filled up, but then the
hashmap would be full of dangling pointers...) When needed, like when
switching to a different language, an entire textbook can be freed at
once.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v b148950367 Add C-HashMap to CMakeLists.txt
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 19275326ce Add c-hashmap submodule (not compiled yet)
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 7cb6176898 Add Space Station font
This has a lot of characters that different languages need.

This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 679619e475 Add (2020) Spanish language files
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 77ac19e4f6 Add Esperanto language files
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 684ccb9ccd Add Dutch language files
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 925fc76d56 Add English language files and README
This commit is part of rewritten history of the localization branch.
The original (unsquashed) commit history can be found here:
https://github.com/Dav999-v/VVVVVV/tree/localization-orig
2022-12-31 20:04:56 -08:00
Dav999-v 2d6b2e685b Clarify submodules in desktop_version/README.md
VVVVVV uses submodules now, so you need to know how to initialize them.

I'm explicitly not including `git clone --recurse-submodules`. Usage of
submodules in git projects is kinda rare in my experience, so people
are used to doing simple clones, and that instruction would just result
in people being annoyed thinking they have to delete the repo they
already cloned, and clone it again except slightly differently.

It also doesn't help you if you need submodules that aren't in the
master branch (for example, if you clone my fork recursively and then
checkout the localization branch, you won't have C-HashMap and you'll
need the update command anyway). And you also need it whenever VVVVVV
updates its submodules. So teaching people just the update command is
better.
2022-10-16 09:56:34 -07:00
Dav999-v 10acd67377 Add support for start position via level XML for CLI playtesting
As already described in cc61194bed, as
well as Ved's commits from the last almost two weeks, starting VVVVVV
from Ved for playtesting could be made a lot faster by "preloading" the
game - letting it do all its asset loading in the background without
creating a window - and then waiting until the level is passed in via
stdin. There's only one problem left with this approach: VVVVVV
currently expects the starting position to be passed via command line
arguments, which isn't known yet at the time we'd like to start VVVVVV.
Therefore, this commit allows passing the starting position via the
level XML, instead of via arguments.

The extra XML looks like this, and is added next to the <Data> tag:

    <Playtest>
        <playx>214</playx>
        <playy>112</playy>
        <playrx>100</playrx>
        <playry>100</playry>
        <playgc>0</playgc>
        <playmusic>4</playmusic>
    </Playtest>

This is handled similarly to how the equivalent arguments are handled:
when the level metadata is loaded for CLI playtesting, we also try to
find this tag, and if it exists, it sets the same variables that the
arguments would have otherwise set.
2022-06-19 15:21:36 -07:00
Dav999-v ea4302b41e Implement new string formatting system (VFormat)
This commit adds a new string formatting system to replace uses of
`SDL_snprintf` and string concatenation.

Making our own string formatting system has been briefly discussed
during the review of the localization branch, and on the VVVVVV
Discord. It's inspired by Python's format strings, but simpler.

This is primarily to benefit localization - strings will be easier to
understand (`Now using %s Tileset` → `Now using {area} Tileset`,
`"%s remain"` → `"{n_crewmates|wordy} remain"`), translators can change
the word order for their language's grammar (`%1$s` is a POSIX
extension), and this system is also less error-prone (making the format
string not align with the actual arguments won't result in a crash or
UB).

It also integrates our needs better - particularly the "wordy" numbers
without having to have a `help.number_words(n).c_str()` at the
callsite, translators can opt in and out of wordy numbers per string,
and this should also make it easier to solve #859.

This commit adds the formatting system itself, and changes one
`SDL_snprintf` in the code to use it as a small demo (the rest should
probably be done in the localization branch to avoid more unneeded
work).

The system is described in full detail in VFormat.h and in the pull
request description.
2022-05-06 00:19:30 -07:00
Dav999-v c61c4fab6f Fix C/C++ standards being unset for VVVVVV target if CMake is >= 3.1.3
So, it turns out we weren't quite done fighting CMake yet...

To accommodate #869 (and actually also #272), the C standard was raised
from C90 to C99. This turned out to require a bit of a fight with the
CentOS CI's CMake version to get it to set the flags we wanted (and to
not overwrite them later). Eventually the fix was to move the block
that sets the standards to later in the file, which was done in
24353a54bb.

As it apparently turns out, if your CMake is at least 3.1.3 and
`CMAKE_<LANG>_STANDARD` is used instead of the workaround, the standard
setting now has an effect on the third party libraries, but not on
VVVVVV itself. The cause is (probably) the phrase "if it is set when a
target is created" in the CMake documentation - the
`CMAKE_<LANG>_STANDARD` values have to come before the VVVVVV target is
defined. In other words, the compiler's default C/C++ standard will be
used, probably something like C17 and C++17. As I can confirm with
`__cplusplus` and `__STDC_VERSION__` with my recent-enough CMake. If I
force the pre-3.1.3 workaround to be used, everything is compiled with
C99/C++98 as expected; and the `-fno-exceptions` `-fno-rtti` flags
appear everywhere regardless of version.

So my fix is to make the CMakeLists a little less complex by
simplifying away the `CMAKE_<LANG>_STANDARD` and
`CMAKE_<LANG>_EXTENSIONS`, and always using the workaround regardless
of CMake version. There's nothing wrong with the workaround, the same
thing is also done for `-fno-exceptions` `-fno-rtti`, and it's good to
have a less complicated CMakeLists that doesn't do different and
unexpected things for different versions.
2022-03-22 13:03:55 -07:00
Dav999-v 3e36bfd56f Simplify time formatting functions
Here's my notes on all the existing functions and what kind of time
formats they output:

- Game::giventimestring(int hrs, int min, int sec)
	H:MM:SS
	MM:SS

- Game::timestring()
// uses game.hours/minutes/seconds
	H:MM:SS
	MM:SS

- Game::partimestring()
// uses game.timetrialpar (seconds)
	MM:SS

- Game::resulttimestring()
// uses game.timetrialresulttime (sec) + timetrialresultframes (1/30s)
	MM:SS.CC

- Game::timetstring(int t)
// t = seconds
	MM:SS

- Game::timestringcenti(char* buffer, const size_t buffer_size)
// uses game.hours/minutes/seconds/frames
	H:MM:SS.CC
	MM:SS.CC

- UtilityClass::timestring(int t)
// t = frames, 30 frames = 1 second
	S:CC
	M:SS:CC

This is kind of a mess, and there's a lot of functions that do the same
thing except using different variables. For localization, I also want
translators to be able to localize all these time formats - many
languages use the decimal comma instead of the decimal point (12:34,56)
maybe some languages really prefer something like 1時02分11秒44瞬...
Which I don't know to be correct, but it's good to be prepared for it
and not restrict translators arbitrarily to only changing ":" and "."
when we can start making the system better in the first place.

I added a new function, UtilityClass::format_time. This is the place
where all time formats come together, given the number of seconds and
optionally frames. I have simplified the above-mentioned functions
somewhat, but I haven't given them a complete refactor or renaming -
I mainly made sure that they all use the same backend so I can make the
formats consistent and properly localizable.

(And before we start shoving more temporary char buffers everywhere
just to get rid of the std::string's, maybe we need to think of a
globally used working buffer of size SCREEN_WIDTH_CHARS+1, as a
register of sorts, for when any line of text needs to be made or
processed, then printed, and then goes unused. Maybe help.textrow,
or something like that.)

As for this commit, the available time formats are now more consistent
and changed a little in some places. Leading zeroes for the first unit
are now no longer included, time trial results and the Super Gravitron
can now display hours when they went to 60 minutes before, and we now
always use .CC instead of :CC. These are the formats:
- H:MM:SS
- H:MM:SS.CC
- M:SS
- M:SS.CC
- S.CC  (only used when always_minutes=false, for the Gravitrons)

Here's what changes to the current functions:
- Game::partimestring() is removed - it was used in two places, and
  could be replaced by game.timetstring(game.timetrialpar)
- Game::giventimestring(h,m,s) and Game::timestring() are now wrappers
  for the other functions
- The four remaining functions (Game::resulttimestring(),
  Game::timetstring(t), Game::timestringcenti(buffer, buffer_size)
  and UtilityClass::timestring(t)) are now wrappers for the "central
  function", UtilityClass::format_time.
- UtilityClass::twodigits(int t) is now unused so it's also removed.
- I also added int UtilityClass::hms_to_seconds(int h, int m, int s)
2021-12-25 11:38:12 -08:00
Dav999-v f60d2a2964 Fix -Wformat-security warnings
These warnings are kinda spammy, and they make sense in principle.
vlog_error takes a format string, so passing it an arbitrary string
(even error messages from libraries) isn't a good idea.
2021-12-05 10:45:36 -08:00
Dav999-v 274ae98915 Re-fix handling filepaths with non-ASCII characters on Windows
In #52 I fixed VVVVVV not being able to handle filepaths with non-ASCII
characters on Windows. 2f0a0bce4c and
aa5c2d9dc2 reintroduce this problem,
however, by reverting the definition of mkdir to how it was before the
fix and using the non-Unicode version of CreateDirectory. And I can
confirm that VVVVVV indeed doesn't make its folder anymore with a
Windows username of "тест". This commit fixes that issue.
2021-04-12 13:25:27 -04:00
Dav999-v 04da8085a3 Simplify lua-esque assignment
`success = success && savesettings();` is now changed to
`success &= savesettings();`. It's bitwise, and I think C++ should have
had a &&= for completeness, but it shouldn't matter here.
2020-12-18 14:16:53 -05:00
Dav999-v 09986c90f7 Make indentation in settings saving error consistent with rest of cases 2020-12-18 14:16:53 -05:00
Dav999-v 444074a931 Add error messages for failed writes to disk of settings
Changing settings would most of the time attempt to save unlock.vvv and
now also settings.vvv, but there would be no feedback whether the files
have been saved successfully or not. Now, if saving fails when changing
settings in the menu, a warning message will be shown. The setting will
still be applied of course, but the user will be informed it couldn't
be saved. This message can be silenced until the game is restarted,
because I can imagine this could get very annoying when someone already
knows their settings aren't writeable.

Also, some options didn't even save settings in the first place. These
are turning off invincibility, and by coincidence precisely all the
options in the advanced options menu. I made sure these options now do
so.
2020-12-18 14:16:53 -05:00
Dav999-v db0c38711c Visually remove all other tabs in SAVE-only enter screen
This commit does this:
> Yeah, it'd be better if all the other options were gone, and "[SAVE]"
> would be re-centered in the middle of the screen.
2020-12-18 10:03:10 -05:00
Dav999-v 679b590da5 Restrict the ENTER menu to saving while in a cutscene
PR #468 made it so you can use the menus while in a cutscene, in order
to counteract softlocks. However, this has resulted in more
unintentional behavior:
- `gamemode(teleporter)` breaks when opening the ENTER menu (Misa
  mentioned this)
- The player can now interrupt shakes and walks, and have their timers
  run out before resuming the cutscene
- After completing the game, the player can warp to the ship while a
  dialogue is active, and prevent themselves from advancing text (plus
  it's always rude to just teleport away while someone's talking)
- The player can peek at the map before hidecoordinates is run, and can
  also peek at what the game does with missing/rescued crewmates during
  cutscenes

This commit fixes the latter two issues. While a script is running,
only the SAVE tab is now available. Therefore the player can still get
themselves out of softlocks as intended, but they do things like
looking at the map or teleporting away during a cutscene.
2020-12-18 10:03:10 -05:00
Dav999-v 4ebf89e844 Add error message if quicksave fails 2020-11-03 22:05:26 -05:00
Dav999-v 5dbb90c7fd Add error message if telesave fails
At least, whenever it would say "Game Saved", it now instead gives an
error message if saving is not successful.
2020-11-03 22:05:26 -05:00
Dav999-v 70e82dfe12 Fix "name lookup of ‘i’ changed" warning in editor.cpp
I got this warning during compilation because there were two nested for
loops both defining i. Better to have different names to make sure some
compilers won't overwrite the outer variable with the inner one.
2020-10-13 22:39:12 -04:00
Dav999-v 4adcf7013c Reposition game time and trinket count in game save box
The game time is moved a little to the left, and the trinket count a
little to the right. To fix #376 for real, the trinket count is now
positioned automatically based on its length. The trinket icon is now
also displayed at the far right (instead of to the left of the count)
for better symmetry, and so that switching between tele save and quick
save doesn't make the trinket icon move if the trinket counts have
different lengths.
2020-08-02 20:22:23 -04:00
Dav999-v 6c02095d99 Make game save box 16 pixels wider
While I'm going to fix #376 anyway to make longer numbers (like Seventy
Eight) fit, I decided to also make the box a little wider in advance of
the game being localized, those extra chars could be a lifesaver, while
you wouldn't really notice the difference if you play the game in
English.
2020-08-02 20:22:23 -04:00
Dav999-v 563b10b666 Fix Direct Mode selection square not moving with tile selection drawer
Closes TerryCavanagh#386.
2020-08-01 17:36:32 -04:00
Dav999-v 7adf71a21b Change "toggle letterbox" to "scaling mode"
This change was half-backported from the localization branch, except I
just came up with "scaling mode" as a better term than the more generic
"graphics mode". It doesn't make sense to still have the option be
called "toggle letterbox" because a third option (integer mode) was
added at some point.
2020-06-30 16:53:33 -04:00
Dav999-v e20c01deed Move "resize to nearest" grouped with other resolution-related options
The options for fullscreen and scaling mode were at the top, then there
were various other graphical options, and then the option to resize to
the nearest window size that is of an integer multiple was all the way
below that. Now that last option is moved to be right below the other
options related to window sizing.
2020-06-30 16:53:33 -04:00
Dav999-v a2d8e57af0 Move some options to a new menu, "advanced options"
VVVVVV's menus are kind of packed to the brim, so I thought it was time
to recategorize the menus a little bit. There's now a new "advanced
options" menu which holds the following options which were moved out of
graphic options, game options and especially accessibility options:

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

I also made the positioning of the titles and descriptions more
consistent, and made some options which were moved to the new menu not
so abbreviated ("load screen" and "room name bg")
2020-06-30 16:53:33 -04:00
Dav999-v cc538a0965 Merge remote-tracking branch 'upstream/master' into auto-center-menu
Fix one conflict.
2020-06-29 23:40:10 +02:00
Dav999-v 803d0f45de Document menu width limit better
The reason for the menu width to be limited to 272 pixels was rather
undocumented in the code, now the comment explains more about it.
2020-06-29 23:18:33 +02:00
Dav999-v 46d5fc6576 Correct minimum horizontal spacing check
It should've checked the final spacing and not the intermediate maximum
value. I had changed some things around, and now the minimum spacing
was 5 instead of 0 by mistake.
2020-06-29 02:58:38 +02:00
Dav999-v 0023c821db Make menus automatically centered and narrowed
All menus had a hardcoded X position (offset to an arbitrary starting
point of 110) and a hardcoded horizontal spacing for the "staircasing"
(mostly 30 pixels, but for some specific menus hardcoded to 15, 20 or
something else). Not all menus were centered, and seem to have been
manually made narrower (with lower horizontal spacing) whenever text
ran offscreen during development.

This system may already be hard to work with in an English-only menu
system, since you may need to adjust horizontal spacing or positioning
when adding an option. The main reason I made this change is that it's
even less optimal when menu options have to be translated, since
maximum string lengths are hard to determine, and it's easy to have
menu options running offscreen, especially when not all menus are
checked for all languages and when options could be added in the middle
of a menu after translations of that menu are already checked.

Now, menus are automatically centered based on their options, and they
are automatically made narrower if they won't fit with the default
horizontal spacing of 30 pixels (with some padding). The game.menuxoff
variable for the menu X position is now also offset to 0 instead of 110

The _default_ horizontal spacing can be changed on a per-menu basis,
and most menus (not all) which already had a narrower spacing set,
retain that as a maximum spacing, simply because they looked odd with
30 pixels of spacing (especially the main menu). They will be made even
narrower automatically if needed. In the most extreme case, the spacing
can go down to 0 and options will be displayed right below each other.
This isn't in the usual style of the game, but at least we did the best
we could to prevent options running offscreen.

The only exception to automatic menu centering and narrowing is the
list of player levels, because it's a special case and existing
behavior would be better than automatic centering there.
2020-06-29 02:09:52 +02:00
Dav999-v 3bb4eefaff Fix editor unexpectedly quitting after failed save-and-quit
Also simplified away the success variable.
2020-06-02 09:46:42 -04:00
Dav999-v ae45391ec0 Add editor saving/loading error messages
Previously, the editor would always say it saved or loaded a level,
even if it was not successful. For example, because a file to load does
not exist, a file to save has illegal characters in its name or the
name is too long to be stored. Now failure is reported. Also, when
quitting the editor and saving before quitting is unsuccessful, the
editor will abort quitting.
2020-06-02 09:46:42 -04:00
Dav999-v 165882182b Add myself to CONTRIBUTORS
I've never given out my real name online, so I'll sort my username as a
last name. My personal preference would have been to sort the list by
first name instead of last name, since that'd be clearer, plus you
often recognize people by their first name rather than their last name.
2020-01-12 10:44:11 -05:00
Dav999-v facc34d86c Replace 2 remaining TinyXml LoadFile()s by FILESYSTEM_loadTiXmlDocument 2020-01-12 10:44:11 -05:00
Dav999-v b884b7e4e9 Replace TiXmlDocument load and save functions by PHYSFS
The TinyXml functions to load and save files don't properly support
unicode file paths on Windows, so in order to support that properly, I
saw no other option than to do the actual loading and saving via PHYSFS
(or to use the Windows API on Windows and retain doc.LoadFile and
doc.SaveFile on other OSes, but that'd be more complicated and
unnecessary, we already have PHYSFS, right?).

There are two new functions in FileSystemUtils:
bool FILESYSTEM_saveTiXmlDocument(const char *name, TiXmlDocument *doc)
bool FILESYSTEM_loadTiXmlDocument(const char *name, TiXmlDocument *doc)

Any instances of doc.SaveFile(<FULL_PATH>) have been replaced by
FILESYSTEM_saveTiXmlDocument(<VVVVVV_FOLDER_PATH>, &doc), where
<FULL_PATH> included the full path to the saves or levels directory,
and <VVVVVV_FOLDER_PATH> only includes the path relative to the VVVVVV
directory.
When loading a document, a TiXmlDocument used to be created with a full
path in its constructor and doc.LoadFile() would then be called, now a
TiXmlDocument is constructed with no path name and
FILESYSTEM_loadTiXmlDocument(<VVVVVV_FOLDER_PATH>, &doc) is called.
2020-01-12 10:44:11 -05:00
Dav999-v ddaa5e13c8 Use wide-char Windows API functions on Windows
There's now a thin layer of UTF-16 around the WinAPI functions to get
the path to the Documents folder and to create a new directory, so that
account usernames with non-ASCII characters do not result in no VVVVVV
folder being created or used.
2020-01-12 10:44:11 -05:00