Merge branch 'develop' of https://github.com/cocos2d/cocos2d-x into cocos-console-test

This commit is contained in:
shujunqiao 2014-03-27 10:56:29 +08:00
commit d38f873ecc
311 changed files with 6564 additions and 3988 deletions

10
AUTHORS
View File

@ -548,6 +548,7 @@ Developers:
hannon235 (Chris)
Fixing a bug that the submenu of ExtensionTest in TestCpp can't scroll.
Implements a socket.io client extension and adds a test case.
Implements 'SIODelegate::fireEventToScript' method to integrate JSB event handling with the original native code.
pktangyue
Fixing a bug that CCScale9Sprite::setInsetLeft/XXX can't work for rotated sprite frame.
@ -787,6 +788,15 @@ Developers:
youknowone
Adds iOS-like elastic bounceback support for cocos2d::extension::ScrollView
aeonmine
Fixed ActionObject memory leak in ActionManagerEx::initWithDictionary
LoungeKatt
Corrected a mistake of building android project in README.md
flashjay
Remove deprecated code in lua tests & template
Retired Core Developers:
WenSheng Yang
Author of windows port, CCTextField,

View File

@ -1 +1 @@
e1d0a713b9c239ae437f21ab7c256413cebf3241
24725aaaf53bbf506d1ea378c6af1d9ff1e61c12

View File

@ -36,7 +36,7 @@ Example:
### Build and run new project for android ###
$ cocos run -p -j 4 android
$ cocos run -p android -j 4
### Build and run new project for iOS ###

View File

@ -1 +1 @@
68ac83318dc8df5fee3badc4eb3f0e75ee0a9ce0
bdcba92fe68d80bd996d1c61e15ea07397895549

View File

@ -159,6 +159,19 @@ Sequence* Sequence::createWithTwoActions(FiniteTimeAction *actionOne, FiniteTime
return sequence;
}
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
Sequence* Sequence::variadicCreate(FiniteTimeAction *action1, ...)
{
va_list params;
va_start(params, action1);
Sequence *ret = Sequence::createWithVariableList(action1, params);
va_end(params);
return ret;
}
#else
Sequence* Sequence::create(FiniteTimeAction *action1, ...)
{
va_list params;
@ -170,6 +183,7 @@ Sequence* Sequence::create(FiniteTimeAction *action1, ...)
return ret;
}
#endif
Sequence* Sequence::createWithVariableList(FiniteTimeAction *action1, va_list args)
{
@ -532,6 +546,19 @@ RepeatForever *RepeatForever::reverse() const
// Spawn
//
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
Spawn* Spawn::variadicCreate(FiniteTimeAction *action1, ...)
{
va_list params;
va_start(params, action1);
Spawn *ret = Spawn::createWithVariableList(action1, params);
va_end(params);
return ret;
}
#else
Spawn* Spawn::create(FiniteTimeAction *action1, ...)
{
va_list params;
@ -543,6 +570,7 @@ Spawn* Spawn::create(FiniteTimeAction *action1, ...)
return ret;
}
#endif
Spawn* Spawn::createWithVariableList(FiniteTimeAction *action1, va_list args)
{

View File

@ -93,7 +93,26 @@ class CC_DLL Sequence : public ActionInterval
{
public:
/** helper constructor to create an array of sequenceable actions */
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
// WP8 in VS2012 does not support nullptr in variable args lists and variadic templates are also not supported
typedef FiniteTimeAction* M;
static Sequence* create(M m1, std::nullptr_t listEnd) { return variadicCreate(m1, NULL); }
static Sequence* create(M m1, M m2, std::nullptr_t listEnd) { return variadicCreate(m1, m2, NULL); }
static Sequence* create(M m1, M m2, M m3, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, M m5, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, m9, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, M m10, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, NULL); }
// On WP8 for variable argument lists longer than 10 items, use the other create functions or variadicCreate with NULL as the last argument
static Sequence* variadicCreate(FiniteTimeAction* item, ...);
#else
static Sequence* create(FiniteTimeAction *action1, ...) CC_REQUIRES_NULL_TERMINATION;
#endif
/** helper constructor to create an array of sequenceable actions given an array
* @code
* When this funtion bound to the js or lua,the input params changed
@ -248,7 +267,25 @@ public:
* in lua :local create(local object1,local object2, ...)
* @endcode
*/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
// WP8 in VS2012 does not support nullptr in variable args lists and variadic templates are also not supported
typedef FiniteTimeAction* M;
static Spawn* create(M m1, std::nullptr_t listEnd) { return variadicCreate(m1, NULL); }
static Spawn* create(M m1, M m2, std::nullptr_t listEnd) { return variadicCreate(m1, m2, NULL); }
static Spawn* create(M m1, M m2, M m3, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, NULL); }
static Spawn* create(M m1, M m2, M m3, M m4, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, NULL); }
static Spawn* create(M m1, M m2, M m3, M m4, M m5, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, NULL); }
static Spawn* create(M m1, M m2, M m3, M m4, M m5, M m6, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, NULL); }
static Spawn* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, NULL); }
static Spawn* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, NULL); }
static Spawn* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, m9, NULL); }
static Spawn* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, M m10, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, NULL); }
// On WP8 for variable argument lists longer than 10 items, use the other create functions or createSpawn with NULL as the last argument
static Spawn* variadicCreate(FiniteTimeAction* item, ...);
#else
static Spawn* create(FiniteTimeAction *action1, ...) CC_REQUIRES_NULL_TERMINATION;
#endif
/** helper constructor to create an array of spawned actions */
static Spawn* createWithVariableList(FiniteTimeAction *action1, va_list args);

View File

@ -23,6 +23,7 @@ THE SOFTWARE.
****************************************************************************/
#include "CCComponent.h"
#include "CCScriptSupport.h"
NS_CC_BEGIN
@ -31,6 +32,10 @@ Component::Component(void)
: _owner(nullptr)
, _enabled(true)
{
#if CC_ENABLE_SCRIPT_BINDING
ScriptEngineProtocol* engine = ScriptEngineManager::getInstance()->getScriptEngine();
_scriptType = engine != nullptr ? engine->getScriptType() : kScriptTypeNone;
#endif
}
Component::~Component(void)
@ -42,16 +47,60 @@ bool Component::init()
return true;
}
#if CC_ENABLE_SCRIPT_BINDING
static bool sendComponentEventToJS(Component* node, int action)
{
auto scriptEngine = ScriptEngineManager::getInstance()->getScriptEngine();
if (scriptEngine->isCalledFromScript())
{
scriptEngine->setCalledFromScript(false);
}
else
{
BasicScriptData data(node,(void*)&action);
ScriptEvent scriptEvent(kComponentEvent,(void*)&data);
if (scriptEngine->sendEvent(&scriptEvent))
return true;
}
return false;
}
#endif
void Component::onEnter()
{
#if CC_ENABLE_SCRIPT_BINDING
if (_scriptType == kScriptTypeJavascript)
{
if (sendComponentEventToJS(this, kComponentOnEnter))
return;
}
#endif
}
void Component::onExit()
{
#if CC_ENABLE_SCRIPT_BINDING
if (_scriptType == kScriptTypeJavascript)
{
if (sendComponentEventToJS(this, kComponentOnExit))
return;
}
#endif
}
void Component::update(float delta)
{
#if CC_ENABLE_SCRIPT_BINDING
if (_scriptType == kScriptTypeJavascript)
{
if (sendComponentEventToJS(this, kComponentOnUpdate))
return;
}
#endif
}
bool Component::serialize(void *ar)

View File

@ -26,15 +26,22 @@ THE SOFTWARE.
#define __CC_FRAMEWORK_COMPONENT_H__
#include "CCRef.h"
#include "CCScriptSupport.h"
#include <string>
NS_CC_BEGIN
class Node;
enum {
kComponentOnEnter,
kComponentOnExit,
kComponentOnUpdate
};
class CC_DLL Component : public Ref
{
protected:
CC_CONSTRUCTOR_ACCESS:
/**
* @js ctor
*/
@ -46,15 +53,8 @@ public:
*/
virtual ~Component(void);
virtual bool init();
/**
* @js NA
* @lua NA
*/
virtual void onEnter();
/**
* @js NA
* @lua NA
*/
virtual void onExit();
virtual void update(float delta);
virtual bool serialize(void* r);
@ -72,6 +72,10 @@ protected:
Node *_owner;
std::string _name;
bool _enabled;
#if CC_ENABLE_SCRIPT_BINDING
ccScriptType _scriptType; ///< type of script binding, lua or javascript
#endif
};
NS_CC_END

View File

@ -61,7 +61,6 @@ bool ComponentContainer::add(Component *com)
if (_components == nullptr)
{
_components = new Map<std::string, Component*>();
_owner->scheduleUpdate();
}
Component *component = _components->at(com->getName());

View File

@ -963,6 +963,8 @@ CC_DEPRECATED_ATTRIBUTE const Application::Platform kTargetBlackBerry = Applic
CC_DEPRECATED_ATTRIBUTE const Application::Platform kTargetNaCl = Application::Platform::OS_NACL;
CC_DEPRECATED_ATTRIBUTE const Application::Platform kTargetEmscripten = Application::Platform::OS_EMSCRIPTEN;
CC_DEPRECATED_ATTRIBUTE const Application::Platform kTargetTizen = Application::Platform::OS_TIZEN;
CC_DEPRECATED_ATTRIBUTE const Application::Platform kTargetWinRT = Application::Platform::OS_WINRT;
CC_DEPRECATED_ATTRIBUTE const Application::Platform kTargetWP8 = Application::Platform::OS_WP8;
CC_DEPRECATED_ATTRIBUTE typedef Application::Platform TargetPlatform;
CC_DEPRECATED_ATTRIBUTE const ResolutionPolicy kResolutionExactFit = ResolutionPolicy::EXACT_FIT;

View File

@ -45,6 +45,7 @@ THE SOFTWARE.
#include "platform/CCFileUtils.h"
#include "CCApplication.h"
#include "CCFontFNT.h"
#include "CCFontAtlasCache.h"
#include "CCActionManager.h"
#include "CCAnimationCache.h"
#include "CCTouch.h"
@ -157,8 +158,10 @@ bool Director::init(void)
initTextureCache();
_renderer = new Renderer;
_console = new Console;
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
_console = new Console;
#endif
return true;
}
@ -182,7 +185,10 @@ Director::~Director(void)
delete _eventProjectionChanged;
delete _renderer;
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
delete _console;
#endif
// clean auto release pool
PoolManager::destroyInstance();
@ -432,6 +438,12 @@ void Director::setProjection(Projection projection)
case Projection::_2D:
kmGLMatrixMode(KM_GL_PROJECTION);
kmGLLoadIdentity();
#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
if(getOpenGLView() != nullptr)
{
kmGLMultMatrix( getOpenGLView()->getOrientationMatrix());
}
#endif
kmMat4 orthoMatrix;
kmMat4OrthographicProjection(&orthoMatrix, 0, size.width, 0, size.height, -1024, 1024);
kmGLMultMatrix(&orthoMatrix);
@ -448,6 +460,14 @@ void Director::setProjection(Projection projection)
kmGLMatrixMode(KM_GL_PROJECTION);
kmGLLoadIdentity();
#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
//if needed, we need to add a rotation for Landscape orientations on Windows Phone 8 since it is always in Portrait Mode
GLView* view = getOpenGLView();
if(getOpenGLView() != nullptr)
{
kmGLMultMatrix(getOpenGLView()->getOrientationMatrix());
}
#endif
// issue #1334
kmMat4PerspectiveProjection(&matrixPerspective, 60, (GLfloat)size.width/size.height, 10, zeye+size.height/2);
// kmMat4PerspectiveProjection( &matrixPerspective, 60, (GLfloat)size.width/size.height, 0.1f, 1500);
@ -485,10 +505,16 @@ void Director::setProjection(Projection projection)
void Director::purgeCachedData(void)
{
FontFNT::purgeCachedData();
FontAtlasCache::purgeCachedData();
if (s_SharedDirector->getOpenGLView())
{
SpriteFrameCache::getInstance()->removeUnusedSpriteFrames();
_textureCache->removeUnusedTextures();
// Note: some tests such as ActionsTest are leaking refcounted textures
// There should be no test textures left in the cache
log("%s\n", _textureCache->getCachedTextureInfo().c_str());
}
FileUtils::getInstance()->purgeCachedEntries();
}
@ -533,6 +559,11 @@ static void GLToClipTransform(kmMat4 *transformOut)
kmMat4 projection;
kmGLGetMatrix(KM_GL_PROJECTION, &projection);
#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
//if needed, we need to undo the rotation for Landscape orientation in order to get the correct positions
kmMat4Multiply(&projection, Director::getInstance()->getOpenGLView()->getReverseOrientationMatrix(), &projection);
#endif
kmMat4 modelview;
kmGLGetMatrix(KM_GL_MODELVIEW, &modelview);

View File

@ -59,7 +59,10 @@ class EventCustom;
class EventListenerCustom;
class TextureCache;
class Renderer;
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
class Console;
#endif
/**
@brief Class that creates and handles the main Window and manages how
@ -368,7 +371,9 @@ public:
/** Returns the Console
@since v3.0
*/
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
Console* getConsole() const { return _console; }
#endif
/* Gets delta time since last tick to main loop */
float getDeltaTime() const;
@ -477,8 +482,10 @@ protected:
/* Renderer for the Director */
Renderer *_renderer;
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
/* Console for the director */
Console *_console;
#endif
// GLViewProtocol will recreate stats labels to fit visible rect
friend class GLViewProtocol;

