d1-style mission briefings
[btb/d2x.git] / main / titles.c
1 /* $Id: titles.c,v 1.12 2002-08-27 04:15:23 btb Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include <conf.h>
17 #endif
18
19 #define ROBOT_MOVIES
20
21 #ifdef WINDOWS
22 #include "desw.h"
23 #endif
24
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #ifdef MACINTOSH
30 #include <Events.h>
31 #endif
32
33 #include "pa_enabl.h"                   //$$POLY_ACC
34 #include "pstypes.h"
35 #include "timer.h"
36 #include "key.h"
37 #include "gr.h"
38 #include "palette.h"
39 #include "iff.h"
40 #include "pcx.h"
41 #include "u_mem.h"
42 #include "joy.h"
43 #include "mono.h"
44 #include "gamefont.h"
45 #include "cfile.h"
46 #include "error.h"
47 #include "polyobj.h"
48 #include "textures.h"
49 #include "screens.h"
50 #include "multi.h"
51 #include "player.h"
52 #include "digi.h"
53 #include "compbit.h"
54 #include "text.h"
55 #include "kmatrix.h"
56 #include "piggy.h"
57 #include "songs.h"
58 #include "newmenu.h"
59 #include "state.h"
60 #ifdef ROBOT_MOVIES
61 #include "movie.h"
62 #endif
63 #include "menu.h"
64
65 #if defined(POLY_ACC)
66 #include "poly_acc.h"
67 #endif
68
69 #ifdef ROBOT_MOVIES
70 extern void RotateRobot();
71 #endif
72
73 void DoBriefingColorStuff ();
74 int get_new_message_num(char **message);
75 int DefineBriefingBox (char **buf);
76
77 extern unsigned RobSX,RobSY,RobDX,RobDY; // Robot movie coords
78
79 extern int MVEPaletteCalls;
80
81 ubyte New_pal[768];
82 int     New_pal_254_bash;
83
84 char CurBriefScreenName[15]="brief03.pcx";
85 char    * Briefing_text;
86 #ifdef ROBOT_MOVIES
87 char RobotPlaying=0;
88 #endif
89
90 #define MAX_BRIEFING_COLORS     3
91
92 // Descent 1 briefings
93 char Ending_text_filename[13] = "endreg.tex";
94 char Briefing_text_filename[13] = "briefing.tex";
95
96 #define SHAREWARE_ENDING_FILENAME       "ending.tex"
97
98 //      Can be set by -noscreens command line option.  Causes bypassing of all briefing screens.
99 int     Skip_briefing_screens=0;
100 int     Briefing_foreground_colors[MAX_BRIEFING_COLORS], Briefing_background_colors[MAX_BRIEFING_COLORS];
101 int     Current_color = 0;
102 int     Erase_color;
103
104 extern int check_button_press();
105
106 #ifdef MACINTOSH
107 extern void macintosh_quit(void);
108 #endif
109
110 #ifndef ROBOT_MOVIES
111 static int rescale_x(int x)
112 {
113         return x * GWIDTH / 320;
114 }
115
116 static int rescale_y(int y)
117 {
118         return y * GHEIGHT / 200;
119 }
120 #endif
121
122 #ifndef MACINTOSH
123 int local_key_inkey(void)
124 {
125         int     rval;
126
127 #ifdef WINDOWS
128         MSG msg;
129         
130         DoMessageStuff(&msg);
131 #endif
132
133         rval = key_inkey();
134
135         if (rval == KEY_PRINT_SCREEN) {
136                 #ifdef POLY_ACC
137 #ifdef ROBOT_MOVIES
138                 if (RobotPlaying) {
139                         gr_palette_read(gr_palette);
140                         gr_copy_palette(gr_palette,gr_palette,0);       //reset color lookup cache
141                 }
142 #endif
143                 #endif
144                 save_screen_shot(0);
145                 return 0;                               //say no key pressed
146         }
147
148         if (check_button_press())               //joystick or mouse button pressed?
149                 rval = KEY_SPACEBAR;
150
151         #ifdef MACINTOSH
152         if ( rval == KEY_Q+KEY_COMMAND )
153                 macintosh_quit();
154         #endif
155
156         return rval;
157 }
158 #else
159 int local_key_inkey(void)
160 {
161         EventRecord event;
162         int     rval;
163
164         if (!GetOSEvent(everyEvent, &event))
165                 return 0;
166
167         if (event.what != keyDown)
168                 return 0;
169                 
170         rval = (int)((event.message & keyCodeMask) >> 8);
171
172         if (rval == KEY_PRINT_SCREEN) {
173                 save_screen_shot(0);
174                 return 0;                               //say no key pressed
175         }
176
177         if (check_button_press())               //joystick or mouse button pressed?
178                 rval = KEY_SPACEBAR;
179
180         #ifdef MACINTOSH
181         if ( rval == KEY_Q+KEY_COMMAND )
182                 macintosh_quit();
183         #endif
184
185         return rval;
186 }
187 #endif
188
189 int show_title_screen( char * filename, int allow_keys, int from_hog_only )
190 {
191         fix timer;
192         int pcx_error;
193         grs_bitmap title_bm;
194         ubyte   palette_save[768];
195         char new_filename[FILENAME_LEN+1] = "";
196
197         #ifdef RELEASE
198         if (from_hog_only)
199                 strcpy(new_filename,"\x01");    //only read from hog file
200         #endif
201
202         strcat(new_filename,filename);
203         filename = new_filename;
204
205         title_bm.bm_data=NULL;
206         if ((pcx_error=pcx_read_bitmap( filename, &title_bm, BM_LINEAR, New_pal ))!=PCX_ERROR_NONE)     {
207                 printf( "File '%s', PCX load error: %s (%i)\n  (No big deal, just no title screen.)\n",filename, pcx_errormsg(pcx_error), pcx_error);
208                 mprintf((0, "File '%s', PCX load error: %s (%i)\n  (No big deal, just no title screen.)\n",filename, pcx_errormsg(pcx_error), pcx_error));
209                 Error( "Error loading briefing screen <%s>, PCX load error: %s (%i)\n",filename, pcx_errormsg(pcx_error), pcx_error);
210         }
211
212         memcpy(palette_save,gr_palette,sizeof(palette_save));
213
214 #if defined(POLY_ACC)
215     pa_save_clut();
216     pa_update_clut(New_pal, 0, 256, 0);
217 #endif
218
219         //vfx_set_palette_sub( New_pal );
220 #ifdef OGL
221         gr_palette_load( New_pal );
222 #else
223         gr_palette_clear();     
224 #endif
225
226         WINDOS( 
227                 dd_gr_set_current_canvas(NULL),
228                 gr_set_current_canvas( NULL )
229         );
230         WIN(DDGRLOCK(dd_grd_curcanv));
231         show_fullscr(&title_bm);
232         WIN(DDGRUNLOCK(dd_grd_curcanv));
233
234         WIN(DDGRRESTORE);
235
236 #if defined(POLY_ACC)
237     pa_restore_clut();
238 #endif
239
240         if (gr_palette_fade_in( New_pal, 32, allow_keys ))      
241                 return 1;
242         gr_copy_palette(gr_palette, New_pal, sizeof(gr_palette));
243
244         gr_palette_load( New_pal );
245         timer   = timer_get_fixed_seconds() + i2f(3);
246         while (1)       {
247                 if ( local_key_inkey() && allow_keys ) break;
248                 if ( timer_get_fixed_seconds() > timer ) break;
249         }                       
250         if (gr_palette_fade_out( New_pal, 32, allow_keys ))
251                 return 1;
252         gr_copy_palette(gr_palette, palette_save, sizeof(palette_save));
253         d_free(title_bm.bm_data);
254         return 0;
255 }
256
257 typedef struct {
258         char    bs_name[14];                                            //      filename, eg merc01.  Assumes .lbm suffix.
259         byte    level_num;
260         byte    message_num;
261         short   text_ulx, text_uly;                     //      upper left x,y of text window
262         short   text_width, text_height;        //      width and height of text window
263 } briefing_screen;
264
265 #define BRIEFING_SECRET_NUM     31                      //      This must correspond to the first secret level which must come at the end of the list.
266 #define BRIEFING_OFFSET_NUM     4                       // This must correspond to the first level screen (ie, past the bald guy briefing screens)
267
268 #define SHAREWARE_ENDING_LEVEL_NUM  0x7f
269 #define REGISTERED_ENDING_LEVEL_NUM 0x7e
270
271 #ifdef SHAREWARE
272 #define ENDING_LEVEL_NUM        SHAREWARE_ENDING_LEVEL_NUM
273 #else
274 #define ENDING_LEVEL_NUM        REGISTERED_ENDING_LEVEL_NUM
275 #endif
276
277 #define MAX_BRIEFING_SCREENS 60
278
279 briefing_screen Briefing_screens[MAX_BRIEFING_SCREENS]=
280  {{"brief03.pcx",0,3,8,8,257,177}}; // default=0!!!
281
282 int     Briefing_text_x, Briefing_text_y;
283
284 void init_char_pos(int x, int y)
285 {
286         Briefing_text_x = x;
287         Briefing_text_y = y;
288    mprintf ((0,"Setting init x=%d y=%d\n",x,y));
289 }
290
291 grs_canvas      *Robot_canv = NULL;
292 vms_angvec      Robot_angles;
293
294 char    Bitmap_name[32] = "";
295 #define EXIT_DOOR_MAX   14
296 #define OTHER_THING_MAX 10              //      Adam: This is the number of frames in your new animating thing.
297 #define DOOR_DIV_INIT   6
298 byte    Door_dir=1, Door_div_count=0, Animating_bitmap_type=0;
299
300 //      -----------------------------------------------------------------------------
301 void show_bitmap_frame(void)
302 {
303 #ifdef WINDOWS
304         dd_grs_canvas *curcanv_save, *bitmap_canv=0;
305 #else
306         grs_canvas      *curcanv_save, *bitmap_canv=0;
307 #endif
308
309         grs_bitmap      *bitmap_ptr;
310
311         //      Only plot every nth frame.
312         if (Door_div_count) {
313                 Door_div_count--;
314                 return;
315         }
316
317         Door_div_count = DOOR_DIV_INIT;
318
319         if (Bitmap_name[0] != 0) {
320                 char            *pound_signp;
321                 int             num, dig1, dig2;
322
323                 //      Set supertransparency color to black
324                 if (!New_pal_254_bash) {
325                         New_pal_254_bash = 1;
326                         New_pal[254*3] = 0;
327                         New_pal[254*3+1] = 0;
328                         New_pal[254*3+2] = 0;
329                         gr_palette_load( New_pal );
330                 }
331
332                 switch (Animating_bitmap_type) {
333                         case 0:
334                         WINDOS( 
335                                 bitmap_canv = dd_gr_create_sub_canvas(dd_grd_curcanv, 220, 45, 64, 64); break,
336                                 bitmap_canv = gr_create_sub_canvas(grd_curcanv, 220, 45, 64, 64);       break
337                         );
338                         case 1: 
339                         WINDOS(
340                                 bitmap_canv = dd_gr_create_sub_canvas(dd_grd_curcanv, 220, 45, 94, 94); break,
341                                 bitmap_canv = gr_create_sub_canvas(grd_curcanv, 220, 45, 94, 94);       break
342                         );      
343                         
344                         //      Adam: Change here for your new animating bitmap thing. 94, 94 are bitmap size.
345                         default:        Int3(); //      Impossible, illegal value for Animating_bitmap_type
346                 }
347
348                 WINDOS(
349                         curcanv_save = dd_grd_curcanv; dd_grd_curcanv = bitmap_canv,
350                         curcanv_save = grd_curcanv; grd_curcanv = bitmap_canv
351                 );
352
353                 pound_signp = strchr(Bitmap_name, '#');
354                 Assert(pound_signp != NULL);
355
356                 dig1 = *(pound_signp+1);
357                 dig2 = *(pound_signp+2);
358                 if (dig2 == 0)
359                         num = dig1-'0';
360                 else
361                         num = (dig1-'0')*10 + (dig2-'0');
362
363                 switch (Animating_bitmap_type) {
364                         case 0:
365                                 num += Door_dir;
366                                 if (num > EXIT_DOOR_MAX) {
367                                         num = EXIT_DOOR_MAX;
368                                         Door_dir = -1;
369                                 } else if (num < 0) {
370                                         num = 0;
371                                         Door_dir = 1;
372                                 }
373                                 break;
374                         case 1:
375                                 num++;
376                                 if (num > OTHER_THING_MAX)
377                                         num = 0;
378                                 break;
379                 }
380
381                 Assert(num < 100);
382                 if (num >= 10) {
383                         *(pound_signp+1) = (num / 10) + '0';
384                         *(pound_signp+2) = (num % 10) + '0';
385                         *(pound_signp+3) = 0;
386                 } else {
387                         *(pound_signp+1) = (num % 10) + '0';
388                         *(pound_signp+2) = 0;
389                 }
390
391                 {
392                         bitmap_index bi;
393                         bi = piggy_find_bitmap(Bitmap_name);
394                         bitmap_ptr = &GameBitmaps[bi.index];
395                         PIGGY_PAGE_IN( bi );
396                 }
397
398                 WIN(DDGRLOCK(dd_grd_curcanv));
399                 gr_bitmapm(0, 0, bitmap_ptr);
400                 WIN(DDGRUNLOCK(dd_grd_curcanv));
401
402                 WINDOS(
403                         dd_grd_curcanv = curcanv_save,
404                         grd_curcanv = curcanv_save
405                 );
406                 d_free(bitmap_canv);
407
408                 switch (Animating_bitmap_type) {
409                         case 0:
410                                 if (num == EXIT_DOOR_MAX) {
411                                         Door_dir = -1;
412                                         Door_div_count = 64;
413                                 } else if (num == 0) {
414                                         Door_dir = 1;
415                                         Door_div_count = 64;
416                                 }
417                                 break;
418                         case 1:
419                                 break;
420                 }
421         }
422
423 }
424
425 //      -----------------------------------------------------------------------------
426 void show_briefing_bitmap(grs_bitmap *bmp)
427 {
428 #ifdef WINDOWS
429         dd_grs_canvas *bitmap_canv, *curcanv_save;
430   
431         bitmap_canv = dd_gr_create_sub_canvas(dd_grd_curcanv, 220, 45, bmp->bm_w, bmp->bm_h); 
432         curcanv_save = dd_grd_curcanv;
433         dd_gr_set_current_canvas(bitmap_canv);
434         DDGRLOCK(dd_grd_curcanv);
435         gr_bitmapm(0,0,bmp);
436         DDGRUNLOCK(dd_grd_curcanv);
437         dd_gr_set_current_canvas(curcanv_save);
438 #else
439         grs_canvas      *curcanv_save, *bitmap_canv;
440
441         bitmap_canv = gr_create_sub_canvas(grd_curcanv, 220, 45, bmp->bm_w, bmp->bm_h);
442         curcanv_save = grd_curcanv;
443         gr_set_current_canvas(bitmap_canv);
444         gr_bitmapm(0, 0, bmp);
445         gr_set_current_canvas(curcanv_save);
446 #endif
447
448         d_free(bitmap_canv);
449 }
450
451 #ifndef ROBOT_MOVIES //WINDOWS
452 //      -----------------------------------------------------------------------------
453 void show_spinning_robot_frame(int robot_num)
454 {
455         grs_canvas      *curcanv_save;
456
457         if (robot_num != -1) {
458                 Robot_angles.h += 150;
459
460                 curcanv_save = grd_curcanv;
461                 grd_curcanv = Robot_canv;
462                 Assert(Robot_info[robot_num].model_num != -1);
463                 draw_model_picture(Robot_info[robot_num].model_num, &Robot_angles);
464                 grd_curcanv = curcanv_save;
465         }
466
467 }
468
469 //  -----------------------------------------------------------------------------
470 void init_spinning_robot(void) //(int x,int y,int w,int h)
471  {
472 #if 0
473         Robot_angles.p += 0;
474         Robot_angles.b += 0;
475         Robot_angles.h += 0;
476
477 #else
478         int x = rescale_x(138);
479         int y = rescale_y(55);
480         int w = rescale_x(166);
481         int h = rescale_y(138);
482 #endif
483
484         Robot_canv = gr_create_sub_canvas(grd_curcanv, x, y, w, h);
485         // 138, 55, 166, 138
486  }
487 #endif
488
489 //      ---------------------------------------------------------------------------
490 //      Returns char width.
491 //      If show_robot_flag set, then show a frame of the spinning robot.
492 int show_char_delay(char the_char, int delay, int robot_num, int cursor_flag)
493 {
494         int     w, h, aw;
495         char    message[2];
496         static fix      start_time=0;
497
498         robot_num=0;
499         message[0] = the_char;
500         message[1] = 0;
501
502         if (start_time==0 && timer_get_fixed_seconds()<0)
503                 start_time=timer_get_fixed_seconds();
504
505         gr_get_string_size(message, &w, &h, &aw );
506
507         Assert((Current_color >= 0) && (Current_color < MAX_BRIEFING_COLORS));
508
509         //      Draw cursor if there is some delay and caller says to draw cursor
510         if (cursor_flag && delay) {
511                 WIN(DDGRLOCK(dd_grd_curcanv));
512                 gr_set_fontcolor(Briefing_foreground_colors[Current_color], -1);
513                 gr_printf(Briefing_text_x+1, Briefing_text_y, "_" );
514                 WIN(DDGRUNLOCK(dd_grd_curcanv));
515         }
516
517         if (delay)
518                 delay=fixdiv (F1_0,i2f(15));
519
520         if (delay != 0)
521                 show_bitmap_frame();
522
523 #ifdef ROBOT_MOVIES
524         if (RobotPlaying && (delay != 0))
525                 RotateRobot();
526
527         while (timer_get_fixed_seconds() < (start_time + delay)) {
528                 if (RobotPlaying && delay != 0)
529                         RotateRobot();
530         }
531 #else
532         if (robot_num != -1)
533                 show_spinning_robot_frame(robot_num);
534 #endif
535
536         start_time = timer_get_fixed_seconds();
537
538         WIN(DDGRLOCK(dd_grd_curcanv));
539         //      Erase cursor
540         if (cursor_flag && delay) {
541                 gr_set_fontcolor(Erase_color, -1);
542                 gr_printf(Briefing_text_x+1, Briefing_text_y, "_" );
543         }
544
545         //      Draw the character
546         gr_set_fontcolor(Briefing_background_colors[Current_color], -1);
547         gr_printf(Briefing_text_x, Briefing_text_y, message );
548
549         gr_set_fontcolor(Briefing_foreground_colors[Current_color], -1);
550         gr_printf(Briefing_text_x+1, Briefing_text_y, message );
551         WIN(DDGRUNLOCK(dd_grd_curcanv));
552
553         if (delay) gr_update();
554
555 //      if (the_char != ' ')
556 //              if (!digi_is_sound_playing(SOUND_MARKER_HIT))
557 //                      digi_play_sample( SOUND_MARKER_HIT, F1_0 );
558
559         return w;
560 }
561
562 //      -----------------------------------------------------------------------------
563 int load_briefing_screen( int screen_num )
564 {
565         int     pcx_error;
566
567         WIN(DDGRLOCK(dd_grd_curcanv));
568         if ((pcx_error=pcx_read_fullscr( CurBriefScreenName, New_pal ))!=PCX_ERROR_NONE) {
569                 printf( "File '%s', PCX load error: %s\n  (It's a briefing screen.  Does this cause you pain?)\n",Briefing_screens[screen_num].bs_name, pcx_errormsg(pcx_error));
570                 printf( "File '%s', PCX load error: %s (%i)\n  (It's a briefing screen.  Does this cause you pain?)\n",Briefing_screens[screen_num].bs_name, pcx_errormsg(pcx_error), pcx_error);
571                 WIN(DDGRUNLOCK(dd_grd_curcanv));
572                 Error( "Error loading briefing screen <%s>, PCX load error: %s (%i)\n",CurBriefScreenName, pcx_errormsg(pcx_error), pcx_error);
573         }
574         WIN(DDGRUNLOCK(dd_grd_curcanv));
575
576         WIN(DDGRRESTORE);
577
578         return 0;
579 }
580
581 int load_new_briefing_screen( char *fname )
582 {
583         int pcx_error;
584
585         mprintf ((0,"Loading new briefing %s!\n",fname));
586         strcpy (CurBriefScreenName,fname);
587
588         //WIN(DEFINE_SCREEN(CurBriefScreenName));
589
590         if (gr_palette_fade_out( New_pal, 32, 0 ))
591                 return 0;
592
593         WIN(DDGRLOCK(dd_grd_curcanv));
594         if ((pcx_error=pcx_read_fullscr( fname, New_pal ))!=PCX_ERROR_NONE)     {
595         //if ((pcx_error=pcx_read_bitmap( fname, &grd_curcanv->cv_bitmap, grd_curcanv->cv_bitmap.bm_type, New_pal ))!=PCX_ERROR_NONE)     {
596                 printf( "File '%s', PCX load error: %s (%i)\n  (It's a briefing screen.  Does this cause you pain?)\n",fname, pcx_errormsg(pcx_error), pcx_error);
597                 WIN(DDGRUNLOCK(dd_grd_curcanv));
598                 Error( "Error loading briefing screen <%s>, PCX load error: %s (%i)\n",fname, pcx_errormsg(pcx_error), pcx_error);
599         }
600         WIN(DDGRUNLOCK(dd_grd_curcanv));
601
602         WIN(DDGRRESTORE);
603
604         gr_copy_palette(gr_palette, New_pal, sizeof(gr_palette));
605
606         if (gr_palette_fade_in( New_pal, 32, 0 ))
607                 return 0;
608         DoBriefingColorStuff();
609
610         return 1;
611 }
612
613
614
615 #define KEY_DELAY_DEFAULT       ((F1_0*20)/1000)
616
617 //      -----------------------------------------------------------------------------
618 int get_message_num(char **message)
619 {
620         int     num=0;
621
622         while (**message == ' ')
623                 (*message)++;
624
625         while ((**message >= '0') && (**message <= '9')) {
626                 num = 10*num + **message-'0';
627                 (*message)++;
628         }
629
630         while (*(*message)++ != 10)             //      Get and drop eoln
631                 ;
632
633         return num;
634 }
635
636 //      -----------------------------------------------------------------------------
637 void get_message_name(char **message, char *result)
638 {
639         while (**message == ' ')
640                 (*message)++;
641
642         while ((**message != ' ') && (**message != 10)) {
643                 if (**message != '\n')
644                         *result++ = **message;
645                 (*message)++;
646         }
647
648         if (**message != 10)
649                 while (*(*message)++ != 10)             //      Get and drop eoln
650                         ;
651
652         *result = 0;
653 }
654
655 //      -----------------------------------------------------------------------------
656 void flash_cursor(int cursor_flag)
657 {
658         if (cursor_flag == 0)
659                 return;
660
661 WIN(DDGRLOCK(dd_grd_curcanv));
662         if ((timer_get_fixed_seconds() % (F1_0/2) ) > (F1_0/4))
663                 gr_set_fontcolor(Briefing_foreground_colors[Current_color], -1);
664         else
665                 gr_set_fontcolor(Erase_color, -1);
666
667         gr_printf(Briefing_text_x+1, Briefing_text_y, "_" );
668 WIN(DDGRUNLOCK(dd_grd_curcanv));
669 }
670
671 extern int InitMovieBriefing();
672
673 //      -----------------------------------------------------------------------------
674 //      Return true if message got aborted by user (pressed ESC), else return false.
675 int show_briefing_message(int screen_num, char *message)
676 {
677         int     prev_ch=-1;
678         int     ch, done=0,i;
679         briefing_screen *bsp = &Briefing_screens[screen_num];
680         int     delay_count = KEY_DELAY_DEFAULT;
681         int     key_check;
682         int     robot_num=-1;
683         int     rval=0;
684         static int tab_stop=0;
685         int     flashing_cursor=0;
686         int     new_page=0,GotZ=0;
687 #ifdef ROBOT_MOVIES
688         char spinRobotName[]="rba.mve",kludge;  // matt don't change this!
689 #endif
690         char fname[15];
691         char DumbAdjust=0;
692         char chattering=0;
693         int hum_channel=-1,printing_channel=-1;
694         int LineAdjustment=1;
695         WIN(int wpage_done=0);
696
697         Bitmap_name[0] = 0;
698         Current_color = 0;
699 #ifdef ROBOT_MOVIES
700         RobotPlaying=0;
701
702         InitMovieBriefing();
703 #endif
704
705         #ifndef SHAREWARE
706         hum_channel  = digi_start_sound( digi_xlat_sound(SOUND_BRIEFING_HUM), F1_0/2, 0xFFFF/2, 1, -1, -1, -1 );
707         #endif
708  
709         // mprintf((0, "Going to print message [%s] at x=%i, y=%i\n", message, x, y));
710         gr_set_curfont( GAME_FONT );
711
712         bsp=&Briefing_screens[0];
713         init_char_pos(bsp->text_ulx, bsp->text_uly-(8*(1+MenuHires)));
714
715         while (!done) {
716                 ch = *message++;
717                 if (ch == '$') {
718                         ch = *message++;
719                         if (ch=='D') {
720                                 screen_num=DefineBriefingBox (&message);
721                         //load_new_briefing_screen (Briefing_screens[screen_num].bs_name);
722
723                                 bsp = &Briefing_screens[screen_num];
724                                 init_char_pos(bsp->text_ulx, bsp->text_uly);
725                                 //LineAdjustment=0;
726                                 prev_ch = 10;                                   // read to eoln
727                         } else if (ch=='U') {
728                                 screen_num=get_message_num(&message);
729                                 bsp = &Briefing_screens[screen_num];
730                                 init_char_pos(bsp->text_ulx, bsp->text_uly);
731                                 prev_ch = 10;                                   // read to eoln
732                         } else if (ch == 'C') {
733                                 Current_color = get_message_num(&message)-1;
734                                 Assert((Current_color >= 0) && (Current_color < MAX_BRIEFING_COLORS));
735                                 prev_ch = 10;
736                         } else if (ch == 'F') {     // toggle flashing cursor
737                                 flashing_cursor = !flashing_cursor;
738                                 prev_ch = 10;
739                                 while (*message++ != 10)
740                                         ;
741                         } else if (ch == 'T') {
742                                 tab_stop = get_message_num(&message);
743                                 tab_stop*=(1+MenuHires);
744                                 prev_ch = 10;                                                   //      read to eoln
745                         } else if (ch == 'R') {
746                                 if (Robot_canv != NULL) {
747                                         d_free(Robot_canv);
748                                         Robot_canv=NULL;
749                                 }
750 #ifdef ROBOT_MOVIES
751                                 if (RobotPlaying) {
752                                         DeInitRobotMovie();
753                                         RobotPlaying=0;
754                                 }
755
756                                 kludge=*message++;
757                                 spinRobotName[2]=kludge; // ugly but proud
758
759                                 RobotPlaying=InitRobotMovie(spinRobotName);
760
761                                 // gr_remap_bitmap_good( &grd_curcanv->cv_bitmap, pal, -1, -1 );
762
763                                 if (RobotPlaying) {
764                                         DoBriefingColorStuff ();
765                                         mprintf ((0,"Robot playing is %d!!!",RobotPlaying));
766                                 }
767 #else
768                                 init_spinning_robot();
769                                 robot_num = get_message_num(&message);
770 #endif
771                                 prev_ch = 10;                           // read to eoln
772                         } else if (ch == 'N') {
773                                 //--grs_bitmap *bitmap_ptr;
774                                 if (Robot_canv != NULL) {
775                                         d_free(Robot_canv);
776                                         Robot_canv=NULL;
777                                 }
778
779                                 get_message_name(&message, Bitmap_name);
780                                 strcat(Bitmap_name, "#0");
781                                 Animating_bitmap_type = 0;
782                                 prev_ch = 10;
783                         } else if (ch == 'O') {
784                                 if (Robot_canv != NULL) {
785                                                 d_free(Robot_canv);
786                                                 Robot_canv=NULL;
787                                 }
788
789                                 get_message_name(&message, Bitmap_name);
790                                 strcat(Bitmap_name, "#0");
791                                 Animating_bitmap_type = 1;
792                                 prev_ch = 10;
793                         } else if (ch=='A') {
794                                 LineAdjustment=1-LineAdjustment;
795                         } else if (ch=='Z') {
796                                 //mprintf ((0,"Got a Z!\n"));
797                                 GotZ=1;
798 #if defined (D2_OEM) || defined(COMPILATION) || (defined(MACINTOSH) && defined(SHAREWARE))
799                                 DumbAdjust=1;
800 #else
801                                 if (LineAdjustment==1)
802                                         DumbAdjust=1;
803                                 else
804                                         DumbAdjust=2;
805 #endif
806
807                                 i=0;
808                                 while ((fname[i]=*message) != '\n') {
809                                         i++;
810                                         message++;
811                                 }
812                                 fname[i]=0;
813
814                                 if (MenuHires) {
815                                         char fname2[15];
816
817                                         i=0;
818                                         while (fname[i]!='.')
819                                                 fname2[i] = fname[i++];
820 #ifndef SHAREWARE
821                                         fname2[i++]='b';
822 #endif
823                                         fname2[i++]='.';
824                                         fname2[i++]='p';
825                                         fname2[i++]='c';
826                                         fname2[i++]='x';
827                                         fname2[i++]=0;
828
829                                         load_new_briefing_screen (cfexist(fname2)?fname2:fname);
830                                 } else
831                                         load_new_briefing_screen (fname);
832
833                                 //load_new_briefing_screen (MenuHires?"end01b.pcx":"end01.pcx");
834
835                         } else if (ch == 'B') {
836                                 char        bitmap_name[32];
837                                 grs_bitmap  guy_bitmap;
838                                 ubyte       temp_palette[768];
839                                 int         iff_error;
840
841                                 if (Robot_canv != NULL) {
842                                         d_free(Robot_canv);
843                                         Robot_canv=NULL;
844                                 }
845
846                                 get_message_name(&message, bitmap_name);
847                                 strcat(bitmap_name, ".bbm");
848                                 guy_bitmap.bm_data = NULL;
849                                 iff_error = iff_read_bitmap(bitmap_name, &guy_bitmap, BM_LINEAR, temp_palette);
850                                 Assert(iff_error == IFF_NO_ERROR);
851                                 gr_remap_bitmap_good( &guy_bitmap, temp_palette, -1, -1 );
852
853                                 show_briefing_bitmap(&guy_bitmap);
854                                 d_free(guy_bitmap.bm_data);
855                                 prev_ch = 10;
856 //                      } else if (ch==EOF) {
857 //                              done=1;
858 //                      } else if (ch == 'B') {
859 //                              if (Robot_canv != NULL) {
860 //                                      d_free(Robot_canv);
861 //                                      Robot_canv=NULL;
862 //                              }
863 //
864 //                              bitmap_num = get_message_num(&message);
865 //                              if (bitmap_num != -1)
866 //                                      show_briefing_bitmap(Textures[bitmap_num]);
867 //                              prev_ch = 10;                           // read to eoln
868                         } else if (ch == 'S') {
869                                 int keypress;
870                                 fix start_time;
871
872                                 chattering=0;
873                                 if (printing_channel>-1)
874                                         digi_stop_sound( printing_channel );
875                                 printing_channel=-1;
876
877 #ifdef WINDOWS
878                                 if (!wpage_done) {
879                                         DDGRRESTORE;
880                                         wpage_done =1;
881                                 }
882 #endif
883
884                                 start_time = timer_get_fixed_seconds();
885                                 while ( (keypress = local_key_inkey()) == 0 ) {         //      Wait for a key
886 #ifdef WINDOWS
887                                         if (_RedrawScreen) {
888                                                 _RedrawScreen = FALSE;
889                                                 hum_channel  = digi_start_sound( digi_xlat_sound(SOUND_BRIEFING_HUM), F1_0/2, 0xFFFF/2, 1, -1, -1, -1 );
890                                                 keypress = KEY_ESC;
891                                                 break;
892                                         }
893 #endif
894
895                                         while (timer_get_fixed_seconds() < start_time + KEY_DELAY_DEFAULT/2)
896                                                 ;
897                                         flash_cursor(flashing_cursor);
898
899 #ifdef ROBOT_MOVIES
900                                         if (RobotPlaying)
901                                                 RotateRobot ();
902 #else
903                                         show_spinning_robot_frame(robot_num);
904 #endif
905
906                                         show_bitmap_frame();
907                                         start_time += KEY_DELAY_DEFAULT/2;
908                                 }
909
910 #ifndef NDEBUG
911                                 if (keypress == KEY_BACKSP)
912                                         Int3();
913 #endif
914                                 if (keypress == KEY_ESC)
915                                         rval = 1;
916
917                                 flashing_cursor = 0;
918                                 done = 1;
919                                 WIN(wpage_done = 0);
920                         } else if (ch == 'P') {         //      New page.
921                                 if (!GotZ) {
922                                         Int3(); // Hey ryan!!!! You gotta load a screen before you start
923                                                 // printing to it! You know, $Z !!!
924                                     load_new_briefing_screen (MenuHires?"end01b.pcx":"end01.pcx");
925                                 }
926
927                                 new_page = 1;
928                                 while (*message != 10) {
929                                         message++;      //      drop carriage return after special escape sequence
930                                 }
931                                 message++;
932                                 prev_ch = 10;
933                                 gr_update();
934                         }
935                 } else if (ch == '\t') {                //      Tab
936                         if (Briefing_text_x - bsp->text_ulx < tab_stop)
937                                 Briefing_text_x = bsp->text_ulx + tab_stop;
938                 } else if ((ch == ';') && (prev_ch == 10)) {
939                         while (*message++ != 10)
940                                 ;
941                         prev_ch = 10;
942                 } else if (ch == '\\') {
943                         prev_ch = ch;
944                 } else if (ch == 10) {
945                         if (prev_ch != '\\') {
946                                 prev_ch = ch;
947                                 if (1) //DumbAdjust==0)
948                                         Briefing_text_y += (8*(MenuHires+1));
949                                 else
950                                         DumbAdjust--;
951                                 Briefing_text_x = bsp->text_ulx;
952                                 if (Briefing_text_y > bsp->text_uly + bsp->text_height) {
953                                         load_briefing_screen(screen_num);
954                                         Briefing_text_x = bsp->text_ulx;
955                                         Briefing_text_y = bsp->text_uly;
956                                 }
957                         } else {
958                                 if (ch == 13)           //Can this happen? Above says ch==10
959                                         Int3();
960                                 prev_ch = ch;
961                         }
962
963                 } else {
964                         if (!GotZ) {
965                                 Int3(); // Hey ryan!!!! You gotta load a screen before you start
966                                         // printing to it! You know, $Z !!!
967                                 load_new_briefing_screen (MenuHires?"end01b.pcx":"end01.pcx");
968                         }
969
970                         prev_ch = ch;
971
972                         if (!chattering) {
973                                 printing_channel  = digi_start_sound( digi_xlat_sound(SOUND_BRIEFING_PRINTING), F1_0, 0xFFFF/2, 1, -1, -1, -1 );
974                                 chattering=1;
975                         }
976
977                         WIN(if (GRMODEINFO(emul)) delay_count = 0);
978
979                         Briefing_text_x += show_char_delay(ch, delay_count, robot_num, flashing_cursor);
980
981                 }
982
983                 //      Check for Esc -> abort.
984                 if(delay_count)
985                         key_check=local_key_inkey();
986                 else
987                         key_check=0;
988
989 #ifdef WINDOWS
990                 if (_RedrawScreen) {
991                         _RedrawScreen = FALSE;
992                         hum_channel  = digi_start_sound( digi_xlat_sound(SOUND_BRIEFING_HUM), F1_0/2, 0xFFFF/2, 1, -1, -1, -1 );
993                         key_check = KEY_ESC;
994                 }
995 #endif
996                 if ( key_check == KEY_ESC ) {
997                         rval = 1;
998                         done = 1;
999                 }
1000
1001                 if ((key_check == KEY_SPACEBAR) || (key_check == KEY_ENTER))
1002                         delay_count = 0;
1003
1004                 if (Briefing_text_x > bsp->text_ulx + bsp->text_width) {
1005                         Briefing_text_x = bsp->text_ulx;
1006                         Briefing_text_y += bsp->text_uly;
1007                 }
1008
1009                 if ((new_page) || (Briefing_text_y > bsp->text_uly + bsp->text_height)) {
1010                         fix     start_time = 0;
1011                         int     keypress;
1012
1013                         new_page = 0;
1014
1015                         if (printing_channel>-1)
1016                                 digi_stop_sound( printing_channel );
1017                         printing_channel=-1;
1018
1019                         chattering=0;
1020
1021 #ifdef WINDOWS
1022                         if (!wpage_done) {
1023                                 DDGRRESTORE;
1024                                 wpage_done =1;
1025                         }
1026 #endif
1027
1028                         start_time = timer_get_fixed_seconds();
1029                         while ( (keypress = local_key_inkey()) == 0 ) {         //      Wait for a key
1030 #ifdef WINDOWS
1031                                 if (_RedrawScreen) {
1032                                         _RedrawScreen = FALSE;
1033                                         hum_channel  = digi_start_sound( digi_xlat_sound(SOUND_BRIEFING_HUM), F1_0/2, 0xFFFF/2, 1, -1, -1, -1 );
1034                                         keypress = KEY_ESC;
1035                                         break;
1036                                 }
1037 #endif
1038
1039                                 while (timer_get_fixed_seconds() < start_time + KEY_DELAY_DEFAULT/2)
1040                                         ;
1041                                 flash_cursor(flashing_cursor);
1042 #ifdef ROBOT_MOVIES
1043                                 if (RobotPlaying)
1044                                         RotateRobot();
1045 #else
1046                                 show_spinning_robot_frame(robot_num);
1047 #endif
1048                                 show_bitmap_frame();
1049                                 start_time += KEY_DELAY_DEFAULT/2;
1050                         }
1051
1052 #ifdef ROBOT_MOVIES
1053                         if (RobotPlaying)
1054                                 DeInitRobotMovie();
1055                         RobotPlaying=0;
1056 #endif
1057                         robot_num = -1;
1058
1059 #ifndef NDEBUG
1060                         if (keypress == KEY_BACKSP)
1061                                 Int3();
1062 #endif
1063                         if (keypress == KEY_ESC) {
1064                                 rval = 1;
1065                                 done = 1;
1066                         }
1067
1068                         load_briefing_screen(screen_num);
1069                         Briefing_text_x = bsp->text_ulx;
1070                         Briefing_text_y = bsp->text_uly;
1071                         delay_count = KEY_DELAY_DEFAULT;
1072
1073                         WIN(wpage_done = 0);
1074                 }
1075         }
1076
1077 #ifdef ROBOT_MOVIES
1078         if (RobotPlaying) {
1079                 DeInitRobotMovie();
1080                 RobotPlaying=0;
1081         }
1082 #endif
1083
1084         if (Robot_canv != NULL)
1085                 {d_free(Robot_canv); Robot_canv=NULL;}
1086
1087         if (hum_channel>-1)
1088                 digi_stop_sound( hum_channel );
1089         if (printing_channel>-1)
1090                 digi_stop_sound( printing_channel );
1091
1092         return rval;
1093 }
1094
1095 //      -----------------------------------------------------------------------------
1096 //      Return a pointer to the start of text for screen #screen_num.
1097 char * get_briefing_message(int screen_num)
1098 {
1099         char    *tptr = Briefing_text;
1100         int     cur_screen=0;
1101         int     ch;
1102
1103         Assert(screen_num >= 0);
1104
1105         while ( (*tptr != 0 ) && (screen_num != cur_screen)) {
1106                 ch = *tptr++;
1107                 if (ch == '$') {
1108                         ch = *tptr++;
1109                         if (ch == 'S')
1110                                 cur_screen = get_message_num(&tptr);
1111                 }
1112         }
1113
1114    if (screen_num!=cur_screen)
1115          return (NULL);
1116   
1117         return tptr;
1118 }
1119
1120 // -----------------------------------------------------------------------------
1121 //      Load Descent briefing text.
1122 int load_screen_text(char *filename, char **buf)
1123 {
1124         CFILE   *tfile;
1125         CFILE *ifile;
1126         int     len, i,x;
1127         int     have_binary = 0;
1128
1129         if ((tfile = cfopen(filename,"rb")) == NULL) {
1130                 char nfilename[30], *ptr;
1131
1132                 strcpy(nfilename, filename);
1133                 ptr = strrchr(nfilename, '.');
1134                 *ptr = '\0';
1135                 strcat(nfilename, ".txb");
1136                 if ((ifile = cfopen(nfilename, "rb")) == NULL)
1137                 { 
1138                         mprintf ((0,"can't open %s!\n",nfilename));
1139                         return (0); 
1140                         //Error("Cannot open file %s or %s", filename, nfilename); 
1141                 }       
1142    
1143                 mprintf ((0,"reading...\n"));
1144                 have_binary = 1;
1145
1146                 len = cfilelength(ifile);
1147                 MALLOC(*buf, char, len+500); 
1148       mprintf ((0,"len=%d\n",len));
1149                 for (x=0,i=0;i<len;i++,x++)
1150                  {
1151              cfread (*buf+x,1,1,ifile);
1152                 //  mprintf ((0,"%c",*(*buf+x)));
1153                   if (*(*buf+x)==13)
1154                         x--;
1155        }
1156       
1157                 cfclose(ifile);
1158         } else {
1159                 len = cfilelength(tfile);
1160                 MALLOC(*buf, char, len+500); 
1161                 for (x=0,i=0;i<len;i++,x++)
1162                  {
1163              cfread (*buf+x,1,1,tfile);
1164                  // mprintf ((0,"%c",*(*buf+x)));
1165                   if (*(*buf+x)==13)
1166                         x--;
1167        }
1168           
1169       
1170                 //cfread(*buf, 1, len, tfile);
1171                 cfclose(tfile);
1172         }
1173
1174         if (have_binary) {
1175                 char *ptr;
1176
1177                 for (i = 0, ptr = *buf; i < len; i++, ptr++) {
1178                         if (*ptr != '\n') {
1179                                 encode_rotate_left(ptr);
1180                                 *ptr = *ptr ^ BITMAP_TBL_XOR;
1181                                 encode_rotate_left(ptr);
1182                         }
1183                 }
1184         }
1185
1186  return (1);
1187 }
1188
1189 //-----------------------------------------------------------------------------
1190 // Return true if message got aborted, else return false.
1191 int show_briefing_text(int screen_num)
1192 {
1193         char    *message_ptr;
1194
1195         message_ptr = get_briefing_message(screen_num);
1196         if (message_ptr==NULL)
1197                 return (0);
1198
1199         DoBriefingColorStuff();
1200
1201         return show_briefing_message(screen_num, message_ptr);
1202 }
1203
1204 void DoBriefingColorStuff ()
1205 {
1206         Briefing_foreground_colors[0] = gr_find_closest_color_current( 0, 40, 0);
1207         Briefing_background_colors[0] = gr_find_closest_color_current( 0, 6, 0);
1208
1209         Briefing_foreground_colors[1] = gr_find_closest_color_current( 40, 33, 35);
1210         Briefing_background_colors[1] = gr_find_closest_color_current( 5, 5, 5);
1211
1212         Briefing_foreground_colors[2] = gr_find_closest_color_current( 8, 31, 54);
1213         Briefing_background_colors[2] = gr_find_closest_color_current( 1, 4, 7);
1214
1215         Erase_color = gr_find_closest_color_current(0, 0, 0);
1216 }
1217
1218 //-----------------------------------------------------------------------------
1219 // Return true if screen got aborted by user, else return false.
1220 int show_briefing_screen( int screen_num, int allow_keys)
1221 {
1222         int     rval=0;
1223         ubyte   palette_save[768];
1224
1225         New_pal_254_bash = 0;
1226
1227         if (Skip_briefing_screens) {
1228         mprintf((0, "Skipping briefing screen [brief03.pcx]\n"));
1229                 return 0;
1230         }
1231
1232 //      briefing_bm.bm_data=NULL;       
1233 //   if ((pcx_error=pcx_read_bitmap( "brief03.pcx", &briefing_bm, BM_LINEAR, New_pal ))!=PCX_ERROR_NONE)     {
1234 //        mprintf((0, "File '%s', PCX load error: %s (%i)\n  (It's a briefing screen.  Does this cause you pain?)\n","Brief03.pcx", pcx_errormsg(pcx_error), pcx_error));
1235 //              Int3();
1236 //              return 0;
1237 //      }
1238
1239         memcpy(palette_save,gr_palette,sizeof(palette_save));
1240         memcpy(New_pal,gr_palette,sizeof(gr_palette));
1241    
1242
1243 //      vfx_set_palette_sub( New_pal );
1244 //      gr_palette_clear();
1245 //      gr_bitmap( 0, 0, &briefing_bm );
1246 #ifdef OGL
1247         gr_palette_load(New_pal);
1248 #endif
1249
1250 //      if (gr_palette_fade_in( New_pal, 32, allow_keys ))      
1251 //              return 1;
1252 //      memcpy(gr_palette,New_pal,sizeof(gr_palette));
1253
1254         #ifdef MACINTOSH
1255         key_close();            // kill the keyboard handler during briefing screens for movies
1256         #endif
1257         rval = show_briefing_text(screen_num);
1258         #ifdef MACINTOSH
1259         key_init();
1260         #endif
1261         
1262         #if defined (MACINTOSH) || defined(WINDOWS)
1263         memcpy(New_pal,gr_palette,sizeof(gr_palette));          // attempt to get fades after briefing screens done correctly.
1264         #endif
1265
1266
1267         #ifndef WINDOWS 
1268         if (gr_palette_fade_out( New_pal, 32, allow_keys ))
1269                 return 1;
1270    #else
1271                 DEFINE_SCREEN(NULL);
1272                 WIN(DDGRLOCK(dd_grd_curcanv));
1273                 gr_clear_canvas (0);
1274                 WIN(DDGRUNLOCK(dd_grd_curcanv));
1275                 if (gr_palette_fade_out( New_pal, 32, allow_keys ))
1276                         return 1;
1277         #endif
1278
1279         gr_copy_palette(gr_palette, palette_save, sizeof(palette_save));
1280
1281 //      d_free(briefing_bm.bm_data);
1282
1283         return rval;
1284 }
1285
1286
1287 //      -----------------------------------------------------------------------------
1288 void do_briefing_screens(char *filename,int level_num)
1289 {
1290
1291    MVEPaletteCalls=0;
1292
1293         if (Skip_briefing_screens) {
1294                 mprintf((0, "Skipping all briefing screens.\n"));
1295                 return;
1296         }
1297         
1298         #ifdef APPLE_DEMO
1299         return;                 // no briefing screens at all for demo
1300         #endif
1301
1302         mprintf ((0,"Trying briefing screen! %s\n",filename));
1303
1304         if (!filename)
1305                 filename = Briefing_text_filename[0];
1306
1307         if (!filename)
1308                 return;
1309
1310         if (!load_screen_text(filename, &Briefing_text))
1311          return;
1312
1313         #ifdef SHAREWARE
1314         songs_play_song( SONG_BRIEFING, 1 );
1315         #else
1316         songs_stop_all();
1317         #endif
1318
1319         set_screen_mode( SCREEN_MENU );
1320         
1321         WINDOS(
1322                 dd_gr_set_current_canvas(NULL),
1323                 gr_set_current_canvas(NULL)
1324         );
1325
1326         mprintf ((0,"Playing briefing screen! %s %d\n",filename,level_num));
1327
1328         key_flush();
1329         
1330         show_briefing_screen(level_num,0);
1331
1332         d_free (Briefing_text);
1333         key_flush();
1334
1335         return;
1336
1337 }
1338
1339 int DefineBriefingBox (char **buf)
1340  {
1341   int n,i=0;
1342   char name[20];
1343
1344   n=get_new_message_num (buf);
1345
1346         Assert(n < MAX_BRIEFING_SCREENS);
1347
1348   while (**buf!=' ')
1349    {
1350     name[i++]=**buf;
1351     (*buf)++;
1352    }
1353
1354   name[i]='\0';   // slap a delimiter on this guy
1355
1356   strcpy (Briefing_screens[n].bs_name,name);
1357   Briefing_screens[n].level_num=get_new_message_num (buf);
1358   Briefing_screens[n].message_num=get_new_message_num (buf);
1359   Briefing_screens[n].text_ulx=get_new_message_num (buf);
1360   Briefing_screens[n].text_uly=get_new_message_num (buf);
1361   Briefing_screens[n].text_width=get_new_message_num (buf);
1362   Briefing_screens[n].text_height=get_message_num (buf);  // NOTICE!!!
1363
1364   if (MenuHires)
1365         {
1366          Briefing_screens[n].text_ulx*=2;
1367          Briefing_screens[n].text_uly*=2.4;
1368          Briefing_screens[n].text_width*=2;
1369          Briefing_screens[n].text_height*=2.4;
1370         }
1371  
1372   return (n);
1373  }
1374
1375 int get_new_message_num(char **message)
1376 {
1377         int     num=0;
1378
1379         while (**message == ' ')
1380                 (*message)++;
1381
1382         while ((**message >= '0') && (**message <= '9')) {
1383                 num = 10*num + **message-'0';
1384                 (*message)++;
1385         }
1386
1387        (*message)++;
1388
1389         return num;
1390 }
1391