Merge branch 'minggo-upto-0.99.5' into upto-0.99.5

This commit is contained in:
minggo 2010-12-29 18:18:14 +08:00
commit 94c7f968e1
35 changed files with 3822 additions and 954 deletions

View File

@ -27,10 +27,29 @@ THE SOFTWARE.
#include "NSObject.h"
#include <string>
#include <GLES/gl.h>
#include "CCGL.h"
namespace cocos2d {
/** OS version definitions. Includes both iOS and Mac OS versions
*/
enum {
kCCiOSVersion_3_0 = 0x03000000,
kCCiOSVersion_3_1 = 0x03010000,
kCCiOSVersion_3_1_1 = 0x03010100,
kCCiOSVersion_3_1_2 = 0x03010200,
kCCiOSVersion_3_1_3 = 0x03010300,
kCCiOSVersion_3_2 = 0x03020000,
kCCiOSVersion_3_2_1 = 0x03020100,
kCCiOSVersion_4_0 = 0x04000000,
kCCiOSVersion_4_0_1 = 0x04000100,
kCCiOSVersion_4_1 = 0x04010000,
kCCMacVersion_10_5 = 0x0a050000,
kCCMacVersion_10_6 = 0x0a060000,
kCCMacVersion_10_7 = 0x0a070000,
};
/**
@brief CCConfiguration contains some openGL variables
@since v0.99.0
@ -38,12 +57,14 @@ namespace cocos2d {
class CCConfiguration : public NSObject
{
protected:
GLint m_nMaxTextureSize;
GLint m_nMaxModelviewStackDepth;
bool m_bSupportsPVRTC;
bool m_bSupportsNPOT;
bool m_bSupportsBGRA8888;
bool m_bSupportsDiscardFramebuffer;
GLint m_nMaxTextureSize;
GLint m_nMaxModelviewStackDepth;
bool m_bSupportsPVRTC;
bool m_bSupportsNPOT;
bool m_bSupportsBGRA8888;
bool m_bSupportsDiscardFramebuffer;
unsigned int m_uOSVersion;
GLint m_nMaxSamplesAllowed;
public:
CCConfiguration(void);
@ -94,6 +115,14 @@ public:
return m_bSupportsDiscardFramebuffer;
}
/** returns the OS version.
- On iOS devices it returns the firmware version.
- On Mac returns the OS version
@since v0.99.5
*/
inline unsigned int getOSVersion() { return m_uOSVersion; }
/** returns whether or not an OpenGL is supported */
bool checkForGLExtension(const std::string &searchName);

View File

@ -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;

View File

@ -23,6 +23,9 @@ THE SOFTWARE.
****************************************************************************/
#include "CCDrawingPrimitives.h"
#include "ccTypes.h"
#include "ccMacros.h"
#include "CCGL.h"
#include <string.h>
#include <cmath>
@ -36,6 +39,7 @@ namespace cocos2d {
void ccDrawPoint(CGPoint point)
{
ccVertex2F p = {point.x * CC_CONTENT_SCALE_FACTOR(), point.y * CC_CONTENT_SCALE_FACTOR() };
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
// Unneeded states: GL_TEXTURE_2D, GL_TEXTURE_COORD_ARRAY, GL_COLOR_ARRAY
@ -43,7 +47,7 @@ void ccDrawPoint(CGPoint point)
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, &point);
glVertexPointer(2, GL_FLOAT, 0, &p);
glDrawArrays(GL_POINTS, 0, 1);
// restore default state
@ -52,7 +56,7 @@ void ccDrawPoint(CGPoint point)
glEnable(GL_TEXTURE_2D);
}
void ccDrawPoints(CGPoint *points, unsigned int numberOfPoints)
void ccDrawPoints(const CGPoint *points, unsigned int numberOfPoints)
{
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
@ -61,8 +65,41 @@ void ccDrawPoints(CGPoint *points, unsigned int numberOfPoints)
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, points);
glDrawArrays(GL_POINTS, 0, numberOfPoints);
ccVertex2F *newPoints = new ccVertex2F[numberOfPoints];
// iPhone and 32-bit machines optimization
if( sizeof(CGPoint) == sizeof(ccVertex2F) ) {
// points ?
if( CC_CONTENT_SCALE_FACTOR() != 1 )
{
for( unsigned int i= 0; i < numberOfPoints; i++)
{
newPoints[i].x = points[i].x * CC_CONTENT_SCALE_FACTOR();
newPoints[i].y = points[i].y * CC_CONTENT_SCALE_FACTOR();
}
glVertexPointer(2, GL_FLOAT, 0, newPoints);
} else
glVertexPointer(2, GL_FLOAT, 0, points);
glDrawArrays(GL_POINTS, 0, numberOfPoints);
} else {
// Mac on 64-bit
for( unsigned int i = 0; i < numberOfPoints; i++)
{
newPoints[i].x = points[i].x;
newPoints[i].y = points[i].y;
}
glVertexPointer(2, GL_FLOAT, 0, newPoints);
glDrawArrays(GL_POINTS, 0, numberOfPoints);
}
delete[] newPoints;
// restore default state
glEnableClientState(GL_COLOR_ARRAY);
@ -94,7 +131,7 @@ void ccDrawLine(CGPoint origin, CGPoint destination)
}
void ccDrawPoly(CGPoint *poli, int points, bool closePolygon)
void ccDrawPoly(const CGPoint *poli, int points, bool closePolygon)
{
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,

View File

@ -225,32 +225,26 @@ void CCScheduler::scheduleSelector(SEL_SCHEDULE pfnSelector, SelectorProtocol *p
if (pElement->timers == NULL)
{
pElement->timers = ccArrayNew(10);
}else
if (pElement->timers->num == pElement->timers->max)
{
ccArrayDoubleCapacity(pElement->timers);
}
bool found = false;
for (unsigned int i = 0; i < pElement->timers->num; ++i)
else
{
CCTimer *timer = (CCTimer*)pElement->timers->arr[i];
if (pfnSelector == timer->m_pfnSelector)
for (unsigned int i = 0; i < pElement->timers->num; ++i)
{
CCLOG("CCSheduler#scheduleSelector. Selector already scheduled.");
timer->m_fInterval = fInterval;
found = true;
CCTimer *timer = (CCTimer*)pElement->timers->arr[i];
if (pfnSelector == timer->m_pfnSelector)
{
CCLOG("CCSheduler#scheduleSelector. Selector already scheduled.");
timer->m_fInterval = fInterval;
return;
}
}
ccArrayEnsureExtraCapacity(pElement->timers, 1);
}
if (! found)
{
CCTimer *pTimer = new CCTimer();
pTimer->initWithTarget(pTarget, pfnSelector, fInterval);
ccArrayAppendObject(pElement->timers, pTimer);
pTimer->release();
}
CCTimer *pTimer = new CCTimer();
pTimer->initWithTarget(pTarget, pfnSelector, fInterval);
ccArrayAppendObject(pElement->timers, pTimer);
pTimer->release();
}
void CCScheduler::unscheduleSelector(SEL_SCHEDULE pfnSelector, SelectorProtocol *pTarget)
@ -620,5 +614,6 @@ void CCScheduler::tick(ccTime dt)
void CCScheduler::purgeSharedScheduler(void)
{
pSharedScheduler->release();
pSharedScheduler = NULL;
}
}//namespace cocos2d

