2018-03-17 04:15:40 +00:00
2018-02-24 13:50:35 +00:00
2018-03-17 04:15:40 +00:00
2018-03-17 04:15:11 +00:00
2018-03-17 04:15:11 +00:00
2018-02-24 13:50:35 +00:00

WH40K: Chaos Gate

Re-implementation of the WH40K binary using SDL.

You must have a copy of the original game data to use this project

Files:

Anim/
    WarHammer.ani # Doesn't seem to be a RIFF file. 398M so very important.
       * There's a pcx image header at `dd ... bs=1 skip=213` but it seems to be a false alert
       * Hits for "AmigaOS bitmap font"... probably a false positive
       * Lots of 8-byte reads when loading stuff in the mission editor
       * Some ~4K reads, havent found one corresponding to a known format yet
Assign/
    *.asn # Unknown, seems to be related to .obj files
Cursor/
    *.ani # RIFF data
    *.cur # Presumably standard windows-format non-animated cursors
Data/
    *.dat # plaintext files defining properties of objects. No single format
      PARSED:
        Accounting.dat  # key = value => internal/data/accounting.go
        AniObjDef.dat   # animated object definitions
        GenericData.dat # Generic Game Settings
      IN PROGRESS:

      TODO:
        ChaNames.dat    # list of character names
        Coordinates.dat # Weapon Firing Coordinates
        Defs.dat        # defines properties for objects and tiles, each of which seems to have an id
        GDestroy.dat    # table of what destroys what?
        HasAction.dat   # "Are there animation for each of the character" - list of booleans
        MiniMap.dat     # lots of seemingly random numbers. IDs?
        MissionBriefing.dat # Contains all Campaign Mission Briefing Text. Sections: "CAMPAIGN MISSION X ... END CAMPAIGN MISSION X"
        PWeight.dat     # Personality weights for the individual character types
        Random_AI.dat   # contains the percentage of the different AI types for each of the different Chaos Squad Types
        RandomPlanets.dat #  Campaign Primary and Secondary Objectives
        Sounds.dat      # Sound Effect Data
        SpellDef.dat    # SPELL DEFINITIONS
        StdWeap.dat     # SQUAD STANDARD WEAPONS
        Ultnames.dat    # List of names for ultramarines
        VehicDef.dat    # VEHICLE DEFINITIONS
        WeapDef.dat     # Weapon definitions
      PROBABLY NOT NEEDED:
        BugHunt.dat     # Contains SMF text for Bug hunt random missions
        Credits.dat     # list of credits
        GenArm.dat      # "Random campaign armory levels - space marine"
        HeroArm.dat     # "Random campaign armory levels - Veteran"
        MHeroArm.dat    # "Random campaign armory levels - Veteran"
        PlanetDesc.dat  # well-documented params. random mission generator params per planet.
        RandChar.dat    # Random character matrix. Information on what goes into a character matrix.
        RandSMFtext.dat # SuperMacro Objectives for Campaign Random Mission Generator.
        SpArm.dat       # "RANDOM CAMPAIGN ARMORY LEVELS - Veteran"
        VetArm.dat      # "RANDOM CAMPAIGN ARMORY LEVELS - Veteran"

    *.chk # checksums? Mentions all the .dat files
    *.cyc # ColorCycle DataFile. 
    *.dta # localized strings and things
      Encyclopedia.dta # encyclopedia entries
      KeyMap.dta       # unknown
      Keymap.dta # unknown
      USEng.dta  # Localized strings

EquipmentMenuData # gzip-compressed, presumably to do with (initial?) squad configuration
Filters/
    wh40k.flt # Audio filter(s?)
Fonts/
    cboxfont # unknown
    *.fnt # ASCII text. Map keycodes to sprites?
    *.spr # sprites, presumably
Idx/
    WarHammer.idx # unknown, 1.8M
Maps/
    *.MAP # gzip-compressed, must be map definition, contains `WHMAP` constant and character names
    *.TXT # scenario text
Menu/
    *.mnu # plain text, linked to .obj file, contains definitions
    *.obj # unknown, not 3D .obj format
Misc/
    occlusio.lis # plain text, presumably occlusion mappings?
MultiMaps/
    *.MAP # Like Maps/
    *.TXT
Obj/
    *.obj # must be visual data of some sort, one per placeable map object?
