Skip to content
View in the app

A better way to browse. Learn more.

ResHax

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Help us keep the site running.
Zero Tolerance for Disrespect

Deadly Premonition PC .XMD

Featured Replies

  • Localization

Hello I am trying to see models from Deadly Premonition From PC any way how to rip them? thanks!
Here are some Xmds of some models from 01_PL
Some rough ideas judging from XPCs
CPL011- Agent
CPL0112- Workaholic
Okay Figured out how to send the folder
https://drive.google.com/file/d/1Gyx_pUYpQC-w-0PWVtkX2hw6L10T9A3D/view?usp=sharing

CPL013A.zip

Edited by Sirduckdude

Solved by h3x3r

  • Supporter
//------------------------------------------------
//--- 010 Editor v14.0 Binary Template
//
//      File: 
//   Authors: 
//   Version: 
//   Purpose: 
//  Category: 
// File Mask: 
//  ID Bytes: 
//   History: 
//------------------------------------------------
char Sign[4];
uint32 TotalFileSize;

if (Sign == "XPC2")
{
    uint16 ResourceCount;
    uint16 Unknown_0;
    uint32 Unknown_1;
    uint32 Unknown_2;
    uint32 Reserved[3];
    uint32 ResourceDefOffset;
    uint32 ResourceDataBaseOffset;
    
    FSeek(ResourceDefOffset);
    struct
    {
        char ResourceName[16];
        uint32 ResourceOffset;
        uint32 ResourceZSize;
        uint16 WBits;
        uint16 CompFlag;
        ubyte Flags[4];
    }ResourceDefinition[ResourceCount];
}
else if (Sign == "XZP1")
{
    uint32 ResourceZSize;
    uint32 ResourceSize;
    byte ZLibData[ResourceZSize];
}

BMS

##############################
get BaseFileName basename
get FileSize asize
get FileExtension extension

getdstring Sign 0x4
get TotalFileSize uint32

if Sign == "XPC2"
	comtype zlib_noerror
	get ResourceCount ushort
	getdstring Dummy 0x16
	get ResourceDefOffset uint32
	get ResourceDataBaseOffset uint32

	goto ResourceDefOffset
	
	for i = 0 < ResourceCount
		getdstring ResourceName 0x10
		get ResourceOffset uint32
		get ResourceZSize uint32
		get WBits ushort
		get CompFlag ushort
		getdstring Flags 0x4
		
		string Name p "%s/%s" BaseFileName ResourceName
		if CompFlag == 0
			log Name ResourceOffset ResourceZSize
		else
			clog Name ResourceOffset ResourceZSize ResourceZSize
		endif
	next i
	
elif Sign == "XZP1"
	get ResourceZSize uint32
	get ResourceSize uint32
	savepos ResourceOffset
	string Name p "%s/%s.%s" BaseFileName BaseFileName FileExtension
	clog Name ResourceOffset ResourceZSize ResourceSize
endif


Edited by h3x3r

  • Author
  • Localization
1 hour ago, h3x3r said:
//------------------------------------------------
//--- 010 Editor v14.0 Binary Template
//
//      File: 
//   Authors: 
//   Version: 
//   Purpose: 
//  Category: 
// File Mask: 
//  ID Bytes: 
//   History: 
//------------------------------------------------
char Sign[4];
uint32 TotalFileSize;

if (Sign == "XPC2")
{
    uint16 ResourceCount;
    uint16 Unknown_0;
    uint32 Unknown_1;
    uint32 Unknown_2;
    uint32 Reserved[3];
    uint32 ResourceDefOffset;
    uint32 ResourceDataBaseOffset;
    
    FSeek(ResourceDefOffset);
    struct
    {
        char ResourceName[16];
        uint32 ResourceOffset;
        uint32 ResourceZSize;
        uint16 WBits;
        uint16 CompFlag;
        ubyte Flags[4];
    }ResourceDefinition[ResourceCount];
}
else if (Sign == "XZP1")
{
    uint32 ResourceZSize;
    uint32 ResourceSize;
    byte ZLibData[ResourceZSize];
}

BMS

##############################
get BaseFileName basename
get FileSize asize
get FileExtension extension

getdstring Sign 0x4
get TotalFileSize uint32

if Sign == "XPC2"
	comtype zlib_noerror
	get ResourceCount ushort
	getdstring Dummy 0x16
	get ResourceDefOffset uint32
	get ResourceDataBaseOffset uint32

	goto ResourceDefOffset
	
	for i = 0 < ResourceCount
		getdstring ResourceName 0x10
		get ResourceOffset uint32
		get ResourceZSize uint32
		get WBits ushort
		get CompFlag ushort
		getdstring Flags 0x4
		
		string Name p "%s/%s" BaseFileName ResourceName
		if CompFlag == 0
			log Name ResourceOffset ResourceZSize
		else
			clog Name ResourceOffset ResourceZSize ResourceZSize
		endif
	next i
	
elif Sign == "XZP1"
	get ResourceZSize uint32
	get ResourceSize uint32
	savepos ResourceOffset
	string Name p "%s/%s.%s" BaseFileName BaseFileName FileExtension
	clog Name ResourceOffset ResourceZSize ResourceSize
endif


Yea! nice I can get the textures A bit more quicker now! though still don't know how to find the models but thanks!image.png

  • Supporter
  • Solution

Working on it...

image.png

But struggling with decompression via noesis. You need to use BMS first to decompress *.XMD. Or maybe i'll figure out.

EDiT: Figured out. Now you don't need to decompress model...

Here we go...

# Script by h3x3r

from inc_noesis import *
import noesis
import rapi
import os

def registerNoesisTypes():
   handle = noesis.register("Deadly Premonition - XMD Mesh", ".xmd")
   noesis.setHandlerTypeCheck(handle, noepyCheckType)
   noesis.setHandlerLoadModel(handle, noepyLoadModel)
   noesis.logPopup()
   return 1
        
def noepyCheckType(data):
	bs = NoeBitStream(data)
	bs.read(8)
	CSize = bs.readUInt()
	Size = bs.readUInt()
	Buffer = bs.read(CSize)
	data = rapi.decompInflate(Buffer,Size)
    
	bs = NoeBitStream(data)
    
	if len(data) < 20:
	    return 0
	if bs.readUInt() != 0x33444D58:
	    return 0
	return 1
        
def noepyLoadModel(data, mdlList):
	bs = NoeBitStream(data)
	bs.read(8)
	CSize = bs.readUInt()
	Size = bs.readUInt()
	Buffer = bs.read(CSize)
	data = rapi.decompInflate(Buffer,Size)
    
	bs = NoeBitStream(data)
	baseName = rapi.getExtensionlessName(rapi.getLocalFileName(rapi.getInputName()))
	ctx = rapi.rpgCreateContext()
	Underline = "_"
    
    # Main Info
	Sign = bs.read(4)
	ResourceSize = bs.readUInt()
	TotalIndexCount = bs.readUInt()
	TotalElementCount = bs.readUInt()
	Unknown_2 = bs.readUInt()
	Reserved0 = bs.read(20)
	Unknown_3 = bs.readUShort()
	BoneCount = bs.readUShort()
	ShapeCount = bs.readUInt()
	Unknown_4 = bs.readUInt()
	Unknown_5 = bs.readUByte()
	Unknown_6 = bs.readUByte()
	Unknown_7 = bs.readUByte()
	Unknown_8 = bs.readUByte()
	Unknown_9 = bs.readUByte()
	ElementStride = bs.readUByte()
	NormalSkinStride = bs.readUByte()
	Unknown_12 = bs.readUByte()
	Reserved1 = bs.readUInt()
	BBoxMin = bs.read(12)
	BBoxMax = bs.read(12)
	Unknown_13 = bs.readUShort()
	Unknown_14_Count = bs.readUShort()
	Unknown_15 = bs.readUInt()
	Unknown_16 = bs.readUInt()
	MaterialDefOffset = bs.readUInt()
	BoneDefOffset = bs.readUInt()
	ShapeDefOffset = bs.readUInt()
	Unknown_17 = bs.readUInt()
	Unknown_18 = bs.readUInt()
	UnknownDefOffset = bs.readUInt()
	Reserved2 = bs.read(16)
	IndexBufferBaseOffset = bs.readUInt()
	ElementBufferBaseOffset = bs.readUInt()
	NormalSkinBufferBaseOffset = bs.readUInt()
	Reserved3 = bs.read(16)
	Unknown_14_Offset = bs.readUInt()
	print("Element Stride >",ElementStride,"NormalSkin Stride >",NormalSkinStride)
    
    # Material Info
	bs.seek(MaterialDefOffset, NOESEEK_ABS)
	MaterialName = bs.readString()
	rapi.rpgSetMaterial(MaterialName)
    
    # Shape Info
	bs.seek(ShapeDefOffset, NOESEEK_ABS)
	for i in range(0, ShapeCount):
		StrPos = bs.tell()
		ShapeName = bs.readString()
		bs.seek(StrPos, NOESEEK_ABS)
		bs.read(16)
		Unknown_0 = bs.readShort()
		BoneId = bs.readShort()
		Unknown_2 = bs.readUInt()
		Unknown_3 = bs.readUInt()
		BBoxMin = bs.read(12)
		BBoxMax = bs.read(12)
		IndexCount = bs.readUInt()
		ElementCount = bs.readUInt()
		IndexOffset = bs.readUInt() * 2
		ElementOffset = bs.readUInt()
		Unknown_4 = bs.readUInt()
		Reserved = bs.read(8)
		cPos = bs.tell()
		
        
		bs.seek(ElementBufferBaseOffset + (ElementOffset * ElementStride), NOESEEK_ABS)
		ElementBuffer = bs.read(ElementCount * ElementStride)
        
		if ElementStride == 20:
		    rapi.rpgBindPositionBufferOfs(ElementBuffer, noesis.RPGEODATA_HALFFLOAT, 20, 0)
		    rapi.rpgBindUV1BufferOfs(ElementBuffer, noesis.RPGEODATA_HALFFLOAT, 20, 8)
		elif ElementStride == 24:
		    rapi.rpgBindPositionBufferOfs(ElementBuffer, noesis.RPGEODATA_FLOAT, 24, 0)
		    rapi.rpgBindUV1BufferOfs(ElementBuffer, noesis.RPGEODATA_HALFFLOAT, 24, 12)
        
		bs.seek(NormalSkinBufferBaseOffset + (ElementOffset * NormalSkinStride), NOESEEK_ABS)
		NormalSkinBuffer = bs.read(ElementCount * NormalSkinStride)
        
		if NormalSkinStride == 12:
		    rapi.rpgBindNormalBufferOfs(NormalSkinBuffer, noesis.RPGEODATA_HALFFLOAT, 12, 0)
		    rapi.rpgBindBoneWeightBufferOfs(NormalSkinBuffer, noesis.RPGEODATA_HALFFLOAT, 12, 6, 3)
		elif NormalSkinStride == 16:
		    rapi.rpgBindNormalBufferOfs(NormalSkinBuffer, noesis.RPGEODATA_HALFFLOAT, 16, 0)
		    rapi.rpgBindBoneWeightBufferOfs(NormalSkinBuffer, noesis.RPGEODATA_HALFFLOAT, 16, 8, 3)
            
		bs.seek(IndexBufferBaseOffset + IndexOffset, NOESEEK_ABS)
		IndexBuffer = bs.read(IndexCount * 2)
		rapi.rpgSetStripEnder(0xFFFF)
		rapi.rpgSetName(ShapeName)
		rapi.rpgCommitTriangles(IndexBuffer, noesis.RPGEODATA_USHORT, IndexCount, noesis.RPGEO_TRIANGLE_STRIP)
        
		bs.seek(cPos, NOESEEK_ABS)
	mdl = rapi.rpgConstructModel()
	mdlList.append(mdl)
	return 1

No skin/bones/skeleton. Could be done later...

Edited by h3x3r

  • Author
  • Localization
5 hours ago, h3x3r said:

Working on it...

image.png

But struggling with decompression via noesis. You need to use BMS first to decompress *.XMD. Or maybe i'll figure out.

EDiT: Figured out. Now you don't need to decompress model...

Here we go...

# Script by h3x3r

from inc_noesis import *
import noesis
import rapi
import os

def registerNoesisTypes():
   handle = noesis.register("Deadly Premotion - XMD Mesh", ".xmd")
   noesis.setHandlerTypeCheck(handle, noepyCheckType)
   noesis.setHandlerLoadModel(handle, noepyLoadModel)
   noesis.logPopup()
   return 1
        
def noepyCheckType(data):
	bs = NoeBitStream(data)
	bs.read(8)
	CSize = bs.readUInt()
	Size = bs.readUInt()
	Buffer = bs.read(CSize)
	data = rapi.decompInflate(Buffer,Size)
    
	bs = NoeBitStream(data)
    
	if len(data) < 20:
	    return 0
	if bs.readUInt() != 0x33444D58:
	    return 0
	return 1
        
def noepyLoadModel(data, mdlList):
	bs = NoeBitStream(data)
	bs.read(8)
	CSize = bs.readUInt()
	Size = bs.readUInt()
	Buffer = bs.read(CSize)
	data = rapi.decompInflate(Buffer,Size)
    
	bs = NoeBitStream(data)
	baseName = rapi.getExtensionlessName(rapi.getLocalFileName(rapi.getInputName()))
	ctx = rapi.rpgCreateContext()
	Underline = "_"
    
    # Main Info
	Sign = bs.read(4)
	ResourceSize = bs.readUInt()
	TotalIndexCount = bs.readUInt()
	TotalElementCount = bs.readUInt()
	Unknown_2 = bs.readUInt()
	Reserved0 = bs.read(20)
	Unknown_3 = bs.readUShort()
	BoneCount = bs.readUShort()
	ShapeCount = bs.readUInt()
	Unknown_4 = bs.readUInt()
	Unknown_5 = bs.readUByte()
	Unknown_6 = bs.readUByte()
	Unknown_7 = bs.readUByte()
	Unknown_8 = bs.readUByte()
	Unknown_9 = bs.readUByte()
	ElementStride = bs.readUByte()
	Unknown_11 = bs.readUByte()
	Unknown_12 = bs.readUByte()
	Reserved1 = bs.readUInt()
	BBoxMin = bs.read(12)
	BBoxMax = bs.read(12)
	Unknown_13 = bs.readUShort()
	Unknown_14_Count = bs.readUShort()
	Unknown_15 = bs.readUInt()
	Unknown_16 = bs.readUInt()
	MaterialDefOffset = bs.readUInt()
	BoneDefOffset = bs.readUInt()
	ShapeDefOffset = bs.readUInt()
	Unknown_17 = bs.readUInt()
	Unknown_18 = bs.readUInt()
	UnknownDefOffset = bs.readUInt()
	Reserved2 = bs.read(16)
	IndexBufferBaseOffset = bs.readUInt()
	ElementBufferBaseOffset = bs.readUInt()
	NormalSkinBufferBaseOffset = bs.readUInt()
	Reserved3 = bs.read(16)
	Unknown_14_Offset = bs.readUInt()
    
    # Material Info
	bs.seek(MaterialDefOffset, NOESEEK_ABS)
	MaterialName = bs.readString()
	rapi.rpgSetMaterial(MaterialName)
    
    # Shape Info
	bs.seek(ShapeDefOffset, NOESEEK_ABS)
	for i in range(0, ShapeCount):
		StrPos = bs.tell()
		ShapeName = bs.readString()
		bs.seek(StrPos, NOESEEK_ABS)
		bs.read(16)
		Unknown_0 = bs.readShort()
		BoneId = bs.readShort()
		Unknown_2 = bs.readUInt()
		Unknown_3 = bs.readUInt()
		BBoxMin = bs.read(12)
		BBoxMax = bs.read(12)
		IndexCount = bs.readUInt()
		ElementCount = bs.readUInt()
		IndexOffset = bs.readUInt() * 2
		ElementOffset = bs.readUInt()
		Unknown_4 = bs.readUInt()
		Reserved = bs.read(8)
		cPos = bs.tell()
		
		bs.seek(ElementBufferBaseOffset + (ElementOffset * ElementStride), NOESEEK_ABS)
		ElementBuffer = bs.read(ElementCount * ElementStride)
		rapi.rpgBindPositionBufferOfs(ElementBuffer, noesis.RPGEODATA_HALFFLOAT, 20, 0)
		rapi.rpgBindUV1BufferOfs(ElementBuffer, noesis.RPGEODATA_HALFFLOAT, 20, 8)
        
		bs.seek(NormalSkinBufferBaseOffset + (ElementOffset * 16), NOESEEK_ABS)
		NormalSkinBuffer = bs.read(ElementCount * 16)
		rapi.rpgBindNormalBufferOfs(NormalSkinBuffer, noesis.RPGEODATA_HALFFLOAT, 16, 0)
		rapi.rpgBindBoneWeightBufferOfs(NormalSkinBuffer, noesis.RPGEODATA_HALFFLOAT, 16, 6, 3)
        
		bs.seek(IndexBufferBaseOffset + IndexOffset, NOESEEK_ABS)
		IndexBuffer = bs.read(IndexCount * 2)
		rapi.rpgSetStripEnder(0xFFFF)
		rapi.rpgSetName(ShapeName)
		rapi.rpgCommitTriangles(IndexBuffer, noesis.RPGEODATA_USHORT, IndexCount, noesis.RPGEO_TRIANGLE_STRIP)
        
		bs.seek(cPos, NOESEEK_ABS)
	mdl = rapi.rpgConstructModel()
	mdlList.append(mdl)
	return 1

