]> icculus.org git repositories - btb/d2x.git/blob - main/editor/ehostage.c
Rename include/error.h to include/dxxerror.h
[btb/d2x.git] / main / editor / ehostage.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14 /*
15  *
16  * Routines for placing hostages, etc...
17  *
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "conf.h"
22 #endif
23
24 #if 0   // the hostage code was simplified for Descent 2
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #ifdef __MSDOS__
29 #include <conio.h>
30 #include <dos.h>
31 #include <direct.h>
32 #endif 
33 #include <string.h>
34 #include <math.h>
35
36 #include "inferno.h"
37 #include "editor.h"
38 #include "timer.h"
39 #include "maths.h"
40 #include "mono.h"
41 #include "dxxerror.h"
42 #include "key.h"
43
44
45 //-------------------------------------------------------------------------
46 // Variables for this module...
47 //-------------------------------------------------------------------------
48 static UI_WINDOW                                *MainWindow = NULL;
49 static UI_GADGET_USERBOX        *HostageViewBox;
50 static UI_GADGET_INPUTBOX       *HostageText;
51 static UI_GADGET_BUTTON         *QuitButton;
52 static int                                              CurrentHostageIndex=-1;
53 static int                                              LastHostageIndex=-1;
54
55 static fix                      Vclip_animation_time=0;                 // How long the rescue sequence has been playing
56 static fix                      Vclip_playback_speed=0;                         // Calculated internally.  Frames/second of vclip.
57 static vclip            *Vclip_ptr = NULL;                              // Used for the vclip on monitor
58
59 void vclip_play( vclip * vc, fix frame_time )   
60 {
61         int bitmapnum;
62
63         if ( vc == NULL )
64                 return;
65
66         if ( vc != Vclip_ptr )  {
67                 // Start new vclip
68                 Vclip_ptr = vc;
69                 Vclip_animation_time = 1;
70
71                 // Calculate the frame/second of the playback
72                 Vclip_playback_speed = fixdiv(i2f(Vclip_ptr->num_frames),Vclip_ptr->play_time);
73         }
74
75         if ( Vclip_animation_time <= 0 )
76                 return;
77
78         // Find next bitmap in the vclip
79         bitmapnum = f2i(Vclip_animation_time);
80
81         // Check if vclip is done playing.
82         if (bitmapnum >= Vclip_ptr->num_frames)         {
83                 Vclip_animation_time    = 1;                                                                                    // Restart this vclip
84                 bitmapnum = 0;
85         }
86
87         PIGGY_PAGE_IN( Vclip_ptr->frames[bitmapnum] );
88         gr_bitmap(0,0,&GameBitmaps[Vclip_ptr->frames[bitmapnum].index] );
89         
90         Vclip_animation_time += fixmul(frame_time, Vclip_playback_speed );
91 }
92
93
94
95 static char HostageMessage[]  = "  ";
96
97 static fix Time;
98
99 int SelectPrevHostage() {
100         int start=0;
101
102         do      {
103                 CurrentHostageIndex--;
104                 if ( CurrentHostageIndex < 0 ) CurrentHostageIndex = MAX_HOSTAGES-1;
105                 start++;
106                 if ( start > MAX_HOSTAGES ) break;
107         } while ( !hostage_is_valid( CurrentHostageIndex ) );
108
109         if (hostage_is_valid( CurrentHostageIndex ) )   {
110                 Cur_object_index = Hostages[CurrentHostageIndex].objnum;
111         } else {
112                 CurrentHostageIndex =-1;
113         }
114         
115         return CurrentHostageIndex;
116 }
117
118
119 int SelectNextHostage() {
120         int start=0;
121
122         do      {
123                 CurrentHostageIndex++;
124                 if ( CurrentHostageIndex >= MAX_HOSTAGES ) CurrentHostageIndex = 0;
125                 start++;
126                 if ( start > MAX_HOSTAGES ) break;
127         } while ( !hostage_is_valid( CurrentHostageIndex ) );
128
129         if (hostage_is_valid( CurrentHostageIndex ) )   {
130                 Cur_object_index = Hostages[CurrentHostageIndex].objnum;
131         } else {
132                 CurrentHostageIndex =-1;
133         }
134         
135         return CurrentHostageIndex;
136 }
137
138
139 int SelectClosestHostage()      {
140         int start=0;
141
142         while ( !hostage_is_valid( CurrentHostageIndex ) )      {
143                 CurrentHostageIndex++;
144                 if ( CurrentHostageIndex >= MAX_HOSTAGES ) CurrentHostageIndex = 0;
145                 start++;
146                 if ( start > MAX_HOSTAGES ) break;
147         }
148
149         if (hostage_is_valid( CurrentHostageIndex ) )   {
150                 Cur_object_index = Hostages[CurrentHostageIndex].objnum;
151         } else {
152                 CurrentHostageIndex =-1;
153         }
154         
155         return CurrentHostageIndex;
156 }
157
158
159 int PlaceHostage()      {
160         int ctype,i;
161         vms_vector      cur_object_loc;
162
163         //update_due_to_new_segment();
164         compute_segment_center(&cur_object_loc, Cursegp);
165
166         ctype = -1;
167         for (i=0; i<Num_total_object_types; i++ )       {
168                 if (ObjType[i] == OL_HOSTAGE )  {
169                         ctype = i;      
170                         break;
171                 }
172         }
173
174         Assert( ctype != -1 );
175
176         if (place_object(Cursegp, &cur_object_loc, ctype )==0)  {
177                 Int3();         // Debug below
178                 i=place_object(Cursegp, &cur_object_loc, ctype );
179                 return 1;
180         }
181
182         if (hostage_object_is_valid( Cur_object_index ) )       {
183                 CurrentHostageIndex     = Objects[Cur_object_index].id;
184         } else {
185                 Int3();         // Get John! (Object should be valid)
186                 i=hostage_object_is_valid( Cur_object_index );  // For debugging only
187         }
188
189         return 0;
190 }
191
192 int CompressHostages()
193 {
194         hostage_compress_all();
195
196         return 0;
197 }
198
199 //@@int SelectPrevVclip()       {
200 //@@    if (!hostage_is_valid( CurrentHostageIndex ) )  
201 //@@            return 0;
202 //@@
203 //@@    if ( Hostages[CurrentHostageIndex].type == 0 )
204 //@@            Hostages[CurrentHostageIndex].type = N_hostage_types-1;
205 //@@    else
206 //@@            Hostages[CurrentHostageIndex].type--;
207 //@@    
208 //@@    if ( Hostages[CurrentHostageIndex].type >= N_hostage_types )
209 //@@            Hostages[CurrentHostageIndex].type = 0;
210 //@@    
211 //@@    return 1;
212 //@@}
213 //@@
214 //@@int SelectNextVclip()       {
215 //@@    if (!hostage_is_valid( CurrentHostageIndex ) )  
216 //@@            return 0;
217 //@@
218 //@@    Hostages[CurrentHostageIndex].type++;
219 //@@    if ( Hostages[CurrentHostageIndex].type >= N_hostage_types )
220 //@@            Hostages[CurrentHostageIndex].type = 0;
221 //@@
222 //@@    return 1;
223 //@@}
224
225 int SelectNextFace()
226 {
227         int start = Hostages[CurrentHostageIndex].vclip_num;
228         
229         if (!hostage_is_valid( CurrentHostageIndex ) )  
230                 return 0;
231
232         do {
233                 Hostages[CurrentHostageIndex].vclip_num++;
234                 if ( Hostages[CurrentHostageIndex].vclip_num >= MAX_HOSTAGES)
235                         Hostages[CurrentHostageIndex].vclip_num = 0;
236
237                 if (Hostages[CurrentHostageIndex].vclip_num == start)
238                         return 0;
239
240         } while (Hostage_face_clip[Hostages[CurrentHostageIndex].vclip_num].num_frames == 0);
241
242         return 1;
243 }
244
245 int SelectPrevFace()
246 {
247         int start = Hostages[CurrentHostageIndex].vclip_num;
248         
249         if (!hostage_is_valid( CurrentHostageIndex ) )  
250                 return 0;
251
252         do {
253                 Hostages[CurrentHostageIndex].vclip_num--;
254                 if ( Hostages[CurrentHostageIndex].vclip_num < 0)
255                         Hostages[CurrentHostageIndex].vclip_num = MAX_HOSTAGES-1;
256
257                 if (Hostages[CurrentHostageIndex].vclip_num == start)
258                         return 0;
259
260         } while (Hostage_face_clip[Hostages[CurrentHostageIndex].vclip_num].num_frames == 0);
261
262         return 1;
263 }
264
265 int PlayHostageSound()  {
266         int sound_num;
267
268         if (!hostage_is_valid( CurrentHostageIndex ) )  
269                 return 0;
270
271         sound_num = Hostage_face_clip[Hostages[CurrentHostageIndex].vclip_num].sound_num;
272
273         if ( sound_num > -1 )   {
274                 digi_play_sample( sound_num, F1_0 );
275         }
276
277         return 1;       
278 }
279
280 //@@int find_next_hostage_sound()       {
281 //@@    int start=0,n;
282 //@@
283 //@@    n = Hostages[CurrentHostageIndex].sound_num;
284 //@@    do      {
285 //@@            n++;
286 //@@            if ( n < SOUND_HOSTAGE_VOICES ) n = SOUND_HOSTAGE_VOICES+MAX_HOSTAGE_SOUNDS-1;
287 //@@            if ( n >= SOUND_HOSTAGE_VOICES+MAX_HOSTAGE_SOUNDS ) n = SOUND_HOSTAGE_VOICES;
288 //@@            start++;
289 //@@            if ( start > MAX_HOSTAGE_SOUNDS ) break;
290 //@@    } while ( Sounds[n] == NULL );
291 //@@
292 //@@    if ( Sounds[n] == NULL )
293 //@@            Hostages[CurrentHostageIndex].sound_num = -1;
294 //@@    else    {
295 //@@            Hostages[CurrentHostageIndex].sound_num = n;
296 //@@            PlayHostageSound();
297 //@@    }
298 //@@    return 1;
299 //@@}
300 //@@
301 //@@int find_prev_hostage_sound()       {
302 //@@    int start=0,n;
303 //@@
304 //@@    n = Hostages[CurrentHostageIndex].sound_num;
305 //@@    do      {
306 //@@            n--;
307 //@@            if ( n < SOUND_HOSTAGE_VOICES ) n = SOUND_HOSTAGE_VOICES+MAX_HOSTAGE_SOUNDS-1;
308 //@@            if ( n >= SOUND_HOSTAGE_VOICES+MAX_HOSTAGE_SOUNDS ) n = SOUND_HOSTAGE_VOICES;
309 //@@            start++;
310 //@@            if ( start > MAX_HOSTAGE_SOUNDS ) break;
311 //@@    } while ( Sounds[n] == NULL );
312 //@@
313 //@@    if ( Sounds[n] == NULL )
314 //@@            Hostages[CurrentHostageIndex].sound_num = -1;
315 //@@    else    {
316 //@@            Hostages[CurrentHostageIndex].sound_num = n;
317 //@@            PlayHostageSound();
318 //@@    }
319 //@@    return 1;
320 //@@}
321
322 #endif // 0
323
324 //-------------------------------------------------------------------------
325 // Called from the editor... does one instance of the hostage dialog box
326 //-------------------------------------------------------------------------
327 int do_hostage_dialog()
328 {
329 #if 0
330         int i;
331
332         // Only open 1 instance of this window...
333         if ( MainWindow != NULL ) return 0;
334         
335         // Close other windows
336         close_all_windows();
337
338         CurrentHostageIndex = 0;
339         SelectClosestHostage();
340
341         // Open a window with a quit button
342         MainWindow = ui_open_window( TMAPBOX_X+10, TMAPBOX_Y+20, 765-TMAPBOX_X, 545-TMAPBOX_Y, WIN_DIALOG );
343         QuitButton = ui_add_gadget_button( MainWindow, 20, 222, 48, 40, "Done", NULL );
344
345         ui_wprintf_at( MainWindow, 10, 32,"&Message:" );
346         HostageText = ui_add_gadget_inputbox( MainWindow, 10, 50, HOSTAGE_MESSAGE_LEN, HOSTAGE_MESSAGE_LEN, HostageMessage );
347
348         // The little box the hostage vclip will play in.
349         HostageViewBox = ui_add_gadget_userbox( MainWindow,10, 90+10, 64, 64 );
350
351         // A bunch of buttons...
352         i = 90;
353 //@@    ui_add_gadget_button( MainWindow,155,i,70, 26, "<< Type", SelectPrevVclip );
354 //@@    ui_add_gadget_button( MainWindow,155+70,i,70, 26, "Type >>", SelectNextVclip );i += 29;         
355 //@@    ui_add_gadget_button( MainWindow,155,i,70, 26, "<< Sound",  find_prev_hostage_sound );
356 //@@    ui_add_gadget_button( MainWindow,155+70,i,70, 26, "Sound >>", find_next_hostage_sound );i += 29;                
357
358         ui_add_gadget_button( MainWindow,155,i,70, 26, "<< Face", SelectPrevFace );
359         ui_add_gadget_button( MainWindow,155+70,i,70, 26, "Face >>", SelectNextFace );i += 29;          
360         ui_add_gadget_button( MainWindow,155,i,140, 26, "Play sound", PlayHostageSound );i += 29;               
361         ui_add_gadget_button( MainWindow,155,i,140, 26, "Next Hostage", SelectNextHostage );    i += 29;                
362         ui_add_gadget_button( MainWindow,155,i,140, 26, "Prev Hostage", SelectPrevHostage ); i += 29;           
363         ui_add_gadget_button( MainWindow,155,i,140, 26, "Compress All", CompressHostages ); i += 29;            
364         ui_add_gadget_button( MainWindow,155,i,140, 26, "Delete", ObjectDelete );       i += 29;                
365         ui_add_gadget_button( MainWindow,155,i,140, 26, "Create New", PlaceHostage );   i += 29;                
366         
367         Time = timer_get_fixed_seconds();
368
369         LastHostageIndex = -2;          // Set to some dummy value so everything works ok on the first frame.
370         
371 //      if ( CurrentHostageIndex == -1 )
372 //              SelectNextHostage();
373 #endif
374         return 1;
375
376 }
377
378 void hostage_close_window()
379 {
380 #if 0
381         if ( MainWindow!=NULL ) {
382                 ui_close_window( MainWindow );
383                 MainWindow = NULL;
384         }
385 #endif
386 }
387
388 void do_hostage_window()
389 {
390 #if 0   // redundant
391         fix DeltaTime, Temp;
392
393         if ( MainWindow == NULL ) return;
394
395         SelectClosestHostage();
396
397         //------------------------------------------------------------
398         // Call the ui code..
399         //------------------------------------------------------------
400         ui_button_any_drawn = 0;
401         ui_window_do_gadgets(MainWindow);
402
403         //------------------------------------------------------------
404         // If we change objects, we need to reset the ui code for all
405         // of the radio buttons that control the ai mode.  Also makes
406         // the current AI mode button be flagged as pressed down.
407         //------------------------------------------------------------
408         if (LastHostageIndex != CurrentHostageIndex )   {
409
410                 if ( CurrentHostageIndex > -1 ) 
411                         strcpy( HostageText->text, Hostages[CurrentHostageIndex].text );
412                 else
413                         strcpy(HostageText->text, " " );
414
415                 HostageText->position = strlen(HostageText->text);
416                 HostageText->oldposition = HostageText->position;
417                 HostageText->status=1;
418                 HostageText->first_time = 1;
419
420         }
421
422         //------------------------------------------------------------
423         // If any of the radio buttons that control the mode are set, then
424         // update the cooresponding AI state.
425         //------------------------------------------------------------
426         if ( CurrentHostageIndex > -1 ) 
427                 strcpy( Hostages[CurrentHostageIndex].text, HostageText->text );
428
429         //------------------------------------------------------------
430         // A simple frame time counter for spinning the objects...
431         //------------------------------------------------------------
432         Temp = timer_get_fixed_seconds();
433         DeltaTime = Temp - Time;
434         Time = Temp;
435
436         //------------------------------------------------------------
437         // Redraw the object in the little 64x64 box
438         //------------------------------------------------------------
439         if (CurrentHostageIndex > -1 )  {
440                 int vclip_num;
441                 
442                 vclip_num = Hostages[CurrentHostageIndex].vclip_num;
443
444                 Assert(vclip_num != -1);
445
446                 gr_set_current_canvas( HostageViewBox->canvas );
447
448                 if ( vclip_num > -1 )   {
449                         vclip_play( &Hostage_face_clip[vclip_num], DeltaTime ); 
450                 } else {
451                         gr_clear_canvas( CGREY );
452                 }
453         } else {
454                 // no hostage, so just blank out
455                 gr_set_current_canvas( HostageViewBox->canvas );
456                 gr_clear_canvas( CGREY );
457         }
458
459         //------------------------------------------------------------
460         // If anything changes in the ui system, redraw all the text that
461         // identifies this robot.
462         //------------------------------------------------------------
463         if (ui_button_any_drawn || (LastHostageIndex != CurrentHostageIndex) )  {
464                 if ( CurrentHostageIndex > -1 ) {
465                         ui_wprintf_at( MainWindow, 10, 15, "Hostage: %d   Object: %d", CurrentHostageIndex, Hostages[CurrentHostageIndex].objnum );
466                         //@@ui_wprintf_at( MainWindow, 10, 73, "Type: %d   Sound: %d   ", Hostages[CurrentHostageIndex].type, Hostages[CurrentHostageIndex].sound_num );
467                         ui_wprintf_at( MainWindow, 10, 73, "Face: %d   ", Hostages[CurrentHostageIndex].vclip_num);
468                 }       else {
469                         ui_wprintf_at( MainWindow, 10, 15, "Hostage: none " );
470                         //@@ui_wprintf_at( MainWindow, 10, 73, "Type:    Sound:       " );
471                         ui_wprintf_at( MainWindow, 10, 73, "Face:         " );
472                 }
473                 Update_flags |= UF_WORLD_CHANGED;
474         }
475
476         if ( QuitButton->pressed || (last_keypress==KEY_ESC))   {
477                 hostage_close_window();
478                 return;
479         }               
480
481         LastHostageIndex = CurrentHostageIndex;
482 #endif
483 }
484
485
486