• Ever wanted an RSS feed of all your favorite gaming news sites? Go check out our new Gaming Headlines feed! Read more about it here.

sweetmini

Member
Jun 12, 2019
3,921
That's one question that doesn't have only one answer, since it depends on your country laws on reverse engineering. ;)

In mine it's fully legal as long as the code is not accompanied by the original binaries, was not retrieved through unlawful means (hacking of the developer computers for example) and was not made using stolen tools.
 

DanteLinkX

Banned
Oct 27, 2017
3,730
What can I do with this? Port Mario 64 to unreal engine 4? Rebuild it with sunshine assets? Por its levels to galaxy engine?
 

P-Tux7

Member
Mar 11, 2019
1,344
This repo contains a full decompilation of Super Mario 64 (J) and (U). The source and data have been decompiled but complete naming and documentation all of the code and data is still a work in progress. Decompiling the (E) ROM is also an ongoing effort. It builds the following ROMs: sm64.jp.z64 sha1: 8a20a5c83d6ceb0f0506cfc9fa20d8f438cafe51sm64.us.z64 sha1: 9bef1128717f958171a4afac3ed78ee2bb4e86ce This repo does not include all assets necessary for compiling the ROMs. A prior copy of the game is required to extract the required assets.
Sounds like anything copyrighted isn't included and you need your own copy of the game in order to get the Mario parts. If you can compile this for other systems and we see a non-Mario edition, it would be pretty cool IMO. As long as it's sufficiently easy for kids to edit how objects work and build their own levels as a learning tool.
 

ekim

Member
Oct 26, 2017
3,405
What can I do with this? Port Mario 64 to unreal engine 4? Rebuild it with sunshine assets? Por its levels to galaxy engine?

Depending on the completeness of the code and availability of external libs:
Completely change the game logic, compile and play it.
It can also help to find new glitches (or add them) for speedruns.
 
May 26, 2018
24,006

MealyJointBobolink-size_restricted.gif
 

Deleted member 12790

User requested account closure
Banned
Oct 27, 2017
24,537
As I mentioned in the last topic on this, calling this a "full decompilation" is only technically correct. It is a mechanical decompilation, but it's not nearly complete enough for full comprehension. Like a mechanical disassembly, all symbols are missing until the community goes back and relabels everything, and if you go through the source only a small portion of that is done. Much of it is still incomprehensible stuff like:

Code:
struct Object *Unknown802C8460(struct Object *a) {
    struct Object *sp24;
    UNUSED s32 unused;
    s32 i;

    for (i = 0; i < a->numCollidedObjs; i++) {
        print_debug_top_down_objectinfo("ON", 0);
        sp24 = a->collidedObjs[i];
        if (sp24 != gMarioObject)
            return sp24;
    }
    return NULL;
}

int func_802C8504(struct Object *a, struct Object *b) {
    f32 sp3C = a->oPosY - a->hitboxDownOffset;
    f32 sp38 = b->oPosY - b->hitboxDownOffset;
    f32 dx = a->oPosX - b->oPosX;
    UNUSED f32 sp30 = sp3C - sp38;
    f32 dz = a->oPosZ - b->oPosZ;
    f32 collisionRadius = a->hitboxRadius + b->hitboxRadius;
    f32 distance = sqrtf(dx * dx + dz * dz);

    if (collisionRadius > distance) {
        f32 sp20 = a->hitboxHeight + sp3C;
        f32 sp1C = b->hitboxHeight + sp38;

        if (sp3C > sp1C)
            return 0;
        if (sp20 < sp38)
            return 0;
        if (a->numCollidedObjs >= 4)
            return 0;
        if (b->numCollidedObjs >= 4)
            return 0;
        a->collidedObjs[a->numCollidedObjs] = b;
        b->collidedObjs[b->numCollidedObjs] = a;
        a->collidedObjInteractTypes |= b->oInteractType;
        b->collidedObjInteractTypes |= a->oInteractType;
        a->numCollidedObjs++;
        b->numCollidedObjs++;
        return 1;
    }

    //! no return value
}

