Ticket #8797: dlgTim_v3.patch
File dlgTim_v3.patch, 39.1 KB (added by , 17 years ago) |
---|
-
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(), … … 1972 1994 } // end of namespace Kyra 1973 1995 1974 1996 1997 -
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 objectId, 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 uint8 *tim_loadFile(const char *filename, uint8 *buffer, int32 bufferSize); 675 void tim_releaseBuffer(uint8 *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 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 730 // Talk object handling 731 void initTalkObject(int index); 732 void deinitTalkObject(int index); 733 734 struct TalkObject { 735 char filename[13]; 736 int8 scriptId; 737 int16 x, y; 738 int8 color; 739 }; 740 TalkObject *_talkObjectList; 741 742 struct TalkSections { 743 uint8 *STATim; 744 uint8 *TLKTim; 745 uint8 *ENDTim; 746 }; 747 TalkSections _currentTalkSections; 748 749 char _TLKFilename[13]; 750 bool _objectChatFinished; 751 658 752 // sound 659 753 int _oldTalkFile; 660 754 int _currentTalkFile; … … 688 782 // delay 689 783 void delay(uint32 millis, bool updateGame = false, bool isMainLoop = false); 690 784 691 // Talk object handling692 struct TalkObject {693 char filename[13];694 int8 scriptId;695 int16 x, y;696 int8 color;697 };698 TalkObject *_talkObjectList;699 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 struct TalkSections {726 byte *STATim;727 byte *TLKTim;728 byte *ENDTim;729 };730 TalkSections _currentTalkSections;731 732 bool _objectChatFinished;733 byte *loadTIMFile(const char *filename, byte *buffer, int32 bufferSize);734 void freeTIM(byte *buffer);735 736 785 // ingame static sequence handling 737 786 void seq_makeBookOrCauldronAppear(int type); 738 787 void seq_makeBookAppear(); … … 809 858 int o2_setSpecialSceneScriptRunTime(ScriptState *script); 810 859 int o2_defineSceneAnim(ScriptState *script); 811 860 int o2_updateSceneAnim(ScriptState *script); 861 int o2_useItemOnMainChar(ScriptState *script); 862 int o2_startDialogue(ScriptState *script); 863 int o2_setupDialogue(ScriptState *script); 864 int o2_getDlgIndex(ScriptState *script); 812 865 int o2_defineRoom(ScriptState *script); 813 866 int o2_objectChat(ScriptState *script); 867 int o2_getColorCodeFlag1(ScriptState *script); 868 int o2_setColorCodeFlag1(ScriptState *script); 869 int o2_getColorCodeFlag2(ScriptState *script); 870 int o2_setColorCodeFlag2(ScriptState *script); 814 871 int o2_countItemInstances(ScriptState *script); 815 872 int o2_initObject(ScriptState *script); 873 int o2_npcChat(ScriptState *script); 816 874 int o2_deinitObject(ScriptState *script); 817 875 int o2_makeBookOrCauldronAppear(ScriptState *script); 818 876 int o2_setSpecialSceneScriptState(ScriptState *script); … … 896 954 int _ingameSoundIndexSize; 897 955 const char *const *_sequenceStrings; 898 956 int _sequenceStringsSize; 957 const uint16 *_ingameTalkObjIndex; 958 int _ingameTalkObjIndexSize; 959 const char *const *_ingameTimJpStr; 960 int _ingameTimJpStrSize; 899 961 uint8 *_demoShapeDefs; 900 962 int _sequenceStringsDuration[33]; 901 963 … … 919 981 920 982 Sequence *_sequences; 921 983 NestedSequence *_nSequences; 984 985 // these are used whenever the color code has to be entered 986 int _colorCodeFlag1; 987 int _colorCodeFlag2; 922 988 }; 923 989 924 990 } // end of namespace Kyra … … 926 992 #endif 927 993 928 994 995 -
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 \ -
resource.h
218 218 k2IngameSfxIndex, 219 219 k2IngameTracks, 220 220 k2IngameCDA, 221 k2IngameTalkObjIndex, 222 k2IngameTimJpStrings, 221 223 222 224 kMaxResIDs 223 225 }; … … 328 330 329 331 #endif 330 332 333 -
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(&_ingameTalkObjIndex[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; … … 910 928 911 929 } // end of namespace Kyra 912 930 931 -
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)); … … 840 908 } // end of namespace Kyra 841 909 842 910 911 -
sequences_tim.cpp
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/kyra/sequences_v1.cpp $ 22 * $Id: sequences_v1.cpp 30667 2008-01-28 00:14:17Z jvprat $ 23 * 24 */ 25 26 #include "kyra/text_v2.h" 27 #include "kyra/kyra_v2.h" 28 #include "kyra/sound.h" 29 #include "kyra/resource.h" 30 31 #include "common/endian.h" 32 33 namespace Kyra { 34 35 uint8 *KyraEngine_v2::tim_loadFile(const char *filename, byte *buffer, int32 bufferSize) { 36 ScriptFileParser file(filename, _res); 37 if (!file) { 38 error("Couldn't open script file '%s'", filename); 39 return NULL; 40 } 41 42 int32 formBlockSize = file.getFORMBlockSize(); 43 if (formBlockSize == -1) { 44 error("No FORM chunk found in file: '%s'", filename); 45 return NULL; 46 } 47 48 if (formBlockSize < 20) { 49 return NULL; 50 } 51 52 formBlockSize += sizeof(TIMHeader) + 10 * (sizeof(Cmds) + 120); 53 54 TIMHeader *timHeader; 55 if (buffer == NULL || bufferSize < formBlockSize) { 56 buffer = new byte[formBlockSize]; 57 timHeader = (TIMHeader *)buffer; 58 timHeader->deleteBufferFlag = 0xBABE; 59 } else { 60 timHeader = (TIMHeader *)buffer; 61 timHeader->deleteBufferFlag = 0x0; 62 } 63 64 int32 chunkSize = file.getIFFBlockSize(AVTL_CHUNK); 65 timHeader->unkFlag = -1; 66 timHeader->unkFlag2 = 0; 67 timHeader->cmdsOffset = sizeof(TIMHeader); 68 timHeader->unkOffset2 = timHeader->cmdsOffset + 10 * sizeof(Cmds); 69 timHeader->AVTLOffset = timHeader->unkOffset2 + 120; 70 timHeader->TEXTOffset = timHeader->AVTLOffset + chunkSize; 71 72 _TIMBuffers.AVTLChunk = buffer + timHeader->AVTLOffset; 73 _TIMBuffers.TEXTChunk = buffer + timHeader->TEXTOffset; 74 75 if (!file.loadIFFBlock(AVTL_CHUNK, _TIMBuffers.AVTLChunk, chunkSize)) { 76 error("Couldn't load AVTL chunk from file: '%s'", filename); 77 return NULL; 78 } 79 80 _TIMBuffers.currentCommandSet = (Cmds *)(buffer + timHeader->cmdsOffset); 81 82 for (int i = 0; i < 10; i++) { 83 _TIMBuffers.currentCommandSet[i].dataPtr = 0; 84 _TIMBuffers.currentCommandSet[i].unk_2 = 0; 85 _TIMBuffers.currentCommandSet[i].AVTLSubChunk = &_TIMBuffers.AVTLChunk[READ_LE_UINT16(&_TIMBuffers.AVTLChunk[i << 1]) << 1]; 86 _TIMBuffers.currentCommandSet[i].timer1 = 0; 87 _TIMBuffers.currentCommandSet[i].timer2 = 0; 88 } 89 90 chunkSize = file.getIFFBlockSize(TEXT_CHUNK); 91 if (chunkSize > 0) { 92 if (!file.loadIFFBlock(TEXT_CHUNK, _TIMBuffers.TEXTChunk, chunkSize)) { 93 error("Couldn't load TEXT chunk from file: '%s'", filename); 94 return NULL; 95 } 96 } 97 98 return buffer; 99 } 100 101 void KyraEngine_v2::tim_releaseBuffer(byte *buffer) { 102 TIMHeader *timHeader = (TIMHeader *)buffer; 103 if (timHeader->deleteBufferFlag == 0xBABE) 104 delete[] buffer; 105 } 106 107 void KyraEngine_v2::tim_processSequence(uint8 *timBuffer, int loop) { 108 if (!timBuffer) 109 return; 110 111 TIMHeader *hdr = (TIMHeader*) timBuffer; 112 _TIMBuffers.offsUnkFlag = (uint8*) &hdr->unkFlag; 113 _TIMBuffers.offsUnkFlag2 = (uint8*) &hdr->unkFlag2; 114 _TIMBuffers.currentCommandSet = (Cmds*) (timBuffer + hdr->cmdsOffset); 115 _TIMBuffers.unkCmds = timBuffer + hdr->unkOffset2; 116 _TIMBuffers.AVTLChunk = timBuffer + hdr->AVTLOffset; 117 _TIMBuffers.TEXTChunk = timBuffer + hdr->TEXTOffset; 118 119 if (!_TIMBuffers.currentCommandSet->dataPtr) { 120 _TIMBuffers.currentCommandSet->dataPtr = _TIMBuffers.currentCommandSet->AVTLSubChunk; 121 _TIMBuffers.currentCommandSet->timer1 = _system->getMillis(); 122 _TIMBuffers.currentCommandSet->timer2 = _system->getMillis(); 123 } 124 125 do { 126 _TIMBuffers.currentEntry = 0; 127 128 while (_TIMBuffers.currentEntry < 10) { 129 Cmds *s = &_TIMBuffers.currentCommandSet[_TIMBuffers.currentEntry]; 130 if ((int16)READ_LE_UINT16(_TIMBuffers.offsUnkFlag) != -1) 131 (this->*_timOpcodes[28])(_TIMBuffers.offsUnkFlag2); 132 133 bool loop = true; 134 135 while (s->dataPtr && s->timer2 <= _system->getMillis() && loop) { 136 uint8 cmd = s->dataPtr[4]; 137 hdr->unkFlag2 = cmd; 138 uint8 *para = &s->dataPtr[6]; 139 140 switch((this->*_timOpcodes[cmd])(para)) { 141 case -3: 142 WRITE_LE_UINT16(_TIMBuffers.offsUnkFlag, _TIMBuffers.currentEntry); 143 _TIMBuffers.unk_12 = -1; 144 break; 145 146 case -2: 147 loop = false; 148 break; 149 150 case -1: 151 loop = 0; 152 loop = false; 153 _TIMBuffers.currentEntry = 11; 154 break; 155 156 case 22: 157 s->backupPtr = 0; 158 break; 159 160 default: 161 break; 162 } 163 164 if (s) { 165 if (s->dataPtr) { 166 s->dataPtr += (READ_LE_UINT16(s->dataPtr) * 2); 167 s->timer1 = s->timer2; 168 s->timer2 += (READ_LE_UINT16(s->dataPtr + 2) * _tickLength); 169 } 170 } 171 } 172 173 _TIMBuffers.currentEntry++; 174 } 175 } while (loop == 1); 176 177 } 178 179 int KyraEngine_v2::tim_o_dummy_r0(uint8 *ptr) { 180 return 0; 181 } 182 183 int KyraEngine_v2::tim_o_dummy_r1(uint8 *ptr) { 184 return 1; 185 } 186 187 int KyraEngine_v2::tim_o_clearCmds2(uint8 *ptr) { 188 for (int i = 1; i < 10; i++) 189 memset(&_TIMBuffers.unkCmds[i], 0, 12); 190 _TIMBuffers.currentCommandSet[0].dataPtr = _TIMBuffers.currentCommandSet[0].AVTLSubChunk; 191 _TIMBuffers.currentCommandSet[0].timer1 = _system->getMillis(); 192 return 1; 193 } 194 195 int KyraEngine_v2::tim_o_abort(uint8 *ptr) { 196 _TIMBuffers.currentCommandSet[_TIMBuffers.currentEntry].dataPtr = 0; 197 if(!_TIMBuffers.currentEntry) 198 _objectChatFinished = true; 199 return -2; 200 } 201 202 203 int KyraEngine_v2::tim_o_selectcurrentCommandSet(uint8 *ptr) { 204 _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].dataPtr = _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].AVTLSubChunk ? 205 _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].AVTLSubChunk : &_TIMBuffers.AVTLChunk[_TIMBuffers.AVTLChunk[READ_LE_UINT16(ptr) << 1] << 1]; 206 return 1; 207 } 208 209 int KyraEngine_v2::tim_o_deleteBuffer(uint8 *ptr) { 210 _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].dataPtr = 0; 211 return 1; 212 } 213 214 int KyraEngine_v2::tim_o_refreshTimers(uint8 *ptr) { 215 for (int i = 1; i < 10; i++) { 216 if (_TIMBuffers.currentCommandSet[i].dataPtr) 217 _TIMBuffers.currentCommandSet[i].timer2 = _system->getMillis(); 218 } 219 220 return 1; 221 } 222 223 int KyraEngine_v2::tim_o_execSubOpcode(uint8 *ptr) { 224 return (this->*_timOpcodes[30 + READ_LE_UINT16(ptr)])(ptr + 2); 225 } 226 227 int KyraEngine_v2::tim_o_initActiveSub(uint8 *ptr) { 228 _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].dataPtr = _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].AVTLSubChunk; 229 _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].timer1 = _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].timer2 = _system->getMillis(); 230 return 1; 231 } 232 233 int KyraEngine_v2::tim_o_resetActiveSub(uint8 *ptr) { 234 _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].dataPtr = 0; 235 _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].timer2 = 0; 236 _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].timer1 = 0; 237 return 1; 238 } 239 240 int KyraEngine_v2::tim_o_printTalkText(uint8 *ptr) { 241 _chatText = _timChatText = (const char*) _TIMBuffers.TEXTChunk + (READ_LE_UINT16(ptr) << 1); 242 _chatObject = _timChatObject = READ_LE_UINT16(ptr + 2); 243 244 if (_flags.lang == Common::JA_JPN) { 245 for (int i = 0; i < _ingameTimJpStrSize; i += 2) { 246 if (!scumm_stricmp(_timChatText, _ingameTimJpStr[i])) 247 _chatText = _ingameTimJpStr[i + 1]; 248 } 249 } 250 objectChatInit(_chatText, _timChatObject); 251 return 0; 252 } 253 254 int KyraEngine_v2::tim_o_updateSceneAnim(uint8 *ptr) { 255 updateSceneAnim(READ_LE_UINT16(ptr + 2), READ_LE_UINT16(ptr)); 256 return 0; 257 } 258 259 int KyraEngine_v2::tim_o_resetChat(uint8 *ptr) { 260 _text->restoreScreen(); 261 _chatText = 0; 262 _chatObject = -1; 263 _timChatText = 0; 264 _timChatObject = -1; 265 return 0; 266 } 267 268 int KyraEngine_v2::tim_o_playSoundEffect(uint8 *ptr) { 269 snd_playSoundEffect(READ_LE_UINT16(ptr)); 270 return 0; 271 } 272 273 void KyraEngine_v2::tim_setupOpcodes() { 274 static const TimOpc Opcodes[] = { 275 &KyraEngine_v2::tim_o_clearCmds2, 276 &KyraEngine_v2::tim_o_abort, 277 &KyraEngine_v2::tim_o_dummy_r0, 278 &KyraEngine_v2::tim_o_dummy_r0, 279 &KyraEngine_v2::tim_o_selectcurrentCommandSet, 280 &KyraEngine_v2::tim_o_deleteBuffer, 281 &KyraEngine_v2::tim_o_dummy_r0, 282 &KyraEngine_v2::tim_o_dummy_r0, 283 &KyraEngine_v2::tim_o_dummy_r0, 284 &KyraEngine_v2::tim_o_dummy_r0, 285 &KyraEngine_v2::tim_o_dummy_r0, 286 &KyraEngine_v2::tim_o_dummy_r0, 287 &KyraEngine_v2::tim_o_dummy_r0, 288 &KyraEngine_v2::tim_o_dummy_r0, 289 &KyraEngine_v2::tim_o_dummy_r0, 290 &KyraEngine_v2::tim_o_dummy_r0, 291 &KyraEngine_v2::tim_o_dummy_r0, 292 &KyraEngine_v2::tim_o_dummy_r0, 293 &KyraEngine_v2::tim_o_dummy_r0, 294 &KyraEngine_v2::tim_o_dummy_r0, 295 &KyraEngine_v2::tim_o_dummy_r0, 296 &KyraEngine_v2::tim_o_dummy_r0, 297 &KyraEngine_v2::tim_o_dummy_r0, 298 &KyraEngine_v2::tim_o_refreshTimers, 299 &KyraEngine_v2::tim_o_dummy_r1, 300 &KyraEngine_v2::tim_o_execSubOpcode, 301 &KyraEngine_v2::tim_o_initActiveSub, 302 &KyraEngine_v2::tim_o_resetActiveSub, 303 &KyraEngine_v2::tim_o_dummy_r1, 304 &KyraEngine_v2::tim_o_dummy_r1, 305 &KyraEngine_v2::tim_o_printTalkText, 306 &KyraEngine_v2::tim_o_updateSceneAnim, 307 &KyraEngine_v2::tim_o_resetChat, 308 &KyraEngine_v2::tim_o_playSoundEffect, 309 }; 310 311 _timOpcodes = (TimOpc*) (Opcodes); 312 } 313 314 } // end of namespace Kyra 315 -
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 … … 52 52 bool found = false; 53 53 char filenamebuffer[25]; 54 54 55 int h = 0; 56 if (_currentVocFile) { 57 while (_mixer->isSoundHandleActive(_vocHandles[h])) 58 h++; 59 if (h >= NUM_VOC_HANDLES) 60 return; 61 } 62 55 63 for (int i = 0; _supportedCodes[i].fileext; ++i) { 56 64 strcpy(filenamebuffer, file); 57 65 strcat(filenamebuffer, _supportedCodes[i].fileext); … … 76 84 _currentVocFile = Audio::makeVOCStream(vocStream); 77 85 } 78 86 79 if (_currentVocFile) { 80 //_mixer->stopHandle(_vocHandle); 81 _mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_vocHandle, _currentVocFile); 82 } 87 _mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_vocHandles[h], _currentVocFile); 88 83 89 delete [] fileData; 84 90 fileSize = 0; 85 91 } 86 92 87 93 void Sound::voiceStop() { 88 if (_mixer->isSoundHandleActive(_vocHandle)) 89 _mixer->stopHandle(_vocHandle); 94 for (int h = 0; h < kNumVocHandles; h++) { 95 if (_mixer->isSoundHandleActive(_vocHandles[h])) 96 _mixer->stopHandle(_vocHandles[h]); 97 } 90 98 } 91 99 92 100 bool Sound::voiceIsPlaying() { 93 return _mixer->isSoundHandleActive(_vocHandle); 101 bool res = false; 102 for (int h = 0; h < kNumVocHandles; h++) { 103 if (_mixer->isSoundHandleActive(_vocHandles[h])) 104 res = true; 105 } 106 return res; 94 107 } 95 108 96 109 #pragma mark - … … 522 535 523 536 } // end of namespace Kyra 524 537 538 -
sound.h
54 54 #include "kyra/kyra.h" 55 55 #include "kyra/kyra_v2.h" 56 56 57 #define NUM_VOC_HANDLES 4 58 57 59 namespace Audio { 58 60 class AudioStream; 59 61 } // end of namespace Audio … … 180 182 const void *cdaData() const { return _soundDataList != 0 ? _soundDataList->_cdaTracks : 0; } 181 183 const int cdaTrackNum() const { return _soundDataList != 0 ? _soundDataList->_cdaNumTracks : 0; } 182 184 185 enum { 186 kNumVocHandles = 4 187 }; 188 183 189 int _musicEnabled; 184 190 bool _sfxEnabled; 185 191 … … 191 197 private: 192 198 const AudioDataStruct *_soundDataList; 193 199 Audio::AudioStream *_currentVocFile; 194 Audio::SoundHandle _vocHandle ;200 Audio::SoundHandle _vocHandles[kNumVocHandles]; 195 201 196 202 struct SpeechCodecs { 197 203 const char *fileext; … … 425 431 int _lastTrack; 426 432 427 433 Audio::AudioStream *_currentSFX; 428 Audio::SoundHandle _sfxHandle ;434 Audio::SoundHandle _sfxHandles[NUM_VOC_HANDLES]; 429 435 430 436 //SoundTowns_v2_TwnDriver * _driver; 431 437 uint8 * _twnTrackData; -
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; … … 241 241 242 242 // Ingame 243 243 { k2IngamePakFiles, kStringList, "I_PAKFILES.TXT" }, 244 { k2IngameSfxFiles, kStringList, "I_SFXFILES.T XT" },245 { k2IngameSfxIndex, kRawData, "I_SFXINDEX. TRA" },244 { k2IngameSfxFiles, kStringList, "I_SFXFILES.TRA" }, 245 { k2IngameSfxIndex, kRawData, "I_SFXINDEX.MAP" }, 246 246 { k2IngameTracks, kStringList, "I_TRACKS.TRA" }, 247 247 { k2IngameCDA, kRawData, "I_TRACKS.CDA" }, 248 { k2IngameTalkObjIndex, kRawData, "I_TALKOBJECTS.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 _ingameTalkObjIndex = (const uint16*) _staticres->loadRawData(k2IngameTalkObjIndex, _ingameTalkObjIndexSize); 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 … … 1494 1498 } // End of namespace Kyra 1495 1499 1496 1500 1501 -
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(&_ingameTalkObjIndex[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 char TLKFilename[13];348 514 char ENDFilename[13]; 349 515 350 516 strcpy(STAFilename, object.filename); 351 strcpy( TLKFilename, object.filename);517 strcpy(_TLKFilename, object.filename); 352 518 strcpy(ENDFilename, object.filename); 353 519 354 520 strcpy(STAFilename + 4, "_STA.TIM"); 355 strcpy( TLKFilename + 4, "_TLK.TIM");521 strcpy(_TLKFilename + 4, "_TLK.TIM"); 356 522 strcpy(ENDFilename + 4, "_END.TIM"); 357 523 358 _currentTalkSections.STATim = loadTIMFile(STAFilename, NULL, 0);359 _currentTalkSections.TLKTim = loadTIMFile(TLKFilename, NULL, 0);360 _currentTalkSections.ENDTim = loadTIMFile(ENDFilename, NULL, 0);524 _currentTalkSections.STATim = tim_loadFile(STAFilename, NULL, 0); 525 _currentTalkSections.TLKTim = tim_loadFile(_TLKFilename, NULL, 0); 526 _currentTalkSections.ENDTim = tim_loadFile(ENDFilename, NULL, 0); 361 527 362 528 if (object.scriptId != -1) { 363 529 _specialSceneScriptStateBackup[object.scriptId] = _specialSceneScriptState[object.scriptId]; 364 530 _specialSceneScriptState[object.scriptId] = 1; 365 531 } 366 532 367 /*if (_currentTalkObject.STATim) {533 if (_currentTalkSections.STATim) { 368 534 _objectChatFinished = false; 369 535 while (!_objectChatFinished) { 370 processTalkObject(_currentTalkObject.STATim, 0);536 tim_processSequence(_currentTalkSections.STATim, 0); 371 537 if (_chatText) 372 538 updateWithText(); 373 539 else 374 540 update(); 375 541 } 376 } */542 } 377 543 } 378 544 379 void KyraEngine_v2::deinitTalkObject(int in itObject) {380 TalkObject &object = _talkObjectList[in itObject];545 void KyraEngine_v2::deinitTalkObject(int index) { 546 TalkObject &object = _talkObjectList[index]; 381 547 382 /*if (_currentTalkObject.ENDTim) {548 if (_currentTalkSections.ENDTim) { 383 549 _objectChatFinished = false; 384 550 while (!_objectChatFinished) { 385 processTalkObject(_currentTalkObject.ENDTim, 0);551 tim_processSequence(_currentTalkSections.ENDTim, 0); 386 552 if (_chatText) 387 553 updateWithText(); 388 554 else 389 555 update(); 390 556 } 391 } */557 } 392 558 393 559 if (object.scriptId != -1) { 394 560 _specialSceneScriptState[object.scriptId] = _specialSceneScriptStateBackup[object.scriptId]; 395 561 } 396 562 397 563 if (_currentTalkSections.STATim != NULL) { 398 freeTIM(_currentTalkSections.STATim);564 tim_releaseBuffer(_currentTalkSections.STATim); 399 565 _currentTalkSections.STATim = NULL; 400 566 } 401 567 402 568 if (_currentTalkSections.TLKTim != NULL) { 403 freeTIM(_currentTalkSections.TLKTim);569 tim_releaseBuffer(_currentTalkSections.TLKTim); 404 570 _currentTalkSections.TLKTim = NULL; 405 571 } 406 572 407 573 if (_currentTalkSections.ENDTim != NULL) { 408 freeTIM(_currentTalkSections.ENDTim);574 tim_releaseBuffer(_currentTalkSections.ENDTim); 409 575 _currentTalkSections.ENDTim = NULL; 410 576 } 411 577 } 412 578 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 } 579 void KyraEngine_v2::npcChatSequence(const char *str, int objectId, int vocHigh, int vocLow) { 580 _chatText = str; 581 _chatObject = objectId; 582 objectChatInit(str, objectId, vocHigh, vocLow); 419 583 420 int32 formBlockSize = file.getFORMBlockSize(); 421 if (formBlockSize == -1) { 422 error("No FORM chunk found in file: '%s'", filename); 423 return NULL; 424 } 584 if (!_currentTalkSections.TLKTim) 585 _currentTalkSections.TLKTim = tim_loadFile(_TLKFilename, 0, 0); 425 586 426 if (formBlockSize < 20) { 427 return NULL; 428 } 587 setNextIdleAnimTimer(); 588 589 uint32 ct = chatCalcDuration(str); 590 uint32 time = _system->getMillis(); 591 _chatEndTime = time + (3 + ct) * _tickLength; 592 uint32 chatAnimEndTime = time + (3 + (ct >> 1)) * _tickLength; 429 593 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; 594 if (_chatVocHigh >= 0) { 595 playVoice(_chatVocHigh, _chatVocLow); 596 _chatVocHigh = _chatVocLow = -1; 440 597 } 441 598 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; 599 while (((textEnabled() && _chatEndTime > _system->getMillis()) || (speechEnabled() && snd_voiceIsPlaying())) && !(_quitFlag || _skipFlag)) { 600 if (!speechEnabled() && chatAnimEndTime > _system->getMillis() || speechEnabled() && snd_voiceIsPlaying()) { 601 _objectChatFinished = false; 449 602 450 _TIMBuffers.AVTLChunk = (uint16 *)(buffer + timHeader->AVTLOffset); 451 _TIMBuffers.TEXTChunk = buffer + timHeader->TEXTOffset; 603 while (!_objectChatFinished && !_skipFlag) { 604 if (_currentTalkSections.TLKTim) 605 tim_processSequence(_currentTalkSections.TLKTim, 0); 606 else 607 _objectChatFinished = false; 452 608 453 if (!file.loadIFFBlock(AVTL_CHUNK, _TIMBuffers.AVTLChunk, chunkSize)) { 454 error("Couldn't load AVTL chunk from file: '%s'", filename); 455 return NULL; 609 updateWithText(); 610 611 int inputFlag = checkInput(0); 612 removeInputTop(); 613 if (inputFlag == 198 || inputFlag == 199) { 614 //XXX 615 _skipFlag = true; 616 snd_stopVoice(); 617 } 618 delay(10); 619 } 620 if (_currentTalkSections.TLKTim) 621 tim_o_abort(0); 622 } 623 updateWithText(); 456 624 } 457 625 458 _ TIMBuffers.UnkChunk = (TIMStructUnk1 *)(buffer + timHeader->unkOffset);626 _skipFlag = false; 459 627 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; 628 if (_currentTalkSections.TLKTim) { 629 tim_releaseBuffer(_currentTalkSections.TLKTim); 630 _currentTalkSections.TLKTim = 0; 466 631 } 467 632 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; 633 _text->restoreScreen(); 634 _chatText = 0; 635 _chatObject = -1; 636 setNextIdleAnimTimer(); 477 637 } 478 638 479 void KyraEngine_v2::freeTIM(byte *buffer) { 480 TIMHeader *timHeader = (TIMHeader *)buffer; 481 482 if (timHeader->deleteBufferFlag == 0xBABE) { 483 delete[] buffer; 484 } 639 void KyraEngine_v2::setNewDlgIndex(int dlgIndex) { 640 if (dlgIndex == _mainCharacter.dlgIndex) 641 return; 642 memset(_newSceneDlgState, 0, 32); 643 for (int i = 0; i < 19; i++) 644 memset(_conversationState[i], -1, 14); 645 _npcTalkUNK = 0; 646 _mainCharacter.dlgIndex = dlgIndex; 485 647 } 486 648 487 649 } // end of namespace Kyra 488 489