[engine] [cocos2d-x] [jsb-adapter] 适配引擎 v2.4.12 版本

This commit is contained in:
SmallMain
2023-10-30 22:32:32 +08:00
parent 2508616ad9
commit 0092eb9f05
787 changed files with 206249 additions and 422 deletions

View File

@@ -55,6 +55,13 @@ public:
ANDROIDOS, /**< Android, because ANDROID is a macro, so use ANDROIDOS instead */
IPHONE, /**< iPhone */
IPAD, /**< iPad */
BLACKBERRY, /**< BLACKBERRY> */
NACL, /**according to CCSys.js below*/
EMSCRIPTEN,
TIZEN,
WINRT,
WP8,
OpenHarmony /**< OpenHarmony > */
};
enum class LanguageType

View File

@@ -111,6 +111,8 @@ THE SOFTWARE.
#include "platform/winrt/CCGL.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_LINUX
#include "platform/linux/CCGL-linux.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include "platform/openharmony/CCGL-openharmony.h"
#endif
/// @endcond

View File

@@ -81,6 +81,8 @@ extern "C"
#include "base/etc2.h"
}
#include "base/astc.h"
#if CC_USE_WEBP
#include "webp/decode.h"
#endif // CC_USE_WEBP
@@ -95,6 +97,8 @@ extern "C"
#include "base/ZipUtils.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/CCFileUtils-android.h"
#elif(CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#include "platform/openharmony/FileUtils-openharmony.h"
#endif
#include <map>
@@ -141,7 +145,24 @@ namespace
#ifdef GL_COMPRESSED_RGBA8_ETC2_EAC
PixelFormatInfoMapValue(Image::PixelFormat::ETC2_RGBA, Image::PixelFormatInfo(GL_COMPRESSED_RGBA8_ETC2_EAC, 0xFFFFFFFF, 0xFFFFFFFF, 8, true, true)),
#endif
#ifdef GL_COMPRESSED_RGBA_ASTC_4x4_KHR
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_4x4, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_4x4_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 8, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_5x4, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_5x4_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 6, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_5x5, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_5x5_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 5, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_6x5, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_6x5_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_6x6, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_6x6_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 5, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_8x5, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_8x5_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 3, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_8x6, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_8x6_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 3, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_8x8, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_8x8_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 2, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_10x5, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_10x5_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 3, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_10x6, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_10x6_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 2, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_10x8, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_10x8_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 2, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_10x10, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_10x10_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 1, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_12x10, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_12x10_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 1, true, true)),
PixelFormatInfoMapValue(Image::PixelFormat::ASTC_RGBA_12x12, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_ASTC_12x12_KHR, 0xFFFFFFFF, 0xFFFFFFFF, 1, true, true)),
#endif
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
PixelFormatInfoMapValue(Image::PixelFormat::S3TC_DXT1, Image::PixelFormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, false)),
#endif
@@ -596,6 +617,9 @@ bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen)
case Format::ETC2:
ret = initWithETC2Data(unpackedData, unpackedLen);
break;
case Format::ASTC:
ret = initWithASTCData(unpackedData, unpackedLen);
break;
case Format::S3TC:
ret = initWithS3TCData(unpackedData, unpackedLen);
break;
@@ -649,7 +673,6 @@ bool Image::isEtc2(const unsigned char * data, ssize_t dataLen)
return etc2_pkm_is_valid((etc2_byte*)data) ? true : false;
}
bool Image::isS3TC(const unsigned char * data, ssize_t /*dataLen*/)
{
S3TCTexHeader *header = (S3TCTexHeader *)data;
@@ -661,6 +684,11 @@ bool Image::isS3TC(const unsigned char * data, ssize_t /*dataLen*/)
return true;
}
bool Image::isASTC(const unsigned char * data, ssize_t dataLen)
{
return astcIsValid(const_cast<astc_byte *>(data));
}
bool Image::isJpg(const unsigned char * data, ssize_t dataLen)
{
if (dataLen <= 4)
@@ -744,6 +772,10 @@ Image::Format Image::detectFormat(const unsigned char * data, ssize_t dataLen)
{
return Format::ETC2;
}
else if (isASTC(data, dataLen))
{
return Format::ASTC;
}
else if (isS3TC(data, dataLen))
{
return Format::S3TC;
@@ -774,6 +806,35 @@ const Image::PixelFormatInfo& Image::getPixelFormatInfo() const
return getPixelFormatInfoMap().at(_renderFormat);
}
Image::PixelFormat Image::getASTCFormat(const unsigned char *pHeader) const
{
int xdim = pHeader[ASTC_HEADER_MAGIC];
int ydim = pHeader[ASTC_HEADER_MAGIC + 1];
if (xdim == 4) return Image::PixelFormat::ASTC_RGBA_4x4;
if (xdim == 5) {
if (ydim == 4) return Image::PixelFormat::ASTC_RGBA_5x4;
return Image::PixelFormat::ASTC_RGBA_5x5;
}
if (xdim == 6) {
if (ydim == 5) return Image::PixelFormat::ASTC_RGBA_6x5;
return Image::PixelFormat::ASTC_RGBA_6x6;
}
if (xdim == 8) {
if (ydim == 5) return Image::PixelFormat::ASTC_RGBA_8x5;
if (ydim == 6) return Image::PixelFormat::ASTC_RGBA_8x6;
return Image::PixelFormat::ASTC_RGBA_8x8;
}
if (xdim == 10) {
if (ydim == 5) return Image::PixelFormat::ASTC_RGBA_10x5;
if (ydim == 6) return Image::PixelFormat::ASTC_RGBA_10x6;
if (ydim == 8) return Image::PixelFormat::ASTC_RGBA_10x8;
return Image::PixelFormat::ASTC_RGBA_10x10;
}
if (ydim == 10) return Image::PixelFormat::ASTC_RGBA_12x10;
return Image::PixelFormat::ASTC_RGBA_12x12;
}
namespace
{
/*
@@ -894,6 +955,7 @@ bool Image::initWithJpgData(const unsigned char * data, ssize_t dataLen)
jpeg_start_decompress( &cinfo );
/* init image info */
_isCompressed = false;
_width = cinfo.output_width;
_height = cinfo.output_height;
_hasPremultipliedAlpha = false;
@@ -974,6 +1036,7 @@ bool Image::initWithPngData(const unsigned char * data, ssize_t dataLen)
// read png file info
png_read_info(png_ptr, info_ptr);
_isCompressed = false;
_width = png_get_image_width(png_ptr, info_ptr);
_height = png_get_image_height(png_ptr, info_ptr);
png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr);
@@ -1366,11 +1429,17 @@ bool Image::initWithPVRv2Data(const unsigned char * data, ssize_t dataLen)
//Get size of mipmap
_width = width = CC_SWAP_INT32_LITTLE_TO_HOST(header->width);
_height = height = CC_SWAP_INT32_LITTLE_TO_HOST(header->height);
_isCompressed = true;
//Get ptr to where data starts..
dataLength = CC_SWAP_INT32_LITTLE_TO_HOST(header->dataLength);
assert(Configuration::getInstance()->supportsPVRTC());
if (Configuration::getInstance()->supportsPVRTC() == false)
{
CCLOG("initWithPVRv2Data: ERROR: Unsupported PVR Compress texture on this device");
return false;
}
//Move by size of header
_dataLen = dataLen - sizeof(PVRv2TexHeader);
@@ -1496,12 +1565,18 @@ bool Image::initWithPVRv3Data(const unsigned char * data, ssize_t dataLen)
// sizing
int width = CC_SWAP_INT32_LITTLE_TO_HOST(header->width);
int height = CC_SWAP_INT32_LITTLE_TO_HOST(header->height);
_isCompressed = true;
_width = width;
_height = height;
int dataOffset = 0, dataSize = 0;
int blockSize = 0, widthBlocks = 0, heightBlocks = 0;
assert(Configuration::getInstance()->supportsPVRTC());
if (Configuration::getInstance()->supportsPVRTC() == false)
{
CCLOG("initWithPVRv3Data: ERROR: Unsupported PVR Compress texture on this device");
return false;
}
_dataLen = dataLen - (sizeof(PVRv3TexHeader) + header->metadataLength);
_data = static_cast<unsigned char*>(malloc(_dataLen * sizeof(unsigned char)));
@@ -1585,6 +1660,7 @@ bool Image::initWithETCData(const unsigned char * data, ssize_t dataLen)
_width = etc1_pkm_get_width(header);
_height = etc1_pkm_get_height(header);
_isCompressed = true;
if (0 == _width || 0 == _height)
{
@@ -1592,6 +1668,11 @@ bool Image::initWithETCData(const unsigned char * data, ssize_t dataLen)
}
assert(Configuration::getInstance()->supportsETC());
if (Configuration::getInstance()->supportsETC() == false)
{
CCLOG("initWithETCData: ERROR: Unsupported ETC Compress texture on this device");
return false;
}
//old opengl version has no define for GL_ETC1_RGB8_OES, add macro to make compiler happy.
#ifdef GL_ETC1_RGB8_OES
@@ -1617,6 +1698,7 @@ bool Image::initWithETC2Data(const unsigned char * data, ssize_t dataLen)
_width = etc2_pkm_get_width(header);
_height = etc2_pkm_get_height(header);
_isCompressed = true;
if (0 == _width || 0 == _height)
{
@@ -1624,6 +1706,11 @@ bool Image::initWithETC2Data(const unsigned char * data, ssize_t dataLen)
}
assert(Configuration::getInstance()->supportsETC2());
if (Configuration::getInstance()->supportsETC2() == false)
{
CCLOG("initWithETC2Data: ERROR: Unsupported ETC2 Compress texture on this device");
return false;
}
etc2_uint32 format = etc2_pkm_get_format(header);
if (format == ETC2_RGB_NO_MIPMAPS)
@@ -1718,6 +1805,45 @@ bool Image::initWithTGAData(tImageTGA* tgaData)
return ret;
}
bool Image::initWithASTCData(const unsigned char *data, ssize_t dataLen)
{
const auto *header = static_cast<const astc_byte *>(data);
//check the data
if (!astcIsValid(header))
{
return false;
}
_width = astcGetWidth(header);
_height = astcGetHeight(header);
_isCompressed = true;
if (0 == _width || 0 == _height)
{
return false;
}
assert(Configuration::getInstance()->supportsASTC());
if (Configuration::getInstance()->supportsASTC() == false)
{
CCLOG("initWithASTCData: ERROR: Unsupported ASTC Compress texture on this device");
return false;
}
_renderFormat = getASTCFormat(header);
_dataLen = dataLen - ASTC_HEADER_SIZE;
_data = static_cast<unsigned char *>(malloc(_dataLen * sizeof(unsigned char)));
if (_data == nullptr)
{
CCLOG("initWithASTCData: ERROR : Image _data is null!");
return false;
}
memcpy(_data, static_cast<const unsigned char *>(data) + ASTC_HEADER_SIZE, _dataLen);
return true;
}
static uint32_t makeFourCC(char ch0, char ch1, char ch2, char ch3)
{
const uint32_t fourCC = ((uint32_t)(char)(ch0) | ((uint32_t)(char)(ch1) << 8) | ((uint32_t)(char)(ch2) << 16) | ((uint32_t)(char)(ch3) << 24 ));
@@ -1748,6 +1874,11 @@ bool Image::initWithS3TCData(const unsigned char * data, ssize_t dataLen)
int height = _height;
assert(Configuration::getInstance()->supportsS3TC());
if (Configuration::getInstance()->supportsS3TC() == false)
{
CCLOG("initWithS3TCData: ERROR: Unsupported S3TC Compress texture on this device");
return false;
}
_dataLen = dataLen - sizeof(S3TCTexHeader);
_data = static_cast<unsigned char*>(malloc(_dataLen * sizeof(unsigned char)));
@@ -1826,6 +1957,7 @@ bool Image::initWithWebpData(const unsigned char * data, ssize_t dataLen)
_renderFormat = config.input.has_alpha?Image::PixelFormat::RGBA8888:Image::PixelFormat::RGB888;
_width = config.input.width;
_height = config.input.height;
_isCompressed = false;
//we ask webp to give data with premultiplied alpha
_hasPremultipliedAlpha = (config.input.has_alpha != 0);
@@ -1866,6 +1998,7 @@ bool Image::initWithRawData(const unsigned char * data, ssize_t dataLen, int wid
_width = width;
_hasPremultipliedAlpha = preMulti;
_renderFormat = Image::PixelFormat::RGBA8888;
_isCompressed = false;
// only RGBA8888 supported
int bytesPerComponent = 4;

View File

@@ -84,6 +84,8 @@ public:
ETC,
//! ETC2
ETC2,
//! ASTC
ASTC,
//! S3TC
S3TC,
//! ATITC
@@ -135,6 +137,34 @@ public:
ETC2_RGB,
//! ETC-compressed texture: GL_COMPRESSED_RGBA8_ETC2
ETC2_RGBA,
//! ASTC-compressed texture: ASTC_4x4
ASTC_RGBA_4x4,
//! ASTC-compressed texture: ASTC_5x4
ASTC_RGBA_5x4,
//! ASTC-compressed texture: ASTC_5x5
ASTC_RGBA_5x5,
//! ASTC-compressed texture: ASTC_6x5
ASTC_RGBA_6x5,
//! ASTC-compressed texture: ASTC_6x6
ASTC_RGBA_6x6,
//! ASTC-compressed texture: ASTC_8x5
ASTC_RGBA_8x5,
//! ASTC-compressed texture: ASTC_8x6
ASTC_RGBA_8x6,
//! ASTC-compressed texture: ASTC_8x8
ASTC_RGBA_8x8,
//! ASTC-compressed texture: ASTC_10x5
ASTC_RGBA_10x5,
//! ASTC-compressed texture: ASTC_10x6
ASTC_RGBA_10x6,
//! ASTC-compressed texture: ASTC_10x8
ASTC_RGBA_10x8,
//! ASTC-compressed texture: ASTC_10x10
ASTC_RGBA_10x10,
//! ASTC-compressed texture: ASTC_12x10
ASTC_RGBA_12x10,
//! ASTC-compressed texture: ASTC_12x12
ASTC_RGBA_12x12,
//! S3TC-compressed texture: S3TC_Dxt1
S3TC_DXT1,
//! S3TC-compressed texture: S3TC_Dxt3
@@ -244,6 +274,7 @@ protected:
bool initWithPVRv3Data(const unsigned char * data, ssize_t dataLen);
bool initWithETCData(const unsigned char * data, ssize_t dataLen);
bool initWithETC2Data(const unsigned char * data, ssize_t dataLen);
bool initWithASTCData(const unsigned char * data, ssize_t dataLen);
bool initWithS3TCData(const unsigned char * data, ssize_t dataLen);
typedef struct sImageTGA tImageTGA;
@@ -275,6 +306,7 @@ protected:
// false if we can't auto detect the image is premultiplied or not.
bool _hasPremultipliedAlpha;
std::string _filePath;
bool _isCompressed = false;
protected:
// noncopyable
@@ -299,7 +331,10 @@ protected:
bool isPvr(const unsigned char * data, ssize_t dataLen);
bool isEtc(const unsigned char * data, ssize_t dataLen);
bool isEtc2(const unsigned char * data, ssize_t dataLen);
bool isASTC(const unsigned char * data, ssize_t detaLen);
bool isS3TC(const unsigned char * data,ssize_t dataLen);
PixelFormat getASTCFormat(const unsigned char * pHeader) const;
};
// end of platform group

View File

@@ -53,6 +53,7 @@ THE SOFTWARE.
#define CC_PLATFORM_TIZEN 11
#define CC_PLATFORM_QT5 12
#define CC_PLATFORM_WINRT 13
#define CC_PLATFORM_OPENHARMONY 14
// Determine target platform by compile environment macro.
#define CC_TARGET_PLATFORM CC_PLATFORM_UNKNOWN
@@ -135,6 +136,12 @@ THE SOFTWARE.
#define CC_TARGET_PLATFORM CC_PLATFORM_WINRT
#endif
//OPENHARMONY
#if defined(OPENHARMONY)
#undef CC_TARGET_PLATFORM
#define CC_TARGET_PLATFORM CC_PLATFORM_OPENHARMONY
#endif
//////////////////////////////////////////////////////////////////////////
// post configure
//////////////////////////////////////////////////////////////////////////
@@ -150,5 +157,15 @@ THE SOFTWARE.
#endif
#endif // CC_PLATFORM_WIN32
#if (CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY)
#ifdef __cplusplus
#define __BEGIN_DECLS extern "C" {
#define __END_DECLS }
#else
#define __BEGIN_DECLS
#define __END_DECLS
#endif
#endif // CC_PLATFORM_OPENHARMONY
/// @endcond
#endif // __BASE_CC_PLATFORM_CONFIG_H__

View File

@@ -42,6 +42,8 @@ THE SOFTWARE.
#include "platform/winrt/CCPlatformDefine-winrt.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_LINUX
#include "platform/linux/CCPlatformDefine-linux.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include "platform/openharmony/CCPlatformDefine-openharmony.h"
#endif
/// @endcond

View File

@@ -42,11 +42,12 @@ public class Cocos2dxAccelerometer implements SensorEventListener {
// Fields
// ===========================================================
private final Context mContext;
private final SensorManager mSensorManager;
private final Sensor mAcceleration;
private final Sensor mAccelerationIncludingGravity;
private final Sensor mGyroscope;
private SensorManager mSensorManager;
private Sensor mAcceleration;
private Sensor mAccelerationIncludingGravity;
private Sensor mGyroscope;
private int mSamplingPeriodUs = SensorManager.SENSOR_DELAY_GAME;
private boolean mEnableSensor = false;
class Acceleration {
public float x = 0.0f;
@@ -74,24 +75,39 @@ public class Cocos2dxAccelerometer implements SensorEventListener {
public Cocos2dxAccelerometer(final Context context) {
mContext = context;
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
mAcceleration = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mAccelerationIncludingGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
}
// ===========================================================
// Getter & Setter
// ===========================================================
public void enable() {
mSensorManager.registerListener(this, mAcceleration, mSamplingPeriodUs);
mSensorManager.registerListener(this, mAccelerationIncludingGravity, mSamplingPeriodUs);
mSensorManager.registerListener(this, mGyroscope, mSamplingPeriodUs);
if (mEnableSensor) {
if (null == mSensorManager) {
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
mAcceleration = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mAccelerationIncludingGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
}
mSensorManager.registerListener(this, mAcceleration, mSamplingPeriodUs);
mSensorManager.registerListener(this, mAccelerationIncludingGravity, mSamplingPeriodUs);
mSensorManager.registerListener(this, mGyroscope, mSamplingPeriodUs);
}
}
public void enableAccelerometer(boolean enabled) {
mEnableSensor = enabled;
if (enabled) {
enable();
} else {
disable();
}
}
public void disable() {
this.mSensorManager.unregisterListener(this);
if (mEnableSensor && null != mSensorManager) {
this.mSensorManager.unregisterListener(this);
}
}
public void setInterval(float interval) {

View File

@@ -28,6 +28,7 @@ package org.cocos2dx.lib;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
@@ -296,7 +297,9 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
e.printStackTrace();
}
mCocos2dxOrientationHelper = new Cocos2dxOrientationHelper(this);
if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_SENSOR) {
mCocos2dxOrientationHelper = new Cocos2dxOrientationHelper(this);
}
}
public void setKeepScreenOn(boolean value) {
@@ -390,7 +393,9 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
Cocos2dxAudioFocusManager.registerAudioFocusListener(this);
Utils.hideVirtualButton();
resumeIfHasFocus();
mCocos2dxOrientationHelper.onResume();
if (null != mCocos2dxOrientationHelper) {
mCocos2dxOrientationHelper.onResume();
}
}
@Override
@@ -419,7 +424,9 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
Cocos2dxAudioFocusManager.unregisterAudioFocusListener(this);
Cocos2dxHelper.onPause();
mGLSurfaceView.onPause();
mCocos2dxOrientationHelper.onPause();
if (null != mCocos2dxOrientationHelper) {
mCocos2dxOrientationHelper.onPause();
}
}
@Override

View File

@@ -82,7 +82,6 @@ public class Cocos2dxHelper {
private static AssetManager sAssetManager;
private static Cocos2dxAccelerometer sCocos2dxAccelerometer;
private static boolean sAccelerometerEnabled;
private static boolean sCompassEnabled;
private static boolean sActivityVisible;
private static String sPackageName;
@@ -314,9 +313,9 @@ public class Cocos2dxHelper {
public static String getCurrentLanguageCode() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return LocaleList.getDefault().get(0).getLanguage();
return LocaleList.getDefault().get(0).toString();
} else {
return Locale.getDefault().getLanguage();
return Locale.getDefault().toString();
}
}
@@ -329,8 +328,7 @@ public class Cocos2dxHelper {
}
public static void enableAccelerometer() {
Cocos2dxHelper.sAccelerometerEnabled = true;
Cocos2dxHelper.sCocos2dxAccelerometer.enable();
Cocos2dxHelper.sCocos2dxAccelerometer.enableAccelerometer(true);
}
public static void setAccelerometerInterval(float interval) {
@@ -338,8 +336,7 @@ public class Cocos2dxHelper {
}
public static void disableAccelerometer() {
Cocos2dxHelper.sAccelerometerEnabled = false;
Cocos2dxHelper.sCocos2dxAccelerometer.disable();
Cocos2dxHelper.sCocos2dxAccelerometer.enableAccelerometer(false);
}
public static void setKeepScreenOn(boolean value) {
@@ -437,16 +434,12 @@ public class Cocos2dxHelper {
public static void onResume() {
sActivityVisible = true;
if (Cocos2dxHelper.sAccelerometerEnabled) {
Cocos2dxHelper.sCocos2dxAccelerometer.enable();
}
Cocos2dxHelper.sCocos2dxAccelerometer.enable();
}
public static void onPause() {
sActivityVisible = false;
if (Cocos2dxHelper.sAccelerometerEnabled) {
Cocos2dxHelper.sCocos2dxAccelerometer.disable();
}
Cocos2dxHelper.sCocos2dxAccelerometer.disable();
}
public static void onEnterBackground() {

View File

@@ -1,4 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.cocos2dx.lib">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
</manifest>

View File

@@ -3,7 +3,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
buildToolsVersion PROP_BUILD_TOOLS_VERSION
namespace "org.cocos2dx.lib"
defaultConfig {
minSdkVersion PROP_MIN_SDK_VERSION
targetSdkVersion PROP_TARGET_SDK_VERSION

View File

@@ -265,7 +265,8 @@ void Device::vibrate(float duration)
}
float Device::getBatteryLevel()
{
{
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
return [UIDevice currentDevice].batteryLevel;
}

View File

@@ -46,4 +46,33 @@ THE SOFTWARE.
//#define GL_MAX_SAMPLES_APPLE GL_MAX_SAMPLES
#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
#endif // CC_PLATFORM_IOS

View File

@@ -0,0 +1,86 @@
/****************************************************************************
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "AppDelegate.h"
#include "cocos2d.h"
#include "cocos/scripting/js-bindings/manual/jsb_module_register.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/event/EventDispatcher.h"
#include "cocos/scripting/js-bindings/manual/jsb_classtype.hpp"
USING_NS_CC;
AppDelegate::AppDelegate(int width, int height) : Application("Cocos Game", width, height)
{
}
AppDelegate::~AppDelegate()
{
}
bool AppDelegate::applicationDidFinishLaunching()
{
se::ScriptEngine *se = se::ScriptEngine::getInstance();
jsb_set_xxtea_key("");
jsb_init_file_operation_delegate();
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
// Enable debugger here
jsb_enable_debugger("0.0.0.0", 6086, false);
#endif
se->setExceptionCallback([](const char *location, const char *message, const char *stack) {
// Send exception information to server like Tencent Bugly.
cocos2d::log("\nUncaught Exception:\n - location : %s\n - msg : %s\n - detail : \n %s\n", location, message, stack);
});
jsb_register_all_modules();
se->start();
se::AutoHandleScope hs;
// jsb_run_script("jsb-adapter/jsb-builtin.js");
// jsb_run_script("main.js");
se->addAfterCleanupHook([]() {
JSBClassType::destroy();
});
return true;
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::onPause()
{
}
// this function will be called when the app is active again
void AppDelegate::onResume()
{
}

View File

@@ -0,0 +1,55 @@
/****************************************************************************
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "platform/CCApplication.h"
/**
@brief The cocos2d Application.
The reason for implement as private inheritance is to hide some interface call by Director.
*/
class AppDelegate : public cocos2d::Application
{
public:
AppDelegate(int width, int height);
virtual ~AppDelegate();
/**
@brief Implement Director and Scene init code here.
@return true Initialize success, app continue.
@return false Initialize failed, app terminate.
*/
virtual bool applicationDidFinishLaunching() override;
/**
@brief The function be called when the application is paused
*/
virtual void onPause() override;
/**
@brief The function be called when the application is resumed
*/
virtual void onResume() override;
};

View File

@@ -0,0 +1,143 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include "platform/CCDevice.h"
#include "platform/openharmony/napi/NapiHelper.h"
NS_CC_BEGIN
int Device::getDPI() {
float value;
NapiHelper::napiCallFunction("getDPI", &value);
return value;
}
int Device::getDevicePixelRatio() {
// float value;
// NapiHelper::napiCallFunction("getPixelRation", &value);
// return value;
// TODO(qgh):openharmony does support this interface, but returning a value of 1.5 will cause the entire page to zoom in.
return 1;
}
void Device::setKeepScreenOn(bool value) {
CC_UNUSED_PARAM(value);
}
cocos2d::Vec4 Device::getSafeAreaEdge() {
return cocos2d::Vec4();
}
Device::Rotation Device::getDeviceRotation() {
int32_t value = 0;
NapiHelper::napiCallFunction("getDeviceOrientation", &value);
if(value == 0) {
return cocos2d::Device::Rotation::_0;
} else if(value == 1) {
// TODO(qgh): The openharmony platform is rotated clockwise.
return cocos2d::Device::Rotation::_270;
} else if(value == 2) {
return cocos2d::Device::Rotation::_180;
} else if(value == 3) {
// TODO(qgh): The openharmony platform is rotated clockwise.
return cocos2d::Device::Rotation::_90;
}
CC_ASSERT(false);
return cocos2d::Device::Rotation::_0;
}
Device::NetworkType Device::getNetworkType() {
int32_t value;
NapiHelper::napiCallFunction("getNetworkType", &value);
if(value == 0) {
return cocos2d::Device::NetworkType::WWAN;
} else if(value == 1 or value == 3) {
return cocos2d::Device::NetworkType::LAN;
} else {
return cocos2d::Device::NetworkType::NONE;
}
}
float Device::getBatteryLevel() {
int32_t value;
NapiHelper::napiCallFunction("getBatteryLevel", &value);
return value;
}
const Device::MotionValue& Device::getDeviceMotionValue() {
std::vector<float> v;
NapiHelper::napiCallFunction<std::vector<float> >("getDeviceMotionValue", &v);
static MotionValue motionValue;
if (!v.empty()) {
motionValue.accelerationIncludingGravityX = v[0];
motionValue.accelerationIncludingGravityY = v[1];
motionValue.accelerationIncludingGravityZ = v[2];
motionValue.accelerationX = v[3];
motionValue.accelerationY = v[4];
motionValue.accelerationZ = v[5];
motionValue.rotationRateAlpha = v[6];
motionValue.rotationRateBeta = v[7];
motionValue.rotationRateGamma = v[8];
} else {
memset(&motionValue, 0, sizeof(motionValue));
}
return motionValue;
}
std::string Device::getDeviceModel() {
std::string str;
NapiHelper::napiCallFunction<std::string>("getDeviceModel", &str);
return str;
}
void Device::setAccelerometerEnabled(bool isEnabled) {
// if (isEnabled)
// {
// JniHelper::callStaticVoidMethod(JCLS_HELPER, "enableAccelerometer");
// }
// else
// {
// JniHelper::callStaticVoidMethod(JCLS_HELPER, "disableAccelerometer");
// }
}
void Device::setAccelerometerInterval(float interval) {
// JniHelper::callStaticVoidMethod(JCLS_HELPER, "setAccelerometerInterval", interval);
}
void Device::vibrate(float duration) {
int32_t value = 0;
NapiHelper::napiCallFunctionByFloatArgs("vibrate", duration, &value);
}
NS_CC_END
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY

View File

@@ -0,0 +1,80 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCGL_H__
#define __CCGL_H__
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#define glClearDepth glClearDepthf
#define glDeleteVertexArrays glDeleteVertexArraysOES
#define glGenVertexArrays glGenVertexArraysOES
#define glBindVertexArray glBindVertexArrayOES
#define glMapBuffer glMapBufferOES
#define glUnmapBuffer glUnmapBufferOES
#define glTexImage3D glTexImage3DOES
#define glCompressedTexImage3D glCompressedTexImage3DOES
#define glCompressedTexSubImage3D glCompressedTexSubImage3DOES
#define glTexSubImage3D glTexSubImage3DOES
#define glDepthRange glDepthRangef
#define glSubImage3D glSubImage3DOES
#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES
#define GL_WRITE_ONLY GL_WRITE_ONLY_OES
// GL_GLEXT_PROTOTYPES isn't defined in glplatform.h on android ndk r7
// we manually define it here
#include <GLES2/gl2platform.h>
#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES 1
#endif
// normal process
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
// gl2.h doesn't define GLchar on Android
typedef char GLchar;
// android defines GL_BGRA_EXT but not GL_BRGA
#ifndef GL_BGRA
#define GL_BGRA 0x80E1
#endif
//declare here while define in EGLView_android.cpp
extern PFNGLGENVERTEXARRAYSOESPROC glGenVertexArraysOESEXT;
extern PFNGLBINDVERTEXARRAYOESPROC glBindVertexArrayOESEXT;
extern PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArraysOESEXT;
#define glGenVertexArraysOES glGenVertexArraysOESEXT
#define glBindVertexArrayOES glBindVertexArrayOESEXT
#define glDeleteVertexArraysOES glDeleteVertexArraysOESEXT
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#endif // __CCGL_H__

View File

@@ -0,0 +1,66 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCPLATFORMDEFINE_H__
#define __CCPLATFORMDEFINE_H__
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_OPENHARMONY
#include <sys/types.h>
#include <hilog/log.h>
#define CC_DLL
#define CC_NO_MESSAGE_PSEUDOASSERT(cond) \
if (!(cond)) { \
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "HMG_LOG", \
"assert file:%{public}s function:%{public}s line:%{public}d", \
__FILE__, __FUNCTION__, __LINE__); \
}
#define CC_MESSAGE_PSEUDOASSERT(cond, msg) \
if (!(cond)) { \
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "HMG_LOG", \
"assert file:%{public}s function:%{public}s line:%{public}d, %{public}s", \
__FILE__, __FUNCTION__, __LINE__, msg); \
}
#define CC_ASSERT(cond) CC_NO_MESSAGE_PSEUDOASSERT(cond)
#define CC_UNUSED_PARAM(unusedparam) (void)unusedparam
/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#endif /* __CCPLATFORMDEFINE_H__*/

View File

@@ -0,0 +1,233 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "cocos/platform/openharmony/FileUtils-openharmony.h"
#include <hilog/log.h>
#include <sys/stat.h>
#include <cstdio>
#include <regex>
#include <string>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <assert.h>
#include "base/CCLog.h"
#include "scripting/js-bindings/jswrapper/napi/HelperMacros.h"
#define ASSETS_FOLDER_WRITEABLE_PATH "/data/accounts/account_0/applications/ohos.example.xcomponent1/ohos.example.xcomponent1/writeable_path"
#include "rawfile/raw_file_manager.h"
namespace cocos2d {
NativeResourceManager* FileUtilsOpenHarmony::_nativeResourceManager = nullptr;
FileUtils *createFileUtils() {
return new (std::nothrow) FileUtilsOpenHarmony();
}
FileUtilsOpenHarmony::FileUtilsOpenHarmony() {
// init();
}
std::string FileUtilsOpenHarmony::_ohWritablePath;
bool FileUtilsOpenHarmony::initResourceManager(napi_env env, napi_value param) {
_nativeResourceManager = OH_ResourceManager_InitNativeResourceManager(env, param);
return true;
}
FileUtils* FileUtils::getInstance()
{
if (s_sharedFileUtils == nullptr)
{
s_sharedFileUtils = new (std::nothrow) FileUtilsOpenHarmony();
if (!s_sharedFileUtils->init())
{
delete s_sharedFileUtils;
s_sharedFileUtils = nullptr;
cocos2d::log("ERROR: Could not init CCFileUtilsOpenHarmony");
}
}
return s_sharedFileUtils;
}
FileUtils::Status FileUtilsOpenHarmony::getContents(const std::string &filename, ResizableBuffer *buffer) {
if (filename.empty()) {
return FileUtils::Status::NotExists;
}
std::string fullPath = fullPathForFilename(filename);
if (fullPath.empty()) {
return FileUtils::Status::NotExists;
}
if (fullPath[0] == '/') {
return FileUtils::getContents(fullPath, buffer);
}
if (nullptr == _nativeResourceManager) {
cocos2d::log("[ERROR]ativeResourceManager is nullptr");
return FileUtils::Status::NotInitialized;
}
RawFile *rawFile = OH_ResourceManager_OpenRawFile(_nativeResourceManager, fullPath.c_str());
if (nullptr == rawFile) {
return FileUtils::Status::OpenFailed;
}
auto size = OH_ResourceManager_GetRawFileSize(rawFile);
buffer->resize(size);
assert(buffer->buffer());
int readsize = OH_ResourceManager_ReadRawFile(rawFile, buffer->buffer(), size);
// TODO(unknown): read error
if (readsize < size) {
if (readsize >= 0) {
buffer->resize(readsize);
}
OH_ResourceManager_CloseRawFile(rawFile);
return FileUtils::Status::ReadFailed;
}
OH_ResourceManager_CloseRawFile(rawFile);
return FileUtils::Status::OK;
}
FileUtilsOpenHarmony::~FileUtilsOpenHarmony() {
if(_nativeResourceManager)
OH_ResourceManager_ReleaseNativeResourceManager(_nativeResourceManager);
}
bool FileUtilsOpenHarmony::init() {
_defaultResRootPath = "";
return FileUtils::init();
}
bool FileUtilsOpenHarmony::isAbsolutePath(const std::string &strPath) const {
return !strPath.empty() && (strPath[0] == '/');
}
std::string FileUtilsOpenHarmony::getWritablePath() const {
std::string dir("");
if (_ohWritablePath.length() > 0)
{
dir.append(_ohWritablePath).append("/");
}
return dir;
}
bool FileUtilsOpenHarmony::isFileExistInternal(const std::string &strFilePath) const {
if (strFilePath.empty()) {
return false;
}
std::string strPath = strFilePath;
if (!isAbsolutePath(strPath)) { // Not absolute path, add the default root path at the beginning.
strPath.insert(0, _defaultResRootPath);
} else {
FILE *fp = fopen(strFilePath.c_str(), "r");
if (fp)
{
fclose(fp);
return true;
}
return false;
}
if (nullptr == _nativeResourceManager) {
cocos2d::log("[ERROR]ativeResourceManager is nullptr");
return false;
}
RawFile* rawFile = OH_ResourceManager_OpenRawFile(_nativeResourceManager, strPath.c_str());
if(rawFile) {
OH_ResourceManager_CloseRawFile(rawFile);
return true;
}
return false;
}
FileUtils::Status FileUtilsOpenHarmony::getRawFileDescriptor(const std::string &filename,RawFileDescriptor& descriptor) {
if (filename.empty()) {
return FileUtils::Status::NotExists;
}
std::string fullPath = fullPathForFilename(filename);
if (fullPath.empty()) {
return FileUtils::Status::NotExists;
}
if (nullptr == _nativeResourceManager) {
cocos2d::log("[ERROR]ativeResourceManager is nullptr");
return FileUtils::Status::NotInitialized;
}
RawFile *rawFile = OH_ResourceManager_OpenRawFile(_nativeResourceManager, fullPath.c_str());
if (nullptr == rawFile) {
return FileUtils::Status::OpenFailed;
}
bool result = OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor);
if (!result) {
OH_ResourceManager_CloseRawFile(rawFile);
return FileUtils::Status::OpenFailed;
}
OH_ResourceManager_CloseRawFile(rawFile);
return FileUtils::Status::OK;
}
bool FileUtilsOpenHarmony::isDirectoryExistInternal(const std::string &dirPath) const {
if (dirPath.empty()) return false;
std::string dirPathMf = dirPath[dirPath.length() - 1] == '/' ? dirPath.substr(0, dirPath.length() - 1) : dirPath;
if (dirPathMf[0] == '/') {
struct stat st;
return stat(dirPathMf.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
}
if (dirPathMf.find(_defaultResRootPath) == 0) {
dirPathMf = dirPathMf.substr(_defaultResRootPath.length(), dirPathMf.length());
}
if (nullptr == _nativeResourceManager) {
cocos2d::log("[ERROR]ativeResourceManager is nullptr");
return false;
}
RawDir* rawDir = OH_ResourceManager_OpenRawDir(_nativeResourceManager, dirPathMf.c_str());
if(rawDir) {
OH_ResourceManager_CloseRawDir(rawDir);
return true;
}
return false;
}
} // namespace cc

View File

@@ -0,0 +1,66 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
//clang-format off
#include <cstdint>
//clang-format on
#include <rawfile/raw_dir.h>
#include <rawfile/raw_file.h>
#include <rawfile/raw_file_manager.h>
#include "cocos/platform/CCFileUtils.h"
#include <napi/native_api.h>
class NativeResourceManager;
namespace cocos2d {
class CC_DLL FileUtilsOpenHarmony : public FileUtils {
public:
FileUtilsOpenHarmony();
virtual ~FileUtilsOpenHarmony() override;
static bool initResourceManager(napi_env env, napi_value info);
bool init() override;
bool isAbsolutePath(const std::string &strPath) const override;
FileUtils::Status getRawFileDescriptor(const std::string &filename,RawFileDescriptor& descriptor);
virtual std::string getWritablePath() const override;
virtual FileUtils::Status getContents(const std::string &filename, ResizableBuffer *buffer) override;
static std::string _ohWritablePath;
private:
virtual bool isFileExistInternal(const std::string &strFilePath) const override;
virtual bool isDirectoryExistInternal(const std::string &dirPath) const override;
friend class FileUtils;
static NativeResourceManager* _nativeResourceManager;
};
} // namespace cc

View File

@@ -0,0 +1,291 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/openharmony/OpenHarmonyPlatform.h"
#include "platform/CCPlatformDefine.h"
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <napi/native_api.h>
#include "cocos2d.h"
#include "cocos/scripting/js-bindings/manual/jsb_module_register.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_global.h"
#include "cocos/scripting/js-bindings/event/EventDispatcher.h"
#include "cocos/scripting/js-bindings/manual/jsb_classtype.hpp"
#include "base/CCScheduler.h"
#include "cocos/scripting/js-bindings/event/EventDispatcher.h"
#include <sstream>
#include <chrono>
namespace {
void sendMsgToWorker(const cocos2d::MessageType& type, void* component, void* window) {
cocos2d::OpenHarmonyPlatform* platform = cocos2d::OpenHarmonyPlatform::getInstance();
cocos2d::WorkerMessageData data{type, static_cast<void*>(component), window};
platform->enqueue(data);
}
void onSurfaceCreatedCB(OH_NativeXComponent* component, void* window) {
sendMsgToWorker(cocos2d::MessageType::WM_XCOMPONENT_SURFACE_CREATED, component, window);
}
void dispatchTouchEventCB(OH_NativeXComponent* component, void* window) {
OH_NativeXComponent_TouchEvent touchEvent;
int32_t ret = OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent);
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
return;
}
cocos2d::TouchEvent* ev = new cocos2d::TouchEvent;
if (touchEvent.type == OH_NATIVEXCOMPONENT_DOWN) {
ev->type = cocos2d::TouchEvent::Type::BEGAN;
} else if (touchEvent.type == OH_NATIVEXCOMPONENT_MOVE) {
ev->type = cocos2d::TouchEvent::Type::MOVED;
} else if (touchEvent.type == OH_NATIVEXCOMPONENT_UP) {
ev->type = cocos2d::TouchEvent::Type::ENDED;
} else if (touchEvent.type == OH_NATIVEXCOMPONENT_CANCEL) {
ev->type = cocos2d::TouchEvent::Type::CANCELLED;
}
for(int i = 0; i < touchEvent.numPoints; ++i) {
cocos2d::TouchInfo touchInfo;
touchInfo.index = touchEvent.touchPoints[i].id;
touchInfo.x = touchEvent.touchPoints[i].x;
touchInfo.y = touchEvent.touchPoints[i].y;
if (touchEvent.id == touchInfo.index) {
ev->touches.push_back(touchInfo);
}
}
sendMsgToWorker(cocos2d::MessageType::WM_XCOMPONENT_TOUCH_EVENT, reinterpret_cast<void*>(ev), window);
}
void onSurfaceChangedCB(OH_NativeXComponent* component, void* window) {
sendMsgToWorker(cocos2d::MessageType::WM_XCOMPONENT_SURFACE_CHANGED, component, window);
}
void onSurfaceDestroyedCB(OH_NativeXComponent* component, void* window) {
sendMsgToWorker(cocos2d::MessageType::WM_XCOMPONENT_SURFACE_DESTROY, component, window);
}
bool setCanvasCallback(se::Object* global) {
cocos2d::OpenHarmonyPlatform* platform = cocos2d::OpenHarmonyPlatform::getInstance();
uint32_t innerWidth = (uint32_t)platform->width_;
uint32_t innerHeight = (uint32_t)platform->height_;
global->setProperty("innerWidth", se::Value(innerWidth));
global->setProperty("innerHeight", se::Value(innerHeight));
LOGD("exit setCanvasCallback setCanvasCallback");
return true;
}
} // namespace
namespace cocos2d {
OpenHarmonyPlatform::OpenHarmonyPlatform() {
_callback.OnSurfaceCreated = onSurfaceCreatedCB;
_callback.OnSurfaceChanged = onSurfaceChangedCB;
_callback.OnSurfaceDestroyed = onSurfaceDestroyedCB;
_callback.DispatchTouchEvent = dispatchTouchEventCB;
}
int32_t OpenHarmonyPlatform::init() {
return 0;
}
OpenHarmonyPlatform* OpenHarmonyPlatform::getInstance() {
static OpenHarmonyPlatform platform;
return &platform;
}
int32_t OpenHarmonyPlatform::run(int argc, const char** argv) {
LOGD("begin openharmonyplatform run");
int width = static_cast<int>(width_);
int height = static_cast<int>(height_);
g_app = new AppDelegate(width, height);
g_app->applicationDidFinishLaunching();
EventDispatcher::init();
g_started = true;
LOGD("end openharmonyplatform run");
return 0;
}
void OpenHarmonyPlatform::setNativeXComponent(OH_NativeXComponent* component) {
_component = component;
OH_NativeXComponent_RegisterCallback(_component, &_callback);
}
void OpenHarmonyPlatform::enqueue(const WorkerMessageData& msg) {
_messageQueue.enqueue(msg);
triggerMessageSignal();
}
void OpenHarmonyPlatform::triggerMessageSignal() {
if(_workerLoop != nullptr) {
// It is possible that when the message is sent, the worker thread has not yet started.
uv_async_send(&_messageSignal);
}
}
bool OpenHarmonyPlatform::dequeue(WorkerMessageData* msg) {
return _messageQueue.dequeue(msg);
}
// static
void OpenHarmonyPlatform::onMessageCallback(const uv_async_t* /* req */) {
void* window = nullptr;
WorkerMessageData msgData;
OpenHarmonyPlatform* platform = OpenHarmonyPlatform::getInstance();
while (true) {
//loop until all msg dispatch
if (!platform->dequeue(reinterpret_cast<WorkerMessageData*>(&msgData))) {
// Queue has no data
break;
}
if ((msgData.type >= MessageType::WM_XCOMPONENT_SURFACE_CREATED) && (msgData.type <= MessageType::WM_XCOMPONENT_SURFACE_DESTROY)) {
if (msgData.type == MessageType::WM_XCOMPONENT_TOUCH_EVENT) {
TouchEvent* ev = reinterpret_cast<TouchEvent*>(msgData.data);
EventDispatcher::dispatchTouchEvent(*ev);
delete ev;
ev = nullptr;
} else if (msgData.type == MessageType::WM_XCOMPONENT_SURFACE_CREATED) {
OH_NativeXComponent* nativexcomponet = reinterpret_cast<OH_NativeXComponent*>(msgData.data);
CC_ASSERT(nativexcomponet != nullptr);
platform->onSurfaceCreated(nativexcomponet, msgData.window);
} else if (msgData.type == MessageType::WM_XCOMPONENT_SURFACE_CHANGED) {
OH_NativeXComponent* nativexcomponet = reinterpret_cast<OH_NativeXComponent*>(msgData.data);
CC_ASSERT(nativexcomponet != nullptr);
platform->onSurfaceChanged(nativexcomponet, msgData.window);
} else if (msgData.type == MessageType::WM_XCOMPONENT_SURFACE_DESTROY) {
OH_NativeXComponent* nativexcomponet = reinterpret_cast<OH_NativeXComponent*>(msgData.data);
CC_ASSERT(nativexcomponet != nullptr);
platform->onSurfaceDestroyed(nativexcomponet, msgData.window);
} else {
CC_ASSERT(false);
}
continue;
}
if (msgData.type == MessageType::WM_APP_SHOW) {
platform->onShowNative();
} else if (msgData.type == MessageType::WM_APP_HIDE) {
platform->onHideNative();
} else if (msgData.type == MessageType::WM_APP_DESTROY) {
platform->onDestroyNative();
}
}
}
void OpenHarmonyPlatform::onCreateNative(napi_env env, uv_loop_t* loop) {
LOGD("OpenHarmonyPlatform::onCreateNative");
}
void OpenHarmonyPlatform::onShowNative() {
LOGD("OpenHarmonyPlatform::onShowNative");
EventDispatcher::dispatchOnResumeEvent();
}
void OpenHarmonyPlatform::onHideNative() {
LOGD("OpenHarmonyPlatform::onHideNative");
EventDispatcher::dispatchOnPauseEvent();
}
void OpenHarmonyPlatform::onDestroyNative() {
LOGD("OpenHarmonyPlatform::onDestroyNative");
}
void OpenHarmonyPlatform::timerCb(uv_timer_t* handle) {
if(OpenHarmonyPlatform::getInstance()->eglCore_ != nullptr){
OpenHarmonyPlatform::getInstance()->tick();
OpenHarmonyPlatform::getInstance()->eglCore_->Update();
}
}
void OpenHarmonyPlatform::workerInit(napi_env env, uv_loop_t* loop) {
_workerLoop = loop;
if (_workerLoop) {
uv_async_init(_workerLoop, &_messageSignal, reinterpret_cast<uv_async_cb>(OpenHarmonyPlatform::onMessageCallback));
if (!_messageQueue.empty()) {
triggerMessageSignal(); // trigger the signal to handle the pending message
}
}
}
void OpenHarmonyPlatform::requestVSync() {
// OH_NativeVSync_RequestFrame(OpenHarmonyPlatform::getInstance()->_nativeVSync, OnVSync, nullptr);
if (_workerLoop) {
// Todo: Starting the timer in this way is inaccurate and will be fixed later.
uv_timer_init(_workerLoop, &_timerHandle);
// The tick function needs to be called as quickly as possible because it is controlling the frame rate inside the engine.
uv_timer_start(&_timerHandle, &OpenHarmonyPlatform::timerCb, 0, 1);
}
}
int32_t OpenHarmonyPlatform::loop() {
return 0;
}
void OpenHarmonyPlatform::onSurfaceCreated(OH_NativeXComponent* component, void* window) {
eglCore_ = new EGLCore();
int32_t ret=OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_);
if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
eglCore_->GLContextInit(window, width_, height_);
se::ScriptEngine *scriptEngine = se::ScriptEngine::getInstance();
scriptEngine->addRegisterCallback(setCanvasCallback);
if(g_app!=nullptr){
OpenHarmonyPlatform* platform = OpenHarmonyPlatform::getInstance();
g_app->updateViewSize(static_cast<float>(platform->width_), static_cast<float>(platform->height_));
}
LOGD("egl init finished.");
}
}
void OpenHarmonyPlatform::onSurfaceChanged(OH_NativeXComponent* component, void* window) {
int32_t ret = OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_);
// nativeOnSizeChanged is firstly called before Application initiating.
if (g_app != nullptr) {
g_app->updateViewSize(width_, height_);
}
}
void OpenHarmonyPlatform::onSurfaceDestroyed(OH_NativeXComponent* component, void* window) {
}
void OpenHarmonyPlatform::tick() {
static std::chrono::steady_clock::time_point prevTime;
static std::chrono::steady_clock::time_point now;
static float dt = 0.f;
static float dtSum = 0.f;
static uint32_t jsbInvocationTotalCount = 0;
static uint32_t jsbInvocationTotalFrames = 0;
std::shared_ptr<Scheduler> scheduler = g_app->getScheduler();
scheduler->update(dt);
EventDispatcher::dispatchTickEvent(dt);
PoolManager::getInstance()->getCurrentPool()->clear();
now = std::chrono::steady_clock::now();
dt = std::chrono::duration_cast<std::chrono::microseconds>(now - prevTime).count() / 1000000.f;
prevTime = std::chrono::steady_clock::now();
}
}; // namespace cc

