Shorten QFT

This commit is contained in:
sup39 2022-04-21 23:54:05 +09:00
parent d0cf826395
commit d9bb06f3ba
9 changed files with 92 additions and 112 deletions

View file

@ -1236,12 +1236,14 @@
</source> </source>
</code> </code>
<code> <code>
<id>qft</id>
<category>timer</category> <category>timer</category>
<title lang="en-US">Quarterframe Timer (Experimental)</title> <title lang="en-US">Quarterframe Timer (Experimental)</title>
<title lang="ja-JP">QFタイマー</title> <title lang="ja-JP">QFタイマー</title>
<author>Noki Doki, sup39(サポミク)</author> <author>Noki Doki, sup39(サポミク)</author>
<version>0.5</version> <version>0.5</version>
<date>Nov 28, 2021</date> <date>Nov 28, 2021</date>
<dependencies version="GMSJ01">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 after 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

View file

@ -51,7 +51,8 @@ Some codes store some states in the games memory starting from address 0x817F000
| ![](./docs/buffer.svg) | `0x10D` | `0x10F` | Buffer (Ingame Timer) | | ![](./docs/buffer.svg) | `0x10D` | `0x10F` | Buffer (Ingame Timer) |
| ![](./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/unallocated.svg) | `0x348` | `0xFFF` | Not Allocated | | ![](./docs/buffer.svg) | `0x348` | `0x3BF` | Buffer (QF Timer) |
| ![](./docs/unallocated.svg) | `0x3C0` | `0xFFF` | Not Allocated |
### Adding translations ### Adding translations

View file

@ -1,5 +1,9 @@
# Changelog # Changelog
## Apr 21, 2022 ## Apr 21, 2022
### Shortened QFT
- Shortened QFT's freeze code by replacing C2 with 04(bl@event) and 07.
- Reserve `817F0348`~`817F03BF` (120 bytes)
### Reduced code size of Pattern Selector ### Reduced code size of Pattern Selector
Reduce 240 bytes of PS by replacing switch case with lookup table. Reduce 240 bytes of PS by replacing switch case with lookup table.

View file

