Skip to content

Commit

Permalink
Add support for button glyph display
Browse files Browse the repository at this point in the history
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 TerryCavanagh#834 (Jan 18, 2022).
  • Loading branch information
Daaaav committed Mar 21, 2023
1 parent e3612af commit 9d03ab6
Show file tree
Hide file tree
Showing 10 changed files with 331 additions and 38 deletions.
1 change: 1 addition & 0 deletions desktop_version/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 7 additions & 3 deletions desktop_version/lang/en/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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"/>
Expand All @@ -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"/>
Expand Down Expand Up @@ -636,8 +638,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"/>
Expand Down
80 changes: 80 additions & 0 deletions desktop_version/src/ActionSets.h
Original file line number Diff line number Diff line change
@@ -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 changes: 131 additions & 0 deletions desktop_version/src/ButtonGlyphs.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 24 additions & 0 deletions desktop_version/src/ButtonGlyphs.h
Original file line number Diff line number Diff line change
@@ -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
31 changes: 22 additions & 9 deletions desktop_version/src/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <string.h>
#include <tinyxml2.h>

#include "ButtonGlyphs.h"
#include "Constants.h"
#include "CustomLevels.h"
#include "DeferCallbacks.h"
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -1067,13 +1077,16 @@ void Game::updatestate(void)
case 17:
//Arrow key tutorial
obj.removetrigger(17);
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);
graphics.textboxcentertext();
graphics.textboxpad(1, 1);
graphics.textboxcenterx();
graphics.textboxtimer(100);
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);
graphics.textboxcentertext();
graphics.textboxpad(1, 1);
graphics.textboxcenterx();
graphics.textboxtimer(100);
}
setstate(0);
break;

Expand Down
Loading

0 comments on commit 9d03ab6

Please sign in to comment.