From 4fa435f78409ad46a89b672582ac64a0f1105ada Mon Sep 17 00:00:00 2001 From: Misa Date: Sun, 18 Apr 2021 23:23:44 -0700 Subject: [PATCH] Separate pressing Enter to open map from pressing Enter to interact This is a lot of copy-pasted code, but a little bit of copy-pasting never hurt anyone... The keybind to interact with activity zones and teleporters is now separate from the keybind to open the map, or return to the editor from in-editor playtesting, or restart a time trial. The keybind is now E, and the default controller bind is X. No controller button prompts, but the game didn't have controller button prompts anyways, so whatever. Doing this now because if people's muscle memory are going to be broken by not being able to spam the map keybind anymore, at least we can help a bit by changing the keybind so they can keep spamming it - their muscle memory is going to be broken anyways. This option has to be enabled by going to the speedrunner menu options and selecting "interact button". It is disabled by default. All prompt text needs to be string-interpolated every time they are drawn, because it is possible for people to change which interact button they use in the middle of gameplay, via the in-game options. Closes #736. --- desktop_version/src/Entity.cpp | 52 ++++---- desktop_version/src/Game.cpp | 42 ++++++- desktop_version/src/Game.h | 5 +- desktop_version/src/Input.cpp | 211 ++++++++++++++++++++++++++------- desktop_version/src/KeyPoll.h | 1 + desktop_version/src/Render.cpp | 123 +++++++++++++++---- desktop_version/src/editor.cpp | 1 + 7 files changed, 337 insertions(+), 98 deletions(-) diff --git a/desktop_version/src/Entity.cpp b/desktop_version/src/Entity.cpp index a627790b..aabec8a8 100644 --- a/desktop_version/src/Entity.cpp +++ b/desktop_version/src/Entity.cpp @@ -838,151 +838,151 @@ void entityclass::createblock( int t, int xp, int yp, int w, int h, int trig /*= switch(trig) { case 0: //testing zone - block.prompt = "Press ENTER to explode"; + block.prompt = "Press %s to explode"; block.script = "intro"; block.setblockcolour("orange"); trig=1; break; case 1: - block.prompt = "Press ENTER to talk to Violet"; + block.prompt = "Press %s to talk to Violet"; block.script = "talkpurple"; block.setblockcolour("purple"); trig=0; break; case 2: - block.prompt = "Press ENTER to talk to Vitellary"; + block.prompt = "Press %s to talk to Vitellary"; block.script = "talkyellow"; block.setblockcolour("yellow"); trig=0; break; case 3: - block.prompt = "Press ENTER to talk to Vermilion"; + block.prompt = "Press %s to talk to Vermilion"; block.script = "talkred"; block.setblockcolour("red"); trig=0; break; case 4: - block.prompt = "Press ENTER to talk to Verdigris"; + block.prompt = "Press %s to talk to Verdigris"; block.script = "talkgreen"; block.setblockcolour("green"); trig=0; break; case 5: - block.prompt = "Press ENTER to talk to Victoria"; + block.prompt = "Press %s to talk to Victoria"; block.script = "talkblue"; block.setblockcolour("blue"); trig=0; break; case 6: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_station_1"; block.setblockcolour("orange"); trig=0; break; case 7: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_outside_1"; block.setblockcolour("orange"); trig=0; break; case 8: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_outside_2"; block.setblockcolour("orange"); trig=0; break; case 9: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_outside_3"; block.setblockcolour("orange"); trig=0; break; case 10: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_outside_4"; block.setblockcolour("orange"); trig=0; break; case 11: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_outside_5"; block.setblockcolour("orange"); trig=0; break; case 12: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_outside_6"; block.setblockcolour("orange"); trig=0; break; case 13: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_finallevel"; block.setblockcolour("orange"); trig=0; break; case 14: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_station_2"; block.setblockcolour("orange"); trig=0; break; case 15: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_station_3"; block.setblockcolour("orange"); trig=0; break; case 16: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_station_4"; block.setblockcolour("orange"); trig=0; break; case 17: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_warp_1"; block.setblockcolour("orange"); trig=0; break; case 18: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_warp_2"; block.setblockcolour("orange"); trig=0; break; case 19: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_lab_1"; block.setblockcolour("orange"); trig=0; break; case 20: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_lab_2"; block.setblockcolour("orange"); trig=0; break; case 21: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_secretlab"; block.setblockcolour("orange"); trig=0; break; case 22: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_shipcomputer"; block.setblockcolour("orange"); trig=0; break; case 23: - block.prompt = "Press ENTER to activate terminals"; + block.prompt = "Press %s to activate terminals"; block.script = "terminal_radio"; block.setblockcolour("orange"); trig=0; break; case 24: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "terminal_jukebox"; block.setblockcolour("orange"); trig=0; @@ -1048,7 +1048,7 @@ void entityclass::createblock( int t, int xp, int yp, int w, int h, int trig /*= trig=0; break; case 35: - block.prompt = "Press ENTER to activate terminal"; + block.prompt = "Press %s to activate terminal"; block.script = "custom_"+customscript; block.setblockcolour("orange"); trig=0; diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index 0c85574f..2c00a7b3 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -131,8 +131,14 @@ void Game::init(void) tapleft = 0; tapright = 0; - press_right = 0; - press_left = 0; + press_right = false; + press_left = false; + press_action = false; + press_map = false; + press_interact = false; + interactheld = false; + separate_interact = false; + mapheld = false; pausescript = false; @@ -4102,6 +4108,7 @@ void Game::deserializesettings(tinyxml2::XMLElement* dataNode, ScreenSettings* s controllerButton_map.clear(); controllerButton_esc.clear(); controllerButton_restart.clear(); + controllerButton_interact.clear(); for (tinyxml2::XMLElement* pElem = dataNode; pElem != NULL; @@ -4230,6 +4237,11 @@ void Game::deserializesettings(tinyxml2::XMLElement* dataNode, ScreenSettings* s music.user_sound_volume = help.Int(pText); } + if (SDL_strcmp(pKey, "separate_interact") == 0) + { + separate_interact = help.Int(pText); + } + if (SDL_strcmp(pKey, "flipButton") == 0) { SDL_GameControllerButton newButton; @@ -4266,6 +4278,15 @@ void Game::deserializesettings(tinyxml2::XMLElement* dataNode, ScreenSettings* s } } + if (SDL_strcmp(pKey, "interactButton") == 0) + { + SDL_GameControllerButton newButton; + if (GetButtonFromString(pText, &newButton)) + { + controllerButton_interact.push_back(newButton); + } + } + if (SDL_strcmp(pKey, "controllerSensitivity") == 0) { key.sensitivity = help.Int(pText); @@ -4289,6 +4310,10 @@ void Game::deserializesettings(tinyxml2::XMLElement* dataNode, ScreenSettings* s { controllerButton_restart.push_back(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); } + if (controllerButton_interact.size() < 1) + { + controllerButton_interact.push_back(SDL_CONTROLLER_BUTTON_X); + } } bool Game::savestats(void) @@ -4454,6 +4479,8 @@ void Game::serializesettings(tinyxml2::XMLElement* dataNode, const ScreenSetting xml::update_tag(dataNode, "soundvolume", music.user_sound_volume); + xml::update_tag(dataNode, "separate_interact", (int) separate_interact); + // Delete all controller buttons we had previously. // dataNode->FirstChildElement() shouldn't be NULL at this point... // we've already added a bunch of elements @@ -4466,7 +4493,8 @@ void Game::serializesettings(tinyxml2::XMLElement* dataNode, const ScreenSetting if (SDL_strcmp(name, "flipButton") == 0 || SDL_strcmp(name, "enterButton") == 0 || SDL_strcmp(name, "escButton") == 0 - || SDL_strcmp(name, "restartButton") == 0) + || SDL_strcmp(name, "restartButton") == 0 + || SDL_strcmp(name, "interactButton") == 0) { // Can't just doc.DeleteNode(element) and then go to next, // element->NextSiblingElement() will be NULL. @@ -4508,6 +4536,12 @@ void Game::serializesettings(tinyxml2::XMLElement* dataNode, const ScreenSetting msg->LinkEndChild(doc.NewText(help.String((int) controllerButton_restart[i]).c_str())); dataNode->LinkEndChild(msg); } + for (size_t i = 0; i < controllerButton_interact.size(); i += 1) + { + tinyxml2::XMLElement* msg = doc.NewElement("interactButton"); + msg->LinkEndChild(doc.NewText(help.String((int) controllerButton_interact[i]).c_str())); + dataNode->LinkEndChild(msg); + } xml::update_tag(dataNode, "controllerSensitivity", key.sensitivity); } @@ -6045,6 +6079,7 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) case Menu::speedrunneroptions: option("glitchrunner mode"); option("input delay"); + option("interact button"); option("fake load screen"); option("return"); menuyoff = 0; @@ -6087,6 +6122,7 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) option("bind enter"); option("bind menu"); option("bind restart"); + option("bind interact"); option("return"); menuyoff = 0; maxspacing = 10; diff --git a/desktop_version/src/Game.h b/desktop_version/src/Game.h index 2c05e201..bfe41fb0 100644 --- a/desktop_version/src/Game.h +++ b/desktop_version/src/Game.h @@ -392,7 +392,9 @@ public: int activeactivity, act_fade; int prev_act_fade; - bool press_left, press_right, press_action, press_map; + bool press_left, press_right, press_action, press_map, press_interact; + bool interactheld; + bool separate_interact; //Some stats: int totalflips; @@ -422,6 +424,7 @@ public: std::vector controllerButton_flip; std::vector controllerButton_esc; std::vector controllerButton_restart; + std::vector controllerButton_interact; bool skipfakeload; bool ghostsenabled; diff --git a/desktop_version/src/Input.cpp b/desktop_version/src/Input.cpp index 54c9965d..b9027b39 100644 --- a/desktop_version/src/Input.cpp +++ b/desktop_version/src/Input.cpp @@ -24,9 +24,12 @@ static void updatebuttonmappings(int bind) if (key.isDown(i)) { bool dupe = false; - if (bind == 1) + switch (bind) { - for (size_t j = 0; j < game.controllerButton_flip.size(); j += 1) + case 1: + { + size_t j; + for (j = 0; j < game.controllerButton_flip.size(); j += 1) { if (i == game.controllerButton_flip[j]) { @@ -38,31 +41,40 @@ static void updatebuttonmappings(int bind) game.controllerButton_flip.push_back(i); music.playef(11); } - for (size_t j = 0; j < game.controllerButton_map.size(); j += 1) + for (j = 0; j < game.controllerButton_map.size(); j += 1) { if (i == game.controllerButton_map[j]) { game.controllerButton_map.erase(game.controllerButton_map.begin() + j); } } - for (size_t j = 0; j < game.controllerButton_esc.size(); j += 1) + for (j = 0; j < game.controllerButton_esc.size(); j += 1) { if (i == game.controllerButton_esc[j]) { game.controllerButton_esc.erase(game.controllerButton_esc.begin() + j); } } - for (size_t j = 0; j < game.controllerButton_restart.size(); j += 1) + for (j = 0; j < game.controllerButton_restart.size(); j += 1) { if (i == game.controllerButton_restart[j]) { game.controllerButton_restart.erase(game.controllerButton_restart.begin() + j); } } + for (j = 0; j < game.controllerButton_interact.size(); j += 1) + { + if (i == game.controllerButton_interact[j]) + { + game.controllerButton_interact.erase(game.controllerButton_interact.begin() + j); + } + } + break; } - if (bind == 2) + case 2: { - for (size_t j = 0; j < game.controllerButton_map.size(); j += 1) + size_t j; + for (j = 0; j < game.controllerButton_map.size(); j += 1) { if (i == game.controllerButton_map[j]) { @@ -74,31 +86,40 @@ static void updatebuttonmappings(int bind) game.controllerButton_map.push_back(i); music.playef(11); } - for (size_t j = 0; j < game.controllerButton_flip.size(); j += 1) + for (j = 0; j < game.controllerButton_flip.size(); j += 1) { if (i == game.controllerButton_flip[j]) { game.controllerButton_flip.erase(game.controllerButton_flip.begin() + j); } } - for (size_t j = 0; j < game.controllerButton_esc.size(); j += 1) + for (j = 0; j < game.controllerButton_esc.size(); j += 1) { if (i == game.controllerButton_esc[j]) { game.controllerButton_esc.erase(game.controllerButton_esc.begin() + j); } } - for (size_t j = 0; j < game.controllerButton_restart.size(); j += 1) + for (j = 0; j < game.controllerButton_restart.size(); j += 1) { if (i == game.controllerButton_restart[j]) { game.controllerButton_restart.erase(game.controllerButton_restart.begin() + j); } } + for (j = 0; j < game.controllerButton_interact.size(); j += 1) + { + if (i == game.controllerButton_interact[j]) + { + game.controllerButton_interact.erase(game.controllerButton_interact.begin() + j); + } + } + break; } - if (bind == 3) + case 3: { - for (size_t j = 0; j < game.controllerButton_esc.size(); j += 1) + size_t j; + for (j = 0; j < game.controllerButton_esc.size(); j += 1) { if (i == game.controllerButton_esc[j]) { @@ -110,31 +131,40 @@ static void updatebuttonmappings(int bind) game.controllerButton_esc.push_back(i); music.playef(11); } - for (size_t j = 0; j < game.controllerButton_flip.size(); j += 1) + for (j = 0; j < game.controllerButton_flip.size(); j += 1) { if (i == game.controllerButton_flip[j]) { game.controllerButton_flip.erase(game.controllerButton_flip.begin() + j); } } - for (size_t j = 0; j < game.controllerButton_map.size(); j += 1) + for (j = 0; j < game.controllerButton_map.size(); j += 1) { if (i == game.controllerButton_map[j]) { game.controllerButton_map.erase(game.controllerButton_map.begin() + j); } } - for (size_t j = 0; j < game.controllerButton_restart.size(); j += 1) + for (j = 0; j < game.controllerButton_restart.size(); j += 1) { if (i == game.controllerButton_restart[j]) { game.controllerButton_restart.erase(game.controllerButton_restart.begin() + j); } } + for (j = 0; j < game.controllerButton_interact.size(); j += 1) + { + if (i == game.controllerButton_interact[j]) + { + game.controllerButton_interact.erase(game.controllerButton_interact.begin() + j); + } + } + break; } - if (bind == 4) + case 4: { - for (size_t j = 0; j < game.controllerButton_restart.size(); j += 1) + size_t j; + for (j = 0; j < game.controllerButton_restart.size(); j += 1) { if (i == game.controllerButton_restart[j]) { @@ -146,27 +176,82 @@ static void updatebuttonmappings(int bind) game.controllerButton_restart.push_back(i); music.playef(11); } - for (size_t j = 0; j < game.controllerButton_flip.size(); j += 1) + for (j = 0; j < game.controllerButton_flip.size(); j += 1) { if (i == game.controllerButton_flip[j]) { game.controllerButton_flip.erase(game.controllerButton_flip.begin() + j); } } - for (size_t j = 0; j < game.controllerButton_map.size(); j += 1) + for (j = 0; j < game.controllerButton_map.size(); j += 1) { if (i == game.controllerButton_map[j]) { game.controllerButton_map.erase(game.controllerButton_map.begin() + j); } } - for (size_t j = 0; j < game.controllerButton_esc.size(); j += 1) + for (j = 0; j < game.controllerButton_esc.size(); j += 1) { if (i == game.controllerButton_esc[j]) { game.controllerButton_esc.erase(game.controllerButton_esc.begin() + j); } } + for (j = 0; j < game.controllerButton_interact.size(); j += 1) + { + if (i == game.controllerButton_interact[j]) + { + game.controllerButton_interact.erase(game.controllerButton_interact.begin() + j); + } + } + break; + } + case 5: + { + size_t j; + for (j = 0; j < game.controllerButton_interact.size(); j += 1) + { + if (i == game.controllerButton_interact[j]) + { + dupe = true; + } + } + if (!dupe) + { + game.controllerButton_interact.push_back(i); + music.playef(11); + } + for (j = 0; j < game.controllerButton_flip.size(); j += 1) + { + if (i == game.controllerButton_flip[j]) + { + game.controllerButton_flip.erase(game.controllerButton_flip.begin() + j); + } + } + for (j = 0; j < game.controllerButton_map.size(); j += 1) + { + if (i == game.controllerButton_map[j]) + { + game.controllerButton_map.erase(game.controllerButton_map.begin() + j); + } + } + for (j = 0; j < game.controllerButton_esc.size(); j += 1) + { + if (i == game.controllerButton_esc[j]) + { + game.controllerButton_esc.erase(game.controllerButton_esc.begin() + j); + } + } + for (j = 0; j < game.controllerButton_restart.size(); j += 1) + { + if (i == game.controllerButton_restart[j]) + { + game.controllerButton_restart.erase(game.controllerButton_restart.begin() + j); + } + } + break; + } + } } } @@ -586,6 +671,12 @@ static void menuactionpress(void) game.savestatsandsettings_menu(); break; case 2: + /* Interact button toggle */ + music.playef(11); + game.separate_interact = !game.separate_interact; + game.savestatsandsettings_menu(); + break; + case 3: // toggle fake load screen game.skipfakeload = !game.skipfakeload; game.savestatsandsettings_menu(); @@ -1310,7 +1401,7 @@ static void menuactionpress(void) game.savestatsandsettings_menu(); break; - case 5: + case 6: music.playef(11); game.returnmenu(); map.nexttowercolour(); @@ -1628,6 +1719,7 @@ void titleinput(void) game.press_right = false; game.press_action = false; game.press_map = false; + game.press_interact = false; if (graphics.flipmode) { @@ -1744,7 +1836,7 @@ void titleinput(void) } if ( game.currentmenuname == Menu::controller && game.currentmenuoption > 0 && - game.currentmenuoption < 5 && + game.currentmenuoption < 6 && key.controllerButtonDown() ) { updatebuttonmappings(game.currentmenuoption); @@ -1777,6 +1869,7 @@ void gameinput(void) game.press_left = false; game.press_right = false; game.press_action = false; + game.press_interact = false; if (key.isDown(KEYBOARD_LEFT) || key.isDown(KEYBOARD_a) || key.controllerWantsLeft(false)) { @@ -1790,7 +1883,12 @@ void gameinput(void) || key.isDown(KEYBOARD_UP) || key.isDown(KEYBOARD_DOWN) || key.isDown(KEYBOARD_w) || key.isDown(KEYBOARD_s)|| key.isDown(game.controllerButton_flip)) { game.press_action = true; - }; + } + + if (key.isDown(KEYBOARD_e) || key.isDown(game.controllerButton_interact)) + { + game.press_interact = true; + } } game.press_map = false; @@ -1838,6 +1936,11 @@ void gameinput(void) game.mapheld = false; } + if (!game.press_interact) + { + game.interactheld = false; + } + if (game.intimetrial && graphics.fademode == 1 && game.quickrestartkludge) { //restart the time trial @@ -1849,17 +1952,12 @@ void gameinput(void) //Returning to editor mode must always be possible #if !defined(NO_CUSTOM_LEVELS) - if(map.custommode && !map.custommodeforreal){ - if ((game.press_map || key.isDown(27)) && !game.mapheld){ - //Return to level editor - if (INBOUNDS_VEC(game.activeactivity, obj.blocks) && game.press_map){ - //pass, let code block below handle it - }else if(game.activetele && game.readytotele > 20 && game.press_map){ - //pass, let code block below handle it - }else{ - game.returntoeditor(); - game.mapheld = true; - } + if (map.custommode && !map.custommodeforreal) + { + if ((game.press_map || key.isDown(27)) && !game.mapheld) + { + game.returntoeditor(); + game.mapheld = true; } } #endif @@ -1868,6 +1966,15 @@ void gameinput(void) bool has_control = false; bool enter_pressed = game.press_map && !game.mapheld; bool enter_already_processed = false; + bool interact_pressed; + if (game.separate_interact) + { + interact_pressed = game.press_interact && !game.interactheld; + } + else + { + interact_pressed = enter_pressed; + } for (size_t ie = 0; ie < obj.entities.size(); ++ie) { if (obj.entities[ie].rule == 0) @@ -1875,12 +1982,16 @@ void gameinput(void) if (game.hascontrol && game.deathseq == -1 && game.lifeseq <= 5) { has_control = true; - if (enter_pressed) + if (interact_pressed) { - game.mapheld = true; + game.interactheld = true; + if (!game.separate_interact) + { + game.mapheld = true; + } } - if (enter_pressed && !script.running) + if (interact_pressed && !script.running) { if (game.activetele && game.readytotele > 20 && !game.intimetrial) { @@ -2058,9 +2169,10 @@ void gameinput(void) } } - // Continuation of Enter processing. The rest of the if-tree runs only if - // enter_pressed && !enter_already_pressed - if (!enter_pressed || enter_already_processed) + /* The rest of the if-tree runs only if enter is pressed and it has not + * already been processed with 'separate interact' off. + */ + if (!enter_pressed || (enter_already_processed && !game.separate_interact)) { // Do nothing } @@ -2135,6 +2247,7 @@ void mapinput(void) game.press_right = false; game.press_action = false; game.press_map = false; + game.press_interact = false; if (game.glitchrunnermode && graphics.fademode == 1 && graphics.menuoffset == 0) { @@ -2441,6 +2554,7 @@ void teleporterinput(void) game.press_right = false; game.press_action = false; game.press_map = false; + game.press_interact = false; if(graphics.menuoffset==0) { @@ -2448,10 +2562,17 @@ void teleporterinput(void) if (key.isDown(KEYBOARD_RIGHT) || key.isDown(KEYBOARD_d)|| key.controllerWantsRight(false) ) game.press_right = true; if (key.isDown(KEYBOARD_z) || key.isDown(KEYBOARD_SPACE) || key.isDown(KEYBOARD_v) || key.isDown(KEYBOARD_UP) || key.isDown(KEYBOARD_DOWN)|| key.isDown(KEYBOARD_w)|| key.isDown(KEYBOARD_s) || key.isDown(game.controllerButton_flip)) game.press_action = true; - if (key.isDown(KEYBOARD_ENTER) || key.isDown(game.controllerButton_map)) game.press_map = true; + if (!game.separate_interact && (key.isDown(KEYBOARD_ENTER) || key.isDown(game.controllerButton_map))) + { + game.press_map = true; + } + if (key.isDown(KEYBOARD_e) || key.isDown(game.controllerButton_interact)) + { + game.press_interact = true; + } //In the menu system, all keypresses are single taps rather than holds. Therefore this test has to be done for all presses - if (!game.press_action && !game.press_left && !game.press_right) game.jumpheld = false; + if (!game.press_action && !game.press_left && !game.press_right && !game.press_interact) game.jumpheld = false; if (!game.press_map) game.mapheld = false; if (key.isDown(27)) @@ -2478,7 +2599,7 @@ void teleporterinput(void) if (!game.jumpheld) { - if (game.press_action || game.press_left || game.press_right || game.press_map) + if (game.press_action || game.press_left || game.press_right || game.press_map || game.press_interact) { game.jumpheld = true; } @@ -2521,7 +2642,7 @@ void teleporterinput(void) while (!map.isexplored(tempx, tempy)); } - if (game.press_map) + if ((game.separate_interact && game.press_interact) || game.press_map) { tempx = map.teleporters[game.teleport_to_teleporter].x; tempy = map.teleporters[game.teleport_to_teleporter].y; @@ -2568,6 +2689,7 @@ void gamecompleteinput(void) game.press_right = false; game.press_action = false; game.press_map = false; + game.press_interact = false; //Do this before we update map.bypos if (!game.colourblindmode) @@ -2617,6 +2739,7 @@ void gamecompleteinput2(void) game.press_right = false; game.press_action = false; game.press_map = false; + game.press_interact = false; //Do this here because input comes first game.oldcreditposx = game.creditposx; diff --git a/desktop_version/src/KeyPoll.h b/desktop_version/src/KeyPoll.h index 1af5ed9c..038218ba 100644 --- a/desktop_version/src/KeyPoll.h +++ b/desktop_version/src/KeyPoll.h @@ -19,6 +19,7 @@ enum Kybrd KEYBOARD_s = SDLK_s, KEYBOARD_a = SDLK_a, KEYBOARD_d = SDLK_d, + KEYBOARD_e = SDLK_e, KEYBOARD_m = SDLK_m, KEYBOARD_n = SDLK_n, diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp index 65eb655c..0dff1ee6 100644 --- a/desktop_version/src/Render.cpp +++ b/desktop_version/src/Render.cpp @@ -1,3 +1,5 @@ +#include + #include "Credits.h" #include "editor.h" #include "Entity.h" @@ -525,24 +527,24 @@ static void menurender(void) switch(key.sensitivity) { case 0: - graphics.Print( -1, 85, " Low Medium High", tr, tg, tb, true); - graphics.Print( -1, 95, "[]..................", tr, tg, tb, true); + graphics.Print( -1, 75, " Low Medium High", tr, tg, tb, true); + graphics.Print( -1, 85, "[]..................", tr, tg, tb, true); break; case 1: - graphics.Print( -1, 85, " Low Medium High", tr, tg, tb, true); - graphics.Print( -1, 95, ".....[].............", tr, tg, tb, true); + graphics.Print( -1, 75, " Low Medium High", tr, tg, tb, true); + graphics.Print( -1, 85, ".....[].............", tr, tg, tb, true); break; case 2: - graphics.Print( -1, 85, " Low Medium High", tr, tg, tb, true); - graphics.Print( -1, 95, ".........[].........", tr, tg, tb, true); + graphics.Print( -1, 75, " Low Medium High", tr, tg, tb, true); + graphics.Print( -1, 85, ".........[].........", tr, tg, tb, true); break; case 3: - graphics.Print( -1, 85, " Low Medium High", tr, tg, tb, true); - graphics.Print( -1, 95, ".............[].....", tr, tg, tb, true); + graphics.Print( -1, 75, " Low Medium High", tr, tg, tb, true); + graphics.Print( -1, 85, ".............[].....", tr, tg, tb, true); break; case 4: - graphics.Print( -1, 85, " Low Medium High", tr, tg, tb, true); - graphics.Print( -1, 95, "..................[]", tr, tg, tb, true); + graphics.Print( -1, 75, " Low Medium High", tr, tg, tb, true); + graphics.Print( -1, 85, "..................[]", tr, tg, tb, true); break; } break; @@ -550,10 +552,12 @@ static void menurender(void) case 2: case 3: case 4: - graphics.Print( -1, 85, "Flip is bound to: " + std::string(help.GCString(game.controllerButton_flip)) , tr, tg, tb, true); - graphics.Print( -1, 95, "Enter is bound to: " + std::string(help.GCString(game.controllerButton_map)), tr, tg, tb, true); - graphics.Print( -1, 105, "Menu is bound to: " + std::string(help.GCString(game.controllerButton_esc)) , tr, tg, tb, true); - graphics.Print( -1, 115, "Restart is bound to: " + std::string(help.GCString(game.controllerButton_restart)) , tr, tg, tb, true); + case 5: + graphics.Print( -1, 75, "Flip is bound to: " + std::string(help.GCString(game.controllerButton_flip)) , tr, tg, tb, true); + graphics.Print( -1, 85, "Enter is bound to: " + std::string(help.GCString(game.controllerButton_map)), tr, tg, tb, true); + graphics.Print( -1, 95, "Menu is bound to: " + std::string(help.GCString(game.controllerButton_esc)) , tr, tg, tb, true); + graphics.Print( -1, 105, "Restart is bound to: " + std::string(help.GCString(game.controllerButton_restart)) , tr, tg, tb, true); + graphics.Print( -1, 115, "Interact is bound to: " + std::string(help.GCString(game.controllerButton_interact)) , tr, tg, tb, true); break; } @@ -589,6 +593,29 @@ static void menurender(void) } break; case 2: + { + /* Screen width 40 chars, 4 per char */ + char buffer[160 + 1]; + const char* button; + + graphics.bigprint(-1, 30, "Interact Button", tr, tg, tb, true); + graphics.Print(-1, 65, "Toggle whether you interact", tr, tg, tb, true); + graphics.Print(-1, 75, "with prompts using ENTER or E.", tr, tg, tb, true); + + if (game.separate_interact) + { + button = "E"; + } + else + { + button = "ENTER"; + } + + SDL_snprintf(buffer, sizeof(buffer), "Interact button: %s", button); + graphics.Print(-1, 95, buffer, tr, tg, tb, true); + break; + } + case 3: graphics.bigprint(-1, 30, "Fake Load Screen", tr, tg, tb, true); if (game.skipfakeload) graphics.Print(-1, 65, "Fake loading screen is OFF", tr / 2, tg / 2, tb / 2, true); @@ -1530,6 +1557,35 @@ void gamecompleterender2(void) graphics.render(); } +static const char* interact_prompt( + char* buffer, + const size_t buffer_size, + const char* raw +) { + const char* string_fmt_loc = SDL_strstr(raw, "%s"); + const char* button; + + if (string_fmt_loc == NULL /* No "%s". */ + || string_fmt_loc != SDL_strchr(raw, '%') /* First "%" found is not "%s". */ + || SDL_strchr(&string_fmt_loc[1], '%') != NULL) /* Other "%" after "%s". */ + { + return raw; + } + + if (game.separate_interact) + { + button = "E"; + } + else + { + button = "ENTER"; + } + + SDL_snprintf(buffer, buffer_size, raw, button); + + return buffer; +} + void gamerender(void) { @@ -1632,15 +1688,17 @@ void gamerender(void) if (game.readytotele > 100 || game.oldreadytotele > 100) { + /* Screen width 40 chars, 4 per char */ + char buffer[160 + 1]; + static const char raw[] = "- Press %s to Teleport - "; + const char* final_string = interact_prompt( + buffer, + sizeof(buffer), + raw + ); int alpha = graphics.lerp(game.oldreadytotele, game.readytotele); - if(graphics.flipmode) - { - graphics.bprint(5, 20, "- Press ENTER to Teleport -", alpha - 20 - (help.glow / 2), alpha - 20 - (help.glow / 2), alpha, true); - } - else - { - graphics.bprint(5, 210, "- Press ENTER to Teleport -", alpha - 20 - (help.glow / 2), alpha - 20 - (help.glow / 2), alpha, true); - } + + graphics.bprint(5, graphics.flipmode ? 20 : 210, final_string, alpha - 20 - (help.glow / 2), alpha - 20 - (help.glow / 2), alpha, true); } if (game.swnmode) @@ -1827,8 +1885,16 @@ void gamerender(void) float act_alpha = graphics.lerp(game.prev_act_fade, game.act_fade) / 10.0f; if(game.act_fade>5 || game.prev_act_fade>5) { + /* Screen width 40 chars, 4 per char */ + char buffer[160 + 1]; + const char* final_string = interact_prompt( + buffer, + sizeof(buffer), + game.activity_lastprompt.c_str() + ); + graphics.drawtextbox(16, 4, 36, 3, game.activity_r*act_alpha, game.activity_g*act_alpha, game.activity_b*act_alpha); - graphics.Print(5, 12, game.activity_lastprompt, game.activity_r*act_alpha, game.activity_g*act_alpha, game.activity_b*act_alpha, true); + graphics.Print(5, 12, final_string, game.activity_r*act_alpha, game.activity_g*act_alpha, game.activity_b*act_alpha, true); } if (obj.trophytext > 0 || obj.oldtrophytext > 0) @@ -2707,9 +2773,18 @@ void teleporterrender(void) if (game.useteleporter) { + /* Screen width 40 chars, 4 per char */ + char buffer[160 + 1]; + static const char raw[] = "Press %s to Teleport"; + const char* final_string = interact_prompt( + buffer, + sizeof(buffer), + raw + ); + //Instructions! graphics.Print(5, 210, "Press Left/Right to choose a Teleporter", 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2), true); - graphics.Print(5, 225, "Press ENTER to Teleport", 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2), true); + graphics.Print(5, 225, final_string, 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2), true); } graphics.drawgui(); diff --git a/desktop_version/src/editor.cpp b/desktop_version/src/editor.cpp index 05f17b52..5397f84a 100644 --- a/desktop_version/src/editor.cpp +++ b/desktop_version/src/editor.cpp @@ -3995,6 +3995,7 @@ void editorinput(void) game.press_right = false; game.press_action = false; game.press_map = false; + game.press_interact = false; if (key.isDown(KEYBOARD_LEFT) || key.isDown(KEYBOARD_a) || key.controllerWantsLeft(false)) {