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

View file

@ -1,4 +1,23 @@
# 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
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-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",
"@vuepress/plugin-back-to-top": "1.9.8",
"@vuepress/plugin-medium-zoom": "1.9.8",
"encoding-japanese": "^2.0.0",
"jsdom": "20.0.2",
"jsdom": "21.1.0",
"pre-commit": "1.2.2",
"prettier": "2.7.1",
"serve": "14.1.1",
"vuepress": "1.9.7"
"prettier": "2.8.3",
"serve": "14.2.0",
"vuepress": "1.9.8"
},
"dependencies": {
"vuedraggable": "2.24.3"

View file

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

View file

@ -1,93 +1,19 @@
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 = {
redCoin: { addr: 0x801be474, orig: 0x38a00000 },
blueCoin: { addr: 0x801be288, orig: 0x7c030378 },
export const freezeCodeHooks = {
yellowCoin: 0x801bee10,
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 onChangeStatusAddr = 0x801335b8;
/**
* @type {{[key: string]: {addr: number, orig: number}}}
* @type {{[key: string]: number|{addr: number, orig: number}}}
*/
export const freezeCodeInfo = {
yellowCoin: { addr: 0x80196b54, orig: 0x8805000e },
redCoin: { addr: 0x80196314, orig: 0x38a00000 },
blueCoin: { addr: 0x80196128, orig: 0x7c030378 },
item: { addr: 0x801971f8, orig: 0x8001001c },
talk: { addr: 0x800eb6e4, orig: 0x807f00b0 },
demo: { addr: 0x800eb760, orig: 0x88e7013c },
cleaned: { addr: 0x8017a3c0, orig: 0x80010044 },
bowser: { addr: 0x801d3c78, orig: 0x2c1d0003 },
export const freezeCodeHooks = {
yellowCoin: 0x80196cb0,
redCoin: 0x801963c4,
blueCoin: 0x80196128,
item: 0x80197208,
talk: 0x80214f00,
demo: 0x800ed89c,
cleaned: 0x8017a3d4,
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 onChangeStatusAddr = 0x80233f18;
/**
* @type {{[key: string]: {addr: number, orig: number}}}
* @type {{[key: string]: number|{addr: number, orig: number}}}
*/
export const freezeCodeInfo = {
yellowCoin: { addr: 0x8019ea3c, orig: 0x8805000e },
redCoin: { addr: 0x8019e1fc, orig: 0x38a00000 },
blueCoin: { addr: 0x8019e010, orig: 0x7c030378 },
item: { addr: 0x8019f13c, orig: 0x8001001c },
talk: { addr: 0x80277dd0, orig: 0x807f00b0 },
demo: { addr: 0x80277e4c, orig: 0x88e7013c },
cleaned: { addr: 0x801f5af8, orig: 0x80010044 },
bowser: { addr: 0x801dbe48, orig: 0x2c1d0003 },
export const freezeCodeHooks = {
yellowCoin: 0x8019eb98,
redCoin: 0x8019e2ac,
blueCoin: 0x8019e010,
item: 0x8019f14c,
talk: 0x80134e58,
demo: 0x80279fc8,
cleaned: 0x801f5b0c,
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 onChangeStatusAddr = 0x8024bf54;
/**
* @type {{[key: string]: {addr: number, orig: number}}}
* @type {{[key: string]: number|{addr: number, orig: number}}}
*/
export const freezeCodeInfo = {
redCoin: { addr: 0x801b632c, orig: 0x38a00000 },
blueCoin: { addr: 0x801b6140, orig: 0x7c030378 },
export const freezeCodeHooks = {
yellowCoin: 0x801b6cc8,
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,
cleaned: true,
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 */
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 GMSE01 from './code/GMSE01.js';
@ -47,48 +57,55 @@ import * as GMSP01 from './code/GMSP01.js';
import * as GMSJ0A from './code/GMSJ0A.js';
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
## this function destroys r11(freeze frame), r12
## this function destroys r11 and r12
077F0348:
lwz r11, gpMarDirector-_SDA_BASE_(r13)
lis r12, 0x817F
stw r11, 0xBC(r12)
lwz r11, -0x6818(r13)
lwz r11, 0x5C(r11)
stw r11, 0xB8(r12)
li r11, freezeDuration
stw r11, 0xBC(r12)
blr
## for each code
ORIG
li r11, xxxx
b 817f0348
04xxxxxx:
bl 817fxxxx
## for each hook (over a blr): b 817f0348
****/
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 { freezeCodeInfo, baseCode, r13off } = codes[version] ?? {};
if (baseCode == null) return '';
const { freezeCodeHooks, r13off, onChangeStatusAddr } = codes[version] ?? {};
let code = baseCode;
const { freezeDuration: frame } = config;
// freezing code
const freezeEnableds = [];
const enabledFreezes = [];
const statuses = [];
if (frame > 0) {
for (const [key, enabled] of Object.entries(config.freeze)) {
const info = freezeCodeInfo[key];
if (enabled && info) {
const { addr, orig } = info;
if (!enabled) continue;
// add status
statuses.push(...(statusDB[key] ?? []));
// add hook
const hook = freezeCodeHooks[key];
if (hook) {
if (key === 'blueCoin') {
const addr = hook;
// special: needs to adjust QF -> use separate C2 instead
code += [
0xc2000000 + (addr & 0x1ffffff),
0x00000005,
orig,
0x7c030378,
0x80a3005c,
0x38a50003,
0x54a0003a,
@ -99,36 +116,60 @@ export default function codegen(version) {
0x60000000,
0x00000000,
]
.map(inst2gecko)
.map(int2gecko)
.join('');
} else {
} else if (typeof hook === 'number') {
// 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
if (freezeEnableds.length <= 1) {
if (enabledFreezes.length <= 1 && statuses.length === 0) {
// use C2 directly
code += freezeEnableds
.flatMap(({ addr, orig }) => [
code += enabledFreezes
.flatMap((addr) => [
0xc2000000 + (addr & 0x1ffffff),
0x00000004,
orig,
0x816d0000 | (r13off & 0xffff), // lwz r11, r13off(r13)
0x3d80817f, // lis r12, 0x817F
0x816b005c, // lwz r11, 0x5C(r11)
0x916c00b8, // stw r11, 0xB8(r12)
0x39600000 | (frame & 0xffff), // li r11, frame
0x916c00bc, // stw r11, 0xBC(r12)
0x60000000, // nop
0x00000000,
])
.map(inst2gecko)
.map(int2gecko)
.join('');
} else {
const code04 = [];
const code07 = [
// could be shorter to turn this into a Gecko loop if enough freezes are enabled
const hooks = enabledFreezes.flatMap((addr) => [
0xc6000000 | (addr & 0x1ffffff),
freezeCodeAddr,
]);
const freezer = [
0x06000000 | (freezeCodeAddr & 0x1ffffff),
0x0000001c,
0x816d0000 | (r13off & 0xffff), // lwz r11, r13off(r13)
0x3d80817f, // lis r12, 0x817F
0x816b005c, // lwz r11, 0x5C(r11)
@ -136,56 +177,82 @@ export default function codegen(version) {
0x39600000 | (frame & 0xffff), // li r11, frame
0x916c00bc, // stw r11, 0xBC(r12)
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
code += [...code04, ...code07].map(inst2gecko).join('');
code += [...hooks, ...freezer].map(int2gecko).join('');
}
// ui (GMSJ01/GMSJ0A only)
if (['GMSJ01', 'GMSJ0A'].includes(version)) {
/* bounds */
const { x, y, fontSize, width } = config;
const scale = fontSize / 20;
code += '077F0094 0000001D';
// onChangeStatus hook
if (statuses.length) {
const c = [
// check each status
...statuses.flatMap((x, i) => {
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 += [
x, // x1
y - fontSize - 2, // y1
x + width * scale, // x2
y, // y2
0xc2000000 + (onChangeStatusAddr & 0x1ffffff),
c.length >> 1, // line count
...c,
]
.map(inst2gecko)
.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(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, '');
}

View file

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

View file

@ -24,7 +24,17 @@
"talk": "会話開始時",
"demo": "カットシーン開始時",
"cleaned": "NPCを洗った時",
"bowser": "クッパ戦の足場を破壊した時"
"bowser": "クッパ戦の足場を破壊した時",
"yoshi": "ヨッシーに乗った時",
"take": "オブジェクトを持った時",
"drop": "オブジェクトを投げた時",
"put": "オブジェクトを置いた時",
"tripleJump": "三段ジャンプした時",
"spinJump": "スピンジャンプした時",
"ledgeGrab": "崖掴まりした時",
"wallKick": "壁キックした時",
"ropeJump": "ロープ、大車輪でジャンプした時",
"bounce": "アメンボやジャンプ台で跳ねた時"
}
}
},
@ -34,8 +44,8 @@
"fontSize": "Font size: ",
"fgColor": "Font color: ",
"fgColorGrad": "Gradient",
"fgColor1": "Font color(Top): ",
"fgColor2": "Font color(Bottom): ",
"fgColor1": "Font color (top): ",
"fgColor2": "Font color (bottom): ",
"bgColor": "Background color: ",
"alpha": "Alpha=",
"preview": "Preview",
@ -43,17 +53,57 @@
"freeze": {
"h3": "Freezing the timer",
"duration": "Duration: ",
"frame": "(frame)",
"frame": "(frames)",
"sec": "(sec)",
"rows": {
"yellowCoin": "When collected a yellow coin",
"redCoin": "When collected a red coin",
"blueCoin": "When collected a blue coin",
"item": "When collected an item (e.g. nozzle)",
"talk": "When dialogue started",
"demo": "When cutscene started",
"cleaned": "When NPC is cleaned",
"bowser": "When destroyed platform in Bowser fight"
"yellowCoin": "When a yellow coin is collected",
"redCoin": "When a red coin is collected",
"blueCoin": "When a blue coin is collected",
"item": "When an item (e.g. nozzle) is collected",
"talk": "When dialogue starts",
"demo": "When a cutscene starts",
"cleaned": "When an NPC is cleaned",
"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é"
}
}
}