1 /**
2 * @file handler_resources.cc
3 * @brief Handler of the files resources
4 * @created 2004-04-20
5 * @date 2014-07-20
6 * @copyright 1991-2014 TLK Games
7 * @author Bruno Ethvignot
8 * @version $Revision: 24 $
9 */
10 /*
11 * copyright (c) 1991-2014 TLK Games all rights reserved
12 * $Id: handler_resources.cc 24 2014-09-28 15:30:04Z bruno.ethvignot@gmail.com $
13 *
14 * TecnoballZ is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * TecnoballZ is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27 * MA 02110-1301, USA.
28 */
29 #include "../include/handler_resources.h"
30 #include "../include/bitmap_data.h"
31 #include "../config.h"
32 #include <string>
33 #include <fstream>
34
35 #ifndef DATADIR
36 #define DATADIR "/usr/share/games/tecnoballz"
37 #endif
38
39 #ifndef SCOREFILE
40 #define SCOREFILE "/var/lib/games/tecnoballz.hi"
41 #endif
42
43 #ifdef _WIN32
44 #ifndef _S_ISDIR
45 #define _S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
46 #endif
47 #endif
48
49 handler_resources *
50 handler_resources::handler_resources_singleton = NULL;
51
52 const char * handler_resources::fnamescore = SCOREFILE;
53 const char *
54 handler_resources::folder_640 = "hires/";
55 const char *
56 handler_resources::folder_320 = "lores/";
57 char
58 handler_resources::tmp_filename[512];
59 char
60 handler_resources::pathstring[512];
61
62 const char *
63 handler_resources::standfiles[] = {
64 "cosinus128.list", //RESCOSLIST
65 /* MAP_GUARDIANS_20 */
66 "tilemap-guardians_20.data",
67 "tilemap-guardians_40.data",
68 /* MAP_CONGRATULATIONS_20 */
69 "tilemap-congratulation_20.data",
70 "tilemap-congratulation_40.data",
71 /* MAP_MENU_20 */
72 "tilemap-menu_20.data",
73 "tilemap-menu_40.data",
74 "gard_lissa.list", //RESGCURVES
75 /* DATA_BRICKS_LEVELS */
76 "tableau.data",
77 "min60map.png", //RES60BACKG
78 /* DATA_LEVELS */
79 "levels-data.xml"
80 };
81
82 const char *
83 handler_resources::musicfiles[] = {
84 "area1-game2.mod",
85 "area2-game.mod",
86 "area3-game.mod",
87 "area4-game.mod",
88 "area5-game.mod",
89 "gardien-go.mod",
90 "high-score.mod",
91 "over-theme.mod",
92 "tecnoballz.mod",
93 "tecno-winn.mod",
94 "termigator_reg-zbb.mod",
95 "in-game-music-1_reg.mod",
96 "fridge-in-space_from_reg-zbb.mod",
97 "mon-lapin_reg-zbb.mod"
98 };
99
100 const char *
101 handler_resources::soundfiles[] = { "rlife_moins.wav", // 01
102 "rexplo_rak.wav",
103 "rlife_plus.wav",
104 "rmoney.wav",
105 "ralarm.wav", //05
106 "rgadget_sound.wav",
107 "rtecno.wav",
108 "rappar.wav",
109 "rtransfo.wav",
110 "rtir_monstre.wav", //10
111 "rtir_rak.wav",
112 "rexplo_big.wav",
113 "rdetruit_indes.wav",
114 "rexeplo_atom.wav",
115 "rmontre_touche.wav", //15
116 "ratom.wav",
117 "rindes_1.wav",
118 "rindes_2.wav",
119 "rraquette.wav",
120 "rbricote.wav", //20
121 "rbrique1.wav",
122 "rbrique2.wav",
123 "rbrique3.wav",
124 "rbrique4.wav",
125 "rbrique5.wav", //25
126 "raspire.wav",
127 "reject.wav", //27
128 };
129
130 const char * handler_resources::bitmap_files[] =
131 {
132 /* BITMAP_HEAD_ANIMATION */
133 "head_animation.png",
134 /* BITMAP_RIGHT_PANEL */
135 "right_panel.png",
136 /* BITMAP_PADDLES_1 */
137 "paddles_1.png",
138 /* BITMAP_PADDLES_2 */
139 "paddles_2.png",
140 /* BITMAP_GAME_FONTS */
141 "game_fonts.png",
142 /* BITMAP_MENU_FONTS */
143 "menu_fonts.png",
144 /* BITMAP_SMALL_FONTS */
145 "small_fonts.png",
146 /* BITMAP_GIGABLITZ */
147 "gigablitz.png",
148 /* BITMAP_TILESMAP */
149 "tilesmap.png",
150 /* BITMAP_SHOP */
151 "shop.png",
152 /* BITMAP_ALL_SPRITES */
153 "all_sprites.png",
154 /* BITMAP_BRICKS */
155 "bricks.png",
156 /* BITMAP_SCORES_FONTS */
157 "font_score.png"
158 };
159
160 const char * handler_resources::texts_files[] =
161 {
162 /* TEXTS_SHOP */
163 "shop_%s.txt",
164 /* TEXTS_MESSAGES */
165 "short_info_messages_%s.txt",
166 /* TEXTS_SCROLL_MENU */
167 "scrolltext_%s.txt",
168 /* TEXTS_POPUP_MENU */
169 "popup_menu_%s.txt",
170 /* TEXTS_MAIN_MENU */
171 "main_menu_%s.txt"
172 };
173
174 //char handler_resources::ze_mapfile[] = "map??.png";
175
176 /**
177 * Create the resources manager object
178 */
handler_resources()179 handler_resources::handler_resources ()
180 {
181 last_filesize_loaded = 0;
182 set_filesize_loaded(0);
183 }
184
185 /**
186 * Get the object instance
187 * handler_resources is a singleton
188 * @return the handler_resources object
189 */
190 handler_resources *
get_instance()191 handler_resources::get_instance ()
192 {
193 if (NULL == handler_resources_singleton)
194 {
195 handler_resources_singleton = new handler_resources ();
196 }
197 return handler_resources_singleton;
198 }
199
200 /**
201 * Release the resources manager object
202 */
~handler_resources()203 handler_resources::~handler_resources ()
204 {
205 if (table_cosL != NULL)
206 {
207 delete[](char *)table_cosL;
208 table_cosL = (Sint16 *) NULL;
209 }
210 release_sprites_bitmap ();
211 }
212
213 /**
214 * Load a resources file in memory
215 * @param resource_id resource identifier of the data
216 * @return file data buffer pointer
217 */
218 char *
load_data(Uint32 resource_id)219 handler_resources::load_data (Uint32 resource_id)
220 {
221 char *filename = get_filename (resource_id);
222 return load_file (filename);
223 }
224
225 /**
226 * Return valid name from a resource identifier
227 * @param resource_id resource identifier
228 * @param resolution 0 default, 1 = 320 or 2 640,
229 * @return filename with a relative pathname
230 */
231 char *
get_filename(Uint32 resource_id,Uint32 res)232 handler_resources::get_filename (Uint32 resource_id, Uint32 res)
233 {
234 const char *pfile;
235 if (resource_id >= BITMAP_OFFSET)
236 {
237 if (0 == res)
238 {
239 res = resolution;
240 }
241 resource_id -= BITMAP_OFFSET;
242 pfile = bitmap_files[resource_id];
243 if (1 == res)
244 {
245 strcpy (tmp_filename, folder_320);
246 }
247 else
248 {
249 strcpy (tmp_filename, folder_640);
250 }
251 strcat (tmp_filename, pfile);
252 }
253 else
254 {
255 pfile = standfiles[resource_id];
256 strcpy (tmp_filename, pfile);
257 }
258 return tmp_filename;
259 }
260
261 /**
262 * Return valid music filename from a resource identifier
263 * @param resource_id resource identifier of the music
264 * @return music filename with a relative pathname
265 */
266 char *
get_music_filename(Uint32 resource_id)267 handler_resources::get_music_filename (Uint32 resource_id)
268 {
269 const char *pfile;
270 strcpy (tmp_filename, "musics/");
271 pfile = musicfiles[resource_id];
272 strcat (tmp_filename, pfile);
273 return locate_data_file (tmp_filename);
274 }
275
276 /**
277 * Return valid sound filename from a resource identifier
278 * @param resource_id resource identifier of the sound
279 * @return sound filename with a relative pathname
280 */
281 char *
get_sound_filename(Uint32 resource_id)282 handler_resources::get_sound_filename (Uint32 resource_id)
283 {
284 strcpy (tmp_filename, "sounds/");
285 strcat (tmp_filename, soundfiles[resource_id]);
286 return locate_data_file (tmp_filename);
287 }
288
289 /**
290 * Return valid tilemaps filename from a tilemap number
291 * @param title_num filename number from 1 to 78
292 * @return tilemap filename with a relative pathname
293 */
294 char *
get_tilemaps_filename(Uint32 title_num)295 handler_resources::get_tilemaps_filename (Uint32 title_num)
296 {
297 sprintf(tmp_filename, "textures/map%02d.png", title_num);
298 return tmp_filename;
299 }
300
301 /**
302 * Return the full pathname from a resource identifier
303 * @param resource_id a resource identifier
304 * @return a pointer to the file data buffer
305 */
306 char *
get_full_pathname(Uint32 resource_id)307 handler_resources::get_full_pathname (Uint32 resource_id)
308 {
309 return locate_data_file (get_filename (resource_id));
310 }
311
312 /**
313 * Directory list to locate a file
314 */
315 const char * handler_resources::folderlist[] =
316 {
317 /* special value meaning "$(PREFIX)/share/games/tecnoballz/" */
318 DATADIR,
319 "/",
320 /* normally unused, except when running from the source directory */
321 "./TecnoballZ/",
322 /* also marks end of list */
323 0
324 };
325 /**
326 * Locate a file under one of the data directories
327 * @param name name of file relative to data directory
328 */
329 char *
locate_data_file(const char * const name)330 handler_resources::locate_data_file (const char *const name)
331 {
332 /*
333 if (is_verbose)
334 {
335 std::
336 cout << "(*) handler_resources::locate_data_file(" << name << ")" << std::
337 endl;
338 }
339 */
340
341 /* clear path name string */
342 for (Sint32 i = 0; i < 256; i++)
343 pathstring[i] = 0;
344
345 if (NULL == name)
346 {
347 std::cerr << "(!)handler_resources::locate_data_file() " <<
348 "NULL pointer was passed as an argument!" << std::endl;
349 throw std::ios_base::
350 failure ("[!] handler_resources::locate_data_file "
351 "NULL pointer was passed as an argument!");
352 }
353
354 /* if absolute path, return a pointer to a duplicate string */
355 char *pathname;
356 if (*name == '/')
357 {
358 pathname = &pathstring[0];
359 strcpy (pathname, name);
360 return pathname;
361 }
362
363 /* process each folder of the list */
364 for (const char **p = folderlist;; p++)
365 {
366 if (*p != 0)
367 {
368 /* check if the file is located in current directory */
369 pathname = &pathstring[0];
370 strcpy (pathname, *p);
371 if (pathname[strlen (pathname) - 1] != '/')
372 {
373 strcat (pathname, "/");
374 }
375 strcat (pathname, name);
376
377 }
378 else
379 {
380 /* file not found, try default folder as last chance */
381 const char *subdir = "/share/games/tecnoballz/";
382 pathname = &pathstring[0];
383 strcpy (pathname, nomprefix);
384 strcat (pathname, subdir);
385 strcat (pathname, name);
386 }
387 /*
388 if (is_verbose)
389 {
390 std::cout << "handler_resources::locate_data_file() try " << pathname << std::endl;
391 }
392 */
393 #ifdef WIN32
394 struct _stat s;
395 if (_stat (pathname, &s) == 0 && !_S_ISDIR (s.st_mode))
396 {
397 return pathname;
398 }
399 #else
400 struct stat s;
401 if (stat (pathname, &s) == 0 && !S_ISDIR (s.st_mode))
402 {
403 /*
404 if (is_verbose)
405 {
406 std::
407 cout << "handler_resources::locate_data_file(" << pathname <<
408 ") find!" << std::endl;
409 }
410 */
411 return pathname;
412 }
413 #endif
414 /* end of the list, error file not found! */
415 if (*p == 0)
416 {
417 break;
418 }
419 }
420 std::cerr << "(!)handler_resources::locate_data_file() file '"
421 << name << "' not found!" << std::endl;
422 throw std::ios_base::failure (std::string
423 ("[!]handler_resources::locate_data_file() File '")
424 + name + std::string ("' not found!"));
425 }
426
427 /**
428 * Load a bitmap of sprites
429 * @param resource_id resource identifier of the bitmap
430 * BITMAP_ALL_SPRITES by default
431 */
432 void
load_sprites_bitmap(Uint32 resource_id)433 handler_resources::load_sprites_bitmap (Uint32 resource_id)
434 {
435 release_sprites_bitmap ();
436 sprites_bitmap = new bitmap_data ();
437 sprites_bitmap->load (resource_id);
438 sprites_bitmap->enable_palette ();
439 }
440
441 /**
442 * Release the bitmap of sprites
443 */
444 void
release_sprites_bitmap()445 handler_resources::release_sprites_bitmap ()
446 {
447 if (sprites_bitmap != NULL)
448 {
449 delete sprites_bitmap;
450 }
451 sprites_bitmap = (bitmap_data *) NULL;
452 }
453
454 /**
455 * Load texts data into strings list
456 * @param resource_id resource identifier of the texts data
457 * @param numof_lines number of lines
458 * @param row_length maximum number of chars by string, 0 if preserve the size of
459 * the original string
460 * @param modulo 0 if non concatenation, 2 concatene strings 3 by 3
461 * @param upper_case Change from 'a' to 'z' chars by 'A' to 'Z' chars
462 */
463 char **
load_texts(Uint32 resource_id,Uint32 numof_lines,Uint32 row_length,Uint32 modulo,bool upper_case)464 handler_resources::load_texts(Uint32 resource_id, Uint32 numof_lines, Uint32 row_length, Uint32 modulo, bool upper_case)
465 {
466 resource_id -=TEXTS_OFFSET;
467 const char *file = texts_files[resource_id];
468 strcpy (tmp_filename, "texts/");
469 strcat (tmp_filename, file);
470 Uint32 filesize;
471 char *filedata = loadfile_with_lang (tmp_filename, &filesize);
472
473 /*
474 * caclulate the number of lines
475 */
476 Uint32 offset = 0;
477 bool is_first_row = true;
478 bool is_comment = false;
479 Uint32 row_count = 0;
480 Uint32 alloc_size = 0;
481 Uint32 list_count = 0;
482 Uint32 str_count = 0;
483 while (offset < filesize)
484 {
485 char c = filedata[offset++];
486 row_count++;
487 if (is_first_row && c == '#')
488 {
489 is_comment = true;
490 }
491 is_first_row = false;
492 if (c == '\n')
493 {
494 if (!is_comment)
495 {
496 if (row_length > 0)
497 {
498 alloc_size += row_length;
499 }
500 else
501 {
502 alloc_size += row_count - 1;
503 }
504 str_count++;
505 if (modulo == 0 || (str_count % modulo == 0))
506 {
507 /* null-terminated string */
508 alloc_size++;
509 list_count++;
510 }
511 }
512 is_first_row = true;
513 is_comment = false;
514 row_count = 0;
515 }
516 }
517
518 if (numof_lines > 0 && numof_lines != list_count)
519 {
520 std::cerr << "(!)handler_resources::load_texts() " <<
521 numof_lines << " exceptes lines, read " << list_count <<
522 " lines!" << std::endl;
523 throw std::runtime_error ("(!))handler_resources::load_texts() "
524 "bad number of lines!");
525 }
526
527 /*
528 * allocate memory require to create strings list
529 */
530 alloc_size += sizeof(char *) * list_count;
531 char *buffer = NULL;
532 try
533 {
534 buffer = new char[alloc_size];
535 }
536 catch (std::bad_alloc &)
537 {
538 std::cerr << "(!)handler_resources::load_texts() " <<
539 "not enough memory to allocate " <<
540 alloc_size << " bytes!" << std::endl;
541 throw;
542 }
543 char **list = (char**) buffer;
544 char *strs = buffer + sizeof(char *) * list_count;
545
546
547 offset = 0;
548 is_first_row = true;
549 is_comment = false;
550 row_count = 0;
551 char* source = filedata;
552 list_count = 0;
553 str_count = 0;
554 char *str_current = strs;
555 while (offset < filesize)
556 {
557 char c = filedata[offset++];
558 row_count++;
559 if (is_first_row && c == '#')
560 {
561 is_comment = true;
562 }
563 is_first_row = false;
564 if (c == '\n')
565 {
566 if (!is_comment)
567 {
568 /* do not copy the carriage return */
569 row_count--;
570 if (row_length > 0 && row_count >= row_length)
571 {
572 row_count = row_length;
573 }
574 for (Uint32 i = 0; i < row_count; i++)
575 {
576 char c = source[i];
577 if (upper_case && c >= 'a' && c <= 'z')
578 {
579 c = c - ('a' - 'A');
580 }
581 if (c < ' ')
582 {
583 c = ' ';
584 }
585 *(strs++) = c;
586 }
587 for (Uint32 i = row_count; i < row_length; i++)
588 {
589 *(strs++) = ' ';
590 }
591 str_count++;
592 if (modulo == 0 || (str_count % modulo == 0))
593 {
594 *(strs++) = '\0';
595 list[list_count++] = str_current;
596 str_current = strs;
597 }
598 }
599 is_first_row = true;
600 is_comment = false;
601 row_count = 0;
602 source = &filedata[offset];
603 }
604 }
605 delete[]filedata;
606 return list;
607 }
608
609 /**
610 * Allocate memory and load a file (filename with a language code)
611 * @param filename specified by path
612 * @param fsize pointer on the size of file which will be loaded
613 * @return a pointer to the file data
614 */
615 char *
loadfile_with_lang(const char * const filename,Uint32 * const fsize)616 handler_resources::loadfile_with_lang (const char *const filename, Uint32 * const fsize)
617 {
618 if(filename == NULL || strlen (filename) == 0)
619 {
620 std::cerr << "(!)handler_resources::loadfile_with_lang() " <<
621 "NULL string!" << std::endl;
622 throw std::ios_base::failure ("(!)handler_resources::loadfile_with_lang() "
623 "can't open a file!");
624 }
625 char* fname = new char[strlen (filename) + 1];
626 strcpy (fname, filename);
627 const char* lang = config_file->get_language ();
628 sprintf (fname, filename, lang);
629 if (is_verbose)
630 {
631 std::cout << "handler_resources::loadfile_with_lang() " <<
632 "file " << fname << " was loaded in memory" << std::endl;
633 }
634 char* data = load_file (fname, fsize);
635 delete[]fname;
636 return data;
637 }
638
639 /**
640 * Load a file in memory
641 * @param fname filename specified by path
642 */
643 char *
load_file(const char * fname)644 handler_resources::load_file (const char *fname)
645 {
646 return load_file (fname, &last_filesize_loaded);
647 }
648
649 /**
650 * Load a file in memory
651 * @param fname filename specified by path
652 * @param fsize pointer on the size of file which will be loaded
653 * return a pointer to the file data
654 */
655 char *
load_file(const char * fname,Uint32 * fsize)656 handler_resources::load_file (const char *fname, Uint32 * fsize)
657 {
658 /* locate a file under one of the data directories */
659 char *pname = locate_data_file (fname);
660
661 /* open the file */
662 #ifdef WIN32
663 Sint32 fhand = open (pname, O_RDONLY | O_BINARY, 0);
664 #else
665 Sint32 fhand = open (pname, O_RDONLY, 0);
666 #endif
667 if (fhand == -1)
668 {
669 std::cerr << "(!)handler_resources::load_file() " <<
670 "can't open file " << fname
671 << "; error: " << strerror (errno) << std::endl;
672 throw std::ios_base::failure ("(!)handler_resources::load_file() "
673 "can't open a file!");
674 }
675
676 /* read the size of the file */
677 struct stat sb;
678 if (fstat (fhand, &sb))
679 {
680 std::cerr << "(!)handler_resources::load_file() " <<
681 "can't stat file " << fname
682 << "strerror:" << strerror (errno) << std::endl;
683 throw std::ios_base::failure ("(!)handler_resources::load_file() "
684 "can't stat a file!");
685 }
686 /* save filesize */
687 (*fsize) = sb.st_size;
688
689 /* allocate memory require to load the filedata */
690 char *buffer = NULL;
691 try
692 {
693 buffer = new char[sb.st_size];
694 }
695 catch (std::bad_alloc &)
696 {
697 std::cerr << "(!)handler_resources::load_file() " <<
698 "not enough memory to allocate " <<
699 sb.st_size << " bytes!" << std::endl;
700 throw;
701 }
702
703 /* read the file */
704 if (read (fhand, buffer, sb.st_size) != sb.st_size)
705 {
706 std::cerr << "(!)handler_resources::load_file() " <<
707 "can't read file " << fname
708 << "strerror:" << strerror (errno) << std::endl;
709 throw std::ios_base::failure ("(!)handler_resources::load_file() "
710 "can't read a file!");
711 return NULL;
712 }
713
714 /* close the file */
715 close (fhand);
716 return buffer;
717 }
718
719 /**
720 * Return size last file loaded in memory
721 * @return the size of the last filesize previously
722 */
723 Uint32
get_filesize_loaded()724 handler_resources::get_filesize_loaded ()
725 {
726 return last_filesize_loaded;
727 }
728
729
730 void
set_filesize_loaded(Uint32 size)731 handler_resources::set_filesize_loaded (Uint32 size)
732 {
733 Uint32 i = size;
734 i++;
735 last_filesize_loaded = size;
736 }
737
738 char*
read_complete_file(const char * filename)739 handler_resources::read_complete_file (const char* filename )
740 {
741 std::ifstream file (filename, std::ios::ate);
742 if (! file.is_open () )
743 {
744 std::cerr << "(!)handler_ressources::read_complete_file()"
745 "can't open file '" << filename << "'" << std::endl;
746 //throw std::ios_base::failure ("(!)handler_ressources::read_complete_file() can't read a file!");
747 return NULL;
748 }
749 //Uint32 size = (Uint32) file.tellg();
750 std::ifstream::pos_type size = file.tellg();
751 //int filesize = (int)size;
752 //last_filesize_loaded = 1;
753 //last_filesize_loaded = 2;
754 //last_filesize_loaded = size;
755 char *buffer = NULL;
756 try
757 {
758 buffer = new char[size];
759 }
760 catch (std::bad_alloc &)
761 {
762 file.close();
763 std::cerr << "(!)handler_resources::read_complete_file() " <<
764 "not enough memory to allocate " <<
765 size << " bytes!" << std::endl;
766 throw;
767 }
768 file.seekg (0, std::ios::beg);
769 file.read (buffer, size);
770 file.close();
771 return buffer;
772 }
773
774 /**
775 * Load a precalculated sinus & cosinus table (1790 bytes <=> 895 values)
776 * 0 to 511 cosinus / 383 to 894 sinus
777 */
778 void
load_sinus()779 handler_resources::load_sinus ()
780 {
781 table_cosL = (Sint16 *) load_data (handler_resources::RESCOSLIST);
782 table_sinL = table_cosL + 383;
783
784 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
785 /* convert big endian values to little endian values */
786 Sint32 fsize = get_filesize_loaded ();
787 /* convert bytes = 16-bits words */
788 fsize = fsize / 2;
789 for (Sint32 i = 0; i < fsize; i++)
790 {
791 char *p = (char *) &table_cosL[i];
792 char a = p[0];
793 p[0] = p[1];
794 p[1] = a;
795 }
796 #endif
797 }
798
799 /**
800 * load scores table
801 */
802 char *
load_high_score_file()803 handler_resources::load_high_score_file ()
804 {
805 char* filedata = NULL;
806 try
807 {
808 filedata = load_file (fnamescore, &last_filesize_loaded);
809 }
810 catch (...)
811 {
812 std::cerr << "(!)handler_resources::load_high_score_file() " <<
813 "can't open the scores files!" << std::endl;
814 filedata = NULL;
815 }
816 return filedata;
817 }
818
819 /*
820 * Save scores table
821 * @param buffer
822 * @pram size
823 */
824 void
save_high_score_file(char * buffer,Uint32 size)825 handler_resources::save_high_score_file (char *buffer, Uint32 size)
826 {
827 size_t left;
828 ssize_t bytes_written;
829 #ifdef WIN32
830 /* set umask so that files are group-writable */
831 _umask (0002);
832 #else
833 umask (0002);
834 #endif
835 Sint32 fhand = open (fnamescore, O_WRONLY | O_CREAT, 00666);
836 if (fhand == -1)
837 {
838 fprintf (stderr,
839 "handler_resources::save_high_score_file(): file:%s / error:%s\n",
840 fnamescore, strerror (errno));
841 }
842 left = size;
843 while (left > 0)
844 {
845 #ifdef WIN32
846 bytes_written = _write (fhand, buffer + size - left, left);
847 #else
848 bytes_written = write (fhand, buffer + size - left, left);
849 if (bytes_written == -1)
850 {
851 std::cerr << "(!)handler_resources::save_high_score_file():" <<
852 " filename: " << fnamescore << "; error: " << strerror (errno) << std::endl;
853 close (fhand);
854 return;
855 }
856 left -= bytes_written;
857 }
858 #endif
859 if (close (fhand) == -1)
860 {
861 fprintf (stderr,
862 "handler_resources::save_high_score_file(): file:%s / error:%s\n",
863 fnamescore, strerror (errno));
864 }
865 else
866 {
867 if (is_verbose)
868 fprintf (stdout, "handler_resources::save_high_score_file(): "
869 "file:%s size:%i\n", fnamescore, size);
870 }
871 }
872
873 /**
874 * Precalculated cosinus and sinus table
875 */
876 const Sint16
877 handler_resources::cosinus360[720] =
878 { 0, 2, 4, 7, 9, 11, 13, 15, 18, 20, 22, 24, 26, 29, 31, 33, 35, 37, 39, 41,
879 43,
880 46, 48, 50, 52, 54, 56, 58, 60, 62, 63, 65, 67, 69, 71, 73, 75, 76, 78, 80,
881 82, 83, 85, 87, 88, 90, 91, 93, 94, 96, 97, 99, 100, 101, 103, 104, 105,
882 107,
883 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 119, 120, 121,
884 121, 122, 123, 123, 124, 124, 125, 125, 125, 126, 126, 126, 127, 127, 127,
885 127, 127, 127, 127, 127, 127, 127, 127, 126, 126, 126, 125, 125, 125, 124,
886 124, 123, 123, 122, 121, 121, 120, 119, 119, 118, 117, 116, 115, 114, 113,
887 112, 111, 110, 109, 108, 107, 105, 104, 103, 101, 100, 99, 97, 96, 94, 93,
888 91,
889 90, 88, 87, 85, 83, 82, 80, 78, 76, 75, 73, 71, 69, 67, 65, 64, 62, 60, 58,
890 56, 54, 52, 50, 48, 46, 43, 41, 39, 37, 35, 33, 31, 29, 26, 24, 22, 20, 18,
891 16, 13, 11, 9, 7, 4, 2, 0, -2, -4, -7, -9, -11, -13, -15, -18, -20, -22,
892 -24,
893 -26, -29, -31, -33, -35, -37, -39, -41, -43, -45, -48, -50, -52, -54, -56,
894 -58, -60, -62, -63, -65, -67, -69, -71, -73, -75, -76, -78, -80, -82, -83,
895 -85, -87, -88, -90, -91, -93, -94, -96, -97, -99, -100, -101, -103, -104,
896 -105, -106, -108, -109, -110, -111, -112, -113, -114, -115, -116, -117,
897 -118,
898 -119, -119, -120, -121, -121, -122, -123, -123, -124, -124, -125, -125,
899 -125,
900 -126, -126, -126, -127, -127, -127, -127, -127, -127, -127, -127, -127,
901 -127,
902 -127, -126, -126, -126, -125, -125, -125, -124, -124, -123, -123, -122,
903 -121,
904 -121, -120, -119, -119, -118, -117, -116, -115, -114, -113, -112, -111,
905 -110,
906 -109, -108, -107, -105, -104, -103, -101, -100, -99, -97, -96, -94, -93,
907 -91,
908 -90, -88, -87, -85, -83, -82, -80, -78, -76, -75, -73, -71, -69, -67, -65,
909 -64, -62, -60, -58, -56, -54, -52, -50, -48, -46, -43, -41, -39, -37, -35,
910 -33, -31, -29, -26, -24, -22, -20, -18, -16, -13, -11, -9, -7, -4, -2, 127,
911 127, 127, 127, 127, 127, 126, 126, 126, 125, 125, 125, 124, 124, 123, 123,
912 122, 121, 121, 120, 119, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110,
913 109, 108, 107, 105, 104, 103, 101, 100, 99, 97, 96, 94, 93, 91, 90, 88, 87,
914 85, 83, 82, 80, 78, 76, 75, 73, 71, 69, 67, 65, 64, 62, 60, 58, 56, 54, 52,
915 50, 48, 46, 43, 41, 39, 37, 35, 33, 31, 29, 26, 24, 22, 20, 18, 15, 13, 11,
916 9, 7, 4, 2, 0, -2, -4, -7, -9, -11, -13, -15, -18, -20, -22, -24, -26, -29,
917 -31, -33, -35, -37, -39, -41, -43, -45, -48, -50, -52, -54, -56, -58, -60,
918 -62, -63, -65, -67, -69, -71, -73, -75, -76, -78, -80, -82, -83, -85, -87,
919 -88, -90, -91, -93, -94, -96, -97, -99, -100, -101, -103, -104, -105, -107,
920 -108, -109, -110, -111, -112, -113, -114, -115, -116, -117, -118, -119,
921 -119,
922 -120, -121, -121, -122, -123, -123, -124, -124, -125, -125, -125, -126,
923 -126,
924 -126, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127,
925 -126,
926 -126, -126, -125, -125, -125, -124, -124, -123, -123, -122, -121, -121,
927 -120,
928 -119, -119, -118, -117, -116, -115, -114, -113, -112, -111, -110, -109,
929 -108,
930 -107, -105, -104, -103, -101, -100, -99, -97, -96, -94, -93, -91, -90, -88,
931 -87, -85, -83, -82, -80, -78, -76, -75, -73, -71, -69, -67, -65, -64, -62,
932 -60, -58, -56, -54, -52, -50, -48, -46, -43, -41, -39, -37, -35, -33, -31,
933 -29, -26, -24, -22, -20, -18, -16, -13, -11, -9, -7, -4, -2, 0, 2, 4, 7, 9,
934 11, 13, 15, 18, 20, 22, 24, 26, 29, 31, 33, 35, 37, 39, 41, 43, 45, 48, 50,
935 52, 54, 56, 58, 60, 62, 63, 65, 67, 69, 71, 73, 75, 76, 78, 80, 82, 83, 85,
936 87, 88, 90, 91, 93, 94, 96, 97, 99, 100, 101, 103, 104, 105, 106, 108, 109,
937 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 119, 120, 121, 121, 122,
938 123, 123, 124, 124, 125, 125, 125, 126, 126, 126, 127, 127, 127, 127, 127
939 };
940 const Sint16 *
941 handler_resources::zesinus360 = handler_resources::cosinus360 + 360;
942
943
944 const
945 Uint32
946 handler_resources::color_gradations[180] =
947 { 0x0400180, 0x0420290, 0x0440392, 0x0500494, 0x0600596, 0x0700698,
948 0x0800795, 0x0900893, 0x0A00990, 0x0A20A80, 0x0A40B70, 0x0A60C60,
949 0x0A80D50, 0x0AA0E40, 0x0AC0F30, 0x0AE1020, 0x0B01110, 0x0B21200,
950 0x0014080, 0x0024590, 0x0034A92, 0x0045094, 0x0056096, 0x0067097,
951 0x0078096, 0x0089093, 0x009A090, 0x00AA180, 0x00BA270, 0x00CA360,
952 0x00DA450, 0x00EA540, 0x00FA630, 0x010A720, 0x011A810, 0x012A900,
953 0x0408001, 0x0459002, 0x04A9203, 0x0509404, 0x0609605, 0x0709806,
954 0x0809507, 0x0909308, 0x0A19009, 0x0A2800A, 0x0A3700B, 0x0A4600C,
955 0x0A5500D, 0x0A6400E, 0x0A7300F, 0x0A82010, 0x0A91011, 0x0AA0012,
956 0x0002080, 0x0102190, 0x0202292, 0x0302394, 0x0402496, 0x0502598,
957 0x0602695, 0x0702793, 0x0802890, 0x0782980, 0x0702A90, 0x0602B92,
958 0x0502C94, 0x0402D96, 0x0302E98, 0x0202F95, 0x0102A93, 0x0002B92,
959 0x0104080, 0x0204590, 0x0304A92, 0x0405094, 0x0506096, 0x0607098,
960 0x0708095, 0x0809093, 0x090A090, 0x0A0A280, 0x0B0A470, 0x0C0A660,
961 0x0B0A850, 0x0A0AA40, 0x090AC30, 0x080AE20, 0x070B010, 0x060B210,
962 0x04080B0, 0x04590A0, 0x04A9290, 0x0509480, 0x0609670, 0x0709860,
963 0x0809550, 0x0909340, 0x0A09030, 0x0A18020, 0x0A27010, 0x0A36020,
964 0x0A45030, 0x0A54040, 0x0A63050, 0x0A72060, 0x0A81070, 0x0A90080,
965 0x0101080, 0x0181290, 0x0201492, 0x0281694, 0x0301896, 0x0381A98,
966 0x0401C95, 0x0451E93, 0x04A2080, 0x0502270, 0x0582460, 0x0602650,
967 0x0702840, 0x0782B30, 0x0802E20, 0x0853010, 0x08A3205, 0x0903600,
968 0x0404080, 0x0484890, 0x0504A91, 0x0605092, 0x0706093, 0x0807094,
969 0x0908093, 0x0889092, 0x080A090, 0x081A280, 0x082A670, 0x083A860,
970 0x084AA50, 0x085AC40, 0x086AE30, 0x087B020, 0x088B210, 0x089B405,
971 0x0458040, 0x04A9045, 0x040924A, 0x0509450, 0x0609655, 0x070985A,
972 0x0809562, 0x0909364, 0x0A09066, 0x0A1806A, 0x0A2706C, 0x0A36070,
973 0x0A45073, 0x0A54076, 0x0A6307A, 0x0A72080, 0x0A81085, 0x0A90590,
974 0x0407080, 0x0457890, 0x04A8091, 0x0508892, 0x0609093, 0x0709894,
975 0x080A093, 0x090A892, 0x0A0B090, 0x0A1B880, 0x0A2C070, 0x0A3B860,
976 0x0A4B050, 0x0A5A840, 0x0A6A030, 0x0A79820, 0x0A89010, 0x0A98805
977 };
978