View File

@ -94,11 +94,12 @@ public:
// Overrides
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
protected:
CC_CONSTRUCTOR_ACCESS:
DrawNode();
virtual ~DrawNode();
virtual bool init();
protected:
void ensureCapacity(int count);
GLuint _vao;

View File

@ -590,7 +590,7 @@ void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, c
// priority < 0
if (fixedPriorityListeners)
{
CCASSERT(listeners->getGt0Index() <= fixedPriorityListeners->size(), "Out of range exception!");
CCASSERT(listeners->getGt0Index() <= static_cast<ssize_t>(fixedPriorityListeners->size()), "Out of range exception!");
if (!fixedPriorityListeners->empty())
{

View File

@ -185,7 +185,9 @@ void FontAtlas::listenToForeground(EventCustom *event)
auto contentSize = Size(CacheTextureWidth,CacheTextureHeight);
auto pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8;
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
// this is a memory leak as the texture previously in _atlasTextures[_currentPage] is not deleted from OpenGL
// see CCTexture2D::initWithData for the temporary fix
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
}
}
#endif
@ -231,6 +233,8 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
auto pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8;
bool existNewLetter = false;
int bottomHeight = _commonLineHeight - _fontAscender;
for (int i = 0; i < length; ++i)
{
auto outIterator = _fontLetterDefinitions.find(utf16String[i]);
@ -248,6 +252,7 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
tempDef.height = tempRect.size.height + _letterPadding;
tempDef.offsetX = tempRect.origin.x + offsetAdjust;
tempDef.offsetY = _fontAscender + tempRect.origin.y - offsetAdjust;
tempDef.clipBottom = bottomHeight - (tempDef.height + tempRect.origin.y + offsetAdjust);
if (_currentPageOrigX + tempDef.width > CacheTextureWidth)
{
@ -255,7 +260,9 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
_currentPageOrigX = 0;
if(_currentPageOrigY + _commonLineHeight >= CacheTextureHeight)
{
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
// this is a memory leak as the texture previously in _atlasTextures[_currentPage] is not deleted from OpenGL
// see CCTexture2D::initWithData for the temporary fix
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
_currentPageOrigY = 0;
memset(_currentPageData, 0, _currentPageDataSize);
_currentPage++;
@ -290,6 +297,7 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
tempDef.offsetX = 0;
tempDef.offsetY = 0;
tempDef.textureID = 0;
tempDef.clipBottom = 0;
_currentPageOrigX += 1;
}
@ -299,6 +307,8 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
if(existNewLetter)
{
// this is a memory leak as the texture previously in _atlasTextures[_currentPage] is not deleted from OpenGL
// see CCTexture2D::initWithData for the temporary fix
_atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
}
return true;

View File

@ -50,6 +50,8 @@ struct FontLetterDefinition
int textureID;
bool validDefinition;
int xAdvance;
int clipBottom;
};
class CC_DLL FontAtlas : public Ref

View File

@ -52,9 +52,11 @@ FontAtlas * FontAtlasCache::getFontAtlasTTF(const TTFConfig & config)
useDistanceField = false;
}
int fontSize = config.fontSize;
auto contentScaleFactor = CC_CONTENT_SCALE_FACTOR();
if (useDistanceField)
{
fontSize = Label::DistanceFieldFontSize / CC_CONTENT_SCALE_FACTOR();
fontSize = Label::DistanceFieldFontSize / contentScaleFactor;
}
std::string atlasName = generateFontName(config.fontFilePath, fontSize, GlyphCollection::DYNAMIC, useDistanceField);
@ -67,7 +69,8 @@ FontAtlas * FontAtlasCache::getFontAtlasTTF(const TTFConfig & config)
if ( !tempAtlas )
{
FontFreeType *font = FontFreeType::create(config.fontFilePath, fontSize * CC_CONTENT_SCALE_FACTOR(), config.glyphs, config.customGlyphs,useDistanceField,config.outlineSize);
FontFreeType *font = FontFreeType::create(config.fontFilePath, fontSize * contentScaleFactor, config.glyphs,
config.customGlyphs,useDistanceField,config.outlineSize * contentScaleFactor);
if (font)
{
tempAtlas = font->createFontAtlas();

View File

@ -388,7 +388,7 @@ unsigned char * makeDistanceMap( unsigned char *img, long width, long height)
double * data = (double *) calloc( pixelAmount, sizeof(double) );
double * outside = (double *) calloc( pixelAmount, sizeof(double) );
double * inside = (double *) calloc( pixelAmount, sizeof(double) );
unsigned int i,j;
long i,j;
// Convert img into double (data) rescale image levels between 0 and 1
long outWidth = width + 2 * FontFreeType::DistanceMapSpread;

View File

@ -26,15 +26,29 @@
#ifndef _FontFreetype_h_
#define _FontFreetype_h_
#include "CCFont.h"
#include "CCData.h"
#include <string>
#include <ft2build.h>
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
#define generic GenericFromFreeTypeLibrary
#define internal InternalFromFreeTypeLibrary
#endif
#include FT_FREETYPE_H
#include FT_STROKER_H
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
#undef generic
#undef internal
#endif
NS_CC_BEGIN
class CC_DLL FontFreeType : public Font

View File

@ -37,6 +37,10 @@ THE SOFTWARE.
#include "kazmath/GL/matrix.h"
#include "kazmath/kazmath.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
#include "CCPrecompiledShaders.h"
#endif
NS_CC_BEGIN
typedef struct _hashUniformEntry
@ -116,6 +120,18 @@ GLProgram::~GLProgram()
bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
GLboolean hasCompiler = false;
glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler);
_hasShaderCompiler = (hasCompiler == GL_TRUE);
if(!_hasShaderCompiler)
{
return initWithPrecompiledProgramByteArray(vShaderByteArray,fShaderByteArray);
}
#endif
_program = glCreateProgram();
CHECK_GL_ERROR_DEBUG();
@ -126,7 +142,8 @@ bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar*
if (!compileShader(&_vertShader, GL_VERTEX_SHADER, vShaderByteArray))
{
CCLOG("cocos2d: ERROR: Failed to compile vertex shader");
}
return false;
}
}
// Create and compile fragment shader
@ -135,6 +152,7 @@ bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar*
if (!compileShader(&_fragShader, GL_FRAGMENT_SHADER, fShaderByteArray))
{
CCLOG("cocos2d: ERROR: Failed to compile fragment shader");
return false;
}
}
@ -152,9 +170,34 @@ bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar*
CHECK_GL_ERROR_DEBUG();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
_shaderId = CCPrecompiledShaders::getInstance()->addShaders(vShaderByteArray, fShaderByteArray);
#endif
return true;
}
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
bool GLProgram::initWithPrecompiledProgramByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{
bool haveProgram = false;
_program = glCreateProgram();
CHECK_GL_ERROR_DEBUG();
_vertShader = _fragShader = 0;
haveProgram = CCPrecompiledShaders::getInstance()->loadProgram(_program, vShaderByteArray, fShaderByteArray);
CHECK_GL_ERROR_DEBUG();
_hashForUniforms = NULL;
CHECK_GL_ERROR_DEBUG();
return haveProgram;
}
#endif
bool GLProgram::initWithFilenames(const std::string &vShaderFilename, const std::string &fShaderFilename)
{
auto fileUtils = FileUtils::getInstance();
@ -275,6 +318,15 @@ bool GLProgram::link()
{
CCASSERT(_program != 0, "Cannot link invalid program");
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
if(!_hasShaderCompiler)
{
// precompiled shader program is already linked
return true;
}
#endif
GLint status = GL_TRUE;
glLinkProgram(_program);
@ -291,7 +343,7 @@ bool GLProgram::link()
_vertShader = _fragShader = 0;
#if COCOS2D_DEBUG
#if DEBUG || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
glGetProgramiv(_program, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
@ -302,6 +354,13 @@ bool GLProgram::link()
}
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
if (status == GL_TRUE)
{
CCPrecompiledShaders::getInstance()->addProgram(_program, _shaderId);
}
#endif
return (status == GL_TRUE);
}

View File

@ -126,7 +126,18 @@ public:
* @js initWithString
* @lua initWithString
*/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
/** Initializes the CCGLProgram with precompiled shader program */
bool initWithPrecompiledProgramByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray);
#endif
/** Initializes the GLProgram with a vertex and fragment with bytes array
* @js initWithString
* @lua initWithString
*/
bool initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray);
/** Initializes the GLProgram with a vertex and fragment with contents of filenames
* @js init
* @lua init
@ -266,6 +277,10 @@ private:
GLuint _fragShader;
GLint _uniforms[UNIFORM_MAX];
struct _hashUniformEntry* _hashForUniforms;
bool _hasShaderCompiler;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
std::string _shaderId;
#endif
struct flag_struct {
unsigned int usesTime:1;

View File

@ -279,6 +279,7 @@ Label::Label(FontAtlas *atlas /* = nullptr */, TextHAlignment hAlignment /* = Te
, _textSprite(nullptr)
, _contentDirty(false)
{
setAnchorPoint(Point::ANCHOR_MIDDLE);
reset();
#if CC_ENABLE_CACHE_TEXTURE_DATA
@ -333,12 +334,16 @@ void Label::reset()
Node::removeAllChildrenWithCleanup(true);
_textSprite = nullptr;
_shadowNode = nullptr;
CC_SAFE_RELEASE_NULL(_reusedLetter);
_textColor = Color4B::WHITE;
_textColorF = Color4F::WHITE;
setColor(Color3B::WHITE);
_shadowEnabled = false;
_clipEnabled = false;
}
void Label::updateShaderProgram()
@ -346,7 +351,6 @@ void Label::updateShaderProgram()
switch (_currLabelEffect)
{
case cocos2d::LabelEffect::NORMAL:
case cocos2d::LabelEffect::SHADOW:
if (_useDistanceField)
setShaderProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_NORMAL));
else if (_useA8Shader)
@ -477,6 +481,13 @@ void Label::setFontDefinition(const FontDefinition& textDefinition)
_fontDefinition = textDefinition;
_fontName = textDefinition._fontName;
_fontSize = textDefinition._fontSize;
_shadowEnabled = textDefinition._shadow._shadowEnabled;
if (_shadowEnabled)
{
enableShadow(Color4B::BLACK,_fontDefinition._shadow._shadowOffset,_fontDefinition._shadow._shadowBlur);
}
_textColor = Color4B(_fontDefinition._fontFillColor);
_textColorF.r = _textColor.r / 255.0f;
_textColorF.g = _textColor.g / 255.0f;
@ -831,22 +842,31 @@ void Label::enableOutline(const Color4B& outlineColor,int outlineSize /* = -1 */
void Label::enableShadow(const Color4B& shadowColor /* = Color4B::BLACK */,const Size &offset /* = Size(2 ,-2)*/, int blurRadius /* = 0 */)
{
_shadowEnabled = true;
_fontDefinition._shadow._shadowEnabled = false;
_effectColor = shadowColor;
_effectColorF.r = _effectColor.r / 255.0f;
_effectColorF.g = _effectColor.g / 255.0f;
_effectColorF.b = _effectColor.b / 255.0f;
_effectColorF.a = _effectColor.a / 255.0f;
_shadowOffset = offset;
_shadowColor.r = _effectColor.r;
_shadowColor.g = _effectColor.g;
_shadowColor.b = _effectColor.b;
auto contentScaleFactor = CC_CONTENT_SCALE_FACTOR();
_shadowOffset.width = offset.width * contentScaleFactor;
_shadowOffset.height = offset.height * contentScaleFactor;
//todo:support blur for shadow
_shadowBlurRadius = 0;
_currLabelEffect = LabelEffect::SHADOW;
_fontDefinition._shadow._shadowEnabled = true;
_fontDefinition._shadow._shadowBlur = blurRadius;
_fontDefinition._shadow._shadowOffset = offset;
_fontDefinition._shadow._shadowOpacity = shadowColor.a / 255.0f;
_contentDirty = true;
if (_textSprite && _shadowNode)
{
_shadowNode->setColor(_shadowColor);
_shadowNode->setOpacity(_effectColorF.a * _displayedOpacity);
_shadowNode->setPosition(_shadowOffset.width, _shadowOffset.height);
}
}
void Label::disableEffect()
@ -859,6 +879,12 @@ void Label::disableEffect()
_currLabelEffect = LabelEffect::NORMAL;
updateShaderProgram();
_contentDirty = true;
_shadowEnabled = false;
if (_shadowNode)
{
Node::removeChild(_shadowNode,true);
_shadowNode = nullptr;
}
}
void Label::setFontScale(float fontScale)
@ -881,25 +907,26 @@ void Label::onDraw(const kmMat4& transform, bool transformUpdated)
GL::blendFunc( _blendFunc.src, _blendFunc.dst );
bool trans = false;
if (_currLabelEffect == LabelEffect::OUTLINE || _currLabelEffect == LabelEffect::GLOW)
{
_shaderProgram->setUniformLocationWith4f(_uniformEffectColor,
_effectColorF.r,_effectColorF.g,_effectColorF.b,_effectColorF.a);
}
else if(_currLabelEffect == LabelEffect::SHADOW && _shadowBlurRadius <= 0)
{
trans = true;
drawShadowWithoutBlur();
}
_shaderProgram->setUniformsForBuiltins(transform);
if (_currentLabelType == LabelType::TTF)
{
_shaderProgram->setUniformLocationWith4f(_uniformTextColor,
_textColorF.r,_textColorF.g,_textColorF.b,_textColorF.a);
}
if (_currLabelEffect == LabelEffect::OUTLINE || _currLabelEffect == LabelEffect::GLOW)
{
_shaderProgram->setUniformLocationWith4f(_uniformEffectColor,
_effectColorF.r,_effectColorF.g,_effectColorF.b,_effectColorF.a);
}
else if(_shadowEnabled && _shadowBlurRadius <= 0)
{
trans = true;
kmGLPushMatrix();
drawShadowWithoutBlur();
}
_shaderProgram->setUniformsForBuiltins(transform);
for(const auto &child: _children)
{
if(child->getTag() >= 0)
@ -927,19 +954,10 @@ void Label::drawShadowWithoutBlur()
Color3B oldColor = _realColor;
GLubyte oldOPacity = _displayedOpacity;
if (_currentLabelType == LabelType::TTF)
{
_shaderProgram->setUniformLocationWith4f(_uniformTextColor,
_effectColorF.r,_effectColorF.g,_effectColorF.b,_effectColorF.a);
}
else
{
_displayedOpacity = _effectColorF.a * _displayedOpacity;
setColor(Color3B(_effectColor));
}
_displayedOpacity = _effectColorF.a * _displayedOpacity;
setColor(_shadowColor);
_modelViewTransform = transform(_parentTransform);
kmGLPushMatrix();
kmGLLoadMatrix(&_modelViewTransform);
_shaderProgram->setUniformsForBuiltins(_modelViewTransform);
@ -956,11 +974,9 @@ void Label::drawShadowWithoutBlur()
_position.y -= _shadowOffset.height;
_transformDirty = _inverseDirty = true;
if (_currentLabelType != LabelType::TTF)
{
_displayedOpacity = oldOPacity;
setColor(oldColor);
}
_displayedOpacity = oldOPacity;
setColor(oldColor);
_modelViewTransform = transform(_parentTransform);
kmGLLoadMatrix(&_modelViewTransform);
}
@ -1005,6 +1021,11 @@ void Label::updateContent()
{
Node::removeChild(_textSprite,true);
_textSprite = nullptr;
if (_shadowNode)
{
Node::removeChild(_shadowNode,true);
_shadowNode = nullptr;
}
}
if (_fontAtlas)
{
@ -1035,6 +1056,40 @@ void Label::updateFont()
_fontDirty = false;
}
void Label::drawTextSprite(Renderer *renderer, bool parentTransformUpdated)
{
if (_fontDefinition._fontFillColor != _textColor)
{
Node::removeChild(_textSprite,true);
_textSprite = nullptr;
if (_shadowNode)
{
Node::removeChild(_shadowNode,true);
_shadowNode = nullptr;
}
_fontDefinition._fontFillColor.r = _textColor.r;
_fontDefinition._fontFillColor.g = _textColor.g;
_fontDefinition._fontFillColor.b = _textColor.b;
createSpriteWithFontDefinition();
}
if (_shadowEnabled && _shadowNode == nullptr)
{
_shadowNode = Sprite::createWithTexture(_textSprite->getTexture());
_shadowNode->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
_shadowNode->setColor(_shadowColor);
_shadowNode->setOpacity(_effectColorF.a * _displayedOpacity);
_shadowNode->setPosition(_shadowOffset.width, _shadowOffset.height);
Node::addChild(_shadowNode,0,Node::INVALID_TAG);
}
if (_shadowNode)
{
_shadowNode->visit(renderer, _modelViewTransform, parentTransformUpdated);
}
_textSprite->visit(renderer, _modelViewTransform, parentTransformUpdated);
}
void Label::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
if (! _visible || _originalUTF8String.empty())
@ -1050,7 +1105,7 @@ void Label::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parent
updateContent();
}
if (! _textSprite && _currLabelEffect == LabelEffect::SHADOW && _shadowBlurRadius <= 0)
if (! _textSprite && _shadowEnabled && _shadowBlurRadius <= 0)
{
_parentTransform = parentTransform;
draw(renderer, _modelViewTransform, true);
@ -1071,15 +1126,7 @@ void Label::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parent
if (_textSprite)
{
if (_fontDefinition._fontFillColor != _textColor)
{
Node::removeChild(_textSprite,true);
_fontDefinition._fontFillColor.r = _textColor.r;
_fontDefinition._fontFillColor.g = _textColor.g;
_fontDefinition._fontFillColor.b = _textColor.b;
createSpriteWithFontDefinition();
}
_textSprite->visit(renderer, _modelViewTransform, dirty);
drawTextSprite(renderer,dirty);
}
else
{
@ -1223,6 +1270,10 @@ void Label::updateDisplayedColor(const Color3B& parentColor)
if (_textSprite)
{
_textSprite->updateDisplayedColor(_displayedColor);
if (_shadowNode)
{
_shadowNode->updateDisplayedColor(_displayedColor);
}
}
}
@ -1234,6 +1285,10 @@ void Label::updateDisplayedOpacity(GLubyte parentOpacity)
if (_textSprite)
{
_textSprite->updateDisplayedOpacity(_displayedOpacity);
if (_shadowNode)
{
_shadowNode->updateDisplayedOpacity(_displayedOpacity);
}
}
}

