Page 1 of 7 123 ... LastLast
Results 1 to 10 of 69

Thread: DK2 texture format

  
  1. #1
    Demon Spawn
    Join Date
    Sep 2009
    Location
    Germany
    Posts
    172

    Post DK2 texture format

    First of all, here are all the EngineTextures.dat textures unpacked if you wanna investigate them:
    http://ul.to/0ic5sm

    Some older information can be obtained there:
    http://durchschuss.du.funpic.de/inde...te=dk2textures
    Those aren't up-to-date anymore though.


    Format

    There are 4 quality levels indicated by the file suffix ranging from MM0(highest) to MM3.

    The file structure is as follows:
    Code:
    struct Header {
        int resx; // width
        int resy; // height
        int size; // size of the rest of the file (i.e. without those 3 first ints)
        int resxy; // ? containing the height and width in low and high word?
        int uk; // = 0x75?
    }
    I just found files where that uk was 0xF5 instead of 0x75, maybe it's some flag field.


    Compression

    I thought the used compression could be S3TC (.dds compression) since it was introduced in DirectX 6, but I read it uses a fixed compression ratio so it's yet unlikely.

  2. #2
    Demon Spawn
    Join Date
    Sep 2009
    Location
    Germany
    Posts
    172

    Default Re: DK2 texture format

    Ok I finally found the place where the textures get loaded
    Setting a breakpoint didn't give me anything so far though

    Regarding the use of high-res textures:
    The texture sizes are checked to be in the range [16,128].
    If they're not, another procedure is called that seems to check if the texturename contains the string "PRESCALED_TO" and in some cases again calls the procedure that called it to load the texture (didn't have a closer look at it).
    Code:
            fread_s(&resX, 4u, 1u, (int)dword_7920E0);
            fread_s(&resY, 4u, 1u, (int)dword_7920E0);
            v6 = 0;
            if ( resX < 16 )
              v6 = 1;
            v7 = resY;
            if ( resY < 16 )
              v6 = 1;
            if ( resX > 128 )
              v6 = 1;
            if ( resY > 128 )
              v6 = 1;
            if ( v6 )
            {
              sub_5911E0(v1);
            }
    Code:
    int __fastcall sub_5911E0(int a1)
    {
      char *v1; // [email protected]
      char v2; // [email protected]
      int v3; // [email protected]
      int i; // [email protected]
      int v5; // [email protected]
      int v6; // esi[email protected]
      int v7; // [email protected]
      int result; // [email protected]
      int v9; // [email protected]
      signed int j; // [email protected]
      int v11; // [email protected]
      int v12; // [email protected]
      int v13; // [email protected]
      char v14; // [email protected]
      int v15; // [email protected]
      int v16; // [email protected]
      char v17; // [email protected]
      int v18; // [email protected]
      int v19; // [email protected]
      int v20; // [email protected]
      char v21; // [email protected]
      int v22; // [email protected]
      int v23; // [email protected]
      int v24; // [email protected]
      int v25; // [email protected]
      int v26; // [email protected]
      int v27; // [email protected]
      int v28; // [email protected]
      int v29; // [email protected]
      int v30; // [email protected]
      int v31; // [email protected]
      int v32; // [email protected]
      char v33; // [email protected]
      char v34; // [sp+414h] [bp-800h]@1
      signed int v35; // [sp+10h] [bp-C04h]@10
      char v36; // [sp+14h] [bp-C00h]@18
    
      v3 = a1;
      sprintf(&v34, *(const char **)(dword_792D44 + 12 * *(_DWORD *)(a1 + 36)));
      v2 = 0;
      v1 = strstr(&v34, "PRESCALED_TO");
      if ( v1 )
      {
        *v1 = 0;
        v2 = 1;
      }
      if ( v2 )
      {
        v6 = *(_DWORD *)(dword_792D44 + 12 * getMMxTextureOffset(&v34) + 4);
        v13 = *(_DWORD *)(v6 + 60);
        BYTE1(v13) |= 2u;
        i = *(_DWORD *)v6;
        v5 = v6 + 60;
        v14 = *(_DWORD *)v6 == 0;
        *(_DWORD *)(v6 + 60) = v13;
        if ( v14 )
        {
          HandleMM0(v6);
          for ( i = *(_DWORD *)v6; !*(_DWORD *)v6; i = *(_DWORD *)v6 )
          {
            v15 = *(_DWORD *)v5;
            BYTE1(v15) &= 0xFDu;
            *(_DWORD *)v5 = v15;
            v6 = *(_DWORD *)(v6 + 24);
            v16 = *(_DWORD *)(v6 + 60);
            i = *(_DWORD *)v6;
            v5 = v6 + 60;
            BYTE1(v16) |= 2u;
            v17 = *(_DWORD *)v6 == 0;
            *(_DWORD *)(v6 + 60) = v16;
            if ( !v17 )
              break;
            HandleMM0(v6);
          }
        }

  3. #3
    KeeperFX Author mefistotelis's Avatar
    Join Date
    Sep 2009
    Location
    Poland
    Posts
    1,235

    Default Re: DK2 texture format

    Nice work!

  4. #4
    Demon Spawn
    Join Date
    Sep 2009
    Location
    Germany
    Posts
    172

    Default Re: DK2 texture format

    Thanks. I just can't seem to get it to break, neither memory bp nor hardware bps break.. or it simply crashes when done loading.
    If I could just get DK2 to run in windowed mode or at least in 1600x1200x32

  5. #5
    Ghost
    Join Date
    Sep 2009
    Location
    Holland
    Posts
    372

    Default Re: DK2 texture format

    Quote Originally Posted by Trass3r View Post
    Thanks. I just can't seem to get it to break, neither memory bp nor hardware bps break.. or it simply crashes when done loading.
    If I could just get DK2 to run in windowed mode or at least in 1600x1200x32
    You can run the game in 1600x1200 by changing a registry value. But it isn't stable. And the view angle gets messed up so it doesn't play very well.

  6. #6
    Demon Spawn
    Join Date
    Sep 2009
    Location
    Germany
    Posts
    172

    Default Re: DK2 texture format

    Immediately crashes for me.
    Edit:
    And my sound is gone when changing that. Anyways, my DK2 seems to be totally fucked up again, grainy pictures etc.
    Last edited by Trass3r; October 1st, 2009 at 04:58.

  7. #7
    Awakening Game Master Metal Gear Rex's Avatar
    Join Date
    Sep 2009
    Posts
    5,624

    Default Re: DK2 texture format

    If you fix that, tell me. I have no idea how to fix that for me either. Though, I think it is only for the main menu but I'm not really sure as I don't remember.
    Dungeon Keeper 2 Patch: With More Balance and Pie [Hiatus]
    Forever Hiatus. Probably. Latest Version: 3.5 w/Levels 1-11 Revised.

    The Awakening: GM Powers Activate!
    Tesonu is napping!

    LOL, WFTO

  8. #8
    KeeperFX Author mefistotelis's Avatar
    Join Date
    Sep 2009
    Location
    Poland
    Posts
    1,235

    Default Re: DK2 texture format

    Quote Originally Posted by Trass3r View Post
    Thanks. I just can't seem to get it to break, neither memory bp nor hardware bps break..
    You can find it with IDA, you only need to define everything

    look at this:
    Code:
    int __thiscall sub_591070(struct unkstruc6 *this, char *fname)
    {
      int idx; // [email protected]
      struct unkstruc6 *this1; // [email protected]
      int result; // [email protected]
      struct eheapitm1 *v5; // [email protected]
      int v6; // [email protected]
      FILE *v7; // [email protected]
      int v8; // [email protected]
      int v9; // [email protected]
      int v10; // [email protected]
      int vtable; // [email protected]
      void *v12; // [email protected]
      signed int DstBuf; // [sp+8h] [bp-18h]@3
      signed int v14; // [sp+4h] [bp-1Ch]@3
      struct eheapitm1 *v15; // [sp+10h] [bp-10h]@3
      signed int v16; // [sp+1Ch] [bp-4h]@3
      size_t ElementSize; // [sp+Ch] [bp-14h]@8
    
      this1 = this;
      idx = get_slot_for_texture_file(&this->field_434, fname);
      if ( idx >= 0 )
      {
        fseek(this1->texturesFile, this1->field_434.field_410[idx].field_0, 0);
        v7 = this1->texturesFile;
        DstBuf = -1;
        v14 = -1;
        fname = (char *)-1;
        read_from_file(&DstBuf, 4u, 1u, v7);
        read_from_file(&v14, 4u, 1u, this1->texturesFile);
        read_from_file(&fname, 4u, 1u, this1->texturesFile);
        v8 = allocate_engine_heap(28);
        v5 = (struct eheapitm1 *)v8;
        v15 = (struct eheapitm1 *)v8;
        v16 = 0;
        if ( v8 )
        {
          v9 = v14;
          v10 = DstBuf;
          v6 = (int)fname;
          v5->ptrfield_10 = (int)&unk_792D98;
          v5->vtable = (int)&unkn_vtable1;
          v5->field_4 = v10;
          v5->field_8 = v9;
          v5->field_C = v10 * dword_792DA0;
          LOBYTE(v16) = 1;
          v5->vtable = (int)&off_67039C;
          v5->ptrfield_14 = 0;
          if ( v6 )
            v5->ptrfield_14 = allocate_engine_heap(v6);
          v5->mem14_len = v6;
        }
        else
        {
          v5 = 0;
        }
        ElementSize = 0;
        vtable = v5->vtable;
        v16 = -1;
        v12 = (void *)(*(int (__thiscall **)(_DWORD, _DWORD))(vtable + 32))(v5, &ElementSize);
        read_from_file(v12, ElementSize, 1u, this1->texturesFile);
        result = (int)v5;
      }
      else
      {
        result = 0;
      }
      return result;
    }
    As you see, it's easier to read if you'll define the function calling convention properly (most of them are __thiscall and they get "this" pointer in ecx).

    Also, defining structures helps a lot, even if you can't properly name them.
    Code:
    struct unkstruc2
    {
      unsigned long ptrfield_0[9];
      unsigned long field_24;
      unsigned char field_28[16];
      unsigned char field_38;
      unsigned char field_39[3];
      unsigned char field_3C;
      unsigned char field_3D[3];
      unsigned char field_40;
      unsigned char field_41;
      unsigned char field_42[970];
      void *ptrfield_40C;
      unkstruc2_sub2 field_410[2];
    };
    
    struct unkstruc6
    {
      unsigned long field_0;
      void *field_4;
      void *texturesFile;
      unsigned char field_C[1060];
      unsigned long field_430;
      unkstruc2 field_434;
    };
    Last edited by mefistotelis; October 1st, 2009 at 11:52.

  9. #9
    Demon Spawn
    Join Date
    Sep 2009
    Location
    Germany
    Posts
    172

    Default Re: DK2 texture format

    Unfortunately I'm not that of an IDA crack. Really need to get some tutorials to dive deeper into all that (defining structures,... there's even some way to write some kind of plugins for an exe afaik)
    I already know that function, it does read in the texture but the question is where it is used (the bps were set on the read texture data from
    Code:
    read_from_file(v12, ElementSize, 1u, this1->texturesFile);

  10. #10
    KeeperFX Author mefistotelis's Avatar
    Join Date
    Sep 2009
    Location
    Poland
    Posts
    1,235

    Default Re: DK2 texture format

    Then we must learn where v12 is.

    It's returned by function at (v5->vtable + 32) - to learn where it is, we need to look a bit higher:
    Code:
          v5->vtable = (int)&off_67039C;
    So - to learn the address, we must analyze function pointed at (off_67039C + 32).

Similar Threads

  1. Best dk2 AI!!!
    By blragh in forum Dungeon Keeper 2
    Replies: 49
    Last Post: November 27th, 2010, 12:26
  2. Dk1 vs dk2
    By dk2player in forum Off Topic
    Replies: 34
    Last Post: October 6th, 2009, 16:43
  3. A complete guide: How to play DK2 multiplayer
    By Ðârk Âñgêl in forum DK2 Multiplayer
    Replies: 0
    Last Post: September 1st, 2009, 14:55

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •