]> git.localhorst.tv Git - l2e.git/blob - src/graphics/CharSelect.cpp
415c7a623f9247db2f9e26ae23d34f25d276b961
[l2e.git] / src / graphics / CharSelect.cpp
1 #include "CharSelect.h"
2
3 #include "Font.h"
4 #include "Sprite.h"
5 #include "../loader/Interpreter.h"
6 #include "../loader/TypeDescription.h"
7
8 #include <cstring>
9
10 using geometry::Vector;
11 using loader::FieldDescription;
12 using loader::Interpreter;
13 using loader::TypeDescription;
14
15 namespace graphics {
16
17 CharSelect::CharSelect()
18 : font(0)
19 , cursor(0)
20 , chars("")
21 , numChars(0)
22 , width(10)
23 , groupX(0)
24 , groupY(0)
25 , selected(0) {
26
27 }
28
29
30 void CharSelect::Draw(SDL_Surface *screen, const Vector<int> &positionIn) const {
31         Vector<int> position(positionIn);
32         Vector<int> lineHead(positionIn);
33         const Vector<int> step(2 * font->CharWidth(), 0);
34         const Vector<int> doubleStep(3 * font->CharWidth(), 0);
35         const Vector<int> newline(0, 2 * font->CharHeight());
36         const Vector<int> doubleNewline(0, 3 * font->CharHeight());
37         const Vector<int> cursorOffset(font->CharWidth() / 2, font->CharHeight() / 2);
38
39         for (int i = 0; chars[i] != '\0'; ++i) {
40                 if (i == selected) {
41                         cursor->DrawCenter(screen, position + cursorOffset);
42                 }
43
44                 font->DrawChar(chars[i], screen, position);
45
46                 if (i % width == width - 1) {
47                         if (groupY > 0 && (i / width) % groupY == groupY - 1) {
48                                 lineHead += doubleNewline;
49                         } else {
50                                 lineHead += newline;
51                         }
52                         position = lineHead;
53                 } else {
54                         if (groupX > 0 && (i % width) % groupX == groupX - 1) {
55                                 position += doubleStep;
56                         } else {
57                                 position += step;
58                         }
59                 }
60         }
61 }
62
63
64 void CharSelect::NextCol() {
65         ++selected;
66         if (selected % width == 0) {
67                 selected -= width;
68         }
69 }
70
71 void CharSelect::PreviousCol() {
72         --selected;
73         if (selected < 0 || selected % width == width - 1) {
74                 selected += width;
75         }
76 }
77
78 void CharSelect::NextRow() {
79         selected += width;
80         if (selected >= numChars) {
81                 selected -= numChars;
82         }
83 }
84
85 void CharSelect::PreviousRow() {
86         selected -= width;
87         if (selected < 0) {
88                 selected += numChars;
89         }
90 }
91
92
93 char CharSelect::Selected() const {
94         return chars[selected];
95 }
96
97
98 void CharSelect::CreateTypeDescription() {
99         CharSelect c;
100
101         TypeDescription &td(TypeDescription::Create(TYPE_ID, "CharSelect"));
102         td.SetConstructor(&Construct);
103         td.SetLoader(&Load);
104         td.SetSize(sizeof(CharSelect));
105
106         td.AddField("font", FieldDescription(((char *)&c.font) - ((char *)&c), Font::TYPE_ID).SetReferenced().SetDescription("the font to use for characters"));
107         td.AddField("cursor", FieldDescription(((char *)&c.cursor) - ((char *)&c), Sprite::TYPE_ID).SetReferenced().SetDescription("sprite for the cursor"));
108         td.AddField("chars", FieldDescription(((char *)&c.chars) - ((char *)&c), Interpreter::STRING_ID).SetReferenced().SetDescription("characters to select from"));
109
110         td.AddField("width", FieldDescription(((char *)&c.width) - ((char *)&c), Interpreter::NUMBER_ID).SetDescription("the width of one row"));
111         td.AddField("groupX", FieldDescription(((char *)&c.groupX) - ((char *)&c), Interpreter::NUMBER_ID).SetDescription("double space after this many columns"));
112         td.AddField("groupY", FieldDescription(((char *)&c.groupY) - ((char *)&c), Interpreter::NUMBER_ID).SetDescription("double space after this many rows"));
113 }
114
115 void CharSelect::Construct(void *data) {
116         new (data) CharSelect;
117 }
118
119 void CharSelect::Load(void *data) {
120         CharSelect *c = reinterpret_cast<CharSelect *>(data);
121         c->numChars = std::strlen(c->chars);
122 }
123
124 }