What's new

Back to Metroid Prime hacking

interdpth

New member
Hello, my name is interdpth, and i've been scouring through the net for data on those CMDL's and stuff. So far I can just draw the points of a model but I can do that pretty good as you can see
http://interdpth.arc-nova.org/SAMUS.png

But that's all I got so far.
I have the basic CMDL header that shalted guy posted. I see the unknown section has patterns in it, i've had a little help from Sarah Harp, and hoping to get more.

If anyone has any data they can share. PLEASE DO. This is my first 3D app, you may know me for my MZM and MF editors Double Helix and Zero Fission.

So help? XD


I found how to reference the texture files. But that's my only progress so far. Still better than nothing.
 
Last edited:

Sercio

New member
Saraharp didnt finish his job. There is no release of his viewer for over 2 years now :(
Curious if something might happen...
 
OP
I

interdpth

New member
The more help I get, the sooner my own can be released. Currently it just reads CMDL's compressed or uncompressed it auto decompresses and reads just the first segment. If anyone wants to help, I can show my CMDL header and tell how I read it. @_@

ANY HELP is appreciated especially how to tell what a segment is and stuff i'll be here all week. =p

I'll have it loading directly from a pak when I can get the models displaying, than directly from the games! ^_^
 
Last edited:

Fluesopp

New member
Have you looked at the code for Thakis' BMD viewer? It might give you a good idea of how to do the rendering.
 
OP
I

interdpth

New member
Yeah, i've looked, i'll be using it for rendering help.

But first I need to get the data figured out @_@

and I can't get in touch with the almighty Thakis i've heard about.


Edit:

If anyone could give me details on how to load textures and map them, that'd be lovely :)
 
Last edited:

revel8n

New member
Progress Update

Hello All,
New here but hopefully my first post will be worth the read.

i have been interested in game file format reverse engineering for a while now, and after getting accustomed to things over on the xentax.com forums, i finally got around to looking into some of the various nintendo related games.

Since Metroid Prime was one of the games i had intended on getting into at some point in the future anyway, with the renewed (continued?) interest in the topic, i offered to help interdpth out with his endeavor to reverse the formats. Having started a little before the beginning of last week we have had a good bit of progress on things, so i am here with my first post to update everyone on how things are going.

So far the CMDL file is mostly done with concern to determining where the vertices, normals, uv, and index information resides. Models can currently be rendered without textures. The texture file information is known and a version that supports at least preliminary support for them should hopefully be done in the near future. For the moment the main things missing from this format is the determination of the texture stage information for blending, texture coordinate usage in multitexture, and some of the data that determines the number of indices present in the index data.

There is also a start on the CINF and CSKR skeleton and skinning information data, but this still needs a bit of testing with the model data, and there is a version of the CSKR format that contains some extra information that still needs to be deciphered as it is not present in all CSKR files. Hopefully the ANCS and ANIM formats will come to follow soon after.

Still trying to get more accustomed to the way the gamecube and revolution handle things as this is the first gamecube format i have worked with. But hopefully things will come together nicely in the end.

i have probably missed some things, but oh well, heh.






 
OP
I

interdpth

New member
Basic texture support has been added.
:)

Some textures like Samus show as all color...
Should have that fixed soon I hope.

I think we'll have a release within the month guaranteed, as revl8n we still need to determine blending and all that, but I think we'll get it done soon, but check out this pirate in the mean time. :)
pirate-1.png
 
Last edited:

MasterPhW

Master of the Emulation Flame
It's nice to see, that there is still interest in Metroid hacking and that you already archived that much stuff.
Your IRC chat is also funny. xD
Keep up the good work!
 

revel8n

New member
Texture Work

Just a quick update on the status of textures. They work! For the most part anyway. Still a few formats to work out. Now to work out the blending and other assignment flags as it appears some of the textures are used to specify specular or other appearance attributes for rendering.

textures.png
 
OP
I

interdpth

