Jump to content

[PC] Moorhuhn Adventure 2 ._img format


Recommended Posts

  • MaxBOOST changed the title to [PC] Moorhuhn Adventure 2 ._img format

> color palette being big endian ... 4 bytes per color, RGB Order, and it starts at offset 0x50.

That sounds reasonable, given there are exactly 256 entries starting from 0x50. The left image is {R,G,B,X} order, and the right is {B,G,R,X} order. Do you know what the expected target image looks like?

image.png.77732eccbd8678ebf68a9230b36ea725.png

Then just after the palette comes some directory of 17-byte records with increasing uint32le offsets (008Ch, 0118h, 011A, 0230h...), presumably to the start of each frame (too small to be a byte offset to the frames given the frames appear ~6'000 bytes apart). I've no idea what the A0, 8C, and 01 mean, but they don't change:

image.png.75daf637f09f1ae0cd684634bc663f63.png

Next comes an array of at least 70 uint32le offsets, which match pretty nicely to the distances you see between frames (e.g. 8611 - 2574 = 6037):

image.png.5fccaf9c1a652a6655f9742f1919402b.png

Then finally comes variable width frames of 8-bpp pixel data, with interesting divisions between each one that might be a header for that frame:

image.png.874478fa4636e1aa6aec354f73552ac3.png

TiledGGD is not going to help with compressed graphics, as it displays linear bitmaps and tiles. This might be a simple run length encoding, or it might trim the edges (some games trim the translucent left and right side of each row, storing a count instead - example), or it might be more advanced. If you can find the matching graphics in their decompressed state (in RAM/VRAM), you could compare them to these and glean some insights. 🤔 (deferring to knowledgeable others for analysis)

Edited by piken
Fix undesirable auto-inserted smiley
  • Like 1
Link to comment
Share on other sites

6 hours ago, piken said:

> color palette being big endian ... 4 bytes per color, RGB Order, and it starts at offset 0x50.

That sounds reasonable, given there are exactly 256 entries starting from 0x50. The left image is {R,G,B,X} order, and the right is {B,G,R,X} order. Do you know what the expected target image looks like?

image.png.77732eccbd8678ebf68a9230b36ea725.png

Then just after the palette comes some directory of 17-byte records with increasing uint32le offsets (008Ch, 0118h, 011A, 0230h...), presumably to the start of each frame (too small to be a byte offset to the frames given the frames appear ~6'000 bytes apart). I've no idea what the A0, 8C, and 01 mean, but they don't change:

image.png.75daf637f09f1ae0cd684634bc663f63.png

Next comes an array of at least 70 uint32le offsets, which match pretty nicely to the distances you see between frames (e.g. 8611 - 2574 = 6037):

image.png.5fccaf9c1a652a6655f9742f1919402b.png

Then finally comes variable width frames of 8-bpp pixel data, with interesting divisions between each one that might be a header for that frame:

image.png.874478fa4636e1aa6aec354f73552ac3.png

TiledGGD is not going to help with compressed graphics, as it displays linear bitmaps and tiles. This might be a simple run length encoding, or it might trim the edges (some games trim the translucent left and right side of each row, storing a count instead - example), or it might be more advanced. If you can find the matching graphics in their decompressed state (in RAM/VRAM), you could compare them to these and glean some insights. 🤔 (deferring to knowledgeable others for analysis)

You are most likely correct. The game does use RLE for most of its files. Issue is I don't know how to decode that RLE. And i do have an idea of what the image might look like.

Link to comment
Share on other sites

ok so i got some help from a friend and dug deeper, and he told me some stuff:

 

It doesn't seem like RLE per se.

The header encodes two pointers paired with counts which could be crucial. You might find these starting at offset 0x38. It's 4 uint32s. Pointer, Count, Pointer, Count.

The first pointer will point to what seems like a list of rectangles. The rectangles are 4 uint32 (left, top, width, height) and then a uint8 (looks like a bool). Amount of rectangles matches the associated count from header.

The second pointer from the header will point to the section that immediately follows the rects.

This section then again encodes yet another list of pointers. Amount of these pointers matches the associated count from header.

These pointers each point to the start of the metadata section for what I presume is an animation frame/sub texture.

These metadata sections seem to look like this:

2x uint32 describing the dimensions?

0xFF00FF00

uint32 that seems to be width x height? But it doesn't always match up

unknown uint32

6x uint32 that seem to encode some unknown ordinal values (0, 1, 2, 4)

uint32 pointer to start of some image data for this particular sub texture, usually directly adjacent

There are some weird bytes injected in the image data occasionally that I cannot quite reason about at the moment. For square textures (especially without more subframes), it always seems to be two bytes after one row width... It could be some form of RLE because their frequency changes in other files but it's quite weird.

  • Like 1
Link to comment
Share on other sites

ok so we analyzed the file again, and it turns out it's not rle at all, but rather it trims the edges.

but i need anything i can use to convert them, even if it's a quickbms script.
I tried doing it myself, but i couldn't. That's why i am asking here

  • Like 1
Link to comment
Share on other sites

15 hours ago, piken said:

Aha, one of my earlier theories 😉 (https://reshax.com/topic/345-zenonia-pzx-file/#comment-1150).

 

> And i do have an idea of what the image might look like.

Sharing a sample or screenshot of the rendered image would help folks to help you.

(I am interested from the puzzle point of view, but my time is already allocated the next week 🥱)

sure, thanks for the tip.

anyways here, it's a vertical sprite sheet with a pink background that contain the images of a plane. these are some of the sprites i managed to take screenshots of.
vlcsnap-2022-06-26-00h56m32s191.png.f218f4f264c3e4c12a965ac1cb9c8044.pngvlcsnap-2022-06-26-18h14m42s17.png.1a30d2047661365177a4a386ae0e5cb3.pngvlcsnap-2022-06-26-05h12m09s233.png.0b5d285c499537d54b52c60b76306493.png

  • Like 1
Link to comment
Share on other sites

9 hours ago, MaxBOOST said:

sure, thanks for the tip.

anyways here, it's a vertical sprite sheet with a pink background that contain the images of a plane. these are some of the sprites i managed to take screenshots of.
vlcsnap-2022-06-26-00h56m32s191.png.f218f4f264c3e4c12a965ac1cb9c8044.pngvlcsnap-2022-06-26-18h14m42s17.png.1a30d2047661365177a4a386ae0e5cb3.pngvlcsnap-2022-06-26-05h12m09s233.png.0b5d285c499537d54b52c60b76306493.png

cuz when my friend looked at it, he mentioned how he found this:

one weird byte
Image data
two weird bytes
Image data
two weird bytes
Image data
etc....

so yeah we're pretty sure it's that.
the image type used by that game is... weird... to say the least.

Link to comment
Share on other sites

Posted (edited)

ok, so i am attempting to write a bms script myself.

endian little
idstring "/x01"
get spriteAmount long
get imageWidth long
get imageHeight long
get unknown1 long
get unknown2 long
get unknown2 long
get null long
get null long
get null long
get PalettePointer long
get PaletteAmount long
get null long
get null long
get BoundingBoxPointer long
get BoundingBoxAmount long
get PointerListPointer long
get PointerAmount long
get null long
get null long

this is what i got so far.

EDIT: decoded all the header.

ok so the pointer list pointer points to the pointers that point to each frame's metadata

Edited by MaxBOOST
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...