#1 Re: Справочная информация » Адреса и функции gta_sa.exe 1.0 » 21-07-2007 18:37

Кстати, может тебе пригодится вот этот кусок кода с одной программки, а то я смотрю у вас невнятно эта структрура описана здесь на форуме:

struct GTASA_SCRIPT_THREAD	// 0xE0 bytes total
{
	void* pNext;			// 0x00
	void* pPrev;			// 0x04
	char strName[8];		// 0x08
	DWORD dwBaseIP;			// 0x10
	DWORD dwScriptIP;		// 0x14
	DWORD dwReturnStack[8];	// 0x18
	WORD dwStackPointer;	// 0x38
	DWORD dwLocalVar[34];	// 0x3C
	BYTE bStartNewScript;	// 0xC4
	BYTE bJumpFlag;			// 0xC5
	BYTE bIsMissionThread;	// 0xC6
	BYTE bIsExternalScript;	// 0xC7
	BYTE bInMenu;			// 0xC8
	BYTE bUnknown;			// 0xC9
	DWORD dwWakeTime;		// 0xCC
	WORD wIfParam;			// 0xD0
	BYTE bNotFlag;			// 0xD2
	BYTE bWastedBustedCheck;// 0xD3
	BYTE bWastedBustedFlag;	// 0xD4
	DWORD dwSceneSkipIP;	// 0xD8
	BYTE bMissionThread;	// 0xDC
};

#2 Re: Справочная информация » Адреса и функции gta_sa.exe 1.0 » 21-07-2007 18:26

На закуску:)

018c=4,play_sound %4d% at %1d% %2d% %3d%
097A=4,play_audio_at %1d% %2d% %3d% event %4d%

00507340 CAudioEvent::Buffer::PlayAt (t_coords Coords; int16 EventID)

Покапавшись в ассемблере отличий у этих опкодов не нашёл. Они положи почти как две капли воды. Хотя последний, наверное, должен использоваться после 03CF, который загружает банки.

Я думаю, так будет логичнее их назвать:

018c=4,play_at %1d% %2d% %3d% loaded_audio_event %4d%
// проигрывает уже загруженные события (1000..1800)

097A=4,play_at %1d% %2d% %3d% loaded_bank_audio_event %4d%
// проигрывает уже загруженные события (1000..1800) из банков (1800..2000)

%4d% = -1 // возможно проигрывает последний загруженный звук, но неуверен.
Надо проверить в игре.
Seemann wrote:

Edit:
На всякий случай скажу, что 0xC47A0000 = -100.0

Почему -100 ?
(Добавлено) А точно это ж float! Блин, это значит, что в буфере содержутся координаты воспроизведения звука!

Seemann wrote:

...посмотреть исходники SAAT.

Зачем? Я смотрел раньше, но ничего нового я не узнал.

А программа работает нормально? В будущем я ещё и для AudioStreams что-то подобное сделаю.

#3 Re: Справочная информация » Адреса и функции gta_sa.exe 1.0 » 21-07-2007 11:51

Не совсем в рамках темы, но всё таки...

