Views: 845,199,019
33 users online: BabaYegha, Batata Douce,  bebn legg, Bernardo, blocc, ChrillePan, codfish1002, Darolac, dmarek,  FPzero, h.carrell, HD_DankBaron, Infinity, Israelcv12cv,  JamesD28, LeaderAngelo, Lum4Ever,  MarioFanGamer, mariofreak4500, MMaxwell, Nirv, Ralshi02, Rykon-V73, Sariel,  Sayuri,  Sinc-X, SLBros., Sparkle-And-Syro, SubconYoshi, SuperMarisa1999, tommas2008, TSian7, Wyatt - Guests: 75 - Bots: 80 Users: 46,483 (2,727 active)
Latest: Juanx2007
Tip: Keep your graphics within a specific style. Don't mix cartoony sprites with detailed and realistic back/foregrounds!Not logged in.
Posts by Davideesk
Davideesk's Profile - Posts by Davideesk
Pages: « 1 2 3 4 5 »

Hello, I have a few questions about HUD textures and ASM.

I am new to assembly coding and hex editing (as in I started yesterday). Yesterday, I found this tutorial that was made by Tarek701. The tutorial was super simple to follow, I now mostly understand the 3 types of instructions, the 32 registers, and the different opcodes (though I did have to google for those).

In the comment section of this video by pidi64 on youtube, Tarek701 explained how to add an image, like the beta-key, to the HUD. I followed it and it worked:

I want to use this code so I can add back the J,Q,V,X,Z characters back into the game. I now have the image textures setup in the ROM's memory.

0x1204A48 == "Key" icon
0x1204C48 == "J" icon
0x1204E48 == "Q" icon
0x1205048 == "V" icon
0x1205248 == "X" icon
0x1205448 == "Z" icon

Each letter texture does in fact work:

But I have a few questions to ask because I'm confused on certain things.

1.) In Tarek's youtube comment he says that "D6 is segmented and is: 0x80072580 (RAM offset)."

Where did he get "0x80072580" from? How does D6 give him that address?

2.) Why does "/" equal (02 00 D6 00)? Is there a list of numbers to characters that I can look at? How do I look at this Hex table and tell what bytes go with what letter? How do I find J, Q, V, X, and Z in this table?

3.) Is there a way to make the loading code only run once instead of being part of a loop? (I currently have it in the same code as the text display). I tried to use Tarek's code, but there seems to be an error with the line "LB T4, 0xB201". That 0xB201 needs parenthesis with a register after it, right?

Here is my asm code so far (I am using CajeASM v6.01 as my assembler)

.org 0x861C0 
ADDIU SP, SP, 0xFFE8 // Allocates space on stack (24-bits), allocating works by subtracting 24
SW RA, 0x14(SP)// Store's the return address to the stack.

// Loads the Key Texture
LUI V0, 0x8007       // Upper Half of RAM Address (where our texture is copied to)
ORI A0, V0, 0x2580 // Lower Half of RAM address, A0 := 0x80072580.
LUI V0, 0x0120       // Upper half of ROM offset begin(where our texture is stored)
ORI A1, V0, 0x4A48 // Upper half of ROM offset end (where the texture ends)
JAL 0x00278504 // DMACopy function.
ORI A2, V0, 0x4E48 // Lower half of ROM offset end.

// Displays the ascii text.
LUI A2, 0x802C // Loads Top half of the text address
ORI A0, R0, 0x0F // sets X-Pos argument by ORing 70 with 0
ORI A2, A2, 0xB23C // Adds Bottom half of the text address
JAL 0x802d62d8 // Calls ("jumps") to PrintXY function
ORI A1, R0, 0x0F // sets Y-Pos argument by ORing 70 with 0

LW RA, 0x14(SP) // Loads the RA from the stack.
JR RA // Jumps back to the return address
ADDIU SP, SP, 0x18 // Adds back the "Allocated" space from the stack (Executed before JR)

.org 0x8623C //RAM offset = 0x802CB23C
.asciiz "/JQVXZ"

// Ascii Text Reference:
//(+ = Coin image)
//(- = Star image)
//(* = x image)
//(, = Mario image)

Originally posted by Kazeshin
to understand why "/" the equivalent of 0xD6 is get the ascii value of "/" and let it run through the routine in here:

I found that "/" was 2F in Hex, and going through the routine gave me V0 = 0x37

// Starting input (A0) is "/" (which is 2F in Hex)
// I'm leaving out Nops to keep this short.

