1 /*
2 * Kuklomenos
3 * Copyright (C) 2008-2009 Martin Bays <mbays@sdf.lonestar.org>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see http://www.gnu.org/licenses/.
17 */
18
19 #include "net.h"
20 #include "overlay.h"
21 #include "conffile.h"
22 #include <SDL_gfxPrimitivesDirty.h>
23
24 #include <SDL/SDL.h>
25 #include <sstream>
26
27 const char* HSProtocolVersion = "v1";
28
29 Overlay highOverlay(-0.1);
30 Overlay lowOverlay(0.1);
31
inputText(SDL_Surface * surface,char * text,int maxlen)32 bool inputText(SDL_Surface* surface, char* text, int maxlen)
33 {
34 // quick-and-dirty text entry:
35 int i=0;
36 text[i] = '\0';
37 SDL_Event event;
38 int done = false;
39 while (!done)
40 {
41 SDL_Delay(50);
42 int redraw = false;
43 while (SDL_PollEvent(&event))
44 switch (event.type)
45 {
46 case SDL_QUIT:
47 return false;
48 case SDL_KEYDOWN:
49 SDLKey sym = event.key.keysym.sym;
50 char c=0;
51 if (0 <= sym - SDLK_0 && sym - SDLK_0 < 10 &&
52 !(event.key.keysym.mod & KMOD_SHIFT))
53 c = (sym - SDLK_0) + '0';
54 else if (0 <= sym - SDLK_a && sym - SDLK_a < 26)
55 if (!(event.key.keysym.mod & KMOD_SHIFT))
56 c = (sym - SDLK_a) + 'a';
57 else
58 c = (sym - SDLK_a) + 'A';
59 if (c)
60 {
61 if (i < maxlen)
62 {
63 text[i++] = c;
64 text[i] = '\0';
65 redraw = true;
66 }
67 }
68
69 else if ( (sym == SDLK_DELETE || sym == SDLK_BACKSPACE) &&
70 i > 0 )
71 {
72 text[--i] = '\0';
73 redraw = true;
74 }
75
76 else if (sym == SDLK_ESCAPE)
77 return false;
78
79 else if (sym == SDLK_RETURN)
80 done = true;
81
82 break;
83 }
84 if (redraw)
85 {
86 lowOverlay.drawstr(surface, text);
87 highOverlay.drawstr(surface, "Pick a username:");
88 SDL_Flip(surface);
89 blankDirty();
90 }
91 }
92 return true;
93 }
waitKey()94 void waitKey()
95 {
96 bool down = false;
97 while (true)
98 {
99 SDL_Delay(50);
100 SDL_Event event;
101 while (SDL_PollEvent(&event))
102 switch (event.type)
103 {
104 case SDL_QUIT:
105 return;
106 case SDL_KEYDOWN:
107 down = true;
108 break;
109 case SDL_KEYUP:
110 if (down)
111 return;
112 break;
113 }
114 }
115 }
showErr(SDL_Surface * surface,const char * error)116 void showErr(SDL_Surface* surface, const char* error)
117 {
118 highOverlay.colour = lowOverlay.colour = 0xff0000ff;
119 highOverlay.drawstr(surface, "Error:");
120 lowOverlay.drawstr(surface, error);
121
122 SDL_Flip(surface);
123 blankDirty();
124
125 waitKey();
126 }
reportHighScore(SDL_Surface * surface,int speed)127 bool reportHighScore(SDL_Surface* surface, int speed)
128 {
129 const double highRating = config.highestRating[speed];
130 if (highRating <= 5.0)
131 return false;
132 highOverlay.colour = lowOverlay.colour = 0x00ffffff;
133 if (config.username[0] == '\0')
134 {
135 highOverlay.drawstr(surface, "Pick a username:");
136 SDL_Flip(surface);
137 blankDirty();
138
139 char username[17];
140 bool ret = inputText(surface, username, 16);
141 if (!ret)
142 {
143 return false;
144 }
145 strncpy(config.username, username, 17);
146 }
147
148 if (config.uuid == 0)
149 {
150 std::string response = "";
151 ostringstream command;
152 command << HSProtocolVersion << ":" << "reg:" << config.username;
153 hssResponseCode ret = doHSSCommand(command.str(), response);
154
155 if (ret == HSS_ERROR || HSS_FAIL)
156 {
157 config.username[0]='\0';
158 if (ret == HSS_ERROR)
159 showErr(surface, response.c_str());
160 else
161 showErr(surface, "Server communication failed");
162 return false;
163 }
164 else
165 {
166 int n = sscanf(response.c_str(), "%x", &config.uuid);
167 if ( n != 1 )
168 {
169 showErr(surface, "Server communication failed");
170 return false;
171 }
172 }
173 }
174
175 highOverlay.drawstr(surface, "Submitting high score");
176 ostringstream s;
177 s << config.username << " - " << highRating << ", " << speedString(speed);
178 lowOverlay.drawstr(surface, s.str());
179 SDL_Flip(surface);
180 blankDirty();
181
182 std::string response = "";
183 ostringstream command;
184 command << HSProtocolVersion << ":" << "sub:" << hex << config.uuid << dec
185 << ":" << speed << ":" << obfuscatedRating(highRating);
186 hssResponseCode ret = doHSSCommand(command.str(), response);
187
188 if (ret == HSS_ERROR || ret == HSS_FAIL)
189 {
190 if (ret == HSS_ERROR)
191 showErr(surface, response.c_str());
192 else
193 showErr(surface, "Server communication failed");
194 return false;
195 }
196 else
197 {
198 highOverlay.drawstr(surface, "Rating Submitted");
199 lowOverlay.drawstr(surface, response);
200 SDL_Flip(surface);
201 blankDirty();
202 waitKey();
203 return true;
204 }
205 }
206