<- 1  -   of 75 ->
^^
vv
List results:
Search options:
Use \ before commas in usernames
Wow, you nailed it jackoalan. really great! your documentation on PART seems to fit with DKCR and MP3's PART's. But then we have files like RULE which seem to follow their own script, or am I wrong?

Regarding to Antidote, this is why asked to parax on what he was focusing on. It seems completely a waste of time for me to make a tool while someone else is going to make a competing one. This is half true since everyone seems to put their own features in their tools. But still... it would be better to have one kind of open source tool, but I don´t know about the DKCR series for that part, since these games work differently?
If DKCR's similar enough to MP3 then it probably won't be a big deal to support it, since I definitely intend on supporting MP3. I haven't spent much time with either yet, but they seem to be extremely similar from what I've seen. I don't think I've seen any DKCR formats that aren't also in MP3.
Quote:
then we have files like RULE which seem to follow their own script, or am I wrong?


So far, my research has been limited to MP1 only. I can't comment on other Retro games at the moment.

In other news, here's the doc for PATH:
http://www.metroid2002.com/retromodding/wiki/PATH_(File_Format%29
Edit history:
jackoalan: 2015-02-22 05:19:22 am
jackoalan: 2015-02-22 05:15:13 am
jackoalan: 2015-02-22 04:41:13 am
jackoalan: 2015-02-22 04:22:38 am
Okay.. A much more exciting particle effect... Now as a 720p60 youtube video:


It doesn't look completely right due to the black background
Edit history:
Aruki: 2015-02-22 10:05:41 pm
Aruki: 2015-02-22 09:58:07 pm
Aruki: 2015-02-22 08:02:30 pm
MP3 materials are proving to be fairly difficult to figure out specifics on. It seems that what they did was they set up the materials to only use a mix of certain preset configurations, rather than allowing the ability to set every little thing manually like in MP1/2. From what I can tell the advantage of that is that they were able to construct display lists that could be called to set up the material rather than calling each SetTev* function manually, which would've offloaded material setup onto the GPU and probably given them a nice performance boost. The downside of that for us is it's rather difficult to tell specifically what values are being set with each configuration... there's not that many small things that can be tweaked to get good results out of the Dolphin shader dumps, and finding the values that get set in the code isn't as simple as tracking calls to the SetTev* functions. So I'm a little stumped for now as to how to go about figuring this out.

All this might be completely wrong, still looking into it.

I did add some very very basic support though, only displays diffuse maps for now