No skin/bones/skeleton. Could be done later...

Omg thanks so much!!! seeing these models with out the weird filters is awesome! though other chara characters do give errors other than george sorry to bother i sent the CHARA folder fully from the google drive link if you need itimage.pngimage.png!

Edited by Sirduckdude

  • Supporter

Found the problem. There is variable NormalSkinStride.

Fixed! You can try now.

Edited by h3x3r

  • Author
  • Localization
29 minutes ago, h3x3r said:

Found the problem. There is variable NormalSkinStride.

Fixed! You can try now.

It works! Thanks!!!
image.png

  • Supporter

If anything went wrong just let me know.

BTW what about levels? Do you need them too? Maybe i can take a look.

Well i noticed there are also uncompressed models. Will update later.

Edited by h3x3r

  • Author
  • Localization
2 hours ago, h3x3r said:

If anything went wrong just let me know.

BTW what about levels? Do you need them too? Maybe i can take a look.

Well i noticed there are also uncompressed models. Will update later.

nah its fine since the maps are all in parts hopes the rigs are finable though!
I can try to send the Progammer_PC folder fully though if you wanna take a full look at it

got the entire folder of the extracts
https://drive.google.com/file/d/12seH5uJbhEhGp7gebx3zMAeQxJtVlDFu/view?usp=drive_link

Edited by Sirduckdude

  • Author
  • Localization
35 minutes ago, Sirduckdude said:

nah its fine since the maps are all in parts hopes the rigs are finable though!
I can try to send the Progammer_PC folder fully though if you wanna take a full look at it (its loading!)

also odd thing is the characters that did give errors merge all model lods ah wait i'm dumb I gotta import as fbx
image.png

Edited by Sirduckdude

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.