You are not logged in.
Немного тряхнул стариной перебрал функцию registerNativeByHash взял за основу CHashtable из базы от listener'a
Получилось несколько сумбурно стихийно, но в целом мне кажется неплохо
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
Хорошо, только goto немного не к месту. 
А вообще, там практически все сделано на template, и, примерно 300К кода сгенерилось компилятором автоматически. (Т.е., в оригинале это был список функций с параметрами).
Принцип работы такой хэш-таблицы я вычитал у Дженкинса (как раз, когда алгоритм хэш функции читал). Если я ничего не путаю, это называется "хэш-таблица с лавинным заполнением".
У меня, в относительно свежем исходнике, это выглядит так:
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;
};А вот маленький кусочек самой регистрации нэйтивов:
// 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;
//....Сами нэйтивы получаются как-то так (несколько самых мелких для примера):
__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
Продолжу тему хэш-таблиц. 
IV использует три разных типа хэш-таблиц, с требя разными алгоритмами хэшей. 
Первый - приведенный выше, в котором используется Jenkins one at time hash. используется для нэутивов и загруженных скриптов.
Второй - массив связных списков. Хэш-функция - ELF hash. Используется как кэш vertex declaration и в парсерах текстовых форматов.
Третий - балансированное дерево в grcResourceCache. Хэш-функция - CRC32. 
Таблица второго типа выглядит так:
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
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
Ув. 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
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
Графические форматы RAGE разобраны процентов на 80 для IV и процентов на 50 для RDR. 
(MC:LA - тоже процентов на 50). Просто большого потока интересующихся не было, и информация перестала выходить за пределы "узкого круга"
Offline
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
Нубский вопро - как получить 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
Но ведь 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
0x9FAC90 void __thiscall CVehicle__doVehicleLights(CVehicle *this, CMatrix *matrix, unsigned int damageStatus)
Ощущается old-GTA стиль 
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
Ну и вот некоторые разобранные (почти 
) структуры
ссылка
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
Хорошо. До катсцен я еще не добирался.
Маленькое замечание: размер rage::Vector3 - не 12, а 16 байт (SSE-aligned)
В паре объектов "лишние" четыре байта используется для хранения даных, но, практически везде, это просто выравнивание.
Пропустил вопрос про FrameDof
DOF = Degree Of Freedom
короче, на первый взгляд, это ограничения для инверсной кинематики. 
Они у меня были слегка разобраны, если надо - попробую поискать
Offline
listener
Исследовал вот эту процедуру
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;
}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 процедуры
getVector getFloat
которые работают с этим dof.
PS Какой обьект возвращает CAnimManager__getAnimByName? Он есть в базе?
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
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
Хотел бы спросить, что такое
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
@DK22Pac - DC == Display Command.
Т.е., несколько упрощая, по ходу обработки, они набираются в очередь и потом отрисовываются все пачкой. CBaseDC - базовый класс  для всех DC, а Execute - метод, непосредственно выполняющий команду.
Offline
В паблике не так давно появилась замечательная база EFLC http://public.sannybuilder.com/gtasa_ex … 141007.rar
А для GTA IV 1.0.7 имеется подобная?
Offline