Загрузка данных


/* CFileSystem::CFileSystem(char const*) */

void __thiscall CFileSystem::CFileSystem(CFileSystem *this,char *param_1)

{
  if (param_1 == (char *)0x0) {
    *(char **)this = "data.pak";
    *(undefined4 *)(this + 0x14) = 0;
    *(undefined4 *)(this + 0x10) = 0;
    return;
  }
  *(char **)this = param_1;
  *(undefined4 *)(this + 0x14) = 0;
  *(undefined4 *)(this + 0x10) = 0;
  return;
}


/* CFileSystem::getResSize(unsigned int) */

undefined4 __thiscall CFileSystem::getResSize(CFileSystem *this,uint param_1)

{
  return *(undefined4 *)(*(int *)(this + 0x14) + param_1 * 0x10 + 8);
}


/* CFileSystem::calcFileIdCode(unsigned char*) */

int __thiscall CFileSystem::calcFileIdCode(CFileSystem *this,uchar *param_1)

{
  int iVar1;
  uint uVar2;
  uint uVar3;
  int iVar4;
  
  uVar2 = (uint)*param_1;
  if (uVar2 == 0) {
    iVar1 = 0x12345678;
  }
  else {
    iVar1 = 0x12345678;
    uVar3 = 1;
    do {
      iVar4 = uVar3 * uVar2;
      uVar2 = (uint)param_1[uVar3];
      iVar1 = iVar1 + (iVar4 << ((uVar3 & 3) << 3));
      uVar3 = uVar3 + 1;
    } while (uVar2 != 0);
  }
  return iVar1;
}


/* CFileSystem::getIdFromName(unsigned char*) */

int __thiscall CFileSystem::getIdFromName(CFileSystem *this,uchar *param_1)

{
  int iVar1;
  int iVar2;
  
  iVar1 = calcFileIdCode(this,param_1);
  if ((*(int *)(this + 8) != 0) && (*(int *)(this + 0x14) != 0)) {
    iVar2 = 0;
    do {
      if (iVar1 == *(int *)(*(int *)(this + 0x14) + iVar2 * 0x10)) {
        return iVar2;
      }
      iVar2 = iVar2 + 1;
    } while (iVar2 != *(int *)(this + 8));
  }
  return -1;
}



/* CFileSystem::getResSize(unsigned char*) */

undefined4 __thiscall CFileSystem::getResSize(CFileSystem *this,uchar *param_1)

{
  int iVar1;
  undefined4 uVar2;
  
  iVar1 = getIdFromName(this,param_1);
  if (iVar1 == -1) {
    uVar2 = 0;
  }
  else {
    uVar2 = *(undefined4 *)(*(int *)(this + 0x14) + iVar1 * 0x10 + 8);
  }
  return uVar2;
}


/* CFileSystem::enableXorCoding() */

void __thiscall CFileSystem::enableXorCoding(CFileSystem *this)

{
  **(undefined4 **)(this + 0x10) = 0xaa;
  return;
}



/* CFileSystem::disableXorCoding() */

void __thiscall CFileSystem::disableXorCoding(CFileSystem *this)

{
  **(undefined4 **)(this + 0x10) = 0;
  return;
}


/* CFileSystem::saveFile(unsigned char*, unsigned char*, unsigned int) */

void __thiscall CFileSystem::saveFile(CFileSystem *this,uchar *param_1,uchar *param_2,uint param_3)

{
  CFileManager::save(*(CFileManager **)(this + 0x10),param_1,param_2,param_3);
  return;
}


/* CFileSystem::loadFileInMemory(unsigned char*, unsigned char*) */

void __thiscall CFileSystem::loadFileInMemory(CFileSystem *this,uchar *param_1,uchar *param_2)

{
  CFileManager::loadInMemory(*(CFileManager **)(this + 0x10),param_1,param_2);
  return;
}


/* CFileSystem::loadExternalAndCustomMalloc(char*) */

uchar * __thiscall CFileSystem::loadExternalAndCustomMalloc(CFileSystem *this,char *param_1)

{
  int iVar1;
  uchar *puVar2;
  CFileManager *this_00;
  
  iVar1 = CFileManager::getSize(*(CFileManager **)(this + 0x10),(uchar *)param_1);
  puVar2 = (uchar *)0x0;
  if (iVar1 != 0) {
    iVar1 = CFileManager::getSize(*(CFileManager **)(this + 0x10),(uchar *)param_1);
    puVar2 = (uchar *)__allocCustomHeap(iVar1);
    this_00 = *(CFileManager **)(this + 0x10);
    *(undefined4 *)this_00 = 0;
    CFileManager::loadInMemory(this_00,(uchar *)param_1,puVar2);
    **(undefined4 **)(this + 0x10) = 0xaa;
  }
  return puVar2;
}

void __thiscall CImp::CImp(CImp *this)

{
  char cVar1;
  uint uVar2;
  CImp *pCVar3;
  uint uVar4;
  
  uVar4 = 0;
  pCVar3 = this + 0x7438;
  do {
    cVar1 = '\b';
    uVar2 = uVar4;
    do {
      cVar1 = cVar1 + -1;
      if ((uVar2 & 1) == 0) {
        uVar2 = uVar2 >> 1;
      }
      else {
        uVar2 = uVar2 >> 1 ^ 0xedb88320;
      }
    } while (cVar1 != '\0');
    pCVar3 = pCVar3 + 4;
    *(uint *)pCVar3 = uVar2;
    uVar4 = uVar4 + 1;
  } while (uVar4 != 0x100);
  *(undefined4 *)(this + 0x52f0) = 0x2a;
  *(undefined4 *)(this + 0x52fc) = 0x120;
  *(undefined4 *)(this + 0x52f4) = 0xe;
  *(undefined4 *)(this + 0x5300) = 0x14a;
  *(undefined4 *)(this + 0x52f8) = 0x1c;
  *(undefined4 *)(this + 0x5304) = 0x158;
  *(undefined4 *)(this + 0x8874) = 0;
  *(undefined4 *)(this + 0x8860) = 0;
  *(undefined4 *)(this + 0x8870) = 0;
  return;
}


/* CImp::block_crc(void*, int, unsigned int) */

uint __thiscall CImp::block_crc(CImp *this,void *param_1,int param_2,uint param_3)

{
  byte *pbVar1;
  byte *pbVar2;
  
  pbVar2 = param_1;
  if (param_1 < (byte *)((int)param_1 + param_2)) {
    do {
      pbVar1 = pbVar2 + 1;
      param_3 = *(uint *)(this + (((param_3 ^ *pbVar2) & 0xff) + 0x1d00) * 4 + 0x3c) ^ param_3 >> 8;
      pbVar2 = pbVar1;
    } while (pbVar1 != (byte *)((int)param_1 + param_2));
  }
  return param_3;
}


/* CImp::get_uint16(void*) */

int __thiscall CImp::get_uint16(CImp *this,void *param_1)

{
  return (uint)*(byte *)param_1 + (uint)*(byte *)((int)param_1 + 1) * 0x100;
}


/* CImp::init_getbits() */

void __thiscall CImp::init_getbits(CImp *this)

{
  *(undefined4 *)(this + 0x7430) = 0;
  *(CImp **)(this + 0x7310) = this + 0x7318;
  *(CImp **)(this + 0x7314) = this + 0x7318;
  *(undefined4 *)(this + 0x7428) = 0;
  *(undefined4 *)(this + 0x7858) = 0;
  return;
}


/* CImp::getbits(int) */

int __thiscall CImp::getbits(CImp *this,int param_1)

{
  CImp CVar1;
  int iVar2;
  undefined4 uVar3;
  int iVar4;
  CImp *pCVar5;
  CImp *pCVar6;
  CImp *pCVar7;
  
  if ((*(int *)(this + 0x7428) < param_1) && (*(int *)(this + 0x7428) < 0x19)) {
    pCVar5 = *(CImp **)(this + 0x7310);
    pCVar7 = this + 0x7318;
    do {
      pCVar6 = pCVar5;
      if ((*(CImp **)(this + 0x7314) <= pCVar5) &&
         (*(CImp **)(this + 0x7310) = pCVar7, pCVar6 = pCVar7, *(int *)(this + 0x7430) == 0)) {
        iVar2 = vFILE::fread(*(vFILE **)(this + 0x8870),pCVar7,1,0x100);
        *(CImp **)(this + 0x7314) = this + iVar2 + 0x7318;
        uVar3 = vFILE::veof(*(vFILE **)(this + 0x8870));
        pCVar6 = *(CImp **)(this + 0x7310);
        *(undefined4 *)(this + 0x7430) = uVar3;
      }
      pCVar5 = pCVar6 + 1;
      CVar1 = *pCVar6;
      *(CImp **)(this + 0x7310) = pCVar5;
      iVar4 = *(uint *)(this + 0x7428) + 8;
      iVar2 = *(int *)(this + 0x7858) + ((uint)(byte)CVar1 << (*(uint *)(this + 0x7428) & 0xff));
      *(int *)(this + 0x7858) = iVar2;
      *(int *)(this + 0x7428) = iVar4;
    } while (iVar4 < 0x19);
    return iVar2;
  }
  return *(int *)(this + 0x7858);
}