edit: okay, so starting to think I'm sorta right but sorta wrong. It doesn't call the GXSetTev* functions, but it DOES call the CGX equivalents (Retro's wrapper class around GX functions). What threw me off is that the CGX functions don't call the GXSetTev* functions either. It seems to be passing raw GPU commands somewhere. Still haven't figured it out but I think I'm getting somewhere at least. If the materials are calling CGX's SetTev* functions then that should be feasible to track down.
Edit history:
jackoalan: 2015-02-23 12:09:11 am
jackoalan: 2015-02-23 12:09:02 am
OK. ANIM doc now complete:
http://www.metroid2002.com/retromodding/wiki/ANIM_(File_Format%29
Hey, everyone. I've been lurking here a long while, so I figured I'd contribute something. I found out what of the unknowns in SCAN does; it controls where the image appears on screen:
http://www.metroid2002.com/retromodding/wiki/SCAN_(Metroid_Prime%29

I have a few more images to put up, but I'm worried about image overload on that page. Especially considering:
- Position 0x03 only appears when you scan Omega Pirate's projectile
- Positions 0x0A and 0x0D only appear for an unused Chozo Elder scan
- Positions 0x07, 0x08, 0x0B, 0x0C, 0x11, and 0x12 are completely unused
It seems like uploading all of those images would just clutter the page with useless information.

Another thing I found in that the first image to appear (regardless of whether it's the first scan image in the array or the fourth) will "fly in" from the side, while the remaining images will "fade in". However, if the first image to appear is a blank image, nothing will fly in. I have no clue how to put this on the wiki page, however, since it really doesn't have anything to do with the SCAN format itself.
I think we should be able to set up a gallery on the wiki page, so image overload shouldn't be a problem. Documenting all the possible positions isn't really useless IMO. Also, the thing about flying in sounds relevant; I'd put it on the page somewhere.

Might be worth creating another header section separate from the "Format" one to document stuff like this.
Thanks for that info, and for the future: if ANY of you think you have any information that might be useful don't be afraid to post it, if it can be verified then it certainly belongs on the wiki.
Cool, good to have those scan visor image panes figured out.

I added a column of the FRME_ScanHud widget names relating the contained transformation matrices to your findings
That's pretty handy.
Edit history:
Aruki: 2015-02-23 03:30:16 am
I guess since we're all posting wiki pages now, I've just written what I've come up with so far after spending the day reverse engineering Prime 3's material loading code. Will do more tomorrow. http://www.metroid2002.com/retromodding/wiki/Materials_(Metroid_Prime_3%29
Quote from Antidote:
The table immediately following the language FOURCC list follows this format:
Code:
struct
{
    uint tableSize; // total size of strings
    uint stringOffsets[stringCount];
} lang[languageCount];


The offset is calculated from the beginning of the string pool, so in that example offset 0 points to "1-2 King of Cling".

I looked again to this and I found something odd.

The name pointer section begins with 4 bytes of a repeat of the name counter in the header. that is to begin with already weird. then it is followed by 4 bytes of the whole section. then blocks of 8 bytes with 4 bytes being the offset and the next 4 bytes being a priority counter?

after the language fourCC list we got, as you said, 4 bytes for the table size. but this doesn't make sense at all. the number doesn't seem to fit with any calculation. then we got blocks of 4 bytes which are the offsets for each field/name.

after that we should get like a normal strg a list of counters and pointers, but what I see is very odd. first we seem to have a absolute offset, and then a relative offset. that seems to be a pointer block but then we get a 32 bit value which doesn't fit with absolute or relative offsets.

I hope you understand what my troubles are here.

on a side note, I tried to convert a TXTR (type 08 not 0A) to a png format. as you can see there obviously went something wrong while reading the blocks. but not the pixels! the whole image just seems to be messed up.
Edit history:
Aruki: 2015-02-23 11:34:49 am
Aruki: 2015-02-23 11:31:15 am
Aruki: 2015-02-23 11:30:41 am
Quote from Jesse:
after the language fourCC list we got, as you said, 4 bytes for the table size. but this doesn't make sense at all. the number doesn't seem to fit with any calculation.


Okay, so take FrontEnd/00ccc151d0c8eb00.STRG for example. The first table size, for the English strings, is listed as 0xF2. Then it's followed by 7 string offsets, since the file has 7 strings as indicated by the header. So we start following those offsets at the start of the string table, at 0x180. Each of those strings starts with a size value. The sizes each of those 7 strings are: 0x1A, 0x1D, 0x1D, 0x26, 0x2A, 0x22, 0x2C. Add those up, and you get 0xF2. That's how the size works.

Also, the name section does not have a repeat of the name counter in the header, it has a separate name count. What you're probably seeing is that every string has a name, so the name count matches the string count (the header value).
Edit history:
Antidote: 2015-02-24 02:44:13 am
I'm sure a few of you seen Skyrim's making of video and saw how they put the maps together, well Metroid Prime was put together in a very similar fashion, and luckily enough we can still physically see that in the level models:
Cracked UV animation mode 7 today, which mean all UV animations are now 100% cracked. I've implemented support for it in PWE, so now all UV animation modes play back correctly. Antidote's added it to RetroView as well. Details on the wiki.
Quote from Antidote:
I'm sure a few of you seen Skyrim's making of video and saw how they put the maps together, well Metroid Prime was put together in a very similar fashion, and luckily enough we can still physically see that in the level models:

I'm confused, what exactly is going on here?
I pulled a few of the "legos" that made the level out of their homes, to demonstrate how retro built that room.
I know what you're trying to show and I can barely even tell what's in that picture, lol.
Lol, I'll do something a bit better here in a bit

100% custom, (need to rig that pipe and pose it properly)
is DDS by any chance exactly the same as a 0xA TXTR format? I have been looking for days into this txtr.ms script now and the only thing what happens is putting these blocks of data in the right order, but no actual conversion is going on.

The easiest format for me to convert to PNG is until now the 0x8 format, even that is simple yet I am running into trouble with ordering every pixel due to this pixel block system. I tried to do 0xA formats now but this is simply getting impossible, even though I can get pallete data, I need to have some kind of magic formula which makes a sensible 32 byte pixel from the two bits I get. I am starting to think these maxScripts contain some kind of secret functions or something.
Edit history:
Aruki: 2015-02-26 11:20:16 am
Aruki: 2015-02-26 11:14:21 am
0xA is CMPR, aka BC1/DXT1. DDS is a texture format that supports a bunch of different common texture formats, including DXT1. So the TXTR maxscript doesn't need to decode the blocks, it just needs to unswizzle them so they display correctly on a PC. That's why you don't see any conversion happening in the script.

This page has some info on how CMPR works: http://wiki.tockdom.com/wiki/Image_Formats#CMPR Basically 4x4 blocks where each 8-byte block has its own color palette; the first 4 bytes are a pair of 16-bit color values that are the first two palettes, the last two palettes are created by interpolating the first two, and then the remaining 4 bytes are 16 two-bit palette indices that represent the actual pixels.

I find it pretty easy to work with DDS :P If I were you I'd consider learning how that works and working with that instead; it removes the need to fully decode most of the texture formats. PWE decodes the game's 11 texture formats into six possible internal formats: Luminance, LuminanceAlpha, RGBA4, RGBA565, RGBA8, and DXT1. All of those can be easily directly exported to DDS. It also means I can easily create custom textures by letting a program like Photoshop do the actual encoding for me when it saves to DDS, and then just swizzle the resulting image so it looks good in the game. But if you do wanna decode them to png, hopefully that info helps.
Converting to PNG is actually pretty simple and my TXTR code supports both DDS and PNG, not really any extra steps except for CMPR and the intensity formats, CMPR needs to be decompressed (i use squish for that), and the intensity formats are as simple using the intensity value as your RGB. Here is the code I use as an example:

Code:
void Texture::exportPNG(const std::string& path)
{
    // Temporary
    png::image<png::rgba_pixel> output(m_width, m_height);
    atUint8* pixels = nullptr;


    if (m_format == Format::RGBA8 || m_format == Format::RGB565)
        pixels = m_bits;
    else if (m_format == Format::DXT1)
    {
        pixels = new atUint8[m_width * m_height * 4];
        squish::DecompressImage(pixels, m_width, m_height, m_bits, squish::kDxt1);
    }


    atUint32 i = 0;
    for (atUint32 y = 0; y < m_height; ++y)
    {
        for (atUint32 x = 0; x < m_width; ++x)
        {
            // Luminance, and Luminance Alpha are pretty simple
            // for Luminance we just assign 'l' to our RGB values, and set alpha to 255
            // for Luminance Alpha the alpha value is directly after the luminance value,
            // and we use that value instead
            if (m_format == Format::Luminance || m_format == Format::LuminanceAlpha)
            {
                atUint8 l, a;
                l = *(atUint8*)(m_bits + i);
                i++;
                if (m_format == Format::LuminanceAlpha)
                {
                    a = *(atUint8*)(m_bits + i);
                    i++;
                }
                else
                    a = 0xFF;

                output.set_pixel(x, y, png::rgba_pixel(l, l, l, a));
            }
            // RGB565 is an interesting format, it's in a 565 bit packing (hence RGB565 = Red 5-bits Green 6-bits Blue 5-bits)
            // what this also means is that green gets truncated less in comparison to red and blue,
            // Other than havingt to unpack the bits, it's in reverse order (red being last)
            else if (m_format == Format::RGB565)
            {
                atUint16 rgb = *(atUint16*)(pixels + i);
                atUint8 r, g, b;
                r = ((rgb & 0xF800) >> 11) << 3;
                g = ((rgb & 0x07E0) >>  5) << 2;
                b = ((rgb & 0x001F) >>  0) << 3;
                output.set_pixel(x, y, png::rgba_pixel(r, g, b, 0xFF));
                i += 2;
            }
            // DXT1 and RGBA8 are the same, it's simply a straight copy.
            else if (m_format == Format::DXT1 || m_format == Format::RGBA8)
            {

                output.set_pixel(x, y, png::rgba_pixel(*(char*)(pixels + i + 0),
                                                       *(char*)(pixels + i + 1),
                                                       *(char*)(pixels + i + 2),
                                                       *(char*)(pixels + i + 3)));
                i += 4;
            }
        }
    }

    output.write(path);
}
The problem with dds is is that it is not supported with everything. However there seems to be libraries which actually convert a datadds format to bitmap, Like the devIL.ddl. So I might use that. I feel not much for writing much code while its supported by another library, but having too much dll's is also a pain.