Merge pull request #5896 from splhack/remove_nativeactivity

Remove NativeActivity
This commit is contained in:
minggo 2014-03-25 15:37:12 +08:00
commit 3fc15e5e7d
30 changed files with 1739 additions and 1182 deletions

View File

@ -12,12 +12,15 @@ CCCommon.cpp \
CCDevice.cpp \
CCGLView.cpp \
CCFileUtilsAndroid.cpp \
nativeactivity.cpp \
javaactivity.cpp \
jni/DPIJni.cpp \
jni/IMEJni.cpp \
jni/Java_org_cocos2dx_lib_Cocos2dxAccelerometer.cpp \
jni/Java_org_cocos2dx_lib_Cocos2dxBitmap.cpp \
jni/Java_org_cocos2dx_lib_Cocos2dxHelper.cpp \
jni/JniHelper.cpp
jni/Java_org_cocos2dx_lib_Cocos2dxRenderer.cpp \
jni/JniHelper.cpp \
jni/TouchesJni.cpp
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
@ -41,7 +44,7 @@ LOCAL_EXPORT_LDLIBS := -lGLESv1_CM \
-lz \
-landroid
LOCAL_WHOLE_STATIC_LIBRARIES := android_native_app_glue cocos_png_static cocos_jpeg_static cocos_tiff_static cocos_webp_static
LOCAL_WHOLE_STATIC_LIBRARIES := cocos_png_static cocos_jpeg_static cocos_tiff_static cocos_webp_static
include $(BUILD_STATIC_LIBRARY)
@ -50,4 +53,3 @@ $(call import-module,jpeg/prebuilt/android)
$(call import-module,png/prebuilt/android)
$(call import-module,tiff/prebuilt/android)
$(call import-module,webp/prebuilt/android)
$(call import-module,android/native_app_glue)

View File

@ -32,8 +32,8 @@ THE SOFTWARE.
#include <jni.h>
#include "ccTypes.h"
#include "jni/DPIJni.h"
#include "jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h"
#include "jni/JniHelper.h"
#include "nativeactivity.h"
#include "platform/CCFileUtils.h"
NS_CC_BEGIN

View File

