#26 18-05-2010 01:37

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

Re: Ресурсы и структуры GTA IV

2listener:

Где был бы моддинг SA, если бы не было sannybuilder?

Юзали бы старенький Mission Builder by Barton Waterduck  wink


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

Offline

#27 23-07-2011 20:53

VoLT
Registered: 05-08-2009
Posts: 4

Re: Ресурсы и структуры GTA IV

Немного тряхнул стариной перебрал функцию registerNativeByHash взял за основу CHashtable из базы от listener'a
Получилось несколько сумбурно стихийно, но в целом мне кажется неплохо

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
struct CHashData
{
  int hash;
  int addr;
};
 
struct CHashtable // 0x01865954 in EFLC
{
  CHashData *m_pData;
  int m_nSize;
  int m_nRequestedSize;
  int m_nCount;
};
 
CHashtable Hashtable;
 
char __stdcall registerNativeByHash(unsigned int a1, int a2)
{
  int v2; // edi@1
  unsigned int v4; // edx@5
  unsigned int v5; // ecx@5
  unsigned int v6; // eax@5
 
  v2 = Hashtable.m_nSize;
  if ( !Hashtable.m_nSize )
  {
    sub_4CF3D0();
    v2 = Hashtable.m_nSize;
  }
  if ( Hashtable.m_nCount == v2 )
    return 0;
  v4 = a1 % v2;
  v5 = a1;
  v6 = Hashtable.m_pData[a1 % v2].hash;
  if ( v6 > 1 )
  {
    while ( v6 != a1 )
    {
      v5 = (v5 >> 1) + 1;
      v4 = (v5 + v4) % v2;
      v6 = Hashtable.m_pData[v4].hash;
      if ( v6 <= 1 )
        goto LABEL_8;
    }
    return 0;
  }
LABEL_8:
  Hashtable.m_pData[v4].hash = a1;
  Hashtable.m_pData[v4].addr = a2;
  ++Hashtable.m_nCount;
  return 1;
}

Last edited by VoLT (23-07-2011 21:08)

Offline

#28 23-07-2011 21:15

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

Re: Ресурсы и структуры GTA IV

Хорошо, только goto немного не к месту.
А вообще, там практически все сделано на template, и, примерно 300К кода сгенерилось компилятором автоматически. (Т.е., в оригинале это был список функций с параметрами).

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

У меня, в относительно свежем исходнике, это выглядит так:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
template <class T> class scrHashtable {
public:
    struct Pair {
        DWORD   dwKey;
        T       item;
    };
 
    __inline T operator[] (const DWORD dwKey) {
        if (!m_dwAllocatedSize) return NULL;
        DWORD i = dwKey % m_dwAllocatedSize;
        DWORD h = dwKey;
        while (m_pData[i].dwKey != dwKey) {
            if (!m_pData[i].dwKey)  return NULL;
            h = (h >> 1)+1;
            i = (i+h) % m_dwAllocatedSize;
        }
        return m_pData[i].item;
    }
 
    bool insert (DWORD dwKey, T item) {
        if (m_dwAllocatedSize == m_dwCount)
            return false;   // table full
 
        DWORD i = dwKey%m_dwAllocatedSize;
        DWORD h = dwKey;            // R9
 
        while (m_pData[i].dwKey > 1) {
            if (m_pData[i].dwKey == dwKey) {
                trace ("FATAL: native $%x is already registered\n", dwKey);
                exit (0);
                return false;   // already present
            }
            h = (h >> 1)+1;
            i = (i+h) % m_dwAllocatedSize;     
        }
 
        m_pData[i].dwKey = dwKey;
        m_pData[i].item = item;
        m_dwCount++;
        return true;
    }   
 
    Pair *  m_pData;
    DWORD   m_dwAllocatedSize;
    DWORD   m_dwInitialSize;
    DWORD   m_dwCount;
};

