Jump to content

Leaderboard

Popular Content

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

  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. Version 1.0.0

    263 downloads

    My old tool for TLOU2 PS4 fixed to work with PC files. Unpack .psarc files with UnPSARC_v2.7, and then you can use any .PAK file with the tool. Use command line, or just drop .PAK file onto the .exe Work same as old tool, described here: https://web.archive.org/web/20230819184855/https://forum.xentax.com/viewtopic.php?t=22580 After extraction, model and skeleton are in separate files. So they must be manually combined to work together. SMD model & skeleton can be just imported separately and then connected in blender. For ascii it will not work, so you have to open model in text editor, remove first line (0), which is bone number, and copy-paste skeleton there instead of that zero. So far tested on models, textures, maps - all looks fine. Animations are probably wrong, i can look into that later.
    3 points
  6. 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
  7. 2 points
  8. 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
  9. 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
  10. 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
  11. At least he left my name on it - some don't 🙂
    2 points
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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
  20. These ones? From geomchr006. I think I've just about got the basic mesh format sorted.
    2 points
  21. 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
  22. 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
  23. 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
  24. How do you think will whining bring you any step further? After 5 weeks it's a little bit unlikely that someone pops up with the "ultimate" solution. How about uploading a model sample?
    1 point
  25. I figured it out. In addition to making sure the .blend file is opening with Blender249, I needed to make sure the newGameLib folder from the .zip download is copied and placed in my python folder. Once I did that, Blender did finally open a window for me to select my files. Thanks for all your help!
    1 point
  26. I didn't know about the -fileopenlog command the first time I needed it.
    1 point
  27. hey! I looked at the bones and other things for this game. from the start of the file, at dec 12 the bone count is stored, and at 144 is the offset to the bone data. at dec 96 theres another pointer to a different set of bone data but it seems just to be matrices, and I haven't looked at it further than that. Regarding the data thats pointed to at offset dec 144, the pointers in that block seem to be all relative to themselves. the pointer at dec 24 points to the bones (quaternion) rotation, position, scale, (in that order) and at dec 60 is the relations count, followed by a list of [child, parent (or 32767 if its null)] the data following seems to be related to the bones but doesn't matter here. I also looked at the names. I couldn't find anything used to link any of the bones to their names, so I'd think they just go through the list as texture names, bones, materials and then meshes to assign them. I'm curious about the list of counts at the start of the file, so if you ever find what they do please let me know Thank you!
    1 point
  28. This Python script should do the trick: import os def convert_to_utf16(input_path: str, output_path: str) -> None: print("Starting convert...") with open(input_path, 'rt', encoding='utf-8') as f_in: content = f_in.read() with open(output_path, 'wb') as f_out: f_out.write(b'\xff\xfe') f_out.write(content.encode('utf-16-le')) print("Convert success!") def convert_all_txt_in_folder(input_folder: str, output_folder: str) -> None: os.makedirs(output_folder, exist_ok=True) for filename in os.listdir(input_folder): if filename.lower().endswith('.txt'): input_path = os.path.join(input_folder, filename) base_name = os.path.splitext(filename)[0] output_filename = f"{base_name}_utf16le.txt" output_path = os.path.join(output_folder, output_filename) convert_to_utf16(input_path, output_path) print(f'Converted: {filename} -> {output_filename}') if __name__ == '__main__': convert_all_txt_in_folder('C:\\Users\\User\\Desktop\\UTF_FILES\\input', 'C:\\Users\\User\\Desktop\\UTF_FILES\\output')
    1 point
  29. While type 3 is normal ZSTD which decompresses fine, types 4 and 10 seem to have the ZSTD 4-byte identifier, but then some modifications to the data so that it doesn't decompress normally. The meshes that can be decompressed do have some slight differences to the ones in the beta, so I'll need to look at them sometime.
    1 point
  30. Yes, they are compressed. In the PCMP header, there is the compressed and decompressed sizes. For the title image, compressed size is 0x11e33a and decompressed is 0x500030. There are several images in that file when decompressed. The first image title one is in RGBA32 format with Morton swizzling. Should be possible to do a proper script to handle multiple images. The compression type is "Yakuza" from the QuickBMS compression scanner.
    1 point
  31. can anyone help me with .pck and .dat samples from Midnight Club 3 DUB Edition Remix PS2 version? I ripped the asset.dat archive using MC3 Tools from xentax archive link found https://web.archive.org/web/20220826005749fw_/https://forum.xentax.com/viewtopic.php?f=10&t=12738&sid=e105694a4ca0adf67b8c0fccc73c7251 https://github.com/XeNTaXBackup/XeNTaXBackup.github.io/blob/main/markdown/Midnight Club 3 Dub Edition Research Thread_12738.md the step is to drag ASSET.DAT and drop to ar_extract.exe (same for texture.dat for tex_extract.exe) And I don't think i can use MC3_extraction_tool from TahmidAlam unless I get the .pck to .mesh result (I know it takes more time and knowledge so please don't assume that I want it quickly because I still don't have knowledge on any file structure) https://github.com/TahmidAlam-git/MC3_extraction_tools MC3_Tools.zip vp_d_f355_98.7z
    1 point
  32. Writing scripts for mpk3 on quickbms should be more troublesome than imagined, because this version is too weird, and many places need to constantly adjust scripts. In games using mpk3, each game uses different structures, and different versions of the same game will also have minor changes. If someone can write a quickbms script for you, it means he is very patient
    1 point
  33. Try this script, it only verifies the files you provide, and does not fully verify all files By the way, if you can download it online, you can download it directly Because the file extracted in this version is no longer complete Script running method The first input content requires input.mpkinfo file The second input requires an output directory mpk3.py
    1 point
  34. You mean like this? EMI_HEAD_MemoryDump.zip
    1 point
  35. How do you mean scrambled? They're decompressed and not encrypted. As for editing and repacking, that's a lot more complicated than just extracting, as you probably need to know a lot more about every piece of data in the files to properly recreate them with new data.
    1 point
  36. This is sick, I'd love to see mods for this game. Want to edit textures, models, music, etc. Looking forward to it!.
    1 point
  37. edit: sadly the following worked for an emd from 2001 only. (The em02.emd you provided results in a tim file with 5 millions of zeroes.) I started the "BioHazard File Archive Tool" mentioned in the tutorial and used Bio1.5/EMD/Disassemble on em001.emd (2001) - a.tim and a .tmd file were extracted. Point cloud from tmd: 2 meshes from em20.emd (2017) with faked face indices (strips), boot and hair: em08-head:
    1 point
  38. I updated the netease_mpk.bms script Added two new compression types, which should now handle more games # NetEase messiah game mpkinfo/mpk (script 0.3) # List of supported games:Diablo Immortal,Ace Racer,Badlanders,Lovebrush Chronicles,TankCompany # Originally created by aluigi get EXT extension if EXT & "info" # mpkinfo and any other similar extension else print "Error: you must open the info file" cleanexit endif string EXT - "info" get RES_NAME basename get VER long get FILES long for i = 0 < FILES get NAMESZ short getdstring NAME NAMESZ get OFFSET long get SIZE long get FILENUM long math IS_FOLDER = FILENUM math IS_FOLDER & 1 math FILENUM >> 1 putarray 0 i FILENUM putarray 1 i NAME putarray 2 i OFFSET putarray 3 i SIZE putarray 4 i IS_FOLDER next i sortarray 0 1 math LAST_FILENUM = -1 for i = 0 < FILES getarray FILENUM 0 i getarray NAME 1 i getarray OFFSET 2 i getarray SIZE 3 i getarray IS_FOLDER 4 i if IS_FOLDER == 0 if FILENUM != LAST_FILENUM math LAST_FILENUM = FILENUM if FILENUM == 0 string TMP p "%s.%s" RES_NAME EXT else string TMP p "%s%d.%s" RES_NAME FILENUM EXT endif open FDSE TMP 0 EXISTS endif if EXISTS != 0 goto OFFSET getdstring ALGO 4 if ALGO == "ZZZ4" comtype lz4 get XSIZE long savepos OFFSET clog NAME OFFSET SIZE XSIZE elif ALGO == "LZMA" comtype lzma get XSIZE long savepos OFFSET clog NAME OFFSET SIZE XSIZE elif ALGO == "ZSTD" comtype zstd get XSIZE long savepos OFFSET clog NAME OFFSET SIZE XSIZE elif ALGO == "ZZZZ" comtype lzo1x get XSIZE long savepos OFFSET clog NAME OFFSET SIZE XSIZE else log NAME OFFSET SIZE endif endif endif next i netease_mpk_v3.zip
    1 point
  39. 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
  40. You don't need to keep asking. If and when there is one, it'll be posted here somewhere.
    1 point
  41. Great job!! A lot information that needs to be preserved in an way that is easy to search it.
    1 point
  42. Version 0.4.4

    467 downloads

    A QuickBMS archive extraction script for NetEase NeoX Engine NXPK (.npk) archives. Originally authored by aluigi (pre-v0.4.0) and modified by me. Currently Supported Games Force Extraction (no guarantees) Identity V Onmyoji Changelog
    1 point
  43. Things are getting better. Almost everything is in place now.
    1 point
  44. Its getting there, I have more objects placed now. But still not all.
    1 point
  45. This BMS script that can turn the .atd files into .ktx files: https://www.mediafire.com/file/0ziila22cy8hl0v/Dairoku_atd_ktx.bms/file Then, you can use a program (I use Tacent View) to convert those .ktx files into .pngs.
    1 point
  46. 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
  47. Version 1.0.0

    205 downloads

    Works with many Phyre engine games: - Godzilla 2014, - Super Heroine Chronicles - Onechanbara Z2 Chaos - Final Fantasy X/X2 HD remaster - Uta Kumi 575 - Oreimo Happy End - Trails of Cold Steel/Sen no Kiseki
    1 point
×
×
  • Create New...