fixed #2301: Merge branch 'emscriptenate' of https://github.com/j4m3z0r/cocos2d-x into j4m3z0r-emscriptenate

Conflicts:
	cocos2dx/proj.emscripten/cocos2dx.mk
This commit is contained in:
James Chen 2013-06-19 13:03:51 +08:00
commit 1eadcd8b38
13 changed files with 616 additions and 391 deletions

View File

@ -27,6 +27,14 @@ THE SOFTWARE.
#include "cocoa/CCObject.h"
// premultiply alpha, or the effect will wrong when want to use other pixel format in CCTexture2D,
// such as RGB888, RGB5A1
#define CC_RGB_PREMULTIPLY_ALPHA(vr, vg, vb, va) \
(unsigned)(((unsigned)((unsigned char)(vr) * ((unsigned char)(va) + 1)) >> 8) | \
((unsigned)((unsigned char)(vg) * ((unsigned char)(va) + 1) >> 8) << 8) | \
((unsigned)((unsigned char)(vb) * ((unsigned char)(va) + 1) >> 8) << 16) | \
((unsigned)(unsigned char)(va) << 24))
NS_CC_BEGIN
/**
@ -96,6 +104,9 @@ public:
int nHeight = 0,
int nBitsPerComponent = 8);
// @warning kFmtRawData only support RGBA8888
bool initWithRawData(void *pData, int nDatalen, int nWidth, int nHeight, int nBitsPerComponent, bool bPreMulti);
/**
@brief Create image with specified string.
@param pText the text the image will show (cannot be nil).
@ -165,8 +176,6 @@ protected:
bool _initWithPngData(void *pData, int nDatalen);
bool _initWithTiffData(void *pData, int nDataLen);
bool _initWithWebpData(void *pData, int nDataLen);
// @warning kFmtRawData only support RGBA8888
bool _initWithRawData(void *pData, int nDatalen, int nWidth, int nHeight, int nBitsPerComponent, bool bPreMulti);
bool _saveImageToPNG(const char *pszFilePath, bool bIsToRGB = true);
bool _saveImageToJPG(const char *pszFilePath);

View File

@ -47,14 +47,6 @@ THE SOFTWARE.
NS_CC_BEGIN
// premultiply alpha, or the effect will wrong when want to use other pixel format in CCTexture2D,
// such as RGB888, RGB5A1
#define CC_RGB_PREMULTIPLY_ALPHA(vr, vg, vb, va) \
(unsigned)(((unsigned)((unsigned char)(vr) * ((unsigned char)(va) + 1)) >> 8) | \
((unsigned)((unsigned char)(vg) * ((unsigned char)(va) + 1) >> 8) << 8) | \
((unsigned)((unsigned char)(vb) * ((unsigned char)(va) + 1) >> 8) << 16) | \
((unsigned)(unsigned char)(va) << 24))
// on ios, we should use platform/ios/CCImage_ios.mm instead
typedef struct
@ -111,7 +103,7 @@ bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = e
SDL_Surface *iSurf = IMG_Load(strPath);
int size = 4 * (iSurf->w * iSurf->h);
bRet = _initWithRawData((void*)iSurf->pixels, size, iSurf->w, iSurf->h, 8, true);
bRet = initWithRawData((void*)iSurf->pixels, size, iSurf->w, iSurf->h, 8, true);
unsigned int *tmp = (unsigned int *)_data;
int nrPixels = iSurf->w * iSurf->h;
@ -188,7 +180,7 @@ bool CCImage::initWithImageData(void * pData,
}
else if (kFmtRawData == eFmt)
{
bRet = _initWithRawData(pData, nDataLen, nWidth, nHeight, nBitsPerComponent, false);
bRet = initWithRawData(pData, nDataLen, nWidth, nHeight, nBitsPerComponent, false);
break;
}
else
@ -689,7 +681,7 @@ bool CCImage::_initWithTiffData(void* pData, int nDataLen)
return bRet;
}
bool CCImage::_initWithRawData(void * pData, int nDatalen, int nWidth, int nHeight, int nBitsPerComponent, bool bPreMulti)
bool CCImage::initWithRawData(void * pData, int nDatalen, int nWidth, int nHeight, int nBitsPerComponent, bool bPreMulti)
{
bool bRet = false;
do

View File

@ -76,11 +76,12 @@ CC_DEPRECATED_ATTRIBUTE static __TYPE__* node() \
/** @def CC_ENABLE_CACHE_TEXTURE_DATA
Enable it if you want to cache the texture data.
Basically, it's only enabled for Emscripten.
Not enabling for Emscripten any more -- doesn't seem necessary and don't want
to be different from other platforms unless there's a good reason.
It's new in cocos2d-x since v0.99.5
*/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_EMSCRIPTEN)
#if 0
#define CC_ENABLE_CACHE_TEXTURE_DATA 1
#else
#define CC_ENABLE_CACHE_TEXTURE_DATA 0

View File

@ -34,6 +34,7 @@ THE SOFTWARE.
#include "CCAccelerometer.h"
#include "CCApplication.h"
#include <emscripten/emscripten.h>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <SDL/SDL_mixer.h>

View File

