mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2024-12-22 17:49:43 +01:00
Add support for button glyph display
This adds a function that converts an action (such as interacting in-game) to the corresponding button text ("ENTER", "E") or button glyph (PlayStation triangle, Steam Deck Y, etc). This function currently only gives the existing ENTERs or Es, because I don't know how best to detect controller usage, or whether the game is running on a Steam Deck, or what buttons need to be displayed there. Still, it should now be really easy to adapt the rendering of keyboard keys to consoles, controllers, or rebound keys. To identify the actions that currently need to be displayed, this commit also adds the initial enums for action sets as described by Ethan in a comment in #834 (Jan 18, 2022).
This commit is contained in:
parent
5180e430a2
commit
3354a1a352
10 changed files with 332 additions and 39 deletions
|
@ -71,6 +71,7 @@ endif()
|
|||
set(VVV_SRC
|
||||
src/BinaryBlob.cpp
|
||||
src/BlockV.cpp
|
||||
src/ButtonGlyphs.cpp
|
||||
src/CWrappers.cpp
|
||||
src/Ent.cpp
|
||||
src/Entity.cpp
|
||||
|
|
|
@ -420,7 +420,8 @@
|
|||
<string english="The levels path is:" translation="" explanation="" max="40"/>
|
||||
<string english="[ Press ACTION to Start ]" translation="" explanation="title screen" max="38*2"/>
|
||||
<string english="ACTION = Space, Z, or V" translation="" explanation="title screen" max="38*3"/>
|
||||
<string english="[Press ENTER to return to editor]" translation="" explanation="`to editor` is sorta redundant" max="40"/>
|
||||
<string english="[Press ENTER to return to editor]" translation="" explanation="***OUTDATED***" max="40"/>
|
||||
<string english="[Press {button} to return to editor]" translation="" explanation="`to editor` is sorta redundant" max="40"/>
|
||||
<string english="- Press ACTION to advance text -" translation="" explanation="to dismiss a textbox" max="40"/>
|
||||
<string english="Press ACTION to continue" translation="" explanation="" max="34"/>
|
||||
<string english="Current Time" translation="" explanation="super gravitron, stopwatch time" max="20"/>
|
||||
|
@ -434,7 +435,8 @@
|
|||
<string english="All Trophies collected!" translation="" explanation="" max="38*2"/>
|
||||
<string english="New Record!" translation="" explanation="" max="20"/>
|
||||
<string english="New Trophy!" translation="" explanation="" max="20"/>
|
||||
<string english="[Press ENTER to stop]" translation="" explanation="stop super gravitron" max="40"/>
|
||||
<string english="[Press ENTER to stop]" translation="" explanation="***OUTDATED***" max="40"/>
|
||||
<string english="[Press {button} to stop]" translation="" explanation="stop super gravitron" max="40"/>
|
||||
<string english="SUPER GRAVITRON" translation="" explanation="" max="20"/>
|
||||
<string english="SUPER GRAVITRON HIGHSCORE" translation="" explanation="" max="38*4"/>
|
||||
<string english="MAP" translation="" explanation="in-game menu" max="8"/>
|
||||
|
@ -652,8 +654,10 @@
|
|||
<string english="All crewmates rescued!" translation="" explanation="" max="32"/>
|
||||
<string english="Game Saved" translation="" explanation="" max="30"/>
|
||||
<string english="Press arrow keys or WASD to move" translation="" explanation="" max="32*2"/>
|
||||
<string english="Press left/right to move" translation="" explanation="" max="32*2"/>
|
||||
<string english="Press ACTION to flip" translation="" explanation="" max="32*3"/>
|
||||
<string english="Press ENTER to view map and quicksave" translation="" explanation="" max="32*3"/>
|
||||
<string english="Press ENTER to view map and quicksave" translation="" explanation="***OUTDATED***" max="32*3"/>
|
||||
<string english="Press {button} to view map and quicksave" translation="" explanation="" max="32*3"/>
|
||||
<string english="If you prefer, you can press UP or DOWN instead of ACTION to flip." translation="" explanation="" max="34*3"/>
|
||||
<string english="Help! Can anyone hear this message?" translation="" explanation="Violet speaking via Comms Relay" max="25*4"/>
|
||||
<string english="Verdigris? Are you out there? Are you ok?" translation="" explanation="Violet speaking via Comms Relay" max="25*4"/>
|
||||
|
|
80
desktop_version/src/ActionSets.h
Normal file
80
desktop_version/src/ActionSets.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* For now, this isn't really a foundation for action sets yet; button glyphs
|
||||
* just need to be able to identify actions that are printed in text like
|
||||
* "Press ENTER to teleport". Thus, this currently ONLY contains identifiers
|
||||
* for the actions that button glyphs are needed for.
|
||||
*
|
||||
* Based on this comment:
|
||||
* https://github.com/TerryCavanagh/VVVVVV/issues/834#issuecomment-1015692161
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ACTIONSETS_H
|
||||
#define ACTIONSETS_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------*
|
||||
* List of all action sets (all "states") *
|
||||
*----------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
//ActionSet_Global,
|
||||
//ActionSet_Menu,
|
||||
ActionSet_InGame
|
||||
//ActionSet_Editor
|
||||
}
|
||||
ActionSet;
|
||||
|
||||
|
||||
/*----------------------------------------------------------*
|
||||
* An enum for each actionset, with the actions in that set *
|
||||
*----------------------------------------------------------*/
|
||||
/*
|
||||
typedef enum
|
||||
{
|
||||
Action_Global_Mute,
|
||||
Action_Global_MuteMusic
|
||||
}
|
||||
Action_Global;
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Action_InGame_Interact,
|
||||
Action_InGame_Map
|
||||
}
|
||||
Action_InGame;
|
||||
|
||||
/*
|
||||
typedef enum
|
||||
{
|
||||
//Action_Editor_PrevTool,
|
||||
//Action_Editor_NextTool
|
||||
}
|
||||
Action_Editor;
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------*
|
||||
* A union to represent any actionset enum *
|
||||
*-----------------------------------------*/
|
||||
typedef union
|
||||
{
|
||||
int intval;
|
||||
//Action_Global Global;
|
||||
Action_InGame InGame;
|
||||
//Action_Editor Editor;
|
||||
}
|
||||
Action;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ACTIONSETS_H
|
131
desktop_version/src/ButtonGlyphs.cpp
Normal file
131
desktop_version/src/ButtonGlyphs.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
#include "ButtonGlyphs.h"
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "Game.h"
|
||||
#include "Localization.h"
|
||||
#include "UTF8.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GLYPH_NINTENDO_DECK_A, // Note that for the Deck, the icons are same as Nintendo but the layout is the same as Xbox
|
||||
GLYPH_NINTENDO_DECK_B,
|
||||
GLYPH_NINTENDO_DECK_X,
|
||||
GLYPH_NINTENDO_DECK_Y,
|
||||
GLYPH_NINTENDO_PLUS,
|
||||
GLYPH_NINTENDO_MINUS,
|
||||
GLYPH_NINTENDO_L,
|
||||
GLYPH_NINTENDO_R,
|
||||
GLYPH_NINTENDO_ZL,
|
||||
GLYPH_NINTENDO_ZR,
|
||||
GLYPH_NINTENDO_XBOX_LSTICK,
|
||||
GLYPH_NINTENDO_XBOX_RSTICK,
|
||||
GLYPH_NINTENDO_SL,
|
||||
GLYPH_NINTENDO_SR,
|
||||
GLYPH_GENERIC_L,
|
||||
GLYPH_GENERIC_R,
|
||||
|
||||
GLYPH_PLAYSTATION_CIRCLE,
|
||||
GLYPH_PLAYSTATION_CROSS,
|
||||
GLYPH_PLAYSTATION_TRIANGLE,
|
||||
GLYPH_PLAYSTATION_SQUARE,
|
||||
GLYPH_PLAYSTATION_START,
|
||||
GLYPH_PLAYSTATION_OPTIONS,
|
||||
GLYPH_PLAYSTATION_DECK_L1,
|
||||
GLYPH_PLAYSTATION_DECK_R1,
|
||||
GLYPH_PLAYSTATION_DECK_L2,
|
||||
GLYPH_PLAYSTATION_DECK_R2,
|
||||
GLYPH_PLAYSTATION_DECK_L3,
|
||||
GLYPH_PLAYSTATION_DECK_R3,
|
||||
GLYPH_DECK_L4,
|
||||
GLYPH_DECK_R4,
|
||||
GLYPH_DECK_L5,
|
||||
GLYPH_DECK_R5,
|
||||
|
||||
GLYPH_XBOX_B,
|
||||
GLYPH_XBOX_A,
|
||||
GLYPH_XBOX_Y,
|
||||
GLYPH_XBOX_X,
|
||||
GLYPH_XBOX_DECK_VIEW,
|
||||
GLYPH_XBOX_DECK_MENU,
|
||||
GLYPH_XBOX_LB,
|
||||
GLYPH_XBOX_RB,
|
||||
GLYPH_XBOX_LT,
|
||||
GLYPH_XBOX_RT,
|
||||
GLYPH_NINTENDO_GENERIC_ACTIONRIGHT,
|
||||
GLYPH_NINTENDO_GENERIC_ACTIONDOWN,
|
||||
GLYPH_NINTENDO_GENERIC_ACTIONUP,
|
||||
GLYPH_NINTENDO_GENERIC_ACTIONLEFT,
|
||||
GLYPH_NINTENDO_GENERIC_STICK,
|
||||
GLYPH_UNKNOWN,
|
||||
|
||||
GLYPH_TOTAL
|
||||
}
|
||||
ButtonGlyphKey;
|
||||
|
||||
static char glyph[GLYPH_TOTAL][5];
|
||||
|
||||
void BUTTONGLYPHS_init(void)
|
||||
{
|
||||
/* Set glyph array to strings for all the button glyph codepoints (U+EBxx) */
|
||||
for (int i = 0; i < GLYPH_TOTAL; i++)
|
||||
{
|
||||
SDL_strlcpy(glyph[i], UTF8_encode(0xEB00+i).bytes, sizeof(glyph[i]));
|
||||
}
|
||||
}
|
||||
|
||||
bool BUTTONGLYPHS_keyboard_is_available(void)
|
||||
{
|
||||
/* Returns true if it makes sense to show button hints that are only available
|
||||
* on keyboards (like press M to mute), false if we're on a console. */
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BUTTONGLYPHS_keyboard_is_active(void)
|
||||
{
|
||||
/* Returns true if, not only do we have a keyboard available, but it's also the
|
||||
* active input method. (So, show keyboard keys, if false, show controller glyphs) */
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* BUTTONGLYPHS_get_wasd_text(void)
|
||||
{
|
||||
/* Returns the string to use in Welcome Aboard */
|
||||
if (BUTTONGLYPHS_keyboard_is_active())
|
||||
{
|
||||
return loc::gettext("Press arrow keys or WASD to move");
|
||||
}
|
||||
return loc::gettext("Press left/right to move");
|
||||
}
|
||||
|
||||
const char* BUTTONGLYPHS_get_button(const ActionSet actionset, const Action action)
|
||||
{
|
||||
/* Given a specific action (like INTERACT in-game),
|
||||
* return either a (localized) keyboard key string like "ENTER" or "E",
|
||||
* or a controller button glyph from the table above like glyph[GLYPH_XBOX_Y],
|
||||
* to fill into strings like "Press {button} to activate terminal". */
|
||||
switch (actionset)
|
||||
{
|
||||
case ActionSet_InGame:
|
||||
switch (action.InGame)
|
||||
{
|
||||
case Action_InGame_Interact:
|
||||
if (game.separate_interact)
|
||||
{
|
||||
return "E";
|
||||
}
|
||||
return loc::gettext("ENTER");
|
||||
case Action_InGame_Map:
|
||||
return loc::gettext("ENTER");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_assert(0 && "Trying to get label/glyph for unknown action!");
|
||||
return glyph[GLYPH_UNKNOWN];
|
||||
}
|
||||
|
||||
} // extern "C"
|
24
desktop_version/src/ButtonGlyphs.h
Normal file
24
desktop_version/src/ButtonGlyphs.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef BUTTONGLYPHS_H
|
||||
#define BUTTONGLYPHS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "ActionSets.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void BUTTONGLYPHS_init(void);
|
||||
|
||||
bool BUTTONGLYPHS_keyboard_is_available(void);
|
||||
bool BUTTONGLYPHS_keyboard_is_active(void);
|
||||
const char* BUTTONGLYPHS_get_wasd_text(void);
|
||||
const char* BUTTONGLYPHS_get_button(ActionSet actionset, Action action);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // BUTTONGLYPHS_H
|
|
@ -6,6 +6,7 @@
|
|||
#include <string.h>
|
||||
#include <tinyxml2.h>
|
||||
|
||||
#include "ButtonGlyphs.h"
|
||||
#include "Constants.h"
|
||||
#include "CustomLevels.h"
|
||||
#include "DeferCallbacks.h"
|
||||
|
@ -832,7 +833,7 @@ void Game::updatestate(void)
|
|||
break;
|
||||
case 4:
|
||||
//End of opening cutscene for now
|
||||
graphics.createtextbox(loc::gettext("Press arrow keys or WASD to move"), -1, 195, 174, 174, 174);
|
||||
graphics.createtextbox(BUTTONGLYPHS_get_wasd_text(), -1, 195, 174, 174, 174);
|
||||
graphics.textboxprintflags(PR_FONT_INTERFACE);
|
||||
graphics.textboxwrap(4);
|
||||
graphics.textboxcentertext();
|
||||
|
@ -864,7 +865,16 @@ void Game::updatestate(void)
|
|||
if (!obj.flags[13])
|
||||
{
|
||||
obj.flags[13] = true;
|
||||
graphics.createtextbox(loc::gettext("Press ENTER to view map and quicksave"), -1, 155, 174, 174, 174);
|
||||
|
||||
char buffer[SCREEN_WIDTH_CHARS*3 + 1];
|
||||
vformat_buf(
|
||||
buffer, sizeof(buffer),
|
||||
loc::gettext("Press {button} to view map and quicksave"),
|
||||
"button:but",
|
||||
vformat_button(ActionSet_InGame, Action_InGame_Map)
|
||||
);
|
||||
|
||||
graphics.createtextbox(buffer, -1, 155, 174, 174, 174);
|
||||
graphics.textboxprintflags(PR_FONT_INTERFACE);
|
||||
graphics.textboxwrap(4);
|
||||
graphics.textboxcentertext();
|
||||
|
@ -1067,6 +1077,8 @@ void Game::updatestate(void)
|
|||
case 17:
|
||||
//Arrow key tutorial
|
||||
obj.removetrigger(17);
|
||||
if (BUTTONGLYPHS_keyboard_is_active())
|
||||
{
|
||||
graphics.createtextbox(loc::gettext("If you prefer, you can press UP or DOWN instead of ACTION to flip."), -1, 187, 174, 174, 174);
|
||||
graphics.textboxprintflags(PR_FONT_INTERFACE);
|
||||
graphics.textboxwrap(2);
|
||||
|
@ -1074,6 +1086,7 @@ void Game::updatestate(void)
|
|||
graphics.textboxpad(1, 1);
|
||||
graphics.textboxcenterx();
|
||||
graphics.textboxtimer(100);
|
||||
}
|
||||
setstate(0);
|
||||
break;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <SDL.h>
|
||||
|
||||
#include "ActionSets.h"
|
||||
#include "Constants.h"
|
||||
#include "Credits.h"
|
||||
#include "CustomLevels.h"
|
||||
|
@ -1841,18 +1842,12 @@ static const char* interact_prompt(
|
|||
const size_t buffer_size,
|
||||
const char* raw
|
||||
) {
|
||||
const char* button;
|
||||
|
||||
if (game.separate_interact)
|
||||
{
|
||||
button = loc::gettext("E");
|
||||
}
|
||||
else
|
||||
{
|
||||
button = loc::gettext("ENTER");
|
||||
}
|
||||
|
||||
vformat_buf(buffer, buffer_size, raw, "button:str", button);
|
||||
vformat_buf(
|
||||
buffer, buffer_size,
|
||||
raw,
|
||||
"button:but",
|
||||
vformat_button(ActionSet_InGame, Action_InGame_Interact)
|
||||
);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
@ -1958,7 +1953,14 @@ void gamerender(void)
|
|||
|
||||
if (alpha > 100)
|
||||
{
|
||||
font::print(PR_BRIGHTNESS(alpha) | PR_BOR, 5, 5, loc::gettext("[Press ENTER to return to editor]"), 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2));
|
||||
char buffer[SCREEN_WIDTH_CHARS + 1];
|
||||
vformat_buf(
|
||||
buffer, sizeof(buffer),
|
||||
loc::gettext("[Press {button} to return to editor]"),
|
||||
"button:but",
|
||||
vformat_button(ActionSet_InGame, Action_InGame_Map)
|
||||
);
|
||||
font::print(PR_BRIGHTNESS(alpha) | PR_BOR, 5, 5, buffer, 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -2077,7 +2079,14 @@ void gamerender(void)
|
|||
}
|
||||
}
|
||||
|
||||
font::print(PR_BOR | PR_CEN, -1, 228, loc::gettext("[Press ENTER to stop]"), 160 - (help.glow/2), 160 - (help.glow/2), 160 - (help.glow/2));
|
||||
char buffer[SCREEN_WIDTH_CHARS + 1];
|
||||
vformat_buf(
|
||||
buffer, sizeof(buffer),
|
||||
loc::gettext("[Press {button} to stop]"),
|
||||
"button:but",
|
||||
vformat_button(ActionSet_InGame, Action_InGame_Map)
|
||||
);
|
||||
font::print(PR_BOR | PR_CEN, -1, 228, buffer, 160 - (help.glow/2), 160 - (help.glow/2), 160 - (help.glow/2));
|
||||
}
|
||||
else if(game.swngame==2)
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "ButtonGlyphs.h"
|
||||
#include "CWrappers.h"
|
||||
#include "UTF8.h"
|
||||
|
||||
|
@ -28,18 +29,36 @@ static inline void trim_whitespace(const char** string, size_t* bytes)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void call_with_button(format_callback callback, void* userdata, int button_value)
|
||||
int vformat_button(ActionSet actionset, int action)
|
||||
{
|
||||
/* Pack an ActionSet and Action into a single vararg int.
|
||||
* action is an Action */
|
||||
return (((int) actionset) << 16) | action;
|
||||
}
|
||||
|
||||
static void vformat_unbutton(ActionSet* actionset, Action* action, const int vararg_value)
|
||||
{
|
||||
// Unpack the ActionSet and Action from a packed vararg value.
|
||||
*actionset = vararg_value >> 16;
|
||||
action->intval = vararg_value & 0xFFFF;
|
||||
}
|
||||
|
||||
static inline void call_with_button(format_callback callback, void* userdata, int vararg_value)
|
||||
{
|
||||
/* Call the given callback with the specified button character (from
|
||||
* Unicode Private Use Area) so the text renderer can display it. */
|
||||
|
||||
if (button_value < 0 || button_value > 0xFF)
|
||||
{
|
||||
button_value = 0xFF;
|
||||
}
|
||||
ActionSet actionset;
|
||||
Action action;
|
||||
vformat_unbutton(&actionset, &action, vararg_value);
|
||||
|
||||
UTF8_encoding utf8 = UTF8_encode(0xE000 + button_value);
|
||||
callback(userdata, utf8.bytes, utf8.nbytes);
|
||||
const char* button_text = BUTTONGLYPHS_get_button(actionset, action);
|
||||
if (button_text == NULL)
|
||||
{
|
||||
callback(userdata, "[null]", 6);
|
||||
return;
|
||||
}
|
||||
callback(userdata, button_text, SDL_strlen(button_text));
|
||||
}
|
||||
|
||||
static inline void call_with_upper(format_callback callback, void* userdata, const char* string, size_t bytes)
|
||||
|
@ -274,11 +293,11 @@ void vformat_cb_valist(
|
|||
}
|
||||
else if (arg_type_len == 3 && SDL_memcmp(arg_type, "but", 3) == 0)
|
||||
{
|
||||
int button_value = va_arg(args_copy, int);
|
||||
int vararg_value = va_arg(args_copy, int);
|
||||
|
||||
if (match)
|
||||
{
|
||||
call_with_button(callback, userdata, button_value);
|
||||
call_with_button(callback, userdata, vararg_value);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
* The valid types are:
|
||||
* - int Signed integer
|
||||
* - str const char*
|
||||
* - but Controller button icon
|
||||
* - but Controller button icon: vformat_button(actionset, action)
|
||||
*
|
||||
* Special case: if an argument name is a single underscore (_), it matches
|
||||
* any name not found earlier in the list. This should normally not be needed.
|
||||
|
@ -75,6 +75,8 @@
|
|||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "ActionSets.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
@ -83,6 +85,9 @@ extern "C"
|
|||
typedef void (*format_callback)(void* userdata, const char* string, size_t bytes);
|
||||
|
||||
|
||||
int vformat_button(ActionSet actionset, int action);
|
||||
|
||||
|
||||
void vformat_cb_valist(
|
||||
format_callback callback,
|
||||
void* userdata,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <emscripten/html5.h>
|
||||
#endif
|
||||
|
||||
#include "ButtonGlyphs.h"
|
||||
#include "CustomLevels.h"
|
||||
#include "DeferCallbacks.h"
|
||||
#include "Editor.h"
|
||||
|
@ -649,6 +650,7 @@ int main(int argc, char *argv[])
|
|||
gameScreen.init(&screen_settings);
|
||||
}
|
||||
|
||||
BUTTONGLYPHS_init();
|
||||
font::load_main();
|
||||
|
||||
// This loads music too...
|
||||
|
@ -915,9 +917,14 @@ static void unfocused_run(void)
|
|||
* a language changes the used language metadata but not the loaded strings... */
|
||||
uint32_t flags = PR_CEN | PR_BOR | PR_FONT_IDX(loc::langmeta.font_idx);
|
||||
font::print(flags | PR_CJK_HIGH, -1, FLIP(110), loc::gettext("Game paused"), 196 - help.glow, 255 - help.glow, 196 - help.glow);
|
||||
|
||||
if (BUTTONGLYPHS_keyboard_is_available())
|
||||
{
|
||||
font::print(flags | PR_CJK_LOW, -1, FLIP(120), loc::gettext("[click to resume]"), 196 - help.glow, 255 - help.glow, 196 - help.glow);
|
||||
|
||||
font::print(flags | PR_CJK_HIGH, -1, FLIP(220), loc::gettext("Press M to mute in game"), 164 - help.glow, 196 - help.glow, 164 - help.glow);
|
||||
font::print(flags, -1, FLIP(230), loc::gettext("Press N to mute music only"), 164 - help.glow, 196 - help.glow, 164 - help.glow);
|
||||
}
|
||||
#undef FLIP
|
||||
}
|
||||
graphics.render();
|
||||
|
|
Loading…
Reference in a new issue