#51 25-04-2007 13:13

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Адреса и функции gta_sa.exe 1.0

в первую очередь, хотелось нормально методы CScriptThread обозвать нормально

.text:00469F00 ParseThread

движок перебирает опкоды, пока не найдет 0001: wait

.text:00464080 ; int __stdcall CollectNumberParams(__int16 ParamsNumber)

движок читает опр. число числовых параметров (константы, переменные, массивы) из SCM. Параметры пишутся в ParamsArray[32].

.text:00464DA0 ; int __cdecl j_SetJumpLocation(int JumpLocation)

thread->IP ставится в указанную позицию (опкод 0002: jump и подобные)

.text:00464790 ; int __cdecl GetVariablePos(int VarType)

функция читает следующий параметр (предполагается, что там переменная) и возвращает адрес переменной в варспейсе. Используется в основном в выражениях
Vartype:
1 - local var
2 - global var

Параметр не используется.

.text:004859D0 ; int __stdcall SetConditionResult(boolean ConditionResult)

устанавливает значение условия в потоке (Thread->If_result)

.text:00464500 ; int __stdcall GetThreadExtraParams(int *NewThreadStruct)

собирает параметры, переданные в новый поток (опкод 004F). Останавливается после типа данных 0. Параметры пишутся в ParamsArray[32].

.text:00464370 ; int __stdcall WriteResult2Variable(__int16 VariablesCount)

записывает N значений из ParamsArray[32] в переменные, которые идут в SCM. Используется в основном для записи результата (конструкторов).

.text:00463D50 ; int __stdcall GetStringParam(int MoveAddress_ptr,byte MaxStringLength)

тоже что CollectNumberParams только для строковых параметров (строк, строковых переменных).

.text:00465AA0 EndThread

заканчивает поток (опкод 004E)

Offline

#52 25-04-2007 15:39

listener
From: Vice City
Registered: 09-11-2006
Posts: 616
Website

Re: Адреса и функции gta_sa.exe 1.0

2Seemann:
.text:00464080 ; int __stdcall CollectNumberParams(__int16 ParamsNumber)
.text:00464370 ; int __stdcall WriteResult2Variable(__int16 VariablesCount)

У меня они сначала назывались примерно так же. Потом я решил их унифицировать и обозвал их
CScriptThread::loadNumberParams и CScriptThread::storeNumberParams.

Обсуждабельно, но хотелось бы прийти к какому-нибудь унифицированному наименованию.

.text:00464DA0 ; int __cdecl j_SetJumpLocation(int JumpLocation)
У меня CScriptThread::goto. Опять-таки, обсуждабельно.

Была идея называть подобные методы opЧтоТо (она, соответственно, была opJump).

.text:00464790 ; int __cdecl GetVariablePos(int VarType)
До этой я пока не добрался.

.text:004859D0 ; int __stdcall SetConditionResult(boolean ConditionResult)
Предполагаtncz CScriptThread::storeConditionResult (для унификации с storeNumberParams).

.text:00464500 ; int __stdcall GetThreadExtraParams(int *NewThreadStruct)
Угу. А это как раз то, над чем я задумался. Параметром должен, по идее, передаваться CScriptThread * newThread.

Что касается того, что он заполняет. У меня это обозвано tls (Thread Local Storage) - по аналогии с "реальными потоками". Массив там 34 элемента, два последних - таймеры. Если есть лучшие идеи - переобзову.

.text:00463D50 ; int __stdcall GetStringParam(int MoveAddress_ptr,byte MaxStringLength)
Опять же, по аналогии - CScriptThread::loadStringParam (хотелось бы договориться о какой-то паре слов для обзывания этих функций: либо get/put, либо load/store, чтобы, в дальнейшем, не было разногласий. IMHO, load/store чуть логичнее, но, по большому счету, мне без разницы).

.text:00465AA0 EndThread
Если нет возражений, CScriptThread::terminate - два Thread в одном имени - слегка нелогично.

Еще немного:

