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