diff --git a/docs/css/frankenfirm.css b/docs/css/frankenfirm.css new file mode 100755 index 0000000..860b0ae --- /dev/null +++ b/docs/css/frankenfirm.css @@ -0,0 +1,261 @@ +body { + background-color: black; +} + +.logo img{ + margin-left: auto; + margin-right: auto; + width: 30%; + display: block; + padding-top: 4%; +} + +.text p { + margin-left: auto; + margin-right: auto; + margin-bottom: 0; + width: 30%; + text-align: center; + display: block; + padding-top: 4%; + padding-bottom: 0; +} +.text img { + margin-left: auto; + margin-right: auto; + width: 30%; + display: block; + padding-top: 0; +} + +.graphics img{ + position:fixed; + bottom:0px; + margin-left: auto; + margin-right: auto; + width: 100%; + z-index: -99; +} + +/*.downloads { + padding-top: 5%; +}*/ + +.hidden { + display: none; +} + +button.donate { + margin-top: 10px; + font-weight: 700; + font-size: 1.2rem; + word-spacing: 30px; + background-color: #FFFFFF; + text-align: center; + border:none; + letter-spacing: 1px; + margin-left: auto; + margin-right: auto; + display: flex; + justify-content: center; + width:240px; + color: black; + min-width: 200px; +} + +p { + font-family: 'PT Sans Caption', sans-serif; + color: white; +} +select { + font-family: 'PT Sans Caption', sans-serif; + text-transform: uppercase; + padding-top: 10px; + padding-right: 10px; + padding-bottom: 10px; + padding-left: 10px; + cursor: pointer; + border: solid 2px; + border-color: white; + background-color: rgba(0,0,0,0); + color: white; + margin: 0; +} +option { + font-family: 'PT Sans Caption', sans-serif; + text-transform: uppercase; + padding-top: 10px; + padding-right: 10px; + padding-bottom: 10px; + padding-left: 10px; + background-color: rgba(0,0,0,255); + color: white; +} +button { + font-family: 'PT Sans Caption', sans-serif; + text-transform: uppercase; + padding-top: 10px; + padding-right: 30px; + padding-bottom: 10px; + padding-left: 30px; + cursor: pointer; +} + +.btn-group.error { + margin-left: auto; + margin-right: auto; + text-align: center; + margin-top: 2%; +} + +.btn-group.firmware { + margin-left: auto; + margin-right: auto; + text-align: center; +} + +.btn-group.console { + margin-left: auto; + margin-right: auto; + text-align: center; +} + +.btn-group.forced { + pointer-events: none; +} + +button.group{ + border: solid 2px; + border-color: white; + background-color: rgba(0,0,0,0); + color: white; + margin: 0; +} +button.group:hover { + background-color: #333333; +} + +button.group.selected{ + background-color: #FFFFFF; + color: black; +} + +button#download{ + margin-top: 2% +} + +button#download.active{ + background-color: #FFFFFF; + color: black; +} + +button#download{ + font-weight: 700; + color: white; + font-size: 1.2rem; + background-color: rgba(0,0,0,0); + border:solid 2px; + border-color: white; + letter-spacing: 1px; + margin-left: auto; + margin-right: auto; + display: flex; + justify-content: center; + width:280px; + text-align: center; + min-width: 200px; + height: 45px; +} + +.round { + border-radius: 2px; +} + +@media only screen and (max-width: 1024px) and (-webkit-min-device-pixel-ratio: 3) { + .logo img{ + margin-left: auto; + margin-right: auto; + width: 80%; + display: block; + padding-top: 4%; + } + + .text img { + margin-left: auto; + margin-right: auto; + width: 80%; + display: block; + padding-top: 5%; + } + + .graphics img{ + position:fixed; + bottom:0px; + margin-left: auto; + margin-right: auto; + width: 100%; + z-index: -99; + } + p { + font-size: 50px; + } + + button { + font-family: 'PT Sans Caption', sans-serif; + text-transform: uppercase; + font-size: 50px; + padding-top: 20px; + padding-right: 40px; + padding-bottom: 20px; + padding-left: 40px; + } + button.group{ + border: solid 5px; + border-color: white; + background-color: rgba(0,0,0,0); + color: white; + margin: 0; + } + div.downloads { + margin-top: 15% + } + + button#download{ + padding-top: 20px; + padding-right: 40px; + padding-bottom: 70px; + padding-left: 40px; + font-weight: 700; + color: white; + font-size: 50px; + background-color: rgba(0,0,0,0); + border:solid 5px; + border-color: white; + margin-left: 20%; + margin-right: 20%; + display: flex; + justify-content: center; + width:60%; + text-align: center; + } + button#download.active{ + background-color: #FFFFFF; + color: black; + } + button.donate { + margin-top: 30px; + font-weight: 700; + font-size: 50px; + word-spacing: 30px; + background-color: #FFFFFF; + text-align: center; + border:none; + letter-spacing: 1px; + margin-left: auto; + margin-right: auto; + display: flex; + justify-content: center; + width: 60%; + color: black; + } +} diff --git a/docs/frankenfirm.html b/docs/frankenfirm.html new file mode 100755 index 0000000..7530623 --- /dev/null +++ b/docs/frankenfirm.html @@ -0,0 +1,168 @@ + + + + + + + SoundHax - Frankenfirm | Nintendo Hacking 2016-2020 + + + + + + + + + + + + + +

FRANKENFIRM/CARTUPDATED

+ soundhax text +
+ + +
+

+ Choose error from running normal soundhax:
+ Don't choose if you haven't tried yet +

+ + +
+
+

Input your full system version:

+ ..- +
+
+

Choose a console:

+ + +
+ + + +
+ + + bottom graphics + + + + + + diff --git a/docs/js/frankenfirm.js b/docs/js/frankenfirm.js new file mode 100755 index 0000000..9733315 --- /dev/null +++ b/docs/js/frankenfirm.js @@ -0,0 +1,268 @@ +/* http://stackoverflow.com/a/5077091 */ +String.prototype.format = function () { + var args = arguments; + return this.replace(/\{(\d+)\}/g, function (m, n) { return args[n]; }); +}; + +var ERR_INVALID_INPUT = 0; +var ERR_NOT_SUPPORTED = 1; +var ERR_USE_NORMAL_FIRST = 2; +var ERR_LIKELY_WRONG_NORMAL = 3; + +var ERRS_USE_NORMAL = [ERR_USE_NORMAL_FIRST, ERR_LIKELY_WRONG_NORMAL]; + +function checkDownloadable() { + var href = checkSelection(); + console.log("check result", href) + if (ERRS_USE_NORMAL.includes(href)) { + $('#download').text("Normal Soundhax"); + } else if (href === ERR_INVALID_INPUT) { + $('#download').text("Invalid Input"); + } else if (href === ERR_NOT_SUPPORTED) { + $('#download').text("Not Supported"); + } else { + $('#download').text("Download M4A"); + } + if (typeof href === "string" || ERRS_USE_NORMAL.includes(href)) { + $('#download').addClass('active'); + } else { + $('#download').removeClass('active'); + } +} + +$('button.group').on('click', function() { + if ($(this).parent().hasClass('forced')) { + return; + } + if ($(this).hasClass('selected')) { + $(this).removeClass('selected'); + } else { + $(this).siblings().removeClass('selected'); + $(this).addClass('selected'); + } + + checkDownloadable(); +}); + +$('select').on('change', function() { + checkDownloadable(); +}); + +function regionFN(region) { + switch (region) { + case "E": + return "eur"; + case "U": + return "usa"; + case "J": + return "jpn"; + case "K": + return "kor"; + case "C": + return "chn"; + case "T": + return "twn"; + } +} + +function updateConsoleSelector(region, show) { + if (["C", "T"].includes(region)) { + show = false; + } + if (show) { + $('.console').show(); + } else { + $('.console').hide(); + if (!$('.console').hasClass("forced")) { + $('.console').children().removeClass('selected'); + } + } +} + +function checkSelection() { + // Possible max minor for each major, major as key + var major_minor_map = { + 0: -1, // invalidate all 0.x + 1: 1, + 2: 2, + 3: 1, + 4: 5, + 5: 1, + 6: 4, + 7: 2, + 8: 1, + 9: 9, + 10: 7, + 11: 17 + }; + + var error = $('.error').children('.selected').attr('id'); + var console_ = $('.console').children('.selected').attr('id'); + var major = parseInt($('#major').val()); + var minor = parseInt($('#minor').val()); + var nver = parseInt($('#nver').val()); + var region = $('#region').val(); + + updateConsoleSelector(region, major >= 8); + + if (major == 11 && minor == 17 && ["K", "C", "T"].includes(region)) { + return ERR_INVALID_INPUT; + } + + var minor_max = major_minor_map[major]; + if (!isNaN(minor_max) && minor > minor_max) { + return ERR_INVALID_INPUT; + } + + if (console_ === "n3ds") { + return ERR_USE_NORMAL_FIRST; + } + + if (["K", "C", "T"].includes(region)) { + return ERR_USE_NORMAL_FIRST; + } + + switch (nver) { + case 0: + case 1: + case 2: + case 3: + console.log("nver 0-3") + if (major < 2 || (major == 2 && minor <= 1)) { + switch (error) { + case "unplayable": + // very unlikely to have v1027 sound app in this case? + return "soundhax-{0}-{1}.m4a".format(regionFN(region), "o3ds-pre2.1"); + case "crash": + return ERR_INVALID_INPUT; // WTF + default: + return ERR_USE_NORMAL_FIRST; + } + } else if (major < 5) { + switch (error) { + case "unplayable": + return "soundhax-{0}-{1}.m4a".format(regionFN(region), "o3ds-pre2.1"); + case "crash": + return "soundhax-{0}-{1}.m4a".format(regionFN(region), "o3ds-v2.1and2.2"); + default: + return ERR_USE_NORMAL_FIRST; + } + } else if (major < 11 || (major == 11 && minor <= 3)) { + switch (error) { + case "unplayable": + return "soundhax-{0}-{1}.m4a".format(regionFN(region), "o3ds-pre2.1-post5franken"); + case "crash": + return "soundhax-{0}-{1}.m4a".format(regionFN(region), "o3ds-v2.1and2.2-post5franken"); + default: + return ERR_USE_NORMAL_FIRST; + } + } else if ((major == 11 && minor > 3) || major > 11) { + return ERR_NOT_SUPPORTED; + } + case 4: + console.log("nver 4") + if (major < 2 || (major == 2 && minor < 1)) { + return ERR_INVALID_INPUT; // WTF + } else if (major == 2 && minor == 1) { + switch (error) { + case "unplayable": + return "soundhax-{0}-{1}.m4a".format(regionFN(region), "o3ds-v2.1and2.2"); + case "crash": + return ERR_INVALID_INPUT; // WTF + default: + return ERR_USE_NORMAL_FIRST; + } + } else if (major < 5) { + switch (error) { + case "unplayable": + return ERR_LIKELY_WRONG_NORMAL; + case "crash": + return "soundhax-{0}-{1}.m4a".format(regionFN(region), "o3ds-v2.1and2.2"); + default: + return ERR_USE_NORMAL_FIRST; + } + } else if (major < 11 || (major == 11 && minor <= 3)) { + switch (error) { + case "unplayable": + return ERR_LIKELY_WRONG_NORMAL; + case "crash": + return "soundhax-{0}-{1}.m4a".format(regionFN(region), "o3ds-v2.1and2.2-post5franken"); + default: + return ERR_USE_NORMAL_FIRST; + } + } else if ((major == 11 && minor > 3) || major > 11) { + return ERR_NOT_SUPPORTED; + } + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + console.log("nver 5-10"); + if (major < 5) { + switch (error) { + case "unplayable": + case "crash": + return ERR_LIKELY_WRONG_NORMAL; + default: + return ERR_USE_NORMAL_FIRST; + } + } else if (major < 11 || (major == 11 && minor <= 3)) { + switch (error) { + case "unplayable": + case "crash": + return ERR_LIKELY_WRONG_NORMAL; + default: + return ERR_USE_NORMAL_FIRST; + } + } else if ((major == 11 && minor > 3) || major > 11) { + return ERR_NOT_SUPPORTED; + } + default: + if (nver < 37) { + console.log("nver 11-36"); + switch (error) { + case "unplayable": + case "crash": + return ERR_NOT_SUPPORTED; + default: + return "soundhax-{0}-{1}.m4a".format(regionFN(region), "o3ds-post5.0"); + } + } else { + console.log("nver 37+"); + return ERR_NOT_SUPPORTED; + } + } +} +checkDownloadable(); + +$('#download').on('click', function() { + if (!$(this).hasClass('active')) { + return; + } + + var href = checkSelection(); + if (ERRS_USE_NORMAL.includes(href)) { + if (href === ERR_LIKELY_WRONG_NORMAL) { + alert("You likely chosed wrong file previously in normal soundhax, make sure you select it correctly and try again."); + } + //window.location.href = "index.html"; + window.location.href = "http://soundhax.com"; + } else if (typeof href === "string") { + var base = "https://github.com/danny8376/soundhax/raw/frankenfirmware/"; + window.location.href = base + href; + } +}); + +function forceOptionSelected(id) { + $('#' + id).trigger("click"); + $('#' + id).parent().addClass("forced"); + //$('#' + id).parent().hide(); +} + +$.each(["unplayable", "crash"], function(idx, opt) { + if (location.search.includes(opt)) { + forceOptionSelected(opt); + } +}); diff --git a/exp.py b/exp.py index b8e8527..cd6a6f2 100644 --- a/exp.py +++ b/exp.py @@ -9,6 +9,7 @@ REGION = "usa" TYPE = "old" FIRM = "post5" +POST5FRANKEN = False if len(sys.argv) > 1: REGION = sys.argv[1].lower() @@ -18,6 +19,9 @@ if len(sys.argv) > 3: FIRM = sys.argv[3].lower() +if len(sys.argv) > 4: + POST5FRANKEN = sys.argv[4].lower() == "true" + # Check for impossible combinations if TYPE not in ("old", "new"): print("Error: invalid console type: {}".format(TYPE)) @@ -31,6 +35,9 @@ if FIRM in ("pre21", "v21and22") and REGION not in ("usa", "eur", "jpn"): print("Error: {} can only be used for USA/EUR/JPN regions".format(FIRM)) sys.exit(1) +if FIRM in ("v3xand4x", "post5") and POST5FRANKEN: + print("Error: use normal \"post5\", no need for franken build") + sys.exit(1) constants = { "pre21": constants_pre_21, @@ -112,7 +119,7 @@ def code_va_to_pa(va): off = va - 0x00100000 appmem_end = 0x24000000 if TYPE == "old" else 0x27C00000 - if FIRM == "post5" or TYPE == "new": + if FIRM == "post5" or TYPE == "new" or POST5FRANKEN: return appmem_end - 0x00200000 + off else: return appmem_end - code_image_size + off @@ -272,9 +279,15 @@ def internal(tree): else: assert TYPE == "old" if FIRM == "pre21": - fn = './soundhax-{}-{}-{}.m4a'.format(REGION, "o3ds", "pre2.1") + if POST5FRANKEN: + fn = './soundhax-{}-{}-{}-post5franken.m4a'.format(REGION, "o3ds", "pre2.1") + else: + fn = './soundhax-{}-{}-{}.m4a'.format(REGION, "o3ds", "pre2.1") elif FIRM == "v21and22": - fn = './soundhax-{}-{}-{}.m4a'.format(REGION, "o3ds", "v2.1and2.2") + if POST5FRANKEN: + fn = './soundhax-{}-{}-{}-post5franken.m4a'.format(REGION, "o3ds", "v2.1and2.2") + else: + fn = './soundhax-{}-{}-{}.m4a'.format(REGION, "o3ds", "v2.1and2.2") elif FIRM == "v3xand4x": fn = './soundhax-{}-{}-{}.m4a'.format(REGION, "o3ds", "v3.xand4.x") else : diff --git a/generate_all.sh b/generate_all.sh index 57f8337..bc50511 100755 --- a/generate_all.sh +++ b/generate_all.sh @@ -3,33 +3,45 @@ # There is no New3DS model for CHN/TWN # N3DS (post5) -python exp.py usa new -python exp.py eur new -python exp.py jpn new -python exp.py kor new +python2 exp.py usa new +python2 exp.py eur new +python2 exp.py jpn new +python2 exp.py kor new # O3DS (post5) -python exp.py usa old post5 -python exp.py eur old post5 -python exp.py jpn old post5 -python exp.py kor old post5 -python exp.py chn old post5 -python exp.py twn old post5 +python2 exp.py usa old post5 +python2 exp.py eur old post5 +python2 exp.py jpn old post5 +python2 exp.py kor old post5 +python2 exp.py chn old post5 +python2 exp.py twn old post5 # O3DS (v3xand4x) -python exp.py usa old v3xand4x -python exp.py eur old v3xand4x -python exp.py jpn old v3xand4x -python exp.py kor old v3xand4x -python exp.py chn old v3xand4x -python exp.py twn old v3xand4x +python2 exp.py usa old v3xand4x +python2 exp.py eur old v3xand4x +python2 exp.py jpn old v3xand4x +python2 exp.py kor old v3xand4x +python2 exp.py chn old v3xand4x +python2 exp.py twn old v3xand4x # O3DS (v21and22) -python exp.py usa old v21and22 -python exp.py eur old v21and22 -python exp.py jpn old v21and22 +python2 exp.py usa old v21and22 +python2 exp.py eur old v21and22 +python2 exp.py jpn old v21and22 # O3DS (pre21) -python exp.py usa old pre21 -python exp.py eur old pre21 -python exp.py jpn old pre21 +python2 exp.py usa old pre21 +python2 exp.py eur old pre21 +python2 exp.py jpn old pre21 + +# ==== FRANKENFIRMWARE ==== + +# O3DS (v21and22) +python2 exp.py usa old v21and22 true +python2 exp.py eur old v21and22 true +python2 exp.py jpn old v21and22 true + +# O3DS (pre21) +python2 exp.py usa old pre21 true +python2 exp.py eur old pre21 true +python2 exp.py jpn old pre21 true diff --git a/soundhax-eur-o3ds-pre2.1-post5franken.m4a b/soundhax-eur-o3ds-pre2.1-post5franken.m4a new file mode 100644 index 0000000..3444852 Binary files /dev/null and b/soundhax-eur-o3ds-pre2.1-post5franken.m4a differ diff --git a/soundhax-eur-o3ds-v2.1and2.2-post5franken.m4a b/soundhax-eur-o3ds-v2.1and2.2-post5franken.m4a new file mode 100644 index 0000000..03a8f2b Binary files /dev/null and b/soundhax-eur-o3ds-v2.1and2.2-post5franken.m4a differ diff --git a/soundhax-jpn-o3ds-pre2.1-post5franken.m4a b/soundhax-jpn-o3ds-pre2.1-post5franken.m4a new file mode 100644 index 0000000..6b93534 Binary files /dev/null and b/soundhax-jpn-o3ds-pre2.1-post5franken.m4a differ diff --git a/soundhax-jpn-o3ds-v2.1and2.2-post5franken.m4a b/soundhax-jpn-o3ds-v2.1and2.2-post5franken.m4a new file mode 100644 index 0000000..0f7c173 Binary files /dev/null and b/soundhax-jpn-o3ds-v2.1and2.2-post5franken.m4a differ diff --git a/soundhax-usa-o3ds-pre2.1-post5franken.m4a b/soundhax-usa-o3ds-pre2.1-post5franken.m4a new file mode 100644 index 0000000..57fadb7 Binary files /dev/null and b/soundhax-usa-o3ds-pre2.1-post5franken.m4a differ diff --git a/soundhax-usa-o3ds-v2.1and2.2-post5franken.m4a b/soundhax-usa-o3ds-v2.1and2.2-post5franken.m4a new file mode 100644 index 0000000..8caf6c9 Binary files /dev/null and b/soundhax-usa-o3ds-v2.1and2.2-post5franken.m4a differ