From 1f9a54de6a61953566955a1a1cbe3420fd6abfb7 Mon Sep 17 00:00:00 2001 From: ALONSO Laurent Date: Mon, 11 Oct 2021 15:55:32 +0200 Subject: [PATCH] game: try to fix some details: - always add help node in talk mode, - in shop/talk mode do no try to find a combat frame, ... - add a framerate_limiters in various loops of events, - try to improve the minimap update. --- src/game/boe.actions.cpp | 223 +++++++++++++++++++------------------- src/game/boe.dlgutil.cpp | 14 ++- src/game/boe.locutils.cpp | 10 +- src/game/boe.minimap.cpp | 6 + src/game/boe.specials.cpp | 3 + src/game/boe.startup.cpp | 9 +- src/game/boe.town.hpp | 4 +- src/game/boe.ui.cpp | 14 ++- 8 files changed, 157 insertions(+), 126 deletions(-) diff --git a/src/game/boe.actions.cpp b/src/game/boe.actions.cpp index a78ecc95..fcc37e90 100644 --- a/src/game/boe.actions.cpp +++ b/src/game/boe.actions.cpp @@ -1067,17 +1067,17 @@ bool handle_action(const sf::Event& event) { if(overall_mode != MODE_TALKING) return false; } - if(overall_mode == MODE_SHOPPING) { + else if(overall_mode == MODE_SHOPPING) { handle_shop_event(the_point); if(overall_mode != MODE_SHOPPING) return false; } - // Otherwise they're in a terrain view mode - location cur_loc = is_out() ? univ.party.out_loc : center; - auto button_hit = UI::toolbar.button_hit(mainPtr, the_point); + else { + location cur_loc = is_out() ? univ.party.out_loc : center; + auto button_hit = UI::toolbar.button_hit(mainPtr, the_point); - // MARK: Then, handle a button being hit. + // MARK: Then, handle a button being hit. switch(button_hit) { case TOOLBAR_NONE: break; case TOOLBAR_MAGE: case TOOLBAR_PRIEST: @@ -1154,122 +1154,123 @@ bool handle_action(const sf::Event& event) { break; } - // MARK: Begin: click in terrain - if(the_point.in(world_screen) && (is_out() || is_town() || is_combat())){ - int i = (the_point.x - 32) / 28; - int j = (the_point.y - 20) / 36; - location destination = cur_loc; + // MARK: Begin: click in terrain + if(the_point.in(world_screen) && (is_out() || is_town() || is_combat())){ + int i = (the_point.x - 32) / 28; + int j = (the_point.y - 20) / 36; + location destination = cur_loc; - // Check for quick look - if(right_button) { - previous_mode = overall_mode; - if(is_combat()) overall_mode = MODE_LOOK_COMBAT; - if(is_out()) overall_mode = MODE_LOOK_OUTDOORS; - if(is_town()) overall_mode = MODE_LOOK_TOWN; - } - - // Moving/pausing - if(overall_mode == MODE_OUTDOORS || overall_mode == MODE_TOWN || overall_mode == MODE_COMBAT) { - if((i == 4) & (j == 4)) handle_pause(did_something, need_redraw); - else { - cur_direction = get_cur_direction(the_point); - destination.x += cur_direction.x; - destination.y += cur_direction.y; - handle_move(destination, did_something, need_redraw, need_reprint); + // Check for quick look + if(right_button) { + previous_mode = overall_mode; + if(is_combat()) overall_mode = MODE_LOOK_COMBAT; + if(is_out()) overall_mode = MODE_LOOK_OUTDOORS; + if(is_town()) overall_mode = MODE_LOOK_TOWN; } - } - // Looking at something - else if(overall_mode == MODE_LOOK_OUTDOORS || overall_mode == MODE_LOOK_TOWN || overall_mode == MODE_LOOK_COMBAT) { - if(overall_mode == MODE_LOOK_OUTDOORS) destination = univ.party.out_loc; - destination.x = destination.x + i - 4; - destination.y = destination.y + j - 4; - handle_look(destination, need_redraw, need_reprint); - // If option/ctrl not pressed, looking done, so restore center - bool look_done = true; - if(sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt)) look_done = false; - if(sf::Keyboard::isKeyPressed(sf::Keyboard::RAlt)) look_done = false; - if(sf::Keyboard::isKeyPressed(sf::Keyboard::LControl)) look_done = false; - if(sf::Keyboard::isKeyPressed(sf::Keyboard::RControl)) look_done = false; - if(look_done) { - if(right_button) overall_mode = previous_mode; - else if(overall_mode == MODE_LOOK_COMBAT) { - overall_mode = MODE_COMBAT; - center = univ.current_pc().combat_pos; - pause(5); - need_redraw = true; + // Moving/pausing + if(overall_mode == MODE_OUTDOORS || overall_mode == MODE_TOWN || overall_mode == MODE_COMBAT) { + if((i == 4) & (j == 4)) handle_pause(did_something, need_redraw); + else { + cur_direction = get_cur_direction(the_point); + destination.x += cur_direction.x; + destination.y += cur_direction.y; + handle_move(destination, did_something, need_redraw, need_reprint); } - else if(overall_mode == MODE_LOOK_TOWN) { - overall_mode = MODE_TOWN; - center = univ.party.town_loc; - need_redraw = true; - } - else if(overall_mode == MODE_LOOK_OUTDOORS) - overall_mode = MODE_OUTDOORS; + } + + // Looking at something + else if(overall_mode == MODE_LOOK_OUTDOORS || overall_mode == MODE_LOOK_TOWN || overall_mode == MODE_LOOK_COMBAT) { + if(overall_mode == MODE_LOOK_OUTDOORS) destination = univ.party.out_loc; + destination.x = destination.x + i - 4; + destination.y = destination.y + j - 4; + handle_look(destination, need_redraw, need_reprint); + // If option/ctrl not pressed, looking done, so restore center + bool look_done = true; + if(sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt)) look_done = false; + if(sf::Keyboard::isKeyPressed(sf::Keyboard::RAlt)) look_done = false; + if(sf::Keyboard::isKeyPressed(sf::Keyboard::LControl)) look_done = false; + if(sf::Keyboard::isKeyPressed(sf::Keyboard::RControl)) look_done = false; + if(look_done) { + if(right_button) overall_mode = previous_mode; + else if(overall_mode == MODE_LOOK_COMBAT) { + overall_mode = MODE_COMBAT; + center = univ.current_pc().combat_pos; + pause(5); + need_redraw = true; + } + else if(overall_mode == MODE_LOOK_TOWN) { + overall_mode = MODE_TOWN; + center = univ.party.town_loc; + need_redraw = true; + } + else if(overall_mode == MODE_LOOK_OUTDOORS) + overall_mode = MODE_OUTDOORS; + } + } + + // Talking to someone + else if(overall_mode == MODE_TALK_TOWN) { + destination.x = destination.x + i - 4; + destination.y = destination.y + j - 4; + handle_talk(destination, did_something, need_redraw, need_reprint); + } + + // Targeting a space + else if(overall_mode == MODE_SPELL_TARGET || overall_mode == MODE_FIRING || overall_mode == MODE_THROWING || + overall_mode == MODE_FANCY_TARGET || overall_mode == MODE_TOWN_TARGET) { + destination = center; + destination.x += i - 4; + destination.y += j - 4; + handle_target_space(destination, did_something, need_redraw, need_reprint); + } + + // Dropping an item + else if(overall_mode == MODE_DROP_TOWN || overall_mode == MODE_DROP_COMBAT) { + destination.x += i - 4; + destination.y += j - 4; + handle_drop_item(destination, need_redraw); + } + + // Using a space + else if(overall_mode == MODE_USE_TOWN) { + destination.x += i - 4; + destination.y += j - 4; + handle_use_space(destination, did_something, need_redraw); + } + + // Bashing/lockpicking + else if(overall_mode == MODE_BASH_TOWN || overall_mode == MODE_PICK_TOWN) { + destination.x += i - 4; + destination.y += j - 4; + handle_bash_pick(destination, did_something, need_redraw, overall_mode == MODE_BASH_TOWN); } } - - // Talking to someone - else if(overall_mode == MODE_TALK_TOWN) { - destination.x = destination.x + i - 4; - destination.y = destination.y + j - 4; - handle_talk(destination, did_something, need_redraw, need_reprint); - } - - // Targeting a space - else if(overall_mode == MODE_SPELL_TARGET || overall_mode == MODE_FIRING || overall_mode == MODE_THROWING || - overall_mode == MODE_FANCY_TARGET || overall_mode == MODE_TOWN_TARGET) { - destination = center; - destination.x += i - 4; - destination.y += j - 4; - handle_target_space(destination, did_something, need_redraw, need_reprint); - } - - // Dropping an item - else if(overall_mode == MODE_DROP_TOWN || overall_mode == MODE_DROP_COMBAT) { - destination.x += i - 4; - destination.y += j - 4; - handle_drop_item(destination, need_redraw); - } - - // Using a space - else if(overall_mode == MODE_USE_TOWN) { - destination.x += i - 4; - destination.y += j - 4; - handle_use_space(destination, did_something, need_redraw); - } - - // Bashing/lockpicking - else if(overall_mode == MODE_BASH_TOWN || overall_mode == MODE_PICK_TOWN) { - destination.x += i - 4; - destination.y += j - 4; - handle_bash_pick(destination, did_something, need_redraw, overall_mode == MODE_BASH_TOWN); - } - } - // MARK: End: click in terrain + // MARK: End: click in terrain - // MARK: Begin: Screen shift - if(scrollableModes.count(overall_mode) && the_point.in(terrain_viewport) && !the_point.in(world_screen)) { - if(the_point.y < world_screen.top && center.y > univ.town->in_town_rect.top && center.y > 4) { - center.y--; - need_redraw = true; - } - if(the_point.x < world_screen.left && center.x > univ.town->in_town_rect.left && center.x > 4) { - center.x--; - need_redraw = true; - } - if(the_point.y > world_screen.bottom && center.y < univ.town->in_town_rect.bottom && center.y < univ.town->max_dim - 5) { - center.y++; - need_redraw = true; - } - if(the_point.x > world_screen.right && center.x < univ.town->in_town_rect.right && center.x < univ.town->max_dim - 5) { - center.x++; - need_redraw = true; + // MARK: Begin: Screen shift + if(scrollableModes.count(overall_mode) && the_point.in(terrain_viewport) && !the_point.in(world_screen)) { + if(the_point.y < world_screen.top && center.y > univ.town->in_town_rect.top && center.y > 4) { + center.y--; + need_redraw = true; + } + if(the_point.x < world_screen.left && center.x > univ.town->in_town_rect.left && center.x > 4) { + center.x--; + need_redraw = true; + } + if(the_point.y > world_screen.bottom && center.y < univ.town->in_town_rect.bottom && center.y < univ.town->max_dim - 5) { + center.y++; + need_redraw = true; + } + if(the_point.x > world_screen.right && center.x < univ.town->in_town_rect.right && center.x < univ.town->max_dim - 5) { + center.x++; + need_redraw = true; + } } + // MARK: End: Screen shift } - // MARK: End: Screen shift - + // MARK: Process clicks in PC stats area if(the_point.in(win_to_rects[WINRECT_PCSTATS])) { location pc_win_ul = win_to_rects[WINRECT_PCSTATS].topLeft(); diff --git a/src/game/boe.dlgutil.cpp b/src/game/boe.dlgutil.cpp index fb1d855c..8a0a398a 100644 --- a/src/game/boe.dlgutil.cpp +++ b/src/game/boe.dlgutil.cpp @@ -174,10 +174,6 @@ void end_shop_mode() { shop_sbar->hide(); done_btn->hide(); help_btn->hide(); - if(store_pre_shop_mode == MODE_TALKING) { - place_talk_str("You conclude your business.", "", 0, dummy_rect); - update_last_talk(TALK_BUSINESS); - } overall_mode = store_pre_shop_mode; if(overall_mode == MODE_TALK_TOWN) @@ -186,7 +182,15 @@ void end_shop_mode() { center = univ.party.town_loc; update_explored(center); } - stat_screen_mode = MODE_INVEN; + + if (overall_mode == MODE_TALKING) { + // fixme: there must be a function to reset the talking state correctly + place_talk_str("You conclude your business.", "", 0, dummy_rect); + stat_screen_mode = MODE_SHOP; + help_btn->show(); + } + else + stat_screen_mode = MODE_INVEN; put_item_screen(stat_window); put_pc_screen(); // TODO: I suspect REFRESH_NONE will suffice here diff --git a/src/game/boe.locutils.cpp b/src/game/boe.locutils.cpp index 89fbfb88..5bf2ebf0 100644 --- a/src/game/boe.locutils.cpp +++ b/src/game/boe.locutils.cpp @@ -607,10 +607,16 @@ void alter_space(short i,short j,ter_num_t ter) { location l(i,j); l = local_to_global(l); univ.out[l.x][l.y] = ter; - univ.out->terrain[i][j] = ter; + if (univ.out->terrain[i][j] != ter) { + univ.out->terrain[i][j] = ter; + minimap::draw(true); + } } else { ter_num_t former = univ.town->terrain(i,j); - univ.town->terrain(i,j) = ter; + if (former!=ter) { + univ.town->terrain(i,j) = ter; + minimap::draw(true); + } if(univ.scenario.ter_types[ter].special == eTerSpec::CONVEYOR) univ.town.belt_present = true; if(univ.scenario.ter_types[former].light_radius != univ.scenario.ter_types[ter].light_radius) diff --git a/src/game/boe.minimap.cpp b/src/game/boe.minimap.cpp index 55268761..f184512a 100644 --- a/src/game/boe.minimap.cpp +++ b/src/game/boe.minimap.cpp @@ -93,6 +93,9 @@ void set_visible(bool vis) windows.setVisible(true); visible = true; draw(true); + // when a game is loaded, the windows is not adapted correctly + // try to force a new refresh + changed = true; makeFrontWindow(mainPtr); set_cursor(sword_curs); @@ -354,6 +357,9 @@ bool pollEvent() makeFrontWindow(mainPtr); else if(event.type == sf::Event::KeyPressed) { switch(event.key.code) { + // checkme: the zone seems big enough + // but maybe we can check for arrows here to move + // in the zone case sf::Keyboard::Escape: set_visible(false); break; diff --git a/src/game/boe.specials.cpp b/src/game/boe.specials.cpp index d47a2c3d..70871fe7 100644 --- a/src/game/boe.specials.cpp +++ b/src/game/boe.specials.cpp @@ -9,6 +9,7 @@ #include "strdlog.hpp" #include "choicedlog.hpp" #include "fileio.hpp" +#include "framerate_limiter.hpp" #include "spell.hpp" #include "sounds.hpp" #include "universe.hpp" @@ -2006,9 +2007,11 @@ void run_special(eSpecCtx which_mode, eSpecCtxType which_type, spec_num_t start_ add_string_to_buf(debug); redraw_screen(REFRESH_TRANS); sf::Event evt; + cFramerateLimiter fps_limiter; while(true) { if(mainPtr.pollEvent(evt) && (evt.type == sf::Event::KeyPressed || evt.type == sf::Event::MouseButtonPressed)) break; + fps_limiter.frame_finished(); } if(evt.type == sf::Event::KeyPressed && evt.key.code == sf::Keyboard::Escape) univ.node_step_through = false; diff --git a/src/game/boe.startup.cpp b/src/game/boe.startup.cpp index b4bfbc4b..018a8f89 100644 --- a/src/game/boe.startup.cpp +++ b/src/game/boe.startup.cpp @@ -1,6 +1,7 @@ #include "boe.global.hpp" +#include "framerate_limiter.hpp" #include "universe.hpp" #include "boe.newgraph.hpp" #include "boe.graphics.hpp" @@ -124,15 +125,19 @@ void show_logo() { auto const &pict_to_draw = *ResMgr::textures.get("spidlogo", true); play_sound(-95); + cFramerateLimiter fps_limiter; while(sound_going(95)) { draw_splash(pict_to_draw, mainPtr, logo_from); handle_splash_events(); + fps_limiter.frame_finished(); } if(!get_int_pref("ShowStartupSplash", true)) { sf::Time delay = time_in_ticks(60); sf::Clock timer; - while(timer.getElapsedTime() < delay) + while(timer.getElapsedTime() < delay) { handle_splash_events(); + fps_limiter.frame_finished(); + } } } @@ -149,9 +154,11 @@ void plop_fancy_startup() { play_sound(-22); sf::Clock timer; + cFramerateLimiter fps_limiter; while(timer.getElapsedTime() < delay) { draw_splash(pict_to_draw, mainPtr, intro_from); handle_splash_events(); + fps_limiter.frame_finished(); } } diff --git a/src/game/boe.town.hpp b/src/game/boe.town.hpp index f1d853f2..73ce84f1 100644 --- a/src/game/boe.town.hpp +++ b/src/game/boe.town.hpp @@ -26,9 +26,7 @@ void erase_hidden_towns(cOutdoors& sector, int quadrant_x, int quadrant_y); void erase_completed_specials(cArea& sector, std::function clear_spot); void erase_out_specials(); bool does_location_have_special(cOutdoors& sector, location loc, eTerSpec type); -void clear_map(); -void draw_map(bool need_refresh); bool is_door(location destination); -void display_map(); + void check_done(); bool quadrant_legal(short i, short j) ; diff --git a/src/game/boe.ui.cpp b/src/game/boe.ui.cpp index a9625d63..515010bc 100644 --- a/src/game/boe.ui.cpp +++ b/src/game/boe.ui.cpp @@ -9,16 +9,19 @@ #include "boe.ui.hpp" #include + #include "enum_map.hpp" -#include "boe.consts.hpp" -#include "boe.locutils.hpp" -#include "boe.graphics.hpp" +#include "framerate_limiter.hpp" +#include "mathutil.hpp" #include "render_shapes.hpp" #include "render_image.hpp" #include "res_image.hpp" -#include "mathutil.hpp" #include "sounds.hpp" +#include "boe.consts.hpp" +#include "boe.locutils.hpp" +#include "boe.graphics.hpp" + namespace UI { cToolbar toolbar; } @@ -60,6 +63,7 @@ eToolbarButton cToolbar::button_hit(sf::RenderWindow& win, location click) { bool done = false, clicked = false; win.setActive(); active = i; + cFramerateLimiter fps_limiter; while(!done){ redraw_screen(REFRESH_NONE); while(win.pollEvent(e)) { @@ -79,6 +83,8 @@ eToolbarButton cToolbar::button_hit(sf::RenderWindow& win, location click) { active = toolbar[i].bounds.contains(toPos) ? i : -1; } } + if (!done) + fps_limiter.frame_finished(); } play_sound(37, time_in_ticks(5)); redraw_screen(REFRESH_NONE);