/* CImp::make_codes(unsigned int*, unsigned char*, int) */

void __thiscall CImp::make_codes(CImp *this,uint *param_1,uchar *param_2,int param_3)

{
  byte *pbVar1;
  uint uVar2;
  uint uVar3;
  uint *puVar4;
  int iVar5;
  int *piVar6;
  int iVar7;
  int iVar8;
  uint uVar9;
  uint auStack_98 [16];
  int aiStack_58 [18];
  
  puVar4 = auStack_98;
  piVar6 = aiStack_58;
  do {
    piVar6 = piVar6 + 1;
    *piVar6 = 0;
  } while (piVar6 != aiStack_58 + 0x11);
  if (param_3 != 0) {
    iVar7 = 0;
    do {
      pbVar1 = param_2 + iVar7;
      iVar7 = iVar7 + 1;
      aiStack_58[*pbVar1 + 1] = aiStack_58[*pbVar1 + 1] + 1;
    } while (iVar7 != param_3);
  }
  iVar7 = 0;
  aiStack_58[1] = 0;
  iVar5 = 0;
  iVar8 = 0;
  while( true ) {
    iVar7 = (iVar7 + iVar5) * 2;
    puVar4 = puVar4 + 1;
    *puVar4 = iVar7;
    if (iVar8 + 4 == 0x40) break;
    iVar5 = *(int *)((int)aiStack_58 + iVar8 + 8);
    iVar8 = iVar8 + 4;
  }
  if (param_3 != 0) {
    iVar7 = 0;
    do {
      uVar2 = (uint)param_2[iVar7];
      if (uVar2 != 0) {
        uVar9 = auStack_98[uVar2];
        uVar3 = 0;
        auStack_98[uVar2] = uVar9 + 1;
        do {
          uVar2 = uVar2 - 1;
          uVar3 = (uVar9 & 1) + uVar3 * 2;
          uVar9 = uVar9 >> 1;
        } while (uVar2 != 0);
        param_1[iVar7] = uVar3;
      }
      iVar7 = iVar7 + 1;
    } while (iVar7 != param_3);
  }
  return;
}


/* CImp::make_decode_tables(int*, int (*) [2], unsigned int*, unsigned char*, int, int) */

undefined4 __thiscall
CImp::make_decode_tables
          (CImp *this,int *param_1,int *param_2,uint *param_3,uchar *param_4,int param_5,int param_6
          )

{
  uint uVar1;
  int *piVar2;
  int iVar3;
  int iVar4;
  int iVar5;
  uint uVar6;
  uint uVar7;
  int iVar8;
  uint uVar9;
  int iVar10;
  int iVar11;
  
  uVar1 = 1 << (param_5 & 0xffU);
  if ((param_2 != (int *)0x0) && (0 < param_6)) {
    iVar5 = 0;
    piVar2 = param_2;
    do {
      iVar5 = iVar5 + 1;
      piVar2[1] = -0x120;
      *piVar2 = -0x120;
      piVar2 = piVar2 + 2;
    } while (iVar5 != param_6);
  }
  if (0 < (int)uVar1) {
    uVar6 = 0;
    piVar2 = param_1;
    do {
      uVar6 = uVar6 + 1;
      *piVar2 = -0x120;
      piVar2 = piVar2 + 1;
    } while (uVar6 != uVar1);
  }
  if (0 < param_6) {
    iVar5 = 1;
    iVar11 = 0;
    do {
      while (uVar6 = (uint)param_4[iVar11], uVar6 != 0) {
        uVar9 = 1 << uVar6;
        uVar7 = param_3[iVar11];
        if (uVar9 <= uVar1) {
          if (uVar7 < uVar1) {
            iVar8 = uVar9 + uVar7;
            piVar2 = param_1 + uVar7;
            do {
              iVar8 = iVar8 + uVar9;
              *piVar2 = iVar11;
              piVar2 = piVar2 + uVar9;
            } while (iVar8 - uVar9 < uVar1);
          }
          break;
        }
        if (param_2 == (int *)0x0) break;
        uVar9 = uVar1 - 1 & uVar7;
        iVar3 = param_1[uVar9];
        iVar8 = (uVar6 - 1) - param_5;
        uVar7 = uVar7 >> (param_5 & 0xffU);
        if (iVar3 == -0x120) {
          param_1[uVar9] = -iVar5;
          iVar3 = iVar5;
          iVar5 = iVar5 + 1;
        }
        else {
          iVar4 = param_2[iVar3 * -2 + (uVar7 & 1)];
          iVar3 = -iVar3;
          while (iVar10 = iVar4, -1 < iVar10) {
            uVar7 = uVar7 >> 1;
            iVar8 = iVar8 + -1;
            iVar3 = iVar10;
            iVar4 = param_2[iVar10 * 2 + (uVar7 & 1)];
          }
        }
        if (iVar8 != 0) {
          if (param_6 == iVar5) {
            return 0xfffffffd;
          }
          iVar4 = iVar3;
          iVar3 = iVar5;
          while( true ) {
            param_2[iVar4 * 2 + (uVar7 & 1)] = iVar3;
            uVar7 = uVar7 >> 1;
            if (iVar3 == iVar5 + iVar8 + -1) break;
            iVar10 = iVar3 + 1;
            iVar4 = iVar3;
            iVar3 = iVar10;
            if (iVar10 == param_6) {
              return 0xfffffffd;
            }
          }
          iVar5 = iVar3 + 1;
        }
        iVar8 = -iVar11;
        iVar11 = iVar11 + 1;
        param_2[iVar3 * 2 + (uVar7 & 1)] = iVar8;
        if (iVar11 == param_6) {
          return 0;
        }
      }
      iVar11 = iVar11 + 1;
    } while (iVar11 != param_6);
  }
  return 0;
}


/* CImp::reverse_mm(unsigned char*, int) */

void __thiscall CImp::reverse_mm(CImp *this,uchar *param_1,int param_2)

{
  bool bVar1;
  uint uVar2;
  uint uVar3;
  uchar *puVar4;
  uchar *puVar5;
  int iVar6;
  CImp *pCVar7;
  uchar *unaff_r10;
  int iVar8;
  uchar *puVar9;
  
  iVar8 = *(int *)(this + 0x742c);
  if (0 < iVar8) {
    iVar6 = 1;
    pCVar7 = this + 0x785c;
    do {
      uVar3 = *(uint *)(pCVar7 + 4);
      uVar2 = uVar3 >> 0x18;
      if (uVar2 != 0) {
        if (iVar6 + -1 < iVar8 + -1) {
          unaff_r10 = *(uchar **)(pCVar7 + 8);
        }
        puVar4 = param_1 + (uVar3 & 0xffffff);
        uVar3 = param_2;
        if (iVar6 + -1 < iVar8 + -1) {
          uVar3 = (uint)unaff_r10 & 0xffffff;
        }
        unaff_r10 = param_1 + uVar3;
        if (puVar4 < unaff_r10) {
          puVar9 = puVar4 + -uVar2;
          do {
            puVar5 = puVar4 + 1;
            *puVar4 = *puVar9 + *puVar4;
            puVar4 = puVar5;
            puVar9 = puVar9 + 1;
          } while (puVar5 != unaff_r10);
        }
      }
      iVar8 = *(int *)(this + 0x742c);
      bVar1 = iVar6 < iVar8;
      iVar6 = iVar6 + 1;
      pCVar7 = pCVar7 + 4;
    } while (bVar1);
  }
  return;
}


/* CImp::redo_mm(unsigned int) */

void __thiscall CImp::redo_mm(CImp *this,uint param_1)

