mirror of
https://github.com/godotengine/godot.git
synced 2024-11-25 13:43:15 +00:00
Merge pull request #31437 from volzhs/vibrate-mobile
Support vibration for Android and iOS
This commit is contained in:
commit
1a4dbd9ee2
@ -80,6 +80,7 @@ void Input::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_joy_axis_index_from_string", "axis"), &Input::get_joy_axis_index_from_string);
|
||||
ClassDB::bind_method(D_METHOD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &Input::start_joy_vibration, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("stop_joy_vibration", "device"), &Input::stop_joy_vibration);
|
||||
ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms"), &Input::vibrate_handheld, DEFVAL(500));
|
||||
ClassDB::bind_method(D_METHOD("get_gravity"), &Input::get_gravity);
|
||||
ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer);
|
||||
ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer);
|
||||
|
@ -100,6 +100,7 @@ public:
|
||||
virtual uint64_t get_joy_vibration_timestamp(int p_device) = 0;
|
||||
virtual void start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration = 0) = 0;
|
||||
virtual void stop_joy_vibration(int p_device) = 0;
|
||||
virtual void vibrate_handheld(int p_duration_ms = 500) = 0;
|
||||
|
||||
virtual Point2 get_mouse_position() const = 0;
|
||||
virtual Point2 get_last_mouse_speed() const = 0;
|
||||
|
@ -186,6 +186,11 @@ int OS::get_process_id() const {
|
||||
return -1;
|
||||
};
|
||||
|
||||
void OS::vibrate_handheld(int p_duration_ms) {
|
||||
|
||||
WARN_PRINTS("vibrate_handheld() only works with Android and iOS");
|
||||
}
|
||||
|
||||
bool OS::is_stdout_verbose() const {
|
||||
|
||||
return _verbose_stdout;
|
||||
|
@ -265,6 +265,7 @@ public:
|
||||
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL) = 0;
|
||||
virtual Error kill(const ProcessID &p_pid) = 0;
|
||||
virtual int get_process_id() const;
|
||||
virtual void vibrate_handheld(int p_duration_ms = 500);
|
||||
|
||||
virtual Error shell_open(String p_uri);
|
||||
virtual Error set_cwd(const String &p_cwd);
|
||||
|
@ -372,6 +372,16 @@
|
||||
Stops the vibration of the joypad.
|
||||
</description>
|
||||
</method>
|
||||
<method name="vibrate_handheld">
|
||||
<return type="void">
|
||||
</return>
|
||||
<argument index="0" name="duration_ms" type="int" default="500">
|
||||
</argument>
|
||||
<description>
|
||||
Vibrate Android and iOS devices.
|
||||
[b]Note:[/b] It needs VIBRATE permission for Android at export settings. iOS does not support duration.
|
||||
</description>
|
||||
</method>
|
||||
<method name="warp_mouse_position">
|
||||
<return type="void">
|
||||
</return>
|
||||
|
@ -472,6 +472,10 @@ void InputDefault::stop_joy_vibration(int p_device) {
|
||||
joy_vibration[p_device] = vibration;
|
||||
}
|
||||
|
||||
void InputDefault::vibrate_handheld(int p_duration_ms) {
|
||||
OS::get_singleton()->vibrate_handheld(p_duration_ms);
|
||||
}
|
||||
|
||||
void InputDefault::set_gravity(const Vector3 &p_gravity) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
@ -226,6 +226,7 @@ public:
|
||||
|
||||
virtual void start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration = 0);
|
||||
virtual void stop_joy_vibration(int p_device);
|
||||
virtual void vibrate_handheld(int p_duration_ms = 500);
|
||||
|
||||
void set_main_loop(MainLoop *p_main_loop);
|
||||
void set_mouse_position(const Point2 &p_posf);
|
||||
|
@ -56,6 +56,7 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Messenger;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.view.Display;
|
||||
@ -98,6 +99,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
|
||||
static final int MAX_SINGLETONS = 64;
|
||||
static final int REQUEST_RECORD_AUDIO_PERMISSION = 1;
|
||||
static final int REQUEST_CAMERA_PERMISSION = 2;
|
||||
static final int REQUEST_VIBRATE_PERMISSION = 3;
|
||||
private IStub mDownloaderClientStub;
|
||||
private IDownloaderService mRemoteService;
|
||||
private TextView mStatusText;
|
||||
@ -324,6 +326,15 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
|
||||
});
|
||||
}
|
||||
|
||||
public void vibrate(int p_duration_ms) {
|
||||
if (requestPermission("VIBRATE")) {
|
||||
Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
|
||||
if (v != null) {
|
||||
v.vibrate(p_duration_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
// HACK:
|
||||
//
|
||||
@ -989,6 +1000,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_name.equals("VIBRATE")) {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) {
|
||||
requestPermissions(new String[] { Manifest.permission.VIBRATE }, REQUEST_VIBRATE_PERMISSION);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance) {
|
||||
_init_input_devices = p_env->GetMethodID(cls, "initInputDevices", "()V");
|
||||
_get_surface = p_env->GetMethodID(cls, "getSurface", "()Landroid/view/Surface;");
|
||||
_is_activity_resumed = p_env->GetMethodID(cls, "isActivityResumed", "()Z");
|
||||
_vibrate = p_env->GetMethodID(cls, "vibrate", "(I)V");
|
||||
}
|
||||
|
||||
GodotJavaWrapper::~GodotJavaWrapper() {
|
||||
@ -211,3 +212,10 @@ bool GodotJavaWrapper::is_activity_resumed() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void GodotJavaWrapper::vibrate(int p_duration_ms) {
|
||||
if (_vibrate) {
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
env->CallVoidMethod(godot_instance, _vibrate, p_duration_ms);
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ private:
|
||||
jmethodID _init_input_devices = 0;
|
||||
jmethodID _get_surface = 0;
|
||||
jmethodID _is_activity_resumed = 0;
|
||||
jmethodID _vibrate = 0;
|
||||
|
||||
public:
|
||||
GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance);
|
||||
@ -82,6 +83,7 @@ public:
|
||||
void init_input_devices();
|
||||
jobject get_surface();
|
||||
bool is_activity_resumed();
|
||||
void vibrate(int p_duration_ms);
|
||||
};
|
||||
|
||||
#endif /* !JAVA_GODOT_WRAPPER_H */
|
||||
|
@ -700,6 +700,10 @@ String OS_Android::get_joy_guid(int p_device) const {
|
||||
return input->get_joy_guid_remapped(p_device);
|
||||
}
|
||||
|
||||
void OS_Android::vibrate_handheld(int p_duration_ms) {
|
||||
godot_java->vibrate(p_duration_ms);
|
||||
}
|
||||
|
||||
bool OS_Android::_check_internal_feature_support(const String &p_feature) {
|
||||
if (p_feature == "mobile") {
|
||||
//TODO support etc2 only if GLES3 driver is selected
|
||||
|
@ -198,6 +198,7 @@ public:
|
||||
virtual bool is_joy_known(int p_device);
|
||||
virtual String get_joy_guid(int p_device) const;
|
||||
void joy_connection_changed(int p_device, bool p_connected, String p_name);
|
||||
void vibrate_handheld(int p_duration_ms);
|
||||
|
||||
virtual bool _check_internal_feature_support(const String &p_feature);
|
||||
OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion);
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "os_iphone.h"
|
||||
|
||||
#import "GameController/GameController.h"
|
||||
#import <AudioToolbox/AudioServices.h>
|
||||
|
||||
#define kFilteringFactor 0.1
|
||||
#define kRenderingFrequency 60
|
||||
@ -61,6 +62,10 @@ void _set_keep_screen_on(bool p_enabled) {
|
||||
[[UIApplication sharedApplication] setIdleTimerDisabled:(BOOL)p_enabled];
|
||||
};
|
||||
|
||||
void _vibrate() {
|
||||
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
|
||||
};
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
@synthesize window;
|
||||
|
@ -470,6 +470,7 @@ extern void _show_keyboard(String p_existing);
|
||||
extern void _hide_keyboard();
|
||||
extern Error _shell_open(String p_uri);
|
||||
extern void _set_keep_screen_on(bool p_enabled);
|
||||
extern void _vibrate();
|
||||
|
||||
void OSIPhone::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect) {
|
||||
_show_keyboard(p_existing_text);
|
||||
@ -585,6 +586,11 @@ void OSIPhone::native_video_stop() {
|
||||
_stop_video();
|
||||
}
|
||||
|
||||
void OSIPhone::vibrate_handheld(int p_duration_ms) {
|
||||
// iOS does not support duration for vibration
|
||||
_vibrate();
|
||||
}
|
||||
|
||||
bool OSIPhone::_check_internal_feature_support(const String &p_feature) {
|
||||
|
||||
return p_feature == "mobile";
|
||||
|
@ -195,6 +195,7 @@ public:
|
||||
virtual void native_video_unpause();
|
||||
virtual void native_video_focus_out();
|
||||
virtual void native_video_stop();
|
||||
virtual void vibrate_handheld(int p_duration_ms = 500);
|
||||
|
||||
virtual bool _check_internal_feature_support(const String &p_feature);
|
||||
OSIPhone(int width, int height, String p_data_dir);
|
||||
|
Loading…
Reference in New Issue
Block a user