Pic/
    *.pcx # Standard .pcx format
RandomMaps/
    *.chk # multiplayer. worry about these another day
    *.dat
Save_G/
    *.sav # savedata, gzip-compressed, custom format
    *.txt # Seems to be a copy of one of Maps/*.txt
Sets/
    Data.chk # checksums? Mentions all the .set files
    *.set # plain text, related to maps, lists a set of .obj files for that map?
SMK/
    *.smk # Videos: RAD Game Tools Smacker Multimedia version 2
Sounds/
    wh40k.ds # 0xffffffff then a list of .wav file names. Some sort of index?
Wav/
    *.wav # normal WAV files, all mentioned in Sounds/wh40k.ds

WH40K.exe is the existing game engine

WH40K_TD.exe is the map editor. Allows things to be saved as .MAP or as .SMF ("Super Macro File")

"Mission Setup" includes information about available squad types

From EquipDef.cpp Dumo: CEquipment we learn the following object types:

  1. DELETED
  2. WEAPON
  3. GRENADE
  4. MEDIPACK
  5. SCANNER
  6. GENESEED
  7. CLIP
  8. DOOR KEY
  9. DOOR KEY
  10. DOOR KEY
  11. DOOR KEY

And we learn they can be "on"....

  1. CHARACTER
  2. VEHICLE
  3. CANISTER

Hypothesis: Idx/WarHammer.idx points objects into bitmap data in Anim/WarHammer.ani

We can use WH40K_TD.exe and investigate reads of .idx followed by reads of .ani to test this.

Obj/.obj and Assign/.asn files seem to have some identity