А вот маленький кусочек самой регистрации нэйтивов:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Native: no args, no return value
template <DWORD K, void (*F)()> class Native {
public:
    Native () { scrVM::ms_natives->insert (K, invoke); }
    static void __cdecl invoke (NativeParam&) { F(); }
};
 
// ....
 
// Native 2 args, return value
template <DWORD K, typename R, typename A1, typename A2, R (*F)(A1, A2)> class NativeR2{
public:
    NativeR2 () { scrVM::ms_natives->insert (K, invoke); }
    static void __cdecl invoke (NativeParam& p) { p.pRet[0] = F (p.pArgs[0], p.pArgs[1]); }
};
 
// ...
 
void scrVM::registerSystemNatives () {
    NativeR <0x75706300, int, TIMERA> _TIMERA;
    NativeR <0x62984AB7, int, TIMERB> _TIMERB;
    NativeR <0x1BF55D6F, int, TIMERC> _TIMERC;
    Native1 <0x32501B1E, int, SETTIMERA> _SETTIMERA;
    Native1 <0x3B4C2E2E, int, SETTIMERB> _SETTIMERB;
    Native1 <0x499852DB, int, SETTIMERC> _SETTIMERC;
//....

Сами нэйтивы получаются как-то так (несколько самых мелких для примера):

1
2
3
4
__inline int TIMERA () { return scrThread::getRunningThread()->m_context.nTimerA; }  // $75706300
__inline void SETTIMERA (int n) { scrThread::getRunningThread ()->m_context.nTimerA = n; }  // $32501B1E
__inline DWORD SHIFT_LEFT (DWORD d, DWORD s) { return d << s; } // $102A0A6C
__inline DWORD SHIFT_RIGHT (DWORD d, DWORD s) { return d >> s; }// $64DD173C

Offline

#29 25-07-2011 21:29

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

Re: Ресурсы и структуры GTA IV

Продолжу тему хэш-таблиц.
IV использует три разных типа хэш-таблиц, с требя разными алгоритмами хэшей.
Первый - приведенный выше, в котором используется Jenkins one at time hash. используется для нэутивов и загруженных скриптов.
Второй - массив связных списков. Хэш-функция - ELF hash. Используется как кэш vertex declaration и в парсерах текстовых форматов.
Третий - балансированное дерево в grcResourceCache. Хэш-функция - CRC32.

Таблица второго типа выглядит так:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
template<typename T> class atHashtable {
protected:
    struct Entry {       
        // ... здесь были конструктор и деструктор ...
        const char *    pszKey; // TODO: use sysString
        T               item;
        Entry *         pNext;
    };
 
public:
   // ... какое-то количество кода пропущено ...
 
    T* at (const char * pszKey) const {
        if (!wSize) return *NULL;
        DWORD dwIndex = sysHashElf (pszKey);
        while (Entry * p = pItems[dwIndex]; p; p = p->pNext)
            if (!strcmp (pszKey, p->pszKey))
                return &(p->item);
        return NULL;
    }
 
    // в отличие от atArray, здесь сначала идет wSize, а потом wCount
    Entry** pData;  // +0 array of linked lists of Entry
    WORD    wSize;  // +4 allocated size
    WORD    wCount; // +6 number of used items
    WORD    _f8;
    BYTE    _fA;
    BYTE    bInitialized;   // +B
};

Offline

#30 05-12-2011 21:12

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Ресурсы и структуры GTA IV

0x1202800 - в базе listener'а (1.0.4) - старт CPickups?
0x8DF0C0 - destroyPickup?


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#31 13-12-2011 16:48

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Ресурсы и структуры GTA IV

Ув. listener, будете ли обновлять базу по IV?)


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#32 13-12-2011 23:29

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

Re: Ресурсы и структуры GTA IV

Основная обновляемая база - EfLC 1.1.2.0
Увы, последние два месяца, на новой работе так напрягают, что я уже забыл, когда послений раз в дизассемблер залезал

Offline

#33 25-12-2011 14:17

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Ресурсы и структуры GTA IV