View File

@ -85,18 +85,18 @@ float CCCamera::getZEye(void)
void CCCamera::setEyeXYZ(float fEyeX, float fEyeY, float fEyeZ)
{
m_fEyeX = fEyeX;
m_fEyeY = fEyeY;
m_fEyeZ = fEyeZ;
m_fEyeX = fEyeX * CC_CONTENT_SCALE_FACTOR();
m_fEyeY = fEyeY * CC_CONTENT_SCALE_FACTOR();
m_fEyeZ = fEyeZ * CC_CONTENT_SCALE_FACTOR();
m_bDirty = true;
}
void CCCamera::setCenterXYZ(float fCenterX, float fCenterY, float fCenterZ)
{
m_fCenterX = fCenterX;
m_fCenterY = fCenterY;
m_fCenterZ = fCenterZ;
m_fCenterX = fCenterX * CC_CONTENT_SCALE_FACTOR();
m_fCenterY = fCenterY * CC_CONTENT_SCALE_FACTOR();
m_fCenterZ = fCenterZ * CC_CONTENT_SCALE_FACTOR();
m_bDirty = true;
}
@ -112,16 +112,16 @@ void CCCamera::setUpXYZ(float fUpX, float fUpY, float fUpZ)
void CCCamera::getEyeXYZ(float *pEyeX, float *pEyeY, float *pEyeZ)
{
*pEyeX = m_fEyeX;
*pEyeY = m_fEyeY;
*pEyeZ = m_fEyeZ;
*pEyeX = m_fEyeX / CC_CONTENT_SCALE_FACTOR();
*pEyeY = m_fEyeY / CC_CONTENT_SCALE_FACTOR();
*pEyeZ = m_fEyeZ / CC_CONTENT_SCALE_FACTOR();
}
void CCCamera::getCenterXYZ(float *pCenterX, float *pCenterY, float *pCenterZ)
{
*pCenterX = m_fCenterX;
*pCenterY = m_fCenterY;
*pCenterZ = m_fCenterZ;
*pCenterX = m_fCenterX / CC_CONTENT_SCALE_FACTOR();
*pCenterY = m_fCenterY / CC_CONTENT_SCALE_FACTOR();
*pCenterZ = m_fCenterZ / CC_CONTENT_SCALE_FACTOR();
}
void CCCamera::getUpXYZ(float *pUpX, float *pUpY, float *pUpZ)

