diff options
Diffstat (limited to 'platform')
71 files changed, 1584 insertions, 735 deletions
diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java index aef6591864..7c5ac33c85 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/src/org/godotengine/godot/GodotLib.java @@ -54,6 +54,8 @@ public class GodotLib { public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed); public static native void joybutton(int p_device, int p_but, boolean p_pressed); public static native void joyaxis(int p_device, int p_axis, float p_value); + public static native void joyhat(int p_device, int p_hat_x, int p_hat_y); + public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name); public static native void focusin(); public static native void focusout(); public static native void audio(); diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java index 492eb4cb54..e210161e8b 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/src/org/godotengine/godot/GodotView.java @@ -36,14 +36,21 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.content.ContextWrapper; import android.view.InputDevice; +import android.hardware.input.InputManager; import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.opengles.GL10; +import org.godotengine.godot.input.InputManagerCompat; +import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener; /** * A simple GLSurfaceView sub-class that demonstrate how to perform * OpenGL ES 2.0 rendering into a GL Surface. Note the following important @@ -62,7 +69,7 @@ import javax.microedition.khronos.opengles.GL10; * that matches it exactly (with regards to red/green/blue/alpha channels * bit depths). Failure to do so would result in an EGL_BAD_MATCH error. */ -public class GodotView extends GLSurfaceView { +public class GodotView extends GLSurfaceView implements InputDeviceListener { private static String TAG = "GodotView"; private static final boolean DEBUG = false; @@ -75,6 +82,8 @@ public class GodotView extends GLSurfaceView { private Godot activity; + + private InputManagerCompat mInputManager; public GodotView(Context context,GodotIO p_io,boolean p_use_gl2, boolean p_use_32_bits, Godot p_activity) { super(context); ctx=context; @@ -88,7 +97,8 @@ public class GodotView extends GLSurfaceView { //will only work on SDK 11+!! setPreserveEGLContextOnPause(true); } - + mInputManager = InputManagerCompat.Factory.getInputManager(this.getContext()); + mInputManager.registerInputDeviceListener(this, null); init(false, 16, 0); } @@ -119,50 +129,112 @@ public class GodotView extends GLSurfaceView { button = 3; break; case KeyEvent.KEYCODE_BUTTON_L1: - button = 4; + button = 9; break; case KeyEvent.KEYCODE_BUTTON_L2: - button = 6; + button = 15; break; case KeyEvent.KEYCODE_BUTTON_R1: - button = 5; + button = 10; break; case KeyEvent.KEYCODE_BUTTON_R2: - button = 7; + button = 16; break; case KeyEvent.KEYCODE_BUTTON_SELECT: - button = 10; + button = 4; break; case KeyEvent.KEYCODE_BUTTON_START: - button = 11; + button = 6; break; case KeyEvent.KEYCODE_BUTTON_THUMBL: - button = 8; + button = 7; break; case KeyEvent.KEYCODE_BUTTON_THUMBR: - button = 9; + button = 8; break; case KeyEvent.KEYCODE_DPAD_UP: - button = 12; + button = 11; break; case KeyEvent.KEYCODE_DPAD_DOWN: - button = 13; + button = 12; break; case KeyEvent.KEYCODE_DPAD_LEFT: - button = 14; + button = 13; break; case KeyEvent.KEYCODE_DPAD_RIGHT: - button = 15; + button = 14; + break; + case KeyEvent.KEYCODE_BUTTON_C: + button = 17; + break; + case KeyEvent.KEYCODE_BUTTON_Z: + button = 18; break; default: - button = keyCode - KeyEvent.KEYCODE_BUTTON_1; + button = keyCode - KeyEvent.KEYCODE_BUTTON_1 + 20; break; }; - return button; }; + private static class joystick { + public int device_id; + public String name; + public ArrayList<InputDevice.MotionRange> axes; + public ArrayList<InputDevice.MotionRange> hats; + } + + private static class RangeComparator implements Comparator<InputDevice.MotionRange> { + @Override + public int compare(InputDevice.MotionRange arg0, InputDevice.MotionRange arg1) { + return arg0.getAxis() - arg1.getAxis(); + } + } + + ArrayList<joystick> joy_devices = new ArrayList<joystick>(); + + private int find_joy_device(int device_id) { + for (int i=0; i<joy_devices.size(); i++) { + if (joy_devices.get(i).device_id == device_id) { + return i; + } + } + onInputDeviceAdded(device_id); + return joy_devices.size() - 1; + } + + @Override public void onInputDeviceAdded(int deviceId) { + joystick joy = new joystick(); + joy.device_id = deviceId; + int id = joy_devices.size(); + InputDevice device = mInputManager.getInputDevice(deviceId); + joy.name = device.getName(); + joy.axes = new ArrayList<InputDevice.MotionRange>(); + joy.hats = new ArrayList<InputDevice.MotionRange>(); + List<InputDevice.MotionRange> ranges = device.getMotionRanges(); + Collections.sort(ranges, new RangeComparator()); + for (InputDevice.MotionRange range : ranges) { + if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) { + joy.hats.add(range); + } + else { + joy.axes.add(range); + } + } + joy_devices.add(joy); + GodotLib.joyconnectionchanged(id, true, joy.name); + } + + @Override public void onInputDeviceRemoved(int deviceId) { + int id = find_joy_device(deviceId); + joy_devices.remove(id); + GodotLib.joyconnectionchanged(id, false, ""); + } + + @Override public void onInputDeviceChanged(int deviceId) { + + } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { @@ -177,7 +249,7 @@ public class GodotView extends GLSurfaceView { if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { int button = get_godot_button(keyCode); - int device = event.getDeviceId(); + int device = find_joy_device(event.getDeviceId()); GodotLib.joybutton(device, button, false); return true; @@ -209,7 +281,8 @@ public class GodotView extends GLSurfaceView { if (event.getRepeatCount() > 0) // ignore key echo return true; int button = get_godot_button(keyCode); - int device = event.getDeviceId(); + int device = find_joy_device(event.getDeviceId()); + //Log.e(TAG, String.format("joy button down! button %x, %d, device %d", keyCode, button, device)); GodotLib.joybutton(device, button, true); @@ -221,125 +294,27 @@ public class GodotView extends GLSurfaceView { return super.onKeyDown(keyCode, event); } - public float axis_value(MotionEvent p_event, InputDevice p_device, int p_axis, int p_pos) { - - final InputDevice.MotionRange range = p_device.getMotionRange(p_axis, p_event.getSource()); - if (range == null) - return 0; - - //Log.e(TAG, String.format("axis ranges %f, %f, %f", range.getRange(), range.getMin(), range.getMax())); - - final float flat = range.getFlat(); - final float value = - p_pos < 0 ? p_event.getAxisValue(p_axis): - p_event.getHistoricalAxisValue(p_axis, p_pos); - - final float absval = Math.abs(value); - if (absval <= flat) { - return 0; - }; - - final float ret = (value - range.getMin()) / range.getRange() * 2 - 1.0f; - - return ret; - }; - - float[] last_axis_values = { 0, 0, 0, 0, -1, -1 }; - boolean[] last_axis_buttons = { false, false, false, false, false, false }; // dpad up down left right, ltrigger, rtrigger - - public void process_axis_state(MotionEvent p_event, int p_pos) { - - int device_id = p_event.getDeviceId(); - InputDevice device = p_event.getDevice(); - float val; - - val = axis_value(p_event, device, MotionEvent.AXIS_X, p_pos); - if (val != last_axis_values[0]) { - last_axis_values[0] = val; - //Log.e(TAG, String.format("axis moved! axis %d, value %f", 0, val)); - GodotLib.joyaxis(device_id, 0, val); - }; - - val = axis_value(p_event, device, MotionEvent.AXIS_Y, p_pos); - if (val != last_axis_values[1]) { - last_axis_values[1] = val; - //Log.e(TAG, String.format("axis moved! axis %d, value %f", 1, val)); - GodotLib.joyaxis(device_id, 1, val); - }; - - val = axis_value(p_event, device, MotionEvent.AXIS_Z, p_pos); - if (val != last_axis_values[2]) { - last_axis_values[2] = val; - //Log.e(TAG, String.format("axis moved! axis %d, value %f", 2, val)); - GodotLib.joyaxis(device_id, 2, val); - }; - - val = axis_value(p_event, device, MotionEvent.AXIS_RZ, p_pos); - if (val != last_axis_values[3]) { - last_axis_values[3] = val; - //Log.e(TAG, String.format("axis moved! axis %d, value %f", 3, val)); - GodotLib.joyaxis(device_id, 3, val); - }; - - val = axis_value(p_event, device, MotionEvent.AXIS_LTRIGGER, p_pos); - if (val != last_axis_values[4]) { - last_axis_values[4] = val; - if ((val != 0) != (last_axis_buttons[4])) { - last_axis_buttons[4] = (val != 0); - GodotLib.joybutton(device_id, 6, (val != 0)); - }; - }; - - val = axis_value(p_event, device, MotionEvent.AXIS_RTRIGGER, p_pos); - if (val != last_axis_values[5]) { - last_axis_values[5] = val; - if ((val != 0) != (last_axis_buttons[5])) { - last_axis_buttons[5] = (val != 0); - GodotLib.joybutton(device_id, 7, (val != 0)); - }; - }; - - val = axis_value(p_event, device, MotionEvent.AXIS_HAT_Y, p_pos); - - if (last_axis_buttons[0] != (val > 0)) { - last_axis_buttons[0] = val > 0; - GodotLib.joybutton(device_id, 12, val > 0); - }; - if (last_axis_buttons[1] != (val < 0)) { - last_axis_buttons[1] = val < 0; - GodotLib.joybutton(device_id, 13, val > 0); - }; - - val = axis_value(p_event, device, MotionEvent.AXIS_HAT_X, p_pos); - if (last_axis_buttons[2] != (val < 0)) { - last_axis_buttons[2] = val < 0; - GodotLib.joybutton(device_id, 14, val < 0); - }; - if (last_axis_buttons[3] != (val > 0)) { - last_axis_buttons[3] = val > 0; - GodotLib.joybutton(device_id, 15, val > 0); - }; - }; - @Override public boolean onGenericMotionEvent(MotionEvent event) { if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) { - // Process all historical movement samples in the batch - final int historySize = event.getHistorySize(); + int device_id = find_joy_device(event.getDeviceId()); + joystick joy = joy_devices.get(device_id); - // Process the movements starting from the - // earliest historical position in the batch - for (int i = 0; i < historySize; i++) { - // Process the event at historical position i - process_axis_state(event, i); + for (int i = 0; i < joy.axes.size(); i++) { + InputDevice.MotionRange range = joy.axes.get(i); + float value = (event.getAxisValue(range.getAxis()) - range.getMin() ) / range.getRange() * 2.0f - 1.0f; + //Log.e(TAG, String.format("axis event: %d, value %f", i, value)); + GodotLib.joyaxis(device_id, i, value); } - // Process the current movement sample in the batch (position -1) - process_axis_state(event, -1); + for (int i = 0; i < joy.hats.size(); i+=2) { + int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis())); + int hatY = Math.round(event.getAxisValue(joy.hats.get(i+1).getAxis())); + //Log.e(TAG, String.format("HAT EVENT %d, %d", hatX, hatY)); + GodotLib.joyhat(device_id, hatX, hatY); + } return true; - - }; return super.onGenericMotionEvent(event); @@ -413,12 +388,12 @@ public class GodotView extends GLSurfaceView { /* Fallback if 32bit View is not supported*/ private static class FallbackConfigChooser extends ConfigChooser { private ConfigChooser fallback; - + public FallbackConfigChooser(int r, int g, int b, int a, int depth, int stencil, ConfigChooser fallback) { super(r, g, b, a, depth, stencil); this.fallback = fallback; } - + @Override public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) { EGLConfig ec = super.chooseConfig(egl, display, configs); diff --git a/platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java b/platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java new file mode 100644 index 0000000000..4615d2fbb5 --- /dev/null +++ b/platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.godotengine.godot.input; + +import android.content.Context; +import android.os.Build; +import android.os.Handler; +import android.view.InputDevice; +import android.view.MotionEvent; + +public interface InputManagerCompat { + /** + * Gets information about the input device with the specified id. + * + * @param id The device id + * @return The input device or null if not found + */ + public InputDevice getInputDevice(int id); + + /** + * Gets the ids of all input devices in the system. + * + * @return The input device ids. + */ + public int[] getInputDeviceIds(); + + /** + * Registers an input device listener to receive notifications about when + * input devices are added, removed or changed. + * + * @param listener The listener to register. + * @param handler The handler on which the listener should be invoked, or + * null if the listener should be invoked on the calling thread's + * looper. + */ + public void registerInputDeviceListener(InputManagerCompat.InputDeviceListener listener, + Handler handler); + + /** + * Unregisters an input device listener. + * + * @param listener The listener to unregister. + */ + public void unregisterInputDeviceListener(InputManagerCompat.InputDeviceListener listener); + + /* + * The following three calls are to simulate V16 behavior on pre-Jellybean + * devices. If you don't call them, your callback will never be called + * pre-API 16. + */ + + /** + * Pass the motion events to the InputManagerCompat. This is used to + * optimize for polling for controllers. If you do not pass these events in, + * polling will cause regular object creation. + * + * @param event the motion event from the app + */ + public void onGenericMotionEvent(MotionEvent event); + + /** + * Tell the V9 input manager that it should stop polling for disconnected + * devices. You can call this during onPause in your activity, although you + * might want to call it whenever your game is not active (or whenever you + * don't care about being notified of new input devices) + */ + public void onPause(); + + /** + * Tell the V9 input manager that it should start polling for disconnected + * devices. You can call this during onResume in your activity, although you + * might want to call it less often (only when the gameplay is actually + * active) + */ + public void onResume(); + + public interface InputDeviceListener { + /** + * Called whenever the input manager detects that a device has been + * added. This will only be called in the V9 version when a motion event + * is detected. + * + * @param deviceId The id of the input device that was added. + */ + void onInputDeviceAdded(int deviceId); + + /** + * Called whenever the properties of an input device have changed since + * they were last queried. This will not be called for the V9 version of + * the API. + * + * @param deviceId The id of the input device that changed. + */ + void onInputDeviceChanged(int deviceId); + + /** + * Called whenever the input manager detects that a device has been + * removed. For the V9 version, this can take some time depending on the + * poll rate. + * + * @param deviceId The id of the input device that was removed. + */ + void onInputDeviceRemoved(int deviceId); + } + + /** + * Use this to construct a compatible InputManager. + */ + public static class Factory { + + /** + * Constructs and returns a compatible InputManger + * + * @param context the Context that will be used to get the system + * service from + * @return a compatible implementation of InputManager + */ + public static InputManagerCompat getInputManager(Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + return new InputManagerV16(context); + } else { + return new InputManagerV9(); + } + } + } +} diff --git a/platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java b/platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java new file mode 100644 index 0000000000..f05701f455 --- /dev/null +++ b/platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.godotengine.godot.input; + +import android.annotation.TargetApi; +import android.content.Context; +import android.hardware.input.InputManager; +import android.os.Build; +import android.os.Handler; +import android.view.InputDevice; +import android.view.MotionEvent; + +import java.util.HashMap; +import java.util.Map; + +@TargetApi(Build.VERSION_CODES.JELLY_BEAN) +public class InputManagerV16 implements InputManagerCompat { + + private final InputManager mInputManager; + private final Map<InputManagerCompat.InputDeviceListener, V16InputDeviceListener> mListeners; + + public InputManagerV16(Context context) { + mInputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE); + mListeners = new HashMap<InputManagerCompat.InputDeviceListener, V16InputDeviceListener>(); + } + + @Override + public InputDevice getInputDevice(int id) { + return mInputManager.getInputDevice(id); + } + + @Override + public int[] getInputDeviceIds() { + return mInputManager.getInputDeviceIds(); + } + + static class V16InputDeviceListener implements InputManager.InputDeviceListener { + final InputManagerCompat.InputDeviceListener mIDL; + + public V16InputDeviceListener(InputDeviceListener idl) { + mIDL = idl; + } + + @Override + public void onInputDeviceAdded(int deviceId) { + mIDL.onInputDeviceAdded(deviceId); + } + + @Override + public void onInputDeviceChanged(int deviceId) { + mIDL.onInputDeviceChanged(deviceId); + } + + @Override + public void onInputDeviceRemoved(int deviceId) { + mIDL.onInputDeviceRemoved(deviceId); + } + + } + + @Override + public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) { + V16InputDeviceListener v16Listener = new V16InputDeviceListener(listener); + mInputManager.registerInputDeviceListener(v16Listener, handler); + mListeners.put(listener, v16Listener); + } + + @Override + public void unregisterInputDeviceListener(InputDeviceListener listener) { + V16InputDeviceListener curListener = mListeners.remove(listener); + if (null != curListener) + { + mInputManager.unregisterInputDeviceListener(curListener); + } + + } + + @Override + public void onGenericMotionEvent(MotionEvent event) { + // unused in V16 + } + + @Override + public void onPause() { + // unused in V16 + } + + @Override + public void onResume() { + // unused in V16 + } + +} diff --git a/platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java b/platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java new file mode 100644 index 0000000000..0334c00997 --- /dev/null +++ b/platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.godotengine.godot.input; + +import android.os.Handler; +import android.os.Message; +import android.os.SystemClock; +import android.util.Log; +import android.util.SparseArray; +import android.view.InputDevice; +import android.view.MotionEvent; + +import java.lang.ref.WeakReference; +import java.util.ArrayDeque; +import java.util.HashMap; +import java.util.Map; +import java.util.Queue; + +public class InputManagerV9 implements InputManagerCompat { + private static final String LOG_TAG = "InputManagerV9"; + private static final int MESSAGE_TEST_FOR_DISCONNECT = 101; + private static final long CHECK_ELAPSED_TIME = 3000L; + + private static final int ON_DEVICE_ADDED = 0; + private static final int ON_DEVICE_CHANGED = 1; + private static final int ON_DEVICE_REMOVED = 2; + + private final SparseArray<long[]> mDevices; + private final Map<InputDeviceListener, Handler> mListeners; + private final Handler mDefaultHandler; + + private static class PollingMessageHandler extends Handler { + private final WeakReference<InputManagerV9> mInputManager; + + PollingMessageHandler(InputManagerV9 im) { + mInputManager = new WeakReference<InputManagerV9>(im); + } + + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + switch (msg.what) { + case MESSAGE_TEST_FOR_DISCONNECT: + InputManagerV9 imv = mInputManager.get(); + if (null != imv) { + long time = SystemClock.elapsedRealtime(); + int size = imv.mDevices.size(); + for (int i = 0; i < size; i++) { + long[] lastContact = imv.mDevices.valueAt(i); + if (null != lastContact) { + if (time - lastContact[0] > CHECK_ELAPSED_TIME) { + // check to see if the device has been + // disconnected + int id = imv.mDevices.keyAt(i); + if (null == InputDevice.getDevice(id)) { + // disconnected! + imv.notifyListeners(ON_DEVICE_REMOVED, id); + imv.mDevices.remove(id); + } else { + lastContact[0] = time; + } + } + } + } + sendEmptyMessageDelayed(MESSAGE_TEST_FOR_DISCONNECT, + CHECK_ELAPSED_TIME); + } + break; + } + } + + } + + public InputManagerV9() { + mDevices = new SparseArray<long[]>(); + mListeners = new HashMap<InputDeviceListener, Handler>(); + mDefaultHandler = new PollingMessageHandler(this); + // as a side-effect, populates our collection of watched + // input devices + getInputDeviceIds(); + } + + @Override + public InputDevice getInputDevice(int id) { + return InputDevice.getDevice(id); + } + + @Override + public int[] getInputDeviceIds() { + // add any hitherto unknown devices to our + // collection of watched input devices + int[] activeDevices = InputDevice.getDeviceIds(); + long time = SystemClock.elapsedRealtime(); + for ( int id : activeDevices ) { + long[] lastContact = mDevices.get(id); + if ( null == lastContact ) { + // we have a new device + mDevices.put(id, new long[] { time }); + } + } + return activeDevices; + } + + @Override + public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) { + mListeners.remove(listener); + if (handler == null) { + handler = mDefaultHandler; + } + mListeners.put(listener, handler); + } + + @Override + public void unregisterInputDeviceListener(InputDeviceListener listener) { + mListeners.remove(listener); + } + + private void notifyListeners(int why, int deviceId) { + // the state of some device has changed + if (!mListeners.isEmpty()) { + // yes... this will cause an object to get created... hopefully + // it won't happen very often + for (InputDeviceListener listener : mListeners.keySet()) { + Handler handler = mListeners.get(listener); + DeviceEvent odc = DeviceEvent.getDeviceEvent(why, deviceId, listener); + handler.post(odc); + } + } + } + + private static class DeviceEvent implements Runnable { + private int mMessageType; + private int mId; + private InputDeviceListener mListener; + private static Queue<DeviceEvent> sEventQueue = new ArrayDeque<DeviceEvent>(); + + private DeviceEvent() { + } + + static DeviceEvent getDeviceEvent(int messageType, int id, + InputDeviceListener listener) { + DeviceEvent curChanged = sEventQueue.poll(); + if (null == curChanged) { + curChanged = new DeviceEvent(); + } + curChanged.mMessageType = messageType; + curChanged.mId = id; + curChanged.mListener = listener; + return curChanged; + } + + @Override + public void run() { + switch (mMessageType) { + case ON_DEVICE_ADDED: + mListener.onInputDeviceAdded(mId); + break; + case ON_DEVICE_CHANGED: + mListener.onInputDeviceChanged(mId); + break; + case ON_DEVICE_REMOVED: + mListener.onInputDeviceRemoved(mId); + break; + default: + Log.e(LOG_TAG, "Unknown Message Type"); + break; + } + // dump this runnable back in the queue + sEventQueue.offer(this); + } + } + + @Override + public void onGenericMotionEvent(MotionEvent event) { + // detect new devices + int id = event.getDeviceId(); + long[] timeArray = mDevices.get(id); + if (null == timeArray) { + notifyListeners(ON_DEVICE_ADDED, id); + timeArray = new long[1]; + mDevices.put(id, timeArray); + } + long time = SystemClock.elapsedRealtime(); + timeArray[0] = time; + } + + @Override + public void onPause() { + mDefaultHandler.removeMessages(MESSAGE_TEST_FOR_DISCONNECT); + } + + @Override + public void onResume() { + mDefaultHandler.sendEmptyMessage(MESSAGE_TEST_FOR_DISCONNECT); + } + +} diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 75c1d78151..b5beb8fa2c 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -41,6 +41,7 @@ #include "core/os/keyboard.h" #include "java_class_wrapper.h" #include "android/asset_manager_jni.h" +#include "main/input_default.h" static JavaClassWrapper *java_class_wrapper=NULL; static OS_Android *os_android=NULL; @@ -639,6 +640,7 @@ struct JAndroidPointerEvent { static List<JAndroidPointerEvent> pointer_events; static List<InputEvent> key_events; +static List<OS_Android::JoystickEvent> joy_events; static bool initialized=false; static Mutex *input_mutex=NULL; static Mutex *suspend_mutex=NULL; @@ -1067,6 +1069,14 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv * env, jo key_events.pop_front(); }; + while (joy_events.size()) { + + OS_Android::JoystickEvent event = joy_events.front()->get(); + os_android->process_joy_event(event); + + joy_events.pop_front(); + } + if (quit_request) { os_android->main_loop_request_quit(); @@ -1380,48 +1390,57 @@ static unsigned int android_get_keysym(unsigned int p_code) { return KEY_UNKNOWN; } -static int find_device(int p_device) { - - for (int i=0; i<joy_device_ids.size(); i++) { - - if (joy_device_ids[i] == p_device) { - //print_line("found device at "+String::num(i)); - return i; - }; - }; - - //print_line("adding a device at" + String::num(joy_device_ids.size())); - joy_device_ids.push_back(p_device); - - return joy_device_ids.size() - 1; -}; - JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv * env, jobject obj, jint p_device, jint p_button, jboolean p_pressed) { - InputEvent ievent; - ievent.type = InputEvent::JOYSTICK_BUTTON; - ievent.device = find_device(p_device); - ievent.joy_button.button_index = p_button; - ievent.joy_button.pressed = p_pressed; + OS_Android::JoystickEvent jevent; + jevent.device = p_device; + jevent.type = OS_Android::JOY_EVENT_BUTTON; + jevent.index = p_button; + jevent.pressed = p_pressed; input_mutex->lock(); - key_events.push_back(ievent); + joy_events.push_back(jevent); input_mutex->unlock(); }; JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv * env, jobject obj, jint p_device, jint p_axis, jfloat p_value) { - InputEvent ievent; - ievent.type = InputEvent::JOYSTICK_MOTION; - ievent.device = find_device(p_device); - ievent.joy_motion.axis = p_axis; - ievent.joy_motion.axis_value = p_value; + OS_Android::JoystickEvent jevent; + jevent.device = p_device; + jevent.type = OS_Android::JOY_EVENT_AXIS; + jevent.index = p_axis; + jevent.value = p_value; input_mutex->lock(); - key_events.push_back(ievent); + joy_events.push_back(jevent); input_mutex->unlock(); }; +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv * env, jobject obj, jint p_device, jint p_hat_x, jint p_hat_y) { + OS_Android::JoystickEvent jevent; + jevent.device = p_device; + jevent.type = OS_Android::JOY_EVENT_HAT; + int hat = 0; + if (p_hat_x != 0) { + if (p_hat_x < 0) hat |= InputDefault::HAT_MASK_LEFT; + else hat |= InputDefault::HAT_MASK_RIGHT; + } + if (p_hat_y != 0) { + if (p_hat_y < 0) hat |= InputDefault::HAT_MASK_UP; + else hat |= InputDefault::HAT_MASK_DOWN; + } + jevent.hat = hat; + input_mutex->lock(); + joy_events.push_back(jevent); + input_mutex->unlock(); +} + +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv * env, jobject obj, jint p_device, jboolean p_connected, jstring p_name) { + if (os_android) { + String name = env->GetStringUTFChars( p_name, NULL ); + os_android->joy_connection_changed(p_device, p_connected, name); + } +} JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv * env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed) { diff --git a/platform/android/java_glue.h b/platform/android/java_glue.h index efa5b2839d..1d65d21251 100644 --- a/platform/android/java_glue.h +++ b/platform/android/java_glue.h @@ -45,6 +45,8 @@ extern "C" { JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv * env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv * env, jobject obj, jint p_device, jint p_button, jboolean p_pressed); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv * env, jobject obj, jint p_device, jint p_axis, jfloat p_value); + JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv * env, jobject obj, jint p_device, jint p_hat_x, jint p_hat_y); + JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv * env, jobject obj, jint p_device, jboolean p_connected, jstring p_name); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv * env, jobject obj, jfloat x, jfloat y, jfloat z); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv * env, jobject obj); diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 03177317af..1751334c9b 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -178,7 +178,7 @@ void OS_Android::initialize(const VideoMode& p_desired,int p_video_driver,int p_ physics_2d_server->init(); input = memnew( InputDefault ); - + input->set_fallback_mapping("Default Android Gamepad"); } void OS_Android::set_main_loop( MainLoop * p_main_loop ) { @@ -370,6 +370,25 @@ void OS_Android::main_loop_focusin(){ } +void OS_Android::process_joy_event(OS_Android::JoystickEvent p_event) { + + switch (p_event.type) { + case JOY_EVENT_BUTTON: + last_id = input->joy_button(last_id, p_event.device, p_event.index, p_event.pressed); + break; + case JOY_EVENT_AXIS: + InputDefault::JoyAxis value; + value.min = -1; + value.value = p_event.value; + last_id = input->joy_axis(last_id, p_event.device, p_event.index, value); + break; + case JOY_EVENT_HAT: + last_id = input->joy_hat(last_id, p_event.device, p_event.hat); + break; + default: + return; + } +} void OS_Android::process_event(InputEvent p_event) { @@ -742,6 +761,18 @@ void OS_Android::set_context_is_16_bits(bool p_is_16) { rasterizer->set_force_16_bits_fbo(p_is_16); } +void OS_Android::joy_connection_changed(int p_device, bool p_connected, String p_name) { + return input->joy_connection_changed(p_device, p_connected, p_name, ""); +} + +bool OS_Android::is_joy_known(int p_device) { + return input->is_joy_mapped(p_device); +} + +String OS_Android::get_joy_guid(int p_device) const { + return input->get_joy_guid_remapped(p_device); +} + OS_Android::OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func,GetModelFunc p_get_model_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, SetScreenOrientationFunc p_screen_orient,GetUniqueIDFunc p_get_unique_id,GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, bool p_use_apk_expansion) { diff --git a/platform/android/os_android.h b/platform/android/os_android.h index 1ae42e9cc7..5075e766bc 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -83,6 +83,22 @@ public: Point2 pos; }; + enum { + JOY_EVENT_BUTTON = 0, + JOY_EVENT_AXIS = 1, + JOY_EVENT_HAT = 2 + }; + + struct JoystickEvent { + + int device; + int type; + int index; + bool pressed; + float value; + int hat; + }; + private: Vector<TouchPos> touch; @@ -224,6 +240,7 @@ public: void process_accelerometer(const Vector3& p_accelerometer); void process_touch(int p_what,int p_pointer, const Vector<TouchPos>& p_points); + void process_joy_event(JoystickEvent p_event); void process_event(InputEvent p_event); void init_video_mode(int p_video_width,int p_video_height); @@ -232,6 +249,10 @@ public: virtual void native_video_pause(); virtual void native_video_stop(); + 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); + OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func,GetModelFunc p_get_model_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, SetScreenOrientationFunc p_screen_orient,GetUniqueIDFunc p_get_unique_id,GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, bool p_use_apk_expansion); ~OS_Android(); diff --git a/platform/bb10/os_bb10.cpp b/platform/bb10/os_bb10.cpp index d2a350cf83..58ea26b8c9 100644 --- a/platform/bb10/os_bb10.cpp +++ b/platform/bb10/os_bb10.cpp @@ -29,7 +29,6 @@ #include "os_bb10.h" #include "drivers/gles2/rasterizer_gles2.h" -#include "drivers/gles1/rasterizer_gles1.h" #include "servers/visual/visual_server_raster.h" #include "core/os/dir_access.h" @@ -605,6 +604,9 @@ String OSBB10::get_data_dir() const { return data_dir; }; +Size2 OSBB10::get_window_size() const { + return Vector2(default_videomode.width, default_videomode.height); +} OSBB10::OSBB10() { diff --git a/platform/bb10/os_bb10.h b/platform/bb10/os_bb10.h index a0481d1190..4ee5af8323 100644 --- a/platform/bb10/os_bb10.h +++ b/platform/bb10/os_bb10.h @@ -32,6 +32,7 @@ #include "os/input.h" #include "drivers/unix/os_unix.h" #include "os/main_loop.h" +#include "main/input_default.h" #include "servers/physics/physics_server_sw.h" #include "servers/spatial_sound/spatial_sound_server_sw.h" #include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h" @@ -135,6 +136,7 @@ public: virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const; + virtual Size2 get_window_size() const; virtual String get_name(); virtual MainLoop *get_main_loop() const; diff --git a/platform/haiku/key_mapping_haiku.cpp b/platform/haiku/key_mapping_haiku.cpp index d7bde9a727..1c0584523a 100644 --- a/platform/haiku/key_mapping_haiku.cpp +++ b/platform/haiku/key_mapping_haiku.cpp @@ -160,7 +160,7 @@ unsigned int KeyMappingHaiku::get_keysym(int32 raw_char, int32 key) { if (raw_char == B_UP_ARROW && key == 0x38) { return KEY_KP_8; } if (raw_char == B_PAGE_UP && key == 0x39) { return KEY_KP_9; } if (raw_char == 0x2F && key == 0x23) { return KEY_KP_DIVIDE; } - if (raw_char == 0x2D && key == 0x25) { return KEY_KP_SUBSTRACT; } + if (raw_char == 0x2D && key == 0x25) { return KEY_KP_SUBTRACT; } if (raw_char == B_DELETE && key == 0x65) { return KEY_KP_PERIOD; } if (raw_char == 0x10) { diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm index 88361e87e4..94fbb9e174 100755 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -58,6 +58,7 @@ void _show_keyboard(String); void _hide_keyboard(); bool _play_video(String, float, String, String); bool _is_video_playing(); +void _pause_video(); void _focus_out_video(); void _unpause_video(); void _stop_video(); @@ -74,64 +75,30 @@ void _hide_keyboard() { keyboard_text = ""; }; -/* -bool _play_video(String p_path, float p_volume) { - - float player_volume = p_volume * AudioServer::get_singleton()->get_singleton()->get_stream_global_volume_scale(); - video_previous_volume = [[MPMusicPlayerController applicationMusicPlayer] volume]; - - //[[MPMusicPlayerController applicationMusicPlayer] setVolume: player_volume]; - - p_path = Globals::get_singleton()->globalize_path(p_path); - - NSString* file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease]; - NSURL *file_url = [NSURL fileURLWithPath:file_path]; - - _instance.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:file_url]; - _instance.moviePlayerController.controlStyle = MPMovieControlStyleNone; - [_instance.moviePlayerController setScalingMode:MPMovieScalingModeAspectFit]; - //[_instance.moviePlayerController setScalingMode:MPMovieScalingModeAspectFill]; - - [[NSNotificationCenter defaultCenter] addObserver:_instance - selector:@selector(moviePlayBackDidFinish:) - name:MPMoviePlayerPlaybackDidFinishNotification - object:_instance.moviePlayerController]; - - [_instance.moviePlayerController.view setFrame:_instance.bounds]; - _instance.moviePlayerController.view.userInteractionEnabled = NO; - [_instance addSubview:_instance.moviePlayerController.view]; - [_instance.moviePlayerController play]; - - video_playing = true; - - return true; -} -*/ - bool _play_video(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) { p_path = Globals::get_singleton()->globalize_path(p_path); NSString* file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease]; - //NSURL *file_url = [NSURL fileURLWithPath:file_path]; _instance.avAsset = [AVAsset assetWithURL:[NSURL fileURLWithPath:file_path]]; + _instance.avPlayerItem =[[AVPlayerItem alloc]initWithAsset:_instance.avAsset]; [_instance.avPlayerItem addObserver:_instance forKeyPath:@"status" options:0 context:nil]; - _instance.avPlayer = [[AVPlayer alloc]initWithPlayerItem:_instance.avPlayerItem]; - _instance.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:_instance.avPlayer]; + _instance.avPlayer = [[AVPlayer alloc]initWithPlayerItem:_instance.avPlayerItem]; + _instance.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:_instance.avPlayer]; - [_instance.avPlayer addObserver:_instance forKeyPath:@"status" options:0 context:nil]; - [[NSNotificationCenter defaultCenter] addObserver:_instance + [_instance.avPlayer addObserver:_instance forKeyPath:@"status" options:0 context:nil]; + [[NSNotificationCenter defaultCenter] addObserver:_instance selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:[_instance.avPlayer currentItem]]; [_instance.avPlayer addObserver:_instance forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:0]; - [_instance.avPlayerLayer setFrame:_instance.bounds]; - [_instance.layer addSublayer:_instance.avPlayerLayer]; - [_instance.avPlayer play]; + [_instance.avPlayerLayer setFrame:_instance.bounds]; + [_instance.layer addSublayer:_instance.avPlayerLayer]; + [_instance.avPlayer play]; AVMediaSelectionGroup *audioGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic: AVMediaCharacteristicAudible]; @@ -173,23 +140,19 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s } } - video_playing = true; + video_playing = true; return true; } bool _is_video_playing() { - //NSInteger playback_state = _instance.moviePlayerController.playbackState; - //return video_playing || _instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying; - //if (video_found_error) - // return false; - //return (_instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying); - - return video_playing || (_instance.avPlayer.rate > 0 && !_instance.avPlayer.error); + if (_instance.avPlayer.error) { + printf("Error during playback\n"); + } + return (_instance.avPlayer.rate > 0 && !_instance.avPlayer.error); } void _pause_video() { - //[_instance.moviePlayerController pause]; video_current_time = _instance.avPlayer.currentTime; [_instance.avPlayer pause]; video_playing = false; @@ -204,15 +167,9 @@ void _unpause_video() { [_instance.avPlayer play]; video_playing = true; - - //video_current_time = kCMTimeZero; }; void _stop_video() { - //[_instance.moviePlayerController stop]; - //[_instance.moviePlayerController.view removeFromSuperview]; - //[[MPMusicPlayerController applicationMusicPlayer] setVolume: video_previous_volume]; - [_instance.avPlayer pause]; [_instance.avPlayerLayer removeFromSuperlayer]; _instance.avPlayer = nil; diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index ec62cb5c26..9f6b8433aa 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -41,6 +41,7 @@ #include "core/os/dir_access.h" #include "core/os/file_access.h" +#include "core/io/file_access_pack.h" #include "core/globals.h" #include "sem_iphone.h" @@ -517,12 +518,25 @@ extern void _focus_out_video(); Error OSIPhone::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) { FileAccess* f = FileAccess::open(p_path, FileAccess::READ); bool exists = f && f->is_open(); - printf("file exists for %ls, %i, %p\n", p_path.c_str(), (int)exists, f); - if (f) - memdelete(f); + + String tempFile = get_data_dir(); if (!exists) return FAILED; - if ( _play_video(p_path, p_volume, p_audio_track, p_subtitle_track) ) + + if (p_path.begins_with("res://")) { + if (PackedData::get_singleton()->has_path(p_path)) { + print("Unable to play %S using the native player as it resides in a .pck file\n", p_path.c_str()); + return ERR_INVALID_PARAMETER; + } else { + p_path = p_path.replace("res:/", Globals::get_singleton()->get_resource_path()); + } + } else if (p_path.begins_with("user://")) + p_path = p_path.replace("user:/", get_data_dir()); + + memdelete(f); + + print("Playing video: %S\n", p_path.c_str()); + if (_play_video(p_path, p_volume, p_audio_track, p_subtitle_track) ) return OK; return FAILED; } diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index abe797fed1..d34e8bfe95 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -195,12 +195,12 @@ public: void set_unique_ID(String p_ID); String get_unique_ID() const; - virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track); - virtual bool native_video_is_playing() const; - virtual void native_video_pause(); + virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track); + virtual bool native_video_is_playing() const; + virtual void native_video_pause(); virtual void native_video_unpause(); virtual void native_video_focus_out(); - virtual void native_video_stop(); + virtual void native_video_stop(); OSIPhone(int width, int height); ~OSIPhone(); diff --git a/platform/iphone/xcode/godot_xcode/data.pck b/platform/iphone/xcode/godot_xcode/data.pck new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/data.pck diff --git a/platform/iphone/xcode/godot_xcode/godot_debug.iphone b/platform/iphone/xcode/godot_xcode/godot_debug.iphone new file mode 100755 index 0000000000..e69de29bb2 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_debug.iphone diff --git a/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.pbxproj b/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..bdba8488c8 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.pbxproj @@ -0,0 +1,370 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + D07CD43F1C5D573600B7FB28 /* Default-568h@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4331C5D573600B7FB28 /* Default-568h@2x~iphone.png */; }; + D07CD4401C5D573600B7FB28 /* Default-667h.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4341C5D573600B7FB28 /* Default-667h.png */; }; + D07CD4411C5D573600B7FB28 /* Default-667h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4351C5D573600B7FB28 /* Default-667h@2x.png */; }; + D07CD4421C5D573600B7FB28 /* Default-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4361C5D573600B7FB28 /* Default-736h.png */; }; + D07CD4431C5D573600B7FB28 /* Default-736h@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4371C5D573600B7FB28 /* Default-736h@3x.png */; }; + D07CD4441C5D573600B7FB28 /* Default-Landscape-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4381C5D573600B7FB28 /* Default-Landscape-736h.png */; }; + D07CD4451C5D573600B7FB28 /* Default-Landscape@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4391C5D573600B7FB28 /* Default-Landscape@2x~ipad.png */; }; + D07CD4461C5D573600B7FB28 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43A1C5D573600B7FB28 /* Default-Landscape~ipad.png */; }; + D07CD4471C5D573600B7FB28 /* Default-Portrait@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43B1C5D573600B7FB28 /* Default-Portrait@2x~ipad.png */; }; + D07CD4481C5D573600B7FB28 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43C1C5D573600B7FB28 /* Default-Portrait~ipad.png */; }; + D07CD4491C5D573600B7FB28 /* Default@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43D1C5D573600B7FB28 /* Default@2x~iphone.png */; }; + D07CD44A1C5D573600B7FB28 /* Default~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43E1C5D573600B7FB28 /* Default~iphone.png */; }; + D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D07CD44D1C5D589C00B7FB28 /* Images.xcassets */; }; + D0BCFE3818AEBDA2004A7AAE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3718AEBDA2004A7AAE /* Foundation.framework */; }; + D0BCFE3A18AEBDA2004A7AAE /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3918AEBDA2004A7AAE /* CoreGraphics.framework */; }; + D0BCFE3C18AEBDA2004A7AAE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3B18AEBDA2004A7AAE /* UIKit.framework */; }; + D0BCFE3E18AEBDA2004A7AAE /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3D18AEBDA2004A7AAE /* GLKit.framework */; }; + D0BCFE4018AEBDA2004A7AAE /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3F18AEBDA2004A7AAE /* OpenGLES.framework */; }; + D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */; }; + D0BCFE7818AEBFEB004A7AAE /* data.pck in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE7718AEBFEB004A7AAE /* data.pck */; }; + D0BCFE7A18AEC06A004A7AAE /* godot_opt.iphone in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE7918AEC06A004A7AAE /* godot_opt.iphone */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D07CD4331C5D573600B7FB28 /* Default-568h@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x~iphone.png"; sourceTree = "<group>"; }; + D07CD4341C5D573600B7FB28 /* Default-667h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h.png"; sourceTree = "<group>"; }; + D07CD4351C5D573600B7FB28 /* Default-667h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h@2x.png"; sourceTree = "<group>"; }; + D07CD4361C5D573600B7FB28 /* Default-736h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h.png"; sourceTree = "<group>"; }; + D07CD4371C5D573600B7FB28 /* Default-736h@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h@3x.png"; sourceTree = "<group>"; }; + D07CD4381C5D573600B7FB28 /* Default-Landscape-736h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape-736h.png"; sourceTree = "<group>"; }; + D07CD4391C5D573600B7FB28 /* Default-Landscape@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape@2x~ipad.png"; sourceTree = "<group>"; }; + D07CD43A1C5D573600B7FB28 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = "<group>"; }; + D07CD43B1C5D573600B7FB28 /* Default-Portrait@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait@2x~ipad.png"; sourceTree = "<group>"; }; + D07CD43C1C5D573600B7FB28 /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = "<group>"; }; + D07CD43D1C5D573600B7FB28 /* Default@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x~iphone.png"; sourceTree = "<group>"; }; + D07CD43E1C5D573600B7FB28 /* Default~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default~iphone.png"; sourceTree = "<group>"; }; + D07CD44D1C5D589C00B7FB28 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; }; + D0BCFE3418AEBDA2004A7AAE /* godot_ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = godot_ios.app; sourceTree = BUILT_PRODUCTS_DIR; }; + D0BCFE3718AEBDA2004A7AAE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + D0BCFE3918AEBDA2004A7AAE /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + D0BCFE3B18AEBDA2004A7AAE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + D0BCFE3D18AEBDA2004A7AAE /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; }; + D0BCFE3F18AEBDA2004A7AAE /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + D0BCFE4318AEBDA2004A7AAE /* godot_ios-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "godot_ios-Info.plist"; sourceTree = "<group>"; }; + D0BCFE4518AEBDA2004A7AAE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; }; + D0BCFE4918AEBDA2004A7AAE /* godot_ios-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "godot_ios-Prefix.pch"; sourceTree = "<group>"; }; + D0BCFE6118AEBDA3004A7AAE /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + D0BCFE7718AEBFEB004A7AAE /* data.pck */ = {isa = PBXFileReference; lastKnownFileType = text; path = data.pck; sourceTree = "<group>"; }; + D0BCFE7918AEC06A004A7AAE /* godot_opt.iphone */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = godot_opt.iphone; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D0BCFE3118AEBDA2004A7AAE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D0BCFE4018AEBDA2004A7AAE /* OpenGLES.framework in Frameworks */, + D0BCFE3A18AEBDA2004A7AAE /* CoreGraphics.framework in Frameworks */, + D0BCFE3C18AEBDA2004A7AAE /* UIKit.framework in Frameworks */, + D0BCFE3E18AEBDA2004A7AAE /* GLKit.framework in Frameworks */, + D0BCFE3818AEBDA2004A7AAE /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D0BCFE2B18AEBDA2004A7AAE = { + isa = PBXGroup; + children = ( + D0BCFE7918AEC06A004A7AAE /* godot_opt.iphone */, + D0BCFE7718AEBFEB004A7AAE /* data.pck */, + D0BCFE4118AEBDA2004A7AAE /* godot_ios */, + D0BCFE3618AEBDA2004A7AAE /* Frameworks */, + D0BCFE3518AEBDA2004A7AAE /* Products */, + ); + sourceTree = "<group>"; + }; + D0BCFE3518AEBDA2004A7AAE /* Products */ = { + isa = PBXGroup; + children = ( + D0BCFE3418AEBDA2004A7AAE /* godot_ios.app */, + ); + name = Products; + sourceTree = "<group>"; + }; + D0BCFE3618AEBDA2004A7AAE /* Frameworks */ = { + isa = PBXGroup; + children = ( + D0BCFE3718AEBDA2004A7AAE /* Foundation.framework */, + D0BCFE3918AEBDA2004A7AAE /* CoreGraphics.framework */, + D0BCFE3B18AEBDA2004A7AAE /* UIKit.framework */, + D0BCFE3D18AEBDA2004A7AAE /* GLKit.framework */, + D0BCFE3F18AEBDA2004A7AAE /* OpenGLES.framework */, + D0BCFE6118AEBDA3004A7AAE /* XCTest.framework */, + ); + name = Frameworks; + sourceTree = "<group>"; + }; + D0BCFE4118AEBDA2004A7AAE /* godot_ios */ = { + isa = PBXGroup; + children = ( + D07CD4331C5D573600B7FB28 /* Default-568h@2x~iphone.png */, + D07CD4341C5D573600B7FB28 /* Default-667h.png */, + D07CD4351C5D573600B7FB28 /* Default-667h@2x.png */, + D07CD4361C5D573600B7FB28 /* Default-736h.png */, + D07CD4371C5D573600B7FB28 /* Default-736h@3x.png */, + D07CD4381C5D573600B7FB28 /* Default-Landscape-736h.png */, + D07CD4391C5D573600B7FB28 /* Default-Landscape@2x~ipad.png */, + D07CD43A1C5D573600B7FB28 /* Default-Landscape~ipad.png */, + D07CD43B1C5D573600B7FB28 /* Default-Portrait@2x~ipad.png */, + D07CD43C1C5D573600B7FB28 /* Default-Portrait~ipad.png */, + D07CD43D1C5D573600B7FB28 /* Default@2x~iphone.png */, + D07CD43E1C5D573600B7FB28 /* Default~iphone.png */, + D07CD44D1C5D589C00B7FB28 /* Images.xcassets */, + D0BCFE4218AEBDA2004A7AAE /* Supporting Files */, + ); + path = godot_ios; + sourceTree = "<group>"; + }; + D0BCFE4218AEBDA2004A7AAE /* Supporting Files */ = { + isa = PBXGroup; + children = ( + D0BCFE4318AEBDA2004A7AAE /* godot_ios-Info.plist */, + D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */, + D0BCFE4918AEBDA2004A7AAE /* godot_ios-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + D0BCFE3318AEBDA2004A7AAE /* godot_ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = D0BCFE7118AEBDA3004A7AAE /* Build configuration list for PBXNativeTarget "godot_ios" */; + buildPhases = ( + D0BCFE3018AEBDA2004A7AAE /* Sources */, + D0BCFE3118AEBDA2004A7AAE /* Frameworks */, + D0BCFE3218AEBDA2004A7AAE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = godot_ios; + productName = godot_ios; + productReference = D0BCFE3418AEBDA2004A7AAE /* godot_ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D0BCFE2C18AEBDA2004A7AAE /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0500; + ORGANIZATIONNAME = GodotEngine; + }; + buildConfigurationList = D0BCFE2F18AEBDA2004A7AAE /* Build configuration list for PBXProject "godot_ios" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = D0BCFE2B18AEBDA2004A7AAE; + productRefGroup = D0BCFE3518AEBDA2004A7AAE /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D0BCFE3318AEBDA2004A7AAE /* godot_ios */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D0BCFE3218AEBDA2004A7AAE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D07CD4471C5D573600B7FB28 /* Default-Portrait@2x~ipad.png in Resources */, + D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */, + D0BCFE7818AEBFEB004A7AAE /* data.pck in Resources */, + D07CD4461C5D573600B7FB28 /* Default-Landscape~ipad.png in Resources */, + D07CD4411C5D573600B7FB28 /* Default-667h@2x.png in Resources */, + D07CD4401C5D573600B7FB28 /* Default-667h.png in Resources */, + D07CD4431C5D573600B7FB28 /* Default-736h@3x.png in Resources */, + D07CD43F1C5D573600B7FB28 /* Default-568h@2x~iphone.png in Resources */, + D07CD4451C5D573600B7FB28 /* Default-Landscape@2x~ipad.png in Resources */, + D07CD44A1C5D573600B7FB28 /* Default~iphone.png in Resources */, + D07CD4491C5D573600B7FB28 /* Default@2x~iphone.png in Resources */, + D07CD4441C5D573600B7FB28 /* Default-Landscape-736h.png in Resources */, + D07CD4421C5D573600B7FB28 /* Default-736h.png in Resources */, + D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */, + D0BCFE7A18AEC06A004A7AAE /* godot_opt.iphone in Resources */, + D07CD4481C5D573600B7FB28 /* Default-Portrait~ipad.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D0BCFE3018AEBDA2004A7AAE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + D0BCFE4518AEBDA2004A7AAE /* en */, + ); + name = InfoPlist.strings; + sourceTree = "<group>"; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + D0BCFE6F18AEBDA3004A7AAE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + D0BCFE7018AEBDA3004A7AAE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + D0BCFE7218AEBDA3004A7AAE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD)"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "godot_ios/godot_ios-Prefix.pch"; + INFOPLIST_FILE = "godot_ios/godot_ios-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + PRODUCT_BUNDLE_IDENTIFIER = org.godotengine.game.ios; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALID_ARCHS = "armv7 armv7s"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + D0BCFE7318AEBDA3004A7AAE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD)"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Distribution: Ariel Manzur (BYC57PA2Q5)"; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "godot_ios/godot_ios-Prefix.pch"; + INFOPLIST_FILE = "godot_ios/godot_ios-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + PRODUCT_BUNDLE_IDENTIFIER = org.godotengine.game.ios; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALID_ARCHS = "armv7 armv7s"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D0BCFE2F18AEBDA2004A7AAE /* Build configuration list for PBXProject "godot_ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0BCFE6F18AEBDA3004A7AAE /* Debug */, + D0BCFE7018AEBDA3004A7AAE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D0BCFE7118AEBDA3004A7AAE /* Build configuration list for PBXNativeTarget "godot_ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D0BCFE7218AEBDA3004A7AAE /* Debug */, + D0BCFE7318AEBDA3004A7AAE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D0BCFE2C18AEBDA2004A7AAE /* Project object */; +} diff --git a/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..3c9ba38bbe --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "self:godot_ios.xcodeproj"> + </FileRef> +</Workspace> diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-568h@2x~iphone.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-568h@2x~iphone.png Binary files differnew file mode 100644 index 0000000000..1341174454 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-568h@2x~iphone.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h.png Binary files differnew file mode 100644 index 0000000000..c480d2e3c0 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h@2x.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h@2x.png Binary files differnew file mode 100644 index 0000000000..3cc1dfa290 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h@2x.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h.png Binary files differnew file mode 100644 index 0000000000..813d689162 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h@3x.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h@3x.png Binary files differnew file mode 100644 index 0000000000..7707005e76 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h@3x.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape-736h.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape-736h.png Binary files differnew file mode 100644 index 0000000000..b02873323e --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape-736h.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape@2x~ipad.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape@2x~ipad.png Binary files differnew file mode 100644 index 0000000000..d86c4a2510 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape@2x~ipad.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape~ipad.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape~ipad.png Binary files differnew file mode 100644 index 0000000000..e4f6cef02b --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape~ipad.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait@2x~ipad.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait@2x~ipad.png Binary files differnew file mode 100644 index 0000000000..f306652a31 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait@2x~ipad.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait~ipad.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait~ipad.png Binary files differnew file mode 100644 index 0000000000..71a16db6df --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait~ipad.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default@2x~iphone.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default@2x~iphone.png Binary files differnew file mode 100644 index 0000000000..5305cb9bdb --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default@2x~iphone.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default~iphone.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default~iphone.png Binary files differnew file mode 100644 index 0000000000..91c62d1e43 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default~iphone.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Contents.json b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..a458b67873 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,128 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "1x", + "filename": "Icon-29.png", + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x", + "filename": "Icon-58.png", + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x", + "filename": "icon-87.png", + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x", + "filename": "Icon-80.png", + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x", + "filename": "Icon-120.png", + }, + { + "idiom" : "iphone", + "size" : "57x57", + "scale" : "1x", + "filename": "Icon-57.png", + }, + { + "idiom" : "iphone", + "size" : "57x57", + "scale" : "2x", + "filename": "Icon-114.png", + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x", + "filename": "Icon-120.png", + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x", + "filename": "Icon-180.png", + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x", + "filename": "Icon-29.png", + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x", + "filename": "Icon-58.png", + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x", + "filename": "Icon-40.png", + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x", + "filename": "Icon-80.png", + }, + { + "idiom" : "ipad", + "size" : "50x50", + "scale" : "1x", + "filename": "Icon-50.png", + }, + { + "idiom" : "ipad", + "size" : "50x50", + "scale" : "2x", + "filename": "Icon-100.png", + }, + { + "idiom" : "ipad", + "size" : "72x72", + "scale" : "1x", + "filename": "Icon-72.png", + }, + { + "idiom" : "ipad", + "size" : "72x72", + "scale" : "2x", + "filename": "Icon-144.png", + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-76.png", + "scale" : "1x", + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x", + "filename": "Icon-152.png", + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x", + "filename": "icon-167.png", + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-100.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-100.png Binary files differnew file mode 100644 index 0000000000..f9dca1ab57 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-100.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-114.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-114.png Binary files differnew file mode 100644 index 0000000000..e7f9bd7388 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-114.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-120.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-120.png Binary files differnew file mode 100644 index 0000000000..4faa0f28e2 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-120.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-144.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-144.png Binary files differnew file mode 100644 index 0000000000..1c4cb51d56 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-144.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-152.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-152.png Binary files differnew file mode 100644 index 0000000000..e99b11c519 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-152.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-180.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-180.png Binary files differnew file mode 100644 index 0000000000..3edbcadfc5 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-180.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-29.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-29.png Binary files differnew file mode 100644 index 0000000000..0ae5893203 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-29.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-40.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-40.png Binary files differnew file mode 100644 index 0000000000..bb4ffa70ad --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-40.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-50.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-50.png Binary files differnew file mode 100644 index 0000000000..7a4b7107e7 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-50.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-57.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-57.png Binary files differnew file mode 100644 index 0000000000..b00bd79091 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-57.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-58.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-58.png Binary files differnew file mode 100644 index 0000000000..46335efdf6 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-58.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-60.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-60.png Binary files differnew file mode 100644 index 0000000000..2c9c2b61dc --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-60.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-72.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-72.png Binary files differnew file mode 100644 index 0000000000..d711958ef1 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-72.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-76.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-76.png Binary files differnew file mode 100644 index 0000000000..464e7e7289 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-76.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-80.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-80.png Binary files differnew file mode 100644 index 0000000000..1151bc6b4b --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-80.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-167.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-167.png Binary files differnew file mode 100644 index 0000000000..487c8326be --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-167.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-87.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-87.png Binary files differnew file mode 100644 index 0000000000..e54cee23a6 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-87.png diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/sizes b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/sizes new file mode 100644 index 0000000000..e328a62cb6 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/sizes @@ -0,0 +1,17 @@ +100 +114 +120 +144 +152 +167 +180 +29 +40 +50 +57 +58 +60 +72 +76 +80 +87 diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/en.lproj/InfoPlist.strings b/platform/iphone/xcode/godot_xcode/godot_ios/en.lproj/InfoPlist.strings new file mode 100644 index 0000000000..477b28ff8f --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/godot_ios-Info.plist b/platform/iphone/xcode/godot_xcode/godot_ios/godot_ios-Info.plist new file mode 100644 index 0000000000..f97b0fca36 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/godot_ios-Info.plist @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleDisplayName</key> + <string>Insert Name Here</string> + <key>CFBundleExecutable</key> + <string>godot_opt.iphone</string> + <key>CFBundleIcons</key> + <dict/> + <key>CFBundleIcons~ipad</key> + <dict/> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1.0</string> + <key>LSRequiresIPhoneOS</key> + <true/> + <key>UIRequiredDeviceCapabilities</key> + <array> + <string>armv7</string> + </array> + <key>UIRequiresFullScreen</key> + <true/> + <key>UIStatusBarHidden</key> + <true/> + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> + <key>UISupportedInterfaceOrientations~ipad</key> + <array> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> +</dict> +</plist> diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/main.m b/platform/iphone/xcode/godot_xcode/godot_ios/main.m new file mode 100644 index 0000000000..3e4ea5e129 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_ios/main.m @@ -0,0 +1,39 @@ +/*************************************************************************/ +/* main.m */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#import <UIKit/UIKit.h> + +#import "AppDelegate.h" + +int main(int argc, char * argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/platform/iphone/xcode/godot_xcode/godot_opt.iphone b/platform/iphone/xcode/godot_xcode/godot_opt.iphone new file mode 100755 index 0000000000..e69de29bb2 --- /dev/null +++ b/platform/iphone/xcode/godot_xcode/godot_opt.iphone diff --git a/platform/nacl/nacl_keycodes.h b/platform/nacl/nacl_keycodes.h index 45dba075db..a0642fc3b7 100644 --- a/platform/nacl/nacl_keycodes.h +++ b/platform/nacl/nacl_keycodes.h @@ -286,7 +286,7 @@ static uint32_t godot_key(uint32_t p_key, bool& is_char) { case VKEY_MULTIPLY: return KEY_KP_MULTIPLY; case VKEY_ADD: return KEY_KP_ADD; // case VKEY_SEPARATOR: return KEY_SEPARATOR; - case VKEY_SUBTRACT: return KEY_KP_SUBSTRACT; + case VKEY_SUBTRACT: return KEY_KP_SUBTRACT; case VKEY_DECIMAL: return KEY_KP_PERIOD; case VKEY_DIVIDE: return KEY_KP_DIVIDE; case VKEY_F1: return KEY_F1; diff --git a/platform/osx/audio_driver_osx.cpp b/platform/osx/audio_driver_osx.cpp index a74303e6c2..d9d91b22fb 100644 --- a/platform/osx/audio_driver_osx.cpp +++ b/platform/osx/audio_driver_osx.cpp @@ -172,6 +172,9 @@ void AudioDriverOSX::unlock() { void AudioDriverOSX::finish() { + if (active) + AudioOutputUnitStop(audio_unit); + memdelete_arr(samples_in); }; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 2bb35fdc60..bb99e6ade7 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -650,7 +650,7 @@ static int translateKey(unsigned int key) /* 4b */ KEY_KP_DIVIDE, /* 4c */ KEY_KP_ENTER, /* 4d */ KEY_UNKNOWN, - /* 4e */ KEY_KP_SUBSTRACT, + /* 4e */ KEY_KP_SUBTRACT, /* 4f */ KEY_UNKNOWN, /* 50 */ KEY_UNKNOWN, /* 51 */ KEY_EQUAL, //wtf equal? @@ -809,6 +809,21 @@ static int translateKey(unsigned int key) OS_OSX::singleton->push_input(ev); } + if (fabs(deltaX)) { + + InputEvent ev; + ev.type=InputEvent::MOUSE_BUTTON; + ev.mouse_button.button_index=deltaX >0 ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_LEFT; + ev.mouse_button.pressed=true; + ev.mouse_button.x=mouse_x; + ev.mouse_button.y=mouse_y; + ev.mouse_button.global_x=mouse_x; + ev.mouse_button.global_y=mouse_y; + ev.mouse_button.button_mask=button_mask; + OS_OSX::singleton->push_input(ev); + ev.mouse_button.pressed=false; + OS_OSX::singleton->push_input(ev); + } } @end diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 0d7ee64d80..1ad0f164d2 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -262,7 +262,7 @@ def configure(env): env.Append(CCFLAGS=["/I"+DIRECTX_PATH+"/Include"]) env.Append(LIBPATH=[DIRECTX_PATH+"/Lib/x86"]) env['ENV'] = os.environ; - env["x86_opt_vc"]=env["bits"]!="64" + env["x86_opt_vc"]=True else: # Workaround for MinGW. See: @@ -305,7 +305,7 @@ def configure(env): if (env["target"]=="release"): - env.Append(CCFLAGS=['-ffast-math','-fomit-frame-pointer','-msse2']) + env.Append(CCFLAGS=['-msse2']) if (env["bits"]=="64"): env.Append(CCFLAGS=['-O3']) diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index 899edde087..952f51fdd4 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -1,345 +1,6 @@ -/*************************************************************************/ -/* export.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - #include "export.h" #include "platform/windows/logo.h" -#include "os/os.h" -#include "globals.h" -#include "tools/editor/editor_node.h" -#include "tools/pe_bliss/pe_bliss_godot.h" - -/** - @author Masoud BaniHashemian <masoudbh3@gmail.com> -*/ - - -void EditorExportPlatformWindows::store_16(DVector<uint8_t>& vector, uint16_t value) { - const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&value); - int size = vector.size(); - vector.resize( size + 2 ); - DVector<uint8_t>::Write w = vector.write(); - w[size]=bytes[0]; - w[size+1]=bytes[1]; -} -void EditorExportPlatformWindows::store_32(DVector<uint8_t>& vector, uint32_t value) { - const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&value); - int size = vector.size(); - vector.resize( size + 4 ); - DVector<uint8_t>::Write w = vector.write(); - w[size]=bytes[0]; - w[size+1]=bytes[1]; - w[size+2]=bytes[2]; - w[size+3]=bytes[3]; -} - -bool EditorExportPlatformWindows::_set(const StringName& p_name, const Variant& p_value) { - - String n = p_name; - - if (n=="icon/icon_ico") { - - icon_ico=p_value; - } else if (n=="icon/icon_png") { - - icon_png=p_value; - } else if (n=="icon/icon_png16x16") { - - icon16=p_value; - } else if (n=="icon/icon_png32x32") { - - icon32=p_value; - } else if (n=="icon/icon_png48x48") { - - icon48=p_value; - } else if (n=="icon/icon_png64x64") { - - icon64=p_value; - } else if (n=="icon/icon_png128x128") { - - icon128=p_value; - } else if (n=="icon/icon_png256x256") { - - icon256=p_value; - } else if (n=="version_info/version_major") { - - version_major=p_value; - } else if (n=="version_info/version_minor") { - - version_minor=p_value; - } else if (n=="version_info/version_text") { - - version_text=p_value; - } else if (n=="version_info/company_name") { - - company_name=p_value; - } else if (n=="version_info/file_description") { - - file_description=p_value; - } else if (n=="version_info/product_name") { - - product_name=p_value; - } else if (n=="version_info/legal_copyright") { - - legal_copyright=p_value; - } else if (n=="version_info/add_godot_version") { - - set_godot_version=p_value; - } else - return false; - - return true; - -} - -bool EditorExportPlatformWindows::_get(const StringName& p_name,Variant &r_ret) const { - - String n = p_name; - - if (n=="icon/icon_ico") { - - r_ret=icon_ico; - } else if (n=="icon/icon_png") { - - r_ret=icon_png; - } else if (n=="icon/icon_png16x16") { - - r_ret=icon16; - } else if (n=="icon/icon_png32x32") { - - r_ret=icon32; - } else if (n=="icon/icon_png48x48") { - - r_ret=icon48; - } else if (n=="icon/icon_png64x64") { - - r_ret=icon64; - } else if (n=="icon/icon_png128x128") { - - r_ret=icon128; - } else if (n=="icon/icon_png256x256") { - - r_ret=icon256; - } else if (n=="version_info/version_major") { - - r_ret=version_major; - } else if (n=="version_info/version_minor") { - - r_ret=version_minor; - } else if (n=="version_info/version_text") { - - r_ret=version_text; - } else if (n=="version_info/company_name") { - - r_ret=company_name; - } else if (n=="version_info/file_description") { - - r_ret=file_description; - } else if (n=="version_info/product_name") { - - r_ret=product_name; - } else if (n=="version_info/legal_copyright") { - - r_ret=legal_copyright; - } else if (n=="version_info/add_godot_version") { - - r_ret=set_godot_version; - } else - return false; - - return true; - -} - -void EditorExportPlatformWindows::_get_property_list( List<PropertyInfo> *p_list) const { - - p_list->push_back( PropertyInfo( Variant::STRING, "icon/icon_ico",PROPERTY_HINT_FILE,"ico") ); - p_list->push_back( PropertyInfo( Variant::STRING, "icon/icon_png",PROPERTY_HINT_FILE,"png") ); - p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png16x16") ); - p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png32x32") ); - p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png48x48") ); - p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png64x64") ); - p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png128x128") ); - p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png256x256") ); - p_list->push_back( PropertyInfo( Variant::INT, "version_info/version_major", PROPERTY_HINT_RANGE,"0,65535,1")); - p_list->push_back( PropertyInfo( Variant::INT, "version_info/version_minor", PROPERTY_HINT_RANGE,"0,65535,0")); - p_list->push_back( PropertyInfo( Variant::STRING, "version_info/version_text") ); - p_list->push_back( PropertyInfo( Variant::STRING, "version_info/company_name") ); - p_list->push_back( PropertyInfo( Variant::STRING, "version_info/file_description") ); - p_list->push_back( PropertyInfo( Variant::STRING, "version_info/product_name") ); - p_list->push_back( PropertyInfo( Variant::STRING, "version_info/legal_copyright") ); - p_list->push_back( PropertyInfo( Variant::BOOL, "version_info/add_godot_version") ); - -} - -Error EditorExportPlatformWindows::export_project(const String& p_path, bool p_debug, int p_flags) { - - Error err = EditorExportPlatformPC::export_project(p_path, p_debug, p_flags); - if(err != OK) - { - return err; - } - EditorProgress ep("editexe","Edit EXE File",102); - ep.step("Create ico file..",0); - - DVector<uint8_t> icon_content; - if (this->icon_ico!="" && this->icon_ico.ends_with(".ico")) { - FileAccess *f = FileAccess::open(this->icon_ico,FileAccess::READ); - if (f) { - icon_content.resize(f->get_len()); - DVector<uint8_t>::Write write = icon_content.write(); - f->get_buffer(write.ptr(),icon_content.size()); - f->close(); - memdelete(f); - } - } else if (this->icon_png!="" && this->icon_png.ends_with(".png") && (icon16 || icon32 || icon48 || icon64 || icon128 || icon256)) { - #ifdef PNG_ENABLED - Vector<Image> pngs; - Image png; - Error err_png = png.load(this->icon_png); - if (err_png==OK && !png.empty()) { - if(icon256) { - Image icon_256(png); - if(!(png.get_height()==256 && png.get_width()==256)) icon_256.resize(256,256); - pngs.push_back(icon_256); - } - if(icon128) { - Image icon_128(png); - if(!(png.get_height()==128 && png.get_width()==128)) icon_128.resize(128,128); - pngs.push_back(icon_128); - } - if(icon64) { - Image icon_64(png); - if(!(png.get_height()==64 && png.get_width()==64)) icon_64.resize(64,64); - pngs.push_back(icon_64); - } - if(icon48) { - Image icon_48(png); - if(!(png.get_height()==48 && png.get_width()==48)) icon_48.resize(48,48); - pngs.push_back(icon_48); - } - if(icon32) { - Image icon_32(png); - if(!(png.get_height()==32 && png.get_width()==32)) icon_32.resize(32,32); - pngs.push_back(icon_32); - } - if(icon16) { - Image icon_16(png); - if(!(png.get_height()==16 && png.get_width()==16)) icon_16.resize(16,16); - pngs.push_back(icon_16); - } - // create icon according to https://www.daubnet.com/en/file-format-ico - store_16(icon_content,0); //Reserved - store_16(icon_content,1); //Type - store_16(icon_content,pngs.size()); //Count - int offset = 6+pngs.size()*16; - //List of bitmaps - for(int i=0;i<pngs.size();i++) { - int w = pngs[i].get_width(); - int h = pngs[i].get_height(); - icon_content.push_back(w<256?w:0); //width - icon_content.push_back(h<256?h:0); //height - icon_content.push_back(0); //ColorCount = 0 - icon_content.push_back(0); //Reserved - store_16(icon_content,1); //Planes - store_16(icon_content,32); //BitCount (bit per pixel) - int size = 40 + (w * h * 4) + (w * h / 8); - store_32(icon_content,size); //Size of (InfoHeader + ANDbitmap + XORbitmap) - store_32(icon_content,offset); //FileOffset - offset += size; - } - //Write bmp files. - for(int i=0;i<pngs.size();i++) { - int w = pngs[i].get_width(); - int h = pngs[i].get_height(); - store_32(icon_content,40); //Size of InfoHeader structure = 40 - store_32(icon_content,w); //Width - store_32(icon_content,h*2); //Height - store_16(icon_content,1); //Planes - store_16(icon_content,32); //BitCount - store_32(icon_content,0); //Compression - store_32(icon_content,w*h*4); //ImageSize = Size of Image in Bytes - store_32(icon_content,0); //unused = 0 - store_32(icon_content,0); //unused = 0 - store_32(icon_content,0); //unused = 0 - store_32(icon_content,0); //unused = 0 - //XORBitmap - for(int y=h-1;y>=0;y--) { - for(int x=0;x<w;x++) { - store_32(icon_content,pngs[i].get_pixel(x,y).to_32()); - } - } - //ANDBitmap - for(int m=0;m<(w * h / 8);m+=4) store_32(icon_content,0x00000000); // Add empty ANDBitmap , TODO create full ANDBitmap Structure if need. - } - } - #endif - } - - ep.step("Add rsrc..",50); - - String basename = Globals::get_singleton()->get("application/name"); - product_name=product_name.replace("$genname",basename); - String godot_version; - if(set_godot_version) godot_version = String( VERSION_MKSTRING ); - String ret = pe_bliss_add_resrc(p_path.utf8(), version_major, version_minor, - company_name, file_description, legal_copyright, version_text, - product_name, godot_version, icon_content); - if (ret.empty()) { - return OK; - } else { - EditorNode::add_io_error(ret); - return ERR_FILE_CANT_WRITE; - } -} - -EditorExportPlatformWindows::EditorExportPlatformWindows() { - - icon16=true; - icon32=true; - icon48=true; - icon64=true; - icon128=true; - icon256=true; - product_name="$genname"; - company_name="Godot Engine"; - file_description="Created With Godot Engine"; - version_text="1.0"; - OS::Date date = OS::get_singleton()->get_date(); - legal_copyright="Copyright (c) 2007-"; - legal_copyright+=String::num(date.year); - legal_copyright+=" Juan Linietsky, Ariel Manzur"; - version_major=1; - version_minor=0; - set_godot_version=true; -} - - +#include "tools/editor/editor_import_export.h" void register_windows_exporter() { @@ -348,7 +9,7 @@ void register_windows_exporter() { logo->create_from_image(img); { - Ref<EditorExportPlatformWindows> exporter = Ref<EditorExportPlatformWindows>( memnew(EditorExportPlatformWindows) ); + Ref<EditorExportPlatformPC> exporter = Ref<EditorExportPlatformPC>( memnew(EditorExportPlatformPC) ); exporter->set_binary_extension("exe"); exporter->set_release_binary32("windows_32_release.exe"); exporter->set_debug_binary32("windows_32_debug.exe"); diff --git a/platform/windows/export/export.h b/platform/windows/export/export.h index 2424efc861..68ce500a20 100644 --- a/platform/windows/export/export.h +++ b/platform/windows/export/export.h @@ -1,37 +1,4 @@ -#include "tools/editor/editor_import_export.h" -class EditorExportPlatformWindows : public EditorExportPlatformPC { - OBJ_TYPE( EditorExportPlatformWindows,EditorExportPlatformPC ); - -private: - String icon_ico; - String icon_png; - bool icon16; - bool icon32; - bool icon48; - bool icon64; - bool icon128; - bool icon256; - String company_name; - String file_description; - String product_name; - String legal_copyright; - String version_text; - int version_major; - int version_minor; - bool set_godot_version; - void store_16(DVector<uint8_t>& vector, uint16_t value); ///< store 16 bits uint - void store_32(DVector<uint8_t>& vector, uint32_t value); ///< store 32 bits uint - -protected: - bool _set(const StringName& p_name, const Variant& p_value); - bool _get(const StringName& p_name,Variant &r_ret) const; - void _get_property_list( List<PropertyInfo> *p_list) const; - -public: - Error export_project(const String& p_path, bool p_debug,int p_flags=0); - EditorExportPlatformWindows(); -}; void register_windows_exporter(); diff --git a/platform/windows/joystick.cpp b/platform/windows/joystick.cpp index f4fb09820f..f8526b5ec1 100644 --- a/platform/windows/joystick.cpp +++ b/platform/windows/joystick.cpp @@ -472,7 +472,7 @@ InputDefault::JoyAxis joystick_windows::axis_correct(int p_val, bool p_xinput, b InputDefault::JoyAxis jx; if (Math::abs(p_val) < MIN_JOY_AXIS) { - jx.min = -1; + jx.min = p_trigger ? 0 : -1; jx.value = 0.0f; return jx; } diff --git a/platform/windows/key_mapping_win.cpp b/platform/windows/key_mapping_win.cpp index 07d5f32253..23fa29d68f 100644 --- a/platform/windows/key_mapping_win.cpp +++ b/platform/windows/key_mapping_win.cpp @@ -145,7 +145,7 @@ static _WinTranslatePair _vk_to_keycode[]={ { KEY_KP_MULTIPLY,VK_MULTIPLY},// (0x6A) { KEY_KP_ADD,VK_ADD},// (0x6B) //VK_SEPARATOR (0x6C) -{ KEY_KP_SUBSTRACT,VK_SUBTRACT},// (0x6D) +{ KEY_KP_SUBTRACT,VK_SUBTRACT},// (0x6D) { KEY_KP_PERIOD,VK_DECIMAL},// (0x6E) { KEY_KP_DIVIDE,VK_DIVIDE},// (0x6F) { KEY_F1,VK_F1},// (0x70) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 886c43d116..95a6a6ac58 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -47,7 +47,6 @@ #include "tcp_server_winsock.h" #include "packet_peer_udp_winsock.h" #include "stream_peer_winsock.h" -#include "os/pc_joystick_map.h" #include "lang_table.h" #include "os/memory_pool_dynamic_prealloc.h" #include "globals.h" @@ -67,6 +66,10 @@ extern "C" { #endif } +#ifndef WM_MOUSEHWHEEL +#define WM_MOUSEHWHEEL 0x020e +#endif + //#define STDOUT_FILE extern HINSTANCE godot_hinstance; @@ -433,6 +436,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_MOUSEWHEEL: + case WM_MOUSEHWHEEL: case WM_LBUTTONDBLCLK: case WM_RBUTTONDBLCLK: /*case WM_XBUTTONDOWN: @@ -503,12 +507,24 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { if (motion>0) - mb.button_index=4; + mb.button_index= BUTTON_WHEEL_UP; else - mb.button_index=5; + mb.button_index= BUTTON_WHEEL_DOWN; } break; + case WM_MOUSEHWHEEL: { + + mb.pressed = true; + int motion = (short)HIWORD(wParam); + if (!motion) + return 0; + + if (motion<0) + mb.button_index = BUTTON_WHEEL_LEFT; + else + mb.button_index = BUTTON_WHEEL_RIGHT; + } break; /* case WM_XBUTTONDOWN: { mb.pressed=true; @@ -2059,7 +2075,7 @@ String OS_Windows::get_system_dir(SystemDir p_dir) const { id=CSIDL_MYPICTURES; } break; case SYSTEM_DIR_DOCUMENTS: { - id=0x000C; + id=CSIDL_PERSONAL; } break; case SYSTEM_DIR_DOWNLOADS: { id=0x000C ; diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index e433d5cc11..ab4acf312c 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -29,7 +29,7 @@ #ifndef OS_WINDOWS_H #define OS_WINDOWS_H -#define WINVER 0x0500 +#define WINVER 0x0600 #include "os/input.h" #include "os/os.h" diff --git a/platform/winrt/os_winrt.cpp b/platform/winrt/os_winrt.cpp index f507c1aae7..b6ce7f950d 100644 --- a/platform/winrt/os_winrt.cpp +++ b/platform/winrt/os_winrt.cpp @@ -43,7 +43,6 @@ #include "servers/audio/audio_server_sw.h" #include "servers/visual/visual_server_wrap_mt.h" -#include "os/pc_joystick_map.h" #include "os/memory_pool_dynamic_prealloc.h" #include "globals.h" #include "io/marshalls.h" diff --git a/platform/x11/detect.py b/platform/x11/detect.py index e035c72993..6b147db130 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -52,10 +52,11 @@ def get_opts(): return [ ('use_llvm','Use llvm compiler','no'), + ('use_static_cpp','link stdc++ statically','no'), ('use_sanitizer','Use llvm compiler sanitize address','no'), ('use_leak_sanitizer','Use llvm compiler sanitize memory leaks','no'), ('pulseaudio','Detect & Use pulseaudio','yes'), - ('gamepad','Gamepad support, requires libudev and libevdev','yes'), + ('udev','Use udev for gamepad connection callbacks','no'), ('new_wm_api', 'Use experimental window management API','no'), ('debug_release', 'Add debug symbols to release version','no'), ] @@ -155,24 +156,18 @@ def configure(env): else: print("ALSA libraries not found, disabling driver") - if (env["gamepad"]=="yes" and platform.system() == "Linux"): + if (platform.system() == "Linux"): + env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"]) + if (env["udev"]=="yes"): # pkg-config returns 0 when the lib exists... found_udev = not os.system("pkg-config --exists libudev") - found_evdev = not os.system("pkg-config --exists libevdev") - - if (found_udev and found_evdev): - print("Enabling gamepad support with udev/evdev") - env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"]) + + if (found_udev): + print("Enabling udev support") + env.Append(CPPFLAGS=["-DUDEV_ENABLED"]) env.ParseConfig('pkg-config libudev --cflags --libs') - env.ParseConfig('pkg-config libevdev --cflags --libs') else: - if (not found_udev): - print("libudev development libraries not found") - if (not found_evdev): - print("libevdev development libraries not found") - print("Some libraries are missing for the required gamepad support, aborting!") - print("Install the mentioned libraries or build with 'gamepad=no' to disable gamepad support.") - sys.exit(255) + print("libudev development libraries not found, disabling udev support") if (env["pulseaudio"]=="yes"): if not os.system("pkg-config --exists libpulse-simple"): @@ -207,5 +202,8 @@ def configure(env): env.Append(CPPFLAGS=['-DNEW_WM_API']) env.ParseConfig('pkg-config xinerama --cflags --libs') + if (env["use_static_cpp"]=="yes"): + env.Append(LINKFLAGS=['-static-libstdc++']) + env["x86_opt_gcc"]=True diff --git a/platform/x11/joystick_linux.cpp b/platform/x11/joystick_linux.cpp index 6eb3671bc0..9a52c4ff36 100644 --- a/platform/x11/joystick_linux.cpp +++ b/platform/x11/joystick_linux.cpp @@ -31,22 +31,38 @@ #ifdef JOYDEV_ENABLED #include "joystick_linux.h" -#include "print_string.h" -#include <libevdev/libevdev.h> -#include <libudev.h> +#include <linux/input.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> -#include <cstring> + +#ifdef UDEV_ENABLED +#include <libudev.h> +#endif + +#define LONG_BITS (sizeof(long) * 8) +#define test_bit(nr, addr) (((1UL << ((nr) % LONG_BITS)) & ((addr)[(nr) / LONG_BITS])) != 0) +#define NBITS(x) ((((x)-1)/LONG_BITS)+1) static const char* ignore_str = "/dev/input/js"; joystick_linux::Joystick::Joystick() { fd = -1; dpad = 0; - dev = NULL; devpath = ""; + for (int i = 0; i < MAX_ABS; i++) { + abs_info[i] = NULL; + } +} + +joystick_linux::Joystick::~Joystick() { + + for (int i = 0; i < MAX_ABS; i++) { + if (abs_info[i]) { + memdelete(abs_info[i]); + } + } } void joystick_linux::Joystick::reset() { @@ -86,14 +102,18 @@ void joystick_linux::joy_thread_func(void *p_user) { } void joystick_linux::run_joystick_thread() { - +#ifdef UDEV_ENABLED udev *_udev = udev_new(); ERR_FAIL_COND(!_udev); enumerate_joysticks(_udev); monitor_joysticks(_udev); udev_unref(_udev); +#else + monitor_joysticks(); +#endif } +#ifdef UDEV_ENABLED void joystick_linux::enumerate_joysticks(udev *p_udev) { udev_enumerate *enumerate; @@ -112,10 +132,14 @@ void joystick_linux::enumerate_joysticks(udev *p_udev) { dev = udev_device_new_from_syspath(p_udev, path); const char* devnode = udev_device_get_devnode(dev); - if (devnode != NULL && strstr(devnode, ignore_str) == NULL) { - joy_mutex->lock(); - open_joystick(devnode); - joy_mutex->unlock(); + if (devnode) { + + String devnode_str = devnode; + if (devnode_str.find(ignore_str) == -1) { + joy_mutex->lock(); + open_joystick(devnode); + joy_mutex->unlock(); + } } udev_device_unref(dev); } @@ -146,22 +170,24 @@ void joystick_linux::monitor_joysticks(udev *p_udev) { /* Check if our file descriptor has received data. */ if (ret > 0 && FD_ISSET(fd, &fds)) { /* Make the call to receive the device. - select() ensured that this will not block. */ + select() ensured that this will not block. */ dev = udev_monitor_receive_device(mon); if (dev && udev_device_get_devnode(dev) != 0) { joy_mutex->lock(); - const char* action = udev_device_get_action(dev); + String action = udev_device_get_action(dev); const char* devnode = udev_device_get_devnode(dev); + if (devnode) { - if (strstr(devnode, ignore_str) == NULL) { + String devnode_str = devnode; + if (devnode_str.find(ignore_str) == -1) { - if (strcmp(action, "add") == 0) - open_joystick(devnode); - - else if (strcmp(action, "remove") == 0) - close_joystick(get_joy_from_path(devnode)); + if (action == "add") + open_joystick(devnode); + else if (String(action) == "remove") + close_joystick(get_joy_from_path(devnode)); + } } udev_device_unref(dev); @@ -173,6 +199,23 @@ void joystick_linux::monitor_joysticks(udev *p_udev) { //printf("exit udev\n"); udev_monitor_unref(mon); } +#endif + +void joystick_linux::monitor_joysticks() { + + while (!exit_udev) { + joy_mutex->lock(); + for (int i = 0; i < 32; i++) { + char fname[64]; + sprintf(fname, "/dev/input/event%d", i); + if (attached_devices.find(fname) == -1) { + open_joystick(fname); + } + } + joy_mutex->unlock(); + usleep(1000000); // 1s + } +} int joystick_linux::get_free_joy_slot() const { @@ -208,9 +251,9 @@ void joystick_linux::close_joystick(int p_id) { if (joy.fd != -1) { - libevdev_free(joy.dev); close(joy.fd); joy.fd = -1; + attached_devices.remove(attached_devices.find(joy.devpath)); input->joy_connection_changed(p_id, false, ""); }; }; @@ -230,21 +273,27 @@ static String _hex_str(uint8_t p_byte) { void joystick_linux::setup_joystick_properties(int p_id) { Joystick* joy = &joysticks[p_id]; - libevdev* dev = joy->dev; + + unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; + unsigned long absbit[NBITS(ABS_MAX)] = { 0 }; int num_buttons = 0; int num_axes = 0; + if ((ioctl(joy->fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) || + (ioctl(joy->fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) { + return; + } for (int i = BTN_JOYSTICK; i < KEY_MAX; ++i) { - if (libevdev_has_event_code(dev, EV_KEY, i)) { + if (test_bit(i, keybit)) { joy->key_map[i] = num_buttons++; } } for (int i = BTN_MISC; i < BTN_JOYSTICK; ++i) { - if (libevdev_has_event_code(dev, EV_KEY, i)) { + if (test_bit(i, keybit)) { joy->key_map[i] = num_buttons++; } @@ -255,68 +304,88 @@ void joystick_linux::setup_joystick_properties(int p_id) { i = ABS_HAT3Y; continue; } - if (libevdev_has_event_code(dev, EV_ABS, i)) { + if (test_bit(i, absbit)) { joy->abs_map[i] = num_axes++; + joy->abs_info[i] = memnew(input_absinfo); + if (ioctl(joy->fd, EVIOCGABS(i), joy->abs_info[i]) < 0) { + memdelete(joy->abs_info[i]); + joy->abs_info[i] = NULL; + } } } } + void joystick_linux::open_joystick(const char *p_path) { int joy_num = get_free_joy_slot(); int fd = open(p_path, O_RDONLY | O_NONBLOCK); if (fd != -1 && joy_num != -1) { - int rc = libevdev_new_from_fd(fd, &joysticks[joy_num].dev); - if (rc < 0) { + unsigned long evbit[NBITS(EV_MAX)] = { 0 }; + unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; + unsigned long absbit[NBITS(ABS_MAX)] = { 0 }; + + // add to attached devices so we don't try to open it again + attached_devices.push_back(String(p_path)); - fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc)); + if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) || + (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) || + (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) { + close(fd); return; } - libevdev *dev = joysticks[joy_num].dev; - //check if the device supports basic gamepad events, prevents certain keyboards from //being detected as joysticks - if (libevdev_has_event_type(dev, EV_ABS) && libevdev_has_event_type(dev, EV_KEY) && - (libevdev_has_event_code(dev, EV_KEY, BTN_A) || libevdev_has_event_code(dev, EV_KEY, BTN_THUMBL) || libevdev_has_event_code(dev, EV_KEY, BTN_TOP))) { - - char uid[128]; - String name = libevdev_get_name(dev); - uint16_t bus = __bswap_16(libevdev_get_id_bustype(dev)); - uint16_t vendor = __bswap_16(libevdev_get_id_vendor(dev)); - uint16_t product = __bswap_16(libevdev_get_id_product(dev)); - uint16_t version = __bswap_16(libevdev_get_id_version(dev)); - - joysticks[joy_num].reset(); - - Joystick &joy = joysticks[joy_num]; - joy.fd = fd; - joy.devpath = String(p_path); - setup_joystick_properties(joy_num); - sprintf(uid, "%04x%04x", bus, 0); - if (vendor && product && version) { - - sprintf(uid + String(uid).length(), "%04x%04x%04x%04x%04x%04x", vendor,0,product,0,version,0); - input->joy_connection_changed(joy_num, true, name, uid); - } - else { - String uidname = uid; - int uidlen = MIN(name.length(), 11); - for (int i=0; i<uidlen; i++) { + if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) && + (test_bit(ABS_X, absbit) || test_bit(ABS_Y, absbit) || test_bit(ABS_HAT0X, absbit) || + test_bit(ABS_GAS, absbit) || test_bit(ABS_RUDDER, absbit)) && + (test_bit(BTN_A, keybit) || test_bit(BTN_THUMBL, keybit) || + test_bit(BTN_TRIGGER, keybit) || test_bit(BTN_1, keybit)))) { + close(fd); + return; + } - uidname = uidname + _hex_str(name[i]); - } - uidname += "00"; - input->joy_connection_changed(joy_num, true, name, uidname); + char uid[128]; + char namebuf[128]; + String name = ""; + input_id inpid; + if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) >= 0) { + name = namebuf; + } - } + if (ioctl(fd, EVIOCGID, &inpid) < 0) { + close(fd); + return; + } + + joysticks[joy_num].reset(); + + Joystick &joy = joysticks[joy_num]; + joy.fd = fd; + joy.devpath = String(p_path); + setup_joystick_properties(joy_num); + sprintf(uid, "%04x%04x", __bswap_16(inpid.bustype), 0); + if (inpid.vendor && inpid.product && inpid.version) { + + uint16_t vendor = __bswap_16(inpid.vendor); + uint16_t product = __bswap_16(inpid.product); + uint16_t version = __bswap_16(inpid.version); + + sprintf(uid + String(uid).length(), "%04x%04x%04x%04x%04x%04x", vendor,0,product,0,version,0); + input->joy_connection_changed(joy_num, true, name, uid); } else { - //device is not a gamepad, clean up - libevdev_free(dev); - close(fd); + String uidname = uid; + int uidlen = MIN(name.length(), 11); + for (int i=0; i<uidlen; i++) { + + uidname = uidname + _hex_str(name[i]); + } + uidname += "00"; + input->joy_connection_changed(joy_num, true, name, uidname); } } } @@ -350,58 +419,54 @@ uint32_t joystick_linux::process_joysticks(uint32_t p_event_id) { if (joysticks[i].fd == -1) continue; - input_event ev; + input_event events[32]; Joystick* joy = &joysticks[i]; - libevdev* dev = joy->dev; - int rc = 1; - - rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev); - - if (rc < 0 && rc != -EAGAIN) { - continue; - } - - while (rc == LIBEVDEV_READ_STATUS_SYNC || rc == LIBEVDEV_READ_STATUS_SUCCESS) { - - switch (ev.type) { - case EV_KEY: - p_event_id = input->joy_button(p_event_id, i, joy->key_map[ev.code], ev.value); - break; - case EV_ABS: + int len; - switch (ev.code) { - case ABS_HAT0X: - if (ev.value != 0) { - if (ev.value < 0) joy->dpad |= InputDefault::HAT_MASK_LEFT; - else joy->dpad |= InputDefault::HAT_MASK_RIGHT; + while ((len = read(joy->fd, events, (sizeof events))) > 0) { + len /= sizeof(events[0]); + for (int j = 0; j < len; j++) { - } - else joy->dpad &= ~(InputDefault::HAT_MASK_LEFT | InputDefault::HAT_MASK_RIGHT); - - p_event_id = input->joy_hat(p_event_id, i, joy->dpad); - break; - - case ABS_HAT0Y: - if (ev.value != 0) { - if (ev.value < 0) joy->dpad |= InputDefault::HAT_MASK_UP; - else joy->dpad |= InputDefault::HAT_MASK_DOWN; - } - else joy->dpad &= ~(InputDefault::HAT_MASK_UP | InputDefault::HAT_MASK_DOWN); - - p_event_id = input->joy_hat(p_event_id, i, joy->dpad); + input_event &ev = events[j]; + switch (ev.type) { + case EV_KEY: + p_event_id = input->joy_button(p_event_id, i, joy->key_map[ev.code], ev.value); break; - default: - if (joy->abs_map[ev.code] != -1) { - InputDefault::JoyAxis value = axis_correct(libevdev_get_abs_info(dev, ev.code), ev.value); - joy->curr_axis[joy->abs_map[ev.code]] = value; + case EV_ABS: + + switch (ev.code) { + case ABS_HAT0X: + if (ev.value != 0) { + if (ev.value < 0) joy->dpad |= InputDefault::HAT_MASK_LEFT; + else joy->dpad |= InputDefault::HAT_MASK_RIGHT; + } + else joy->dpad &= ~(InputDefault::HAT_MASK_LEFT | InputDefault::HAT_MASK_RIGHT); + + p_event_id = input->joy_hat(p_event_id, i, joy->dpad); + break; + + case ABS_HAT0Y: + if (ev.value != 0) { + if (ev.value < 0) joy->dpad |= InputDefault::HAT_MASK_UP; + else joy->dpad |= InputDefault::HAT_MASK_DOWN; + } + else joy->dpad &= ~(InputDefault::HAT_MASK_UP | InputDefault::HAT_MASK_DOWN); + + p_event_id = input->joy_hat(p_event_id, i, joy->dpad); + break; + + default: + if (joy->abs_map[ev.code] != -1 && joy->abs_info[ev.code]) { + InputDefault::JoyAxis value = axis_correct(joy->abs_info[ev.code], ev.value); + joy->curr_axis[joy->abs_map[ev.code]] = value; + } + break; } break; } - break; } - rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev); } for (int j = 0; j < MAX_ABS; j++) { int index = joy->abs_map[j]; @@ -409,6 +474,9 @@ uint32_t joystick_linux::process_joysticks(uint32_t p_event_id) { p_event_id = input->joy_axis(p_event_id, i, index, joy->curr_axis[index]); } } + if (len == 0 || (len < 0 && errno != EAGAIN)) { + close_joystick(i); + }; } joy_mutex->unlock(); return p_event_id; diff --git a/platform/x11/joystick_linux.h b/platform/x11/joystick_linux.h index ee9bd0352a..e433f5e8e3 100644 --- a/platform/x11/joystick_linux.h +++ b/platform/x11/joystick_linux.h @@ -61,9 +61,10 @@ private: int fd; String devpath; - struct libevdev *dev; + input_absinfo *abs_info[MAX_ABS]; Joystick(); + ~Joystick(); void reset(); }; @@ -72,6 +73,7 @@ private: Thread *joy_thread; InputDefault *input; Joystick joysticks[JOYSTICKS_MAX]; + Vector<String> attached_devices; static void joy_thread_func(void *p_user); @@ -80,8 +82,11 @@ private: void setup_joystick_properties(int p_id); void close_joystick(int p_id = -1); +#ifdef UDEV_ENABLED void enumerate_joysticks(struct udev *_udev); void monitor_joysticks(struct udev *_udev); +#endif + void monitor_joysticks(); void run_joystick_thread(); void open_joystick(const char* path); diff --git a/platform/x11/key_mapping_x11.cpp b/platform/x11/key_mapping_x11.cpp index 48f415a730..46f1483767 100644 --- a/platform/x11/key_mapping_x11.cpp +++ b/platform/x11/key_mapping_x11.cpp @@ -97,7 +97,7 @@ static _XTranslatePair _xkeysym_to_keycode[]={ { XK_KP_Enter, KEY_KP_ENTER }, { XK_KP_Multiply, KEY_KP_MULTIPLY}, { XK_KP_Divide, KEY_KP_DIVIDE}, - { XK_KP_Subtract, KEY_KP_SUBSTRACT}, + { XK_KP_Subtract, KEY_KP_SUBTRACT}, { XK_KP_Add, KEY_KP_ADD}, { XK_KP_0, KEY_KP_0}, { XK_KP_1, KEY_KP_1}, diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index f42e93b93f..e5591810e7 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -65,7 +65,6 @@ #include <X11/Xatom.h> -//#include "os/pc_joystick_map.h" #undef CursorShape @@ -575,6 +574,10 @@ Point2 OS_X11::get_mouse_pos() const { void OS_X11::set_window_title(const String& p_title) { XStoreName(x11_display,x11_window,p_title.utf8().get_data()); + + Atom _net_wm_name = XInternAtom(x11_display, "_NET_WM_NAME", false); + Atom utf8_string = XInternAtom(x11_display, "UTF8_STRING", false); + XChangeProperty( x11_display, x11_window, _net_wm_name, utf8_string, 8, PropModeReplace, (unsigned char*) p_title.utf8().get_data(), p_title.utf8().length()); } void OS_X11::set_video_mode(const VideoMode& p_video_mode,int p_screen) { @@ -1782,6 +1785,22 @@ String OS_X11::get_joy_guid(int p_device) const { return input->get_joy_guid_remapped(p_device); } +void OS_X11::set_context(int p_context) { + + XClassHint* classHint = NULL; + classHint = XAllocClassHint(); + if (classHint) { + + if (p_context == CONTEXT_EDITOR) + classHint->res_name = (char *)"Godot_Editor"; + if (p_context == CONTEXT_PROJECTMAN) + classHint->res_name = (char *)"Godot_ProjectList"; + classHint->res_class = (char *)"Godot"; + XSetClassHint(x11_display, x11_window, classHint); + XFree(classHint); + } +} + OS_X11::OS_X11() { #ifdef RTAUDIO_ENABLED diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 91dbeac284..0891e4b8eb 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -226,6 +226,8 @@ public: virtual bool is_joy_known(int p_device); virtual String get_joy_guid(int p_device) const; + virtual void set_context(int p_context); + void run(); OS_X11(); |