/* I am assuming that the reason for the shift left then 
the shift back right is to zero out the first 24 bits of A0.*/
802D6858: SLL A0, A0, 0x18
802D685C: SRA A0, A0, 0x18

802D6860: SLTI AT, A0, 0x0041 // (2F < 41)? true (AT = 1)
802D6864: BNEZ AT, 0x802D6890 // (AT != 0)? true

802D6890: SLTI AT, A0, 0x0061 // (2F < 61)? true (AT = 1)
802D6894: BNEZ AT, 0x802D68C0 // (AT != 0)? true

802D68C0: SLTI AT, A0, 0x0030 // (2F < 30)? true (AT = 1)
802D68C4: BNEZ AT, 0x802D68F0 // (AT != 0)? true

802D68F0: ADDIU AT, R0, 0x0020 // AT = 20 ("space")
802D68F4: BNE A0, AT, 0x802D6904 // (2F != 20)? true

802D6904: ADDIU AT, R0, 0x0021 // AT = 21 ("!")
802D6908: BNE A0, AT, 0x802D6918 // (2F != 21)? true

(This continues for 23("#"), 3F("?"), 26("#"), 25("%"), 2A("*"), 2B("+"), 2C(","), 2D("-"), and 2E(".") until...)

802D69CC: ADDIU AT, R0, 0x002F // AT = 2F ("/")
802D69D0: BNE A0, AT, 0x802D69E0 // (2F != 2F)? false
802D69D8: JR RA
802D69DC: ADDIU V0, R0, 0x0037 // V0 = 0x37

"V0 gets multiplied by 4 and added to the start pointer. V0*4+start pointer is a pointer to the segmented start pointer. A0 gets ignored after this."

So 0x37 * 4 = DC. DC + 80A856 = 80A932. So this gives me the address to write (02 00 D6 00) to in the hex editor?

I'm still a little confused to where 0xD6 comes from though, and I'm going to bet that it's painfully obvious too.

So I've been looking at the source code of danielx's Super Mario 64 level viewer. He has a section of code that conveniently documents most of the commands that the level scripts use. This helps me a lot as a newbie, because now I can look at the level scripts in TT64's level script dump and sorta know what each line does.