@ -0,0 +1,191 @@
/****************************************************************************
Copyright (c) 2013 Zynga Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "CCTextureCacheEmscripten.h"
#include "platform/CCImage.h"
#include "platform/CCFileUtils.h"
#include <emscripten/emscripten.h>
#include <sstream>
using namespace cocos2d;
using namespace std;
#define MULTILINE(...) #__VA_ARGS__
// Following methods are implemented in CCTextureCacheEmscripten.js:
extern "C" {
void cocos2dx_newAsyncImageLoader(int textureCache, int callback__ignored);
void cocos2dx_asyncImageLoader_LoadImage(const char *path, AsyncStruct *asyncData);
void cocos2dx_shutdownAsyncImageLoader();
};
extern "C" {
// This C interface is exposed so that the JavaScript in
// CCTextureCacheEmscripten.js is able to call into these functions.
void CCTextureCacheEmscripten_addImageAsyncCallBack(CCTextureCacheEmscripten *tc, AsyncStruct *data, unsigned char *imgData, int width, int height);
void CCTextureCacheEmscripten_preMultiplyImageRegion( unsigned char *in, int win, int hin, unsigned char *out, int wout, int hout, int xout, int yout);
};
void CCTextureCacheEmscripten_addImageAsyncCallBack(CCTextureCacheEmscripten *tc, AsyncStruct *data, unsigned char *imgData, int width, int height)
{
tc->addImageAsyncCallBack_emscripten(data, imgData, width, height);
}
/**
* Construct a new CCTextureCacheEmscripten object. Note that the code in
* CCTextureCacheEmscripten.js will be injected into the JavaScript runtime as
* a side-affect.
*/
CCTextureCacheEmscripten::CCTextureCacheEmscripten()
{
// Add dummy references to these functions so that the compiler will emit
// code for them prior to this point (which is before when we will call
// them.
int deps[] = {
(int)&CCTextureCacheEmscripten_addImageAsyncCallBack,
(int)&CCTextureCacheEmscripten_preMultiplyImageRegion
};
cocos2dx_newAsyncImageLoader((int)this, (int)&deps);
}
/**
* Destroy this object. Note that this will shutdown the image processing queue
* (and hence stall anything waiting for those images to finish loading), and
* unload the classes and objects instantiated in JavaScript to make this class
* work.
*/
CCTextureCacheEmscripten::~CCTextureCacheEmscripten()
{
cocos2dx_shutdownAsyncImageLoader();
}
/**
* "Blit" the input image to a particular location on the target image. Output
* image will be alpha pre-multiplied in the process.
*
* @in: Pointer to input image raw data bytes
* @win: Width of input image in pixels
* @hin: Height of input image in pixels
* @out: Pointer to memory where output image raw pixels should be written
* @wout: Width of output image in pixels
* @hout: Height of output image in pixels
* @xout: x-offset into target image where blitted image should be placed
* @yout: y-offset into target image where blitted image should be placed
*/
void CCTextureCacheEmscripten_preMultiplyImageRegion(
unsigned char *in, int win, int hin, // Input image, its width and height
unsigned char *out, int wout, int hout, // Output image, its width and height
int xout, int yout) // x and y offsets into the output image
{
int iter = 0;
for(int j = 0; j < hin; j++)
{
for(int i = 0; i < win; i++)
{
int inOffset = 4 * (j * win + i);
int outOffset = 4 * ((j + yout) * wout + (i + xout));
unsigned char *pin = in + inOffset;
unsigned int *pout = (unsigned int *) (out + outOffset);
*pout = CC_RGB_PREMULTIPLY_ALPHA( pin[0], pin[1], pin[2], pin[3] );
}
}
}
/**
* "Private" callback method to load a texture based on the image data
* generated in CCTextureCacheEmscripten.js. Exposed here as public so that it
* can be called from the C wrapper method
* @CCTextureCacheEmscripten_addImageAsyncCallBack, above.
*/
void CCTextureCacheEmscripten::addImageAsyncCallBack_emscripten(AsyncStruct *data, unsigned char *imgData, int width, int height)
{
const char *filename = data->filename.c_str();
CCImage *pImage = new CCImage();
pImage->initWithRawData((unsigned char*) imgData, 4 * width * height, width, height, 8, true);
free(imgData);
CCTexture2D *texture = new CCTexture2D();
texture->initWithImage(pImage);
#if CC_ENABLE_CACHE_TEXTURE_DATA
// cache the texture file name
VolatileTexture::addImageTexture(texture, filename, CCImage::kFmtRawData);
#endif
// cache the texture
m_pTextures->setObject(texture, filename);
texture->autorelease();
CCObject *target = data->target;
SEL_CallFuncO selector = data->selector;
if (target && selector)
{
(target->*selector)(texture);
target->release();
}
pImage->release();
delete data;
}
void CCTextureCacheEmscripten::addImageAsync(const char *path, CCObject *target, SEL_CallFuncO selector)
{
CCAssert(path != NULL, "TextureCache: fileimage MUST not be NULL");
CCTexture2D *texture = NULL;
// optimization
std::string pathKey = CCFileUtils::sharedFileUtils()->fullPathForFilename(path);
texture = (CCTexture2D*)m_pTextures->objectForKey(pathKey.c_str());
std::string fullpath = pathKey;
if (texture != NULL)
{
if (target && selector)
{
(target->*selector)(texture);
}
return;
}
if (target)
{
target->retain();
}
// generate async struct
AsyncStruct *data = new AsyncStruct(fullpath, target, selector);
// Call into JavaScript code in CCTextureCacheEmscripten.js to do the rest.
cocos2dx_asyncImageLoader_LoadImage(data->filename.c_str(), data);
return;
}

View File