View File

@@ -0,0 +1,96 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
// #include "platform/UniversalPlatform.h"
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <uv.h>
#include <string>
#include <unordered_map>
#include <napi/native_api.h>
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "platform/openharmony/WorkerMessageQueue.h"
#include "scripting/js-bindings/event/EventDispatcher.h"
#include "platform/openharmony/render/egl_core.h"
#include "platform/openharmony/AppDelegate.h"
namespace cocos2d {
#define NANOSECONDS_PER_SECOND 1000000000
#define NANOSECONDS_60FPS 16666667L
class OpenHarmonyPlatform {
public:
OpenHarmonyPlatform();
int32_t init();
static OpenHarmonyPlatform* getInstance();
void onCreateNative(napi_env env, uv_loop_t* loop);
void onShowNative();
void onHideNative();
void onDestroyNative();
void workerInit(napi_env env, uv_loop_t* loop);
void setNativeXComponent(OH_NativeXComponent* component);
int32_t run(int argc, const char** argv);
void resume();
void pause();
int32_t loop();
void requestVSync();
void enqueue(const WorkerMessageData& data);
bool dequeue(WorkerMessageData* data);
void triggerMessageSignal();
public:
// Callback, called by ACE XComponent
void onSurfaceCreated(OH_NativeXComponent* component, void* window);
void onSurfaceChanged(OH_NativeXComponent* component, void* window);
void onSurfaceDestroyed(OH_NativeXComponent* component, void* window);
void dispatchTouchEvent(OH_NativeXComponent* component, void* window);
static void onMessageCallback(const uv_async_t* req);
static void timerCb(uv_timer_t* handle);
void tick();
OH_NativeXComponent* _component{nullptr};
OH_NativeXComponent_Callback _callback;
uv_timer_t _timerHandle;
uv_loop_t* _workerLoop{nullptr};
uv_async_t _messageSignal{};
WorkerMessageQueue _messageQueue;
EGLCore* eglCore_{nullptr};
uint64_t width_;
uint64_t height_;
Application* g_app = nullptr;
//game started
bool g_started = false;
};
} // namespace cc

