Implemented player controls dialog.

This last missing major feature brings v2 into feature parity with the original and closer to release.
Ref issues #16, #17.
This commit is contained in:
Muzychenko Andrey 2021-10-01 09:05:38 +03:00
parent a281000308
commit 8a421a2623
4 changed files with 184 additions and 104 deletions

View File

@ -8,44 +8,23 @@
#include "Sound.h" #include "Sound.h"
#include "winmain.h" #include "winmain.h"
optionsStruct options::Options{};
short options::vk_list[28]
{
-32703,
0x5A,
-32720,
0x39,
0x402E,
0x402F,
0x403B,
0x4027,
0x405B,
0x405D,
0x20,
0x0D,
0x9,
0x14,
0x25,
0x27,
0x26,
0x28,
0x2D,
0x2E,
0x24,
0x23,
0x21,
0x22,
0x90,
0x91,
0x13,
-1
};
std::map<std::string, std::string> options::settings{};
constexpr int options::MaxUps, options::MaxFps, options::MinUps, options::MinFps, options::DefUps, options::DefFps; constexpr int options::MaxUps, options::MaxFps, options::MinUps, options::MinFps, options::DefUps, options::DefFps;
optionsStruct options::Options{};
std::map<std::string, std::string> options::settings{};
ControlsStruct options::RebindControls{};
bool options::ShowDialog = false;
const ControlRef* options::ControlWaitingForKey = nullptr;
const ControlRef options::Controls[6]
{
{"Left Flipper", RebindControls.LeftFlipper},
{"Right Flipper", RebindControls.RightFlipper},
{"Left Table Bump", RebindControls.LeftTableBump},
{"Right Table Bump", RebindControls.RightTableBump},
{"Bottom Table Bump", RebindControls.BottomTableBump},
{"Plunger", RebindControls.Plunger},
};
void options::init() void options::init()
{ {
@ -68,36 +47,26 @@ void options::init()
Options.Sounds = 1; Options.Sounds = 1;
Options.Music = 0; Options.Music = 0;
Options.FullScreen = 0; Options.FullScreen = 0;
Options.LeftFlipperKeyDft = SDLK_z; Options.KeyDft.LeftFlipper = SDLK_z;
Options.RightFlipperKeyDft = SDLK_SLASH; Options.KeyDft.RightFlipper = SDLK_SLASH;
Options.PlungerKeyDft = SDLK_SPACE; Options.KeyDft.Plunger = SDLK_SPACE;
Options.LeftTableBumpKeyDft = SDLK_x; Options.KeyDft.LeftTableBump = SDLK_x;
Options.RightTableBumpKeyDft = SDLK_PERIOD; Options.KeyDft.RightTableBump = SDLK_PERIOD;
Options.BottomTableBumpKeyDft = SDLK_UP; Options.KeyDft.BottomTableBump = SDLK_UP;
/*pinball::get_rc_int(159, &Options.LeftFlipperKeyDft); Options.Key = Options.KeyDft;
pinball::get_rc_int(160, &Options.RightFlipperKeyDft);
pinball::get_rc_int(161, &Options.PlungerKeyDft);
pinball::get_rc_int(162, &Options.LeftTableBumpKeyDft);
pinball::get_rc_int(163, &Options.RightTableBumpKeyDft);
pinball::get_rc_int(164, &Options.BottomTableBumpKeyDft);*/
Options.LeftFlipperKey = Options.LeftFlipperKeyDft;
Options.RightFlipperKey = Options.RightFlipperKeyDft;
Options.PlungerKey = Options.PlungerKeyDft;
Options.LeftTableBumpKey = Options.LeftTableBumpKeyDft;
Options.RightTableBumpKey = Options.RightTableBumpKeyDft;
Options.Players = 1; Options.Players = 1;
Options.BottomTableBumpKey = Options.BottomTableBumpKeyDft;
Options.UniformScaling = true; Options.UniformScaling = true;
Options.Sounds = get_int("Sounds", Options.Sounds); Options.Sounds = get_int("Sounds", Options.Sounds);
Options.Music = get_int("Music", Options.Music); Options.Music = get_int("Music", Options.Music);
Options.FullScreen = get_int("FullScreen", Options.FullScreen); Options.FullScreen = get_int("FullScreen", Options.FullScreen);
Options.Players = get_int("Players", Options.Players); Options.Players = get_int("Players", Options.Players);
Options.LeftFlipperKey = get_int("Left Flipper key", Options.LeftFlipperKey); Options.Key.LeftFlipper = get_int("Left Flipper key", Options.Key.LeftFlipper);
Options.RightFlipperKey = get_int("Right Flipper key", Options.RightFlipperKey); Options.Key.RightFlipper = get_int("Right Flipper key", Options.Key.RightFlipper);
Options.PlungerKey = get_int("Plunger key", Options.PlungerKey); Options.Key.Plunger = get_int("Plunger key", Options.Key.Plunger);
Options.LeftTableBumpKey = get_int("Left Table Bump key", Options.LeftTableBumpKey); Options.Key.LeftTableBump = get_int("Left Table Bump key", Options.Key.LeftTableBump);
Options.RightTableBumpKey = get_int("Right Table Bump key", Options.RightTableBumpKey); Options.Key.RightTableBump = get_int("Right Table Bump key", Options.Key.RightTableBump);
Options.BottomTableBumpKey = get_int("Bottom Table Bump key", Options.BottomTableBumpKey); Options.Key.BottomTableBump = get_int("Bottom Table Bump key", Options.Key.BottomTableBump);
Options.UniformScaling = get_int("Uniform scaling", Options.UniformScaling); Options.UniformScaling = get_int("Uniform scaling", Options.UniformScaling);
ImGui::GetIO().FontGlobalScale = get_float("UI Scale", 1.0f); ImGui::GetIO().FontGlobalScale = get_float("UI Scale", 1.0f);
Options.Resolution = get_int("Screen Resolution", -1); Options.Resolution = get_int("Screen Resolution", -1);
@ -123,12 +92,12 @@ void options::uninit()
set_int("Music", Options.Music); set_int("Music", Options.Music);
set_int("FullScreen", Options.FullScreen); set_int("FullScreen", Options.FullScreen);
set_int("Players", Options.Players); set_int("Players", Options.Players);
set_int("Left Flipper key", Options.LeftFlipperKey); set_int("Left Flipper key", Options.Key.LeftFlipper);
set_int("Right Flipper key", Options.RightFlipperKey); set_int("Right Flipper key", Options.Key.RightFlipper);
set_int("Plunger key", Options.PlungerKey); set_int("Plunger key", Options.Key.Plunger);
set_int("Left Table Bump key", Options.LeftTableBumpKey); set_int("Left Table Bump key", Options.Key.LeftTableBump);
set_int("Right Table Bump key", Options.RightTableBumpKey); set_int("Right Table Bump key", Options.Key.RightTableBump);
set_int("Bottom Table Bump key", Options.BottomTableBumpKey); set_int("Bottom Table Bump key", Options.Key.BottomTableBump);
set_int("Screen Resolution", Options.Resolution); set_int("Screen Resolution", Options.Resolution);
set_int("Uniform scaling", Options.UniformScaling); set_int("Uniform scaling", Options.UniformScaling);
set_float("UI Scale", ImGui::GetIO().FontGlobalScale); set_float("UI Scale", ImGui::GetIO().FontGlobalScale);
@ -241,9 +210,108 @@ void options::toggle(Menu1 uIDCheckItem)
} }
} }
void options::keyboard() void options::KeyDown(int key)
{ {
//DialogBoxParamA(nullptr, "KEYMAPPER", nullptr, KeyMapDlgProc, 0); if (ControlWaitingForKey)
{
// Skip function keys, just in case.
if (key < SDLK_F1 || key > SDLK_F12)
{
ControlWaitingForKey->Option = key;
ControlWaitingForKey = nullptr;
}
}
}
void options::ShowControlDialog()
{
if (!ShowDialog)
{
ControlWaitingForKey = nullptr;
RebindControls = Options.Key;
ShowDialog = true;
}
}
void options::RenderControlDialog()
{
if (!ShowDialog)
return;
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2{500, 400});
if (ImGui::Begin("3D Pinball: Player Controls", &ShowDialog))
{
ImGui::TextUnformatted("Instructions");
ImGui::Separator();
ImGui::TextWrapped(
"To change game controls, click the control button, press the new key, and then choose OK.");
ImGui::TextWrapped(
"To restore 3D Pinball to its original settings, choose Default, and then choose OK.");
ImGui::TextWrapped("Original warns against binding the same key to multiple controls, but does not forbid it.");
ImGui::Spacing();
ImGui::TextUnformatted("Control Options");
ImGui::Separator();
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{5, 10});
if (ImGui::BeginTable("Controls", 2, ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders))
{
for (auto& ctrl : Controls)
{
ImGui::TableNextColumn();
if (ImGui::BeginTable("Control", 2, ImGuiTableFlags_NoSavedSettings))
{
ImGui::TableNextColumn();
ImGui::TextWrapped("%s", ctrl.Name);
ImGui::TableNextColumn();
if (ControlWaitingForKey == &ctrl)
{
ImGui::Button("Press the key", ImVec2(-1, 0));
}
else
{
auto keyName = SDL_GetKeyName(ctrl.Option);
if (!keyName[0])
keyName = "Unknown key";
if (ImGui::Button(keyName, ImVec2(-1, 0)))
{
ControlWaitingForKey = &ctrl;
}
}
ImGui::EndTable();
}
}
ImGui::EndTable();
}
ImGui::PopStyleVar();
ImGui::Spacing();
if (ImGui::Button("OK"))
{
Options.Key = RebindControls;
ShowDialog = false;
}
ImGui::SameLine();
if (ImGui::Button("Cancel"))
{
ShowDialog = false;
}
ImGui::SameLine();
if (ImGui::Button("Default"))
{
RebindControls = Options.KeyDft;
ControlWaitingForKey = nullptr;
}
}
ImGui::End();
ImGui::PopStyleVar();
if (!ShowDialog)
ControlWaitingForKey = nullptr;
} }
void options::MyUserData_ReadLine(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line) void options::MyUserData_ReadLine(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line)