New member
Possibly after we get this segment figured out and the mesh headers, I'd like to not release it until we have basic support for all the files in all the games, but, revl8n has his own say, he can release whenever he's ready as I can too. So who knows?

But it will be released, and it will be open source! ^_^

if someone could come on and tell us how the material segment is laid out that'd be really awesome, the stuff after what texture what segment uses. >_> Attribute data and the like
 
Last edited:

antidote

New member
Sarah! oh Sarah! *picks up rock*

hmm... sorry can't find him...

Wish I knew how to help you, i'll take a look but I know next to nothing about image formats.
 
OP
I

interdpth

New member
Got blending and all that stuff working. So new screenshots.
Tomorrow i'll take a look at material defs seeing as how I now know lighting is controlled in there.

The viewer is officially called MPxViewer.
Revl8n is taking a look at the animation stuff right now, hopefully we can finish CMDL soon, and move on to other things.

There's a surprise at the end XD

betagravity.png
Beta Gravity
insideship.png
Yes, there is more to the inside, it's just that circle textured. We never see inside it...I wonder why they felt the need to texture it
planet.png

powersuit.png

varia.png


Basic MP2 support.
Material Definitions and other bugs are plaguing MPxViewer for now, support will be added of course. :)
lololol.png
 
OP
I

interdpth

New member
Yes of course there will be MP3 support! ^_^

Honestly i've had enough of the CMDL format, we'll probably get back to eventually, but models render amazingly.

But in this update, you'll see that we have a tree view now, it needs a bit more work. XD

But raw texture viewer is now implemented, and a skeleton viewer is too! ^_^

Chozo.png

Flaahgra.png

Morphball.png

Skeleton.png
Samus's skeleto
TextureViewer.png
some cool looking texture.
 

antidote

New member
mp3 lzo compression = cracked

Code:
//version 2.0 (20061001)
//by thakis

//decompresses compressed metroid prime files.
//metroid prime 1 uses zlib compression,
//metroid prime 2 uses segmented LZO1x (thanks to SkippyJr
// for pointing this out)

//zlib decompression is handled by http://www.zlib.net/,
//LZO code (lzo.h/c) was taken from ffmpegs libavcodec.

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zlib.h"
#include "lzo.h"

using namespace std;

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;

char* fname;
vector<u8> dst;

inline void toWORD(u16& d)
{
    u8 w1 = d & 0xff;
    u8 w2 = (d >> 8) & 0xff;
    d = (w1 << 8) | w2;
}

inline void toDWORD(u32& d)
{
    u8 w1 = d & 0xff;
    u8 w2 = (d >> 8) & 0xff;
    u8 w3 = (d >> 16) & 0xff;
    u8 w4 = d >> 24;
    d = (w1 << 24) | (w2 << 16) | (w3 << 8) | w4;
}

#pragma pack(push, 1)

struct HeaderMP1_2
{
    u32 uncompSize;
    //mp1 has 0x78da (zlib stream with maximal compression)
    //mp2 has something else :-P (lzo doesn't seem to have a header)
    u16 compressionMethod;
};

struct HeaderMP3
{
    char id[4];
    u32 unk; // version maybe?
    u32 unk2; // Hash?
    u32 uncompSize;
};


#pragma pack(pop)
int decompressZLib(u8* source, int sourceSize, u8* dest, int dstSize)
{
    int ret;
    z_stream strm;

    // allocate decompression state
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    strm.avail_in = sourceSize;
    strm.next_in = source;
    ret = inflateInit(&strm);
    if (ret != Z_OK)
        return ret;

    //decompress input
    strm.avail_out = dstSize;
    strm.next_out = dest;
    ret = inflate(&strm, Z_NO_FLUSH);
    assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
    switch (ret)
    {
    case Z_NEED_DICT:
        ret = Z_DATA_ERROR;     /* and fall through */
    case Z_DATA_ERROR:
    case Z_MEM_ERROR:
        (void)inflateEnd(&strm);
        return ret;
    }

    assert(strm.avail_out == 0);
    assert(ret == Z_STREAM_END);

    // clean up and return
    (void)inflateEnd(&strm);
    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}

