From 783143974e36856e92be3fe1b13cc6a0d0b1faeb Mon Sep 17 00:00:00 2001
From: drumsetmonkey <abelleisle@roadrunner.com>
Date: Tue, 2 Feb 2016 08:46:58 -0500
Subject: Better menus and config writing

---
 src/config.cpp   |  36 ++++++++++++
 src/gameplay.cpp |  20 ++++---
 src/ui.cpp       | 167 +++++++++++++++++++++++++++++++++++++++++--------------
 3 files changed, 175 insertions(+), 48 deletions(-)
 create mode 100644 src/config.cpp

(limited to 'src')

diff --git a/src/config.cpp b/src/config.cpp
new file mode 100644
index 0000000..31ce578
--- /dev/null
+++ b/src/config.cpp
@@ -0,0 +1,36 @@
+#include <config.h>
+
+using namespace tinyxml2;
+
+extern unsigned int HLINE;
+extern unsigned int SCREEN_WIDTH;
+extern unsigned int SCREEN_HEIGHT;
+extern bool		 	FULLSCREEN;
+
+extern float 		 VOLUME_MASTER;
+extern float 		 VOLUME_MUSIC;
+
+XMLDocument xml;
+
+void readConfig(){
+	XMLElement *scr;
+	XMLElement *vol;
+	xml.LoadFile("config/settings.xml");
+	scr = xml.FirstChildElement("screen");
+	SCREEN_WIDTH  = scr->UnsignedAttribute("width");
+	SCREEN_HEIGHT = scr->UnsignedAttribute("height");
+	FULLSCREEN    = scr->BoolAttribute("fullscreen");
+	HLINE         = xml.FirstChildElement("hline")->UnsignedAttribute("size");
+
+	vol = xml.FirstChildElement("volume");
+	VOLUME_MASTER = vol->FirstChildElement("master")->FloatAttribute("volume");
+	VOLUME_MUSIC = vol->FirstChildElement("music")->FloatAttribute("volume");
+
+}
+
+void updateConfig(){
+	XMLElement *vol = xml.FirstChildElement("volume")->FirstChildElement("master")->ToElement();
+	vol->SetAttribute("volume",VOLUME_MASTER);
+	
+	xml.SaveFile("config/settings.xml", false);
+}
\ No newline at end of file
diff --git a/src/gameplay.cpp b/src/gameplay.cpp
index 7c238b4..d9ae6b5 100644
--- a/src/gameplay.cpp
+++ b/src/gameplay.cpp
@@ -11,8 +11,9 @@ extern World	*currentWorld;
 extern Player	*player;
 
 extern float shit;
-extern std::vector<menuItem>pauseMenu;
-extern std::vector<menuItem>optionsMenu;
+extern Menu* currentMenu;
+extern Menu pauseMenu;
+extern Menu optionsMenu;
 
 extern void mainLoop(void);
 
@@ -222,14 +223,19 @@ void initEverything(void){
 
 	currentWorld->bgmPlay(NULL);
 	atexit(destroyEverything);
+	std::cout << "Hey";
 
-	pauseMenu.push_back(ui::createButton({-256/2,0},{256,75},{0.0f,0.0f,0.0f}, (const char*)("Resume"), ui::quitMenu));
-	pauseMenu.push_back(ui::createButton({-256/2,-100},{256,75},{0.0f,0.0f,0.0f}, (const char*)("Options"), ui::optionsMenuF));
-	pauseMenu.push_back(ui::createButton({-256/2,-200},{256,75},{0.0f,0.0f,0.0f}, (const char*)("Save and Quit"), ui::quitGame));
-	pauseMenu.push_back(ui::createButton({-256/2,-300},{256,75},{0.0f,0.0f,0.0f}, (const char*)("Segfault"), segFault));
+	pauseMenu.items.push_back(ui::createParentButton({-256/2,0},{256,75},{0.0f,0.0f,0.0f}, (const char*)("Resume")));
+	pauseMenu.items.push_back(ui::createChildButton({-256/2,-100},{256,75},{0.0f,0.0f,0.0f}, (const char*)("Options")));
+	pauseMenu.items.push_back(ui::createButton({-256/2,-200},{256,75},{0.0f,0.0f,0.0f}, (const char*)("Save and Quit"), ui::quitGame));
+	pauseMenu.items.push_back(ui::createButton({-256/2,-300},{256,75},{0.0f,0.0f,0.0f}, (const char*)("Segfault"), segFault));
+	pauseMenu.child = &optionsMenu;
+	pauseMenu.parent = NULL;
 
 
-	optionsMenu.push_back(ui::createSlider({-512/2,100}, {512,50}, {0.0f, 0.0f, 0.0f}, 0, 100, (const char*)("Shit"), &shit));
+	optionsMenu.items.push_back(ui::createSlider({-512/2,100}, {512,50}, {0.0f, 0.0f, 0.0f}, 0, 100, (const char*)("Shit"), &VOLUME_MASTER));
+	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"), );
 }
 
diff --git a/src/ui.cpp b/src/ui.cpp
index 1520e9f..2118022 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -55,6 +55,10 @@ static unsigned char dialogOptCount = 0;
 static bool dialogPassive = false;
 static bool typeOutDone = true;
 
+extern Menu* currentMenu;
+extern Menu pauseMenu;
+
+
 Mix_Chunk *dialogClick;
 
 extern void mainLoop(void);
@@ -73,6 +77,23 @@ Mix_Chunk *battleStart;
 
 Mix_Chunk *sanic;
 
+void Menu::gotoParent(){
+	if(parent == NULL){
+		currentMenu = NULL;
+		updateConfig();
+	}else{
+		currentMenu = parent;
+	}
+}
+
+void Menu::gotoChild(){
+	if(child == NULL){
+		currentMenu = this;
+	}else{
+		currentMenu = child;
+	}
+}
+
 namespace ui {
 	
 	/*
@@ -86,10 +107,7 @@ namespace ui {
 	 *	Variety of keydown bools
 	*/
 	bool edown;
-	bool oMenu = false;
-	bool pMenu = false;
-	bool menu = false;
-	
+
 	/*
 	 *	Debugging flags.
 	*/
@@ -620,25 +638,14 @@ namespace ui {
 	}
 
 	void quitGame(){
-		if(pMenu)pMenu^=pMenu;
-		if(oMenu)oMenu^=oMenu;
-		if(menu)menu^=menu;
 		gameRunning = false;
+		updateConfig();
 	}
 
 	void quitMenu(){
-		if(pMenu)pMenu^=pMenu;
-		if(oMenu)oMenu^=oMenu;
-		if(menu)menu^=menu;
+		currentMenu = NULL;
 	}
 
-	void optionsMenuF(){
-		//pMenu = false;
-		oMenu = true;
-		drawMenu(optionsMenu);
-	}
-
-
 	menuItem createButton(vec2 l, dim2 d, Color c, const char* t, menuFunc f){
 		menuItem temp;
 		temp.member = 0;
@@ -654,6 +661,36 @@ namespace ui {
 		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;
@@ -682,15 +719,16 @@ namespace ui {
 	}
 
 	/*
-	 *	Don't even try to understand this Clyne...
+	 *	Draws the menu
 	*/
 
-	void drawMenu(std::vector<menuItem>mi){
+	void drawMenu(Menu *menu){
 		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:
@@ -703,7 +741,7 @@ namespace ui {
 				break;
 			case SDL_KEYUP:
 				if(SDL_KEY == SDLK_ESCAPE){
-					quitMenu();
+					menu->gotoParent();
 					return;
 				}
 				break;
@@ -711,19 +749,29 @@ namespace ui {
 			}
 		}
 
+		//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);
-		for(auto &m : mi){
-			if(m.member == 0){
+
+		//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);
+				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);
@@ -733,27 +781,57 @@ namespace ui {
 							glVertex2f(offset.x+m.button.loc.x, 					offset.y+m.button.loc.y);
 						glEnd();
 
-						if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)) m.button.func();
+						//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);
+
+				//width of the slider handle
 				float sliderW = m.slider.dim.x * .05;
+
+				//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);
+				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);
-					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 + (m.slider.dim.x*.05),
-							offset.y+m.slider.loc.y + m.slider.dim.y);
+				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 + (m.slider.dim.x*.05),
+						offset.y+m.slider.loc.y + m.slider.dim.y);
+
+				//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);
@@ -762,6 +840,7 @@ namespace ui {
 							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);
 
+							//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);
@@ -769,14 +848,21 @@ namespace ui {
 							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
 							*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);
+							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;
 					}
@@ -977,8 +1063,7 @@ DONE:
 			case SDL_KEYUP:
 				if(SDL_KEY == SDLK_ESCAPE){
 					//gameRunning = false;
-					pMenu = true;
-					menu = true;
+					currentMenu = &pauseMenu;
 					return;
 				}
 				switch(SDL_KEY){
-- 
cgit v1.2.3