1 /*
2
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 */
19 /*
20 * $Source: r:/prj/cit/src/RCS/vmail.c $
21 * $Revision: 1.31 $
22 * $Author: xemu $
23 * $Date: 1994/11/01 09:17:43 $
24 *
25 */
26
27 #include "Shock.h"
28
29 // KLC #include <screen.h>
30 #include "game_screen.h"
31 #include "vmail.h"
32 #include "invent.h"
33 #include "mainloop.h"
34 #include "gameloop.h"
35 #include "tools.h"
36 #include "gametime.h"
37 #include "sfxlist.h"
38 #include "musicai.h"
39 #include "player.h"
40 #include "statics.h"
41 #include "fullscrn.h"
42 #include "render.h"
43 #include "gr2ss.h"
44 #include "criterr.h"
45
46 #include "anim.h"
47
48 //#include <mprintf.h>
49 //#define LOTS_O_SPEW
50 uchar vmail_wait_for_input = TRUE;
51
52 //#define CONTINUOUS_VMAIL_TEST
53
54 ActAnim *main_anim;
55
56 #define NUM_VMAIL 6
57 #define INTRO_VMAIL (NUM_VMAIL+1)
58
59 byte current_vmail = -1;
60 extern LGCursor vmail_cursor;
61
62 extern void SDLDraw(void);
63 extern void pump_events(void);
64
65 Ref vmail_frame_anim[NUM_VMAIL] = {
66 RES_FRAMES_shield,
67 RES_FRAMES_grove,
68 RES_FRAMES_bridge,
69 RES_FRAMES_laser1,
70 RES_FRAMES_status,
71 RES_FRAMES_explode1
72 };
73
74 Ref vmail_res[NUM_VMAIL] = {
75 RES_shield,
76 RES_grove,
77 RES_bridge,
78 RES_laser1,
79 RES_status,
80 RES_explode1
81 };
82
83 ubyte vmail_len[NUM_VMAIL] = {
84 1, // shield
85 1, // grove
86 1, // bridge
87 2, // laser
88 1, // status
89 5, // explode
90 };
91
92 #define MAX_VMAIL_SIZE 100000
93
94 // --------------------------------------------------------------------
95 //
96 //
97
98 extern grs_canvas *anim_offscreen;
99 uchar copied_background = FALSE;
100 grs_bitmap *vmail_background = NULL;
101 extern uchar uiCheckInput(void);
102
103 #pragma disable_message(202)
vmail_intro(LGRect * area,ubyte flags)104 void vmail_intro(LGRect *area, ubyte flags)
105 {
106 if (flags & BEFORE_ANIM_BITMAP)
107 {
108 if (vmail_background)
109 gr_bitmap(vmail_background, 0, 0);
110 }
111 }
112 #pragma enable_message(202)
113
114 // --------------------------------------------------------------------
115 //
116 //
117
118 #pragma disable_message(202)
vmail_anim_end(ActAnim * paa,AnimCode ancode,AnimCodeData * pdata)119 void vmail_anim_end(ActAnim *paa, AnimCode ancode, AnimCodeData *pdata)
120 {
121 #ifdef PLAYTEST
122 if (current_vmail == -1)
123 {
124 Warning(("Trying to end vmail, with no current vmail!\n"));
125 }
126 #endif
127 current_vmail = -1;
128 }
129 #pragma enable_message(202)
130
131 // --------------------------------------------------------------------
132 //
133 //
134
135 #pragma disable_message(202)
vmail_start_anim_end(ActAnim * paa,AnimCode ancode,AnimCodeData * pdata)136 void vmail_start_anim_end(ActAnim *paa, AnimCode ancode, AnimCodeData *pdata)
137 {
138 #ifdef PLAYTEST
139 if (current_vmail == -1)
140 {
141 Warning(("Trying to end vmail, with no current vmail!\n"));
142 }
143 #endif
144 current_vmail = -1;
145 }
146 #pragma enable_message(202)
147
148 #define EARLY_EXIT ((errtype)200)
149
150 // ---------------------------------------------
151 //
152 // play_vmail_intro()
153 //
154
155 #define MOVIE_BUFFER_SIZE (512 * 1024)
156
play_vmail_intro(uchar use_texture_buffer)157 errtype play_vmail_intro(uchar use_texture_buffer)
158 {
159 LGPoint animloc = {VINTRO_X, VINTRO_Y};
160 uchar *p, *useBuffer;
161 int bsize;
162 short w,h;
163
164 DEBUG("Playing vmail intro");
165
166 main_anim = AnimPlayRegion(REF_ANIM_vintro, mainview_region, animloc, 0, vmail_intro);
167 if (main_anim == NULL)
168 return(ERR_NOEFFECT);
169
170 if (use_texture_buffer)
171 {
172 AnimSetDataBufferSafe(main_anim, tmap_static_mem,sizeof(tmap_static_mem));
173 AnimPreloadFrames(main_anim, REF_ANIM_vintro);
174 }
175
176 // let's slork up memory!!!!
177 w = VINTRO_W;
178 h = VINTRO_H;
179 {
180 useBuffer = frameBuffer;
181 bsize = sizeof(frameBuffer);
182 }
183 if ((w * h) + sizeof(grs_bitmap) > bsize)
184 critical_error(CRITERR_MEM|8);
185 p = useBuffer+bsize-(w*h);
186 vmail_background = (grs_bitmap *) (p - sizeof(grs_bitmap));
187
188 gr_init_bm(vmail_background, p, BMT_FLAT8, 0, w,h);
189 uiHideMouse(NULL);
190 #ifdef SVGA_SUPPORT
191 if (convert_use_mode)
192 {
193 grs_canvas tempcanv;
194 gr_make_canvas(vmail_background,&tempcanv);
195 gr_push_canvas(&tempcanv);
196 gr_clear(1);
197 gr_pop_canvas();
198 }
199 else
200 #endif
201 gr_get_bitmap(vmail_background, VINTRO_X, VINTRO_Y);
202 uiShowMouse(NULL);
203
204 AnimSetNotify(main_anim, NULL, ANCODE_KILL, vmail_start_anim_end);
205 current_vmail = INTRO_VMAIL;
206 play_digi_fx(SFX_VMAIL, 1);
207
208 #ifdef LOTS_O_SPEW
209 mprintf("*PLAY INTRO*");
210 #endif
211 while (current_vmail != -1)
212 {
213 AnimRecur();
214 tight_loop(TRUE);
215 }
216 #ifdef LOTS_O_SPEW
217 mprintf("*DONE INTRO*");
218 #endif
219 vmail_background = NULL;
220
221 return(OK);
222 }
223
224 // --------------------------------------------------------------------
225 //
226 // play_vmail()
227 //
228
229 #pragma disable_message(202)
play_vmail(byte vmail_no)230 errtype play_vmail(byte vmail_no)
231 {
232 LGPoint animloc = {VINTRO_X, VINTRO_Y};
233 errtype intro_error;
234 int vmail_animfile_num = 0;
235 uchar early_exit = FALSE;
236 uchar preload_animation= TRUE;
237 uchar use_texture_buffer = FALSE;
238 int len = vmail_len[vmail_no];
239 int i;
240 //MemStat data;
241
242 // let's extern
243
244 DEBUG("Playing vmail %i", vmail_no);
245
246 // the more I look at this procedure - the more I think
247 // art - what were you thinking
248 extern uiSlab fullscreen_slab;
249 extern uiSlab main_slab;
250 extern uchar game_paused;
251 extern uchar checking_mouse_button_emulation;
252 extern uchar citadel_check_input(void);
253 extern void email_page_exit(void);
254 extern short old_invent_page;
255
256 // make sure we don't have a current vmail, and we're given a valid vmail num
257 if ((current_vmail != -1) || (vmail_no < 0) || (vmail_no >= NUM_VMAIL))
258 return(ERR_NOEFFECT);
259
260 if (full_game_3d)
261 render_run();
262
263 // spew the appropriate text for vmail - full screen needs a draw!
264 suspend_game_time();
265 time_passes = FALSE;
266 checking_mouse_button_emulation = game_paused = TRUE;
267
268 // open the res file
269 vmail_animfile_num = ResOpenFile("res/data/vidmail.res");
270 if (vmail_animfile_num < 0)
271 return(ERR_FOPEN);
272
273 uiPushSlabCursor(&fullscreen_slab, &vmail_cursor);
274 uiPushSlabCursor(&main_slab, &vmail_cursor);
275
276 //MemStats(&data);
277 //use_texture_buffer = (data.free.sizeMax < MAX_VMAIL_SIZE);
278
279 #ifdef LOTS_O_SPEW
280 mprintf("\nBUFFER:(%d)\n", use_texture_buffer);
281 #endif
282
283 // if we're not using the texture buffer - then we can probably
284 // preload the animations
285 if (!use_texture_buffer)
286 {
287 uchar cant_preload_all = FALSE;
288
289 // load the intro in first! before checking for preloading
290 if (ResLock(RES_FRAMES_vintro) == NULL)
291 use_texture_buffer = TRUE;
292 else
293 {
294 for (i=0;i<len && !cant_preload_all;i++)
295 {
296 // check if we have enough memory to preload another segment
297 /*MemStats(&data);
298 if (data.free.sizeMax < MAX_VMAIL_SIZE)
299 {
300 cant_preload_all = TRUE;
301 break;
302 }*/
303
304 // preload vmail frame animation first, and then play intro -> no pause between the two
305 // if it fails on the lock - then say you can't preload!
306 if(ResLock(vmail_frame_anim[vmail_no]+i) == NULL)
307 {
308 cant_preload_all = TRUE;
309 break;
310 }
311 }
312 // if we failed our preloading for whatever reason
313 // let's unlock it all - drop it so that it doesn't stay
314 // in memory
315 if (cant_preload_all)
316 {
317 int j;
318 preload_animation = FALSE;
319 for (j=0; j<i;j++)
320 {
321 ResUnlock(vmail_frame_anim[vmail_no]+j);
322 ResDrop(vmail_frame_anim[vmail_no]+j);
323 }
324 ResUnlock(RES_FRAMES_vintro);
325 ResDrop(RES_FRAMES_vintro);
326 use_texture_buffer = TRUE;
327 #ifdef LOTS_O_SPEW
328 mprintf("**TRIED TO PRELOAD-CAN'T PRELOAD**\n");
329 #endif
330 }
331 }
332 }
333 else
334 preload_animation = FALSE;
335
336 #ifdef LOTS_O_SPEW
337 mprintf("**PREL:(%d) INTRO:(%d)**", preload_animation, use_texture_buffer);
338 #endif
339 intro_error = play_vmail_intro(use_texture_buffer);
340 if (preload_animation)
341 {
342 ResUnlock(RES_FRAMES_vintro);
343 ResDrop(RES_FRAMES_vintro);
344 }
345
346 if (intro_error != OK) // did it have no effect - don't worry about texture buffer
347 {
348 // if we had a problem with the intro - then flush
349 // the animation all out - close it and
350 // then return error code
351 DEBUG("Could not play vmail intro");
352 if (preload_animation)
353 for (i=0;i<len;i++)
354 {
355 ResUnlock(vmail_frame_anim[vmail_no]+i);
356 ResDrop(vmail_frame_anim[vmail_no]+i);
357 }
358 ResCloseFile(vmail_animfile_num);
359 return(intro_error);
360 }
361
362 for (i=0; (i<len) && !early_exit;i++)
363 {
364 DEBUG("Playing segment.");
365 Ref vmail_ref = MKREF(vmail_res[vmail_no]+i,0);
366 main_anim = AnimPlayRegion(vmail_ref,mainview_region,animloc, 0, NULL);
367 if (main_anim == NULL)
368 {
369 early_exit = TRUE;
370 break;
371 }
372 if(use_texture_buffer)
373 {
374 AnimSetDataBufferSafe(main_anim, tmap_static_mem, sizeof(tmap_static_mem));
375 AnimPreloadFrames(main_anim, vmail_ref);
376 }
377 current_vmail = vmail_no;
378
379 AnimSetNotify(main_anim, NULL, ANCODE_KILL, vmail_anim_end);
380 uiFlush();
381 while (current_vmail != -1)
382 {
383 #ifdef LOTS_O_SPEW
384 // mprintf("R");
385 #endif
386 AnimRecur();
387 #ifdef LOTS_O_SPEW
388 // mprintf("S");
389 #endif
390 if(citadel_check_input())
391 {
392 early_exit = TRUE;
393 #ifdef LOTS_O_SPEW
394 mprintf("Early Exit\n");
395 #endif
396 AnimKill(main_anim);
397 }
398 tight_loop(TRUE);
399 }
400 }
401
402 DEBUG("Finished playing!");
403 if (preload_animation)
404 {
405 for (i=0;i<len;i++)
406 {
407 ResUnlock(vmail_frame_anim[vmail_no]+i);
408 ResDrop(vmail_frame_anim[vmail_no]+i);
409 }
410 }
411 ResCloseFile(vmail_animfile_num);
412
413 #ifdef LOTS_O_SPEW
414 mprintf("T");
415 #endif
416 uiFlush();
417 #ifdef LOTS_O_SPEW
418 mprintf("U");
419 #endif
420
421 if (use_texture_buffer)
422 {
423 #ifdef LOTS_O_SPEW
424 mprintf("V");
425 #endif
426 load_textures();
427 #ifdef LOTS_O_SPEW
428 mprintf("W");
429 #endif
430 }
431
432 #ifndef CONTINUOUS_VMAIL_TEST
433 if (!early_exit && vmail_wait_for_input)
434 while (!citadel_check_input()) {
435 uiHideMouse(NULL); //trick to prevent
436 uiShowMouse(NULL); // mouse pointer freeze
437 pump_events();
438 SDLDraw();
439 tight_loop(FALSE); //keep the music playing
440 }
441 #endif
442
443 email_page_exit();
444
445 screen_draw();
446 inventory_draw_new_page(old_invent_page);
447
448 DEBUG("Resuming game time");
449 resume_game_time();
450 checking_mouse_button_emulation = game_paused = FALSE;
451
452 // let the player wait before firing auto fire weapon
453 player_struct.auto_fire_click = player_struct.game_time + 60;
454 time_passes = TRUE;
455
456 #ifdef LOTS_O_SPEW
457 mprintf("X");
458 #endif
459 uiPopSlabCursor(&fullscreen_slab);
460 uiPopSlabCursor(&main_slab);
461 #ifdef LOTS_O_SPEW
462 mprintf("Y");
463 #endif
464 chg_set_flg(DEMOVIEW_UPDATE);
465
466 return(OK);
467 }
468 #pragma enable_message(202)
469
470 byte test_vmail = 0;
471 #pragma disable_message(202)
shield_test_func(short keycode,ulong context,void * data)472 uchar shield_test_func(short keycode, ulong context, void* data)
473 {
474 int i;
475 vmail_wait_for_input = FALSE;
476 for (i=0;i<5; i++)
477 {
478 play_vmail(test_vmail);
479 test_vmail = (test_vmail+1)%NUM_VMAIL;
480 }
481 vmail_wait_for_input = TRUE;
482 return(TRUE);
483 }
484 #pragma enable_message(202)
485
486 #ifdef PLAYTEST
487 #pragma disable_message(202)
shield_off_func(short keycode,ulong context,void * data)488 uchar shield_off_func(short keycode, ulong context, void* data)
489 {
490 return(TRUE);
491 }
492 #pragma enable_message(202)
493
494 #endif
495