00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef HAVE_CONFIG_H
00020 # include <config.h>
00021 #endif
00022
00023 #ifndef ALPHA_LINUX_CXX
00024 # include <cctype>
00025 #endif
00026
00027 #include "SDL_events.h"
00028 #include "files/U7file.h"
00029 #include "files/utils.h"
00030 #include "flic/playfli.h"
00031 #include "gamewin.h"
00032 #include "Audio.h"
00033 #include "sigame.h"
00034 #include "palette.h"
00035 #include "databuf.h"
00036 #include "font.h"
00037 #include "txtscroll.h"
00038 #include "exult_types.h"
00039 #include "mappatch.h"
00040 #include "shapeid.h"
00041
00042 #ifndef UNDER_CE
00043 using std::cout;
00044 using std::endl;
00045 using std::rand;
00046 using std::strlen;
00047 using std::toupper;
00048 #endif
00049
00050 SI_Game::SI_Game()
00051 {
00052 add_shape("gumps/check",2);
00053 add_shape("gumps/fileio",3);
00054 add_shape("gumps/fntext",4);
00055 add_shape("gumps/loadbtn",5);
00056 add_shape("gumps/savebtn",6);
00057 add_shape("gumps/halo",7);
00058 add_shape("gumps/disk",19);
00059 add_shape("gumps/heart",20);
00060 add_shape("gumps/statatts",23);
00061 add_shape("gumps/musicbtn",24);
00062 add_shape("gumps/speechbtn",25);
00063 add_shape("gumps/soundbtn",26);
00064 add_shape("gumps/spellbook",38);
00065 add_shape("gumps/combat",41);
00066 add_shape("gumps/statsdisplay",42);
00067 add_shape("gumps/quitbtn",50);
00068 add_shape("gumps/yesnobox",51);
00069 add_shape("gumps/yesbtn",52);
00070 add_shape("gumps/nobtn",53);
00071 add_shape("gumps/book",27);
00072 add_shape("gumps/scroll",49);
00073 add_shape("gumps/combat_stats",91);
00074 add_shape("gumps/combatmode",12);
00075 add_shape("gumps/slider",14);
00076 add_shape("gumps/slider_diamond",15);
00077 add_shape("gumps/slider_right",16);
00078 add_shape("gumps/slider_left",17);
00079
00080 add_shape("gumps/box", 0);
00081 add_shape("gumps/crate", 1);
00082 add_shape("gumps/barrel", 8);
00083 add_shape("gumps/bag", 9);
00084 add_shape("gumps/backpack", 10);
00085 add_shape("gumps/basket", 11);
00086 add_shape("gumps/chest", 18);
00087 add_shape("gumps/shipshold", 21);
00088 add_shape("gumps/drawer", 22);
00089 add_shape("gumps/woodsign", 44);
00090 add_shape("gumps/tombstone", 45);
00091 add_shape("gumps/goldsign", 46);
00092 add_shape("gumps/body", 48);
00093 add_shape("gumps/tree", 64);
00094
00095 add_shape("gumps/cstats/1",58);
00096 add_shape("gumps/cstats/2",59);
00097 add_shape("gumps/cstats/3",60);
00098 add_shape("gumps/cstats/4",61);
00099 add_shape("gumps/cstats/5",62);
00100 add_shape("gumps/cstats/6",63);
00101
00102 add_shape("sprites/map", 22);
00103 add_shape("sprites/cheatmap", 0);
00104
00105
00106 add_shape("gumps/spell_scroll",65);
00107 add_shape("gumps/jawbone", 56);
00108 add_shape("gumps/tooth", 57);
00109
00110 add_resource("files/shapes/count", 0, 8);
00111 add_resource("files/shapes/0", "<STATIC>/shapes.vga", 0);
00112 add_resource("files/shapes/1", "<STATIC>/faces.vga", 0);
00113 add_resource("files/shapes/2", "<STATIC>/gumps.vga", 0);
00114 add_resource("files/shapes/3", "<STATIC>/sprites.vga", 0);
00115 add_resource("files/shapes/4", MAINSHP_FLX, 0);
00116 add_resource("files/shapes/5", "<STATIC>/paperdol.vga", 0);
00117 add_resource("files/shapes/6", "<DATA>/exult.flx", 0);
00118 add_resource("files/shapes/7", "<STATIC>/fonts.vga", 0);
00119
00120 add_resource("files/gameflx", "<DATA>/exult_si.flx", 0);
00121
00122 add_resource("config/defaultkeys", "<DATA>/exult_si.flx", 1);
00123
00124 add_resource("palettes/count", 0, 14);
00125 add_resource("palettes/0", PALETTES_FLX, 0);
00126 add_resource("palettes/1", PALETTES_FLX, 1);
00127 add_resource("palettes/2", PALETTES_FLX, 2);
00128 add_resource("palettes/3", PALETTES_FLX, 3);
00129 add_resource("palettes/4", PALETTES_FLX, 4);
00130 add_resource("palettes/5", PALETTES_FLX, 5);
00131 add_resource("palettes/6", PALETTES_FLX, 6);
00132 add_resource("palettes/7", PALETTES_FLX, 7);
00133 add_resource("palettes/8", PALETTES_FLX, 8);
00134 add_resource("palettes/9", PALETTES_FLX, 9);
00135 add_resource("palettes/10", PALETTES_FLX, 10);
00136 add_resource("palettes/11", PALETTES_FLX, 11);
00137 add_resource("palettes/12", PALETTES_FLX, 12);
00138 add_resource("palettes/13", MAINSHP_FLX, 1);
00139 add_resource("palettes/14", MAINSHP_FLX, 26);
00140
00141 fontManager.add_font("MENU_FONT", MAINSHP_FLX, 9, 1);
00142 fontManager.add_font("SIINTRO_FONT", "<STATIC>/intro.dat", 14, 0);
00143 Map_patch_collection *mp = gwin->get_map_patches();
00144
00145 mp->add(new Map_patch_remove(Object_spec(
00146 Tile_coord(647, 1899, 0), 275, 7, 1)));
00147
00148 mp->add(new Map_patch_remove(Object_spec(
00149 Tile_coord(1035, 2572, 8), 483, 1, 0), true));
00150 mp->add(new Map_patch_remove(Object_spec(
00151 Tile_coord(1034, 2571, 6), 483, 1, 0)));
00152 mp->add(new Map_patch_remove(Object_spec(
00153 Tile_coord(1034, 2571, 5), 483, 1, 0), true));
00154
00155 mp->add(new Map_patch_modify(Object_spec(
00156 Tile_coord(1012, 873, 0), 867, 13, 0),
00157 Object_spec(
00158 Tile_coord(1013, 873, 1), 867, 13, 0)));
00159
00160 }
00161
00162 SI_Game::~SI_Game()
00163 {
00164 }
00165
00166
00167 static int get_frame (void)
00168 {
00169 int num = rand() % 9;
00170
00171 if (num >= 8) return 2;
00172 else if (num >= 6) return 1;
00173 return 0;
00174 }
00175
00176 void SI_Game::play_intro()
00177 {
00178 int next = 0;
00179 size_t flisize;
00180 char *fli_b = 0;
00181 uint8 *buffer = 0;
00182 size_t size;
00183 size_t shapesize;
00184 char * shape_buf = 0;
00185 int i,j;
00186 Font *font = fontManager.get_font("MENU_FONT");
00187 Font *sifont = fontManager.get_font("SIINTRO_FONT");
00188
00189 bool speech = Audio::get_ptr()->is_speech_enabled();
00190
00191 gwin->clear_screen(true);
00192
00193 Audio::get_ptr()->stop_music();
00194
00195
00196 try
00197 {
00198 U7object lbflic("<STATIC>/intro.dat", 0);
00199 fli_b = lbflic.retrieve(flisize);
00200 playfli fli0(fli_b+8, flisize-8);
00201 fli0.info();
00202
00203 const char *txt_msg[] = { "with help from",
00204 "The Exult Team",
00205 "Driven by Exult" };
00206
00207 for (j = 0; j < 20; j++)
00208 {
00209 next = fli0.play(win, 0, 0, next, j*5);
00210 font->center_text(ibuf, centerx, centery+50, txt_msg[0]);
00211 font->center_text(ibuf, centerx, centery+65, txt_msg[1]);
00212 win->show();
00213 }
00214
00215
00216 next = fli0.play(win, 0, 0, next, 100);
00217 font->center_text(ibuf, centerx, centery+50, txt_msg[0]);
00218 font->center_text(ibuf, centerx, centery+65, txt_msg[1]);
00219 win->show();
00220
00221 if (wait_delay (3000))
00222 throw UserBreakException();
00223
00224 for (j = 20; j; j--)
00225 {
00226 next = fli0.play(win, 0, 0, next, j*5);
00227 font->center_text(ibuf, centerx, centery+50, txt_msg[0]);
00228 font->center_text(ibuf, centerx, centery+65, txt_msg[1]);
00229 win->show();
00230 }
00231
00232
00233 FORGET_ARRAY(fli_b);
00234
00235 if (wait_delay (0))
00236 throw UserBreakException();
00237
00238 gwin->clear_screen(true);
00239
00240
00241
00242
00243
00244 Audio *audio = Audio::get_ptr();
00245 if (audio) {
00246 const char *fn = "<STATIC>/r_sintro.xmi";
00247 MyMidiPlayer *midi = audio->get_midi();
00248 if (midi && midi->is_fm_synth()) fn = "<STATIC>/a_sintro.xmi";
00249 audio->start_music (fn, 0, false);
00250 }
00251
00252
00253 if (speech)
00254 {
00255 U7object voc_thunder("<STATIC>/intro.dat", 15);
00256 buffer = (uint8 *) voc_thunder.retrieve(size);
00257 Audio::get_ptr()->play (buffer+8, size-8, false);
00258 }
00259
00260 U7object flic("<STATIC>/intro.dat", 1);
00261 fli_b = flic.retrieve(flisize);
00262 playfli fli1(fli_b+8, flisize-8);
00263 fli1.info();
00264
00265 fli1.play(win, 0, 1, 0, 0);
00266
00267 next = SDL_GetTicks();
00268 int prev = -1;
00269 int num;
00270
00271 for (j = 0; j < 20; j++)
00272 {
00273 num = get_frame();
00274 if (prev != num)
00275 for (i = 0; i < num+1; i++)
00276 fli1.play(win, i, i, next);
00277
00278 prev = num;
00279 next += 75;
00280 win->show();
00281 if (wait_delay (1))
00282 throw UserBreakException();
00283
00284 }
00285
00286 const char *lb_cas = "Lord British's Castle";
00287 const char *db_cas = "Dick British's Castle";
00288
00289 for (j = 0; j < 50; j++)
00290 {
00291 num = get_frame();
00292 if (prev != num)
00293 for (i = 0; i < num+1; i++)
00294 fli1.play(win, i, i, next);
00295
00296 if (jive)
00297 sifont->center_text(ibuf, centerx, centery+50, db_cas);
00298 else
00299 sifont->center_text(ibuf, centerx, centery+50, lb_cas);
00300
00301 prev = num;
00302 next += 75;
00303 win->show();
00304 if (wait_delay (1))
00305 throw UserBreakException();
00306
00307 }
00308
00309 for (j = 0; j < 10; j++)
00310 {
00311 num = get_frame();
00312 if (prev != num)
00313 for (i = 0; i < num+1; i++)
00314 fli1.play(win, i, i, next);
00315
00316
00317 if (speech && j == 5) {
00318 Audio::get_ptr()->play (buffer+8, size-8, false);
00319 FORGET_ARRAY(buffer);
00320 }
00321
00322 prev = num;
00323 next += 75;
00324 win->show();
00325 if (wait_delay (1))
00326 throw UserBreakException();
00327
00328 }
00329
00330 const char *bg_fellow[] = { "Eighteen months after the destruction",
00331 "of the Black Gate and the",
00332 "dismantling of The Fellowship"};
00333
00334
00335 for (j = 0; j < 75; j++)
00336 {
00337 num = get_frame();
00338 if (prev != num)
00339 for (i = 0; i < num+1; i++)
00340 fli1.play(win, i, i, next);
00341
00342 for(i=0; i<3; i++) {
00343 sifont->center_text(ibuf, centerx, centery+50+15*i, bg_fellow[i]);
00344 }
00345
00346 prev = num;
00347 next += 75;
00348 win->show();
00349 if (wait_delay (1))
00350 throw UserBreakException();
00351
00352 }
00353
00354 for (j = 20; j; j--)
00355 {
00356 next = fli1.play(win, 0, 0, next, j*5);
00357 win->show();
00358 if (wait_delay (0))
00359 throw UserBreakException();
00360
00361 }
00362 FORGET_ARRAY(fli_b);
00363
00364 if (wait_delay (0))
00365 throw UserBreakException();
00366
00367
00368 gwin->clear_screen(true);
00369
00370
00371 U7object flic2("<STATIC>/intro.dat", 2);
00372 fli_b = flic2.retrieve(flisize);
00373 playfli fli2(fli_b+8, flisize-8);
00374 fli2.info();
00375
00376 for (j = 0; j < 20; j++)
00377 {
00378 next = fli2.play(win, 0, 0, next, j*5);
00379 win->show();
00380 if (wait_delay (0))
00381 throw UserBreakException();
00382 }
00383
00384
00385 for (j = 0; j < 37; j++)
00386 {
00387 next = fli2.play(win, j, j, next);
00388 win->show();
00389 if (wait_delay (0))
00390 throw UserBreakException();
00391 }
00392
00393
00394 const char *my_leige = "My leige";
00395 const char *yo_homes = "Yo, homes";
00396
00397 if (speech && !jive)
00398 {
00399 U7object voc_my_leige("<STATIC>/intro.dat", 16);
00400 buffer = (uint8 *) voc_my_leige.retrieve (size);
00401 Audio::get_ptr()->play (buffer+8, size-8, false);
00402 FORGET_ARRAY(buffer);
00403 }
00404
00405
00406 for (; j < 55; j++)
00407 {
00408 next = fli2.play(win, j, j, next);
00409
00410 if (jive)
00411 sifont->draw_text(ibuf, centerx+30, centery+87, yo_homes);
00412 else if (!speech)
00413 sifont->draw_text(ibuf, centerx+30, centery+87, my_leige);
00414
00415 win->show();
00416 if (wait_delay (0))
00417 throw UserBreakException();
00418 }
00419
00420 next = fli2.play(win, j, j, next);
00421 win->show();
00422
00423 const char *all_we[2] = { "All we found among Batlin's",
00424 "belongings was this enchanted scroll.." };
00425
00426 if (speech && !jive)
00427 {
00428 U7object voc_all_we("<STATIC>/intro.dat", 17);
00429 buffer = (uint8 *) voc_all_we.retrieve (size);
00430 Audio::get_ptr()->play (buffer+8, size-8, false);
00431 FORGET_ARRAY(buffer);
00432 }
00433
00434 for (; j < 73; j++)
00435 {
00436 next = fli2.play(win, j, j, next);
00437
00438 if (!speech || jive)
00439 {
00440 sifont->draw_text(ibuf, centerx+150-sifont->get_text_width(all_we[0]), centery+74, all_we[0]);
00441 sifont->draw_text(ibuf, centerx+160-sifont->get_text_width(all_we[1]), centery+87, all_we[1]);
00442 }
00443
00444 win->show();
00445 if (wait_delay (0))
00446 throw UserBreakException();
00447 }
00448 for (i = 0; i < 220; i++)
00449 if (wait_delay (10))
00450 throw UserBreakException();
00451
00452 const char *and_a[2] = { "and a map showing the way to",
00453 "a place called the Serpent Isle" };
00454
00455 next = fli2.play(win, j, j, next);
00456
00457 if (!speech || jive)
00458 {
00459 sifont->draw_text(ibuf, centerx+150-sifont->get_text_width(and_a[0]), centery+74, and_a[0]);
00460 sifont->draw_text(ibuf, centerx+150-sifont->get_text_width(and_a[1]), centery+87, and_a[1]);
00461 }
00462
00463 win->show();
00464 j++;
00465
00466 for (i = 0; i < 290; i++)
00467 if (wait_delay (10))
00468 throw UserBreakException();
00469
00470
00471 fli2.play(win, j, j);
00472 j++;
00473
00474 for (i = 0; i < 50; i++)
00475 if (wait_delay (10))
00476 throw UserBreakException();
00477
00478 const char *indeed[2] = { "Indeed.",
00479 "Put it on the table." };
00480
00481 const char *iree = "Iree. Slap it down there!";
00482
00483 if (speech && !jive)
00484 {
00485 U7object voc_indeed("<STATIC>/intro.dat", 18);
00486 buffer = (uint8 *) voc_indeed.retrieve(size);
00487 Audio::get_ptr()->play (buffer+8, size-8, false);
00488 FORGET_ARRAY(buffer);
00489 }
00490
00491 next = fli2.play(win, j, j);
00492 j++;
00493
00494 for (; j < 81; j++)
00495 {
00496 next = fli2.play(win, j, j, next);
00497
00498 if (jive)
00499 sifont->draw_text(ibuf, topx+40, centery+74, iree);
00500 else if (!speech)
00501 {
00502 sifont->draw_text(ibuf, topx+40, centery+74, indeed[0]);
00503 sifont->draw_text(ibuf, topx+40, centery+87, indeed[1]);
00504 }
00505
00506 win->show();
00507 if (wait_delay (0))
00508 throw UserBreakException();
00509 }
00510
00511 for (i = 0; i < 200; i++)
00512 if (wait_delay (10))
00513 throw UserBreakException();
00514
00515 FORGET_ARRAY(fli_b);
00516
00517
00518 gwin->clear_screen(true);
00519
00520
00521 U7object flic3("<STATIC>/intro.dat", 3);
00522 fli_b = flic3.retrieve(flisize);
00523 playfli fli3(fli_b+8, flisize-8);
00524 fli3.info();
00525
00526 next = 0;
00527
00528
00529 for (j = 0; j < 20; j++)
00530 {
00531 next = fli3.play(win, j, j, next)+20;
00532 win->show();
00533 if (wait_delay (0))
00534 throw UserBreakException();
00535 }
00536
00537
00538
00539 const char *stand_back = "Stand Back!";
00540 const char *jump_back = "Jump Back!";
00541
00542 if (speech && !jive)
00543 {
00544 U7object voc_stand_back("<STATIC>/intro.dat", 19);
00545 buffer = (uint8 *) voc_stand_back.retrieve(size);
00546 Audio::get_ptr()->play (buffer+8, size-8, false);
00547 FORGET_ARRAY(buffer);
00548 }
00549
00550 for (; j < 61; j++)
00551 {
00552 next = fli3.play(win, j, j, next)+20;
00553
00554 if (jive)
00555 sifont->draw_text(ibuf, topx+70, centery+60, jump_back);
00556 else if (!speech)
00557 sifont->draw_text(ibuf, topx+70, centery+60, stand_back);
00558
00559 win->show();
00560 if (wait_delay (0))
00561 throw UserBreakException();
00562 }
00563
00564 FORGET_ARRAY(fli_b);
00565
00566
00567 gwin->clear_screen(true);
00568
00569
00570 U7object flic4("<STATIC>/intro.dat", 4);
00571 fli_b = flic4.retrieve(flisize);
00572 playfli fli4(fli_b+8, flisize-8);
00573 fli4.info();
00574
00575 U7object shapes("<STATIC>/intro.dat", 30);
00576 shape_buf = shapes.retrieve(shapesize);
00577 BufferDataSource gshape_ds(shape_buf+8, shapesize-8);
00578 Shape_frame *sf;
00579
00580 Shape_file gshape(&gshape_ds);
00581
00582 cout << "Shape in intro.dat has " << gshape.get_num_frames() << endl;
00583
00584 if (speech && !jive)
00585 {
00586 U7object voc_big_g("<STATIC>/intro.dat", 20);
00587 buffer = (uint8 *) voc_big_g.retrieve ( size);
00588 Audio::get_ptr()->play (buffer+8, size-8, false);
00589 FORGET_ARRAY(buffer);
00590 }
00591
00592 next = 0;
00593
00594
00595 const char *batlin[2] = { "Batlin! In the event that the",
00596 "Avatar destroys the Black Gate" };
00597
00598 const char *you_shall[2] = { "you shall follow the unwitting",
00599 "human Gwenno to the Serpent Isle" };
00600
00601 const char *there_i[2] = { "There I shall outline my plan",
00602 "to destroy Britannia!" };
00603
00604
00605 const char *batlin2[2] = { "Batlin! Know that my face is most",
00606 "muppet like!" };
00607
00608 const char *you_must[2] = { "You must go to the Serpent Isle",
00609 "to learn the secret of Acne Medication" };
00610
00611 const char *soon_i[2] = { "Soon I and my horde of muppets will",
00612 "destroy Britannia!" };
00613
00614 for (j = 0; j < 320; j++)
00615 {
00616 next = fli4.play(win, j%40, j%40, next);
00617
00618 if (j < 300)
00619 sf = gshape.get_frame((j/2)%7);
00620 else
00621 sf = gshape.get_frame(0);
00622
00623 if (sf)
00624 sman->paint_shape (centerx-36, centery, sf);
00625
00626 if (j < 100 && jive)
00627 {
00628 sifont->center_text(ibuf, centerx, centery+74, batlin2[0]);
00629 sifont->center_text(ibuf, centerx, centery+87, batlin2[1]);
00630 }
00631 else if (j < 200 && jive)
00632 {
00633 sifont->center_text(ibuf, centerx, centery+74, you_must[0]);
00634 sifont->center_text(ibuf, centerx, centery+87, you_must[1]);
00635 }
00636 else if (j < 300 && jive)
00637 {
00638 sifont->center_text(ibuf, centerx, centery+74, soon_i[0]);
00639 sifont->center_text(ibuf, centerx, centery+87, soon_i[1]);
00640 }
00641 else if (j < 100 && !speech)
00642 {
00643 sifont->center_text(ibuf, centerx, centery+74, batlin[0]);
00644 sifont->center_text(ibuf, centerx, centery+87, batlin[1]);
00645 }
00646 else if (j < 200 && !speech)
00647 {
00648 sifont->center_text(ibuf, centerx, centery+74, you_shall[0]);
00649 sifont->center_text(ibuf, centerx, centery+87, you_shall[1]);
00650 }
00651 else if (j < 300 && !speech)
00652 {
00653 sifont->center_text(ibuf, centerx, centery+74, there_i[0]);
00654 sifont->center_text(ibuf, centerx, centery+87, there_i[1]);
00655 }
00656
00657 win->show();
00658 if (wait_delay (0))
00659 throw UserBreakException();
00660 }
00661 sf = gshape.get_frame(0);
00662
00663 for (j = 20; j; j--)
00664 {
00665 next = fli4.play(win, 0, 0, next, j*5);
00666 if (sf)
00667 sman->paint_shape (centerx-36, centery, sf);
00668
00669 win->show();
00670 if (wait_delay (0))
00671 throw UserBreakException();
00672 }
00673
00674 FORGET_ARRAY(shape_buf);
00675 FORGET_ARRAY(fli_b);
00676
00677
00678 gwin->clear_screen(true);
00679
00680
00681 U7object flic5("<STATIC>/intro.dat", 5);
00682 fli_b = flic5.retrieve(flisize);
00683 playfli fli5(fli_b+8, flisize-8);
00684 fli5.info();
00685
00686 for (j=0; j < 20; j++)
00687 {
00688 next = fli5.play(win, 0, 0, next, j*5);
00689
00690 win->show();
00691 if (wait_delay (0))
00692 throw UserBreakException();
00693 }
00694
00695
00696 const char *tis_my[3] = {"'Tis my worst fear!",
00697 "I must send the Avatar through",
00698 "the pillars to the Serpent Isle!" };
00699
00700
00701 if (speech && !jive)
00702 {
00703 U7object voc_tis_my("<STATIC>/intro.dat", 21);
00704 buffer = (uint8 *) voc_tis_my.retrieve(size);
00705 Audio::get_ptr()->play (buffer+8, size-8, false);
00706 FORGET_ARRAY(buffer);
00707 }
00708
00709 for (j=0; j < 61; j++)
00710 {
00711 next = fli5.play(win, j, j, next)+30;
00712
00713 if (j < 20 && (!speech || jive))
00714 {
00715 sifont->center_text(ibuf, centerx, centery+74, tis_my[0]);
00716 }
00717 else if (j > 22 && (!speech || jive))
00718 {
00719 sifont->center_text(ibuf, centerx, centery+74, tis_my[1]);
00720 sifont->center_text(ibuf, centerx, centery+87, tis_my[2]);
00721 }
00722
00723 win->show();
00724 if (wait_delay (0))
00725 throw UserBreakException();
00726 }
00727
00728 FORGET_ARRAY(fli_b);
00729
00730
00731 gwin->clear_screen(true);
00732
00733
00734 U7object flic6("<STATIC>/intro.dat", 6);
00735 fli_b = flic6.retrieve(flisize);
00736 playfli fli6(fli_b+8, flisize-8);
00737 fli6.info();
00738
00739 for (j=0; j < 61; j++)
00740 {
00741 next = fli6.play(win, j, j, next)+30;
00742
00743 win->show();
00744 if (wait_delay (0))
00745 throw UserBreakException();
00746 }
00747
00748 FORGET_ARRAY(fli_b);
00749
00750
00751 gwin->clear_screen(true);
00752
00753
00754 U7object flic7("<STATIC>/intro.dat", 7);
00755 fli_b = flic7.retrieve(flisize);
00756 playfli fli7(fli_b+8, flisize-8);
00757 fli7.info();
00758
00759 const char *zot = "Zot!";
00760
00761 for (j=0; j < 61; j++)
00762 {
00763 next = fli7.play(win, j, j, next)+30;
00764
00765 if (j > 55 && jive)
00766 sifont->center_text(ibuf, centerx, centery+74, zot);
00767
00768 win->show();
00769 if (wait_delay (0))
00770 throw UserBreakException();
00771 }
00772
00773 FORGET_ARRAY(fli_b);
00774
00775
00776 gwin->clear_screen(true);
00777
00778
00779 U7object flic8("<STATIC>/intro.dat", 8);
00780 fli_b = flic8.retrieve(flisize);
00781 playfli fli8(fli_b+8, flisize-8);
00782 fli8.info();
00783
00784 for (j = 0; j < 20; j++)
00785 {
00786 next = fli8.play(win, 0, 0, next, j*5);
00787 font->center_text(ibuf, centerx, centery+75, txt_msg[2]);
00788 win->show();
00789 }
00790
00791
00792 next = fli8.play(win, 0, 0, next, 100);
00793 font->center_text(ibuf, centerx, centery+75, txt_msg[2]);
00794 win->show();
00795
00796 for (i = 0; i < 300; i++)
00797 if (wait_delay (10))
00798 throw UserBreakException();
00799
00800
00801 for (j = 20; j; j--)
00802 {
00803 next = fli8.play(win, 0, 0, next, j*5);
00804 font->center_text(ibuf, centerx, centery+75, txt_msg[2]);
00805 win->show();
00806 }
00807
00808 FORGET_ARRAY(fli_b);
00809 }
00810 catch(const UserBreakException &x)
00811 {
00812 FORGET_ARRAY(shape_buf);
00813 FORGET_ARRAY(fli_b);
00814 FORGET_ARRAY(buffer);
00815 }
00816
00817
00818
00819
00820
00821
00822
00823 gwin->clear_screen(true);
00824
00825
00826 Audio::get_ptr()->cancel_streams();
00827 }
00828
00829 void SI_Game::top_menu()
00830 {
00831 play_midi(28, true);
00832 sman->paint_shape(topx,topy,menushapes.get_shape(0x2,0));
00833 pal->load(MAINSHP_FLX,26);
00834 pal->fade_in(60);
00835 }
00836
00837 void SI_Game::show_journey_failed()
00838 {
00839 pal->fade_out(50);
00840 sman->paint_shape(topx,topy,menushapes.get_shape(0x2,0));
00841 journey_failed_text();
00842 }
00843
00844
00845
00846
00847
00848
00849 struct ExCineEvent {
00850 uint32 time;
00851 char *file;
00852 int index;
00853
00854 virtual bool play_it(Image_window *win, int time) = 0;
00855
00856 bool can_play() { return file != 0; }
00857
00858 ExCineEvent(uint32 t, char*f, int i) :
00859 time(t), file(f), index(i) { }
00860
00861 virtual ~ExCineEvent() { }
00862 };
00863
00864
00865
00866
00867
00868 struct ExCineFlic : public ExCineEvent {
00869 private:
00870 int start;
00871 int count;
00872 bool repeat;
00873 int cur;
00874 int speed;
00875
00876
00877 U7object *flic_obj;
00878 size_t size;
00879 char *buffer;
00880 playfli *player;
00881
00882 public:
00883 virtual bool play_it(Image_window *win, int t);
00884
00885 void load_flic(void);
00886 void free_flic(void);
00887
00888 void fade_out(int cycles);
00889
00890 ExCineFlic(uint32 time, char *file, int i, int s, int c, bool r, int spd) :
00891 ExCineEvent(time, file, i), start(s), count(c), repeat(r), cur(-1), speed(spd),
00892 flic_obj(0), size(0), buffer(0), player(0) { }
00893
00894 ExCineFlic(uint32 time) : ExCineEvent(time, 0, 0), start(0), count(0),
00895 repeat(false), cur(0), speed(0),
00896 flic_obj(0), size(0), buffer(0), player(0) { }
00897
00898 virtual ~ExCineFlic() {
00899 free_flic();
00900 }
00901 };
00902
00903 void ExCineFlic::load_flic()
00904 {
00905 free_flic();
00906
00907 if (file) COUT("Loading " << file << ":" << index);
00908
00909 flic_obj = new U7object(file, index);
00910
00911 buffer = flic_obj->retrieve(size);
00912
00913 player = new playfli(buffer+8, size-8);
00914 player->info();
00915 }
00916
00917 void ExCineFlic::free_flic()
00918 {
00919 if (file) COUT("Freeing " << file << ":" << index);
00920
00921 FORGET_OBJECT(player);
00922 FORGET_ARRAY(buffer);
00923 size = 0;
00924 FORGET_OBJECT(flic_obj);
00925 }
00926
00927 bool ExCineFlic::play_it(Image_window *win, int t)
00928 {
00929 if (t < time) return false;
00930
00931 if (cur+1 < count || repeat) {
00932
00933
00934 int time_next = time + (cur+1) * speed;
00935 if (time_next <= t) {
00936 cur++;
00937
00938
00939 int actual = start + (cur%count);
00940
00941 player->play(win, actual, actual, 0);
00942
00943 return true;
00944 }
00945 }
00946
00947 player->put_buffer(win);
00948
00949 return false;
00950 }
00951
00952 void ExCineFlic::fade_out(int cycles)
00953 {
00954 if (player) player->get_palette()->fade_out(cycles);
00955 }
00956
00957
00958
00959
00960
00961 struct ExCineVoc : public ExCineEvent {
00962 private:
00963 bool played;
00964
00965 public:
00966 virtual bool play_it(Image_window *win, int t);
00967
00968 ExCineVoc(uint32 time, char *f, int index) :
00969 ExCineEvent(time, file, index), played(false) { }
00970
00971 virtual ~ExCineVoc() { }
00972 };
00973
00974 bool ExCineVoc::play_it(Image_window *win, int t)
00975 {
00976 size_t size;
00977 U7object voc("<STATIC>/intro.dat", index);
00978 uint8 *buffer = (uint8 *) voc.retrieve (size);
00979 Audio::get_ptr()->play (buffer+8, size-8, false);
00980 FORGET_ARRAY(buffer);
00981 played = true;
00982
00983 return false;
00984 }
00985
00986
00987
00988
00989 void SI_Game::end_game(bool success)
00990 {
00991 int next = 0;
00992
00993 Font *font = fontManager.get_font("MENU_FONT");
00994 Font *sifont = fontManager.get_font("SIINTRO_FONT");
00995
00996 bool speech = Audio::get_ptr()->is_speech_enabled();
00997
00998 gwin->clear_screen(true);
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098 ExCineFlic flics[] = {
01099 ExCineFlic(0, "<STATIC>/intro.dat", 9, 0, 61, true, 75),
01100 ExCineFlic(6350, "<STATIC>/intro.dat", 10, 0, 156, false, 95),
01101 ExCineFlic(21170, "<STATIC>/intro.dat", 9, 0, 61, true, 75),
01102 ExCineFlic(39800, "<STATIC>/intro.dat", 11, 0, 4, true, 75),
01103 ExCineFlic(48900, "<STATIC>/intro.dat", 13, 0, 61, true, 75),
01104 ExCineFlic(62500, "<STATIC>/intro.dat", 12, 0, 61, true, 75),
01105 ExCineFlic(70250, "<STATIC>/intro.dat", 13, 0, 121, false, 75),
01106 ExCineFlic(82300)
01107 };
01108 int last_flic = 7;
01109 int cur_flic = -1;
01110 ExCineFlic *flic = 0;
01111 ExCineFlic *pal_flic = 0;
01112
01113
01114 ExCineVoc vocs[] = {
01115 ExCineVoc(14700, "<STATIC>/intro.dat", 22),
01116 ExCineVoc(21300, "<STATIC>/intro.dat", 23),
01117 ExCineVoc(39800, "<STATIC>/intro.dat", 24),
01118 ExCineVoc(47700, "<STATIC>/intro.dat", 25),
01119 ExCineVoc(55400, "<STATIC>/intro.dat", 26),
01120 ExCineVoc(62500, "<STATIC>/intro.dat", 27),
01121 ExCineVoc(70250, "<STATIC>/intro.dat", 28),
01122 ExCineVoc(74750, "<STATIC>/intro.dat", 29)
01123 };
01124 int last_voc = 7;
01125 int cur_voc = -1;
01126
01127
01128 Audio::get_ptr()->stop_music();
01129
01130
01131 Audio *audio = Audio::get_ptr();
01132 if (audio) {
01133 const char *fn = "<STATIC>/r_send.xmi";
01134 MyMidiPlayer *midi = audio->get_midi();
01135 if (midi && midi->is_fm_synth()) fn = "<STATIC>/a_send.xmi";
01136 audio->start_music (fn, 0, false);
01137 }
01138
01139
01140 int start_time = SDL_GetTicks();
01141
01142 while (1) {
01143
01144 int time = SDL_GetTicks() - start_time;
01145
01146
01147 if (cur_flic < last_flic && flics[cur_flic+1].time <= time) {
01148
01149 bool next_play = flics[cur_flic+1].can_play();
01150
01151
01152 if(next_play) {
01153
01154 if (flic) flic->free_flic();
01155
01156
01157 if (pal_flic && pal_flic != flic)
01158 pal_flic->free_flic();
01159
01160 pal_flic = 0;
01161 }
01162
01163 else if (flic && flic->can_play()) {
01164 pal_flic = flic;
01165 }
01166
01167 else if (flic) {
01168 flic->free_flic();
01169 }
01170
01171 cur_flic++;
01172 flic = flics+cur_flic;
01173
01174 if (next_play) {
01175
01176 gwin->clear_screen(true);
01177
01178
01179 (pal_flic = flic)->load_flic();
01180 }
01181 else COUT("Teminator ");
01182 COUT("Flic at time: " << flic->time);
01183 }
01184
01185
01186 if (cur_voc < last_voc && vocs[cur_voc+1].time <= time) {
01187 cur_voc++;
01188 ExCineVoc *voc = vocs+cur_voc;
01189
01190
01191 voc->play_it(NULL, time);
01192
01193 COUT("voc at time: " << voc->time);
01194
01195 }
01196
01197
01198 if (cur_flic == last_flic && cur_voc == last_voc) {
01199
01200 if (pal_flic && pal_flic->can_play()) pal_flic->fade_out(100);
01201
01202 COUT("Finished!" << std::endl);
01203 break;
01204 }
01205
01206
01207
01208 bool updated = false;
01209
01210 if (flic->can_play()) updated = flic->play_it(win, time);
01211
01212 if (updated) win->show();
01213
01214 if (wait_delay (0)) {
01215
01216
01217 if (pal_flic && pal_flic->can_play()) pal_flic->fade_out(20);
01218 break;
01219 }
01220 }
01221
01222 gwin->clear_screen(true);
01223
01224
01225 Audio::get_ptr()->cancel_streams();
01226
01227
01228 Audio::get_ptr()->stop_music();
01229 }
01230
01231 void SI_Game::show_quotes()
01232 {
01233 play_midi(32);
01234 TextScroller quotes(MAINSHP_FLX, 0x10,
01235 fontManager.get_font("MENU_FONT"),
01236 menushapes.extract_shape(0x14)
01237 );
01238 quotes.run(gwin);
01239 }
01240
01241 void SI_Game::show_credits()
01242 {
01243 play_midi(30);
01244 TextScroller credits(MAINSHP_FLX, 0x0E,
01245 fontManager.get_font("MENU_FONT"),
01246 menushapes.extract_shape(0x14)
01247 );
01248 if(credits.run(gwin)) {
01249 std::ofstream quotesflg;
01250 U7open(quotesflg, "<SAVEGAME>/quotes.flg");
01251 quotesflg.close();
01252 }
01253 }
01254
01255 bool SI_Game::new_game(Vga_file &shapes)
01256 {
01257 SDL_EnableUNICODE(1);
01258
01259 int menuy = topy+110;
01260 Font *font = fontManager.get_font("MENU_FONT");
01261
01262 Vga_file faces_vga(FACES_VGA);
01263
01264 const int max_len = 16;
01265 char npc_name[max_len+1];
01266 char disp_name[max_len+2];
01267 npc_name[0] = 0;
01268 int sex = 0;
01269 int selected = 0;
01270 int num_choices = 4;
01271
01272 SDL_Event event;
01273 bool editing = true;
01274 bool redraw = true;
01275 bool ok = true;
01276 do
01277 {
01278 if (redraw)
01279 {
01280 gwin->clear_screen();
01281 sman->paint_shape(topx,topy,menushapes.get_shape(0x2,0));
01282 sman->paint_shape(topx+10,menuy+10,shapes.get_shape(0xC, selected==0?1:0));
01283 sman->paint_shape(topx+10,menuy+25,shapes.get_shape(0x19, selected==1?1:0));
01284 Shape_frame *sh = faces_vga.get_shape(0,sex);
01285 sman->paint_shape(topx+300,menuy+50,sh);
01286 sman->paint_shape(topx+10,topy+180,shapes.get_shape(0x8,selected==2?1:0));
01287 sman->paint_shape(centerx+10,topy+180,shapes.get_shape(0x7,selected==3?1:0));
01288 if(selected==0)
01289 snprintf(disp_name, max_len+2, "%s_", npc_name);
01290 else
01291 snprintf(disp_name, max_len+2, "%s", npc_name);
01292 font->draw_text(ibuf, topx+60, menuy+10, disp_name);
01293 pal->apply();
01294 redraw = false;
01295 }
01296 SDL_WaitEvent(&event);
01297 if(event.type==SDL_KEYDOWN)
01298 {
01299 redraw = true;
01300 switch(event.key.keysym.sym)
01301 {
01302 case SDLK_SPACE:
01303 if(selected==0)
01304 {
01305 int len = strlen(npc_name);
01306 if(len<max_len)
01307 {
01308 npc_name[len] = ' ';
01309 npc_name[len+1] = 0;
01310 }
01311 }
01312 else if(selected==1)
01313 {
01314 ++sex;
01315 if(sex>5)
01316 sex = 0;
01317 }
01318 break;
01319 case SDLK_LEFT:
01320 if(selected==1)
01321 {
01322 --sex;
01323 if(sex<0)
01324 sex = 5;
01325 }
01326 break;
01327 case SDLK_RIGHT:
01328 if(selected==1)
01329 {
01330 ++sex;
01331 if(sex>5)
01332 sex = 0;
01333 }
01334 break;
01335 case SDLK_ESCAPE:
01336 editing = false;
01337 ok = false;
01338 break;
01339 case SDLK_DOWN:
01340 ++selected;
01341 if(selected==num_choices)
01342 selected = 0;
01343 break;
01344 case SDLK_UP:
01345 --selected;
01346 if(selected<0)
01347 selected = num_choices-1;
01348 break;
01349 case SDLK_RETURN:
01350 if(selected<2)
01351 ++selected;
01352 else if(selected==2)
01353 {
01354 editing=false;
01355 ok = true;
01356 }
01357 else
01358 {
01359 editing = false;
01360 ok = false;
01361 }
01362 break;
01363 case SDLK_BACKSPACE:
01364 if(selected==0)
01365 {
01366 if(strlen(npc_name)>0)
01367 npc_name[strlen(npc_name)-1] = 0;
01368 }
01369 break;
01370 default:
01371 {
01372 if (selected == 0)
01373 {
01374 int len = strlen(npc_name);
01375 char chr = 0;
01376
01377 if ((event.key.keysym.unicode & 0xFF80) == 0)
01378 chr = event.key.keysym.unicode & 0x7F;
01379
01380 if (chr >= ' ' && len < max_len)
01381 {
01382 npc_name[len] = chr;
01383 npc_name[len+1] = 0;
01384 }
01385 }
01386 else
01387 {
01388 redraw = false;
01389 }
01390 }
01391 break;
01392 }
01393 }
01394 }
01395 while(editing);
01396
01397 gwin->clear_screen();
01398 sman->paint_shape(topx,topy,menushapes.get_shape(0x2,0));
01399
01400 if(ok)
01401 {
01402 set_avname (npc_name);
01403 set_avsex (1-(sex%2));
01404 set_avskin (sex/2);
01405 pal->fade_out(c_fade_out_time);
01406 gwin->clear_screen(true);
01407 ok = gwin->init_gamedat(true);
01408 }
01409
01410 SDL_EnableUNICODE(0);
01411
01412 return ok;
01413 }
01414
01415 bool SI_Game::is_installed()
01416 {
01417 std::string buf("<SERPENTISLE_STATIC>/sispeech.spc");
01418 bool foundsi = U7exists(buf);
01419 bool foundsiflx = U7exists("<DATA>/exult_si.flx");
01420
01421 if (foundsi)
01422 std::cout << "Serpent Isle : found" << std::endl;
01423 else
01424 std::cout << "Serpent Isle : not found ("
01425 << get_system_path(buf) << ")" << std::endl;
01426
01427 if (foundsiflx)
01428 std::cout << "exult_si.flx : found" << std::endl;
01429 else
01430 std::cout << "exult_si.flx : not found ("
01431 << get_system_path("<DATA>/exult_si.flx")
01432 << ")" << std::endl;
01433
01434 return (foundsi && foundsiflx);
01435 }