View File

@@ -0,0 +1,49 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/openharmony/WorkerMessageQueue.h"
namespace cocos2d {
void WorkerMessageQueue::enqueue(const WorkerMessageData& data) {
std::lock_guard<std::mutex> lck(_mutex);
_queue.push(data);
}
bool WorkerMessageQueue::dequeue(WorkerMessageData *data) {
std::lock_guard<std::mutex> lck(_mutex);
if (empty()) {
return false;
}
*data = _queue.front();
_queue.pop();
return true;
}
bool WorkerMessageQueue::empty() const {
return _queue.empty();
}
} // namespace cocos2d

View File

@@ -0,0 +1,67 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <queue>
#include <thread>
#include <mutex>
namespace cocos2d {
enum class MessageType {
WM_XCOMPONENT_SURFACE_CREATED = 0,
WM_XCOMPONENT_TOUCH_EVENT,
WM_XCOMPONENT_SURFACE_CHANGED,
WM_XCOMPONENT_SURFACE_DESTROY,
WM_APP_SHOW,
WM_APP_HIDE,
WM_APP_DESTROY,
WM_VSYNC,
};
struct WorkerMessageData {
MessageType type;
void* data;
void* window;
};
class WorkerMessageQueue final {
public:
void enqueue(const WorkerMessageData& data);
bool dequeue(WorkerMessageData *data);
bool empty() const;
size_t size() const {
return _queue.size();
}
private:
std::mutex _mutex;
std::queue<WorkerMessageData> _queue;
};
} // namespace cc

