mirror of https://github.com/axmolengine/axmol.git
fixed #292
This commit is contained in:
parent
355570ea8f
commit
dc55c164ba
|
@ -350,28 +350,6 @@ void CCDirector::setDeviceOrientation(ccDeviceOrientation kDeviceOrientation)
|
|||
// m_obSurfaceSize = CGSizeMake(m_obScreenSize.width * m_fContentScaleFactor,
|
||||
// m_obScreenSize.height * m_fContentScaleFactor);
|
||||
}
|
||||
// if (m_eDeviceOrientation != kDeviceOrientation)
|
||||
// {
|
||||
|
||||
// switch (m_eDeviceOrientation)
|
||||
// {
|
||||
// case CCDeviceOrientationPortrait:
|
||||
// CCXApplication::sharedApplication()->setDeviceOrientation(CCDeviceOrientationPortrait);
|
||||
// break;
|
||||
// case CCDeviceOrientationPortraitUpsideDown:
|
||||
// CCXApplication::sharedApplication()->setDeviceOrientation(CCDeviceOrientationPortraitUpsideDown);
|
||||
// break;
|
||||
// case CCDeviceOrientationLandscapeLeft:
|
||||
// CCXApplication::sharedApplication()->setDeviceOrientation(CCDeviceOrientationLandscapeLeft);
|
||||
// break;
|
||||
// case CCDeviceOrientationLandscapeRight:
|
||||
// CCXApplication::sharedApplication()->setDeviceOrientation(CCDeviceOrientationLandscapeRight);
|
||||
// break;
|
||||
// default:
|
||||
// CCLOG("Director: Unknown device orientation");
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void CCDirector::setProjection(ccDirectorProjection kProjection)
|
||||
|
@ -546,12 +524,22 @@ CGSize CCDirector::getWinSize(void)
|
|||
return s;
|
||||
}
|
||||
|
||||
CGSize CCDirector::getWinSizeInPixels()
|
||||
{
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
// return the current frame size
|
||||
CGSize CCDirector::getDisplaySize(void)
|
||||
CGSize CCDirector::getDisplaySizeInPiXels(void)
|
||||
{
|
||||
return m_obSurfaceSize;
|
||||
}
|
||||
|
||||
void CCDirector::reshapeProjection(CGSize newWindowSize)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CCDirector::applyOrientation(void)
|
||||
{
|
||||
CGSize s = m_obSurfaceSize;
|
||||
|
@ -792,6 +780,11 @@ void CCDirector::calculateFramerateDeltaTime(void)
|
|||
*m_pLastComputeFrameRate = now;
|
||||
}
|
||||
|
||||
void CCDirector::showProfilers()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CCDirector::computeFrameRate()
|
||||
{
|
||||
static bool bInvoked = true;
|
||||
|
|
|
@ -1,641 +0,0 @@
|
|||
/****************************************************************************
|
||||
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 "ccMacros.h"
|
||||
#include "CCGrid.h"
|
||||
#include "CCDirector.h"
|
||||
#include "CCGrabber.h"
|
||||
|
||||
#include "CCGL.h"
|
||||
#include "CGPointExtension.h"
|
||||
|
||||
namespace cocos2d
|
||||
{
|
||||
// implementation of CCGridBase
|
||||
|
||||
CCGridBase* CCGridBase::gridWithSize(cocos2d::ccGridSize gridSize)
|
||||
{
|
||||
CCGridBase *pGridBase = new CCGridBase();
|
||||
|
||||
if (pGridBase)
|
||||
{
|
||||
if (pGridBase->initWithSize(gridSize))
|
||||
{
|
||||
pGridBase->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
CCX_SAFE_RELEASE_NULL(pGridBase);
|
||||
}
|
||||
}
|
||||
|
||||
return pGridBase;
|
||||
}
|
||||
|
||||
CCGridBase* CCGridBase::gridWithSize(ccGridSize gridSize, CCTexture2D *texture, bool flipped)
|
||||
{
|
||||
CCGridBase *pGridBase = new CCGridBase();
|
||||
|
||||
if (pGridBase)
|
||||
{
|
||||
if (pGridBase->initWithSize(gridSize, texture, flipped))
|
||||
{
|
||||
pGridBase->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
CCX_SAFE_RELEASE_NULL(pGridBase);
|
||||
}
|
||||
}
|
||||
|
||||
return pGridBase;
|
||||
}
|
||||
|
||||
bool CCGridBase::initWithSize(ccGridSize gridSize, CCTexture2D *pTexture, bool bFlipped)
|
||||
{
|
||||
bool bRet = true;
|
||||
|
||||
m_bActive = false;
|
||||
m_nReuseGrid = 0;
|
||||
m_sGridSize = gridSize;
|
||||
|
||||
m_pTexture = pTexture;
|
||||
CCX_SAFE_RETAIN(m_pTexture);
|
||||
m_bIsTextureFlipped = bFlipped;
|
||||
|
||||
CGSize texSize = m_pTexture->getContentSizeInPixels();
|
||||
m_obStep.x = texSize.width / m_sGridSize.x;
|
||||
m_obStep.y = texSize.height / m_sGridSize.y;
|
||||
|
||||
m_pGrabber = new CCGrabber();
|
||||
if (m_pGrabber)
|
||||
{
|
||||
m_pGrabber->grab(m_pTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
|
||||
calculateVertexPoints();
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool CCGridBase::initWithSize(ccGridSize gridSize)
|
||||
{
|
||||
CCDirector *pDirector = CCDirector::sharedDirector();
|
||||
CGSize s = pDirector->getWinSizeInPixels();
|
||||
|
||||
unsigned int POTWide = ccNextPOT(s.width);
|
||||
unsigned int POTHigh = ccNextPOT(s.height);
|
||||
|
||||
CCTexture2DPixelFormat format = pDirector->getPiexFormat() == kCCPixelFormatRGB565 ? kCCTexture2DPixelFormat_RGB565 : kCCTexture2DPixelFormat_RGBA8888;
|
||||
|
||||
void *data = calloc((int)(POTWide * POTHigh * 4), 1);
|
||||
if (! data)
|
||||
{
|
||||
CCLOG("cocos2d: CCGrid: not enough memory.");
|
||||
this->release();
|
||||
return false;
|
||||
}
|
||||
|
||||
CCTexture2D *pTexture = new CCTexture2D();
|
||||
pTexture->initWithData(data, format, textureSize, textureSize, s);
|
||||
pTexture->autorelease();
|
||||
|
||||
free(data);
|
||||
|
||||
if (! pTexture)
|
||||
{
|
||||
CCLOG("cocos2d: CCGrid: error creating texture");
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (initWithSize(gridSize, pTexture, false))
|
||||
{
|
||||
// do something
|
||||
}
|
||||
|
||||
pTexture->release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CCGridBase::~CCGridBase(void)
|
||||
{
|
||||
CCLOGINFO("cocos2d: deallocing %p", this);
|
||||
|
||||
setActive(false);
|
||||
CCX_SAFE_RELEASE(m_pTexture);
|
||||
CCX_SAFE_RELEASE(m_pGrabber);
|
||||
}
|
||||
|
||||
// properties
|
||||
void CCGridBase::setActive(bool bActive)
|
||||
{
|
||||
m_bActive = bActive;
|
||||
if (! bActive)
|
||||
{
|
||||
CCDirector *pDirector = CCDirector::sharedDirector();
|
||||
ccDirectorProjection proj = pDirector->getProjection();
|
||||
pDirector->setProjection(proj);
|
||||
}
|
||||
}
|
||||
|
||||
void CCGridBase::setIsTextureFlipped(bool bFlipped)
|
||||
{
|
||||
if (m_bIsTextureFlipped != bFlipped)
|
||||
{
|
||||
m_bIsTextureFlipped = bFlipped;
|
||||
calculateVertexPoints();
|
||||
}
|
||||
}
|
||||
|
||||
// This routine can be merged with Director
|
||||
void CCGridBase::applyLandscape(void)
|
||||
{
|
||||
CCDirector *pDirector = CCDirector::sharedDirector();
|
||||
|
||||
CGSize winSize = pDirector->getDisplaySize();
|
||||
float w = winSize.width / 2;
|
||||
float h = winSize.height / 2;
|
||||
|
||||
ccDeviceOrientation orientation = pDirector->getDeviceOrientation();
|
||||
|
||||
switch (orientation)
|
||||
{
|
||||
case CCDeviceOrientationLandscapeLeft:
|
||||
glTranslatef(w,h,0);
|
||||
glRotatef(-90,0,0,1);
|
||||
glTranslatef(-h,-w,0);
|
||||
break;
|
||||
case CCDeviceOrientationLandscapeRight:
|
||||
glTranslatef(w,h,0);
|
||||
glRotatef(90,0,0,1);
|
||||
glTranslatef(-h,-w,0);
|
||||
break;
|
||||
case CCDeviceOrientationPortraitUpsideDown:
|
||||
glTranslatef(w,h,0);
|
||||
glRotatef(180,0,0,1);
|
||||
glTranslatef(-w,-h,0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CCGridBase::set2DProjection()
|
||||
{
|
||||
CGSize winSize = CCDirector::sharedDirector()->getWinSize();
|
||||
|
||||
glLoadIdentity();
|
||||
glViewport((GLsizei)0, (GLsizei)0, (GLsizei)winSize.width, (GLsizei)winSize.height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrthof(0, winSize.width, 0, winSize.height, -100, 100);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
// This routine can be merged with Director
|
||||
void CCGridBase::set3DProjection()
|
||||
{
|
||||
CGSize winSize = CCDirector::sharedDirector()->getDisplaySize();
|
||||
|
||||
glViewport(0, 0, (GLsizei)winSize.width, (GLsizei)winSize.height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60, (GLfloat)winSize.width/winSize.height, 0.5f, 1500.0f);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt( winSize.width/2, winSize.height/2, CCDirector::sharedDirector()->getZEye(),
|
||||
winSize.width/2, winSize.height/2, 0,
|
||||
0.0f, 1.0f, 0.0f
|
||||
);
|
||||
}
|
||||
|
||||
void CCGridBase::beforeDraw(void)
|
||||
{
|
||||
set2DProjection();
|
||||
m_pGrabber->beforeRender(m_pTexture);
|
||||
}
|
||||
|
||||
void CCGridBase::afterDraw(cocos2d::CCNode *pTarget)
|
||||
{
|
||||
m_pGrabber->afterRender(m_pTexture);
|
||||
|
||||
set3DProjection();
|
||||
applyLandscape();
|
||||
|
||||
if (pTarget->getCamera()->getDirty())
|
||||
{
|
||||
CGPoint offset = pTarget->getAnchorPointInPixels();
|
||||
|
||||
//
|
||||
// XXX: Camera should be applied in the AnchorPoint
|
||||
//
|
||||
glTranslatef(offset.x, offset.y, 0);
|
||||
pTarget->getCamera()->locate();
|
||||
glTranslatef(-offset.x, -offset.y, 0);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_pTexture->getName());
|
||||
|
||||
blit();
|
||||
}
|
||||
|
||||
void CCGridBase::blit(void)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CCGridBase::reuse(void)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CCGridBase::calculateVertexPoints(void)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
// implementation of CCGrid3D
|
||||
|
||||
CCGrid3D* CCGrid3D::gridWithSize(ccGridSize gridSize, CCTexture2D *pTexture, bool bFlipped)
|
||||
{
|
||||
CCGrid3D *pRet= new CCGrid3D();
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
if (pRet->initWithSize(gridSize, pTexture, bFlipped))
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pRet;
|
||||
pRet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
CCGrid3D* CCGrid3D::gridWithSize(ccGridSize gridSize)
|
||||
{
|
||||
CCGrid3D *pRet= new CCGrid3D();
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
if (pRet->initWithSize(gridSize))
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pRet;
|
||||
pRet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
CCGrid3D::~CCGrid3D(void)
|
||||
{
|
||||
free(m_pTexCoordinates);
|
||||
free(m_pVertices);
|
||||
free(m_pIndices);
|
||||
free(m_pOriginalVertices);
|
||||
}
|
||||
|
||||
void CCGrid3D::blit(void)
|
||||
{
|
||||
int n = m_sGridSize.x * m_sGridSize.y;
|
||||
|
||||
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
|
||||
// Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY
|
||||
// Unneeded states: GL_COLOR_ARRAY
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, m_pVertices);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, m_pTexCoordinates);
|
||||
glDrawElements(GL_TRIANGLES, n * 6, GL_UNSIGNED_SHORT, m_pIndices);
|
||||
|
||||
// restore GL default state
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
void CCGrid3D::calculateVertexPoints(void)
|
||||
{
|
||||
float width = (float)m_pTexture->getPixelsWide();
|
||||
float height = (float)m_pTexture->getPixelsHigh();
|
||||
float imageH = m_pTexture->getContentSize().height;
|
||||
|
||||
int x, y, i;
|
||||
|
||||
m_pVertices = malloc((m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(ccVertex3F));
|
||||
m_pOriginalVertices = malloc((m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(ccVertex3F));
|
||||
m_pTexCoordinates = malloc((m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(CGPoint));
|
||||
m_pIndices = (GLushort*)malloc(m_sGridSize.x * m_sGridSize.y * sizeof(GLushort) * 6);
|
||||
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
float *texArray = (float*)m_pTexCoordinates;
|
||||
GLushort *idxArray = m_pIndices;
|
||||
|
||||
for (x = 0; x < m_sGridSize.x; ++x)
|
||||
{
|
||||
for (y = 0; y < m_sGridSize.y; ++y)
|
||||
{
|
||||
int idx = (y * m_sGridSize.x) + x;
|
||||
|
||||
float x1 = x * m_obStep.x;
|
||||
float x2 = x1 + m_obStep.x;
|
||||
float y1 = y * m_obStep.y;
|
||||
float y2= y1 + m_obStep.y;
|
||||
|
||||
GLushort a = x * (m_sGridSize.y + 1) + y;
|
||||
GLushort b = (x + 1) * (m_sGridSize.y + 1) + y;
|
||||
GLushort c = (x + 1) * (m_sGridSize.y + 1) + (y + 1);
|
||||
GLushort d = x * (m_sGridSize.y + 1) + (y + 1);
|
||||
|
||||
GLushort tempidx[6] = {a, b, d, b, c, d};
|
||||
|
||||
memcpy(&idxArray[6*idx], tempidx, 6*sizeof(GLushort));
|
||||
|
||||
int l1[4] = {a*3, b*3, c*3, d*3};
|
||||
ccVertex3F e = {x1, y1, 0};
|
||||
ccVertex3F f = {x2, y1, 0};
|
||||
ccVertex3F g = {x2, y2, 0};
|
||||
ccVertex3F h = {x1, y2, 0};
|
||||
|
||||
ccVertex3F l2[4] = {e, f, g, h};
|
||||
|
||||
int tex1[4] = {a*2, b*2, c*2, d*2};
|
||||
CGPoint tex2[4] = {ccp(x1, y1), ccp(x2, y1), ccp(x2, y2), ccp(x1, y2)};
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
vertArray[l1[i]] = l2[i].x;
|
||||
vertArray[l1[i] + 1] = l2[i].y;
|
||||
vertArray[l1[i] + 2] = l2[i].z;
|
||||
|
||||
texArray[tex1[i]] = tex2[i].x / width;
|
||||
if (m_bIsTextureFlipped)
|
||||
{
|
||||
texArray[tex1[i] + 1] = (imageH - tex2[i].y) / height;
|
||||
}
|
||||
else
|
||||
{
|
||||
texArray[tex1[i] + 1] = tex2[i].y / height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(m_pOriginalVertices, m_pVertices, (m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(ccVertex3F));
|
||||
}
|
||||
|
||||
ccVertex3F CCGrid3D::vertex(ccGridSize pos)
|
||||
{
|
||||
int index = (pos.x * (m_sGridSize.y+1) + pos.y) * 3;
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
|
||||
ccVertex3F vert = {vertArray[index], vertArray[index+1], vertArray[index+2]};
|
||||
|
||||
return vert;
|
||||
}
|
||||
|
||||
ccVertex3F CCGrid3D::originalVertex(cocos2d::ccGridSize pos)
|
||||
{
|
||||
int index = (pos.x * (m_sGridSize.y+1) + pos.y) * 3;
|
||||
float *vertArray = (float*)m_pOriginalVertices;
|
||||
|
||||
ccVertex3F vert = {vertArray[index], vertArray[index+1], vertArray[index+2]};
|
||||
|
||||
return vert;
|
||||
}
|
||||
|
||||
void CCGrid3D::setVertex(ccGridSize pos, ccVertex3F vertex)
|
||||
{
|
||||
int index = (pos.x * (m_sGridSize.y + 1) + pos.y) * 3;
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
vertArray[index] = vertex.x;
|
||||
vertArray[index+1] = vertex.y;
|
||||
vertArray[index+2] = vertex.z;
|
||||
}
|
||||
|
||||
void CCGrid3D::reuse(void)
|
||||
{
|
||||
if (m_nReuseGrid > 0)
|
||||
{
|
||||
memcpy(m_pOriginalVertices, m_pVertices, (m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(ccVertex3F));
|
||||
--m_nReuseGrid;
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of CCTiledGrid3D
|
||||
|
||||
CCTiledGrid3D::~CCTiledGrid3D(void)
|
||||
{
|
||||
free(m_pTexCoordinates);
|
||||
free(m_pVertices);
|
||||
free(m_pOriginalVertices);
|
||||
free(m_pIndices);
|
||||
}
|
||||
|
||||
CCTiledGrid3D* CCTiledGrid3D::gridWithSize(cocos2d::ccGridSize gridSize, cocos2d::CCTexture2D *pTexture, bool bFlipped)
|
||||
{
|
||||
CCTiledGrid3D *pRet= new CCTiledGrid3D();
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
if (pRet->initWithSize(gridSize, pTexture, bFlipped))
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pRet;
|
||||
pRet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
CCTiledGrid3D* CCTiledGrid3D::gridWithSize(cocos2d::ccGridSize gridSize)
|
||||
{
|
||||
CCTiledGrid3D *pRet= new CCTiledGrid3D();
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
if (pRet->initWithSize(gridSize))
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pRet;
|
||||
pRet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
void CCTiledGrid3D::blit(void)
|
||||
{
|
||||
int n = m_sGridSize.x * m_sGridSize.y;
|
||||
|
||||
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
|
||||
// Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY
|
||||
// Unneeded states: GL_COLOR_ARRAY
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, m_pVertices);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, m_pTexCoordinates);
|
||||
glDrawElements(GL_TRIANGLES, n*6, GL_UNSIGNED_SHORT, m_pIndices);
|
||||
|
||||
// restore default GL state
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
void CCTiledGrid3D::calculateVertexPoints(void)
|
||||
{
|
||||
float width = (float)m_pTexture->getPixelsWide();
|
||||
float height = (float)m_pTexture->getPixelsHigh();
|
||||
float imageH = m_pTexture->getContentSize().height;
|
||||
|
||||
int numQuads = m_sGridSize.x * m_sGridSize.y;
|
||||
|
||||
m_pVertices = malloc(numQuads * 12 * sizeof(GLfloat));
|
||||
m_pOriginalVertices = malloc(numQuads * 12 * sizeof(GLfloat));
|
||||
m_pTexCoordinates = malloc(numQuads * 8 * sizeof(GLfloat));
|
||||
m_pIndices = (GLushort *)malloc(numQuads * 6 * sizeof(GLushort));
|
||||
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
float *texArray = (float*)m_pTexCoordinates;
|
||||
GLushort *idxArray = m_pIndices;
|
||||
|
||||
int x, y;
|
||||
|
||||
for( x = 0; x < m_sGridSize.x; x++ )
|
||||
{
|
||||
for( y = 0; y < m_sGridSize.y; y++ )
|
||||
{
|
||||
float x1 = x * m_obStep.x;
|
||||
float x2 = x1 + m_obStep.x;
|
||||
float y1 = y * m_obStep.y;
|
||||
float y2 = y1 + m_obStep.y;
|
||||
|
||||
*vertArray++ = x1;
|
||||
*vertArray++ = y1;
|
||||
*vertArray++ = 0;
|
||||
*vertArray++ = x2;
|
||||
*vertArray++ = y1;
|
||||
*vertArray++ = 0;
|
||||
*vertArray++ = x1;
|
||||
*vertArray++ = y2;
|
||||
*vertArray++ = 0;
|
||||
*vertArray++ = x2;
|
||||
*vertArray++ = y2;
|
||||
*vertArray++ = 0;
|
||||
|
||||
float newY1 = y1;
|
||||
float newY2 = y2;
|
||||
|
||||
if (m_bIsTextureFlipped)
|
||||
{
|
||||
newY1 = imageH - y1;
|
||||
newY2 = imageH - y2;
|
||||
}
|
||||
|
||||
*texArray++ = x1 / width;
|
||||
*texArray++ = newY1 / height;
|
||||
*texArray++ = x2 / width;
|
||||
*texArray++ = newY1 / height;
|
||||
*texArray++ = x1 / width;
|
||||
*texArray++ = newY2 / height;
|
||||
*texArray++ = x2 / width;
|
||||
*texArray++ = newY2 / height;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < numQuads; x++)
|
||||
{
|
||||
idxArray[x*6+0] = x * 4 + 0;
|
||||
idxArray[x*6+1] = x * 4 + 1;
|
||||
idxArray[x*6+2] = x * 4 + 2;
|
||||
|
||||
idxArray[x*6+3] = x * 4 + 1;
|
||||
idxArray[x*6+4] = x * 4 + 2;
|
||||
idxArray[x*6+5] = x * 4 + 3;
|
||||
}
|
||||
|
||||
memcpy(m_pOriginalVertices, m_pVertices, numQuads * 12 * sizeof(GLfloat));
|
||||
}
|
||||
|
||||
void CCTiledGrid3D::setTile(cocos2d::ccGridSize pos, cocos2d::ccQuad3 coords)
|
||||
{
|
||||
int idx = (m_sGridSize.y * pos.x + pos.y) * 4 * 3;
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
memcpy(&vertArray[idx], &coords, sizeof(ccQuad3));
|
||||
}
|
||||
|
||||
ccQuad3 CCTiledGrid3D::originalTile(ccGridSize pos)
|
||||
{
|
||||
int idx = (m_sGridSize.y * pos.x + pos.y) * 4 * 3;
|
||||
float *vertArray = (float*)m_pOriginalVertices;
|
||||
|
||||
ccQuad3 ret;
|
||||
memcpy(&ret, &vertArray[idx], sizeof(ccQuad3));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ccQuad3 CCTiledGrid3D::tile(cocos2d::ccGridSize pos)
|
||||
{
|
||||
int idx = (m_sGridSize.y * pos.x + pos.y) * 4 * 3;
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
|
||||
ccQuad3 ret;
|
||||
memcpy(&ret, &vertArray[idx], sizeof(ccQuad3));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CCTiledGrid3D::reuse(void)
|
||||
{
|
||||
if (m_nReuseGrid > 0)
|
||||
{
|
||||
int numQuads = m_sGridSize.x * m_sGridSize.y;
|
||||
|
||||
memcpy(m_pOriginalVertices, m_pVertices, numQuads * 12 * sizeof(GLfloat));
|
||||
--m_nReuseGrid;
|
||||
}
|
||||
}
|
||||
} // end of namespace cocos2d
|
|
@ -34,10 +34,18 @@ THE SOFTWARE.
|
|||
#include "CGGeometry.h"
|
||||
#include "CCXEGLView.h"
|
||||
#include "ccxCommon.h"
|
||||
#include "CCGL.h"
|
||||
|
||||
#include <assert.h>
|
||||
namespace cocos2d {
|
||||
|
||||
enum {
|
||||
/// If the window is resized, it won't be autoscaled
|
||||
kCCDirectorResize_NoScale,
|
||||
/// If the window is resized, it will be autoscaled (default behavior)
|
||||
kCCDirectorResize_AutoScale,
|
||||
};
|
||||
|
||||
/** @typedef tPixelFormat
|
||||
Possible Pixel Formats for the CCXEGLView
|
||||
*/
|
||||
|
@ -83,7 +91,7 @@ typedef enum {
|
|||
/// sets a 3D projection with a fovy=60, znear=0.5f and zfar=1500.
|
||||
kCCDirectorProjection3D,
|
||||
|
||||
/// it does nothing. But if you are using a custom projection set it this value.
|
||||
/// it calls "updateProjection" on the projection delegate.
|
||||
kCCDirectorProjectionCustom,
|
||||
|
||||
/// Detault projection is 3D projection
|
||||
|
@ -172,22 +180,23 @@ typedef enum {
|
|||
class CCLabelTTF;
|
||||
class CCScene;
|
||||
class cocos2d::CCXEGLView;
|
||||
class NSEvent;
|
||||
|
||||
/**
|
||||
@brief Class that creates and handle the main Window and manages how
|
||||
and when to execute the Scenes.
|
||||
|
||||
The CCDirector is also responsible for:
|
||||
- initializing the OpenGL ES context
|
||||
- setting the OpenGL ES pixel format (default on is RGB565)
|
||||
- setting the OpenGL ES buffer depth (default one is 0-bit)
|
||||
- setting the projection (default one is 2D)
|
||||
- initializing the OpenGL context
|
||||
- setting the OpenGL pixel format (default on is RGB565)
|
||||
- setting the OpenGL buffer depth (default one is 0-bit)
|
||||
- setting the projection (default one is 3D)
|
||||
- setting the orientation (default one is Protrait)
|
||||
|
||||
Since the CCDirector is a singleton, the standard way to use it is by calling:
|
||||
_ CCDirector::sharedDirector()->xxx();
|
||||
_ CCDirector::sharedDirector()->methodName();
|
||||
|
||||
The CCDirector also sets the default OpenGL ES context:
|
||||
The CCDirector also sets the default OpenGL context:
|
||||
- GL_TEXTURE_2D is enabled
|
||||
- GL_VERTEX_ARRAY is enabled
|
||||
- GL_COLOR_ARRAY is enabled
|
||||
|
@ -216,15 +225,12 @@ public:
|
|||
inline void setDisplayFPS(bool bDisplayFPS) { m_bDisplayFPS = bDisplayFPS; }
|
||||
|
||||
/** Get the CCXEGLView, where everything is rendered */
|
||||
inline cocos2d::CCXEGLView* getOpenGLView(void) { return m_pobOpenGLView; }
|
||||
void setOpenGLView(cocos2d::CCXEGLView *pobOpenGLView);
|
||||
inline CC_GLVIEW* getOpenGLView(void) { return m_pobOpenGLView; }
|
||||
void setOpenGLView(CC_GLVIEW *pobOpenGLView);
|
||||
|
||||
inline bool isNextDeltaTimeZero(void) { return m_bNextDeltaTimeZero; }
|
||||
void setNextDeltaTimeZero(bool bNextDeltaTimeZero);
|
||||
|
||||
inline ccDeviceOrientation getDeviceOrientation(void) { return m_eDeviceOrientation; }
|
||||
void setDeviceOrientation(ccDeviceOrientation kDeviceOrientation);
|
||||
|
||||
/** Whether or not the Director is paused */
|
||||
inline bool isPaused(void) { return m_bPaused; }
|
||||
|
||||
|
@ -241,54 +247,27 @@ public:
|
|||
*/
|
||||
inline bool isSendCleanupToScene(void) { return m_bSendCleanupToScene; }
|
||||
|
||||
/** The size in pixels of the surface. It could be different than the screen size.
|
||||
High-res devices might have a higher surface size than the screen size.
|
||||
Only available when compiled using SDK >= 4.0.
|
||||
@since v0.99.4
|
||||
*/
|
||||
void setContentScaleFactor(CGFloat scaleFactor);
|
||||
|
||||
inline CGFloat getContentScaleFactor(void) { return m_fContentScaleFactor; }
|
||||
|
||||
// UI dependent
|
||||
// window size
|
||||
|
||||
/** Uses a new pixel format for the CCXEGLView.
|
||||
Call this class method before attaching it to a UIView
|
||||
Default pixel format: kRGB565. Supported pixel formats: kRGBA8 and kRGB565
|
||||
|
||||
@deprecated Set the pixel format when creating the CCXEGLView. This method will be removed in v1.0
|
||||
*/
|
||||
inline void setPixelFormat(tPixelFormat kPixelFormat)
|
||||
{
|
||||
// assert(! isOpenGLAttached());
|
||||
m_ePixelFormat = kPixelFormat;
|
||||
}
|
||||
/** Pixel format used to create the context */
|
||||
inline tPixelFormat getPiexFormat(void) { return m_ePixelFormat; }
|
||||
|
||||
/** Change depth buffer format of the render buffer.
|
||||
Call this class method before attaching it to a UIWindow/UIView
|
||||
Default depth buffer: 0 (none). Supported: kCCDepthBufferNone, kCCDepthBuffer16, and kCCDepthBuffer24
|
||||
|
||||
@deprecated Set the depth buffer format when creating the CCXEGLView. This method will be removed in v1.0
|
||||
*/
|
||||
inline void setDepthBufferFormat(tDepthBufferFormat kDepthBufferFormat)
|
||||
{
|
||||
assert(! isOpenGLAttached());
|
||||
m_eDepthBufferFormat = kDepthBufferFormat;
|
||||
}
|
||||
|
||||
// Integration with UI
|
||||
/** detach the cocos2d view from the view/window */
|
||||
bool detach(void);
|
||||
|
||||
// Landspace
|
||||
|
||||
/** returns the size of the OpenGL view in pixels, according to the landspace */
|
||||
/** returns the size of the OpenGL view in points.
|
||||
It takes into account any possible rotation (device orientation) of the window
|
||||
*/
|
||||
CGSize getWinSize(void);
|
||||
|
||||
/** returns the display size of the OpenGL view in pixels */
|
||||
CGSize getDisplaySize(void);
|
||||
/** returns the size of the OpenGL view in pixels.
|
||||
It takes into account any possible rotation (device orientation) of the window.
|
||||
On Mac winSize and winSizeInPixels return the same value.
|
||||
*/
|
||||
CGSize getWinSizeInPixels(void);
|
||||
|
||||
/** returns the display size of the OpenGL view in pixels.
|
||||
It doesn't take into account any possible rotation of the window.
|
||||
*/
|
||||
CGSize getDisplaySizeInPiXels(void);
|
||||
|
||||
/** changes the projection size */
|
||||
void reshapeProjection(CGSize newWindowSize);
|
||||
|
||||
/** converts a UIKit coordinate to an OpenGL coordinate
|
||||
Useful to convert (multi) touches coordinates to the current layout (portrait or landscape)
|
||||
|
@ -300,9 +279,6 @@ public:
|
|||
*/
|
||||
CGPoint convertToUI(CGPoint obPoint);
|
||||
|
||||
/** rotates the screen if an orientation different than Portrait is used */
|
||||
void applyOrientation(void);
|
||||
|
||||
/// XXX: missing description
|
||||
float getZEye(void);
|
||||
|
||||
|
@ -385,36 +361,103 @@ public:
|
|||
/** enables/disables OpenGL depth test */
|
||||
void setDepthTest(bool bOn);
|
||||
|
||||
virtual void preMainLoop(void);
|
||||
virtual void mainLoop(void);
|
||||
|
||||
// Profiler
|
||||
void showProfilers(void);
|
||||
|
||||
|
||||
/***************************************************
|
||||
* mobile platforms specific functions
|
||||
**************************************************/
|
||||
|
||||
/** rotates the screen if an orientation different than Portrait is used */
|
||||
void applyOrientation(void);
|
||||
|
||||
ccDeviceOrientation getDeviceOrientation(void);
|
||||
void setDeviceOrientation(ccDeviceOrientation kDeviceOrientation);
|
||||
|
||||
/** The size in pixels of the surface. It could be different than the screen size.
|
||||
High-res devices might have a higher surface size than the screen size.
|
||||
Only available when compiled using SDK >= 4.0.
|
||||
@since v0.99.4
|
||||
*/
|
||||
void setContentScaleFactor(CGFloat scaleFactor);
|
||||
CGFloat getContentScaleFactor(void);
|
||||
|
||||
/** Will enable Retina Display on devices that supports it.
|
||||
It will enable Retina Display on iPhone4 and iPod Touch 4.
|
||||
It will return YES, if it could enabled it, otherwise it will return NO.
|
||||
|
||||
This is the recommened way to enable Retina Display.
|
||||
@since v0.99.5
|
||||
*/
|
||||
bool enableRetinaDisplay(bool enabled);
|
||||
|
||||
/** There are 4 types of Director.
|
||||
- kCCDirectorTypeNSTimer (default)
|
||||
- kCCDirectorTypeMainLoop
|
||||
- kCCDirectorTypeThreadMainLoop
|
||||
- kCCDirectorTypeDisplayLink
|
||||
|
||||
Each Director has it's own benefits, limitations.
|
||||
Now we only support DisplayLink director, so it has not effect.
|
||||
|
||||
This method should be called before any other call to the director.
|
||||
|
||||
@since v0.8.2
|
||||
*/
|
||||
static bool setDirectorType(ccDirectorType obDirectorType);
|
||||
|
||||
/** Uses a new pixel format for the CCXEGLView.
|
||||
Call this class method before attaching it to a UIView
|
||||
Default pixel format: kRGB565. Supported pixel formats: kRGBA8 and kRGB565
|
||||
|
||||
@deprecated Set the pixel format when creating the CCXEGLView. This method will be removed in v1.0
|
||||
*/
|
||||
void setPixelFormat(tPixelFormat kPixelFormat);
|
||||
/** Pixel format used to create the context */
|
||||
tPixelFormat getPiexFormat(void);
|
||||
|
||||
/** Change depth buffer format of the render buffer.
|
||||
Call this class method before attaching it to a UIWindow/UIView
|
||||
Default depth buffer: 0 (none). Supported: kCCDepthBufferNone, kCCDepthBuffer16, and kCCDepthBuffer24
|
||||
|
||||
@deprecated Set the depth buffer format when creating the CCXEGLView. This method will be removed in v1.0
|
||||
*/
|
||||
void setDepthBufferFormat(tDepthBufferFormat kDepthBufferFormat);
|
||||
|
||||
/** detach the cocos2d view from the view/window */
|
||||
bool detach(void);
|
||||
|
||||
/***************************************************
|
||||
* PC platforms specific functions, such as mac
|
||||
**************************************************/
|
||||
CGPoint convertEventToGL(NSEvent *event);
|
||||
// whether or not the view is in fullscreen mode
|
||||
bool isFullScreen(void);
|
||||
// resize mode: with or without scaling
|
||||
void setResizeMode(int resizeMode);
|
||||
int getResizeMode(void);
|
||||
/** Sets the view in fullscreen or window mode */
|
||||
void setFullScreen(bool fullscreen);
|
||||
/** Converts window size coordiantes to logical coordinates.
|
||||
Useful only if resizeMode is kCCDirectorResize_Scale.
|
||||
If resizeMode is kCCDirectorResize_NoScale, then no conversion will be done.
|
||||
*/
|
||||
CGPoint convertToLogicalCoordinates(CGPoint coordinates);
|
||||
|
||||
public:
|
||||
/** returns a shared instance of the director */
|
||||
static CCDirector* sharedDirector(void);
|
||||
|
||||
/** There are 4 types of Director.
|
||||
- kCCDirectorTypeNSTimer (default)
|
||||
- kCCDirectorTypeMainLoop
|
||||
- kCCDirectorTypeThreadMainLoop
|
||||
- kCCDirectorTypeDisplayLink
|
||||
|
||||
Each Director has it's own benefits, limitations.
|
||||
Now we only support DisplayLink director, so it has not effect.
|
||||
|
||||
This method should be called before any other call to the director.
|
||||
|
||||
@since v0.8.2
|
||||
*/
|
||||
static bool setDirectorType(ccDirectorType obDirectorType);
|
||||
|
||||
/** recalculate the projection view and projection size based on the EAGLVIEW
|
||||
@since v0.99.4
|
||||
*/
|
||||
void recalculateProjectionAndEAGLViewSize();
|
||||
|
||||
protected:
|
||||
/***************************************************
|
||||
* mobile platforms specific functions
|
||||
**************************************************/
|
||||
bool isOpenGLAttached(void);
|
||||
|
||||
void updateContentScaleFactor(void);
|
||||
|
||||
void setNextScene(void);
|
||||
|
||||
#if CC_DIRECTOR_FAST_FPS
|
||||
|
@ -427,32 +470,22 @@ protected:
|
|||
/** calculates delta time since last time it was called */
|
||||
void calculateDeltaTime();
|
||||
|
||||
#if CC_ENABLE_PROFILERS
|
||||
void showProfilers(void);
|
||||
#endif // CC_ENABLE_PROFILERS
|
||||
|
||||
protected:
|
||||
// compute frame rate
|
||||
void computeFrameRate(void);
|
||||
void computeFrameRate(void);
|
||||
// compute delta time between computing frame rate
|
||||
void calculateFramerateDeltaTime(void);
|
||||
|
||||
protected:
|
||||
/* The CCXEGLView, where everything is rendered */
|
||||
cocos2d::CCXEGLView *m_pobOpenGLView;
|
||||
CC_GLVIEW *m_pobOpenGLView;
|
||||
|
||||
double m_dAnimationInterval;
|
||||
double m_dOldAnimationInterval;
|
||||
|
||||
tPixelFormat m_ePixelFormat;
|
||||
tDepthBufferFormat m_eDepthBufferFormat;
|
||||
|
||||
/* landscape mode ? */
|
||||
bool m_bLandscape;
|
||||
|
||||
/* The device orientation */
|
||||
ccDeviceOrientation m_eDeviceOrientation;
|
||||
|
||||
bool m_bDisplayFPS;
|
||||
int m_nFrames;
|
||||
ccTime m_fAccumDt;
|
||||
|
@ -494,21 +527,49 @@ protected:
|
|||
|
||||
/* projection used */
|
||||
ccDirectorProjection m_eProjection;
|
||||
|
||||
/* screen, different than surface size */
|
||||
CGSize m_obScreenSize;
|
||||
|
||||
/* screen, different than surface size */
|
||||
CGSize m_obSurfaceSize;
|
||||
/* window size in points */
|
||||
CGSize m_obWinSizeInPoints;
|
||||
|
||||
/* window size in pixels */
|
||||
CGSize m_obWinSizeInPixels;
|
||||
|
||||
/* content scale factor */
|
||||
CGFloat m_fContentScaleFactor;
|
||||
|
||||
/* contentScaleFactor could be simulated */
|
||||
bool m_bIsContentScaleSupported;
|
||||
|
||||
/* store the fps string */
|
||||
char *m_pszFPS;
|
||||
|
||||
/* This object will be visited after the scene. Useful to hook a notification node */
|
||||
CCNode *m_pNotificationNode;
|
||||
|
||||
/* Projection protocol delegate */
|
||||
CCProjectionProtocol *m_pProjectionDelegate;
|
||||
|
||||
/***************************************************
|
||||
* mobile platforms specific members
|
||||
**************************************************/
|
||||
/* The device orientation */
|
||||
ccDeviceOrientation m_eDeviceOrientation;
|
||||
/* contentScaleFactor could be simulated */
|
||||
bool m_bIsContentScaleSupported;
|
||||
// Deprecated. Will be removed in 1.0
|
||||
tPixelFormat m_ePixelFormat;
|
||||
tDepthBufferFormat m_eDepthBufferFormat;
|
||||
|
||||
/***************************************************
|
||||
* mac platforms specific members
|
||||
**************************************************/
|
||||
bool m_bIsFullScreen;
|
||||
int m_nResizeMode;
|
||||
CGPoint m_winOffset;
|
||||
CGSize m_originalWinSize;
|
||||
|
||||
MacGLView *m_pFullScreenGLView;
|
||||
NSWindow *m_pFullScreenWindow;
|
||||
|
||||
// cache
|
||||
MacGLView *m_pWindowGLView;
|
||||
|
||||
#if CC_ENABLE_PROFILERS
|
||||
ccTime m_fAccumDtForProfiler;
|
||||
|
@ -529,7 +590,7 @@ class CCDisplayLinkDirector : public CCDirector
|
|||
public:
|
||||
CCDisplayLinkDirector(void) {}
|
||||
|
||||
virtual void preMainLoop(void);
|
||||
virtual void mainLoop(void);
|
||||
virtual void setAnimationInterval(double dValue);
|
||||
virtual void startAnimation(void);
|
||||
virtual void stopAnimation();
|
||||
|
|
|
@ -116,7 +116,7 @@ public:
|
|||
};
|
||||
|
||||
/** OpenGL projection protocol */
|
||||
class CCX_DLL CCProjectionProtocol
|
||||
class CCX_DLL CCProjectionProtocol : public NSObject
|
||||
{
|
||||
/** Called by CCDirector when the porjection is updated, and "custom" projection is used
|
||||
@since v0.99.5
|
||||
|
|
|
@ -191,7 +191,7 @@ Platforms: Only used on Retina Display devices like iPhone 4.
|
|||
|
||||
@since v0.99.5
|
||||
*/
|
||||
#define CC_RETINA_DISPLAY_FILENAME_SUFFIX @"-hd"
|
||||
#define CC_RETINA_DISPLAY_FILENAME_SUFFIX "-hd"
|
||||
|
||||
/** @def CC_USE_RGBA32_LABELS_ON_NEON_ARCH
|
||||
If enabled, it will use RGBA8888 (32-bit textures) on Neon devices for CCLabelTTF objects.
|
||||
|
|
|
@ -0,0 +1,989 @@
|
|||
/****************************************************************************
|
||||
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 "CCDirector.h"
|
||||
#include "CCScene.h"
|
||||
#include "NSMutableArray.h"
|
||||
#include "CCScheduler.h"
|
||||
#include "ccMacros.h"
|
||||
#include "CCXCocos2dDefine.h"
|
||||
#include "CCTouchDispatcher.h"
|
||||
#include "support/opengl_support/glu.h"
|
||||
#include "CGPointExtension.h"
|
||||
#include "CCTransition.h"
|
||||
#include "CCTextureCache.h"
|
||||
#include "CCTransition.h"
|
||||
#include "CCSpriteFrameCache.h"
|
||||
#include "NSAutoreleasePool.h"
|
||||
#include "platform/platform.h"
|
||||
#include "CCXApplication.h"
|
||||
#include "CCLabelBMFont.h"
|
||||
#include "CCActionManager.h"
|
||||
#include "CCLabelTTF.h"
|
||||
#include "CCConfiguration.h"
|
||||
#include "CCKeypadDispatcher.h"
|
||||
#include "CCGL.h"
|
||||
|
||||
#if CC_ENABLE_PROFILERS
|
||||
#include "support/CCProfiling.h"
|
||||
#endif // CC_ENABLE_PROFILERS
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
using namespace cocos2d;
|
||||
namespace cocos2d
|
||||
{
|
||||
|
||||
// singleton stuff
|
||||
static CCDisplayLinkDirector s_sharedDirector;
|
||||
static bool s_bFirstRun = true;
|
||||
|
||||
#define kDefaultFPS 60 // 60 frames per second
|
||||
extern const char* cocos2dVersion(void);
|
||||
|
||||
CCDirector* CCDirector::sharedDirector(void)
|
||||
{
|
||||
if (s_bFirstRun)
|
||||
{
|
||||
s_sharedDirector.init();
|
||||
s_bFirstRun = false;
|
||||
}
|
||||
|
||||
return &s_sharedDirector;
|
||||
}
|
||||
|
||||
bool CCDirector::init(void)
|
||||
{
|
||||
CCLOG("cocos2d: %s", cocos2dVersion());
|
||||
|
||||
CCLOG("cocos2d: Using Director Type: CCDirectorDisplayLink");
|
||||
|
||||
// scenes
|
||||
m_pRunningScene = NULL;
|
||||
m_pNextScene = NULL;
|
||||
|
||||
m_pNotificationNode = NULL;
|
||||
|
||||
m_dOldAnimationInterval = m_dAnimationInterval = 1.0 / kDefaultFPS;
|
||||
m_pobScenesStack = new NSMutableArray<CCScene*>();
|
||||
|
||||
// Set default projection (3D)
|
||||
m_eProjection = kCCDirectorProjectionDefault;
|
||||
|
||||
// projection delegate if "Custom" projection is used
|
||||
m_pProjectionDelegate = NULL;
|
||||
|
||||
// FPS
|
||||
m_bDisplayFPS = false;
|
||||
m_nFrames = 0;
|
||||
m_pszFPS = new char[10];
|
||||
m_fExpectedFrameRate = (ccTime)(1 / m_dAnimationInterval);
|
||||
m_fComputeFrameRateDeltaTime = 0;
|
||||
m_pLastComputeFrameRate = new struct cc_timeval();
|
||||
m_pLastUpdate = new struct cc_timeval();
|
||||
|
||||
// paused ?
|
||||
m_bPaused = false;
|
||||
|
||||
m_obWinSizeInPixels = m_obWinSizeInPoints = CGSizeZero;
|
||||
|
||||
// default values
|
||||
m_ePixelFormat = kCCPixelFormatDefault;
|
||||
m_eDepthBufferFormat = kCCDepthBufferNone; // 0
|
||||
|
||||
// portrait mode default
|
||||
m_eDeviceOrientation = CCDeviceOrientationPortrait;
|
||||
|
||||
m_pobOpenGLView = NULL;
|
||||
|
||||
m_fContentScaleFactor = 1;
|
||||
m_bIsContentScaleSupported = false;
|
||||
|
||||
// create autorelease pool
|
||||
NSPoolManager::getInstance()->push();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CCDirector::~CCDirector(void)
|
||||
{
|
||||
CCLOGINFO("cocos2d: deallocing %p", this);
|
||||
|
||||
#if CC_DIRECTOR_FAST_FPS
|
||||
CCX_SAFE_RELEASE(m_pFPSLabel);
|
||||
#endif
|
||||
|
||||
CCX_SAFE_RELEASE(m_pRunningScene);
|
||||
CCX_SAFE_RELEASE(m_pNotificationNode);
|
||||
CCX_SAFE_RELEASE(m_pobScenesStack);
|
||||
|
||||
// pop the autorelease pool
|
||||
NSPoolManager::getInstance()->pop();
|
||||
|
||||
// delete m_pLastUpdate
|
||||
CCX_SAFE_DELETE(m_pLastUpdate);
|
||||
|
||||
// delete last compute time
|
||||
CCX_SAFE_DELETE(m_pLastComputeFrameRate);
|
||||
|
||||
CCKeypadDispatcher::purgeSharedDispatcher();
|
||||
|
||||
// delete fps string
|
||||
delete []m_pszFPS;
|
||||
}
|
||||
|
||||
void CCDirector::setGLDefaultValues(void)
|
||||
{
|
||||
// This method SHOULD be called only after openGLView_ was initialized
|
||||
assert(m_pobOpenGLView);
|
||||
|
||||
setAlphaBlending(true);
|
||||
setDepthTest(true);
|
||||
setProjection(m_eProjection);
|
||||
|
||||
// set other opengl default values
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
#if CC_DIRECTOR_FAST_FPS
|
||||
if (! m_pFPSLabel)
|
||||
{
|
||||
m_pFPSLabel = CCLabelTTF::labelWithString("00.0", "XXX", 24);
|
||||
m_pFPSLabel->retain();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Draw the SCene
|
||||
void CCDirector::drawScene(void)
|
||||
{
|
||||
// calculate "global" dt
|
||||
calculateDeltaTime();
|
||||
|
||||
//tick before glClear: issue #533
|
||||
if (! m_bPaused)
|
||||
{
|
||||
CCScheduler::sharedScheduler()->tick(m_fDeltaTime);
|
||||
}
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/* to avoid flickr, nextScene MUST be here: after tick and before draw.
|
||||
XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */
|
||||
if (m_pNextScene)
|
||||
{
|
||||
setNextScene();
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
applyOrientation();
|
||||
|
||||
// By default enable VertexArray, ColorArray, TextureCoordArray and Texture2D
|
||||
CC_ENABLE_DEFAULT_GL_STATES();
|
||||
|
||||
// draw the scene
|
||||
if (m_pRunningScene)
|
||||
{
|
||||
m_pRunningScene->visit();
|
||||
}
|
||||
|
||||
// draw the notifications node
|
||||
if (m_pNotificationNode)
|
||||
{
|
||||
m_pNotificationNode->visit();
|
||||
}
|
||||
|
||||
if (m_bDisplayFPS)
|
||||
{
|
||||
showFPS();
|
||||
}
|
||||
|
||||
#if CC_ENABLE_PROFILERS
|
||||
showProfilers();
|
||||
#endif
|
||||
|
||||
CC_DISABLE_DEFAULT_GL_STATES();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
// swap buffers
|
||||
if (m_pobOpenGLView)
|
||||
{
|
||||
m_pobOpenGLView->swapBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
void CCDirector::calculateDeltaTime(void)
|
||||
{
|
||||
struct cc_timeval now;
|
||||
|
||||
if (CCTime::gettimeofdayCocos2d(&now, NULL) != 0)
|
||||
{
|
||||
CCLOG("error in gettimeofday");
|
||||
m_fDeltaTime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// new delta time
|
||||
if (m_bNextDeltaTimeZero)
|
||||
{
|
||||
m_fDeltaTime = 0;
|
||||
m_bNextDeltaTimeZero = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fDeltaTime = (now.tv_sec - m_pLastUpdate->tv_sec) + (now.tv_usec - m_pLastUpdate->tv_usec) / 1000000.0f;
|
||||
m_fDeltaTime = MAX(0, m_fDeltaTime);
|
||||
}
|
||||
|
||||
*m_pLastUpdate = now;
|
||||
}
|
||||
|
||||
|
||||
// m_dAnimationInterval
|
||||
void CCDirector::setAnimationInterval(double dValue)
|
||||
{
|
||||
CCLOG("cocos2d: Director#setAnimationInterval. Overrride me");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
// m_pobOpenGLView
|
||||
|
||||
void CCDirector::setOpenGLView(CC_GLVIEW *pobOpenGLView)
|
||||
{
|
||||
assert(pobOpenGLView);
|
||||
|
||||
if (m_pobOpenGLView != pobOpenGLView)
|
||||
{
|
||||
// because EAGLView is not kind of NSObject
|
||||
delete m_pobOpenGLView; // [openGLView_ release]
|
||||
m_pobOpenGLView = pobOpenGLView;
|
||||
|
||||
setGLDefaultValues();
|
||||
|
||||
// set size
|
||||
m_obWinSizeInPoints = CCNSSizeToCGSize(m_pobOpenGLView->getSize());
|
||||
m_obWinSizeInPixels = CGSizeMake(m_obWinSizeInPoints.width * m_fContentScaleFactor, m_obWinSizeInPoints * m_fContentScaleFactor);
|
||||
|
||||
if (m_fContentScaleFactor != 1)
|
||||
{
|
||||
updateContentScaleFactor();
|
||||
}
|
||||
|
||||
CCTouchDispatcher *pTouchDispatcher = CCTouchDispatcher::sharedDispatcher();
|
||||
m_pobOpenGLView->setTouchDelegate(pTouchDispatcher);
|
||||
pTouchDispatcher->setDispatchEvents(true);
|
||||
}
|
||||
}
|
||||
|
||||
void CCDirector::setNextDeltaTimeZero(bool bNextDeltaTimeZero)
|
||||
{
|
||||
m_bNextDeltaTimeZero = bNextDeltaTimeZero;
|
||||
}
|
||||
|
||||
void CCDirector::setProjection(ccDirectorProjection kProjection)
|
||||
{
|
||||
CGSize size = m_obWinSizeInPixels;
|
||||
switch (kProjection)
|
||||
{
|
||||
case kCCDirectorProjection2D:
|
||||
glViewport((GLsizei)0, (GLsizei)0, (GLsizei)size.width, (GLsizei)size.height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
ccglOrtho(0, size.width, 0, size.height, -1024 * CC_CONTENT_SCALE_FACTOR(),
|
||||
1024 * CC_CONTENT_SCALE_FACTOR());
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
break;
|
||||
|
||||
case kCCDirectorProjection3D:
|
||||
glViewport(0, 0, (GLsizei)size.width, (GLsizei)size.height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60, (GLfloat)size.width/size.height, 0.5f, 1500.0f);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt( size.width/2, size.height/2, getZEye(),
|
||||
size.width/2, size.height/2, 0,
|
||||
0.0f, 1.0f, 0.0f);
|
||||
break;
|
||||
|
||||
case kCCDirectorProjectionCustom:
|
||||
if (m_pProjectionDelegate)
|
||||
{
|
||||
m_pProjectionDelegate->updateProjection();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
CCLOG("cocos2d: Director: unrecognized projecgtion");
|
||||
break;
|
||||
}
|
||||
|
||||
m_eProjection = kProjection;
|
||||
}
|
||||
|
||||
void CCDirector::purgeCachedData(void)
|
||||
{
|
||||
CCLabelBMFont::purgeCachedData();
|
||||
CCTextureCache::purgeSharedTextureCache();
|
||||
}
|
||||
|
||||
float CCDirector::getZEye(void)
|
||||
{
|
||||
return (m_obWinSizeInPixels.height / 1.1566f);
|
||||
}
|
||||
|
||||
void CCDirector::setAlphaBlending(bool bOn)
|
||||
{
|
||||
if (bOn)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
void CCDirector::setDepthTest(bool bOn)
|
||||
{
|
||||
if (bOn)
|
||||
{
|
||||
ccglClearDepth(1.0f);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
CGPoint CCDirector::convertToGL(CGPoint obPoint)
|
||||
{
|
||||
CGSize s = m_obWinSizeInPoints;
|
||||
float newY = s.height - obPoint.y;
|
||||
float newX = s.width - obPoint.x;
|
||||
|
||||
CGPoint ret = CGPointZero;
|
||||
switch (m_eDeviceOrientation)
|
||||
{
|
||||
case CCDeviceOrientationPortrait:
|
||||
ret = ccp(obPoint.x, newY);
|
||||
break;
|
||||
case CCDeviceOrientationPortraitUpsideDown:
|
||||
ret = ccp(newX, obPoint.y);
|
||||
break;
|
||||
case CCDeviceOrientationLandscapeLeft:
|
||||
ret.x = obPoint.y;
|
||||
ret.y = obPoint.x;
|
||||
break;
|
||||
case CCDeviceOrientationLandscapeRight:
|
||||
ret.x = newY;
|
||||
ret.y = newX;
|
||||
break;
|
||||
}
|
||||
|
||||
// if (m_fContentScaleFactor != 1 && m_bIsContentScaleSupported)
|
||||
// {
|
||||
// ret = ccpMult(ret, m_fContentScaleFactor);
|
||||
// }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CGPoint CCDirector::convertToUI(CGPoint obPoint)
|
||||
{
|
||||
CGSize winSize = m_obWinSizeInPoints;
|
||||
float oppositeX = winSize.width - obPoint.x;
|
||||
float oppositeY = winSize.height - obPoint.y;
|
||||
CGPoint uiPoint = CGPointZero;
|
||||
|
||||
switch (m_eDeviceOrientation)
|
||||
{
|
||||
case CCDeviceOrientationPortrait:
|
||||
uiPoint = ccp(obPoint.x, oppositeY);
|
||||
break;
|
||||
case CCDeviceOrientationPortraitUpsideDown:
|
||||
uiPoint = ccp(oppositeX, obPoint.y);
|
||||
break;
|
||||
case CCDeviceOrientationLandscapeLeft:
|
||||
uiPoint = ccp(obPoint.y, obPoint.x);
|
||||
break;
|
||||
case CCDeviceOrientationLandscapeRight:
|
||||
// Can't use oppositeX/Y because x/y are flipped
|
||||
uiPoint = ccp(winSize.width - obPoint.y, winSize.height - obPoint.x);
|
||||
break;
|
||||
}
|
||||
|
||||
uiPoint = ccpMult(uiPoint, 1/m_fContentScaleFactor);
|
||||
return uiPoint;
|
||||
}
|
||||
|
||||
CGSize CCDirector::getWinSize(void)
|
||||
{
|
||||
CGSize s = m_obWinSizeInPoints;
|
||||
|
||||
if (m_eDeviceOrientation == CCDeviceOrientationLandscapeLeft
|
||||
|| m_eDeviceOrientation == CCDeviceOrientationLandscapeRight)
|
||||
{
|
||||
// swap x,y in landspace mode
|
||||
CGSize tmp = s;
|
||||
s.width = tmp.height;
|
||||
s.height = tmp.width;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
CGSize CCDirector::getWinSizeInPixels()
|
||||
{
|
||||
CGSize s = getWinSize();
|
||||
|
||||
s.width *= CC_CONTENT_SCALE_FACTOR();
|
||||
s.height *= CC_CONTENT_SCALE_FACTOR();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// return the current frame size
|
||||
CGSize CCDirector::getDisplaySizeInPiXels(void)
|
||||
{
|
||||
return m_obWinSizeInPixels;
|
||||
}
|
||||
|
||||
void CCDirector::reshapeProjection(CGSize newWindowSize)
|
||||
{
|
||||
m_obWinSizeInPoints = m_pobOpenGLView->getSize();
|
||||
m_obWinSizeInPixels = CGSizeMake(m_obWinSizeInPoints.width * m_fContentScaleFactor,
|
||||
m_obWinSizeInPoints.height * m_fContentScaleFactor);
|
||||
|
||||
setProjection(m_eProjection);
|
||||
}
|
||||
|
||||
// scene management
|
||||
|
||||
void CCDirector::runWithScene(CCScene *pScene)
|
||||
{
|
||||
assert(pScene != NULL);
|
||||
assert(m_pRunningScene == NULL);
|
||||
|
||||
pushScene(pScene);
|
||||
startAnimation();
|
||||
}
|
||||
|
||||
void CCDirector::replaceScene(CCScene *pScene)
|
||||
{
|
||||
assert(pScene != NULL);
|
||||
|
||||
unsigned int index = m_pobScenesStack->count();
|
||||
|
||||
m_bSendCleanupToScene = true;
|
||||
m_pobScenesStack->replaceObjectAtIndex(index - 1, pScene);
|
||||
|
||||
m_pNextScene = pScene;
|
||||
}
|
||||
|
||||
void CCDirector::pushScene(CCScene *pScene)
|
||||
{
|
||||
assert(pScene);
|
||||
|
||||
m_bSendCleanupToScene = false;
|
||||
|
||||
m_pobScenesStack->addObject(pScene);
|
||||
m_pNextScene = pScene;
|
||||
}
|
||||
|
||||
void CCDirector::popScene(void)
|
||||
{
|
||||
assert(m_pRunningScene != NULL);
|
||||
|
||||
m_pobScenesStack->removeLastObject();
|
||||
unsigned int c = m_pobScenesStack->count();
|
||||
|
||||
if (c == 0)
|
||||
{
|
||||
end();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bSendCleanupToScene = true;
|
||||
m_pNextScene = m_pobScenesStack->getObjectAtIndex(c - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void CCDirector::end(void)
|
||||
{
|
||||
// don't release the event handlers
|
||||
// They are needed in case the director is run again
|
||||
CCTouchDispatcher::sharedDispatcher()->removeAllDelegates();
|
||||
|
||||
m_pRunningScene->onExit();
|
||||
m_pRunningScene->cleanup();
|
||||
m_pRunningScene->release();
|
||||
|
||||
m_pRunningScene = NULL;
|
||||
m_pNextScene = NULL;
|
||||
|
||||
// remove all objects, but don't release it.
|
||||
// runWithScene might be executed after 'end'.
|
||||
m_pobScenesStack->removeAllObjects();
|
||||
|
||||
stopAnimation();
|
||||
|
||||
#if CC_DIRECTOR_FAST_FPS
|
||||
CCX_SAFE_RELEASE_NULL(m_pFPSLabel);
|
||||
#endif
|
||||
|
||||
CCX_SAFE_RELEASE_NULL(m_pProjectionDelegate);
|
||||
|
||||
// purge bitmap cache
|
||||
CCLabelBMFont::purgeCachedData();
|
||||
|
||||
// purge all managers
|
||||
CCAnimationCache::purgeSharedAnimationCache();
|
||||
CCSpriteFrameCache::purgeSharedSpriteFrameCache();
|
||||
CCActionManager::sharedManager()->purgeSharedManager();
|
||||
CCScheduler::purgeSharedScheduler();
|
||||
CCTextureCache::purgeSharedTextureCache();
|
||||
|
||||
// OpenGL view
|
||||
m_pobOpenGLView->release();
|
||||
m_pobOpenGLView = NULL;
|
||||
}
|
||||
|
||||
void CCDirector::setNextScene(void)
|
||||
{
|
||||
ccSceneFlag runningSceneType = ccNormalScene;
|
||||
ccSceneFlag newSceneType = m_pNextScene->getSceneType();
|
||||
|
||||
if (m_pRunningScene)
|
||||
{
|
||||
runningSceneType = m_pRunningScene->getSceneType();
|
||||
}
|
||||
|
||||
// If it is not a transition, call onExit/cleanup
|
||||
/*if (! newIsTransition)*/
|
||||
if (! (newSceneType & ccTransitionScene))
|
||||
{
|
||||
if (m_pRunningScene)
|
||||
{
|
||||
m_pRunningScene->onExit();
|
||||
}
|
||||
|
||||
// issue #709. the root node (scene) should receive the cleanup message too
|
||||
// otherwise it might be leaked.
|
||||
if (m_bSendCleanupToScene && m_pRunningScene)
|
||||
{
|
||||
m_pRunningScene->cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pRunningScene)
|
||||
{
|
||||
m_pRunningScene->release();
|
||||
}
|
||||
m_pRunningScene = m_pNextScene;
|
||||
m_pNextScene->retain();
|
||||
m_pNextScene = NULL;
|
||||
|
||||
if (! (runningSceneType & ccTransitionScene) && m_pRunningScene)
|
||||
{
|
||||
m_pRunningScene->onEnter();
|
||||
m_pRunningScene->onEnterTransitionDidFinish();
|
||||
}
|
||||
}
|
||||
|
||||
void CCDirector::pause(void)
|
||||
{
|
||||
if (m_bPaused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_dOldAnimationInterval = m_dAnimationInterval;
|
||||
|
||||
// when paused, don't consume CPU
|
||||
setAnimationInterval(1 / 4.0);
|
||||
m_bPaused = true;
|
||||
}
|
||||
|
||||
void CCDirector::resume(void)
|
||||
{
|
||||
if (! m_bPaused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setAnimationInterval(m_dOldAnimationInterval);
|
||||
|
||||
if (CCTime::gettimeofdayCocos2d(m_pLastUpdate, NULL) != 0)
|
||||
{
|
||||
CCLOG("cocos2d: Director: Error in gettimeofday");
|
||||
}
|
||||
|
||||
m_bPaused = false;
|
||||
m_fDeltaTime = 0;
|
||||
}
|
||||
|
||||
void CCDirector::startAnimation(void)
|
||||
{
|
||||
CCLOG("cocos2d: Director#startAnimation. Overrride me");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CCDirector::stopAnimation(void)
|
||||
{
|
||||
CCLOG("cocos2d: Director#stopAnimation. Overrride me");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CCDirector::mainLoop(void)
|
||||
{
|
||||
CCLOG("cocos2d: Director#preMainLoop. Overrride me");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
#if CC_DIRECTOR_FAST_FPS
|
||||
// display the FPS using a LabelAtlas
|
||||
// updates the FPS every frame
|
||||
void CCDirector::showFPS(void)
|
||||
{
|
||||
sprintf(m_pszFPS, "%.1f", m_fFrameRate);
|
||||
m_pFPSLabel->setString(m_pszFPS);
|
||||
|
||||
m_pFPSLabel->draw();
|
||||
}
|
||||
#endif // CC_DIRECTOR_FAST_FPS
|
||||
|
||||
void CCDirector::calculateFramerateDeltaTime(void)
|
||||
{
|
||||
struct cc_timeval now;
|
||||
|
||||
if (CCTime::gettimeofdayCocos2d(&now, NULL) != 0)
|
||||
{
|
||||
CCLOG("error in gettimeofday");
|
||||
m_fComputeFrameRateDeltaTime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
m_fComputeFrameRateDeltaTime = (now.tv_sec - m_pLastComputeFrameRate->tv_sec) + (now.tv_usec - m_pLastComputeFrameRate->tv_usec) / 1000000.0f;
|
||||
m_fComputeFrameRateDeltaTime = MAX(0, m_fComputeFrameRateDeltaTime);
|
||||
|
||||
*m_pLastComputeFrameRate = now;
|
||||
}
|
||||
|
||||
void CCDirector::computeFrameRate()
|
||||
{
|
||||
static bool bInvoked = true;
|
||||
|
||||
// compute delta time
|
||||
calculateFramerateDeltaTime();
|
||||
|
||||
// only add frames if the director really draw the scene
|
||||
if (bInvoked)
|
||||
{
|
||||
m_nFrames++;
|
||||
}
|
||||
|
||||
m_fAccumDt += m_fComputeFrameRateDeltaTime;
|
||||
|
||||
if (m_fAccumDt > CC_DIRECTOR_FPS_INTERVAL)
|
||||
{
|
||||
m_fFrameRate = m_nFrames / m_fAccumDt;
|
||||
|
||||
if (m_fFrameRate > m_fExpectedFrameRate)
|
||||
{
|
||||
bInvoked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nFrames = 0;
|
||||
m_fAccumDt = 0;
|
||||
bInvoked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCDirector::showProfilers()
|
||||
{
|
||||
#if CC_ENABLE_PROFILERS
|
||||
m_fAccumDtForProfiler += m_fDeltaTime;
|
||||
if (m_fAccumDtForProfiler > 1.0f)
|
||||
{
|
||||
m_fAccumDtForProfiler = 0;
|
||||
CCProfiler::sharedProfiler()->displayTimers();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* mobile platforms specific functions
|
||||
**************************************************/
|
||||
|
||||
// is the view currently attached
|
||||
bool CCDirector::isOpenGLAttached(void)
|
||||
{
|
||||
return m_pobOpenGLView->isOpenGLReady();
|
||||
}
|
||||
|
||||
void CCDirector::updateContentScaleFactor()
|
||||
{
|
||||
// [openGLView responseToSelector:@selector(setContentScaleFactor)]
|
||||
if (m_pobOpenGLView->canSetContentScaleFactor())
|
||||
{
|
||||
m_pobOpenGLView->setContentScaleFactor(m_fContentScaleFactor);
|
||||
m_bIsContentScaleSupported = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCLOG("cocos2d: setContentScaleFactor:'is not supported on this device");
|
||||
}
|
||||
}
|
||||
|
||||
// detach or attach to a view or a window
|
||||
bool CCDirector::detach(void)
|
||||
{
|
||||
assert(isOpenGLAttached());
|
||||
|
||||
CCX_SAFE_DELETE(m_pobOpenGLView);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCDirector::setDepthBufferFormat(tDepthBufferFormat kDepthBufferFormat)
|
||||
{
|
||||
assert(! isOpenGLAttached());
|
||||
m_eDepthBufferFormat = kDepthBufferFormat;
|
||||
}
|
||||
|
||||
void CCDirector::setPixelFormat(tPixelFormat kPixelFormat)
|
||||
{
|
||||
m_ePixelFormat = kPixelFormat;
|
||||
}
|
||||
|
||||
tPixelFormat CCDirector::getPiexFormat(void)
|
||||
{
|
||||
return m_ePixelFormat;
|
||||
}
|
||||
|
||||
bool CCDirector::setDirectorType(ccDirectorType obDirectorType)
|
||||
{
|
||||
// we only support CCDisplayLinkDirector
|
||||
CCDirector::sharedDirector();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCDirector::enableRetinaDisplay(bool enabled)
|
||||
{
|
||||
// Already enabled?
|
||||
if (enabled && m_fContentScaleFactor == 2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Already diabled?
|
||||
if (!enabled && m_fContentScaleFactor == 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// setContentScaleFactor is not supported
|
||||
if (! m_pobOpenGLView->canSetContentScaleFactor())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
///@todo SD device iphone specific
|
||||
// if ([[UIScreen mainScreen] scale] == 1.0)
|
||||
// return NO;
float newScale = enabled ? 2 : 1;
setContentScaleFactor(newScale);
|
||||
return true;
|
||||
}
|
||||
|
||||
CGFloat CCDirector::getContentScaleFactor(void)
|
||||
{
|
||||
return m_fContentScaleFactor;
|
||||
}
|
||||
|
||||
void CCDirector::setContentScaleFactor(CGFloat scaleFactor)
|
||||
{
|
||||
if (scaleFactor != m_fContentScaleFactor)
|
||||
{
|
||||
m_fContentScaleFactor = scaleFactor;
|
||||
m_obWinSizeInPixels = CGSizeMake(m_obWinSizeInPoints.width * scaleFactor, m_obWinSizeInPoints.height * scaleFactor);
|
||||
|
||||
if (m_pobOpenGLView)
|
||||
{
|
||||
updateContentScaleFactor();
|
||||
}
|
||||
|
||||
// update projection
|
||||
setProjection(m_eProjection);
|
||||
}
|
||||
}
|
||||
|
||||
void CCDirector::applyOrientation(void)
|
||||
{
|
||||
CGSize s = m_obWinSizeInPixels;
|
||||
float w = s.width / 2;
|
||||
float h = s.height / 2;
|
||||
|
||||
// XXX it's using hardcoded values.
|
||||
// What if the the screen size changes in the future?
|
||||
switch (m_eDeviceOrientation)
|
||||
{
|
||||
case CCDeviceOrientationPortrait:
|
||||
// nothing
|
||||
break;
|
||||
case CCDeviceOrientationPortraitUpsideDown:
|
||||
// upside down
|
||||
glTranslatef(w,h,0);
|
||||
glRotatef(180,0,0,1);
|
||||
glTranslatef(-w,-h,0);
|
||||
break;
|
||||
case CCDeviceOrientationLandscapeRight:
|
||||
glTranslatef(w,h,0);
|
||||
glRotatef(90,0,0,1);
|
||||
glTranslatef(-h,-w,0);
|
||||
break;
|
||||
case CCDeviceOrientationLandscapeLeft:
|
||||
glTranslatef(w,h,0);
|
||||
glRotatef(-90,0,0,1);
|
||||
glTranslatef(-h,-w,0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ccDeviceOrientation CCDirector::getDeviceOrientation(void)
|
||||
{
|
||||
return m_eDeviceOrientation;
|
||||
}
|
||||
|
||||
void CCDirector::setDeviceOrientation(ccDeviceOrientation kDeviceOrientation)
|
||||
{
|
||||
ccDeviceOrientation eNewOrientation;
|
||||
eNewOrientation = CCXApplication::sharedApplication()->setDeviceOrientation(kDeviceOrientation);
|
||||
if (m_eDeviceOrientation != eNewOrientation)
|
||||
{
|
||||
m_eDeviceOrientation = kDeviceOrientation;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* PC platforms specific functions, such as mac
|
||||
**************************************************/
|
||||
|
||||
CGPoint CCDirector::convertEventToGL(NSEvent *event);
|
||||
{
|
||||
assert(false);
|
||||
return CGPointZero;
|
||||
}
|
||||
|
||||
bool CCDirector::isFullScreen(void)
|
||||
{
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
void CCDirector::setResizeMode(int resizeMode)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
int CCDirector::getResizeMode(void);
|
||||
{
|
||||
assert(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CCDirector::setFullScreen(bool fullscreen)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
CGPoint CCDirector::convertToLogicalCoordinates(CGPoint coordinates)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************
|
||||
* implementation of DisplayLinkDirector
|
||||
**************************************************/
|
||||
|
||||
// should we afford 4 types of director ??
|
||||
// I think DisplayLinkDirector is enough
|
||||
// so we now only support DisplayLinkDirector
|
||||
void CCDisplayLinkDirector::startAnimation(void)
|
||||
{
|
||||
if (CCTime::gettimeofdayCocos2d(m_pLastUpdate, NULL) != 0)
|
||||
{
|
||||
CCLOG("cocos2d: DisplayLinkDirector: Error on gettimeofday");
|
||||
}
|
||||
|
||||
m_bInvalid = false;
|
||||
}
|
||||
|
||||
void CCDisplayLinkDirector::mainLoop(void)
|
||||
{
|
||||
if (! m_bInvalid)
|
||||
{
|
||||
// compute frame rate
|
||||
computeFrameRate();
|
||||
|
||||
// control frame rate
|
||||
if (m_fFrameRate <= m_fExpectedFrameRate)
|
||||
{
|
||||
drawScene();
|
||||
|
||||
// release the objects
|
||||
NSPoolManager::getInstance()->pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCDisplayLinkDirector::stopAnimation(void)
|
||||
{
|
||||
m_bInvalid = true;
|
||||
}
|
||||
|
||||
void CCDisplayLinkDirector::setAnimationInterval(double dValue)
|
||||
{
|
||||
m_dAnimationInterval = dValue;
|
||||
m_fExpectedFrameRate = (ccTime)(1 / m_dAnimationInterval);
|
||||
if (! m_bInvalid)
|
||||
{
|
||||
stopAnimation();
|
||||
startAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace cocos2d
|
|
@ -43,11 +43,9 @@ THE SOFTWARE.
|
|||
#error
|
||||
#endif
|
||||
|
||||
#define CC_GLVIEW CCXEGLView
|
||||
|
||||
|
||||
// iOS
|
||||
#if defined(CCX_PLATFORM_MOBILE)
|
||||
#define CC_GLVIEW cocos2d::CCXEGLView
|
||||
#define ccglOrtho glOrthof
|
||||
#define ccglClearDepth glClearDepthf
|
||||
#define ccglGenerateMipmap glGenerateMipmapOES
|
||||
|
@ -65,6 +63,7 @@ THE SOFTWARE.
|
|||
|
||||
// Mac
|
||||
#elif defined(CCX_PLATFORM_PC)
|
||||
#define CC_GLVIEW MacGLView
|
||||
#define ccglOrtho glOrtho
|
||||
#define ccglClearDepth glClearDepth
|
||||
#define ccglGenerateMipmap glGenerateMipmap
|
||||
|
|
|
@ -43,11 +43,15 @@ THE SOFTWARE.
|
|||
#define CCTextAlignmentLeft UITextAlignmentLeft
|
||||
#define CCTextAlignmentRight UITextAlignmentRight
|
||||
|
||||
#define MacGLView void
|
||||
#define NSWindow void
|
||||
|
||||
|
||||
#elif defined(CCX_PLATFORM_MAC)
|
||||
|
||||
#include <Availability.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
#include "platform/MacGLView.h"
|
||||
|
||||
#define CCRectFromString(__r__) NSRectToCGRect( NSRectFromString(__r__) )
|
||||
#define CCPointFromString(__p__) NSPointToCGPoint( NSPointFromString(__p__) )
|
||||
|
@ -68,14 +72,17 @@ THE SOFTWARE.
|
|||
#define CCRectFromString(__r__) CGRectZero
|
||||
#define CCPointFromString(__p__) CGPointZero
|
||||
#define CCSizeFromString(__s__) CGSizeZero
|
||||
#define CCNSSizeToCGSize CGSizeZero
|
||||
#define CCNSRectToCGRect CGRectZero
|
||||
#define CCNSPointToCGPoint CGPointZero
|
||||
#define CCNSSizeToCGSize
|
||||
#define CCNSRectToCGRect
|
||||
#define CCNSPointToCGPoint
|
||||
#define CCTextAlignment 0
|
||||
#define CCTextAlignmentCenter 0
|
||||
#define CCTextAlignmentLeft 0
|
||||
#define CCTextAlignmentRight 0
|
||||
|
||||
#define MacGLView void
|
||||
#define NSWindow void
|
||||
|
||||
#endif
|
||||
|
||||
#endif // __PLATFOMR_CCNS_H__
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/****************************************************************************
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __PLATFORM_MAC_CCDIRECTOR_DISPLAYLINK_MAC_WRAPPER
|
||||
#define __PLATFORM_MAC_CCDIRECTOR_DISPLAYLINK_MAC_WRAPPER
|
||||
|
||||
#import <QuartzCore/CVDisplayLink.h>
|
||||
|
||||
@interface CCDirectorDisplayLinkMacWrapper
|
||||
{
|
||||
CVDisplayLinkRef displayLink;
|
||||
NSThread *runningThread_;
|
||||
}
|
||||
|
||||
@property(nonatomic, readonly)NSThread *runningThread_;
|
||||
|
||||
+(CCDirectorDisplayLinkMacWrapper*)sharedDisplayLinkMacWrapper;
|
||||
-(void)startAnimation;
|
||||
-(void)stopAnimation;
|
||||
|
||||
@end
|
||||
|
||||
#endif // __PLATFORM_MAC_CCDIRECTOR_DISPLAYLINK_MAC_WRAPPER
|
|
@ -0,0 +1,141 @@
|
|||
/****************************************************************************
|
||||
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.
|
||||
****************************************************************************/
|
||||
#import "CCDirectorDisplayLinkMacWrapper.h"
|
||||
#import "ccConfig.h"
|
||||
|
||||
@implementation CCDirectorDisplayLinkMacWrapper
|
||||
|
||||
static CCDirectorDisplayLinkMacWrapper* sharedDisplayLinkMacWrapper;
|
||||
|
||||
@synthesize runningThread = runningThread_;
|
||||
|
||||
+(CCDirectorDisplayLinkMacWrapper*)sharedDisplayLinkMacWrapper
|
||||
{
|
||||
if (! sharedDisplayLinkMacWrapper)
|
||||
{
|
||||
sharedDiplayLinkMacWrapper = [CCDirectorDisplayLinkMacWrapper new];
|
||||
}
|
||||
|
||||
return sharedDiplayLinkMacWrapper;
|
||||
}
|
||||
|
||||
- (void) init
|
||||
{
|
||||
runningThread_ = nil;
|
||||
displayLink = nil;
|
||||
}
|
||||
|
||||
- (CVReturn) getFrameForTime:(const CVTimeStamp*)outputTime
|
||||
{
|
||||
#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
|
||||
if( ! runningThread_ )
|
||||
runningThread_ = [NSThread currentThread];
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
[self drawScene];
|
||||
[[CCEventDispatcher sharedDispatcher] dispatchQueuedEvents];
|
||||
|
||||
[[NSRunLoop currentRunLoop] run];
|
||||
|
||||
[pool release];
|
||||
|
||||
#else
|
||||
[self performSelector:@selector(drawScene) onThread:runningThread_ withObject:nil waitUntilDone:YES];
|
||||
#endif
|
||||
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
// This is the renderer output callback function
|
||||
static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
|
||||
{
|
||||
CVReturn result = [(CCDirectorDisplayLinkMacWrapper*)displayLinkContext getFrameForTime:outputTime];
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void) startAnimation
|
||||
{
|
||||
#if ! CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
|
||||
runningThread_ = [[NSThread alloc] initWithTarget:self selector:@selector(mainLoop) object:nil];
|
||||
[runningThread_ start];
|
||||
#endif
|
||||
|
||||
// Create a display link capable of being used with all active displays
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
|
||||
|
||||
// Set the renderer output callback function
|
||||
CVDisplayLinkSetOutputCallback(displayLink, &MyDisplayLinkCallback, self);
|
||||
|
||||
// Set the display link for the current renderer
|
||||
CGLContextObj cglContext = [[openGLView_ openGLContext] CGLContextObj];
|
||||
CGLPixelFormatObj cglPixelFormat = [[openGLView_ pixelFormat] CGLPixelFormatObj];
|
||||
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, cglContext, cglPixelFormat);
|
||||
|
||||
// Activate the display link
|
||||
CVDisplayLinkStart(displayLink);
|
||||
}
|
||||
|
||||
- (void) mainLoop
|
||||
{
|
||||
cocos2d::CCDirector::sharedDirector()->mainLoop();
|
||||
}
|
||||
|
||||
- (void) stopAnimation
|
||||
{
|
||||
if( displayLink ) {
|
||||
CVDisplayLinkStop(displayLink);
|
||||
CVDisplayLinkRelease(displayLink);
|
||||
displayLink = NULL;
|
||||
|
||||
#if ! CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
|
||||
[runningThread_ cancel];
|
||||
[runningThread_ release];
|
||||
runningThread_ = nil;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
-(void) dealloc
|
||||
{
|
||||
if( displayLink )
|
||||
{
|
||||
CVDisplayLinkStop(displayLink);
|
||||
CVDisplayLinkRelease(displayLink);
|
||||
}
|
||||
|
||||
sharedDisplayLinkMacWrapper = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
//
|
||||
// Draw the Scene
|
||||
//
|
||||
- (void) drawScene
|
||||
{
|
||||
cocos2d::CCDirector::sharedDirector()->drawScene();
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,973 @@
|
|||
/****************************************************************************
|
||||
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 "CCDirector.h"
|
||||
#include "CCScene.h"
|
||||
#include "NSMutableArray.h"
|
||||
#include "CCScheduler.h"
|
||||
#include "ccMacros.h"
|
||||
#include "CCXCocos2dDefine.h"
|
||||
#include "CCTouchDispatcher.h"
|
||||
#include "support/opengl_support/glu.h"
|
||||
#include "CGPointExtension.h"
|
||||
#include "CCTransition.h"
|
||||
#include "CCTextureCache.h"
|
||||
#include "CCTransition.h"
|
||||
#include "CCSpriteFrameCache.h"
|
||||
#include "NSAutoreleasePool.h"
|
||||
#include "platform/platform.h"
|
||||
#include "CCXApplication.h"
|
||||
#include "CCLabelBMFont.h"
|
||||
#include "CCActionManager.h"
|
||||
#include "CCLabelTTF.h"
|
||||
#include "CCConfiguration.h"
|
||||
#include "CCKeypadDispatcher.h"
|
||||
#include "CCGL.h"
|
||||
#include "CCDirectorDisplayLinkMacWrapper.h"
|
||||
|
||||
#if CC_ENABLE_PROFILERS
|
||||
#include "support/CCProfiling.h"
|
||||
#endif // CC_ENABLE_PROFILERS
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
using namespace cocos2d;
|
||||
namespace cocos2d
|
||||
{
|
||||
|
||||
// singleton stuff
|
||||
static CCDisplayLinkDirector s_sharedDirector;
|
||||
static bool s_bFirstRun = true;
|
||||
|
||||
#define kDefaultFPS 60 // 60 frames per second
|
||||
extern const char* cocos2dVersion(void);
|
||||
|
||||
CCDirector* CCDirector::sharedDirector(void)
|
||||
{
|
||||
if (s_bFirstRun)
|
||||
{
|
||||
s_sharedDirector.init();
|
||||
s_bFirstRun = false;
|
||||
}
|
||||
|
||||
return &s_sharedDirector;
|
||||
}
|
||||
|
||||
bool CCDirector::init(void)
|
||||
{
|
||||
CCLOG("cocos2d: %s", cocos2dVersion());
|
||||
|
||||
CCLOG("cocos2d: Using Director Type: CCDirectorDisplayLink");
|
||||
|
||||
// scenes
|
||||
m_pRunningScene = NULL;
|
||||
m_pNextScene = NULL;
|
||||
|
||||
m_pNotificationNode = NULL;
|
||||
|
||||
m_dOldAnimationInterval = m_dAnimationInterval = 1.0 / kDefaultFPS;
|
||||
m_pobScenesStack = new NSMutableArray<CCScene*>();
|
||||
|
||||
// Set default projection (3D)
|
||||
m_eProjection = kCCDirectorProjectionDefault;
|
||||
|
||||
// projection delegate if "Custom" projection is used
|
||||
m_pProjectionDelegate = NULL;
|
||||
|
||||
// FPS
|
||||
m_bDisplayFPS = false;
|
||||
m_nFrames = 0;
|
||||
m_pszFPS = new char[10];
|
||||
m_fExpectedFrameRate = (ccTime)(1 / m_dAnimationInterval);
|
||||
m_fComputeFrameRateDeltaTime = 0;
|
||||
m_pLastComputeFrameRate = new struct cc_timeval();
|
||||
m_pLastUpdate = new struct cc_timeval();
|
||||
|
||||
// paused ?
|
||||
m_bPaused = false;
|
||||
|
||||
m_obWinSizeInPixels = m_obWinSizeInPoints = CGSizeZero;
|
||||
|
||||
m_pobOpenGLView = NULL;
|
||||
|
||||
m_bIsFullScreen = false;
|
||||
m_nResizeMode = kCCDirectorResize_AutoScale;
|
||||
|
||||
m_pFullScreenGLView = NULL;
|
||||
m_pFullScreenWindow = NULL;
|
||||
m_pWindowGLView = NULL;
|
||||
m_winOffset = CGPointZero;
|
||||
|
||||
// create autorelease pool
|
||||
NSPoolManager::getInstance()->push();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CCDirector::~CCDirector(void)
|
||||
{
|
||||
CCLOGINFO("cocos2d: deallocing %p", this);
|
||||
|
||||
#if CC_DIRECTOR_FAST_FPS
|
||||
CCX_SAFE_RELEASE(m_pFPSLabel);
|
||||
#endif
|
||||
|
||||
CCX_SAFE_RELEASE(m_pRunningScene);
|
||||
CCX_SAFE_RELEASE(m_pNotificationNode);
|
||||
CCX_SAFE_RELEASE(m_pobScenesStack);
|
||||
|
||||
// pop the autorelease pool
|
||||
NSPoolManager::getInstance()->pop();
|
||||
|
||||
// delete m_pLastUpdate
|
||||
CCX_SAFE_DELETE(m_pLastUpdate);
|
||||
|
||||
// delete last compute time
|
||||
CCX_SAFE_DELETE(m_pLastComputeFrameRate);
|
||||
|
||||
CCKeypadDispatcher::purgeSharedDispatcher();
|
||||
|
||||
// delete fps string
|
||||
delete []m_pszFPS;
|
||||
|
||||
[m_pFullScreenGLView release];
|
||||
[m_pFullScreenWindow release];
|
||||
[m_pWindowGLView release];
|
||||
[[CCDirectorDisplayLinkMacWrapper sharedDisplayLinkMacWrapper] release];
|
||||
}
|
||||
|
||||
void CCDirector::setGLDefaultValues(void)
|
||||
{
|
||||
// This method SHOULD be called only after openGLView_ was initialized
|
||||
assert(m_pobOpenGLView);
|
||||
|
||||
setAlphaBlending(true);
|
||||
setDepthTest(true);
|
||||
setProjection(m_eProjection);
|
||||
|
||||
// set other opengl default values
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
#if CC_DIRECTOR_FAST_FPS
|
||||
if (! m_pFPSLabel)
|
||||
{
|
||||
m_pFPSLabel = CCLabelTTF::labelWithString("00.0", "XXX", 24);
|
||||
m_pFPSLabel->retain();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Draw the SCene
|
||||
void CCDirector::drawScene(void)
|
||||
{
|
||||
// calculate "global" dt
|
||||
calculateDeltaTime();
|
||||
|
||||
//tick before glClear: issue #533
|
||||
if (! m_bPaused)
|
||||
{
|
||||
CCScheduler::sharedScheduler()->tick(m_fDeltaTime);
|
||||
}
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/* to avoid flickr, nextScene MUST be here: after tick and before draw.
|
||||
XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */
|
||||
if (m_pNextScene)
|
||||
{
|
||||
setNextScene();
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
// By default enable VertexArray, ColorArray, TextureCoordArray and Texture2D
|
||||
CC_ENABLE_DEFAULT_GL_STATES();
|
||||
|
||||
// draw the scene
|
||||
if (m_pRunningScene)
|
||||
{
|
||||
m_pRunningScene->visit();
|
||||
}
|
||||
|
||||
// draw the notifications node
|
||||
if (m_pNotificationNode)
|
||||
{
|
||||
m_pNotificationNode->visit();
|
||||
}
|
||||
|
||||
if (m_bDisplayFPS)
|
||||
{
|
||||
showFPS();
|
||||
}
|
||||
|
||||
#if CC_ENABLE_PROFILERS
|
||||
showProfilers();
|
||||
#endif
|
||||
|
||||
CC_DISABLE_DEFAULT_GL_STATES();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
// swap buffers
|
||||
if (m_pobOpenGLView)
|
||||
{
|
||||
m_pobOpenGLView->swapBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
void CCDirector::calculateDeltaTime(void)
|
||||
{
|
||||
struct cc_timeval now;
|
||||
|
||||
if (CCTime::gettimeofdayCocos2d(&now, NULL) != 0)
|
||||
{
|
||||
CCLOG("error in gettimeofday");
|
||||
m_fDeltaTime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// new delta time
|
||||
if (m_bNextDeltaTimeZero)
|
||||
{
|
||||
m_fDeltaTime = 0;
|
||||
m_bNextDeltaTimeZero = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fDeltaTime = (now.tv_sec - m_pLastUpdate->tv_sec) + (now.tv_usec - m_pLastUpdate->tv_usec) / 1000000.0f;
|
||||
m_fDeltaTime = MAX(0, m_fDeltaTime);
|
||||
}
|
||||
|
||||
*m_pLastUpdate = now;
|
||||
}
|
||||
|
||||
|
||||
// m_dAnimationInterval
|
||||
void CCDirector::setAnimationInterval(double dValue)
|
||||
{
|
||||
CCLOG("cocos2d: Director#setAnimationInterval. Overrride me");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
// m_pobOpenGLView
|
||||
|
||||
void CCDirector::setOpenGLView(CC_GLVIEW *pobOpenGLView)
|
||||
{
|
||||
assert(pobOpenGLView);
|
||||
|
||||
if (m_pobOpenGLView != pobOpenGLView)
|
||||
{
|
||||
[m_pobOpenGLView release];
|
||||
m_pobOpenGLView = [pobOpenGLView retain];
|
||||
|
||||
|
||||
|
||||
// set size
|
||||
m_obWinSizeInPixels = m_obWinSizeInPoints = CCNSSizeToCGSize([pobOpenGLView bounds].size);
|
||||
|
||||
setGLDefaultValues();
|
||||
|
||||
// cache the NSWindow and NSOpgenGLView created from the NIB
|
||||
if (!m_bIsFullScreen && !m_pWindowGLView)
|
||||
{
|
||||
m_pWindowGLView = [pobOpenGLView retain];
|
||||
m_originalWinSize = m_obWinSizeInPixels;
|
||||
}
|
||||
|
||||
// for DirectorDisplayLink, because the it doesn't override setOpenGLView
|
||||
|
||||
CCEventDispatcher *eventDispatcher = [CCEventDispatcher sharedDispatcher];
|
||||
[m_pobOpenGLView setEventDelegate: eventDispatcher];
|
||||
[eventDispatcher setDispatchEvents: YES];
|
||||
|
||||
// Enable Touches. Default no.
|
||||
[pobOpenGLView setAcceptsTouchEvents:NO];
|
||||
// [view setAcceptsTouchEvents:YES];
|
||||
|
||||
|
||||
// Synchronize buffer swaps with vertical refresh rate
|
||||
[[pobOpenGLView openGLContext] makeCurrentContext];
|
||||
GLint swapInt = 1;
|
||||
[[pobOpenGLView openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
}
|
||||
|
||||
void CCDirector::setNextDeltaTimeZero(bool bNextDeltaTimeZero)
|
||||
{
|
||||
m_bNextDeltaTimeZero = bNextDeltaTimeZero;
|
||||
}
|
||||
|
||||
void CCDirector::setProjection(ccDirectorProjection kProjection)
|
||||
{
|
||||
CGSize size = m_obWinSizeInPixels;
|
||||
|
||||
CGPoint offset = CGPointZero;
|
||||
float widthAspect = size.width;
|
||||
float heightAspect = size.height;
|
||||
|
||||
if( m_nResizeMode == kCCDirectorResize_AutoScale && ! CGSizeEqualToSize(m_originalWinSize, CGSizeZero ) )
|
||||
{
|
||||
size = m_originalWinSize;
|
||||
|
||||
float aspect = m_originalWinSize.width / m_originalWinSize.height;
|
||||
widthAspect = m_obWinSizeInPixels.width;
|
||||
heightAspect = m_obWinSizeInPixels.width / aspect;
|
||||
|
||||
if( heightAspect > m_obWinSizeInPixels.height )
|
||||
{
|
||||
widthAspect = m_obWinSizeInPixels.height * aspect;
|
||||
heightAspect = m_obWinSizeInPixels.height;
|
||||
}
|
||||
|
||||
m_winOffset.x = (m_obWinSizeInPixels.width - widthAspect) / 2;
|
||||
m_winOffset.y = (m_obWinSizeInPixels.height - heightAspect) / 2;
|
||||
|
||||
offset = m_winOffset;
|
||||
}
|
||||
|
||||
switch (kProjection) {
|
||||
case kCCDirectorProjection2D:
|
||||
glViewport(offset.x, offset.y, widthAspect, heightAspect);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
ccglOrtho(0, size.width, 0, size.height, -1024, 1024);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
break;
|
||||
|
||||
case kCCDirectorProjection3D:
|
||||
glViewport(offset.x, offset.y, widthAspect, heightAspect);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60, (GLfloat)widthAspect/heightAspect, 0.1f, 1500.0f);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
float eyeZ = size.height * getZEye() / m_obWinSizeInPixels.height;
|
||||
|
||||
gluLookAt( size.width/2, size.height/2, eyeZ,
|
||||
size.width/2, size.height/2, 0,
|
||||
0.0f, 1.0f, 0.0f);
|
||||
break;
|
||||
|
||||
case kCCDirectorProjectionCustom:
|
||||
if(m_pProjectionDelegate)
|
||||
{
|
||||
m_pProjectionDelegate->updateProjection();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
CCLOG("cocos2d: Director: unrecognized projecgtion");
|
||||
break;
|
||||
}
|
||||
|
||||
m_eProjection = kProjection;
|
||||
}
|
||||
|
||||
void CCDirector::purgeCachedData(void)
|
||||
{
|
||||
CCLabelBMFont::purgeCachedData();
|
||||
CCTextureCache::purgeSharedTextureCache();
|
||||
}
|
||||
|
||||
float CCDirector::getZEye(void)
|
||||
{
|
||||
return (m_obWinSizeInPixels.height / 1.1566f);
|
||||
}
|
||||
|
||||
void CCDirector::setAlphaBlending(bool bOn)
|
||||
{
|
||||
if (bOn)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
void CCDirector::setDepthTest(bool bOn)
|
||||
{
|
||||
if (bOn)
|
||||
{
|
||||
ccglClearDepth(1.0f);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
CGPoint CCDirector::convertToGL(CGPoint obPoint)
|
||||
{
|
||||
assert(0);
|
||||
return CGPointZero;
|
||||
}
|
||||
|
||||
CGPoint CCDirector::convertToUI(CGPoint obPoint)
|
||||
{
|
||||
assert(0);
|
||||
return CGPointZero;
|
||||
}
|
||||
|
||||
CGSize CCDirector::getWinSize(void)
|
||||
{
|
||||
if (m_nResizeMode == kCCDirectorResize_AutoScale)
|
||||
{
|
||||
return m_originalWinSize;
|
||||
}
|
||||
|
||||
return m_obWinSizeInPixels;
|
||||
}
|
||||
|
||||
CGSize CCDirector::getWinSizeInPixels()
|
||||
{
|
||||
return getWinSize();
|
||||
}
|
||||
|
||||
// return the current frame size
|
||||
CGSize CCDirector::getDisplaySizeInPiXels(void)
|
||||
{
|
||||
return m_obWinSizeInPixels;
|
||||
}
|
||||
|
||||
void CCDirector::reshapeProjection(CGSize newWindowSize)
|
||||
{
|
||||
m_obWinSizeInPixels = m_originalWinSize = newWindowSize;
|
||||
setProjection(m_eProjection);
|
||||
}
|
||||
|
||||
// scene management
|
||||
|
||||
void CCDirector::runWithScene(CCScene *pScene)
|
||||
{
|
||||
assert(pScene != NULL);
|
||||
assert(m_pRunningScene == NULL);
|
||||
|
||||
pushScene(pScene);
|
||||
startAnimation();
|
||||
}
|
||||
|
||||
void CCDirector::replaceScene(CCScene *pScene)
|
||||
{
|
||||
assert(pScene != NULL);
|
||||
|
||||
unsigned int index = m_pobScenesStack->count();
|
||||
|
||||
m_bSendCleanupToScene = true;
|
||||
m_pobScenesStack->replaceObjectAtIndex(index - 1, pScene);
|
||||
|
||||
m_pNextScene = pScene;
|
||||
}
|
||||
|
||||
void CCDirector::pushScene(CCScene *pScene)
|
||||
{
|
||||
assert(pScene);
|
||||
|
||||
m_bSendCleanupToScene = false;
|
||||
|
||||
m_pobScenesStack->addObject(pScene);
|
||||
m_pNextScene = pScene;
|
||||
}
|
||||
|
||||
void CCDirector::popScene(void)
|
||||
{
|
||||
assert(m_pRunningScene != NULL);
|
||||
|
||||
m_pobScenesStack->removeLastObject();
|
||||
unsigned int c = m_pobScenesStack->count();
|
||||
|
||||
if (c == 0)
|
||||
{
|
||||
end();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bSendCleanupToScene = true;
|
||||
m_pNextScene = m_pobScenesStack->getObjectAtIndex(c - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void CCDirector::end(void)
|
||||
{
|
||||
// don't release the event handlers
|
||||
// They are needed in case the director is run again
|
||||
CCTouchDispatcher::sharedDispatcher()->removeAllDelegates();
|
||||
|
||||
m_pRunningScene->onExit();
|
||||
m_pRunningScene->cleanup();
|
||||
m_pRunningScene->release();
|
||||
|
||||
m_pRunningScene = NULL;
|
||||
m_pNextScene = NULL;
|
||||
|
||||
// remove all objects, but don't release it.
|
||||
// runWithScene might be executed after 'end'.
|
||||
m_pobScenesStack->removeAllObjects();
|
||||
|
||||
stopAnimation();
|
||||
|
||||
#if CC_DIRECTOR_FAST_FPS
|
||||
CCX_SAFE_RELEASE_NULL(m_pFPSLabel);
|
||||
#endif
|
||||
|
||||
CCX_SAFE_RELEASE_NULL(m_pProjectionDelegate);
|
||||
|
||||
// purge bitmap cache
|
||||
CCLabelBMFont::purgeCachedData();
|
||||
|
||||
// purge all managers
|
||||
CCAnimationCache::purgeSharedAnimationCache();
|
||||
CCSpriteFrameCache::purgeSharedSpriteFrameCache();
|
||||
CCActionManager::sharedManager()->purgeSharedManager();
|
||||
CCScheduler::purgeSharedScheduler();
|
||||
CCTextureCache::purgeSharedTextureCache();
|
||||
|
||||
// OpenGL view
|
||||
[m_pobOpenGLView release];
|
||||
m_pobOpenGLView = NULL;
|
||||
}
|
||||
|
||||
void CCDirector::setNextScene(void)
|
||||
{
|
||||
ccSceneFlag runningSceneType = ccNormalScene;
|
||||
ccSceneFlag newSceneType = m_pNextScene->getSceneType();
|
||||
|
||||
if (m_pRunningScene)
|
||||
{
|
||||
runningSceneType = m_pRunningScene->getSceneType();
|
||||
}
|
||||
|
||||
// If it is not a transition, call onExit/cleanup
|
||||
/*if (! newIsTransition)*/
|
||||
if (! (newSceneType & ccTransitionScene))
|
||||
{
|
||||
if (m_pRunningScene)
|
||||
{
|
||||
m_pRunningScene->onExit();
|
||||
}
|
||||
|
||||
// issue #709. the root node (scene) should receive the cleanup message too
|
||||
// otherwise it might be leaked.
|
||||
if (m_bSendCleanupToScene && m_pRunningScene)
|
||||
{
|
||||
m_pRunningScene->cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pRunningScene)
|
||||
{
|
||||
m_pRunningScene->release();
|
||||
}
|
||||
m_pRunningScene = m_pNextScene;
|
||||
m_pNextScene->retain();
|
||||
m_pNextScene = NULL;
|
||||
|
||||
if (! (runningSceneType & ccTransitionScene) && m_pRunningScene)
|
||||
{
|
||||
m_pRunningScene->onEnter();
|
||||
m_pRunningScene->onEnterTransitionDidFinish();
|
||||
}
|
||||
}
|
||||
|
||||
void CCDirector::pause(void)
|
||||
{
|
||||
if (m_bPaused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_dOldAnimationInterval = m_dAnimationInterval;
|
||||
|
||||
// when paused, don't consume CPU
|
||||
setAnimationInterval(1 / 4.0);
|
||||
m_bPaused = true;
|
||||
}
|
||||
|
||||
void CCDirector::resume(void)
|
||||
{
|
||||
if (! m_bPaused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setAnimationInterval(m_dOldAnimationInterval);
|
||||
|
||||
if (CCTime::gettimeofdayCocos2d(m_pLastUpdate, NULL) != 0)
|
||||
{
|
||||
CCLOG("cocos2d: Director: Error in gettimeofday");
|
||||
}
|
||||
|
||||
m_bPaused = false;
|
||||
m_fDeltaTime = 0;
|
||||
}
|
||||
|
||||
void CCDirector::startAnimation(void)
|
||||
{
|
||||
CCLOG("cocos2d: Director#startAnimation. Overrride me");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CCDirector::stopAnimation(void)
|
||||
{
|
||||
CCLOG("cocos2d: Director#stopAnimation. Overrride me");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CCDirector::mainLoop(void)
|
||||
{
|
||||
CCLOG("cocos2d: Director#preMainLoop. Overrride me");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
#if CC_DIRECTOR_FAST_FPS
|
||||
// display the FPS using a LabelAtlas
|
||||
// updates the FPS every frame
|
||||
void CCDirector::showFPS(void)
|
||||
{
|
||||
sprintf(m_pszFPS, "%.1f", m_fFrameRate);
|
||||
m_pFPSLabel->setString(m_pszFPS);
|
||||
|
||||
m_pFPSLabel->draw();
|
||||
}
|
||||
#endif // CC_DIRECTOR_FAST_FPS
|
||||
|
||||
void CCDirector::calculateFramerateDeltaTime(void)
|
||||
{
|
||||
struct cc_timeval now;
|
||||
|
||||
if (CCTime::gettimeofdayCocos2d(&now, NULL) != 0)
|
||||
{
|
||||
CCLOG("error in gettimeofday");
|
||||
m_fComputeFrameRateDeltaTime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
m_fComputeFrameRateDeltaTime = (now.tv_sec - m_pLastComputeFrameRate->tv_sec) + (now.tv_usec - m_pLastComputeFrameRate->tv_usec) / 1000000.0f;
|
||||
m_fComputeFrameRateDeltaTime = MAX(0, m_fComputeFrameRateDeltaTime);
|
||||
|
||||
*m_pLastComputeFrameRate = now;
|
||||
}
|
||||
|
||||
void CCDirector::computeFrameRate()
|
||||
{
|
||||
static bool bInvoked = true;
|
||||
|
||||
// compute delta time
|
||||
calculateFramerateDeltaTime();
|
||||
|
||||
// only add frames if the director really draw the scene
|
||||
if (bInvoked)
|
||||
{
|
||||
m_nFrames++;
|
||||
}
|
||||
|
||||
m_fAccumDt += m_fComputeFrameRateDeltaTime;
|
||||
|
||||
if (m_fAccumDt > CC_DIRECTOR_FPS_INTERVAL)
|
||||
{
|
||||
m_fFrameRate = m_nFrames / m_fAccumDt;
|
||||
|
||||
if (m_fFrameRate > m_fExpectedFrameRate)
|
||||
{
|
||||
bInvoked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nFrames = 0;
|
||||
m_fAccumDt = 0;
|
||||
bInvoked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCDirector::showProfilers()
|
||||
{
|
||||
#if CC_ENABLE_PROFILERS
|
||||
m_fAccumDtForProfiler += m_fDeltaTime;
|
||||
if (m_fAccumDtForProfiler > 1.0f)
|
||||
{
|
||||
m_fAccumDtForProfiler = 0;
|
||||
CCProfiler::sharedProfiler()->displayTimers();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* mobile platforms specific functions
|
||||
**************************************************/
|
||||
|
||||
// is the view currently attached
|
||||
bool CCDirector::isOpenGLAttached(void)
|
||||
{
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
void CCDirector::updateContentScaleFactor()
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
// detach or attach to a view or a window
|
||||
bool CCDirector::detach(void)
|
||||
{
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
void CCDirector::setDepthBufferFormat(tDepthBufferFormat kDepthBufferFormat)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void CCDirector::setPixelFormat(tPixelFormat kPixelFormat)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
tPixelFormat CCDirector::getPiexFormat(void)
|
||||
{
|
||||
assert(false);
|
||||
return m_ePixelFormat;
|
||||
}
|
||||
|
||||
bool CCDirector::setDirectorType(ccDirectorType obDirectorType)
|
||||
{
|
||||
// we only support CCDisplayLinkDirector
|
||||
CCDirector::sharedDirector();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCDirector::enableRetinaDisplay(bool enabled)
|
||||
{
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
CGFloat CCDirector::getContentScaleFactor(void)
|
||||
{
|
||||
assert(false);
|
||||
return m_fContentScaleFactor;
|
||||
}
|
||||
|
||||
void CCDirector::setContentScaleFactor(CGFloat scaleFactor)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void CCDirector::applyOrientation(void)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
ccDeviceOrientation CCDirector::getDeviceOrientation(void)
|
||||
{
|
||||
assert(false);
|
||||
return m_eDeviceOrientation;
|
||||
}
|
||||
|
||||
void CCDirector::setDeviceOrientation(ccDeviceOrientation kDeviceOrientation)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
/***************************************************
|
||||
* PC platforms specific functions, such as mac
|
||||
**************************************************/
|
||||
|
||||
CGPoint CCDirector::convertEventToGL(NSEvent *event);
|
||||
{
|
||||
///@todo NSEvent have not implemented
|
||||
return CGPointZero;
|
||||
}
|
||||
|
||||
bool CCDirector::isFullScreen(void)
|
||||
{
|
||||
return m_bIsFullScreen;
|
||||
}
|
||||
|
||||
void CCDirector::setResizeMode(int resizeMode)
|
||||
{
|
||||
assert("not supported.");
|
||||
}
|
||||
|
||||
int CCDirector::getResizeMode(void);
|
||||
{
|
||||
assert("not supported.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CCDirector::setFullScreen(bool fullscreen)
|
||||
{
|
||||
// Mac OS X 10.6 and later offer a simplified mechanism to create full-screen contexts
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5
|
||||
|
||||
if( m_bIsFullScreen != fullscreen )
|
||||
{
|
||||
m_bIsFullScreen = fullscreen;
|
||||
|
||||
if( fullscreen )
|
||||
{
|
||||
// create the fullscreen view/window
|
||||
NSRect mainDisplayRect, viewRect;
|
||||
|
||||
// Create a screen-sized window on the display you want to take over
|
||||
// Note, mainDisplayRect has a non-zero origin if the key window is on a secondary display
|
||||
mainDisplayRect = [[NSScreen mainScreen] frame];
|
||||
m_pFullScreenWindow = [[NSWindow alloc] initWithContentRect:mainDisplayRect
|
||||
styleMask:NSBorderlessWindowMask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:YES];
|
||||
|
||||
// Set the window level to be above the menu bar
|
||||
[m_pFullScreenWindow setLevel:NSMainMenuWindowLevel+1];
|
||||
|
||||
// Perform any other window configuration you desire
|
||||
[m_pFullScreenWindow setOpaque:YES];
|
||||
[m_pFullScreenWindow setHidesOnDeactivate:YES];
|
||||
|
||||
// Create a view with a double-buffered OpenGL context and attach it to the window
|
||||
// By specifying the non-fullscreen context as the shareContext, we automatically inherit the OpenGL objects (textures, etc) it has defined
|
||||
viewRect = NSMakeRect(0.0, 0.0, mainDisplayRect.size.width, mainDisplayRect.size.height);
|
||||
|
||||
m_pFullScreenGLView = [[MacGLView alloc] initWithFrame:viewRect shareContext:[m_pobOpenGLView openGLContext]];
|
||||
|
||||
[m_pFullScreenWindow setContentView:m_pFullScreenGLView];
|
||||
|
||||
// Show the window
|
||||
[m_pFullScreenWindow makeKeyAndOrderFront:self];
|
||||
|
||||
[self setOpenGLView:fullScreenGLView_];
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
[m_pFullScreenWindow release];
|
||||
[m_pFullScreenGLView release];
|
||||
m_pFullScreenWindow = nil;
|
||||
m_pFullScreenGLView = nil;
|
||||
|
||||
[[m_pFullScreenGLView openGLContext] makeCurrentContext];
|
||||
setOpenGLView(m_pFullScreenGLView);
|
||||
}
|
||||
|
||||
[m_pobOpenGLView setNeedsDisplay:YES];
|
||||
}
|
||||
#else
|
||||
#error Full screen is not supported for Mac OS 10.5 or older yet
|
||||
#error If you don't want FullScreen support, you can safely remove these 2 lines
|
||||
#endif
|
||||
}
|
||||
|
||||
CGPoint CCDirector::convertToLogicalCoordinates(CGPoint coordinates)
|
||||
{
|
||||
CGPoint ret;
|
||||
|
||||
if( m_nResizeMode == kCCDirectorResize_NoScale )
|
||||
{
|
||||
ret = coordinates;
|
||||
}
|
||||
else
|
||||
{
|
||||
float x_diff = m_originalWinSize.width / (m_obWinSizeInPixels.width - m_winOffset.x * 2);
|
||||
float y_diff = m_originalWinSize.height / (m_obWinSizeInPixels.height - m_winOffset.y * 2);
|
||||
|
||||
float adjust_x = (m_obWinSizeInPixels.width * x_diff - m_originalWinSize.width ) / 2;
|
||||
float adjust_y = (m_obWinSizeInPixels.height * y_diff - m_originalWinSize.height ) / 2;
|
||||
|
||||
ret = CGPointMake( (x_diff * coordinates.x) - adjust_x, ( y_diff * coordinates.y ) - adjust_y );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************
|
||||
* implementation of DisplayLinkDirector
|
||||
**************************************************/
|
||||
|
||||
// should we afford 4 types of director ??
|
||||
// I think DisplayLinkDirector is enough
|
||||
// so we now only support DisplayLinkDirector
|
||||
void CCDisplayLinkDirector::startAnimation(void)
|
||||
{
|
||||
if (CCTime::gettimeofdayCocos2d(m_pLastUpdate, NULL) != 0)
|
||||
{
|
||||
CCLOG("cocos2d: DisplayLinkDirector: Error on gettimeofday");
|
||||
}
|
||||
|
||||
m_bInvalid = false;
|
||||
|
||||
[[CCDirectorDisplayLinkMacWrapper sharedDisplayLinkMacWrapper] startAnimation];
|
||||
}
|
||||
|
||||
void CCDisplayLinkDirector::mainLoop(void)
|
||||
{
|
||||
if (! m_bInvalid)
|
||||
{
|
||||
// compute frame rate
|
||||
computeFrameRate();
|
||||
|
||||
// control frame rate
|
||||
if (m_fFrameRate <= m_fExpectedFrameRate)
|
||||
{
|
||||
drawScene();
|
||||
|
||||
// release the objects
|
||||
NSPoolManager::getInstance()->pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCDisplayLinkDirector::stopAnimation(void)
|
||||
{
|
||||
m_bInvalid = true;
|
||||
|
||||
[[CCDirectorDisplayLinkMacWrapper sharedDisplayLinkMacWrapper] stopAnimation];
|
||||
}
|
||||
|
||||
void CCDisplayLinkDirector::setAnimationInterval(double dValue)
|
||||
{
|
||||
m_dAnimationInterval = dValue;
|
||||
m_fExpectedFrameRate = (ccTime)(1 / m_dAnimationInterval);
|
||||
if (! m_bInvalid)
|
||||
{
|
||||
stopAnimation();
|
||||
startAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace cocos2d
|
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* cocos2d for iPhone: http://www.cocos2d-iphone.org
|
||||
*
|
||||
* Copyright (c) 2010 Ricardo Quesada
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Only compile this code on Mac. These files should not be included on your iOS project.
|
||||
// But in case they are included, it won't be compiled.
|
||||
#import <Availability.h>
|
||||
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
|
||||
#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "MacGLView.h"
|
||||
#import "../../Support/uthash.h" // hack: uthash needs to be imported before utlist to prevent warning
|
||||
#import "../../Support/utlist.h"
|
||||
#import "../../ccConfig.h"
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark CCMouseEventDelegate
|
||||
|
||||
/** CCMouseEventDelegate protocol.
|
||||
Implement it in your node to receive any of mouse events
|
||||
*/
|
||||
@protocol CCMouseEventDelegate <NSObject>
|
||||
@optional
|
||||
|
||||
//
|
||||
// left
|
||||
//
|
||||
/** called when the "mouseDown" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
-(BOOL) ccMouseDown:(NSEvent*)event;
|
||||
|
||||
/** called when the "mouseDragged" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
-(BOOL) ccMouseDragged:(NSEvent*)event;
|
||||
|
||||
/** called when the "mouseMoved" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
By default, "mouseMoved" is disabled. To enable it, send the "setAcceptsMouseMovedEvents:YES" message to the main window.
|
||||
*/
|
||||
-(BOOL) ccMouseMoved:(NSEvent*)event;
|
||||
|
||||
/** called when the "mouseUp" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
-(BOOL) ccMouseUp:(NSEvent*)event;
|
||||
|
||||
|
||||
//
|
||||
// right
|
||||
//
|
||||
|
||||
/** called when the "rightMouseDown" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
-(BOOL) ccRightMouseDown:(NSEvent*)event;
|
||||
|
||||
/** called when the "rightMouseDragged" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
-(BOOL) ccRightMouseDragged:(NSEvent*)event;
|
||||
|
||||
/** called when the "rightMouseUp" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
-(BOOL) ccRightMouseUp:(NSEvent*)event;
|
||||
|
||||
//
|
||||
// other
|
||||
//
|
||||
|
||||
/** called when the "otherMouseDown" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
-(BOOL) ccOtherMouseDown:(NSEvent*)event;
|
||||
|
||||
/** called when the "otherMouseDragged" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
-(BOOL) ccOtherMouseDragged:(NSEvent*)event;
|
||||
|
||||
/** called when the "otherMouseUp" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
-(BOOL) ccOtherMouseUp:(NSEvent*)event;
|
||||
|
||||
//
|
||||
// scroll wheel
|
||||
//
|
||||
|
||||
/** called when the "scrollWheel" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
- (BOOL)ccScrollWheel:(NSEvent *)theEvent;
|
||||
|
||||
|
||||
//
|
||||
// enter / exit
|
||||
//
|
||||
|
||||
/** called when the "mouseEntered" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
- (void)ccMouseEntered:(NSEvent *)theEvent;
|
||||
|
||||
/** called when the "mouseExited" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
- (void)ccMouseExited:(NSEvent *)theEvent;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark CCKeyboardEventDelegate
|
||||
|
||||
/** CCKeyboardEventDelegate protocol.
|
||||
Implement it in your node to receive any of keyboard events
|
||||
*/
|
||||
@protocol CCKeyboardEventDelegate <NSObject>
|
||||
@optional
|
||||
/** called when the "keyUp" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
-(BOOL) ccKeyUp:(NSEvent*)event;
|
||||
|
||||
/** called when the "keyDown" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
-(BOOL) ccKeyDown:(NSEvent*)event;
|
||||
/** called when the "flagsChanged" event is received.
|
||||
Return YES to avoid propagating the event to other delegates.
|
||||
*/
|
||||
-(BOOL) ccFlagsChanged:(NSEvent*)event;
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark CCEventDispatcher
|
||||
|
||||
struct _listEntry;
|
||||
|
||||
/** CCEventDispatcher
|
||||
|
||||
This is object is responsible for dispatching the events:
|
||||
- Mouse events
|
||||
- Keyboard events
|
||||
- Touch events
|
||||
|
||||
Only available on Mac
|
||||
*/
|
||||
@interface CCEventDispatcher : NSObject <MacEventDelegate> {
|
||||
|
||||
BOOL dispatchEvents_;
|
||||
|
||||
struct _listEntry *keyboardDelegates_;
|
||||
struct _listEntry *mouseDelegates_;
|
||||
}
|
||||
|
||||
@property (nonatomic, readwrite) BOOL dispatchEvents;
|
||||
|
||||
|
||||
/** CCEventDispatcher singleton */
|
||||
+(CCEventDispatcher*) sharedDispatcher;
|
||||
|
||||
#pragma mark CCEventDispatcher - Mouse
|
||||
|
||||
/** Adds a mouse delegate to the dispatcher's list.
|
||||
Delegates with a lower priority value will be called before higher priority values.
|
||||
All the events will be propgated to all the delegates, unless the one delegate returns YES.
|
||||
|
||||
IMPORTANT: The delegate will be retained.
|
||||
*/
|
||||
-(void) addMouseDelegate:(id<CCMouseEventDelegate>) delegate priority:(NSInteger)priority;
|
||||
|
||||
/** removes a mouse delegate */
|
||||
-(void) removeMouseDelegate:(id) delegate;
|
||||
|
||||
/** Removes all mouse delegates, releasing all the delegates */
|
||||
-(void) removeAllMouseDelegates;
|
||||
|
||||
#pragma mark CCEventDispatcher - Keyboard
|
||||
|
||||
/** Adds a Keyboard delegate to the dispatcher's list.
|
||||
Delegates with a lower priority value will be called before higher priority values.
|
||||
All the events will be propgated to all the delegates, unless the one delegate returns YES.
|
||||
|
||||
IMPORTANT: The delegate will be retained.
|
||||
*/
|
||||
-(void) addKeyboardDelegate:(id<CCKeyboardEventDelegate>) delegate priority:(NSInteger)priority;
|
||||
|
||||
/** removes a mouse delegate */
|
||||
-(void) removeKeyboardDelegate:(id) delegate;
|
||||
|
||||
/** Removes all mouse delegates, releasing all the delegates */
|
||||
-(void) removeAllKeyboardDelegates;
|
||||
|
||||
#pragma mark CCEventDispatcher - Touches
|
||||
|
||||
// XXX
|
||||
|
||||
#pragma mark CCEventDispatcher - Dispatch Events
|
||||
|
||||
#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
|
||||
-(void) dispatchQueuedEvents;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#endif // __MAC_OS_X_VERSION_MAX_ALLOWED
|
|
@ -0,0 +1,578 @@
|
|||
/*
|
||||
* cocos2d for iPhone: http://www.cocos2d-iphone.org
|
||||
*
|
||||
* Copyright (c) 2010 Ricardo Quesada
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Only compile this code on Mac. These files should not be included on your iOS project.
|
||||
// But in case they are included, it won't be compiled.
|
||||
#import <Availability.h>
|
||||
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
|
||||
#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
|
||||
|
||||
#import "CCEventDispatcher.h"
|
||||
#import "../../ccConfig.h"
|
||||
|
||||
static CCEventDispatcher *sharedDispatcher = nil;
|
||||
|
||||
enum {
|
||||
// mouse
|
||||
kCCImplementsMouseDown = 1 << 0,
|
||||
kCCImplementsMouseMoved = 1 << 1,
|
||||
kCCImplementsMouseDragged = 1 << 2,
|
||||
kCCImplementsMouseUp = 1 << 3,
|
||||
kCCImplementsRightMouseDown = 1 << 4,
|
||||
kCCImplementsRightMouseDragged = 1 << 5,
|
||||
kCCImplementsRightMouseUp = 1 << 6,
|
||||
kCCImplementsOtherMouseDown = 1 << 7,
|
||||
kCCImplementsOtherMouseDragged = 1 << 8,
|
||||
kCCImplementsOtherMouseUp = 1 << 9,
|
||||
kCCImplementsScrollWheel = 1 << 10,
|
||||
kCCImplementsMouseEntered = 1 << 11,
|
||||
kCCImplementsMouseExited = 1 << 12,
|
||||
|
||||
// keyboard
|
||||
kCCImplementsKeyUp = 1 << 0,
|
||||
kCCImplementsKeyDown = 1 << 1,
|
||||
kCCImplementsFlagsChanged = 1 << 2,
|
||||
};
|
||||
|
||||
|
||||
typedef struct _listEntry
|
||||
{
|
||||
struct _listEntry *prev, *next;
|
||||
id delegate;
|
||||
NSInteger priority;
|
||||
NSUInteger flags;
|
||||
} tListEntry;
|
||||
|
||||
|
||||
#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
|
||||
|
||||
#define QUEUE_EVENT_MAX 128
|
||||
struct _eventQueue {
|
||||
SEL selector;
|
||||
NSEvent *event;
|
||||
};
|
||||
|
||||
static struct _eventQueue eventQueue[QUEUE_EVENT_MAX];
|
||||
static int eventQueueCount;
|
||||
|
||||
#endif // CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
|
||||
|
||||
|
||||
@implementation CCEventDispatcher
|
||||
|
||||
@synthesize dispatchEvents=dispatchEvents_;
|
||||
|
||||
|
||||
+(CCEventDispatcher*) sharedDispatcher
|
||||
{
|
||||
@synchronized(self) {
|
||||
if (sharedDispatcher == nil)
|
||||
sharedDispatcher = [[self alloc] init]; // assignment not done here
|
||||
}
|
||||
return sharedDispatcher;
|
||||
}
|
||||
|
||||
+(id) allocWithZone:(NSZone *)zone
|
||||
{
|
||||
@synchronized(self) {
|
||||
NSAssert(sharedDispatcher == nil, @"Attempted to allocate a second instance of a singleton.");
|
||||
return [super allocWithZone:zone];
|
||||
}
|
||||
return nil; // on subsequent allocation attempts return nil
|
||||
}
|
||||
|
||||
-(id) init
|
||||
{
|
||||
if( (self = [super init]) )
|
||||
{
|
||||
// events enabled by default
|
||||
dispatchEvents_ = YES;
|
||||
|
||||
// delegates
|
||||
keyboardDelegates_ = NULL;
|
||||
mouseDelegates_ = NULL;
|
||||
|
||||
#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
|
||||
eventQueueCount = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
#pragma mark CCEventDispatcher - add / remove delegates
|
||||
|
||||
-(void) addDelegate:(id)delegate priority:(NSInteger)priority flags:(NSUInteger)flags list:(tListEntry**)list
|
||||
{
|
||||
tListEntry *listElement = malloc( sizeof(*listElement) );
|
||||
|
||||
listElement->delegate = [delegate retain];
|
||||
listElement->priority = priority;
|
||||
listElement->flags = flags;
|
||||
listElement->next = listElement->prev = NULL;
|
||||
|
||||
// empty list ?
|
||||
if( ! *list ) {
|
||||
DL_APPEND( *list, listElement );
|
||||
|
||||
} else {
|
||||
BOOL added = NO;
|
||||
|
||||
for( tListEntry *elem = *list; elem ; elem = elem->next ) {
|
||||
if( priority < elem->priority ) {
|
||||
|
||||
if( elem == *list )
|
||||
DL_PREPEND(*list, listElement);
|
||||
else {
|
||||
listElement->next = elem;
|
||||
listElement->prev = elem->prev;
|
||||
|
||||
elem->prev->next = listElement;
|
||||
elem->prev = listElement;
|
||||
}
|
||||
|
||||
added = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Not added? priority has the higher value. Append it.
|
||||
if( !added )
|
||||
DL_APPEND(*list, listElement);
|
||||
}
|
||||
}
|
||||
|
||||
-(void) removeDelegate:(id)delegate fromList:(tListEntry**)list
|
||||
{
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
// updates with priority < 0
|
||||
DL_FOREACH_SAFE( *list, entry, tmp ) {
|
||||
if( entry->delegate == delegate ) {
|
||||
DL_DELETE( *list, entry );
|
||||
[delegate release];
|
||||
free(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void) removeAllDelegatesFromList:(tListEntry**)list
|
||||
{
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( *list, entry, tmp ) {
|
||||
DL_DELETE( *list, entry );
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void) addMouseDelegate:(id<CCMouseEventDelegate>) delegate priority:(NSInteger)priority
|
||||
{
|
||||
NSUInteger flags = 0;
|
||||
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccMouseDown:)] ? kCCImplementsMouseDown : 0 );
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccMouseDragged:)] ? kCCImplementsMouseDragged : 0 );
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccMouseMoved:)] ? kCCImplementsMouseMoved : 0 );
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccMouseUp:)] ? kCCImplementsMouseUp : 0 );
|
||||
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccRightMouseDown:)] ? kCCImplementsRightMouseDown : 0 );
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccRightMouseDragged:)] ? kCCImplementsRightMouseDragged : 0 );
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccRightMouseUp:)] ? kCCImplementsRightMouseUp : 0 );
|
||||
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccOtherMouseDown:)] ? kCCImplementsOtherMouseDown : 0 );
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccOtherMouseDragged:)] ? kCCImplementsOtherMouseDragged : 0 );
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccOtherMouseUp:)] ? kCCImplementsOtherMouseUp : 0 );
|
||||
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccMouseEntered:)] ? kCCImplementsMouseEntered : 0 );
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccMouseExited:)] ? kCCImplementsMouseExited : 0 );
|
||||
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccScrollWheel:)] ? kCCImplementsScrollWheel : 0 );
|
||||
|
||||
[self addDelegate:delegate priority:priority flags:flags list:&mouseDelegates_];
|
||||
}
|
||||
|
||||
-(void) removeMouseDelegate:(id) delegate
|
||||
{
|
||||
[self removeDelegate:delegate fromList:&mouseDelegates_];
|
||||
}
|
||||
|
||||
-(void) removeAllMouseDelegates
|
||||
{
|
||||
[self removeAllDelegatesFromList:&mouseDelegates_];
|
||||
}
|
||||
|
||||
-(void) addKeyboardDelegate:(id<CCKeyboardEventDelegate>) delegate priority:(NSInteger)priority
|
||||
{
|
||||
NSUInteger flags = 0;
|
||||
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccKeyUp:)] ? kCCImplementsKeyUp : 0 );
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccKeyDown:)] ? kCCImplementsKeyDown : 0 );
|
||||
flags |= ( [delegate respondsToSelector:@selector(ccFlagsChanged:)] ? kCCImplementsFlagsChanged : 0 );
|
||||
|
||||
[self addDelegate:delegate priority:priority flags:flags list:&keyboardDelegates_];
|
||||
}
|
||||
|
||||
-(void) removeKeyboardDelegate:(id) delegate
|
||||
{
|
||||
[self removeDelegate:delegate fromList:&keyboardDelegates_];
|
||||
}
|
||||
|
||||
-(void) removeAllKeyboardDelegates
|
||||
{
|
||||
[self removeAllDelegatesFromList:&keyboardDelegates_];
|
||||
}
|
||||
|
||||
#pragma mark CCEventDispatcher - Mouse events
|
||||
//
|
||||
// Mouse events
|
||||
//
|
||||
|
||||
//
|
||||
// Left
|
||||
//
|
||||
- (void)mouseDown:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsMouseDown ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccMouseDown:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseMoved:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsMouseMoved ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccMouseMoved:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseDragged:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsMouseDragged ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccMouseDragged:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseUp:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsMouseUp ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccMouseUp:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Mouse Right
|
||||
//
|
||||
- (void)rightMouseDown:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsRightMouseDown ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccRightMouseDown:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)rightMouseDragged:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsRightMouseDragged ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccRightMouseDragged:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)rightMouseUp:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsRightMouseUp ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccRightMouseUp:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Mouse Other
|
||||
//
|
||||
- (void)otherMouseDown:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsOtherMouseDown ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccOtherMouseDown:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)otherMouseDragged:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsOtherMouseDragged ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccOtherMouseDragged:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)otherMouseUp:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsOtherMouseUp ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccOtherMouseUp:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Scroll Wheel
|
||||
//
|
||||
- (void)scrollWheel:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsScrollWheel ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccScrollWheel:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Mouse enter / exit
|
||||
- (void)mouseExited:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsMouseEntered ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccMouseEntered:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseEntered:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsMouseExited) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccMouseExited:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark CCEventDispatcher - Keyboard events
|
||||
|
||||
// Keyboard events
|
||||
- (void)keyDown:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( keyboardDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsKeyDown ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccKeyDown:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)keyUp:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( keyboardDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsKeyUp ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccKeyUp:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)flagsChanged:(NSEvent *)event
|
||||
{
|
||||
if( dispatchEvents_ ) {
|
||||
tListEntry *entry, *tmp;
|
||||
|
||||
DL_FOREACH_SAFE( keyboardDelegates_, entry, tmp ) {
|
||||
if ( entry->flags & kCCImplementsKeyUp ) {
|
||||
void *swallows = [entry->delegate performSelector:@selector(ccFlagsChanged:) withObject:event];
|
||||
if( swallows )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark CCEventDispatcher - Touch events
|
||||
|
||||
- (void)touchesBeganWithEvent:(NSEvent *)event
|
||||
{
|
||||
if (dispatchEvents_ ) {
|
||||
NSLog(@"Touch Events: Not supported yet");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)touchesMovedWithEvent:(NSEvent *)event
|
||||
{
|
||||
if (dispatchEvents_ ) {
|
||||
NSLog(@"Touch Events: Not supported yet");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)touchesEndedWithEvent:(NSEvent *)event
|
||||
{
|
||||
if (dispatchEvents_ ) {
|
||||
NSLog(@"Touch Events: Not supported yet");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)touchesCancelledWithEvent:(NSEvent *)event
|
||||
{
|
||||
if (dispatchEvents_ ) {
|
||||
NSLog(@"Touch Events: Not supported yet");
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark CCEventDispatcher - queue events
|
||||
|
||||
#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
|
||||
-(void) queueEvent:(NSEvent*)event selector:(SEL)selector
|
||||
{
|
||||
NSAssert( eventQueueCount < QUEUE_EVENT_MAX, @"CCEventDispatcher: recompile. Increment QUEUE_EVENT_MAX value");
|
||||
|
||||
eventQueue[eventQueueCount].selector = selector;
|
||||
eventQueue[eventQueueCount].event = [event copy];
|
||||
|
||||
eventQueueCount++;
|
||||
}
|
||||
|
||||
-(void) dispatchQueuedEvents
|
||||
{
|
||||
for( int i=0; i < eventQueueCount; i++ ) {
|
||||
SEL sel = eventQueue[i].selector;
|
||||
NSEvent *event = eventQueue[i].event;
|
||||
|
||||
[self performSelector:sel withObject:event];
|
||||
|
||||
[event release];
|
||||
}
|
||||
|
||||
eventQueueCount = 0;
|
||||
}
|
||||
#endif // CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
|
||||
|
||||
|
||||
@end
|
||||
|
||||
#endif // __MAC_OS_X_VERSION_MAX_ALLOWED
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* cocos2d for iPhone: http://www.cocos2d-iphone.org
|
||||
*
|
||||
* Copyright (c) 2010 Ricardo Quesada
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Only compile this code on Mac. These files should not be included on your iOS project.
|
||||
// But in case they are included, it won't be compiled.
|
||||
#import <Availability.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "ccConfig.h"
|
||||
|
||||
//PROTOCOLS:
|
||||
|
||||
@protocol MacEventDelegate <NSObject>
|
||||
// Mouse
|
||||
- (void)mouseDown:(NSEvent *)theEvent;
|
||||
- (void)mouseUp:(NSEvent *)theEvent;
|
||||
- (void)mouseMoved:(NSEvent *)theEvent;
|
||||
- (void)mouseDragged:(NSEvent *)theEvent;
|
||||
- (void)rightMouseDown:(NSEvent*)event;
|
||||
- (void)rightMouseDragged:(NSEvent*)event;
|
||||
- (void)rightMouseUp:(NSEvent*)event;
|
||||
- (void)otherMouseDown:(NSEvent*)event;
|
||||
- (void)otherMouseDragged:(NSEvent*)event;
|
||||
- (void)otherMouseUp:(NSEvent*)event;
|
||||
- (void)scrollWheel:(NSEvent *)theEvent;
|
||||
- (void)mouseEntered:(NSEvent *)theEvent;
|
||||
- (void)mouseExited:(NSEvent *)theEvent;
|
||||
|
||||
|
||||
// Keyboard
|
||||
- (void)keyDown:(NSEvent *)theEvent;
|
||||
- (void)keyUp:(NSEvent *)theEvent;
|
||||
- (void)flagsChanged:(NSEvent *)theEvent;
|
||||
|
||||
// Touches
|
||||
- (void)touchesBeganWithEvent:(NSEvent *)event;
|
||||
- (void)touchesMovedWithEvent:(NSEvent *)event;
|
||||
- (void)touchesEndedWithEvent:(NSEvent *)event;
|
||||
- (void)touchesCancelledWithEvent:(NSEvent *)event;
|
||||
|
||||
#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
|
||||
- (void)queueEvent:(NSEvent*)event selector:(SEL)selector;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
/** MacGLView
|
||||
|
||||
Only available for Mac OS X
|
||||
*/
|
||||
@interface MacGLView : NSOpenGLView {
|
||||
id<MacEventDelegate> eventDelegate_;
|
||||
}
|
||||
|
||||
@property (nonatomic, readwrite, assign) id<MacEventDelegate> eventDelegate;
|
||||
|
||||
// initializes the MacGLView with a frame rect and an OpenGL context
|
||||
- (id) initWithFrame:(NSRect)frameRect shareContext:(NSOpenGLContext*)context;
|
||||
|
||||
// private
|
||||
+(void) load_;
|
||||
@end
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* cocos2d for iPhone: http://www.cocos2d-iphone.org
|
||||
*
|
||||
* Copyright (c) 2010 Ricardo Quesada
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Idea of subclassing NSOpenGLView was taken from "TextureUpload" Apple's sample
|
||||
*/
|
||||
|
||||
// Only compile this code on Mac. These files should not be included on your iOS project.
|
||||
// But in case they are included, it won't be compiled.
|
||||
#import <Availability.h>
|
||||
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
|
||||
#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
|
||||
|
||||
#import "MacGLView.h"
|
||||
#import <OpenGL/gl.h>
|
||||
|
||||
#import "CCDirectorMac.h"
|
||||
#import "ccConfig.h"
|
||||
|
||||
|
||||
@implementation MacGLView
|
||||
|
||||
@synthesize eventDelegate = eventDelegate_;
|
||||
|
||||
+(void) load_
|
||||
{
|
||||
NSLog(@"%@ loaded", self);
|
||||
}
|
||||
|
||||
- (id) initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
self = [self initWithFrame:frameRect shareContext:nil];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithFrame:(NSRect)frameRect shareContext:(NSOpenGLContext*)context
|
||||
{
|
||||
NSOpenGLPixelFormatAttribute attribs[] =
|
||||
{
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFANoRecovery,
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFADepthSize, 24,
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
||||
|
||||
if (!pixelFormat)
|
||||
NSLog(@"No OpenGL pixel format");
|
||||
|
||||
if (self = [super initWithFrame:frameRect pixelFormat:[pixelFormat autorelease]]) {
|
||||
|
||||
if( context )
|
||||
[self setOpenGLContext:context];
|
||||
|
||||
// Synchronize buffer swaps with vertical refresh rate
|
||||
GLint swapInt = 1;
|
||||
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
||||
|
||||
// GLint order = -1;
|
||||
// [[self openGLContext] setValues:&order forParameter:NSOpenGLCPSurfaceOrder];
|
||||
|
||||
// event delegate
|
||||
eventDelegate_ = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) reshape
|
||||
{
|
||||
// We draw on a secondary thread through the display link
|
||||
// When resizing the view, -reshape is called automatically on the main thread
|
||||
// Add a mutex around to avoid the threads accessing the context simultaneously when resizing
|
||||
CGLLockContext([[self openGLContext] CGLContextObj]);
|
||||
|
||||
NSRect rect = [self bounds];
|
||||
|
||||
CCDirector *director = cocos2d::CCDirector::sharedDirector();
|
||||
director->reshapeProjection(NSSizeToCGSize(rect.size));
|
||||
|
||||
// avoid flicker
|
||||
director->drawScene();
|
||||
// [self setNeedsDisplay:YES];
|
||||
|
||||
CGLUnlockContext([[self openGLContext] CGLContextObj]);
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
|
||||
#define DISPATCH_EVENT(__event__, __selector__) [eventDelegate_ queueEvent:__event__ selector:__selector__];
|
||||
#else
|
||||
#define DISPATCH_EVENT(__event__, __selector__) \
|
||||
id obj = eventDelegate_; \
|
||||
[obj performSelector:__selector__ \
|
||||
onThread:[[CCDirectorDisplayLinkMacWrapper sharedDisplayLinkMacWrapper] runningThread] \
|
||||
withObject:__event__ \
|
||||
waitUntilDone:NO];
|
||||
#endif
|
||||
|
||||
#pragma mark MacGLView - Mouse events
|
||||
- (void)mouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)mouseMoved:(NSEvent *)theEvent
|
||||
{
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)mouseDragged:(NSEvent *)theEvent
|
||||
{
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)mouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)rightMouseDown:(NSEvent *)theEvent {
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)rightMouseDragged:(NSEvent *)theEvent {
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)rightMouseUp:(NSEvent *)theEvent {
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)otherMouseDown:(NSEvent *)theEvent {
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)otherMouseDragged:(NSEvent *)theEvent {
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)otherMouseUp:(NSEvent *)theEvent {
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)mouseEntered:(NSEvent *)theEvent {
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)mouseExited:(NSEvent *)theEvent {
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
-(void) scrollWheel:(NSEvent *)theEvent {
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
#pragma mark MacGLView - Key events
|
||||
|
||||
-(BOOL) becomeFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL) acceptsFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL) resignFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent *)theEvent
|
||||
{
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)keyUp:(NSEvent *)theEvent
|
||||
{
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)flagsChanged:(NSEvent *)theEvent
|
||||
{
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
#pragma mark MacGLView - Touch events
|
||||
- (void)touchesBeganWithEvent:(NSEvent *)theEvent
|
||||
{
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)touchesMovedWithEvent:(NSEvent *)theEvent
|
||||
{
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)touchesEndedWithEvent:(NSEvent *)theEvent
|
||||
{
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
- (void)touchesCancelledWithEvent:(NSEvent *)theEvent
|
||||
{
|
||||
DISPATCH_EVENT(theEvent, _cmd);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif // __MAC_OS_X_VERSION_MAX_ALLOWED
|
|
@ -458,4 +458,15 @@ void CCXEGLView::swapBuffers()
|
|||
}
|
||||
}
|
||||
|
||||
bool CCXEGLView::canSetContentScaleFactor()
|
||||
{
|
||||
// can scale content?
|
||||
return false;
|
||||
}
|
||||
|
||||
void CCXEGLView::setContentScaleFactor(float contentScaleFactor)
|
||||
{
|
||||
// if it supports scaling content, set it
|
||||
}
|
||||
|
||||
} // end of namespace cocos2d
|
||||
|
|
|
@ -55,6 +55,8 @@ public:
|
|||
void release();
|
||||
void setTouchDelegate(EGLTouchDelegate * pDelegate);
|
||||
void swapBuffers();
|
||||
bool canSetContentScaleFactor();
|
||||
void setContentScaleFactor(float contentScaleFactor);
|
||||
|
||||
protected:
|
||||
Boolean OnPenDown(EventType* pEvent, Int32 nIndex);
|
||||
|
|
|
@ -912,6 +912,10 @@
|
|||
<Filter
|
||||
Name="platform"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\platform\CCDirector_mobile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\platform\CCFileUtils_platform.h"
|
||||
>
|
||||
|
@ -1089,10 +1093,6 @@
|
|||
RelativePath="..\CCConfiguration.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CCDirector.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CCDrawingPrimitives.cpp"
|
||||
>
|
||||
|
|
|
@ -102,7 +102,7 @@ namespace cocos2d
|
|||
return err;
|
||||
}
|
||||
|
||||
int ZipUtils::ccccInflateMemory(unsigned char *in, unsigned int inLength, unsigned char **out)
|
||||
int ZipUtils::ccInflateMemory(unsigned char *in, unsigned int inLength, unsigned char **out)
|
||||
{
|
||||
unsigned int outLength = 0;
|
||||
int err = inflateMemory_(in, inLength, out, &outLength);
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace cocos2d
|
|||
*
|
||||
@since v0.8.1
|
||||
*/
|
||||
static int ccccInflateMemory(unsigned char *in, unsigned int inLength, unsigned char **out);
|
||||
static int ccInflateMemory(unsigned char *in, unsigned int inLength, unsigned char **out);
|
||||
|
||||
/** inflates a GZip file into memory
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue