1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 11:03:00 +01:00
Files
OpenRCT2/src/openrct2-ui/input/KeyboardShortcuts.cpp
zyliwax 7bffc4ae33 Adding gridlines display toggle shortcut. (#6313)
This feature existed in the original RCT1/2 games but was not present in
the latest development commit.

The original shortcut for this key was '7', placing it between the
"Invisible people toggle" (6) shortcut and the "Height marks on land
toggle" (8). This commit preserves as much as possible, using
placeholder comments that signify the relevant values which this
feature actually uses where this is not possible.
2017-11-22 12:02:23 +00:00

312 lines
12 KiB
C++

#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#include <openrct2/common.h>
#include <SDL.h>
#include <openrct2/core/Console.hpp>
#include <openrct2/core/File.h>
#include <openrct2/core/FileStream.hpp>
#include <openrct2/core/Memory.hpp>
#include <openrct2/core/Path.hpp>
#include <openrct2/core/String.hpp>
#include <openrct2/PlatformEnvironment.h>
#include "KeyboardShortcuts.h"
#include <openrct2/localisation/localisation.h>
using namespace OpenRCT2;
using namespace OpenRCT2::Input;
// Remove when the C calls are removed
static KeyboardShortcuts * _instance;
KeyboardShortcuts::KeyboardShortcuts(IPlatformEnvironment * env)
: _env(env)
{
_instance = this;
}
void KeyboardShortcuts::Reset()
{
for (size_t i = 0; i < SHORTCUT_COUNT; i++)
{
_keys[i] = DefaultKeys[i];
}
}
bool KeyboardShortcuts::Load()
{
bool result = false;
Reset();
try
{
std::string path = _env->GetFilePath(PATHID::CONFIG_KEYBOARD);
if (File::Exists(path))
{
auto fs = FileStream(path, FILE_MODE_OPEN);
uint16 version = fs.ReadValue<uint16>();
if (version == KeyboardShortcuts::CURRENT_FILE_VERSION)
{
sint32 numShortcutsInFile = (fs.GetLength() - sizeof(uint16)) / sizeof(uint16);
sint32 numShortcutsToRead = std::min<sint32>(SHORTCUT_COUNT, numShortcutsInFile);
for (sint32 i = 0; i < numShortcutsToRead; i++)
{
_keys[i] = fs.ReadValue<uint16>();
}
result = true;
}
}
}
catch (const Exception &ex)
{
Console::WriteLine("Error reading shortcut keys: %s", ex.GetMessage());
}
return result;
}
bool KeyboardShortcuts::Save()
{
bool result = false;
try
{
std::string path = _env->GetFilePath(PATHID::CONFIG_KEYBOARD);
auto fs = FileStream(path, FILE_MODE_WRITE);
fs.WriteValue<uint16>(KeyboardShortcuts::CURRENT_FILE_VERSION);
for (sint32 i = 0; i < SHORTCUT_COUNT; i++)
{
fs.WriteValue<uint16>(_keys[i]);
}
result = true;
}
catch (const Exception &ex)
{
Console::WriteLine("Error writing shortcut keys: %s", ex.GetMessage());
}
return result;
}
void KeyboardShortcuts::Set(sint32 key)
{
// Unmap shortcut that already uses this key
sint32 shortcut = GetFromKey(key);
if (shortcut != SHORTCUT_UNDEFINED)
{
_keys[shortcut] = SHORTCUT_UNDEFINED;
}
// Map shortcut to this key
_keys[gKeyboardShortcutChangeId] = key;
Save();
}
sint32 KeyboardShortcuts::GetFromKey(sint32 key)
{
for (sint32 i = 0; i < SHORTCUT_COUNT; i++)
{
if (key == _keys[i])
{
return i;
}
}
return SHORTCUT_UNDEFINED;
}
std::string KeyboardShortcuts::GetShortcutString(sint32 shortcut) const
{
utf8 buffer[256] = { 0 };
utf8 formatBuffer[256] = { 0 };
uint16 shortcutKey = _keys[shortcut];
if (shortcutKey == SHORTCUT_UNDEFINED) return std::string();
if (shortcutKey & SHIFT)
{
format_string(formatBuffer, sizeof(formatBuffer), STR_SHIFT_PLUS, nullptr);
String::Append(buffer, sizeof(buffer), formatBuffer);
}
if (shortcutKey & CTRL)
{
format_string(formatBuffer, sizeof(formatBuffer), STR_CTRL_PLUS, nullptr);
String::Append(buffer, sizeof(buffer), formatBuffer);
}
if (shortcutKey & ALT)
{
#ifdef __MACOSX__
format_string(formatBuffer, sizeof(formatBuffer), STR_OPTION_PLUS, nullptr);
#else
format_string(formatBuffer, sizeof(formatBuffer), STR_ALT_PLUS, nullptr);
#endif
String::Append(buffer, sizeof(buffer), formatBuffer);
}
if (shortcutKey & CMD)
{
format_string(formatBuffer, sizeof(formatBuffer), STR_CMD_PLUS, nullptr);
String::Append(buffer, sizeof(buffer), formatBuffer);
}
String::Append(buffer, sizeof(buffer), SDL_GetScancodeName((SDL_Scancode)(shortcutKey & 0xFF)));
return std::string(buffer);
}
void KeyboardShortcuts::GetKeyboardMapScroll(const uint8 * keysState, sint32 * x, sint32 * y) const
{
for (sint32 shortcutId = SHORTCUT_SCROLL_MAP_UP; shortcutId <= SHORTCUT_SCROLL_MAP_RIGHT; shortcutId++)
{
uint16 shortcutKey = _keys[shortcutId];
uint8 scancode = shortcutKey & 0xFF;
if (shortcutKey == 0xFFFF) continue;
if (!keysState[scancode]) continue;
if (shortcutKey & SHIFT) {
if (!keysState[SDL_SCANCODE_LSHIFT] && !keysState[SDL_SCANCODE_RSHIFT]) continue;
}
if (shortcutKey & CTRL) {
if (!keysState[SDL_SCANCODE_LCTRL] && !keysState[SDL_SCANCODE_RCTRL]) continue;
}
if (shortcutKey & ALT) {
if (!keysState[SDL_SCANCODE_LALT] && !keysState[SDL_SCANCODE_RALT]) continue;
}
#ifdef __MACOSX__
if (shortcutKey & CMD) {
if (!keysState[SDL_SCANCODE_LGUI] && !keysState[SDL_SCANCODE_RGUI]) continue;
}
#endif
switch (shortcutId) {
case SHORTCUT_SCROLL_MAP_UP:
*y = -1;
break;
case SHORTCUT_SCROLL_MAP_LEFT:
*x = -1;
break;
case SHORTCUT_SCROLL_MAP_DOWN:
*y = 1;
break;
case SHORTCUT_SCROLL_MAP_RIGHT:
*x = 1;
break;
default:
break;
}
}
}
extern "C"
{
void keyboard_shortcuts_reset()
{
_instance->Reset();
}
bool keyboard_shortcuts_load()
{
return _instance->Load();
}
bool keyboard_shortcuts_save()
{
return _instance->Save();
}
void keyboard_shortcuts_set(sint32 key)
{
return _instance->Set(key);
}
sint32 keyboard_shortcuts_get_from_key(sint32 key)
{
return _instance->GetFromKey(key);
}
void keyboard_shortcuts_format_string(char * buffer, size_t bufferSize, sint32 shortcut)
{
auto str = _instance->GetShortcutString(shortcut);
String::Set(buffer, bufferSize, str.c_str());
}
void get_keyboard_map_scroll(const uint8 * keysState, sint32 * x, sint32 * y)
{
_instance->GetKeyboardMapScroll(keysState, x, y);
}
}
// Default keyboard shortcuts
const uint16 KeyboardShortcuts::DefaultKeys[SHORTCUT_COUNT] =
{
SDL_SCANCODE_BACKSPACE, // SHORTCUT_CLOSE_TOP_MOST_WINDOW
SHIFT | SDL_SCANCODE_BACKSPACE, // SHORTCUT_CLOSE_ALL_FLOATING_WINDOWS
SDL_SCANCODE_ESCAPE, // SHORTCUT_CANCEL_CONSTRUCTION_MODE
SDL_SCANCODE_PAUSE, // SHORTCUT_PAUSE_GAME
SDL_SCANCODE_PAGEUP, // SHORTCUT_ZOOM_VIEW_OUT
SDL_SCANCODE_PAGEDOWN, // SHORTCUT_ZOOM_VIEW_IN
SDL_SCANCODE_RETURN, // SHORTCUT_ROTATE_VIEW_CLOCKWISE
SHIFT | SDL_SCANCODE_RETURN, // SHORTCUT_ROTATE_VIEW_ANTICLOCKWISE
SDL_SCANCODE_Z, // SHORTCUT_ROTATE_CONSTRUCTION_OBJECT
SDL_SCANCODE_1, // SHORTCUT_UNDERGROUND_VIEW_TOGGLE
SDL_SCANCODE_H, // SHORTCUT_REMOVE_BASE_LAND_TOGGLE
SDL_SCANCODE_V, // SHORTCUT_REMOVE_VERTICAL_LAND_TOGGLE
SDL_SCANCODE_3, // SHORTCUT_SEE_THROUGH_RIDES_TOGGLE
SDL_SCANCODE_4, // SHORTCUT_SEE_THROUGH_SCENERY_TOGGLE
SDL_SCANCODE_5, // SHORTCUT_INVISIBLE_SUPPORTS_TOGGLE
SDL_SCANCODE_6, // SHORTCUT_INVISIBLE_PEOPLE_TOGGLE
SDL_SCANCODE_8, // SHORTCUT_HEIGHT_MARKS_ON_LAND_TOGGLE
SDL_SCANCODE_9, // SHORTCUT_HEIGHT_MARKS_ON_RIDE_TRACKS_TOGGLE
SDL_SCANCODE_0, // SHORTCUT_HEIGHT_MARKS_ON_PATHS_TOGGLE
SDL_SCANCODE_F1, // SHORTCUT_ADJUST_LAND
SDL_SCANCODE_F2, // SHORTCUT_ADJUST_WATER
SDL_SCANCODE_F3, // SHORTCUT_BUILD_SCENERY
SDL_SCANCODE_F4, // SHORTCUT_BUILD_PATHS
SDL_SCANCODE_F5, // SHORTCUT_BUILD_NEW_RIDE
SDL_SCANCODE_F, // SHORTCUT_SHOW_FINANCIAL_INFORMATION
SDL_SCANCODE_D, // SHORTCUT_SHOW_RESEARCH_INFORMATION
SDL_SCANCODE_R, // SHORTCUT_SHOW_RIDES_LIST
SDL_SCANCODE_P, // SHORTCUT_SHOW_PARK_INFORMATION
SDL_SCANCODE_G, // SHORTCUT_SHOW_GUEST_LIST
SDL_SCANCODE_S, // SHORTCUT_SHOW_STAFF_LIST
SDL_SCANCODE_M, // SHORTCUT_SHOW_RECENT_MESSAGES
SDL_SCANCODE_TAB, // SHORTCUT_SHOW_MAP
PLATFORM_MODIFIER | SDL_SCANCODE_S, // SHORTCUT_SCREENSHOT
SDL_SCANCODE_MINUS, // SHORTCUT_REDUCE_GAME_SPEED,
SDL_SCANCODE_EQUALS, // SHORTCUT_INCREASE_GAME_SPEED,
PLATFORM_MODIFIER | ALT | SDL_SCANCODE_C, // SHORTCUT_OPEN_CHEAT_WINDOW,
SDL_SCANCODE_T, // SHORTCUT_REMOVE_TOP_BOTTOM_TOOLBAR_TOGGLE,
SDL_SCANCODE_UP, // SHORTCUT_SCROLL_MAP_UP
SDL_SCANCODE_LEFT, // SHORTCUT_SCROLL_MAP_LEFT
SDL_SCANCODE_DOWN, // SHORTCUT_SCROLL_MAP_DOWN
SDL_SCANCODE_RIGHT, // SHORTCUT_SCROLL_MAP_RIGHT
SDL_SCANCODE_C, // SHORTCUT_OPEN_CHAT_WINDOW
PLATFORM_MODIFIER | SDL_SCANCODE_F10, // SHORTCUT_QUICK_SAVE_GAME
SHORTCUT_UNDEFINED, // SHORTCUT_SHOW_OPTIONS
SHORTCUT_UNDEFINED, // SHORTCUT_MUTE_SOUND
ALT | SDL_SCANCODE_RETURN, // SHORTCUT_WINDOWED_MODE_TOGGLE
SHORTCUT_UNDEFINED, // SHORTCUT_SHOW_MULTIPLAYER
SHORTCUT_UNDEFINED, // SHORTCUT_PAINT_ORIGINAL_TOGGLE
SHORTCUT_UNDEFINED, // SHORTCUT_DEBUG_PAINT_TOGGLE
SHORTCUT_UNDEFINED, // SHORTCUT_SEE_THROUGH_PATHS_TOGGLE
SDL_SCANCODE_KP_4, // SHORTCUT_RIDE_CONSTRUCTION_TURN_LEFT
SDL_SCANCODE_KP_6, // SHORTCUT_RIDE_CONSTRUCTION_TURN_RIGHT
SDL_SCANCODE_KP_5, // SHORTCUT_RIDE_CONSTRUCTION_USE_TRACK_DEFAULT
SDL_SCANCODE_KP_2, // SHORTCUT_RIDE_CONSTRUCTION_SLOPE_DOWN
SDL_SCANCODE_KP_8, // SHORTCUT_RIDE_CONSTRUCTION_SLOPE_UP
SDL_SCANCODE_KP_PLUS, // SHORTCUT_RIDE_CONSTRUCTION_CHAIN_LIFT_TOGGLE
SDL_SCANCODE_KP_1, // SHORTCUT_RIDE_CONSTRUCTION_BANK_LEFT
SDL_SCANCODE_KP_3, // SHORTCUT_RIDE_CONSTRUCTION_BANK_RIGHT
SDL_SCANCODE_KP_7, // SHORTCUT_RIDE_CONSTRUCTION_PREVIOUS_TRACK
SDL_SCANCODE_KP_9, // SHORTCUT_RIDE_CONSTRUCTION_NEXT_TRACK
SDL_SCANCODE_KP_0, // SHORTCUT_RIDE_CONSTRUCTION_BUILD_CURRENT
SDL_SCANCODE_KP_MINUS, // SHORTCUT_RIDE_CONSTRUCTION_DEMOLISH_CURRENT
PLATFORM_MODIFIER | SDL_SCANCODE_L, // SHORTCUT_LOAD_GAME
SDL_SCANCODE_B, // SHORTCUT_CLEAR_SCENERY
SDL_SCANCODE_7, // SHORTCUT_GRIDLINES_DISPLAY_TOGGLE
};