Merge branch 'develop' of https://github.com/cocos2d/cocos2d-x into LayerGradientCtor

This commit is contained in:
pandamicro 2014-03-26 18:46:00 +08:00
commit c08bf69370
299 changed files with 6070 additions and 3584 deletions

View File

@ -787,6 +787,12 @@ Developers:
youknowone youknowone
Adds iOS-like elastic bounceback support for cocos2d::extension::ScrollView 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
Retired Core Developers: Retired Core Developers:
WenSheng Yang WenSheng Yang

View File

@ -1 +1 @@
a220377dfc7c4fce177d53c2fb3ab5baddf8e404 24725aaaf53bbf506d1ea378c6af1d9ff1e61c12

View File

@ -36,7 +36,7 @@ Example:
### Build and run new project for android ### ### 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 ### ### 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; 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, ...) Sequence* Sequence::create(FiniteTimeAction *action1, ...)
{ {
va_list params; va_list params;
@ -170,6 +183,7 @@ Sequence* Sequence::create(FiniteTimeAction *action1, ...)
return ret; return ret;
} }
#endif
Sequence* Sequence::createWithVariableList(FiniteTimeAction *action1, va_list args) Sequence* Sequence::createWithVariableList(FiniteTimeAction *action1, va_list args)
{ {
@ -532,6 +546,19 @@ RepeatForever *RepeatForever::reverse() const
// Spawn // 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, ...) Spawn* Spawn::create(FiniteTimeAction *action1, ...)
{ {
va_list params; va_list params;
@ -543,6 +570,7 @@ Spawn* Spawn::create(FiniteTimeAction *action1, ...)
return ret; return ret;
} }
#endif
Spawn* Spawn::createWithVariableList(FiniteTimeAction *action1, va_list args) Spawn* Spawn::createWithVariableList(FiniteTimeAction *action1, va_list args)
{ {

View File

@ -93,7 +93,26 @@ class CC_DLL Sequence : public ActionInterval
{ {
public: public:
/** helper constructor to create an array of sequenceable actions */ /** 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; static Sequence* create(FiniteTimeAction *action1, ...) CC_REQUIRES_NULL_TERMINATION;
#endif
/** helper constructor to create an array of sequenceable actions given an array /** helper constructor to create an array of sequenceable actions given an array
* @code * @code
* When this funtion bound to the js or lua,the input params changed * 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, ...) * in lua :local create(local object1,local object2, ...)
* @endcode * @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; static Spawn* create(FiniteTimeAction *action1, ...) CC_REQUIRES_NULL_TERMINATION;
#endif
/** helper constructor to create an array of spawned actions */ /** helper constructor to create an array of spawned actions */
static Spawn* createWithVariableList(FiniteTimeAction *action1, va_list args); static Spawn* createWithVariableList(FiniteTimeAction *action1, va_list args);

View File

@ -67,7 +67,7 @@ public:
void setOwner(Node *pOwner); void setOwner(Node *pOwner);
Node* getOwner() const; Node* getOwner() const;
protected: protected:
Node *_owner; Node *_owner;
std::string _name; std::string _name;

View File

@ -61,7 +61,6 @@ bool ComponentContainer::add(Component *com)
if (_components == nullptr) if (_components == nullptr)
{ {
_components = new Map<std::string, Component*>(); _components = new Map<std::string, Component*>();
_owner->scheduleUpdate();
} }
Component *component = _components->at(com->getName()); 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 kTargetNaCl = Application::Platform::OS_NACL;
CC_DEPRECATED_ATTRIBUTE const Application::Platform kTargetEmscripten = Application::Platform::OS_EMSCRIPTEN; 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 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 typedef Application::Platform TargetPlatform;
CC_DEPRECATED_ATTRIBUTE const ResolutionPolicy kResolutionExactFit = ResolutionPolicy::EXACT_FIT; CC_DEPRECATED_ATTRIBUTE const ResolutionPolicy kResolutionExactFit = ResolutionPolicy::EXACT_FIT;

View File

@ -45,6 +45,7 @@ THE SOFTWARE.
#include "platform/CCFileUtils.h" #include "platform/CCFileUtils.h"
#include "CCApplication.h" #include "CCApplication.h"
#include "CCFontFNT.h" #include "CCFontFNT.h"
#include "CCFontAtlasCache.h"
#include "CCActionManager.h" #include "CCActionManager.h"
#include "CCAnimationCache.h" #include "CCAnimationCache.h"
#include "CCTouch.h" #include "CCTouch.h"
@ -157,8 +158,10 @@ bool Director::init(void)
initTextureCache(); initTextureCache();
_renderer = new Renderer; _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; return true;
} }
@ -182,7 +185,10 @@ Director::~Director(void)
delete _eventProjectionChanged; delete _eventProjectionChanged;
delete _renderer; delete _renderer;
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
delete _console; delete _console;
#endif
// clean auto release pool // clean auto release pool
PoolManager::destroyInstance(); PoolManager::destroyInstance();
@ -432,6 +438,12 @@ void Director::setProjection(Projection projection)
case Projection::_2D: case Projection::_2D:
kmGLMatrixMode(KM_GL_PROJECTION); kmGLMatrixMode(KM_GL_PROJECTION);
kmGLLoadIdentity(); kmGLLoadIdentity();
#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
if(getOpenGLView() != nullptr)
{
kmGLMultMatrix( getOpenGLView()->getOrientationMatrix());
}
#endif
kmMat4 orthoMatrix; kmMat4 orthoMatrix;
kmMat4OrthographicProjection(&orthoMatrix, 0, size.width, 0, size.height, -1024, 1024); kmMat4OrthographicProjection(&orthoMatrix, 0, size.width, 0, size.height, -1024, 1024);
kmGLMultMatrix(&orthoMatrix); kmGLMultMatrix(&orthoMatrix);
@ -447,7 +459,15 @@ void Director::setProjection(Projection projection)
kmGLMatrixMode(KM_GL_PROJECTION); kmGLMatrixMode(KM_GL_PROJECTION);
kmGLLoadIdentity(); 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 // issue #1334
kmMat4PerspectiveProjection(&matrixPerspective, 60, (GLfloat)size.width/size.height, 10, zeye+size.height/2); kmMat4PerspectiveProjection(&matrixPerspective, 60, (GLfloat)size.width/size.height, 10, zeye+size.height/2);
// kmMat4PerspectiveProjection( &matrixPerspective, 60, (GLfloat)size.width/size.height, 0.1f, 1500); // kmMat4PerspectiveProjection( &matrixPerspective, 60, (GLfloat)size.width/size.height, 0.1f, 1500);
@ -485,10 +505,16 @@ void Director::setProjection(Projection projection)
void Director::purgeCachedData(void) void Director::purgeCachedData(void)
{ {
FontFNT::purgeCachedData(); FontFNT::purgeCachedData();
FontAtlasCache::purgeCachedData();
if (s_SharedDirector->getOpenGLView()) if (s_SharedDirector->getOpenGLView())
{ {
SpriteFrameCache::getInstance()->removeUnusedSpriteFrames(); SpriteFrameCache::getInstance()->removeUnusedSpriteFrames();
_textureCache->removeUnusedTextures(); _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(); FileUtils::getInstance()->purgeCachedEntries();
} }
@ -533,6 +559,11 @@ static void GLToClipTransform(kmMat4 *transformOut)
kmMat4 projection; kmMat4 projection;
kmGLGetMatrix(KM_GL_PROJECTION, &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; kmMat4 modelview;
kmGLGetMatrix(KM_GL_MODELVIEW, &modelview); kmGLGetMatrix(KM_GL_MODELVIEW, &modelview);

View File

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

View File

@ -590,7 +590,7 @@ void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, c
// priority < 0 // priority < 0
if (fixedPriorityListeners) 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()) if (!fixedPriorityListeners->empty())
{ {

View File

@ -185,7 +185,9 @@ void FontAtlas::listenToForeground(EventCustom *event)
auto contentSize = Size(CacheTextureWidth,CacheTextureHeight); auto contentSize = Size(CacheTextureWidth,CacheTextureHeight);
auto pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8; 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 #endif
@ -231,6 +233,8 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
auto pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8; auto pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8;
bool existNewLetter = false; bool existNewLetter = false;
int bottomHeight = _commonLineHeight - _fontAscender;
for (int i = 0; i < length; ++i) for (int i = 0; i < length; ++i)
{ {
auto outIterator = _fontLetterDefinitions.find(utf16String[i]); auto outIterator = _fontLetterDefinitions.find(utf16String[i]);
@ -248,14 +252,17 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
tempDef.height = tempRect.size.height + _letterPadding; tempDef.height = tempRect.size.height + _letterPadding;
tempDef.offsetX = tempRect.origin.x + offsetAdjust; tempDef.offsetX = tempRect.origin.x + offsetAdjust;
tempDef.offsetY = _fontAscender + tempRect.origin.y - offsetAdjust; tempDef.offsetY = _fontAscender + tempRect.origin.y - offsetAdjust;
tempDef.clipBottom = bottomHeight - (tempDef.height + tempRect.origin.y + offsetAdjust);
if (_currentPageOrigX + tempDef.width > CacheTextureWidth) if (_currentPageOrigX + tempDef.width > CacheTextureWidth)
{ {
_currentPageOrigY += _commonLineHeight; _currentPageOrigY += _commonLineHeight;
_currentPageOrigX = 0; _currentPageOrigX = 0;
if(_currentPageOrigY + _commonLineHeight >= CacheTextureHeight) 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; _currentPageOrigY = 0;
memset(_currentPageData, 0, _currentPageDataSize); memset(_currentPageData, 0, _currentPageDataSize);
_currentPage++; _currentPage++;
@ -290,6 +297,7 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
tempDef.offsetX = 0; tempDef.offsetX = 0;
tempDef.offsetY = 0; tempDef.offsetY = 0;
tempDef.textureID = 0; tempDef.textureID = 0;
tempDef.clipBottom = 0;
_currentPageOrigX += 1; _currentPageOrigX += 1;
} }
@ -299,6 +307,8 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
if(existNewLetter) 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 ); _atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
} }
return true; return true;

View File

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

View File

@ -52,9 +52,11 @@ FontAtlas * FontAtlasCache::getFontAtlasTTF(const TTFConfig & config)
useDistanceField = false; useDistanceField = false;
} }
int fontSize = config.fontSize; int fontSize = config.fontSize;
auto contentScaleFactor = CC_CONTENT_SCALE_FACTOR();
if (useDistanceField) if (useDistanceField)
{ {
fontSize = Label::DistanceFieldFontSize / CC_CONTENT_SCALE_FACTOR(); fontSize = Label::DistanceFieldFontSize / contentScaleFactor;
} }
std::string atlasName = generateFontName(config.fontFilePath, fontSize, GlyphCollection::DYNAMIC, useDistanceField); std::string atlasName = generateFontName(config.fontFilePath, fontSize, GlyphCollection::DYNAMIC, useDistanceField);
@ -67,7 +69,8 @@ FontAtlas * FontAtlasCache::getFontAtlasTTF(const TTFConfig & config)
if ( !tempAtlas ) 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) if (font)
{ {
tempAtlas = font->createFontAtlas(); 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 * data = (double *) calloc( pixelAmount, sizeof(double) );
double * outside = (double *) calloc( pixelAmount, sizeof(double) ); double * outside = (double *) calloc( pixelAmount, sizeof(double) );
double * inside = (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 // Convert img into double (data) rescale image levels between 0 and 1
long outWidth = width + 2 * FontFreeType::DistanceMapSpread; long outWidth = width + 2 * FontFreeType::DistanceMapSpread;

View File

@ -26,15 +26,29 @@
#ifndef _FontFreetype_h_ #ifndef _FontFreetype_h_
#define _FontFreetype_h_ #define _FontFreetype_h_
#include "CCFont.h" #include "CCFont.h"
#include "CCData.h" #include "CCData.h"
#include <string> #include <string>
#include <ft2build.h> #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_FREETYPE_H
#include FT_STROKER_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 NS_CC_BEGIN
class CC_DLL FontFreeType : public Font class CC_DLL FontFreeType : public Font

View File

@ -37,6 +37,10 @@ THE SOFTWARE.
#include "kazmath/GL/matrix.h" #include "kazmath/GL/matrix.h"
#include "kazmath/kazmath.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 NS_CC_BEGIN
typedef struct _hashUniformEntry typedef struct _hashUniformEntry
@ -116,6 +120,18 @@ GLProgram::~GLProgram()
bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray) 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(); _program = glCreateProgram();
CHECK_GL_ERROR_DEBUG(); CHECK_GL_ERROR_DEBUG();
@ -126,7 +142,8 @@ bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar*
if (!compileShader(&_vertShader, GL_VERTEX_SHADER, vShaderByteArray)) if (!compileShader(&_vertShader, GL_VERTEX_SHADER, vShaderByteArray))
{ {
CCLOG("cocos2d: ERROR: Failed to compile vertex shader"); CCLOG("cocos2d: ERROR: Failed to compile vertex shader");
} return false;
}
} }
// Create and compile fragment shader // Create and compile fragment shader
@ -135,6 +152,7 @@ bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar*
if (!compileShader(&_fragShader, GL_FRAGMENT_SHADER, fShaderByteArray)) if (!compileShader(&_fragShader, GL_FRAGMENT_SHADER, fShaderByteArray))
{ {
CCLOG("cocos2d: ERROR: Failed to compile fragment shader"); 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(); 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; 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) bool GLProgram::initWithFilenames(const std::string &vShaderFilename, const std::string &fShaderFilename)
{ {
auto fileUtils = FileUtils::getInstance(); auto fileUtils = FileUtils::getInstance();
@ -275,6 +318,15 @@ bool GLProgram::link()
{ {
CCASSERT(_program != 0, "Cannot link invalid program"); 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; GLint status = GL_TRUE;
glLinkProgram(_program); glLinkProgram(_program);
@ -291,7 +343,7 @@ bool GLProgram::link()
_vertShader = _fragShader = 0; _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); glGetProgramiv(_program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) if (status == GL_FALSE)
@ -301,7 +353,14 @@ bool GLProgram::link()
_program = 0; _program = 0;
} }
#endif #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); return (status == GL_TRUE);
} }

View File

@ -126,7 +126,18 @@ public:
* @js initWithString * @js initWithString
* @lua 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); bool initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray);
/** Initializes the GLProgram with a vertex and fragment with contents of filenames /** Initializes the GLProgram with a vertex and fragment with contents of filenames
* @js init * @js init
* @lua init * @lua init
@ -266,6 +277,10 @@ private:
GLuint _fragShader; GLuint _fragShader;
GLint _uniforms[UNIFORM_MAX]; GLint _uniforms[UNIFORM_MAX];
struct _hashUniformEntry* _hashForUniforms; 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 { struct flag_struct {
unsigned int usesTime:1; unsigned int usesTime:1;

View File

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

View File

@ -217,6 +217,10 @@ public:
virtual Sprite * getLetter(int lettetIndex); 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 // font related stuff
int getCommonLineHeight() const; int getCommonLineHeight() const;
@ -300,6 +304,8 @@ protected:
void drawShadowWithoutBlur(); void drawShadowWithoutBlur();
void drawTextSprite(Renderer *renderer, bool parentTransformUpdated);
void createSpriteWithFontDefinition(); void createSpriteWithFontDefinition();
void updateFont(); void updateFont();
@ -358,13 +364,18 @@ protected:
GLuint _uniformTextColor; GLuint _uniformTextColor;
CustomCommand _customCommand; CustomCommand _customCommand;
bool _shadowEnabled;
Size _shadowOffset; Size _shadowOffset;
int _shadowBlurRadius; int _shadowBlurRadius;
kmMat4 _parentTransform; kmMat4 _parentTransform;
Color3B _shadowColor;
Node* _shadowNode;
Color4B _textColor; Color4B _textColor;
Color4F _textColorF; Color4F _textColorF;
bool _clipEnabled;
private: private:
CC_DISALLOW_COPY_AND_ASSIGN(Label); CC_DISALLOW_COPY_AND_ASSIGN(Label);

View File

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

View File

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

View File

@ -321,6 +321,16 @@ bool LabelTextFormatter::createStringSprites(Label *theLabel)
FontLetterDefinition tempDefinition; FontLetterDefinition tempDefinition;
Point letterPosition; Point letterPosition;
const auto& kernings = theLabel->_horizontalKernings; 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++) for (unsigned int i = 0; i < stringLen; i++)
{ {
@ -337,9 +347,10 @@ bool LabelTextFormatter::createStringSprites(Label *theLabel)
charYOffset = -1; charYOffset = -1;
charAdvance = -1; charAdvance = -1;
} }
if (c == '\n') if (c == '\n')
{ {
lineIndex++;
nextFontPositionX = 0; nextFontPositionX = 0;
nextFontPositionY -= theLabel->_commonLineHeight; nextFontPositionY -= theLabel->_commonLineHeight;
@ -347,8 +358,30 @@ bool LabelTextFormatter::createStringSprites(Label *theLabel)
if(nextFontPositionY < theLabel->_commonLineHeight) if(nextFontPositionY < theLabel->_commonLineHeight)
break; break;
lineStart = true;
continue; 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.x = (nextFontPositionX + charXOffset + kernings[i]) / contentScaleFactor;
letterPosition.y = (nextFontPositionY - charYOffset) / contentScaleFactor; letterPosition.y = (nextFontPositionY - charYOffset) / contentScaleFactor;
@ -382,11 +415,26 @@ bool LabelTextFormatter::createStringSprites(Label *theLabel)
} }
tmpSize.height = totalHeight; tmpSize.height = totalHeight;
if (theLabel->_labelHeight > 0) if (theLabel->_labelHeight > 0)
{ {
tmpSize.height = theLabel->_labelHeight * contentScaleFactor; 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)); theLabel->setContentSize(CC_SIZE_PIXELS_TO_POINTS(tmpSize));
return true; return true;
} }

View File

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

View File

@ -435,7 +435,25 @@ public:
* In lua:local create(...) * In lua:local create(...)
* @endcode * @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, ... ); static LayerMultiplex * create(Layer* layer, ... );
#endif
/** /**
* lua script can not init with undetermined number of variables * 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); CCLOGINFO("In the destructor of Menu. %p", this);
} }
Menu* Menu::create() Menu* Menu::create()
{ {
return Menu::create(nullptr, nullptr); 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, ...) Menu * Menu::create(MenuItem* item, ...)
{ {
va_list args; va_list args;
@ -69,6 +85,8 @@ Menu * Menu::create(MenuItem* item, ...)
return ret; return ret;
} }
#endif
Menu* Menu::createWithArray(const Vector<MenuItem*>& arrayOfItems) Menu* Menu::createWithArray(const Vector<MenuItem*>& arrayOfItems)
{ {

View File

@ -60,9 +60,27 @@ public:
/** creates an empty Menu */ /** creates an empty Menu */
static Menu* create(); 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 */ /** creates a Menu with MenuItem objects */
static Menu* create(MenuItem* item, ...) CC_REQUIRES_NULL_TERMINATION; static Menu* create(MenuItem* item, ...) CC_REQUIRES_NULL_TERMINATION;
#endif
/** creates a Menu with a Array of MenuItem objects */ /** creates a Menu with a Array of MenuItem objects */
static Menu* createWithArray(const Vector<MenuItem*>& arrayOfItems); static Menu* createWithArray(const Vector<MenuItem*>& arrayOfItems);
@ -136,6 +154,9 @@ CC_CONSTRUCTOR_ACCESS:
bool initWithArray(const Vector<MenuItem*>& arrayOfItems); bool initWithArray(const Vector<MenuItem*>& arrayOfItems);
protected: protected:
/** whether or not the menu will receive events */ /** whether or not the menu will receive events */
bool _enabled; bool _enabled;

View File

@ -178,9 +178,9 @@ void MenuItemLabel::setLabel(Node* var)
{ {
if (var) if (var)
{ {
var->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
setContentSize(var->getContentSize());
addChild(var); addChild(var);
var->setAnchorPoint(Point(0, 0));
setContentSize(var->getContentSize());
} }
if (_label) 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. // 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) Node::Node(void)
: _rotationX(0.0f) : _rotationX(0.0f)

View File

@ -1452,11 +1452,13 @@ protected:
bool _cascadeColorEnabled; bool _cascadeColorEnabled;
bool _cascadeOpacityEnabled; bool _cascadeOpacityEnabled;
static int s_globalOrderOfArrival;
private: private:
CC_DISALLOW_COPY_AND_ASSIGN(Node); CC_DISALLOW_COPY_AND_ASSIGN(Node);
}; };
//#pragma mark - NodeRGBA // NodeRGBA
/** NodeRGBA is a subclass of Node that implements the RGBAProtocol protocol. /** 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.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(); modeB.rotatePerSecond = dictionary["rotatePerSecond"].asInt();
} }
@ -468,8 +477,6 @@ bool ParticleSystem::initWithTotalParticles(int numberOfParticles)
//updateParticleImp = (CC_UPDATE_PARTICLE_IMP) [self methodForSelector:updateParticleSel]; //updateParticleImp = (CC_UPDATE_PARTICLE_IMP) [self methodForSelector:updateParticleSel];
//for batchNode //for batchNode
_transformSystemDirty = false; _transformSystemDirty = false;
// update after action in run!
this->scheduleUpdateWithPriority(1);
return true; 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() void ParticleSystem::stopSystem()
{ {
_isActive = false; _isActive = false;

View File

@ -125,6 +125,13 @@ emitter.startSpin = 0;
@endcode @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 class CC_DLL ParticleSystem : public Node, public TextureProtocol
{ {
public: public:
@ -184,6 +191,7 @@ public:
//! whether or not the system is full //! whether or not the system is full
bool isFull(); bool isFull();
virtual void onEnter();
//! should be overridden by subclasses //! should be overridden by subclasses
virtual void updateQuadWithParticle(tParticle* particle, const Point& newPosition); virtual void updateQuadWithParticle(tParticle* particle, const Point& newPosition);
//! should be overridden by subclasses //! should be overridden by subclasses

View File

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

View File

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

View File

@ -41,8 +41,8 @@ bool CC_DLL cc_assert_script_compatible(const char *msg)
NS_CC_BEGIN NS_CC_BEGIN
// #pragma mark - //
// #pragma mark ScriptHandlerEntry // // ScriptHandlerEntry
ScriptHandlerEntry* ScriptHandlerEntry::create(int handler) 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) 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, TouchScriptHandlerEntry* TouchScriptHandlerEntry::create(int handler,
bool isMultiTouches, bool isMultiTouches,
@ -115,8 +115,8 @@ bool TouchScriptHandlerEntry::init(bool isMultiTouches, int priority, bool swall
return true; return true;
} }
// #pragma mark - //
// #pragma mark ScriptEngineManager // // ScriptEngineManager
static ScriptEngineManager* s_pSharedScriptEngineManager = nullptr; static ScriptEngineManager* s_pSharedScriptEngineManager = nullptr;

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(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(_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; TMXTileFlags currentFlags;
uint32_t currentGID = getTileGIDAt(pos, &currentFlags); uint32_t currentGID = getTileGIDAt(pos, &currentFlags);

View File

@ -55,7 +55,7 @@ TextFieldTTF::TextFieldTTF()
: _delegate(0) : _delegate(0)
, _charCount(0) , _charCount(0)
, _inputText("") , _inputText("")
, _placeHolder("") // prevent LabelTTF initWithString assertion , _placeHolder("") // prevent Label initWithString assertion
, _secureTextEntry(false) , _secureTextEntry(false)
{ {
_colorSpaceHolder.r = _colorSpaceHolder.g = _colorSpaceHolder.b = 127; _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 * TextFieldTTF::textFieldWithPlaceHolder(const std::string& placeholder, const std::string& fontName, float fontSize)
{ {
TextFieldTTF *ret = new TextFieldTTF(); TextFieldTTF *ret = new TextFieldTTF();
if(ret && ret->initWithString("", fontName, fontSize)) if(ret && ret->initWithPlaceHolder("", fontName, fontSize))
{ {
ret->autorelease(); ret->autorelease();
if (placeholder.size()>0) 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) bool TextFieldTTF::initWithPlaceHolder(const std::string& placeholder, const Size& dimensions, TextHAlignment alignment, const std::string& fontName, float fontSize)
{ {
_placeHolder = placeholder; _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) bool TextFieldTTF::initWithPlaceHolder(const std::string& placeholder, const std::string& fontName, float fontSize)
{ {
_placeHolder = std::string(placeholder); _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 = ""; _inputText = "";
_charCount = 0; _charCount = 0;
LabelTTF::setString(_placeHolder); Label::setString(_placeHolder);
return; return;
} }
@ -242,23 +252,19 @@ const std::string& TextFieldTTF::getContentText()
return _inputText; return _inputText;
} }
void TextFieldTTF::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) void TextFieldTTF::setColor(const Color3B& color)
{ {
if (_delegate && _delegate->onDraw(this)) _colorText = color;
{ Label::setColor(color);
return; }
}
if (_inputText.length())
{
LabelTTF::draw(renderer, transform, transformUpdated);
return;
}
// draw placeholder void TextFieldTTF::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
Color3B color = getColor(); {
setColor(_colorSpaceHolder); if (_delegate && _delegate->onVisit(this,renderer,parentTransform,parentTransformUpdated))
LabelTTF::draw(renderer, transform, transformUpdated); {
setColor(color); return;
}
Label::visit(renderer,parentTransform,parentTransformUpdated);
} }
const Color3B& TextFieldTTF::getColorSpaceHolder() 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 there is no input text, display placeholder instead
if (! _inputText.length()) if (! _inputText.length())
{ {
LabelTTF::setString(_placeHolder); Label::setColor(_colorSpaceHolder);
Label::setString(_placeHolder);
} }
else else
{ {
LabelTTF::setString(displayText); Label::setColor(_colorText);
Label::setString(displayText);
} }
_charCount = _calcCharCount(_inputText.c_str()); _charCount = _calcCharCount(_inputText.c_str());
} }
@ -325,7 +333,7 @@ void TextFieldTTF::setPlaceHolder(const std::string& text)
_placeHolder = text; _placeHolder = text;
if (! _inputText.length()) if (! _inputText.length())
{ {
LabelTTF::setString(_placeHolder); Label::setString(_placeHolder);
} }
} }

View File

@ -26,7 +26,7 @@ THE SOFTWARE.
#ifndef __CC_TEXT_FIELD_H__ #ifndef __CC_TEXT_FIELD_H__
#define __CC_TEXT_FIELD_H__ #define __CC_TEXT_FIELD_H__
#include "CCLabelTTF.h" #include "CCLabel.h"
#include "CCIMEDelegate.h" #include "CCIMEDelegate.h"
NS_CC_BEGIN NS_CC_BEGIN
@ -86,7 +86,7 @@ public:
/** /**
@brief If the sender doesn't want to draw, return true. @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); CC_UNUSED_PARAM(sender);
return false; return false;
@ -96,7 +96,7 @@ public:
/** /**
@brief A simple text input field with TTF font. @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: public:
/** /**
@ -113,7 +113,7 @@ public:
/** creates a TextFieldTTF from a fontname, alignment, dimension and font size */ /** 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); 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); 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 */ /** 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); 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 const Color3B& getColorSpaceHolder();
virtual void setColorSpaceHolder(const Color3B& color); virtual void setColorSpaceHolder(const Color3B& color);
virtual void setColor(const Color3B& color) override;
// input text property // input text property
public:
virtual void setString(const std::string& text) override; virtual void setString(const std::string& text) override;
virtual const std::string& getString() const override; virtual const std::string& getString() const override;
protected:
TextFieldDelegate * _delegate;
int _charCount;
std::string _inputText;
// place holder text property // place holder text property
// place holder text displayed when there is no text in the text field. // place holder text displayed when there is no text in the text field.
public:
virtual void setPlaceHolder(const std::string& text); virtual void setPlaceHolder(const std::string& text);
virtual const std::string& getPlaceHolder(void) const; virtual const std::string& getPlaceHolder(void) const;
protected:
std::string _placeHolder;
Color3B _colorSpaceHolder;
public:
virtual void setSecureTextEntry(bool value); virtual void setSecureTextEntry(bool value);
virtual bool isSecureTextEntry(); 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 // IMEDelegate interface
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -184,6 +174,18 @@ protected:
virtual void insertText(const char * text, size_t len) override; virtual void insertText(const char * text, size_t len) override;
virtual void deleteBackward() override; virtual void deleteBackward() override;
virtual const std::string& getContentText() override; virtual const std::string& getContentText() override;
TextFieldDelegate * _delegate;
int _charCount;
std::string _inputText;
std::string _placeHolder;
Color3B _colorSpaceHolder;
Color3B _colorText;
bool _secureTextEntry;
private: private:
class LengthStack; class LengthStack;
LengthStack * _lens; LengthStack * _lens;

View File

@ -51,6 +51,8 @@ THE SOFTWARE.
NS_CC_BEGIN NS_CC_BEGIN
namespace { namespace {
typedef Texture2D::PixelFormatInfoMap::value_type PixelFormatInfoMapValue; typedef Texture2D::PixelFormatInfoMap::value_type PixelFormatInfoMapValue;
static const PixelFormatInfoMapValue TexturePixelFormatInfoTablesValue[] = 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) 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 //the pixelFormat must be a certain value
CCASSERT(pixelFormat != PixelFormat::NONE && pixelFormat != PixelFormat::AUTO, "the \"pixelFormat\" param 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"); 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) #if (CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID) && (CC_TARGET_PLATFORM != CC_PLATFORM_IOS)
bool requestUnsupported = textDefinition._shadow._shadowEnabled || textDefinition._stroke._strokeEnabled; CCASSERT(textDefinition._stroke._strokeEnabled == false, "Currently stroke only supported on iOS and Android!");
CCASSERT(requestUnsupported == false, "Currently shadow and stroke only supported on iOS and Android!");
#endif #endif
PixelFormat pixelFormat = g_defaultAlphaPixelFormat; PixelFormat pixelFormat = g_defaultAlphaPixelFormat;
@ -1088,6 +1097,9 @@ bool Texture2D::initWithString(const char *text, const FontDefinition& textDefin
textDef._fontSize *= contentScaleFactor; textDef._fontSize *= contentScaleFactor;
textDef._dimensions.width *= contentScaleFactor; textDef._dimensions.width *= contentScaleFactor;
textDef._dimensions.height *= contentScaleFactor; textDef._dimensions.height *= contentScaleFactor;
textDef._stroke._strokeSize *= contentScaleFactor;
textDef._shadow._shadowEnabled = false;
Data outData = Device::getTextureDataForText(text,textDef,align,imageWidth,imageHeight); Data outData = Device::getTextureDataForText(text,textDef,align,imageWidth,imageHeight);
if(outData.isNull()) if(outData.isNull())
return false; return false;
@ -1199,6 +1211,9 @@ void Texture2D::generateMipmap()
GL::bindTexture2D( _name ); GL::bindTexture2D( _name );
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
_hasMipmaps = true; _hasMipmaps = true;
#if CC_ENABLE_CACHE_TEXTURE_DATA
VolatileTextureMgr::setHasMipmaps(this, _hasMipmaps);
#endif
} }
bool Texture2D::hasMipmaps() const bool Texture2D::hasMipmaps() const

View File

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

View File

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

View File

@ -32,7 +32,7 @@ THE SOFTWARE.
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/CCFileUtilsAndroid.h" #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 // for import ssize_t on win32 platform
#include "CCStdC.h" #include "CCStdC.h"
#endif #endif

View File

@ -278,8 +278,8 @@ void ccArrayFullRemoveArray(ccArray *arr, ccArray *minusArr)
arr->num -= back; 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 */ /** Allocates and initializes a new C array with specified capacity */
ccCArray* ccCArrayNew(ssize_t 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. */ matching instances in arr will be removed. */
void ccArrayFullRemoveArray(ccArray *arr, ccArray *minusArr); void ccArrayFullRemoveArray(ccArray *arr, ccArray *minusArr);
// #pragma mark - //
// #pragma mark ccCArray for Values (c structures) // // ccCArray for Values (c structures)
typedef struct _ccCArray { typedef struct _ccCArray {
ssize_t num, max; 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 ) 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 ) void setProjectionMatrixDirty( void )
{ {

View File

@ -195,6 +195,22 @@ THE SOFTWARE.
#include "platform/linux/CCStdC.h" #include "platform/linux/CCStdC.h"
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_LINUX #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 // script_support
#include "CCScriptSupport.h" #include "CCScriptSupport.h"

View File

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

View File

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

View File

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

View File

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

View File

@ -46,7 +46,9 @@ extern "C"
#include "atitc.h" #include "atitc.h"
#include "TGAlib.h" #include "TGAlib.h"
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WP8) && (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)
#include "decode.h" #include "decode.h"
#endif
#include "ccMacros.h" #include "ccMacros.h"
#include "CCCommon.h" #include "CCCommon.h"
@ -1832,7 +1834,11 @@ bool Image::initWithPVRData(const unsigned char * data, ssize_t dataLen)
bool Image::initWithWebpData(const unsigned char * data, ssize_t dataLen) bool Image::initWithWebpData(const unsigned char * data, ssize_t dataLen)
{ {
bool bRet = false; 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 do
{ {
WebPDecoderConfig config; WebPDecoderConfig config;
@ -1862,9 +1868,11 @@ bool Image::initWithWebpData(const unsigned char * data, ssize_t dataLen)
bRet = true; bRet = true;
} while (0); } while (0);
#endif
return bRet; return bRet;
} }
bool Image::initWithRawData(const unsigned char * data, ssize_t dataLen, int width, int height, int bitsPerComponent, bool preMulti) bool Image::initWithRawData(const unsigned char * data, ssize_t dataLen, int width, int height, int bitsPerComponent, bool preMulti)
{ {
bool bRet = false; bool bRet = false;

View File

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

View File

@ -12,12 +12,15 @@ CCCommon.cpp \
CCDevice.cpp \ CCDevice.cpp \
CCGLView.cpp \ CCGLView.cpp \
CCFileUtilsAndroid.cpp \ CCFileUtilsAndroid.cpp \
nativeactivity.cpp \ javaactivity.cpp \
jni/DPIJni.cpp \ jni/DPIJni.cpp \
jni/IMEJni.cpp \ jni/IMEJni.cpp \
jni/Java_org_cocos2dx_lib_Cocos2dxAccelerometer.cpp \
jni/Java_org_cocos2dx_lib_Cocos2dxBitmap.cpp \ jni/Java_org_cocos2dx_lib_Cocos2dxBitmap.cpp \
jni/Java_org_cocos2dx_lib_Cocos2dxHelper.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) LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
@ -41,7 +44,7 @@ LOCAL_EXPORT_LDLIBS := -lGLESv1_CM \
-lz \ -lz \
-landroid -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) include $(BUILD_STATIC_LIBRARY)
@ -50,4 +53,3 @@ $(call import-module,jpeg/prebuilt/android)
$(call import-module,png/prebuilt/android) $(call import-module,png/prebuilt/android)
$(call import-module,tiff/prebuilt/android) $(call import-module,tiff/prebuilt/android)
$(call import-module,webp/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 <jni.h>
#include "ccTypes.h" #include "ccTypes.h"
#include "jni/DPIJni.h" #include "jni/DPIJni.h"
#include "jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h"
#include "jni/JniHelper.h" #include "jni/JniHelper.h"
#include "nativeactivity.h"
#include "platform/CCFileUtils.h" #include "platform/CCFileUtils.h"
NS_CC_BEGIN 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.graphics.Typeface;
import android.text.TextPaint; import android.text.TextPaint;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.FloatMath;
import android.util.Log; import android.util.Log;
public class Cocos2dxBitmap { public class Cocos2dxBitmap {
@ -119,7 +118,7 @@ public class Cocos2dxBitmap {
*/ */
if(0 != width) 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) if ( firstWordWidth > width)
{ {
Log.w("createTextBitmapShadowStroke warning:","the input width is less than the width of the pString's first word\n"); 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 renderTextDeltaX = 0.0f;
float renderTextDeltaY = 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) if (0 == textProperty.mMaxWidth || 0 == bitmapTotalHeight)
{ {
Log.w("createTextBitmapShadowStroke warning:","textProperty MaxWidth is 0 or bitMapTotalHeight is 0\n"); Log.w("createTextBitmapShadowStroke warning:","textProperty MaxWidth is 0 or bitMapTotalHeight is 0\n");
@ -173,41 +153,44 @@ public class Cocos2dxBitmap {
/* Draw string. */ /* Draw string. */
final FontMetricsInt fontMetricsInt = paint.getFontMetricsInt(); 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 // draw again with stroke on if needed
if ( stroke ) { if ( stroke )
{
final Paint paintStroke = Cocos2dxBitmap.newPaint(fontName, fontSize, horizontalAlignment); final Paint paintStroke = Cocos2dxBitmap.newPaint(fontName, fontSize, horizontalAlignment);
paintStroke.setStyle(Paint.Style.STROKE); 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)); paintStroke.setARGB(255, (int) (strokeR * 255), (int) (strokeG * 255), (int) (strokeB * 255));
x = 0; int x = 0;
y = Cocos2dxBitmap.computeY(fontMetricsInt, height, textProperty.mTotalHeight, verticalAlignment); int y = Cocos2dxBitmap.computeY(fontMetricsInt, height, textProperty.mTotalHeight, verticalAlignment);
final String[] lines2 = textProperty.mLines; final String[] lines2 = textProperty.mLines;
for (final String line : lines2) { for (final String line : lines2) {
x = Cocos2dxBitmap.computeX(line, textProperty.mMaxWidth, horizontalAlignment); x = Cocos2dxBitmap.computeX(line, textProperty.mMaxWidth, horizontalAlignment);
canvas.drawText(line, x + renderTextDeltaX, y + renderTextDeltaY, paintStroke); canvas.drawText(line, x + renderTextDeltaX, y + renderTextDeltaY, paintStroke);
canvas.drawText(line, x + renderTextDeltaX, y + renderTextDeltaY, paint);
y += textProperty.mHeightPerLine; 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); Cocos2dxBitmap.initNativeObject(bitmap);
@ -269,7 +252,7 @@ public class Cocos2dxBitmap {
/* Compute the max width. */ /* Compute the max width. */
int temp = 0; int temp = 0;
for (final String line : lines) { for (final String line : lines) {
temp = (int) FloatMath.ceil(paint.measureText(line, 0, temp = (int) Math.ceil(paint.measureText(line, 0,
line.length())); line.length()));
if (temp > maxContentWidth) { if (temp > maxContentWidth) {
maxContentWidth = temp; maxContentWidth = temp;
@ -343,7 +326,7 @@ public class Cocos2dxBitmap {
* The width of line is exceed maxWidth, should divide it into * The width of line is exceed maxWidth, should divide it into
* two or more lines. * two or more lines.
*/ */
final int lineWidth = (int) FloatMath.ceil(paint final int lineWidth = (int) Math.ceil(paint
.measureText(line)); .measureText(line));
if (lineWidth > maxWidth) { if (lineWidth > maxWidth) {
strList.addAll(Cocos2dxBitmap.divideStringWithMaxWidth( strList.addAll(Cocos2dxBitmap.divideStringWithMaxWidth(
@ -391,7 +374,7 @@ public class Cocos2dxBitmap {
/* Break a String into String[] by the width & should wrap the word. */ /* Break a String into String[] by the width & should wrap the word. */
for (int i = 1; i <= charLength; ++i) { for (int i = 1; i <= charLength; ++i) {
tempWidth = (int) FloatMath.ceil(paint.measureText(string, start, tempWidth = (int) Math.ceil(paint.measureText(string, start,
i)); i));
if (tempWidth >= maxWidth) { if (tempWidth >= maxWidth) {
final int lastIndexOfSpace = string.substring(0, i) 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()); final LinearLayout layout = new LinearLayout(this.getContext());
layout.setOrientation(LinearLayout.VERTICAL); 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()); this.mTextViewTitle = new TextView(this.getContext());
final LinearLayout.LayoutParams textviewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 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); layout.addView(this.mTextViewTitle, textviewParams);
this.mInputEditText = new EditText(this.getContext()); 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); editTextParams.leftMargin = editTextParams.rightMargin = this.convertDipsToPixels(10);
layout.addView(this.mInputEditText, editTextParams); layout.addView(this.mInputEditText, editTextParams);

View File

@ -24,17 +24,10 @@ THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
package org.cocos2dx.lib; package org.cocos2dx.lib;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.text.Editable; import android.util.AttributeSet;
import android.text.TextWatcher;
import android.view.KeyEvent; 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.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
public class Cocos2dxEditText extends EditText { public class Cocos2dxEditText extends EditText {
// =========================================================== // ===========================================================
@ -44,10 +37,8 @@ public class Cocos2dxEditText extends EditText {
// =========================================================== // ===========================================================
// Fields // Fields
// =========================================================== // ===========================================================
private Cocos2dxTextInputWraper mTextWatcher = null; private Cocos2dxGLSurfaceView mCocos2dxGLSurfaceView;
private Context mContext = null;
private static Cocos2dxEditText instance = null;
// =========================================================== // ===========================================================
// Constructors // Constructors
@ -55,61 +46,35 @@ public class Cocos2dxEditText extends EditText {
public Cocos2dxEditText(final Context context) { public Cocos2dxEditText(final Context context) {
super(context); super(context);
}
this.mContext = context;
this.mTextWatcher = new Cocos2dxTextInputWraper(context, this); public Cocos2dxEditText(final Context context, final AttributeSet attrs) {
this.setOnEditorActionListener(this.mTextWatcher); super(context, attrs);
}
ViewGroup.LayoutParams layout =
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, public Cocos2dxEditText(final Context context, final AttributeSet attrs, final int defStyle) {
ViewGroup.LayoutParams.WRAP_CONTENT); super(context, attrs, defStyle);
Activity activity = (Activity)context;
activity.addContentView(this, layout);
} }
// =========================================================== // ===========================================================
// Getter & Setter // Getter & Setter
// =========================================================== // ===========================================================
public void setCocos2dxGLSurfaceView(final Cocos2dxGLSurfaceView pCocos2dxGLSurfaceView) {
this.mCocos2dxGLSurfaceView = pCocos2dxGLSurfaceView;
}
// =========================================================== // ===========================================================
// Methods for/from SuperClass/Interfaces // 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 @Override
public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) { public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) {
super.onKeyDown(keyCode, keyEvent); super.onKeyDown(pKeyCode, pKeyEvent);
/* Let GlSurfaceView get focus if back key is input. */ /* Let GlSurfaceView get focus if back key is input. */
if (keyCode == KeyEvent.KEYCODE_BACK) { if (pKeyCode == KeyEvent.KEYCODE_BACK) {
//Cocos2dxHelper.nativeRequestFocus(); this.mCocos2dxGLSurfaceView.requestFocus();
} }
return true; return true;
@ -118,133 +83,8 @@ public class Cocos2dxEditText extends EditText {
// =========================================================== // ===========================================================
// Methods // Methods
// =========================================================== // ===========================================================
private native static String nativeGetContent();
// =========================================================== // ===========================================================
// Inner and Anonymous Classes // 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 java.lang.Runnable;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
@ -56,6 +55,7 @@ public class Cocos2dxHelper {
private static Cocos2dxMusic sCocos2dMusic; private static Cocos2dxMusic sCocos2dMusic;
private static Cocos2dxSound sCocos2dSound; private static Cocos2dxSound sCocos2dSound;
private static AssetManager sAssetManager; private static AssetManager sAssetManager;
private static Cocos2dxAccelerometer sCocos2dxAccelerometer;
private static boolean sAccelerometerEnabled; private static boolean sAccelerometerEnabled;
private static String sPackageName; private static String sPackageName;
private static String sFileDirectory; private static String sFileDirectory;
@ -94,7 +94,7 @@ public class Cocos2dxHelper {
if (!sInited) { if (!sInited) {
final ApplicationInfo applicationInfo = activity.getApplicationInfo(); final ApplicationInfo applicationInfo = activity.getApplicationInfo();
initListener(); Cocos2dxHelper.sCocos2dxHelperListener = (Cocos2dxHelperListener)activity;
try { try {
// Get the lib_name from AndroidManifest.xml metadata // Get the lib_name from AndroidManifest.xml metadata
@ -114,87 +114,23 @@ public class Cocos2dxHelper {
Cocos2dxHelper.sPackageName = applicationInfo.packageName; Cocos2dxHelper.sPackageName = applicationInfo.packageName;
Cocos2dxHelper.sFileDirectory = activity.getFilesDir().getAbsolutePath(); Cocos2dxHelper.sFileDirectory = activity.getFilesDir().getAbsolutePath();
//Cocos2dxHelper.nativeSetApkPath(applicationInfo.sourceDir); Cocos2dxHelper.nativeSetApkPath(applicationInfo.sourceDir);
Cocos2dxHelper.sCocos2dxAccelerometer = new Cocos2dxAccelerometer(activity);
Cocos2dxHelper.sCocos2dMusic = new Cocos2dxMusic(activity); Cocos2dxHelper.sCocos2dMusic = new Cocos2dxMusic(activity);
Cocos2dxHelper.sCocos2dSound = new Cocos2dxSound(activity); Cocos2dxHelper.sCocos2dSound = new Cocos2dxSound(activity);
Cocos2dxHelper.sAssetManager = activity.getAssets(); Cocos2dxHelper.sAssetManager = activity.getAssets();
Cocos2dxHelper.nativeSetContext((Context)activity, Cocos2dxHelper.sAssetManager);
//Cocos2dxHelper.nativeSetAssetManager(sAssetManager);
Cocos2dxBitmap.setContext(activity); Cocos2dxBitmap.setContext(activity);
Cocos2dxETCLoader.setContext(activity);
sActivity = activity; sActivity = activity;
sInited = true; 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() { public static Activity getActivity() {
return sActivity; return sActivity;
} }
@ -211,8 +147,12 @@ public class Cocos2dxHelper {
// Methods // Methods
// =========================================================== // ===========================================================
private static native void nativeSetApkPath(final String pApkPath);
private static native void nativeSetEditTextDialogResult(final byte[] pBytes); private static native void nativeSetEditTextDialogResult(final byte[] pBytes);
private static native void nativeSetContext(final Context pContext, final AssetManager pAssetManager);
public static String getCocos2dxPackageName() { public static String getCocos2dxPackageName() {
return Cocos2dxHelper.sPackageName; return Cocos2dxHelper.sPackageName;
} }
@ -233,6 +173,21 @@ public class Cocos2dxHelper {
return Cocos2dxHelper.sAssetManager; 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) { public static void preloadBackgroundMusic(final String pPath) {
Cocos2dxHelper.sCocos2dMusic.preloadBackgroundMusic(pPath); Cocos2dxHelper.sCocos2dMusic.preloadBackgroundMusic(pPath);
} }
@ -318,6 +273,18 @@ public class Cocos2dxHelper {
Cocos2dxHelper.sCocos2dSound.end(); 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() { public static void terminateProcess() {
android.os.Process.killProcess(android.os.Process.myPid()); android.os.Process.killProcess(android.os.Process.myPid());
} }
@ -333,19 +300,17 @@ public class Cocos2dxHelper {
public static void setEditTextDialogResult(final String pResult) { public static void setEditTextDialogResult(final String pResult) {
try { try {
final byte[] bytesUTF8 = pResult.getBytes("UTF8"); final byte[] bytesUTF8 = pResult.getBytes("UTF8");
Cocos2dxHelper.nativeSetEditTextDialogResult(bytesUTF8);
Cocos2dxHelper.sCocos2dxHelperListener.runOnGLThread(new Runnable() {
@Override
public void run() {
Cocos2dxHelper.nativeSetEditTextDialogResult(bytesUTF8);
}
});
} catch (UnsupportedEncodingException pUnsupportedEncodingException) { } catch (UnsupportedEncodingException pUnsupportedEncodingException) {
/* Nothing. */ /* Nothing. */
} }
} }
private static void openIMEKeyboard() {
sCocos2dxHelperListener.openIMEKeyboard();
}
private static void closeIMEKeyboard() {
sCocos2dxHelperListener.closeIMEKeyboard();
}
public static int getDPI() public static int getDPI()
{ {
@ -431,17 +396,15 @@ public class Cocos2dxHelper {
editor.putString(key, value); editor.putString(key, value);
editor.commit(); editor.commit();
} }
public static native void nativeRequestFocus();
// =========================================================== // ===========================================================
// Inner and Anonymous Classes // Inner and Anonymous Classes
// =========================================================== // ===========================================================
public static interface Cocos2dxHelperListener { public static interface Cocos2dxHelperListener {
public void showDialog(final String title, final String message); public void showDialog(final String pTitle, final String pMessage);
public void showEditTextDialog(final String title, final String message, final int inputMode, final int inputFlag, final int returnType, final int maxLength); public void showEditTextDialog(final String pTitle, final String pMessage, final int pInputMode, final int pInputFlag, final int pReturnType, final int pMaxLength);
public void openIMEKeyboard();
public void closeIMEKeyboard(); public void runOnGLThread(final Runnable pRunnable);
} }
} }

View File

@ -46,10 +46,10 @@ public class Cocos2dxLocalStorage {
* @return * @return
*/ */
public static boolean init(String dbName, String tableName) { public static boolean init(String dbName, String tableName) {
if (Cocos2dxHelper.getActivity() != null) { if (Cocos2dxActivity.getContext() != null) {
DATABASE_NAME = dbName; DATABASE_NAME = dbName;
TABLE_NAME = tableName; TABLE_NAME = tableName;
mDatabaseOpenHelper = new DBOpenHelper(Cocos2dxHelper.getActivity()); mDatabaseOpenHelper = new DBOpenHelper(Cocos2dxActivity.getContext());
mDatabase = mDatabaseOpenHelper.getWritableDatabase(); mDatabase = mDatabaseOpenHelper.getWritableDatabase();
return true; 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() { void openKeyboardJNI() {
JniMethodInfo t; 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->CallStaticVoidMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID); t.env->DeleteLocalRef(t.classID);
} }
@ -53,29 +53,9 @@ extern "C" {
void closeKeyboardJNI() { void closeKeyboardJNI() {
JniMethodInfo t; 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->CallStaticVoidMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID); 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 <android/log.h>
#include <string> #include <string>
#include "JniHelper.h" #include "JniHelper.h"
#include "CCFileUtilsAndroid.h"
#include "android/asset_manager_jni.h"
#include "CCString.h" #include "CCString.h"
#include "Java_org_cocos2dx_lib_Cocos2dxHelper.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) { JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHelper_nativeSetApkPath(JNIEnv* env, jobject thiz, jstring apkPath) {
g_apkPath = JniHelper::jstring2string(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() { const char * getApkPath() {
@ -156,6 +182,33 @@ std::string getCurrentLanguageJNI() {
return ret; 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 // functions for UserDefault
bool getBoolForKeyJNI(const char* pKey, bool defaultValue) bool getBoolForKeyJNI(const char* pKey, bool defaultValue)
{ {

View File

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

View File

@ -45,7 +45,7 @@ public:
static JavaVM* getJavaVM(); static JavaVM* getJavaVM();
static JNIEnv* getEnv(); static JNIEnv* getEnv();
static bool setClassLoaderFrom(jobject nativeActivityInstance); static bool setClassLoaderFrom(jobject activityInstance);
static bool getStaticMethodInfo(JniMethodInfo &methodinfo, static bool getStaticMethodInfo(JniMethodInfo &methodinfo,
const char *className, const char *className,
const char *methodName, const char *methodName,
@ -61,8 +61,7 @@ public:
static jobject classloader; static jobject classloader;
private: private:
static void detach_current_thread (void *env); static JNIEnv* cacheEnv(JavaVM* jvm);
static bool cacheEnv(JavaVM* jvm);
static bool getMethodInfo_DefaultClassLoader(JniMethodInfo &methodinfo, static bool getMethodInfo_DefaultClassLoader(JniMethodInfo &methodinfo,
const char *className, const char *className,
@ -70,7 +69,6 @@ private:
const char *paramCode); const char *paramCode);
static JavaVM* _psJavaVM; static JavaVM* _psJavaVM;
static JNIEnv* env;
}; };
NS_CC_END 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,11 +51,29 @@ static void addItemToArray(id item, ValueVector& array)
} }
// add number value into array(such as int, float, bool and so on) // add number value into array(such as int, float, bool and so on)
// the value is a number
if ([item isKindOfClass:[NSNumber class]]) 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; return;
} }
// add dictionary value into array // add dictionary value into array
if ([item isKindOfClass:[NSDictionary class]]) if ([item isKindOfClass:[NSDictionary class]])
@ -94,6 +112,31 @@ static void addObjectToNSArray(const Value& value, NSMutableArray *array)
return; 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 // add array into array
if (value.getType() == Value::Type::VECTOR) if (value.getType() == Value::Type::VECTOR)
{ {
@ -141,9 +184,26 @@ static void addValueToDict(id nsKey, id nsValue, ValueMap& dict)
// the value is a number // the value is a number
if ([nsValue isKindOfClass:[NSNumber class]]) 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; return;
} }
// the value is a new dictionary // the value is a new dictionary
if ([nsValue isKindOfClass:[NSDictionary class]]) if ([nsValue isKindOfClass:[NSDictionary class]])
@ -171,6 +231,7 @@ static void addValueToDict(id nsKey, id nsValue, ValueMap& dict)
dict[key] = Value(valueArray); dict[key] = Value(valueArray);
return; return;
} }
} }
static void addObjectToNSDict(const std::string& key, const Value& value, NSMutableDictionary *dict) 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; 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 // the object is a String
if (value.getType() == Value::Type::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; _captured = true;
if (this->getViewPortRect().equals(Rect::ZERO) || this->getViewPortRect().containsPoint(Point(_mouseX,_mouseY))) 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); this->handleTouchesBegin(1, &id, &_mouseX, &_mouseY);
} }
} }
@ -532,7 +532,7 @@ void GLView::onGLFWMouseCallBack(GLFWwindow* window, int button, int action, int
if (_captured) if (_captured)
{ {
_captured = false; _captured = false;
int id = 0; intptr_t id = 0;
this->handleTouchesEnd(1, &id, &_mouseX, &_mouseY); this->handleTouchesEnd(1, &id, &_mouseX, &_mouseY);
} }
} }
@ -575,7 +575,7 @@ void GLView::onGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y)
if (_captured) if (_captured)
{ {
int id = 0; intptr_t id = 0;
this->handleTouchesMove(1, &id, &_mouseX, &_mouseY); 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); 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) // add the padding (this could be 0 if no shadow and no stroke)
dim.width += shadowStrokePaddingX; dim.width += shadowStrokePaddingX*2;
dim.height += shadowStrokePaddingY; dim.height += shadowStrokePaddingY*2;
unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * (int)(dim.width * dim.height * 4)); unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * (int)(dim.width * dim.height * 4));
@ -356,84 +350,69 @@ static bool _initWithString(const char * text, cocos2d::Device::TextAlign align,
// measure text size with specified font and determine the rectangle to draw text in // measure text size with specified font and determine the rectangle to draw text in
unsigned uHoriFlag = (int)align & 0x0f; unsigned uHoriFlag = (int)align & 0x0f;
UITextAlignment testAlign = (UITextAlignment)((2 == uHoriFlag) ? UITextAlignmentRight NSTextAlignment nsAlign = (2 == uHoriFlag) ? NSTextAlignmentRight
: (3 == uHoriFlag) ? UITextAlignmentCenter : (3 == uHoriFlag) ? NSTextAlignmentCenter
: UITextAlignmentLeft); : 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); 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 // compute the rect used for rendering the text
// based on wether shadows or stroke are enabled // based on wether shadows or stroke are enabled
float textOriginX = 0.0; float textOriginX = 0;
float textOrigingY = 0.0; float textOrigingY = startH;
float textWidth = dim.width - shadowStrokePaddingX; float textWidth = dim.width;
float textHeight = dim.height - shadowStrokePaddingY; float textHeight = dim.height;
if ( info->shadowOffset.width < 0 )
{
textOriginX = shadowStrokePaddingX;
}
else
{
textOriginX = 0.0;
}
if (info->shadowOffset.height > 0)
{
textOrigingY = startH;
}
else
{
textOrigingY = startH - shadowStrokePaddingY;
}
CGRect rect = CGRectMake(textOriginX, textOrigingY, textWidth, textHeight); CGRect rect = CGRectMake(textOriginX, textOrigingY, textWidth, textHeight);
CGContextBeginTransparencyLayerWithRect(context, rect, nullptr); CGContextSetShouldSubpixelQuantizeFonts(context, false);
// actually draw the text in the context
// XXX: ios7 casting
[str drawInRect: rect withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:(NSTextAlignment)testAlign];
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
[str drawInRect: rect withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:nsAlign];
CGContextEndTransparencyLayer(context); CGContextEndTransparencyLayer(context);
// pop the context // pop the context

View File

@ -408,7 +408,7 @@ Copyright (C) 2008 Apple Inc. All Rights Reserved.
} }
auto glview = cocos2d::Director::getInstance()->getOpenGLView(); 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 - (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(); 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 - (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(); 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 - (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(); 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 #pragma mark - UIView - Responder

View File

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

View File

@ -68,6 +68,8 @@ void CC_DLL log(const char * format, ...) CC_FORMAT_PRINTF(1, 2);
scheduler->performFunctionInCocosThread( ... ); scheduler->performFunctionInCocosThread( ... );
``` ```
*/ */
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
class CC_DLL Console class CC_DLL Console
{ {
public: public:
@ -137,11 +139,12 @@ protected:
std::mutex _DebugStringsMutex; std::mutex _DebugStringsMutex;
std::vector<std::string> _DebugStrings; std::vector<std::string> _DebugStrings;
int _touchId; intptr_t _touchId;
private: private:
CC_DISALLOW_COPY_AND_ASSIGN(Console); CC_DISALLOW_COPY_AND_ASSIGN(Console);
}; };
#endif /* #if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8) */
NS_CC_END NS_CC_END
#endif /* defined(__CCCONSOLE_H__) */ #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_EMSCRIPTEN 10
#define CC_PLATFORM_TIZEN 11 #define CC_PLATFORM_TIZEN 11
#define CC_PLATFORM_QT5 12 #define CC_PLATFORM_QT5 12
#define CC_PLATFORM_WP8 13
#define CC_PLATFORM_WINRT 14
// Determine target platform by compile environment macro. // Determine target platform by compile environment macro.
#define CC_TARGET_PLATFORM CC_PLATFORM_UNKNOWN #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 #define CC_TARGET_PLATFORM CC_PLATFORM_QT5
#endif #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 // 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 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 #define CC_ENABLE_CACHE_TEXTURE_DATA 1
#else #else
#define CC_ENABLE_CACHE_TEXTURE_DATA 0 #define CC_ENABLE_CACHE_TEXTURE_DATA 0

View File

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

View File

@ -128,7 +128,12 @@ public:
PERCENT, PERCENT,
MULTIPLY_RESOLUTION, MULTIPLY_RESOLUTION,
}; };
#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8
#ifdef ABSOLUTE
#undef ABSOLUTE
#endif
#endif
enum class SizeType enum class SizeType
{ {
ABSOLUTE, ABSOLUTE,

View File

@ -16,7 +16,7 @@ namespace cocosbuilder {
void LabelTTFLoader::onHandlePropTypeColor3(Node * pNode, Node * pParent, const char * pPropertyName, Color3B pColor3B, CCBReader * ccbReader) { void LabelTTFLoader::onHandlePropTypeColor3(Node * pNode, Node * pParent, const char * pPropertyName, Color3B pColor3B, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_COLOR) == 0) { if(strcmp(pPropertyName, PROPERTY_COLOR) == 0) {
((LabelTTF *)pNode)->setColor(pColor3B); ((Label *)pNode)->setColor(pColor3B);
} else { } else {
NodeLoader::onHandlePropTypeColor3(pNode, pParent, pPropertyName, pColor3B, ccbReader); 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) { void LabelTTFLoader::onHandlePropTypeByte(Node * pNode, Node * pParent, const char * pPropertyName, unsigned char pByte, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_OPACITY) == 0) { if(strcmp(pPropertyName, PROPERTY_OPACITY) == 0) {
((LabelTTF *)pNode)->setOpacity(pByte); ((Label *)pNode)->setOpacity(pByte);
} else { } else {
NodeLoader::onHandlePropTypeByte(pNode, pParent, pPropertyName, pByte, ccbReader); 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) { void LabelTTFLoader::onHandlePropTypeBlendFunc(Node * pNode, Node * pParent, const char * pPropertyName, BlendFunc pBlendFunc, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_BLENDFUNC) == 0) { if(strcmp(pPropertyName, PROPERTY_BLENDFUNC) == 0) {
((LabelTTF *)pNode)->setBlendFunc(pBlendFunc); ((Label *)pNode)->setBlendFunc(pBlendFunc);
} else { } else {
NodeLoader::onHandlePropTypeBlendFunc(pNode, pParent, pPropertyName, pBlendFunc, ccbReader); 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) { void LabelTTFLoader::onHandlePropTypeFontTTF(Node * pNode, Node * pParent, const char * pPropertyName, const char * pFontTTF, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_FONTNAME) == 0) { if(strcmp(pPropertyName, PROPERTY_FONTNAME) == 0) {
((LabelTTF *)pNode)->setFontName(pFontTTF); ((Label *)pNode)->setFontName(pFontTTF);
} else { } else {
NodeLoader::onHandlePropTypeFontTTF(pNode, pParent, pPropertyName, pFontTTF, ccbReader); 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) { void LabelTTFLoader::onHandlePropTypeText(Node * pNode, Node * pParent, const char * pPropertyName, const char * pText, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_STRING) == 0) { if(strcmp(pPropertyName, PROPERTY_STRING) == 0) {
((LabelTTF *)pNode)->setString(pText); ((Label *)pNode)->setString(pText);
} else { } else {
NodeLoader::onHandlePropTypeText(pNode, pParent, pPropertyName, pText, ccbReader); 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) { void LabelTTFLoader::onHandlePropTypeFloatScale(Node * pNode, Node * pParent, const char * pPropertyName, float pFloatScale, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_FONTSIZE) == 0) { if(strcmp(pPropertyName, PROPERTY_FONTSIZE) == 0) {
((LabelTTF *)pNode)->setFontSize(pFloatScale); ((Label *)pNode)->setFontSize(pFloatScale);
} else { } else {
NodeLoader::onHandlePropTypeFloatScale(pNode, pParent, pPropertyName, pFloatScale, ccbReader); 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) { void LabelTTFLoader::onHandlePropTypeIntegerLabeled(Node * pNode, Node * pParent, const char * pPropertyName, int pIntegerLabeled, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_HORIZONTALALIGNMENT) == 0) { if(strcmp(pPropertyName, PROPERTY_HORIZONTALALIGNMENT) == 0) {
((LabelTTF *)pNode)->setHorizontalAlignment(TextHAlignment(pIntegerLabeled)); ((Label *)pNode)->setHorizontalAlignment(TextHAlignment(pIntegerLabeled));
} else if(strcmp(pPropertyName, PROPERTY_VERTICALALIGNMENT) == 0) { } else if(strcmp(pPropertyName, PROPERTY_VERTICALALIGNMENT) == 0) {
((LabelTTF *)pNode)->setVerticalAlignment(TextVAlignment(pIntegerLabeled)); ((Label *)pNode)->setVerticalAlignment(TextVAlignment(pIntegerLabeled));
} else { } else {
NodeLoader::onHandlePropTypeFloatScale(pNode, pParent, pPropertyName, pIntegerLabeled, ccbReader); 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) { if(strcmp(pPropertyName, PROPERTY_DIMENSIONS) == 0) {
((LabelTTF *)pNode)->setDimensions(pSize); ((Label *)pNode)->setDimensions(size.width,size.height);
} else { } 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_ #define _CCB_CCLABELTTFLOADER_H_
#include "CCRef.h" #include "CCRef.h"
#include "CCLabelTTF.h" #include "CCLabel.h"
#include "CCNodeLoader.h" #include "CCNodeLoader.h"
@ -21,7 +21,7 @@ public:
CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(LabelTTFLoader, loader); CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(LabelTTFLoader, loader);
protected: 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 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); 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"); int actionCount = DICTOOL->getArrayCount_json(dic, "actionlist");
for (int i=0; i<actionCount; i++) { for (int i=0; i<actionCount; i++) {
ActionObject* action = new ActionObject(); ActionObject* action = new ActionObject();
action->autorelease();
const rapidjson::Value &actionDic = DICTOOL->getDictionaryFromArray_json(dic, "actionlist", i); const rapidjson::Value &actionDic = DICTOOL->getDictionaryFromArray_json(dic, "actionlist", i);
action->initWithDictionary(actionDic,root); action->initWithDictionary(actionDic,root);
actionList.pushBack(action); actionList.pushBack(action);
@ -122,4 +123,4 @@ void ActionManagerEx::releaseActions()
_actionDic.clear(); _actionDic.clear();
} }
} }

View File

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

View File

@ -97,6 +97,15 @@ bool ComAudio::serialize(void* r)
CC_BREAK_IF(resType != 0); CC_BREAK_IF(resType != 0);
if (strcmp(className, "CCBackgroundAudio") == 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()); preloadBackgroundMusic(filePath.c_str());
bool loop = DICTOOL->getIntValue_json(*v, "loop") != 0? true:false; bool loop = DICTOOL->getIntValue_json(*v, "loop") != 0? true:false;
setLoop(loop); setLoop(loop);

View File

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

View File

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

View File

@ -37,6 +37,7 @@ SceneReader* SceneReader::s_sharedReader = nullptr;
SceneReader::SceneReader() SceneReader::SceneReader()
: _fnSelector(nullptr) : _fnSelector(nullptr)
, _node(nullptr) , _node(nullptr)
, _attachComponent(AttachComponentType::EMPTY_NODE)
{ {
ObjectFactory::getInstance()->registerType(CREATE_CLASS_COMPONENT_INFO(ComAttribute)); ObjectFactory::getInstance()->registerType(CREATE_CLASS_COMPONENT_INFO(ComAttribute));
ObjectFactory::getInstance()->registerType(CREATE_CLASS_COMPONENT_INFO(ComRender)); ObjectFactory::getInstance()->registerType(CREATE_CLASS_COMPONENT_INFO(ComRender));
@ -53,12 +54,12 @@ const char* SceneReader::sceneReaderVersion()
return "1.0.0.0"; 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; rapidjson::Document jsonDict;
do { do {
CC_BREAK_IF(!readJson(fileName, jsonDict)); CC_BREAK_IF(!readJson(fileName, jsonDict));
_node = createObject(jsonDict, nullptr); _node = createObject(jsonDict, nullptr, attachComponent);
TriggerMng::getInstance()->parse(jsonDict); TriggerMng::getInstance()->parse(jsonDict);
} while (0); } 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"); const char *className = DICTOOL->getStringValue_json(dict, "classname");
if(strcmp(className, "CCNode") == 0) if(strcmp(className, "CCNode") == 0)
@ -120,14 +121,9 @@ Node* SceneReader::createObject(const rapidjson::Value &dict, cocos2d::Node* par
{ {
gb = Node::create(); 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"); int count = DICTOOL->getArrayCount_json(dict, "components");
for (int i = 0; i < count; i++) 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"); const char *comName = DICTOOL->getStringValue_json(subDict, "classname");
Component *com = ObjectFactory::getInstance()->createComponent(comName); Component *com = ObjectFactory::getInstance()->createComponent(comName);
if (com != NULL) if (com != nullptr)
{ {
if (com->serialize((void*)(&subDict))) if (com->serialize((void*)(&subDict)))
{
gb->addComponent(com);
}
else
{ {
com = nullptr; ComRender *tRender = dynamic_cast<ComRender*>(com);
if (tRender == nullptr)
{
vecComs.push_back(com);
}
else
{
render = tRender;
}
} }
} }
if(_fnSelector != nullptr) if(_fnSelector != nullptr)
{ {
_fnSelector(com, (void*)(&subDict)); _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"); int length = DICTOOL->getArrayCount_json(dict, "gameobjects");
for (int i = 0; i < length; ++i) for (int i = 0; i < length; ++i)
{ {
@ -163,7 +188,7 @@ Node* SceneReader::createObject(const rapidjson::Value &dict, cocos2d::Node* par
{ {
break; break;
} }
createObject(subDict, gb); createObject(subDict, gb, attachComponent);
} }
return gb; return gb;

View File

@ -30,9 +30,30 @@ THE SOFTWARE.
namespace cocostudio { namespace cocostudio {
class SceneReader class SceneReader
{ {
public: 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(); static SceneReader* getInstance();
/** /**
* @js purge * @js purge
@ -40,22 +61,23 @@ public:
*/ */
static void destroyInstance(); static void destroyInstance();
static const char* sceneReaderVersion(); static const char* sceneReaderVersion();
cocos2d::Node* createNodeWithSceneFile(const std::string &fileName); cocos2d::Node* createNodeWithSceneFile(const std::string &fileName, AttachComponentType attachComponent = AttachComponentType::EMPTY_NODE);
void setTarget(const std::function<void(cocos2d::Ref* obj, void* doc)>& selector); void setTarget(const std::function<void(cocos2d::Ref* obj, void* doc)>& selector);
cocos2d::Node* getNodeByTag(int nTag); cocos2d::Node* getNodeByTag(int nTag);
inline AttachComponentType getAttachComponentType(){return _attachComponent;}
private: private:
SceneReader(void); SceneReader(void);
virtual ~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); void setPropertyFromJsonDict(const rapidjson::Value& dict, cocos2d::Node *node);
bool readJson(const std::string &fileName, rapidjson::Document& doc); 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: private:
static SceneReader* s_sharedReader; static SceneReader* s_sharedReader;
std::function<void(cocos2d::Ref* obj, void* doc)> _fnSelector; 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); setScaleX(_skinData.scaleX);
setScaleY(_skinData.scaleY); setScaleY(_skinData.scaleY);
setRotationX(CC_RADIANS_TO_DEGREES(_skinData.skewX)); setRotationSkewX(CC_RADIANS_TO_DEGREES(_skinData.skewX));
setRotationY(CC_RADIANS_TO_DEGREES(-_skinData.skewY)); setRotationSkewY(CC_RADIANS_TO_DEGREES(-_skinData.skewY));
setPosition(Point(_skinData.x, _skinData.y)); setPosition(Point(_skinData.x, _skinData.y));
_skinTransform = getNodeToParentTransform(); _skinTransform = getNodeToParentTransform();

View File

@ -187,16 +187,19 @@ void WsThreadHelper::update(float dt)
WsMessage *msg = nullptr; WsMessage *msg = nullptr;
// Returns quickly if no message // Returns quickly if no message
std::lock_guard<std::mutex> lk(_UIWsMessageQueueMutex); _UIWsMessageQueueMutex.lock();
if (0 == _UIWsMessageQueue->size()) if (0 == _UIWsMessageQueue->size())
{ {
_UIWsMessageQueueMutex.unlock();
return; return;
} }
// Gets message // Gets message
msg = *(_UIWsMessageQueue->begin()); msg = *(_UIWsMessageQueue->begin());
_UIWsMessageQueue->pop_front(); _UIWsMessageQueue->pop_front();
_UIWsMessageQueueMutex.unlock();
if (_ws) if (_ws)
{ {

View File

@ -349,6 +349,7 @@ protected:
friend class PhysicsShape; friend class PhysicsShape;
friend class PhysicsJoint; friend class PhysicsJoint;
friend class Node; friend class Node;
friend class ProtectedNode;
}; };
NS_CC_END NS_CC_END

View File

@ -1,6 +1,7 @@
-------------------------------- --------------------------------
-- @module ActionManagerEx -- @module ActionManagerEx
-- @extend Ref
-------------------------------- --------------------------------
-- overload function: playActionByName(char, char, cc.CallFunc) -- overload function: playActionByName(char, char, cc.CallFunc)

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