View File

@ -27,6 +27,6 @@ namespace cocos2d {
const char* cocos2dVersion()
{
return "cocos2d v0.99.4";
return "cocos2d v0.99.5";
}
}//namespace cocos2d

View File

@ -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

View File

@ -29,60 +29,82 @@ THE SOFTWARE.
#include "ccMacros.h"
#include <string>
namespace cocos2d {
/**
A CCCamera is used in every CCNode.
Useful to look at the object from different views.
The OpenGL gluLookAt() function is used to locate the
camera.
class CCX_DLL CCCamera : public NSObject
{
protected:
float m_fEyeX;
float m_fEyeY;
float m_fEyeZ;
If the object is transformed by any of the scale, rotation or
position attributes, then they will override the camera.
float m_fCenterX;
float m_fCenterY;
float m_fCenterZ;
IMPORTANT: Either your use the camera or the rotation/scale/position properties. You can't use both.
World coordinates won't work if you use the camera.
float m_fUpX;
float m_fUpY;
float m_fUpZ;
Limitations:
bool m_bDirty;
public:
CCCamera(void);
~CCCamera(void);
- Some nodes, like CCParallaxNode, CCParticle uses world node coordinates, and they won't work properly if you move them (or any of their ancestors)
using the camera.
void init(void);
- It doesn't work on batched nodes like CCSprite objects when they are parented to a CCSpriteBatchNode object.
char * description(void);
- It is recommended to use it ONLY if you are going to create 3D effects. For 2D effecs, use the action CCFollow or position/scale/rotate.
/** sets the dirty value */
inline void setDirty(bool bValue) { m_bDirty = bValue; }
/** get the dirty value */
inline bool getDirty(void) { return m_bDirty; }
*/
class CCX_DLL CCCamera : public NSObject
{
protected:
float m_fEyeX;
float m_fEyeY;
float m_fEyeZ;
/** sets the camera in the default position */
void restore(void);
/** Sets the camera using gluLookAt using its eye, center and up_vector */
void locate(void);
/** sets the eye values */
void setEyeXYZ(float fEyeX, float fEyeY, float fEyeZ);
/** sets the center values */
void setCenterXYZ(float fCenterX, float fCenterY, float fCenterZ);
/** sets the up values */
void setUpXYZ(float fUpX, float fUpY, float fUpZ);
float m_fCenterX;
float m_fCenterY;
float m_fCenterZ;
/** get the eye vector values */
void getEyeXYZ(float *pEyeX, float *pEyeY, float *pEyeZ);
/** get the center vector values */
void getCenterXYZ(float *pCenterX, float *pCenterY, float *pCenterZ);
/** get the up vector values */
void getUpXYZ(float *pUpX, float *pUpY, float *pUpZ);
public:
/** returns the Z eye */
static float getZEye();
float m_fUpX;
float m_fUpY;
float m_fUpZ;
bool m_bDirty;
public:
CCCamera(void);
~CCCamera(void);
void init(void);
char * description(void);
/** sets the dirty value */
inline void setDirty(bool bValue) { m_bDirty = bValue; }
/** get the dirty value */
inline bool getDirty(void) { return m_bDirty; }
/** sets the camera in the default position */
void restore(void);
/** Sets the camera using gluLookAt using its eye, center and up_vector */
void locate(void);
/** sets the eye values in points */
void setEyeXYZ(float fEyeX, float fEyeY, float fEyeZ);
/** sets the center values in points */
void setCenterXYZ(float fCenterX, float fCenterY, float fCenterZ);
/** sets the up values */
void setUpXYZ(float fUpX, float fUpY, float fUpZ);
/** get the eye vector values in points */
void getEyeXYZ(float *pEyeX, float *pEyeY, float *pEyeZ);
/** get the center vector values int points */
void getCenterXYZ(float *pCenterX, float *pCenterY, float *pCenterZ);
/** get the up vector values */
void getUpXYZ(float *pUpX, float *pUpY, float *pUpZ);
public:
/** returns the Z eye */
static float getZEye();
private:
DISALLOW_COPY_AND_ASSIGN(CCCamera);
};
private:
DISALLOW_COPY_AND_ASSIGN(CCCamera);
};
}//namespace cocos2d
#endif // __CCCAMERA_H__