View File

@@ -0,0 +1,280 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/CCApplication.h"
#include "platform/openharmony/napi/NapiHelper.h"
#include "base/CCScheduler.h"
#include "base/CCConfiguration.h"
#include "audio/include/AudioEngine.h"
#include "scripting/js-bindings/event/EventDispatcher.h"
#include "platform/openharmony/OpenHarmonyPlatform.h"
PFNGLGENVERTEXARRAYSOESPROC glGenVertexArraysOESEXT = 0;
PFNGLBINDVERTEXARRAYOESPROC glBindVertexArrayOESEXT = 0;
PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArraysOESEXT = 0;
NS_CC_BEGIN
void Application::updateViewSize(int width, int height)
{
if(width <= 0 || height <= 0)
{
return;
}
_viewSize.x = width;
_viewSize.y = height;
// handle resize event
Application::getInstance()->getScheduler()->performFunctionInCocosThread([=]() {
EventDispatcher::dispatchResizeEvent(width, height);
});
}
Application* Application::_instance = nullptr;
std::shared_ptr<Scheduler> Application::_scheduler = nullptr;
Application::Application(const std::string& name, int width, int height)
{
Application::_instance = this;
Configuration::getInstance();
_scheduler = std::make_shared<Scheduler>();
_renderTexture = new RenderTexture(width, height);
updateViewSize(width, height);
}
Application::~Application()
{
#if USE_AUDIO
AudioEngine::end();
#endif
EventDispatcher::destroy();
se::ScriptEngine::destroyInstance();
delete _renderTexture;
_renderTexture = nullptr;
Application::_instance = nullptr;
}
void Application::start()
{
if(!applicationDidFinishLaunching())
return;
}
void Application::restart()
{
// restartJSVM();
}
void Application::end()
{
int32_t value;
NapiHelper::napiCallFunction("terminateProcess", &value);
}
void Application::setMultitouch(bool /*value*/)
{
}
bool Application::applicationDidFinishLaunching()
{
return true;
}
void Application::onPause()
{
}
void Application::onResume()
{
}
void Application::setPreferredFramesPerSecond(int fps)
{
_fps = fps;
// setPreferredFramesPerSecondJNI(_fps);
}
bool Application::isDisplayStats() {
se::AutoHandleScope hs;
se::Value ret;
char commandBuf[100] = "cc.debug.isDisplayStats();";
se::ScriptEngine::getInstance()->evalString(commandBuf, 100, &ret);
return ret.toBoolean();
}
void Application::setDisplayStats(bool isShow) {
se::AutoHandleScope hs;
char commandBuf[100] = {0};
sprintf(commandBuf, "cc.debug.setDisplayStats(%s);", isShow ? "true" : "false");
se::ScriptEngine::getInstance()->evalString(commandBuf);
}
std::string Application::getCurrentLanguageCode() const {
std::string str;
NapiHelper::napiCallFunction<std::string>("getSystemLanguage", &str);
std::string::size_type pos = str.find('-');
if(pos != std::string::npos) {
str = str.substr(0, pos);
}
return str;
}
Application::LanguageType Application::getCurrentLanguage() const
{
std::string languageName = getCurrentLanguageCode(); // NOLINT
const char* pLanguageName = languageName.c_str();
LanguageType ret = LanguageType::ENGLISH;
if (0 == strcmp("zh", pLanguageName))
{
ret = LanguageType::CHINESE;
}
else if (0 == strcmp("en", pLanguageName))
{
ret = LanguageType::ENGLISH;
}
else if (0 == strcmp("fr", pLanguageName))
{
ret = LanguageType::FRENCH;
}
else if (0 == strcmp("it", pLanguageName))
{
ret = LanguageType::ITALIAN;
}
else if (0 == strcmp("de", pLanguageName))
{
ret = LanguageType::GERMAN;
}
else if (0 == strcmp("es", pLanguageName))
{
ret = LanguageType::SPANISH;
}
else if (0 == strcmp("ru", pLanguageName))
{
ret = LanguageType::RUSSIAN;
}
else if (0 == strcmp("nl", pLanguageName))
{
ret = LanguageType::DUTCH;
}
else if (0 == strcmp("ko", pLanguageName))
{
ret = LanguageType::KOREAN;
}
else if (0 == strcmp("ja", pLanguageName))
{
ret = LanguageType::JAPANESE;
}
else if (0 == strcmp("hu", pLanguageName))
{
ret = LanguageType::HUNGARIAN;
}
else if (0 == strcmp("pt", pLanguageName))
{
ret = LanguageType::PORTUGUESE;
}
else if (0 == strcmp("ar", pLanguageName))
{
ret = LanguageType::ARABIC;
}
else if (0 == strcmp("nb", pLanguageName))
{
ret = LanguageType::NORWEGIAN;
}
else if (0 == strcmp("pl", pLanguageName))
{
ret = LanguageType::POLISH;
}
else if (0 == strcmp("tr", pLanguageName))
{
ret = LanguageType::TURKISH;
}
else if (0 == strcmp("uk", pLanguageName))
{
ret = LanguageType::UKRAINIAN;
}
else if (0 == strcmp("ro", pLanguageName))
{
ret = LanguageType::ROMANIAN;
}
else if (0 == strcmp("bg", pLanguageName))
{
ret = LanguageType::BULGARIAN;
}
return ret;
}
Application::Platform Application::getPlatform() const
{
return Platform::OpenHarmony;
}
float Application::getScreenScale() const
{
return 1.f;
}
GLint Application::getMainFBO() const
{
return _mainFBO;
}
void Application::onCreateView(PixelFormat& /*pixelformat*/, DepthFormat& /*depthFormat*/, int& /*multisamplingCount*/)
{
}
bool Application::openURL(const std::string &url)
{
return false;
}
void Application::copyTextToClipboard(const std::string &text)
{
// copyTextToClipboardJNI(text);
}
std::string Application::getSystemVersion()
{
std::string str;
NapiHelper::napiCallFunction<std::string>("getOSFullName", &str);
return str;
}
const cocos2d::Vec2& Application::getViewSize() const
{
return _viewSize;
}
NS_CC_END