@ -0,0 +1,144 @@
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
http://www.cocos2d-x.org
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.
****************************************************************************/
package org.cocos2dx.lib;
import android.content.Context;
import android.content.res.Configuration;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;
import android.os.Build.*;
public class Cocos2dxAccelerometer implements SensorEventListener {
// ===========================================================
// Constants
// ===========================================================
private static final String TAG = Cocos2dxAccelerometer.class.getSimpleName();
// ===========================================================
// Fields
// ===========================================================
private final Context mContext;
private final SensorManager mSensorManager;
private final Sensor mAccelerometer;
private final int mNaturalOrientation;
// ===========================================================
// Constructors
// ===========================================================
public Cocos2dxAccelerometer(final Context pContext) {
this.mContext = pContext;
this.mSensorManager = (SensorManager) this.mContext.getSystemService(Context.SENSOR_SERVICE);
this.mAccelerometer = this.mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
final Display display = ((WindowManager) this.mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
this.mNaturalOrientation = display.getOrientation();
}
// ===========================================================
// Getter & Setter
// ===========================================================
public void enable() {
this.mSensorManager.registerListener(this, this.mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
}
public void setInterval(float interval) {
// Honeycomb version is 11
if(android.os.Build.VERSION.SDK_INT < 11) {
this.mSensorManager.registerListener(this, this.mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
} else {
//convert seconds to microseconds
this.mSensorManager.registerListener(this, this.mAccelerometer, (int)(interval*100000));
}
}
public void disable() {
this.mSensorManager.unregisterListener(this);
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public void onSensorChanged(final SensorEvent pSensorEvent) {
if (pSensorEvent.sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
return;
}
float x = pSensorEvent.values[0];
float y = pSensorEvent.values[1];
final float z = pSensorEvent.values[2];
/*
* Because the axes are not swapped when the device's screen orientation
* changes. So we should swap it here. In tablets such as Motorola Xoom,
* the default orientation is landscape, so should consider this.
*/
final int orientation = this.mContext.getResources().getConfiguration().orientation;
if ((orientation == Configuration.ORIENTATION_LANDSCAPE) && (this.mNaturalOrientation != Surface.ROTATION_0)) {
final float tmp = x;
x = -y;
y = tmp;
} else if ((orientation == Configuration.ORIENTATION_PORTRAIT) && (this.mNaturalOrientation != Surface.ROTATION_0)) {
final float tmp = x;
x = y;
y = -tmp;
}
Cocos2dxGLSurfaceView.queueAccelerometer(x,y,z,pSensorEvent.timestamp);
/*
if(BuildConfig.DEBUG) {
Log.d(TAG, "x = " + pSensorEvent.values[0] + " y = " + pSensorEvent.values[1] + " z = " + pSensorEvent.values[2]);
}
*/
}
@Override
public void onAccuracyChanged(final Sensor pSensor, final int pAccuracy) {
}
// ===========================================================
// Methods
// Native method called from Cocos2dxGLSurfaceView (To be in the same thread)
// ===========================================================
public static native void onSensorChanged(final float pX, final float pY, final float pZ, final long pTimestamp);
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}

View File

@ -0,0 +1,193 @@
/****************************************************************************
Copyright (c) 2010-2013 cocos2d-x.org
http://www.cocos2d-x.org
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.
****************************************************************************/
package org.cocos2dx.lib;
import org.cocos2dx.lib.Cocos2dxHelper.Cocos2dxHelperListener;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.view.ViewGroup;
import android.util.Log;
import android.widget.FrameLayout;
import java.io.File;
public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener {
// ===========================================================
// Constants
// ===========================================================
private static final String TAG = Cocos2dxActivity.class.getSimpleName();
// ===========================================================
// Fields
// ===========================================================
private Cocos2dxGLSurfaceView mGLSurfaceView;
private Cocos2dxHandler mHandler;
private static Context sContext = null;
public static Context getContext() {
return sContext;
}
// ===========================================================
// Constructors
// ===========================================================
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
Bundle bundle = ai.metaData;
try {
String libName = bundle.getString("android.app.lib_name");
System.loadLibrary(libName);
} catch (Exception e) {
// ERROR
}
} catch (PackageManager.NameNotFoundException e) {
// ERROR
}
sContext = this;
this.mHandler = new Cocos2dxHandler(this);
this.init();
Cocos2dxHelper.init(this);
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
protected void onResume() {
super.onResume();
Cocos2dxHelper.onResume();
this.mGLSurfaceView.onResume();
}
@Override
protected void onPause() {
super.onPause();
Cocos2dxHelper.onPause();
this.mGLSurfaceView.onPause();
}
@Override
public void showDialog(final String pTitle, final String pMessage) {
Message msg = new Message();
msg.what = Cocos2dxHandler.HANDLER_SHOW_DIALOG;
msg.obj = new Cocos2dxHandler.DialogMessage(pTitle, pMessage);
this.mHandler.sendMessage(msg);
}
@Override
public void showEditTextDialog(final String pTitle, final String pContent, final int pInputMode, final int pInputFlag, final int pReturnType, final int pMaxLength) {
Message msg = new Message();
msg.what = Cocos2dxHandler.HANDLER_SHOW_EDITBOX_DIALOG;
msg.obj = new Cocos2dxHandler.EditBoxMessage(pTitle, pContent, pInputMode, pInputFlag, pReturnType, pMaxLength);
this.mHandler.sendMessage(msg);
}
@Override
public void runOnGLThread(final Runnable pRunnable) {
this.mGLSurfaceView.queueEvent(pRunnable);
}
// ===========================================================
// Methods
// ===========================================================
public void init() {
// FrameLayout
ViewGroup.LayoutParams framelayout_params =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
FrameLayout framelayout = new FrameLayout(this);
framelayout.setLayoutParams(framelayout_params);
// Cocos2dxEditText layout
ViewGroup.LayoutParams edittext_layout_params =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
Cocos2dxEditText edittext = new Cocos2dxEditText(this);
edittext.setLayoutParams(edittext_layout_params);
// ...add to FrameLayout
framelayout.addView(edittext);
// Cocos2dxGLSurfaceView
this.mGLSurfaceView = this.onCreateView();
// ...add to FrameLayout
framelayout.addView(this.mGLSurfaceView);
// Switch to supported OpenGL (ARGB888) mode on emulator
if (isAndroidEmulator())
this.mGLSurfaceView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0);
this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());
this.mGLSurfaceView.setCocos2dxEditText(edittext);
// Set framelayout as the content view
setContentView(framelayout);
}
public Cocos2dxGLSurfaceView onCreateView() {
return new Cocos2dxGLSurfaceView(this);
}
private final static boolean isAndroidEmulator() {
String model = Build.MODEL;
Log.d(TAG, "model=" + model);
String product = Build.PRODUCT;
Log.d(TAG, "product=" + product);
boolean isEmulator = false;
if (product != null) {
isEmulator = product.equals("sdk") || product.contains("_sdk") || product.contains("sdk_");
}
Log.d(TAG, "isEmulator=" + isEmulator);
return isEmulator;
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}

View File

@ -0,0 +1,109 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
http://www.cocos2d-x.org
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.
****************************************************************************/
package org.cocos2dx.lib;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import android.content.Context;
import android.content.res.AssetManager;
import android.opengl.ETC1Util;
import android.util.Log;
public class Cocos2dxETCLoader {
private static final String ASSETS_PATH = "assets/";
private static Context context;
public static boolean loadTexture(String filePath) {
if (! ETC1Util.isETC1Supported()) {
return false;
}
if (filePath.length() == 0) {
return false;
}
// Create ETC1Texture
InputStream inputStream = null;
ETC1Util.ETC1Texture texture = null;
AssetManager assetManager = null;
try {
if (filePath.charAt(0) == '/') {
// absolute path
inputStream = new FileInputStream(filePath);
} else {
// remove prefix: "assets/"
if (filePath.startsWith(ASSETS_PATH)) {
filePath = filePath.substring(ASSETS_PATH.length());
}
assetManager = context.getAssets();
inputStream = assetManager.open(filePath);
}
texture = ETC1Util.createTexture(inputStream);
inputStream.close();
} catch (Exception e) {
Log.d("Cocos2dx", "Unable to create texture for " + filePath);
texture = null;
}
if (texture != null) {
boolean ret = true;
try {
final int width = texture.getWidth();
final int height = texture.getHeight();
final int length = texture.getData().remaining();
final byte[] data = new byte[length];
final ByteBuffer buf = ByteBuffer.wrap(data);
buf.order(ByteOrder.nativeOrder());
buf.put(texture.getData());
nativeSetTextureInfo(width,
height,
data,
length);
} catch (Exception e)
{
Log.d("invoke native function error", e.toString());
ret = false;
}
return ret;
} else {
return false;
}
}
public static void setContext(Context context) {
Cocos2dxETCLoader.context = context;
}
private static native void nativeSetTextureInfo(final int width, final int height, final byte[] data,
final int dataLength);
}

View File

@ -26,15 +26,9 @@ package org.cocos2dx.lib;
import android.app.Activity;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
public class Cocos2dxEditText extends EditText {
// ===========================================================
@ -44,10 +38,8 @@ public class Cocos2dxEditText extends EditText {
// ===========================================================
// Fields
// ===========================================================
private Cocos2dxTextInputWraper mTextWatcher = null;
private Context mContext = null;
private static Cocos2dxEditText instance = null;
private Cocos2dxGLSurfaceView mCocos2dxGLSurfaceView;
// ===========================================================
// Constructors
@ -55,61 +47,35 @@ public class Cocos2dxEditText extends EditText {
public Cocos2dxEditText(final Context context) {
super(context);
this.mContext = context;
this.mTextWatcher = new Cocos2dxTextInputWraper(context, this);
this.setOnEditorActionListener(this.mTextWatcher);
ViewGroup.LayoutParams layout =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
Activity activity = (Activity)context;
activity.addContentView(this, layout);
}
public Cocos2dxEditText(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public Cocos2dxEditText(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}
// ===========================================================
// Getter & Setter
// ===========================================================
public void setCocos2dxGLSurfaceView(final Cocos2dxGLSurfaceView pCocos2dxGLSurfaceView) {
this.mCocos2dxGLSurfaceView = pCocos2dxGLSurfaceView;
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
public static Cocos2dxEditText getInstance(final Context context) {
if (instance == null) {
instance = new Cocos2dxEditText(context);
}
return instance;
}
public void closeIMEKeyboard() {
this.removeTextChangedListener(mTextWatcher);
final InputMethodManager imm = (InputMethodManager)mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(this.getWindowToken(), 0);
//Cocos2dxHelper.nativeRequestFocus();
}
public void openIMEKeyboard() {
this.requestFocus();
final String content = nativeGetContent();
this.setText(content);
mTextWatcher.setOriginText(content);
this.addTextChangedListener(mTextWatcher);
final InputMethodManager imm = (InputMethodManager)mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(this, InputMethodManager.SHOW_FORCED);
}
@Override
public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) {
super.onKeyDown(keyCode, keyEvent);
public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) {
super.onKeyDown(pKeyCode, pKeyEvent);
/* Let GlSurfaceView get focus if back key is input. */
if (keyCode == KeyEvent.KEYCODE_BACK) {
//Cocos2dxHelper.nativeRequestFocus();
if (pKeyCode == KeyEvent.KEYCODE_BACK) {
this.mCocos2dxGLSurfaceView.requestFocus();
}
return true;
@ -118,133 +84,8 @@ public class Cocos2dxEditText extends EditText {
// ===========================================================
// Methods
// ===========================================================
private native static String nativeGetContent();
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
class Cocos2dxTextInputWraper implements TextWatcher, OnEditorActionListener {
// ===========================================================
// Constants
// ===========================================================
private static final String TAG = Cocos2dxTextInputWraper.class.getSimpleName();
// ===========================================================
// Fields
// ===========================================================
private String mText;
private String mOriginText;
private Context mContext;
private TextView mTextView;
// ===========================================================
// Constructors
// ===========================================================
public Cocos2dxTextInputWraper(Context context, TextView textView) {
this.mContext = context;
this.mTextView = textView;
}
// ===========================================================
// Getter & Setter
// ===========================================================
private boolean isFullScreenEdit() {
final InputMethodManager imm = (InputMethodManager) this.mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
return imm.isFullscreenMode();
}
public void setOriginText(final String originText) {
this.mOriginText = originText;
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public void afterTextChanged(final Editable s) {
if (this.isFullScreenEdit()) {
return;
}
int nModified = s.length() - this.mText.length();
if (nModified > 0) {
final String insertText = s.subSequence(this.mText.length(), s.length()).toString();
nativeInsertText(insertText);
} else {
for (; nModified < 0; ++nModified) {
nativeDeleteBackward();
}
}
this.mText = s.toString();
}
@Override
public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) {
this.mText = pCharSequence.toString();
}
@Override
public void onTextChanged(final CharSequence pCharSequence, final int start, final int before, final int count) {
}
@Override
public boolean onEditorAction(final TextView pTextView, final int pActionID, final KeyEvent pKeyEvent) {
if (this.mTextView == pTextView && this.isFullScreenEdit()) {
// user press the action button, delete all old text and insert new text
for (int i = this.mOriginText.length(); i > 0; i--) {
Cocos2dxHelper.runOnGLThread(new Runnable() {
@Override
public void run() {
nativeDeleteBackward();
}
});
}
String text = pTextView.getText().toString();
/* If user input nothing, translate "\n" to engine. */
if (text.compareTo("") == 0) {
text = "\n";
}
if ('\n' != text.charAt(text.length() - 1)) {
text += '\n';
}
final String insertText = text;
Cocos2dxHelper.runOnGLThread(new Runnable() {
@Override
public void run() {
nativeInsertText(insertText);
}
});
}
if (pActionID == EditorInfo.IME_ACTION_DONE) {
//Cocos2dxHelper.nativeRequestFocus();
}
return false;
}
// ===========================================================
// Methods
// ===========================================================
private native static void nativeInsertText(String text);
private native static void nativeDeleteBackward();
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}

View File

@ -0,0 +1,370 @@
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
http://www.cocos2d-x.org
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.
****************************************************************************/
package org.cocos2dx.lib;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.inputmethod.InputMethodManager;
public class Cocos2dxGLSurfaceView extends GLSurfaceView {
// ===========================================================
// Constants
// ===========================================================
private static final String TAG = Cocos2dxGLSurfaceView.class.getSimpleName();
private final static int HANDLER_OPEN_IME_KEYBOARD = 2;
private final static int HANDLER_CLOSE_IME_KEYBOARD = 3;
// ===========================================================
// Fields
// ===========================================================
// TODO Static handler -> Potential leak!
private static Handler sHandler;
private static Cocos2dxGLSurfaceView mCocos2dxGLSurfaceView;
private static Cocos2dxTextInputWraper sCocos2dxTextInputWraper;
private Cocos2dxRenderer mCocos2dxRenderer;
private Cocos2dxEditText mCocos2dxEditText;
// ===========================================================
// Constructors
// ===========================================================
public Cocos2dxGLSurfaceView(final Context context) {
super(context);
this.initView();
}
public Cocos2dxGLSurfaceView(final Context context, final AttributeSet attrs) {
super(context, attrs);
this.initView();
}
protected void initView() {
this.setEGLContextClientVersion(2);
this.setFocusableInTouchMode(true);
Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView = this;
Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper = new Cocos2dxTextInputWraper(this);
Cocos2dxGLSurfaceView.sHandler = new Handler() {
@Override
public void handleMessage(final Message msg) {
switch (msg.what) {
case HANDLER_OPEN_IME_KEYBOARD:
if (null != Cocos2dxGLSurfaceView.this.mCocos2dxEditText && Cocos2dxGLSurfaceView.this.mCocos2dxEditText.requestFocus()) {
Cocos2dxGLSurfaceView.this.mCocos2dxEditText.removeTextChangedListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper);
Cocos2dxGLSurfaceView.this.mCocos2dxEditText.setText("");
final String text = (String) msg.obj;
Cocos2dxGLSurfaceView.this.mCocos2dxEditText.append(text);
Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper.setOriginText(text);
Cocos2dxGLSurfaceView.this.mCocos2dxEditText.addTextChangedListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper);
final InputMethodManager imm = (InputMethodManager) Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(Cocos2dxGLSurfaceView.this.mCocos2dxEditText, 0);
Log.d("GLSurfaceView", "showSoftInput");
}
break;
case HANDLER_CLOSE_IME_KEYBOARD:
if (null != Cocos2dxGLSurfaceView.this.mCocos2dxEditText) {
Cocos2dxGLSurfaceView.this.mCocos2dxEditText.removeTextChangedListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper);
final InputMethodManager imm = (InputMethodManager) Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(Cocos2dxGLSurfaceView.this.mCocos2dxEditText.getWindowToken(), 0);
Cocos2dxGLSurfaceView.this.requestFocus();
Log.d("GLSurfaceView", "HideSoftInput");
}
break;
}
}
};
}
// ===========================================================
// Getter & Setter
// ===========================================================
public static Cocos2dxGLSurfaceView getInstance() {
return mCocos2dxGLSurfaceView;
}
public static void queueAccelerometer(final float x, final float y, final float z, final long timestamp) {
mCocos2dxGLSurfaceView.queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxAccelerometer.onSensorChanged(x, y, z, timestamp);
}
});
}
public void setCocos2dxRenderer(final Cocos2dxRenderer renderer) {
this.mCocos2dxRenderer = renderer;
this.setRenderer(this.mCocos2dxRenderer);
}
private String getContentText() {
return this.mCocos2dxRenderer.getContentText();
}
public Cocos2dxEditText getCocos2dxEditText() {
return this.mCocos2dxEditText;
}
public void setCocos2dxEditText(final Cocos2dxEditText pCocos2dxEditText) {
this.mCocos2dxEditText = pCocos2dxEditText;
if (null != this.mCocos2dxEditText && null != Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper) {
this.mCocos2dxEditText.setOnEditorActionListener(Cocos2dxGLSurfaceView.sCocos2dxTextInputWraper);
this.mCocos2dxEditText.setCocos2dxGLSurfaceView(this);
this.requestFocus();
}
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public void onResume() {
super.onResume();
this.queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleOnResume();
}
});
}
@Override
public void onPause() {
this.queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleOnPause();
}
});
//super.onPause();
}
@Override
public boolean onTouchEvent(final MotionEvent pMotionEvent) {
// these data are used in ACTION_MOVE and ACTION_CANCEL
final int pointerNumber = pMotionEvent.getPointerCount();
final int[] ids = new int[pointerNumber];
final float[] xs = new float[pointerNumber];
final float[] ys = new float[pointerNumber];
for (int i = 0; i < pointerNumber; i++) {
ids[i] = pMotionEvent.getPointerId(i);
xs[i] = pMotionEvent.getX(i);
ys[i] = pMotionEvent.getY(i);
}
switch (pMotionEvent.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_DOWN:
final int indexPointerDown = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT;
final int idPointerDown = pMotionEvent.getPointerId(indexPointerDown);
final float xPointerDown = pMotionEvent.getX(indexPointerDown);
final float yPointerDown = pMotionEvent.getY(indexPointerDown);
this.queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown(idPointerDown, xPointerDown, yPointerDown);
}
});
break;
case MotionEvent.ACTION_DOWN:
// there are only one finger on the screen
final int idDown = pMotionEvent.getPointerId(0);
final float xDown = xs[0];
final float yDown = ys[0];
this.queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown(idDown, xDown, yDown);
}
});
break;
case MotionEvent.ACTION_MOVE:
this.queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionMove(ids, xs, ys);
}
});
break;
case MotionEvent.ACTION_POINTER_UP:
final int indexPointUp = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT;
final int idPointerUp = pMotionEvent.getPointerId(indexPointUp);
final float xPointerUp = pMotionEvent.getX(indexPointUp);
final float yPointerUp = pMotionEvent.getY(indexPointUp);
this.queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp(idPointerUp, xPointerUp, yPointerUp);
}
});
break;
case MotionEvent.ACTION_UP:
// there are only one finger on the screen
final int idUp = pMotionEvent.getPointerId(0);
final float xUp = xs[0];
final float yUp = ys[0];
this.queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp(idUp, xUp, yUp);
}
});
break;
case MotionEvent.ACTION_CANCEL:
this.queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionCancel(ids, xs, ys);
}
});
break;
}
/*
if (BuildConfig.DEBUG) {
Cocos2dxGLSurfaceView.dumpMotionEvent(pMotionEvent);
}
*/
return true;
}
/*
* This function is called before Cocos2dxRenderer.nativeInit(), so the
* width and height is correct.
*/
@Override
protected void onSizeChanged(final int pNewSurfaceWidth, final int pNewSurfaceHeight, final int pOldSurfaceWidth, final int pOldSurfaceHeight) {
if(!this.isInEditMode()) {
this.mCocos2dxRenderer.setScreenWidthAndHeight(pNewSurfaceWidth, pNewSurfaceHeight);
}
}
@Override
public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) {
switch (pKeyCode) {
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_MENU:
this.queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleKeyDown(pKeyCode);
}
});
return true;
default:
return super.onKeyDown(pKeyCode, pKeyEvent);
}
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
public static void openIMEKeyboard() {
final Message msg = new Message();
msg.what = Cocos2dxGLSurfaceView.HANDLER_OPEN_IME_KEYBOARD;
msg.obj = Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView.getContentText();
Cocos2dxGLSurfaceView.sHandler.sendMessage(msg);
}
public static void closeIMEKeyboard() {
final Message msg = new Message();
msg.what = Cocos2dxGLSurfaceView.HANDLER_CLOSE_IME_KEYBOARD;
Cocos2dxGLSurfaceView.sHandler.sendMessage(msg);
}
public void insertText(final String pText) {
this.queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleInsertText(pText);
}
});
}
public void deleteBackward() {
this.queueEvent(new Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleDeleteBackward();
}
});
}
private static void dumpMotionEvent(final MotionEvent event) {
final String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
final StringBuilder sb = new StringBuilder();
final int action = event.getAction();
final int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_").append(names[actionCode]);
if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) {
sb.append("(pid ").append(action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")");
}
sb.append("[");
for (int i = 0; i < event.getPointerCount(); i++) {
sb.append("#").append(i);
sb.append("(pid ").append(event.getPointerId(i));
sb.append(")=").append((int) event.getX(i));
sb.append(",").append((int) event.getY(i));
if (i + 1 < event.getPointerCount()) {
sb.append(";");
}
}
sb.append("]");
Log.d(Cocos2dxGLSurfaceView.TAG, sb.toString());
}
}