int func_802C870C(struct Object *a, struct Object *b) {
    f32 sp3C = a->oPosY - a->hitboxDownOffset;
    f32 sp38 = b->oPosY - b->hitboxDownOffset;
    f32 sp34 = a->oPosX - b->oPosX;
    UNUSED f32 sp30 = sp3C - sp38;
    f32 sp2C = a->oPosZ - b->oPosZ;
    f32 sp28 = a->hurtboxRadius + b->hurtboxRadius;
    f32 sp24 = sqrtf(sp34 * sp34 + sp2C * sp2C);

    if (a == gMarioObject)
        b->oUnk190 |= 2;

    if (sp28 > sp24) {
        f32 sp20 = a->hitboxHeight + sp3C;
        f32 sp1C = b->hurtboxHeight + sp38;

        if (sp3C > sp1C)
            return 0;
        if (sp20 < sp38)
            return 0;
        if (a == gMarioObject)
            b->oUnk190 &= ~2;
        return 1;
    }

    //! no return value
}

void func_802C88A8(struct Object *a) {
    struct Object *sp4 = (struct Object *) a->header.next;

    while (sp4 != a) {
        sp4->numCollidedObjs = 0;
        sp4->collidedObjInteractTypes = 0;
        if (sp4->oIntangibleTimer > 0)
            sp4->oIntangibleTimer--;
        sp4 = (struct Object *) sp4->header.next;
    }
}

void func_802C8918(struct Object *a, struct Object *b, struct Object *c) {
    if (a->oIntangibleTimer == 0) {
        while (b != c) {
            if (b->oIntangibleTimer == 0) {
                if (func_802C8504(a, b) && b->hurtboxRadius != 0.0f)
                    func_802C870C(a, b);
            }
            b = (struct Object *) b->header.next;
        }
    }
}

It'll still take an enormous effort to get this into something really usable.

But for those wondering, this is a big step towards generating a community source code to Mario 64. The Sonic the Hedgehog community did this exact same thing many years ago:

 

mugurumakensei

Elizabeth, I’m coming to join you!
Member
Oct 25, 2017
11,320
As I mentioned in the last topic on this, calling this a "full decompilation" is only technically correct. It is a mechanical decompilation, but it's not nearly complete enough for full comprehension. Like a mechanical disassembly, all symbols are missing until the community goes back and relabels everything, and if you go through the source only a small portion of that is done. Much of it is still incomprehensible stuff like:

Code:
struct Object *Unknown802C8460(struct Object *a) {
    struct Object *sp24;
    UNUSED s32 unused;
    s32 i;

    for (i = 0; i < a->numCollidedObjs; i++) {
        print_debug_top_down_objectinfo("ON", 0);
        sp24 = a->collidedObjs[i];
        if (sp24 != gMarioObject)
            return sp24;
    }
    return NULL;
}

int func_802C8504(struct Object *a, struct Object *b) {
    f32 sp3C = a->oPosY - a->hitboxDownOffset;
    f32 sp38 = b->oPosY - b->hitboxDownOffset;
    f32 dx = a->oPosX - b->oPosX;
    UNUSED f32 sp30 = sp3C - sp38;
    f32 dz = a->oPosZ - b->oPosZ;
    f32 collisionRadius = a->hitboxRadius + b->hitboxRadius;
    f32 distance = sqrtf(dx * dx + dz * dz);

    if (collisionRadius > distance) {
        f32 sp20 = a->hitboxHeight + sp3C;
        f32 sp1C = b->hitboxHeight + sp38;

        if (sp3C > sp1C)
            return 0;
        if (sp20 < sp38)
            return 0;
        if (a->numCollidedObjs >= 4)
            return 0;
        if (b->numCollidedObjs >= 4)
            return 0;
        a->collidedObjs[a->numCollidedObjs] = b;
        b->collidedObjs[b->numCollidedObjs] = a;
        a->collidedObjInteractTypes |= b->oInteractType;
        b->collidedObjInteractTypes |= a->oInteractType;
        a->numCollidedObjs++;
        b->numCollidedObjs++;
        return 1;
    }

    //! no return value
}

int func_802C870C(struct Object *a, struct Object *b) {
    f32 sp3C = a->oPosY - a->hitboxDownOffset;
    f32 sp38 = b->oPosY - b->hitboxDownOffset;
    f32 sp34 = a->oPosX - b->oPosX;
    UNUSED f32 sp30 = sp3C - sp38;
    f32 sp2C = a->oPosZ - b->oPosZ;
    f32 sp28 = a->hurtboxRadius + b->hurtboxRadius;
    f32 sp24 = sqrtf(sp34 * sp34 + sp2C * sp2C);

    if (a == gMarioObject)
        b->oUnk190 |= 2;

    if (sp28 > sp24) {
        f32 sp20 = a->hitboxHeight + sp3C;
        f32 sp1C = b->hurtboxHeight + sp38;

        if (sp3C > sp1C)
            return 0;
        if (sp20 < sp38)
            return 0;
        if (a == gMarioObject)
            b->oUnk190 &= ~2;
        return 1;
    }

    //! no return value
}

void func_802C88A8(struct Object *a) {
    struct Object *sp4 = (struct Object *) a->header.next;

    while (sp4 != a) {
        sp4->numCollidedObjs = 0;
        sp4->collidedObjInteractTypes = 0;
        if (sp4->oIntangibleTimer > 0)
            sp4->oIntangibleTimer--;
        sp4 = (struct Object *) sp4->header.next;
    }
}

void func_802C8918(struct Object *a, struct Object *b, struct Object *c) {
    if (a->oIntangibleTimer == 0) {
        while (b != c) {
            if (b->oIntangibleTimer == 0) {
                if (func_802C8504(a, b) && b->hurtboxRadius != 0.0f)
                    func_802C870C(a, b);
            }
            b = (struct Object *) b->header.next;
        }
    }
}

It'll still take an enormous effort to get this into something really usable.

But for those wondering, this is a big step towards generating a community source code to Mario 64. The Sonic the Hedgehog community did this exact same thing many years ago:


func_802C870C is doing spherical collision detection right?
 

Deleted member 12790

User requested account closure
Banned
Oct 27, 2017
24,537
func_802C870C is doing spherical collision detection right?

That's the gist, yes, but on what kind of objects? Context is needed in how that function is called in order to properly label it, which makes the overall source code much more readable. And most of the source code is like that currently. It's not an insurmountable problem, it's just not quite ready for people to use for larger projects yet.
 

adumb

Banned
Aug 17, 2019
548
Oh nice, so this mean some nice fellows will make super mario 64 II?

It's been done! The creator was supposedly making an even more impressive follow up, but it's been radio silence for years as far as I can tell. At least his first one is finished, available, and genuinely excellent.
 

MondoMega

One Winged Slayer
Member
Jan 10, 2018
47,474
Australia
It's been done! The creator was supposedly making an even more impressive follow up, but it's been radio silence for years as far as I can tell. At least his first one is finished, available, and genuinely excellent.
Star Road 2 is long dead, unfortunately.

Instead, they are working on an updated remake of Star Road (with a lot of new content) using Super Mario 64 DS as a base. The engine is heavily altered though, and a proper control stick mode will be available for emulators. Here's a few (probably outdated) previews:

 
Last edited:

P-Tux7

Member
Mar 11, 2019
1,344
Star Road 2 is long dead, unfortunately.
Didn't he once say it would have had 300 stars? I can see why that would have died LMAO

Skelux (that guy) does seem to be kind of scuzzy though, his highest Patreon tier is

12 solid hours of my time per month, which can be spent on whatever you please, be it a personal project or otherwise. Can also be used for requested features in my own projects.
Sounds illegal of him to charge for making hacks where the Nintendo IP is the main draw. Even if Nintendo will never sue it's still unethical to take advantage of that fact.
 

Deleted member 55822

User requested account closure
Banned
Apr 10, 2019
698
Didn't he once say it would have had 300 stars? I can see why that would have died LMAO

Skelux (that guy) does seem to be kind of scuzzy though, his highest Patreon tier is


Sounds illegal of him to charge for making hacks where the Nintendo IP is the main draw. Even if Nintendo will never sue it's still unethical to take advantage of that fact.
Unrelated, but I remember him saying about making a Mario Odyssey mod which made every Moons to have its own objective instead a majority being floating around in the final game.

It's a really huge workload if you can't tell. And he had backpedaled on that front since then iirc.
 
Nov 2, 2017
6,804
Shibuya
That's one question that doesn't have only one answer, since it depends on your country laws on reverse engineering. ;)

In mine it's fully legal as long as the code is not accompanied by the original binaries, was not retrieved through unlawful means (hacking of the developer computers for example) and was not made using stolen tools.
Is distributing it not inherently forbidden? Just asking because I am actually uncertain.
 

Garlic

Member
Oct 28, 2017
1,687
Star Road 2 is long dead, unfortunately.

Instead, they are working on an updated remake of Star Road (with a lot of new content) using Super Mario 64 DS as a base. The engine is heavily altered though, and a proper control stick mode will be available for emulators. Here's a few (probably outdated) previews:



This guy loves biting Bomberman 64 music, huh?

That stuff looks really nice, actually.
 

Blackpuppy

Member
Oct 28, 2017
4,195
Uh, is a widescreen hack now possible? Because I would like that.

In theory, ports with 60fps, widescreen, ray tracing, 8k is all possible... but the code still needs some deciphering and then it's a matter of getting people to port it to modern stabdards. Not impossible but it's going to take some work.
 

Deleted member 23212

User requested account closure
Banned
Oct 28, 2017
11,225
That's one question that doesn't have only one answer, since it depends on your country laws on reverse engineering. ;)

In mine it's fully legal as long as the code is not accompanied by the original binaries, was not retrieved through unlawful means (hacking of the developer computers for example) and was not made using stolen tools.
Reverse engineering is legal, right?
 

Vague Rant

Member
Oct 28, 2017
81
Melbourne, Australia
Is that true widescreen?
Yeah, the 3D elements are being rendered to a 16:9 aspect ratio with more visible on the sides and the HUD stuff has been moved out to the edges as well instead of sitting in the 4:3 area and/or stretching. The author also had to edit things like the Mario rubber face screen to make the background extend out further and that sort of thing.
 

Zeenbor

Developer at Run Games
Verified
Oct 25, 2017
74
Very interesting to look at. This seems like you could completely rebuild the game + assets and run on hardware - a monumental achievement if that's the case! They even decompiled libultra (N64 SDK)... These are some talented folks.

There was an old Mario 64 decompilation from Nagra in #n64dev back in the late 90s. I wonder if that was at all used as reference.
 

sweetmini

Member
Jun 12, 2019
3,921
Reverse engineering is legal, right?

In the US, it is legal under "fair use", however USA law logic as i understand it is that if there is a user license agreement that forbids disassembly/reverse engineering/etc, the EULA overrules the legislation.

In europe, under the veil of interoperability, it is permitted, this overrules many license agreements terms forbidding disassembly (interoperability = you want to make a plugin for the thing , you try to understand why it crashes your other software or crashes by itself, you want to allow operation under another OS, etc). The law protecting the right of the user to interoperability overrules the EULA.

In japan it is not prohibited (and it was almost required if you wanted to make early games at a time before dev kits and developers portals...).

In china ... ahaha... a former company of mine stopped selling to china because they sold a piece of software very specialized to a chinese company, and later discovered they disassembled, remade the software and sold it themselves (there were dummy functions, with little purpose, just used to "watermark" the logic, and they reproduced them) . So even if it were illegal, they don't give a blip, legal recourse was unsuccessful.

In India, it seems authorized under the interoperability veil, since it's the only way to properly get the essential information about the program logic.

In russia, it is permitted for interoperability

Here, a piece about it covering USA, Japan and europe: http://blog.thecorporateattorneys.c...ensing-issues-us-businesses-europe-japan.html

If it were not legal in the dominant markets, IDA wouldn't exist anymore ;)
 

tehz

Member
Oct 30, 2017
14
Very interesting to look at. This seems like you could completely rebuild the game + assets and run on hardware - a monumental achievement if that's the case! They even decompiled libultra (N64 SDK)... These are some talented folks.

There was an old Mario 64 decompilation from Nagra in #n64dev back in the late 90s. I wonder if that was at all used as reference.

Wow, was there really a 90s era decompilation effort? Nothing like that was even known about afiak
 

Wowfunhappy

Member
Oct 27, 2017
3,102
...I'm not understanding how this falls under fair use. I mean, it should absolutely be legal to decompile the game, but not to distribute the decompiled code.

If this is the same project that leaked a little while ago, it can be recompiled into a binary-identical SM64 rom, which is obviously Nintendo copyrighted.

Edit: Oh, they removed some necessary assets from the repository! Even so, they're effectively redistributing Nintendo's game engine...
 

TripaSeca

Member
Oct 27, 2017
2,762
São Paulo
...I'm not understanding how this falls under fair use. I mean, it should absolutely be legal to decompile the game, but not to distribute the decompiled code.

If this is the same project that leaked a little while ago, it can be recompiled into a binary-identical SM64 rom, which is obviously Nintendo copyrighted.

Edit: Oh, they removed some necessary assets from the repository! Even so, they're effectively redistributing Nintendo's game engine...

The thing is, it's not reeealy decompiled. It's rewrote.
It's more like a manual re-doing of the code from its binaries... At least that's what I understood it was from what the release said.
 

Wowfunhappy

Member
Oct 27, 2017
3,102
The thing is, it's not reeealy decompiled. It's rewrote.
It's more like a manual re-doing of the code from its binaries... At least that's what I understood it was from what the release said.

They rewrote some stuff, but it's still largely decompiled—that's why a lot of the functions and such aren't labeled (yet).

But, even if was a complete rewrite, it would need to be a "clean room" rewrite in order for Nintendo to not have copyright—ie, made without looking at the original code, including assembly code.
 

Deleted member 12790

User requested account closure
Banned
Oct 27, 2017
24,537
They rewrote some stuff, but it's still largely decompiled—that's why a lot of the functions and such aren't labeled (yet).

But, even if was a complete rewrite, it would need to be a "clean room" rewrite in order for Nintendo to not have copyright—ie, made without looking at the original code, including assembly code.

A) This isn't assembly code, this is bytecode.

B) This is remade without looking at the original source code. This is decompiled from bytecode. The source code produced from this decompilation, is not the source code Nintendo wrote. Assemblers are not rote 1:1 mappings of the assembly source. Compilers are not rote 1:1 mappings to assembler code. Optimization happens which makes the end result bytecode different from Nintendo's source. The same applies in reverse. This decompilation is producing code that isn't a 1:1 copy of the original. This is clean room reverse engineering.

You can take the same cpp source code, run it through two different compilers -- say MSVC and g++ - then and the resultant bytecodes will be different. You can take those two bytecodes, and decompile them, and you'll wind up with radically divergent original source codes, even with all the labels put back programmatically.

As for why a company shouldn't be able to own bytecode -- that's akin to owning chord progression. The companies in question such as nintendo don't even have finite control over their resultant bytecode from their compilers.
 
Last edited:

Vague Rant

Member
Oct 28, 2017
81
Melbourne, Australia
You could totally compress the 16:9 aspect into 4:3 signal and have it stretch back when viewed on a widescreen TV. IIRC, this was how anamorphic widescreen worked.

Yep, exactly this. There's been games with anamorphic widescreen since the PlayStation and N64, and while Sony and Microsoft pursued native 16:9 resolutions after that, Nintendo stuck with anamorphic right through the GameCube and Wii, which obviously had no "ability to output widescreen video" in the sense the response above meant it, but nonetheless had hundreds of widescreen games.