View File

@ -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();

View File

@ -29,10 +29,12 @@ THE SOFTWARE.
/**
@file
Drawing OpenGL ES primitives.
- drawPoint
- drawLine
- drawPoly
- drawCircle
- ccDrawPoint
- ccDrawLine
- ccDrawPoly
- ccDrawCircle
- ccDrawQuadBezier
- ccDrawCubicBezier
You can change the color, width and other property by calling the
glColor4ub(), glLineWitdh(), glPointSize().
@ -43,20 +45,21 @@ THE SOFTWARE.
#include "CGGeometry.h" // for CGPoint
namespace cocos2d {
/** draws a point given x and y coordinate */
/** draws a point given x and y coordinate measured in points */
void CCX_DLL ccDrawPoint( CGPoint point );
/** draws an array of points.
@since v0.7.2
*/
void CCX_DLL ccDrawPoints( CGPoint *points, unsigned int numberOfPoints );
void CCX_DLL ccDrawPoints( const CGPoint *points, unsigned int numberOfPoints );
/** draws a line given the origin and destination point */
/** draws a line given the origin and destination point measured in points */
void CCX_DLL ccDrawLine( CGPoint origin, CGPoint destination );
/** draws a poligon given a pointer to CGPoint coordiantes and the number of vertices. The polygon can be closed or open
*/
void CCX_DLL ccDrawPoly( CGPoint *vertices, int numOfVertices, bool closePolygon );
/** draws a poligon given a pointer to CGPoint coordiantes and the number of vertices measured in points.
The polygon can be closed or open
*/
void CCX_DLL ccDrawPoly( const CGPoint *vertices, int numOfVertices, bool closePolygon );
/** draws a circle given the center, radius and number of segments. */
void CCX_DLL ccDrawCircle( CGPoint center, float radius, float angle, int segments, bool drawLineToCenter);

View File

@ -61,7 +61,8 @@ namespace cocos2d{
// super methods
virtual void updateAtlasValues();
virtual void setString(const char *label);
virtual void draw();
virtual const char* getString(void);
virtual void draw();
virtual CCLabelProtocol* convertToLabelProtocol() { return (CCLabelProtocol*)this; }
protected:

View File

@ -169,6 +169,7 @@ namespace cocos2d{
void createFontChars();
// super method
virtual void setString(const char *label);
virtual const char* getString(void);
virtual void setCString(const char *label);
virtual void setAnchorPoint(CGPoint var);
virtual CCRGBAProtocol* convertToRGBAProtocol() { return (CCRGBAProtocol*)this; }

View File

@ -55,6 +55,7 @@ namespace cocos2d{
* @warning Changing the string is as expensive as creating a new CCLabelTTF. To obtain better performance use CCLabelAtlas
*/
virtual void setString(const char *label);
virtual const char* getString(void);
virtual CCLabelProtocol* convertToLabelProtocol() { return (CCLabelProtocol*)this; }
protected:
@ -62,6 +63,7 @@ namespace cocos2d{
UITextAlignment m_eAlignment;
std::string m_sFontName;
float m_fFontSize;
std::string m_sString;
};
} //namespace cocos2d

View File

@ -110,7 +110,20 @@ class CCX_DLL CCLabelProtocol
public:
// sets a new label using an string
virtual void setString(const char *label) = 0;
/** returns the string that is rendered */
virtual const char* getString(void) = 0;
};
/** OpenGL projection protocol */
class CCX_DLL CCProjectionProtocol : public NSObject
{
/** Called by CCDirector when the porjection is updated, and "custom" projection is used
@since v0.99.5
*/
virtual void updateProjection(void) = 0;
};
}//namespace cocos2d
#endif // __CCPROTOCOLS_H__