.text:00463CA0     ; int __stdcall CScriptThread__localPtr(int idx)
Возвращает указатель на локальную переменную по указанному индексу.

.text:00463CC0     ; int __stdcall CScriptThread__localArrayPtr(int off,__int16 idx,char mul)
Возвращает указатель на элемент массива в локальных переменных. Параметры - смещение первого элемента массива, индекс в массива и размер элемента.
Возможно, правильнее будет CScriptThread::getLocalArrayPtr - но как-то длинно получается.

.text:00463CF0     ; int __stdcall CScriptThread__getArrayIndex(int move,__int16 *pOff,__int32 *pIdx)
Получить смещение первого элемента массива и индекс в нем из параметра.

.text:00464250     ; int __cdecl CScriptThread__peekNumber()
Получить следующий numberParam, не перемещая instructionPointer потока.

.text:004648E0     ; void __cdecl CScriptThread__init()
Проинициализировать поля объекта. (начальная инициализация)

Есть еще несколько методов, но они пока еще окончательно не оформлены.

Offline

#53 25-04-2007 15:51

listener
From: Vice City
Registered: 09-11-2006
Posts: 616
Website

Re: Адреса и функции gta_sa.exe 1.0

class CScriptThread {  // только поля, без методов
  CScriptThread * prev;          // _f00:    предыдущий поток в очереди исполнения
  CScriptThread * next;          // _f04:    следующий поток в очереди исполнения
  char            threadName[8]; // _f08: имя потока (8 символов, включая завершающий \0)
  u32             _f10;          // _f10:
  u08           * ip;            // _f14: instruction pointer - указатель на текущий обрабатываемый байт 
  u32             stack[8];      // _f18: стек (для возвратов из процедур)
  u16             sp;            // _f38: stack pointer - текущий элемент стека (индекс)
  u16             _f3A;          // _f3A:
  u32             tls[34];       // _f3C: thread local storage - локальные переменные потока (два последних элемента - таймеры)
  u08             _fC4;          // _fC4:
  u08             _fC5;          // _fC5:
  u08             _fC6;          // _fC6:
  u08             _fC7;          // _fC7:
  u08             _fC8;          // _fC8:
  u08             _fC9;          // _fC9:
  u08             _fCA;          // _fCA:
  u08             _fCB;          // _fCB:
  u32             wakeTime;      // _fCC: время пробуждения потока (используется для команды WAIT)
  u16             _fD0;          // _fD0:
  u08             _fD2;          // _fD2:
  u08             _fD3;          // _fD3:
  u08             _fD4;          // _fD4:
  u08             _fD5;          // _fD5:
  u16             _fD6;          // _fD6:
  u32             _fD8;          // _fD8:
  u08             _fDC;          // _fDC: 0 - в качестве локальных переменных используется TLS, 1 - используется scriptLocals
  u08             pad[3];        // заглушка для выравнивания
};

Размер структуры - 240 байт. Поля, относящиеся к логическим операциям, найдены, но еще не поименованы.
Сами структуры размещаются в:

.data:00A8B430 ; CScriptThread scriptThreads[96];
.data:00A8B430     _scriptThreads  CScriptThread 60h dup(<?>)

Перед ними, в 0xA8B428 и 0xA8B42С находятся два указателя, один из них (пока не ясно, какой), указывает на активный поток. Для чего нужен другой - я пока не понял, возможно, это очередь неактивных потоков. Разберу подробно старт/завершения потока - будет ясно.

Last edited by listener (25-04-2007 15:57)

Offline

#54 25-04-2007 16:00

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Адреса и функции gta_sa.exe 1.0

