• Welcome to Smashboards, the world's largest Super Smash Brothers community! Over 250,000 Smash Bros. fans from around the world have come to discuss these great games in over 19 million posts!

    You are currently viewing our boards as a visitor. Click here to sign up right now and start on your path in the Smash community!

Writing Codes for Melee in C

Savestate

Smash Cadet
Joined
Apr 14, 2015
Messages
38
Location
Greensboro, NC
Hey SmashBoards!

edit: Some rewording as suggested by a friend!

As most of you know, writing any code for melee other than a simple memory replace normally involves coding in assembly, which can be incredibly tedious for more complex functions. I've been thinking of ways to open up another option for people who are more comfortable coding in C, or want to quickly make some less-efficient prototypes for hacks before committing to writing them in assembly.

Given you're running Windows, grab a copy of a gamecube-targeted toolchain from the great guys at devkitPro (automated installer). When installing, you'll want to check the PowerPC toolchain "devkitPPC". If you don't plan on using the other two (I didn't), feel free to uncheck them.

If you're running Linux/OSX, they provide an experimental perl script to put the compiler on your computer. If that doesn't end up working, you may need to build a cross compiler. There's various guides out there to help with that, but I wouldn't be opposed to providing guidance on the issue.

Once the toolchain is installed, you'll need to add the binaries' location to the System Environment Variable "Path". In the Start Menu search for "edit the system environment variables", click "Environment Variables..." button, scrolling down to "Path" in the bottom half of the window, choose "Edit" and add on "C:\devkitPro\devkitPPC\bin" to the end of the large string of text. Make sure there's a semicolon between it and the entry before it. e.g. "...path\directory\location;C:\devkitPro\devkitPPC\bin"

Now open up Command Prompt and type in "powerpc-eabi-gcc". If you see...
Code:
powerpc-eabi-gcc: fatal error: no input files
compilation terminated.
...that means you're ready to start programming! If not, make sure you set your Path correctly, and that the binaries are in the folder "C:\devkitPro\devkitPPC\bin" to begin with.

In the subject of programming, I believe it's best to teach with examples, so I'm going to step through the process of writing a code for Melee in C.
______________________________________________________

Writing a Program in C for Super Smash Bros. Melee
______________________________________________________
: : : : : Step 1. The Concept

First of all, you need to know what you're going to program, so for demo's sake, I'll do something that looks pretty in C, but isn't really all that useful.. Let's write a code that clears out the stale moves table if it's filled up with copies of the same move, and then play the "Menu Forward" sound to indicate that it's been done. Most, if not all, of the info required for this demo can be found on the SSBM v1.2 Datasheet (hosted by Dan Salvato).

: : : : : Step 2. Resources

Alright, so we know what we're gonna do, now let's gather everything we'll need to make it happen. Some functions we'll need are the "Count players in match" function, "Get character data pointer" function, and "Play menu sound: 'Forward'" function. We'll put references to these in the header of our C program as #defines so we can reference them in our code without making it look too confusing.

We'll also need the addresses of the "Stale Moves" table for each player. Now, the stale moves tables are in a fixed place in RAM, spaced equally. Knowing this, we can write down the location of the first one and access the rest by changing the offset by a multiple of the known distance.

Our header will look something like this.
Code:
// - Play Sound Effect
#define SSBM_FUNC_PLAYMENUFORWARD 0x80174338
// - Get Pointer to Character Data
#define SSBM_FUNC_CHARPOINTER 0x80034110
    // r3 = Player Number
// - Count players in match
#define SSBM_FUNC_COUNTPLAYERS 0x8016B558
    // returns r3, number of characters in match

// ==========================
// Staleness Tables
#define SSBM_STALETABLE_P1   0x8045313C
#define SSBM_STALETABLE_DIST 0xE90
#define SSBM_STALETABLE_SIZE 10
: : : : : Step 3. Additional Preparation

