392 lines
8.5 KiB
C++
392 lines
8.5 KiB
C++
/* 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 <windows.h>
|
|
#endif
|
|
|
|
#include <cstdlib>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <SDL/SDL.h>
|
|
#include <GL/gl.h>
|
|
#include <GL/glu.h>
|
|
#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;
|
|
}
|