@ -1,19 +1,9 @@
export const freezeCodegen = { /**
redCoin: (s) => ` * @type {{[key: string]: [addr: number, orig: number]}}
C21BE474 00000004 */
80AD9FB8 8005005C export const freezeCodeInfo = {
3CA0817F 900500B8 redCoin: [0x801be474, 0x38a00000],
3800${s} 900500BC blueCoin: [0x801be288, 0x7c030378], // TODO QF+3 &0xfffffffc
38A00000 00000000
`,
blueCoin: (s) => `
C21BE288 00000005
7C030378 80A3005C
38A50003 54A0003A
3CA0817F 900500B8
3800${s} 900500BC
60000000 00000000
`,
}; };
export const baseCode = ` export const baseCode = `

View file

@ -1,61 +1,15 @@
export const freezeCodegen = { /**
yellowCoin: (s) => ` * @type {{[key: string]: [addr: number, orig: number]}}
C2196B54 00000004 */
806d97e8 8083005c export const freezeCodeInfo = {
3c60817f 908300b8 yellowCoin: [0x80196b54, 0x8805000e],
3880${s} 908300bc redCoin: [0x80196314, 0x38a00000],
8805000E 00000000 blueCoin: [0x80196128, 0x7c030378], // TODO QF+3 &0xfffffffc
`, item: [0x801971f8, 0x8001001c],
redCoin: (s) => ` talk: [0x800eb6e4, 0x807f00b0],
C2196314 00000004 demo: [0x800eb74c, 0x806da8b0],
80AD97E8 8005005C cleaned: [0x8017a3c0, 0x80010044],
3CA0817F 900500B8 bowser: [0x801d3c78, 0x2c1d0003],
3800${s} 900500BC
38A00000 00000000
`,
blueCoin: (s) => `
C2196128 00000005
7C030378 80A3005C
38A50003 54A0003A
3CA0817F 900500B8
3800${s} 900500BC
60000000 00000000
`,
item: (s) => `
C21971F8 00000004
806d97e8 8083005c
3c60817f 908300b8
3880${s} 908300bc
8001001C 00000000
`,
talk: (s) => `
C20EB6E4 00000004
807f005c 3c80817f
906400b8 3860${s}
906400bc 60000000
807f00b0 00000000
`,
demo: (s) => `
C20EB74C 00000004
807f005c 3c80817f
906400b8 3860${s}
906400bc 60000000
806DA8B0 00000000
`,
cleaned: (s) => `
C217A3C0 00000004
806d97e8 8083005c
3c60817f 908300b8
3880${s} 908300bc
80010044 00000000
`,
bowser: (s) => `
C21D3C78 00000004
806d97e8 8083005c
3c60817f 908300b8
3880${s} 908300bc
2c1d0003 00000000
`,
}; };
export const baseCode = ` export const baseCode = `

View file

@ -1,19 +1,9 @@
export const freezeCodegen = { /**
redCoin: (s) => ` * @type {{[key: string]: [addr: number, orig: number]}}
C219E1FC 00000004 */
80AD9E78 8005005C export const freezeCodeInfo = {
3CA0817F 900500B8 redCoin: [0x8019e1fc, 0x38a00000],
3800${s} 900500BC blueCoin: [0x8019e010, 0x7c030378], // TODO QF+3 &0xfffffffc
38A00000 00000000
`,
blueCoin: (s) => `
C219E010 00000005
7C030378 80A3005C
38A50003 54A0003A
3CA0817F 900500B8
3800${s} 900500BC
60000000 00000000
`,
}; };
export const baseCode = ` export const baseCode = `

View file

@ -1,19 +1,9 @@
export const freezeCodegen = { /**
redCoin: (s) => ` * @type {{[key: string]: [addr: number, orig: number]}}
C21B632C 00000004 */
80AD9EE0 8005005C export const freezeCodeInfo = {
3CA0817F 900500B8 redCoin: [0x801b632c, 0x38a00000],
3800${s} 900500BC blueCoin: [0x801b6140, 0x7c030378], // TODO QF+3 &0xfffffffc
38A00000 00000000
`,
blueCoin: (s) => `
C21B6140 00000005
7C030378 80A3005C
38A50003 54A0003A
3CA0817F 900500B8
3800${s} 900500BC
60000000 00000000
`,
}; };
export const baseCode = ` export const baseCode = `

View file

@ -45,17 +45,66 @@ 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 };
/****
## save freeze frame, load and save QF
## this function destroys r11(freeze frame), r12
077F0348:
lis r12, 0x817F
stw r11, 0xBC(r12)
lwz r11, -0x6818(r13)
lwz r11, 0x5C(r11)
stw r11, 0xB8(r12)
blr
## for each code
ORIG
li r11, xxxx
b 817f0348
04xxxxxx:
bl 817fxxxx
****/
const freezeCodeAddr = 0x817f0348;
const freezeCode = [0x3d80817f, 0x916c00bc, 0x816d97e8, 0x816b005c, 0x916c00b8, 0x4e800020];
export default function codegen(version) { export default function codegen(version) {
const config = getConfig(); const config = getConfig();
const { freezeCodegen, baseCode } = codes[version] ?? {}; const { freezeCodeInfo, baseCode } = codes[version] ?? {};
if (baseCode == null) return ''; if (baseCode == null) return '';
let code = baseCode; let code = baseCode;
// freeze code // freeze code
Object.entries(config.freeze).forEach( const code04 = [];
([key, frame]) => (code += frame > 0 ? freezeCodegen[key]?.(int16(frame)) ?? '' : ''), const code07 = [...freezeCode];
); let dst = freezeCodeAddr + 24;
for (const [key, frame] of Object.entries(config.freeze)) {
const info = freezeCodeInfo[key];
if (frame > 0 && info) {
const [addr, orig] = info;
code07.push(
orig, // [dst] original instruction
0x39600000 | (frame & 0xffff), // li r11, $frame
0x4c000000 + (freezeCodeAddr - dst - 8), // b freezeCode
);
code04.push(
0x04000000 | (addr & 0x1ffffff), // 04xxxxxx
0x48000001 | (dst - addr), // bl
);
dst += 12;
}
}
if (code04.length) {
code07.unshift(
0x06000000 | (freezeCodeAddr & 0x1ffffff), // 07xxxxxx
code07.length * 4,
);
if (code07.length & 1) {
// odd -> add 0
code07.push(0);
}
code += [...code04, ...code07].map(int32).join('');
}
// ui (GMSJ01 only) // ui (GMSJ01 only)
if (['GMSJ01'].includes(version)) { if (['GMSJ01'].includes(version)) {

View file

@ -99,7 +99,7 @@ export default {
fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA, fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA,
freeze, freeze,
// const // const
freezeKeys: Object.keys(codes[this.version]?.freezeCodegen ?? {}), freezeKeys: Object.keys(codes[this.version]?.freezeCodeInfo ?? {}),
}; };
}, },
computed: { computed: {