View File

@@ -0,0 +1,718 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. \
****************************************************************************/
#include <array>
#include <regex>
#include <memory>
#include "base/csscolorparser.hpp"
#include "cocos/scripting/js-bindings/manual/jsb_platform.h"
#include "math/CCMath.h"
#include "base/CCData.h"
#include "platform/CCCanvasRenderingContext2D.h"
//#include "platform/openharmony/OpenHarmonyPlatform.h"
#include <native_drawing/drawing_text_typography.h>
#include <native_drawing/drawing_canvas.h>
#include <native_drawing/drawing_font_collection.h>
#include <native_drawing/drawing_types.h>
#include <native_drawing/drawing_path.h>
#include <native_drawing/drawing_bitmap.h>
#include <native_drawing/drawing_text_declaration.h>
#include <native_drawing/drawing_brush.h>
using namespace cocos2d;
enum class TextAlign {
LEFT,
CENTER,
RIGHT
};
enum class TextBaseline {
TOP,
MIDDLE,
BOTTOM,
ALPHABETIC
};
class ScopedTypography {
public:
ScopedTypography(OH_Drawing_Typography* typography) :_typegraphy(typography) {}
~ScopedTypography() {
if(_typegraphy) {
OH_Drawing_DestroyTypography(_typegraphy);
}
}
OH_Drawing_Typography* get() {
return _typegraphy;
}
private:
OH_Drawing_Typography* _typegraphy{nullptr};
};
class CanvasRenderingContext2DImpl {
public:
using Point = std::array<float, 2>;
using Vec2 = std::array<float, 2>;
using Size = std::array<float, 2>;
using Color4F = std::array<float, 4>;
CanvasRenderingContext2DImpl() {
_typographyStyle = OH_Drawing_CreateTypographyStyle();
OH_Drawing_SetTypographyTextDirection(_typographyStyle, TEXT_DIRECTION_LTR);
OH_Drawing_SetTypographyTextAlign(_typographyStyle, TEXT_ALIGN_LEFT);
_fontCollection = OH_Drawing_CreateFontCollection();
_typographyCreate = OH_Drawing_CreateTypographyHandler(_typographyStyle, _fontCollection);
_textStyle = OH_Drawing_CreateTextStyle();
}
~CanvasRenderingContext2DImpl() {
if(_typographyStyle) {
OH_Drawing_DestroyTypographyStyle(_typographyStyle);
_typographyStyle = nullptr;
}
if(_fontCollection) {
OH_Drawing_DestroyFontCollection(_fontCollection);
}
if(_typographyCreate) {
OH_Drawing_DestroyTypographyHandler(_typographyCreate);
_typographyCreate = nullptr;
}
if(_textStyle) {
OH_Drawing_DestroyTextStyle(_textStyle);
_textStyle = nullptr;
}
if(_canvas) {
OH_Drawing_CanvasDestroy(_canvas);
_canvas = nullptr;
}
if(_bitmap) {
OH_Drawing_BitmapDestroy(_bitmap);
_bitmap = nullptr;
}
}
void recreateBuffer(float w, float h) {
_bufferWidth = w;
_bufferHeight = h;
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
if (_canvas) {
OH_Drawing_CanvasDestroy(_canvas);
_canvas = nullptr;
}
if (_bitmap) {
OH_Drawing_BitmapDestroy(_bitmap);
_bitmap = nullptr;
}
_bufferSize = static_cast<int>(_bufferWidth * _bufferHeight * 4);
auto *data = static_cast<uint8_t *>(malloc(sizeof(uint8_t) * _bufferSize));
memset(data, 0x00, _bufferSize);
_imageData.fastSet(data, _bufferSize);
_bitmap = OH_Drawing_BitmapCreate();
OH_Drawing_BitmapBuild(_bitmap, _bufferWidth, _bufferHeight, &_format);
_canvas = OH_Drawing_CanvasCreate();
OH_Drawing_CanvasBind(_canvas, _bitmap);
}
void beginPath() {
}
void closePath() {
}
void moveTo(float x, float y) {
// MoveToEx(_DC, static_cast<int>(x), static_cast<int>(-(y - _bufferHeight - _fontSize)), nullptr);
_x = x;
_y = y;
}
void lineTo(float x, float y) {
}
void stroke() {
}
void saveContext() {
}
void restoreContext() {
}
void clearRect(float x, float y, float w, float h) {
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
if (_imageData.isNull()) {
return;
}
recreateBuffer(w, h);
}
void fillRect(float x, float y, float w, float h) {
if (_bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
uint8_t r = static_cast<uint8_t>(_fillStyle[0]);
uint8_t g = static_cast<uint8_t>(_fillStyle[1]);
uint8_t b = static_cast<uint8_t>(_fillStyle[2]);
uint8_t a = static_cast<uint8_t>(_fillStyle[3]);
OH_Drawing_Path* path = OH_Drawing_PathCreate();
OH_Drawing_PathMoveTo(path, x, y);
OH_Drawing_PathLineTo(path, x + w, y);
OH_Drawing_PathLineTo(path, x + w, y + h);
OH_Drawing_PathLineTo(path, x, y + h);
OH_Drawing_PathLineTo(path, x, y);
OH_Drawing_PathClose(path);
OH_Drawing_Brush* brush = OH_Drawing_BrushCreate();
OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(a, r, g, b));
OH_Drawing_CanvasAttachBrush(_canvas, brush);
OH_Drawing_CanvasDrawPath(_canvas, path);
}
void fillText(const std::string &text, float x, float y, float /*maxWidth*/) {
if (text.empty() || _bufferWidth < 1.0F || _bufferHeight < 1.0F) {
return;
}
Size textSize = {0, 0};
Point offsetPoint = convertDrawPoint(Point{x, y}, text);
drawText(text, offsetPoint[0], offsetPoint[1]);
}
void strokeText(const std::string &text, float /*x*/, float /*y*/, float /*maxWidth*/) const {
}
Size measureText(const std::string &text) {
auto typography = createTypography(text);
return std::array<float, 2>{static_cast<float>(OH_Drawing_TypographyGetMaxIntrinsicWidth(typography->get())),
static_cast<float>(OH_Drawing_TypographyGetHeight(typography->get()))};
}
void updateFont(const std::string &fontName,
float fontSize,
bool bold,
bool italic,
bool oblique,
bool /* smallCaps */) {
_fontName = fontName;
_fontSize = static_cast<int>(fontSize);
std::string fontPath;
if (!_fontName.empty()) {
const char* fontFamilies[1];
fontFamilies[0] = fontName.c_str();
OH_Drawing_SetTextStyleFontFamilies(_textStyle, 1, fontFamilies);
OH_Drawing_SetTextStyleLocale(_textStyle, "en");
}
if (_fontSize)
OH_Drawing_SetTextStyleFontSize(_textStyle, _fontSize);
if (bold)
OH_Drawing_SetTextStyleFontWeight(_textStyle, FONT_WEIGHT_700);
else
OH_Drawing_SetTextStyleFontWeight(_textStyle, FONT_WEIGHT_400);
if(italic)
OH_Drawing_SetTextStyleFontStyle(_textStyle, FONT_STYLE_ITALIC);
else
OH_Drawing_SetTextStyleFontStyle(_textStyle, FONT_STYLE_NORMAL);
}
void setTextAlign(TextAlign align) {
_textAlign = align;
}
void setTextBaseline(TextBaseline baseline) {
_textBaseLine = baseline;
}
void setFillStyle(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
_fillStyle = {static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a)};
OH_Drawing_SetTextStyleColor(_textStyle, OH_Drawing_ColorSetArgb(a, r, g, b));
}
void setStrokeStyle(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
_strokeStyle = {static_cast<float>(r), static_cast<float>(g), static_cast<float>(b), static_cast<float>(a)};
}
void setLineWidth(float lineWidth) {
_lineWidth = lineWidth;
}
const Data &getDataRef() const {
return _imageData;
}
void removeCustomFont() {
}
// x, y offset value
int drawText(const std::string &text, float x, float y) {
auto typography = createTypography(text);
OH_Drawing_TypographyPaint(typography->get(), _canvas, (double)x, (double)y);
void* bitmapAddr = OH_Drawing_BitmapGetPixels(_bitmap);
memcpy(_imageData.getBytes(), bitmapAddr, _bufferSize);
return 0;
}
Size sizeWithText(const wchar_t *pszText, int nLen) {
return std::array<float, 2>{0.0F, 0.0F};
}
void prepareBitmap(int nWidth, int nHeight) {
}
void deleteBitmap() {
}
void fillTextureData() {
}
std::array<float, 2> convertDrawPoint(Point point, const std::string &text) {
auto typography = createTypography(text);
Size textSize {static_cast<float>(OH_Drawing_TypographyGetMaxIntrinsicWidth(typography->get())),
static_cast<float>(OH_Drawing_TypographyGetHeight(typography->get()))};
if (_textAlign == TextAlign::CENTER) {
point[0] -= textSize[0] / 2.0f;
} else if (_textAlign == TextAlign::RIGHT) {
point[0] -= textSize[0];
}
double alphabeticBaseLine = OH_Drawing_TypographyGetAlphabeticBaseline(typography->get());
if (_textBaseLine == TextBaseline::TOP) {
//point[1] += -alphabeticBaseLine;
} else if (_textBaseLine == TextBaseline::MIDDLE) {
point[1] += -textSize[1] / 2.0f;
} else if (_textBaseLine == TextBaseline::BOTTOM) {
point[1] += -textSize[1];
} else if (_textBaseLine == TextBaseline::ALPHABETIC) {
//GetTextMetrics(_DC, &_tm);
//point[1] -= _tm.tmAscent;
point[1] -= alphabeticBaseLine;
}
return point;
}
std::unique_ptr<ScopedTypography> createTypography(const std::string &text) {
OH_Drawing_TypographyHandlerPushTextStyle(_typographyCreate, _textStyle);
OH_Drawing_TypographyHandlerAddText(_typographyCreate, text.c_str());
OH_Drawing_TypographyHandlerPopTextStyle(_typographyCreate);
OH_Drawing_Typography* typography = OH_Drawing_CreateTypography(_typographyCreate);
OH_Drawing_TypographyLayout(typography, _bufferWidth);
return std::make_unique<ScopedTypography>(typography);
}
void fill() {
}
void setLineCap(const std::string &lineCap) {
}
void setLineJoin(const std::string &lineJoin) {
}
void fillImageData(const Data & /* imageData */,
float /* imageWidth */,
float /* imageHeight */,
float /* offsetX */,
float /* offsetY */) {
}
void strokeText(const std::string & /* text */,
float /* x */,
float /* y */,
float /* maxWidth */) {
}
void rect(float /* x */,
float /* y */,
float /* w */,
float /* h */) {
}
void updateData() {
}
private:
int32_t _x{0};
int32_t _y{0};
int32_t _lineCap{0};
int32_t _lineJoin{0};
OH_Drawing_Bitmap* _bitmap{nullptr};
OH_Drawing_BitmapFormat _format {COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE};
OH_Drawing_Canvas* _canvas{nullptr};
OH_Drawing_TypographyStyle* _typographyStyle{nullptr};
OH_Drawing_TypographyCreate* _typographyCreate{nullptr};
OH_Drawing_FontCollection* _fontCollection{nullptr};
OH_Drawing_TextStyle* _textStyle{nullptr};
Data _imageData;
std::string _curFontPath;
int _savedDC{0};
float _lineWidth{0.0F};
float _bufferWidth{0.0F};
float _bufferHeight{0.0F};
int32_t _bufferSize{0};
std::string _fontName;
int _fontSize{0};
Size _textSize;
TextAlign _textAlign{TextAlign::CENTER};
TextBaseline _textBaseLine{TextBaseline::TOP};
Color4F _fillStyle{0};
Color4F _strokeStyle{0};
};
NS_CC_BEGIN
CanvasGradient::CanvasGradient()
{
// SE_LOGD("CanvasGradient constructor: %p\n", this);
}
CanvasGradient::~CanvasGradient()
{
// SE_LOGD("CanvasGradient destructor: %p\n", this);
}
void CanvasGradient::addColorStop(float offset, const std::string& color)
{
// SE_LOGD("CanvasGradient::addColorStop: %p\n", this);
}
// CanvasRenderingContext2D
CanvasRenderingContext2D::CanvasRenderingContext2D(float width, float height)
: __width(width)
, __height(height)
{
// SE_LOGD("CanvasRenderingContext2D constructor: %p, width: %f, height: %f\n", this, width, height);
_impl = new CanvasRenderingContext2DImpl();
recreateBufferIfNeeded();
}
CanvasRenderingContext2D::~CanvasRenderingContext2D()
{
// SE_LOGD("CanvasRenderingContext2D destructor: %p\n", this);
delete _impl;
}
void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height)
{
// SE_LOGD("CanvasRenderingContext2D::clearRect: %p, %f, %f, %f, %f\n", this, x, y, width, height);
recreateBufferIfNeeded();
_impl->clearRect(x, y, width, height);
}
void CanvasRenderingContext2D::fillRect(float x, float y, float width, float height)
{
recreateBufferIfNeeded();
_impl->fillRect(x, y, width, height);
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
void CanvasRenderingContext2D::fillText(const std::string& text, float x, float y, float maxWidth)
{
// SE_LOGD("CanvasRenderingContext2D::fillText: %s, %f, %f, %f\n", text.c_str(), x, y, maxWidth);
if (text.empty())
return;
recreateBufferIfNeeded();
_impl->fillText(text, x, y, maxWidth);
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
void CanvasRenderingContext2D::strokeText(const std::string& text, float x, float y, float maxWidth)
{
// SE_LOGD("CanvasRenderingContext2D::strokeText: %s, %f, %f, %f\n", text.c_str(), x, y, maxWidth);
if (text.empty())
return;
recreateBufferIfNeeded();
_impl->strokeText(text, x, y, maxWidth);
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
cocos2d::Size CanvasRenderingContext2D::measureText(const std::string& text)
{
// SE_LOGD("CanvasRenderingContext2D::measureText: %s\n", text.c_str());
auto s = _impl->measureText(text);
s[0] = ceil(s[0] * 100) / 100;
s[1] = ceil(s[1] * 100) / 100;
return cocos2d::Size(s[0], s[1]);
}
CanvasGradient* CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1)
{
return nullptr;
}
void CanvasRenderingContext2D::save()
{
_impl->saveContext();
}
void CanvasRenderingContext2D::beginPath()
{
_impl->beginPath();
}
void CanvasRenderingContext2D::closePath()
{
_impl->closePath();
}
void CanvasRenderingContext2D::moveTo(float x, float y)
{
_impl->moveTo(x, y);
}
void CanvasRenderingContext2D::lineTo(float x, float y)
{
_impl->lineTo(x, y);
}
void CanvasRenderingContext2D::stroke()
{
_impl->stroke();
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
void CanvasRenderingContext2D::restore()
{
_impl->restoreContext();
}
void CanvasRenderingContext2D::setCanvasBufferUpdatedCallback(const CanvasBufferUpdatedCallback& cb)
{
_canvasBufferUpdatedCB = cb;
}
void CanvasRenderingContext2D::setPremultiply(bool multiply)
{
_premultiply = multiply;
}
void CanvasRenderingContext2D::set__width(float width)
{
// SE_LOGD("CanvasRenderingContext2D::set__width: %f\n", width);
__width = width;
_isBufferSizeDirty = true;
recreateBufferIfNeeded();
}
void CanvasRenderingContext2D::set__height(float height)
{
// SE_LOGD("CanvasRenderingContext2D::set__height: %f\n", height);
__height = height;
_isBufferSizeDirty = true;
recreateBufferIfNeeded();
}
void CanvasRenderingContext2D::set_lineWidth(float lineWidth)
{
_lineWidth = lineWidth;
_impl->setLineWidth(lineWidth);
}
void CanvasRenderingContext2D::set_lineCap(const std::string& lineCap)
{
if(lineCap.empty()) return ;
_impl->setLineCap(lineCap);
}
void CanvasRenderingContext2D::set_lineJoin(const std::string& lineJoin)
{
if(lineJoin.empty()) return ;
_impl->setLineJoin(lineJoin);
}
void CanvasRenderingContext2D::fill()
{
_impl->fill();
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
void CanvasRenderingContext2D::rect(float x, float y, float width, float height)
{
// SE_LOGD("CanvasRenderingContext2D::rect: %p, %f, %f, %f, %f\n", this, x, y, width, height);
recreateBufferIfNeeded();
_impl->rect(x, y, width, height);
}
/*
* support format e.g.: "oblique bold small-caps 18px Arial"
* "italic bold small-caps 25px Arial"
* "italic 25px Arial"
* */
void CanvasRenderingContext2D::set_font(const std::string& font)
{
if (_font != font) {
_font = font;
std::string fontName = "sans-serif";
std::string fontSizeStr = "30";
std::regex re(R"(\s*((\d+)([\.]\d+)?)px\s+([^\r\n]*))");
std::match_results<std::string::const_iterator> results;
if (std::regex_search(_font.cbegin(), _font.cend(), results, re)) {
fontSizeStr = results[2].str();
// support get font name from `60px American` or `60px "American abc-abc_abc"`
// support get font name contain space,example `times new roman`
// if regex rule that does not conform to the rules,such as Chinese,it defaults to sans-serif
std::match_results<std::string::const_iterator> fontResults;
std::regex fontRe(R"(([\w\s-]+|"[\w\s-]+"$))");
std::string tmp(results[4].str());
if (std::regex_match(tmp, fontResults, fontRe)) {
fontName = results[4].str();
}
}
double fontSize = atof(fontSizeStr.c_str());
bool isBold = font.find("bold", 0) != std::string::npos || font.find("Bold", 0) != std::string::npos;
bool isItalic = font.find("italic", 0) != std::string::npos || font.find("Italic", 0) != std::string::npos;
bool isSmallCaps = font.find("small-caps", 0) != std::string::npos || font.find("Small-Caps") != std::string::npos;
bool isOblique = font.find("oblique", 0) != std::string::npos || font.find("Oblique", 0) != std::string::npos;
//font-style: italic, oblique, normal
//font-weight: normal, bold
//font-variant: normal, small-caps
_impl->updateFont(fontName, fontSize, isBold, isItalic, isOblique, isSmallCaps);
}
}
void CanvasRenderingContext2D::set_textAlign(const std::string& textAlign)
{
// SE_LOGD("CanvasRenderingContext2D::set_textAlign: %s\n", textAlign.c_str());
if (textAlign == "left") {
_impl->setTextAlign(TextAlign::LEFT);
} else if (textAlign == "center" || textAlign == "middle") {
_impl->setTextAlign(TextAlign::CENTER);
} else if (textAlign == "right") {
_impl->setTextAlign(TextAlign::RIGHT);
} else {
CC_ASSERT(false);
}
}
void CanvasRenderingContext2D::set_textBaseline(const std::string& textBaseline)
{
// SE_LOGD("CanvasRenderingContext2D::set_textBaseline: %s\n", textBaseline.c_str());
if (textBaseline == "top") {
_impl->setTextBaseline(TextBaseline::TOP);
} else if (textBaseline == "middle") {
_impl->setTextBaseline(TextBaseline::MIDDLE);
} else if (textBaseline == "bottom") //REFINE:, how to deal with alphabetic, currently we handle it as bottom mode.
{
_impl->setTextBaseline(TextBaseline::BOTTOM);
} else if (textBaseline == "alphabetic") {
_impl->setTextBaseline(TextBaseline::ALPHABETIC);
} else {
CC_ASSERT(false);
}
}
void CanvasRenderingContext2D::set_fillStyle(const std::string& fillStyle)
{
CSSColorParser::Color color = CSSColorParser::parse(fillStyle);
_impl->setFillStyle(color.r, color.g, color.b, static_cast<uint8_t>(color.a * 255));
// SE_LOGD("CanvasRenderingContext2D::set_fillStyle: %s, (%d, %d, %d, %f)\n", fillStyle.c_str(), color.r, color.g, color.b, color.a);
}
void CanvasRenderingContext2D::set_strokeStyle(const std::string& strokeStyle)
{
CSSColorParser::Color color = CSSColorParser::parse(strokeStyle);
_impl->setStrokeStyle(color.r, color.g, color.b, static_cast<uint8_t>(color.a * 255));
}
void CanvasRenderingContext2D::set_globalCompositeOperation(const std::string& globalCompositeOperation)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::_fillImageData(const Data& imageData, float imageWidth, float imageHeight, float offsetX, float offsetY)
{
_impl->fillImageData(imageData, imageWidth, imageHeight, offsetX, offsetY);
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
// transform
//REFINE:
void CanvasRenderingContext2D::translate(float x, float y)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::scale(float x, float y)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::rotate(float angle)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::transform(float a, float b, float c, float d, float e, float f)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::setTransform(float a, float b, float c, float d, float e, float f)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::recreateBufferIfNeeded()
{
if (_isBufferSizeDirty) {
_isBufferSizeDirty = false;
// SE_LOGD("Recreate buffer %p, w: %f, h:%f\n", this, __width, __height);
_impl->recreateBuffer(__width, __height);
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
}
NS_CC_END

View File

@@ -0,0 +1,389 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/openharmony/napi/NapiHelper.h"
#include "platform/openharmony/OpenHarmonyPlatform.h"
#include "scripting/js-bindings/jswrapper/napi/HelperMacros.h"
#include "cocos/platform/openharmony/FileUtils-openharmony.h"
#include "scripting/js-bindings/jswrapper/SeApi.h"
#include "ui/edit-box/EditBox-openharmony.h"
#include "ui/webview/WebViewImpl-openharmony.h"
#include "platform/openharmony/WorkerMessageQueue.h"
#define KEYCODE_BACK_OH 6
namespace cocos2d {
const int32_t kMaxStringLen = 512;
// Must be the same as the value called by js
enum ContextType {
APP_LIFECYCLE = 0,
JS_PAGE_LIFECYCLE,
XCOMPONENT_CONTEXT,
XCOMPONENT_REGISTER_LIFECYCLE_CALLBACK,
NATIVE_RENDER_API,
WORKER_INIT,
ENGINE_UTILS,
EDITBOX_UTILS,
WEBVIEW_UTILS,
DISPLAY_UTILS,
UV_ASYNC_SEND,
};
NapiHelper::PostMessage2UIThreadCb NapiHelper::_postMsg2UIThreadCb;
NapiHelper::PostSyncMessage2UIThreadCb NapiHelper::_postSyncMsg2UIThreadCb;
static bool js_set_PostMessage2UIThreadCallback(se::State& s) {
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
do {
if (args[0].isObject() && args[0].toObject()->isFunction()) {
//se::Value jsThis(s.thisObject());
se::Value jsFunc(args[0]);
//jsThis.toObject()->attachObject(jsFunc.toObject());
auto * thisObj = s.thisObject();
NapiHelper::_postMsg2UIThreadCb = [=](const std::string larg0, const se::Value& larg1) -> void {
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
CC_UNUSED bool ok = true;
se::ValueArray args;
args.resize(2);
ok &= std_string_to_seval(larg0, &args[0]);
CC_ASSERT(ok);
args[1] = larg1;
//ok &= nativevalue_to_se(larg1, args[1], nullptr /*ctx*/);
se::Value rval;
se::Object* funcObj = jsFunc.toObject();
bool succeed = funcObj->call(args, thisObj, &rval);
if (!succeed) {
se::ScriptEngine::getInstance()->clearException();
}
};
}
} while(false);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_set_PostMessage2UIThreadCallback);
static bool js_set_PostSyncMessage2UIThreadCallback(se::State& s) {
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
do {
if (args[0].isObject() && args[0].toObject()->isFunction()) {
//se::Value jsThis(s.thisObject());
se::Value jsFunc(args[0]);
//jsThis.toObject()->attachObject(jsFunc.toObject());
auto * thisObj = s.thisObject();
NapiHelper::_postSyncMsg2UIThreadCb = [=](const std::string larg0, const se::Value& larg1, se::Value* res) -> void {
se::ScriptEngine::getInstance()->clearException();
se::AutoHandleScope hs;
CC_UNUSED bool ok = true;
se::ValueArray args;
args.resize(2);
ok &= std_string_to_seval(larg0, &args[0]);
CC_ASSERT(ok);
args[1] = larg1;
//ok &= nativevalue_to_se(larg1, args[1], nullptr /*ctx*/);
//se::Value rval;
se::Object* funcObj = jsFunc.toObject();
bool succeed = funcObj->call(args, thisObj, res);
if (!succeed) {
se::ScriptEngine::getInstance()->clearException();
}
};
}
} while(false);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_set_PostSyncMessage2UIThreadCallback);
// NAPI Interface
napi_value NapiHelper::getContext(napi_env env, napi_callback_info info) {
napi_status status;
napi_value exports;
size_t argc = 1;
napi_value args[1];
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
if (argc != 1) {
napi_throw_type_error(env, NULL, "Wrong number of arguments");
return nullptr;
}
napi_valuetype valuetype;
status = napi_typeof(env, args[0], &valuetype);
if (status != napi_ok) {
return nullptr;
}
if (valuetype != napi_number) {
napi_throw_type_error(env, NULL, "Wrong arguments");
return nullptr;
}
int64_t value;
NAPI_CALL(env, napi_get_value_int64(env, args[0], &value));
NAPI_CALL(env, napi_create_object(env, &exports));
switch (value) {
case APP_LIFECYCLE: {
// Register app lifecycle
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("onCreate", NapiHelper::napiOnCreate),
DECLARE_NAPI_FUNCTION("onShow", NapiHelper::napiOnShow),
DECLARE_NAPI_FUNCTION("onHide", NapiHelper::napiOnHide),
DECLARE_NAPI_FUNCTION("onDestroy", NapiHelper::napiOnDestroy),
DECLARE_NAPI_FUNCTION("onBackPress", NapiHelper::napiOnBackPress),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
}
break;
case JS_PAGE_LIFECYCLE: {
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("onPageShow", NapiHelper::napiOnPageShow),
DECLARE_NAPI_FUNCTION("onPageHide", NapiHelper::napiOnPageHide),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
} break;
case XCOMPONENT_REGISTER_LIFECYCLE_CALLBACK: {
} break;
case NATIVE_RENDER_API: {
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("nativeEngineInit", NapiHelper::napiNativeEngineInit),
DECLARE_NAPI_FUNCTION("nativeEngineStart", NapiHelper::napiNativeEngineStart),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
} break;
case WORKER_INIT: {
se::ScriptEngine::setEnv(env);
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("workerInit", NapiHelper::napiWorkerInit),
DECLARE_NAPI_FUNCTION("setPostMessageFunction", _SE(js_set_PostMessage2UIThreadCallback)),
DECLARE_NAPI_FUNCTION("setPostSyncMessageFunction", _SE(js_set_PostSyncMessage2UIThreadCallback)),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
} break;
case ENGINE_UTILS: {
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("resourceManagerInit", NapiHelper::napiResourceManagerInit),
DECLARE_NAPI_FUNCTION("writablePathInit", NapiHelper::napiWritablePathInit),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
}break;
case EDITBOX_UTILS: {
std::vector<napi_property_descriptor> desc;
OpenHarmonyEditBox::GetInterfaces(desc);
NAPI_CALL(env, napi_define_properties(env, exports, desc.size(), desc.data()));
}break;
case WEBVIEW_UTILS: {
std::vector<napi_property_descriptor> desc;
OpenHarmonyWebView::GetInterfaces(desc);
NAPI_CALL(env, napi_define_properties(env, exports, desc.size(), desc.data()));
} break;
case DISPLAY_UTILS: {
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("onDisplayChange", NapiHelper::napiOnDisplayChange),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
}
case UV_ASYNC_SEND: {
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("send", NapiHelper::napiASend),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
} break;
default:
LOGE("unknown type");
}
return exports;
}
// NAPI Interface
bool NapiHelper::exportFunctions(napi_env env, napi_value exports) {
napi_status status;
// Application/SDK etc. Init
// XComponent Init:
napi_value exportInstance = nullptr;
OH_NativeXComponent* nativeXComponent = nullptr;
int32_t ret;
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
status = napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
if (status != napi_ok) {
return false;
}
status = napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));
if (status != napi_ok) {
LOGE("napi_unwrap error %{public}d", status);
return false;
}
ret = OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize);
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
return false;
}
OpenHarmonyPlatform::getInstance()->setNativeXComponent(nativeXComponent);
return true;
}
napi_value NapiHelper::napiOnCreate(napi_env env, napi_callback_info info) {
// uv_loop_t* loop = nullptr;
// NAPI_CALL(env, napi_get_uv_event_loop(env, &loop));
// OpenHarmonyPlatform::getInstance()->onCreateNative(env, loop);
LOGD("NapiHelper::napiOnCreate");
return nullptr;
}
napi_value NapiHelper::napiOnShow(napi_env env, napi_callback_info info) {
cocos2d::WorkerMessageData data{cocos2d::MessageType::WM_APP_SHOW, nullptr, nullptr};
OpenHarmonyPlatform::getInstance()->enqueue(data);
Application* app = OpenHarmonyPlatform::getInstance()->g_app;
if (app) {
app->onResume();
}
LOGD("NapiHelper::napiOnShow");
return nullptr;
}
napi_value NapiHelper::napiOnHide(napi_env env, napi_callback_info info) {
cocos2d::WorkerMessageData data{cocos2d::MessageType::WM_APP_HIDE, nullptr, nullptr};
OpenHarmonyPlatform::getInstance()->enqueue(data);
Application* app = OpenHarmonyPlatform::getInstance()->g_app;
if (app) {
app->onPause();
}
LOGD("NapiHelper::napiOnHide");
return nullptr;
}
napi_value NapiHelper::napiOnBackPress(napi_env env, napi_callback_info info) {
KeyboardEvent event;
event.key = KEYCODE_BACK_OH;
event.action = KeyboardEvent::Action::RELEASE;
EventDispatcher::dispatchKeyboardEvent(event);
return nullptr;
}
napi_value NapiHelper::napiOnDestroy(napi_env env, napi_callback_info info) {
cocos2d::WorkerMessageData data{cocos2d::MessageType::WM_APP_DESTROY, nullptr, nullptr};
OpenHarmonyPlatform::getInstance()->enqueue(data);
LOGD("NapiHelper::napiOnDestroy");
return nullptr;
}
napi_value NapiHelper::napiOnPageShow(napi_env env, napi_callback_info info) {
LOGD("NapiHelper::napiOnPageShow");
return nullptr;
}
napi_value NapiHelper::napiOnPageHide(napi_env env, napi_callback_info info) {
LOGD("NapiHelper::napiOnPageHide");
return nullptr;
}
napi_value NapiHelper::napiNativeEngineInit(napi_env env, napi_callback_info info) {
LOGD("NapiHelper::napiNativeEngineInit");
se::ScriptEngine::setEnv(env);
OpenHarmonyPlatform::getInstance()->run(0, nullptr);
return nullptr;
}
napi_value NapiHelper::napiNativeEngineStart(napi_env env, napi_callback_info info) {
LOGD("NapiHelper::napiNativeEngineStart");
OpenHarmonyPlatform::getInstance()->requestVSync();
return nullptr;
}
napi_value NapiHelper::napiWorkerInit(napi_env env, napi_callback_info info) {
uv_loop_t* loop = nullptr;
NAPI_CALL(env, napi_get_uv_event_loop(env, &loop));
OpenHarmonyPlatform::getInstance()->workerInit(env, loop);
return nullptr;
}
napi_value NapiHelper::napiOnDisplayChange(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1];
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
CC_ASSERT(argc > 0);
int32_t value;
NAPI_CALL(env, napi_get_value_int32(env, args[0], &value));
cocos2d::Device::Rotation rotation = cocos2d::Device::Rotation::_0;
if(value == 0) {
rotation = cocos2d::Device::Rotation::_0;
} else if(value == 1) {
// TODO(qgh): The openharmony platform is rotated clockwise.
rotation = cocos2d::Device::Rotation::_270;
} else if(value == 2) {
rotation = cocos2d::Device::Rotation::_180;
} else if(value == 3) {
// TODO(qgh): The openharmony platform is rotated clockwise.
rotation = cocos2d::Device::Rotation::_90;
}
EventDispatcher::dispatchOrientationChangeEvent((int)rotation);
return nullptr;
}
napi_value NapiHelper::napiResourceManagerInit(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1];
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
FileUtilsOpenHarmony::initResourceManager(env, args[0]);
return nullptr;
}
napi_value NapiHelper::napiWritablePathInit(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1];
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
napi_status status;
char buffer[kMaxStringLen];
size_t result = 0;
NODE_API_CALL(status, env, napi_get_value_string_utf8(env, args[0], buffer, kMaxStringLen, &result));
FileUtilsOpenHarmony::_ohWritablePath = std::string(buffer);
return nullptr;
}
napi_value NapiHelper::napiASend(napi_env env, napi_callback_info info) {
OpenHarmonyPlatform::getInstance()->triggerMessageSignal();
return nullptr;
}
}