{
  uint uVar1;
  char *pcVar2;
  char *pcVar3;
  char *pcVar4;
  char *pcVar5;
  uint uVar6;
  char *pcVar7;
  int iVar8;
  CImp *pCVar9;
  bool bVar10;
  
  pcVar5 = *(char **)(this + 0x730c);
  if (pcVar5 <= pcVar5 + (*(int *)(this + 0x7850) - param_1)) {
    pcVar5 = pcVar5 + (*(int *)(this + 0x7850) - param_1);
  }
  iVar8 = *(int *)(this + 0x742c) + -1;
  if (-1 < iVar8) {
    pCVar9 = this + (*(int *)(this + 0x742c) + 0x1e18) * 4;
    do {
      uVar6 = *(uint *)(pCVar9 + -4);
      uVar1 = uVar6 >> 0x18;
      if (uVar1 != 0) {
        pcVar7 = (char *)(*(int *)(this + 0x730c) + (uVar6 & 0xffffff));
        if (pcVar7 < pcVar5) {
          pcVar7 = pcVar5;
        }
        uVar6 = *(uint *)(this + 0x7850);
        if (iVar8 < *(int *)(this + 0x742c) + -1) {
          uVar6 = *(uint *)pCVar9 & 0xffffff;
        }
        pcVar3 = (char *)(*(int *)(this + 0x730c) + uVar6);
        if (pcVar7 <= pcVar3 + -1) {
          pcVar4 = pcVar3 + -uVar1;
          do {
            pcVar4 = pcVar4 + -1;
            pcVar2 = pcVar3 + -1;
            pcVar3 = pcVar3 + -1;
            *pcVar3 = *pcVar2 - *pcVar4;
          } while (pcVar3 != pcVar7);
        }
        if (pcVar7 <= pcVar5) {
          return;
        }
      }
      bVar10 = iVar8 != 0;
      iVar8 = iVar8 + -1;
      pCVar9 = pCVar9 + -4;
    } while (bVar10);
  }
  return;
}


/* CImp::e8ut_crc_wr16(CImp::vFILE*, unsigned char*, int, unsigned int) */

int __thiscall
CImp::e8ut_crc_wr16(CImp *this,vFILE *param_1,uchar *param_2,int param_3,uint param_4)

{
  byte bVar1;
  int iVar2;
  uint uVar3;
  byte *pbVar4;
  undefined1 *puVar5;
  CImp *pCVar7;
  byte *pbVar8;
  int iVar9;
  byte *pbVar10;
  CImp *pCVar6;
  
  pbVar8 = param_2 + param_3;
  pCVar7 = this + 0x650;
  if (param_2 < pbVar8) {
    iVar9 = param_4 - (int)param_2;
    do {
      pCVar6 = pCVar7;
      pbVar10 = pbVar8;
      if (0x3ffd < (uint)((int)pbVar8 - (int)param_2)) {
        pbVar10 = param_2 + 0x3ffd;
      }
      while (param_2 < pbVar10) {
        bVar1 = *param_2;
        pbVar4 = param_2;
        while( true ) {
          param_2 = pbVar4 + 1;
          puVar5 = &pCVar6->field_0x1;
          *(byte *)pCVar6 = bVar1;
          *(uint *)&this[0x26bd].field_0x1 =
               *(uint *)((int)this +
                        ((((uint)bVar1 ^ *(uint *)&this[0x26bd].field_0x1) & 0xff) + 0x1d00) * 4 +
                        0x3c) ^ *(uint *)&this[0x26bd].field_0x1 >> 8;
          if (bVar1 == 0xe8) break;
          if (param_2 == pbVar10) {
            iVar2 = vFILE::fwrite(param_1,pCVar7,1,(int)puVar5 - (int)pCVar7);
            if (iVar2 < (int)puVar5 - (int)pCVar7) {
              return -6;
            }
            goto LAB_0003bf04;
          }
          bVar1 = *param_2;
          pCVar6 = (CImp *)puVar5;
          pbVar4 = param_2;
        }
        iVar2 = get_uint16(this,param_2);
        iVar2 = iVar2 - ((uint)(param_2 + iVar9) & 0xffff);
        *puVar5 = (char)iVar2;
        pCVar6->field_0x2 = (char)((uint)iVar2 >> 8);
        uVar3 = *(uint *)((int)this +
                         ((((uint)(byte)*puVar5 ^ *(uint *)&this[0x26bd].field_0x1) & 0xff) + 0x1d00
                         ) * 4 + 0x3c) ^ *(uint *)&this[0x26bd].field_0x1 >> 8;
        *(uint *)&this[0x26bd].field_0x1 = uVar3;
        *(uint *)&this[0x26bd].field_0x1 =
             *(uint *)((int)this + (((uVar3 ^ (byte)pCVar6->field_0x2) & 0xff) + 0x1d00) * 4 + 0x3c)
             ^ uVar3 >> 8;
        pCVar6 = pCVar6 + 1;
        param_2 = pbVar4 + 3;
      }
      iVar2 = vFILE::fwrite(param_1,pCVar7,1,(int)pCVar6 - (int)pCVar7);
      if (iVar2 < (int)pCVar6 - (int)pCVar7) {
        return -6;
      }
LAB_0003bf04:
    } while (param_2 < pbVar8);
  }
  return (int)param_2 - (int)pbVar8;
}


/* CImp::e8ut_crc_wr32(CImp::vFILE*, unsigned char*, int, unsigned int, unsigned int) */

int __thiscall
CImp::e8ut_crc_wr32(CImp *this,vFILE *param_1,uchar *param_2,int param_3,uint param_4,uint param_5)

{
  byte bVar1;
  uint uVar2;
  int iVar3;
  uint uVar4;
  byte *pbVar5;
  byte *pbVar6;
  CImp *pCVar8;
  CImp *pCVar9;
  CImp *pCVar10;
  byte *pbVar11;
  byte *pbVar7;
  
  pbVar5 = param_2 + param_3;
  pbVar11 = pbVar5;
  if (0x3ffb < (uint)param_3) {
    pbVar11 = param_2 + 0x3ffb;
  }
  pCVar10 = this + 0x650;
  pbVar6 = param_2;
  if (param_2 < pbVar11) {
    do {
      if (0x3ffb < (uint)((int)pbVar11 - (int)pbVar6)) {
        pbVar11 = pbVar6 + 0x3ffb;
      }
      pbVar7 = pbVar6;
      pCVar8 = pCVar10;
      pCVar9 = pCVar10;
      if (pbVar6 < pbVar11) {
        do {
          while( true ) {
            pbVar6 = pbVar7 + 1;
            bVar1 = *pbVar7;
            pCVar9 = (CImp *)&pCVar8->field_0x1;
            *(byte *)pCVar8 = bVar1;
            *(uint *)&this[0x26bd].field_0x1 =
                 *(uint *)((int)this +
                          ((((uint)bVar1 ^ *(uint *)&this[0x26bd].field_0x1) & 0xff) + 0x1d00) * 4 +
                          0x3c) ^ *(uint *)&this[0x26bd].field_0x1 >> 8;
            if (bVar1 != 0xe8) break;
            uVar2 = get_uint32(this,pbVar6);
            pbVar6 = pbVar6 + (param_4 - (int)param_2);
            if (((int)uVar2 < 0) && (-(int)pbVar6 <= (int)uVar2)) {
              uVar2 = ((param_5 - 1) - uVar2) - (int)pbVar6;
            }
            else if (uVar2 < param_5) {
              uVar2 = uVar2 - (int)pbVar6;
            }
            pbVar6 = pbVar7 + 5;
            iVar3 = 0;
            do {
              uVar4 = uVar2 & 0xff;
              *(char *)((int)pCVar9 + iVar3) = (char)uVar2;
              iVar3 = iVar3 + 1;
              uVar2 = (int)uVar2 >> 8;
              *(uint *)&this[0x26bd].field_0x1 =
                   *(uint *)((int)this +
                            (((uVar4 ^ *(uint *)&this[0x26bd].field_0x1) & 0xff) + 0x1d00) * 4 +
                            0x3c) ^ *(uint *)&this[0x26bd].field_0x1 >> 8;
            } while (iVar3 != 4);
            pCVar9 = pCVar8 + 1;
            pbVar7 = pbVar6;
            pCVar8 = (CImp *)&pCVar9->field_0x2;
            pCVar9 = (CImp *)&pCVar9->field_0x2;
            if (pbVar11 <= pbVar6) goto LAB_0003c08c;
          }
          pbVar7 = pbVar6;
          pCVar8 = pCVar9;
        } while (pbVar6 != pbVar11);
      }
LAB_0003c08c:
      iVar3 = vFILE::fwrite(param_1,pCVar10,1,(int)pCVar9 - (int)pCVar10);
      if (iVar3 < (int)pCVar9 - (int)pCVar10) {
        return -6;
      }
      pbVar11 = pbVar5;
    } while (pbVar6 < pbVar5);
  }
  return (int)pbVar6 - (int)pbVar11;
}


/* my_memchr(char*, char, unsigned int) */

byte * my_memchr(char *param_1,char param_2,uint param_3)