00000000 THREAD              struc ; (sizeof=0xE0)
00000000 @Active               dd ?
00000004 @Inactive               dd ?
00000008 Name                dd 2 dup(?)
00000010 BaseIP              dd ?
00000014 CurrentIP           dd ?
00000018 ReturnStack         dd 8 dup(?)
00000038 StackCounter        dw ?
0000003A field_3A            dw ?
0000003C LocalVars           dd 32 dup(?)
000000BC TimerA              dd ?
000000C0 TimerB              dd ?
000000C4 _isThreadActive     db ?
000000C5 IF_result           db ?
000000C6 __mission_cleanup   db ?
000000C7 ExternalFlag        db ?
000000C8 InMenu              db ?
000000C9 UnknownScriptAssigned db ?
000000CA field_CA            dw ?
000000CC wakeup_time         dd ?
000000D0 if_Number           dw ?
000000D2 not_flag            db ?
000000D3 WBcheckFlag         db ?
000000D4 isWastedOrBusted    db ?
000000D5 field_D5            db ?
000000D6 field_D6            db ?
000000D7 field_D7            db ?
000000D8 SkipScenePos        dd ?
000000DC MissionFlag         db ?
000000DD field_DD            db ?
000000DE field_DE            dw ?
000000E0 THREAD              ends

первые 2 поля указатели на след. активный (используется при парсинге потоков при переходе от одного к другому), и след. пустой (используется при создании нового потока).

Offline

#55 25-04-2007 16:12

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Адреса и функции gta_sa.exe 1.0

У меня CScriptThread::goto.

скорее CScriptThread::SetIP

хотелось бы договориться о какой-то паре слов для обзывания этих функций: либо

get/put, либо load/store

мне нравится пара Get/Set smile Хотя значения особого не имеет.


Еще есть процедура, связанная с потоками:

.text:00464D40 j_CreateThreadFromStartScm

Создает поток с базой 0xA49960 (т.е. с начала main.scm). Этот поток запускается всегда при начале новой игры (загрузке). Именно благодаря нему создается игрок (CLEO2 тоже запускается из этого потока). Стартовый поток заканчивается после первого wait.

Last edited by Seemann (25-04-2007 16:33)

Offline

#56 25-04-2007 17:00

listener
From: Vice City
Registered: 09-11-2006
Posts: 616
Website

Re: Адреса и функции gta_sa.exe 1.0

первые 2 поля указатели на след. активный (используется при парсинге потоков при переходе от одного к другому), и след. пустой (используется при создании нового потока).

Проверил еще раз. У меня получается четко, что потоки собираются в двусвязный список, и это указатели на предыдущий и следующий элемент списка (возможно, я их перепутал между собой, но это малокритично).

Есть две очереди: активных и неактивных потоков.
.data:00A8B428     ; CScriptThread *inactiveThreadQueue
.data:00A8B42C     ; CScriptThread *activeThreadQueue

.text:00464C00     ; int __stdcall CScriptThread__addToQueue(CScriptThread **queue)
.text:00464BD0     ; int __stdcall CScriptThread__removeFromQueue(CScriptThread **queue)

По коду получается так.

В 004E: end_thread получается:

.... // сбрасывается какой-то флаг

removeFromQueue (&activeThreadQueue);
addToQueue (&inactiveThreadQueue);
endThread (); // да, terminate в качестве названия этой функции подойдет не очень - если не писать явно this->, не ясно, кого терминировать 
return true;

Last edited by listener (25-04-2007 17:01)

Offline

#57 25-04-2007 17:40

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Адреса и функции gta_sa.exe 1.0

У меня получается четко, что потоки собираются в двусвязный список, и это указатели на предыдущий и следующий элемент списка (возможно, я их перепутал между собой, но это малокритично).

да, у меня тоже сначала эти поля называлиcь @Next, @Prev.

сбрасывается какой-то флаг

.text:004667DB                     mov al, [esi+THREAD.MissionFlag]
.text:004667E1                     test al, al
.text:004667E3                     jz  short _not_mission
.text:004667E5                     mov ds:bContinueMission, 0
.text:004667EC
.text:004667EC _not_mission:
.text:004667EC                     push offset @ActiveThread

не помню уже почему назвал bContinueMission

Offline

#58 26-04-2007 12:14