@ -0,0 +1,48 @@
/****************************************************************************
Copyright (c) 2013 Zynga Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCTEXTURE_CACHE_EMSCRIPTEN_H__
#define __CCTEXTURE_CACHE_EMSCRIPTEN_H__
#include "textures/CCTextureCache.h"
NS_CC_BEGIN
class CC_DLL CCTextureCacheEmscripten : public CCTextureCache
{
public:
CCTextureCacheEmscripten();
virtual ~CCTextureCacheEmscripten();
void addImageAsync(const char *path, CCObject *target, SEL_CallFuncO selector);
/* Public method since we need to call it from C code to workaround linkage from JS.
*/
void addImageAsyncCallBack_emscripten(AsyncStruct *data, unsigned char *imgData, int width, int height);
};
NS_CC_END
#endif

View File

@ -0,0 +1,302 @@
/****************************************************************************
Copyright (c) 2013 Zynga Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
// Non-namespaced facade over underlying objects. See above methods for
// documentation. These methods serve two purposes:
//
// 1. convert types to/from JS equivalents.
// 2. expose a "C-like" interface, such that the symbols are easy to find
// for calling code (Emscripten provides no easy way to access nested
// dictionaries).
//
// Note that the leading '_' is because Emscripten prefixes all function
// calls like this. Since this code is being injected at runtime,
// Emscripten's compiler doesn't have a chance to add it for us.
var LibraryCocosHelper = {
$cocos2dx__deps: [ '_CCTextureCacheEmscripten_preMultiplyImageRegion' ],
$cocos2dx: {
objects: {},
classes: {
// AsyncOperationQueue -- simple worker queue. Note that all functions
// passed in should effectively be "static", and have all requisite
// information contained in their args object.
AsyncOperationQueue: function()
{
this.ops = [];
this.timeoutId = null;
// Target using 2/3 of available CPU for texture loading.
this.sliceBudget = 8;
this.sliceInterval = 4;
/**
* If there is a valid scheduled queue consumer, cancel it. Won't cancel
* currently executing operations (as this is not multi-threaded), but will
* prevent future execution from happening until it is re-scheduled.
*/
this.unschedule = function(interval)
{
if(typeof this.timeoutId == "number")
{
clearTimeout(this.timeoutId);
this.timeoutId = null;
}
};
/**
* Schedule the queue-processor to run @interval ms in the future.
*/
this.schedule = function(interval)
{
this.unschedule();
var that = this;
var o = function() {
that.run();
};
this.timeoutId = setTimeout(o, interval);
};
/**
* Enqueue a funtcion @fn with arguments @args to run asynchronously at
* some point in the future, then return control to the caller. Operations
* are guaranteed to be run in the order in which they are enqueued, but no
* guarantee is given about when or in what context they will be executed.
*/
this.enqueue = function(fn, args)
{
var op = {
fn: fn,
args: args
};
this.ops.push(op);
this.schedule(this.sliceInterval);
};
/**
* Start running the consumer "thread". Will consume operations from the
* queue until such time as either the queue is empty, or it has exceeded
* its time budget. If the latter case (budget exceeded), it will
* reschedule itself to run again later and finish draining the queue.
*
* Rescheduling logic still in flux, but the objective is to try to
* schedule it to run at some point after the next frame has been
* requested, whilst still maintaining maximum bandwidth.
*/
this.run = function()
{
if(this.ops.length === 0)
{
return;
}
var start = +new Date();
var end = +new Date();
while(this.ops.length && ((end - start) < this.sliceBudget))
{
var op = this.ops.shift();
op.fn(op.args);
end = +new Date();
}
if(this.ops.length)
{
this.schedule(this.sliceInterval);
}
};
/**
* Unschedule any remaining operations in the queue.
*/
this.shutdown = function()
{
this.unschedule();
this.ops = [];
};
},
/**
* Construct a new AsyncImageLoader object. @cxxTextureCache should be a
* pointer to a valid CCTextureCacheEmscripten object in C++.
*/
AsyncImageLoader: function(cxxTextureCache)
{
this.cxxTextureCache = cxxTextureCache;
this.operationQueue = new cocos2dx.classes.AsyncOperationQueue();
// Since there will only ever be one image being processed at a time,
// we pre-initialize a canvas object and use it for all operations so
// as to save doing this for every image, incurring (probably) both
// compute work and memory fragmentation.
this.canvas = document.createElement('canvas');
this.ctx = this.canvas.getContext('2d');
this.regionSize = 128;
/**
* "Private" and "static" method to copy an input image to a given
* rectangle in the output image. Used by @loadImage.
*/
this._blitAndPremultipyRegion = function(args)
{
// Calculate width and height for this region such that we
// do not run off the edge of the image.
var rw = Math.min(args.i + this.regionSize, args.w) - args.i;
var rh = Math.min(args.j + this.regionSize, args.h) - args.j;
this.ctx.drawImage(args.img, args.i, args.j, rw, rh, args.i, args.j, rw, rh);
var imgData = this.ctx.getImageData(args.i, args.j, rw, rh);
var inImgData = _malloc(rw * rh * 4);
Module.HEAP8.set(imgData.data, inImgData);
// Call into C++ code in CCTextureCacheEmscripten.cpp to do the actual
// copy and pre-multiply.
_CCTextureCacheEmscripten_preMultiplyImageRegion(inImgData, rw, rh, args.outImgData, args.w, args.h, args.i, args.j);
_free(inImgData);
};
/**
* Enqueue the image at @path (interpreted as a URL) to be asynchronously
* loaded, then call the cocos2dx callback specified in @asyncData. Image
* fetch happens asynchronously using browser asset management code, and
* the work of copying pixel data to a buffer (for use by cocos2dx) is
* spread out over several frames such that disruptions to frame rate are
* minimized.
*/
this.loadImage = function(path, asyncData)
{
var img = new Image();
var that = this;
img.onload = function()
{
var w = img.width;
var h = img.height;
// Setup the canvas in the queue also so that it happens in order
// with the operations that depend on the canvas having been
// configured to this resolution. We can get away with this since
// the queue guarantees that operations are executed in the order
// in which they are enqueued.
var setupCanvas = function(args)
{
that.canvas.width = args.w;
that.canvas.height = args.h;
};
that.operationQueue.enqueue(setupCanvas, { w: w, h: h });
var outImgData = _malloc(w * h * 4);
for(var i = 0; i < w; i += that.regionSize)
{
for(var j = 0; j < h; j += that.regionSize)
{
var args = {
i: i, j: j,
w: w, h: h,
img: img,
outImgData: outImgData
};
that.operationQueue.enqueue(function(a) { that._blitAndPremultipyRegion(a); }, args);
}
}
var fireCallback = function(args) {
_CCTextureCacheEmscripten_addImageAsyncCallBack(that.cxxTextureCache, args.asyncData, args.imgData, args.w, args.h);
};
var opArgs = {
asyncData: asyncData,
imgData: outImgData,
w: w, h: h
};
that.operationQueue.enqueue(fireCallback, opArgs);
};
img.onerror = function()
{
console.log("Error loading '" + path + "'");
};
img.src = path;
};
/**
* Shutdown this image loader object. Used by destructor in cocos2dx.
*/
this.shutdown = function()
{
this.operationQueue.shutdown();
};
}
}
},
/*
* Construct a new AsyncImageLoader object. Held as a singleton, referred
* to in other wrapper methods here.
* @deps__ignored is ignored, but is accepted so that we can communicate to
* the compiler what functions we need to ensure are ready by the time this
* class gets instantiated.
*/
cocos2dx_newAsyncImageLoader: function(cxxTextureCache, deps__ignored)
{
cocos2dx.objects.asyncImageLoader = new cocos2dx.classes.AsyncImageLoader(cxxTextureCache);
},
/**
* Shutdown the current image loader object. Used by the cocos2dx
* destructor method.
*/
cocos2dx_shutdownAsyncImageLoader: function()
{
cocos2dx.objects.asyncImageLoader.shutdown();
cocos2dx.objects.asyncImageLoader = null;
},
/**
* Load a new image asynchronously.
*/
cocos2dx_asyncImageLoader_LoadImage: function(path, asyncData)
{
var opArgs = {
path: Pointer_stringify(path),
data: asyncData
};
var op = function(args)
{
cocos2dx.objects.asyncImageLoader.loadImage(args.path, args.data);
};
cocos2dx.objects.asyncImageLoader.operationQueue.enqueue(op, opArgs);
}
};
autoAddDeps(LibraryCocosHelper, '$cocos2dx');
mergeInto(LibraryManager.library, LibraryCocosHelper);