int decompressLZO(u8* source, int sourceSize, u8* dest, u32& dstSize)
{
    int size = dstSize;
    int result = lzo1x_decode(dest, &size, source, &sourceSize);
    dstSize = size;
    return result;
}

void WriteFile(FILE * inFile, u32 uncompSize, int size = 0)
{
    if (size == 0)
    {
        u32 bytesLeft = uncompSize;
        while (bytesLeft > 0)
        {
            u16 segmentSize;
            fread(&segmentSize, sizeof(segmentSize), 1, inFile);
            toWORD(segmentSize);
            vector<u8> src(segmentSize);
            fread(&src[0], 1, segmentSize, inFile);

            int result = decompressLZO(&src[0], segmentSize,
                                       &dst[uncompSize - bytesLeft], bytesLeft);

            if ((result & LZO_ERROR) != 0)
            {
                cerr << "Failed to decompress \'" << fname << "\'" << endl;
                system("pause");
                return;
            }
        }
    }
    else
    {
        vector<u8> src(size - 4);
        fread(&src[0], 1, size - 4, inFile);
        fclose(inFile);

        if (decompressZLib(&src[0], size - 4, &dst[0], uncompSize) != Z_OK)
        {
            cerr << "Failed to decompress \'" << fname << "\'" << endl;
            return;
        }
    }
    //write buffer to output file
    string inName = fname, outName;
    string::size_type pos = inName.rfind('\\');
    if (pos != string::npos)
        outName = inName.substr(0, pos + 1) + "0" + inName.substr(pos + 1);
    else
        outName = "0" + inName;

    FILE* outFile = fopen(outName.c_str(), "wb");
    if (outFile == NULL)
        return;

    fwrite(&dst[0], 1, uncompSize, outFile);
    fclose(outFile);
}

void decompressMP1_2()
{
    FILE* inFile = fopen(fname, "rb");

    //get file size
    fseek(inFile, 0, SEEK_END);
    int size = ftell(inFile);
    fseek(inFile, 0, SEEK_SET);

    //read file
    HeaderMP1_2 h;
    fread(&h, sizeof(h), 1, inFile);
    toDWORD(h.uncompSize);
    toWORD(h.compressionMethod);
    fseek(inFile, -2, SEEK_CUR);

    //decompress to buffer
    dst.resize(h.uncompSize);
    if (h.compressionMethod == 0x78da)
        WriteFile(inFile, h.uncompSize, size);
    else
        WriteFile(inFile, h.uncompSize);
}

void decompressMP3()
{
    FILE* inFile = fopen(fname, "rb");

    HeaderMP3 h;

    fread(&h, sizeof(h), 1, inFile);
    toDWORD(h.unk);
    toDWORD(h.unk2);
    toDWORD(h.uncompSize);

    dst.resize(h.uncompSize);

    WriteFile(inFile, h.uncompSize);
}

int main(int argc, char* argv[])
{
    if (argc < 2)
        return EXIT_FAILURE;

    FILE* inFile = fopen(argv[1], "rb");
    if (inFile == NULL)
        return EXIT_FAILURE;
    fname = argv[1];
    u16 tmp;
    fread(&tmp, sizeof(tmp), 1, inFile);
    toWORD(tmp);
    fclose(inFile);
    switch (tmp)
    {
    case 0x434d:
        decompressMP3();
        break;
    default:
        decompressMP1_2();
        break;
    }

    return EXIT_SUCCESS;
}

currently the code is rather rough because i JUST cracked it and haven't had a chance to clean up the source and add support for the other formats back. so currently it can only decompress metroid prime 3 files

EDIT:
cleaned and reorginized
Download here: mDecomp.zip
EDIT2:
Hmmm it seems that TXTR files use a different compression scheme, i'll have to look into that.
 
Last edited:

Top