listener, а что насчёт построения моделей в IV, как например в RW - Clump>Frame>Atomic. Может известны уже какие-то структуры?


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#34 25-12-2011 16:44

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

Re: Ресурсы и структуры GTA IV

Графические форматы RAGE разобраны процентов на 80 для IV и процентов на 50 для RDR.
(MC:LA - тоже процентов на 50). Просто большого потока интересующихся не было, и информация перестала выходить за пределы "узкого круга"

Offline

#35 30-01-2012 13:32

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Ресурсы и структуры GTA IV

listener, спасибо)

Last edited by DK22Pac (08-02-2012 21:45)


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#36 08-02-2012 21:43

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Ресурсы и структуры GTA IV

Нубский вопро - как получить SkeletonData, если есть CEntity?

Last edited by DK22Pac (09-02-2012 00:00)


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#37 09-02-2012 00:11

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

Re: Ресурсы и структуры GTA IV

В ModelInfo есть указатель на drawable

Если не понятно, как получить modelinfo из entity - позже найду пример.

Offline

#38 09-02-2012 00:23

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Ресурсы и структуры GTA IV

Но ведь modelInfo - общий для всех Entity с этой моделью?
Мне нужно для конкретного субьекта найти.

Ещё один вопрос. frag - это материальный компонент? Как rpAtomic?

Last edited by DK22Pac (09-02-2012 01:20)


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#39 15-04-2012 19:00

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Ресурсы и структуры GTA IV

1
0x9FAC90 void __thiscall CVehicle__doVehicleLights(CVehicle *this, CMatrix *matrix, unsigned int damageStatus)

Ощущается old-GTA стиль lol

1
2
0x9063E0 int __thiscall CHeli__preRender(CHeli *this)
0x4E53F0 int __thiscall CVehicle__getBone(CVehicle *vehicle, int boneID)

PS что-то hex-rays кидает все операции с регистрами xm в __asm{}, может это исправили в новых версиях?

UP
listener, если будет время, пожалуйста, обьясните, что это:
crFrameDofVector3
crFrameDofFloat

Last edited by DK22Pac (18-04-2012 14:19)


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#40 29-04-2012 11:28

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Ресурсы и структуры GTA IV

Ну и вот некоторые разобранные (почти cool) структуры
ссылка

Last edited by DK22Pac (29-04-2012 11:28)


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#41 29-04-2012 12:26

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

Re: Ресурсы и структуры GTA IV

Хорошо. До катсцен я еще не добирался.
Маленькое замечание: размер rage::Vector3 - не 12, а 16 байт (SSE-aligned)
В паре объектов "лишние" четыре байта используется для хранения даных, но, практически везде, это просто выравнивание.

Пропустил вопрос про FrameDof
DOF = Degree Of Freedom
короче, на первый взгляд, это ограничения для инверсной кинематики.
Они у меня были слегка разобраны, если надо - попробую поискать

Offline

#42 03-05-2012 10:24

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Ресурсы и структуры GTA IV

