1 #include "horhints.h"
2 #include "main.h"
3 #include "utils.h"
4 #include "sound.h"
5
6
7 #define HINTS_COLS 3
8 #define HINTS_ROWS 8
9 #define TILE_GAP_X 4
10 #define TILE_GAP_Y 4
11 #define TILE_X 348
12 #define TILE_Y 68
13 #define TILE_WIDTH 48
14 #define TILE_HEIGHT 48
15
16
HorHints(IconSet & is,Rules & r)17 HorHints::HorHints(IconSet &is, Rules &r): iconSet(is)
18 {
19 reset(r);
20 }
21
22
HorHints(IconSet & is,Rules & rl,std::istream & stream)23 HorHints::HorHints(IconSet &is, Rules &rl, std::istream &stream): iconSet(is)
24 {
25 int qty = readInt(stream);
26
27 for (int i = 0; i < qty; i++) {
28 int no = readInt(stream);
29 numbersArr.push_back(no);
30 Rule *r = getRule(rl, no);
31 int excluded = readInt(stream);
32 if (excluded) {
33 excludedRules.push_back(r);
34 rules.push_back(NULL);
35 } else {
36 excludedRules.push_back(NULL);
37 rules.push_back(r);
38 }
39 }
40
41 showExcluded = readInt(stream);
42
43 int x, y;
44 SDL_GetMouseState(&x, &y);
45 highlighted = getRuleNo(x, y);
46 }
47
48
reset(Rules & r)49 void HorHints::reset(Rules &r)
50 {
51 rules.clear();
52 excludedRules.clear();
53 numbersArr.clear();
54
55 int no = 0;
56 for (Rules::iterator i = r.begin(); i != r.end(); i++) {
57 Rule *rule = *i;
58 if (rule->getShowOpts() == Rule::SHOW_HORIZ) {
59 rules.push_back(rule);
60 excludedRules.push_back(NULL);
61 numbersArr.push_back(no);
62 }
63 no++;
64 }
65
66 showExcluded = false;
67
68 int x, y;
69 SDL_GetMouseState(&x, &y);
70 highlighted = getRuleNo(x, y);
71 }
72
draw()73 void HorHints::draw()
74 {
75 for (int i = 0; i < HINTS_ROWS; i++)
76 for (int j = 0; j < HINTS_COLS; j++)
77 drawCell(j, i, true);
78 }
79
drawCell(int col,int row,bool addToUpdate)80 void HorHints::drawCell(int col, int row, bool addToUpdate)
81 {
82 int x = TILE_X + col * (TILE_WIDTH*3 + TILE_GAP_X);
83 int y = TILE_Y + row * (TILE_HEIGHT + TILE_GAP_Y);
84
85 Rule *r = NULL;
86 int no = row * HINTS_COLS + col;
87 if (no < (int)rules.size())
88 if (showExcluded)
89 r = excludedRules[no];
90 else
91 r = rules[no];
92 if (r)
93 r->draw(x, y, iconSet, no == highlighted);
94 else
95 for (int i = 0; i < 3; i++)
96 screen.draw(x + TILE_HEIGHT*i, y, iconSet.getEmptyHintIcon());
97
98 if (addToUpdate)
99 screen.addRegionToUpdate(x, y, TILE_WIDTH*3, TILE_HEIGHT);
100 }
101
102
onMouseButtonDown(int button,int x,int y)103 bool HorHints::onMouseButtonDown(int button, int x, int y)
104 {
105 if (button != 3)
106 return false;
107
108 int no = getRuleNo(x, y);
109 if (no < 0) return false;
110 int row = no / HINTS_COLS;
111 int col = no - row * HINTS_COLS;
112
113 if (showExcluded) {
114 Rule *r = excludedRules[no];
115 if (r) {
116 sound->play(L"whizz.wav");
117 rules[no] = r;
118 excludedRules[no] = NULL;
119 drawCell(col, row);
120 }
121 } else {
122 Rule *r = rules[no];
123 if (r) {
124 sound->play(L"whizz.wav");
125 rules[no] = NULL;
126 excludedRules[no] = r;
127 drawCell(col, row);
128 }
129 }
130
131 return true;
132 }
133
134
toggleExcluded()135 void HorHints::toggleExcluded()
136 {
137 showExcluded = !showExcluded;
138 draw();
139 }
140
141
onMouseMove(int x,int y)142 bool HorHints::onMouseMove(int x, int y)
143 {
144 int no = getRuleNo(x, y);
145
146 if (no != highlighted) {
147 int old = highlighted;
148 highlighted = no;
149 if (isActive(old)) {
150 int row = old / HINTS_COLS;
151 int col = old - row * HINTS_COLS;
152 drawCell(col, row);
153 }
154 if (isActive(no)) {
155 int row = no / HINTS_COLS;
156 int col = no - row * HINTS_COLS;
157 drawCell(col, row);
158 }
159 }
160
161 return false;
162 }
163
164
getRuleNo(int x,int y)165 int HorHints::getRuleNo(int x, int y)
166 {
167 if (! isInRect(x, y, TILE_X, TILE_Y, (TILE_WIDTH*3 + TILE_GAP_X) * HINTS_COLS,
168 (TILE_HEIGHT + TILE_GAP_Y) * HINTS_ROWS))
169 return -1;
170
171 x = x - TILE_X;
172 y = y - TILE_Y;
173
174 int col = x / (TILE_WIDTH*3 + TILE_GAP_X);
175 if (col * (TILE_WIDTH*3 + TILE_GAP_X) + TILE_WIDTH*3 < x)
176 return -1;
177 int row = y / (TILE_HEIGHT + TILE_GAP_Y);
178 if (row * (TILE_HEIGHT + TILE_GAP_Y) + TILE_HEIGHT < y)
179 return -1;
180
181 int no = row * HINTS_COLS + col;
182 if (no >= (int)rules.size())
183 return -1;
184
185 return no;
186 }
187
isActive(int ruleNo)188 bool HorHints::isActive(int ruleNo)
189 {
190 if ((ruleNo < 0) || (ruleNo >= (int)rules.size()))
191 return false;
192 Rule *r = showExcluded ? excludedRules[ruleNo] : rules[ruleNo];
193 return r != NULL;
194 }
195
196
save(std::ostream & stream)197 void HorHints::save(std::ostream &stream)
198 {
199 int cnt = numbersArr.size();
200 writeInt(stream, cnt);
201 for (int i = 0; i < cnt; i++) {
202 writeInt(stream, numbersArr[i]);
203 writeInt(stream, rules[i] ? 0 : 1);
204 }
205 writeInt(stream, showExcluded ? 1 : 0);
206 }
207
208