]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
library-ized ticks
authorClyne Sullivan <tullivan99@gmail.com>
Sun, 24 Apr 2016 13:53:48 +0000 (09:53 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Sun, 24 Apr 2016 13:53:48 +0000 (09:53 -0400)
13 files changed:
include/common.hpp
include/entities.hpp
include/gametime.hpp [new file with mode: 0644]
include/ui.hpp
include/ui_menu.hpp
main.cpp
src/entities.cpp
src/gameplay.cpp
src/gametime.cpp [new file with mode: 0644]
src/inventory.cpp
src/ui.cpp
src/ui_menu.cpp
src/world.cpp

index 9211d56fa05ba47c76c6a7f9989f63aab50d6fe7..7f36be246dbbffb7c2d1867f18702141238445ca 100644 (file)
@@ -224,22 +224,10 @@ extern float VOLUME_SFX;
 #define PI 3.1415926535
 
 
-/**
- * References the variable in main.cpp, used for smoother drawing.
- */
-
-extern unsigned int deltaTime;
-
-/**
- * References the variable in main.cpp, used for drawing with the player.
- */
-
+// references the variable in main.cpp, used for drawing with the player
 extern vec2 offset;
 
-/**
- * Counts the number of times logic() (see main.cpp) has been called, for animating
- * sprites.
- */
+// counts the number of times logic() (see main.cpp) has been called, for animating sprites
 extern unsigned int loops;
 
 extern GLuint shaderProgram;
index 460dc9326ccd2f848d99e964f56ede461d9a563e..720141cacd198299bf1ac7c90da386fee82b7122 100644 (file)
@@ -156,61 +156,19 @@ public:
        bool bounce;
 
        // creates a particle with the desired characteristics
-       Particles(float x, float y, float w, float h, float vx, float vy, Color c, float d){
-               loc = vec2 {x, y};
-               vel = vec2 {vx, vy};
-               width = w;
-               height = h;
-               color = c;
-               duration = d;
-               gravity = true;
-               fountain = false;
-               behind = false;
-               bounce = false;
-               index = Texture::getIndex(c);
-       }
+       Particles(float x, float y, float w, float h, float vx, float vy, Color c, float d);
 
        // allows the particle to be destroyed
        ~Particles(void){}
 
        // draws the particle
-       void draw(void) const {
-               glColor3ub(255, 255, 255);
-               glBegin(GL_QUADS);
-                       vec2 tc = vec2 {0.25f * index.x, 0.125f * index.y};
-                       glTexCoord2f(tc.x, tc.y); glVertex2i(loc.x        , loc.y);
-                       glTexCoord2f(tc.x, tc.y); glVertex2i(loc.x + width, loc.y);
-                       glTexCoord2f(tc.x, tc.y); glVertex2i(loc.x + width, loc.y + height);
-                       glTexCoord2f(tc.x, tc.y); glVertex2i(loc.x        , loc.y + height);
-               glEnd();
-       }
+       void draw(void) const;
 
        // updates a particle
-       void update(float _gravity, float ground_y) {
-               // handle ground collision
-               if (loc.y < ground_y) {
-                       loc.y = ground_y;
-
-                       // handle bounce
-                       if (bounce) {
-                               vel.y *= -0.2f;
-                               vel.x /= 4.0f;
-                       } else {
-                               vel = 0.0f;
-                               canMove = false;
-                       }
-               }
-
-               // handle gravity
-               else if (gravity && vel.y > -1.0f) {
-                       vel.y -= _gravity * deltaTime;
-               }
-       }
+       void update(float _gravity, float ground_y);
 
        // returns true if the particle should be killed
-       bool kill(float delta) {
-               return (duration -= delta) <= 0;
-       }
+       bool kill(float delta);
 };
 
 /**
diff --git a/include/gametime.hpp b/include/gametime.hpp
new file mode 100644 (file)
index 0000000..c2991d2
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef GAMETIME_H_
+#define GAMETIME_H_
+
+namespace gtime {
+    void setTickCount(unsigned int t);
+    unsigned int getTickCount(void);
+    unsigned int getDeltaTime(void);
+
+    void tick(void);
+    void tick(unsigned int ticks);
+    bool tickHasPassed(void);
+
+    void mainLoopHandler(void);
+}
+
+#endif // GAMETIME_H_
index 477c9c3aaf15d30b4e16cfae2fd82cc73c1f61af..9e694977e87de45f1c436e87d3b5e8eb68c05b47 100644 (file)
@@ -1,67 +1,88 @@
-/** @file ui.h
- * @brief Contains functions for handling the user interface.
- */
-
+/* ----------------------------------------------------------------------------
+** The user interface system.
+**
+** This file contains everything user-interface related.
+** --------------------------------------------------------------------------*/
 #ifndef UI_H
 #define UI_H
 