View File

@@ -0,0 +1,174 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include <napi/native_api.h>
#include <uv.h>
#include "scripting/js-bindings/jswrapper/SeApi.h"
#include "scripting/js-bindings/manual/jsb_conversions.hpp"
namespace cocos2d {
class NapiHelper {
public:
static napi_value getContext(napi_env env, napi_callback_info info);
// APP Lifecycle
static napi_value napiOnCreate(napi_env env, napi_callback_info info);
static napi_value napiOnShow(napi_env env, napi_callback_info info);
static napi_value napiOnHide(napi_env env, napi_callback_info info);
static napi_value napiOnDestroy(napi_env env, napi_callback_info info);
static napi_value napiOnBackPress(napi_env env, napi_callback_info info);
// JS Page : Lifecycle
static napi_value napiOnPageShow(napi_env env, napi_callback_info info);
static napi_value napiOnPageHide(napi_env env, napi_callback_info info);
// Worker Func
static napi_value napiWorkerInit(napi_env env, napi_callback_info info);
static napi_value napiASend(napi_env env, napi_callback_info info);
static napi_value napiNativeEngineInit(napi_env env, napi_callback_info info);
static napi_value napiNativeEngineStart(napi_env env, napi_callback_info info);
static napi_value napiWritablePathInit(napi_env env, napi_callback_info info);
static napi_value napiResourceManagerInit(napi_env env, napi_callback_info info);
static napi_value napiOnDisplayChange(napi_env env, napi_callback_info info);
template <class ReturnType>
static napi_value napiCallFunction(const std::string& functionName, ReturnType* value) {
if (!se::ScriptEngine::getInstance()->isValid()) {
return nullptr;
}
se::Value tickVal;
se::AutoHandleScope scope;
if (tickVal.isUndefined()) {
se::ScriptEngine::getInstance()->getGlobalObject()->getProperty(functionName, &tickVal);
}
se::Value rval;
se::ValueArray tickArgsValArr(1);
if (!tickVal.isUndefined()) {
tickVal.toObject()->call(tickArgsValArr, nullptr, &rval);
}
if(rval.isNullOrUndefined()) {
return nullptr;
}
bool ok = true;
ok &= seval_to_native_base_type(rval, value);
SE_PRECONDITION2(ok, nullptr, "Error processing arguments");
return nullptr;
}
static napi_value napiCallFunctionByStrArgs(const std::string& functionName, const std::string& args1, int32_t* value) {
if (!se::ScriptEngine::getInstance()->isValid()) {
return nullptr;
}
se::Value tickVal;
se::AutoHandleScope scope;
if (tickVal.isUndefined()) {
se::ScriptEngine::getInstance()->getGlobalObject()->getProperty(functionName, &tickVal);
}
se::Value rval;
se::ValueArray tickArgsValArr;
tickArgsValArr.push_back(se::Value(args1));
if (!tickVal.isUndefined()) {
tickVal.toObject()->call(tickArgsValArr, nullptr, &rval);
}
if(rval.isNullOrUndefined()) {
return nullptr;
}
bool ok = true;
ok &= seval_to_native_base_type(rval, value);
SE_PRECONDITION2(ok, nullptr, "Error processing arguments");
return nullptr;
}
static napi_value napiCallFunctionByFloatArgs(const std::string& functionName, float& sec, int32_t* value) {
if (!se::ScriptEngine::getInstance()->isValid()) {
return nullptr;
}
se::Value tickVal;
se::AutoHandleScope scope;
if (tickVal.isUndefined()) {
se::ScriptEngine::getInstance()->getGlobalObject()->getProperty(functionName, &tickVal);
}
se::Value rval;
se::ValueArray tickArgsValArr;
tickArgsValArr.push_back(se::Value(sec));
if (!tickVal.isUndefined()) {
tickVal.toObject()->call(tickArgsValArr, nullptr, &rval);
}
if(rval.isNullOrUndefined()) {
return nullptr;
}
bool ok = true;
ok &= seval_to_native_base_type(rval, value);
SE_PRECONDITION2(ok, nullptr, "Error processing arguments");
return nullptr;
}
static napi_value napiSetPostMessageFunction(napi_env env, napi_callback_info info);
// Napi export
static bool exportFunctions(napi_env env, napi_value exports);
static void postStringMessageToUIThread(const std::string& type, std::string param) {
if (!_postMsg2UIThreadCb) {
return;
}
CC_UNUSED bool ok = true;
se::Value value;
ok &= std_string_to_seval(param, &value);
_postMsg2UIThreadCb(type, value);
}
static void postIntMessageToUIThread(const std::string& type, int param) {
if (!_postMsg2UIThreadCb) {
return;
}
CC_UNUSED bool ok = true;
se::Value value;
ok &= native_int_to_se(param, value, nullptr /*ctx*/);
_postMsg2UIThreadCb(type, value);
}
static void postUnorderedMapMessageToUIThread(const std::string& type, std::unordered_map<std::string, cocos2d::Value> param) {
if (!_postMsg2UIThreadCb) {
return;
}
CC_UNUSED bool ok = true;
se::Value value;
ok &= native_unorderedmap_to_se(param, value, nullptr /*ctx*/);
_postMsg2UIThreadCb(type, value);
}
public:
using PostMessage2UIThreadCb = std::function<void(const std::string&, const se::Value&)>;
static PostMessage2UIThreadCb _postMsg2UIThreadCb;
using PostSyncMessage2UIThreadCb = std::function<void(const std::string&, const se::Value&, se::Value*)>;
static PostSyncMessage2UIThreadCb _postSyncMsg2UIThreadCb;
};
}