listener
Исследовал вот эту процедуру

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
CCutsceneSection *__cdecl CCutscenes::createLights(int fParam)
{
  CCutsceneSection *_pSection; // eax@1
  CCutsceneLight *light; // esi@3
  int v5; // edi@5
  Vector4 *pOffset; // eax@5
  Vector4 *vecLightCutsPos; // edx@5
  float lightPosY; // xmm0_4@5
  float lightPosZ; // xmm1_4@5
  float lightPosX; // xmm2_4@5
  int pSection; // eax@5
  int _section; // eax@5
  int flags; // [sp-14h] [bp-B8h]@6
  Vector4 *pLightDirection; // [sp-10h] [bp-B4h]@6
  Vector4 *pShadowDirection; // [sp-Ch] [bp-B0h]@6
  int pLightPos; // [sp-8h] [bp-ACh]@6
  int pRGBA; // [sp-4h] [bp-A8h]@6
  float _range; // [sp+0h] [bp-A4h]@6
  int zero; // [sp+4h] [bp-A0h]@6
  int wtd; // [sp+8h] [bp-9Ch]@6
  float _intensity1; // [sp+Ch] [bp-98h]@6
  float halfIntensity; // [sp+10h] [bp-94h]@6
  float _intensity2; // [sp+14h] [bp-90h]@6
  int minusOne; // [sp+18h] [bp-8Ch]@6
  int _minusOne; // [sp+1Ch] [bp-88h]@6
  int pCutsceneLight; // [sp+20h] [bp-84h]@6
  float intensity2; // [sp+34h] [bp-70h]@5
  float intensity1; // [sp+38h] [bp-6Ch]@5
  float range; // [sp+3Ch] [bp-68h]@4
  int i; // [sp+40h] [bp-64h]@2
  Vector4 shadowDirection; // [sp+44h] [bp-60h]@4
  Vector4 lightDirection; // [sp+54h] [bp-50h]@5
  Vector4 _lightPos; // [sp+64h] [bp-40h]@5
  int RGB; // [sp+74h] [bp-30h]@5
  int buf1[4]; // [sp+84h] [bp-20h]@5
  int buf2[4]; // [sp+94h] [bp-10h]@5
 
  _pSection = cutsceneSections[_dwCutscenePlayState];
  if ( _pSection )
  {
    i = 0;
    if ( _pSection->numLights > 0 )
    {
      light = 0xF930;
      do
      {
        LODWORD(shadowDirection.x) = 0;
        LODWORD(shadowDirection.y) = fOne;
        LODWORD(shadowDirection.z) = 0;
        range = getFloatParam(*(&_pSection->offset.x + light), 0x8Cu, fParam);
        __asm { lahf }
        if ( __SETP__(_AH & 0x44, 0) )
        {
          getVector(*(&light->anim + cutsceneSections[_dwCutscenePlayState]), buf1, 0, fParam);
          v5 = _dwCutscenePlayState;
          pOffset = CCutscenes__getOffset(buf2, _dwCutscenePlayState);
          lightPosY = vecLightCutsPos->y + pOffset->y;
          lightPosZ = vecLightCutsPos->z + pOffset->z;
          lightPosX = vecLightCutsPos->x + pOffset->x;
          pSection = cutsceneSections[v5];
          _lightPos.x = lightPosX;
          _lightPos.y = lightPosY;
          _lightPos.z = lightPosZ;
          getVector(*(&light->anim + pSection), &lightDirection, 0x8Fu, fParam);
          getVector(*(&light->anim + cutsceneSections[_dwCutscenePlayState]), &RGB, 0x8Bu, fParam);
          intensity1 = getFloatParam(*(&light->anim + cutsceneSections[_dwCutscenePlayState]), 0x8Du, fParam);
          intensity2 = getFloatParam(*(&light->anim + cutsceneSections[_dwCutscenePlayState]), 0x8Eu, fParam);
          _section = cutsceneSections[_dwCutscenePlayState];
          shadowDirection.x = lightDirection.y;
          shadowDirection.y = lightDirection.z;
          LODWORD(shadowDirection.z) = lightDirection.x;
          if ( strncmp("shd", &light->name[cutsceneSections[_dwCutscenePlayState]]) )
          {
            pCutsceneLight = (light + cutsceneSections[_dwCutscenePlayState]);
            _minusOne = -1;
            minusOne = -1;
            _intensity2 = intensity2;
            halfIntensity = intensity2 * 0.5;
            _intensity1 = intensity1;
            wtd = LightOcclWTDindex;
            zero = 0;
            _range = range;
            pRGBA = &RGB;
            pLightPos = &_lightPos;
            pShadowDirection = &shadowDirection;
            pLightDirection = &lightDirection;
            flags = 0x184u;
          }
          else
          {
            pCutsceneLight = 0;
            _minusOne = -1;
            minusOne = -1;
            _intensity2 = intensity2;
            halfIntensity = intensity2 * 0.5;
            _intensity1 = intensity1;
            if ( strncmp("env", &light->name[_section]) )
            {
              wtd = LightOcclWTDindex;
              zero = 0;
              _range = range;
              pRGBA = &RGB;
              pLightPos = &_lightPos;
              pShadowDirection = &shadowDirection;
              pLightDirection = &lightDirection;
              flags = 0x180u;
            }
            else
            {
              wtd = LightOcclWTDindex;
              zero = 0;
              _range = range;
              pRGBA = &RGB;
              pLightPos = &_lightPos;
              pShadowDirection = &shadowDirection;
              pLightDirection = &lightDirection;
              flags = 0x80u;
            }
          }
          _registerLight( v5, 0, 2, flags, pLightDirection, pShadowDirection, pLightPos, pRGBA, _range, zero, wtd, _intensity1, halfIntensity, _intensity2, minusOne, _minusOne, pCutsceneLight);
        }
        _pSection = cutsceneSections[_dwCutscenePlayState];
        ++light;
        ++i;
      }
      while ( i < _pSection->numLights );
    }
  }
  return _pSection;
}
1
2
3
4
5
0x872810     ; CCutsceneSection *__cdecl CCutscenes__createLights(float fParam)
0x872410     ; int __cdecl CCutscenes__getOffset(Vector4 *vector, int sectionID)
0xC68F80     ; double __thiscall getFloatParam(void *this, char ?offset, int ?time)
0xC68EA0     ; Vector4 *__thiscall getVector(void *_CCutsceneLight, Vector4 *pResultVector, char ?offset, unsigned int ?time)
0xF26F84     ; int LightOcclWTDindex

Тут присутсвуют 2 процедуры

1
2
getVector
getFloat

которые работают с этим dof.

PS Какой обьект возвращает CAnimManager__getAnimByName? Он есть в базе?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CCamAnimated    struc ; (sizeof=0x1BC)
0x000 cam             CCam
0x140 fState1         dd ; 0.0 - 1.0
0x144 fField_144      dd ?
0x148 virtual_getCurrentCutsceneTime dd
0x14C AnimIndex       dd
0x150 cameraAnimNameHash dd
0x154 field_154       dd
0x158 field_158       dd
0x15C field_15C       dd
0x160 cutsceneOffset  Vector4
0x170 cameraAnimName  db 32
0x190 WADname         db 32
0x1B0 field_1B0       db
0x1B1 field_1B1       db
0x1B2 field_1B2       db
0x1B3 field_1B3       db
0x1B4 fState2         dd
0x1B8 field_1B8       dd
1
2
3
CVehicle +0xFD8 m_pDoorData
CVehicle +0xFDC m_nDoorsCount
CAutomobile +0x1DC0 CAutomobileDoor[6]

Last edited by DK22Pac (04-05-2012 13:36)


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#43 30-07-2012 23:57

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Ресурсы и структуры GTA IV

Хотел бы спросить, что такое

1
2
CBaseDC
CBaseDC::Execute

Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#44 01-08-2012 20:10

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

Re: Ресурсы и структуры GTA IV

@DK22Pac - DC == Display Command.
Т.е., несколько упрощая, по ходу обработки, они набираются в очередь и потом отрисовываются все пачкой. CBaseDC - базовый класс  для всех DC, а Execute - метод, непосредственно выполняющий команду.

Offline

#45 05-04-2015 15:04

Sergey81
Registered: 19-12-2008
Posts: 654

Re: Ресурсы и структуры GTA IV

В паблике не так давно появилась замечательная база EFLC http://public.sannybuilder.com/gtasa_ex … 141007.rar
А для GTA IV 1.0.7 имеется подобная?

Offline

#46 09-04-2015 18:43

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

Re: Ресурсы и структуры GTA IV

Не имеется. И даже не в паблике.
Просто, я занимался EfLC 1.1.2, который отличается буквально парой объектов.
А вести параллельно две базы - у меня просто сил не хватает

Offline

Board footer

Powered by FluxBB