View File

@ -88,30 +88,45 @@ To enabled set it to 1. Disabled by default.
*/
#define CC_DIRECTOR_DISPATCH_FAST_EVENTS 0
/** @def CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
If enabled, cocos2d-mac will run on the Display Link thread. If disabled cocos2d-mac will run in its own thread.
If enabled, the images will be drawn at the "correct" time, but the events might not be very responsive.
If disabled, some frames might be skipped, but the events will be dispatched as they arrived.
To enable set it to a 1, to disable it set to 0. Enabled by default.
Only valid for cocos2d-mac. Not supported on cocos2d-ios.
*/
#define CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD 1
/** @def CC_COCOSNODE_RENDER_SUBPIXEL
If enabled, the CCNode objects (CCSprite, CCLabel,etc) will be able to render in subpixels.
If disabled, integer pixels will be used.
To enable set it to a value different than 0. Enabled by default.
To enable set it to 1. Enabled by default.
*/
#define CC_COCOSNODE_RENDER_SUBPIXEL 1
/** @def CC_SPRITESHEET_RENDER_SUBPIXEL
If enabled, the CCSprite objects rendered with CCSpriteSheet will be able to render in subpixels.
/** @def CC_SPRITEBATCHNODE_RENDER_SUBPIXEL
If enabled, the CCSprite objects rendered with CCSpriteBatchNode will be able to render in subpixels.
If disabled, integer pixels will be used.
To enable set it to a value different than 0. Enabled by default.
To enable set it to 1. Enabled by default.
*/
#define CC_SPRITESHEET_RENDER_SUBPIXEL 1
#define CC_SPRITEBATCHNODE_RENDER_SUBPIXEL 1
/** @def CC_TEXTURE_ATLAS_USES_VBO
If enabled, the CCTextureAtlas object will use VBO instead of vertex list (VBO is recommended by Apple)
To enable set it to a value different than 0. Enabled by default.
/** @def CC_USES_VBO
If enabled, batch nodes (texture atlas and particle system) will use VBO instead of vertex list (VBO is recommended by Apple)
@since v0.99.0
*/
#define CC_TEXTURE_ATLAS_USES_VBO 1
To enable set it to 1.
Enabled by default on iPhone with ARMv7 processors, iPhone Simulator and Mac
Disabled by default on iPhone with ARMv6 processors.
@since v0.99.5
*/
#define CC_USES_VBO 1
/** @def CC_NODE_TRANSFORM_USING_AFFINE_MATRIX
If enabled, CCNode will transform the nodes using a cached Affine matrix.
@ -127,6 +142,16 @@ To enabled set it to 1. Disabled by default.
*/
#define CC_NODE_TRANSFORM_USING_AFFINE_MATRIX 1
/** @def CC_OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA
If most of your imamges have pre-multiplied alpha, set it to 1 (if you are going to use .PNG/.JPG file images).
Only set to 0 if ALL your images by-pass Apple UIImage loading system (eg: if you use libpng or PVR images)
To enable set it to a value different than 0. Enabled by default.
@since v0.99.5
*/
#define CC_OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA 1
/** @def CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
Use GL_TRIANGLE_STRIP instead of GL_TRIANGLES when rendering the texture atlas.
It seems it is the recommend way, but it is much slower, so, enable it at your own risk
@ -148,6 +173,41 @@ To enabled set it to 1. Disabled by default.
*/
#define CC_TEXTURE_NPOT_SUPPORT 0
/** @def CC_RETINA_DISPLAY_SUPPORT
If enabled, cocos2d supports retina display.
For performance reasons, it's recommended disable it in games without retina display support, like iPad only games.
To enable set it to 1. Use 0 to disable it. Enabled by default.
@since v0.99.5
*/
#define CC_RETINA_DISPLAY_SUPPORT 1
/** @def CC_RETINA_DISPLAY_FILENAME_SUFFIX
It's the suffix that will be appended to the files in order to load "retina display" images.
On an iPhone4 with Retina Display support enabled, the file @"sprite-hd.png" will be loaded instead of @"sprite.png".
If the file doesn't exist it will use the non-retina display image.
Platforms: Only used on Retina Display devices like iPhone 4.
@since v0.99.5
*/
#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.
If it is disabled, or if it is used on another architecture it will use A8 (8-bit textures).
On Neon devices, RGBA8888 textures are 6% faster than A8 textures, but then will consule 4x memory.
This feature is disabled by default.
Platforms: Only used on ARM Neon architectures like iPhone 3GS or newer and iPad.
@since v0.99.5
*/
#define CC_USE_RGBA32_LABELS_ON_NEON_ARCH 0
/** @def CC_SPRITE_DEBUG_DRAW
If enabled, all subclasses of CCSprite will draw a bounding box
Useful for debugging purposes only. It is recommened to leave it disabled.
@ -156,13 +216,13 @@ To enabled set it to 1. Disabled by default.
*/
#define CC_SPRITE_DEBUG_DRAW 0
/** @def CC_SPRITESHEET_DEBUG_DRAW
If enabled, all subclasses of CCSprite that are rendered using an CCSpriteSheet draw a bounding box.
Useful for debugging purposes only. It is recommened to leave it disabled.
To enable set it to a value different than 0. Disabled by default.
*/
#define CC_SPRITESHEET_DEBUG_DRAW 0
/** @def CC_SPRITEBATCHNODE_DEBUG_DRAW
If enabled, all subclasses of CCSprite that are rendered using an CCSpriteSheet draw a bounding box.
Useful for debugging purposes only. It is recommened to leave it disabled.
To enable set it to a value different than 0. Disabled by default.
*/
#define CC_SPRITEBATCHNODE_DEBUG_DRAW 0
/** @def CC_BITMAPFONTATLAS_DEBUG_DRAW
If enabled, all subclasses of BitmapFontAtlas will draw a bounding box
@ -198,4 +258,10 @@ To enabled set it to 1. Disabled by default.
*/
#define CC_COMPATIBILITY_WITH_0_8 0
#if CC_RETINA_DISPLAY_SUPPORT
#define CC_IS_RETINA_DISPLAY_SUPPORTED 1
#else
#define CC_IS_RETINA_DISPLAY_SUPPORTED 0
#endif
#endif // __CCCONFIG_H__