View File

@ -0,0 +1,135 @@
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
http://www.cocos2d-x.org
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.
****************************************************************************/
package org.cocos2dx.lib;
import java.lang.ref.WeakReference;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Handler;
import android.os.Message;
public class Cocos2dxHandler extends Handler {
// ===========================================================
// Constants
// ===========================================================
public final static int HANDLER_SHOW_DIALOG = 1;
public final static int HANDLER_SHOW_EDITBOX_DIALOG = 2;
// ===========================================================
// Fields
// ===========================================================
private WeakReference<Cocos2dxActivity> mActivity;
// ===========================================================
// Constructors
// ===========================================================
public Cocos2dxHandler(Cocos2dxActivity activity) {
this.mActivity = new WeakReference<Cocos2dxActivity>(activity);
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
// ===========================================================
// Methods
// ===========================================================
public void handleMessage(Message msg) {
switch (msg.what) {
case Cocos2dxHandler.HANDLER_SHOW_DIALOG:
showDialog(msg);
break;
case Cocos2dxHandler.HANDLER_SHOW_EDITBOX_DIALOG:
showEditBoxDialog(msg);
break;
}
}
private void showDialog(Message msg) {
Cocos2dxActivity theActivity = this.mActivity.get();
DialogMessage dialogMessage = (DialogMessage)msg.obj;
new AlertDialog.Builder(theActivity)
.setTitle(dialogMessage.titile)
.setMessage(dialogMessage.message)
.setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}).create().show();
}
private void showEditBoxDialog(Message msg) {
EditBoxMessage editBoxMessage = (EditBoxMessage)msg.obj;
new Cocos2dxEditBoxDialog(this.mActivity.get(),
editBoxMessage.title,
editBoxMessage.content,
editBoxMessage.inputMode,
editBoxMessage.inputFlag,
editBoxMessage.returnType,
editBoxMessage.maxLength).show();
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
public static class DialogMessage {
public String titile;
public String message;
public DialogMessage(String title, String message) {
this.titile = title;
this.message = message;
}
}
public static class EditBoxMessage {
public String title;
public String content;
public int inputMode;
public int inputFlag;
public int returnType;
public int maxLength;
public EditBoxMessage(String title, String content, int inputMode, int inputFlag, int returnType, int maxLength){
this.content = content;
this.title = title;
this.inputMode = inputMode;
this.inputFlag = inputFlag;
this.returnType = returnType;
this.maxLength = maxLength;
}
}
}

View File