View File

@@ -0,0 +1,63 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include <ace/xcomponent/native_interface_xcomponent.h>
#include "scripting/js-bindings/jswrapper/SeApi.h"
#include "platform/openharmony/napi/NapiHelper.h"
const char kLibname[] = "cocos";
/*
* function for module exports
*/
static napi_value init(napi_env env, napi_value exports) {
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("getContext", cocos2d::NapiHelper::getContext),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
bool ret = cocos2d::NapiHelper::exportFunctions(env, exports);
if (!ret) {
LOGE("Init failed");
}
return exports;
}
/*
* Napi Module define
*/
static napi_module cocos2dModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = init, // called by ACE XComponent
.nm_modname = kLibname,
.nm_priv = ((void*)0),
.reserved = {0},
};
/*
* Module register function
*/
extern "C" __attribute__((constructor)) void RegisterModule(void) {
napi_module_register(&cocos2dModule);
}

View File

@@ -0,0 +1,113 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "egl_core.h"
#include "platform/openharmony/napi/NapiHelper.h"
EGLConfig getConfig(int version, EGLDisplay eglDisplay) {
int attribList[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_STENCIL_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_NONE
};
EGLConfig configs = NULL;
int configsNum;
if (!eglChooseConfig(eglDisplay, attribList, &configs, 1, &configsNum)) {
LOGE("eglChooseConfig ERROR");
return NULL;
}
return configs;
}
void EGLCore::GLContextInit(void* window, int w, int h)
{
LOGD("EGLCore::GLContextInit window = %{public}p, w = %{public}d, h = %{public}d.", window, w, h);
width_ = w;
height_ = h;
mEglWindow = (EGLNativeWindowType)(window);
// 1. create sharedcontext
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (mEGLDisplay == EGL_NO_DISPLAY) {
LOGE("EGLCore::unable to get EGL display.");
return;
}
EGLint eglMajVers, eglMinVers;
if (!eglInitialize(mEGLDisplay, &eglMajVers, &eglMinVers)) {
mEGLDisplay = EGL_NO_DISPLAY;
LOGE("EGLCore::unable to initialize display");
return;
}
mEGLConfig = getConfig(3, mEGLDisplay);
if (mEGLConfig == nullptr) {
LOGE("EGLCore::GLContextInit config ERROR");
return;
}
// 2. Create EGL Surface from Native Window
if (mEglWindow) {
mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mEglWindow, nullptr);
if (mEGLSurface == nullptr) {
LOGE("EGLCore::eglCreateContext eglSurface is null");
return;
}
}
// 3. Create EGLContext from
int attrib3_list[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
mEGLContext = eglCreateContext(mEGLDisplay, mEGLConfig, mSharedEGLContext, attrib3_list);
if (!eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
LOGE("EGLCore::eglMakeCurrent error = %{public}d", eglGetError());
}
}
void EGLCore::Update()
{
eglSwapBuffers(mEGLDisplay, mEGLSurface);
}
bool EGLCore::checkGlError(const char* op)
{
LOGE("EGL ERROR CODE = %{public}x", eglGetError());
GLint error;
for (error = glGetError(); error; error = glGetError()) {
LOGE("ERROR: %{public}s, ERROR CODE = %{public}x", op, error);
return true;
}
return false;
}

View File

@@ -0,0 +1,53 @@
/****************************************************************************
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef _GL_CORE_
#define _GL_CORE_
#include "platform/openharmony/CCGL-openharmony.h"
#include <string>
class EGLCore {
public:
EGLCore() {};
void GLContextInit(void* window, int w, int h);
void Update();
public:
int width_;
int height_;
private:
bool checkGlError(const char* op);
EGLNativeWindowType mEglWindow;
EGLDisplay mEGLDisplay = EGL_NO_DISPLAY;
EGLConfig mEGLConfig = nullptr;
EGLContext mEGLContext = EGL_NO_CONTEXT;
EGLContext mSharedEGLContext = EGL_NO_CONTEXT;
EGLSurface mEGLSurface = nullptr;
};
#endif // _GL_CORE_