-#include <common.hpp>
-#include <inventory.hpp>
+#define DEBUG
+#define SDL_KEY e.key.keysym.sym
+
+/* ----------------------------------------------------------------------------
+** Includes section
+** --------------------------------------------------------------------------*/
+
+// standard library headers
 #include <cstdarg>
+#include <cstdint>
+#include <thread>
 
+// local game headers
+#include <common.hpp>
 #include <config.hpp>
-#include <world.hpp>
-
+#include <inventory.hpp>
 #include <ui_menu.hpp>
 #include <ui_action.hpp>
+#include <world.hpp>
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
+// local library headers
 #include <SDL2/SDL_opengl.h>
-#include <thread>
 
-#define SDL_KEY e.key.keysym.sym
+#include <ft2build.h>
+#include FT_FREETYPE_H
 
-#define DEBUG
+/* ----------------------------------------------------------------------------
+** Structures section
+** --------------------------------------------------------------------------*/
 
-typedef struct{
-       uint16_t        bfType;
-       uint32_t        bfSize;
-       uint16_t        bfReserved1, bfReserved2;
-       uint32_t        bfOffBits; //how many bytes before the image data
-} __attribute__ ((packed)) BITMAPFILEHEADER;
-
-typedef struct{
-       uint32_t        biSize; //size of header in bytes
-        int32_t        biWidth;
-        int32_t        biHeight;
-       uint16_t        biPlanes;
-       uint16_t        biBitCount; //how many bits are in a pixel
-       uint32_t        biCompression;
-       uint32_t        biSizeImage; //size of image in bytes
-        int32_t        biXPelsPerMeter;
-        int32_t        biYPelsPerMeter;
-       uint32_t        biClrUsed; //how many colors there are
-       uint32_t        biClrImportant; //important colors
-} __attribute__ ((packed)) BITMAPINFOHEADER;
+/**
+ * Defines the layout of a bitmap (.bmp) file's header.
+ */
+typedef struct {
+       uint16_t bfType;
+       uint32_t bfSize;
+       uint16_t bfReserved1;
+       uint16_t bfReserved2;
+       uint32_t bfOffBits;
+} __attribute__((packed)) BITMAPFILEHEADER;
+
+/**
+ * Defines the layout of a bitmap's info header.
+ */
+typedef struct {
+       uint32_t biSize;
+        int32_t biWidth;
+        int32_t biHeight;
+       uint16_t biPlanes;
+       uint16_t biBitCount;
+       uint32_t biCompression;
+       uint32_t biSizeImage;
+        int32_t biXPelsPerMeter;
+        int32_t biYPelsPerMeter;
+       uint32_t biClrUsed;
+       uint32_t biClrImportant;
+} __attribute__((packed)) BITMAPINFOHEADER;
+
+/* ----------------------------------------------------------------------------
+** The UI namespace
+** --------------------------------------------------------------------------*/
 
 namespace ui {
 
-       /**
-        *      Contains the coordinates of the mouse inside the window.
-        */
-
+       // the pixel-coordinates of the mouse
        extern vec2 mouse;
-    extern vec2 premouse;
 
-       /*
-        *      These flags are used elsewhere.
-       */
+       // raw mouse values from SDL
+    extern vec2 premouse;
 
+       // the currently used font size for text rendering
        extern unsigned int fontSize;
 
+       // shows the debug overlay when set to true
        extern bool debug;
+
+       // shows tracers when set to true (alongside `debug`)
        extern bool posFlag;
 
        extern unsigned char dialogOptChosen;
@@ -130,6 +151,8 @@ namespace ui {
        */
 
        void draw(void);
+       void drawFade(void);
+       void fadeUpdate(void);
 
        void quitGame();
 
index f9ce39783fbd6aaa1b5a711331c25af1ce14d79e..1ec7ff3b57c3b35f9c49389a2911a0801432ea18 100644 (file)
@@ -67,6 +67,8 @@ namespace ui {
         menuItem createParentButton(vec2 l, dim2 d, Color c, const char* t);
         menuItem createSlider(vec2 l, dim2 d, Color c, float min, float max, const char* t, float* v);
 
+               void init(void);
+               void toggle(void);
         void draw(void);
     }
 }
index fa724949a7d7af8eba24e85aa5051a592cdc02b4..56d82cdb58ed90ea67450a4464ae830a755ea68b 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -15,6 +15,7 @@ using namespace tinyxml2;
 #include <entities.hpp>
 #include <world.hpp>
 #include <ui.hpp>
+#include <gametime.hpp>
 
 // SDL's window object
 SDL_Window *window = NULL;
@@ -27,21 +28,11 @@ World *currentWorld        = NULL,
          *currentWorldToLeft  = NULL,
          *currentWorldToRight = NULL;
 
+Menu *currentMenu;
+
 // the player object
 Player *player;
 
-/**
- * The current number of ticks, used for logic operations and day/night cycles.
- */
-
-unsigned int tickCount = 0;
-
-/**
- * TODO
- */
-
-unsigned int deltaTime = 0;
-
 /**
  * TODO
  */
@@ -95,20 +86,10 @@ unsigned int loops = 0;
 
 vec2 offset;
 
-//std::shared_ptr<Menu>currentMenu;
-Menu *currentMenu;
-Menu optionsMenu;
-Menu pauseMenu;
-
 std::string xmlFolder;
 
 extern WorldWeather weather;
 
-extern int  fadeIntensity;     // ui.cpp
-extern bool fadeEnable;                // ui.cpp
-extern bool fadeWhite;         // ui.cpp
-extern bool fadeFast;          // ui.cpp
-
 unsigned int SCREEN_WIDTH;
 unsigned int SCREEN_HEIGHT;
 unsigned int HLINE;
@@ -335,8 +316,6 @@ int main(int argc, char *argv[]){
         * src/gameplay.cpp
         */
 
-       fadeIntensity = 250;
-
        initEverything();
 
        if(!currentWorld){
@@ -363,8 +342,8 @@ int main(int argc, char *argv[]){
 
        std::cout << "Num threads: " << std::thread::hardware_concurrency() << std::endl;
 
-       //currentWorld->mob.back()->followee = player;
        glClearColor(1,1,1,1);
+       //ui::toggleBlackFast();
 
        gameRunning = true;
        while (gameRunning)
@@ -402,67 +381,32 @@ static float debugY=0;
 
 void mainLoop(void){
        static unsigned int debugDiv=0;                 // A divisor used to update the debug menu if it's open
-
-       static unsigned int prevTime    = 0,    // Used for timing operations
-                                               currentTime = 0,        //
-                                               prevPrevTime= 0;        //
        World *prev;
 
-       if(!currentTime)                                                // Initialize currentTime if it hasn't been
-               currentTime=millis();
-       if(!prevTime){
-               prevTime=currentTime;
-       }
-       /*
-        * Update timing values. This is crucial to calling logic and updating the window (basically
-        * the entire game).
-        */
-
-       currentTime = millis();
-       deltaTime       = currentTime - prevTime;
-       prevTime        = currentTime;
+       gtime::mainLoopHandler();
 
        if (currentMenu)
                goto MENU;
 
-       /*
-        * Run the logic handler if MSEC_PER_TICK milliseconds have passed.
-        */
-
+       // handle keypresses - currentWorld could change here
        prev = currentWorld;
-
-       //pool.Enqueue(ui::handleEvents);
        ui::handleEvents();
 
        if(prev != currentWorld){
                currentWorld->bgmPlay(prev);
                ui::dialogBoxExists = false;
        }
-       if(prevPrevTime + MSEC_PER_TICK <= currentTime){
-               //pool.Enqueue(logic);
-               logic();
-               prevPrevTime = currentTime;
-       }
 
-       /*
-        * Update player and entity coordinates.
-        */
+       if (gtime::tickHasPassed())
+               logic();
 
-       /*pool.Enqueue([](){
-               currentWorld->update(player,deltaTime);
-       });*/
-       currentWorld->update(player, deltaTime);
+       currentWorld->update(player, gtime::getDeltaTime());
        currentWorld->detect(player);
 
-       /*
-        * Update debug variables if necessary
-        */
-
        if (++debugDiv == 20) {
                debugDiv=0;
 
-               if (deltaTime)
-                       fps = 1000 / deltaTime;
+               fps = 1000 / gtime::getDeltaTime();
                if (!(debugDiv % 10))
                        debugY = player->loc.y;
        }
@@ -580,18 +524,7 @@ void render() {
         * Here we draw a black overlay if it's been requested.
         */
 
-       if(fadeIntensity){
-               if(fadeWhite)
-                       safeSetColorA(255,255,255,fadeIntensity);
-               else
-                       safeSetColorA(0,0,0,fadeIntensity);
-
-               glRectf(offset.x-SCREEN_WIDTH /2,
-                               offset.y-SCREEN_HEIGHT/2,
-                               offset.x+SCREEN_WIDTH /2,
-                               offset.y+SCREEN_HEIGHT/2);
-       }else if(ui::fontSize != 16)
-               ui::setFontSize(16);
+       ui::drawFade();
 
        /*
         * Draw UI elements. This includes the player's health bar and the dialog box.
@@ -615,7 +548,7 @@ void render() {
                                        currentWorld->entity.size(),// Size of entity array
                                        player->loc.x,                          // The player's x coordinate
                                        debugY,                                         // The player's y coordinate
-                                       tickCount,
+                                       gtime::getTickCount(),
                                        VOLUME_MASTER,
                                        getWorldWeatherStr(weather).c_str()
                                        );
@@ -738,7 +671,7 @@ void logic(){
         *      Switch between day and night (SUNNY and DARK) if necessary.
         */
 
-       if(!(tickCount%DAY_CYCLE)||!tickCount){
+       if (!(gtime::getTickCount() % DAY_CYCLE) || !gtime::getTickCount()){
                if (weather == WorldWeather::Sunny)
                        weather = WorldWeather::Dark;
                else {
@@ -751,21 +684,13 @@ void logic(){
         *      Calculate an in-game shading value (as opposed to GLSL shading).
        */
 
-       worldShade=50*sin((tickCount+(DAY_CYCLE/2))/(DAY_CYCLE/PI));
+       worldShade = 50 * sin((gtime::getTickCount() + (DAY_CYCLE / 2)) / (DAY_CYCLE / PI));
 
        /*
         *      Transition to and from black if necessary.
        */
 
-       if(fadeEnable){
-                        if(fadeIntensity < 150)fadeIntensity+=fadeFast?40:10;
-               else if(fadeIntensity < 255)fadeIntensity+=fadeFast?20:5;
-               else fadeIntensity = 255;
-       }else{
-                        if(fadeIntensity > 150)fadeIntensity-=fadeFast?20:5;
-               else if(fadeIntensity > 0)      fadeIntensity-=fadeFast?40:10;
-               else fadeIntensity = 0;
-       }
+       ui::fadeUpdate();
 
        /*
         * Rain?
@@ -804,6 +729,6 @@ void logic(){
        */
 
        loops++;
-       tickCount++;            // Used for day/night cycles
+       gtime::tick();
        NPCSelected=false;      // See above
 }
index 16ba7683392a710af897ffd80cf9220012a169f5..631521bba968956249908b7e7ab7bcb09532d9d6 100644 (file)
@@ -4,13 +4,13 @@
 #include <sstream>
 
 #include <ui.hpp>
+#include <gametime.hpp>
 
 extern std::istream *names;
 
 extern Player *player;                 // main.cpp
 extern World *currentWorld;            // main.cpp
 extern unsigned int loops;             // main.cpp
-extern unsigned int tickCount; // main.cpp
 
 extern std::string xmlFolder;
 
@@ -711,6 +711,8 @@ void Mob::wander(int timeRun) {
        static unsigned int heya=0,hi=0;
        static bool YAYA = false;
 
+       auto deltaTime = gtime::getDeltaTime();
+
        if (forcedMove)
                return;
 
@@ -763,7 +765,7 @@ void Mob::wander(int timeRun) {
                break;
        case MS_BIRD:
                if (loc.y<=init_y-.2)vel.y=.02*deltaTime;       // TODO handle direction
-               vel.x=.02*deltaTime;
+               vel.x = 0.02f * deltaTime;
                if (++heya==200) {heya=0;hi^=1;}
                if (hi)vel.x*=-1;
                break;
@@ -785,6 +787,60 @@ void Mob::wander(int timeRun) {
        }
 }
 
+Particles::Particles(float x, float y, float w, float h, float vx, float vy, Color c, float d)
+{
+       loc = vec2 {x, y};
+       vel = vec2 {vx, vy};
+       width = w;
+       height = h;
+       color = c;
+       duration = d;
+       gravity = true;
+       fountain = false;
+       behind = false;
+       bounce = false;
+       index = Texture::getIndex(c);
+}
+
+void Particles::draw(void) const
+{
+       glColor3ub(255, 255, 255);
+       glBegin(GL_QUADS);
+               vec2 tc = vec2 {0.25f * index.x, 0.125f * index.y};
+               glTexCoord2f(tc.x, tc.y); glVertex2i(loc.x        , loc.y);
+               glTexCoord2f(tc.x, tc.y); glVertex2i(loc.x + width, loc.y);
+               glTexCoord2f(tc.x, tc.y); glVertex2i(loc.x + width, loc.y + height);
+               glTexCoord2f(tc.x, tc.y); glVertex2i(loc.x        , loc.y + height);
+       glEnd();
+}
+
+void Particles::update(float _gravity, float ground_y)
+{
+       // handle ground collision
+       if (loc.y < ground_y) {
+               loc.y = ground_y;
+
+               // handle bounce
+               if (bounce) {
+                       vel.y *= -0.2f;
+                       vel.x /= 4.0f;
+               } else {
+                       vel = 0.0f;
+                       canMove = false;
+               }
+       }
+
+       // handle gravity
+       else if (gravity && vel.y > -1.0f) {
+               vel.y -= _gravity * gtime::getDeltaTime();
+       }
+}
+
+bool Particles::kill(float delta)
+{
+       return (duration -= delta) <= 0;
+}
+
 void Player::save(void) {
        std::string data;
        std::ofstream out ("xml/main.dat",std::ios::out | std::ios::binary);
@@ -793,7 +849,7 @@ void Player::save(void) {
        data.append(std::to_string((int)loc.y) + "\n");
        data.append(std::to_string((int)health) + "\n");
        data.append(std::to_string((int)maxHealth) + "\n");
-       data.append(std::to_string((int)tickCount) + "\n");
+       data.append(std::to_string((int)gtime::getTickCount()) + "\n");
 
        data.append(std::to_string((int)inv->items.size()) + "\n");
        for(auto &i : inv->items)
@@ -835,7 +891,7 @@ void Player::sspawn(float x,float y) {
                std::getline(data,ddata);
                maxHealth = std::stoi(ddata);
                std::getline(data,ddata);
-               tickCount = std::stoi(ddata);
+               gtime::tick(std::stoi(ddata));
 
                std::getline(data,ddata);
                for(i = std::stoi(ddata);i;i--) {
index 603ede70d9cade5e24089e1224861d2b30ee9e73..d5969ac2467ff9207863b05a14b727777199b8fd 100644 (file)
@@ -22,10 +22,6 @@ std::vector<XMLElement *> dopt;
 
 void destroyEverything(void);
 
-inline void segFault() {
-       (*((int *)NULL))++;
-}
-
 int commonAIFunc(NPC *speaker)
 {
        XMLDocument xml;
@@ -249,18 +245,6 @@ void initEverything(void) {
                }
        }
 
-       pauseMenu.items.push_back(ui::menu::createParentButton({-256/2,0},{256,75},{0.0f,0.0f,0.0f}, "Resume"));
-       pauseMenu.items.push_back(ui::menu::createChildButton({-256/2,-100},{256,75},{0.0f,0.0f,0.0f}, "Options"));
-       pauseMenu.items.push_back(ui::menu::createButton({-256/2,-200},{256,75},{0.0f,0.0f,0.0f}, "Save and Quit", ui::quitGame));
-       pauseMenu.items.push_back(ui::menu::createButton({-256/2,-300},{256,75},{0.0f,0.0f,0.0f}, "Segfault", segFault));
-       pauseMenu.child = &optionsMenu;
-
-
-       optionsMenu.items.push_back(ui::menu::createSlider({0-(float)SCREEN_WIDTH/4,0-(512/2)}, {50,512}, {0.0f, 0.0f, 0.0f}, 0, 100, "Master", &VOLUME_MASTER));
-       optionsMenu.items.push_back(ui::menu::createSlider({-200,100}, {512,50}, {0.0f, 0.0f, 0.0f}, 0, 100, "Music", &VOLUME_MUSIC));
-       optionsMenu.items.push_back(ui::menu::createSlider({-200,000}, {512,50}, {0.0f, 0.0f, 0.0f}, 0, 100, "SFX", &VOLUME_SFX));
-       optionsMenu.parent = &pauseMenu;
-
        /*
         * Spawn the player and begin the game.
         */
@@ -268,6 +252,8 @@ void initEverything(void) {
        player = new Player();
        player->sspawn(0,100);
 
+       ui::menu::init();
+
        currentWorld->bgmPlay(NULL);
        atexit(destroyEverything);
 }
diff --git a/src/gametime.cpp b/src/gametime.cpp
new file mode 100644 (file)
index 0000000..be63885
--- /dev/null
@@ -0,0 +1,50 @@
+#include <gametime.hpp>
+
+#include <common.hpp>
+
+static unsigned int tickCount = 0;
+static unsigned int deltaTime = 1;
+
+// millisecond timers
+static unsigned int currentTime = 0;
+static unsigned int prevTime, prevPrevTime;
+
+namespace gtime {
+    void setTickCount(unsigned int t) {
+        tickCount = t;
+    }
+
+    unsigned int getTickCount(void) {
+        return tickCount;
+    }
+
+    unsigned int getDeltaTime(void) {
+        return deltaTime;
+    }
+
+    void tick(void) {
+        tickCount++;
+    }
+
+    void tick(unsigned int ticks) {
+        tickCount += ticks;
+    }
+
+    void mainLoopHandler(void) {
+       if (!currentTime)
+               currentTime = prevTime = millis();
+
+       currentTime = millis();
+       deltaTime       = currentTime - prevTime;
+       prevTime        = currentTime;
+    }
+
+    bool tickHasPassed(void) {
+        if (prevPrevTime + MSEC_PER_TICK <= currentTime) {
+               prevPrevTime = currentTime;
+            return true;
+       }
+
+        return false;
+    }
+}
index 4cf5fda8df5cf976273d3da739e2d77c0ca26342..34d99edb27e1de1497e6573f8ad1b78bfd0a5732 100644 (file)
@@ -1,6 +1,7 @@
 #include <inventory.hpp>
 #include <entities.hpp>
 #include <ui.hpp>
+#include <gametime.hpp>
 
 #include <tinyxml2.h>
 using namespace tinyxml2;
@@ -230,6 +231,8 @@ void Inventory::draw(void) {
        static vec2 mouseStart = {0,0};
        C("End define");
 
+       auto deltaTime = gtime::getDeltaTime();
+
        for (auto &r : iray) {
                r.start.x = player->loc.x + (player->width  / 2);
                r.start.y = player->loc.y + (player->height / 2);
@@ -594,7 +597,7 @@ int Inventory::useItem(void)
                                }
 
                                if (up)
-                                       hangle += 0.325f * dir * deltaTime;
+                                       hangle += 0.325f * dir * gtime::getDeltaTime();
 
                                if (!player->left) {
                                        if (hangle <= -90)
index 30d08a2028ce94e41f79ed306ad03faaddc69978..8d3762d1909493998eaeab005132a686dcb54f1d 100644 (file)
@@ -1,8 +1,8 @@
 #include <ui.hpp>
 
-extern std::vector<menuItem> optionsMenu;
+#include <gametime.hpp>
+
 extern Menu* currentMenu;
-extern Menu pauseMenu;
 
 extern SDL_Window *window;
 
@@ -27,7 +27,6 @@ extern std::vector<NPC *> aipreload;
 */
 
 extern bool gameRunning;
-extern unsigned int tickCount;
 
 /*
  *     Freetype variables
@@ -73,10 +72,10 @@ extern void mainLoop(void);
  * Fade effect flags
  */
 
-bool fadeEnable = false;
-bool fadeWhite  = false;
-bool fadeFast   = false;
-unsigned int fadeIntensity = 0;
+static bool fadeEnable = false;
+static bool fadeWhite  = false;
+static bool fadeFast   = false;
+static unsigned int fadeIntensity = 0;
 
 bool inBattle = false;
 Mix_Chunk *battleStart;
@@ -411,6 +410,8 @@ namespace ui {
                                                        linc=0, //      Contains the number of letters that should be drawn.
                                                        size=0; //      Contains the full size of the current string.
 
+               auto tickCount = gtime::getTickCount();
+
                // reset values if a new string is being passed.
                if (!linc || ret.substr(0, linc) != str.substr(0, linc)) {
                        tickk = tickCount + tadv;
@@ -653,7 +654,7 @@ namespace ui {
                        if (dialogImportant) {
                                setFontColor(255,255,255);
                                if (dialogPassive) {
-                                       dialogPassiveTime -= deltaTime;
+                                       dialogPassiveTime -= gtime::getDeltaTime();
                                        if (dialogPassiveTime < 0) {
                                                dialogPassive = false;
                                                dialogImportant = false;
@@ -784,7 +785,8 @@ namespace ui {
                                        Mix_PlayChannel(1, dialogClick, 0);
                        }
 
-               }if (!fadeIntensity) {
+               }
+               if (!fadeIntensity) {
                        vec2 hub = {
                                (SCREEN_WIDTH/2+offset.x)-fontSize*10,
                                (offset.y+SCREEN_HEIGHT/2)-fontSize
@@ -1009,7 +1011,7 @@ EXIT:
                                        tmp = currentWorld;
                                        switch(SDL_KEY) {
                                        case SDLK_t:
-                                               tickCount += 50;
+                                               gtime::tick(50);
                                                break;
                                        case SDLK_a:
                                                if (fadeEnable)break;
@@ -1108,7 +1110,7 @@ EXIT:
 
                        case SDL_KEYUP:
                                if (SDL_KEY == SDLK_ESCAPE) {
-                                       currentMenu = &pauseMenu;
+                                       ui::menu::toggle();
                                        player->save();
                                        return;
                                }
@@ -1216,6 +1218,43 @@ EXIT:
                }
        }
 
+       void drawFade(void) {
+               if (!fadeIntensity) {
+                       if (fontSize != 16)
+                               setFontSize(16);
+                       return;
+               }
+
+               if (fadeWhite)
+                       safeSetColorA(255, 255, 255, fadeIntensity);
+               else
+                       safeSetColorA(0, 0, 0, fadeIntensity);
+
+               glRectf(offset.x - SCREEN_WIDTH  / 2,
+                               offset.y - SCREEN_HEIGHT / 2,
+                               offset.x + SCREEN_WIDTH  / 2,
+                               offset.y + SCREEN_HEIGHT / 2
+                           );
+       }
+
+       void fadeUpdate(void) {
+               if (fadeEnable) {
+                       if (fadeIntensity < 150)
+                               fadeIntensity += fadeFast ? 40 : 10;
+                       else if (fadeIntensity < 255)
+                               fadeIntensity += fadeFast ? 20 : 5;
+                       else
+                               fadeIntensity = 255;
+               } else {
+                       if (fadeIntensity > 150)
+                               fadeIntensity -= fadeFast ? 20 : 5;
+                       else if (fadeIntensity > 0)
+                               fadeIntensity -= fadeFast ? 40 : 10;
+                       else
+                               fadeIntensity = 0;
+               }
+       }
+
        void toggleBlack(void) {
                fadeEnable ^= true;
                fadeWhite   = false;
index cd11dae2b09ae1386ec79885cebbf039293f1d41..0c7a6d8373fec3b5edf7522d713541a55f53d850 100644 (file)
@@ -3,7 +3,9 @@
 extern bool gameRunning;
 
 extern Menu *currentMenu;
-extern Menu pauseMenu;
+
+static Menu pauseMenu;
+static Menu optionsMenu;
 
 void Menu::gotoParent(void)
 {
@@ -20,10 +22,13 @@ void Menu::gotoChild(void)
        currentMenu = child;
 }
 
+inline void segFault() {
+       (*((int *)NULL))++;
+}
+
 namespace ui {
     namespace menu {
-        menuItem createButton(vec2 l, dim2 d, Color c, const char* t, menuFunc f)
-               {
+        menuItem createButton(vec2 l, dim2 d, Color c, const char* t, menuFunc f) {
             menuItem temp;
 
             temp.member = 0;
@@ -36,8 +41,7 @@ namespace ui {
             return temp;
         }
 
-        menuItem createChildButton(vec2 l, dim2 d, Color c, const char* t)
-               {
+        menuItem createChildButton(vec2 l, dim2 d, Color c, const char* t) {
             menuItem temp;
 
             temp.member = -1;
@@ -50,8 +54,7 @@ namespace ui {
             return temp;
         }
 
-        menuItem createParentButton(vec2 l, dim2 d, Color c, const char* t)
-               {
+        menuItem createParentButton(vec2 l, dim2 d, Color c, const char* t) {
             menuItem temp;
 
             temp.member = -2;
@@ -64,8 +67,7 @@ namespace ui {
             return temp;
         }
 
-        menuItem createSlider(vec2 l, dim2 d, Color c, float min, float max, const char* t, float* v)
-               {
+        menuItem createSlider(vec2 l, dim2 d, Color c, float min, float max, const char* t, float* v) {
             menuItem temp;
 
             temp.member = 1;
@@ -81,8 +83,24 @@ namespace ui {
             return temp;
         }
 
-        void draw(void)
-               {
+               void init(void) {
+                       pauseMenu.items.push_back(ui::menu::createParentButton({-256/2,0},{256,75},{0.0f,0.0f,0.0f}, "Resume"));
+                       pauseMenu.items.push_back(ui::menu::createChildButton({-256/2,-100},{256,75},{0.0f,0.0f,0.0f}, "Options"));
+                       pauseMenu.items.push_back(ui::menu::createButton({-256/2,-200},{256,75},{0.0f,0.0f,0.0f}, "Save and Quit", ui::quitGame));
+                       pauseMenu.items.push_back(ui::menu::createButton({-256/2,-300},{256,75},{0.0f,0.0f,0.0f}, "Segfault", segFault));
+                       pauseMenu.child = &optionsMenu;
+
+                       optionsMenu.items.push_back(ui::menu::createSlider({0-(float)SCREEN_WIDTH/4,0-(512/2)}, {50,512}, {0.0f, 0.0f, 0.0f}, 0, 100, "Master", &VOLUME_MASTER));
+                       optionsMenu.items.push_back(ui::menu::createSlider({-200,100}, {512,50}, {0.0f, 0.0f, 0.0f}, 0, 100, "Music", &VOLUME_MUSIC));
+                       optionsMenu.items.push_back(ui::menu::createSlider({-200,000}, {512,50}, {0.0f, 0.0f, 0.0f}, 0, 100, "SFX", &VOLUME_SFX));
+                       optionsMenu.parent = &pauseMenu;
+               }
+
+               void toggle(void) {
+                       currentMenu = &pauseMenu;
+               }
+
+        void draw(void) {
             SDL_Event e;
 
             setFontSize(24);
index 37d899dd7c2d2b1f949e35fe18441f38401dfe94..c5ed9d00532c18398d0b89ba3ef7f4eef12ebb49 100644 (file)
@@ -10,6 +10,7 @@
 
 // local game headers
 #include <ui.hpp>
+#include <gametime.hpp>
 
 // local library headers
 #include <tinyxml2.h>
@@ -36,7 +37,6 @@ extern World       *currentWorld;                     // main.cpp
 extern World       *currentWorldToLeft;                // main.cpp
 extern World       *currentWorldToRight;       // main.cpp
 extern bool         inBattle;               // ui.cpp?
-extern unsigned int tickCount;                         // main.cpp
 extern std::string  xmlFolder;
 
 
@@ -543,6 +543,8 @@ singleDetect(Entity *e)
        unsigned int i;
        int l;
 
+    auto deltaTime = gtime::getDeltaTime();
+
        // kill dead entities
        if (!e->isAlive()) {
         return;
@@ -1356,7 +1358,7 @@ singleDetect(Entity *e)
     }
 
     if (e->vel.y > -2)
-        e->vel.y -= GRAVITY_CONSTANT * deltaTime;
+        e->vel.y -= GRAVITY_CONSTANT * gtime::getDeltaTime();
 
     if (e->ground) {
         e->loc.y = ceil(e->loc.y);
@@ -1761,7 +1763,7 @@ loadWorldFromXMLNoSave(std::string path) {
                } else if (name == "hill") {
                        tmp->addHill(ivec2 { wxml->IntAttribute("peakx"), wxml->IntAttribute("peaky") }, wxml->UnsignedAttribute("width"));
                } else if (name == "time") {
-            tickCount = std::stoi(wxml->GetText());
+            gtime::setTickCount(std::stoi(wxml->GetText()));
         } else if (Indoor && name == "floor") {
             if (wxml->QueryFloatAttribute("start",&spawnx) == XML_NO_ERROR)
                 Indoorp(tmp)->addFloor(wxml->UnsignedAttribute("width"), spawnx);