/* This software is the propery of 'SaraCraft' - developed by Allanis. * Only members directly assosiated with the SaraCraft project may view/change * this code. * * This class is intended to be a base class for all the menu systems * in Lephisto. this will extend the GameState class. */ #ifdef WIN32 #define WIN32_LEAN_AND_MEAN #include #endif #include #include #include #include #include #include #include "Config.h" #include "image.h" #include "font.h" #include "GameState.h" #include "Callback.h" #include "Log.h" #include "Menu.h" using namespace std; Menu::Menu(const char* image, GameState *from, GameState *to): GameState(NULL) { // Bool valie to set to quit done = false; // Make Set from and to gamestates fromState = from; toState = to; // Get ready for text mode EnterTextMode(Config::configuration->getWinWidth(), Config::configuration->getWinHeight()); // Load the background glEnable(GL_TEXTURE_2D); BuildTexture(image, &background, GL_CLAMP, false); glBindTexture(GL_TEXTURE_2D, background); Selected = 0; ButtonID = 0; mouseActive = true; } Menu::~Menu() { unsigned int i; glDeleteTextures(1, &background); for(i = 0; i < lists.size(); i++) { delete lists[i]; } lists.clear(); } void Menu::loop() { while(!lists[Selected]->Select()) { Selected += 1; if(Selected > (int) lists.size()) Selected = 0; } // Draw the menu display(); // Process incoming events processEvents(); } void Menu::display() { int width = Config::configuration->getWinWidth(); int height = Config::configuration->getWinHeight(); int i; glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); // Draw the background // Bind the background texture glBindTexture(GL_TEXTURE_2D, background); // Set the color glColor3f(.8, .8, .8); // Draw the actual background quad glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(0, 0 , 0); glTexCoord2f(0, 1); glVertex3f(0, height, 0); glTexCoord2f(1, 1); glVertex3f(width, height, 0); glTexCoord2f(1, 0); glVertex3f(width, 0, 0); glEnd(); // Draw the text. for(i = 0; i < (signed)lists.size(); i++) { glLoadIdentity(); //glTranslatef((float) width * lists[i].x, (float) height * lists[i].y, 0); lists[i]->Display(); } glColor3f(1, 1, 1); SDL_GL_SwapBuffers(); } void Menu::processEvents() { // Our SDL event placeholder SDL_Event event; handle_mouse(); // Grab all the events off the queue while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_KEYDOWN: // Handle key presses handle_key_down(&event.key.keysym); break; case SDL_KEYUP: handle_key_up(&event.key.keysym); break; case SDL_QUIT: // Handle quit requests (like Ctrl-c) doExit(); break; } } } void Menu::handle_key_up(SDL_keysym* keysym) { switch(keysym->sym) { case SDLK_ESCAPE: // Go back to the game, if it is loaded anyway. if((fromState != NULL) && (toState != NULL)) { switchState(fromState, toState); } break; case SDLK_RETURN: lists[Selected]->Execute(); break; case SDLK_p: Print(); break; default: break; } } void Menu::handle_key_down(SDL_keysym* keysym) { mouseActive = false; int newSelected; switch(keysym->sym) { case SDLK_UP: lists[Selected]->SelectionUp(); break; case SDLK_DOWN: lists[Selected]->SelectionDown(); break; case SDLK_LEFT: newSelected = Selected - 1; if(newSelected < 0) newSelected = lists.size() - 1; while(!lists[newSelected]->Select()) { newSelected -= 1; if(newSelected < 0) newSelected = lists.size() - 1; } lists[Selected]->Deselect(); Selected = newSelected; break; case SDLK_RIGHT: newSelected = Selected + 1; if(newSelected >= (int) lists.size()) newSelected = 0; while(!lists[newSelected]->Select()) { newSelected += 1; if(newSelected >= (int) lists.size()) newSelected = 0; } lists[Selected]->Deselect(); Selected = newSelected; break; case SDLK_z: takeScreenshot(); break; default: break; } } void Menu::doExit() { *done = true; } void Menu::switchTo(GameState *oldState) { // Set selected to return to game Selected = 0; while(!lists[Selected]->Select()) { Selected += 1; if(Selected > (int) lists.size()) Selected = 0; } EnterTextMode(Config::configuration->getWinWidth(), Config::configuration->getWinHeight()); glEnable(GL_TEXTURE_2D); } void Menu::switchFrom() { lists[Selected]->Deselect(); Selected = -1; } void Menu::addList(string Name, float x, float y) { MenuContainer *tempContainer; tempContainer = new MenuContainer(Name, x, y, maLeft); lists.push_back(tempContainer); } void Menu::addList(string Name, float x, float y, int alignment) { MenuContainer *tempContainer; if((alignment < maLeft) || (alignment > maRight)) addList(Name, x, y); tempContainer = new MenuContainer(Name, x, y, alignment); lists.push_back(tempContainer); } int Menu::addMenuItem(string Text, cCallback *recallFunc, string List, bool enabled) { unsigned int i; for(i = 0; i < lists.size(); i++) { if(lists[i]->GetName() == List) { lists[i]->AddButton(Text, recallFunc, enabled, ButtonID); ButtonID++; break; } } return ButtonID - 1; } int Menu::addMenuItem(string Text, cCallback *recallFunc, string List, bool enabled, float red, float green, float blue) { unsigned int i; for(i = 0; i < lists.size(); i++) { if(lists[i]->GetName() == List) { lists[i]->AddButton(Text, recallFunc, enabled, ButtonID, red, green, blue); ButtonID++; break; } } return ButtonID - 1; } void Menu::addDataItem(string Text, string List) { unsigned int i; for(i = 0; i < lists.size(); i++) { if(lists[i]->GetName() == List) { lists[i]->AddData(Text); break; } } } void Menu::addDataItem(string Text, string List, float red, float green, float blue) { unsigned int i; for(i = 0; i < lists.size(); i++) { if(lists[i]->GetName() == List) { lists[i]->AddData(Text, red, green, blue); break; } } } void Menu::changeEnabled(string Text, string List, bool enabled) { unsigned int i; for(i = 0; i < lists.size(); i++) { if(lists[i]->GetName() == List) { lists[i]->ChangeEnabled(Text, enabled); } } } void Menu::handle_mouse() { unsigned int i; Uint8 buttons; buttons = SDL_GetMouseState(&curMousePosX, &curMousePosY); if((!mouseActive) && (!((curMousePosX == lastMousePosX) && (curMousePosY == lastMousePosY)))) mouseActive = true; buttonDown = MouseButtonDown(buttons, 1); for(i = 0; i < lists.size(); i++) { if(lists[i]->LocationWithin(curMousePosX, curMousePosY)) { if(lists[i]->MouseSelect(curMousePosX, curMousePosY)) { if(Selected != (int) i) { lists[Selected]->Deselect(); Selected = i; } if(mouseActive && buttonDown) { lists[Selected]->Execute(); } } } } lastMousePosX = curMousePosX; lastMousePosY = curMousePosY; } bool Menu::MouseLocToMenu(int locX, int locY) { /* unsigned int i; for(i = 0; i < lists.size(); i++) { if((locX >= lists[i].TopLeftX) && (locX <= lists[i].BottomRightX) && (locY >= lists[i].TopLeftY) && (locY <= lists[i].BottomRightY)) { hSelected = (int) i; return ContainerSelection(locX, locY, i); } } return false; */ return false; } bool Menu::ContainerSelection(int locX, int locY, int container) { /* unsigned int i; float vertical; menuItem* tempItem; vertical = lists[container].TopLeftY; //tempItem = lists[container]; for(i = 0; i < lists[container].menuItems.size(); i++) { tempItem = &lists[container].menuItems[i]; if((locY > (vertical + (18 * tempItem->order)) && (locY < (vertical + (18 * (tempItem->order + 1)))))) { vSelected = (int) i; return true; } } */ return false; } void Menu::Print() { unsigned int i; for(i = 0; i < lists.size(); i++) lists[i]->Print(); } bool Menu::MouseButtonDown(Uint8 buttons, int buttonNumber) { if(((buttons & buttonNumber) == buttonNumber) && ((lastButtonState & buttonNumber) == buttonNumber)) { lastButtonState = buttons; return false; } if(((buttons & buttonNumber) == buttonNumber) && ((lastButtonState & buttonNumber) != buttonNumber)) { lastButtonState = buttons; return true; } lastButtonState = buttons; return false; }