git repos / blockattack-game

commit f3ef3495

sago007 · 2008-11-13 20:00
f3ef34953917e7d09b204971ae04bd190aa89f1d patch · browse files
parent 78d03b3876282b978d88caa3bb30df271de8aa00

Something for a main menu. Might not make it in the next version


git-svn-id: https://blockattack.svn.sourceforge.net/svnroot/blockattack/trunk@49 9d7177f8-192b-0410-8f35-a16a89829b06

Changed files

A source/code/MenuSystem.cc
A source/code/MenuSystem.h
diff --git a/source/code/MenuSystem.cc b/source/code/MenuSystem.cc new file mode 100644 index 0000000..5e2997e --- /dev/null +++ b/source/code/MenuSystem.cc
@@ -0,0 +1,227 @@
+/*
+Block Attack - Rise of the Blocks, SDL game, besed on Nintendo's Tetris Attack
+Copyright (C) 2008 Poul Sander
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Poul Sander
+ R�vehjvej 36, V. 1111
+ 2800 Kgs. Lyngby
+ DENMARK
+ blockattack@poulsander.com
+ http://blockattack.sf.net
+*/
+
+#include "MenuSystem.h"
+#include "common.h"
+
+extern SDL_Surface *mouse;
+extern SDL_Surface *backgroundImage;
+extern bool highPriority;
+int mousex;
+int mousey;
+
+/*Draws a image from on a given Surface. Takes source image, destination surface and coordinates*/
+inline void DrawIMG(SDL_Surface *img, SDL_Surface *target, int x, int y)
+{
+ SDL_Rect dest;
+ dest.x = x;
+ dest.y = y;
+ SDL_BlitSurface(img, NULL, target, &dest);
+}
+
+SDL_Surface* ButtonGfx::marked;
+SDL_Surface* ButtonGfx::unmarked;
+int ButtonGfx::xsize;
+int ButtonGfx::ysize;
+TTFont* ButtonGfx::ttf;
+
+void ButtonGfx::setSurfaces(SDL_Surface **marked,SDL_Surface **unmarked)
+{
+ ButtonGfx::marked = *marked;
+ ButtonGfx::unmarked = *unmarked;
+ xsize=(*marked)->w;
+ ysize=(*marked)->h;
+}
+
+Button::Button()
+{
+ label = "";
+ marked = false;
+ surfaceMarked = SDL_ConvertSurface(ButtonGfx::marked, ButtonGfx::marked->format, SDL_SWSURFACE);
+ surfaceUnmarked = SDL_ConvertSurface(ButtonGfx::unmarked, ButtonGfx::unmarked->format, SDL_SWSURFACE);
+}
+
+Button::~Button()
+{
+ SDL_FreeSurface(surfaceMarked);
+ SDL_FreeSurface(surfaceUnmarked);
+}
+
+Button::Button(const Button& b)
+{
+ label = b.label;
+ marked = b.marked;
+ surfaceMarked = SDL_ConvertSurface(ButtonGfx::marked, ButtonGfx::marked->format, SDL_SWSURFACE);
+ surfaceUnmarked = SDL_ConvertSurface(ButtonGfx::unmarked, ButtonGfx::unmarked->format, SDL_SWSURFACE);
+}
+
+void Button::setLabel(string text)
+{
+ label = text;
+}
+
+void Button::setAction(void (*action2run)())
+{
+ action = action2run;
+}
+
+bool Button::isClicked(int x,int y)
+{
+ if ( x >= this->x && y >= this->y && x<= this->x+ButtonGfx::xsize && y <= this->y + ButtonGfx::ysize)
+ return true;
+ else
+ return false;
+}
+
+void Button::doAction()
+{
+ action();
+}
+
+void Button::drawTo(SDL_Surface *surface)
+{
+ #if DEBUG
+ cout << "Painting button: " << label << endl;
+ #endif
+ if (marked)
+ DrawIMG(surfaceMarked,surface,x,y);
+ else
+ DrawIMG(surfaceUnmarked,surface,x,y);
+ //int stringx = x + (ButtonGfx::xsize)/2 - ButtonGfx::ttf->getTextWidth(label)/2;
+ //int stringy = y + (ButtonGfx::ysize)/2 - ButtonGfx::ttf->getTextHeight()/2;
+ //ButtonGfx::ttf->writeText(label,surface,stringx,stringy);
+}
+
+void Menu::drawSelf()
+{
+ DrawIMG(backgroundImage,screen,0,0);
+ vector<Button>::iterator it;
+ for(it = buttons.begin();it < buttons.end(); it++)
+ (*it).drawTo(screen);
+ exit.drawTo(screen);
+ DrawIMG(mouse,screen,mousex,mousey);
+}
+
+void Menu::performClick(int x,int y)
+{
+ vector<Button>::iterator it;
+ for(it = buttons.begin();it < buttons.end(); it++)
+ {
+ Button b = (*it);
+ if(b.isClicked(x,y))
+ b.doAction();
+ }
+ if(exit.isClicked(x,y))
+ running = false;
+}
+
+void Menu::placeButtons()
+{
+ int nextY = 50;
+ const int X = 50;
+ vector<Button>::iterator it;
+ for(it = buttons.begin();it < buttons.end(); it++)
+ {
+ (*it).x = X;
+ (*it).y = nextY;
+ nextY += 50;
+ }
+ exit.x = X;
+ exit.y = nextY;
+}
+
+void Menu::addButton(Button b)
+{
+ buttons.push_back(b);
+ b.marked = false;
+ placeButtons();
+}
+
+Menu::Menu(SDL_Surface **screen)
+{
+ this->screen = *screen;
+ buttons = vector<Button>(10);
+ isSubmenu = true;
+ exit.setLabel("Back");
+}
+
+Menu::Menu(SDL_Surface **screen,bool submenu)
+{
+ this->screen = *screen;
+ buttons = vector<Button>(0);
+ isSubmenu = submenu;
+ if(isSubmenu)
+ exit.setLabel("Back");
+ else
+ exit.setLabel("Exit");
+}
+
+void Menu::run()
+{
+ running = true;
+ while(running)
+ {
+ if (!(highPriority)) SDL_Delay(10);
+
+
+ SDL_Event event;
+
+ while ( SDL_PollEvent(&event) )
+ {
+ if ( event.type == SDL_QUIT ) {
+ running = false;
+ }
+
+ if ( event.type == SDL_KEYDOWN )
+ {
+ if ( event.key.keysym.sym == SDLK_ESCAPE )
+ {
+ running = false;
+ }
+
+ if (event.key.keysym.sym == SDLK_UP)
+ {
+ marked--;
+ if(marked<0)
+ marked = buttons.size(); //not -1, since exit is after the last element in the list
+ }
+
+ if (event.key.keysym.sym == SDLK_DOWN)
+ {
+ marked++;
+ if(marked>buttons.size())
+ marked = 0;
+ }
+ }
+
+ SDL_GetMouseState(&mousex,&mousey);
+
+ }
+
+ drawSelf();
+ SDL_Flip(screen);
+ }
+}
diff --git a/source/code/MenuSystem.h b/source/code/MenuSystem.h new file mode 100644 index 0000000..8e7756e --- /dev/null +++ b/source/code/MenuSystem.h
@@ -0,0 +1,119 @@
+/*
+Block Attack - Rise of the Blocks, SDL game, besed on Nintendo's Tetris Attack
+Copyright (C) 2008 Poul Sander
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Poul Sander
+ R�vehjvej 36, V. 1111
+ 2800 Kgs. Lyngby
+ DENMARK
+ blockattack@poulsander.com
+ http://blockattack.sf.net
+*/
+
+//
+// File: MenuSystem.h
+// Author: poul
+//
+// Created on 28. september 2008, 17:06
+//
+
+#ifndef _MENUSYSTEM_H
+#define _MENUSYSTEM_H
+
+#include <string>
+#include "SDL.h"
+#include <vector>
+#include "ttfont.h"
+
+using namespace std;
+
+//The ButtonGfx object hold common media for all buttons, so we can reskin them by only changeing one pointer
+class ButtonGfx {
+ public:
+ //Holds the graphic for a button that is selected
+ static SDL_Surface *marked;
+ //Holds the graphic for a button that is not selected
+ static SDL_Surface *unmarked;
+ //The size of the buttons, so we don't have to ask w and h from the SDL Surfaces each time
+ static int xsize;
+ static int ysize;
+ //A TTFont used for writing the label on the buttons
+ static TTFont *ttf;
+ //Yes I use pointer-to-pointer and yes it is inheriently insecure
+ static void setSurfaces(SDL_Surface **marked,SDL_Surface **unmarked);
+};
+
+//A button
+class Button {
+ private:
+ //The label. This is written on the button
+ string label;
+ SDL_Surface* surfaceMarked;
+ SDL_Surface* surfaceUnmarked;
+ //Pointer to a callback function.
+ void (*action)();
+
+ public:
+ //Is the button marked?
+ bool marked;
+ //Where is the button on the screen
+ int x;
+ int y;
+
+ Button();
+ Button(const Button& b);
+ ~Button();
+
+
+ //Set the text to write on the button
+ void setLabel(string text);
+ //Set the action to run
+ void setAction(void (*action2run)());
+
+ bool isClicked(int x,int y); //Returns true if (x,y) is within the borders of the button
+ void doAction(); //Run the callback function
+ void drawTo(SDL_Surface *surface); //Draws to screen
+};
+
+class Menu {
+ private:
+ vector<Button> buttons; //Vector holder the buttons
+ Button exit; //The exit button is special since it does not have a callback function
+ bool isSubmenu; //True if the menu is a submenu
+ int marked; //The index of the marked button (for keyboard up/down)
+ bool running; //The menu is running. The menu will terminate then this is false
+ SDL_Surface *screen; //Pointer to the screen to draw to
+// SDL_Surface *background; //Pointer to the background image
+
+ void drawSelf(); //Private function to draw the screen
+ void performClick(int x, int y); //Private function to call then a click is detected.
+ void placeButtons(); //Rearanges the buttons to the correct place.
+ public:
+ //numberOfItems is the expected numberOfItems for vector initialization
+ //SubMenu is true by default
+ Menu(SDL_Surface **screen,bool isSubmenu);
+ Menu(SDL_Surface **screen);
+
+ //Add a button to the menu
+ void addButton(Button b);
+
+ //Run the menu
+ void run();
+};
+
+#endif /* _MENUSYSTEM_H */
+