Members UndercoverBoy833 Posted August 2 Author Members Posted August 2 (edited) 23 hours ago, Taruncreation said: Apparently, the only possible way I see to get some decent working asset from Asphalt Legends Unite would be using Ninja Ripper. I got my hands on the latest version and gave it a go...it's bit messy indeed but yeah it works! are the rippings in a 1:1 scale, dimensions and no skewed model after using Ninja Ripper and import the scene into blender? Btw thx for the response. In fact I wanna collect more of Asphalt Legends Unite all unicorn cars as of today and from recent updates of the games Edited August 2 by UndercoverBoy833
Taruncreation Posted August 2 Posted August 2 (edited) 4 hours ago, UndercoverBoy833 said: are the rippings in a 1:1 scale, dimensions and no skewed model after using Ninja Ripper and import the scene into blender? Btw thx for the response. In fact I wanna collect more of Asphalt Legends Unite all unicorn cars as of today and from recent updates of the games Yeah, as I said it's messy...since I am ripping from the Garage scene...it comes with wheels turned right and also the whole geometry sort of rotated by a few angles on all axis...I have attached the original model and the one I tried to edit a bit...might wanna check different channels for correct UV...textures and UV are fine tho. Arash Imperium Edited August 2 by Taruncreation
Engineers h3x3r Posted August 5 Engineers Posted August 5 (edited) Here's 010 editor template for jtex files. I will write bms for decompress + noesis for preview later... LittleEndian();OutputPaneClear(); local uint32 i,j,k,l,m,n,TotalFileSize=FileSize(); local string FileName=GetFileName(),FilePath=FileNameGetPath(FileName,true),BaseName=FileNameGetBase(FileName,false); struct { ubyte Version; char JTEXSign[4]; uint32 Unknown_0; uint32 Unknown_1; }Header; struct { uint32 TextureTableSize; uint32 TextureInfoSize; uint32 Unknown_0; uint16 Unknown_1; struct { uint16 TextureWidth; uint16 TextureHeight; ubyte Unknown_0; ubyte PixelFormat; ubyte Unknown_1; ubyte Unknown_2; uint16 Unknown_3; ubyte Unknown_4; ubyte MipMap; uint32 Unknown_5; float Unknown_6; float Unknown_7; uint16 TextureWidth_t; uint16 TextureHeight_t; struct { uint32 MipMapTableSize; uint32 MipMapInfoSize; uint32 Unknown_0; uint16 Unknown_1; struct { uint32 MipMapBlockSize; uint32 CompressedSize; // - 8 uint32 DecompressedSize; ubyte CompFlag; ubyte Unknown_1; uint32 Unknown_2; float Unknown_3; if (CompFlag == 0) byte Buffer[DecompressedSize]; else byte ZSDTBuffer[CompressedSize - 8]; }MipMapInfo[MipMap]<optimize=false>; }MipMapTable; }TextureInfo; }TextureTable; Edited August 5 by h3x3r 2
Engineers h3x3r Posted August 6 Engineers Posted August 6 (edited) I checked jmox files but mesh needs transformation... Here's quick sum up content of *.pack archives. main = ? > mixed mdc = jmox > models cars mde = jmox > models environment so = xvs > sounds lm = jtex > textures prb = jtex > textures gin = jtex > textures Edited August 6 by h3x3r 2
Engineers h3x3r Posted August 8 Engineers Posted August 8 Well so here's everything I know so far. Models are pain. Can't figure out monstrous table which has info about buffer id, vertex count, index count. I output only element buffers. I only know about vertex buffer. At cars they are mostly 8 bytes stride, int16 data type. Not sure what are others buffers. But they have type id. Textures on the other hand are simple. You can get pretty much all of them. I also looked into the sound files. Some are wav, but most of them are unexplored... need some time to research. Also those wav files are named by id which is described in track_table file which is also unexplored yet... So here's bms script. You can use it on any file from *.pack file which you can unpack with 7Zip. Spoiler ############################## #### Asphalt 9 Legends PC #### ############################## get BaseFileName basename get Version ubyte getdstring Sign 0x3 if Sign == jte CallFunction jtex_unpack elif Sign == jmo CallFunction jmox_unpack elif Sign == xvs CallFunction xvs_unpack elif Sign == oxa CallFunction voxarch_unpack elif Sign == jcl CallFunction jclx_unpack elif Sign == jan CallFunction janx_unpack endif StartFunction jtex_unpack comtype zstd goto 0 # Header get Version ubyte getdstring JTEXSign 0x4 get Unknown_0 uint32 get Unknown_1 uint32 # Texture Table get TextureTableSize uint32 get TextureInfoSize uint32 get Unknown_0 uint32 get Unknown_1 ushort # Texture Info get TextureWidth ushort get TextureHeight ushort get Unknown_0 ubyte get PixelFormat ubyte get Unknown_1 ubyte get Unknown_2 ubyte get Unknown_3 ushort get Unknown_4 ubyte get MipMap ubyte get Unknown_5 uint32 get Unknown_6 float get Unknown_7 float get TextureWidth_t ushort get TextureHeight_t ushort # MipMap Table get MipMapTableSize uint32 get MipMapInfoSize uint32 get Unknown_0 uint32 get Unknown_1 ushort # MipMap Info get MipMapBlockSize uint32 get CompressedSize uint32 math CompressedSize - 8 get DecompressedSize uint32 get CompFlag ubyte get Unknown_1 ubyte get Unknown_2 uint32 get Unknown_3 float savepos Offset string Name p "_Unpacked/textures/%s.jtex" BaseFileName if CompFlag == 0 append 0 log Name 27 6 log Name 77 4 log Name Offset DecompressedSize else append 0 log Name 27 6 log Name 77 4 clog Name Offset CompressedSize DecompressedSize endif EndFunction StartFunction jmox_unpack comtype zstd goto 0 # Header get Version ubyte getdstring JMOXSign 0x6 get Unknown_0 uint32 get Unknown_1 uint32 # Resource Info get Unknown_0 ushort get Unknown_1_Offset uint32 get Unknown_1_Count ushort get Unknown_2_Offset uint32 get Unknown_2_Count ushort get ChunkInfoOffset uint32 get ChunkCount ushort get Unknown_3_Offset uint32 get Unknown_3_Count uint32 get Unknown_4 uint32 get Unknown_5 uint32 goto ChunkInfoOffset for i = 0 < ChunkCount get ElementType ubyte get Unknown_1 ubyte get CompressedSize uint32 get DecompressedSize uint32 savepos Offset if CompressedSize != 0 getdstring Data CompressedSize endif string Name p "_Unpacked/%s/models/buffer_id_%u_element_type_%u.dat" BaseFileName i ElementType if CompressedSize != 0 clog Name Offset CompressedSize DecompressedSize endif next i EndFunction StartFunction xvs_unpack goto 0 # Header get Version ubyte getdstring XVSSign 0x3 get InfoOffset uint32 getdstring Unknown 0x8 # Resource Table Info get DataOffset uint32 get TotalFileSize uint32 getdstring Sign 0x4 get ResourceTableSize uint32 # Resource Info get ResourceCount uint32 for i = 0 < ResourceCount get TrackId uint32 get Channels uint32 get Frequency uint32 get ResourceOffset uint32 get ResourceSize uint32 get UncompressedSize uint32 get Unknown_0 uint32 get Unknown_1 float get Unknown_2 uint32 math ResourceOffset + DataOffset string Name p "_Unpacked/%s/sounds/track_%u.wav" BaseFileName TrackId log Name ResourceOffset ResourceSize next i savepos TrackTableOffset xmath TrackTableSize "DataOffset - TrackTableOffset" string Name p "_Unpacked/%s/sounds/track_table.dat" BaseFileName log Name TrackTableOffset TrackTableSize EndFunction StartFunction voxarch_unpack goto 0 # Header getdstring VOXARCHSign 0x8 get Unknown_0 uint32 get Unknown_1 uint32 # Resource Table Info get ResourceCount uint32 get NameSectionSize uint32 get ResourceTableOffset uint32 get Unknown_0_Offset uint32 get NameSectionTableOffset uint32 get Unknown_1_Offset uint32 get NameSectionOffset uint32 get Unknown_2 uint32 get Unknown_3 uint32 get Unknown_4_Offset uint32 get Unknown_5_Offset uint32 get SoundDefinitionOffset uint32 goto ResourceTableOffset # Resource Info for i = 0 < ResourceCount get Unknown_0 uint32 get Unknown_1 uint32 get ResourceSize[i] uint32 get ResourceOffset[i] uint32 next i goto NameSectionTableOffset # Resource Name Info for i = 0 < ResourceCount get ResourceNameOffset uint32 math ResourceNameOffset + NameSectionOffset savepos cPos goto ResourceNameOffset get FileName[i] string goto cPos next i goto SoundDefinitionOffset get DefinitionName string for i = 0 < ResourceCount string Name p "_Unpacked/%s/sounds/%s/%s" BaseFileName DefinitionName FileName[i] log Name ResourceOffset[i] ResourceSize[i] next i EndFunction StartFunction jclx_unpack comtype zstd goto 0 # Header get Version ubyte getdstring JCLXSign 0x6 get Unknown_0 uint32 get Unknown_1 uint32 # Resource Info get Unknown_0 uint32 get Unknown_1 ubyte get Unknown_2 uint32 get Unknown_3 uint32 get CompressedSize uint32 get DecompressedSize uint32 savepos Offset string Name p "_Unpacked/%s.jclx" BaseFileName clog Name Offset CompressedSize DecompressedSize EndFunction StartFunction janx_unpack comtype zstd goto 0 # Header get Version ubyte getdstring JANXSign 0x6 get Unknown_0 uint32 get Unknown_1 ushort get Unknown_2 ushort # Resource Info get ResourceCount ubyte for i = 0 < ResourceCount get Unknown_0 uint32 get CompressedSize uint32 get DecompressedSize uint32 savepos Offset getdstring ZSTDBuffer CompressedSize string Name p "_Unpacked/%s/%u.janx" BaseFileName i clog Name Offset CompressedSize DecompressedSize next i EndFunction And here's Noesis for *.jtex files. from inc_noesis import * import noesis import rapi import os def registerNoesisTypes(): handle = noesis.register("Asphalt 9 Legends - Texture", ".jtex") noesis.setHandlerTypeCheck(handle, noepyCheckType) noesis.setHandlerLoadRGBA(handle, noepyLoadRGBA) noesis.logPopup() return 1 def noepyCheckType(data): bs = NoeBitStream(data) if len(data) < 20: return 0 return 1 def noepyLoadRGBA(data, texList): bs = NoeBitStream(data) baseName = rapi.getExtensionlessName(rapi.getLocalFileName(rapi.getInputName())) TextureWidth = bs.readUShort() TextureHeight = bs.readUShort() bs.read(1) PixelFormat = bs.readUByte() BufferSize = bs.readUInt() data = bs.readBytes(BufferSize) if PixelFormat == 34: print("Pixel Format > BC7 ", PixelFormat) elif PixelFormat == 35: print("Pixel Format > BC6H ", PixelFormat) elif PixelFormat == 36: print("Pixel Format > BC5 ", PixelFormat) elif PixelFormat == 5: print("Pixel Format > RGB8", PixelFormat) elif PixelFormat == 6: print("Pixel Format > RGBA8", PixelFormat) else: print("Unknown Pixel Format > ", PixelFormat) if PixelFormat == 34: data = rapi.imageDecodeDXT(data, TextureWidth, TextureHeight, noesis.FOURCC_BC7) texFmt = noesis.NOESISTEX_RGBA32 elif PixelFormat == 35: data = rapi.imageDecodeDXT(data, TextureWidth, TextureHeight, noesis.FOURCC_BC6H) texFmt = noesis.NOESISTEX_RGBA32 elif PixelFormat == 36: data = rapi.imageDecodeDXT(data, TextureWidth, TextureHeight, noesis.FOURCC_BC5) texFmt = noesis.NOESISTEX_RGBA32 elif PixelFormat == 5: texFmt = noesis.NOESISTEX_RGB24 elif PixelFormat == 6: texFmt = noesis.NOESISTEX_RGBA32 texList.append(NoeTexture(rapi.getInputName(), TextureWidth, TextureHeight, data, texFmt)) return 1 2
DKDave Posted August 8 Posted August 8 I also looked at these a while ago. It uses the same jmox format as Speedstorm, so decompressing the data blocks is the easy part. However, the actual info table at the end of the file is weird. As mentioned above, it contains lots of unknown data, but it does have the submesh info. Not sure if there's a model script for Speedstorm, but it might be compatible if you can find one.
Engineers h3x3r Posted August 9 Engineers Posted August 9 (edited) Well i searched for pattern and found exact count of Table_3. But size of each info varies. Anyway there's a script by Durik, but not for free. Edited August 9 by h3x3r
RandomGuy Posted Wednesday at 07:25 PM Posted Wednesday at 07:25 PM On 8/2/2025 at 5:27 PM, Taruncreation said: Yeah, as I said it's messy...since I am ripping from the Garage scene...it comes with wheels turned right and also the whole geometry sort of rotated by a few angles on all axis...I have attached the original model and the one I tried to edit a bit...might wanna check different channels for correct UV...textures and UV are fine tho. Arash Imperium Would you mind sending the model for the formula e gen 3 evo? 🙏
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now