1 /*
2 *
3 * Copyright (c) 1994, 2002, 2003 Johannes Prix
4 * Copyright (c) 1994, 2002, 2003 Reinhard Prix
5 *
6 *
7 * This file is part of Freedroid
8 *
9 * Freedroid is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * Freedroid is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Freedroid; see the file COPYING. If not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 *
24 */
25
26 /*----------------------------------------------------------------------
27 *
28 * Desc: Graphics primitived, such as functions to load LBM or PCX images,
29 * to change the vga color table, to activate or deachtivate monitor
30 * signal, to set video modes etc.
31 *
32 *----------------------------------------------------------------------*/
33
34 #define _graphics_c
35
36 #include "system.h"
37
38 #include "defs.h"
39 #include "struct.h"
40 #include "global.h"
41 #include "proto.h"
42 #include "map.h"
43 #include "text.h"
44 #include "SDL_rotozoom.h"
45 #include "takeover.h"
46
47 const SDL_VideoInfo *vid_info;/* info about current video mode */
48
49 void PutPixel (SDL_Surface * surface, int x, int y, Uint32 pixel);
50 int Load_Fonts (void);
51 SDL_Surface *Load_Block (char *fpath, int line, int col, SDL_Rect * block, int flags);
52 SDL_RWops *load_raw_pic (char *fpath);
53
54 /* XPM */
55 static const char *crosshair_xpm[] = {
56 /* width height num_colors chars_per_pixel */
57 " 32 32 3 1",
58 /* colors */
59 "X c #000000",
60 ". c #ffffff",
61 " c None",
62 /* pixels */
63 " ",
64 " ",
65 " XXXX ",
66 " X..X ",
67 " X..X ",
68 " X..X ",
69 " X..X ",
70 " X..X ",
71 " X..X ",
72 " X..X ",
73 " X..X ",
74 " XXXX ",
75 " ",
76 " XXXXXXXXXXX XXXXXXXXXX ",
77 " X.........X X........X ",
78 " X.........X X........X ",
79 " XXXXXXXXXXX XXXXXXXXXX ",
80 " ",
81 " XXXX ",
82 " X..X ",
83 " X..X ",
84 " X..X ",
85 " X..X ",
86 " X..X ",
87 " X..X ",
88 " X..X ",
89 " X..X ",
90 " X..X ",
91 " X..X ",
92 " XXXX ",
93 " ",
94 " ",
95 "0,0"
96 };
97
98
99 /* XPM */
100 static const char *arrow_xpm[] = {
101 /* width height num_colors chars_per_pixel */
102 " 32 32 3 1",
103 /* colors */
104 "X c #000000",
105 ". c #ffffff",
106 " c None",
107 /* pixels */
108 "X ",
109 "XX ",
110 "X.X ",
111 "X..X ",
112 "X...X ",
113 "X....X ",
114 "X.....X ",
115 "X......X ",
116 "X.......X ",
117 "X........X ",
118 "X.....XXXXX ",
119 "X..X..X ",
120 "X.X X..X ",
121 "XX X..X ",
122 "X X..X ",
123 " X..X ",
124 " X..X ",
125 " X..X ",
126 " XX ",
127 " ",
128 " ",
129 " ",
130 " ",
131 " ",
132 " ",
133 " ",
134 " ",
135 " ",
136 " ",
137 " ",
138 " ",
139 " ",
140 "0,0"
141 };
142
143
144 /* ----------------------------------------------------------------------
145 * This function applies a color filter to a given surface
146 * ---------------------------------------------------------------------- */
147 int
ApplyFilter(SDL_Surface * surf,float fred,float fgreen,float fblue)148 ApplyFilter (SDL_Surface *surf, float fred, float fgreen, float fblue)
149 {
150 int x , y ; // for processing through the surface...
151 Uint8 red, green, blue, alpha;
152
153 //--------------------
154 // First we check for null surfaces given...
155 //
156 if ( surf == NULL )
157 {
158 DebugPrintf (0 , "\nERROR: ApplyFilter called with NULL pointer\n" );
159 return (ERR);
160 }
161
162 //--------------------
163 // Now we start to process through the whole surface and examine each
164 // pixel.
165 //
166 for ( y = 0 ; y < surf -> h ; y ++ )
167 {
168 for ( x = 0 ; x < surf -> w ; x ++ )
169 {
170 GetRGBA (surf, x, y, &red, &green, &blue, &alpha);
171
172 if (alpha == SDL_ALPHA_TRANSPARENT)
173 continue;
174
175 red *= fred;
176 green *= fgreen;
177 blue *= fblue;
178
179 putpixel (surf, x, y, SDL_MapRGBA (surf->format, red, green, blue, alpha) ) ;
180 }
181 }
182
183 return (OK);
184
185 } // Apply_Filter
186
187 /* ----------------------------------------------------------------------
188 * This function gives the green component of a pixel, using a value of
189 * 255 for the most green pixel and 0 for the least green pixel.
190 * ---------------------------------------------------------------------- */
191 void
GetRGBA(SDL_Surface * surface,int x,int y,Uint8 * r,Uint8 * g,Uint8 * b,Uint8 * a)192 GetRGBA ( SDL_Surface* surface, int x, int y, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
193 {
194 SDL_PixelFormat *fmt;
195 Uint32 pixel;
196
197 //--------------------
198 // First we extract the pixel itself and the
199 // format information we need.
200 //
201 fmt = surface -> format ;
202 pixel = * ( ( ( Uint32* ) surface -> pixels ) + x + y * surface->w ) ;
203
204 SDL_GetRGBA (pixel, fmt, r, g, b, a);
205
206 }; // int GetRGBA
207
208
209 /*----------------------------------------------------------------------
210 This function was taken directly from the example in the SDL docu.
211 Even there they say they have stolen if from the mailing list.
212 Anyway it should create a new mouse cursor from an XPM.
213 The XPM is defined above and not read in from disk or something.
214 ----------------------------------------------------------------------*/
init_system_cursor(const char * image[])215 static SDL_Cursor *init_system_cursor(const char *image[])
216 {
217 int i, row, col;
218 Uint8 data[4*32];
219 Uint8 mask[4*32];
220 int hot_x, hot_y;
221
222 i = -1;
223 for ( row=0; row<32; ++row ) {
224 for ( col=0; col<32; ++col ) {
225 if ( col % 8 ) {
226 data[i] <<= 1;
227 mask[i] <<= 1;
228 } else {
229 ++i;
230 data[i] = mask[i] = 0;
231 }
232 switch (image[4+row][col]) {
233 case 'X':
234 data[i] |= 0x01;
235 mask[i] |= 0x01;
236 break;
237 case '.':
238 mask[i] |= 0x01;
239 break;
240 case ' ':
241 break;
242 }
243 }
244 }
245 sscanf(image[4+row], "%d,%d", &hot_x, &hot_y);
246 return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
247 };
248
249 /*
250 ----------------------------------------------------------------------
251 ----------------------------------------------------------------------
252 */
253
254 void
DrawLineBetweenTiles(float x1,float y1,float x2,float y2,int Color)255 DrawLineBetweenTiles( float x1 , float y1 , float x2 , float y2 , int Color )
256 {
257 int i;
258 int pixx;
259 int pixy;
260 float tmp;
261 float slope;
262
263 if ( (x1 == x2) && (y1 == y2) ) return; // nothing is to be done here
264
265
266 if (x1 == x2) // infinite slope!! special case, that must be caught!
267 {
268
269 if (y1 > y2) // in this case, just interchange 1 and 2
270 {
271 tmp = y1;
272 y1=y2;
273 y2=tmp;
274 }
275
276 for ( i=0 ; i < (y2 - y1) * Block_Rect.w ; i++ )
277 {
278 pixx = User_Rect.x + User_Rect.w/2 - Block_Rect.w * (Me.pos.x - x1 );
279 pixy = UserCenter_y - Block_Rect.h * (Me.pos.y - y1 ) + i ;
280 if ( (pixx <= User_Rect.x) ||
281 (pixx >= User_Rect.x + User_Rect.w -1) ||
282 (pixy <= User_Rect.y ) ||
283 (pixy >= User_Rect.y + User_Rect.h -1) ) continue;
284 putpixel( ne_screen , pixx , pixy , Color );
285 putpixel( ne_screen , pixx-1 , pixy , Color );
286 }
287 return;
288 }
289
290 if (x1 > x2) // in this case, just interchange 1 and 2
291 {
292 tmp = x1;
293 x1=x2;
294 x2=tmp;
295 tmp = y1;
296 y1=y2;
297 y2=tmp;
298 }
299
300 //--------------------
301 // Now we start the drawing process
302 //
303 // SDL_LockSurface( ne_screen );
304
305 slope = ( y2 - y1 ) / (x2 - x1) ;
306 for ( i=0 ; i<(x2-x1)*Block_Rect.w ; i++ )
307 {
308 pixx=User_Rect.x + User_Rect.w/2 - Block_Rect.w * (Me.pos.x - x1 ) + i;
309 pixy= UserCenter_y - Block_Rect.h * (Me.pos.y - y1 ) + i * slope ;
310 if ( (pixx <= User_Rect.x) ||
311 (pixx >= User_Rect.x + User_Rect.w -1) ||
312 (pixy <= User_Rect.y ) ||
313 (pixy >= User_Rect.y + User_Rect.h -1) ) continue;
314 putpixel( ne_screen , pixx , pixy , Color );
315 putpixel( ne_screen , pixx , pixy -1 , Color );
316 }
317
318 // SDL_UnlockSurface( ne_screen );
319
320 } // void DrawLineBetweenTiles
321
322
323 /*-----------------------------------------------------------------
324 * This function saves a screenshot to disk.
325 * The screenshots are names "Screenshot_XX.bmp" where XX is a
326 * running number.
327 *
328 * NOTE: This function does NOT check for existing screenshots,
329 * but will silently overwrite them. No problem in most
330 * cases I think.
331 *
332 *-----------------------------------------------------------------*/
333 void
TakeScreenshot(void)334 TakeScreenshot(void)
335 {
336 static int Number_Of_Screenshot=0;
337 char *Screenshoot_Filename;
338
339 Screenshoot_Filename=MyMalloc(100);
340 DebugPrintf (1, "\n\nScreenshoot function called.\n\n");
341 sprintf( Screenshoot_Filename , "Screenshot_%d.bmp", Number_Of_Screenshot );
342 DebugPrintf(1, "\n\nScreenshoot function: The Filename is: %s.\n\n" , Screenshoot_Filename );
343 SDL_SaveBMP( ne_screen , Screenshoot_Filename );
344 Number_Of_Screenshot++;
345 free(Screenshoot_Filename);
346
347 } // void TakeScreenshot(void)
348
349 /*
350 ----------------------------------------------------------------------
351 @Desc: This function draws a "grid" on the screen, that means every
352 "second" pixel is blacked out, thereby generation a fading
353 effect. This function was created to fade the background of the
354 Escape menu and its submenus.
355
356 @Ret: none
357 ----------------------------------------------------------------------
358 */
359 void
MakeGridOnScreen(SDL_Rect * Grid_Rectangle)360 MakeGridOnScreen( SDL_Rect* Grid_Rectangle )
361 {
362 int x,y;
363
364 if ( Grid_Rectangle == NULL ) Grid_Rectangle = & User_Rect ;
365
366 DebugPrintf (2, "\nvoid MakeGridOnScreen(...): real function call confirmed.");
367 SDL_LockSurface( ne_screen );
368 for ( y = Grid_Rectangle->y ; y < (Grid_Rectangle->h + Grid_Rectangle->y) ; y++)
369 {
370 for ( x = Grid_Rectangle->x ; x < (Grid_Rectangle->x + Grid_Rectangle->w) ; x++ )
371 {
372 if ((x+y)%2 == 0)
373 {
374 putpixel( ne_screen, x, y, 0 );
375 }
376 }
377 }
378
379 SDL_UnlockSurface( ne_screen );
380 DebugPrintf (2, "\nvoid MakeGridOnScreen(...): end of function reached.");
381 } // void MakeGridOnSchreen(void)
382
383
384 /*----------------------------------------------------------------------
385 * This function load an image and displays it directly to the ne_screen
386 * but without updating it.
387 * This might be very handy, especially in the Title() function to
388 * display the title image and perhaps also for displaying the ship
389 * and that.
390 *
391 ----------------------------------------------------------------------*/
392 void
DisplayImage(char * datafile)393 DisplayImage(char *datafile)
394 {
395 SDL_Surface *image;
396
397 image = IMG_Load(datafile);
398 if ( image == NULL ) {
399 DebugPrintf(0, "ERROR: Couldn't load image %s: %s\n", datafile, IMG_GetError());
400 Terminate(ERR);
401 }
402
403 if (GameConfig.scale != 1.0)
404 ScalePic (&image, GameConfig.scale);
405
406 SDL_BlitSurface(image, NULL, ne_screen, NULL);
407
408 SDL_FreeSurface(image);
409
410 return;
411
412 } // DisplayImage()
413
414 /*----------------------------------------------------------------------
415 * This function resizes all blocks and structures involved in assembling
416 * the combat picture to a new scale. The new scale is relative to the
417 * standard scale with means scale=1 is 64x64 tile size.
418 *
419 * in the first call we assume the Block_Rect to be the original game-size
420 * and store this value for future rescalings
421 ----------------------------------------------------------------------*/
422 void
SetCombatScaleTo(float scale)423 SetCombatScaleTo(float scale)
424 {
425 int i, j;
426 static SDL_Rect origBlock;
427 static bool firstcall = TRUE;
428 SDL_Surface *tmp;
429
430 if (firstcall) Copy_Rect (Block_Rect, origBlock); // keep that as a backup
431 firstcall = FALSE;
432
433 for ( j=0 ; j < NUM_COLORS ; j++ )
434 for ( i = 0 ; i < NUM_MAP_BLOCKS ; i++ )
435 {
436 // if there's already a rescaled version, free it
437 if (MapBlockSurfacePointer[j][i] != OrigMapBlockSurfacePointer[j][i])
438 SDL_FreeSurface (MapBlockSurfacePointer[j][i]);
439 // then zoom..
440 tmp = zoomSurface(OrigMapBlockSurfacePointer[j][i], scale, scale, 0);
441 // and optimize
442 MapBlockSurfacePointer[j][i]=SDL_DisplayFormat (tmp);
443 SDL_FreeSurface(tmp); // free the old surface
444 }
445
446 Copy_Rect (origBlock, Block_Rect); // always scale with respect to original size!
447 ScaleRect(Block_Rect, scale);
448
449 return;
450
451 } // void SetCombatScaleTo(float new_scale);
452
453 /*
454 ----------------------------------------------------------------------
455 ----------------------------------------------------------------------
456 */
457 void
LoadThemeConfigurationFile(void)458 LoadThemeConfigurationFile(void)
459 {
460 char *Data;
461 char *ReadPointer;
462 char *fpath;
463 char *EndOfThemesBulletData;
464 char *EndOfThemesBlastData;
465 char *EndOfThemesDigitData;
466 int BulletIndex;
467
468 #define END_OF_THEME_DATA_STRING "**** End of theme data section ****"
469 #define END_OF_THEME_BLAST_DATA_STRING "*** End of themes blast data section ***"
470 #define END_OF_THEME_BULLET_DATA_STRING "*** End of themes bullet data section ***"
471 #define END_OF_THEME_DIGIT_DATA_STRING "*** End of themes digit data section ***"
472
473 fpath = find_file ("config.theme", GRAPHICS_DIR, USE_THEME, CRITICAL);
474
475 Data = ReadAndMallocAndTerminateFile( fpath , END_OF_THEME_DATA_STRING ) ;
476
477 EndOfThemesBulletData = LocateStringInData ( Data , END_OF_THEME_BULLET_DATA_STRING );
478 EndOfThemesBlastData = LocateStringInData ( Data , END_OF_THEME_BLAST_DATA_STRING );
479 EndOfThemesDigitData = LocateStringInData ( Data , END_OF_THEME_DIGIT_DATA_STRING );
480
481 //--------------------
482 // Now the file is read in entirely and
483 // we can start to analyze its content,
484 //
485 #define BLAST_ONE_NUMBER_OF_PHASES_STRING "How many phases in Blast one :"
486 #define BLAST_TWO_NUMBER_OF_PHASES_STRING "How many phases in Blast two :"
487
488 ReadValueFromString (Data, BLAST_ONE_NUMBER_OF_PHASES_STRING, "%d", &Blastmap[0].phases);
489
490 ReadValueFromString (Data, BLAST_TWO_NUMBER_OF_PHASES_STRING, "%d", &Blastmap[1].phases);
491
492 //--------------------
493 // Next we read in the number of phases that are to be used for each bullet type
494 ReadPointer = Data ;
495 while ( ( ReadPointer = strstr ( ReadPointer , "For Bullettype Nr.=" ) ) != NULL )
496 {
497 ReadValueFromString (ReadPointer, "For Bullettype Nr.=", "%d", &BulletIndex);
498 if ( BulletIndex >= Number_Of_Bullet_Types )
499 {
500 DebugPrintf (0, "\n\n\
501 ----------------------------------------------------------------------\n\
502 Freedroid has encountered a problem:\n\
503 In function 'char* LoadThemeConfigurationFile ( ... ):\n\
504 \n\
505 There was a specification for the number of phases in a bullet type\n\
506 that does not at all exist in the ruleset.\n\
507 \n\
508 This might indicate that either the ruleset file is corrupt or the \n\
509 theme.config configuration file is corrupt or (less likely) that there\n\
510 is a severe bug in the reading function.\n\
511 \n\
512 Please check that your theme and ruleset files are properly set up.\n\
513 \n\
514 Please also don't forget, that you might have to run 'make install'\n\
515 again after you've made modifications to the data files in the source tree.\n\
516 \n\
517 Freedroid will terminate now to draw attention to the data problem it could\n\
518 not resolve.... Sorry, if that interrupts a major game of yours.....\n\
519 ----------------------------------------------------------------------\n\
520 \n" );
521 Terminate(ERR);
522 }
523 ReadValueFromString (ReadPointer, "we will use number of phases=", "%d", &Bulletmap[BulletIndex].phases);
524 ReadValueFromString (ReadPointer, "and number of phase changes per second=", "%f",
525 &Bulletmap[BulletIndex].phase_changes_per_second);
526 ReadPointer++;
527 }
528
529 // --------------------
530 // Also decidable from the theme is where in the robot to
531 // display the digits. This must also be read from the configuration
532 // file of the theme
533 //
534 #define DIGIT_ONE_POSITION_X_STRING "First digit x :"
535 #define DIGIT_ONE_POSITION_Y_STRING "First digit y :"
536 #define DIGIT_TWO_POSITION_X_STRING "Second digit x :"
537 #define DIGIT_TWO_POSITION_Y_STRING "Second digit y :"
538 #define DIGIT_THREE_POSITION_X_STRING "Third digit x :"
539 #define DIGIT_THREE_POSITION_Y_STRING "Third digit y :"
540
541 ReadValueFromString (Data, DIGIT_ONE_POSITION_X_STRING, "%hd", &FirstDigit_Rect.x);
542 ReadValueFromString (Data, DIGIT_ONE_POSITION_Y_STRING, "%hd", &FirstDigit_Rect.y);
543
544 ReadValueFromString (Data, DIGIT_TWO_POSITION_X_STRING, "%hd", &SecondDigit_Rect.x);
545 ReadValueFromString (Data, DIGIT_TWO_POSITION_Y_STRING, "%hd", &SecondDigit_Rect.y);
546
547 ReadValueFromString (Data, DIGIT_THREE_POSITION_X_STRING, "%hd", &ThirdDigit_Rect.x);
548 ReadValueFromString (Data, DIGIT_THREE_POSITION_Y_STRING, "%hd", &ThirdDigit_Rect.y);
549
550 free (Data);
551
552 return;
553
554 }; // void LoadThemeConfigurationFile ( void )
555
556
557 /*-----------------------------------------------------------------
558 * @Desc: get the pics for: druids, bullets, blasts
559 *
560 * reads all blocks and puts the right pointers into
561 * the various structs
562 *
563 * @Ret: TRUE/FALSE
564 *
565 *-----------------------------------------------------------------*/
566 int
InitPictures(void)567 InitPictures (void)
568 {
569 static bool first_call= TRUE;
570 char *fpath;
571 int line, col, i;
572 BFont_Info *oldfont;
573 SDL_Surface *tmp;
574 char fname[500];
575
576 // Loading all these pictures might take a while...
577 // and we do not want do deal with huge frametimes, which
578 // could box the influencer out of the ship....
579 Activate_Conservative_Frame_Computation();
580
581 oldfont = GetCurrentFont ();
582
583 if (first_call)
584 Load_Fonts ();
585
586 SetCurrentFont (FPS_Display_BFont);
587 printf_SDL (ne_screen, User_Rect.x + 50, Screen_Rect.h - 100, "Loading Theme config ...");
588
589 LoadThemeConfigurationFile();
590
591 printf_SDL (ne_screen, -1, -1, " ok\n");
592
593 printf_SDL (ne_screen, User_Rect.x + 50, -1, "Loading image data ");
594 //---------- get Map blocks
595 fpath = find_file (MAP_BLOCK_FILE, GRAPHICS_DIR, USE_THEME, CRITICAL);
596 Load_Block (fpath, 0, 0, NULL, INIT_ONLY); /* init function */
597 for (line = 0; line < NUM_COLORS; line ++)
598 for (col = 0; col < NUM_MAP_BLOCKS; col ++)
599 {
600 FreeIfUsed (OrigMapBlockSurfacePointer[line][col]);
601 OrigMapBlockSurfacePointer[line][col] = Load_Block (NULL, line, col, &OrigBlock_Rect,0);
602 MapBlockSurfacePointer[line][col] = OrigMapBlockSurfacePointer[line][col];
603 }
604 printf_SDL (ne_screen, -1, -1, ".");
605 //---------- get Droid-model blocks
606 fpath = find_file (DROID_BLOCK_FILE, GRAPHICS_DIR, USE_THEME, CRITICAL);
607 Load_Block (fpath, 0, 0, NULL, INIT_ONLY);
608 for (col = 0; col < DROID_PHASES; col ++)
609 {
610 FreeIfUsed (InfluencerSurfacePointer[col]);
611 FreeIfUsed (EnemySurfacePointer[col]);
612 InfluencerSurfacePointer[col] = Load_Block (NULL, 0, col, &OrigBlock_Rect, 0);
613 EnemySurfacePointer[col] = Load_Block (NULL, 1, col, &OrigBlock_Rect, 0);
614 /* Droid pics are only used in _internal_ blits ==> clear per-surf alpha */
615 SDL_SetAlpha (InfluencerSurfacePointer[col], 0, 0);
616 SDL_SetAlpha (EnemySurfacePointer[col], 0, 0);
617 }
618
619 // SDL_SetAlpha( Me.pic, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
620
621 printf_SDL (ne_screen, -1, -1, ".");
622 //---------- get Bullet blocks
623 fpath = find_file (BULLET_BLOCK_FILE, GRAPHICS_DIR, USE_THEME, CRITICAL);
624 Load_Block (fpath, 0, 0, NULL, INIT_ONLY);
625 for (line = 0; line < Number_Of_Bullet_Types; line ++)
626 for (col = 0; col < Bulletmap[line].phases; col ++)
627 {
628 FreeIfUsed (Bulletmap[line].SurfacePointer[col]);
629 Bulletmap[line].SurfacePointer[col] = Load_Block (NULL, line, col, &OrigBlock_Rect, 0);
630 }
631 printf_SDL (ne_screen, -1, -1, ".");
632
633 //---------- get Blast blocks
634 fpath = find_file (BLAST_BLOCK_FILE, GRAPHICS_DIR, USE_THEME, CRITICAL);
635 Load_Block (fpath, 0, 0, NULL, INIT_ONLY);
636 for (line = 0; line < ALLBLASTTYPES; line ++)
637 for (col = 0; col < Blastmap[line].phases; col ++)
638 {
639 FreeIfUsed (Blastmap[line].SurfacePointer[col]);
640 Blastmap[line].SurfacePointer[col] = Load_Block (NULL, line, col, &OrigBlock_Rect, 0);
641 }
642 printf_SDL (ne_screen, -1, -1, ".");
643 //---------- get Digit blocks
644 fpath = find_file (DIGIT_BLOCK_FILE, GRAPHICS_DIR, USE_THEME, CRITICAL);
645 Load_Block (fpath, 0, 0, NULL, INIT_ONLY);
646 for (col = 0; col < 10; col++)
647 {
648 FreeIfUsed (InfluDigitSurfacePointer[col]);
649 InfluDigitSurfacePointer[col] = Load_Block (NULL, 0, col, &OrigDigit_Rect, 0);
650 FreeIfUsed (EnemyDigitSurfacePointer[col]);
651 EnemyDigitSurfacePointer[col] = Load_Block (NULL, 0, col + 10, &OrigDigit_Rect, 0);
652 }
653 printf_SDL (ne_screen, -1, -1, ".");
654
655 //---------- get Takeover pics
656 GetTakeoverGraphics ();
657 printf_SDL (ne_screen, -1, -1, ".");
658
659 FreeIfUsed(ship_on_pic);
660 ship_on_pic = IMG_Load (find_file (SHIP_ON_PIC_FILE, GRAPHICS_DIR, USE_THEME, CRITICAL));
661 FreeIfUsed(ship_off_pic);
662 ship_off_pic= IMG_Load (find_file (SHIP_OFF_PIC_FILE, GRAPHICS_DIR, USE_THEME, CRITICAL));
663
664 // the following are not theme-specific and are therefore only loaded once!
665 if (first_call)
666 {
667 // create the tmp block-build storage
668 tmp = SDL_CreateRGBSurface( 0 , Block_Rect.w, Block_Rect.h, screen_bpp, 0, 0, 0, 0);
669 BuildBlock = SDL_DisplayFormatAlpha (tmp);
670 SDL_FreeSurface (tmp);
671
672 // takeover pics
673 fpath = find_file (TAKEOVER_BG_PIC_FILE, GRAPHICS_DIR, NO_THEME, CRITICAL);
674 takeover_bg_pic = Load_Block (fpath, 0, 0, NULL, 0);
675 // cursor shapes
676 arrow_cursor = init_system_cursor (arrow_xpm);
677 crosshair_cursor = init_system_cursor (crosshair_xpm);
678 //---------- get Console pictures
679 fpath = find_file (CONSOLE_PIC_FILE, GRAPHICS_DIR, NO_THEME, CRITICAL);
680 console_pic = Load_Block (fpath, 0, 0, NULL, 0);
681 fpath = find_file (CONSOLE_BG_PIC1_FILE, GRAPHICS_DIR, NO_THEME, CRITICAL);
682 console_bg_pic1 = Load_Block (fpath, 0, 0, NULL, 0);
683 fpath = find_file (CONSOLE_BG_PIC2_FILE, GRAPHICS_DIR, NO_THEME, CRITICAL);
684 console_bg_pic2 = Load_Block (fpath, 0, 0, NULL, 0);
685 printf_SDL (ne_screen, -1, -1, ".");
686 arrow_up = IMG_Load (find_file ("arrow_up.png", GRAPHICS_DIR, NO_THEME, CRITICAL) );
687 arrow_down = IMG_Load (find_file ("arrow_down.png", GRAPHICS_DIR, NO_THEME, CRITICAL) );
688 arrow_right = IMG_Load (find_file ("arrow_right.png", GRAPHICS_DIR, NO_THEME, CRITICAL) );
689 arrow_left = IMG_Load (find_file ("arrow_left.png", GRAPHICS_DIR, NO_THEME, CRITICAL) );
690 //---------- get Banner
691 fpath = find_file (BANNER_BLOCK_FILE, GRAPHICS_DIR, NO_THEME, CRITICAL);
692 banner_pic = Load_Block (fpath, 0, 0, NULL, 0);
693 printf_SDL (ne_screen, -1, -1, ".");
694 //---------- get Droid images ----------
695 for (i=0; i<NUM_DROIDS; i++)
696 {
697 // first check if we find a file with rotation-frames: first try .jpg
698 strcpy( fname, Druidmap[i].druidname );
699 strcat( fname , ".jpg" );
700 fpath = find_file (fname, GRAPHICS_DIR, NO_THEME, IGNORE);
701 // then try with .png
702 if (!fpath)
703 {
704 strcpy( fname, Druidmap[i].druidname );
705 strcat( fname , ".png" );
706 fpath = find_file (fname, GRAPHICS_DIR, NO_THEME, CRITICAL);
707 }
708
709 packed_portraits[i] = load_raw_pic (fpath);
710 }
711
712 // we need the 999.png in any case for transparency!
713 strcpy( fname, Druidmap[DRUID999].druidname );
714 strcat( fname , ".png" );
715 fpath = find_file (fname, GRAPHICS_DIR, NO_THEME, CRITICAL);
716 pic999 = Load_Block (fpath, 0, 0, NULL, 0);
717
718 // get the Ashes pics
719 strcpy (fname, "Ashes.png");
720 fpath = find_file (fname, GRAPHICS_DIR, NO_THEME, WARNONLY);
721 if (!fpath)
722 {
723 DebugPrintf (0, "WARNING: deactivated display of droid-decals\n");
724 GameConfig.ShowDecals = FALSE;
725 }
726 else
727 {
728 Load_Block (fpath, 0, 0, NULL, INIT_ONLY);
729 Decal_pics[0] = Load_Block (NULL, 0, 0, &OrigBlock_Rect, 0);
730 Decal_pics[1] = Load_Block (NULL, 0, 1, &OrigBlock_Rect, 0);
731 }
732
733 } // if first_call
734
735 printf_SDL (ne_screen, -1, -1, " ok\n");
736
737 // if scale != 1 then we need to rescale everything now
738 ScaleGraphics (GameConfig.scale);
739
740 // make sure bullet-surfaces get re-generated!
741 for ( i = 0 ; i < MAXBULLETS ; i++ )
742 AllBullets[i].Surfaces_were_generated = FALSE ;
743
744 SetCurrentFont (oldfont);
745
746 first_call = FALSE;
747
748 return (TRUE);
749
750 } // InitPictures
751
752
753 /*----------------------------------------------------------------------
754 * load a pic into memory and return the SDL_RWops pointer to it
755 *----------------------------------------------------------------------*/
756 SDL_RWops *
load_raw_pic(char * fpath)757 load_raw_pic (char *fpath)
758 {
759 struct stat statbuf;
760 FILE *fp;
761 off_t size;
762 void *mem;
763
764 // sanity check
765 if (!fpath)
766 {
767 DebugPrintf (0, "ERROR: load_raw_pic() called with NULL argument!\n");
768 Terminate (ERR);
769 }
770
771 fp = fopen (fpath, "rb");
772 if (!fp)
773 {
774 DebugPrintf (0, "ERROR: could not open file %s. Giving up\n", fpath);
775 Terminate (ERR);
776 }
777
778 size = FS_filelength (fp);
779 mem = MyMalloc (size);
780 if (fread (mem, 1, size, fp) != size)
781 {
782 DebugPrintf (0, "ERROR reading file %s. Giving up...\n", fpath);
783 Terminate (ERR);
784 }
785 fclose (fp);
786
787
788 return (SDL_RWFromMem(mem, size) );
789
790 }
791
792
793 /*------------------------------------------------------------
794 * General block-reading routine: get block from pic-file
795 *
796 * fpath: full pathname of picture-file; if NULL: use previous SDL-surf
797 * line, col: block-position in pic-file to read block from
798 * block: dimension of blocks to consider: if NULL: copy whole pic
799 * NOTE: only w and h of block are used!!
800 *
801 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
802 * NOTE: to avoid memory-leaks, use (flags | INIT_ONLY) if you only
803 * call this function to set up a new pic-file to be read.
804 * This will avoid copying & mallocing a new pic, NULL will be returned
805 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
806 *------------------------------------------------------------*/
807 SDL_Surface *
Load_Block(char * fpath,int line,int col,SDL_Rect * block,int flags)808 Load_Block (char *fpath, int line, int col, SDL_Rect * block, int flags)
809 {
810 static SDL_Surface *pic = NULL;
811 SDL_Surface *tmp;
812 SDL_Rect src, dim;
813 SDL_Surface *ret;
814 int usealpha;
815
816 if (!fpath && !pic) /* we need some info.. */
817 return (NULL);
818
819 if (fpath) // initialize: read & malloc new pic, dont' return a copy!!
820 {
821 if (pic) // previous pic?
822 SDL_FreeSurface (pic);
823 pic = IMG_Load (fpath);
824
825 }
826
827 if ( (flags & INIT_ONLY) != FALSE )
828 return (NULL); // that's it guys, only initialzing...
829
830 if (!block)
831 {
832 Set_Rect (dim, 0, 0, pic->w, pic->h);
833 }
834 else
835 {
836 Set_Rect (dim, 0, 0, block->w, block->h);
837 }
838
839 if (pic->format->Amask != 0)
840 usealpha = TRUE;
841 else
842 usealpha = FALSE;
843
844 if (usealpha)
845 SDL_SetAlpha (pic, 0, 0); /* clear per-surf alpha for internal blit */
846 tmp = SDL_CreateRGBSurface (0, dim.w, dim.h, screen_bpp, 0, 0, 0, 0);
847 if (usealpha)
848 ret = SDL_DisplayFormatAlpha (tmp);
849 else
850 ret = SDL_DisplayFormat (tmp);
851 SDL_FreeSurface (tmp);
852
853 Set_Rect (src, col * (dim.w + 2), line * (dim.h + 2), dim.w, dim.h);
854 SDL_BlitSurface (pic, &src, ret, NULL);
855 if (usealpha)
856 SDL_SetAlpha (ret, SDL_SRCALPHA | SDL_RLEACCEL, SDL_ALPHA_OPAQUE);
857
858 return (ret);
859
860 } // Load_Block()
861
862
863 /*-----------------------------------------------------------------
864 * Initialise the Video display and graphics engine
865 *
866 *
867 *-----------------------------------------------------------------*/
868 void
Init_Video(void)869 Init_Video (void)
870 {
871 char vid_driver[81];
872 Uint32 flags; /* flags for SDL video mode */
873 char *fpath;
874
875 /* Initialize the SDL library */
876 // if ( SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1 )
877
878 if ( SDL_Init (SDL_INIT_VIDEO) == -1 )
879 {
880 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
881 Terminate(ERR);
882 } else
883 DebugPrintf(1, "\nSDL Video initialisation successful.\n");
884
885 // Now SDL_TIMER is initialized here:
886
887 if ( SDL_InitSubSystem ( SDL_INIT_TIMER ) == -1 )
888 {
889 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
890 Terminate(ERR);
891 } else
892 DebugPrintf(1, "\nSDL Timer initialisation successful.\n");
893
894 /* clean up on exit */
895 atexit (SDL_Quit);
896
897
898 vid_info = SDL_GetVideoInfo (); /* just curious */
899 SDL_VideoDriverName (vid_driver, 80);
900
901 // flags = SDL_HWSURFACE | SDL_DOUBLEBUF;
902 flags = 0;
903 if (GameConfig.UseFullscreen) flags |= SDL_FULLSCREEN;
904
905 if (vid_info->wm_available) /* if there's a window-manager */
906 {
907 SDL_WM_SetCaption ("Freedroid", "");
908 fpath = find_file (ICON_FILE, GRAPHICS_DIR, NO_THEME, WARNONLY);
909 if (fpath) SDL_WM_SetIcon( IMG_Load (fpath), NULL);
910 }
911
912 screen_bpp = 16; /* start with the simplest */
913
914 if( !(ne_screen = SDL_SetVideoMode ( Screen_Rect.w, Screen_Rect.h , 0 , flags)) )
915 {
916 DebugPrintf (0, "ERORR: Couldn't set %d x %d video mode. SDL: %s\n",
917 Screen_Rect.w, Screen_Rect.h, SDL_GetError());
918 exit(-1);
919 }
920
921 vid_info = SDL_GetVideoInfo (); /* info about current video mode */
922
923 DebugPrintf(1, "Got video mode: ");
924
925 SDL_SetGamma( 1 , 1 , 1 );
926 GameConfig.Current_Gamma_Correction=1;
927
928 return;
929
930 } /* InitVideo () */
931
932 /*@Function============================================================
933 @Desc:
934
935 @Ret:
936 @Int:
937 * $Function----------------------------------------------------------*/
938 void
ClearGraphMem(void)939 ClearGraphMem ( void )
940 {
941 // One this function is done, the rahmen at the
942 // top of the screen surely is destroyed. We inform the
943 // DisplayBanner function of the matter...
944 BannerIsDestroyed=TRUE;
945
946 //
947 SDL_SetClipRect( ne_screen, NULL );
948
949 // Now we fill the screen with black color...
950 SDL_FillRect( ne_screen , NULL , 0 );
951 SDL_Flip (ne_screen);
952
953 return;
954 } // ClearGraphMem( void )
955
956
957 /*----------------------------------------------------------------------
958 * Return the pixel value at (x, y)
959 * NOTE: The surface must be locked before calling this!
960 *----------------------------------------------------------------------*/
961 Uint32
getpixel(SDL_Surface * surface,int x,int y)962 getpixel(SDL_Surface *surface, int x, int y)
963 {
964 int bpp = surface->format->BytesPerPixel;
965 /* Here p is the address to the pixel we want to retrieve */
966 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
967
968 switch(bpp)
969 {
970 case 1:
971 return *p;
972
973 case 2:
974 return *(Uint16 *)p;
975
976 case 3:
977 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
978 return p[0] << 16 | p[1] << 8 | p[2];
979 else
980 return p[0] | p[1] << 8 | p[2] << 16;
981
982 case 4:
983 return *(Uint32 *)p;
984
985 default:
986 return 0; /* shouldn't happen, but avoids warnings */
987 }
988
989 } // Uint32 getpixel(...)
990
991
992 /*
993 * Set the pixel at (x, y) to the given value
994 * NOTE: The surface must be locked before calling this!
995 */
putpixel(SDL_Surface * surface,int x,int y,Uint32 pixel)996 void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
997 {
998 int bpp = surface->format->BytesPerPixel;
999 /* Here p is the address to the pixel we want to set */
1000 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
1001
1002 switch(bpp) {
1003 case 1:
1004 *p = pixel;
1005 break;
1006
1007 case 2:
1008 *(Uint16 *)p = pixel;
1009 break;
1010
1011 case 3:
1012 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
1013 p[0] = (pixel >> 16) & 0xff;
1014 p[1] = (pixel >> 8) & 0xff;
1015 p[2] = pixel & 0xff;
1016 } else {
1017 p[0] = pixel & 0xff;
1018 p[1] = (pixel >> 8) & 0xff;
1019 p[2] = (pixel >> 16) & 0xff;
1020 }
1021 break;
1022
1023 case 4:
1024 *(Uint32 *)p = pixel;
1025 break;
1026 }
1027 } // void putpixel(...)
1028
1029 /*----------------------------------------------------------------------
1030 *
1031 *----------------------------------------------------------------------*/
1032 int
Load_Fonts(void)1033 Load_Fonts (void)
1034 {
1035 char *fpath;
1036
1037 fpath = find_file (PARA_FONT_FILE, GRAPHICS_DIR, NO_THEME, CRITICAL);
1038 if ( ( Para_BFont = LoadFont (fpath, GameConfig.scale) ) == NULL )
1039 {
1040 DebugPrintf (0, "ERROR: font file named %s was not found.\n", PARA_FONT_FILE );
1041 Terminate(ERR);
1042 } else
1043 DebugPrintf(1, "\nSDL Para Font initialisation successful.\n");
1044
1045 Menu_BFont = Para_BFont;
1046
1047 fpath = find_file (FPS_FONT_FILE, GRAPHICS_DIR, NO_THEME, CRITICAL);
1048 if ( ( FPS_Display_BFont = LoadFont (fpath, GameConfig.scale) ) == NULL )
1049 {
1050 DebugPrintf (0, "ERROR: font file named %s was not found.\n", FPS_FONT_FILE);
1051 Terminate(ERR);
1052 } else
1053 DebugPrintf(1, "\nSDL FPS Display Font initialisation successful.\n");
1054
1055 /* choose a font for highscore displaying... */
1056 Highscore_BFont = Para_BFont;
1057
1058 return (OK);
1059 } // Load_Fonts ()
1060
1061 //------------------------------------------------------------
1062 // display "white noise" effect in Rect.
1063 // algorith basically stolen from
1064 // Greg Knauss's "xteevee" hack in xscreensavers.
1065 //
1066 // timeout is in ms
1067 //------------------------------------------------------------
1068 #define NOISE_COLORS 6
1069 #define NOISE_TILES 8
1070
1071 void
white_noise(SDL_Surface * bitmap,SDL_Rect * rect,int timeout)1072 white_noise (SDL_Surface *bitmap, SDL_Rect *rect, int timeout)
1073 {
1074 int i;
1075 int x, y;
1076 int signal_strengh = 60;
1077 Uint32 grey[NOISE_COLORS];
1078 Uint8 color;
1079 SDL_Surface *tmp, *tmp2;
1080 SDL_Surface *noise_tiles[NOISE_TILES];
1081 SDL_Rect clip_rect;
1082 char used_tiles[NOISE_TILES/2+1];
1083 int next_tile;
1084 int now;
1085
1086 for (i=0; i< NOISE_COLORS; i++)
1087 {
1088 color = (Uint8)(((double)(i+1.0)/NOISE_COLORS)*255.0);
1089 grey[i] = SDL_MapRGB(ne_screen->format, color, color, color);
1090 }
1091
1092 // produce the tiles
1093 tmp = SDL_CreateRGBSurface(0, rect->w, rect->h, screen_bpp, 0, 0, 0, 0);
1094 tmp2 = SDL_DisplayFormat (tmp);
1095 SDL_FreeSurface (tmp);
1096 SDL_BlitSurface (bitmap, rect, tmp2, NULL);
1097 // printf_SDL (ne_screen, rect->x + 10, rect->y + rect->h/2, "Preparing noise-tiles ");
1098 for (i=0; i< NOISE_TILES; i++)
1099 {
1100 noise_tiles[i] = SDL_DisplayFormat(tmp2);
1101
1102 for (x = 0; x < rect->w; x++)
1103 for (y = 0; y < rect->h; y++)
1104 if (rand()%100 > signal_strengh)
1105 PutPixel (noise_tiles[i], x, y, grey[rand()%NOISE_COLORS]);
1106
1107 // printf_SDL (ne_screen, -1, -1, " %d", i+1);
1108 // SDL_BlitSurface (noise_tiles[i], NULL, ne_screen, rect);
1109 // SDL_UpdateRect (ne_screen, rect->x, rect->y, rect->w, rect->h);
1110 }
1111 SDL_FreeSurface (tmp2);
1112
1113 memset(used_tiles,-1, sizeof(used_tiles));
1114 // let's go
1115 Play_Sound (WHITE_NOISE);
1116
1117 now = SDL_GetTicks();
1118
1119 while (1)
1120 {
1121 // pick an old enough tile
1122 do
1123 {
1124 next_tile = rand()%NOISE_TILES;
1125 for (i = 0; i < sizeof(used_tiles); i++)
1126 {
1127 if (next_tile == used_tiles[i])
1128 {
1129 next_tile = -1;
1130 break;
1131 }
1132 }
1133 } while (next_tile == -1);
1134 memmove(used_tiles,used_tiles+1,sizeof(used_tiles)-1);
1135 used_tiles[sizeof(used_tiles)-1] = next_tile;
1136
1137 // make sure we can blit the full rect without clipping! (would change *rect!)
1138 SDL_GetClipRect (ne_screen, &clip_rect);
1139 SDL_SetClipRect (ne_screen, NULL);
1140 // set it
1141 SDL_BlitSurface (noise_tiles[next_tile], NULL, ne_screen, rect);
1142 SDL_UpdateRect (ne_screen, rect->x, rect->y, rect->w, rect->h);
1143 SDL_Delay(25);
1144
1145 if ( (timeout && (SDL_GetTicks()-now > timeout)))
1146 break;
1147
1148 } // while (! finished)
1149
1150 //restore previous clip-rectange
1151 SDL_SetClipRect (ne_screen, &clip_rect);
1152
1153 for (i=0; i<NOISE_TILES; i++)
1154 SDL_FreeSurface (noise_tiles[i]);
1155
1156 return;
1157 }
1158
1159 /*----------------------------------------------------------------------
1160 * ScaleGraphics ()
1161 *----------------------------------------------------------------------*/
1162 void
ScaleGraphics(float scale)1163 ScaleGraphics (float scale)
1164 {
1165 static bool first_call = TRUE;
1166 SDL_Surface *tmp;
1167 int line, col, i, j;
1168
1169 if (scale == 1.0)
1170 return;
1171
1172 // these are reset in a theme-change by the theme-config-file
1173 // therefore we need to rescale them each time again
1174 ScaleRect (FirstDigit_Rect, scale);
1175 ScaleRect (SecondDigit_Rect, scale);
1176 ScaleRect (ThirdDigit_Rect, scale);
1177
1178
1179 // note: only rescale these rects the first time!!
1180 if (first_call)
1181 ScaleStatRects (scale);
1182
1183 printf_SDL (ne_screen, User_Rect.x + 50, -1, "Rescaling graphics ...");
1184
1185 //---------- rescale Map blocks
1186 for (line = 0; line < NUM_COLORS; line ++)
1187 for (col = 0; col < NUM_MAP_BLOCKS; col ++)
1188 {
1189 ScalePic( &OrigMapBlockSurfacePointer[line][col], scale);
1190 MapBlockSurfacePointer[line][col] = OrigMapBlockSurfacePointer[line][col];
1191 }
1192 printf_SDL (ne_screen, -1, -1, ".");
1193 //---------- rescale Droid-model blocks
1194 for (col = 0; col < DROID_PHASES; col ++)
1195 {
1196 ScalePic (&InfluencerSurfacePointer[col], scale);
1197 ScalePic (&EnemySurfacePointer[col], scale);
1198 /* Droid pics are only used in _internal_ blits ==> clear per-surf alpha */
1199 SDL_SetAlpha (InfluencerSurfacePointer[col], 0, 0);
1200 SDL_SetAlpha (EnemySurfacePointer[col], 0, 0);
1201 }
1202
1203 printf_SDL (ne_screen, -1, -1, ".");
1204 //---------- rescale Bullet blocks
1205 for (line = 0; line < Number_Of_Bullet_Types; line ++)
1206 for (col = 0; col < Bulletmap[line].phases; col ++)
1207 ScalePic( &Bulletmap[line].SurfacePointer[col], scale);
1208
1209 printf_SDL (ne_screen, -1, -1, ".");
1210
1211 //---------- rescale Blast blocks
1212 for (line = 0; line < ALLBLASTTYPES; line ++)
1213 for (col = 0; col < Blastmap[line].phases; col ++)
1214 ScalePic (&Blastmap[line].SurfacePointer[col], scale);
1215
1216 printf_SDL (ne_screen, -1, -1, ".");
1217 //---------- rescale Digit blocks
1218 for (col = 0; col < 10; col++)
1219 {
1220 ScalePic (&InfluDigitSurfacePointer[col], scale);
1221 ScalePic (&EnemyDigitSurfacePointer[col], scale);
1222 /* Digits are only used in _internal_ blits ==> clear per-surf alpha */
1223 SDL_SetAlpha (InfluDigitSurfacePointer[col], 0, 0);
1224 SDL_SetAlpha (EnemyDigitSurfacePointer[col], 0, 0);
1225 }
1226 printf_SDL (ne_screen, -1, -1, ".");
1227
1228 //---------- rescale Takeover pics
1229 ScalePic (&to_blocks, scale);
1230 printf_SDL (ne_screen, -1, -1, ".");
1231
1232 ScalePic (&ship_on_pic, scale);
1233 ScalePic (&ship_off_pic, scale);
1234
1235 // the following are not theme-specific and are therefore only loaded once!
1236 if (first_call)
1237 {
1238 // create a new tmp block-build storage
1239 FreeIfUsed (BuildBlock);
1240 tmp = SDL_CreateRGBSurface( 0 , Block_Rect.w, Block_Rect.h, screen_bpp, 0, 0, 0, 0);
1241 BuildBlock = SDL_DisplayFormatAlpha (tmp);
1242 SDL_FreeSurface (tmp);
1243
1244 // takeover pics
1245 ScalePic (&takeover_bg_pic, scale);
1246
1247 //---------- Console pictures
1248 ScalePic (&console_pic, scale);
1249 ScalePic (&console_bg_pic1, scale);
1250 ScalePic (&console_bg_pic2, scale);
1251 ScalePic (&arrow_up, scale);
1252 ScalePic (&arrow_down, scale);
1253 ScalePic (&arrow_right, scale);
1254 ScalePic (&arrow_left, scale);
1255 //---------- Banner
1256 ScalePic (&banner_pic, scale);
1257
1258 //---------- Droid images ----------
1259 // FIXME: this still needs to be done!!!!
1260 for (i=0; i<NUM_DROIDS; i++)
1261 {
1262 // packed_portraits[i] = load_raw_pic (fpath);
1263 }
1264
1265 // we need the 999.png in any case for transparency!
1266 ScalePic (&pic999, scale);
1267
1268 // get the Ashes pics
1269 if (Decal_pics[0]) ScalePic (&Decal_pics[0], scale);
1270 if (Decal_pics[1]) ScalePic (&Decal_pics[1], scale);
1271
1272 } // if first_call
1273
1274 printf_SDL (ne_screen, -1, -1, " ok\n");
1275
1276 first_call = FALSE;
1277
1278 return;
1279
1280 } // ScaleGraphics()
1281
1282 /*----------------------------------------------------------------------
1283 *
1284 *----------------------------------------------------------------------*/
1285 void
ScalePic(SDL_Surface ** pic,float scale)1286 ScalePic (SDL_Surface **pic, float scale)
1287 {
1288 SDL_Surface *tmp;
1289
1290 if (scale == 1.0)
1291 return;
1292
1293 tmp = *pic;
1294 *pic = zoomSurface (tmp, scale, scale, 0);
1295 SDL_FreeSurface (tmp);
1296
1297 return;
1298
1299 } // ScalePic ()
1300
1301 /*----------------------------------------------------------------------
1302 * scale all "static" rectangle
1303 *----------------------------------------------------------------------*/
1304 void
ScaleStatRects(float scale)1305 ScaleStatRects (float scale)
1306 {
1307 int i, j;
1308
1309 ScaleRect (Block_Rect, scale);
1310 ScaleRect (User_Rect, scale);
1311 ScaleRect (Classic_User_Rect, scale);
1312 ScaleRect (Full_User_Rect, scale);
1313 ScaleRect (Banner_Rect, scale);
1314 ScaleRect (Portrait_Rect, scale);
1315 ScaleRect (Cons_Droid_Rect, scale);
1316 ScaleRect (Menu_Rect, scale);
1317 ScaleRect (OptionsMenu_Rect, scale);
1318 ScaleRect (Digit_Rect, scale);
1319 ScaleRect (Cons_Header_Rect, scale);
1320 ScaleRect (Cons_Menu_Rect, scale);
1321 ScaleRect (Cons_Text_Rect, scale);
1322
1323 ScaleRect (Cons_Menu_Rects[0], scale);
1324 ScaleRect (Cons_Menu_Rects[1], scale);
1325 ScaleRect (Cons_Menu_Rects[2], scale);
1326 ScaleRect (Cons_Menu_Rects[3], scale);
1327
1328 ScaleRect (ConsMenuItem_Rect, scale);
1329
1330 ScaleRect (LeftInfo_Rect, scale);
1331 ScaleRect (RightInfo_Rect, scale);
1332
1333 for (i=0; i<NUM_FILL_BLOCKS; i++)
1334 ScaleRect (FillBlocks[i], scale);
1335
1336 for (i = 0; i < NUM_CAPS_BLOCKS; i++)
1337 ScaleRect (CapsuleBlocks[i], scale);
1338
1339 for (j = 0; j < 2*NUM_PHASES; j++)
1340 for (i = 0; i < TO_BLOCKS; i++)
1341 ScaleRect (ToGameBlocks[j*TO_BLOCKS+i], scale);
1342
1343 for (i = 0; i < NUM_GROUND_BLOCKS; i++)
1344 ScaleRect (ToGroundBlocks[i], scale);
1345
1346 ScaleRect (ToColumnBlock, scale);
1347 ScaleRect (ToLeaderBlock, scale);
1348
1349
1350 for (i=0; i < TO_COLORS; i++)
1351 {
1352 ScalePoint (LeftCapsulesStart[i],scale);
1353 ScalePoint (CurCapsuleStart[i],scale);
1354 ScalePoint (PlaygroundStart[i],scale);
1355 ScalePoint (DruidStart[i],scale);
1356 }
1357 ScalePoint (TO_LeftGroundStart, scale);
1358 ScalePoint (TO_ColumnStart, scale);
1359 ScalePoint (TO_RightGroundStart, scale);
1360 ScalePoint( TO_LeaderBlockStart, scale);
1361
1362 ScaleRect (TO_FillBlock, scale);
1363 ScaleRect (TO_ElementRect, scale);
1364 ScaleRect (TO_CapsuleRect, scale);
1365 ScaleRect (TO_LeaderLed, scale);
1366 ScaleRect (TO_GroundRect, scale);
1367 ScaleRect (TO_ColumnRect, scale);
1368
1369 return;
1370
1371 } // ScaleStatRects()
1372
1373
1374
1375 #undef _graphics_c
1376