the countdown timer alert can now start sounding while dialogs are open
added a mechanism for generic monitoring of events::pump()
This commit is contained in:
parent
10386174d9
commit
c491f73077
13 changed files with 150 additions and 66 deletions
|
@ -7,7 +7,8 @@ Version 1.3.6+svn:
|
|||
* language and i18n:
|
||||
* updated translations: Danish, Japanese, Swedish
|
||||
* multiplayer:
|
||||
* improvements to the sound of the timer countdown
|
||||
* improvements to the sound of the countdown timer
|
||||
* the countdown timer alert can now start sounding while dialogs are open
|
||||
* unit descriptions are no longer evaluated for the recruitment checksum
|
||||
and thus avoiding an OOS error when different languages are used.
|
||||
The change is incompatible with older trunk versions fixes (bug #9472).
|
||||
|
|
|
@ -254,7 +254,7 @@ int dialog::show()
|
|||
//create the event context, remember to instruct any passed-in widgets to join it
|
||||
const events::event_context dialog_events_context;
|
||||
const dialog_manager manager;
|
||||
const events::resize_lock prevent_resizing;
|
||||
const resize_lock prevent_resizing;
|
||||
|
||||
//draw
|
||||
draw_frame();
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <vector>
|
||||
|
||||
#define ERR_GEN LOG_STREAM(err, general)
|
||||
#define INFO_GEN LOG_STREAM(info, general)
|
||||
|
||||
|
||||
unsigned input_blocker::instance_count = 0; //static initialization
|
||||
|
@ -39,20 +40,6 @@ namespace events
|
|||
|
||||
void raise_help_string_event(int mousex, int mousey);
|
||||
|
||||
namespace {
|
||||
int disallow_resize = 0;
|
||||
}
|
||||
|
||||
resize_lock::resize_lock()
|
||||
{
|
||||
++disallow_resize;
|
||||
}
|
||||
|
||||
resize_lock::~resize_lock()
|
||||
{
|
||||
--disallow_resize;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct context
|
||||
|
@ -149,8 +136,20 @@ void context::set_focus(const handler* ptr)
|
|||
//in that context. The current context is the one on the top of the stack
|
||||
std::deque<context> event_contexts;
|
||||
|
||||
std::vector<pump_monitor*> pump_monitors;
|
||||
|
||||
} //end anon namespace
|
||||
|
||||
pump_monitor::pump_monitor() {
|
||||
pump_monitors.push_back(this);
|
||||
}
|
||||
|
||||
pump_monitor::~pump_monitor() {
|
||||
pump_monitors.erase(
|
||||
std::remove(pump_monitors.begin(), pump_monitors.end(), this),
|
||||
pump_monitors.end());
|
||||
}
|
||||
|
||||
event_context::event_context()
|
||||
{
|
||||
event_contexts.push_back(context());
|
||||
|
@ -267,7 +266,7 @@ void pump()
|
|||
{
|
||||
SDL_PumpEvents();
|
||||
|
||||
static std::pair<int,int> resize_dimensions(0,0);
|
||||
pump_info info;
|
||||
|
||||
//used to keep track of double click events
|
||||
static int last_mouse_down = -1;
|
||||
|
@ -301,15 +300,8 @@ void pump()
|
|||
|
||||
case SDL_VIDEORESIZE: {
|
||||
const SDL_ResizeEvent* const resize = reinterpret_cast<SDL_ResizeEvent*>(&event);
|
||||
|
||||
if(resize->w < min_allowed_width || resize->h < min_allowed_height) {
|
||||
resize_dimensions.first = 0;
|
||||
resize_dimensions.second = 0;
|
||||
} else {
|
||||
resize_dimensions.first = resize->w;
|
||||
resize_dimensions.second = resize->h;
|
||||
}
|
||||
|
||||
info.resize_dimensions.first = resize->w;
|
||||
info.resize_dimensions.second = resize->h;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -329,8 +321,8 @@ void pump()
|
|||
static const int DoubleClickTime = 500;
|
||||
|
||||
static const int DoubleClickMaxMove = 3;
|
||||
const int current_ticks = ::SDL_GetTicks();
|
||||
if(last_mouse_down >= 0 && current_ticks - last_mouse_down < DoubleClickTime &&
|
||||
info.ticks = ::SDL_GetTicks();
|
||||
if(last_mouse_down >= 0 && info.ticks - last_mouse_down < DoubleClickTime &&
|
||||
abs(event.button.x - last_click_x) < DoubleClickMaxMove &&
|
||||
abs(event.button.y - last_click_y) < DoubleClickMaxMove) {
|
||||
SDL_UserEvent user_event;
|
||||
|
@ -341,7 +333,7 @@ void pump()
|
|||
::SDL_PushEvent(reinterpret_cast<SDL_Event*>(&user_event));
|
||||
}
|
||||
|
||||
last_mouse_down = current_ticks;
|
||||
last_mouse_down = info.ticks;
|
||||
last_click_x = event.button.x;
|
||||
last_click_y = event.button.y;
|
||||
}
|
||||
|
@ -374,14 +366,10 @@ void pump()
|
|||
}
|
||||
}
|
||||
|
||||
if(resize_dimensions.first > 0 && disallow_resize == 0) {
|
||||
preferences::set_resolution(resize_dimensions);
|
||||
resize_dimensions.first = 0;
|
||||
resize_dimensions.second = 0;
|
||||
//inform the pump monitors that an events::pump() has occurred
|
||||
for(size_t i1 = 0, i2 = pump_monitors.size(); i1 != i2 && i1 < pump_monitors.size(); ++i1) {
|
||||
pump_monitors[i1]->process(info);
|
||||
}
|
||||
|
||||
if (preferences::music_on())
|
||||
sound::think_about_music();
|
||||
}
|
||||
|
||||
void raise_process_event()
|
||||
|
|
|
@ -23,13 +23,6 @@
|
|||
namespace events
|
||||
{
|
||||
|
||||
//an object which prevents resizing of the screen occuring during
|
||||
//its lifetime.
|
||||
struct resize_lock {
|
||||
resize_lock();
|
||||
~resize_lock();
|
||||
};
|
||||
|
||||
//any classes that derive from this class will automatically
|
||||
//receive sdl events through the handle function for their lifetime,
|
||||
//while the event context they were created in is active.
|
||||
|
@ -86,6 +79,21 @@ struct event_context
|
|||
|
||||
//causes events to be dispatched to all handler objects.
|
||||
void pump();
|
||||
|
||||
struct pump_info {
|
||||
pump_info() : ticks(0) {}
|
||||
std::pair<int,int> resize_dimensions;
|
||||
int ticks; //0 if not calculated
|
||||
};
|
||||
|
||||
class pump_monitor {
|
||||
//pump_monitors receive notifcation after an events::pump() occurs
|
||||
public:
|
||||
pump_monitor();
|
||||
virtual ~pump_monitor();
|
||||
virtual void process(pump_info& info) = 0;
|
||||
};
|
||||
|
||||
int flush(Uint32 event_mask=SDL_ALLEVENTS);
|
||||
|
||||
void raise_process_event();
|
||||
|
|
|
@ -2674,7 +2674,7 @@ void show_help(display &disp, const section &toplevel_sec, const std::string sho
|
|||
{
|
||||
const events::event_context dialog_events_context;
|
||||
const gui::dialog_manager manager;
|
||||
const events::resize_lock prevent_resizing;
|
||||
const resize_lock prevent_resizing;
|
||||
|
||||
CVideo& screen = disp.video();
|
||||
surface const scr = screen.getSurface();
|
||||
|
|
|
@ -45,7 +45,7 @@ void show_intro(display &disp, const config& data, const config& level)
|
|||
LOG_NG << "showing intro sequence...\n";
|
||||
|
||||
//stop the screen being resized while we're in this function
|
||||
const events::resize_lock stop_resizing;
|
||||
const resize_lock stop_resizing;
|
||||
const events::event_context context;
|
||||
|
||||
bool showing = true;
|
||||
|
|
|
@ -86,7 +86,7 @@ bool default_map_generator::allow_user_config() const { return true; }
|
|||
|
||||
void default_map_generator::user_config(display& disp)
|
||||
{
|
||||
const events::resize_lock prevent_resizing;
|
||||
const resize_lock prevent_resizing;
|
||||
const events::event_context dialog_events_context;
|
||||
|
||||
CVideo& screen = disp.video();
|
||||
|
|
|
@ -38,9 +38,17 @@ playmp_controller::playmp_controller(const config& level, const game_data& gamei
|
|||
bool skip_replay)
|
||||
: playsingle_controller(level, gameinfo, state_of_game, ticks, num_turns, game_config, video, skip_replay)
|
||||
{
|
||||
beep_warning_time_ = 0;
|
||||
turn_data_ = NULL;
|
||||
}
|
||||
|
||||
playmp_controller::~playmp_controller() {
|
||||
//halt and cancel the countdown timer
|
||||
if(beep_warning_time_ < 0) {
|
||||
sound::stop_bell();
|
||||
}
|
||||
}
|
||||
|
||||
void playmp_controller::set_replay_last_turn(unsigned int turn){
|
||||
replay_last_turn_ = turn;
|
||||
}
|
||||
|
@ -62,7 +70,6 @@ void playmp_controller::shout(){
|
|||
}
|
||||
|
||||
void playmp_controller::play_side(const unsigned int team_index, bool save){
|
||||
beep_warning_time_ = 10000; //Starts beeping each second when time is less than this (millisec)
|
||||
do {
|
||||
player_type_changed_ = false;
|
||||
end_turn_ = false;
|
||||
|
@ -93,9 +100,6 @@ void playmp_controller::play_side(const unsigned int team_index, bool save){
|
|||
}
|
||||
}
|
||||
LOG_NG << "human finished turn...\n";
|
||||
if(beep_warning_time_ < 10000) {
|
||||
sound::stop_bell();
|
||||
}
|
||||
} else if(current_team().is_ai()) {
|
||||
play_ai_turn();
|
||||
} else if(current_team().is_network()) {
|
||||
|
@ -113,6 +117,43 @@ void playmp_controller::before_human_turn(bool save){
|
|||
turn_data_->replay_error().attach_handler(this);
|
||||
}
|
||||
|
||||
bool playmp_controller::counting_down() {
|
||||
return beep_warning_time_ > 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
const int WARNTIME = 10000; //start beeping when 10 seconds are left (10,000ms)
|
||||
int timer_refresh = 0;
|
||||
const int timer_refresh_rate = 50; //prevents calling SDL_GetTicks() too frequently
|
||||
}
|
||||
|
||||
//make sure we think about countdown even while dialogs are open
|
||||
void playmp_controller::process(events::pump_info &info) {
|
||||
if(playmp_controller::counting_down()) {
|
||||
if(info.ticks == 0) {
|
||||
if(++timer_refresh % timer_refresh_rate == 0) {
|
||||
playmp_controller::think_about_countdown(::SDL_GetTicks());
|
||||
}
|
||||
} else {
|
||||
playmp_controller::think_about_countdown(info.ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//check if it is time to start playing the timer warning
|
||||
void playmp_controller::think_about_countdown(int ticks) {
|
||||
if(ticks >= beep_warning_time_) {
|
||||
const bool bell_on = preferences::turn_bell();
|
||||
if(bell_on || preferences::sound_on() || preferences::UI_sound_on()) {
|
||||
preferences::set_turn_bell(true);
|
||||
sound::play_bell(game_config::sounds::timer_bell,
|
||||
WARNTIME - (ticks - beep_warning_time_));
|
||||
beep_warning_time_ = -1;
|
||||
preferences::set_turn_bell(bell_on);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void playmp_controller::play_human_turn(){
|
||||
int cur_ticks = SDL_GetTicks();
|
||||
|
||||
|
@ -148,19 +189,15 @@ void playmp_controller::play_human_turn(){
|
|||
if (new_time > 0 ){
|
||||
current_team().set_countdown_time(new_time);
|
||||
cur_ticks = ticks;
|
||||
if (current_team().countdown_time() <= beep_warning_time_){
|
||||
beep_warning_time_ = -1;
|
||||
const bool bell_on = preferences::turn_bell();
|
||||
if(bell_on || preferences::sound_on() || preferences::UI_sound_on()) {
|
||||
preferences::set_turn_bell(true);
|
||||
sound::play_bell(game_config::sounds::timer_bell, new_time);
|
||||
preferences::set_turn_bell(bell_on);
|
||||
}
|
||||
if(current_team().is_human() && !beep_warning_time_) {
|
||||
beep_warning_time_ = new_time - WARNTIME + ticks;
|
||||
}
|
||||
if(counting_down()) {
|
||||
think_about_countdown(ticks);
|
||||
}
|
||||
} else {
|
||||
// Clock time ended
|
||||
// If no turn bonus or action bonus -> defeat
|
||||
beep_warning_time_ = 10000;
|
||||
const int action_increment = lexical_cast_default<int>(level_["mp_countdown_action_bonus"],0);
|
||||
if ( lexical_cast_default<int>(level_["mp_countdown_turn_bonus"],0) == 0
|
||||
&& (action_increment == 0 || current_team().action_bonus_count() == 0)) {
|
||||
|
@ -216,10 +253,14 @@ void playmp_controller::after_human_turn(){
|
|||
|
||||
void playmp_controller::finish_side_turn(){
|
||||
play_controller::finish_side_turn();
|
||||
|
||||
//just in case due to an exception turn_data_ has not been deleted in after_human_turn
|
||||
if (turn_data_ != NULL){
|
||||
delete turn_data_;
|
||||
turn_data_ = NULL;
|
||||
delete turn_data_;
|
||||
turn_data_ = NULL;
|
||||
|
||||
//halt and cancel the countdown timer
|
||||
if(beep_warning_time_ < 0) {
|
||||
sound::stop_bell();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,15 +22,20 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
class playmp_controller : public playsingle_controller
|
||||
class playmp_controller : public playsingle_controller, public events::pump_monitor
|
||||
{
|
||||
public:
|
||||
playmp_controller(const config& level, const game_data& gameinfo, game_state& state_of_game,
|
||||
const int ticks, const int num_turns, const config& game_config, CVideo& video, bool skip_replay);
|
||||
~playmp_controller();
|
||||
|
||||
static unsigned int replay_last_turn() { return replay_last_turn_; }
|
||||
static void set_replay_last_turn(unsigned int turn);
|
||||
|
||||
bool counting_down();
|
||||
void think_about_countdown(int ticks);
|
||||
void process(events::pump_info &info);
|
||||
|
||||
protected:
|
||||
virtual void handle_generic_event(const std::string& name);
|
||||
|
||||
|
|
|
@ -319,7 +319,7 @@ bool compare_resolutions(const std::pair<int,int>& lhs, const std::pair<int,int>
|
|||
|
||||
bool show_video_mode_dialog(display& disp)
|
||||
{
|
||||
const events::resize_lock prevent_resizing;
|
||||
const resize_lock prevent_resizing;
|
||||
const events::event_context dialog_events_context;
|
||||
|
||||
CVideo& video = disp.video();
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
*/
|
||||
|
||||
#include "global.hpp"
|
||||
|
||||
#include "events.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "game_preferences.hpp"
|
||||
|
@ -463,6 +463,17 @@ void stop_UI_sound() {
|
|||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
class music_thinker : public events::pump_monitor {
|
||||
void process(events::pump_info &/*info*/) {
|
||||
if(preferences::music_on()) {
|
||||
think_about_music();
|
||||
}
|
||||
}
|
||||
};
|
||||
music_thinker mthink;
|
||||
}
|
||||
|
||||
void think_about_music(void)
|
||||
{
|
||||
if (!music_start_time) {
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "events.hpp"
|
||||
#include "font.hpp"
|
||||
#include "image.hpp"
|
||||
#include "log.hpp"
|
||||
#include "preferences_display.hpp"
|
||||
#include "video.hpp"
|
||||
|
||||
#define LOG_DP LOG_STREAM(info, display)
|
||||
|
@ -68,7 +70,28 @@ int main( int argc, char** argv )
|
|||
#endif
|
||||
|
||||
namespace {
|
||||
bool fullScreen = false;
|
||||
bool fullScreen = false;
|
||||
int disallow_resize = 0;
|
||||
class resize_monitor : public events::pump_monitor {
|
||||
void process(events::pump_info &info) {
|
||||
if(info.resize_dimensions.first >= min_allowed_width
|
||||
&& info.resize_dimensions.second >= min_allowed_height
|
||||
&& disallow_resize == 0) {
|
||||
preferences::set_resolution(info.resize_dimensions);
|
||||
}
|
||||
}
|
||||
};
|
||||
resize_monitor resize_mon;
|
||||
}
|
||||
|
||||
resize_lock::resize_lock()
|
||||
{
|
||||
++disallow_resize;
|
||||
}
|
||||
|
||||
resize_lock::~resize_lock()
|
||||
{
|
||||
--disallow_resize;
|
||||
}
|
||||
|
||||
static unsigned int get_flags(unsigned int flags)
|
||||
|
|
|
@ -134,4 +134,11 @@ private:
|
|||
bool unlock;
|
||||
};
|
||||
|
||||
//an object which prevents resizing of the screen occuring during
|
||||
//its lifetime.
|
||||
struct resize_lock {
|
||||
resize_lock();
|
||||
~resize_lock();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue