Created
October 19, 2011 06:42
-
-
Save icebreaker/1297627 to your computer and use it in GitHub Desktop.
ATL style templating and inheritance with "no virtuals".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| *.swp | |
| cppsdl |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| Sample: ATL style templating and inheritance with "no virtuals" | |
| almost for free :) | |
| Copyright (c) 2011, Mihail Szabolcs | |
| Released into the public domain. | |
| Compile & Run: | |
| make; ./cppsdl | |
| */ | |
| #include <SDL.h> | |
| struct RectS | |
| { | |
| short x, y; | |
| unsigned short w, h; | |
| }; | |
| template< typename T > | |
| class WindowI | |
| { | |
| public: | |
| void setTitle(const char *pTitle) | |
| { | |
| static_cast<T *>(this)->onSetTitle(pTitle); | |
| } | |
| bool setVideMode(int pWidth, int pHeight, int pBpp) | |
| { | |
| return static_cast<T *>(this)->onSetVideoMode(pWidth, pHeight, pBpp); | |
| } | |
| int exec(void) | |
| { | |
| T *self = static_cast<T *>(this); | |
| bool done = false; | |
| while(!done) | |
| { | |
| while(self->onPollMessages()) | |
| { | |
| if(self->onProcessMessages()) | |
| { | |
| done = true; | |
| break; | |
| } | |
| } | |
| self->onUpdate(); | |
| self->onDraw(); | |
| self->onSwapBuffers(); | |
| // | |
| // sleep 10 ms | |
| // | |
| // Notes: | |
| // in a production app, especially when "rendering" | |
| // we should calculate the "delta" and sleep the | |
| // necessary amount in order to synch up with our | |
| // 'fixed' time-step (i.e => FPS, 1000 sec/30 fps = 33.33 ms) or such :) | |
| // | |
| self->onSleep(10); | |
| } | |
| return EXIT_SUCCESS; | |
| } | |
| void clear(unsigned short pR, unsigned short pG, unsigned short pB, unsigned short pA) | |
| { | |
| static_cast<T *>(this)->onClear(pR, pG, pB, pA); | |
| } | |
| void fill(RectS *pRect, unsigned short pR, unsigned short pG, unsigned short pB, unsigned short pA) | |
| { | |
| static_cast<T *>(this)->onFill(pRect, pR, pG, pB, pA); | |
| } | |
| protected: | |
| bool onPollMessages(void) | |
| { | |
| return true; | |
| } | |
| bool onProcessMessages(void) | |
| { | |
| return true; | |
| } | |
| void onSetTitle(const char *pTitle) | |
| { | |
| // empty | |
| } | |
| bool onSetVideoMode(int pWidth, int pHeight, int pBpp) | |
| { | |
| return false; | |
| } | |
| void onUpdate(void) | |
| { | |
| // empty | |
| } | |
| void onDraw(void) | |
| { | |
| // empty | |
| } | |
| void onSwapBuffers(void) | |
| { | |
| // empty | |
| } | |
| void onSleep(unsigned int pMs) | |
| { | |
| // empty | |
| } | |
| void onClear(unsigned short pR, unsigned short pG, unsigned short pB, unsigned short pA) | |
| { | |
| // empty | |
| } | |
| void onFill(RectS *pRect, unsigned short pR, unsigned short pG, unsigned short pB, unsigned short pA) | |
| { | |
| // empty | |
| } | |
| }; | |
| template< typename T > | |
| class SDLWindowC: public WindowI< SDLWindowC<T> > | |
| { | |
| friend class WindowI< SDLWindowC<T> >; | |
| protected: | |
| SDLWindowC(void) : mScreen(NULL) | |
| { | |
| SDL_Init(SDL_INIT_VIDEO); | |
| } | |
| ~SDLWindowC(void) | |
| { | |
| SDL_Quit(); | |
| } | |
| bool onSetVideoMode(int pWidth, int pHeight, int pBpp) | |
| { | |
| mScreen = SDL_SetVideoMode(pWidth, pHeight, pBpp, SDL_SWSURFACE); | |
| return (mScreen != NULL); | |
| } | |
| bool onPollMessages(void) | |
| { | |
| return SDL_PollEvent(&mEvent) == 1; | |
| } | |
| bool onProcessMessages(void) | |
| { | |
| return mEvent.type == SDL_QUIT; | |
| } | |
| void onSetTitle(const char *pTitle) | |
| { | |
| SDL_WM_SetCaption(pTitle, pTitle); | |
| } | |
| void onSwapBuffers(void) | |
| { | |
| SDL_Flip(mScreen); | |
| } | |
| void onSleep(unsigned int pMs) | |
| { | |
| SDL_Delay(pMs); | |
| } | |
| void onClear(unsigned short pR, unsigned short pG, unsigned short pB, unsigned short pA) | |
| { | |
| SDL_FillRect(mScreen, &mScreen->clip_rect, SDL_MapRGBA(mScreen->format, pR, pG, pB, pA)); | |
| } | |
| void onDraw(void) | |
| { | |
| return static_cast<T *>(this)->onDraw(); | |
| } | |
| void onUpdate(void) | |
| { | |
| return static_cast<T *>(this)->onUpdate(); | |
| } | |
| void onFill(RectS *pRect, unsigned short pR, unsigned short pG, unsigned short pB, unsigned short pA) | |
| { | |
| // FIXME: memcpy | |
| SDL_Rect rect; | |
| rect.x = pRect->x; | |
| rect.y = pRect->y; | |
| rect.w = pRect->w; | |
| rect.h = pRect->h; | |
| SDL_FillRect(mScreen, &rect, SDL_MapRGBA(mScreen->format, pR, pG, pB, pA)); | |
| } | |
| private: | |
| SDL_Surface *mScreen; | |
| SDL_Event mEvent; | |
| }; | |
| class DemoC : public SDLWindowC<DemoC> | |
| { | |
| friend class SDLWindowC<DemoC>; | |
| public: | |
| DemoC(void) | |
| { | |
| mRect.x = 100; | |
| mRect.y = 100; | |
| mRect.w = 100; | |
| mRect.h = 200; | |
| mRnd = 0; | |
| } | |
| protected: | |
| void onDraw(void) | |
| { | |
| clear(120, 55, 23, 255); | |
| fill(&mRect, 200, 120, 200, 255); | |
| } | |
| void onUpdate(void) | |
| { | |
| if(++mRnd > 50) | |
| { | |
| mRect.x = rand() % 200; | |
| mRect.y = rand() % 200; | |
| mRnd = 0; | |
| } | |
| } | |
| private: | |
| RectS mRect; | |
| unsigned int mRnd; | |
| }; | |
| int main(int argc, char *argv[]) | |
| { | |
| DemoC demo; | |
| if(demo.setVideMode(800, 600, 32)) | |
| { | |
| demo.setTitle("SDL Demo"); | |
| return demo.exec(); | |
| } | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| SDL=`sdl-config --cflags --libs` | |
| all: | |
| g++ cppsdl.cpp -Wall -o cppsdl $(SDL) | |
| clean: | |
| rm -f cppsdl | |
| distclean: clean | |
| realclean: clean | |
| .PHONY: all clean distclean realclean |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment