From: Daniel Karbach Date: Mon, 10 Dec 2012 21:51:54 +0000 (+0100) Subject: implemented capsule renaming X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=9666839d0ca6c794d28226a007870c82ef4ddb20;p=l2e.git implemented capsule renaming --- diff --git a/l2e.cbp b/l2e.cbp index 64f428d..4ff8392 100644 --- a/l2e.cbp +++ b/l2e.cbp @@ -139,6 +139,8 @@ + + diff --git a/src/common/Capsule.h b/src/common/Capsule.h index b1039fa..8d4791d 100644 --- a/src/common/Capsule.h +++ b/src/common/Capsule.h @@ -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 index 0000000..415c7a6 --- /dev/null +++ b/src/graphics/CharSelect.cpp @@ -0,0 +1,124 @@ +#include "CharSelect.h" + +#include "Font.h" +#include "Sprite.h" +#include "../loader/Interpreter.h" +#include "../loader/TypeDescription.h" + +#include + +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 &positionIn) const { + Vector position(positionIn); + Vector lineHead(positionIn); + const Vector step(2 * font->CharWidth(), 0); + const Vector doubleStep(3 * font->CharWidth(), 0); + const Vector newline(0, 2 * font->CharHeight()); + const Vector doubleNewline(0, 3 * font->CharHeight()); + const Vector 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(data); + c->numChars = std::strlen(c->chars); +} + +} diff --git a/src/graphics/CharSelect.h b/src/graphics/CharSelect.h new file mode 100644 index 0000000..c5d4cd8 --- /dev/null +++ b/src/graphics/CharSelect.h @@ -0,0 +1,51 @@ +#ifndef GRAPHICS_CHARSELECT_H_ +#define GRAPHICS_CHARSELECT_H_ + +#include "../geometry/Vector.h" + +#include + +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 &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_ */ diff --git a/src/graphics/fwd.h b/src/graphics/fwd.h index f71c02f..6b3bf43 100644 --- a/src/graphics/fwd.h +++ b/src/graphics/fwd.h @@ -6,6 +6,7 @@ namespace graphics { class Animation; class AnimationRunner; class Camera; +class CharSelect; class Color; class ColorFade; class ComplexAnimation; diff --git a/src/main.cpp b/src/main.cpp index 2611a72..2ecd30a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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(); diff --git a/src/menu/CapsuleMenu.cpp b/src/menu/CapsuleMenu.cpp index ab32a1b..dd61dbd 100644 --- a/src/menu/CapsuleMenu.cpp +++ b/src/menu/CapsuleMenu.cpp @@ -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; } diff --git a/src/menu/CapsuleMenu.h b/src/menu/CapsuleMenu.h index 1491f39..6358a6a 100644 --- a/src/menu/CapsuleMenu.h +++ b/src/menu/CapsuleMenu.h @@ -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; diff --git a/src/menu/CapsuleNameMenu.cpp b/src/menu/CapsuleNameMenu.cpp index 14acd46..58db75e 100644 --- a/src/menu/CapsuleNameMenu.cpp +++ b/src/menu/CapsuleNameMenu.cpp @@ -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 &offset) void CapsuleNameMenu::RenderAlphabet(SDL_Surface *screen, const Vector &offset) const { const Font &font(*parent->Res().normalFont); const Frame &frame(*parent->Res().statusFrame); + const Vector 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(); } diff --git a/src/menu/CapsuleNameMenu.h b/src/menu/CapsuleNameMenu.h index 0021da4..77211e2 100644 --- a/src/menu/CapsuleNameMenu.h +++ b/src/menu/CapsuleNameMenu.h @@ -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 &offset) const; void RenderAlphabet(SDL_Surface *screen, const geometry::Vector &offset) const; private: CapsuleMenu *parent; + graphics::CharSelect select; int cursor; char buffer[6]; + bool first; }; diff --git a/src/menu/Resources.cpp b/src/menu/Resources.cpp index a355909..74e4ccd 100644 --- a/src/menu/Resources.cpp +++ b/src/menu/Resources.cpp @@ -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) { diff --git a/src/menu/Resources.h b/src/menu/Resources.h index be2fb25..6fc0641 100644 --- a/src/menu/Resources.h +++ b/src/menu/Resources.h @@ -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 index 0000000..2f6832c Binary files /dev/null and b/test-data/alpha-cursor.png differ diff --git a/test-data/test.l2s b/test-data/test.l2s index 722043d..44ffc60 100644 --- a/test-data/test.l2s +++ b/test-data/test.l2s @@ -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 + } }