Jump to content

[Slayer Engine] Indiana Jones And The Emperor's Tomb (PC) - MSH AND MTX Files


Recommended Posts

  • ikskoks changed the title to Indiana Jones And The Emperor's Tomb (PC) - MSH AND MTX Files
  • ikskoks changed the title to [Slayer Engine] Indiana Jones And The Emperor's Tomb (PC) - MSH AND MTX Files
  • 2 weeks later...

Looks like there's a small problem which a better skilled person should be able to handle:

edit: the first submesh has 444 face indices only. Means a new sub mesh starts when a 0 appears in the bytestream of indices.

(There's some ugly DWords thrown in (two in a row= 8 bytes) which are harder to handle, see 2nd pic) bytes

indianahat-msh.png

 

uglyDWords.png

Edited by shak-otay
Link to comment
Share on other sites

  • 3 weeks later...

First, We Would Have To Start By Modifying The Vertex Of The 3D Model And After The Textures Without Using The TexMod With The DirectX 9.0 Or 8.0 Version shak-otay You Must Already Have Almost All The Vertex Listings For Indy's Hat, You Could Say How Many Vertex That 3D Model Has And Then It Goes With The Other One, That Would Be The First Step, Review The Vertex Listing Of Each 3D Model

Link to comment
Share on other sites

btw, is there any reason that you create a post for every single sentence?🙃

 

For the hat's H2O file: its parameters are in my first post as of November, 24th. But it's for the first sub mesh only.

If you read carefully you may understand that coding is required to get the whole hat.

Edited by shak-otay
Link to comment
Share on other sites

  • 3 weeks later...
On 11/27/2023 at 5:15 PM, Durik256 said:

I once made plugins for *.msh, *.mtx.

(not the easiest format. or maybe that was the case at the time)

532e96_a4eda54155d84e08b8ef4cd29334dd43mv2.png.66f7f2a1fee26a3982c49d93c1ac065e.png

100$ for a plugin to extract meshes from a nearly 21 year old game ? What a rip off. I wil try ninjaripper with this game, rather than pay this astronomical amount. Is the plugin able to export meshes back into msh, mtx and sls or is it only able to extract the meshes?

Link to comment
Share on other sites

  • 4 weeks later...

OK So here is bms only for unpack textures. You must also use bat command to merge header + raw data. I don't know how to append that dds header to the raw data.

######################################################
# Indiana Jones And The Emperors Tomb - *.mtx unpack #
######################################################

get BaseFileName basename

idstring "MULTITEX"
get Flag_0 uint16
get Flag_1 uint16
get Unknown_0 uint32
get Unknown_1 uint32
get TextureCount uint32
get TableSize uint32
get Unknown_2 uint32
get InfoSize uint32

for i = 0 < TextureCount
	get TextureId uint32
	
	if InfoSize == 120
		getdstring Dummy 0x4
	elif InfoSize == 128
		getdstring Dummy 0xC
	endif
	
	get Unknown_0 uint32
	get Unknown_1 uint16
	get Unknown_2 uint16
	savepos StrOffset
	get FileName string
	goto StrOffset
	getdstring Dummy 0x40
	get TextureWidth uint32
	get TextureHeight uint32
	get Unknown_3 uint32
	get Unknown_4 uint32
	getdstring Dummy 0x4
	get MipMapCount uint32
	get Unknown_5 uint32
	get PixelFormat uint32
	get BaseOffset uint32
	get DataSize uint32
	savepos TMP
	
	goto BaseOffset
	get LayerSize uint32
	savepos Offset
	string RAWNAME p "%s/%s.raw" BaseFileName FileName
	string HDRNAME p "%s/%s.dds" BaseFileName FileName
	
 	if PixelFormat == 0
 		set MEMORY_FILE binary "\x44\x44\x53\x20\x7C\x00\x00\x00\x0F\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x03\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\x20\x00\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\xFF\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
 		putVarChr MEMORY_FILE 0x10 TextureWidth long
 		putVarChr MEMORY_FILE 0xC TextureHeight long
		log HDRNAME 0 128 MEMORY_FILE
	elif PixelFormat == 1
		set MEMORY_FILE binary "\x44\x44\x53\x20\x7C\x00\x00\x00\x07\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x03\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\x20\x00\x00\x00\x04\x00\x00\x00\x44\x58\x54\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
		putVarChr MEMORY_FILE 0x10 TextureWidth long
		putVarChr MEMORY_FILE 0xC TextureHeight long
		log HDRNAME 0 128 MEMORY_FILE
	elif PixelFormat == 3
 		set MEMORY_FILE binary "\x44\x44\x53\x20\x7C\x00\x00\x00\x07\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x03\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\x20\x00\x00\x00\x04\x00\x00\x00\x44\x58\x54\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
 		putVarChr MEMORY_FILE 0x10 TextureWidth long
 		putVarChr MEMORY_FILE 0xC TextureHeight long
		log HDRNAME 0 128 MEMORY_FILE
 	elif PixelFormat == 5
 		set MEMORY_FILE binary "\x44\x44\x53\x20\x7C\x00\x00\x00\x07\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x03\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\x20\x00\x00\x00\x04\x00\x00\x00\x44\x58\x54\x35\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
 		putVarChr MEMORY_FILE 0x10 TextureWidth long
 		putVarChr MEMORY_FILE 0xC TextureHeight long
		log HDRNAME 0 128 MEMORY_FILE
 	endif
	
	log RAWNAME Offset LayerSize
	goto TMP
next i

After unpack create bat file and copy it to the folder with unpacked files and run. It will merge all files to the dds and deletes itself. So backup it.

Bat file to merge header + raw data

copy /b *.dds+*.raw *.dds

del *.raw
del create_dds.bat

Here's also 010 template from which was bms made.

//------------------------------------------------
//--- 010 Editor v14.0 Binary Template
//
//      File: 
//   Authors: 
//   Version: 
//   Purpose: 
//  Category: 
// File Mask: 
//  ID Bytes: 
//   History: 
//------------------------------------------------
OutputPaneClear();LittleEndian();
local string FileName=GetFileName(),FilePath=FileNameGetPath(FileName,true),BaseName=FileNameGetBase(FileName,false);
local uint32 i,j,k;

struct HEADER {
    char Sign[8];
    uint16 Flags[2];
    uint32 Unknown_0,Unknown_1,TextureCount,TableSize,Unknown_2,InfoSize;
};

struct FILETABLEINFO {
    struct FILEINFO {
        uint32 TextureId;
        if (Header.InfoSize == 120)
            uint32 FF[1];
        else if (Header.InfoSize == 128)
            uint32 FF[3];
        uint32 Unknown_0;
        uint16 Unknown_1,Unknown_2;
        local uint32 StrOffset=FTell();
        local string TextureName=ReadString(StrOffset,0);
        byte Dummy[64];
        uint32 TextureWidth,TextureHeight,Unknown_3,Unknown_4;
        ubyte Unknown_5[4];
        uint32 MipMapCount,Unknown_6,PixelFormat,FileOffset,FileSize;
    }FileInfo[Header.TextureCount]<optimize=false>;
};

struct FILEDATA {
for (i=0; i < Header.TextureCount; i++){
FSeek(FileTableInfo.FileInfo[i].FileOffset);
    struct DATA {
        struct MIPMAP {
            uint32 LayerSize;
            byte LayerData[LayerSize];
        }MipMap[FileTableInfo.FileInfo[i].MipMapCount]<optimize=false>;
    }Data;
    }
};

HEADER Header;
FILETABLEINFO FileTableInfo;
FILEDATA FileData;

And on top of that Noesis python script. But it has one flaw. First texture doesn't have original file name and I don't know how to fix it. But this is definitely better than bms because you can preview images before export.

from inc_noesis import *
import noesis
import rapi
import os

def registerNoesisTypes():
   handle = noesis.register("Indiana Jones and The Emperors Tomb", ".mtx")
   noesis.setHandlerTypeCheck(handle, noepyCheckType)
   noesis.setHandlerLoadRGBA(handle, noepyLoadRGBA)
   noesis.logPopup()
   return 1
        
def noepyCheckType(data):
   bs = NoeBitStream(data)
   if len(data) < 20:
      return 0
   if bs.readUInt64() != 0x58455449544C554D:
      return 0
   return 1
   
def noepyLoadRGBA(data, texList):
    bs = NoeBitStream(data)
    baseName = rapi.getExtensionlessName(rapi.getLocalFileName(rapi.getInputName()))
    Sign = bs.readBytes(8)
    Unknown_0 = bs.readUShort()
    Unknown_1 = bs.readUShort()
    Unknown_2 = bs.readUInt()
    Unknown_3 = bs.readUInt()
    TextureCount = bs.readUInt()
    TableSize = bs.readUInt()
    Unknown_4 = bs.readUInt()
    InfoSize = bs.readUInt()

    # Header End
    for i in range(TextureCount):
        TextureID = bs.readUInt()
        if InfoSize == 120:
            Unknown_0 = bs.readBytes(4)
        elif InfoSize == 128:
            Unknown_0 = bs.readBytes(12)
        Unknown_1 = bs.readUInt()
        Unknown_2 = bs.readUShort()
        Unknown_3 = bs.readUShort()
        NameStrOffset = bs.tell()
        FileNameStr = bs.readString()
        print(FileNameStr)
        bs.seek(NameStrOffset, NOESEEK_ABS)
        Dummy = bs.readBytes(64)
        TextureWidth = bs.readUInt()
        TextureHeight = bs.readUInt()
        Unknown_4 = bs.readUInt()
        Unknown_5 = bs.readUInt()
        Unknown_6 = bs.readBytes(4)
        MipMapCount = bs.readUInt()
        Unknown_7 = bs.readUInt()
        PixelFormat = bs.readUInt()
        DataOffset = bs.readUInt()
        FileSize = bs.readUInt()
        EndOfEntry = bs.tell()
        # Seek data
        bs.seek(DataOffset, NOESEEK_ABS)
        DataSize = bs.readUInt()
        data = bs.readBytes(DataSize)
        if PixelFormat == 0:
            texFmt = noesis.NOESISTEX_RGBA32
        elif PixelFormat == 1:
            texFmt = noesis.NOESISTEX_DXT1
        elif PixelFormat == 3:
            texFmt = noesis.NOESISTEX_DXT3
        elif PixelFormat == 5:
            texFmt = noesis.NOESISTEX_DXT5
        bs.seek(EndOfEntry, NOESEEK_ABS)
        texList.append(NoeTexture(FileNameStr, TextureWidth, TextureHeight, data, texFmt))
    return 1

 

Edited by h3x3r
Link to comment
Share on other sites

Silent Hill: Homecoming also uses Slayer Engine.

Maybe it could also help. I know something about mesh format and archive format from that game.

Noesis can also extract it's archive and view some character models and textures

Link to comment
Share on other sites

  • 2 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...