В ходе разработки своей программы SFX Editor(http://rapidshare.com/files/44154049/SF … r.rar.html) у меня возникла мысль заглянуть в дебри опкода 03CF и в ходе разбора кода я нарыл много полезной информации. Думаю она вам пригодится.

Вот функции и структуры связанные со звуком (в основном звуковые эффекты):

CODE:
004D88A0 void CAudio->AudioSFX::LoadBankWave (int16 BankID,BankSlotID)
004D8ED0 void CAudio->AudioSFX::LoadWave (int16 BankID,WaveID,BankSlotID)
004D9930 bool CAudio::Create()
004D9CC0 bool CAudioEvents::Buffer::LoadInfo (int32* pAudioEvent,pBankID,pWaveID,EBufferID)
004E01B0 BankLookup* CAudioSFX::GetBankLookupAddress (uint8 BankID)
004E0220 bool CAudioSFX::LoadedBankToSlot (uint16 BankID; int16 BankSlotID)
004EBFE0 bool CAudioEvents::Buffer::LoadedSlot (uint8 BufferID)
004EF520 int8 CSoundManager::LoadedBank (int16 BankSlotID)
00507290 void CAudioEvents::Buffer::Load (uint8 BufferId; int32 AudioEvent)
005B9A60 void CAudioEvents::LoadExplosionSounds()
005B9690 bool CSoundManager::Init(?)
005B9A60 void CAudioEvents::LoadExplosionSounds
005B9C60 bool CAudioEvents::Create()

DATA:
00B5F8B8 CAudio
+D98     CAudioSFX*	// здесь лежит указатель, адрес динамический, обычно 021F0000, насчёт класса не уверен
00B62CB0 CSoundManager
00B6BC90 CAudioEvents

CAudioSFX
+0  dd* pBankSlotData // BankSlot.dat
+4  dd* pBankLookupData // BankLkup.dat
+8  dd* pPakFilesData // PakFiles.dat
+C  dw  NumSlots
+E  dw  NumBanks
+10 db  NumPakFiles
+14 db  BufferFlag?

+24 CAudioSFX::Buffer[50]  // С этим буфером до конца ещё не разобрался
	+0  dd* pBankSlot
	+4  dd  BankLookup.WaveOffset
	+8  dd  BankLookup.WaveLenght
	+14 dd  UnkFlag?
	+18 dw  BankID
	+1A dw  BankSlotID
	+20 dw  WaveID
	+22 db  BankLookup.PackID

+668 dw InitBufferSlotsNum // количество проинициализированных слотов буфера

Ниже следующий кусок кода из моей программы. Он отражает назначение некоторых структур и переменных, которые используются в вышеперечисленных функциях.

  { === Wave Audio Bank Structure === }

  TWaveInfo = record
    HeaderOffset: Cardinal;
    StartLoop:    Integer;
    SampleRate:   Word;
    UnknownFlag1: Byte;   // Pan??
    UnknownFlag2: Shortint;   // Loops???
  end;
  TWaveBankHeader = record
    WaveCount:    Cardinal;
    WaveInfoList: array[0..399] of TWaveInfo;
  end;
  TWaveBank = record
    Header:       TWaveBankHeader;
    Data:         array of Byte;
  end;

  { === SFX PACK Structure === }

  TSFX_Pack = array of TWaveBank;

  { === BankLkup.dat Structure === }

  TWaveBankInfo = record
    PackFileID: Cardinal; // ($CCCCCC00 or $XX), $XX - File ID
    Offset:     Cardinal;
    DataSize:   Cardinal;
  end;
  TWaveBanks = array of TWaveBankInfo;

  { === PakFiles.dat Structure === }

  TPackName = array of array[0..51] of Char;

Здесь я хочу показать алгоритм работы опкода 03CF. Некоторые куски кода мне не совсем понятны, их назначение.

03CF: load_in (AUDIO_EVENT_BUFFER:unsigned_byte) audio_event (AUDIO_EVENT:int)

AUDIO_EVENT_BUFFER(MAX 4 SLOTS)
1,2,3,4: для звуков (SOUNDs 2000..45400,-1)
3,4: для набора звуков (BANKs 1800..1829)

=========================================================================================================================
<gta_sa._opcode_03CF>
=========================================================================================================================
0048519B > > 6A 02          PUSH 2                                      ;  _opcode_03CF; Case 3CF of switch 00483BF2
0048519D   . 8BCE           MOV ECX,ESI
0048519F   . E8 DCEEFDFF    CALL <gta_sa.CScriptThread::LoadNumParams>
004851A4   . 8B0D 7C3CA400  MOV ECX,DWORD PTR DS:[<OpcodeParams[1]>]
004851AA   . 33D2           XOR EDX,EDX
004851AC   . 8A15 783CA400  MOV DL,BYTE PTR DS:[<OpcodeParams[0]>]
004851B2   . FECA           DEC DL
004851B4   . 51             PUSH ECX                                      ;  2: int32 AudioEvent
004851B5   . B9 90BCB600    MOV ECX,OFFSET <gta_sa.CAudioEvent>
004851BA   . 52             PUSH EDX                                      ;  1: uint8 BufferID
004851BB   . E8 D0200800    CALL <gta_sa.CAudioEvent::Load>
004851C0   . 32C0           XOR AL,AL
=========================================================================================================================
<gta_sa.CAudioEvent::Load>
=========================================================================================================================
00507290 > $ 81C1 A0020000  ADD ECX,2A0                                   ;  Buffer& = CAudioEvents::Buffer         
00507296   .^E9 F54EFEFF    JMP gta_sa.004EC190                                    
.........................................................................................................................
004EC190   > 83EC 0C        SUB ESP,0C
004EC193   . 53             PUSH EBX
004EC194   . 8B5C24 14      MOV EBX,DWORD PTR SS:[ESP+14]                  ;  EBX = BufferID
004EC198   . 80FB 04        CMP BL,4
004EC19B   . 56             PUSH ESI
004EC19C   . 8BF1           MOV ESI,ECX
004EC19E   . 0F83 C0000000  JNB gta_sa.004EC264                            ;  exit if BufferID >= 4
004EC1A4   . 53             PUSH EBX
004EC1A5   . E8 36FEFFFF    CALL <gta_sa.CAudioEvents::Buffer::LoadedSlot>
004EC1AA   . 84C0           TEST AL,AL
004EC1AC   . 0F84 B2000000  JE gta_sa.004EC264                             ;  exit if prc = false
004EC1B2   . 0FB6C3         MOVZX EAX,BL
004EC1B5   . 55             PUSH EBP
004EC1B6   . 8BC8           MOV ECX,EAX
004EC1B8   . 57             PUSH EDI
004EC1B9   . C1E1 05        SHL ECX,5                                      ;  BufferID * 32
004EC1BC   . 03F1           ADD ESI,ECX
004EC1BE   . 50             PUSH EAX                                       ;  4: int32 EBufferID = BufferID
004EC1BF   . 8DBE AC000000  LEA EDI,DWORD PTR DS:[ESI+AC]
004EC1C5   . 57             PUSH EDI                                       ;  3: int32* pWaveID = *Buffer::Slot[BufferId].WaveID
004EC1C6   . 8DAE A8000000  LEA EBP,DWORD PTR DS:[ESI+A8]
004EC1CC   . 8D5424 2C      LEA EDX,DWORD PTR SS:[ESP+2C]
004EC1D0   . 55             PUSH EBP                                       ;  2: int32* pBankID = *Buffer::Slot[BufferId].BankID
004EC1D1   . 52             PUSH EDX                                       ;  1: int32* pAudioEvent = *AudioEvent
004EC1D2   . E8 E9DAFEFF    CALL <gta_sa.CAudioEvents::Buffer::LoadInfo>
004EC1D7   . 83C4 10        ADD ESP,10
004EC1DA   . 84C0           TEST AL,AL
004EC1DC   . 0F84 80000000  JE gta_sa.004EC262                             ;  exit if PROC = false
004EC1E2   . 8B07           MOV EAX,DWORD PTR DS:[EDI]
004EC1E4   . 33C9           XOR ECX,ECX
004EC1E6   . 85C0           TEST EAX,EAX
004EC1E8   . 66:0FB6C3      MOVZX AX,BL
004EC1EC   . 7C 1B          JL SHORT gta_sa.004EC209                       ;  jump if WaveID < 0
004EC1EE   . 66:8B0F        MOV CX,WORD PTR DS:[EDI]
004EC1F1   . 33D2           XOR EDX,EDX
004EC1F3   . 66:8B55 00     MOV DX,WORD PTR SS:[EBP]
004EC1F7   . 83C0 1A        ADD EAX,1A
004EC1FA   . 50             PUSH EAX                                       ;  3: int16 BankSlotID
004EC1FB   . 51             PUSH ECX                                       ;  2: int16 WaveID
004EC1FC   . B9 B8F8B500    MOV ECX,<gta_sa.CAudio>
004EC201   . 52             PUSH EDX                                       ;  1: int16 BankID
004EC202   . E8 C9CCFEFF    CALL <gta_sa.CAudio->CAudioSFX::LoadWave>
004EC207   . EB 13          JMP SHORT gta_sa.004EC21C
004EC209   > 66:8B4D 00     MOV CX,WORD PTR SS:[EBP]
004EC20D   . 83C0 1A        ADD EAX,1A
004EC210   . 50             PUSH EAX                                       ;  2: int16 BankSlotID
004EC211   . 51             PUSH ECX                                       ;  1: int16 BankID
004EC212   . B9 B8F8B500    MOV ECX,<gta_sa.CAudio>
004EC217   . E8 84C6FEFF    CALL <gta_sa.CAudio->AudioSFX::LoadBankWave>
004EC21C   > 8B5424 24      MOV EDX,DWORD PTR SS:[ESP+24]
004EC220   . 8996 A4000000  MOV DWORD PTR DS:[ESI+A4],EDX                  ;  Buffer::Slot[BufferId].AudioEvent = AudioEvent
004EC226   . C786 9C000000 >MOV DWORD PTR DS:[ESI+9C],0
004EC230   . C74424 10 0000>MOV DWORD PTR SS:[ESP+10],C47A0000
004EC238   . 8B4424 10      MOV EAX,DWORD PTR SS:[ESP+10]
004EC23C   . 81C6 90000000  ADD ESI,90                                     ;  CurSlot& = Buffer::Slot[BufferId]
004EC242   . C74424 14 0000>MOV DWORD PTR SS:[ESP+14],C47A0000
004EC24A   . 8B4C24 14      MOV ECX,DWORD PTR SS:[ESP+14]
004EC24E   . 8906           MOV DWORD PTR DS:[ESI],EAX                     ;  CurSlot.ddvar1 = 0xC47A0000
004EC250   . C74424 18 0000>MOV DWORD PTR SS:[ESP+18],C47A0000
004EC258   . 8B5424 18      MOV EDX,DWORD PTR SS:[ESP+18]
004EC25C   . 894E 04        MOV DWORD PTR DS:[ESI+4],ECX                   ;  CurSlot.ddvar2 = 0xC47A0000
004EC25F   . 8956 08        MOV DWORD PTR DS:[ESI+8],EDX                   ;  CurSlot.ddvar3 = 0xC47A0000
004EC262   > 5F             POP EDI
004EC263   . 5D             POP EBP
004EC264   > 5E             POP ESI
004EC265   . 5B             POP EBX
004EC266   . 83C4 0C        ADD ESP,0C
004EC269   . C2 0800        RETN 8
=========================================================================================================================

GetAudioEventInfo для 03CF опкода: загружает в буфер информацию о аудио событии.

Буфер находится по адресу 0x00B6BFC0 и содержит четыре элемента размером 32 байта.

AudioEventBuffer [0x00B6BFC0, 32 bytes, 4 elements]
+0  dd ?C4A70000
+4  dd ?C4A70000
+8  dd ?C4A70000
+14 dd AudioEventId
+18 dd BankId
+20 dd WaveId

EBufferID - Extended Buffer Identificator. Он может содержитать не только номер буфера, но и дополнительную информацию.

Pascal: function CAudioEvents::Buffer::LoadInfo(var pAudioEvent,pBankID,pWaveID: Integer; int EBufferID): Boolean; cdecl;
C/C++:  __cdecl int CAudioEvents::Buffer::LoadInfo(int* pAudioEvent,pBankID,pWaveID; int EBufferID);
-------------------------
[ESP+8]	pAudiEvent
[ESP+C]	pBankId
[ESP+10]	pWaveId
[ESP+14]	EBufferID
-------------------------
=========================================================================================================================
004D9CC0 >/$ 56                PUSH ESI                        		;  (* CAudioEvents::Buffer::LoadInfo *)
004D9CC1  |. 8B7424 08         MOV ESI,DWORD PTR SS:[ESP+8]
004D9CC5  |. 8B06              MOV EAX,DWORD PTR DS:[ESI]
004D9CC7  |. 3D 08070000       CMP EAX,708					;  if pAudioEvent < 1800 then
004D9CCC  |. 7D 04             JGE SHORT gta_sa.004D9CD2			;  begin
004D9CCE  |. 32C0              XOR AL,AL						;    Result := False;
004D9CD0  |. 5E                POP ESI						;    Exit;
004D9CD1  |. C3                RETN							;  end;
004D9CD2  |> 3D D0070000       CMP EAX,7D0					;  if pAudioEvent < 2000 then
004D9CD7  |. 7D 1B             JGE SHORT gta_sa.004D9CF4			;  begin
004D9CD9  |. 8B0485 70BC8A00   MOV EAX,DWORD PTR DS:[EAX*4+8ABC70]	;  // BankEvent[AudioEvent - 1800]
004D9CE0  |. 8B4C24 0C         MOV ECX,DWORD PTR SS:[ESP+C]
004D9CE4  |. 8B5424 10         MOV EDX,DWORD PTR SS:[ESP+10]
004D9CE8  |. 8901              MOV DWORD PTR DS:[ECX],EAX			;    pBankID := BankIdEvent[pAudioEvent - 1800];
004D9CEA  |. C702 FFFFFFFF     MOV DWORD PTR DS:[EDX],-1			;    pWaveID := -1;
004D9CF0  |. B0 01             MOV AL,1						;    Result := True; 
004D9CF2  |. 5E                POP ESI						;    Exit;
004D9CF3  |. C3                RETN							;  end;
004D9CF4  |> 3D FFFF0000       CMP EAX,0FFFF					;  if pAudioEvent = -1 then // Для чего???
004D9CF9  |. 75 3D             JNZ SHORT gta_sa.004D9D38			;  begin
004D9CFB  |. 8B4424 0C         MOV EAX,DWORD PTR SS:[ESP+C]			;    // SOUND_BANK_NULL = 291
004D9CFF  |. C700 23010000     MOV DWORD PTR DS:[EAX],123			;    pBankID := SOUND_BANK_NULL;
004D9D05  |. 8B4424 14         MOV EAX,DWORD PTR SS:[ESP+14]
004D9D09  |. 85C0              TEST EAX,EAX					;    if (EBufferID >= 0) and
004D9D0B  |. 7C 1D             JL SHORT gta_sa.004D9D2A
004D9D0D  |. 83F8 04           CMP EAX,4						;       (EBufferID < 4) then
004D9D10  |. 7D 18             JGE SHORT gta_sa.004D9D2A			;    begin
004D9D12  |. 25 01000080       AND EAX,80000001					;      EBufferID := EBufferID and $80000001;  
004D9D17  |. 79 05             JNS SHORT gta_sa.004D9D1E			;      if EBufferID < 0 then	// Зачем? Смысл?
004D9D19  |. 48                DEC EAX						;	 begin
004D9D1A  |. 83C8 FE           OR EAX,FFFFFFFE					;        EBufferID := (EBufferID - 1) or $FFFFFFFE;
004D9D1D  |. 40                INC EAX						;        Inc(EBufferID);
004D9D1E  |> 8B4C24 10         MOV ECX,DWORD PTR SS:[ESP+10]		;      end;
004D9D22  |. D1E0              SHL EAX,1						;      pWaveID := EBufferID * 2; //всегда 0 или 2
004D9D24  |. 8901              MOV DWORD PTR DS:[ECX],EAX			;      Result := True;
004D9D26  |. B0 01             MOV AL,1						;      Exit;
004D9D28  |. 5E                POP ESI						;    end;
004D9D29  |. C3                RETN
004D9D2A  |> 8B5424 10         MOV EDX,DWORD PTR SS:[ESP+10]		;    
004D9D2E  |. C702 00000000     MOV DWORD PTR DS:[EDX],0			;    pWaveID := 0;
004D9D34  |. B0 01             MOV AL,1						;    Result := True;
004D9D36  |. 5E                POP ESI						;    Exit;
004D9D37  |. C3                RETN							;  end
004D9D38  |> 05 30F8FFFF       ADD EAX,-7D0
004D9D3D  |. 894424 08         MOV DWORD PTR SS:[ESP+8],EAX			;  pAudioEvent := pAudioEvent - 2000;
004D9D41  |. DB4424 08         FILD DWORD PTR SS:[ESP+8]
004D9D45  |. 83EC 08           SUB ESP,8
004D9D48  |. D80D 4C8B8500     FMUL DWORD PTR DS:[858B4C]			;  // CONST [858B4C] = 0.005 (1/200)
004D9D4E  |. DD1C24            FSTP QWORD PTR SS:[ESP]
004D9D51  |. E8 9A7C3400       CALL <gta_sa.floor>				
004D9D56  |. 83C4 08           ADD ESP,8
004D9D59  |. E8 E27D3400       CALL <gta_sa.__ftol2> 
004D9D5E  |. 8B4C24 0C         MOV ECX,DWORD PTR SS:[ESP+C]
004D9D62  |. 05 93000000       ADD EAX,93
004D9D67  |. 8901              MOV DWORD PTR DS:[ECX],EAX			;  pBankID := Floor(pAudioEvent/200) + 147
004D9D69  |. 8B06              MOV EAX,DWORD PTR DS:[ESI]			;  // pBankID := AudioEvent div 200 + 147
004D9D6B  |. 2D D0070000       SUB EAX,7D0					;  // 147 - SCRIPT_FIRST_BANK_ID
004D9D70  |. 99                CDQ
004D9D71  |. B9 C8000000       MOV ECX,0C8
004D9D76  |. F7F9              IDIV ECX
004D9D78  |. 8B4424 10         MOV EAX,DWORD PTR SS:[ESP+10]
004D9D7C  |. 5E                POP ESI
004D9D7D  |. 8910              MOV DWORD PTR DS:[EAX],EDX			;  pWaveID := pAudioEvent mod 200
004D9D7F  |. B0 01             MOV AL,1						;  Result := True;
004D9D81  \. C3                RETN							;  Exit;
=========================================================================================================================
CAudio->AudioSFX::LoadBankWave (int16 BankID,BankSlotID)
=========================================================================================================================
004D88A0 > $ 8A41 01        MOV AL,BYTE PTR DS:[ECX+1]                  ;  
004D88A3   . 84C0           TEST AL,AL
004D88A5   . 75 0B          JNZ SHORT gta_sa.004D88B2
004D88A7   . 8B89 980D0000  MOV ECX,DWORD PTR DS:[ECX+D98]              ;  CAudioSFX& = *CAudio->AudioSFX
004D88AD   . E9 BE7D0000    JMP gta_sa.004E0670
004D88B2   > C2 0800        RETN 8
.........................................................................................................................
004E0670   > 56             PUSH ESI
004E0671   . 8BF1           MOV ESI,ECX                                  ;  ESI = CAudioSFX
004E0673   . 8A46 14        MOV AL,BYTE PTR DS:[ESI+14]
004E0676   . 84C0           TEST AL,AL
004E0678   . 0F84 15010000  JE gta_sa.004E0793                           ;  exit if CAudioSFX::UnkFlag1 = 0
004E067E   . 0FBF46 0E      MOVSX EAX,WORD PTR DS:[ESI+E]
004E0682   . 53             PUSH EBX
004E0683   . 8B5C24 0C      MOV EBX,DWORD PTR SS:[ESP+C]
004E0687   . 55             PUSH EBP
004E0688   . 0FB7EB         MOVZX EBP,BX
004E068B   . 3BE8           CMP EBP,EAX
004E068D   . 57             PUSH EDI
004E068E   . 0F8F FC000000  JG gta_sa.004E0790                           ;  exit if BankID > CAudioSFX::NumBanks
004E0694   . 8B7C24 18      MOV EDI,DWORD PTR SS:[ESP+18]
004E0698   . 66:85FF        TEST DI,DI
004E069B   . 0F8C EF000000  JL gta_sa.004E0790                           ;  exit if BankID < 0
004E06A1   . 66:3B7E 0C     CMP DI,WORD PTR DS:[ESI+C]
004E06A5   . 0F8F E5000000  JG gta_sa.004E0790                           ;  exit if BankSlotID > CAudioSFX::NumBankSlots
004E06AB   . 57             PUSH EDI                                     ;  2: int16 BankSlotID
004E06AC   . 53             PUSH EBX                                     ;  1: int16 BankID
004E06AD   . E8 6EFBFFFF    CALL <gta_sa.CAudioSFX::LoadedBankToSlot>    ;  <|=== LoadedBankToSlot??? ===
004E06B2   . 84C0           TEST AL,AL
004E06B4   . 0F85 D6000000  JNZ gta_sa.004E0790                          ;  exit if proc = true
004E06BA   . 33C9           XOR ECX,ECX
004E06BC   . 8D46 3E        LEA EAX,DWORD PTR DS:[ESI+3E]
004E06BF   . 90             NOP                                          ;  /=== LoadedBankToBuffer??? ===
004E06C0   > 0FBF50 FE      MOVSX EDX,WORD PTR DS:[EAX-2]                ;  |!loop ECX = 0..31
004E06C4   . 3BD5           CMP EDX,EBP                                  ;  |
004E06C6   . 75 09          JNZ SHORT gta_sa.004E06D1                    ;  |jump if Buffer[ECX].BankID <> BankID
004E06C8   . 66:3938        CMP WORD PTR DS:[EAX],DI                     ;  |
004E06CB   . 0F84 BF000000  JE gta_sa.004E0790                           ;  |exit if Buffer[ECX].BankSlotID = BankSlotID
004E06D1   > 41             INC ECX                                      ;  |
004E06D2   . 83C0 20        ADD EAX,20                                   ;  |
004E06D5   . 83F9 32        CMP ECX,32                                   ;  |
004E06D8   .^7C E6          JL SHORT gta_sa.004E06C0                     ;  \jump !loop if ECX < 32
004E06DA   . 53             PUSH EBX                                     ;  1: BankID
004E06DB   . 8BCE           MOV ECX,ESI
004E06DD   . E8 CEFAFFFF    CALL <gta_sa.CAudioSFX::GetBankLookupAddress>;  BankLookup* PROC
004E06E2   . 0FBF8E 6806000>MOVSX ECX,WORD PTR DS:[ESI+668]
004E06E9   . C1E1 05        SHL ECX,5                                    ;  InitBufferSlotsNum*32
004E06EC   . 66:895C31 3C   MOV WORD PTR DS:[ECX+ESI+3C],BX              ;  Buffer[InitBufferSlotsNum].BankID = BankID
004E06F1   . 0FBF96 6806000>MOVSX EDX,WORD PTR DS:[ESI+668]
004E06F8   . C1E2 05        SHL EDX,5
004E06FB   . 66:897C32 3E   MOV WORD PTR DS:[EDX+ESI+3E],DI              ;  Buffer[InitBufferSlotsNum].BankSlotID = BankSlotID
004E0700   . 0FBF8E 6806000>MOVSX ECX,WORD PTR DS:[ESI+668]
004E0707   . 83C1 02        ADD ECX,2
004E070A   . C1E1 05        SHL ECX,5
004E070D   . 66:C70431 FFFF MOV WORD PTR DS:[ECX+ESI],0FFFF              ;  Buffer[InitBufferSlotsNum].Unk1 = -1
004E0713   . 0FBF8E 6806000>MOVSX ECX,WORD PTR DS:[ESI+668]
004E071A   . 8B1E           MOV EBX,DWORD PTR DS:[ESI]
004E071C   . 0FBFD7         MOVSX EDX,DI
004E071F   . 69D2 D4120000  IMUL EDX,EDX,12D4
004E0725   . 03D3           ADD EDX,EBX
004E0727   . C1E1 05        SHL ECX,5
004E072A   . 895431 24      MOV DWORD PTR DS:[ECX+ESI+24],EDX            ;  Buffer[InitBufferSlotsNum].pBankSlot = *BankSlot[BankSlotID]
004E072E   . 8A08           MOV CL,BYTE PTR DS:[EAX]
004E0730   . 0FBF96 6806000>MOVSX EDX,WORD PTR DS:[ESI+668]
004E0737   . C1E2 05        SHL EDX,5
004E073A   . 884C32 42      MOV BYTE PTR DS:[EDX+ESI+42],CL              ;  Buffer[InitBufferSlotsNum].PackID = BankLookup.PackID
004E073E   . 8B48 04        MOV ECX,DWORD PTR DS:[EAX+4]
004E0741   . 0FBF96 6806000>MOVSX EDX,WORD PTR DS:[ESI+668]
004E0748   . C1E2 05        SHL EDX,5
004E074B   . 894C32 28      MOV DWORD PTR DS:[EDX+ESI+28],ECX            ;  Buffer[InitBufferSlotsNum].PackID = BankLookup.WaveDataOffset
004E074F   . 0FBF96 6806000>MOVSX EDX,WORD PTR DS:[ESI+668]
004E0756   . 8B40 08        MOV EAX,DWORD PTR DS:[EAX+8]
004E0759   . C1E2 05        SHL EDX,5
004E075C   . 894432 2C      MOV DWORD PTR DS:[EDX+ESI+2C],EAX            ;  Buffer[InitBufferSlotsNum].PackID = BankLookup.WaveLenght
004E0760   . 0FBF8E 6806000>MOVSX ECX,WORD PTR DS:[ESI+668]
004E0767   . C1E1 05        SHL ECX,5
004E076A   . C74431 38 0100>MOV DWORD PTR DS:[ECX+ESI+38],1              ;  Buffer[InitBufferSlotsNum].bUnkFlag1 = 1
004E0772   . 0FBF86 6806000>MOVSX EAX,WORD PTR DS:[ESI+668]
004E0779   . 66:FF86 660600>INC WORD PTR DS:[ESI+666]                    ;  CAudioSFX::InitBankBufNum++
004E0780   . 40             INC EAX
004E0781   . 99             CDQ
004E0782   . B9 32000000    MOV ECX,32
004E0787   . F7F9           IDIV ECX
004E0789   . 66:8996 680600>MOV WORD PTR DS:[ESI+668],DX                 ;  CAudioSFX::InitBufNum++ %= 50
004E0790   > 5F             POP EDI
004E0791   . 5D             POP EBP
004E0792   . 5B             POP EBX
004E0793   > 5E             POP ESI
004E0794   . C2 0800        RETN 8

Ещё мне не совсем понятно назначение файла BankSlot.dat.
Наверное этот файл хранит глобальный буффер, его размер и начальные значения.
Вообще, я так понимаю в игре три буффера для звуковых эффектов.
Первый, и наверное самый главный - это буффер BankSlot. Количество слотов зависит от размера файла. Обычно 45.
Второй - это CAudiSFX::Buffer[]. Имеет 50 слотов.
И третий, наверное для скриптов - это CAudioEvent::Buffer. Он самый маленький имеет всего только 4 слота.

Но фишка в том, что в слот может загружатся как целый банк, так и отдельный файл!
А некоторые загружаются ещё в начале игры. Их не нужно загружать повторно.

Моей программой можно посмотреть EventId, BankId, WaveId и прослушать необходимые звуки.

Думаю, если Seemann согласится встроить SFX плагин, то в SB3 мы сможем прослушивать звуки,
не отвлекаясь от написания скриптов. Думаю, что в мой плагин можно будет добавить функцию,
которая возвращает имя аудио события, если в SB3 не будут именованы аудио-константы.

Ладно хватит. А то уже оффтоп пошёл smile

А, чуть не забыл.
По файловому адресу 004AB490 идут структуры размером 4 байта и в каждой из них номер банка,
положение который соотвествует скриптовым событиям, начиная с 1800 и до 2000.
Это те аудио события, которые загружают банки, а не звуки smile

        352: 1800
        310: 1801
        296: 1802
        291: 1803,1805,1808,1815,1816 // считается как NULL, -1 указывает тоже на этот банк
        242: 1804
        222: 1806
        209: 1807
        167: 1809
        163: 1810
        160: 1811
        265: 1812
        304: 1813
        158: 1814
        292: 1817
        171: 1818
        198: 1819
        226: 1820
        293: 1821
        319: 1822
        345: 1823
        351: 1824
        266: 1825
        183: 1826
        153: 1827
        298: 1828
        339: 1829

Кстати, аудио события, начинающие с 1000 и до 1800, это звуки банков, которые доступны только при загрузке банков.
Они проигрываются только с помощью следующих опкодов:

	097A: play_at 0.0 0.0 0.0 loaded_audio_event 1132
	097B=2,play_audio_at_object %1d% event %2d%

Но некоторые из этих событий не надо загружать, т. к. они уже либо загружены,
либо загружаются и проигрываются вышеупомянутыми опкодами.

#4 Re: Вопросы по скриптингу » Сохранения » 24-06-2007 13:25

Вот у меня вопрос, если в сейве ко всем ячейки содержащие адреса с 0xA49960 до конца SCM блока прибавить размер добаленного кода в SCM, то сейв загрузится? Я думаю, что да, ведь указатели на текущие потоки не собьются.

#5 Re: Вопросы по скриптингу » Один вопрос » 24-06-2007 13:17

Вот скажите мне где находятся в экзешнике (по каким адресам) зашитые скрипты, например, такие как пролетающий самолёт над героем в случайное время, патрулирующий вертолёт в Лос-Сантосе, реакции полиции на нарушения правопорядка и т.д. Хотелось бы их изменить.

#6 Re: Работа с памятью, EXE » "Белимитный город" » 23-06-2007 09:30

Да вот, например, у меня город 3000x3000, а дальше хочу сделать ещё город 3000x3000 (например на севере или на юге, не важно) и мне надо, чтобы была для него отдельная карта, чтобы пути были, но память то не бесконечная! Мне надо, чтобы игрок достигнув одной из "сторон света" мог перейти на следующую локацию не нагружая память! Надо, чтобы старый штат выгрузился и загрузился новый!

Вот эта функция, которую я искал:

LoadGame(char; fileName)) 
Initializes all data structures and loads fileName (which is gta.dat).

#7 Работа с памятью, EXE » "Белимитный город" » 22-06-2007 17:20

San'OK
Replies: 9

Привет всем! Вот я давно хотел сделать так, чтобы игрок достигнув предела карты мог дальше ходить по местности, выполнять миссии и т. д.

Например, проверяется каким-нибудь опкодом местоположение игрока и если он выходит за пределы карты, то выгружается старый город из памяти и загружается новый. Как это реализовать может поможите? Есть проблема со скриптами: использовать один, один как главный с нескольками или каждый по отдельности. Также как пользоваться координатами для разных городов в опкодах? Ещё я где-то видел, что есть функция которая загружает игру через dat файл. Интересно есть функция которая всё выгружает из памяти?

Board footer

Powered by FluxBB