Here are the different commands:
Command 0010 - Loads data into a bank, then jumps to an offset (Start of the script)
Command 0204 - End of the script
Command 0608 - Jump to an offset
Command 0704 - Return from the offset jump
Command 1108 - Calls Function from RAM code segment (Got this and 1208 from VL-Tone's notes)
Command 1208 - Calls Function from RAM code segment (This is slightly different from 1108, but I don't know what is different about it.)
Command 170C - Copy Data from ROM to RAM.
Command 1A0C - Decompress Texture Data from ROM to RAM.
Command 1B04 - Start Loading to RAM.
Command 1D04 - Stop Loading to RAM.
Command 1F08 - Start loading level polygon data with geo layout. (Ends with command 2004)
Command 2004 - End loading level data (Started from 1F08)
Command 2108 - Loads an object's polygon data
Command 2208 - Loads an object's polygon data with geo layout data.
Command 2418 - Places an object into the level.
Command 250C - Loads the Mario object.
Command 2608 - Connect an Entry/Exit.
Command 2708 - Connect an Entry/Exit. (Castle Paintings)
Command 2E08 - Load terrain collision data.
Command 3104 - Define terrain type behavior.
Command 3608 - Assign music to the area.
Command 3908 - Inserts multiple objects from a level data segment.

Even looking through some of VL-Tones notes (SM64MainLevelScripts.txt & FlatWorldBattleFieldHexData.txt),
I can't find anything for these 5 commands: 0404, 1C04, 1E04, 2B0C, and 2F08.

I noticed that they appear at the end of level scripts:

So I have 3 questions.
Does anyone know what those 5 commands do?
(to the hacking experts) Is the command information above correct?
Are there any more notes about level scripts that I can look at?

Originally posted by Kazeshin
all known information on level scripts are gathered here:

unlike how i decoded behavior scripts, i didnt do an intense nemu asm decoding session for all these things and it was mostly gathered from other peoples notes. so i can't guarantee everything to be right, but everything i've ever done with these notes worked perfectly well.

the info you posted seems correct, but kinda incomplete

Thank you kaze, that page is very informative. I just wanted to make sure that everything I know so far is mostly correct. It sucks when I think I know something, but it actually turns out to be completely wrong. :p

Does anyone know how to read the collision data format that is loaded by the 0x2E command? I can't seem to find any documentation on it.

For example in the Castle Grounds Level the command is:

00454BF0 / 0E000610: 2E 08 00 00 07 00 F3 A0

This tells me that the data is located at 0xFD6BA7 (In a fresh 24MB extended rom). I also know that the collision data goes on for 8452 bytes. This is because the 0x43 objects (aka: Special 3D Objects) are loaded after the collision data according to VL-Tone's notes.

Originally posted by
| Object format for commands loaded using 0x2E |

0x2E points to the collision data, which is followed by what I call "0x43 objects" which are similar to
0x42 objects loaded with the 0x39 command except that they can have a variable length.

More details about the collision data format and 0x43 objects will be included in the next version of this doc.


And the first 0x43 object, which is the Castle Tower, is located at 0xFD8CAB [00 65 00 00 0E 33 F0 AC 00 00]. 0xFD8CAB - 0xFD6BA7 = 0x2104 (8452 in decimal).

Here are all of the bytes from 0xFD6BA7 to 0xFD8CAA:

So does anyone here know how to read that format? I've tried to guess on how it works, but nothing I do seems to work right.

Thank you Kazeshin.

Also, do you know the preset list location for 0x43 objects is? I need it to find out whether an 0x43 object is 8, 10, or 12 bytes long.

Originally posted by Kazeshin
0x43 object? i thought there were only 0x3c commands. i only know of 0x39 inserting many objects. my notes say that it somehow related to EC7E0, but ive never really looked at it.

"0x43 Objects" and "0x42 Objects" are the short names that VL-tone gave to Special and Macro Objects. Though I should probably just stick with "Macro" and "Special" to avoid confusion. #tb{:p}

If anyone is wondering what those objects exactly are. Macro & Special Objects are just like the 3D objects from the 0x24 command, but the process of loading them is different.

Macro 3D Objects are loaded from the 0x39 command. Every object is exactly 10 bytes long. If anyone is interested, here is some info from VL-Tone's notes:

Originally posted by
| Object format for objects loaded using 0x39 (called 0x42 objects in TT64)|

Each object loaded with this command is dec 10 bytes long.
[01] [1F] [01 04] [02 DF] [07 80] [00 00]

[1,2]: First 7 bits = Horizontal rotation, last 9 bits are the model/behavior preset number.
Value 1E or 00 as type will end the object list and complete the 0x39 command.
[3,4] [5,6] [7,8]: X Y and Z position in level as 16-bit signed integers
[9,10]: Behavior parameters that will override the ones from the presets.

The preset table used by these commands is found at EC7E0 in the ROM.

There are 366 of them, and the first one in the table is defined as preset 01F.

Here's the format for the table:

1F= [13 00 09 1C] [00 74] [00 00]

[1,2,3,4]: RAM segment number and offset for behavior code to be attached to this object
[5,6]: Model ID number as defined by 0x21 and 0x22 commands
[7,8]: Parameters to be fed into the behavior code, usage varies depending on which behavior

Special 3D Objects are loaded from the 0x2E command. These objects are called from the sub command [00 43 NN NN], where 0xNNNN is the amount of special objects to be loaded. I don't really know all that much about Special Objects since I can't find much documentation on it, but here is what I know so far:

Special Objects can vary in byte length. They can either be 8 bytes long, 10 bytes long, or 12 bytes long depending on the object.

Using the Castle Grounds Level as an example, there are 30 special objects.

0xFD8CA7: [00 43 00 1E] // 0x001E = 30 in decimal

The Bubbly tree is an example of an Object with 8 bytes.

0xFD8CB5: [00 79 FA CB 02 C7 07 59]

[00 79] - Special Preset
[FA CB] - X Coordinate (16 bit signed)
[02 C7] - Y Coordinate (16 bit signed)
[07 59] - Z Coordinate (16 bit signed)

The Castle Tower Object is 10 Bytes in length, and it is mostly the same except that it includes Y-Rotation.

0xFD8CAB: [00 65 00 00 0E 33 F0 AC 00 00]
[00 65] - Special Preset
[00 00] - X Coordinate (16 bit signed)
[0E 33] - Y Coordinate (16 bit signed)
[F0 AC] - Z Coordinate (16 bit signed)
[00 00] - Y Rotation

The Metal Door that leads to the basement of the castle has 12 bytes. These kinds of objects have extra parameters.

0xFD8D85: [00 85 0C DC FE 01 F4 8D 00 A0 00 02]
[00 85] - Special Preset
[0C DC] - X Coordinate (16 bit signed)
[FE 01] - Y Coordinate (16 bit signed)
[F4 8D] - Z Coordinate (16 bit signed)
[00 A0] - Y Rotation
[00] - Extra Parameter 1 (Key#) // Overrides the value if not zero
[02] - Extra Parameter 2 (Warp ID) // Overrides the value if not zero

The length of the Special Object is based off of the Special Preset. The TT64 documentation says that the preset list is similar to the one that goes with the Macro objects, but it's in a different location in the rom.

Originally posted by TT64 ReadMe documentation
•Length: Indicates the length of this particular command. Dependent on the "Special Preset" value. Some commands are 8 bytes long, some 10 or 12 bytes.
•Special Preset: Similar to the Macro Preset parameter of 0x42 commands, but it uses a different preset list in the ROM, with values ranging from 0 to 255. You'll find that the pop-up menu often provide only a few choices, since it's limited to values used by commands of the same size.
•B. Param 1 & 2 (orange): These are not always present in 0x43 commands. Similar to the Behavior parameters in 0x24 commands, the difference here is that the orange parameters will override those defined by this particular Macro Preset value, if they're not equal to zero.
•Y rot: Just like the 0x42 command, but Y rotation is not present for some object commands.

So I was wondering if anyone here knew where that list is located. I may just ask VL-Tone directly if I can, or Skelux since he has the source code for TT64.

Edit: Looks like I found it, it starts at 0xED350 and ends at 0xED5E0. It's literally right after the Macro preset list used by the 0x39 command. lol.

I still don't know what determines the length. But I do know that the length is consistent between levels. So presets 0x65 to 0x78 will always be 10 bytes. I think that the length is determined by the behavior of the preset. Normal doors are 10 bytes long, while the doors that warp you to another area are 12 bytes long. That is just my guess though.

Here is a link to some notes on the preset list. It might not be too useful for people making custom levels, but I'll leave it here anyways.

I have some addresses that you can add.

Some of these images are in lA-16 format (Luminance 8 bits, Alpha 8 bits). So I put that information in brackets []. These images must be imported/exported as .PNG images because they contain transparency.

Star Transition Image (16x64) [Format: lA-16]: 81540E
The Image used when you are warping into a special area (Like the castle secret slide). It is half of a star (it is mirrored in-game).

Circle Transition Image (16x64) [Format: lA-16]: 815C0E
The Image used when you are warping into a normal area (Like going from outside to the inside the castle). It is half of a circle (it is mirrored in-game).

Mario Transition Image (32x64) [Format: lA-16]: 81640E
The Image used when you successfully collect a star.

Death Transition Image (16x64) [Format: lA-16]: 81740E
This is the image that appears when Mario dies. It is half of bowser's face (it is mirrored in-game).

I can confirm this with an upside-down bowser image:

Jolly Roger Bay water (32x32): 81840E

Another type of water? (32x32): 818C0E
This could be the water used in Dire Dire Docks.

Mist (32x32) [Format: lA-16]: 81940E

This thread is all about the Skyboxes that are in SM64. A Skybox is the background image in a level. Some levels have unique skys, while others levels share the same one. I will keep this first post up to date with all of the information & resources regarding skyboxes.


There are 10 skyboxes in the original Super Mario 64, and they are located at the following addresses:

Ocean (256x256): 0xB35715
Icy Mountains (256x256): 0xB5D855
Sky (256x160): 0xB85995
Fiery Sky (256x192): 0xBA22D5
Underwater City (256x256): 0xBC2C15
Clouds (256x256): 0xBEAD55
Desert (256x256): 0xC12E95
Dark Woods (256x160): 0xC3AFD5
Dark World (256x256): 0xC57915
Purple Sky (256x256): 0xC7FA55

(I came up with the names based off how the images look, they are not official in any way)

But hold on a second... If you try to open these with a program like N64Rip then you will be greeted by a jumbled mess:

This is because the skyboxes are actually made up of 32x32 squares.

These 32x32 squares make up an entire skybox. A 256x256 skybox is made up of 64 of these little squares. The reason why N64Rip can't properly render the entire image is because each square is independent, and so it tries to combine them in the wrong way. Which is why I created my own skybox importer.

Skybox Importer (v1.11):

This is a small side project I made today. It allows the user to view and replace skyboxes. I purposely made the design to be like N64Rip, so if anyone uses that program they already kinda know how it works.

Browse Button - The first thing you need to do is load up your rom, so press this button and select it in the file explorer.

Address Field - Enter in the hexadecimal address of the skybox here.

List Button - This button will bring up a list of the 10 skyboxes I mentioned before, pressing the OK button will setup that image in the editor.

Import PNG Button - This is used to import a PNG image to replace the skybox at the address.

NOTE: The imported texture must not be bigger than 256x256.
NOTE #2: Make backups of your ROM file before using this tool. Because once you import a texture, it is saved to the ROM.
NOTE #3: You can import skyboxes anywhere in the ROM file, but keep in mind that a 256x256 skybox takes up 0x20000 bytes of memory (128 kilobytes).

Export PNG Button - This button will take that preview image and make it into a .png image file.

Preview Button - Updates the preview image (For when you change the width/height)

Save Button - Saves the ROM with all the current changes you made. When the text is red, then it means that you should press the button.

Shift Image Left ("◄◄") - Adjusts the order bytes so that the image gets shifted to the left by 1 column.

Shift Image Right ("►►") - Adjusts the order bytes so that the image gets shifted to the right by 1 column.

Shift Image Up ("▲▲") - Adjusts the order bytes so that the image gets shifted up by 1 row.

Shift Image Down ("▼▼") - Adjusts the order bytes so that the image gets shifted down by 1 row.

NOTE: When you shift the order bytes, you need to press the "Save" button.

Show Grid ("#") - Toggles a grid so that you can easily see each 32x32 image.

This program requires at-least Java 7 to run, but I would recommend that you download the latest version of java here:

You can download the executable jar file here (Version 1.11):

Here is a link to the java source code if you are interested (Version 1.11):

Recent Changes (v1.11, The queueRAM update):
* Colors should be more accurate now
* Fixed a small issue with the convertTo5551 function.
* Exporting the image shouldn't make the image smaller

Recent Changes (v1.1):
* Added 6 new buttons
* You should be able to use any image now and not have it look weird.
* You can click any of the 32x32 images to change the order bytes for that chunk:


Even though I know where the textures are located in the rom, I don't know how they are loaded in-game.
So if anyone knows how they work, or if anyone knows any tricks with skyboxes, then leave a reply here and I will update this post with the appropriate information.

Originally posted by Kazeshin
0x20140 bytes are loaded to segment 0x0a and the box is placed with geo layout command 19 00 00 0A 80 27 63 D4, "0A" seems different sometimes, but no clue wtf its supposed to do.

last 0x140 bytes of segment 0x0A are pointers to each texture. (to order the BG image in some way?)

at 802D0048 a function related to drawing the background image gets called.


Originally posted by Kazeshin
do you have any ideas which images work without looking weird and which won't? i had exactly the same error when i tried stuff with a tool to exchange the "thank you" - cake picture. (also my custom backgrounds look kinda fucky because of that sometimes)

I have no idea honestly.

I did a test replacing the 'sky' image.

But it came out like this:

It looks like some of the images overlap each other. Even though they are supposed to be 32x32 sections, the images seem to have a larger width than height in-game.
Do you think it has something to do with the last 0x140 bytes of segment 0x0A you mentioned?

Originally posted by Kazeshin
i dont think it's related to those last few bytes.
also, when looking at it closer, it's 64 pointers to textures, but 80 pointers at the end of the segment, meaning that some of these pointers exist twice. i wonder if that affects specific tiles of the image?

the end cake picture was actually in a display list, but had similar issues, so i can't really imagine that to be the solution.

Well the sky data definitely has a lot of repeats (Because it's a smaller image).

0A 00 00 00
0A 00 08 00
0A 00 10 00
0A 00 18 00
0A 00 20 00
0A 00 28 00
0A 00 30 00
0A 00 38 00
0A 00 00 00
0A 00 08 00

I do agree with you that this is just probably the order in which they are displayed. I'll look into the geo command and edit this post if I find anything.
Well I looked at some of them and I can't really tell what that 4th byte means. All I can tell by looking at this is that areas that have a skybox have "80 27 63 D4" at the end, so it's probably the size (or position) of the skybox. The game locks up if I change these values, so that is probably not it. (I can change it to "00 00 00 00", but that just states that there is no Skybox in the level).

I tried changing the castle ground's 4th byte from 0 to other numbers. Numbers 02-05, 07, and 09 seems to change nothing, while numbers 01, 06, 08, 0A, 0B made the textures mess up. 0C & 0D gave me flashing messed up textures (You have to see it for yourself). However I noticed something when I changed the 4th byte to 0x0F.

I see a texture up there! So maybe that 4th byte is an offset of some kind? (Well 0D gave me textures that changed, so that is probably not it.)

Maybe it's related to a skybox ID?
*I noticed that Lethal Lava Land and Bowser Course 2 both have 01 as their 4th byte.
*Cool Cool Mountain & Snowman's land have their 4th byte as 04.
*BBB, Whomp's Fortress, Tall Tall Mountain, and Castle grounds all share the same skybox and their 4th bytes are 00.
*Rainbow Ride, Rainbow clouds, and Wing Cap all share the same 4th byte and have the same skybox as well.

Here are some addresses from different levels:

003837E0 / 0E000F20 [ 19 00 00 06 80 27 63 D4 ] // Big Boo's Haunt
003961DC / 0E00054C [ 19 00 00 04 80 27 63 D4 ] // Cool Cool Mountain
003FBFF8 / 0E000668 [ 19 00 00 05 80 27 63 D4 ] // Shifting Sand Land
003FC17C / 0E0007EC [ 19 00 00 01 00 00 00 00 ] // Shifting Sand Land (Inside Pyramid)
003FC23C / 0E0008AC [ 19 00 00 01 00 00 00 00 ] // Shifting Sand Land (Boss room)
00405F08 / 0E0004A8 [ 19 00 00 00 80 27 63 D4 ] // Bob-Omb's Battlefield
0040EC08 / 0E0003C8 [ 19 00 00 04 80 27 63 D4 ] // Snowman's Land
0041A608 / 0E000678 [ 19 00 00 02 80 27 63 D4 ] // Wet Dry World (Starting Area)
0041A6D4 / 0E000744 [ 19 00 00 01 00 00 00 00 ] // Wet Dry World (Town Area)
00424558 / 0E000A38 [ 19 00 00 08 80 27 63 D4 ] // Jolly Roger Bay
0042463C / 0E000B1C [ 19 00 00 01 00 00 00 00 ] // Jolly Roger Bay (Inside ship)
0044AB30 / 0E0009F0 [ 19 00 00 03 80 27 63 D4 ] // Rainbow Ride
00454D3C / 0E00075C [ 19 00 00 00 80 27 63 D4 ] // Castle Grounds
0045C598 / 0E000638 [ 19 00 00 07 80 27 63 D4 ] // Bowser 1 Course
0046B000 / 0E0007C0 [ 19 00 00 01 80 27 63 D4 ] // Bowser 2 Course
00478438 / 0E000738 [ 19 00 00 09 80 27 63 D4 ] // Bowser 3 Course
0048D7D0 / 0E000E20 [ 19 00 00 01 80 27 63 D4 ] // Lethal Lava Land
0048D890 / 0E000EE0 [ 19 00 00 01 00 00 00 00 ] // Lethal Lava Land (Inside Volcano)
0049E668 / 0E000C18 [ 19 00 00 03 80 27 63 D4 ] // Whomp's Fortress
004B8030 / 0E000120 [ 19 00 00 01 00 00 00 00 ] // Secret Slide
004C28A8 / 0E0001A8 [ 19 00 00 03 80 27 63 D4 ] // Wing Cap
004CDB40 / 0E000210 [ 19 00 00 03 80 27 63 D4 ] // Rainbow Clouds
004EBC80 / 0E000A90 [ 19 00 00 00 80 27 63 D4 ] // Tall Tall Mountain (Outside)
004EBD6C / 0E000B7C [ 19 00 00 01 00 00 00 00 ] // Tall Tall Mountain (Slide part 1)
004EBDFC / 0E000C0C [ 19 00 00 01 00 00 00 00 ] // Tall Tall Mountain (Slide part 2)
004EBE94 / 0E000CA4 [ 19 00 00 01 00 00 00 00 ] // Tall Tall Mountain (Slide part 3)

Originally posted by Mariohacker14

It's related to the texture borders, they need to be the same with the next texture. I will edit this reply to explain it better later.

I think I understand what you mean. Basically, you have to treat two touching borders as a single line in-game.

That is an annoying design flaw.

Originally posted by Kazeshin
Originally posted by Mariohacker14
elated to the texture borders, they need to be the same with the next texture. I will edit this reply to explain it better later.

you missunderstood me. i am aware that a texture has to be repeating to look somewhat decent. but most textures will have cutoffs within the original picture, which is my issue here.

I think he means that you have to make the touching borders of each 32x32 chunk match up.

Like the east-border line of pixels of one image should match the west-border line of pixels of the next image in that row. And the bottom row of pixels of the top image should match the top row of the bottom image.

Originally posted by Mariohacker14
I wonder if it's possible to make this a button (and a reverse one aswell, to make bgs to look like the original pictures) in Davideesk's tool. It would be the perfect tool for skybox edition in sm64. We could even ask skelux to implement this on a future version of the importer, just an idea.

I added the functionality as part of the import(.png) button in version 1.01. Basically if you import an image that consists of 31x31 chunks, it will use Kaze's function to upscale it. (Skyboxes use different heights, so I took that into account).

if (img.getWidth()%31 == 0 && img.getHeight()%31 == 0) img = UpscaleImg(img,width,height);

    /* Special thanks to Kaze for making this function. Link: */
    BufferedImage UpscaleImg(BufferedImage orig, int width, int height){
        BufferedImage converted = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        int rows = width/32;
        int cols = height/32;
        for (int y = 0; y < cols; y ++) {
            for (int x = 0; x < rows; x++) {
                for (int inY = 0; inY < 32; inY++) {
                    for (int inX = 0; inX < 32; inX++) {
                        converted.setRGB(inX+32*x, inY+32*y, orig.getRGB((inX+31*x)%orig.getWidth(), (inY+31*y)%orig.getHeight()));
        return converted;

I think a skybox image importer would be great for skelux's importer. I found an image of a sky-swapper tool in which I guess was supposed to be in TT64 v0.6.
I'm not sure if this was actually made by VL-Tone or not, but having it look like this would be pretty cool.



Thank you for that information. I'm making updates to the importer to make it a better editor. Like actually being able to edit the order in which the chunk images are placed in, and emulating that 0.5 pixel cutoff.

Though I noticed something interesting with the last 0x140 order bytes. I wondered why they had to use 80 images instead of the regular 64. I think I have an answer.

Skyboxes in every level use 80 images total (10 columns by 8 rows), no matter the original size of the image. The first 8 columns are normal, while the last two are repeats of the first two columns. This is for a clever trick that the developers came up with.

I edited the order of the repeated images to a single image each like so:

And it came with this result:
(I wish we could embed youtube links)

The skybox image moves based off of the camera's angle. The camera can just fit a little over 2 images wide (as seen in the video), so those extra two columns allow the skybox image to jump from one side to the other without breaking any in-game immersion.

PS: I was mistaken about the size of Wet-Dry-World's Image. It is actually (256x256) and not (256x224).

Little update since it's been a few days since the last post on this thread. I have the next version of the importer pretty much done.

Right now I just need some time to test and make sure that there are no major bugs with it. In the next version you should be able to use any .png and have it work fine. I am going to spend some time tomorrow to make sure that is the case with some random texture images I find off of google. :P
If it works correctly, then expect the update that night.

Originally posted by Mariocrash
That's odd... I have installed the file, but it seems the tool isn't there.

Try out the new version, it should load quicker now. If your still having problems let me know. (Make sure that you have the latest version of java)

Version 1.11 is out. The update fixes the issues that queueRAM brought up in the post before. Hopefully there shouldn't be any more major bugs with the tool.

Recent Changes (v1.11, The queueRAM update):
* Colors should be more accurate now.
* Fixed a small issue with the convertTo5551 function. (It used to make the image darker)
* Exporting the image shouldn't make the image smaller.

Jar Download:

I am doing a little experiment where I'm trying to replace the star model's display list from segment 0x03 with a copy from a custom made segment 0x1A (which is normally unused). I am testing this so I can easily change the star model later on. This was made in a fresh rom extended with VL-Tone's Extender. The copied version of the display list is exactly the same as the original.

The segment is loaded near the start of the 0x15 segment, so it can be used in every level.


(Beginning of the 0x15 segment) 002ABCA0 / 15000000 [ 17 0C 00 04 00 82 3B 64 00 85 8E DC ] -- load segment 0x04 002ABCAC / 1500000C [ 17 0C 00 03 00 AB 24 0C 00 AE 57 14 ] -- load segment 0x03 002ABCB8 / 15000018 [ 17 0C 00 17 00 12 79 B0 00 12 A7 E0 ] -- load segment 0x17 002ABCC4 / 15000024 [ 17 0C 00 1A 01 20 00 00 01 20 00 DF ] -- load segment 0x1A (my custom segment) 002ABCD0 / 15000030 [ 06 08 00 00 1A 00 00 00 ] -- Jump 01200000 / 1A000000 [ 17 0C 00 16 00 21 8D A0 00 21 9E 00 ] -- load segment 0x16 0120000C / 1A00000C [ 17 0C 00 13 00 21 9E 00 00 21 F4 C0 ] -- load segment 0x13 01200018 / 1A000018 [ 06 08 00 00 15 00 00 3C ] -- Jump back (I can't use the 0x07 command in this instance) 002ABCDC / 1500003C [ 1D 04 00 00 ] -- End of 0x17 commands ...

The code above is fully functional, however I am having a problem with the star's polygon script.


(Inside 'Star' (0x219C40) poly script) Changed this: 00ADDCDC / 0302B8D0 [ 06 00 00 00 03 02 B7 B0 ] -- Original to this: 00ADDCDC / 0302B8D0 [ 06 00 00 00 1A 00 00 20 ] -- Load display list from segment 0x1A, offset 0x20. (Doesn't work though)

When I change the code, the game messes up when it tries to render a star. In Project 64 1.6 the emulator freezes, while Project 64 2.1 lags a lot (<1 FPS). The display list should be exactly the same, but in another segment. I haven't messed with poly-scripts before, so am I missing something? Or should I approach this in a different way?

Here is the full segment hex code:


(0x1A segment) 01200000 / 1A000000 [ 17 0C 00 16 00 21 8D A0 00 21 9E 00 ] 0120000C / 1A00000C [ 17 0C 00 13 00 21 9E 00 00 21 F4 C0 ] 01200018 / 1A000018 [ 06 08 00 00 15 00 00 3C ] -- Jump back 01200020 / 1A000020 [ 03 86 00 10 03 02 A6 E0 ] -- Start of the Display List (Poly Script) 01200028 / 1A000028 [ 03 88 00 10 03 02 A6 D8 ] 01200030 / 1A000030 [ 04 B0 00 C0 03 02 B6 F0 ] 01200038 / 1A000038 [ BF 00 00 00 00 00 0A 14 ] 01200040 / 1A000040 [ BF 00 00 00 00 00 1E 0A ] 01200048 / 1A000048 [ BF 00 00 00 00 14 0A 28 ] 01200050 / 1A000050 [ BF 00 00 00 00 0A 1E 28 ] 01200058 / 1A000058 [ BF 00 00 00 00 32 1E 00 ] 01200060 / 1A000060 [ BF 00 00 00 00 28 1E 32 ] 01200068 / 1A000068 [ BF 00 00 00 00 3C 46 28 ] 01200070 / 1A000070 [ BF 00 00 00 00 46 14 28 ] 01200078 / 1A000078 [ BF 00 00 00 00 50 3C 28 ] 01200080 / 1A000080 [ BF 00 00 00 00 5A 28 64 ] 01200088 / 1A000088 [ BF 00 00 00 00 5A 6E 28 ] 01200090 / 1A000090 [ BF 00 00 00 00 28 32 64 ] 01200098 / 1A000098 [ BF 00 00 00 00 6E 50 28 ] 012000A0 / 1A0000A0 [ BF 00 00 00 00 00 14 46 ] 012000A8 / 1A0000A8 [ BF 00 00 00 00 00 46 3C ] 012000B0 / 1A0000B0 [ BF 00 00 00 00 00 3C 50 ] 012000B8 / 1A0000B8 [ BF 00 00 00 00 00 50 6E ] 012000C0 / 1A0000C0 [ BF 00 00 00 00 00 6E 5A ] 012000C8 / 1A0000C8 [ BF 00 00 00 00 64 32 00 ] 012000D0 / 1A0000D0 [ BF 00 00 00 00 64 00 5A ] 012000D8 / 1A0000D8 [ B8 00 00 00 00 00 00 00 ] -- End of the Display List

Originally posted by Kazeshin
You can only use the first 0x0F ramsegments for the display lists.
there is some sort of displaylist in segment 0x01 that SEEMS to define where in RAM the first 0x0F banks start. I tried to modify it with a simple code already, but had no real success. i lost the code so i cant tell where the function was again.

Well I guess that I have to change my approach a bit then.

What I could probably do is move the 0x03 segment bytes from 0xAB240C-0xAE5714(0x33308 bytes) to 0x1200000-0x1233308. That will allow me to modify the display lists. It will also allow me to use the 0x33308 bytes at 0xAB240C for my 0x1A segment to make custom Level/Geo Layout/Behavior scripts. Would that cause any issues in a test rom that doesn't use imported levels? (I know that SM64 The Green Stars uses 0x1200000-0x1202000 for one of its imported levels.)

Also, how did you approach this when you made your More objects patch?
Pages: « 1 2 3 4 5 »
Davideesk's Profile - Posts by Davideesk

The purpose of this site is not to distribute copyrighted material, but to honor one of our favourite games.

Copyright © 2005 - 2020 - SMW Central
Legal Information - Privacy Policy - Link To Us


Follow Us On

  • YouTube
  • Twitch
  • Twitter


  • Super Mario Bros. X Community
  • Mario Fan Games Galaxy