aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog6
-rw-r--r--include/ui.hpp58
-rw-r--r--include/ui_menu.hpp63
-rw-r--r--main.cpp5
-rw-r--r--setup.mk2
-rw-r--r--src/gameplay.cpp16
-rw-r--r--src/inventory.cpp5
-rw-r--r--src/ui.cpp425
-rw-r--r--src/ui_menu.cpp275
-rw-r--r--src/world.cpp11
10 files changed, 444 insertions, 422 deletions
diff --git a/Changelog b/Changelog
index 057eb71..18d2efe 100644
--- a/Changelog
+++ b/Changelog
@@ -904,3 +904,9 @@
- fixed bug that caused game to crash idly
- fixed bug with spawning NPCs at specific coordinates
- added functionality to ui to auto-complete the next typeOut
+
+4/12/2016:
+==========
+
+ - potentially fixed inventory drawing bug
+ - moved menu library to its own file
diff --git a/include/ui.hpp b/include/ui.hpp
index a9a7f05..6fa2451 100644
--- a/include/ui.hpp
+++ b/include/ui.hpp
@@ -11,54 +11,16 @@
#include <config.hpp>
#include <world.hpp>
+#include <ui_menu.hpp>
+
#include <ft2build.h>
#include <SDL2/SDL_opengl.h>
#include <thread>
#include FT_FREETYPE_H
-#define DEBUG
+#define SDL_KEY e.key.keysym.sym
-typedef void(*menuFunc)();
-
-struct menuItem{
- int member;
- union{
- struct{
- vec2 loc;
- dim2 dim;
- Color color;
- const char* text;
- menuFunc func;
- }button;
- struct{
- vec2 loc;
- dim2 dim;
- Color color;
- float minValue;
- float maxValue;
- const char* text;
- float* var;
-
- float sliderLoc;
- }slider;
- };
-};
-
-class Menu{
-public:
- std::vector<menuItem>items;
- Menu *child;
- Menu *parent;
- ~Menu(){
- child = NULL;
- parent = NULL;
- delete child;
- delete parent;
- }
-
- void gotoChild();
- void gotoParent();
-};
+#define DEBUG
typedef uint8_t BYTE;
typedef uint16_t WORD;
@@ -87,15 +49,13 @@ typedef struct{
} __attribute__ ((packed)) BITMAPINFOHEADER;
namespace ui {
- menuItem createButton(vec2 l, dim2 d, Color c, const char* t, menuFunc f);
- menuItem createChildButton(vec2 l, dim2 d, Color c, const char* t);
- 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);
+
/**
* Contains the coordinates of the mouse inside the window.
*/
extern vec2 mouse;
+ extern vec2 premouse;
/*
* These flags are used elsewhere.
@@ -172,12 +132,8 @@ namespace ui {
void draw(void);
-
- /*
- * Draw various menu items
- */
void quitGame();
- void drawMenu(Menu* menu);
+
/*
diff --git a/include/ui_menu.hpp b/include/ui_menu.hpp
new file mode 100644
index 0000000..9a51739
--- /dev/null
+++ b/include/ui_menu.hpp
@@ -0,0 +1,63 @@
+#ifndef UI_MENU_H_
+#define UI_MENU_H_
+
+#include <common.hpp>
+#include <config.hpp>
+
+typedef void (*menuFunc)(void);
+
+struct menuItem {
+ int member;
+ union {
+ struct {
+ vec2 loc;
+ dim2 dim;
+ Color color;
+
+ const char *text;
+ menuFunc func;
+ } button;
+ struct {
+ vec2 loc;
+ dim2 dim;
+ Color color;
+
+ float minValue;
+ float maxValue;
+ float sliderLoc;
+
+ const char *text;
+ float *var;
+ } slider;
+ };
+};
+
+class Menu {
+public:
+ std::vector<menuItem> items;
+ Menu *child, *parent;
+
+ ~Menu() {
+ // TODO you CANNOT delete null pointers!
+ /*child = NULL;
+ parent = NULL;
+ delete child;
+ delete parent;*/
+ }
+
+ void gotoChild(void);
+ void gotoParent(void);
+};
+
+namespace ui {
+ namespace menu {
+ menuItem createButton(vec2 l, dim2 d, Color c, const char* t, menuFunc f);
+ menuItem createChildButton(vec2 l, dim2 d, Color c, const char* t);
+ 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 draw( void );
+ }
+}
+
+#endif // UI_MENU_H_
diff --git a/main.cpp b/main.cpp
index c344e81..837c785 100644
--- a/main.cpp
+++ b/main.cpp
@@ -709,9 +709,8 @@ void render() {
}
- if(currentMenu){
- ui::drawMenu(currentMenu);
- }
+ if ( currentMenu )
+ ui::menu::draw();
// draw the mouse cursor
glColor3ub(255,255,255);
diff --git a/setup.mk b/setup.mk
index 89bb9c3..564fa24 100644
--- a/setup.mk
+++ b/setup.mk
@@ -2,4 +2,4 @@
TARGET_OS = linux
# Bits setting, 32 or 64
-TARGET_BITS = 32
+TARGET_BITS = 64
diff --git a/src/gameplay.cpp b/src/gameplay.cpp
index 9bf9728..7b5b3ba 100644
--- a/src/gameplay.cpp
+++ b/src/gameplay.cpp
@@ -299,20 +299,20 @@ void initEverything(void){
}
}
- pauseMenu.items.push_back(ui::createParentButton({-256/2,0},{256,75},{0.0f,0.0f,0.0f}, "Resume"));
- pauseMenu.items.push_back(ui::createChildButton({-256/2,-100},{256,75},{0.0f,0.0f,0.0f}, "Options"));
- pauseMenu.items.push_back(ui::createButton({-256/2,-200},{256,75},{0.0f,0.0f,0.0f}, "Save and Quit", ui::quitGame));
- pauseMenu.items.push_back(ui::createButton({-256/2,-300},{256,75},{0.0f,0.0f,0.0f}, "Segfault", segFault));
+ 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;
pauseMenu.parent = NULL;
- optionsMenu.items.push_back(ui::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::createSlider({-200,100}, {512,50}, {0.0f, 0.0f, 0.0f}, 0, 100, "Music", &VOLUME_MUSIC));
- optionsMenu.items.push_back(ui::createSlider({-200,000}, {512,50}, {0.0f, 0.0f, 0.0f}, 0, 100, "SFX", &VOLUME_SFX));
+ 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.child = NULL;
optionsMenu.parent = &pauseMenu;
- // optionsMenu.push_back(ui::createButton({-256/2,-200},{256,75},{0.0f,0.0f,0.0f}, (const char*)("Save and Quit"), );
+ // optionsMenu.push_back(ui::menu::createButton({-256/2,-200},{256,75},{0.0f,0.0f,0.0f}, (const char*)("Save and Quit"), );
/*
* Spawn the player and begin the game.
diff --git a/src/inventory.cpp b/src/inventory.cpp
index 521b695..64254e9 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -257,7 +257,7 @@ void Inventory::draw(void){
a++;
} a = 0;
- for ( unsigned int i = 0; i < massOrder.size() ; i++, a++ ) {
+ while ( ++a < massOrder.size() ) {
if ( !a || massDfp[ massOrder[a - 1] ] > massRange * 0.75f )
massDfp[ massOrder[a] ] += 5.0f * deltaTime;
if ( massDfp[ massOrder[a] ] > massRange )
@@ -276,7 +276,8 @@ void Inventory::draw(void){
cd -= 1.0f * deltaTime;
}
- for ( unsigned int i = 0; i < massRay.size(); i++, a++ ) {
+ a = 0;
+ while ( ++a < massRay.size() ) {
if ( !a || massDfp[ massOrderClosing[a - 1] ] <= 0 )
massDfp[ massOrderClosing[a] ] -= 10.0f * deltaTime;
if ( massDfp[ massOrderClosing[a - 1] ] < 0 )
diff --git a/src/ui.cpp b/src/ui.cpp
index c102f52..731d18b 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -1,12 +1,8 @@
#include <ui.hpp>
-/*
- * Create a macro to easily access SDL keypresses
-*/
-
-#define SDL_KEY e.key.keysym.sym
-
extern std::vector<menuItem> optionsMenu;
+extern Menu *currentMenu;
+extern Menu pauseMenu;
extern SDL_Window *window;
@@ -69,14 +65,6 @@ static std::vector<vec3> merchArrowLoc ( 2, vec3 { 0, 0, 0 } );
static bool typeOutDone = true;
static bool typeOutSustain = false;
-/*
- * Menu-related objects
- */
-
-extern Menu* currentMenu;
-extern Menu pauseMenu;
-
-
static Mix_Chunk *dialogClick;
extern void mainLoop(void);
@@ -98,19 +86,6 @@ Mix_Chunk *sanic;
static GLuint pageTex = 0;
static bool pageTexReady = false;
-void Menu::gotoParent(){
- if(parent == NULL){
- currentMenu = NULL;
- config::update();
- }else{
- currentMenu = parent;
- }
-}
-
-void Menu::gotoChild(){
- currentMenu = child;
-}
-
void loadFontSize( unsigned int size, std::vector<GLuint> &tex, std::vector<FT_Info> &dat )
{
FT_Set_Pixel_Sizes(ftf,0,size);
@@ -173,7 +148,7 @@ namespace ui {
*/
vec2 mouse;
- static vec2 premouse={0,0};
+ vec2 premouse={0,0};
/*
* Variety of keydown bools
@@ -211,6 +186,8 @@ namespace ui {
unsigned int fontSize;
+ void takeScreenshot(GLubyte* pixels);
+
/*
* Initialises the Freetype library, and sets a font size.
*/
@@ -876,331 +853,6 @@ namespace ui {
config::save();
}
- menuItem createButton(vec2 l, dim2 d, Color c, const char* t, menuFunc f){
- menuItem temp;
- temp.member = 0;
-
- temp.button.loc = l;
- temp.button.dim = d;
- temp.button.color = c;
-
- temp.button.text = t;
-
- temp.button.func = f;
-
- return temp;
- }
-
- menuItem createChildButton(vec2 l, dim2 d, Color c, const char* t){
- menuItem temp;
- temp.member = -1;
-
- temp.button.loc = l;
- temp.button.dim = d;
- temp.button.color = c;
-
- temp.button.text = t;
-
- temp.button.func = NULL;
-
- return temp;
- }
-
- menuItem createParentButton(vec2 l, dim2 d, Color c, const char* t){
- menuItem temp;
- temp.member = -2;
-
- temp.button.loc = l;
- temp.button.dim = d;
- temp.button.color = c;
-
- temp.button.text = t;
-
- temp.button.func = NULL;
-
- return temp;
- }
-
- menuItem createSlider(vec2 l, dim2 d, Color c, float min, float max, const char* t, float* v){
- menuItem temp;
- temp.member = 1;
-
- temp.slider.loc = l;
- temp.slider.dim = d;
- temp.slider.color = c;
- temp.slider.minValue = min;
- temp.slider.maxValue = max;
-
- temp.slider.text = t;
-
- temp.slider.var = v;
-
- temp.slider.sliderLoc = *v;
-
- return temp;
- }
-
- /*
- * Draws the menu
- */
-
- void drawMenu(Menu *menu){
- setFontSize(24);
- config::update();
- SDL_Event e;
-
- mouse.x=premouse.x+offset.x-(SCREEN_WIDTH/2);
- mouse.y=(offset.y+SCREEN_HEIGHT/2)-premouse.y;
-
- //custom event polling for menu's so all other events are disregarded
- while(SDL_PollEvent(&e)){
- switch(e.type){
- case SDL_QUIT:
- gameRunning = false;
- return;
- break;
- case SDL_MOUSEMOTION:
- premouse.x=e.motion.x;
- premouse.y=e.motion.y;
- break;
- case SDL_KEYUP:
- if(SDL_KEY == SDLK_ESCAPE){
- menu->gotoParent();
- return;
- }
- break;
- default:break;
- }
- }
-
- //draw the dark transparent background
- glColor4f(0.0f, 0.0f, 0.0f, .8f);
- glRectf(offset.x-SCREEN_WIDTH/2,0,offset.x+SCREEN_WIDTH/2,SCREEN_HEIGHT);
-
- //loop through all elements of the menu
- for(auto &m : menu->items){
- //if the menu is any type of button
- if(m.member == 0 || m.member == -1 || m.member == -2){
-
- //draw the button background
- glColor3f(m.button.color.red,m.button.color.green,m.button.color.blue);
- glRectf(offset.x+m.button.loc.x,
- offset.y+m.button.loc.y,
- offset.x+m.button.loc.x + m.button.dim.x,
- offset.y+m.button.loc.y + m.button.dim.y);
- //draw the button text
- putStringCentered(offset.x + m.button.loc.x + (m.button.dim.x/2),
- (offset.y + m.button.loc.y + (m.button.dim.y/2)) - ui::fontSize/2,
- m.button.text);
-
- //tests if the mouse is over the button
- if(mouse.x >= offset.x+m.button.loc.x && mouse.x <= offset.x+m.button.loc.x + m.button.dim.x){
- if(mouse.y >= offset.y+m.button.loc.y && mouse.y <= offset.y+m.button.loc.y + m.button.dim.y){
-
- //if the mouse if over the button, it draws this white outline
- glColor3f(1.0f,1.0f,1.0f);
- glBegin(GL_LINE_STRIP);
- glVertex2f(offset.x+m.button.loc.x, offset.y+m.button.loc.y);
- glVertex2f(offset.x+m.button.loc.x+m.button.dim.x, offset.y+m.button.loc.y);
- glVertex2f(offset.x+m.button.loc.x+m.button.dim.x, offset.y+m.button.loc.y+m.button.dim.y);
- glVertex2f(offset.x+m.button.loc.x, offset.y+m.button.loc.y+m.button.dim.y);
- glVertex2f(offset.x+m.button.loc.x, offset.y+m.button.loc.y);
- glEnd();
-
- //if the mouse is over the button and clicks
- if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
- switch(m.member){
- case 0: //normal button
- m.button.func();
- break;
- case -1:
- menu->gotoChild(); //goto child menu
- break;
- case -2:
- menu->gotoParent(); //goto parent menu
- default:break;
- }
- }
- }
- }
-
- //if element is a slider
- }else if(m.member == 1){
- //combining slider text with variable amount
- char outSV[32];
- sprintf(outSV, "%s: %.1f",m.slider.text, *m.slider.var);
-
- float sliderW, sliderH;
-
- if(m.slider.dim.y > m.slider.dim.x){
- //width of the slider handle
- sliderW = m.slider.dim.x;
- sliderH = m.slider.dim.y * .05;
- //location of the slider handle
- m.slider.sliderLoc = m.slider.minValue + (*m.slider.var/m.slider.maxValue)*(m.slider.dim.y-sliderW);
- }else{
- //width of the slider handle
- sliderW = m.slider.dim.x * .05;
- sliderH = m.slider.dim.y;
- //location of the slider handle
- m.slider.sliderLoc = m.slider.minValue + (*m.slider.var/m.slider.maxValue)*(m.slider.dim.x-sliderW);
- }
- //draw the background of the slider
- glColor4f(m.slider.color.red,m.slider.color.green,m.slider.color.blue, .5f);
- glRectf(offset.x+m.slider.loc.x,
- offset.y+m.slider.loc.y,
- offset.x+m.slider.loc.x + m.slider.dim.x,
- offset.y+m.slider.loc.y + m.slider.dim.y);
-
- //draw the slider handle
- glColor4f(m.slider.color.red,m.slider.color.green,m.slider.color.blue, 1.0f);
- if(m.slider.dim.y > m.slider.dim.x){
- glRectf(offset.x+m.slider.loc.x,
- offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05),
- offset.x+m.slider.loc.x + sliderW,
- offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05) + sliderH);
-
- //draw the now combined slider text
- putStringCentered(offset.x + m.slider.loc.x + (m.slider.dim.x/2), (offset.y + m.slider.loc.y + (m.slider.dim.y*1.05)) - ui::fontSize/2, outSV);
- }else{
- glRectf(offset.x+m.slider.loc.x+m.slider.sliderLoc,
- offset.y+m.slider.loc.y,
- offset.x+m.slider.loc.x + m.slider.sliderLoc + sliderW,
- offset.y+m.slider.loc.y + sliderH);
-
- //draw the now combined slider text
- putStringCentered(offset.x + m.slider.loc.x + (m.slider.dim.x/2), (offset.y + m.slider.loc.y + (m.slider.dim.y/2)) - ui::fontSize/2, outSV);
- }
- //test if mouse is inside of the slider's borders
- if(mouse.x >= offset.x+m.slider.loc.x && mouse.x <= offset.x+m.slider.loc.x + m.slider.dim.x){
- if(mouse.y >= offset.y+m.slider.loc.y && mouse.y <= offset.y+m.slider.loc.y + m.slider.dim.y){
-
- //if it is we draw a white border around it
- glColor3f(1.0f,1.0f,1.0f);
- glBegin(GL_LINE_STRIP);
- glVertex2f(offset.x+m.slider.loc.x, offset.y+m.slider.loc.y);
- glVertex2f(offset.x+m.slider.loc.x+m.slider.dim.x, offset.y+m.slider.loc.y);
- glVertex2f(offset.x+m.slider.loc.x+m.slider.dim.x, offset.y+m.slider.loc.y+m.slider.dim.y);
- glVertex2f(offset.x+m.slider.loc.x, offset.y+m.slider.loc.y+m.slider.dim.y);
- glVertex2f(offset.x+m.slider.loc.x, offset.y+m.slider.loc.y);
-
- if(m.slider.dim.y > m.slider.dim.x){
- //and a border around the slider handle
- glVertex2f(offset.x+m.slider.loc.x, offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05));
- glVertex2f(offset.x+m.slider.loc.x + sliderW, offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05));
- glVertex2f(offset.x+m.slider.loc.x + sliderW, offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05) + sliderH);
- glVertex2f(offset.x+m.slider.loc.x, offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05) + sliderH);
- glVertex2f(offset.x+m.slider.loc.x, offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05));
- }else{
- //and a border around the slider handle
- glVertex2f(offset.x+m.slider.loc.x + m.slider.sliderLoc, offset.y+m.slider.loc.y);
- glVertex2f(offset.x+m.slider.loc.x + (m.slider.sliderLoc + sliderW), offset.y+m.slider.loc.y);
- glVertex2f(offset.x+m.slider.loc.x + (m.slider.sliderLoc + sliderW), offset.y+m.slider.loc.y+m.slider.dim.y);
- glVertex2f(offset.x+m.slider.loc.x + m.slider.sliderLoc, offset.y+m.slider.loc.y+m.slider.dim.y);
- glVertex2f(offset.x+m.slider.loc.x + m.slider.sliderLoc, offset.y+m.slider.loc.y);
- }
-
- glEnd();
-
- //if we are inside the slider and click it will set the slider to that point
- if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
- //change handle location
- if(m.slider.dim.y > m.slider.dim.x){
- *m.slider.var = (((mouse.y-offset.y) - m.slider.loc.y)/m.slider.dim.y)*100;
- //draw a white box over the handle
- glColor3f(1.0f,1.0f,1.0f);
- glRectf(offset.x+m.slider.loc.x,
- offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05),
- offset.x+m.slider.loc.x + sliderW,
- offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05) + sliderH);
-
- }else{
- *m.slider.var = (((mouse.x-offset.x) - m.slider.loc.x)/m.slider.dim.x)*100;
- //draw a white box over the handle
- glColor3f(1.0f,1.0f,1.0f);
- glRectf(offset.x+m.slider.loc.x + m.slider.sliderLoc,
- offset.y+m.slider.loc.y,
- offset.x+m.slider.loc.x + (m.slider.sliderLoc + sliderW),
- offset.y+m.slider.loc.y + m.slider.dim.y);
- }
- }
-
- //makes sure handle can't go below or above min and max values
- if(*m.slider.var >= m.slider.maxValue)*m.slider.var = m.slider.maxValue;
- else if(*m.slider.var <= m.slider.minValue)*m.slider.var = m.slider.minValue;
- }
- }
- }
- }
- setFontSize(16);
- }
-
- void takeScreenshot(GLubyte* pixels){
- std::vector<GLubyte> bgr (SCREEN_WIDTH * SCREEN_HEIGHT * 3, 0);
-
- for(uint x = 0; x < SCREEN_WIDTH*SCREEN_HEIGHT*3; x+=3){
- bgr[x] = pixels[x+2];
- bgr[x+1] = pixels[x+1];
- bgr[x+2] = pixels[x];
- }
-
- time_t epoch = time(NULL);
- struct tm* timen = localtime(&epoch);
-
- std::string name = "screenshots/";
- name += std::to_string(1900 + timen->tm_year) += "-";
- name += std::to_string(timen->tm_mon + 1) += "-";
- name += std::to_string(timen->tm_mday) += "_";
- name += std::to_string(timen->tm_hour) += "-";
- name += std::to_string(timen->tm_min) += "-";
- name += std::to_string(timen->tm_sec);
- name += ".bmp";
- FILE* bmp = fopen(name.c_str(), "w+");
-
- // unsigned long header_size = sizeof(BITMAPFILEHEADER) +
- // sizeof(BITMAPINFOHEADER);
-
- BITMAPFILEHEADER bmfh;
- BITMAPINFOHEADER bmih;
-
- memset(&bmfh, 0, sizeof(BITMAPFILEHEADER));
- memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
-
- bmfh.bfType = 0x4d42;
-
- bmfh.bfOffBits = 54;
- bmfh.bfSize = sizeof(BITMAPFILEHEADER) +
- sizeof(BITMAPINFOHEADER);
- bmfh.bfReserved1 = 0;
- bmfh.bfReserved2 = 0;
-
-
- bmih.biSize = sizeof(BITMAPINFOHEADER);
- bmih.biBitCount = 24;
-
- bmih.biClrImportant = 0;
- bmih.biClrUsed = 0;
-
- bmih.biCompression = 0;
-
- bmih.biWidth = SCREEN_WIDTH;
- bmih.biHeight = SCREEN_HEIGHT;
-
- bmih.biPlanes = 1;
- bmih.biSizeImage = 0;
-
- bmih.biXPelsPerMeter = 0x0ec4;
- bmih.biYPelsPerMeter = 0x0ec4;
-
- fwrite(&bmfh, 1,sizeof(BITMAPFILEHEADER),bmp);
- fwrite(&bmih, 1,sizeof(BITMAPINFOHEADER),bmp);
- fwrite(&bgr, 1,3*SCREEN_WIDTH*SCREEN_HEIGHT,bmp);
-
- delete[] pixels;
-
- fclose(bmp);
- }
-
void closeBox(){
dialogBoxExists = false;
dialogMerchant = false;
@@ -1294,6 +946,7 @@ EXIT:
if ( ig ) {
ig->vel.x = (fr.x - mouse.x) / 50.0f;
ig->vel.y = (fr.y - mouse.y) / 50.0f;
+ //ig->forcedMove = true; // kills vel.x too quickly
ig = NULL;
}
break;
@@ -1574,4 +1227,70 @@ EXIT:
Mix_PlayChannel( 1, battleStart, 0 );
}
+
+ void takeScreenshot(GLubyte* pixels){
+ std::vector<GLubyte> bgr (SCREEN_WIDTH * SCREEN_HEIGHT * 3, 0);
+
+ for(uint x = 0; x < SCREEN_WIDTH*SCREEN_HEIGHT*3; x+=3){
+ bgr[x] = pixels[x+2];
+ bgr[x+1] = pixels[x+1];
+ bgr[x+2] = pixels[x];
+ }
+
+ time_t epoch = time(NULL);
+ struct tm* timen = localtime(&epoch);
+
+ std::string name = "screenshots/";
+ name += std::to_string(1900 + timen->tm_year) += "-";
+ name += std::to_string(timen->tm_mon + 1) += "-";
+ name += std::to_string(timen->tm_mday) += "_";
+ name += std::to_string(timen->tm_hour) += "-";
+ name += std::to_string(timen->tm_min) += "-";
+ name += std::to_string(timen->tm_sec);
+ name += ".bmp";
+ FILE* bmp = fopen(name.c_str(), "w+");
+
+ // unsigned long header_size = sizeof(BITMAPFILEHEADER) +
+ // sizeof(BITMAPINFOHEADER);
+
+ BITMAPFILEHEADER bmfh;
+ BITMAPINFOHEADER bmih;
+
+ memset(&bmfh, 0, sizeof(BITMAPFILEHEADER));
+ memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
+
+ bmfh.bfType = 0x4d42;
+
+ bmfh.bfOffBits = 54;
+ bmfh.bfSize = sizeof(BITMAPFILEHEADER) +
+ sizeof(BITMAPINFOHEADER);
+ bmfh.bfReserved1 = 0;
+ bmfh.bfReserved2 = 0;
+
+
+ bmih.biSize = sizeof(BITMAPINFOHEADER);
+ bmih.biBitCount = 24;
+
+ bmih.biClrImportant = 0;
+ bmih.biClrUsed = 0;
+
+ bmih.biCompression = 0;
+
+ bmih.biWidth = SCREEN_WIDTH;
+ bmih.biHeight = SCREEN_HEIGHT;
+
+ bmih.biPlanes = 1;
+ bmih.biSizeImage = 0;
+
+ bmih.biXPelsPerMeter = 0x0ec4;
+ bmih.biYPelsPerMeter = 0x0ec4;
+
+ fwrite(&bmfh, 1,sizeof(BITMAPFILEHEADER),bmp);
+ fwrite(&bmih, 1,sizeof(BITMAPINFOHEADER),bmp);
+ fwrite(&bgr, 1,3*SCREEN_WIDTH*SCREEN_HEIGHT,bmp);
+
+ delete[] pixels;
+
+ fclose(bmp);
+ }
}
diff --git a/src/ui_menu.cpp b/src/ui_menu.cpp
new file mode 100644
index 0000000..775ea81
--- /dev/null
+++ b/src/ui_menu.cpp
@@ -0,0 +1,275 @@
+#include <ui_menu.hpp>
+
+extern bool gameRunning;
+
+extern Menu *currentMenu;
+extern Menu pauseMenu;
+
+void Menu::
+gotoParent( void )
+{
+ if ( !parent ) {
+ currentMenu = NULL;
+ config::update();
+ } else
+ currentMenu = parent;
+}
+
+void Menu::
+gotoChild( void )
+{
+ currentMenu = child;
+}
+
+namespace ui {
+ namespace menu {
+ menuItem createButton(vec2 l, dim2 d, Color c, const char* t, menuFunc f){
+ menuItem temp;
+
+ temp.member = 0;
+ temp.button.loc = l;
+ temp.button.dim = d;
+ temp.button.color = c;
+ temp.button.text = t;
+ temp.button.func = f;
+
+ return temp;
+ }
+
+ menuItem createChildButton(vec2 l, dim2 d, Color c, const char* t){
+ menuItem temp;
+
+ temp.member = -1;
+ temp.button.loc = l;
+ temp.button.dim = d;
+ temp.button.color = c;
+ temp.button.text = t;
+ temp.button.func = NULL;
+
+ return temp;
+ }
+
+ menuItem createParentButton(vec2 l, dim2 d, Color c, const char* t){
+ menuItem temp;
+
+ temp.member = -2;
+ temp.button.loc = l;
+ temp.button.dim = d;
+ temp.button.color = c;
+ temp.button.text = t;
+ temp.button.func = NULL;
+
+ return temp;
+ }
+
+ menuItem createSlider(vec2 l, dim2 d, Color c, float min, float max, const char* t, float* v){
+ menuItem temp;
+
+ temp.member = 1;
+ temp.slider.loc = l;
+ temp.slider.dim = d;
+ temp.slider.color = c;
+ temp.slider.minValue = min;
+ temp.slider.maxValue = max;
+ temp.slider.text = t;
+ temp.slider.var = v;
+ temp.slider.sliderLoc = *v;
+
+ return temp;
+ }
+
+ void draw( void ) {
+ SDL_Event e;
+
+ setFontSize(24);
+ config::update();
+
+ mouse.x = ui::premouse.x+offset.x-(SCREEN_WIDTH/2);
+ mouse.y = (offset.y+SCREEN_HEIGHT/2)-ui::premouse.y;
+
+ //custom event polling for menu's so all other events are ignored
+ while(SDL_PollEvent(&e)){
+ switch(e.type){
+ case SDL_QUIT:
+ gameRunning = false;
+ return;
+ break;
+ case SDL_MOUSEMOTION:
+ premouse.x=e.motion.x;
+ premouse.y=e.motion.y;
+ break;
+ case SDL_KEYUP:
+ if(SDL_KEY == SDLK_ESCAPE){
+ currentMenu->gotoParent();
+ return;
+ }
+ break;
+ default:break;
+ }
+ }
+
+ //draw the dark transparent background
+ glColor4f(0.0f, 0.0f, 0.0f, .8f);
+ glRectf(offset.x-SCREEN_WIDTH/2,0,offset.x+SCREEN_WIDTH/2,SCREEN_HEIGHT);
+
+ //loop through all elements of the menu
+ for(auto &m : currentMenu->items){
+ //if the menu is any type of button
+ if(m.member == 0 || m.member == -1 || m.member == -2){
+
+ //draw the button background
+ glColor3f(m.button.color.red,m.button.color.green,m.button.color.blue);
+ glRectf(offset.x+m.button.loc.x,
+ offset.y+m.button.loc.y,
+ offset.x+m.button.loc.x + m.button.dim.x,
+ offset.y+m.button.loc.y + m.button.dim.y);
+ //draw the button text
+ putStringCentered(offset.x + m.button.loc.x + (m.button.dim.x/2),
+ (offset.y + m.button.loc.y + (m.button.dim.y/2)) - ui::fontSize/2,
+ m.button.text);
+
+ //tests if the mouse is over the button
+ if(mouse.x >= offset.x+m.button.loc.x && mouse.x <= offset.x+m.button.loc.x + m.button.dim.x){
+ if(mouse.y >= offset.y+m.button.loc.y && mouse.y <= offset.y+m.button.loc.y + m.button.dim.y){
+
+ //if the mouse if over the button, it draws this white outline
+ glColor3f(1.0f,1.0f,1.0f);
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(offset.x+m.button.loc.x, offset.y+m.button.loc.y);
+ glVertex2f(offset.x+m.button.loc.x+m.button.dim.x, offset.y+m.button.loc.y);
+ glVertex2f(offset.x+m.button.loc.x+m.button.dim.x, offset.y+m.button.loc.y+m.button.dim.y);
+ glVertex2f(offset.x+m.button.loc.x, offset.y+m.button.loc.y+m.button.dim.y);
+ glVertex2f(offset.x+m.button.loc.x, offset.y+m.button.loc.y);
+ glEnd();
+
+ //if the mouse is over the button and clicks
+ if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
+ switch(m.member){
+ case 0: //normal button
+ m.button.func();
+ break;
+ case -1:
+ currentMenu->gotoChild();
+ break;
+ case -2:
+ currentMenu->gotoParent();
+ default:break;
+ }
+ }
+ }
+ }
+
+ //if element is a slider
+ }else if(m.member == 1){
+ //combining slider text with variable amount
+ char outSV[32];
+ sprintf(outSV, "%s: %.1f",m.slider.text, *m.slider.var);
+
+ float sliderW, sliderH;
+
+ if(m.slider.dim.y > m.slider.dim.x){
+ //width of the slider handle
+ sliderW = m.slider.dim.x;
+ sliderH = m.slider.dim.y * .05;
+ //location of the slider handle
+ m.slider.sliderLoc = m.slider.minValue + (*m.slider.var/m.slider.maxValue)*(m.slider.dim.y-sliderW);
+ }else{
+ //width of the slider handle
+ sliderW = m.slider.dim.x * .05;
+ sliderH = m.slider.dim.y;
+ //location of the slider handle
+ m.slider.sliderLoc = m.slider.minValue + (*m.slider.var/m.slider.maxValue)*(m.slider.dim.x-sliderW);
+ }
+ //draw the background of the slider
+ glColor4f(m.slider.color.red,m.slider.color.green,m.slider.color.blue, .5f);
+ glRectf(offset.x+m.slider.loc.x,
+ offset.y+m.slider.loc.y,
+ offset.x+m.slider.loc.x + m.slider.dim.x,
+ offset.y+m.slider.loc.y + m.slider.dim.y);
+
+ //draw the slider handle
+ glColor4f(m.slider.color.red,m.slider.color.green,m.slider.color.blue, 1.0f);
+ if(m.slider.dim.y > m.slider.dim.x){
+ glRectf(offset.x+m.slider.loc.x,
+ offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05),
+ offset.x+m.slider.loc.x + sliderW,
+ offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05) + sliderH);
+
+ //draw the now combined slider text
+ putStringCentered(offset.x + m.slider.loc.x + (m.slider.dim.x/2), (offset.y + m.slider.loc.y + (m.slider.dim.y*1.05)) - ui::fontSize/2, outSV);
+ }else{
+ glRectf(offset.x+m.slider.loc.x+m.slider.sliderLoc,
+ offset.y+m.slider.loc.y,
+ offset.x+m.slider.loc.x + m.slider.sliderLoc + sliderW,
+ offset.y+m.slider.loc.y + sliderH);
+
+ //draw the now combined slider text
+ putStringCentered(offset.x + m.slider.loc.x + (m.slider.dim.x/2), (offset.y + m.slider.loc.y + (m.slider.dim.y/2)) - ui::fontSize/2, outSV);
+ }
+ //test if mouse is inside of the slider's borders
+ if(mouse.x >= offset.x+m.slider.loc.x && mouse.x <= offset.x+m.slider.loc.x + m.slider.dim.x){
+ if(mouse.y >= offset.y+m.slider.loc.y && mouse.y <= offset.y+m.slider.loc.y + m.slider.dim.y){
+
+ //if it is we draw a white border around it
+ glColor3f(1.0f,1.0f,1.0f);
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(offset.x+m.slider.loc.x, offset.y+m.slider.loc.y);
+ glVertex2f(offset.x+m.slider.loc.x+m.slider.dim.x, offset.y+m.slider.loc.y);
+ glVertex2f(offset.x+m.slider.loc.x+m.slider.dim.x, offset.y+m.slider.loc.y+m.slider.dim.y);
+ glVertex2f(offset.x+m.slider.loc.x, offset.y+m.slider.loc.y+m.slider.dim.y);
+ glVertex2f(offset.x+m.slider.loc.x, offset.y+m.slider.loc.y);
+
+ if(m.slider.dim.y > m.slider.dim.x){
+ //and a border around the slider handle
+ glVertex2f(offset.x+m.slider.loc.x, offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05));
+ glVertex2f(offset.x+m.slider.loc.x + sliderW, offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05));
+ glVertex2f(offset.x+m.slider.loc.x + sliderW, offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05) + sliderH);
+ glVertex2f(offset.x+m.slider.loc.x, offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05) + sliderH);
+ glVertex2f(offset.x+m.slider.loc.x, offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05));
+ }else{
+ //and a border around the slider handle
+ glVertex2f(offset.x+m.slider.loc.x + m.slider.sliderLoc, offset.y+m.slider.loc.y);
+ glVertex2f(offset.x+m.slider.loc.x + (m.slider.sliderLoc + sliderW), offset.y+m.slider.loc.y);
+ glVertex2f(offset.x+m.slider.loc.x + (m.slider.sliderLoc + sliderW), offset.y+m.slider.loc.y+m.slider.dim.y);
+ glVertex2f(offset.x+m.slider.loc.x + m.slider.sliderLoc, offset.y+m.slider.loc.y+m.slider.dim.y);
+ glVertex2f(offset.x+m.slider.loc.x + m.slider.sliderLoc, offset.y+m.slider.loc.y);
+ }
+
+ glEnd();
+
+ //if we are inside the slider and click it will set the slider to that point
+ if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
+ //change handle location
+ if(m.slider.dim.y > m.slider.dim.x){
+ *m.slider.var = (((mouse.y-offset.y) - m.slider.loc.y)/m.slider.dim.y)*100;
+ //draw a white box over the handle
+ glColor3f(1.0f,1.0f,1.0f);
+ glRectf(offset.x+m.slider.loc.x,
+ offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05),
+ offset.x+m.slider.loc.x + sliderW,
+ offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05) + sliderH);
+
+ }else{
+ *m.slider.var = (((mouse.x-offset.x) - m.slider.loc.x)/m.slider.dim.x)*100;
+ //draw a white box over the handle
+ glColor3f(1.0f,1.0f,1.0f);
+ glRectf(offset.x+m.slider.loc.x + m.slider.sliderLoc,
+ offset.y+m.slider.loc.y,
+ offset.x+m.slider.loc.x + (m.slider.sliderLoc + sliderW),
+ offset.y+m.slider.loc.y + m.slider.dim.y);
+ }
+ }
+
+ //makes sure handle can't go below or above min and max values
+ if(*m.slider.var >= m.slider.maxValue)*m.slider.var = m.slider.maxValue;
+ else if(*m.slider.var <= m.slider.minValue)*m.slider.var = m.slider.minValue;
+ }
+ }
+ }
+ }
+ setFontSize(16);
+ }
+
+
+ }
+}
diff --git a/src/world.cpp b/src/world.cpp
index 0e7e41e..be8e682 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -259,8 +259,8 @@ generate( unsigned int width )
// create slopes from the points that were just defined, populate the rest of the WorldData structure
- for(wditer = worldData.begin(); wditer != worldData.end(); wditer++){
- if ((*wditer).groundHeight)
+ for(wditer = worldData.begin() + 1; wditer != worldData.end(); wditer++){
+ if ( (*wditer).groundHeight && wditer + GROUND_HILLINESS < worldData.end() )
// wditer + GROUND_HILLINESS can go out of bounds (invalid read)
geninc = ( (*(wditer + GROUND_HILLINESS)).groundHeight - (*wditer).groundHeight ) / (float)GROUND_HILLINESS;
else
@@ -1152,14 +1152,17 @@ goInsideStructure( Player *p )
void World::
addHole( unsigned int start, unsigned int end )
{
- for ( unsigned int i = end; i-- > start; )
+ if ( end > worldData.size() )
+ end = worldData.size();
+
+ for ( unsigned int i = start; i < end; i++ )
worldData[i].groundHeight = 0;
}
void World::
addHill( const ivec2 peak, const unsigned int width )
{
- int start = peak.x - width / 2, end = start + width, offset;
+ int start = peak.x - width / 2, end = start + width, offset = 0;
const float thing = peak.y - worldData[start].groundHeight;
const float period = PI / width;