-
Notifications
You must be signed in to change notification settings - Fork 3
Notes
I just finished documenting the remaining unknown values, largely thanks to the decompilation project.
All I need to do now is add detailed information about some specific stuff, then refresh the EEPROM editor. Adding my old notes here:
SM64 Misc Flags - 8 bits * 3 bytes (0x09 - 0x0B)
--------------------------
0x09 0x0A 0x0B
--------------------------
00000000 00000000 00000001 = File in use
00000000 00000000 00000010 = Wing cap activated
00000000 00000000 00000100 = Metal cap activated
00000000 00000000 00001000 = Vanish cap activated
00000000 00000000 00010000 = Have key (basement)
00000000 00000000 00100000 = Have key (2nd floor)
00000000 00000000 01000000 = Key door unlocked (basement)
00000000 00000000 10000000 = Key door unlocked (2nd floor)
00000000 00000001 00000000 = 'Dire Dire Docks' portal moved backwards
00000000 00000010 00000000 = Castle moat drained
00000000 00000100 00000000 = Door unlock animation seen - 1 star, Princess's Secret Slide
00000000 00001000 00000000 = Door unlock animation seen - 2 star, Whomp's Fortress
00000000 00010000 00000000 = Door unlock animation seen - 3 star, Cool, Cool Mountain
00000000 00100000 00000000 = Door unlock animation seen - 3 star, Jolly Roger Bay
00000000 01000000 00000000 = Door unlock animation seen - 8 star, Bowser in the Dark World (Boss)
00000000 10000000 00000000 = Door unlock animation seen - 30 star, Bowser in the Fire Sea (Boss)
00000001 00000000 00000000 = Mario's cap is lost - Level ID dependent (Coordinates)
00000010 00000000 00000000 = Mario's cap is lost - Shifting Sand Land
00000100 00000000 00000000 = Mario's cap is lost - Tall, Tall Mountain
00001000 00000000 00000000 = Mario's cap is lost - Snowman's Land
00010000 00000000 00000000 = 50-star door unlocked
00100000 00000000 00000000
01000000 00000000 00000000
10000000 00000000 00000000
"COURSE_NONE", // LEVEL_UNKNOWN_1
"COURSE_NONE", // LEVEL_UNKNOWN_2
"COURSE_NONE", // LEVEL_UNKNOWN_3
"COURSE_BBH", // LEVEL_BBH / Big Boo's Haunt
"COURSE_CCM", // LEVEL_CCM / Cool Cool Mountain
"COURSE_NONE", // LEVEL_CASTLE / Castle lobby
"COURSE_HMC", // LEVEL_HMC / Hazy Maze Cave
"COURSE_SSL", // LEVEL_SSL / Shifting Sand Land
"COURSE_BOB", // LEVEL_BOB / Bob Omb Battlefield
"COURSE_SL", // LEVEL_SL / Snowman's Land
"COURSE_WDW", // LEVEL_WDW / Wet Dry World
"COURSE_JRB", // LEVEL_JRB / Jolly Rodger's Bay
"COURSE_THI", // LEVEL_THI / Tiny Huge Island
"COURSE_TTC", // LEVEL_TTC / Tick Tock Clock
"COURSE_RR", // LEVEL_RR / Rainbow Ride
"COURSE_NONE", // LEVEL_CASTLE_GROUNDS / Castle grounds (outside)
"COURSE_BITDW", // LEVEL_BITDW / Bowser in the Dark World
"COURSE_VCUTM", // LEVEL_VCUTM / Vanish Cap under the Moat
"COURSE_BITFS", // LEVEL_BITFS / Bowser in the Fire Sea
"COURSE_SA", // LEVEL_SA / Secret Aquarium
"COURSE_BITS", // LEVEL_BITS / Bowser in the Sky
"COURSE_LLL", // LEVEL_LLL / Lethal Lava Land
"COURSE_DDD", // LEVEL_DDD / Dire Dire Docks
"COURSE_WF", // LEVEL_WF / Whomp's Fortress
"COURSE_CAKE_END", // LEVEL_ENDING / (Ending Cutscene)
"COURSE_NONE", // LEVEL_CASTLE_COURTYARD / Castle courtyard (BBH entrance)
"COURSE_PSS", // LEVEL_PSS / Princess's Secret Slide
"COURSE_COTMC", // LEVEL_COTMC / Cavern of the Metal Cap
"COURSE_TOTWC", // LEVEL_TOTWC / Tower of the Wing Cap
"COURSE_BITDW", // LEVEL_BOWSER_1 / Bowser in the Dark World (Boss)
"COURSE_WMOTR", // LEVEL_WMOTR / Winged Mario over the Rainbow
"COURSE_NONE", // LEVEL_UNKNOWN_32
"COURSE_BITFS", // LEVEL_BOWSER_2 / Bowser in the Fire Sea (Boss)
"COURSE_BITS", // LEVEL_BOWSER_3 / Bowser in the Sky (Final Boss)
"COURSE_NONE", // LEVEL_UNKNOWN_35
"COURSE_TTM", // LEVEL_TTM / Tall Tall Mountain
"COURSE_NONE", // LEVEL_UNKNOWN_37
"COURSE_NONE" // LEVEL_UNKNOWN_38
A baseline observation of what normally happens when you lose and/or find a cap.
What happens when: Losing your cap in Tall, Tall Mountain Star 1 chosen. The monkey initially runs to you, but if you pick him up, he will take your hat. That fucker. If you collect a star and save, Bit 2 is set at address 0x09, indicating that the monkey has the cap. The coordinate chunk is never written to or changed, by either losing your cap or getting it back. What happens when: Losing your cap in Shifting Sand Land Must choose Star 2 or higher. If you stand around near the bird, he will swoop down and swipe your cap. Collecting a star and saving will set Bit 1 at address 0x09, indicating that the bird has stolen Mario's cap. The coordinate chunk is untouched when saving a lost cap here. However, upon retrieving your cap, the coordinate chunk is replaced with the location where Mario found his cap, and the 0x08 level ID. What happens when: Losing your cap in Snowman's Land Choose Star 1. You lose your cap by being blown off the large snowman mountain. When you lose your cap, and collect a star, Bit 0 is set at address 0x09. Coordinate chunk is set to Snowman's Land, writing both the 0x0A level ID and the coordinates of the cap's position. When you save after collecting your cap, the coordinates are updated to where you picked up the cap.
Address: 0x09 Bit flag: Bit 0, or 0000 0001 Short description: Cap lost – Level ID Previously thought to point to the level Snowman's Land, this bit actually relies on the level ID contained in the 8-byte long coordinate chunk at offset 0x00 to 0x07.
If address 0x00 is set to 0x0A, then the cap is lost in Snowman's Land. If address 0x00 is set to 0x08, then the cap is lost in Shifting Sand Land. If address 0x00 is set to 0x24, then the cap is lost in Tall, Tall Mountain.
If the level ID is set to any other value, Mario has his cap regardless. Address: 0x09 Bit flag: Bit 1, or 0000 0010 Short description: Cap lost – Shifting Sand Land This bit specifies that the cap is lost in Shifting Sand Land. Address: 0x09 Bit flag: Bit 2, or 0000 0100 Short description: Cap lost – Tall, Tall Mountain Despite the fact that bit 0 being set in conjunction with a 0x24 level ID can set Mario's cap being lost in Tall, Tall Mountain, this game never uses this method. Despite it being possible to have Mario's cap lost in Tall, Tall Mountain using bit 0 in conjunction with the level ID set to 0x24, this is not used in the game. Instead, a specific bit indicates whether Mario's cap is lost in Tall, Tall Mountain, which happens to be bit 2. Address: 0x09 Bit flag: Bit 3, or 0000 1000 Short description: Cap lost – Snowman's Land This bit specifies that the cap is lost in Snowman's Land. It is not used during normal gameplay.
Each game slot is checked individually, starting with the first slot. On boot, the Primary copy is checked; if valid, it is left alone, otherwise it Primary copy: If found to be valid, it is left alone -- this is true even if Backup is also valid, but still different than Primary copy. If found to be invalid, the Backup copy, if valid, will be restored into the Primary copy. Backup copy: If found to be valid, it is left alone -- this is true even if Primary is also valid, but still different than the backup. If found to be invalid, the Primary copy, if valid, will be copied to the backup. If neither are valid, the slot will reset itself.
This applies to first boot of the game.
Primary copy is called "Primary" because it is the primary copy of the save. It is the only copy that the game loads into RAM when reading the save data. While the backup copy behaves exactly like the Primary, it has lower priority and only used as a last measure. Primary copy
The Primary copy consists of the first half of a save slot (56 bytes).
If Primary copy is found to be valid, everything is fine, and nothing is written to EEPROM. This is true even in the case that Backup copy is also valid, but not exactly the same as Primary copy -- the backup remains.
If Primary copy is found to be invalid, Backup copy, if valid, will be restored to Primary copy. Backup copy
The Backup copy consists of the last half of a save slot (also 56 bytes).
If Backup copy is found to be valid, everything is fine, and nothing is written to EEPROM. This is true even in the case that Primary copy is also valid, but not exactly the same as the Backup copy -- nothing happens.
If Backup copy is found to be invalid, Primary copy, if valid, will be copied to Backup copy.
If neither copy is valid, both will be reformatted. It's important to note that only the invalid copy is touched when it is being written to. The valid data is untouched. Think of it like changing a letter instead of rewriting the entire word: Reed to Read instead of Reed to Read.
However, this only applies to the integrity checking of the 2 individual copies (primary and backup) of the save data within a save slot. When you save your game, it is written to both primary and backup copies.
It's been known that one of the misc flags determines if the entrance to Dire, Dire Docks is blocking the entrance to Bowser in the Fire Sea.
During normal gameplay, you cannot access the second Bowser area until you satisfy the 30 star door. Once you get there, you have no choice but to jump into the translucent water portal that covers the entrance to the second Bowser level.
Once you collect the first star, for reasons unknown, an animation is played, showing the water portal moving backwards, allowing you access to Bowser.
I assumed that the flag simply set whether the portal was pushed back or not, however, that is not the whole story. I noticed that if you had no stars in the level, the flag had no effect.
I then found that the portal flag only took effect if you had collected the first star in Dire, Dire Docks, which is "Board Bowser's Ship". I even tried the other stars, which had no effect.
Furthermore, if you have the first star set, but not the portal flag, the animation will play out immediately when you enter the corridor. And upon saving, the portal flag is set.
Thus, it is possible that the bit flag marks whether the animation was played. Of course, having that bit set, will change the position of the portal regardless. Then it follows that the bit really only marks the portal being pushed back.
The only new information here, is that it only takes effect if you've obtained the first star in DDD.
This one took quite a while to figure out. As far as stars and cannons are concerned (including level name entries), the Castle acts as a whole. Technically, there are three maps: Castle Interior, Castle Courtyard, and Castle Exterior. Five stars are obtainable on the Castle Interior map. Three Toads and Two MIPS. These stars are all saved to offset 0x08 in EEPROM, which cooresponds to this level. Through level editing, I was able to place a cannon in the Castle Exterior and Castle Courtyard. Upon activating it, the cannon flag was set in offset 0x0C, which, activates the cannon in the PREVIOUS level.
- Implement edit ability for Global values (Sound / Language)
- As-you-type input validation (Low priority, since a simple parseInt does a lot of the work)
- Rewrite the HTML generation code to be cleaner completely self-contained.
- Start the redesign. Make the interface more user-friendly, and give it a nice styled look.
- Implement "Dropdown" File menu - add options like Copy, Paste, Clear, Close, New, etc.
- Visual effect/flash that indicates to the user that a file was loaded / changed.
- Some form of indicator that unsaved changes were made - "Popup" message asking to confirm. (Low priority)
The GUI is currently very simple. There are buttons directly on the page for Save, Save As and Load, including a slot switch utility.
In order to implement additional functions, such as Clear slot, Copy / Paste slot, and Close file, a more concise UI should be used - such as a dropdown menu.
This can be done best through a complete UI redesign. I may redesign the app once I am satisfied with the general functionality of the app being solid.
Revisit the implementation of the Interface. Keep the same simple design. Look into which method of DOM manipulation is best.
Here is an interesting proposal (Note the inline JS must be in its own file):
<!doctype html>
<html>
<head>
<title>sm64eep</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="sm64eep.js"></script>
<script>
window.addEventListener("load", function() {
var Editor = new SM64Editor();
Editor.init();
});
</script>
</head>
<body id="SM64Editor">SM64Editor did not initialize.</body>
</html>
The <body>
tag is empty, but has a very specific id
set. The editor is designed to take up the entire page.
Editor.go()
will replace the entire body#SM64Editor
content with the actual editor.
Keeping this here just in case. I'm not planning to change it. I honestly can't think of a better way than assigning properties, besides using attributes such as id="foo"
or data-*="foo"
. There is also the choice of assigning many different custom eventListeners to each element, like an anonymous function wrapper.
It is extremely convenient to assign parameters directly to the HTMLElement
itself. And I dislike using attributes because they're needlessly long text, and not as flexible as modifying the HTMLElement
object itself.
"Less obtrusive method for assigning events and handling widget params."
Note: The metadata issue above can possibly be implemented using objects and prototypes?
// This is one prototype that could possibly be used to avoid Node modifying
var update = function(param)
{
console.log(param);
}
for(var i = 0; i < 10; i++)
{
var elem = document.createElement("input");
elem.type = "checkbox";
(function(i){
elem.addEventListener("click", function(){
update(i);
});
})(i);
document.body.appendChild(elem);
}
// or
(function (param) {
var o = elem(["input",{
type:'checkbox',
$_addEventListener: ["click", function(){ test(param); } ]
}]);
row.childNodes[1].appendChild(o);
})(["flag",i,j]);