listener
From: Vice City
Registered: 09-11-2006
Posts: 616
Website

Re: Адреса и функции gta_sa.exe 1.0

Все-таки _f0 - next, а _f4 - prev.

// >> 464BD0 - исключить поток из очереди
void CScriptThread::removeFromQueue (CScriptThread ** queue) {
	if (prev)
		prev->next = next;
	else 
		*queue = next;
	if (next)
		next->prev = prev;
}

// >> 464C00 - добавить поток в очередь
void CScriptThread::addToQueue(CScriptThread **queue) {
	next = *queue;
	prev = NULL;
	if (next)
		next->prev = this;
	*queue = this;
}

PS. А на gtaforums народ радостно публикует адрес WinMain ... Жуть какая. Зарегистриться там что-ли и закинуть не только адрес, но и весь декомпилированный WinMain...
Я, кстати, ни из чего найденного не делаю секрета, так что, если кто-нибудь закинет туда что-нибудь из накопанного - я буду только рад.
PPS. Кстати, какие-нибудь C++ - ные куски нужны? А то у меня их уже уже килобайт сто получается.

Offline

#59 26-04-2007 13:50

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Адреса и функции gta_sa.exe 1.0

Зарегистриться там что-ли и закинуть не только адрес, но и весь декомпилированный WinMain...

ты бы лучше сразу сюда добавлял http://www.gtamodding.com/index.php?tit … _Addresses smile

Кстати, какие-нибудь C++ - ные куски нужны?

выкладывай, могут пригодиться (лучше наверно в текстовом файле, чтобы простыней не постить).

Offline

#60 27-04-2007 17:51

listener
From: Vice City
Registered: 09-11-2006
Posts: 616
Website

Re: Адреса и функции gta_sa.exe 1.0

Seemann wrote:

выкладывай, могут пригодиться (лучше наверно в текстовом файле, чтобы простыней не постить).

Ну, постить такие куски в форум - это техномазохизм какой-то получается.

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

А пока, вот что полностью разобрано по CScriptThread:

// >> 463CA0 получить указатель на локальную переменную (с учетом того, используется TLS или нет)
inline u32 * localPtr (u32 idx) { return (_fDC ? scriptLocals : tls)+idx; }

// >> 464700 получить смещение в scmBlock следующего операнда (типы 2, 7) 
// т.е., возвращается не операнд, а только его смещение в scmBlock
u32 getGlobalOffset ();

// >> 463CC0 получить индексированный указатель на локальную переменную (с учетом того, используется TLS или нет)
inline u32 * localArrayPtr (u32 off, u16 idx, u08 mul) { return (_fDC ? scriptLocals : tls)+off+idx*mul;	}

// >> 463CF0 получить индекс и смещение для индексированного операнда. Первый параметр - выполнять переход к следующему байту или нет
void getArrayIndex (bool move, u16 * off, u32 * idx);

void getNumberParams (u16 count);	// >> 464080 получить числовые параметры команды
void getStringParam (char * ptr, u32 len); // >> 463D50 получить строковый параметр команды

u32 peekNumber ();	// >> 464250 получить числовой операнд по текущему IP. IP не меняется

void setNumberParams (u16 count); // >> 464370 записать числовые значения (из opcodeParams в указанные переменные (т.е., indirect значения невозможны))

void getThreadParams (CScriptThread * thread); // >> 464500 получить набор переменных для TLS создаваемого потока

void init ();	// >> 4648E0 - проинициализировать объект

void removeFromQueue (CScriptThread ** queue); // >> 464BD0 - исключить поток из очереди
void addToQueue (CScriptThread ** queue);	// >> 464C00 - добавить поток в очередь

// >> 464C20 - взять поток из очереди неактивных потоков, проинициализировать и добавить в очередь активных потоков
static CScriptThread * allocThread (u08 * startIP);	
// >> 464C90 - аналогично предыдущему, только указывается индекс объекта в scriptThreads (проверяется, что он находится в inactiveThreadQueue)
static CScriptThread * allocThreadByIndex (u08 * startIP, u32 index);

