1 // BlinkenSisters - Hunt for the Lost Pixels
2 // Bringing back the fun of the 80s
3 //
4 // (C) 2005-07 Rene Schickbauer, Wolfgang Dautermann
5 //
6 // See License.txt for licensing information
7 //
8
9
10 #include "../globals.h"
11 #include "guihandler.h"
12 #include "../memops.h"
13 #include "../errorhandler.h"
14 #include "../drawprimitives.h"
15 #include "../blending.h"
16 #include "../showtext.h"
17 #include "blinkensound.h"
18 #include "../engine.h"
19 #include <stdio.h>
20 #include <string.h>
21
22 SDL_Surface* guibg = 0;
23 SDL_Surface* buttons[5];
24 bool mouseShown = false;
25 Sint32 mouseX = 100;
26 Sint32 mouseY = 100;
27 bool buttonMouseOver[5];
28 //char* titleDisplay[] = {"Intro", "Menu", "Orient"};
29 //char* titleFile[] = {"introMusic.ogg", "menuMusic.ogg", "sisters_orient.ogg"};
30 Sint32 maxSnd = -1;
31 Sint32 curSnd = 0;
32 double scrolloffset = SCR_WIDTH / 2 * -1;
33
34 TITLES titles[100];
35
initGUI(char * playlist)36 void initGUI(char * playlist) {
37
38 char fullfname[MAX_FNAME_LENGTH];
39 sprintf(fullfname, "%s", configGetPath("blinkenplayerbg.bmp"));
40 SDL_Surface* temp = IMG_Load(fullfname);
41 if(!temp) {
42 DIE(ERROR_IMAGE_READ, fullfname);
43 }
44 guibg = SDL_DisplayFormat(temp);
45 SDL_FreeSurface(temp);
46
47 const char* buttonfiles[] = {"player_prev.bmp",
48 "player_stop.bmp",
49 "player_play.bmp",
50 "player_pause.bmp",
51 "player_next.bmp"};
52
53 for(Uint32 i = 0; i < 5; i++) {
54 sprintf(fullfname, "%s", configGetPath(buttonfiles[i]));
55 temp = IMG_Load(fullfname);
56 if(!temp) {
57 DIE(ERROR_IMAGE_READ, fullfname);
58 }
59 buttons[i] = SDL_DisplayFormat(temp);
60 SDL_FreeSurface(temp);
61 buttonMouseOver[i] = false;
62 }
63
64 if ( playlist == NULL) {
65 /* Play the blinkensisters sounds. No user defined playlist */
66 FILE* fh = fopen(configGetPath("playersounds.dat"), "r");
67 if(!fh) {
68 DIE(ERROR_FILE_READ, configGetPath("playersounds.dat"));
69 }
70
71 char line[1001];
72 char* tmpchar;
73 char* tmpchar2;
74 while(!feof(fh)) {
75 maxSnd++;
76 if(!fgets(line, 1000, fh)) {
77 break;
78 }
79 while((tmpchar = strstr(line, "\n"))) {
80 *tmpchar = 0;
81 }
82 while((tmpchar = strstr(line, "\r"))) {
83 *tmpchar = 0;
84 }
85
86
87 if(!(tmpchar = strstr(line, "|"))) {
88 DIE(ERROR_HTTPTOC, "1|2");
89 }
90 *tmpchar = 0;
91 sprintf(titles[maxSnd].name, "%s", line);
92 tmpchar++;
93 tmpchar2 = tmpchar;
94
95 if(!(tmpchar = strstr(tmpchar, "|"))) {
96 DIE(ERROR_HTTPTOC, "2|3");
97 }
98 *tmpchar = 0;
99 sprintf(titles[maxSnd].fname, "%s", tmpchar2);
100 tmpchar++;
101 tmpchar2 = tmpchar;
102
103 sprintf(titles[maxSnd].scrolltext, "%s", tmpchar2);
104 soundLoad(maxSnd, titles[maxSnd].fname);
105 }
106 fclose(fh);
107 } else {
108 /* Playlist != NULL. Play the songs in the playlist */
109 /* FIXME: Currently only Filenames, no HTTP-URLs allowed */
110 printf("Playlsit: %s\n",playlist);
111 FILE* fh = fopen(playlist, "r");
112 if(!fh) {
113 DIE(ERROR_FILE_READ, playlist);
114 }
115 char line[1001];
116 char* tmpchar;
117 while(!feof(fh)) {
118 maxSnd++;
119 if(!fgets(line, 1000, fh)) {
120 break;
121 }
122 printf("line: %s\n",line);
123 while((tmpchar = strstr(line, "\n"))) {
124 *tmpchar = 0;
125 }
126 while((tmpchar = strstr(line, "\r"))) {
127 *tmpchar = 0;
128 }
129
130 printf("Zeile: %s\n",line);
131 /* FIXME: Use Information from Ogg-tags for the scrolltest and name */
132 sprintf(titles[maxSnd].name, "File: %d", maxSnd);
133 sprintf(titles[maxSnd].fname, "%s", line);
134 sprintf(titles[maxSnd].scrolltext, "Playing File number %d. Hope you like it.", maxSnd);
135 titles[maxSnd].sdlmusic = Mix_LoadMUS(titles[maxSnd].fname);
136 if(!titles[maxSnd].sdlmusic) {
137 DIE(ERROR_SOUND_READ, titles[maxSnd].fname);
138 }
139 }
140 fclose(fh);
141 }
142
143 }
144
deInitGUI()145 void deInitGUI() {
146 SDL_FreeSurface(guibg);
147 guibg = 0;
148 }
149
showGUI()150 void showGUI() {
151
152
153 // Lock screen
154 if (SDL_MUSTLOCK(gScreen))
155 if (SDL_LockSurface(gScreen) < 0)
156 return;
157
158
159 // Lock guibg
160 if (SDL_MUSTLOCK(guibg))
161 if (SDL_LockSurface(guibg) < 0)
162 return;
163
164 Uint32 pitch_bg = gScreen->pitch / 4;
165
166 // Copy the background into the bigger surface
167 Uint32 bigpitch = gScreen->pitch;
168 Uint32 bigpitchBG = guibg->pitch;
169
170 long fc_src_long = (long)guibg->pixels;
171 long fc_dst_long = (long)gScreen->pixels;
172
173 for(Uint32 j=0; j < SCR_HEIGHT; j++) {
174 fc_src = (fastcopy *)fc_src_long;
175 fc_dest = (fastcopy *)fc_dst_long;
176 *fc_dest = *fc_src;
177 fc_dst_long += bigpitch;
178 fc_src_long += bigpitchBG;
179 }
180
181 // Unlock guibg
182 if (SDL_MUSTLOCK(guibg))
183 SDL_UnlockSurface(guibg);
184
185
186 // Paint Buttons
187 Uint32 buttonpitch;
188 Uint32 color;
189 Uint32 width, height;
190 for(Uint32 c = 0; c < 5; c++) {
191 if(buttonMouseOver[c]) {
192 blend_darkenRect((c+1) * 40, 200, 32, 32, 0xd0b0b0);
193 } else {
194 blend_darkenRect((c+1) * 40, 200, 32, 32, 0x909090);
195 }
196 if (SDL_MUSTLOCK(buttons[c]))
197 if (SDL_LockSurface(buttons[c]) < 0)
198 return;
199
200 buttonpitch = buttons[c]->pitch / 4;
201 width = buttons[c]->w;
202 height = buttons[c]->h;
203
204
205 for(Uint32 ybg = 0; ybg < height; ybg++) {
206 for(Uint32 xbg = 0; xbg < width; xbg++) {
207 color = ((Uint32*)buttons[c]->pixels)[xbg + ybg * buttonpitch];
208
209 if(color != 0x0000ff00) {
210 ((Uint32*)gScreen->pixels)[xbg + (c + 1) * 40 + (ybg + 200) * pitch_bg] = color;
211 }
212
213 }
214 }
215
216 if (SDL_MUSTLOCK(buttons[c]))
217 SDL_UnlockSurface(buttons[c]);
218
219 }
220
221 // Paint title
222 blend_darkenRect(5, 30, 300, 25, 0x808080);
223 drawstring(10, 35, titles[curSnd].name, gScreen);
224
225 // Paint scroller
226 blend_darkenRect(0, 0, SCR_WIDTH, 25, 0xa0a0a0);
227 drawstring((Sint32)scrolloffset * -1, 5, titles[curSnd].scrolltext, gScreen);
228
229 // Paint status
230 blend_darkenRect(7 * 40, 200, 100, 32, 0xa0a0a0);
231 if(isPaused) {
232 drawstring(7 * 40 + 8, 208, "Paused", gScreen);
233 } else if(isPlaying) {
234 drawstring(7 * 40 + 8, 208, "Playing", gScreen);
235 } else {
236 drawstring(7 * 40 + 8, 208, "Stopped", gScreen);
237 }
238
239 // --- Paint waveform ---
240 // -- Background
241 blend_darkenRect(40, 50, 340, 128, 0xa0a0a0);
242
243 // -- Grid
244 blend_darkenRect(40, 94, 340, 3, 0xa0a0a0);
245 blend_darkenRect(40, 134, 340, 3, 0xa0a0a0);
246 for(Uint32 offs = 0; offs < 340; offs += 68) {
247 blend_darkenRect(40 + offs, 50, 3, 128, 0xa0a0a0);
248 }
249 blend_darkenRect(377, 50, 3, 128, 0xa0a0a0);
250 blend_darkenRect(40, 50, 340, 3, 0xa0a0a0);
251 blend_darkenRect(40, 175, 340, 3, 0xa0a0a0);
252
253 Sint16 *curWav = (Sint16*)captureSound;
254 curWav++;
255 Sint16 val;
256 Sint16 lastval;
257
258 // find next zero point
259 bool nfound = false;
260 lastval = (curWav[0] >> 9);
261 for(Uint32 offs = 0; offs < 1300; offs++) {
262 val = (curWav[0] >> 9);
263 if(val > 0 && lastval < 0) {
264 nfound = true;
265 break;
266 }
267 curWav++;
268 curWav++;
269 }
270
271
272 // do the painting
273 for(Uint32 offs = 0; offs < 340; offs++) {
274 val = (curWav[0] >> 9) + 50 + 44;
275 curWav++;
276 ((Uint32*)gScreen->pixels)[offs + 40 + val * pitch_bg] = 0x00ff00;
277 ((Uint32*)gScreen->pixels)[offs + 40 + (val+1) * pitch_bg] = 0x00ff00;
278 ((Uint32*)gScreen->pixels)[offs + 40 + (val+2) * pitch_bg] = 0x00ff00;
279 val = (curWav[0] >> 9) + 50 + 84;
280 curWav++;
281 ((Uint32*)gScreen->pixels)[offs + 40 + val * pitch_bg] = 0xff0000;
282 ((Uint32*)gScreen->pixels)[offs + 40 + (val+1) * pitch_bg] = 0xff0000;
283 ((Uint32*)gScreen->pixels)[offs + 40 + (val+2) * pitch_bg] = 0xff0000;
284 //curWav++;
285 //curWav++;
286 }
287
288 // Paint mouse cursor
289 if(mouseShown) {
290 // Do NOT show the crosshair cursor
291 //drawrect(mouseX - 15, mouseY-1, 30, 3, 0x00a0a0a0);
292 //drawrect(mouseX-1, mouseY - 15, 3, 30, 0x00a0a0a0);
293 }
294
295 // Unlock Surfaces if needed
296 if (SDL_MUSTLOCK(gScreen))
297 SDL_UnlockSurface(gScreen);
298
299 // Tell SDL to update the whole screen
300 SDL_Flip(gScreen);
301
302 }
303
runGUI()304 void runGUI() {
305 SDL_Event event;
306 Sint32 x = 0;
307 Sint32 y = 0;
308 Sint32 i;
309 gLastTick = BS_GetTicks();
310
311 //SDL_ShowCursor(SDL_DISABLE);
312 while(1) {
313 while (SDL_PollEvent(&event))
314 {
315 switch (event.type)
316 {
317 case SDL_QUIT:
318 //SDL_ShowCursor(SDL_ENABLE);
319 return;
320 case SDL_KEYUP:
321 if (event.key.keysym.sym == SDLK_q) {
322 //SDL_ShowCursor(SDL_ENABLE);
323 return;
324 }
325 case SDL_MOUSEMOTION:
326 x = event.motion.x;
327 y = event.motion.y;
328 if(!mouseShown && x > 0 && x < SCR_WIDTH - 1 && y > 0 && y < SCR_HEIGHT - 1) {
329 mouseShown = true;
330 SDL_WM_GrabInput(SDL_GRAB_ON);
331 } else if (x == 0 || x == SCR_WIDTH - 1 || y == 0 || y == SCR_HEIGHT - 1) {
332 mouseShown = false;
333 SDL_WM_GrabInput(SDL_GRAB_OFF);
334 }
335
336 mouseX = x;
337 mouseY = y;
338 break;
339
340 case SDL_MOUSEBUTTONUP:
341 if(event.button.button == SDL_BUTTON_LEFT) {
342 for(i = 0; i < 5; i++) {
343 if(mouseShown && y >= 200 && x < 232 && x >= (i+1)*40 && x < (i+1)*40+32) {
344 switch(i) {
345 case 0:
346 soundStepPrev();
347 scrolloffset = SCR_WIDTH / 2 * -1;
348 break;
349 case 1:
350 soundStopMusic();
351 break;
352 case 2:
353 soundStartMusic();
354 break;
355 case 3:
356 soundPauseMusic();
357 break;
358 case 4:
359 soundStepNext();
360 scrolloffset = SCR_WIDTH / 2 * -1;
361 break;
362 }
363 }
364 }
365 }
366 }
367
368 //blend_darkenRect((c+1) * 40, 200, 32, 32, 0xa0a0a0);
369 for(i = 0; i < 5; i++) {
370 if(mouseShown && y >= 200 && x < 232 && x >= (i+1)*40 && x < (i+1)*40+32) {
371 buttonMouseOver[i] = true;
372 } else {
373 buttonMouseOver[i] = false;
374 }
375 }
376
377 }
378
379
380 // "Physics" engine
381 Uint32 tick = BS_GetTicks();
382 // Delay a bit if we're too fast
383 while (tick <= gLastTick) {
384 SDL_Delay(1);
385 //sprintf(errorMessage, "TOO FAST!");
386 tick = BS_GetTicks();
387 }
388
389 while (gLastTick < tick)
390 {
391 // Run at virtual 100FPS
392 gLastTick += 10;
393 scrolloffset += 0.7;
394 if(scrolloffset > (double)(getstringwidth(titles[curSnd].scrolltext) + SCR_WIDTH)) {
395 scrolloffset = -SCR_WIDTH;
396 }
397 }
398
399 showGUI();
400
401 }
402 }
403
404