Explorar o código

proper joy axis support as actions, can be configured and inquired, fixes #2317

Juan Linietsky %!s(int64=9) %!d(string=hai) anos
pai
achega
432e2e7769

+ 4 - 2
core/globals.cpp

@@ -638,7 +638,9 @@ static Variant _decode_variant(const String& p_string) {
 		InputEvent ie;
 		ie.type=InputEvent::JOYSTICK_MOTION;
 		ie.device=params[0].to_int();
-		ie.joy_motion.axis=params[1].to_int();
+		int axis = params[1].to_int();;
+		ie.joy_motion.axis=axis>>1;
+		ie.joy_motion.axis_value=axis&1?1:-1;
 
 		return ie;
 	}
@@ -1029,7 +1031,7 @@ static String _encode_variant(const Variant& p_variant) {
 				} break;
 				case InputEvent::JOYSTICK_MOTION: {
 
-					return "jaxis("+itos(ev.device)+", "+itos(ev.joy_motion.axis)+")";
+					return "jaxis("+itos(ev.device)+", "+itos(ev.joy_motion.axis * 2 + (ev.joy_motion.axis_value<0?0:1))+")";
 				} break;
 				default: {
 

+ 58 - 0
core/input_map.cpp

@@ -204,6 +204,64 @@ bool InputMap::event_is_action(const InputEvent& p_event, const StringName& p_ac
 	return _find_event(E->get().inputs,p_event)!=NULL;
 }
 
+bool InputMap::event_is_joy_motion_action_pressed(const InputEvent& p_event) const {
+
+	ERR_FAIL_COND_V(p_event.type!=InputEvent::JOYSTICK_MOTION,false);
+	bool pressed=false;
+
+	//this could be optimized by having a separate list of joymotions?
+
+	for (Map<StringName, Action>::Element *A=input_map.front();A;A=A->next()) {
+
+		for (List<InputEvent>::Element *E=A->get().inputs.front();E;E=E->next()) {
+
+			const InputEvent& e=E->get();
+			if(e.type!=p_event.type)
+				continue;
+			if (e.type!=InputEvent::KEY && e.device!=p_event.device)
+				continue;
+
+			switch(p_event.type) {
+
+				case InputEvent::KEY: {
+
+					if (e.key.scancode==p_event.key.scancode && e.key.mod == p_event.key.mod)
+						return e.key.pressed;
+
+				} break;
+				case InputEvent::JOYSTICK_BUTTON: {
+
+					if (e.joy_button.button_index==p_event.joy_button.button_index) {
+						return e.joy_button.pressed;
+					}
+
+				} break;
+				case InputEvent::MOUSE_BUTTON: {
+
+					if (e.mouse_button.button_index==p_event.mouse_button.button_index) {
+						return e.mouse_button.pressed;
+					}
+
+				} break;
+				case InputEvent::JOYSTICK_MOTION: {
+
+					if (e.joy_motion.axis==p_event.joy_motion.axis) {
+						if (
+								(e.joy_motion.axis_value * p_event.joy_motion.axis_value >0) && //same axis
+								ABS(e.joy_motion.axis_value>0.5) && ABS(p_event.joy_motion.axis_value>0.5) )
+							pressed=true;
+					}
+
+				} break;
+			}
+
+		}
+	}
+
+	return pressed;
+
+}
+
 void InputMap::load_from_globals() {
 
 	input_map.clear();;

+ 1 - 0
core/input_map.h

@@ -68,6 +68,7 @@ public:
 
 	const List<InputEvent> *get_action_list(const StringName& p_action);
 	bool event_is_action(const InputEvent& p_event, const StringName& p_action) const;
+	bool event_is_joy_motion_action_pressed(const InputEvent& p_event) const;
 
 
 	void load_from_globals();

+ 1 - 0
core/os/input_event.cpp

@@ -156,6 +156,7 @@ bool InputEvent::is_pressed() const {
 		case MOUSE_BUTTON: return mouse_button.pressed;
 		case JOYSTICK_BUTTON: return joy_button.pressed;
 		case SCREEN_TOUCH: return screen_touch.pressed;
+		case JOYSTICK_MOTION: return InputMap::get_singleton()->event_is_joy_motion_action_pressed(*this);
 		case ACTION: return action.pressed;
 		default: {}
 	}

+ 20 - 2
core/variant_parser.cpp

@@ -1072,8 +1072,24 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
 				ie.joy_motion.axis = token.value;
 
 				get_token(p_stream,token,line,r_err_str);
+
+				if (token.type!=TK_COMMA) {
+					r_err_str="Expected ',' after axis index";
+					return ERR_PARSE_ERROR;
+				}
+
+				get_token(p_stream,token,line,r_err_str);
+				if (token.type!=TK_NUMBER) {
+					r_err_str="Expected axis sign";
+					return ERR_PARSE_ERROR;
+				}
+
+				ie.joy_motion.axis_value = token.value;
+
+				get_token(p_stream,token,line,r_err_str);
+
 				if (token.type!=TK_PARENTHESIS_CLOSE) {
-					r_err_str="Expected ')'";
+					r_err_str="Expected ')' for jaxis";
 					return ERR_PARSE_ERROR;
 				}
 
@@ -1339,7 +1355,9 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
 			InputEvent ie;
 			ie.type=InputEvent::JOYSTICK_MOTION;
 			ie.device=params[0].to_int();
-			ie.joy_motion.axis=params[1].to_int();
+			int axis=params[1].to_int();
+			ie.joy_motion.axis=axis>>1;
+			ie.joy_motion.axis_value=axis&1?1:-1;
 
 			value= ie;
 

+ 8 - 5
tools/editor/project_settings.cpp

@@ -156,12 +156,14 @@ void ProjectSettings::_device_input_add() {
 		} break;
 		case InputEvent::JOYSTICK_MOTION: {
 
-				ie.joy_motion.axis = device_index->get_selected();
+				ie.joy_motion.axis = device_index->get_selected()>>1;
+				ie.joy_motion.axis_value = device_index->get_selected()&1?1:-1;
+
 
 				for(int i=0;i<arr.size();i++) {
 
 					InputEvent aie=arr[i];
-					if (aie.device == ie.device && aie.type==InputEvent::JOYSTICK_MOTION && aie.joy_motion.axis==ie.joy_motion.axis) {
+					if (aie.device == ie.device && aie.type==InputEvent::JOYSTICK_MOTION && aie.joy_motion.axis==ie.joy_motion.axis && aie.joy_motion.axis_value==ie.joy_motion.axis_value) {
 						return;
 					}
 				}
@@ -295,9 +297,10 @@ void ProjectSettings::_add_item(int p_item){
 			device_id->set_val(0);
 			device_index_label->set_text("Joy Button Axis:");
 			device_index->clear();
-			for(int i=0;i<8;i++) {
+			for(int i=0;i<24;i++) {
+
 
-				device_index->add_item("Axis "+itos(i));
+				device_index->add_item("Axis "+itos(i/2)+" "+(i&1?"+":"-"));
 			}
 			device_input->popup_centered(Size2(350,95));
 
@@ -494,7 +497,7 @@ void ProjectSettings::_update_actions() {
 				} break;
 				case InputEvent::JOYSTICK_MOTION: {
 
-					String str = "Device "+itos(ie.device)+", Axis "+itos(ie.joy_motion.axis)+".";
+					String str = "Device "+itos(ie.device)+", Axis "+itos(ie.joy_motion.axis)+" "+(ie.joy_motion.axis_value<0?"-.":"+.");
 					action->set_text(0,str);
 					action->set_icon(0,get_icon("JoyAxis","EditorIcons"));
 				} break;