@ -31,6 +31,7 @@ import java.lang.Runnable;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
@ -56,6 +57,7 @@ public class Cocos2dxHelper {
private static Cocos2dxMusic sCocos2dMusic;
private static Cocos2dxSound sCocos2dSound;
private static AssetManager sAssetManager;
private static Cocos2dxAccelerometer sCocos2dxAccelerometer;
private static boolean sAccelerometerEnabled;
private static String sPackageName;
private static String sFileDirectory;
@ -94,7 +96,7 @@ public class Cocos2dxHelper {
if (!sInited) {
final ApplicationInfo applicationInfo = activity.getApplicationInfo();
initListener();
Cocos2dxHelper.sCocos2dxHelperListener = (Cocos2dxHelperListener)activity;
try {
// Get the lib_name from AndroidManifest.xml metadata
@ -114,87 +116,23 @@ public class Cocos2dxHelper {
Cocos2dxHelper.sPackageName = applicationInfo.packageName;
Cocos2dxHelper.sFileDirectory = activity.getFilesDir().getAbsolutePath();
//Cocos2dxHelper.nativeSetApkPath(applicationInfo.sourceDir);
Cocos2dxHelper.nativeSetApkPath(applicationInfo.sourceDir);
Cocos2dxHelper.sCocos2dxAccelerometer = new Cocos2dxAccelerometer(activity);
Cocos2dxHelper.sCocos2dMusic = new Cocos2dxMusic(activity);
Cocos2dxHelper.sCocos2dSound = new Cocos2dxSound(activity);
Cocos2dxHelper.sAssetManager = activity.getAssets();
Cocos2dxHelper.nativeSetContext((Context)activity, Cocos2dxHelper.sAssetManager);
//Cocos2dxHelper.nativeSetAssetManager(sAssetManager);
Cocos2dxBitmap.setContext(activity);
Cocos2dxETCLoader.setContext(activity);
sActivity = activity;
sInited = true;
}
}
public static void initListener() {
Cocos2dxHelper.sCocos2dxHelperListener = new Cocos2dxHelperListener() {
@Override
public void showEditTextDialog(final String title, final String message,
final int inputMode, final int inputFlag, final int returnType, final int maxLength) {
sActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
new Cocos2dxEditBoxDialog(sActivity,
title,
message,
inputMode,
inputFlag,
returnType,
maxLength).show();
}
});
}
@Override
public void openIMEKeyboard() {
sActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
Cocos2dxEditText.getInstance(sActivity).openIMEKeyboard();
}
});
}
@Override
public void closeIMEKeyboard() {
sActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
Cocos2dxEditText.getInstance(sActivity).closeIMEKeyboard();
}
});
}
@Override
public void showDialog(final String title, final String message) {
sActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
new AlertDialog.Builder(sActivity)
.setTitle(title)
.setMessage(message)
.setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}).create().show();
}
});
}
};
}
public static Activity getActivity() {
return sActivity;
}
@ -211,8 +149,12 @@ public class Cocos2dxHelper {
// Methods
// ===========================================================
private static native void nativeSetApkPath(final String pApkPath);
private static native void nativeSetEditTextDialogResult(final byte[] pBytes);
private static native void nativeSetContext(final Context pContext, final AssetManager pAssetManager);
public static String getCocos2dxPackageName() {
return Cocos2dxHelper.sPackageName;
}
@ -233,6 +175,21 @@ public class Cocos2dxHelper {
return Cocos2dxHelper.sAssetManager;
}
public static void enableAccelerometer() {
Cocos2dxHelper.sAccelerometerEnabled = true;
Cocos2dxHelper.sCocos2dxAccelerometer.enable();
}
public static void setAccelerometerInterval(float interval) {
Cocos2dxHelper.sCocos2dxAccelerometer.setInterval(interval);
}
public static void disableAccelerometer() {
Cocos2dxHelper.sAccelerometerEnabled = false;
Cocos2dxHelper.sCocos2dxAccelerometer.disable();
}
public static void preloadBackgroundMusic(final String pPath) {
Cocos2dxHelper.sCocos2dMusic.preloadBackgroundMusic(pPath);
}
@ -318,6 +275,18 @@ public class Cocos2dxHelper {
Cocos2dxHelper.sCocos2dSound.end();
}
public static void onResume() {
if (Cocos2dxHelper.sAccelerometerEnabled) {
Cocos2dxHelper.sCocos2dxAccelerometer.enable();
}
}
public static void onPause() {
if (Cocos2dxHelper.sAccelerometerEnabled) {
Cocos2dxHelper.sCocos2dxAccelerometer.disable();
}
}
public static void terminateProcess() {
android.os.Process.killProcess(android.os.Process.myPid());
}
@ -333,19 +302,17 @@ public class Cocos2dxHelper {
public static void setEditTextDialogResult(final String pResult) {
try {
final byte[] bytesUTF8 = pResult.getBytes("UTF8");
Cocos2dxHelper.nativeSetEditTextDialogResult(bytesUTF8);
Cocos2dxHelper.sCocos2dxHelperListener.runOnGLThread(new Runnable() {
@Override
public void run() {
Cocos2dxHelper.nativeSetEditTextDialogResult(bytesUTF8);
}
});
} catch (UnsupportedEncodingException pUnsupportedEncodingException) {
/* Nothing. */
}
}
private static void openIMEKeyboard() {
sCocos2dxHelperListener.openIMEKeyboard();
}
private static void closeIMEKeyboard() {
sCocos2dxHelperListener.closeIMEKeyboard();
}
public static int getDPI()
{
@ -431,17 +398,15 @@ public class Cocos2dxHelper {
editor.putString(key, value);
editor.commit();
}
public static native void nativeRequestFocus();
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
public static interface Cocos2dxHelperListener {
public void showDialog(final String title, final String message);
public void showEditTextDialog(final String title, final String message, final int inputMode, final int inputFlag, final int returnType, final int maxLength);
public void openIMEKeyboard();
public void closeIMEKeyboard();
public void showDialog(final String pTitle, final String pMessage);
public void showEditTextDialog(final String pTitle, final String pMessage, final int pInputMode, final int pInputFlag, final int pReturnType, final int pMaxLength);
public void runOnGLThread(final Runnable pRunnable);
}
}

View File

@ -46,10 +46,10 @@ public class Cocos2dxLocalStorage {
* @return
*/
public static boolean init(String dbName, String tableName) {
if (Cocos2dxHelper.getActivity() != null) {
if (Cocos2dxActivity.getContext() != null) {
DATABASE_NAME = dbName;
TABLE_NAME = tableName;
mDatabaseOpenHelper = new DBOpenHelper(Cocos2dxHelper.getActivity());
mDatabaseOpenHelper = new DBOpenHelper(Cocos2dxActivity.getContext());
mDatabase = mDatabaseOpenHelper.getWritableDatabase();
return true;
}

View File

@ -0,0 +1,171 @@
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
http://www.cocos2d-x.org
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.
****************************************************************************/
package org.cocos2dx.lib;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
public class Cocos2dxRenderer implements GLSurfaceView.Renderer {
// ===========================================================
// Constants
// ===========================================================
private final static long NANOSECONDSPERSECOND = 1000000000L;
private final static long NANOSECONDSPERMICROSECOND = 1000000;
private static long sAnimationInterval = (long) (1.0 / 60 * Cocos2dxRenderer.NANOSECONDSPERSECOND);
// ===========================================================
// Fields
// ===========================================================
private long mLastTickInNanoSeconds;
private int mScreenWidth;
private int mScreenHeight;
// ===========================================================
// Constructors
// ===========================================================
// ===========================================================
// Getter & Setter
// ===========================================================
public static void setAnimationInterval(final double pAnimationInterval) {
Cocos2dxRenderer.sAnimationInterval = (long) (pAnimationInterval * Cocos2dxRenderer.NANOSECONDSPERSECOND);
}
public void setScreenWidthAndHeight(final int pSurfaceWidth, final int pSurfaceHeight) {
this.mScreenWidth = pSurfaceWidth;
this.mScreenHeight = pSurfaceHeight;
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public void onSurfaceCreated(final GL10 pGL10, final EGLConfig pEGLConfig) {
Cocos2dxRenderer.nativeInit(this.mScreenWidth, this.mScreenHeight);
this.mLastTickInNanoSeconds = System.nanoTime();
}
@Override
public void onSurfaceChanged(final GL10 pGL10, final int pWidth, final int pHeight) {
}
@Override
public void onDrawFrame(final GL10 gl) {
/*
* FPS controlling algorithm is not accurate, and it will slow down FPS
* on some devices. So comment FPS controlling code.
*/
/*
final long nowInNanoSeconds = System.nanoTime();
final long interval = nowInNanoSeconds - this.mLastTickInNanoSeconds;
*/
// should render a frame when onDrawFrame() is called or there is a
// "ghost"
Cocos2dxRenderer.nativeRender();
/*
// fps controlling
if (interval < Cocos2dxRenderer.sAnimationInterval) {
try {
// because we render it before, so we should sleep twice time interval
Thread.sleep((Cocos2dxRenderer.sAnimationInterval - interval) / Cocos2dxRenderer.NANOSECONDSPERMICROSECOND);
} catch (final Exception e) {
}
}
this.mLastTickInNanoSeconds = nowInNanoSeconds;
*/
}
// ===========================================================
// Methods
// ===========================================================
private static native void nativeTouchesBegin(final int pID, final float pX, final float pY);
private static native void nativeTouchesEnd(final int pID, final float pX, final float pY);
private static native void nativeTouchesMove(final int[] pIDs, final float[] pXs, final float[] pYs);
private static native void nativeTouchesCancel(final int[] pIDs, final float[] pXs, final float[] pYs);
private static native boolean nativeKeyDown(final int pKeyCode);
private static native void nativeRender();
private static native void nativeInit(final int pWidth, final int pHeight);
private static native void nativeOnPause();
private static native void nativeOnResume();
public void handleActionDown(final int pID, final float pX, final float pY) {
Cocos2dxRenderer.nativeTouchesBegin(pID, pX, pY);
}
public void handleActionUp(final int pID, final float pX, final float pY) {
Cocos2dxRenderer.nativeTouchesEnd(pID, pX, pY);
}
public void handleActionCancel(final int[] pIDs, final float[] pXs, final float[] pYs) {
Cocos2dxRenderer.nativeTouchesCancel(pIDs, pXs, pYs);
}
public void handleActionMove(final int[] pIDs, final float[] pXs, final float[] pYs) {
Cocos2dxRenderer.nativeTouchesMove(pIDs, pXs, pYs);
}
public void handleKeyDown(final int pKeyCode) {
Cocos2dxRenderer.nativeKeyDown(pKeyCode);
}
public void handleOnPause() {
Cocos2dxRenderer.nativeOnPause();
}
public void handleOnResume() {
Cocos2dxRenderer.nativeOnResume();
}
private static native void nativeInsertText(final String pText);
private static native void nativeDeleteBackward();
private static native String nativeGetContentText();
public void handleInsertText(final String pText) {
Cocos2dxRenderer.nativeInsertText(pText);
}
public void handleDeleteBackward() {
Cocos2dxRenderer.nativeDeleteBackward();
}
public String getContentText() {
return Cocos2dxRenderer.nativeGetContentText();
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}

View File

@ -0,0 +1,168 @@
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
http://www.cocos2d-x.org
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.
****************************************************************************/
package org.cocos2dx.lib;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
public class Cocos2dxTextInputWraper implements TextWatcher, OnEditorActionListener {
// ===========================================================
// Constants
// ===========================================================
private static final String TAG = Cocos2dxTextInputWraper.class.getSimpleName();
// ===========================================================
// Fields
// ===========================================================
private final Cocos2dxGLSurfaceView mCocos2dxGLSurfaceView;
private String mText;
private String mOriginText;
// ===========================================================
// Constructors
// ===========================================================
public Cocos2dxTextInputWraper(final Cocos2dxGLSurfaceView pCocos2dxGLSurfaceView) {
this.mCocos2dxGLSurfaceView = pCocos2dxGLSurfaceView;
}
// ===========================================================
// Getter & Setter
// ===========================================================
private boolean isFullScreenEdit() {
final TextView textField = this.mCocos2dxGLSurfaceView.getCocos2dxEditText();
final InputMethodManager imm = (InputMethodManager) textField.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
return imm.isFullscreenMode();
}
public void setOriginText(final String pOriginText) {
this.mOriginText = pOriginText;
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public void afterTextChanged(final Editable s) {
if (this.isFullScreenEdit()) {
return;
}
//if (BuildConfig.DEBUG) {
//Log.d(TAG, "afterTextChanged: " + s);
//}
int nModified = s.length() - this.mText.length();
if (nModified > 0) {
final String insertText = s.subSequence(this.mText.length(), s.length()).toString();
this.mCocos2dxGLSurfaceView.insertText(insertText);
/*
if (BuildConfig.DEBUG) {
Log.d(TAG, "insertText(" + insertText + ")");
}
*/
} else {
for (; nModified < 0; ++nModified) {
this.mCocos2dxGLSurfaceView.deleteBackward();
/*
if (BuildConfig.DEBUG) {
Log.d(TAG, "deleteBackward");
}
*/
}
}
this.mText = s.toString();
}
@Override
public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) {
/*
if (BuildConfig.DEBUG) {
Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after);
}
*/
this.mText = pCharSequence.toString();
}
@Override
public void onTextChanged(final CharSequence pCharSequence, final int start, final int before, final int count) {
}
@Override
public boolean onEditorAction(final TextView pTextView, final int pActionID, final KeyEvent pKeyEvent) {
if (this.mCocos2dxGLSurfaceView.getCocos2dxEditText() == pTextView && this.isFullScreenEdit()) {
// user press the action button, delete all old text and insert new text
for (int i = this.mOriginText.length(); i > 0; i--) {
this.mCocos2dxGLSurfaceView.deleteBackward();
/*
if (BuildConfig.DEBUG) {
Log.d(TAG, "deleteBackward");
}
*/
}
String text = pTextView.getText().toString();
/* If user input nothing, translate "\n" to engine. */
if (text.compareTo("") == 0) {
text = "\n";
}
if ('\n' != text.charAt(text.length() - 1)) {
text += '\n';
}
final String insertText = text;
this.mCocos2dxGLSurfaceView.insertText(insertText);
/*
if (BuildConfig.DEBUG) {
Log.d(TAG, "insertText(" + insertText + ")");
}
*/
}
if (pActionID == EditorInfo.IME_ACTION_DONE) {
this.mCocos2dxGLSurfaceView.requestFocus();
}
return false;
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}

View File

@ -0,0 +1,82 @@
/****************************************************************************
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
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 "CCApplication.h"
#include "CCDirector.h"
#include "CCDrawingPrimitives.h"
#include "CCEventCustom.h"
#include "CCEventType.h"
#include "CCGLView.h"
#include "CCShaderCache.h"
#include "CCTextureCache.h"
#include "platform/android/jni/JniHelper.h"
#include <android/log.h>
#include <jni.h>
#define LOG_TAG "main"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
void cocos_android_app_init(JNIEnv* env, jobject thiz) __attribute__((weak));
using namespace cocos2d;
extern "C"
{
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
JniHelper::setJavaVM(vm);
return JNI_VERSION_1_4;
}
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
{
auto director = cocos2d::Director::getInstance();
auto glview = director->getOpenGLView();
if (!glview)
{
glview = cocos2d::GLView::create("Android app");
glview->setFrameSize(w, h);
director->setOpenGLView(glview);
cocos_android_app_init(env, thiz);
cocos2d::Application::getInstance()->run();
}
else
{
cocos2d::GL::invalidateStateCache();
cocos2d::ShaderCache::getInstance()->reloadDefaultShaders();
cocos2d::DrawPrimitives::init();
cocos2d::VolatileTextureMgr::reloadAllTextures();
cocos2d::EventCustom foregroundEvent(EVENT_COME_TO_FOREGROUND);
director->getEventDispatcher()->dispatchEvent(&foregroundEvent);
director->setGLDefaultValues();
}
}
}

View File

@ -44,7 +44,7 @@ extern "C" {
void openKeyboardJNI() {
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxHelper", "openIMEKeyboard", "()V")) {
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxGLSurfaceView", "openIMEKeyboard", "()V")) {
t.env->CallStaticVoidMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID);
}
@ -53,29 +53,9 @@ extern "C" {
void closeKeyboardJNI() {
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxHelper", "closeIMEKeyboard", "()V")) {
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxGLSurfaceView", "closeIMEKeyboard", "()V")) {
t.env->CallStaticVoidMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID);
}
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxTextInputWraper_nativeInsertText(JNIEnv* env, jobject thiz, jstring text) {
const char* tmpText = env->GetStringUTFChars(text, nullptr);
cocos2d::IMEDispatcher::sharedDispatcher()->dispatchInsertText(tmpText, strlen(tmpText));
env->ReleaseStringUTFChars(text, tmpText);
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxTextInputWraper_nativeDeleteBackward(JNIEnv* env, jobject thiz) {
cocos2d::IMEDispatcher::sharedDispatcher()->dispatchDeleteBackward();
}
JNIEXPORT jstring JNICALL Java_org_cocos2dx_lib_Cocos2dxEditText_nativeGetContent() {
JNIEnv * env = 0;
if (JniHelper::getJavaVM()->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK || ! env) {
return 0;
}
const std::string& text = cocos2d::IMEDispatcher::sharedDispatcher()->getContentText();
return env->NewStringUTF(text.c_str());
}
}

View File

@ -0,0 +1,22 @@
#include "JniHelper.h"
#include <jni.h>
#include "CCDirector.h"
#include "CCEventDispatcher.h"
#include "CCEventAcceleration.h"
#define TG3_GRAVITY_EARTH (9.80665f)
using namespace cocos2d;
extern "C" {
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxAccelerometer_onSensorChanged(JNIEnv* env, jobject thiz, jfloat x, jfloat y, jfloat z, jlong timeStamp) {
Acceleration a;
a.x = -((double)x / TG3_GRAVITY_EARTH);
a.y = -((double)y / TG3_GRAVITY_EARTH);
a.z = -((double)z / TG3_GRAVITY_EARTH);
a.timestamp = (double)timeStamp;
EventAcceleration event(a);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
}
}

View File

@ -27,6 +27,8 @@ THE SOFTWARE.
#include <android/log.h>
#include <string>
#include "JniHelper.h"
#include "CCFileUtilsAndroid.h"
#include "android/asset_manager_jni.h"
#include "CCString.h"
#include "Java_org_cocos2dx_lib_Cocos2dxHelper.h"
@ -48,6 +50,30 @@ extern "C" {
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetApkPath(JNIEnv* env, jobject thiz, jstring apkPath) {
g_apkPath = JniHelper::jstring2string(apkPath);
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetContext(JNIEnv* env, jobject thiz, jobject context, jobject assetManager) {
JniHelper::setClassLoaderFrom(context);
FileUtilsAndroid::setassetmanager(AAssetManager_fromJava(env, assetManager));
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetEditTextDialogResult(JNIEnv * env, jobject obj, jbyteArray text) {
jsize size = env->GetArrayLength(text);
if (size > 0) {
jbyte * data = (jbyte*)env->GetByteArrayElements(text, 0);
char* pBuf = (char*)malloc(size+1);
if (pBuf != NULL) {
memcpy(pBuf, data, size);
pBuf[size] = '\0';
// pass data to edittext's delegate
if (s_pfEditTextCallback) s_pfEditTextCallback(pBuf, s_ctx);
free(pBuf);
}
env->ReleaseByteArrayElements(text, data, 0);
} else {
if (s_pfEditTextCallback) s_pfEditTextCallback("", s_ctx);
}
}
}
const char * getApkPath() {
@ -156,6 +182,33 @@ std::string getCurrentLanguageJNI() {
return ret;
}
void enableAccelerometerJni() {
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "enableAccelerometer", "()V")) {
t.env->CallStaticVoidMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID);
}
}
void setAccelerometerIntervalJni(float interval) {
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "setAccelerometerInterval", "(F)V")) {
t.env->CallStaticVoidMethod(t.classID, t.methodID, interval);
t.env->DeleteLocalRef(t.classID);
}
}
void disableAccelerometerJni() {
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "disableAccelerometer", "()V")) {
t.env->CallStaticVoidMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID);
}
}
// functions for UserDefault
bool getBoolForKeyJNI(const char* pKey, bool defaultValue)
{

View File

@ -36,6 +36,9 @@ extern void terminateProcessJNI();
extern std::string getCurrentLanguageJNI();
extern std::string getPackageNameJNI();
extern std::string getFileDirectoryJNI();
extern void enableAccelerometerJni();
extern void disableAccelerometerJni();
extern void setAccelerometerIntervalJni(float interval);
// functions for UserDefault
extern bool getBoolForKeyJNI(const char* pKey, bool defaultValue);
extern int getIntegerForKeyJNI(const char* pKey, int defaultValue);

View File

@ -0,0 +1,46 @@
#include "CCIMEDispatcher.h"
#include "CCDirector.h"
#include "../CCApplication.h"
#include "platform/CCFileUtils.h"
#include "CCEventType.h"
#include "JniHelper.h"
#include <jni.h>
using namespace cocos2d;
extern "C" {
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender(JNIEnv* env) {
cocos2d::Director::getInstance()->mainLoop();
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnPause() {
Application::getInstance()->applicationDidEnterBackground();
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnResume() {
if (Director::getInstance()->getOpenGLView()) {
Application::getInstance()->applicationWillEnterForeground();
}
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInsertText(JNIEnv* env, jobject thiz, jstring text) {
const char* pszText = env->GetStringUTFChars(text, NULL);
cocos2d::IMEDispatcher::sharedDispatcher()->dispatchInsertText(pszText, strlen(pszText));
env->ReleaseStringUTFChars(text, pszText);
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeDeleteBackward(JNIEnv* env, jobject thiz) {
cocos2d::IMEDispatcher::sharedDispatcher()->dispatchDeleteBackward();
}
JNIEXPORT jstring JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeGetContentText() {
JNIEnv * env = 0;
if (JniHelper::getJavaVM()->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK || ! env) {
return 0;
}
std::string pszText = cocos2d::IMEDispatcher::sharedDispatcher()->getContentText();
return env->NewStringUTF(pszText.c_str());
}
}

View File

@ -30,6 +30,8 @@ THE SOFTWARE.
#define LOG_TAG "JniHelper"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
static pthread_key_t g_key;
jclass _getClassID(const char *className) {
if (NULL == className) {
return NULL;
@ -57,29 +59,22 @@ namespace cocos2d {
JavaVM* JniHelper::_psJavaVM = NULL;
jmethodID JniHelper::loadclassMethod_methodID = NULL;
jobject JniHelper::classloader = NULL;
JNIEnv* JniHelper::env = NULL;
static pthread_key_t s_threadKey;
JavaVM* JniHelper::getJavaVM() {
pthread_t thisthread = pthread_self();
LOGD("JniHelper::getJavaVM(), pthread_self() = %X", thisthread);
LOGD("JniHelper::getJavaVM(), pthread_self() = %ld", thisthread);
return _psJavaVM;
}
void JniHelper::setJavaVM(JavaVM *javaVM) {
pthread_t thisthread = pthread_self();
LOGD("JniHelper::setJavaVM(%p), pthread_self() = %X", javaVM, thisthread);
LOGD("JniHelper::setJavaVM(%p), pthread_self() = %ld", javaVM, thisthread);
_psJavaVM = javaVM;
JniHelper::cacheEnv(javaVM);
pthread_key_create(&g_key, NULL);
}
void JniHelper::detach_current_thread (void *env) {
_psJavaVM->DetachCurrentThread();
}
bool JniHelper::cacheEnv(JavaVM* jvm) {
JNIEnv* JniHelper::cacheEnv(JavaVM* jvm) {
JNIEnv* _env = NULL;
// get jni environment
jint ret = jvm->GetEnv((void**)&_env, JNI_VERSION_1_4);
@ -87,8 +82,8 @@ namespace cocos2d {
switch (ret) {
case JNI_OK :
// Success!
JniHelper::env = _env;
return true;
pthread_setspecific(g_key, _env);
return _env;
case JNI_EDETACHED :
// Thread not attached
@ -96,20 +91,16 @@ namespace cocos2d {
// TODO : If calling AttachCurrentThread() on a native thread
// must call DetachCurrentThread() in future.
// see: http://developer.android.com/guide/practices/design/jni.html
pthread_key_create (&s_threadKey, JniHelper::detach_current_thread);
if (jvm->AttachCurrentThread(&_env, NULL) < 0)
{
LOGD("Failed to get the environment using AttachCurrentThread()");
JniHelper::env = NULL;
return false;
return NULL;
} else {
// Success : Attached and obtained JNIEnv!
JniHelper::env = _env;
if (pthread_getspecific(s_threadKey) == NULL)
pthread_setspecific(s_threadKey, _env);
return true;
pthread_setspecific(g_key, _env);
return _env;
}
case JNI_EVERSION :
@ -117,25 +108,27 @@ namespace cocos2d {
LOGD("JNI interface version 1.4 not supported");
default :
LOGD("Failed to get the environment using GetEnv()");
JniHelper::env = NULL;
return false;
return NULL;
}
}
JNIEnv* JniHelper::getEnv() {
return JniHelper::env;
JNIEnv *_env = (JNIEnv *)pthread_getspecific(g_key);
if (_env == NULL)
_env = JniHelper::cacheEnv(_psJavaVM);
return _env;
}
bool JniHelper::setClassLoaderFrom(jobject nativeactivityinstance) {
bool JniHelper::setClassLoaderFrom(jobject activityinstance) {
JniMethodInfo _getclassloaderMethod;
if (!JniHelper::getMethodInfo_DefaultClassLoader(_getclassloaderMethod,
"android/app/NativeActivity",
"android/content/Context",
"getClassLoader",
"()Ljava/lang/ClassLoader;")) {
return false;
}
jobject _c = cocos2d::JniHelper::getEnv()->CallObjectMethod(nativeactivityinstance,
jobject _c = cocos2d::JniHelper::getEnv()->CallObjectMethod(activityinstance,
_getclassloaderMethod.methodID);
if (NULL == _c) {
@ -214,7 +207,6 @@ namespace cocos2d {
jmethodID methodID = pEnv->GetMethodID(classID, methodName, paramCode);
if (! methodID) {
LOGD("Failed to find method id of %s", methodName);
pEnv->ExceptionClear();
return false;
}
@ -243,6 +235,7 @@ namespace cocos2d {
jclass classID = _getClassID(className);
if (! classID) {
LOGD("Failed to find class %s", className);
pEnv->ExceptionClear();
return false;
}

View File

@ -45,7 +45,7 @@ public:
static JavaVM* getJavaVM();
static JNIEnv* getEnv();
static bool setClassLoaderFrom(jobject nativeActivityInstance);
static bool setClassLoaderFrom(jobject activityInstance);
static bool getStaticMethodInfo(JniMethodInfo &methodinfo,
const char *className,
const char *methodName,
@ -61,8 +61,7 @@ public:
static jobject classloader;
private:
static void detach_current_thread (void *env);
static bool cacheEnv(JavaVM* jvm);
static JNIEnv* cacheEnv(JavaVM* jvm);
static bool getMethodInfo_DefaultClassLoader(JniMethodInfo &methodinfo,
const char *className,
@ -70,7 +69,6 @@ private:
const char *paramCode);
static JavaVM* _psJavaVM;
static JNIEnv* env;
};
NS_CC_END

View File

@ -0,0 +1,93 @@
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org
http://www.cocos2d-x.org
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 "CCSet.h"
#include "CCDirector.h"
#include "CCEventKeyboard.h"
#include "CCGLView.h"
#include <android/log.h>
#include <jni.h>
using namespace cocos2d;
extern "C" {
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesBegin(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y) {
cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, &id, &x, &y);
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesEnd(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y) {
cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesEnd(1, &id, &x, &y);
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesMove(JNIEnv * env, jobject thiz, jintArray ids, jfloatArray xs, jfloatArray ys) {
int size = env->GetArrayLength(ids);
jint id[size];
jfloat x[size];
jfloat y[size];
env->GetIntArrayRegion(ids, 0, size, id);
env->GetFloatArrayRegion(xs, 0, size, x);
env->GetFloatArrayRegion(ys, 0, size, y);
cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesMove(size, id, x, y);
}
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesCancel(JNIEnv * env, jobject thiz, jintArray ids, jfloatArray xs, jfloatArray ys) {
int size = env->GetArrayLength(ids);
jint id[size];
jfloat x[size];
jfloat y[size];
env->GetIntArrayRegion(ids, 0, size, id);
env->GetFloatArrayRegion(xs, 0, size, x);
env->GetFloatArrayRegion(ys, 0, size, y);
cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesCancel(size, id, x, y);
}
#define KEYCODE_BACK 0x04
#define KEYCODE_MENU 0x52
JNIEXPORT jboolean JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeKeyDown(JNIEnv * env, jobject thiz, jint keyCode) {
Director* pDirector = Director::getInstance();
switch (keyCode) {
case KEYCODE_BACK:
{
cocos2d::EventKeyboard event(cocos2d::EventKeyboard::KeyCode::KEY_BACKSPACE, false);
cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
return JNI_TRUE;
}
case KEYCODE_MENU:
{
cocos2d::EventKeyboard event(cocos2d::EventKeyboard::KeyCode::KEY_MENU, false);
cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
return JNI_TRUE;
}
default:
return JNI_FALSE;
}
return JNI_FALSE;
}
}

View File

@ -1,765 +0,0 @@
/****************************************************************************
Copyright (c) 2013-2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
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 "CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include "nativeactivity.h"
#include <jni.h>
#include <errno.h>
#include <EGL/egl.h>
#include <GLES/gl.h>
#include <android/sensor.h>
#include <android/log.h>
#include <android_native_app_glue.h>
#include <android/configuration.h>
#include <pthread.h>
#include <chrono>
#include "CCDirector.h"
#include "CCApplication.h"
#include "CCEventType.h"
#include "CCFileUtilsAndroid.h"
#include "jni/JniHelper.h"
#include "CCGLView.h"
#include "CCDrawingPrimitives.h"
#include "CCShaderCache.h"
#include "CCTextureCache.h"
#include "CCEventDispatcher.h"
#include "CCEventAcceleration.h"
#include "CCEventKeyboard.h"
#include "CCEventCustom.h"
#include "jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h"
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "cocos2dx/nativeactivity.cpp", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "cocos2dx/nativeactivity.cpp", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "cocos2dx/nativeactivity.cpp", __VA_ARGS__))
#define LOG_RENDER_DEBUG(...)
// #define LOG_RENDER_DEBUG(...) ((void)__android_log_print(ANDROID_LOG_INFO, "cocos2dx/nativeactivity.cpp", __VA_ARGS__))
#define LOG_EVENTS_DEBUG(...)
// #define LOG_EVENTS_DEBUG(...) ((void)__android_log_print(ANDROID_LOG_INFO, "cocos2dx/nativeactivity.cpp", __VA_ARGS__))
/* For debug builds, always enable the debug traces in this library */
#ifndef NDEBUG
# define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "cocos2dx/nativeactivity.cpp", __VA_ARGS__))
#else
# define LOGV(...) ((void)0)
#endif
void cocos_android_app_init(struct android_app* app);
/**
* Our saved state data.
*/
struct saved_state {
float angle;
int32_t x;
int32_t y;
};
/**
* Shared state for our app.
*/
struct engine {
struct android_app* app;
ASensorManager* sensorManager;
const ASensor* accelerometerSensor;
ASensorEventQueue* sensorEventQueue;
int animating;
EGLDisplay display;
EGLSurface surface;
EGLContext context;
int32_t width;
int32_t height;
struct saved_state state;
};
static bool isContentRectChanged = false;
static std::chrono::steady_clock::time_point timeRectChanged;
static struct engine engine;
static char* editboxText = NULL;
extern EditTextCallback s_pfEditTextCallback;
extern void* s_ctx;
extern "C" {
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetEditTextDialogResult(JNIEnv * env, jobject obj, jbyteArray text) {
jsize size = env->GetArrayLength(text);
pthread_mutex_lock(&(engine.app->mutex));
if (size > 0) {
jbyte * data = (jbyte*)env->GetByteArrayElements(text, 0);
char* pBuf = (char*)malloc(size+1);
if (pBuf != NULL) {
memcpy(pBuf, data, size);
pBuf[size] = '\0';
editboxText = pBuf;
}
env->ReleaseByteArrayElements(text, data, 0);
} else {
char* pBuf = (char*)malloc(1);
pBuf[0] = '\0';
editboxText = pBuf;
}
pthread_cond_broadcast(&engine.app->cond);
pthread_mutex_unlock(&(engine.app->mutex));
}
}
typedef struct cocos_dimensions {
int w;
int h;
} cocos_dimensions;
static void cocos_init(cocos_dimensions d, struct android_app* app)
{
LOGI("cocos_init(...)");
pthread_t thisthread = pthread_self();
LOGI("pthread_self() = %X", thisthread);
cocos2d::FileUtilsAndroid::setassetmanager(app->activity->assetManager);
auto director = cocos2d::Director::getInstance();
auto glview = director->getOpenGLView();
if (!glview)
{
glview = cocos2d::GLView::create("Android app");
glview->setFrameSize(d.w, d.h);
director->setOpenGLView(glview);
cocos_android_app_init(app);
cocos2d::Application::getInstance()->run();
}
else
{
cocos2d::GL::invalidateStateCache();
cocos2d::ShaderCache::getInstance()->reloadDefaultShaders();
cocos2d::DrawPrimitives::init();
cocos2d::VolatileTextureMgr::reloadAllTextures();
cocos2d::EventCustom foregroundEvent(EVENT_COME_TO_FOREGROUND);
director->getEventDispatcher()->dispatchEvent(&foregroundEvent);
director->setGLDefaultValues();
}
}
/**
* Initialize an EGL context for the current display.
*/
static cocos_dimensions engine_init_display(struct engine* engine)
{
cocos_dimensions r;
r.w = -1;
r.h = -1;
// initialize OpenGL ES and EGL
/*
* Here specify the attributes of the desired configuration.
* Below, we select an EGLConfig with at least 8 bits per color
* component compatible with on-screen windows
*/
const EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_BLUE_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_RED_SIZE, 5,
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, 8,
EGL_NONE
};
EGLint w, h, dummy, format;
EGLint numConfigs;
EGLConfig config;
EGLSurface surface;
EGLContext context;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, 0, 0);
/* Here, the application chooses the configuration it desires. In this
* sample, we have a very simplified selection process, where we pick
* the first EGLConfig that matches our criteria */
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
/* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
* guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
* As soon as we picked a EGLConfig, we can safely reconfigure the
* ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format);
surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
const EGLint eglContextAttrs[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
context = eglCreateContext(display, config, NULL, eglContextAttrs);
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
LOGW("Unable to eglMakeCurrent");
return r;
}
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h);
engine->display = display;
engine->context = context;
engine->surface = surface;
engine->width = w;
engine->height = h;
engine->state.angle = 0;
r.w = w;
r.h = h;
return r;
}
/**
* Invoke the dispatching of the next bunch of Runnables in the Java-Land
*/
static bool s_methodInitialized = false;
static void dispatch_pending_runnables() {
static cocos2d::JniMethodInfo info;
if (!s_methodInitialized) {
s_methodInitialized = cocos2d::JniHelper::getStaticMethodInfo(
info,
"org/cocos2dx/lib/Cocos2dxHelper",
"dispatchPendingRunnables",
"()V"
);
if (!s_methodInitialized) {
LOGW("Unable to dispatch pending Runnables!");
return;
}
}
info.env->CallStaticVoidMethod(info.classID, info.methodID);
}
/**
* Just the current frame in the display.
*/
static void engine_draw_frame(struct engine* engine)
{
LOG_RENDER_DEBUG("engine_draw_frame(...)");
pthread_t thisthread = pthread_self();
LOG_RENDER_DEBUG("pthread_self() = %X", thisthread);
if (engine->display == NULL) {
// No display.
LOGW("engine_draw_frame : No display.");
return;
}
dispatch_pending_runnables();
cocos2d::Director::getInstance()->mainLoop();
LOG_RENDER_DEBUG("engine_draw_frame : just called cocos' mainLoop()");
/* // Just fill the screen with a color. */
/* glClearColor(((float)engine->state.x)/engine->width, engine->state.angle, */
/* ((float)engine->state.y)/engine->height, 1); */
/* glClear(GL_COLOR_BUFFER_BIT); */
if (s_pfEditTextCallback && editboxText)
{
s_pfEditTextCallback(editboxText, s_ctx);
free(editboxText);
editboxText = NULL;
}
eglSwapBuffers(engine->display, engine->surface);
}
/**
* Tear down the EGL context currently associated with the display.
*/
static void engine_term_display(struct engine* engine)
{
if (engine->display != EGL_NO_DISPLAY) {
eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (engine->context != EGL_NO_CONTEXT) {
eglDestroyContext(engine->display, engine->context);
}
if (engine->surface != EGL_NO_SURFACE) {
eglDestroySurface(engine->display, engine->surface);
}
eglTerminate(engine->display);
}
engine->animating = 0;
engine->display = EGL_NO_DISPLAY;
engine->context = EGL_NO_CONTEXT;
engine->surface = EGL_NO_SURFACE;
}
/*
* Get X, Y positions and ID's for all pointers
*/
static void getTouchPos(AInputEvent *event, int ids[], float xs[], float ys[]) {
int pointerCount = AMotionEvent_getPointerCount(event);
for(int i = 0; i < pointerCount; ++i) {
ids[i] = AMotionEvent_getPointerId(event, i);
xs[i] = AMotionEvent_getX(event, i);
ys[i] = AMotionEvent_getY(event, i);
}
}
/*
* Handle Touch Inputs
*/
static int32_t handle_touch_input(AInputEvent *event) {
pthread_t thisthread = pthread_self();
LOG_EVENTS_DEBUG("handle_touch_input(%X), pthread_self() = %X", event, thisthread);
switch(AMotionEvent_getAction(event) &
AMOTION_EVENT_ACTION_MASK) {
case AMOTION_EVENT_ACTION_DOWN:
{
LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_DOWN");
int pointerId = AMotionEvent_getPointerId(event, 0);
float xP = AMotionEvent_getX(event,0);
float yP = AMotionEvent_getY(event,0);
LOG_EVENTS_DEBUG("Event: Action DOWN x=%f y=%f pointerID=%d\n",
xP, yP, pointerId);
float x = xP;
float y = yP;
cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, &pointerId, &x, &y);
return 1;
}
break;
case AMOTION_EVENT_ACTION_POINTER_DOWN:
{
LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_POINTER_DOWN");
int pointerIndex = AMotionEvent_getAction(event) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
int pointerId = AMotionEvent_getPointerId(event, pointerIndex);
float xP = AMotionEvent_getX(event,pointerIndex);
float yP = AMotionEvent_getY(event,pointerIndex);
LOG_EVENTS_DEBUG("Event: Action POINTER DOWN x=%f y=%f pointerID=%d\n",
xP, yP, pointerId);
float x = xP;
float y = yP;
cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, &pointerId, &x, &y);
return 1;
}
break;
case AMOTION_EVENT_ACTION_MOVE:
{
LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_MOVE");
int pointerCount = AMotionEvent_getPointerCount(event);
int ids[pointerCount];
float xs[pointerCount], ys[pointerCount];
getTouchPos(event, ids, xs, ys);
cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesMove(pointerCount, ids, xs, ys);
return 1;
}
break;
case AMOTION_EVENT_ACTION_UP:
{
LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_UP");
int pointerId = AMotionEvent_getPointerId(event, 0);
float xP = AMotionEvent_getX(event,0);
float yP = AMotionEvent_getY(event,0);
LOG_EVENTS_DEBUG("Event: Action UP x=%f y=%f pointerID=%d\n",
xP, yP, pointerId);
float x = xP;
float y = yP;
cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesEnd(1, &pointerId, &x, &y);
return 1;
}
break;
case AMOTION_EVENT_ACTION_POINTER_UP:
{
LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_POINTER_UP");
int pointerIndex = AMotionEvent_getAction(event) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
int pointerId = AMotionEvent_getPointerId(event, pointerIndex);
float xP = AMotionEvent_getX(event,pointerIndex);
float yP = AMotionEvent_getY(event,pointerIndex);
LOG_EVENTS_DEBUG("Event: Action POINTER UP x=%f y=%f pointerID=%d\n",
xP, yP, pointerIndex);
float x = xP;
float y = yP;
cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesEnd(1, &pointerId, &x, &y);
return 1;
}
break;
case AMOTION_EVENT_ACTION_CANCEL:
{
LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_CANCEL");
int pointerCount = AMotionEvent_getPointerCount(event);
int ids[pointerCount];
float xs[pointerCount], ys[pointerCount];
getTouchPos(event, ids, xs, ys);
cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesCancel(pointerCount, ids, xs, ys);
return 1;
}
break;
default:
LOG_EVENTS_DEBUG("handle_touch_input() default case.... NOT HANDLE");
return 0;
break;
}
}
/*
* Handle Key Inputs
*/
static int32_t handle_key_input(AInputEvent *event)
{
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_UP)
{
auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher();
switch (AKeyEvent_getKeyCode(event))
{
case AKEYCODE_BACK:
{
cocos2d::EventKeyboard event(cocos2d::EventKeyboard::KeyCode::KEY_BACKSPACE, false);
dispatcher->dispatchEvent(&event);
}
return 1;
case AKEYCODE_MENU:
{
cocos2d::EventKeyboard event(cocos2d::EventKeyboard::KeyCode::KEY_MENU, false);
dispatcher->dispatchEvent(&event);
}
return 1;
default:
break;
}
}
return 0;
}
/**
* Process the next input event.
*/
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {
pthread_t thisthread = pthread_self();
LOG_EVENTS_DEBUG("engine_handle_input(%X, %X), pthread_self() = %X", app, event, thisthread);
struct engine* engine = (struct engine*)app->userData;
if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {
engine->animating = 1;
engine->state.x = AMotionEvent_getX(event, 0);
engine->state.y = AMotionEvent_getY(event, 0);
return handle_touch_input(event);
}
else
return handle_key_input(event);
return 0;
}
void enableAccelerometerJni(void) {
LOGI("enableAccelerometerJni()");
if (engine.accelerometerSensor != NULL) {
ASensorEventQueue_enableSensor(engine.sensorEventQueue,
engine.accelerometerSensor);
// Set a default sample rate
// We'd like to get 60 events per second (in us).
ASensorEventQueue_setEventRate(engine.sensorEventQueue,
engine.accelerometerSensor, (1000L/60)*1000);
}
}
void disableAccelerometerJni(void) {
LOGI("disableAccelerometerJni()");
if (engine.accelerometerSensor != NULL) {
ASensorEventQueue_disableSensor(engine.sensorEventQueue,
engine.accelerometerSensor);
}
}
void setAccelerometerIntervalJni(float interval) {
LOGI("setAccelerometerIntervalJni(%f)", interval);
// We'd like to get 60 events per second (in us).
ASensorEventQueue_setEventRate(engine.sensorEventQueue,
engine.accelerometerSensor, interval * 1000000L);
}
/**
* Process the next main command.
*/
static void engine_handle_cmd(struct android_app* app, int32_t cmd)
{
struct engine* engine = (struct engine*)app->userData;
switch (cmd) {
case APP_CMD_SAVE_STATE:
// The system has asked us to save our current state. Do so.
engine->app->savedState = malloc(sizeof(struct saved_state));
*((struct saved_state*)engine->app->savedState) = engine->state;
engine->app->savedStateSize = sizeof(struct saved_state);
break;
case APP_CMD_INIT_WINDOW:
// The window is being shown, get it ready.
if (engine->app->window != NULL) {
cocos_dimensions d = engine_init_display(engine);
if ((d.w > 0) &&
(d.h > 0)) {
cocos2d::JniHelper::setJavaVM(app->activity->vm);
cocos2d::JniHelper::setClassLoaderFrom(app->activity->clazz);
// call Cocos2dxHelper.init()
cocos2d::JniMethodInfo ccxhelperInit;
if (!cocos2d::JniHelper::getStaticMethodInfo(ccxhelperInit,
"org/cocos2dx/lib/Cocos2dxHelper",
"init",
"(Landroid/app/Activity;)V")) {
LOGI("cocos2d::JniHelper::getStaticMethodInfo(ccxhelperInit) FAILED");
}
ccxhelperInit.env->CallStaticVoidMethod(ccxhelperInit.classID,
ccxhelperInit.methodID,
app->activity->clazz);
cocos_init(d, app);
}
engine->animating = 1;
engine_draw_frame(engine);
}
break;
case APP_CMD_TERM_WINDOW:
// The window is being hidden or closed, clean it up.
engine_term_display(engine);
break;
case APP_CMD_RESUME:
if (cocos2d::Director::getInstance()->getOpenGLView()) {
cocos2d::Application::getInstance()->applicationWillEnterForeground();
if (engine->display != nullptr)
{
engine->animating = 1;
}
}
break;
case APP_CMD_PAUSE:
{
cocos2d::Application::getInstance()->applicationDidEnterBackground();
cocos2d::EventCustom backgroundEvent(EVENT_COME_TO_BACKGROUND);
cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&backgroundEvent);
// Also stop animating.
engine->animating = 0;
engine_draw_frame(engine);
}
break;
}
}
static void onContentRectChanged(ANativeActivity* activity, const ARect* rect) {
timeRectChanged = std::chrono::steady_clock::now();
isContentRectChanged = true;
}
static void process_input(struct android_app* app, struct android_poll_source* source)
{
AInputEvent* event = NULL;
while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
LOGV("New input event: type=%d\n", AInputEvent_getType(event));
if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
continue;
}
int32_t handled = 0;
if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
AInputQueue_finishEvent(app->inputQueue, event, handled);
}
}
/**
* This is the main entry point of a native application that is using
* android_native_app_glue. It runs in its own thread, with its own
* event loop for receiving input events and doing other things.
*/
void android_main(struct android_app* state) {
// Make sure glue isn't stripped.
app_dummy();
memset(&engine, 0, sizeof(engine));
state->userData = &engine;
state->onAppCmd = engine_handle_cmd;
state->onInputEvent = engine_handle_input;
state->inputPollSource.process = process_input;
engine.app = state;
// Prepare to monitor accelerometer
engine.sensorManager = ASensorManager_getInstance();
engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager,
ASENSOR_TYPE_ACCELEROMETER);
engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager,
state->looper, LOOPER_ID_USER, NULL, NULL);
if (state->savedState != NULL) {
// We are starting with a previous saved state; restore from it.
engine.state = *(struct saved_state*)state->savedState;
}
// Screen size change support
state->activity->callbacks->onContentRectChanged = onContentRectChanged;
// loop waiting for stuff to do.
while (1) {
// Read all pending events.
int ident;
int events;
struct android_poll_source* source;
// If not animating, we will block forever waiting for events.
// If animating, we loop until all events are read, then continue
// to draw the next frame of animation.
while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events,
(void**)&source)) >= 0) {
// Process this event.
if (source != NULL) {
source->process(state, source);
}
// If a sensor has data, process it now.
if (ident == LOOPER_ID_USER) {
if (engine.accelerometerSensor != NULL) {
ASensorEvent event;
while (ASensorEventQueue_getEvents(engine.sensorEventQueue,
&event, 1) > 0) {
LOG_EVENTS_DEBUG("accelerometer: x=%f y=%f z=%f",
event.acceleration.x, event.acceleration.y,
event.acceleration.z);
AConfiguration* _currentconf = AConfiguration_new();
AConfiguration_fromAssetManager(_currentconf,
state->activity->assetManager);
static int32_t _orientation = AConfiguration_getOrientation(_currentconf);
if (ACONFIGURATION_ORIENTATION_LAND != _orientation) {
// ACONFIGURATION_ORIENTATION_ANY
// ACONFIGURATION_ORIENTATION_PORT
// ACONFIGURATION_ORIENTATION_SQUARE
cocos2d::Acceleration acc;
acc.x = -event.acceleration.x/10;
acc.y = -event.acceleration.y/10;
acc.z = event.acceleration.z/10;
acc.timestamp = 0;
cocos2d::EventAcceleration accEvent(acc);
auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher();
dispatcher->dispatchEvent(&accEvent);
} else {
// ACONFIGURATION_ORIENTATION_LAND
// swap x and y parameters
cocos2d::Acceleration acc;
acc.x = event.acceleration.y/10;
acc.y = -event.acceleration.x/10;
acc.z = event.acceleration.z/10;
acc.timestamp = 0;
cocos2d::EventAcceleration accEvent(acc);
auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher();
dispatcher->dispatchEvent(&accEvent);
}
}
}
}
// Check if we are exiting.
if (state->destroyRequested != 0) {
engine_term_display(&engine);
memset(&engine, 0, sizeof(engine));
s_methodInitialized = false;
return;
}
}
if (engine.animating) {
// Done with events; draw next animation frame.
engine.state.angle += .01f;
if (engine.state.angle > 1) {
engine.state.angle = 0;
}
// Drawing is throttled to the screen update rate, so there
// is no need to do timing here.
LOG_RENDER_DEBUG("android_main : engine.animating");
engine_draw_frame(&engine);
} else {
LOG_RENDER_DEBUG("android_main : !engine.animating");
}
// Check if screen size changed
if (isContentRectChanged) {
std::chrono::duration<int, std::milli> duration(
std::chrono::duration_cast<std::chrono::duration<int, std::milli>>(std::chrono::steady_clock::now() - timeRectChanged));
// Wait about 30 ms to get new width and height. Without waiting we can get old values sometime
if (duration.count() > 30) {
isContentRectChanged = false;
int32_t newWidth = ANativeWindow_getWidth(engine.app->window);
int32_t newHeight = ANativeWindow_getHeight(engine.app->window);
cocos2d::Application::getInstance()->applicationScreenSizeChanged(newWidth, newHeight);
}
}
}
}
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID

View File

@ -8,18 +8,18 @@
<uses-feature android:glEsVersion="0x00020000" />
<application android:label="@string/app_name"
android:icon="@drawable/icon">
android:icon="@drawable/icon">
<activity android:name="org.cocos2dx.cpp_empty_test.Cocos2dxActivity"
<!-- Tell Cocos2dxActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="cpp_empty_test" />
<activity android:name=".AppActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:configChanges="orientation">
<!-- Tell NativeActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="cpp_empty_test" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

View File

@ -10,7 +10,7 @@
using namespace cocos2d;
void cocos_android_app_init (struct android_app* app) {
void cocos_android_app_init (JNIEnv* env, jobject thiz) {
LOGD("cocos_android_app_init");
AppDelegate *pAppDelegate = new AppDelegate();
}

View File

@ -1,5 +1,5 @@
/****************************************************************************
Copyright (c) 2013-2014 Chukong Technologies Inc.
Copyright (c) 2010-2012 cocos2d-x.org
http://www.cocos2d-x.org
@ -21,20 +21,9 @@ 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.
****************************************************************************/
#ifndef __COCOSNATIVEACTIVITY_H__
#define __COCOSNATIVEACTIVITY_H__
package org.cocos2dx.cpp_empty_test;
#include "CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
import org.cocos2dx.lib.Cocos2dxActivity;
/**
* This is the interface to the Android native activity
*/
void enableAccelerometerJni(void);
void disableAccelerometerJni(void);
void setAccelerometerIntervalJni(float interval);
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#endif // __COCOSNATIVEACTIVITY_H__
public class AppActivity extends Cocos2dxActivity {
}

View File

@ -1,32 +0,0 @@
package org.cocos2dx.cpp_empty_test;
import android.app.NativeActivity;
import android.os.Bundle;
public class Cocos2dxActivity extends NativeActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//For supports translucency
//1.change "attribs" in cocos\2d\platform\android\nativeactivity.cpp
/*const EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
//EGL_BLUE_SIZE, 5, -->delete
//EGL_GREEN_SIZE, 6, -->delete
//EGL_RED_SIZE, 5, -->delete
EGL_BUFFER_SIZE, 32, //-->new field
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, 8,
EGL_NONE
};*/
//2.Set the format of window
// getWindow().setFormat(PixelFormat.TRANSLUCENT);
}
}