{
  byte *pbVar1;
  
  if (param_3 != 0) {
    if ((uint)(byte)*param_1 == (int)param_2) {
      return (byte *)param_1;
    }
    pbVar1 = (byte *)(param_1 + param_3);
    while (param_1 = param_1 + 1, (byte *)param_1 != pbVar1) {
      if ((uint)(byte)*param_1 == (int)param_2) {
        return (byte *)param_1;
      }
    }
  }
  return (byte *)0x0;
}


/* CImp::find_start() */

undefined4 __thiscall CImp::find_start(CImp *this)

{
  char *pcVar1;
  int iVar2;
  int iVar3;
  char *pcVar4;
  
  vFILE::fseek(*(vFILE **)&this[0x2d7a].field_0x2,0,2);
  pcVar1 = (char *)__allocCustomHeap(0x8000);
  if (pcVar1 == (char *)0x0) {
    return 0xfffffff6;
  }
  iVar2 = vFILE::fread(*(vFILE **)&this[0x2d7a].field_0x2,pcVar1,1,0x8000);
  if (0x29 < iVar2) {
    *(undefined4 *)&this[0x2d75].field_0x1 = 0;
    pcVar4 = pcVar1;
    while( true ) {
      iVar3 = my_memchr(pcVar4,'I',(int)(pcVar1 + iVar2 + -0x29) - (int)pcVar4);
      if (iVar3 == 0) {
        return 0xfffffffe;
      }
      pcVar4 = (char *)(iVar3 + 1);
      if (((*(char *)(iVar3 + 1) == 'M') && (*(char *)(iVar3 + 2) == 'P')) &&
         (*(char *)(iVar3 + 3) == '\n')) break;
      if (pcVar1 + iVar2 + -0x29 <= pcVar4) {
        return 0xfffffffe;
      }
    }
    *(int *)&this[0x2d75].field_0x1 = iVar3 - (int)pcVar1;
    __freeCustomHeap(pcVar1);
    return 0;
  }
  __freeCustomHeap(pcVar1);
  return 0xfffffffe;
}


/* CImp::e8ut_crc_write(CImp::vFILE*, unsigned char*, int, unsigned int, unsigned int, int) */

int __thiscall
CImp::e8ut_crc_write
          (CImp *this,vFILE *param_1,uchar *param_2,int param_3,uint param_4,uint param_5,
          int param_6)

{
  int iVar1;
  uint uVar2;
  int iVar3;
  byte *pbVar4;
  size_t __n;
  uint uVar5;
  byte *pbVar6;
  byte *__src;
  byte *pbVar7;
  
  iVar1 = *(int *)&this[0x2d76].field_0x2;
  if (iVar1 != 0) {
    if ((int)(8U - iVar1) <= param_3) {
      memcpy(&this[0x26b2].field_0x2 + iVar1,param_2,8U - iVar1);
      if (*(int *)&this[0x26b5].field_0x1 == 2) {
        iVar3 = e8ut_crc_wr16(this,param_1,&this[0x26b2].field_0x2,*(int *)&this[0x2d76].field_0x2,
                              param_4 - *(int *)&this[0x2d76].field_0x2);
      }
      else {
        iVar3 = e8ut_crc_wr32(this,param_1,&this[0x26b2].field_0x2,*(int *)&this[0x2d76].field_0x2,
                              param_4 - *(int *)&this[0x2d76].field_0x2,param_5);
      }
      if (iVar3 < 0) {
        return iVar3;
      }
      iVar1 = *(int *)&this[0x26b5].field_0x1;
      param_3 = param_3 - iVar3;
      param_2 = param_2 + iVar3;
      param_4 = param_4 + iVar3;
      goto joined_r0x0003c2a8;
    }
    memcpy(&this[0x26b2].field_0x2 + iVar1,param_2,param_3);
    param_2 = &this[0x26b2].field_0x2;
    param_4 = param_4 - *(int *)&this[0x2d76].field_0x2;
    param_3 = param_3 + *(int *)&this[0x2d76].field_0x2;
  }
  iVar1 = *(int *)&this[0x26b5].field_0x1;
joined_r0x0003c2a8:
  if (iVar1 == 2) {
    iVar1 = e8ut_crc_wr16(this,param_1,param_2,param_3 + -2,param_4);
  }
  else {
    iVar1 = e8ut_crc_wr32(this,param_1,param_2,param_3 - iVar1,param_4,param_5);
  }
  if (-1 < iVar1) {
    pbVar7 = param_2 + param_3;
    uVar2 = iVar1 - *(int *)&this[0x26b5].field_0x1;
    pbVar4 = pbVar7 + uVar2;
    __src = pbVar4;
    if (CARRY4((uint)pbVar7,uVar2)) {
      uVar2 = (uint)pbVar7[uVar2];
      if (param_6 != 0 || uVar2 != 0xe8) {
        uVar5 = *(uint *)&this[0x26bd].field_0x1;
        pbVar6 = pbVar4;
        do {
          pbVar6 = pbVar6 + 1;
          uVar5 = *(uint *)((int)this + (((uVar2 ^ uVar5) & 0xff) + 0x1d00) * 4 + 0x3c) ^ uVar5 >> 8
          ;
          *(uint *)&this[0x26bd].field_0x1 = uVar5;
          __src = pbVar7;
          if (pbVar6 == pbVar7) break;
          uVar2 = (uint)*pbVar6;
          __src = pbVar6;
        } while (uVar2 != 0xe8 || param_6 != 0);
        if ((pbVar4 < __src) &&
           (iVar1 = vFILE::fwrite(param_1,pbVar4,1,(int)__src - (int)pbVar4),
           iVar1 < (int)__src - (int)pbVar4)) {
          return -6;
        }
      }
    }
    __n = (int)pbVar7 - (int)__src;
    *(size_t *)&this[0x2d76].field_0x2 = __n;
    if (__n == 0) {
      iVar1 = 0;
    }
    else {
      memmove(&this[0x26b2].field_0x2,__src,__n);
      iVar1 = 0;
    }
  }
  return iVar1;
}


/* CImp::expand_lz(unsigned char*, int, int, int) */

void __thiscall CImp::expand_lz(CImp *this,uchar *param_1,int param_2,int param_3,int param_4)

