1 /*
2  * Martian: Motor para creaci�n de videojuegos con SDL y OpenGL
3  * Copyright (C) 2007  Javier P�rez Pacheco
4  *
5  * Este motor tiene licencia Creative Commons y se permite
6  * su modificacion y utilizacion libremente siempre y cuando se
7  * cite al autor original y se comparta con la misma licencia.
8  * No se permite su uso comercial.
9  *
10  * Para mas informacion visite la web:
11  * http://creativecommons.org/licenses/by-nc-sa/2.0/es/
12  *
13  * PROGRAMADOR
14  * Javier P�rez Pacheco
15  * Cadiz (Spain)
16  * javielinux@gmail.com
17  *
18  */
19 
20 #include "elements.h"
21 
22 namespace Martian {
23 
24 	/*****************************
25 	**
26 	** CLASE Converter
27 	**
28 	******************************/
29 
30 	Converter* Converter::instance = NULL;
31 
Converter()32 	Converter::Converter() {
33 	}
34 
GetInstance()35 	Converter* Converter::GetInstance () {
36 		if ( instance == NULL ) {
37 			instance = new Converter();
38 		}
39 		return instance;
40 	}
41 
ml2cycles(int ml)42 	int Converter::ml2cycles(int ml) {
43 		return (int)( ((float)ml/1000) * Timer::GetInstance()->getFPS() );
44 	}
45 
split(string txt,string chunk)46 	vector<string> Converter::split(string txt, string chunk) {
47 		int i,j;
48 		vector<string> strSeparate;
49 		for (i=0; i<(int)txt.length(); i++) {
50 			if ( (txt.substr(i, (int)chunk.length()) == chunk) || (i>=(int)txt.length()-1) ) {
51 				int ini = 0, end = 0;
52 				for (j=0; j<(int)strSeparate.size(); j++) {
53 					ini += (int)strSeparate[j].length()+1;
54 				}
55 				if (i>=(int)txt.length()-1) {
56 					end = i-ini+1;
57 				} else {
58 					end = i-ini;
59 				}
60 				strSeparate.push_back(txt.substr(ini, end));
61 			}
62 		}
63 		return strSeparate;
64 	}
65 
join(vector<string> txt,string chunk)66 	string Converter::join(vector<string> txt, string chunk) {
67 		int i;
68 		string strJoin;
69 		for (i=0; i<(int)txt.size(); i++) {
70 			strJoin += txt[i];
71 			if (i<(int)txt.size()-1) strJoin += "|";
72 		}
73 		return strJoin;
74 	}
75 
time2cycle(string time)76 	int Converter::time2cycle(string time) {
77 		int minutes = 0;
78 		int	seconds = 0;
79 		int	fracseconds = 0;
80 
81 		int c[3];
82 		char *chunk;
83 
84 		chunk = strtok( (char*)time.c_str(), ":" );
85 		c[0] = atoi(chunk);
86 		int cont = 1;
87 		while( (chunk = strtok( NULL, ":" )) != NULL ) {
88 			c[cont] = atoi(chunk);
89 			cont++;
90 		}
91 
92 		switch(cont) {
93 			case 1:
94 				fracseconds = c[0];
95 			break;
96 			case 2:
97 				fracseconds = c[1];
98 				seconds = c[0];
99 			break;
100 			case 3:
101 				fracseconds = c[2];
102 				seconds = c[1];
103 				minutes = c[0];
104 			break;
105 		}
106 
107 		return ( (minutes*60)*Timer::GetInstance()->getFPS() ) + ( seconds*Timer::GetInstance()->getFPS() ) + ( ((float)fracseconds/60)*Timer::GetInstance()->getFPS() );
108 	}
109 
fillZeros(int i)110 	string Converter::fillZeros(int i) {
111 		string chain = "";
112 		char numbers[4];
113 		if ( (i>=0) && (i<10) ) {
114 			sprintf(numbers, "%d", i);
115 			chain += "000" + string(numbers);
116 		} else if ( (i>=10) && (i<100) ) {
117 			sprintf(numbers, "%d", i);
118 			chain += "00" + string(numbers);
119 		} else if ( (i>=100) && (i<1000) ) {
120 			sprintf(numbers, "%d", i);
121 			chain += "0" + string(numbers);
122 		} else if ( (i>=1000) && (i<10000) ) {
123 			sprintf(numbers, "%d", i);
124 			chain += string(numbers);
125 		} else {
126 			chain += "0000";
127 		}
128 		return chain;
129 	}
130 
131 	/*****************************
132 	**
133 	** CLASE VerifyInfo
134 	**
135 	******************************/
136 
137 	WorkingData* WorkingData::instance = NULL;
138 
WorkingData()139 	WorkingData::WorkingData() {
140 	}
141 
GetInstance()142 	WorkingData* WorkingData::GetInstance () {
143 		if ( instance == NULL ) {
144 			instance = new WorkingData();
145 		}
146 		return instance;
147 	}
148 
validCharacter(string c)149 	bool WorkingData::validCharacter(string c) {
150 		string chain_letters = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890��!�?�@#$%&'+-=><*/,.:;-_()[]{}|^`~\\";
151 
152 		for (int i = 0; i<(int)chain_letters.size(); i ++) {
153 			if (chain_letters.substr(i, 1)==c) {
154 				return true;
155 			}
156 		}
157 
158 		return false;
159 
160 	}
161 
createFile(string file,string text,bool changeSpecialsCharacters)162 	bool WorkingData::createFile(string file, string text, bool changeSpecialsCharacters) {
163 
164 		FILE *f;
165 		f = fopen((char*)file.c_str(), "w+");
166 
167 		if(!f) return false;
168 
169 		string textToFile;
170 
171 		if (changeSpecialsCharacters) {
172 			textToFile = replace(text, "�", "#");
173 			textToFile = replace(textToFile, "�", "$");
174         } else {
175 			textToFile = text;
176         }
177 
178 		fwrite(textToFile.c_str(), strlen(textToFile.c_str()), 1, f);
179 
180 		fclose(f);
181 
182 		return true;
183 	}
184 
existFile(string file)185 	bool WorkingData::existFile(string file) {
186         vector<string> s = Converter::GetInstance()->split(file, "/");
187         string f = s[(int)s.size()-1];
188         string dir = "";
189 
190 		if (file.substr(0,1) == "/") dir += "/";
191 
192         for (int i=0; i<(int)s.size()-1; i++) {
193             if (s[i]!="") dir += s[i] + "/";
194         }
195 
196     	DIR *pdir;
197     	struct dirent *pent;
198     	pdir=opendir(dir.c_str());
199     	if (pdir) {
200             while ((pent=readdir(pdir))) {
201                  if ( strcmp(pent->d_name, f.c_str()) == 0 ) {
202                       closedir(pdir);
203                       return true;
204                  }
205             }
206             closedir(pdir);
207         }
208 
209 		return false;
210 	}
211 
replace(string chain,string search,string replace)212 	string WorkingData::replace(string chain, string search, string replace) {
213         string::size_type pos = 0;
214         string chainReplaced = chain;
215         while ( (pos = chainReplaced.find(search, pos)) != string::npos ) {
216             chainReplaced.replace( pos, search.size(), replace );
217             pos++;
218         }
219         return chainReplaced;
220     }
221 
createDirectory(string dir)222 	void WorkingData::createDirectory(string dir) {
223          if (!existFile(dir)) {
224             #ifdef WIN32
225                 string directory = replace(dir, "/", "\\");
226 
227                 char DirName[256];
228                 char* p = (char*)directory.c_str();
229                 char* q = DirName;
230                 while(*p)
231                 {
232                     if (('\\' == *p) || ('/' == *p))
233                     {
234                         if (':' != *(p-1))
235                         {
236                            CreateDirectory(DirName, NULL);
237                         }
238                     }
239                     *q++ = *p++;
240                     *q = '\0';
241                 }
242                 CreateDirectory(DirName, NULL);
243 
244             #else
245                 string cmd = "mkdir " + dir;
246                 system(cmd.c_str());
247             #endif
248        }
249 	}
250 
deleteDirectory(string dir)251 	void WorkingData::deleteDirectory(string dir) {
252          if (existFile(dir)) {
253             #ifdef WIN32
254                  string directory = replace(dir, "/", "\\");
255 				 char fileFound[256];
256 				 WIN32_FIND_DATA info;
257 				 HANDLE hp;
258 				 sprintf(fileFound, "%s\\*.*", directory.c_str());
259 				 hp = FindFirstFile(fileFound, &info);
260 				 do
261 					{
262 						if (!((strcmp(info.cFileName, ".")==0)||
263 							  (strcmp(info.cFileName, "..")==0)))
264 						{
265 						  if((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==
266 													 FILE_ATTRIBUTE_DIRECTORY)
267 						  {
268                               string subFolder = directory;
269 							  subFolder.append("\\");
270 							  subFolder.append(info.cFileName);
271 							  deleteDirectory((char*)subFolder.c_str());
272 							  RemoveDirectory(subFolder.c_str());
273 						  }
274 						  else
275 						  {
276 							  sprintf(fileFound,"%s\\%s", directory.c_str(), info.cFileName);
277 							  BOOL retVal = DeleteFile(fileFound);
278 						  }
279 						}
280 
281 					} while(FindNextFile(hp, &info));
282 				 FindClose(hp);
283 				 RemoveDirectory(directory.c_str());
284             #else
285                 string cmd = "rm -r " + dir;
286                 system(cmd.c_str());
287             #endif
288        }
289 	}
290 
getPath(string file)291 	string WorkingData::getPath(string file) {
292         vector<string> s = Converter::GetInstance()->split(file, "/");
293         string dir = "";
294 
295 		if (file.substr(0,1) == "/") dir += "/";
296 
297         for (int i=0; i<(int)s.size()-1; i++) {
298             if (s[i]!="") dir += s[i] + "/";
299         }
300         return dir;
301     }
302 
getFilename(string file)303 	string WorkingData::getFilename(string file) {
304         vector<string> s = Converter::GetInstance()->split(file, "/");
305         string f = s[(int)s.size()-1];
306         return f;
307     }
308 
getExtension(string file)309 	string WorkingData::getExtension(string file) {
310         vector<string> s = Converter::GetInstance()->split(file, ".");
311         string ext = s[(int)s.size()-1];
312         return getToUpper(ext);
313     }
314 
getToUpper(string str)315     string WorkingData::getToUpper(string str) {
316        for(unsigned int i=0;i<str.length();i++) {
317           str[i] = toupper(str[i]);
318        }
319        return str;
320     }
321 
getToLower(string str)322     string WorkingData::getToLower(string str) {
323        for(unsigned int i=0;i<str.length();i++) {
324           str[i] = tolower(str[i]);
325        }
326        return str;
327     }
328 
329 	/*****************************
330 	**
331 	** CLASE WorkingSurfaces
332 	**
333 	******************************/
334 
335 	WorkingSurfaces* WorkingSurfaces::instance = NULL;
336 
WorkingSurfaces()337 	WorkingSurfaces::WorkingSurfaces() {
338 	}
339 
GetInstance()340 	WorkingSurfaces* WorkingSurfaces::GetInstance () {
341 		if ( instance == NULL ) {
342 			instance = new WorkingSurfaces();
343 		}
344 		return instance;
345 	}
346 
surfaceFromImage(string path)347 	SDL_Surface* WorkingSurfaces::surfaceFromImage(string path) {
348 		SDL_Surface* temp = IMG_Load((char*)path.c_str());
349 		if ( temp == NULL ) {
350 			printf("Unable to load %s: %s\n", path.c_str(), SDL_GetError());
351 		}
352 		return temp;
353 	}
354 
mixSurfaces(SDL_Surface * back,SDL_Surface * front,Bounds * destiny)355 	SDL_Surface* WorkingSurfaces::mixSurfaces(SDL_Surface* back, SDL_Surface* front, Bounds *destiny) {
356 
357 		SDL_Surface *image;
358 
359 	#if SDL_BYTEORDER == SDL_BIG_ENDIAN
360 		  image = SDL_CreateRGBSurface(SDL_SWSURFACE, back->w, back->h, back->format->BitsPerPixel,
361 									  0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
362 	#else
363 		  image = SDL_CreateRGBSurface(SDL_SWSURFACE, back->w, back->h, back->format->BitsPerPixel,
364 									  0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
365 	#endif
366 		Uint32 saved_flags;
367 		Uint8  saved_alpha;
368 		saved_flags = back->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
369 		saved_alpha = back->format->alpha;
370 		if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
371 			SDL_SetAlpha(back, 0, 0);
372 		}
373 
374 
375 		if (destiny==NULL) {
376 			SDL_BlitSurface(back, NULL, image, NULL);
377 			if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
378 				SDL_SetAlpha(back, saved_flags, saved_alpha);
379 			}
380 			SDL_BlitSurface(front, NULL, image, NULL);
381 			if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
382 				SDL_SetAlpha(back, saved_flags, saved_alpha);
383 			}
384 		} else {
385 			SDL_BlitSurface(back, NULL, image, NULL);
386 			if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
387 				SDL_SetAlpha(back, saved_flags, saved_alpha);
388 			}
389 			SDL_Rect o = {0, 0, (int)destiny->x2-(int)destiny->x1, (int)destiny->y2-(int)destiny->y1};
390 			SDL_Rect d = {(int)destiny->x1, (int)destiny->y1, (int)destiny->x2-(int)destiny->x1, (int)destiny->y2-(int)destiny->y1};
391 			SDL_BlitSurface(front, &o, image, &d);
392 			if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
393 				SDL_SetAlpha(back, saved_flags, saved_alpha);
394 			}
395 		}
396 		SDL_FreeSurface(front);
397 		SDL_FreeSurface(back);
398 		return image;
399 
400 	}
401 
getSize(string file)402 	Size WorkingSurfaces::getSize(string file) {
403 		SDL_Surface* temp = IMG_Load((char*)file.c_str());
404 		Size s;
405 		if ( temp == NULL ) {
406 			printf("Unable to load %s: %s\n", file.c_str(), SDL_GetError());
407 			s.w = 0;
408 			s.h = 0;
409 		} else {
410 			s.w = temp->w;
411 			s.h = temp->h;
412 			SDL_FreeSurface(temp);
413 		}
414 		return s;
415 	}
416 
417 	/*****************************
418 	**
419 	** CLASE Primitives
420 	**
421 	******************************/
422 
423 	Primitives* Primitives::instance = NULL;
424 
Primitives()425 	Primitives::Primitives() {
426 	}
427 
GetInstance()428 	Primitives* Primitives::GetInstance () {
429 		if ( instance == NULL ) {
430 			instance = new Primitives();
431 		}
432 		return instance;
433 	}
434 
rectangle(int w,int h,int r,int g,int b)435 	SDL_Surface* Primitives::rectangle ( int w, int h, int r, int g, int b ) {
436 		SDL_Surface *surface;
437 		Uint32 rmask, gmask, bmask, amask;
438 
439     	#if SDL_BYTEORDER == SDL_BIG_ENDIAN
440     		rmask = 0xff000000;
441     		gmask = 0x00ff0000;
442     		bmask = 0x0000ff00;
443     		amask = 0x000000ff;
444     	#else
445     		rmask = 0x000000ff;
446     		gmask = 0x0000ff00;
447     		bmask = 0x00ff0000;
448     		amask = 0xff000000;
449     	#endif
450 
451 		surface = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
452 									   rmask, gmask, bmask, amask);
453 
454 
455 		int colorkey = SDL_MapRGB(surface->format, r, g, b);
456 		SDL_FillRect(surface, NULL, colorkey);
457 		return surface;
458 	}
459 
put_pixel(SDL_Surface * _ima,int x,int y,Uint32 pixel)460     void Primitives::put_pixel(SDL_Surface *_ima, int x, int y, Uint32 pixel) {
461     	int bpp = _ima->format->BytesPerPixel;
462     	Uint8 *p = (Uint8 *)_ima->pixels + y * _ima->pitch + x*bpp;
463 
464     	switch (bpp)
465     	{
466     		case 1:
467     			*p = pixel;
468     			break;
469 
470     		case 2:
471     			*(Uint16 *)p = pixel;
472     			break;
473 
474     		case 3:
475     			if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
476     			{
477     				p[0]=(pixel >> 16) & 0xff;
478     				p[1]=(pixel >> 8) & 0xff;
479     				p[2]=pixel & 0xff;
480     			}
481     			else
482     			{
483     				p[0]=pixel & 0xff;
484     				p[1]=(pixel >> 8) & 0xff;
485     				p[2]=(pixel >> 16) & 0xff;
486     			}
487     			break;
488 
489     		case 4:
490     			*(Uint32 *) p = pixel;
491     			break;
492     	}
493     }
494 
border(int w,int h,int r,int g,int b,int thickness,int space,bool intercaleSpace)495 	SDL_Surface* Primitives::border ( int w, int h, int r, int g, int b, int thickness, int space, bool intercaleSpace ) {
496 		SDL_Surface *surface;
497 		Uint32 rmask, gmask, bmask, amask;
498 
499     	#if SDL_BYTEORDER == SDL_BIG_ENDIAN
500     		rmask = 0xff000000;
501     		gmask = 0x00ff0000;
502     		bmask = 0x0000ff00;
503     		amask = 0x000000ff;
504     	#else
505     		rmask = 0x000000ff;
506     		gmask = 0x0000ff00;
507     		bmask = 0x00ff0000;
508     		amask = 0xff000000;
509     	#endif
510 
511 		surface = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
512 									   rmask, gmask, bmask, amask);
513 
514         Uint32 color = SDL_MapRGB (surface->format, r, g, b);
515 
516     	int x = 0, y = 0;
517 
518         bool paint = true;
519 
520         for (y = 1; y <= thickness; y++) {
521             if (!intercaleSpace) {
522                paint = true;
523             } else {
524                if (y%2==0) {
525                   paint = true;
526                } else {
527                   paint = false;
528                }
529             }
530         	for (x = 1; x < w; x++) {
531                 if (space!=0) if (x%space==0) paint = !paint;
532                 if (paint) {
533             		put_pixel (surface, x, y, color);
534             		put_pixel (surface, x, h-y, color);
535                 }
536             }
537         }
538 
539        	paint = true;
540 
541         for (x = 1; x <= thickness; x++) {
542             if (!intercaleSpace) {
543                paint = true;
544             } else {
545                if (x%2==0) {
546                   paint = true;
547                } else {
548                   paint = false;
549                }
550             }
551         	for (y = 1; y < h; y++) {
552                 if (space!=0) if (y%space==0) paint = !paint;
553                 if (paint) {
554             		put_pixel (surface, x, y, color);
555             		put_pixel (surface, w-x, y, color);
556                 }
557             }
558         }
559 
560 		return surface;
561 	}
562 
rectangle(int w,int h,int r,int g,int b,int border,int rb,int gb,int bb)563 	SDL_Surface* Primitives::rectangle ( int w, int h, int r, int g, int b, int border, int rb, int gb, int bb ) {
564 		SDL_Surface *surface;
565 		Uint32 rmask, gmask, bmask, amask;
566 
567     	#if SDL_BYTEORDER == SDL_BIG_ENDIAN
568     		rmask = 0xff000000;
569     		gmask = 0x00ff0000;
570     		bmask = 0x0000ff00;
571     		amask = 0x000000ff;
572     	#else
573     		rmask = 0x000000ff;
574     		gmask = 0x0000ff00;
575     		bmask = 0x00ff0000;
576     		amask = 0xff000000;
577     	#endif
578 
579 		surface = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
580 									   rmask, gmask, bmask, amask);
581 
582 
583 		int colorkey = SDL_MapRGB(surface->format, rb, gb, bb);
584 		SDL_FillRect(surface, NULL, colorkey);
585 
586 		SDL_Rect rect;
587 		rect.x = border;
588 		rect.y = border;
589 		rect.w = w-(border*2);
590 		rect.h = h-(border*2);
591 
592 		SDL_Surface* surface2 = SDL_CreateRGBSurface(SDL_SWSURFACE, w-(border*2), h-(border*2), 32,
593 									   rmask, gmask, bmask, amask);
594 
595 		colorkey = SDL_MapRGB(surface->format, r, g, b);
596 		SDL_FillRect(surface2, NULL, colorkey);
597 
598 		SDL_BlitSurface(surface2, NULL, surface, &rect);
599 
600 		SDL_FreeSurface(surface2);
601 
602 		return surface;
603 	}
604 
605 	/*****************************
606 	**
607 	** CLASE VectorColors
608 	**
609 	******************************/
610 
VectorColors()611 	VectorColors::VectorColors() {
612 	}
613 
~VectorColors()614 	VectorColors::~VectorColors() {
615 		colors.clear();
616 	}
617 
getIndexColor(int r,int g,int b)618 	int VectorColors::getIndexColor(int r, int g, int b) {
619 		for (int i=0; i<(int)colors.size(); i++) {
620 			if ( (getColor(i)->r == r) && (getColor(i)->g == g) && (getColor(i)->b == b) ) {
621 				 return i;
622 			}
623 		}
624 		return 0;
625 	}
626 
getColor(int n)627 	Color* VectorColors::getColor(int n) {
628 		if (n<(int)colors.size()) {
629 			return &colors[n];
630 		} else {
631 			return NULL;
632 		}
633 	}
634 
635 
636 	/*****************************
637 	**
638 	** CLASE FRAME
639 	**
640 	******************************/
641 
Frame()642 	Frame::Frame() {
643 		w = 0;
644         h = 0;
645 		w_gl = 0;
646         h_gl = 0;
647 		texture = 0;
648 	}
649 
~Frame()650 	Frame::~Frame() {
651 		unLoad();
652 	}
653 
sizeTexGL(int w,int h)654 	int Frame::sizeTexGL(int w, int h) {
655 
656 		int size, sizeGL;
657 
658 		(w>h)?size=w:size=h;
659 
660 		sizeGL = 4;
661 
662 		while (sizeGL < size) {
663 			sizeGL *= 2;
664 		}
665 
666 		return sizeGL;
667 
668 
669 	}
670 
SurfaceGL(SDL_Surface * sfc)671 	SDL_Surface* Frame::SurfaceGL(SDL_Surface* sfc)
672 	{
673 		SDL_Surface *temp = SDL_DisplayFormatAlpha(sfc);
674 		SDL_FreeSurface(sfc);
675 		SDL_Surface *image;
676 
677 		int sizeGL = sizeTexGL(temp->w, temp->h);
678 
679 		w = temp->w;
680 		h = temp->h;
681 		w_gl = sizeGL;
682 		h_gl = sizeGL;
683 
684 		Uint32 saved_flags;
685 		Uint8  saved_alpha;
686 
687 	#if SDL_BYTEORDER == SDL_BIG_ENDIAN
688 		  image = SDL_CreateRGBSurface(SDL_SWSURFACE, w_gl, h_gl, temp->format->BitsPerPixel,
689 									  0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
690 	#else
691 		  image = SDL_CreateRGBSurface(SDL_SWSURFACE, w_gl, h_gl, temp->format->BitsPerPixel,
692 									  0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
693 	#endif
694 
695 		/* Save the alpha blending attributes */
696 		saved_flags = temp->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
697 		saved_alpha = temp->format->alpha;
698 		if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
699 			SDL_SetAlpha(temp, 0, 0);
700 		}
701 
702 		/*int colorkey = SDL_MapRGB(temp->format, 255, 0, 255);
703 		SDL_SetColorKey(image, SDL_SRCCOLORKEY, colorkey);
704 		SDL_FillRect(image, 0, colorkey);*/
705 
706 
707 		SDL_BlitSurface(temp, 0, image, 0);
708 
709 		if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
710 			SDL_SetAlpha(temp, saved_flags, saved_alpha);
711 		}
712 
713 		SDL_FreeSurface(temp);
714 
715 		return(image);
716 	}
717 
718 	// Load Bitmaps And Convert To Textures
loadGL(char * path)719 	void Frame::loadGL(char *path)
720 	{
721 		// Load Texture
722 
723 		SDL_Surface *surf, *temp;
724 
725 		temp = IMG_Load(path);
726 		if ( temp == NULL ) {
727 			printf("Unable to load %s: %s\n", path, SDL_GetError());
728 		}
729 
730 		surf = SurfaceGL(temp);
731 		if (!surf) {
732 			printf ("No se cargo la imagen: %s\n", path);
733 		}
734 
735 		// Create Texture
736 
737 		glGenTextures(1, &texture);
738 		glBindTexture(GL_TEXTURE_2D , texture);
739 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
740 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
741 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
742 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
743 		glPixelStorei(GL_UNPACK_ROW_LENGTH, surf->pitch / surf->format->BytesPerPixel);
744 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, surf->w, surf->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels);
745 		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
746 
747 		SDL_FreeSurface(surf);
748 
749 	};
750 
loadGLSurface(SDL_Surface * surface)751 	void Frame::loadGLSurface (SDL_Surface *surface) {
752 
753 		// Load Texture
754 
755 		SDL_Surface *surf;
756 
757 		surf = SurfaceGL(surface);
758 
759 		// Create Texture
760 		glGenTextures(1, &texture);
761 		glBindTexture(GL_TEXTURE_2D, texture);   // 2d texture (x and y size)
762 
763 		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // scale linearly when image bigger than texture
764 		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // scale linearly when image smalled than texture
765 
766 
767 		glTexImage2D(GL_TEXTURE_2D, 0, 4, surf->w, surf->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels);
768 		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
769 
770 		SDL_FreeSurface(surf);
771 
772 	}
773 
unLoad()774 	void Frame::unLoad() {
775 		glDeleteTextures( 1, &texture );
776 		glBindTexture(GL_TEXTURE_2D,0);
777 	}
778 
779 
780 	/*****************************
781 	**
782 	** CLASS ANIMATION
783 	**
784 	******************************/
785 
Animation()786 	Animation::Animation() {
787 		name = "";
788 		currentFrame = -1;
789 		cyclesBetweenFrames = 4;
790 		cycles = 0;
791 		typeRotation = CIRCULAR_ROTATION;
792 		avFrame = 1;
793 		stopped = false;
794 		isLastFrame = false;
795 	}
796 
~Animation()797 	Animation::~Animation() {
798 		frame.clear();
799 	}
800 
addRangeFrame(int begin,int end,int steps)801 	void Animation::addRangeFrame(int begin, int end, int steps) {
802 		if (steps>0) {
803 			for (int i = begin; i<=end; i+=steps) {
804 				addFrame(i);
805 			}
806 		} else {
807 			for (int i = begin; i>=end; i+=steps) {
808 				addFrame(i);
809 			}
810 		}
811 
812 	}
813 
getFrame()814 	int Animation::getFrame() {
815 		if (stopped) {
816 			return getCurrentFrame();
817 		}
818 		return nextFrame();
819 	}
820 
nextFrame()821 	int Animation::nextFrame() {
822 		cycles++;
823 		isLastFrame = false;
824 		if (frame.size()==0) return 0;
825 		if (cycles%cyclesBetweenFrames==0) {
826 			if ( (currentFrame == (int)frame.size()-1) && (avFrame==1) ) {
827 				isLastFrame = true;
828 				if (typeRotation == CIRCULAR_ROTATION) {
829 					currentFrame = 0;
830 				} else if (typeRotation == AHEADBACK_ROTATION) {
831 					currentFrame--;
832 					avFrame = -1;
833 				} else {
834 					currentFrame = 0;
835 				}
836 			} else if ( (currentFrame == 0) && (avFrame==-1) ) {
837 				if (typeRotation == CIRCULAR_ROTATION) {
838 					currentFrame = frame.size()-1;
839 				} else if (typeRotation == AHEADBACK_ROTATION) {
840 					currentFrame++;
841 					avFrame = 1;
842 				} else {
843 					currentFrame = frame.size()-1;
844 				}
845 			} else {
846 				currentFrame += avFrame;
847 			}
848 		}
849 		return frame[currentFrame];
850 
851 	}
852 
853 	/*****************************
854 	**
855 	** CLASS GROUP
856 	**
857 	******************************/
858 
Group()859 	Group::Group() {
860 		group = NULL;
861 		groupScene = NULL;
862 		posX = 0.0f;
863 		posY = 0.0f;
864 		posXNew = 0;
865 		posYNew = 0;
866 		polarEndX = 0;
867 		polarEndY = 0;
868 		typeMovement = MOVEMENT_DISPLACEMENT;
869 		isMovement = false;
870 		blinking = 0;
871 		stateBlinking = 1;
872 
873 		nCyclesMovementNormal = 0;
874 		countCyclesMovementNormal = 0;
875 		dirX = 0;
876 		dirY = 0;
877 		dx = 0;
878 		dy = 0;
879 		cyclesFadeIn = 0;
880 		cyclesFadeInTotal = 0;
881 		cyclesFadeOut = 0;
882 		cyclesFadeOutTotal = 0;
883 		cyclesBlinking = 0;
884 
885 		cycle = 0;
886 
887 		oldX = 0;
888 		oldY = 0;
889 		alpha = 255;
890 
891 		flexibleData0 = 0.7;
892         flexibleData1 = 0.1;
893 		smoothData = 6;
894 
895 	}
896 
setVelocitySmooth(int t)897 	void Group::setVelocitySmooth (int t) {
898          switch(t) {
899             case VELOCITY_VERYSLOW:
900                  smoothData = 12;
901             break;
902             case VELOCITY_SLOW:
903                  smoothData = 9;
904             break;
905             case VELOCITY_QUICK:
906                  smoothData = 5;
907             break;
908             case VELOCITY_VERYQUICK:
909                  smoothData = 4;
910             break;
911             default:
912                  smoothData = 6;
913             break;
914          }
915     }
916 
setVelocityFlexible(int t)917 	void Group::setVelocityFlexible (int t) {
918          switch(t) {
919             case VELOCITY_VERYSLOW:
920                  flexibleData0 = 0.88;
921                  flexibleData1 = 0.02;
922             break;
923             case VELOCITY_SLOW:
924                  flexibleData0 = 0.83;
925                  flexibleData1 = 0.03;
926             break;
927             case VELOCITY_QUICK:
928                  flexibleData0 = 0.75;
929                  flexibleData1 = 0.11;
930             break;
931             case VELOCITY_VERYQUICK:
932                  flexibleData0 = 0.73;
933                  flexibleData1 = 0.13;
934             break;
935             default:
936                  flexibleData0 = 0.72;
937                  flexibleData1 = 0.1;
938             break;
939          }
940     }
941 
setCurrentScale(float s)942 	void Group::setCurrentScale(float s) {
943 		for (int i=0; i<(int)elements.size(); i++) {
944 			elements[i]->setCurrentScale(s);
945 		}
946 	}
947 
todoAlpha()948     void Group::todoAlpha () {
949 		for (int i=0; i<(int)elements.size(); i++) {
950 			elements[i]->setAlpha(alpha);
951 		}
952     }
953 
getX()954 	float Group::getX () {
955 		float fOut = 0;
956 		if (groupScene!=NULL) fOut+=groupScene->getX();
957 		if (group!=NULL) fOut+=group->getX();
958 		fOut+=posX;
959 		return fOut;
960 	}
961 
getY()962 	float Group::getY () {
963 		float fOut = 0;
964 		if (groupScene!=NULL) fOut+=groupScene->getY();
965 		if (group!=NULL) fOut+=group->getY();
966 		fOut+=posY;
967 		return fOut;
968 	}
969 
setMovementNormal(float x,float y,int ml)970 	void Group::setMovementNormal (float x, float y, int ml) {
971 		typeMovement = MOVEMENT_NORMAL;
972 		isMovement = true;
973 		polarEndX = x;
974 		polarEndY = y;
975 		if (polarEndX>=getX()) {
976 			dirX = DIR_RIGHT;
977 		} else {
978 			dirX = DIR_LEFT;
979 		}
980 		if (polarEndY>=getY()) {
981 			dirY = DIR_DOWN;
982 		} else {
983 			dirY = DIR_UP;
984 		}
985 		float distanceBetweenPositions = sqrt( (double) (y-getY())*(y-getY()) + (x-getX())*(x-getX()));
986 		float cos = (float)(y-getY())/ distanceBetweenPositions;
987 		float sen = (float)(x-getX())/ distanceBetweenPositions;
988 		setDPolarSen(sen);
989 		setDPolarCos(cos);
990 		setDPolarDistance(distanceBetweenPositions/Converter::GetInstance()->ml2cycles(ml));
991 		nCyclesMovementNormal = Converter::GetInstance()->ml2cycles(ml);
992 		countCyclesMovementNormal = 0;
993 	}
994 
move()995 	void Group::move () {
996 		if (typeMovement == MOVEMENT_NORMAL) {
997     		isMovement = false;
998 			if ( (dirX==DIR_RIGHT) && (polarEndX>getX()) ) {
999 				addX( (float) (polarDistance*polarSen) );
1000 				isMovement = true;
1001 			}
1002 			if ( (dirX==DIR_LEFT) && (polarEndX<getX()) ) {
1003 				addX( (float)(polarDistance*polarSen) );
1004 				isMovement = true;
1005 			}
1006 			if ( (dirY==DIR_UP) && (polarEndY<getY()) ) {
1007 				addY( (float)(polarDistance*polarCos) );
1008 				isMovement = true;
1009 			}
1010 			if ( (dirY==DIR_DOWN) && (polarEndY>getY()) ) {
1011 				addY( (float) (polarDistance*polarCos) );
1012 				isMovement = true;
1013 			}
1014 			if (isMovement) countCyclesMovementNormal++;
1015 		} else if (typeMovement == MOVEMENT_SMOOTH) {
1016             isMovement = false;
1017 			if (posX!=posXNew) {
1018 				addX( ((posXNew-posX)/smoothData) );
1019 				isMovement = true;
1020 				if (oldX == posX) {
1021 					posX = posXNew;
1022 				}
1023 			}
1024 			if (posY!=posYNew) {
1025 				addY( ((posYNew-posY)/smoothData) );
1026 				isMovement = true;
1027 				if (oldY == posY) {
1028 					posY = posYNew;
1029 				}
1030 			}
1031 		} else if (typeMovement == MOVEMENT_FLEXIBLE) {
1032 			xs = (float) (xs*flexibleData0+(posXNew-posX)*flexibleData1);
1033 			ys = (float) (ys*flexibleData0+(posYNew-posY)*flexibleData1);
1034 			addX( xs );
1035 			addY( ys );
1036 		} else if (typeMovement == MOVEMENT_DISPLACEMENT) {
1037 			addX( dx );
1038 			addY( dy );
1039 		}
1040 	}
1041 
work()1042 	void Group::work () {
1043 
1044 		cycle++;
1045 
1046 		move();
1047 
1048 		if (cyclesBlinking>0) {
1049 
1050 			if (blinking >0) {
1051 				if (cycle%blinking==0) {
1052 					if (stateBlinking==0) {
1053 						stateBlinking = 1;
1054 					} else {
1055 						stateBlinking = 0;
1056 					}
1057 				}
1058 			}
1059 
1060 			cyclesBlinking--;
1061 
1062 			if ( (blinking >0) && (stateBlinking==0) ) {
1063 				for (int i=0; i<(int)elements.size(); i++) {
1064 					elements[i]->hide();
1065 				}
1066 			} else {
1067 				for (int i=0; i<(int)elements.size(); i++) {
1068 					elements[i]->show();
1069 				}
1070 			}
1071 
1072 		}
1073 		bool changeAlpha = false;
1074 		if (cyclesFadeIn>0) {
1075             changeAlpha = true;
1076 			cyclesFadeIn--;
1077 			alpha = (255/cyclesFadeInTotal) * (cyclesFadeInTotal - cyclesFadeIn);
1078 			if (cyclesFadeIn == 0) {
1079 				alpha = 255;
1080 			}
1081 		}
1082 
1083 		if (cyclesFadeOut>0) {
1084             changeAlpha = true;
1085 			cyclesFadeOut--;
1086 			alpha = 255 - ((255/cyclesFadeOutTotal) * (cyclesFadeOutTotal - cyclesFadeOut));
1087 			if (cyclesFadeOut == 0) {
1088 				alpha = 0;
1089 			}
1090 		}
1091 		if (changeAlpha) {
1092     		for (int i=0; i<(int)elements.size(); i++) {
1093     			elements[i]->setAlpha(alpha);
1094     		}
1095         }
1096 	}
1097 
draw()1098 	void Group::draw () {
1099 		for (int i=0; i<(int)elements.size(); i++) {
1100 			elements[i]->draw();
1101 		}
1102     }
1103 
unLoad()1104 	void Group::unLoad () {
1105 		for (int i=0; i<(int)elements.size(); i++) {
1106 			delete elements[i];
1107 		}
1108     }
1109 
1110 	/*****************************
1111 	**
1112 	** CLASS MarqueeElement
1113 	**
1114 	******************************/
1115 
MarqueeElement()1116 	MarqueeElement::MarqueeElement() : AnimatedElement () {
1117         text = "";
1118         nLetters = 0;
1119 	}
1120 
1121 
~MarqueeElement()1122 	MarqueeElement::~MarqueeElement () {
1123 		unLoad();
1124 	}
1125 
setText(string font,string t,int nl)1126 	void MarqueeElement::setText(string font, string t, int nl) {
1127 		text = t;
1128 		nLetters = nl;
1129         Animation a;
1130         a.setName("marquee");
1131         a.setCyclesBetweenFrames(15);
1132 		if (nLetters>=(int)text.length()) {
1133              addFrameText(font, text, ALIGN_CENTER);
1134              a.addFrame(0);
1135         } else {
1136              bool sw = true;
1137              for (int i=0; i<(int)text.length(); i++) {
1138             	string s = "";
1139                 if ( (sw) && (i<nLetters) ) {
1140                 	for (int j=0; j<nLetters-i; j++) {
1141                         s = s + " ";
1142                     }
1143                     s = s + text.substr(0, i);
1144                 } else if ( (sw) && (i==nLetters) ) {
1145                     i = -1;
1146                     sw = false;
1147                     continue;
1148                 } else {
1149                     s = s + text.substr(i, nLetters);
1150                     int size = nLetters-(int)s.length();
1151                     for (int j=0; j<size; j++) {
1152                         s = s + " ";
1153                     }
1154                 }
1155             	addFrameText(font, s, ALIGN_CENTER);
1156              }
1157              a.addRangeFrame(0, text.length()+nLetters-1, 1);
1158         }
1159 
1160         addAnimation(a);
1161         setAnimation("marquee");
1162 
1163     }
1164 
1165 	/*****************************
1166 	**
1167 	** CLASS GroupScene
1168 	**
1169 	******************************/
1170 
GroupScene()1171 	GroupScene::GroupScene() : Group () {
1172 	}
1173 
1174 	/*****************************
1175 	**
1176 	** CLASS ELEMENT
1177 	**
1178 	******************************/
1179 
Element()1180 	Element::Element() {
1181 		group = NULL;
1182 		groupScene = NULL;
1183 
1184 		perspectiveX1 = 0;
1185 		perspectiveY1 = 0;
1186 		perspectiveX2 = 0;
1187 		perspectiveY2 = 0;
1188 		perspectiveX3 = 0;
1189 		perspectiveY3 = 0;
1190 		perspectiveX4 = 0;
1191 		perspectiveY4 = 0;
1192 
1193 		factorMaskW = 1.0;
1194         factorMaskH = 1.0;
1195 		flip = false;
1196 		flop = false;
1197 		indexz = 0;
1198 		typeMovement = MOVEMENT_DISPLACEMENT;
1199 		isMovement = false;
1200 		cycle = 0;
1201 		blinking = 0;
1202 		stateBlinking = 1;
1203 		activeBlinking = false;
1204 		cFrame = 0;
1205 		posX = 0;
1206 		posY = 0;
1207 		posXNew = 0;
1208 		posYNew = 0;
1209 		polarEndX = 0;
1210 		polarEndY = 0;
1211 		nCyclesMovementNormal = 0;
1212 		countCyclesMovementNormal = 0;
1213 		dirX = 0;
1214 		dirY = 0;
1215 		dx = 0;
1216 		dy = 0;
1217 		cyclesFadeIn = 0;
1218 		cyclesFadeInTotal = 0;
1219 		cyclesFadeOut = 0;
1220 		cyclesFadeOutTotal = 0;
1221 		cyclesBlinking = 0;
1222 
1223 		red = 255;
1224 		green = 255;
1225 		blue = 255;
1226 
1227 		// rotate
1228 		typeScale = ROTATE_NORMAL;
1229 		forceRotateCenter = false;
1230 		rot = 0.0f;
1231 		rotX = 0.0f;
1232 		rotY = 0.0f;
1233 		rotZ = 1.0f;
1234 		endRotate = 0.0f;
1235 		factorRotate = 0.0f;
1236 		sRotate = 0.0f;
1237 		canRotate = false;
1238 		// scale
1239 		canScale = false;
1240 		typeScale = SCALE_NORMAL;
1241 		factorScaleX = 0.0;
1242 		factorScaleY = 0.0;
1243 		currentScaleX = 1.0;
1244 		currentScaleY = 1.0;
1245 		endScaleX = 0.0;
1246 		endScaleY = 0.0;
1247 		xsScale = 0.0;
1248 		ysScale = 0.0;
1249 
1250 		visible = true;
1251 		oldX = 0;
1252 		oldY = 0;
1253 		alpha = 255;
1254 
1255 		toDoAllEffects = true;
1256 
1257 		align = ALIGN_LEFT;
1258 		valign = VALIGN_TOP;
1259 
1260 		flexibleData0 = 0.7;
1261         flexibleData1 = 0.1;
1262 		smoothData = 6;
1263 
1264 		hasBorder = false;
1265 		showBorderElement = false;
1266 
1267 		hasBackground = false;
1268 		showBackgroundElement = false;
1269 	}
1270 
~Element()1271 	Element::~Element() {
1272 		unLoad();
1273 	}
1274 
setPerspective(float x1,float y1,float x2,float y2,float x3,float y3,float x4,float y4)1275 	void Element::setPerspective(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
1276 		perspectiveX1 = x1;
1277 		perspectiveY1 = y1;
1278 		perspectiveX2 = x2;
1279 		perspectiveY2 = y2;
1280 		perspectiveX3 = x3;
1281 		perspectiveY3 = y3;
1282 		perspectiveX4 = x4;
1283 		perspectiveY4 = y4;
1284 	}
1285 
setPerspectiveRelative(float x1,float y1,float x2,float y2,float x3,float y3,float x4,float y4)1286 	void Element::setPerspectiveRelative(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
1287 		perspectiveX1 = getWidthOriginal()*x1;
1288 		perspectiveY1 = getHeightOriginal()*y1;
1289 		perspectiveX2 = getWidthOriginal()*x2;
1290 		perspectiveY2 = getHeightOriginal()*y2;
1291 		perspectiveX3 = getWidthOriginal()*x3;
1292 		perspectiveY3 = getHeightOriginal()*y3;
1293 		perspectiveX4 = getWidthOriginal()*x4;
1294 		perspectiveY4 = getHeightOriginal()*y4;
1295 	}
1296 
createBorder(int r,int g,int b,int border,int padding)1297 	void Element::createBorder(int r, int g, int b, int border, int padding) {
1298 
1299 		int w=0, h=0;
1300 
1301 		for (int i=0; i<(int)sprite.size(); i++) {
1302 			if (sprite[i]->w > w) {
1303 				w = sprite[i]->w;
1304 			}
1305 			if (sprite[i]->h > h) {
1306 				h = sprite[i]->h;
1307 			}
1308 		}
1309 
1310 		hasBorder = true;
1311 		elmBorder = new Element();
1312 		elmBorder->setAlign(ALIGN_CENTER);
1313 		elmBorder->setVAlign(VALIGN_CENTER);
1314 		elmBorder->setRGB(r,g,b);
1315 		elmBorder->addFrameSurface(Primitives::GetInstance()->border(w+(padding*2), h+(padding*2), 255, 255, 255, border));
1316     }
1317 
createBackground(int r,int g,int b,int padding)1318 	void Element::createBackground(int r, int g, int b, int padding) {
1319 
1320 		int w=0, h=0;
1321 
1322 		for (int i=0; i<(int)sprite.size(); i++) {
1323 			if (sprite[i]->w > w) {
1324 				w = sprite[i]->w;
1325 			}
1326 			if (sprite[i]->h > h) {
1327 				h = sprite[i]->h;
1328 			}
1329 		}
1330 
1331 		hasBackground = true;
1332 		elmBackground = new Element();
1333 		elmBackground->setAlign(ALIGN_CENTER);
1334 		elmBackground->setVAlign(VALIGN_CENTER);
1335 		elmBackground->setRGB(r,g,b);
1336 		elmBackground->addFrameSurface(Primitives::GetInstance()->rectangle(w+((padding-1)*2), h+((padding-1)*2), 255, 255, 255));
1337     }
1338 
setVelocitySmooth(int t)1339 	void Element::setVelocitySmooth (int t) {
1340          switch(t) {
1341             case VELOCITY_VERYSLOW:
1342                  smoothData = 12;
1343             break;
1344             case VELOCITY_SLOW:
1345                  smoothData = 9;
1346             break;
1347             case VELOCITY_QUICK:
1348                  smoothData = 5;
1349             break;
1350             case VELOCITY_VERYQUICK:
1351                  smoothData = 4;
1352             break;
1353             default:
1354                  smoothData = 6;
1355             break;
1356          }
1357     }
1358 
setVelocityFlexible(int t)1359 	void Element::setVelocityFlexible (int t) {
1360          switch(t) {
1361             case VELOCITY_VERYSLOW:
1362                  flexibleData0 = 0.88;
1363                  flexibleData1 = 0.02;
1364             break;
1365             case VELOCITY_SLOW:
1366                  flexibleData0 = 0.83;
1367                  flexibleData1 = 0.03;
1368             break;
1369             case VELOCITY_QUICK:
1370                  flexibleData0 = 0.75;
1371                  flexibleData1 = 0.11;
1372             break;
1373             case VELOCITY_VERYQUICK:
1374                  flexibleData0 = 0.73;
1375                  flexibleData1 = 0.13;
1376             break;
1377             default:
1378                  flexibleData0 = 0.72;
1379                  flexibleData1 = 0.1;
1380             break;
1381          }
1382     }
1383 
getValueXPlusGroups(float x)1384 	float Element::getValueXPlusGroups (float x) {
1385 		float fOut = 0;
1386 		if (groupScene!=NULL) fOut+=groupScene->getX();
1387 		if (group!=NULL) fOut+=group->getX();
1388 		fOut+=x;
1389 		return fOut;
1390 	}
1391 
getValueYPlusGroups(float y)1392 	float Element::getValueYPlusGroups (float y) {
1393 		float fOut = 0;
1394 		if (groupScene!=NULL) fOut+=groupScene->getY();
1395 		if (group!=NULL) fOut+=group->getY();
1396 		fOut+=y;
1397 		return fOut;
1398 	}
1399 
getDisplacementInXByGroups()1400 	float Element::getDisplacementInXByGroups () {
1401 		float fOut = 0;
1402 		if (groupScene!=NULL) fOut+=groupScene->getX();
1403 		if (group!=NULL) fOut+=group->getX();
1404 		return fOut;
1405 	}
1406 
getCenterPosition()1407 	Position Element::getCenterPosition() {
1408 		Position p;
1409 		switch (align) {
1410 			case ALIGN_LEFT:
1411 				p.x = getX()+(getWidth()/2);
1412 			break;
1413 			case ALIGN_CENTER:
1414 				p.x = getX();
1415 			break;
1416 			case ALIGN_RIGHT:
1417 				p.x = getX()-(getWidth()/2);
1418 			break;
1419 		}
1420 		switch (valign) {
1421 			case VALIGN_TOP:
1422 				p.y = getY()+(getHeight()/2);
1423 			break;
1424 			case VALIGN_CENTER:
1425 				p.y = getY();
1426 			break;
1427 			case VALIGN_BOTTOM:
1428 				p.y = getY()-(getHeight()/2);
1429 			break;
1430 		}
1431 		return p;
1432 	}
1433 
getBounds()1434 	Bounds Element::getBounds() {
1435 		Bounds b;
1436 
1437 		float x1 = 0, y1 = 0;
1438 		float x2 = 0, y2 = 0;
1439 
1440 		if (getAlign() == ALIGN_LEFT) {
1441 			x1 = getX();
1442 		} else if (getAlign() == ALIGN_CENTER) {
1443 			x1 = getX() - (getWidth()/2);
1444 		} else if (getAlign() == ALIGN_RIGHT) {
1445 			x1 = getX() - getWidth();
1446 		}
1447 
1448 		if (getVAlign() == VALIGN_TOP) {
1449 			y1 = getY();
1450 		} else if (getVAlign() == VALIGN_CENTER) {
1451 			y1 = getY() - (getHeight()/2);
1452 		} else if (getVAlign() == VALIGN_BOTTOM) {
1453 			y1 = getY() - getHeight();
1454 		}
1455 
1456 		float x2aux1 = x1 + getWidth() + (perspectiveX2*currentScaleX);
1457 		float x2aux2 = x1 + getWidth() + (perspectiveX4*currentScaleX);
1458 
1459 		if (x2aux1>x2aux2) {
1460 			x2 = x2aux1;
1461 		} else {
1462 			x2 = x2aux2;
1463 		}
1464 
1465 		float y2aux1 = y1 + getHeight() + (perspectiveY3*currentScaleY);
1466 		float y2aux2 = y1 + getHeight() + (perspectiveY4*currentScaleY);
1467 
1468 		if (y2aux1>y2aux2) {
1469 			y2 = y2aux1;
1470 		} else {
1471 			y2 = y2aux2;
1472 		}
1473 
1474 		float x1aux1 = x1 + (perspectiveX1*currentScaleX);
1475 		float x1aux2 = x1 + (perspectiveX3*currentScaleX);
1476 
1477 		if (x1aux1<x1aux2) {
1478 			x1 = x1aux1;
1479 		} else {
1480 			x1 = x1aux2;
1481 		}
1482 
1483 		float y1aux1 = y1 + (perspectiveY1*currentScaleY);
1484 		float y1aux2 = y1 + (perspectiveY2*currentScaleY);
1485 
1486 		if (y1aux1<y1aux2) {
1487 			y1 = y1aux1;
1488 		} else {
1489 			y1 = y1aux2;
1490 		}
1491 
1492 		b.x1 = x1;
1493 		b.y1 = y1;
1494 		b.x2 = x2;
1495 		b.y2 = y2;
1496 
1497 		return b;
1498 	}
1499 
getX()1500 	float Element::getX () {
1501 		return getDisplacementInXByGroups () + posX;
1502 	}
1503 
getDisplacementInYByGroups()1504 	float Element::getDisplacementInYByGroups () {
1505 		float fOut = 0;
1506 		if (groupScene!=NULL) fOut+=groupScene->getY();
1507 		if (group!=NULL) fOut+=group->getY();
1508 		return fOut;
1509 	}
1510 
getY()1511 	float Element::getY () {
1512 		return getDisplacementInYByGroups () + posY;
1513 	}
1514 
getLimitBottom()1515 	int Element::getLimitBottom () {
1516 		return World::height + (getHeight() * 2) -5;
1517 	}
1518 
getLimitRight()1519 	int Element::getLimitRight () {
1520 		return World::width + getWidth() * 2 -5;
1521 	}
1522 
outLimitScreen()1523 	bool Element::outLimitScreen() {
1524 		if ( ( getY() < getLimitTop() ) || ( getY() > getLimitBottom() ) || ( getX() < getLimitLeft() ) || ( getX() > getLimitRight() ) ){
1525 			return 1;
1526 		} else {
1527 			return 0;
1528 		}
1529 	}
1530 
unLoad()1531 	void Element::unLoad() {
1532 		int i;
1533 		for (i=0; i<(int)sprite.size(); i++)
1534 			delete sprite[i];
1535 
1536 		parameters.clear();
1537 		sprite.clear();
1538 		if (hasBorder) elmBorder->unLoad();
1539 		if (hasBackground) elmBackground->unLoad();
1540 	}
1541 
addFrame(Frame * frame)1542 	void Element::addFrame (Frame* frame) {
1543 		sprite.push_back(frame);
1544 	}
1545 
addFrame(string file)1546 	void Element::addFrame (string file) {
1547 		Frame *fr = new Frame();
1548 		if (WorkingData::GetInstance()->existFile(file)) {
1549 		   fr->loadGL((char*)file.c_str());
1550         } else {
1551            fr->loadGLSurface(Primitives::GetInstance()->rectangle(1, 1, 0, 0, 0));
1552            printf("Don't exist the file %s\n", file.c_str());
1553         }
1554 		addFrame(fr);
1555 	}
1556 
changeFrame(int position,Frame * frame)1557 	void Element::changeFrame (int position, Frame *frame) {
1558         delete sprite[position];
1559 		sprite[position] = frame;
1560 	}
1561 
changeFrame(int position,string file)1562 	void Element::changeFrame (int position, string file) {
1563 		Frame *fr = new Frame();
1564 		if (WorkingData::GetInstance()->existFile(file)) {
1565 		   fr->loadGL((char*)file.c_str());
1566         } else {
1567            fr->loadGLSurface(Primitives::GetInstance()->rectangle(1, 1, 0, 0, 0));
1568            printf("Don't exist the file %s\n", file.c_str());
1569         }
1570 		changeFrame (position, fr);
1571 	}
1572 
addFrameFile(string file)1573 	void Element::addFrameFile (string file) {
1574 		addFrame(file);
1575 	}
1576 
addFrameFile(string name,string ext,int valueInRange)1577 	void Element::addFrameFile (string name, string ext, int valueInRange) {
1578 		string chain = name + string("_");
1579 		char numbers[4];
1580 		sprintf(numbers, "%d", valueInRange);
1581 		if ( (valueInRange>=0) && (valueInRange<10) ) {
1582 			chain += "000" + string(numbers);
1583 		} else if ( (valueInRange>=10) && (valueInRange<100) ) {
1584 			chain += "00" + string(numbers);
1585 		} else if ( (valueInRange>=100) && (valueInRange<1000) ) {
1586 			chain += "0" + string(numbers);
1587 		} else if ( (valueInRange>=1000) && (valueInRange<10000) ) {
1588 			chain += string(numbers);
1589 		} else {
1590 			chain += "0000";
1591 		}
1592 		chain += string(".") + ext;
1593 		addFrameFile(chain);
1594 	}
1595 
addFrameFileFromData(string file)1596 	void Element::addFrameFileFromData (string file) {
1597 		addFrame((string)DATA_DIR + file);
1598     }
1599 
addFrameFileFromData(string name,string ext,int valueInRange)1600 	void Element::addFrameFileFromData (string name, string ext, int valueInRange) {
1601 		string chain = name + string("_");
1602 		char numbers[4];
1603 		sprintf(numbers, "%d", valueInRange);
1604 		if ( (valueInRange>=0) && (valueInRange<10) ) {
1605 			chain += "000" + string(numbers);
1606 		} else if ( (valueInRange>=10) && (valueInRange<100) ) {
1607 			chain += "00" + string(numbers);
1608 		} else if ( (valueInRange>=100) && (valueInRange<1000) ) {
1609 			chain += "0" + string(numbers);
1610 		} else if ( (valueInRange>=1000) && (valueInRange<10000) ) {
1611 			chain += string(numbers);
1612 		} else {
1613 			chain += "0000";
1614 		}
1615 		chain += string(".") + ext;
1616 		addFrameFileFromData(chain);
1617 	}
1618 
addFrameText(string font,string text,int align)1619 	void Element::addFrameText (string font, string text, int align) {
1620     	Frame *fr = new Frame();
1621     	fr->loadGLSurface(Fonts::GetInstance()->getSurface_TextBitMap(font, align, (char*)text.c_str()));
1622 		addFrame(fr);
1623     }
1624 
addFrameText(string font,string text,int align,int width)1625 	void Element::addFrameText (string font, string text, int align, int width) {
1626     	Frame *fr = new Frame();
1627     	fr->loadGLSurface(Fonts::GetInstance()->getSurface_TextBitMap(font, currentScaleX, width, align, (char*)text.c_str()));
1628 		addFrame(fr);
1629     }
1630 
addFrameLanguage(string font,string key,int align)1631 	void Element::addFrameLanguage (string font, string key, int align) {
1632 		addFrameSurface(Fonts::GetInstance()->getSurface_TextBitMap(font, align, (char*)Language::GetInstance()->getText(key).c_str()));
1633     }
1634 
addFrameLanguage(string font,string key,int align,int width)1635 	void Element::addFrameLanguage (string font, string key, int align, int width) {
1636 		addFrameSurface(Fonts::GetInstance()->getSurface_TextBitMap(font, currentScaleX, width, align, (char*)Language::GetInstance()->getText(key).c_str()));
1637     }
1638 
addFrameSurface(SDL_Surface * sfc)1639 	void Element::addFrameSurface (SDL_Surface *sfc) {
1640     	Frame *fr = new Frame();
1641     	fr->loadGLSurface(sfc);
1642 		addFrame(fr);
1643     }
1644 
changeFrameFile(int pos,string file)1645 	void Element::changeFrameFile (int pos, string file) {
1646 		changeFrame(pos, file);
1647 	}
1648 
changeFrameFile(int pos,string name,string ext,int valueInRange)1649 	void Element::changeFrameFile (int pos, string name, string ext, int valueInRange) {
1650 		string chain = name + string("_");
1651 		char numbers[4];
1652 		sprintf(numbers, "%d", valueInRange);
1653 		if ( (valueInRange>=0) && (valueInRange<10) ) {
1654 			chain += "000" + string(numbers);
1655 		} else if ( (valueInRange>=10) && (valueInRange<100) ) {
1656 			chain += "00" + string(numbers);
1657 		} else if ( (valueInRange>=100) && (valueInRange<1000) ) {
1658 			chain += "0" + string(numbers);
1659 		} else if ( (valueInRange>=1000) && (valueInRange<10000) ) {
1660 			chain += string(numbers);
1661 		} else {
1662 			chain += "0000";
1663 		}
1664 		chain += string(".") + ext;
1665 		changeFrameFile(pos, chain);
1666 	}
1667 
changeFrameFileFromData(int pos,string file)1668 	void Element::changeFrameFileFromData (int pos, string file) {
1669 		changeFrame(pos, (string)DATA_DIR + file);
1670     }
1671 
changeFrameFileFromData(int pos,string name,string ext,int valueInRange)1672 	void Element::changeFrameFileFromData (int pos, string name, string ext, int valueInRange) {
1673 		string chain = name + string("_");
1674 		char numbers[4];
1675 		sprintf(numbers, "%d", valueInRange);
1676 		if ( (valueInRange>=0) && (valueInRange<10) ) {
1677 			chain += "000" + string(numbers);
1678 		} else if ( (valueInRange>=10) && (valueInRange<100) ) {
1679 			chain += "00" + string(numbers);
1680 		} else if ( (valueInRange>=100) && (valueInRange<1000) ) {
1681 			chain += "0" + string(numbers);
1682 		} else if ( (valueInRange>=1000) && (valueInRange<10000) ) {
1683 			chain += string(numbers);
1684 		} else {
1685 			chain += "0000";
1686 		}
1687 		chain += string(".") + ext;
1688 		changeFrameFileFromData(pos, chain);
1689 	}
1690 
changeFrameText(int pos,string font,string text,int align)1691 	void Element::changeFrameText (int pos, string font, string text, int align) {
1692     	Frame *fr = new Frame();
1693     	fr->loadGLSurface(Fonts::GetInstance()->getSurface_TextBitMap(font, align, (char*)text.c_str()));
1694 		changeFrame(pos, fr);
1695     }
1696 
changeFrameText(int pos,string font,string text,int align,int width)1697 	void Element::changeFrameText (int pos, string font, string text, int align, int width) {
1698     	Frame *fr = new Frame();
1699     	fr->loadGLSurface(Fonts::GetInstance()->getSurface_TextBitMap(font, currentScaleX, width, align, (char*)text.c_str()));
1700 		changeFrame(pos, fr);
1701     }
1702 
changeFrameLanguage(int pos,string font,string key,int align)1703 	void Element::changeFrameLanguage (int pos, string font, string key, int align) {
1704     	Frame *fr = new Frame();
1705     	fr->loadGLSurface(Fonts::GetInstance()->getSurface_TextBitMap(font, align, (char*)Language::GetInstance()->getText(key).c_str()));
1706 		changeFrame(pos, fr);
1707     }
1708 
changeFrameLanguage(int pos,string font,string key,int align,int width)1709 	void Element::changeFrameLanguage (int pos, string font, string key, int align, int width) {
1710     	Frame *fr = new Frame();
1711     	fr->loadGLSurface(Fonts::GetInstance()->getSurface_TextBitMap(font, currentScaleX, width, align, (char*)Language::GetInstance()->getText(key).c_str()));
1712 		changeFrame(pos, fr);
1713     }
1714 
changeFrameSurface(int pos,SDL_Surface * sfc)1715 	void Element::changeFrameSurface (int pos, SDL_Surface *sfc) {
1716     	Frame *fr = new Frame();
1717     	fr->loadGLSurface(sfc);
1718 		changeFrame(pos, fr);
1719     }
1720 
addRangeFrames(string name,string ext,int valBeg,int valEnd)1721 	void Element::addRangeFrames (string name, string ext, int valBeg, int valEnd) {
1722 		char tmp[128];
1723 		string chain;
1724 
1725 		for (int i=valBeg; i<=valEnd; i++) {
1726 			chain = name + string("_");
1727 			chain += Converter::GetInstance()->fillZeros(i);
1728 			chain += string(".") + ext;
1729 			strcpy(tmp, chain.c_str());
1730 			Frame *fr = new Frame();
1731 			fr->loadGL(tmp);
1732 			this->addFrame(fr);
1733 		}
1734 	}
1735 
addRangeFramesFromData(string name,string ext,int valBeg,int valEnd)1736 	void Element::addRangeFramesFromData (string name, string ext, int valBeg, int valEnd) {
1737 		char tmp[128];
1738 		string chain;
1739 
1740 		for (int i=valBeg; i<=valEnd; i++) {
1741 			chain = DATA_DIR + string("/") + name + string("_");
1742 			chain += Converter::GetInstance()->fillZeros(i);
1743 			chain += string(".") + ext;
1744 			strcpy(tmp, chain.c_str());
1745 			Frame *fr = new Frame();
1746 			fr->loadGL(tmp);
1747 			this->addFrame(fr);
1748 		}
1749 	}
1750 
setRotationNormal(float degreesEnd,int ml)1751 	void Element::setRotationNormal ( float degreesEnd, int ml) {
1752 		typeRotate = ROTATE_NORMAL;
1753 
1754 		endRotate = degreesEnd;
1755 
1756 		factorRotate = (degreesEnd-rot) / Converter::GetInstance()->ml2cycles(ml);
1757 
1758 		canRotate = true;
1759 
1760 	}
1761 
setRotationNormal(float degreesBegin,float degreesEnd,int ml)1762 	void Element::setRotationNormal (float degreesBegin, float degreesEnd, int ml) {
1763 		typeRotate = ROTATE_NORMAL;
1764 
1765 		endRotate = degreesEnd;
1766 		rot = degreesBegin;
1767 
1768 		factorRotate = (degreesEnd-rot) / Converter::GetInstance()->ml2cycles(ml);
1769 
1770 		canRotate = true;
1771 
1772 	}
1773 
setRotationSmooth(float degreesEnd)1774 	void Element::setRotationSmooth (float degreesEnd) {
1775 		typeRotate = ROTATE_SMOOTH;
1776 
1777 		endRotate = degreesEnd;
1778 
1779 		canRotate = true;
1780 
1781 	}
1782 
setRotationFlexible(float degreesEnd)1783 	void Element::setRotationFlexible (float degreesEnd) {
1784 
1785 		typeRotate = ROTATE_FLEXIBLE;
1786 		canRotate = true;
1787 
1788 		endRotate = degreesEnd;
1789 
1790 		/*while(rot>360) {
1791 			rot = 360%(int)endRotate;
1792 		}
1793 		if (rot==360) rot = 0;*/
1794 
1795 	}
1796 
setScale(float w,float h)1797 	void Element::setScale (float w, float h) {
1798 
1799 		currentScaleX = w/getWidthOriginal();
1800 		currentScaleY = h/getHeightOriginal();
1801 
1802 	}
1803 
setScale(float w,float h,int mlRoute)1804 	void Element::setScale (float w, float h, int mlRoute) {
1805 
1806 		typeScale = SCALE_NORMAL;
1807 		canScale = true;
1808 
1809 		endScaleX = w/getWidthOriginal();
1810 		endScaleY = h/getHeightOriginal();
1811 
1812 		factorScaleX = (endScaleX-currentScaleX) / Converter::GetInstance()->ml2cycles(mlRoute);
1813 		factorScaleY = (endScaleY-currentScaleY) / Converter::GetInstance()->ml2cycles(mlRoute);
1814 
1815 	}
1816 
setScaleSmooth(float w,float h)1817 	void Element::setScaleSmooth (float w, float h) {
1818 
1819 		typeScale = SCALE_SMOOTH;
1820 		canScale = true;
1821 
1822 		endScaleX = w/getWidthOriginal();
1823 		endScaleY = h/getHeightOriginal();
1824 
1825 	}
1826 
setScaleFlexible(float w,float h)1827 	void Element::setScaleFlexible (float w, float h) {
1828 
1829 		typeScale = SCALE_FLEXIBLE;
1830 		canScale = true;
1831 
1832 		endScaleX = w/getWidthOriginal();
1833 		endScaleY = h/getHeightOriginal();
1834 
1835 	}
1836 
transforms()1837 	void Element::transforms () {
1838 		// rotate
1839 
1840 		if (canRotate) {
1841 			if (typeRotate==ROTATE_NORMAL) {
1842 				rot += factorRotate;
1843 				if (factorRotate>0)	{
1844 					if (rot>endRotate) {
1845 						canRotate = false;
1846 						rot = (float)((int)endRotate%360);
1847 					}
1848 				} else {
1849 					if (rot<endRotate) {
1850 						canRotate = false;
1851 						rot = (float)((int)endRotate%360);
1852 					}
1853 				}
1854 			} else if (typeRotate==ROTATE_SMOOTH) {
1855 				rot += (endRotate-rot)/smoothData;
1856 				if ((endRotate-rot)>0) {
1857 					if ((int)rot+1>=(int)endRotate) {
1858 						canRotate = false;
1859 						rot = (float)((int)endRotate%360);
1860 					}
1861 				} else {
1862 					if ((int)rot-1<=(int)endRotate) {
1863 						canRotate = false;
1864 						rot = (float)((int)endRotate%360);
1865 					}
1866 				}
1867 			} else if (typeRotate==ROTATE_FLEXIBLE) {
1868 				sRotate = (float) (sRotate*flexibleData0+(endRotate-rot)*flexibleData1);
1869 				rot += sRotate;
1870 			}
1871 		}
1872 
1873 		// scale
1874 		if (canScale) {
1875 			if (typeScale==SCALE_NORMAL) {
1876 				currentScaleX += factorScaleX;
1877 				currentScaleY += factorScaleY;
1878 				if (factorScaleX>=0) {
1879 					if (currentScaleX>=endScaleX) {
1880 						currentScaleX=endScaleX;
1881 						canScale = false;
1882 					}
1883 				} else {
1884 					if (currentScaleX<=endScaleX) {
1885 						currentScaleX=endScaleX;
1886 						canScale = false;
1887 					}
1888 				}
1889 				if (factorScaleY>=0) {
1890 					if (currentScaleY>=endScaleY) {
1891 						currentScaleY=endScaleY;
1892 						canScale = false;
1893 					}
1894 				} else {
1895 					if (currentScaleY<=endScaleY) {
1896 						currentScaleY=endScaleY;
1897 						canScale = false;
1898 					}
1899 				}
1900 			} else if (typeScale==SCALE_SMOOTH) {
1901 				currentScaleX += (endScaleX-currentScaleX)/smoothData;
1902 				currentScaleY += (endScaleY-currentScaleY)/smoothData;
1903 				if (currentScaleX>=endScaleX) {
1904 					currentScaleX=endScaleX;
1905 					canScale = false;
1906 				}
1907 				if (currentScaleY>=endScaleY) {
1908 					currentScaleY=endScaleY;
1909 					canScale = false;
1910 				}
1911 			} else if (typeScale==SCALE_FLEXIBLE) {
1912 				xsScale = (float) (xsScale*flexibleData0+(endScaleX-currentScaleX)*flexibleData1);
1913 				ysScale = (float) (ysScale*flexibleData0+(endScaleY-currentScaleY)*flexibleData1);
1914 				currentScaleX += xsScale;
1915 				currentScaleY += ysScale;
1916 				/*if (currentScaleX>=endScaleX) {
1917 					currentScaleX=endScaleX;
1918 					canScale = false;
1919 				}
1920 				if (currentScaleY>=endScaleY) {
1921 					currentScaleY=endScaleY;
1922 					canScale = false;
1923 				}*/
1924 			}
1925 		}
1926 
1927 	}
1928 
setMovementNormal(float x,float y,int ml)1929 	void Element::setMovementNormal (float x, float y, int ml) {
1930 		typeMovement = MOVEMENT_NORMAL;
1931 		isMovement = true;
1932 		x = getValueXPlusGroups(x);
1933 		y = getValueYPlusGroups(y);
1934 		polarEndX = x;
1935 		polarEndY = y;
1936 		if (polarEndX>=getX()) {
1937 			dirX = DIR_RIGHT;
1938 		} else {
1939 			dirX = DIR_LEFT;
1940 		}
1941 		if (polarEndY>=getY()) {
1942 			dirY = DIR_DOWN;
1943 		} else {
1944 			dirY = DIR_UP;
1945 		}
1946 		float distanceBetweenPositions = sqrt( (double) (y-getY())*(y-getY()) + (x-getX())*(x-getX()));
1947 		float cos = (float)(y-getY())/ distanceBetweenPositions;
1948 		float sen = (float)(x-getX())/ distanceBetweenPositions;
1949 		setDPolarSen(sen);
1950 		setDPolarCos(cos);
1951 		setDPolarDistance(distanceBetweenPositions/Converter::GetInstance()->ml2cycles(ml));
1952 		nCyclesMovementNormal = Converter::GetInstance()->ml2cycles(ml);
1953 		countCyclesMovementNormal = 0;
1954 	}
1955 
move()1956 	void Element::move () {
1957 		if (typeMovement == MOVEMENT_NORMAL) {
1958     		isMovement = false;
1959 			if ( (dirX==DIR_RIGHT) && (polarEndX>getX()) ) {
1960 				addX( (float) (polarDistance*polarSen) );
1961 				isMovement = true;
1962 			}
1963 			if ( (dirX==DIR_LEFT) && (polarEndX<getX()) ) {
1964 				addX( (float)(polarDistance*polarSen) );
1965 				isMovement = true;
1966 			}
1967 			if ( (dirY==DIR_UP) && (polarEndY<getY()) ) {
1968 				addY( (float)(polarDistance*polarCos) );
1969 				isMovement = true;
1970 			}
1971 			if ( (dirY==DIR_DOWN) && (polarEndY>getY()) ) {
1972 				addY( (float) (polarDistance*polarCos) );
1973 				isMovement = true;
1974 			}
1975 			if (isMovement) countCyclesMovementNormal++;
1976 		} else if (typeMovement == MOVEMENT_SMOOTH) {
1977             isMovement = false;
1978 			if (posX!=posXNew) {
1979 				addX( ((posXNew-posX)/smoothData) );
1980 				isMovement = true;
1981 				if (oldX == posX) {
1982 					posX = posXNew;
1983 				}
1984 			}
1985 			if (posY!=posYNew) {
1986 				addY( ((posYNew-posY)/smoothData) );
1987 				isMovement = true;
1988 				if (oldY == posY) {
1989 					posY = posYNew;
1990 				}
1991 			}
1992 		} else if (typeMovement == MOVEMENT_FLEXIBLE) {
1993 			xs = (float) (xs*flexibleData0+(posXNew-posX)*flexibleData1);
1994 			ys = (float) (ys*flexibleData0+(posYNew-posY)*flexibleData1);
1995 			addX( xs );
1996 			addY( ys );
1997 		} else if (typeMovement == MOVEMENT_DISPLACEMENT) {
1998 			addX( dx );
1999 			addY( dy );
2000 		}
2001 	}
2002 
draw()2003 	void Element::draw () {
2004 		if ((int)sprite.size()>0) {
2005 			if (toDoAllEffects) {
2006 				move();
2007 				transforms();
2008 			}
2009 			paintSprite();
2010 		}
2011 	}
2012 
paintSprite()2013 	void Element::paintSprite () {
2014 
2015 		cycle++;
2016 
2017 		if (!visible) return;
2018 
2019 		if ( (hasBackground) && (showBackgroundElement) ) {
2020 			elmBackground->setCurrentScaleX(currentScaleX);
2021 			elmBackground->setCurrentScaleY(currentScaleY);
2022 			elmBackground->setX(getCenterPosition().x);
2023 			elmBackground->setY(getCenterPosition().y);
2024 			elmBackground->setAlpha(getAlpha());
2025 			elmBackground->draw();
2026         }
2027 
2028 		if ( (hasBorder) && (showBorderElement) ) {
2029 			elmBorder->setCurrentScaleX(currentScaleX);
2030 			elmBorder->setCurrentScaleY(currentScaleY);
2031 			elmBorder->setX(getCenterPosition().x);
2032 			elmBorder->setY(getCenterPosition().y);
2033 			elmBorder->setAlpha(getAlpha());
2034 			elmBorder->draw();
2035         }
2036 
2037 		if (activeBlinking) {
2038 
2039 			if (blinking >0) {
2040 				if (cycle%blinking==0) {
2041 					if (stateBlinking==0) {
2042 						stateBlinking = 1;
2043 					} else {
2044 						stateBlinking = 0;
2045 					}
2046 				}
2047 			}
2048 
2049 			if ( (blinking >0) && (stateBlinking==0) ) {
2050 				return;
2051 			}
2052 
2053 		} else {
2054 
2055 			if (cyclesBlinking>0) {
2056 
2057 				if (blinking >0) {
2058 					if (cycle%blinking==0) {
2059 						if (stateBlinking==0) {
2060 							stateBlinking = 1;
2061 						} else {
2062 							stateBlinking = 0;
2063 						}
2064 					}
2065 				}
2066 
2067 				cyclesBlinking--;
2068 
2069 				if ( (blinking >0) && (stateBlinking==0) ) {
2070 					return;
2071 				}
2072 
2073 			}
2074 
2075 		}
2076 
2077 		float relW = ((float)sprite[cFrame]->w/(float)sprite[cFrame]->w_gl)*factorMaskW;
2078 		float relH = ((float)sprite[cFrame]->h/(float)sprite[cFrame]->h_gl)*factorMaskH;
2079 		float auxCSX = currentScaleX;
2080 		float auxCSY = currentScaleY;
2081 		currentScaleX -= (1.0 - factorMaskW);
2082 		currentScaleY -= (1.0 - factorMaskH);
2083 
2084 		float cornerx1, cornerx2, cornery1, cornery2;
2085 
2086 		if (forceRotateCenter) {
2087 
2088 			cornerx1 = -getWidth()/2;
2089 			cornerx2 = getWidth()/2;
2090 			cornery1 = -getHeight()/2;
2091 			cornery2 = getHeight()/2;
2092 
2093 		} else {
2094 
2095 			switch (align)
2096 			{
2097 				case ALIGN_CENTER:
2098 					cornerx1 = -getWidth()/2;
2099 					cornerx2 = getWidth()/2;
2100 					break;
2101 				case ALIGN_RIGHT:
2102 					cornerx1 = -getWidth();
2103 					cornerx2 = 0;
2104 					break;
2105 				default:
2106 					cornerx1 = 0;
2107 					cornerx2 = getWidth();
2108 					break;
2109 			}
2110 
2111 			switch (valign)
2112 			{
2113 				case VALIGN_CENTER:
2114 					cornery1 = -getHeight()/2;
2115 					cornery2 = getHeight()/2;
2116 					break;
2117 				case VALIGN_BOTTOM:
2118 					cornery1 = -getHeight();
2119 					cornery2 = 0;
2120 					break;
2121 				default:
2122 					cornery1 = 0;
2123 					cornery2 = getHeight();
2124 					break;
2125 			}
2126 
2127 		}
2128 
2129 		float posx1, posy1;
2130 
2131 		if (forceRotateCenter) {
2132 			switch (align)
2133 			{
2134 				case ALIGN_CENTER:
2135 					posx1 = getX();
2136 					break;
2137 				case ALIGN_RIGHT:
2138 					posx1 = getX()-getWidth()/2;
2139 					break;
2140 				default:
2141 					posx1 = getX()+getWidth()/2;
2142 					break;
2143 			}
2144 
2145 			switch (valign)
2146 			{
2147 				case VALIGN_CENTER:
2148 					posy1 = getY();
2149 					break;
2150 				case VALIGN_BOTTOM:
2151 					posy1 = getY()-getHeight()/2;
2152 					break;
2153 				default:
2154 					posy1 = getY()+getHeight()/2;
2155 					break;
2156 			}
2157 
2158 		} else {
2159 			posx1 = getX();
2160 			posy1 = getY();
2161 		}
2162 
2163 
2164 		glPushMatrix();
2165 
2166 		glEnable(GL_TEXTURE_2D);
2167 
2168 
2169 		if (toDoAllEffects) {
2170 
2171 			if (flip) {
2172 				float aux;
2173 				aux = cornerx1;
2174 				cornerx1 = cornerx2;
2175 				cornerx2 = aux;
2176 			}
2177 
2178 			if (flop) {
2179 				float aux;
2180 				aux = cornery1;
2181 				cornery1 = cornery2;
2182 				cornery2 = aux;
2183 			}
2184 
2185 			glColor4ub(red,green,blue,alpha);
2186 
2187 			glTranslatef(posx1, posy1, 0);
2188 
2189 			//glScalef(currentScaleX,currentScaleY,1.0);
2190 
2191 			if (rot!=0)
2192 				glRotatef(rot, rotX, rotY, rotZ);
2193 
2194 			// alpha
2195 			// fade in
2196 
2197 			if (cyclesFadeIn>0) {
2198 				cyclesFadeIn--;
2199 				alpha = (255/cyclesFadeInTotal) * (cyclesFadeInTotal - cyclesFadeIn);
2200 				if (cyclesFadeIn == 0) {
2201 					alpha = 255;
2202 				}
2203 			}
2204 
2205 			if (cyclesFadeOut>0) {
2206 				cyclesFadeOut--;
2207 				alpha = 255 - ((255/cyclesFadeOutTotal) * (cyclesFadeOutTotal - cyclesFadeOut));
2208 				if (cyclesFadeOut == 0) {
2209 					alpha = 0;
2210 				}
2211 			}
2212 
2213 		} else {
2214 
2215 			glColor4ub(red,green,blue,alpha);
2216 
2217 			glTranslatef(posx1, posy1, 0);
2218 
2219 			if (rot!=0)
2220 				glRotatef(rot, rotX, rotY, rotZ);
2221 
2222 		}
2223 
2224 		float x1 = cornerx1 + (perspectiveX1*currentScaleX);
2225 		float y1 = cornery1 + (perspectiveY1*currentScaleY);
2226 		float x2 = cornerx2 + (perspectiveX2*currentScaleX);
2227 		float y2 = cornery1 + (perspectiveY2*currentScaleY);
2228 		float x3 = cornerx1 + (perspectiveX3*currentScaleX);
2229 		float y3 = cornery2 + (perspectiveY3*currentScaleY);
2230 		float x4 = cornerx2 + (perspectiveX4*currentScaleX);
2231 		float y4 = cornery2 + (perspectiveY4*currentScaleY);
2232 
2233 		glBindTexture(GL_TEXTURE_2D, sprite[cFrame]->texture);
2234 
2235 		glBegin(GL_QUADS);
2236 		  glTexCoord2f(0.0f, relH);
2237 		  glVertex2f(x3, y3);
2238 		  glTexCoord2f(relW, relH);
2239 		  glVertex2f(x4, y4);
2240 		  glTexCoord2f(relW, 0.0f);
2241 		  glVertex2f(x2, y2);
2242 		  glTexCoord2f(0.0f, 0.0f);
2243 		  glVertex2f(x1, y1);
2244 		glEnd();
2245 
2246 		//glDisable(GL_BLEND);
2247 		glDisable(GL_TEXTURE_2D);
2248 
2249 		currentScaleX = auxCSX;
2250 		currentScaleY = auxCSY;
2251 
2252 		glColor4ub(255,255,255,255);
2253 
2254 		glPopMatrix();
2255 
2256 	}
2257 
2258 	/*****************************
2259 	**
2260 	** CLASS ANIMATEDELEMENT
2261 	**
2262 	******************************/
2263 
AnimatedElement()2264 	AnimatedElement::AnimatedElement()  : Element () {
2265 		currentAnimation = -1;
2266 		defaultAnimation = -1;
2267 		numberOfTimes = -1;
2268 		countNumberOfTimes = 0;
2269 	}
2270 
~AnimatedElement()2271 	AnimatedElement::~AnimatedElement() {
2272 		unLoad();
2273 	}
2274 
getNextFrame()2275 	int AnimatedElement::getNextFrame () {
2276 		int af = 0;
2277 		int ani = -1;
2278 		if (currentAnimation == -1) {
2279 			if (defaultAnimation == -1) {
2280 				af = 0;
2281 			} else {
2282 				ani = defaultAnimation;
2283 			}
2284 		} else {
2285 			ani = currentAnimation;
2286 		}
2287 
2288 		if (ani == -1) {
2289 			af = 0;
2290 		} else {
2291 
2292 			if ( (animations[ani].getIndexFrame()==animations[ani].lastFrame())
2293 					&& (animations[ani].getCycleInFrame()==animations[ani].getCyclesBetweenFrames()-1) ) {
2294 				if (numberOfTimes>=0) {
2295 					if (countNumberOfTimes>=numberOfTimes) {
2296 						animations[ani].stop();
2297 					} else {
2298 						countNumberOfTimes++;
2299 					}
2300 				} else {
2301 					if ((int)nextsAnimations.size()>0) {
2302 						currentAnimation = nextsAnimations[0].animation;
2303 						numberOfTimes = nextsAnimations[0].numberOfTimes;
2304 						countNumberOfTimes = 0;
2305 						animations[currentAnimation].start();
2306 						nextsAnimations.erase(nextsAnimations.begin());
2307 						return animations[currentAnimation].getFrame();
2308 					}
2309 				}
2310 			}
2311 			af = animations[ani].getFrame();
2312 		}
2313 		return af;
2314 	}
2315 
getAnimation()2316 	Animation* AnimatedElement::getAnimation () {
2317 		if (currentAnimation == -1) {
2318 			if (defaultAnimation == -1) {
2319 				return NULL;
2320 			} else {
2321 				return &animations[defaultAnimation];
2322 			}
2323 		} else {
2324 			return &animations[currentAnimation];
2325 		}
2326 		return NULL;
2327 	}
2328 
getAnimation(string name)2329 	Animation* AnimatedElement::getAnimation (string name) {
2330 		int i;
2331 		for (i=0; i<(int)animations.size(); i++) {
2332 			if ( animations[i].name == name ) {
2333 				return &animations[i];
2334 			}
2335 		}
2336 		return NULL;
2337 	}
2338 
getCurrentFrame()2339 	int AnimatedElement::getCurrentFrame () {
2340 		int af;
2341 		if (currentAnimation == -1) {
2342 			if (defaultAnimation == -1) {
2343 				af = 0;
2344 			} else {
2345 				af = animations[defaultAnimation].getCurrentFrame();
2346 			}
2347 		} else {
2348 			af = animations[currentAnimation].getCurrentFrame();
2349 		}
2350 		return af;
2351 	}
2352 
addAnimation(Animation a)2353 	void AnimatedElement::addAnimation (Animation a) {
2354 		if (defaultAnimation == -1) defaultAnimation = 0;
2355 		animations.push_back(a);
2356 	}
2357 
removeAnimation(string name)2358 	void AnimatedElement::removeAnimation (string name) {
2359 		int i;
2360 		for (i=0; i<(int)animations.size(); i++) {
2361 			if ( animations[i].name == name ) {
2362 				animations.erase(animations.begin()+i);
2363 				return;
2364 			}
2365 		}
2366 	}
2367 
setAnimation(string name,int nt)2368 	bool AnimatedElement::setAnimation (string name, int nt) {
2369         if (existAnimation(name)) {
2370             if (currentAnimation>0) {
2371     		   if (!animations[currentAnimation].playing()) setForceAnimation(name, nt);
2372             }
2373 
2374     		int i;
2375     		for (i=0; i<(int)animations.size(); i++) {
2376     			if ( animations[i].name == name ) {
2377     				NextAnimation na;
2378     				na.animation = i;
2379     				na.numberOfTimes = nt-1;
2380     				nextsAnimations.push_back(na);
2381     				return true;
2382     			}
2383     		}
2384         }
2385 		return false;
2386 	}
2387 
existAnimation(string name)2388 	bool AnimatedElement::existAnimation (string name) {
2389 		int i;
2390 		for (i=0; i<(int)animations.size(); i++) {
2391 			if ( animations[i].name == name ) {
2392 				return true;
2393 			}
2394 		}
2395 		return false;
2396 	}
2397 
setForceAnimation(string name,int nt)2398 	bool AnimatedElement::setForceAnimation (string name, int nt) {
2399         if (existAnimation(name)) {
2400     		int i;
2401     		for (i=0; i<(int)animations.size(); i++) {
2402     			if ( animations[i].name == name ) {
2403     				numberOfTimes = nt-1;
2404     				countNumberOfTimes = 0;
2405     				currentAnimation = i;
2406     				animations[currentAnimation].start();
2407     				nextsAnimations.clear();
2408     				return true;
2409     			}
2410     		}
2411         }
2412 		return false;
2413 	}
2414 
setDefaultAnimation(string name)2415 	bool AnimatedElement::setDefaultAnimation (string name) {
2416 		int i;
2417 		for (i=0; i<(int)animations.size(); i++) {
2418 			if ( animations[i].name == name ) {
2419 				defaultAnimation = i;
2420 				return true;
2421 			}
2422 		}
2423 		return false;
2424 	}
2425 
draw()2426 	void AnimatedElement::draw () {
2427 		if ((int)sprite.size()>0) {
2428 			cFrame = getNextFrame();
2429 			move();
2430 			transforms();
2431 			paintSprite();
2432 		}
2433 	}
2434 
unLoad()2435 	void AnimatedElement::unLoad() {
2436 		int i;
2437 		for (i=0; i<(int)sprite.size(); i++)
2438 			delete sprite[i];
2439 
2440 		animations.clear();
2441 		nextsAnimations.clear();
2442 		parameters.clear();
2443 		sprite.clear();
2444 	}
2445 
2446 	/*****************************
2447 	**
2448 	** CLASS ElementDnD
2449 	**
2450 	******************************/
2451 
ElementDnD()2452 	ElementDnD::ElementDnD()  : Element () {
2453 		toDoDnd = true;
2454 		isDnd = false;
2455 		isRollOver = false;
2456 		mouseX = 0;
2457 		mouseY = 0;
2458 	}
2459 
~ElementDnD()2460 	ElementDnD::~ElementDnD() {
2461 		unLoad();
2462 	}
2463 
onOver()2464 	void ElementDnD::onOver()
2465 	{
2466 		if (isOnMouseOver() && !isRollOver) {
2467 			isRollOver = true;
2468 		}
2469 		if (!isOnMouseOver() && isRollOver) {
2470 			isRollOver = false;
2471 		}
2472 		if (toDoDnd && isDnd) {
2473 			int cMouseX, cMouseY;
2474 			SDL_GetMouseState(&cMouseX, &cMouseY);
2475 			cMouseX -= (int)getDisplacementInXByGroups();
2476 			cMouseY -= (int)getDisplacementInYByGroups();
2477 			addX(cMouseX - mouseX);
2478 			addY(cMouseY - mouseY);
2479 			mouseX = cMouseX;
2480 			mouseY = cMouseY;
2481 		}
2482 
2483 	}
2484 
isOnMouseOver()2485 	bool ElementDnD::isOnMouseOver()
2486 	{
2487 
2488 		int mouse_x, mouse_y;
2489 
2490 		SDL_PumpEvents();
2491 
2492 		SDL_GetMouseState(&mouse_x, &mouse_y);
2493 
2494 		Bounds b = getBounds();
2495 
2496 		if ( (mouse_x > b.x1) && (mouse_x < b.x2) &&
2497 			(mouse_y > b.y1) && (mouse_y < b.y2) ) {
2498 			return true;
2499 		}
2500 
2501 		return false;
2502 
2503 	}
2504 
startDrag()2505 	void ElementDnD::startDrag () {
2506 		setAlpha(100);
2507 		isDnd = true;
2508 		SDL_GetMouseState(&mouseX, &mouseY);
2509 		mouseX -= (int)getDisplacementInXByGroups();
2510 		mouseY -= (int)getDisplacementInYByGroups();
2511 	}
2512 
drop()2513 	void ElementDnD::drop () {
2514 		setAlpha(255);
2515 		isDnd = false;
2516 	}
2517 
2518 	/*****************************
2519 	**
2520 	** CLASS Element_AnimatedGroup
2521 	**
2522 	******************************/
2523 
Element_AnimatedGroup()2524 	Element_AnimatedGroup::Element_AnimatedGroup() : Element() {
2525 		offsetX = 0.0;
2526 		offsetX = 0.0;
2527 	}
2528 
~Element_AnimatedGroup()2529 	Element_AnimatedGroup::~Element_AnimatedGroup() {
2530 		unLoad();
2531 	}
2532 
2533 	/*****************************
2534 	**
2535 	** CLASS ANIMATEDGROUP
2536 	**
2537 	******************************/
2538 
AnimatedGroup()2539 	AnimatedGroup::AnimatedGroup() {
2540 		cols = 3;
2541 		rows = -1;
2542 		indexz = 0;
2543 		posX = 0.0;
2544 		posY = 0.0;
2545 		width = 0;
2546 		height = 0;
2547 
2548 		reverse = false;
2549 
2550 		isMovementNormal = false;
2551 		isMovementSmooth = false;
2552 		isMovementFlexible = false;
2553 
2554 		xMovement = 0;
2555         yMovement = 0;
2556 		mlMovement = 0;
2557 
2558 		cyclesChangeElement = -1;
2559 
2560 		currentElement = 0;
2561 		cycles = 0;
2562 	}
2563 
~AnimatedGroup()2564 	AnimatedGroup::~AnimatedGroup() {
2565 		unLoad();
2566 	}
2567 
addElement(Element_AnimatedGroup * el)2568 	void AnimatedGroup::addElement(Element_AnimatedGroup *el) {
2569 		elements.push_back(el);
2570 	}
2571 
organizeElements()2572 	void AnimatedGroup::organizeElements () {
2573         if (cols==-1) {
2574             cols = ((int)elements.size()/rows)+(elements.size()%rows);
2575         }
2576 
2577         if (rows==-1) {
2578             rows = ((int)elements.size()/cols)+(elements.size()%cols);
2579         }
2580 
2581 		for (int i=0; i<(int)elements.size(); i++) {
2582 			//int r = elements.size()/rows;
2583 			int c = i%cols;
2584 			int h=0, w=0;
2585 			float x=0.0, y=0.0;
2586 			if (i>0) {
2587 				h = elements[i-1]->getHeight();
2588 				w = elements[i-1]->getWidth();
2589 				x = elements[i-1]->getX();
2590 				y = elements[i-1]->getY();
2591 			}
2592 			if (c==0) {
2593 				elements[i]->setOffSetX(0);
2594 				elements[i]->setOffSetY(y+h);
2595 			} else {
2596 				elements[i]->setOffSetX(x+w);
2597 				elements[i]->setOffSetY(y);
2598 			}
2599 
2600 		}
2601 	}
2602 
setVelocitySmooth(int t)2603 	void AnimatedGroup::setVelocitySmooth (int t) {
2604 		int i;
2605 		for (i=0; i<(int)elements.size(); i++) {
2606 			elements[i]->setVelocitySmooth(t);
2607 		}
2608 	}
2609 
setVelocityFlexible(int t)2610 	void AnimatedGroup::setVelocityFlexible (int t) {
2611 		int i;
2612 		for (i=0; i<(int)elements.size(); i++) {
2613 			elements[i]->setVelocityFlexible(t);
2614 		}
2615 	}
2616 
setText(string text,string font)2617 	void AnimatedGroup::setText (string text, string font) {
2618 		int i;
2619 
2620 		for (i=0; i<(int)text.length(); i++) {
2621 			Element_AnimatedGroup* el = new Element_AnimatedGroup();
2622 			el->addFrameText(font, text.substr(i, 1), ALIGN_CENTER);
2623 			addElement(el);
2624 		}
2625 
2626 	}
2627 
setMovementNormal(float x,float y,int ml,int waitMl)2628 	void AnimatedGroup::setMovementNormal(float x, float y, int ml, int waitMl) {
2629 		isMovementNormal = true;
2630 		isMovementSmooth = false;
2631 		isMovementFlexible = false;
2632 		xMovement = x;
2633         yMovement = y;
2634 		mlMovement = ml;
2635 		cyclesChangeElement = Converter::GetInstance()->ml2cycles(waitMl);
2636 		if (reverse) currentElement = (int)elements.size()-1; else currentElement = 0;
2637 		cycles = -1;
2638     }
2639 
setMovementSmooth(float x,float y,int waitMl)2640 	void AnimatedGroup::setMovementSmooth(float x, float y, int waitMl) {
2641 		isMovementNormal = false;
2642 		isMovementSmooth = true;
2643 		isMovementFlexible = false;
2644 		xMovement = x;
2645         yMovement = y;
2646 		cyclesChangeElement = Converter::GetInstance()->ml2cycles(waitMl);
2647 		if (reverse) currentElement = (int)elements.size()-1; else currentElement = 0;
2648 		cycles = -1;
2649     }
2650 
setMovementFlexible(float x,float y,int waitMl)2651 	void AnimatedGroup::setMovementFlexible(float x, float y, int waitMl) {
2652 		isMovementNormal = false;
2653 		isMovementSmooth = false;
2654 		isMovementFlexible = true;
2655 		xMovement = x;
2656         yMovement = y;
2657 		cyclesChangeElement = Converter::GetInstance()->ml2cycles(waitMl);
2658 		if (reverse) currentElement = (int)elements.size()-1; else currentElement = 0;
2659 		cycles = -1;
2660     }
2661 
draw()2662 	void AnimatedGroup::draw () {
2663          cycles ++;
2664          if (isMovementNormal || isMovementSmooth || isMovementFlexible) {
2665              if ( ( (currentElement>(int)elements.size()-1) && (!reverse) )
2666                   || ( (currentElement<0) && (reverse) )  ) {
2667         		isMovementNormal = false;
2668         		isMovementSmooth = false;
2669         		isMovementFlexible = false;
2670         		xMovement = 0;
2671                 yMovement = 0;
2672         		mlMovement = 0;
2673         		cyclesChangeElement = -1;
2674         		currentElement = 0;
2675              } else {
2676                 if (cycles%cyclesChangeElement==0) {
2677                    if (isMovementNormal) elements[currentElement]->setMovementNormal(xMovement+elements[currentElement]->getOffSetX(), yMovement+elements[currentElement]->getOffSetY(), mlMovement);
2678                    if (isMovementSmooth) elements[currentElement]->setMovementSmooth(xMovement+elements[currentElement]->getOffSetX(), yMovement+elements[currentElement]->getOffSetY());
2679                    if (isMovementFlexible) elements[currentElement]->setMovementFlexible(xMovement+elements[currentElement]->getOffSetX(), yMovement+elements[currentElement]->getOffSetY());
2680                    if (reverse) currentElement--; else currentElement++;
2681                 }
2682              }
2683          }
2684          paintSprites ();
2685 	}
2686 
paintSprites()2687 	void AnimatedGroup::paintSprites () {
2688 		int x, y;
2689 
2690 		for (y=0; y<rows; y++) {
2691 			for (x=0; x<cols; x++) {
2692 				int item = y*cols+x;
2693 				if (item < (int)elements.size()) {
2694 					elements[item]->draw();
2695 				}
2696 			}
2697 		}
2698 
2699 	}
2700 
setX(float x)2701 	void AnimatedGroup::setX(float x) {
2702 		posX = x;
2703 		int i;
2704 		for (i=0; i<(int)elements.size(); i++) {
2705 			elements[i]->setX(x);
2706 			elements[i]->setOffSetX();
2707 		}
2708 	}
2709 
setY(float y)2710 	void AnimatedGroup::setY(float y) {
2711 		posY = y;
2712 		int i;
2713 		for (i=0; i<(int)elements.size(); i++) {
2714 			elements[i]->setY(y);
2715 			elements[i]->setOffSetY();
2716 		}
2717 	}
2718 
unLoad()2719 	void AnimatedGroup::unLoad() {
2720 		int i;
2721 		for (i=0; i<(int)elements.size(); i++) {
2722 			delete elements[i];
2723 		}
2724 	}
2725 
2726 	/*****************************
2727 	**
2728 	** CLASS SLIDE
2729 	**
2730 	******************************/
2731 
Slide()2732 	Slide::Slide()  : Element () {
2733         cyclesNextFrame = -1;
2734 		nextFrame = -1;
2735 		degrees = 0;
2736 		rotX = 0.0f;
2737 		rotY = 1.0f;
2738 		rotZ = 0.0f;
2739 		setAlign(ALIGN_CENTER);
2740 		setVAlign(VALIGN_CENTER);
2741 		changingFrame = false;
2742 		degreesByFrame = 10;
2743 		degreesToDoChange = 90;
2744 		typeSlide = TYPESLIDE_FADE;
2745 
2746 		mlFade = 1000;
2747 		stopped = false;
2748 
2749 	}
2750 
~Slide()2751 	Slide::~Slide() {
2752 		unLoad();
2753 	}
2754 
setCurrentFrame(int c)2755 	void Slide::setCurrentFrame(int c) {
2756 		if ((int)sprite.size()>1) {
2757 			if (c<(int)sprite.size()) {
2758 				nextFrame = c;
2759 				if ( typeSlide == TYPESLIDE_FADE ) setFadeOut(mlFade);
2760 			}
2761 		}
2762 	}
2763 
draw()2764 	void Slide::draw () {
2765 		if ((int)sprite.size()>0) {
2766 			move();
2767 			transforms();
2768 			// movement slide
2769 			if ((int)sprite.size()>1) {
2770 				if (nextFrame!=-1) {
2771 
2772 					if ( typeSlide == TYPESLIDE_FADE ) {
2773 
2774 						if (getAlpha()<10) {
2775 							cFrame = nextFrame;
2776 							nextFrame = -1;
2777 							setFadeIn(mlFade);
2778 						}
2779 
2780 					} else if ( typeSlide ==TYPESLIDE_ROTATE ) {
2781 
2782 						degrees+=degreesByFrame;
2783 						if ( (degrees>=degreesToDoChange) && (!changingFrame) ) {
2784 							degrees = 270;
2785 							cFrame = nextFrame;
2786 							changingFrame = true;
2787 						}
2788 						if (degrees>=360) {
2789 							nextFrame = -1;
2790 							degrees = 0;
2791 							changingFrame = false;
2792 						}
2793 						rot = degrees;
2794 
2795 					} else {
2796 						cFrame = nextFrame;
2797 						nextFrame = -1;
2798 					}
2799 
2800 				}
2801 			}
2802 			paintSprite();
2803 
2804 			if (cyclesNextFrame>0) {
2805 				if (cycle%cyclesNextFrame==0) {
2806 					if (!stopped) setNextFrame();
2807 				}
2808 			}
2809 		}
2810 	}
2811 
2812 	/*****************************
2813 	**
2814 	** CLASS ChronometerElement
2815 	**
2816 	******************************/
2817 
ChronometerElement(string n,string f)2818 	ChronometerElement::ChronometerElement(string n, string f)  : Group () {
2819 		name = n;
2820 		Chronometer::GetInstance()->setTime(name);
2821 		stopped = true;
2822 		font = f;
2823         pastSeconds = 0;
2824 		indexz = 0;
2825 
2826 		minute0 = new Slide();
2827 		minute0->setTypeSlide(TYPESLIDE_ROTATE);
2828 		this->addElement((Element*)minute0);
2829 
2830 		minute1 = new Slide();
2831 		minute1->setTypeSlide(TYPESLIDE_ROTATE);
2832 		this->addElement((Element*)minute1);
2833 
2834 		second0 = new Slide();
2835 		second0->setTypeSlide(TYPESLIDE_ROTATE);
2836 		this->addElement((Element*)second0);
2837 
2838 		second1 = new Slide();
2839 		second1->setTypeSlide(TYPESLIDE_ROTATE);
2840 		this->addElement((Element*)second1);
2841 
2842 		char tmp[4];
2843 		for (int i=0; i<10; i++) {
2844 			sprintf(tmp, "%d", i);
2845 			minute0->addFrameText(font, tmp, ALIGN_LEFT);
2846 			minute1->addFrameText(font, tmp, ALIGN_LEFT);
2847 			second0->addFrameText(font, tmp, ALIGN_LEFT);
2848 			second1->addFrameText(font, tmp, ALIGN_LEFT);
2849 		}
2850 
2851 		points = new Element();
2852 		points->setAlign(ALIGN_CENTER);
2853 		points->setVAlign(VALIGN_CENTER);
2854 		points->addFrameText(font, ":", ALIGN_LEFT);
2855 		this->addElement(points);
2856 
2857 	}
2858 
~ChronometerElement()2859 	ChronometerElement::~ChronometerElement () {
2860 		unLoad();
2861 	}
2862 
setTime()2863 	void ChronometerElement::setTime() {
2864 		int minutes = 0;
2865 		int seconds = 0;
2866 		if (pastSeconds<60) {
2867 			seconds = pastSeconds;
2868 		} else {
2869 			minutes = pastSeconds/60;
2870 			seconds = pastSeconds%60;
2871 		}
2872 
2873 		int frMinute0 = minutes/10;
2874 		if (frMinute0!=minute0->getCurrentFrame()) minute0->setCurrentFrame(frMinute0);
2875 
2876 		minute1->setX(minute0->getWidth()+2);
2877 		int frMinute1 = minutes%10;
2878 		if (frMinute1!=minute1->getCurrentFrame()) minute1->setCurrentFrame(frMinute1);
2879 
2880 		points->setX(minute1->getXWithoutDisplacementByGroups()+minute1->getWidth()+2);
2881 
2882 		second0->setX(points->getXWithoutDisplacementByGroups()+points->getWidth()+2);
2883 		int frSeconds0 = seconds/10;
2884 		if (frSeconds0!=second0->getCurrentFrame()) second0->setCurrentFrame(frSeconds0);
2885 
2886 		second1->setX(second0->getXWithoutDisplacementByGroups()+second0->getWidth()+2);
2887 		int frSeconds1 = seconds%10;
2888 		if (frSeconds1!=second1->getCurrentFrame()) second1->setCurrentFrame(frSeconds1);
2889 
2890 	}
2891 
draw()2892 	void ChronometerElement::draw() {
2893 		if (!stopped) {
2894 			if (Chronometer::GetInstance()->getTime(name) >= 1000) {
2895 				Chronometer::GetInstance()->setTime(name);
2896 				addSecond();
2897 			}
2898 		}
2899 		minute0->draw();
2900 		minute1->draw();
2901 		points->draw();
2902 		second0->draw();
2903 		second1->draw();
2904 	}
2905 
unLoad()2906 	void ChronometerElement::unLoad() {
2907 		delete minute0;
2908 		delete minute1;
2909 		delete points;
2910 		delete second0;
2911 		delete second1;
2912 	}
2913 
2914 	/*****************************
2915 	**
2916 	** CLASS ProgressBar
2917 	**
2918 	******************************/
2919 
ProgressBar(int tc,int w,int h,int r,int g,int b)2920 	ProgressBar::ProgressBar(int tc, int w, int h, int r, int g, int b) {
2921 
2922 		//Frame frBar;
2923 
2924 		width = w;
2925 		height = h;
2926 
2927 		bar = new Element();
2928 		//frBar.loadGLSurface(Primitives::GetInstance()->rectangle(w, h, r, g, b));
2929 		bar->addFrameSurface(Primitives::GetInstance()->rectangle(w, h, r, g, b));
2930 		bar->setAlign(ALIGN_LEFT);
2931 		bar->setVAlign(VALIGN_BOTTOM);
2932 
2933 		txt = new Element();
2934 		txt->setAlign(ALIGN_CENTER);
2935 		txt->setVAlign(VALIGN_TOP);
2936 
2937 		bg = new Element();
2938 		bg->setAlign(ALIGN_CENTER);
2939 		bg->setVAlign(VALIGN_CENTER);
2940 		bg->setX(World::width/2);
2941 		bg->setY(World::height/2);
2942 
2943 		bg_bar = new Element();
2944 		bg_bar->setAlign(ALIGN_CENTER);
2945 		bg_bar->setVAlign(VALIGN_CENTER);
2946 
2947 		total = tc;
2948 		status = 0;
2949 
2950 		posBarX = World::width/2;
2951         posBarY = World::height/2;
2952 
2953 		setPositionBar(posBarX, posBarY);
2954 
2955 	}
2956 
~ProgressBar()2957 	ProgressBar::~ProgressBar () {
2958 		unLoad();
2959 	}
2960 
setPositionBar(int posX,int posY)2961 	void ProgressBar::setPositionBar(int posX, int posY) {
2962         posBarX = posX;
2963         posBarY = posY;
2964 		bar->setX(posX-(width/2));
2965 		bar->setY(posY-10);
2966         bg_bar->setX(bar->getX()+(width/2));
2967 		bg_bar->setY(bar->getY()-(height/2)+1);
2968 		txt->setX(posX);
2969 		txt->setY(posY+10);
2970 	}
2971 
setText(string font,string t)2972 	void ProgressBar::setText(string font, string t) {
2973 		Debug::GetInstance()->writeText(t);
2974 		if (txt->getFrames()==0) {
2975 			txt->addFrameText(font, t, ALIGN_CENTER);
2976 		} else {
2977 			txt->changeFrameText(0, font, t, ALIGN_CENTER);
2978 		}
2979 	}
2980 
setBg(string file)2981 	void ProgressBar::setBg(string file) {
2982 		if (bg->getFrames()==0) {
2983 			bg->addFrameFile(file);
2984 		} else {
2985 			bg->changeFrameFile(0, file);
2986 		}
2987 	}
2988 
setBgBar(string file)2989 	void ProgressBar::setBgBar(string file) {
2990 		if (bg_bar->getFrames()==0) {
2991 			bg_bar->addFrameFile(file);
2992 		} else {
2993 			bg_bar->changeFrameFile(0, file);
2994 		}
2995 	}
2996 
draw()2997 	void ProgressBar::draw() {
2998 		addStatus();
2999 		bar->setCurrentScaleX((float)status/(float)total);
3000 
3001 		glClear(GL_COLOR_BUFFER_BIT);
3002 		glLoadIdentity();
3003 
3004 		glEnable(GL_BLEND);
3005 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3006 
3007 		if (bg->getFrames()>0) {
3008 			bg->draw();
3009 		}
3010 
3011 		if (bg_bar->getFrames()>0) {
3012 			bg_bar->draw();
3013 		}
3014 
3015 		bar->draw();
3016 
3017 		if (txt->getFrames()>0) {
3018 			txt->draw();
3019 		}
3020 
3021 		glDisable(GL_BLEND);
3022 
3023 		SDL_GL_SwapBuffers();
3024 
3025 	}
3026 
unLoad()3027 	void ProgressBar::unLoad() {
3028 		delete bar;
3029 		delete bg;
3030 		delete txt;
3031 		delete bg_bar;
3032 		Debug::GetInstance()->writeText("Cargado todo el escenario");
3033 	}
3034 
3035 	/*****************************
3036 	**
3037 	** CLASS ListView
3038 	**
3039 	******************************/
3040 
CoverFlow()3041 	CoverFlow::CoverFlow() : Group () {
3042     	beginItem = 0;
3043     	itemFadeOut = -1;
3044     	itemSeparate = 0;
3045 		index = 0;
3046 		indexz = 0;
3047 
3048 		width = World::width;
3049 		widthItem = 200;
3050 
3051     	itemsVisible = 5;
3052     	cursor = 0;
3053 
3054     	timeChangeItem = 300;
3055 
3056     	separateGrid = 80;
3057     	drawButtons = false;
3058 	}
3059 
~CoverFlow()3060 	CoverFlow::~CoverFlow() {
3061 		unLoad();
3062 	}
3063 
inicialize()3064 	void CoverFlow::inicialize() {
3065     	beginItem = 0;
3066     	itemFadeOut = -1;
3067     	itemSeparate = 0;
3068 		index = 0;
3069 
3070 		for (int i=0; i<(int)data.size(); i++) {
3071 			delete data[i];
3072 		}
3073 		data.clear();
3074     }
3075 
lastItem()3076 	int CoverFlow::lastItem() {
3077 		if (beginItem+itemsVisible<(int)data.size()) {
3078 			return beginItem+itemsVisible;
3079 		} else {
3080 			return (int)data.size();
3081 		}
3082 	}
3083 
setIndex(int i)3084     void CoverFlow::setIndex(int i) {
3085         int oldIndex = index;
3086 		index = i;
3087 
3088 		if ((int)data.size()>0) {
3089    			beginItem = index - (itemsVisible/2);
3090         	itemFadeOut = -1;
3091         	itemSeparate = 0;
3092 
3093     		data[index]->setMovementNormalX((float)width/2, timeChangeItem);
3094     		data[index]->setScaleGL(1, timeChangeItem);
3095 			data[index]->removeRGB();
3096 
3097     		// right
3098     		for (int i=1; i<=(itemsVisible/2); i++) {
3099     			int value = index + i;
3100     			if ( (value>=0) && (value<(int)data.size()) ) {
3101                     if ( (oldIndex<index) && i==(itemsVisible/2) ) {
3102                          data[value]->setX(((float)width/2) + ((float)widthItem/3) +((i+1)*separateGrid));
3103                          data[value]->setCurrentScale(0);
3104                     }
3105     				data[value]->setMovementNormalX(((float)width/2) + ((float)widthItem/3) +(i*separateGrid), timeChangeItem);
3106     				data[value]->setScaleGL(1.0-(i*0.3), timeChangeItem);
3107 					data[value]->setRGB(255-(i*100), 255-(i*100), 255-(i*100));
3108     			}
3109     		}
3110 
3111             // left
3112     		for (int i=1; i<=(itemsVisible/2); i++) {
3113     			int value = index - i;
3114     			if (value>=0) {
3115                     if ( (oldIndex>index) && i==(itemsVisible/2) ) {
3116                          data[value]->setX(((float)width/2) - ((float)widthItem/3) -((i+1)*separateGrid));
3117                          data[value]->setCurrentScale(0);
3118                     }
3119     				data[value]->setMovementNormalX(((float)width/2) - ((float)widthItem/3) -(i*separateGrid), timeChangeItem);
3120     				data[value]->setScaleGL(1.0-(i*0.3), timeChangeItem);
3121 					data[value]->setRGB(255-(i*100), 255-(i*100), 255-(i*100));
3122     			}
3123     		}
3124 
3125     		/*for (int i=firtsItem(); i<lastItem(); i++) {
3126     			if ( (i!=index) && (i>=0) ) data[i]->setCurrentScale(0.5);
3127     		}*/
3128 
3129     		verifySensitiveButtons();
3130        }
3131 
3132     }
3133 
3134 
startPosition()3135     void CoverFlow::startPosition() {
3136 		index = 0;
3137 
3138 		if ((int)data.size()>0) {
3139    			beginItem = index - (itemsVisible/2);
3140         	itemFadeOut = -1;
3141         	itemSeparate = 0;
3142 
3143     		data[index]->setX(width/2);
3144     		data[index]->setCurrentScale(1);
3145 
3146     		for (int i=1; i<=(itemsVisible/2); i++) {
3147     			int value = index + i;
3148     			if ( (value>=0) && (value<(int)data.size()) ) {
3149     				data[value]->setX(((float)width/2) + ((float)widthItem/3) +(i*separateGrid));
3150 					data[value]->setCurrentScale(1.0-(i*0.3));
3151 					data[value]->setRGB(255-(i*100), 255-(i*100), 255-(i*100));
3152     			}
3153     		}
3154 
3155     		verifySensitiveButtons();
3156        }
3157 
3158     }
3159 
setButtons(Button * buttom_left,Button * buttom_right,int separateX,int separateY)3160     void CoverFlow::setButtons(Button *buttom_left, Button *buttom_right, int separateX, int separateY) {
3161          bLeft = buttom_left;
3162          bRight = buttom_right;
3163          this->addElement(bLeft);
3164          this->addElement(bRight);
3165 
3166 		 bLeft->setX(5-separateX);
3167 		 bRight->setX(width-bRight->getWidth()-5+separateX);
3168 
3169 		 bLeft->setY(separateY);
3170 		 bRight->setY(separateY);
3171 
3172          drawButtons = true;
3173     }
3174 
verifySensitiveButtons()3175     void CoverFlow::verifySensitiveButtons() {
3176          if (drawButtons) {
3177               if ( (index>0) ) {
3178                    bLeft->setSensitive(true);
3179               } else {
3180                    bLeft->setSensitive(false);
3181               }
3182 
3183               if ( (index<(int)data.size()-1) ) {
3184                    bRight->setSensitive(true);
3185               } else {
3186                    bRight->setSensitive(false);
3187               }
3188          }
3189     }
3190 
verifyClickButtons()3191     void CoverFlow::verifyClickButtons() {
3192          if (drawButtons) {
3193         	if (bLeft->isOnMouseOver()) {
3194 				if (bLeft->getSoundClick()!="") Sounds::GetInstance()->getSound(bLeft->getSoundClick())->play(-1, 0);
3195         		previousIndex();
3196         	}
3197         	if (bRight->isOnMouseOver()) {
3198 				if (bRight->getSoundClick()!="") Sounds::GetInstance()->getSound(bRight->getSoundClick())->play(-1, 0);
3199         		nextIndex();
3200         	}
3201          }
3202     }
3203 
onOver()3204     void CoverFlow::onOver() {
3205          bLeft->onOver();
3206          bRight->onOver();
3207     }
3208 
draw()3209     void CoverFlow::draw() {
3210 
3211     	for (int i=firtsItem(); i<lastItem(); i++) {
3212    			if (i>=0) data[i]->draw();
3213     	}
3214 
3215         if (drawButtons) {
3216 
3217        		bLeft->draw();
3218 
3219        		bRight->draw();
3220 
3221         }
3222 
3223      }
3224 
unLoad()3225     void CoverFlow::unLoad() {
3226         if (drawButtons) {
3227             delete bLeft;
3228             delete bRight;
3229         }
3230 		for (int i=0; i<(int)data.size(); i++) {
3231 			delete data[i];
3232 		}
3233 		data.clear();
3234     }
3235 
3236 	/*****************************
3237 	**
3238 	** CLASS ListImage
3239 	**
3240 	******************************/
3241 
ListImage(int r,int c)3242 	ListImage::ListImage(int r, int c) : Group () {
3243 		indexz = 0;
3244 		cursor = 0;
3245 		rows = r;
3246 		cols = c;
3247     	rowBeginObjects = 0;
3248     	separateGrid = 80;
3249     	drawButtons = false;
3250 		bUp = NULL;
3251 		bDown = NULL;
3252 		boxImage = NULL;
3253 		drawBoxImage = false;
3254 
3255 		categories.push_back("all");
3256 
3257 		currentCategory = 0;
3258 
3259 	}
3260 
~ListImage()3261 	ListImage::~ListImage () {
3262 		unLoad();
3263 	}
3264 
nTotalRowObjects()3265 	int ListImage::nTotalRowObjects() {
3266         int count = 0;
3267         for (int i=0; i<(int)data.size(); i++) {
3268              if ( (data[i]->getParameter("category") == categories[currentCategory]) || (currentCategory==0) ) {
3269                   count++;
3270              }
3271         }
3272 
3273         int v = count/cols;
3274         if (count%cols==0) {
3275             return v;
3276         } else {
3277             return v+1;
3278         }
3279     }
3280 
add(Button * b)3281 	void ListImage::add(Button* b) {
3282 		b->setX(( ((int)data.size()%cols) *separateGrid)+(separateGrid/2));
3283     	b->setY(( ((int)data.size()/cols) *separateGrid)+(separateGrid/2));
3284     	b->setAlign(ALIGN_CENTER);
3285     	b->setVAlign(VALIGN_CENTER);
3286 		this->addElement(b);
3287     	data.push_back(b);
3288     }
3289 
setCategory(string c)3290 	void ListImage::setCategory(string c) {
3291 		for (int i=0; i<(int)categories.size(); i++) {
3292             if (categories[i]==c) {
3293                 currentCategory = i;
3294             }
3295         }
3296         rowBeginObjects = 0;
3297         orderElements();
3298     }
3299 
orderElements()3300     void ListImage::orderElements() {
3301         int count = 0;
3302         for (int i=0; i<(int)data.size(); i++) {
3303              if ( (data[i]->getParameter("category") == categories[currentCategory]) || (currentCategory==0) ) {
3304         		data[i]->setX(( (count%cols) *separateGrid)+(separateGrid/2));
3305             	data[i]->setY(( (count/cols) *separateGrid)+(separateGrid/2));
3306             	data[i]->show();
3307             	count++;
3308              }
3309         }
3310         verifyObjectsToShow();
3311     }
3312 
verifyObjectsToShow()3313 	void ListImage::verifyObjectsToShow() {
3314         int count = 0;
3315 		for (int i=0; i<(int)data.size(); i++) {
3316             if ( (data[i]->getParameter("category") == categories[currentCategory]) || (currentCategory==0) ) {
3317     			if ( (count>=rowBeginObjects*cols) && (count<(rowBeginObjects+rows)*cols) ) {
3318     				data[i]->show();
3319     			} else {
3320     				data[i]->hide();
3321     			}
3322     			count++;
3323             } else {
3324                 data[i]->hide();
3325             }
3326 		}
3327 
3328 		if (drawButtons) {
3329     		if (rowBeginObjects>0) {
3330     			bUp->setSensitive(true);
3331     		} else {
3332     			bUp->setSensitive(false);
3333     		}
3334 
3335     		if (rowBeginObjects+rows<nTotalRowObjects())  {
3336     			bDown->setSensitive(true);
3337     		} else {
3338     			bDown->setSensitive(false);
3339     		}
3340         }
3341 	}
3342 
inicialize()3343 	void ListImage::inicialize() {
3344     	rowBeginObjects = 0;
3345 
3346 		for (int i=0; i<(int)data.size(); i++) {
3347 			delete data[i];
3348 		}
3349 		data.clear();
3350     }
3351 
setButtons(Button * buttom_up,Button * buttom_down,int xSeparate,int ySeparate)3352     void ListImage::setButtons(Button *buttom_up, Button *buttom_down, int xSeparate, int ySeparate) {
3353 		if (bUp!=NULL) {
3354 			delete bUp;
3355 		}
3356 		bUp = buttom_up;
3357 		if (bDown!=NULL) {
3358 			delete bDown;
3359 		}
3360 		bDown = buttom_down;
3361 		this->addElement(bUp);
3362 		this->addElement(bDown);
3363 
3364 		bUp->setX(xSeparate);
3365 		bUp->setY(ySeparate);
3366 		bDown->setX(xSeparate);
3367 		bDown->setY((rows*separateGrid)-ySeparate);
3368 
3369 		drawButtons = true;
3370     }
3371 
setBoxImage(Element * box)3372 	void ListImage::setBoxImage (Element* box) {
3373 		boxImage = box;
3374 		this->addElement(boxImage);
3375 		drawBoxImage = true;
3376 	}
3377 
upItems()3378     void ListImage::upItems() {
3379 		if (rowBeginObjects>0) {
3380 			rowBeginObjects--;
3381 			for (int i=0; i<(int)data.size(); i++) {
3382 				data[i]->addY(110);
3383 			}
3384 			verifyObjectsToShow();
3385 		}
3386     }
3387 
downItems()3388     void ListImage::downItems() {
3389 		if (rowBeginObjects+rows<nTotalRowObjects()) {
3390 			rowBeginObjects++;
3391 			for (int i=0; i<(int)data.size(); i++) {
3392 				data[i]->addY(-110);
3393 			}
3394 			verifyObjectsToShow();
3395 		}
3396     }
3397 
verifyClickButtons()3398     void ListImage::verifyClickButtons() {
3399 		if (drawButtons) {
3400 			if (bUp->isOnMouseOver()) {
3401 				if (bUp->getSoundClick()!="") Sounds::GetInstance()->getSound(bUp->getSoundClick())->play(-1, 0);
3402 				upItems();
3403 			}
3404 			if (bDown->isOnMouseOver()) {
3405 				if (bDown->getSoundClick()!="") Sounds::GetInstance()->getSound(bDown->getSoundClick())->play(-1, 0);
3406 				downItems();
3407 			}
3408 		}
3409     }
3410 
onOver()3411     void ListImage::onOver() {
3412 		for (int i=0; i<(int)data.size(); i++) {
3413 			data[i]->onOver();
3414 		}
3415 		if (drawButtons) {
3416         	bUp->onOver();
3417         	bDown->onOver();
3418 		}
3419     }
3420 
draw()3421     void ListImage::draw() {
3422 
3423 		if (drawBoxImage) {
3424 			for (int i=0; i<cols; i++) {
3425 				for (int j=0; j<rows; j++) {
3426 					boxImage->setXY(separateGrid*i, separateGrid*j);
3427 					boxImage->draw();
3428 				}
3429 			}
3430 		}
3431 
3432 		for (int i=0; i<(int)data.size(); i++) {
3433 			data[i]->draw();
3434 		}
3435 
3436         if (drawButtons) {
3437 
3438        		bUp->draw();
3439 
3440        		bDown->draw();
3441 
3442         }
3443 
3444      }
3445 
clear()3446     void ListImage::clear() {
3447 		for (int i=0; i<(int)data.size(); i++) {
3448 			delete data[i];
3449 		}
3450 		data.clear();
3451     }
3452 
unLoad()3453     void ListImage::unLoad() {
3454         if (drawButtons) {
3455 			delete bUp;
3456             delete bDown;
3457         }
3458 		if (drawBoxImage) {
3459 			delete boxImage;
3460 		}
3461 		clear();
3462     }
3463 
3464 
3465 
3466 
3467 	/*****************************
3468 	**
3469 	** CLASS ListView
3470 	**
3471 	******************************/
3472 
ListView()3473 	ListView::ListView() : Group () {
3474     	beginItem = 0;
3475     	itemFadeOut = -1;
3476     	itemSeparate = 0;
3477 		indexz = 0;
3478 
3479 		todoMovement = true;
3480 
3481     	itemsVisible = 4;
3482     	cursor = 0;
3483 
3484     	timeChangeItem = 300;
3485 
3486     	separateGrid = 80;
3487     	drawButtons = false;
3488 
3489 		bUp = NULL;
3490 		bDown = NULL;
3491 	}
3492 
~ListView()3493 	ListView::~ListView () {
3494 		unLoad();
3495 	}
3496 
setBeginItem(int b)3497 	void ListView::setBeginItem (int b) {
3498         beginItem = b;
3499 		for (int i=0; i<(int)data.size(); i++) {
3500 			data[i]->addY(-(beginItem*separateGrid));
3501 		}
3502 		verifySensitiveButtons();
3503     }
3504 
inicialize()3505 	void ListView::inicialize() {
3506     	beginItem = 0;
3507     	itemFadeOut = -1;
3508     	itemSeparate = 0;
3509 
3510 		data.clear();
3511     }
3512 
setButtons(Button * buttom_up,Button * buttom_down,int xSeparate)3513     void ListView::setButtons(Button *buttom_up, Button *buttom_down, int xSeparate) {
3514 		if (bUp!=NULL) {
3515 			delete bUp;
3516 		}
3517 		bUp = buttom_up;
3518 		if (bDown!=NULL) {
3519 			delete bDown;
3520 		}
3521 		bDown = buttom_down;
3522 		this->addElement(bUp);
3523 		this->addElement(bDown);
3524 
3525 		bUp->setX(xSeparate);
3526 		bDown->setX(xSeparate);
3527 		bDown->setY(itemsVisible*separateGrid);
3528 
3529 		drawButtons = true;
3530     }
3531 
upItems()3532     void ListView::upItems() {
3533         bool todo = true;
3534         if (itemFadeOut!=-1) todo = false;
3535         for (int i=firtsItem(); i<lastItem(); i++) {
3536             if (data[i]->getAlpha()!=255) todo = false;
3537         }
3538         if (todo) {
3539         	if (beginItem>0) {
3540                 itemFadeOut = lastItem()-1;
3541         		beginItem--;
3542         		for (int i=0; i<(int)data.size(); i++) {
3543         			if ( i==itemFadeOut ) {
3544                         data[i]->setFadeOut(timeChangeItem);
3545                         itemSeparate = separateGrid;
3546         			} else if ( (i<firtsItem()) || (i>=lastItem()) ) {
3547         				data[i]->addY(separateGrid);
3548         			} else {
3549         				data[i]->setMovementNormal(posX, data[i]->getY()+separateGrid, timeChangeItem);
3550         			}
3551         		}
3552         		verifySensitiveButtons();
3553         	}
3554         }
3555     }
3556 
downItems()3557     void ListView::downItems() {
3558         bool todo = true;
3559         if (itemFadeOut!=-1) todo = false;
3560         for (int i=firtsItem(); i<lastItem(); i++) {
3561             if (data[i]->getAlpha()!=255) todo = false;
3562         }
3563         if (todo) {
3564         	if (beginItem+itemsVisible<(int)data.size()) {
3565                 itemFadeOut = beginItem;
3566         		beginItem++;
3567         		for (int i=0; i<(int)data.size(); i++) {
3568                     if ( i==itemFadeOut ) {
3569                         data[i]->setFadeOut(timeChangeItem);
3570                         itemSeparate = -separateGrid;
3571         			} else if ( (i<firtsItem()) || (i>=lastItem()) ) {
3572         				data[i]->addY(-separateGrid);
3573         			} else {
3574         				data[i]->setMovementNormal(posX, data[i]->getY()-separateGrid, timeChangeItem);
3575         			}
3576         		}
3577         		verifySensitiveButtons();
3578         	}
3579         }
3580     }
3581 
verifySensitiveButtons()3582     void ListView::verifySensitiveButtons() {
3583          if (drawButtons) {
3584               if ( (beginItem>0) ) {
3585                    bUp->setSensitive(true);
3586               } else {
3587                    bUp->setSensitive(false);
3588               }
3589 
3590               if ( (beginItem+itemsVisible<(int)data.size()) ) {
3591                    bDown->setSensitive(true);
3592               } else {
3593                    bDown->setSensitive(false);
3594               }
3595          }
3596     }
3597 
verifyClickButtons()3598     void ListView::verifyClickButtons() {
3599          if (drawButtons) {
3600         	if (bUp->isOnMouseOver()) {
3601 				if (bUp->getSoundClick()!="") Sounds::GetInstance()->getSound(bUp->getSoundClick())->play(-1, 0);
3602         		upItems();
3603         	}
3604         	if (bDown->isOnMouseOver()) {
3605 				if (bDown->getSoundClick()!="") Sounds::GetInstance()->getSound(bDown->getSoundClick())->play(-1, 0);
3606         		downItems();
3607         	}
3608          }
3609     }
3610 
onOver()3611     void ListView::onOver() {
3612          bUp->onOver();
3613          bDown->onOver();
3614     }
3615 
draw()3616     void ListView::draw() {
3617 
3618         if (itemFadeOut!=-1) {
3619 
3620 			data[itemFadeOut]->work();
3621 			data[itemFadeOut]->draw();
3622 
3623             if (data[itemFadeOut]->getAlpha()<=0) {
3624                 data[itemFadeOut]->addY(itemSeparate);
3625                 data[itemFadeOut]->removeAlpha();
3626                 itemFadeOut=-1;
3627                 if (itemSeparate>0) {
3628 					if (!todoMovement) {
3629 						data[firtsItem()]->addY(itemSeparate);
3630 					}
3631                     data[firtsItem()]->setFadeIn(timeChangeItem);
3632                 } else {
3633 					if (!todoMovement) {
3634 						data[lastItem()-1]->addY(itemSeparate);
3635 					}
3636                     data[lastItem()-1]->setFadeIn(timeChangeItem);
3637                 }
3638             }
3639 
3640             int b, e;
3641             if (itemSeparate>0) {
3642                  b = firtsItem()+1;
3643                  e = lastItem();
3644             } else {
3645                  b = firtsItem();
3646                  e = lastItem()-1;
3647             }
3648     		for (int i=b; i<e; i++) {
3649    				data[i]->work();
3650    				data[i]->draw();
3651     		}
3652 
3653         } else {
3654     		for (int i=firtsItem(); i<lastItem(); i++) {
3655    				data[i]->work();
3656    				data[i]->draw();
3657     		}
3658         }
3659 
3660         if (drawButtons) {
3661 
3662        		bUp->draw();
3663 
3664        		bDown->draw();
3665 
3666         }
3667 
3668      }
3669 
unLoad()3670     void ListView::unLoad() {
3671         if (drawButtons) {
3672             delete bUp;
3673             delete bDown;
3674         }
3675 		data.clear();
3676     }
3677 
3678 
3679 	/*****************************
3680 	**
3681 	** CLASS BUTTON
3682 	**
3683 	******************************/
3684 
Button()3685 	Button::Button()  : AnimatedElement () {
3686 		isRollOver = false;
3687 		scaleOut = 1.0f;
3688 		scaleOn = 1.0f;
3689 		sensitive = true;
3690 
3691 		textAlt = "";
3692 		alignAlt = ALIGN_LEFT;
3693 		soundOn = "";
3694 		soundOut = "";
3695 		soundClick = "";
3696 	}
3697 
~Button()3698 	Button::~Button() {
3699 		unLoad();
3700 	}
3701 
setSensitive(bool s)3702 	void Button::setSensitive(bool s) {
3703          sensitive = s;
3704          if (sensitive) {
3705              if (existAnimation("out")) {
3706                  setForceAnimation("out");
3707              }
3708          } else {
3709              if (existAnimation("off")) {
3710                  setForceAnimation("off");
3711              }
3712          }
3713     }
3714 
onOver()3715 	bool Button::onOver()
3716 	{
3717         if (sensitive) {
3718     		if (isOnMouseOver() && !isRollOver) {
3719 				if (textAlt!="") Cursor::GetInstance()->showText(textAlt, alignAlt, valignAlt);
3720 				if (soundOn!="") Sounds::GetInstance()->getSound(soundOn)->play(-1, 0);
3721 
3722     			isRollOver = true;
3723     			if (existAnimation("on")) {
3724     				setForceAnimation("on");
3725     			}
3726     			if (scaleOn!= scaleOut) {
3727     				setScale(getWidthOriginal()*scaleOn, getHeightOriginal()*scaleOn, 100);
3728     			}
3729 				return true;
3730     		}
3731     		if (!isOnMouseOver() && isRollOver) {
3732 				if (textAlt!="") Cursor::GetInstance()->hideText(textAlt);
3733 				if (soundOut!="") Sounds::GetInstance()->getSound(soundOut)->play(-1, 0);
3734 
3735     			setForceAnimation("out");
3736     			isRollOver = false;
3737     			if (scaleOn!= scaleOut) {
3738     				setScale(getWidthOriginal()*scaleOut, getHeightOriginal()*scaleOut, 100);
3739     			}
3740 				return true;
3741     		}
3742         }
3743 		return false;
3744 	}
3745 
isOnMouseOver()3746 	bool Button::isOnMouseOver()
3747 	{
3748 	    if (!sensitive) return false;
3749 
3750 		int mouse_x, mouse_y;
3751 
3752 		SDL_PumpEvents();
3753 
3754 		SDL_GetMouseState(&mouse_x, &mouse_y);
3755 
3756 		Bounds b = getBounds();
3757 
3758 		if ( (mouse_x > b.x1) && (mouse_x < b.x2) &&
3759 			(mouse_y > b.y1) && (mouse_y < b.y2) ) {
3760 			return true;
3761 		}
3762 
3763 		return false;
3764 
3765 	}
3766 
3767 
imageOut(SDL_Surface * sfc)3768 	void Button::imageOut(SDL_Surface* sfc)
3769 	{
3770 		this->addFrameSurface(sfc);
3771 		this->removeAnimation("out");
3772 		Animation anim;
3773 		anim.setName("out");
3774 		anim.addFrame(this->getFrames()-1);
3775 		this->addAnimation(anim);
3776 	}
3777 
imageOn(SDL_Surface * sfc)3778 	void Button::imageOn(SDL_Surface* sfc)
3779 	{
3780 		this->addFrameSurface(sfc);
3781 		this->removeAnimation("on");
3782 		Animation anim;
3783 		anim.setName("on");
3784 		anim.addFrame(this->getFrames()-1);
3785 		this->addAnimation(anim);
3786 	}
3787 
imageOff(SDL_Surface * sfc)3788 	void Button::imageOff(SDL_Surface* sfc)
3789 	{
3790 		this->addFrameSurface(sfc);
3791 		this->removeAnimation("off");
3792 		Animation anim;
3793 		anim.setName("off");
3794 		anim.addFrame(this->getFrames()-1);
3795 		this->addAnimation(anim);
3796 	}
3797 
3798 
3799 	/*****************************
3800 	**
3801 	** CLASS CHECKBUTTON
3802 	**
3803 	******************************/
3804 
CheckButton()3805 	CheckButton::CheckButton()  : Group () {
3806 		isRollOver = false;
3807 		active = false;
3808 		indexz = 0;
3809 		text = "";
3810 
3811 		textAlt = "";
3812 		alignAlt = ALIGN_LEFT;
3813 		soundOn = "";
3814 		soundOut = "";
3815 		soundClick = "";
3816 
3817 		scaleOut = 1.0f;
3818 		scaleOn = 1.0f;
3819 		sensitive = true;
3820 
3821 		elBox = new Element();
3822 		elBox->addFrameSurface(Primitives::GetInstance()->rectangle(20, 20, 255, 0, 0));
3823 		elBox->addFrameSurface(Primitives::GetInstance()->rectangle(20, 20, 255, 0, 0));
3824 		this->addElement(elBox);
3825 		elBox->setGroup(this);
3826 
3827 		char tmp[2];
3828 		sprintf(tmp, ".");
3829 		elText = new Element();
3830 		elText->addFrameText(Fonts::GetInstance()->getDefaultFont(), tmp, ALIGN_CENTER);
3831 		elText->setVAlign(VALIGN_CENTER);
3832 		this->addElement(elText);
3833 		elText->setGroup(this);
3834 
3835 	}
3836 
CheckButton(string font,string t)3837 	CheckButton::CheckButton(string font, string t)  : Group () {
3838 		isRollOver = false;
3839 		active = false;
3840 		indexz = 0;
3841 		text = "";
3842 
3843 		elBox = new Element();
3844 		this->addElement(elBox);
3845 		elBox->addFrameSurface(Primitives::GetInstance()->rectangle(20, 20, 255, 0, 0));
3846 		elBox->addFrameSurface(Primitives::GetInstance()->rectangle(20, 20, 255, 0, 0));
3847 		elBox->setGroup(this);
3848 
3849 		setText(font, t);
3850 
3851 	}
3852 
~CheckButton()3853 	CheckButton::~CheckButton () {
3854 		unLoad();
3855 	}
3856 
isOnMouseOver()3857 	bool CheckButton::isOnMouseOver()
3858 	{
3859 
3860 		int mouse_x, mouse_y;
3861 
3862 		SDL_PumpEvents();
3863 
3864 		SDL_GetMouseState(&mouse_x, &mouse_y);
3865 
3866 		float x1, x2, y1, y2;
3867 
3868 		x1 = elBox->getX();
3869 		y1 = elBox->getY();
3870 
3871 		if (text=="") {
3872 			x2 = x1 + elBox->getWidth();
3873 			y2 = y1 + elBox->getHeight();
3874 		} else {
3875 			x2 = x1 + elBox->getWidth() + elText->getWidth() + 10;
3876 			y2 = y1 + elBox->getHeight() + elText->getHeight() + 10;
3877 		}
3878 
3879 		if ( (mouse_x > x1) && (mouse_x < x2) &&
3880 			(mouse_y > y1) && (mouse_y < y2) ) {
3881 			return true;
3882 		}
3883 
3884 		return false;
3885 
3886 	}
3887 
onOver()3888 	bool CheckButton::onOver()
3889 	{
3890 
3891         if (sensitive) {
3892     		if (isOnMouseOver() && !isRollOver) {
3893 				if (textAlt!="") Cursor::GetInstance()->showText(textAlt, alignAlt, valignAlt);
3894 				if (soundOn!="") Sounds::GetInstance()->getSound(soundOn)->play(-1, 0);
3895 
3896     			isRollOver = true;
3897     			if (scaleOn!= scaleOut) {
3898 					for (int i=0; i<(int)elements.size(); i++) {
3899     					elements[i]->setScale(elements[i]->getWidthOriginal()*scaleOn, elements[i]->getHeightOriginal()*scaleOn, 100);
3900 					}
3901     			}
3902 				return true;
3903     		}
3904     		if (!isOnMouseOver() && isRollOver) {
3905 				if (textAlt!="") Cursor::GetInstance()->hideText(textAlt);
3906 				if (soundOut!="") Sounds::GetInstance()->getSound(soundOut)->play(-1, 0);
3907 
3908     			isRollOver = false;
3909     			if (scaleOn!= scaleOut) {
3910 					for (int i=0; i<(int)elements.size(); i++) {
3911     					elements[i]->setScale(elements[i]->getWidthOriginal()*scaleOut, elements[i]->getHeightOriginal()*scaleOut, 100);
3912 					}
3913     			}
3914 				return true;
3915     		}
3916         }
3917 		return false;
3918 
3919 	}
3920 
3921 
imageActive(SDL_Surface * sfc)3922 	void CheckButton::imageActive(SDL_Surface* sfc)
3923 	{
3924 		elBox->changeFrameSurface(1, sfc);
3925 		elText->setX(elBox->getWidth()+5);
3926 		elText->setY(elBox->getHeight()/2);
3927 	}
3928 
imageInactive(SDL_Surface * sfc)3929 	void CheckButton::imageInactive(SDL_Surface* sfc)
3930 	{
3931 		elBox->changeFrameSurface(0, sfc);
3932 		elText->setX(elBox->getWidth()+5);
3933 		elText->setY(elBox->getHeight()/2);
3934 	}
3935 
setText(string font,string t)3936 	void CheckButton::setText (string font, string t) {
3937 		if (text=="") {
3938 			text = t;
3939 			elText = new Element();
3940 			elText->addFrameText(font, text, ALIGN_CENTER);
3941 			elText->setVAlign(VALIGN_CENTER);
3942 			elText->setX(elBox->getWidth()+5);
3943 			elText->setY(elBox->getHeight()/2);
3944 			this->addElement(elText);
3945 			elText->setGroup(this);
3946 		} else {
3947 			text = t;
3948 			elText->changeFrameText(0, font, text, ALIGN_CENTER);
3949 			elText->setX(elBox->getWidth()+5);
3950 			elText->setY(elBox->getHeight()/2);
3951 		}
3952 	}
3953 
unLoad()3954 	void CheckButton::unLoad()
3955 	{
3956 		delete elBox;
3957 		if (text!="") delete elText;
3958 	}
3959 
draw()3960 	void CheckButton::draw()
3961 	{
3962 		elBox->draw();
3963 		if (text!="") elText->draw();
3964 	}
3965 
3966 	/*****************************
3967 	**
3968 	** CLASS RADIOBUTTON
3969 	**
3970 	******************************/
3971 
RadioButton(RadioButton * p)3972 	RadioButton::RadioButton(RadioButton *p)  : CheckButton() {
3973 		parent = p;
3974 		if (parent!=NULL) {
3975 			parent->addChild(this);
3976 		}
3977 	}
3978 
RadioButton(RadioButton * p,string font,string t)3979 	RadioButton::RadioButton(RadioButton *p, string font, string t)  : CheckButton(font, t) {
3980 		parent = p;
3981 		if (parent!=NULL) {
3982 			parent->addChild(this);
3983 		}
3984 	}
3985 
~RadioButton()3986 	RadioButton::~RadioButton () {
3987 		unLoad();
3988 	}
3989 
addChild(RadioButton * r)3990 	void RadioButton::addChild(RadioButton *r) {
3991 		childs.push_back(r);
3992 	}
3993 
setActive(bool a)3994 	void RadioButton::setActive (bool a) {
3995 		if (a) {
3996 			RadioButton *p;
3997 			if (parent==NULL) {
3998 				p = this;
3999 			} else {
4000 				p = parent;
4001 			}
4002 			if (p!=NULL) {
4003 				int i;
4004 				for (i=0; i<(int)p->childs.size(); i++) {
4005 					p->childs[i]->setActive(false);
4006 				}
4007 				p->setActive(false);
4008 			}
4009 			active = a;
4010 			changeFrame();
4011 		} else {
4012 			active = a;
4013 			changeFrame();
4014 		}
4015 	}
4016 
swapActive()4017 	void RadioButton::swapActive () {
4018 		RadioButton *p;
4019 		if (parent==NULL) {
4020 			p = this;
4021 		} else {
4022 			p = parent;
4023 		}
4024 		if (p!=NULL) {
4025 			int i;
4026 			for (i=0; i<(int)p->childs.size(); i++) {
4027 				p->childs[i]->setActive(false);
4028 			}
4029 			p->setActive(false);
4030 		}
4031 		active = !active;
4032 		changeFrame();
4033 
4034 	}
4035 
getRadioButtonActive()4036 	RadioButton* RadioButton::getRadioButtonActive () {
4037 		RadioButton *p;
4038 		if (parent==NULL) {
4039 			p = this;
4040 		} else {
4041 			p = parent;
4042 		}
4043 		if (p!=NULL) {
4044 			int i;
4045 			for (i=0; i<(int)p->childs.size(); i++) {
4046 				if (p->childs[i]->getActive()) {
4047 					return p->childs[i];
4048 				}
4049 			}
4050 			return p;
4051 		}
4052 		return NULL;
4053 	}
4054 
unLoad()4055 	void RadioButton::unLoad()
4056 	{
4057 	}
4058 
4059 	/*****************************
4060 	**
4061 	** CLASS ENTRY
4062 	**
4063 	******************************/
4064 
Entry(Entry * p,int w,int h,float pt,float pl)4065 	Entry::Entry(Entry *p, int w, int h, float pt, float pl)  : Element () {
4066 
4067 		parent = p;
4068 		if (parent!=NULL) {
4069 			parent->addChild(this);
4070 		}
4071 
4072 		totalRows = 1;
4073 		currentRow = 1;
4074 		multiline = false;
4075 
4076 		width = w;
4077 		height = h;
4078 		padding_top = pt;
4079 		padding_left = pl;
4080 		text = "";
4081 		maxLetters = -1;
4082 		font = Fonts::GetInstance()->getDefaultFont();
4083 		fontLabel = Fonts::GetInstance()->getDefaultFont();
4084 		nospace = false;
4085 		nosigns = false;
4086 		active = false;
4087 		drawBox = true;
4088 
4089 		bg = new Button();
4090 
4091 		bg->imageOut(Primitives::GetInstance()->rectangle(w, h, 0, 0, 0, 2, 255, 255, 255));
4092 		bg->imageOn(Primitives::GetInstance()->rectangle(w, h, 0, 0, 0, 2, 253, 246, 173));
4093 		bg->setAnimation("out");
4094 
4095 		select = new Element();
4096 		select->addFrameSurface(Primitives::GetInstance()->rectangle(w, h, 253, 246, 173, 2, 255, 255, 255));
4097 
4098 		elmLabel = new Element();
4099 		elmLabel->setAlign(ALIGN_RIGHT);
4100 		elmLabel->addFrameSurface(Primitives::GetInstance()->rectangle(2, 2, 0, 0, 0));
4101 
4102 		this->addFrameSurface(Primitives::GetInstance()->rectangle(2, 2, 0, 0, 0));
4103 
4104         elmCursor = new Element();
4105         elmCursor->addFrameSurface(Primitives::GetInstance()->rectangle(2, h, 255, 255, 255));
4106     	elmCursor->setBlinking(30);
4107     	elmCursor->setActiveBlinking(true);
4108         posCursor=0;
4109 
4110 		setHorizontal(true);
4111 
4112 	}
4113 
~Entry()4114 	Entry::~Entry() {
4115 		unLoad();
4116 	}
4117 
setPosCursor(int p)4118 	void Entry::setPosCursor(int p) {
4119          if (p<0) {
4120              posCursor = 0;
4121          } else if (p>(int)text.length()) {
4122              posCursor = text.length();
4123          } else {
4124              posCursor = p;
4125          }
4126     }
4127 
setXCursor()4128 	void Entry::setXCursor() {
4129          InfoFontBitMap ifb = Fonts::GetInstance()->getInfoFontBitMap (font, -1, currentScaleX, width, ALIGN_LEFT, text.substr(0, posCursor));
4130          elmCursor->setX(getX()+ifb.xPosCursor);
4131          if (multiline) {
4132              InfoFontBitMap ifbComplete = Fonts::GetInstance()->getInfoFontBitMap (font, -1, currentScaleX, width, ALIGN_LEFT, text);
4133              //if ( (ifb.nLettersByLine[ifb.nLines-1] == ifbComplete.nLettersByLine[ifb.nLines-1])
4134              //     && (ifb.nLines<ifbComplete.nLines) ) { // last character and isn't in last line
4135 			 currentRow = ifb.nLines;
4136              elmCursor->setY(getY()+(currentRow-1)*height);
4137 			 if (posCursor>0) {
4138 				 if (text.substr(posCursor-1, 1)=="|") {
4139 					 elmCursor->setX(getX());
4140 					 elmCursor->setY(getY()+(currentRow)*height);
4141 				 }
4142 			 }
4143          }
4144     }
4145 
downLineCursor()4146 	void Entry::downLineCursor() {
4147          if ( (posCursor<(int)text.length()) && (multiline) ) {
4148              InfoFontBitMap ifb = Fonts::GetInstance()->getInfoFontBitMap (font, -1, currentScaleX, width, ALIGN_LEFT, text.substr(0, posCursor));
4149              InfoFontBitMap ifbComplete = Fonts::GetInstance()->getInfoFontBitMap (font, -1, currentScaleX, width, ALIGN_LEFT, text);
4150              if (ifb.nLines<ifbComplete.nLines) {
4151                   int pos = 0;
4152                   for (int i=0; i<currentRow; i++) {
4153                       pos += ifbComplete.nLettersByLine[i]+1;
4154                   }
4155                   if (ifb.nLettersByLine[currentRow-1] != ifbComplete.nLettersByLine[currentRow-1]) { // last character
4156                      pos += ifb.nLettersByLine[currentRow-1];
4157                   }
4158                   setPosCursor(pos);
4159                   setXCursor();
4160              }
4161          }
4162     }
4163 
upLineCursor()4164 	void Entry::upLineCursor() {
4165          if ( (posCursor>0) && (multiline) ) {
4166              InfoFontBitMap ifb = Fonts::GetInstance()->getInfoFontBitMap (font, -1, currentScaleX, width, ALIGN_LEFT, text.substr(0, posCursor));
4167              if (ifb.nLines>0) {
4168                   int pos = 0;
4169                   for (int i=0; i<currentRow-2; i++) {
4170                       pos += ifb.nLettersByLine[i]+1;
4171                   }
4172                   pos += ifb.nLettersByLine[currentRow-1];
4173                   setPosCursor(pos);
4174                   setXCursor();
4175              }
4176          }
4177     }
4178 
forwardCursor()4179 	void Entry::forwardCursor() {
4180          if (posCursor<(int)text.length()) {
4181              posCursor++;
4182              setXCursor();
4183          }
4184     }
4185 
backCursor()4186 	void Entry::backCursor() {
4187          if (posCursor>0) {
4188              posCursor--;
4189              setXCursor();
4190          }
4191     }
4192 
setHorizontal(bool h)4193 	void Entry::setHorizontal (bool h) {
4194          horizontal = h;
4195          if (horizontal) {
4196             setAlign(ALIGN_LEFT);
4197             elmCursor->setAlign(ALIGN_LEFT);
4198             bg->setAlign(ALIGN_LEFT);
4199 		    select->setAlign(ALIGN_LEFT);
4200             elmLabel->setAlign(ALIGN_RIGHT);
4201 
4202             setVAlign(VALIGN_CENTER);
4203             elmCursor->setVAlign(VALIGN_CENTER);
4204             bg->setVAlign(VALIGN_CENTER);
4205 		    select->setVAlign(VALIGN_CENTER);
4206             elmLabel->setVAlign(VALIGN_CENTER);
4207          } else {
4208             setAlign(ALIGN_LEFT);
4209             elmCursor->setAlign(ALIGN_LEFT);
4210             bg->setAlign(VALIGN_CENTER);
4211 		    select->setAlign(VALIGN_CENTER);
4212 		    elmLabel->setAlign(ALIGN_CENTER);
4213 
4214             setVAlign(VALIGN_TOP);
4215             elmCursor->setVAlign(VALIGN_TOP);
4216             bg->setVAlign(VALIGN_TOP);
4217 		    select->setVAlign(VALIGN_TOP);
4218             elmLabel->setVAlign(VALIGN_BOTTOM);
4219          }
4220     }
4221 
setX(float x)4222 	void Entry::setX (float x) {
4223         if (horizontal) {
4224     		oldX = posX+padding_left;
4225     		posX = x+padding_left;
4226     		elmCursor->setX(posX);
4227     		bg->setX(x);
4228     		select->setX(x);
4229     		elmLabel->setX(x-10);
4230         } else {
4231     		oldX = posX+padding_left-(width/2);
4232     		posX = x+padding_left-(width/2);
4233     		elmCursor->setX(posX);
4234     		bg->setX(x);
4235     		select->setX(x);
4236    			elmLabel->setX(x);
4237         }
4238 	}
4239 
setY(float y)4240 	void Entry::setY (float y) {
4241         if (horizontal) {
4242     		oldY = posY+padding_top;
4243     		posY = y+padding_top;
4244     		elmCursor->setY(posY);
4245     		bg->setY(y);
4246     		select->setY(y);
4247     		elmLabel->setY(y);
4248         } else {
4249     		oldY = posY+padding_top;
4250     		posY = y+padding_top;
4251     		elmCursor->setY(posY);
4252     		bg->setY(y);
4253     		select->setY(y);
4254     		elmLabel->setY(y);
4255         }
4256 	}
4257 
setXY(float x,float y)4258 	void Entry::setXY (float x, float y) {
4259 		setX(x);
4260 		setY(y);
4261 	}
4262 
addChild(Entry * e)4263 	void Entry::addChild(Entry *e) {
4264 		childs.push_back(e);
4265 	}
4266 
setLabel(string l)4267 	void Entry::setLabel (string l) {
4268 		label = l;
4269 		elmLabel->changeFrameText(0, fontLabel, label, ALIGN_CENTER);
4270 	}
4271 
colorBoxNormal(int r,int g,int b,int border,int rb,int gb,int bb)4272 	void Entry::colorBoxNormal (int r, int g, int b, int border, int rb, int gb, int bb) {
4273 		bg->imageOut(Primitives::GetInstance()->rectangle(width, height, r, g, b, border, rb, gb, bb));
4274 	}
4275 
colorBoxOnOver(int r,int g,int b,int border,int rb,int gb,int bb)4276 	void Entry::colorBoxOnOver (int r, int g, int b, int border, int rb, int gb, int bb) {
4277 		bg->imageOn(Primitives::GetInstance()->rectangle(width, height, r, g, b, border, rb, gb, bb));
4278 	}
4279 
colorBoxActived(int r,int g,int b,int border,int rb,int gb,int bb)4280 	void Entry::colorBoxActived (int r, int g, int b, int border, int rb, int gb, int bb) {
4281 		select->changeFrameSurface(0, Primitives::GetInstance()->rectangle(width, height, r, g, b, border, rb, gb, bb));
4282 	}
4283 
addFrameBoxNormal(SDL_Surface * sfc)4284 	void Entry::addFrameBoxNormal (SDL_Surface *sfc) {
4285 		bg->imageOut(sfc);
4286 	}
4287 
addFrameBoxOnOver(SDL_Surface * sfc)4288 	void Entry::addFrameBoxOnOver (SDL_Surface *sfc) {
4289 		bg->imageOn(sfc);
4290 	}
4291 
addFrameBoxActived(SDL_Surface * sfc)4292 	void Entry::addFrameBoxActived (SDL_Surface *sfc) {
4293 		select->changeFrameSurface(0, sfc);
4294 	}
4295 
setActive(bool a)4296 	void Entry::setActive (bool a) {
4297 		if (a) {
4298 			Entry *p;
4299 			if (parent==NULL) {
4300 				p = this;
4301 			} else {
4302 				p = parent;
4303 			}
4304 			if (p!=NULL) {
4305 				int i;
4306 				for (i=0; i<(int)p->childs.size(); i++) {
4307 					p->childs[i]->setActive(false);
4308 				}
4309 				p->setActive(false);
4310 			}
4311 			active = a;
4312 		} else {
4313 			active = a;
4314 		}
4315 	}
4316 
swapActive()4317 	void Entry::swapActive () {
4318 		Entry *p;
4319 		if (parent==NULL) {
4320 			p = this;
4321 		} else {
4322 			p = parent;
4323 		}
4324 		if (p!=NULL) {
4325 			int i;
4326 			for (i=0; i<(int)p->childs.size(); i++) {
4327 				p->childs[i]->setActive(false);
4328 			}
4329 			p->setActive(false);
4330 		}
4331 		active = !active;
4332 
4333 	}
4334 
getEntryActive()4335 	Entry* Entry::getEntryActive () {
4336 		Entry *p;
4337 		if (parent==NULL) {
4338 			p = this;
4339 		} else {
4340 			p = parent;
4341 		}
4342 		if (p!=NULL) {
4343 			int i;
4344 			for (i=0; i<(int)p->childs.size(); i++) {
4345 				if (p->childs[i]->getActive()) {
4346 					return p->childs[i];
4347 				}
4348 			}
4349 			return p;
4350 		}
4351 		return NULL;
4352 	}
4353 
getNextEntry()4354 	Entry* Entry::getNextEntry () {
4355 		Entry *p;
4356 		if (parent==NULL) {
4357 			p = this;
4358 		} else {
4359 			p = parent;
4360 		}
4361 
4362 		if ((int)p->childs.size()<=0) return NULL;
4363 
4364 		if (p!=NULL) {
4365             if (p->getActive()) {
4366                 return p->childs[0];
4367             }
4368 			int i;
4369 			for (i=0; i<(int)p->childs.size(); i++) {
4370 				if (p->childs[i]->getActive()) {
4371                     if (i+1<(int)p->childs.size()) {
4372 					   return p->childs[i+1];
4373                     } else {
4374                        return p;
4375                     }
4376 				}
4377 			}
4378 			return p;
4379 		}
4380 		return NULL;
4381 	}
4382 
setText(string t)4383 	void Entry::setText (string t) {
4384 		if (maxLetters>0) {
4385 			if ((int)t.length()>maxLetters) {
4386 				t = t.substr(0, maxLetters);
4387 			}
4388 		}
4389 		text = t;
4390 		updateText();
4391 		setPosCursor(0);
4392 		setXCursor();
4393 		currentRow = 1;
4394     }
4395 
4396 	/*void Entry::setText(SDLKey key) {
4397 		getEntryActive()->introKey(key);
4398 	}*/
4399 
insertText(string t)4400 	void Entry::insertText(string t) {
4401 		getEntryActive()->introText(t);
4402 	}
4403 
verifyKey(SDLKey k)4404 	bool Entry::verifyKey (SDLKey k) {
4405 
4406 		if (text!="") {
4407 			if (k == SDLK_BACKSPACE) {
4408 				text.erase(posCursor-1, 1);
4409 			    updateText();
4410 			    backCursor();
4411 			    return true;
4412 			}
4413 
4414 			if (k == SDLK_RETURN) {
4415 				if (multiline) {
4416 					text.insert(posCursor, "|");
4417 					forwardCursor();
4418 					updateText();
4419 				}
4420 				return true;
4421 			}
4422 			if (k == SDLK_TAB) {
4423 				if (getNextEntry()!=NULL) getNextEntry()->setActive(true);
4424 				return true;
4425 			}
4426 
4427 			if (k == SDLK_LEFT) {
4428 			    backCursor();
4429 			    return true;
4430 			}
4431 			if (k == SDLK_RIGHT) {
4432 			    forwardCursor();
4433 			    return true;
4434 			}
4435 
4436 			if (k == SDLK_UP) {
4437 				if (multiline) upLineCursor();
4438 				return true;
4439 			}
4440 			if (k == SDLK_DOWN) {
4441 				if (multiline) downLineCursor();
4442 				return true;
4443 			}
4444 			if (k == SDLK_LSHIFT) {
4445 				return true;
4446 			}
4447 			if (k == SDLK_RSHIFT) {
4448 				return true;
4449 			}
4450 			if (k == SDLK_RCTRL) {
4451 				return true;
4452 			}
4453 			if (k == SDLK_LCTRL) {
4454 				return true;
4455 			}
4456 			if (k == SDLK_LALT) {
4457 				return true;
4458 			}
4459 			if (k == SDLK_RALT) {
4460 				return true;
4461 			}
4462 		}
4463 
4464 		return false;
4465 
4466 	}
4467 
insertTextUnicode(SDLKey k,int i)4468 	void Entry::insertTextUnicode (SDLKey k, int i) {
4469 
4470 		if (!getEntryActive()->verifyKey(k)) {
4471 			char c[4];
4472 			sprintf(c, "%c", i);
4473 
4474 			if (WorkingData::GetInstance()->validCharacter(c)) insertText(c);
4475 		}
4476 
4477 
4478 	}
4479 
introText(string t)4480 	void Entry::introText(string t) {
4481 		if ( (!((int)text.length()+1>maxLetters)) || (maxLetters<0) ) {
4482 			if ( (t=="|") && (!multiline) ) return;
4483 			text.insert(posCursor, t);
4484 			forwardCursor();
4485 			updateText();
4486 		}
4487 	}
4488 
updateText()4489 	void Entry::updateText()
4490 	{
4491         if (!multiline) {
4492 
4493     		SDL_Surface *sfc;
4494 
4495     		if (text == "") {
4496     			sfc = Primitives::GetInstance()->rectangle(1, 1, 0, 0, 0);
4497     		} else {
4498     			sfc = Fonts::GetInstance()->getSurface_TextBitMap(font, ALIGN_LEFT, text);
4499     		}
4500 
4501     		this->changeFrameSurface(0, sfc);
4502 
4503     		this->setScaleH(height);
4504 
4505         } else {
4506 
4507     		SDL_Surface *sfc;
4508     		if (text == "") {
4509     			sfc = Primitives::GetInstance()->rectangle(1, 1, 0, 0, 0);
4510     		} else {
4511     			sfc = Fonts::GetInstance()->getSurface_TextBitMap(font, totalRows, getCurrentScaleX(), width, ALIGN_LEFT, text);
4512     		}
4513 			this->changeFrameSurface(0, sfc);
4514 
4515     		InfoFontBitMap info = Fonts::GetInstance()->getInfoFontBitMap(font, totalRows, getCurrentScaleX(), width, ALIGN_LEFT, text);
4516     		text = info.text;
4517     		currentRow = info.nLines;
4518 
4519 			if (info.nLettersByLine[(int)info.nLettersByLine.size()-1] == 0) {
4520     			this->setScaleH((currentRow-1)*height);
4521 			} else {
4522 				this->setScaleH(currentRow*height);
4523 			}
4524 
4525         }
4526 	}
4527 
onOver()4528 	void Entry::onOver()
4529 	{
4530 		bg->onOver();
4531 	}
4532 
isOnMouseOver()4533 	bool Entry::isOnMouseOver()
4534 	{
4535 		return bg->isOnMouseOver();
4536 	}
4537 
draw()4538 	void Entry::draw()
4539 	{
4540         if (drawBox) {
4541     		if (active)
4542     			select->draw();
4543     		else
4544     			bg->draw();
4545         }
4546 		if (label!="")
4547 			elmLabel->draw();
4548 
4549 		if (text!="") {
4550 			move();
4551 			transforms();
4552 			paintSprite();
4553 		}
4554 		if (active) {
4555             elmCursor->draw();
4556         }
4557 	}
4558 
unLoad()4559 	void Entry::unLoad()
4560 	{
4561 		/*for (int i=0; i<(int)sprite.size(); i++)
4562 			sprite[i]->unLoad();
4563 		sprite.clear();*/
4564 		delete bg;
4565 		delete select;
4566 		delete elmLabel;
4567 		delete elmCursor;
4568 	}
4569 
4570 	/*****************************
4571 	**
4572 	** CLASS SELECTBUTTON
4573 	**
4574 	******************************/
4575 
SelectButton()4576 	SelectButton::SelectButton()  : Group () {
4577 		isRollOver = false;
4578 		arrows = false;
4579 		sensitive = true;
4580 		indexz = 0;
4581 		minSeparateButtons = 0;
4582 		greaterWidthObject = 0;
4583 
4584 		textAlt = "";
4585 		alignAlt = ALIGN_LEFT;
4586 		soundClick = "";
4587 
4588 		elObjects = new Element();
4589 		elObjects->setGroup(this);
4590 
4591 		elArrowLeft = new Button();
4592 		elArrowLeft->setVAlign(VALIGN_CENTER);
4593 		elArrowLeft->addFrameSurface(Primitives::GetInstance()->rectangle(20, 20, 255, 0, 0));
4594 		elArrowLeft->setGroup(this);
4595 
4596 		elArrowRight = new Button();
4597 		elArrowRight->setVAlign(VALIGN_CENTER);
4598 		elArrowRight->addFrameSurface(Primitives::GetInstance()->rectangle(20, 20, 255, 0, 0));
4599 		elArrowRight->setGroup(this);
4600 
4601 	}
4602 
~SelectButton()4603 	SelectButton::~SelectButton () {
4604 		unLoad();
4605 	}
4606 
setSensitive(bool s)4607 	void SelectButton::setSensitive(bool s) {
4608          sensitive = s;
4609          if (sensitive) {
4610              elObjects->setRGB(255,255,255);
4611              elArrowLeft->setRGB(255,255,255);
4612              elArrowRight->setRGB(255,255,255);
4613          } else {
4614              elObjects->setRGB(100,100,100);
4615              elArrowLeft->setRGB(100,100,100);
4616              elArrowRight->setRGB(100,100,100);
4617          }
4618     }
4619 
onOver()4620 	bool SelectButton::onOver()
4621 	{
4622 
4623         if (sensitive) {
4624     		if (isOnMouseOver() && !isRollOver) {
4625 				if (textAlt!="") Cursor::GetInstance()->showText(textAlt, alignAlt, valignAlt);
4626 				isRollOver = true;
4627 				return true;
4628     		}
4629     		if (!isOnMouseOver() && isRollOver) {
4630 				if (textAlt!="") Cursor::GetInstance()->hideText(textAlt);
4631 				isRollOver = false;
4632 				return true;
4633     		}
4634         }
4635 		return false;
4636 
4637 	}
4638 
setArrows(SDL_Surface * left,SDL_Surface * right)4639 	void SelectButton::setArrows(SDL_Surface* left, SDL_Surface* right) {
4640 		arrows = true;
4641 		elArrowLeft->changeFrameSurface(0, left);
4642 		elArrowLeft->setX(0);
4643 		elArrowLeft->setY(0);
4644 
4645 		elArrowRight->changeFrameSurface(0, right);
4646 
4647 		if (greaterWidthObject<minSeparateButtons) {
4648               greaterWidthObject = minSeparateButtons;
4649         }
4650 
4651   		elArrowRight->setX(elArrowLeft->getWidth()+10+greaterWidthObject);
4652   		elArrowRight->setY(0);
4653 
4654     	elObjects->setX(elArrowLeft->getWidth()+5+(greaterWidthObject/2));
4655     	elObjects->setY(0);
4656     	elObjects->setAlign(ALIGN_CENTER);
4657     	elObjects->setVAlign(VALIGN_CENTER);
4658 
4659 	}
4660 
4661 
isOnMouseOver()4662 	bool SelectButton::isOnMouseOver()
4663 	{
4664 
4665 		int mouse_x, mouse_y;
4666 
4667 		SDL_PumpEvents();
4668 
4669 		SDL_GetMouseState(&mouse_x, &mouse_y);
4670 
4671 		float x1, x2, y1, y2;
4672 
4673 		if (!arrows) {
4674 			x1 = elObjects->getX();
4675 			y1 = elObjects->getY();
4676 			x2 = x1 + elObjects->getWidth();
4677 			y2 = y1 + elObjects->getHeight();
4678 		} else {
4679 			int mostHeight = 0;
4680 			if ( elArrowLeft->getHeight() > mostHeight ) mostHeight = elArrowLeft->getHeight();
4681 			if ( elObjects->getHeight() > mostHeight ) mostHeight = elObjects->getHeight();
4682 			if ( elArrowRight->getHeight() > mostHeight ) mostHeight = elArrowRight->getHeight();
4683 
4684 			x1 = elArrowLeft->getX();
4685 			y1 = elArrowLeft->getY()-(mostHeight/2);
4686 			x2 = x1 + greaterWidthObject + elArrowLeft->getWidth() + elArrowRight->getWidth() + 10;
4687 			y2 = y1 + mostHeight;
4688 		}
4689 
4690 		if ( (mouse_x > x1) && (mouse_x < x2) &&
4691 			(mouse_y > y1) && (mouse_y < y2) ) {
4692 			return true;
4693 		}
4694 
4695 		return false;
4696 
4697 	}
4698 
getOverBottom()4699 	int SelectButton::getOverBottom() {
4700 		if (elArrowLeft->isOnMouseOver()) return LEFT;
4701 		if (elArrowRight->isOnMouseOver()) return RIGHT;
4702 		return -1;
4703 	}
4704 
addObject(SDL_Surface * sfc)4705 	void SelectButton::addObject(SDL_Surface* sfc)
4706 	{
4707 		if (sfc->w > greaterWidthObject) greaterWidthObject = sfc->w;
4708 		elObjects->addFrameSurface(sfc);
4709 	}
4710 
4711 
unLoad()4712 	void SelectButton::unLoad()
4713 	{
4714 		delete elObjects;
4715 		if (arrows) {
4716 			delete elArrowLeft;
4717 			delete elArrowRight;
4718 		}
4719 	}
4720 
draw()4721 	void SelectButton::draw()
4722 	{
4723 		elObjects->draw();
4724 		if (arrows) {
4725 			elArrowLeft->draw();
4726 			elArrowRight->draw();
4727 		}
4728 	}
4729 
4730 
4731 	/*****************************
4732 	**
4733 	** CLASE Particle
4734 	**
4735 	******************************/
4736 
Particle(ParticlesSystem * ps)4737 	Particle::Particle(ParticlesSystem *ps) : Element () {
4738 
4739 		particlesSystem = ps;
4740 
4741         type = TYPE_EXPLOSION;
4742         cyclesLife = Converter::GetInstance()->ml2cycles(1000);
4743         currentCyclesLife = 0;
4744 
4745         displacementX = 0;
4746         displacementY = 0;
4747 
4748         positionX = 0;
4749         positionY = 0;
4750         positionW = World::width;
4751         positionH = World::height;
4752 
4753         changeColor = false;
4754         currentColor = 0;
4755 
4756         color.r = 255;
4757         color.g = 255;
4758         color.b = 255;
4759 
4760         setRGB(color.r, color.g, color.b);
4761 
4762         state = PARTICLE_BEINGBORN;
4763 
4764         factorAlpha = 6;
4765 
4766         returnToBeBorn = false;
4767 
4768         setAlign(ALIGN_CENTER);
4769         setVAlign(VALIGN_CENTER);
4770 
4771         rot = 5;
4772 
4773         scale = 0.03;
4774 
4775     }
4776 
~Particle()4777 	Particle::~Particle () {
4778 		unLoad();
4779 	}
4780 
setMlLife(int ml)4781     void Particle::setMlLife(int ml) {
4782         cyclesLife = Converter::GetInstance()->ml2cycles(ml);
4783     }
4784 
start()4785 	void Particle::start() {
4786 		show();
4787 		currentCyclesLife = 0;
4788 
4789 		if (type == TYPE_EXPLOSION) setCurrentScale(1.0);
4790 
4791 		setRot(0);
4792 
4793 		setX( positionX + (rand()%(int)positionW) );
4794 		setY( positionY + (rand()%(int)positionH) );
4795 
4796 	}
4797 
setPositions(float px,float py,float pw,float ph)4798 	void Particle::setPositions(float px, float py, float pw, float ph) {
4799         positionX = px;
4800         positionY = py;
4801         positionW = pw;
4802         positionH = ph;
4803 	}
4804 
change()4805 	void Particle::change () {
4806         if (type == TYPE_EXPLOSION) {
4807             switch (state) {
4808                 case PARTICLE_BEINGBORN:
4809                      addAlpha(factorAlpha);
4810                      if (getAlpha()>=255) {
4811                          state = PARTICLE_LIFE;
4812                          setAlpha(255);
4813                      }
4814                 break;
4815                 case PARTICLE_LIFE:
4816                      addCurrentCyclesLife();
4817                      if (currentCyclesLife>=cyclesLife) state = PARTICLE_DYING;
4818                 break;
4819                 case PARTICLE_DYING:
4820                      addAlpha(-factorAlpha);
4821                      if (getAlpha()<=0) {
4822                         state = PARTICLE_BEINGBORN;
4823                         setAlpha(0);
4824                         if (!returnToBeBorn) hide();
4825                      }
4826                 break;
4827             }
4828 
4829             if (changeColor) {
4830                 addCurrentColor();
4831                 setRGB(particlesSystem->colors->getColor(currentColor)->r, particlesSystem->colors->getColor(currentColor)->g, particlesSystem->colors->getColor(currentColor)->b);
4832             }
4833 
4834             addRot(rot);
4835             addCurrentScale(scale);
4836 
4837     		float factorMovHorizontal = 2.0f;
4838     		float factorMovVertical = 2.0f;
4839 
4840     		float rangox = (float)(rand()%(int)factorMovHorizontal)-((factorMovHorizontal/2)-0.5);
4841     		float rangoy = (float)(rand()%(int)factorMovVertical)-((factorMovVertical/2)-0.5);
4842     		addX(rangox);
4843     		addY(rangoy);
4844 
4845         } else if (type == TYPE_STARS) {
4846 
4847             switch (state) {
4848                 case PARTICLE_BEINGBORN:
4849                      addAlpha(factorAlpha);
4850                      if (getAlpha()>=255) {
4851                         state = PARTICLE_LIFE;
4852                         setAlpha(255);
4853                      }
4854                 break;
4855                 case PARTICLE_LIFE:
4856                      if (outLimitScreen()) {
4857                          state = PARTICLE_BEINGBORN;
4858                          setAlpha(0);
4859                          start();
4860 						 setX( positionX + (rand()%((int)positionW)/4) );
4861                      }
4862                 break;
4863             }
4864 
4865             if (changeColor) {
4866                 addCurrentColor();
4867                 setRGB(particlesSystem->colors->getColor(currentColor)->r, particlesSystem->colors->getColor(currentColor)->g, particlesSystem->colors->getColor(currentColor)->b);
4868             }
4869 
4870     		addX(displacementX);
4871     		addY(displacementY);
4872 
4873         }
4874 	}
4875 
4876 	/*****************************
4877 	**
4878 	** CLASE ParticlesSystem
4879 	**
4880 	******************************/
4881 
ParticlesSystem()4882 	ParticlesSystem::ParticlesSystem() {
4883         type = TYPE_EXPLOSION;
4884         positionX = 0;
4885         positionY = 0;
4886         positionW = World::width;
4887         positionH = World::height;
4888 
4889 	    nParticles = NPARTICLES;
4890         indexz = 0;
4891         int i;
4892 		for (i=0; i<nParticles; i++) {
4893 			particles[i] = new Particle(this);
4894 			particles[i]->hide();
4895 		}
4896 
4897 		colors = new VectorColors();
4898 		colors->addColor(100,200,156);
4899 		colors->addColor(76,68,43);
4900 		colors->addColor(245,190,255);
4901 		colors->addColor(34,2,23);
4902 		colors->addColor(100,100,167);
4903 		colors->addColor(255,20,0);
4904 		colors->addColor(129,212,5);
4905 		colors->addColor(45,45,88);
4906 		colors->addColor(45,123,234);
4907 		colors->addColor(72,45,178);
4908 		colors->addColor(92,232,91);
4909 		colors->addColor(90,178,210);
4910 
4911     }
4912 
ParticlesSystem(int np)4913 	ParticlesSystem::ParticlesSystem(int np) {
4914 		type = TYPE_EXPLOSION;
4915         positionX = 0;
4916         positionY = 0;
4917         positionW = World::width;
4918         positionH = World::height;
4919 
4920         if (np>NPARTICLES) {
4921 		    nParticles = NPARTICLES;
4922         } else {
4923             nParticles = np;
4924         }
4925         indexz = 0;
4926         int i;
4927 		for (i=0; i<nParticles; i++) {
4928 			particles[i] = new Particle(this);
4929 			particles[i]->hide();
4930 		}
4931 
4932 		colors = new VectorColors();
4933 		colors->addColor(100,200,156);
4934 		colors->addColor(76,68,43);
4935 		colors->addColor(245,190,255);
4936 		colors->addColor(34,2,23);
4937 		colors->addColor(100,100,167);
4938 		colors->addColor(255,20,0);
4939 		colors->addColor(129,212,5);
4940 		colors->addColor(45,45,88);
4941 		colors->addColor(45,123,234);
4942 		colors->addColor(72,45,178);
4943 		colors->addColor(92,232,91);
4944 		colors->addColor(90,178,210);
4945 
4946     }
4947 
~ParticlesSystem()4948 	ParticlesSystem::~ParticlesSystem () {
4949 		unLoad();
4950 	}
4951 
isVisible()4952     bool ParticlesSystem::isVisible() {
4953 		int i;
4954 		for (i=0; i<nParticles; i++) {
4955 			if (particles[i]->isVisible()) {
4956                return true;
4957             }
4958 		}
4959 		return false;
4960 	}
4961 
setType(int t)4962 	void ParticlesSystem::setType(int t) {
4963 		type = t;
4964 		int i;
4965 		for (i=0; i<nParticles; i++) {
4966 			particles[i]->setType(t);
4967 		}
4968 	}
4969 
start()4970 	void ParticlesSystem::start() {
4971 		int i;
4972 		for (i=0; i<nParticles; i++) {
4973 			particles[i]->start();
4974 		}
4975 	}
4976 
setFrame(SDL_Surface * sfc)4977 	void ParticlesSystem::setFrame(SDL_Surface* sfc) {
4978 		int i;
4979 		for (i=0; i<nParticles; i++) {
4980 			particles[i]->addFrameSurface(sfc);
4981 		}
4982 	}
4983 
setFrame(string fr)4984 	void ParticlesSystem::setFrame(string fr) {
4985 		int i;
4986 		for (i=0; i<nParticles; i++) {
4987 			particles[i]->addFrameFile(fr);
4988 		}
4989 	}
4990 
setPositions(float px,float py,float pw,float ph)4991 	void ParticlesSystem::setPositions(float px, float py, float pw, float ph) {
4992         positionX = px;
4993         positionY = py;
4994         positionW = pw;
4995         positionH = ph;
4996 		int i;
4997 		for (i=0; i<nParticles; i++) {
4998 			particles[i]->setPositions(px, py, pw, ph);
4999 		}
5000 	}
5001 
setChangeColor(bool cl)5002 	void ParticlesSystem::setChangeColor(bool cl) {
5003 		int i;
5004 		for (i=0; i<nParticles; i++) {
5005 			particles[i]->setChangeColor(cl);
5006 		}
5007 	}
5008 
setScale(int s)5009 	void ParticlesSystem::setScale(int s) {
5010 		int i;
5011 		for (i=0; i<nParticles; i++) {
5012 			particles[i]->setScale(s);
5013 		}
5014 	}
5015 
setCurrentScale(float s)5016 	void ParticlesSystem::setCurrentScale(float s) {
5017 		int i;
5018 		for (i=0; i<nParticles; i++) {
5019 			particles[i]->setCurrentScale(s);
5020 		}
5021 	}
5022 
setRotation(int r)5023 	void ParticlesSystem::setRotation(int r) {
5024 		int i;
5025 		for (i=0; i<nParticles; i++) {
5026 			particles[i]->setRotation(r);
5027 		}
5028 	}
5029 
setFactorAlpha(float fa)5030 	void ParticlesSystem::setFactorAlpha(float fa) {
5031 		int i;
5032 		for (i=0; i<nParticles; i++) {
5033 			particles[i]->setFactorAlpha(fa);
5034 		}
5035 	}
5036 
setMlLife(int ml)5037 	void ParticlesSystem::setMlLife(int ml) {
5038 		int i;
5039 		for (i=0; i<nParticles; i++) {
5040 			particles[i]->setMlLife(ml);
5041 		}
5042 	}
5043 
setMlLife(int ml1,int ml2)5044 	void ParticlesSystem::setMlLife(int ml1, int ml2) {
5045 		int i;
5046 		for (i=0; i<nParticles; i++) {
5047             int ml = rand()%(int)(ml2-ml1);
5048 			particles[i]->setMlLife(ml);
5049 		}
5050 	}
5051 
setDisplacementX(float b,float e)5052     void ParticlesSystem::setDisplacementX(float b, float e) {
5053 		int i;
5054 		for (i=0; i<nParticles; i++) {
5055             /*float d = rand()%(int)(e-b);
5056             d += b;*/
5057 			float d = rand()%(int)((e-b)*10);
5058 			d /= 10.0;
5059             d += b;
5060 			if (d==0.0) d=0.1;
5061 			particles[i]->setDisplacementX(d);
5062 		}
5063     }
5064 
setDisplacementY(float b,float e)5065 	void ParticlesSystem::setDisplacementY(float b, float e) {
5066 		int i;
5067 		for (i=0; i<nParticles; i++) {
5068 			float d = rand()%(int)((e-b)*10);
5069 			d /= 10.0;
5070 			d += b;
5071 			if (d==0.0) d=0.1;
5072 			particles[i]->setDisplacementY(d);
5073 		}
5074     }
5075 
setReturnToBeBorn(bool r)5076 	void ParticlesSystem::setReturnToBeBorn(bool r) {
5077 		int i;
5078 		for (i=0; i<nParticles; i++) {
5079 			particles[i]->setReturnToBeBorn(r);
5080 		}
5081 	}
5082 
draw()5083 	void ParticlesSystem::draw() {
5084 		int i;
5085 		for (i=0; i<nParticles; i++) {
5086 			if (particles[i]->isVisible()) {
5087 				particles[i]->change();
5088 				particles[i]->draw();
5089 			}
5090 		}
5091 	}
5092 
unLoad()5093 	void ParticlesSystem::unLoad() {
5094 		int i;
5095 		for (i=0; i<nParticles; i++) {
5096 			delete particles[i];
5097 		}
5098 		delete colors;
5099 	}
5100 
5101 
5102 }
5103