1/* This file is part of OpenBubbles.
2 *
3 * OpenBubbles is an SDL clone of Bubbles.
4 * Copyright (C) 2004  Benny Sperisen
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program 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 this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * main.cpp contains main().
21 *
22 * Written by:
23 *  Benny Sperisen
24 *  lasindi@gmail.com
25 *  www.freewebs.com/lasindi
26 *****************************************************************************/
27
28#include "SDL.h"
29#include "SDL_gfxPrimitives.h"
30#include "SDL_image.h"
31#include <iostream>
32#include <string.h>
33#include <string>
34#include <fstream>
35using namespace std;
36
37#include "screen.h"
38#include "gameloop.h"
39#include "button.h"
40#include "highscores.h"
41#include "BFont.h"
42#include "audioplayer.h"
43
44#define BUTTONS_START 180
45#define BUTTONS_SPACING 45
46
47// Used for pulsing the cursor on the high score entry.
48#define CURSOR_PULSE_RATE 20
49#define UP 1
50#define DOWN 0
51
52// The rate at which the logo animation proceeds.
53#define ANIMATION_RATE 5
54
55#define ANIMATION_WIDTH 80
56#define ANIMATION_HEIGHT 80
57
58enum SCREENS {MENU,INSTRUCTIONS,GAME,HIGHSCORE};
59enum ANIMATION_IMAGES {PI_ABUBBLE,ABUBBLE_VERSION,VERSION_ABUBBLE,ABUBBLE_PI};
60
61/* The code in initButtons is called twice, so to save space, it's in a
62 * separate function. */
63void initButtons();
64
65// Transitions to screen 'to' (from the SCREENS enumeration).
66void transition(char to);
67
68SDL_Surface* boxChecked;
69SDL_Surface* boxUnchecked;
70
71int main()
72{
73  SDL_Surface* icon;
74  SDL_Surface* logo;
75  SDL_Surface* visit;
76  SDL_Surface* copyright;
77  SDL_Surface* instructions;
78  SDL_Surface* enterback;
79  SDL_Surface* highbanner;
80  SDL_Surface* cursor;
81  SDL_Surface* abubble;
82  SDL_Surface* pi;
83  SDL_Surface* version;
84	SDL_Surface* labels;
85  SDL_Surface* from;
86  SDL_Surface* to;
87  SDL_Rect src,dest;
88  SDL_Event event;
89  BFont_Info* font;
90  char* result;
91  char* temp=new char[MAX_CHARACTERS+1];
92  char cursor_direction,currentimage;
93  double score;
94  int time1,time2,diff_time,pause_time,cursor_pos,cursor_alpha,totalwidth,
95      from_alpha,to_alpha;
96  string datadir2,datadir3,name;
97	soundOn=fadingOn=true;
98  if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)!=0)
99  {
100    cerr<<"ERROR: unable to initialize SDL: "<<SDL_GetError()<<endl;
101    return 1;
102  }
103  atexit(SDL_Quit);
104	atexit(SDL_CloseAudio);
105	atexit(saveEverything);
106  screen=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,32,SDL_HWSURFACE);
107  if(screen==NULL)
108  {
109    cerr<<"ERROR: unable to set video mode: "<<SDL_GetError()<<endl;
110    return 1;
111  }
112  loadHighScores();
113	audio=new audioPlayer;
114	// Load the sounds.
115	datadir=DATA_PREFIX;
116	datadir+="/bubble.wav";
117	bubbleSound=audio->loadSound(datadir);
118	datadir=DATA_PREFIX;
119	datadir+="/fire.wav";
120	missleSound=audio->loadSound(datadir);
121	datadir=DATA_PREFIX;
122	datadir+="/gameover.wav";
123	gameoverSound=audio->loadSound(datadir);
124	datadir=DATA_PREFIX;
125	datadir+="/bounce.wav";
126	bounceSound=audio->loadSound(datadir);
127	loadSettings(); // Load fadingOn and soundOn.
128  // Load all of the surfaces used in main().
129  datadir=DATA_PREFIX;
130  datadir+="/icon.xpm";
131  icon=IMG_Load(datadir.c_str());
132  if(icon==NULL)
133  {
134    cerr<<"ERROR: unable to load icon.\n";
135    exit(1);
136  }
137  SDL_WM_SetIcon(icon,NULL);
138  datadir=DATA_PREFIX;
139  datadir+="/logo.png";
140  logo=IMG_Load(datadir.c_str());
141  if(logo==NULL)
142  {
143    cerr<<"ERROR: unable to load logo.\n";
144    exit(1);
145  }
146  datadir=DATA_PREFIX;
147  datadir+="/visit.png";
148  visit=IMG_Load(datadir.c_str());
149  if(visit==NULL)
150  {
151    cerr<<"ERROR: unable to load visit.\n";
152    exit(1);
153  }
154  datadir=DATA_PREFIX;
155  datadir+="/copyright.png";
156  copyright=IMG_Load(datadir.c_str());
157  if(copyright==NULL)
158  {
159    cerr<<"ERROR: unable to load copyright.\n";
160    exit(1);
161  }
162  datadir=DATA_PREFIX;
163  datadir+="/instructions.png";
164  instructions=IMG_Load(datadir.c_str());
165  if(instructions==NULL)
166  {
167    cerr<<"ERROR: unable to load instructions.\n";
168    exit(1);
169  }
170  datadir=DATA_PREFIX;
171  datadir+="/enterback.png";
172  enterback=IMG_Load(datadir.c_str());
173  if(enterback==NULL)
174  {
175    cerr<<"ERROR: unable to load enterback.\n";
176    exit(1);
177  }
178  datadir=DATA_PREFIX;
179  datadir+="/highbanner.png";
180  highbanner=IMG_Load(datadir.c_str());
181  if(highbanner==NULL)
182  {
183    cerr<<"ERROR: unable to load highbanner.\n";
184    exit(1);
185  }
186  datadir=DATA_PREFIX;
187  datadir+="/cursor.png";
188  cursor=IMG_Load(datadir.c_str());
189  if(cursor==NULL)
190  {
191    cerr<<"ERROR: unable to load cursor.\n";
192    exit(1);
193  }
194  datadir=DATA_PREFIX;
195  datadir+="/pi.png";
196  pi=IMG_Load(datadir.c_str());
197  if(pi==NULL)
198  {
199    cerr<<"ERROR: unable to load pi.\n";
200    exit(1);
201  }
202  datadir=DATA_PREFIX;
203  datadir+="/version.png";
204  version=IMG_Load(datadir.c_str());
205  if(version==NULL)
206  {
207    cerr<<"ERROR: unable to load version.\n";
208    exit(1);
209  }
210  datadir=DATA_PREFIX;
211  datadir+="/abubble.png";
212  abubble=IMG_Load(datadir.c_str());
213  if(abubble==NULL)
214  {
215    cerr<<"ERROR: unable to load abubble.\n";
216    exit(1);
217  }
218	datadir=DATA_PREFIX;
219  datadir+="/labels.png";
220  labels=IMG_Load(datadir.c_str());
221  if(abubble==NULL)
222  {
223    cerr<<"ERROR: unable to load labels.png.\n";
224    exit(1);
225  }
226	datadir=DATA_PREFIX;
227  datadir+="/checkshot.png";
228  boxChecked=IMG_Load(datadir.c_str());
229  if(boxChecked==NULL)
230  {
231    cerr<<"ERROR: unable to load checkshot.png.\n";
232    exit(1);
233  }
234	datadir=DATA_PREFIX;
235  datadir+="/checkboxshot.png";
236  boxUnchecked=IMG_Load(datadir.c_str());
237  if(boxUnchecked==NULL)
238  {
239    cerr<<"ERROR: unable to load checkboxshot.png.\n";
240    exit(1);
241  }
242  datadir=DATA_PREFIX;
243  datadir+="/font2.png";
244  font=BFont_LoadFont(datadir.c_str());
245  if(font==NULL)
246  {
247    cerr<<"ERROR: unable to load font2.\n";
248    exit(1);
249  }
250	audio->clearSounds();
251	SDL_PauseAudio(0);
252  for(;;)
253  {
254    initButtons();
255    SDL_WM_SetCaption("OpenBubbles","OpenBubbles");
256    currentimage=PI_ABUBBLE;
257    from_alpha=255;
258    to_alpha=0;
259    from=pi;
260    to=abubble;
261    for(;;)
262    {
263      time1=clock()/CLOCKS_PER_SEC; //get time at start of loop
264      result=handleButtons();
265			fadingOn=isChecked("fading");
266			soundOn=isChecked("sound");
267			audio->mute(!soundOn);
268      while(SDL_PollEvent(&event))
269      {
270        if(event.type==SDL_QUIT)
271          goto leave;
272        else if((event.type==SDL_KEYUP)&&(event.key.keysym.sym==SDLK_RETURN))
273          result="start";
274      }
275      boxRGBA(screen,0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1,0,0,0,255);
276      // Animation code.
277      switch(currentimage)
278      {
279        case PI_ABUBBLE:
280          from=pi;
281          to=abubble;
282          break;
283        case ABUBBLE_VERSION:
284          from=abubble;
285          to=version;
286          break;
287        case VERSION_ABUBBLE:
288          from=version;
289          to=abubble;
290          break;
291        case ABUBBLE_PI:
292          from=abubble;
293          to=pi;
294      }
295      to_alpha+=ANIMATION_RATE;
296      if(to_alpha>=255)
297      {
298        SDL_SetAlpha(to,SDL_SRCALPHA,255);
299        // Rotate the images.
300        if(currentimage==ABUBBLE_PI)
301          currentimage=PI_ABUBBLE;
302        else
303          currentimage++;
304        to_alpha=0;
305      }
306      else
307      {
308        SDL_SetAlpha(from,SDL_SRCALPHA,from_alpha);
309        SDL_SetAlpha(to,SDL_SRCALPHA,to_alpha);
310      }
311      // Logo blitting.
312      src.x=0;
313      src.y=0;
314      src.w=logo->w;
315      src.h=logo->h;
316      dest.x=SCREEN_WIDTH/2-src.w/2;
317      dest.y=10;
318      dest.w=src.w;
319      dest.h=src.h;
320      SDL_BlitSurface(logo,&src,screen,&dest);
321      // Animation blitting.
322      src.w=ANIMATION_WIDTH;
323      src.h=ANIMATION_HEIGHT;
324      dest.x=SCREEN_WIDTH/2+105;
325      dest.y=115;
326      dest.w=src.w;
327      dest.h=src.h;
328      SDL_BlitSurface(from,&src,screen,&dest);
329      SDL_BlitSurface(to,&src,screen,&dest);
330      // "Visit ..." blitting.
331      src.w=visit->w;
332      src.h=visit->h;
333      dest.x=SCREEN_WIDTH/2-src.w/2;
334      dest.y=360;
335      dest.w=src.w;
336      dest.h=src.h;
337      SDL_BlitSurface(visit,&src,screen,&dest);
338      // Copyright notice blitting.
339      src.w=copyright->w;
340      src.h=copyright->h;
341      dest.x=SCREEN_WIDTH/2-src.w/2;
342      dest.y=380;
343      dest.w=src.w;
344      dest.h=src.h;
345      SDL_BlitSurface(copyright,&src,screen,&dest);
346			// Checkbox label blitting.
347			src.w=labels->w;
348			src.h=labels->h;
349			dest.x=SCREEN_WIDTH/2+120;
350			dest.y=232;
351			dest.w=src.w;
352			dest.h=src.h;
353			SDL_BlitSurface(labels,&src,screen,&dest);
354      drawButtons();
355      SDL_UpdateRect(screen,0,0,screen->w,screen->h);
356      if(strcmp(result,"start")==0)
357      {
358				if(fadingOn)
359					transition(GAME);
360        break;
361      }
362      // Load the instructions.
363      else if(strcmp(result,"instructions")==0)
364      {
365        for(list<button*>::iterator i=buttons.begin();i!=buttons.end();i++)
366          (*i)->freeSurfaces();
367        buttons.clear();
368				checkboxes.clear();
369				buttons.push_back(new button(SCREEN_WIDTH/2-140,420,"return.png",
370																		 "return","return_hilight.png",
371																		 "return_pressed.png"));
372        if(fadingOn)
373					transition(INSTRUCTIONS);
374        for(;;)
375        {
376          time1=clock()/CLOCKS_PER_SEC; //get time at start of loop
377          while(SDL_PollEvent(&event))
378            if(event.type==SDL_QUIT)
379              goto leave;
380          boxRGBA(screen,0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1,0,0,0,255);
381          src.x=0;
382          src.y=0;
383          src.w=instructions->w;
384          src.h=instructions->h;
385          dest.x=SCREEN_WIDTH/2-src.w/2;
386          dest.y=10;
387          dest.w=src.w;
388          dest.h=src.h;
389          SDL_BlitSurface(instructions,&src,screen,&dest);
390          drawButtons();
391          SDL_UpdateRect(screen,0,0,screen->w,screen->h);
392          if(strcmp(handleButtons(),"return")==0)
393            break;
394          else if(strcmp(handleButtons(),"quit")==0)
395            goto leave;
396          time2=clock()/CLOCKS_PER_SEC; //get time at end of loop
397          diff_time=time2-time1;    //compare...
398          pause_time=30-diff_time;
399          SDL_Delay(pause_time);    //and pause for required amount of time
400        }
401        for(list<button*>::iterator i=buttons.begin();i!=buttons.end();i++)
402          (*i)->freeSurfaces();
403        buttons.clear();
404				checkboxes.clear();
405        while(SDL_PollEvent(&event)); // Flush events.
406        initButtons();
407        currentimage=PI_ABUBBLE;
408        from_alpha=255;
409        to_alpha=0;
410        from=pi;
411        to=abubble;
412				if(fadingOn)
413					transition(MENU);
414      }
415      else if(strcmp(result,"highscores")==0)
416      {
417        displayHighScores(fadingOn);
418        buttons.clear();
419        while(SDL_PollEvent(&event)); // Flush events.
420        initButtons();
421      }
422      else if(strcmp(result,"quit")==0)
423        goto leave;
424      time2=clock()/CLOCKS_PER_SEC; //get time at end of loop
425      diff_time=time2-time1;    //compare...
426      pause_time=30-diff_time;
427      SDL_Delay(pause_time);    //and pause for required amount of time
428    }
429    score=gameloop();
430    // Check to see if the player got a high score.
431    for(vector<highscore>::iterator i=high_scores.begin();i!=high_scores.end();
432				i++)
433      if(score>(*i).score()) // They got one.
434      {
435        for(list<button*>::iterator j=buttons.begin();j!=buttons.end();j++)
436          (*j)->freeSurfaces();
437        buttons.clear();
438				checkboxes.clear();
439			  buttons.push_back(new button(SCREEN_WIDTH/2-70,
440																		 SCREEN_HEIGHT/2-enterback->h/2+62,
441																		 "ok.png","ok","ok_hilight.png",
442																		 "ok_pressed.png"));
443				buttons.push_back(new button(SCREEN_WIDTH/2+3,
444																		 SCREEN_HEIGHT/2-enterback->h/2+62,
445																		 "cancel.png","cancel",
446																		 "cancel_hilight.png",
447																		 "cancel_pressed.png"));
448        src.x=src.y=0;
449        cursor_pos=0;
450        name="";
451        SDL_EnableKeyRepeat(300,30);
452        cursor_alpha=0;
453        cursor_direction=UP;
454				if(fadingOn)
455					transition(HIGHSCORE);
456        for(;;)
457        {
458          time1=clock()/CLOCKS_PER_SEC; //get time at start of loop
459          result=handleButtons();
460          while(SDL_PollEvent(&event))
461          {
462            if(event.type==SDL_QUIT)
463              goto leave;
464            else if((event.type==SDL_KEYUP)&&
465                    (event.key.keysym.sym==SDLK_RETURN))
466              result="ok";
467            else
468              typestr(event,name,cursor_pos,font);
469          }
470          if(cursor_direction==UP)
471          {
472            cursor_alpha+=CURSOR_PULSE_RATE;
473            if(cursor_alpha>=255)
474            {
475              cursor_alpha=255;
476              cursor_direction=DOWN;
477            }
478          }
479          else
480          {
481            cursor_alpha-=CURSOR_PULSE_RATE;
482            if(cursor_alpha<=0)
483            {
484              cursor_alpha=0;
485              cursor_direction=UP;
486            }
487          }
488          SDL_SetAlpha(cursor,SDL_SRCALPHA,cursor_alpha);
489          boxRGBA(screen,0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1,0,0,0,255);
490          src.w=highbanner->w;
491          src.h=highbanner->h;
492          dest.x=SCREEN_WIDTH/2-src.w/2;
493          dest.y=SCREEN_HEIGHT/4-src.h/2;
494          dest.w=src.w;
495          dest.h=src.h;
496          SDL_BlitSurface(highbanner,&src,screen,&dest);
497          src.w=enterback->w;
498          src.h=enterback->h;
499          dest.x=SCREEN_WIDTH/2-src.w/2;
500          dest.y=SCREEN_HEIGHT/2-src.h/2;
501          dest.w=src.w;
502          dest.h=src.h;
503          SDL_BlitSurface(enterback,&src,screen,&dest);
504          for(unsigned int j=0;j<name.length();j++)
505            temp[j]=name[j];
506          temp[name.length()]='\0';
507          BFont_PutStringFont(screen,font,dest.x+33,dest.y+40,temp);
508          totalwidth=0;
509          for(int j=0;j<cursor_pos;j++)
510            totalwidth+=BFont_CharWidth(font,name[j]);
511          src.w=cursor->w;
512          src.h=cursor->h;
513          dest.x+=33+totalwidth;
514          dest.y+=40;
515          dest.w=src.w;
516          dest.h=src.h;
517          SDL_BlitSurface(cursor,&src,screen,&dest);
518          drawButtons();
519          SDL_UpdateRect(screen,0,0,screen->w,screen->h);
520          if(strcmp(result,"ok")==0)
521          {
522            high_scores.insert(i,highscore(name,(int)score));
523            high_scores.pop_back();
524            saveEverything();
525            break;
526          }
527          else if(strcmp(result,"cancel")==0)
528            break;
529          time2=clock()/CLOCKS_PER_SEC; //get time at end of loop
530          diff_time=time2-time1;    //compare...
531          pause_time=30-diff_time;
532          SDL_Delay(pause_time);    //and pause for required amount of time
533        }
534        SDL_EnableKeyRepeat(0,0);
535        for(list<button*>::iterator i=buttons.begin();i!=buttons.end();i++)
536          (*i)->freeSurfaces();
537        buttons.clear();
538				checkboxes.clear();
539        while(SDL_PollEvent(&event)); // Flush events.
540        initButtons();
541        break;
542      }
543		if(fadingOn)
544			transition(MENU);
545    for(list<bubble*>::iterator i=bubs.begin();i!=bubs.end();i++)
546      (*i)->freeSurfaces();
547    bubs.clear();
548    crumbs.clear();
549		missles.clear();
550    for(list<button*>::iterator i=buttons.begin();i!=buttons.end();i++)
551      (*i)->freeSurfaces();
552    buttons.clear();
553		checkboxes.clear();
554  }
555leave:
556  bubs.clear();
557  crumbs.clear();
558  for(list<button*>::iterator i=buttons.begin();i!=buttons.end();i++)
559    (*i)->freeSurfaces();
560  buttons.clear();
561	checkboxes.clear();
562	SDL_FreeSurface(labels);
563	SDL_FreeSurface(boxChecked);
564	SDL_FreeSurface(boxUnchecked);
565  SDL_FreeSurface(pi);
566  SDL_FreeSurface(version);
567  SDL_FreeSurface(abubble);
568  SDL_FreeSurface(enterback);
569  SDL_FreeSurface(highbanner);
570  SDL_FreeSurface(screen);
571  SDL_FreeSurface(icon);
572  SDL_FreeSurface(logo);
573  SDL_FreeSurface(instructions);
574  SDL_FreeSurface(visit);
575  SDL_FreeSurface(copyright);
576  SDL_FreeSurface(cursor);
577  BFont_FreeFont(font);
578  delete[] temp;
579	delete audio;
580  return 0;
581}
582
583void initButtons()
584{
585	checkbox* fadingbox=new checkbox(SCREEN_WIDTH/2+128,246,"fading",fadingOn);
586	checkbox* soundbox=new checkbox(SCREEN_WIDTH/2+128,269,"sound",soundOn);
587	buttons.push_back(new button(SCREEN_WIDTH/2-101,BUTTONS_START,"start.png",
588															 "start","start_hilight.png",
589															 "start_pressed.png"));
590	buttons.push_back(new button(SCREEN_WIDTH/2-101,
591															 BUTTONS_START+BUTTONS_SPACING,
592															 "instructions_button.png","instructions",
593															 "instructions_hilight.png",
594															 "instructions_pressed.png"));
595  buttons.push_back(new button(SCREEN_WIDTH/2-101,
596															 BUTTONS_START+2*BUTTONS_SPACING,
597															 "highscores.png",
598															 "highscores","highscores_hilight.png",
599															 "highscores_pressed.png"));
600	buttons.push_back(new button(SCREEN_WIDTH/2-101,
601															 BUTTONS_START+3*BUTTONS_SPACING,"quit.png",
602															 "quit","quit_hilight.png","quit_pressed.png"));
603	checkboxes.push_back(fadingbox);
604	checkboxes.push_back(soundbox);
605	buttons.push_back(fadingbox);
606	buttons.push_back(soundbox);
607}
608
609void transition(char to)
610{
611  string datadir;
612  int time1,time2,diff_time,pause_time; // Time loop
613  SDL_Surface* from_surface;
614  SDL_Surface* to_surface;
615  SDL_Rect src,dest;
616  datadir=DATA_PREFIX;
617  datadir+="/menushot.png";
618  from_surface=IMG_Load(datadir.c_str());
619  if(from_surface==NULL)
620  {
621    cerr<<"ERROR: unable to load from_surface.\n";
622    exit(1);
623  }
624	// Get the SDL_Rects ready.
625  src.x=src.y=dest.x=dest.y=0;
626  src.w=dest.w=SCREEN_WIDTH;
627  src.h=dest.h=SCREEN_HEIGHT;
628  SDL_BlitSurface(screen,&src,from_surface,&dest);
629  switch(to)
630  {
631  case MENU:
632    datadir=DATA_PREFIX;
633    datadir+="/menushot.png";
634    to_surface=IMG_Load(datadir.c_str());
635    if(to_surface==NULL)
636    {
637      cerr<<"ERROR: unable to load menushot.\n";
638      exit(1);
639    }
640		src.x=src.y=0;
641		src.w=boxChecked->w;
642		src.h=boxChecked->h;
643		dest.x=448;
644		dest.y=246;
645		dest.w=src.w;
646		dest.h=src.h;
647		if(fadingOn)
648			SDL_BlitSurface(boxChecked,&src,to_surface,&dest);
649		else
650			SDL_BlitSurface(boxUnchecked,&src,to_surface,&dest);
651		dest.y=269;
652		if(soundOn)
653			SDL_BlitSurface(boxChecked,&src,to_surface,&dest);
654		else
655			SDL_BlitSurface(boxUnchecked,&src,to_surface,&dest);
656    boxRGBA(screen,0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1,0,0,0,255);
657		// Reset the SDL_Rects.
658		src.x=src.y=dest.x=dest.y=0;
659		src.w=dest.w=SCREEN_WIDTH;
660		src.h=dest.h=SCREEN_HEIGHT;
661    break;
662  case INSTRUCTIONS:
663    datadir=DATA_PREFIX;
664    datadir+="/instructionsshot.png";
665    to_surface=IMG_Load(datadir.c_str());
666    if(to_surface==NULL)
667    {
668      cerr<<"ERROR: unable to load instructionsshot.\n";
669      exit(1);
670    }
671    break;
672  case GAME:
673    datadir=DATA_PREFIX;
674    datadir+="/gameshot.png";
675    to_surface=IMG_Load(datadir.c_str());
676    if(to_surface==NULL)
677    {
678      cerr<<"ERROR: unable to load gameshot.\n";
679      exit(1);
680    }
681    break;
682  case HIGHSCORE:
683    datadir=DATA_PREFIX;
684    datadir+="/highshot.png";
685    to_surface=IMG_Load(datadir.c_str());
686    if(to_surface==NULL)
687    {
688      cerr<<"ERROR: unable to load highshot.\n";
689      exit(1);
690    }
691    break;
692  default:
693    cerr<<"ERROR: invalid argument passed to transition().\n";
694    exit(1);
695  }
696  for(int i=0;i<256;i+=TRANSITION_SPEED)
697  {
698    time1=clock()/CLOCKS_PER_SEC; //get time at start of loop
699    boxRGBA(screen,0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1,0,0,0,255);
700    SDL_SetAlpha(from_surface,SDL_SRCALPHA,255-i);
701    SDL_SetAlpha(to_surface,SDL_SRCALPHA,i);
702    SDL_BlitSurface(from_surface,&src,screen,&dest);
703    SDL_BlitSurface(to_surface,&src,screen,&dest);
704    SDL_UpdateRect(screen,0,0,screen->w,screen->h);
705    time2=clock()/CLOCKS_PER_SEC; //get time at end of loop
706    diff_time=time2-time1;    //compare...
707    pause_time=25-diff_time;
708    SDL_Delay(pause_time);    //and pause for required amount of time
709  }
710  SDL_FreeSurface(from_surface);
711  SDL_FreeSurface(to_surface);
712}
713