<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" />
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;
--- /dev/null
+#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);
+}
+
+}
--- /dev/null
+#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_ */
class Animation;
class AnimationRunner;
class Camera;
+class CharSelect;
class Color;
class ColorFade;
class ComplexAnimation;
#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"
common::TargetingMode::CreateTypeDescription();
graphics::Animation::CreateTypeDescription();
+ graphics::CharSelect::CreateTypeDescription();
graphics::ComplexAnimation::CreateTypeDescription();
graphics::Font::CreateTypeDescription();
graphics::Frame::CreateTypeDescription();
return parent->Height();
}
+Capsule &CapsuleMenu::GetCapsule() {
+ return *Game().state->capsule;
+}
+
const Capsule &CapsuleMenu::GetCapsule() const {
return *Game().state->capsule;
}
const common::GameConfig &Game() const;
Resources &Res();
const Resources &Res() const;
+ common::Capsule &GetCapsule();
const common::Capsule &GetCapsule() const;
int Width() const;
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] = '_';
+ }
+ }
}
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) {
}
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);
}
return parent->Height();
}
+Capsule &CapsuleNameMenu::GetCapsule() {
+ return parent->GetCapsule();
+}
+
const Capsule &CapsuleNameMenu::GetCapsule() const {
return parent->GetCapsule();
}
#include "../app/State.h"
#include "../common/fwd.h"
#include "../geometry/Vector.h"
+#include "../graphics/CharSelect.h"
namespace menu {
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;
};
#include "Resources.h"
+#include "../graphics/CharSelect.h"
#include "../graphics/Font.h"
#include "../graphics/Frame.h"
#include "../graphics/Menu.h"
#include "../loader/Interpreter.h"
#include "../loader/TypeDescription.h"
+using graphics::CharSelect;
using graphics::Font;
using graphics::Frame;
using graphics::MenuProperties;
, capsuleNoAttackText(0)
, capsuleNotHungryText(0)
+, capsuleNameCharSelectTemplate(0)
+
{ }
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) {
const char *capsuleNoAttackText;
const char *capsuleNotHungryText;
+ graphics::CharSelect *capsuleNameCharSelectTemplate;
+
Resources();
static void CreateTypeDescription();
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
+ }
}