diff --git a/MiniEngine.cpp b/MiniEngine.cpp index bc3f8a3..4bcc1a1 100644 --- a/MiniEngine.cpp +++ b/MiniEngine.cpp @@ -86,6 +86,9 @@ namespace MiniEngine return SDL_WINDOW_ALLOW_HIGHDPI; case WindowType::MouseCapture: return SDL_WINDOW_MOUSE_CAPTURE; + + /// The following value are not defined on C4. + #ifndef __C4DROID__ case WindowType::AlwaysOnTop: return SDL_WINDOW_ALWAYS_ON_TOP; case WindowType::SkipTaskBar: @@ -96,6 +99,8 @@ namespace MiniEngine return SDL_WINDOW_TOOLTIP; case WindowType::PopUpMenu: return SDL_WINDOW_POPUP_MENU; + #endif // __C4DROID__ + default: return 0;/// Return 0 on default. } @@ -376,7 +381,7 @@ namespace MiniEngine } // private - SDL_RWops* RWOP::_get() + SDL_RWops* RWOP::_get() const { return _op.get(); } @@ -412,17 +417,20 @@ namespace MiniEngine _clear(); } - void Surface::_set(SDL_Surface* p)//private + //private + void Surface::_set(SDL_Surface* p) { _surf.reset(p,SDL_FreeSurface); } - void Surface::_clear()//private + //private + void Surface::_clear() { _surf.reset(); } - SDL_Surface* Surface::_get()//private + //private + SDL_Surface* Surface::_get() const { return _surf.get(); } @@ -432,6 +440,115 @@ namespace MiniEngine return _surf; } + Surface::Surface(int width,int height,int depth,int Rmask,int Gmask,int Bmask,int Amask) throw(ErrorViewer) + { + if(create(width,height,depth,Rmask,Gmask,Bmask,Amask)!=0) + { + ErrorViewer e; + e.fetch(); + throw e; + } + } + + Surface::Surface(int width,int height,int depth,RGBA maskPack) throw (ErrorViewer) + : Surface(width,height,depth,maskPack.r,maskPack.g,maskPack.b,maskPack.a) + { + + } + + Surface::Surface(int width,int height,int depth,Uint32 surfaceFormat) throw(ErrorViewer) + { + if(create(width,height,depth,surfaceFormat)!=0) + { + ErrorViewer e; + e.fetch(); + throw e; + } + } + + Surface::Surface(const std::string& filename) throw(ErrorViewer) + { + if(load(filename)!=0) + { + ErrorViewer e; + e.fetch(); + throw e; + } + } + + Surface::Surface(const RWOP& rwop) throw (ErrorViewer) + { + if(load(rwop)!=0) + { + ErrorViewer e; + e.fetch(); + throw e; + } + } + + int Surface::load(const std::string& filename) + { + SDL_Surface* temp=IMG_Load(filename.c_str()); + if(temp==nullptr) + { + return -1; + } + else + { + _set(temp); + return 0; + } + } + + int Surface::load(const RWOP& rwop) + { + SDL_Surface* temp=IMG_Load_RW(rwop._get(),0); + if(temp==nullptr) + { + return -1; + } + else + { + _set(temp); + return 0; + } + } + + int Surface::create(int width,int height,int depth,int Rmask,int Gmask,int Bmask,int Amask) + { + SDL_Surface* temp=SDL_CreateRGBSurface(0,width,height,depth,Rmask,Gmask,Bmask,Amask); + if(temp==nullptr) + { + return -1; + } + else + { + _set(temp); + return 0; + } + } + + int Surface::create(int width,int height,int depth,Uint32 surfaceFormat) + { + /// FIXME: This Function is available from SDL2.0.5. But the linker report a undefined reference. + + /* + SDL_Surface* temp=SDL_CreateRGBSurfaceWithFormat(0,width,height,depth,surfaceFormat); + if(temp==nullptr) + { + return -1; + } + else + { + _set(temp); + return 0; + } + */ + + SDL_SetError("[MiniEngine] SDL_CreateRGBSurfaceWithFormat Not Linked."); + return -1; + } + int Surface::getw() { if(_get()!=nullptr) @@ -588,19 +705,9 @@ namespace MiniEngine SDL_UnlockSurface(_get()); } - //static - Surface Surface::createSurface(int width,int height,int depth,int Rmask,int Gmask,int Bmask,int Amask) throw(ErrorViewer) + bool Surface::isReady() const { - SDL_Surface* temp=SDL_CreateRGBSurface(0,width,height,depth,Rmask,Gmask,Bmask,Amask); - if(temp==nullptr) - { - ErrorViewer e; - e.fetch(); - throw e; - } - Surface surf; - surf._set(temp); - return surf; + return _get()!=nullptr; } void Surface::release() @@ -608,6 +715,12 @@ namespace MiniEngine _clear(); } + /// Experimental + SDL_Surface* Surface::getRawPointer() + { + return _get(); + } + void Texture::_set(SDL_Texture* p)//private { _text.reset(p,SDL_DestroyTexture); @@ -871,34 +984,6 @@ namespace MiniEngine return SDL_RenderCopyEx(_get(),t._get(),pR1,pR2,angle,pPoint,flip); } - Surface Renderer::loadSurface(std::string FileName) throw(ErrorViewer) - { - Surface surf; - SDL_Surface* temp = IMG_Load(FileName.c_str()); - if (temp == nullptr) - { - ErrorViewer e; - e.fetch(); - throw e; - } - surf._set(temp); - return surf; - } - - Surface Renderer::loadSurfaceRW(RWOP rwop) throw (ErrorViewer) - { - Surface surf; - SDL_Surface* temp=IMG_Load_RW(rwop._get(),0); - if(temp==nullptr) - { - ErrorViewer e; - e.fetch(); - throw e; - } - surf._set(temp); - return surf; - } - Texture Renderer::render(Surface surf) throw(ErrorViewer) { Texture t; diff --git a/MiniEngine.h b/MiniEngine.h index 20de1aa..822015e 100644 --- a/MiniEngine.h +++ b/MiniEngine.h @@ -84,9 +84,10 @@ namespace MiniEngine void release(); private: std::shared_ptr _op; - SDL_RWops* _get(); + SDL_RWops* _get() const; void _clear(); void _set(SDL_RWops*); + friend class Surface; friend class Renderer; }; @@ -95,7 +96,20 @@ namespace MiniEngine class Surface { public: + Surface()=default; + Surface(int width,int height,int depth,int Rmask,int Gmask,int Bmask,int Amask) throw(ErrorViewer); + Surface(int width,int height,int depth,RGBA colorPack) throw(ErrorViewer); + Surface(int width,int height,int depth,Uint32 surfaceFormat) throw(ErrorViewer); + Surface(const std::string& filename) throw(ErrorViewer); + Surface(const RWOP& rwop) throw(ErrorViewer); ~Surface() = default; + + int load(const std::string& filename); + int load(const RWOP& rwop); + + int create(int width,int height,int depth,int Rmask,int Gmask,int Bmask,int Amask); + int create(int width,int height,int depth,Uint32 surfaceFormat); + int savePNG(const std::string& filename); int getw(); int geth(); @@ -126,16 +140,16 @@ namespace MiniEngine int lock(); void unlock(); - static Surface createSurface(int width,int height,int depth,int Rmask,int Gmask,int Bmask,int Amask) throw(ErrorViewer); - + bool isReady() const; void release(); - protected: - Surface() = default; + + /// Experimental : Get SDL_Surface Pointer and then do anything you want! + SDL_Surface* getRawPointer(); private: std::shared_ptr _surf; void _set(SDL_Surface*); void _clear(); - SDL_Surface* _get(); + SDL_Surface* _get() const; std::shared_ptr& _getex(); friend class Window; @@ -208,8 +222,6 @@ namespace MiniEngine int supercopy(Texture t,bool srcfull,Rect src,bool dstfull,Rect dst,double angle,bool haspoint,Point center,FlipMode mode); - Surface loadSurface(std::string FileName) throw(ErrorViewer); - Surface loadSurfaceRW(RWOP rwop) throw(ErrorViewer); Texture render(Surface surf) throw (ErrorViewer); Texture loadTexture(std::string FileName) throw(ErrorViewer); Texture loadTextureRW(RWOP rwop) throw(ErrorViewer); diff --git a/MiniEngine_Android.cpp b/MiniEngine_Android.cpp index d45630f..fba67c6 100644 --- a/MiniEngine_Android.cpp +++ b/MiniEngine_Android.cpp @@ -7,12 +7,12 @@ namespace MiniEngine #if defined(__ANDROID__) && __ANDROID__ std::string SDLSystem::Android::GetInternal() { - return string(SDL_AndroidGetInternalStoragePath()); + return std::string(SDL_AndroidGetInternalStoragePath()); } std::string SDLSystem::Android::GetExternal() { - return string(SDL_AndroidGetExternalStoragePath()); + return std::string(SDL_AndroidGetExternalStoragePath()); } bool SDLSystem::Android::CanReadExternal() diff --git a/MiniEngine_SQLite.h b/MiniEngine_SQLite.h index cc3a507..575bf0f 100644 --- a/MiniEngine_SQLite.h +++ b/MiniEngine_SQLite.h @@ -2,6 +2,7 @@ #include "sqlite/sqlite3.h" #include #include +#include namespace MiniEngine { diff --git a/MiniEngine_Windows.cpp b/MiniEngine_Windows.cpp index b07522e..d929338 100644 --- a/MiniEngine_Windows.cpp +++ b/MiniEngine_Windows.cpp @@ -3,118 +3,83 @@ using namespace std; #include -//GBK编码转换到UTF8编码 -int _GBKToUTF8(unsigned char * lpGBKStr,unsigned char * lpUTF8Str,int nUTF8StrLen) +int _utf8_to_gb(const char* src, char* dst, int len) { - wchar_t * lpUnicodeStr = NULL; - int nRetLen = 0; - - if(!lpGBKStr) //如果GBK字符串为NULL则出错退出 - return 0; - - nRetLen = MultiByteToWideChar(CP_ACP,0,(char *)lpGBKStr,-1,NULL,0); //获取转换到Unicode编码后所需要的字符空间长度 - lpUnicodeStr = new WCHAR[nRetLen + 1]; //为Unicode字符串空间 - nRetLen = ::MultiByteToWideChar(CP_ACP,0,(char *)lpGBKStr,-1,lpUnicodeStr,nRetLen); //转换到Unicode编码 - if(!nRetLen) //转换失败则出错退出 - return 0; - - nRetLen = ::WideCharToMultiByte(CP_UTF8,0,lpUnicodeStr,-1,NULL,0,NULL,0); //获取转换到UTF8编码后所需要的字符空间长度 - - if(!lpUTF8Str) //输出缓冲区为空则返回转换后需要的空间大小 - { - if(lpUnicodeStr) - delete []lpUnicodeStr; - return nRetLen; + int ret = 0; + WCHAR* strA; + int i= MultiByteToWideChar(CP_UTF8, 0, src, -1, NULL, 0); + if (i <= 0) { + return -1; } - - if(nUTF8StrLen < nRetLen) //如果输出缓冲区长度不够则退出 - { - if(lpUnicodeStr) - delete []lpUnicodeStr; - return 0; + strA = (WCHAR*)malloc(i * 2); + MultiByteToWideChar(CP_UTF8, 0, src, -1, strA, i); + i = WideCharToMultiByte(CP_ACP, 0, strA, -1, NULL, 0, NULL, NULL); + if (len >= i) { + ret = WideCharToMultiByte(CP_ACP, 0, strA, -1, dst, i, NULL, NULL); + dst[i] = 0; } - - nRetLen = ::WideCharToMultiByte(CP_UTF8,0,lpUnicodeStr,-1,(char *)lpUTF8Str,nUTF8StrLen,NULL,NULL); //转换到UTF8编码 - - if(lpUnicodeStr) - delete []lpUnicodeStr; - - return nRetLen; + if (ret <= 0) { + free(strA); + return -2; + } + free( strA ); + return 0; } -// UTF8编码转换到GBK编码 -int _UTF8ToGBK(unsigned char * lpUTF8Str,unsigned char * lpGBKStr,int nGBKStrLen) +int _gb_to_utf8(const char* src, char* dst, int len) { - wchar_t * lpUnicodeStr = NULL; - int nRetLen = 0; - - if(!lpUTF8Str) //如果UTF8字符串为NULL则出错退出 - return 0; - - nRetLen = ::MultiByteToWideChar(CP_UTF8,0,(char *)lpUTF8Str,-1,NULL,0); //获取转换到Unicode编码后所需要的字符空间长度 - lpUnicodeStr = new WCHAR[nRetLen + 1]; //为Unicode字符串空间 - nRetLen = ::MultiByteToWideChar(CP_UTF8,0,(char *)lpUTF8Str,-1,lpUnicodeStr,nRetLen); //转换到Unicode编码 - if(!nRetLen) //转换失败则出错退出 - return 0; - - nRetLen = ::WideCharToMultiByte(CP_ACP,0,lpUnicodeStr,-1,NULL,0,NULL,NULL); //获取转换到GBK编码后所需要的字符空间长度 - - if(!lpGBKStr) //输出缓冲区为空则返回转换后需要的空间大小 - { - if(lpUnicodeStr) - delete []lpUnicodeStr; - return nRetLen; + int ret = 0; + WCHAR* strA; + int i= MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0); + if (i <= 0) { + return -1; + } + strA = (WCHAR*)malloc(i * 2); + MultiByteToWideChar(CP_ACP, 0, src, -1, strA, i); + i = WideCharToMultiByte(CP_UTF8, 0, strA, -1, NULL, 0, NULL, NULL); + if (len >= i) { + ret = WideCharToMultiByte(CP_UTF8, 0, strA, -1, dst, i, NULL, NULL); + dst[i] = 0; } - if(nGBKStrLen < nRetLen) //如果输出缓冲区长度不够则退出 - { - if(lpUnicodeStr) - delete []lpUnicodeStr; - return 0; + if (ret <= 0) { + free(strA); + return -2; } - - nRetLen = ::WideCharToMultiByte(CP_ACP,0,lpUnicodeStr,-1,(char *)lpGBKStr,nRetLen,NULL,NULL); //转换到GBK编码 - - if(lpUnicodeStr) - delete []lpUnicodeStr; - - return nRetLen; + free(strA); + return 0; } string UTF8ToGBK(string UTF8String) { int sz=UTF8String.size()*2/3+256; - auto utf8str=new unsigned char[sz]; - memset(utf8str,0,sz); - memcpy(utf8str,UTF8String.c_str(),UTF8String.size()); - - auto gbkstr=new unsigned char[sz]; + auto gbkstr=new char[sz]; memset(gbkstr,0,sz); - _UTF8ToGBK(utf8str,gbkstr,sz); + if(_utf8_to_gb(UTF8String.c_str(),gbkstr,sz)!=0) + { + return "[MiniEngine] UT8ToGBK Convert Failed"; + } string s((char*)gbkstr); delete[] gbkstr; - delete[] utf8str; return s; } string GBKToUTF8(string GBKString) { int sz=GBKString.size()*3/2+32; - auto gbkstr=new unsigned char[sz]; - memset(gbkstr,0,sz); - memcpy(gbkstr,GBKString.c_str(),GBKString.size()); - - auto utf8str=new unsigned char[sz]; + auto utf8str=new char[sz]; memset(utf8str,0,sz); - _GBKToUTF8(gbkstr,utf8str,sz); + if(_gb_to_utf8(GBKString.c_str(),utf8str,sz)!=0) + { + return "[MiniEngine] GBKToUTF8 Convert Failed"; + } - string s((char*)utf8str); + string s(utf8str); - delete[] gbkstr; delete[] utf8str; return s; }