mirror of https://github.com/axmolengine/axmol.git
Improve emission shapes workflow.
`ps->addEmissionShape(ParticleSystem::createConeShape({ -2000, 0 }, 400, 90, 50));` is the new workflow.
This commit is contained in:
parent
0462dbea43
commit
237a3ccbad
|
@ -4,6 +4,7 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- dev
|
||||
- main
|
||||
paths:
|
||||
- core/**/*
|
||||
- extensions/**/*
|
||||
|
@ -30,10 +31,10 @@ jobs:
|
|||
run: tools\win-ci\genbindings.ps1
|
||||
|
||||
- name: Commit genbindings changes
|
||||
uses: EndBug/add-and-commit@v9.0.0
|
||||
uses: EndBug/add-and-commit@v7.5.0
|
||||
with:
|
||||
committer_name: GitHub Actions
|
||||
committer_email: 41898282+github-actions[bot]@users.noreply.github.com
|
||||
message: 'Committing genbindings changes'
|
||||
message: 'Committing genbindings changes [skip ci]'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# adxe
|
||||
|
||||
[![dev](https://img.shields.io/github/v/release/adxeproject/adxe?include_prereleases&label=release)](https://github.com/adxeproject/adxe/releases)
|
||||
[![dev](https://img.shields.io/badge/v1.0.0-beta6-yellow.svg)](https://github.com/adxeproject/adxe/releases)
|
||||
[![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/adxeproject/adxe/blob/master/LICENSE)
|
||||
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/1c5628dea478449ea0c6e1b0e30c3be9)](https://app.codacy.com/gh/adxeproject/adxe?utm_source=github.com&utm_medium=referral&utm_content=adxeproject/adxe&utm_campaign=Badge_Grade_Settings)
|
||||
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-blue.svg)](https://github.com/adxeproject/adxe/pulls)
|
||||
|
@ -99,7 +99,7 @@ Open [APPENDIX.md](APPENDIX.md) for additional information and see [Milestones](
|
|||
4. Start Android Studio and Open [Tools][SDKManager], then switch to ```SDK Tools```, check the ```Show Package Details```, choose the following tools and click the button ```Apply``` to install them:
|
||||
* Android SDK Platform 29 r5
|
||||
* Android SDK Build-Tools 29.0.2
|
||||
* NDK r23c+
|
||||
* NDK r19c+
|
||||
* CMake 3.10+
|
||||
5. Wait for ```Gradle sync``` finish.
|
||||
6. Note: If you use non-sdk provided CMake edition, you will need to download ```ninja``` from https://github.com/ninja-build/ninja/releases, and copy ```ninja.exe``` to cmake's bin directory
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# adxe
|
||||
|
||||
[![dev](https://img.shields.io/github/v/release/adxeproject/adxe?include_prereleases&label=release)](https://github.com/adxeproject/adxe/releases)
|
||||
[![dev](https://img.shields.io/badge/v1.0.0-beta6-yellow.svg)](https://github.com/adxeproject/adxe/releases)
|
||||
[![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/adxeproject/adxe/blob/master/LICENSE)
|
||||
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/1c5628dea478449ea0c6e1b0e30c3be9)](https://app.codacy.com/gh/adxeproject/adxe?utm_source=github.com&utm_medium=referral&utm_content=adxeproject/adxe&utm_campaign=Badge_Grade_Settings)
|
||||
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-blue.svg)](https://github.com/adxeproject/adxe/pulls)
|
||||
|
@ -73,7 +73,7 @@
|
|||
3. 通过 [Tools][SdkManagers] 打开sdk管理工具,选择如下SDK Platforms和SDK Tools后, 点击按钮 ```Apply``` 一路跟着引导安装即可:
|
||||
* Android SDK Platform 29 r5 (在SDK Platforms页签)
|
||||
* Android SDK Build-Tools 29.0.2
|
||||
* NDK r23c+
|
||||
* NDK r19c+
|
||||
* CMake 3.10+
|
||||
|
||||
5. 等待Gradle sync完成后,Build APKs,安装运行
|
||||
|
|
|
@ -55,7 +55,7 @@ macro(cocos2dx_depend)
|
|||
find_library(APPLICATIONSERVICES_LIBRARY ApplicationServices)
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
find_library(APPKIT_LIBRARY AppKit)
|
||||
#find_library(ICONV_LIBRARY iconv)
|
||||
find_library(ICONV_LIBRARY iconv)
|
||||
find_library(AUDIOUNIT_LIBRARY AudioUnit)
|
||||
find_library(COREAUDIO_LIBRARY CoreAudio)
|
||||
find_library(SYSTEMCONFIGURATION_LIBRARY SystemConfiguration)
|
||||
|
@ -66,7 +66,7 @@ macro(cocos2dx_depend)
|
|||
${IOKIT_LIBRARY}
|
||||
${COCOS_APPLE_LIBS}
|
||||
${APPKIT_LIBRARY}
|
||||
#${ICONV_LIBRARY}
|
||||
${ICONV_LIBRARY}
|
||||
${AUDIOUNIT_LIBRARY}
|
||||
${COREAUDIO_LIBRARY}
|
||||
${SYSTEMCONFIGURATION_LIBRARY}
|
||||
|
@ -84,7 +84,7 @@ macro(cocos2dx_depend)
|
|||
find_library(AV_FOUNDATION_LIBRARY AVFoundation)
|
||||
find_library(WEBKIT_LIBRARY WebKit)
|
||||
find_library(ZLIB z)
|
||||
#find_library(ICONVLIB iconv)
|
||||
find_library(ICONVLIB iconv)
|
||||
list(APPEND PLATFORM_SPECIFIC_LIBS
|
||||
${UIKIT_LIBRARY}
|
||||
${OPENGLES_LIBRARY}
|
||||
|
@ -98,7 +98,7 @@ macro(cocos2dx_depend)
|
|||
${WEBKIT_LIBRARY}
|
||||
${COCOS_APPLE_LIBS}
|
||||
${ZLIB}
|
||||
#${ICONVLIB}
|
||||
${ICONVLIB}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright (c) 2013 Zynga Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
Copyright (c) 2021-2022 Bytedance Inc.
|
||||
Copyright (c) 2021 Bytedance Inc.
|
||||
|
||||
https://adxeproject.github.io/
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "2d/CCFontAtlas.h"
|
||||
#if CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 && CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID
|
||||
# include <iconv.h>
|
||||
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
|
||||
# include "platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h"
|
||||
#endif
|
||||
|
@ -124,6 +125,14 @@ FontAtlas::~FontAtlas()
|
|||
releaseTextures();
|
||||
|
||||
delete[] _currentPageData;
|
||||
|
||||
#if CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 && CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID
|
||||
if (_iconv)
|
||||
{
|
||||
iconv_close(_iconv);
|
||||
_iconv = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FontAtlas::initTextureWithZeros(Texture2D* texture)
|
||||
|
@ -220,9 +229,80 @@ bool FontAtlas::getLetterDefinitionForChar(char32_t utf32Char, FontLetterDefinit
|
|||
}
|
||||
}
|
||||
|
||||
void FontAtlas::findNewCharacters(const std::u32string& u32Text, std::unordered_set<char32_t>& charset)
|
||||
void FontAtlas::conversionU32TOGB2312(const std::u32string& u32Text,
|
||||
std::unordered_map<unsigned int, unsigned int>& charCodeMap)
|
||||
{
|
||||
size_t strLen = u32Text.length();
|
||||
auto gb2312StrSize = strLen * 2;
|
||||
auto gb2312Text = new char[gb2312StrSize];
|
||||
memset(gb2312Text, 0, gb2312StrSize);
|
||||
|
||||
switch (_fontFreeType->getEncoding())
|
||||
{
|
||||
case FT_ENCODING_GB2312:
|
||||
{
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
||||
std::u16string u16Text;
|
||||
cocos2d::StringUtils::UTF32ToUTF16(u32Text, u16Text);
|
||||
WideCharToMultiByte(936, NULL, (LPCWCH)u16Text.c_str(), strLen, (LPSTR)gb2312Text, gb2312StrSize, NULL, NULL);
|
||||
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
|
||||
conversionEncodingJNI((char*)u32Text.c_str(), gb2312StrSize, "UTF-32LE", gb2312Text, "GB2312");
|
||||
#else
|
||||
if (_iconv == nullptr)
|
||||
{
|
||||
_iconv = iconv_open("GBK//TRANSLIT", "UTF-32LE");
|
||||
}
|
||||
|
||||
if (_iconv == (iconv_t)-1)
|
||||
{
|
||||
CCLOG("conversion from utf32 to gb2312 not available");
|
||||
}
|
||||
else
|
||||
{
|
||||
char* pin = (char*)u32Text.c_str();
|
||||
char* pout = gb2312Text;
|
||||
size_t inLen = strLen * 2;
|
||||
size_t outLen = gb2312StrSize;
|
||||
|
||||
iconv(_iconv, (char**)&pin, &inLen, &pout, &outLen);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CCLOG("Unsupported encoding:%d", _fontFreeType->getEncoding());
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned short gb2312Code = 0;
|
||||
unsigned char* dst = (unsigned char*)&gb2312Code;
|
||||
char32_t u32Code;
|
||||
for (size_t index = 0, gbIndex = 0; index < strLen; ++index)
|
||||
{
|
||||
u32Code = u32Text[index];
|
||||
if (u32Code < 256)
|
||||
{
|
||||
charCodeMap[u32Code] = u32Code;
|
||||
gbIndex += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = gb2312Text[gbIndex + 1];
|
||||
dst[1] = gb2312Text[gbIndex];
|
||||
charCodeMap[u32Code] = gb2312Code;
|
||||
|
||||
gbIndex += 2;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] gb2312Text;
|
||||
}
|
||||
|
||||
void FontAtlas::findNewCharacters(const std::u32string& u32Text,
|
||||
std::unordered_map<unsigned int, unsigned int>& charCodeMap)
|
||||
{
|
||||
std::u32string newChars;
|
||||
FT_Encoding charEncoding = _fontFreeType->getEncoding();
|
||||
|
||||
// find new characters
|
||||
if (_letterDefinitions.empty())
|
||||
|
@ -258,8 +338,25 @@ void FontAtlas::findNewCharacters(const std::u32string& u32Text, std::unordered_
|
|||
|
||||
if (!newChars.empty())
|
||||
{
|
||||
for (auto u32Code : newChars)
|
||||
charset.insert(u32Code);
|
||||
switch (charEncoding)
|
||||
{
|
||||
case FT_ENCODING_UNICODE:
|
||||
{
|
||||
for (auto u32Code : newChars)
|
||||
{
|
||||
charCodeMap[u32Code] = u32Code;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FT_ENCODING_GB2312:
|
||||
{
|
||||
conversionU32TOGB2312(newChars, charCodeMap);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CCLOG("FontAtlas::findNewCharacters: Unsupported encoding:%d", charEncoding);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,9 +370,9 @@ bool FontAtlas::prepareLetterDefinitions(const std::u32string& utf32Text)
|
|||
if (!_currentPageData)
|
||||
reinit();
|
||||
|
||||
std::unordered_set<char32_t> charCodeSet;
|
||||
findNewCharacters(utf32Text, charCodeSet);
|
||||
if (charCodeSet.empty())
|
||||
std::unordered_map<unsigned int, unsigned int> codeMapOfNewChar;
|
||||
findNewCharacters(utf32Text, codeMapOfNewChar);
|
||||
if (codeMapOfNewChar.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -293,9 +390,9 @@ bool FontAtlas::prepareLetterDefinitions(const std::u32string& utf32Text)
|
|||
|
||||
int startY = (int)_currentPageOrigY;
|
||||
|
||||
for (auto charCode : charCodeSet)
|
||||
for (auto&& it : codeMapOfNewChar)
|
||||
{
|
||||
auto bitmap = _fontFreeType->getGlyphBitmap(charCode, bitmapWidth, bitmapHeight, tempRect, tempDef.xAdvance);
|
||||
auto bitmap = _fontFreeType->getGlyphBitmap(it.second, bitmapWidth, bitmapHeight, tempRect, tempDef.xAdvance);
|
||||
if (bitmap && bitmapWidth > 0 && bitmapHeight > 0)
|
||||
{
|
||||
tempDef.validDefinition = true;
|
||||
|
@ -374,7 +471,7 @@ bool FontAtlas::prepareLetterDefinitions(const std::u32string& utf32Text)
|
|||
_currentPageOrigX += 1;
|
||||
}
|
||||
|
||||
_letterDefinitions[charCode] = tempDef;
|
||||
_letterDefinitions[it.first] = tempDef;
|
||||
}
|
||||
|
||||
updateTextureContent(pixelFormat, startY);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright (c) 2013 Zynga Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
Copyright (c) 2021-2022 Bytedance Inc.
|
||||
Copyright (c) 2021 Bytedance Inc.
|
||||
|
||||
https://adxeproject.github.io/
|
||||
|
||||
|
@ -120,7 +120,10 @@ protected:
|
|||
|
||||
void releaseTextures();
|
||||
|
||||
void findNewCharacters(const std::u32string& u32Text, std::unordered_set<char32_t>& charCodeSet);
|
||||
void findNewCharacters(const std::u32string& u32Text, std::unordered_map<unsigned int, unsigned int>& charCodeMap);
|
||||
|
||||
void conversionU32TOGB2312(const std::u32string& u32Text,
|
||||
std::unordered_map<unsigned int, unsigned int>& charCodeMap);
|
||||
|
||||
void initTextureWithZeros(Texture2D* texture);
|
||||
|
||||
|
@ -138,6 +141,7 @@ protected:
|
|||
float _lineHeight = 0.f;
|
||||
Font* _font = nullptr;
|
||||
FontFreeType* _fontFreeType = nullptr;
|
||||
void* _iconv = nullptr;
|
||||
|
||||
// Dynamic GlyphCollection related stuff
|
||||
int _currentPage = 0;
|
||||
|
|
|
@ -54,7 +54,8 @@ void FontAtlasCache::purgeCachedData()
|
|||
|
||||
FontAtlas* FontAtlasCache::getFontAtlasTTF(const _ttfConfig* config)
|
||||
{
|
||||
auto realFontFilename = config->fontFilePath; // resolves real file path, to prevent storing multiple atlases for the same file.
|
||||
auto realFontFilename = FileUtils::getInstance()->getNewFilename(
|
||||
config->fontFilePath); // resolves real file path, to prevent storing multiple atlases for the same file.
|
||||
bool useDistanceField = config->distanceFieldEnabled;
|
||||
if (config->outlineSize > 0)
|
||||
{
|
||||
|
@ -96,7 +97,8 @@ FontAtlas* FontAtlasCache::getFontAtlasFNT(std::string_view fontFileName)
|
|||
|
||||
FontAtlas* FontAtlasCache::getFontAtlasFNT(std::string_view fontFileName, std::string_view subTextureKey)
|
||||
{
|
||||
const auto realFontFilename = fontFileName; // resolves real file path, to prevent storing multiple atlases for the same file.
|
||||
const auto realFontFilename = FileUtils::getInstance()->getNewFilename(
|
||||
fontFileName); // resolves real file path, to prevent storing multiple atlases for the same file.
|
||||
std::string atlasName{subTextureKey};
|
||||
atlasName.append(" ", 1).append(realFontFilename);
|
||||
|
||||
|
@ -123,7 +125,8 @@ FontAtlas* FontAtlasCache::getFontAtlasFNT(std::string_view fontFileName, std::s
|
|||
|
||||
FontAtlas* FontAtlasCache::getFontAtlasFNT(std::string_view fontFileName, const Rect& imageRect, bool imageRotated)
|
||||
{
|
||||
const auto realFontFilename = fontFileName; // resolves real file path, to prevent storing multiple atlases for the same file.
|
||||
const auto realFontFilename = FileUtils::getInstance()->getNewFilename(
|
||||
fontFileName); // resolves real file path, to prevent storing multiple atlases for the same file.
|
||||
char keyPrefix[ATLAS_MAP_KEY_PREFIX_BUFFER_SIZE];
|
||||
snprintf(keyPrefix, ATLAS_MAP_KEY_PREFIX_BUFFER_SIZE, "%.2f %.2f ", imageRect.origin.x, imageRect.origin.y);
|
||||
std::string atlasName(keyPrefix);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright (c) 2013 Zynga Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
Copyright (c) 2021-2022 Bytedance Inc.
|
||||
Copyright (c) 2021 Bytedance Inc.
|
||||
|
||||
https://adxeproject.github.io/
|
||||
|
||||
|
@ -59,7 +59,7 @@ typedef struct _DataRef
|
|||
unsigned int referenceCount = 0;
|
||||
} DataRef;
|
||||
|
||||
static hlookup::string_map<DataRef> s_cacheFontData;
|
||||
static std::unordered_map<std::string, DataRef> s_cacheFontData;
|
||||
|
||||
// ------ freetype2 stream parsing support ---
|
||||
static unsigned long ft_stream_read_callback(FT_Stream stream,
|
||||
|
@ -149,6 +149,7 @@ FT_Library FontFreeType::getFTLibrary()
|
|||
FontFreeType::FontFreeType(bool distanceFieldEnabled /* = false */, float outline /* = 0 */)
|
||||
: _fontFace(nullptr)
|
||||
, _stroker(nullptr)
|
||||
, _encoding(FT_ENCODING_UNICODE)
|
||||
, _distanceFieldEnabled(distanceFieldEnabled)
|
||||
, _outlineSize(0.0f)
|
||||
, _ascender(0)
|
||||
|
@ -169,12 +170,16 @@ FontFreeType::FontFreeType(bool distanceFieldEnabled /* = false */, float outlin
|
|||
}
|
||||
// clang-format on
|
||||
|
||||
bool FontFreeType::loadFontFace(std::string_view fontPath, float fontSize)
|
||||
bool FontFreeType::loadFontFace(std::string_view fontName, float fontSize)
|
||||
{
|
||||
FT_Face face;
|
||||
// save font name locally
|
||||
_fontName = fontName;
|
||||
_fontSize = fontSize;
|
||||
|
||||
if (_streamParsingEnabled)
|
||||
{
|
||||
auto fullPath = FileUtils::getInstance()->fullPathForFilename(fontPath);
|
||||
auto fullPath = FileUtils::getInstance()->fullPathForFilename(_fontName);
|
||||
if (fullPath.empty())
|
||||
return false;
|
||||
|
||||
|
@ -202,15 +207,15 @@ bool FontFreeType::loadFontFace(std::string_view fontPath, float fontSize)
|
|||
else
|
||||
{
|
||||
DataRef* sharableData;
|
||||
auto it = s_cacheFontData.find(fontPath);
|
||||
auto it = s_cacheFontData.find(_fontName);
|
||||
if (it != s_cacheFontData.end())
|
||||
{
|
||||
sharableData = &it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
sharableData = &s_cacheFontData[fontPath];
|
||||
sharableData->data = FileUtils::getInstance()->getDataFromFile(fontPath);
|
||||
sharableData = &s_cacheFontData[_fontName];
|
||||
sharableData->data = FileUtils::getInstance()->getDataFromFile(_fontName);
|
||||
}
|
||||
|
||||
++sharableData->referenceCount;
|
||||
|
@ -220,55 +225,66 @@ bool FontFreeType::loadFontFace(std::string_view fontPath, float fontSize)
|
|||
return false;
|
||||
}
|
||||
|
||||
do
|
||||
if (FT_Select_Charmap(face, FT_ENCODING_UNICODE))
|
||||
{
|
||||
if (!face->charmap || face->charmap->encoding != FT_ENCODING_UNICODE)
|
||||
break;
|
||||
|
||||
// set the requested font size
|
||||
int dpi = 72;
|
||||
int fontSizePoints = (int)(64.f * fontSize * CC_CONTENT_SCALE_FACTOR());
|
||||
if (FT_Set_Char_Size(face, fontSizePoints, fontSizePoints, dpi, dpi))
|
||||
break;
|
||||
|
||||
// store the face globally
|
||||
_fontFace = face;
|
||||
_fontSize = fontSize;
|
||||
_fontName = fontPath;
|
||||
|
||||
// Notes:
|
||||
// a. Since freetype 2.8.1 the TT matrics isn't sync to size_matrics, see the function 'tt_size_request' in
|
||||
// truetype/ttdriver.c b. The TT spec always asks for ROUND, not FLOOR or CEIL, see also the function
|
||||
// 'tt_size_reset' in truetype/ttobjs.c
|
||||
// ** Please see description of FT_Size_Metrics_ in freetype.h about this solution
|
||||
// FT_PIX_ROUND is copy from freetype/internal/ftobjs.h
|
||||
auto& size_metrics = _fontFace->size->metrics;
|
||||
if (_doNativeBytecodeHinting && !strcmp(FT_Get_Font_Format(face), "TrueType"))
|
||||
int foundIndex = -1;
|
||||
for (int charmapIndex = 0; charmapIndex < face->num_charmaps; charmapIndex++)
|
||||
{
|
||||
if (face->charmaps[charmapIndex]->encoding != FT_ENCODING_NONE)
|
||||
{
|
||||
foundIndex = charmapIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundIndex == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_encoding = face->charmaps[foundIndex]->encoding;
|
||||
if (FT_Select_Charmap(face, _encoding))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// set the requested font size
|
||||
int dpi = 72;
|
||||
int fontSizePoints = (int)(64.f * fontSize * CC_CONTENT_SCALE_FACTOR());
|
||||
if (FT_Set_Char_Size(face, fontSizePoints, fontSizePoints, dpi, dpi))
|
||||
return false;
|
||||
|
||||
// store the face globally
|
||||
_fontFace = face;
|
||||
|
||||
// Notes:
|
||||
// a. Since freetype 2.8.1 the TT matrics isn't sync to size_matrics, see the function 'tt_size_request' in
|
||||
// truetype/ttdriver.c b. The TT spec always asks for ROUND, not FLOOR or CEIL, see also the function
|
||||
// 'tt_size_reset' in truetype/ttobjs.c
|
||||
// ** Please see description of FT_Size_Metrics_ in freetype.h about this solution
|
||||
// FT_PIX_ROUND is copy from freetype/internal/ftobjs.h
|
||||
auto& size_metrics = _fontFace->size->metrics;
|
||||
if (_doNativeBytecodeHinting && !strcmp(FT_Get_Font_Format(face), "TrueType"))
|
||||
{
|
||||
#if !defined(FT_PIX_ROUND)
|
||||
# define FT_TYPEOF(type)
|
||||
# define FT_PIX_FLOOR(x) ((x) & ~FT_TYPEOF(x) 63)
|
||||
# define FT_PIX_ROUND(x) FT_PIX_FLOOR((x) + 32)
|
||||
#endif
|
||||
_ascender = FT_PIX_ROUND(FT_MulFix(face->ascender, size_metrics.y_scale));
|
||||
_descender = FT_PIX_ROUND(FT_MulFix(face->descender, size_metrics.y_scale));
|
||||
}
|
||||
else
|
||||
{
|
||||
_ascender = size_metrics.ascender;
|
||||
_descender = size_metrics.descender;
|
||||
}
|
||||
_ascender = FT_PIX_ROUND(FT_MulFix(face->ascender, size_metrics.y_scale));
|
||||
_descender = FT_PIX_ROUND(FT_MulFix(face->descender, size_metrics.y_scale));
|
||||
}
|
||||
else
|
||||
{
|
||||
_ascender = size_metrics.ascender;
|
||||
_descender = size_metrics.descender;
|
||||
}
|
||||
|
||||
_lineHeight = (_ascender - _descender) >> 6;
|
||||
_lineHeight = (_ascender - _descender) >> 6;
|
||||
|
||||
// done and good
|
||||
return true;
|
||||
} while (false);
|
||||
|
||||
FT_Done_Face(face);
|
||||
|
||||
cocos2d::log("Init font '%s' failed, only unicode ttf/ttc was supported.", fontPath.data());
|
||||
return false;
|
||||
// done and good
|
||||
return true;
|
||||
}
|
||||
|
||||
FontFreeType::~FontFreeType()
|
||||
|
@ -370,7 +386,7 @@ const char* FontFreeType::getFontFamily() const
|
|||
return _fontFace->family_name;
|
||||
}
|
||||
|
||||
unsigned char* FontFreeType::getGlyphBitmap(char32_t charCode,
|
||||
unsigned char* FontFreeType::getGlyphBitmap(uint32_t theChar,
|
||||
int32_t& outWidth,
|
||||
int32_t& outHeight,
|
||||
Rect& outRect,
|
||||
|
@ -384,11 +400,11 @@ unsigned char* FontFreeType::getGlyphBitmap(char32_t charCode,
|
|||
break;
|
||||
|
||||
// @remark: glyphIndex=0 means charactor is mssing on current font face
|
||||
auto glyphIndex = FT_Get_Char_Index(_fontFace, static_cast<FT_ULong>(charCode));
|
||||
auto glyphIndex = FT_Get_Char_Index(_fontFace, static_cast<FT_ULong>(theChar));
|
||||
#if defined(COCOS2D_DEBUG) && COCOS2D_DEBUG > 0
|
||||
if (glyphIndex == 0)
|
||||
{
|
||||
char32_t ntcs[2] = {charCode, (char32_t)0};
|
||||
char32_t ntcs[2] = {theChar, (char32_t)0};
|
||||
std::u32string_view charUTF32(ntcs, 1);
|
||||
std::string charUTF8;
|
||||
cocos2d::StringUtils::UTF32ToUTF8(charUTF32, charUTF8);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright (c) 2013 Zynga Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
Copyright (c) 2021-2022 Bytedance Inc.
|
||||
Copyright (c) 2021 Bytedance Inc.
|
||||
|
||||
https://adxeproject.github.io/
|
||||
|
||||
|
@ -45,7 +45,7 @@ class CC_DLL FontFreeType : public Font
|
|||
public:
|
||||
static const int DistanceMapSpread;
|
||||
|
||||
static FontFreeType* create(std::string_view fontPath,
|
||||
static FontFreeType* create(std::string_view fontName,
|
||||
float fontSize,
|
||||
GlyphCollection glyphs,
|
||||
std::string_view customGlyphs,
|
||||
|
@ -89,9 +89,11 @@ public:
|
|||
int32_t bitmapWidth,
|
||||
int32_t bitmapHeight);
|
||||
|
||||
FT_Encoding getEncoding() const { return _encoding; }
|
||||
|
||||
int* getHorizontalKerningForTextUTF32(const std::u32string& text, int& outNumLetters) const override;
|
||||
|
||||
unsigned char* getGlyphBitmap(char32_t charCode,
|
||||
unsigned char* getGlyphBitmap(uint32_t theChar,
|
||||
int32_t& outWidth,
|
||||
int32_t& outHeight,
|
||||
Rect& outRect,
|
||||
|
@ -117,7 +119,7 @@ private:
|
|||
FontFreeType(bool distanceFieldEnabled = false, float outline = 0);
|
||||
virtual ~FontFreeType();
|
||||
|
||||
bool loadFontFace(std::string_view fontPath, float fontSize);
|
||||
bool loadFontFace(std::string_view fontName, float fontSize);
|
||||
|
||||
static bool initFreeType();
|
||||
|
||||
|
@ -130,6 +132,7 @@ private:
|
|||
FT_Face _fontFace;
|
||||
std::unique_ptr<FT_StreamRec> _fontStream;
|
||||
FT_Stroker _stroker;
|
||||
FT_Encoding _encoding;
|
||||
|
||||
std::string _fontName;
|
||||
float _fontSize;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -32,6 +32,8 @@ THE SOFTWARE.
|
|||
#include "base/CCProtocols.h"
|
||||
#include "2d/CCNode.h"
|
||||
#include "base/CCValue.h"
|
||||
#include "2d/CCSpriteFrame.h"
|
||||
#include "2d/CCSpriteFrameCache.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -52,6 +54,64 @@ struct particle_point
|
|||
float y;
|
||||
};
|
||||
|
||||
/**
|
||||
* Particle emission shapes.
|
||||
* Current supported shapes are Point, Rectangle, RectangularTorus, Circle, Torus
|
||||
* @since adxe-1.0.0b7
|
||||
*/
|
||||
enum class EmissionShapeType
|
||||
{
|
||||
POINT,
|
||||
RECT,
|
||||
RECTTORUS,
|
||||
CIRCLE,
|
||||
TORUS
|
||||
};
|
||||
|
||||
/**
|
||||
* Particle emission shapes.
|
||||
* Current supported shapes are Point, Rectangle, RectangularTorus, Circle, Torus, Cone, Cone Torus
|
||||
* @since adxe-1.0.0b7
|
||||
*/
|
||||
struct EmissionShape
|
||||
{
|
||||
EmissionShapeType type;
|
||||
|
||||
float x;
|
||||
float y;
|
||||
|
||||
float innerWidth;
|
||||
float innerHeight;
|
||||
float outerWidth;
|
||||
float outerHeight;
|
||||
|
||||
float innerRadius;
|
||||
float outerRadius;
|
||||
float coneOffset;
|
||||
float coneAngle;
|
||||
float edgeElasticity;
|
||||
};
|
||||
|
||||
/** @struct ParticleAnimationDescriptor
|
||||
Structure that contains animation description
|
||||
*/
|
||||
struct ParticleAnimationDescriptor
|
||||
{
|
||||
float animationSpeed;
|
||||
float animationSpeedVariance;
|
||||
std::vector<unsigned short> animationIndices;
|
||||
bool reverseIndices;
|
||||
};
|
||||
|
||||
/** @struct ParticleFrameDescriptor
|
||||
Structure that contains frame description
|
||||
*/
|
||||
struct ParticleFrameDescriptor
|
||||
{
|
||||
cocos2d::Rect rect;
|
||||
bool isRotated;
|
||||
};
|
||||
|
||||
class CC_DLL ParticleData
|
||||
{
|
||||
public:
|
||||
|
@ -70,11 +130,27 @@ public:
|
|||
float* deltaColorB;
|
||||
float* deltaColorA;
|
||||
|
||||
float* hue;
|
||||
float* sat;
|
||||
float* val;
|
||||
|
||||
float* opacityFadeInDelta;
|
||||
float* opacityFadeInLength;
|
||||
|
||||
float* scaleInDelta;
|
||||
float* scaleInLength;
|
||||
|
||||
float* size;
|
||||
float* deltaSize;
|
||||
float* rotation;
|
||||
float* staticRotation;
|
||||
float* deltaRotation;
|
||||
float* totalTimeToLive;
|
||||
float* timeToLive;
|
||||
float* animTimeDelta;
|
||||
float* animTimeLength;
|
||||
unsigned short* animIndex;
|
||||
unsigned short* animCellIndex;
|
||||
unsigned int* atlasIndex;
|
||||
|
||||
//! Mode A: gravity, direction, radial accel, tangential accel
|
||||
|
@ -118,13 +194,41 @@ public:
|
|||
deltaColorB[p1] = deltaColorB[p2];
|
||||
deltaColorA[p1] = deltaColorA[p2];
|
||||
|
||||
size[p1] = size[p2];
|
||||
deltaSize[p1] = deltaSize[p2];
|
||||
if (hue && sat && val)
|
||||
{
|
||||
hue[p1] = hue[p2];
|
||||
sat[p1] = sat[p2];
|
||||
val[p1] = val[p2];
|
||||
}
|
||||
|
||||
rotation[p1] = rotation[p2];
|
||||
deltaRotation[p1] = deltaRotation[p2];
|
||||
if (opacityFadeInDelta && opacityFadeInLength)
|
||||
{
|
||||
opacityFadeInDelta[p1] = opacityFadeInDelta[p2];
|
||||
opacityFadeInLength[p1] = opacityFadeInLength[p2];
|
||||
}
|
||||
|
||||
timeToLive[p1] = timeToLive[p2];
|
||||
if (scaleInDelta && scaleInLength)
|
||||
{
|
||||
scaleInDelta[p1] = scaleInDelta[p2];
|
||||
scaleInLength[p1] = scaleInLength[p2];
|
||||
}
|
||||
|
||||
size[p1] = size[p2];
|
||||
deltaSize[p1] = deltaSize[p2];
|
||||
rotation[p1] = rotation[p2];
|
||||
staticRotation[p1] = staticRotation[p2];
|
||||
deltaRotation[p1] = deltaRotation[p2];
|
||||
|
||||
totalTimeToLive[p1] = totalTimeToLive[p2];
|
||||
timeToLive[p1] = timeToLive[p2];
|
||||
|
||||
if (animTimeDelta && animTimeLength && animIndex && animCellIndex)
|
||||
{
|
||||
animTimeDelta[p1] = animTimeDelta[p2];
|
||||
animTimeLength[p1] = animTimeLength[p2];
|
||||
animIndex[p1] = animIndex[p2];
|
||||
animCellIndex[p1] = animCellIndex[p2];
|
||||
}
|
||||
|
||||
atlasIndex[p1] = atlasIndex[p2];
|
||||
|
||||
|
@ -202,7 +306,7 @@ public:
|
|||
};
|
||||
|
||||
/** PositionType
|
||||
Possible types of particle positions.
|
||||
Types of particle positioning.
|
||||
* @js cc.ParticleSystem.TYPE_FREE
|
||||
*/
|
||||
enum class PositionType
|
||||
|
@ -216,6 +320,17 @@ public:
|
|||
|
||||
};
|
||||
|
||||
/** TexAnimDir
|
||||
Texture animation direction for the particles.
|
||||
*/
|
||||
enum class TexAnimDir
|
||||
{
|
||||
VERTICAL, /** texture coordinates are read top to bottom within the texture */
|
||||
|
||||
HORIZONTAL, /** texture coordinates are read left to right within the texture */
|
||||
|
||||
};
|
||||
|
||||
//* @enum
|
||||
enum
|
||||
{
|
||||
|
@ -227,6 +342,12 @@ public:
|
|||
|
||||
/** The starting radius of the particle is equal to the ending radius. */
|
||||
START_RADIUS_EQUAL_TO_END_RADIUS = -1,
|
||||
|
||||
/** The simulation's seconds are set to the particles' lifetime specified inclusive of variant. */
|
||||
SIMULATION_USE_PARTICLE_LIFETIME = -1,
|
||||
|
||||
/** The simulation's framerate is set to the animation interval specified in director. */
|
||||
SIMULATION_USE_GAME_ANIMATION_INTERVAL = -1,
|
||||
};
|
||||
|
||||
/** Creates an initializes a ParticleSystem from a plist file.
|
||||
|
@ -251,8 +372,25 @@ public:
|
|||
*/
|
||||
static Vector<ParticleSystem*>& getAllParticleSystems();
|
||||
|
||||
protected:
|
||||
bool allocAnimationMem();
|
||||
void deallocAnimationMem();
|
||||
bool _isAnimAllocated;
|
||||
|
||||
bool allocHSVMem();
|
||||
void deallocHSVMem();
|
||||
bool _isHSVAllocated;
|
||||
|
||||
bool allocOpacityFadeInMem();
|
||||
void deallocOpacityFadeInMem();
|
||||
bool _isOpacityFadeInAllocated;
|
||||
|
||||
bool allocScaleInMem();
|
||||
void deallocScaleInMem();
|
||||
bool _isScaleInAllocated;
|
||||
|
||||
public:
|
||||
void addParticles(int count);
|
||||
void addParticles(int count, int animationIndex = -1, int animationCellIndex = -1);
|
||||
|
||||
void stopSystem();
|
||||
/** Kill all living particles.
|
||||
|
@ -658,6 +796,58 @@ public:
|
|||
*/
|
||||
void setEndColorVar(const Color4F& color) { _endColorVar = color; }
|
||||
|
||||
/** Sets wether to use HSV color system.
|
||||
* WARNING: becareful when using HSV with too many particles because it's expensive.
|
||||
*
|
||||
* @param hsv Use HSV color system.
|
||||
*/
|
||||
void useHSV(bool hsv);
|
||||
bool isHSV() { return _isHSVAllocated; };
|
||||
|
||||
/** Gets the hue of each particle.
|
||||
*
|
||||
* @return The hue of each particle.
|
||||
*/
|
||||
float getHue() const { return _hsv.h; }
|
||||
/** Sets the hue of each particle.
|
||||
*
|
||||
* @param hsv The hue color of each particle.
|
||||
*/
|
||||
void setHue(float hue) { _hsv.h = hue; }
|
||||
|
||||
/** Gets the hue variance of each particle.
|
||||
*
|
||||
* @return The hue variance of each particle.
|
||||
*/
|
||||
float getHueVar() const { return _hsvVar.h; }
|
||||
/** Sets the hue variance of each particle.
|
||||
*
|
||||
* @param hsv The hue variance color of each particle.
|
||||
*/
|
||||
void setHueVar(float hue) { _hsvVar.h = hue; }
|
||||
|
||||
/** Gets the HSV color of each particle.
|
||||
*
|
||||
* @return The HSV color of each particle.
|
||||
*/
|
||||
const HSV& getHSV() const { return _hsv; }
|
||||
/** Sets the HSV color of each particle.
|
||||
*
|
||||
* @param hsv The HSV color of each particle.
|
||||
*/
|
||||
void setHSV(const HSV& hsv) { _hsv = hsv; }
|
||||
|
||||
/** Gets the HSV color variance of each particle.
|
||||
*
|
||||
* @return The HSV color variance of each particle.
|
||||
*/
|
||||
const HSV& getHSVVar() const { return _hsvVar; }
|
||||
/** Sets the HSV color variance of each particle.
|
||||
*
|
||||
* @param hsv The HSV color variance of each particle.
|
||||
*/
|
||||
void setHSVVar(const HSV& hsv) { _hsvVar = hsv; }
|
||||
|
||||
/** Gets the start spin of each particle.
|
||||
*
|
||||
* @return The start spin of each particle.
|
||||
|
@ -702,6 +892,88 @@ public:
|
|||
*/
|
||||
void setEndSpinVar(float endSpinVar) { _endSpinVar = endSpinVar; }
|
||||
|
||||
/** Gets the spawn angle of each particle
|
||||
*
|
||||
* @return The angle in degrees of each particle.
|
||||
*/
|
||||
float getSpawnAngle() { return _spawnAngle; }
|
||||
/** Sets the spawn angle of each particle
|
||||
*
|
||||
* @param angle The angle in degrees of each particle.
|
||||
*/
|
||||
void setSpawnAngle(float angle) { _spawnAngle = angle; }
|
||||
|
||||
/** Sets the spawn angle variance of each particle.
|
||||
*
|
||||
* @return The angle variance in degrees of each particle.
|
||||
*/
|
||||
float getSpawnAngleVar() { return _spawnAngleVar; }
|
||||
/** Sets the spawn angle variance of each particle.
|
||||
*
|
||||
* @param angle The angle variance in degrees of each particle.
|
||||
*/
|
||||
void setSpawnAngleVar(float angle) { _spawnAngleVar = angle; }
|
||||
|
||||
/** Gets the spawn opacity fade in time of each particle.
|
||||
* Particles have the ability to spawn while having 0 opacity and gradually start going to 255 opacity with a
|
||||
specified time.
|
||||
|
||||
* @return The spawn opacity fade in time in seconds.
|
||||
*/
|
||||
float getSpawnFadeIn() { return _spawnFadeIn; }
|
||||
/** Sets the spawn opacity fade in time of each particle when it's created.
|
||||
* Particles have the ability to spawn while having 0 opacity and gradually start going to 255 opacity with a
|
||||
* specified time.
|
||||
*
|
||||
* @param time The spawn opacity fade in time in seconds.
|
||||
*/
|
||||
void setSpawnFadeIn(float time);
|
||||
|
||||
/** Gets the spawn opacity fade in time variance of each particle.
|
||||
* Particles have the ability to spawn while having 0 opacity and gradually start going to 255 opacity with a
|
||||
* specified time.
|
||||
*
|
||||
* @return The spawn opacity fade in time variance in seconds.
|
||||
*/
|
||||
float getSpawnFadeInVar() { return _spawnFadeInVar; }
|
||||
/** Sets the spawn opacity fade in time variance of each particle when it's created.
|
||||
* Particles have the ability to spawn while having 0 opacity and gradually start going to 255 opacity with a
|
||||
* specified time.
|
||||
*
|
||||
* @param time The spawn opacity fade in time variance in seconds.
|
||||
*/
|
||||
void setSpawnFadeInVar(float time);
|
||||
|
||||
/** Gets the spawn opacity fade in time of each particle.
|
||||
* Particles have the ability to spawn while having 0.0 size and gradually start going to 1.0 size with a specified
|
||||
* time.
|
||||
*
|
||||
* @return The spawn opacity fade in time in seconds.
|
||||
*/
|
||||
float getSpawnScaleIn() { return _spawnScaleIn; }
|
||||
/** Sets the spawn opacity fade in time of each particle when it's created.
|
||||
* Particles have the ability to spawn while having 0.0 size and gradually start going to 1.0 size with a specified
|
||||
* time.
|
||||
*
|
||||
* @param time The spawn opacity fade in time in seconds.
|
||||
*/
|
||||
void setSpawnScaleIn(float time);
|
||||
|
||||
/** Gets the spawn opacity fade in time variance of each particle.
|
||||
* Particles have the ability to spawn while having 0.0 size and gradually start going to 1.0 size with a specified
|
||||
* time.
|
||||
*
|
||||
* @return The spawn opacity fade in time variance in seconds.
|
||||
*/
|
||||
float getSpawnScaleInVar() { return _spawnScaleInVar; }
|
||||
/** Sets the spawn opacity fade in time variance of each particle when it's created.
|
||||
* Particles have the ability to spawn while having 0.0 size and gradually start going to 1.0 size with a specified
|
||||
* time.
|
||||
*
|
||||
* @param time The spawn opacity fade in time variance in seconds.
|
||||
*/
|
||||
void setSpawnScaleInVar(float time);
|
||||
|
||||
/** Gets the emission rate of the particles.
|
||||
*
|
||||
* @return The emission rate of the particles.
|
||||
|
@ -728,6 +1000,255 @@ public:
|
|||
void setOpacityModifyRGB(bool opacityModifyRGB) override { _opacityModifyRGB = opacityModifyRGB; }
|
||||
bool isOpacityModifyRGB() const override { return _opacityModifyRGB; }
|
||||
|
||||
/** Enables or disables tex coord animations that are set based on particle life. */
|
||||
void setLifeAnimation(bool enabled);
|
||||
|
||||
/** Enables or disables tex coord animations that are set by the emitter randomly when a particle is emitted. */
|
||||
void setEmitterAnimation(bool enabled);
|
||||
|
||||
/** Enables or disables tex coord animations that are used to make particles play a sequence forever until they die
|
||||
*/
|
||||
void setLoopAnimation(bool enabled);
|
||||
|
||||
bool isLifeAnimated() { return _isLifeAnimated; }
|
||||
bool isEmitterAnimated() { return _isEmitterAnimated; }
|
||||
bool isLoopAnimated() { return _isLoopAnimated; }
|
||||
|
||||
/** Gets the total number of indices.
|
||||
*
|
||||
* @return The size of the list holding animation indices.
|
||||
*/
|
||||
int getTotalAnimationIndices() { return _animIndexCount; }
|
||||
|
||||
/** Sets wether to start from first cell and go forwards (normal) or last cell and go backwards (reversed) */
|
||||
void setAnimationReverse(bool reverse) { _isAnimationReversed = reverse; }
|
||||
bool isAnimationReversed() { return _isAnimationReversed; }
|
||||
|
||||
/** Resets the count of indices to 0 and empties the animation index array */
|
||||
void resetAnimationIndices();
|
||||
|
||||
/** Empties the container of animation descriptors */
|
||||
void resetAnimationDescriptors();
|
||||
|
||||
/** Choose what animation descriptors are to be selected at random for particles.
|
||||
* This function should be called after you've inserted/overwritten any animation descriptors.
|
||||
*
|
||||
* @param animations Array of specific indices of animations to play at random
|
||||
*/
|
||||
void setMultiAnimationRandomSpecific(const std::vector<unsigned short>& animations)
|
||||
{
|
||||
_randomAnimations = animations;
|
||||
};
|
||||
|
||||
/** Choose ALL animation descriptors to be selected at random for particles.
|
||||
* This function should be called after you've inserted/overwritten any animation descriptors.
|
||||
*/
|
||||
void setMultiAnimationRandom();
|
||||
|
||||
/** Add all particle animation indices based on cells size and direction spicified using a texture atlas.
|
||||
* will erase the array and add new indices from the atlas.
|
||||
* This function will automatically figure out your atlas cell size and direction for you! thank her later :) */
|
||||
void setAnimationIndicesAtlas();
|
||||
|
||||
/** Add all particle animation indices based on cell size and direction spicified if the method of rendering
|
||||
* preferred is texture atlas. will erase the array and add new indices from the atlas.
|
||||
*
|
||||
* @param unifiedCellSize The size of cell unified.
|
||||
* @param direction What direction is the atlas
|
||||
*/
|
||||
void setAnimationIndicesAtlas(unsigned int unifiedCellSize, TexAnimDir direction = TexAnimDir::HORIZONTAL);
|
||||
|
||||
/** Add a particle animation index based on tex coords spicified using a sprite frame.
|
||||
* The index is automatically incremented on each addition.
|
||||
*
|
||||
* @param frameName SpriteFrame name to search for
|
||||
*
|
||||
* @return Returns true of the index was successfully found and added. Otherwise, false
|
||||
*/
|
||||
bool addAnimationIndex(std::string_view frameName);
|
||||
|
||||
/** Add a particle animation index based on tex coords spicified using a sprite frame.
|
||||
*
|
||||
* @param index Index id to add the frame to or override it with the new frame
|
||||
* @param frameName SpriteFrame name to search for
|
||||
*
|
||||
* @return Returns true of the index was successfully found and added. Otherwise, false
|
||||
*/
|
||||
bool addAnimationIndex(unsigned short index, std::string_view frameName);
|
||||
|
||||
/** Add a particle animation index based on tex coords spicified using a sprite frame.
|
||||
* The index is automatically incremented on each addition.
|
||||
*
|
||||
* @param frame SpriteFrame containting data about tex coords
|
||||
*
|
||||
* @return Returns true of the index was successfully found and added. Otherwise, false
|
||||
*/
|
||||
bool addAnimationIndex(cocos2d::SpriteFrame* frame);
|
||||
|
||||
/** Add a particle animation index based on tex coords spicified using a sprite frame.
|
||||
* you can specify which index you want to override in this function
|
||||
*
|
||||
* @param index Index id to add the frame to or override it with the new frame
|
||||
* @param frame SpriteFrame containting data about tex coords
|
||||
*
|
||||
* @return Returns true of the index was successfully found and added. Otherwise, false
|
||||
*/
|
||||
bool addAnimationIndex(unsigned short index, cocos2d::SpriteFrame* frame);
|
||||
|
||||
/** Add a particle animation index based on tex coords spicified.
|
||||
* you can specify which index you want to override in this function
|
||||
*
|
||||
* @param index Index id to add the frame to or override it with the new rect
|
||||
* @param rect Rect containting data about tex coords in pixels
|
||||
* @param rotated Not implemented.
|
||||
*
|
||||
* @return Returns true of the index was successfully found and added. Otherwise, false
|
||||
*/
|
||||
bool addAnimationIndex(unsigned short index, cocos2d::Rect rect, bool rotated = false);
|
||||
|
||||
/** You can specify what rect is used if an index in an animation descriptor wasn't found.
|
||||
*
|
||||
* @param rect Rect containting data about tex coords in pixels
|
||||
*/
|
||||
void setRectForUndefinedIndices(cocos2d::Rect rect) { _undefinedIndexRect = rect; };
|
||||
|
||||
/** Add a particle animation descriptor with an index.
|
||||
*
|
||||
* @param indexOfDescriptor Index of the animation to be added, adding to the same index will just override the
|
||||
* pervious animation descriptor
|
||||
* @param time length of the animation in seconds
|
||||
* @param timeVariance Time randomly selected for each different particle added on the animation length
|
||||
* @param indices An array of the indicies
|
||||
* @param reverse Should the animation indicies be played backwards? (default: false)
|
||||
*/
|
||||
void setAnimationDescriptor(unsigned short indexOfDescriptor,
|
||||
float time,
|
||||
float timeVariance,
|
||||
const std::vector<unsigned short>& indices,
|
||||
bool reverse = false);
|
||||
|
||||
/** Add a particle animation descriptor with the index 0.
|
||||
*
|
||||
* @param indices An array of the indicies
|
||||
* @param reverse Should the animation indicies be played backwards? (default: false)
|
||||
*/
|
||||
void setAnimationDescriptor(const std::vector<unsigned short>& indices, bool reverse = false)
|
||||
{
|
||||
setAnimationDescriptor(0, 0, 0, indices, reverse);
|
||||
};
|
||||
|
||||
/** Sets wether the animation descriptors should follow the time scale of the system or not.
|
||||
*
|
||||
* @param independent Should the animation descriptor speeds be played independently? (default: false)
|
||||
*/
|
||||
void setAnimationSpeedTimescaleIndependent(bool independent) { _animationTimescaleInd = independent; };
|
||||
bool isAnimationSpeedTimescaleIndependent() { return _animationTimescaleInd; };
|
||||
|
||||
/** Sets wether to use emission shapes for this particle system or not */
|
||||
void setEmissionShapes(bool enabled) { _isEmissionShapes = enabled; }
|
||||
bool isEmissionShapes() { return _isEmissionShapes; }
|
||||
|
||||
/** Resets the count of emission shapes to 0 and empties the emission shapes array */
|
||||
void resetEmissionShapes();
|
||||
|
||||
/** Adds an emission shape to the system.
|
||||
* The index is automatically incremented on each addition.
|
||||
*
|
||||
* @param shape Shape descriptor object.
|
||||
*/
|
||||
void addEmissionShape(EmissionShape shape);
|
||||
|
||||
/** Updates an existing emission shape or adds it.
|
||||
* @param index index of the shape descriptor.
|
||||
* @param shape Shape descriptor object.
|
||||
*/
|
||||
void setEmissionShape(unsigned short index, EmissionShape shape);
|
||||
|
||||
/** Adds an emission shape of type point to the system.
|
||||
* @param pos Position of the emission shape in local space.
|
||||
*/
|
||||
static EmissionShape createPointShape(Vec2 pos);
|
||||
|
||||
/** Adds an emission shape of type Rectangle to the system.
|
||||
* @param pos Position of the emission shape in local space.
|
||||
* @param size Size of the rectangle.
|
||||
*/
|
||||
static EmissionShape createRectShape(Vec2 pos, Size size);
|
||||
|
||||
/** Adds an emission shape of type Rectangular Torus to the system.
|
||||
* @param pos Position of the emission shape in local space.
|
||||
* @param innerSize Inner size offset of the rectangle.
|
||||
* @param outerSize Outer size of the rectangle.
|
||||
*/
|
||||
static EmissionShape createRectTorusShape(Vec2 pos, Size innerSize, Size outerSize);
|
||||
|
||||
/** Adds an emission shape of type Circle to the system.
|
||||
*
|
||||
* The default angle offset of the circle is 0 and the default angle of the circle is 360
|
||||
*
|
||||
* @param pos Position of the emission shape in local space.
|
||||
* @param radius Radius of the circle.
|
||||
* @param edgeBias circle edge center bias value, If the value is greater than 1.0 then particles will bias
|
||||
* towards the edge of the circle more often the greater the value is; If the value is lower than 1.0 then particles
|
||||
* will bias towards the center of the circle more often the closer the value is to 0.0; If the value is exactly 1.0
|
||||
* then there will be no bias behaviour.
|
||||
*/
|
||||
static EmissionShape createCircleShape(Vec2 pos, float radius, float edgeBias = 1.0F);
|
||||
|
||||
/** Adds an emission shape of type Cone to the system.
|
||||
*
|
||||
* The default angle offset of the circle is 0 and the default angle of the circle is 360
|
||||
*
|
||||
* @param pos Position of the emission shape in local space.
|
||||
* @param radius Radius of the circle.
|
||||
* @param offset Cone offset angle in degrees.
|
||||
* @param angle Cone angle in degrees.
|
||||
* @param edgeBias circle edge center bias value, If the value is greater than 1.0 then particles will bias
|
||||
* towards the edge of the circle more often the greater the value is; If the value is lower than 1.0 then particles
|
||||
* will bias towards the center of the circle more often the closer the value is to 0.0; If the value is exactly 1.0
|
||||
* then there will be no bias behaviour.
|
||||
*/
|
||||
static EmissionShape createConeShape(Vec2 pos,
|
||||
float radius,
|
||||
float offset,
|
||||
float angle,
|
||||
float edgeBias = 1.0F);
|
||||
|
||||
/** Adds an emission shape of type Torus to the system.
|
||||
*
|
||||
* The default angle offset of the torus is 0 and the default angle of the torus is 360
|
||||
*
|
||||
* @param pos Position of the emission shape in local space.
|
||||
* @param innerRadius Inner radius offset of the torus.
|
||||
* @param outerRadius Outer radius of the torus.
|
||||
* @param edgeBias torus edge center bias value, If the value is greater than 1.0 then particles will bias
|
||||
* towards the edge of the torus more often the greater the value is; If the value is lower than 1.0 then particles
|
||||
* will bias towards the center of the torus more often the closer the value is to 0.0; If the value is exactly 1.0
|
||||
* then there will be no bias behaviour.
|
||||
*/
|
||||
static EmissionShape createTorusShape(Vec2 pos, float innerRadius, float outerRadius, float edgeBias = 1.0F);
|
||||
|
||||
/** Adds an emission shape of type Torus to the system.
|
||||
*
|
||||
* The default angle offset of the torus is 0 and the default angle of the torus is 360
|
||||
*
|
||||
* @param pos Position of the emission shape in local space.
|
||||
* @param innerRadius Inner radius offset of the torus.
|
||||
* @param outerRadius Outer radius of the torus.
|
||||
* @param offset Cone offset angle in degrees.
|
||||
* @param angle Cone angle in degrees.
|
||||
* @param edgeBias torus edge center bias value, If the value is greater than 1.0 then particles will bias
|
||||
* towards the edge of the torus more often the greater the value is; If the value is lower than 1.0 then particles
|
||||
* will bias towards the center of the torus more often the closer the value is to 0.0; If the value is exactly 1.0
|
||||
* then there will be no bias behaviour.
|
||||
*/
|
||||
static EmissionShape createConeTorusShape(Vec2 pos,
|
||||
float innerRadius,
|
||||
float outerRadius,
|
||||
float offset,
|
||||
float angle,
|
||||
float edgeBias = 1.0F);
|
||||
|
||||
/** Gets the particles movement type: Free or Grouped.
|
||||
@since v0.8
|
||||
*
|
||||
|
@ -741,6 +1262,27 @@ public:
|
|||
*/
|
||||
void setPositionType(PositionType type) { _positionType = type; }
|
||||
|
||||
/** Advance the particle system and make it seem like it ran for this many seconds.
|
||||
*
|
||||
* @param seconds Seconds to advance. value of -1 means (SIMULATION_USE_PARTICLE_LIFETIME)
|
||||
* @param frameRate Frame rate to run the simulation with (preferred: 30.0) The higher this value is the more
|
||||
* accurate the simulation will be at the cost of performance. value of -1 means
|
||||
* (SIMULATION_USE_GAME_ANIMATION_INTERVAL)
|
||||
*/
|
||||
void simulate(float seconds = SIMULATION_USE_PARTICLE_LIFETIME,
|
||||
float frameRate = SIMULATION_USE_GAME_ANIMATION_INTERVAL);
|
||||
|
||||
/** Resets the particle system and then advances the particle system and make it seem like it ran for this many
|
||||
* seconds. The frame rate used for simulation accuracy is the director's animation interval.
|
||||
*
|
||||
* @param seconds Seconds to advance. value of -1 means (SIMULATION_USE_PARTICLE_LIFETIME)
|
||||
* @param frameRate Frame rate to run the simulation with (preferred: 30.0) The higher this value is the more
|
||||
* accurate the simulation will be at the cost of performance. value of -1 means
|
||||
* (SIMULATION_USE_GAME_ANIMATION_INTERVAL)
|
||||
*/
|
||||
void resimulate(float seconds = SIMULATION_USE_PARTICLE_LIFETIME,
|
||||
float frameRate = SIMULATION_USE_GAME_ANIMATION_INTERVAL);
|
||||
|
||||
// Overrides
|
||||
virtual void onEnter() override;
|
||||
virtual void onExit() override;
|
||||
|
@ -812,12 +1354,46 @@ public:
|
|||
*/
|
||||
virtual bool isPaused() const;
|
||||
|
||||
/* Pause the emissions*/
|
||||
/* Pause the emissions */
|
||||
virtual void pauseEmissions();
|
||||
|
||||
/* UnPause the emissions*/
|
||||
/* Unpause the emissions */
|
||||
virtual void resumeEmissions();
|
||||
|
||||
/** Is system update paused
|
||||
@return True if system update is paused, else false
|
||||
*/
|
||||
virtual bool isUpdatePaused() const;
|
||||
|
||||
/* Pause the particles from being updated */
|
||||
virtual void pauseUpdate();
|
||||
|
||||
/* Unpause the particles from being updated */
|
||||
virtual void resumeUpdate();
|
||||
|
||||
/** Gets the fixed frame rate count of the particle system.
|
||||
@return Fixed frame rate count of the particle system.
|
||||
*/
|
||||
virtual float getFixedFPS();
|
||||
|
||||
/** Sets the fixed frame rate count of the particle system.
|
||||
* i.e. if the framerate is set to 30.0 while the refresh rate is greater than 30.0 then the particle system will
|
||||
wait until it hits the 30.0 FPS mark.
|
||||
* This is usefull for increasing performance or for creating old-school effects with it.
|
||||
@param Fixed frame rate count of the particle system. (default: 0.0)
|
||||
*/
|
||||
virtual void setFixedFPS(float frameRate = 0.0F);
|
||||
|
||||
/** Gets the time scale of the particle system.
|
||||
@return Time scale of the particle system.
|
||||
*/
|
||||
virtual float getTimeScale();
|
||||
|
||||
/** Sets the time scale of the particle system.
|
||||
@param Time scale of the particle system. (default: 1.0)
|
||||
*/
|
||||
virtual void setTimeScale(float scale = 1.0F);
|
||||
|
||||
protected:
|
||||
virtual void updateBlendFunc();
|
||||
|
||||
|
@ -957,6 +1533,10 @@ protected:
|
|||
Color4F _endColor;
|
||||
/** end color variance of each particle */
|
||||
Color4F _endColorVar;
|
||||
/** hsv color of each particle */
|
||||
HSV _hsv;
|
||||
/** hsv color variance of each particle */
|
||||
HSV _hsvVar;
|
||||
//* initial angle of each particle
|
||||
float _startSpin;
|
||||
//* initial angle of each particle
|
||||
|
@ -965,6 +1545,18 @@ protected:
|
|||
float _endSpin;
|
||||
//* initial angle of each particle
|
||||
float _endSpinVar;
|
||||
//* initial rotation of each particle
|
||||
float _spawnAngle;
|
||||
//* initial rotation of each particle
|
||||
float _spawnAngleVar;
|
||||
//* initial fade in time of each particle
|
||||
float _spawnFadeIn;
|
||||
//* initial fade in time variance of each particle
|
||||
float _spawnFadeInVar;
|
||||
//* initial scale in time of each particle
|
||||
float _spawnScaleIn;
|
||||
//* initial scale in time variance of each particle
|
||||
float _spawnScaleInVar;
|
||||
/** emission rate of the particles */
|
||||
float _emissionRate;
|
||||
/** maximum particles of the system */
|
||||
|
@ -975,9 +1567,37 @@ protected:
|
|||
BlendFunc _blendFunc;
|
||||
/** does the alpha value modify color */
|
||||
bool _opacityModifyRGB;
|
||||
/** is the particle system animated */
|
||||
bool _isLifeAnimated;
|
||||
/** is the emitter particle system animated */
|
||||
bool _isEmitterAnimated;
|
||||
/** is the emitter particle system animated */
|
||||
bool _isLoopAnimated;
|
||||
/** variable keeping count of sprite frames or atlas indices added */
|
||||
int _animIndexCount;
|
||||
/** wether to start from first or last when using life animation */
|
||||
bool _isAnimationReversed;
|
||||
/** A map that stores particle animation index coords */
|
||||
std::unordered_map<unsigned short, ParticleFrameDescriptor> _animationIndices;
|
||||
/** A map that stores particle animation descriptors */
|
||||
std::unordered_map<unsigned short, ParticleAnimationDescriptor> _animations;
|
||||
/** A vector that stores ids of animation descriptors that are choosen at random */
|
||||
std::vector<unsigned short> _randomAnimations;
|
||||
/** Wether the animation goes with the time scale of the system or is independent. */
|
||||
bool _animationTimescaleInd;
|
||||
/** A rect that is used instead when an index is not found */
|
||||
cocos2d::Rect _undefinedIndexRect;
|
||||
/** does FlippedY variance of each particle */
|
||||
int _yCoordFlipped;
|
||||
|
||||
/** Wether to use emission shapes for this particle system or not */
|
||||
bool _isEmissionShapes;
|
||||
|
||||
/** variable keeping count of emission shapes added */
|
||||
int _emissionShapeIndex;
|
||||
/** A map that stores emission shapes that are choosen at random */
|
||||
std::unordered_map<unsigned short, EmissionShape> _emissionShapes;
|
||||
|
||||
/** particles movement type: Free or Grouped
|
||||
@since v0.8
|
||||
*/
|
||||
|
@ -986,6 +1606,18 @@ protected:
|
|||
/** is the emitter paused */
|
||||
bool _paused;
|
||||
|
||||
/** is particle system update paused */
|
||||
bool _updatePaused;
|
||||
|
||||
/** time scale of the particle system */
|
||||
float _timeScale;
|
||||
|
||||
/** Fixed frame rate of the particle system */
|
||||
float _fixedFPS;
|
||||
|
||||
/** Fixed frame rate delta (internal) */
|
||||
float _fixedFPSDelta;
|
||||
|
||||
/** is sourcePosition compatible */
|
||||
bool _sourcePositionCompatible;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ THE SOFTWARE.
|
|||
#include "base/ccUTF8.h"
|
||||
#include "renderer/ccShaders.h"
|
||||
#include "renderer/backend/ProgramState.h"
|
||||
#include "2d/CCTweenFunction.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -105,6 +106,10 @@ ParticleSystemQuad* ParticleSystemQuad::create(std::string_view filename)
|
|||
|
||||
ParticleSystemQuad* ParticleSystemQuad::createWithTotalParticles(int numberOfParticles)
|
||||
{
|
||||
CCASSERT(numberOfParticles <= 10000,
|
||||
"Adding more than 10000 particles will crash the renderer, the mesh generated has an index format of "
|
||||
"U_SHORT (uint16_t)");
|
||||
|
||||
ParticleSystemQuad* ret = new ParticleSystemQuad();
|
||||
if (ret->initWithTotalParticles(numberOfParticles))
|
||||
{
|
||||
|
@ -273,19 +278,24 @@ void ParticleSystemQuad::initIndices()
|
|||
}
|
||||
}
|
||||
|
||||
inline void updatePosWithParticle(V3F_C4B_T2F_Quad* quad, const Vec2& newPosition, float size, float rotation)
|
||||
inline void updatePosWithParticle(V3F_C4B_T2F_Quad* quad,
|
||||
const Vec2& newPosition,
|
||||
float size,
|
||||
float scaleInSize,
|
||||
float rotation,
|
||||
float staticRotation)
|
||||
{
|
||||
// vertices
|
||||
float size_2 = size / 2;
|
||||
float x1 = -size_2;
|
||||
float y1 = -size_2;
|
||||
float x1 = -size_2 * scaleInSize;
|
||||
float y1 = -size_2 * scaleInSize;
|
||||
|
||||
float x2 = size_2;
|
||||
float y2 = size_2;
|
||||
float x2 = size_2 * scaleInSize;
|
||||
float y2 = size_2 * scaleInSize;
|
||||
float x = newPosition.x;
|
||||
float y = newPosition.y;
|
||||
|
||||
float r = (float)-CC_DEGREES_TO_RADIANS(rotation);
|
||||
float r = (float)-CC_DEGREES_TO_RADIANS(rotation + staticRotation);
|
||||
float cr = cosf(r);
|
||||
float sr = sinf(r);
|
||||
float ax = x1 * cr - y1 * sr + x;
|
||||
|
@ -357,16 +367,36 @@ void ParticleSystemQuad::updateParticleQuads()
|
|||
float* y = _particleData.posy;
|
||||
float* s = _particleData.size;
|
||||
float* r = _particleData.rotation;
|
||||
float* sr = _particleData.staticRotation;
|
||||
float* sid = _particleData.scaleInDelta;
|
||||
float* sil = _particleData.scaleInLength;
|
||||
V3F_C4B_T2F_Quad* quadStart = startQuad;
|
||||
for (int i = 0; i < _particleCount; ++i, ++startX, ++startY, ++x, ++y, ++quadStart, ++s, ++r)
|
||||
if (_isScaleInAllocated)
|
||||
{
|
||||
p2.set(*startX, *startY, 0);
|
||||
worldToNodeTM.transformPoint(&p2);
|
||||
newPos.set(*x, *y);
|
||||
p2 = p1 - p2;
|
||||
newPos.x -= p2.x - pos.x;
|
||||
newPos.y -= p2.y - pos.y;
|
||||
updatePosWithParticle(quadStart, newPos, *s, *r);
|
||||
for (int i = 0; i < _particleCount;
|
||||
++i, ++startX, ++startY, ++x, ++y, ++quadStart, ++s, ++r, ++sr, ++sid, ++sil)
|
||||
{
|
||||
p2.set(*startX, *startY, 0);
|
||||
worldToNodeTM.transformPoint(&p2);
|
||||
newPos.set(*x, *y);
|
||||
p2 = p1 - p2;
|
||||
newPos.x -= p2.x - pos.x;
|
||||
newPos.y -= p2.y - pos.y;
|
||||
updatePosWithParticle(quadStart, newPos, *s, tweenfunc::expoEaseOut(*sid / *sil), *r, *sr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < _particleCount; ++i, ++startX, ++startY, ++x, ++y, ++quadStart, ++s, ++r, ++sr)
|
||||
{
|
||||
p2.set(*startX, *startY, 0);
|
||||
worldToNodeTM.transformPoint(&p2);
|
||||
newPos.set(*x, *y);
|
||||
p2 = p1 - p2;
|
||||
newPos.x -= p2.x - pos.x;
|
||||
newPos.y -= p2.y - pos.y;
|
||||
updatePosWithParticle(quadStart, newPos, *s, 1.0F, *r, *sr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_positionType == PositionType::RELATIVE)
|
||||
|
@ -378,14 +408,32 @@ void ParticleSystemQuad::updateParticleQuads()
|
|||
float* y = _particleData.posy;
|
||||
float* s = _particleData.size;
|
||||
float* r = _particleData.rotation;
|
||||
float* sr = _particleData.staticRotation;
|
||||
float* sid = _particleData.scaleInDelta;
|
||||
float* sil = _particleData.scaleInLength;
|
||||
V3F_C4B_T2F_Quad* quadStart = startQuad;
|
||||
for (int i = 0; i < _particleCount; ++i, ++startX, ++startY, ++x, ++y, ++quadStart, ++s, ++r)
|
||||
if (_isScaleInAllocated)
|
||||
{
|
||||
newPos.set(*x, *y);
|
||||
newPos.x = *x - (currentPosition.x - *startX);
|
||||
newPos.y = *y - (currentPosition.y - *startY);
|
||||
newPos += pos;
|
||||
updatePosWithParticle(quadStart, newPos, *s, *r);
|
||||
for (int i = 0; i < _particleCount;
|
||||
++i, ++startX, ++startY, ++x, ++y, ++quadStart, ++s, ++r, ++sr, ++sid, ++sil)
|
||||
{
|
||||
newPos.set(*x, *y);
|
||||
newPos.x = *x - (currentPosition.x - *startX);
|
||||
newPos.y = *y - (currentPosition.y - *startY);
|
||||
newPos += pos;
|
||||
updatePosWithParticle(quadStart, newPos, *s, tweenfunc::expoEaseOut(*sid / *sil), *r, *sr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < _particleCount; ++i, ++startX, ++startY, ++x, ++y, ++quadStart, ++s, ++r, ++sr)
|
||||
{
|
||||
newPos.set(*x, *y);
|
||||
newPos.x = *x - (currentPosition.x - *startX);
|
||||
newPos.y = *y - (currentPosition.y - *startY);
|
||||
newPos += pos;
|
||||
updatePosWithParticle(quadStart, newPos, *s, 1.0F, *r, *sr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -397,53 +445,259 @@ void ParticleSystemQuad::updateParticleQuads()
|
|||
float* y = _particleData.posy;
|
||||
float* s = _particleData.size;
|
||||
float* r = _particleData.rotation;
|
||||
float* sr = _particleData.staticRotation;
|
||||
float* sid = _particleData.scaleInDelta;
|
||||
float* sil = _particleData.scaleInLength;
|
||||
V3F_C4B_T2F_Quad* quadStart = startQuad;
|
||||
for (int i = 0; i < _particleCount; ++i, ++startX, ++startY, ++x, ++y, ++quadStart, ++s, ++r)
|
||||
if (_isScaleInAllocated)
|
||||
{
|
||||
newPos.set(*x + pos.x, *y + pos.y);
|
||||
updatePosWithParticle(quadStart, newPos, *s, *r);
|
||||
for (int i = 0; i < _particleCount;
|
||||
++i, ++startX, ++startY, ++x, ++y, ++quadStart, ++s, ++r, ++sr, ++sid, ++sil)
|
||||
{
|
||||
newPos.set(*x + pos.x, *y + pos.y);
|
||||
updatePosWithParticle(quadStart, newPos, *s, tweenfunc::expoEaseOut(*sid / *sil), *r, *sr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < _particleCount; ++i, ++startX, ++startY, ++x, ++y, ++quadStart, ++s, ++r, ++sr)
|
||||
{
|
||||
newPos.set(*x + pos.x, *y + pos.y);
|
||||
updatePosWithParticle(quadStart, newPos, *s, 1.0F, *r, *sr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set color
|
||||
if (_opacityModifyRGB)
|
||||
{
|
||||
V3F_C4B_T2F_Quad* quad = startQuad;
|
||||
float* r = _particleData.colorR;
|
||||
float* g = _particleData.colorG;
|
||||
float* b = _particleData.colorB;
|
||||
float* a = _particleData.colorA;
|
||||
V3F_C4B_T2F_Quad* quad = startQuad;
|
||||
float* r = _particleData.colorR;
|
||||
float* g = _particleData.colorG;
|
||||
float* b = _particleData.colorB;
|
||||
float* a = _particleData.colorA;
|
||||
|
||||
for (int i = 0; i < _particleCount; ++i, ++quad, ++r, ++g, ++b, ++a)
|
||||
if (_isOpacityFadeInAllocated)
|
||||
{
|
||||
float* fadeDt = _particleData.opacityFadeInDelta;
|
||||
float* fadeLn = _particleData.opacityFadeInLength;
|
||||
|
||||
// HSV calculation is expensive, so we should skip it if it's not enabled.
|
||||
if (_isHSVAllocated)
|
||||
{
|
||||
uint8_t colorR = *r * *a * 255;
|
||||
uint8_t colorG = *g * *a * 255;
|
||||
uint8_t colorB = *b * *a * 255;
|
||||
uint8_t colorA = *a * 255;
|
||||
quad->bl.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->br.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->tl.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->tr.colors.set(colorR, colorG, colorB, colorA);
|
||||
float* hue = _particleData.hue;
|
||||
float* sat = _particleData.sat;
|
||||
float* val = _particleData.val;
|
||||
|
||||
if (_opacityModifyRGB)
|
||||
{
|
||||
auto hsv = HSV();
|
||||
for (int i = 0; i < _particleCount;
|
||||
++i, ++quad, ++r, ++g, ++b, ++a, ++hue, ++sat, ++val, ++fadeDt, ++fadeLn)
|
||||
{
|
||||
float colorR = *r;
|
||||
float colorG = *g;
|
||||
float colorB = *b;
|
||||
float colorA = *a * (*fadeDt / *fadeLn);
|
||||
hsv.set(colorR, colorG, colorB, colorA);
|
||||
hsv.h += *hue;
|
||||
hsv.s = abs(*sat);
|
||||
hsv.v = abs(*val);
|
||||
auto colF = hsv.toColor4F();
|
||||
quad->bl.colors.set(colF.r * colF.a * 255.0F, colF.g * colF.a * 255.0F, colF.b * colF.a * 255.0F,
|
||||
colF.a * 255.0F);
|
||||
quad->br.colors.set(colF.r * colF.a * 255.0F, colF.g * colF.a * 255.0F, colF.b * colF.a * 255.0F,
|
||||
colF.a * 255.0F);
|
||||
quad->tl.colors.set(colF.r * colF.a * 255.0F, colF.g * colF.a * 255.0F, colF.b * colF.a * 255.0F,
|
||||
colF.a * 255.0F);
|
||||
quad->tr.colors.set(colF.r * colF.a * 255.0F, colF.g * colF.a * 255.0F, colF.b * colF.a * 255.0F,
|
||||
colF.a * 255.0F);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto hsv = HSV();
|
||||
for (int i = 0; i < _particleCount;
|
||||
++i, ++quad, ++r, ++g, ++b, ++a, ++hue, ++sat, ++val, ++fadeDt, ++fadeLn)
|
||||
{
|
||||
float colorR = *r;
|
||||
float colorG = *g;
|
||||
float colorB = *b;
|
||||
float colorA = *a * (*fadeDt / *fadeLn);
|
||||
hsv.set(colorR, colorG, colorB, colorA);
|
||||
hsv.h += *hue;
|
||||
hsv.s = abs(*sat);
|
||||
hsv.v = abs(*val);
|
||||
auto col = hsv.toColor4B();
|
||||
quad->bl.colors.set(col.r, col.g, col.b, col.a);
|
||||
quad->br.colors.set(col.r, col.g, col.b, col.a);
|
||||
quad->tl.colors.set(col.r, col.g, col.b, col.a);
|
||||
quad->tr.colors.set(col.r, col.g, col.b, col.a);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// set color
|
||||
if (_opacityModifyRGB)
|
||||
{
|
||||
for (int i = 0; i < _particleCount; ++i, ++quad, ++r, ++g, ++b, ++a, ++fadeDt, ++fadeLn)
|
||||
{
|
||||
uint8_t colorR = *r * *a * 255;
|
||||
uint8_t colorG = *g * *a * 255;
|
||||
uint8_t colorB = *b * *a * 255;
|
||||
uint8_t colorA = *a * (*fadeDt / *fadeLn) * 255;
|
||||
quad->bl.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->br.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->tl.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->tr.colors.set(colorR, colorG, colorB, colorA);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < _particleCount; ++i, ++quad, ++r, ++g, ++b, ++a, ++fadeDt, ++fadeLn)
|
||||
{
|
||||
uint8_t colorR = *r * 255;
|
||||
uint8_t colorG = *g * 255;
|
||||
uint8_t colorB = *b * 255;
|
||||
uint8_t colorA = *a * (*fadeDt / *fadeLn) * 255;
|
||||
quad->bl.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->br.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->tl.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->tr.colors.set(colorR, colorG, colorB, colorA);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
V3F_C4B_T2F_Quad* quad = startQuad;
|
||||
float* r = _particleData.colorR;
|
||||
float* g = _particleData.colorG;
|
||||
float* b = _particleData.colorB;
|
||||
float* a = _particleData.colorA;
|
||||
|
||||
for (int i = 0; i < _particleCount; ++i, ++quad, ++r, ++g, ++b, ++a)
|
||||
// HSV calculation is expensive, so we should skip it if it's not enabled.
|
||||
if (_isHSVAllocated)
|
||||
{
|
||||
uint8_t colorR = *r * 255;
|
||||
uint8_t colorG = *g * 255;
|
||||
uint8_t colorB = *b * 255;
|
||||
uint8_t colorA = *a * 255;
|
||||
quad->bl.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->br.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->tl.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->tr.colors.set(colorR, colorG, colorB, colorA);
|
||||
float* hue = _particleData.hue;
|
||||
float* sat = _particleData.sat;
|
||||
float* val = _particleData.val;
|
||||
|
||||
if (_opacityModifyRGB)
|
||||
{
|
||||
auto hsv = HSV();
|
||||
for (int i = 0; i < _particleCount; ++i, ++quad, ++r, ++g, ++b, ++a, ++hue, ++sat, ++val)
|
||||
{
|
||||
float colorR = *r;
|
||||
float colorG = *g;
|
||||
float colorB = *b;
|
||||
float colorA = *a;
|
||||
hsv.set(colorR, colorG, colorB, colorA);
|
||||
hsv.h += *hue;
|
||||
hsv.s = abs(*sat);
|
||||
hsv.v = abs(*val);
|
||||
auto colF = hsv.toColor4F();
|
||||
quad->bl.colors.set(colF.r * colF.a * 255.0F, colF.g * colF.a * 255.0F, colF.b * colF.a * 255.0F,
|
||||
colF.a * 255.0F);
|
||||
quad->br.colors.set(colF.r * colF.a * 255.0F, colF.g * colF.a * 255.0F, colF.b * colF.a * 255.0F,
|
||||
colF.a * 255.0F);
|
||||
quad->tl.colors.set(colF.r * colF.a * 255.0F, colF.g * colF.a * 255.0F, colF.b * colF.a * 255.0F,
|
||||
colF.a * 255.0F);
|
||||
quad->tr.colors.set(colF.r * colF.a * 255.0F, colF.g * colF.a * 255.0F, colF.b * colF.a * 255.0F,
|
||||
colF.a * 255.0F);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto hsv = HSV();
|
||||
for (int i = 0; i < _particleCount; ++i, ++quad, ++r, ++g, ++b, ++a, ++hue, ++sat, ++val)
|
||||
{
|
||||
float colorR = *r;
|
||||
float colorG = *g;
|
||||
float colorB = *b;
|
||||
float colorA = *a;
|
||||
hsv.set(colorR, colorG, colorB, colorA);
|
||||
hsv.h += *hue;
|
||||
hsv.s = abs(*sat);
|
||||
hsv.v = abs(*val);
|
||||
auto col = hsv.toColor4B();
|
||||
quad->bl.colors.set(col.r, col.g, col.b, col.a);
|
||||
quad->br.colors.set(col.r, col.g, col.b, col.a);
|
||||
quad->tl.colors.set(col.r, col.g, col.b, col.a);
|
||||
quad->tr.colors.set(col.r, col.g, col.b, col.a);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// set color
|
||||
if (_opacityModifyRGB)
|
||||
{
|
||||
for (int i = 0; i < _particleCount; ++i, ++quad, ++r, ++g, ++b, ++a)
|
||||
{
|
||||
uint8_t colorR = *r * *a * 255;
|
||||
uint8_t colorG = *g * *a * 255;
|
||||
uint8_t colorB = *b * *a * 255;
|
||||
uint8_t colorA = *a * 255;
|
||||
quad->bl.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->br.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->tl.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->tr.colors.set(colorR, colorG, colorB, colorA);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < _particleCount; ++i, ++quad, ++r, ++g, ++b, ++a)
|
||||
{
|
||||
uint8_t colorR = *r * 255;
|
||||
uint8_t colorG = *g * 255;
|
||||
uint8_t colorB = *b * 255;
|
||||
uint8_t colorA = *a * 255;
|
||||
quad->bl.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->br.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->tl.colors.set(colorR, colorG, colorB, colorA);
|
||||
quad->tr.colors.set(colorR, colorG, colorB, colorA);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The reason for using for-loops separately for every property is because
|
||||
// When the processor needs to read from or write to a location in memory,
|
||||
// it first checks whether a copy of that data is in the cpu's cache.
|
||||
// And wether if every property's memory of the particle system is continuous,
|
||||
// for the purpose of improving cache hit rate, we should process only one property in one for-loop.
|
||||
// It was proved to be effective especially for low-end devices.
|
||||
if (_isLifeAnimated || _isEmitterAnimated || _isLoopAnimated || _isAnimAllocated)
|
||||
{
|
||||
V3F_C4B_T2F_Quad* quad = startQuad;
|
||||
unsigned short* cellIndex = _particleData.animCellIndex;
|
||||
|
||||
ParticleFrameDescriptor index;
|
||||
for (int i = 0; i < _particleCount; ++i, ++quad, ++cellIndex)
|
||||
{
|
||||
float left = 0.0F, bottom = 0.0F, top = 1.0F, right = 1.0F;
|
||||
|
||||
// TODO: index.isRotated should be treated accordingly
|
||||
|
||||
auto iter = _animationIndices.find(*cellIndex);
|
||||
if (iter == _animationIndices.end())
|
||||
index.rect = {0, 0, float(_texture->getPixelsWide()), float(_texture->getPixelsHigh())};
|
||||
else
|
||||
index = iter->second;
|
||||
|
||||
auto texWidth = _texture->getPixelsWide();
|
||||
auto texHeight = _texture->getPixelsHigh();
|
||||
|
||||
left = index.rect.origin.x / texWidth;
|
||||
right = (index.rect.origin.x + index.rect.size.x) / texWidth;
|
||||
|
||||
top = index.rect.origin.y / texHeight;
|
||||
bottom = (index.rect.origin.y + index.rect.size.y) / texHeight;
|
||||
|
||||
quad->bl.texCoords.u = left;
|
||||
quad->bl.texCoords.v = bottom;
|
||||
|
||||
quad->br.texCoords.u = right;
|
||||
quad->br.texCoords.v = bottom;
|
||||
|
||||
quad->tl.texCoords.u = left;
|
||||
quad->tl.texCoords.v = top;
|
||||
|
||||
quad->tr.texCoords.u = right;
|
||||
quad->tr.texCoords.v = top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ void log(const char* format, ...)
|
|||
va_end(args);
|
||||
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
|
||||
__android_log_print(ANDROID_LOG_DEBUG, "adxe debug info", "%s", buf.c_str());
|
||||
__android_log_print(ANDROID_LOG_DEBUG, "cocos2d-x debug info", "%s", buf.c_str());
|
||||
|
||||
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
||||
buf.push_back('\n');
|
||||
|
|
|
@ -210,7 +210,7 @@ Value& Value::operator=(Value&& other)
|
|||
switch (other.getTypeFamily())
|
||||
{
|
||||
case Type::INTEGER:
|
||||
_field.uint64Val = other._field.uint64Val;
|
||||
_field.uintVal = other._field.uintVal;
|
||||
break;
|
||||
case Type::FLOAT:
|
||||
_field.floatVal = other._field.floatVal;
|
||||
|
|
|
@ -405,7 +405,7 @@ std::string getDataMD5Hash(const Data& data)
|
|||
return computeDigest(std::string_view{(const char*)data.getBytes(), (size_t)data.getSize()}, "md5"sv);
|
||||
}
|
||||
|
||||
std::string computeDigest(std::string_view data, std::string_view algorithm)
|
||||
CC_DLL std::string computeDigest(std::string_view data, std::string_view algorithm)
|
||||
{
|
||||
const EVP_MD* md = nullptr;
|
||||
unsigned char mdValue[EVP_MAX_MD_SIZE] = {0};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2015-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
Copyright (c) 2021-2022 Bytedance Inc.
|
||||
Copyright (c) 2021 Bytedance Inc.
|
||||
|
||||
https://adxeproject.github.io/
|
||||
|
||||
|
@ -206,8 +206,7 @@ public:
|
|||
_cancelled = true;
|
||||
if (this->_sockfd != -1)
|
||||
{
|
||||
if(::shutdown(this->_sockfd, SD_BOTH) == -1) // may cause curl CURLE_SEND_ERROR(55) or CURLE_RECV_ERROR(56)
|
||||
::closesocket(this->_sockfd);
|
||||
::shutdown(this->_sockfd, SD_BOTH); // may cause curl CURLE_SEND_ERROR(55) or CURLE_RECV_ERROR(56)
|
||||
this->_sockfd = -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ THE SOFTWARE.
|
|||
#include "base/ccMacros.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "platform/CCSAXParser.h"
|
||||
//#include "base/ccUtils.h"
|
||||
#include "platform/CCPosixFileStream.h"
|
||||
|
||||
#ifdef MINIZIP_FROM_SYSTEM
|
||||
|
@ -49,19 +50,19 @@ THE SOFTWARE.
|
|||
# include "yasio/cxx17/string_view.hpp"
|
||||
#endif
|
||||
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
|
||||
# include "tinydir/tinydir.h"
|
||||
#endif
|
||||
|
||||
#include "pugixml/pugixml.hpp"
|
||||
|
||||
#define DECLARE_GUARD (void)0
|
||||
|
||||
#if CC_TARGET_PLATFORM != CC_PLATFORM_IOS && \
|
||||
(CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID || (defined(__NDK_MAJOR__) && __NDK_MAJOR__ >= 22))
|
||||
# define ADXE_HAVE_STDFS 1
|
||||
# include <filesystem>
|
||||
namespace stdfs = std::filesystem;
|
||||
#else
|
||||
#include "ghc/filesystem.hpp"
|
||||
namespace stdfs = ghc::filesystem;
|
||||
#endif
|
||||
|
||||
# if defined(_WIN32)
|
||||
inline stdfs::path toFspath(const std::string_view& pathSV)
|
||||
{
|
||||
|
@ -73,6 +74,10 @@ inline stdfs::path toFspath(const std::string_view& pathSV)
|
|||
return stdfs::path{pathSV};
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
# include "tinydir/tinydir.h"
|
||||
# define ADXE_HAVE_STDFS 0
|
||||
#endif
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -158,7 +163,7 @@ public:
|
|||
void startElement(void* ctx, const char* name, const char** atts) override
|
||||
{
|
||||
const std::string sName(name);
|
||||
if (sName == "dict"sv)
|
||||
if (sName == "dict")
|
||||
{
|
||||
if (_resultType == SAX_RESULT_DICT && _rootDict.empty())
|
||||
{
|
||||
|
@ -192,23 +197,23 @@ public:
|
|||
_stateStack.push(_state);
|
||||
_dictStack.push(_curDict);
|
||||
}
|
||||
else if (sName == "key"sv)
|
||||
else if (sName == "key")
|
||||
{
|
||||
_state = SAX_KEY;
|
||||
}
|
||||
else if (sName == "integer"sv)
|
||||
else if (sName == "integer")
|
||||
{
|
||||
_state = SAX_INT;
|
||||
}
|
||||
else if (sName == "real"sv)
|
||||
else if (sName == "real")
|
||||
{
|
||||
_state = SAX_REAL;
|
||||
}
|
||||
else if (sName == "string"sv)
|
||||
else if (sName == "string")
|
||||
{
|
||||
_state = SAX_STRING;
|
||||
}
|
||||
else if (sName == "array"sv)
|
||||
else if (sName == "array")
|
||||
{
|
||||
_state = SAX_ARRAY;
|
||||
|
||||
|
@ -248,7 +253,7 @@ public:
|
|||
{
|
||||
SAXState curState = _stateStack.empty() ? SAX_DICT : _stateStack.top();
|
||||
const std::string sName((char*)name);
|
||||
if (sName == "dict"sv)
|
||||
if (sName == "dict")
|
||||
{
|
||||
_stateStack.pop();
|
||||
_dictStack.pop();
|
||||
|
@ -257,7 +262,7 @@ public:
|
|||
_curDict = _dictStack.top();
|
||||
}
|
||||
}
|
||||
else if (sName == "array"sv)
|
||||
else if (sName == "array")
|
||||
{
|
||||
_stateStack.pop();
|
||||
_arrayStack.pop();
|
||||
|
@ -266,7 +271,7 @@ public:
|
|||
_curArray = _arrayStack.top();
|
||||
}
|
||||
}
|
||||
else if (sName == "true"sv)
|
||||
else if (sName == "true")
|
||||
{
|
||||
if (SAX_ARRAY == curState)
|
||||
{
|
||||
|
@ -277,7 +282,7 @@ public:
|
|||
(*_curDict)[_curKey] = Value(true);
|
||||
}
|
||||
}
|
||||
else if (sName == "false"sv)
|
||||
else if (sName == "false")
|
||||
{
|
||||
if (SAX_ARRAY == curState)
|
||||
{
|
||||
|
@ -288,22 +293,22 @@ public:
|
|||
(*_curDict)[_curKey] = Value(false);
|
||||
}
|
||||
}
|
||||
else if (sName == "string"sv || sName == "integer"sv || sName == "real"sv)
|
||||
else if (sName == "string" || sName == "integer" || sName == "real")
|
||||
{
|
||||
if (SAX_ARRAY == curState)
|
||||
{
|
||||
if (sName == "string"sv)
|
||||
if (sName == "string")
|
||||
_curArray->push_back(Value(_curValue));
|
||||
else if (sName == "integer"sv)
|
||||
else if (sName == "integer")
|
||||
_curArray->push_back(Value(atoi(_curValue.c_str())));
|
||||
else
|
||||
_curArray->push_back(Value(std::atof(_curValue.c_str())));
|
||||
}
|
||||
else if (SAX_DICT == curState)
|
||||
{
|
||||
if (sName == "string"sv)
|
||||
if (sName == "string")
|
||||
(*_curDict)[_curKey] = Value(_curValue);
|
||||
else if (sName == "integer"sv)
|
||||
else if (sName == "integer")
|
||||
(*_curDict)[_curKey] = Value(atoi(_curValue.c_str()));
|
||||
else
|
||||
(*_curDict)[_curKey] = Value(std::atof(_curValue.c_str()));
|
||||
|
@ -418,25 +423,25 @@ static void generateElementForObject(const Value& value, pugi::xml_node& parent)
|
|||
// object is String
|
||||
if (value.getType() == Value::Type::STRING)
|
||||
{
|
||||
auto node = parent.append_child("string"sv);
|
||||
node.append_child(pugi::xml_node_type::node_pcdata).set_value(value.asString());
|
||||
auto node = parent.append_child("string");
|
||||
node.append_child(pugi::xml_node_type::node_pcdata).set_value(value.asString().c_str());
|
||||
}
|
||||
// object is integer
|
||||
else if (value.getType() == Value::Type::INTEGER)
|
||||
{
|
||||
auto node = parent.append_child("integer"sv);
|
||||
node.append_child(pugi::xml_node_type::node_pcdata).set_value(value.asString());
|
||||
auto node = parent.append_child("integer");
|
||||
node.append_child(pugi::xml_node_type::node_pcdata).set_value(value.asString().c_str());
|
||||
}
|
||||
// object is real
|
||||
else if (value.getType() == Value::Type::FLOAT || value.getType() == Value::Type::DOUBLE)
|
||||
{
|
||||
auto node = parent.append_child("real"sv);
|
||||
node.append_child(pugi::xml_node_type::node_pcdata).set_value(value.asString());
|
||||
auto node = parent.append_child("real");
|
||||
node.append_child(pugi::xml_node_type::node_pcdata).set_value(value.asString().c_str());
|
||||
}
|
||||
// object is bool
|
||||
else if (value.getType() == Value::Type::BOOLEAN)
|
||||
{
|
||||
parent.append_child(value.asString());
|
||||
parent.append_child(value.asString().c_str());
|
||||
}
|
||||
// object is Array
|
||||
else if (value.getType() == Value::Type::VECTOR)
|
||||
|
@ -448,11 +453,11 @@ static void generateElementForObject(const Value& value, pugi::xml_node& parent)
|
|||
|
||||
static void generateElementForDict(const ValueMap& dict, pugi::xml_node& parent)
|
||||
{
|
||||
auto dictDS = parent.append_child("dict"sv);
|
||||
auto dictDS = parent.append_child("dict");
|
||||
for (const auto& iter : dict)
|
||||
{
|
||||
auto key = dictDS.append_child("key"sv);
|
||||
key.append_child(pugi::xml_node_type::node_pcdata).set_value(iter.first);
|
||||
auto key = dictDS.append_child("key");
|
||||
key.append_child(pugi::xml_node_type::node_pcdata).set_value(iter.first.c_str());
|
||||
|
||||
generateElementForObject(iter.second, dictDS);
|
||||
}
|
||||
|
@ -460,7 +465,7 @@ static void generateElementForDict(const ValueMap& dict, pugi::xml_node& parent)
|
|||
|
||||
static void generateElementForArray(const ValueVector& array, pugi::xml_node& parent)
|
||||
{
|
||||
auto arrayDS = parent.append_child("array"sv);
|
||||
auto arrayDS = parent.append_child("array");
|
||||
for (const auto& value : array)
|
||||
{
|
||||
generateElementForObject(value, arrayDS);
|
||||
|
@ -641,6 +646,26 @@ void FileUtils::writeValueVectorToFile(ValueVector vecData,
|
|||
std::move(callback), std::move(vecData));
|
||||
}
|
||||
|
||||
std::string FileUtils::getNewFilename(std::string_view filename) const
|
||||
{
|
||||
std::string newFileName;
|
||||
|
||||
DECLARE_GUARD;
|
||||
|
||||
// in Lookup Filename dictionary ?
|
||||
auto iter = _filenameLookupDict.find(filename);
|
||||
|
||||
if (iter == _filenameLookupDict.end())
|
||||
{
|
||||
newFileName = filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
newFileName = iter->second.asString();
|
||||
}
|
||||
return newFileName;
|
||||
}
|
||||
|
||||
std::string FileUtils::getPathForFilename(std::string_view filename,
|
||||
std::string_view resolutionDirectory,
|
||||
std::string_view searchPath) const
|
||||
|
@ -699,13 +724,16 @@ std::string FileUtils::fullPathForFilename(std::string_view filename) const
|
|||
return cacheIter->second;
|
||||
}
|
||||
|
||||
// Get the new file name.
|
||||
const std::string newFilename(getNewFilename(filename));
|
||||
|
||||
std::string fullpath;
|
||||
|
||||
for (const auto& searchIt : _searchPathArray)
|
||||
{
|
||||
for (const auto& resolutionIt : _searchResolutionsOrderArray)
|
||||
{
|
||||
fullpath = this->getPathForFilename(filename, resolutionIt, searchIt);
|
||||
fullpath = this->getPathForFilename(newFilename, resolutionIt, searchIt);
|
||||
|
||||
if (!fullpath.empty())
|
||||
{
|
||||
|
@ -753,11 +781,13 @@ std::string FileUtils::fullPathForDirectory(std::string_view dir) const
|
|||
longdir += "/";
|
||||
}
|
||||
|
||||
const std::string newdirname(getNewFilename(longdir));
|
||||
|
||||
for (const auto& searchIt : _searchPathArray)
|
||||
{
|
||||
for (const auto& resolutionIt : _searchResolutionsOrderArray)
|
||||
{
|
||||
fullpath = this->getPathForDirectory(longdir, resolutionIt, searchIt);
|
||||
fullpath = this->getPathForDirectory(newdirname, resolutionIt, searchIt);
|
||||
if (!fullpath.empty() && isDirectoryExistInternal(fullpath))
|
||||
{
|
||||
// Using the filename passed in as key.
|
||||
|
@ -778,7 +808,7 @@ std::string FileUtils::fullPathForDirectory(std::string_view dir) const
|
|||
|
||||
std::string FileUtils::fullPathFromRelativeFile(std::string_view filename, std::string_view relativeFile) const
|
||||
{
|
||||
return std::string{relativeFile.substr(0, relativeFile.rfind('/') + 1)}.append(filename);
|
||||
return std::string{relativeFile.substr(0, relativeFile.rfind('/') + 1)}.append(getNewFilename(filename));
|
||||
}
|
||||
|
||||
void FileUtils::setSearchResolutionsOrder(const std::vector<std::string>& searchResolutionsOrder)
|
||||
|
@ -947,6 +977,35 @@ void FileUtils::addSearchPath(std::string_view searchpath, const bool front)
|
|||
}
|
||||
}
|
||||
|
||||
void FileUtils::setFilenameLookupDictionary(const ValueMap& filenameLookupDict)
|
||||
{
|
||||
DECLARE_GUARD;
|
||||
_fullPathCache.clear();
|
||||
_fullPathCacheDir.clear();
|
||||
_filenameLookupDict = filenameLookupDict;
|
||||
}
|
||||
|
||||
void FileUtils::loadFilenameLookupDictionaryFromFile(std::string_view filename)
|
||||
{
|
||||
const std::string fullPath = fullPathForFilename(filename);
|
||||
if (!fullPath.empty())
|
||||
{
|
||||
ValueMap dict = getValueMapFromFile(fullPath);
|
||||
if (!dict.empty())
|
||||
{
|
||||
ValueMap& metadata = dict["metadata"].asValueMap();
|
||||
int version = metadata["version"].asInt();
|
||||
if (version != 1)
|
||||
{
|
||||
CCLOG("cocos2d: ERROR: Invalid filenameLookup dictionary version: %d. Filename: %s", version,
|
||||
filename.data());
|
||||
return;
|
||||
}
|
||||
setFilenameLookupDictionary(dict["filenames"].asValueMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string FileUtils::getFullPathForFilenameWithinDirectory(std::string_view directory,
|
||||
std::string_view filename) const
|
||||
{
|
||||
|
@ -1117,9 +1176,10 @@ std::unique_ptr<FileStream> FileUtils::openFileStream(std::string_view filePath,
|
|||
}
|
||||
|
||||
/* !!!Notes for c++fs
|
||||
a. ios: require ios 13.0+, currently use ghc as workaround in lower ios 13.0- devices
|
||||
a. ios: require ios 13.0+
|
||||
b. android: require ndk-r22+
|
||||
*/
|
||||
#if ADXE_HAVE_STDFS
|
||||
std::vector<std::string> FileUtils::listFiles(std::string_view dirPath) const
|
||||
{
|
||||
const auto fullPath = fullPathForDirectory(dirPath);
|
||||
|
@ -1146,7 +1206,9 @@ std::vector<std::string> FileUtils::listFiles(std::string_view dirPath) const
|
|||
std::string pathStr = entry.path().string();
|
||||
# endif
|
||||
if (isDir)
|
||||
{
|
||||
pathStr += '/';
|
||||
}
|
||||
files.emplace_back(std::move(pathStr));
|
||||
}
|
||||
}
|
||||
|
@ -1178,11 +1240,100 @@ void FileUtils::listFilesRecursively(std::string_view dirPath, std::vector<std::
|
|||
std::string pathStr = entry.path().string();
|
||||
# endif
|
||||
if (isDir)
|
||||
{
|
||||
pathStr += '/';
|
||||
}
|
||||
files->emplace_back(std::move(pathStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
std::vector<std::string> FileUtils::listFiles(std::string_view dirPath) const
|
||||
{
|
||||
std::vector<std::string> files;
|
||||
std::string fullpath = fullPathForDirectory(dirPath);
|
||||
if (!fullpath.empty() && isDirectoryExist(fullpath))
|
||||
{
|
||||
tinydir_dir dir;
|
||||
std::string fullpathstr = fullpath;
|
||||
|
||||
if (tinydir_open(&dir, &fullpathstr[0]) != -1)
|
||||
{
|
||||
while (dir.has_next)
|
||||
{
|
||||
tinydir_file file;
|
||||
if (tinydir_readfile(&dir, &file) == -1)
|
||||
{
|
||||
// Error getting file
|
||||
break;
|
||||
}
|
||||
std::string filepath = file.path;
|
||||
|
||||
if (strcmp(file.name, ".") != 0 && strcmp(file.name, "..") != 0)
|
||||
{
|
||||
if (file.is_dir)
|
||||
filepath.push_back('/');
|
||||
|
||||
files.push_back(std::move(filepath));
|
||||
}
|
||||
|
||||
if (tinydir_next(&dir) == -1)
|
||||
{
|
||||
// Error getting next file
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tinydir_close(&dir);
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
void FileUtils::listFilesRecursively(std::string_view dirPath, std::vector<std::string>* files) const
|
||||
{
|
||||
std::string fullpath = fullPathForDirectory(dirPath);
|
||||
if (isDirectoryExist(fullpath))
|
||||
{
|
||||
tinydir_dir dir;
|
||||
std::string fullpathstr = fullpath;
|
||||
|
||||
if (tinydir_open(&dir, &fullpathstr[0]) != -1)
|
||||
{
|
||||
while (dir.has_next)
|
||||
{
|
||||
tinydir_file file;
|
||||
if (tinydir_readfile(&dir, &file) == -1)
|
||||
{
|
||||
// Error getting file
|
||||
break;
|
||||
}
|
||||
|
||||
if (strcmp(file.name, ".") != 0 && strcmp(file.name, "..") != 0)
|
||||
{
|
||||
std::string filepath = file.path;
|
||||
if (file.is_dir)
|
||||
{
|
||||
filepath.push_back('/');
|
||||
files->push_back(filepath);
|
||||
listFilesRecursively(filepath, files);
|
||||
}
|
||||
else
|
||||
{
|
||||
files->push_back(std::move(filepath));
|
||||
}
|
||||
}
|
||||
|
||||
if (tinydir_next(&dir) == -1)
|
||||
{
|
||||
// Error getting next file
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tinydir_close(&dir);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
||||
// windows os implement should override in platform specific FileUtiles class
|
||||
|
|
|
@ -293,6 +293,49 @@ public:
|
|||
*/
|
||||
virtual std::string fullPathForFilename(std::string_view filename) const;
|
||||
|
||||
/**
|
||||
* Loads the filenameLookup dictionary from the contents of a filename.
|
||||
*
|
||||
* @note The plist file name should follow the format below:
|
||||
*
|
||||
* @code
|
||||
* <?xml version="1.0" encoding="UTF-8"?>
|
||||
* <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
* <plist version="1.0">
|
||||
* <dict>
|
||||
* <key>filenames</key>
|
||||
* <dict>
|
||||
* <key>sounds/click.wav</key>
|
||||
* <string>sounds/click.caf</string>
|
||||
* <key>sounds/endgame.wav</key>
|
||||
* <string>sounds/endgame.caf</string>
|
||||
* <key>sounds/gem-0.wav</key>
|
||||
* <string>sounds/gem-0.caf</string>
|
||||
* </dict>
|
||||
* <key>metadata</key>
|
||||
* <dict>
|
||||
* <key>version</key>
|
||||
* <integer>1</integer>
|
||||
* </dict>
|
||||
* </dict>
|
||||
* </plist>
|
||||
* @endcode
|
||||
* @param filename The plist file name.
|
||||
*
|
||||
@since v2.1
|
||||
* @js loadFilenameLookup
|
||||
* @lua loadFilenameLookup
|
||||
*/
|
||||
virtual void loadFilenameLookupDictionaryFromFile(std::string_view filename);
|
||||
|
||||
/**
|
||||
* Sets the filenameLookup dictionary.
|
||||
*
|
||||
* @param filenameLookupDict The dictionary for replacing filename.
|
||||
* @since v2.1
|
||||
*/
|
||||
virtual void setFilenameLookupDictionary(const ValueMap& filenameLookupDict);
|
||||
|
||||
/**
|
||||
* Gets full path from a file name and the path of the relative file.
|
||||
* @param filename The file name.
|
||||
|
@ -777,6 +820,15 @@ public:
|
|||
/** Returns the full path cache. */
|
||||
const hlookup::string_map<std::string> getFullPathCache() const { return _fullPathCache; }
|
||||
|
||||
/**
|
||||
* Gets the new filename from the filename lookup dictionary.
|
||||
* It is possible to have a override names.
|
||||
* @param filename The original filename.
|
||||
* @return The new filename after searching in the filename lookup dictionary.
|
||||
* If the original filename wasn't in the dictionary, it will return the original filename.
|
||||
*/
|
||||
virtual std::string getNewFilename(std::string_view filename) const;
|
||||
|
||||
/**
|
||||
* Checks whether a file exists without considering search paths and resolution orders.
|
||||
* @param filename The file (with absolute path) to look up for
|
||||
|
@ -857,6 +909,15 @@ protected:
|
|||
*/
|
||||
mutable std::recursive_mutex _mutex;
|
||||
|
||||
/** Dictionary used to lookup filenames based on a key.
|
||||
* It is used internally by the following methods:
|
||||
*
|
||||
* std::string fullPathForFilename(const char*);
|
||||
*
|
||||
* @since v2.1
|
||||
*/
|
||||
ValueMap _filenameLookupDict;
|
||||
|
||||
/**
|
||||
* The vector contains resolution folders.
|
||||
* The lower index of the element in this vector, the higher priority for this resolution directory.
|
||||
|
|
|
@ -105,6 +105,59 @@ bool FileUtilsAndroid::init()
|
|||
return FileUtils::init();
|
||||
}
|
||||
|
||||
std::string FileUtilsAndroid::getNewFilename(std::string_view filename) const
|
||||
{
|
||||
std::string newFileName = FileUtils::getNewFilename(filename);
|
||||
// ../xxx do not fix this path
|
||||
auto pos = newFileName.find("../");
|
||||
if (pos == std::string::npos || pos == 0)
|
||||
{
|
||||
return newFileName;
|
||||
}
|
||||
|
||||
std::vector<std::string> v(3);
|
||||
v.resize(0);
|
||||
auto change = false;
|
||||
size_t size = newFileName.size();
|
||||
size_t idx = 0;
|
||||
bool noexit = true;
|
||||
while (noexit)
|
||||
{
|
||||
pos = newFileName.find('/', idx);
|
||||
std::string tmp;
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
tmp = newFileName.substr(idx, size - idx);
|
||||
noexit = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = newFileName.substr(idx, pos - idx + 1);
|
||||
}
|
||||
auto t = v.size();
|
||||
if (t > 0 && v[t - 1].compare("../") != 0 && (tmp.compare("../") == 0 || tmp.compare("..") == 0))
|
||||
{
|
||||
v.pop_back();
|
||||
change = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
v.push_back(tmp);
|
||||
}
|
||||
idx = pos + 1;
|
||||
}
|
||||
|
||||
if (change)
|
||||
{
|
||||
newFileName.clear();
|
||||
for (auto& s : v)
|
||||
{
|
||||
newFileName.append(s);
|
||||
}
|
||||
}
|
||||
return newFileName;
|
||||
}
|
||||
|
||||
bool FileUtilsAndroid::isFileExistInternal(std::string_view strFilePath) const
|
||||
{
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
/* override functions */
|
||||
bool init() override;
|
||||
|
||||
virtual std::string getNewFilename(std::string_view filename) const override;
|
||||
|
||||
virtual FileUtils::Status getContents(std::string_view filename, ResizableBuffer* buffer) const override;
|
||||
|
||||
virtual std::string getWritablePath() const override;
|
||||
|
|
|
@ -171,9 +171,8 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
|
|||
Log.d(TAG, "onResume()");
|
||||
paused = false;
|
||||
super.onResume();
|
||||
if (this.hasFocus) {
|
||||
resume();
|
||||
}
|
||||
this.hideVirtualButton();
|
||||
resumeIfHasFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -182,15 +181,7 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
|
|||
super.onWindowFocusChanged(hasFocus);
|
||||
|
||||
this.hasFocus = hasFocus;
|
||||
if (this.hasFocus && !paused) {
|
||||
resume();
|
||||
}
|
||||
}
|
||||
|
||||
private void resume() {
|
||||
this.hideVirtualButton();
|
||||
Cocos2dxHelper.onResume();
|
||||
mGLSurfaceView.onResume();
|
||||
resumeIfHasFocus();
|
||||
}
|
||||
|
||||
private void resumeIfHasFocus() {
|
||||
|
@ -199,7 +190,9 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
|
|||
boolean readyToPlay = !isDeviceLocked() && !isDeviceAsleep();
|
||||
|
||||
if(hasFocus && readyToPlay) {
|
||||
resume();
|
||||
this.hideVirtualButton();
|
||||
Cocos2dxHelper.onResume();
|
||||
mGLSurfaceView.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,9 +96,7 @@ class adxetools {
|
|||
return new VersionComparator().compare(ver1, ver2);
|
||||
}
|
||||
|
||||
static String[] findNDK(){
|
||||
def ndkVer = "23.2.8568313" // ndk-r23c
|
||||
|
||||
static String[] findNDK(String ndkVer){
|
||||
def allowNewerNdk = false
|
||||
if(ndkVer.endsWith('+')) {
|
||||
allowNewerNdk = true
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
//
|
||||
// Copyright (c) 2014-2022 @HALX99 - All Rights Reserved
|
||||
// Copyright (c) 2014-2020 @HALX99 - All Rights Reserved
|
||||
//
|
||||
#ifndef _UITEXTFIELD_CPP_H_
|
||||
#define _UITEXTFIELD_CPP_H_
|
||||
#include "UITextFieldEx.h"
|
||||
|
||||
#include "base/CCDirector.h"
|
||||
// #include "CCGLView.h"
|
||||
//#include "NXMacroDefs.h"
|
||||
//#include "purelib/utils/iconvw.h"
|
||||
|
||||
/// cocos2d singleton objects
|
||||
#define CCDIRECTOR cocos2d::Director::getInstance()
|
||||
|
|
|
@ -32132,6 +32132,56 @@ int lua_cocos2dx_FileUtils_getStringFromFile(lua_State* tolua_S)
|
|||
|
||||
return 0;
|
||||
}
|
||||
int lua_cocos2dx_FileUtils_setFilenameLookupDictionary(lua_State* tolua_S)
|
||||
{
|
||||
int argc = 0;
|
||||
cocos2d::FileUtils* cobj = nullptr;
|
||||
bool ok = true;
|
||||
|
||||
#if COCOS2D_DEBUG >= 1
|
||||
tolua_Error tolua_err;
|
||||
#endif
|
||||
|
||||
|
||||
#if COCOS2D_DEBUG >= 1
|
||||
if (!tolua_isusertype(tolua_S,1,"cc.FileUtils",0,&tolua_err)) goto tolua_lerror;
|
||||
#endif
|
||||
|
||||
cobj = (cocos2d::FileUtils*)tolua_tousertype(tolua_S,1,0);
|
||||
|
||||
#if COCOS2D_DEBUG >= 1
|
||||
if (!cobj)
|
||||
{
|
||||
tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_FileUtils_setFilenameLookupDictionary'", nullptr);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
argc = lua_gettop(tolua_S)-1;
|
||||
if (argc == 1)
|
||||
{
|
||||
cocos2d::ValueMap arg0;
|
||||
|
||||
ok &= luaval_to_ccvaluemap(tolua_S, 2, &arg0, "cc.FileUtils:setFilenameLookupDictionary");
|
||||
if(!ok)
|
||||
{
|
||||
tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_FileUtils_setFilenameLookupDictionary'", nullptr);
|
||||
return 0;
|
||||
}
|
||||
cobj->setFilenameLookupDictionary(arg0);
|
||||
lua_settop(tolua_S, 1);
|
||||
return 1;
|
||||
}
|
||||
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.FileUtils:setFilenameLookupDictionary",argc, 1);
|
||||
return 0;
|
||||
|
||||
#if COCOS2D_DEBUG >= 1
|
||||
tolua_lerror:
|
||||
tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_FileUtils_setFilenameLookupDictionary'.",&tolua_err);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
int lua_cocos2dx_FileUtils_getNativeWritableAbsolutePath(lua_State* tolua_S)
|
||||
{
|
||||
int argc = 0;
|
||||
|
@ -32515,6 +32565,56 @@ int lua_cocos2dx_FileUtils_getDefaultResourceRootPath(lua_State* tolua_S)
|
|||
|
||||
return 0;
|
||||
}
|
||||
int lua_cocos2dx_FileUtils_loadFilenameLookupDictionaryFromFile(lua_State* tolua_S)
|
||||
{
|
||||
int argc = 0;
|
||||
cocos2d::FileUtils* cobj = nullptr;
|
||||
bool ok = true;
|
||||
|
||||
#if COCOS2D_DEBUG >= 1
|
||||
tolua_Error tolua_err;
|
||||
#endif
|
||||
|
||||
|
||||
#if COCOS2D_DEBUG >= 1
|
||||
if (!tolua_isusertype(tolua_S,1,"cc.FileUtils",0,&tolua_err)) goto tolua_lerror;
|
||||
#endif
|
||||
|
||||
cobj = (cocos2d::FileUtils*)tolua_tousertype(tolua_S,1,0);
|
||||
|
||||
#if COCOS2D_DEBUG >= 1
|
||||
if (!cobj)
|
||||
{
|
||||
tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_FileUtils_loadFilenameLookupDictionaryFromFile'", nullptr);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
argc = lua_gettop(tolua_S)-1;
|
||||
if (argc == 1)
|
||||
{
|
||||
std::string_view arg0;
|
||||
|
||||
ok &= luaval_to_std_string_view(tolua_S, 2,&arg0, "cc.FileUtils:loadFilenameLookupDictionaryFromFile");
|
||||
if(!ok)
|
||||
{
|
||||
tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_FileUtils_loadFilenameLookupDictionaryFromFile'", nullptr);
|
||||
return 0;
|
||||
}
|
||||
cobj->loadFilenameLookupDictionaryFromFile(arg0);
|
||||
lua_settop(tolua_S, 1);
|
||||
return 1;
|
||||
}
|
||||
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.FileUtils:loadFilenameLookupDictionaryFromFile",argc, 1);
|
||||
return 0;
|
||||
|
||||
#if COCOS2D_DEBUG >= 1
|
||||
tolua_lerror:
|
||||
tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_FileUtils_loadFilenameLookupDictionaryFromFile'.",&tolua_err);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
int lua_cocos2dx_FileUtils_isPopupNotify(lua_State* tolua_S)
|
||||
{
|
||||
int argc = 0;
|
||||
|
@ -32759,6 +32859,56 @@ int lua_cocos2dx_FileUtils_getOriginalSearchPaths(lua_State* tolua_S)
|
|||
|
||||
return 0;
|
||||
}
|
||||
int lua_cocos2dx_FileUtils_getNewFilename(lua_State* tolua_S)
|
||||
{
|
||||
int argc = 0;
|
||||
cocos2d::FileUtils* cobj = nullptr;
|
||||
bool ok = true;
|
||||
|
||||
#if COCOS2D_DEBUG >= 1
|
||||
tolua_Error tolua_err;
|
||||
#endif
|
||||
|
||||
|
||||
#if COCOS2D_DEBUG >= 1
|
||||
if (!tolua_isusertype(tolua_S,1,"cc.FileUtils",0,&tolua_err)) goto tolua_lerror;
|
||||
#endif
|
||||
|
||||
cobj = (cocos2d::FileUtils*)tolua_tousertype(tolua_S,1,0);
|
||||
|
||||
#if COCOS2D_DEBUG >= 1
|
||||
if (!cobj)
|
||||
{
|
||||
tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_FileUtils_getNewFilename'", nullptr);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
argc = lua_gettop(tolua_S)-1;
|
||||
if (argc == 1)
|
||||
{
|
||||
std::string_view arg0;
|
||||
|
||||
ok &= luaval_to_std_string_view(tolua_S, 2,&arg0, "cc.FileUtils:getNewFilename");
|
||||
if(!ok)
|
||||
{
|
||||
tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_FileUtils_getNewFilename'", nullptr);
|
||||
return 0;
|
||||
}
|
||||
std::string ret = cobj->getNewFilename(arg0);
|
||||
lua_pushlstring(tolua_S,ret.c_str(),ret.length());
|
||||
return 1;
|
||||
}
|
||||
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.FileUtils:getNewFilename",argc, 1);
|
||||
return 0;
|
||||
|
||||
#if COCOS2D_DEBUG >= 1
|
||||
tolua_lerror:
|
||||
tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_FileUtils_getNewFilename'.",&tolua_err);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
int lua_cocos2dx_FileUtils_listFiles(lua_State* tolua_S)
|
||||
{
|
||||
int argc = 0;
|
||||
|
@ -34473,17 +34623,20 @@ int lua_register_cocos2dx_FileUtils(lua_State* tolua_S)
|
|||
tolua_beginmodule(tolua_S,"FileUtils");
|
||||
tolua_function(tolua_S,"fullPathForFilename",lua_cocos2dx_FileUtils_fullPathForFilename);
|
||||
tolua_function(tolua_S,"getStringFromFile",lua_cocos2dx_FileUtils_getStringFromFile);
|
||||
tolua_function(tolua_S,"setFilenameLookupDictionary",lua_cocos2dx_FileUtils_setFilenameLookupDictionary);
|
||||
tolua_function(tolua_S,"getNativeWritableAbsolutePath",lua_cocos2dx_FileUtils_getNativeWritableAbsolutePath);
|
||||
tolua_function(tolua_S,"removeFile",lua_cocos2dx_FileUtils_removeFile);
|
||||
tolua_function(tolua_S,"listFilesRecursivelyAsync",lua_cocos2dx_FileUtils_listFilesRecursivelyAsync);
|
||||
tolua_function(tolua_S,"isAbsolutePath",lua_cocos2dx_FileUtils_isAbsolutePath);
|
||||
tolua_function(tolua_S,"renameFile",lua_cocos2dx_FileUtils_renameFile);
|
||||
tolua_function(tolua_S,"getDefaultResourceRootPath",lua_cocos2dx_FileUtils_getDefaultResourceRootPath);
|
||||
tolua_function(tolua_S,"loadFilenameLookup",lua_cocos2dx_FileUtils_loadFilenameLookupDictionaryFromFile);
|
||||
tolua_function(tolua_S,"isPopupNotify",lua_cocos2dx_FileUtils_isPopupNotify);
|
||||
tolua_function(tolua_S,"getValueVectorFromFile",lua_cocos2dx_FileUtils_getValueVectorFromFile);
|
||||
tolua_function(tolua_S,"getSearchPaths",lua_cocos2dx_FileUtils_getSearchPaths);
|
||||
tolua_function(tolua_S,"writeToFile",lua_cocos2dx_FileUtils_writeToFile);
|
||||
tolua_function(tolua_S,"getOriginalSearchPaths",lua_cocos2dx_FileUtils_getOriginalSearchPaths);
|
||||
tolua_function(tolua_S,"getNewFilename",lua_cocos2dx_FileUtils_getNewFilename);
|
||||
tolua_function(tolua_S,"listFiles",lua_cocos2dx_FileUtils_listFiles);
|
||||
tolua_function(tolua_S,"getValueMapFromFile",lua_cocos2dx_FileUtils_getValueMapFromFile);
|
||||
tolua_function(tolua_S,"getFileSize",lua_cocos2dx_FileUtils_getFileSize);
|
||||
|
|
|
@ -2325,6 +2325,9 @@ int register_all_cocos2dx(lua_State* tolua_S);
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ android {
|
|||
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
|
||||
|
||||
// setup ndk
|
||||
def ndkInfo = adxetools.findNDK()
|
||||
def ndkInfo = adxetools.findNDK("19.2.5345600+")
|
||||
ndkVersion = ndkInfo[0]
|
||||
if(ndkInfo[1]) {
|
||||
ndkPath = ndkInfo[1]
|
||||
|
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.2.0'
|
||||
classpath 'com.android.tools.build:gradle:7.1.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
|
|
|
@ -9,7 +9,7 @@ android {
|
|||
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
|
||||
|
||||
// setup ndk
|
||||
def ndkInfo = adxetools.findNDK()
|
||||
def ndkInfo = adxetools.findNDK("19.2.5345600+")
|
||||
ndkVersion = ndkInfo[0]
|
||||
if(ndkInfo[1]) {
|
||||
ndkPath = ndkInfo[1]
|
||||
|
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.2.0'
|
||||
classpath 'com.android.tools.build:gradle:7.1.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
|
|
|
@ -30,6 +30,7 @@ FileUtilsTests::FileUtilsTests()
|
|||
{
|
||||
ADD_TEST_CASE(TestResolutionDirectories);
|
||||
ADD_TEST_CASE(TestSearchPath);
|
||||
ADD_TEST_CASE(TestFilenameLookup);
|
||||
ADD_TEST_CASE(TestIsFileExist);
|
||||
ADD_TEST_CASE(TestIsDirectoryExist);
|
||||
ADD_TEST_CASE(TestFileFuncs);
|
||||
|
@ -207,6 +208,44 @@ std::string TestSearchPath::subtitle() const
|
|||
return "See the console, can see a orange box and a 'about' picture, except Android";
|
||||
}
|
||||
|
||||
// TestFilenameLookup
|
||||
|
||||
void TestFilenameLookup::onEnter()
|
||||
{
|
||||
FileUtilsDemo::onEnter();
|
||||
|
||||
auto sharedFileUtils = FileUtils::getInstance();
|
||||
|
||||
ValueMap dict;
|
||||
dict["grossini.bmp"] = Value("Images/grossini.png");
|
||||
dict["grossini.xcf"] = Value("Images/grossini.png");
|
||||
|
||||
sharedFileUtils->setFilenameLookupDictionary(dict);
|
||||
|
||||
// Instead of loading carlitos.xcf, it will load grossini.png
|
||||
auto sprite = Sprite::create("grossini.xcf");
|
||||
this->addChild(sprite);
|
||||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
sprite->setPosition(s.width / 2, s.height / 2);
|
||||
}
|
||||
|
||||
void TestFilenameLookup::onExit()
|
||||
{
|
||||
|
||||
FileUtils* sharedFileUtils = FileUtils::getInstance();
|
||||
|
||||
// reset filename lookup
|
||||
sharedFileUtils->setFilenameLookupDictionary(ValueMap());
|
||||
|
||||
FileUtilsDemo::onExit();
|
||||
}
|
||||
|
||||
std::string TestFilenameLookup::title() const
|
||||
{
|
||||
return "FileUtils: filename lookup";
|
||||
}
|
||||
|
||||
// TestIsFileExist
|
||||
|
||||
void TestIsFileExist::onEnter()
|
||||
|
@ -237,6 +276,9 @@ void TestIsFileExist::onExit()
|
|||
|
||||
FileUtils* sharedFileUtils = FileUtils::getInstance();
|
||||
|
||||
// reset filename lookup
|
||||
sharedFileUtils->setFilenameLookupDictionary(ValueMap());
|
||||
|
||||
FileUtilsDemo::onExit();
|
||||
}
|
||||
|
||||
|
@ -955,6 +997,7 @@ void TestUnicodePath::onExit()
|
|||
|
||||
FileUtils* sharedFileUtils = FileUtils::getInstance();
|
||||
sharedFileUtils->purgeCachedEntries();
|
||||
sharedFileUtils->setFilenameLookupDictionary(ValueMap());
|
||||
FileUtilsDemo::onExit();
|
||||
}
|
||||
|
||||
|
@ -994,6 +1037,12 @@ void TestIsFileExistAsync::onEnter()
|
|||
|
||||
void TestIsFileExistAsync::onExit()
|
||||
{
|
||||
|
||||
FileUtils* sharedFileUtils = FileUtils::getInstance();
|
||||
|
||||
// reset filename lookup
|
||||
sharedFileUtils->setFilenameLookupDictionary(ValueMap());
|
||||
|
||||
FileUtilsDemo::onExit();
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,16 @@ private:
|
|||
std::vector<std::string> _defaultResolutionsOrderArray;
|
||||
};
|
||||
|
||||
class TestFilenameLookup : public FileUtilsDemo
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(TestFilenameLookup);
|
||||
|
||||
virtual void onEnter() override;
|
||||
virtual void onExit() override;
|
||||
virtual std::string title() const override;
|
||||
};
|
||||
|
||||
class TestIsFileExist : public FileUtilsDemo
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -80,6 +80,7 @@ FontTests::FontTests()
|
|||
});
|
||||
}
|
||||
ADD_TEST_CASE(FontNoReplacementTest);
|
||||
ADD_TEST_CASE(FontReplacementTest);
|
||||
}
|
||||
|
||||
void FontTest::showFont(std::string_view fontFile)
|
||||
|
@ -161,6 +162,7 @@ FontNoReplacementTest* FontNoReplacementTest::create()
|
|||
|
||||
FontNoReplacementTest::FontNoReplacementTest()
|
||||
{
|
||||
_replace = false;
|
||||
}
|
||||
|
||||
FontNoReplacementTest::~FontNoReplacementTest()
|
||||
|
@ -174,6 +176,7 @@ FontNoReplacementTest::~FontNoReplacementTest()
|
|||
FontFreeType::releaseFont("fonts/Abduction.ttf");
|
||||
FontAtlasCache::unloadFontAtlasTTF("fonts/Schwarzwald.ttf");
|
||||
FontFreeType::releaseFont("fonts/Schwarzwald.ttf");
|
||||
FileUtils::getInstance()->setFilenameLookupDictionary(ValueMap());
|
||||
}
|
||||
|
||||
void FontNoReplacementTest::onEnter()
|
||||
|
@ -181,6 +184,17 @@ void FontNoReplacementTest::onEnter()
|
|||
TestCase::onEnter();
|
||||
|
||||
std::string suffix;
|
||||
if (_replace)
|
||||
{
|
||||
ValueMap dict{{"fonts/A Damn Mess.ttf", Value("fonts/arial.ttf")},
|
||||
{"fonts/Abberancy.ttf", Value("fonts/arial.ttf")},
|
||||
{"fonts/Abduction.ttf", Value("fonts/arial.ttf")},
|
||||
{"fonts/Schwarzwald.ttf", Value("fonts/arial.ttf")}};
|
||||
|
||||
FileUtils::getInstance()->setFilenameLookupDictionary(dict);
|
||||
suffix = " replaced by arial.ttf";
|
||||
}
|
||||
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
|
||||
auto blockSize = Size(s.width / 3, 200);
|
||||
|
@ -239,3 +253,29 @@ std::string FontNoReplacementTest::title() const
|
|||
{
|
||||
return "Font no replacement test";
|
||||
}
|
||||
|
||||
FontReplacementTest* FontReplacementTest::create()
|
||||
{
|
||||
auto ret = new FontReplacementTest;
|
||||
if (ret->init())
|
||||
{
|
||||
ret->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete ret;
|
||||
ret = nullptr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FontReplacementTest::FontReplacementTest()
|
||||
{
|
||||
_replace = true;
|
||||
}
|
||||
|
||||
std::string FontReplacementTest::title() const
|
||||
{
|
||||
return "Font replacement test";
|
||||
}
|
||||
|
|
|
@ -65,6 +65,18 @@ public:
|
|||
|
||||
protected:
|
||||
FontNoReplacementTest();
|
||||
|
||||
bool _replace;
|
||||
};
|
||||
|
||||
class FontReplacementTest : public FontNoReplacementTest
|
||||
{
|
||||
public:
|
||||
static FontReplacementTest* create();
|
||||
virtual std::string title() const override;
|
||||
|
||||
protected:
|
||||
FontReplacementTest();
|
||||
};
|
||||
|
||||
#endif // _FONT_TEST_H_
|
||||
|
|
|
@ -9,7 +9,7 @@ android {
|
|||
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
|
||||
|
||||
// setup ndk
|
||||
def ndkInfo = adxetools.findNDK()
|
||||
def ndkInfo = adxetools.findNDK("19.2.5345600+")
|
||||
ndkVersion = ndkInfo[0]
|
||||
if(ndkInfo[1]) {
|
||||
ndkPath = ndkInfo[1]
|
||||
|
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.2.0'
|
||||
classpath 'com.android.tools.build:gradle:7.1.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
|
|
|
@ -9,7 +9,7 @@ android {
|
|||
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
|
||||
|
||||
// setup ndk
|
||||
def ndkInfo = adxetools.findNDK()
|
||||
def ndkInfo = adxetools.findNDK("19.2.5345600+")
|
||||
ndkVersion = ndkInfo[0]
|
||||
if(ndkInfo[1]) {
|
||||
ndkPath = ndkInfo[1]
|
||||
|
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.2.0'
|
||||
classpath 'com.android.tools.build:gradle:7.1.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
|
@ -9,7 +9,7 @@ android {
|
|||
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
|
||||
|
||||
// setup ndk
|
||||
def ndkInfo = adxetools.findNDK()
|
||||
def ndkInfo = adxetools.findNDK("19.2.5345600+")
|
||||
ndkVersion = ndkInfo[0]
|
||||
if(ndkInfo[1]) {
|
||||
ndkPath = ndkInfo[1]
|
||||
|
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.2.0'
|
||||
classpath 'com.android.tools.build:gradle:7.1.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
|
|
|
@ -28,9 +28,9 @@ COCOS2D_X = os.path.abspath(os.path.join(DIR_PATH, "../.."))
|
|||
ROOT_DIR = os.path.abspath(os.path.join(COCOS2D_X, ".."))
|
||||
|
||||
# cmdlinetools download page: https://developer.android.com/studio#command-tools
|
||||
# commandlinetools-win-8512546_latest.zip
|
||||
CMDLINETOOLS_REV = "8512546"
|
||||
NDK_VER = "23.2.8568313" # "r23c LTS"
|
||||
# commandlinetools-linux-8092744_latest.zip
|
||||
CMDLINETOOLS_REV = "8092744"
|
||||
NDK_VER = "19.2.5345600" # "r19c"
|
||||
|
||||
# ANDROID_NDK = os.path.join(ROOT_DIR, "android-ndk-" + NDK_VER)
|
||||
ANDROID_SDK = os.path.join(ROOT_DIR, "android-sdk")
|
||||
|
|
Loading…
Reference in New Issue