Ticket #8797: dlgTim_v2.patch
File dlgTim_v2.patch, 27.0 KB (added by , 16 years ago) |
---|
-
staticres.cpp
35 35 36 36 namespace Kyra { 37 37 38 #define RESFILE_VERSION 2 038 #define RESFILE_VERSION 21 39 39 40 40 bool StaticResource::checkKyraDat() { 41 41 Common::File kyraDat; … … 242 242 // Ingame 243 243 { k2IngamePakFiles, kStringList, "I_PAKFILES.TXT" }, 244 244 { k2IngameSfxFiles, kStringList, "I_SFXFILES.TXT" }, 245 { k2IngameSfxIndex, kRawData, "I_SFXINDEX. TRA" },245 { k2IngameSfxIndex, kRawData, "I_SFXINDEX.MAP" }, 246 246 { k2IngameTracks, kStringList, "I_TRACKS.TRA" }, 247 247 { k2IngameCDA, kRawData, "I_TRACKS.CDA" }, 248 { k2IngameTimIndex, kRawData, "I_TIMINDEX.MAP" }, 249 { k2IngameTimJpStrings, kStringList, "I_TIMJPSTR.TXT" }, 248 250 249 251 { 0, 0, 0 } 250 252 }; … … 926 928 _cdaTrackTableIntro = _staticres->loadRawData(k2SeqplayIntroCDA, _cdaTrackTableIntroSize); 927 929 _cdaTrackTableIngame = _staticres->loadRawData(k2IngameCDA, _cdaTrackTableIngameSize); 928 930 _cdaTrackTableFinale = _staticres->loadRawData(k2SeqplayFinaleCDA, _cdaTrackTableFinaleSize); 931 _ingameTimIndex = (const uint16*) _staticres->loadRawData(k2IngameTimIndex, _ingameTimIndexSize); 932 _ingameTimJpStr = _staticres->loadStrings(k2IngameTimJpStrings, _ingameTimJpStrSize); 929 933 930 934 // replace sequence talkie files with localized versions and cut off .voc 931 935 // suffix from voc files so as to allow compression specific file extensions -
module.mk
25 25 script_v2.o \ 26 26 script.o \ 27 27 seqplayer.o \ 28 sequences_tim.o \ 28 29 sequences_v1.o \ 29 30 sequences_v2.o \ 30 31 sound_adlib.o \ -
script_v2.cpp
622 622 return 0; 623 623 } 624 624 625 int KyraEngine_v2::o2_useItemOnMainChar(ScriptState *script) { 626 ScriptState tmpScript; 627 _scriptInterpreter->initScript(&tmpScript, &_npcScriptData); 628 _scriptInterpreter->startScript(&tmpScript, 0); 629 tmpScript.regs[4] = _itemInHand; 630 tmpScript.regs[0] = _mainCharacter.sceneId; 631 632 int oldVocH = _vocHigh; 633 _vocHigh = 0x5a; 634 635 while(_scriptInterpreter->validScript(&tmpScript)) 636 _scriptInterpreter->runScript(&tmpScript); 637 638 _vocHigh = oldVocH; 639 640 return 0; 641 } 642 643 int KyraEngine_v2::o2_startDialogue(ScriptState *script) { 644 debugC(3, kDebugLevelScriptFuncs, "o2_startDialogue(%p) (%d)", (const void *)script, stackPos(0)); 645 startDialogue(stackPos(0)); 646 return 0; 647 } 648 649 int KyraEngine_v2::o2_setupDialogue(ScriptState *script) { 650 debugC(3, kDebugLevelScriptFuncs, "o2_setupDialogue(%p) (%d)", (const void *)script, stackPos(0)); 651 setNewDlgIndex(stackPos(0)); 652 return 0; 653 } 654 655 int KyraEngine_v2::o2_getDlgIndex(ScriptState *script) { 656 debugC(3, kDebugLevelScriptFuncs, "o2_setNewDlgIndex(%p) (%d)", (const void *)script, stackPos(0)); 657 return _mainCharacter.dlgIndex; 658 } 659 625 660 int KyraEngine_v2::o2_defineRoom(ScriptState *script) { 626 661 debugC(3, kDebugLevelScriptFuncs, "o2_defineRoom(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", (const void *)script, 627 662 stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); … … 653 688 return 0; 654 689 } 655 690 691 int KyraEngine_v2::o2_getColorCodeFlag1(ScriptState *script) { 692 debugC(3, kDebugLevelScriptFuncs, "o2_getColorCodeFlag1(%p)", (const void *)script); 693 return _colorCodeFlag1; 694 } 695 696 int KyraEngine_v2::o2_setColorCodeFlag1(ScriptState *script) { 697 debugC(3, kDebugLevelScriptFuncs, "o2_getColorCodeFlag1(%p) (%d)", (const void *)script, stackPos(0)); 698 _colorCodeFlag1 = stackPos(0); 699 return 0; 700 } 701 702 int KyraEngine_v2::o2_getColorCodeFlag2(ScriptState *script) { 703 debugC(3, kDebugLevelScriptFuncs, "o2_getColorCodeFlag2(%p)", (const void *)script); 704 return _colorCodeFlag2; 705 } 706 707 int KyraEngine_v2::o2_setColorCodeFlag2(ScriptState *script) { 708 debugC(3, kDebugLevelScriptFuncs, "o2_getColorCodeFlag2(%p) (%d)", (const void *)script, stackPos(0)); 709 _colorCodeFlag2 = stackPos(0); 710 return 0; 711 } 712 656 713 int KyraEngine_v2::o2_countItemInstances(ScriptState *script) { 657 714 debugC(3, kDebugLevelScriptFuncs, "o2_countItemInstances(%p) (%d)", (const void *)script, stackPos(0)); 658 715 uint16 item = stackPos(0); … … 691 748 return 0; 692 749 } 693 750 751 int KyraEngine_v2::o2_npcChat(ScriptState *script) { 752 if (_flags.isTalkie) { 753 debugC(3, kDebugLevelScriptFuncs, "o2_npcChat(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), _vocHigh, stackPos(2)); 754 npcChatSequence(stackPosString(0), stackPos(1), _vocHigh, stackPos(2)); 755 } else { 756 debugC(3, kDebugLevelScriptFuncs, "o2_npcChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); 757 npcChatSequence(stackPosString(0), stackPos(1)); 758 } 759 return 0; 760 } 761 694 762 int KyraEngine_v2::o2_deinitObject(ScriptState *script) { 695 763 debugC(3, kDebugLevelScriptFuncs, "o2_deinitObject(%p) (%d)", (const void *)script, stackPos(0)); 696 764 deinitTalkObject(stackPos(0)); -
kyra_v2.h
495 495 void runSceneScript6(); 496 496 void runSceneScript7(); 497 497 498 void sceneStartupChat(); 499 498 500 void initSceneAnims(int unk1); 499 501 void initSceneScreen(int unk1); 500 502 … … 589 591 // character 590 592 struct Character { 591 593 uint16 sceneId; 592 uint16 unk2;594 uint16 dlgIndex; 593 595 uint8 height; 594 596 uint8 facing; 595 597 uint16 animFrame; … … 652 654 void objectChatPrintText(const char *text, int object); 653 655 void objectChatProcess(const char *script); 654 656 void objectChatWaitToFinish(); 655 void initTalkObject(int initObject);656 void deinitTalkObject(int initObject);657 657 658 void startDialogue(int dlgIndex); 659 void updateDlgBuffer(); 660 void loadDlgHeader(int &csEntry, int &vocH, int &scIndex1, int &scIndex2); 661 void processDialogue(int dlgOffset, int vocH = 0, int csEntry = 0); 662 void npcChatSequence(const char *str, int timId, int vocHigh = -1, int vocLow = -1); 663 void setNewDlgIndex(int dlgIndex); 664 665 int _npcTalkChpIndex; 666 int _npcTalkDlgIndex; 667 uint8 _newSceneDlgState[32]; 668 int8 **_conversationState; 669 uint8 _npcTalkUNK; 670 uint8 *_dlgBuffer; 671 672 // tim sequence 673 void tim_setupOpcodes(); 674 byte* tim_loadFile(const char *filename, byte *buffer, int32 bufferSize); 675 void tim_releaseBuffer(byte *buffer); 676 void tim_processSequence(uint8 *timBuffer, int loop); 677 678 int tim_o_dummy_r0(uint8 *ptr); 679 int tim_o_dummy_r1(uint8 *ptr); 680 int tim_o_clearCmds2(uint8 *ptr); 681 int tim_o_abort(uint8 *ptr); 682 int tim_o_selectcurrentCommandSet(uint8 *ptr); 683 int tim_o_deleteBuffer(uint8 *ptr); 684 int tim_o_refreshTimers(uint8 *ptr); 685 int tim_o_execSubOpcode(uint8 *ptr); 686 int tim_o_initActiveSub(uint8 *ptr); 687 int tim_o_resetActiveSub(uint8 *ptr); 688 int tim_o_printTalkText(uint8 *ptr); 689 int tim_o_updateSceneAnim(uint8 *ptr); 690 int tim_o_resetChat(uint8 *ptr); 691 int tim_o_playSoundEffect(uint8 *ptr); 692 693 typedef int (KyraEngine_v2::*TimOpc)(uint8 *ptr); 694 const TimOpc *_timOpcodes; 695 696 struct TIMHeader { 697 uint16 deleteBufferFlag; 698 int16 unkFlag; 699 int16 unkFlag2; 700 int16 cmdsOffset; 701 int16 unkOffset2; 702 int16 AVTLOffset; 703 int16 TEXTOffset; 704 }; 705 706 struct Cmds { 707 uint8 *dataPtr; 708 uint32 unk_2; 709 uint32 timer1; 710 uint32 timer2; 711 uint8 *backupPtr; 712 uint8 *AVTLSubChunk; 713 }; 714 715 struct TIMBuffers { 716 uint8 *AVTLChunk; 717 uint8 *TEXTChunk; 718 uint8 *offsUnkFlag2; 719 uint8 *offsUnkFlag; 720 int16 currentEntry; 721 int16 unk_12; 722 Cmds *currentCommandSet; 723 uint8 *unkCmds; 724 }; 725 TIMBuffers _TIMBuffers; 726 727 const char *_timChatText; 728 int _timChatObject; 729 658 730 // sound 659 731 int _oldTalkFile; 660 732 int _currentTalkFile; … … 689 761 void delay(uint32 millis, bool updateGame = false, bool isMainLoop = false); 690 762 691 763 // Talk object handling 764 void initTalkObject(int index); 765 void deinitTalkObject(int index); 766 692 767 struct TalkObject { 693 768 char filename[13]; 694 769 int8 scriptId; … … 697 772 }; 698 773 TalkObject *_talkObjectList; 699 774 700 struct TIMHeader {701 uint16 deleteBufferFlag;702 int16 unkFlag;703 int16 unkFlag2;704 int16 unkOffset;705 int16 unkOffset2;706 int16 AVTLOffset;707 int16 TEXTOffset;708 };709 710 struct TIMStructUnk1 {711 uint16 unk_0;712 uint16 unk_2;713 uint16 unk_4;714 uint16 unk_8;715 uint16 *unk_20;716 };717 718 struct TIMBuffers {719 uint16 *AVTLChunk;720 byte *TEXTChunk;721 TIMStructUnk1 *UnkChunk;722 };723 TIMBuffers _TIMBuffers;724 725 775 struct TalkSections { 726 776 byte *STATim; 727 777 byte *TLKTim; … … 730 780 TalkSections _currentTalkSections; 731 781 732 782 bool _objectChatFinished; 733 byte *loadTIMFile(const char *filename, byte *buffer, int32 bufferSize);734 void freeTIM(byte *buffer);735 783 736 784 // ingame static sequence handling 737 785 void seq_makeBookOrCauldronAppear(int type); … … 809 857 int o2_setSpecialSceneScriptRunTime(ScriptState *script); 810 858 int o2_defineSceneAnim(ScriptState *script); 811 859 int o2_updateSceneAnim(ScriptState *script); 860 int o2_useItemOnMainChar(ScriptState *script); 861 int o2_startDialogue(ScriptState *script); 862 int o2_setupDialogue(ScriptState *script); 863 int o2_getDlgIndex(ScriptState *script); 812 864 int o2_defineRoom(ScriptState *script); 813 865 int o2_objectChat(ScriptState *script); 866 int o2_getColorCodeFlag1(ScriptState *script); 867 int o2_setColorCodeFlag1(ScriptState *script); 868 int o2_getColorCodeFlag2(ScriptState *script); 869 int o2_setColorCodeFlag2(ScriptState *script); 814 870 int o2_countItemInstances(ScriptState *script); 815 871 int o2_initObject(ScriptState *script); 872 int o2_npcChat(ScriptState *script); 816 873 int o2_deinitObject(ScriptState *script); 817 874 int o2_makeBookOrCauldronAppear(ScriptState *script); 818 875 int o2_setSpecialSceneScriptState(ScriptState *script); … … 896 953 int _ingameSoundIndexSize; 897 954 const char *const *_sequenceStrings; 898 955 int _sequenceStringsSize; 956 const uint16 *_ingameTimIndex; 957 int _ingameTimIndexSize; 958 const char *const *_ingameTimJpStr; 959 int _ingameTimJpStrSize; 899 960 uint8 *_demoShapeDefs; 900 961 int _sequenceStringsDuration[33]; 901 962 … … 919 980 920 981 Sequence *_sequences; 921 982 NestedSequence *_nSequences; 983 984 // these are used whenever the color code has to be entered 985 int _colorCodeFlag1; 986 int _colorCodeFlag2; 922 987 }; 923 988 924 989 } // end of namespace Kyra -
text_v2.cpp
27 27 #include "kyra/kyra_v2.h" 28 28 #include "kyra/resource.h" 29 29 30 #include "common/endian.h" 31 30 32 namespace Kyra { 31 33 32 34 TextDisplayer_v2::TextDisplayer_v2(KyraEngine_v2 *vm, Screen_v2 *screen) … … 325 327 } 326 328 327 329 const uint32 curTime = _system->getMillis(); 328 if ((textEnabled() && curTime > endTime) || (speechEnabled() && ! snd_voiceIsPlaying()) || _skipFlag) {330 if ((textEnabled() && curTime > endTime) || (speechEnabled() && !textEnabled() && !snd_voiceIsPlaying()) || _skipFlag) { 329 331 _skipFlag = false; 330 332 nextFrame = curTime; 331 333 running = false; … … 340 342 resetCharacterAnimDim(); 341 343 } 342 344 343 void KyraEngine_v2::initTalkObject(int initObject) { 344 TalkObject &object = _talkObjectList[initObject]; 345 void KyraEngine_v2::startDialogue(int dlgIndex) { 346 updateDlgBuffer(); 347 int csEntry, vocH, unused1, unused2; 348 loadDlgHeader(csEntry, vocH, unused1, unused2); 349 int s = _conversationState[dlgIndex][csEntry]; 350 uint8 bufferIndex = 8; 345 351 352 if (s == -1) { 353 bufferIndex += (dlgIndex * 6); 354 _conversationState[dlgIndex][csEntry] = 0; 355 } else if (!s || s == 2) { 356 bufferIndex += (dlgIndex * 6 + 2); 357 _conversationState[dlgIndex][csEntry] = 1; 358 } else { 359 bufferIndex += (dlgIndex * 6 + 4); 360 _conversationState[dlgIndex][csEntry] = 2; 361 } 362 363 int offs = READ_LE_UINT16(_dlgBuffer + bufferIndex); 364 processDialogue(offs, vocH, csEntry); 365 } 366 367 void KyraEngine_v2::updateDlgBuffer() { 368 static const char DlgFileTemplate[] = "CH**-S**.DLG"; 369 char filename[13]; 370 filename[12] = 0; 371 memcpy(filename, DlgFileTemplate, 12); 372 373 static const char suffixTalkie[] = "EFG"; 374 static const char suffixTowns[] = "G J"; 375 const char *suffix = _flags.isTalkie ? suffixTalkie : suffixTowns; 376 377 filename[2] = (char)((_currentChapter / 10 + 48) & 0xFF); 378 filename[3] = (char)((_currentChapter % 10 + 48) & 0xFF); 379 380 if (!(_flags.platform == Common::kPlatformPC && !_flags.isTalkie)) 381 filename[11] = suffix[_lang]; 382 383 if (_currentChapter == _npcTalkChpIndex && _mainCharacter.dlgIndex == _npcTalkDlgIndex) 384 return; 385 386 _npcTalkChpIndex = _currentChapter; 387 _npcTalkDlgIndex = _mainCharacter.dlgIndex; 388 389 filename[6] = (char)((_npcTalkDlgIndex / 10 + 48) & 0xFF); 390 filename[7] = (char)((_npcTalkDlgIndex % 10 + 48) & 0xFF); 391 392 if (_dlgBuffer) 393 delete [] _dlgBuffer; 394 395 _dlgBuffer = _res->fileData(filename, 0); 396 } 397 398 void KyraEngine_v2::loadDlgHeader(int &csEntry, int &vocH, int &scIndex1, int &scIndex2) { 399 csEntry = READ_LE_UINT16(_dlgBuffer); 400 vocH = READ_LE_UINT16(_dlgBuffer + 2); 401 scIndex1 = READ_LE_UINT16(_dlgBuffer + 4); 402 scIndex2 = READ_LE_UINT16(_dlgBuffer + 6); 403 } 404 405 void KyraEngine_v2::processDialogue(int dlgOffset, int vocH, int csEntry) { 406 int activeTimSequence = -1; 407 int nextTimSequence = -1; 408 int cmd = 0; 409 int vocHi = -1; 410 int vocLo = -1; 411 bool loop = true; 412 int offs = dlgOffset; 413 414 _screen->hideMouse(); 415 416 while (loop) { 417 cmd = READ_LE_UINT16(_dlgBuffer + offs); 418 offs += 2; 419 420 nextTimSequence = READ_LE_UINT16(&_ingameTimIndex[cmd]); 421 422 if (nextTimSequence == 10) { 423 if (queryGameFlag(0x3e)) 424 nextTimSequence = 14; 425 if (queryGameFlag(0x3f)) 426 nextTimSequence = 15; 427 if (queryGameFlag(0x40)) 428 nextTimSequence = 16; 429 } 430 431 if (nextTimSequence == 27 && _mainCharacter.sceneId == 34) 432 nextTimSequence = 41; 433 434 if (queryGameFlag(0x72)) { 435 if (nextTimSequence == 18) 436 nextTimSequence = 43; 437 else if (nextTimSequence == 19) 438 nextTimSequence = 44; 439 } 440 441 if (_mainCharacter.x1 > 160) { 442 if (nextTimSequence == 4) 443 nextTimSequence = 46; 444 else if (nextTimSequence == 5) 445 nextTimSequence = 47; 446 } 447 448 if (cmd == 10) { 449 loop = false; 450 451 } else if (cmd == 4) { 452 csEntry = READ_LE_UINT16(_dlgBuffer + offs); 453 setNewDlgIndex(csEntry); 454 offs += 2; 455 456 } else { 457 if (!_flags.isTalkie || cmd == 11) { 458 int len = READ_LE_UINT16(_dlgBuffer + offs); 459 offs += 2; 460 if (_flags.isTalkie) { 461 vocLo = READ_LE_UINT16(_dlgBuffer + offs); 462 offs += 2; 463 } 464 memcpy(_unkBuf500Bytes, _dlgBuffer + offs, len); 465 _unkBuf500Bytes[len] = 0; 466 offs += len; 467 if (_flags.isTalkie) 468 continue; 469 470 } else if (_flags.isTalkie) { 471 int len = READ_LE_UINT16(_dlgBuffer + offs); 472 offs += 2; 473 static const int irnv[] = { 91, 105, 110, 114, 118 }; 474 vocHi = irnv[vocH - 1] + csEntry; 475 vocLo = READ_LE_UINT16(_dlgBuffer + offs); 476 offs += 2; 477 memcpy(_unkBuf500Bytes, _dlgBuffer + offs, len); 478 _unkBuf500Bytes[len] = 0; 479 offs += len; 480 } 481 482 if (_unkBuf500Bytes[0]) { 483 if ((!_flags.isTalkie && cmd == 11) || (_flags.isTalkie && cmd == 12)) { 484 if (activeTimSequence > -1) { 485 deinitTalkObject(activeTimSequence); 486 activeTimSequence = -1; 487 } 488 objectChat((const char*) _unkBuf500Bytes, 0, vocHi, vocLo); 489 } else { 490 if (activeTimSequence != nextTimSequence ) { 491 if (activeTimSequence > -1) { 492 deinitTalkObject(activeTimSequence); 493 activeTimSequence = -1; 494 } 495 initTalkObject(nextTimSequence); 496 activeTimSequence = nextTimSequence; 497 } 498 npcChatSequence((const char *)_unkBuf500Bytes, nextTimSequence, vocHi, vocLo); 499 } 500 } 501 } 502 } 503 504 if (activeTimSequence > -1) 505 deinitTalkObject(activeTimSequence); 506 507 _screen->showMouse(); 508 } 509 510 void KyraEngine_v2::initTalkObject(int index) { 511 TalkObject &object = _talkObjectList[index]; 512 346 513 char STAFilename[13]; 347 514 char TLKFilename[13]; 348 515 char ENDFilename[13]; … … 355 522 strcpy(TLKFilename + 4, "_TLK.TIM"); 356 523 strcpy(ENDFilename + 4, "_END.TIM"); 357 524 358 _currentTalkSections.STATim = loadTIMFile(STAFilename, NULL, 0);359 _currentTalkSections.TLKTim = loadTIMFile(TLKFilename, NULL, 0);360 _currentTalkSections.ENDTim = loadTIMFile(ENDFilename, NULL, 0);525 _currentTalkSections.STATim = tim_loadFile(STAFilename, NULL, 0); 526 _currentTalkSections.TLKTim = tim_loadFile(TLKFilename, NULL, 0); 527 _currentTalkSections.ENDTim = tim_loadFile(ENDFilename, NULL, 0); 361 528 362 529 if (object.scriptId != -1) { 363 530 _specialSceneScriptStateBackup[object.scriptId] = _specialSceneScriptState[object.scriptId]; 364 531 _specialSceneScriptState[object.scriptId] = 1; 365 532 } 366 533 367 /*if (_currentTalkObject.STATim) {534 if (_currentTalkSections.STATim) { 368 535 _objectChatFinished = false; 369 536 while (!_objectChatFinished) { 370 processTalkObject(_currentTalkObject.STATim, 0);537 tim_processSequence(_currentTalkSections.STATim, 0); 371 538 if (_chatText) 372 539 updateWithText(); 373 540 else 374 541 update(); 375 542 } 376 } */543 } 377 544 } 378 545 379 void KyraEngine_v2::deinitTalkObject(int in itObject) {380 TalkObject &object = _talkObjectList[in itObject];546 void KyraEngine_v2::deinitTalkObject(int index) { 547 TalkObject &object = _talkObjectList[index]; 381 548 382 /*if (_currentTalkObject.ENDTim) {549 if (_currentTalkSections.ENDTim) { 383 550 _objectChatFinished = false; 384 551 while (!_objectChatFinished) { 385 processTalkObject(_currentTalkObject.ENDTim, 0);552 tim_processSequence(_currentTalkSections.ENDTim, 0); 386 553 if (_chatText) 387 554 updateWithText(); 388 555 else 389 556 update(); 390 557 } 391 } */558 } 392 559 393 560 if (object.scriptId != -1) { 394 561 _specialSceneScriptState[object.scriptId] = _specialSceneScriptStateBackup[object.scriptId]; 395 562 } 396 563 397 564 if (_currentTalkSections.STATim != NULL) { 398 freeTIM(_currentTalkSections.STATim);565 tim_releaseBuffer(_currentTalkSections.STATim); 399 566 _currentTalkSections.STATim = NULL; 400 567 } 401 568 402 569 if (_currentTalkSections.TLKTim != NULL) { 403 freeTIM(_currentTalkSections.TLKTim);570 tim_releaseBuffer(_currentTalkSections.TLKTim); 404 571 _currentTalkSections.TLKTim = NULL; 405 572 } 406 573 407 574 if (_currentTalkSections.ENDTim != NULL) { 408 freeTIM(_currentTalkSections.ENDTim);575 tim_releaseBuffer(_currentTalkSections.ENDTim); 409 576 _currentTalkSections.ENDTim = NULL; 410 577 } 411 578 } 412 579 413 byte *KyraEngine_v2::loadTIMFile(const char *filename, byte *buffer, int32 bufferSize) { 414 ScriptFileParser file(filename, _res); 415 if (!file) { 416 error("Couldn't open script file '%s'", filename); 417 return NULL; 418 } 580 void KyraEngine_v2::npcChatSequence(const char *str, int timId, int vocHigh, int vocLow) { 581 _chatText = str; 582 _chatObject = timId; 583 objectChatInit(str, timId, vocHigh, vocLow); 419 584 420 int32 formBlockSize = file.getFORMBlockSize(); 421 if (formBlockSize == -1) { 422 error("No FORM chunk found in file: '%s'", filename); 423 return NULL; 424 } 585 if (!_currentTalkSections.TLKTim) 586 _currentTalkSections.TLKTim = tim_loadFile(_talkObjectList[READ_LE_UINT16(&_ingameTimIndex[timId])].filename, 0, 0); 425 587 426 if (formBlockSize < 20) { 427 return NULL; 428 } 588 setNextIdleAnimTimer(); 589 590 uint32 ct = chatCalcDuration(str); 591 uint32 time = _system->getMillis(); 592 _chatEndTime = time + (3 + ct) * _tickLength; 593 uint32 chatAnimEndTime = time + (3 + (ct >> 1)) * _tickLength; 429 594 430 formBlockSize += sizeof(TIMHeader) + 120 + sizeof(TIMStructUnk1) * 10; 431 432 TIMHeader *timHeader; 433 if (buffer == NULL || bufferSize < formBlockSize) { 434 buffer = new byte[formBlockSize]; 435 timHeader = (TIMHeader *)buffer; 436 timHeader->deleteBufferFlag = 0xBABE; 437 } else { 438 timHeader = (TIMHeader *)buffer; 439 timHeader->deleteBufferFlag = 0x0; 595 if (_chatVocHigh >= 0) { 596 playVoice(_chatVocHigh, _chatVocLow); 597 _chatVocHigh = _chatVocLow = -1; 440 598 } 441 599 442 int32 chunkSize = file.getIFFBlockSize(AVTL_CHUNK); 443 timHeader->unkFlag = -1; 444 timHeader->unkFlag2 = 0; 445 timHeader->unkOffset = sizeof(TIMHeader); 446 timHeader->unkOffset2 = timHeader->unkOffset + sizeof(TIMStructUnk1) * 10; 447 timHeader->AVTLOffset = timHeader->unkOffset2 + 120; 448 timHeader->TEXTOffset = timHeader->AVTLOffset + chunkSize; 600 while (((textEnabled() && _chatEndTime > _system->getMillis()) || (speechEnabled() && snd_voiceIsPlaying())) && !(_quitFlag || _skipFlag)) { 601 if (chatAnimEndTime > _system->getMillis()) { 602 _objectChatFinished = false; 449 603 450 _TIMBuffers.AVTLChunk = (uint16 *)(buffer + timHeader->AVTLOffset); 451 _TIMBuffers.TEXTChunk = buffer + timHeader->TEXTOffset; 604 while (!_objectChatFinished && !_skipFlag) { 605 if (_currentTalkSections.TLKTim) 606 tim_processSequence(_currentTalkSections.TLKTim, 0); 607 else 608 _objectChatFinished = false; 452 609 453 if (!file.loadIFFBlock(AVTL_CHUNK, _TIMBuffers.AVTLChunk, chunkSize)) { 454 error("Couldn't load AVTL chunk from file: '%s'", filename); 455 return NULL; 610 updateWithText(); 611 612 int inputFlag = checkInput(0); 613 removeInputTop(); 614 if (inputFlag == 198 || inputFlag == 199) { 615 //XXX 616 _skipFlag = true; 617 snd_stopVoice(); 618 } 619 delay(10); 620 } 621 if (_currentTalkSections.TLKTim) 622 tim_o_abort(0); 623 } 624 updateWithText(); 456 625 } 457 626 458 _ TIMBuffers.UnkChunk = (TIMStructUnk1 *)(buffer + timHeader->unkOffset);627 _skipFlag = false; 459 628 460 for (int i = 0; i < 10; i++) { 461 _TIMBuffers.UnkChunk[i].unk_0 = 0; 462 _TIMBuffers.UnkChunk[i].unk_2 = 0; 463 _TIMBuffers.UnkChunk[i].unk_20 = &_TIMBuffers.AVTLChunk[ _TIMBuffers.AVTLChunk[i] ]; 464 _TIMBuffers.UnkChunk[i].unk_4 = 0; 465 _TIMBuffers.UnkChunk[i].unk_8 = 0; 629 if (_currentTalkSections.TLKTim) { 630 tim_releaseBuffer(_currentTalkSections.TLKTim); 631 _currentTalkSections.TLKTim = 0; 466 632 } 467 633 468 chunkSize = file.getIFFBlockSize(TEXT_CHUNK); 469 if (chunkSize > 0) { 470 if (!file.loadIFFBlock(TEXT_CHUNK, _TIMBuffers.TEXTChunk, chunkSize)) { 471 error("Couldn't load TEXT chunk from file: '%s'", filename); 472 return NULL; 473 } 474 } 475 476 return buffer; 634 snd_stopVoice(); 635 _text->restoreScreen(); 636 _chatText = 0; 637 _chatObject = -1; 638 setNextIdleAnimTimer(); 477 639 } 478 640 479 void KyraEngine_v2::freeTIM(byte *buffer) { 480 TIMHeader *timHeader = (TIMHeader *)buffer; 481 482 if (timHeader->deleteBufferFlag == 0xBABE) { 483 delete[] buffer; 484 } 641 void KyraEngine_v2::setNewDlgIndex(int dlgIndex) { 642 if (dlgIndex == _mainCharacter.dlgIndex) 643 return; 644 memset(_newSceneDlgState, 0, 32); 645 for (int i = 0; i < 19; i++) 646 memset(_conversationState[i], -1, 14); 647 _npcTalkUNK = 0; 648 _mainCharacter.dlgIndex = dlgIndex; 485 649 } 486 650 487 651 } // end of namespace Kyra 488 652 489 -
resource.h
218 218 k2IngameSfxIndex, 219 219 k2IngameTracks, 220 220 k2IngameCDA, 221 k2IngameTimIndex, 222 k2IngameTimJpStrings, 221 223 222 224 kMaxResIDs 223 225 }; -
sound.h
191 191 private: 192 192 const AudioDataStruct *_soundDataList; 193 193 Audio::AudioStream *_currentVocFile; 194 Audio::SoundHandle _vocHandle; 194 enum { 195 kNumVocHandles = 4 196 }; 197 Audio::SoundHandle _vocHandles[kNumVocHandles]; 195 198 196 199 struct SpeechCodecs { 197 200 const char *fileext; -
scene_v2.cpp
243 243 244 244 if (!unk1) { 245 245 runSceneScript4(0); 246 //XXX sub_27158246 sceneStartupChat(); 247 247 } 248 248 249 249 _unk4 = 0; … … 499 499 _screen->_curPage = oldPage; 500 500 } 501 501 502 void KyraEngine_v2::sceneStartupChat() { 503 int tableIndex = _mainCharacter.sceneId - READ_LE_UINT16(&_ingameTimIndex[5 + _newChapterFile]); 504 if (queryGameFlag(0x159) || _newSceneDlgState[tableIndex]) 505 return; 506 507 int csEntry, vocH, scIndex1, scIndex2; 508 updateDlgBuffer(); 509 loadDlgHeader(csEntry, vocH, scIndex1, scIndex2); 510 511 uint8 bufferIndex = 8; 512 513 bufferIndex += (scIndex1 * 6 + scIndex2 * 4 + tableIndex * 2); 514 int offs = READ_LE_UINT16(_dlgBuffer + bufferIndex); 515 processDialogue(offs, vocH, csEntry); 516 517 _newSceneDlgState[tableIndex] = 1; 518 } 519 502 520 void KyraEngine_v2::initSceneAnims(int unk1) { 503 521 for (int i = 0; i < ARRAYSIZE(_animObjects); ++i) 504 522 _animObjects[i].enabled = 0; -
kyra_v2.cpp
86 86 _chatObject = -1; 87 87 _lastIdleScript = -1; 88 88 89 _timChatText = 0; 90 _timChatObject = -1; 91 89 92 _currentTalkSections.STATim = NULL; 90 93 _currentTalkSections.TLKTim = NULL; 91 94 _currentTalkSections.ENDTim = NULL; 92 95 93 96 _invWsa.wsa = 0; 94 97 98 _colorCodeFlag1 = 0; 99 _colorCodeFlag2 = -1; 100 95 101 memset(&_sceneScriptData, 0, sizeof(_sceneScriptData)); 102 103 _dlgBuffer = 0; 104 _conversationState = new int8*[19]; 105 for (int i = 0; i < 19; i++) 106 _conversationState[i] = new int8[14]; 107 _npcTalkChpIndex = _npcTalkDlgIndex = -1; 108 _mainCharacter.dlgIndex = 0; 109 setNewDlgIndex(-1); 96 110 } 97 111 98 112 KyraEngine_v2::~KyraEngine_v2() { … … 109 123 _text = 0; 110 124 delete _debugger; 111 125 delete _invWsa.wsa; 126 127 if (_dlgBuffer) 128 delete [] _dlgBuffer; 129 for (int i = 0; i < 19; i++) 130 delete [] _conversationState[i]; 131 delete [] _conversationState; 112 132 } 113 133 114 134 Movie *KyraEngine_v2::createWSAMovie() { … … 155 175 if (_flags.isDemo) 156 176 return 0; 157 177 178 tim_setupOpcodes(); 179 158 180 _mouseSHPBuf = _res->fileData("PWGMOUSE.SHP", 0); 159 181 assert(_mouseSHPBuf); 160 182 … … 1877 1899 Opcode(o2_updateSceneAnim), 1878 1900 OpcodeUnImpl(), 1879 1901 // 0x74 1902 Opcode(o2_useItemOnMainChar), 1903 Opcode(o2_startDialogue), 1880 1904 OpcodeUnImpl(), 1881 OpcodeUnImpl(), 1882 OpcodeUnImpl(), 1883 OpcodeUnImpl(), 1905 Opcode(o2_setupDialogue), 1884 1906 // 0x78 1885 Opcode UnImpl(),1907 Opcode(o2_getDlgIndex), 1886 1908 Opcode(o2_defineRoom), 1887 1909 OpcodeUnImpl(), 1888 1910 OpcodeUnImpl(), … … 1894 1916 // 0x80 1895 1917 Opcode(o2_objectChat), 1896 1918 OpcodeUnImpl(), 1897 Opcode UnImpl(),1898 Opcode UnImpl(),1919 Opcode(o2_getColorCodeFlag1), 1920 Opcode(o2_setColorCodeFlag1), 1899 1921 // 0x84 1922 Opcode(o2_getColorCodeFlag2), 1923 Opcode(o2_setColorCodeFlag2), 1900 1924 OpcodeUnImpl(), 1901 1925 OpcodeUnImpl(), 1902 OpcodeUnImpl(),1903 OpcodeUnImpl(),1904 1926 // 0x88 1905 1927 Opcode(o2_countItemInstances), 1906 1928 OpcodeUnImpl(), 1907 1929 Opcode(o2_initObject), 1908 Opcode UnImpl(),1930 Opcode(o2_npcChat), 1909 1931 // 0x8c 1910 1932 Opcode(o2_deinitObject), 1911 1933 OpcodeUnImpl(), -
sound.cpp
39 39 namespace Kyra { 40 40 41 41 Sound::Sound(KyraEngine *vm, Audio::Mixer *mixer) 42 : _vm(vm), _mixer(mixer), _currentVocFile(0), _vocHandle (),42 : _vm(vm), _mixer(mixer), _currentVocFile(0), _vocHandles(), 43 43 _musicEnabled(1), _sfxEnabled(true), _soundDataList(0) { 44 44 } 45 45 … … 77 77 } 78 78 79 79 if (_currentVocFile) { 80 //_mixer->stopHandle(_vocHandle); 81 _mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_vocHandle, _currentVocFile); 80 int h = 0; 81 while (_mixer->isSoundHandleActive(_vocHandles[h])) 82 h++; 83 if (h >= kNumVocHandles) 84 error("Overflow in function 'Sound::voicePlay(const char *file)'. More voc handles required."); 85 _mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_vocHandles[h], _currentVocFile); 82 86 } 83 87 delete [] fileData; 84 88 fileSize = 0; 85 89 } 86 90 87 91 void Sound::voiceStop() { 88 if (_mixer->isSoundHandleActive(_vocHandle)) 89 _mixer->stopHandle(_vocHandle); 92 for (int h = 0; h < kNumVocHandles; h++) { 93 if (_mixer->isSoundHandleActive(_vocHandles[h])) 94 _mixer->stopHandle(_vocHandles[h]); 95 } 90 96 } 91 97 92 98 bool Sound::voiceIsPlaying() { 93 return _mixer->isSoundHandleActive(_vocHandle); 99 bool res = false; 100 for (int h = 0; h < kNumVocHandles; h++) { 101 if (_mixer->isSoundHandleActive(_vocHandles[h])) 102 res = true; 103 } 104 return res; 94 105 } 95 106 96 107 #pragma mark -