void * getPointerParam (); // >> 464790 

void setIP (s32 newIP); // 464DA0 - перейти к указанному адресу

Дальше можно, прикола ради и проверки для, вкомпилить это в DLL и попробовать подменить то, что в exe-шнике.

Offline

#61 27-04-2007 21:10

Capushon
Registered: 13-08-2006
Posts: 350
Website

Re: Адреса и функции gta_sa.exe 1.0

2Seemann:
2listener:
Нельзя ли в exe'шник встроить что-то типа эксепшинхендлера, чтобы при падении игры можно было увидеть хоть какую-нибудь информацию о причинах, или место скрипта где произошел баг ???

ps: Это резко снизило бы кол-во багов в разных модах...


Сначала ты надежда и гордость,
Потом о спину ломают аршин. (c)БГ

Offline

#62 28-04-2007 02:21

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Адреса и функции gta_sa.exe 1.0

2Capushon:
дык, это... CLEO2 + ScmLog. Берутся с http://cleo.sannybuilder.com

Offline

#63 28-04-2007 08:54

Sanchez
Registered: 18-08-2006
Posts: 280

Re: Адреса и функции gta_sa.exe 1.0

2listener:
2Seemann:
Выложите структуру CPlayer и CWanted, если такая имеется.

Last edited by Sanchez (28-04-2007 08:55)

Offline

#64 28-04-2007 09:41

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Адреса и функции gta_sa.exe 1.0

CPlayer
CWanted

у меня, к сожалению, больше этого нет.

Offline

#65 30-04-2007 15:03

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Адреса и функции gta_sa.exe 1.0

2listener:
Есть идеи как при старте игры пропустить главное меню и сразу начать новую игру?

Пробовал 2 способа:
1. занопить строки в 0x0053E799, 0x00576C34, 0x576C41

глюк: в игре по понятной причине не открывается меню

2. заменить в 00748C90

mov ds:dwLoadingStage, 7
на
mov ds:dwLoadingStage, 8

глюк: если в игре выбрать новую игру - вылетает.

Offline

#66 01-05-2007 16:21

Alexander
Registered: 19-08-2006
Posts: 184
Website

Re: Адреса и функции gta_sa.exe 1.0

2. заменить в 00748C90

mov ds:dwLoadingStage, 7
на
mov ds:dwLoadingStage, 8

глюк: если в игре выбрать новую игру - вылетает.

Так в САМП сделали , тоже новая игра не запускается ...

Offline

#67 14-06-2007 09:47

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Адреса и функции gta_sa.exe 1.0

База listener'а по его же компактному gta_sa.exe.

[You must login to view hidden text.]

Must have для всех кто интересуется устройством игры. Надеюсь, мы еще увидим обновление для этого. wink

Offline

#68 15-06-2007 12:54

listener
From: Vice City
Registered: 09-11-2006
Posts: 616
Website

Re: Адреса и функции gta_sa.exe 1.0

2Seemann:
Я сам на это надеюсь - но, сейчас нет ни времени, ни сил. (Лето, сезон отпусков, работать приходится за шестерых)

Offline

#69 15-06-2007 15:37

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Адреса и функции gta_sa.exe 1.0

2listener:
Рад вновь видеть тебя smile Надеюсь время у тебя появится и ты нас еще чем-нибудь порадуешь.
Если можешь, ответь пожалуйста на пост 66 в этой теме.

Offline

#70 21-07-2007 11:51

San'OK
Registered: 22-06-2007
Posts: 7

Re: Адреса и функции gta_sa.exe 1.0

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

В ходе разработки своей программы 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%

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

Last edited by San'OK (21-07-2007 11:54)

Offline

#71 21-07-2007 12:35

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Адреса и функции gta_sa.exe 1.0

Некоторую информацию по SA SFX можно почерпнуть отсюда:

