diff --git a/.gitignore b/.gitignore index b4bc46a..1d3d47c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +[Bb]eta/ [Tt]rash/ *.db \ No newline at end of file diff --git a/changelog.html b/changelog.html index 673d8b6..05baeb1 100644 --- a/changelog.html +++ b/changelog.html @@ -2,136 +2,136 @@ + - Changelog -
-

Full Changelog

-

Jan 24, 2048

-

Optimized 'Fast Any%'

-

Shortens the code by a few lines

-

Jan 20, 2018

-

Added 'Remove Save Boxes'

-

Adds the option to have save boxes removed outside of 'Fast Any%'

-

Fixed episode names in 'Fast Any%'.

-

Makes the correct episode names appear in the demo cutscenes and the pause menu in Fast Any%.

-

Made 'Fast Any%' compatible with 'Shine Get Timer' and 'Shine Touch Timer'.

-

Allows the use of IGT in Fast Any%, which was previously impossible.

-

Jan 18, 2018

-

Site changes

-

Updated guides.

-

Jan 17, 2018

-

Site changes

-

Added JP-A port for all codes.

-

Jan 8, 2018

-

Site changes

-

Added a guide on how to install IOS58.

-

Jan 1, 2018

-

Updated 'D-Pad Functions'

-

Fixed dialogue replacement.

-

Dec 30, 2017

-

Updated 'D-Pad Functions'

-

Added Plaza Yoshi Unlock.

-

Dec 19, 2017

-

Updated 'Fast Any%'

-

Added FMV Skips except for Pinna 1.

-

Dec 05, 2017

-

Site Changes

-

Added option to download codes formatted for the Gecko Cheat Manager.

-

Nov 29, 2017

-

Updated 'Level Select' for PAL

-

Fixed Pinna not resetting inside the park.

-

Updated 'Shine Touch Timer' and 'Shine Get Timer'

-

Made timers stop after the bowser fight when hitting the last platform.

-

Nov 12, 2017

-

Updated 'Free Pause'

-

Fixed 'Free Pause' incompatibility with 'Shine Get Timer' caused by them injecting code in the same address.

-

Nov 09, 2017

-

Site changes

-

Added download button for raw codes for Dolphin.

-

Nov 08, 2017

-

Added 'Fast 79 Shines' for NTSC-U

-

Same concept as 'Fast Any%'.

-

Nov 07, 2017

-

Seperated 'Exit Area Everywhere' from 'Free Pause'

-

Seperated these two codes again since they don't depend on each other.

-

Nov 06, 2017

-

Updated Ingame Timers and Level Select

-

The Original Ingame Timer has been marked as deprecated. You can still find it on the bottom of the codelist though if you still want to use it. Instead, there are now two other timers:

-
- -

Since the Shine Get timer contained a way better Level Select, the Level Select code has been replaced with the one from the timer. It includes the most recent fixes and also has some maintenance advantages.

-
-

Level Select changes:

- -

Timer changes (compared to original timer):

- -

Known bugs:

- -

Added 'Free Pause'

-

'Free Pause' replaces 'Enable Pause Mid-Air' and 'Enable Exit Area Everywhere'. It now also allows you to pause during cutscenes.

-

Site Changes

- -

Nov 04, 2017

-

Changed Shine Get Timer

-

Fixed timer resetting during wrong cutscenes when using 'Exit Area' after touching a Shine.

-

Oct 30, 2017

-

Added 'Enable Exit Area Everywhere'

-

Allows you to choose 'Exit Area' in the pause menu on Plaza.

-

Oct 29, 2017

-

Added 'Shine Get Timer'

-

New timer that starts and ends consistently in different levels, making comparisons easier.

-

Oct 28, 2017

-

Updated 'DPad Functions'

-

New functions have been added to the DPad Functions:

- -

Oct 26, 2017

-

Added 'Enable Pause Mid-Air'

-

Allows you to pause mid-air.

-

Oct 24, 2017

-

Added 'Shine Outfit'

-

Always wear glasses and the shirt.

-

Oct 15, 2017

-

Site Changes

-

Fixed the download button not working for Firefox.

-

Oct 14, 2017

-

Added 'Fast Any%' for JP and PAL

-

-

-

Oct 11, 2017

-

Added 'Stage Randomizer' for NTSC-U

-

Experimental! Loads a random stage after exiting of finishing a level.

-
+
+

Full Changelog

+

Feb 02, 2018

+

Site changes

+

Integrated Noki Dokis Stage Loader into the Generator.

+

Jan 24, 2018

+

Optimized 'Fast Any%'

+

Shortens the code by a few lines

+

Jan 20, 2018

+

Added 'Remove Save Boxes'

+

Adds the option to have save boxes removed outside of 'Fast Any%'

+

Fixed episode names in 'Fast Any%'.

+

Makes the correct episode names appear in the demo cutscenes and the pause menu in Fast Any%.

+

Made 'Fast Any%' compatible with 'Shine Get Timer' and 'Shine Touch Timer'.

+

Allows the use of IGT in Fast Any%, which was previously impossible.

+

Jan 18, 2018

+

Site changes

+

Updated guides.

+

Jan 17, 2018

+

Site changes

+

Added JP-A port for all codes.

+

Jan 8, 2018

+

Site changes

+

Added a guide on how to install IOS58.

+

Jan 1, 2018

+

Updated 'D-Pad Functions'

+

Fixed dialogue replacement.

+

Dec 30, 2017

+

Updated 'D-Pad Functions'

+

Added Plaza Yoshi Unlock.

+

Dec 19, 2017

+

Updated 'Fast Any%'

+

Added FMV Skips except for Pinna 1.

+

Dec 05, 2017

+

Site Changes

+

Added option to download codes formatted for the Gecko Cheat Manager.

+

Nov 29, 2017

+

Updated 'Level Select' for PAL

+

Fixed Pinna not resetting inside the park.

+

Updated 'Shine Touch Timer' and 'Shine Get Timer'

+

Made timers stop after the bowser fight when hitting the last platform.

+

Nov 12, 2017

+

Updated 'Free Pause'

+

Fixed 'Free Pause' incompatibility with 'Shine Get Timer' caused by them injecting code in the same address.

+

Nov 09, 2017

+

Site changes

+

Added download button for raw codes for Dolphin.

+

Nov 08, 2017

+

Added 'Fast 79 Shines' for NTSC-U

+

Same concept as 'Fast Any%'.

+

Nov 07, 2017

+

Seperated 'Exit Area Everywhere' from 'Free Pause'

+

Seperated these two codes again since they don't depend on each other.

+

Nov 06, 2017

+

Updated Ingame Timers and Level Select

+

The Original Ingame Timer has been marked as deprecated. You can still find it on the bottom of the codelist though if you still want to use it. Instead, there are now two other timers:

+
+ +

Since the Shine Get timer contained a way better Level Select, the Level Select code has been replaced with the one from the timer. It includes the most recent fixes and also has some maintenance advantages.

+
+

Level Select changes:

+ +

Timer changes (compared to original timer):

+ +

Known bugs:

+ +

Added 'Free Pause'

+

'Free Pause' replaces 'Enable Pause Mid-Air' and 'Enable Exit Area Everywhere'. It now also allows you to pause during cutscenes.

+

Site Changes

+ +

Nov 04, 2017

+

Changed Shine Get Timer

+

Fixed timer resetting during wrong cutscenes when using 'Exit Area' after touching a Shine.

+

Oct 30, 2017

+

Added 'Enable Exit Area Everywhere'

+

Allows you to choose 'Exit Area' in the pause menu on Plaza.

+

Oct 29, 2017

+

Added 'Shine Get Timer'

+

New timer that starts and ends consistently in different levels, making comparisons easier.

+

Oct 28, 2017

+

Updated 'DPad Functions'

+

New functions have been added to the DPad Functions:

+ +

Oct 26, 2017

+

Added 'Enable Pause Mid-Air'

+

Allows you to pause mid-air.

+

Oct 24, 2017

+

Added 'Shine Outfit'

+

Always wear glasses and the shirt.

+

Oct 15, 2017

+

Site Changes

+

Fixed the download button not working for Firefox.

+

Oct 14, 2017

+

Added 'Fast Any%' for JP and PAL

+

-

+

Oct 11, 2017

+

Added 'Stage Randomizer' for NTSC-U

+

Experimental! Loads a random stage after exiting of finishing a level.

+
\ No newline at end of file diff --git a/changelog.xml b/changelog.xml index 88b260b..f4216a8 100644 --- a/changelog.xml +++ b/changelog.xml @@ -1,5 +1,9 @@ + + Feb 02, 2018 + Integrated Noki Dokis Stage Loader. + Jan 24, 2018 Optimized 'Fast Any%'. diff --git a/codes/GMSE01.xml b/codes/GMSE01.xml index 95597af..e7ae3d6 100644 --- a/codes/GMSE01.xml +++ b/codes/GMSE01.xml @@ -132,7 +132,7 @@ Psychonauter 1.6 Nov 29, 2017 -
Requires the Level Select code or Fast Any% to be active.]]>
+
Requires the Level Select code, Fast Any% or Stage Loader to be active.]]>
C2031F68 0000000F 3CC0817F 60C60100 @@ -233,7 +233,7 @@ Shine Get Timer Psychonauter 1.6 -
Requires the Level Select code or Fast Any% to be active.]]>
+
Requires the Level Select code, Fast Any% or Stage Loader to be active.]]>
Nov 29, 2017 C2031F68 0000000F @@ -345,7 +345,7 @@ Psychonauter, Dan Salvato, Noki Doki 1.5 Nov 06, 2017 -
]]>
+
]]>
C22A6710 0000007F 3C60803E 60639710 @@ -481,7 +481,7 @@ Fast Any% Psychonauter, Noki Doki 1.3.2 - Loads stages in any% order, skips all save boxes, replaces all dialog with "!!!" (except for the Pianta 5 secret) and makes all FMVs skippable (except for the Pinna 1 cutscenes). This code is not compatible with the Level Select or Stage Randomizer code. + Loads stages in any% order, skips all save boxes, replaces all dialog with "!!!" (except for the Pianta 5 secret) and makes all FMVs skippable (except for the Pinna 1 cutscenes). This code is not compatible with the Level Select, Stage Loader or Stage Randomizer code. Jan 24, 2018 C22A6710 00000077 diff --git a/codes/GMSJ01.xml b/codes/GMSJ01.xml index ab1dcee..b4a6d56 100644 --- a/codes/GMSJ01.xml +++ b/codes/GMSJ01.xml @@ -134,7 +134,7 @@ Psychonauter 1.6 Nov 29, 2017 -
Requires the Level Select code or Fast Any% to be active.]]>
+
Requires the Level Select code, Fast Any% or Stage Loader to be active.]]>
C23617C4 0000000F 3CC0817F 60C60100 @@ -235,7 +235,7 @@ Shine Get Timer Psychonauter 1.6 -
Requires the Level Select code or Fast Any% to be active.]]>
+
Requires the Level Select code, Fast Any% or Stage Loader to be active.]]>
Nov 29, 2017 C23617C4 0000000F @@ -347,7 +347,7 @@ Psychonauter, Dan Salvato, ParadoxKarl, Noki Doki 1.5 Nov 06, 2017 -
]]>
+
]]>
C20FA19C 0000007F 3C60803E 60636010 @@ -484,7 +484,7 @@ Psychonauter, Noki Doki 1.3.2 Jan 24, 2018 - Loads stages in any% order, skips all save boxes, replaces all dialog with "!!!" (except for the Pianta 5 secret) and makes all FMVs skippable (except for the Pinna 1 cutscenes). This code is not compatible with the Level Select code. + Loads stages in any% order, skips all save boxes, replaces all dialog with "!!!" (except for the Pianta 5 secret) and makes all FMVs skippable (except for the Pinna 1 cutscenes). This code is not compatible with the Level Select or Stage Loader code. C20FA19C 00000077 3C60817F 60630100 diff --git a/codes/GMSJ0A.xml b/codes/GMSJ0A.xml index f60f8b8..bc61a03 100644 --- a/codes/GMSJ0A.xml +++ b/codes/GMSJ0A.xml @@ -134,7 +134,7 @@ Psychonauter, Noki Doki 1.6 Jan 17, 2018 -
Requires the Level Select code or Fast Any% to be active.]]>
+
Requires the Level Select code, Fast Any% or Stage Loader to be active.]]>
C2363E70 0000000F 3CC0817F 60C60100 @@ -235,7 +235,7 @@ Shine Get Timer Psychonauter, Noki Doki 1.6 -
Requires the Level Select code or Fast Any% to be active.]]>
+
Requires the Level Select code, Fast Any% or Stage Loader to be active.]]>
Jan 17, 2018 C2363E70 0000000F @@ -347,7 +347,7 @@ Psychonauter, Dan Salvato, ParadoxKarl, Noki Doki 1.5 Jan 17, 2018 -
]]>
+
]]>
C20FA19C 0000007F 3C60803D 6063A8F0 @@ -484,7 +484,7 @@ Psychonauter, Noki Doki 1.3.2 Jan 24, 2018 - Loads stages in any% order, skips all save boxes, replaces all dialog with "!!!" (except for the Pianta 5 secret) and makes all FMVs skippable (except for the Pinna 1 cutscenes). This code is not compatible with the Level Select code. + Loads stages in any% order, skips all save boxes, replaces all dialog with "!!!" (except for the Pianta 5 secret) and makes all FMVs skippable (except for the Pinna 1 cutscenes). This code is not compatible with the Level Select or Stage Loader code. C22865F4 00000077 3C60817F 60630100 diff --git a/codes/GMSP01.xml b/codes/GMSP01.xml index 69041b6..ba637a8 100644 --- a/codes/GMSP01.xml +++ b/codes/GMSP01.xml @@ -142,7 +142,7 @@ Psychonauter 1.6 Nov 29, 2017 -
Requires the Level Select code or Fast Any% to be active.]]>
+
Requires the Level Select code, Fast Any% or Stage Loader to be active.]]>
C2032020 0000000F 3CC0817F 60C60100 @@ -243,7 +243,7 @@ Shine Get Timer Psychonauter 1.6 -
Requires the Level Select code or Fast Any% to be active.]]>
+
Requires the Level Select code, Fast Any% or Stage Loader to be active.]]>
Nov 29, 2017 C2032020 0000000F @@ -355,7 +355,7 @@ Psychonauter, Dan Salvato, Noki Doki 1.5.1 Nov 29, 2017 -
]]>
+
]]>
C229E668 0000007F 3C60803E 606310D0 @@ -492,7 +492,7 @@ Psychonauter, Noki Doki 1.3.2 Jan 24, 2018 - Loads stages in any% order, skips all save boxes, replaces all dialog with "!!!" (except for the Pianta 5 secret) and makes all FMVs skippable (except for the Pinna 1 cutscenes). This code is not compatible with the Level Select code. + Loads stages in any% order, skips all save boxes, replaces all dialog with "!!!" (except for the Pianta 5 secret) and makes all FMVs skippable (except for the Pinna 1 cutscenes). This code is not compatible with the Level Select or Stage Loader code. C229E668 00000077 3C60817F 60630100 diff --git a/codes/fast/GMSE01.json b/codes/fast/GMSE01.json new file mode 100644 index 0000000..5e00c13 --- /dev/null +++ b/codes/fast/GMSE01.json @@ -0,0 +1 @@ +{"injectAddr":"2A6710","fmOffset":"9FA0","notext":{"yes":"048D3A3C 21000000\r\n04153DA0 38000000\r\n0415317C 38005000\r\n","pv5":"048D3A3C 21000000\r\n283E9712 00002A00\r\n04153DA0 801C0004\r\n0415317C A81C0340\r\nE2000001 00000000\r\n2A3E9712 00002A00\r\n04153DA0 38000000\r\n0415317C 38005000\r\nE2000001 00000000\r\n","no":""},"nofmvs":{"yes":"042B5EF4 38600001\r\n042B5E8C 38600001\r\n","pp1":"C22B5EF0 00000004\r\n38840391 5480043C\r\n2C000398 4182000C\r\n3C800001 6084039A\r\n60000000 00000000\r\nC22B5E88 00000004\r\n38840391 5480043C\r\n2C000398 4182000C\r\n3C800001 6084039A\r\n60000000 00000000\r\n","no":""}} \ No newline at end of file diff --git a/codes/fast/GMSJ01.json b/codes/fast/GMSJ01.json new file mode 100644 index 0000000..781be56 --- /dev/null +++ b/codes/fast/GMSJ01.json @@ -0,0 +1 @@ +{"injectAddr":"0FA19C","fmOffset":"97D0","notext":{"yes":"048D8A7C D6008149\r\n048D8A80 81498149\r\n048D8A84 00000000\r\n04215290 38000000\r\n04214610 38005000\r\n","pv5":"048D8A7C D6008149\r\n048D8A80 81498149\r\n048D8A84 00000000\r\n283E6012 00002A00\r\n04215290 801C0004\r\n04214610 A81C0340\r\nE2000001 00000000\r\n2A3E6012 00002A00\r\n04215290 38000000\r\n04214610 38005000\r\nE2000001 00000000\r\n","no":""},"nofmvs":{"yes":"0410AF5C 38600001\r\n0410AFC0 38600001\r\n","pp1":"C210AF58 00000004\r\n38840391 5480043C\r\n2C000398 4182000C\r\n3C800001 6084039A\r\n60000000 00000000\r\nC210AFBC 00000004\r\n38840391 5480043C\r\n2C000398 4182000C\r\n3C800001 6084039A\r\n60000000 00000000\r\n","no":""}} \ No newline at end of file diff --git a/codes/fast/GMSJ0A.json b/codes/fast/GMSJ0A.json new file mode 100644 index 0000000..379932d --- /dev/null +++ b/codes/fast/GMSJ0A.json @@ -0,0 +1 @@ +{"injectAddr":"2865F4","fmOffset":"9E60","notext":{"yes":"048CD55C D6008149\r\n048CD560 81498149\r\n048CD564 00000000\r\n041351C4 38000000\r\n04134524 38005000\r\n","pv5":"048CD55C D6008149\r\n048CD560 81498149\r\n048CD564 00000000\r\n283DA8F2 00002A00\r\n041351C4 801C0004\r\n04134524 A81C0340\r\nE2000001 00000000\r\n2A3DA8F2 00002A00\r\n041351C4 38000000\r\n04134524 38005000\r\nE2000001 00000000\r\n","no":""},"nofmvs":{"yes":"04295AB4 38600001\r\n04295B18 38600001\r\n","pp1":"C2295AB0 00000004\r\n38840391 5480043C\r\n2C000398 4182000C\r\n3C800001 6084039A\r\n60000000 00000000\r\nC2295B14 00000004\r\n38840391 5480043C\r\n2C000398 4182000C\r\n3C800001 6084039A\r\n60000000 00000000\r\n","no":""}} \ No newline at end of file diff --git a/codes/fast/GMSP01.json b/codes/fast/GMSP01.json new file mode 100644 index 0000000..932f1fd --- /dev/null +++ b/codes/fast/GMSP01.json @@ -0,0 +1 @@ +{"injectAddr":"29E668","fmOffset":"9EC8","notext":{"yes":"20570B7C 00000000\r\n0474E87C 21000000\r\n20570B7D 00000001\r\n0474E9F4 21210000\r\n20570B7D 00000002\r\n0474ED38 00000000\r\n20570B7D 00000003\r\n0474EE04 A1000000\r\n20570B7D 00000004\r\n0474EBDC 21210000\r\nE2000001 00000000\r\n04148D20 38000000\r\n04147F98 38005000\r\n","pv5":"283E10D2 00002A00\r\n04148D20 801C0004\r\n04147F98 A81C0340\r\nE2000001 00000000\r\n2A3E10D2 00002A00\r\n04148D20 38000000\r\n04147F98 38005000\r\nE2000001 00000000\r\n20570B7C 00000000\r\n0474E87C 21000000\r\n20570B7D 00000001\r\n0474E9F4 21210000\r\n20570B7D 00000002\r\n0474ED38 00000000\r\n20570B7D 00000003\r\n0474EE04 A1000000\r\n20570B7D 00000004\r\n0474EBDC 21210000\r\nE2000001 00000000\r\n","no":""},"nofmvs":{"yes":"042ADE20 38600001\r\n042ADE88 38600001\r\n","pp1":"C22ADE1C 00000004\r\n38840391 5480043C\r\n2C000398 4182000C\r\n3C800001 6084039A\r\n60000000 00000000\r\nC22ADE84 00000004\r\n38840391 5480043C\r\n2C000398 4182000C\r\n3C800001 6084039A\r\n60000000 00000000\r\n","no":""}} \ No newline at end of file diff --git a/gctGenerator.js b/gctGenerator.js index e20392a..5ac7f42 100644 --- a/gctGenerator.js +++ b/gctGenerator.js @@ -1,14 +1,14 @@ if (navigator.userAgent.toLowerCase().indexOf("firefox") > -1) { - HTMLElement.prototype.click = function() { - var evt = this.ownerDocument.createEvent("MouseEvents"); - evt.initMouseEvent("click", true, true, this.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null); - this.dispatchEvent(evt); + HTMLElement.prototype.click = function() { + var evt = this.ownerDocument.createEvent("MouseEvents"); + evt.initMouseEvent("click", true, true, this.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null); + this.dispatchEvent(evt); } } -document.getElementById("checkList").addEventListener("click", function(ev) { - if (ev.target && ev.target.nodeName == "LI") { - ev.target.classList.toggle("checked"); +document.getElementById("checklist").addEventListener("click", function(ev) { + if (ev.target && ev.target.nodeName == "LI") { + ev.target.classList.toggle("checked"); } }); @@ -27,26 +27,20 @@ function parseXML(name) { var desc = xmlData[i].getElementsByTagName("title")[0].textContent; var t = document.createTextNode(desc); li.appendChild(t); - li.setAttribute("data-codename", xmlData[i].getElementsByTagName("title")[0].textContent); - li.setAttribute("data-codeauthor", xmlData[i].getElementsByTagName("author")[0].textContent); - li.setAttribute("data-codedesc", xmlData[i].getElementsByTagName("description")[0].textContent); - li.setAttribute("data-codeversion", xmlData[i].getElementsByTagName("version")[0].textContent); - li.setAttribute("data-codedate", xmlData[i].getElementsByTagName("date")[0].textContent); - li.setAttribute("data-codesrc", xmlData[i].getElementsByTagName("source")[0].textContent.replace(/[\s\n\r\t]+/gm, "")); + li.setAttribute("data-codename", btoa(xmlData[i].getElementsByTagName("title")[0].textContent)); + li.setAttribute("data-codeauthor", btoa(xmlData[i].getElementsByTagName("author")[0].textContent)); + li.setAttribute("data-codedesc", btoa(xmlData[i].getElementsByTagName("description")[0].textContent)); + li.setAttribute("data-codeversion", btoa(xmlData[i].getElementsByTagName("version")[0].textContent)); + li.setAttribute("data-codedate", btoa(xmlData[i].getElementsByTagName("date")[0].textContent)); + li.setAttribute("data-codesrc", btoa(xmlData[i].getElementsByTagName("source")[0].textContent.replace(/[\s\n\r\t]+/gm, ""))); li.setAttribute("onmouseover", "updateDescription(this)"); - document.getElementById("checkList").appendChild(li); + document.getElementById("checklist").appendChild(li); } - button = document.getElementById("downloadButton"); - button.style.visibility = "visible"; - button.disabled = false; - button = document.getElementById("dolphinDownloadButton"); - button.style.visibility = "visible"; - button.disabled = false; - button = document.getElementById("gcmDownloadButton"); - button.style.visibility = "visible"; - button.disabled = false; - document.getElementById("gameID").disabled = false; + var buttons = document.getElementsByTagName("button"); + for (var i = 0; i < buttons.length; i++) buttons[i].disabled = false; + + document.getElementById("gameversion").disabled = false; } }; @@ -54,140 +48,358 @@ function parseXML(name) { xml.send(); } +function updateFastCode(name) { + var xml = new XMLHttpRequest(); + var file = "codes/fast/" + name + ".json"; + xml.onreadystatechange = function() { + if (this.status == 200 && this.readyState == 4) { + document.getElementById("route_levels").setAttribute("data-json", btoa(xml.responseText)); + } + } + xml.open("GET",file); + xml.send(); +} + function downloadFile(data, filename) { - var fname = filename.replace("GMSJ0A","GMSJ01"); - - var file = new Blob([data], { - type: "application/octet-stream" - }); + var file = new Blob([data], { + type: "application/octet-stream" + }); - if (window.navigator.msSaveOrOpenBlob) - window.navigator.msSaveOrOpenBlob(file, fname); - else { - var a = document.createElement("a"), + if (window.navigator.msSaveOrOpenBlob) window.navigator.msSaveOrOpenBlob(file, filename.replace("GMSJ0A","GMSJ01")); + else { + var a = document.createElement("a"), url = window.URL.createObjectURL(file); - a.href = url; - a.download = fname; - a.click(); - setTimeout(function() { - window.URL.revokeObjectURL(url); - }, 500); + a.href = url; + a.download = filename.replace("GMSJ0A","GMSJ01"); + a.click(); + setTimeout(function() { window.URL.revokeObjectURL(url); }, 500); } } function generateGCT() { - if (document.getElementById("gameID").value === "Choose Version") { - alert("Select the game version!"); - return; - } - var data = "00D0C0DE00D0C0DE"; - var codeList = document.getElementById("checkList").getElementsByTagName("li"); - var valueSelected = false; - for (var i = 0; i < codeList.length; i++) { - if (codeList[i].className === "checked") { - data += codeList[i].getAttribute("data-codesrc"); + if (document.getElementById("gameversion").value === "Choose Version") { + alert("Select the game version!"); + return; + } + var data = "00D0C0DE00D0C0DE"; + var codeList = document.getElementById("checklist").getElementsByTagName("li"); + var valueSelected = false; + for (var i = 0; i < codeList.length; i++) { + if (codeList[i].className === "checked") { + data += atob(codeList[i].getAttribute("data-codesrc")); + valueSelected = true; + } + } + + var fastcode = getFastCode(); + + if(fastcode !== false) { + data += fastcode; valueSelected = true; - } - } + } - if (valueSelected) { - data += "FF00000000000000"; - var rawData = new Uint8Array(data.length / 2); + if (valueSelected) { + data += "FF00000000000000"; + var rawData = new Uint8Array(data.length / 2); - for (var x = 0; x < rawData.length; x++) { - rawData[x] = parseInt(data.substr(x * 2, 2), 16); - } + for (var x = 0; x < rawData.length; x++) { + rawData[x] = parseInt(data.substr(x * 2, 2), 16); + } - downloadFile(rawData, document.getElementById("gameID").value + ".gct"); - } else { - alert("No cheat(s) selected!"); - } + downloadFile(rawData, document.getElementById("gameversion").value + ".gct"); + } else { + alert("No cheat(s) selected!"); + } } -function generateTXT(s) { - if (document.getElementById("gameID").value === "Choose Version") { - alert("Select the game version!"); - return; - } - if (s.id === "dolphinDownloadButton") var data = "Paste the following on top of your games .ini file:\r\n[Gecko]"; - else var data = document.getElementById("gameID").value.replace("GMSJ0A","GMSJ01") + "\r\nSuper Mario Sunshine"; - var codeList = document.getElementById("checkList").getElementsByTagName("li"); - var valueSelected = false; - for (var i = 0; i < codeList.length; i++) { - if (codeList[i].className === "checked") { - data += "\r\n"; - if (s.id === "gcmDownloadButton") data += "\r\n"; - else data += "$"; - data += codeList[i].getAttribute("data-codename") + " (" + codeList[i].getAttribute("data-codedate") + ") [" + codeList[i].getAttribute("data-codeauthor") + "]\r\n"; - data += (codeList[i].getAttribute("data-codesrc").match(/.{8}/g).join(" ")).replace(/(.{17})./g, "$1\r\n"); - valueSelected = true; - } - } +function generateTXT() { - if (valueSelected) { - downloadFile(data, document.getElementById("gameID").value + ".txt"); - } else { - alert("No cheat(s) selected!"); - } + var dolphin = (document.getElementById("downloadformat").value === "ini"); + + if (document.getElementById("gameversion").value === "Choose Version") { + alert("Select the game version!"); + return; + } + if (dolphin) var data = "Paste the following on top of your games .ini file:\r\n[Gecko]"; + else var data = document.getElementById("gameversion").value.replace("GMSJ0A","GMSJ01") + "\r\nSuper Mario Sunshine"; + var codeList = document.getElementById("checklist").getElementsByTagName("li"); + var valueSelected = false; + for (var i = 0; i < codeList.length; i++) { + if (codeList[i].className === "checked") { + data += "\r\n"; + if (dolphin) data += "$"; + else data += "\r\n"; + data += atob(codeList[i].getAttribute("data-codename")) + " (" + atob(codeList[i].getAttribute("data-codedate")) + ") [" + atob(codeList[i].getAttribute("data-codeauthor")) + "]\r\n"; + data += (atob(codeList[i].getAttribute("data-codesrc")).match(/.{8}/g).join(" ")).replace(/(.{17})./g, "$1\r\n"); + valueSelected = true; + } + } + + var fastcode = getFastCode(); + + if(fastcode !== false) { + data += "\r\n"; + if (dolphin) data += "$"; + else data += "\r\n"; + data += "Stage list loader [Noki Doki]\r\n"; + data += (fastcode.match(/.{8}/g).join(" ")).replace(/(.{17})./g, "$1\r\n"); + valueSelected = true; + } + + if (valueSelected) + downloadFile(data, document.getElementById("gameversion").value + ".txt"); + else alert("No cheat(s) selected!"); +} + +function downloadCodes() { + if (document.getElementById("downloadformat").value === "gct") generateGCT(); + else generateTXT(); } function updateCodelist() { - resetDescription(); - document.getElementById("gameID").disabled = true; - button = document.getElementById("downloadButton"); - button.style.visibility = "hidden"; - button.disabled = true; - button = document.getElementById("dolphinDownloadButton"); - button.style.visibility = "hidden"; - button.disabled = true; - button = document.getElementById("gcmDownloadButton"); - button.style.visibility = "hidden"; - button.disabled = true; - document.getElementById("checkList").innerHTML = ""; - var gameVersion = document.getElementById("gameID").value; - parseXML(gameVersion); + resetDescription(); + document.getElementById("gameversion").disabled = true; + var buttons = document.getElementsByTagName("button"); + for (var i = 0; i < buttons.length; i++) buttons[i].disabled = true; + document.getElementById("checklist").innerHTML = ""; + var gameVersion = document.getElementById("gameversion").value; + parseXML(gameVersion); + updateFastCode(gameVersion); + document.getElementById("left").style.visibility = "visible"; + while (document.getElementsByClassName("initialhidden").length > 0) { + document.getElementsByClassName("initialhidden")[0].classList.remove("initialhidden"); + } } function updateDescription(s) { - document.getElementById("descriptionBox").innerHTML = "

" + - s.getAttribute("data-codename") + "

Author(s): " + - s.getAttribute("data-codeauthor") + "

Version: " + - s.getAttribute("data-codeversion") + " (" + - s.getAttribute("data-codedate") + ")

" + "

Description:

" + - s.getAttribute("data-codedesc") + "

"; + document.getElementById("descriptionbox").innerHTML = "

" + + atob(s.getAttribute("data-codename")) + "

Author(s): " + + atob(s.getAttribute("data-codeauthor")) + "

Version: " + + atob(s.getAttribute("data-codeversion")) + " (" + + atob(s.getAttribute("data-codedate")) + ")

" + "

Description:

" + + atob(s.getAttribute("data-codedesc")) + "

"; } -function setButtonDescription(s) { - if (s.id === "downloadButton") - document.getElementById("descriptionBox").innerHTML = "

Download GCT

Download the cheats in the GCT format for use with Nintendont.

"; - else if (s.id === "dolphinDownloadButton") - document.getElementById("descriptionBox").innerHTML = "

Download for Dolphin

Download a textfile containing the formatted codes for use with Dolphin. Copy the contents of the file on top of your games .ini file.

You can open the .ini file by right clicking the game in Dolphin. In the context menu select \"Properties\" and then \"Edit configuration\".

"; - else - document.getElementById("descriptionBox").innerHTML = "

Download for Gecko Cheat Manager

Download the cheats in a textfile formatted for use with the Gecko Cheat Manager. Place the txt file in SD:/txtcodes/.

A zip archive containing pregenerated txt files with all available codes on this site can be downloaded here."; +function updateUIDescription(s) { + if (s.id === "route_notext") + document.getElementById("descriptionbox").innerHTML = "

Remove Dialogue

Replaces all Dialogue with \"!!!\". 'Always' and 'Not in Pianta 5' will override the dialogue skip from the DPad Functions.

"; + else if (s.id === "route_nofmvs") + document.getElementById("descriptionbox").innerHTML = "

Skippable Cutscenes

Makes FMVs Skippable. 'Always' has the same effect as the 'FMV Skips' code. Also, having 'FMV Skips' enabled will override 'Not in Pinna 1' - so don't use both simultaneously.

"; + else if (s.id === "route_random") + document.getElementById("descriptionbox").innerHTML = "

Random Level Order

Randomizes what level is loaded next - it can be any from the levels you choose on the list. Even levels that you've finished already.

"; + else if (s.id === "downloadformat") + document.getElementById("descriptionbox").innerHTML = "

File Format

You can choose between 3 file formats:

GCT

Download a GCT file for use with Nintendont

Dolphin INI

Download a textfile containing the formatted codes for use with Dolphin. Copy the contents of the file on top of your games .ini file.

You can open the .ini file by right clicking the game in Dolphin. In the context menu select 'Properties' and then 'Edit configuration'.

Cheat Manager TXT

Download the cheats in a textfile formatted for use with the Gecko Cheat Manager. Place the txt file in SD:/txtcodes/.

A zip archive containing pregenerated txt files with all available codes on this site can be downloaded here.

"; + else if (s.id === "stageloader") + document.getElementById("descriptionbox").innerHTML = "

Stage Loader

Select yes if you want to use a custom stage loader, which automatically loads the levels you choose, similiar to 'Fast Any%'.

"; } function resetDescription() { - document.getElementById("descriptionBox").innerHTML = "

Select your codes from the list...

"; + document.getElementById("descriptionbox").innerHTML = "

Choose your codes from the list...

"; } function updateChangelog() { - var xml = new XMLHttpRequest(); - var file = "changelog.xml"; - xml.onload = function() { - if (this.status == 200 && this.responseXML != null) { - var changelogData = xml.responseXML; - changelogData = (new DOMParser()).parseFromString(xml.responseText, "text/xml"); - changelogData = changelogData.getElementsByTagName("update"); + document.getElementById("gameversion").style.visibility = "visible"; + var xml = new XMLHttpRequest(); + var file = "changelog.xml"; + xml.onload = function() { + if (this.status == 200 && this.responseXML != null) { + var changelogData = xml.responseXML; + changelogData = (new DOMParser()).parseFromString(xml.responseText, "text/xml"); + changelogData = changelogData.getElementsByTagName("update"); - for (var i = 0; i < changelogData.length && i < 5; i++) { - document.getElementById("changelog").innerHTML += "

" + changelogData[i].getElementsByTagName("date")[0].textContent + ": " + changelogData[i].getElementsByTagName("change")[0].textContent + "

"; + document.getElementById("lastupdate").innerHTML = "Last Updated: " + changelogData[0].getElementsByTagName("date")[0].textContent; + for (var i = 0; i < changelogData.length && i < 5; i++) { + document.getElementById("changelog").innerHTML += "

" + changelogData[i].getElementsByTagName("date")[0].textContent + ": " + changelogData[i].getElementsByTagName("change")[0].textContent + "

"; + } + + document.getElementById("changelog").innerHTML += "more ..."; + }; + } + + xml.open("GET", file); + xml.send(); +} + +/**************************** +* +* Fastcode, https://github.com/QbeRoot/fastcodes/blob/master/script.js +* +****************************/ + +'strict mode' +const levels = document.querySelector("#route_levels"); +const template = levels.lastElementChild; +template.ondragstart = function() { return false; }; + +function appendLevel(code) { + const clone = template.cloneNode(true); + clone.draggable = true; + selSetHandlers(clone); + clone.querySelector("select").value = code; + levels.insertBefore(clone, template); +} + +function clearLevels() { + while (levels.firstChild !== template) levels.removeChild(levels.firstChild); +} + +template.addEventListener("change", function () { + appendLevel(template.querySelector("select").value); + template.querySelector("select").value = "0F00"; +}) + +levels.addEventListener("change", function ({target: t}) { + if (t.value === "0F00" && t.parentNode !== template) levels.removeChild(t.parentNode); +}) + +levels.addEventListener("click", function ({target: t}) { + if (t.tagName.toUpperCase() === "BUTTON") levels.removeChild(t.parentNode); +}) + +document.querySelector("#route_presets").addEventListener("change", function ({currentTarget: t}) { + if (levels.childElementCount <= 1 || confirm("Loading a preset will erase your current list. Continue?")) { + clearLevels(); + const preset = t.value; + for (let i = 0; i <= preset.length - 4; i += 4) appendLevel(preset.substr(i, 4)); + } + t.value = "" +}) + +document.querySelector("#route_clear").addEventListener("click", function () { + confirm("Do you really want to clear the list?") && clearLevels(); +}) + +{ + let selection; + + function selDragStart(e) { + selection = this; + e.dataTransfer.effectAllowed = "move"; + e.dataTransfer.setData("text/html", this.querySelector("select").value); + + this.classList.add("dragelement"); + } + + function selDragOver(e) { + if (e.preventDefault) { + e.preventDefault(); } - document.getElementById("changelog").innerHTML += "more ..."; - }; - } - xml.open("GET", file); - xml.send(); -} \ No newline at end of file + this.classList.add("dragover"); + e.dataTransfer.dropEffect = "move"; + + return false; + } + + function selDragLeave() { + this.classList.remove("dragover"); + } + + function selDragDrop(e) { + if (e.stopPropagation) { + e.stopPropagation(); + } + + if (selection != this) { + this.parentNode.removeChild(selection); + this.insertAdjacentHTML("afterend", template.outerHTML); + this.nextSibling.querySelector("select").value = e.dataTransfer.getData('text/html'); + this.nextSibling.draggable = true; + selSetHandlers(this.nextSibling); + } + + this.classList.remove("dragover"); + return false; + } + + function selDragEnd() { + this.classList.remove("dragelement"); + } + + function selSetHandlers(elem) { + elem.addEventListener('dragstart', selDragStart, false); + elem.addEventListener('dragover', selDragOver, false); + elem.addEventListener('dragleave', selDragLeave, false); + elem.addEventListener('drop', selDragDrop, false); + elem.addEventListener('dragend', selDragEnd, false); + } +} + +//Interface +function getFastCode() { + + const levelCodes = Array.prototype.map.call(levels.querySelectorAll("select"), s => s.value); + + levelCodes.pop(); + + if (!(document.getElementById("usefastcode").checked) || levelCodes.length <= 1) return false; + + let game = JSON.parse(atob(document.getElementById("route_levels").getAttribute("data-json"))); + const randomize = (document.getElementById("route_random").value === "yes"); + const levelWords = Math.ceil(levelCodes.length / 2); + const asm = []; + asm.push("48" + ("00000" + (levelWords + 1 << 2 | 1).toString(16).toUpperCase()).slice(-6)); // bl to the code + for (let i = 0; i < levelWords; ++i) { + asm.push(levelCodes[2 * i] + (levelCodes[2 * i + 1] || "0000")); + } + + //Timer compatibility + asm.push("3C80817F"); // lis r4, 0x817F + asm.push("38000000"); // li r0, 0 + asm.push("9004010C"); // stw r0, 0x010C(r4) + asm.push("38000001"); // li r0, 1 + asm.push("98040101"); // stb r0, 0x0101(r4) + + asm.push("881F0012"); // lbz r0, 0x12(r31) + + if (!randomize) { + asm.push("2C00000F"); // cmpwi r0, 15 + asm.push("40820010"); // bne- 0x10 + asm.push("38000000"); // li r0, 0 + asm.push("90040000"); // stw r0, 0(r4) + asm.push("4800002C"); // b 0x2C + } + + asm.push("2C000001"); // cmpwi r0, 1 + + if (randomize) { + asm.push("41810030"); // bgt- 0x30 + asm.push("7C6C42E6"); // mftbl r3 + asm.push("3880" + ("000" + (levelCodes.length * 2).toString(16).toUpperCase()).slice(-4)); // li r4, length + asm.push("7C032396"); // divwu r0, r3, r4 + asm.push("7C0021D6"); // mullw r0, r0, r4 + asm.push("7C601850"); // sub r3, r3, r0 + asm.push("5463003C"); // rlwinm r3, r3, 0, 0, 30 + } else { + asm.push("41810024"); // bgt- 0x24 + asm.push("80640000"); // lwz r3, 0(r4) + asm.push("38030002"); // addi r0, r3, 2 + asm.push("90040000"); // stw r0, 0(r4) + } + + asm.push("7C8802A6"); // mflr r4 + asm.push("7C641A2E"); // lhzx r3, r4, r3 + asm.push("B07F0012"); // sth r3, 0x12(r31) + asm.push("808D" + game.fmOffset); // lwz r4, TFlagManager::smInstance + asm.push("986400DF"); // stb r3, 0xDF(r4) + asm.push("807F0020"); // lwz r3, 0x20(r31) + + if (asm.length % 2 === 0) { + asm.push("60000000"); // nop + } + asm.push("00000000"); + + const geckoLines = asm.length / 2; + let gecko = "C2" + game.injectAddr + " " + ("0000000" + geckoLines.toString(16).toUpperCase()).slice(-8) + "\r\n"; + for (let i = 0; i < geckoLines; ++i) { + gecko += asm[2 * i] + " " + asm[2 * i + 1] + "\r\n"; + } + + let codes = gecko + + game.notext[document.getElementById("route_notext").value] + + game.nofmvs[document.getElementById("route_nofmvs").value]; + + return codes.replace(/[^0-9A-F]/g, ''); +} diff --git a/guide.html b/guide.html index 8110ea5..12e760a 100644 --- a/guide.html +++ b/guide.html @@ -2,21 +2,22 @@ + Guide -
+

How to install and use practice codes

This page is a simple guide to explain the recommended way to install practice codes on your Nintendo Wii.




diff --git a/index.html b/index.html index 1792251..9781c82 100644 --- a/index.html +++ b/index.html @@ -3,55 +3,251 @@ + - SMS GCT Generator + Super Mario Sunshine Practice Code Generator -
-
-
- -
    -
- - - -
+
+ +
+
+ + + + + + + + + + + + + + + + + +
+ Game Version: + + +
+ Stage Loader: + + +
+ File Format: + + +
+ +
+
+
+ +
    +
    -
    - - - - - - -
    Challonge - 2018 Super Mario Sunshine Any% Tournament
    - Signup deadline: February 14th -
    Challonge
    -
    -

    Mario Sunshine Cheatfile Generator

    -

    Authors: Psy & Milk

    -

    Last Updated: Jan 24, 2018

    -

    Description:

    +
    +
    +

    Stage Loader

    +
    + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + + +
    +
    +
    +
      +
    • +
      + + +
    • +
    +
    +
    + + +
    +
    +
    +