Merge remote-tracking branch 'gct/master' into gci

This commit is contained in:
sup39 2023-02-11 02:17:04 +09:00
commit ac637e0712
14 changed files with 2547 additions and 2196 deletions

706
Codes.xml
View file

@ -1234,15 +1234,17 @@
<code> <code>
<id>qft</id> <id>qft</id>
<category>timer</category> <category>timer</category>
<title lang="en-US">Quarterframe Timer (Experimental)</title> <title lang="en-US">Quarterframe Timer</title>
<title lang="ja-JP">QFタイマー</title> <title lang="ja-JP">QFタイマー</title>
<author>Noki Doki, sup39(サポミク)</author> <author>Noki Doki, sup39(サポミク)</author>
<version>1.2</version> <version>1.4</version>
<date>Oct 16, 2022</date> <date>Dec 16, 2022</date>
<dependencies version="GMSJ01">drawText</dependencies> <dependencies version="GMSJ01">drawText</dependencies>
<dependencies version="GMSE01">drawText</dependencies>
<dependencies version="GMSP01">drawText</dependencies>
<dependencies version="GMSJ0A">drawText</dependencies> <dependencies version="GMSJ0A">drawText</dependencies>
<description lang="en-US"> <description lang="en-US">
Adds an in-game timer to every level, starting on the last black frame after the Adds an in-game timer to every level, starting on the last black frame of the
loading screen and ending as soon as the 'Shine Get' animation starts loading screen and ending as soon as the 'Shine Get' animation starts
(similar to the x-cam timer of SM64). (similar to the x-cam timer of SM64).
@ -1251,46 +1253,45 @@
::: :::
</description> </description>
<source version="GMSJ01"> <source version="GMSJ01">
C20ECE44 0000000B C20ECE44 00000006
981A0260 3CE0817F 981A0260 3CE0817F
880700B3 2C000000 880700B3 2C000000
38800000 908700BC 38000000 900700BC
41820010 B08700B2 41820010 B00700B2
3800FFFC 900700B4 3800FFFC 900700B4
60E30110 60E50094 60000000 00000000
80CD97F8 80C60048 C2206738 0000001F
60E700A4 39000002 3C60817F 6064011C
39200000 3D808001 38630094 3D808020
618C9904 7D8803A6 398C1EA8 7D8803A6
4E800021 00000000 4E800021 3C60817F
C2206738 0000001B 888300B2 810300B4
3C60817F 888300B2 2C040000 40A20030
810300B4 2C040000 808300BC 2C040000
40A20030 808300BC 40A20010 810D97E8
2C040000 40A20010 8108005C 48000010
810D97E8 8108005C 3884FFFF 908300BC
48000010 3884FFFF 810300B8 800300B4
908300BC 810300B8 7D080214 3CE0000A
800300B4 7D080214 60E7F9B0 7C074000
3CE0000A 60E7F9B0 40A00010 7CE83B78
7C074000 40A00010 98E300B2 90E300B4
7CE83B78 98E300B2 1D0803E9 38000078
90E300B4 1D0803E9 7D080396 9421FFF0
38000078 7D080396
380003E8 7CE80396 380003E8 7CE80396
7C0701D6 7D004050 7C0701D6 7D004050
3800003C 7CC70396 91010008 3800003C
7C0601D6 7CE03850 7D270396 7C0901D6
38A300A4 3880000F 7D403850 80E30118
80630210 4CC63182 390300A4 80C30114
3D808008 618C40C4 3D80817F 80A30110
7D8803A6 4E800021 618C0238 808300A0
3C60817F 60630110 7D8803A6 80630094
38800000 38A00000 4E800021 38210010
38C10E90 38E00081 38610E90 3D808003
3D808001 618C8E64 398C5228 7D8803A6
7D8803A6 4E800021 4E800021 881F0046
881F0046 00000000 60000000 00000000
C20EFA30 00000005 C20EFA30 00000005
3CA0817F A00500B2 3CA0817F A00500B2
2C000000 40820014 2C000000 40820014
@ -1327,64 +1328,47 @@
5400003A 900500B8 5400003A 900500B8
3800FFFF 900500BC 3800FFFF 900500BC
60000000 00000000 60000000 00000000
C2196314 00000004
80AD97E8 8005005C
3CA0817F 900500B8
3800001E 900500BC
38A00000 00000000
C2196128 00000005
7C030378 80A3005C
38A50003 54A0003A
3CA0817F 900500B8
3800001E 900500BC
60000000 00000000
077F0094 0000001D
00000010 000001A0
00000280 000001E0
25753A25 3032752E
25303375 00000000
</source> </source>
<source version="GMSE01"> <source version="GMSE01">
C22998C0 0000000B C22998C0 00000006
981A0260 3CE0817F 981A0260 3CE0817F
880700B3 2C000000 880700B3 2C000000
38800000 908700BC 38000000 900700BC
41820010 B08700B2 41820010 B00700B2
3800FFFC 900700B4 3800FFFC 900700B4
60E30110 60E50094 60000000 00000000
80CD9FC8 80C60048 C2143F18 0000001F
60E700A4 39000002 3C60817F 6064011C
39200000 3D80802D 38630094 3D808014
618C0848 7D8803A6 398C0390 7D8803A6
4E800021 00000000 4E800021 3C60817F
C2143F18 0000001B 888300B2 810300B4
3C60817F 888300B2 2C040000 40A20030
810300B4 2C040000 808300BC 2C040000
40A20030 808300BC 40A20010 810D9FB8
2C040000 40A20010 8108005C 48000010
810D9FB8 8108005C 3884FFFF 908300BC
48000010 3884FFFF 810300B8 800300B4
908300BC 810300B8 7D080214 3CE0000A
800300B4 7D080214 60E7F9B0 7C074000
3CE0000A 60E7F9B0 40A00010 7CE83B78
7C074000 40A00010 98E300B2 90E300B4
7CE83B78 98E300B2 1D0803E9 38000078
90E300B4 1D0803E9 7D080396 9421FFF0
38000078 7D080396
380003E8 7CE80396 380003E8 7CE80396
7C0701D6 7D004050 7C0701D6 7D004050
3800003C 7CC70396 91010008 3800003C
7C0601D6 7CE03850 7D270396 7C0901D6
38A300A4 3880000F 7D403850 80E30118
80630210 4CC63182 390300A4 80C30114
3D808033 618C97A4 3D80817F 80A30110
7D8803A6 4E800021 618C0238 808300A0
3C60817F 60630110 7D8803A6 80630094
38800000 38A00000 4E800021 38210010
38C10BD0 38E00081 38610BD0 3D80802F
3D80802C 618CFDA8 398CB6BC 7D8803A6
7D8803A6 4E800021 4E800021 881F0046
881F0046 00000000 60000000 00000000
C229C520 00000005 C229C520 00000005
3CA0817F A00500B2 3CA0817F A00500B2
2C000000 40820014 2C000000 40820014
@ -1421,64 +1405,47 @@
5400003A 900500B8 5400003A 900500B8
3800FFFF 900500BC 3800FFFF 900500BC
60000000 00000000 60000000 00000000
077F0094 0000001D
00000010 000001A0
00000280 000001E0
25753A25 3032752E
25303375 00000000
C21BE474 00000004
80AD9FB8 8005005C
3CA0817F 900500B8
3800001E 900500BC
38A00000 00000000
C21BE288 00000005
7C030378 80A3005C
38A50003 54A0003A
3CA0817F 900500B8
3800001E 900500BC
60000000 00000000
</source> </source>
<source version="GMSP01"> <source version="GMSP01">
C2291758 0000000B C2291758 00000006
981A0260 3CE0817F 981A0260 3CE0817F
880700B3 2C000000 880700B3 2C000000
38800000 908700BC 38000000 900700BC
41820010 B08700B2 41820010 B00700B2
3800FFFC 900700B4 3800FFFC 900700B4
60E30110 60E50094 60000000 00000000
80CD9EF0 80C60048 C2138B54 0000001F
60E700A4 39000002 3C60817F 6064011C
39200000 3D80802C 38630094 3D808013
618C89F0 7D8803A6 398C4F0C 7D8803A6
4E800021 00000000 4E800021 3C60817F
C2138B54 0000001B 888300B2 810300B4
3C60817F 888300B2 2C040000 40A20030
810300B4 2C040000 808300BC 2C040000
40A20030 808300BC 40A20010 810D9EE0
2C040000 40A20010 8108005C 48000010
810D9EE0 8108005C 3884FFFF 908300BC
48000010 3884FFFF 810300B8 800300B4
908300BC 810300B8 7D080214 3CE0000A
800300B4 7D080214 60E7F9B0 7C074000
3CE0000A 60E7F9B0 40A00010 7CE83B78
7C074000 40A00010 98E300B2 90E300B4
7CE83B78 98E300B2 1D0803E9 38000078
90E300B4 1D0803E9 7D080396 9421FFF0
38000078 7D080396
380003E8 7CE80396 380003E8 7CE80396
7C0701D6 7D004050 7C0701D6 7D004050
3800003C 7CC70396 91010008 3800003C
7C0601D6 7CE03850 7D270396 7C0901D6
38A300A4 3880000F 7D403850 80E30118
80630210 4CC63182 390300A4 80C30114
3D808033 618C1924 3D80817F 80A30110
7D8803A6 4E800021 618C0238 808300A0
3C60817F 60630110 7D8803A6 80630094
38800000 38A00000 4E800021 38210010
38C10BE4 38E00081 38610BE4 3D80802E
3D80802C 618C7F50 398C3864 7D8803A6
7D8803A6 4E800021 4E800021 881F0046
881F0046 00000000 60000000 00000000
C22943FC 00000005 C22943FC 00000005
3CA0817F A00500B2 3CA0817F A00500B2
2C000000 40820014 2C000000 40820014
@ -1515,64 +1482,47 @@
5400003A 900500B8 5400003A 900500B8
3800FFFF 900500BC 3800FFFF 900500BC
60000000 00000000 60000000 00000000
077F0094 0000001D
00000010 000001A0
00000280 000001E0
25753A25 3032752E
25303375 00000000
C21B632C 00000004
80AD9EE0 8005005C
3CA0817F 900500B8
3800001E 900500BC
38A00000 00000000
C21B6140 00000005
7C030378 80A3005C
38A50003 54A0003A
3CA0817F 900500B8
3800001E 900500BC
60000000 00000000
</source> </source>
<source version="GMSJ0A"> <source version="GMSJ0A">
C2279570 0000000B C2279570 00000006
981A0260 3CE0817F 981A0260 3CE0817F
880700B3 2C000000 880700B3 2C000000
38800000 908700BC 38000000 900700BC
41820010 B08700B2 41820010 B00700B2
3800FFFC 900700B4 3800FFFC 900700B4
60E30110 60E50094 60000000 00000000
80CD9E88 80C60048 C21252A4 0000001F
60E700A4 39000002 3C60817F 6064011C
39200000 3D80802B 38630094 3D808012
618C0058 7D8803A6 398C1660 7D8803A6
4E800021 00000000 4E800021 3C60817F
C21252A4 0000001B 888300B2 810300B4
3C60817F 888300B2 2C040000 40A20030
810300B4 2C040000 808300BC 2C040000
40A20030 808300BC 40A20010 810D9E78
2C040000 40A20010 8108005C 48000010
810D9E78 8108005C 3884FFFF 908300BC
48000010 3884FFFF 810300B8 800300B4
908300BC 810300B8 7D080214 3CE0000A
800300B4 7D080214 60E7F9B0 7C074000
3CE0000A 60E7F9B0 40A00010 7CE83B78
7C074000 40A00010 98E300B2 90E300B4
7CE83B78 98E300B2 1D0803E9 38000078
90E300B4 1D0803E9 7D080396 9421FFF0
38000078 7D080396
380003E8 7CE80396 380003E8 7CE80396
7C0701D6 7D004050 7C0701D6 7D004050
3800003C 7CC70396 91010008 3800003C
7C0601D6 7CE03850 7D270396 7C0901D6
38A300A4 3880000F 7D403850 80E30118
80630210 4CC63182 390300A4 80C30114
3D808031 618C90A4 3D80817F 80A30110
7D8803A6 4E800021 618C0238 808300A0
3C60817F 60630110 7D8803A6 80630094
38800000 38A00000 4E800021 38210010
38C10BEC 38E00081 38610BEC 3D80802D
3D80802A 618CF5B8 398CAECC 7D8803A6
7D8803A6 4E800021 4E800021 881F0046
881F0046 00000000 60000000 00000000
C227C214 00000005 C227C214 00000005
3CA0817F A00500B2 3CA0817F A00500B2
2C000000 40820014 2C000000 40820014
@ -1609,22 +1559,6 @@
5400003A 900500B8 5400003A 900500B8
3800FFFF 900500BC 3800FFFF 900500BC
60000000 00000000 60000000 00000000
077F0094 0000001D
00000010 000001A0
00000280 000001E0
25753A25 3032752E
25303375 00000000
C219E1FC 00000004
80AD9E78 8005005C
3CA0817F 900500B8
3800001E 900500BC
38A00000 00000000
C219E010 00000005
7C030378 80A3005C
38A50003 54A0003A
3CA0817F 900500B8
3800001E 900500BC
60000000 00000000
</source> </source>
</code> </code>
<code> <code>
@ -4487,15 +4421,12 @@
<title lang="en-US">Instant Level Select</title> <title lang="en-US">Instant Level Select</title>
<title lang="ja-JP">レベル選択DX</title> <title lang="ja-JP">レベル選択DX</title>
<author>sup39(サポミク)</author> <author>sup39(サポミク)</author>
<version>0.1</version> <version>0.3</version>
<date>Oct 16, 2022</date> <date>Feb 08, 2023</date>
<description lang="en-US"> <description lang="en-US">
::: warning ::: warning
Shine Get Timer does not restart with this code. Shine Get Timer does not restart with this code.
::: :::
::: warning
Z menu will be disabled
:::
#### Instant Restart #### Instant Restart
- Press `B + D-Pad Up` to **restart the current area** - Press `B + D-Pad Up` to **restart the current area**
@ -4523,9 +4454,6 @@
::: warning ::: warning
シャインゲットタイマーには未対応です。 シャインゲットタイマーには未対応です。
::: :::
::: warning
Zメニューは無効化されます。
:::
#### ポーズせずにやり直し #### ポーズせずにやり直し
- `B+十字キー上`で**現在のエリアをやり直す** - `B+十字キー上`で**現在のエリアをやり直す**
@ -4548,60 +4476,55 @@
4. これで好きなだけハニスキを練習できます。他のエリアに入ろうとする時に自動的にやり直すので、手動でやり直す必要がありません。必要であれば`B + 十字キー上`でやり直すこともできます。 4. これで好きなだけハニスキを練習できます。他のエリアに入ろうとする時に自動的にやり直すので、手動でやり直す必要がありません。必要であれば`B + 十字キー上`でやり直すこともできます。
</description> </description>
<source version="GMSJ01"> <source version="GMSJ01">
040ED64C 4970C435 C20F9B74 00000046
0410B100 496EE990 3C80817F 816D97D0
040EC420 4970D600 3D808040 80AC0D80
04236600 495C34C4 20050022 540A043D
0410B3CC 496EE6DC 41820008 8804002B
040FBAD8 496FDF30 540007FF 9804002B
040F9D68 496FFD78 28830001 4C451102
040EAB80 4970EEC0 40A2000C 38A00208
077F9800 000002F4 90AC0D80 7C7D1B79
3CA08040 80A50D80 418201EC 4800003D
70A00208 28800208 00141516 0017181D
3C60817F 88030004 34000090 2F2E3020
7C000379 4CC61202 32293328 2A1FBA3C
4CA60020 7D8802A6 371E213A 0E2C3900
4800003D 00141516 00010507 08090200
0017181D 34000090 123457D0 24567000
2F2E3020 32293328 12234070 23467001
2A1FBA3C 371E213A 7D2802A6 70A00208
0E2C3900 00010507 28000208 40A201A0
08090200 123457D0
24567000 12234070
23467001 7D2802A6
7D8803A6 3D40803E
394A6000 816D97D0
54A6CF38 50A6F77A 54A6CF38 50A6F77A
50A6E7BC 50A6D7FE 50A6E7BC 50A6D7FE
54A0C738 50A0B77C 54A0C738 50A0B77C
7CC60378 54A4873F 7CC60378 54A3873F
41820054 2C040009 41820054 2C030009
41820098 3C00C84A 41820098 3C00C84A
6000C004 1C840003 6000C004 1C630003
5C04277E 5485103A 5C031F7E 5465103A
2C06000C 408000BC 2C06000C 408000BC
2C06000A 408000D4 2C06000A 408000D4
2C060008 40800090 2C060008 40800090
3C005689 60000234 3C005689 60000234
548C103A 5C0C652E 546C103A 5C0C652E
7CC76378 54C8077E 7CC76378 54C8077E
480000C4 A0EA000E 480000C4 A0FF000E
2C060000 41820028 2C060000 41820028
2C060004 41820028 2C060004 41820028
2C06000A 41820028 2C06000A 41820028
7C0930AE 540744AE 7C0930AE 540744AE
5408CFFE 1D080007 5408CFFE 1D080007
48000094 A00A000A 48000094 A01F000A
B00A000E 890B00DF B01F000E 890B00DF
4800008C A0E30000 4800008C A0E40028
89030002 48000078 8904002A 48000078
3989000C 7C0C30AE 3989000C 7C0C30AE
540744AE 5007CFFE 540744AE 5007CFFE
3C00AC1A 60005CA2 3C00AC1A 60005CA2
1D860003 5C08677E 1D860003 5C08677E
48000054 39890018 48000054 39890018
7C0C20AE 540744AE 7C0C18AE 540744AE
3C001373 60002301 3C001373 60002301
5C082F7E 48000038 5C082F7E 48000038
3989FFF8 54C016B8 3989FFF8 54C016B8
@ -4610,54 +4533,239 @@
5C082F7E 48000018 5C082F7E 48000018
3C001578 60009200 3C001578 60009200
5C072F3E 60E70100 5C072F3E 60E70100
39000000 B0E30000 39000000 B0E40028
99030002 38000001 9904002A 38000001
980300B3 98030004 980400B3 990B00DF
990B00DF 38000000 38000000 900B00D8
900B00D8 A00B00CC A00B00CC 60004000
60004000 54000524 54000524 B00B00CC
B00B00CC B0EA0012 B0FF0012 54E0C63E
54E0C63E 818A0020 819F0020 2C000007
3880003B 2C000007 2C80000E 4C423382
41820010 2C00000E 3800003B 41820008
41820008 38800000 38000000 B00C00E4
B08C00E4 4E800020 A00C00E2 540007FA
3D80817F 880C0004 B00C00E2 54FDD7BE
7C000379 4C820020 3BBD0005 00000000
3800003C 4A9020C0 </source>
4BFFFDE1 40A60014 <source version="GMSJ0A">
7FE3FB78 4A8F1115 C2285FCC 00000046
3B800009 4A8F30F4 3C80817F 816D9E60
881F0064 4A8F29E8 3D80803F 80AC5458
3C60817F A0030004 20050022 540A043D
2C000001 40820028 41820008 8804002B
A01F004C 5400062C 540007FF 9804002B
B01F004C 816D97D0 28830001 4C451102
7F8AE378 A0EA000E 40A2000C 38A00208
4BFFFEB5 A0FC000A 90AC5458 7C7D1B79
B0FC000E 380000FF 418201EC 4800003D
38810054 4A8F1108 00141516 0017181D
3D80817F 888C0005 34000090 2F2E3020
68840001 4A8EE414 32293328 2A1FBA3C
4BFFFD71 40A6000C 371E213A 0E2C3900
38600002 9061012C 00010507 08090200
807F0020 4A911660 123457D0 24567000
3C60817F 88030004 12234070 23467001
2C000001 40820008 7D2802A6 70A00208
4A911A7C 2805000E 28000208 40A201A0
4A911910 4BFFFD3D 54A6CF38 50A6F77A
40A60008 4AA3CB54 50A6E7BC 50A6D7FE
807E0020 38BFFFCC 54A0C738 50A0B77C
8803013B 4AA3CB28 7CC60378 54A3873F
3C60817F 38000000 41820054 2C030009
98030004 7FA3EB78 41820098 3C00C84A
4A90027C 00000000 6000C004 1C630003
28400D50 00000021 5C031F7E 5465103A
017F0005 00000001 2C06000C 408000BC
28400D51 00000022 2C06000A 408000D4
017F0005 00000000 2C060008 40800090
E0000000 00000000 3C005689 60000234
040eb024 60000000 546C103A 5C0C652E
7CC76378 54C8077E
480000C4 A0FF000E
2C060000 41820028
2C060004 41820028
2C06000A 41820028
7C0930AE 540744AE
5408CFFE 1D080007
48000094 A01F000A
B01F000E 890B00DF
4800008C A0E40028
8904002A 48000078
3989000C 7C0C30AE
540744AE 5007CFFE
3C00AC1A 60005CA2
1D860003 5C08677E
48000054 39890018
7C0C18AE 540744AE
3C001373 60002301
5C082F7E 48000038
3989FFF8 54C016B8
7C0C006E 5C072F7E
5007252E 800C0004
5C082F7E 48000018
3C001578 60009200
5C072F3E 60E70100
39000000 B0E40028
9904002A 38000001
980400B3 990B00DF
38000000 900B00D8
A00B00CC 60004000
54000524 B00B00CC
B0FF0012 54E0C63E
819F0020 2C000007
2C80000E 4C423382
3800003B 41820008
38000000 B00C00E4
A00C00E2 540007FA
B00C00E2 54FDD7BE
3BBD0005 00000000
</source>
<source version="GMSP01">
C229E080 00000046
3C80817F 816D9EC8
3D808040 80ACBC24
20050022 540A043D
41820008 8804002B
540007FF 9804002B
28830001 4C451102
40A2000C 38A00208
90ACBC24 7C7D1B79
418201EC 4800003D
00141516 0017181D
34000090 2F2E3020
32293328 2A1FBA3C
371E213A 0E2C3900
00010507 08090200
123457D0 24567000
12234070 23467001
7D2802A6 70A00208
28000208 40A201A0
54A6CF38 50A6F77A
50A6E7BC 50A6D7FE
54A0C738 50A0B77C
7CC60378 54A3873F
41820054 2C030009
41820098 3C00C84A
6000C004 1C630003
5C031F7E 5465103A
2C06000C 408000BC
2C06000A 408000D4
2C060008 40800090
3C005689 60000234
546C103A 5C0C652E
7CC76378 54C8077E
480000C4 A0FF000E
2C060000 41820028
2C060004 41820028
2C06000A 41820028
7C0930AE 540744AE
5408CFFE 1D080007
48000094 A01F000A
B01F000E 890B00DF
4800008C A0E40028
8904002A 48000078
3989000C 7C0C30AE
540744AE 5007CFFE
3C00AC1A 60005CA2
1D860003 5C08677E
48000054 39890018
7C0C18AE 540744AE
3C001373 60002301
5C082F7E 48000038
3989FFF8 54C016B8
7C0C006E 5C072F7E
5007252E 800C0004
5C082F7E 48000018
3C001578 60009200
5C072F3E 60E70100
39000000 B0E40028
9904002A 38000001
980400B3 990B00DF
38000000 900B00D8
A00B00CC 60004000
54000524 B00B00CC
B0FF0012 54E0C63E
819F0020 2C000007
2C80000E 4C423382
3800003B 41820008
38000000 B00C00E4
A00C00E2 540007FA
B00C00E2 54FDD7BE
3BBD0005 00000000
</source>
<source version="GMSE01">
C22A6170 00000046
3C80817F 816D9FA0
3D808040 80AC4484
20050022 540A043D
41820008 8804002B
540007FF 9804002B
28830001 4C451102
40A2000C 38A00208
90AC4484 7C7D1B79
418201EC 4800003D
00141516 0017181D
34000090 2F2E3020
32293328 2A1FBA3C
371E213A 0E2C3900
00010507 08090200
123457D0 24567000
12234070 23467001
7D2802A6 70A00208
28000208 40A201A0
54A6CF38 50A6F77A
50A6E7BC 50A6D7FE
54A0C738 50A0B77C
7CC60378 54A3873F
41820054 2C030009
41820098 3C00C84A
6000C004 1C630003
5C031F7E 5465103A
2C06000C 408000BC
2C06000A 408000D4
2C060008 40800090
3C005689 60000234
546C103A 5C0C652E
7CC76378 54C8077E
480000C4 A0FF000E
2C060000 41820028
2C060004 41820028
2C06000A 41820028
7C0930AE 540744AE
5408CFFE 1D080007
48000094 A01F000A
B01F000E 890B00DF
4800008C A0E40028
8904002A 48000078
3989000C 7C0C30AE
540744AE 5007CFFE
3C00AC1A 60005CA2
1D860003 5C08677E
48000054 39890018
7C0C18AE 540744AE
3C001373 60002301
5C082F7E 48000038
3989FFF8 54C016B8
7C0C006E 5C072F7E
5007252E 800C0004
5C082F7E 48000018
3C001578 60009200
5C072F3E 60E70100
39000000 B0E40028
9904002A 38000001
980400B3 990B00DF
38000000 900B00D8
A00B00CC 60004000
54000524 B00B00CC
B0FF0012 54E0C63E
819F0020 2C000007
2C80000E 4C423382
3800003B 41820008
38000000 B00C00E4
A00C00E2 540007FA
B00C00E2 54FDD7BE
3BBD0005 00000000
</source> </source>
</code> </code>
<code> <code>

