初始化

This commit is contained in:
SmallMain
2022-06-25 00:23:03 +08:00
commit ef0589e8e5
2264 changed files with 617829 additions and 0 deletions

View File

@@ -0,0 +1,435 @@
/****************************************************************************
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/CCStdC.h" // need it to include Windows.h
#include <algorithm>
#include <shellapi.h>
#include <MMSystem.h>
#include "platform/CCFileUtils.h"
#include "platform/desktop/CCGLView-desktop.h"
#include "renderer/gfx/DeviceGraphics.h"
#include "scripting/js-bindings/jswrapper/SeApi.h"
#include "scripting/js-bindings/event/EventDispatcher.h"
#include "base/CCScheduler.h"
#include "base/CCAutoreleasePool.h"
#include "base/CCGLUtils.h"
#include "audio/include/AudioEngine.h"
#define CAST_VIEW(view) ((GLView*)view)
namespace
{
/**
@brief This function changes the PVRFrame show/hide setting in register.
@param bEnable If true show the PVRFrame window, otherwise hide.
*/
void PVRFrameEnableControlWindow(bool bEnable)
{
HKEY hKey = 0;
// Open PVRFrame control key, if not exist create it.
if(ERROR_SUCCESS != RegCreateKeyExW(HKEY_CURRENT_USER,
L"Software\\Imagination Technologies\\PVRVFRame\\STARTUP\\",
0,
0,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
0,
&hKey,
nullptr))
{
return;
}
const WCHAR* wszValue = L"hide_gui";
const WCHAR* wszNewData = (bEnable) ? L"NO" : L"YES";
WCHAR wszOldData[256] = {0};
DWORD dwSize = sizeof(wszOldData);
LSTATUS status = RegQueryValueExW(hKey, wszValue, 0, nullptr, (LPBYTE)wszOldData, &dwSize);
if (ERROR_FILE_NOT_FOUND == status // the key not exist
|| (ERROR_SUCCESS == status // or the hide_gui value is exist
&& 0 != wcscmp(wszNewData, wszOldData))) // but new data and old data not equal
{
dwSize = sizeof(WCHAR) * (wcslen(wszNewData) + 1);
RegSetValueEx(hKey, wszValue, 0, REG_SZ, (const BYTE *)wszNewData, dwSize);
}
RegCloseKey(hKey);
}
bool setCanvasCallback(se::Object* global)
{
auto viewSize = cocos2d::Application::getInstance()->getViewSize();
se::ScriptEngine* se = se::ScriptEngine::getInstance();
uint8_t devicePixelRatio = cocos2d::Application::getInstance()->getScreenScale();
char commandBuf[200] = {0};
sprintf(commandBuf, "window.innerWidth = %d; window.innerHeight = %d;",
(int)(viewSize.x / devicePixelRatio),
(int)(viewSize.y / devicePixelRatio));
se->evalString(commandBuf);
cocos2d::ccViewport(0, 0, viewSize.x, viewSize.y);
glDepthMask(GL_TRUE);
return true;
}
}
NS_CC_BEGIN
Application* Application::_instance = nullptr;
std::shared_ptr<Scheduler> Application::_scheduler = nullptr;
Application::Application(const std::string& name, int width, int height)
{
Application::_instance = this;
_scheduler = std::make_shared<Scheduler>();
createView(name, width, height);
_renderTexture = new RenderTexture(width, height);
EventDispatcher::init();
se::ScriptEngine::getInstance();
}
Application::~Application()
{
#if USE_AUDIO
AudioEngine::end();
#endif
EventDispatcher::destroy();
se::ScriptEngine::destroyInstance();
delete CAST_VIEW(_view);
_view = nullptr;
delete _renderTexture;
_renderTexture = nullptr;
Application::_instance = nullptr;
}
const cocos2d::Vec2& Application::getViewSize() const
{
return _viewSize;
}
void Application::updateViewSize(int width, int height)
{
_viewSize.x = width;
_viewSize.y = height;
}
void Application::start()
{
if (!_view)
return;
PVRFrameEnableControlWindow(false);
///////////////////////////////////////////////////////////////////////////
/////////////// changing timer resolution
///////////////////////////////////////////////////////////////////////////
UINT TARGET_RESOLUTION = 1; // 1 millisecond target resolution
TIMECAPS tc;
UINT wTimerRes = 0;
if (TIMERR_NOERROR == timeGetDevCaps(&tc, sizeof(TIMECAPS)))
{
wTimerRes = std::min(std::max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
timeBeginPeriod(wTimerRes);
}
float dt = 0.f;
const DWORD _16ms = 16;
// Main message loop:
LARGE_INTEGER nFreq;
LARGE_INTEGER nLast;
LARGE_INTEGER nNow;
LONGLONG actualInterval = 0LL; // actual frame internal
LONGLONG desiredInterval = 0LL; // desired frame internal, 1 / fps
LONG waitMS = 0L;
QueryPerformanceCounter(&nLast);
QueryPerformanceFrequency(&nFreq);
se::ScriptEngine* se = se::ScriptEngine::getInstance();
while (!CAST_VIEW(_view)->windowShouldClose())
{
desiredInterval = (LONGLONG)(1.0 / _fps * nFreq.QuadPart);
if (!_isStarted)
{
auto scheduler = Application::getInstance()->getScheduler();
scheduler->removeAllFunctionsToBePerformedInCocosThread();
scheduler->unscheduleAll();
se::ScriptEngine::getInstance()->cleanup();
cocos2d::PoolManager::getInstance()->getCurrentPool()->clear();
cocos2d::EventDispatcher::init();
ccInvalidateStateCache();
se->addRegisterCallback(setCanvasCallback);
if(!applicationDidFinishLaunching())
return;
_isStarted = true;
}
// should be invoked at the begin of rendering a frame
if (_isDownsampleEnabled)
_renderTexture->prepare();
CAST_VIEW(_view)->pollEvents();
if(_isStarted)
{
QueryPerformanceCounter(&nNow);
actualInterval = nNow.QuadPart - nLast.QuadPart;
if (actualInterval >= desiredInterval)
{
nLast.QuadPart = nNow.QuadPart;
dt = (float)actualInterval / nFreq.QuadPart;
_scheduler->update(dt);
EventDispatcher::dispatchTickEvent(dt);
if (_isDownsampleEnabled)
_renderTexture->draw();
CAST_VIEW(_view)->swapBuffers();
PoolManager::getInstance()->getCurrentPool()->clear();
}
else
{
// The precision of timer on Windows is set to highest (1ms) by 'timeBeginPeriod' from above code,
// but it's still not precise enough. For example, if the precision of timer is 1ms,
// Sleep(3) may make a sleep of 2ms or 4ms. Therefore, we subtract 1ms here to make Sleep time shorter.
// If 'waitMS' is equal or less than 1ms, don't sleep and run into next loop to
// boost CPU to next frame accurately.
waitMS = (desiredInterval - actualInterval) * 1000LL / nFreq.QuadPart - 1L;
if (waitMS > 1L)
Sleep(waitMS);
}
}
else
{
Sleep(_16ms);
}
}
if (wTimerRes != 0)
timeEndPeriod(wTimerRes);
}
void Application::restart()
{
_isStarted = false;
}
void Application::end()
{
glfwSetWindowShouldClose(CAST_VIEW(_view)->getGLFWWindow(), 1);
}
void Application::setPreferredFramesPerSecond(int fps)
{
_fps = fps;
}
Application::LanguageType Application::getCurrentLanguage() const
{
LanguageType ret = LanguageType::ENGLISH;
LCID localeID = GetUserDefaultLCID();
unsigned short primaryLanguageID = localeID & 0xFF;
switch (primaryLanguageID)
{
case LANG_CHINESE:
ret = LanguageType::CHINESE;
break;
case LANG_ENGLISH:
ret = LanguageType::ENGLISH;
break;
case LANG_FRENCH:
ret = LanguageType::FRENCH;
break;
case LANG_ITALIAN:
ret = LanguageType::ITALIAN;
break;
case LANG_GERMAN:
ret = LanguageType::GERMAN;
break;
case LANG_SPANISH:
ret = LanguageType::SPANISH;
break;
case LANG_DUTCH:
ret = LanguageType::DUTCH;
break;
case LANG_RUSSIAN:
ret = LanguageType::RUSSIAN;
break;
case LANG_KOREAN:
ret = LanguageType::KOREAN;
break;
case LANG_JAPANESE:
ret = LanguageType::JAPANESE;
break;
case LANG_HUNGARIAN:
ret = LanguageType::HUNGARIAN;
break;
case LANG_PORTUGUESE:
ret = LanguageType::PORTUGUESE;
break;
case LANG_ARABIC:
ret = LanguageType::ARABIC;
break;
case LANG_NORWEGIAN:
ret = LanguageType::NORWEGIAN;
break;
case LANG_POLISH:
ret = LanguageType::POLISH;
break;
case LANG_TURKISH:
ret = LanguageType::TURKISH;
break;
case LANG_UKRAINIAN:
ret = LanguageType::UKRAINIAN;
break;
case LANG_ROMANIAN:
ret = LanguageType::ROMANIAN;
break;
case LANG_BULGARIAN:
ret = LanguageType::BULGARIAN;
break;
}
return ret;
}
std::string Application::getCurrentLanguageCode() const
{
LANGID lid = GetUserDefaultUILanguage();
const LCID locale_id = MAKELCID(lid, SORT_DEFAULT);
int length = GetLocaleInfoA(locale_id, LOCALE_SISO639LANGNAME, nullptr, 0);
char *tempCode = new char[length];
GetLocaleInfoA(locale_id, LOCALE_SISO639LANGNAME, tempCode, length);
std::string code = tempCode;
delete tempCode;
return code;
}
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);
}
float Application::getScreenScale() const
{
return CAST_VIEW(_view)->getScale();
}
GLint Application::getMainFBO() const
{
return CAST_VIEW(_view)->getMainFBO();
}
Application::Platform Application::getPlatform() const
{
return Platform::WINDOWS;
}
bool Application::openURL(const std::string &url)
{
WCHAR *temp = new WCHAR[url.size() + 1];
int wchars_num = MultiByteToWideChar(CP_UTF8, 0, url.c_str(), url.size() + 1, temp, url.size() + 1);
HINSTANCE r = ShellExecuteW(NULL, L"open", temp, NULL, NULL, SW_SHOWNORMAL);
delete[] temp;
return (size_t)r>32;
}
void Application::copyTextToClipboard(const std::string &text)
{
//TODO
}
bool Application::applicationDidFinishLaunching()
{
return true;
}
void Application::onPause()
{
}
void Application::onResume()
{
}
void Application::setMultitouch(bool)
{
}
void Application::onCreateView(PixelFormat& pixelformat, DepthFormat& depthFormat, int& multisamplingCount)
{
pixelformat = PixelFormat::RGBA8;
depthFormat = DepthFormat::DEPTH24_STENCIL8;
multisamplingCount = 0;
}
void Application::createView(const std::string& name, int width, int height)
{
int multisamplingCount = 0;
PixelFormat pixelformat;
DepthFormat depthFormat;
onCreateView(pixelformat,
depthFormat,
multisamplingCount);
_view = new GLView(this, name, 0, 0, width, height, pixelformat, depthFormat, multisamplingCount);
}
std::string Application::getSystemVersion()
{
// REFINE
return std::string("unknown Windows version");
}
NS_CC_END