To make accessing the stale moves tables easier, I went ahead and defined some structs that match the format of the tables. This way, I can create new pointers to the structs in the RAM and use them just like how I would any other variable! Neat stuff!
Code:
typedef struct SSBM_staleness_slot {
    uint16_t move_id;           // The action state number
    uint16_t action_state_num;  // The number of action states
                                // since the beginning of the match
} SSBM_staleness_slot;

typedef struct SSBM_staleness_table {
    uint32_t write_next;        // The next slot to write to in the table
    SSBM_staleness_slot slots[SSBM_STALETABLE_SIZE]; // The 10 staleness slots
} SSBM_staleness_table;
: : : : : Step 4a. Let's Code! (creating pointers to functions in the game)

Ok, so we're ready to start coding! To begin, we'll start with a main function and create new function pointers to the previously defined functions in Melee's RAM.

Side note: Do not call your main function main! Call it _main, calling it main will make the assembler insert a call to
__eabi which breaks things.
Code:
int _main() {
    // built in functions setup
    void     * (*play_menu_forward)() = SSBM_FUNC_PLAYMENUFORWARD;
    uint32_t * (*pointer_to_character)(int) = SSBM_FUNC_CHARPOINTER;
    uint32_t * (*player_count)() = SSBM_FUNC_COUNTPLAYERS;

    // to-do ... !
}
In case you're wondering, uint32_t is a way of saying "32-bit unsigned integer". There's also other ones like uint8_t, uint16_t, etc You'll need to add "#include <stdint.h>" to the top of your C file to use 'em.

: : : : : Step 4b. Let's Code! (variable setup)

Now that we have our Melee functions declared, we should set up our Stale Moves tables. We're going to create an array of pointers to each stale-moves-table currently active in the game. First, we need to know how big our array should be! We can figure this out by calling the player_count() function. It returns an integer that indicates how many players are in the current match. Once we have that, we can set our array of pointers to be the size of the number of characters playing.

Once your array of pointers has been initialized, we need to populate it with the pointers to the stale moves tables for each of the currently active players. We'll also need to create an index variable to keep track of which slot we're putting the pointer into.

A neat thing about the pointer_to_character(int) function is that it will return a 0 if the player isn't playing this match. With this in mind, we can make a for loop that goes from zero to four and feeds the loop variable into the pointer_to_character(int) function. If it returns a zero, skip the iteration, if it returns a pointer to a character, we'll use the iteration we're on to determine the character number and multiply the stale table offset by it to get the offset of the stale table for the current character (current in regards to the loop variable). We then put this final calculated offset into the array of pointers to stale tables and increase the current index by one. Rinse and repeat all 4 times.
Code:
    // populate the array of stale table pointers 

    int i;
    int index = 0;
    for (i=0; i<4; i++) {
        if (pointer_to_character(i) != 0)
            stale_tables[index++] = SSBM_STALETABLE_P1 + (i*SSBM_STALETABLE_DIST);
    }
: : : : : Step 4c. Let's Code! (using our variables)


By this point, we know exactly where all the info we need to access is... we just need to use it now! Given our original plan, we'll need to make a loop that iterates through all the known stale moves tables in our array of pointers to them and check if all of the moves in the stale moves table are the same. If they are, we'll clear the table and play the menu forward sound.

That sounds like a lot to put in a for loop though ... so let's make functions that'll help split the job up!

Essentially, we are going to create functions that this following block of code can reference.
Code:
    for(i=0; i<num_players; i++) {
        // if all slots in a stale table are the same
        // move, then clear out the table and menu
        // forward noise.
        if (all_the_same_move(stale_tables[i])) {
            clear_table(stale_tables[i]);
            play_menu_forward();
        }
    }
So our two functions will have to follow the format of ...
Code:
int all_the_same_move(SSBM_staleness_table *table)
void clear_table(SSBM_staleness_table *table)
A moderately easy of implementing all_the_same_move is by saving the first move_id in the table to a local variable and looping through the array of staleness slots, comparing their move_id to the one saved in the beginning. We should also keep track of whether or not the entire slot list is zeros, because if it is, then technically the function would return true even though there's nothing in the list.
Code:
// returns whether or not a staleness table is filled all with the same move

// 0 = not all the same move (or filled completely with zeros)
// 1 = all the same move
int all_the_same_move(SSBM_staleness_table *table) {
    uint16_t action = table->slots[0].move_id;
    int i;
    int all_zeros = 1;
    for (i=0; i<SSBM_STALETABLE_SIZE; i++) {
        uint16_t move_in_slot = table->slots[i].move_id;
        if (action != move_in_slot)
            return 0;
        if (move_in_slot != 0)
            all_zeros = 0;
    }

    if (all_zeros == 1)
        return 0;

    return 1;
}

clear_table is going to be much easier to implement. We just need to loop through the staleness table slots and set them all to zero (both move_id and action_state_num)
Code:
// zeros out a staleness table's slots
void clear_table(SSBM_staleness_table *table) {
    int i;
    for (i=0; i<SSBM_STALETABLE_SIZE; i++) {
        table->slots[i].move_id = 0x0000;
        table->slots[i].action_state_num = 0x0000;
    }
}
: : : : : Step 5. Compiling your Code to Assembly

Our finished C program:
wow !
Code:
#include <stdint.h>

// - Play Sound Effect
#define SSBM_FUNC_PLAYMENUFORWARD 0x80174338
// - Get Pointer to Character Data
#define SSBM_FUNC_CHARPOINTER 0x80034110
    // r3 = Player Number
// - Count players in match
#define SSBM_FUNC_COUNTPLAYERS 0x8016B558
    // returns r3, number of characters in match

// ==========================
// Staleness Tables
#define SSBM_STALETABLE_P1   0x8045313C
#define SSBM_STALETABLE_DIST 0xE90
#define SSBM_STALETABLE_SIZE 10

typedef struct SSBM_staleness_slot {
    uint16_t move_id;           // The action state number
    uint16_t action_state_num;  // The number of action states
                                // since the beginning of the match
} SSBM_staleness_slot;

typedef struct SSBM_staleness_table {
    uint32_t write_next;        // The next slot to write to in the table
    SSBM_staleness_slot slots[SSBM_STALETABLE_SIZE]; // The 10 staleness slots
} SSBM_staleness_table;

// returns whether or not a staleness table is filled all with the same move
// 0 = not all the same move (or filled completely with zeros)
// 1 = all the same move
int all_the_same_move(SSBM_staleness_table *table) {
    uint16_t action = table->slots[0].move_id;
    int i;
    int all_zeros = 1;
    for (i=0; i<SSBM_STALETABLE_SIZE; i++) {
        uint16_t move_in_slot = table->slots[i].move_id;
        if (action != move_in_slot)
            return 0;
        if (move_in_slot != 0)
            all_zeros = 0;
    }

    if (all_zeros == 1)
        return 0;

    return 1;
}

// zeros out a staleness table's slots
void clear_table(SSBM_staleness_table *table) {
    int i;
    for (i=0; i<SSBM_STALETABLE_SIZE; i++) {
        table->slots[i].move_id = 0x0000;
        table->slots[i].action_state_num = 0x0000;
    }
}

int _main() {
    // built in functions setup
    void     * (*play_menu_forward)() = SSBM_FUNC_PLAYMENUFORWARD;
    uint32_t * (*pointer_to_character)(int) = SSBM_FUNC_CHARPOINTER;
    uint32_t * (*player_count)() = SSBM_FUNC_COUNTPLAYERS;

    int num_players = player_count();
    SSBM_staleness_table *stale_tables[num_players];

    // populate the array of stale table pointers
    int i;
    int index = 0;
    for (i=0; i<4; i++) {
        if (pointer_to_character(i) != 0)
            stale_tables[index++] = SSBM_STALETABLE_P1 + (i*SSBM_STALETABLE_DIST);
    }

    for(i=0; i<num_players; i++) {
        // if all slots in a stale table are the same
        // move, then clear out the table and play_sfx
        // trophy get noise.
        if (all_the_same_move(stale_tables[i])) {
            clear_table(stale_tables[i]);
            play_menu_forward();
        }
    }
}

Time to make some assembly! Go ahead and open up the command prompt and navigate to your code's directory. Run the command powerpc-eabi-gcc -S unstaler.c to generate an assembly file called unstaler.s. To prepare this assembly code for use with ASM <> WiiRD, we need to clean out a few lines of code and add a branch to the _main function.

Remove all the lines of code that begin with a period, except for the loop labels.
They're usually located at the beginning and ends of functions.
Code:
# Get rid of all the junk that looks like this!

    .file    "unstaler.c"
    .section    ".text"
    .align 2
    .globl all_the_same_move
    .type    all_the_same_move, @function
Once you finish that, add some code to the beginning of the assembly that backs up r3 to the stack, branches and link to _main, restores r3, and branches to the bottom of the assembly to exit.
Code:
begin:
   subi sp,sp,4
   stw r3,0(sp)
   bl _main

cleanup:
   lwz r3,0(sp)
   addi sp,sp,4
   b exit

all_the_same_move:
   stwu 1,-40(1)
   stw 31,36(1)
   mr 31,1
   stw 3,24(31)
   lwz 9,24(31)
   lhz 9,4(9)
   sth 9,16(31)
   li 9,1
   stw 9,12(31)
   li 9,0
   stw 9,8(31)
   b .L2
.L6:
   lwz 10,24(31)
   lwz 9,8(31)
   slwi 9,9,2
   add 9,10,9
   lhz 9,4(9)
   sth 9,18(31)
   lhz 9,16(31)
   rlwinm 10,9,0,0xffff
   lhz 9,18(31)
   rlwinm 9,9,0,0xffff
   cmpw 7,10,9
   beq 7,.L3
   li 9,0
   b .L4
.L3:
   lhz 9,18(31)
   rlwinm 9,9,0,0xffff
   cmpwi 7,9,0
   beq 7,.L5
   li 9,0
   stw 9,12(31)
.L5:
   lwz 9,8(31)
   addi 9,9,1
   stw 9,8(31)
.L2:
   lwz 9,8(31)
   cmpwi 7,9,9
   ble 7,.L6
   lwz 9,12(31)
   cmpwi 7,9,1
   bne 7,.L7
   li 9,0
   b .L4
.L7:
   li 9,1
.L4:
   mr 3,9
   addi 11,31,40
   lwz 31,-4(11)
   mr 1,11
   blr

clear_table:
   stwu 1,-40(1)
   stw 31,36(1)
   mr 31,1
   stw 3,24(31)
   li 9,0
   stw 9,8(31)
   b .L9
.L10:
   lwz 10,24(31)
   lwz 9,8(31)
   slwi 9,9,2
   add 9,10,9
   li 10,0
   sth 10,4(9)
   lwz 10,24(31)
   lwz 9,8(31)
   slwi 9,9,2
   add 9,10,9
   li 10,0
   sth 10,6(9)
   lwz 9,8(31)
   addi 9,9,1
   stw 9,8(31)
.L9:
   lwz 9,8(31)
   cmpwi 7,9,9
   ble 7,.L10
   addi 11,31,40
   lwz 31,-4(11)
   mr 1,11
   blr

_main:
   stwu 1,-80(1)
   mflr 0
   stw 0,84(1)
   stw 22,40(1)
   stw 23,44(1)
   stw 24,48(1)
   stw 25,52(1)
   stw 26,56(1)
   stw 27,60(1)
   stw 28,64(1)
   stw 29,68(1)
   stw 30,72(1)
   stw 31,76(1)
   mr 31,1
   mr 9,1
   mr 22,9
   lis 9,0x8017
   ori 9,9,17208
   stw 9,16(31)
   lis 9,0x8003
   ori 9,9,16656
   stw 9,20(31)
   lis 9,0x8016
   ori 9,9,46424
   stw 9,24(31)
   lwz 9,24(31)
   mtctr 9
   bctrl
   mr 9,3
   stw 9,28(31)
   lwz 9,28(31)
   addi 10,9,-1
   stw 10,32(31)
   mr 10,9
   mr 28,10
   li 27,0
   srwi 10,28,27
   slwi 23,27,5
   or 23,10,23
   slwi 24,28,5
   mr 10,9
   mr 30,10
   li 29,0
   srwi 10,30,27
   slwi 25,29,5
   or 25,10,25
   slwi 26,30,5
   slwi 9,9,2
   addi 9,9,3
   addi 9,9,15
   srwi 9,9,4
   slwi 9,9,4
   lwz 10,0(1)
   neg 9,9
   stwux 10,1,9
   addi 9,1,8
   addi 9,9,3
   srwi 9,9,2
   slwi 9,9,2
   stw 9,36(31)
   li 9,0
   stw 9,12(31)
   li 9,0
   stw 9,8(31)
   b .L12
.L14:
   lwz 9,20(31)
   lwz 3,8(31)
   mtctr 9
   bctrl
   mr 9,3
   cmpwi 7,9,0
   beq 7,.L13
   lwz 9,12(31)
   addi 10,9,1
   stw 10,12(31)
   lwz 10,8(31)
   mulli 10,10,3728
   addis 10,10,0x8045
   addi 10,10,12604
   lwz 8,36(31)
   slwi 9,9,2
   add 9,8,9
   stw 10,0(9)
.L13:
   lwz 9,8(31)
   addi 9,9,1
   stw 9,8(31)
.L12:
   lwz 9,8(31)
   cmpwi 7,9,3
   ble 7,.L14
   li 9,0
   stw 9,8(31)
   b .L15
.L17:
   lwz 10,36(31)
   lwz 9,8(31)
   slwi 9,9,2
   add 9,10,9
   lwz 9,0(9)
   mr 3,9
   bl all_the_same_move
   mr 9,3
   cmpwi 7,9,0
   beq 7,.L16
   lwz 10,36(31)
   lwz 9,8(31)
   slwi 9,9,2
   add 9,10,9
   lwz 9,0(9)
   mr 3,9
   bl clear_table
   lwz 9,16(31)
   mtctr 9
   bctrl
.L16:
   lwz 9,8(31)
   addi 9,9,1
   stw 9,8(31)
.L15:
   lwz 10,8(31)
   lwz 9,28(31)
   cmpw 7,10,9
   blt 7,.L17
   lwz 9,0(1)
   stw 9,0(22)
   mr 1,22
   mr 3,9
   addi 11,31,80
   lwz 0,4(11)
   mtlr 0
   lwz 22,-40(11)
   lwz 23,-36(11)
   lwz 24,-32(11)
   lwz 25,-28(11)
   lwz 26,-24(11)
   lwz 27,-20(11)
   lwz 28,-16(11)
   lwz 29,-12(11)
   lwz 30,-8(11)
   lwz 31,-4(11)
   mr 1,11
   blr

exit:
   opcode-to-replace
Lastly, replace opcode-to-replace with the opcode that's going to be overwritten. To determine that though, we gotta find a good place to inject the code into. After some digging around, I believe I found a function that deals with calculating how much damage a hitbox makes (it's executed once per new hitbox) so we'll just inject it into that function. The address in question is 0x8008923C and the opcode we're replacing is addi r31, r5, 0.

Run your assembly through ASM <> WiiRD to get your Gecko code!

Code:
C208923C 00000070
3821FFFC 90610000
48000149 80610000
38210004 48000364
9421FFD8 93E10024
7C3F0B78 907F0018
813F0018 A1290004
B13F0010 39200001
913F000C 39200000
913F0008 48000060
815F0018 813F0008
5529103A 7D2A4A14
A1290004 B13F0012
A13F0010 552A043E
A13F0012 5529043E
7F8A4800 419E000C
39200000 4800004C
A13F0012 5529043E
2F890000 419E000C
39200000 913F000C
813F0008 39290001
913F0008 813F0008
2F890009 409DFF9C
813F000C 2F890001
409E000C 39200000
48000008 39200001
7D234B78 397F0028
83EBFFFC 7D615B78
4E800020 9421FFD8
93E10024 7C3F0B78
907F0018 39200000
913F0008 48000040
815F0018 813F0008
5529103A 7D2A4A14
39400000 B1490004
815F0018 813F0008
5529103A 7D2A4A14
39400000 B1490006
813F0008 39290001
913F0008 813F0008
2F890009 409DFFBC
397F0028 83EBFFFC
7D615B78 4E800020
9421FFB0 7C0802A6
90010054 92C10028
92E1002C 93010030
93210034 93410038
9361003C 93810040
93A10044 93C10048
93E1004C 7C3F0B78
7C290B78 7D364B78
3D208017 61294338
913F0010 3D208003
61294110 913F0014
3D208016 6129B558
913F0018 813F0018
7D2903A6 4E800421
7C691B78 913F001C
813F001C 3949FFFF
915F0020 7D2A4B78
7D5C5378 3B600000
578A2EFE 57772834
7D57BB78 57982834
7D2A4B78 7D5E5378
3BA00000 57CA2EFE
57B92834 7D59CB78
57DA2834 5529103A
39290003 3929000F
5529E13E 55292036
81410000 7D2900D0
7D41496E 39210008
39290003 5529F0BE
5529103A 913F0024
39200000 913F000C
39200000 913F0008
48000058 813F0014
807F0008 7D2903A6
4E800421 7C691B78
2F890000 419E0030
813F000C 39490001
915F000C 815F0008
1D4A0E90 3D4A8045
394A313C 811F0024
5529103A 7D284A14
91490000 813F0008
39290001 913F0008
813F0008 2F890003
409DFFA4 39200000
913F0008 48000060
815F0024 813F0008
5529103A 7D2A4A14
81290000 7D234B78
4BFFFD41 7C691B78
2F890000 419E002C
815F0024 813F0008
5529103A 7D2A4A14
81290000 7D234B78
4BFFFDDD 813F0010
7D2903A6 4E800421
813F0008 39290001
913F0008 815F0008
813F001C 7F8A4800
419CFF98 81210000
91360000 7EC1B378
7D234B78 397F0050
800B0004 7C0803A6
82CBFFD8 82EBFFDC
830BFFE0 832BFFE4
834BFFE8 836BFFEC
838BFFF0 83ABFFF4
83CBFFF8 83EBFFFC
7D615B78 4E800020
3BE50000 00000000

________________________________________________________________________

Video

________________________________________________________________________
That's it! A crash course for programming in C for Melee. Feel free to ask any questions, I'll try my best to answer them.
 
Last edited:

Absolome

Smash Cadet
Joined
Jan 3, 2014
Messages
68
Location
Asheville, NC
HEY I found that stale moves table yesterday while procrastinating

I'm famous! Hi mom!

Seriously though has nobody else worked on writing code for melee in C (or any other language) and then compiling it into usable asm? I know it's probably less efficient but it seems like this would be so much faster and easier for modding the game
 

Savestate

Smash Cadet
Joined
Apr 14, 2015
Messages
38
Location
Greensboro, NC
HEY I found that stale moves table yesterday while procrastinating

I'm famous! Hi mom!

Seriously though has nobody else worked on writing code for melee in C (or any other language) and then compiling it into usable asm? I know it's probably less efficient but it seems like this would be so much faster and easier for modding the game
Thank you for procrastinating! Your notes on how it was structured made it really easy to reference as a struct, and I felt it'd be a good base for a demo.
As far as what I was able to look into, I didn't see anyone else trying to compile to ASM for Melee, so I think (?) this is a first? Dunno.
Hopefully this opens the door to more structured mods.
 

zankyou

Smash Lord
Joined
Sep 12, 2014
Messages
1,055
HEY I found that stale moves table yesterday while procrastinating

I'm famous! Hi mom!

Seriously though has nobody else worked on writing code for melee in C (or any other language) and then compiling it into usable asm? I know it's probably less efficient but it seems like this would be so much faster and easier for modding the game
There were a lot of limitations to this idea because there isnt THAT much free space in the dol so I use a lot of dirty tricks and borrowed registers when Im 1 word over or something. With Melee Code Manager out now something like this is far more appealing although I dont know if its capable of dealing with branching within your code.
Also does this follow the ABI for the wii. Achilles pointed out that in order to call another function the first 2 words of the stack are reserved so youd start pushing onto 0x8
 
Last edited:

Savestate

Smash Cadet
Joined
Apr 14, 2015
Messages
38
Location
Greensboro, NC
There were a lot of limitations to this idea because there isnt THAT much free space in the dol so I use a lot of dirty tricks and borrowed registers when Im 1 word over or something. With Melee Code Manager out now something like this is far more appealing although I dont know if its capable of dealing with branching within your code.
Also does this follow the ABI for the wii. Achilles pointed out that in order to call another function the first 2 words of the stack are reserved so youd start pushing onto 0x8
Looking at the ASM, while it's a bit cryptic, it seems that it also reserves the first two words. This must be a common thing in compiled code. This leads me to believe it's safe for use with the builtin Melee functions.
 
Last edited:

jam1garner

Smash Apprentice
Joined
Apr 24, 2015
Messages
103
Nice job. It would be very interesting if someone actually made C/C++ library for modding melee as I'm sure that would draw in quite a few more modders. And again, cool stuff.
 

Acryte

Smash Ace
Joined
Mar 30, 2005
Messages
986
That's true, it could increase the popularity of Melee coding a bit, provided it doesn't cause issues due to some type of inaccuracy.
 
Last edited:

Savestate

Smash Cadet
Joined
Apr 14, 2015
Messages
38
Location
Greensboro, NC
That's true, it could increase the popularity of Melee coding a bit, provided it doesn't cause issues due to some type of inaccuracy.
Coding in C shouldn't cause any inaccuracies unless your compiler is borked d;

Nice job. It would be very interesting if someone actually made C/C++ library for modding melee as I'm sure that would draw in quite a few more modders. And again, cool stuff.
I'm working on a header that has most of all the stuff in the 1.2 datasheet. I'll post it here when it's finished (probably sometime this weekend)
 
Last edited:

Acryte

Smash Ace
Joined
Mar 30, 2005
Messages
986
Coding in C shouldn't cause any inaccuracies unless your compiler is borked d;


I'm working on a header that has most of all the stuff in the 1.2 datasheet. I'll post it here when it's finished (probably sometime this weekend)
Sweet.
 

Savestate

Smash Cadet
Joined
Apr 14, 2015
Messages
38
Location
Greensboro, NC
Ah man, I completely forgot about that!
My computer is currently out of commission since I lost the charger for it a few days ago, so it might be a few more until I get this done.
If I haven't gotten it made by Saturday night, bug me again about it!
 
Last edited:

Savestate

Smash Cadet
Joined
Apr 14, 2015
Messages
38
Location
Greensboro, NC
Finished most of the relevant ID list values, and most of the global offsets. I'd say I'm about 50% done, and should be done by wednesday night if I don't slack off! (I thought I'd be done sooner, sorry ... u __ u) Bug me again if I don't post it by then!

current progress : http://pastebin.com/HZ7PwGGX

WEDNESDAY UPDATE: lol i got distracted (sorry)
it won't be too long from now though so just keep holdin' out. (I'm gonna try to put the Community Symbol Map in it as well)


4/15/2016: ugh, too many things and then i went on to other things
honestly, most of the stuff you can find on the 1.2 datasheet and copy/paste when you need it
sorry for abandoning the header file ...
 
Last edited:

Savestate

Smash Cadet
Joined
Apr 14, 2015
Messages
38
Location
Greensboro, NC
Sorry, I haven't been on SB in a while.

This could be used for an AI given you have the space in the DOL / gecko code area to put a compiled program. You'd need to overwrite the AI's controls with your own each frame produced from whatever AI logic you create.

The command line program is a cross compiler for the PowerPC in the Gamecube. It generates assembly code / machine code based off of the C code and then you can use wiird to generate a gecko code based off it.
 
Top Bottom