#pragma once #include "MiniEngine_Config.h" #include #include #include #include #define _MINIENGINE_SDL_VERSION_ATLEAST(X,Y,Z) SDL_VERSION_ATLEAST(X,Y,Z) namespace MiniEngine { class Rect { public: int x, y, w, h; Rect(int X, int Y, int W, int H); Rect(const SDL_Rect&); Rect(); SDL_Rect toSDLRect() const; bool isEmpty(); bool operator == (const Rect&) const; bool hasIntersection(const Rect&); Rect getIntersection(const Rect&); Rect getUnion(const Rect&); }; class Point { public: int x, y; Point(int X, int Y); Point(); SDL_Point toSDLPoint(); bool inRect(Rect rect); }; class ColorMode { public: int r, g, b; ColorMode(int R, int G, int B); ColorMode(); }; class RGBA { public: int r, g, b, a; RGBA(int R, int G, int B, int A); RGBA(ColorMode mode, int A); RGBA(); SDL_Color toSDLColor(); ColorMode toColorMode(); }; class NonCopyable { protected: NonCopyable() = default; ~NonCopyable() = default; NonCopyable(const NonCopyable&) = delete; NonCopyable& operator = (const NonCopyable&) = delete; }; class ErrorViewer : public std::exception { public: void fetch(); std::string getError(); const char* what() const throw() override; private: std::string str; }; class RWOP { public: RWOP(FILE* fp,bool autoclose); RWOP(const std::string& filename,const std::string& openmode); RWOP(const void* mem,int size); RWOP(void* mem,int size); RWOP()=default; ~RWOP()=default; void release(); private: std::shared_ptr _op; SDL_RWops* _get() const; void _clear(); void _set(SDL_RWops*); friend class Surface; friend class Renderer; }; enum class BlendMode { None,Blend,Add,Mod }; 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(); BlendMode getBlendMode(); int setBlendMode(BlendMode mode); int blit(Surface s,Rect src,Rect dst); int blitTo(Surface t, Rect dst); int blitTo(Surface t, Point lupoint); int blitFill(Surface t, Rect src); int blitFullFill(Surface t); int blitScaled(Surface s,Rect src,Rect dst); int blitScaledTo(Surface t, Rect dst); int blitScaledTo(Surface t, Point lupoint); int blitScaledFill(Surface t, Rect src); int blitScaledFullFill(Surface t); int setClipRect(const Rect& clipRect); Rect getClipRect() const; void disableClipping(); int setAlphaMode(int alpha); int getAlphaMode(); ColorMode getColorMode(); int setColorMode(ColorMode mode); RGBA getRGBA(); void setRGBA(RGBA pack); bool mustlock(); int lock(); void unlock(); bool isReady() const; void release(); /// Experimental : Get SDL_Surface Pointer and then do anything you want! SDL_Surface* getRawPointer() const; private: std::shared_ptr _surf; void _set(SDL_Surface*); void _clear(); SDL_Surface* _get() const; std::shared_ptr& _getex(); friend class Window; friend class Renderer; friend class Font; friend class Cursor; }; class Texture { public: Texture(); ~Texture() = default; Rect getSize(); int getw(); int geth(); bool isReady(); int setBlendMode(BlendMode mode); BlendMode getBlendMode(); /// Alpha: 0: Transparent 255: opaque int setAlphaMode(int alpha); int getAlphaMode(); ColorMode getColorMode(); int setColorMode(ColorMode mode); RGBA getRGBA(); void setRGBA(RGBA pack); void release(); protected: /// updateInfo() must be called after Texture is changed. void updateInfo(); private: std::shared_ptr _text; void _set(SDL_Texture*); void _clear(); SDL_Texture* _get(); Rect rect; friend class Renderer; }; enum class RendererType { Software, Accelerated, PresentSync, TargetTexture }; enum class FlipMode { None, Horizontal, Vertical }; class Renderer { public: Renderer() = default; int setColor(RGBA pack); RGBA getColor(); int setBlendMode(BlendMode mode); BlendMode getBlendMode(); int setTarget(Texture& t); int setTarget(); int fillRect(Rect rect); int drawRect(Rect rect); int drawPoint(Point p); int clear(); void update(); int copy(Texture t, Rect src, Rect dst); int copyTo(Texture t, Rect dst); int copyTo(Texture t, Point lupoint); int copyFill(Texture t, Rect src); int copyFullFill(Texture t); int supercopy(Texture t,bool srcfull,Rect src,bool dstfull,Rect dst,double angle,bool haspoint,Point center,FlipMode mode); Texture render(Surface surf) throw (ErrorViewer); Texture loadTexture(std::string FileName) throw(ErrorViewer); Texture loadTextureRW(RWOP rwop) throw(ErrorViewer); Texture createTexture(int Width, int Height) throw(ErrorViewer); bool isReady(); void release(); private: std::shared_ptr _rnd; void _set(SDL_Renderer*); void _clear(); SDL_Renderer* _get(); friend class Window; }; enum class SystemCursorType { Arrow, Ibeam, CrossHair, Wait, WaitArrow, SizeNWSE, SizeNESW, SizeWE, SizeNS, SizeAll, No, Hand }; class Cursor { public: Cursor()=default; Cursor(SystemCursorType); Cursor(Surface surf,Point hotspot={0,0}); static Cursor GetActiveCursor(); static Cursor GetDefaultCursor(); static void setShow(bool); static bool isShow(); void activate(); void release(); private: std::shared_ptr _cur; void _set(SDL_Cursor*); void _set_no_delete(SDL_Cursor*); SDL_Cursor* _get(); void _clear(); }; enum class MessageBoxType { Error, Warning, Information }; enum class WindowType { FullScreen, OpenGL, Shown, Hidden, Borderless, Resizable, Minimized, Maximized, InputGrabbed, InputFocus, MouseFocus, FullScreenDesktop, Foreign, AllowHighDPI, MouseCapture, AlwaysOnTop, SkipTaskBar, Utility, ToolTip, PopUpMenu }; class Window { public: Window()=default; Window(std::string Title, int Width, int Height, std::initializer_list RendererFlags = { RendererType::Accelerated,RendererType::TargetTexture }, std::initializer_list WindowFlags = {WindowType::Shown} , int WindowPositionX=SDL_WINDOWPOS_CENTERED, int WindowPositionY=SDL_WINDOWPOS_CENTERED) throw(ErrorViewer); Renderer getRenderer() const; void setRenderer(RendererType Type) { int flagcalc=0; _setRenderer(flagcalc,Type); } template void setRenderer(RendererType Type,Args&&... args) { int flagcalc=0; _setRenderer(flagcalc,Type,std::forward(args...)); } void setRenderer(std::initializer_list); Rect getSize(); void setSize(Rect sizeRect); void setSize(int w, int h); Rect getPosition(); void setPosition(int x, int y); /// FIXME: Use class Point or class Rect ? void setPosition(Point point); void setTitle(std::string Title); std::string getTitle(); void setGrab(bool); bool getGrab(); /// SDL2.0.5 Required. /// If MiniEngine Runs on a lower version of SDL, /// setOpacity() and getOpacity() always returns -1 int setOpacity(float opacity); float getOpacity() const; void setResizable(bool resizable); /// Use UTF8 in Title and Message please. int showSimpleMessageBox(MessageBoxType type,std::string Title,std::string Message); void show(); void hide(); void raise(); void minimize(); void maximize(); void restore(); _DECL_DEPRECATED Surface getSurface(); bool isScreenKeyboardShown(); void release(); protected: template void _setRenderer(int& refcalc,RendererType Type,Args&&... args) { refcalc|=_render_caster(Type); _setRenderer(refcalc,args...); } void _setRenderer(int& refcalc,RendererType Type) { refcalc|=_render_caster(Type); _setRenderer_Real(refcalc); } private: void _setRenderer_Real(Uint32 flags); Uint32 _render_caster(RendererType); std::shared_ptr _wnd; void _set(SDL_Window*); void _clear(); SDL_Window* _get() const; Renderer winrnd; }; class Font { public: enum class Style { Normal, Bold, Italic, UnderLine, StrikeThrough }; Font() = default; Font(std::string FontFileName, int size) throw(ErrorViewer); int use(std::string FontFileName, int size); bool isReady(); bool isNormal(); bool isBold(); bool isItalic(); bool isUnderLine(); bool isStrikeThrough(); void setNormal(); void setBold(bool); void setItalic(bool); void setUnderLine(bool); void setStrikeThrough(bool); template void setFontStyle(Style style,Args&&... args) { int fontcalc=0; _setFontStyle(fontcalc,style,args...); } void setFontStyle(Style style) { int fontcalc=0; _setFontStyle(fontcalc,style); } std::vector