{
  byte bVar1;
  byte bVar2;
  byte bVar3;
  undefined1 uVar4;
  char cVar5;
  uint uVar6;
  int iVar7;
  uchar *puVar8;
  uint uVar9;
  char cVar10;
  uchar *puVar11;
  char cVar12;
  int iVar13;
  uint uVar14;
  uint uVar15;
  undefined1 *puVar16;
  char *pcVar17;
  int *piVar18;
  uint *puVar19;
  uchar *puVar20;
  uchar *puVar21;
  int iVar22;
  uchar *puVar23;
  char cVar24;
  int iVar25;
  int iVar26;
  uint local_e64;
  uint local_e3c;
  uint local_e38;
  int aiStack_e2c [512];
  uint auStack_62c [288];
  uint local_1ac [14];
  byte abStack_172 [20];
  byte abStack_15e [20];
  byte abStack_14a [46];
  int local_11c [34];
  byte abStack_92 [6];
  undefined4 local_8c;
  undefined1 local_68 [20];
  char local_54 [20];
  undefined4 local_40;
  int local_2c [2];
  
  local_2c[0] = __stack_chk_guard;
  if (param_4 != 0) {
    *(undefined4 *)&this[0x26b9].field_0x1 = 0;
  }
  uVar6 = getbits(this,2);
  iVar13 = *(int *)(this + 0x26b8);
  uVar6 = uVar6 & 3;
  *(uint *)&this[0x281d].field_0x1 = *(uint *)&this[0x281d].field_0x1 >> 2;
  *(int *)(this + 0x26b8) = iVar13 + -2;
  if (uVar6 == 0) {
    iVar13 = -3;
  }
  else {
    local_e64 = getbits(this,6);
    iVar13 = *(int *)(this + 0x26b8);
    if (2 < uVar6) {
      iVar25 = 0x174;
    }
    else {
      iVar25 = 0x158;
    }
    local_e64 = local_e64 & 0x3f;
    *(uint *)&this[0x281d].field_0x1 = *(uint *)&this[0x281d].field_0x1 >> 6;
    if (local_e64 == 0) {
      iVar7 = 0x158;
    }
    else {
      iVar7 = iVar25 * local_e64;
    }
    *(int *)(this + 0x26b8) = iVar13 + -6;
    puVar8 = (uchar *)__allocCustomHeap(iVar7);
    if (puVar8 == (uchar *)0x0) {
      iVar13 = -10;
    }
    else {
      iVar13 = load_hcodes(this,puVar8,iVar25,local_e64,param_3 + param_2);
      if (iVar13 < 0) {
        __freeCustomHeap(puVar8);
      }
      else {
        piVar18 = (int *)(local_54 + 0x14);
        cVar10 = '\v';
        cVar12 = '\x02';
        do {
          cVar24 = cVar12 + cVar10 + cVar12;
          cVar5 = cVar24 + cVar12;
          *(char *)piVar18 = cVar10;
          *(char *)((int)piVar18 + 1) = cVar12 + cVar10;
          *(char *)((int)piVar18 + 2) = cVar24;
          *(char *)((int)piVar18 + 3) = cVar5;
          piVar18 = piVar18 + 1;
          cVar10 = cVar5 + cVar12;
          cVar12 = cVar12 << 1;
        } while (piVar18 != local_2c);
        puVar16 = local_68;
        iVar13 = 1;
        do {
          uVar4 = (undefined1)iVar13;
          iVar13 = iVar13 + 1;
          puVar16[3] = uVar4;
          *puVar16 = uVar4;
          puVar16[1] = uVar4;
          puVar16[2] = uVar4;
          puVar16 = puVar16 + 4;
        } while (iVar13 != 6);
        pcVar17 = local_54;
        cVar12 = '\x01';
        do {
          pcVar17[3] = cVar12;
          *pcVar17 = cVar12;
          pcVar17[1] = cVar12;
          pcVar17[2] = cVar12;
          pcVar17 = pcVar17 + 4;
          cVar12 = cVar12 * '\x02' + '\x01';
        } while (pcVar17 != local_54 + 0x14);
        piVar18 = local_11c;
        iVar7 = 5;
        iVar13 = 2;
        do {
          *piVar18 = iVar7;
          piVar18[1] = iVar7 + iVar13;
          piVar18 = piVar18 + 2;
          iVar7 = iVar7 + iVar13 + iVar13;
          iVar13 = iVar13 << 1;
        } while (piVar18 != &local_8c);
        puVar16 = (undefined1 *)((int)&local_8c + 1);
        iVar13 = 1;
        do {
          uVar4 = (undefined1)iVar13;
          iVar13 = iVar13 + 1;
          puVar16[-1] = uVar4;
          *puVar16 = uVar4;
          puVar16 = puVar16 + 2;
        } while (iVar13 != 0x13);
        uVar14 = 1;
        puVar19 = local_1ac + 1;
        do {
          *puVar19 = uVar14;
          puVar19[-1] = uVar14;
          puVar19 = puVar19 + 2;
          uVar14 = uVar14 * 2 + 1;
        } while (puVar19 != (uint *)(local_11c + 1));
        puVar11 = param_1 + param_2;
        puVar20 = puVar11 + param_3;
        if (puVar11 < puVar20) {
          if (local_e64 == 0) {
            local_e64 = 1;
          }
          local_e38 = 0;
          iVar7 = (int)puVar8 + -iVar25;
          local_e3c = 0;
          iVar13 = 0x100;
          do {
            uVar15 = local_e38;
            uVar14 = local_e3c;
            puVar23 = puVar11;
            if (iVar13 == 0x100) {
              if (local_e64 == 0) break;
              puVar21 = (uchar *)(iVar7 + iVar25);
              make_codes(this,auStack_62c,puVar21,0x120);
              make_decode_tables(this,aiStack_e2c,(int *)this,auStack_62c,puVar21,9,0x120);
              puVar21 = puVar21 + 0x120;
              local_e64 = local_e64 - 1;
              iVar13 = 0;
              piVar18 = (int *)&this[0x1ba5].field_0x1;
              do {
                make_codes(this,auStack_62c,puVar21,*piVar18);
                make_decode_tables(this,(int *)((int)this + iVar13 * 0x200 + 0xcf0),
                                   (int *)(this + iVar13 * 0x70 + 0x300),auStack_62c,puVar21,7,
                                   *piVar18);
                iVar13 = iVar13 + 1;
                puVar21 = puVar21 + *piVar18;
                piVar18 = piVar18 + 1;
              } while (iVar13 < (int)uVar6);
              iVar7 = (int)puVar21 + -iVar25;
            }
            uVar9 = getbits(this,9);
            iVar13 = aiStack_e2c[uVar9 & 0x1ff];
            if (iVar13 < 0) {
              if (iVar13 == -0x120) {
LAB_0003d0f4:
                uVar14 = (int)puVar11 - (int)param_1;
              }
              else {
                uVar9 = getbits(this,0x10);
                iVar13 = -iVar13;
                uVar9 = uVar9 >> 9;
                do {
                  iVar13 = *(int *)((int)this + ((uVar9 & 1) + iVar13 * 2) * 4);
                  uVar9 = uVar9 >> 1;
                } while (0 < iVar13);
                if (iVar13 != -0x120) {
                  iVar13 = -iVar13;
                  goto LAB_0003cd34;
                }
LAB_0003d10c:
                uVar14 = (int)puVar11 - (int)param_1;
              }
              goto LAB_0003ce18;
            }
LAB_0003cd34:
            *(uint *)(this + 0x26b8) = *(int *)(this + 0x26b8) - (uint)*(byte *)(iVar7 + iVar13);
            *(uint *)&this[0x281d].field_0x1 =
                 *(uint *)&this[0x281d].field_0x1 >> *(sbyte *)(iVar7 + iVar13);
            if (iVar13 < 0x100) {
              *puVar11 = (uchar)iVar13;
              puVar23 = puVar11 + 1;
            }
            else if (iVar13 != 0x100) {
              if (iVar13 < 0x10a) {
                iVar22 = iVar13 + -0xff;
              }
              else if (iVar13 < 0x11e) {
                uVar9 = getbits(this,5);
                bVar3 = abStack_172[iVar13];
                bVar1 = abStack_15e[iVar13];
                iVar22 = *(int *)(this + 0x26b8);
                bVar2 = abStack_14a[iVar13];
                *(uint *)&this[0x281d].field_0x1 = *(uint *)&this[0x281d].field_0x1 >> (uint)bVar3;
                *(uint *)(this + 0x26b8) = iVar22 - (uint)bVar3;
                iVar22 = (uVar9 & bVar1) + (uint)bVar2;
              }
              else {
                if (iVar13 != 0x11e) {
                  uVar14 = getbits(this,3);
                  iVar22 = *(int *)&this[0x26b9].field_0x1;
                  iVar26 = *(int *)(this + 0x26b8);
                  *(uint *)&this[0x281d].field_0x1 = *(uint *)&this[0x281d].field_0x1 >> 3;
                  *(uint *)((int)this + (iVar22 + 0x1e18) * 4) =
                       (int)puVar11 - (int)param_1 | (uVar14 & 7) << 0x18;
                  *(int *)&this[0x26b9].field_0x1 = iVar22 + 1;
                  *(int *)(this + 0x26b8) = iVar26 + -3;
                  goto LAB_0003cdf8;
                }
                uVar9 = getbits(this,0xf);
                iVar13 = *(int *)(this + 0x26b8);
                *(uint *)&this[0x281d].field_0x1 = *(uint *)&this[0x281d].field_0x1 >> 0xf;
                *(int *)(this + 0x26b8) = iVar13 + -0xf;
                iVar22 = (uVar9 & 0x7fff) + 0x103;
              }
              if (iVar22 == 3) {
                uVar9 = (uint)(2 < uVar6);
              }
              else {
                uVar9 = 0;
              }
              iVar26 = (uint)(iVar22 == 2) + uVar9 * 2;
              uVar9 = getbits(this,7);
              iVar13 = *(int *)((int)this + ((uVar9 & 0x7f) + iVar26 * 0x80 + 0x33c) * 4);
              if (iVar13 < 0) {
                if (iVar13 == -0x120) goto LAB_0003d0f4;
                uVar9 = getbits(this,0x10);
                uVar9 = uVar9 >> 7;
                iVar13 = -iVar13;
                do {
                  iVar13 = *(int *)((int)this +
                                   ((uVar9 & 1) + (iVar26 * 0x2a + iVar13) * 2 + 0x240) * 4);
                  uVar9 = uVar9 >> 1;
                } while (0 < iVar13);
                if (iVar13 == -0x120) goto LAB_0003d10c;
                iVar13 = -iVar13;
              }
              iVar26 = *(int *)((int)this + (iVar26 + 0x1480) * 4 + 0xfc);
              *(uint *)(this + 0x26b8) =
                   *(int *)(this + 0x26b8) - (uint)*(byte *)(iVar7 + iVar13 + iVar26);
              *(uint *)&this[0x281d].field_0x1 =
                   *(uint *)&this[0x281d].field_0x1 >> *(sbyte *)(iVar7 + iVar13 + iVar26);
              uVar9 = local_e3c;
              if (iVar13 != 0) {
                if (iVar13 == 1) {
                  local_e3c = local_e38;
                  local_e38 = uVar14;
                  uVar9 = uVar15;
                }
                else if (iVar13 < 6) {
                  uVar9 = iVar13 - 1;
                }
                else {
                  uVar14 = getbits(this,0x12);
                  bVar3 = abStack_92[iVar13];
                  uVar15 = local_1ac[iVar13 + -6];
                  iVar26 = local_11c[iVar13 + -6];
                  *(uint *)&this[0x281d].field_0x1 = *(uint *)&this[0x281d].field_0x1 >> (uint)bVar3
                  ;
                  uVar9 = (uVar14 & uVar15) + iVar26;
                  local_e38 = local_e3c;
                  *(uint *)(this + 0x26b8) = *(int *)(this + 0x26b8) - (uint)bVar3;
                  local_e3c = uVar9;
                }
              }
              uVar14 = (int)puVar11 - (int)param_1;
              if ((uVar9 <= uVar14) && (iVar22 != 0)) {
                if (puVar20 <= puVar11) goto LAB_0003ce18;
                iVar26 = 0;
                puVar21 = puVar11;
                while( true ) {
                  puVar23 = puVar21 + 1;
                  *puVar21 = puVar11[iVar26 - uVar9];
                  if (iVar26 == iVar22 + -1) break;
                  iVar26 = iVar26 + 1;
                  puVar21 = puVar23;
                  if (puVar23 == puVar20) {
                    uVar14 = (int)puVar23 - (int)param_1;
                    goto LAB_0003ce18;
                  }
                }
              }
            }
LAB_0003cdf8:
            puVar11 = puVar23;
          } while (puVar23 < puVar20);
          uVar14 = (int)puVar23 - (int)param_1;
        }
        else {
          uVar14 = (int)puVar11 - (int)param_1;
        }
LAB_0003ce18:
        __freeCustomHeap(puVar8);
        if (param_4 != 0) {
          reverse_mm(this,param_1,param_3 + param_2);
        }
        iVar13 = uVar14 - param_2;
      }
    }
  }
  if (local_2c[0] == __stack_chk_guard) {
    return;
  }
                    /* WARNING: Subroutine does not return */
  __stack_chk_fail(iVar13);
}


