Simplify QFT config
This commit is contained in:
parent
912a8b067c
commit
df449cc97c
9 changed files with 99 additions and 95 deletions
|
@ -51,8 +51,8 @@ Some codes store some states in the games memory starting from address 0x817F000
|
|||
| ![](./docs/buffer.svg) | `0x10D` | `0x10F` | Buffer (Ingame Timer) |
|
||||
| ![](./docs/reserved.svg) | `0x110` | `0x237` | QF Timer: Timer Textbox |
|
||||
| ![](./docs/reserved.svg) | `0x238` | `0x347` | General Function (`drawText`) |
|
||||
| ![](./docs/buffer.svg) | `0x348` | `0x3BF` | Buffer (QF Timer) |
|
||||
| ![](./docs/unallocated.svg) | `0x3C0` | `0xFFF` | Not Allocated |
|
||||
| ![](./docs/buffer.svg) | `0x348` | `0x39B` | Buffer (QF Timer) |
|
||||
| ![](./docs/unallocated.svg) | `0x39C` | `0xFFF` | Not Allocated |
|
||||
|
||||
### Adding translations
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
# Changelog
|
||||
## Apr 22, 2022
|
||||
### Shortened QFT
|
||||
- Shortened QFT's freeze code by replacing C2 with 04(bl@event) and 07.
|
||||
- Reserve `817F0348`~`817F03BF` (120 bytes)
|
||||
### Shortened QFT and simplified config
|
||||
- Shorten QFT's freeze code by replacing C2 with 04(bl@event) and 07.
|
||||
- Reserve `817F0348`~`817F039B` (84 bytes)
|
||||
- Change freezing config from [duration for each event] to [one duration + toggle for each event]
|
||||
|
||||
## Apr 21, 2022
|
||||
### Reduced code size of Pattern Selector
|
||||
Reduce 240 bytes of PS by replacing switch case with lookup table.
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
export const r13off = -0x6048;
|
||||
|
||||
/**
|
||||
* @type {{[key: string]: [addr: number, orig: number]}}
|
||||
* @type {{[key: string]: {addr: number, orig: number}}}
|
||||
*/
|
||||
export const freezeCodeInfo = {
|
||||
redCoin: [0x801be474, 0x38a00000],
|
||||
blueCoin: [0x801be288, 0x7c030378], // TODO QF+3 &0xfffffffc
|
||||
redCoin: { addr: 0x801be474, orig: 0x38a00000 },
|
||||
blueCoin: { addr: 0x801be288, orig: 0x7c030378 },
|
||||
};
|
||||
|
||||
export const baseCode = `
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
export const r13off = -0x6818;
|
||||
|
||||
/**
|
||||
* @type {{[key: string]: [addr: number, orig: number]}}
|
||||
* @type {{[key: string]: {addr: number, orig: number}}}
|
||||
*/
|
||||
export const freezeCodeInfo = {
|
||||
yellowCoin: [0x80196b54, 0x8805000e],
|
||||
redCoin: [0x80196314, 0x38a00000],
|
||||
blueCoin: [0x80196128, 0x7c030378], // TODO QF+3 &0xfffffffc
|
||||
item: [0x801971f8, 0x8001001c],
|
||||
talk: [0x800eb6e4, 0x807f00b0],
|
||||
demo: [0x800eb74c, 0x806da8b0],
|
||||
cleaned: [0x8017a3c0, 0x80010044],
|
||||
bowser: [0x801d3c78, 0x2c1d0003],
|
||||
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: 0x800eb74c, orig: 0x806da8b0 },
|
||||
cleaned: { addr: 0x8017a3c0, orig: 0x80010044 },
|
||||
bowser: { addr: 0x801d3c78, orig: 0x2c1d0003 },
|
||||
};
|
||||
|
||||
export const baseCode = `
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
export const r13off = -0x6188;
|
||||
|
||||
/**
|
||||
* @type {{[key: string]: [addr: number, orig: number]}}
|
||||
* @type {{[key: string]: {addr: number, orig: number}}}
|
||||
*/
|
||||
export const freezeCodeInfo = {
|
||||
redCoin: [0x8019e1fc, 0x38a00000],
|
||||
blueCoin: [0x8019e010, 0x7c030378], // TODO QF+3 &0xfffffffc
|
||||
redCoin: { addr: 0x8019e1fc, orig: 0x38a00000 },
|
||||
blueCoin: { addr: 0x8019e010, orig: 0x7c030378 },
|
||||
};
|
||||
|
||||
export const baseCode = `
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
export const r13off = -0x6120;
|
||||
|
||||
/**
|
||||
* @type {{[key: string]: [addr: number, orig: number]}}
|
||||
* @type {{[key: string]: {addr: number, orig: number}}}
|
||||
*/
|
||||
export const freezeCodeInfo = {
|
||||
redCoin: [0x801b632c, 0x38a00000],
|
||||
blueCoin: [0x801b6140, 0x7c030378], // TODO QF+3 &0xfffffffc
|
||||
redCoin: { addr: 0x801b632c, orig: 0x38a00000 },
|
||||
blueCoin: { addr: 0x801b6140, orig: 0x7c030378 },
|
||||
};
|
||||
|
||||
export const baseCode = `
|
||||
|
|
|
@ -12,15 +12,16 @@ export const defaultConfig = {
|
|||
fgA2: null,
|
||||
bgRGB: 0x000000,
|
||||
bgA: 0x80,
|
||||
freezeDuration: 30,
|
||||
freeze: {
|
||||
yellowCoin: 0,
|
||||
redCoin: 30,
|
||||
blueCoin: 30,
|
||||
item: 30,
|
||||
talk: 30,
|
||||
demo: 30,
|
||||
cleaned: 30,
|
||||
bowser: 30, // onBathhubGripDestroyed
|
||||
yellowCoin: false,
|
||||
redCoin: true,
|
||||
blueCoin: true,
|
||||
item: true,
|
||||
talk: true,
|
||||
demo: true,
|
||||
cleaned: true,
|
||||
bowser: true, // onBathhubGripDestroyed
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -36,8 +37,10 @@ export function getConfig() {
|
|||
};
|
||||
}
|
||||
|
||||
const int16 = (x) => (x < 0 ? x + 0x10000 : x).toString(16).padStart(4, '0').slice(-4);
|
||||
const int32 = (x) => (x < 0 ? x + 0x100000000 : x).toString(16).padStart(8, '0').slice(-8);
|
||||
const int16 = (x) =>
|
||||
(x < 0 ? x + 0x10000 : x).toString(16).padStart(4, '0').slice(-4).toUpperCase();
|
||||
const int32 = (x) =>
|
||||
(x < 0 ? x + 0x100000000 : x).toString(16).padStart(8, '0').slice(-8).toUpperCase();
|
||||
|
||||
import * as GMSJ01 from './code/GMSJ01.js';
|
||||
import * as GMSE01 from './code/GMSE01.js';
|
||||
|
@ -71,78 +74,81 @@ export default function codegen(version) {
|
|||
if (baseCode == null) return '';
|
||||
|
||||
let code = baseCode;
|
||||
const { freezeDuration: frame } = config;
|
||||
|
||||
// freezing code
|
||||
const freezeConfigs = [];
|
||||
for (const [key, frame] of Object.entries(config.freeze)) {
|
||||
const info = freezeCodeInfo[key];
|
||||
if (frame > 0 && info) {
|
||||
const [addr, orig] = info;
|
||||
if (key === 'blueCoin') {
|
||||
// special: needs to adjust QF -> use separate C2 instead
|
||||
code += [
|
||||
0xc2000000 + (addr & 0x1ffffff),
|
||||
0x00000005,
|
||||
orig,
|
||||
0x80a3005c,
|
||||
0x38a50003,
|
||||
0x54a0003a,
|
||||
0x3ca0817f,
|
||||
0x900500b8,
|
||||
0x38000000 | (frame & 0xffff),
|
||||
0x900500bc,
|
||||
0x60000000,
|
||||
0x00000000,
|
||||
]
|
||||
.map(int32)
|
||||
.join('');
|
||||
} else {
|
||||
// handle regular freezing code later
|
||||
freezeConfigs.push({ frame, addr, orig });
|
||||
const freezeEnableds = [];
|
||||
if (frame > 0) {
|
||||
for (const [key, enabled] of Object.entries(config.freeze)) {
|
||||
const info = freezeCodeInfo[key];
|
||||
if (enabled && info) {
|
||||
const { addr, orig } = info;
|
||||
if (key === 'blueCoin') {
|
||||
// special: needs to adjust QF -> use separate C2 instead
|
||||
code += [
|
||||
0xc2000000 + (addr & 0x1ffffff),
|
||||
0x00000005,
|
||||
orig,
|
||||
0x80a3005c,
|
||||
0x38a50003,
|
||||
0x54a0003a,
|
||||
0x3ca0817f,
|
||||
0x900500b8,
|
||||
0x38000000 | (frame & 0xffff),
|
||||
0x900500bc,
|
||||
0x60000000,
|
||||
0x00000000,
|
||||
]
|
||||
.map(int32)
|
||||
.join('');
|
||||
} else {
|
||||
// handle regular freezing code later
|
||||
freezeEnableds.push(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// handle regular freezing code
|
||||
if (freezeConfigs.length <= 1) {
|
||||
if (freezeEnableds.length <= 1) {
|
||||
// use C2 directly
|
||||
code += freezeConfigs
|
||||
.flatMap(({ frame, addr, orig }) => [
|
||||
code += freezeEnableds
|
||||
.flatMap(({ addr, orig }) => [
|
||||
0xc2000000 + (addr & 0x1ffffff),
|
||||
0x00000004,
|
||||
0x39600000 | (frame & 0xffff), // li r11, frame
|
||||
0x3d80817f, // lis r12, 0x817F
|
||||
0x916c00bc, // stw r11, 0xBC(r12)
|
||||
orig,
|
||||
0x816d0000 | (r13off & 0xffff), // lwz r11, r13off(r13)
|
||||
0x3d80817f, // lis r12, 0x817F
|
||||
0x816b005c, // lwz r11, 0x5C(r11)
|
||||
0x916c00b8, // stw r11, 0xB8(r12)
|
||||
orig,
|
||||
0x39600000 | (frame & 0xffff), // li r11, frame
|
||||
0x916c00bc, // stw r11, 0xBC(r12)
|
||||
0x00000000,
|
||||
])
|
||||
.map(int32)
|
||||
.join('');
|
||||
} else {
|
||||
let dst = freezeCodeAddr + 24;
|
||||
const code04 = [];
|
||||
const code07 = [
|
||||
0x3d80817f, // lis r12, 0x817F
|
||||
0x916c00bc, // stw r11, 0xBC(r12)
|
||||
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)
|
||||
0x4e800020, // blr
|
||||
];
|
||||
let dst = freezeCodeAddr + code07.length * 4;
|
||||
// put code together
|
||||
for (const { frame, addr, orig } of freezeConfigs) {
|
||||
for (const { addr, orig } of freezeEnableds) {
|
||||
code07.push(
|
||||
orig, // [dst] original instruction
|
||||
0x39600000 | (frame & 0xffff), // li r11, $frame
|
||||
0x4c000000 + (freezeCodeAddr - dst - 8), // b freezeCode
|
||||
0x4c000000 + (freezeCodeAddr - dst - 4), // b freezeCode
|
||||
);
|
||||
code04.push(
|
||||
0x04000000 | (addr & 0x1ffffff), // 04 addr
|
||||
0x48000001 | (dst - addr), // bl dst
|
||||
);
|
||||
dst += 12;
|
||||
dst += 8;
|
||||
}
|
||||
// make 07 code
|
||||
code07.unshift(
|
||||
|
|
|
@ -41,15 +41,15 @@
|
|||
</section>
|
||||
<section class="freeze">
|
||||
<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}}
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<th v-for="s in l.freeze.th" :key="s">{{s}}</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="key in freezeKeys" :key="key">
|
||||
<td>{{l.freeze.rows[key]}}</td>
|
||||
<td><input type="number" :value="freeze[key]" @change="onChangeFreeze($event, key)"></td>
|
||||
<td class="right">{{(freeze[key]*1001/30000).toFixed(2)}}</td>
|
||||
<td><input type="checkbox" :checked="freeze[key]" @change="onChangeFreeze($event, key)"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -63,9 +63,9 @@ import labels from './labels.json';
|
|||
import {getLabels} from '../codegen.js';
|
||||
|
||||
function updateConfig() {
|
||||
const {x, y, fontSize, width, fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA, freeze} = this;
|
||||
const {x, y, fontSize, width, fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA, freeze, freezeDuration} = this;
|
||||
localStorage.setItem(lskey, JSON.stringify({
|
||||
x, y, fontSize, width, fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA, freeze,
|
||||
x, y, fontSize, width, fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA, freeze, freezeDuration
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ export default {
|
|||
methods: {
|
||||
updateConfig,
|
||||
onChangeFreeze($event, key) {
|
||||
this.freeze[key] = parseInt($event.target.value);
|
||||
this.freeze[key] = $event.target.checked;
|
||||
this.updateConfig();
|
||||
},
|
||||
toggleGradient($event) {
|
||||
|
@ -93,11 +93,11 @@ export default {
|
|||
rgbaI2S: (rgb, a) => '#'+rgb.toString(16).padStart(6, '0')+a.toString(16).padStart(2, '0'),
|
||||
},
|
||||
data() {
|
||||
const {x, y, fontSize, width, fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA, freeze} = getConfig();
|
||||
const {x, y, fontSize, width, fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA, freeze, freezeDuration} = getConfig();
|
||||
return {
|
||||
x, y, fontSize, width,
|
||||
fgRGB, fgA, fgRGB2, fgA2, bgRGB, bgA,
|
||||
freeze,
|
||||
freeze, freezeDuration,
|
||||
// const
|
||||
freezeKeys: Object.keys(codes[this.version]?.freezeCodeInfo ?? {}),
|
||||
};
|
||||
|
@ -118,6 +118,7 @@ export default {
|
|||
fgA2: updateConfig,
|
||||
bgRGB: updateConfig,
|
||||
bgA: updateConfig,
|
||||
freezeDuration: updateConfig,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@ -126,7 +127,7 @@ export default {
|
|||
input[type=number], td.right {
|
||||
text-align: right;
|
||||
}
|
||||
.appearance input[type="number"] {
|
||||
input[type="number"] {
|
||||
width: 3em;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
@ -134,15 +135,6 @@ input[type=number], td.right {
|
|||
padding: 0 0 4px;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: center;
|
||||
}
|
||||
td > input[type=number] {
|
||||
width: 8em;
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input[type=number] {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
"previewNote": "※ x座標の範囲は0~600、y座標の範囲は16~464です\n※ ゲーム内のフォントはプレビューのより幅が広いです",
|
||||
"freeze": {
|
||||
"h3": "一時停止",
|
||||
"th": ["タイミング", "停止フレーム数", "停止秒数"],
|
||||
"duration": "長さ:",
|
||||
"frame": "(フレーム)",
|
||||
"sec": "(秒)",
|
||||
"rows": {
|
||||
"yellowCoin": "黄コインを取った時",
|
||||
"redCoin": "赤コインを取った時",
|
||||
|
@ -40,7 +42,9 @@
|
|||
"previewNote": "※ x ranges from 0 to 600, and y ranges from 16 to 464.\n※ The font is wider in the game compared to the preview.",
|
||||
"freeze": {
|
||||
"h3": "Freezing the timer",
|
||||
"th": ["Timing", "Duration(frame)", "Duration(sec)"],
|
||||
"duration": "Duration: ",
|
||||
"frame": "(frame)",
|
||||
"sec": "(sec)",
|
||||
"rows": {
|
||||
"yellowCoin": "When collected a yellow coin",
|
||||
"redCoin": "When collected a red coin",
|
||||
|
|
Loading…
Reference in a new issue