View File

@@ -0,0 +1,917 @@
#include "platform/CCCanvasRenderingContext2D.h"
#include "base/ccTypes.h"
#include "base/csscolorparser.hpp"
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
#include "cocos/scripting/js-bindings/manual/jsb_platform.h"
#include "platform/CCFileUtils.h"
#include <regex>
using namespace cocos2d;
enum class CanvasTextAlign {
LEFT,
CENTER,
RIGHT
};
enum class CanvasTextBaseline {
TOP,
MIDDLE,
BOTTOM
};
namespace {
void fillRectWithColor(uint8_t* buf, uint32_t totalWidth, uint32_t totalHeight, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
assert(x + width <= totalWidth);
assert(y + height <= totalHeight);
uint32_t y0 = y;
uint32_t y1 = y + height;
uint8_t* p;
for (uint32_t offsetY = y0; offsetY < y1; ++offsetY)
{
for (uint32_t offsetX = x; offsetX < (x + width); ++offsetX)
{
p = buf + (totalWidth * offsetY + offsetX) * 4;
*p++ = r;
*p++ = g;
*p++ = b;
*p++ = a;
}
}
}
}
class CanvasRenderingContext2DImpl
{
public:
CanvasRenderingContext2DImpl() : _DC(nullptr)
, _bmp(nullptr)
, _font((HFONT)GetStockObject(DEFAULT_GUI_FONT))
, _wnd(nullptr)
, _savedDC(0)
{
_wnd = nullptr;
HDC hdc = GetDC(_wnd);
_DC = CreateCompatibleDC(hdc);
ReleaseDC(_wnd, hdc);
}
~CanvasRenderingContext2DImpl()
{
_deleteBitmap();
_removeCustomFont();
if (_DC)
DeleteDC(_DC);
}
void recreateBuffer(float w, float h)
{
_bufferWidth = w;
_bufferHeight = h;
if (_bufferWidth < 1.0f || _bufferHeight < 1.0f)
{
_deleteBitmap();
return;
}
int textureSize = _bufferWidth * _bufferHeight * 4;
uint8_t* data = (uint8_t*)malloc(sizeof(uint8_t) * textureSize);
memset(data, 0x00, textureSize);
_imageData.fastSet(data, textureSize);
_prepareBitmap(_bufferWidth, _bufferHeight);
}
void beginPath()
{
// called: set_lineWidth() -> beginPath() -> moveTo() -> lineTo() -> stroke(), when draw line
_hpen = CreatePen(PS_SOLID, _lineWidth, RGB(255, 255, 255));
// the return value of SelectObject is a handle to the object being replaced, so we should delete them to avoid memory leak
HGDIOBJ hOldPen = SelectObject(_DC, _hpen);
HGDIOBJ hOldBmp = SelectObject(_DC, _bmp);
DeleteObject(hOldPen);
DeleteObject(hOldBmp);
SetBkMode(_DC, TRANSPARENT);
}
void closePath()
{
}
void moveTo(float x, float y)
{
MoveToEx(_DC, x, -(y - _bufferHeight - _fontSize), nullptr);
}
void lineTo(float x, float y)
{
LineTo(_DC, x, -(y - _bufferHeight - _fontSize));
}
void stroke()
{
DeleteObject(_hpen);
if (_bufferWidth < 1.0f || _bufferHeight < 1.0f)
return;
_fillTextureData();
}
void saveContext()
{
_savedDC = SaveDC(_DC);
}
void restoreContext()
{
BOOL ret = RestoreDC(_DC, _savedDC);
if (0 == ret)
{
SE_LOGD("CanvasRenderingContext2DImpl restore context failed.\n");
}
}
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;
//not filled all Bits in buffer? the buffer length is _bufferWidth * _bufferHeight * 4, but it filled _bufferWidth * _bufferHeight * 3?
uint8_t* buffer = _imageData.getBytes();
if (buffer)
{
uint8_t r = _fillStyle.r * 255.0f;
uint8_t g = _fillStyle.g * 255.0f;
uint8_t b = _fillStyle.b * 255.0f;
uint8_t a = _fillStyle.a * 255.0f;
fillRectWithColor(buffer, (uint32_t)_bufferWidth, (uint32_t)_bufferHeight, (uint32_t)x, (uint32_t)y, (uint32_t)w, (uint32_t)h, r, g, b, a);
}
}
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, (int)offsetPoint.x, (int)offsetPoint.y);
_fillTextureData();
}
void strokeText(const std::string& text, float x, float y, float maxWidth)
{
if (text.empty() || _bufferWidth < 1.0f || _bufferHeight < 1.0f)
return;
// REFINE
}
cocos2d::Size measureText(const std::string& text)
{
if (text.empty())
return Size(0.0f, 0.0f);
int bufferLen = 0;
wchar_t * pwszBuffer = _utf8ToUtf16(text, &bufferLen);
SIZE size = _sizeWithText(pwszBuffer, bufferLen);
//SE_LOGD("CanvasRenderingContext2DImpl::measureText: %s, %d, %d\n", text.c_str(), size.cx, size.cy);
CC_SAFE_DELETE_ARRAY(pwszBuffer);
return Size(size.cx, size.cy);
}
void updateFont(const std::string& fontName, float fontSize, bool bold = false)
{
do
{
_fontName = fontName;
_fontSize = fontSize;
std::string fontPath;
LOGFONTA tFont = { 0 };
if (!_fontName.empty())
{
// firstly, try to create font from ttf file
const auto& fontInfoMap = getFontFamilyNameMap();
auto iter = fontInfoMap.find(_fontName);
if (iter != fontInfoMap.end())
{
fontPath = iter->second;
std::string tmpFontPath = fontPath;
int nFindPos = tmpFontPath.rfind("/");
tmpFontPath = &tmpFontPath[nFindPos + 1];
nFindPos = tmpFontPath.rfind(".");
// IDEA: draw ttf failed if font file name not equal font face name
// for example: "DejaVuSansMono-Oblique" not equal "DejaVu Sans Mono" when using DejaVuSansMono-Oblique.ttf
_fontName = tmpFontPath.substr(0, nFindPos);
}
else
{
auto nFindPos = fontName.rfind("/");
if (nFindPos != fontName.npos)
{
if (fontName.length() == nFindPos + 1)
{
_fontName = "";
}
else
{
_fontName = &_fontName[nFindPos + 1];
}
}
}
tFont.lfCharSet = DEFAULT_CHARSET;
strcpy_s(tFont.lfFaceName, LF_FACESIZE, _fontName.c_str());
}
if (_fontSize)
tFont.lfHeight = -_fontSize;
if (bold)
tFont.lfWeight = FW_BOLD;
else
tFont.lfWeight = FW_NORMAL;
// disable Cleartype
tFont.lfQuality = ANTIALIASED_QUALITY;
// delete old font
_removeCustomFont();
if (fontPath.size() > 0)
{
_curFontPath = fontPath;
wchar_t * pwszBuffer = _utf8ToUtf16(_curFontPath);
if (pwszBuffer)
{
if (AddFontResource(pwszBuffer))
{
SendMessage(_wnd, WM_FONTCHANGE, 0, 0);
}
delete[] pwszBuffer;
pwszBuffer = nullptr;
}
}
// create new font
_font = CreateFontIndirectA(&tFont);
if (!_font)
{
// create failed, use default font
SE_LOGE("Failed to create custom font(font name: %s, font size: %f), use default font.\n",
_fontName.c_str(), fontSize);
break;
}
else
{
SelectObject(_DC, _font);
SendMessage(_wnd, WM_FONTCHANGE, 0, 0);
}
} while (0);
}
void setTextAlign(CanvasTextAlign align)
{
_textAlign = align;
}
void setTextBaseline(CanvasTextBaseline baseline)
{
_textBaseLine = baseline;
}
void setFillStyle(float r, float g, float b, float a)
{
_fillStyle.r = r;
_fillStyle.g = g;
_fillStyle.b = b;
_fillStyle.a = a;
}
void setStrokeStyle(float r, float g, float b, float a)
{
_strokeStyle.r = r;
_strokeStyle.g = g;
_strokeStyle.b = b;
_strokeStyle.a = a;
}
void setLineWidth(float lineWidth)
{
_lineWidth = lineWidth;
}
void setPremultiply(bool multiply)
{
_premultiply = multiply;
}
const Data& getDataRef() const
{
return _imageData;
}
HDC _DC;
HBITMAP _bmp;
private:
Data _imageData;
HFONT _font;
HWND _wnd;
HPEN _hpen;
PAINTSTRUCT _paintStruct;
std::string _curFontPath;
int _savedDC;
float _lineWidth = 0.0f;
float _bufferWidth = 0.0f;
float _bufferHeight = 0.0f;
bool _premultiply = true;
std::string _fontName;
int _fontSize;
SIZE _textSize;
CanvasTextAlign _textAlign;
CanvasTextBaseline _textBaseLine;
cocos2d::Color4F _fillStyle;
cocos2d::Color4F _strokeStyle;
TEXTMETRIC _tm;
// change utf-8 string to utf-16, pRetLen is the string length after changing
wchar_t * _utf8ToUtf16(const std::string& str, int * pRetLen = nullptr)
{
wchar_t * pwszBuffer = nullptr;
do
{
if (str.empty())
{
break;
}
int nLen = str.size();
int nBufLen = nLen + 1;
pwszBuffer = new wchar_t[nBufLen];
CC_BREAK_IF(!pwszBuffer);
memset(pwszBuffer, 0, sizeof(wchar_t) * nBufLen);
// str.size() not equal actuallyLen for Chinese char
int actuallyLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), nLen, pwszBuffer, nBufLen);
// SE_LOGE("_utf8ToUtf16, str:%s, strLen:%d, retLen:%d\n", str.c_str(), str.size(), actuallyLen);
if (pRetLen != nullptr) {
*pRetLen = actuallyLen;
}
} while (0);
return pwszBuffer;
}
void _removeCustomFont()
{
HFONT hDefFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
if (hDefFont != _font)
{
DeleteObject(SelectObject(_DC, hDefFont));
}
// release temp font resource
if (_curFontPath.size() > 0)
{
wchar_t * pwszBuffer = _utf8ToUtf16(_curFontPath);
if (pwszBuffer)
{
RemoveFontResource(pwszBuffer);
SendMessage(_wnd, WM_FONTCHANGE, 0, 0);
delete[] pwszBuffer;
pwszBuffer = nullptr;
}
_curFontPath.clear();
}
}
// x, y offset value
int _drawText(const std::string& text, int x, int y)
{
int nRet = 0;
wchar_t * pwszBuffer = nullptr;
do
{
CC_BREAK_IF(text.empty());
DWORD dwFmt = DT_SINGLELINE | DT_NOPREFIX;
int bufferLen = 0;
pwszBuffer = _utf8ToUtf16(text, &bufferLen);
SIZE newSize = _sizeWithText(pwszBuffer, bufferLen);
_textSize = newSize;
RECT rcText = { 0 };
rcText.right = newSize.cx;
rcText.bottom = newSize.cy;
LONG offsetX = x;
LONG offsetY = y;
if (offsetX || offsetY)
{
OffsetRect(&rcText, offsetX, offsetY);
}
// SE_LOGE("_drawText text,%s size: (%d, %d) offset after convert: (%d, %d) \n", text.c_str(), newSize.cx, newSize.cy, offsetX, offsetY);
SetBkMode(_DC, TRANSPARENT);
SetTextColor(_DC, RGB(255, 255, 255)); // white color
// draw text
nRet = DrawTextW(_DC, pwszBuffer, bufferLen, &rcText, dwFmt);
} while (0);
CC_SAFE_DELETE_ARRAY(pwszBuffer);
return nRet;
}
SIZE _sizeWithText(const wchar_t * pszText, int nLen)
{
SIZE tRet = { 0 };
do
{
CC_BREAK_IF(!pszText || nLen <= 0);
RECT rc = { 0, 0, 0, 0 };
DWORD dwCalcFmt = DT_CALCRECT | DT_NOPREFIX;
// measure text size
DrawTextW(_DC, pszText, nLen, &rc, dwCalcFmt);
tRet.cx = rc.right;
tRet.cy = rc.bottom;
} while (0);
return tRet;
}
void _prepareBitmap(int nWidth, int nHeight)
{
// release bitmap
_deleteBitmap();
if (nWidth > 0 && nHeight > 0)
{
_bmp = CreateBitmap(nWidth, nHeight, 1, 32, nullptr);
SelectObject(_DC, _bmp);
}
}
void _deleteBitmap()
{
if (_bmp)
{
DeleteObject(_bmp);
_bmp = nullptr;
}
}
void _fillTextureData()
{
do
{
int dataLen = _bufferWidth * _bufferHeight * 4;
unsigned char* dataBuf = (unsigned char*)malloc(sizeof(unsigned char) * dataLen);
CC_BREAK_IF(!dataBuf);
unsigned char* imageBuf = _imageData.getBytes();
CC_BREAK_IF(!imageBuf);
struct
{
BITMAPINFOHEADER bmiHeader;
int mask[4];
} bi = { 0 };
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
CC_BREAK_IF(!GetDIBits(_DC, _bmp, 0, 0,
nullptr, (LPBITMAPINFO)&bi, DIB_RGB_COLORS));
// copy pixel data
bi.bmiHeader.biHeight = (bi.bmiHeader.biHeight > 0) ? -bi.bmiHeader.biHeight : bi.bmiHeader.biHeight;
GetDIBits(_DC, _bmp, 0, _bufferHeight, dataBuf,
(LPBITMAPINFO)&bi, DIB_RGB_COLORS);
uint8_t r = _fillStyle.r * 255;
uint8_t g = _fillStyle.g * 255;
uint8_t b = _fillStyle.b * 255;
uint8_t a = _fillStyle.a;
COLORREF textColor = (b << 16 | g << 8 | r) & 0x00ffffff;
COLORREF * pPixel = nullptr;
COLORREF * pImage = nullptr;
if (_premultiply)
{
uint8_t dirtyValue = 0;
for (int y = 0; y < _bufferHeight; ++y)
{
pPixel = (COLORREF *)dataBuf + y * (int)_bufferWidth;
pImage = (COLORREF *)imageBuf + y * (int)_bufferWidth;
for (int x = 0; x < _bufferWidth; ++x)
{
COLORREF& clr = *pPixel;
COLORREF& val = *pImage;
dirtyValue = GetRValue(clr);
// "dirtyValue > 0" means pixel was covered when drawing text
if (dirtyValue > 0)
{
// r = _fillStyle.r * 255 * (dirtyValue / 255) * alpha;
r = _fillStyle.r * dirtyValue * a;
g = _fillStyle.g * dirtyValue * a;
b = _fillStyle.b * dirtyValue * a;
textColor = (b << 16 | g << 8 | r) & 0x00ffffff;
val = ((BYTE)(dirtyValue * a) << 24) | textColor;
}
++pPixel;
++pImage;
}
}
}
else
{
for (int y = 0; y < _bufferHeight; ++y)
{
pPixel = (COLORREF *)dataBuf + y * (int)_bufferWidth;
pImage = (COLORREF *)imageBuf + y * (int)_bufferWidth;
for (int x = 0; x < _bufferWidth; ++x)
{
COLORREF& clr = *pPixel;
COLORREF& val = *pImage;
// Because text is drawn in white color, and background color is black,
// so the red value is equal to alpha value. And we should keep this value
// as it includes anti-atlas information.
uint8_t alpha = GetRValue(clr);
if (alpha > 0)
{
val = (alpha << 24) | textColor;
}
++pPixel;
++pImage;
}
}
}
free(dataBuf);
} while (0);
}
Point _convertDrawPoint(Point point, std::string text) {
Size textSize = measureText(text);
if (_textAlign == CanvasTextAlign::CENTER)
{
point.x -= textSize.width / 2.0f;
}
else if (_textAlign == CanvasTextAlign::RIGHT)
{
point.x -= textSize.width;
}
if (_textBaseLine == CanvasTextBaseline::TOP)
{
point.y += _fontSize;
}
else if (_textBaseLine == CanvasTextBaseline::MIDDLE)
{
point.y += _fontSize / 2.0f;
}
// Since the web platform cannot get the baseline of the font, an additive offset is performed for all platforms.
// That's why we should add baseline back again on other platforms
GetTextMetrics(_DC, &_tm);
point.y -= _tm.tmAscent;
return point;
}
};
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::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());
}
}
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, offset: (%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());
return _impl->measureText(text);
}
CanvasGradient* CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1)
{
return nullptr;
}
void CanvasRenderingContext2D::save()
{
//SE_LOGD("CanvasRenderingContext2D::save\n");
_impl->saveContext();
}
void CanvasRenderingContext2D::beginPath()
{
//SE_LOGD("\n-----------begin------------------\nCanvasRenderingContext2D::beginPath\n");
_impl->beginPath();
}
void CanvasRenderingContext2D::closePath()
{
//SE_LOGD("CanvasRenderingContext2D::closePath\n");
_impl->closePath();
}
void CanvasRenderingContext2D::moveTo(float x, float y)
{
//SE_LOGD("CanvasRenderingContext2D::moveTo\n");
_impl->moveTo(x, y);
}
void CanvasRenderingContext2D::lineTo(float x, float y)
{
//SE_LOGD("CanvasRenderingContext2D::lineTo\n");
_impl->lineTo(x, y);
}
void CanvasRenderingContext2D::stroke()
{
//SE_LOGD("CanvasRenderingContext2D::stroke\n");
_impl->stroke();
if (_canvasBufferUpdatedCB != nullptr)
_canvasBufferUpdatedCB(_impl->getDataRef());
}
void CanvasRenderingContext2D::restore()
{
//SE_LOGD("CanvasRenderingContext2D::restore\n");
_impl->restoreContext();
}
void CanvasRenderingContext2D::setCanvasBufferUpdatedCallback(const CanvasBufferUpdatedCallback& cb)
{
_canvasBufferUpdatedCB = cb;
}
void CanvasRenderingContext2D::setPremultiply(bool multiply)
{
_impl->setPremultiply(_premultiply);
}
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)
{
//SE_LOGD("CanvasRenderingContext2D::set_lineWidth %d\n", lineWidth);
_lineWidth = lineWidth;
_impl->setLineWidth(lineWidth);
}
void CanvasRenderingContext2D::set_lineCap(const std::string& lineCap)
{
//SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::set_lineJoin(const std::string& lineJoin)
{
//SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::fill()
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::rect(float x, float y, float w, float h)
{
// SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
void CanvasRenderingContext2D::set_font(const std::string& font)
{
if (_font != font)
{
_font = font;
std::string boldStr;
std::string fontName = "Arial";
std::string fontSizeStr = "30";
// support get font name from `60px American` or `60px "American abc-abc_abc"`
std::regex re("(bold)?\\s*((\\d+)([\\.]\\d+)?)px\\s+([\\w-]+|\"[\\w -]+\"$)");
std::match_results<std::string::const_iterator> results;
if (std::regex_search(_font.cbegin(), _font.cend(), results, re))
{
boldStr = results[1].str();
fontSizeStr = results[2].str();
fontName = results[5].str();
}
float fontSize = atof(fontSizeStr.c_str());
//SE_LOGD("CanvasRenderingContext2D::set_font: %s, Size: %f, isBold: %b\n", fontName.c_str(), fontSize, !boldStr.empty());
_impl->updateFont(fontName, fontSize, !boldStr.empty());
}
}
void CanvasRenderingContext2D::set_textAlign(const std::string& textAlign)
{
//SE_LOGD("CanvasRenderingContext2D::set_textAlign: %s\n", textAlign.c_str());
if (textAlign == "left")
{
_impl->setTextAlign(CanvasTextAlign::LEFT);
}
else if (textAlign == "center" || textAlign == "middle")
{
_impl->setTextAlign(CanvasTextAlign::CENTER);
}
else if (textAlign == "right")
{
_impl->setTextAlign(CanvasTextAlign::RIGHT);
}
else
{
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(CanvasTextBaseline::TOP);
}
else if (textBaseline == "middle")
{
_impl->setTextBaseline(CanvasTextBaseline::MIDDLE);
}
else if (textBaseline == "bottom" || textBaseline == "alphabetic") //REFINE:, how to deal with alphabetic, currently we handle it as bottom mode.
{
_impl->setTextBaseline(CanvasTextBaseline::BOTTOM);
}
else
{
assert(false);
}
}
void CanvasRenderingContext2D::set_fillStyle(const std::string& fillStyle)
{
CSSColorParser::Color color = CSSColorParser::parse(fillStyle);
_impl->setFillStyle(color.r/255.0f, color.g/255.0f, color.b/255.0f, color.a);
//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/255.0f, color.g/255.0f, color.b/255.0f, color.a);
}
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)
{
//SE_LOGE("%s isn't implemented!\n", __FUNCTION__);
}
// 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__);
}
NS_CC_END

View File

@@ -0,0 +1,107 @@
/****************************************************************************
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_WIN32
#include "platform/CCDevice.h"
#include "platform/CCFileUtils.h"
#include "platform/CCStdC.h"
#include "platform/CCApplication.h"
NS_CC_BEGIN
int Device::getDPI()
{
static int dpi = -1;
if (dpi == -1)
{
HDC hScreenDC = GetDC( nullptr );
int PixelsX = GetDeviceCaps( hScreenDC, HORZRES );
int MMX = GetDeviceCaps( hScreenDC, HORZSIZE );
ReleaseDC( nullptr, hScreenDC );
dpi = 254.0f*PixelsX/MMX/10;
}
return dpi;
}
void Device::setAccelerometerEnabled(bool isEnabled)
{}
void Device::setAccelerometerInterval(float interval)
{}
const Device::MotionValue & Device::getDeviceMotionValue()
{
static MotionValue __motionValue;
return __motionValue;
}
Device::Rotation Device::getDeviceRotation()
{
return Device::Rotation::_0;
}
std::string Device::getDeviceModel()
{
// REFINE
return std::string("Windows");
}
void Device::setKeepScreenOn(bool value)
{
CC_UNUSED_PARAM(value);
}
void Device::vibrate(float duration)
{
CC_UNUSED_PARAM(duration);
}
float Device::getBatteryLevel()
{
return 1.0f;
}
Device::NetworkType Device::getNetworkType()
{
return Device::NetworkType::LAN;
}
cocos2d::Vec4 Device::getSafeAreaEdge()
{
// no SafeArea concept on win32, return ZERO Vec4.
return cocos2d::Vec4();
}
int Device::getDevicePixelRatio()
{
return 1;
}
NS_CC_END
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32

View File

@@ -0,0 +1,429 @@
/****************************************************************************
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_WIN32
#include "platform/win32/CCFileUtils-win32.h"
#include "platform/win32/CCUtils-win32.h"
#include <Shlobj.h>
#include <cstdlib>
#include <regex>
#include <sstream>
using namespace std;
NS_CC_BEGIN
#define CC_MAX_PATH 512
// The root path of resources, the character encoding is UTF-8.
// UTF-8 is the only encoding supported by cocos2d-x API.
static std::string s_resourcePath = "";
// D:\aaa\bbb\ccc\ddd\abc.txt --> D:/aaa/bbb/ccc/ddd/abc.txt
static inline std::string convertPathFormatToUnixStyle(const std::string& path)
{
std::string ret = path;
int len = ret.length();
for (int i = 0; i < len; ++i)
{
if (ret[i] == '\\')
{
ret[i] = '/';
}
}
return ret;
}
static void _checkPath()
{
if (s_resourcePath.empty())
{
WCHAR utf16Path[CC_MAX_PATH] = { 0 };
GetModuleFileNameW(NULL, utf16Path, CC_MAX_PATH - 1);
WCHAR *pUtf16ExePath = &(utf16Path[0]);
// We need only directory part without exe
WCHAR *pUtf16DirEnd = wcsrchr(pUtf16ExePath, L'\\');
char utf8ExeDir[CC_MAX_PATH] = { 0 };
int nNum = WideCharToMultiByte(CP_UTF8, 0, pUtf16ExePath, pUtf16DirEnd-pUtf16ExePath+1, utf8ExeDir, sizeof(utf8ExeDir), nullptr, nullptr);
s_resourcePath = convertPathFormatToUnixStyle(utf8ExeDir);
}
}
FileUtils* FileUtils::getInstance()
{
if (s_sharedFileUtils == nullptr)
{
s_sharedFileUtils = new FileUtilsWin32();
if(!s_sharedFileUtils->init())
{
delete s_sharedFileUtils;
s_sharedFileUtils = nullptr;
CCLOG("ERROR: Could not init CCFileUtilsWin32");
}
}
return s_sharedFileUtils;
}
FileUtilsWin32::FileUtilsWin32()
{
}
bool FileUtilsWin32::init()
{
_checkPath();
_defaultResRootPath = s_resourcePath;
return FileUtils::init();
}
bool FileUtilsWin32::isDirectoryExistInternal(const std::string& dirPath) const
{
unsigned long fAttrib = GetFileAttributes(StringUtf8ToWideChar(dirPath).c_str());
if (fAttrib != INVALID_FILE_ATTRIBUTES &&
(fAttrib & FILE_ATTRIBUTE_DIRECTORY))
{
return true;
}
return false;
}
std::string FileUtilsWin32::getSuitableFOpen(const std::string& filenameUtf8) const
{
return UTF8StringToMultiByte(filenameUtf8);
}
long FileUtilsWin32::getFileSize(const std::string &filepath)
{
WIN32_FILE_ATTRIBUTE_DATA fad;
if (!GetFileAttributesEx(StringUtf8ToWideChar(filepath).c_str(), GetFileExInfoStandard, &fad))
{
return 0; // error condition, could call GetLastError to find out more
}
LARGE_INTEGER size;
size.HighPart = fad.nFileSizeHigh;
size.LowPart = fad.nFileSizeLow;
return (long)size.QuadPart;
}
bool FileUtilsWin32::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);
}
DWORD attr = GetFileAttributesW(StringUtf8ToWideChar(strPath).c_str());
if(attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY))
return false; // not a file
return true;
}
bool FileUtilsWin32::isAbsolutePath(const std::string& strPath) const
{
if ( (strPath.length() > 2
&& ( (strPath[0] >= 'a' && strPath[0] <= 'z') || (strPath[0] >= 'A' && strPath[0] <= 'Z') )
&& strPath[1] == ':') || (strPath[0] == '/' && strPath[1] == '/'))
{
return true;
}
return false;
}
FileUtils::Status FileUtilsWin32::getContents(const std::string& filename, ResizableBuffer* buffer)
{
if (filename.empty())
return FileUtils::Status::NotExists;
// read the file from hardware
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename);
HANDLE fileHandle = ::CreateFile(StringUtf8ToWideChar(fullPath).c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, nullptr);
if (fileHandle == INVALID_HANDLE_VALUE)
return FileUtils::Status::OpenFailed;
DWORD hi;
auto size = ::GetFileSize(fileHandle, &hi);
if (hi > 0)
{
::CloseHandle(fileHandle);
return FileUtils::Status::TooLarge;
}
// don't read file content if it is empty
if (size == 0)
{
::CloseHandle(fileHandle);
return FileUtils::Status::OK;
}
buffer->resize(size);
DWORD sizeRead = 0;
BOOL successed = ::ReadFile(fileHandle, buffer->buffer(), size, &sizeRead, nullptr);
::CloseHandle(fileHandle);
if (!successed) {
CCLOG("Get data from file(%s) failed, error code is %s", filename.data(), std::to_string(::GetLastError()).data());
buffer->resize(sizeRead);
return FileUtils::Status::ReadFailed;
}
return FileUtils::Status::OK;
}
std::string FileUtilsWin32::getPathForFilename(const std::string& filename, const std::string& resolutionDirectory, const std::string& searchPath) const
{
std::string unixFileName = convertPathFormatToUnixStyle(filename);
std::string unixResolutionDirectory = convertPathFormatToUnixStyle(resolutionDirectory);
std::string unixSearchPath = convertPathFormatToUnixStyle(searchPath);
return FileUtils::getPathForFilename(unixFileName, unixResolutionDirectory, unixSearchPath);
}
std::string FileUtilsWin32::getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename) const
{
std::string unixDirectory = convertPathFormatToUnixStyle(strDirectory);
std::string unixFilename = convertPathFormatToUnixStyle(strFilename);
return FileUtils::getFullPathForDirectoryAndFilename(unixDirectory, unixFilename);
}
string FileUtilsWin32::getWritablePath() const
{
if (_writablePath.length())
{
return _writablePath;
}
// Get full path of executable, e.g. c:\Program Files (x86)\My Game Folder\MyGame.exe
WCHAR full_path[CC_MAX_PATH + 1] = { 0 };
::GetModuleFileName(nullptr, full_path, CC_MAX_PATH + 1);
// Debug app uses executable directory; Non-debug app uses local app data directory
//#ifndef _DEBUG
// Get filename of executable only, e.g. MyGame.exe
WCHAR *base_name = wcsrchr(full_path, '\\');
wstring retPath;
if(base_name)
{
WCHAR app_data_path[CC_MAX_PATH + 1];
// Get local app data directory, e.g. C:\Documents and Settings\username\Local Settings\Application Data
if (SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_LOCAL_APPDATA, nullptr, SHGFP_TYPE_CURRENT, app_data_path)))
{
wstring ret(app_data_path);
// Adding executable filename, e.g. C:\Documents and Settings\username\Local Settings\Application Data\MyGame.exe
ret += base_name;
// Remove ".exe" extension, e.g. C:\Documents and Settings\username\Local Settings\Application Data\MyGame
ret = ret.substr(0, ret.rfind(L"."));
ret += L"\\";
// Create directory
if (SUCCEEDED(SHCreateDirectoryEx(nullptr, ret.c_str(), nullptr)))
{
retPath = ret;
}
}
}
if (retPath.empty())
//#endif // not defined _DEBUG
{
// If fetching of local app data directory fails, use the executable one
retPath = full_path;
// remove xxx.exe
retPath = retPath.substr(0, retPath.rfind(L"\\") + 1);
}
return convertPathFormatToUnixStyle(StringWideCharToUtf8(retPath));
}
bool FileUtilsWin32::renameFile(const std::string &oldfullpath, const std::string& newfullpath)
{
CCASSERT(!oldfullpath.empty(), "Invalid path");
CCASSERT(!newfullpath.empty(), "Invalid path");
std::wstring _wNew = StringUtf8ToWideChar(newfullpath);
std::wstring _wOld = StringUtf8ToWideChar(oldfullpath);
if (FileUtils::getInstance()->isFileExist(newfullpath))
{
if (!DeleteFile(_wNew.c_str()))
{
CCLOGERROR("Fail to delete file %s !Error code is 0x%x", newfullpath.c_str(), GetLastError());
}
}
if (MoveFile(_wOld.c_str(), _wNew.c_str()))
{
return true;
}
else
{
CCLOGERROR("Fail to rename file %s to %s !Error code is 0x%x", oldfullpath.c_str(), newfullpath.c_str(), GetLastError());
return false;
}
}
bool FileUtilsWin32::renameFile(const std::string &path, const std::string &oldname, const std::string &name)
{
CCASSERT(!path.empty(), "Invalid path");
std::string oldPath = path + oldname;
std::string newPath = path + name;
std::regex pat("\\/");
std::string _old = std::regex_replace(oldPath, pat, "\\");
std::string _new = std::regex_replace(newPath, pat, "\\");
return renameFile(_old, _new);
}
bool FileUtilsWin32::createDirectory(const std::string& dirPath)
{
CCASSERT(!dirPath.empty(), "Invalid path");
if (isDirectoryExist(dirPath))
return true;
std::wstring path = StringUtf8ToWideChar(dirPath);
// Split the path
size_t start = 0;
size_t found = path.find_first_of(L"/\\", start);
std::wstring subpath;
std::vector<std::wstring> dirs;
if (found != std::wstring::npos)
{
while (true)
{
subpath = path.substr(start, found - start + 1);
if (!subpath.empty())
dirs.push_back(subpath);
start = found + 1;
found = path.find_first_of(L"/\\", start);
if (found == std::wstring::npos)
{
if (start < path.length())
{
dirs.push_back(path.substr(start));
}
break;
}
}
}
if ((GetFileAttributes(path.c_str())) == INVALID_FILE_ATTRIBUTES)
{
subpath = L"";
for (unsigned int i = 0; i < dirs.size(); ++i)
{
subpath += dirs[i];
std::string utf8Path = StringWideCharToUtf8(subpath);
if (!isDirectoryExist(utf8Path))
{
BOOL ret = CreateDirectory(subpath.c_str(), NULL);
if (!ret && ERROR_ALREADY_EXISTS != GetLastError())
{
CCLOGERROR("Fail create directory %s !Error code is 0x%x", utf8Path.c_str(), GetLastError());
return false;
}
}
}
}
return true;
}
bool FileUtilsWin32::removeFile(const std::string &filepath)
{
std::regex pat("\\/");
std::string win32path = std::regex_replace(filepath, pat, "\\");
if (DeleteFile(StringUtf8ToWideChar(win32path).c_str()))
{
return true;
}
else
{
CCLOGERROR("Fail remove file %s !Error code is 0x%x", filepath.c_str(), GetLastError());
return false;
}
}
bool FileUtilsWin32::removeDirectory(const std::string& dirPath)
{
std::wstring wpath = StringUtf8ToWideChar(dirPath);
std::wstring files = wpath + L"*.*";
WIN32_FIND_DATA wfd;
HANDLE search = FindFirstFileEx(files.c_str(), FindExInfoStandard, &wfd, FindExSearchNameMatch, NULL, 0);
bool ret = true;
if (search != INVALID_HANDLE_VALUE)
{
BOOL find = true;
while (find)
{
// Need check string . and .. for delete folders and files begin name.
std::wstring fileName = wfd.cFileName;
if (fileName != L"." && fileName != L"..")
{
std::wstring temp = wpath + wfd.cFileName;
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
temp += '/';
ret = ret && this->removeDirectory(StringWideCharToUtf8(temp));
}
else
{
SetFileAttributes(temp.c_str(), FILE_ATTRIBUTE_NORMAL);
ret = ret && DeleteFile(temp.c_str());
}
}
find = FindNextFile(search, &wfd);
}
FindClose(search);
}
if (ret && RemoveDirectory(wpath.c_str()))
{
return true;
}
return false;
}
NS_CC_END
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32

View File

@@ -0,0 +1,144 @@
/****************************************************************************
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 __CC_FILEUTILS_WIN32_H__
#define __CC_FILEUTILS_WIN32_H__
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#include "platform/CCFileUtils.h"
#include "base/ccMacros.h"
#include "base/ccTypes.h"
#include <string>
#include <vector>
NS_CC_BEGIN
/**
* @addtogroup platform
* @{
*/
//! @brief Helper class to handle file operations
class CC_DLL FileUtilsWin32 : public FileUtils
{
friend class FileUtils;
FileUtilsWin32();
public:
/* override functions */
bool init();
virtual std::string getWritablePath() const override;
virtual bool isAbsolutePath(const std::string& strPath) const override;
virtual std::string getSuitableFOpen(const std::string& filenameUtf8) const override;
virtual long getFileSize(const std::string &filepath);
protected:
virtual bool isFileExistInternal(const std::string& strFilePath) const override;
/**
* Renames a file under the given directory.
*
* @param path The parent directory path of the file, it must be an absolute path.
* @param oldname The current name of the file.
* @param name The new name of the file.
* @return True if the file have been renamed successfully, false if not.
*/
virtual bool renameFile(const std::string &path, const std::string &oldname, const std::string &name) override;
/**
* Renames a file under the given directory.
*
* @param oldfullpath The current path + name of the file.
* @param newfullpath The new path + name of the file.
* @return True if the file have been renamed successfully, false if not.
*/
virtual bool renameFile(const std::string &oldfullpath, const std::string &newfullpath) override;
/**
* Checks whether a directory exists without considering search paths and resolution orders.
* @param dirPath The directory (with absolute path) to look up for
* @return Returns true if the directory found at the given absolute path, otherwise returns false
*/
virtual bool isDirectoryExistInternal(const std::string& dirPath) const override;
/**
* Removes a file.
*
* @param filepath The full path of the file, it must be an absolute path.
* @return True if the file have been removed successfully, false if not.
*/
virtual bool removeFile(const std::string &filepath) override;
/**
* Creates a directory.
*
* @param dirPath The path of the directory, it must be an absolute path.
* @return True if the directory have been created successfully, false if not.
*/
virtual bool createDirectory(const std::string& dirPath) override;
/**
* Removes a directory.
*
* @param dirPath The full path of the directory, it must be an absolute path.
* @return True if the directory have been removed successfully, false if not.
*/
virtual bool removeDirectory(const std::string& dirPath) override;
virtual FileUtils::Status getContents(const std::string& filename, ResizableBuffer* buffer) override;
/**
* Gets full path for filename, resolution directory and search path.
*
* @param filename The file name.
* @param resolutionDirectory The resolution directory.
* @param searchPath The search path.
* @return The full path of the file. It will return an empty string if the full path of the file doesn't exist.
*/
virtual std::string getPathForFilename(const std::string& filename, const std::string& resolutionDirectory, const std::string& searchPath) const override;
/**
* Gets full path for the directory and the filename.
*
* @note Only iOS and Mac need to override this method since they are using
* `[[NSBundle mainBundle] pathForResource: ofType: inDirectory:]` to make a full path.
* Other platforms will use the default implementation of this method.
* @param directory The directory contains the file we are looking for.
* @param filename The name of the file.
* @return The full path of the file, if the file can't be found, it will return an empty string.
*/
virtual std::string getFullPathForDirectoryAndFilename(const std::string& directory, const std::string& filename) const override;
};
// end of platform group
/// @}
NS_CC_END
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#endif // __CC_FILEUTILS_WIN32_H__

View File

@@ -0,0 +1,39 @@
/****************************************************************************
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_WIN32
#include "gles/glew.h"
#define CC_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#endif // __CCGL_H__

View File

@@ -0,0 +1,79 @@
/****************************************************************************
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_WIN32
#ifdef __MINGW32__
#include <string.h>
#endif
#if defined(CC_STATIC)
#define CC_DLL
#else
#if defined(_USRDLL)
#define CC_DLL __declspec(dllexport)
#else /* use a DLL library */
#define CC_DLL __declspec(dllimport)
#endif
#endif
#include <assert.h>
#if CC_DISABLE_ASSERT > 0
#define CC_ASSERT(cond)
#else
#define CC_ASSERT(cond) assert(cond)
#endif
#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
#if _MSC_VER > 1800
#pragma comment(lib,"libpng-2015.lib")
#pragma comment(lib,"libjpeg-2015.lib")
#pragma comment(lib,"libtiff-2015.lib")
#pragma comment(lib,"glfw3-2015.lib")
#else
#pragma comment(lib,"libpng.lib")
#pragma comment(lib,"libjpeg.lib")
#pragma comment(lib,"libtiff.lib")
#pragma comment(lib,"glfw3.lib")
#endif
#endif //s CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#endif /* __CCPLATFORMDEFINE_H__*/

View File

@@ -0,0 +1,55 @@
/****************************************************************************
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_WIN32
#include "platform/CCStdC.h"
#ifndef __MINGW32__
NS_CC_BEGIN
int gettimeofday(struct timeval * val, struct timezone *)
{
if (val)
{
LARGE_INTEGER liTime, liFreq;
QueryPerformanceFrequency( &liFreq );
QueryPerformanceCounter( &liTime );
val->tv_sec = (long)( liTime.QuadPart / liFreq.QuadPart );
val->tv_usec = (long)( liTime.QuadPart * 1000000.0 / liFreq.QuadPart - val->tv_sec * 1000000.0 );
}
return 0;
}
NS_CC_END
#endif // __MINGW32__
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32

View File

@@ -0,0 +1,98 @@
/****************************************************************************
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.
****************************************************************************/
#pragma once
#include <BaseTsd.h>
#ifndef __SSIZE_T
#define __SSIZE_T
typedef SSIZE_T ssize_t;
#endif // __SSIZE_T
#include <float.h>
// for math.h on win32 platform
#ifndef __MINGW32__
#if !defined(_USE_MATH_DEFINES)
#define _USE_MATH_DEFINES // make M_PI can be use
#endif
#if _MSC_VER < 1800
#if !defined(isnan)
#define isnan _isnan
#endif
#endif
#if _MSC_VER < 1900
#ifndef snprintf
#define snprintf _snprintf
#endif
#endif
#endif // __MINGW32__
#include <math.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifndef M_PI
#define M_PI 3.14159265358
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679
#endif
// for MIN MAX and sys/time.h on win32 platform
#if _MSC_VER >= 1600 || defined(__MINGW32__)
#include <stdint.h>
#else
#include "platform/win32/compat/stdint.h"
#endif
// Conflicted with ParticleSystem::PositionType::RELATIVE, so we need to undef it.
#ifdef RELATIVE
#undef RELATIVE
#endif
// Conflicted with CCBReader::SizeType::RELATIVE and CCBReader::ScaleType::RELATIVE, so we need to undef it.
#ifdef ABSOLUTE
#undef ABSOLUTE
#endif
// Conflicted with HttpRequest::Type::DELETE, so we need to undef it.
#ifdef DELETE
#undef DELETE
#endif
#undef min
#undef max

View File

@@ -0,0 +1,108 @@
/****************************************************************************
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/win32/CCUtils-win32.h"
#include "platform/CCStdC.h"
#include <sstream>
#include "base/ccMacros.h"
NS_CC_BEGIN
std::wstring StringUtf8ToWideChar(const std::string& strUtf8)
{
std::wstring ret;
if (!strUtf8.empty())
{
int nNum = MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), -1, nullptr, 0);
if (nNum)
{
WCHAR* wideCharString = new WCHAR[nNum + 1];
wideCharString[0] = 0;
nNum = MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), -1, wideCharString, nNum + 1);
ret = wideCharString;
delete[] wideCharString;
}
else
{
CCLOG("Wrong convert to WideChar code:0x%x", GetLastError());
}
}
return ret;
}
std::string StringWideCharToUtf8(const std::wstring& strWideChar)
{
std::string ret;
if (!strWideChar.empty())
{
int nNum = WideCharToMultiByte(CP_UTF8, 0, strWideChar.c_str(), -1, nullptr, 0, nullptr, FALSE);
if (nNum)
{
char* utf8String = new char[nNum + 1];
utf8String[0] = 0;
nNum = WideCharToMultiByte(CP_UTF8, 0, strWideChar.c_str(), -1, utf8String, nNum + 1, nullptr, FALSE);
ret = utf8String;
delete[] utf8String;
}
else
{
CCLOG("Wrong convert to Utf8 code:0x%x", GetLastError());
}
}
return ret;
}
std::string UTF8StringToMultiByte(const std::string& strUtf8)
{
std::string ret;
if (!strUtf8.empty())
{
std::wstring strWideChar = StringUtf8ToWideChar(strUtf8);
int nNum = WideCharToMultiByte(CP_ACP, 0, strWideChar.c_str(), -1, nullptr, 0, nullptr, FALSE);
if (nNum)
{
char* ansiString = new char[nNum + 1];
ansiString[0] = 0;
nNum = WideCharToMultiByte(CP_ACP, 0, strWideChar.c_str(), -1, ansiString, nNum + 1, nullptr, FALSE);
ret = ansiString;
delete[] ansiString;
}
else
{
CCLOG("Wrong convert to Ansi code:0x%x", GetLastError());
}
}
return ret;
}
NS_CC_END

View File

@@ -0,0 +1,42 @@
/****************************************************************************
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 __CC_UTILS_WIN32_H__
#define __CC_UTILS_WIN32_H__
#include "base/ccMacros.h"
#include <string>
NS_CC_BEGIN
std::wstring CC_DLL StringUtf8ToWideChar(const std::string& strUtf8);
std::string CC_DLL StringWideCharToUtf8(const std::wstring& strWideChar);
std::string CC_DLL UTF8StringToMultiByte(const std::string& strUtf8);
NS_CC_END
#endif // __CC_UTILS_WIN32_H__

View File

@@ -0,0 +1,251 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#if _MSC_VER > 1000
#pragma once
#endif
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#endif // _MSC_STDINT_H_ ]

View File

@@ -0,0 +1,236 @@
/* This is from the BIND 4.9.4 release, modified to compile by itself */
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/* Portions Copyright (c) Microsoft Open Technologies, Inc. */
/*modifications by Microsoft Open Technologies, Inc. to implement missing inet_pton() from Windows 8 SDK */
#if defined(__MINGW32__)
#include <errno.h>
#include <assert.h>
#include <WS2tcpip.h>
#include <Winsock2.h>
#define ERRNO ((int)GetLastError())
#define SET_ERRNO(x) (SetLastError((DWORD)(x)))
#include "platform/win32/inet_pton_mingw.h"
#define ENABLE_IPV6
#define IN6ADDRSZ 16
#define INADDRSZ 4
#define INT16SZ 2
/*
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
static int inet_pton4(const char *src, unsigned char *dst);
#ifdef ENABLE_IPV6
static int inet_pton6(const char *src, unsigned char *dst);
#endif
/* int
* inet_pton(af, src, dst)
* convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).
* return:
* 1 if the address was valid for the specified address family
* 0 if the address wasn't valid (`dst' is untouched in this case)
* -1 if some other error occurred (`dst' is untouched in this case, too)
* notice:
* On Windows we store the error in the thread errno, not
* in the winsock error code. This is to avoid losing the
* actual last winsock error. So use macro ERRNO to fetch the
* errno this function sets when returning (-1), not SOCKERRNO.
* author:
* Paul Vixie, 1996.
*/
int inet_pton(int af, const char *src, void *dst)
{
switch (af) {
case AF_INET:
return (inet_pton4(src, (unsigned char *)dst));
#ifdef ENABLE_IPV6
case AF_INET6:
return (inet_pton6(src, (unsigned char *)dst));
#endif
default:
SET_ERRNO(EAFNOSUPPORT);
return (-1);
}
/* NOTREACHED */
}
/* int
* inet_pton4(src, dst)
* like inet_aton() but without all the hexadecimal and shorthand.
* return:
* 1 if `src' is a valid dotted quad, else 0.
* notice:
* does not touch `dst' unless it's returning 1.
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton4(const char *src, unsigned char *dst)
{
static const char digits[] = "0123456789";
int saw_digit, octets, ch;
unsigned char tmp[INADDRSZ], *tp;
saw_digit = 0;
octets = 0;
tp = tmp;
*tp = 0;
while((ch = *src++) != '\0') {
const char *pch;
if((pch = strchr(digits, ch)) != NULL) {
unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
if(saw_digit && *tp == 0)
return (0);
if(val > 255)
return (0);
*tp = (unsigned char)val;
if(! saw_digit) {
if(++octets > 4)
return (0);
saw_digit = 1;
}
}
else if(ch == '.' && saw_digit) {
if(octets == 4)
return (0);
*++tp = 0;
saw_digit = 0;
}
else
return (0);
}
if(octets < 4)
return (0);
memcpy(dst, tmp, INADDRSZ);
return (1);
}
#ifdef ENABLE_IPV6
/* int
* inet_pton6(src, dst)
* convert presentation level address to network order binary form.
* return:
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
* notice:
* (1) does not touch `dst' unless it's returning 1.
* (2) :: in a full address is silently ignored.
* credit:
* inspired by Mark Andrews.
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton6(const char *src, unsigned char *dst)
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, saw_xdigit;
size_t val;
memset((tp = tmp), 0, IN6ADDRSZ);
endp = tp + IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if(*src == ':')
if(*++src != ':')
return (0);
curtok = src;
saw_xdigit = 0;
val = 0;
while((ch = *src++) != '\0') {
const char *pch;
if((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
pch = strchr((xdigits = xdigits_u), ch);
if(pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
if(++saw_xdigit > 4)
return (0);
continue;
}
if(ch == ':') {
curtok = src;
if(!saw_xdigit) {
if(colonp)
return (0);
colonp = tp;
continue;
}
if(tp + INT16SZ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if(ch == '.' && ((tp + INADDRSZ) <= endp) &&
inet_pton4(curtok, tp) > 0) {
tp += INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return (0);
}
if(saw_xdigit) {
if(tp + INT16SZ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
}
if(colonp != NULL) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const ssize_t n = tp - colonp;
ssize_t i;
if(tp == endp)
return (0);
for(i = 1; i <= n; i++) {
*(endp - i) = *(colonp + n - i);
*(colonp + n - i) = 0;
}
tp = endp;
}
if(tp != endp)
return (0);
memcpy(dst, tmp, IN6ADDRSZ);
return (1);
}
#endif /* ENABLE_IPV6 */
#endif /* HAVE_INET_PTON */

View File

@@ -0,0 +1,32 @@
#ifndef HEADER_CURL_INET_PTON_MINGW_H
#define HEADER_CURL_INET_PTON_MINGW_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* Portions Copyright (c) Microsoft Open Technologies, Inc.
*
***************************************************************************/
#if defined(__MINGW32__)
int inet_pton(int af, const char *src, void *dst);
#endif
#endif /* HEADER_CURL_INET_PTON_MINGW_H */