/* CImp::extract_dir() */

void __thiscall CImp::extract_dir(CImp *this)

{
  int iVar1;
  uint uVar2;
  uint uVar3;
  uint uVar4;
  uint uVar5;
  undefined1 *puVar6;
  int unaff_r9;
  uint uVar7;
  undefined1 auStack_34 [8];
  int local_2c;
  
  local_2c = __stack_chk_guard;
  uVar7 = *(uint *)(*(vFILE **)&this[0x2d7a].field_0x2 + 4);
  vFILE::fseek(*(vFILE **)&this[0x2d7a].field_0x2,*(uint *)(this + 0x2814),2);
  puVar6 = &this[0x1bad].field_0x1;
  *(undefined1 **)(this + 0x2d78) = puVar6;
  *(undefined1 **)&this[0x2d79].field_0x1 = puVar6;
  iVar1 = vFILE::fread(*(vFILE **)&this[0x2d7a].field_0x2,auStack_34,6,1);
  if (iVar1 == 0) {
    unaff_r9 = -5;
  }
  else {
    iVar1 = memcmp(auStack_34,"IMPDE",6);
    if (iVar1 == 0) {
      init_getbits(this);
      uVar2 = getbits(this,5);
      uVar3 = *(uint *)&this[0x281d].field_0x1;
      *(int *)(this + 0x26b8) = *(int *)(this + 0x26b8) + -5;
      *(uint *)&this[0x281d].field_0x1 = uVar3 >> 5;
      if ((uVar2 & 0xf) < 2) {
        uVar3 = getbits(this,0x14);
        uVar4 = *(uint *)&this[0x281d].field_0x1;
        *(int *)(this + 0x26b8) = *(int *)(this + 0x26b8) + -0x14;
        *(uint *)&this[0x281d].field_0x1 = uVar4 >> 0x14;
        if ((uVar3 & 0xfffff) < 0x2001) {
          uVar4 = getbits(this,0x14);
          iVar1 = *(int *)(this + 0x26b8);
          uVar5 = *(uint *)&this[0x281d].field_0x1;
          *(int *)(this + 0x26b8) = iVar1 + -0x14;
          *(uint *)&this[0x281d].field_0x1 = uVar5 >> 0x14;
          if ((uVar2 & 0xf) == 1) {
            *(uint *)&this[0x281d].field_0x1 = uVar5 >> 0x19;
            *(int *)(this + 0x26b8) = iVar1 + -0x19;
            unaff_r9 = expand_lz(this,puVar6,0,uVar3 & 0xfffff,0);
          }
          *(uint *)(this + 0x2814) = *(int *)(this + 0x2814) + 6 + (uVar4 & 0xfffff);
          vFILE::fseek(*(vFILE **)&this[0x2d7a].field_0x2,uVar7,2);
          if (-1 < unaff_r9) {
            *(int *)&this[0x2d79].field_0x1 = *(int *)&this[0x2d79].field_0x1 + unaff_r9;
            unaff_r9 = 0;
          }
          goto LAB_0003d1cc;
        }
      }
    }
    unaff_r9 = -4;
  }
LAB_0003d1cc:
  if (local_2c != __stack_chk_guard) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail(unaff_r9);
  }
  return;
}


/* CImp::get_dir_entry(IMP_DIR_ENTRY*, char*) */

int __thiscall CImp::get_dir_entry(CImp *this,IMP_DIR_ENTRY *param_1,char *param_2)

{
  undefined2 uVar1;
  ushort uVar2;
  int iVar3;
  undefined4 uVar4;
  void *pvVar5;
  void *pvVar6;
  
  pvVar5 = *(void **)(this + 0x2d78);
  pvVar6 = *(void **)&this[0x2d79].field_0x1;
  if (pvVar6 <= pvVar5) {
    iVar3 = extract_dir(this);
    if (iVar3 < 0) {
      return iVar3;
    }
    pvVar6 = *(void **)&this[0x2d79].field_0x1;
    pvVar5 = *(void **)(this + 0x2d78);
  }
  if (0x25 < (int)pvVar6 - (int)pvVar5) {
    uVar1 = get_uint16(this,pvVar5);
    iVar3 = *(int *)(this + 0x2d78);
    *(undefined2 *)param_1 = uVar1;
    uVar4 = get_uint32(this,(void *)(iVar3 + 4));
    iVar3 = *(int *)(this + 0x2d78);
    *(undefined4 *)(param_1 + 4) = uVar4;
    param_1[10] = *(IMP_DIR_ENTRY *)(iVar3 + 10);
    param_1[0xb] = *(IMP_DIR_ENTRY *)(*(int *)(this + 0x2d78) + 0xb);
    uVar4 = get_uint32(this,(void *)(*(int *)(this + 0x2d78) + 0xc));
    iVar3 = *(int *)(this + 0x2d78);
    *(undefined4 *)(param_1 + 0xc) = uVar4;
    uVar4 = get_uint32(this,(void *)(iVar3 + 0x10));
    iVar3 = *(int *)(this + 0x2d78);
    *(undefined4 *)(param_1 + 0x10) = uVar4;
    uVar4 = get_uint32(this,(void *)(iVar3 + 0x14));
    iVar3 = *(int *)(this + 0x2d78);
    *(undefined4 *)(param_1 + 0x14) = uVar4;
    uVar1 = get_uint16(this,(void *)(iVar3 + 0x18));
    iVar3 = *(int *)(this + 0x2d78);
    *(undefined2 *)(param_1 + 0x18) = uVar1;
    uVar1 = get_uint16(this,(void *)(iVar3 + 0x1a));
    iVar3 = *(int *)(this + 0x2d78);
    *(undefined2 *)(param_1 + 0x1a) = uVar1;
    uVar1 = get_uint16(this,(void *)(iVar3 + 0x20));
    iVar3 = *(int *)(this + 0x2d78);
    *(undefined2 *)(param_1 + 0x20) = uVar1;
    uVar1 = get_uint16(this,(void *)(iVar3 + 0x22));
    iVar3 = *(int *)(this + 0x2d78);
    *(undefined2 *)(param_1 + 0x22) = uVar1;
    uVar1 = get_uint16(this,(void *)(iVar3 + 0x24));
    *(undefined2 *)(param_1 + 0x24) = uVar1;
    if (0x10a < (*(ushort *)param_1 & 0xfff)) {
      *(undefined4 *)(this + 0x26bc) = 2;
      return -1;
    }
    iVar3 = (uint)*(ushort *)(param_1 + 0x1a) + (uint)(byte)param_1[10] + 0x26 +
            (uint)*(ushort *)(param_1 + 0x18);
    if (iVar3 <= *(int *)&this[0x2d79].field_0x1 - *(int *)(this + 0x2d78)) {
      *(undefined1 *)(*(int *)(this + 0x2d78) + 0x24) = 0;
      *(undefined1 *)(*(int *)(this + 0x2d78) + 0x25) = 0;
      uVar2 = block_crc(this,*(void **)(this + 0x2d78),iVar3,0xffffffff);
      if ((ushort)~uVar2 == *(ushort *)(param_1 + 0x24)) {
        memcpy(param_2,(void *)(*(int *)(this + 0x2d78) + 0x26),(uint)*(ushort *)(param_1 + 0x1a));
        param_2[*(ushort *)(param_1 + 0x1a)] = '\0';
        *(int *)(this + 0x2d78) = *(int *)(this + 0x2d78) + iVar3;
        return 0;
      }
    }
  }
  return -4;
}