View file

@ -35,6 +35,8 @@ you may also need to check the following files:
- [site/.vuepress/components/codes/ui.js](site/.vuepress/components/codes/ui.js): - [site/.vuepress/components/codes/ui.js](site/.vuepress/components/codes/ui.js):
Specify the vue component for the configuration of the code. Specify the vue component for the configuration of the code.
The version string will be passed as a property. The version string will be passed as a property.
- [site/.vuepress/components/codes/preview.js](site/.vuepress/components/codes/preview.js):
Specify the `id` and the `getConfig(version)` function of the code to make it shown in preview.
#### Reserved Memory #### Reserved Memory
@ -47,7 +49,12 @@ Some codes store some states in the games memory starting from address 0x817F000
| ![](./docs/reserved.svg) | `0x14` | `0x15` | DPad Functions: Stored Angle (Mario) | | ![](./docs/reserved.svg) | `0x14` | `0x15` | DPad Functions: Stored Angle (Mario) |
| ![](./docs/reserved.svg) | `0x16` | `0x1B` | DPad Functions: Stored Position (Camera) | | ![](./docs/reserved.svg) | `0x16` | `0x1B` | DPad Functions: Stored Position (Camera) |
| ![](./docs/reserved.svg) | `0x20` | `0x23` | Coin Count Savestate: Coin Count | | ![](./docs/reserved.svg) | `0x20` | `0x23` | Coin Count Savestate: Coin Count |
| ![](./docs/unallocated.svg) | `0x24` | `0x93` | Not Allocated | | ![](./docs/reserved.svg) | `0x24` | `0x26` | Pattern Selector: Selected Pattern Numbers |
| ![](./docs/reserved.svg) | `0x27` | `0x27` | Pattern Selector: Cursor Position |
| ![](./docs/reserved.svg) | `0x28` | `0x29` | Instant Level Select: Last Selected Area ID |
| ![](./docs/reserved.svg) | `0x2A` | `0x2A` | Instant Level Select: Last Selected Episode Number |
| ![](./docs/reserved.svg) | `0x2B` | `0x2B` | Instant Level Select: Area Lock Flag |
| ![](./docs/unallocated.svg) | `0x2C` | `0x93` | Not Allocated |
| ![](./docs/reserved.svg) | `0x94` | `0xA3` | QF Timer: Coordinates of the Text box (LTRB) | | ![](./docs/reserved.svg) | `0x94` | `0xA3` | QF Timer: Coordinates of the Text box (LTRB) |
| ![](./docs/reserved.svg) | `0xA4` | `0xB0` | QF Timer: Timer Format String | | ![](./docs/reserved.svg) | `0xA4` | `0xB0` | QF Timer: Timer Format String |
| ![](./docs/reserved.svg) | `0xB0` | `0xB1` | QF Timer: (Unused) | | ![](./docs/reserved.svg) | `0xB0` | `0xB1` | QF Timer: (Unused) |
@ -65,7 +72,35 @@ Some codes store some states in the games memory starting from address 0x817F000
| ![](./docs/reserved.svg) | `0x110` | `0x237` | QF Timer: Timer Textbox | | ![](./docs/reserved.svg) | `0x110` | `0x237` | QF Timer: Timer Textbox |
| ![](./docs/reserved.svg) | `0x238` | `0x347` | General Function (`drawText`) | | ![](./docs/reserved.svg) | `0x238` | `0x347` | General Function (`drawText`) |
| ![](./docs/buffer.svg) | `0x348` | `0x39B` | Buffer (QF Timer) | | ![](./docs/buffer.svg) | `0x348` | `0x39B` | Buffer (QF Timer) |
| ![](./docs/unallocated.svg) | `0x39C` | `0xFFF` | Not Allocated | | ![](./docs/reserved.svg) | `0x39C` | `0x3AF` | QF Section Timer: Background Config |
| ![](./docs/reserved.svg) | `0x3B0` | `0x3BF` | QF Section Timer: Text Config |
| ![](./docs/reserved.svg) | `0x3C0` | `0x3C8` | QF Section Timer: Format String |
| ![](./docs/reserved.svg) | `0x3C9` | `0x3C9` | QF Section Timer: (Unused) |
| ![](./docs/reserved.svg) | `0x3CA` | `0x3CB` | QF Section Timer: Section Count |
| ![](./docs/reserved.svg) | `0x3CC` | `0x3CF` | QF Section Timer: Last Freezed Time |
| ![](./docs/reserved.svg) | `0x3D0` | `0x40F` | QF Section Timer: Section Time Array |
| ![](./docs/reserved.svg) | `0x410` | `0x41F` | Pattern Selector: Background Config |
| ![](./docs/reserved.svg) | `0x424` | `0x433` | Pattern Selector: Text Config |
| ![](./docs/reserved.svg) | `0x434` | `0x440` | Pattern Selector: Format String |
| ![](./docs/reserved.svg) | `0x441` | `0x475` | Pattern Selector: Pattern Data |
| ![](./docs/reserved.svg) | `0x476` | `0x477` | Attempt Counter: Previous Area |
| ![](./docs/reserved.svg) | `0x478` | `0x478` | Attempt Counter: Display Timer |
| ![](./docs/reserved.svg) | `0x479` | `0x479` | Attempt Counter: Display Duration |
| ![](./docs/reserved.svg) | `0x47A` | `0x47F` | Attempt Counter: Format String |
| ![](./docs/reserved.svg) | `0x480` | `0x48F` | Attempt Counter: Text Config |
| ![](./docs/reserved.svg) | `0x490` | `0x4A3` | Attempt Counter: Background Config |
| ![](./docs/reserved.svg) | `0x4A4` | `0x4A5` | Attempt Counter: Success Count |
| ![](./docs/reserved.svg) | `0x4A6` | `0x4A7` | Attempt Counter: Attempt Count |
| ![](./docs/reserved.svg) | `0x4A8` | `0x4A8` | Attempt Counter: Got Shine Flag |
| ![](./docs/buffer.svg) | `0x4A9` | `0x4AF` | Buffer (Attempt Counter) |
| ![](./docs/unallocated.svg) | `0x4B0` | `0x4BF` | Not Allocated |
| ![](./docs/buffer.svg) | `0x4C0` | `0x4C2` | Buffer (Controller Input Display) |
| ![](./docs/reserved.svg) | `0x4C3` | `0x4C3` | Controller Input Display: Line Width |
| ![](./docs/reserved.svg) | `0x4C4` | `0x4C7` | Controller Input Display: Scale |
| ![](./docs/reserved.svg) | `0x4C8` | `0x4CB` | Controller Input Display: (X, Y) Coordinate |
| ![](./docs/reserved.svg) | `0x4CC` | `0x4CF` | Controller Input Display: Background Color |
| ![](./docs/reserved.svg) | `0x4D0` | `0x53F` | Controller Input Display: Components Config |
| ![](./docs/unallocated.svg) | `0x540` | `0xFFF` | Not Allocated |
### Adding translations ### Adding translations

