add stage loader code generator
This commit is contained in:
parent
df1aef2c11
commit
e2b9e2bd44
6 changed files with 224 additions and 29 deletions
|
@ -1,5 +1,9 @@
|
|||
<template>
|
||||
<ButtonComponent label="Download" :onClick="onClick" :disabled="!codes || codes.length === 0" />
|
||||
<ButtonComponent
|
||||
label="Download"
|
||||
:onClick="onClick"
|
||||
:disabled="(!codes || codes.length === 0) && !stageLoaderCode"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -9,33 +13,39 @@ import CodeFormatter from "./scripts/codeFormatter";
|
|||
export default {
|
||||
props: {
|
||||
codes: { type: Array },
|
||||
stageLoaderCode: { type: String },
|
||||
format: { type: String },
|
||||
versionIdentifier: { type: String }
|
||||
versionIdentifier: { type: String },
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
if (!this.codes || this.codes.length === 0) {
|
||||
if (!(this.codes || this.codes.length === 0) && !this.stageLoaderCode) {
|
||||
return;
|
||||
}
|
||||
const c = [...(this.codes ?? [])];
|
||||
|
||||
if (this.stageLoaderCode)
|
||||
c.push({
|
||||
title: "Stage List Loader",
|
||||
author: "Noki Doki",
|
||||
date: "-",
|
||||
version: "",
|
||||
source: this.stageLoaderCode,
|
||||
});
|
||||
|
||||
console.log(`Preparing download for ${this.format}`);
|
||||
switch (this.format) {
|
||||
case "gct":
|
||||
CodeFormatter.generateGCT(this.codes, this.versionIdentifier);
|
||||
CodeFormatter.generateGCT(c, this.versionIdentifier);
|
||||
break;
|
||||
case "dolphin":
|
||||
CodeFormatter.generateDolphinINI(this.codes, this.versionIdentifier);
|
||||
CodeFormatter.generateDolphinINI(c, this.versionIdentifier);
|
||||
break;
|
||||
case "gcm":
|
||||
CodeFormatter.generateCheatManagerTXT(
|
||||
this.codes,
|
||||
this.versionIdentifier
|
||||
);
|
||||
CodeFormatter.generateCheatManagerTXT(c, this.versionIdentifier);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
<template>
|
||||
<SelectComponent :options="options" :onChange="onChange" />
|
||||
<SelectComponent
|
||||
placeholder="Choose Format"
|
||||
:options="options"
|
||||
:selectedValue="selectedValue"
|
||||
:onChange="onChange"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components
|
||||
import SelectComponent from "./SelectComponent";
|
||||
|
||||
// Data
|
||||
import downloadFormats from "../data/downloadFormats.json";
|
||||
|
||||
export default {
|
||||
|
@ -12,9 +19,6 @@ export default {
|
|||
selectedValue: { type: String },
|
||||
onChange: { type: Function },
|
||||
},
|
||||
mounted() {
|
||||
this.onChange(downloadFormats[0].target);
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: downloadFormats.map((v) => ({
|
||||
|
|
|
@ -6,28 +6,38 @@
|
|||
<section class="config">
|
||||
<div>
|
||||
<span>Game Version:</span>
|
||||
<VersionSelect :onChange="onVersionChanged" />
|
||||
<VersionSelect
|
||||
:onChange="onVersionChanged"
|
||||
:selectedValue="selectedVersion"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<span>Download Format:</span>
|
||||
<FormatSelect :onChange="onFormatChanged" />
|
||||
<FormatSelect
|
||||
:onChange="onFormatChanged"
|
||||
:selectedValue="selectedFormat"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<span>Use Stage Loader:</span>
|
||||
<SelectComponent
|
||||
:options="useStageLoaderOptions"
|
||||
:onChange="onStageLoaderChanged"
|
||||
:value="useStageLoader"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<span>Download:</span>
|
||||
<DownloadButton
|
||||
:codes="selectedCheats"
|
||||
:stageLoaderCode="selectedStageLoader"
|
||||
:versionIdentifier="selectedVersion"
|
||||
:format="selectedFormat"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
<br />
|
||||
<hr />
|
||||
<section>
|
||||
<div v-if="codes && codes.length > 0">
|
||||
<h3>Available Codes</h3>
|
||||
|
@ -42,7 +52,10 @@
|
|||
v-if="codes && codes.length > 0 && useStageLoader"
|
||||
>
|
||||
<h3>Stage Loader</h3>
|
||||
<StageLoader :fastCodes="stageLoaderCodes" />
|
||||
<StageLoader
|
||||
:fastCodes="stageLoaderCodes"
|
||||
:onChange="onStageLoaderCodeChanged"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="codes && codes.length > 0" class="help">
|
||||
|
@ -126,7 +139,7 @@ import DownloadButton from "./DownloadButton";
|
|||
// Data
|
||||
import gameVersions from "../data/gameVersions.json";
|
||||
|
||||
// Helpers
|
||||
// Util
|
||||
import parseXml from "./scripts/parseXml";
|
||||
|
||||
// Libs
|
||||
|
@ -157,7 +170,7 @@ export default {
|
|||
selectedStageLoader: null,
|
||||
inspectingCode: null,
|
||||
selectedVersion: null,
|
||||
selectedFormat: null,
|
||||
selectedFormat: "gct",
|
||||
useStageLoader: false,
|
||||
stageLoaderCodes: [],
|
||||
useStageLoaderOptions: [
|
||||
|
@ -182,10 +195,14 @@ export default {
|
|||
},
|
||||
onStageLoaderChanged(e) {
|
||||
this.useStageLoader = e === true || e === "true";
|
||||
if (!this.useStageLoader) this.selectedStageLoader = null;
|
||||
},
|
||||
onCheatSelectionChanged(e) {
|
||||
this.selectedCheats = e;
|
||||
},
|
||||
onStageLoaderCodeChanged(e) {
|
||||
this.selectedStageLoader = e;
|
||||
},
|
||||
inspect(code) {
|
||||
this.inspectingCode = code;
|
||||
},
|
||||
|
|
|
@ -96,12 +96,16 @@ import GroupSelectComponent from "./GroupSelectComponent";
|
|||
import stageLoaderLevels from "../data/stageLoaderLevels.json";
|
||||
import stageLoaderPresets from "../data/stageLoaderPresets.json";
|
||||
|
||||
// Util
|
||||
import generateStageLoaderCode from "./scripts/generateStageLoadercode";
|
||||
|
||||
// Lib
|
||||
import draggable from "vuedraggable";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
fastCodes: { type: Object },
|
||||
onChange: { type: Function },
|
||||
},
|
||||
components: {
|
||||
draggable,
|
||||
|
@ -132,39 +136,46 @@ export default {
|
|||
{ value: "3400", label: "Load post-Corona plaza" },
|
||||
{ value: "3C00", label: "Load the Bowser fight" },
|
||||
],
|
||||
removeDialogSelection: null,
|
||||
skippableFMVsSelection: null,
|
||||
levelOrderSelection: null,
|
||||
postGameSelection: null,
|
||||
removeDialogSelection: "yes",
|
||||
skippableFMVsSelection: "yes",
|
||||
levelOrderSelection: "list",
|
||||
postGameSelection: "0F00",
|
||||
generation: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onRemoveDialogueSelectionChanged(e) {
|
||||
this.removeDialogSelection = e;
|
||||
this.updateCode();
|
||||
},
|
||||
onSkippableFMVsSelectionChanged(e) {
|
||||
this.skippableFMVsSelection = e;
|
||||
this.updateCode();
|
||||
},
|
||||
onLevelOrderSelectionChanged(e) {
|
||||
this.levelOrderSelection = e;
|
||||
this.updateCode();
|
||||
},
|
||||
onPostGameSelectionChanged(e) {
|
||||
this.postGameSelection = e;
|
||||
this.updateCode();
|
||||
},
|
||||
onStageLoaderLevelSelected(e) {
|
||||
this.generation++;
|
||||
this.selectedRoute.push({
|
||||
value: e,
|
||||
});
|
||||
this.updateCode();
|
||||
},
|
||||
onStageLoaderLevelChanged(index, e) {
|
||||
this.selectedRoute[index] = {
|
||||
value: e,
|
||||
};
|
||||
this.updateCode();
|
||||
},
|
||||
onLevelDeleted(e) {
|
||||
this.selectedRoute.splice(e, 1);
|
||||
this.updateCode();
|
||||
},
|
||||
onStageLoaderPresetSelected(e) {
|
||||
this.generation++;
|
||||
|
@ -185,7 +196,9 @@ export default {
|
|||
newRoute.push({ value: preset.substr(i, 4) });
|
||||
|
||||
this.selectedRoute = newRoute;
|
||||
this.postGameSelection = ending;
|
||||
|
||||
if (ending) this.postGameSelection;
|
||||
this.updateCode();
|
||||
},
|
||||
onClearList() {
|
||||
if (
|
||||
|
@ -195,9 +208,31 @@ export default {
|
|||
return;
|
||||
|
||||
this.selectedRoute = [];
|
||||
this.updateCode();
|
||||
},
|
||||
checkMove(e) {
|
||||
window.console.log("Future index: " + e.draggedContext.futureIndex);
|
||||
updateCode() {
|
||||
if (
|
||||
this.selectedRoute.length === 0 ||
|
||||
this.levelOrderSelection == null ||
|
||||
this.postGameSelection == null ||
|
||||
this.skippableFMVsSelection == null ||
|
||||
this.removeDialogSelection == null
|
||||
) {
|
||||
this.onChange(null);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Generating new Stageloader-Code");
|
||||
this.onChange(
|
||||
generateStageLoaderCode(
|
||||
this.fastCodes,
|
||||
this.selectedRoute.map((v) => v.value),
|
||||
this.levelOrderSelection,
|
||||
this.postGameSelection,
|
||||
this.skippableFMVsSelection,
|
||||
this.removeDialogSelection
|
||||
)
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -208,6 +243,7 @@ export default {
|
|||
display: block;
|
||||
margin-bottom: 5px;
|
||||
padding-left: 2px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.config:not(:first-child) span {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<SelectComponent
|
||||
placeholder="Choose Version.."
|
||||
:selectedValue="selectedValue"
|
||||
:options="options"
|
||||
:onChange="onChange"
|
||||
/>
|
||||
|
|
127
docs/.vuepress/components/scripts/generateStageLoadercode.js
Normal file
127
docs/.vuepress/components/scripts/generateStageLoadercode.js
Normal file
|
@ -0,0 +1,127 @@
|
|||
const generateStageLoaderCode = (
|
||||
gameConfig,
|
||||
selectedLevels,
|
||||
routeOrder,
|
||||
routeEnding,
|
||||
fmvSkips,
|
||||
dialgueSkips
|
||||
) => {
|
||||
const loadStageLength = {
|
||||
list: 0x20,
|
||||
random: 0x2c,
|
||||
shuffle: 0x40,
|
||||
}[routeOrder];
|
||||
|
||||
let codes = "";
|
||||
|
||||
// Reset counter on file select
|
||||
codes +=
|
||||
"0" +
|
||||
(0x04000000 + (gameConfig.fileSelect & 0x01ffffff)).toString(16) +
|
||||
(
|
||||
0x48000001 +
|
||||
((gameConfig.system + 0x52c - gameConfig.fileSelect) & 0x03fffffc)
|
||||
).toString(16);
|
||||
|
||||
// Load next stage on Shine get
|
||||
codes +=
|
||||
"0" +
|
||||
(0x04000000 + (gameConfig.shineGet & 0x01ffffff)).toString(16) +
|
||||
(
|
||||
0x48000001 +
|
||||
((gameConfig.system + 0x53c - gameConfig.shineGet) & 0x03fffffc)
|
||||
).toString(16);
|
||||
|
||||
// Reload stage on exit area
|
||||
codes +=
|
||||
"0" +
|
||||
(0x04000000 + (gameConfig.system & 0x01ffffff)).toString(16) +
|
||||
"48000511";
|
||||
|
||||
// Set next stage on game over
|
||||
codes +=
|
||||
"0" +
|
||||
(0x06000000 + ((gameConfig.system + 0xb4) & 0x01ffffff)).toString(16) +
|
||||
"000000084800048948000044";
|
||||
|
||||
// Reset timer on secret death
|
||||
codes +=
|
||||
(0xc2000000 + ((gameConfig.system + 0x208) & 0x01ffffff)).toString(16) +
|
||||
"000000033C60817F38000001980300FF881C00006000000000000000";
|
||||
|
||||
// Reset coin count on loading main world
|
||||
codes +=
|
||||
(0xc2000000 + ((gameConfig.shineGet - 0x674) & 0x01ffffff)).toString(16) +
|
||||
"00000005887D00002C030002418000142C0300074182000C2C03000A418000087C0400406000000000000000";
|
||||
|
||||
// Overwrite decideNextStage(void) with useful routines
|
||||
codes +=
|
||||
"0" +
|
||||
(0x06000000 + ((gameConfig.system + 0x510) & 0x01ffffff)).toString(16) +
|
||||
("0000000" + (loadStageLength + 0x5c).toString(16)).slice(-8) +
|
||||
"3C60817F38000001980300FFA00300023C60" +
|
||||
gameConfig.gpAppHi +
|
||||
"B003" +
|
||||
gameConfig.gpAppLo +
|
||||
"4E800020" + // reload current level
|
||||
"3C60817F" +
|
||||
(0x38800000 + ((selectedLevels.length * 2) & 0x0000ffff)).toString(16) +
|
||||
"B08300004E800020" + // reset counter
|
||||
"3C60817F38000001980300FFA00300002C00000038E0" +
|
||||
routeEnding + // load next stage - the fun begins
|
||||
(0x40810000 + (loadStageLength & 0x0000fffc)).toString(16) +
|
||||
"7C8802A6600000007CC802A67C8803A6";
|
||||
|
||||
switch (routeOrder) {
|
||||
case "list":
|
||||
codes += "3400FFFEB00300007CE6022E";
|
||||
break;
|
||||
case "random":
|
||||
codes += "7C8C42E67CA403967CA501D67C8520505484003C7CE6222E";
|
||||
break;
|
||||
case "shuffle":
|
||||
codes +=
|
||||
"7C8C42E67CA403967CA501D67C8520505484003C3400FFFEB00300007CE6222E7CA6022E7CA6232E7CE6032E";
|
||||
}
|
||||
|
||||
codes +=
|
||||
"B0E300023C60" +
|
||||
gameConfig.gpAppHi +
|
||||
"B0E3" +
|
||||
gameConfig.gpAppLo +
|
||||
"806D" +
|
||||
gameConfig.fmOffset +
|
||||
"98E300DF4E800020" +
|
||||
(routeOrder === "random" ? "" : "00000000");
|
||||
|
||||
selectedLevels.reverse();
|
||||
|
||||
while (selectedLevels.length % 4) selectedLevels.push("0000");
|
||||
|
||||
// Insert the list of levels into the loader
|
||||
codes +=
|
||||
(0xc2000000 + ((gameConfig.system + 0x55c) & 0x01ffffff)).toString(16) +
|
||||
("0000000" + (selectedLevels.length / 4 + 1).toString(16)).slice(-8) +
|
||||
(0x48000001 + ((selectedLevels.length * 2 + 4) & 0x03fffffc)).toString(16) +
|
||||
selectedLevels.join("") +
|
||||
"00000000";
|
||||
|
||||
// Load next stage on setNextStage into main level
|
||||
codes +=
|
||||
"0" +
|
||||
(0x06000000 + ((gameConfig.system + 0x118c) & 0x01ffffff)).toString(16) +
|
||||
"00000028B07D00143C80817F38000000B00400FFA0010038B01D00122C1C00094181000C4BFFF391B0E10038";
|
||||
|
||||
// Setup timer
|
||||
codes +=
|
||||
(0xc2000000 + (gameConfig.proc & 0x01ffffff)).toString(16) +
|
||||
"000000053CA0817F388000009085010C880500FF98050100988500FF38800001988501016000000000000000";
|
||||
|
||||
codes = codes.toUpperCase();
|
||||
|
||||
codes += gameConfig.notext[dialgueSkips] + gameConfig.nofmvs[fmvSkips];
|
||||
|
||||
return codes;
|
||||
};
|
||||
|
||||
export default generateStageLoaderCode;
|
Loading…
Reference in a new issue