Skip to content

Commit

Permalink
Merge pull request #129 from BitPatty/gci
Browse files Browse the repository at this point in the history
GCI support
  • Loading branch information
BitPatty authored Jul 31, 2024
2 parents d06ab94 + b365b60 commit 1c4bca4
Show file tree
Hide file tree
Showing 20 changed files with 1,021 additions and 13 deletions.
767 changes: 767 additions & 0 deletions Codes.xml

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Changelog

## Jul 31, 2024

Added GCT & GCI Download (Experimental).

## Oct 16, 2023
Added dependencies information to generated ini/txt

Expand Down
91 changes: 84 additions & 7 deletions site/.vuepress/components/DownloadButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,14 @@ export default {
source: this.stageLoaderCode,
});
const fileName = gameVersions.find((v) => v.identifier === this.versionIdentifier).version;
const version = gameVersions.find((v) => v.identifier === this.versionIdentifier).version;
// save download code list to local storage for retrieval (last downloaded)
try {
const codeTitles = codeList.map(c => c.title.find(o => o.lang === 'en-US').content);
localStorage.setItem(lskeyLDC, JSON.stringify(codeTitles));
} catch {}
// apply customizable codes
for (const code of codeList) {
Expand All @@ -88,21 +95,58 @@ export default {
}
}
let format;
const formats = this.format.split('+');
if (formats[0] === 'gci') {
format = formats[1];
const codeListGCT = [];
const codeListGCI = codeList.splice(0).flatMap(c => {
// TODO
if (c.id === 'IntroSkip' || c.category === 'memcardpatch') {
codeListGCT.push(c);
return [];
}
return c;
});
// download GCI Loader + GCT only code as remaining format
const {codes} = gameVersions.find((v) => v.identifier === this.versionIdentifier);
const gciLoader = codes.find(code => code.id === 'GCILoader');
codeList.push({
...gciLoader,
title: translateCode(gciLoader, this.$lang).title,
}, ...codeListGCT);
if (!format && codeListGCT.length) {
const list = codeListGCT.map(c => (
c.title.find(o => o.lang === this.$lang) ??
c.title.find(o => o.lang === 'en-US')
).content).join(', ');
alert(translate('generatorconfig.alert.gci-compatibility', this.$lang)+list);
}
// download GCI file
if (codeListGCI.length) {
this.generateGCI(codeListGCI, version);
}
} else {
format = formats[0];
}
// 16 = 8(00D0C0DE 00D0C0DE) + 8(F0000000 00000000)
const codeSize = codeList.reduce((a, e) => a + e.source.length, 0) / 2 + 16;
// generate file
const codeSize = codeList.reduce((a, e) => a + e.source.length, 0) / 2 + 16; // 8(00D0)+8(F000)
// console.log(codeSize, codeList);
switch (this.format) {
switch (format) {
case 'gct':
this.alertGCTCodeSize(codeSize);
this.generateGCT(codeList, fileName);
this.generateGCT(codeList, version);
break;
case 'dolphin':
this.alertDolphinCodeSize(codeSize);
this.generateDolphinINI(codeList, fileName);
this.generateDolphinINI(codeList, version);
break;
case 'gcm':
this.alertDolphinCodeSize(codeSize);
this.generateCheatManagerTXT(codeList, fileName);
this.generateCheatManagerTXT(codeList, version);
break;
}
},
Expand All @@ -120,6 +164,11 @@ export default {
);
}
},
getGCILoader() {
const {codes} = gameVersions.find((v) => v.identifier === this.versionIdentifier);
const code = codes.find(code => code.id === 'GCILoader');
return [code];
},
generateGCT(codes, version) {
let code = '00D0C0DE00D0C0DE';
codes.forEach((c) => (code += c.source));
Expand Down Expand Up @@ -162,6 +211,34 @@ export default {
this.downloadFile(data, `${version}.txt`);
},
generateGCI(codes, version) {
let code = '';
codes.forEach((c) => (code += c.source));
code += 'C0000000000000023C60817F81E317FC7DE478504E800020'; // return
// const codeSize = code.length>>1;
const fileName = `GCT_${this.versionIdentifier}`; // GMSJ0A
const blockCount = 6; // Math.ceil(codeSize/0x2000); // TODO
const headSize = 0x40;
const gciSize = headSize+0x2000*blockCount;
const rawData = new Uint8Array(gciSize);
for (let iD=headSize, iC=0; iC<code.length; iD++, iC+=2) {
rawData[iD] = parseInt(code.slice(iC, iC+2), 16);
}
// game id
[...new TextEncoder().encode(version), 0xff, 0x00].forEach((e, i) => rawData[i] = e);
// file name
[...new TextEncoder().encode(fileName)].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)}-${fileName}.gci`);
},
downloadFile(data, filename) {
var file = new Blob([data], {
type: 'application/octet-stream',
Expand Down
16 changes: 16 additions & 0 deletions site/.vuepress/data/downloadFormats.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,21 @@
{
"target": "gcm",
"i18nKey": "generatorconfig.downloadformat.options.gcm"
},
{
"target": "gci+gct",
"i18nKey": "generatorconfig.downloadformat.options.gci+gct"
},
{
"target": "gci+dolphin",
"i18nKey": "generatorconfig.downloadformat.options.gci+dolphin"
},
{
"target": "gci+gcm",
"i18nKey": "generatorconfig.downloadformat.options.gci+gcm"
},
{
"target": "gci",
"i18nKey": "generatorconfig.downloadformat.options.gci"
}
]
6 changes: 5 additions & 1 deletion site/.vuepress/i18n/de-CH.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@
"options": {
"gct": "GCT",
"dolphin": "Dolphin INI",
"gcm": "CheatManager TXT"
"gcm": "CheatManager TXT",
"gci+gct": "GCI + GCT (Experimental)",
"gci+dolphin": "GCI + Dolphin INI",
"gci+gcm": "GCI + CheatManager TXT",
"gci": "GCI"
}
},
"categories": {
Expand Down
9 changes: 7 additions & 2 deletions site/.vuepress/i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,17 @@
"options": {
"gct": "GCT",
"dolphin": "Dolphin INI",
"gcm": "CheatManager TXT"
"gcm": "CheatManager TXT",
"gci+gct": "GCI + GCT (Experimental)",
"gci+dolphin": "GCI + Dolphin INI",
"gci+gcm": "GCI + CheatManager TXT",
"gci": "GCI"
}
},
"alert": {
"gct": "The generated GCT file size exceeds 5000 bytes ({size} bytes). All of the codes may not work when using this file on Nintendont.",
"dolphin": "The total code size exceeds 3256 bytes ({size} bytes). All of the codes may not work when all of them are enabled on Dolphin. Try to disable some codes in that case."
"dolphin": "The total code size exceeds 3256 bytes ({size} bytes). All of the codes may not work when all of them are enabled on Dolphin. Try to disable some codes in that case.",
"gci-compatibility": "The following code is not included in the GCI file due to incompatibility: "
},
"categories": {
"qol": "Quality of Life",
Expand Down
6 changes: 5 additions & 1 deletion site/.vuepress/i18n/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@
"options": {
"gct": "GCT",
"dolphin": "Dolphin INI",
"gcm": "CheatManager TXT"
"gcm": "CheatManager TXT",
"gci+gct": "GCI + GCT (Experimental)",
"gci+dolphin": "GCI + Dolphin INI",
"gci+gcm": "GCI + CheatManager TXT",
"gci": "GCI"
}
}
},
Expand Down
9 changes: 7 additions & 2 deletions site/.vuepress/i18n/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@
"options": {
"gct": "GCT",
"dolphin": "Dolphin INI",
"gcm": "CheatManager TXT"
"gcm": "CheatManager TXT",
"gci+gct": "GCI + GCT (Experimental)",
"gci+dolphin": "GCI + Dolphin INI",
"gci+gcm": "GCI + CheatManager TXT",
"gci": "GCI"
}
},
"presets": {
Expand All @@ -42,7 +46,8 @@
},
"alert": {
"gct": "生成されたGCTファイルのサイズが5000バイトを超えました({size}バイト)。NintendontでこのGCTファイルを使う時、全ての機能が動作しなくなることがあるため、5000バイトを超えないようにいくつかの機能を減らすことをおすすめします。",
"dolphin": "コードの合計サイズが3256バイトを超えました({size}バイト)。Dolphinで全てのコードをONにすると、全ての機能が動作しなくなることがあります。その場合はいくつかのコードをOFFにしてください。"
"dolphin": "コードの合計サイズが3256バイトを超えました({size}バイト)。Dolphinで全てのコードをONにすると、全ての機能が動作しなくなることがあります。その場合はいくつかのコードをOFFにしてください。",
"gci-compatibility": "互換性がないため次のコードはGCIファイルに含まれません:"
}
},
"landingpage": {
Expand Down
Binary file added site/.vuepress/public/img/gci/0-gcmm-files.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added site/.vuepress/public/img/gci/1-cheat-files.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added site/.vuepress/public/img/gci/2-0-open-gcmm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added site/.vuepress/public/img/gci/2-5-complete.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 73 additions & 0 deletions site/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,76 @@ Right click the game in Dolphin and click on "Properties". In the "Game Config"
### Using the codes

Select the "Gecko-Codes" tab in the game properties and check all the codes you want to be active. Most (but not all codes) will work with Dolphin.

## Appendix: Using large cheat file with Nintendont

There is a file size limit of 5000 bytes in Nintendont.
To use cheat file with size larger than 5000 bytes,
you need to store the cheat file in your Gamecube memory card
and load it on runtime.

### Preparation: Installing GCMM

You need GCMM to store the cheat file to your Gamecube memory card.
[Download the latest GCMM release](https://github.com/suloku/gcmm/releases/download/1.4f/gcmm_1.4f.zip) and unzip it.
Copy the `apps/gcmm` folder to `/apps/` folder in your SD card.

![File list after GCMM is installed](/img/gci/0-gcmm-files.jpg)

### [Step 1/3] Generating cheat file

Select the game version and the functions you want in [GCT Generator](/).
Choose `GCI + GCT` as Download Format and press the download button.

There will be 2 files being downloaded.
Put the first file (GCI) in `/MCBACKUP/` folder
and the second file (GCT) in `/codes/` folder in your SD card.
Create the folders if they do not exist.

![File list after downloading the cheat files](/img/gci/1-cheat-files.jpg)

### [Step 2/3] Write the GCI file to Gamecube memory card with GCMM

Open your Homebrew channel and run GCMM.

![Run GCMM in Homebrew channel](/img/gci/2-0-open-gcmm.png)

Press A if you are using SD card, or B if you are using USB.

![Choose device](/img/gci/2-1-choose-device.png)

Press X (Restore) in mode selection.

![Choose mode](/img/gci/2-2-choose-mode.png)

Put your Gamecube memory card in slot A and press A.
Press B instead if you put it in slot B.

![Choose slot](/img/gci/2-3-choose-slot.png)

Use D-Pad to select the downloaded GCI file,
and then press A to restore the file to your Gamecube memory card.

![Choose file](/img/gci/2-4-choose-file.png)

After the message "Restore Complete" appears,
press A to return to the main menu,
and then press Start to return to Homebrew.

![Restore Complete](/img/gci/2-5-complete.png)

#### For the second time and onwards

There will be a message to confirm
whether you want to overwrite the file since the second time.
Press B and then Z to overwrite.

![Overwrite confirm 1](/img/gci/2-6-overwrite-1.png)
![Overwrite confirm 2](/img/gci/2-6-overwrite-2.png)

### [Step 3/3] Run the game with Nintendont

Run the game with Nintendont with your Gamecube memory card plugged in.
The GCI file stored in your memory card will be loaded automatically.
You can remove your memory card
after confirming the functions you selected work.
52 changes: 52 additions & 0 deletions site/ja/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,56 @@ Dolphinを起動し、「Option」->「Configuration」から「Settings」を
### チートコードの使い方

ゲームのプロパティで「Gecko-Codes」タブを選択し、有効にしたい全てのコードにチェックを入れてください。Dolphinにおいても、ほとんどのチートコードが動作します。(全てのチートコードが動作するわけではないので注意)


## 付録:大きなチートファイルをNintendontで使うためには
Nintendontには5000バイトのファイルサイズ制限があります。5000バイト超えのチートファイルを使うためには、チートファイルをGCメモリカードに保存してゲーム実行時にGCメモリカードから読み込む必要があります。

### 準備:GCMMのインストール
チートファイルをGCメモリカードに書き込むためにはGCMMを使います。[最新版のGCMM](https://github.com/suloku/gcmm/releases/download/1.4f/gcmm_1.4f.zip)をダウンロードして解凍します。その中にある`apps/gcmm`フォルダをSDカードの`/apps/`フォルダにコピーします。

![GCMMをインストールした後のファイル一覧](/img/gci/0-gcmm-files.jpg)

### [ステップ 1/3] チートファイルの作成
[GCT Generator](/ja/)でゲームバージョンと入れたい機能を選択し、ダウンロードフォーマットを`GCI + GCT`にしてダウンロードボタンを押します。

二つのファイルがダウンロードされますが、一つ目のGCIファイルをSDカードの`/MCBACKUP/`フォルダに、二つ目のGCTファイルを`/codes/`フォルダにダウンロードします。上記のフォルダが存在しない場合は作成してください。

![チートファイルをダウンロードした後のファイル一覧](/img/gci/1-cheat-files.jpg)

### [ステップ 2/3] GCMMでGCIファイルをGCメモリカードに書き込む
WiiでHomebrewチャンネルを開いてGCMMを起動します。

![HomebrewチャンネルでGCMMを起動](/img/gci/2-0-open-gcmm.png)

SDカードを使っているのであればAボタン、USBを使っているのであればBボタンを押します。

![デバイス選択](/img/gci/2-1-choose-device.png)

モード選択では「Xボタン」(Restore)を押します。

![モード選択](/img/gci/2-2-choose-mode.png)

GCメモリカードをスロットAに挿して「Aボタン」を押します。スロットBに挿した場合はBボタンを押します。

![スロット選択](/img/gci/2-3-choose-slot.png)

十字キーでダウンロードしたGCIファイルを選択し、「Aボタン」を押してGCIファイルをGCメモリカードに書き込みます。

![ファイル選択](/img/gci/2-4-choose-file.png)

「Restore Complete」というメッセージが出たら成功です。「Aボタン」を押してメニュー画面に戻って「スタートボタン」を押してHomebrewに戻ります。

![完成](/img/gci/2-5-complete.png)

#### 二回目以降の書き込み
二回目以降GCIファイルを書き込む際に「ファイルを上書きしますか」という確認するメッセージが出てきます。「Bボタン」そして「Zボタン」を押して上書きします。

![上書き確認1](/img/gci/2-6-overwrite-1.png)
![上書き確認2](/img/gci/2-6-overwrite-2.png)

### [ステップ 3/3] Nintendontでゲームを起動
GCメモリカードを挿したままNintendontでゲームを起動します。GCメモリカードに保存したGCIファイルは自動的に読み込まれます。入れた機能が動作することを確認できたらメモリカードを取り外しても構いません。


<!-- prettier-ignore-end -->

0 comments on commit 1c4bca4

Please sign in to comment.