View file

@ -1,4 +1,23 @@
# Changelog # Changelog
## Feb 08, 2023
### Updated 'Instant Level Select'
Overwrite button input value to prevent Level Select being activated when AreaLock is enabled
## Jan 10, 2023
### Updated 'Quarterframe Timer'
Added the following options to freeze QFT:
- When Mario holds, throws, puts down an object
- When Mario triple jumps, spin jumps, ledge grabs, wall kicks, bounces, rope jumps
## Jan 7, 2023
### Updated 'Quarterframe Timer'
Reworked the existing freezes and added the option to freeze when mounting Yoshi
## Dec 16, 2022
### Updated 'Quarterframe Timer'
- Gave the timer a 1 frame headstart to make it more accurate to SGT and IL retiming rules
- Ported the customizable visuals and freeze conditions to the US and PAL versions
## Nov 19, 2022 ## Nov 19, 2022
Added `CAngle` for 'Customized Display' to show camera angle Added `CAngle` for 'Customized Display' to show camera angle

3152
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -23,14 +23,14 @@
"@sup39/markdown-it-attr": "1.2.2", "@sup39/markdown-it-attr": "1.2.2",
"@sup39/markdown-it-inline-tag": "1.0.1", "@sup39/markdown-it-inline-tag": "1.0.1",
"@types/encoding-japanese": "^2.0.1", "@types/encoding-japanese": "^2.0.1",
"@vuepress/plugin-back-to-top": "1.9.7", "@vuepress/plugin-back-to-top": "1.9.8",
"@vuepress/plugin-medium-zoom": "1.9.7", "@vuepress/plugin-medium-zoom": "1.9.8",
"encoding-japanese": "^2.0.0", "encoding-japanese": "^2.0.0",
"jsdom": "20.0.2", "jsdom": "21.1.0",
"pre-commit": "1.2.2", "pre-commit": "1.2.2",
"prettier": "2.7.1", "prettier": "2.8.3",
"serve": "14.1.1", "serve": "14.2.0",
"vuepress": "1.9.7" "vuepress": "1.9.8"
}, },
"dependencies": { "dependencies": {
"vuedraggable": "2.24.3" "vuedraggable": "2.24.3"

View file

@ -30,13 +30,13 @@ export default {
}, },
methods: { methods: {
onClick() { onClick() {
if (!(this.codes || this.codes.length === 0) && !this.stageLoaderCode) { if ((!this.codes || !this.codes.length) && !this.stageLoaderCode) {
return; return;
} }
const c = [...(this.codes ?? [])]; const codeList = this.codes.map((c) => ({ ...c }));
if (this.stageLoaderCode) if (this.stageLoaderCode)
c.push({ codeList.push({
title: 'Stage List Loader', title: 'Stage List Loader',
author: 'Noki Doki', author: 'Noki Doki',
date: '-', date: '-',
@ -52,7 +52,7 @@ export default {
JSON.stringify({ JSON.stringify({
gameVersion: this.versionIdentifier, gameVersion: this.versionIdentifier,
format: this.format, format: this.format,
codes: c.map((code) => ({ codes: codeList.map((code) => ({
title: code.title, title: code.title,
version: code.version, version: code.version,
})), })),
@ -63,28 +63,28 @@ export default {
const fileName = gameVersions.find((v) => v.identifier === this.versionIdentifier).version; const fileName = gameVersions.find((v) => v.identifier === this.versionIdentifier).version;
// apply customizable codes // apply customizable codes
for (const code of c) { for (const code of codeList) {
const codegen = codegens[code.id]; const codegen = codegens[code.id];
if (codegen) { if (codegen) {
code.source = codegen(this.versionIdentifier); code.source = codegen(this.versionIdentifier, code.source);
} }
} }
// generate file // generate file
const codeSize = c.reduce((a, e) => a+e.source.length, 0)/2 + 16; // 8(00D0)+8(F000) const codeSize = codeList.reduce((a, e) => a + e.source.length, 0) / 2 + 16; // 8(00D0)+8(F000)
// console.log(codeSize, c); // console.log(codeSize, codeList);
switch (this.format) { switch (this.format) {
case 'gct': case 'gct':
this.alertGCTCodeSize(codeSize); this.alertGCTCodeSize(codeSize);
this.generateGCT(c, fileName); this.generateGCT(codeList, fileName);
break; break;
case 'dolphin': case 'dolphin':
this.alertDolphinCodeSize(codeSize); this.alertDolphinCodeSize(codeSize);
this.generateDolphinINI(c, fileName); this.generateDolphinINI(codeList, fileName);
break; break;
case 'gcm': case 'gcm':
this.alertDolphinCodeSize(codeSize); this.alertDolphinCodeSize(codeSize);
this.generateCheatManagerTXT(c, fileName); this.generateCheatManagerTXT(codeList, fileName);
break; break;
case 'gci+gct': case 'gci+gct':
this.generateGCI(c, fileName) && this.generateGCI(c, fileName) &&
@ -109,9 +109,12 @@ export default {
} }
}, },
alertDolphinCodeSize(size) { alertDolphinCodeSize(size) {
if (size > 3272) { // 0x3000-0x2338 if (size > 3272) {
// 0x3000-0x2338
// excluding header+footer // excluding header+footer
alert(translate('generatorconfig.alert.dolphin', this.$lang).replaceAll('{size}', size-16)); alert(
translate('generatorconfig.alert.dolphin', this.$lang).replaceAll('{size}', size - 16),
);
} }
}, },
getGCILoader() { getGCILoader() {

View file

@ -1,93 +1,19 @@
export const r13off = -0x6048; export const r13off = -0x6048;
export const onChangeStatusAddr = 0x802541c8;
/** /**
* @type {{[key: string]: {addr: number, orig: number}}} * @type {{[key: string]: number|{addr: number, orig: number}}}
*/ */
export const freezeCodeInfo = { export const freezeCodeHooks = {
redCoin: { addr: 0x801be474, orig: 0x38a00000 }, yellowCoin: 0x801bee10,
blueCoin: { addr: 0x801be288, orig: 0x7c030378 }, redCoin: 0x801be524,
blueCoin: 0x801be288,
item: 0x801bf3c4,
talk: 0x80153a34,
demo: 0x8029a318,
cleaned: 0x80215c6c,
bowser: 0x801fb7ac,
yoshi: 0x802704d4,
take: { addr: 0x8023f9a8, orig: 0x801f0384 },
drop: { addr: 0x802437d4, orig: 0x38000000 },
}; };
export const baseCode = `
C22998C0 0000000B
981A0260 3CE0817F
880700B3 2C000000
38000000 900700BC
4182000C B00700B2
900700B4 60E30110
38800000 60E50094
80CD9FC8 80C60048
60E700A4 39000002
39200000 3D80802D
618C0848 7D8803A6
4E800021 00000000
C2143F18 0000001B
3C60817F 888300B2
810300B4 2C040000
40A20030 808300BC
2C040000 40A20010
810D9FB8 8108005C
48000010 3884FFFF
908300BC 810300B8
800300B4 7D080214
3CE0000A 60E7F9B0
7C074000 40A00010
7CE83B78 98E300B2
90E300B4 1D0803E9
38000078 7D080396
380003E8 7CE80396
7C0701D6 7D004050
3800003C 7CC70396
7C0601D6 7CE03850
38A300A4 3880000F
80630210 4CC63182
3D808033 618C97A4
7D8803A6 4E800021
3C60817F 60630110
38800000 38A00000
38C10BD0 38E00081
3D80802C 618CFDA8
7D8803A6 4E800021
881F0046 00000000
C229C520 00000005
3CA0817F A00500B2
2C000000 40820014
800500B4 80C3005C
7C003214 900500B4
7C0802A6 00000000
C229A5AC 00000005
3CA0817F 80C500B4
8003005C 7CC60214
38C60004 54C6003A
90C500B4 38C0FFFF
B0C500B2 00000000
C21FA380 00000005
3D00817F 80C800B4
8003005C 7CC60214
38C60004 54C6003A
90C800B4 38C0FFFF
B0C800B2 00000000
C2164E24 00000002
2C030001 3C60817F
98A300B3 00000000
C229880C 00000002
389C0001 3CA0817F
988500B3 00000000
C22991A8 00000005
3CA0817F 38600001
986500B3 807F005C
38630003 5463003A
906500B8 3860FFFF
906500BC 00000000
C229A36C 00000005
3CA0817F 980500B3
801E005C 30000004
5400003A 900500B8
3800FFFF 900500BC
60000000 00000000
077F0094 0000001D
00000010 000001A0
00000280 000001E0
25753A25 3032752E
25303375 00000000
`;

View file

@ -1,92 +1,19 @@
export const r13off = -0x6818; export const r13off = -0x6818;
export const onChangeStatusAddr = 0x801335b8;
/** /**
* @type {{[key: string]: {addr: number, orig: number}}} * @type {{[key: string]: number|{addr: number, orig: number}}}
*/ */
export const freezeCodeInfo = { export const freezeCodeHooks = {
yellowCoin: { addr: 0x80196b54, orig: 0x8805000e }, yellowCoin: 0x80196cb0,
redCoin: { addr: 0x80196314, orig: 0x38a00000 }, redCoin: 0x801963c4,
blueCoin: { addr: 0x80196128, orig: 0x7c030378 }, blueCoin: 0x80196128,
item: { addr: 0x801971f8, orig: 0x8001001c }, item: 0x80197208,
talk: { addr: 0x800eb6e4, orig: 0x807f00b0 }, talk: 0x80214f00,
demo: { addr: 0x800eb760, orig: 0x88e7013c }, demo: 0x800ed89c,
cleaned: { addr: 0x8017a3c0, orig: 0x80010044 }, cleaned: 0x8017a3d4,
bowser: { addr: 0x801d3c78, orig: 0x2c1d0003 }, bowser: 0x801d3380,
yoshi: 0x8014f830,
take: { addr: 0x8011eae4, orig: 0x801f0384 },
drop: { addr: 0x80122964, orig: 0x38000000 },
}; };
export const baseCode = `
C20ECE44 00000005
981A0260 3CE0817F
880700B3 2C000000
38000000 900700BC
4182000C B00700B2
900700B4 00000000
C2206738 0000001F
3C60817F 6064011C
38630094 3D808020
398C1EA8 7D8803A6
4E800021 3C60817F
888300B2 810300B4
2C040000 40820030
808300BC 2C040000
40820010 810D97E8
8108005C 48000010
3884FFFF 908300BC
810300B8 800300B4
7D080214 3CE0000A
60E7F9B0 7C074000
40800010 7CE83B78
98E300B2 90E300B4
3C60817F 1D0803E9
38000078 7D080396
9421FFF0 380003E8
7CE80396 7C0701D6
7D004050 91010008
3800003C 7D270396
7C0901D6 7D403850
80E30118 390300A4
80C30114 3D80817F
80A30110 618C0238
808300A0 7D8803A6
80630094 4E800021
38210010 38610E90
3D808003 398C5228
7D8803A6 4E800021
881F0046 00000000
C20EFA30 00000005
3CA0817F A00500B2
2C000000 40820014
800500B4 80C3005C
7C003214 900500B4
7C0802A6 00000000
C20EDB30 00000005
3CA0817F 80C500B4
8003005C 7CC60214
38C60004 54C6003A
90C500B4 38C0FFFF
B0C500B2 00000000
C21D1F38 00000005
3D00817F 80C800B4
8003005C 7CC60214
38C60004 54C6003A
90C800B4 38C0FFFF
B0C800B2 00000000
C22257CC 00000002
2C030001 3C60817F
98A300B3 00000000
C20EBD78 00000002
389C0001 3CA0817F
988500B3 00000000
C20EC72C 00000005
3CA0817F 38600001
986500B3 807F005C
38630003 5463003A
906500B8 3860FFFF
906500BC 00000000
C20ED8F0 00000005
3CA0817F 980500B3
801E005C 30000004
5400003A 900500B8
3800FFFF 900500BC
60000000 00000000
`;

View file

@ -1,92 +1,19 @@
export const r13off = -0x6188; export const r13off = -0x6188;
export const onChangeStatusAddr = 0x80233f18;
/** /**
* @type {{[key: string]: {addr: number, orig: number}}} * @type {{[key: string]: number|{addr: number, orig: number}}}
*/ */
export const freezeCodeInfo = { export const freezeCodeHooks = {
yellowCoin: { addr: 0x8019ea3c, orig: 0x8805000e }, yellowCoin: 0x8019eb98,
redCoin: { addr: 0x8019e1fc, orig: 0x38a00000 }, redCoin: 0x8019e2ac,
blueCoin: { addr: 0x8019e010, orig: 0x7c030378 }, blueCoin: 0x8019e010,
item: { addr: 0x8019f13c, orig: 0x8001001c }, item: 0x8019f14c,
talk: { addr: 0x80277dd0, orig: 0x807f00b0 }, talk: 0x80134e58,
demo: { addr: 0x80277e4c, orig: 0x88e7013c }, demo: 0x80279fc8,
cleaned: { addr: 0x801f5af8, orig: 0x80010044 }, cleaned: 0x801f5b0c,
bowser: { addr: 0x801dbe48, orig: 0x2c1d0003 }, bowser: 0x801db550,
yoshi: 0x80250224,
take: { addr: 0x8021f6f0, orig: 0x801f0384 },
drop: { addr: 0x8022351c, orig: 0x38000000 },
}; };
export const baseCode = `
C2279570 00000005
981A0260 3CE0817F
880700B3 2C000000
38000000 900700BC
4182000C B00700B2
900700B4 00000000
C21252A4 0000001F
3C60817F 6064011C
38630094 3D808012
398C1660 7D8803A6
4E800021 3C60817F
888300B2 810300B4
2C040000 40820030
808300BC 2C040000
40820010 810D9E78
8108005C 48000010
3884FFFF 908300BC
810300B8 800300B4
7D080214 3CE0000A
60E7F9B0 7C074000
40800010 7CE83B78
98E300B2 90E300B4
3C60817F 1D0803E9
38000078 7D080396
9421FFF0 380003E8
7CE80396 7C0701D6
7D004050 91010008
3800003C 7D270396
7C0901D6 7D403850
80E30118 390300A4
80C30114 3D80817F
80A30110 618C0238
808300A0 7D8803A6
80630094 4E800021
38210010 38610E90
3D80802D 398CAECC
7D8803A6 4E800021
881F0046 00000000
C227C214 00000005
3CA0817F A00500B2
2C000000 40820014
800500B4 80C3005C
7C003214 900500B4
7C0802A6 00000000
C227A298 00000005
3CA0817F 80C500B4
8003005C 7CC60214
38C60004 54C6003A
90C500B4 38C0FFFF
B0C500B2 00000000
C21DA0FC 00000005
3D00817F 80C800B4
8003005C 7CC60214
38C60004 54C6003A
90C800B4 38C0FFFF
B0C800B2 00000000
C2145EBC 00000002
2C030001 3C60817F
98A300B3 00000000
C22784B4 00000002
389C0001 3CA0817F
988500B3 00000000
C2278E58 00000005
3CA0817F 38600001
986500B3 807F005C
38630003 5463003A
906500B8 3860FFFF
906500BC 00000000
C227A01C 00000005
3CA0817F 980500B3
801E005C 30000004
5400003A 900500B8
3800FFFF 900500BC
60000000 00000000
`;

View file

@ -1,93 +1,19 @@
export const r13off = -0x6120; export const r13off = -0x6120;
export const onChangeStatusAddr = 0x8024bf54;
/** /**
* @type {{[key: string]: {addr: number, orig: number}}} * @type {{[key: string]: number|{addr: number, orig: number}}}
*/ */
export const freezeCodeInfo = { export const freezeCodeHooks = {
redCoin: { addr: 0x801b632c, orig: 0x38a00000 }, yellowCoin: 0x801b6cc8,
blueCoin: { addr: 0x801b6140, orig: 0x7c030378 }, redCoin: 0x801b63dc,
blueCoin: 0x801b6140,
item: 0x801b727c,
talk: 0x801489b4,
demo: 0x802921b0,
cleaned: 0x8020db50,
bowser: 0x801f3690,
yoshi: 0x80268260,
take: { addr: 0x80237734, orig: 0x801f0384 },
drop: { addr: 0x8023b560, orig: 0x38000000 },
}; };
export const baseCode = `
C2291758 0000000B
981A0260 3CE0817F
880700B3 2C000000
38000000 900700BC
4182000C B00700B2
900700B4 60E30110
38800000 60E50094
80CD9EF0 80C60048
60E700A4 39000002
39200000 3D80802C
618C89F0 7D8803A6
4E800021 00000000
C2138B54 0000001B
3C60817F 888300B2
810300B4 2C040000
40A20030 808300BC
2C040000 40A20010
810D9EE0 8108005C
48000010 3884FFFF
908300BC 810300B8
800300B4 7D080214
3CE0000A 60E7F9B0
7C074000 40A00010
7CE83B78 98E300B2
90E300B4 1D0803E9
38000078 7D080396
380003E8 7CE80396
7C0701D6 7D004050
3800003C 7CC70396
7C0601D6 7CE03850
38A300A4 3880000F
80630210 4CC63182
3D808033 618C1924
7D8803A6 4E800021
3C60817F 60630110
38800000 38A00000
38C10BE4 38E00081
3D80802C 618C7F50
7D8803A6 4E800021
881F0046 00000000
C22943FC 00000005
3CA0817F A00500B2
2C000000 40820014
800500B4 80C3005C
7C003214 900500B4
7C0802A6 00000000
C2292480 00000005
3CA0817F 80C500B4
8003005C 7CC60214
38C60004 54C6003A
90C500B4 38C0FFFF
B0C500B2 00000000
C21F2258 00000005
3D00817F 80C800B4
8003005C 7CC60214
38C60004 54C6003A
90C800B4 38C0FFFF
B0C800B2 00000000
C2159E9C 00000002
2C030001 3C60817F
98A300B3 00000000
C22906A4 00000002
389C0001 3CA0817F
988500B3 00000000
C2291040 00000005
3CA0817F 38600001
986500B3 807F005C
38630003 5463003A
906500B8 3860FFFF
906500BC 00000000
C2292204 00000005
3CA0817F 980500B3
801E005C 30000004
5400003A 900500B8
3800FFFF 900500BC
60000000 00000000
077F0094 0000001D
00000010 000001A0
00000280 000001E0
25753A25 3032752E
25303375 00000000
`;

View file

@ -0,0 +1,9 @@
export default {
put: [0x80000387],
tripleJump: [0x882],
spinJump: [0x895, 0x896],
ledgeGrab: [0x3800034b],
wallKick: [0x2000886],
bounce: [0x884],
ropeJump: [0x892, 0x893],
};

View file

@ -22,6 +22,16 @@ export const defaultConfig = {
demo: true, demo: true,
cleaned: true, cleaned: true,
bowser: true, // onBathhubGripDestroyed bowser: true, // onBathhubGripDestroyed
yoshi: true,
take: true,
drop: true,
put: true,
tripleJump: true,
spinJump: true,
ledgeGrab: true,
wallKick: true,
ropeJump: true,
bounce: true,
}, },
}; };
@ -39,7 +49,7 @@ export function getConfig() {
} }
/** @param {number} x */ /** @param {number} x */
const inst2gecko = (x) => (x >>> 0).toString(16).toUpperCase().padStart(8, '0'); const int2gecko = (x) => (x >>> 0).toString(16).toUpperCase().padStart(8, '0');
import * as GMSJ01 from './code/GMSJ01.js'; import * as GMSJ01 from './code/GMSJ01.js';
import * as GMSE01 from './code/GMSE01.js'; import * as GMSE01 from './code/GMSE01.js';
@ -47,48 +57,55 @@ import * as GMSP01 from './code/GMSP01.js';
import * as GMSJ0A from './code/GMSJ0A.js'; import * as GMSJ0A from './code/GMSJ0A.js';
export const codes = { GMSJ01, GMSE01, GMSP01, GMSJ0A }; export const codes = { GMSJ01, GMSE01, GMSP01, GMSJ0A };
import statusDB from './code/status.js';
export const statusKeys = Object.keys(statusDB);
/**** /****
## save freeze frame, load and save QF ## save freeze frame, load and save QF
## this function destroys r11(freeze frame), r12 ## this function destroys r11 and r12
077F0348: 077F0348:
lwz r11, gpMarDirector-_SDA_BASE_(r13)
lis r12, 0x817F lis r12, 0x817F
stw r11, 0xBC(r12)
lwz r11, -0x6818(r13)
lwz r11, 0x5C(r11) lwz r11, 0x5C(r11)
stw r11, 0xB8(r12) stw r11, 0xB8(r12)
li r11, freezeDuration
stw r11, 0xBC(r12)
blr blr
## for each code ## for each hook (over a blr): b 817f0348
ORIG
li r11, xxxx
b 817f0348
04xxxxxx:
bl 817fxxxx
****/ ****/
const freezeCodeAddr = 0x817f0348; const freezeCodeAddr = 0x817f0348;
/** @param {keyof typeof codes} version */ /**
export default function codegen(version) { * @param {keyof typeof codes} version
* @param {string=} baseCode
*/
export default function codegen(version, baseCode) {
if (!baseCode) return '';
const config = getConfig(); const config = getConfig();
const { freezeCodeInfo, baseCode, r13off } = codes[version] ?? {}; const { freezeCodeHooks, r13off, onChangeStatusAddr } = codes[version] ?? {};
if (baseCode == null) return '';
let code = baseCode; let code = baseCode;
const { freezeDuration: frame } = config; const { freezeDuration: frame } = config;
// freezing code // freezing code
const freezeEnableds = []; const enabledFreezes = [];
const statuses = [];
if (frame > 0) { if (frame > 0) {
for (const [key, enabled] of Object.entries(config.freeze)) { for (const [key, enabled] of Object.entries(config.freeze)) {
const info = freezeCodeInfo[key]; if (!enabled) continue;
if (enabled && info) { // add status
const { addr, orig } = info; statuses.push(...(statusDB[key] ?? []));
// add hook
const hook = freezeCodeHooks[key];
if (hook) {
if (key === 'blueCoin') { if (key === 'blueCoin') {
const addr = hook;
// special: needs to adjust QF -> use separate C2 instead // special: needs to adjust QF -> use separate C2 instead
code += [ code += [
0xc2000000 + (addr & 0x1ffffff), 0xc2000000 + (addr & 0x1ffffff),
0x00000005, 0x00000005,
orig, 0x7c030378,
0x80a3005c, 0x80a3005c,
0x38a50003, 0x38a50003,
0x54a0003a, 0x54a0003a,
@ -99,36 +116,60 @@ export default function codegen(version) {
0x60000000, 0x60000000,
0x00000000, 0x00000000,
] ]
.map(inst2gecko) .map(int2gecko)
.join(''); .join('');
} else { } else if (typeof hook === 'number') {
// handle regular freezing code later // handle regular freezing code later
freezeEnableds.push(info); const addr = hook;
enabledFreezes.push(addr);
} else {
// {addr: number, orig: number}
// separate C2 code to handle orig
const { addr, orig } = hook;
code += [
0xc2000000 + (addr & 0x1ffffff),
0x00000003,
0x3d800000 + (freezeCodeAddr >>> 16), // lis r12, freezeCodeAddr@h
0x618c0000 + (freezeCodeAddr & 0xffff), // ori r12, r12, freezeCodeAddr@l
0x7d8803a6, // mtlr r12
0x4e800021, // blrl
orig,
0x00000000,
]
.map(int2gecko)
.join('');
} }
} }
} }
} }
// handle regular freezing code // handle regular freezing code
if (freezeEnableds.length <= 1) { if (enabledFreezes.length <= 1 && statuses.length === 0) {
// use C2 directly // use C2 directly
code += freezeEnableds code += enabledFreezes
.flatMap(({ addr, orig }) => [ .flatMap((addr) => [
0xc2000000 + (addr & 0x1ffffff), 0xc2000000 + (addr & 0x1ffffff),
0x00000004, 0x00000004,
orig,
0x816d0000 | (r13off & 0xffff), // lwz r11, r13off(r13) 0x816d0000 | (r13off & 0xffff), // lwz r11, r13off(r13)
0x3d80817f, // lis r12, 0x817F 0x3d80817f, // lis r12, 0x817F
0x816b005c, // lwz r11, 0x5C(r11) 0x816b005c, // lwz r11, 0x5C(r11)
0x916c00b8, // stw r11, 0xB8(r12) 0x916c00b8, // stw r11, 0xB8(r12)
0x39600000 | (frame & 0xffff), // li r11, frame 0x39600000 | (frame & 0xffff), // li r11, frame
0x916c00bc, // stw r11, 0xBC(r12) 0x916c00bc, // stw r11, 0xBC(r12)
0x60000000, // nop
0x00000000, 0x00000000,
]) ])
.map(inst2gecko) .map(int2gecko)
.join(''); .join('');
} else { } else {
const code04 = []; // could be shorter to turn this into a Gecko loop if enough freezes are enabled
const code07 = [ const hooks = enabledFreezes.flatMap((addr) => [
0xc6000000 | (addr & 0x1ffffff),
freezeCodeAddr,
]);
const freezer = [
0x06000000 | (freezeCodeAddr & 0x1ffffff),
0x0000001c,
0x816d0000 | (r13off & 0xffff), // lwz r11, r13off(r13) 0x816d0000 | (r13off & 0xffff), // lwz r11, r13off(r13)
0x3d80817f, // lis r12, 0x817F 0x3d80817f, // lis r12, 0x817F
0x816b005c, // lwz r11, 0x5C(r11) 0x816b005c, // lwz r11, 0x5C(r11)
@ -136,56 +177,82 @@ export default function codegen(version) {
0x39600000 | (frame & 0xffff), // li r11, frame 0x39600000 | (frame & 0xffff), // li r11, frame
0x916c00bc, // stw r11, 0xBC(r12) 0x916c00bc, // stw r11, 0xBC(r12)
0x4e800020, // blr 0x4e800020, // blr
0x00000000,
]; ];
let dst = freezeCodeAddr + code07.length * 4;
// put code together
for (const { addr, orig } of freezeEnableds) {
code07.push(
orig, // [dst] original instruction
0x4c000000 + (freezeCodeAddr - dst - 4), // b freezeCode
);
code04.push(
0x04000000 | (addr & 0x1ffffff), // 04 addr
0x48000001 | (dst - addr), // bl dst
);
dst += 8;
}
// make 07 code
code07.unshift(
0x06000000 | (freezeCodeAddr & 0x1ffffff), // 07 freezeCodeAddr
code07.length * 4,
);
if (code07.length & 1) {
// odd => pad with 0
code07.push(0);
}
// apply code // apply code
code += [...code04, ...code07].map(inst2gecko).join(''); code += [...hooks, ...freezer].map(int2gecko).join('');
} }
// ui (GMSJ01/GMSJ0A only) // onChangeStatus hook
if (['GMSJ01', 'GMSJ0A'].includes(version)) { if (statuses.length) {
/* bounds */ const c = [
const { x, y, fontSize, width } = config; // check each status
const scale = fontSize / 20; ...statuses.flatMap((x, i) => {
code += '077F0094 0000001D'; const cr = i > 0 ? 0x800000 : 0; // i>0 ? cr1 : cr0
const c =
x < 0x10000
? [
0x281d0000 + cr + x, // cmplwi crX, r29, $x
]
: [
0x3c000000 + (x >>> 16), // lis r0, $x@h
0x60000000 + (x & 0xffff), // ori r0, r0, $x@l
0x7c1d0040 + cr, // cmplw crX, r29, r0
];
if (i > 0) {
// cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
c.push(0x4c423382);
}
return c;
}),
// freeze
0x3d800000 + (freezeCodeAddr >>> 16), // lis r12, freezeCodeAddr@h
0x618c0000 + (freezeCodeAddr & 0xffff), // ori r12, r12, freezeCodeAddr@l
0x7d8803a6, // mtlr r12
0x4d820021, // beqlrl
// orig
0x38000000, // li r0, 0
];
// pad nop
if (c.length % 2 === 0) {
c.push(0x60000000);
}
// end of C2
c.push(0x00000000);
// apply code
code += [ code += [
x, // x1 0xc2000000 + (onChangeStatusAddr & 0x1ffffff),
y - fontSize - 2, // y1 c.length >> 1, // line count
x + width * scale, // x2 ...c,
y, // y2
] ]
.map(inst2gecko) .map(int2gecko)
.join(''); .join('');
code += '25753a253032752e2530337500000000'; // fmt
/* fontSize, fgColor, bgColor */
code += '077F0110 00000010';
const bgColor = (config.bgRGB & 0xffffff) * 256 + (config.bgA & 0xff);
const fgColor = (config.fgRGB & 0xffffff) * 256 + (config.fgA & 0xff);
const fgColor2 =
((config.fgRGB2 ?? config.fgRGB) & 0xffffff) * 256 + ((config.fgA2 ?? config.fgA) & 0xff);
code += [fontSize, fgColor, fgColor2, bgColor].map(inst2gecko).join('');
} }
// ui
/* bounds */
const { x, y, fontSize, width } = config;
const scale = fontSize / 20;
code += '077F0094 0000001D';
code += [
x, // x1
y - fontSize - 2, // y1
x + width * scale, // x2
y, // y2
]
.map(int2gecko)
.join('');
code += '25753a253032752e2530337500000000'; // fmt
/* fontSize, fgColor, bgColor */
code += '077F0110 00000010';
const bgColor = (config.bgRGB & 0xffffff) * 256 + (config.bgA & 0xff);
const fgColor = (config.fgRGB & 0xffffff) * 256 + (config.fgA & 0xff);
const fgColor2 =
((config.fgRGB2 ?? config.fgRGB) & 0xffffff) * 256 + ((config.fgA2 ?? config.fgA) & 0xff);
code += [fontSize, fgColor, fgColor2, bgColor].map(int2gecko).join('');
return code.replace(/\s/g, ''); return code.replace(/\s/g, '');
} }

View file

@ -1,26 +1,32 @@
<template> <template>
<div id="config"> <div id="config">
<section v-if="['GMSJ01', 'GMSJ0A'].includes(version)" class="appearance"> <section class="appearance">
<h3>{{l.h3}}</h3> <h3>{{ l.h3 }}</h3>
<div> <div>
<TextConfig v-model="textConfig" /> <TextConfig v-model="textConfig" />
</div> </div>
<div> <div>
<span>{{l.bgColor}}</span><input type="color" :value="rgbI2S(bgRGB)" @change="bgRGB = rgbS2I($event.target.value)"> <span>{{ l.bgColor }}</span
<span>{{l.alpha}}</span><input type="number" min="0" max="255" v-model.number="bgA"><span>/255={{(bgA/2.55).toFixed(1)}}%</span> ><input type="color" :value="rgbI2S(bgRGB)" @change="bgRGB = rgbS2I($event.target.value)" />
<span>{{ l.alpha }}</span
><input type="number" min="0" max="255" v-model.number="bgA" /><span
>/255={{ (bgA / 2.55).toFixed(1) }}%</span
>
</div> </div>
</section> </section>
<section class="freeze"> <section class="freeze">
<h3>{{l.freeze.h3}}</h3> <h3>{{ l.freeze.h3 }}</h3>
<div> <div>
{{l.freeze.duration}}<input type="number" min="0" max="32767" v-model="freezeDuration"> {{l.freeze.frame}} {{ l.freeze.duration }}<input type="number" min="0" max="32767" v-model="freezeDuration" />
= {{(freezeDuration*1001/30000).toFixed(2)}} {{l.freeze.sec}} {{ l.freeze.frame }} = {{ ((freezeDuration * 1001) / 30000).toFixed(2) }} {{ l.freeze.sec }}
</div> </div>
<table> <table>
<tbody> <tbody>
<tr v-for="key in freezeKeys" :key="key"> <tr v-for="key in freezeKeys" :key="key">
<td>{{l.freeze.rows[key]}}</td> <td>{{ l.freeze.rows[key] }}</td>
<td><input type="checkbox" :checked="freeze[key]" @change="onChangeFreeze($event, key)"></td> <td>
<input type="checkbox" :checked="freeze[key]" @change="onChangeFreeze($event, key)" />
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -29,15 +35,26 @@
</template> </template>
<script> <script>
import {getConfig, lskey, codes} from './codegen.js'; import { getConfig, lskey, codes, statusKeys } from './codegen.js';
import {rgbI2S, rgbS2I, rgbaI2S} from '../utils'; import { rgbI2S, rgbS2I, rgbaI2S } from '../utils';
import labels from './labels.json'; import labels from './labels.json';
import TextConfig from '../TextConfig.vue'; import TextConfig from '../TextConfig.vue';
function updateConfig() { function updateConfig() {
const {x, y, fontSize, width, fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA, freeze, freezeDuration} = this; const { x, y, fontSize, width, fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA, freeze, freezeDuration } = this;
const config = { const config = {
x, y, fontSize, width, fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA, freeze, freezeDuration x,
y,
fontSize,
width,
fgRGB,
fgA,
fgRGB2,
fgA2,
bgRGB,
bgA,
freeze,
freezeDuration,
}; };
localStorage.setItem(lskey, JSON.stringify(config)); localStorage.setItem(lskey, JSON.stringify(config));
this.$emit('config', config); this.$emit('config', config);
@ -48,7 +65,7 @@ export default {
TextConfig, TextConfig,
}, },
props: { props: {
version: {type: String}, version: { type: String },
}, },
methods: { methods: {
onChangeFreeze($event, key) { onChangeFreeze($event, key) {
@ -70,14 +87,26 @@ export default {
rgbaI2S, rgbaI2S,
}, },
data() { data() {
const {x, y, fontSize, width, fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA, freeze, freezeDuration} = getConfig(); const { x, y, fontSize, width, fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA, freeze, freezeDuration } =
getConfig();
return { return {
x, y, fontSize, x,
fgRGB, fgA, fgRGB2, fgA2, y,
width, bgRGB, bgA, fontSize,
freeze, freezeDuration, fgRGB,
fgA,
fgRGB2,
fgA2,
width,
bgRGB,
bgA,
freeze,
freezeDuration,
// const // const
freezeKeys: Object.keys(codes[this.version]?.freezeCodeInfo ?? {}), freezeKeys: [
...Object.keys(codes[this.version]?.freezeCodeHooks ?? {}),
...statusKeys,
],
}; };
}, },
computed: { computed: {
@ -86,8 +115,8 @@ export default {
}, },
textConfig: { textConfig: {
get() { get() {
const {x, y, fontSize, fgRGB, fgA, fgRGB2, fgA2} = this; const { x, y, fontSize, fgRGB, fgA, fgRGB2, fgA2 } = this;
return {x, y, fontSize, fgRGB, fgA, fgRGB2, fgA2}; return { x, y, fontSize, fgRGB, fgA, fgRGB2, fgA2 };
}, },
set(value) { set(value) {
Object.assign(this, value); Object.assign(this, value);
@ -101,14 +130,15 @@ export default {
bgA: updateConfig, bgA: updateConfig,
freezeDuration: updateConfig, freezeDuration: updateConfig,
}, },
} };
</script> </script>
<style scoped> <style scoped>
input[type=number], td.right { input[type='number'],
td.right {
text-align: right; text-align: right;
} }
input[type="number"] { input[type='number'] {
width: 3em; width: 3em;
margin: 0 2px; margin: 0 2px;
} }
@ -116,11 +146,11 @@ input[type="number"] {
padding: 0 0 4px; padding: 0 0 4px;
} }
input[type=number] { input[type='number'] {
-moz-appearance: textfield; -moz-appearance: textfield;
} }
input[type="number"]::-webkit-inner-spin-button, input[type='number']::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button { input[type='number']::-webkit-outer-spin-button {
-webkit-appearance: none; -webkit-appearance: none;
margin: 0; margin: 0;
} }

View file

@ -24,7 +24,17 @@
"talk": "会話開始時", "talk": "会話開始時",
"demo": "カットシーン開始時", "demo": "カットシーン開始時",
"cleaned": "NPCを洗った時", "cleaned": "NPCを洗った時",
"bowser": "クッパ戦の足場を破壊した時" "bowser": "クッパ戦の足場を破壊した時",
"yoshi": "ヨッシーに乗った時",
"take": "オブジェクトを持った時",
"drop": "オブジェクトを投げた時",
"put": "オブジェクトを置いた時",
"tripleJump": "三段ジャンプした時",
"spinJump": "スピンジャンプした時",
"ledgeGrab": "崖掴まりした時",
"wallKick": "壁キックした時",
"ropeJump": "ロープ、大車輪でジャンプした時",
"bounce": "アメンボやジャンプ台で跳ねた時"
} }
} }
}, },
@ -34,8 +44,8 @@
"fontSize": "Font size: ", "fontSize": "Font size: ",
"fgColor": "Font color: ", "fgColor": "Font color: ",
"fgColorGrad": "Gradient", "fgColorGrad": "Gradient",
"fgColor1": "Font color(Top): ", "fgColor1": "Font color (top): ",
"fgColor2": "Font color(Bottom): ", "fgColor2": "Font color (bottom): ",
"bgColor": "Background color: ", "bgColor": "Background color: ",
"alpha": "Alpha=", "alpha": "Alpha=",
"preview": "Preview", "preview": "Preview",
@ -43,17 +53,57 @@
"freeze": { "freeze": {
"h3": "Freezing the timer", "h3": "Freezing the timer",
"duration": "Duration: ", "duration": "Duration: ",
"frame": "(frame)", "frame": "(frames)",
"sec": "(sec)", "sec": "(sec)",
"rows": { "rows": {
"yellowCoin": "When collected a yellow coin", "yellowCoin": "When a yellow coin is collected",
"redCoin": "When collected a red coin", "redCoin": "When a red coin is collected",
"blueCoin": "When collected a blue coin", "blueCoin": "When a blue coin is collected",
"item": "When collected an item (e.g. nozzle)", "item": "When an item (e.g. nozzle) is collected",
"talk": "When dialogue started", "talk": "When dialogue starts",
"demo": "When cutscene started", "demo": "When a cutscene starts",
"cleaned": "When NPC is cleaned", "cleaned": "When an NPC is cleaned",
"bowser": "When destroyed platform in Bowser fight" "bowser": "When a platform is destroyed in the Bowser fight",
"yoshi": "When Yoshi is mounted",
"take": "When Mario holds an object",
"drop": "When Mario throws an object",
"put": "When Mario puts down an object",
"tripleJump": "When Mario triple jumps",
"spinJump": "When Mario spin jumps",
"ledgeGrab": "When Mario ledge grabs",
"wallKick": "When Mario wall kicks",
"ropeJump": "When Mario jumps from a rope",
"bounce": "When Mario bounces (e.g. on a roof)"
}
}
},
"fr-FR": {
"h3": "Apparence",
"location": "Position : ",
"fontSize": "Taille de police : ",
"fgColor": "Couleur du texte : ",
"fgColorGrad": "Dégradé",
"fgColor1": "Couleur du texte (haut) : ",
"fgColor2": "Couleur du texte (bas) : ",
"bgColor": "Couleur de fond : ",
"alpha": "Alpha = ",
"preview": "Aperçu",
"previewNote": "※ x doit être entre 0 et 600, et y entre 16 et 464.",
"freeze": {
"h3": "Temps intermédiaires",
"duration": "Durée d'affichage : ",
"frame": "(frames)",
"sec": "(sec)",
"rows": {
"yellowCoin": "Quand une pièce jaune est ramassée",
"redCoin": "Quand une pièce rouge est ramassée",
"blueCoin": "Quand une pièce bleue est ramassée",
"item": "Quand un power-up (buse, etc.) est ramassé",
"talk": "Quand un dialogue commence",
"demo": "Quand une cutscene commence",
"cleaned": "Quand un PNJ est nettoyé",
"bowser": "Quand une plate-forme est détruite dans le combat de Bowser",
"yoshi": "Quand Yoshi est monté"
} }
} }
} }