View File

@ -29,24 +29,24 @@ enum class Menu1:int
WindowLinearFilter = 601, WindowLinearFilter = 601,
}; };
struct ControlsStruct
{
int LeftFlipper;
int RightFlipper;
int Plunger;
int LeftTableBump;
int RightTableBump;
int BottomTableBump;
};
struct optionsStruct struct optionsStruct
{ {
ControlsStruct Key;
ControlsStruct KeyDft;
int Sounds; int Sounds;
int Music; int Music;
int FullScreen; int FullScreen;
int Players; int Players;
int LeftFlipperKey;
int RightFlipperKey;
int PlungerKey;
int LeftTableBumpKey;
int RightTableBumpKey;
int BottomTableBumpKey;
int LeftFlipperKeyDft;
int RightFlipperKeyDft;
int PlungerKeyDft;
int LeftTableBumpKeyDft;
int RightTableBumpKeyDft;
int BottomTableBumpKeyDft;
int Resolution; int Resolution;
bool UniformScaling; bool UniformScaling;
bool LinearFiltering; bool LinearFiltering;
@ -55,6 +55,12 @@ struct optionsStruct
bool ShowMenu; bool ShowMenu;
}; };
struct ControlRef
{
const char* Name;
int& Option;
};
class options class options
{ {
@ -73,11 +79,15 @@ public:
static float get_float(LPCSTR lpValueName, float defaultValue); static float get_float(LPCSTR lpValueName, float defaultValue);
static void set_float(LPCSTR lpValueName, float data); static void set_float(LPCSTR lpValueName, float data);
static void toggle(Menu1 uIDCheckItem); static void toggle(Menu1 uIDCheckItem);
static void KeyDown(int key);
static void keyboard(); static void ShowControlDialog();
static void RenderControlDialog();
private: private:
static short vk_list[28];
static std::map<std::string, std::string> settings; static std::map<std::string, std::string> settings;
static ControlsStruct RebindControls;
static bool ShowDialog;
static const ControlRef Controls[6];
static const ControlRef* ControlWaitingForKey;
static void MyUserData_ReadLine(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line); static void MyUserData_ReadLine(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line);
static void* MyUserData_ReadOpen(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name); static void* MyUserData_ReadOpen(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name);

View File

@ -365,27 +365,27 @@ void pb::keyup(int key)
{ {
if (game_mode == 1 && !winmain::single_step && !demo_mode) if (game_mode == 1 && !winmain::single_step && !demo_mode)
{ {
if (key == options::Options.LeftFlipperKey) if (key == options::Options.Key.LeftFlipper)
{ {
MainTable->Message(1001, time_now); MainTable->Message(1001, time_now);
} }
else if (key == options::Options.RightFlipperKey) else if (key == options::Options.Key.RightFlipper)
{ {
MainTable->Message(1003, time_now); MainTable->Message(1003, time_now);
} }
else if (key == options::Options.PlungerKey) else if (key == options::Options.Key.Plunger)
{ {
MainTable->Message(1005, time_now); MainTable->Message(1005, time_now);
} }
else if (key == options::Options.LeftTableBumpKey) else if (key == options::Options.Key.LeftTableBump)
{ {
nudge::un_nudge_right(0, nullptr); nudge::un_nudge_right(0, nullptr);
} }
else if (key == options::Options.RightTableBumpKey) else if (key == options::Options.Key.RightTableBump)
{ {
nudge::un_nudge_left(0, nullptr); nudge::un_nudge_left(0, nullptr);
} }
else if (key == options::Options.BottomTableBumpKey) else if (key == options::Options.Key.BottomTableBump)
{ {
nudge::un_nudge_up(0, nullptr); nudge::un_nudge_up(0, nullptr);
} }
@ -394,6 +394,7 @@ void pb::keyup(int key)
void pb::keydown(int key) void pb::keydown(int key)
{ {
options::KeyDown(key);
if (winmain::single_step || demo_mode) if (winmain::single_step || demo_mode)
return; return;
if (game_mode != 1) if (game_mode != 1)
@ -402,35 +403,35 @@ void pb::keydown(int key)
return; return;
} }
control::pbctrl_bdoor_controller(key); control::pbctrl_bdoor_controller(key);
if (key == options::Options.LeftFlipperKey) if (key == options::Options.Key.LeftFlipper)
{ {
MainTable->Message(1000, time_now); MainTable->Message(1000, time_now);
return; return;
} }
if (key == options::Options.RightFlipperKey) if (key == options::Options.Key.RightFlipper)
{ {
MainTable->Message(1002, time_now); MainTable->Message(1002, time_now);
} }
else else
{ {
if (key == options::Options.PlungerKey) if (key == options::Options.Key.Plunger)
{ {
MainTable->Message(1004, time_now); MainTable->Message(1004, time_now);
return; return;
} }
if (key == options::Options.LeftTableBumpKey) if (key == options::Options.Key.LeftTableBump)
{ {
if (!MainTable->TiltLockFlag) if (!MainTable->TiltLockFlag)
nudge::nudge_right(); nudge::nudge_right();
return; return;
} }
if (key == options::Options.RightTableBumpKey) if (key == options::Options.Key.RightTableBump)
{ {
if (!MainTable->TiltLockFlag) if (!MainTable->TiltLockFlag)
nudge::nudge_left(); nudge::nudge_left();
return; return;
} }
if (key == options::Options.BottomTableBumpKey) if (key == options::Options.Key.BottomTableBump)
{ {
if (!MainTable->TiltLockFlag) if (!MainTable->TiltLockFlag)
nudge::nudge_up(); nudge::nudge_up();

View File

@ -324,8 +324,8 @@ void winmain::RenderUi()
} }
ImGui::PopStyleColor(1); ImGui::PopStyleColor(1);
ImGui::PopID(); ImGui::PopID();
ImGui::End();
} }
ImGui::End();
ImGui::PopStyleVar(); ImGui::PopStyleVar();
return; return;
} }
@ -424,7 +424,7 @@ void winmain::RenderUi()
{ {
if (!single_step) if (!single_step)
pause(); pause();
options::keyboard(); options::ShowControlDialog();
} }
if (ImGui::BeginMenu("Table Resolution")) if (ImGui::BeginMenu("Table Resolution"))
{ {
@ -524,6 +524,7 @@ void winmain::RenderUi()
high_score::RenderHighScoreDialog(); high_score::RenderHighScoreDialog();
if (ShowSpriteViewer) if (ShowSpriteViewer)
render::SpriteViewer(&ShowSpriteViewer); render::SpriteViewer(&ShowSpriteViewer);
options::RenderControlDialog();
} }
int winmain::event_handler(const SDL_Event* event) int winmain::event_handler(const SDL_Event* event)
@ -598,7 +599,7 @@ int winmain::event_handler(const SDL_Event* event)
case SDLK_F8: case SDLK_F8:
if (!single_step) if (!single_step)
pause(); pause();
options::keyboard(); options::ShowControlDialog();
break; break;
case SDLK_F9: case SDLK_F9:
options::toggle(Menu1::Show_Menu); options::toggle(Menu1::Show_Menu);
@ -644,14 +645,14 @@ int winmain::event_handler(const SDL_Event* event)
SDL_SetWindowGrab(MainWindow, SDL_TRUE); SDL_SetWindowGrab(MainWindow, SDL_TRUE);
} }
else else
pb::keydown(options::Options.LeftFlipperKey); pb::keydown(options::Options.Key.LeftFlipper);
break; break;
case SDL_BUTTON_RIGHT: case SDL_BUTTON_RIGHT:
if (!pb::cheat_mode) if (!pb::cheat_mode)
pb::keydown(options::Options.RightFlipperKey); pb::keydown(options::Options.Key.RightFlipper);
break; break;
case SDL_BUTTON_MIDDLE: case SDL_BUTTON_MIDDLE:
pb::keydown(options::Options.PlungerKey); pb::keydown(options::Options.Key.Plunger);
break; break;
default: default:
break; break;
@ -668,14 +669,14 @@ int winmain::event_handler(const SDL_Event* event)
SDL_SetWindowGrab(MainWindow, SDL_FALSE); SDL_SetWindowGrab(MainWindow, SDL_FALSE);
} }
if (!pb::cheat_mode) if (!pb::cheat_mode)
pb::keyup(options::Options.LeftFlipperKey); pb::keyup(options::Options.Key.LeftFlipper);
break; break;
case SDL_BUTTON_RIGHT: case SDL_BUTTON_RIGHT:
if (!pb::cheat_mode) if (!pb::cheat_mode)
pb::keyup(options::Options.RightFlipperKey); pb::keyup(options::Options.Key.RightFlipper);
break; break;
case SDL_BUTTON_MIDDLE: case SDL_BUTTON_MIDDLE:
pb::keyup(options::Options.PlungerKey); pb::keyup(options::Options.Key.Plunger);
break; break;
default: default:
break; break;