/* CImp::decomp(CImp::vFILE*, unsigned int, unsigned int, unsigned int, unsigned char) */

void __thiscall
CImp::decomp(CImp *this,vFILE *param_1,uint param_2,uint param_3,uint param_4,uchar param_5)

{
  byte bVar1;
  int iVar2;
  undefined1 *__dest;
  undefined4 uVar3;
  uint uVar4;
  uint uVar5;
  uchar *puVar6;
  int iVar7;
  uint uVar8;
  int iVar9;
  int iVar10;
  size_t __n;
  bool bVar11;
  uint local_6c;
  uint local_60;
  int local_54;
  uint local_4c;
  undefined1 auStack_38 [4];
  undefined1 auStack_34 [8];
  int local_2c;
  
  local_2c = __stack_chk_guard;
  if (param_4 == 0) {
    *(undefined4 *)&this[0x26bd].field_0x1 = 0;
    uVar4 = 0;
LAB_0003d97c:
    if (local_2c != __stack_chk_guard) {
                    /* WARNING: Subroutine does not return */
      __stack_chk_fail(uVar4);
    }
    return;
  }
  uVar3 = 0;
  bVar11 = (param_5 & 2) != 0;
  *(undefined4 *)&this[0x26b5].field_0x1 = 0;
  *(undefined4 *)&this[0x2d76].field_0x2 = 0;
  this[0x2658].field_0x1 = 0;
  if (bVar11) {
    uVar3 = 2;
  }
  *(undefined4 *)&this[0x26bd].field_0x1 = 0xffffffff;
  if (bVar11) {
    *(undefined4 *)&this[0x26b5].field_0x1 = uVar3;
  }
  else if ((param_5 & 4) != 0) {
    *(undefined4 *)&this[0x26b5].field_0x1 = 4;
  }
  uVar4 = *(int *)&this[0x2d75].field_0x1 + 6 + param_2;
  if ((*(uint *)&this[0x2816].field_0x2 != uVar4) || (param_3 < *(uint *)(this + 0x2818))) {
    *(undefined4 *)&this[0x26b9].field_0x1 = 0;
    *(uint *)&this[0x2816].field_0x2 = uVar4;
    *(undefined4 *)&this[0x281a].field_0x2 = 0;
    *(undefined4 *)(this + 0x281c) = 0;
    this[0x2658].field_0x1 = 0;
    *(undefined1 *)(this + 0x2658) = 0;
    *(undefined4 *)(this + 0x2818) = 0;
    this[0x2658].field_0x2 = 0;
    vFILE::fseek(*(vFILE **)&this[0x2d7a].field_0x2,uVar4,2);
    if (*(void **)&this[0x2659].field_0x1 != (void *)0x0) {
      freeSystemHeap(*(void **)&this[0x2659].field_0x1);
      *(undefined4 *)&this[0x2659].field_0x1 = 0;
    }
  }
  local_4c = 0;
  local_60 = param_4;
  local_54 = 0;
  iVar10 = 0;
LAB_0003d744:
  if (this[0x2658].field_0x2 == '\0') {
    do {
      local_6c = *(int *)(this + 0x2818) + *(int *)(this + 0x281c);
      if (param_3 < local_6c) {
        puVar6 = (uchar *)(*(int *)&this[0x2659].field_0x1 +
                          (*(int *)&this[0x281a].field_0x2 - *(int *)(this + 0x2818)) + param_3);
        local_6c = local_6c - param_3;
        if (iVar10 < 0xb) {
          __n = 0xbU - iVar10;
          if ((int)local_6c <= (int)(0xbU - iVar10)) {
            __n = local_6c;
          }
          __dest = auStack_38 + iVar10;
          iVar10 = iVar10 + __n;
          memcpy(__dest,puVar6,__n);
          param_3 = param_3 + __n;
          if (iVar10 < 0xb) goto LAB_0003d744;
          local_6c = local_6c - __n;
        }
        iVar2 = get_uint16(this,auStack_34);
        if (local_54 < iVar2) goto code_r0x0003da44;
        if (local_60 < local_6c) {
          local_6c = local_60;
        }
        if (*(int *)&this[0x26b5].field_0x1 == 0) {
          uVar3 = block_crc(this,puVar6,local_6c,*(uint *)&this[0x26bd].field_0x1);
          *(undefined4 *)&this[0x26bd].field_0x1 = uVar3;
          iVar2 = vFILE::fwrite(param_1,puVar6,1,local_6c);
          if (iVar2 < (int)local_6c) {
            uVar4 = 0xfffffffa;
            goto LAB_0003d97c;
          }
        }
        else {
          uVar4 = e8ut_crc_write(this,param_1,puVar6,local_6c,local_4c,param_4,
                                 (uint)(local_60 == local_6c));
          if ((int)uVar4 < 0) goto LAB_0003d97c;
          local_4c = local_4c + local_6c;
        }
        local_60 = local_60 - local_6c;
        if (local_60 == 0) {
          if (*(void **)&this[0x2659].field_0x1 != (void *)0x0) {
            freeSystemHeap(*(void **)&this[0x2659].field_0x1);
            *(undefined4 *)&this[0x2659].field_0x1 = 0;
          }
          uVar4 = 0;
          *(uint *)&this[0x26bd].field_0x1 = ~*(uint *)&this[0x26bd].field_0x1;
          goto LAB_0003d97c;
        }
        param_3 = param_3 + local_6c;
      }
      this[0x2658].field_0x2 = 1;
      if (this[0x2658].field_0x1 != '\0') {
        uVar4 = 0;
        goto LAB_0003d97c;
      }
      iVar7 = *(int *)(this + 0x281c);
      iVar2 = *(int *)(this + 0x2818);
      *(int *)&this[0x281a].field_0x2 = iVar7 + *(int *)&this[0x281a].field_0x2;
      iVar9 = *(int *)&this[0x2d7a].field_0x2;
      *(int *)(this + 0x2818) = iVar7 + iVar2;
      iVar2 = *(int *)(iVar9 + 4);
      init_getbits(this);
      uVar4 = getbits(this,4);
      uVar5 = *(uint *)&this[0x281d].field_0x1;
      uVar4 = uVar4 & 0xf;
      *(int *)(this + 0x26b8) = *(int *)(this + 0x26b8) + -4;
      *(uint *)&this[0x281d].field_0x1 = uVar5 >> 4;
      if (3 < uVar4) break;
      bVar1 = getbits(this,1);
      iVar7 = *(int *)(this + 0x26b8);
      uVar5 = *(uint *)&this[0x281d].field_0x1;
      this[0x2658].field_0x1 = bVar1 & 1;
      *(int *)(this + 0x26b8) = iVar7 + -1;
      *(uint *)&this[0x281d].field_0x1 = uVar5 >> 1;
      uVar5 = getbits(this,0x14);
      uVar8 = *(uint *)&this[0x281d].field_0x1;
      *(uint *)(this + 0x281c) = uVar5 & 0xfffff;
      *(int *)(this + 0x26b8) = *(int *)(this + 0x26b8) + -0x14;
      *(uint *)&this[0x281d].field_0x1 = uVar8 >> 0x14;
      uVar5 = getbits(this,0x14);
      iVar9 = *(int *)(this + 0x26b8);
      iVar7 = *(int *)&this[0x2659].field_0x1;
      *(uint *)&this[0x281d].field_0x1 = *(uint *)&this[0x281d].field_0x1 >> 0x14;
      *(int *)(this + 0x26b8) = iVar9 + -0x14;
      if (iVar7 == 0) {
        iVar7 = *(int *)(this + 0x281c);
        *(int *)&this[0x2819].field_0x1 = iVar7;
        iVar7 = allocSystemHeap(iVar7 + 0x200);
        *(int *)&this[0x2659].field_0x1 = iVar7;
        if (iVar7 != 0) goto LAB_0003d8a0;
LAB_0003dcf4:
        uVar4 = 0xfffffff6;
        goto LAB_0003d97c;
      }
LAB_0003d8a0:
      if (uVar4 == 1 || uVar4 == 3) {
        if (*(char *)(this + 0x2658) == '\0') {
          iVar9 = *(int *)(this + 0x26b8);
          puVar6 = *(uchar **)&this[0x2659].field_0x1;
          uVar4 = *(uint *)&this[0x281a].field_0x2;
          iVar7 = *(int *)(this + 0x281c);
          *(uint *)&this[0x281d].field_0x1 = *(uint *)&this[0x281d].field_0x1 >> 5;
          *(int *)(this + 0x26b8) = iVar9 + -5;
        }
        else {
          uVar4 = getbits(this,2);
          uVar8 = *(uint *)&this[0x281d].field_0x1;
          *(int *)(this + 0x26b8) = *(int *)(this + 0x26b8) + -2;
          *(uint *)&this[0x281d].field_0x1 = uVar8 >> 2;
          if ((uVar4 & 3) == 3) break;
          uVar8 = getbits(this,3);
          iVar7 = *(int *)(this + 0x26b8);
          uVar8 = *(uint *)(&DAT_00085064 + ((uVar8 & 7) + (uVar4 & 3) * 8) * 4);
          *(uint *)&this[0x281d].field_0x1 = *(uint *)&this[0x281d].field_0x1 >> 3;
          *(int *)(this + 0x26b8) = iVar7 + -3;
          redo_mm(this,uVar8);
          uVar4 = *(uint *)&this[0x281a].field_0x2;
          if (uVar8 < uVar4) {
            memmove(*(void **)&this[0x2659].field_0x1,
                    (void *)((int)*(void **)&this[0x2659].field_0x1 + (uVar4 - uVar8)),uVar8);
            *(uint *)&this[0x281a].field_0x2 = uVar8;
            uVar4 = uVar8;
          }
          iVar7 = *(int *)(this + 0x281c);
          if (*(uint *)&this[0x2819].field_0x1 < uVar4 + iVar7) {
            *(uint *)&this[0x2819].field_0x1 = uVar4 + iVar7;
            freeSystemHeap(*(void **)&this[0x2659].field_0x1);
            puVar6 = (uchar *)allocSystemHeap(*(int *)&this[0x2819].field_0x1 + 0x200);
            if (puVar6 == (uchar *)0x0) {
              freeSystemHeap(*(void **)&this[0x2659].field_0x1);
              *(undefined4 *)&this[0x2659].field_0x1 = 0;
              goto LAB_0003dcf4;
            }
            *(uchar **)&this[0x2659].field_0x1 = puVar6;
            iVar7 = *(int *)(this + 0x281c);
            uVar4 = *(uint *)&this[0x281a].field_0x2;
          }
          else {
            puVar6 = *(uchar **)&this[0x2659].field_0x1;
          }
        }
        uVar4 = expand_lz(this,puVar6,uVar4,iVar7,1);
        if ((int)uVar4 < 0) goto LAB_0003d97c;
        if (uVar4 < *(uint *)(this + 0x281c)) {
          *(uint *)(this + 0x281c) = uVar4;
          this[0x2658].field_0x1 = 1;
        }
      }
      vFILE::fseek(*(vFILE **)&this[0x2d7a].field_0x2,(uVar5 & 0xfffff) + iVar2,2);
      *(undefined1 *)(this + 0x2658) = 1;
      this[0x2658].field_0x2 = 0;
      if (this[0x2658].field_0x2 != '\0') break;
    } while( true );
  }
  uVar4 = 0xfffffffd;
  goto LAB_0003d97c;
code_r0x0003da44:
  uVar4 = iVar2 - local_54;
  if ((int)local_6c <= iVar2 - local_54) {
    uVar4 = local_6c;
  }
  local_54 = local_54 + uVar4;
  param_3 = param_3 + uVar4;
  goto LAB_0003d744;
}


