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: the konsole- and lift functions
29 *
30 *----------------------------------------------------------------------*/
31
32 #define _ship_c
33
34 #include "system.h"
35
36 #include "defs.h"
37 #include "struct.h"
38 #include "global.h"
39 #include "proto.h"
40 #include "text.h"
41 #include "SDL_rotozoom.h"
42
43
44 int CursorIsOnRect (SDL_Rect *rect);
45 SDL_Rect up_rect,down_rect,left_rect,right_rect;
46 extern bool show_cursor;
47
48 #define UPDATE_ONLY 0x01
49
50 //--------------------
51 // Definitions for the menu inside the in-game console
52 //
53 #define CONS_MENU_HEIGHT 256
54 #define CONS_MENU_LENGTH 100
55
56 #define WAIT_ELEVATOR 9 /* warte, bevor Lift weitergeht */
57
58 #define MENUTEXT_X (132 + USERFENSTERPOSX + 5 )
59
60
61 SDL_Rect up_rect;
62 SDL_Rect down_rect;
63 SDL_Rect left_rect;
64 SDL_Rect right_rect;
65
66
67 /*-----------------------------------------------------------------
68 * @Desc: does all the work when we enter a lift
69 *
70 *-----------------------------------------------------------------*/
71 void
EnterLift(void)72 EnterLift (void)
73 {
74 int i;
75 int curLevel;
76 int curLift, upLift, downLift, liftrow;
77
78 DebugPrintf (2, "\nvoid EnterLift(void): Function call confirmed.");
79
80 /* Prevent distortion of framerate by the delay coming from
81 * the time spend in the menu. */
82 Activate_Conservative_Frame_Computation();
83
84
85 /* make sure to release the fire-key */
86 SpacePressedR();
87 MouseLeftPressedR();
88 MouseRightPressedR();
89
90 /* Prevent the influ from coming out of the lift in transfer mode
91 * by turning off transfer mode as soon as the influ enters the lift */
92 Me.status= ELEVATOR;
93
94 ResetMouseWheel (); // forget previous mouse-wheel action
95 SDL_ShowCursor(SDL_DISABLE);
96
97 curLevel = CurLevel->levelnum;
98
99 if ((curLift = GetCurrentLift ()) == -1)
100 {
101 printf ("Lift out of order, I'm so sorry !");
102 return;
103 }
104
105 EnterLiftSound ();
106 Switch_Background_Music_To (NULL); // turn off Bg music
107
108 upLift = curShip.AllLifts[curLift].up;
109 downLift = curShip.AllLifts[curLift].down;
110
111 liftrow = curShip.AllLifts[curLift].lift_row;
112
113 // clear the whole screen
114 ClearGraphMem();
115 DisplayBanner (NULL, NULL, BANNER_FORCE_UPDATE );
116
117 ShowLifts (curLevel, liftrow);
118
119
120 while (! FirePressedR())
121 {
122 if (UpPressedR () || WheelUpPressed ())
123 if (upLift != -1)
124 { /* gibt es noch einen Lift hoeher ? */
125 if (curShip.AllLifts[upLift].x == 99)
126 {
127 DebugPrintf (0, "Lift out of order, so sorry ..");
128 }
129 else
130 {
131 downLift = curLift;
132 curLift = upLift;
133 curLevel = curShip.AllLifts[curLift].level;
134 upLift = curShip.AllLifts[curLift].up;
135
136 ShowLifts (curLevel, liftrow);
137
138 MoveLiftSound ();
139 }
140 } /* if uplevel */
141
142
143 if (DownPressedR () || WheelDownPressed ())
144 if (downLift != -1)
145 { /* gibt es noch einen Lift tiefer ? */
146 if (curShip.AllLifts[downLift].x == 99)
147 {
148 printf ("Lift Out of order, so sorry ..");
149 }
150 else
151 {
152 upLift = curLift;
153 curLift = downLift;
154 curLevel = curShip.AllLifts[curLift].level;
155 downLift = curShip.AllLifts[curLift].down;
156
157 ShowLifts (curLevel, liftrow);
158
159 MoveLiftSound ();
160 }
161 } /* if downlevel */
162 } /* while !SpaceReleased */
163
164 //--------------------
165 // It might happen, that the influencer enters the elevator, but then decides to
166 // come out on the same level where he has been before. In this case of course there
167 // is no need to reshuffle enemys or to reset influencers position. Therefore, only
168 // when a real level change has occured, we need to do real changes as below, where
169 // we set the new level and set new position and initiate timers and all that...
170 //
171 if (curLevel != CurLevel->levelnum)
172 { /* wirklich neu ??? */
173 int array_num = 0;
174 Level tmp;
175
176 /* Aktuellen Level setzen */
177 while ((tmp = curShip.AllLevels[array_num]) != NULL)
178 {
179 if (tmp->levelnum == curLevel)
180 break;
181 else
182 array_num++;
183 }
184
185
186 CurLevel = curShip.AllLevels[array_num];
187
188 // redistribute the enemys around the level
189 // ShuffleEnemys ();
190
191 // set the position of the influencer to the correct locatiohn
192 Me.pos.x = curShip.AllLifts[curLift].x;
193 Me.pos.y = curShip.AllLifts[curLift].y;
194
195 for (i = 0; i < MAXBLASTS; i++)
196 DeleteBlast( i );
197 for (i = 0; i < MAXBULLETS; i++)
198 DeleteBullet ( i ) ;
199 } // if real level change has occured
200
201 LeaveLiftSound ( );
202 Switch_Background_Music_To (CurLevel->Background_Song_Name);
203 ClearGraphMem ( );
204 DisplayBanner (NULL, NULL, BANNER_FORCE_UPDATE );
205
206 // UnfadeLevel ();
207
208 Me.status = MOBILE;
209 Me.TextVisibleTime=0;
210 Me.TextToBeDisplayed=CurLevel->Level_Enter_Comment;
211
212 DebugPrintf (2, "\nvoid EnterLift(void): Usual end of function reached.");
213
214 return;
215 } /* EnterLift */
216
217 /*-----------------------------------------------------------------
218 * @Desc: show side-view of the ship, and hightlight the current
219 * level + lift
220 *
221 * if level==-1: don't highlight any level
222 * if liftrow==-1: dont' highlight any liftrows
223 *
224 *-----------------------------------------------------------------*/
225 void
ShowLifts(int level,int liftrow)226 ShowLifts (int level, int liftrow)
227 {
228 SDL_Rect src, dst;
229 int i;
230 SDL_Color lift_bg_color = {0,0,0}; /* black... */
231 int xoffs = User_Rect.w/20;
232 int yoffs = User_Rect.h/5;
233
234 SDL_ShowCursor (SDL_DISABLE);
235 // fill the user fenster with some color
236 Fill_Rect (User_Rect, lift_bg_color);
237
238 /* First blit ship "lights off" */
239 Copy_Rect (User_Rect, dst);
240 SDL_SetClipRect (ne_screen, &dst);
241 Copy_Rect (User_Rect, dst);
242 dst.x += xoffs;
243 dst.y += yoffs;
244 SDL_BlitSurface (ship_off_pic, NULL, ne_screen, &dst);
245
246 if (level >= 0)
247 for (i=0; i<curShip.num_level_rects[level]; i++)
248 {
249 Copy_Rect (curShip.Level_Rects[level][i], src);
250 Copy_Rect (src, dst);
251 dst.x += User_Rect.x + xoffs; /* offset respective to User-Rectangle */
252 dst.y += User_Rect.y + yoffs;
253 SDL_BlitSurface (ship_on_pic, &src, ne_screen, &dst);
254 }
255
256 if (liftrow >=0)
257 {
258 Copy_Rect (curShip.LiftRow_Rect[liftrow], src);
259 Copy_Rect (src, dst);
260 dst.x += User_Rect.x + xoffs; /* offset respective to User-Rectangle */
261 dst.y += User_Rect.y + yoffs;
262 SDL_BlitSurface (ship_on_pic, &src, ne_screen, &dst);
263 }
264
265 SDL_Flip (ne_screen);
266
267 return;
268
269 } /* ShowLifts() */
270
271 /*@Function============================================================
272 @Desc: EnterKonsole(): does all konsole- duties
273 This function runs the consoles. This means the following duties:
274 2 * Show a small-scale plan of the current deck
275 3 * Show a side-elevation on the ship
276 1 * Give all available data on lower druid types
277 0 * Reenter the game without squashing the colortable
278 @Ret:
279 @Int:
280 * $Function----------------------------------------------------------*/
281 void
EnterKonsole(void)282 EnterKonsole (void)
283 {
284 int ReenterGame = FALSE;
285 int i, pos, mousemove_buf;
286 SDL_Rect TmpRect;
287 // Prevent distortion of framerate by the delay coming from
288 // the time spend in the menu.
289 Activate_Conservative_Frame_Computation();
290
291 Copy_Rect (User_Rect, TmpRect);
292 Copy_Rect (Full_User_Rect, User_Rect);
293
294 // make sure to release fire keys
295 SpacePressedR();
296 MouseLeftPressedR();
297 MouseRightPressedR();
298
299 ResetMouseWheel ();
300
301 Me.status = CONSOLE;
302
303 SDL_SetCursor (arrow_cursor);
304
305 SetCurrentFont( Para_BFont );
306
307 pos = 0; // starting menu position
308 PaintConsoleMenu (pos, 0);
309
310 /* Gesamtkonsolenschleife */
311
312 while (!ReenterGame)
313 {
314 SDL_Delay(1);
315 if (show_cursor) SDL_ShowCursor (SDL_ENABLE);
316 else SDL_ShowCursor (SDL_DISABLE);
317
318 if (EscapePressedR() || MouseRightPressedR())
319 ReenterGame = TRUE;
320
321 if (UpPressedR () || WheelUpPressed())
322 {
323 MoveMenuPositionSound ();
324 if (pos > 0) pos--;
325 else pos = 3;
326 // when warping the mouse-cursor: don't count that as a mouse-activity
327 // this is a dirty hack, but that should be enough for here...
328 mousemove_buf = last_mouse_event;
329 if (show_cursor)
330 SDL_WarpMouse (Cons_Menu_Rects[pos].x+Cons_Menu_Rects[pos].w/2,
331 Cons_Menu_Rects[pos].y+Cons_Menu_Rects[pos].h/2);
332 keyboard_update (); // this sets a new last_mouse_event
333 last_mouse_event = mousemove_buf; //... which we override.. ;)
334
335
336 PaintConsoleMenu (pos, UPDATE_ONLY);
337 }
338 if (DownPressedR () || WheelDownPressed())
339 {
340 MoveMenuPositionSound ();
341 if (pos < 3) pos++;
342 else pos = 0;
343 // when warping the mouse-cursor: don't count that as a mouse-activity
344 // this is a dirty hack, but that should be enough for here...
345 mousemove_buf = last_mouse_event;
346 if (show_cursor)
347 SDL_WarpMouse (Cons_Menu_Rects[pos].x+Cons_Menu_Rects[pos].w/2,
348 Cons_Menu_Rects[pos].y+Cons_Menu_Rects[pos].h/2);
349 keyboard_update (); // this sets a new last_mouse_event
350 last_mouse_event = mousemove_buf; //... which we override.. ;)
351
352 PaintConsoleMenu (pos, UPDATE_ONLY);
353 }
354
355 // check if the mouse-cursor is on any of the console-menu points
356 for (i=0; i < 4; i++)
357 if (show_cursor && (pos != i) && CursorIsOnRect(&Cons_Menu_Rects[i]) )
358 {
359 MoveMenuPositionSound ();
360 pos = i;
361 PaintConsoleMenu (pos, UPDATE_ONLY);
362 }
363
364 if (FirePressedR())
365 {
366 MenuItemSelectedSound();
367 switch (pos)
368 {
369 case 0:
370 ReenterGame = TRUE;
371 break;
372 case 1:
373 GreatDruidShow ();
374 PaintConsoleMenu (pos, 0);
375 break;
376 case 2:
377 ClearGraphMem();
378 DisplayBanner (NULL, NULL, BANNER_FORCE_UPDATE);
379 ShowDeckMap (CurLevel);
380 PaintConsoleMenu(pos, 0);
381 break;
382 case 3:
383 ClearGraphMem();
384 DisplayBanner (NULL, NULL, BANNER_FORCE_UPDATE);
385 ShowLifts (CurLevel->levelnum, -1);
386
387 while (! (FirePressedR() || EscapePressedR() || MouseRightPressedR() ))
388 SDL_Delay(1);
389 PaintConsoleMenu(pos, 0);
390 break;
391 default:
392 DebugPrintf (1, "Konsole menu out of bounds... pos = %d", pos);
393 pos = 0;
394 break;
395 } // switch
396 } // if SpacePressed
397
398 } /* (while !ReenterGane) */
399
400 Copy_Rect (TmpRect, User_Rect);
401
402 Me.status = MOBILE;
403
404 ClearGraphMem();
405
406 SDL_SetCursor (crosshair_cursor);
407 if (!show_cursor)
408 SDL_ShowCursor (SDL_DISABLE);
409
410 return;
411
412 } // void EnterKonsole(void)
413
414 /*-----------------------------------------------------------------
415 * @Desc: diese Funktion zeigt die m"oglichen Auswahlpunkte des Menus
416 * Sie soll die Schriftfarben nicht ver"andern
417 *
418 * NOTE: this function does not actually _display_ anything yet,
419 * it just prepares the display, so you need
420 * to call SDL_Flip() to display the result!
421 * pos : 0<=pos<=3: which menu-position is currently active?
422 * flag : UPDATE_ONLY only update the console-menu bar, not text & background
423 *-----------------------------------------------------------------*/
424 void
PaintConsoleMenu(int pos,int flag)425 PaintConsoleMenu (int pos, int flag)
426 {
427 char MenuText[200];
428 SDL_Rect src;
429
430 if ( !(flag & UPDATE_ONLY) )
431 {
432 ClearGraphMem ();
433 SDL_SetClipRect ( ne_screen , NULL );
434 SDL_BlitSurface( console_bg_pic1 , NULL , ne_screen , NULL );
435
436 DisplayBanner (NULL, NULL, BANNER_FORCE_UPDATE );
437
438 sprintf (MenuText, "Area : %s\nDeck : %s Alert: %s",
439 curShip.AreaName, CurLevel->Levelname, Alertcolor[AlertLevel]);
440 DisplayText (MenuText, Cons_Header_Rect.x, Cons_Header_Rect.y, &Cons_Header_Rect);
441
442 sprintf (MenuText, "Logout from console\n\nDroid info\n\nDeck map\n\nShip map");
443 DisplayText (MenuText, Cons_Text_Rect.x, Cons_Text_Rect.y+25, &Cons_Text_Rect);
444
445 } // only if not UPDATE_ONLY was required
446
447 src.x = Cons_Menu_Rects[0].w * pos;
448 src.y = 0;
449 src.w = Cons_Menu_Rect.w;
450 src.h = 4 * Cons_Menu_Rect.h;
451 SDL_BlitSurface (console_pic, &src, ne_screen, &Cons_Menu_Rect);
452
453 SDL_Flip (ne_screen);
454
455 return;
456 } // PaintConsoleMenu ()
457
458 /*-----------------------------------------------------------------
459 * @Desc: Displays the concept view of Level "deck" in Userfenster
460 *
461 * Note: we no longer wait here for a key-press, but return
462 * immediately
463 *-----------------------------------------------------------------*/
464 void
ShowDeckMap(Level deck)465 ShowDeckMap (Level deck)
466 {
467 finepoint tmp;
468 tmp.x=Me.pos.x;
469 tmp.y=Me.pos.y;
470
471 Me.pos.x = CurLevel->xlen/2;
472 Me.pos.y = CurLevel->ylen/2;
473
474 SDL_ShowCursor (SDL_DISABLE);
475
476 SetCombatScaleTo( 0.25 );
477
478 Assemble_Combat_Picture( ONLY_SHOW_MAP|SHOW_FULL_MAP );
479
480 SDL_Flip (ne_screen);
481
482 Me.pos.x=tmp.x;
483 Me.pos.y=tmp.y;
484
485 while (! (FirePressedR() || EscapePressedR() || MouseRightPressedR() ))
486 SDL_Delay(1);
487
488 SetCombatScaleTo (1.0);
489
490 return;
491 } /* ShowDeckMap() */
492
493 /*@Function============================================================
494 @Desc:
495
496 @Ret:
497 @Int:
498 * $Function----------------------------------------------------------*/
499 int
LevelEmpty(void)500 LevelEmpty (void)
501 {
502 int i;
503 int levelnum = CurLevel->levelnum;
504
505 if (CurLevel->empty)
506 return TRUE;
507
508 for (i = 0; i < NumEnemys; i++)
509 {
510 if ((AllEnemys[i].levelnum == levelnum) &&
511 ( (AllEnemys[i].status != OUT) && (AllEnemys[i].status != TERMINATED) ) )
512 return FALSE;
513 }
514
515 return TRUE;
516 }
517
518 /* ----------------------------------------------------------------------
519 * This function should check if the mouse cursor is in the given Rectangle
520 * ---------------------------------------------------------------------- */
521 int
CursorIsOnRect(SDL_Rect * rect)522 CursorIsOnRect (SDL_Rect *rect)
523 {
524 point CurPos;
525
526 CurPos.x = input_axis.x + (UserCenter_x - 16);
527 CurPos.y = input_axis.y + (UserCenter_y - 16);
528
529 if ( (CurPos.x >= rect->x) && (CurPos.x <= rect->x + rect->w) )
530 if ( (CurPos.y >= rect->y) && (CurPos.y <= rect->y + rect->h) )
531 return (TRUE);
532
533 return (FALSE);
534
535 }; // int CursorIsOnRect
536
537 /* ----------------------------------------------------------------------
538 * This function does the robot show when the user has selected robot
539 * show from the console menu.
540 * ---------------------------------------------------------------------- */
541 void
GreatDruidShow(void)542 GreatDruidShow (void)
543 {
544 int droidtype;
545 int page;
546 bool finished = FALSE;
547 bool key = FALSE;
548
549 droidtype = Me.type;
550 page = 0;
551
552 show_droid_info (droidtype, page, 0);
553 show_droid_portrait (Cons_Droid_Rect, droidtype, 0.0, UPDATE|RESET);
554
555 SpacePressedR();
556 MouseLeftPressedR();
557
558 while (!finished)
559 {
560 show_droid_portrait (Cons_Droid_Rect, droidtype, DROID_ROTATION_TIME, 0);
561 SDL_Delay(1);
562 if (show_cursor) SDL_ShowCursor (SDL_ENABLE);
563 else SDL_ShowCursor (SDL_DISABLE);
564
565 if (key)
566 {
567 show_droid_info (droidtype, page, UPDATE_ONLY);
568 show_droid_portrait (Cons_Droid_Rect, droidtype, DROID_ROTATION_TIME, UPDATE);
569 key = FALSE;
570 }
571
572 if (MouseLeftPressedR ())
573 {
574 if ( CursorIsOnRect (&left_rect) && (page > 0) )
575 {
576 page --;
577 MoveMenuPositionSound();
578 key = TRUE;
579 }
580 else if (CursorIsOnRect (&right_rect) && (page < 2) )
581 {
582 page ++;
583 MoveMenuPositionSound();
584 key = TRUE;
585 }
586 else if (CursorIsOnRect (&up_rect) && (droidtype < Me.type) )
587 {
588 droidtype ++;
589 MoveMenuPositionSound();
590 key = TRUE;
591 }
592 else if (CursorIsOnRect (&down_rect) && (droidtype > 0))
593 {
594 droidtype --;
595 MoveMenuPositionSound();
596 key = TRUE;
597 }
598 }
599 if (SpacePressedR() || EscapePressedR() || MouseRightPressedR())
600 finished = TRUE;
601
602 if ( (UpPressedR()||WheelUpPressed()) && (droidtype < Me.type) )
603 {
604 droidtype ++;
605 MoveMenuPositionSound();
606 key = TRUE;
607 }
608 if ( (DownPressedR()||WheelDownPressed()) && (droidtype > 0) )
609 {
610 droidtype --;
611 MoveMenuPositionSound();
612 key = TRUE;
613 }
614 if (RightPressedR() && (page < 2) )
615 {
616 page ++;
617 MoveMenuPositionSound();
618 key = TRUE;
619 }
620 if (LeftPressedR() && (page > 0) )
621 {
622 page --;
623 MoveMenuPositionSound();
624 key = TRUE;
625 }
626
627 } /* while !finished */
628
629 return;
630 }; // void GreatDroidShow( void )
631
632 /*------------------------------------------------------------
633 * display infopage page of droidtype
634 *
635 * if flags == UPDATE_ONLY : don't blit a new background&banner,
636 * only update the text-regions
637 *
638 * does update the screen: all if flags=0, text-rect if flags=UPDATE_ONLY
639 *
640 *------------------------------------------------------------*/
641 void
show_droid_info(int droidtype,int page,int flags)642 show_droid_info (int droidtype, int page, int flags)
643 {
644 char InfoText[1000];
645 char DroidName[80];
646 bool show_title = FALSE;
647 bool show_arrows = FALSE;
648 int lineskip, lastline;
649
650 SDL_SetClipRect ( ne_screen , NULL );
651 SetCurrentFont( Para_BFont );
652
653 lineskip = FontHeight (GetCurrentFont()) * TEXT_STRETCH;
654 lastline = Cons_Header_Rect.y + Cons_Header_Rect.h;
655 Set_Rect(up_rect, Cons_Header_Rect.x, lastline - 1.0*lineskip, 25, 13);
656 Set_Rect(down_rect, Cons_Header_Rect.x, lastline - 0.5*lineskip, 25, 13);
657 Set_Rect(left_rect, Cons_Header_Rect.x + Cons_Header_Rect.w - 1.5*lineskip, lastline - 0.9*lineskip,13,25);
658 Set_Rect(right_rect,Cons_Header_Rect.x + Cons_Header_Rect.w - 1.0*lineskip, lastline - 0.9*lineskip,13,25);
659
660 // Fill_Rect (Cons_Header_Rect, Black); // for debugging menu-rects...
661
662 sprintf (DroidName, " Unit type %s - %s", Druidmap[droidtype].druidname,
663 Classname[Druidmap[droidtype].class]);
664
665 switch (page)
666 {
667 case -3: // Title screen: intro unit
668 sprintf (InfoText, "This is the unit that you currently control. Prepare to board Robo-frighter \
669 Paradroid to eliminate all rogue robots.");
670 break;
671 case -2: // Takeover: unit that you wish to control
672 sprintf (InfoText, "This is the unit that you wish to control.\n\n Prepare to takeover.");
673 break;
674 case -1: // Takeover: unit that you control
675 sprintf (InfoText, "This is the unit that you currently control.");
676 break;
677 case 0:
678 show_title = TRUE;
679 show_arrows = TRUE;
680 sprintf (InfoText, "\
681 Entry : %02d\n\
682 Class : %s\n\
683 Height : %5.2f m\n\
684 Weight: %d kg\n\
685 Drive : %s \n\
686 Brain : %s", droidtype+1, Classes[Druidmap[droidtype].class],
687 Druidmap[droidtype].height, Druidmap[droidtype].weight,
688 Drivenames [ Druidmap[ droidtype].drive],
689 Brainnames[ Druidmap[droidtype].brain ]);
690 break;
691 case 1:
692 show_title = TRUE;
693 show_arrows = TRUE;
694 sprintf( InfoText , "\
695 Armament : %s\n\
696 Sensors 1: %s\n\
697 2: %s\n\
698 3: %s",
699 Weaponnames [ Druidmap[droidtype].gun],
700 Sensornames[ Druidmap[droidtype].sensor1 ],
701 Sensornames[ Druidmap[droidtype].sensor2 ],
702 Sensornames[ Druidmap[droidtype].sensor3 ]);
703 break;
704 case 2:
705 show_title = TRUE;
706 show_arrows = TRUE;
707 sprintf (InfoText, "Notes: %s", Druidmap[droidtype].notes);
708 break;
709 default:
710 sprintf (InfoText, "ERROR: Page not implemented!! \nPlease report bug!");
711 break;
712 } /* switch (page) */
713
714
715
716 // if UPDATE_ONLY then the background has not been cleared, so we have do it
717 // it for each menu-rect:
718 if (flags & UPDATE_ONLY)
719 {
720 SDL_SetClipRect (ne_screen, &Cons_Text_Rect);
721 SDL_BlitSurface (console_bg_pic2, NULL, ne_screen, NULL);
722 SDL_SetClipRect (ne_screen, &Cons_Header_Rect);
723 SDL_BlitSurface (console_bg_pic2, NULL, ne_screen, NULL);
724 SDL_SetClipRect (ne_screen, NULL);
725 }
726 else // otherwise we just redraw the whole screen
727 {
728 SDL_BlitSurface (console_bg_pic2, NULL, ne_screen, NULL);
729 DisplayBanner (NULL, NULL, BANNER_NO_SDL_UPDATE | BANNER_FORCE_UPDATE );
730 }
731
732 DisplayText (InfoText, Cons_Text_Rect.x, Cons_Text_Rect.y, &Cons_Text_Rect);
733
734 DisplayText (DroidName, Cons_Header_Rect.x + lineskip , lastline - 0.9*lineskip, NULL);
735
736 if (show_arrows)
737 {
738 if (Me.type > droidtype)
739 SDL_BlitSurface ( arrow_up, NULL, ne_screen, &up_rect);
740
741 if (droidtype > 0)
742 SDL_BlitSurface ( arrow_down, NULL, ne_screen, &down_rect);
743
744 if (page > 0)
745 SDL_BlitSurface ( arrow_left, NULL, ne_screen, &left_rect);
746
747 if (page < 2)
748 SDL_BlitSurface ( arrow_right, NULL, ne_screen, &right_rect);
749 }
750
751 if (flags & UPDATE_ONLY)
752 {
753 SDL_UpdateRects (ne_screen, 1, &Cons_Header_Rect);
754 SDL_UpdateRects (ne_screen, 1, &Cons_Text_Rect);
755 }
756 else
757 SDL_Flip (ne_screen);
758
759 return;
760
761 } /* show_droid_info */
762
763
764 //----------------------------------------------------------------------
765 // show a an animated droid-pic: automatically counts frames and frametimes
766 // stored internally, so you just have to keep calling this function to get
767 // an animation. The target-rect dst is only updated when a new frame is set
768 // if flags & RESET: to restart a fresh animation at frame 0
769 // if flags & UPDATE: force a blit of droid-pic
770 //
771 // cycle_time is the time in seconds for a full animation-cycle,
772 // if cycle_time == 0 : display static pic, using only first frame
773 //
774 //----------------------------------------------------------------------
775 void
show_droid_portrait(SDL_Rect dst,int droid_type,float cycle_time,int flags)776 show_droid_portrait (SDL_Rect dst, int droid_type, float cycle_time, int flags)
777 {
778 static SDL_Surface *background = NULL;
779 static SDL_Surface *droid_pics = NULL;
780 static int frame_num = 0;
781 static int last_droid_type = -1;
782 static Uint32 last_frame_time = 0;
783 static SDL_Rect src_rect;
784 SDL_Surface *tmp;
785 Uint32 frame_duration;
786 bool need_new_frame = FALSE;
787 int num_frames;
788
789 SDL_SetClipRect (ne_screen, &dst);
790
791 if (!background) // first call
792 {
793 tmp = SDL_CreateRGBSurface (0, dst.w, dst.h, screen_bpp, 0, 0, 0, 0);
794 background = SDL_DisplayFormat (tmp);
795 SDL_FreeSurface (tmp);
796 SDL_BlitSurface (ne_screen, &dst, background, NULL);
797 Copy_Rect (Portrait_Rect, src_rect);
798 }
799
800 if (flags & RESET)
801 {
802 SDL_BlitSurface (ne_screen, &dst, background, NULL);
803 frame_num = 0;
804 last_frame_time = SDL_GetTicks ();
805 }
806
807 if ( (droid_type != last_droid_type) || (droid_pics == NULL))
808 { // we need to unpack the droid-pics into our local storage
809 if (droid_pics) SDL_FreeSurface (droid_pics);
810 droid_pics = NULL;
811 tmp = IMG_Load_RW (packed_portraits[droid_type], 0);
812 // important: return seek-position to beginning of RWops for next operation to succeed!
813 SDL_RWseek (packed_portraits[droid_type], 0, SEEK_SET);
814 if (!tmp)
815 {
816 DebugPrintf (0, "ERROR: failed to unpack droid-portraits of droid-type %d\n", droid_type);
817 return; // ok, so no pic but we continue ;)
818 }
819 // now see if its a jpg, then we add some transparency by color-keying:
820 if (IMG_isJPG(packed_portraits[droid_type]))
821 {
822 droid_pics = SDL_DisplayFormat (tmp);
823 } // else assume it's png ;)
824 else
825 {
826 droid_pics = SDL_DisplayFormatAlpha (tmp);
827 }
828 SDL_FreeSurface (tmp);
829 SDL_RWseek (packed_portraits[droid_type], 0, SEEK_SET);
830
831
832 // do we have to scale the droid pics
833 if (GameConfig.scale != 1.0)
834 ScalePic (&droid_pics, GameConfig.scale);
835
836 last_droid_type = droid_type;
837 }
838
839 num_frames = droid_pics->w / Portrait_Rect.w;
840
841 // sanity check
842 if ( num_frames == 0)
843 {
844 DebugPrintf (0, "WARNING: Only one frame found. Width droid-pics=%d, Frame-width=%d\n",
845 droid_pics->w, Portrait_Rect.w);
846 num_frames = 1; // continue and hope for the best
847 }
848
849 frame_duration = SDL_GetTicks() - last_frame_time;
850
851 if (cycle_time && (frame_duration > 1000.0*cycle_time/num_frames) )
852 {
853 need_new_frame = TRUE;
854 frame_num ++;
855 }
856
857 if (frame_num >= num_frames)
858 frame_num = 0;
859
860 if ( (flags & (RESET|UPDATE)) || need_new_frame)
861 {
862 src_rect.x = frame_num*src_rect.w;
863
864 SDL_BlitSurface (background, NULL, ne_screen, &dst);
865 SDL_BlitSurface (droid_pics, &src_rect, ne_screen, &dst);
866
867 SDL_UpdateRects (ne_screen, 1, &dst);
868
869 last_frame_time = SDL_GetTicks();
870
871 }
872
873 SDL_SetClipRect (ne_screen, NULL);
874
875 return;
876
877 } // show_droid_portrait
878
879 // ----------------------------------------------------------------------
880 // do all alert-related agitations: alert-sirens and alert-lights
881 // ----------------------------------------------------------------------
882 #define SIREN_WAIT 2.5
883 #define BLINK_WAIT 0.2
884 void
AlertLevelWarning(void)885 AlertLevelWarning (void)
886 {
887 static Uint32 last_siren = 0;
888 // static Uint32 last_blink = 0;
889 int i, posx, posy;
890 int cur_alert = 0;
891
892
893 switch (AlertLevel)
894 {
895 case AL_GREEN:
896 break;
897 case AL_YELLOW:
898 case AL_AMBER:
899 case AL_RED:
900 if (SDL_GetTicks() - last_siren > SIREN_WAIT * 1000.0 / AlertLevel) // higher alert-> faster sirens!
901 {
902 Play_Sound (ALERT_SOUND);
903 last_siren = SDL_GetTicks ();
904 }
905 break;
906 default:
907 DebugPrintf (0, "WARNING: illegal AlertLevel = %d > %d.. something's gone wrong!!\n",
908 AlertLevel, AL_RED);
909 break;
910 }
911
912 // so much to the sirens, now make sure the alert-tiles are updated correctly:
913 posx = CurLevel->alerts[0].x;
914 posy = CurLevel->alerts[0].y;
915 if (posx == -1) return; // no alerts here...
916
917
918 cur_alert = ALERT_GREEN + AlertLevel;
919
920 // check if alert-tiles are up-to-date
921 if (GetMapBrick(CurLevel, posx, posy) == cur_alert)
922 return; // ok
923
924 for (i=0; i< MAX_ALERTS_ON_LEVEL; i++)
925 {
926 posx = CurLevel->alerts[i].x;
927 posy = CurLevel->alerts[i].y;
928 if ( posx == -1) break;
929
930 CurLevel->map[posy][posx] = cur_alert;
931 }
932
933 return;
934 }
935
936 #undef _ship_c
937