diff --git a/AccessoryMenus.cpp b/AccessoryMenus.cpp new file mode 100644 index 0000000..7cea8af --- /dev/null +++ b/AccessoryMenus.cpp @@ -0,0 +1,167 @@ +#include "AccessoryMenus.h" +#include "SDL_include.h" +using namespace widgets; + +AccessoryMenus::AccessoryMenus(const int &x, const int &y, const int &width, const int &height, std::map *_library, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini) +{ + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + visible = false; + library = _library; + current_classification = "accessory"; + SDL_Color color; + color.a = 255; + color.b = 0; + color.g = 0; + color.r = 0; + std::string xmlpath = "assets//xml//accessory_menu_config.xml"; + std::string xmltype = "accessory"; + hxmlFile = new rapidxml::file<>(xmlpath.c_str()); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node(xmltype.c_str()); + } + else{ + pNode = hpRoot->first_node("config")->first_node(xmltype.c_str()); + } + sNode = pNode->first_node("slots"); + nNode = pNode->first_node("slot_name"); + dNode = pNode->first_node("slot_description"); + w = atoi(sNode->first_node("pos")->first_node("w")->value()); + h = atoi(sNode->first_node("pos")->first_node("h")->value()); + for (int i = 0; i < 3; ++i){ + slots.push_back(MeguButton(rect.x + atoi(sNode->first_node("pos")->first_node("x")->value()), + rect.y + i * atoi(sNode->first_node("offset")->first_node("y")->value()) + atoi(sNode->first_node("pos")->first_node("y")->value()), + atoi(sNode->first_node("pos")->first_node("w")->value()), + atoi(sNode->first_node("pos")->first_node("h")->value()), NULL, false)); + + slots_name.push_back(TtfWrapper(rect.x + atoi(nNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(nNode->first_node("offset")->first_node("y")->value()) + atoi(nNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(nNode->first_node("font_size")->value()) + , nNode->first_node("font")->value() + , 300 + , false) + ); + + + slots_description.push_back(TtfWrapper(rect.x + atoi(dNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(dNode->first_node("offset")->first_node("y")->value()) + atoi(dNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(dNode->first_node("font_size")->value()) + , nNode->first_node("font")->value() + , 300 + , false) + ); + + } + marker = loadTexture(pNode->first_node("marker")->first_node("texture")->value(), renderer); + marker_rect.w = atoi(pNode->first_node("marker")->first_node("size")->first_node("w")->value()); + marker_rect.h = atoi(pNode->first_node("marker")->first_node("size")->first_node("h")->value()); + marker_visible = false; + + for (rapidxml::xml_node<> *bNode = pNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")) + { + controls.push_back(MeguButton( + rect.x + atoi(bNode->first_node("pos")->first_node("x")->value()) + , rect.y + atoi(bNode->first_node("pos")->first_node("y")->value()) + , atoi(bNode->first_node("pos")->first_node("w")->value()) + , atoi(bNode->first_node("pos")->first_node("h")->value()) + , NULL + , true) + ); + } + int index = 0; + for (rapidxml::xml_node<> *bNode = pNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")){ + controls[index].changeObject(loadTexture(bNode->first_node("texture")->value(), renderer)); + ++index; + } + current_page = 0; + //Load image at specified path +} + +void AccessoryMenus::RenderButtons(SDL_Renderer *renderer) +{ + if (visible){ + if (marker_visible){ + SDL_RenderCopy(renderer, marker, NULL, &marker_rect); + + } + } +} + +void AccessoryMenus::updateSlots(SDL_Renderer *renderer){ + //clean up first + for (int i = 0; i < 3; ++i){ + slots[i].changeObject(NULL); + slots[i].setEnable(false); + slots_name[i].free(); + slots_name[i].setVisible(false); + slots_description[i].free(); + slots_description[i].setVisible(false); + } + for (int i = 0; i < 3; ++i){ + int curr_index = current_page * 3 + i; + if (curr_index > id_library[current_classification].size() - 1){ + return; + } + else{ + int id = id_library[current_classification].at(curr_index); + int w, h; + SDL_QueryTexture(*library->at(id).texture.begin(), NULL, NULL, &w, &h); + if (w > marker_rect.w){ + float ratio = (float)h / (float)w; + h = (int)(ratio * marker_rect.h); + w = marker_rect.w; + } + if (h > marker_rect.h){ + float ratio = (float)w / (float)h; + w = (int)(ratio * marker_rect.h); + h = marker_rect.h; + } + slots[i].changeDisplayObject(*library->at(id).texture.begin(), w, h, id); + slots[i].setEnable(true); + slots_name[i].setText(library->at(id).en_name); + slots_name[i].loadFromRenderedText(renderer); + slots_name[i].setVisible(true); + slots_description[i].setText(library->at(id).en_detail); + slots_description[i].loadFromRenderedText(renderer); + slots_description[i].setVisible(true); + } + } +} +AccessoryMenus::~AccessoryMenus() +{ +} +SDL_Texture* AccessoryMenus::loadTexture(std::string path, SDL_Renderer *renderer) +{ + //The final texture + SDL_Texture* newTexture = NULL; + + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + + return newTexture; +} + diff --git a/AccessoryMenus.h b/AccessoryMenus.h new file mode 100644 index 0000000..89c42de --- /dev/null +++ b/AccessoryMenus.h @@ -0,0 +1,35 @@ +#pragma once +#include "MeguMenus.h" +#include "MeguButton.h" +#include "SDL_include.h" +#include "SDL_include.h" +#include"Items_library.h" +#include +namespace widgets{ + class AccessoryMenus : + public MeguMenus + { + typedef int ID; + public: + AccessoryMenus(const int &x, const int &y, const int &width, const int &height, std::map *_library, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini); + void loadSelectorTexture(const std::string &filename); + void RenderButtons(SDL_Renderer *renderer); + void updateSlots(SDL_Renderer *renderer); + ~AccessoryMenus(); + std::string isInDisplay(int x, int y); + MeguButton *goright; + MeguButton *goleft; + SDL_Texture *marker; + SDL_Rect marker_rect; + bool marker_visible; + MeguButton *back_button; + MeguButton *select_button; + protected: + std::map *library; + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + SDL_Texture *buttons_overlay; + SDL_Rect overlay_pos; + + + }; +} diff --git a/CareMenus.cpp b/CareMenus.cpp new file mode 100644 index 0000000..2f3de70 --- /dev/null +++ b/CareMenus.cpp @@ -0,0 +1,91 @@ +#include "CareMenus.h" +#include "SDL_include.h" +using namespace widgets; + +CareMenus::CareMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini) +{ + + selected_id = 0; + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + SDL_Color color; + color.a = 255; + color.b = 0; + color.g = 0; + color.r = 0; + visible = false; + + std::string xmlpath = "assets//xml//care_menu_config.xml"; + std::string xmltype = "care"; + hxmlFile = new rapidxml::file<>(xmlpath.c_str()); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node(xmltype.c_str()); + } + else{ + pNode = hpRoot->first_node("config")->first_node(xmltype.c_str()); + } + sNode = pNode->first_node("button_displacement"); + for (int i = 0; i < 3; ++i){ + for (int j = 0; j < 3; ++j){ + slots.push_back(MeguButton(rect.x + atoi(sNode->first_node("pos")->first_node("x")->value()) + i*atoi(sNode->first_node("offset")->first_node("x")->value()), + rect.y + atoi(sNode->first_node("pos")->first_node("y")->value()) + j*atoi(sNode->first_node("offset")->first_node("y")->value()), + atoi(sNode->first_node("pos")->first_node("w")->value()), + atoi(sNode->first_node("pos")->first_node("h")->value()), NULL, false)); + } + } + + controls.push_back(MeguButton(rect.x + atoi(pNode->first_node("back_button")->first_node("pos")->first_node("x")->value()) + , rect.y + atoi(pNode->first_node("back_button")->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("back_button")->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("back_button")->first_node("pos")->first_node("h")->value()), NULL, false)); + + for (widgets::button_container::iterator it = slots.begin(); it != slots.end(); ++it){ + it->setEnable(false); + it->setVisible(false); + } + for (std::vector::iterator it = slots_name.begin(); it != slots_name.end(); ++it) + it->setVisible(false); + + controls[0].setEnable(false); + controls[0].setVisible(false); +} + +void CareMenus::RenderButtons(SDL_Renderer *renderer) +{ +} + +CareMenus::~CareMenus() +{ +} + +SDL_Texture* CareMenus::loadTexture(std::string path, SDL_Renderer *renderer) +{ + //The final texture + SDL_Texture* newTexture = NULL; + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + + return newTexture; +} \ No newline at end of file diff --git a/CareMenus.h b/CareMenus.h new file mode 100644 index 0000000..4f6bf5d --- /dev/null +++ b/CareMenus.h @@ -0,0 +1,21 @@ +#pragma once +#include "MeguMenus.h" +#include "MeguButton.h" +#include "SDL_include.h" +#include"Items_library.h" +#include +namespace widgets{ + class CareMenus : + public MeguMenus + { + typedef int ID; + public: + CareMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini); + void loadSelectorTexture(const std::string &filename); + void RenderButtons(SDL_Renderer *renderer); + ~CareMenus(); + protected: + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + + }; +} diff --git a/EditMenus.cpp b/EditMenus.cpp new file mode 100644 index 0000000..ce5e3e1 --- /dev/null +++ b/EditMenus.cpp @@ -0,0 +1,88 @@ +#include "EditMenus.h" + +#include "SDL_include.h" +using namespace widgets; + +EditMenus::EditMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini) +{ + selected_id = 0; + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + SDL_Color color; + color.a = 255; + color.b = 0; + color.g = 0; + color.r = 0; + visible = false; + + std::string xmlpath = "assets//xml//edit_menu_config.xml"; + std::string xmltype = "edit"; + hxmlFile = new rapidxml::file<>(xmlpath.c_str()); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node(xmltype.c_str()); + } + else{ + pNode = hpRoot->first_node("config")->first_node(xmltype.c_str()); + } + sNode = pNode->first_node("button_displacement"); + for (int i = 0; i < 3; ++i){ + for (int j = 0; j < 3; ++j){ + slots.push_back(MeguButton(rect.x + atoi(sNode->first_node("pos")->first_node("x")->value()) + i*atoi(sNode->first_node("offset")->first_node("x")->value()), + rect.y + atoi(sNode->first_node("pos")->first_node("y")->value()) + j*atoi(sNode->first_node("offset")->first_node("y")->value()), + atoi(sNode->first_node("pos")->first_node("w")->value()), + atoi(sNode->first_node("pos")->first_node("h")->value()), NULL, false)); + } + } + + controls.push_back(MeguButton(rect.x + atoi(pNode->first_node("back_button")->first_node("pos")->first_node("x")->value()) + , rect.y + atoi(pNode->first_node("back_button")->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("back_button")->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("back_button")->first_node("pos")->first_node("h")->value()), NULL, false)); + + for (widgets::button_container::iterator it = slots.begin(); it != slots.end(); ++it){ + it->setEnable(false); + it->setVisible(false); + } + for (std::vector::iterator it = slots_name.begin(); it != slots_name.end(); ++it) + it->setVisible(false); + + controls[0].setEnable(false); + controls[0].setVisible(false); +} + +EditMenus::~EditMenus() +{ +} + +SDL_Texture* EditMenus::loadTexture(std::string path, SDL_Renderer *renderer) +{ + //The final texture + SDL_Texture* newTexture = NULL; + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + + return newTexture; +} + diff --git a/EditMenus.h b/EditMenus.h new file mode 100644 index 0000000..6f7573d --- /dev/null +++ b/EditMenus.h @@ -0,0 +1,25 @@ +#pragma once +#include "MeguMenus.h" +#include "MeguButton.h" +#include "SDL_include.h" +#include"Items_library.h" +#include + +namespace widgets{ + class EditMenus : + public MeguMenus + { + typedef int ID; + public: + EditMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini); + void loadSelectorTexture(const std::string &filename); + void RenderButtons(SDL_Renderer *renderer); + void initBackButton(SDL_Texture *b_texture); + ~EditMenus(); + MeguButton *back_button; + protected: + + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + + }; +} diff --git a/FoodMenus.cpp b/FoodMenus.cpp new file mode 100644 index 0000000..5c453c2 --- /dev/null +++ b/FoodMenus.cpp @@ -0,0 +1,215 @@ +#include "FoodMenus.h" +#include "TtfWrapper.h" +#include "SDL_include.h" +using namespace widgets; + +FoodMenus::FoodMenus(const int &x, const int &y, const int &width, const int &height, std::map *_library, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini) +{ + selected_id = 0; + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + visible = false; + library = _library; + SDL_Color color; + color.a = 255; + color.b = 0; + color.g = 0; + color.r = 0; + std::string xmlpath = "assets//xml//food_menu_config.xml"; + std::string xmltype = "food"; + hxmlFile = new rapidxml::file<>(xmlpath.c_str()); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node(xmltype.c_str()); + } + else{ + pNode = hpRoot->first_node("config")->first_node(xmltype.c_str()); + } + sNode = pNode->first_node("slots"); + nNode = pNode->first_node("slot_name"); + dNode = pNode->first_node("slot_description"); + for (int i = 0; i < 3; ++i){ + slots.push_back(MeguButton(rect.x + atoi(sNode->first_node("pos")->first_node("x")->value()), + rect.y + i * atoi(sNode->first_node("offset")->first_node("y")->value()) + atoi(sNode->first_node("pos")->first_node("y")->value()), + atoi(sNode->first_node("pos")->first_node("w")->value()), + atoi(sNode->first_node("pos")->first_node("h")->value()), NULL, false)); + + slots_name.push_back(TtfWrapper(rect.x + atoi(nNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(nNode->first_node("offset")->first_node("y")->value()) + atoi(nNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(nNode->first_node("font_size")->value()) + , dNode->first_node("font")->value() + , 300 + , false) + ); + + + slots_description.push_back(TtfWrapper(rect.x + atoi(dNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(dNode->first_node("offset")->first_node("y")->value()) + atoi(dNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(dNode->first_node("font_size")->value()) + , dNode->first_node("font")->value() + , 150 + , false) + ); + + } + marker = loadTexture(pNode->first_node("marker")->first_node("texture")->value(), renderer); + marker_rect.w = atoi(pNode->first_node("marker")->first_node("size")->first_node("w")->value()); + marker_rect.h = atoi(pNode->first_node("marker")->first_node("size")->first_node("h")->value()); + marker_visible = false; + + + for (rapidxml::xml_node<> *bNode = pNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")) + { + controls.push_back(MeguButton( + rect.x + atoi(bNode->first_node("pos")->first_node("x")->value()) + , rect.y + atoi(bNode->first_node("pos")->first_node("y")->value()) + , atoi(bNode->first_node("pos")->first_node("w")->value()) + , atoi(bNode->first_node("pos")->first_node("h")->value()) + , NULL + , true) + ); + } + int index = 0; + for (rapidxml::xml_node<> *bNode = pNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")){ + controls[index].changeObject(loadTexture(bNode->first_node("texture")->value(), renderer)); + ++index; + } + current_classification = "American"; + current_page = 0; + + + //Load image at specified path + int row,row_c, col,col_c; + rapidxml::xml_node<> *displayNode = pNode->first_node("display_selector"); + row = atoi(displayNode->first_node("displacement")->first_node("rows")->value()); + col = atoi(displayNode->first_node("displacement")->first_node("collumns")->value()); + row_c = 0; + col_c = 0; + + int bx,by, bw,bh, off_x, off_y; + bx = atoi(displayNode->first_node("pos")->first_node("x")->value()); + by = atoi(displayNode->first_node("pos")->first_node("y")->value()); + bw = atoi(displayNode->first_node("pos")->first_node("w")->value()); + bh = atoi(displayNode->first_node("pos")->first_node("h")->value()); + off_x = atoi(displayNode->first_node("offset")->first_node("x")->value()); + off_y = atoi(displayNode->first_node("offset")->first_node("y")->value()); + for (rapidxml::xml_node<> *bNode = displayNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")) + { + display_selector[bNode->first_node("type")->value()] = new MeguButton(rect.x + bx + col_c * off_x, rect.y + by + row_c * off_y, bw, bh, NULL, true); + ++col_c; + if (col_c == col){ + col_c = 0; + ++row_c; + } + } + for (widgets::button_container::iterator it = slots.begin(); it != slots.end(); ++it){ + it->setEnable(false); + it->setVisible(false); + } + for (std::vector::iterator it = slots_name.begin(); it != slots_name.end(); ++it) + it->setVisible(false); +} + +void FoodMenus::RenderButtons(SDL_Renderer *renderer) +{ + if (visible){ + for (std::map::iterator it = display_selector.begin(); it != display_selector.end(); ++it){ + it->second->Render(renderer); + + } + if (marker_visible){ + SDL_RenderCopy(renderer, marker, NULL, &marker_rect); + + } + } +} + + +std::string FoodMenus::isInDisplay(int mouseX, int mouseY){ + for (std::map::iterator it = display_selector.begin(); it != display_selector.end(); ++it){ + if (it->second->IsIn(mouseX, mouseY)){ + return it->first; + } + } + return("NONE"); +} +void FoodMenus::updateSlots(SDL_Renderer *renderer){ + //clean up first + for (int i = 0; i < 3; ++i){ + slots[i].changeObject(NULL); + slots[i].setEnable(false); + slots_name[i].free(); + slots_name[i].setVisible(false); + slots_description[i].free(); + slots_description[i].setVisible(false); + + } + for (int i = 0; i < 3; ++i){ + int curr_index = current_page * 3 + i; + if (curr_index > id_library[current_classification].size() - 1){ + return; + } + else{ + if (id_library.find(current_classification) != id_library.end()){ + int id = id_library[current_classification].at(curr_index); + int w, h; + SDL_QueryTexture(*library->at(id).texture.begin(), NULL, NULL, &w, &h); + if (w > marker_rect.w){ + float ratio = (float)h / (float)w; + h = (int)(ratio * marker_rect.w); + w = marker_rect.w; + } + if (h > marker_rect.h){ + float ratio = (float)w / (float)h; + w = (int)(ratio * marker_rect.h); + h = marker_rect.h; + } + slots[i].changeDisplayObject((*library->at(id).texture.begin()), w, h, id); + slots[i].setEnable(true); + slots_name[i].setText(library->at(id).en_name); + slots_name[i].loadFromRenderedText(renderer); + slots_name[i].setVisible(true); + slots_description[i].setText(library->at(id).en_detail); + slots_description[i].loadFromRenderedText(renderer); + slots_description[i].setVisible(true); + } + } + } +} + +FoodMenus::~FoodMenus() +{ +} +SDL_Texture* FoodMenus::loadTexture(std::string path, SDL_Renderer *renderer) +{ + //The final texture + SDL_Texture* newTexture = NULL; + + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + + return newTexture; +} diff --git a/FoodMenus.h b/FoodMenus.h new file mode 100644 index 0000000..6562e1c --- /dev/null +++ b/FoodMenus.h @@ -0,0 +1,30 @@ +#pragma once +#include "MeguMenus.h" +#include "MeguButton.h" +#include"Items_library.h" +#include "SDL_include.h" + +#include +namespace widgets{ + class FoodMenus : + public MeguMenus + { + typedef int ID; + public: + FoodMenus(const int &x, const int &y, const int &width, const int &height, std::map *_library, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini); + void loadSelectorTexture(const std::string &filename); + void RenderButtons(SDL_Renderer *renderer); + ~FoodMenus(); + void updateSlots(SDL_Renderer *renderer); + std::map display_selector; + std::string isInDisplay(int x, int y); + SDL_Texture *marker; + SDL_Rect marker_rect; + bool marker_visible; + protected: + std::map *library; + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + + + }; +} diff --git a/FriendsMenus.cpp b/FriendsMenus.cpp new file mode 100644 index 0000000..7538f93 --- /dev/null +++ b/FriendsMenus.cpp @@ -0,0 +1,202 @@ +#include "FriendsMenus.h" +#include "SDL_include.h" +using namespace widgets; + +FriendsMenus::FriendsMenus(const int &x, const int &y, const int &width, const int &height, std::map *_library, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini) +{ + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + visible = false; + library = _library; + current_classification = "megus"; + SDL_Color color; + color.a = 255; + color.b = 0; + color.g = 0; + color.r = 0; + current_page = 0; + std::string xmlpath = "assets//xml//friends_menu_config.xml"; + std::string xmltype = "friends"; + hxmlFile = new rapidxml::file<>(xmlpath.c_str()); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node(xmltype.c_str()); + } + else{ + pNode = hpRoot->first_node("config")->first_node(xmltype.c_str()); + } + sNode = pNode->first_node("slots"); + nNode = pNode->first_node("slot_name"); + dNode = pNode->first_node("slot_description"); + for (int i = 0; i < 3; ++i){ + slots.push_back(MeguButton(rect.x + atoi(sNode->first_node("pos")->first_node("x")->value()), + rect.y + i * atoi(sNode->first_node("offset")->first_node("y")->value()) + atoi(sNode->first_node("pos")->first_node("y")->value()), + atoi(sNode->first_node("pos")->first_node("w")->value()), + atoi(sNode->first_node("pos")->first_node("h")->value()), NULL, false)); + + slots_name.push_back(TtfWrapper(rect.x + atoi(nNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(nNode->first_node("offset")->first_node("y")->value()) + atoi(nNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(nNode->first_node("font_size")->value()) + , nNode->first_node("font")->value() + , 150 + , false) + ); + + + slots_description.push_back(TtfWrapper(rect.x + atoi(dNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(dNode->first_node("offset")->first_node("y")->value()) + atoi(dNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(dNode->first_node("font_size")->value()) + , nNode->first_node("font")->value() + , 150 + , false) + ); + + } + marker = loadTexture(pNode->first_node("marker")->first_node("texture")->value(), renderer); + marker_rect.w = atoi(pNode->first_node("marker")->first_node("size")->first_node("w")->value()); + marker_rect.h = atoi(pNode->first_node("marker")->first_node("size")->first_node("h")->value()); + marker_visible = false; + + for (rapidxml::xml_node<> *bNode = pNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")) + { + controls.push_back(MeguButton( + rect.x + atoi(bNode->first_node("pos")->first_node("x")->value()) + , rect.y + atoi(bNode->first_node("pos")->first_node("y")->value()) + , atoi(bNode->first_node("pos")->first_node("w")->value()) + , atoi(bNode->first_node("pos")->first_node("h")->value()) + , NULL + , true) + ); + } + int index = 0; + //Load image at specified path +} + +void FriendsMenus::RenderButtons(SDL_Renderer *renderer) +{ + if (visible){ + if (marker_visible){ + SDL_RenderCopy(renderer, marker, NULL, &marker_rect); + + } + } +} + +void FriendsMenus::parseFiles(const std::vector &friend_file_list){ + friend_list.clear(); + for (std::vector::const_iterator it = friend_file_list.begin(); it != friend_file_list.end(); ++it){ + std::ifstream file; + std::string filename = "gamedata/friends/" + *it; + file.open(filename); + file_data f; + std::string owner_name; + std::string pet_name; + if (file.is_open()){ + f.path = filename; + file >> f.owner_name; + file >> f.megu_name; + file >> f.ID; + friend_list.push_back(f); + file.close(); + } + } +} + +void FriendsMenus::setViewPage(const int &page, SDL_Renderer *renderer){ + if (page <= (friend_list.size() - 1) / 3 && page >= 0){ + current_page = page; + updateSlots(renderer); + } +} +void FriendsMenus::updateSlots(SDL_Renderer *renderer){ + //clean up first + for (int i = 0; i < 3; ++i){ + slots[i].changeObject(NULL); + slots[i].setEnable(false); + slots_name[i].free(); + slots_name[i].setVisible(false); + slots_description[i].free(); + slots_description[i].setVisible(false); + } + + + //replacing + if (friend_list.size() > 0){ + for (int i = 0; i < 3; ++i){ + int curr_index = current_page * 3 + i; + if (curr_index > friend_list.size() - 1){ + return; + } + else{ + int id = friend_list.at(curr_index).ID; + SDL_QueryTexture(library->at(id).front_texture, NULL, NULL, &w, &h); + if (w > marker_rect.w){ + float ratio = (float)h / (float)w; + h = (int)(ratio * marker_rect.h); + w = marker_rect.w; + } + if (h > marker_rect.h){ + float ratio = (float)w / (float)h; + w = (int)(ratio * marker_rect.h); + h = marker_rect.h; + } + std::cerr << library->at(id).en_name << std::endl; + slots[i].changeDisplayObject(library->at(id).front_texture, w, h, id); + slots[i].setEnable(true); + std::cerr << i << std::endl; + slots_name[i].setText(friend_list.at(curr_index).owner_name); + slots_name[i].loadFromRenderedText(renderer); + slots_name[i].setVisible(true); + slots_description[i].setText(friend_list.at(curr_index).megu_name); + slots_description[i].loadFromRenderedText(renderer); + slots_description[i].setVisible(true); + } + + } + } +} +void FriendsMenus::setCurrentString(const int &slot){ + current_path = friend_list.at(slot + current_page * 3).path; +} + +std::string FriendsMenus::getCurrentPath(){ + return current_path; +} + +FriendsMenus::~FriendsMenus() +{ +} +SDL_Texture* FriendsMenus::loadTexture(std::string path, SDL_Renderer *renderer) +{ + //The final texture + SDL_Texture* newTexture = NULL; + + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + + return newTexture; +} + diff --git a/FriendsMenus.h b/FriendsMenus.h new file mode 100644 index 0000000..f329de1 --- /dev/null +++ b/FriendsMenus.h @@ -0,0 +1,48 @@ +#pragma once +#include "MeguMenus.h" +#include "MeguButton.h" +#include "SDL_include.h" +#include"Items_library.h" +#include +namespace widgets{ + class FriendsMenus : + public MeguMenus + { + typedef int ID; + public: + FriendsMenus(const int &x, const int &y, const int &width, const int &height, std::map *_library, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini); + void loadSelectorTexture(const std::string &filename); + void RenderButtons(SDL_Renderer *renderer); + void updateSlots(SDL_Renderer *renderer); + ~FriendsMenus(); + std::string isInDisplay(int x, int y); + void parseFiles(const std::vector &friend_file_list); + MeguButton *goright; + MeguButton *goleft; + SDL_Texture *marker; + SDL_Rect marker_rect; + bool marker_visible; + MeguButton *back_button; + MeguButton *select_button; + void setCurrentString(const int &slot); + void setViewPage(const int &page, SDL_Renderer *renderer); + std::string getCurrentPath(); + protected: + std::map *library; + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + SDL_Texture *buttons_overlay; + SDL_Rect overlay_pos; + std::string current_owner; + std::string current_pet_name; + std::string current_path; + struct file_data{ + int ID; + std::string path; + std::string owner_name; + std::string megu_name; + }; + std::vector friend_list; + + + }; +} diff --git a/FurnitureMenus.cpp b/FurnitureMenus.cpp new file mode 100644 index 0000000..44564c2 --- /dev/null +++ b/FurnitureMenus.cpp @@ -0,0 +1,167 @@ +#include "FurnitureMenus.h" +#include "SDL_include.h" +using namespace widgets; + +FurnitureMenus::FurnitureMenus(const int &x, const int &y, const int &width, const int &height, std::map *_library, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini) +{ + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + visible = false; + library = _library; + current_classification = "furniture"; + SDL_Color color; + color.a = 255; + color.b = 0; + color.g = 0; + color.r = 0; + std::string xmlpath = "assets//xml//furniture_menu_config.xml"; + std::string xmltype = "furniture"; + hxmlFile = new rapidxml::file<>(xmlpath.c_str()); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node(xmltype.c_str()); + } + else{ + pNode = hpRoot->first_node("config")->first_node(xmltype.c_str()); + } + sNode = pNode->first_node("slots"); + nNode = pNode->first_node("slot_name"); + dNode = pNode->first_node("slot_description"); + w = atoi(sNode->first_node("pos")->first_node("w")->value()); + h = atoi(sNode->first_node("pos")->first_node("h")->value()); + for (int i = 0; i < 3; ++i){ + slots.push_back(MeguButton(rect.x + atoi(sNode->first_node("pos")->first_node("x")->value()), + rect.y + i * atoi(sNode->first_node("offset")->first_node("y")->value()) + atoi(sNode->first_node("pos")->first_node("y")->value()), + atoi(sNode->first_node("pos")->first_node("w")->value()), + atoi(sNode->first_node("pos")->first_node("h")->value()), NULL, false)); + + slots_name.push_back(TtfWrapper(rect.x + atoi(nNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(nNode->first_node("offset")->first_node("y")->value()) + atoi(nNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(nNode->first_node("font_size")->value()) + , nNode->first_node("font")->value() + , 300 + , false) + ); + + + slots_description.push_back(TtfWrapper(rect.x + atoi(dNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(dNode->first_node("offset")->first_node("y")->value()) + atoi(dNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(dNode->first_node("font_size")->value()) + , nNode->first_node("font")->value() + , 300 + , false) + ); + + } + marker = loadTexture(pNode->first_node("marker")->first_node("texture")->value(), renderer); + marker_rect.w = atoi(pNode->first_node("marker")->first_node("size")->first_node("w")->value()); + marker_rect.h = atoi(pNode->first_node("marker")->first_node("size")->first_node("h")->value()); + marker_visible = false; + + for (rapidxml::xml_node<> *bNode = pNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")) + { + controls.push_back(MeguButton( + rect.x + atoi(bNode->first_node("pos")->first_node("x")->value()) + , rect.y + atoi(bNode->first_node("pos")->first_node("y")->value()) + , atoi(bNode->first_node("pos")->first_node("w")->value()) + , atoi(bNode->first_node("pos")->first_node("h")->value()) + , NULL + , true) + ); + } + int index = 0; + for (rapidxml::xml_node<> *bNode = pNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")){ + controls[index].changeObject(loadTexture(bNode->first_node("texture")->value(), renderer)); + ++index; + } + current_page = 0; + //Load image at specified path +} + +void FurnitureMenus::RenderButtons(SDL_Renderer *renderer) +{ + if (visible){ + if (marker_visible){ + SDL_RenderCopy(renderer, marker, NULL, &marker_rect); + + } + } +} + +void FurnitureMenus::updateSlots(SDL_Renderer *renderer){ + //clean up first + for (int i = 0; i < 3; ++i){ + slots[i].changeObject(NULL); + slots[i].setEnable(false); + slots_name[i].free(); + slots_name[i].setVisible(false); + slots_description[i].free(); + slots_description[i].setVisible(false); + } + for (int i = 0; i < 3; ++i){ + int curr_index = current_page * 3 + i; + if (curr_index > id_library[current_classification].size() - 1){ + return; + } + else{ + int id = id_library[current_classification].at(curr_index); + int w, h; + SDL_QueryTexture(*library->at(id).texture.begin(), NULL, NULL, &w, &h); + if (w > marker_rect.w){ + float ratio = (float)h / (float)w; + h = (int)(ratio * marker_rect.h); + w = marker_rect.w; + } + if (h > marker_rect.h){ + float ratio = (float)w / (float)h; + w = (int)(ratio * marker_rect.h); + h = marker_rect.h; + } + slots[i].changeDisplayObject(*library->at(id).texture.begin(), w, h, id); + slots[i].setEnable(true); + slots_name[i].setText(library->at(id).en_name); + slots_name[i].loadFromRenderedText(renderer); + slots_name[i].setVisible(true); + slots_description[i].setText(library->at(id).en_detail); + slots_description[i].loadFromRenderedText(renderer); + slots_description[i].setVisible(true); + } + } +} +FurnitureMenus::~FurnitureMenus() +{ +} +SDL_Texture* FurnitureMenus::loadTexture(std::string path, SDL_Renderer *renderer) +{ + //The final texture + SDL_Texture* newTexture = NULL; + + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + + return newTexture; +} + diff --git a/FurnitureMenus.h b/FurnitureMenus.h new file mode 100644 index 0000000..7c80a65 --- /dev/null +++ b/FurnitureMenus.h @@ -0,0 +1,35 @@ +#pragma once +#include "MeguMenus.h" +#include "MeguButton.h" +#include "SDL_include.h" +#include "SDL_include.h" +#include"Items_library.h" +#include +namespace widgets{ + class FurnitureMenus : + public MeguMenus + { + typedef int ID; + public: + FurnitureMenus(const int &x, const int &y, const int &width, const int &height, std::map *_library, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini); + void loadSelectorTexture(const std::string &filename); + void RenderButtons(SDL_Renderer *renderer); + void updateSlots(SDL_Renderer *renderer); + ~FurnitureMenus(); + std::string isInDisplay(int x, int y); + MeguButton *goright; + MeguButton *goleft; + SDL_Texture *marker; + SDL_Rect marker_rect; + bool marker_visible; + MeguButton *back_button; + MeguButton *select_button; + protected: + std::map *library; + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + SDL_Texture *buttons_overlay; + SDL_Rect overlay_pos; + + + }; +} diff --git a/HouseMenus.cpp b/HouseMenus.cpp new file mode 100644 index 0000000..b31453c --- /dev/null +++ b/HouseMenus.cpp @@ -0,0 +1,160 @@ +#include "HouseMenus.h" +#include "SDL_include.h" +using namespace widgets; + +HouseMenus::HouseMenus(const int &x, const int &y, const int &width, const int &height, std::map *_library, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini) +{ + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + visible = false; + library = _library; + SDL_Color color; + color.a = 255; + color.b = 0; + color.g = 0; + color.r = 0; + current_classification = "house"; + std::string xmlpath = "assets//xml//house_menu_config.xml"; + std::string xmltype = "house"; + hxmlFile = new rapidxml::file<>(xmlpath.c_str()); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node(xmltype.c_str()); + } + else{ + pNode = hpRoot->first_node("config")->first_node(xmltype.c_str()); + } + sNode = pNode->first_node("slots"); + nNode = pNode->first_node("slot_name"); + dNode = pNode->first_node("slot_description"); + for (int i = 0; i < 3; ++i){ + slots.push_back(MeguButton(rect.x + atoi(sNode->first_node("pos")->first_node("x")->value()), + rect.y + i * atoi(sNode->first_node("offset")->first_node("y")->value()) + atoi(sNode->first_node("pos")->first_node("y")->value()), + atoi(sNode->first_node("pos")->first_node("w")->value()), + atoi(sNode->first_node("pos")->first_node("h")->value()), NULL, false)); + + slots_name.push_back(TtfWrapper(rect.x + atoi(nNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(nNode->first_node("offset")->first_node("y")->value()) + atoi(nNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(nNode->first_node("font_size")->value()) + , nNode->first_node("font")->value() + , 300 + , false) + ); + + + slots_description.push_back(TtfWrapper(rect.x + atoi(dNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(dNode->first_node("offset")->first_node("y")->value()) + atoi(dNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(dNode->first_node("font_size")->value()) + , nNode->first_node("font")->value() + , 300 + , false) + ); + + } + marker = loadTexture(pNode->first_node("marker")->first_node("texture")->value(), renderer); + marker_rect.w = atoi(pNode->first_node("marker")->first_node("size")->first_node("w")->value()); + marker_rect.h = atoi(pNode->first_node("marker")->first_node("size")->first_node("h")->value()); + marker_visible = false; + + for (rapidxml::xml_node<> *bNode = pNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")) + { + controls.push_back(MeguButton( + rect.x + atoi(bNode->first_node("pos")->first_node("x")->value()) + , rect.y + atoi(bNode->first_node("pos")->first_node("y")->value()) + , atoi(bNode->first_node("pos")->first_node("w")->value()) + , atoi(bNode->first_node("pos")->first_node("h")->value()) + , NULL + , true) + ); + } + int index = 0; + current_page = 0; + //Load image at specified path +} + +void HouseMenus::RenderButtons(SDL_Renderer *renderer) +{ + if (visible){ + if (marker_visible){ + SDL_RenderCopy(renderer, marker, NULL, &marker_rect); + } + } +} + + +HouseMenus::~HouseMenus() +{ +} +void HouseMenus::updateSlots(SDL_Renderer *renderer){ + //clean up first + for (int i = 0; i < 3; ++i){ + slots[i].changeObject(NULL); + slots[i].setEnable(false); + slots_name[i].free(); + slots_name[i].setVisible(false); + slots_description[i].free(); + slots_description[i].setVisible(false); + } + for (int i = 0; i < 3; ++i){ + int curr_index = current_page * 3 + i; + if (curr_index > id_library[current_classification].size() - 1){ + return; + } + else{ + int id = id_library[current_classification].at(curr_index); + int w, h; + SDL_QueryTexture(library->at(id).front_texture, NULL, NULL, &w, &h); + if (w > marker_rect.w){ + float ratio = (float)h / (float)w; + h = (int)(ratio * marker_rect.w); + w = marker_rect.w; + } + if (h > marker_rect.h){ + float ratio = (float)w / (float)h; + w = (int)(ratio * marker_rect.h); + h = marker_rect.h; + } + slots[i].changeDisplayObject(library->at(id).front_texture, w, h, id); + slots[i].setEnable(true); + slots_name[i].setText(library->at(id).en_name); + slots_name[i].loadFromRenderedText(renderer); + slots_name[i].setVisible(true); + slots_description[i].setText(library->at(id).en_detail); + slots_description[i].loadFromRenderedText(renderer); + slots_description[i].setVisible(true); + + } + } +} +SDL_Texture* HouseMenus::loadTexture(std::string path, SDL_Renderer *renderer) +{ + //The final texture + SDL_Texture* newTexture = NULL; + + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + return newTexture; +} diff --git a/HouseMenus.h b/HouseMenus.h new file mode 100644 index 0000000..a079a6b --- /dev/null +++ b/HouseMenus.h @@ -0,0 +1,30 @@ +#pragma once +#include "MeguMenus.h" +#include "MeguButton.h" +#include "SDL_include.h" +#include"Items_library.h" +#include +namespace widgets{ + class HouseMenus : + public MeguMenus + { + typedef int ID; + public: + HouseMenus(const int &x, const int &y, const int &width, const int &height, std::map *_library, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini); + void loadSelectorTexture(const std::string &filename); + void RenderButtons(SDL_Renderer *renderer); + void updateSlots(SDL_Renderer *renderer); + ~HouseMenus(); + std::string isInDisplay(int x, int y); + SDL_Texture *marker; + SDL_Rect marker_rect; + bool marker_visible; + protected: + std::map *library; + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + SDL_Texture *buttons_overlay; + SDL_Rect overlay_pos; + + + }; +} diff --git a/Items_library.h b/Items_library.h new file mode 100644 index 0000000..5aafdc9 --- /dev/null +++ b/Items_library.h @@ -0,0 +1,229 @@ +#pragma once + +#include +#include +#include +#include "SDL_include.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef int ID; +typedef std::string ITEM_TYPE; +class item_library{ + + + + inline SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer) + { + //The final texture + SDL_Texture* newTexture = NULL; + + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + + return newTexture; + } +public: + struct megu{ + ID id; + std::string en_name; + std::string en_detail; + std::string en_family; + std::wstring jp_name; + std::wstring jp_detail; + std::wstring jp_family; + int size; + int hungry; + int change; + float min_weight; + float max_weight; + SDL_Texture *front_texture;//front small image + }; + struct item{ + ID id; + + std::string en_name; + std::wstring jp_name; + std::string en_detail; + std::wstring jp_detail; + + ITEM_TYPE type; + int nutrition; + int calories; + int freshness; + int lvl; + int exp; + int price; + int animation_time; + bool isanimated; + std::vector animation_order; + std::vectortexture; + }; + + struct house{ + ID id; + std::string en_name; + std::wstring jp_name; + std::string en_detail; + std::wstring jp_detail; + + int size; + int lvl; + int comfort; + int price; + SDL_Texture * front_texture; + + }; + + std::map food_lib; + std::map furniture_lib; + std::map accessory_lib; + std::map megu_lib; + std::map house_lib; + + + void populate(SDL_Renderer *renderer){ + std::fstream f("assets/xml/house.xml"); + if(f.is_open()){ + std::cerr << "opened!" << std::endl; + } + else{ + std::cerr << "it is not :(" << std::endl; + } + f.close(); + rapidxml::file<> hxmlFile("assets//xml//house.xml"); // Default template is char + rapidxml::xml_document<> hdoc; + hdoc.parse<0>(hxmlFile.data()); + rapidxml::xml_node<> *hpRoot = hdoc.first_node(); + for (rapidxml::xml_node<> *pNode = hpRoot->first_node("house"); pNode; pNode = pNode->next_sibling("house")) + { + house h_obj; + h_obj.id = atoi(pNode->first_node("id")->value()); + h_obj.en_name = pNode->last_node("strings")->first_node("name")->first_node()->value(); + h_obj.en_detail = pNode->last_node("strings")->first_node("detail")->first_node()->value(); + h_obj.size = atoi(pNode->first_node("size")->value()); + h_obj.lvl = atoi(pNode->first_node("level")->value()); + h_obj.comfort = atoi(pNode->first_node("comfort")->value()); + h_obj.price = atoi(pNode->first_node("price")->value()); + h_obj.front_texture = loadTexture("assets/Houses/ID" + std::to_string(h_obj.id) + ".png", renderer); + house_lib[h_obj.id] = h_obj; + } + rapidxml::file<> mxmlFile("assets/xml/megu_dl.xml"); // Default template is char + rapidxml::xml_document<> mdoc; + mdoc.parse<0>(mxmlFile.data()); + rapidxml::xml_node<> *mpRoot = mdoc.first_node(); + for (rapidxml::xml_node<> *pNode = mpRoot->first_node("megu"); pNode; pNode = pNode->next_sibling("megu")) + { + megu f_obj; + f_obj.id = atoi(pNode->first_node("id")->value()); + // f_obj.jp_name = (pNode->first_node("strings")->first_node("name")->value()); + // f_obj.jp_detail = pNode->first_node("strings")->first_node("detail")->value(); + // f_obj.jp_family = pNode->first_node("strings")->first_node("family")->value(); + f_obj.en_name = pNode->last_node("strings")->first_node("name")->value(); + f_obj.en_detail = pNode->last_node("strings")->first_node("detail")->value(); + f_obj.en_family = pNode->last_node("strings")->first_node("family")->value(); + f_obj.size = atoi(pNode->first_node("size")->value()); + f_obj.hungry = atoi(pNode->first_node("hungry")->value()); + f_obj.change = atoi(pNode->first_node("change")->value()); + f_obj.min_weight = (float)(atof(pNode->first_node("min_weight")->value())); + f_obj.max_weight = (float)(atof(pNode->first_node("max_weight")->value())); + + f_obj.front_texture = loadTexture("assets/megu/ID" + std::to_string(f_obj.id) + "_3.png",renderer); + megu_lib[f_obj.id] = f_obj; + } + + rapidxml::file<> fxmlFile("assets/xml/food.xml"); // Default template is char + rapidxml::xml_document<> fdoc; + fdoc.parse<0>(fxmlFile.data()); + rapidxml::xml_node<> *fpRoot = fdoc.first_node(); + for (rapidxml::xml_node<> *pNode = fpRoot->first_node("food"); pNode; pNode = pNode->next_sibling("food")) + { + item f_obj; + f_obj.id = atoi(pNode->first_node("id")->value()); + f_obj.en_name = pNode->last_node("strings")->first_node("name")->first_node()->value(); + f_obj.en_detail = pNode->last_node("strings")->first_node("detail")->first_node()->value(); + f_obj.type = pNode->first_node("classification")->value(); + f_obj.nutrition = atoi(pNode->first_node("nutrition")->value()); + f_obj.calories = atoi(pNode->first_node("calorie")->value()); + f_obj.freshness = atoi(pNode->first_node("freshness")->value()); + f_obj.lvl = atoi(pNode->first_node("level")->value()); + f_obj.exp = atoi(pNode->first_node("exp")->value()); + f_obj.price = atoi(pNode->first_node("price")->value()); + f_obj.texture.push_back(loadTexture("assets/Food/Food_" + std::to_string(f_obj.id) + "@2x.png", renderer)); + food_lib[f_obj.id] = f_obj; + } + + rapidxml::file<> ixmlFile("assets/xml/furniture.xml"); // Default template is char + rapidxml::xml_document<> idoc; + idoc.parse<0>(ixmlFile.data()); + rapidxml::xml_node<> *ipRoot = idoc.first_node(); + for (rapidxml::xml_node<> *pNode = ipRoot->first_node("furniture"); pNode; pNode = pNode->next_sibling("furniture")) + { + item fur_obj; + fur_obj.id = atoi(pNode->first_node("id")->value()); + fur_obj.en_name = pNode->last_node("strings")->first_node("name")->first_node()->value(); + fur_obj.en_detail = pNode->last_node("strings")->first_node("detail")->first_node()->value(); + fur_obj.type = "furniture"; + fur_obj.lvl = atoi(pNode->first_node("level")->value()); + fur_obj.price = atoi(pNode->first_node("price")->value()); + if (pNode->first_node("animation") != NULL){ + fur_obj.isanimated = true; + fur_obj.animation_time = (int)(atof(pNode->first_node("animation")->first_node("duration")->value()) * 100); + std::string buf = pNode->first_node("animation")->first_node("list")->value(); + std::stringstream ss(buf); + int i; + while (ss >> i) + { + fur_obj.animation_order.push_back(i); + if(ss.peek() == ',' || ss.peek() == ' ') + ss.ignore(); + } + } + fur_obj.texture.push_back(loadTexture("assets/Furniture/KG" + std::to_string(fur_obj.id) + "@2x.png", renderer)); + + furniture_lib[fur_obj.id] = fur_obj; + } + + rapidxml::file<> axmlFile("assets/xml/accessory.xml"); // Default template is char + rapidxml::xml_document<> adoc; + adoc.parse<0>(axmlFile.data()); + rapidxml::xml_node<> *apRoot = adoc.first_node(); + for (rapidxml::xml_node<> *pNode = apRoot->first_node("accessory"); pNode; pNode = pNode->next_sibling("accessory")) + { + item acc_obj; + acc_obj.id = atoi(pNode->first_node("id")->value()); + acc_obj.en_name = pNode->last_node("strings")->first_node("name")->first_node()->value(); + acc_obj.en_detail = pNode->last_node("strings")->first_node("detail")->first_node()->value(); + acc_obj.type = "accessory"; + acc_obj.lvl = atoi(pNode->first_node("level")->value()); + acc_obj.price = atoi(pNode->first_node("price")->value()); + + acc_obj.texture.push_back(loadTexture("assets/Accessory/FUKU" + std::to_string(acc_obj.id) + ".png", renderer)); + accessory_lib[acc_obj.id] = acc_obj; + } + + } +}; \ No newline at end of file diff --git a/LayoutMenus.cpp b/LayoutMenus.cpp new file mode 100644 index 0000000..1e5b2d4 --- /dev/null +++ b/LayoutMenus.cpp @@ -0,0 +1,218 @@ +#include "LayoutMenus.h" +#include "SDL_include.h" +#include +#include +using namespace widgets; + +LayoutMenus::LayoutMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini) +{ + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + visible = false; + SDL_Color color; + color.a = 255; + color.b = 0; + color.g = 0; + color.r = 0; + std::string xmlpath = "assets//xml//layout_menu_config.xml"; + std::string xmltype = "layout"; + hxmlFile = new rapidxml::file<>(xmlpath.c_str()); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node(xmltype.c_str()); + } + else{ + pNode = hpRoot->first_node("config")->first_node(xmltype.c_str()); + } + sNode = pNode->first_node("slots"); + nNode = pNode->first_node("slot_name"); + dNode = pNode->first_node("slot_description"); + for (int i = 0; i < 3; ++i){ + slots.push_back(MeguButton(rect.x + atoi(sNode->first_node("pos")->first_node("x")->value()), + rect.y + i * atoi(sNode->first_node("offset")->first_node("y")->value()) + atoi(sNode->first_node("pos")->first_node("y")->value()), + atoi(sNode->first_node("pos")->first_node("w")->value()), + atoi(sNode->first_node("pos")->first_node("h")->value()), NULL, false)); + + slots_name.push_back(TtfWrapper(rect.x + atoi(nNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(nNode->first_node("offset")->first_node("y")->value()) + atoi(nNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(nNode->first_node("font_size")->value()) + , nNode->first_node("font")->value() + , 300 + , false) + ); + + + slots_description.push_back(TtfWrapper(rect.x + atoi(dNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(dNode->first_node("offset")->first_node("y")->value()) + atoi(dNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(dNode->first_node("font_size")->value()) + , nNode->first_node("font")->value() + , 300 + , false) + ); + + } + marker = loadTexture(pNode->first_node("marker")->first_node("texture")->value(), renderer); + marker_rect.w = atoi(pNode->first_node("marker")->first_node("size")->first_node("w")->value()); + marker_rect.h = atoi(pNode->first_node("marker")->first_node("size")->first_node("h")->value()); + marker_visible = false; + + for (rapidxml::xml_node<> *bNode = pNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")) + { + controls.push_back(MeguButton( + rect.x + atoi(bNode->first_node("pos")->first_node("x")->value()) + , rect.y + atoi(bNode->first_node("pos")->first_node("y")->value()) + , atoi(bNode->first_node("pos")->first_node("w")->value()) + , atoi(bNode->first_node("pos")->first_node("h")->value()) + , NULL + , true) + ); + } + int index = 0; + current_page = 0; + //Load image at specified path +} + +void LayoutMenus::RenderButtons(SDL_Renderer *renderer) +{ + if (visible){ + if (marker_visible){ + SDL_RenderCopy(renderer, marker, NULL, &marker_rect); + } + } +} + +void LayoutMenus::setViewPage(const int &page, SDL_Renderer *renderer){ + if (save){ + if (page >= 0){ + current_page = page; + updateSlots(renderer); + } + } + else{ + std::cerr << "layout list size: " << layout_list.size() << std::endl; + std::cerr << "page: " << page << std::endl; + std::cerr << "page limit: " << (layout_list.size() - 1) / 3 << std::endl; + if (page <= (layout_list.size() - 1) / 3 && page >= 0){ + + current_page = page; + updateSlots(renderer); + } + + } +} + +LayoutMenus::~LayoutMenus() +{ +} +void LayoutMenus::parseFiles(const std::vector &layout_friend_list){ + layout_list.clear(); + int i = 1; + + for (std::vector::const_iterator it = layout_friend_list.begin(); it != layout_friend_list.end(); ++it){ + std::ifstream file; + std::string filename = "gamedata/house/"; + file_data f; + std::stringstream ss; + std::string s; + std::cerr << *it << std::endl; + ss << std::setw(3) << std::setfill('0') << i; + s= "SAV" + ss.str() + ".house"; + ss.clear(); + while (s != *it){ + std::cerr << "s " << s << " " << *it << std::endl; + f.enabled = false; + layout_list.push_back(f); + i= i+1; + std::stringstream ss1; + ss1.clear(); + ss1 << std::setw(3) << std::setfill('0') << i; + s.clear(); + s = "SAV" + ss1.str() + ".house"; + } + file.open(filename + *it); + + if (file.is_open()){ + f.path = filename; + file >> f.img_path; + f.enabled = true; + layout_list.push_back(f); + file.close(); + } + ++i; + } +} + +void LayoutMenus::updateSlots(SDL_Renderer *renderer){ + //clean up first + for (int i = 0; i < 3; ++i){ + slots[i].changeObject(NULL); + slots[i].setEnable(false); + slots_name[i].free(); + slots_name[i].setVisible(false); + slots_description[i].free(); + slots_description[i].setVisible(false); + } + for (int i = 0; i < 3; ++i){ + int curr_index = current_page * 3 + i; + SDL_Texture * texture = NULL; + if (curr_index < layout_list.size()){ + int w, h; + texture = loadTexture("gamedata/house/preview/" + layout_list.at(curr_index).img_path, renderer); + std::cerr << "layout list: " << layout_list.at(curr_index).img_path << std::endl; + std::cerr << layout_list.at(curr_index).img_path << std::endl; + } + + std::cerr << "current index: " << curr_index << std::endl; + + slots[i].changeDisplayObject(texture, marker_rect.w, marker_rect.h, curr_index + 1); + if (save){ + slots[i].setEnable(true); + } + else{ + if (layout_list.at(curr_index).enabled){ + slots[i].setEnable(true); + + } + else{ + slots[i].setEnable(false); + } + } + } +} + + +SDL_Texture* LayoutMenus::loadTexture(std::string path, SDL_Renderer *renderer) +{ + //The final texture + SDL_Texture* newTexture = NULL; + + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + return newTexture; +} +void LayoutMenus::setMode(const bool &mode){ + save = mode; +} \ No newline at end of file diff --git a/LayoutMenus.h b/LayoutMenus.h new file mode 100644 index 0000000..24b196e --- /dev/null +++ b/LayoutMenus.h @@ -0,0 +1,37 @@ +#pragma once +#include "MeguMenus.h" +#include "MeguButton.h" +#include "SDL_include.h" +#include"Items_library.h" +#include +namespace widgets{ + class LayoutMenus : + public MeguMenus + { + struct file_data{ + std::string path; + std::string img_path;//path to preview png + bool enabled; + }; + typedef int ID; + public: + LayoutMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool& mini); + void loadSelectorTexture(const std::string &filename); + void RenderButtons(SDL_Renderer *renderer); + void updateSlots(SDL_Renderer *renderer); + void parseFiles(const std::vector &layout_file_list); + void setMode(const bool &mode); + void setViewPage(const int &page, SDL_Renderer *renderer); + ~LayoutMenus(); + std::string isInDisplay(int x, int y); + SDL_Texture *marker; + SDL_Rect marker_rect; + bool marker_visible; + bool save;//true yes, false no + protected: + std::vector layout_list; + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + + + }; +} diff --git a/MeguButton.h b/MeguButton.h new file mode 100644 index 0000000..33a2432 --- /dev/null +++ b/MeguButton.h @@ -0,0 +1,99 @@ +#pragma once +#include "SDL_include.h" +#include +#include + +namespace widgets{ + class MeguButton + { + private: + SDL_Texture* texture; + SDL_Rect rect; + SDL_Rect obj_rect; + //Load image at specified path + bool visible;//if yes then render/do stuff + bool enabled;//if yes then active/otherwise no + int id; // id for object, if applicable + + + + public: + MeguButton(){ + }; + + MeguButton(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, const bool &_visible = true) + { + texture = NULL; + rect.x = x; + rect.y = y; + obj_rect.x = x; + obj_rect.y = y; + rect.w = width; + rect.h = height; + obj_rect.w = width; + obj_rect.h = height; + texture = newtexture; + visible = _visible; + enabled = _visible; + } + int getX(){ + return rect.x; + } + int getY(){ + return rect.y; + } + void changeObject(SDL_Texture* newtexture){ + texture = NULL; + texture = newtexture; + } + + void changeDisplayObject(SDL_Texture* newtexture, const int &w, const int &h, const int &_id){ + texture = newtexture; + obj_rect.w = w; + obj_rect.h = h; + obj_rect.x = rect.x + (rect.w- obj_rect.w)/2; + obj_rect.y = rect.y + (rect.h- obj_rect.h)/2; + id = _id; + } + + void changePos(const int &x, const int &y){ + rect.x = x; + rect.y = y; + } + void setVisible(bool _visible){ + visible = _visible; + } + void setEnable(bool _enabled){ + enabled = _enabled; + } + bool getEnable(){ + return enabled; + } + bool IsIn(int mouseX, int mouseY) + { + if (((mouseX > rect.x) && (mouseX < rect.x + rect.w)) + && ((mouseY > rect.y) && (mouseY < rect.y + rect.h)) + && enabled) { + return true; + } + else { + return false; + } + } + + int getId(){ + return id; + } + + void Render(SDL_Renderer *renderer) + { + if (visible) + SDL_RenderCopy(renderer, texture, NULL, &obj_rect); + // use the same code you use now to render the button in OpenGL/SDL + } + + ~MeguButton(){ + SDL_DestroyTexture(texture); + } + }; +} \ No newline at end of file diff --git a/MeguData.cpp b/MeguData.cpp new file mode 100644 index 0000000..1c090a3 --- /dev/null +++ b/MeguData.cpp @@ -0,0 +1,11 @@ +#include "MeguData.h" + + +MeguData::MeguData() +{ +} + + +MeguData::~MeguData() +{ +} diff --git a/MeguData.h b/MeguData.h new file mode 100644 index 0000000..b94be7b --- /dev/null +++ b/MeguData.h @@ -0,0 +1,8 @@ +#pragma once +class MeguData +{ +public: + MeguData(); + ~MeguData(); +}; + diff --git a/MeguEngine.cpp b/MeguEngine.cpp new file mode 100644 index 0000000..afeae4c --- /dev/null +++ b/MeguEngine.cpp @@ -0,0 +1,3065 @@ +#include "MeguEngine.h" +#include "MeguSound.h" +#ifdef __APPLE__ +#include "CoreFoundation/CoreFoundation.h" +#include +#include +#endif +#ifdef _WIN32 +#include "dirent.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#include "SDL_include.h" +#include +#include + +MeguEngine::MeguEngine() : megu_blink_counter(1500), +megu_animation_counter(1000), +megu_misc_counter(5000), +megu_event_action(10000), +scene_limit(320), +megu_openeye_counter(50), +megu_pet_counter(150), +megu_spd(20), +megu_msg_counter(30000), +megu_heart_event_counter(250) +{ + Running = true; + curr_time = 0; + last_time = 0; + mPosition.x = 0; + mPosition.y = 0; + menu_open = false; + player_counter = 0; + msg_time = 0; + id_accessory = 0; +} + + +bool sortfunct(render_ordering i, render_ordering j){ + return (i.position_y < j.position_y); +} + +bool sortobjects(Megu::scene_objects i, Megu::scene_objects j){ + return (i.render_id < j.render_id); +} + +void MeguEngine::SetRenderOrder(){ + render_order.clear(); + for (std::map::iterator sprite_it = megu_list.begin(); sprite_it != megu_list.end(); ++sprite_it){ + render_order.push_back(render_ordering(sprite_it->first, sprite_it->second.position.y)); + } + std::sort(render_order.begin(), render_order.end(), sortfunct); +} + +void MeguEngine::initMenus(){ + rapidxml::file<> *hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//main_screen_config.xml"); // Default template is char + rapidxml::xml_document<> hdoc; + hdoc.parse<0>(hxmlFile->data()); + rapidxml::xml_node<> *hpRoot = hdoc.first_node(); + rapidxml::xml_node<> *pNode; + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("main_menu"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("main_menu"); + } + //load menus + + menu_bar_pos.w = atoi(pNode->first_node("menu_bar")->first_node("pos")->first_node("w")->value()); + menu_bar_pos.h = atoi(pNode->first_node("menu_bar")->first_node("pos")->first_node("h")->value()); + menu_bar_pos.x = atoi(pNode->first_node("menu_bar")->first_node("pos")->first_node("x")->value()); + menu_bar_pos.y = atoi(pNode->first_node("menu_bar")->first_node("pos")->first_node("y")->value()); + menu_background_pos.x = atoi(pNode->first_node("background")->first_node("pos")->first_node("x")->value()); + menu_background_pos.y = atoi(pNode->first_node("background")->first_node("pos")->first_node("y")->value()); + menu_background_pos.w = atoi(pNode->first_node("background")->first_node("pos")->first_node("w")->value()); + menu_background_pos.h = atoi(pNode->first_node("background")->first_node("pos")->first_node("h")->value()); + + + edit_holding = false; + //loading xml files + + + + std::cerr << "mouse cursor loading" << std::endl; + mouse_cursor = loadTexture("assets/cursor/hand.png"); + menu_bar = loadTexture(pNode->first_node("menu_bar")->first_node("texture")->value()); + updateBackground(1); + std::cerr << "populate libs " << std::endl; + library.populate(renderer); + std::cerr <<"load buttons" << std::endl; + care_button = new widgets::MeguButton( + atoi(pNode->first_node("care_button")->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("care_button")->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("care_button")->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("care_button")->first_node("pos")->first_node("h")->value()) + , NULL + , true + ); + edit_button = new widgets::MeguButton( + atoi(pNode->first_node("edit_button")->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("edit_button")->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("edit_button")->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("edit_button")->first_node("pos")->first_node("h")->value()) + , NULL + , true + ); + option_button = new widgets::MeguButton( + atoi(pNode->first_node("option_button")->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("option_button")->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("option_button")->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("option_button")->first_node("pos")->first_node("h")->value()) + , NULL + , true + ); + return_button = new widgets::MeguButton( + atoi(pNode->first_node("return_button")->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("return_button")->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("return_button")->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("return_button")->first_node("pos")->first_node("h")->value()) + , loadTexture(pNode->first_node("return_button")->first_node("texture")->value()) + , true); + return_button->setEnable(false); + return_button->setVisible(false); + std::cerr << "load house objects" << std::endl; + std::cerr << "populate house libs" << std::endl; + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//house_menu_config.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("house"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("house"); + } + house_menu = new widgets::HouseMenus( + atoi(pNode->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("pos")->first_node("h")->value()) + , &library.house_lib + , loadTexture(pNode->first_node("texture")->value()) + , renderer + , mini); + populateHouseLib(*house_menu, library.house_lib); + std::cerr << "load food objects" << std::endl; + std::cerr << "populate food libs" << std::endl; + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//food_menu_config.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("food"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("food"); + } + food_menu = new widgets::FoodMenus( + atoi(pNode->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("pos")->first_node("h")->value()) + , &library.food_lib + , loadTexture(pNode->first_node("texture")->value()) + , renderer + , mini); + populateLib(*food_menu, library.food_lib); + std::cerr << "load furniture objects" << std::endl; + std::cerr << "populate furniture libs" << std::endl; + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//furniture_menu_config.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("furniture"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("furniture"); + } + furniture_menu = new widgets::FurnitureMenus( + atoi(pNode->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("pos")->first_node("h")->value()) + , &library.furniture_lib + , loadTexture(pNode->first_node("texture")->value()) + , renderer + , mini); + + populateLib(*furniture_menu, library.furniture_lib); + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//accessory_menu_config.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("accessory"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("accessory"); + } + accessory_menu = new widgets::AccessoryMenus( + atoi(pNode->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("pos")->first_node("h")->value()) + , &library.accessory_lib + , loadTexture(pNode->first_node("texture")->value()) + , renderer + , mini); + + populateLib(*accessory_menu, library.accessory_lib); + std::cerr << "load pet objects" << std::endl; + std::cerr << "populate pet libs" << std::endl; + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//megutate_menu_config.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("megutate"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("megutate"); + } + pet_menu = new widgets::PetMenus( + atoi(pNode->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("pos")->first_node("h")->value()) + , &library.megu_lib + , loadTexture(pNode->first_node("texture")->value()) + , renderer + , mini); + + populatePetLib(*pet_menu, library.megu_lib); + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//friends_menu_config.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("friends"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("friends"); + } + + friends_menu = new widgets::FriendsMenus( + atoi(pNode->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("pos")->first_node("h")->value()) + , &library.megu_lib + , loadTexture(pNode->first_node("texture")->value()) + , renderer + , mini); + populatePetLib(*friends_menu, library.megu_lib); + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//layout_menu_config.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("layout"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("layout"); + } + + layout_menu = new widgets::LayoutMenus( + atoi(pNode->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("pos")->first_node("h")->value()) + , loadTexture(pNode->first_node("texture")->value()) + , renderer + , mini); + loadLayouts(); + food_menu->setClassificationType("American", renderer); + furniture_menu->setClassificationType("furniture", renderer); + pet_menu->setClassificationType("megu", renderer); + house_menu->setClassificationType("house", renderer); + accessory_menu->setClassificationType("accessory", renderer); + food_menu->setViewPage(0, renderer); + furniture_menu->setViewPage(0, renderer); + pet_menu->setViewPage(0, renderer); + house_menu->setViewPage(0, renderer); + accessory_menu->setViewPage(0, renderer); + std::cerr << "start menus" << std::endl; + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//care_menu_config.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("care"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("care"); + } + care_menu = new widgets::CareMenus( + atoi(pNode->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("pos")->first_node("h")->value()) + , loadTexture(pNode->first_node("texture")->value()) + , renderer + , mini); + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//edit_menu_config.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("edit"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("edit"); + } + edit_menu = new widgets::EditMenus( + atoi(pNode->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("pos")->first_node("h")->value()) + , loadTexture(pNode->first_node("texture")->value()) + , renderer + , mini); + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//name_menu_config.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("name"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("name"); + } + name_menu = new widgets::NameMenus( + atoi(pNode->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("pos")->first_node("h")->value()) + , loadTexture(pNode->first_node("texture")->value()) + , renderer + , mini); + + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//options_menu_config.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + //*Change this portion + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("options"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("options"); + } + options_menu = new widgets::OptionsMenus( + atoi(pNode->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("pos")->first_node("h")->value()) + , loadTexture(pNode->first_node("texture")->value()) + , renderer + , mini); + std::cerr << "load friend list" << std::endl; + loadFriendList(); + std::cerr << "parse friend list" << std::endl; + friends_menu->parseFiles(friends_save_list); + layout_menu->parseFiles(layout_save_list); + //food kit init + kit.table = (*library.furniture_lib[1].texture.begin()); + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//main_screen_config.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + //*Change this portion + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("food_kit"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("food_kit"); + } + kit.table_shadow = loadTexture(pNode->first_node("shadow")->first_node("texture")->value()); + SDL_SetTextureAlphaMod(kit.table_shadow, 46); + int w, h; + kit.rect_t.h = atoi(pNode->first_node("pos")->first_node("h")->value()); + kit.rect_t.w = atoi(pNode->first_node("pos")->first_node("w")->value()); + kit.rect_t.x = atoi(pNode->first_node("pos")->first_node("x")->value()) - kit.rect_t.w / 2; + kit.rect_t.y = atoi(pNode->first_node("pos")->first_node("y")->value()); + + kit.rect_s.x = kit.rect_t.x; + kit.rect_s.y = kit.rect_t.y + kit.rect_t.h + atoi(pNode->first_node("shadow")->first_node("pos")->first_node("y")->value()); + kit.rect_s.h = atoi(pNode->first_node("shadow")->first_node("pos")->first_node("h")->value()); + kit.rect_s.w = atoi(pNode->first_node("shadow")->first_node("pos")->first_node("w")->value()); + + kit.even_megu.x = atoi(pNode->first_node("megu_even_pos")->first_node("x")->value()); + kit.even_megu.y = atoi(pNode->first_node("megu_even_pos")->first_node("y")->value()); + kit.odd_megu.x = atoi(pNode->first_node("megu_odd_pos")->first_node("x")->value()); + kit.odd_megu.y = atoi(pNode->first_node("megu_odd_pos")->first_node("y")->value()); + kit.rect_f.x = kit.rect_t.x + atoi(pNode->first_node("food")->first_node("pos")->first_node("x")->value()); + kit.rect_f.y = kit.rect_t.y + atoi(pNode->first_node("food")->first_node("pos")->first_node("y")->value()); + kit.rect_f.w = atoi(pNode->first_node("food")->first_node("pos")->first_node("w")->value()); + kit.rect_f.h = atoi(pNode->first_node("food")->first_node("pos")->first_node("h")->value()); + + kit.visible = false; + SDL_Color color; + color.a = 255; + color.b = 230; + color.g = 230; + color.r = 230; + if (!mini){ + pNode = hpRoot->last_node("config")->first_node("main_menu"); + } + else{ + pNode = hpRoot->first_node("config")->first_node("main_menu"); + } + ui_texts.push_back(TtfWrapper(menu_bar_pos.x + atoi(pNode->first_node("name_input")->first_node("pos")->first_node("x")->value()) + , menu_bar_pos.y + atoi(pNode->first_node("name_input")->first_node("pos")->first_node("y")->value()) + , 255 + , 255 + , 255 + , SDL_BLENDMODE_BLEND + , 0 + , color + , atoi(pNode->first_node("name_input")->first_node("font_size")->value()) + , pNode->first_node("owner_input")->first_node("font")->value() + , 300 + , false) + ); + ui_texts.push_back(TtfWrapper(menu_bar_pos.x + atoi(pNode->first_node("owner_input")->first_node("pos")->first_node("x")->value()) + , menu_bar_pos.y + atoi(pNode->first_node("owner_input")->first_node("pos")->first_node("y")->value()) + , 255 + , 255 + , 255 + , SDL_BLENDMODE_BLEND + , 0 + , color + , atoi(pNode->first_node("owner_input")->first_node("font_size")->value()) + , pNode->first_node("owner_input")->first_node("font")->value() + , 300 + , false) + ); +} + +bool MeguEngine::OnInit() { + mini = true; +#ifdef __APPLE__ + CFBundleRef mainBundle = CFBundleGetMainBundle(); + CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); + char path[PATH_MAX]; + if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) + { + // error! + } + CFRelease(resourcesURL); + + chdir(path); + std::cout << "Current Path: " << path << std::endl; +#endif + if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { + std::cerr << "SDL initializing" << std::endl; + return false; + } + if (TTF_Init() == -1){ + std::cerr << "SDL_TTF error: " << TTF_GetError() << std::endl; + exit(2); + } + std::cerr << "open audio" << std::endl; + if (Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 4096) == -1) + { + return false; + } + sounds.loadAll(); + //init window + std::cerr << "create window" << std::endl; + win = SDL_CreateWindow("MEGU 2.2!", 100, 100, 180, 100, 0); + //init render + std::cerr << "set renderer" << std::endl; + renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + + rapidxml::file<> shxmlFile("assets//xml//size_menu_config.xml"); // Default template is char + rapidxml::xml_document<> shdoc; + shdoc.parse<0>(shxmlFile.data()); + rapidxml::xml_node<> *shpRoot = shdoc.first_node(); + rapidxml::xml_node<> *spNode; + status = Game::INIT; + spNode = shpRoot->first_node("config")->first_node("size_selector"); + sounds.setBGMVolume(3); + sounds.playBGM("stroll"); + size_menu = new widgets::SizeMenus( + atoi(spNode->first_node("pos")->first_node("x")->value()) + , atoi(spNode->first_node("pos")->first_node("y")->value()) + , atoi(spNode->first_node("pos")->first_node("w")->value()) + , atoi(spNode->first_node("pos")->first_node("h")->value()) + , loadTexture(spNode->first_node("texture")->value()) + , renderer); + size_menu->callMenu(); + SDL_Event Event; + while (status == Game::INIT) { + + while (SDL_PollEvent(&Event)) { + handleSizeSelector(&Event); + } + size_menu->Render(renderer); + SDL_RenderPresent(renderer); + } + size_menu->disableMenu(); + + delete size_menu; + + int win_h, win_w; + rapidxml::file<> hxmlFile("assets//xml//game_window_config.xml"); // Default template is char + rapidxml::xml_document<> hdoc; + hdoc.parse<0>(hxmlFile.data()); + rapidxml::xml_node<> *hpRoot = hdoc.first_node(); + rapidxml::xml_node<> *pNode; + if (!mini){ + pNode = hpRoot->last_node("config"); + } + else{ + pNode = hpRoot->first_node("config"); + } + win_w = atoi(pNode->first_node("game_window")->first_node("size")->first_node("w")->value()); + win_h = atoi(pNode->first_node("game_window")->first_node("size")->first_node("h")->value()); + + SDL_SetWindowSize(win, win_w, win_h); + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + std::cerr << "init menus" << std::endl; + initMenus(); + //init other objects + initObjects(); + populateRndMsg(); + deserializeOptions(); + std::cerr << "game running" << std::endl; + status = Game::RUNNING; + return true; + +} +void MeguEngine::initObjects(){ + rapidxml::file<> *hxmlFile = new rapidxml::file<>("assets//xml//main_screen_config.xml"); // Default template is char + rapidxml::xml_document<> hdoc; + hdoc.parse<0>(hxmlFile->data()); + rapidxml::xml_node<> *hpRoot = hdoc.first_node(); + rapidxml::xml_node<> *pNode; + rapidxml::xml_node<> *gNode; + rapidxml::xml_node<> *cNode; + if (!mini){ + gNode = hpRoot->last_node("config"); + } + else{ + gNode = hpRoot->first_node("config"); + } + pNode = gNode->first_node("game_models")->first_node("megu"); + megu_size.x = atoi(pNode->first_node("init_pos")->first_node("x")->value()); + megu_size.y = atoi(pNode->first_node("init_pos")->first_node("y")->value()); + megu_size.w = atoi(pNode->first_node("init_pos")->first_node("w")->value()); + megu_size.h = atoi(pNode->first_node("init_pos")->first_node("h")->value()); + shadow_pos.x = atoi(pNode->first_node("shadow")->first_node("pos")->first_node("x")->value()); + shadow_pos.y = atoi(pNode->first_node("shadow")->first_node("pos")->first_node("y")->value()); + shadow_pos.w = atoi(pNode->first_node("shadow")->first_node("pos")->first_node("w")->value()); + shadow_pos.h = atoi(pNode->first_node("shadow")->first_node("pos")->first_node("h")->value()); + shadow_texture = pNode->first_node("shadow")->first_node("texture")->value(); + shadow_alpha = atoi(pNode->first_node("shadow")->first_node("texture")->value()); + + clickable_area.x = atoi(gNode->first_node("walk_area")->first_node("pos")->first_node("x")->value()); + clickable_area.y = atoi(gNode->first_node("walk_area")->first_node("pos")->first_node("y")->value()); + clickable_area.w = atoi(gNode->first_node("walk_area")->first_node("pos")->first_node("w")->value()); + clickable_area.h = atoi(gNode->first_node("walk_area")->first_node("pos")->first_node("h")->value()); + + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//message_plaque_config.xml"); + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + if (!mini){ + gNode = hpRoot->last_node("config"); + } + else{ + gNode = hpRoot->first_node("config"); + } + pNode = gNode->first_node("message_plaque"); + message_screen = new widgets::MessageScreen( + atoi(pNode->first_node("pos")->first_node("x")->value()) + , atoi(pNode->first_node("pos")->first_node("y")->value()) + , atoi(pNode->first_node("pos")->first_node("w")->value()) + , atoi(pNode->first_node("pos")->first_node("h")->value()) + , loadTexture(pNode->first_node("texture")->value()) + , renderer + , mini); + if (!mini){ + hearts_texture.push_back(loadTexture("assets/objects/heart_s@2x.png")); + hearts_texture.push_back(loadTexture("assets/objects/heart_m@2x.png")); + hearts_texture.push_back(loadTexture("assets/objects/heart_l@2x.png")); + heart_offset.x = 128; + heart_offset.y = -50; + } + else{ + hearts_texture.push_back(loadTexture("assets/objects/heart_s.png")); + hearts_texture.push_back(loadTexture("assets/objects/heart_m.png")); + hearts_texture.push_back(loadTexture("assets/objects/heart_l.png")); + heart_offset.x = 64; + heart_offset.y = -25; + } + +} + + +void MeguEngine::setMousePosition(int x, int y) +{ + mPosition.x = x; + mPosition.y = y; +} + +void MeguEngine::handleSizeSelector(SDL_Event* e){ + int x, y; + SDL_GetMouseState(&x, &y); + switch (e->type){ + case SDL_MOUSEBUTTONDOWN: + if (size_menu->buttons.at(0).IsIn(x, y)){ + mini = false; + status = Game::RUNNING; + } + else if (size_menu->buttons.at(1).IsIn(x, y)){ + mini = true; + status = Game::RUNNING; + } + break; + } +} +void MeguEngine::handleMouseEvent(SDL_Event* e) +{ + //Get mouse position + int x, y; + SDL_GetMouseState(&x, &y); + //mouse event + //verify typing + if (name_menu->text_edits.at(0).getFocus()){ + name_menu->text_edits.at(0).handleKey(e); + } + else if (name_menu->text_edits.at(1).getFocus()){ + name_menu->text_edits.at(1).handleKey(e); + } + switch (e->type){ + + case SDL_MOUSEBUTTONDOWN: + + if (status == Game::RUNNING){ + //Check if mouse is in button + for (std::map::iterator sprite_it = megu_list.begin(); sprite_it != megu_list.end(); ++sprite_it){ + std::cerr << "mouse coords: " << x << " " << y << std::endl; + if (care_button->IsIn(x, y)){ + sounds.playSFX(std::string("click"), 5); + care_menu->callMenu(); + status = Game::CARE_MENU; + } + else if (edit_button->IsIn(x, y)){ + sounds.playSFX("click", 5); + edit_menu->callMenu(); + status = Game::EDIT_MENU; + } + else if (option_button->IsIn(x, y)){ + sounds.playSFX("click", 5); + options_menu->callMenu(); + status = Game::OPTIONS_MENU; + } + if (e->button.button == SDL_BUTTON_LEFT){ + if ((x > sprite_it->second.position.x) && (x < sprite_it->second.position.x + sprite_it->second.position.w) && + (y > sprite_it->second.position.y) && (y < sprite_it->second.position.y + sprite_it->second.position.h)){ + sprite_it->second.pet_flag = true; + } + else if (y > clickable_area.y && y < clickable_area.y + clickable_area.h && x > clickable_area.x && x < clickable_area.x + clickable_area.w){ + for (std::map::iterator it = megu_list.begin(); it != megu_list.end(); ++it){ + if ((it->first) % 2 == 1){ + MeguClickScene(it->first, x - megu_size.w / 2, y - megu_size.h); + if (e->button.clicks == 1){ + it->second.run_flag = false; + } + else if (e->button.clicks == 2){ + it->second.run_flag = true; + } + } + } + + } + + } + if (e->button.button == SDL_BUTTON_RIGHT){ + if ((x > sprite_it->second.position.x) && (x < sprite_it->second.position.x + sprite_it->second.position.w) && + (y > sprite_it->second.position.y) && (y < sprite_it->second.position.y + sprite_it->second.position.h)){ + sprite_it->second.pet_flag = true; + } + else if (y > clickable_area.y && y < clickable_area.y + clickable_area.h && x > clickable_area.x && x < clickable_area.x + clickable_area.w){ + for (std::map::iterator it = megu_list.begin(); it != megu_list.end(); ++it){ + if ((it->first) % 2 == 0){ + MeguClickScene(it->first, x - megu_size.w / 2, y - megu_size.h); + if (e->button.clicks == 1){ + it->second.run_flag = false; + } + else if (e->button.clicks == 2){ + it->second.run_flag = true; + } + } + } + } + } + + } + } + + else if (status == Game::CARE_MENU){ + if (care_menu->controls[0].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::RUNNING; + care_menu->disableMenu(); + } + if (care_menu->slots[0].IsIn(x, y)){ + care_menu->disableMenu(); + sounds.playSFX("click", 5); + food_menu->callMenu(); + food_menu->updateSlots(renderer); + status = Game::FOOD_MENU; + } + if (care_menu->slots[1].IsIn(x, y)){ + care_menu->disableMenu(); + sounds.playSFX("click", 5); + furniture_menu->callMenu(); + furniture_menu->updateSlots(renderer); + status = Game::FURNITURE_MENU; + } + else if (care_menu->slots[2].IsIn(x, y)){ + care_menu->disableMenu(); + sounds.playSFX("click", 5); + status = Game::EDIT_MODE; + return_button->setEnable(true); + return_button->setVisible(true); + message_screen->addMessage("Click to pick. DEL to delete. PGUP PGDN to organize"); + message_screen->visible = true; + message_screen->locked = true; + } + else if (care_menu->slots[3].IsIn(x, y)){ + care_menu->disableMenu(); + sounds.playSFX("click", 5); + pet_menu->callMenu(); + pet_menu->updateSlots(renderer); + status = Game::PET_MENU; + sounds.pauseMusic(); + sounds.playSFX("changing", 5); + } + else if (care_menu->slots[4].IsIn(x, y)){ + care_menu->disableMenu(); + sounds.playSFX("click", 5); + objects_list.clear(); + status = Game::HOUSE_MENU; + status = Game::RUNNING; + } + else if (care_menu->slots[5].IsIn(x, y)){ + care_menu->disableMenu(); + sounds.playSFX("click", 5); + house_menu->callMenu(); + house_menu->updateSlots(renderer); + sounds.pauseMusic(); + sounds.playSFX("Continuation", 5); + status = Game::HOUSE_MENU; + } +/* else if (care_menu->slots[6].IsIn(x, y)){ + care_menu->disableMenu(); + sounds.playSFX("click", 5); + accessory_menu->callMenu(); + accessory_menu->updateSlots(renderer); + status = Game::ACCESSORY_MENU; + } + else if (care_menu->slots[7].IsIn(x, y)){ + care_menu->disableMenu(); + sounds.playSFX("click", 5); + return_button->setEnable(true); + return_button->setVisible(true); + message_screen->addMessage("Click to pick. DEL to delete. PGUP PGDN to organize"); + message_screen->visible = true; + message_screen->locked = true; + SetMeguPos(1, 192, 192, SDL_FLIP_NONE); + OnRender(); + status = Game::ACCESSORY_MODE; + } + */ + } + + else if (status == Game::EDIT_MENU){ + if (edit_menu->controls[0].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::RUNNING; + edit_menu->disableMenu(); + } + if (edit_menu->slots[0].IsIn(x, y)){ + edit_menu->disableMenu(); + name_menu->text_edits.at(0).setText(megu_list[1].owner_name); + name_menu->text_edits.at(1).setText(megu_list[1].pet_name); + name_menu->callMenu(); + status = Game::NAME_MENU; + } + + if (edit_menu->slots[1].IsIn(x, y)){ + + edit_menu->disableMenu(); + sounds.playSFX("click", 5); + loadLayouts(); + layout_menu->parseFiles(layout_save_list); + layout_menu->callMenu(); + layout_menu->setMode(true); + layout_menu->updateSlots(renderer); + + status = Game::LAYOUT_SAVE_MENU; + } + + else if (edit_menu->slots[2].IsIn(x, y)){ + sounds.playSFX("click", 5); + loadLayouts(); + if (!layout_save_list.empty()){ + edit_menu->disableMenu(); + layout_menu->parseFiles(layout_save_list); + layout_menu->callMenu(); + layout_menu->updateSlots(renderer); + layout_menu->setMode(false); + status = Game::LAYOUT_LOAD_MENU; + } + } + + else if (edit_menu->slots[3].IsIn(x, y)){ + sounds.playSFX("click", 5); + edit_menu->disableMenu(); + sounds.playSFX("click", 5); + pet_menu->callMenu(); + status = Game::NEW_MEGU_PET_MENU; + + + } + else if (edit_menu->slots[4].IsIn(x, y)){ + edit_menu->disableMenu(); + friends_menu->parseFiles(friends_save_list); + friends_menu->callMenu(); + friends_menu->updateSlots(renderer); + sounds.playSFX("click", 5); + status = Game::FRIEND_INVITE_MENU; + } + else if (edit_menu->slots[5].IsIn(x, y)){ + sounds.playSFX("Departure", 5); + if (megu_list.size() > 1){ + std::vector id_list; + for (std::map::iterator it = megu_list.begin(); it != megu_list.end(); ++it){ + if (it->first != 1){//except user + id_list.push_back(it->first); + } + } + render_order.clear(); + render_order.push_back(render_ordering(1, megu_list[1].position.y)); + + for (std::vector::iterator r_it = id_list.begin(); r_it != id_list.end(); ++r_it){ + std::map::iterator ID_iterator; + ID_iterator = megu_list.find(*r_it); + megu_list.erase(ID_iterator, megu_list.end()); + } + } + edit_menu->disableMenu(); + status = Game::RUNNING; + + + } + else if (edit_menu->slots[6].IsIn(x, y)){ + edit_menu->disableMenu(); + sounds.playSFX("click", 5); + serializePlayer("gamedata/friends/player.megu", megu_list[1]); + status = Game::RUNNING; + } + + } + else if (status == Game::OPTIONS_MENU){ + if (options_menu->controls[0].IsIn(x, y)){ + sounds.playSFX("click", 5); + serializeOptions(); + options_menu->disableMenu(); + status = Game::RUNNING; + } + else if (options_menu->option_buttons[0].IsIn(x, y)){ + sounds.playSFX("click", 5); + options_menu->setSFXLevel(options_menu->getSFXLevel() - 1); + sounds.setSFXVolume(options_menu->getSFXLevel()); + options_menu->updateMarkers(); + } + else if (options_menu->option_buttons[1].IsIn(x, y)){ + sounds.playSFX("click", 5); + options_menu->setSFXLevel(options_menu->getSFXLevel() + 1); + sounds.setSFXVolume(options_menu->getSFXLevel()); + options_menu->updateMarkers(); + } + else if (options_menu->option_buttons[2].IsIn(x, y)){ + sounds.playSFX("click", 5); + options_menu->setBGMLevel(options_menu->getBGMLevel() - 1); + sounds.setBGMVolume(options_menu->getBGMLevel()); + options_menu->updateMarkers(); + } + else if (options_menu->option_buttons[3].IsIn(x, y)){ + sounds.playSFX("click", 5); + options_menu->setBGMLevel(options_menu->getBGMLevel() + 1); + sounds.setBGMVolume(options_menu->getBGMLevel()); + options_menu->updateMarkers(); + } + else if (options_menu->option_buttons[4].IsIn(x, y)){ + sounds.playSFX("click", 5); + options_menu->setMSGOn(true); + options_menu->updateMarkers(); + } + else if (options_menu->option_buttons[5].IsIn(x, y)){ + sounds.playSFX("click", 5); + options_menu->setMSGOn(false); + options_menu->updateMarkers(); + } + + } + else if (status == Game::NAME_MENU){ + if (name_menu->controls[0].IsIn(x, y)){ + sounds.playSFX("click", 5); + name_menu->disableMenu(); + status = Game::RUNNING; + name_menu->text_edits.at(0).setFocus(false); + name_menu->text_edits.at(1).setFocus(false); + } + else if (name_menu->text_edits.at(0).isIn(x, y)){ + name_menu->text_edits.at(0).setFocus(true); + name_menu->text_edits.at(1).setFocus(false); + } + else if (name_menu->text_edits.at(1).isIn(x, y)){ + name_menu->text_edits.at(0).setFocus(false); + name_menu->text_edits.at(1).setFocus(true); + } + else if (name_menu->controls[1].IsIn(x, y)){ + sounds.playSFX("click", 5); + megu_list[1].owner_name = name_menu->text_edits.at(0).getText(); + megu_list[1].pet_name = name_menu->text_edits.at(1).getText(); + status = Game::RUNNING; + ui_texts[0].text = megu_list[1].owner_name; + ui_texts[1].text = megu_list[1].pet_name; + for (std::vector::iterator it = ui_texts.begin(); it != ui_texts.end(); ++it){ + it->loadFromRenderedText(renderer); + } + name_menu->disableMenu(); + } + else{ + name_menu->text_edits.at(0).setFocus(false); + name_menu->text_edits.at(1).setFocus(false); + } + } + else if (status == Game::HOUSE_MENU){ + if (house_menu->controls[2].IsIn(x, y)){ + sounds.playSFX("click", 5); + sounds.cutSFX(6); + house_menu->disableMenu(); + if (sounds.getBGMOn()) + sounds.resumeMusic(); + status = Game::RUNNING; + } + else if (house_menu->controls[3].IsIn(x, y)){ + sounds.playSFX("click", 5); + house_menu->marker_visible = false; + updateBackground(house_menu->getCurrentId()); + sounds.cutSFX(6); + house_menu->disableMenu(); + sounds.playSFX("GetCntinuation", 5); + if (sounds.getBGMOn()) + sounds.resumeMusic(); + OnRender(); + serializeHouse("DEFAULT"); + status = Game::RUNNING; + } + else if (house_menu->controls[1].IsIn(x, y)){ + house_menu->setViewPage(house_menu->current_page - 1, renderer); + house_menu->marker_visible = false; + house_menu->controls[3].setEnable(false); + sounds.playSFX("click", 5); + + } + else if (house_menu->controls[0].IsIn(x, y)){ + house_menu->setViewPage(house_menu->current_page + 1, renderer); + house_menu->marker_visible = false; + house_menu->controls[3].setEnable(false); + sounds.playSFX("click", 5); + } + //item selector + for (widgets::button_container::iterator it = house_menu->slots.begin(); it != house_menu->slots.end(); ++it){ + if (it->IsIn(x, y)){ + if (it->getEnable()){ + house_menu->setCurrentId(it->getId()); + house_menu->marker_rect.x = it->getX(); + house_menu->marker_rect.y = it->getY(); + house_menu->marker_visible = true; + house_menu->controls[3].setEnable(true); + + } + } + } + } + else if (status == Game::PET_MENU){ + if (pet_menu->controls[2].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::RUNNING; + sounds.cutSFX(3); + if (sounds.getBGMOn()) + sounds.resumeMusic(); + pet_menu->marker_visible = false; + pet_menu->disableMenu(); + } + if (pet_menu->controls[3].IsIn(x, y)){ + int player = 0; + if (e->button.button == SDL_BUTTON_LEFT){ + player = 1; + } + + sounds.playSFX("click", 5); + int x = megu_list[player].position.x; + int y = megu_list[player].position.y; + SDL_RendererFlip flip = megu_list[player].side; + LoadMegu(pet_menu->getCurrentId(), player); + SetMeguPos(player, x, y, flip); + SetMeguState(player, Megu::VERY_HAPPY); + sounds.cutSFX(3); + if (sounds.getBGMOn()) + sounds.resumeMusic(); + sounds.playSFX("changed", 5); + pet_menu->marker_visible = false; + ui_texts[0].text = megu_list[1].owner_name; + ui_texts[1].text = megu_list[1].pet_name; + //ui_texts[2].text = megu_list[1].pet_race; + for (std::vector::iterator it = ui_texts.begin(); it != ui_texts.end(); ++it){ + it->loadFromRenderedText(renderer); + } + pet_menu->disableMenu(); + status = Game::RUNNING; + } + else if (pet_menu->controls[1].IsIn(x, y)){ + pet_menu->setViewPage(pet_menu->current_page - 1, renderer); + pet_menu->marker_visible = false; + pet_menu->controls[3].setEnable(false); + } + else if (pet_menu->controls[0].IsIn(x, y)){ + pet_menu->setViewPage(pet_menu->current_page + 1, renderer); + pet_menu->marker_visible = false; + pet_menu->controls[3].setEnable(false); + } + //item selector + + for (widgets::button_container::iterator it = pet_menu->slots.begin(); it != pet_menu->slots.end(); ++it){ + if (it->IsIn(x, y)){ + if (it->getEnable()){ + pet_menu->setCurrentId(it->getId()); + pet_menu->marker_rect.x = it->getX(); + pet_menu->marker_rect.y = it->getY(); + pet_menu->marker_visible = true; + pet_menu->controls[3].setEnable(true); + } + } + } + } + + else if (status == Game::NEW_MEGU_NAME_MENU){ + if (name_menu->controls[0].IsIn(x, y)){ + sounds.playSFX("click", 5); + name_menu->disableMenu(); + new_megu_id = 0; + status = Game::RUNNING; + name_menu->text_edits.at(0).setFocus(false); + name_menu->text_edits.at(1).setFocus(false); + } + else if (name_menu->text_edits.at(0).isIn(x, y)){ + name_menu->text_edits.at(0).setFocus(true); + name_menu->text_edits.at(1).setFocus(false); + } + else if (name_menu->text_edits.at(1).isIn(x, y)){ + name_menu->text_edits.at(0).setFocus(false); + name_menu->text_edits.at(1).setFocus(true); + } + else if (name_menu->controls[1].IsIn(x, y)){ + sounds.playSFX("click", 5); + int p_id = megu_list.rbegin()->first + 1; + LoadMegu(new_megu_id, p_id); + megu_list[p_id].owner_name = name_menu->text_edits.at(0).getText(); + megu_list[p_id].pet_name = name_menu->text_edits.at(1).getText(); + megu_list[p_id].position.x = megu_size.x; + megu_list[p_id].position.y = megu_size.y; + megu_list[p_id].shadow_pos.x = megu_size.x + shadow_pos.x; + megu_list[p_id].shadow_pos.y = megu_size.y + shadow_pos.y; + + megu_list[p_id].blink = Megu::OPEN; + megu_list[p_id].state = Megu::STOP_ONE; + serializePlayer("gamedata/friends/" + megu_list[p_id].pet_race + "_" + megu_list[p_id].owner_name + "_" + megu_list[p_id].pet_name + ".megu", megu_list[p_id]); + name_menu->disableMenu(); + loadFriendList(); + sounds.playSFX("Complete", 5); + status = Game::RUNNING; + OnRender(); + } + else{ + name_menu->text_edits.at(0).setFocus(false); + name_menu->text_edits.at(1).setFocus(false); + } + } + else if (status == Game::NEW_MEGU_PET_MENU){ + if (pet_menu->controls[2].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::RUNNING; + sounds.cutSFX(3); + if (sounds.getBGMOn()) + sounds.resumeMusic(); + pet_menu->marker_visible = false; + pet_menu->disableMenu(); + } + if (pet_menu->controls[3].IsIn(x, y)){ + sounds.playSFX("click", 5); + pet_menu->disableMenu(); + name_menu->text_edits[0].setText(megu_list[1].owner_name); + name_menu->text_edits[1].setText("MEGU"); + name_menu->callMenu(); + status = Game::NEW_MEGU_NAME_MENU; + } + else if (pet_menu->controls[1].IsIn(x, y)){ + pet_menu->setViewPage(pet_menu->current_page - 1, renderer); + pet_menu->marker_visible = false; + pet_menu->controls[3].setEnable(false); + } + else if (pet_menu->controls[0].IsIn(x, y)){ + pet_menu->setViewPage(pet_menu->current_page + 1, renderer); + pet_menu->marker_visible = false; + pet_menu->controls[3].setEnable(false); + } + //item selector + + for (widgets::button_container::iterator it = pet_menu->slots.begin(); it != pet_menu->slots.end(); ++it){ + if (it->IsIn(x, y)){ + if (it->getEnable()){ + new_megu_id = it->getId(); + pet_menu->marker_rect.x = it->getX(); + pet_menu->marker_rect.y = it->getY(); + pet_menu->marker_visible = true; + pet_menu->controls[3].setEnable(true); + } + } + } + } + + + else if (status == Game::FURNITURE_MENU){ + if (furniture_menu->controls[2].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::RUNNING; + furniture_menu->disableMenu(); + } + if (furniture_menu->controls[3].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::EDIT_MODE; + return_button->setEnable(true); + return_button->setVisible(true); + message_screen->addMessage("Click to pick. DEL to delete. PGUP PGDN to organize"); + message_screen->visible = true; + message_screen->locked = true; + LoadFurniture(furniture_menu->getCurrentId(), "furniture"); + furniture_menu->disableMenu(); + } + else if (furniture_menu->controls[1].IsIn(x, y)){ + sounds.playSFX("click", 5); + furniture_menu->setViewPage(furniture_menu->current_page - 1, renderer); + furniture_menu->marker_visible = false; + furniture_menu->controls[3].setEnable(false); + } + else if (furniture_menu->controls[0].IsIn(x, y)){ + sounds.playSFX("click", 5); + furniture_menu->setViewPage(furniture_menu->current_page + 1, renderer); + furniture_menu->marker_visible = false; + furniture_menu->controls[3].setEnable(false); + } + //item selector + for (widgets::button_container::iterator it = furniture_menu->slots.begin(); it != furniture_menu->slots.end(); ++it){ + if (it->IsIn(x, y)){ + if (it->getEnable()){ + furniture_menu->setCurrentId(it->getId()); + furniture_menu->marker_rect.x = it->getX(); + furniture_menu->marker_rect.y = it->getY(); + furniture_menu->marker_visible = true; + furniture_menu->controls[3].setEnable(true); + } + } + } + } + /* + else if (status == Game::ACCESSORY_MENU){ + if (accessory_menu->controls[2].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::RUNNING; + accessory_menu->disableMenu(); + } + if (accessory_menu->controls[3].IsIn(x, y)){ + sounds.playSFX("click", 5); + return_button->setEnable(true); + return_button->setVisible(true); + message_screen->addMessage("Click to pick. DEL to delete. PGUP PGDN to organize"); + message_screen->visible = true; + message_screen->locked = true; + LoadAccessory(accessory_menu->getCurrentId(), megu_list.begin()->first,0,0,300,300, "accessory"); + SetMeguPos(1, 192, 192, SDL_FLIP_NONE); + SetMeguDestination(1, 192, 192); + OnRender(); + status = Game::ACCESSORY_MODE; + accessory_menu->disableMenu(); + } + else if (accessory_menu->controls[1].IsIn(x, y)){ + sounds.playSFX("click", 5); + accessory_menu->setViewPage(accessory_menu->current_page - 1, renderer); + accessory_menu->marker_visible = false; + accessory_menu->controls[3].setEnable(false); + } + else if (accessory_menu->controls[0].IsIn(x, y)){ + sounds.playSFX("click", 5); + accessory_menu->setViewPage(accessory_menu->current_page + 1, renderer); + accessory_menu->marker_visible = false; + accessory_menu->controls[3].setEnable(false); + } + //item selector + for (widgets::button_container::iterator it = accessory_menu->slots.begin(); it != accessory_menu->slots.end(); ++it){ + if (it->IsIn(x, y)){ + if (it->getEnable()){ + accessory_menu->setCurrentId(it->getId()); + accessory_menu->marker_rect.x = it->getX(); + accessory_menu->marker_rect.y = it->getY(); + accessory_menu->marker_visible = true; + accessory_menu->controls[3].setEnable(true); + } + } + } + } + */ + else if (status == Game::FOOD_MENU){ + if (food_menu->controls[2].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::RUNNING; + food_menu->marker_visible = false; + food_menu->disableMenu(); + } + else if (food_menu->controls[3].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::FEEDING; + sounds.playSFX("changed", 5); + food_mode(food_menu->getCurrentId()); + food_menu->marker_visible = false; + food_menu->disableMenu(); + + } + else if (food_menu->controls[1].IsIn(x, y)){ + sounds.playSFX("click", 5); + food_menu->setViewPage(food_menu->current_page - 1, renderer); + food_menu->marker_visible = false; + food_menu->controls[3].setEnable(false); + } + else if (food_menu->controls[0].IsIn(x, y)){ + sounds.playSFX("click", 5); + food_menu->setViewPage(food_menu->current_page + 1, renderer); + food_menu->marker_visible = false; + food_menu->controls[3].setEnable(false); + } + if (food_menu->controls[4].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::EDIT_MODE; + return_button->setEnable(true); + return_button->setVisible(true); + message_screen->addMessage("Click to pick. DEL to delete. PGUP PGDN to organize"); + message_screen->visible = true; + message_screen->locked = true; + LoadFurniture(food_menu->getCurrentId(), "food"); + food_menu->disableMenu(); + } + else{ + std::string class_button = food_menu->isInDisplay(x, y); + if (class_button.compare("NONE") != 0){ + food_menu->setClassificationType(food_menu->isInDisplay(x, y), renderer); + food_menu->setViewPage(0, renderer); + food_menu->marker_visible = false; + food_menu->controls[3].setEnable(false); + sounds.playSFX("click", 5); + } + //item selector + for (widgets::button_container::iterator it = food_menu->slots.begin(); it != food_menu->slots.end(); ++it){ + if (it->IsIn(x, y)){ + if (it->getEnable()){ + food_menu->setCurrentId(it->getId()); + food_menu->marker_rect.x = it->getX(); + food_menu->marker_rect.y = it->getY(); + food_menu->marker_visible = true; + food_menu->controls[3].setEnable(true); + + } + + } + } + } + //food + } + + else if (status == Game::LAYOUT_SAVE_MENU){ + if (layout_menu->controls[2].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::RUNNING; + layout_menu->marker_visible = false; + layout_menu->disableMenu(); + } + else if (layout_menu->controls[3].IsIn(x, y)){ + sounds.playSFX("changed", 5); + layout_menu->marker_visible = false; + layout_menu->disableMenu(); + OnRender(); + std::stringstream ss; + ss << std::setw(3) << std::setfill('0') << layout_menu->getCurrentId(); + std::string s = ss.str(); + serializeHouse(s); + takeScreenshot("gamedata/house/preview/SAV" + s, 120, 120); + status = Game::RUNNING; + + } + else if (layout_menu->controls[1].IsIn(x, y)){ + sounds.playSFX("click", 5); + layout_menu->setViewPage(layout_menu->current_page - 1, renderer); + layout_menu->marker_visible = false; + layout_menu->controls[3].setEnable(false); + } + else if (layout_menu->controls[0].IsIn(x, y)){ + sounds.playSFX("click", 5); + layout_menu->setViewPage(layout_menu->current_page + 1, renderer); + layout_menu->marker_visible = false; + layout_menu->controls[3].setEnable(false); + } + else{ + //item selector + for (widgets::button_container::iterator it = layout_menu->slots.begin(); it != layout_menu->slots.end(); ++it){ + if (it->IsIn(x, y)){ + layout_menu->setCurrentId(it->getId()); + layout_menu->marker_rect.x = it->getX(); + layout_menu->marker_rect.y = it->getY(); + layout_menu->marker_visible = true; + layout_menu->controls[3].setEnable(true); + } + } + } //food + } + + else if (status == Game::LAYOUT_LOAD_MENU){ + + if (layout_menu->controls[2].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::RUNNING; + layout_menu->marker_visible = false; + layout_menu->disableMenu(); + } + else if (layout_menu->controls[3].IsIn(x, y)){ + sounds.playSFX("click", 5);; + sounds.playSFX("changed", 5); + layout_menu->marker_visible = false; + std::stringstream ss; + ss << std::setw(3) << std::setfill('0') << layout_menu->getCurrentId(); + std::string s = ss.str(); + std::cerr << "string: " << s << std::endl; + deserializeHouse(s); + serializeHouse("DEFAULT");//update default + layout_menu->disableMenu(); + status = Game::RUNNING; + } + + else if (layout_menu->controls[1].IsIn(x, y)){ + sounds.playSFX("click", 5); + layout_menu->setViewPage(layout_menu->current_page - 1, renderer); + layout_menu->marker_visible = false; + layout_menu->controls[3].setEnable(false); + } + else if (layout_menu->controls[0].IsIn(x, y)){ + sounds.playSFX("click", 5); + layout_menu->setViewPage(layout_menu->current_page + 1, renderer); + layout_menu->marker_visible = false; + layout_menu->controls[3].setEnable(false); + } + else{ + //item selector + for (widgets::button_container::iterator it = layout_menu->slots.begin(); it != layout_menu->slots.end(); ++it){ + if (it->IsIn(x, y)){ + layout_menu->setCurrentId(it->getId()); + layout_menu->marker_rect.x = it->getX(); + layout_menu->marker_rect.y = it->getY(); + layout_menu->marker_visible = true; + layout_menu->controls[3].setEnable(true); + } + } + } + } + + else if (status == Game::FRIEND_INVITE_MENU){ + if (friends_menu->controls[2].IsIn(x, y)){ + sounds.playSFX("click", 5); + status = Game::RUNNING; + friends_menu->marker_visible = false; + friends_menu->disableMenu(); + } + else if (friends_menu->controls[3].IsIn(x, y)){ + sounds.playSFX("click", 5);; + sounds.playSFX("changed", 5); + friends_menu->marker_visible = false; + deserializePlayer(friends_menu->getCurrentPath(), -1); + friends_menu->disableMenu(); + status = Game::RUNNING; + + } + else if (friends_menu->controls[1].IsIn(x, y)){ + sounds.playSFX("click", 5); + friends_menu->setViewPage(friends_menu->current_page - 1, renderer); + friends_menu->marker_visible = false; + friends_menu->controls[3].setEnable(false); + } + else if (friends_menu->controls[0].IsIn(x, y)){ + sounds.playSFX("click", 5); + friends_menu->setViewPage(friends_menu->current_page + 1, renderer); + friends_menu->marker_visible = false; + friends_menu->controls[3].setEnable(false); + } + else{ + //item selector + for (widgets::button_container::iterator it = friends_menu->slots.begin(); it != friends_menu->slots.end(); ++it){ + if (it->IsIn(x, y)){ + if (it->getEnable()){ + std::cerr << it->getEnable() << std::endl; + friends_menu->setCurrentId(it->getId()); + friends_menu->setCurrentString(it - friends_menu->slots.begin()); + friends_menu->marker_rect.x = it->getX(); + friends_menu->marker_rect.y = it->getY(); + friends_menu->marker_visible = true; + friends_menu->controls[3].setEnable(true); + + } + + } + } + } + //food + } + else if (status == Game::EDIT_MODE){ + //return button + if (return_button->IsIn(x, y)){ + if (return_button->getEnable()){ + sounds.playSFX("click", 5); + status = Game::RUNNING; + return_button->setEnable(false); + return_button->setVisible(false); + message_screen->visible = false; + message_screen->locked = false; + OnRender(); + serializeHouse("DEFAULT"); + + } + } + if (edit_holding == false){ + for (unsigned int i = 0; i < objects_list.size(); ++i){ + if (objects_list[i].IsIn(x, y)){ + object_index = i; + edit_holding = true; + SDL_ShowCursor(0); + } + } + } + else if (edit_holding == true){ + SDL_ShowCursor(1); + edit_holding = false; + } + } + +/* else if (status == Game::ACCESSORY_MODE){ + //return button + if (return_button->IsIn(x, y)){ + if (return_button->getEnable()){ + //change to relative values + for (std::vector::iterator i = megu_list.begin()->second.accessories_list.begin(); i != megu_list.begin()->second.accessories_list.end(); ++i){ + i->offset.x = i->rectangle.x - megu_list.begin()->second.position.x; + i->offset.y = i->rectangle.y - megu_list.begin()->second.position.y; + i->offset_side = i->side; + } + sounds.playSFX("click", 5); + + return_button->setEnable(false); + return_button->setVisible(false); + message_screen->visible = false; + message_screen->locked = false; + serializePlayer("gamedata/friends/player.megu", megu_list.begin()->second); + status = Game::RUNNING; + } + } + if (edit_holding == false){ + if (!megu_list.begin()->second.accessories_list.empty()){ + for (unsigned int i = 0; i < megu_list.begin()->second.accessories_list.size(); ++i){ + if (megu_list.begin()->second.accessories_list[i].IsIn(x, y)){ + megu_list.begin()->second.accessory_index = i; + edit_holding = true; + SDL_ShowCursor(0); + } + } + } + } + else if (edit_holding == true){ + SDL_ShowCursor(1); + edit_holding = false; + } + else{ + //do nothing + } + }*/ + break; + + case SDL_MOUSEMOTION: + if (status == Game::EDIT_MODE){ + if (edit_holding == true){ + objects_list[object_index].rectangle.x = x - objects_list[object_index].rectangle.w / 2; + objects_list[object_index].rectangle.y = y - objects_list[object_index].rectangle.h / 2; + + if (objects_list[object_index].rectangle.y > clickable_area.y + clickable_area.h)//boundary + objects_list[object_index].rectangle.y = clickable_area.y + clickable_area.h; + + } + } + /* + else if (status == Game::ACCESSORY_MODE){ + if (edit_holding == true){ + + megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].rectangle.x = x - megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].rectangle.w / 2; + megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].rectangle.y = y - megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].rectangle.h / 2; + + if (megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].rectangle.y > clickable_area.y + clickable_area.h)//boundary + megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].rectangle.y = clickable_area.y + clickable_area.h; + } + }*/ + else{ + for (std::map::iterator sprite_it = megu_list.begin(); sprite_it != megu_list.end(); ++sprite_it){ + if (sprite_it->second.pet_flag == true){ + ++sprite_it->second.pet_timer; + } + } + } + break; + case SDL_MOUSEBUTTONUP: + for (std::map::iterator sprite_it = megu_list.begin(); sprite_it != megu_list.end(); ++sprite_it){ + sprite_it->second.pet_flag = false; + sprite_it->second.pet_timer = 0; + } + break; + case SDL_KEYDOWN: + if (status == Game::EDIT_MODE){ + if (edit_holding == true){ + if (e->key.keysym.scancode == SDL_SCANCODE_DELETE){ + objects_list.erase(objects_list.begin() + object_index); + object_index = -1; + edit_holding = false; + } + if (e->key.keysym.scancode == SDL_SCANCODE_BACKSPACE){ + + if (objects_list[object_index].side == SDL_FLIP_HORIZONTAL) + objects_list[object_index].side = SDL_FLIP_NONE; + else if (objects_list[object_index].side == SDL_FLIP_NONE) + objects_list[object_index].side = SDL_FLIP_HORIZONTAL; + } + if (e->key.keysym.scancode == SDL_SCANCODE_PAGEDOWN){ + + if (objects_list.size() != 1){ + if (object_index != 0){ + + --objects_list[object_index].render_id; + ++objects_list[object_index - 1].render_id; + std::sort(objects_list.begin(), objects_list.end(), sortobjects); + --object_index; + } + } + } + if (e->key.keysym.scancode == SDL_SCANCODE_PAGEUP){ + if (objects_list.size() != 1){ + if (object_index != objects_list.size() - 1){ + ++objects_list[object_index].render_id; + --objects_list[object_index + 1].render_id; + std::sort(objects_list.begin(), objects_list.end(), sortobjects); + ++object_index; + } + } + } + if (e->key.keysym.scancode == SDL_SCANCODE_END){ + if (objects_list.size() != 1){ + if (object_index != 0){ + + for (unsigned int i = 0; i < object_index; ++i){ + ++objects_list[i].render_id;//remove gap + } + objects_list[object_index].render_id = 1; + std::sort(objects_list.begin(), objects_list.end(), sortobjects); + object_index = 0; + } + } + } + if (e->key.keysym.scancode == SDL_SCANCODE_HOME){ + if (objects_list.size() != 1){ + if (object_index != objects_list.size() - 1){ + for (unsigned int i = object_index + 1; i < objects_list.size(); ++i){ + --objects_list[i].render_id;//remove gap + } + objects_list[object_index].render_id = objects_list.size(); + std::sort(objects_list.begin(), objects_list.end(), sortobjects); + object_index = objects_list.size() - 1; + } + } + } + } + } + +/* else if (status == Game::ACCESSORY_MODE){ + if (edit_holding == true){ + if (e->key.keysym.scancode == SDL_SCANCODE_DELETE){ + megu_list.begin()->second.accessories_list.erase(megu_list.begin()->second.accessories_list.begin() + megu_list.begin()->second.accessory_index); + megu_list.begin()->second.accessory_index = -1; + edit_holding = false; + } + if (e->key.keysym.scancode == SDL_SCANCODE_BACKSPACE){ + + if (megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].side == SDL_FLIP_HORIZONTAL) + megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].side = SDL_FLIP_NONE; + else if (megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].side == SDL_FLIP_NONE) + megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].side = SDL_FLIP_HORIZONTAL; + } + + if (e->key.keysym.scancode == SDL_SCANCODE_PAGEDOWN){ + + if (megu_list.begin()->second.accessories_list.size() != 1){ + if (megu_list.begin()->second.accessory_index != 0){ + + --megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].render_id; + ++megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index - 1].render_id; + std::sort(megu_list.begin()->second.accessories_list.begin(), megu_list.begin()->second.accessories_list.end(), sortobjects); + --megu_list.begin()->second.accessory_index; + } + } + } + if (e->key.keysym.scancode == SDL_SCANCODE_PAGEUP){ + if (megu_list.begin()->second.accessories_list.size() != 1){ + if (megu_list.begin()->second.accessory_index != megu_list.begin()->second.accessories_list.size() - 1){ + ++megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].render_id; + --megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index + 1].render_id; + std::sort(megu_list.begin()->second.accessories_list.begin(), megu_list.begin()->second.accessories_list.end(), sortobjects); + ++megu_list.begin()->second.accessory_index; + } + } + } + if (e->key.keysym.scancode == SDL_SCANCODE_END){ + if (megu_list.begin()->second.accessories_list.size() != 1){ + if (megu_list.begin()->second.accessory_index != 0){ + for (unsigned int i = 0; i < megu_list.begin()->second.accessory_index; ++i){ + ++megu_list.begin()->second.accessories_list[i].render_id;//remove gap + } + megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].render_id = 1; + std::sort(megu_list.begin()->second.accessories_list.begin(), megu_list.begin()->second.accessories_list.end(), sortobjects); + megu_list.begin()->second.accessory_index = 0; + } + } + } + if (e->key.keysym.scancode == SDL_SCANCODE_HOME){ + if (megu_list.begin()->second.accessories_list.size() != 1){ + if (megu_list.begin()->second.accessory_index != megu_list.begin()->second.accessories_list.size() - 1){ + for (unsigned int i = megu_list.begin()->second.accessory_index + 1; i < megu_list.begin()->second.accessories_list.size(); ++i){ + --megu_list.begin()->second.accessories_list[i].render_id;//remove gap + } + megu_list.begin()->second.accessories_list[megu_list.begin()->second.accessory_index].render_id = megu_list.begin()->second.accessories_list.size(); + std::sort(megu_list.begin()->second.accessories_list.begin(), megu_list.begin()->second.accessories_list.end(), sortobjects); + megu_list.begin()->second.accessory_index = megu_list.begin()->second.accessories_list.size() - 1; + } + } + } + } + }*/ + else{ + if (status == Game::RUNNING){ + if (e->key.keysym.scancode == SDL_SCANCODE_TAB){ + takeScreenshot("img", 640, 640); + } + } + } + break; + } +} + +void MeguEngine::foodAnimationCallback(const PLAYER_ID &player){ + megu_list[player].blink = Megu::NONE; + megu_list[player].state = Megu::VERY_HAPPY; + int last_time = 0; + int current_time = 0; + int diff_time = 0; + int animation_delay = 1000; + sounds.playSFX("food", 5); + while (diff_time < animation_delay){ + curr_time = SDL_GetTicks(); + diff_time += curr_time - last_time; + last_time = curr_time; + } + + switch (megu_list[player].size){ + case 1: + { + sounds.playSFX("happy1", player); + break; + } + case 2: + { + sounds.playSFX("happy2", player); + break; + } + case 3: + { + sounds.playSFX("happy3", player); + break; + } + } +} + +void MeguEngine::food_mode(const int &ID){ + int nplayers = megu_list.size(); + kit.food.push_back(*library.food_lib[ID].texture.begin()); + kit.visible = true; + for (std::map::iterator it = megu_list.begin(); it != megu_list.end(); ++it){ + it->second.state = Megu::WALK_ONE; + it->second.blink = Megu::NONE; + + it->second.run_flag = true; + if (it->first % 2){ + SetMeguDestination(it->first, kit.rect_t.x + kit.even_megu.x, kit.rect_t.y + kit.even_megu.y); + } + else{ + SetMeguDestination(it->first, kit.rect_t.x + kit.odd_megu.y, kit.rect_t.y + kit.odd_megu.y); + } + } +} + +bool MeguEngine::updateBackground(const int &id){ + house_id = id; + if (house != NULL){ + SDL_DestroyTexture(house); + } + std::string path("assets/Houses/ID" + std::to_string(house_id) + "@2x.png"); + house = loadTexture(path); + if (house == NULL){ + std::cerr << "Error Loading Background" << std::endl; + return false; + } + return true; +} + +SDL_Texture* MeguEngine::loadTexture(std::string path) +{ + //The final texture + SDL_Texture* newTexture = NULL; + + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + + return newTexture; +} + +void MeguEngine::LoadMegu(const int &new_megu_id, const PLAYER_ID &player){ + if (megu_list.find(player) != megu_list.end()){ + for (int i = 0; i < 11; ++i) + SDL_DestroyTexture(megu_list[player].sprites[i]); + } + std::string suffix; + if (mini){ + suffix = ".png"; + } + else{ + suffix = "@2x.png"; + } + for (int i = 0; i < 11; ++i){ + megu_list[player].sprites[i] = loadTexture("assets/megu/ID" + std::to_string(new_megu_id) + "_" + std::to_string(i + 3) + suffix); + } + std::string path = "assets//megu//ID" + std::to_string(new_megu_id) + "_" + std::to_string(3) + suffix; + std::cerr << path << std::endl; + megu_list[player].pet_race = library.megu_lib[new_megu_id].en_name; + megu_list[player].id = new_megu_id; + megu_list[player].shadow = loadTexture(shadow_texture); + megu_list[player].size = library.megu_lib[new_megu_id].size; + megu_list[player].position.x = megu_size.x; + megu_list[player].position.y = megu_size.y; + megu_list[player].destination.x = megu_list[player].position.x; + megu_list[player].destination.y = megu_list[player].position.y; + megu_list[player].position.h = megu_size.h; + megu_list[player].position.w = megu_size.w; + megu_list[player].side = SDL_FLIP_NONE; + megu_list[player].state = Megu::STOP_ONE; + megu_list[player].blink = Megu::NONE; + SDL_SetTextureAlphaMod(megu_list[player].shadow, 46); + megu_list[player].shadow_pos.x = megu_list[player].position.x + shadow_pos.x; + megu_list[player].shadow_pos.y = megu_list[player].position.y + shadow_pos.y; + megu_list[player].shadow_pos.h = shadow_pos.h; + megu_list[player].shadow_pos.w = shadow_pos.w; + + +} +void MeguEngine::SetMeguPos(const PLAYER_ID &player, const int &x, const int &y, const SDL_RendererFlip &side){ + megu_list[player].position.x = x; + megu_list[player].position.y = y; + megu_list[player].side = side; + megu_list[player].shadow_pos.x = x + shadow_pos.x;// +shadow_pos.x; + megu_list[player].shadow_pos.y = y + shadow_pos.y;// + shadow_pos.y; + megu_list[player].shadow_pos.h = shadow_pos.h; + megu_list[player].shadow_pos.w = shadow_pos.w; + + +} + +void MeguEngine::SetMeguState(const PLAYER_ID &player, const Megu::MEGU_STATE &new_state, const Megu::MEGU_EYE &eye_state){ + megu_list[player].state = new_state; + megu_list[player].blink = eye_state; +} + +void MeguEngine::OnEvent(SDL_Event* Event) { + handleMouseEvent(Event); + if (Event->type == SDL_QUIT){ + Running = false; + } +} + +void MeguEngine::getConstrainedMovement(const int &wx, const int &wy, int &out_wx, int &out_wy){ + if (wy > clickable_area.h + clickable_area.y - megu_size.h) + out_wy = clickable_area.h + clickable_area.y - megu_size.h; + else if (wy < clickable_area.y - megu_size.h) + out_wy = clickable_area.y; + else{ + out_wy = wy; + } + if (wx < clickable_area.x + megu_size.w/2) + out_wx = clickable_area.x; + else if (wx > clickable_area.x + clickable_area.w - megu_size.w/2) + out_wx = clickable_area.x + clickable_area.w - megu_size.w/2; + else{ + out_wx = wx; + } +} + +void MeguEngine::MeguStateMachine(){ + //get timers + if (status == Game::RUNNING || status == Game::FEEDING){ + curr_time = SDL_GetTicks(); + uint32_t diff_time = curr_time - last_time;//calculate diff + msg_time += diff_time; + for (std::vector::iterator obj_it = objects_list.begin(); obj_it != objects_list.end(); ++obj_it){ + if (obj_it->animation_order.size() > 0){//if animated + obj_it->current_time += diff_time; //increment time + if (obj_it->current_time > obj_it->animation_interval){ //if transitioning texture + obj_it->current_time = 0; //zero timer + ++obj_it->current_frame; //move to next frame + if (obj_it->current_frame > obj_it->animation_order.size()){//return to begin + obj_it->current_frame = 0; + + } + } + } + } + + for (std::map::iterator sprite_it = megu_list.begin(); sprite_it != megu_list.end(); ++sprite_it){ + std::uniform_int_distribution distribution(1, 36); + msg_time += diff_time; + sprite_it->second.blink_timer += diff_time; + sprite_it->second.animation_timer += diff_time; + sprite_it->second.random_action_timer += diff_time + distribution(sprite_it->second.generator); + //petting flag on, hovering + if (sprite_it->second.pet_flag){ + if (sprite_it->second.pet_timer > megu_pet_counter){ + sprite_it->second.pet_timer = 0; + if (sprite_it->second.pet_counting < 8){ + sprite_it->second.state = Megu::HAPPY; + ++sprite_it->second.pet_counting; + sprite_it->second.run_flag = false; + sounds.playSFX("pet", sprite_it->first); + if (sprite_it->second.pet_counting % 3 == 0){ + std::uniform_int_distribution pet_distrib(0, 11); + std::string msg = sprite_it->second.pet_name + pet_message_list[pet_distrib(sprite_it->second.generator)]; + message_screen->addMessage(msg); + message_screen->visible = true; + message_screen->setTimeOut(3000); + message_screen->setTimer(0); + } + } + else{ + sprite_it->second.state = Megu::VERY_HAPPY; + sprite_it->second.pet_counting = 0; + switch (sprite_it->second.size){ + case 1: + { + sounds.playSFX("happy1", sprite_it->first); + break; + } + case 2: + { + sounds.playSFX("happy2", sprite_it->first); + break; + } + case 3: + { + sounds.playSFX("happy3", sprite_it->first); + break; + } + } + std::uniform_int_distribution pet_distrib(0, 11); + std::string msg = sprite_it->second.pet_name + pet_message_list[pet_distrib(sprite_it->second.generator)]; + message_screen->addMessage(msg); + message_screen->visible = true; + message_screen->setTimeOut(5000); + message_screen->setTimer(0); + } + + sprite_it->second.blink = Megu::NONE; + sprite_it->second.animation_timer = 0; + sprite_it->second.misc_timer = 0; + sprite_it->second.destination.x = sprite_it->second.position.x; + sprite_it->second.destination.y = sprite_it->second.position.y; + } + } + //blink eye trigger + if (sprite_it->second.state == Megu::STOP_ONE || + sprite_it->second.state == Megu::STOP_TWO){ + if (sprite_it->second.blink_timer > megu_blink_counter){ + sprite_it->second.blink_timer -= megu_blink_counter; + sprite_it->second.blink = Megu::BLINK; + sprite_it->second.blink_openeye = 0; + } + //open eye blink + if (sprite_it->second.blink == Megu::BLINK){ + sprite_it->second.blink_openeye += curr_time - last_time; + uint32_t diff_time = curr_time - last_time; + if (sprite_it->second.blink_openeye > megu_openeye_counter){ + sprite_it->second.blink_openeye = 0; + sprite_it->second.blink = Megu::OPEN; + } + } + } + //animation switching + unsigned int animation_time = megu_animation_counter; + if (sprite_it->second.run_flag){ + animation_time /= 8; + } + //animation switching + if (sprite_it->second.animation_timer > animation_time) + { + sprite_it->second.animation_timer = 0; + switch (sprite_it->second.state){ + case Megu::WALK_ONE: + if (sprite_it->second.position.x == sprite_it->second.destination.x && //get to destination, end animation cycle + sprite_it->second.position.y == sprite_it->second.destination.y){ + sprite_it->second.run_flag = false; + sprite_it->second.state = Megu::STOP_ONE; + sprite_it->second.blink = Megu::OPEN; + sprite_it->second.blink_timer = 0; + } + else{ + sprite_it->second.state = Megu::WALK_TWO; + MeguPositionHandler(sprite_it->first); + } + break; + case Megu::WALK_TWO: + if (sprite_it->second.position.x == sprite_it->second.destination.x && //get to destination, end animation cycle + sprite_it->second.position.y == sprite_it->second.destination.y){ + sprite_it->second.run_flag = false; + sprite_it->second.state = Megu::STOP_ONE; + sprite_it->second.blink = Megu::OPEN; + sprite_it->second.blink_timer = 0; + } + else{ + sprite_it->second.state = Megu::WALK_ONE; + MeguPositionHandler(sprite_it->first); + } + break; + case Megu::STOP_ONE: + + sprite_it->second.state = Megu::STOP_TWO; + break; + + case Megu::STOP_TWO: + //blink eye trigger + if (sprite_it->second.blink_timer > megu_blink_counter){ + sprite_it->second.blink_timer -= megu_blink_counter; + sprite_it->second.blink = Megu::BLINK; + sprite_it->second.blink_openeye = 0; + } + //open eye blink + if (sprite_it->second.blink == Megu::BLINK){ + sprite_it->second.blink_openeye += curr_time - last_time; + uint32_t diff_time = curr_time - last_time; + if (sprite_it->second.blink_openeye > megu_openeye_counter){ + sprite_it->second.blink_openeye = 0; + sprite_it->second.blink = Megu::OPEN; + } + } + sprite_it->second.state = Megu::STOP_ONE; + break; + } + } + if (sprite_it->second.state == Megu::AFRAID || + sprite_it->second.state == Megu::HAPPY || + sprite_it->second.state == Megu::SCARED || + sprite_it->second.state == Megu::THINKING + ){ + sprite_it->second.misc_timer += diff_time; + if (sprite_it->second.misc_timer > megu_misc_counter){ + sprite_it->second.misc_timer = 0; + sprite_it->second.state = Megu::STOP_ONE; + sprite_it->second.blink = Megu::OPEN; + } + } + if (sprite_it->second.state == Megu::VERY_HAPPY){ + sprite_it->second.misc_timer += diff_time; + if (sprite_it->second.misc_timer > megu_misc_counter * 2){ + sprite_it->second.misc_timer = 0; + sprite_it->second.state = Megu::STOP_ONE; + sprite_it->second.blink = Megu::OPEN; + } + } + + if (status == Game::FEEDING){ + if (sprite_it->second.state == Megu::STOP_ONE || sprite_it->second.state == Megu::STOP_TWO){ + foodAnimationCallback(sprite_it->first); + ++player_counter; + if (player_counter == megu_list.size()){ + player_counter = 0; + status = Game::RUNNING; + kit.destroy_food_kit(); + sounds.playSFX("food", 5); + + } + } + } + if (sprite_it->second.random_action_timer > megu_event_action){ + sprite_it->second.random_action_timer -= megu_event_action; + sprite_it->second.random_action_timer += distribution(sprite_it->second.generator) * 500; + if (sprite_it->second.state == Megu::STOP_ONE || sprite_it->second.state == Megu::STOP_TWO){ + //random events + int w_x = 0; + int w_y = 0; + switch (distribution(sprite_it->second.generator)){ + case 1: + { + sprite_it->second.state = Megu::HAPPY; + sprite_it->second.blink = Megu::NONE; + sprite_it->second.run_flag = false; + sounds.playSFX("megu" + std::to_string(distribution(sprite_it->second.generator)), sprite_it->first); + break; + } + case 2: + { + sprite_it->second.state = Megu::HAPPY; + sprite_it->second.blink = Megu::NONE; + sprite_it->second.run_flag = false; + sounds.playSFX("megu" + std::to_string(distribution(sprite_it->second.generator)), sprite_it->first); + break; + } + case 3: + { + sprite_it->second.state = Megu::THINKING; + sprite_it->second.blink = Megu::NONE; + sprite_it->second.run_flag = false; + sounds.playSFX("megu" + std::to_string(distribution(sprite_it->second.generator)), sprite_it->first); + break; + } + case 4: + { + sprite_it->second.state = Megu::HAPPY; + sprite_it->second.blink = Megu::NONE; + sprite_it->second.run_flag = true; + sounds.playSFX("megu" + std::to_string(distribution(sprite_it->second.generator)), sprite_it->first); + break; + } + case 5: + { + sprite_it->second.state = Megu::HAPPY; + sprite_it->second.blink = Megu::NONE; + sprite_it->second.run_flag = false; + sounds.playSFX("megu" + std::to_string(distribution(sprite_it->second.generator)), sprite_it->first); + break; + } + case 6: + { + sprite_it->second.state = Megu::VERY_HAPPY; + sprite_it->second.blink = Megu::NONE; + sprite_it->second.run_flag = false; + sounds.playSFX("megu" + std::to_string(distribution(sprite_it->second.generator)), sprite_it->first); + break; + } + case 7: + { + sprite_it->second.state = Megu::STOP_ONE; + sprite_it->second.blink = Megu::OPEN; + sprite_it->second.run_flag = false; + sounds.playSFX("megu" + std::to_string(distribution(sprite_it->second.generator)), sprite_it->first); + break; + } + case 8: + { + sprite_it->second.blink = Megu::OPEN; + sprite_it->second.state = Megu::STOP_ONE; + sprite_it->second.run_flag = false; + sounds.playSFX("megu" + std::to_string(distribution(sprite_it->second.generator)), sprite_it->first); + break; + } + case 9: + { + sprite_it->second.state = Megu::STOP_ONE; + sprite_it->second.blink = Megu::OPEN; + sprite_it->second.run_flag = true; + sounds.playSFX("megu" + std::to_string(distribution(sprite_it->second.generator)), sprite_it->first); + break; + } + case 10: + { + sprite_it->second.state = Megu::STOP_ONE; + sprite_it->second.blink = Megu::OPEN; + sprite_it->second.run_flag = true; + sounds.playSFX("megu" + std::to_string(distribution(sprite_it->second.generator)), sprite_it->first); + break; + } + case 11:{ + w_x = sprite_it->second.position.x + 10 * distribution(sprite_it->second.generator); + w_y = sprite_it->second.position.y; + + sprite_it->second.destination.x = w_x; + sprite_it->second.destination.y = w_y; + sprite_it->second.blink = Megu::NONE; + sprite_it->second.state = Megu::WALK_ONE; + break; + } + case 12:{ + w_x = sprite_it->second.position.x + 5 * distribution(sprite_it->second.generator); + w_y = sprite_it->second.position.y + 5 * distribution(sprite_it->second.generator); + getConstrainedMovement(w_x, w_y, sprite_it->second.destination.x, sprite_it->second.destination.y); + sprite_it->second.blink = Megu::NONE; + sprite_it->second.state = Megu::WALK_ONE; + break; + } + case 13:{ + w_x = sprite_it->second.position.x; + w_y = sprite_it->second.position.y + 10 * distribution(sprite_it->second.generator); + getConstrainedMovement(w_x, w_y, sprite_it->second.destination.x, sprite_it->second.destination.y); + sprite_it->second.blink = Megu::NONE; + sprite_it->second.state = Megu::WALK_ONE; + break; + } + case 14:{ + w_x = sprite_it->second.position.x - 5 * distribution(sprite_it->second.generator); + w_y = sprite_it->second.position.y + 5 * distribution(sprite_it->second.generator); + getConstrainedMovement(w_x, w_y, sprite_it->second.destination.x, sprite_it->second.destination.y); + sprite_it->second.blink = Megu::NONE; + sprite_it->second.state = Megu::WALK_ONE; + break; + } + case 15:{ + w_x = sprite_it->second.position.x - 10 * distribution(sprite_it->second.generator); + w_y = sprite_it->second.position.y; + getConstrainedMovement(w_x, w_y, sprite_it->second.destination.x, sprite_it->second.destination.y); + sprite_it->second.blink = Megu::NONE; + sprite_it->second.state = Megu::WALK_ONE; + break; + } + case 16:{ + w_x = sprite_it->second.position.x - 5 * distribution(sprite_it->second.generator); + w_y = sprite_it->second.position.y - 5 * distribution(sprite_it->second.generator); + getConstrainedMovement(w_x, w_y, sprite_it->second.destination.x, sprite_it->second.destination.y); + sprite_it->second.blink = Megu::NONE; + sprite_it->second.state = Megu::WALK_ONE; + break; + } + case 17:{ + w_x = sprite_it->second.position.x; + w_y = sprite_it->second.position.y - 10 * distribution(sprite_it->second.generator); + getConstrainedMovement(w_x, w_y, sprite_it->second.destination.x, sprite_it->second.destination.y); + sprite_it->second.blink = Megu::NONE; + sprite_it->second.state = Megu::WALK_ONE; + break; + } + case 18:{ + w_x = sprite_it->second.position.x + 5 * distribution(sprite_it->second.generator); + w_y = sprite_it->second.position.y - 5 * distribution(sprite_it->second.generator); + getConstrainedMovement(w_x, w_y, sprite_it->second.destination.x, sprite_it->second.destination.y); + sprite_it->second.blink = Megu::NONE; + sprite_it->second.state = Megu::WALK_ONE; + break; + } + } + } + } + } + last_time = curr_time; + //message timer + if (!message_screen->locked){ + if (message_screen->visible){ + if (message_screen->getTimer() < message_screen->getTimeout()){ + message_screen->setTimer(message_screen->getTimer() + diff_time); + } + else if (message_screen->getTimer() >= message_screen->getTimeout()){ + message_screen->visible = false; + message_screen->setTimer(0); + message_screen->setTimeOut(0); + } + } + if (msg_time > megu_msg_counter){ + msg_time = 0; + std::uniform_int_distribution distribution(0, random_message_list.size()-1); + message_screen->addMessage(random_message_list[distribution(megu_list.begin()->second.generator)]); + message_screen->setTimeOut(5000); + message_screen->setTimer(0); + message_screen->visible = true; + } + } + } +} +void MeguEngine::OnRender() { + mutex = SDL_CreateMutex(); + if (SDL_LockMutex(mutex) == 0){ + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, house, 0, &menu_background_pos); + for (std::vector::iterator obj_it = objects_list.begin(); obj_it != objects_list.end(); ++obj_it){ + SDL_RenderCopyEx(renderer, obj_it->textures.at(obj_it->current_frame), NULL, &obj_it->rectangle, 0, 0, obj_it->side); + } + /* if (status == Game::ACCESSORY_MODE){ + SDL_RenderCopyEx(renderer, megu_list.begin()->second.sprites[2], NULL, &megu_list.begin()->second.position, 0, 0, megu_list.begin()->second.side); + SDL_RenderCopyEx(renderer, megu_list.begin()->second.sprites[4], NULL, &megu_list.begin()->second.position, 0, 0, megu_list.begin()->second.side); + for (std::vector::iterator obj_it = megu_list.begin()->second.accessories_list.begin(); obj_it != megu_list.begin()->second.accessories_list.end(); ++obj_it){ + SDL_RenderCopyEx(renderer, obj_it->textures.at(0), NULL, &obj_it->rectangle, 0, 0, obj_it->side); + } + }*/ + if (status == Game::EDIT_MODE && status == Game::NAME_MENU){ + } + else if (status == Game::RUNNING || status == Game::FEEDING){ + for (std::vector::iterator player_it = render_order.begin(); player_it != render_order.end(); ++player_it){ + SDL_RenderCopy(renderer, megu_list[player_it->player].shadow, NULL, &megu_list[player_it->player].shadow_pos); + SDL_RenderCopyEx(renderer, megu_list[player_it->player].sprites[megu_list[player_it->player].state], NULL, &megu_list[player_it->player].position, 0, 0, megu_list[player_it->player].side); + if (megu_list[player_it->player].blink != Megu::NONE){ + SDL_RenderCopyEx(renderer, megu_list[player_it->player].sprites[megu_list[player_it->player].blink], NULL, &megu_list[player_it->player].position, 0, 0, megu_list[player_it->player].side); + } + for (std::vector::iterator obj_it = megu_list[player_it->player].accessories_list.begin(); obj_it != megu_list[player_it->player].accessories_list.end(); ++obj_it){ + obj_it->rectangle.x = megu_list[player_it->player].position.x; + if (megu_list[player_it->player].side == SDL_FLIP_NONE){ + obj_it->rectangle.x += obj_it->offset.x; + if (obj_it->offset_side == SDL_FLIP_NONE){ + obj_it->side = SDL_FLIP_NONE; + } + else{ + obj_it->side = SDL_FLIP_HORIZONTAL; + } + } + else{ + obj_it->rectangle.x += (megu_list[player_it->player].position.w - obj_it->offset.x - obj_it->rectangle.w); + if (obj_it->offset_side == SDL_FLIP_HORIZONTAL){ + obj_it->side = SDL_FLIP_NONE; + } + else{ + obj_it->side = SDL_FLIP_HORIZONTAL; + } + } + obj_it->rectangle.y = obj_it->offset.y + megu_list[player_it->player].position.y; + SDL_RenderCopyEx(renderer, obj_it->textures.at(0), NULL, &obj_it->rectangle, 0, 0, obj_it->side); + } + } + } + if (kit.visible){ + SDL_RenderCopy(renderer, kit.table_shadow, NULL, &kit.rect_s); + SDL_RenderCopy(renderer, kit.table, NULL, &kit.rect_t); + for (int i = 0; i < kit.food.size(); ++i){ + SDL_RenderCopy(renderer, kit.food.at(i), NULL, &kit.rect_f); + } + } + SDL_RenderCopy(renderer, menu_bar, 0, &menu_bar_pos); + for (std::vector::iterator it = ui_texts.begin(); it != ui_texts.end(); ++it){ + it->Render(renderer); + } + return_button->Render(renderer); + care_button->Render(renderer); + edit_button->Render(renderer); + option_button->Render(renderer); + food_menu->Render(renderer); + food_menu->RenderButtons(renderer); + furniture_menu->Render(renderer); + furniture_menu->RenderButtons(renderer); + pet_menu->Render(renderer); + pet_menu->RenderButtons(renderer); + house_menu->Render(renderer); + house_menu->RenderButtons(renderer); + friends_menu->Render(renderer); + friends_menu->RenderButtons(renderer); + layout_menu->Render(renderer); + layout_menu->RenderButtons(renderer); + care_menu->Render(renderer); + edit_menu->Render(renderer); + name_menu->Render(renderer); + options_menu->Render(renderer); + message_screen->Render(renderer); + // accessory_menu->Render(renderer); + + for (std::map::iterator it = megu_list.begin(); it != megu_list.end(); ++it){ + if (it->second.pet_flag){ + SDL_ShowCursor(0); + SDL_Rect m_pos; + m_pos.h = 120; + m_pos.w = 120; + if (mini){ + m_pos.h /= 2; + m_pos.w /= 2; + } + SDL_GetMouseState(&m_pos.x, &m_pos.y); + m_pos.x -= m_pos.w / 2; + m_pos.y -= m_pos.h / 2; + SDL_RenderCopy(renderer, mouse_cursor, NULL, &m_pos); + break; + } + else{ + SDL_ShowCursor(1); + } + } + SDL_RenderPresent(renderer); + SDL_DestroyMutex(mutex); + } + else { + std::cerr << "could not lock mutex " << std::endl; + } + +} +void MeguEngine::OnLoop() { + //while (Running){ + MeguStateMachine(); + // } + // kill_thread(); +} +void MeguEngine::OnCleanup() { + SDL_Quit(); +} +void MeguEngine::SetMeguDestination(const PLAYER_ID &player, const int &x, const int &y){ + megu_list[player].destination.x = x; + megu_list[player].destination.y = y; +} +void MeguEngine::MeguClickScene(const PLAYER_ID &player, const int &x, const int&y) +{ + SetMeguDestination(player, x, y); + megu_list[player].state = Megu::WALK_ONE; + megu_list[player].blink = Megu::NONE; +} +void MeguEngine::MeguPositionHandler(const PLAYER_ID &player){ + + //set model side + SDL_RendererFlip side; + if (megu_list[player].position.x < megu_list[player].destination.x) + side = SDL_FLIP_HORIZONTAL; + else + side = SDL_FLIP_NONE; + //total distance + double dist = sqrt(pow(megu_list[player].position.x - megu_list[player].destination.x, 2) + pow(megu_list[player].position.y - megu_list[player].destination.y, 2)); + //distance components x and y + double addx; + double addy; + //calculate decomposed distance x velocity + addx = megu_spd*(megu_list[player].destination.x - megu_list[player].position.x) / dist; + addy = megu_spd*(megu_list[player].destination.y - megu_list[player].position.y) / dist; + //if running + if (megu_list[player].run_flag){ + addx *= 0.5; + addy *= 0.5; + } + //add to current position + addx += (int)megu_list[player].position.x; + //stop criteria + if (megu_list[player].destination.x - megu_list[player].position.x > 0){ + if (addx > megu_list[player].destination.x) + addx = megu_list[player].destination.x; + } + else{ + if (addx < megu_list[player].destination.x) + addx = megu_list[player].destination.x; + } + //same for y + addy += megu_list[player].position.y; + if (megu_list[player].destination.y - megu_list[player].position.y > 0){ + if (addy > megu_list[player].destination.y) + addy = megu_list[player].destination.y; + } + else{ + if (addy < megu_list[player].destination.y) + addy = megu_list[player].destination.y; + } + //update Megu Position + SetMeguPos(player, (int)addx, (int)addy, side); + //update rendering order + SetRenderOrder(); +} +int MeguEngine::OnExecute() { + if (OnInit() == false) { + return -1; + } + std::cerr << "loading player" << std::endl; + std::ifstream f("gamedata/friends/player.megu"); + if (f.good()) { + f.close(); + std::cerr << "player found" << std::endl; + deserializePlayer("gamedata/friends/player.megu"); + } + + else { + f.close(); + std::cerr << "Loading Megu default" << std::endl; + LoadMegu(1, 1); + megu_list[1].owner_name = "NEW OWNER"; + megu_list[1].pet_name = "MEGU"; + megu_list[1].position.x = 200; + megu_list[1].position.y = 200; + if (mini){ + megu_list[1].position.x /= 2; + megu_list[1].position.y /= 2; + } + megu_list[1].shadow_pos.x = megu_size.x + shadow_pos.x; + megu_list[1].shadow_pos.y = megu_size.y + shadow_pos.y; + megu_list[1].blink = Megu::OPEN; + megu_list[1].state = Megu::STOP_ONE; + } + ui_texts[0].text = megu_list[1].owner_name; + ui_texts[1].text = megu_list[1].pet_name; + //ui_texts[2].text = megu_list[1].pet_race; + for (std::vector::iterator it = ui_texts.begin(); it != ui_texts.end(); ++it){ + it->loadFromRenderedText(renderer); + } + std::cerr << "load house" << std::endl; + deserializeHouse("DEFAULT"); + std::cerr << "set render order" << std::endl; + SetRenderOrder(); + //init sound + std::cerr << "play house bgm" << std::endl; + sounds.playBGM("house"); + SDL_Event Event; + + //start_thread(); + while (Running) { + OnLoop(); + while (SDL_PollEvent(&Event)) { + OnEvent(&Event); + } + OnRender(); + } + OnCleanup(); + + return 0; +} +void MeguEngine::populateHouseLib(widgets::MeguMenus &menu, std::map &item_lib){ + for (std::map::iterator it = item_lib.begin(); it != item_lib.end(); ++it){ + menu.id_library["house"].push_back(it->first); + } +} + +void MeguEngine::populateLib(widgets::MeguMenus &menu, std::map &item_lib){ + for (std::map::iterator it = item_lib.begin(); it != item_lib.end(); ++it){ + menu.id_library[it->second.type].push_back(it->first); + } +} + +void MeguEngine::populatePetLib(widgets::MeguMenus &menu, std::map &item_lib){ + for (std::map::iterator it = item_lib.begin(); it != item_lib.end(); ++it){ + menu.id_library["megu"].push_back(it->first); + } +} +//thread impl + +void MeguEngine::LoadAccessory(const int &accessory_id, const int &player_id, const int &off_x, const int &off_y, const int &pos_x, const int &pos_y, const std::string &type, const SDL_RendererFlip &side){ + Megu::scene_objects new_obj; + new_obj.animation_interval = 0; + new_obj.current_frame = 0; + new_obj.current_time = 0; + new_obj.id = accessory_id; + new_obj.type = type; + std::string suffix; + if (mini){ + suffix = ".png"; + } + else{ + suffix = ".png"; + } + if (type.compare("accessory") == 0){ + new_obj.textures.push_back(loadTexture("assets/Accessory/FUKU" + std::to_string(new_obj.id) + suffix)); + } + SDL_QueryTexture(*new_obj.textures.begin(), NULL, NULL, &new_obj.rectangle.w, &new_obj.rectangle.h); + new_obj.offset.x = off_x; + new_obj.offset.y = off_y; + new_obj.rectangle.x = pos_x; + new_obj.rectangle.y = pos_y; + new_obj.side = side; + new_obj.offset_side = side; + if (megu_list[player_id].accessories_list.size() == 0){ + new_obj.render_id = 1; + } + else{ + new_obj.render_id = megu_list[player_id].accessories_list.rend()->render_id + 1; + } + megu_list[player_id].accessories_list.push_back(new_obj); +} + +void MeguEngine::LoadFurniture(const int &furniture_id, const std::string &type, const SDL_RendererFlip &side){ + Megu::scene_objects new_obj; + new_obj.animation_interval = 0; + new_obj.current_frame = 0; + new_obj.current_time = 0; + new_obj.id = furniture_id; + new_obj.type = type; + std::string suffix; + if (mini){ + suffix = ".png"; + } + else{ + suffix = "@2x.png"; + } + if (type.compare("furniture") == 0){ + new_obj.textures.push_back(loadTexture("assets/Furniture/KG" + std::to_string(new_obj.id) + suffix)); + if (library.furniture_lib[furniture_id].isanimated){ + new_obj.animation_order = library.furniture_lib[furniture_id].animation_order; + new_obj.animation_interval = library.furniture_lib[furniture_id].animation_time; + for (std::vector::iterator it = new_obj.animation_order.begin(); it != new_obj.animation_order.end(); ++it){ + std::stringstream ss; + ss << std::setw(2) << std::setfill('0') << *it; + std::string s = ss.str(); + new_obj.textures.push_back(loadTexture("assets/Furniture/KG" + std::to_string(new_obj.id) + "_" + s + suffix)); + } + } + + } + else { + new_obj.textures.push_back(loadTexture("assets/Food/FOOD_" + std::to_string(new_obj.id) + suffix)); + } + SDL_QueryTexture(*new_obj.textures.begin(), NULL, NULL, &new_obj.rectangle.w, &new_obj.rectangle.h); + new_obj.rectangle.x = 200; + new_obj.rectangle.y = 200; + new_obj.side = side; + if (objects_list.size() == 0){ + new_obj.render_id = 1; + } + else{ + new_obj.render_id = objects_list.rend()->render_id + 1; + } + objects_list.push_back(new_obj); +} + +void MeguEngine::serializePlayer(const std::string &path, Megu::megu_sprites &player){ + std::ofstream file; + file.open(path.c_str()); + if (file.is_open()){ + file << player.owner_name << "\r\n"; + file << player.pet_name << "\r\n"; + file << player.id << "\r\n"; + int num_objs = player.accessories_list.size(); + file << num_objs << "\r\n"; + for (int i = 0; i < num_objs; ++i){ + file << player.accessories_list[i].id << "\r\n"; + file << player.accessories_list[i].type << "\r\n"; + file << player.accessories_list[i].render_id << "\r\n"; + if (mini == false){ + file << player.accessories_list[i].offset.x << "\r\n"; + file << player.accessories_list[i].offset.y << "\r\n"; + } + else{ + file << player.accessories_list[i].offset.x * 2 << "\r\n"; + file << player.accessories_list[i].offset.y * 2 << "\r\n"; + } + if (player.accessories_list[i].offset_side == SDL_FLIP_NONE){ + file << 0 << "\r\n"; + } + if (player.accessories_list[i].offset_side == SDL_FLIP_HORIZONTAL){ + file << 1 << "\r\n"; + } + } + file.close(); + } + else{ + std::cerr << "error opening file" << std::endl; + } + } +void MeguEngine::deserializePlayer(const std::string &path, const int &id){ + mutex = SDL_CreateMutex(); + if (SDL_LockMutex(mutex) == 0){ + std::ifstream file; + std::string line; + + file.open(path.c_str()); + int megu_id; + std::string owner_name; + std::string pet_name; + int num_obj = 0; + std::vector acc_list; + + if (file.is_open()){ + file >> owner_name; + file >> pet_name; + file >> megu_id; + file >> num_obj; + for (int i = 0; i < num_obj; ++i){ + Megu::scene_objects obj; + file >> obj.id; + file >> obj.type; + file >> obj.render_id; + file >> obj.offset.x; + file >> obj.offset.y; + if (mini == true){ + obj.offset.x /= 2; + obj.offset.y /= 2; + } + int side; + file >> side; + if (side == 0){ + obj.offset_side = SDL_FLIP_NONE; + } + else{ + obj.offset_side = SDL_FLIP_HORIZONTAL; + } + acc_list.push_back(obj); + } + file.close(); + std::cerr << "acc list size: " << acc_list.size() << std::endl;; + if (id == -1){ + + if (megu_list.size() == 0){ + LoadMegu(megu_id, 1); + megu_list[1].owner_name = owner_name; + megu_list[1].pet_name = pet_name; + + megu_list[1].position.x = 200; + megu_list[1].position.y = 200; + if (mini){ + megu_list[1].position.x /= 2; + megu_list[1].position.y /= 2; + } + megu_list[1].shadow_pos.x = megu_list[1].position.x + shadow_pos.x; + megu_list[1].shadow_pos.y = megu_list[1].position.y + shadow_pos.y; + megu_list[1].shadow_pos.w = shadow_pos.w; + megu_list[1].shadow_pos.h = shadow_pos.h; + megu_list[1].blink = Megu::OPEN; + megu_list[1].state = Megu::STOP_ONE; + /* for (std::vector::iterator it = acc_list.begin(); it != acc_list.end(); ++it){ + LoadAccessory(it->id, 1, it->offset.x, it->offset.y, 0, 0, it->type, it->offset_side); + }*/ + } + else { + int p_id = megu_list.rbegin()->first + 1; + LoadMegu(megu_id, p_id); + megu_list[p_id].owner_name = owner_name; + megu_list[p_id].pet_name = pet_name; + megu_list[p_id].position.x = 200; + megu_list[p_id].position.y = 200; + if (mini){ + megu_list[p_id].position.x /= 2; + megu_list[p_id].position.y /= 2; + } + megu_list[p_id].shadow_pos.x = megu_list[p_id].position.x + shadow_pos.x; + megu_list[p_id].shadow_pos.y = megu_list[p_id].position.y + shadow_pos.y; + megu_list[p_id].blink = Megu::OPEN; + megu_list[p_id].state = Megu::STOP_ONE; + /* for (std::vector::iterator it = acc_list.begin(); it != acc_list.end(); ++it){ + LoadAccessory(it->id, p_id, it->offset.x, it->offset.y, 0, 0, it->type, it->offset_side); + }*/ + } + } + else{ + LoadMegu(megu_id, id); + megu_list[id].owner_name = owner_name; + megu_list[id].pet_name = pet_name; + megu_list[id].position.x = 200; + megu_list[id].position.y = 200; + if (mini){ + megu_list[id].position.x /= 2; + megu_list[id].position.y /= 2; + } + megu_list[id].shadow_pos.x = megu_list[id].position.x + shadow_pos.x; + megu_list[id].shadow_pos.y = megu_list[id].position.y + shadow_pos.y; + megu_list[id].blink = Megu::OPEN; + megu_list[id].state = Megu::STOP_ONE; + /* for (std::vector::iterator it = acc_list.begin(); it != acc_list.end(); ++it){ + LoadAccessory(it->id, id, it->offset.x, it->offset.y, 0, 0, it->type, it->offset_side); + }*/ + } + } + else{ + std::cerr << "error opening file" << std::endl; + } + SDL_UnlockMutex(mutex); + } + + SDL_DestroyMutex(mutex); +} + + void MeguEngine::serializeHouse(const std::string &filename){ + std::ofstream file; + std::string path = "gamedata/house/SAV" + filename + ".house"; + file.open(path); + if (file.is_open()){ + //house first + file << "SAV" << filename << ".png\r\n"; + file << house_id << "\r\n"; + //then objects + int num_objs = objects_list.size(); + file << num_objs << "\r\n"; + for (int i = 0; i < num_objs; ++i){ + file << objects_list[i].id << "\r\n"; + file << objects_list[i].type << "\r\n"; + file << objects_list[i].render_id << "\r\n"; + if (mini == false){ + file << objects_list[i].rectangle.x << "\r\n"; + file << objects_list[i].rectangle.y << "\r\n"; + } + else{ + file << objects_list[i].rectangle.x*2 << "\r\n"; + file << objects_list[i].rectangle.y*2 << "\r\n"; + } + if (objects_list[i].side == SDL_FLIP_NONE){ + file << 0 << "\r\n"; + } + if (objects_list[i].side == SDL_FLIP_HORIZONTAL){ + file << 1 << "\r\n"; + } + } + file.close(); + } + else{ + std::cerr << "error saving file: " << path << std::endl; + } + } + void MeguEngine::deserializeHouse(const std::string &filename){ + std::string path = "gamedata/house/SAV" + filename + ".house"; + objects_list.clear(); + std::ifstream file; + file.open(path.c_str()); + if (file.is_open()){ + std::string dump; + file >> dump; + //house first + file >> house_id; + updateBackground(house_id); + //then objects + int num_objs = 0; + file >> num_objs; + for (int i = 0; i < num_objs; ++i){ + int id = 0; + int x, y; + int render_id; + std::string type = ""; + SDL_RendererFlip side; + file >> id; + file >> type; + file >> render_id; + file >> x; + file >> y; + int sside; + file >> sside; + if (sside == 0){ + side = SDL_FLIP_NONE; + } + else if (sside == 1){ + side = SDL_FLIP_HORIZONTAL; + } + + LoadFurniture(id,type,side); + if (mini == false){ + objects_list.rbegin()->rectangle.x = x; + objects_list.rbegin()->rectangle.y = y; + } + else{ + objects_list.rbegin()->rectangle.x = x/2; + objects_list.rbegin()->rectangle.y = y/2; + } + objects_list.rbegin()->render_id = render_id; + } + file.close(); + } + else{ + std::cerr << "error loading file: " << path << std::endl; + updateBackground(1); + serializeHouse("DEFAULT");//save new file + } + } + void MeguEngine::populateRndMsg(){ + rapidxml::file<> *hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//random_message.xml"); // Default template is char + rapidxml::xml_document<> hdoc; + hdoc.parse<0>(hxmlFile->data()); + rapidxml::xml_node<> *hpRoot = hdoc.first_node(); + int i = 0; + for (rapidxml::xml_node<> *bNode = hpRoot->first_node("message"); bNode; bNode = bNode->next_sibling("message")) + { + random_message_list[i] = bNode->value(); + ++i; + } + delete hxmlFile; + hxmlFile = new rapidxml::file<>("assets//xml//pet_message.xml"); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + i = 0; + for (rapidxml::xml_node<> *bNode = hpRoot->first_node("message"); bNode; bNode = bNode->next_sibling("message")) + { + pet_message_list[i] = bNode->value(); + ++i; + } + + } + void MeguEngine::takeScreenshot(const std::string &path, const int &w, const int &h){ + SDL_Surface* saveSurface = NULL; + SDL_Surface* copySurface = NULL; + SDL_Surface* infoSurface = NULL; + + infoSurface = SDL_GetWindowSurface(win); + if (infoSurface == NULL) { + std::cerr << "Failed to create info surface from window in saveScreenshotBMP(string), SDL_GetError() - " << SDL_GetError() << "\n"; + } else { + unsigned char * pixels = new (std::nothrow) unsigned char[infoSurface->w * infoSurface->h * infoSurface->format->BytesPerPixel]; + if (pixels == 0) { + std::cerr << "Unable to allocate memory for screenshot pixel data buffer!\n"; + return ; + } + else { + if (SDL_RenderReadPixels(renderer, &infoSurface->clip_rect, infoSurface->format->format, pixels, infoSurface->w * infoSurface->format->BytesPerPixel) != 0) { + std::cerr << "Failed to read pixel data from SDL_Renderer object. SDL_GetError() - " << SDL_GetError() << "\n"; + pixels = NULL; + return; + } + else { + copySurface = SDL_CreateRGBSurfaceFrom(pixels, infoSurface->w, infoSurface->w, infoSurface->format->BitsPerPixel, infoSurface->w * infoSurface->format->BytesPerPixel, infoSurface->format->Rmask, infoSurface->format->Gmask, infoSurface->format->Bmask, infoSurface->format->Amask); + if (copySurface == NULL) { + std::cerr << "Couldn't create SDL_Surface from renderer pixel data. SDL_GetError() - " << SDL_GetError() << "\n"; + return; + } + saveSurface = SDL_CreateRGBSurface(infoSurface->flags, + w, + h, + infoSurface->format->BitsPerPixel, + infoSurface->format->Rmask, + infoSurface->format->Gmask, + infoSurface->format->Bmask, + infoSurface->format->Amask); + if (saveSurface == NULL) { + std::cerr << "Couldn't create SDL_Surface from renderer pixel data. SDL_GetError() - " << SDL_GetError() << "\n"; + return; + } + SDL_BlitScaled(copySurface, NULL, saveSurface, NULL); + + SDL_FreeSurface(copySurface); + std::string t_path = path + ".png"; + std::cerr << t_path << std::endl; + SDL_SaveBMP(saveSurface, t_path.c_str()); + SDL_FreeSurface(saveSurface); + saveSurface = NULL; + } + delete[] pixels; + } + + SDL_FreeSurface(infoSurface); + infoSurface = NULL; + } + } + void MeguEngine::loadFriendList(){ + friends_save_list.clear(); +#ifdef __APPLE__ + + DIR* dirFile = opendir("gamedata/friends"); + if (dirFile) + { + struct dirent* hFile; + errno = 0; + while ((hFile = readdir(dirFile)) != NULL) + { + if (!strcmp(hFile->d_name, ".")) continue; + if (!strcmp(hFile->d_name, "..")) continue; + + // in linux hidden files all start with '.' + if ((hFile->d_name[0] == '.')) continue; + + // dirFile.name is the name of the file. Do whatever string comparison + // you want here. Something like: + if (strstr(hFile->d_name, ".megu")){ + if (std::string(hFile->d_name) != "player.megu"){ + std::string filename = std::string(hFile->d_name); + friends_save_list.push_back(filename); + } + else { + std::cout << "skipping" << std::endl; + } + } + closedir(dirFile); + } + } +#elif WIN32 + + + DIR *dp; + struct dirent *dirp; + dp = opendir("gamedata/friends"); + if (dp == NULL) { + return; + } + else{ + + while ((dirp = readdir(dp)) != NULL) { + + if (!strcmp(dirp->d_name, ".")) continue; + if (!strcmp(dirp->d_name, "..")) continue; + std::string fn = dirp->d_name; + if (fn.substr(fn.find_last_of(".") + 1) == "megu") { + if (std::string(dirp->d_name) != "player.megu"){ + // std::string filename = "gamedata/friends/" + fn; + std::cerr << fn << std::endl; + friends_save_list.push_back(fn); + } + } + else { + std::cout << "skipping" << std::endl; + } + } + } +#endif + } + + void MeguEngine::serializeOptions(){ + std::ofstream file; + file.open("gamedata//settings.dat"); + if (file.is_open()){ + //house first + file << options_menu->getBGMLevel() << "\r\n"; + file << options_menu->getSFXLevel() << "\r\n"; + file << options_menu->getMSGOn(); + file.close(); + } + else{ + std::cerr << "error saving file: " << "gamedata//settings.dat" << std::endl; + } + } + + void MeguEngine::deserializeOptions(){ + std::ifstream file; + int bgmlevel = 5; + int sfxlevel = 5; + bool msgon = true; + file.open("gamedata//settings.dat"); + if (file.is_open()){ + //house first + file >> bgmlevel; + file >> sfxlevel; + file >> msgon; + file.close(); + } + else{ + std::cerr << "loading files at, setting to default: " << "gamedata//settings.dat" << std::endl; + } + options_menu->setBGMLevel(bgmlevel); + options_menu->setMSGOn(msgon); + options_menu->setSFXLevel(sfxlevel); + sounds.setBGMVolume(bgmlevel); + sounds.setSFXVolume(sfxlevel); + message_screen->locked = msgon; + } + + void MeguEngine::loadLayouts(){ + layout_save_list.clear(); +#ifdef __APPLE__ + + DIR* dirFile = opendir("gamedata/house"); + if (dirFile) + { + struct dirent* hFile; + errno = 0; + while ((hFile = readdir(dirFile)) != NULL) + { + if (!strcmp(hFile->d_name, ".")) continue; + if (!strcmp(hFile->d_name, "..")) continue; + + // in linux hidden files all start with '.' + if ((hFile->d_name[0] == '.')) continue; + + // dirFile.name is the name of the file. Do whatever string comparison + // you want here. Something like: + if (strstr(hFile->d_name, "house")){ + if (std::string(hFile->d_name) != "SAVDEFAULT"){ + std::string filename = std::string(hFile->d_name); + std::cerr << "layout: "<< filename << std::endl; + layout_save_list.push_back(filename); + } + else { + std::cout << "skipping" << std::endl; + } + } + closedir(dirFile); + } + } +#elif WIN32 + + + DIR *dp; + struct dirent *dirp; + dp = opendir("gamedata/house"); + if (dp == NULL) { + return; + } + else{ + + while ((dirp = readdir(dp)) != NULL) { + + if (!strcmp(dirp->d_name, ".")) continue; + if (!strcmp(dirp->d_name, "..")) continue; + std::string fn = dirp->d_name; + if (fn.substr(fn.find_last_of(".") + 1) == "house") { + if (std::string(dirp->d_name) != "SAVDEFAULT.house"){ + std::cerr << "layout: " << fn << std::endl; + layout_save_list.push_back(fn); + + } + } + else { + std::cout << "skipping" << std::endl; + } + } + } +#endif + + } \ No newline at end of file diff --git a/MeguEngine.h b/MeguEngine.h new file mode 100644 index 0000000..2c0bbcf --- /dev/null +++ b/MeguEngine.h @@ -0,0 +1,224 @@ +#pragma once +#include "MeguSound.h" +#include "MeguStructs.h" +#include"items_library.h" +#include +#include +#include +#include +#include "SDL_include.h" +#include "MeguButton.h" +#include "AccessoryMenus.h" +#include "FoodMenus.h" +#include "FurnitureMenus.h" +#include "CareMenus.h" +#include "PetMenus.h" +#include "HouseMenus.h" +#include "CareMenus.h" +#include "EditMenus.h" +#include "EditMenus.h" +#include "NameMenus.h" +#include "FriendsMenus.h" +#include "LayoutMenus.h" +#include "OptionsMenus.h" +#include "SizeMenus.h" +#include "MessageScreen.h" +#include "TtfWrapper.h" +#include + + +class MeguEngine { +private: + bool mini; + SDL_mutex *mutex; + unsigned int player_counter; + //food kit + Megu::food_kit kit; + //game state + Game::GAME_STATE status; + //menu variables + bool menu_open;//disable stuff if any menu is opened + MeguSound sounds; + //timer thresholds + const uint32_t megu_blink_counter; + const uint32_t megu_openeye_counter; + const uint32_t megu_animation_counter; + const uint32_t megu_misc_counter; + const uint32_t megu_pet_counter; + const uint32_t megu_event_action; + const uint32_t megu_heart_event_counter; + const uint32_t megu_msg_counter; + uint32_t curr_time; + uint32_t last_time; + uint32_t msg_time; + //megu speed + const int megu_spd; + const uint32_t scene_limit; + //ID mapping + bool Running; + //players list + std::vector player_list; + //megu player map association + std::map megu_list; + //object in scene list + std::vector objects_list; + std::map random_message_list; + std::map pet_message_list; + //current house id + int house_id; + + bool edit_holding; + int object_index; + //SDL render variables + SDL_Window *win = NULL; + SDL_Renderer *renderer = NULL; + SDL_Texture *menu_bar = NULL; // menu bar texture + SDL_Texture *house = NULL; //house texture + SDL_Rect clickable_area; + SDL_Texture *mouse_cursor = NULL; + //SDL_Rect Positioning + SDL_Rect menu_bar_pos; + SDL_Rect menu_food_pos; + SDL_Rect menu_furniture_pos; + SDL_Rect menu_background_pos; + item_library library; + SDL_Point mPosition; + SDL_Rect shadow_pos; + std::string shadow_texture; + SDL_Rect megu_size; + int shadow_alpha; + //button widgets + widgets::MeguButton *care_button; + widgets::MeguButton *edit_button; + widgets::MeguButton *option_button; + widgets::MeguButton *return_button; + //menu + widgets::FoodMenus *food_menu; + widgets::FurnitureMenus *furniture_menu; + widgets::PetMenus *pet_menu; + widgets::HouseMenus *house_menu; + widgets::CareMenus *care_menu; + widgets::EditMenus *edit_menu; + widgets::NameMenus *name_menu; + widgets::OptionsMenus *options_menu; + widgets::FriendsMenus *friends_menu; + widgets::LayoutMenus *layout_menu; + widgets::SizeMenus *size_menu; + widgets::AccessoryMenus *accessory_menu; + widgets::MessageScreen *message_screen; + std::vector render_order; + std::vector friends_save_list; + std::vector layout_save_list; + std::vector hearts_texture; + SDL_Rect heart_offset; + ID id_accessory; + + void populateLib(widgets::MeguMenus &menu, std::map &item_lib); + void populateHouseLib(widgets::MeguMenus &menu, std::map &item_lib); + void populatePetLib(widgets::MeguMenus &menu, std::map &pet_lib); + void populateRndMsg(); + inline void getConstrainedMovement(const int &wx, const int &wy, int &out_wx, int &out_wy); +public: + + MeguEngine(); + + int OnExecute(); + + //basic functions + //Loads individual image as texture + SDL_Texture* loadTexture(std::string path); + + //The window we'll be rendering to + SDL_Window* gWindow = NULL; + + //Current displayed texture + SDL_Texture* gTexture = NULL; + + //init method + bool OnInit(); + + //init menus + void initMenus(); + //init objects + void initObjects(); + //event triggered process + void OnEvent(SDL_Event* Event); + + //loop process + void OnLoop(); + + //rendering process + void OnRender(); + + void OnCleanup(); + + //specific functions + //load house background + bool updateBackground(const int &id); + + //megu name, player + void LoadMegu(const int &megu_id, const PLAYER_ID &player); + + void LoadFurniture(const int &furniture_id, const std::string &type, const SDL_RendererFlip &side = SDL_FLIP_NONE); + + void LoadAccessory(const int &accessory_id, const int &player_id, const int &off_x, const int &off_y, const int &pos_x, const int &pos_y, const std::string &type, const SDL_RendererFlip &side = SDL_FLIP_NONE); + + void SetMeguPos(const PLAYER_ID &player, const int &x, const int &y, const SDL_RendererFlip &side = SDL_FLIP_NONE); + + //set Megu Position + void SetMeguState(const PLAYER_ID &player, const Megu::MEGU_STATE &new_state, const Megu::MEGU_EYE &eye_state = Megu::NONE); + + //Megu State Machine + void MeguStateMachine(); + + //Megus Position Handler, manages movement across the map + void MeguPositionHandler(const PLAYER_ID&player); + //Set Megu Destination for movement. + void SetMeguDestination(const PLAYER_ID &player, const int &x, const int &y); + + //Click on scene callback function + void MeguClickScene(const PLAYER_ID &player, const int &x, const int&y); + //MouseEvents + //Sets top left position + void setMousePosition(int x, int y); + //Handles mouse event + void handleMouseEvent(SDL_Event* e); + //Shows button sprite + void mouserender(); + //sort render order + void SetRenderOrder(); + //render food table + void food_mode(const int &ID); + + void saveGame(); + + void importMegu(); + + void foodAnimationCallback(const PLAYER_ID &player); + + void serializePlayer(const std::string &path, Megu::megu_sprites &player); + + void deserializePlayer(const std::string &path, const int &id = -1); + + void serializeHouse(const std::string &filename); + + void deserializeHouse(const std::string &filename); + + void loadFriendList(); + + void loadLayouts(); + + void takeScreenshot(const std::string &path, const int &w, const int &h); + + void loadMessages(); + + void serializeOptions(); + + void deserializeOptions(); + + void handleSizeSelector(SDL_Event *e); +protected: + std::vector ui_texts; + int new_megu_id; +}; + diff --git a/MeguMenus.cpp b/MeguMenus.cpp new file mode 100644 index 0000000..2c011c5 --- /dev/null +++ b/MeguMenus.cpp @@ -0,0 +1,103 @@ +#include "MeguMenus.h" +#include "SDL_include.h" +#include "Items_library.h" +using namespace widgets; + +MeguMenus::MeguMenus(){ +} +MeguMenus::MeguMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture) +{ + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + visible = false; + SDL_Color color; + color.r = 255; + color.b = 255; + color.a = 0; + color.g = 255; + + current_page = 0; +} + +void MeguMenus::disableMenu(){ + visible = false; + for (widgets::button_container::iterator it = slots.begin(); it != slots.end(); ++it){ + it->setEnable(false); + it->setVisible(false); + } + for (std::vector::iterator it = slots_name.begin(); it != slots_name.end(); ++it){ + it->setVisible(false); + } + for (std::vector::iterator it = slots_description.begin(); it != slots_description.end(); ++it){ + it->setVisible(false); + } + for (widgets::button_container::iterator it = controls.begin(); it != controls.end(); ++it){ + it->setVisible(false); + it->setEnable(false); + } +} + +void MeguMenus::callMenu(){ + visible = true; + for (widgets::button_container::iterator it = slots.begin(); it != slots.end(); ++it){ + it->setEnable(true); + it->setVisible(true); + } + for (std::vector::iterator it = slots_name.begin(); it != slots_name.end(); ++it){ + it->setVisible(true); + } + for (std::vector::iterator it = slots_description.begin(); it != slots_description.end(); ++it){ + it->setVisible(true); + } + for (widgets::button_container::iterator it = controls.begin(); it != controls.end(); ++it){ + it->setVisible(true); + it->setEnable(true); + } +} +void MeguMenus::Render(SDL_Renderer *renderer) +{ + if (visible){ + SDL_RenderCopy(renderer, texture, NULL, &rect); + for (widgets::button_container::iterator it = slots.begin(); it != slots.end(); ++it){ + it->Render(renderer); + } + for (std::vector::iterator it = slots_name.begin(); it != slots_name.end(); ++it){ + it->Render(renderer); + } + for (std::vector::iterator it = slots_description.begin(); it != slots_description.end(); ++it){ + it->Render(renderer); + } + for (widgets::button_container::iterator it = controls.begin(); it != controls.end(); ++it){ + it->Render(renderer); + } + } +} + +void MeguMenus::updateSlots(SDL_Renderer *renderer){} + +void MeguMenus::setClassificationType(const CLASSIFICATION &classification, SDL_Renderer *renderer){ + current_classification = classification; + updateSlots(renderer); +} +void MeguMenus::setViewPage(const int &page, SDL_Renderer *renderer){ + if (page <= (id_library[current_classification].size()-1)/3 && page >= 0){ + current_page = page; + updateSlots(renderer); + } + +} + +void MeguMenus::setCurrentId(const int &id){ + selected_id = id; +} + +int MeguMenus::getCurrentId(){ + return selected_id; +} + +MeguMenus::~MeguMenus() +{ +} diff --git a/MeguMenus.h b/MeguMenus.h new file mode 100644 index 0000000..7154741 --- /dev/null +++ b/MeguMenus.h @@ -0,0 +1,55 @@ +#pragma once +#include "SDL_include.h" +#include "MeguButton.h" +#include "TtfWrapper.h" +#include "Items_library.h" +#include +#include +#include +#include +namespace widgets{ + typedef std::string CLASSIFICATION; + typedef int ID; + typedef std::vector button_container; + class MeguMenus + { + + public: + MeguMenus(); + MeguMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture); + void disableMenu(); + void callMenu(); + void Render(SDL_Renderer *renderer); + ~MeguMenus(); + button_container slots; + button_container controls; + std::vector slots_name; + std::vector slots_description; + int current_page; + CLASSIFICATION current_classification; + std::map> id_library; + void setClassificationType(const CLASSIFICATION &classification, SDL_Renderer *renderer); + virtual void updateSlots(SDL_Renderer *renderer); + virtual void setViewPage(const int &page, SDL_Renderer *renderer); + void setCurrentId(const int &id); + int getCurrentId(); + + protected: + //Globally used font + int selected_id; + SDL_Texture* texture; + SDL_Rect rect; + int w, h; + //Load image at specified path + bool visible;//if yes then render/do stuff + rapidxml::file<> *hxmlFile; + rapidxml::xml_document<> hdoc; + rapidxml::xml_node<> *hpRoot; + rapidxml::xml_node<> *pNode; + rapidxml::xml_node<> *sNode; + rapidxml::xml_node<> *dNode; + rapidxml::xml_node<> *nNode; + rapidxml::xml_node<> *overlayNode; + + }; +} \ No newline at end of file diff --git a/MeguSerialize.h b/MeguSerialize.h new file mode 100644 index 0000000..3e8df48 --- /dev/null +++ b/MeguSerialize.h @@ -0,0 +1,45 @@ +#pragma once +#include +#include +#include +#include +#include +#include"MeguStructs.h" + +class MeguSerialize{ + friend class MeguEngine; +public: + static void serializePlayer(const std::string &path, Megu::megu_sprites &player){ + std::ofstream file; + file.open(path.c_str()); + if (file.is_open()){ + file << player.owner_name << "/n"; + file << player.pet_name << "/n"; + file << player.id << "/n"; + file.close(); + } + else{ + std::cerr << "error opening file" << std::endl; + } + } + static void deserializePlayer(const std::string &path, const int id, SDL_Renderer *renderer){ + std::ifstream file; + std::string line; + + file.open(path.c_str()); + int megu_id; + std::string owner_name; + std::string pet_name; + if (file.is_open()){ + file >> owner_name; + file >> pet_name; + file >> megu_id; + file.close(); + } + else{ + std::cerr << "error opening file" << std::endl; + } + } + static void serializeHouse(const std::string &path, std::vector &objects_list); + static void deserializeHouse(const std::string &path, std::vector &objects_list, SDL_Renderer *renderer); +}; \ No newline at end of file diff --git a/MeguSound.cpp b/MeguSound.cpp new file mode 100644 index 0000000..48214ff --- /dev/null +++ b/MeguSound.cpp @@ -0,0 +1,105 @@ +#include "MeguSound.h" +#include "SDL_include.h" + + +void MeguSound::playSFX(const sfx_name &name, const int &channel){ + if (sfx_on){ + Mix_PlayChannel(channel, sfx[name], 0); + Mix_Volume(channel, sfx_volume*24); + } +} +void MeguSound::playBGM(const sfx_name &name){ + if (bgm_on){ + if (Mix_PlayMusic(bgm[name], -1) == -1){ + printf("Mix_PlayMusic: %s\n", Mix_GetError()); + } + Mix_VolumeMusic(bgm_volume*6); + } +} + +void MeguSound::setSFX(const sfx_name &name, const char *filename){ + sfx[name] = Mix_LoadWAV(filename); +} +void MeguSound::setBGM(const sfx_name &name, const char* filename){ + bgm[name] = Mix_LoadMUS(filename); +} + +void MeguSound::setBGMVolume(const int& volume){ + bgm_volume = volume; + Mix_VolumeMusic(volume*6); +} +void MeguSound::loadAll(){ + setBGM("stroll", "assets/sound/BGM_stroll.mp3"); + setBGM("race", "assets/sound/BGM_race.mp3"); + setBGM("house", "assets/sound/MEGU_BGM.mp3"); + setBGM("adventure", "assets/sound/BGM_Adventure.mp3"); + setSFX("bad", "assets/sound/sfx/SE_bad.wav"); + setSFX("balltoss", "assets/sound/sfx/SE_balltoss.wav"); + setSFX("beat", "assets/sound/sfx/SE_beat.wav"); + setSFX("changed", "assets/sound/sfx/SE_changed.wav"); + setSFX("changing", "assets/sound/sfx/SE_changing.wav"); + setSFX("click", "assets/sound/sfx/SE_click.wav"); + setSFX("Complete", "assets/sound/sfx/SE_Complete.wav"); + setSFX("Continuation", "assets/sound/sfx/SE_Continuation.wav"); + setSFX("Departure", "assets/sound/sfx/SE_Departure.wav"); + setSFX("elixir", "assets/sound/sfx/SE_elixir.wav"); + setSFX("food", "assets/sound/sfx/SE_food.wav"); + setSFX("GetCntinuation", "assets/sound/sfx/SE_GetCntinuation.wav"); + setSFX("gold", "assets/sound/sfx/SE_gold.wav"); + setSFX("GotTheItem", "assets/sound/sfx/SE_beat.wav"); + setSFX("happy1", "assets/sound/sfx/SE_happy1.wav"); + setSFX("happy2", "assets/sound/sfx/SE_happy2.wav"); + setSFX("happy3", "assets/sound/sfx/SE_happy3.wav"); + setSFX("levelup", "assets/sound/sfx/SE_levelup.wav"); + setSFX("megu1", "assets/sound/sfx/SE_megu1.wav"); + setSFX("megu2", "assets/sound/sfx/SE_megu2.wav"); + setSFX("megu3", "assets/sound/sfx/SE_megu3.wav"); + setSFX("megu4", "assets/sound/sfx/SE_megu4.wav"); + setSFX("megu5", "assets/sound/sfx/SE_megu5.wav"); + setSFX("megu6", "assets/sound/sfx/SE_megu6.wav"); + setSFX("megu7", "assets/sound/sfx/SE_megu7.wav"); + setSFX("megu8", "assets/sound/sfx/SE_megu8.wav"); + setSFX("megu9", "assets/sound/sfx/SE_megu10.wav"); + setSFX("megu10", "assets/sound/sfx/SE_megu10.wav"); + setSFX("notsobad", "assets/sound/sfx/SE_notsobad.wav"); + setSFX("pet", "assets/sound/sfx/SE_pet.wav"); + setSFX("Stamp", "assets/sound/sfx/SE_Stamp.wav"); + setSFX("sweep", "assets/sound/sfx/SE_sweep.wav"); + setSFX("wash", "assets/sound/sfx/SE_wash.wav"); + bgm_on = true; + sfx_on = true; + sfx_volume = 120; + bgm_volume = 30; +} + +void MeguSound::cutSFX(const int &channel){ + Mix_Pause(channel); +} + +void MeguSound::pauseMusic(){ + Mix_PauseMusic(); +} +void MeguSound::resumeMusic(){ + Mix_ResumeMusic(); +} +MeguSound::~MeguSound(){ + bgm.clear(); + sfx.clear(); +} + +void MeguSound::setBGMOn(const bool &bgm){ + bgm_on = bgm; +} +void MeguSound::setSoundOn(const bool &sfx){ + sfx_on = sfx; +} +bool MeguSound::getBGMOn(){ + return bgm_on; +} +bool MeguSound::getSoundOn(){ + return sfx_on; +} + +void MeguSound::setSFXVolume(const int &sfx){ + sfx_volume = sfx; +} \ No newline at end of file diff --git a/MeguSound.h b/MeguSound.h new file mode 100644 index 0000000..53341a7 --- /dev/null +++ b/MeguSound.h @@ -0,0 +1,35 @@ +#pragma once +#include "SDL_include.h" +#include +#include + +typedef std::string sfx_name; + +class MeguSound{ +private: + + std::map bgm; + std::map sfx; + bool bgm_on; + bool sfx_on; + +public: + + void playSFX(const sfx_name &name, const int &channel); + void playBGM(const sfx_name &name); + void setSFX(const sfx_name &name, const char *filename); + void setBGM(const sfx_name &name, const char *filename); + void cutSFX(const int &channel); + void pauseMusic(); + void resumeMusic(); + void loadAll(); + void setBGMOn(const bool &bgm); + void setSoundOn(const bool &bgm); + bool getBGMOn(); + bool getSoundOn(); + void setBGMVolume(const int &bgm); + void setSFXVolume(const int &sfx); + ~MeguSound(); + int sfx_volume; + int bgm_volume; +}; \ No newline at end of file diff --git a/MeguStructs.h b/MeguStructs.h new file mode 100644 index 0000000..79b5cc9 --- /dev/null +++ b/MeguStructs.h @@ -0,0 +1,185 @@ + +#include "SDL_include.h" +#include +#include +#include +namespace Game{ + enum GAME_STATE{ + ERROR, + INIT, + STOP, + RUNNING, + EDIT_MODE, + ACCESSORY_MODE, + FOOD_MENU, + FURNITURE_MENU, + PET_MENU, + HOUSE_MENU, + ACCESSORY_MENU, + CARE_MENU, + EDIT_MENU, + STATUS_MENU, + NAME_MENU, + SAVE_MEGU_MENU, + SAVE_HOUSE_MENU, + LOAD_MEGU_MENU, + LOAD_HOUSE_MENU, + NEW_MEGU_NAME_MENU, + NEW_MEGU_PET_MENU, + FRIEND_INVITE_MENU, + OPTIONS_MENU, + LAYOUT_SAVE_MENU, + LAYOUT_LOAD_MENU, + FEEDING + + + + + }; +} +namespace Megu{ + typedef int ID; + typedef int MEGU_SIZE; + + enum MEGU_STATE{ + WALK_ONE = 0, + WALK_TWO = 1, + STOP_ONE = 2, + STOP_TWO = 3, + SCARED = 6, + VERY_HAPPY = 7, + HAPPY = 8, + AFRAID = 9, + THINKING = 10 + }; + + enum MEGU_EYE{ + NONE = -1, + OPEN = 4, + BLINK = 5, + BLINKED = 6 + }; + //for food positioning + struct food_kit{ + bool visible; + //table + SDL_Texture *table; + //table shadow + SDL_Texture *table_shadow; + //table pos + SDL_Rect rect_t; + //shadow pos + SDL_Rect rect_s; + //even megu id position to go + SDL_Rect even_megu; + //odd megu id position to go + SDL_Rect odd_megu; + //food texture + std::vector food; + //food position + SDL_Rect rect_f; + void destroy_food_kit(){ + food.clear(); + visible = false; + } + }; + + struct scene_objects{ + ID id; //unique ID + ID render_id; //unique ID each time an object is created + SDL_Rect rectangle;//position + SDL_Rect offset;//position + SDL_RendererFlip offset_side; //offset side + std::string type; //for foods as furniture specifically + int animation_interval;//if required + int current_frame; + int current_time; + std::vector animation_order; + std::vector textures; //if required + SDL_RendererFlip side; // SDL_FLIP_NONE or SDL_FLIP_HORIZONTAL + bool IsIn(int mouseX, int mouseY) + { + if (((mouseX > rectangle.x) && (mouseX < rectangle.x + rectangle.w)) + && ((mouseY > rectangle.y) && (mouseY < rectangle.y + rectangle.h)) + ) { + return true; + } + else { + return false; + } + } + }; + + struct megu_sprites{ + int id; //megu id + std::string pet_name; //name of your megu + std::string owner_name; //name of owner + std::string pet_race; //race of megu + int pet_counting; //number of pets done in sequence, after 8 gets super happy :) + uint32_t pet_timer; //hover mouse over megu over a certain threshold trigger pet + std::default_random_engine generator; + SDL_Texture* sprites[11]; + SDL_Texture* shadow; + SDL_Rect shadow_pos; + Megu::MEGU_SIZE size; + SDL_Rect position; //current position + SDL_Rect destination; // destination position + bool run_flag; //if running 1 + bool pet_flag; //if petting + std::vector heart_textures; + std::vector accessories_list;//acessories + int accessory_index;//selected accessories + MEGU_STATE state; + MEGU_EYE blink; //if open 4, blink 5 + uint32_t blink_timer; //eye blinking trigger + uint32_t blink_openeye; //open eye timer + uint32_t animation_timer; //animation switching + uint32_t misc_timer; //happy, sad etc + uint32_t random_action_timer; //walking and sounds + uint32_t heart_animation_timer;// heart animation timer + enum heart_animation_state{ + STOP = 0, + FIRST = 1, + SECOND = 2, + THIRD = 3 + }heart_animation; + SDL_RendererFlip side; // SDL_FLIP_NONE or SDL_FLIP_HORIZONTAL + + ~megu_sprites(){ + for (int i = 0; i < 11; ++i){ + SDL_DestroyTexture(sprites[i]); + SDL_DestroyTexture(shadow); + } + } + megu_sprites(){ + blink_timer = 0; + animation_timer = 0; + pet_timer = 0; + run_flag = false; + misc_timer = 0; + pet_counting = 0; + pet_flag = 0; + random_action_timer = 0; + heart_animation_timer = 0; + heart_animation = STOP; + } + }; +}; + + +typedef std::string MEGU_NAME; +typedef unsigned int PLAYER_ID; + +struct render_ordering{ + PLAYER_ID player; + int position_y; + render_ordering(){ + player = -1; + position_y = 0; + } + render_ordering(PLAYER_ID p, int _y){ + player = p; + position_y = _y; + + } +}; diff --git a/MessageScreen.cpp b/MessageScreen.cpp new file mode 100644 index 0000000..afc753a --- /dev/null +++ b/MessageScreen.cpp @@ -0,0 +1,97 @@ +#include "MessageScreen.h" +#include +using namespace widgets; + +MessageScreen::MessageScreen() +{ +} + + +MessageScreen::~MessageScreen() +{ +} +MessageScreen::MessageScreen(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool &mini){ + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + color.a = 50; + color.b = 50; + color.g = 50; + color.r = 50; + timer = 0; + timeout = 0; + hxmlFile = new rapidxml::file<>("assets//xml//message_plaque_config.xml"); + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + if (!mini){ + gNode = hpRoot->last_node("config"); + } + else{ + gNode = hpRoot->first_node("config"); + } + pNode = gNode->first_node("message_plaque"); + msg_pos.x = atoi(pNode->first_node("message_text")->first_node("pos")->first_node("x")->value()); + msg_pos.y = atoi(pNode->first_node("message_text")->first_node("pos")->first_node("y")->value()); + font_size = atoi(pNode->first_node("message_text")->first_node("font_size")->value()); + font = pNode->first_node("message_text")->first_node("font")->value(); + render_msg = new TtfWrapper(rect.x + msg_pos.x, rect.y + msg_pos.y, 50, 50, 50, SDL_BLENDMODE_BLEND, 0, color, font_size, font,600, true); + render_msg->loadFromRenderedText(renderer); + setTimer(0); + setTimeOut(0); + visible = false; + locked = false; +} + +void MessageScreen::addMessage(const std::string &_msg){ + msg = _msg; + render_msg->text = msg; + +} + +SDL_Texture* MessageScreen::loadTexture(std::string path, SDL_Renderer *renderer){ + //The final texture + SDL_Texture* newTexture = NULL; + + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + return newTexture; +} + +long MessageScreen::getTimeout(){ + return timeout; + +} +void MessageScreen::setTimeOut(const long &time){ + timeout = time; +} +void MessageScreen::setTimer(const long &time){ + timer = time; +} +long MessageScreen::getTimer(){ + return timer; +} +void MessageScreen::Render(SDL_Renderer *renderer){ + if (visible){ + SDL_RenderCopy(renderer, texture, NULL, &rect); + render_msg->loadFromRenderedText(renderer); + render_msg->Render(renderer); + } +} \ No newline at end of file diff --git a/MessageScreen.h b/MessageScreen.h new file mode 100644 index 0000000..b2a7e36 --- /dev/null +++ b/MessageScreen.h @@ -0,0 +1,44 @@ +#pragma once +#include "SDL_include.h" +#include "TtfWrapper.h" +#include +#include +#include +namespace widgets{ + class MessageScreen + { + public: + MessageScreen(); + MessageScreen(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool &mini); + void addMessage(const std::string &_msg); + TtfWrapper rendered_msg; + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + void Render(SDL_Renderer *renderer); + ~MessageScreen(); + long getTimeout(); + void setTimeOut(const long &time); + void setTimer(const long &time); + long getTimer(); + bool visible;//if yes then render + bool locked; //lock message on screen + private: + int font_size; + SDL_Color color; + long timer; + long timeout; + SDL_Rect msg_pos; + SDL_Rect rect; + std::string msg; + SDL_Texture* texture; + std::string font; + //Load image at specified path + + rapidxml::file<> *hxmlFile; + rapidxml::xml_document<> hdoc; + rapidxml::xml_node<> *hpRoot; + rapidxml::xml_node<> *gNode; + rapidxml::xml_node<> *pNode; + TtfWrapper *render_msg; + }; + +} \ No newline at end of file diff --git a/NameMenus.cpp b/NameMenus.cpp new file mode 100644 index 0000000..69bdb63 --- /dev/null +++ b/NameMenus.cpp @@ -0,0 +1,121 @@ +#include "NameMenus.h" +#include "SDL_include.h" +using namespace widgets; + +NameMenus::NameMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool &mini) +{ + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + SDL_Color color; + color.a = 255; + color.b = 0; + color.g = 0; + color.r = 0; + visible = false; + + std::string xmlpath = "assets//xml//name_menu_config.xml"; + std::string xmltype = "name"; + hxmlFile = new rapidxml::file<>(xmlpath.c_str()); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node(xmltype.c_str()); + } + else{ + pNode = hpRoot->first_node("config")->first_node(xmltype.c_str()); + } + for (rapidxml::xml_node<> *bNode = pNode->first_node("textedit"); bNode; bNode = bNode->next_sibling("textedit")) + { + text_edits.push_back(TextEdit( + rect.x + atoi(bNode->first_node("pos")->first_node("x")->value()), + rect.y + atoi(bNode->first_node("pos")->first_node("y")->value()), + atoi(bNode->first_node("pos")->first_node("w")->value()), + atoi(bNode->first_node("pos")->first_node("h")->value()), + 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color, + pNode->first_node("font")->value(), + atoi(pNode->first_node("fontsize")->value()), + false)); + } + + for (rapidxml::xml_node<> *bNode = pNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")) + { + controls.push_back(MeguButton( + rect.x + atoi(bNode->first_node("pos")->first_node("x")->value()), + rect.y + atoi(bNode->first_node("pos")->first_node("y")->value()), + atoi(bNode->first_node("pos")->first_node("w")->value()), + atoi(bNode->first_node("pos")->first_node("h")->value()), NULL, true)); + } +} + +NameMenus::~NameMenus() +{ +} + +void NameMenus::disableMenu(){ + visible = false; + controls[0].setEnable(true); + controls[0].setVisible(true); + controls[1].setEnable(false); + controls[1].setVisible(false); + for (std::vector::iterator te_it = text_edits.begin(); te_it != text_edits.end(); ++te_it){ + te_it->setFocus(false); + te_it->setVisible(false); + } +} + +void NameMenus::callMenu(){ + visible = true; + controls[0].setEnable(true); + controls[0].setVisible(true);; + controls[1].setEnable(true); + controls[1].setVisible(true); + for (std::vector::iterator te_it = text_edits.begin(); te_it != text_edits.end(); ++te_it){ + te_it->setVisible(true); + } +} +void NameMenus::Render(SDL_Renderer *renderer) +{ + if (visible){ + SDL_RenderCopy(renderer, texture, NULL, &rect); + controls[0].Render(renderer); + controls[1].Render(renderer); + for (std::vector::iterator te_it = text_edits.begin(); te_it != text_edits.end(); ++te_it){ + if (te_it->getText().empty()){ + } + else{ + te_it->loadFromRenderedText(renderer); + te_it->Render(renderer); + } + } + } +} + +SDL_Texture* NameMenus::loadTexture(std::string path, SDL_Renderer *renderer) +{ + //The final texture + SDL_Texture* newTexture = NULL; + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + + return newTexture; +} \ No newline at end of file diff --git a/NameMenus.h b/NameMenus.h new file mode 100644 index 0000000..dafa28e --- /dev/null +++ b/NameMenus.h @@ -0,0 +1,35 @@ +#pragma once +#include "MeguMenus.h" +#include "MeguButton.h" +#include "SDL_include.h" +#include"Items_library.h" +#include +#include "TextEdit.h" +namespace widgets{ + class NameMenus + { + typedef int ID; + public: + NameMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool &mini); + ~NameMenus(); + void disableMenu(); + void callMenu(); + void Render(SDL_Renderer *renderer); + widgets::button_container controls; + std::vector text_edits; + protected: + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + bool visible; + SDL_Rect rect; + SDL_Texture *texture; + rapidxml::file<> *hxmlFile; + rapidxml::xml_document<> hdoc; + rapidxml::xml_node<> *hpRoot; + rapidxml::xml_node<> *pNode; + rapidxml::xml_node<> *sNode; + rapidxml::xml_node<> *dNode; + rapidxml::xml_node<> *nNode; + rapidxml::xml_node<> *overlayNode; + + }; +} diff --git a/OptionsMenus.cpp b/OptionsMenus.cpp new file mode 100644 index 0000000..1b4b75c --- /dev/null +++ b/OptionsMenus.cpp @@ -0,0 +1,177 @@ +#include "OptionsMenus.h" +#include "SDL_include.h" +using namespace widgets; + +OptionsMenus::OptionsMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool &mini) +{ + + msg_on = true; + bgm_level = 5; + sfx_level = 5; + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + SDL_Color color; + color.a = 255; + color.b = 0; + color.g = 0; + color.r = 0; + visible = false; + std::string xmlpath = "assets//xml//options_menu_config.xml"; + std::string xmltype = "options"; + rapidxml::file<>* hxmlFile; + hxmlFile = new rapidxml::file<>(xmlpath.c_str()); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node(xmltype.c_str()); + } + else{ + pNode = hpRoot->first_node("config")->first_node(xmltype.c_str()); + } + //option buttons + + + for (rapidxml::xml_node<> *dNode = pNode->first_node("slot"); dNode; dNode = dNode->next_sibling("slot")){ + option_buttons.push_back(MeguButton(rect.x + atoi(dNode->first_node("pos")->first_node("x")->value()), rect.y + atoi(dNode->first_node("pos")->first_node("y")->value()), atoi(dNode->first_node("pos")->first_node("w")->value()), atoi(dNode->first_node("pos")->first_node("h")->value()), NULL, true)); + } + //control buttons aka back button + for (rapidxml::xml_node<> *dNode = pNode->first_node("buttons"); dNode; dNode = dNode->next_sibling("buttons")){ + controls.push_back(MeguButton(rect.x + atoi(dNode->first_node("pos")->first_node("x")->value()), rect.y + atoi(dNode->first_node("pos")->first_node("y")->value()), atoi(dNode->first_node("pos")->first_node("w")->value()), atoi(dNode->first_node("pos")->first_node("h")->value()), NULL, true)); + } + bgm_marker_pos.x = atoi(pNode->first_node("bgm_marker_pos")->first_node("pos")->first_node("x")->value()); + bgm_marker_pos.y = atoi(pNode->first_node("bgm_marker_pos")->first_node("pos")->first_node("y")->value()); + bgm_marker_offset = atoi(pNode->first_node("bgm_marker_pos")->first_node("offset")->first_node("x")->value()); + bgm_marker_cd.w = atoi(pNode->first_node("marker")->first_node("size")->first_node("w")->value()); + bgm_marker_cd.h = atoi(pNode->first_node("marker")->first_node("size")->first_node("h")->value()); + + sfx_marker_pos.x = atoi(pNode->first_node("sfx_marker_pos")->first_node("pos")->first_node("x")->value()); + sfx_marker_pos.y = atoi(pNode->first_node("sfx_marker_pos")->first_node("pos")->first_node("y")->value()); + sfx_marker_offset = atoi(pNode->first_node("sfx_marker_pos")->first_node("offset")->first_node("x")->value()); + sfx_marker_cd.w = atoi(pNode->first_node("marker")->first_node("size")->first_node("w")->value()); + sfx_marker_cd.h = atoi(pNode->first_node("marker")->first_node("size")->first_node("h")->value()); + + msg_on_pos.h = sfx_marker_cd.h; + msg_on_pos.w = sfx_marker_cd.w; + marker = loadTexture(pNode->first_node("marker")->first_node("texture")->value(), renderer); + +} + +void OptionsMenus::RenderButtons(SDL_Renderer *renderer) +{ +} + +OptionsMenus::~OptionsMenus() +{ +} +void OptionsMenus::setBGMLevel(const int&bgm){ + if (bgm < 6 && bgm > -1){ + bgm_level = bgm; + } +} +void OptionsMenus::setSFXLevel(const int&sfx){ + if (sfx < 6 && sfx > -1){ + sfx_level = sfx; + } +} +void OptionsMenus::setMSGOn(const bool&msg){ + msg_on = msg; +} +int OptionsMenus::getBGMLevel() +{ + return bgm_level; +} +int OptionsMenus::getSFXLevel(){ + return sfx_level; +} +bool OptionsMenus::getMSGOn(){ + return msg_on; + +} +void OptionsMenus::updateMarkers(){ + bgm_marker_cd.x = bgm_marker_pos.x + bgm_level*bgm_marker_offset; + bgm_marker_cd.y = bgm_marker_pos.y; + sfx_marker_cd.x = sfx_marker_pos.x + sfx_level*sfx_marker_offset; + sfx_marker_cd.y = sfx_marker_pos.y; + +} +SDL_Texture* OptionsMenus::loadTexture(std::string path, SDL_Renderer *renderer) +{ + //The final texture + SDL_Texture* newTexture = NULL; + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + + return newTexture; +} + + +void OptionsMenus::disableMenu(){ + visible = false; + + for (widgets::button_container::iterator it = option_buttons.begin(); it != option_buttons.end(); ++it){ + it->setVisible(false); + } + for (widgets::button_container::iterator it = controls.begin(); it != controls.end(); ++it){ + it->setVisible(false); + it->setEnable(false); + } +} + +void OptionsMenus::callMenu(){ + visible = true; + updateMarkers(); + for (widgets::button_container::iterator it = option_buttons.begin(); it != option_buttons.end(); ++it){ + it->setVisible(true); + } + + for (widgets::button_container::iterator it = controls.begin(); it != controls.end(); ++it){ + it->setVisible(true); + it->setEnable(true); + } + +} +void OptionsMenus::Render(SDL_Renderer *renderer) +{ + if (visible){ + SDL_RenderCopy(renderer, texture, NULL, &rect); + for (widgets::button_container::iterator it = option_buttons.begin(); it != option_buttons.end(); ++it){ + it->Render(renderer); + } + for (widgets::button_container::iterator it = controls.begin(); it != controls.end(); ++it){ + it->Render(renderer); + } + + if (msg_on){ + msg_on_pos.x = option_buttons[4].getX(); + msg_on_pos.y = option_buttons[4].getY(); + SDL_RenderCopy(renderer, marker, 0, &msg_on_pos); + } + else{ + msg_on_pos.x = option_buttons[5].getX(); + msg_on_pos.y = option_buttons[5].getY(); + SDL_RenderCopy(renderer, marker, 0, &msg_on_pos); + } + SDL_RenderCopy(renderer, marker, 0, &bgm_marker_cd); + SDL_RenderCopy(renderer, marker, 0, &sfx_marker_cd); + } +} \ No newline at end of file diff --git a/OptionsMenus.h b/OptionsMenus.h new file mode 100644 index 0000000..eed936e --- /dev/null +++ b/OptionsMenus.h @@ -0,0 +1,58 @@ +#pragma once +#include "MeguMenus.h" +#include "MeguButton.h" +#include "SDL_include.h" +#include"Items_library.h" +#include +#include +#include +namespace widgets{ + class OptionsMenus + { + typedef std::vector button_container; + + public: + OptionsMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool &mini); + void loadSelectorTexture(const std::string &filename); + void RenderButtons(SDL_Renderer *renderer); + void disableMenu(); + void callMenu(); + void Render(SDL_Renderer *renderer); + int getBGMLevel(); + int getSFXLevel(); + bool getMSGOn(); + void setBGMLevel(const int&bgm); + void setSFXLevel(const int&sfx); + void setMSGOn(const bool&msg); + void updateMarkers(); + ~OptionsMenus(); + button_container option_buttons; + button_container controls; + protected: + SDL_Rect bgm_marker_cd; + SDL_Rect bgm_marker_pos; + int bgm_marker_offset; + SDL_Rect sfx_marker_cd; + SDL_Rect sfx_marker_pos; + int sfx_marker_offset; + int bgm_level; + int sfx_level; + bool msg_on; + SDL_Texture* marker; + SDL_Rect msg_on_pos; + + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + SDL_Texture* texture; + SDL_Rect rect; + //Load image at specified path + bool visible;//if yes then render/do stuff + rapidxml::file<> *hxmlFile; + rapidxml::xml_document<> hdoc; + rapidxml::xml_node<> *hpRoot; + rapidxml::xml_node<> *pNode; + rapidxml::xml_node<> *sNode; + rapidxml::xml_node<> *dNode; + rapidxml::xml_node<> *nNode; + rapidxml::xml_node<> *overlayNode; + }; +} diff --git a/PetMenus.cpp b/PetMenus.cpp new file mode 100644 index 0000000..58eb4f5 --- /dev/null +++ b/PetMenus.cpp @@ -0,0 +1,164 @@ +#include "PetMenus.h" +#include "SDL_include.h" +using namespace widgets; + +PetMenus::PetMenus(const int &x, const int &y, const int &width, const int &height, std::map *_library, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool &mini) +{ + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + visible = false; + library = _library; + SDL_Color color; + color.a = 255; + color.b = 0; + color.g = 0; + color.r = 0; + current_classification = "megu"; + std::string xmlpath = "assets//xml//megutate_menu_config.xml"; + std::string xmltype = "megutate"; + hxmlFile = new rapidxml::file<>(xmlpath.c_str()); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + if (!mini){ + pNode = hpRoot->last_node("config")->first_node(xmltype.c_str()); + } + else{ + pNode = hpRoot->first_node("config")->first_node(xmltype.c_str()); + } + sNode = pNode->first_node("slots"); + nNode = pNode->first_node("slot_name"); + dNode = pNode->first_node("slot_description"); + for (int i = 0; i < 3; ++i){ + slots.push_back(MeguButton(rect.x + atoi(sNode->first_node("pos")->first_node("x")->value()), + rect.y + i * atoi(sNode->first_node("offset")->first_node("y")->value()) + atoi(sNode->first_node("pos")->first_node("y")->value()), + atoi(sNode->first_node("pos")->first_node("w")->value()), + atoi(sNode->first_node("pos")->first_node("h")->value()), NULL, false)); + + slots_name.push_back(TtfWrapper(rect.x + atoi(nNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(nNode->first_node("offset")->first_node("y")->value()) + atoi(nNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(nNode->first_node("font_size")->value()) + , nNode->first_node("font")->value() + , 150 + , false) + ); + + + slots_description.push_back(TtfWrapper(rect.x + atoi(dNode->first_node("pos")->first_node("x")->value()) + , rect.y + i * atoi(dNode->first_node("offset")->first_node("y")->value()) + atoi(dNode->first_node("pos")->first_node("y")->value()) + , 255, 255, 255, SDL_BLENDMODE_BLEND, 0, color + , atoi(dNode->first_node("font_size")->value()) + , nNode->first_node("font")->value() + , 150 + , false) + ); + + } + marker = loadTexture(pNode->first_node("marker")->first_node("texture")->value(), renderer); + marker_rect.w = atoi(pNode->first_node("marker")->first_node("size")->first_node("w")->value()); + marker_rect.h = atoi(pNode->first_node("marker")->first_node("size")->first_node("h")->value()); + marker_visible = false; + + for (rapidxml::xml_node<> *bNode = pNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")) + { + controls.push_back(MeguButton( + rect.x + atoi(bNode->first_node("pos")->first_node("x")->value()) + , rect.y + atoi(bNode->first_node("pos")->first_node("y")->value()) + , atoi(bNode->first_node("pos")->first_node("w")->value()) + , atoi(bNode->first_node("pos")->first_node("h")->value()) + , NULL + , true) + ); + } + int index = 0; + + //Load image at specified path +} + +void PetMenus::RenderButtons(SDL_Renderer *renderer) +{ + if (visible){ + if (marker_visible){ + SDL_RenderCopy(renderer, marker, NULL, &marker_rect); + } + } +} + + +PetMenus::~PetMenus() +{ +} + +void PetMenus::updateSlots(SDL_Renderer *renderer){ + //clean up first + for (int i = 0; i < 3; ++i){ + slots[i].changeObject(NULL); + slots[i].setEnable(false); + slots_name[i].free(); + slots_name[i].setVisible(false); + slots_description[i].free(); + slots_description[i].setVisible(false); + } + for (int i = 0; i < 3; ++i){ + unsigned int curr_index = current_page * 3 + i; + if (curr_index > id_library[current_classification].size() - 1){ + return; + } + else{ + int id = id_library[current_classification].at(curr_index); + int w, h; + SDL_QueryTexture(library->at(id).front_texture, NULL, NULL, &w, &h); + if (w > marker_rect.w){ + float ratio = (float)h / (float)w; + h = (int)(ratio * marker_rect.h); + w = marker_rect.w; + } + if (h > marker_rect.h){ + float ratio = (float)w / (float)h; + w = (int)(ratio * marker_rect.h); + h = marker_rect.h; + } + slots[i].changeDisplayObject((library->at(id).front_texture), w, h, id); + slots[i].setEnable(true); + slots_name[i].setText(library->at(id).en_name); + slots_name[i].loadFromRenderedText(renderer); + slots_name[i].setVisible(true); + std::string detail; + + slots_description[i].setText(library->at(id).en_detail); + slots_description[i].loadFromRenderedText(renderer); + slots_description[i].setVisible(true); + } + } + +} +SDL_Texture* PetMenus::loadTexture(std::string path, SDL_Renderer *renderer) +{ + //The final texture + SDL_Texture* newTexture = NULL; + + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + + return newTexture; +} diff --git a/PetMenus.h b/PetMenus.h new file mode 100644 index 0000000..3da9fd9 --- /dev/null +++ b/PetMenus.h @@ -0,0 +1,30 @@ +#pragma once +#include "MeguMenus.h" +#include "MeguButton.h" +#include "SDL_include.h" +#include"Items_library.h" +#include +namespace widgets{ + class PetMenus : + public MeguMenus + { + typedef int ID; + public: + PetMenus(const int &x, const int &y, const int &width, const int &height, std::map *_library, SDL_Texture *newtexture, SDL_Renderer *renderer, const bool &mini); + void loadSelectorTexture(const std::string &filename); + void RenderButtons(SDL_Renderer *renderer); + void updateSlots(SDL_Renderer *renderer); + ~PetMenus(); + std::string isInDisplay(int x, int y); + SDL_Texture *marker; + SDL_Rect marker_rect; + bool marker_visible; + protected: + std::map *library; + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + SDL_Texture *buttons_overlay; + SDL_Rect overlay_pos; + + + }; +} diff --git a/SDL_image.h b/SDL_image.h new file mode 100644 index 0000000..57a773d --- /dev/null +++ b/SDL_image.h @@ -0,0 +1,145 @@ +/* + SDL_image: An example image loading library for use with SDL + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* A simple library to load images of various formats as SDL surfaces */ + +#ifndef _SDL_IMAGE_H +#define _SDL_IMAGE_H + +#include +#include +#include + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL +*/ +#define SDL_IMAGE_MAJOR_VERSION 2 +#define SDL_IMAGE_MINOR_VERSION 0 +#define SDL_IMAGE_PATCHLEVEL 0 + +/* This macro can be used to fill a version structure with the compile-time + * version of the SDL_image library. + */ +#define SDL_IMAGE_VERSION(X) \ +{ \ + (X)->major = SDL_IMAGE_MAJOR_VERSION; \ + (X)->minor = SDL_IMAGE_MINOR_VERSION; \ + (X)->patch = SDL_IMAGE_PATCHLEVEL; \ +} + +/* This function gets the version of the dynamically linked SDL_image library. + it should NOT be used to fill a version structure, instead you should + use the SDL_IMAGE_VERSION() macro. + */ +extern DECLSPEC const SDL_version * SDLCALL IMG_Linked_Version(void); + +typedef enum +{ + IMG_INIT_JPG = 0x00000001, + IMG_INIT_PNG = 0x00000002, + IMG_INIT_TIF = 0x00000004, + IMG_INIT_WEBP = 0x00000008 +} IMG_InitFlags; + +/* Loads dynamic libraries and prepares them for use. Flags should be + one or more flags from IMG_InitFlags OR'd together. + It returns the flags successfully initialized, or 0 on failure. + */ +extern DECLSPEC int SDLCALL IMG_Init(int flags); + +/* Unloads libraries loaded with IMG_Init */ +extern DECLSPEC void SDLCALL IMG_Quit(void); + +/* Load an image from an SDL data source. + The 'type' may be one of: "BMP", "GIF", "PNG", etc. + + If the image format supports a transparent pixel, SDL will set the + colorkey for the surface. You can enable RLE acceleration on the + surface afterwards by calling: + SDL_SetColorKey(image, SDL_RLEACCEL, image->format->colorkey); + */ +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadTyped_RW(SDL_RWops *src, int freesrc, const char *type); +/* Convenience functions */ +extern DECLSPEC SDL_Surface * SDLCALL IMG_Load(const char *file); +extern DECLSPEC SDL_Surface * SDLCALL IMG_Load_RW(SDL_RWops *src, int freesrc); + +#if SDL_VERSION_ATLEAST(2,0,0) +/* Load an image directly into a render texture. + */ +extern DECLSPEC SDL_Texture * SDLCALL IMG_LoadTexture(SDL_Renderer *renderer, const char *file); +extern DECLSPEC SDL_Texture * SDLCALL IMG_LoadTexture_RW(SDL_Renderer *renderer, SDL_RWops *src, int freesrc); +extern DECLSPEC SDL_Texture * SDLCALL IMG_LoadTextureTyped_RW(SDL_Renderer *renderer, SDL_RWops *src, int freesrc, const char *type); +#endif /* SDL 2.0 */ + +/* Functions to detect a file type, given a seekable source */ +extern DECLSPEC int SDLCALL IMG_isICO(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isCUR(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isBMP(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isGIF(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isJPG(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isLBM(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isPCX(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isPNG(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isPNM(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isTIF(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isXCF(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isXPM(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isXV(SDL_RWops *src); +extern DECLSPEC int SDLCALL IMG_isWEBP(SDL_RWops *src); + +/* Individual loading functions */ +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadICO_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadCUR_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadBMP_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadGIF_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadJPG_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadLBM_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadPCX_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadPNG_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadPNM_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadTGA_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadTIF_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadXCF_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadXPM_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadXV_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadWEBP_RW(SDL_RWops *src); + +extern DECLSPEC SDL_Surface * SDLCALL IMG_ReadXPMFromArray(char **xpm); + +/* Individual saving functions */ +extern DECLSPEC int SDLCALL IMG_SavePNG(SDL_Surface *surface, const char *file); +extern DECLSPEC int SDLCALL IMG_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst); + +/* We'll use SDL for reporting errors */ +#define IMG_SetError SDL_SetError +#define IMG_GetError SDL_GetError + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include + +#endif /* _SDL_IMAGE_H */ diff --git a/SDL_include.h b/SDL_include.h new file mode 100644 index 0000000..f7df42a --- /dev/null +++ b/SDL_include.h @@ -0,0 +1,12 @@ +#pragma once +#ifdef __APPLE__ +#include "SDL_include.h" +#include +#include +#include +#elif _WIN32 +#include +#include +#include +#include +#endif \ No newline at end of file diff --git a/SDL_mixer.h b/SDL_mixer.h new file mode 100644 index 0000000..465d280 --- /dev/null +++ b/SDL_mixer.h @@ -0,0 +1,631 @@ +/* + SDL_mixer: An audio mixer library based on the SDL library + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* $Id$ */ + +#ifndef _SDL_MIXER_H +#define _SDL_MIXER_H + +#include +#include +#include +#include +#include +#include + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL +*/ +#define SDL_MIXER_MAJOR_VERSION 2 +#define SDL_MIXER_MINOR_VERSION 0 +#define SDL_MIXER_PATCHLEVEL 0 + +/* This macro can be used to fill a version structure with the compile-time + * version of the SDL_mixer library. + */ +#define SDL_MIXER_VERSION(X) \ +{ \ + (X)->major = SDL_MIXER_MAJOR_VERSION; \ + (X)->minor = SDL_MIXER_MINOR_VERSION; \ + (X)->patch = SDL_MIXER_PATCHLEVEL; \ +} + +/* Backwards compatibility */ +#define MIX_MAJOR_VERSION SDL_MIXER_MAJOR_VERSION +#define MIX_MINOR_VERSION SDL_MIXER_MINOR_VERSION +#define MIX_PATCHLEVEL SDL_MIXER_PATCHLEVEL +#define MIX_VERSION(X) SDL_MIXER_VERSION(X) + +/* This function gets the version of the dynamically linked SDL_mixer library. + it should NOT be used to fill a version structure, instead you should + use the SDL_MIXER_VERSION() macro. + */ +extern DECLSPEC const SDL_version * SDLCALL Mix_Linked_Version(void); + +typedef enum +{ + MIX_INIT_FLAC = 0x00000001, + MIX_INIT_MOD = 0x00000002, + MIX_INIT_MODPLUG = 0x00000004, + MIX_INIT_MP3 = 0x00000008, + MIX_INIT_OGG = 0x00000010, + MIX_INIT_FLUIDSYNTH = 0x00000020 +} MIX_InitFlags; + +/* Loads dynamic libraries and prepares them for use. Flags should be + one or more flags from MIX_InitFlags OR'd together. + It returns the flags successfully initialized, or 0 on failure. + */ +extern DECLSPEC int SDLCALL Mix_Init(int flags); + +/* Unloads libraries loaded with Mix_Init */ +extern DECLSPEC void SDLCALL Mix_Quit(void); + + +/* The default mixer has 8 simultaneous mixing channels */ +#ifndef MIX_CHANNELS +#define MIX_CHANNELS 8 +#endif + +/* Good default values for a PC soundcard */ +#define MIX_DEFAULT_FREQUENCY 22050 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define MIX_DEFAULT_FORMAT AUDIO_S16LSB +#else +#define MIX_DEFAULT_FORMAT AUDIO_S16MSB +#endif +#define MIX_DEFAULT_CHANNELS 2 +#define MIX_MAX_VOLUME 128 /* Volume of a chunk */ + +/* The internal format for an audio chunk */ +typedef struct Mix_Chunk { + int allocated; + Uint8 *abuf; + Uint32 alen; + Uint8 volume; /* Per-sample volume, 0-128 */ +} Mix_Chunk; + +/* The different fading types supported */ +typedef enum { + MIX_NO_FADING, + MIX_FADING_OUT, + MIX_FADING_IN +} Mix_Fading; + +typedef enum { + MUS_NONE, + MUS_CMD, + MUS_WAV, + MUS_MOD, + MUS_MID, + MUS_OGG, + MUS_MP3, + MUS_MP3_MAD, + MUS_FLAC, + MUS_MODPLUG +} Mix_MusicType; + +/* The internal format for a music chunk interpreted via mikmod */ +typedef struct _Mix_Music Mix_Music; + +/* Open the mixer with a certain audio format */ +extern DECLSPEC int SDLCALL Mix_OpenAudio(int frequency, Uint16 format, int channels, int chunksize); + +/* Dynamically change the number of channels managed by the mixer. + If decreasing the number of channels, the upper channels are + stopped. + This function returns the new number of allocated channels. + */ +extern DECLSPEC int SDLCALL Mix_AllocateChannels(int numchans); + +/* Find out what the actual audio device parameters are. + This function returns 1 if the audio has been opened, 0 otherwise. + */ +extern DECLSPEC int SDLCALL Mix_QuerySpec(int *frequency,Uint16 *format,int *channels); + +/* Load a wave file or a music (.mod .s3m .it .xm) file */ +extern DECLSPEC Mix_Chunk * SDLCALL Mix_LoadWAV_RW(SDL_RWops *src, int freesrc); +#define Mix_LoadWAV(file) Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1) +extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUS(const char *file); + +/* Load a music file from an SDL_RWop object (Ogg and MikMod specific currently) + Matt Campbell (matt@campbellhome.dhs.org) April 2000 */ +extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUS_RW(SDL_RWops *src, int freesrc); + +/* Load a music file from an SDL_RWop object assuming a specific format */ +extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUSType_RW(SDL_RWops *src, Mix_MusicType type, int freesrc); + +/* Load a wave file of the mixer format from a memory buffer */ +extern DECLSPEC Mix_Chunk * SDLCALL Mix_QuickLoad_WAV(Uint8 *mem); + +/* Load raw audio data of the mixer format from a memory buffer */ +extern DECLSPEC Mix_Chunk * SDLCALL Mix_QuickLoad_RAW(Uint8 *mem, Uint32 len); + +/* Free an audio chunk previously loaded */ +extern DECLSPEC void SDLCALL Mix_FreeChunk(Mix_Chunk *chunk); +extern DECLSPEC void SDLCALL Mix_FreeMusic(Mix_Music *music); + +/* Get a list of chunk/music decoders that this build of SDL_mixer provides. + This list can change between builds AND runs of the program, if external + libraries that add functionality become available. + You must successfully call Mix_OpenAudio() before calling these functions. + This API is only available in SDL_mixer 1.2.9 and later. + + // usage... + int i; + const int total = Mix_GetNumChunkDecoders(); + for (i = 0; i < total; i++) + printf("Supported chunk decoder: [%s]\n", Mix_GetChunkDecoder(i)); + + Appearing in this list doesn't promise your specific audio file will + decode...but it's handy to know if you have, say, a functioning Timidity + install. + + These return values are static, read-only data; do not modify or free it. + The pointers remain valid until you call Mix_CloseAudio(). +*/ +extern DECLSPEC int SDLCALL Mix_GetNumChunkDecoders(void); +extern DECLSPEC const char * SDLCALL Mix_GetChunkDecoder(int index); +extern DECLSPEC int SDLCALL Mix_GetNumMusicDecoders(void); +extern DECLSPEC const char * SDLCALL Mix_GetMusicDecoder(int index); + +/* Find out the music format of a mixer music, or the currently playing + music, if 'music' is NULL. +*/ +extern DECLSPEC Mix_MusicType SDLCALL Mix_GetMusicType(const Mix_Music *music); + +/* Set a function that is called after all mixing is performed. + This can be used to provide real-time visual display of the audio stream + or add a custom mixer filter for the stream data. +*/ +extern DECLSPEC void SDLCALL Mix_SetPostMix(void (*mix_func)(void *udata, Uint8 *stream, int len), void *arg); + +/* Add your own music player or additional mixer function. + If 'mix_func' is NULL, the default music player is re-enabled. + */ +extern DECLSPEC void SDLCALL Mix_HookMusic(void (*mix_func)(void *udata, Uint8 *stream, int len), void *arg); + +/* Add your own callback when the music has finished playing. + This callback is only called if the music finishes naturally. + */ +extern DECLSPEC void SDLCALL Mix_HookMusicFinished(void (*music_finished)(void)); + +/* Get a pointer to the user data for the current music hook */ +extern DECLSPEC void * SDLCALL Mix_GetMusicHookData(void); + +/* + * Add your own callback when a channel has finished playing. NULL + * to disable callback. The callback may be called from the mixer's audio + * callback or it could be called as a result of Mix_HaltChannel(), etc. + * do not call SDL_LockAudio() from this callback; you will either be + * inside the audio callback, or SDL_mixer will explicitly lock the audio + * before calling your callback. + */ +extern DECLSPEC void SDLCALL Mix_ChannelFinished(void (*channel_finished)(int channel)); + + +/* Special Effects API by ryan c. gordon. (icculus@icculus.org) */ + +#define MIX_CHANNEL_POST -2 + +/* This is the format of a special effect callback: + * + * myeffect(int chan, void *stream, int len, void *udata); + * + * (chan) is the channel number that your effect is affecting. (stream) is + * the buffer of data to work upon. (len) is the size of (stream), and + * (udata) is a user-defined bit of data, which you pass as the last arg of + * Mix_RegisterEffect(), and is passed back unmolested to your callback. + * Your effect changes the contents of (stream) based on whatever parameters + * are significant, or just leaves it be, if you prefer. You can do whatever + * you like to the buffer, though, and it will continue in its changed state + * down the mixing pipeline, through any other effect functions, then finally + * to be mixed with the rest of the channels and music for the final output + * stream. + * + * DO NOT EVER call SDL_LockAudio() from your callback function! + */ +typedef void (*Mix_EffectFunc_t)(int chan, void *stream, int len, void *udata); + +/* + * This is a callback that signifies that a channel has finished all its + * loops and has completed playback. This gets called if the buffer + * plays out normally, or if you call Mix_HaltChannel(), implicitly stop + * a channel via Mix_AllocateChannels(), or unregister a callback while + * it's still playing. + * + * DO NOT EVER call SDL_LockAudio() from your callback function! + */ +typedef void (*Mix_EffectDone_t)(int chan, void *udata); + + +/* Register a special effect function. At mixing time, the channel data is + * copied into a buffer and passed through each registered effect function. + * After it passes through all the functions, it is mixed into the final + * output stream. The copy to buffer is performed once, then each effect + * function performs on the output of the previous effect. Understand that + * this extra copy to a buffer is not performed if there are no effects + * registered for a given chunk, which saves CPU cycles, and any given + * effect will be extra cycles, too, so it is crucial that your code run + * fast. Also note that the data that your function is given is in the + * format of the sound device, and not the format you gave to Mix_OpenAudio(), + * although they may in reality be the same. This is an unfortunate but + * necessary speed concern. Use Mix_QuerySpec() to determine if you can + * handle the data before you register your effect, and take appropriate + * actions. + * You may also specify a callback (Mix_EffectDone_t) that is called when + * the channel finishes playing. This gives you a more fine-grained control + * than Mix_ChannelFinished(), in case you need to free effect-specific + * resources, etc. If you don't need this, you can specify NULL. + * You may set the callbacks before or after calling Mix_PlayChannel(). + * Things like Mix_SetPanning() are just internal special effect functions, + * so if you are using that, you've already incurred the overhead of a copy + * to a separate buffer, and that these effects will be in the queue with + * any functions you've registered. The list of registered effects for a + * channel is reset when a chunk finishes playing, so you need to explicitly + * set them with each call to Mix_PlayChannel*(). + * You may also register a special effect function that is to be run after + * final mixing occurs. The rules for these callbacks are identical to those + * in Mix_RegisterEffect, but they are run after all the channels and the + * music have been mixed into a single stream, whereas channel-specific + * effects run on a given channel before any other mixing occurs. These + * global effect callbacks are call "posteffects". Posteffects only have + * their Mix_EffectDone_t function called when they are unregistered (since + * the main output stream is never "done" in the same sense as a channel). + * You must unregister them manually when you've had enough. Your callback + * will be told that the channel being mixed is (MIX_CHANNEL_POST) if the + * processing is considered a posteffect. + * + * After all these effects have finished processing, the callback registered + * through Mix_SetPostMix() runs, and then the stream goes to the audio + * device. + * + * DO NOT EVER call SDL_LockAudio() from your callback function! + * + * returns zero if error (no such channel), nonzero if added. + * Error messages can be retrieved from Mix_GetError(). + */ +extern DECLSPEC int SDLCALL Mix_RegisterEffect(int chan, Mix_EffectFunc_t f, Mix_EffectDone_t d, void *arg); + + +/* You may not need to call this explicitly, unless you need to stop an + * effect from processing in the middle of a chunk's playback. + * Posteffects are never implicitly unregistered as they are for channels, + * but they may be explicitly unregistered through this function by + * specifying MIX_CHANNEL_POST for a channel. + * returns zero if error (no such channel or effect), nonzero if removed. + * Error messages can be retrieved from Mix_GetError(). + */ +extern DECLSPEC int SDLCALL Mix_UnregisterEffect(int channel, Mix_EffectFunc_t f); + + +/* You may not need to call this explicitly, unless you need to stop all + * effects from processing in the middle of a chunk's playback. Note that + * this will also shut off some internal effect processing, since + * Mix_SetPanning() and others may use this API under the hood. This is + * called internally when a channel completes playback. + * Posteffects are never implicitly unregistered as they are for channels, + * but they may be explicitly unregistered through this function by + * specifying MIX_CHANNEL_POST for a channel. + * returns zero if error (no such channel), nonzero if all effects removed. + * Error messages can be retrieved from Mix_GetError(). + */ +extern DECLSPEC int SDLCALL Mix_UnregisterAllEffects(int channel); + + +#define MIX_EFFECTSMAXSPEED "MIX_EFFECTSMAXSPEED" + +/* + * These are the internally-defined mixing effects. They use the same API that + * effects defined in the application use, but are provided here as a + * convenience. Some effects can reduce their quality or use more memory in + * the name of speed; to enable this, make sure the environment variable + * MIX_EFFECTSMAXSPEED (see above) is defined before you call + * Mix_OpenAudio(). + */ + + +/* Set the panning of a channel. The left and right channels are specified + * as integers between 0 and 255, quietest to loudest, respectively. + * + * Technically, this is just individual volume control for a sample with + * two (stereo) channels, so it can be used for more than just panning. + * If you want real panning, call it like this: + * + * Mix_SetPanning(channel, left, 255 - left); + * + * ...which isn't so hard. + * + * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and + * the panning will be done to the final mixed stream before passing it on + * to the audio device. + * + * This uses the Mix_RegisterEffect() API internally, and returns without + * registering the effect function if the audio device is not configured + * for stereo output. Setting both (left) and (right) to 255 causes this + * effect to be unregistered, since that is the data's normal state. + * + * returns zero if error (no such channel or Mix_RegisterEffect() fails), + * nonzero if panning effect enabled. Note that an audio device in mono + * mode is a no-op, but this call will return successful in that case. + * Error messages can be retrieved from Mix_GetError(). + */ +extern DECLSPEC int SDLCALL Mix_SetPanning(int channel, Uint8 left, Uint8 right); + + +/* Set the position of a channel. (angle) is an integer from 0 to 360, that + * specifies the location of the sound in relation to the listener. (angle) + * will be reduced as neccesary (540 becomes 180 degrees, -100 becomes 260). + * Angle 0 is due north, and rotates clockwise as the value increases. + * For efficiency, the precision of this effect may be limited (angles 1 + * through 7 might all produce the same effect, 8 through 15 are equal, etc). + * (distance) is an integer between 0 and 255 that specifies the space + * between the sound and the listener. The larger the number, the further + * away the sound is. Using 255 does not guarantee that the channel will be + * culled from the mixing process or be completely silent. For efficiency, + * the precision of this effect may be limited (distance 0 through 5 might + * all produce the same effect, 6 through 10 are equal, etc). Setting (angle) + * and (distance) to 0 unregisters this effect, since the data would be + * unchanged. + * + * If you need more precise positional audio, consider using OpenAL for + * spatialized effects instead of SDL_mixer. This is only meant to be a + * basic effect for simple "3D" games. + * + * If the audio device is configured for mono output, then you won't get + * any effectiveness from the angle; however, distance attenuation on the + * channel will still occur. While this effect will function with stereo + * voices, it makes more sense to use voices with only one channel of sound, + * so when they are mixed through this effect, the positioning will sound + * correct. You can convert them to mono through SDL before giving them to + * the mixer in the first place if you like. + * + * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and + * the positioning will be done to the final mixed stream before passing it + * on to the audio device. + * + * This is a convenience wrapper over Mix_SetDistance() and Mix_SetPanning(). + * + * returns zero if error (no such channel or Mix_RegisterEffect() fails), + * nonzero if position effect is enabled. + * Error messages can be retrieved from Mix_GetError(). + */ +extern DECLSPEC int SDLCALL Mix_SetPosition(int channel, Sint16 angle, Uint8 distance); + + +/* Set the "distance" of a channel. (distance) is an integer from 0 to 255 + * that specifies the location of the sound in relation to the listener. + * Distance 0 is overlapping the listener, and 255 is as far away as possible + * A distance of 255 does not guarantee silence; in such a case, you might + * want to try changing the chunk's volume, or just cull the sample from the + * mixing process with Mix_HaltChannel(). + * For efficiency, the precision of this effect may be limited (distances 1 + * through 7 might all produce the same effect, 8 through 15 are equal, etc). + * (distance) is an integer between 0 and 255 that specifies the space + * between the sound and the listener. The larger the number, the further + * away the sound is. + * Setting (distance) to 0 unregisters this effect, since the data would be + * unchanged. + * If you need more precise positional audio, consider using OpenAL for + * spatialized effects instead of SDL_mixer. This is only meant to be a + * basic effect for simple "3D" games. + * + * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and + * the distance attenuation will be done to the final mixed stream before + * passing it on to the audio device. + * + * This uses the Mix_RegisterEffect() API internally. + * + * returns zero if error (no such channel or Mix_RegisterEffect() fails), + * nonzero if position effect is enabled. + * Error messages can be retrieved from Mix_GetError(). + */ +extern DECLSPEC int SDLCALL Mix_SetDistance(int channel, Uint8 distance); + + +/* + * !!! FIXME : Haven't implemented, since the effect goes past the + * end of the sound buffer. Will have to think about this. + * --ryan. + */ +#if 0 +/* Causes an echo effect to be mixed into a sound. (echo) is the amount + * of echo to mix. 0 is no echo, 255 is infinite (and probably not + * what you want). + * + * Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and + * the reverbing will be done to the final mixed stream before passing it on + * to the audio device. + * + * This uses the Mix_RegisterEffect() API internally. If you specify an echo + * of zero, the effect is unregistered, as the data is already in that state. + * + * returns zero if error (no such channel or Mix_RegisterEffect() fails), + * nonzero if reversing effect is enabled. + * Error messages can be retrieved from Mix_GetError(). + */ +extern no_parse_DECLSPEC int SDLCALL Mix_SetReverb(int channel, Uint8 echo); +#endif + +/* Causes a channel to reverse its stereo. This is handy if the user has his + * speakers hooked up backwards, or you would like to have a minor bit of + * psychedelia in your sound code. :) Calling this function with (flip) + * set to non-zero reverses the chunks's usual channels. If (flip) is zero, + * the effect is unregistered. + * + * This uses the Mix_RegisterEffect() API internally, and thus is probably + * more CPU intensive than having the user just plug in his speakers + * correctly. Mix_SetReverseStereo() returns without registering the effect + * function if the audio device is not configured for stereo output. + * + * If you specify MIX_CHANNEL_POST for (channel), then this the effect is used + * on the final mixed stream before sending it on to the audio device (a + * posteffect). + * + * returns zero if error (no such channel or Mix_RegisterEffect() fails), + * nonzero if reversing effect is enabled. Note that an audio device in mono + * mode is a no-op, but this call will return successful in that case. + * Error messages can be retrieved from Mix_GetError(). + */ +extern DECLSPEC int SDLCALL Mix_SetReverseStereo(int channel, int flip); + +/* end of effects API. --ryan. */ + + +/* Reserve the first channels (0 -> n-1) for the application, i.e. don't allocate + them dynamically to the next sample if requested with a -1 value below. + Returns the number of reserved channels. + */ +extern DECLSPEC int SDLCALL Mix_ReserveChannels(int num); + +/* Channel grouping functions */ + +/* Attach a tag to a channel. A tag can be assigned to several mixer + channels, to form groups of channels. + If 'tag' is -1, the tag is removed (actually -1 is the tag used to + represent the group of all the channels). + Returns true if everything was OK. + */ +extern DECLSPEC int SDLCALL Mix_GroupChannel(int which, int tag); +/* Assign several consecutive channels to a group */ +extern DECLSPEC int SDLCALL Mix_GroupChannels(int from, int to, int tag); +/* Finds the first available channel in a group of channels, + returning -1 if none are available. + */ +extern DECLSPEC int SDLCALL Mix_GroupAvailable(int tag); +/* Returns the number of channels in a group. This is also a subtle + way to get the total number of channels when 'tag' is -1 + */ +extern DECLSPEC int SDLCALL Mix_GroupCount(int tag); +/* Finds the "oldest" sample playing in a group of channels */ +extern DECLSPEC int SDLCALL Mix_GroupOldest(int tag); +/* Finds the "most recent" (i.e. last) sample playing in a group of channels */ +extern DECLSPEC int SDLCALL Mix_GroupNewer(int tag); + +/* Play an audio chunk on a specific channel. + If the specified channel is -1, play on the first free channel. + If 'loops' is greater than zero, loop the sound that many times. + If 'loops' is -1, loop inifinitely (~65000 times). + Returns which channel was used to play the sound. +*/ +#define Mix_PlayChannel(channel,chunk,loops) Mix_PlayChannelTimed(channel,chunk,loops,-1) +/* The same as above, but the sound is played at most 'ticks' milliseconds */ +extern DECLSPEC int SDLCALL Mix_PlayChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ticks); +extern DECLSPEC int SDLCALL Mix_PlayMusic(Mix_Music *music, int loops); + +/* Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions */ +extern DECLSPEC int SDLCALL Mix_FadeInMusic(Mix_Music *music, int loops, int ms); +extern DECLSPEC int SDLCALL Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position); +#define Mix_FadeInChannel(channel,chunk,loops,ms) Mix_FadeInChannelTimed(channel,chunk,loops,ms,-1) +extern DECLSPEC int SDLCALL Mix_FadeInChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ms, int ticks); + +/* Set the volume in the range of 0-128 of a specific channel or chunk. + If the specified channel is -1, set volume for all channels. + Returns the original volume. + If the specified volume is -1, just return the current volume. +*/ +extern DECLSPEC int SDLCALL Mix_Volume(int channel, int volume); +extern DECLSPEC int SDLCALL Mix_VolumeChunk(Mix_Chunk *chunk, int volume); +extern DECLSPEC int SDLCALL Mix_VolumeMusic(int volume); + +/* Halt playing of a particular channel */ +extern DECLSPEC int SDLCALL Mix_HaltChannel(int channel); +extern DECLSPEC int SDLCALL Mix_HaltGroup(int tag); +extern DECLSPEC int SDLCALL Mix_HaltMusic(void); + +/* Change the expiration delay for a particular channel. + The sample will stop playing after the 'ticks' milliseconds have elapsed, + or remove the expiration if 'ticks' is -1 +*/ +extern DECLSPEC int SDLCALL Mix_ExpireChannel(int channel, int ticks); + +/* Halt a channel, fading it out progressively till it's silent + The ms parameter indicates the number of milliseconds the fading + will take. + */ +extern DECLSPEC int SDLCALL Mix_FadeOutChannel(int which, int ms); +extern DECLSPEC int SDLCALL Mix_FadeOutGroup(int tag, int ms); +extern DECLSPEC int SDLCALL Mix_FadeOutMusic(int ms); + +/* Query the fading status of a channel */ +extern DECLSPEC Mix_Fading SDLCALL Mix_FadingMusic(void); +extern DECLSPEC Mix_Fading SDLCALL Mix_FadingChannel(int which); + +/* Pause/Resume a particular channel */ +extern DECLSPEC void SDLCALL Mix_Pause(int channel); +extern DECLSPEC void SDLCALL Mix_Resume(int channel); +extern DECLSPEC int SDLCALL Mix_Paused(int channel); + +/* Pause/Resume the music stream */ +extern DECLSPEC void SDLCALL Mix_PauseMusic(void); +extern DECLSPEC void SDLCALL Mix_ResumeMusic(void); +extern DECLSPEC void SDLCALL Mix_RewindMusic(void); +extern DECLSPEC int SDLCALL Mix_PausedMusic(void); + +/* Set the current position in the music stream. + This returns 0 if successful, or -1 if it failed or isn't implemented. + This function is only implemented for MOD music formats (set pattern + order number) and for OGG, FLAC, MP3_MAD, and MODPLUG music (set + position in seconds), at the moment. +*/ +extern DECLSPEC int SDLCALL Mix_SetMusicPosition(double position); + +/* Check the status of a specific channel. + If the specified channel is -1, check all channels. +*/ +extern DECLSPEC int SDLCALL Mix_Playing(int channel); +extern DECLSPEC int SDLCALL Mix_PlayingMusic(void); + +/* Stop music and set external music playback command */ +extern DECLSPEC int SDLCALL Mix_SetMusicCMD(const char *command); + +/* Synchro value is set by MikMod from modules while playing */ +extern DECLSPEC int SDLCALL Mix_SetSynchroValue(int value); +extern DECLSPEC int SDLCALL Mix_GetSynchroValue(void); + +/* Set/Get/Iterate SoundFonts paths to use by supported MIDI backends */ +extern DECLSPEC int SDLCALL Mix_SetSoundFonts(const char *paths); +extern DECLSPEC const char* SDLCALL Mix_GetSoundFonts(void); +extern DECLSPEC int SDLCALL Mix_EachSoundFont(int (*function)(const char*, void*), void *data); + +/* Get the Mix_Chunk currently associated with a mixer channel + Returns NULL if it's an invalid channel, or there's no chunk associated. +*/ +extern DECLSPEC Mix_Chunk * SDLCALL Mix_GetChunk(int channel); + +/* Close the mixer, halting all playing audio */ +extern DECLSPEC void SDLCALL Mix_CloseAudio(void); + +/* We'll use SDL for reporting errors */ +#define Mix_SetError SDL_SetError +#define Mix_GetError SDL_GetError + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include + +#endif /* _SDL_MIXER_H */ diff --git a/SizeMenus.cpp b/SizeMenus.cpp new file mode 100644 index 0000000..63a7808 --- /dev/null +++ b/SizeMenus.cpp @@ -0,0 +1,93 @@ +#include "SizeMenus.h" +#include "SDL_include.h" +using namespace widgets; + +SizeMenus::SizeMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer) +{ + rect.x = x; + rect.y = y; + rect.w = width; + rect.h = height; + texture = newtexture; + SDL_Color color; + color.a = 255; + color.b = 0; + color.g = 0; + color.r = 0; + visible = false; + + std::string xmlpath = "assets//xml//size_menu_config.xml"; + std::string xmltype = "size_selector"; + hxmlFile = new rapidxml::file<>(xmlpath.c_str()); // Default template is char + hdoc.parse<0>(hxmlFile->data()); + hpRoot = hdoc.first_node(); + + pNode = hpRoot->first_node("config")->first_node("size_selector"); + for (rapidxml::xml_node<> *bNode = pNode->first_node("button"); bNode; bNode = bNode->next_sibling("button")) + { + buttons.push_back(MeguButton( + rect.x + atoi(bNode->first_node("pos")->first_node("x")->value()), + rect.y + atoi(bNode->first_node("pos")->first_node("y")->value()), + atoi(bNode->first_node("pos")->first_node("w")->value()), + atoi(bNode->first_node("pos")->first_node("h")->value()), + NULL, + false)); + } +} + +SizeMenus::~SizeMenus() +{ +} + +void SizeMenus::disableMenu(){ + visible = false; + + for (std::vector::iterator te_it = buttons.begin(); te_it != buttons.end(); ++te_it){ + te_it->setEnable(false); + te_it->setVisible(false); + } +} + +void SizeMenus::callMenu(){ + visible = true; + for (std::vector::iterator te_it = buttons.begin(); te_it != buttons.end(); ++te_it){ + te_it->setEnable(true); + te_it->setVisible(true); + } +} +void SizeMenus::Render(SDL_Renderer *renderer) +{ + if (visible){ + SDL_RenderCopy(renderer, texture, NULL, &rect); + for (std::vector::iterator te_it = buttons.begin(); te_it != buttons.end(); ++te_it){ + te_it->Render(renderer); + } + } +} + + +SDL_Texture* SizeMenus::loadTexture(std::string path, SDL_Renderer *renderer) +{ + //The final texture + SDL_Texture* newTexture = NULL; + //Load image at specified path + SDL_Surface* loadedSurface = IMG_Load(path.c_str()); + if (loadedSurface == NULL) + { + printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); + } + else + { + //Create texture from surface pixels + newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); + if (newTexture == NULL) + { + printf("Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); + } + + //Get rid of old loaded surface + SDL_FreeSurface(loadedSurface); + } + + return newTexture; +} \ No newline at end of file diff --git a/SizeMenus.h b/SizeMenus.h new file mode 100644 index 0000000..b87c009 --- /dev/null +++ b/SizeMenus.h @@ -0,0 +1,34 @@ +#pragma once +#include "MeguMenus.h" +#include "MeguButton.h" +#include "SDL_include.h" +#include"Items_library.h" +#include +#include "TextEdit.h" +namespace widgets{ + class SizeMenus + { + typedef int ID; + public: + SizeMenus(const int &x, const int &y, const int &width, const int &height, SDL_Texture *newtexture, SDL_Renderer *renderer); + ~SizeMenus(); + void disableMenu(); + void callMenu(); + void Render(SDL_Renderer *renderer); + std::vector buttons; + protected: + SDL_Texture* loadTexture(std::string path, SDL_Renderer *renderer); + bool visible; + SDL_Rect rect; + SDL_Texture *texture; + rapidxml::file<> *hxmlFile; + rapidxml::xml_document<> hdoc; + rapidxml::xml_node<> *hpRoot; + rapidxml::xml_node<> *pNode; + rapidxml::xml_node<> *sNode; + rapidxml::xml_node<> *dNode; + rapidxml::xml_node<> *nNode; + rapidxml::xml_node<> *overlayNode; + + }; +} diff --git a/TextEdit.h b/TextEdit.h new file mode 100644 index 0000000..d15dd50 --- /dev/null +++ b/TextEdit.h @@ -0,0 +1,80 @@ +#pragma once +#include "TtfWrapper.h" +#include "SDL_include.h" +#include +class TextEdit : public TtfWrapper +{ +public: + SDL_Rect click_area; + //Initializes variables + TextEdit(){} + TextEdit(const int &x, const int &y, const int &w, const int &h, + const Uint8 &red, const Uint8 &green, const Uint8 &blue, + const SDL_BlendMode &blending, const Uint8 &alpha, + const SDL_Color &_textColor, const std::string &font_name, const int &font_size,const bool &_visible){ + click_area.x = x; + click_area.y = y; + click_area.w = w; + click_area.h = h; + renderQuad.x = x; + renderQuad.y = y; + textColor = _textColor; + setColor(red, green, blue); + setBlendMode(blending); + setAlpha(alpha); + font = TTF_OpenFont(font_name.c_str(), font_size); + visible = _visible; + + } + ~TextEdit(){} + + bool isIn(const int &x, const int &y){ + if (click_area.x <= x && x <= click_area.x + click_area.w && click_area.y <= y && y <= click_area.y + click_area.h){ + return true; + } + return false; + } + + void handleKey(SDL_Event *e){ + //Special key input + if (e->type == SDL_KEYDOWN) + { + //Handle backspace + if (e->key.keysym.sym == SDLK_BACKSPACE && text.length() > 0) + { + //lop off character + text.pop_back(); + } + //Handle copy + else if (e->key.keysym.sym == SDLK_c && SDL_GetModState() & KMOD_CTRL) + { + text = SDL_SetClipboardText(text.c_str()); + } + //Handle paste + else if (e->key.keysym.sym == SDLK_v && SDL_GetModState() & KMOD_CTRL) + { + text = SDL_GetClipboardText(); + } + if (e->key.keysym.sym == SDLK_RETURN) + setFocus(false); + } + //Special text input event + else if (e->type == SDL_TEXTINPUT) + { + //Not copy or pasting + if (!((e->text.text[0] == 'c' || e->text.text[0] == 'C') && (e->text.text[0] == 'v' || e->text.text[0] == 'V') && SDL_GetModState() & KMOD_CTRL)) + { + //Append character + text += e->text.text; + } + } + } + bool getFocus(){ + return focus; + } + void setFocus(bool _focus){ + focus = _focus; + } +private: + bool focus; +}; \ No newline at end of file diff --git a/TtfWrapper.h b/TtfWrapper.h new file mode 100644 index 0000000..7ac8f5a --- /dev/null +++ b/TtfWrapper.h @@ -0,0 +1,143 @@ +#pragma once +#include "SDL_include.h" +#include +#include +class TtfWrapper +{ +public: + std::string text;//written text + //Initializes variables + TtfWrapper(){ + //Initialize + mTexture = NULL; + font = TTF_OpenFont("assets/fonts/ahronbd.ttf", 28); + } + + //Initializes variables with position + TtfWrapper(const int &x, const int &y, + const Uint8 &red, const Uint8 &green, const Uint8 &blue, + const SDL_BlendMode &blending, const Uint8 &alpha, + const SDL_Color &_textColor, const Uint8 &_size, const std::string &fontpath, const int &letters, bool _visible){ + //Initialize + mTexture = NULL; + renderQuad.x = x; + renderQuad.y = y; + + textColor = _textColor; + setColor(red, green, blue); + setBlendMode(blending); + setAlpha(alpha); + font = TTF_OpenFont(fontpath.c_str(), _size); + visible = _visible; + max_letters = letters; + } + + //Deallocates memory + ~TtfWrapper(){ + //Deallocate + free(); + } + void setText(const std::string &_text){ + text = _text; + } + std::string getText(){ + return text; + } + //Creates image from font string + bool loadFromRenderedText(SDL_Renderer *renderer){ + //Get rid of preexisting texture + if (mTexture != NULL) + free(); + + //Render text surface + + SDL_Surface* textSurface = TTF_RenderText_Blended_Wrapped(font, text.c_str(), textColor, max_letters); + if (textSurface == NULL) + { + printf("Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError()); + } + else + { + //Create texture from surface pixels + mTexture = SDL_CreateTextureFromSurface(renderer, textSurface); + if (mTexture == NULL) + { + printf("Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError()); + } + else + { + //Get image dimensions + renderQuad.w = textSurface->w; + renderQuad.h = textSurface->h; + } + + //Get rid of old surface + SDL_FreeSurface(textSurface); + } + + //Return success + return mTexture != NULL; + } + + //Deallocates texture + void free(){ + //Free texture if it exists + if (mTexture != NULL) + { + SDL_DestroyTexture(mTexture); + mTexture = NULL; + } + } + + //Set color modulation + void setColor(Uint8 red, Uint8 green, Uint8 blue){ + //Modulate texture rgb + SDL_SetTextureColorMod(mTexture, red, green, blue); + } + + //Set blending + void setBlendMode(SDL_BlendMode blending){ + //Set blending function + SDL_SetTextureBlendMode(mTexture, blending); + } + + //Set alpha modulation + void setAlpha(Uint8 alpha){ + //Modulate texture alpha + SDL_SetTextureAlphaMod(mTexture, alpha); + } + + //Renders texture at given point + void Render(SDL_Renderer *renderer, SDL_RendererFlip flip = SDL_FLIP_NONE){ + //Set rendering space and render to screen + //Render to screen + SDL_RenderCopy(renderer, mTexture, NULL, &renderQuad); + } + + //Gets image dimensions + int getWidth(){ + return renderQuad.w; + } + + int getHeight(){ + return renderQuad.h; + } + + //Visibility + void setVisible(bool _v){ + visible = _v; + } + bool getVisible(){ + return visible; + } + +protected: + SDL_Rect renderQuad; + TTF_Font *font; + //The actual hardware texture + SDL_Texture* mTexture; + //Image dimensions + bool visible; + SDL_Color textColor; + int max_letters; +}; diff --git a/cApp.cpp b/cApp.cpp new file mode 100644 index 0000000..e69de29 diff --git a/dirent.h b/dirent.h new file mode 100644 index 0000000..39ff0f3 --- /dev/null +++ b/dirent.h @@ -0,0 +1,364 @@ +/***************************************************************************** + * dirent.h - dirent API for Microsoft Visual Studio + * + * Copyright (C) 2006 Toni Ronkko + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Aug 11, 2010, Toni Ronkko + * Added d_type and d_namlen fields to dirent structure. The former is + * especially useful for determining whether directory entry represents a + * file or a directory. For more information, see + * http://www.delorie.com/gnu/docs/glibc/libc_270.html + * + * Aug 11, 2010, Toni Ronkko + * Improved conformance to the standards. For example, errno is now set + * properly on failure and assert() is never used. Thanks to Peter Brockam + * for suggestions. + * + * Aug 11, 2010, Toni Ronkko + * Fixed a bug in rewinddir(): when using relative directory names, change + * of working directory no longer causes rewinddir() to fail. + * + * Dec 15, 2009, John Cunningham + * Added rewinddir member function + * + * Jan 18, 2008, Toni Ronkko + * Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string + * between multi-byte and unicode representations. This makes the + * code simpler and also allows the code to be compiled under MingW. Thanks + * to Azriel Fasten for the suggestion. + * + * Mar 4, 2007, Toni Ronkko + * Bug fix: due to the strncpy_s() function this file only compiled in + * Visual Studio 2005. Using the new string functions only when the + * compiler version allows. + * + * Nov 2, 2006, Toni Ronkko + * Major update: removed support for Watcom C, MS-DOS and Turbo C to + * simplify the file, updated the code to compile cleanly on Visual + * Studio 2005 with both unicode and multi-byte character strings, + * removed rewinddir() as it had a bug. + * + * Aug 20, 2006, Toni Ronkko + * Removed all remarks about MSVC 1.0, which is antiqued now. Simplified + * comments by removing SGML tags. + * + * May 14 2002, Toni Ronkko + * Embedded the function definitions directly to the header so that no + * source modules need to be included in the Visual Studio project. Removed + * all the dependencies to other projects so that this very header can be + * used independently. + * + * May 28 1998, Toni Ronkko + * First version. + *****************************************************************************/ +#ifndef DIRENT_H +#define DIRENT_H + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include + +/* File type and permission flags for stat() */ +#if defined(_MSC_VER) && !defined(S_IREAD) +# define S_IFMT _S_IFMT /* file type mask */ +# define S_IFDIR _S_IFDIR /* directory */ +# define S_IFCHR _S_IFCHR /* character device */ +# define S_IFFIFO _S_IFFIFO /* pipe */ +# define S_IFREG _S_IFREG /* regular file */ +# define S_IREAD _S_IREAD /* read permission */ +# define S_IWRITE _S_IWRITE /* write permission */ +# define S_IEXEC _S_IEXEC /* execute permission */ +#endif +#define S_IFBLK 0 /* block device */ +#define S_IFLNK 0 /* link */ +#define S_IFSOCK 0 /* socket */ + +#if defined(_MSC_VER) +# define S_IRUSR S_IREAD /* read, user */ +# define S_IWUSR S_IWRITE /* write, user */ +# define S_IXUSR 0 /* execute, user */ +# define S_IRGRP 0 /* read, group */ +# define S_IWGRP 0 /* write, group */ +# define S_IXGRP 0 /* execute, group */ +# define S_IROTH 0 /* read, others */ +# define S_IWOTH 0 /* write, others */ +# define S_IXOTH 0 /* execute, others */ +#endif + +/* Indicates that d_type field is available in dirent structure */ +#define _DIRENT_HAVE_D_TYPE + +/* File type flags for d_type */ +#define DT_UNKNOWN 0 +#define DT_REG S_IFREG +#define DT_DIR S_IFDIR +#define DT_FIFO S_IFFIFO +#define DT_SOCK S_IFSOCK +#define DT_CHR S_IFCHR +#define DT_BLK S_IFBLK + +/* Macros for converting between st_mode and d_type */ +#define IFTODT(mode) ((mode) & S_IFMT) +#define DTTOIF(type) (type) + +/* + * File type macros. Note that block devices, sockets and links cannot be + * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are + * only defined for compatibility. These macros should always return false + * on Windows. + */ +#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO) +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) +#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct dirent +{ + char d_name[MAX_PATH + 1]; /* File name */ + size_t d_namlen; /* Length of name without \0 */ + int d_type; /* File type */ +} dirent; + + +typedef struct DIR +{ + dirent curentry; /* Current directory entry */ + WIN32_FIND_DATAA find_data; /* Private file data */ + int cached; /* True if data is valid */ + HANDLE search_handle; /* Win32 search handle */ + char patt[MAX_PATH + 3]; /* Initial directory name */ +} DIR; + + +/* Forward declarations */ +static DIR *opendir(const char *dirname); +static struct dirent *readdir(DIR *dirp); +static int closedir(DIR *dirp); +static void rewinddir(DIR* dirp); + + +/* Use the new safe string functions introduced in Visual Studio 2005 */ +#if defined(_MSC_VER) && _MSC_VER >= 1400 +# define DIRENT_STRNCPY(dest,src,size) strncpy_s((dest),(size),(src),_TRUNCATE) +#else +# define DIRENT_STRNCPY(dest,src,size) strncpy((dest),(src),(size)) +#endif + +/* Set errno variable */ +#if defined(_MSC_VER) +#define DIRENT_SET_ERRNO(x) _set_errno (x) +#else +#define DIRENT_SET_ERRNO(x) (errno = (x)) +#endif + + +/***************************************************************************** + * Open directory stream DIRNAME for read and return a pointer to the + * internal working area that is used to retrieve individual directory + * entries. + */ +static DIR *opendir(const char *dirname) +{ + DIR *dirp; + + /* ensure that the resulting search pattern will be a valid file name */ + if (dirname == NULL) { + DIRENT_SET_ERRNO (ENOENT); + return NULL; + } + if (strlen (dirname) + 3 >= MAX_PATH) { + DIRENT_SET_ERRNO (ENAMETOOLONG); + return NULL; + } + + /* construct new DIR structure */ + dirp = (DIR*) malloc (sizeof (struct DIR)); + if (dirp != NULL) { + int error; + + /* + * Convert relative directory name to an absolute directory one. This + * allows rewinddir() to function correctly when the current working + * directory is changed between opendir() and rewinddir(). + */ + if (GetFullPathNameA (dirname, MAX_PATH, dirp->patt, NULL)) { + char *p; + + /* append the search pattern "\\*\0" to the directory name */ + p = strchr (dirp->patt, '\0'); + if (dirp->patt < p && *(p-1) != '\\' && *(p-1) != ':') { + *p++ = '\\'; + } + *p++ = '*'; + *p = '\0'; + + /* open directory stream and retrieve the first entry */ + dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data); + if (dirp->search_handle != INVALID_HANDLE_VALUE) { + /* a directory entry is now waiting in memory */ + dirp->cached = 1; + error = 0; + } else { + /* search pattern is not a directory name? */ + DIRENT_SET_ERRNO (ENOENT); + error = 1; + } + } else { + /* buffer too small */ + DIRENT_SET_ERRNO (ENOMEM); + error = 1; + } + + if (error) { + free (dirp); + dirp = NULL; + } + } + + return dirp; +} + + +/***************************************************************************** + * Read a directory entry, and return a pointer to a dirent structure + * containing the name of the entry in d_name field. Individual directory + * entries returned by this very function include regular files, + * sub-directories, pseudo-directories "." and "..", but also volume labels, + * hidden files and system files may be returned. + */ +static struct dirent *readdir(DIR *dirp) +{ + DWORD attr; + if (dirp == NULL) { + /* directory stream did not open */ + DIRENT_SET_ERRNO (EBADF); + return NULL; + } + + /* get next directory entry */ + if (dirp->cached != 0) { + /* a valid directory entry already in memory */ + dirp->cached = 0; + } else { + /* get the next directory entry from stream */ + if (dirp->search_handle == INVALID_HANDLE_VALUE) { + return NULL; + } + if (FindNextFileA (dirp->search_handle, &dirp->find_data) == FALSE) { + /* the very last entry has been processed or an error occured */ + FindClose (dirp->search_handle); + dirp->search_handle = INVALID_HANDLE_VALUE; + return NULL; + } + } + + /* copy as a multibyte character string */ + DIRENT_STRNCPY ( dirp->curentry.d_name, + dirp->find_data.cFileName, + sizeof(dirp->curentry.d_name) ); + dirp->curentry.d_name[MAX_PATH] = '\0'; + + /* compute the length of name */ + dirp->curentry.d_namlen = strlen (dirp->curentry.d_name); + + /* determine file type */ + attr = dirp->find_data.dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { + dirp->curentry.d_type = DT_CHR; + } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { + dirp->curentry.d_type = DT_DIR; + } else { + dirp->curentry.d_type = DT_REG; + } + return &dirp->curentry; +} + + +/***************************************************************************** + * Close directory stream opened by opendir() function. Close of the + * directory stream invalidates the DIR structure as well as any previously + * read directory entry. + */ +static int closedir(DIR *dirp) +{ + if (dirp == NULL) { + /* invalid directory stream */ + DIRENT_SET_ERRNO (EBADF); + return -1; + } + + /* release search handle */ + if (dirp->search_handle != INVALID_HANDLE_VALUE) { + FindClose (dirp->search_handle); + dirp->search_handle = INVALID_HANDLE_VALUE; + } + + /* release directory structure */ + free (dirp); + return 0; +} + + +/***************************************************************************** + * Resets the position of the directory stream to which dirp refers to the + * beginning of the directory. It also causes the directory stream to refer + * to the current state of the corresponding directory, as a call to opendir() + * would have done. If dirp does not refer to a directory stream, the effect + * is undefined. + */ +static void rewinddir(DIR* dirp) +{ + if (dirp != NULL) { + /* release search handle */ + if (dirp->search_handle != INVALID_HANDLE_VALUE) { + FindClose (dirp->search_handle); + } + + /* open new search handle and retrieve the first entry */ + dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data); + if (dirp->search_handle != INVALID_HANDLE_VALUE) { + /* a directory entry is now waiting in memory */ + dirp->cached = 1; + } else { + /* failed to re-open directory: no directory entry in memory */ + dirp->cached = 0; + } + } +} + + +#ifdef __cplusplus +} +#endif +#endif /*DIRENT_H*/ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..bdca85c --- /dev/null +++ b/main.cpp @@ -0,0 +1,11 @@ +#include "MeguEngine.h" + + +int main(int argc, char* argv[]) { + + MeguEngine theApp; + + return theApp.OnExecute(); + + +} \ No newline at end of file diff --git a/resource.h b/resource.h new file mode 100644 index 0000000..1df7f90 Binary files /dev/null and b/resource.h differ