Touch input on Android.
Run NinjaSnowWar by default on Android. Rudimentary touch controls (virtual on-screen joystick) in NinjaSnowWar. Improved OpenGL ES depth bias. Support GetUserDocumentsDir() on Android (return the getFilesDir() path.) Fixed OpenGL ES mode erroneously attempting to use shadowed point lights. Added .bat file to copy Data & CoreData directories as Android assets.
This commit is contained in:
Родитель
4d317ebdef
Коммит
0706ae397f
|
@ -3,7 +3,7 @@
|
|||
package="org.libsdl.app"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-feature android:glEsVersion="0x00020000" />
|
||||
<uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8" />
|
||||
<application android:label="@string/app_name" android:icon="@drawable/icon">
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
md assets\Data
|
||||
xcopy ..\Bin\Data\*.* assets\Data /S /E /C /Y
|
||||
md assets\CoreData
|
||||
xcopy ..\Bin\CoreData\*.* assets\CoreData /S /E /C /Y
|
|
@ -1,4 +1,4 @@
|
|||
// Modified by Lasse Öörni for Urho3D
|
||||
// Modified by Lasse Oorni for Urho3D
|
||||
|
||||
package org.libsdl.app;
|
||||
|
||||
|
@ -82,8 +82,8 @@ public class SDLActivity extends Activity {
|
|||
}
|
||||
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
Log.v("SDL", "onDestroy()");
|
||||
super.onDestroy();
|
||||
|
||||
mFinished = true;
|
||||
|
||||
|
@ -109,6 +109,10 @@ public class SDLActivity extends Activity {
|
|||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
public static SDLActivity getSingleton() {
|
||||
return mSingleton;
|
||||
}
|
||||
|
||||
// Messages from the SDLMain thread
|
||||
static int COMMAND_CHANGE_TITLE = 1;
|
||||
static int COMMAND_FINISH = 2;
|
||||
|
@ -137,7 +141,7 @@ public class SDLActivity extends Activity {
|
|||
}
|
||||
|
||||
// C functions we call
|
||||
public static native void nativeInit();
|
||||
public static native void nativeInit(String filesDir);
|
||||
public static native void nativeQuit();
|
||||
public static native void nativePause();
|
||||
public static native void nativeResume();
|
||||
|
@ -145,7 +149,7 @@ public class SDLActivity extends Activity {
|
|||
public static native void onNativeKeyDown(int keycode);
|
||||
public static native void onNativeKeyUp(int keycode);
|
||||
public static native void onNativeTouch(int touchDevId, int pointerFingerId,
|
||||
int action, float x,
|
||||
int action, float x,
|
||||
float y, float p);
|
||||
public static native void onNativeAccel(float x, float y, float z);
|
||||
public static native void nativeRunAudioThread();
|
||||
|
@ -165,7 +169,7 @@ public class SDLActivity extends Activity {
|
|||
// Called from SDLMain() thread and can't directly affect the view
|
||||
mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
|
||||
}
|
||||
|
||||
|
||||
public static void finishActivity() {
|
||||
mSingleton.sendCommand(COMMAND_FINISH, null);
|
||||
}
|
||||
|
@ -310,34 +314,34 @@ public class SDLActivity extends Activity {
|
|||
|
||||
// Audio
|
||||
private static Object buf;
|
||||
|
||||
|
||||
public static Object audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
|
||||
int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
|
||||
int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
|
||||
int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
|
||||
|
||||
|
||||
Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + ((float)sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
|
||||
|
||||
|
||||
// Let the user pick a larger buffer if they really want -- but ye
|
||||
// gods they probably shouldn't, the minimums are horrifyingly high
|
||||
// latency already
|
||||
desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
|
||||
|
||||
|
||||
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
|
||||
channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
|
||||
|
||||
|
||||
audioStartThread();
|
||||
|
||||
|
||||
Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
|
||||
|
||||
|
||||
if (is16Bit) {
|
||||
buf = new short[desiredFrames * (isStereo ? 2 : 1)];
|
||||
} else {
|
||||
buf = new byte[desiredFrames * (isStereo ? 2 : 1)];
|
||||
buf = new byte[desiredFrames * (isStereo ? 2 : 1)];
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
public static void audioStartThread() {
|
||||
mAudioThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
|
@ -345,12 +349,12 @@ public class SDLActivity extends Activity {
|
|||
nativeRunAudioThread();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// I'd take REALTIME if I could get it!
|
||||
mAudioThread.setPriority(Thread.MAX_PRIORITY);
|
||||
mAudioThread.start();
|
||||
}
|
||||
|
||||
|
||||
public static void audioWriteShortBuffer(short[] buffer) {
|
||||
for (int i = 0; i < buffer.length; ) {
|
||||
int result = mAudioTrack.write(buffer, i, buffer.length - i);
|
||||
|
@ -368,7 +372,7 @@ public class SDLActivity extends Activity {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void audioWriteByteBuffer(byte[] buffer) {
|
||||
for (int i = 0; i < buffer.length; ) {
|
||||
int result = mAudioTrack.write(buffer, i, buffer.length - i);
|
||||
|
@ -412,7 +416,7 @@ public class SDLActivity extends Activity {
|
|||
class SDLMain implements Runnable {
|
||||
public void run() {
|
||||
// Runs SDL_main()
|
||||
SDLActivity.nativeInit();
|
||||
SDLActivity.nativeInit(SDLActivity.getSingleton().getFilesDir().getAbsolutePath());
|
||||
|
||||
//Log.v("SDL", "SDL thread terminated");
|
||||
SDLActivity.finishActivity();
|
||||
|
@ -436,14 +440,14 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
public SDLSurface(Context context) {
|
||||
super(context);
|
||||
getHolder().addCallback(this);
|
||||
|
||||
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
requestFocus();
|
||||
setOnKeyListener(this);
|
||||
setOnTouchListener(this);
|
||||
setOnKeyListener(this);
|
||||
setOnTouchListener(this);
|
||||
|
||||
mSensorManager = (SensorManager)context.getSystemService("sensor");
|
||||
mSensorManager = (SensorManager)context.getSystemService("sensor");
|
||||
}
|
||||
|
||||
// Called when we have a valid drawing surface
|
||||
|
@ -525,6 +529,10 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
// Key events
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
|
||||
// Urho3D: let the home & volume keys be handled by the system
|
||||
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_HOME)
|
||||
return false;
|
||||
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
//Log.v("SDL", "key down: " + keyCode);
|
||||
SDLActivity.onNativeKeyDown(keyCode);
|
||||
|
@ -535,7 +543,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
SDLActivity.onNativeKeyUp(keyCode);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -568,21 +576,21 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Sensor events
|
||||
public void enableSensor(int sensortype, boolean enabled) {
|
||||
// TODO: This uses getDefaultSensor - what if we have >1 accels?
|
||||
if (enabled) {
|
||||
mSensorManager.registerListener(this,
|
||||
mSensorManager.getDefaultSensor(sensortype),
|
||||
mSensorManager.registerListener(this,
|
||||
mSensorManager.getDefaultSensor(sensortype),
|
||||
SensorManager.SENSOR_DELAY_GAME, null);
|
||||
} else {
|
||||
mSensorManager.unregisterListener(this,
|
||||
mSensorManager.unregisterListener(this,
|
||||
mSensorManager.getDefaultSensor(sensortype));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
// TODO
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ void CreateCursor()
|
|||
cursor.style = uiStyle;
|
||||
cursor.SetPosition(graphics.width / 2, graphics.height / 2);
|
||||
ui.cursor = cursor;
|
||||
if (GetPlatform() == "Android")
|
||||
ui.cursor.visible = false;
|
||||
}
|
||||
|
||||
void CreateMenuBar()
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "Scripts/Utilities/Network.as"
|
||||
|
||||
const float mouseSensitivity = 0.125;
|
||||
const float touchSensitivity = 2.0;
|
||||
const float cameraMinDist = 25;
|
||||
const float cameraMaxDist = 500;
|
||||
const float cameraSafetyDist = 30;
|
||||
|
@ -29,6 +30,8 @@ Text@ hiscoreText;
|
|||
Text@ messageText;
|
||||
BorderImage@ healthBar;
|
||||
BorderImage@ sight;
|
||||
BorderImage@ moveButton;
|
||||
BorderImage@ shootButton;
|
||||
SoundSource@ musicSource;
|
||||
|
||||
Controls playerControls;
|
||||
|
@ -44,6 +47,12 @@ float powerupSpawnTimer = 0;
|
|||
uint clientNodeID = 0;
|
||||
int clientScore = 0;
|
||||
|
||||
bool touchEnabled = false;
|
||||
int touchButtonSize = 96;
|
||||
int moveTouchID = -1;
|
||||
int rotateTouchID = -1;
|
||||
int fireTouchID = -1;
|
||||
|
||||
Array<Player> players;
|
||||
Array<HiscoreEntry> hiscores;
|
||||
|
||||
|
@ -73,6 +82,8 @@ void Start()
|
|||
SubscribeToEvent("Kill", "HandleKill");
|
||||
SubscribeToEvent("ScreenMode", "HandleScreenMode");
|
||||
|
||||
if (touchEnabled)
|
||||
SubscribeToEvent("TouchEnd", "HandleTouchEnd");
|
||||
if (singlePlayer)
|
||||
StartGame(null);
|
||||
}
|
||||
|
@ -225,6 +236,25 @@ void CreateOverlays()
|
|||
healthBar.SetPosition(2, 2);
|
||||
healthBar.SetSize(116, 16);
|
||||
healthBorder.AddChild(healthBar);
|
||||
|
||||
if (GetPlatform() == "Android")
|
||||
{
|
||||
touchEnabled = true;
|
||||
|
||||
moveButton = BorderImage();
|
||||
moveButton.texture = cache.GetResource("Texture2D", "Textures/TouchInput.png");
|
||||
moveButton.imageRect = IntRect(0, 0, 96, 96);
|
||||
moveButton.SetPosition(0, graphics.height - touchButtonSize);
|
||||
moveButton.SetSize(touchButtonSize, touchButtonSize);
|
||||
ui.root.AddChild(moveButton);
|
||||
|
||||
shootButton = BorderImage();
|
||||
shootButton.texture = cache.GetResource("Texture2D", "Textures/TouchInput.png");
|
||||
shootButton.imageRect = IntRect(96, 0, 192, 96);
|
||||
shootButton.SetPosition(graphics.width - touchButtonSize, graphics.height - touchButtonSize);
|
||||
shootButton.SetSize(touchButtonSize, touchButtonSize);
|
||||
ui.root.AddChild(shootButton);
|
||||
}
|
||||
}
|
||||
|
||||
void SetMessage(const String&in message)
|
||||
|
@ -374,6 +404,17 @@ void HandlePostRenderUpdate()
|
|||
gameScene.octree.DrawDebugGeometry(true);
|
||||
}
|
||||
|
||||
void HandleTouchEnd(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
int touchID = eventData["TouchID"].GetInt();
|
||||
if (touchID == moveTouchID)
|
||||
moveTouchID = -1;
|
||||
if (touchID == rotateTouchID)
|
||||
rotateTouchID = -1;
|
||||
if (touchID == fireTouchID)
|
||||
fireTouchID = -1;
|
||||
}
|
||||
|
||||
void HandleKeyDown(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
int key = eventData["Key"].GetInt();
|
||||
|
@ -724,6 +765,41 @@ void UpdateControls()
|
|||
prevPlayerControls = playerControls;
|
||||
playerControls.Set(CTRL_ALL, false);
|
||||
|
||||
if (touchEnabled)
|
||||
{
|
||||
for (int i = 0; i < input.numTouches; ++i)
|
||||
{
|
||||
TouchState touch = input.touches[i];
|
||||
if (touch.touchID == rotateTouchID || (touch.position.y < graphics.height - touchButtonSize ||
|
||||
(touch.position.x >= touchButtonSize && touch.position.x < graphics.width - touchButtonSize)))
|
||||
{
|
||||
rotateTouchID = touch.touchID;
|
||||
playerControls.yaw += touchSensitivity * gameCamera.fov / graphics.height * touch.delta.x;
|
||||
playerControls.pitch += touchSensitivity * gameCamera.fov / graphics.height * touch.delta.y;
|
||||
}
|
||||
else if (touch.position.y >= graphics.height - touchButtonSize && touch.position.x < touchButtonSize)
|
||||
{
|
||||
moveTouchID = touch.touchID;
|
||||
int relX = touch.position.x - touchButtonSize / 2;
|
||||
int relY = touch.position.y - (graphics.height - touchButtonSize / 2);
|
||||
if (relY < 0 && Abs(relX * 3 / 2) < Abs(relY))
|
||||
playerControls.Set(CTRL_UP, true);
|
||||
if (relY > 0 && Abs(relX * 3 / 2) < Abs(relY))
|
||||
playerControls.Set(CTRL_DOWN, true);
|
||||
if (relX < 0 && Abs(relY * 3 / 2) < Abs(relX))
|
||||
playerControls.Set(CTRL_LEFT, true);
|
||||
if (relX > 0 && Abs(relY * 3 / 2) < Abs(relX))
|
||||
playerControls.Set(CTRL_RIGHT, true);
|
||||
}
|
||||
else if (touch.position.y >= graphics.height - touchButtonSize && touch.position.x >= graphics.width -
|
||||
touchButtonSize)
|
||||
{
|
||||
fireTouchID = touch.touchID;
|
||||
playerControls.Set(CTRL_FIRE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For the triggered actions (fire & jump) check also for press, in case the FPS is low
|
||||
// and the key was already released
|
||||
if ((console is null) || (!console.visible))
|
||||
|
|
|
@ -83,7 +83,9 @@ void InitUI()
|
|||
newCursor.style = uiStyle;
|
||||
newCursor.position = IntVector2(graphics.width / 2, graphics.height / 2);
|
||||
ui.cursor = newCursor;
|
||||
|
||||
if (GetPlatform() == "Android")
|
||||
ui.cursor.visible = false;
|
||||
|
||||
downloadsText = Text();
|
||||
downloadsText.SetAlignment(HA_CENTER, VA_CENTER);
|
||||
downloadsText.SetFont(cache.GetResource("Font", "Fonts/Anonymous Pro.ttf"), 20);
|
||||
|
|
|
@ -289,6 +289,8 @@ void InitUI()
|
|||
cursor.style = uiStyle;
|
||||
cursor.position = IntVector2(graphics.width / 2, graphics.height / 2);
|
||||
ui.cursor = cursor;
|
||||
if (GetPlatform() == "Android")
|
||||
ui.cursor.visible = false;
|
||||
}
|
||||
|
||||
void CreateCamera()
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.9 KiB |
|
@ -54,7 +54,7 @@ Urho3D.exe <scriptfilename> [options]
|
|||
|
||||
The scripting language used is AngelScript (http://www.angelcode.com/angelscript); the script files have .as extension and need to be placed under either the Data or CoreData subdirectories so that Urho3D.exe can find them. An application script is required to have the function void Start(), which will be executed before starting the engine main loop. It is this function's responsibility to initialize the application and to hook up to any necessary \ref Events "events", such as the update that happens every frame.
|
||||
|
||||
On Android there are no command line options, so the Urho3D activity chooses to load the TestScene example. This can be changed from Urho3D.cpp.
|
||||
On Android there are no command line options, so running the NinjaSnowWar example is hardcoded. This can be changed from Urho3D.cpp.
|
||||
|
||||
Currently, five example application scripts exist:
|
||||
|
||||
|
|
|
@ -2368,6 +2368,15 @@ Properties:<br>
|
|||
- uint[] numOccluders (readonly)
|
||||
|
||||
|
||||
TouchState
|
||||
|
||||
Properties:<br>
|
||||
- int touchID
|
||||
- IntVector2 position
|
||||
- IntVector2 delta
|
||||
- int pressure
|
||||
|
||||
|
||||
Input
|
||||
|
||||
Properties:<br>
|
||||
|
@ -2385,6 +2394,8 @@ Properties:<br>
|
|||
- int mouseMoveX (readonly)
|
||||
- int mouseMoveY (readonly)
|
||||
- int mouseMoveWheel (readonly)
|
||||
- uint numTouches (readonly)
|
||||
- TouchState[] touches (readonly)
|
||||
- bool active (readonly)
|
||||
- bool minimized (readonly)
|
||||
|
||||
|
|
|
@ -108,8 +108,20 @@ static Input* GetInput()
|
|||
return GetScriptContext()->GetSubsystem<Input>();
|
||||
}
|
||||
|
||||
static void ConstructTouchState(TouchState* ptr)
|
||||
{
|
||||
new(ptr) TouchState();
|
||||
}
|
||||
|
||||
static void RegisterInput(asIScriptEngine* engine)
|
||||
{
|
||||
engine->RegisterObjectType("TouchState", sizeof(TouchState), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS);
|
||||
engine->RegisterObjectBehaviour("TouchState", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructTouchState), asCALL_CDECL_OBJLAST);
|
||||
engine->RegisterObjectProperty("TouchState", "int touchID", offsetof(TouchState, touchID_));
|
||||
engine->RegisterObjectProperty("TouchState", "IntVector2 position", offsetof(TouchState, position_));
|
||||
engine->RegisterObjectProperty("TouchState", "IntVector2 delta", offsetof(TouchState, delta_));
|
||||
engine->RegisterObjectProperty("TouchState", "int pressure", offsetof(TouchState, pressure_));
|
||||
|
||||
RegisterObject<Input>(engine, "Input");
|
||||
engine->RegisterObjectMethod("Input", "void set_toggleFullscreen(bool)", asMETHOD(Input, SetToggleFullscreen), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Input", "bool get_toggleFullscreen() const", asMETHOD(Input, GetToggleFullscreen), asCALL_THISCALL);
|
||||
|
@ -124,6 +136,8 @@ static void RegisterInput(asIScriptEngine* engine)
|
|||
engine->RegisterObjectMethod("Input", "int get_mouseMoveX() const", asMETHOD(Input, GetMouseMoveX), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Input", "int get_mouseMoveY() const", asMETHOD(Input, GetMouseMoveY), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Input", "int get_mouseMoveWheel() const", asMETHOD(Input, GetMouseMoveWheel), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Input", "uint get_numTouches() const", asMETHOD(Input, GetNumTouches), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Input", "TouchState get_touches(uint) const", asMETHOD(Input, GetTouch), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Input", "bool get_active() const", asMETHOD(Input, IsActive), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("Input", "bool get_minimized() const", asMETHOD(Input, IsMinimized), asCALL_THISCALL);
|
||||
engine->RegisterGlobalFunction("Input@+ get_input()", asFUNCTION(GetInput), asCALL_CDECL);
|
||||
|
|
|
@ -1414,9 +1414,14 @@ void Graphics::SetDepthBias(float constantBias, float slopeScaledBias)
|
|||
{
|
||||
// Bring the constant bias from Direct3D9 scale to OpenGL (depends on depth buffer bitdepth)
|
||||
// Zero depth bits may be returned if using the packed depth-stencil format. Assume 24bit in that case
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
int depthBits = Min(impl_->depthBits_, 23);
|
||||
if (!depthBits)
|
||||
depthBits = 23;
|
||||
#else
|
||||
int depthBits = 25;
|
||||
#endif
|
||||
|
||||
float adjustedConstantBias = constantBias * (float)(1 << (depthBits - 1));
|
||||
float adjustedSlopeScaledBias = slopeScaledBias + 1.0f;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "DebugRenderer.h"
|
||||
#include "Geometry.h"
|
||||
#include "Graphics.h"
|
||||
#include "GraphicsImpl.h"
|
||||
#include "Light.h"
|
||||
#include "Log.h"
|
||||
#include "OcclusionBuffer.h"
|
||||
|
|
|
@ -50,6 +50,10 @@
|
|||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
extern "C" const char* SDL_Android_GetFilesDir();
|
||||
#endif
|
||||
|
||||
#include "DebugNew.h"
|
||||
|
||||
OBJECTTYPESTATIC(FileSystem);
|
||||
|
@ -398,11 +402,13 @@ String FileSystem::GetProgramDir()
|
|||
|
||||
String FileSystem::GetUserDocumentsDir()
|
||||
{
|
||||
#ifdef WIN32
|
||||
#if defined(WIN32)
|
||||
wchar_t pathName[MAX_PATH];
|
||||
pathName[0] = 0;
|
||||
SHGetSpecialFolderPathW(0, pathName, CSIDL_PERSONAL, 0);
|
||||
return AddTrailingSlash(String(pathName));
|
||||
#elif defined(ANDROID)
|
||||
return AddTrailingSlash(String(SDL_Android_GetFilesDir()));
|
||||
#else
|
||||
char pathName[MAX_PATH];
|
||||
pathName[0] = 0;
|
||||
|
|
|
@ -169,6 +169,13 @@ void Input::Update()
|
|||
mouseMove_ = IntVector2::ZERO;
|
||||
mouseMoveWheel_ = 0;
|
||||
|
||||
// Reset touch delta movement. Note: last coordinates are stored internally, but the frame delta is returned to user
|
||||
for (Map<int, TouchState>::Iterator i = touches_.Begin(); i != touches_.End(); ++i)
|
||||
{
|
||||
TouchState& state = i->second_;
|
||||
state.delta_ = state.position_;
|
||||
}
|
||||
|
||||
#ifndef USE_OPENGL
|
||||
// Pump Win32 events
|
||||
MSG msg;
|
||||
|
@ -312,6 +319,25 @@ int Input::GetQualifiers() const
|
|||
return ret;
|
||||
}
|
||||
|
||||
TouchState Input::GetTouch(unsigned index) const
|
||||
{
|
||||
unsigned cmpIndex = 0;
|
||||
for (Map<int, TouchState>::ConstIterator i = touches_.Begin(); i != touches_.End(); ++i)
|
||||
{
|
||||
if (cmpIndex == index)
|
||||
{
|
||||
TouchState ret = i->second_;
|
||||
// Convert last position to delta
|
||||
ret.delta_ = ret.position_ - ret.delta_;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
++cmpIndex;
|
||||
}
|
||||
|
||||
return TouchState();
|
||||
}
|
||||
|
||||
void Input::Initialize()
|
||||
{
|
||||
Graphics* graphics = GetSubsystem<Graphics>();
|
||||
|
@ -397,6 +423,21 @@ void Input::ResetState()
|
|||
keyDown_.Clear();
|
||||
keyPress_.Clear();
|
||||
|
||||
// When clearing touch states, send the corresponding touch end events
|
||||
for (Map<int, TouchState>::Iterator i = touches_.Begin(); i != touches_.End(); ++i)
|
||||
{
|
||||
TouchState& state = i->second_;
|
||||
|
||||
using namespace TouchEnd;
|
||||
|
||||
VariantMap eventData;
|
||||
|
||||
eventData[P_TOUCHID] = state.touchID_;
|
||||
eventData[P_X] = state.position_.x_;
|
||||
eventData[P_Y] = state.position_.y_;
|
||||
SendEvent(E_TOUCHEND, eventData);
|
||||
}
|
||||
|
||||
// Use SetMouseButton() to reset the state so that mouse events will be sent properly
|
||||
SetMouseButton(MOUSEB_LEFT, false);
|
||||
SetMouseButton(MOUSEB_RIGHT, false);
|
||||
|
@ -733,6 +774,72 @@ void Input::HandleSDLEvent(void* sdlEvent)
|
|||
input->SetMouseWheel(evt.wheel.y);
|
||||
break;
|
||||
|
||||
case SDL_FINGERDOWN:
|
||||
input = GetInputInstance(evt.tfinger.windowID);
|
||||
if (input)
|
||||
{
|
||||
int touchID = (int)evt.tfinger.fingerId;
|
||||
TouchState& state = input->touches_[touchID];
|
||||
state.touchID_ = touchID;
|
||||
state.delta_ = state.position_ = IntVector2(evt.tfinger.x * input->graphics_->GetWidth() / 32768,
|
||||
evt.tfinger.y * input->graphics_->GetHeight() / 32768);
|
||||
state.pressure_ = evt.tfinger.pressure;
|
||||
|
||||
using namespace TouchBegin;
|
||||
|
||||
VariantMap eventData;
|
||||
|
||||
eventData[P_TOUCHID] = touchID;
|
||||
eventData[P_X] = state.position_.x_;
|
||||
eventData[P_Y] = state.position_.y_;
|
||||
eventData[P_PRESSURE] = state.pressure_;
|
||||
input->SendEvent(E_TOUCHBEGIN, eventData);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_FINGERUP:
|
||||
input = GetInputInstance(evt.tfinger.windowID);
|
||||
if (input)
|
||||
{
|
||||
int touchID = (int)evt.tfinger.fingerId;
|
||||
input->touches_.Erase(touchID);
|
||||
|
||||
using namespace TouchEnd;
|
||||
|
||||
VariantMap eventData;
|
||||
|
||||
eventData[P_TOUCHID] = touchID;
|
||||
eventData[P_X] = evt.tfinger.x * input->graphics_->GetWidth() / 32768;
|
||||
eventData[P_Y] = evt.tfinger.y * input->graphics_->GetHeight() / 32768;
|
||||
input->SendEvent(E_TOUCHEND, eventData);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_FINGERMOTION:
|
||||
input = GetInputInstance(evt.tfinger.windowID);
|
||||
if (input)
|
||||
{
|
||||
int touchID = (int)evt.tfinger.fingerId;
|
||||
TouchState& state = input->touches_[touchID];
|
||||
state.touchID_ = touchID;
|
||||
state.position_ = IntVector2(evt.tfinger.x * input->graphics_->GetWidth() / 32768,
|
||||
evt.tfinger.y * input->graphics_->GetHeight() / 32768);
|
||||
state.pressure_ = evt.tfinger.pressure;
|
||||
|
||||
using namespace TouchMove;
|
||||
|
||||
VariantMap eventData;
|
||||
|
||||
eventData[P_TOUCHID] = touchID;
|
||||
eventData[P_X] = state.position_.x_;
|
||||
eventData[P_Y] = state.position_.y_;
|
||||
eventData[P_DX] = evt.tfinger.dx * input->graphics_->GetWidth() / 32768;
|
||||
eventData[P_DY] = evt.tfinger.dy * input->graphics_->GetHeight() / 32768;
|
||||
eventData[P_PRESSURE] = state.pressure_;
|
||||
input->SendEvent(E_TOUCHMOVE, eventData);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
if (evt.window.event == SDL_WINDOWEVENT_CLOSE)
|
||||
{
|
||||
|
|
|
@ -23,12 +23,26 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Map.h"
|
||||
#include "HashSet.h"
|
||||
#include "InputEvents.h"
|
||||
#include "Object.h"
|
||||
|
||||
class Graphics;
|
||||
|
||||
/// Structure for an ongoing finger touch.
|
||||
struct TouchState
|
||||
{
|
||||
/// Touch (finger) ID.
|
||||
int touchID_;
|
||||
/// Position in screen coordinates.
|
||||
IntVector2 position_;
|
||||
/// Movement since last frame.
|
||||
IntVector2 delta_;
|
||||
/// Finger pressure.
|
||||
int pressure_;
|
||||
};
|
||||
|
||||
/// %Input subsystem. Converts operating system window messages to input state and events.
|
||||
class Input : public Object
|
||||
{
|
||||
|
@ -67,6 +81,10 @@ public:
|
|||
int GetMouseMoveY() const { return mouseMove_.y_; }
|
||||
/// Return mouse wheel movement since last frame.
|
||||
int GetMouseMoveWheel() const { return mouseMoveWheel_; }
|
||||
/// Return number of active finger touches.
|
||||
unsigned GetNumTouches() const { return touches_.Size(); }
|
||||
/// Return active finger touch by index.
|
||||
TouchState GetTouch(unsigned index) const;
|
||||
/// Return whether fullscreen toggle is enabled.
|
||||
bool GetToggleFullscreen() const { return toggleFullscreen_; }
|
||||
/// Return whether application window is active.
|
||||
|
@ -117,6 +135,8 @@ private:
|
|||
HashSet<int> keyDown_;
|
||||
/// Key pressed state.
|
||||
HashSet<int> keyPress_;
|
||||
/// Active finger touches.
|
||||
Map<int, TouchState> touches_;
|
||||
/// Mouse buttons' down state.
|
||||
unsigned mouseButtonDown_;
|
||||
/// Mouse buttons' pressed state.
|
||||
|
|
|
@ -87,6 +87,34 @@ EVENT(E_CHAR, Char)
|
|||
PARAM(P_QUALIFIERS, Qualifiers); // int
|
||||
}
|
||||
|
||||
/// Finger pressed on the screen.
|
||||
EVENT(E_TOUCHBEGIN, TouchBegin)
|
||||
{
|
||||
PARAM(P_TOUCHID, TouchID); // int
|
||||
PARAM(P_X, X); // int
|
||||
PARAM(P_Y, Y); // int
|
||||
PARAM(P_PRESSURE, Pressure); // int
|
||||
}
|
||||
|
||||
/// Finger released from the screen.
|
||||
EVENT(E_TOUCHEND, TouchEnd)
|
||||
{
|
||||
PARAM(P_TOUCHID, TouchID); // int
|
||||
PARAM(P_X, X); // int
|
||||
PARAM(P_Y, Y); // int
|
||||
}
|
||||
|
||||
/// Finger moved on the screen.
|
||||
EVENT(E_TOUCHMOVE, TouchMove)
|
||||
{
|
||||
PARAM(P_TOUCHID, TouchID); // int
|
||||
PARAM(P_X, X); // int
|
||||
PARAM(P_Y, Y); // int
|
||||
PARAM(P_DX, DX); // int
|
||||
PARAM(P_DY, DY); // int
|
||||
PARAM(P_PRESSURE, Pressure); // int
|
||||
}
|
||||
|
||||
/// Application activation state changed.
|
||||
EVENT(E_ACTIVATION, Activation)
|
||||
{
|
||||
|
|
|
@ -38,7 +38,7 @@ LineEdit::LineEdit(Context* context) :
|
|||
lastFont_(0),
|
||||
lastFontSize_(0),
|
||||
cursorPosition_(0),
|
||||
dragStartCursor_(M_MAX_UNSIGNED),
|
||||
dragBeginCursor_(M_MAX_UNSIGNED),
|
||||
cursorBlinkRate_(1.0f),
|
||||
cursorBlinkTimer_(0.0f),
|
||||
maxLength_(0),
|
||||
|
@ -144,16 +144,16 @@ void LineEdit::OnClick(const IntVector2& position, const IntVector2& screenPosit
|
|||
}
|
||||
}
|
||||
|
||||
void LineEdit::OnDragStart(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
|
||||
void LineEdit::OnDragBegin(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
|
||||
{
|
||||
dragStartCursor_ = GetCharIndex(position);
|
||||
dragBeginCursor_ = GetCharIndex(position);
|
||||
}
|
||||
|
||||
void LineEdit::OnDragMove(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
|
||||
{
|
||||
if (cursorMovable_ && textSelectable_)
|
||||
{
|
||||
unsigned start = dragStartCursor_;
|
||||
unsigned start = dragBeginCursor_;
|
||||
unsigned current = GetCharIndex(position);
|
||||
if (start != M_MAX_UNSIGNED && current != M_MAX_UNSIGNED)
|
||||
{
|
||||
|
@ -235,7 +235,7 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
|
|||
if (cursorMovable_ && cursorPosition_ > 0)
|
||||
{
|
||||
if (textSelectable_ && qualifiers & QUAL_SHIFT && !text_->GetSelectionLength())
|
||||
dragStartCursor_ = cursorPosition_;
|
||||
dragBeginCursor_ = cursorPosition_;
|
||||
|
||||
if (qualifiers & QUAL_CTRL)
|
||||
cursorPosition_ = 0;
|
||||
|
@ -245,7 +245,7 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
|
|||
|
||||
if (textSelectable_ && qualifiers & QUAL_SHIFT)
|
||||
{
|
||||
unsigned start = dragStartCursor_;
|
||||
unsigned start = dragBeginCursor_;
|
||||
unsigned current = cursorPosition_;
|
||||
if (start < current)
|
||||
text_->SetSelection(start, current - start);
|
||||
|
@ -261,7 +261,7 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
|
|||
if (cursorMovable_ && cursorPosition_ < line_.LengthUTF8())
|
||||
{
|
||||
if (textSelectable_ && qualifiers & QUAL_SHIFT && !text_->GetSelectionLength())
|
||||
dragStartCursor_ = cursorPosition_;
|
||||
dragBeginCursor_ = cursorPosition_;
|
||||
|
||||
if (qualifiers & QUAL_CTRL)
|
||||
cursorPosition_ = line_.LengthUTF8();
|
||||
|
@ -271,7 +271,7 @@ void LineEdit::OnKey(int key, int buttons, int qualifiers)
|
|||
|
||||
if (textSelectable_ && qualifiers & QUAL_SHIFT)
|
||||
{
|
||||
unsigned start = dragStartCursor_;
|
||||
unsigned start = dragBeginCursor_;
|
||||
unsigned current = cursorPosition_;
|
||||
if (start < current)
|
||||
text_->SetSelection(start, current - start);
|
||||
|
|
|
@ -50,8 +50,8 @@ public:
|
|||
|
||||
/// React to mouse click.
|
||||
virtual void OnClick(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag start.
|
||||
virtual void OnDragStart(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag begin.
|
||||
virtual void OnDragBegin(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag motion.
|
||||
virtual void OnDragMove(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to drag and drop test. Return true to signal that the drop is acceptable.
|
||||
|
@ -121,8 +121,8 @@ protected:
|
|||
int lastFontSize_;
|
||||
/// Text edit cursor position.
|
||||
unsigned cursorPosition_;
|
||||
/// Drag start edit cursor position.
|
||||
unsigned dragStartCursor_;
|
||||
/// Drag begin cursor position.
|
||||
unsigned dragBeginCursor_;
|
||||
/// Cursor blink rate.
|
||||
float cursorBlinkRate_;
|
||||
/// Cursor blink timer.
|
||||
|
|
|
@ -95,10 +95,10 @@ void Slider::OnHover(const IntVector2& position, const IntVector2& screenPositio
|
|||
hovering_ = knob_->IsInside(screenPosition, true);
|
||||
}
|
||||
|
||||
void Slider::OnDragStart(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
|
||||
void Slider::OnDragBegin(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
|
||||
{
|
||||
dragStartCursor_ = position;
|
||||
dragStartPosition_ = knob_->GetPosition();
|
||||
dragBeginCursor_ = position;
|
||||
dragBeginPosition_ = knob_->GetPosition();
|
||||
dragSlider_ = knob_->IsInside(screenPosition, true);
|
||||
}
|
||||
|
||||
|
@ -108,17 +108,17 @@ void Slider::OnDragMove(const IntVector2& position, const IntVector2& screenPosi
|
|||
return;
|
||||
|
||||
float newValue = value_;
|
||||
IntVector2 delta = position - dragStartCursor_;
|
||||
IntVector2 delta = position - dragBeginCursor_;
|
||||
|
||||
if (orientation_ == O_HORIZONTAL)
|
||||
{
|
||||
int newX = Clamp(dragStartPosition_.x_ + delta.x_, 0, GetWidth() - knob_->GetWidth());
|
||||
int newX = Clamp(dragBeginPosition_.x_ + delta.x_, 0, GetWidth() - knob_->GetWidth());
|
||||
knob_->SetPosition(newX, 0);
|
||||
newValue = (float)newX * range_ / (float)(GetWidth() - knob_->GetWidth());
|
||||
}
|
||||
else
|
||||
{
|
||||
int newY = Clamp(dragStartPosition_.y_ + delta.y_, 0, GetHeight() - knob_->GetHeight());
|
||||
int newY = Clamp(dragBeginPosition_.y_ + delta.y_, 0, GetHeight() - knob_->GetHeight());
|
||||
knob_->SetPosition(0, newY);
|
||||
newValue = (float)newY * range_ / (float)(GetHeight() - knob_->GetHeight());
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@ public:
|
|||
virtual void Update(float timeStep);
|
||||
/// React to mouse hover.
|
||||
virtual void OnHover(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag start.
|
||||
virtual void OnDragStart(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag begin.
|
||||
virtual void OnDragBegin(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag motion.
|
||||
virtual void OnDragMove(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag end.
|
||||
|
@ -87,8 +87,8 @@ protected:
|
|||
float value_;
|
||||
/// Internal flag of whether the slider is being dragged.
|
||||
bool dragSlider_;
|
||||
/// Original mouse cursor position at drag start.
|
||||
IntVector2 dragStartCursor_;
|
||||
/// Original slider position at drag start.
|
||||
IntVector2 dragStartPosition_;
|
||||
/// Original mouse cursor position at drag begin.
|
||||
IntVector2 dragBeginCursor_;
|
||||
/// Original slider position at drag begin.
|
||||
IntVector2 dragBeginPosition_;
|
||||
};
|
||||
|
|
204
Engine/UI/UI.cpp
204
Engine/UI/UI.cpp
|
@ -31,6 +31,7 @@
|
|||
#include "Font.h"
|
||||
#include "Graphics.h"
|
||||
#include "GraphicsEvents.h"
|
||||
#include "Input.h"
|
||||
#include "InputEvents.h"
|
||||
#include "LineEdit.h"
|
||||
#include "ListView.h"
|
||||
|
@ -62,10 +63,13 @@ UI::UI(Context* context) :
|
|||
initialized_(false)
|
||||
{
|
||||
SubscribeToEvent(E_SCREENMODE, HANDLER(UI, HandleScreenMode));
|
||||
SubscribeToEvent(E_MOUSEMOVE, HANDLER(UI, HandleMouseMove));
|
||||
SubscribeToEvent(E_MOUSEBUTTONDOWN, HANDLER(UI, HandleMouseButtonDown));
|
||||
SubscribeToEvent(E_MOUSEBUTTONUP, HANDLER(UI, HandleMouseButtonUp));
|
||||
SubscribeToEvent(E_MOUSEMOVE, HANDLER(UI, HandleMouseMove));
|
||||
SubscribeToEvent(E_MOUSEWHEEL, HANDLER(UI, HandleMouseWheel));
|
||||
SubscribeToEvent(E_TOUCHBEGIN, HANDLER(UI, HandleTouchBegin));
|
||||
SubscribeToEvent(E_TOUCHEND, HANDLER(UI, HandleTouchEnd));
|
||||
SubscribeToEvent(E_TOUCHMOVE, HANDLER(UI, HandleTouchMove));
|
||||
SubscribeToEvent(E_KEYDOWN, HANDLER(UI, HandleKeyDown));
|
||||
SubscribeToEvent(E_CHAR, HANDLER(UI, HandleChar));
|
||||
SubscribeToEvent(E_POSTUPDATE, HANDLER(UI, HandlePostUpdate));
|
||||
|
@ -206,6 +210,20 @@ void UI::Update(float timeStep)
|
|||
cursor_->SetShape(dragElement_ == element ? CS_ACCEPTDROP : CS_REJECTDROP);
|
||||
}
|
||||
|
||||
// Touch hover
|
||||
Input* input = GetSubsystem<Input>();
|
||||
if (input)
|
||||
{
|
||||
unsigned numTouches = input->GetNumTouches();
|
||||
for (unsigned i = 0; i < numTouches; ++i)
|
||||
{
|
||||
TouchState touch = input->GetTouch(i);
|
||||
WeakPtr<UIElement> element(GetElementAt(touch.position_));
|
||||
if (element)
|
||||
element->OnHover(element->ScreenToElement(touch.position_), touch.position_, MOUSEB_LEFT, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Update(timeStep, rootElement_);
|
||||
}
|
||||
|
||||
|
@ -665,42 +683,6 @@ void UI::HandleScreenMode(StringHash eventType, VariantMap& eventData)
|
|||
rootElement_->SetSize(eventData[P_WIDTH].GetInt(), eventData[P_HEIGHT].GetInt());
|
||||
}
|
||||
|
||||
void UI::HandleMouseMove(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
using namespace MouseMove;
|
||||
|
||||
mouseButtons_ = eventData[P_BUTTONS].GetInt();
|
||||
qualifiers_ = eventData[P_QUALIFIERS].GetInt();
|
||||
|
||||
if (cursor_)
|
||||
{
|
||||
const IntVector2& rootSize = rootElement_->GetSize();
|
||||
|
||||
// Move cursor only when visible
|
||||
if (cursor_->IsVisible())
|
||||
{
|
||||
IntVector2 pos = cursor_->GetPosition();
|
||||
pos.x_ += eventData[P_DX].GetInt();
|
||||
pos.y_ += eventData[P_DY].GetInt();
|
||||
pos.x_ = Clamp(pos.x_, 0, rootSize.x_ - 1);
|
||||
pos.y_ = Clamp(pos.y_, 0, rootSize.y_ - 1);
|
||||
cursor_->SetPosition(pos);
|
||||
}
|
||||
|
||||
if (dragElement_ && mouseButtons_)
|
||||
{
|
||||
IntVector2 pos = cursor_->GetPosition();
|
||||
if (dragElement_->IsActive() && dragElement_->IsVisible())
|
||||
dragElement_->OnDragMove(dragElement_->ScreenToElement(pos), pos, mouseButtons_, qualifiers_, cursor_);
|
||||
else
|
||||
{
|
||||
dragElement_->OnDragEnd(dragElement_->ScreenToElement(pos), pos, cursor_);
|
||||
dragElement_.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UI::HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
mouseButtons_ = eventData[MouseButtonDown::P_BUTTONS].GetInt();
|
||||
|
@ -728,7 +710,7 @@ void UI::HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
|
|||
if (element && !dragElement_ && mouseButtons_ == MOUSEB_LEFT)
|
||||
{
|
||||
dragElement_ = element;
|
||||
element->OnDragStart(element->ScreenToElement(pos), pos, mouseButtons_, qualifiers_, cursor_);
|
||||
element->OnDragBegin(element->ScreenToElement(pos), pos, mouseButtons_, qualifiers_, cursor_);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -757,7 +739,7 @@ void UI::HandleMouseButtonUp(StringHash eventType, VariantMap& eventData)
|
|||
mouseButtons_ = eventData[P_BUTTONS].GetInt();
|
||||
qualifiers_ = eventData[P_QUALIFIERS].GetInt();
|
||||
|
||||
if (cursor_ && (cursor_->IsVisible())|| (dragElement_))
|
||||
if (cursor_ && (cursor_->IsVisible()) || (dragElement_))
|
||||
{
|
||||
IntVector2 pos = cursor_->GetPosition();
|
||||
|
||||
|
@ -799,6 +781,42 @@ void UI::HandleMouseButtonUp(StringHash eventType, VariantMap& eventData)
|
|||
}
|
||||
}
|
||||
|
||||
void UI::HandleMouseMove(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
using namespace MouseMove;
|
||||
|
||||
mouseButtons_ = eventData[P_BUTTONS].GetInt();
|
||||
qualifiers_ = eventData[P_QUALIFIERS].GetInt();
|
||||
|
||||
if (cursor_)
|
||||
{
|
||||
const IntVector2& rootSize = rootElement_->GetSize();
|
||||
|
||||
// Move cursor only when visible
|
||||
if (cursor_->IsVisible())
|
||||
{
|
||||
IntVector2 pos = cursor_->GetPosition();
|
||||
pos.x_ += eventData[P_DX].GetInt();
|
||||
pos.y_ += eventData[P_DY].GetInt();
|
||||
pos.x_ = Clamp(pos.x_, 0, rootSize.x_ - 1);
|
||||
pos.y_ = Clamp(pos.y_, 0, rootSize.y_ - 1);
|
||||
cursor_->SetPosition(pos);
|
||||
}
|
||||
|
||||
if (dragElement_ && mouseButtons_)
|
||||
{
|
||||
IntVector2 pos = cursor_->GetPosition();
|
||||
if (dragElement_->IsActive() && dragElement_->IsVisible())
|
||||
dragElement_->OnDragMove(dragElement_->ScreenToElement(pos), pos, mouseButtons_, qualifiers_, cursor_);
|
||||
else
|
||||
{
|
||||
dragElement_->OnDragEnd(dragElement_->ScreenToElement(pos), pos, cursor_);
|
||||
dragElement_.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UI::HandleMouseWheel(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
using namespace MouseWheel;
|
||||
|
@ -825,6 +843,114 @@ void UI::HandleMouseWheel(StringHash eventType, VariantMap& eventData)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void UI::HandleTouchBegin(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
using namespace TouchBegin;
|
||||
|
||||
IntVector2 pos(eventData[P_X].GetInt(), eventData[P_Y].GetInt());
|
||||
WeakPtr<UIElement> element(GetElementAt(pos));
|
||||
|
||||
if (element)
|
||||
{
|
||||
// Handle focusing & bringing to front
|
||||
SetFocusElement(element);
|
||||
element->BringToFront();
|
||||
|
||||
// Handle click
|
||||
element->OnClick(element->ScreenToElement(pos), pos, MOUSEB_LEFT, 0, 0);
|
||||
|
||||
// Handle start of drag. OnClick() may have caused destruction of the element, so check the pointer again
|
||||
if (element && !dragElement_ )
|
||||
{
|
||||
dragElement_ = element;
|
||||
element->OnDragBegin(element->ScreenToElement(pos), pos, MOUSEB_LEFT, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If clicked over no element, or a disabled element, lose focus
|
||||
SetFocusElement(0);
|
||||
}
|
||||
|
||||
using namespace UIMouseClick;
|
||||
|
||||
VariantMap clickEventData;
|
||||
clickEventData[UIMouseClick::P_ELEMENT] = (void*)element.Get();
|
||||
clickEventData[UIMouseClick::P_X] = pos.x_;
|
||||
clickEventData[UIMouseClick::P_Y] = pos.y_;
|
||||
clickEventData[UIMouseClick::P_BUTTON] = MOUSEB_LEFT;
|
||||
clickEventData[UIMouseClick::P_BUTTONS] = MOUSEB_LEFT;
|
||||
clickEventData[UIMouseClick::P_QUALIFIERS] = 0;
|
||||
SendEvent(E_UIMOUSECLICK, clickEventData);
|
||||
}
|
||||
|
||||
void UI::HandleTouchEnd(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
using namespace TouchEnd;
|
||||
|
||||
IntVector2 pos(eventData[P_X].GetInt(), eventData[P_Y].GetInt());
|
||||
|
||||
// Transmit hover end to the position where the finger was lifted
|
||||
WeakPtr<UIElement> element(GetElementAt(pos));
|
||||
if (element)
|
||||
element->OnHover(element->ScreenToElement(pos), pos, 0, 0, 0);
|
||||
|
||||
if (dragElement_)
|
||||
{
|
||||
if (dragElement_->IsActive() && dragElement_->IsVisible())
|
||||
{
|
||||
dragElement_->OnDragEnd(dragElement_->ScreenToElement(pos), pos, cursor_);
|
||||
|
||||
// Drag and drop finish
|
||||
bool dragSource = dragElement_ && (dragElement_->GetDragDropMode() & DD_SOURCE) != 0;
|
||||
if (dragSource)
|
||||
{
|
||||
WeakPtr<UIElement> target(GetElementAt(pos));
|
||||
bool dragTarget = target && (target->GetDragDropMode() & DD_TARGET) != 0;
|
||||
bool dragDropFinish = dragSource && dragTarget && target != dragElement_;
|
||||
|
||||
if (dragDropFinish)
|
||||
{
|
||||
bool accept = target->OnDragDropFinish(dragElement_);
|
||||
|
||||
// OnDragDropFinish() may have caused destruction of the elements, so check the pointers again
|
||||
if (accept && dragElement_ && target)
|
||||
{
|
||||
using namespace DragDropFinish;
|
||||
|
||||
VariantMap eventData;
|
||||
eventData[P_SOURCE] = (void*)dragElement_.Get();
|
||||
eventData[P_TARGET] = (void*)target.Get();
|
||||
eventData[P_ACCEPT] = accept;
|
||||
SendEvent(E_DRAGDROPFINISH, eventData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dragElement_.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void UI::HandleTouchMove(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
using namespace TouchMove;
|
||||
|
||||
IntVector2 pos(eventData[P_X].GetInt(), eventData[P_Y].GetInt());
|
||||
|
||||
if (dragElement_)
|
||||
{
|
||||
if (dragElement_->IsActive() && dragElement_->IsVisible())
|
||||
dragElement_->OnDragMove(dragElement_->ScreenToElement(pos), pos, MOUSEB_LEFT, 0, 0);
|
||||
else
|
||||
{
|
||||
dragElement_->OnDragEnd(dragElement_->ScreenToElement(pos), pos, 0);
|
||||
dragElement_.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UI::HandleKeyDown(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
using namespace KeyDown;
|
||||
|
|
|
@ -97,14 +97,20 @@ private:
|
|||
void LoadLayout(UIElement* current, const XMLElement& elem, XMLFile* styleFile);
|
||||
/// Handle screen mode event.
|
||||
void HandleScreenMode(StringHash eventType, VariantMap& eventData);
|
||||
/// Handle mouse move event.
|
||||
void HandleMouseMove(StringHash eventType, VariantMap& eventData);
|
||||
/// Handle mouse button down event.
|
||||
void HandleMouseButtonDown(StringHash eventType, VariantMap& eventData);
|
||||
/// Handle mouse button up event.
|
||||
void HandleMouseButtonUp(StringHash eventType, VariantMap& eventData);
|
||||
/// Handle mouse move event.
|
||||
void HandleMouseMove(StringHash eventType, VariantMap& eventData);
|
||||
/// Handle mouse wheel event.
|
||||
void HandleMouseWheel(StringHash eventType, VariantMap& eventData);
|
||||
/// Handle touch begin event.
|
||||
void HandleTouchBegin(StringHash eventType, VariantMap& eventData);
|
||||
/// Handle touch end event.
|
||||
void HandleTouchEnd(StringHash eventType, VariantMap& eventData);
|
||||
/// Handle touch move event.
|
||||
void HandleTouchMove(StringHash eventType, VariantMap& eventData);
|
||||
/// Handle keypress event.
|
||||
void HandleKeyDown(StringHash eventType, VariantMap& eventData);
|
||||
/// Handle character event.
|
||||
|
|
|
@ -264,7 +264,7 @@ void UIElement::OnClick(const IntVector2& position, const IntVector2& screenPosi
|
|||
{
|
||||
}
|
||||
|
||||
void UIElement::OnDragStart(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
|
||||
void UIElement::OnDragBegin(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -122,8 +122,8 @@ public:
|
|||
virtual void OnHover(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse click.
|
||||
virtual void OnClick(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag start.
|
||||
virtual void OnDragStart(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag begin.
|
||||
virtual void OnDragBegin(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag motion.
|
||||
virtual void OnDragMove(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag end.
|
||||
|
|
|
@ -77,7 +77,7 @@ void Window::OnHover(const IntVector2& position, const IntVector2& screenPositio
|
|||
SetCursorShape(dragMode_, cursor);
|
||||
}
|
||||
|
||||
void Window::OnDragStart(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
|
||||
void Window::OnDragBegin(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor)
|
||||
{
|
||||
if (buttons != MOUSEB_LEFT || !CheckAlignment())
|
||||
{
|
||||
|
@ -85,9 +85,9 @@ void Window::OnDragStart(const IntVector2& position, const IntVector2& screenPos
|
|||
return;
|
||||
}
|
||||
|
||||
dragStartCursor_ = screenPosition;
|
||||
dragStartPosition_ = GetPosition();
|
||||
dragStartSize_ = GetSize();
|
||||
dragBeginCursor_ = screenPosition;
|
||||
dragBeginPosition_ = GetPosition();
|
||||
dragBeginSize_ = GetSize();
|
||||
dragMode_ = GetDragMode(position);
|
||||
SetCursorShape(dragMode_, cursor);
|
||||
}
|
||||
|
@ -97,49 +97,49 @@ void Window::OnDragMove(const IntVector2& position, const IntVector2& screenPosi
|
|||
if (dragMode_ == DRAG_NONE)
|
||||
return;
|
||||
|
||||
IntVector2 delta = screenPosition - dragStartCursor_;
|
||||
IntVector2 delta = screenPosition - dragBeginCursor_;
|
||||
|
||||
switch (dragMode_)
|
||||
{
|
||||
case DRAG_MOVE:
|
||||
SetPosition(dragStartPosition_ + delta);
|
||||
SetPosition(dragBeginPosition_ + delta);
|
||||
break;
|
||||
|
||||
case DRAG_RESIZE_TOPLEFT:
|
||||
SetPosition(dragStartPosition_ + delta);
|
||||
SetSize(dragStartSize_ - delta);
|
||||
SetPosition(dragBeginPosition_ + delta);
|
||||
SetSize(dragBeginSize_ - delta);
|
||||
break;
|
||||
|
||||
case DRAG_RESIZE_TOP:
|
||||
SetPosition(dragStartPosition_.x_, dragStartPosition_.y_ + delta.y_);
|
||||
SetSize(dragStartSize_.x_, dragStartSize_.y_ - delta.y_);
|
||||
SetPosition(dragBeginPosition_.x_, dragBeginPosition_.y_ + delta.y_);
|
||||
SetSize(dragBeginSize_.x_, dragBeginSize_.y_ - delta.y_);
|
||||
break;
|
||||
|
||||
case DRAG_RESIZE_TOPRIGHT:
|
||||
SetPosition(dragStartPosition_.x_, dragStartPosition_.y_ + delta.y_);
|
||||
SetSize(dragStartSize_.x_ + delta.x_, dragStartSize_.y_ - delta.y_);
|
||||
SetPosition(dragBeginPosition_.x_, dragBeginPosition_.y_ + delta.y_);
|
||||
SetSize(dragBeginSize_.x_ + delta.x_, dragBeginSize_.y_ - delta.y_);
|
||||
break;
|
||||
|
||||
case DRAG_RESIZE_RIGHT:
|
||||
SetSize(dragStartSize_.x_ + delta.x_, dragStartSize_.y_);
|
||||
SetSize(dragBeginSize_.x_ + delta.x_, dragBeginSize_.y_);
|
||||
break;
|
||||
|
||||
case DRAG_RESIZE_BOTTOMRIGHT:
|
||||
SetSize(dragStartSize_ + delta);
|
||||
SetSize(dragBeginSize_ + delta);
|
||||
break;
|
||||
|
||||
case DRAG_RESIZE_BOTTOM:
|
||||
SetSize(dragStartSize_.x_, dragStartSize_.y_ + delta.y_);
|
||||
SetSize(dragBeginSize_.x_, dragBeginSize_.y_ + delta.y_);
|
||||
break;
|
||||
|
||||
case DRAG_RESIZE_BOTTOMLEFT:
|
||||
SetPosition(dragStartPosition_.x_ + delta.x_, dragStartPosition_.y_);
|
||||
SetSize(dragStartSize_.x_ - delta.x_, dragStartSize_.y_ + delta.y_);
|
||||
SetPosition(dragBeginPosition_.x_ + delta.x_, dragBeginPosition_.y_);
|
||||
SetSize(dragBeginSize_.x_ - delta.x_, dragBeginSize_.y_ + delta.y_);
|
||||
break;
|
||||
|
||||
case DRAG_RESIZE_LEFT:
|
||||
SetPosition(dragStartPosition_.x_ + delta.x_, dragStartPosition_.y_);
|
||||
SetSize(dragStartSize_.x_ - delta.x_, dragStartSize_.y_);
|
||||
SetPosition(dragBeginPosition_.x_ + delta.x_, dragBeginPosition_.y_);
|
||||
SetSize(dragBeginSize_.x_ - delta.x_, dragBeginSize_.y_);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -224,6 +224,9 @@ WindowDragMode Window::GetDragMode(const IntVector2& position) const
|
|||
|
||||
void Window::SetCursorShape(WindowDragMode mode, Cursor* cursor) const
|
||||
{
|
||||
if (!cursor)
|
||||
return;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case DRAG_RESIZE_TOP:
|
||||
|
|
|
@ -59,8 +59,8 @@ public:
|
|||
virtual void SetStyle(const XMLElement& element);
|
||||
/// React to mouse hover.
|
||||
virtual void OnHover(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag start.
|
||||
virtual void OnDragStart(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag begin.
|
||||
virtual void OnDragBegin(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag motion.
|
||||
virtual void OnDragMove(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers, Cursor* cursor);
|
||||
/// React to mouse drag end.
|
||||
|
@ -98,10 +98,10 @@ protected:
|
|||
IntRect resizeBorder_;
|
||||
/// Current drag mode.
|
||||
WindowDragMode dragMode_;
|
||||
/// Mouse position at drag start.
|
||||
IntVector2 dragStartCursor_;
|
||||
/// Original position at drag start.
|
||||
IntVector2 dragStartPosition_;
|
||||
/// Original size at drag start.
|
||||
IntVector2 dragStartSize_;
|
||||
/// Mouse position at drag begin.
|
||||
IntVector2 dragBeginCursor_;
|
||||
/// Original position at drag begin.
|
||||
IntVector2 dragBeginPosition_;
|
||||
/// Original size at drag begin.
|
||||
IntVector2 dragBeginSize_;
|
||||
};
|
||||
|
|
|
@ -17,7 +17,7 @@ uniform sampler2DShadow sShadowMap;
|
|||
uniform samplerCube sFaceSelectCubeMap;
|
||||
uniform samplerCube sIndirectionCubeMap;
|
||||
#else
|
||||
uniform sampler2D sShadowMap;
|
||||
uniform mediump sampler2D sShadowMap;
|
||||
#endif
|
||||
|
||||
vec3 DecodeNormal(vec4 normalInput)
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
// Modified by Lasse Öörni for Urho3D
|
||||
|
||||
#include "SDL_config.h"
|
||||
#include "SDL_stdinc.h"
|
||||
#include "SDL_assert.h"
|
||||
|
@ -73,6 +76,9 @@ static jmethodID midAudioQuit;
|
|||
static float fLastAccelerometer[3];
|
||||
static bool bHasNewData;
|
||||
|
||||
// Application files dir
|
||||
static char* mFilesDir = 0;
|
||||
|
||||
/*******************************************************************************
|
||||
Functions called by JNI
|
||||
*******************************************************************************/
|
||||
|
@ -91,11 +97,30 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
extern "C" const char* SDL_Android_GetFilesDir()
|
||||
{
|
||||
return mFilesDir;
|
||||
}
|
||||
|
||||
// Called before SDL_main() to initialize JNI bindings
|
||||
extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls)
|
||||
extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls, jstring filesDir)
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()");
|
||||
|
||||
// Copy the files dir
|
||||
const char *str;
|
||||
str = env->GetStringUTFChars(filesDir, 0);
|
||||
if (str)
|
||||
{
|
||||
if (mFilesDir)
|
||||
free(mFilesDir);
|
||||
|
||||
size_t length = strlen(str) + 1;
|
||||
mFilesDir = (char*)malloc(length);
|
||||
memcpy(mFilesDir, str, length);
|
||||
env->ReleaseStringUTFChars(filesDir, str);
|
||||
}
|
||||
|
||||
mEnv = env;
|
||||
mActivityClass = (jclass)env->NewGlobalRef(cls);
|
||||
|
||||
|
@ -103,7 +128,7 @@ extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls)
|
|||
"createGLContext","(II)Z");
|
||||
midFlipBuffers = mEnv->GetStaticMethodID(mActivityClass,
|
||||
"flipBuffers","()V");
|
||||
midAudioInit = mEnv->GetStaticMethodID(mActivityClass,
|
||||
midAudioInit = mEnv->GetStaticMethodID(mActivityClass,
|
||||
"audioInit", "(IZZI)Ljava/lang/Object;");
|
||||
midAudioWriteShortBuffer = mEnv->GetStaticMethodID(mActivityClass,
|
||||
"audioWriteShortBuffer", "([S)V");
|
||||
|
@ -165,53 +190,53 @@ extern "C" void Java_org_libsdl_app_SDLActivity_onNativeAccel(
|
|||
|
||||
// Quit
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_nativeQuit(
|
||||
JNIEnv* env, jclass cls)
|
||||
{
|
||||
// Inject a SDL_QUIT event
|
||||
SDL_Event event;
|
||||
event.type=SDL_SYSEVENT_TERMINATE;
|
||||
event.sysevent.data=NULL;
|
||||
if (SDL_SysEventHandler)
|
||||
SDL_SysEventHandler(&event);
|
||||
else SDL_SendQuit();
|
||||
}
|
||||
|
||||
// Pause
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_nativePause(
|
||||
JNIEnv* env, jclass cls)
|
||||
{
|
||||
SDL_Event event;
|
||||
event.type=SDL_SYSEVENT_WILL_SUSPEND;
|
||||
event.sysevent.data=NULL;
|
||||
if (SDL_SysEventHandler)
|
||||
SDL_SysEventHandler(&event);
|
||||
event.type=SDL_SYSEVENT_SUSPEND;
|
||||
event.sysevent.data=NULL;
|
||||
if (SDL_SysEventHandler)
|
||||
SDL_SysEventHandler(&event);
|
||||
else if (Android_Window) {
|
||||
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
|
||||
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
|
||||
}
|
||||
JNIEnv* env, jclass cls)
|
||||
{
|
||||
// Inject a SDL_QUIT event
|
||||
SDL_Event event;
|
||||
event.type=SDL_SYSEVENT_TERMINATE;
|
||||
event.sysevent.data=NULL;
|
||||
if (SDL_SysEventHandler)
|
||||
SDL_SysEventHandler(&event);
|
||||
else SDL_SendQuit();
|
||||
}
|
||||
|
||||
// Pause
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_nativePause(
|
||||
JNIEnv* env, jclass cls)
|
||||
{
|
||||
SDL_Event event;
|
||||
event.type=SDL_SYSEVENT_WILL_SUSPEND;
|
||||
event.sysevent.data=NULL;
|
||||
if (SDL_SysEventHandler)
|
||||
SDL_SysEventHandler(&event);
|
||||
event.type=SDL_SYSEVENT_SUSPEND;
|
||||
event.sysevent.data=NULL;
|
||||
if (SDL_SysEventHandler)
|
||||
SDL_SysEventHandler(&event);
|
||||
else if (Android_Window) {
|
||||
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
|
||||
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Resume
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_nativeResume(
|
||||
JNIEnv* env, jclass cls)
|
||||
{
|
||||
SDL_Event event;
|
||||
event.type=SDL_SYSEVENT_WILL_RESUME;
|
||||
event.sysevent.data=NULL;
|
||||
if (SDL_SysEventHandler)
|
||||
SDL_SysEventHandler(&event);
|
||||
event.type=SDL_SYSEVENT_RESUME;
|
||||
event.sysevent.data=NULL;
|
||||
if (SDL_SysEventHandler)
|
||||
SDL_SysEventHandler(&event);
|
||||
else if (Android_Window) {
|
||||
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
|
||||
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESTORED, 0, 0);
|
||||
}
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_nativeResume(
|
||||
JNIEnv* env, jclass cls)
|
||||
{
|
||||
SDL_Event event;
|
||||
event.type=SDL_SYSEVENT_WILL_RESUME;
|
||||
event.sysevent.data=NULL;
|
||||
if (SDL_SysEventHandler)
|
||||
SDL_SysEventHandler(&event);
|
||||
event.type=SDL_SYSEVENT_RESUME;
|
||||
event.sysevent.data=NULL;
|
||||
if (SDL_SysEventHandler)
|
||||
SDL_SysEventHandler(&event);
|
||||
else if (Android_Window) {
|
||||
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
|
||||
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESTORED, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_nativeRunAudioThread(
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -13,13 +13,13 @@
|
|||
#include <jni.h>
|
||||
|
||||
// Called before SDL_main() to initialize JNI bindings in SDL library
|
||||
extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls);
|
||||
|
||||
extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls, jstring filesDir);
|
||||
|
||||
// Start up the SDL app
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj)
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jstring filesDir)
|
||||
{
|
||||
/* This interface could expand with ABI negotiation, calbacks, etc. */
|
||||
SDL_Android_Init(env, cls);
|
||||
SDL_Android_Init(env, cls, filesDir);
|
||||
|
||||
/* Run the application code! */
|
||||
int status;
|
||||
|
|
|
@ -96,7 +96,7 @@ void Run()
|
|||
|
||||
#ifdef ANDROID
|
||||
// Can not pass script name on Android, so choose a hardcoded default
|
||||
scriptFileName = "Scripts/TestScene.as";
|
||||
scriptFileName = "Scripts/NinjaSnowWar.as";
|
||||
#endif
|
||||
|
||||
// Show usage if not found
|
||||
|
|
Загрузка…
Ссылка в новой задаче