]> git.localhorst.tv Git - l2e.git/commitdiff
added rough implementation of a Menu
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 8 Aug 2012 20:47:20 +0000 (22:47 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 8 Aug 2012 20:47:20 +0000 (22:47 +0200)
src/battle/BattleState.cpp
src/battle/BattleState.h
src/battle/states/SelectSpell.cpp
src/battle/states/SelectSpell.h
src/graphics/Menu.h [new file with mode: 0644]
src/main.cpp
test-data/normal-font.png

index ae882a614ed981f4083626ebab77ad894d813cbc..15d9d18c5b2739d0d1ed0d77c012036452b2d2a6 100644 (file)
@@ -20,6 +20,7 @@ using app::Application;
 using app::Input;
 using geometry::Point;
 using geometry::Vector;
+using graphics::Menu;
 
 using std::vector;
 
@@ -50,6 +51,14 @@ void BattleState::EnterState(Application &ctrl, SDL_Surface *screen) {
        heroesLayout->CalculatePositions(background->w, background->h, heroesPositions);
        attackChoices.resize(heroes.size());
        for (vector<Hero>::size_type i(0), end(heroes.size()); i < end; ++i) {
+               // TODO: extract menu dimensions to resources
+               Menu</* Spell */ void *> spellMenu(res->normalFont, 12, 6, 8, 2, 32);
+               spellMenu.Add("Strong   : 3", 0);
+               spellMenu.Add("Stronger : 8", 0);
+               spellMenu.Add("Champion :16", 0);
+               spellMenu.Add("Rally    :10", 0);
+               spellMenu.Add("Valor    :30", 0);
+               spellMenus.push_back(spellMenu);
                heroTags.push_back(HeroTag(&heroes[i], &attackChoices[i], res, HeroTag::Alignment((i + 1) % 2)));
        }
 }
index 484e4529c6a49d7d78776b3de9420f286a96bcdf..365f1983305fcb3de5139b295cb89947c6db2dd0 100644 (file)
@@ -18,6 +18,7 @@
 #include "../app/State.h"
 #include "../geometry/Point.h"
 #include "../geometry/Vector.h"
+#include "../graphics/Menu.h"
 
 #include <vector>
 #include <SDL.h>
@@ -77,6 +78,7 @@ public:
        bool HasChosenAttackType() const { return attackChoices[activeHero].GetType() != AttackChoice::UNDECIDED; }
        void SetAttackType(AttackChoice::Type t) { attackChoices[activeHero].SetType(t); }
        bool AttackSelectionDone() const { return activeHero >= (int) heroes.size(); }
+       const graphics::Menu</* Spell */ void *> GetSpellMenu() const { return spellMenus[activeHero]; }
 
 public:
        geometry::Vector<int> CalculateScreenOffset(SDL_Surface *screen) const {
@@ -103,6 +105,7 @@ private:
        std::vector<geometry::Point<int> > heroesPositions;
        std::vector<Monster> monsters;
        std::vector<Hero> heroes;
+       std::vector<graphics::Menu</* Spell */ void *> > spellMenus;
        std::vector<HeroTag> heroTags;
        std::vector<AttackChoice> attackChoices;
        int activeHero;
index 1b012503551b23b73d386ae5eb81b8a49f6baeec..5f358fbe45c031f2420749654f97885941e29c8b 100644 (file)
@@ -63,13 +63,23 @@ void SelectSpell::UpdateWorld(float deltaT) {
 
 void SelectSpell::Render(SDL_Surface *screen) {
        parent->Render(screen);
+       Vector<int> offset(battle->CalculateScreenOffset(screen));
+       RenderFrame(screen, offset);
+       RenderMenu(screen, offset);
+}
+
+void SelectSpell::RenderFrame(SDL_Surface *screen, const Vector<int> &offset) {
        const Frame *frame(battle->Res().selectFrame);
        Point<int> position(frame->BorderWidth(), frame->BorderHeight());
-       Vector<int> offset(battle->CalculateScreenOffset(screen));
        int width(battle->BackgroundWidth() - 2 * frame->BorderWidth());
        // TODO: replace with font height
        int height(frame->BorderHeight() * 13);
        frame->Draw(screen, position + offset, width, height);
 }
 
+void SelectSpell::RenderMenu(SDL_Surface *screen, const Vector<int> &offset) {
+       Point<int> position(2 * battle->Res().selectFrame->BorderWidth(), 2 * battle->Res().selectFrame->BorderHeight());
+       battle->GetSpellMenu().Draw(screen, position + offset);
+}
+
 }
index e0bb118040e24b09d6214203b2c789f5f5e67bf1..f3841a1f92e78b0e8bf076972af872f67baf74f5 100644 (file)
@@ -10,6 +10,8 @@
 
 #include "../../app/State.h"
 
+#include "../../geometry/Vector.h"
+
 namespace battle {
 
 class BattleState;
@@ -34,6 +36,10 @@ public:
        virtual void UpdateWorld(float deltaT);
        virtual void Render(SDL_Surface *);
 
+private:
+       void RenderFrame(SDL_Surface *, const geometry::Vector<int> &offset);
+       void RenderMenu(SDL_Surface *, const geometry::Vector<int> &offset);
+
 private:
        app::Application *ctrl;
        BattleState *battle;
diff --git a/src/graphics/Menu.h b/src/graphics/Menu.h
new file mode 100644 (file)
index 0000000..0a4a698
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Menu.h
+ *
+ *  Created on: Aug 8, 2012
+ *      Author: holy
+ */
+
+#ifndef GRAPHICS_MENU_H_
+#define GRAPHICS_MENU_H_
+
+#include "Font.h"
+#include "../geometry/operators.h"
+#include "../geometry/Point.h"
+#include "../geometry/Vector.h"
+
+#include <vector>
+#include <SDL.h>
+
+namespace graphics {
+
+class Sprite;
+
+template<class T>
+class Menu {
+
+public:
+       Menu(const Font *font, int charsPerEntry, int rows, int rowGap = 0, int cols = 1, int colGap = 0);
+
+public:
+       int Width() const;
+       int Height() const;
+       int ColWidth() const { return font->CharWidth() * charsPerEntry; }
+       int RowHeight() const { return font->CharHeight() + rowGap; }
+
+       T &Selected() { return entries[selected].value; }
+       const T &Selected() const { return entries[selected].value; }
+       const char *SelectedTitle() const { return entries[selected].title; }
+
+       void NextItem();
+       void PreviousItem();
+       void NextRow();
+       void PreviousRow();
+       void SelectIndex(int index);
+
+       void Add(const char *title, const T &value, const Sprite *icon = 0) { entries.push_back(Entry(title, value, icon)); }
+       void Reserve(int n) { entries.reserve(n); }
+
+       void Draw(SDL_Surface *dest, geometry::Point<int> position) const;
+
+private:
+       int GetRow(int index) const { return index / cols; }
+       int GetCol(int index) const { return index % cols; }
+
+private:
+       struct Entry {
+               Entry(const char *title, const T &value, const Sprite *icon = 0)
+               : title(title), icon(icon), value(value) { }
+               const char *title;
+               const Sprite *icon;
+               T value;
+       };
+       const Font *font;
+       std::vector<Entry> entries;
+       int charsPerEntry;
+       int rows;
+       int rowGap;
+       int cols;
+       int colGap;
+       int selected;
+       int topRow;
+
+};
+
+
+template<class T>
+Menu<T>::Menu(const Font *font, int charsPerEntry, int rows, int rowGap, int cols, int colGap)
+: font(font)
+, charsPerEntry(charsPerEntry)
+, rows(rows)
+, rowGap(rowGap)
+, cols(cols)
+, colGap(colGap)
+, selected(0)
+, topRow(0) {
+
+}
+
+
+template<class T>
+int Menu<T>::Width() const {
+       return cols * ColWidth() + (cols - 1) * colGap;
+}
+
+template<class T>
+int Menu<T>::Height() const {
+       return rows * font->CharHeight() + (rows - 1) * rowGap;
+}
+
+
+template<class T>
+void Menu<T>::NextItem() {
+       SelectIndex(selected + 1);
+}
+
+template<class T>
+void Menu<T>::PreviousItem() {
+       SelectIndex(selected - 1);
+}
+
+template<class T>
+void Menu<T>::NextRow() {
+       SelectIndex(selected + cols);
+}
+
+template<class T>
+void Menu<T>::PreviousRow() {
+       SelectIndex(selected - cols);
+}
+
+template<class T>
+void Menu<T>::SelectIndex(int index) {
+       if (index < 0 || entries.size() < index) return;
+       selected = index;
+       if (GetRow(selected) - rows > topRow) {
+               topRow = GetRow(selected) - rows;
+       } else if (GetRow(selected) < topRow) {
+               topRow = GetRow(selected);
+       }
+}
+
+
+template<class T>
+void Menu<T>::Draw(SDL_Surface *dest, geometry::Point<int> position) const {
+       int start(topRow * cols);
+       int slots((topRow + rows) * cols);
+       int items(entries.size() - start);
+       int end(items < slots ? items : slots);
+       for (int i(0), count(end - start); i < count; ++i) {
+               geometry::Vector<int> offset((i % cols) * (ColWidth() + colGap), (i / cols) * RowHeight());
+               font->DrawString(entries[start + i].title, dest, position + offset, charsPerEntry);
+       }
+}
+
+}
+
+#endif /* GRAPHICS_MENU_H_ */
index d9a2f57c438cb4b1dfa3685e57b8d0cd3d419b68..676f2d7da7541c8dcccffadf2ef3aff90f0d4cf7 100644 (file)
@@ -161,6 +161,9 @@ int main(int argc, char **argv) {
                normalFont.MapRange('N', 'Z', 0, 2);
                normalFont.MapRange('a', 'm', 0, 3);
                normalFont.MapRange('n', 'z', 0, 4);
+               normalFont.MapChar(':', 10, 0);
+               normalFont.MapChar('!', 10, 0);
+               normalFont.MapChar('?', 10, 0);
                battleRes.normalFont = &normalFont;
 
                BattleState *battleState(new BattleState(bg, monstersLayout, heroesLayout, &battleRes));
index b2b1a40927bbccd470302247b7220bf403c81000..0bd50d02efb6c249d24a7431c9d0bf4214965010 100644 (file)
Binary files a/test-data/normal-font.png and b/test-data/normal-font.png differ