Super Mario 64 has been decompiled

CrashOveride

Well-Known Member
Newcomer
Joined
May 29, 2017
Messages
50
Trophies
0
XP
127
Country
United States
You can rewrite the graphics routines to not use F3D if you're porting this, and it's already possible to dump graphics to a higher level format while emulating.

You almost don't have to touch the F3D GBI at all. Only a very small number of graphics are dynamically generated.

So you're saying you'd rather use crappy export from VRML than editing the raw displaylist data?
 

Ecchi95

Well-Known Member
OP
Member
Joined
Jul 7, 2019
Messages
121
Trophies
0
Age
29
XP
891
Country
United States
So you're saying you'd rather use crappy export from VRML than editing the raw displaylist data?
My point is you don't have to use the original models. You could make all new models if you're doing an enhanced port. (Original code, brand new assets.)
 

Zacharybinx34

Active Member
Newcomer
Joined
Aug 19, 2010
Messages
27
Trophies
0
XP
218
Country
United States
In theory, yes, in practice, it still would require some work, because one has to re-model everything, or just import models from newer Mario games, but again, that requires some extra time to be worked, because the developers back then, made tricky workarounds for many things that were still unknown for it's time, after all, 3D Videogame development was on its early days. For example, many people doesn't know that Mario's body isn't textured at all, those are raw colored polygons and nothing else lol.



Well, I would need some time to know the 3DS internals and capabilities homebrew-wise, such as what control we have on the system so far. I believe that as today we have full control, so anything is possible inside that tiny but marvelous handheld. I will try to play around with the source code on PC first, and maybe, little maybe I will look if I can port that to the 3DS, if someone can put me in the right direction it would be much appreciated.

I would LOVE to see an upgraded Camera + Mario 64 looking like Mario Sunshine/Odyssey :)
 

Ecchi95

Well-Known Member
OP
Member
Joined
Jul 7, 2019
Messages
121
Trophies
0
Age
29
XP
891
Country
United States
>My point is you don't have to use the original models. You could make all new models if you're doing an enhanced port. (Original code, brand new assets.

Hard when a lot of the code is tied to the graphics
You can get rid of that code. You only really need the logic for Mario and the things he interacts with.
 

mountainflaw

Member
Newcomer
Joined
Jul 11, 2018
Messages
22
Trophies
0
Age
34
XP
107
Country
Australia
I never said it was impossible. However as someone who actually has worked on the project, I can tell you removing the n64 graphicsisms from the main code isn't fun. Also, there is much much MUCH more than just Mario's code you'd want, especially since it's all intertwined.
 

CrashOveride

Well-Known Member
Newcomer
Joined
May 29, 2017
Messages
50
Trophies
0
XP
127
Country
United States
>You can get rid of that code. You only really need the logic for Mario and the things he interacts with.

what? have you even looked at the code at all?
 
  • Like
Reactions: AlanJohn

Ecchi95

Well-Known Member
OP
Member
Joined
Jul 7, 2019
Messages
121
Trophies
0
Age
29
XP
891
Country
United States
>You can get rid of that code. You only really need the logic for Mario and the things he interacts with.

what? have you even looked at the code at all?
Yes, I have. I couldn't have made the file list for one of the src directories if I didn't have it.

The most important parts are the player code and the code for all the animate and inanimate objects they interact with. You can abstract out the N64-dependent stuff. You just reference it to get the gist of what it's trying to do.
 

CrashOveride

Well-Known Member
Newcomer
Joined
May 29, 2017
Messages
50
Trophies
0
XP
127
Country
United States
I didn't ask if you had the code, I asked have you bothered to read it at all.

Using a search function for .c and .asm is not an answer

I consider arguing with @mountainflaw, someone who actively participated in the decomp process, useless
 
Last edited by CrashOveride,

Ecchi95

Well-Known Member
OP
Member
Joined
Jul 7, 2019
Messages
121
Trophies
0
Age
29
XP
891
Country
United States
I didn't ask if you had the code, I asked have you bothered to read it at all.

Using a search function for .c and .asm is not an answer

I consider arguing with @mountainflaw, someone who actively participated in the decomp process, useless
YES, I HAVE. Look at the files in src/behaviors. Not too many N64 graphics things in them: (you can REFERENCE the graphics stuff in the other files to get the GIST of it instead of faithfully doing every little thing)

(what @mountainflaw is saying is irrelevant depending on how much accuracy you want to trade)


Code:
/**
 * Behavior for bhvEnemyLakitu.
 * Lakitu comes before it spawned spinies in processing order.
 * TODO: bhvCloud processing oredr
 */


/**
 * Hitbox for evil lakitu.
 */
static struct ObjectHitbox sEnemyLakituHitbox =
{
    /* interactType:      */ INTERACT_HIT_FROM_BELOW,
    /* downOffset:        */ 0,
    /* damageOrCoinValue: */ 2,
    /* health:            */ 0,
    /* numLootCoins:      */ 5,
    /* radius:            */ 50,
    /* height:            */ 50,
    /* hurtboxRadius:     */ 40,
    /* hurtboxHeight:     */ 50,
};


/**
 * Wait for mario to approach, then spawn the cloud and become visible.
 */
static void enemy_lakitu_act_uninitialized(void)
{
    if (o->oDistanceToMario < 2000.0f)
    {
        spawn_object_relative_with_scale(
            CLOUD_BP_LAKITU_CLOUD,
            0, 0, 0,
            2.0f,
            o,
            MODEL_MIST,
            bhvCloud);

        obj_unhide();
        o->oAction = ENEMY_LAKITU_ACT_MAIN;
    }
}

/**
 * Accelerate toward mario vertically.
 */
static void enemy_lakitu_update_vel_y(f32 offsetY)
{
    // In order to encourage oscillation, pass mario by a small margin before
    // accelerating the opposite direction
    f32 margin;
    if (o->oVelY < 0.0f)
    {
        margin = -3.0f;
    }
    else
    {
        margin = 3.0f;
    }

    if (o->oPosY < gMarioObject->oPosY + offsetY + margin)
    {
        obj_y_vel_approach(4.0f, 0.4f);
    }
    else
    {
        obj_y_vel_approach(-4.0f, 0.4f);
    }
}

/**
 * Control speed based on distance to mario, turn toward mario, and change move
 * angle toward mario.
 */
static void enemy_lakitu_update_speed_and_angle(void)
{
    f32 minSpeed;
    s16 turnSpeed;

    f32 distToMario = o->oDistanceToMario;
    if (distToMario > 500.0f)
    {
        distToMario = 500.0f;
    }

    // Move faster the farther away mario is and the faster mario is moving
    if ((minSpeed = 1.2f * gMarioStates[0].forwardVel) < 8.0f)
    {
        minSpeed = 8.0f;
    }
    o->oForwardVel = distToMario * 0.04f;
    clamp_f32(&o->oForwardVel, minSpeed, 40.0f);

    // Accelerate toward mario vertically
    enemy_lakitu_update_vel_y(300.0f);

    // Turn toward mario except right after throwing a spiny
    if (o->oEnemyLakituFaceForwardCountdown != 0)
    {
        o->oEnemyLakituFaceForwardCountdown -= 1;
    }
    else
    {
        obj_face_yaw_approach(o->oAngleToMario, 0x600);
    }

    // Change move angle toward mario faster when farther from mario
    turnSpeed = (s16)(distToMario * 2.0f);
    clamp_s16(&turnSpeed, 0xC8, 0xFA0);
    obj_rotate_yaw_toward(o->oAngleToMario, turnSpeed);
}

/**
 * When close enough to mario and facing roughly toward him, spawn a spiny and
 * hold it, then enter the hold spiny sub-action.
 */
static void enemy_lakitu_sub_act_no_spiny(void)
{
    func_8029ED38(1);

    if (o->oEnemyLakituSpinyCooldown != 0)
    {
        o->oEnemyLakituSpinyCooldown -= 1;
    }
    else if (o->oEnemyLakituNumSpinies < 3 &&
        o->oDistanceToMario < 800.0f &&
        abs_angle_diff(o->oAngleToMario, o->oFaceAngleYaw) < 0x4000)
    {
        struct Object *spiny = spawn_object(o, MODEL_SPINY_BALL, bhvSpiny);
        if (spiny != NULL)
        {
            o->prevObj = spiny;
            spiny->oAction = SPINY_ACT_HELD_BY_LAKITU;

            func_8029EE20(spiny, spiny_egg_seg5_anims_050157E4, 0);

            o->oEnemyLakituNumSpinies += 1;
            o->oSubAction = ENEMY_LAKITU_SUB_ACT_HOLD_SPINY;
            o->oEnemyLakituSpinyCooldown = 30;
        }
    }
}

/**
 * When close to mario and facing toward him or when mario gets far enough away,
 * enter the throw spiny sub-action.
 */
static void enemy_lakitu_sub_act_hold_spiny(void)
{
    func_802F927C(3);

    if (o->oEnemyLakituSpinyCooldown != 0)
    {
        o->oEnemyLakituSpinyCooldown -= 1;
    }
    // TODO: Check if anything interesting happens if we bypass this with speed
    else if (o->oDistanceToMario > o->oDrawingDistance - 100.0f ||
        (o->oDistanceToMario < 500.0f &&
            abs_angle_diff(o->oAngleToMario, o->oFaceAngleYaw) < 0x2000))
    {
        o->oSubAction = ENEMY_LAKITU_SUB_ACT_THROW_SPINY;
        o->oEnemyLakituFaceForwardCountdown = 20;
    }
}

/**
 * Throw the spiny, then enter the no spiny sub-action.
 */
static void enemy_lakitu_sub_act_throw_spiny(void)
{
    if (func_802F92EC(2, 2))
    {
        PlaySound2(SOUND_OBJECT_EVILLAKITUTHROW);
        o->prevObj = NULL;
    }

    if (func_8029F788())
    {
        o->oSubAction = ENEMY_LAKITU_SUB_ACT_NO_SPINY;
        o->oEnemyLakituSpinyCooldown = random_linear_offset(100, 100);
    }
}

/**
 * Main update function.
 */
static void enemy_lakitu_act_main(void)
{
    PlaySound(SOUND_CH6_UNKNOWN002);

    obj_update_floor_and_walls();

    enemy_lakitu_update_speed_and_angle();
    if (o->oMoveFlags & OBJ_MOVE_HIT_WALL)
    {
        o->oMoveAngleYaw = obj_reflect_move_angle_off_wall();
    }

    obj_update_blinking(&o->oEnemyLakituBlinkTimer, 20, 40, 4);

    switch (o->oSubAction)
    {
    case ENEMY_LAKITU_SUB_ACT_NO_SPINY:    enemy_lakitu_sub_act_no_spiny();    break;
    case ENEMY_LAKITU_SUB_ACT_HOLD_SPINY:  enemy_lakitu_sub_act_hold_spiny();  break;
    case ENEMY_LAKITU_SUB_ACT_THROW_SPINY: enemy_lakitu_sub_act_throw_spiny(); break;
    }

    obj_move_standard(78);

    // Die and drop held spiny when attacked by mario
    if (obj_check_attacks(&sEnemyLakituHitbox, o->oAction))
    {
        // The spiny uses this as a signal to get thrown
        o->prevObj = NULL;
    }
}

/**
 * Update function for bhvEnemyLakitu.
 */
void bhv_enemy_lakitu_update(void)
{
    //PARTIAL_UPDATE

    treat_far_home_as_mario(2000.0f);

    switch (o->oAction)
    {
    case ENEMY_LAKITU_ACT_UNINITIALIZED: enemy_lakitu_act_uninitialized(); break;
    case ENEMY_LAKITU_ACT_MAIN:          enemy_lakitu_act_main();          break;
    }
}
 
Last edited by Ecchi95,

SuckerPunch32

New Member
Newbie
Joined
Jul 11, 2019
Messages
3
Trophies
0
XP
56
Country
United States
YES, I HAVE. Look at the files in src/behaviors. Not too many N64 graphics things in them: (you can REFERENCE the graphics stuff in the other files to get the GIST of it instead of faithfully doing every little thing)

(what @mountainflaw is saying is irrelevant depending on how much accuracy you want to trade)

Code:
/**
 * Behavior for bhvEnemyLakitu.
 * Lakitu comes before it spawned spinies in processing order.
 * TODO: bhvCloud processing oredr
 */


/**
 * Hitbox for evil lakitu.
 */
static struct ObjectHitbox sEnemyLakituHitbox =
{
    /* interactType:      */ INTERACT_HIT_FROM_BELOW,
    /* downOffset:        */ 0,
    /* damageOrCoinValue: */ 2,
    /* health:            */ 0,
    /* numLootCoins:      */ 5,
    /* radius:            */ 50,
    /* height:            */ 50,
    /* hurtboxRadius:     */ 40,
    /* hurtboxHeight:     */ 50,
};


/**
 * Wait for mario to approach, then spawn the cloud and become visible.
 */
static void enemy_lakitu_act_uninitialized(void)
{
    if (o->oDistanceToMario < 2000.0f)
    {
        spawn_object_relative_with_scale(
            CLOUD_BP_LAKITU_CLOUD,
            0, 0, 0,
            2.0f,
            o,
            MODEL_MIST,
            bhvCloud);

        obj_unhide();
        o->oAction = ENEMY_LAKITU_ACT_MAIN;
    }
}

/**
 * Accelerate toward mario vertically.
 */
static void enemy_lakitu_update_vel_y(f32 offsetY)
{
    // In order to encourage oscillation, pass mario by a small margin before
    // accelerating the opposite direction
    f32 margin;
    if (o->oVelY < 0.0f)
    {
        margin = -3.0f;
    }
    else
    {
        margin = 3.0f;
    }

    if (o->oPosY < gMarioObject->oPosY + offsetY + margin)
    {
        obj_y_vel_approach(4.0f, 0.4f);
    }
    else
    {
        obj_y_vel_approach(-4.0f, 0.4f);
    }
}

/**
 * Control speed based on distance to mario, turn toward mario, and change move
 * angle toward mario.
 */
static void enemy_lakitu_update_speed_and_angle(void)
{
    f32 minSpeed;
    s16 turnSpeed;

    f32 distToMario = o->oDistanceToMario;
    if (distToMario > 500.0f)
    {
        distToMario = 500.0f;
    }

    // Move faster the farther away mario is and the faster mario is moving
    if ((minSpeed = 1.2f * gMarioStates[0].forwardVel) < 8.0f)
    {
        minSpeed = 8.0f;
    }
    o->oForwardVel = distToMario * 0.04f;
    clamp_f32(&o->oForwardVel, minSpeed, 40.0f);

    // Accelerate toward mario vertically
    enemy_lakitu_update_vel_y(300.0f);

    // Turn toward mario except right after throwing a spiny
    if (o->oEnemyLakituFaceForwardCountdown != 0)
    {
        o->oEnemyLakituFaceForwardCountdown -= 1;
    }
    else
    {
        obj_face_yaw_approach(o->oAngleToMario, 0x600);
    }

    // Change move angle toward mario faster when farther from mario
    turnSpeed = (s16)(distToMario * 2.0f);
    clamp_s16(&turnSpeed, 0xC8, 0xFA0);
    obj_rotate_yaw_toward(o->oAngleToMario, turnSpeed);
}

/**
 * When close enough to mario and facing roughly toward him, spawn a spiny and
 * hold it, then enter the hold spiny sub-action.
 */
static void enemy_lakitu_sub_act_no_spiny(void)
{
    func_8029ED38(1);

    if (o->oEnemyLakituSpinyCooldown != 0)
    {
        o->oEnemyLakituSpinyCooldown -= 1;
    }
    else if (o->oEnemyLakituNumSpinies < 3 &&
        o->oDistanceToMario < 800.0f &&
        abs_angle_diff(o->oAngleToMario, o->oFaceAngleYaw) < 0x4000)
    {
        struct Object *spiny = spawn_object(o, MODEL_SPINY_BALL, bhvSpiny);
        if (spiny != NULL)
        {
            o->prevObj = spiny;
            spiny->oAction = SPINY_ACT_HELD_BY_LAKITU;

            func_8029EE20(spiny, spiny_egg_seg5_anims_050157E4, 0);

            o->oEnemyLakituNumSpinies += 1;
            o->oSubAction = ENEMY_LAKITU_SUB_ACT_HOLD_SPINY;
            o->oEnemyLakituSpinyCooldown = 30;
        }
    }
}

/**
 * When close to mario and facing toward him or when mario gets far enough away,
 * enter the throw spiny sub-action.
 */
static void enemy_lakitu_sub_act_hold_spiny(void)
{
    func_802F927C(3);

    if (o->oEnemyLakituSpinyCooldown != 0)
    {
        o->oEnemyLakituSpinyCooldown -= 1;
    }
    // TODO: Check if anything interesting happens if we bypass this with speed
    else if (o->oDistanceToMario > o->oDrawingDistance - 100.0f ||
        (o->oDistanceToMario < 500.0f &&
            abs_angle_diff(o->oAngleToMario, o->oFaceAngleYaw) < 0x2000))
    {
        o->oSubAction = ENEMY_LAKITU_SUB_ACT_THROW_SPINY;
        o->oEnemyLakituFaceForwardCountdown = 20;
    }
}

/**
 * Throw the spiny, then enter the no spiny sub-action.
 */
static void enemy_lakitu_sub_act_throw_spiny(void)
{
    if (func_802F92EC(2, 2))
    {
        PlaySound2(SOUND_OBJECT_EVILLAKITUTHROW);
        o->prevObj = NULL;
    }

    if (func_8029F788())
    {
        o->oSubAction = ENEMY_LAKITU_SUB_ACT_NO_SPINY;
        o->oEnemyLakituSpinyCooldown = random_linear_offset(100, 100);
    }
}

/**
 * Main update function.
 */
static void enemy_lakitu_act_main(void)
{
    PlaySound(SOUND_CH6_UNKNOWN002);

    obj_update_floor_and_walls();

    enemy_lakitu_update_speed_and_angle();
    if (o->oMoveFlags & OBJ_MOVE_HIT_WALL)
    {
        o->oMoveAngleYaw = obj_reflect_move_angle_off_wall();
    }

    obj_update_blinking(&o->oEnemyLakituBlinkTimer, 20, 40, 4);

    switch (o->oSubAction)
    {
    case ENEMY_LAKITU_SUB_ACT_NO_SPINY:    enemy_lakitu_sub_act_no_spiny();    break;
    case ENEMY_LAKITU_SUB_ACT_HOLD_SPINY:  enemy_lakitu_sub_act_hold_spiny();  break;
    case ENEMY_LAKITU_SUB_ACT_THROW_SPINY: enemy_lakitu_sub_act_throw_spiny(); break;
    }

    obj_move_standard(78);

    // Die and drop held spiny when attacked by mario
    if (obj_check_attacks(&sEnemyLakituHitbox, o->oAction))
    {
        // The spiny uses this as a signal to get thrown
        o->prevObj = NULL;
    }
}

/**
 * Update function for bhvEnemyLakitu.
 */
void bhv_enemy_lakitu_update(void)
{
    //PARTIAL_UPDATE

    treat_far_home_as_mario(2000.0f);

    switch (o->oAction)
    {
    case ENEMY_LAKITU_ACT_UNINITIALIZED: enemy_lakitu_act_uninitialized(); break;
    case ENEMY_LAKITU_ACT_MAIN:          enemy_lakitu_act_main();          break;
    }
}

That has nothing to do with the game or Mario, it's just behaviour code for an object. The rest of the game is basically tied to the N64 hardware. (Graphics, Audio, Engine (partially), etc.)
 
Last edited by SuckerPunch32,
  • Like
Reactions: CrashOveride

CrashOveride

Well-Known Member
Newcomer
Joined
May 29, 2017
Messages
50
Trophies
0
XP
127
Country
United States
>(you can REFERENCE the graphics stuff in the other files to get the GIST of it instead of faithfully doing every little thing)
Then what is the point of making a source port if you can just do it from scratch
 

Ecchi95

Well-Known Member
OP
Member
Joined
Jul 7, 2019
Messages
121
Trophies
0
Age
29
XP
891
Country
United States
>(you can REFERENCE the graphics stuff in the other files to get the GIST of it instead of faithfully doing every little thing)
Then what is the point of making a source port if you can just do it from scratch
You have the precise code for the behaviors. You can do everything else yourself, just referencing the original code for the gist.

You think when they made Ocarina of Time 3D they reproduced EVERYTHING? No.
 

SuckerPunch32

New Member
Newbie
Joined
Jul 11, 2019
Messages
3
Trophies
0
XP
56
Country
United States
You have the precise code for the behaviors. You can do everything else yourself, just referencing the original code for the gist.

You think when they made Ocarina of Time 3D they reproduced EVERYTHING? No.

So what you're saying is basically just port over the logic? That has already been done, here:
 
Last edited by SuckerPunch32,
  • Like
Reactions: Ecchi95

mountainflaw

Member
Newcomer
Joined
Jul 11, 2018
Messages
22
Trophies
0
Age
34
XP
107
Country
Australia
I'm not sure who said it was impossible, all I was trying to say is that it's still not a walk in the park for a port.
The port bad_boot made took about a week to make, getting the graphics and sound systems to work would probably be a pain in the ass that would take a month or two.
 
Last edited by mountainflaw,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • Xdqwerty @ Xdqwerty:
    @K3Nv2, i have a physical copy of mgs4
  • Xdqwerty @ Xdqwerty:
    ok I tried it and 1) it doesnt boot wood menu automatically and 2) when trying to load a game through wood theres just a loading screen
  • K3Nv2 @ K3Nv2:
    It's low on wood
    +1
  • Xdqwerty @ Xdqwerty:
    lemme ask in forums
  • Xdqwerty @ Xdqwerty:
    yawn
  • BigOnYa @ BigOnYa:
    @Xdqwerty No you heard wrong, and don't believe till you experience yourself. Fallout 4 is one of my favorite games of all time. Yes it had issues early on, esp with older hardware like the xbox1, but it is awesome, esp now being 4k on Series S/X or PS5
    +2
  • Xdqwerty @ Xdqwerty:
    @BigOnYa, Then i think people were talking about fallout 76
  • Xdqwerty @ Xdqwerty:
    that one was buggy too
  • BigOnYa @ BigOnYa:
    Yea you right there, fallout 76 was a letdown, but it not that bad now, they have fixed slot of issues they had at launch. Biggest issue with Fallout 76 is its a pay to advance further type of game, which sucks
  • Xdqwerty @ Xdqwerty:
    @BigOnYa, I may probably download fallout 3 or new vegas on my ps3
  • Xdqwerty @ Xdqwerty:
    cuz I didnt like fallout 1 that much
  • BigOnYa @ BigOnYa:
    New Vegas is awesome, F3 was ok too.
  • Psionic Roshambo @ Psionic Roshambo:
    I played Fallout 4 on PC, I enjoyed it honestly. Not my favorite game on earth but at the same time I didn't hate it at all lol
  • BigOnYa @ BigOnYa:
    That's cool you got a ps3... Glad to hear. Game on!
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    Ironic this was posted today lol
  • BigOnYa @ BigOnYa:
    I think the tv series has boasted play of, I did see they said playing of it Is up, way more than norm
    +1
  • BigOnYa @ BigOnYa:
    I've been playing the next gen version on Series X all day, I love it. :wub:
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    Downloading some random stuff, damn almost 400GBs in like 4 hours lol
  • Psionic Roshambo @ Psionic Roshambo:
    Gonna be over 1TB this month.... damn lol
  • Xdqwerty @ Xdqwerty:
    good night
    +1
  • BigOnYa @ BigOnYa:
    At least you have some fast speeds. What a drag that used to be, I remb downloading 1 pic back in the day, and seeing line by line show
  • BigOnYa @ BigOnYa:
    Nighty night.
  • BigOnYa @ BigOnYa:
    Or worse, you downloading something, and someone calls your phone and interupts the download, good ole AOL. Of course that's before most you guys even were born yet.
    BigOnYa @ BigOnYa: Or worse, you downloading something, and someone calls your phone and interupts the download...