Jump to content

All Activity

This stream auto-updates

  1. Past hour
  2. You should use the -G command, which will force GUI startup
  3. These are really very good "last words", I feel. My final idea is to use an emulator/debugger (did it for PC games only so far). The compatibility list of PCSX2 shows Garou - Mark of the Wolves only, which had a PS4 release. So yeah, another dead end, I guess. (Luckily I have some other unfinished projects so I think, I can live with the fact that the GGK animations will remain a riddle for me.)
  4. Today
  5. I don't own the game so I can't personally test anything or look at the files. What I can say just from observation is that with some of the animations and your model importer it is having orientation issues. To find out if this is the armature itself or error with importing the animations, make a duplicate skeleton and retarget to it the animation that has normal skeletal/bone orientation. If the hands/fingers still look off, you got your answer. About the "spider stretch" screenshot I see from your pictures. I have seen that a LOT with people trying to work with Mortal Kombat 1 animations and many games in Unity engine. Totally different engines but probably similar issue. Importer is wonky with the skeleton/bones and gets incorrect animation data. First try a retarget. If you have Claude A.I you can use the blender MCP with Claude and it can generate a normal skeleton with duplicate names in blender for your retargeting tests to save time.
  6. UModel is mis-parsing the package, usually because the game’s UE2 fork / package format doesn’t match what UModel expects with the current settings. Umodel to my knowledge works with this game. Your settings are not correct. I will elaborate using your error. FArray::Empty: -116 x 12 UModel tried to allocate an array with -116 elements of 12 bytes each. A negative element count is impossible, so the size overflows to a negative number (-1392) and appMalloc blows up. UModel is reading the wrong structure at that position (e.g., thinks this field is “NumVerts” but it’s actually some other 32-bit value), because the package layout / engine profile doesn’t match what UModel expects for “game=ue2” in this case. The rest of the stack confirms it dies while trying to load a skeletal mesh from that .ukx, not on textures or trivial data. In easy to understand terms. "wrong assumptions about how this game’s .ukx stores its skeletal meshes". Umodel should have a selection on the side for where you can pick game targets. If the game isn't there then you might be out of luck. However, I think this game shares a target with another game. Just trial and error to see if any of them work. Also, if this is not a "PC" version of the game you need to change the "Auto" on the bottom right of the gui to the specific platform. I know the topic says PC. People do make mistakes. Unreal Engine 2 games are rare and few in between. Not many people cared to work with any of them. Even the Wheels of Time game didn't get much investment. Also, turn off all forms of textures/material when first trying with unreal engine 2 games to speed up the process especially with whack a mole trial and error. The only people that would even bother adding support to this game which is extremely unlikely are on Gildor's forum. Again, very few people would ever care for an Unreal Engine 2 or 1 game. I am sorry if this wasn't helpful.
  7. I don't know how the quote thing works with this forum so I apologize for doing full quotes. While I do have other renderware file types, none of them are near the same as this game. It is an extreme outlier. For models, it is the same as most other renderware games. Mainly the Eighting flavour. The animations are unique to this game exclusively. It's bizarre dual animation system with renderware is not used on any other game I have come across. The only similarity this game has with others using the same/similar engine are the models but even that is only by half since Garou mixes the older PS1/N64/Saturn/Early Dos style of animating with the normal style we are all used to with more modern games. I have no RWANM reference that is solved usable with this. Most of my other PS2 RenderWare titles I worked on either use the standard ANM/TMO chunk (for which there are public importers) or completely different animation containers (GNTA and similar), so I don’t have a clean “known good” PS2 DFF+RWANM pair to compare against. What I can provide are the DFF for this exact under-mesh rig which you already have, with the full bone list / hierarchy along with all others this game has. If there’s any particular chunk/offset range from gar.rws.dec_be_-15_anim_77.rwanm that would be more useful for you to see, or a specific format for the bone list that would make your life easier, let me know what you’d prefer and I’ll try to supply it. From the looks of it... without having more knowledge on this specific animation format it might be a dead end..... I hate to say that. I will say that if someone else does figure this out they should refrain from making it public instantly because there are people willing to pay around 800 USD for this animation importer/exporter. You could take their commission and get paid for it. That is what I was offered and now I have to say no to this because it would take too many weeks of reverse engineering to figure it out and in my opinion won't be worth the money by then. If you do make it public and snub the possible money that is fine as well. The people interested only want to mod the game to add/change characters in it since it is possible to add more characters to the game without the game itself breaking. They basically want to make their own Smash Bros game using Garou Golden Knight to make/add more characters from that anime/manga series. Thank you for trying and looking!! ^^ As of now I am quitting on this. I have too many other jobs to look at and this is too much of a time sink for me. If people want to continue on this and have questions feel free to message me. I will give my tools and such along with any information so you can continue where I left off.
  8. Hello! Out of boredom, I decided to replace texture from a Godot game, in this case Slot or Not, by using Python but failing and failing over again exhausted me. My script has data and their MD5 hash code replacement, and data header change. I doubt that something doesn’t work or they are others data somewhere. I also think even if both WebP data from Godot and PIL are working, their data processing are different thus incompatible. Not even replacing them with PNG data works. I suspect there is a checksum for PCK somewhere. I compared its PCK file with Super Mario 127’s. Although the WebP data for CTEX and STEX are the same, the data pointers in SM127 are at the start of the file, after the header; SoN are at the bottom. The PCK for V1 is documented in Xentax wiki but not for V3. It may be small but this comparison shouldn’t be dismissed. What I need: If there is a checksum for PCK, where it is? The Bytes leading to the data header thus making the Python script adaptable If the WebP data is the issue, a better understanding of Godot’s WebP data Feel free to reply if you find anything! Slot or Not (PCK File V3) son PCK File.zip Godot Picture Replacer Script (Work in progress) Godot Pictures Replacer Script.py Note for the creator of Slot Or Not, you don’t have to turn it into an moddable game. The game need its own resource to be good game. I do this because why not and for research purpose. Knowledge GODOT PCK FILE FORMAT (Little Endian) (From Slot or Not) HEADER (112 Bytes) 4 Bytes = Signature ("GDPC") 4 Bytes = 03 00 00 00 (Engine Version) 4 Bytes = 04 00 00 00 (Major) 4 Bytes = 05 00 00 00 (Minor) 4 Bytes = 00 00 00 00 (Revision) 4 Bytes = 02 00 00 00 4 Bytes = 70 00 00 00 (First File Pointer) 4 Bytes = 00 00 00 00 4 Bytes = File Numbers 4 x 19 Bytes = 00s (Reserved) DATA HEADER (Found at the last part of the file) 4 Bytes = Length of Path, Including the 00s X Bytes = Path Name + 00s (If not divisible by 4) 8 Bytes = Data Pointer - 112 8 Bytes = File Size 16 Bytes = Data MD5 Checksum 4 Bytes = 00 00 00 00 GODOT CTEX FILE FORMAT (Little Endian) For WebP Format { 4 Bytes = String GTS2 4 Bytes = Use Alpha or Not (01 = Yes; 00 = No) 4 Bytes = Height 4 Bytes = Width 4 Bytes = 00 00 00 0D 4 Bytes = FF FF FF FF 4 x 3 Bytes = 00s (Reserved?) 4 Bytes = 02 00 00 00 2 Bytes = Height 2 Bytes = Width 4 Bytes = 00s 4 Bytes = 05 00 00 00 4 Bytes = Data Size after this Byte 4 Bytes = String RIFF 4 Bytes = WebP Data Size after this Byte 8 Bytes = WEBPVP8L / Tag for Loseless Encoded Image Data 4 Bytes = Data Size (or Data Size - 1 if WebP Chunk ends with 00) (Rest of the File) X Bytes = WEBP VP8L Chunk (On Python, the settings are Loseless = True, EXIF = False) 0-15 Bytes = 00 for Fill Up if the CTex Data Size isn't a divisible of 16 } [NOTE: You can get the WebP data by removing the GTS2 Header.] For PNG Format { X Bytes = PNG File Data 0-15 Bytes = 00 for Fill Up if the CTex Data Size isn't a divisible of 16 } X Bytes = String for [Remap], Settings, Path, Texture, Vram X Bytes = 00s (if the length the String isn’t a divisible of 16)
  9. I tried UE viewer but returns an error and crashes appMalloc: size=-1392 (total=2 Mbytes) <- FArray::Empty: -116 x 12 <- TArray::SerializeSimple <- TLazyArray<< <- FStaticLODModel<< <- TArray::Serialize: 1/4 <- USkeletalMesh::Serialize <- LoadObject: SkeletalMesh'CBA_Characters.General', pos=132000, ver=129/10, game=ue2 <- UObject::EndLoad <- LoadWholePackage: Animations/CBA_Characters.ukx <- CUmodelApp::ShowPackageUI <- Main: umodel_build=1590 Any ideas where to convert UKX and SkeletalMesh files. Thanks in advance. ww2crtb_ukx.zip CBA_Characters.zip
  10. Yep. 0x2d72 is the start address of a block, 1100 is the count of 22 bytes blocks. Since hex2obj usually is used to display vertices I assumed the data at 0x2d72 to be translations which the visualizations seems to confirm. Other than wildest guessings? I fear, no. Another question is how the data is assigned to the bones. Do you have a PS2 example (dff/rwanm files of another game or just a picture) where this assignment can be traced? I'm glad when I could help somehow. Forgot to mention that (see picture in my previous post) I pressed the 'table' button to get the timeline list. The 'ptCld' button needs to be toggled to 'noPtC' for this (or you press 'mesh' to get the point cloud visualization).
  11. This is actually very helpful. Thank you. I seen the same repeating groups of ~10 unsigned 16-bit value and came to a similar conclusion. The constants like 0, 1632x (~0x3FCx), 21845 (0x5555), 39322 (0x999A), 43691 (0xAAAB), 52429 (0xCCCC), 56798 (0xDDDE), 63488 (0xF800) hex patterns are classic fixed-point / normalized values (fractions of 0xFFFF), which is exactly what you’d expect for compressed curves (rotations, maybe scales or tangents)... I am not 100% sure though. Your step back that you are seeing is because multiple tracks/bones are interleaved via small index tables or there’s a separate header that says “keyframe list starts at X for track Y. I have not figured it out. Also, I am only assuming. It is an educated guess. 2d72 1100 looks more smooth because it is probably for the static pieces. That is also a guess. I don't really know. I haven't found a clean stride/format yet from any area to the extent I was happy with any result. Thankfully your poking proves it isn't baked matrices. However, it might have "junk" data inside of it or switch between the two different formats on the fly which would have a call/read from the game engine the game was made with "elf statements/running". For the last two days I have been looking for a header or track and still haven't found one. I don't know what the meaning "definition" for each of the 10 values per entry (time? quat? s,t,r? tangents? flags?). Also haven't figured out how these numbers convert back to usable floats/matrices for a bone rig. You found the right haystack to be looking for the needle here and I thank you for this. The repeated 16-bit values like 0x3FCx, 0x5555, 0xAAAA, 0xF800, and the way they change over “time” gave light on this. That matches my expectation that GARO is storing proper animation curves rather than just baked matrices which most people would have assumed because of the static model additive animations. Sorry for repeating myself here. I have a client for this game that is CONSTANTLY having me repeat over and over some of this information and it started to turn into habit. Going back to the “step back” jumps you pointed out I believe show the timeline might be split into several blocks (per-bone or per-channel segments) instead of one clean linear stream, which is probably why tools that only understand standard RWANM fail on this game. I don’t have much experience with your viewer. The tools I use are far different and I have been doing a lot of direct hex poking along with using renderware tools, so I’m still trying to figure out the parameters you showcase here. When you mention 2d72 1100 in step 3, is that essentially a stride / FVF setup you’re using to visualize the data as a point cloud? That was my original assumption but now I am second guessing myself. Do you have any thoughts yet on how those 10-value records break down (e.g. time + rotation + something else), or on where the per-track headers might sit? You helped a lot with this and I am very thankful.
  12. So basically I would have to "unzip" the .lvl and feed the Blender plugin with the rbm files right ?
  13. I don't know if there are more models in that unpacked folder, you need to check that so examine each file there. Just remember that characters use shorts in vertices buffer, I think I saw other file with floats but maybe that file is not a character or maybe it is but with floats, I really don't know, lol. Here is the script if you want to test it: fmt_black_ps2_prototype_DB.py
  14. I found a model, I used that script to split the file(LEVEL_00/CHARDATA.DB). Then in unpacked folder "CHARDATA.DB_unpacked" I went to "segment_03_0007c600" folder and inside I used the file "key_53b10f70a0da0000_off_000d4c00.bin", I renamed that .bin to DB again because .bin is very generic. And I made a script using the old function to create faces from Allen and the byte seach by Durik. I noticed that buffers have a tag(like almost all PS2 games): verts buffer Tag: 05 03 01 00 01 00 80(then 1 byte vert count and 1 byte unk) buffer: 3 shorts XYZ, 1 short flag uvs buffer Tag: 05 03 01 00 01 01 80(count and unk and then buffer 2 shorts XY) normals buffer Tag: 05 03 01 00 01 02 80(count and unk and then buffer 3 bytes XYZ) UVs were tiny so I scaled that using "rapi.rpgSetUVScaleBias((8.0, 8.0, 8.0), None)", You can use other value if you want but I used 8.0.
  15. the lvl file is essentially like a zip/container file containing a bunch of .rbm/.rba (CAFF) files and the .rbm/.rba files are basically containers with the data for any given asset, eg models will include a model(header), scenegraph, textures and may additional things like hits/animation data packed inside too if its relevant to the model and/or not shared between a bunch of other models in which case they are usually packed inside the zpackage rbm files.
  16. _M = {} from hexm.common import portable if portable.IS_CLIENT: from hexm.common.data import base_data_object BaseDataObject = base_data_object.BaseDataObject class LocaleDataObject(BaseDataObject): -- Closure assigned: ctor def ctor(self, root, table_name): super(self, root, table_name) self.__table = MTableReader.LocalizedTableV2(table_name) self.__diff_table = G.datam.get((table_name + "_bin_diff")) if not self.__diff_table.is_data(): self.__diff_table = null self.__is_inited = false self.__is_speedup = false self.__is_use_mmap = false self.__enable_iteration = true self.__hotfix_cache = {} self.__is_hotfix = false self.__exist_data_cache = setmetatable({}, { "__mode": "v" }) return -- Closure assigned: load_data def load_data(self): is_succ = True if not self.__is_inited: __table_name = self.__table_name is_succ = self.__table.LoadData(("locale/" + __table_name), ("locale/" + __table_name + "_diff")) self.__is_inited = is_succ return is_succ -- Closure assigned: unload_data def unload_data(self): if self.__is_inited: self.__table.UnLoadData() self.__is_inited = false -- Closure assigned: set_cache_capacity def set_cache_capacity(self, capacity): if self.__table.SetCacheCapacity: self.__table.SetCacheCapacity(capacity) -- Closure assigned: speedup def speedup(self, is_use_mmap): self.__is_speedup = true self.__is_use_mmap = is_use_mmap if self.__is_inited: if self.__table.SpeedUp: self.__table.SpeedUp(is_use_mmap) -- Closure assigned: unspeedup def unspeedup(self): self.__is_speedup = false if self.__is_inited: if self.__table.UnSpeedUp: self.__table.UnSpeedUp(False) -- Closure assigned: is_bin_data def is_bin_data(self): return True -- Closure assigned: contains def contains(self, key): if not self.__is_inited: return False if self.__is_hotfix: if self.__hotfix_cache.contains(key): if not self.__hotfix_cache[key]: value = None return value == None return self.get(key) == None -- Closure assigned: __index def __index(self, key): return self.get(key) -- Closure assigned: get def get(self, key, default): if not self.__is_inited: return default if key: if not (type(key) == "number"): return None else: return None if self.__is_hotfix: if self.__hotfix_cache.contains(key): if not self.__hotfix_cache[key]: return default if self.__diff_table: val = self.__diff_table.get(key) if val == -1: return default if not val: val = self.__exist_data_cache[key] if val: return val val = self.__table.GetData(key) if not val: return default self.__exist_data_cache[key] = val return val -- Closure assigned: get_hotfix_data def get_hotfix_data(self): if self.__is_hotfix: if bool(self.__hotfix_cache): return self.__hotfix_cache return -- Closure assigned: __len def __len(self): if not self.__is_inited: return 0 return len(self.keys()) -- Closure assigned: keys def keys(self): if self.__is_hotfix: if not self.__is_inited: table_keys = {} return table_keys table_keys = self.__table.GetLuaKeys().copy() if self.__diff_table: for key, value in pairs(self.__diff_table): if value == -1: if table_keys.contains(key): table_keys.remove(key) else: if not table_keys.contains(key): table_keys.append(key) if not self.__is_hotfix: return table_keys if bool(self.__hotfix_cache): for k, v in pairs(self.__hotfix_cache): if not v: if table_keys.contains(k): table_keys.remove(k) else: if not table_keys.contains(k): table_keys.append(k) return table_keys else: if self.__enable_iteration: if not self.__is_inited: table_keys = {} return table_keys table_keys = self.__table.GetLuaKeys().copy() if self.__diff_table: for key, value in pairs(self.__diff_table): if value == -1: if table_keys.contains(key): table_keys.remove(key) else: if not table_keys.contains(key): table_keys.append(key) if not self.__is_hotfix: return table_keys if bool(self.__hotfix_cache): for k, v in pairs(self.__hotfix_cache): if not v: if table_keys.contains(k): table_keys.remove(k) else: if not table_keys.contains(k): table_keys.append(k) return table_keys error("Cannot do this operation") -- Closure assigned: values def values(self): list = [] if self.__enable_iteration: if not self.__is_inited: return [] keys = self.keys() if keys: for _, k in pairs(keys): val = self.get(k) if not (val == None): list.append(val) return [] error("Cannot do this operation") -- Closure assigned: items def items(self): if self.__enable_iteration: if not self.__is_inited: return [] keys = self.keys() list = [] if keys: for _, k in pairs(keys): val = self.get(k) if not (val == None): item_list = [k, val] list.append(item_list) return list error("Cannot do this operation") -- Closure assigned: to_dict def to_dict(self): error("Cannot do this operation!") -- Closure assigned: copy def copy(self): error("Cannot do this operation!") -- Closure assigned: __pairs def __pairs(self): if self.__enable_iteration: if not self.__is_inited: values = {} return pairs(values) keys = self.keys() values = {} if keys: for _, k in pairs(keys): val = self.get(k) if not (val == None): values[k] = val return pairs(values) error("Cannot do this operation") -- Closure assigned: update_remove_rows def update_remove_rows(self, r_rows): self.__is_hotfix = true for _, key in pairs(r_rows): self.__hotfix_cache[key] = None self.__exist_data_cache[key] = None -- Closure assigned: update_new_rows def update_new_rows(self, n_rows): self.__is_hotfix = true self.__hotfix_cache.update(n_rows) -- Closure assigned: update_new_values def update_new_values(self, n_values): return -- Closure assigned: update_remove_values def update_remove_values(self, r_values): return -- Closure assigned: update_table_len def update_table_len(self, t_len): return -- Closure assigned: reload def reload(self): from hexm.client.consts import data_consts import data_consts.get_data_path("generated_data.manifest_overlay") if manifest_overlay.table.get(self.__table_name): return False self.__exist_data_cache = setmetatable({}, { "__mode": "v" }) if self.__is_inited: self.unload_data() self.load_data() return True -- Closure assigned: destroy_object def destroy_object(self): self.unload_data() LocaleDataObject.super.destroy_object(self) _M.LocaleDataObject = LocaleDataObject return _M So for translating all ids that not in words_map, you have to find the hotfix file or hook into game hotfix process
  17. Here is a update on my render doc process, i was able to locate to the shader cache list, AND DELETED THE FILE, and my openGL works, in the process of ripping guys 🙂
  18. Thanks, but i tried out the falcom_lst tool with UMDGen but replacing the vag files cause the tool to return an error. I guess a new and better tool should be created to handle the English .vag files or other modded files. and then repack as ISO.
  19. Long ago my friend just make Python script for replace extract and replace audio files, have fun guys https://github.com/FMate01/wolfeinstein-tweeker
  20. Anybody can help me extract localization file? I try myself but something wrong
  21. I tried it out recently with the newest updates, but it doesn't work well with the game from my testing. UVs do not export correctly at all and there's no local mesh space support (which I don't think there ever will be). Maybe if I change around some settings I could get UVs but without the rest pose the models are mostly useless to me.
  22. Yesterday
  23. As per i am a good for nothing in 3d model issues., i can´t tell if te unpack works, but studying DB, i can see 2 types of TOC. Attached the py script, if someone wants to take a look. just drop the files DB or bins in .py or double click in .py black_ps2_unpack.py
  24. Version 1.0.0

    1 download

    This tool is a dedicated utility designed for modifying Konami games on the PlayStation 1 (PSX). It specifically manages .FAD files, which are proprietary archives used by Konami to store game data. Key Features: Unpacker: It allows you to extract the contents of .FAD archives, giving access to internal game assets such as textures, models, and audio. Repacker: It enables you to rebuild valid .FAD files from extracted folders. This is crucial for inserting modified files back into the game ISO. Compatibility: The tool supports a variety of Konami titles on the PS1 that utilize this specific file structure. FadTool-Konami.zip
  1. Load more activity
×
×
  • Create New...