View File

@ -9,18 +9,18 @@
<uses-feature android:glEsVersion="0x00020000" />
<application android:label="@string/app_name"
android:icon="@drawable/icon">
android:icon="@drawable/icon">
<activity android:name=".Cocos2dxActivity"
<!-- Tell Cocos2dxActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="cpp_tests" />
<activity android:name=".AppActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:configChanges="orientation">
<!-- Tell NativeActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="cpp_tests" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

View File

@ -10,7 +10,7 @@
using namespace cocos2d;
void cocos_android_app_init (struct android_app* app) {
void cocos_android_app_init (JNIEnv* env, jobject thiz) {
LOGD("cocos_android_app_init");
AppDelegate *pAppDelegate = new AppDelegate();
}

View File

@ -0,0 +1,29 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
http://www.cocos2d-x.org
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.
****************************************************************************/
package org.cocos2dx.cpp_tests;
import org.cocos2dx.lib.Cocos2dxActivity;
public class AppActivity extends Cocos2dxActivity {
}

View File

@ -1,32 +0,0 @@
package org.cocos2dx.cpp_tests;
import android.app.NativeActivity;
import android.os.Bundle;
public class Cocos2dxActivity extends NativeActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//For supports translucency
//1.change "attribs" in cocos\2d\platform\android\nativeactivity.cpp
/*const EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
//EGL_BLUE_SIZE, 5, -->delete
//EGL_GREEN_SIZE, 6, -->delete
//EGL_RED_SIZE, 5, -->delete
EGL_BUFFER_SIZE, 32, //-->new field
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, 8,
EGL_NONE
};*/
//2.Set the format of window
// getWindow().setFormat(PixelFormat.TRANSLUCENT);
}
}