Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 04/17/2025 in Posts

  1. Python code to extract the texts: import struct, codecs BIN = "/mnt/data/menu_decompress.dat" OUT = "/mnt/data/menu_decompress_output.txt" be16 = lambda b, o: struct.unpack_from(">H", b, o)[0] le32 = lambda b, o: struct.unpack_from("<I", b, o)[0] be32 = lambda b, o: struct.unpack_from(">I", b, o)[0] def read_wstr_be(buf, off): raw = bytearray() while off + 1 < len(buf): val = be16(buf, off) off += 2 if val == 0: break raw += val.to_bytes(2, "big") return raw.decode("utf-16-be", errors="replace") with open(BIN, "rb") as f: data = f.read() p = 8 name_len = le32(data, p) p += 4 + name_len + 1 p += 1 + 4 + 4 + 20 + 4 + 8 base = p max_num = be16(data, p) p += 2 count = be16(data, p) p += 2 data_pos = p p += count * 4 num_blocks = be16(data, p) p += 2 tbl = p memo, visiting = {}, set() def tex(idx): if idx == 0: return "" if idx in memo: return memo[idx] if idx in visiting: memo[idx] = "" return "" visiting.add(idx) node_off = data_pos + idx * 4 if node_off + 3 >= len(data): visiting.remove(idx) memo[idx] = "" return "" right = be16(data, node_off) left = be16(data, node_off + 2) s = read_wstr_be(data, node_off) if left == 0 else tex(left) + tex(right) visiting.remove(idx) memo[idx] = s return s out = [] ptr = tbl for _ in range(num_blocks): if ptr + 12 > len(data): break data_u = be32(data, ptr + 4) + base loc = be32(data, ptr + 8) + base + 2 ptr += 12 if loc - 2 >= len(data): continue rec_cnt = be16(data, loc - 2) pos_tmp = data_u for r in range(rec_cnt + 1): ent_off = loc + r * 4 if ent_off + 1 >= len(data): break end = be16(data, ent_off) + data_u if end > len(data): break pos = pos_tmp buf = [] while pos < end: b = data[pos] if b < max_num: buf.append(tex(b + 1)) pos += 1 elif b < 255: val = be16(data, pos) - 255 * max_num buf.append(tex(val + 1)) pos += 2 else: # b == 255 val = be16(data, pos + 1) buf.append(tex(val + 1)) pos += 3 out.append("".join(buf)) pos_tmp = pos with codecs.open(OUT, "w", "utf-8") as f: f.write("\n".join(out)) I can also work on repack if I find spare time.
    5 points
  2. I'm working on a tool to modify existing models or import custom models into Horizon Forbidden West. So far my first test is to fix Aloy's face. I tried a few options, and now I'm sure it will work and looks good, and probably a few mods will be already released soon. Then after import tool is ready, it will be release here on reshax. Here are some example screens. First i reduced her cheeks to 70%, to be sure i can see difference. Since only face shape is changed, you can see the old "fat" shape of peachfuzz (which is not scaled down yet). And then i did 90%
    4 points
  3. Mod released: https://www.nexusmods.com/horizonforbiddenwest/mods/113
    4 points
  4. Ok, now my tool works fine with the original files. Usage: Run ExportText.exe, select *.cat file. BleachRoS_cat_ExportToolByGier.7z If you just need to decompress files, then use this script: comtype zlib get NAME basename get id longlong get SIZE long get ZERO long get OFFSET long get ZSIZE asize math ZSIZE - OFFSET string NAME += "_dec.cat" clog NAME OFFSET ZSIZE SIZE
    3 points
  5. Oh, here is my script. It is based in other script that I made before. A lot of PS2 games use that mesh format with tags, I just changed a few things here and there: fmt_legend_of_spyro_ps2_mdg.py
    2 points
  6. 2 points
  7. Small World is it? I was helping a spanish guy in Xentax discord about this exactly game a few days ago. I made a tool to unpack/pack descompress/compress LZSS compression. The tool is in Modern Portuguese, my native language, but is easy to understand. GsS_Lzss_Tool_v2.zip
    2 points
  8. Hello, for the Guardian_Fire dragon Dave's (DKDave?, dunno) script collects 997 small vertex chunks with 3 to 16 vertices, afaics. First 0080026C block has 11 elements in each sub block (0B000000 after first signature 0080026C). Vertex block signature is 02800B68, maybe the 0B is the count again (as it's known from vif signatures). I've rectangular bordered the first and last vertex of the first chunk in black, the green block seems to contain the uv data as shorts, tx, ty, unk1, unk2, so 11x8 bytes . edit: uvs ok so far (I think), except the for the garbage at the lower left corner:
    2 points
  9. O.K, here's Noesis script. Not sure how to assign material + texture to it. from inc_noesis import * import noesis import rapi import os def registerNoesisTypes(): handle = noesis.register("Bright Light", ".ea3") noesis.setHandlerTypeCheck(handle, noepyCheckType) noesis.setHandlerLoadModel(handle, noepyLoadModel) noesis.logPopup() return 1 def noepyCheckType(data): bs = NoeBitStream(data) if len(data) < 20: return 0 return 1 def noepyLoadModel(data, mdlList): bs = NoeBitStream(data) baseName = rapi.getExtensionlessName(rapi.getLocalFileName(rapi.getInputName())) ctx = rapi.rpgCreateContext() Underline = "_" # Header Start bs.read(4) # Sign TotalFileSize = bs.readUInt() MatrixOffset = bs.readUInt() MeshDataBaseOffset = bs.readUInt() # Base Offset bs.read(16) Matrix4x4 = bs.read(64) BBox = bs.read(32) Unknown_0 = bs.readUInt() UnknownOffset = bs.readUInt() MaterialIndex = bs.readUInt() MaterialIndexOffset = bs.readUInt() TextureCount = bs.readUInt() MaterialInfoOffset = bs.readUInt() Unknown_1 = bs.readUInt() Unknown_2 = bs.readUInt() BoneMatrixOffset = bs.readUInt() Unknown_3 = bs.readUInt() Unknown_4 = bs.readUInt() Unknown_5 = bs.readUInt() Unknown_6 = bs.readUInt() Unknown_7 = bs.readUInt() RootOffset = bs.readUInt() Unknown_8 = bs.readUInt() # Header End MaterialPropOffsetList = [] TextureIndexList = [] TextureNameList = [] ShapeInfoOffsetList = [] MaterialIndexList = [] bs.seek(MaterialIndexOffset, NOESEEK_ABS) for i in range(0, MaterialIndex): MaterialPropOffsetList.append(bs.readUInt()) TextureMapCount = bs.readUByte() bs.read(11) for i in range(0, MaterialIndex): MaterialPropOffset = MaterialPropOffsetList[i] bs.seek(MaterialPropOffset, NOESEEK_ABS) TextureIndexList.append(bs.readUByte()) bs.read(7) bs.seek(MaterialInfoOffset, NOESEEK_ABS) TextureNameOffset = bs.readUInt() bs.seek(TextureNameOffset, NOESEEK_ABS) for j in range(0, TextureCount): TextureNameList.append(bs.readString()) TextureName = TextureNameList[j] bs.seek(UnknownOffset, NOESEEK_ABS) bs.read(80) MeshIndex = bs.readUInt() bs.read(4) MeshInfoOffset = bs.readUInt() bs.seek(MeshInfoOffset, NOESEEK_ABS) for k in range(0, MeshIndex): BBox = bs.read(32) ShapeInfoOffsetList.append(bs.readUInt()) Unknown_0 = bs.readUInt() UnknownOffset = bs.readUInt() MaterialIndexList.append(bs.readUByte()) bs.read(3) for k in range(0, MeshIndex): ShapeIndexDigfmt = "{:04d}".format(k) ShapeInfoOffset = ShapeInfoOffsetList[k] MaterialIndex = MaterialIndexList[k] bs.seek(ShapeInfoOffset, NOESEEK_ABS) bs.read(20) IndexOffset = bs.readUInt() + MeshDataBaseOffset bs.read(10) IndexCount = bs.readUShort() Stride = bs.readUByte() Unknown_9 = bs.readUByte() VertexCount = bs.readUShort() bs.read(24) VertexBuffer = bs.readBytes(VertexCount * Stride) bs.seek(IndexOffset, NOESEEK_ABS) IndexBuffer = bs.readBytes(IndexCount * 2) rapi.rpgBindPositionBufferOfs(VertexBuffer, noesis.RPGEODATA_FLOAT, Stride, 0) rapi.rpgBindUV1BufferOfs(VertexBuffer, noesis.RPGEODATA_FLOAT, Stride, 24) rapi.rpgBindNormalBufferOfs(VertexBuffer, noesis.RPGEODATA_FLOAT, Stride, 12) rapi.rpgSetName(baseName + Underline + ShapeIndexDigfmt) rapi.rpgSetMaterial(TextureNameList[TextureIndexList[MaterialIndexList[k]]]) rapi.rpgCommitTriangles(IndexBuffer, noesis.RPGEODATA_USHORT, IndexCount, noesis.RPGEO_TRIANGLE_STRIP) mdl = rapi.rpgConstructModel() mdlList.append(mdl) return 1
    2 points
  10. At least he left my name on it - some don't πŸ™‚
    2 points
  11. it uses a rather simple LZSS compression. I haven't tested it myself because I don't have these new graphics tools, and I don't even know where to open the file! LOL if you can test the tool attached if works or not. """ Descompressor PCMP β†’ LZSS -------------------------------------------------------------""" from __future__ import annotations import struct, argparse from pathlib import Path import tkinter as tk from tkinter import filedialog as fd, messagebox as mb DATA_OFFSET = 0x20 # inΓ­cio dos dados comprimidos # --------------------------------------------------------------------------- # SIMPLE HEADER # --------------------------------------------------------------------------- def _read_header(buf: bytes): if len(buf) < DATA_OFFSET: raise ValueError("Arquivo muito curto para cabeΓ§alho PCMP.") if buf[:4] != b"PCMP": raise ValueError("Assinatura 'PCMP' nΓ£o encontrada.") out_size, comp_size = struct.unpack_from("<II", buf, 0x14) remaining = len(buf) - DATA_OFFSET if comp_size == 0 or comp_size > remaining: comp_size = remaining # fallback: usa o resto do arquivo return out_size, comp_size # --------------------------------------------------------------------------- # LZSS # --------------------------------------------------------------------------- def _lzss_simple(comp: memoryview, out_size: int) -> bytes: out = bytearray() idx = 0 ilen = len(comp) if ilen == 0: raise EOFError("Fluxo comprimido vazio.") b = comp[idx]; idx += 1 bits = 8 while len(out) < out_size: if idx > ilen: raise EOFError("Fluxo comprimido terminou antes do previsto.") op = 1 if (b & 0x80) else 0 # 1 = cΓ³pia, 0 = literal b <<= 1 bits -= 1 if bits == 0: if idx >= ilen: break # nΓ£o hΓ‘ mais flags b = comp[idx]; idx += 1 bits = 8 if op: if idx + 1 >= ilen: raise EOFError("Fim prematuro lendo bloco de cΓ³pia.") d = ((comp[idx] >> 4) | (comp[idx + 1] << 4)) + 1 # deslocamento cnt = (comp[idx] & 0x0F) + 3 # comprimento idx += 2 for _ in range(cnt): if len(out) >= out_size: break if d > len(out): out.append(0) else: out.append(out[-d]) else: # literal if idx >= ilen: raise EOFError("Fim prematuro lendo literal.") out.append(comp[idx]); idx += 1 return bytes(out) # --------------------------------------------------------------------------- # FunΓ§Γ£o principal # --------------------------------------------------------------------------- def decompress_pcmp(data: bytes) -> bytes: out_sz, comp_sz = _read_header(data) return _lzss_simple(memoryview(data[DATA_OFFSET: DATA_OFFSET + comp_sz]), out_sz) # --------------------------------------------------------------------------- # CLI & GUI enxutos # --------------------------------------------------------------------------- def _decompress_file(src: Path, dst: Path): dst.write_bytes(decompress_pcmp(src.read_bytes())) print(f"Descomprimido β†’ {dst}") def _cli(argv=None): ap = argparse.ArgumentParser(description="Descompressor PCMP (comtype YAKUZA)") ap.add_argument("input", nargs="?", help="Arquivo PCMP de entrada") ap.add_argument("output", nargs="?", help="Arquivo BIN de saΓ­da") ap.add_argument("--nogui", action="store_true", help="ForΓ§ar modo terminal") ar = ap.parse_args(argv) if ar.nogui or (ar.input and ar.output): if not (ar.input and ar.output): ap.error("Informe entrada e saΓ­da ou utilize a GUI.") _decompress_file(Path(ar.input), Path(ar.output)) else: _launch_gui() class _App(tk.Tk): def __init__(self): super().__init__() self.title("PCMP β†’ BIN (lzss)") self.geometry("500x160") self.in_path = tk.StringVar(self); self.out_path = tk.StringVar(self) tk.Label(self, text="Arquivo PCMP:").grid(row=0, column=0, sticky="e", padx=10, pady=10) tk.Entry(self, textvariable=self.in_path, width=45).grid(row=0, column=1, padx=5) tk.Button(self, text="…", width=3, command=self._choose_in).grid(row=0, column=2, padx=5) tk.Label(self, text="Salvar como:").grid(row=1, column=0, sticky="e", padx=10, pady=10) tk.Entry(self, textvariable=self.out_path, width=45).grid(row=1, column=1, padx=5) tk.Button(self, text="…", width=3, command=self._choose_out).grid(row=1, column=2, padx=5) tk.Button(self, text="Descomprimir", width=15, command=self._run).grid(row=2, column=1, pady=20) def _choose_in(self): p = fd.askopenfilename(title="Selecione o arquivo PCMP", filetypes=[("TXB", "*.txb"), ("Todos", "*.*")]) if p: self.in_path.set(p) if not self.out_path.get(): self.out_path.set(Path(p).with_suffix(".dec")) def _choose_out(self): p = fd.asksaveasfilename(title="Salvar arquivo descomprimido", defaultextension=".bin", filetypes=[("DEC", "*.dec"), ("Todos", "*.*")]) if p: self.out_path.set(p) def _run(self): if not self.in_path.get(): mb.showwarning("AtenΓ§Γ£o", "Selecione um arquivo de entrada.") return if not self.out_path.get(): mb.showwarning("AtenΓ§Γ£o", "Selecione um local de saΓ­da.") return try: _decompress_file(Path(self.in_path.get()), Path(self.out_path.get())) mb.showinfo("Sucesso", "DescompressΓ£o concluΓ­da!") except Exception as exc: mb.showerror("Erro", str(exc)) def _launch_gui(): _App().mainloop() # --------------------------------------------------------------------------- if __name__ == "__main__": _cli() tool._TXB.py
    2 points
  12. No updated as yet. Haven't looked at it for a few days, but I'll have another look at it soon and upload an updated script.
    2 points
  13. I was able to rewrite PS2 4-bit swizzle code to Python and add it to ReverseBox v0.30.0. Enjoy: https://github.com/bartlomiejduda/ReverseBox/blob/main/reversebox/image/swizzling/swizzle_ps2_4bit.py
    2 points
  14. Firstly, don't open files in notepad - you need a proper hex editor at the very least to see the proper information. Most files won't have anything recognisable, that's where experience of reverse engineering comes in to recognise data offsets, different types of data, etc. You might get some files that are fairly "standard", such as DDS image files or RIFF/WAVE audio files, but most will be proprietary. Sometimes you might get lucky and versions of the file may have been used in previous games and others have already looked at them. Even just editing text can be tricky. For example, if your text is larger than the existing text, it may affect offsets for other lines of text, and you would also have to amend all of those affected. If your text is smaller, it may work. If you're doing something like translating to another language, it may not have the font data for specific symbols. A lot of things to consider, even for seemingly simple tasks.
    2 points
  15. I've been looking into the materials a bit more and made some progress. Here's a few test renders. I'm not sure if some UVs are exactly right, but it's better than no textures.
    2 points
  16. I checked the wav file (WAVS) that was unzipped from the compressed file and found that the value represented by the file size is counted after the file size, not from the flag (RIFF), but the flag and size must exist. I updated the script to make sure the extracted file size is counted after these eight bytes to make sure the extracted .wav file is complete In addition, the WAVS of the file is also modified to WAVE by the way Because it is not modified, vgmstream cannot be converted Convert with vgmsstream https://vgmstream.org/ https://github.com/vgmstream/vgmstream By the way, you can run the script like this python saf.py saf file output folder saf.py
    2 points
  17. They are *almost* normal wave files. For some reason the type is "WAVS" and not "WAVE" that prevents them playing. It uses XBox ADPCM which will play fine in vgmstream, but the "WAVS" needs to be changed to "WAVE" in each file.
    2 points
  18. For .saf files try to extract with this python script, if there is no problem you will get a bunch of .wav files saf.py
    2 points
  19. These ones? From geomchr006. I think I've just about got the basic mesh format sorted.
    2 points
  20. This script should be better handled import struct import zlib import sys from pathlib import Path def parse_index(input_path): index_data = [] current_path = [] with open(input_path, 'rb') as f: f.seek(44) while True: pos = f.tell() entry_type = struct.unpack('<H', f.read(2))[0] name_length = struct.unpack('<H', f.read(2))[0] if entry_type == 1: f.read(24) folder_name = f.read(name_length).decode('latin-1').rstrip('\x00') current_path = [folder_name] elif entry_type == 0: f.read(8) file_size = struct.unpack('<I', f.read(4))[0] uncompressed_size = struct.unpack('<I', f.read(4))[0] f.read(4) offset = struct.unpack('<I', f.read(4))[0] filename = f.read(name_length).decode('latin-1').rstrip('\x00') full_path = '/'.join(current_path + [filename]) index_data.append({ 'path': full_path, 'offset': offset, 'size': file_size, 'uncompressed_size': uncompressed_size }) else: break if f.tell() >= os.path.getsize(input_path): break return index_data def extract_files(input_path, output_dir, index_data): header_patterns = { b'\x04\x00\x00\x00': 8, b'\x08\x00\x00\x00': 12, b'\x0C\x00\x00\x00': 16, b'\x10\x00\x00\x00': 20, b'\x14\x00\x00\x00': 24, b'\x24\x00\x00\x00': 40, b'\x34\x00\x00\x00': 56 } with open(input_path, 'rb') as f: for entry in index_data: print(f"{entry['offset']} {entry['size']} {entry['path']}") output_path = Path(output_dir) / entry['path'] output_path.parent.mkdir(parents=True, exist_ok=True) f.seek(entry['offset']) full_data = f.read(entry['size']) skip_bytes = 0 for pattern, length in header_patterns.items(): if full_data.startswith(pattern): skip_bytes = length break compressed_data = full_data[skip_bytes:] try: decompressed = zlib.decompress(compressed_data) with open(output_path, 'wb') as out: out.write(decompressed) except Exception: pass if __name__ == '__main__': if len(sys.argv) != 3: print("Usage: python jrz.py <input_file> <output_dir>") sys.exit(1) input_file = sys.argv[1] output_dir = sys.argv[2] import os index_data = parse_index(input_file) extract_files(input_file, output_dir, index_data) jrz.py
    2 points
  21. I made an importer that import every tmd2 model correctly. it can read models with more than 255 bones, all uv layers, all vertex color layers, tangents, binormals, both sets of normals, etc... https://www.nexusmods.com/bleachrebirthofsouls/mods/63
    2 points
  22. yes, need latest BMS version and only quickbms_4gb_files.exe all attachments below AES_finder_0.9h.zip AES_finder_mobile_0.9e.zip custom_UE4_scripts.zip sound_extraction_UE4.zip UE4_specific_scripts.zip unreal_tournament_4_0.4.25e.zip unreal_tournament_4_0.4.27e.zip
    2 points
  23. The initial discussion of this thread was done in zenhax I linked the original topic from zenhax This post completed the early preliminary research on this game, and at that time, the extraction of files was basically implemented. In order to make the post more practical and give more topics to discuss, I will set the topic of this post as a Messiah engine file format research, which can discuss more Messiah-related games, not just for ace racer During these times, the engine version has been upgraded many times, and the index table has been updated. Now the hash names of some games have been encrypted in the index table. The index table of each game is basically the same, but it is different. As far as I know, there should be more than three different versions of the index table. 1. Index Version 1 If they have not been updated, these indexes should be the earliest version, without any fiddling, and are also the easiest version to study. You can use netease_mpk_v2.bms to disassemble it //Some new games still use these initial index versions, but have added new compression formats. If you are familiar with bms scripts or python scripts, you can add decompression by yourself, and others remain unchanged 2. Index version 2 The index of this structure is still very simple, but the file name seems to have been specially processed, and normal file names will not be generated in the index. Under the same version of the index, the number of bytes used by different games is also different. Some games take up 20 bytes in one file, while some games take up 24 bytes in one file 3. Index version 3 I seem to have only seen this version of the index on Knives Out games. A large part of the index is overwritten by 0, the file name is not encrypted, the size and offset can also be read, but the index structure is very messy, I can only complete manual extraction, and have not written an automated script (from the index after hot update) 4/Index version 4? Now some index files seem to be replaced directly by database file types, so I directly call them version 4, the entries of these index files are stored in the database file, and after parsing from the database, it may be necessary to make some fiddling to allow the script to extract correctly More types are also added for compressed files, I'm trying to understand all compressions to support more games 1.ZZZ4 (lz4 compression) 2.ZZZZ (lzo1x compression) 3.ZZZX (seems to be encrypted lz4) has a script where_winds_meet_mpk.bms that can handle this compression, but the script is outdated, not sure if the key is outdated 4.LZMA (lzma compression) 5.ZSTD (zstd compression) 6.1084 (exclusive or lz4 compression) 7.108D (zstd compression) 8.E206 (corrupted zlib compression) 9.EZST (Unknown compression This post will discuss the index structure, compression type, and other related files about the engine
    1 point
  24. I've been doing a Noesis script for the beta of Once Human. Still got a few things to do on it, but it should work for most of the models so far: Edit: Read the notes at the start of the script regarding the various files needed. once_human_mesh.zip
    1 point
  25. .psc its just text file. .dat container with files insede (txt,psc,dds,abc) .xex idk from offset ~8191 it is too dense, possibly compressed or encrypted EDIT: first link in google ("XEX is the executable file format used by the Xbox 360 operating system. It seems to be a crypto and packing container for PPC PE executable files.") i make script for unpack your *.dat file: unpack.py
    1 point
  26. All games made from UE4-5 have fonts .ufont is ttf. You should extract .ufont and after extracting the font rename the file extension .ufont to .ttf. To add letters in the font, edit ttf with different programs such as FontForge etc. Then rename the extension of the edited font .ttf to .ufont.
    1 point
  27. There was a ProjectG1M project (on xentax?) which I could generate a .dll from, April 2024. Drag&drop of g1m onto Noesis gave me this: Sadly I don't remember much so you'll need to search in xentax archives for more infos. edit: Seems it was Joschka's project, compare here, Zenhax archive Joschuka, github
    1 point
  28. coming back here to bring updates on the game files, I decided to rewrite the parser and ended up learning a lot from it, with that I was even able to add support for more files that the original parser didn't support πŸ™‚ https://github.com/JeanxPereira/recap_parser thanks a lot @shak-otay for helping me with the old parser 😁🫑 and props for all your work in this community
    1 point
  29. Why not use rapi.rpgSetMaterial(TextureNameList[MaterialIndexList[k]]) ? edit: without the if k < texCnt: of course
    1 point
  30. Great! Good luck on your translation.
    1 point
  31. I managed to revive my old 3dsmax and started the MHK2 maxscript but dunno whether the colors are correct:
    1 point
  32. hey there, i've spent some time to inspect these files, headers of this game starts always with EVOSLITL the next 4 bytes are the file id for example 1765932410 or 7AFD4169 is "ferrari_laferrari_fxxk_lite.hierarchy" with these freaking long filepaths it could be part of a hash algo? vertexbuffer do display its own id for reference etc. the next 2 bytes are a file flag? no clue yet the next 4 bytes are the extension identifier https://github.com/Nenkai/010GameTemplates/blob/main/Evolution Studios/RPK_ResourcePack.bt 8 bytes - header - or 2 x 4 bytes EVOS LITL (little endian) EVOS BIG? (big endian)? 4 bytes - file id - uint32 2 bytes - file flag? 2 bytes - file type 2 bytes - file subtype? textures for example are 05 05 hierarchy files contain the overall bone / dummy structure, i assume collision related stuff is inside the .havok file it continues with 2 bytes (unknown) and then the bonecount for each bone it loads matrices for rotation and position some bones look like they also inherit the position of the parent bone, requires more research at a later block you can see the name string for each bone, these names do also match with the *.mesh files texture files continue like this 2 bytes - flag 2 bytes - x size 2 bytes - y size 18 bytes - unknown 4 bytes - block size x bytes actual texture file - but its playstation, it is swizzled πŸ€·β€β™‚οΈ couldnt find the right setting yet vertexbuffer files continue with 4 bytes - block count 2 bytes - vertex stride 2 bytes - vertex count x bytes - vertex block it looks like the vertex buffer are more like a pair of one with a stride of 8 12 16 for x y z floats and the second data block contains normals, uv boneweights etc. the mesh files however are still a riddle to me, they do contain everything, but the format is just... damn random i've picked your fxxk _BODY_COL_BODY_BODYShape list to orientate after the header stuff they start with 2 bytes - (11) unknown 2 bytes - (14) the number of vertexbuffer to load 2 bytes - (01) the number of indexbuffer to load 2 bytes - (16) the number of submeshes in this file (selected black) after that count it starts right away with 4 bytes - fvfcode? 4 bytes - vertexbuffer id (8 12 or 16 stride) light blue 2 bytes - flag? 4 bytes - fvfcode? 4 bytes - vertexbuffer id (20+ strides) dark blue 2 bytes - flag? 2 bytes - 0003? 1 bytes - 3 material file indicator (not selected here but 53B84A1D = 491436115 = carbon_damage_2step_gloss_streaks.material 4 bytes - material file 2 bytes - flag? 2 bytes - 0007? 1 bytes - 5 indexbuffer indicator 2 bytes - flag? 2 bytes - 0004? 2 bytes - 0203 indicator for a submesh block? 4 bytes first vertex - light green 4 bytes count - yellow 4 bytes indexoffset / start - red 4 bytes indexcount - purple 4 bytes zeros? 1 bytes material indicator 4 bytes material id - pink so far so good, it continues with a couple more submeshes (16 in total) but the order is entirely messed up + you can see that the first block (the list you posted) appears three times in that file how messed up is messed up ... not sure if someone else is working on these files - maybe this little sum up helps spotting something
    1 point
  33. Where did you find these files? It looks like they've been modified. Is that a fan-made Hungarian translation? Please upload original files.
    1 point
  34. You'll need to analyze it - Children may start from FF00 ..., blue bold marks string length count (zero ending byte included):
    1 point
  35. Hell yes! An epic conclusion 🚬🦾😎 If you're the sharing type hmu on Instagram, would love to make some low poly sopranos content πŸ˜‚πŸ™ Zachx.gif
    1 point
  36. gameloft's texture formats are strange, usually encrypted or are different types when using a hex editor, it has a pvr header, rename it to .pvr and it'll open, make sure you choose the srgb colourspace as with linear it's brighter in particular, you sent a lightmap for the alps track the bus texture you sent has the same texture format
    1 point
  37. I've had a quick look at the first archive. I don't know the exact format of the file tables and how they relate filenames to the actual files, but I can see that it uses LZ4 compression, so the raw files can be easily extracted without names. Here's an example image extracted manually as a test. If I can work out the filename/file relationship, a script should be easy enough.
    1 point
  38. damn, my bad then. thx for correction Also as for manifest.7z requiring a password, it's "Thank you!"
    1 point
  39. The script does call for some extra cleanup work, but it's all worth the trouble:
    1 point
  40. Did the tool work? can you mark as solutiion? its the minimal.
    1 point
  41. Please see rule #11 about not asking for assets. You should extract them from your own copy of the game.
    1 point
  42. Great job!! A lot information that needs to be preserved in an way that is easy to search it.
    1 point
  43. Anybody has a unpack script for this game? How to extract game files please like you did?
    1 point
  44. Adding materials... thats probably last thing its missing before release
    1 point
  45. Things are getting better. Almost everything is in place now.
    1 point
  46. Works fine in quickbms. try this script: idstring "LZMA" comtype lzma get UNCOMPRESSED_SIZE long get ARCHIVE_SIZE asize xmath COMPRESSED_SIZE "ARCHIVE_SIZE - 8" SavePos DATA_OFFSET get NAME basename get EXTENSION extension string NAME + ".decompressed." + EXTENSION clog NAME DATA_OFFSET COMPRESSED_SIZE UNCOMPRESSED_SIZE So maybe something is wrong with Python's lzma library that you're using.
    1 point
  47. Here is, extract all in a folder then open wrldview.exe(there are three: d3d8, d3d9 and opengl choose one) and drag and drop level.bsp If everything is fine you can use NJ ripper or 3D Ripper Dx on the wrldviewer.exe(just for viewers d3d8 or d3d9) Some notes: *You need to place all textures in a folder. Textures folder and .bsp file should have the same name, in this case: level **Textures folder and .bsp file need to be together in same location or folder. ***All textures should be .bmp or .PNG with original names. RW bsp World viewer.rar
    1 point
  48. The first value in each file entry is the start sector of the file in the iso, so you don't need to extract the SIREN.xxx files first. I've attached a script that should work. siren_tbl.zip
    1 point
Γ—
Γ—
  • Create New...