1 /*
2 Copyright (C) 2009 Facundo Domínguez
3
4 This file is part of Spacejunk.
5
6 Spacejunk is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Foobar is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <guichan.hpp>
21 #include <guichan/sdl.hpp>
22 #include "graphic.h"
23 #include "screens.h"
24 #include "scorelist.h"
25 #include <sge.h>
26 #include "gcnlayouts.h"
27 #include "soundcollection.h"
28 #include "music.h"
29 #include "bar.h"
30 #include <sstream>
31 #include "parsercombinators.h"
32 #include "fade.h"
33 #include "debugmsg.h"
34 #include "clipping.h"
35 #include "imagescroller.h"
36
37 extern SoundCollection * sounds;
38
39 using namespace std;
40
41 extern int mousePositionX;
42 extern int mousePositionY;
43
44 const int initwait=1000;
45 int waitdelay=0;
46 int laststep;
47
48 /**
49 * @returns false if the event loop must finish.
50 */
GUI_process_events(gcn::SDLInput * input,gcn::SDLGraphics * graphics)51 bool GUI_process_events(gcn::SDLInput * input,gcn::SDLGraphics * graphics) {
52 SDL_Event e;
53 while (SDL_PollEvent(&e)) {
54 if (waitdelay>0) continue;
55 input->pushInput(e);
56 switch (e.type) {
57 case SDL_KEYDOWN:
58 switch (e.key.keysym.sym) {
59 case SDLK_ESCAPE:
60 return false;
61 default:
62 ;
63 }
64 break;
65 case SDL_MOUSEMOTION:
66 mousePositionX=Graphic::fromScreenx(e.motion.x);
67 mousePositionY=Graphic::fromScreeny(e.motion.y);
68 break;
69 case SDL_ACTIVEEVENT: {
70 Uint8 st=SDL_GetAppState();
71 if (st & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) {
72 if (!e.active.gain)
73 Music::pause();
74 else
75 Music::resume();
76 }
77 break;
78 }
79 case SDL_QUIT:
80 throw 0;
81 return false;
82 default:
83 ;
84 }
85 };
86 return true;
87 };
88
89 class MainScreenAction : public gcn::ActionListener {
90 private:
91 ButtonPress * st;
92 bool * quit;
93 int * levelcount;
94 int leveltotal;
95 public:
MainScreenAction(ButtonPress * st,bool * q,int * levelcount,int leveltotal)96 MainScreenAction(ButtonPress * st,bool * q,int * levelcount,int leveltotal) :
97 st(st),quit(q),levelcount(levelcount),leveltotal(leveltotal) {};
action(const gcn::ActionEvent & actionEvent)98 void action (const gcn::ActionEvent& actionEvent) {
99 const string id = actionEvent.getId();
100 if (sounds && id!="quit" && id!="play" && id!="levelup" && id!="leveldown") sounds->mainScreenMenuButtons.play();
101 if (id=="play") {
102 if (sounds) sounds->playButton.play();
103 *st=PLAYBT;
104 *quit=true;
105 } else if (id=="quit") {
106 *quit=true;
107 } else if (id=="scores") {
108 *st=SCORESBT;
109 *quit=true;
110 } else if (id=="levelup") {
111 if (leveltotal>0) {
112 (*levelcount)++;
113 *levelcount%=leveltotal;
114 }
115 } else if (id=="leveldown") {
116 if (leveltotal>0) {
117 (*levelcount)+=leveltotal-1;
118 *levelcount%=leveltotal;
119 }
120 } else if (id=="story") {
121 *st=STORYBT;
122 *quit=true;
123 } else if (id=="credits") {
124 *st=CREDITSBT;
125 *quit=true;
126 } else if (id=="scores") {
127 *st=SCORESBT;
128 *quit=true;
129 } else if (id=="options") {
130 *st=OPTIONSBT;
131 *quit=true;
132 } else if (id=="editor") {
133 *st=EDITORBT;
134 *quit=true;
135 } else if (id=="multiplayer") {
136 *st=MULTIPLAYERBT;
137 *quit=true;
138 }
139 }
140 };
141
142 extern int mousePositionX;
143 extern int mousePositionY;
144
145 class ImageButton : public gcn::Button {
146 public:
147 ImageButton(const std::string & label,const std::string & imgid);
148
draw(gcn::Graphics * g)149 void draw(gcn::Graphics *g) {
150 int x=g->getCurrentClipArea().xOffset;
151 int y=g->getCurrentClipArea().yOffset;
152 img.setFrame(isPressed()?1:0);
153 img.draw(x,y);
154 }
155 private:
156 Graphic img;
157 };
158
ImageButton(const std::string & label,const std::string & imgid)159 ImageButton::ImageButton(const std::string & label,const std::string & imgid) :
160 gcn::Button(label), img(imgid,false) {
161 setDimension(gcn::Rectangle(0,0,img.getWidth(),img.getHeight()));
162 setFrameSize(0);
163 };
164
165
166 class FontButton : public gcn::Button {
167 public:
168 FontButton(const std::string & label,const std::string & fontid,const std::string & fontgrayid);
169
draw(gcn::Graphics * g)170 void draw(gcn::Graphics *g) {
171 int x=g->getCurrentClipArea().xOffset;
172 int y=g->getCurrentClipArea().yOffset;
173 if (isPressed()) font->draw(x,y,getCaption());
174 else fontgray->draw(x,y,getCaption());
175 }
176
177 private:
178 RMFONTRef font;
179 RMFONTRef fontgray;
180 };
181
FontButton(const std::string & label,const std::string & fontid,const std::string & fontgrayid)182 FontButton::FontButton(const std::string & label,const std::string & fontid,const std::string & fontgrayid) :
183 gcn::Button(label), font(fontid), fontgray(fontgrayid) {
184 setDimension(gcn::Rectangle(0,0,font->getWidth(label)+1,font->getHeight()));
185 setFrameSize(0);
186 };
187
188
mainScreen(int & levelcount,int leveltotal)189 ButtonPress mainScreen(int & levelcount,int leveltotal) {
190
191 SDL_WM_SetCaption("Spacejunk","Spacejunk");
192 Graphic::setPalette("title",SDL_LOGPAL);
193
194 gcn::SDLImageLoader imageLoader;
195 gcn::Image::setImageLoader(&imageLoader);
196
197 gcn::SDLGraphics graphics;
198 graphics.setTarget(Graphic::getScreen());
199 RMFONTRef font("asimovgray20");
200
201 //ImageFont font("fixedfont.bmp", " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
202 gcn::Widget::setGlobalFont(&*font);
203
204 gcn::SDLInput input;
205 ButtonPress state=QUITBT;
206 bool quit=false;
207
208 MainScreenAction a(&state,&quit,&levelcount,leveltotal);
209 //EditorControl ec;
210 LeftVerticalLayout c;
211 Graphic titlescreen("titlescreen",false,true);
212 Graphic mousepointer("mousepointer",false);
213 gcn::Label numlevel(getText("numlevelbt"));
214
215 char s[5];
216 snprintf(s,5,"%2d",levelcount+1);
217 gcn::Label numl("00");
218 numl.setCaption(s);
219 FontButton ldown("<<","asimov20","asimovgray20"), lup(">>","asimov20","asimovgray20");
220 CenterHorizontalLayout levell(5);
221 ldown.setActionEventId("leveldown");
222 ldown.addActionListener(&a);
223 lup.setActionEventId("levelup");
224 lup.addActionListener(&a);
225 levell.add(&numlevel);
226 levell.add(&ldown);
227 levell.add(&numl);
228 levell.add(&lup);
229 levell.fitWidgets();
230
231 FontButton bt(getText("playbt"),"asimov20","asimovgray20"),
232 btStory(getText("storybt"),"asimov20","asimovgray20"),
233 bt3(getText("scoresbt"),"asimov20","asimovgray20"),
234 bt5(getText("optionsbt"),"asimov20","asimovgray20"),
235 bt2(getText("quitbt"),"asimov20","asimovgray20"),
236 bt7(getText("creditsbt"),"asimov20","asimovgray20");
237 FontButton bt6(getText("leveleditorbt"),"asimov20","asimovgray20");
238 bt.setActionEventId("play");
239 bt.addActionListener(&a);
240 bt3.setActionEventId("scores");
241 bt3.addActionListener(&a);
242 bt6.setActionEventId("editor");
243 bt6.addActionListener(&a);
244 bt5.setActionEventId("options");
245 bt5.addActionListener(&a);
246 bt7.setActionEventId("credits");
247 bt7.addActionListener(&a);
248 bt2.setActionEventId("quit");
249 bt2.addActionListener(&a);
250 btStory.setActionEventId("story");
251 btStory.addActionListener(&a);
252 c.add(&bt);
253 c.add(&levell);
254 c.add(&btStory);
255 c.add(&bt5);
256 c.add(&bt3);
257 c.add(&bt6);
258 c.add(&bt7);
259 c.add(&bt2);
260 c.setOpaque(false);
261 c.fitWidgets();
262 c.setPosition(Graphic::toScreenx(395),Graphic::toScreeny(148));
263 gcn::Gui gui;
264 gui.setGraphics(&graphics);
265 gui.setInput(&input);
266 gui.setTop(&c);
267
268 int nx,ny;
269 numl.getAbsolutePosition(nx,ny);
270 SDL_Rect numlrect = {Graphic::fromScreenx(nx),Graphic::fromScreeny(ny),
271 int(numl.getWidth()/Graphic::getBaseScaleFactorX()),int(numl.getHeight()/Graphic::getBaseScaleFactorY())};
272 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
273 Fade fade;
274 fade.setMode(Fade::IN,1000);
275 bool endfade=false;
276 while (!quit && GUI_process_events(&input,&graphics)) {
277 titlescreen.draw(0,0);
278 gui.logic();
279 gui.draw();
280 if (!fade.step()) {
281 endfade=true;
282 break;
283 }
284 mousepointer.draw(mousePositionX,mousePositionY);
285
286 Graphic::flip();
287 Graphic::sleep(20);
288 }
289 if (endfade) {
290 UPDATEbegin;
291 bool first=true;
292 while (!quit && GUI_process_events(&input,&graphics)) {
293 UPDATEOFF(titlescreen.draw(0,0));
294 gui.logic();
295
296 char s[5];
297 snprintf(s,5,"%2d",levelcount+1);
298 numl.setCaption(s);
299 Graphic::updateRect(&numlrect);
300
301 gui.draw();
302 mousepointer.draw(mousePositionX,mousePositionY);
303
304 Graphic::flip(first);
305 first=false;
306 Graphic::sleep(20);
307 }
308 UPDATEend;
309 }
310 fade.setMode(Fade::OUT,state==PLAYBT?1000:500);
311 while (fade.getMode()!=Fade::NONE) {
312 GUI_process_events(&input,&graphics);
313 titlescreen.draw(0,0);
314 gui.logic();
315 gui.draw();
316 mousepointer.draw(mousePositionX,mousePositionY);
317 if (!fade.step()) break;
318
319 Graphic::flip();
320 Graphic::sleep(20);
321 }
322
323 return state;
324 };
325
326
fallen_process_events(int * state)327 bool fallen_process_events(int * state) {
328 SDL_Event e;
329 while (SDL_PollEvent(&e)) {
330 if (waitdelay>0) continue;
331 switch (e.type) {
332 case SDL_KEYDOWN:
333 switch (e.key.keysym.sym) {
334 case SDLK_ESCAPE:
335 *state=0;
336 return false;
337 default:
338 *state=1;
339 return false;
340 }
341 break;
342 case SDL_MOUSEBUTTONDOWN:
343 *state=1;
344 return false;
345 case SDL_ACTIVEEVENT: {
346 Uint8 st=SDL_GetAppState();
347 if (st & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) {
348 if (!e.active.gain)
349 Music::pause();
350 else
351 Music::resume();
352 }
353 break;
354 }
355 case SDL_QUIT:
356 throw 0;
357 *state=0;
358 return false;
359 default:
360 ;
361 }
362 };
363 return true;
364 }
365
fallenScreen()366 bool fallenScreen() {
367
368 RMFONTRef fr("24p");
369 Graphic planet("star3",false);
370 int state=0;
371 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
372 Graphic::flip();
373 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
374
375 string text=getText("leveldied");
376 laststep=Graphic::ticks();
377 waitdelay=initwait;
378
379 Fade f;
380 f.setMode(Fade::IN,1000);
381 while (fallen_process_events(&state)) {
382 planet.draw(Graphic::screencenter-Vector2d(125,325));
383 fr->drawL(int(Graphic::screencenter.x),int(Graphic::screencenter.y),text,FontRenderer::CENTER);
384 f.step();
385 Graphic::flip();
386 Graphic::sleep(40);
387
388 int delta=Graphic::ticks()-laststep;
389 if (waitdelay<delta) waitdelay=0;
390 else waitdelay-=delta;
391 laststep+=delta;
392 }
393
394 f.setMode(Fade::OUT,1000);
395 while (f.getMode()!=Fade::NONE) {
396 planet.draw(Graphic::screencenter-Vector2d(125,325));
397 fr->drawL(int(Graphic::screencenter.x),int(Graphic::screencenter.y),text,FontRenderer::CENTER);
398 f.step();
399 Graphic::flip();
400 Graphic::sleep(40);
401 }
402
403 return state;
404 };
405
406
lastLevelScreen()407 void lastLevelScreen() {
408
409 Music::play("final");
410
411 RMFONTRef fr("24p");
412 Graphic ship("starship1",false);
413 Graphic trash("trash8");
414 Graphic trash1("trash6");
415 Graphic trash2("trash2");
416 Graphic g1("galaxia1",false);
417 Graphic g2("galaxia0grande",false);
418 Graphic g3("galaxia3",false);
419 Graphic s1("farstargroup1",false);
420 Graphic s2("farstargroup2",false);
421 Graphic s3("farstargroup3",false);
422 int state=0;
423 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
424 Graphic::flip();
425 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
426 string text=getText("endcongratulation");
427 int init=laststep=Graphic::ticks();
428 waitdelay=initwait;
429
430 Fade f;
431 f.setMode(Fade::IN,1000);
432 while (fallen_process_events(&state)) {
433 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
434 g1.draw(50,400);
435 g2.draw(400,0);
436 g3.draw(50,50);
437 s1.draw(450,250);
438 s2.draw(100,350);
439 s2.draw(50,120);
440 s3.draw(250,250);
441 ship.draw(Graphic::screencenter-Vector2d(16,100+(laststep-init)*0.03));
442 trash.draw(int(Graphic::screencenter.x),int(Graphic::screencenter.y+100),1,(laststep-init)*0.05);
443 trash1.draw(100,50,1,(laststep-init)*0.1);
444 trash2.draw(500,100,1,(laststep-init)*0.2);
445 fr->drawL(int(Graphic::screencenter.x),int(Graphic::screencenter.y)-50,text,FontRenderer::CENTER);
446
447 if (f.step()) break;
448 Graphic::flip();
449 Graphic::sleep(30);
450
451 int delta=Graphic::ticks()-laststep;
452 if (waitdelay<delta) waitdelay=0;
453 else waitdelay-=delta;
454 laststep+=delta;
455 }
456
457 UPDATEbegin;
458 while (fallen_process_events(&state)) {
459 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
460 UPDATEOFF(g1.draw(50,400));
461 UPDATEOFF(g2.draw(400,0));
462 UPDATEOFF(g3.draw(50,50));
463 UPDATEOFF(s1.draw(450,250));
464 UPDATEOFF(s2.draw(100,350));
465 UPDATEOFF(s2.draw(50,120));
466 UPDATEOFF(s3.draw(250,250));
467 ship.draw(Graphic::screencenter-Vector2d(16,100+(laststep-init)*0.03));
468 trash.draw(int(Graphic::screencenter.x),int(Graphic::screencenter.y+100),1,(laststep-init)*0.05);
469 trash1.draw(100,50,1,(laststep-init)*0.1);
470 trash2.draw(500,100,1,(laststep-init)*0.2);
471 fr->drawL(int(Graphic::screencenter.x),int(Graphic::screencenter.y)-50,text,FontRenderer::CENTER);
472
473 Graphic::flip();
474 Graphic::sleep(30);
475
476 int delta=Graphic::ticks()-laststep;
477 if (waitdelay<delta) waitdelay=0;
478 else waitdelay-=delta;
479 laststep+=delta;
480 }
481 UPDATEend;
482
483 f.setMode(Fade::OUT,500);
484 while (f.getMode()!=Fade::NONE) {
485 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
486 g1.draw(50,400);
487 g2.draw(400,0);
488 g3.draw(50,50);
489 s1.draw(450,250);
490 s2.draw(100,350);
491 s2.draw(50,120);
492 s3.draw(250,250);
493 ship.draw(Graphic::screencenter-Vector2d(16,100+(laststep-init)*0.03));
494 trash.draw(int(Graphic::screencenter.x),int(Graphic::screencenter.y)+100,1,(laststep-initwait)*0.05);
495 trash1.draw(100,50,1,(laststep-init)*0.1);
496 trash2.draw(500,100,1,(laststep-init)*0.2);
497 fr->drawL(int(Graphic::screencenter.x),int(Graphic::screencenter.y)-50,text,FontRenderer::CENTER);
498 f.step();
499 Graphic::flip();
500 Graphic::sleep(40);
501
502 int delta=Graphic::ticks()-laststep;
503 laststep+=delta;
504 }
505 };
506
scoreScreen(const ScoreList & scorelist)507 void scoreScreen(const ScoreList &scorelist) {
508 RMFONTRef fr("12p");
509 RMFONTRef fr2("asimov27");
510 fr->linespacing=15;
511 int state=0;
512 Graphic background("scorescreen",false);
513 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
514 string names=scorelist.getNames();
515 string points=scorelist.getPoints();
516 string title=getText("scoresbt");
517
518 Fade f;
519 f.setMode(Fade::IN,1000);
520 while (fallen_process_events(&state)) {
521 background.draw(0,0);
522 fr->drawL(195,125,names);
523 fr->drawL(450,125,points,FontRenderer::RIGHT);
524 fr2->drawL((640-fr2->getWidth(title))/2,50,title);
525 f.step();
526 Graphic::flip();
527 Graphic::sleep(40);
528 }
529 f.setMode(Fade::OUT,500);
530 while (f.getMode()!=Fade::NONE) {
531 background.draw(0,0);
532 fr->drawL(195,125,names);
533 fr->drawL(450,125,points,FontRenderer::RIGHT);
534 fr2->drawL((640-fr2->getWidth(title))/2,50,title);
535 f.step();
536 Graphic::flip();
537 Graphic::sleep(40);
538 }
539 };
540
enter_score_process_events(sge_TextEditor & text)541 bool enter_score_process_events(sge_TextEditor & text) {
542 SDL_Event e;
543 while (SDL_PollEvent(&e)) {
544 switch (e.type) {
545 case SDL_KEYDOWN:
546 switch (e.key.keysym.sym) {
547 case SDLK_QUOTEDBL:
548 break;
549 case SDLK_RETURN:
550 if (sounds) sounds->typeEnter.play();
551 case SDLK_ESCAPE:
552 if (text.get_string(false).length()>0 && sounds)
553 sounds->typeEnter.play();
554 return false;
555 case SDLK_DELETE:
556 case SDLK_BACKSPACE:
557 case SDLK_RSHIFT:
558 case SDLK_LSHIFT:
559 case SDLK_LEFT:
560 case SDLK_RIGHT:
561 text.check(&e);
562 break;
563 default:
564 if (text.get_string(false).length()<30) {
565 if (sounds && e.key.keysym.unicode!=0)
566 sounds->typeNotEnter.play();
567 text.check(&e);
568 }
569 }
570 break;
571 case SDL_ACTIVEEVENT: {
572 Uint8 st=SDL_GetAppState();
573 if (st & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) {
574 if (!e.active.gain)
575 Music::pause();
576 else
577 Music::resume();
578 }
579 break;
580 }
581 case SDL_QUIT:
582 throw 0;
583 return false;
584 default:
585 text.check(&e);
586 }
587 };
588 return true;
589 }
590
remapwsUint16(Uint16 * str)591 string remapwsUint16(Uint16*str) {
592 basic_string<wchar_t> s;
593 for (;*str;str++)
594 s+=*str;
595 return wstos(s);
596 }
597
enterScoreScreen(ScoreList * scorelist,int playerPoints)598 void enterScoreScreen(ScoreList * scorelist,int playerPoints) {
599 if (playerPoints<=0 || (!scorelist->inside(playerPoints) && scorelist->size()>=14)) return;
600
601 Graphic background("scorescreen",false);
602 RMFONTRef fr("12p");
603 fr->linespacing=15;
604 SDL_Rect r={0,0,LOGICAL_WIDTH,LOGICAL_HEIGHT};
605 ScoreList::iterator i=scorelist->setScore("",playerPoints);
606 int posy=scorelist->position(i)*(fr->getHeight()+fr->linespacing);
607 while (scorelist->size()>14) {
608 scorelist->erase_last();
609 }
610
611 string names=scorelist->getNames();
612 string points=scorelist->getPoints();
613 sge_TextEditor text;
614
615 Uint16 * t;
616 Fade f;
617 f.setMode(Fade::IN,1000);
618 while (enter_score_process_events(text)) {
619 SDL_FillRect(Graphic::getScreen(),&r,SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
620 background.draw(0,0);
621 fr->drawL(195,125,names);
622 t=text.get_ucstring((Graphic::ticks()/300)%2);
623 fr->drawLine(Graphic::toScreenx(195),Graphic::toScreeny(125)+posy,remapwsUint16(t));
624 delete t;
625 fr->drawL(450,125,points,FontRenderer::RIGHT);
626 f.step();
627 Graphic::flip();
628 Graphic::sleep(40);
629 }
630 t=text.get_ucstring(false);
631 if (*t!=L'\0')
632 scorelist->setName(remapwsUint16(t),i);
633 else
634 scorelist->erase(i);
635 delete t;
636
637 f.setMode(Fade::OUT,500);
638 while (f.getMode()!=Fade::NONE) {
639 SDL_FillRect(Graphic::getScreen(),&r,SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
640 background.draw(0,0);
641 fr->drawL(195,125,names);
642 t=text.get_ucstring();
643 fr->drawLine(Graphic::toScreenx(195),Graphic::toScreeny(125)+posy,remapwsUint16(t));
644 delete t;
645 fr->drawL(450,125,points,FontRenderer::RIGHT);
646 f.step();
647 Graphic::flip();
648 Graphic::sleep(40);
649 }
650 };
651
652
countLines(const std::string & text)653 int countLines(const std::string& text) {
654 int count=0;
655 for(unsigned int i=0;i<text.length();i++) {
656 if (text[i]=='\n')
657 count++;
658 }
659 return count;
660 }
661
662
storyScreen()663 void storyScreen() {
664 RMFONTRef fr("24p");
665 RMFONTRef fr2("asimov27");
666 int state=0;
667 Graphic background("storyscreen",false);
668 string story=getText("story");
669 string title=getText("storybt");
670
671 /*******************************************
672 Get the text on a temporal surface
673 *******************************************/
674 SDL_Surface * screen=Graphic::getScreen();
675 SDL_Surface * temp=Graphic::createSurface(Graphic::toScreenw(400),Graphic::toScreenh(520));
676 SDL_FillRect(temp,NULL,SDL_MapRGB(screen->format, 0x00, 0x00, 0x00));
677 fr->s=temp;
678 fr->draw(0,0,story);
679 fr->s=NULL;
680
681 const int textheight = (fr->getHeight()+fr->linespacing)*countLines(story);
682 const int windowheight = LOGICAL_HEIGHT-(150+50);
683 const bool drawfull = textheight/Graphic::getBaseScaleFactorY()<=windowheight;
684 SDL_Rect orig={0,-windowheight,400,windowheight};
685 SDL_Rect dest={175,150,400,windowheight};
686 ImageScroller imgs(temp,orig,0.010);
687
688
689 /*******************************************
690 Fade In
691 *******************************************/
692
693 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
694 Fade f;
695 f.setMode(Fade::IN,1000);
696 while (fallen_process_events(&state)) {
697 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
698 background.draw(0,0);
699 fr2->drawL(265,91,title);
700 if (drawfull)
701 imgs.draw(Graphic::getScreen(),175,dest.y,drawfull);
702 if (!f.step())
703 break;
704 Graphic::flip();
705 Graphic::sleep(30);
706 }
707
708 imgs.reset();
709 bool first = true;
710 UPDATEbegin
711 while (fallen_process_events(&state)) {
712 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
713 UPDATEOFF(background.draw(0,0);fr2->drawL(265,91,title));
714 imgs.draw(Graphic::getScreen(),175,dest.y,drawfull);
715 Graphic::updateRect(&dest);
716 Graphic::flip(first);
717 first = false;
718 Graphic::sleep(30);
719 }
720 UPDATEend
721
722 f.setMode(Fade::OUT,500);
723 while (f.getMode()!=Fade::NONE) {
724 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
725 background.draw(0,0);
726 fr2->drawL(265,91,title);
727 imgs.draw(Graphic::getScreen(),175,dest.y,drawfull);
728 f.step();
729 Graphic::flip();
730 Graphic::sleep(30);
731 }
732
733 SDL_FreeSurface(temp);
734 };
735
creditsScreen()736 void creditsScreen() {
737 RMFONTRef fr("asimovgray20");
738 RMFONTRef fr2("asimov27");
739 int state=0;
740 Graphic background("storyscreen",false);
741 string credittitles=getText("credittitles");
742 string creditnames=getText("creditnames");
743 string title=getText("creditsbt");
744
745 /*******************************************
746 Get the text on a temporal surface
747 *******************************************/
748 SDL_Surface * screen=Graphic::getScreen();
749 SDL_Surface * temp=Graphic::createSurface(Graphic::toScreenw(400),Graphic::toScreenh(520));
750 SDL_FillRect(temp,NULL,SDL_MapRGB(screen->format, 0x00, 0x00, 0x00));
751 fr->s=temp;
752 fr->draw(Graphic::toScreenw(175),0,credittitles,FontRenderer::CENTER);
753 fr->s=NULL;
754 fr=RMFONTRef("asimov20");
755 fr->s=temp;
756 fr->draw(Graphic::toScreenw(175),0,creditnames,FontRenderer::CENTER);
757 fr->s=NULL;
758
759 /*******************************************
760 Fade In
761 *******************************************/
762
763 Fade f;
764 f.setMode(Fade::IN,1000);
765 while (fallen_process_events(&state)) {
766 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
767 background.draw(0,0);
768 fr2->drawL(275,91,title);
769 if (!f.step()) break;
770 Graphic::flip();
771 Graphic::sleep(30);
772 }
773
774 const int windowheight = LOGICAL_HEIGHT-(150+50);
775 SDL_Rect orig={0,-windowheight,400,windowheight};
776 SDL_Rect dest={150,150,400,windowheight};
777 ImageScroller imgs(temp,orig,0.015);
778
779 UPDATEbegin
780 while (fallen_process_events(&state)) {
781 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
782 UPDATEOFF(background.draw(0,0));
783 UPDATEOFF(fr2->drawL(275,91,title));
784 imgs.draw(Graphic::getScreen(),dest.x,dest.y,false);
785 Graphic::updateRect(&dest);
786 Graphic::flip(false);
787 Graphic::sleep(30);
788 }
789 UPDATEend
790
791 f.setMode(Fade::OUT,500);
792 while (f.getMode()!=Fade::NONE) {
793 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
794 background.draw(0,0);
795 fr2->drawL(275,91,title);
796 imgs.draw(Graphic::getScreen(),dest.x,dest.y,false);
797 f.step();
798 Graphic::flip();
799 Graphic::sleep(30);
800 }
801
802 SDL_FreeSurface(temp);
803 };
804
giveUpScreen()805 bool giveUpScreen() {
806 RMFONTRef fr("24p");
807 Graphic planet("planet1",false);
808 int state=0;
809 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
810 Graphic::flip();
811 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
812 string text=getText("giveup");
813
814 Fade f;
815 f.setMode(Fade::IN,1000);
816 while (fallen_process_events(&state)) {
817 planet.draw(Graphic::screencenter-Vector2d(50,150));
818 fr->drawL(int(Graphic::screencenter.x),int(Graphic::screencenter.y),text,FontRenderer::CENTER);
819 f.step();
820 Graphic::flip();
821 Graphic::sleep(40);
822 }
823
824 f.setMode(Fade::OUT,500);
825 while (f.getMode()!=Fade::NONE) {
826 planet.draw(Graphic::screencenter-Vector2d(50,150));
827 fr->drawL(int(Graphic::screencenter.x),int(Graphic::screencenter.y),text,FontRenderer::CENTER);
828 f.step();
829 Graphic::flip();
830 Graphic::sleep(40);
831 }
832
833 return state;
834 };
835
missionFailedScreen()836 bool missionFailedScreen() {
837 RMFONTRef fr("24p");
838 Graphic planet("nebula1",false);
839 int state=0;
840 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
841 Graphic::flip();
842 Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0));
843
844 string text=getText("missionFailed");
845 laststep=Graphic::ticks();
846 waitdelay=initwait;
847
848 Fade f;
849 f.setMode(Fade::IN,1000);
850 while (fallen_process_events(&state)) {
851 planet.draw(Graphic::screencenter-Vector2d(75,175));
852 fr->drawL(int(Graphic::screencenter.x),int(Graphic::screencenter.y),text,FontRenderer::CENTER);
853 f.step();
854 Graphic::flip();
855 Graphic::sleep(40);
856
857 int delta=Graphic::ticks()-laststep;
858 if (waitdelay<delta) waitdelay=0;
859 else waitdelay-=delta;
860 laststep+=delta;
861 }
862
863 f.setMode(Fade::OUT,500);
864 while (f.getMode()!=Fade::NONE) {
865 planet.draw(Graphic::screencenter-Vector2d(75,175));
866 fr->drawL(int(Graphic::screencenter.x),int(Graphic::screencenter.y),text,FontRenderer::CENTER);
867 f.step();
868 Graphic::flip();
869 Graphic::sleep(40);
870 }
871
872 return state;
873 };
874
875
876
congratulation_process_events(int * state)877 bool congratulation_process_events(int * state) {
878 SDL_Event e;
879 while (SDL_PollEvent(&e)) {
880 if (waitdelay>0) continue;
881 switch (e.type) {
882 case SDL_KEYDOWN:
883 switch (e.key.keysym.sym) {
884 default:
885 *state=1;
886 return false;
887 }
888 break;
889 case SDL_MOUSEBUTTONDOWN:
890 *state=1;
891 return false;
892 case SDL_ACTIVEEVENT: {
893 Uint8 st=SDL_GetAppState();
894 if (st & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) {
895 if (!e.active.gain)
896 Music::pause();
897 else
898 Music::resume();
899 }
900 break;
901 }
902 case SDL_QUIT:
903 throw 0;
904 *state=0;
905 return false;
906 default:
907 ;
908 }
909 };
910 return true;
911 }
912
913
914 #define drawsumary Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0)); \
915 UPDATEOFF(planet.draw(500,250)); \
916 UPDATEOFF(planet2.draw(200,200)); \
917 UPDATEOFF(farstar.draw(600,50)); \
918 UPDATEOFF(farstar.draw(350,150)); \
919 UPDATEOFF(farstar.draw(100,100)); \
920 UPDATEOFF(farstar.draw(300,430)); \
921 fuelbar.draw(units/TOTALFUELPOINTS); \
922 UPDATEOFF(scoredisplay.draw((LOGICAL_WIDTH-scoredisplay.getWidth())/2,0)); \
923 UPDATEOFF(shipcontrol.draw(0,LOGICAL_HEIGHT-shipcontrol.getHeight())); \
924 o.str(""); \
925 o<<bonus; \
926 fr->drawL(380,5,o.str(),FontRenderer::RIGHT); \
927 o.str(""); \
928 o<<*score; \
929 fr->drawL(240,5,o.str(),FontRenderer::RIGHT); \
930 fr->drawL(520,5,"0",FontRenderer::RIGHT); \
931 fr2->drawL(int(Graphic::screencenter.x),int(Graphic::screencenter.y)-170,text,FontRenderer::CENTER); \
932 UPDATEOFF(font24pgray->drawL(scorelabelx,1,scorelabel)); \
933 UPDATEOFF(font24pgray->drawL(bonuslabelx,1,bonuslabel)); \
934 UPDATEOFF(font24pgray->drawL(collectlabelx,1,collectlabel));
935
936 #define TOTALFUELPOINTS (50.0)
937 #define DISCOUNTUNIT (25)
938
sumaryScreen(real fuel,real maxFuel,int bonus,int * score)939 bool sumaryScreen(real fuel,real maxFuel,int bonus,int * score) {
940
941 Music::play("success");
942
943 FuelBar fuelbar;
944 RMFONTRef fr("12p");
945 RMFONTRef fr2("24p");
946 RMFONTRef font24pgray("24pgray");
947
948 string scorelabel=getText("scorelabel");
949 string bonuslabel=getText("bonuslabel");
950 string collectlabel=getText("collectlabel");
951
952 Graphic planet("star2",false);
953 Graphic planet2("planet2",false);
954 Graphic farstar("farstar1",false);
955
956 Graphic scoredisplay("scoredisplay",false);
957 Graphic shipcontrol("controlpanel",false);
958 string text=getText("levelcongratulation");
959
960 int scorex = (LOGICAL_WIDTH-scoredisplay.getWidth())/2;
961 int scorelabelx = scorex + 59;
962 int bonuslabelx = scorex + 200;
963 int collectlabelx = scorex + 343;
964
965
966 int units=int(floor(fuel*TOTALFUELPOINTS/maxFuel));
967 int unitTime=0;
968 int delta;
969 int state=0;
970 waitdelay=initwait;
971
972 ostringstream o;
973
974 Fade f;
975 f.setMode(Fade::IN,1000);
976 while (f.getMode()!=Fade::NONE) {
977 drawsumary;
978 f.step();
979 Graphic::flip();
980 }
981
982 laststep=Graphic::ticks();
983 delta=50;
984
985 if (sounds) sounds->timeBack.play();
986
987 while (congratulation_process_events(&state)) {
988 drawsumary;
989 Graphic::flip();
990
991 if (units>0) {
992 unitTime+=delta;
993 if (unitTime>=DISCOUNTUNIT) {
994 int addunits=unitTime/DISCOUNTUNIT;
995 if (units<addunits) addunits=units;
996
997 units-=addunits;
998 *score+=addunits;
999 unitTime%=DISCOUNTUNIT;
1000 }
1001 } else if (bonus>0) {
1002 unitTime+=delta;
1003 if (unitTime>=DISCOUNTUNIT) {
1004 int addunits=unitTime/DISCOUNTUNIT;
1005 if (bonus<addunits) addunits=bonus;
1006
1007 bonus-=addunits;
1008 *score+=addunits;
1009 unitTime%=DISCOUNTUNIT;
1010 }
1011 if (bonus<=0 && sounds) sounds->timeBack.stop();
1012 }
1013
1014 delta=Graphic::ticks()-laststep;
1015 if (delta<45) Graphic::sleep(45-delta);
1016 delta=Graphic::ticks()-laststep;
1017 if (waitdelay<delta) waitdelay=0;
1018 else waitdelay-=delta;
1019 laststep+=delta;
1020 }
1021
1022 *score+=units;
1023 *score+=bonus;
1024
1025 f.setMode(Fade::OUT,500);
1026 while (f.getMode()!=Fade::NONE) {
1027 drawsumary;
1028 f.step();
1029 Graphic::flip();
1030 }
1031
1032 return state;
1033 };
1034
1035
1036 class ImageSlider : public gcn::Slider {
1037 public:
1038 ImageSlider(float inf,float sup,const std::string & imgid);
1039
setValue(double value)1040 void setValue(double value) {
1041 if (value>getScaleEnd())
1042 gcn::Slider::setValue(getScaleEnd());
1043 else if (value<getScaleStart())
1044 gcn::Slider::setValue(getScaleStart());
1045 else
1046 gcn::Slider::setValue(value);
1047 }
1048
drawMarker(gcn::Graphics * g)1049 void drawMarker(gcn::Graphics *g) {
1050 int x=g->getCurrentClipArea().xOffset;
1051 int y=g->getCurrentClipArea().yOffset;
1052 img.draw(int(1+Graphic::fromScreenx(int(x+getMarkerLength()/2+getValue()*(getWidth()-getMarkerLength()-1)/(getScaleEnd()-getScaleStart())))),Graphic::fromScreeny(y));
1053 }
1054
draw(gcn::Graphics * g)1055 void draw(gcn::Graphics * g) {
1056 drawMarker(g);
1057 };
1058
1059 private:
1060 Graphic img;
1061 };
1062
ImageSlider(float inf,float sup,const std::string & imgid)1063 ImageSlider::ImageSlider(float inf,float sup,const std::string & imgid) :
1064 gcn::Slider(inf,sup), img(imgid,false) {
1065 setMarkerLength(Graphic::toScreenw(img.getWidth()+10));
1066 setFrameSize(0);
1067 img.hotspot=Vector2d(img.getWidth()/2,0);
1068 };
1069
1070
1071 class SldListener : public gcn::MouseListener {
1072 public:
SldListener()1073 SldListener() {};
mouseReleased(gcn::MouseEvent & e)1074 void mouseReleased(gcn::MouseEvent& e) {
1075 if (sounds)
1076 sounds->typeEnter.play();
1077 }
1078 };
1079
1080 class OptionsAction : public gcn::ActionListener {
1081 public:
1082 bool * quit;
1083 int * musvol, * fxvol;
1084 ImageSlider fxvolume,musicvolume;
1085 SldListener sldl;
1086
OptionsAction(bool * q,int * musvol,int * fxvol)1087 OptionsAction(bool * q, int * musvol, int * fxvol) :
1088 quit(q), musvol(musvol), fxvol(fxvol),
1089 fxvolume(0,100,"soundslidermarker"),
1090 musicvolume(0,128,"soundslidermarker") {
1091 fxvolume.setActionEventId("fxvolume");
1092 fxvolume.setValue(Soundfx::getOverallVolume());
1093 fxvolume.addActionListener(this);
1094 fxvolume.addMouseListener(&sldl);
1095 fxvolume.setDimension(gcn::Rectangle(Graphic::toScreenx(344),Graphic::toScreeny(237),
1096 Graphic::toScreenw(79),Graphic::toScreenh(16)));
1097 musicvolume.setActionEventId("musicvolume");
1098 musicvolume.setValue(Music::getVolume());
1099 musicvolume.addActionListener(this);
1100 musicvolume.setDimension(gcn::Rectangle(Graphic::toScreenx(344),Graphic::toScreeny(213),
1101 Graphic::toScreenw(79),Graphic::toScreenh(16)));
1102 };
action(const gcn::ActionEvent & e)1103 void action (const gcn::ActionEvent& e) {
1104 const string id = e.getId();
1105 if (id=="done") {
1106 if (sounds) sounds->mainScreenMenuButtons.play();
1107 *quit=true;
1108 } else if (id=="musicvolume") {
1109 Music::setVolume(Uint8(musicvolume.getValue()));
1110 *musvol=Uint8(musicvolume.getValue());
1111 } else if (id=="fxvolume") {
1112 Soundfx::setOverallVolume(Uint8(fxvolume.getValue()));
1113 *fxvol=Uint8(fxvolume.getValue());
1114 }
1115 }
1116 };
1117
optionsScreen(int * musvolume,int * fxvolume)1118 void optionsScreen(int * musvolume, int * fxvolume) {
1119
1120 gcn::SDLImageLoader imageLoader;
1121 gcn::Image::setImageLoader(&imageLoader);
1122
1123 gcn::SDLGraphics graphics;
1124 graphics.setTarget(Graphic::getScreen());
1125 RMFONTRef font("12p");
1126 RMFONTRef font24("24pgray");
1127 RMFONTRef fr2("asimov27");
1128
1129 gcn::Widget::setGlobalFont(&*font);
1130
1131 gcn::SDLInput input;
1132 bool quit=false;
1133
1134 string title = getText("optionsbt");
1135 string musiclabel = getText("musiclabel");
1136 string fxlabel = getText("fxlabel");
1137
1138 OptionsAction a(&quit,musvolume,fxvolume);
1139
1140 Graphic background("soundscreen",false);
1141 Layout c;
1142 Graphic mousepointer("mousepointer",false);
1143 FontButton bt(getText("donebt"),"asimov20","asimovgray20");
1144 bt.setActionEventId("done");
1145 bt.addActionListener(&a);
1146 bt.setPosition(Graphic::toScreenx(285),Graphic::toScreeny(370));
1147 c.add(&a.musicvolume);
1148 c.add(&a.fxvolume);
1149 c.add(&bt);
1150 c.setOpaque(false);
1151 c.fitWidgets();
1152 gcn::Gui gui;
1153 gui.setGraphics(&graphics);
1154 gui.setInput(&input);
1155 gui.setTop(&c);
1156
1157 Fade f;
1158 bool fullupdate=true;
1159 f.setMode(Fade::IN,1000);
1160 while (!quit && GUI_process_events(&input,&graphics)) {
1161 UPDATEOFF(Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0)));
1162 UPDATEOFF(background.draw(0,0));
1163 fr2->drawL(int(LOGICAL_WIDTH-fr2->getWidth(title)/Graphic::getBaseScaleFactorX())/2,147,title);
1164 font24->drawL(int(LOGICAL_WIDTH/2-10-font24->getWidth(musiclabel)/Graphic::getBaseScaleFactorX()),206,musiclabel);
1165 font24->drawL(int(LOGICAL_WIDTH/2-10-font24->getWidth(fxlabel)/Graphic::getBaseScaleFactorX()),229,fxlabel);
1166 gui.logic();
1167 gui.draw();
1168 f.step();
1169 mousepointer.draw(mousePositionX,mousePositionY);
1170
1171 Graphic::flip(fullupdate);
1172 fullupdate = f.getMode()!=Fade::NONE;
1173 Graphic::sleep(20);
1174 }
1175
1176 f.setMode(Fade::OUT,500);
1177 while (f.getMode()!=Fade::NONE) {
1178 UPDATEOFF(Graphic::clearScreen(SDL_MapRGB(Graphic::getScreen()->format, 0, 0,0)));
1179 UPDATEOFF(background.draw(0,0));
1180 fr2->drawL(int(LOGICAL_WIDTH-fr2->getWidth(title)/Graphic::getBaseScaleFactorX())/2,147,title);
1181 font24->drawL(int(LOGICAL_WIDTH/2-10-font24->getWidth(musiclabel)/Graphic::getBaseScaleFactorX()),206,musiclabel);
1182 font24->drawL(int(LOGICAL_WIDTH/2-10-font24->getWidth(fxlabel)/Graphic::getBaseScaleFactorX()),229,fxlabel);
1183 gui.draw();
1184 mousepointer.draw(mousePositionX,mousePositionY);
1185 f.step();
1186 Graphic::flip();
1187 }
1188 };
1189