diff --git a/Codes.xml b/Codes.xml
index 75fc64d..0899928 100644
--- a/Codes.xml
+++ b/Codes.xml
@@ -4764,4 +4764,315 @@
4E800021 00000000
+
+ controller
+ metadata
+ Controller Input Display
+ コントローラ入力表示
+ sup39(サポミク)
+ 0.1
+ Feb 05, 2023
+
+ Display controller input.
+
+
+ コントローラ入力を表示します。
+
+
+
+
+
+
diff --git a/changelog.md b/changelog.md
index 3e6845c..fb070c3 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,7 @@
# Changelog
## Feb 05, 2023
+### Created 'Controller Input Display'
+Display controller input
### Created 'Attempt Counter'
Display attempt count and success count of current area
### Updated 'Instant Level Select'
diff --git a/site/.vuepress/components/Preview.vue b/site/.vuepress/components/Preview.vue
index 8e65974..b9a357a 100644
--- a/site/.vuepress/components/Preview.vue
+++ b/site/.vuepress/components/Preview.vue
@@ -3,13 +3,21 @@
+
+
diff --git a/site/.vuepress/components/codes/controller/hidden.js b/site/.vuepress/components/codes/controller/hidden.js
new file mode 100644
index 0000000..812ad2f
--- /dev/null
+++ b/site/.vuepress/components/codes/controller/hidden.js
@@ -0,0 +1,66 @@
+export const buttons = [
+ { x: 138, y: 66, r: 18, id: 'A', c: 0x2ee5b8bf },
+ { x: 113, y: 89, r: 9, id: 'B', c: 0xff1a1abf },
+ { x: 164, y: 50, r: 8, id: 'X', c: 0xeeeeeebf },
+ { x: 119, y: 41, r: 8, id: 'Y', c: 0xeeeeeebf },
+ { x: 144, y: 34, r: 6, id: 'Z', c: 0x9494ffbf },
+ { x: 91, y: 64, r: 5, id: 'S', c: 0xeeeeeebf },
+];
+
+export const sticks = [
+ {
+ id: 'M',
+ x: 32,
+ y: 52,
+ rMove: 14,
+ rS: 19,
+ cS: 0xeeeeeeef,
+ rF: 12,
+ cF: 0xeeeeeeef,
+ },
+ {
+ id: 'C',
+ x: 64,
+ y: 92,
+ rMove: 14,
+ rS: 19,
+ cS: 0xffd300ef,
+ rF: 12,
+ cF: 0xffd300ef,
+ },
+];
+
+export const triggers = [
+ {
+ id: 'L',
+ x: 12,
+ y0: 10,
+ y1: 18,
+ w: 64,
+ wa: 56,
+ },
+ {
+ id: 'R',
+ x: 170,
+ y0: 10,
+ y1: 18,
+ w: -64,
+ wa: -56,
+ },
+];
+
+export default {
+ // background
+ bgLeft: 0,
+ bgRight: 182,
+ bgTop: 0,
+ bgBot: 120,
+ // trigger fill
+ cTF: 0xdfdfdfbf,
+ // trigger stroke
+ cTS: 0xeeeeeebf,
+ // input
+ buttons,
+ triggers,
+ sticks,
+};
diff --git a/site/.vuepress/components/codes/controller/preview.vue b/site/.vuepress/components/codes/controller/preview.vue
new file mode 100644
index 0000000..cf9ec68
--- /dev/null
+++ b/site/.vuepress/components/codes/controller/preview.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
diff --git a/site/.vuepress/components/codes/controller/utils.js b/site/.vuepress/components/codes/controller/utils.js
new file mode 100644
index 0000000..1fb4c99
--- /dev/null
+++ b/site/.vuepress/components/codes/controller/utils.js
@@ -0,0 +1,37 @@
+import { int2hex } from '../utils.js';
+
+/** @type {Record} */
+export const SHIFTS = {
+ Z: 32 - 4,
+ R: 32 - 5,
+ L: 32 - 6,
+ A: 32 - 8,
+ B: 32 - 9,
+ X: 32 - 10,
+ Y: 32 - 11,
+ S: 32 - 12,
+};
+
+/**
+ * @param {number} x0
+ * @param {number} y0
+ * @param {number} x1
+ * @param {number} y1
+ */
+export const makeRect = (x0, y0, x1, y1) => [x0, y0, x1, y1].map((x) => int2hex(x, 1)).join('');
+
+/**
+ * @param {number} x
+ * @param {number} y
+ * @param {number} r
+ * @param {number} s
+ * @param {number} color
+ */
+export const makeNgon = (x, y, r, s, color) =>
+ [x, y, r, s].map((x) => int2hex(x, 1)).join('') + int2hex(color, 4);
+
+/**
+ * @param {number} shift
+ * @param {number} WA
+ */
+export const makeTriggerInfo = (shift, WA) => [shift, WA].map((x) => int2hex(x, 1)).join('');
diff --git a/site/.vuepress/components/codes/labels.json b/site/.vuepress/components/codes/labels.json
index 9fa231e..80dc8ed 100644
--- a/site/.vuepress/components/codes/labels.json
+++ b/site/.vuepress/components/codes/labels.json
@@ -12,6 +12,7 @@
"alpha": "不透明度=",
"bgColor": "背景色:",
"bgOffset": "背景位置:",
+ "size": "サイズ:",
"left": "左",
"right": "右",
"top": "上",
@@ -35,6 +36,7 @@
"alpha": "Alpha=",
"bgColor": "Background color: ",
"bgOffset": "Background offset: ",
+ "size": "Size: ",
"left": "Left",
"right": "Right",
"top": "Top",
diff --git a/site/.vuepress/components/codes/preview.js b/site/.vuepress/components/codes/preview.js
index fdf3381..5ffa598 100644
--- a/site/.vuepress/components/codes/preview.js
+++ b/site/.vuepress/components/codes/preview.js
@@ -3,8 +3,16 @@ import * as qfst from './qfst/codegen.js';
import * as CustomizedDisplay from './CustomizedDisplay/codegen.js';
import * as PatternSelector from './PatternSelector/codegen.js';
import * as AttemptCounter from './AttemptCounter/codegen.js';
+import * as controller from './controller/codegen.js';
-export const previewIds = ['CustomizedDisplay', 'AttemptCounter', 'PatternSelector', 'qft', 'qfst'];
+export const previewIds = [
+ 'CustomizedDisplay',
+ 'AttemptCounter',
+ 'PatternSelector',
+ 'qft',
+ 'qfst',
+ 'controller',
+];
/**
* Get code configs for preview
@@ -18,5 +26,6 @@ export const getConfigs = (version) =>
CustomizedDisplay,
PatternSelector,
AttemptCounter,
+ controller,
}).map(([k, v]) => [k, v.getConfig(version)]),
);
diff --git a/site/.vuepress/components/codes/ui.js b/site/.vuepress/components/codes/ui.js
index c8f861b..b89c396 100644
--- a/site/.vuepress/components/codes/ui.js
+++ b/site/.vuepress/components/codes/ui.js
@@ -4,6 +4,7 @@ import PatternSelector from './PatternSelector/config.vue';
import qft from './qft/config.vue';
import qfst from './qfst/config.vue';
import AttemptCounter from './AttemptCounter/config.vue';
+import controller from './controller/config.vue';
export default {
InstantRestart,
@@ -12,4 +13,5 @@ export default {
qft,
qfst,
AttemptCounter,
+ controller,
};
diff --git a/site/.vuepress/components/codes/utils.js b/site/.vuepress/components/codes/utils.js
index c89b774..397dfac 100644
--- a/site/.vuepress/components/codes/utils.js
+++ b/site/.vuepress/components/codes/utils.js
@@ -2,9 +2,10 @@
* @template T extends {Record|Record[]}
* @param {string} lskey
* @param {T} defaultConfig
- * @param {(config: T)=>string} [makeText]
+ * @param {((config: T)=>string)|null} [makeText]
+ * @param {any} [hiddenConfig]
*/
-export function makeUpdateConfig(lskey, defaultConfig, makeText) {
+export function makeUpdateConfig(lskey, defaultConfig, makeText, hiddenConfig = {}) {
const configKeys = Object.keys(defaultConfig);
/** @type {(o: any)=>T} */
const makeConfig =
@@ -18,7 +19,8 @@ export function makeUpdateConfig(lskey, defaultConfig, makeText) {
const config = makeConfig(this);
localStorage.setItem(lskey, JSON.stringify(config));
// emit `config` event to parent
- this.$emit('config', makeText ? { ...config, text: makeText(config) } : config);
+ const configEmit = { ...hiddenConfig, ...config };
+ this.$emit('config', makeText ? { ...configEmit, text: makeText(config) } : configEmit);
};
}
@@ -33,6 +35,15 @@ export const int2hex = (x, size) =>
.padStart(size << 1, '0')
.slice(-(size << 1));
+/**
+ * @param {number} x -- number to convert
+ */
+export function float2hex(x) {
+ const dv = new DataView(new ArrayBuffer(4));
+ dv.setFloat32(0, x);
+ return int2hex(dv.getUint32(0), 4);
+}
+
/** @param {number} rgb */
export const rgbI2S = (rgb) => '#' + rgb.toString(16).padStart(6, '0');
/** @param {string} s */
@@ -43,6 +54,8 @@ export const rgbS2I = (s) => parseInt(s.slice(1), 16);
*/
export const rgbaI2S = (rgb, a) =>
'#' + rgb.toString(16).padStart(6, '0') + a.toString(16).padStart(2, '0');
+/** @param {number} rgba */
+export const cI2S = (rgba) => '#' + (rgba >>> 0).toString(16).padStart(8, '0');
/** @type {(labels: Record, locale: string, fallbackLocale?: string) => (key: string) => string} */
export const makeGetLabel =
diff --git a/site/.vuepress/data/codeCategories.json b/site/.vuepress/data/codeCategories.json
index c6492c3..af70781 100644
--- a/site/.vuepress/data/codeCategories.json
+++ b/site/.vuepress/data/codeCategories.json
@@ -17,7 +17,7 @@
{
"identifier": "metadata",
"i18nKey": "generatorconfig.categories.metadata",
- "exclusive": true
+ "exclusive": false
},
{
"identifier": "misc",