View File

@ -77,6 +77,7 @@ SOURCES = ../actions/CCAction.cpp \
../platform/emscripten/CCImage.cpp \
../platform/emscripten/CCDevice.cpp \
../platform/emscripten/CCFileUtilsEmscripten.cpp \
../platform/emscripten/CCTextureCacheEmscripten.cpp \
../script_support/CCScriptSupport.cpp \
../sprite_nodes/CCAnimation.cpp \
../sprite_nodes/CCAnimationCache.cpp \

View File

@ -13,13 +13,24 @@ OBJ_DIR ?= obj
EMSCRIPTEN_ROOT := $(realpath $(COCOS_ROOT)/external/emscripten)
PACKAGER := $(EMSCRIPTEN_ROOT)/tools/file_packager.py
CC := EMSCRIPTEN=$(EMSCRIPTEN_ROOT) $(COCOS_ROOT)/external/emscripten/emcc
CXX := EMSCRIPTEN=$(EMSCRIPTEN_ROOT) $(COCOS_ROOT)/external/emscripten/em++
AR := EMSCRIPTEN=$(EMSCRIPTEN_ROOT) $(COCOS_ROOT)/external/emscripten/emar
CCFLAGS += -MMD -Wall -fPIC -Qunused-arguments -Wno-overloaded-virtual -Qunused-variable -s TOTAL_MEMORY=268435456 -s VERBOSE=1 -U__native_client__ -Wno-deprecated-declarations
CXXFLAGS += -MMD -Wall -fPIC -Qunused-arguments -Wno-overloaded-virtual -Qunused-variable -s TOTAL_MEMORY=268435456 -s VERBOSE=1 -U__native_client__ -std=c++11 -Wno-deprecated-declarations
ARFLAGS = cr
CC := EMSCRIPTEN=$(EMSCRIPTEN_ROOT) $(COCOS_ROOT)/external/emscripten/emcc
CXX := EMSCRIPTEN=$(EMSCRIPTEN_ROOT) $(COCOS_ROOT)/external/emscripten/em++
# XXX: Not entirely sure why main, malloc and free need to be explicitly listed
# here, but after adding a --js-library library, these symbols seem to get
# stripped unless enumerated here.
EXPORTED_FLAGS := -s EXPORTED_FUNCTIONS="['_CCTextureCacheEmscripten_addImageAsyncCallBack','_CCTextureCacheEmscripten_preMultiplyImageRegion','_malloc','_free','_main']"
JSLIBS := --js-library $(COCOS_SRC)/platform/emscripten/CCTextureCacheEmscripten.js
CCFLAGS += -MMD -Wall -fPIC -Qunused-arguments -Wno-overloaded-virtual -Qunused-variable -s TOTAL_MEMORY=268435456 -s VERBOSE=1 -U__native_client__ $(EXPORTED_FLAGS) $(JSLIBS)
CXXFLAGS += -MMD -Wall -fPIC -Qunused-arguments -Wno-overloaded-virtual -Qunused-variable -s TOTAL_MEMORY=268435456 -s VERBOSE=1 -U__native_client__ $(EXPORTED_FLAGS) $(JSLIBS)
LIB_DIR = $(COCOS_SRC)/lib/emscripten
BIN_DIR = bin
@ -48,6 +59,9 @@ OBJ_DIR := $(OBJ_DIR)/debug
LIB_DIR := $(LIB_DIR)/debug
BIN_DIR := $(BIN_DIR)/debug
else
# Async image loading code incompatible with asm.js for now. Disable until
# we've had time to investigate. --closure 0 so that symbols don't get mangled,
# rendering them inaccessible from JS code.
CCFLAGS += -O2 --jcache -s GL_UNSAFE_OPTS=0 -s ASM_JS=1
CXXFLAGS += -O2 --jcache -s GL_UNSAFE_OPTS=0 -s ASM_JS=1
DEFINES += -DNDEBUG -DCP_USE_DOUBLES=0

