]> git.localhorst.tv Git - l2e.git/commitdiff
implemented capsule renaming
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 10 Dec 2012 21:51:54 +0000 (22:51 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 10 Dec 2012 21:51:54 +0000 (22:51 +0100)
14 files changed:
l2e.cbp
src/common/Capsule.h
src/graphics/CharSelect.cpp [new file with mode: 0644]
src/graphics/CharSelect.h [new file with mode: 0644]
src/graphics/fwd.h
src/main.cpp
src/menu/CapsuleMenu.cpp
src/menu/CapsuleMenu.h
src/menu/CapsuleNameMenu.cpp
src/menu/CapsuleNameMenu.h
src/menu/Resources.cpp
src/menu/Resources.h
test-data/alpha-cursor.png [new file with mode: 0644]
test-data/test.l2s

diff --git a/l2e.cbp b/l2e.cbp
index 64f428d99f9a85cb1cdd955bad0b71bec476c544..4ff83920c3f34c8cd81e6384caf2a8a117d825b3 100644 (file)
--- a/l2e.cbp
+++ b/l2e.cbp
                <Unit filename="src\graphics\Animation.h" />
                <Unit filename="src\graphics\Camera.cpp" />
                <Unit filename="src\graphics\Camera.h" />
+               <Unit filename="src\graphics\CharSelect.cpp" />
+               <Unit filename="src\graphics\CharSelect.h" />
                <Unit filename="src\graphics\Color.h" />
                <Unit filename="src\graphics\ColorFade.cpp" />
                <Unit filename="src\graphics\ColorFade.h" />
index b1039fa90e2474fe94d54204726a79d36af88a6d..8d4791d20b2e4d20c2ed8c59dda9882115ce7bae 100644 (file)
@@ -23,6 +23,7 @@ public:
        Capsule();
 
        const char *Name() const { return name; }
+       void SetName(const char *n) { name = n; }
        const char *ClassName() const;
        const char *Alignment() const { return alignment; }
        const char *Tribe() const;
diff --git a/src/graphics/CharSelect.cpp b/src/graphics/CharSelect.cpp
new file mode 100644 (file)
index 0000000..415c7a6
--- /dev/null
@@ -0,0 +1,124 @@
+#include "CharSelect.h"
+
+#include "Font.h"
+#include "Sprite.h"
+#include "../loader/Interpreter.h"
+#include "../loader/TypeDescription.h"
+
+#include <cstring>
+
+using geometry::Vector;
+using loader::FieldDescription;
+using loader::Interpreter;
+using loader::TypeDescription;
+
+namespace graphics {
+
+CharSelect::CharSelect()
+: font(0)
+, cursor(0)
+, chars("")
+, numChars(0)
+, width(10)
+, groupX(0)
+, groupY(0)
+, selected(0) {
+
+}
+
+
+void CharSelect::Draw(SDL_Surface *screen, const Vector<int> &positionIn) const {
+       Vector<int> position(positionIn);
+       Vector<int> lineHead(positionIn);
+       const Vector<int> step(2 * font->CharWidth(), 0);
+       const Vector<int> doubleStep(3 * font->CharWidth(), 0);
+       const Vector<int> newline(0, 2 * font->CharHeight());
+       const Vector<int> doubleNewline(0, 3 * font->CharHeight());
+       const Vector<int> cursorOffset(font->CharWidth() / 2, font->CharHeight() / 2);
+
+       for (int i = 0; chars[i] != '\0'; ++i) {
+               if (i == selected) {
+                       cursor->DrawCenter(screen, position + cursorOffset);
+               }
+
+               font->DrawChar(chars[i], screen, position);
+
+               if (i % width == width - 1) {
+                       if (groupY > 0 && (i / width) % groupY == groupY - 1) {
+                               lineHead += doubleNewline;
+                       } else {
+                               lineHead += newline;
+                       }
+                       position = lineHead;
+               } else {
+                       if (groupX > 0 && (i % width) % groupX == groupX - 1) {
+                               position += doubleStep;
+                       } else {
+                               position += step;
+                       }
+               }
+       }
+}
+
+
+void CharSelect::NextCol() {
+       ++selected;
+       if (selected % width == 0) {
+               selected -= width;
+       }
+}
+
+void CharSelect::PreviousCol() {
+       --selected;
+       if (selected < 0 || selected % width == width - 1) {
+               selected += width;
+       }
+}
+
+void CharSelect::NextRow() {
+       selected += width;
+       if (selected >= numChars) {
+               selected -= numChars;
+       }
+}
+
+void CharSelect::PreviousRow() {
+       selected -= width;
+       if (selected < 0) {
+               selected += numChars;
+       }
+}
+
+
+char CharSelect::Selected() const {
+       return chars[selected];
+}
+
+
+void CharSelect::CreateTypeDescription() {
+       CharSelect c;
+
+       TypeDescription &td(TypeDescription::Create(TYPE_ID, "CharSelect"));
+       td.SetConstructor(&Construct);
+       td.SetLoader(&Load);
+       td.SetSize(sizeof(CharSelect));
+
+       td.AddField("font", FieldDescription(((char *)&c.font) - ((char *)&c), Font::TYPE_ID).SetReferenced().SetDescription("the font to use for characters"));
+       td.AddField("cursor", FieldDescription(((char *)&c.cursor) - ((char *)&c), Sprite::TYPE_ID).SetReferenced().SetDescription("sprite for the cursor"));
+       td.AddField("chars", FieldDescription(((char *)&c.chars) - ((char *)&c), Interpreter::STRING_ID).SetReferenced().SetDescription("characters to select from"));
+
+       td.AddField("width", FieldDescription(((char *)&c.width) - ((char *)&c), Interpreter::NUMBER_ID).SetDescription("the width of one row"));
+       td.AddField("groupX", FieldDescription(((char *)&c.groupX) - ((char *)&c), Interpreter::NUMBER_ID).SetDescription("double space after this many columns"));
+       td.AddField("groupY", FieldDescription(((char *)&c.groupY) - ((char *)&c), Interpreter::NUMBER_ID).SetDescription("double space after this many rows"));
+}
+
+void CharSelect::Construct(void *data) {
+       new (data) CharSelect;
+}
+
+void CharSelect::Load(void *data) {
+       CharSelect *c = reinterpret_cast<CharSelect *>(data);
+       c->numChars = std::strlen(c->chars);
+}
+
+}
diff --git a/src/graphics/CharSelect.h b/src/graphics/CharSelect.h
new file mode 100644 (file)
index 0000000..c5d4cd8
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef GRAPHICS_CHARSELECT_H_
+#define GRAPHICS_CHARSELECT_H_
+
+#include "../geometry/Vector.h"
+
+#include <SDL.h>
+
+namespace graphics {
+
+class Font;
+class Sprite;
+
+class CharSelect {
+
+public:
+       CharSelect();
+
+       static const int TYPE_ID = 411;
+
+public:
+       void Draw(SDL_Surface *screen, const geometry::Vector<int> &position) const;
+
+       void NextCol();
+       void PreviousCol();
+       void NextRow();
+       void PreviousRow();
+
+       char Selected() const;
+
+public:
+       static void CreateTypeDescription();
+       static void Construct(void *);
+       static void Load(void *);
+
+private:
+       const Font *font;
+       const Sprite *cursor;
+       const char *chars;
+       int numChars;
+
+       int width;
+       int groupX;
+       int groupY;
+
+       int selected;
+
+};
+
+}
+
+#endif /* GRAPHICS_CHARSELECT_H_ */
index f71c02f76fb453efbdd24d773505dbaed83096a3..6b3bf433f3ac05adca6c4d60b110b12837af6ee1 100644 (file)
@@ -6,6 +6,7 @@ namespace graphics {
 class Animation;
 class AnimationRunner;
 class Camera;
+class CharSelect;
 class Color;
 class ColorFade;
 class ComplexAnimation;
index 2611a722aeba9b20ebf2431e33606e846be645e8..2ecd30ab6705e1fb77e98d360b2a2bfa76687559 100644 (file)
@@ -18,6 +18,7 @@
 #include "common/Spell.h"
 #include "common/Stats.h"
 #include "geometry/Vector.h"
+#include "graphics/CharSelect.h"
 #include "graphics/ComplexAnimation.h"
 #include "graphics/Font.h"
 #include "graphics/Frame.h"
@@ -111,6 +112,7 @@ int main(int argc, char **argv) {
                common::TargetingMode::CreateTypeDescription();
 
                graphics::Animation::CreateTypeDescription();
+               graphics::CharSelect::CreateTypeDescription();
                graphics::ComplexAnimation::CreateTypeDescription();
                graphics::Font::CreateTypeDescription();
                graphics::Frame::CreateTypeDescription();
index ab32a1bcb2260b3b2a51d57d6cda58958ed23362..dd61dbde091360378dafdde71572bf297f402e0c 100644 (file)
@@ -260,6 +260,10 @@ int CapsuleMenu::Height() const {
        return parent->Height();
 }
 
+Capsule &CapsuleMenu::GetCapsule() {
+       return *Game().state->capsule;
+}
+
 const Capsule &CapsuleMenu::GetCapsule() const {
        return *Game().state->capsule;
 }
index 1491f391d294b5e70cbdf479d6d4b3aff7a1f41f..6358a6a269a2d986a09dae61a6a60c6bfdf895ce 100644 (file)
@@ -33,6 +33,7 @@ public:
        const common::GameConfig &Game() const;
        Resources &Res();
        const Resources &Res() const;
+       common::Capsule &GetCapsule();
        const common::Capsule &GetCapsule() const;
 
        int Width() const;
index 14acd461fa2e491b8ec86686bb5c26b960d1a668..58db75e89b9fddd81173e5c8f0df30907b0c25c8 100644 (file)
@@ -25,9 +25,16 @@ namespace menu {
 
 CapsuleNameMenu::CapsuleNameMenu(CapsuleMenu *parent)
 : parent(parent)
-, cursor(5) {
+, select(*parent->Res().capsuleNameCharSelectTemplate)
+, cursor(5)
+, first(true) {
+       bzero(buffer, 6);
        std::strncpy(buffer, GetCapsule().Name(), 6);
-       buffer[5] = '\0';
+       for (int i = 4; i > 0; --i) {
+               if (buffer[i] == '\0') {
+                       buffer[i] = '_';
+               }
+       }
 }
 
 
@@ -54,11 +61,74 @@ void CapsuleNameMenu::OnResize(int width, int height) {
 
 
 void CapsuleNameMenu::HandleEvents(const Input &input) {
-       if (input.JustPressed(Input::START)) {
+       if (input.JustPressed(Input::PAD_UP)) {
+               select.PreviousRow();
+       }
+       if (input.JustPressed(Input::PAD_RIGHT)) {
+               select.NextCol();
+       }
+       if (input.JustPressed(Input::PAD_DOWN)) {
+               select.NextRow();
+       }
+       if (input.JustPressed(Input::PAD_LEFT)) {
+               select.PreviousCol();
+       }
+
+       if (input.JustPressed(Input::ACTION_A)) {
+               AddChar();
+       }
+       if (input.JustPressed(Input::ACTION_B)) {
+               RemoveChar();
+       }
+
+       if (input.JustPressed(Input::START) && cursor > 0) {
+               StoreName();
                Ctrl().PopState();
        }
 }
 
+void CapsuleNameMenu::AddChar() {
+       if (first) {
+               cursor = 1;
+               buffer[0] = select.Selected();
+               for (int i = 1; i < 5; ++i) {
+                       buffer[i] = '_';
+               }
+               first = false;
+       } else {
+               if (cursor < 5) {
+                       buffer[cursor] = select.Selected();
+                       ++cursor;
+               } else {
+                       // noise
+               }
+       }
+}
+
+void CapsuleNameMenu::RemoveChar() {
+       first = false;
+       if (cursor > 0) {
+               --cursor;
+               buffer[cursor] = '_';
+       }
+}
+
+void CapsuleNameMenu::StoreName() {
+       // NOTE: this will leak the memory allocated for the new name
+       char *name = 0;
+       for (int i = 0; i < 6; ++i) {
+               if (buffer[i] == '_' || buffer[i] == '\0') {
+                       buffer[i] = '\0';
+                       name = new char[i + 1];
+                       std::strncpy(name, buffer, i + 1);
+                       break;
+               }
+       }
+       if (name != 0) {
+               GetCapsule().SetName(name);
+       }
+}
+
 void CapsuleNameMenu::UpdateWorld(float deltaT) {
 
 }
@@ -94,8 +164,10 @@ void CapsuleNameMenu::RenderName(SDL_Surface *screen, const Vector<int> &offset)
 void CapsuleNameMenu::RenderAlphabet(SDL_Surface *screen, const Vector<int> &offset) const {
        const Font &font(*parent->Res().normalFont);
        const Frame &frame(*parent->Res().statusFrame);
+       const Vector<int> selectOffset(2 * font.CharWidth(), 2 * font.CharHeight());
 
        frame.Draw(screen, offset, 24 * font.CharWidth(), 17 * font.CharHeight());
+       select.Draw(screen, offset + selectOffset);
 }
 
 
@@ -107,6 +179,10 @@ int CapsuleNameMenu::Height() const {
        return parent->Height();
 }
 
+Capsule &CapsuleNameMenu::GetCapsule() {
+       return parent->GetCapsule();
+}
+
 const Capsule &CapsuleNameMenu::GetCapsule() const {
        return parent->GetCapsule();
 }
index 0021da4d5f2bb3bfc9aee2ab17e783b632e3daa1..77211e2152c8dcc7d53f882d33c31d6aaf25f525 100644 (file)
@@ -5,6 +5,7 @@
 #include "../app/State.h"
 #include "../common/fwd.h"
 #include "../geometry/Vector.h"
+#include "../graphics/CharSelect.h"
 
 namespace menu {
 
@@ -33,17 +34,22 @@ private:
 
        virtual void OnResize(int width, int height);
 
+       common::Capsule &GetCapsule();
        const common::Capsule &GetCapsule() const;
 
-       void LoadInventory();
+       void AddChar();
+       void RemoveChar();
+       void StoreName();
 
        void RenderName(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
        void RenderAlphabet(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
 
 private:
        CapsuleMenu *parent;
+       graphics::CharSelect select;
        int cursor;
        char buffer[6];
+       bool first;
 
 };
 
index a355909d87b1412bba23871fdd8102a0b060e1a6..74e4ccd89512e3f458023bb4cd9235da79b2ed31 100644 (file)
@@ -1,5 +1,6 @@
 #include "Resources.h"
 
+#include "../graphics/CharSelect.h"
 #include "../graphics/Font.h"
 #include "../graphics/Frame.h"
 #include "../graphics/Menu.h"
@@ -8,6 +9,7 @@
 #include "../loader/Interpreter.h"
 #include "../loader/TypeDescription.h"
 
+using graphics::CharSelect;
 using graphics::Font;
 using graphics::Frame;
 using graphics::MenuProperties;
@@ -118,6 +120,8 @@ Resources::Resources()
 , capsuleNoAttackText(0)
 , capsuleNotHungryText(0)
 
+, capsuleNameCharSelectTemplate(0)
+
 { }
 
 
@@ -225,6 +229,8 @@ void Resources::CreateTypeDescription() {
        td.AddField("capsuleAttack3Label", FieldDescription(((char *)&r.capsuleAttack3Label) - ((char *)&r), Interpreter::STRING_ID).SetReferenced());
        td.AddField("capsuleNoAttackText", FieldDescription(((char *)&r.capsuleNoAttackText) - ((char *)&r), Interpreter::STRING_ID).SetReferenced());
        td.AddField("capsuleNotHungryText", FieldDescription(((char *)&r.capsuleNotHungryText) - ((char *)&r), Interpreter::STRING_ID).SetReferenced());
+
+       td.AddField("capsuleNameSelect", FieldDescription(((char *)&r.capsuleNameCharSelectTemplate) - ((char *)&r), CharSelect::TYPE_ID).SetReferenced().SetDescription("properties of the letter array for changing the capsule name"));
 }
 
 void Resources::Construct(void *data) {
index be2fb2559284568a753346e6404d221710be49c1..6fc064167d3ca901508e57d8eaef0dbff1ab31bb 100644 (file)
@@ -108,6 +108,8 @@ struct Resources {
        const char *capsuleNoAttackText;
        const char *capsuleNotHungryText;
 
+       graphics::CharSelect *capsuleNameCharSelectTemplate;
+
        Resources();
 
        static void CreateTypeDescription();
diff --git a/test-data/alpha-cursor.png b/test-data/alpha-cursor.png
new file mode 100644 (file)
index 0000000..2f6832c
Binary files /dev/null and b/test-data/alpha-cursor.png differ
index 722043d1a8cf73e1089b32885eaa11d62eb9ee20..44ffc60d39d27c1c43979a14db7429f3f59d6e13 100644 (file)
@@ -874,5 +874,15 @@ export MenuResources menuResources {
        capsuleAttack2Label: "SP.2",
        capsuleAttack3Label: "SP.3",
        capsuleNoAttackText: "Nothing",
-       capsuleNotHungryText: "I'm not hungry."
+       capsuleNotHungryText: "I'm not hungry.",
+       capsuleNameSelect: CharSelect {
+               font: menuFont,
+               cursor: Sprite {
+                       image: :"alpha-cursor.png",
+                       size: <20, 28>
+               },
+               chars: "0123456789ABCDEabcdeFGHIJfghijKLMNOklmnoPQRSTpqrstUVWXYuvwxyZ!?  z!?  ",
+               width: 10,
+               groupX: 5
+       }
 }