1 /**
2  * @file script_page.c
3  * @brief Handle the displaying of the pages order in Windows shareware
4  *        version
5  * @created 2007-04-18
6  * @date 2012-08-26
7  * @author Laurent Cance
8  * @author Patrice Duhamel
9  * @author Bruno Ethvignot
10  */
11 /*
12  * copyright (c) 1998-2015 TLK Games all rights reserved
13  * $Id: script_page.c,v 1.15 2012/08/26 19:22:39 gurumeditation Exp $
14  *
15  * Powermanga is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * Powermanga is distributed in the hope that it will be useful, but
21  * WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
28  * MA  02110-1301, USA.
29  */
30 #include "config.h"
31 #include "powermanga.h"
32 #include "tools.h"
33 #include "config_file.h"
34 #include "log_recorder.h"
35 #ifdef SHAREWARE_VERSION
36 #ifdef WIN32
37 #include <objbase.h>
38 #include <basetsd.h>
39 #define   sprintf   _snwprintf
40 #else
41 #include <wchar.h>
42 #endif
43 #include <stdarg.h>
44 #include "script_page.h"
45 static Sint32 window_width = 1024;
46 static Sint32 window_height = 768;
47 static char *script_dirname = ".";
48 static bool is_16bits_dithering = FALSE;
49 static char sname[512];
50 
51 /**
52  * Locate a file under one of the data directories
53  * param filename The single filename
54  * @return Pointer to a malloc'd buffer containing the full pathname
55  */
56 static char *
script_locate_file(const char const * filename)57 script_locate_file (const char const *filename)
58 {
59   char *name, *pathname;
60   name = memory_allocation (strlen (script_dirname) + strlen (filename) + 1);
61   if (name == NULL)
62     {
63       TRACE_ERR ("not enough memory!");
64       return NULL;
65     }
66   sprintf (name, "%s%s", script_dirname, filename);
67   pathname = locate_data_file (name);
68   if (pathname == NULL)
69     {
70       TRACE_ERR ("'%s' file not found!", name);
71       return NULL;
72     }
73   free_memory (name);
74   return pathname;
75 }
76 
77 /**
78  * Initialize some values
79  * @param width Width of the main window
80  * @param height Hieght of the main windows
81  * @param dirname Name of directory which contains the files
82  */
83 void
script_initialize(Sint32 width,Sint32 height,char * dirname)84 script_initialize (Sint32 width, Sint32 height, char *dirname)
85 {
86   window_width = width;
87   window_height = height;
88   script_dirname = dirname;
89 }
90 
91 /**
92  * Enable the dithering
93  */
94 void
script_set_dithering(void)95 script_set_dithering (void)
96 {
97   is_16bits_dithering = TRUE;
98 }
99 
100 /**
101  * Load file for use as a font
102  * @param name
103  * @param fonte
104  * @return TRUE if it completed successfully or FALSE otherwise
105  */
106 static bool
script_open_font(char * name,struct Fonte * fonte)107 script_open_font (char *name, struct Fonte *fonte)
108 {
109   char *pathname;
110   pathname = script_locate_file (name);
111   if (pathname == NULL)
112     {
113       return NULL;
114     }
115   fonte->font = TTF_OpenFont (pathname, fonte->size);
116   if (fonte->font == NULL)
117     {
118       LOG_ERR ("TTF_OpenFont(%s) return %s", pathname, TTF_GetError ());
119       free_memory (pathname);
120       return FALSE;
121     }
122   LOG_INF ("TTF_OpenFont(%s) successful!", pathname);
123   free_memory (pathname);
124   /* set a rendering style of the loaded font if required */
125   if (fonte->style == TTF_STYLE_ITALIC)
126     {
127       TTF_SetFontStyle (fonte->font, TTF_STYLE_ITALIC);
128     }
129   if (fonte->style == TTF_STYLE_BOLD)
130     {
131       TTF_SetFontStyle (fonte->font, TTF_STYLE_BOLD);
132     }
133   return TRUE;
134 }
135 
136 /**
137  * @param str
138  * @return
139  */
140 static bool
isBEGIN(char * str)141 isBEGIN (char *str)
142 {
143   bool result = FALSE;
144   Sint32 n, nn;
145   nn = strlen (str);
146   n = 0;
147   while ((n < nn) && (!result))
148     {
149       if (str[n] == (char) '{')
150         {
151           result = TRUE;
152         }
153       n++;
154     }
155   return result;
156 }
157 
158 /**
159  * @param str
160  * @return
161  */
162 static bool
isEND(char * str)163 isEND (char *str)
164 {
165   Sint32 n, nn, res;
166   nn = strlen (str);
167   res = 0;
168   n = 0;
169   while ((n < nn) && (res == 0))
170     {
171       if (str[n] == (char) '}')
172         res = 1;
173       n++;
174     }
175 
176   return (res == 1);
177 }
178 
179 /**
180  * @param str
181  * @param m
182  * @return
183  */
184 static bool
match(char * str,char * m)185 match (char *str, char *m)
186 {
187   Sint32 res;
188   res = 0;
189   Uint32 n = 0;
190   while ((n < strlen (m)) && (res == 0))
191     {
192       if (str[n] != m[n])
193         res = 1;
194       n++;
195     }
196 
197   return (res == 0);
198 }
199 
200 
201 /**
202  *
203  * @param str
204  * @param c
205  * @return
206  */
207 static Sint32
car(char * str,char c)208 car (char *str, char c)
209 {
210   Sint32 n;
211   n = 0;
212   while (str[n] != c)
213     {
214       n++;
215     }
216   return n;
217 }
218 
219 /**
220  * @param str
221  * @param m
222  * @return
223  */
224 static bool
script_match_strings(char * str,char * m)225 script_match_strings (char *str, char *m)
226 {
227   Uint32 n;
228   Sint32 res;
229   n = 0;
230   res = 0;
231   while ((n < strlen (str)) && (res == 0))
232     {
233       if (match (&str[n], m))
234         {
235           res = 1;
236         }
237       n++;
238     }
239   return (res == 1);
240 }
241 
242 /**
243  * Read a string delimited by quotes
244  * @input str The string to check
245  * @return The string delimited by quotes
246  */
247 static char *
script_get_string(char * str)248 script_get_string (char *str)
249 {
250   Sint32 n, nn;
251   n = 0;
252   while (str[n] != (char) '"')
253     {
254       n++;
255     }
256   n++;
257   nn = 0;
258   while (str[n] != (char) '"')
259     {
260       sname[nn] = str[n];
261       n++;
262       nn++;
263     }
264   sname[nn] = '\0';
265   return sname;
266 }
267 
268 /**
269  * Parse the "FONTES" section
270  * @param f File structure pointer that identifies the stream to read
271  * @param fontename
272  * @param page
273  * @return TRUE if it completed successfully or FALSE otherwise
274  */
275 static bool
script_add_font_section(FILE * f,char * fontename,struct Page * page)276 script_add_font_section (FILE * f, char *fontename, struct Page *page)
277 {
278   Sint32 nfonte;
279   char *fname;
280   char str[256];
281   Sint32 res;
282   nfonte = page->nFONTES;
283   snprintf (page->FONTES[nfonte].name, 256, "%s", fontename);
284   page->FONTES[nfonte].OMBRAGE = 0;
285   page->FONTES[nfonte].DEGRADE = 0;
286   page->FONTES[nfonte].OUTLINE = 0;
287   page->FONTES[nfonte].font = NULL;
288   page->FONTES[nfonte].style = TTF_STYLE_NORMAL;
289   fgets (str, 256, f);
290   while (!isBEGIN (str))
291     {
292       fgets (str, 256, f);
293     }
294   res = 0;
295   while (!isEND (str))
296     {
297       fgets (str, 256, f);
298       if (script_match_strings (str, "FICHIER"))
299         {
300           fname = script_get_string (str);
301           res = 1;
302         }
303       if (script_match_strings (str, "OMBRAGE"))
304         {
305           page->FONTES[nfonte].OMBRAGE = 1;
306           sscanf (&str[car (str, '=') + 1], "(%d,%d)",
307                   &page->FONTES[nfonte].Ombrex, &page->FONTES[nfonte].Ombrey);
308 
309         }
310       if (script_match_strings (str, "SIZE"))
311         {
312           sscanf (&str[car (str, (char) '=') + 1], "%d",
313                   &page->FONTES[nfonte].size);
314         }
315       if (script_match_strings (str, "OUTLINE"))
316         {
317           sscanf (&str[car (str, (char) '=') + 1], "%d",
318                   &page->FONTES[nfonte].OUTLINE);
319         }
320       if (script_match_strings (str, "DEGRADE"))
321         {
322           page->FONTES[nfonte].DEGRADE = 1;
323           sscanf (&str[car (str, (char) '=') + 1], "(%d,%d,%d)/(%d,%d,%d)",
324                   &page->FONTES[nfonte].DEGRADE_HAUT.r,
325                   &page->FONTES[nfonte].DEGRADE_HAUT.g,
326                   &page->FONTES[nfonte].DEGRADE_HAUT.b,
327                   &page->FONTES[nfonte].DEGRADE_BAS.r,
328                   &page->FONTES[nfonte].DEGRADE_BAS.g,
329                   &page->FONTES[nfonte].DEGRADE_BAS.b);
330         }
331       if (script_match_strings (str, "SINUS"))
332         {
333           page->FONTES[nfonte].DEGRADE = 2;
334         }
335       if (script_match_strings (str, "ITALIQUE"))
336         {
337           page->FONTES[nfonte].style = TTF_STYLE_ITALIC;
338         }
339       if (script_match_strings (str, "GRAS"))
340         {
341           page->FONTES[nfonte].style = TTF_STYLE_BOLD;
342         }
343     }
344   if ((page->FONTES[nfonte].size != 0) && (res == 1))
345     {
346       sprintf (page->FONTES[nfonte].strfile, "%s", fname);
347       if (!script_open_font (fname, &page->FONTES[nfonte]))
348         {
349           LOG_ERR ("script_open_font(%s) failed!", fname);
350           return FALSE;
351         }
352       page->nFONTES++;
353     }
354   return TRUE;
355 }
356 
357 /**
358  * @param ptr
359  * @param x1
360  * @param y1
361  * @param x2
362  * @param y2
363  * @param sizex
364  * @param sizey
365  */
366 static void
script_recurs(char * ptr,Sint32 x1,Sint32 y1,Sint32 x2,Sint32 y2,Sint32 sizex,Sint32 sizey)367 script_recurs (char *ptr, Sint32 x1, Sint32 y1, Sint32 x2, Sint32 y2,
368                Sint32 sizex, Sint32 sizey)
369 {
370   Sint32 x, y, dx, dy, d;
371   Sint32 c, c1, c2, c3, c4;
372   dx = 1 + x2 - x1;
373   dy = 1 + y2 - y1;
374   if (dx > dy)
375     {
376       d = dx;
377     }
378   else
379     {
380       d = dy;
381     }
382   if ((dx > 1) && (dy > 1))
383     {
384       x = (x1 + x2) / 2;
385       y = y1;
386       c1 = (ptr[x1 + y1 * sizex] & 255);
387       c2 = (ptr[x2 + y1 * sizex] & 255);
388       c = (c1 + c2) / 2 + rand () % dx - dx / 2;
389       if (c < 0)
390         {
391           c = 0;
392         }
393       if (c > 255)
394         {
395           c = 255;
396         }
397       if (ptr[x + y * sizex] == 0)
398         {
399           ptr[x + y * sizex] = c;
400         }
401       x = (x1 + x2) / 2;
402       y = y2;
403       c1 = (ptr[x1 + y2 * sizex] & 255);
404       c2 = (ptr[x2 + y2 * sizex] & 255);
405       c = (c1 + c2) / 2 + rand () % dx - dx / 2;
406       if (c < 0)
407         c = 0;
408       if (c > 255)
409         {
410           c = 255;
411         }
412       if (ptr[x + y * sizex] == 0)
413         {
414           ptr[x + y * sizex] = c;
415         }
416       x = x1;
417       y = (y1 + y2) / 2;
418       c1 = (ptr[x1 + y1 * sizex] & 255);
419       c2 = (ptr[x1 + y2 * sizex] & 255);
420       c = (c1 + c2) / 2 + rand () % dy - dy / 2;
421       if (c < 0)
422         c = 0;
423       if (c > 255)
424         c = 255;
425       if (ptr[x + y * sizex] == 0)
426         ptr[x + y * sizex] = c;
427       x = x2;
428       y = (y1 + y2) / 2;
429       c1 = (ptr[x2 + y1 * sizex] & 255);
430       c2 = (ptr[x2 + y2 * sizex] & 255);
431       c = (c1 + c2) / 2 + rand () % dy - dy / 2;
432       if (c < 0)
433         {
434           c = 0;
435         }
436       if (c > 255)
437         {
438           c = 255;
439         }
440       if (ptr[x + y * sizex] == 0)
441         {
442           ptr[x + y * sizex] = c;
443         }
444       x = (x1 + x2) / 2;
445       y = (y1 + y2) / 2;
446       c1 = (ptr[x1 + y1 * sizex] & 255);
447       c2 = (ptr[x2 + y1 * sizex] & 255);
448       c3 = (ptr[x1 + y2 * sizex] & 255);
449       c4 = (ptr[x2 + y2 * sizex] & 255);
450       c = (c1 + c2 + c3 + c4) / 4 + rand () % d - d / 2;
451       if (c < 0)
452         {
453           c = 0;
454         }
455       if (c > 255)
456         {
457           c = 255;
458         }
459       if (ptr[x + y * sizex] == 0)
460         {
461           ptr[x + y * sizex] = c;
462         }
463       if ((dx > 2) && (dy > 2))
464         {
465           script_recurs (ptr, x1, y1, (x1 + x2) / 2, (y1 + y2) / 2, sizex,
466                          sizey);
467           script_recurs (ptr, (x1 + x2) / 2, y1, x2, (y1 + y2) / 2, sizex,
468                          sizey);
469           script_recurs (ptr, x1, (y1 + y2) / 2, (x1 + x2) / 2, y2, sizex,
470                          sizey);
471           script_recurs (ptr, (x1 + x2) / 2, (y1 + y2) / 2, x2, y2, sizex,
472                          sizey);
473         }
474     }
475 }
476 
477 
478 /**
479  *
480  * @param prt
481  * @param x1
482  * @param x2
483  * @param y
484  * @param sizex
485  * @param sizey
486  */
487 static void
script_recursx(char * ptr,Sint32 x1,Sint32 x2,Sint32 y,Sint32 sizex,Sint32 sizey)488 script_recursx (char *ptr, Sint32 x1, Sint32 x2, Sint32 y, Sint32 sizex,
489                 Sint32 sizey)
490 {
491   Sint32 x, dx;
492   Sint32 c, c1, c2;
493   dx = 1 + x2 - x1;
494   if (dx > 1)
495     {
496       x = (x1 + x2) / 2;
497       c1 = (ptr[x1 + y * sizex] & 255);
498       c2 = (ptr[x2 + y * sizex] & 255);
499       c = (c1 + c2) / 2 + rand () % dx - dx / 2;
500       if (c < 0)
501         {
502           c = 0;
503         }
504       if (c > 255)
505         {
506           c = 255;
507         }
508       if (ptr[x + y * sizex] == 0)
509         {
510           ptr[x + y * sizex] = c;
511         }
512       if (dx > 2)
513         {
514           script_recursx (ptr, x1, (x1 + x2) / 2, y, sizex, sizey);
515           script_recursx (ptr, (x1 + x2) / 2, x2, y, sizex, sizey);
516         }
517     }
518 }
519 
520 /**
521  *
522  * @param ptr
523  * @param y1
524  * @param y2
525  * @param x
526  * @param sizex
527  * @param sizey
528  */
529 static void
script_recursy(char * ptr,Sint32 y1,Sint32 y2,Sint32 x,Sint32 sizex,Sint32 sizey)530 script_recursy (char *ptr, Sint32 y1, Sint32 y2, Sint32 x, Sint32 sizex,
531                 Sint32 sizey)
532 {
533   Sint32 y, dy;
534   Sint32 c, c1, c2;
535 
536   dy = 1 + y2 - y1;
537 
538   if (dy > 1)
539     {
540       y = (y1 + y2) / 2;
541       c1 = (ptr[x + y1 * sizex] & 255);
542       c2 = (ptr[x + y2 * sizex] & 255);
543       c = (c1 + c2) / 2 + rand () % dy - dy / 2;
544       if (c < 0)
545         c = 0;
546       if (c > 255)
547         c = 255;
548       if (ptr[x + y * sizex] == 0)
549         ptr[x + y * sizex] = c;
550 
551       if (dy > 2)
552         {
553           script_recursy (ptr, y1, (y1 + y2) / 2, x, sizex, sizey);
554           script_recursy (ptr, (y1 + y2) / 2, y2, x, sizex, sizey);
555         }
556     }
557 }
558 
559 /**
560  * Parse a 'BITMAPS' section
561  * @param f File structure pointer that identifies the stream to read
562  * @param name
563  * @param page
564  * @return TRUE if it completed successfully or FALSE otherwise
565  */
566 static bool
script_add_bitmap_section(FILE * f,char * name,struct Page * page)567 script_add_bitmap_section (FILE * f, char *name, struct Page *page)
568 {
569   SDL_PixelFormat SDL_FormatRGB32A;
570   SDL_Surface *surface_tmp;
571   Sint32 nBM;
572   char *fname, *pathname;
573   char str[256];
574   Sint32 res;
575   Sint32 n1, n2;
576   Sint32 r, g, b;
577   char *ptr, *ptr2;
578   Sint32 lx, ly;
579   Sint32 c;
580   nBM = page->nBITMAPS;
581   snprintf (page->BITMAPS[nBM].name, 256, "%s", name);
582   memset (page->BITMAPS[nBM].strfile, 0, 256);
583   page->BITMAPS[nBM].OMBRAGE = 0;
584   page->BITMAPS[nBM].OUTLINE = 0;
585   page->BITMAPS[nBM].ptr = NULL;
586   page->BITMAPS[nBM].Surface = NULL;
587   page->BITMAPS[nBM].CLOUDS = 0;
588   fgets (str, 256, f);
589   while (!isBEGIN (str))
590     {
591       fgets (str, 256, f);
592     }
593   res = 0;
594   fgets (str, 256, f);
595   while (!isEND (str))
596     {
597       if (script_match_strings (str, "FICHIER"))
598         {
599           fname = script_get_string (str);
600           res = 1;
601         }
602 
603       if (script_match_strings (str, "CLOUDS"))
604         {
605           page->BITMAPS[nBM].CLOUDS = 1;
606           sscanf (&str[car (str, (char) '=') + 1], "(%d,%d,%d,%d,%d)", &r,
607                   &g, &b, &lx, &ly);
608 
609           page->BITMAPS[nBM].cloud[0] = r;
610           page->BITMAPS[nBM].cloud[1] = g;
611           page->BITMAPS[nBM].cloud[2] = b;
612           page->BITMAPS[nBM].cloud[3] = lx;
613           page->BITMAPS[nBM].cloud[4] = ly;
614 
615           res = 2;
616         }
617       if (script_match_strings (str, "OMBRAGE"))
618         {
619           page->BITMAPS[nBM].OMBRAGE = 1;
620           sscanf (&str[car (str, (char) '=') + 1], "(%d,%d)",
621                   &page->BITMAPS[nBM].Ombrex, &page->BITMAPS[nBM].Ombrey);
622 
623         }
624       if (script_match_strings (str, "OUTLINE"))
625         {
626           sscanf (&str[car (str, (char) '=') + 1], "%d",
627                   &page->BITMAPS[nBM].OUTLINE);
628         }
629       fgets (str, 256, f);
630     }
631   if (res == 1)
632     {
633       pathname = script_locate_file (fname);
634       if (pathname == NULL)
635         {
636           return FALSE;
637         }
638       SDL_FormatRGB32A =
639       {
640       NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24, 0x000000FF, 0x0000FF00,
641           0x00FF0000, 0xFF000000, 0, 0};
642       /* load bitmap and converted it in 32 bpp */
643       surface_tmp = IMG_Load (pathname);
644       if (surface_tmp == NULL)
645         {
646           LOG_ERR ("IMG_Load(%s) return %s", pathname, SDL_GetError ());
647           free_memory (pathname);
648           return FALSE;
649         }
650       free_memory (pathname);
651       page->BITMAPS[nBM].Surface =
652         SDL_ConvertSurface (surface_tmp, &SDL_FormatRGB32A, SDL_SWSURFACE);
653       page->BITMAPS[nBM].x = page->BITMAPS[nBM].Surface->w;
654       page->BITMAPS[nBM].y = page->BITMAPS[nBM].Surface->h;
655       page->BITMAPS[nBM].ptr = (char *) page->BITMAPS[nBM].Surface->pixels;
656       page->nBITMAPS++;
657     }
658   if (res == 2)
659     {
660       ptr2 = (char *) memory_allocation (lx * ly * 4);
661       if (ptr2 == NULL)
662         {
663           LOG_ERR ("not enough memory to alloc %i bytes!", lx * ly * 4);
664           return FALSE;
665         }
666       ptr = (char *) memory_allocation ((lx + 1) * (ly + 1));
667       if (ptr == NULL)
668         {
669           LOG_ERR ("not enough memory to alloc %i bytes!",
670                    (lx + 1) * (ly + 1));
671           return FALSE;
672         }
673       for (n1 = 0; n1 <= lx; n1++)
674         {
675           for (n2 = 0; n2 <= ly; n2++)
676             {
677               ptr[n1 + n2 * (lx + 1)] = 0;
678             }
679         }
680       ptr[0] = 128 + rand () % 127;
681       ptr[lx] = 128 + rand () % 127;
682       ptr[(lx + 1) * (ly) + 0] = ptr[lx];
683       script_recursx (ptr, 0, lx, 0, lx + 1, ly + 1);
684       script_recursy (ptr, 0, ly, 0, lx + 1, ly + 1);
685       for (n1 = 0; n1 <= lx; n1++)
686         {
687           ptr[n1 + (ly) * (lx + 1)] = ptr[n1];
688         }
689       for (n1 = 0; n1 <= ly; n1++)
690         {
691           ptr[lx + n1 * (lx + 1)] = ptr[(lx + 1) * n1];
692         }
693       script_recurs (ptr, 0, 0, lx, ly, lx + 1, ly + 1);
694       for (n1 = 0; n1 < lx; n1++)
695         {
696           for (n2 = 0; n2 < ly; n2++)
697             {
698               c = ptr[n1 + n2 * (lx + 1)] & 255;
699               ptr2[4 * (n1 + n2 * lx) + 0] = (r * c) / 255;
700               ptr2[4 * (n1 + n2 * lx) + 1] = (g * c) / 255;
701               ptr2[4 * (n1 + n2 * lx) + 2] = (b * c) / 255;
702             }
703         }
704       page->BITMAPS[nBM].x = lx;
705       page->BITMAPS[nBM].y = ly;
706       page->BITMAPS[nBM].ptr = ptr2;
707       page->nBITMAPS++;
708       free_memory (ptr);
709     }
710   return TRUE;
711 }
712 
713 /**
714  * Search a font from 'Page' structure
715  * @param font_name The font name (ie "FONTE0")
716  * @param page Pointer to a 'Page' structure
717  * @return Font index from 0 to n, otherwise -1 if font was not found
718  */
719 static Sint32
script_search_font(char * font_name,struct Page * page)720 script_search_font (char *font_name, struct Page *page)
721 {
722   Sint32 n, index;
723   index = -1;
724   n = 0;
725   while ((n < page->nFONTES) && (index == -1))
726     {
727       if (strcmp (font_name, page->FONTES[n].name) == 0)
728         {
729           index = n;
730         }
731       n++;
732     }
733   if (index == -1)
734     {
735       LOG_ERR ("\"%s\" font not found!", font_name);
736     }
737   return index;
738 }
739 
740 /**
741  * Search a bitmap from 'Page' structure
742  * @param bmp_name The bitmap name (ie "SCREENSHOT1")
743  * @param page Pointer to a 'Page' structure
744  * @return Bitmap index from 0 to n, otherwise -1 if bitmap was not found
745  */
746 static Sint32
script_search_bitmap(char * bmp_name,struct Page * page)747 script_search_bitmap (char *bmp_name, struct Page *page)
748 {
749   Sint32 n, index;
750   index = -1;
751   LOG_DBG ("bitmap name: %s", bmp_name);
752   n = 0;
753   while ((n < page->nBITMAPS) && (index == -1))
754     {
755       if (strcmp (bmp_name, page->BITMAPS[n].name) == 0)
756         {
757           index = n;
758         }
759       n++;
760     }
761   if (index == -1)
762     {
763       LOG_ERR ("\"$s\" bitmap not found!", bmp_name);
764     }
765   return index;
766 }
767 
768 /**
769  * Check if a string contains a quote char
770  * @param str The sting to check
771  * @return TRUE if the string contains a quote char, otherwise FALSE
772  */
773 static bool
script_check_quote(char * str)774 script_check_quote (char *str)
775 {
776   Sint32 index, g, length;
777   index = 0;
778   g = 0;
779   length = strlen (str);
780   while (index < length)
781     {
782       if (str[index] == (char) '"')
783         {
784           g++;
785         }
786       index++;
787     }
788   return (g == 1);
789 }
790 
791 /**
792  * Read a string from a 'TEXTE' section
793  * @param f File structure pointer that identifies the stream to read
794  * @return String pointer to string or NULL if alloc failed
795  */
796 static char *
script_read_string(FILE * f)797 script_read_string (FILE * f)
798 {
799   char ss[512];
800   char *sss;
801   Sint32 nn, nnn, nn2;
802   sss = (char *) memory_allocation (512);
803   if (sss == NULL)
804     {
805       return NULL;
806     }
807   fscanf (f, "%s", ss);
808   nn = 0;
809   nnn = strlen (ss);
810   while (nn < nnn - 1)
811     {
812       sss[nn] = ss[nn + 1];
813       nn++;
814     }
815   sss[nn] = (char) ' ';
816   nn++;
817   if (script_check_quote (ss))
818     {
819       fscanf (f, "%s", ss);
820       nnn = strlen (ss);
821       nn2 = 0;
822       while (nn2 < nnn)
823         {
824           sss[nn] = ss[nn2];
825           nn++;
826           nn2++;
827         }
828       sss[nn] = (char) ' ';
829       nn++;
830       while (!script_check_quote (ss))
831         {
832           fscanf (f, "%s", ss);
833           nnn = strlen (ss);
834           nn2 = 0;
835           while (nn2 < nnn)
836             {
837               sss[nn] = ss[nn2];
838               nn++;
839               nn2++;
840             }
841           sss[nn] = (char) ' ';
842           nn++;
843         }
844     }
845   nn = 0;
846   while (sss[nn] != (char) '"')
847     {
848       nn++;
849     }
850   sss[nn] = (char) '\0';
851   return sss;
852 }
853 
854 /**
855  * Read "COMPOSITION" section
856  * @param f File structure pointer that identifies the stream to read
857  */
858 static bool
script_read_composition_section(FILE * f,struct Page * page)859 script_read_composition_section (FILE * f, struct Page *page)
860 {
861   char str[256];
862   Sint32 n;
863   fscanf (f, "%s", str);
864   while (!isBEGIN (str))
865     {
866       fscanf (f, "%s", str);
867     }
868   n = 0;
869   fscanf (f, "%s", str);
870   while (!isEND (str))
871     {
872       if (script_match_strings (str, "MOSAIC"))
873         {
874           page->OPS[n].op = MOSAIQUE;
875           sscanf (&str[car (str, (char) '=') + 1], "%s", page->OPS[n].name);
876           fscanf (f, "%s", str);
877           sscanf (str, "(%d,%d)", &page->OPS[n].x, &page->OPS[n].y);
878           n++;
879         }
880       if (script_match_strings (str, "ETIRER"))
881         {
882           page->OPS[n].op = ETIRER;
883           sscanf (&str[car (str, (char) '=') + 1], "%s", page->OPS[n].name);
884           fscanf (f, "%s", str);
885           sscanf (str, "(%d,%d)", &page->OPS[n].x, &page->OPS[n].y);
886           n++;
887         }
888       if (script_match_strings (str, "TEXTE"))
889         {
890           page->OPS[n].op = TEXTE;
891           sscanf (&str[car (str, (char) '=') + 1], "%s", page->OPS[n].name);
892           fscanf (f, "%s", str);
893           sscanf (str, "(%d,%d)", &page->OPS[n].x, &page->OPS[n].y);
894           page->OPS[n].str = script_read_string (f);
895           if (page->OPS[n].str == NULL)
896             {
897               return FALSE;
898             }
899           n++;
900         }
901       /* coordinates of counter string */
902       if (script_match_strings (str, "COMPTEUR"))
903         {
904           page->OPS[n].op = COMPTEUR;
905           memset (page->OPS[n].name, 0, 512);
906           char tmp[256];
907           sscanf (&str[car (str, (char) '=') + 1], "%s", tmp);
908           sscanf (tmp, "(%d,%d)", &page->OPS[n].x, &page->OPS[n].y);
909           n++;
910         }
911       /* coordinates of sting of number of
912        * times the game has been launched */
913       if (script_match_strings (str, "NBLAUNCH"))
914         {
915           page->OPS[n].op = NBLAUNCH;
916           /* intiatlize number of times */
917           page->OPS[n].amp = 0;
918           sscanf (&str[car (str, (char) '=') + 1], "%s", page->OPS[n].name);
919           fscanf (f, "%s", str);
920           sscanf (str, "(%d,%d)", &page->OPS[n].x, &page->OPS[n].y);
921           n++;
922         }
923       if (script_match_strings (str, "FBITMAP"))
924         {
925           page->OPS[n].op = BITMAPFADE;
926           sscanf (&str[car (str, (char) '=') + 1], "%s", page->OPS[n].name);
927           fscanf (f, "%s", str);
928           sscanf (str, "(%d,%d)", &page->OPS[n].x, &page->OPS[n].y);
929           n++;
930         }
931       else if (script_match_strings (str, "BITMAP"))
932         {
933           page->OPS[n].op = BITMAP;
934           sscanf (&str[car (str, (char) '=') + 1], "%s", page->OPS[n].name);
935           fscanf (f, "%s", str);
936           sscanf (str, "(%d,%d)", &page->OPS[n].x, &page->OPS[n].y);
937           n++;
938         }
939       else if (script_match_strings (str, "ONDEOMBREE"))
940         {
941           page->OPS[n].op = ONDES2;
942           memset (page->OPS[n].name, 0, 512);
943           sscanf (&str[car (str, (char) '=') + 1], "(%d,%d)",
944                   &page->OPS[n].amp, &page->OPS[n].rayon);
945           fscanf (f, "%s", str);
946           sscanf (str, "(%d,%d)", &page->OPS[n].x, &page->OPS[n].y);
947           n++;
948         }
949       else if (script_match_strings (str, "ONDE"))
950         {
951           page->OPS[n].op = ONDES;
952           memset (page->OPS[n].name, 0, 512);
953           sscanf (&str[car (str, (char) '=') + 1], "(%d,%d)",
954                   &page->OPS[n].amp, &page->OPS[n].rayon);
955           n++;
956         }
957       else if (script_match_strings (str, "EMBOSS"))
958         {
959           page->OPS[n].op = EMBOSS;
960           memset (page->OPS[n].name, 0, 512);
961           sscanf (&str[car (str, (char) '=') + 1], "(%d,%d,%d)",
962                   &page->OPS[n].x, &page->OPS[n].y, &page->OPS[n].rayon);
963           fscanf (f, "%s", str);
964           sscanf (str, "(%d,%d,%d)", &page->OPS[n].rgb.r,
965                   &page->OPS[n].rgb.g, &page->OPS[n].rgb.b);
966           n++;
967         }
968       if (script_match_strings (str, "CARREDEGRADE"))
969         {
970           page->OPS[n].op = CARREDEGRADE;
971           memset (page->OPS[n].name, 0, 512);
972           sscanf (&str[car (str, '=') + 1], "COULEUR(%d,%d,%d)",
973                   &page->OPS[n].rgb.r, &page->OPS[n].rgb.g,
974                   &page->OPS[n].rgb.b);
975           fscanf (f, "%s", str);
976           sscanf (str, "(%d,%d)", &page->OPS[n].x, &page->OPS[n].y);
977           fscanf (f, "%s", str);
978           sscanf (str, "(%d,%d)", &page->OPS[n].lx, &page->OPS[n].ly);
979           n++;
980         }
981       fscanf (f, "%s", str);
982     }
983   page->nOPS = n;
984   return TRUE;
985 }
986 
987 /**
988  * Read the script file
989  * @param fname The filename specified by path
990  * @return
991  */
992 struct Page *
script_read_file(char * fname)993 script_read_file (char *fname)
994 {
995   bool read_file = TRUE;
996   char *pathname;
997   struct Page *PAGE;
998   FILE *f;
999   char str[512];
1000   PAGE = (struct Page *) memory_allocation (sizeof (struct Page));
1001   if (PAGE == NULL)
1002     {
1003       LOG_ERR ("not enough memory to allocate 'Page' structure");
1004       return NULL;
1005     }
1006   PAGE->nBITMAPS = 0;
1007   PAGE->nFONTES = 0;
1008   PAGE->nOPS = 0;
1009   pathname = script_locate_file (fname);
1010   if (pathname == NULL)
1011     {
1012       return NULL;
1013     }
1014   LOG_DBG ("filename = %s", fname);
1015   f = fopen (pathname, "rb");
1016   free_memory (pathname);
1017   if (f == NULL)
1018     {
1019       return NULL;
1020     }
1021   while (read_file)
1022     {
1023       fscanf (f, "%s", str);
1024       if (strcmp (str, "FONTES") == 0)
1025         {
1026           fscanf (f, "%s", str);
1027           while (!isBEGIN (str))
1028             {
1029               fscanf (f, "%s", str);
1030             }
1031 
1032           fscanf (f, "%s", str);
1033           while (!isEND (str))
1034             {
1035               if (!script_add_font_section (f, str, PAGE))
1036                 {
1037                   return FALSE;
1038                 }
1039               fscanf (f, "%s", str);
1040             }
1041         }
1042       if (strcmp (str, "BITMAPS") == 0)
1043         {
1044           fscanf (f, "%s", str);
1045           while (!isBEGIN (str))
1046             {
1047               fscanf (f, "%s", str);
1048             }
1049           fscanf (f, "%s", str);
1050           while (!isEND (str))
1051             {
1052               if (!script_add_bitmap_section (f, str, PAGE))
1053                 {
1054                   return NULL;
1055                 }
1056               fscanf (f, "%s", str);
1057             }
1058         }
1059       if (strcmp (str, "COMPOSITION") == 0)
1060         {
1061           if (!script_read_composition_section (f, PAGE))
1062             {
1063               return NULL;
1064             }
1065           read_file = FALSE;
1066         }
1067       if (strcmp (str, "END") == 0)
1068         {
1069           read_file = FALSE;
1070         }
1071       if (feof (f))
1072         {
1073           read_file = FALSE;
1074         }
1075     }
1076   fclose (f);
1077   return PAGE;
1078 }
1079 
1080 /**
1081  *
1082  * @param prt
1083  * @param sizex
1084  * @param sizey
1085  * @return
1086  */
1087 static char *
script_outline(char * ptr,Sint32 sizex,Sint32 sizey)1088 script_outline (char *ptr, Sint32 sizex, Sint32 sizey)
1089 {
1090   char *pp;
1091   char c;
1092   Sint32 n1, n2, n;
1093   pp = (char *) memory_allocation (sizex * sizey);
1094   if (pp == NULL)
1095     {
1096       return NULL;
1097     }
1098   for (n = 0; n < sizex * sizey; n++)
1099     {
1100       pp[n] = 0;
1101     }
1102   for (n1 = 1; n1 < sizex - 1; n1++)
1103     for (n2 = 1; n2 < sizey - 1; n2++)
1104       {
1105         if (ptr[n1 + n2 * sizex] != (char) 255)
1106           {
1107             c = 0;
1108             if (ptr[n1 + 1 + (n2 + 0) * sizex] != 0)
1109               {
1110                 c = 1;
1111               }
1112             if (ptr[n1 - 1 + (n2 + 0) * sizex] != 0)
1113               {
1114                 c = 1;
1115               }
1116             if (ptr[n1 + 0 + (n2 + 1) * sizex] != 0)
1117               {
1118                 c = 1;
1119               }
1120             if (ptr[n1 + 0 + (n2 - 1) * sizex] != 0)
1121               {
1122                 c = 1;
1123               }
1124             if (c == 0)
1125               {
1126                 pp[n1 + n2 * sizex] = 0;
1127               }
1128             else
1129               {
1130                 pp[n1 + n2 * sizex] = 128;
1131               }
1132           }
1133         else
1134           {
1135             pp[n1 + n2 * sizex] = 255;
1136           }
1137       }
1138   free_memory (ptr);
1139   return pp;
1140 }
1141 
1142 /**
1143  * Draw a string
1144  * @param prt
1145  * @param str
1146  * @param x
1147  * @param y
1148  * @param font
1149  * @param f
1150  * @return
1151  */
1152 Sint32
script_draw_string(char * ptr,char * str,Sint32 x,Sint32 y,struct Fonte * font,Sint32 f)1153 script_draw_string (char *ptr, char *str, Sint32 x, Sint32 y,
1154                     struct Fonte * font, Sint32 f)
1155 {
1156   Sint32 n;
1157   SDL_Surface *stext;
1158   char *tmp;
1159   Sint32 sizex, sizey;
1160   Sint32 px, py;
1161   char *psrc;
1162   Sint32 n1, n2;
1163   Sint32 c[4];
1164   Sint32 r[4];
1165   Sint32 g[4];
1166   Sint32 b[4];
1167   Sint32 r0, g0, b0;
1168   Sint32 adr, adr2;
1169   char *ptr2;
1170   Sint32 nn2;
1171   SDL_Color white = { 255, 255, 255, 0 };
1172   if (font->font == NULL)
1173     {
1174       LOG_ERR ("TTF_Font pointer is NULL!");
1175       return 0;
1176     }
1177   stext = TTF_RenderUTF8_Blended (font->font, str, white);
1178   if (stext == NULL)
1179     {
1180       LOG_ERR ("TTF_RenderUTF8_Blended(%s) return %s", ptr, SDL_GetError ());
1181       return 0;
1182     }
1183   sizex = stext->w + font->OUTLINE * 2;
1184   sizey = stext->h + font->OUTLINE * 2 * 4;
1185   tmp = (char *) memory_allocation (sizex * sizey);
1186   if (tmp == NULL)
1187     {
1188       return 0;
1189     }
1190   memset (tmp, 0, sizex * sizey);
1191   for (n = 0; n < sizex * sizey; n++)
1192     {
1193       tmp[n] = 0;
1194     }
1195   psrc = (char *) stext->pixels;
1196   for (py = 0; py < stext->h; py++)
1197     {
1198       for (px = 0; px < stext->w; px++)
1199         {
1200 
1201           tmp[(py + font->OUTLINE) * sizex + (px + font->OUTLINE)] =
1202             psrc[py * stext->pitch + px * 4 + 3];
1203         }
1204     }
1205   for (n = 0; n < font->OUTLINE; n++)
1206     {
1207       tmp = script_outline (tmp, sizex, sizey);
1208     }
1209   SDL_FreeSurface (stext);
1210   ptr2 = (char *) memory_allocation ((sizey / 2) * (sizex / 2) * 4);
1211   if (ptr2 == NULL)
1212     {
1213       return 0;
1214     }
1215 
1216   for (n2 = 0; n2 < sizey / 2; n2++)
1217     {
1218       adr2 = 4 * ((sizex / 2) * n2);
1219       adr = 4 * (x + window_width * (y + n2));
1220 
1221       for (n1 = 0; n1 < sizex / 2; n1++)
1222         {
1223           r0 = ptr[adr + 0] & 255;
1224           g0 = ptr[adr + 1] & 255;
1225           b0 = ptr[adr + 2] & 255;
1226           ptr2[adr2 + 0] = r0;
1227           ptr2[adr2 + 1] = g0;
1228           ptr2[adr2 + 2] = b0;
1229           adr2 += 4;
1230           adr += 4;
1231         }
1232     }
1233   for (n2 = 0; n2 < sizey / 2; n2++)
1234     {
1235       if ((y + n2 >= 0) && (y + n2 < window_height))
1236         for (n1 = 0; n1 < sizex / 2; n1++)
1237           {
1238             if ((x + n1 >= 0) && (x + n1 < window_width))
1239               {
1240                 adr = n1 * 2 + 0 + sizex * (n2 * 2 + 0);
1241                 c[0] = tmp[adr] & 255;
1242                 c[1] = tmp[adr + 1] & 255;
1243                 c[2] = tmp[adr + sizex] & 255;
1244                 c[3] = tmp[adr + sizex + 1] & 255;
1245                 adr2 = 4 * (n1 + (sizex / 2) * (n2));
1246                 for (n = 0; n < 4; n++)
1247                   {
1248                     if (c[n] == 0)
1249                       {
1250                         r[n] = ptr2[adr2 + 0] & 255;
1251                         g[n] = ptr2[adr2 + 1] & 255;
1252                         b[n] = ptr2[adr2 + 2] & 255;
1253                       }
1254                     else if (c[n] == 128)
1255                       {
1256                         if (f == 1)
1257                           {
1258                             r[n] = (ptr2[adr2 + 0] & 255) >> 1;
1259                             g[n] = (ptr2[adr2 + 1] & 255) >> 1;
1260                             b[n] = (ptr2[adr2 + 2] & 255) >> 1;
1261                           }
1262                         else
1263                           {
1264                             /* outline */
1265                             r[n] = 0;
1266                             g[n] = 0;
1267                             b[n] = 0;
1268                           }
1269                       }
1270                     else
1271                       {
1272                         if (f == 1)
1273                           {
1274                             r[n] = (ptr2[adr2 + 0] & 255) >> 1;
1275                             g[n] = (ptr2[adr2 + 1] & 255) >> 1;
1276                             b[n] = (ptr2[adr2 + 2] & 255) >> 1;
1277                           }
1278                         else
1279                           {
1280 
1281                             if (font->DEGRADE == 2)
1282                               {
1283                                 nn2 =
1284                                   (Sint32) (n2 + 7 * sin (n1 * 3.14159 / 90));
1285                                 if (nn2 > sizey / 2)
1286                                   {
1287                                     nn2 = sizey / 2;
1288                                   }
1289                                 if (nn2 < 0)
1290                                   {
1291                                     nn2 = 0;
1292                                   }
1293                               }
1294                             else
1295                               {
1296                                 nn2 = n2;
1297                               }
1298                             r[n] =
1299                               font->DEGRADE_HAUT.r +
1300                               nn2 * (font->DEGRADE_BAS.r -
1301                                      font->DEGRADE_HAUT.r) / ((sizey /
1302                                                                2) + 1);
1303                             g[n] =
1304                               font->DEGRADE_HAUT.g +
1305                               nn2 * (font->DEGRADE_BAS.g -
1306                                      font->DEGRADE_HAUT.g) / ((sizey /
1307                                                                2) + 1);
1308                             b[n] =
1309                               font->DEGRADE_HAUT.b +
1310                               nn2 * (font->DEGRADE_BAS.b -
1311                                      font->DEGRADE_HAUT.b) / ((sizey /
1312                                                                2) + 1);
1313                           }
1314 
1315                       }
1316                   }
1317 
1318                 r0 = (r[0] + r[1] + r[2] + r[3]) / 4;
1319                 g0 = (g[0] + g[1] + g[2] + g[3]) / 4;
1320                 b0 = (b[0] + b[1] + b[2] + b[3]) / 4;
1321 
1322                 ptr[4 * (x + n1 + window_width * (y + n2)) + 0] = (char) r0;
1323                 ptr[4 * (x + n1 + window_width * (y + n2)) + 1] = (char) g0;
1324                 ptr[4 * (x + n1 + window_width * (y + n2)) + 2] = (char) b0;
1325 
1326               }
1327           }
1328     }
1329   free_memory (ptr2);
1330   free_memory (tmp);
1331   return (sizex / 2);
1332 }
1333 
1334 /**
1335  * Draw rectangle
1336  * @param ptr
1337  * @param x
1338  * @param y
1339  * @param lx
1340  * @param ly
1341  * @param r
1342  * @param g
1343  * @param b
1344  */
1345 void
script_draw_rectangle(char * ptr,Sint32 x,Sint32 y,Sint32 lx,Sint32 ly,Sint32 r,Sint32 g,Sint32 b)1346 script_draw_rectangle (char *ptr, Sint32 x, Sint32 y, Sint32 lx, Sint32 ly,
1347                        Sint32 r, Sint32 g, Sint32 b)
1348 {
1349   Sint32 n1, n2;
1350   float s;
1351   Sint32 r0, g0, b0;
1352   Sint32 top, bottom, left, right;
1353   Sint32 ss;
1354   ss = 24;
1355   for (n1 = 0; n1 < ly; n1++)
1356     {
1357       if ((y + n1 >= 0) && (y + n1 < window_height))
1358         for (n2 = 0; n2 < lx; n2++)
1359           {
1360 
1361             if ((x + n2 >= 0) && (x + n2 < window_width))
1362               {
1363 
1364                 top = n1 - ss;
1365                 bottom = n1 + ss;
1366                 left = n2 - ss;
1367                 right = n2 + ss;
1368 
1369                 if (right >= lx)
1370                   right = lx - 1;
1371                 if (left < 0)
1372                   left = 0;
1373                 if (top < 0)
1374                   top = 0;
1375                 if (bottom >= ly)
1376                   bottom = ly - 1;
1377 
1378                 s =
1379                   ((float) ((right - left) * (bottom - top)) -
1380                    ss * ss * 2) / (ss * ss * 2);
1381                 if (s > 1)
1382                   s = 1;
1383                 if (s < 0)
1384                   s = 0;
1385                 s = s * s;
1386 
1387                 r0 = ptr[4 * (x + n2 + (y + n1) * window_width) + 0] & 255;
1388                 g0 = ptr[4 * (x + n2 + (y + n1) * window_width) + 1] & 255;
1389                 b0 = ptr[4 * (x + n2 + (y + n1) * window_width) + 2] & 255;
1390 
1391                 r0 = (Sint32) (r * s + (1 - s) * r0);
1392                 g0 = (Sint32) (g * s + (1 - s) * g0);
1393                 b0 = (Sint32) (b * s + (1 - s) * b0);
1394 
1395 
1396                 ptr[4 * (x + n2 + (y + n1) * window_width) + 0] = r0;
1397                 ptr[4 * (x + n2 + (y + n1) * window_width) + 1] = g0;
1398                 ptr[4 * (x + n2 + (y + n1) * window_width) + 2] = b0;
1399 
1400               }
1401           }
1402     }
1403 }
1404 
1405 /**
1406  *
1407  * @param prt
1408  * @param x
1409  * @param y
1410  * @param lx
1411  * @param ly
1412  * @param im
1413  */
1414 void
script_draw_rectangleBitmap(char * ptr,Sint32 x,Sint32 y,Sint32 lx,Sint32 ly,char * im)1415 script_draw_rectangleBitmap (char *ptr, Sint32 x, Sint32 y, Sint32 lx,
1416                              Sint32 ly, char *im)
1417 {
1418   Sint32 n1, n2;
1419   float s;
1420   Sint32 r0, g0, b0;
1421   Sint32 top, bottom, left, right;
1422   Sint32 r, g, b;
1423   Sint32 ss;
1424 
1425   ss = (Sint32) (sqrt (lx * lx + ly * ly) / 10);
1426 
1427 
1428   for (n1 = 0; n1 < ly; n1++)
1429     {
1430       if ((y + n1 >= 0) && (y + n1 < window_height))
1431         for (n2 = 0; n2 < lx; n2++)
1432           {
1433 
1434             if ((x + n2 >= 0) && (x + n2 < window_width))
1435               {
1436 
1437                 top = n1 - ss;
1438                 bottom = n1 + ss;
1439                 left = n2 - ss;
1440                 right = n2 + ss;
1441 
1442                 if (right >= lx)
1443                   right = lx - 1;
1444                 if (left < 0)
1445                   left = 0;
1446                 if (top < 0)
1447                   top = 0;
1448                 if (bottom >= ly)
1449                   bottom = ly - 1;
1450 
1451                 s =
1452                   ((float) ((right - left) * (bottom - top)) -
1453                    ss * ss * 2) / (ss * ss * 2);
1454                 if (s > 1)
1455                   s = 1;
1456                 if (s < 0)
1457                   s = 0;
1458                 s = s * s;
1459 
1460                 r0 = ptr[4 * (x + n2 + (y + n1) * window_width) + 0] & 255;
1461                 g0 = ptr[4 * (x + n2 + (y + n1) * window_width) + 1] & 255;
1462                 b0 = ptr[4 * (x + n2 + (y + n1) * window_width) + 2] & 255;
1463 
1464                 r = im[4 * (n1 * lx + n2) + 0] & 255;
1465                 g = im[4 * (n1 * lx + n2) + 1] & 255;
1466                 b = im[4 * (n1 * lx + n2) + 2] & 255;
1467 
1468                 r0 = (Sint32) (r * s + (1 - s) * r0);
1469                 g0 = (Sint32) (g * s + (1 - s) * g0);
1470                 b0 = (Sint32) (b * s + (1 - s) * b0);
1471 
1472 
1473                 ptr[4 * (x + n2 + (y + n1) * window_width) + 0] = r0;
1474                 ptr[4 * (x + n2 + (y + n1) * window_width) + 1] = g0;
1475                 ptr[4 * (x + n2 + (y + n1) * window_width) + 2] = b0;
1476 
1477               }
1478 
1479           }
1480     }
1481 }
1482 
1483 static char dither16[5][2][2] =
1484   { {{1, 1}, {1, 1}}, {{1, 1}, {0, 1}}, {{1, 0}, {0, 1}}, {{1, 0}, {0, 0}},
1485   {{0, 0}, {0, 0}} };
1486 /**
1487  *
1488  * @param ptr
1489  * @param x
1490  * @param y
1491  * @param lx
1492  * @param ly
1493  * @param ss
1494  */
1495 static void
script_draw_shadow_rectangle(char * ptr,Sint32 x,Sint32 y,Sint32 lx,Sint32 ly,Sint32 ss)1496 script_draw_shadow_rectangle (char *ptr, Sint32 x, Sint32 y, Sint32 lx,
1497                               Sint32 ly, Sint32 ss)
1498 {
1499   Sint32 n1, n2;
1500   float s;
1501   Sint32 r0, g0, b0;
1502   Sint32 r, g, b;
1503   Sint32 top, bottom, left, right;
1504   for (n1 = 0; n1 < ly; n1++)
1505     {
1506       if ((y + n1 >= 0) && (y + n1 < window_height))
1507         for (n2 = 0; n2 < lx; n2++)
1508           {
1509             if ((x + n2 >= 0) && (x + n2 < window_width))
1510               {
1511                 top = n1 - ss;
1512                 bottom = n1 + ss;
1513                 left = n2 - ss;
1514                 right = n2 + ss;
1515                 if (right >= lx)
1516                   {
1517                     right = lx - 1;
1518                   }
1519                 if (left < 0)
1520                   {
1521                     left = 0;
1522                   }
1523                 if (top < 0)
1524                   {
1525                     top = 0;
1526                   }
1527                 if (bottom >= ly)
1528                   {
1529                     bottom = ly - 1;
1530                   }
1531                 s =
1532                   ((float) ((right - left) * (bottom - top)) -
1533                    ss * ss * 2) / (ss * ss * 2);
1534                 if (s > 1)
1535                   {
1536                     s = 1;
1537                   }
1538                 if (s < 0)
1539                   {
1540                     s = 0;
1541                   }
1542                 s = s * s;
1543                 r0 = ptr[4 * (x + n2 + (y + n1) * window_width) + 0] & 255;
1544                 g0 = ptr[4 * (x + n2 + (y + n1) * window_width) + 1] & 255;
1545                 b0 = ptr[4 * (x + n2 + (y + n1) * window_width) + 2] & 255;
1546                 r = (Sint32) (1 - s / 2) * r0;
1547                 g = (Sint32) (1 - s / 2) * g0;
1548                 b = (Sint32) (1 - s / 2) * b0;
1549                 if (is_16bits_dithering)
1550                   {
1551                     r0 = r & 7;
1552                     if (r0 > 4)
1553                       r0 = 4;
1554                     r0 = dither16[4 - r0][x & 1][y & 1];
1555                     r = ((r >> 3) + r0) << 3;
1556                     if (r > 255)
1557                       r = 255;
1558                     g0 = g & 3;
1559                     g0 = dither16[4 - g0][x & 1][y & 1];
1560                     g = ((g >> 2) + g0) << 2;
1561                     if (g > 255)
1562                       g = 255;
1563                     b0 = b & 7;
1564                     if (b0 > 4)
1565                       b0 = 4;
1566                     b0 = dither16[4 - b0][x & 1][y & 1];
1567                     b = ((b >> 3) + b0) << 3;
1568                     if (b > 255)
1569                       b = 255;
1570                   }
1571                 ptr[4 * (x + n2 + (y + n1) * window_width) + 0] = r;
1572                 ptr[4 * (x + n2 + (y + n1) * window_width) + 1] = g;
1573                 ptr[4 * (x + n2 + (y + n1) * window_width) + 2] = b;
1574               }
1575           }
1576     }
1577 }
1578 
1579 /**
1580  *
1581  * @param n1
1582  * @param n2
1583  * @param amp
1584  * @param rayon
1585  * @param rmax
1586  * @return
1587  */
1588 static float
script_wave_heights(Sint32 n1,Sint32 n2,Sint32 amp,Sint32 rayon,float rmax)1589 script_wave_heights (Sint32 n1, Sint32 n2, Sint32 amp, Sint32 rayon,
1590                      float rmax)
1591 {
1592   float r, a, aa;
1593   r =
1594     (float) sqrt ((n1 - (window_width / 2)) * (n1 - (window_width / 2)) +
1595                   (n2 - (window_height / 2)) * (n2 -
1596                                                 (window_height / 2))) / rmax;
1597   if (r > 1)
1598     {
1599       r = 1;
1600     }
1601   if (r < 0)
1602     {
1603       r = 0;
1604     }
1605   a = amp * (1 - r);
1606   aa = ((float) sin (3.14159 * rayon * r) + 1) / 2;
1607   return a * aa;
1608 }
1609 
1610 
1611 /**
1612  * Generate the page
1613  * @param page Pointer to a 'Page' structure
1614  * @return Pointer to a SDL_Surface structure
1615  */
1616 SDL_Surface *
script_generate_page(struct Page * page)1617 script_generate_page (struct Page * page)
1618 {
1619   Sint32 n, nn, x, y, lx, ly, x0, y0;
1620   char *ptr, *ptr2, *ptr3;
1621   char *bm;
1622   Sint32 len;
1623   float f;
1624   SDL_Surface *Surface;
1625 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1626   Surface =
1627     SDL_CreateRGBSurface (SDL_SWSURFACE, window_width, window_height, 32,
1628                           0x000000FF, 0x0000FF00, 0x00FF0000, 0x000000FF);
1629 #else
1630   Surface =
1631     SDL_CreateRGBSurface (SDL_SWSURFACE, window_width, window_height, 32,
1632                           0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
1633 #endif
1634   if (Surface == NULL)
1635     {
1636       LOG_ERR ("SDL_CreateRGBSurface() return %s", SDL_GetError ());
1637       return NULL;
1638     }
1639   ptr = (char *) Surface->pixels;
1640   for (n = 0; n < page->nOPS; n++)
1641     {
1642       if (page->OPS[n].op == MOSAIQUE)
1643         {
1644           nn = script_search_bitmap (page->OPS[n].name, page);
1645           if (nn == -1)
1646             {
1647               LOG_ERR ("script_search_bitmap() failed!");
1648               return NULL;
1649             }
1650           bm = page->BITMAPS[nn].ptr;
1651           lx = page->BITMAPS[nn].x;
1652           ly = page->BITMAPS[nn].y;
1653           x0 = page->OPS[n].x;
1654           y0 = page->OPS[n].y;
1655           for (x = 0; x < window_width; x++)
1656             for (y = 0; y < window_height; y++)
1657               {
1658                 ptr[4 * (x + y * window_width) + 0] =
1659                   bm[4 * (((x0 + x) % lx) + ((y0 + y) % ly) * lx) + 0];
1660                 ptr[4 * (x + y * window_width) + 1] =
1661                   bm[4 * (((x0 + x) % lx) + ((y0 + y) % ly) * lx) + 1];
1662                 ptr[4 * (x + y * window_width) + 2] =
1663                   bm[4 * (((x0 + x) % lx) + ((y0 + y) % ly) * lx) + 2];
1664 
1665               }
1666         }
1667 
1668       if (page->OPS[n].op == ETIRER)
1669         {
1670           nn = script_search_bitmap (page->OPS[n].name, page);
1671           if (nn == -1)
1672             {
1673               LOG_ERR ("script_search_bitmap() failed!");
1674               return NULL;
1675             }
1676           bm = page->BITMAPS[nn].ptr;
1677           lx = page->BITMAPS[nn].x;
1678           ly = page->BITMAPS[nn].y;
1679           x0 = page->OPS[n].x;
1680           y0 = page->OPS[n].y;
1681           float fx, fy, xx, yy;
1682           Sint32 r0, g0, b0;
1683           Sint32 r1, g1, b1;
1684           Sint32 r2, g2, b2;
1685           Sint32 r3, g3, b3;
1686           Sint32 r00, g00, b00;
1687           Sint32 r01, g01, b01;
1688           Sint32 r, g, b;
1689           float incx, incy;
1690 
1691           incx = (float) (lx - 1) / window_width;
1692           incy = (float) (ly - 1) / window_height;
1693 
1694           fy = 0;
1695           for (y = 0; y < window_height; y++)
1696             {
1697               fx = 0;
1698               for (x = 0; x < window_width; x++)
1699                 {
1700                   xx = fx - (int) fx;
1701                   yy = fy - (int) fy;
1702 
1703                   r0 =
1704                     (bm[4 * ((x0 + (int) fx) + (y0 + (int) fy) * lx) + 0] &
1705                      255);
1706                   g0 =
1707                     (bm[4 * ((x0 + (int) fx) + (y0 + (int) fy) * lx) + 1] &
1708                      255);
1709                   b0 =
1710                     (bm[4 * ((x0 + (int) fx) + (y0 + (int) fy) * lx) + 2] &
1711                      255);
1712 
1713                   r1 =
1714                     (bm[4 * ((x0 + 1 + (int) fx) + (y0 + (int) fy) * lx) + 0]
1715                      & 255);
1716                   g1 =
1717                     (bm[4 * ((x0 + 1 + (int) fx) + (y0 + (int) fy) * lx) + 1]
1718                      & 255);
1719                   b1 =
1720                     (bm[4 * ((x0 + 1 + (int) fx) + (y0 + (int) fy) * lx) + 2]
1721                      & 255);
1722 
1723                   r2 =
1724                     (bm[4 * ((x0 + (int) fx) + (y0 + 1 + (int) fy) * lx) + 0]
1725                      & 255);
1726                   g2 =
1727                     (bm[4 * ((x0 + (int) fx) + (y0 + 1 + (int) fy) * lx) + 1]
1728                      & 255);
1729                   b2 =
1730                     (bm[4 * ((x0 + (int) fx) + (y0 + 1 + (int) fy) * lx) + 2]
1731                      & 255);
1732 
1733                   r3 =
1734                     (bm
1735                      [4 * ((x0 + 1 + (int) fx) + (y0 + 1 + (int) fy) * lx) +
1736                       0] & 255);
1737                   g3 =
1738                     (bm
1739                      [4 * ((x0 + 1 + (int) fx) + (y0 + 1 + (int) fy) * lx) +
1740                       1] & 255);
1741                   b3 =
1742                     (bm
1743                      [4 * ((x0 + 1 + (int) fx) + (y0 + 1 + (int) fy) * lx) +
1744                       2] & 255);
1745 
1746                   r00 = (Sint32) (r0 + xx * (r1 - r0));
1747                   g00 = (Sint32) (g0 + xx * (g1 - g0));
1748                   b00 = (Sint32) (b0 + xx * (b1 - b0));
1749 
1750                   r01 = (Sint32) (r2 + xx * (r3 - r2));
1751                   g01 = (Sint32) (g2 + xx * (g3 - g2));
1752                   b01 = (Sint32) (b2 + xx * (b3 - b2));
1753 
1754                   r = (Sint32) (r00 + yy * (r01 - r00));
1755                   g = (Sint32) (g00 + yy * (g01 - g00));
1756                   b = (Sint32) (b00 + yy * (b01 - b00));
1757 
1758                   if (is_16bits_dithering)
1759                     {
1760                       r0 = r & 7;
1761                       if (r0 > 4)
1762                         r0 = 4;
1763                       r0 = dither16[4 - r0][x & 1][y & 1];
1764                       r = ((r >> 3) + r0) << 3;
1765                       if (r > 255)
1766                         r = 255;
1767                       g0 = g & 3;
1768                       g0 = dither16[4 - g0][x & 1][y & 1];
1769                       g = ((g >> 2) + g0) << 2;
1770                       if (g > 255)
1771                         g = 255;
1772                       b0 = b & 7;
1773                       if (b0 > 4)
1774                         b0 = 4;
1775                       b0 = dither16[4 - b0][x & 1][y & 1];
1776                       b = ((b >> 3) + b0) << 3;
1777                       if (b > 255)
1778                         b = 255;
1779                     }
1780 
1781                   ptr[4 * (x + y * window_width) + 0] = r;
1782                   ptr[4 * (x + y * window_width) + 1] = g;
1783                   ptr[4 * (x + y * window_width) + 2] = b;
1784 
1785                   fx += incx;
1786                 }
1787               fy += incy;
1788             }
1789         }
1790       if (page->OPS[n].op == BITMAP)
1791         {
1792           nn = script_search_bitmap (page->OPS[n].name, page);
1793           if (nn == -1)
1794             {
1795               LOG_ERR ("script_search_bitmap() failed!");
1796               return NULL;
1797             }
1798           bm = page->BITMAPS[nn].ptr;
1799           lx = page->BITMAPS[nn].x;
1800           ly = page->BITMAPS[nn].y;
1801           if (page->BITMAPS[nn].OMBRAGE == 1)
1802             {
1803               x0 = page->OPS[n].x + page->BITMAPS[nn].Ombrex * 3;
1804               y0 = page->OPS[n].y + page->BITMAPS[nn].Ombrey * 3;
1805               script_draw_shadow_rectangle (ptr, x0, y0, lx, ly, 6);
1806             }
1807           x0 = page->OPS[n].x;
1808           y0 = page->OPS[n].y;
1809           Sint32 pr, pv, pb;
1810           float pa;
1811           for (x = 0; x < lx; x++)
1812             for (y = 0; y < ly; y++)
1813               {
1814                 pa = (unsigned char) bm[4 * (x + y * lx) + 3] / 255.0f;
1815 
1816                 pr =
1817                   ((unsigned char)
1818                    ptr[4 * (x0 + x + (y0 + y) * window_width) +
1819                        0]) * (Sint32) (1.0f - pa) +
1820                   ((unsigned char) bm[4 * (x + y * lx) + 0]) * (Sint32) pa;
1821                 pv =
1822                   ((unsigned char)
1823                    ptr[4 * (x0 + x + (y0 + y) * window_width) +
1824                        1]) * (Sint32) (1.0f - pa) +
1825                   ((unsigned char) bm[4 * (x + y * lx) + 1]) * (Sint32) pa;
1826                 pb =
1827                   ((unsigned char)
1828                    ptr[4 * (x0 + x + (y0 + y) * window_width) +
1829                        2]) * (Sint32) (1.0f - pa) +
1830                   ((unsigned char) bm[4 * (x + y * lx) + 2]) * (Sint32) pa;
1831 
1832                 ptr[4 * (x0 + x + (y0 + y) * window_width) + 0] = pr;
1833                 ptr[4 * (x0 + x + (y0 + y) * window_width) + 1] = pv;
1834                 ptr[4 * (x0 + x + (y0 + y) * window_width) + 2] = pb;
1835               }
1836 
1837           if (page->BITMAPS[nn].OUTLINE == 1)
1838             {
1839               x0 = page->OPS[n].x;
1840               y0 = page->OPS[n].y;
1841               for (x = -1; x <= lx; x++)
1842                 {
1843                   y = -1;
1844                   ptr[4 * (x0 + x + (y0 + y) * window_width) + 0] = 255;
1845                   ptr[4 * (x0 + x + (y0 + y) * window_width) + 1] = 255;
1846                   ptr[4 * (x0 + x + (y0 + y) * window_width) + 2] = 255;
1847                   y = ly;
1848                   ptr[4 * (x0 + x + (y0 + y) * window_width) + 0] = 255;
1849                   ptr[4 * (x0 + x + (y0 + y) * window_width) + 1] = 255;
1850                   ptr[4 * (x0 + x + (y0 + y) * window_width) + 2] = 255;
1851                 }
1852               for (y = 0; y <= ly; y++)
1853                 {
1854                   x = -1;
1855                   ptr[4 * (x0 + x + (y0 + y) * window_width) + 0] = 255;
1856                   ptr[4 * (x0 + x + (y0 + y) * window_width) + 1] = 255;
1857                   ptr[4 * (x0 + x + (y0 + y) * window_width) + 2] = 255;
1858                   x = lx;
1859                   ptr[4 * (x0 + x + (y0 + y) * window_width) + 0] = 255;
1860                   ptr[4 * (x0 + x + (y0 + y) * window_width) + 1] = 255;
1861                   ptr[4 * (x0 + x + (y0 + y) * window_width) + 2] = 255;
1862 
1863                 }
1864             }
1865           page->OPS[n].x1 = x0;
1866           page->OPS[n].y1 = y0;
1867           page->OPS[n].x2 = x0 + lx;
1868           page->OPS[n].y2 = y0 + ly;
1869         }
1870 
1871       if (page->OPS[n].op == BITMAPFADE)
1872         {
1873           nn = script_search_bitmap (page->OPS[n].name, page);
1874           if (nn == -1)
1875             {
1876               LOG_ERR ("script_search_bitmap() failed!");
1877               return NULL;
1878             }
1879           bm = page->BITMAPS[nn].ptr;
1880           lx = page->BITMAPS[nn].x;
1881           ly = page->BITMAPS[nn].y;
1882           x0 = page->OPS[n].x;
1883           y0 = page->OPS[n].y;
1884           script_draw_rectangleBitmap (ptr, x0, y0, lx, ly, bm);
1885           page->OPS[n].x1 = x0;
1886           page->OPS[n].y1 = y0;
1887           page->OPS[n].x2 = x0 + lx;
1888           page->OPS[n].y2 = y0 + ly;
1889         }
1890 
1891       if (page->OPS[n].op == TEXTE)
1892         {
1893           nn = script_search_font (page->OPS[n].name, page);
1894           if (nn == -1)
1895             {
1896               LOG_ERR ("script_search_font() failed!");
1897               return NULL;
1898             }
1899           if (page->FONTES[nn].OMBRAGE == 1)
1900             {
1901               x0 = page->OPS[n].x + page->FONTES[nn].Ombrex;
1902               y0 = page->OPS[n].y + page->FONTES[nn].Ombrey;
1903               script_draw_string (ptr, page->OPS[n].str, x0, y0,
1904                                   &page->FONTES[nn], 1);
1905 
1906             }
1907           x0 = page->OPS[n].x;
1908           y0 = page->OPS[n].y;
1909           len =
1910             script_draw_string (ptr, page->OPS[n].str, x0, y0,
1911                                 &page->FONTES[nn], 0);
1912 
1913           page->OPS[n].x1 = x0;
1914           page->OPS[n].y1 = y0;
1915           page->OPS[n].x2 = x0 + len;
1916           page->OPS[n].y2 = y0 + page->FONTES[nn].size / 2;
1917 
1918         }
1919 
1920 
1921       /* display number of times the game has been launched */
1922       if (page->OPS[n].op == NBLAUNCH)
1923         {
1924           nn = script_search_font (page->OPS[n].name, page);
1925           if (nn == -1)
1926             {
1927               LOG_ERR ("script_search_font() failed!");
1928               return NULL;
1929             }
1930           snprintf (sname, 512, "%d", page->OPS[n].amp);
1931           if (page->FONTES[nn].OMBRAGE == 1)
1932             {
1933               x0 = page->OPS[n].x + page->FONTES[nn].Ombrex;
1934               y0 = page->OPS[n].y + page->FONTES[nn].Ombrey;
1935               script_draw_string (ptr, sname, x0, y0, &page->FONTES[nn], 1);
1936 
1937             }
1938           x0 = page->OPS[n].x;
1939           y0 = page->OPS[n].y;
1940           len = script_draw_string (ptr, sname, x0, y0, &page->FONTES[nn], 0);
1941           page->OPS[n].x1 = x0;
1942           page->OPS[n].y1 = y0;
1943           page->OPS[n].x2 = x0 + len;
1944           page->OPS[n].y2 = y0 + page->FONTES[nn].size / 2;
1945         }
1946 
1947       if (page->OPS[n].op == CARREDEGRADE)
1948         {
1949           x0 = page->OPS[n].x;
1950           y0 = page->OPS[n].y;
1951           script_draw_shadow_rectangle (ptr, x0 + 16, y0 + 16,
1952                                         page->OPS[n].lx, page->OPS[n].ly, 24);
1953 
1954           script_draw_rectangle (ptr, x0, y0, page->OPS[n].lx,
1955                                  page->OPS[n].ly, page->OPS[n].rgb.r,
1956                                  page->OPS[n].rgb.g, page->OPS[n].rgb.b);
1957           page->OPS[n].x1 = x0;
1958           page->OPS[n].y1 = y0;
1959           page->OPS[n].x2 = x0 + page->OPS[n].lx;
1960           page->OPS[n].y2 = y0 + page->OPS[n].ly;
1961         }
1962 
1963       if (page->OPS[n].op == ONDES)
1964         {
1965           ptr2 =
1966             (char *) memory_allocation (window_width * window_height * 4);
1967           if (ptr2 == NULL)
1968             {
1969               return NULL;
1970             }
1971           memcpy (ptr2, ptr, window_width * window_height * 4);
1972           float ax1, ay1, ax2, ay2, rmax;
1973           Sint32 ax, ay;
1974           Sint32 n1, n2;
1975           Sint32 adr, adr2;
1976           rmax =
1977             (float) sqrt ((window_width / 2) * (window_width / 2) +
1978                           (window_height / 2) * (window_height / 2));
1979           adr2 = 0;
1980           for (n2 = 0; n2 < window_height; n2++)
1981             {
1982               for (n1 = 0; n1 < window_width; n1++)
1983                 {
1984                   ax1 =
1985                     script_wave_heights (n1 - 1, n2, page->OPS[n].amp,
1986                                          page->OPS[n].rayon, rmax);
1987                   ay1 =
1988                     script_wave_heights (n1, n2 - 1, page->OPS[n].amp,
1989                                          page->OPS[n].rayon, rmax);
1990                   ax2 =
1991                     script_wave_heights (n1 + 1, n2, page->OPS[n].amp,
1992                                          page->OPS[n].rayon, rmax);
1993                   ay2 =
1994                     script_wave_heights (n1, n2 + 1, page->OPS[n].amp,
1995                                          page->OPS[n].rayon, rmax);
1996 
1997                   ax = n1 + (Sint32) (ax2 - ax1);
1998                   ay = n2 + (Sint32) (ay2 - ay1);
1999 
2000                   if (!
2001                       ((ax >= 0) && (ax < window_width) && (ay >= 0)
2002                        && (ay < window_height)))
2003                     {
2004                       if (ax < 0)
2005                         ax = 0;
2006                       if (ay < 0)
2007                         ay = 0;
2008                       if (ax >= window_width)
2009                         ax = window_width - 1;
2010                       if (ay >= window_height)
2011                         ay = window_height - 1;
2012 
2013                     }
2014                   adr = 4 * (ax + (ay) * window_width);
2015                   ptr[adr2 + 0] = ptr2[adr + 0];
2016                   ptr[adr2 + 1] = ptr2[adr + 1];
2017                   ptr[adr2 + 2] = ptr2[adr + 2];
2018                   adr2 += 4;
2019                 }
2020             }
2021           free_memory (ptr2);
2022         }
2023 
2024 
2025       if (page->OPS[n].op == ONDES2)
2026         {
2027           ptr2 =
2028             (char *) memory_allocation (window_width * window_height * 4);
2029           if (ptr2 == NULL)
2030             {
2031               return NULL;
2032             }
2033           memcpy (ptr2, ptr, window_width * window_height * 4);
2034           float ax1, ay1, ax2, ay2, rmax;
2035           Sint32 ax, ay;
2036           Sint32 n1, n2;
2037           Sint32 r, g, b;
2038           Sint32 adr, adr2;
2039           rmax =
2040             (float) sqrt ((window_width / 2) * (window_width / 2) +
2041                           (window_height / 2) * (window_height / 2));
2042           adr2 = 0;
2043           for (n2 = 0; n2 < window_height; n2++)
2044             {
2045               for (n1 = 0; n1 < window_width; n1++)
2046                 {
2047                   ax1 =
2048                     script_wave_heights (n1 - 1, n2, page->OPS[n].amp,
2049                                          page->OPS[n].rayon, rmax);
2050                   ay1 =
2051                     script_wave_heights (n1, n2 - 1, page->OPS[n].amp,
2052                                          page->OPS[n].rayon, rmax);
2053                   ax2 =
2054                     script_wave_heights (n1 + 1, n2, page->OPS[n].amp,
2055                                          page->OPS[n].rayon, rmax);
2056                   ay2 =
2057                     script_wave_heights (n1, n2 + 1, page->OPS[n].amp,
2058                                          page->OPS[n].rayon, rmax);
2059 
2060                   ax =
2061                     ((Sint32) (ax2 - ax1) * page->OPS[n].x +
2062                      (Sint32) (ay2 - ay1) * page->OPS[n].y);
2063 
2064                   f = 1 + (float) ax / (16 * 128);
2065                   ax = n1 + (Sint32) (ax2 - ax1);
2066                   ay = n2 + (Sint32) (ay2 - ay1);
2067                   if (!
2068                       ((ax >= 0) && (ax < window_width) && (ay >= 0)
2069                        && (ay < window_height)))
2070                     {
2071                       if (ax < 0)
2072                         ax = 0;
2073                       if (ay < 0)
2074                         ay = 0;
2075                       if (ax >= window_width)
2076                         ax = window_width - 1;
2077                       if (ay >= window_height)
2078                         ay = window_height - 1;
2079 
2080                     }
2081 
2082                   adr = 4 * (ax + (ay) * window_width);
2083                   r = ptr2[adr + 0] & 255;
2084                   g = ptr2[adr + 1] & 255;
2085                   b = ptr2[adr + 2] & 255;
2086                   r *= (Sint32) f;
2087                   g *= (Sint32) f;
2088                   b *= (Sint32) f;
2089                   if (r > 255)
2090                     {
2091                       r = 255;
2092                     }
2093                   if (g > 255)
2094                     {
2095                       g = 255;
2096                     }
2097                   if (b > 255)
2098                     {
2099                       b = 255;
2100                     }
2101                   if (r < 0)
2102                     {
2103                       r = 0;
2104                     }
2105                   if (g < 0)
2106                     {
2107                       g = 0;
2108                     }
2109                   if (b < 0)
2110                     {
2111                       b = 0;
2112                     }
2113                   ptr[adr2 + 0] = r;
2114                   ptr[adr2 + 1] = g;
2115                   ptr[adr2 + 2] = b;
2116                   adr2 += 4;
2117                 }
2118             }
2119           free_memory (ptr2);
2120         }
2121       if (page->OPS[n].op == EMBOSS)
2122         {
2123           Sint32 h00, h01, h10;
2124           Sint32 n1, n2;
2125           Sint32 r, g, b;
2126           Sint32 adr;
2127           ptr2 =
2128             (char *) memory_allocation (window_width * window_height * 4);
2129           if (ptr2 == NULL)
2130             {
2131               return NULL;
2132             }
2133           memcpy (ptr2, ptr, window_width * window_height * 4);
2134           ptr3 =
2135             (char *) memory_allocation (window_width * window_height * 4);
2136           if (ptr3 == NULL)
2137             {
2138               return NULL;
2139             }
2140           for (n2 = 0; n2 < window_height * 2; n2++)
2141             {
2142               for (n1 = 0; n1 < window_width * 2; n1++)
2143                 {
2144                   adr = (n1 + n2 * window_width * 2);
2145                   x = page->OPS[n].x - n1 + window_width / 2;
2146                   y = page->OPS[n].y - n2 + window_height / 2;
2147                   f = sqrt (x * x + y * y) / page->OPS[n].rayon;
2148                   if (f > 1)
2149                     {
2150                       f = 1;
2151                     }
2152                   if (f < 0)
2153                     {
2154                       f = 0;
2155                     }
2156                   f = 1 - f;
2157                   f = 300 * f;
2158                   if (f > 255)
2159                     {
2160                       f = 255;
2161                     }
2162                   ptr3[adr] = (int) f;
2163                 }
2164             }
2165           for (n2 = 0; n2 < window_height; n2++)
2166             {
2167               for (n1 = 0; n1 < window_width; n1++)
2168                 {
2169                   adr = 4 * (n1 + n2 * window_width);
2170                   r = ptr2[adr + 0] & 255;
2171                   g = ptr2[adr + 1] & 255;
2172                   b = ptr2[adr + 2] & 255;
2173                   h00 =
2174                     r * page->OPS[n].rgb.r + g * page->OPS[n].rgb.g +
2175                     b * page->OPS[n].rgb.b;
2176 
2177                   if (n1 < window_width - 1)
2178                     {
2179                       r = ptr2[adr + 4 + 0] & 255;
2180                       g = ptr2[adr + 4 + 1] & 255;
2181                       b = ptr2[adr + 4 + 2] & 255;
2182                     }
2183                   h10 =
2184                     r * page->OPS[n].rgb.r + g * page->OPS[n].rgb.g +
2185                     b * page->OPS[n].rgb.b;
2186                   if (n2 < window_height - 1)
2187                     {
2188                       r = ptr2[adr + 4 * window_width + 0] & 255;
2189                       g = ptr2[adr + 4 * window_width + 1] & 255;
2190                       b = ptr2[adr + 4 * window_width + 2] & 255;
2191                     }
2192                   h01 =
2193                     r * page->OPS[n].rgb.r + g * page->OPS[n].rgb.g +
2194                     b * page->OPS[n].rgb.b;
2195                   r = ptr2[adr + 0] & 255;
2196                   g = ptr2[adr + 1] & 255;
2197                   b = ptr2[adr + 2] & 255;
2198                   x = n1 + (h10 - h00) + window_width / 2;
2199                   y = n2 + (h01 - h00) + window_height / 2;
2200                   if (x < 0)
2201                     {
2202                       x = 0;
2203                     }
2204                   if (y < 0)
2205                     {
2206                       y = 0;
2207                     }
2208                   if (x >= window_width * 2)
2209                     {
2210                       x = window_width * 2 - 1;
2211                     }
2212                   if (y >= window_height * 2)
2213                     {
2214                       y = window_height * 2 - 1;
2215                     }
2216                   nn = ptr3[x + y * (window_width * 2)] & 255;
2217                   f = (float) nn / 255;
2218                   r = (Sint32) (2 * r * f);
2219                   g = (Sint32) (2 * g * f);
2220                   b = (Sint32) (2 * b * f);
2221                   if (r > 255)
2222                     {
2223                       r = 255;
2224                     }
2225                   if (g > 255)
2226                     {
2227                       g = 255;
2228                     }
2229                   if (b > 255)
2230                     {
2231                       b = 255;
2232                     }
2233                   if (r < 0)
2234                     {
2235                       r = 0;
2236                     }
2237                   if (g < 0)
2238                     {
2239                       g = 0;
2240                     }
2241                   if (b < 0)
2242                     {
2243                       b = 0;
2244                     }
2245                   ptr[adr + 0] = r;
2246                   ptr[adr + 1] = g;
2247                   ptr[adr + 2] = b;
2248                 }
2249             }
2250           free_memory (ptr3);
2251           free_memory (ptr2);
2252         }
2253     }
2254 
2255   /* convert */
2256   for (x = 0; x < window_width; x++)
2257     for (y = 0; y < window_height; y++)
2258       {
2259         unsigned char c = ptr[4 * (x + y * window_width) + 0];
2260         ptr[4 * (x + y * window_width) + 0] =
2261           ptr[4 * (x + y * window_width) + 2];
2262         ptr[4 * (x + y * window_width) + 2] = c;
2263         ptr[4 * (x + y * window_width) + 3] = 255;
2264       }
2265   return Surface;
2266 }
2267 
2268 
2269 /**
2270  * Free memory allocated for the script
2271  * @param page a pointer to a page structure
2272  */
2273 void
script_free(Page * page)2274 script_free (Page * page)
2275 {
2276   Uint32 i;
2277   Sint32 n;
2278   if (page == NULL)
2279     {
2280       return;
2281     }
2282   for (i = 0; i < 256; i++)
2283     {
2284       if (page->OPS[i].str != NULL)
2285         {
2286           free_memory ((char *) page->OPS[i].str);
2287           page->OPS[i].str = NULL;
2288         }
2289     }
2290   /* free images */
2291   for (n = 0; n < page->nBITMAPS; n++)
2292     {
2293       if (page->BITMAPS[n].Surface != NULL)
2294         {
2295           SDL_FreeSurface (page->BITMAPS[n].Surface);
2296           page->BITMAPS[n].Surface = NULL;
2297           page->BITMAPS[n].ptr = NULL;
2298         }
2299       if (page->BITMAPS[n].ptr != NULL)
2300         {
2301           free_memory ((char *) page->BITMAPS[n].ptr);
2302           page->BITMAPS[n].ptr = NULL;
2303         }
2304     }
2305 
2306   /* remove fontes */
2307   for (n = 0; n < page->nFONTES; n++)
2308     {
2309       if (page->FONTES[n].font != NULL)
2310         {
2311           TTF_CloseFont (page->FONTES[n].font);
2312           page->FONTES[n].font = NULL;
2313         }
2314     }
2315   free_memory ((char *) page);
2316 }
2317 
2318 /**
2319  * Return counter position if exists
2320  * @param page Pointer to a 'Page' structure
2321  * @param x
2322  * @param y
2323  * @returni TRUE
2324  */
2325 bool
script_get_counter_pos(Page * page,Sint32 * x,Sint32 * y)2326 script_get_counter_pos (Page * page, Sint32 * x, Sint32 * y)
2327 {
2328   Sint32 n;
2329   for (n = 0; n < page->nOPS; n++)
2330     {
2331       if (page->OPS[n].op == COMPTEUR)
2332         {
2333           *x = page->OPS[n].x;
2334           *y = page->OPS[n].y;
2335           return TRUE;
2336         }
2337     }
2338   return FALSE;
2339 }
2340 
2341 /**
2342  * Modify  number of times the game has been launched
2343  * in OPS->amp for op NBLAUNCH
2344  * to call before script_generate_page() function
2345  */
2346 void
script_set_number_of_launch(Page * page,Sint32 count)2347 script_set_number_of_launch (Page * page, Sint32 count)
2348 {
2349   Sint32 n;
2350   for (n = 0; n < page->nOPS; n++)
2351     {
2352       if (page->OPS[n].op == NBLAUNCH)
2353         {
2354 
2355           page->OPS[n].amp = count;
2356         }
2357     }
2358 }
2359 
2360 
2361 #endif
2362