Advertisement
MegaLoler

SDL Base Engine

Jul 24th, 2012
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.86 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <math.h>
  4. #include "SDL/SDL.h"
  5. #include "SDL/SDL_gfxPrimitives.h"
  6.  
  7. #define WIDTH 640
  8. #define HEIGHT 480
  9.  
  10. #define FPS 60
  11. #define SPF 5
  12.  
  13. using namespace std;
  14.  
  15. struct Dimension
  16. {
  17.     public:
  18.         double x;
  19.         double y;
  20.        
  21.         Dimension();
  22.         Dimension(double x);
  23.         Dimension(double x, double y);
  24.        
  25.         double length();
  26.         double distance(Dimension operend);
  27.         double dotProduct(Dimension operend);
  28.        
  29.         Dimension operator +(Dimension operend);
  30.         Dimension operator -(Dimension operend);
  31.         Dimension operator *(Dimension operend);
  32.         Dimension operator /(Dimension operend);
  33.        
  34.         bool operator ==(Dimension operend);
  35.         bool operator !=(Dimension operend);
  36.         bool operator >(Dimension operend);
  37.         bool operator <(Dimension operend);
  38.         bool operator >=(Dimension operend);
  39.         bool operator <=(Dimension operend);
  40. };
  41.  
  42. Dimension::Dimension()
  43. {
  44.     this->x = 0;
  45.     this->y = 0;
  46. }
  47.  
  48. Dimension::Dimension(double x)
  49. {
  50.     this->x = x;
  51.     this->y = x;
  52. }
  53.  
  54. Dimension::Dimension(double x, double y)
  55. {
  56.     this->x = x;
  57.     this->y = y;
  58. }
  59.  
  60. double Dimension::length()
  61. {
  62.     return sqrt(pow(x, 2) + pow(y, 2));
  63. }
  64.  
  65. double Dimension::distance(Dimension operend)
  66. {
  67.     Dimension difference = operend - *this;
  68.     return difference.length();
  69. }
  70.  
  71. double Dimension::dotProduct(Dimension operend)
  72. {
  73.     return x * operend.x + y * operend.y;
  74. }
  75.  
  76. Dimension Dimension::operator +(Dimension operend)
  77. {
  78.     x += operend.x;
  79.     y += operend.y;
  80.     return *this;
  81. }
  82.  
  83. Dimension Dimension::operator -(Dimension operend)
  84. {
  85.     x -= operend.x;
  86.     y -= operend.y;
  87.     return *this;
  88. }
  89.  
  90. Dimension Dimension::operator *(Dimension operend)
  91. {
  92.     x *= operend.x;
  93.     y *= operend.y;
  94.     return *this;
  95. }
  96.  
  97. Dimension Dimension::operator /(Dimension operend)
  98. {
  99.     x /= operend.x;
  100.     y /= operend.y;
  101.     return *this;
  102. }
  103.  
  104. bool Dimension::operator ==(Dimension operend)
  105. {
  106.     return x == operend.x && y == operend.y;
  107. }
  108.  
  109. bool Dimension::operator !=(Dimension operend)
  110. {
  111.     return x != operend.x || y != operend.y;
  112. }
  113.  
  114. bool Dimension::operator >(Dimension operend)
  115. {
  116.     return x > operend.x && y > operend.y;
  117. }
  118.  
  119. bool Dimension::operator <(Dimension operend)
  120. {
  121.     return x < operend.x && y < operend.y;
  122. }
  123.  
  124. bool Dimension::operator >=(Dimension operend)
  125. {
  126.     return (x > operend.x && y > operend.y) || ((*this) == operend);
  127. }
  128.  
  129. bool Dimension::operator <=(Dimension operend)
  130. {
  131.     return (x < operend.x && y < operend.y) || ((*this) == operend);
  132. }
  133.  
  134. class Entity
  135. {
  136.     public:
  137.         Entity();
  138.         ~Entity();
  139.    
  140.         void update();
  141.         void render(SDL_Surface *surface);
  142.        
  143.         void keyDown(SDL_keysym key);
  144.         void keyUp(SDL_keysym key);
  145.         void mouseDown(unsigned short button, Dimension position);
  146.         void mouseUp(unsigned short button, Dimension position);
  147.         void mouseMotion(Dimension position, Dimension motion);
  148.        
  149.         Dimension getPosition();
  150.         Dimension getSize();
  151.        
  152.         long getBackgroundColor();
  153.        
  154.         void setParent(Entity *parent);
  155.        
  156.     protected:
  157.         long getTick();
  158.         long getFrame();
  159.        
  160.         void addEntity(Entity *entity);
  161.         void removeEntity(Entity *entity);
  162.         void removeEntity(int entity);
  163.         void clearEntities();
  164.        
  165.         void bringToFront(Entity *entity);
  166.         void bringToFront();
  167.        
  168.         void remove();
  169.        
  170.         void setFocused(bool focused);
  171.         bool isFocused();
  172.        
  173.         virtual void update2() = 0;
  174.         virtual void render2(SDL_Surface *surface) = 0;
  175.        
  176.         virtual void onKeyDown(SDL_keysym key) {}
  177.         virtual void onKeyUp(SDL_keysym key) {}
  178.         virtual void onMouseDown(unsigned short button, Dimension position) {}
  179.         virtual void onMouseUp(unsigned short button, Dimension position) {}
  180.         virtual void onMouseMotion(Dimension position, Dimension motion) {}
  181.         virtual void onClick(unsigned short button, Dimension position) {}
  182.         virtual void onDrag(unsigned short button, Dimension position, Dimension motion) {}
  183.         virtual void onFocus() {}
  184.         virtual void onUnfocus() {}
  185.        
  186.         Entity *getEntityInBounds(Dimension bounds);
  187.        
  188.         Dimension position;
  189.         Dimension size;
  190.        
  191.         long backgroundColor;
  192.        
  193.         Entity *getParent();
  194.        
  195.     private:
  196.         vector<Entity *> contents;
  197.         Entity *focus;
  198.        
  199.         bool mouse;
  200.         unsigned short button;
  201.        
  202.         bool focused;
  203.        
  204.         long tick;
  205.         long frame;
  206.        
  207.         Entity *parent;
  208. };
  209.  
  210. Entity::Entity()
  211. {
  212.     contents = vector<Entity *>();
  213.     focus = NULL;
  214.    
  215.     mouse = false;
  216.     button = 0;
  217.    
  218.     focused = false;
  219.    
  220.     tick = 0;
  221.     frame = 0;
  222.    
  223.     position = Dimension(0, 0);
  224.     size = Dimension(0, 0);
  225.    
  226.     backgroundColor = 0x000000;
  227.    
  228.     parent = NULL;
  229. }
  230.  
  231. Entity::~Entity()
  232. {
  233.     clearEntities();
  234. }
  235.  
  236. void Entity::update()
  237. {
  238.     update2();
  239.     tick++;
  240.    
  241.     vector<Entity *>::iterator it;
  242.     for(it = contents.begin(); it < contents.end(); it++)
  243.     {
  244.         (*it)->update();
  245.     }
  246. }
  247.  
  248. void Entity::render(SDL_Surface *surface)
  249. {
  250.     SDL_Surface *surface2 = SDL_CreateRGBSurface(SDL_HWSURFACE, size.x, size.y, 32, 0, 0, 0, 0);
  251.    
  252.     render2(surface2);
  253.     frame++;
  254.    
  255.     vector<Entity *>::iterator it;
  256.     for(it = contents.begin(); it < contents.end(); it++)
  257.     {
  258.         (*it)->render(surface2);
  259.     }
  260.    
  261.     SDL_Rect offset;
  262.     offset.x = position.x;
  263.     offset.y = position.y;
  264.    
  265.     SDL_BlitSurface(surface2, NULL, surface, &offset);
  266.     SDL_FreeSurface(surface2);
  267. }
  268.        
  269. void Entity::keyDown(SDL_keysym key)
  270. {
  271.     onKeyDown(key);
  272.    
  273.     if(focus != NULL)
  274.     {
  275.         focus->onKeyDown(key);
  276.     }
  277. }
  278.  
  279. void Entity::keyUp(SDL_keysym key)
  280. {
  281.     onKeyUp(key);
  282.    
  283.     if(focus != NULL)
  284.     {
  285.         focus->onKeyUp(key);
  286.     }
  287. }
  288.  
  289. void Entity::mouseDown(unsigned short button, Dimension position)
  290. {
  291.     mouse = true;
  292.     this->button = button;
  293.     onMouseDown(button, position);
  294.    
  295.     Entity *oldFocus = focus;
  296.     focus = getEntityInBounds(position);   
  297.    
  298.     if(focus != oldFocus)
  299.     {
  300.         if(focus != NULL)
  301.         {
  302.             focus->setFocused(true);
  303.         }
  304.         if(oldFocus != NULL)
  305.         {
  306.             oldFocus->setFocused(false);
  307.         }
  308.     }
  309.    
  310.     if(focus != NULL)
  311.     {
  312.         focus->onMouseDown(button, position);
  313.     }
  314. }
  315.  
  316. void Entity::mouseUp(unsigned short button, Dimension position)
  317. {
  318.     Entity *focus = getEntityInBounds(position);
  319.    
  320.     onMouseUp(button, position);
  321.     if(mouse)
  322.     {
  323.         onClick(button, position);
  324.    
  325.         if(focus != NULL && focus == this->focus)
  326.         {
  327.             focus->onClick(button, position);
  328.         }
  329.     }
  330.     mouse = false;
  331.    
  332.     if(focus != NULL)
  333.     {
  334.         focus->onMouseUp(button, position);
  335.     }
  336. }
  337.  
  338. void Entity::mouseMotion(Dimension position, Dimension motion)
  339. {
  340.     onMouseMotion(position, motion);
  341.     if(mouse)
  342.     {
  343.         onDrag(button, position, motion);
  344.    
  345.         if(focus != NULL)
  346.         {
  347.             focus->onDrag(button, position, motion);
  348.         }
  349.     }
  350.    
  351.     Entity *focus = getEntityInBounds(position);
  352.    
  353.     if(focus != NULL)
  354.     {
  355.         focus->onMouseMotion(position, motion);
  356.     }
  357. }
  358.  
  359. Entity *Entity::getParent()
  360. {
  361.     return parent;
  362. }
  363.  
  364. void Entity::setParent(Entity *parent)
  365. {
  366.     this->parent = parent;
  367. }
  368.  
  369. Dimension Entity::getPosition()
  370. {
  371.     return position;
  372. }
  373.  
  374. Dimension Entity::getSize()
  375. {
  376.     return size;
  377. }
  378.  
  379. long Entity::getBackgroundColor()
  380. {
  381.     return backgroundColor;
  382. }
  383.  
  384. long Entity::getTick()
  385. {
  386.     return tick;
  387. }
  388.  
  389. long Entity::getFrame()
  390. {
  391.     return frame;
  392. }
  393.  
  394. void Entity::addEntity(Entity *entity)
  395. {
  396.     contents.push_back(entity);
  397.     entity->setParent(this);
  398. }
  399.  
  400. void Entity::removeEntity(Entity *entity)
  401. {
  402.     vector<Entity *>::iterator it;
  403.     for(it = contents.begin(); it < contents.end(); it++)
  404.     {
  405.         if(entity == *it)
  406.         {
  407.             contents.erase(it);
  408.             break;
  409.         }
  410.     }
  411. }
  412.  
  413. void Entity::removeEntity(int entity)
  414. {
  415.     contents.erase(contents.begin() + entity);
  416. }
  417.  
  418. void Entity::clearEntities()
  419. {
  420.     contents.clear();
  421. }
  422.  
  423. void Entity::bringToFront(Entity *entity)
  424. {
  425.     removeEntity(entity);
  426.     addEntity(entity);
  427. }
  428.  
  429. void Entity::bringToFront()
  430. {
  431.     if(parent != NULL)
  432.     {
  433.         parent->bringToFront(this);
  434.     }
  435. }
  436.  
  437. void Entity::remove()
  438. {
  439.     if(parent != NULL)
  440.     {
  441.         parent->removeEntity(this);
  442.     }
  443. }
  444.  
  445. void Entity::setFocused(bool focused)
  446. {
  447.     this->focused = focused;
  448.     if(focused)
  449.     {
  450.         onFocus();
  451.     }
  452.     else
  453.     {
  454.         onUnfocus();
  455.     }
  456. }
  457.  
  458. bool Entity::isFocused()
  459. {
  460.     return focused;
  461. }
  462.  
  463. Entity *Entity::getEntityInBounds(Dimension position)
  464. {
  465.     if(contents.size())
  466.     {
  467.         vector<Entity *>::iterator it;
  468.         for(it = contents.end() - 1; it >= contents.begin(); it--)
  469.         {
  470.             Entity *entity = *it;
  471.             if(position >= entity->getPosition() && position < entity->getPosition() + entity->getSize())
  472.             {
  473.                 return entity;
  474.             }
  475.         }
  476.     }
  477.    
  478.     return NULL;
  479. }
  480.  
  481. class TestObject: public Entity
  482. {
  483.     public:
  484.         TestObject(Dimension position, Dimension size);
  485.         ~TestObject();
  486.        
  487.     protected:
  488.         void update2();
  489.         void render2(SDL_Surface *surface);
  490.        
  491.         void onDrag(unsigned short button, Dimension position, Dimension motion);
  492.         void onFocus();
  493. };
  494.  
  495. TestObject::TestObject(Dimension position, Dimension size)
  496. {
  497.     this->position = position;
  498.     this->size = size;
  499. }
  500.  
  501. TestObject::~TestObject()
  502. {
  503.    
  504. }
  505.  
  506. void TestObject::update2()
  507. {
  508.    
  509. }
  510.  
  511. void TestObject::render2(SDL_Surface *surface)
  512. {
  513.     SDL_FillRect(surface, NULL, isFocused() ? 0xFF0000 : 0x888888);
  514. }
  515.  
  516. void TestObject::onFocus()
  517. {
  518.     bringToFront();
  519. }
  520.  
  521. void TestObject::onDrag(unsigned short button, Dimension position, Dimension motion)
  522. {
  523.     this->position = this->position + motion;
  524. }
  525.  
  526. class TestScreen: public Entity
  527. {
  528.     public:
  529.         TestScreen();
  530.         ~TestScreen();
  531.        
  532.     protected:
  533.         void update2();
  534.         void render2(SDL_Surface *surface);
  535. };
  536.  
  537. TestScreen::TestScreen()
  538. {
  539.     size = Dimension(WIDTH, HEIGHT);
  540.    
  541.     addEntity(new TestObject(Dimension(5, 5), Dimension(20, 20)));
  542.     addEntity(new TestObject(Dimension(45, 45), Dimension(20, 20)));
  543.     addEntity(new TestObject(Dimension(85, 85), Dimension(20, 20)));
  544. }
  545.  
  546. TestScreen::~TestScreen()
  547. {
  548.    
  549. }
  550.  
  551. void TestScreen::update2()
  552. {
  553.    
  554. }
  555.  
  556. void TestScreen::render2(SDL_Surface *surface)
  557. {
  558.    
  559. }
  560.  
  561. class Engine
  562. {
  563.     public:
  564.         static Engine *engine;
  565.        
  566.         Engine();
  567.         ~Engine();
  568.        
  569.         void start();
  570.         void stop();
  571.        
  572.         void setContent(Entity *content);
  573.    
  574.     private:
  575.         bool running;
  576.        
  577.         long tick;
  578.         long frame;
  579.        
  580.         Entity *content;
  581.        
  582.         SDL_Surface *surface;
  583.        
  584.         void events();
  585.         void update();
  586.         void render();
  587. };
  588.    
  589. Engine *Engine::engine;
  590.  
  591. Engine::Engine()
  592. {
  593.     engine = this;
  594.    
  595.     running = false;
  596.    
  597.     tick = 0;
  598.     frame = 0;
  599.    
  600.     content = NULL;
  601.    
  602.     SDL_Init(SDL_INIT_EVERYTHING);
  603.     SDL_WM_SetCaption("Game Engine", 0);
  604.     surface = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
  605. }
  606.  
  607. Engine::~Engine()
  608. {
  609.     stop();
  610.     SDL_Quit();
  611. }
  612.  
  613. void Engine::start()
  614. {
  615.     if(!running)
  616.     {
  617.         running = true;
  618.         while(running)
  619.         {
  620.             int now = SDL_GetTicks();
  621.            
  622.             events();
  623.             for(int i = 0; i < SPF; i++)
  624.             {
  625.                 update();
  626.                 tick++;
  627.             }
  628.             render();
  629.             frame++;
  630.            
  631.             int passed = SDL_GetTicks() - now;
  632.             int wait = 1000 / FPS;
  633.             int left = wait - passed;
  634.            
  635.             SDL_Delay(left);
  636.         }
  637.     }
  638. }
  639.  
  640. void Engine::stop()
  641. {
  642.     running = false;
  643. }
  644.  
  645. void Engine::setContent(Entity *content)
  646. {
  647.     this->content = content;
  648. }
  649.  
  650. void Engine::events()
  651. {
  652.     if(content != NULL)
  653.     {
  654.         SDL_Event event;
  655.         while(SDL_PollEvent(&event))
  656.         {
  657.             switch(event.type)
  658.             {
  659.                 case SDL_KEYDOWN:
  660.                     content->keyDown(event.key.keysym);
  661.                     break;
  662.                    
  663.                 case SDL_KEYUP:
  664.                     content->keyUp(event.key.keysym);
  665.                     break;
  666.                    
  667.                 case SDL_MOUSEBUTTONDOWN:
  668.                     content->mouseDown(event.button.button, Dimension(event.button.x, event.button.y));
  669.                     break;
  670.                    
  671.                 case SDL_MOUSEBUTTONUP:
  672.                     content->mouseUp(event.button.button, Dimension(event.button.x, event.button.y));
  673.                     break;
  674.                    
  675.                 case SDL_MOUSEMOTION:
  676.                     content->mouseMotion(Dimension(event.motion.x, event.motion.y), Dimension(event.motion.xrel, event.motion.yrel));
  677.                     break;
  678.                    
  679.                 case SDL_QUIT:
  680.                     stop();
  681.                     break;
  682.             }
  683.         }
  684.     }
  685. }
  686.  
  687. void Engine::update()
  688. {
  689.     if(content != NULL)
  690.     {
  691.         content->update();
  692.     }
  693. }
  694.  
  695. void Engine::render()
  696. {
  697.     if(content != NULL)
  698.     {
  699.         SDL_FillRect(surface, NULL, content->getBackgroundColor());
  700.         content->render(surface);
  701.         SDL_Flip(surface);
  702.     }
  703. }
  704.  
  705. int main()
  706. {
  707.     Engine engine;
  708.    
  709.     engine.setContent(new TestScreen());
  710.     engine.start();
  711.    
  712.     return 0;
  713. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement