Mario Kart 64 Hacking General Discussion « 1 ... 11 12 13 14 15 ... 17 »
Users browsing this thread: 2 Guest(s)

Impressive. Thanks for all yours jobs !

Notes on run-time objects

There are two arrays of objects that I've started to decode. I'm naming them "Simple Objects" and "Complex Objects" for the lack of better terms. These names mostly reflect the size of data maintained for each. I have a more thorough listing of these notes and decompiled routines in this .txt file which I've checked into a fork of shygoo's mk64project repo.

​Course_Objects.txt

Edit: Bonus gif to show modifying Mario Raceway object rotation function (8029AB60)
[Image: PyhkA5n.gif]

Simple Objects
The simple object array is stored at 8015F9B8-80162578 (0x64 number of objects, each 0x70 bytes long). Objects such as the following are stored there:
  • ​shells
  • ​bananas
  • ​item boxes
  • ​trees, cacti, shrubs
  • ​piranha plants
  • ​falling rocks
  • ​spinning signs
  • ​train, railroad crossing

The structure of each simple object contains the following. There is clear variation in data stored at offset 0x24, so I indicate those as "union". However, offset 0x08 is used as float in some cases, so the entire structure may be a union for each type. If you want to help, I could use some help decoding these values and better determining which types use them.
Code:

typedef struct {
  i16 type;     // 00: used in switch at 802A3568
  i16 flags;    // 02: non-zero if used, 0x800 = gone (tree hit by star)
  i16 i16_04;   // 04: 1 = visible, -1 = not visible, used as timer in KD RR crossing
  i16 i16_06;   // 06: TODO some sort of state: 3 = touched by kart?
  i16 i16_08;   // 08: TODO, also float in proc_8029817C(), proc_802A10F0(), proc_802B0E98()
  i16 i16_0A;   // 0A: TODO
  float f32_0C; // 0C: float in fake item box
  i16 rotX;     // 10: rotation about X axis (e.g., rotating item boxes)
  i16 rotY;     // 12: rotation about Y (vertical) axis (e.g., Mario Raceway spinning signs)
  i16 rotZ;     // 14: rotation about Z axis (e.g., rotating item boxes)
  // 16-17
  float poxX;   // 18: X position
  float posY;   // 1C: Y position
  float posZ;   // 20: Z position
  union {
     struct item_box {
        float f32_24; // 24: TODO
        float f32_28; // 28: TODO fake item box
     };
     struct piranha {
        i16 i16_24;   // 24: TODO: state in piranha plant?
        i16 i16_26;   // 26: TODO: state in piranha plant?
        i16 i16_28;   // 28: TODO: state in piranha plant?
        i16 i16_2A;   // 2A: TODO
     };
     struct triple_shell {
        float f32_24; // 24: TODO
        float f32_28; // 28: TODO
        float f32_2C; // 2C: TODO
     };
     struct rocks {
        float f32_24; // 24
        float f32_28; // 28
        float f32_2C; // 2C
        // 30,34,38?
        float f32_3C; // 3C
        float f32_40; // 40
        float f32_44; // 44
        float f32_48; // 48
        float f32_4C; // 4C
        float f32_50; // 50
        float f32_54; // 54
        float f32_58; // 58
        float f32_5C; // 5C
        float f32_60; // 60
        float f32_64; // 64
        // 68,6C?
     };
  }
  // ?-6F
} SimpleObject;


The halfword at offset 0x00 designates the type of object and is handled in function UpdateSimpleObjects/802A3548 which loops through all objects in the simple object array each cycles with a large switch statement. I have decoded all of the types handled here:
TypeHandlerDescription
0x0280297D04trees in Mario Raceway (27x)
0x0380297D04trees in Yoshi Valley (13x)
0x0480297D04trees in Royal Raceway (24x)
0x058029D188Choco Mountain (x3) falling rocks?
0x06802B2034single banana
0x07802B32C4single green shell
0x08802B4218single red shell
0x0980297BFCYoshi's Valley egg
0x0A802981ECpiranha plant
0x0C802A1600item box
0x0D802A10F0fake item box
0x0E802B0A28bunch of bananas
0x0F8029817Csomething in Kalimari Desert 2x(1x) engine?
0x10802981CCsomething in Kalimari Desert 2x(1x) caboose?
0x11802981DCsomething in Kalimari Desert 2x(5x) train cars?
0x1380297D04trees in Moo Moo Farm (21x)
0x15802B0E98triple green shell?
0x16802B0E98triple red shell
0x178029AB60Mario Raceway spinning signs
0x1980297D04trees in Koopa Troopa Beach (12x)
0x1A80297D04trees in Luigi Raceway (20x)
0x1B80297D04TODO: couldn't find it used
0x1C80297D04trees by castle in Royal Raceway? (8x)
0x1D80297D04trees in Frappe Snowland (30x)
0x1E80297D04cacti in Kalimari Desert (44x of 30, 31, 32)
0x1F80297D04cacti in Kalimari Desert
0x2080297D04cacti in Kalimari Desert
0x2180297D04shrubs in Bowser's Castle (27x)
0x238029AAC8Wario Stadium (3x) spinning sign
0x268029816Cpaddle wheel on boat in DK's
0x278029AAD8something in Kalimari Desert (x4) railroad crossing?
0x2A802B4218single blue shell
0x2B802A156Citem box under balloon in Luigi Raceway
0x2D80297D5Ckiwano fruit in DKJP

Complex Objects
The complex object array is stored at 80165C18-80183D57 (0x226 objects, each 0xE0 bytes long). Objects such as the following are stored there:
  • ​hot air balloon
  • ​shell fire trails
  • ​thwomps
  • ​TODO: many more

The structure of each complex object contains the following and haven't seen any variation in the data types between elements yet, so it probably did not contain a union. Many of these elements are TODOs.
Code:

typedef struct {
  float f32_00; // size (scale) read from *0x800EEB14 (0x3E99999A = 0.3)
  float f32_04; // current X position?, from proc_8008BF18
  float f32_08; // current Y position?, from proc_8008BF18
  float f32_0C; // current Z position?, from proc_8008BF18
  float f32_10; // base X position?
  float f32_14; // base Y position?
  float f32_18; // base Z position?
  float f32_1C; // start of structure passed through A1 to proc_80042A20
  float f32_20; //
  float f32_24; //
  float f32_28; // delta X position used in proc_80050E34 (04 = 10 + 28)
  float f32_2C; // delta Y position used in proc_80050E34 (08 = 14 + 2C)
  float f32_30; // delta Z position used in proc_80050E34 (0C = 18 + 30)
  float f32_34;
  float f32_38; // proc_80054E10
  float f32_3C; // proc_80054E10, proc_80074924
  float f32_40; // proc_80054E10
  float f32_44; // proc_80054E10, proc_8004A6EC, proc_80055CCC, proc_800568A0
  i32 i32_48; // proc_80073E18
  i32 i32_4C; // init to -1 in proc_8006EE7C, used in proc_8007375C
  u32 u32_50; // proc_8007278C
  u32 u32_54;
  u32 u32_58;
  u32 u32_5C;
  i32 i32_60; // init to -0x2128 in proc_8006EE7C
  i32 i32_64; // init to  -0x128 in proc_8006EE7C
  i32 i32_68; // init to -0x2128 in proc_8006EE7C
  i32 i32_6C; // init to  -0x128 in proc_8006EE7C
  u32 u32_70; // proc_80055164
  u32 u32_74; // proc_800518F8, proc_800519D4, proc_80055164
  // 78
  // 7C
  // 80
  i16 i16_84; // proc_80053D74, proc_80054AFC, proc_80074924
  i16 i16_86; // proc_80053D74, proc_80054AFC, proc_80074924
  i16 i16_88; // proc_80053D74, proc_80054AFC, proc_80074924
  i16 i16_8A; // proc_80053D74, proc_80074924
  i16 i16_8C; // proc_80053D74, proc_80074924
  i16 i16_8E; // proc_80053D74, proc_80074924
  i16 i16_90; // proc_80053D74, proc_80074924
  i16 i16_92; // proc_800528EC, proc_80074924
  u16 u16_94; // proc_80085878, proc_80088364, proc_8008B284, proc_8008B620, proc_8008B6A4
  i16 i16_96; // proc_80088364, proc_8008B284, proc_8008B620, proc_8008B6A4
  u16 u16_98; // proc_8007AC9C, proc_8008B478, proc_8008B620, proc_8008B6A4
  // 9A
  i16 i16_9C; // casts f32_04 to u16 in proc_8008BFC0, read in proc_80051ABC, proc_80051C60
  i16 i16_9E; // casts f32_08 to u16 in proc_8008BFC0, read in proc_80051ABC, proc_80051C60
  i16 i16_A0; // opacity? starts at 0xFF and decays to 0x00
  i16 i16_A2; // proc_80054324, proc_80055164
  i16 i16_A4;
  i16 i16_A6; // proc_80074E28, proc_80074EE8, proc_80075CA8
  // i16? A8
  i16 i16_AA; // proc_8007401C
  i16 i16_AC; // proc_800738A8, proc_80073A10
  i16 i16_AE; // proc_8008BFFC, proc_80074D94
  i16 i16_B0; // proc_8007FB48, proc_8007FB48, proc_80087060
  u16 u16_B2; // start of structure passed through A1 to proc_800484BC
  u16 u16_B4;
  u16 u16_B6;
  u16 u16_B8; // start of structure passed through A1 to proc_80042E00
  u16 u16_BA;
  u16 u16_BC;
  u16 u16_BE; // start of structure passed through A1 to proc_80042E00
  u16 u16_C0; // proc_80055CCC, proc_80070250
  u16 u16_C2; // proc_80055CCC, proc_8005A14C
  // C4
  // C8
  u8  u08_CA; // is used flag?
  u8  u08_CB; // proc_8007278C, proc_80072B48
  i8  i08_CC; // proc_80072C00
  i8  i08_CD; // proc_8007401C
  i8  i08_CE; // proc_8007401C
  u8  u08_CF;
  i8  i08_D0; // proc_800738A8, proc_80073A10
  i8  i08_D1; // proc_8007CC00, proc_8007FB48
  i8  i08_D2; // proc_800557B4, proc_800747F0
  i8  i08_D3; // proc_80073404, proc_8007466C, proc_800747F0
  i8  i08_D4; // proc_80072C00
  u8  u08_D5; // proc_800750D8, proc_80075698
  u8  u08_D6; // proc_80073600, proc_80073654
  u8  u08_D7; // proc_800724F8
  u8  u08_D8; // proc_800557B4, proc_800723A4
  u8  u08_D9; // proc_800518F8, proc_800519D4
  u8  u08_DA; // proc_800518F8, proc_800519D4
  u8  u08_DB; // proc_80073FAC
  u8  u08_DC; // proc_8007381C
  u8  u08_DD; // proc_8008275C, proc_800850B0
  u8  u08_DE; // proc_8008BFFC
  u8  i08_DF; // proc_80053870
} CourseComplexObj;


Unlike the simple objects that are passed around by pointer, the complex objects are passed by index and each subroutine indexes into the global complex course objects. For example, routines at 8008B7D4, 8008B80C, 8008B8BC initialize different sections of the structure to provided values as follows:
Code:

#define COURSE_OBJ_COUNT 550 // 0x226

CourseComplexObj course_objs[COURSE_OBJ_COUNT]; // stored at 0x80165C18

void proc_8008B7D4(int idx, float a1, float a2, float a3)
{
  course_objs[idx].f32_10 = a1;
  course_objs[idx].f32_14 = a2;
  course_objs[idx].f32_18 = a3;
}

void proc_8008B80C(int idx, float a1, float a2, float a3)
{
  course_objs[idx].f32_28 = a1;
  course_objs[idx].f32_2C = a2;
  course_objs[idx].f32_30 = a3;
}

void proc_8008B8BC(int idx, u16 a1, u16 a2, u16 a3)
{
  course_objs[idx].u16_B2 = a1;
  course_objs[idx].u16_B4 = a2;
  course_objs[idx].u16_B6 = a3;
}
(This post was last modified: 17-08-2016, 04:27 AM by queueRAM. Edit Reason: kiwano )

Hello guys,

I was pretty amazed to see that some people continue to work on one of my favourite game : Mario Kart 64. "Bravo" as we say in France.

With the knowledge you have now, do you think it's possible to get music when playing 4 players VS ?

Thank you and keep up the good work !

(26-08-2016, 08:40 AM)Troll Wrote: Hello guys,

I was pretty amazed to see that some people continue to work on one of my favourite game : Mario Kart 64. "Bravo" as we say in France.

With the knowledge you have now, do you think it's possible to get music when playing 4 players VS ?

Thank you and keep up the good work !


​This hack includes an option to enable music in 3p/4p.

Woaw ! We've been looking for this... forever.

Thank you so much ! Other additions are pretty cool too.

(26-08-2016, 10:54 AM)abitalive Wrote: This hack includes an option to enable music in 3p/4p.


How use this hack ? Undecided
Thanks

(26-08-2016, 11:32 PM)zouzzz Wrote:
(26-08-2016, 10:54 AM)abitalive Wrote:
​This hack includes an option to enable music in 3p/4p.


How use this hack ? Undecided
Thanks


I've added build instructions to the bottom of the readme.

Thanks but "No usable files found.."

[Image: 227284Sanstitre.png]
(This post was last modified: 27-08-2016, 10:32 AM by zouzzz.)

(27-08-2016, 10:32 AM)zouzzz Wrote: Thanks but "No usable files found.."


It looks like you didn't download the repo properly, try this link.

Thanks, i tested with Mario Kart 64 (U) [!].z64 , CRC = 434389c1
Not working.

[Image: 814536Sanstitre.png]

Mario Kart 64 Hacking General Discussion « 1 ... 11 12 13 14 15 ... 17 »
Users browsing this thread: 2 Guest(s)