void widget::normalize_event(SDL_Event* event, bool translate_coords) { int tx, ty; //temp x, y switch(event->type) { case SDL_MOUSEMOTION: #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE event->motion.x = (event->motion.x*graphics::screen_width())/preferences::virtual_screen_width(); event->motion.y = (event->motion.y*graphics::screen_height())/preferences::virtual_screen_height(); #else event->motion.x = (event->motion.x*preferences::virtual_screen_width())/preferences::actual_screen_width(); event->motion.y = (event->motion.y*preferences::virtual_screen_height())/preferences::actual_screen_height(); #endif tx = event->motion.x; ty = event->motion.y; translate_mouse_coords(&tx, &ty); event->motion.x = tx-x(); event->motion.y = ty-y(); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE event->button.x = (event->button.x*graphics::screen_width())/preferences::virtual_screen_width(); event->button.y = (event->button.y*graphics::screen_height())/preferences::virtual_screen_height(); #else event->button.x = (event->button.x*preferences::virtual_screen_width())/preferences::actual_screen_width(); event->button.y = (event->button.y*preferences::virtual_screen_height())/preferences::actual_screen_height(); #endif tx = event->button.x; ty = event->button.y; translate_mouse_coords(&tx, &ty); event->button.x = tx-x(); event->button.y = ty-y(); break; default: break; } }
bool speech_dialog::handle_mouse_move(int x, int y) { translate_mouse_coords(&x, &y); rect box( preferences::virtual_screen_width() - OptionsX - option_width_ - OptionsBorder, preferences::virtual_screen_height() - OptionsY - OptionHeight*options_.size() - OptionsBorder, option_width_ + OptionsBorder*2, OptionHeight*options_.size() + OptionsBorder*2 ); //std::cerr << "Options box: " << box << " : " << x << " : " << y << "\n"; if (point_in_rect(point(x, y), box)) { option_selected_ = (y-box.y())/OptionHeight; return true; } else { option_selected_ = -1; return false; } }
void iphone_controls::handle_event (const SDL_Event& event) { int x = event.type == SDL_MOUSEMOTION ? event.motion.x : event.button.x; int y = event.type == SDL_MOUSEMOTION ? event.motion.y : event.button.y; int i = event.type == SDL_MOUSEMOTION ? event.motion.which : event.button.which; translate_mouse_coords(&x, &y); while(all_mice.size() <= i) { all_mice.push_back(Mouse()); all_mice[i].active = false; } if(!all_mice[i].active) { all_mice[i].starting_x = x; all_mice[i].starting_y = y; } all_mice[i].x = x; all_mice[i].y = y; all_mice[i].active = event.type != SDL_MOUSEBUTTONUP; }
void iphone_controls::read_controls() { active_mice.clear(); #if defined(TARGET_OS_HARMATTAN) || defined(TARGET_BLACKBERRY) || defined(__ANDROID__) // there is no SDL_Get_NumMice and SDL_SelectMouse support on // Harmattan, so all_mice has been updated via calls to handle_event const int nmice = all_mice.size(); #else const int nmice = SDL_GetNumMice(); if(all_mice.size() > nmice) { all_mice.resize(nmice); } for(int i = 0; i < nmice; i++) { int x, y; SDL_SelectMouse(i); Uint8 button_state = SDL_GetMouseState(&x, &y); translate_mouse_coords(&x, &y); if(all_mice.size() == i) { all_mice.push_back(Mouse()); all_mice[i].active = false; } if(!all_mice[i].active) { all_mice[i].starting_x = x; all_mice[i].starting_y = y; } all_mice[i].x = x; all_mice[i].y = y; all_mice[i].active = button_state & SDL_BUTTON(SDL_BUTTON_LEFT); } #endif for(int i = 0; i < nmice; i++) { if(all_mice[i].active) { active_mice.push_back(all_mice[i]); } } }
void iphone_controls::handle_event (const SDL_Event& event) { int x = event.type == SDL_JOYBALLMOTION ? event.jball.xrel : event.jbutton.x; int y = event.type == SDL_JOYBALLMOTION ? event.jball.yrel : event.jbutton.y; int i = event.type == SDL_JOYBALLMOTION ? event.jball.ball : event.jbutton.button; std::string joy_txt = event.type == SDL_JOYBUTTONUP ? "up" : event.type == SDL_JOYBUTTONDOWN ? "down" : "move"; LOG( "mouse " << joy_txt << " (" << x << "," << y << ";" << i << ")"); translate_mouse_coords(&x, &y); while(all_mice.size() <= i) { all_mice.push_back(Mouse()); all_mice[i].active = false; } if(!all_mice[i].active) { all_mice[i].starting_x = x; all_mice[i].starting_y = y; } all_mice[i].x = x; all_mice[i].y = y; all_mice[i].active = event.type != SDL_JOYBUTTONUP; }
variant playable_custom_object::get_player_value_by_slot(int slot) const { switch(slot) { case CUSTOM_OBJECT_PLAYER_DIFFICULTY: { if(preferences::force_difficulty() != INT_MIN) { return variant(preferences::force_difficulty()); } return variant(difficulty_); } case CUSTOM_OBJECT_PLAYER_CAN_INTERACT: { return variant(can_interact_); } case CUSTOM_OBJECT_PLAYER_UNDERWATER_CONTROLS: { return variant(underwater_controls_); } case CUSTOM_OBJECT_PLAYER_CTRL_MOD_KEY: { return variant(SDL_GetModState()); } case CUSTOM_OBJECT_PLAYER_CTRL_KEYS: { std::vector<variant> result; if(level_runner::get_current() && level_runner::get_current()->get_debug_console() && level_runner::get_current()->get_debug_console()->has_keyboard_focus()) { //the debug console is stealing all keystrokes. return variant(&result); } #if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR int ary_length; const Uint8* key_state = SDL_GetKeyboardState(&ary_length); #ifndef NO_EDITOR if(level_runner::get_current()) { const editor* e = level_runner::get_current()->get_editor(); if(e && e->has_keyboard_focus()) { //the editor has the focus, so we tell the game there //are no keys pressed. ary_length = 0; } } #endif for(int count = 0; count < ary_length; ++count) { if(key_state[count]) { //Returns only keys that are down so the list that ffl has to deal with is small. SDL_Keycode k = SDL_GetKeyFromScancode(SDL_Scancode(count)); if(k < 128 && util::c_isprint(k)) { std::string str(1,k); result.push_back(variant(str)); } else { result.push_back(variant(k)); } } } #endif return variant(&result); } case CUSTOM_OBJECT_PLAYER_CTRL_MICE: { std::vector<variant> result; #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR const int nmice = SDL_GetNumMice(); #else const int nmice = 1; #endif for(int n = 0; n != nmice; ++n) { #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR SDL_SelectMouse(n); #endif std::vector<variant> info; int x, y; Uint8 button_state = input::sdl_get_mouse_state(&x, &y); translate_mouse_coords(&x, &y); info.push_back(variant(x)); info.push_back(variant(y)); if(button_state & SDL_BUTTON(SDL_BUTTON_LEFT)) { info.push_back(variant("left")); } if(button_state & SDL_BUTTON(SDL_BUTTON_RIGHT)) { info.push_back(variant("right")); } if(button_state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) { info.push_back(variant("middle")); } if(button_state & SDL_BUTTON(SDL_BUTTON_X1)) { //these aren't tested info.push_back(variant("x1")); } if(button_state & SDL_BUTTON(SDL_BUTTON_X2)) { info.push_back(variant("x2")); } result.push_back(variant(&info)); } return variant(&result); } case CUSTOM_OBJECT_PLAYER_CTRL_TILT: { return variant(-joystick::iphone_tilt()); } case CUSTOM_OBJECT_PLAYER_CTRL_X: { return variant(underwater_ctrl_x_); } case CUSTOM_OBJECT_PLAYER_CTRL_Y: { return variant(underwater_ctrl_y_); } case CUSTOM_OBJECT_PLAYER_CTRL_REVERSE_AB: { return variant::from_bool(reverse_ab_); } case CUSTOM_OBJECT_PLAYER_CONTROL_SCHEME: { return variant(preferences::control_scheme()); } case CUSTOM_OBJECT_PLAYER_VERTICAL_LOOK: { return variant(vertical_look_); } case CUSTOM_OBJECT_PLAYER_CONTROL_LOCK: { std::vector<variant> result; const unsigned char* locked_control_frame = controls::get_local_control_lock(); if (locked_control_frame == nullptr) { return variant(); } for(int i = 0; i < 8; ++i){ if((*locked_control_frame & (0x01 << i)) ){ result.push_back( variant(ctrl[i]) ); } else { //this key isn't pressed } } return variant(&result); } } ASSERT_LOG(false, "unknown slot in get_player_value_by_slot: " << slot); }
bool key_button::in_button(int xloc, int yloc) const { translate_mouse_coords(&xloc, &yloc); return xloc > x() && xloc < x() + width() && yloc > y() && yloc < y() + height(); }
bool level_runner::handle_mouse_events(const SDL_Event &event) { static const int MouseDownEventID = get_object_event_id("mouse_down"); static const int MouseUpEventID = get_object_event_id("mouse_up"); static const int MouseMoveEventID = get_object_event_id("mouse_move"); static const int MouseDownEventAllID = get_object_event_id("mouse_down*"); static const int MouseUpEventAllID = get_object_event_id("mouse_up*"); static const int MouseMoveEventAllID = get_object_event_id("mouse_move*"); static const int MouseEnterID = get_object_event_id("mouse_enter"); static const int MouseLeaveID = get_object_event_id("mouse_leave"); static const int MouseClickID = get_object_event_id("click"); //static const int MouseDblClickID = get_object_event_id("dblclick"); static const int MouseDragID = get_object_event_id("drag"); static const int MouseDragStartID = get_object_event_id("drag_start"); static const int MouseDragEndID = get_object_event_id("drag_end"); if(paused) { // skip mouse event handling when paused. // XXX: when we become unpaused we need to reset the state of drag operations // and partial clicks. return false; } switch(event.type) { #if defined(__ANDROID__) case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: case SDL_JOYBALLMOTION: int x, mx = event.type == SDL_JOYBALLMOTION ? event.jball.xrel : event.jbutton.x; int y, my = event.type == SDL_JOYBALLMOTION ? event.jball.yrel : event.jbutton.y; int i = event.type == SDL_JOYBALLMOTION ? event.jball.ball : event.jbutton.button; int event_button_button = event.jbutton.button; int event_type = event.type == SDL_JOYBALLMOTION ? SDL_MOUSEMOTION : event.type == SDL_JOYBUTTONDOWN ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP; #else case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: case SDL_MOUSEMOTION: int x, mx = event.type == SDL_MOUSEMOTION ? event.motion.x : event.button.x; int y, my = event.type == SDL_MOUSEMOTION ? event.motion.y : event.button.y; int i = event.type == SDL_MOUSEMOTION ? event.motion.which : event.button.which; int event_type = event.type; int event_button_button = event.button.button; #endif #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE translate_mouse_coords(&x,&y); translate_mouse_coords(&mx,&my); //std::cerr << x << ", " << y << " x, y\n"; #endif const int basic_evt = event_type == SDL_MOUSEBUTTONDOWN ? MouseDownEventID : event_type == SDL_MOUSEMOTION ? MouseMoveEventID : MouseUpEventID; const int catch_all_event = event_type == SDL_MOUSEBUTTONDOWN ? MouseDownEventAllID : event_type == SDL_MOUSEMOTION ? MouseMoveEventAllID : MouseUpEventAllID; Uint8 button_state = SDL_GetMouseState(0,0); if(!lvl_->gui_event(event)) { x = (mx*graphics::screen_width())/preferences::virtual_screen_width() + last_draw_position().x/100; y = (my*graphics::screen_height())/preferences::virtual_screen_height() + last_draw_position().y/100; game_logic::map_formula_callable_ptr callable(new game_logic::map_formula_callable); callable->add("mouse_x", variant(x)); callable->add("mouse_y", variant(y)); callable->add("mouse_index", variant(i)); if(event_type != SDL_MOUSEMOTION) { callable->add("mouse_button", variant(event_button_button)); } else { callable->add("mouse_button", variant(button_state)); } std::vector<variant> items; // Grab characters around point, z-order sort them, so that when // we process them we go from highest to lowest, allowing a higher // object to swallow an event before the lower ones get it. std::vector<entity_ptr> cs = lvl_->get_characters_at_point(x, y, last_draw_position().x/100, last_draw_position().y/100); std::sort(cs.begin(), cs.end(), zorder_compare); std::vector<entity_ptr>::iterator it; bool handled = false; bool click_handled = false; std::set<entity_ptr> mouse_in; for(it = cs.begin(); it != cs.end(); ++it) { rect clip_area; // n.b. clip_area is in level coordinates, not relative to the object. if((*it)->get_clip_area(&clip_area)) { point p(x,y); if((*it)->use_absolute_screen_coordinates()) { p = point(mx,my); } if(point_in_rect(p, clip_area) == false) { continue; } } if(event_type == SDL_MOUSEBUTTONDOWN) { (*it)->set_mouse_buttons((*it)->get_mouse_buttons() | SDL_BUTTON(event_button_button)); } else if(event_type == SDL_MOUSEMOTION) { // handling for mouse_enter if((*it)->is_mouse_over_entity() == false) { (*it)->handle_event(MouseEnterID, callable.get()); (*it)->set_mouse_over_entity(); } mouse_in.insert(*it); } handled |= (*it)->handle_event(basic_evt, callable.get()); // XXX: fix this for dragging(with multiple mice) if(event_type == SDL_MOUSEBUTTONUP && !click_handled && (*it)->is_being_dragged() == false) { (*it)->handle_event(MouseClickID, callable.get()); if((*it)->mouse_event_swallowed()) { click_handled = true; } } items.push_back(variant((*it).get())); } // Handling for "catch all" mouse events. callable->add("handled", variant(handled)); variant obj_ary(&items); callable->add("objects_under_mouse", obj_ary); std::vector<entity_ptr> level_chars(level::current().get_chars()); foreach(entity_ptr object, level_chars) { if(object) { object->handle_event(catch_all_event, callable.get()); // drag handling if(event_type == SDL_MOUSEBUTTONUP) { object->set_mouse_buttons(object->get_mouse_buttons() & ~SDL_BUTTON(event_button_button)); if(object->get_mouse_buttons() == 0 && object->is_being_dragged()) { object->handle_event(MouseDragEndID, callable.get()); object->set_being_dragged(false); } } else if(event_type == SDL_MOUSEMOTION) { // drag check. if(object->is_being_dragged()) { if(object->get_mouse_buttons() & button_state) { object->handle_event(MouseDragID, callable.get()); } else { object->handle_event(MouseDragEndID, callable.get()); object->set_being_dragged(false); } } else if(object->get_mouse_buttons() & button_state) { // start drag. object->handle_event(MouseDragStartID, callable.get()); object->set_being_dragged(); } } } } if(event_type == SDL_MOUSEMOTION) { // handling for mouse_leave level_chars = level::current().get_chars(); foreach(const entity_ptr& e, level_chars) { if(e) { // n.b. clip_area is in level coordinates, not relative to the object. rect clip_area; bool has_clip_area = e->get_clip_area(&clip_area); point p(x,y); if(e->use_absolute_screen_coordinates()) { p = point(mx,my); } if(mouse_in.find(e) == mouse_in.end() && ((has_clip_area == false && e->is_mouse_over_entity()) || (e->is_mouse_over_entity() && has_clip_area && point_in_rect(p, clip_area) == false))) { e->handle_event(MouseLeaveID, callable.get()); e->set_mouse_over_entity(false); } } } } }