/* CImp::decode(unsigned char*, unsigned char*, unsigned int, unsigned int) */

void __thiscall CImp::decode(CImp *this,uchar *param_1,uchar *param_2,uint param_3,uint param_4)

{
  vFILE *pvVar1;
  int iVar2;
  int iVar3;
  uint uVar4;
  uint uVar5;
  uint uVar6;
  int iVar7;
  IMP_DIR_ENTRY aIStack_288 [4];
  uint local_284;
  uchar local_27d;
  uint local_27c;
  uint local_278;
  int local_274;
  char acStack_260 [260];
  char acStack_15c [260];
  undefined1 auStack_58 [4];
  undefined1 auStack_54 [4];
  undefined1 auStack_50 [8];
  undefined1 auStack_48 [22];
  undefined1 auStack_32 [2];
  undefined1 local_30;
  undefined1 local_2f;
  int local_2c;
  
  local_2c = __stack_chk_guard;
  pvVar1 = ::operator.new(0x10);
  vFILE::vFILE(pvVar1,(uint)param_1,param_3,0);
  *(vFILE **)&this[0x2d7a].field_0x2 = pvVar1;
  pvVar1 = ::operator.new(0x10);
  vFILE::vFILE(pvVar1,(uint)param_2,param_4,1);
  *(vFILE **)(this + 0x2d7c) = pvVar1;
  vFILE::fseek(*(vFILE **)&this[0x2d7a].field_0x2,0,2);
  iVar2 = vFILE::fread(*(vFILE **)&this[0x2d7a].field_0x2,auStack_58,4,1);
  if (iVar2 != 0) {
    vFILE::fseek(*(vFILE **)&this[0x2d7a].field_0x2,0,2);
    iVar2 = get_uint32(this,auStack_58);
    if (iVar2 != 0xa504d49) {
      iVar2 = find_start(this);
      if (iVar2 < 0) goto LAB_0003dde0;
      vFILE::fseek(*(vFILE **)&this[0x2d7a].field_0x2,*(uint *)&this[0x2d75].field_0x1,2);
    }
    iVar2 = vFILE::fread(*(vFILE **)&this[0x2d7a].field_0x2,auStack_58,0x2a,1);
    if (iVar2 != 0) {
      iVar2 = get_uint32(this,auStack_54);
      iVar3 = get_uint32(this,auStack_50);
      get_uint32(this,auStack_48);
      uVar4 = get_uint16(this,auStack_32);
      uVar5 = get_uint16(this,&local_30);
      local_2f = 0;
      local_30 = 0;
      uVar6 = block_crc(this,auStack_58,0x2a,0xffffffff);
      if ((~uVar6 & 0xffff) == uVar5) {
        if (iVar3 == 0) {
          iVar2 = 0;
        }
        else if ((uVar4 & 1) == 0) {
          if ((uVar4 & 4) == 0) {
            uVar4 = iVar2 + *(int *)&this[0x2d75].field_0x1;
            *(undefined1 **)&this[0x2d79].field_0x1 = &this[0x1bad].field_0x1;
            *(undefined4 *)&this[0x2816].field_0x2 = 0xffffffff;
            *(undefined1 **)(this + 0x2d78) = &this[0x1bad].field_0x1;
            *(undefined4 *)&this[0x2659].field_0x1 = 0;
            *(uint *)(this + 0x2814) = uVar4;
            vFILE::fseek(*(vFILE **)&this[0x2d7a].field_0x2,uVar4,2);
            iVar7 = 0;
            do {
              iVar2 = get_dir_entry(this,aIStack_288,acStack_15c);
              if (iVar2 < 0) goto LAB_0003dde0;
              strcpy(acStack_260,acStack_15c);
              if (*(vFILE **)(this + 0x2d7c) == (vFILE *)0x0) {
                *(undefined4 *)(this + 0x26bc) = 7;
              }
              else {
                iVar2 = decomp(this,*(vFILE **)(this + 0x2d7c),local_284,local_27c,local_278,
                               local_27d);
                if (iVar2 < 0) {
                  if (iVar2 == -6) {
                    *(undefined4 *)(this + 0x26bc) = 7;
                    iVar2 = 0;
                  }
                  goto LAB_0003dde0;
                }
                if (*(int *)&this[0x26bd].field_0x1 != local_274) {
                  *(undefined4 *)(this + 0x26bc) = 3;
                }
              }
              iVar7 = iVar7 + 1;
            } while (iVar7 != iVar3);
            iVar2 = 0;
          }
          else {
            iVar2 = -7;
          }
        }
        else {
          iVar2 = -8;
        }
      }
      else {
        iVar2 = -3;
      }
      goto LAB_0003dde0;
    }
  }
  iVar2 = -5;
LAB_0003dde0:
  if (local_2c != __stack_chk_guard) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail(iVar2);
  }
  return;
}