View File

@ -217,6 +217,10 @@ public:
virtual Sprite * getLetter(int lettetIndex);
/** clip upper and lower margin for reduce height of label.
*/
void setClipMarginEnabled(bool clipEnabled) { _clipEnabled = clipEnabled; }
bool isClipMarginEnabled() const { return _clipEnabled; }
// font related stuff
int getCommonLineHeight() const;
@ -300,6 +304,8 @@ protected:
void drawShadowWithoutBlur();
void drawTextSprite(Renderer *renderer, bool parentTransformUpdated);
void createSpriteWithFontDefinition();
void updateFont();
@ -358,13 +364,18 @@ protected:
GLuint _uniformTextColor;
CustomCommand _customCommand;
bool _shadowEnabled;
Size _shadowOffset;
int _shadowBlurRadius;
kmMat4 _parentTransform;
Color3B _shadowColor;
Node* _shadowNode;
Color4B _textColor;
Color4F _textColorF;
bool _clipEnabled;
private:
CC_DISALLOW_COPY_AND_ASSIGN(Label);

View File

@ -43,7 +43,7 @@ NS_CC_BEGIN
LabelBMFont * LabelBMFont::create()
{
LabelBMFont * pRet = new LabelBMFont();
if (pRet && pRet->init())
if (pRet)
{
pRet->autorelease();
return pRet;
@ -72,8 +72,6 @@ bool LabelBMFont::initWithString(const std::string& str, const std::string& fntF
_fntFile = fntFile;
_label->setMaxLineWidth(width);
_label->setAlignment(alignment);
_label->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
_label->setPosition(Point::ZERO);
_label->setString(str);
this->setContentSize(_label->getContentSize());
return true;
@ -85,6 +83,7 @@ bool LabelBMFont::initWithString(const std::string& str, const std::string& fntF
LabelBMFont::LabelBMFont()
{
_label = Label::create();
_label->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
this->addChild(_label);
this->setAnchorPoint(Point::ANCHOR_MIDDLE);
_cascadeOpacityEnabled = true;

View File

@ -32,6 +32,7 @@ NS_CC_BEGIN
LabelTTF::LabelTTF()
{
_renderLabel = Label::create();
_renderLabel->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
this->addChild(_renderLabel);
this->setAnchorPoint(Point::ANCHOR_MIDDLE);

View File

@ -322,6 +322,16 @@ bool LabelTextFormatter::createStringSprites(Label *theLabel)
Point letterPosition;
const auto& kernings = theLabel->_horizontalKernings;
float clipTop = 0;
float clipBottom = 0;
int lineIndex = 0;
bool lineStart = true;
bool clip = false;
if (theLabel->_currentLabelType == Label::LabelType::TTF && theLabel->_clipEnabled)
{
clip = true;
}
for (unsigned int i = 0; i < stringLen; i++)
{
unsigned short c = strWhole[i];
@ -340,6 +350,7 @@ bool LabelTextFormatter::createStringSprites(Label *theLabel)
if (c == '\n')
{
lineIndex++;
nextFontPositionX = 0;
nextFontPositionY -= theLabel->_commonLineHeight;
@ -347,8 +358,30 @@ bool LabelTextFormatter::createStringSprites(Label *theLabel)
if(nextFontPositionY < theLabel->_commonLineHeight)
break;
lineStart = true;
continue;
}
else if (clip && tempDefinition.height > 0.0f)
{
if (lineStart)
{
if (lineIndex == 0)
{
clipTop = charYOffset;
}
lineStart = false;
clipBottom = tempDefinition.clipBottom;
}
else if(tempDefinition.clipBottom < clipBottom)
{
clipBottom = tempDefinition.clipBottom;
}
if (lineIndex == 0 && charYOffset < clipTop)
{
clipTop = charYOffset;
}
}
letterPosition.x = (nextFontPositionX + charXOffset + kernings[i]) / contentScaleFactor;
letterPosition.y = (nextFontPositionY - charYOffset) / contentScaleFactor;
@ -382,11 +415,26 @@ bool LabelTextFormatter::createStringSprites(Label *theLabel)
}
tmpSize.height = totalHeight;
if (theLabel->_labelHeight > 0)
{
tmpSize.height = theLabel->_labelHeight * contentScaleFactor;
}
if (clip)
{
int clipTotal = (clipTop + clipBottom) / contentScaleFactor;
tmpSize.height -= clipTotal * contentScaleFactor;
clipBottom /= contentScaleFactor;
for (int i = 0; i < theLabel->_limitShowCount; i++)
{
theLabel->_lettersInfo[i].position.y -= clipBottom;
}
}
theLabel->setContentSize(CC_SIZE_PIXELS_TO_POINTS(tmpSize));
return true;
}

View File

@ -852,7 +852,7 @@ LayerMultiplex * LayerMultiplex::create(Layer * layer, ...)
LayerMultiplex * LayerMultiplex::createWithLayer(Layer* layer)
{
return LayerMultiplex::create(layer, nullptr);
return LayerMultiplex::create(layer, NULL);
}
LayerMultiplex* LayerMultiplex::create()

View File

@ -431,7 +431,25 @@ public:
* In lua:local create(...)
* @endcode
*/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
// WP8 in VS2012 does not support nullptr in variable args lists and variadic templates are also not supported
typedef Layer* M;
static LayerMultiplex* create(M m1, std::nullptr_t listEnd) { return createVariadic(m1, NULL); }
static LayerMultiplex* create(M m1, M m2, std::nullptr_t listEnd) { return createVariadic(m1, m2, NULL); }
static LayerMultiplex* create(M m1, M m2, M m3, std::nullptr_t listEnd) { return createVariadic(m1, m2, m3, NULL); }
static LayerMultiplex* create(M m1, M m2, M m3, M m4, std::nullptr_t listEnd) { return createVariadic(m1, m2, m3, m4, NULL); }
static LayerMultiplex* create(M m1, M m2, M m3, M m4, M m5, std::nullptr_t listEnd) { return createVariadic(m1, m2, m3, m4, m5, NULL); }
static LayerMultiplex* create(M m1, M m2, M m3, M m4, M m5, M m6, std::nullptr_t listEnd) { return createVariadic(m1, m2, m3, m4, m5, m6, NULL); }
static LayerMultiplex* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, std::nullptr_t listEnd) { return createVariadic(m1, m2, m3, m4, m5, m6, m7, NULL); }
static LayerMultiplex* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, std::nullptr_t listEnd) { return createVariadic(m1, m2, m3, m4, m5, m6, m7, m8, NULL); }
static LayerMultiplex* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, std::nullptr_t listEnd) { return createVariadic(m1, m2, m3, m4, m5, m6, m7, m8, m9, NULL); }
static LayerMultiplex* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, M m10, std::nullptr_t listEnd) { return createVariadic(m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, NULL); }
// On WP8 for variable argument lists longer than 10 items, use createWithArray or createVariadic with NULL as the last argument
static LayerMultiplex* createVariadic(Layer* item, ...) CC_REQUIRES_NULL_TERMINATION;
#else
static LayerMultiplex * create(Layer* layer, ... );
#endif
/**
* lua script can not init with undetermined number of variables

View File

@ -53,11 +53,27 @@ Menu::~Menu()
CCLOGINFO("In the destructor of Menu. %p", this);
}
Menu* Menu::create()
{
return Menu::create(nullptr, nullptr);
}
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
Menu * Menu::variadicCreate(MenuItem* item, ...)
{
va_list args;
va_start(args,item);
Menu *ret = Menu::createWithItems(item, args);
va_end(args);
return ret;
}
#else
Menu * Menu::create(MenuItem* item, ...)
{
va_list args;
@ -69,6 +85,8 @@ Menu * Menu::create(MenuItem* item, ...)
return ret;
}
#endif
Menu* Menu::createWithArray(const Vector<MenuItem*>& arrayOfItems)
{

View File

@ -61,8 +61,26 @@ public:
/** creates an empty Menu */
static Menu* create();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
// WP8 in VS2012 does not support nullptr in variable args lists and variadic templates are also not supported
typedef MenuItem* M;
static Menu* create(M m1, std::nullptr_t listEnd) { return variadicCreate(m1, NULL); }
static Menu* create(M m1, M m2, std::nullptr_t listEnd) { return variadicCreate(m1, m2, NULL); }
static Menu* create(M m1, M m2, M m3, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, NULL); }
static Menu* create(M m1, M m2, M m3, M m4, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, NULL); }
static Menu* create(M m1, M m2, M m3, M m4, M m5, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, NULL); }
static Menu* create(M m1, M m2, M m3, M m4, M m5, M m6, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, NULL); }
static Menu* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, NULL); }
static Menu* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, NULL); }
static Menu* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, m9, NULL); }
static Menu* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, M m10, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, NULL); }
// On WP8 for lists longer than 10 items, use createWithArray or variadicCreate with NULL as the last argument
static Menu* variadicCreate(MenuItem* item, ...);
#else
/** creates a Menu with MenuItem objects */
static Menu* create(MenuItem* item, ...) CC_REQUIRES_NULL_TERMINATION;
#endif
/** creates a Menu with a Array of MenuItem objects */
static Menu* createWithArray(const Vector<MenuItem*>& arrayOfItems);
@ -136,6 +154,9 @@ CC_CONSTRUCTOR_ACCESS:
bool initWithArray(const Vector<MenuItem*>& arrayOfItems);
protected:
/** whether or not the menu will receive events */
bool _enabled;