http://www.gtaforums.com/index.php?showtopic=225049
http://pdescobar.home.comcast.net/gta/saat/sfx_dir.html

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

За описания процедур спасибо. Насчет плагина еще обсудим wink

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

Last edited by Seemann (21-07-2007 14:41)

Offline

#72 21-07-2007 18:26

San'OK
Registered: 22-06-2007
Posts: 7

Re: Адреса и функции gta_sa.exe 1.0

На закуску:)

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 что-то подобное сделаю.

Last edited by San'OK (21-07-2007 18:43)

Offline

#73 21-07-2007 18:37

San'OK
Registered: 22-06-2007
Posts: 7

Re: Адреса и функции gta_sa.exe 1.0

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

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
};

Offline

#74 29-07-2007 04:19

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Адреса и функции gta_sa.exe 1.0

Добавил обновленные списки функций. Ссылки в первом посте.

Offline

#75 30-07-2007 14:20

AleX AciD
From: RU-VLG
Registered: 27-02-2007
Posts: 36
Website

Re: Адреса и функции gta_sa.exe 1.0

Вот, немного покопался в новой базе, сравнивая некоторые функции с исходниками RenderWare'вского "скелета":

файл: renderware/skel/skeleton.c
6193F0   RsKeyFromScanCode
619410   RsTimer
619420   RsWindowSetText
619430   RsPathGetSeparator
619440   RsCameraShowRaster
619460   RsAlwaysOnTop
619470   RsRegisterImageLoader
619480   RsSetDebug
619490   RsMouseSetVisibility
6194A0   RsMouseSetPos
6194B0   RsSelectDevice
6194C0   RsInputDeviceAttach
619510   rsCommandLine
619530   rsPreInitCommandLine
619560   RsKeyboardEventHandler
619580   RsMouseEventHandler
6195A0   RsPadEventHandler
6195E0   RsRwTerminate
6195F0   RsTerminate
619600   RsInitialize
619670   RsSetModelTexturePath
619780   RsSetPresetView
619840   RsSetNextPresetView
619880   RsSetPreviousPresetView
6198C0   RsDestroyPresetViews
619910   CameraElAzPosFromLTM
619AB0   RsGetPresetViewDescription
619AF0   RsGrabScreen
619B00   RsErrorMessage
619B30   RsWarningMessage
619C90   RsRwInitialize
619D60   RsLoadPresetViews
619FA0   RsSavePresetView

файл: renderware/skel/win/win.c
7451B0   psWindowSetText   (gta_SetWindowText)
7451D0   psErrorMessage   (_ShowMessageBoxHand)
7451F0   psWarningMessage
745240   psCameraShowRaster
745270   psTimer
7452B0   psGrabScreen
7453E0   psMouseSetVisibility
7453F0   psMouseSetPos
745500   psPathGetSeparator
745540   psDebugMessageHandler
7458A0   psTerminate
7458B0   psAlwaysOnTop
745CC0   dialogInit
746190   psSelectDevice
747420   psInitialize

RW:
802EA0   RwImageSetPath

Несколько переменных:
dword_C1707C   PresetViews
dword_C17080   NumPresetViews
dword_C92104   ClocksStart_msb
dword_C92108   ClocksStart_lsb
array_8D2C00   KeysNormal
array_8D2D00   KeysShifted
struct_8D2E00  Xaxis
struct_8D2E0C  Yaxis
struct_8D2E18  Zaxis
string_8D2E24  ViewsFileName
dword_8D2E30   CurrentPresetView
dword_8D2E34   DefaultVideoMode

PS: в базе RwEngineInstance и RwGlobals представлены как две разных структуры, на самом деле RwEngineInstance это указатель на структуру типа RwGlobals.

PPS: если нужно, могу выложить исходники этого скелетного приложения.:cool:


[large][acronym=Завтра, завтра, постоянно завтра, так проходит жизнь]Cras, cras, semper cras, sic evadit aetas[/acronym][/large]

Offline

Board footer

Powered by FluxBB