View File

@ -43,17 +43,15 @@ THE SOFTWARE.
#include <list>
#include <pthread.h>
#ifdef EMSCRIPTEN
#include <emscripten/emscripten.h>
#include "platform/emscripten/CCTextureCacheEmscripten.h"
#endif // EMSCRIPTEN
using namespace std;
NS_CC_BEGIN
typedef struct _AsyncStruct
{
std::string filename;
CCObject *target;
SEL_CallFuncO selector;
} AsyncStruct;
typedef struct _ImageInfo
{
AsyncStruct *asyncStruct;
@ -193,7 +191,11 @@ CCTextureCache * CCTextureCache::sharedTextureCache()
{
if (!g_sharedTextureCache)
{
#ifdef EMSCRIPTEN
g_sharedTextureCache = new CCTextureCacheEmscripten();
#else
g_sharedTextureCache = new CCTextureCache();
#endif // EMSCRIPTEN
}
return g_sharedTextureCache;
}
@ -238,10 +240,6 @@ CCDictionary* CCTextureCache::snapshotTextures()
void CCTextureCache::addImageAsync(const char *path, CCObject *target, SEL_CallFuncO selector)
{
#ifdef EMSCRIPTEN
CCLOGWARN("Cannot load image %s asynchronously in Emscripten builds.", path);
return;
#endif // EMSCRIPTEN
CCAssert(path != NULL, "TextureCache: fileimage MUST not be NULL");
@ -293,10 +291,7 @@ void CCTextureCache::addImageAsync(const char *path, CCObject *target, SEL_CallF
}
// generate async struct
AsyncStruct *data = new AsyncStruct();
data->filename = fullpath.c_str();
data->target = target;
data->selector = selector;
AsyncStruct *data = new AsyncStruct(fullpath, target, selector);
// add async struct into queue
pthread_mutex_lock(&s_asyncStructQueueMutex);

View File

@ -40,6 +40,16 @@ THE SOFTWARE.
NS_CC_BEGIN
class AsyncStruct
{
public:
AsyncStruct(const std::string& fn, CCObject *t, SEL_CallFuncO s) : filename(fn), target(t), selector(s) {}
std::string filename;
CCObject *target;
SEL_CallFuncO selector;
};
class CCLock;
class CCImage;
@ -96,7 +106,7 @@ public:
* @since v0.8
*/
void addImageAsync(const char *path, CCObject *target, SEL_CallFuncO selector);
virtual void addImageAsync(const char *path, CCObject *target, SEL_CallFuncO selector);
/* Returns a Texture2D object given an CGImageRef image
* If the image was not previously loaded, it will create a new CCTexture2D object and it will return it.
@ -105,6 +115,7 @@ public:
* If "key" is nil, then a new texture will be created each time.
* @since v0.8
*/
// todo: CGImageRef CCTexture2D* addCGImage(CGImageRef image, string & key);
/** Returns a Texture2D object given an UIImage image
* If the image was not previously loaded, it will create a new CCTexture2D object and it will return it.

View File

@ -101,368 +101,13 @@ SOURCES = ../Classes/AccelerometerTest/AccelerometerTest.cpp \
RESOURCE_PATH = ../Resources
RESOURCES = \
Hello.png \
Images/Comet.png \
Images/Fog.png \
Images/HelloWorld.png \
Images/Icon.png \
Images/Pea.png \
Images/PlanetCute-1024x1024.png \
Images/SendScoreButton.png \
Images/SendScoreButtonPressed.png \
Images/SpinningPeas.png \
Images/SpookyPeas.png \
Images/arrows.png \
Images/arrowsBar.png \
Images/atlastest.png \
Images/b1.png \
Images/b2.png \
Images/background.png \
Images/background1.jpg \
Images/background1.png \
Images/background2.jpg \
Images/background2.png \
Images/background3.jpg \
Images/background3.png \
Images/ball.png \
Images/bitmapFontTest3.fnt \
Images/bitmapFontTest3.png \
Images/blocks.png \
Images/btn-about-normal.png \
Images/btn-about-selected.png \
Images/btn-highscores-normal.png \
Images/btn-highscores-selected.png \
Images/btn-play-normal.png \
Images/btn-play-selected.png \
Images/bugs/RetinaDisplay.jpg \
Images/bugs/bug886.jpg \
Images/bugs/bug886.png \
Images/bugs/circle.plist \
Images/bugs/circle.png \
Images/bugs/corner.png \
Images/bugs/edge.png \
Images/bugs/fill.png \
Images/bugs/picture.png \
Images/close.png \
Images/f1.png \
Images/f2.png \
Images/fire-grayscale.png \
Images/fire.png \
Images/fire_rgba8888.pvr \
Images/grossini.png \
Images/grossini_128x256_mipmap.pvr \
Images/grossini_dance_01.png \
Images/grossini_dance_02.png \
Images/grossini_dance_03.png \
Images/grossini_dance_04.png \
Images/grossini_dance_05.png \
Images/grossini_dance_06.png \
Images/grossini_dance_07.png \
Images/grossini_dance_08.png \
Images/grossini_dance_09.png \
Images/grossini_dance_10.png \
Images/grossini_dance_11.png \
Images/grossini_dance_12.png \
Images/grossini_dance_13.png \
Images/grossini_dance_14.png \
Images/grossini_dance_atlas-mono.png \
Images/grossini_dance_atlas.png \
Images/grossini_dance_atlas_nomipmap.png \
Images/grossini_pvr_rgba4444.pvr \
Images/grossini_pvr_rgba8888.pvr \
Images/grossinis_sister1-testalpha.png \
Images/grossinis_sister1-testalpha.ppng \
Images/grossinis_sister1-testalpha_nopremult.pvr \
Images/grossinis_sister1-testalpha_premult.pvr \
Images/grossinis_sister1.png \
Images/grossinis_sister2.png \
Images/hole_effect.png \
Images/hole_stencil.png \
Images/labelatlas.png \
Images/landscape-1024x1024.png \
Images/logo-mipmap.pvr \
Images/logo-nomipmap.pvr \
Images/menuitemsprite.png \
Images/paddle.png \
Images/particles.png \
Images/pattern1.png \
Images/piece.png \
Images/powered.png \
Images/r1.png \
Images/r2.png \
Images/snow.png \
Images/sprites_test/sprite-0-0.png \
Images/sprites_test/sprite-0-1.png \
Images/sprites_test/sprite-0-2.png \
Images/sprites_test/sprite-0-3.png \
Images/sprites_test/sprite-0-4.png \
Images/sprites_test/sprite-0-5.png \
Images/sprites_test/sprite-0-6.png \
Images/sprites_test/sprite-0-7.png \
Images/sprites_test/sprite-1-0.png \
Images/sprites_test/sprite-1-1.png \
Images/sprites_test/sprite-1-2.png \
Images/sprites_test/sprite-1-3.png \
Images/sprites_test/sprite-1-4.png \
Images/sprites_test/sprite-1-5.png \
Images/sprites_test/sprite-1-6.png \
Images/sprites_test/sprite-1-7.png \
Images/sprites_test/sprite-2-0.png \
Images/sprites_test/sprite-2-1.png \
Images/sprites_test/sprite-2-2.png \
Images/sprites_test/sprite-2-3.png \
Images/sprites_test/sprite-2-4.png \
Images/sprites_test/sprite-2-5.png \
Images/sprites_test/sprite-2-6.png \
Images/sprites_test/sprite-2-7.png \
Images/sprites_test/sprite-3-0.png \
Images/sprites_test/sprite-3-1.png \
Images/sprites_test/sprite-3-2.png \
Images/sprites_test/sprite-3-3.png \
Images/sprites_test/sprite-3-4.png \
Images/sprites_test/sprite-3-5.png \
Images/sprites_test/sprite-3-6.png \
Images/sprites_test/sprite-3-7.png \
Images/sprites_test/sprite-4-0.png \
Images/sprites_test/sprite-4-1.png \
Images/sprites_test/sprite-4-2.png \
Images/sprites_test/sprite-4-3.png \
Images/sprites_test/sprite-4-4.png \
Images/sprites_test/sprite-4-5.png \
Images/sprites_test/sprite-4-6.png \
Images/sprites_test/sprite-4-7.png \
Images/sprites_test/sprite-5-0.png \
Images/sprites_test/sprite-5-1.png \
Images/sprites_test/sprite-5-2.png \
Images/sprites_test/sprite-5-3.png \
Images/sprites_test/sprite-5-4.png \
Images/sprites_test/sprite-5-5.png \
Images/sprites_test/sprite-5-6.png \
Images/sprites_test/sprite-5-7.png \
Images/sprites_test/sprite-6-0.png \
Images/sprites_test/sprite-6-1.png \
Images/sprites_test/sprite-6-2.png \
Images/sprites_test/sprite-6-3.png \
Images/sprites_test/sprite-6-4.png \
Images/sprites_test/sprite-6-5.png \
Images/sprites_test/sprite-6-6.png \
Images/sprites_test/sprite-6-7.png \
Images/sprites_test/sprite-7-0.png \
Images/sprites_test/sprite-7-1.png \
Images/sprites_test/sprite-7-2.png \
Images/sprites_test/sprite-7-3.png \
Images/sprites_test/sprite-7-4.png \
Images/sprites_test/sprite-7-5.png \
Images/sprites_test/sprite-7-6.png \
Images/sprites_test/sprite-7-7.png \
Images/spritesheet1.png \
Images/stars-grayscale.png \
Images/stars.png \
Images/stars2-grayscale.png \
Images/stars2.png \
Images/streak.png \
Images/test-rgba1.png \
Images/test_1021x1024.png \
Images/test_1021x1024_a8.pvr \
Images/test_1021x1024_a8.pvr.gz \
Images/test_1021x1024_rgb888.pvr \
Images/test_1021x1024_rgb888.pvr.gz \
Images/test_1021x1024_rgba4444.pvr \
Images/test_1021x1024_rgba4444.pvr.gz \
Images/test_1021x1024_rgba8888.pvr \
Images/test_1021x1024_rgba8888.pvr.gz \
Images/test_blend.png \
Images/test_image-bad_encoding.pvr \
Images/test_image.jpeg \
Images/test_image.png \
Images/test_image.pvr \
Images/test_image.pvrraw \
Images/test_image.tiff \
Images/test_image.webp \
Images/test_image_a8.pvr \
Images/test_image_a8_v3.pvr \
Images/test_image_ai88.pvr \
Images/test_image_ai88_v3.pvr \
Images/test_image_bgra8888.pvr \
Images/test_image_bgra8888_v3.pvr \
Images/test_image_i8.pvr \
Images/test_image_i8_v3.pvr \
Images/test_image_pvrtc2bpp.pvr \
Images/test_image_pvrtc2bpp_v3.pvr \
Images/test_image_pvrtc4bpp.pvr \
Images/test_image_pvrtc4bpp_v3.pvr \
Images/test_image_pvrtcii2bpp_v3.pvr \
Images/test_image_pvrtcii4bpp_v3.pvr \
Images/test_image_rgb565.pvr \
Images/test_image_rgb565_v3.pvr \
Images/test_image_rgb888.pvr \
Images/test_image_rgb888_v3.pvr \
Images/test_image_rgba4444.pvr \
Images/test_image_rgba4444.pvr.ccz \
Images/test_image_rgba4444.pvr.gz \
Images/test_image_rgba4444_mipmap.pvr \
Images/test_image_rgba4444_v3.pvr \
Images/test_image_rgba5551.pvr \
Images/test_image_rgba5551_v3.pvr \
Images/test_image_rgba8888.pvr \
Images/test_image_rgba8888_v3.pvr \
Images/texture1024x1024.png \
Images/texture2048x2048.png \
Images/texture512x512.png \
Images/white-512x512.png \
Particles/BoilingFoam.plist \
Particles/BurstPipe.plist \
Particles/Comet.plist \
Particles/ExplodingRing.plist \
Particles/Flower.plist \
Particles/Galaxy.plist \
Particles/LavaFlow.plist \
Particles/Phoenix.plist \
Particles/SmallSun.plist \
Particles/SpinningPeas.plist \
Particles/Spiral.plist \
Particles/SpookyPeas.plist \
Particles/TestPremultipliedAlpha.plist \
Particles/Upsidedown.plist \
Particles/debian.plist \
Particles/lines.plist \
TileMaps/fixed-ortho-test2.png \
TileMaps/hexa-test.tmx \
TileMaps/hexa-tiles.png \
TileMaps/iso-test-bug787.tmx \
TileMaps/iso-test-movelayer.tmx \
TileMaps/iso-test-objectgroup.tmx \
TileMaps/iso-test-vertexz.tmx \
TileMaps/iso-test-zorder.tmx \
TileMaps/iso-test.png \
TileMaps/iso-test.tmx \
TileMaps/iso-test1.tmx \
TileMaps/iso-test2-uncompressed.tmx \
TileMaps/iso-test2.png \
TileMaps/iso-test2.tmx \
TileMaps/iso.png \
TileMaps/levelmap.tga \
TileMaps/ortho-objects.tmx \
TileMaps/ortho-rotation-test.tmx \
TileMaps/ortho-test1.png \
TileMaps/ortho-test1_bw.png \
TileMaps/ortho-test2.png \
TileMaps/ortho-tile-property.tmx \
TileMaps/orthogonal-test-movelayer.tmx \
TileMaps/orthogonal-test-vertexz.tmx \
TileMaps/orthogonal-test-zorder.tmx \
TileMaps/orthogonal-test1.tmx \
TileMaps/orthogonal-test1.tsx \
TileMaps/orthogonal-test2.tmx \
TileMaps/orthogonal-test3.tmx \
TileMaps/orthogonal-test4.tmx \
TileMaps/orthogonal-test5.tmx \
TileMaps/orthogonal-test6.tmx \
TileMaps/test-object-layer.tmx \
TileMaps/tiles.png \
TileMaps/tmw_desert_spacing.png \
animations/dragon_animation.png \
animations/ghosts.png \
animations/grossini-aliases.png \
animations/grossini.png \
animations/grossini_blue.png \
animations/grossini_family.png \
animations/grossini_gray.png \
background.mp3 \
effect1.wav \
extensions/CCControlColourPickerSpriteSheet.png \
extensions/background.png \
extensions/button.png \
extensions/buttonBackground.png \
extensions/buttonHighlighted.png \
extensions/green_edit.png \
extensions/orange_edit.png \
extensions/potentiometerButton.png \
extensions/potentiometerProgress.png \
extensions/potentiometerTrack.png \
extensions/ribbon.png \
extensions/sliderProgress.png \
extensions/sliderProgress2.png \
extensions/sliderThumb.png \
extensions/sliderTrack.png \
extensions/sliderTrack2.png \
extensions/stepper-minus.png \
extensions/stepper-plus.png \
extensions/switch-mask.png \
extensions/switch-off.png \
extensions/switch-on.png \
extensions/switch-thumb.png \
extensions/yellow_edit.png \
fonts/Abberancy.ttf \
fonts/Abduction.ttf \
fonts/Thonburi.ttf \
fonts/ThonburiBold.ttf \
fonts/arial-unicode-26.GlyphProject \
fonts/arial-unicode-26.fnt \
fonts/arial-unicode-26.png \
fonts/arial.ttf \
fonts/arial16.fnt \
fonts/arial16.png \
fonts/bitmapFontChinese.fnt \
fonts/bitmapFontChinese.png \
fonts/bitmapFontTest.fnt \
fonts/bitmapFontTest.png \
fonts/bitmapFontTest2.bmp \
fonts/bitmapFontTest2.fnt \
fonts/bitmapFontTest2.png \
fonts/bitmapFontTest3.fnt \
fonts/bitmapFontTest3.png \
fonts/bitmapFontTest4.fnt \
fonts/bitmapFontTest4.png \
fonts/bitmapFontTest5.fnt \
fonts/bitmapFontTest5.png \
fonts/boundsTestFont.fnt \
fonts/boundsTestFont.png \
fonts/font-issue1343-hd.fnt \
fonts/font-issue1343-hd.png \
fonts/font-issue1343.fnt \
fonts/font-issue1343.png \
fonts/futura-48.fnt \
fonts/futura-48.png \
fonts/geneva-32.fnt \
fonts/helvetica-32.fnt \
fonts/helvetica-geneva-32.png \
fonts/konqa32.fnt \
fonts/konqa32.png \
fonts/labelatlas.png \
fonts/larabie-16.plist \
fonts/larabie-16.png \
fonts/markerFelt.fnt \
fonts/markerFelt.png \
fonts/strings.xml \
fonts/tahoma.ttf \
fonts/tuffy_bold_italic-charmap.plist \
fonts/tuffy_bold_italic-charmap.png \
fonts/west_england-64.fnt \
fonts/west_england-64.png \
fps_images.png \
fonts/bitmapFontTest.fnt \
zwoptex/grossini-generic.plist \
zwoptex/grossini-generic.png \
zwoptex/grossini.plist \
zwoptex/grossini.png
# XXX: Need to figure out how to accept filnames with spaces in them.
# fonts/A\ Damn\ Mess.ttf \
fonts/American\ Typewriter.ttf \
fonts/Courier New.ttf \
fonts/Marker Felt.ttf \
fonts/Paint Boy.ttf \
fonts/Schwarzwald Regular.ttf \
fonts/Scissor Cuts.ttf \
RESOURCES := $(shell (cd $(RESOURCE_PATH); find . -type f ! -name '* *'))
SHAREDLIBS = -lcocos2d -lcocosdenshion
COCOS_LIBS = $(LIB_DIR)/libcocos2d.so $(LIB_DIR)/libcocosdenshion.so
include ../../../../cocos2dx/proj.emscripten/cocos2dx.mk
INCLUDES += -I../ \
-I../../ \
-I../Classes \
@ -489,11 +134,12 @@ $(TARGET).data: $(CORE_MAKEFILE_LIST) $(patsubst %,$(RESOURCE_PATH)/%,$(RESOURCE
# Always need a font path, so ensure that it is created first.
mkdir -p $(RESTMP)/fonts
(cd $(RESOURCE_PATH) && tar cf - $(RESOURCES)) | (cd $(RESTMP) && tar xvf -)
# NOTE: we copy the system arial.ttf so that there is always a fallback.
cp /Library/Fonts/Arial.ttf $(RESTMP)/fonts/arial.ttf
(cd $(RESTMP); python $(PACKAGER) $(EXECUTABLE).data $(patsubst %,--preload %,$(RESOURCES)) --preload fonts --pre-run > $(EXECUTABLE).data.js)
mv $(RESTMP)/$(EXECUTABLE).data $@
mv $(RESTMP)/$(EXECUTABLE).data.js $@.js
# Copy the assets as individual files to the output directory in addition
# to building the .data file so that async texture loading works.
cp -av $(RESOURCE_PATH)/* $(shell dirname $@)
rm -rf $(RESTMP)
$(BIN_DIR)/index.html: index.html $(CORE_MAKEFILE_LIST)

View File

@ -37,12 +37,20 @@
<script type='text/javascript'>
// connect to canvas
var Module = {
debug: true,
consoleLogging: true,
preRun: [],
postRun: [],
print: (function() {
var element = document.getElementById('output');
element.value = ''; // clear browser cache
return function(text) {
if(!Module.debug) return;
if(Module.consoleLogging)
{
console.log(text);
return;
}
text = Array.prototype.slice.call(arguments).join(' ');
// These replacements are necessary if you render to raw HTML
//text = text.replace(/&/g, "&amp;");
@ -54,6 +62,12 @@
};
})(),
printErr: function(text) {
if(!Module.debug) return;
if(Module.consoleLogging)
{
console.log(text);
return;
}
text = Array.prototype.slice.call(arguments).join(' ');
if (0) { // XXX disabled for safety typeof dump == 'function') {
dump(text + '\n'); // fast, straight to the real console