From 918eb0eb50899dd2a16dec369e4e714e8544ffce Mon Sep 17 00:00:00 2001 From: sup39 Date: Fri, 11 Nov 2022 21:58:24 +0900 Subject: [PATCH] add GCI Loader; support GCI as download format (NTSC-J 1.0 only) --- Codes.xml | 57 ++++++++++++++ changelog.md | 4 + package.json | 82 ++++++++++---------- site/.vuepress/components/DownloadButton.vue | 32 ++++++++ site/.vuepress/components/codes/asm.js | 5 +- site/.vuepress/data/downloadFormats.json | 4 + site/.vuepress/i18n/de-CH.json | 3 +- site/.vuepress/i18n/en-US.json | 3 +- site/.vuepress/i18n/fr-FR.json | 3 +- site/.vuepress/i18n/ja-JP.json | 3 +- 10 files changed, 150 insertions(+), 46 deletions(-) diff --git a/Codes.xml b/Codes.xml index 9970bdc..b3afc78 100644 --- a/Codes.xml +++ b/Codes.xml @@ -4658,4 +4658,61 @@ 040eb024 60000000 + + misc + GCI Loader + sup39(サポミク) + 0.1 + Nov 11, 2022 + + Execute Gecko code loaded from GCI file. + ::: warning + You will need to reset the game if you hotplug your memory card + ::: + + + C21069F4 0000001C + 9421FFF0 7C0802A6 + BFC10008 7C9F2378 + 38800001 90010014 + 7C7E1B78 3D808010 + 618C7B50 7D8803A6 + 4E800021 2C030000 + 40820084 807E0000 + 48000009 67637400 + 7C8802A6 7FE5FB78 + 3D80800A 618C3CAC + 7D8803A6 4E800021 + 2C030000 40820058 + 38A00000 38C00000 + 60A5E000 3C80817F + 7FE3FB78 3D80800A + 618C4640 7D8803A6 + 4E800021 2C030000 + 40820018 3D20817F + 3D40534D 6129DFFC + 614A53FF 91490000 + 7FE3FB78 3D80800A + 618C3E24 7D8803A6 + 4E800021 80010014 + 7FE4FB78 7FC3F378 + 83E1000C 83C10008 + 38210010 3D808010 + 618C72F4 7D8803A6 + 4E800021 00000000 + C0000000 0000000C + 3CA0803E 88A56008 + 28050004 4D800020 + 3CA0534D 60A553FF + 3C608180 8003DFFC + 7C002840 4C820020 + 3CA000D0 60A5C0DE + 3C608180 8403B000 + 7C002840 4C820020 + 80030004 7C002840 + 4C820020 7C0F2214 + 9003FFFC 39E30008 + 7DE47850 4E800020 + + diff --git a/changelog.md b/changelog.md index 1887ad3..bbebe17 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,8 @@ # Changelog +## Nov 11, 2022 +- Add GCI Loader (NTSC-J 1.0 only) +- Support GCI as download format (NTSC-J 1.0 only) + ## Nov 9, 2022 ### Added 'Fast Piantissimo' To make Piantissimo go as fast as he will in a level, you need to beat him with an in-game time under 25 seconds and grab his Shine. Or you could just use this code. diff --git a/package.json b/package.json index 9b2ff76..36b5eca 100644 --- a/package.json +++ b/package.json @@ -1,41 +1,41 @@ -{ - "name": "gctgenerator", - "version": "3.0.1", - "description": "Super Mario Sunshine Practice File Generator", - "main": "index.js", - "authors": { - "name": "Matteias Collet", - "email": "matteias.collet@bluewin.ch" - }, - "repository": "https://github.com/BitPatty/gctGenerator/gctGenerator", - "scripts": { - "dev": "npm run codes:inject && npm run translations:compare && vuepress dev site", - "build": "node ./scripts/inject_codes.js && npm run translations:compare && vuepress build site", - "format": "prettier --write ./site/**/*{.md,.js,.json}", - "translations:compare": "node ./scripts/compare_translations.js", - "codes:inject": "node ./scripts/inject_codes.js && npm run format", - "codes:clean": "node ./scripts/clean_codes.js && npm run format", - "precommit": "npm run codes:clean && git add .", - "serve": "serve ./site/.vuepress/dist" - }, - "license": "Apache-2.0", - "devDependencies": { - "@sup39/markdown-it-attr": "1.2.2", - "@sup39/markdown-it-inline-tag": "1.0.1", - "@types/encoding-japanese": "^2.0.1", - "@vuepress/plugin-back-to-top": "1.9.7", - "@vuepress/plugin-medium-zoom": "1.9.7", - "encoding-japanese": "^2.0.0", - "jsdom": "20.0.2", - "pre-commit": "1.2.2", - "prettier": "2.7.1", - "serve": "14.1.1", - "vuepress": "1.9.7" - }, - "dependencies": { - "vuedraggable": "2.24.3" - }, - "pre-commit": [ - "precommit" - ] -} +{ + "name": "gctgenerator", + "version": "3.0.1", + "description": "Super Mario Sunshine Practice File Generator", + "main": "index.js", + "authors": { + "name": "Matteias Collet", + "email": "matteias.collet@bluewin.ch" + }, + "repository": "https://github.com/BitPatty/gctGenerator/gctGenerator", + "scripts": { + "dev": "npm run codes:inject && npm run translations:compare && vuepress dev site", + "build": "node ./scripts/inject_codes.js && npm run translations:compare && vuepress build site", + "format": "prettier --write ./site/**/*{.md,.js,.json}", + "translations:compare": "node ./scripts/compare_translations.js", + "codes:inject": "node ./scripts/inject_codes.js && npm run format", + "codes:clean": "node ./scripts/clean_codes.js && npm run format", + "precommit": "npm run codes:clean && git add .", + "serve": "serve ./site/.vuepress/dist" + }, + "license": "Apache-2.0", + "devDependencies": { + "@sup39/markdown-it-attr": "1.2.2", + "@sup39/markdown-it-inline-tag": "1.0.1", + "@types/encoding-japanese": "^2.0.1", + "@vuepress/plugin-back-to-top": "1.9.7", + "@vuepress/plugin-medium-zoom": "1.9.7", + "encoding-japanese": "^2.0.0", + "jsdom": "20.0.2", + "pre-commit": "1.2.2", + "prettier": "2.7.1", + "serve": "14.1.1", + "vuepress": "1.9.7" + }, + "dependencies": { + "vuedraggable": "2.24.3" + }, + "pre-commit": [ + "precommit" + ] +} diff --git a/site/.vuepress/components/DownloadButton.vue b/site/.vuepress/components/DownloadButton.vue index 36e1a08..f9629a5 100644 --- a/site/.vuepress/components/DownloadButton.vue +++ b/site/.vuepress/components/DownloadButton.vue @@ -86,6 +86,9 @@ export default { this.alertDolphinCodeSize(codeSize); this.generateCheatManagerTXT(c, fileName); break; + case 'gci': + this.generateGCI(c, fileName); + break; } }, alertGCTCodeSize(size) { @@ -144,6 +147,35 @@ export default { this.downloadFile(data, `${version}.txt`); }, + generateGCI(codes, version) { + if (!['GMSJ01'].includes(version)) { + alert('GCI format is not yet supported for versions other than GMSJ01'); + return; + } + let code = '00D0C0DE00D0C0DE'; + codes.forEach((c) => (code += c.source)); + code += 'F000000000000000'; + + const blockCount = 7; // TODO + const gciSize = 0x40+0x2000*blockCount; + const padSize = 0xB040; // TODO + let rawData = new Uint8Array(gciSize); + + for (let iD=padSize, iC=0; iD rawData[i] = e); + // file name + [...new TextEncoder().encode('gct')].forEach((e, i) => rawData[0x8+i] = e); + // block count + rawData[0x39] = blockCount; + // ff*6 + for (let i=0x3A; i<0x40; i++) rawData[i] = 0xff; + + this.downloadFile(rawData, `01-${version.slice(0, 4)}-gct.gci`); + }, downloadFile(data, filename) { var file = new Blob([data], { type: 'application/octet-stream', diff --git a/site/.vuepress/components/codes/asm.js b/site/.vuepress/components/codes/asm.js index 1d1b796..6117066 100644 --- a/site/.vuepress/components/codes/asm.js +++ b/site/.vuepress/components/codes/asm.js @@ -114,7 +114,10 @@ const makeInstXS = (op, op2) => (rA, rS, rB, Rc) => InstX(op, rA, rS, rB, op2, + /** @type {(op: number) => InstM} */ const makeInstM = (op) => (rA, rS, SH, MB, ME, Rc) => InstM(op, rA, rS, SH, MB, ME, +Rc); /** @type {(op: number) => InstI} */ -const makeInstI = (op) => (LL, LK, AA = 0) => InstI(op, LL >> 2, +AA, +LK); +const makeInstI = + (op) => + (LL, LK, AA = 0) => + InstI(op, LL >> 2, +AA, +LK); export const ASM = { // store rT, rA, D diff --git a/site/.vuepress/data/downloadFormats.json b/site/.vuepress/data/downloadFormats.json index f0b6504..d4e2507 100644 --- a/site/.vuepress/data/downloadFormats.json +++ b/site/.vuepress/data/downloadFormats.json @@ -10,5 +10,9 @@ { "target": "gcm", "i18nKey": "generatorconfig.downloadformat.options.gcm" + }, + { + "target": "gci", + "i18nKey": "generatorconfig.downloadformat.options.gci" } ] diff --git a/site/.vuepress/i18n/de-CH.json b/site/.vuepress/i18n/de-CH.json index a89d742..94c1a3d 100644 --- a/site/.vuepress/i18n/de-CH.json +++ b/site/.vuepress/i18n/de-CH.json @@ -44,7 +44,8 @@ "options": { "gct": "GCT", "dolphin": "Dolphin INI", - "gcm": "CheatManager TXT" + "gcm": "CheatManager TXT", + "gci": "GCI" } }, "categories": { diff --git a/site/.vuepress/i18n/en-US.json b/site/.vuepress/i18n/en-US.json index 81a767e..e5ed35f 100644 --- a/site/.vuepress/i18n/en-US.json +++ b/site/.vuepress/i18n/en-US.json @@ -44,7 +44,8 @@ "options": { "gct": "GCT", "dolphin": "Dolphin INI", - "gcm": "CheatManager TXT" + "gcm": "CheatManager TXT", + "gci": "GCI" } }, "alert": { diff --git a/site/.vuepress/i18n/fr-FR.json b/site/.vuepress/i18n/fr-FR.json index 3800f79..de03677 100644 --- a/site/.vuepress/i18n/fr-FR.json +++ b/site/.vuepress/i18n/fr-FR.json @@ -29,7 +29,8 @@ "options": { "gct": "GCT", "dolphin": "Dolphin INI", - "gcm": "CheatManager TXT" + "gcm": "CheatManager TXT", + "gci": "GCI" } } }, diff --git a/site/.vuepress/i18n/ja-JP.json b/site/.vuepress/i18n/ja-JP.json index 47727f0..f03d752 100644 --- a/site/.vuepress/i18n/ja-JP.json +++ b/site/.vuepress/i18n/ja-JP.json @@ -29,7 +29,8 @@ "options": { "gct": "GCT", "dolphin": "Dolphin INI", - "gcm": "CheatManager TXT" + "gcm": "CheatManager TXT", + "gci": "GCI" } }, "alert": {