WH40K_TD.exe opens files in this order:

  1. Data/USEng.dta
  2. WH40K_TD.exe (?)
  3. Cursor/Cursors.cur
  4. pread64(fd, 23, 0) = 23
  5. _llseek(fd, 0, [0], SEEK_CUR) = 0
  6. _llseek(fd, 0, [0], SEEK_CUR) = 0
  7. _llseek(fd, 40666, [40666], SEEK_SET) = 0
  8. _llseek(fd, 0, [0], SEEK_SET) = 0
  9. close(fd) = 0
  10. read(fd, "\x26\x00\x00\x00\x20\x00\x00\x00\x30\x01\x00\x00\x50\x01\x00\x00\x8a\x9d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32) = 32
  11. (...)
  12. _llseek(15</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Cursor/Cursors.cur>, 39868, [39868], SEEK_SET) = 0
  13. read(15</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Cursor/Cursors.cur>, "\x27\x00\x1f\x00\x22\x00\x24\x00\x00\x00\x00\x00\x06\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x03\x81\x1f\x80\x1a\x81\x1f\x80\x03\x00\x80\x02\x83\x1f\x32\x1f\x80\x18\x83\x1f\x32\x1f\x80\x02\x00\x80\x01\x85\x1f\x32\x37\x39\x1f\x80\x16\x85\x1f\x32\x37"..., 798) = 798
  14. (some statting of Idx/WarHammer.idx, no reading that I saw)
  15. Anim/WarHammer.ani
  16. read(15</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Anim/WarHammer.ani>, "\x7e\xdf\x02\x00\x20\x00\x00\x00\xf0\xfb\x16\x00\x10\xfc\x16\x00\xa5\x4a\xc3\x18\x00\x00\x00\x00\x00\x00\x00\x00\x28\x92\x52\x00", 32) = 32
  17. (some clones of child procs, I didn't follow them)
  18. Sounds/wh40k.ds
  19. pread64(31</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Sounds/wh40k.ds>, "\xff\xff\xff\xff\x08\x60\x06\x00\x61\x6d\x62\x5f\x30\x31\x5f\x6a\x75\x6e\x67\x6c\x65\x2e\x77", 23, 0) = 23
  20. read(31</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Sounds/wh40k.ds>, "\xff\xff\xff\xff\x08\x60\x06\x00\x61\x6d\x62\x5f\x30\x31\x5f\x6a\x75\x6e\x67\x6c\x65\x2e\x77\x61\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., 417792) = 417792
  21. read(31</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Sounds/wh40k.ds>, "\xe5\x03\x00\x00\x00\x58\x02\x00\x05\x10\x00\x50\xfe\x5e\xff\x00\x72\x03\x3d\x89\x12\x30\x00\x1f\x9e\xe2\x10\xf4\x32\xdd\xef\xf1\x42\xff\x0f\xc0\x12\x9c\xf2\x70\xeb\x01\x41\x04\x20\xad\xf1\x20\x11\x60\xce\xf3\x20\xc1\x42\xfa\x01\x32\x22\x0c\xcd\x00\x0b\xfe"..., 4096) = 4096
  22. Data/Sounds.dat
  23. pread64(34</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/Sounds.dat>, "#**********************", 23, 0) = 23
  24. ...
  25. Pic/wh40k.pcx
  26. read(34</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Pic/wh40k.pcx>, "\x0a\x05\x01\x08\x00\x00\x00\x00\x7f\x02\xdf\x01\x48\x00\x48\x00\x00\x00\x00\x80\x00\x00\x00\x80\x00\x80\x80\x00\x00\x00\x80\x80\x00\x80\x00\x80\x80\xc0\xc0\xc0\xc0\xdc\xc0\xa6\xca\xf0\xff\xff\xff\xf0\xf0\xf0\xdd\xdd\xdd\xcb\xcb\xcb\xbb\xbb\xbb\xb2\xb2\xb2"..., 168509) = 168509
  27. Sets/*
  28. (lots of statting these)
  29. Data/Randchar.dat
  30. pread64(34</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/RandChar.dat>, "#**********************", 23, 0) = 23
  31. read(34</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/RandChar.dat>, "#***************************************************************"..., 4096) = 4096
  32. ...
  33. Data/WeapDef.dat
  34. pread64(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/WeapDef.dat>, "#**********************", 23, 0) = 23
  35. read(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/WeapDef.dat>, "#***************************************************************"..., 4096) = 4096
  36. ...
  37. Data/SpellDef.dat
  38. pread64(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/SpellDef.dat>, "#**********************", 23, 0) = 23
  39. read(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/SpellDef.dat>, "#***************************************************************"..., 4096) = 4096
  40. ...
  41. Data/AniObDef.dat
  42. pread64(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/AniObDef.dat>, "# ******** ANIMATED OBJ", 23, 0) = 23
  43. read(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/AniObDef.dat>, "# ******** ANIMATED OBJECT DEFINITIONS **************\r\n#\t\t0 : **"..., 4096) = 4096
  44. ...
  45. Data/VehicDef.dat
  46. pread64(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/VehicDef.dat>, "# ******** VEHICLE DEFI", 23, 0) = 23
  47. read(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/VehicDef.dat>, "# ******** VEHICLE DEFINITIONS **************\r\n#\t\t0 : *** VEHICL"..., 4096) = 4096
  48. ...
  49. Data/StdWeap.dat
  50. pread64(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/StdWeap.dat>, "# ******** SQUAD STANDA", 23, 0) = 23
  51. read(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Data/StdWeap.dat>, "# ******** SQUAD STANDARD WEAPONS **************\r\n#\t\t0 : *** SQU"..., 4096) = 4096
  52. ...
  53. Data/Ultnames.dat
  54. Data/Chanames.dat
  55. Data/keymap.dta
  56. Filters/wh40k.flt
  57. _llseek(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Filters/wh40k.flt>, 0, [0], SEEK_SET) = 0
  58. read(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Filters/wh40k.flt>, "\x01\x00\x00\x00", 4) = 4
  59. _llseek(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Filters/wh40k.flt>, 4, [4], SEEK_SET) = 0
  60. read(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Filters/wh40k.flt>, "\x4d\x79\x46\x69\x6c\x74\x65\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., 72) = 72
  61. _llseek(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Filters/wh40k.flt>, 1444, [1444], SEEK_SET) = 0
  62. read(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Filters/wh40k.flt>, "\x1f\x1e\x7f\x77\x1e\x1e\x1e\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1f\x1f\x1f\x4f\x4f\x1d\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1f\x1f\x1f\x1f\x1f\xaf\xaf\xaf\x97\x97\x97\x97\x1e\x1e\x1e\x1e\x1e\x1e\x1f\x1f\x1f"..., 327680) = 327680
  63. Misc/occlusio.lis
  64. pread64(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Misc/occlusio.lis>, "62 # Number of Absol", 23, 0) = 23
  65. read(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Misc/occlusio.lis>, "62 # Number of Absolute Deltas.\r\n # These Deltas are off"..., 4096) = 982
  66. read(35</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Misc/occlusio.lis>, "", 3114) = 0
  67. Data/GDestroy.dat
  68. (stat Obj/destroy.obj)
  69. Data/minimap.dat
  70. Misc/occlusio.list
  71. Obj/specials.obj
  72. Obj/Man_Shadow.obj
  73. Sets/map01.set
  74. Data/Defs.dat
  75. Assign/jungtil.asn
  76. pread64(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Assign/jungtil.asn>, "# jungle floor\r\n# jungt", 23, 0) = 23
  77. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Assign/jungtil.asn>, "# jungle floor\r\n# jungtil.obj/.asn\r\n# /--> d:\warflics\mission"..., 4096) = 408
  78. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Assign/jungtil.asn>, "", 3688) = 0
  79. Obj/jungtil.obj
  80. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\x12\x00\x00\x00\x20\x00\x00\x00\x90\x00\x00\x00\xb0\x00\x00\x00\x88\x17\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32) = 32
  81. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 32, [32], SEEK_SET) = 0
  82. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\x00\x00\x00\x00\xcf\x01\x00\x00\xcf\x01\x00\x00\x72\x11\x00\x00\x41\x13\x00\x00\x55\x11\x00\x00\x96\x24\x00\x00\x74\x11\x00\x00\x0a\x36\x00\x00\x76\x11\x00\x00\x80\x47\x00\x00\x6d\x11\x00\x00\xed\x58\x00\x00\x78\x11\x00\x00\x65\x6a\x00\x00\x70\x11\x00\x00"..., 144) = 144
  83. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 176, [176], SEEK_SET) = 0
  84. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\xb7\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x04\x1f\x80\x3e\x00\x80\x3c\x08\x1f\x80\x3c\x00\x80\x3a\x0c\x1f\x80\x3a\x00\x80\x38\x10\x1f\x80\x38\x00\x80\x36\x14\x1f\x80\x36\x00\x80\x34\x18\x1f\x80"..., 463) = 463
  85. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 639, [639], SEEK_SET) = 0
  86. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x5a\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x6e\x1e\x80\x3e\x00\x80\x3c\x88\xbf\x76\x6e\x6d\x6e\x76\x76\x6e\x80\x3c\x00\x80\x3a\x84\xbf\x76\x6e\x76\x04\x6d\x84\x6e\x76\x7d\x97\x80\x3a"..., 4466) = 4466
  87. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 5105, [5105], SEEK_SET) = 0
  88. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x3d\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x6e\x1e\x80\x3e\x00\x80\x3c\x88\xbf\x76\x6e\x6d\x6e\x76\x97\x6d\x80\x3c\x00\x80\x3a\x8c\xbf\x1e\x6c\x6d\x6d\x6e\x6d\x76\x6e\x97\x1c\x76\x80"..., 4437) = 4437
  89. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 9542, [9542], SEEK_SET) = 0
  90. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x5c\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x76\x7e\x80\x3e\x00\x80\x3c\x88\xbf\x76\x6d\x6e\x6d\x6e\x76\x97\x80\x3c\x00\x80\x3a\x83\x6d\x1e\x6c\x03\x6d\x86\x6e\x96\x76\x6d\x1c\x97\x80"..., 4468) = 4468
  91. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 14010, [14010], SEEK_SET) = 0
  92. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x5e\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x6e\x1e\x80\x3e\x00\x80\x3c\x88\xbf\x6e\x97\x6e\x76\x67\x97\x76\x80\x3c\x00\x80\x3a\x8c\x7d\xbf\x1e\x7f\x6e\x6e\x1e\x7d\x96\x6e\x7f\x97\x80"..., 4470) = 4470
  93. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 18480, [18480], SEEK_SET) = 0
  94. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x55\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x65\x6e\x1e\x7c\x80\x3e\x00\x80\x3c\x88\x66\x6e\x6b\x8f\x1c\x67\x6d\x6c\x80\x3c\x00\x80\x3a\x8c\x75\x1c\x6e\x6e\xad\x8f\x1c\x8f\x6d\x1c\x7d\x1c\x80"..., 4461) = 4461
  95. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 22941, [22941], SEEK_SET) = 0
  96. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x60\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x6e\x1e\x80\x3e\x00\x80\x3c\x88\xbf\x75\x76\x6e\x6d\x6e\x97\x97\x80\x3c\x00\x80\x3a\x85\x6b\x6b\x6e\x96\x76\x04\x6d\x83\x6e\x6b\x97\x80\x3a"..., 4472) = 4472
  97. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 27413, [27413], SEEK_SET) = 0
  98. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x58\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x76\x76\x1e\x80\x3e\x00\x80\x3c\x88\x8f\x6e\x6d\x6e\x96\x6e\x76\x67\x80\x3c\x00\x80\x3a\x87\x6b\x1a\x8f\x75\x96\x1c\x76\x03\x6e\x82\x6d\x6e\x80"..., 4464) = 4464
  99. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 31877, [31877], SEEK_SET) = 0
  100. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x65\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6c\x6e\x97\x1c\x80\x3e\x00\x80\x3c\x88\x6d\x6e\x76\x6e\x76\x6d\x97\x1c\x80\x3c\x00\x80\x3a\x8c\x6d\x6d\x96\xad\x76\x96\x6e\x76\x6e\x6e\x97\x6e\x80"..., 4477) = 4477
  101. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 36354, [36354], SEEK_SET) = 0
  102. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x61\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x6e\x1e\x80\x3e\x00\x80\x3c\x88\x75\x67\x6e\x76\x6d\x6e\x97\x1c\x80\x3c\x00\x80\x3a\x8c\x8f\x76\xad\x97\x6e\x6d\x6e\xbe\x6e\x76\x6e\x7d\x80"..., 4473) = 4473
  103. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 40827, [40827], SEEK_SET) = 0
  104. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x60\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x6e\x1e\x80\x3e\x00\x80\x3c\x88\xbf\x76\x6e\x6d\x6d\x6e\x97\x1c\x80\x3c\x00\x80\x3a\x82\x76\x97\x03\x6d\x87\xbe\x6e\x76\x96\x6e\x1e\x6d\x80"..., 4472) = 4472
  105. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 45299, [45299], SEEK_SET) = 0
  106. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x3d\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x6e\x1e\x80\x3e\x00\x80\x3c\x88\xbf\x76\x6e\x6d\x6e\x76\x97\x6d\x80\x3c\x00\x80\x3a\x8c\xbf\x1e\x6c\x6d\x6d\x6e\x6d\x76\x6e\x97\x1c\x76\x80"..., 4437) = 4437
  107. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 49736, [49736], SEEK_SET) = 0
  108. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\xb7\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x04\x1f\x80\x3e\x00\x80\x3c\x08\x1f\x80\x3c\x00\x80\x3a\x0c\x1f\x80\x3a\x00\x80\x38\x10\x1f\x80\x38\x00\x80\x36\x14\x1f\x80\x36\x00\x80\x34\x18\x1f\x80"..., 463) = 463
  109. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 50199, [50199], SEEK_SET) = 0
  110. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x83\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x6e\x1e\x80\x3e\x00\x80\x3c\x88\xbf\x76\x6e\x6d\x6e\x76\x76\x6e\x80\x3c\x00\x80\x3a\x84\xbf\x76\x6e\x76\x04\x6d\x84\x6e\x76\x7d\x97\x80\x3a"..., 4251) = 4251
  111. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 54450, [54450], SEEK_SET) = 0
  112. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\xe6\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x6e\x1e\x80\x3e\x00\x80\x3c\x88\xbf\x76\x6e\x6d\x6e\x76\x76\x6e\x80\x3c\x00\x80\x3a\x84\xbf\x76\x6e\x76\x04\x6d\x84\x6e\x76\x7d\x97\x80\x3a"..., 4350) = 4350
  113. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 58800, [58800], SEEK_SET) = 0
  114. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\x9e\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x6e\x1e\x80\x3e\x00\x80\x3c\x88\xbf\x76\x6e\x6d\x6e\x76\x76\x6e\x80\x3c\x00\x80\x3a\x84\xbf\x76\x6e\x76\x04\x6d\x84\x6e\x76\x7d\x97\x80\x3a"..., 4278) = 4278
  115. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 63078, [63078], SEEK_SET) = 0
  116. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\xd1\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x6e\x1e\x80\x3e\x00\x80\x3c\x88\xbf\x76\x6e\x6d\x6e\x76\x76\x6e\x80\x3c\x00\x80\x3a\x84\xbf\x76\x6e\x76\x04\x6d\x84\x6e\x76\x7d\x97\x80\x3a"..., 4329) = 4329
  117. _llseek(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, 67407, [67407], SEEK_SET) = 0
  118. read(36</home/lupine/.wine/drive_c/GOG Games/ChaosGate/Obj/jungtil.obj>, "\xd1\x00\x42\x01\x80\x00\x3f\x00\x00\x00\x00\x00\xd1\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3e\x84\x6d\x6c\x6e\x1e\x80\x3e\x00\x80\x3c\x88\xbf\x76\x6e\x6d\x6e\x76\x76\x6e\x80\x3c\x00\x80\x3a\x84\xbf\x76\x6e\x76\x04\x6d\x84\x6e\x76\x7d\x97\x80\x3a"..., 4329) = 4329
  119. Assign/h_jung4.asn
  120. Obj/h_jung4.obj
  121. (more assign + obj pairs)
  122. Data/Cycle.cyc

jungtil.asn references 18 frames (0-17) and a jungtil.flc, which is an AutoDesk format

We read jungtil.obj in about that number of blocks. Presumably each is a frame in some format or another, but seemingly not FLC.

Here's our list of reads:

Offset Size Gap Purpose
0 32 0 Main header
32 144 0 Frame headers
176 463 0 Frame 1
639 4466 0 ...
5105 4437 0
9542 4468 0
14010 4470 0
18480 4461 0
22941 4472 0
27413 4464 0
31877 4477 0
36354 4473 0
40827 4472 0
45299 4437 0
49736 463 0
50199 4251 0
54450 4350 0
58800 4278 0
63078 4329 0
67407 4329 0 Frame 18

20 reads in total.

The following chunks are identical:

*   176 and 49736 (all  463-byte frames)
* 63078 and 67407 (all 4329-byte frames)

Here's the hex of the first 32 bytes:

         0  1  2  3   4  5  6  7   8  9  a  b   c  d  e  f
0x0000  12 00 00 00  20 00 00 00  90 00 00 00  B0 00 00 00
0x0010  88 17 01 00  00 00 00 00  00 00 00 00  00 00 00 00
  • Offset 0 = 0x12 = 18 = the total number of frames ?
  • Offset 4 = 0x20 = 32 = the size of the this block ?
  • Offset 8 = 0x90 = 144 = the size of the next block ?
  • Offset c = 0xB0 = 176 = the offset of the third read, or the size of the first two blocks combined ?

Need to unpack a few more objs to check what these numbers do. They could all be 32-bit LE integers too.

0x10-0x13 as a 32-bit LE is 71560.

Total file size (71736) - 32 - 144 = 71560 = size of all frames combined

Obj/j_tree02.obj doesn't seem to adhere to these rules at all...

Then the next 144 bytes:

         0  1  2  3   4  5  6  7
0x0020  00 00 00 00  CF 01 00 00 =    0,  463
0x0028  CF 01 00 00  72 11 00 00 =  463, 4466
0x0030  41 13 00 00  55 11 00 00 = 4929, 4437
0x0038  96 24 00 00  74 11 00 00 = ...
0x0040  0A 36 00 00  76 11 00 00
0x0048  80 47 00 00  6D 11 00 00
0x0050  ED 58 00 00  78 11 00 00
0x0058  65 6A 00 00  70 11 00 00
0x0060  D5 7B 00 00  7D 11 00 00
0c0068  52 8D 00 00  79 11 00 00
0x0070  CB 9E 00 00  78 11 00 00
0x0078  43 B0 00 00  55 11 00 00
0x0080  98 C1 00 00  CF 01 00 00
0x0088  67 C3 00 00  9B 10 00 00
0x0090  02 D4 00 00  FE 10 00 00
0x0098  00 E5 00 00  B6 10 00 00
0x00A0  B6 F5 00 00  E9 10 00 00
0x00A8  9F 06 01 00  E9 10 00 00

8 bytes per frame (8*18=144).

First four bytes in each line are the position relative to the start of the first frame (i.e., minus the size of the first two blocks).

Last four bytes in each line are the total size of the frame, header + data.

Then there are 18 blocks of varying size. These must be the frames. First 32 bytes of all 18 blocks has a lot of similarities:

            0  1  2  3   4  5  6  7   8  9  a  b   c  d  e  f  10 11 12 13  14 15 16 17  18 19 1a 1b  1c 1d 1e 1f  (0c,0d)  (18,19)  (1a,1b)  (1c,1d)  (1e,1f)
00176.0463 D1 00 42 01  80 00 3F 00  00 00 00 00  B7 01 00 00  00 00 00 00  00 00 00 00  80 3E 04 1F  80 3E 00 80   439      16000    7940     16000    32768
00639.4466 D1 00 42 01  80 00 3F 00  00 00 00 00  5A 11 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 6E 1E 80  4442      16000    28036    28268    32798
05105.4437 D1 00 42 01  80 00 3F 00  00 00 00 00  3D 11 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 6E 1E 80  4413      16000    28036    28268    32798
09542.4468 D1 00 42 01  80 00 3F 00  00 00 00 00  5C 11 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 76 7E 80  4444      16000    28036    30316    32894
14010.4470 D1 00 42 01  80 00 3F 00  00 00 00 00  5E 11 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 6E 1E 80  4446      16000    28036    28268    32798
18480.4461 D1 00 42 01  80 00 3F 00  00 00 00 00  55 11 00 00  00 00 00 00  00 00 00 00  80 3E 84 65  6E 1E 7C 80  4437      16000    25988     7790    32892
22941.4472 D1 00 42 01  80 00 3F 00  00 00 00 00  60 11 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 6E 1E 80  4448      16000    28036    28268    32798
27413.4464 D1 00 42 01  80 00 3F 00  00 00 00 00  58 11 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  76 76 1E 80  ...       16000    28036    30326    32798
31877.4477 D1 00 42 01  80 00 3F 00  00 00 00 00  65 11 00 00  00 00 00 00  00 00 00 00  80 3E 84 6C  6E 97 1C 80            16000    27780    38766    32796
36354.4473 D1 00 42 01  80 00 3F 00  00 00 00 00  61 11 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 6E 1E 80            16000    28036    28268    32798
40827.4472 D1 00 42 01  80 00 3F 00  00 00 00 00  60 11 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 6E 1E 80            16000    28036    28268    32798
45299.4437 D1 00 42 01  80 00 3F 00  00 00 00 00  3D 11 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 6E 1E 80            16000    28036    28268    32798
49736.0463 D1 00 42 01  80 00 3F 00  00 00 00 00  B7 01 00 00  00 00 00 00  00 00 00 00  80 3E 04 1F  80 3E 00 80            16000     7940    16000    32768
50199.4251 D1 00 42 01  80 00 3F 00  00 00 00 00  83 10 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 6E 1E 80            16000    28036    28268    32798
54450.4350 D1 00 42 01  80 00 3F 00  00 00 00 00  E6 10 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 6E 1E 80            16000    28036    28268    32798
58800.4278 D1 00 42 01  80 00 3F 00  00 00 00 00  9E 10 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 6E 1E 80            16000    28036    28268    32798
63078.4329 D1 00 42 01  80 00 3F 00  00 00 00 00  D1 10 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 6E 1E 80            16000    28036    28268    32798
67407.4329 D1 00 42 01  80 00 3F 00  00 00 00 00  D1 10 00 00  00 00 00 00  00 00 00 00  80 3E 84 6D  6C 6E 1E 80            16000    28036    28268    32798
             IDENTICAL    IDENTICAL    IDENTICAL     LE SIZE?    IDENTICAL    IDENTICAL
V            21102801      4128896        0
vv          [209, 322]    [128, 63]      [0,0]

Remainder of each block is highly variable, so probably pixel data, and (some of?) these 32 bytes are header data

bytes 4-7 could be dimension?

Tiles are 64x64 pixels (I think?), displayed in an isometric fashion, so I am wrong or it's something else.

bytes 12 & 13 as LE 16-bit (or 12-15 as LE 32-bit) is always 24 bytes under full block size.

Perhaps we have 24 bytes of header and that's the header-exclusive pixel data size? Last 8 bits would then actually be the start of the image, but there's a lot of similarity between them...

Now, how to convert the pixel data to an image?!?!

Description
Unofficial remake of the classic game, Warhammer 40K: Chaos Gate. Ordoor = Order Door = Chaos Gate. Obviously.
Readme 59 MiB
Languages
Go 94.4%
Ruby 5.2%
Makefile 0.4%