View File

@ -178,9 +178,9 @@ void MenuItemLabel::setLabel(Node* var)
{
if (var)
{
addChild(var);
var->setAnchorPoint(Point(0, 0));
var->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
setContentSize(var->getContentSize());
addChild(var);
}
if (_label)

View File

@ -72,7 +72,7 @@ bool nodeComparisonLess(Node* n1, Node* n2)
}
// XXX: Yes, nodes might have a sort problem once every 15 days if the game runs at 60 FPS and each frame sprites are reordered.
static int s_globalOrderOfArrival = 1;
int Node::s_globalOrderOfArrival = 1;
Node::Node(void)
: _rotationX(0.0f)

View File

@ -1452,11 +1452,13 @@ protected:
bool _cascadeColorEnabled;
bool _cascadeOpacityEnabled;
static int s_globalOrderOfArrival;
private:
CC_DISALLOW_COPY_AND_ASSIGN(Node);
};
//#pragma mark - NodeRGBA
// NodeRGBA
/** NodeRGBA is a subclass of Node that implements the RGBAProtocol protocol.

View File

@ -312,8 +312,17 @@ bool ParticleSystem::initWithDictionary(ValueMap& dictionary, const std::string&
{
modeB.endRadius = dictionary["minRadius"].asFloat();
}
modeB.endRadiusVar = 0.0f;
if (_configName.length()>0)
if (dictionary.find("minRadiusVariance") != dictionary.end())
{
modeB.endRadiusVar = dictionary["minRadiusVariance"].asFloat();
}
else
{
modeB.endRadiusVar = 0.0f;
}
if (_configName.length()>0)
{
modeB.rotatePerSecond = dictionary["rotatePerSecond"].asInt();
}
@ -468,8 +477,6 @@ bool ParticleSystem::initWithTotalParticles(int numberOfParticles)
//updateParticleImp = (CC_UPDATE_PARTICLE_IMP) [self methodForSelector:updateParticleSel];
//for batchNode
_transformSystemDirty = false;
// update after action in run!
this->scheduleUpdateWithPriority(1);
return true;
}
@ -609,6 +616,14 @@ void ParticleSystem::initParticle(tParticle* particle)
}
}
void ParticleSystem::onEnter()
{
Node::onEnter();
// update after action in run!
this->scheduleUpdateWithPriority(1);
}
void ParticleSystem::stopSystem()
{
_isActive = false;

View File

@ -125,6 +125,13 @@ emitter.startSpin = 0;
@endcode
*/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
#ifdef RELATIVE
#undef RELATIVE
#endif
#endif
class CC_DLL ParticleSystem : public Node, public TextureProtocol
{
public:
@ -184,6 +191,7 @@ public:
//! whether or not the system is full
bool isFull();
virtual void onEnter();
//! should be overridden by subclasses
virtual void updateQuadWithParticle(tParticle* particle, const Point& newPosition);
//! should be overridden by subclasses

View File

@ -31,7 +31,7 @@ using namespace std;
NS_CC_BEGIN
//#pragma mark - Profiling Categories
// Profiling Categories
/* set to false the categories that you don't want to profile */
bool kProfilerCategorySprite = false;
bool kProfilerCategoryBatchSprite = false;

View File

@ -68,6 +68,7 @@ CC_CONSTRUCTOR_ACCESS:
protected:
friend class Node;
friend class ProtectedNode;
friend class SpriteBatchNode;
private:

View File

@ -41,8 +41,8 @@ bool CC_DLL cc_assert_script_compatible(const char *msg)
NS_CC_BEGIN
// #pragma mark -
// #pragma mark ScriptHandlerEntry
//
// // ScriptHandlerEntry
ScriptHandlerEntry* ScriptHandlerEntry::create(int handler)
{
@ -61,8 +61,8 @@ ScriptHandlerEntry::~ScriptHandlerEntry(void)
}
}
// #pragma mark -
// #pragma mark SchedulerScriptHandlerEntry
//
// // SchedulerScriptHandlerEntry
SchedulerScriptHandlerEntry* SchedulerScriptHandlerEntry::create(int handler, float interval, bool paused)
{
@ -88,8 +88,8 @@ SchedulerScriptHandlerEntry::~SchedulerScriptHandlerEntry(void)
}
// #pragma mark -
// #pragma mark TouchScriptHandlerEntry
//
// // TouchScriptHandlerEntry
TouchScriptHandlerEntry* TouchScriptHandlerEntry::create(int handler,
bool isMultiTouches,
@ -115,8 +115,8 @@ bool TouchScriptHandlerEntry::init(bool isMultiTouches, int priority, bool swall
return true;
}
// #pragma mark -
// #pragma mark ScriptEngineManager
//
// // ScriptEngineManager
static ScriptEngineManager* s_pSharedScriptEngineManager = nullptr;

View File

@ -212,6 +212,7 @@ enum ScriptEventType
kAccelerometerEvent,
kControlEvent,
kCommonEvent,
kComponentEvent
};
struct BasicScriptData

View File

@ -492,7 +492,7 @@ void TMXLayer::setTileGID(uint32_t gid, const Point& pos, TMXTileFlags flags)
{
CCASSERT(pos.x < _layerSize.width && pos.y < _layerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCASSERT(_tiles && _atlasIndexArray, "TMXLayer: the tiles map has been released");
CCASSERT(gid == 0 || gid >= _tileSet->_firstGid, "TMXLayer: invalid gid" );
CCASSERT(gid == 0 || (int)gid >= _tileSet->_firstGid, "TMXLayer: invalid gid" );
TMXTileFlags currentFlags;
uint32_t currentGID = getTileGIDAt(pos, &currentFlags);

View File

@ -55,7 +55,7 @@ TextFieldTTF::TextFieldTTF()
: _delegate(0)
, _charCount(0)
, _inputText("")
, _placeHolder("") // prevent LabelTTF initWithString assertion
, _placeHolder("") // prevent Label initWithString assertion
, _secureTextEntry(false)
{
_colorSpaceHolder.r = _colorSpaceHolder.g = _colorSpaceHolder.b = 127;
@ -88,7 +88,7 @@ TextFieldTTF * TextFieldTTF::textFieldWithPlaceHolder(const std::string& placeho
TextFieldTTF * TextFieldTTF::textFieldWithPlaceHolder(const std::string& placeholder, const std::string& fontName, float fontSize)
{
TextFieldTTF *ret = new TextFieldTTF();
if(ret && ret->initWithString("", fontName, fontSize))
if(ret && ret->initWithPlaceHolder("", fontName, fontSize))
{
ret->autorelease();
if (placeholder.size()>0)
@ -108,12 +108,22 @@ TextFieldTTF * TextFieldTTF::textFieldWithPlaceHolder(const std::string& placeho
bool TextFieldTTF::initWithPlaceHolder(const std::string& placeholder, const Size& dimensions, TextHAlignment alignment, const std::string& fontName, float fontSize)
{
_placeHolder = placeholder;
return LabelTTF::initWithString(_placeHolder, fontName, fontSize, dimensions, alignment);
setDimensions(dimensions.width,dimensions.height);
setFontName(fontName);
setFontSize(fontSize);
setAlignment(alignment,TextVAlignment::CENTER);
Label::setString(_placeHolder);
return true;
}
bool TextFieldTTF::initWithPlaceHolder(const std::string& placeholder, const std::string& fontName, float fontSize)
{
_placeHolder = std::string(placeholder);
return LabelTTF::initWithString(_placeHolder, fontName, fontSize);
setFontName(fontName);
setFontSize(fontSize);
Label::setString(_placeHolder);
return true;
}
//////////////////////////////////////////////////////////////////////////
@ -228,7 +238,7 @@ void TextFieldTTF::deleteBackward()
{
_inputText = "";
_charCount = 0;
LabelTTF::setString(_placeHolder);
Label::setString(_placeHolder);
return;
}
@ -242,23 +252,19 @@ const std::string& TextFieldTTF::getContentText()
return _inputText;
}
void TextFieldTTF::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
void TextFieldTTF::setColor(const Color3B& color)
{
if (_delegate && _delegate->onDraw(this))
{
return;
}
if (_inputText.length())
{
LabelTTF::draw(renderer, transform, transformUpdated);
return;
}
_colorText = color;
Label::setColor(color);
}
// draw placeholder
Color3B color = getColor();
setColor(_colorSpaceHolder);
LabelTTF::draw(renderer, transform, transformUpdated);
setColor(color);
void TextFieldTTF::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
if (_delegate && _delegate->onVisit(this,renderer,parentTransform,parentTransformUpdated))
{
return;
}
Label::visit(renderer,parentTransform,parentTransformUpdated);
}
const Color3B& TextFieldTTF::getColorSpaceHolder()
@ -305,11 +311,13 @@ void TextFieldTTF::setString(const std::string &text)
// if there is no input text, display placeholder instead
if (! _inputText.length())
{
LabelTTF::setString(_placeHolder);
Label::setColor(_colorSpaceHolder);
Label::setString(_placeHolder);
}
else
{
LabelTTF::setString(displayText);
Label::setColor(_colorText);
Label::setString(displayText);
}
_charCount = _calcCharCount(_inputText.c_str());
}
@ -325,7 +333,7 @@ void TextFieldTTF::setPlaceHolder(const std::string& text)
_placeHolder = text;
if (! _inputText.length())
{
LabelTTF::setString(_placeHolder);
Label::setString(_placeHolder);
}
}

View File

@ -26,7 +26,7 @@ THE SOFTWARE.
#ifndef __CC_TEXT_FIELD_H__
#define __CC_TEXT_FIELD_H__
#include "CCLabelTTF.h"
#include "CCLabel.h"
#include "CCIMEDelegate.h"
NS_CC_BEGIN
@ -86,7 +86,7 @@ public:
/**
@brief If the sender doesn't want to draw, return true.
*/
virtual bool onDraw(TextFieldTTF * sender)
virtual bool onVisit(TextFieldTTF * sender,Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
CC_UNUSED_PARAM(sender);
return false;
@ -96,7 +96,7 @@ public:
/**
@brief A simple text input field with TTF font.
*/
class CC_DLL TextFieldTTF : public LabelTTF, public IMEDelegate
class CC_DLL TextFieldTTF : public Label, public IMEDelegate
{
public:
/**
@ -113,7 +113,7 @@ public:
/** creates a TextFieldTTF from a fontname, alignment, dimension and font size */
static TextFieldTTF * textFieldWithPlaceHolder(const std::string& placeholder, const Size& dimensions, TextHAlignment alignment, const std::string& fontName, float fontSize);
/** creates a LabelTTF from a fontname and font size */
/** creates a TextFieldTTF from a fontname and font size */
static TextFieldTTF * textFieldWithPlaceHolder(const std::string& placeholder, const std::string& fontName, float fontSize);
/** initializes the TextFieldTTF with a font name, alignment, dimension and font size */
bool initWithPlaceHolder(const std::string& placeholder, const Size& dimensions, TextHAlignment alignment, const std::string& fontName, float fontSize);
@ -148,33 +148,23 @@ public:
virtual const Color3B& getColorSpaceHolder();
virtual void setColorSpaceHolder(const Color3B& color);
virtual void setColor(const Color3B& color) override;
// input text property
public:
virtual void setString(const std::string& text) override;
virtual const std::string& getString() const override;
protected:
TextFieldDelegate * _delegate;
int _charCount;
std::string _inputText;
// place holder text property
// place holder text displayed when there is no text in the text field.
public:
virtual void setPlaceHolder(const std::string& text);
virtual const std::string& getPlaceHolder(void) const;
protected:
std::string _placeHolder;
Color3B _colorSpaceHolder;
public:
virtual void setSecureTextEntry(bool value);
virtual bool isSecureTextEntry();
protected:
bool _secureTextEntry;
protected:
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
protected:
//////////////////////////////////////////////////////////////////////////
// IMEDelegate interface
//////////////////////////////////////////////////////////////////////////
@ -184,6 +174,18 @@ protected:
virtual void insertText(const char * text, size_t len) override;
virtual void deleteBackward() override;
virtual const std::string& getContentText() override;
TextFieldDelegate * _delegate;
int _charCount;
std::string _inputText;
std::string _placeHolder;
Color3B _colorSpaceHolder;
Color3B _colorText;
bool _secureTextEntry;
private:
class LengthStack;
LengthStack * _lens;

View File

@ -51,6 +51,8 @@ THE SOFTWARE.
NS_CC_BEGIN
namespace {
typedef Texture2D::PixelFormatInfoMap::value_type PixelFormatInfoMapValue;
static const PixelFormatInfoMapValue TexturePixelFormatInfoTablesValue[] =
@ -549,6 +551,15 @@ bool Texture2D::initWithData(const void *data, ssize_t dataLen, Texture2D::Pixel
bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, PixelFormat pixelFormat, int pixelsWide, int pixelsHigh)
{
// cocos2d-x is currently calling this multiple times on the same Texture2D
// if the GL texture has already been created,it will be leaked in OpenGL
// For now, call deleteTexture if the texture already exists
if(_name)
{
GL::deleteTexture(_name);
_name = 0;
}
//the pixelFormat must be a certain value
CCASSERT(pixelFormat != PixelFormat::NONE && pixelFormat != PixelFormat::AUTO, "the \"pixelFormat\" param must be a certain value!");
CCASSERT(pixelsWide>0 && pixelsHigh>0, "Invalid size");
@ -1072,9 +1083,7 @@ bool Texture2D::initWithString(const char *text, const FontDefinition& textDefin
}
#if (CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID) && (CC_TARGET_PLATFORM != CC_PLATFORM_IOS)
bool requestUnsupported = textDefinition._shadow._shadowEnabled || textDefinition._stroke._strokeEnabled;
CCASSERT(requestUnsupported == false, "Currently shadow and stroke only supported on iOS and Android!");
CCASSERT(textDefinition._stroke._strokeEnabled == false, "Currently stroke only supported on iOS and Android!");
#endif
PixelFormat pixelFormat = g_defaultAlphaPixelFormat;
@ -1088,6 +1097,9 @@ bool Texture2D::initWithString(const char *text, const FontDefinition& textDefin
textDef._fontSize *= contentScaleFactor;
textDef._dimensions.width *= contentScaleFactor;
textDef._dimensions.height *= contentScaleFactor;
textDef._stroke._strokeSize *= contentScaleFactor;
textDef._shadow._shadowEnabled = false;
Data outData = Device::getTextureDataForText(text,textDef,align,imageWidth,imageHeight);
if(outData.isNull())
return false;
@ -1199,6 +1211,9 @@ void Texture2D::generateMipmap()
GL::bindTexture2D( _name );
glGenerateMipmap(GL_TEXTURE_2D);
_hasMipmaps = true;
#if CC_ENABLE_CACHE_TEXTURE_DATA
VolatileTextureMgr::setHasMipmaps(this, _hasMipmaps);
#endif
}
bool Texture2D::hasMipmaps() const

View File

@ -635,6 +635,12 @@ void VolatileTextureMgr::addStringTexture(Texture2D *tt, const char* text, const
vt->_fontDefinition = fontDefinition;
}
void VolatileTextureMgr::setHasMipmaps(Texture2D *t, bool hasMipmaps)
{
VolatileTexture *vt = findVolotileTexture(t);
vt->_hasMipmaps = hasMipmaps;
}
void VolatileTextureMgr::setTexParameters(Texture2D *t, const Texture2D::TexParams &texParams)
{
VolatileTexture *vt = findVolotileTexture(t);
@ -717,6 +723,9 @@ void VolatileTextureMgr::reloadAllTextures()
default:
break;
}
if (vt->_hasMipmaps) {
vt->_texture->generateMipmap();
}
vt->_texture->setTexParameters(vt->_texParams);
}

View File

@ -251,6 +251,7 @@ protected:
std::string _fileName;
bool _hasMipmaps;
Texture2D::TexParams _texParams;
std::string _text;
FontDefinition _fontDefinition;
@ -264,6 +265,7 @@ public:
static void addDataTexture(Texture2D *tt, void* data, int dataLen, Texture2D::PixelFormat pixelFormat, const Size& contentSize);
static void addImage(Texture2D *tt, Image *image);
static void setHasMipmaps(Texture2D *t, bool hasMipmaps);
static void setTexParameters(Texture2D *t, const Texture2D::TexParams &texParams);
static void removeTexture(Texture2D *t);
static void reloadAllTextures();

View File

@ -32,7 +32,7 @@ THE SOFTWARE.
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/CCFileUtilsAndroid.h"
#elif(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#elif(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
// for import ssize_t on win32 platform
#include "CCStdC.h"
#endif

View File

@ -278,8 +278,8 @@ void ccArrayFullRemoveArray(ccArray *arr, ccArray *minusArr)
arr->num -= back;
}
// #pragma mark -
// #pragma mark ccCArray for Values (c structures)
//
// // ccCArray for Values (c structures)
/** Allocates and initializes a new C array with specified capacity */
ccCArray* ccCArrayNew(ssize_t capacity)

View File

@ -130,8 +130,8 @@ void ccArrayRemoveArray(ccArray *arr, ccArray *minusArr);
matching instances in arr will be removed. */
void ccArrayFullRemoveArray(ccArray *arr, ccArray *minusArr);
// #pragma mark -
// #pragma mark ccCArray for Values (c structures)
//
// // ccCArray for Values (c structures)
typedef struct _ccCArray {
ssize_t num, max;

View File

@ -217,7 +217,7 @@ void bindVAO(GLuint vaoId)
}
}
//#pragma mark - GL Vertex Attrib functions
// GL Vertex Attrib functions
void enableVertexAttribs( unsigned int flags )
{
@ -260,7 +260,7 @@ void enableVertexAttribs( unsigned int flags )
}
}
//#pragma mark - GL Uniforms functions
// GL Uniforms functions
void setProjectionMatrixDirty( void )
{

View File

@ -195,6 +195,22 @@ THE SOFTWARE.
#include "platform/linux/CCStdC.h"
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_LINUX
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
#include "platform/winrt/CCApplication.h"
#include "platform/winrt/CCGLView.h"
#include "platform/winrt/CCGL.h"
#include "platform/winrt/CCStdC.h"
#include "platform/winrt/CCPrecompiledShaders.h"
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WINRT
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
#include "platform/winrt/CCApplication.h"
#include "platform/wp8/CCGLView.h"
#include "platform/winrt/CCGL.h"
#include "platform/winrt/CCStdC.h"
#include "platform/winrt/CCPrecompiledShaders.h"
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WP8
// script_support
#include "CCScriptSupport.h"

View File

@ -52,7 +52,9 @@ public:
OS_BLACKBERRY,
OS_NACL,
OS_EMSCRIPTEN,
OS_TIZEN
OS_TIZEN,
OS_WINRT,
OS_WP8
};
/**

View File

@ -402,7 +402,12 @@ static tinyxml2::XMLElement* generateElementForObject(const Value& value, tinyxm
return node;
}
//FIXME:XXX How to deal with Boolean ??
//object is bool
if (value.getType() == Value::Type::BOOLEAN) {
tinyxml2::XMLElement* node = doc->NewElement(value.asString().c_str());
return node;
}
// object is Array
if (value.getType() == Value::Type::VECTOR)

View File

@ -37,7 +37,7 @@ namespace {
static Touch* g_touches[EventTouch::MAX_TOUCHES] = { nullptr };
static unsigned int g_indexBitsUsed = 0;
// System touch pointer ID (It may not be ascending order number) <-> Ascending order number from 0
static std::map<int, int> g_touchIdReorderMap;
static std::map<intptr_t, int> g_touchIdReorderMap;
static int getUnUsedIndex()
{
@ -235,9 +235,9 @@ const std::string& GLViewProtocol::getViewName() const
return _viewName;
}
void GLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float ys[])
void GLViewProtocol::handleTouchesBegin(int num, intptr_t ids[], float xs[], float ys[])
{
int id = 0;
intptr_t id = 0;
float x = 0.0f;
float y = 0.0f;
int unusedIndex = 0;
@ -285,9 +285,9 @@ void GLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float ys
dispatcher->dispatchEvent(&touchEvent);
}
void GLViewProtocol::handleTouchesMove(int num, int ids[], float xs[], float ys[])
void GLViewProtocol::handleTouchesMove(int num, intptr_t ids[], float xs[], float ys[])
{
int id = 0;
intptr_t id = 0;
float x = 0.0f;
float y = 0.0f;
EventTouch touchEvent;
@ -317,7 +317,7 @@ void GLViewProtocol::handleTouchesMove(int num, int ids[], float xs[], float ys[
else
{
// It is error, should return.
CCLOG("Moving touches with id: %d error", id);
CCLOG("Moving touches with id: %ld error", id);
return;
}
}
@ -333,9 +333,9 @@ void GLViewProtocol::handleTouchesMove(int num, int ids[], float xs[], float ys[
dispatcher->dispatchEvent(&touchEvent);
}
void GLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode, int num, int ids[], float xs[], float ys[])
void GLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode, int num, intptr_t ids[], float xs[], float ys[])
{
int id = 0;
intptr_t id = 0;
float x = 0.0f;
float y = 0.0f;
EventTouch touchEvent;
@ -370,7 +370,7 @@ void GLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode,
}
else
{
CCLOG("Ending touches with id: %d error", id);
CCLOG("Ending touches with id: %ld error", id);
return;
}
@ -393,12 +393,12 @@ void GLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode,
}
}
void GLViewProtocol::handleTouchesEnd(int num, int ids[], float xs[], float ys[])
void GLViewProtocol::handleTouchesEnd(int num, intptr_t ids[], float xs[], float ys[])
{
handleTouchesOfEndOrCancel(EventTouch::EventCode::ENDED, num, ids, xs, ys);
}
void GLViewProtocol::handleTouchesCancel(int num, int ids[], float xs[], float ys[])
void GLViewProtocol::handleTouchesCancel(int num, intptr_t ids[], float xs[], float ys[])
{
handleTouchesOfEndOrCancel(EventTouch::EventCode::CANCELLED, num, ids, xs, ys);
}

View File

@ -160,10 +160,10 @@ public:
const std::string& getViewName() const;
/** Touch events are handled by default; if you want to customize your handlers, please override these functions: */
virtual void handleTouchesBegin(int num, int ids[], float xs[], float ys[]);
virtual void handleTouchesMove(int num, int ids[], float xs[], float ys[]);
virtual void handleTouchesEnd(int num, int ids[], float xs[], float ys[]);
virtual void handleTouchesCancel(int num, int ids[], float xs[], float ys[]);
virtual void handleTouchesBegin(int num, intptr_t ids[], float xs[], float ys[]);
virtual void handleTouchesMove(int num, intptr_t ids[], float xs[], float ys[]);
virtual void handleTouchesEnd(int num, intptr_t ids[], float xs[], float ys[]);
virtual void handleTouchesCancel(int num, intptr_t ids[], float xs[], float ys[]);
/**
* Get the opengl view port rectangle.
@ -186,7 +186,7 @@ public:
protected:
void updateDesignResolutionSize();
void handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode, int num, int ids[], float xs[], float ys[]);
void handleTouchesOfEndOrCancel(EventTouch::EventCode eventCode, int num, intptr_t ids[], float xs[], float ys[]);
// real screen size
Size _screenSize;

View File

@ -46,7 +46,9 @@ extern "C"
#include "atitc.h"
#include "TGAlib.h"
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WP8) && (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)
#include "decode.h"
#endif
#include "ccMacros.h"
#include "CCCommon.h"
@ -1833,6 +1835,10 @@ bool Image::initWithPVRData(const unsigned char * data, ssize_t dataLen)
bool Image::initWithWebpData(const unsigned char * data, ssize_t dataLen)
{
bool bRet = false;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
CCLOG("WEBP image format not supported on WinRT or WP8");
#else
do
{
WebPDecoderConfig config;
@ -1862,9 +1868,11 @@ bool Image::initWithWebpData(const unsigned char * data, ssize_t dataLen)
bRet = true;
} while (0);
#endif
return bRet;
}
bool Image::initWithRawData(const unsigned char * data, ssize_t dataLen, int width, int height, int bitsPerComponent, bool preMulti)
{
bool bRet = false;

View File

@ -155,7 +155,7 @@ protected:
bool saveImageToPNG(const std::string& filePath, bool isToRGB = true);
bool saveImageToJPG(const std::string& filePath);
private:
protected:
/**
@brief Determine how many mipmaps can we have.
Its same as define but it respects namespaces
@ -175,7 +175,7 @@ private:
std::string _filePath;
private:
protected:
// noncopyable
Image(const Image& rImg);
Image & operator=(const Image&);

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,191 @@
/****************************************************************************
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;
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.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
FrameLayout framelayout = new FrameLayout(this);
framelayout.setLayoutParams(framelayout_params);
// Cocos2dxEditText layout
ViewGroup.LayoutParams edittext_layout_params =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_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

@ -39,7 +39,6 @@ import android.graphics.Rect;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.FloatMath;
import android.util.Log;
public class Cocos2dxBitmap {
@ -119,7 +118,7 @@ public class Cocos2dxBitmap {
*/
if(0 != width)
{
final int firstWordWidth = (int) FloatMath.ceil(paint.measureText(string, 0,1));
final int firstWordWidth = (int) Math.ceil(paint.measureText(string, 0,1));
if ( firstWordWidth > width)
{
Log.w("createTextBitmapShadowStroke warning:","the input width is less than the width of the pString's first word\n");
@ -140,25 +139,6 @@ public class Cocos2dxBitmap {
float renderTextDeltaX = 0.0f;
float renderTextDeltaY = 0.0f;
if ( shadow ) {
int shadowColor = ((int)(255 * shadowOpacity) & 0xff) << 24;
paint.setShadowLayer(shadowBlur, shadowDX, shadowDY, shadowColor);
bitmapPaddingX = Math.abs(shadowDX);
bitmapPaddingY = Math.abs(shadowDY);
if ( shadowDX < 0.0 )
{
renderTextDeltaX = bitmapPaddingX;
}
if ( shadowDY < 0.0 )
{
renderTextDeltaY = bitmapPaddingY;
}
}
if (0 == textProperty.mMaxWidth || 0 == bitmapTotalHeight)
{
Log.w("createTextBitmapShadowStroke warning:","textProperty MaxWidth is 0 or bitMapTotalHeight is 0\n");
@ -174,40 +154,43 @@ public class Cocos2dxBitmap {
/* Draw string. */
final FontMetricsInt fontMetricsInt = paint.getFontMetricsInt();
int x = 0;
int y = Cocos2dxBitmap.computeY(fontMetricsInt, height, textProperty.mTotalHeight, verticalAlignment);
final String[] lines = textProperty.mLines;
for (final String line : lines) {
x = Cocos2dxBitmap.computeX(line, textProperty.mMaxWidth, horizontalAlignment);
canvas.drawText(line, x + renderTextDeltaX, y + renderTextDeltaY, paint);
y += textProperty.mHeightPerLine;
}
// draw again with stroke on if needed
if ( stroke ) {
if ( stroke )
{
final Paint paintStroke = Cocos2dxBitmap.newPaint(fontName, fontSize, horizontalAlignment);
paintStroke.setStyle(Paint.Style.STROKE);
paintStroke.setStrokeWidth(strokeSize * 0.5f);
paintStroke.setStrokeWidth(strokeSize);
paintStroke.setARGB(255, (int) (strokeR * 255), (int) (strokeG * 255), (int) (strokeB * 255));
x = 0;
y = Cocos2dxBitmap.computeY(fontMetricsInt, height, textProperty.mTotalHeight, verticalAlignment);
int x = 0;
int y = Cocos2dxBitmap.computeY(fontMetricsInt, height, textProperty.mTotalHeight, verticalAlignment);
final String[] lines2 = textProperty.mLines;
for (final String line : lines2) {
x = Cocos2dxBitmap.computeX(line, textProperty.mMaxWidth, horizontalAlignment);
canvas.drawText(line, x + renderTextDeltaX, y + renderTextDeltaY, paintStroke);
canvas.drawText(line, x + renderTextDeltaX, y + renderTextDeltaY, paint);
y += textProperty.mHeightPerLine;
}
}
else
{
int x = 0;
int y = Cocos2dxBitmap.computeY(fontMetricsInt, height, textProperty.mTotalHeight, verticalAlignment);
final String[] lines = textProperty.mLines;
for (final String line : lines) {
x = Cocos2dxBitmap.computeX(line, textProperty.mMaxWidth, horizontalAlignment);
canvas.drawText(line, x + renderTextDeltaX, y + renderTextDeltaY, paint);
y += textProperty.mHeightPerLine;
}
}
Cocos2dxBitmap.initNativeObject(bitmap);
@ -269,7 +252,7 @@ public class Cocos2dxBitmap {
/* Compute the max width. */
int temp = 0;
for (final String line : lines) {
temp = (int) FloatMath.ceil(paint.measureText(line, 0,
temp = (int) Math.ceil(paint.measureText(line, 0,
line.length()));
if (temp > maxContentWidth) {
maxContentWidth = temp;
@ -343,7 +326,7 @@ public class Cocos2dxBitmap {
* The width of line is exceed maxWidth, should divide it into
* two or more lines.
*/
final int lineWidth = (int) FloatMath.ceil(paint
final int lineWidth = (int) Math.ceil(paint
.measureText(line));
if (lineWidth > maxWidth) {
strList.addAll(Cocos2dxBitmap.divideStringWithMaxWidth(
@ -391,7 +374,7 @@ public class Cocos2dxBitmap {
/* Break a String into String[] by the width & should wrap the word. */
for (int i = 1; i <= charLength; ++i) {
tempWidth = (int) FloatMath.ceil(paint.measureText(string, start,
tempWidth = (int) Math.ceil(paint.measureText(string, start,
i));
if (tempWidth >= maxWidth) {
final int lastIndexOfSpace = string.substring(0, i)

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

@ -157,7 +157,7 @@ public class Cocos2dxEditBoxDialog extends Dialog {
final LinearLayout layout = new LinearLayout(this.getContext());
layout.setOrientation(LinearLayout.VERTICAL);
final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
this.mTextViewTitle = new TextView(this.getContext());
final LinearLayout.LayoutParams textviewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@ -166,7 +166,7 @@ public class Cocos2dxEditBoxDialog extends Dialog {
layout.addView(this.mTextViewTitle, textviewParams);
this.mInputEditText = new EditText(this.getContext());
final LinearLayout.LayoutParams editTextParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final LinearLayout.LayoutParams editTextParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
editTextParams.leftMargin = editTextParams.rightMargin = this.convertDipsToPixels(10);
layout.addView(this.mInputEditText, editTextParams);

View File

@ -24,17 +24,10 @@ THE SOFTWARE.
****************************************************************************/
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 {
// ===========================================================
@ -45,9 +38,7 @@ 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 +46,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);
public Cocos2dxEditText(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
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, 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;
@ -119,131 +84,6 @@ 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_INDEX_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_INDEX_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_INDEX_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

@ -30,8 +30,7 @@ import java.util.Locale;
import java.lang.Runnable;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@ -56,6 +55,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 +94,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 +114,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 +147,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 +173,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 +273,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,20 +300,18 @@ 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()
{
if (sActivity != null)
@ -432,16 +397,14 @@ public class Cocos2dxHelper {
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,167 @@
/****************************************************************************
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.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
@ -97,19 +92,15 @@ namespace cocos2d {
// 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

@ -51,12 +51,30 @@ static void addItemToArray(id item, ValueVector& array)
}
// add number value into array(such as int, float, bool and so on)
// the value is a number
if ([item isKindOfClass:[NSNumber class]])
{
array.push_back(Value([item doubleValue]));
NSNumber* num = item;
const char* numType = [num objCType];
if(num == (void*)kCFBooleanFalse || num == (void*)kCFBooleanTrue)
{
array.push_back(Value([num boolValue]));
}
else if(strcmp(numType, @encode(float)) == 0)
{
array.push_back(Value([num floatValue]));
}
else if(strcmp(numType, @encode(double)) == 0)
{
array.push_back(Value([num doubleValue]));
}
else{
array.push_back(Value([num intValue]));
}
return;
}
// add dictionary value into array
if ([item isKindOfClass:[NSDictionary class]])
{
@ -94,6 +112,31 @@ static void addObjectToNSArray(const Value& value, NSMutableArray *array)
return;
}
//add float into array
if (value.getType() == Value::Type::FLOAT) {
NSNumber *number = [NSNumber numberWithFloat:value.asFloat()];
[array addObject:number];
}
//add double into array
if (value.getType() == Value::Type::DOUBLE) {
NSNumber *number = [NSNumber numberWithDouble:value.asDouble()];
[array addObject:number];
}
//add boolean into array
if (value.getType() == Value::Type::BOOLEAN) {
NSNumber *element = [NSNumber numberWithBool:value.asBool()];
[array addObject:element];
}
if (value.getType() == Value::Type::INTEGER) {
NSNumber *element = [NSNumber numberWithInt:value.asInt()];
[array addObject:element];
}
//todo: add date and data support
// add array into array
if (value.getType() == Value::Type::VECTOR)
{
@ -141,10 +184,27 @@ static void addValueToDict(id nsKey, id nsValue, ValueMap& dict)
// the value is a number
if ([nsValue isKindOfClass:[NSNumber class]])
{
dict[key] = Value([nsValue doubleValue]);
NSNumber* num = nsValue;
const char* numType = [num objCType];
if(num == (void*)kCFBooleanFalse || num == (void*)kCFBooleanTrue)
{
dict[key] = Value([num boolValue]);
}
else if(strcmp(numType, @encode(float)) == 0)
{
dict[key] = Value([num floatValue]);
}
else if(strcmp(numType, @encode(double)) == 0)
{
dict[key] = Value([num doubleValue]);
}
else{
dict[key] = Value([num intValue]);
}
return;
}
// the value is a new dictionary
if ([nsValue isKindOfClass:[NSDictionary class]])
{
@ -171,6 +231,7 @@ static void addValueToDict(id nsKey, id nsValue, ValueMap& dict)
dict[key] = Value(valueArray);
return;
}
}
static void addObjectToNSDict(const std::string& key, const Value& value, NSMutableDictionary *dict)
@ -191,6 +252,30 @@ static void addObjectToNSDict(const std::string& key, const Value& value, NSMuta
return;
}
//add float into dict
if (value.getType() == Value::Type::FLOAT) {
NSNumber *number = [NSNumber numberWithFloat:value.asFloat()];
[dict setObject:number forKey:NSkey];
}
//add double into dict
if (value.getType() == Value::Type::DOUBLE) {
NSNumber *number = [NSNumber numberWithDouble:value.asDouble()];
[dict setObject:number forKey:NSkey];
}
//add boolean into dict
if (value.getType() == Value::Type::BOOLEAN) {
NSNumber *element = [NSNumber numberWithBool:value.asBool()];
[dict setObject:element forKey:NSkey];
}
//add integer into dict
if (value.getType() == Value::Type::INTEGER) {
NSNumber *element = [NSNumber numberWithInt:value.asInt()];
[dict setObject:element forKey:NSkey];
}
// the object is a String
if (value.getType() == Value::Type::STRING)
{

View File

@ -523,7 +523,7 @@ void GLView::onGLFWMouseCallBack(GLFWwindow* window, int button, int action, int
_captured = true;
if (this->getViewPortRect().equals(Rect::ZERO) || this->getViewPortRect().containsPoint(Point(_mouseX,_mouseY)))
{
int id = 0;
intptr_t id = 0;
this->handleTouchesBegin(1, &id, &_mouseX, &_mouseY);
}
}
@ -532,7 +532,7 @@ void GLView::onGLFWMouseCallBack(GLFWwindow* window, int button, int action, int
if (_captured)
{
_captured = false;
int id = 0;
intptr_t id = 0;
this->handleTouchesEnd(1, &id, &_mouseX, &_mouseY);
}
}
@ -575,7 +575,7 @@ void GLView::onGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y)
if (_captured)
{
int id = 0;
intptr_t id = 0;
this->handleTouchesMove(1, &id, &_mouseX, &_mouseY);
}

View File

@ -315,15 +315,9 @@ static bool _initWithString(const char * text, cocos2d::Device::TextAlign align,
shadowStrokePaddingY = ceilf(info->strokeSize);
}
if ( info->hasShadow )
{
shadowStrokePaddingX = std::max(shadowStrokePaddingX, (float)fabs(info->shadowOffset.width));
shadowStrokePaddingY = std::max(shadowStrokePaddingY, (float)fabs(info->shadowOffset.height));
}
// add the padding (this could be 0 if no shadow and no stroke)
dim.width += shadowStrokePaddingX;
dim.height += shadowStrokePaddingY;
dim.width += shadowStrokePaddingX*2;
dim.height += shadowStrokePaddingY*2;
unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * (int)(dim.width * dim.height * 4));
@ -356,83 +350,68 @@ static bool _initWithString(const char * text, cocos2d::Device::TextAlign align,
// measure text size with specified font and determine the rectangle to draw text in
unsigned uHoriFlag = (int)align & 0x0f;
UITextAlignment testAlign = (UITextAlignment)((2 == uHoriFlag) ? UITextAlignmentRight
: (3 == uHoriFlag) ? UITextAlignmentCenter
: UITextAlignmentLeft);
NSTextAlignment nsAlign = (2 == uHoriFlag) ? NSTextAlignmentRight
: (3 == uHoriFlag) ? NSTextAlignmentCenter
: NSTextAlignmentLeft;
// take care of stroke if needed
if ( info->hasStroke )
{
CGContextSetTextDrawingMode(context, kCGTextFillStroke);
CGContextSetRGBStrokeColor(context, info->strokeColorR, info->strokeColorG, info->strokeColorB, 1);
CGContextSetLineWidth(context, info->strokeSize);
}
// take care of shadow if needed
if ( info->hasShadow )
{
CGSize offset;
offset.height = info->shadowOffset.height;
offset.width = info->shadowOffset.width;
CGFloat shadowColorValues[] = {0, 0, 0, info->shadowOpacity};
CGColorRef shadowColor = CGColorCreate (colorSpace, shadowColorValues);
CGContextSetShadowWithColor(context, offset, info->shadowBlur, shadowColor);
CGColorRelease (shadowColor);
}
CGColorSpaceRelease(colorSpace);
// normal fonts
//if( [font isKindOfClass:[UIFont class] ] )
//{
// [str drawInRect:CGRectMake(0, startH, dim.width, dim.height) withFont:font lineBreakMode:(UILineBreakMode)UILineBreakModeWordWrap alignment:align];
//}
//else // ZFont class
//{
// [FontLabelStringDrawingHelper drawInRect:str rect:CGRectMake(0, startH, dim.width, dim.height) withZFont:font lineBreakMode:(UILineBreakMode)UILineBreakModeWordWrap
////alignment:align];
//}
// compute the rect used for rendering the text
// based on wether shadows or stroke are enabled
float textOriginX = 0.0;
float textOrigingY = 0.0;
float textOriginX = 0;
float textOrigingY = startH;
float textWidth = dim.width - shadowStrokePaddingX;
float textHeight = dim.height - shadowStrokePaddingY;
if ( info->shadowOffset.width < 0 )
{
textOriginX = shadowStrokePaddingX;
}
else
{
textOriginX = 0.0;
}
if (info->shadowOffset.height > 0)
{
textOrigingY = startH;
}
else
{
textOrigingY = startH - shadowStrokePaddingY;
}
float textWidth = dim.width;
float textHeight = dim.height;
CGRect rect = CGRectMake(textOriginX, textOrigingY, textWidth, textHeight);
CGContextBeginTransparencyLayerWithRect(context, rect, nullptr);
CGContextSetShouldSubpixelQuantizeFonts(context, false);
CGContextBeginTransparencyLayerWithRect(context, rect, NULL);
if ( info->hasStroke )
{
CGContextSetTextDrawingMode(context, kCGTextStroke);
if([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)
{
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = nsAlign;
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
[str drawInRect:rect withAttributes:@{
NSFontAttributeName: font,
NSStrokeWidthAttributeName: [NSNumber numberWithFloat: info->strokeSize / size * 100 ],
NSForegroundColorAttributeName:[UIColor colorWithRed:info->tintColorR
green:info->tintColorG
blue:info->tintColorB
alpha:1.0f],
NSParagraphStyleAttributeName:paragraphStyle,
NSStrokeColorAttributeName: [UIColor colorWithRed:info->strokeColorR
green:info->strokeColorG
blue:info->strokeColorB
alpha:1.0f]
}
];
[paragraphStyle release];
}
else
{
CGContextSetRGBStrokeColor(context, info->strokeColorR, info->strokeColorG, info->strokeColorB, 1);
CGContextSetLineWidth(context, info->strokeSize);
//original code that was not working in iOS 7
[str drawInRect: rect withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:nsAlign];
}
}
CGContextSetTextDrawingMode(context, kCGTextFill);
// actually draw the text in the context
// XXX: ios7 casting
[str drawInRect: rect withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:(NSTextAlignment)testAlign];
[str drawInRect: rect withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:nsAlign];
CGContextEndTransparencyLayer(context);

View File

@ -408,7 +408,7 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
}
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
glview->handleTouchesBegin(i, (int*)ids, xs, ys);
glview->handleTouchesBegin(i, (intptr_t*)ids, xs, ys);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
@ -430,7 +430,7 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
}
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
glview->handleTouchesMove(i, (int*)ids, xs, ys);
glview->handleTouchesMove(i, (intptr_t*)ids, xs, ys);
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
@ -453,7 +453,7 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
}
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
glview->handleTouchesEnd(i, (int*)ids, xs, ys);
glview->handleTouchesEnd(i, (intptr_t*)ids, xs, ys);
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
@ -476,7 +476,7 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
}
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
glview->handleTouchesCancel(i, (int*)ids, xs, ys);
glview->handleTouchesCancel(i, (intptr_t*)ids, xs, ys);
}
#pragma mark - UIView - Responder

View File

@ -106,6 +106,8 @@ static bool isFloat( std::string myString ) {
return iss.eof() && !iss.fail();
}
#if CC_TARGET_PLATFORM != CC_PLATFORM_WINRT && CC_TARGET_PLATFORM != CC_PLATFORM_WP8
// helper free functions
// dprintf() is not defined in Android
@ -176,6 +178,7 @@ static void printFileUtils(int fd)
}
sendPrompt(fd);
}
#endif
#if defined(__MINGW32__)
@ -210,20 +213,22 @@ static void _log(const char *format, va_list args)
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
__android_log_print(ANDROID_LOG_DEBUG, "cocos2d-x debug info", "%s", buf);
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT || CC_TARGET_PLATFORM == CC_PLATFORM_WP8
WCHAR wszBuf[MAX_LOG_LENGTH] = {0};
MultiByteToWideChar(CP_UTF8, 0, buf, -1, wszBuf, sizeof(wszBuf));
OutputDebugStringW(wszBuf);
WideCharToMultiByte(CP_ACP, 0, wszBuf, -1, buf, sizeof(buf), NULL, FALSE);
printf("%s", buf);
#else
// Linux, Mac, iOS, etc
fprintf(stdout, "cocos2d: %s", buf);
fflush(stdout);
#endif
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
Director::getInstance()->getConsole()->log(buf);
#endif
}
// XXX: Deprecated
@ -243,6 +248,8 @@ void log(const char * format, ...)
va_end(args);
}
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
//
// Console code
//
@ -1081,4 +1088,7 @@ void Console::loop()
_running = false;
}
#endif /* #if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8) */
NS_CC_END

View File

@ -68,6 +68,8 @@ void CC_DLL log(const char * format, ...) CC_FORMAT_PRINTF(1, 2);
scheduler->performFunctionInCocosThread( ... );
```
*/
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
class CC_DLL Console
{
public:
@ -137,11 +139,12 @@ protected:
std::mutex _DebugStringsMutex;
std::vector<std::string> _DebugStrings;
int _touchId;
intptr_t _touchId;
private:
CC_DISALLOW_COPY_AND_ASSIGN(Console);
};
#endif /* #if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8) */
NS_CC_END
#endif /* defined(__CCCONSOLE_H__) */

View File

@ -48,6 +48,8 @@ Config of cocos2d-x project, per target platform.
#define CC_PLATFORM_EMSCRIPTEN 10
#define CC_PLATFORM_TIZEN 11
#define CC_PLATFORM_QT5 12
#define CC_PLATFORM_WP8 13
#define CC_PLATFORM_WINRT 14
// Determine target platform by compile environment macro.
#define CC_TARGET_PLATFORM CC_PLATFORM_UNKNOWN
@ -124,6 +126,19 @@ Config of cocos2d-x project, per target platform.
#define CC_TARGET_PLATFORM CC_PLATFORM_QT5
#endif
// WinRT (Windows Store App)
#if defined(WINRT)
#undef CC_TARGET_PLATFORM
#define CC_TARGET_PLATFORM CC_PLATFORM_WINRT
#endif
// WP8 (Windows Phone 8 App)
#if defined(WP8)
#undef CC_TARGET_PLATFORM
#define CC_TARGET_PLATFORM CC_PLATFORM_WP8
#endif
//////////////////////////////////////////////////////////////////////////
// post configure
//////////////////////////////////////////////////////////////////////////

View File

@ -82,7 +82,7 @@ to be different from other platforms unless there's a good reason.
It's new in cocos2d-x since v0.99.5
*/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
#define CC_ENABLE_CACHE_TEXTURE_DATA 1
#else
#define CC_ENABLE_CACHE_TEXTURE_DATA 0

View File

@ -24,6 +24,7 @@
#include "CCValue.h"
#include <sstream>
#include <iomanip>
NS_CC_BEGIN
@ -572,6 +573,7 @@ std::string Value::asString() const
std::stringstream ret;
switch (_type) {
case Type::BYTE:
ret << _baseData.byteVal;
@ -580,10 +582,10 @@ std::string Value::asString() const
ret << _baseData.intVal;
break;
case Type::FLOAT:
ret << _baseData.floatVal;
ret << std::fixed << std::setprecision( 7 )<< _baseData.floatVal;
break;
case Type::DOUBLE:
ret << _baseData.doubleVal;
ret << std::fixed << std::setprecision( 16 ) << _baseData.doubleVal;
break;
case Type::BOOLEAN:
ret << (_baseData.boolVal ? "true" : "false");

View File

@ -129,6 +129,11 @@ public:
MULTIPLY_RESOLUTION,
};
#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
#ifdef ABSOLUTE
#undef ABSOLUTE
#endif
#endif
enum class SizeType
{
ABSOLUTE,

View File

@ -16,7 +16,7 @@ namespace cocosbuilder {
void LabelTTFLoader::onHandlePropTypeColor3(Node * pNode, Node * pParent, const char * pPropertyName, Color3B pColor3B, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_COLOR) == 0) {
((LabelTTF *)pNode)->setColor(pColor3B);
((Label *)pNode)->setColor(pColor3B);
} else {
NodeLoader::onHandlePropTypeColor3(pNode, pParent, pPropertyName, pColor3B, ccbReader);
}
@ -24,7 +24,7 @@ void LabelTTFLoader::onHandlePropTypeColor3(Node * pNode, Node * pParent, const
void LabelTTFLoader::onHandlePropTypeByte(Node * pNode, Node * pParent, const char * pPropertyName, unsigned char pByte, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_OPACITY) == 0) {
((LabelTTF *)pNode)->setOpacity(pByte);
((Label *)pNode)->setOpacity(pByte);
} else {
NodeLoader::onHandlePropTypeByte(pNode, pParent, pPropertyName, pByte, ccbReader);
}
@ -32,7 +32,7 @@ void LabelTTFLoader::onHandlePropTypeByte(Node * pNode, Node * pParent, const ch
void LabelTTFLoader::onHandlePropTypeBlendFunc(Node * pNode, Node * pParent, const char * pPropertyName, BlendFunc pBlendFunc, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_BLENDFUNC) == 0) {
((LabelTTF *)pNode)->setBlendFunc(pBlendFunc);
((Label *)pNode)->setBlendFunc(pBlendFunc);
} else {
NodeLoader::onHandlePropTypeBlendFunc(pNode, pParent, pPropertyName, pBlendFunc, ccbReader);
}
@ -40,7 +40,7 @@ void LabelTTFLoader::onHandlePropTypeBlendFunc(Node * pNode, Node * pParent, con
void LabelTTFLoader::onHandlePropTypeFontTTF(Node * pNode, Node * pParent, const char * pPropertyName, const char * pFontTTF, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_FONTNAME) == 0) {
((LabelTTF *)pNode)->setFontName(pFontTTF);
((Label *)pNode)->setFontName(pFontTTF);
} else {
NodeLoader::onHandlePropTypeFontTTF(pNode, pParent, pPropertyName, pFontTTF, ccbReader);
}
@ -48,7 +48,7 @@ void LabelTTFLoader::onHandlePropTypeFontTTF(Node * pNode, Node * pParent, const
void LabelTTFLoader::onHandlePropTypeText(Node * pNode, Node * pParent, const char * pPropertyName, const char * pText, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_STRING) == 0) {
((LabelTTF *)pNode)->setString(pText);
((Label *)pNode)->setString(pText);
} else {
NodeLoader::onHandlePropTypeText(pNode, pParent, pPropertyName, pText, ccbReader);
}
@ -56,7 +56,7 @@ void LabelTTFLoader::onHandlePropTypeText(Node * pNode, Node * pParent, const ch
void LabelTTFLoader::onHandlePropTypeFloatScale(Node * pNode, Node * pParent, const char * pPropertyName, float pFloatScale, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_FONTSIZE) == 0) {
((LabelTTF *)pNode)->setFontSize(pFloatScale);
((Label *)pNode)->setFontSize(pFloatScale);
} else {
NodeLoader::onHandlePropTypeFloatScale(pNode, pParent, pPropertyName, pFloatScale, ccbReader);
}
@ -64,19 +64,19 @@ void LabelTTFLoader::onHandlePropTypeFloatScale(Node * pNode, Node * pParent, co
void LabelTTFLoader::onHandlePropTypeIntegerLabeled(Node * pNode, Node * pParent, const char * pPropertyName, int pIntegerLabeled, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_HORIZONTALALIGNMENT) == 0) {
((LabelTTF *)pNode)->setHorizontalAlignment(TextHAlignment(pIntegerLabeled));
((Label *)pNode)->setHorizontalAlignment(TextHAlignment(pIntegerLabeled));
} else if(strcmp(pPropertyName, PROPERTY_VERTICALALIGNMENT) == 0) {
((LabelTTF *)pNode)->setVerticalAlignment(TextVAlignment(pIntegerLabeled));
((Label *)pNode)->setVerticalAlignment(TextVAlignment(pIntegerLabeled));
} else {
NodeLoader::onHandlePropTypeFloatScale(pNode, pParent, pPropertyName, pIntegerLabeled, ccbReader);
}
}
void LabelTTFLoader::onHandlePropTypeSize(Node * pNode, Node * pParent, const char * pPropertyName, Size pSize, CCBReader * ccbReader) {
void LabelTTFLoader::onHandlePropTypeSize(Node * pNode, Node * pParent, const char * pPropertyName, Size size, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_DIMENSIONS) == 0) {
((LabelTTF *)pNode)->setDimensions(pSize);
((Label *)pNode)->setDimensions(size.width,size.height);
} else {
NodeLoader::onHandlePropTypeSize(pNode, pParent, pPropertyName, pSize, ccbReader);
NodeLoader::onHandlePropTypeSize(pNode, pParent, pPropertyName, size, ccbReader);
}
}

View File

@ -2,7 +2,7 @@
#define _CCB_CCLABELTTFLOADER_H_
#include "CCRef.h"
#include "CCLabelTTF.h"
#include "CCLabel.h"
#include "CCNodeLoader.h"
@ -21,7 +21,7 @@ public:
CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(LabelTTFLoader, loader);
protected:
CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(cocos2d::LabelTTF);
CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(cocos2d::Label);
virtual void onHandlePropTypeColor3(cocos2d::Node * pNode, cocos2d::Node * pParent, const char * pPropertyName, cocos2d::Color3B pColor3B, CCBReader * ccbReader);
virtual void onHandlePropTypeByte(cocos2d::Node * pNode, cocos2d::Node * pParent, const char * pPropertyName, unsigned char pByte, CCBReader * ccbReader);

View File

@ -63,6 +63,7 @@ void ActionManagerEx::initWithDictionary(const char* jsonName,const rapidjson::V
int actionCount = DICTOOL->getArrayCount_json(dic, "actionlist");
for (int i=0; i<actionCount; i++) {
ActionObject* action = new ActionObject();
action->autorelease();
const rapidjson::Value &actionDic = DICTOOL->getDictionaryFromArray_json(dic, "actionlist", i);
action->initWithDictionary(actionDic,root);
actionList.pushBack(action);

View File

@ -241,7 +241,7 @@ void ActionNode::insertFrame(int index, ActionFrame* frame)
return;
}
int frameType = frame->getFrameType();
if(frameType < _frameArray.size())
if(frameType < (int)_frameArray.size())
{
auto cArray = _frameArray.at(frameType);
cArray->insert(index, frame);
@ -256,7 +256,7 @@ void ActionNode::addFrame(ActionFrame* frame)
}
int frameType = frame->getFrameType();
if(frameType < _frameArray.size())
if(frameType < (int)_frameArray.size())
{
auto cArray = _frameArray.at(frameType);
cArray->pushBack(frame);
@ -270,7 +270,7 @@ void ActionNode::deleteFrame(ActionFrame* frame)
return;
}
int frameType = frame->getFrameType();
if(frameType < _frameArray.size())
if(frameType < (int)_frameArray.size())
{
auto cArray = _frameArray.at(frameType);
cArray->eraseObject(frame);

View File

@ -97,6 +97,15 @@ bool ComAudio::serialize(void* r)
CC_BREAK_IF(resType != 0);
if (strcmp(className, "CCBackgroundAudio") == 0)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
// no MP3 support for CC_PLATFORM_WP8
std::string::size_type pos = filePath.find(".mp3");
if (pos == filePath.npos)
{
continue;
}
filePath.replace(pos, filePath.length(), ".wav");
#endif
preloadBackgroundMusic(filePath.c_str());
bool loop = DICTOOL->getIntValue_json(*v, "loop") != 0? true:false;
setLoop(loop);

View File

@ -43,6 +43,10 @@ bool ComController::init()
void ComController::onEnter()
{
if (_owner != nullptr)
{
_owner->scheduleUpdate();
}
}
void ComController::onExit()

View File

@ -39,13 +39,17 @@ ComRender::ComRender(void)
ComRender::ComRender(cocos2d::Node *node, const char *comName)
{
_render = node;
if (node != nullptr)
{
_render = node;
_render->retain();
}
_name.assign(comName);
}
ComRender::~ComRender(void)
{
_render = nullptr;
CC_SAFE_RELEASE_NULL(_render);
}
void ComRender::onEnter()
@ -58,7 +62,10 @@ void ComRender::onEnter()
void ComRender::onExit()
{
_render = nullptr;
if (_owner != nullptr)
{
_owner->removeChild(_render, true);
}
}
cocos2d::Node* ComRender::getNode()
@ -68,7 +75,16 @@ cocos2d::Node* ComRender::getNode()
void ComRender::setNode(cocos2d::Node *node)
{
_render = node;
if (_render != nullptr)
{
_render->release();
_render = nullptr;
}
if (node != nullptr)
{
_render = node;
_render->retain();
}
}
@ -111,15 +127,18 @@ bool ComRender::serialize(void* r)
if (strcmp(className, "CCSprite") == 0 && filePath.find(".png") != std::string::npos)
{
_render = Sprite::create(filePath.c_str());
_render->retain();
}
else if(strcmp(className, "CCTMXTiledMap") == 0 && filePath.find(".tmx") != std::string::npos)
{
_render = TMXTiledMap::create(filePath.c_str());
_render->retain();
}
else if(strcmp(className, "CCParticleSystemQuad") == 0 && filePath.find(".plist") != std::string::npos)
{
_render = ParticleSystemQuad::create(filePath.c_str());
_render->setPosition(Point(0.0f, 0.0f));
_render->retain();
}
else if(strcmp(className, "CCArmature") == 0)
{
@ -141,6 +160,7 @@ bool ComRender::serialize(void* r)
ArmatureDataManager::getInstance()->addArmatureFileInfo(filePath.c_str());
Armature *pAr = Armature::create(name);
_render = pAr;
_render->retain();
const char *actionName = DICTOOL->getStringValue_json(*v, "selectedactionname");
if (actionName != nullptr && pAr->getAnimation() != nullptr)
{
@ -151,6 +171,7 @@ bool ComRender::serialize(void* r)
{
cocos2d::ui::Widget* widget = GUIReader::getInstance()->widgetFromJsonFile(filePath.c_str());
_render = widget;
_render->retain();
}
else
{
@ -170,6 +191,7 @@ bool ComRender::serialize(void* r)
strPngFile.replace(pos, strPngFile.length(), ".png");
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(plistPath.c_str(), strPngFile.c_str());
_render = Sprite::createWithSpriteFrameName(filePath.c_str());
_render->retain();
}
else
{

View File

@ -37,6 +37,7 @@ SceneReader* SceneReader::s_sharedReader = nullptr;
SceneReader::SceneReader()
: _fnSelector(nullptr)
, _node(nullptr)
, _attachComponent(AttachComponentType::EMPTY_NODE)
{
ObjectFactory::getInstance()->registerType(CREATE_CLASS_COMPONENT_INFO(ComAttribute));
ObjectFactory::getInstance()->registerType(CREATE_CLASS_COMPONENT_INFO(ComRender));
@ -53,12 +54,12 @@ const char* SceneReader::sceneReaderVersion()
return "1.0.0.0";
}
cocos2d::Node* SceneReader::createNodeWithSceneFile(const std::string &fileName)
cocos2d::Node* SceneReader::createNodeWithSceneFile(const std::string &fileName, AttachComponentType attachComponent /*= AttachComponentType::EMPTY_NODE*/)
{
rapidjson::Document jsonDict;
do {
CC_BREAK_IF(!readJson(fileName, jsonDict));
_node = createObject(jsonDict, nullptr);
_node = createObject(jsonDict, nullptr, attachComponent);
TriggerMng::getInstance()->parse(jsonDict);
} while (0);
@ -110,7 +111,7 @@ Node* SceneReader::nodeByTag(Node *parent, int tag)
}
Node* SceneReader::createObject(const rapidjson::Value &dict, cocos2d::Node* parent)
Node* SceneReader::createObject(const rapidjson::Value &dict, cocos2d::Node* parent, AttachComponentType attachComponent)
{
const char *className = DICTOOL->getStringValue_json(dict, "classname");
if(strcmp(className, "CCNode") == 0)
@ -120,14 +121,9 @@ Node* SceneReader::createObject(const rapidjson::Value &dict, cocos2d::Node* par
{
gb = Node::create();
}
else
{
gb = Node::create();
parent->addChild(gb);
}
setPropertyFromJsonDict(dict, gb);
std::vector<Component*> vecComs;
ComRender *render = nullptr;
int count = DICTOOL->getArrayCount_json(dict, "components");
for (int i = 0; i < count; i++)
{
@ -138,23 +134,52 @@ Node* SceneReader::createObject(const rapidjson::Value &dict, cocos2d::Node* par
}
const char *comName = DICTOOL->getStringValue_json(subDict, "classname");
Component *com = ObjectFactory::getInstance()->createComponent(comName);
if (com != NULL)
{
if (com->serialize((void*)(&subDict)))
{
gb->addComponent(com);
}
else
if (com != nullptr)
{
if (com->serialize((void*)(&subDict)))
{
com = nullptr;
ComRender *tRender = dynamic_cast<ComRender*>(com);
if (tRender == nullptr)
{
vecComs.push_back(com);
}
else
{
render = tRender;
}
}
}
}
if(_fnSelector != nullptr)
{
_fnSelector(com, (void*)(&subDict));
}
}
if (parent != nullptr)
{
if (render == nullptr || attachComponent == AttachComponentType::EMPTY_NODE)
{
gb = Node::create();
if (render != nullptr)
{
vecComs.push_back(render);
}
}
else
{
gb = render->getNode();
gb->retain();
render->setNode(nullptr);
}
parent->addChild(gb);
}
setPropertyFromJsonDict(dict, gb);
for (std::vector<Component*>::iterator iter = vecComs.begin(); iter != vecComs.end(); ++iter)
{
gb->addComponent(*iter);
}
int length = DICTOOL->getArrayCount_json(dict, "gameobjects");
for (int i = 0; i < length; ++i)
{
@ -163,7 +188,7 @@ Node* SceneReader::createObject(const rapidjson::Value &dict, cocos2d::Node* par
{
break;
}
createObject(subDict, gb);
createObject(subDict, gb, attachComponent);
}
return gb;

View File

@ -30,9 +30,30 @@ THE SOFTWARE.
namespace cocostudio {
class SceneReader
{
public:
enum class AttachComponentType
{
///parent: Empty Node
/// ComRender(Sprite, Armature, TMXTiledMap, ParticleSystemQuad, GUIComponent)
/// ComAttribute
/// ComAudio
/// ....
EMPTY_NODE,
///parent: ComRender(Sprite, Armature, TMXTiledMap, ParticleSystemQuad, GUIComponent)
/// ComAttribute
/// ComAudio
/// .....
RENDER_NODE,
/// Default AttachComponentType is _EmptyNode
DEFAULT = EMPTY_NODE,
};
static SceneReader* getInstance();
/**
* @js purge
@ -40,22 +61,23 @@ public:
*/
static void destroyInstance();
static const char* sceneReaderVersion();
cocos2d::Node* createNodeWithSceneFile(const std::string &fileName);
void setTarget(const std::function<void(cocos2d::Ref* obj, void* doc)>& selector);
cocos2d::Node* getNodeByTag(int nTag);
cocos2d::Node* createNodeWithSceneFile(const std::string &fileName, AttachComponentType attachComponent = AttachComponentType::EMPTY_NODE);
void setTarget(const std::function<void(cocos2d::Ref* obj, void* doc)>& selector);
cocos2d::Node* getNodeByTag(int nTag);
inline AttachComponentType getAttachComponentType(){return _attachComponent;}
private:
SceneReader(void);
virtual ~SceneReader(void);
cocos2d::Node* createObject(const rapidjson::Value& dict, cocos2d::Node* parent);
cocos2d::Node* createObject(const rapidjson::Value& dict, cocos2d::Node* parent, AttachComponentType attachComponent);
void setPropertyFromJsonDict(const rapidjson::Value& dict, cocos2d::Node *node);
bool readJson(const std::string &fileName, rapidjson::Document& doc);
cocos2d::Node* nodeByTag(cocos2d::Node *parent, int tag);
cocos2d::Node* nodeByTag(cocos2d::Node *parent, int tag);
private:
static SceneReader* s_sharedReader;
std::function<void(cocos2d::Ref* obj, void* doc)> _fnSelector;
cocos2d::Node* _node;
cocos2d::Node* _node;
AttachComponentType _attachComponent;
};

View File

@ -126,8 +126,8 @@ void Skin::setSkinData(const BaseData &var)
setScaleX(_skinData.scaleX);
setScaleY(_skinData.scaleY);
setRotationX(CC_RADIANS_TO_DEGREES(_skinData.skewX));
setRotationY(CC_RADIANS_TO_DEGREES(-_skinData.skewY));
setRotationSkewX(CC_RADIANS_TO_DEGREES(_skinData.skewX));
setRotationSkewY(CC_RADIANS_TO_DEGREES(-_skinData.skewY));
setPosition(Point(_skinData.x, _skinData.y));
_skinTransform = getNodeToParentTransform();

Some files were not shown because too many files have changed in this diff Show More