View File

@ -32,6 +32,8 @@ THE SOFTWARE.
#include <math.h>
#include <cstdio>
#include "ccConfig.h"
/**
@file
cocos2d helper macros
@ -205,45 +207,6 @@ do { \
// [__director end]; \
// } while(0)
#if CC_IS_RETINA_DISPLAY_SUPPORTED
/****************************/
/** RETINA DISPLAY ENABLED **/
/****************************/
/** @def CC_CONTENT_SCALE_FACTOR
On Mac it returns 1;
On iPhone it returns 2 if RetinaDisplay is On. Otherwise it returns 1
*/
#import "Platforms/iOS/CCDirectorIOS.h"
#define CC_CONTENT_SCALE_FACTOR() __ccContentScaleFactor
/** @def CC_RECT_PIXELS_TO_POINTS
Converts a rect in pixels to points
*/
#define CC_RECT_PIXELS_TO_POINTS(__pixels__) \
CGRectMake( (__pixels__).origin.x / CC_CONTENT_SCALE_FACTOR(), (__pixels__).origin.y / CC_CONTENT_SCALE_FACTOR(), \
(__pixels__).size.width / CC_CONTENT_SCALE_FACTOR(), (__pixels__).size.height / CC_CONTENT_SCALE_FACTOR() )
/** @def CC_RECT_POINTS_TO_PIXELS
Converts a rect in points to pixels
*/
#define CC_RECT_POINTS_TO_PIXELS(__points__) \
CGRectMake( (__points__).origin.x * CC_CONTENT_SCALE_FACTOR(), (__points__).origin.y * CC_CONTENT_SCALE_FACTOR(), \
(__points__).size.width * CC_CONTENT_SCALE_FACTOR(), (__points__).size.height * CC_CONTENT_SCALE_FACTOR() )
#else // retina disabled
/*****************************/
/** RETINA DISPLAY DISABLED **/
/*****************************/
#define CC_CONTENT_SCALE_FACTOR() 1
#define CC_RECT_PIXELS_TO_POINTS(__pixels__) __pixels__
#define CC_RECT_POINTS_TO_PIXELS(__points__) __points__
#endif // CC_IS_RETINA_DISPLAY_SUPPORTED
#ifndef FLT_EPSILON
#define FLT_EPSILON 1.192092896e-07F
@ -267,8 +230,8 @@ Converts a rect in points to pixels
On Mac it returns 1;
On iPhone it returns 2 if RetinaDisplay is On. Otherwise it returns 1
*/
#include "Platforms/iOS/CCDirectorIOS.h"
#define CC_CONTENT_SCALE_FACTOR() __ccContentScaleFactor
#include "CCDirector.h"
#define CC_CONTENT_SCALE_FACTOR() CCDirector::sharedDirector()->getContentScaleFactor()
/** @def CC_RECT_PIXELS_TO_POINTS

View File

@ -27,7 +27,7 @@ THE SOFTWARE.
#include "CGGeometry.h"
#include <GLES/gl.h>
#include "CCGL.h"
namespace cocos2d {
@ -73,10 +73,10 @@ static const ccColor3B ccGRAY={166,166,166};
*/
typedef struct _ccColor4B
{
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
GLubyte r;
GLubyte g;
GLubyte b;
GLubyte a;
} ccColor4B;
//! helper macro that creates an ccColor4B type
static inline ccColor4B
@ -91,10 +91,10 @@ ccc4(const GLubyte r, const GLubyte g, const GLubyte b, const GLubyte o)
@since v0.8
*/
typedef struct _ccColor4F {
float r;
float g;
float b;
float a;
GLfloat r;
GLfloat g;
GLfloat b;
GLfloat a;
} ccColor4F;
/** Returns a ccColor4F from a ccColor3B. Alpha will be 1.
@ -126,16 +126,21 @@ static inline bool ccc4FEqual(ccColor4F a, ccColor4F b)
/** A vertex composed of 2 floats: x, y
@since v0.8
*/
#define ccVertex2F CGPoint
typedef struct _ccVertex2F
{
GLfloat x;
GLfloat y;
} ccVertex2F;
/** A vertex composed of 2 floats: x, y
@since v0.8
*/
typedef struct _ccVertex3F
{
float x;
float y;
float z;
GLfloat x;
GLfloat y;
GLfloat z;
} ccVertex3F;
static inline ccVertex3F vertex3(const float x, const float y, const float z)
@ -148,8 +153,8 @@ static inline ccVertex3F vertex3(const float x, const float y, const float z)
@since v0.8
*/
typedef struct _ccTex2F {
float u;
float v;
GLfloat u;
GLfloat v;
} ccTex2F;
static inline ccTex2F tex2(const float u, const float v)
@ -164,7 +169,7 @@ typedef struct _ccPointSprite
{
ccVertex2F pos; // 8 bytes
ccColor4F colors; // 16 bytes
float size; // 4 bytes
GLfloat size; // 4 bytes
} ccPointSprite;
//! A 2D Quad. 4 * 2 floats

View File

@ -133,6 +133,11 @@ namespace cocos2d{
this->setContentSizeInPixels(s);
}
const char* CCLabelAtlas::getString(void)
{
return m_sString.c_str();
}
//CCLabelAtlas - draw
// XXX: overriding draw from AtlasNode

View File

@ -565,6 +565,11 @@ namespace cocos2d{
this->createFontChars();
}
const char* CCLabelBMFont::getString(void)
{
return m_sString.c_str();
}
void CCLabelBMFont::setCString(const char *label)
{
setString(label);

View File

@ -83,6 +83,8 @@ namespace cocos2d{
{
return;
}
m_sString = string(label);
CCTexture2D *texture;
if( CGSize::CGSizeEqualToSize( m_tDimensions, CGSizeZero ) )
@ -103,6 +105,11 @@ namespace cocos2d{
this->setTextureRect(rect);
}
const char* CCLabelTTF::getString(void)
{
return m_sString.c_str();
}
char * CCLabelTTF::description()
{
char *ret = new char[100] ;

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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"
>

View File

@ -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);

View File

@ -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
*