danoniplus 47.5.3 → 47.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/js/danoni_main.js +669 -8
- package/js/lib/danoni_constants.js +26 -4
- package/package.json +1 -1
package/js/danoni_main.js
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Source by tickle
|
|
6
6
|
* Created : 2018/10/08
|
|
7
|
-
* Revised : 2026/05/
|
|
7
|
+
* Revised : 2026/05/13
|
|
8
8
|
*
|
|
9
9
|
* https://github.com/cwtickle/danoniplus
|
|
10
10
|
*/
|
|
11
|
-
const g_version = `Ver 47.
|
|
12
|
-
const g_revisedDate = `2026/05/
|
|
11
|
+
const g_version = `Ver 47.6.1`;
|
|
12
|
+
const g_revisedDate = `2026/05/13`;
|
|
13
13
|
|
|
14
14
|
// カスタム用バージョン (danoni_custom.js 等で指定可)
|
|
15
15
|
let g_localVersion = ``;
|
|
@@ -10194,6 +10194,9 @@ const keyConfigInit = (_kcType = g_kcType) => {
|
|
|
10194
10194
|
// カーソル位置の初期化
|
|
10195
10195
|
appearConfigSteps(g_keycons.keySwitchNum);
|
|
10196
10196
|
|
|
10197
|
+
keyconfigKeyboardPreview.dispose();
|
|
10198
|
+
keyconfigKeyboardPreview.init(divRoot);
|
|
10199
|
+
|
|
10197
10200
|
// ラベル・ボタン描画
|
|
10198
10201
|
multiAppend(divRoot,
|
|
10199
10202
|
|
|
@@ -10342,6 +10345,664 @@ const keyConfigInit = (_kcType = g_kcType) => {
|
|
|
10342
10345
|
document.oncontextmenu = () => false;
|
|
10343
10346
|
};
|
|
10344
10347
|
|
|
10348
|
+
/**
|
|
10349
|
+
* キーボードレイアウトプレビュー(Canvas版)
|
|
10350
|
+
*
|
|
10351
|
+
* キーコンフィグ画面(divRoot)配下に以下の要素を追加する:
|
|
10352
|
+
* - [Preview] ボタン (createCss2Button)
|
|
10353
|
+
* - プレビュー用コンテナ div (createEmptySprite)
|
|
10354
|
+
* ├ キーボード背景 canvas (_state.canvasBase) ← 起動時のみ描画
|
|
10355
|
+
* └ マッピング強調 canvas (_state.canvasMap) ← キー変更・表示時に再描画
|
|
10356
|
+
*
|
|
10357
|
+
* 前提:
|
|
10358
|
+
* - g_kCd : グローバル定義済み。ロケール切替後は g_lang_kCd がマージ済み。
|
|
10359
|
+
* 未設定キーは空文字列 `""` で初期化。
|
|
10360
|
+
* 右Shift/Ctrl/Alt は 256/257/258 の独自コードで定義。
|
|
10361
|
+
* - g_btnWidth() : 画面の横幅(px)を返すグローバル関数。
|
|
10362
|
+
* - g_sHeight : 画面の縦幅(px)を保持するグローバル変数。
|
|
10363
|
+
* - createCss2Button, createEmptySprite : danoniplus 本体のグローバル関数。
|
|
10364
|
+
*
|
|
10365
|
+
* 使い方:
|
|
10366
|
+
* 【初期化時】
|
|
10367
|
+
* keyconfigKeyboardPreview.init(divRoot);
|
|
10368
|
+
*
|
|
10369
|
+
* 【キー割り当てが変わった時】
|
|
10370
|
+
* keyconfigKeyboardPreview.refresh();
|
|
10371
|
+
* ※ g_keyObj.currentKey / currentPtn から自動取得する
|
|
10372
|
+
*
|
|
10373
|
+
* 【キーコンフィグ画面を離脱する時】
|
|
10374
|
+
* keyconfigKeyboardPreview.dispose();
|
|
10375
|
+
*/
|
|
10376
|
+
|
|
10377
|
+
const keyconfigKeyboardPreview = (() => {
|
|
10378
|
+
|
|
10379
|
+
// -------------------------------------------------------------------------
|
|
10380
|
+
// 定数
|
|
10381
|
+
// -------------------------------------------------------------------------
|
|
10382
|
+
const C_PREVIEW_ID = `kbPreviewArea`;
|
|
10383
|
+
const C_BTN_ID = `btnKbPreview`;
|
|
10384
|
+
const C_CANVAS_BASE_ID = `kbCanvasBase`;
|
|
10385
|
+
const C_CANVAS_MAP_ID = `kbCanvasMap`;
|
|
10386
|
+
|
|
10387
|
+
// 色定義(既存ゲームの配色に合わせたダーク系)
|
|
10388
|
+
const C_COLOR = {
|
|
10389
|
+
keyFill: `#1a1a2e`, // 通常キー背景
|
|
10390
|
+
keyStroke: `#555577`, // 通常キー枠
|
|
10391
|
+
keyText: `#ccccdd`, // 通常キー文字
|
|
10392
|
+
keySubText: `#888899`, // サブラベル(Shift面)
|
|
10393
|
+
mappedFill: `#003366`, // メインキー背景
|
|
10394
|
+
mappedStroke: `#4488ff`, // メインキー枠
|
|
10395
|
+
mappedText: `#aaddff`, // メインキー文字
|
|
10396
|
+
altFill: `#3e3e1a`, // 代替キー背景
|
|
10397
|
+
altStroke: `#777755`, // 代替キー枠
|
|
10398
|
+
altText: `#eeeecc`, // 代替キー文字
|
|
10399
|
+
shortcutFill: `#330011`, // ショートカットキー背景
|
|
10400
|
+
shortcutStroke: `#ff4466`, // ショートカットキー枠
|
|
10401
|
+
shortcutText: `#ffaacc`, // ショートカットキー文字
|
|
10402
|
+
bgFill: `#0d0d1a`, // Canvas 背景
|
|
10403
|
+
legendText: `#888899`, // 凡例テキスト
|
|
10404
|
+
};
|
|
10405
|
+
|
|
10406
|
+
// ボタン配置
|
|
10407
|
+
// X・W は init() 内で動的計算(g_btnWidth() 依存)
|
|
10408
|
+
// Y: KeyConfig テキスト上の余白に収まるよう小さく設定
|
|
10409
|
+
const BTN_H = 18; // ボタン高さ
|
|
10410
|
+
const BTN_Y = 3; // divRoot 内 Y 座標
|
|
10411
|
+
const BTN_FS = 11; // ボタンのフォントサイズ(px)
|
|
10412
|
+
|
|
10413
|
+
// プレビューエリア
|
|
10414
|
+
// X: canvas を divRoot 内で水平センタリング(init で動的計算)
|
|
10415
|
+
// Y: g_sHeight に対して垂直センタリング(init で動的計算)
|
|
10416
|
+
|
|
10417
|
+
// 凡例エリアの高さ
|
|
10418
|
+
const LEGEND_H = 25;
|
|
10419
|
+
|
|
10420
|
+
// -------------------------------------------------------------------------
|
|
10421
|
+
// キーレイアウト定義
|
|
10422
|
+
//
|
|
10423
|
+
// 各行: { offsetX, keys }
|
|
10424
|
+
// offsetX : 行左端の水平オフセット(単位: BASE_KEY_W)。全行 0 で統一し、
|
|
10425
|
+
// L)Shift の幅で行頭位置を調整する。
|
|
10426
|
+
// keys : キー定義の配列
|
|
10427
|
+
//
|
|
10428
|
+
// 各キー: { kc, w?, h?, label? }
|
|
10429
|
+
// kc : keyCode(数値)。-1 はスペーサー(描画・キャッシュなし)。
|
|
10430
|
+
// w : 幅倍率(BASE_KEY_W 基準。省略時 1)
|
|
10431
|
+
// h : 高さ倍率(BASE_KEY_H 基準。省略時 1)
|
|
10432
|
+
// label : 省略時は g_kCd[kc] を参照。g_kCd が空文字のキーや
|
|
10433
|
+
// 左右を区別したいキーに指定する。
|
|
10434
|
+
//
|
|
10435
|
+
// 右Shift/Ctrl/Alt は danoniplus 独自コード 256〜258 を使用。
|
|
10436
|
+
// Appli キーは 93 を使用(g_kCd[93] = `Appli`)。
|
|
10437
|
+
// -------------------------------------------------------------------------
|
|
10438
|
+
/**
|
|
10439
|
+
* g_localeObj.val に応じた MAIN_ROWS を生成して返す。
|
|
10440
|
+
* drawBase / calcScale の都度呼び出し、locale 変化を反映する。
|
|
10441
|
+
*
|
|
10442
|
+
* @returns {Array} MAIN_ROWS 相当の配列
|
|
10443
|
+
*/
|
|
10444
|
+
const buildMainRows = () => {
|
|
10445
|
+
const isJa = g_localeObj.val === `Ja`;
|
|
10446
|
+
return [
|
|
10447
|
+
// Row0: Fn キー行(JIS/US 共通)
|
|
10448
|
+
{
|
|
10449
|
+
offsetX: 0,
|
|
10450
|
+
keys: [
|
|
10451
|
+
{ kc: 27 }, // Esc
|
|
10452
|
+
{ kc: -1, w: 0.5 }, // スペーサー
|
|
10453
|
+
{ kc: 112 }, { kc: 113 }, { kc: 114 }, { kc: 115 },
|
|
10454
|
+
{ kc: -1, w: 0.25 }, // スペーサー
|
|
10455
|
+
{ kc: 116 }, { kc: 117 }, { kc: 118 }, { kc: 119 },
|
|
10456
|
+
{ kc: -1, w: 0.25 }, // スペーサー
|
|
10457
|
+
{ kc: 120 }, { kc: 121 }, { kc: 122 }, { kc: 123 },
|
|
10458
|
+
],
|
|
10459
|
+
},
|
|
10460
|
+
// Row1: 数字行
|
|
10461
|
+
// JIS: ..., 220(intlYen), BS
|
|
10462
|
+
// US : ..., BS
|
|
10463
|
+
{
|
|
10464
|
+
offsetX: 0,
|
|
10465
|
+
keys: [
|
|
10466
|
+
{ kc: 229 },
|
|
10467
|
+
{ kc: 49 }, { kc: 50 }, { kc: 51 },
|
|
10468
|
+
{ kc: 52 }, { kc: 53 }, { kc: 54 },
|
|
10469
|
+
{ kc: 55 }, { kc: 56 }, { kc: 57 },
|
|
10470
|
+
{ kc: 48 }, { kc: 189 }, { kc: 222 },
|
|
10471
|
+
...(isJa
|
|
10472
|
+
? [{ kc: 220, w: 0.75 }, { kc: 8 }] // JIS: intlYen + BS
|
|
10473
|
+
: [{ kc: 8, w: 1.7 }] // US : BS のみ(広い)
|
|
10474
|
+
),
|
|
10475
|
+
],
|
|
10476
|
+
},
|
|
10477
|
+
// Row2: QWERTY
|
|
10478
|
+
// JIS: ..., [, Enter(13)
|
|
10479
|
+
// US : ..., [, ]
|
|
10480
|
+
{
|
|
10481
|
+
offsetX: 0,
|
|
10482
|
+
keys: [
|
|
10483
|
+
{ kc: 9, w: 1.5 },
|
|
10484
|
+
{ kc: 81 }, { kc: 87 }, { kc: 69 },
|
|
10485
|
+
{ kc: 82 }, { kc: 84 }, { kc: 89 },
|
|
10486
|
+
{ kc: 85 }, { kc: 73 }, { kc: 79 },
|
|
10487
|
+
{ kc: 80 }, { kc: 192 },
|
|
10488
|
+
...(isJa
|
|
10489
|
+
? [{ kc: 219 }, { kc: 13, w: 1.25, h: 2 }] // JIS: [, Enter縦長
|
|
10490
|
+
: [{ kc: 219 }, { kc: 221, w: 1.2 }] // US : [, ]
|
|
10491
|
+
),
|
|
10492
|
+
],
|
|
10493
|
+
},
|
|
10494
|
+
// Row3: ASDF
|
|
10495
|
+
// JIS: ..., L, ;, ', ¥(221)
|
|
10496
|
+
// US : ..., L, ;, ', Enter(13)
|
|
10497
|
+
{
|
|
10498
|
+
offsetX: 0,
|
|
10499
|
+
keys: [
|
|
10500
|
+
{ kc: 20, w: 1.75, label: `CapsLk` },
|
|
10501
|
+
{ kc: 65 }, { kc: 83 }, { kc: 68 },
|
|
10502
|
+
{ kc: 70 }, { kc: 71 }, { kc: 72 },
|
|
10503
|
+
{ kc: 74 }, { kc: 75 }, { kc: 76 },
|
|
10504
|
+
{ kc: 187 }, { kc: 186 },
|
|
10505
|
+
...(isJa
|
|
10506
|
+
? [{ kc: 221 }] // JIS: ¥
|
|
10507
|
+
: [{ kc: 13, w: 1.9 }] // US : Enter横長
|
|
10508
|
+
),
|
|
10509
|
+
],
|
|
10510
|
+
},
|
|
10511
|
+
// Row4: ZXCV
|
|
10512
|
+
// L)Shift の幅で行頭位置を揃える
|
|
10513
|
+
// JIS: L)Shift, ..., intlRo(226), R)Shift
|
|
10514
|
+
// US : L)Shift, ..., R)Shift
|
|
10515
|
+
{
|
|
10516
|
+
offsetX: 0,
|
|
10517
|
+
keys: [
|
|
10518
|
+
{ kc: 16, w: 2.25 },
|
|
10519
|
+
{ kc: 90 }, { kc: 88 }, { kc: 67 },
|
|
10520
|
+
{ kc: 86 }, { kc: 66 }, { kc: 78 },
|
|
10521
|
+
{ kc: 77 }, { kc: 188 }, { kc: 190 },
|
|
10522
|
+
{ kc: 191 },
|
|
10523
|
+
...(isJa
|
|
10524
|
+
? [{ kc: 226 }, { kc: 256, w: 1.5 }] // JIS: intlRo + R)Shift
|
|
10525
|
+
: [{ kc: 256, w: 2.4 }] // US : R)Shift のみ(広い)
|
|
10526
|
+
),
|
|
10527
|
+
],
|
|
10528
|
+
},
|
|
10529
|
+
// Row5: スペースバー行
|
|
10530
|
+
// JIS: ..., NoConv(29), Space, Conv(28), カタカナひらがな(242), ...
|
|
10531
|
+
// US : ..., Space, ...
|
|
10532
|
+
{
|
|
10533
|
+
offsetX: 0,
|
|
10534
|
+
keys: [
|
|
10535
|
+
{ kc: 17, w: 1.25 },
|
|
10536
|
+
{ kc: 91 },
|
|
10537
|
+
{ kc: 18 },
|
|
10538
|
+
...(isJa
|
|
10539
|
+
? [
|
|
10540
|
+
{ kc: 29 },
|
|
10541
|
+
{ kc: 32, w: 5.25 },
|
|
10542
|
+
{ kc: 28 },
|
|
10543
|
+
{ kc: 242 },
|
|
10544
|
+
]
|
|
10545
|
+
: [
|
|
10546
|
+
{ kc: 32, w: 8.25 },
|
|
10547
|
+
]
|
|
10548
|
+
),
|
|
10549
|
+
{ kc: 258 },
|
|
10550
|
+
{ kc: 93 },
|
|
10551
|
+
...(isJa
|
|
10552
|
+
? [{ kc: 257, w: 1.2 }]
|
|
10553
|
+
: [{ kc: 257, w: 1.05 }]
|
|
10554
|
+
),
|
|
10555
|
+
],
|
|
10556
|
+
},
|
|
10557
|
+
];
|
|
10558
|
+
};
|
|
10559
|
+
// 編集キークラスター(PrintSc/ScrollLk/Pause/Insert/Delete/Home/End/PgUp/PgDn + 矢印キー)
|
|
10560
|
+
// MAIN_ROWS と行インデックスを揃えて配置する。空行はスキップされる。
|
|
10561
|
+
const NAV_ROWS = [
|
|
10562
|
+
{ offsetX: 0, keys: [{ kc: 44, label: `PrintSc` }, { kc: 145, label: `ScrollLk` }, { kc: 19 }] }, // PrintSc ScrollLk Pause
|
|
10563
|
+
{ offsetX: 0, keys: [{ kc: 45 }, { kc: 36 }, { kc: 33 }] }, // Insert Home PgUp
|
|
10564
|
+
{ offsetX: 0, keys: [{ kc: 46 }, { kc: 35 }, { kc: 34 }] }, // Delete End PgDn
|
|
10565
|
+
{ offsetX: 0, keys: [] }, // ASDF行:空
|
|
10566
|
+
{ offsetX: 0, keys: [{ kc: -1 }, { kc: 38 }, { kc: -1 }] }, // ↑
|
|
10567
|
+
{ offsetX: 0, keys: [{ kc: 37 }, { kc: 40 }, { kc: 39 }] }, // ← ↓ →
|
|
10568
|
+
];
|
|
10569
|
+
|
|
10570
|
+
// テンキー(MAIN_ROWS と行インデックスを揃えて配置。1行目は空行で Fn行に揃える)
|
|
10571
|
+
// kc は g_kCd 定義に従う: 96〜111=テンキー各種, 144=NumLk
|
|
10572
|
+
// 標準テンキーレイアウト(2行目から):
|
|
10573
|
+
// [NumLk] [T/] [T*] [T-]
|
|
10574
|
+
// [T7][T8][T9] [T+]
|
|
10575
|
+
// [T4][T5][T6] [T+] ← T+ は縦2u
|
|
10576
|
+
// [T1][T2][T3] [TEnter]
|
|
10577
|
+
// [ T0 ][T.] [TEnter] ← T0 は横2u、TEnter は縦2u
|
|
10578
|
+
const NUM_ROWS = [
|
|
10579
|
+
{ offsetX: 0, keys: [] },
|
|
10580
|
+
{ offsetX: 0, keys: [{ kc: 144 }, { kc: 111 }, { kc: 106 }, { kc: 109 }] }, // NumLk T/ T* T-
|
|
10581
|
+
{ offsetX: 0, keys: [{ kc: 103 }, { kc: 104 }, { kc: 105 }, { kc: 107, h: 2 }] }, // T7 T8 T9 T+(縦2u)
|
|
10582
|
+
{ offsetX: 0, keys: [{ kc: 100 }, { kc: 101 }, { kc: 102 }] }, // T4 T5 T6
|
|
10583
|
+
{ offsetX: 0, keys: [{ kc: 97 }, { kc: 98 }, { kc: 99 }, { kc: 108, h: 2 }] }, // T1 T2 T3 TEnter(縦2u)
|
|
10584
|
+
{ offsetX: 0, keys: [{ kc: 96, w: 2 }, { kc: 110 }] }, // T0(横2u) T.
|
|
10585
|
+
];
|
|
10586
|
+
|
|
10587
|
+
// -------------------------------------------------------------------------
|
|
10588
|
+
// 内部状態
|
|
10589
|
+
// -------------------------------------------------------------------------
|
|
10590
|
+
const _state = {
|
|
10591
|
+
visible: false,
|
|
10592
|
+
mappedSet: new Set(), // メインキー(各矢印の index 0)
|
|
10593
|
+
altSet: new Set(), // 代替キー(各矢印の index 1 以降)
|
|
10594
|
+
shortcutSet: new Set(), // プレイ中ショートカット(keyRetry / keyTitleBack / PgDn / PgUp)
|
|
10595
|
+
canvasBase: null,
|
|
10596
|
+
canvasMap: null,
|
|
10597
|
+
keyRects: [], // { kc, x, y, w, h, label } — drawMap で照合するキャッシュ
|
|
10598
|
+
scale: 1, // BASE_KEY_W/H に掛けるスケール係数
|
|
10599
|
+
cvsW: 500, // 実際の Canvas 幅(スケール計算後)
|
|
10600
|
+
cvsH: 240, // 実際の Canvas 高さ(スケール計算後)
|
|
10601
|
+
};
|
|
10602
|
+
|
|
10603
|
+
// -------------------------------------------------------------------------
|
|
10604
|
+
// スケール計算
|
|
10605
|
+
// -------------------------------------------------------------------------
|
|
10606
|
+
|
|
10607
|
+
/**
|
|
10608
|
+
* g_btnWidth() / g_sHeight を元にスケール係数と Canvas サイズを算出して
|
|
10609
|
+
* _state に書き込む。init 時に呼ぶ。
|
|
10610
|
+
*
|
|
10611
|
+
* 基準サイズ(フルキーボード = メイン + ナビクラスター):
|
|
10612
|
+
* 横: MAIN最大行幅 + ナビ幅(3キー) + 余白
|
|
10613
|
+
* 縦: 6行 × (BASE_KEY_H + BASE_KEY_GAP) - BASE_KEY_GAP
|
|
10614
|
+
* BASE_KEY_W = BASE_KEY_H = 28px、BASE_KEY_GAP = 3px を基準とする。
|
|
10615
|
+
*/
|
|
10616
|
+
const BASE_KEY_W = 28;
|
|
10617
|
+
const BASE_KEY_H = 28;
|
|
10618
|
+
const BASE_KEY_GAP = 3;
|
|
10619
|
+
const MAIN_ROWS_LEN = 6; // MAIN_ROWS の行数(Fn行を含む)
|
|
10620
|
+
|
|
10621
|
+
// 行幅計算(スペーサー含む)
|
|
10622
|
+
const calcRowBaseW = row =>
|
|
10623
|
+
row.keys.reduce((acc, k) => acc + (k.w || 1) * BASE_KEY_W + BASE_KEY_GAP, -BASE_KEY_GAP);
|
|
10624
|
+
|
|
10625
|
+
const BASE_NAV_W = 3 * BASE_KEY_W + 2 * BASE_KEY_GAP; // NAV は 3列固定
|
|
10626
|
+
const BASE_ROW_H = MAIN_ROWS_LEN * (BASE_KEY_H + BASE_KEY_GAP) - BASE_KEY_GAP; // MAIN+NAV 分の高さ
|
|
10627
|
+
const NUM_ROWS_LEN = 6; // テンキーの行数(1行目は空行、2行目からテンキー配置)
|
|
10628
|
+
const NUM_GAP_H = BASE_KEY_H * 0.4; // テンキー上部の余白(基準キー高の40%)
|
|
10629
|
+
const BASE_NUM_ROW_H = NUM_ROWS_LEN * (BASE_KEY_H + BASE_KEY_GAP) - BASE_KEY_GAP; // テンキー部の高さ
|
|
10630
|
+
const BASE_NUM_W = 4 * BASE_KEY_W + 3 * BASE_KEY_GAP; // テンキー横幅(4列固定)
|
|
10631
|
+
|
|
10632
|
+
const calcScale = () => {
|
|
10633
|
+
// locale に依存した行幅を毎回計算する
|
|
10634
|
+
const rows = buildMainRows();
|
|
10635
|
+
const baseMainW = Math.max(...rows.map(calcRowBaseW));
|
|
10636
|
+
// 横幅: メイン + NAV + テンキー + 余白
|
|
10637
|
+
const totalW = baseMainW + BASE_KEY_GAP * 2 + BASE_NAV_W + BASE_KEY_GAP * 2
|
|
10638
|
+
+ BASE_KEY_GAP * 3 + BASE_NUM_W;
|
|
10639
|
+
|
|
10640
|
+
const availW = g_btnWidth();
|
|
10641
|
+
const availH = g_sHeight - 200 - LEGEND_H; // 下部 UI ぶんを除いた高さ
|
|
10642
|
+
|
|
10643
|
+
// 縦幅基準: MAIN/NAV 高さ と テンキー高さ(余白込み)の大きい方
|
|
10644
|
+
const totalH = Math.max(BASE_ROW_H, BASE_NUM_ROW_H + Math.ceil(NUM_GAP_H));
|
|
10645
|
+
|
|
10646
|
+
const scaleW = availW / totalW;
|
|
10647
|
+
const scaleH = availH / totalH;
|
|
10648
|
+
_state.scale = Math.min(scaleW, scaleH, 1.5); // 最大 1.5 倍まで拡大可
|
|
10649
|
+
|
|
10650
|
+
_state.cvsW = Math.floor(totalW * _state.scale);
|
|
10651
|
+
_state.cvsH = Math.floor(totalH * _state.scale) + LEGEND_H;
|
|
10652
|
+
};
|
|
10653
|
+
|
|
10654
|
+
// -------------------------------------------------------------------------
|
|
10655
|
+
// ラベル取得
|
|
10656
|
+
// -------------------------------------------------------------------------
|
|
10657
|
+
|
|
10658
|
+
/**
|
|
10659
|
+
* keyCode に対応する [primaryLabel, subLabel] を返す。
|
|
10660
|
+
* kc が -1(スペーサー)の場合は [``, ``] を返す。
|
|
10661
|
+
* g_kCd の値は `"primary"` または `"primary sub"` 形式の文字列。
|
|
10662
|
+
*
|
|
10663
|
+
* @param {number} kc
|
|
10664
|
+
* @param {string|undefined} forcedLabel - ROWS の label 指定がある場合に優先
|
|
10665
|
+
* @returns {string[]} [primary, sub]
|
|
10666
|
+
*/
|
|
10667
|
+
const getKeyLabels = (kc, forcedLabel) => {
|
|
10668
|
+
if (kc < 0) return [``, ``];
|
|
10669
|
+
if (forcedLabel !== undefined) return [forcedLabel, ``];
|
|
10670
|
+
|
|
10671
|
+
const raw = g_kCd[kc];
|
|
10672
|
+
if (raw && raw !== `- - -` && raw !== `Unknown`) {
|
|
10673
|
+
const parts = raw.split(` `);
|
|
10674
|
+
return [parts[0] || ``, parts[1] || ``];
|
|
10675
|
+
}
|
|
10676
|
+
return [`?`, ``];
|
|
10677
|
+
};
|
|
10678
|
+
|
|
10679
|
+
// -------------------------------------------------------------------------
|
|
10680
|
+
// Canvas ヘルパー
|
|
10681
|
+
// -------------------------------------------------------------------------
|
|
10682
|
+
|
|
10683
|
+
// スケール済みの各寸法を返すヘルパー
|
|
10684
|
+
const kw = w => Math.floor(w * BASE_KEY_W * _state.scale + (w - 1) * BASE_KEY_GAP * _state.scale);
|
|
10685
|
+
const kh = h => Math.floor(h * BASE_KEY_H * _state.scale + (h - 1) * BASE_KEY_GAP * _state.scale);
|
|
10686
|
+
const kg = () => Math.max(1, Math.round(BASE_KEY_GAP * _state.scale));
|
|
10687
|
+
const kr = () => Math.max(2, Math.round(4 * _state.scale));
|
|
10688
|
+
|
|
10689
|
+
const roundRect = (ctx, x, y, w, h, r) => {
|
|
10690
|
+
ctx.beginPath();
|
|
10691
|
+
ctx.moveTo(x + r, y);
|
|
10692
|
+
ctx.lineTo(x + w - r, y);
|
|
10693
|
+
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
|
|
10694
|
+
ctx.lineTo(x + w, y + h - r);
|
|
10695
|
+
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
|
|
10696
|
+
ctx.lineTo(x + r, y + h);
|
|
10697
|
+
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
|
|
10698
|
+
ctx.lineTo(x, y + r);
|
|
10699
|
+
ctx.quadraticCurveTo(x, y, x + r, y);
|
|
10700
|
+
ctx.closePath();
|
|
10701
|
+
};
|
|
10702
|
+
|
|
10703
|
+
const drawKeyLabel = (ctx, x, y, keyW, keyH, primary, sub, textColor, subColor) => {
|
|
10704
|
+
const fs = primary.length >= 5
|
|
10705
|
+
? Math.max(6, Math.floor(8 * _state.scale))
|
|
10706
|
+
: Math.max(7, Math.floor(11 * _state.scale));
|
|
10707
|
+
|
|
10708
|
+
if (sub) {
|
|
10709
|
+
ctx.fillStyle = subColor;
|
|
10710
|
+
ctx.font = `bold ${Math.max(6, Math.floor(8 * _state.scale))}px monospace`;
|
|
10711
|
+
ctx.textAlign = `right`;
|
|
10712
|
+
ctx.textBaseline = `top`;
|
|
10713
|
+
ctx.fillText(sub, x + keyW - 2, y + 2);
|
|
10714
|
+
}
|
|
10715
|
+
ctx.fillStyle = textColor;
|
|
10716
|
+
ctx.font = `bold ${fs}px monospace`;
|
|
10717
|
+
ctx.textAlign = `center`;
|
|
10718
|
+
ctx.textBaseline = `middle`;
|
|
10719
|
+
ctx.fillText(primary, x + keyW / 2, y + keyH / 2 + (sub ? 2 : 0));
|
|
10720
|
+
};
|
|
10721
|
+
|
|
10722
|
+
const drawOneKey = (ctx, x, y, keyW, keyH, fill, stroke, lw, primary, sub, textColor, subColor) => {
|
|
10723
|
+
roundRect(ctx, x + 0.5, y + 0.5, keyW - 1, keyH - 1, kr());
|
|
10724
|
+
ctx.fillStyle = fill;
|
|
10725
|
+
ctx.strokeStyle = stroke;
|
|
10726
|
+
ctx.lineWidth = lw;
|
|
10727
|
+
ctx.fill();
|
|
10728
|
+
ctx.stroke();
|
|
10729
|
+
drawKeyLabel(ctx, x, y, keyW, keyH, primary, sub, textColor, subColor);
|
|
10730
|
+
};
|
|
10731
|
+
|
|
10732
|
+
// -------------------------------------------------------------------------
|
|
10733
|
+
// レイアウト計算・描画
|
|
10734
|
+
// -------------------------------------------------------------------------
|
|
10735
|
+
|
|
10736
|
+
/**
|
|
10737
|
+
* rows 配列から各キーの矩形座標を計算し、
|
|
10738
|
+
* canvas に描画しながら keyRects へキャッシュする。
|
|
10739
|
+
*
|
|
10740
|
+
* @param {CanvasRenderingContext2D} ctx
|
|
10741
|
+
* @param {Array} rows - MAIN_ROWS または NAV_ROWS({offsetX, keys} 形式)
|
|
10742
|
+
* @param {number} originX - セクション左端の X 座標(canvas 座標)
|
|
10743
|
+
* @param {number} originY - セクション上端の Y 座標(canvas 座標)
|
|
10744
|
+
*/
|
|
10745
|
+
const layoutSection = (ctx, rows, originX, originY) => {
|
|
10746
|
+
const gap = kg();
|
|
10747
|
+
const baseKeyH = kh(1);
|
|
10748
|
+
|
|
10749
|
+
rows.forEach((rowDef, rowIdx) => {
|
|
10750
|
+
if (rowDef.keys.length === 0) return;
|
|
10751
|
+
|
|
10752
|
+
const rowY = originY + rowIdx * (baseKeyH + gap);
|
|
10753
|
+
const startX = originX + Math.floor(rowDef.offsetX * BASE_KEY_W * _state.scale);
|
|
10754
|
+
let curX = startX;
|
|
10755
|
+
|
|
10756
|
+
rowDef.keys.forEach(keyDef => {
|
|
10757
|
+
const keyW = kw(keyDef.w || 1);
|
|
10758
|
+
const keyH = kh(keyDef.h || 1);
|
|
10759
|
+
|
|
10760
|
+
if (keyDef.kc >= 0) {
|
|
10761
|
+
_state.keyRects.push({
|
|
10762
|
+
kc: keyDef.kc,
|
|
10763
|
+
x: curX,
|
|
10764
|
+
y: rowY,
|
|
10765
|
+
w: keyW,
|
|
10766
|
+
h: keyH,
|
|
10767
|
+
label: keyDef.label,
|
|
10768
|
+
});
|
|
10769
|
+
const [primary, sub] = getKeyLabels(keyDef.kc, keyDef.label);
|
|
10770
|
+
drawOneKey(
|
|
10771
|
+
ctx, curX, rowY, keyW, keyH,
|
|
10772
|
+
C_COLOR.keyFill, C_COLOR.keyStroke, 1,
|
|
10773
|
+
primary, sub, C_COLOR.keyText, C_COLOR.keySubText
|
|
10774
|
+
);
|
|
10775
|
+
}
|
|
10776
|
+
|
|
10777
|
+
curX += keyW + gap;
|
|
10778
|
+
});
|
|
10779
|
+
});
|
|
10780
|
+
};
|
|
10781
|
+
|
|
10782
|
+
/**
|
|
10783
|
+
* キーボード背景レイヤーを描画し keyRects をキャッシュする。
|
|
10784
|
+
* init 時に呼ぶ。
|
|
10785
|
+
*/
|
|
10786
|
+
const drawBase = () => {
|
|
10787
|
+
const canvas = _state.canvasBase;
|
|
10788
|
+
if (!canvas) return;
|
|
10789
|
+
|
|
10790
|
+
const dpr = window.devicePixelRatio || 1;
|
|
10791
|
+
canvas.style.top = wUnit(40);
|
|
10792
|
+
canvas.width = _state.cvsW * dpr;
|
|
10793
|
+
canvas.height = _state.cvsH * dpr;
|
|
10794
|
+
canvas.style.width = wUnit(_state.cvsW);
|
|
10795
|
+
canvas.style.height = wUnit(_state.cvsH);
|
|
10796
|
+
|
|
10797
|
+
const ctx = canvas.getContext(`2d`);
|
|
10798
|
+
ctx.scale(dpr, dpr);
|
|
10799
|
+
ctx.clearRect(0, 0, _state.cvsW, _state.cvsH);
|
|
10800
|
+
ctx.fillStyle = C_COLOR.bgFill;
|
|
10801
|
+
ctx.fillRect(0, 0, _state.cvsW, _state.cvsH);
|
|
10802
|
+
|
|
10803
|
+
_state.keyRects = [];
|
|
10804
|
+
|
|
10805
|
+
const mainRows = buildMainRows();
|
|
10806
|
+
const gap = kg();
|
|
10807
|
+
const baseMainW = Math.max(...mainRows.map(calcRowBaseW));
|
|
10808
|
+
const mainW = Math.floor(baseMainW * _state.scale);
|
|
10809
|
+
const originY = gap;
|
|
10810
|
+
const navOriginX = mainW + gap * 3;
|
|
10811
|
+
|
|
10812
|
+
// テンキー: NAV クラスターの右に gap*3 の余白を空けて配置
|
|
10813
|
+
const numOriginX = navOriginX + Math.floor(BASE_NAV_W * _state.scale) + gap * 3;
|
|
10814
|
+
// テンキーは MAIN 全体に対して縦方向センタリング
|
|
10815
|
+
const numH = Math.floor(BASE_NUM_ROW_H * _state.scale);
|
|
10816
|
+
const mainH = Math.floor(BASE_ROW_H * _state.scale);
|
|
10817
|
+
const numOriginY = originY + Math.floor((mainH - numH) / 2);
|
|
10818
|
+
|
|
10819
|
+
layoutSection(ctx, mainRows, 0, originY);
|
|
10820
|
+
layoutSection(ctx, NAV_ROWS, navOriginX, originY);
|
|
10821
|
+
layoutSection(ctx, NUM_ROWS, numOriginX, numOriginY);
|
|
10822
|
+
|
|
10823
|
+
// 凡例
|
|
10824
|
+
const ly = _state.cvsH - 10;
|
|
10825
|
+
const fnt = `${Math.max(9, Math.floor(10 * _state.scale))}px ${getBasicFont()}`;
|
|
10826
|
+
ctx.font = fnt;
|
|
10827
|
+
ctx.textAlign = `left`;
|
|
10828
|
+
ctx.textBaseline = `middle`;
|
|
10829
|
+
|
|
10830
|
+
const drawLegend = (x, fill, stroke, label) => {
|
|
10831
|
+
roundRect(ctx, x, ly - 5, 10, 10, 2);
|
|
10832
|
+
ctx.fillStyle = fill; ctx.fill();
|
|
10833
|
+
ctx.strokeStyle = stroke; ctx.lineWidth = 1; ctx.stroke();
|
|
10834
|
+
ctx.fillStyle = C_COLOR.legendText;
|
|
10835
|
+
ctx.fillText(label, x + 14, ly);
|
|
10836
|
+
|
|
10837
|
+
return 14 + ctx.measureText(label).width + 14;
|
|
10838
|
+
};
|
|
10839
|
+
let lx = 8;
|
|
10840
|
+
lx += drawLegend(lx, C_COLOR.keyFill, C_COLOR.keyStroke, g_lblNameObj.unallocated);
|
|
10841
|
+
lx += drawLegend(lx, C_COLOR.mappedFill, C_COLOR.mappedStroke, g_lblNameObj.allocated);
|
|
10842
|
+
lx += drawLegend(lx, C_COLOR.altFill, C_COLOR.altStroke, g_lblNameObj.altAllocated);
|
|
10843
|
+
lx += drawLegend(lx, C_COLOR.shortcutFill, C_COLOR.shortcutStroke, g_lblNameObj.shortcutKey);
|
|
10844
|
+
};
|
|
10845
|
+
|
|
10846
|
+
/**
|
|
10847
|
+
* マッピング強調レイヤーを再描画する。
|
|
10848
|
+
* メインキー(mappedSet)を青系、代替キー(altSet)を黄系で色分けする。
|
|
10849
|
+
* 同一キーにメインと代替が重なる場合はメインを優先する。
|
|
10850
|
+
*/
|
|
10851
|
+
const drawMap = () => {
|
|
10852
|
+
const canvas = _state.canvasMap;
|
|
10853
|
+
if (!canvas) return;
|
|
10854
|
+
|
|
10855
|
+
const dpr = window.devicePixelRatio || 1;
|
|
10856
|
+
canvas.style.top = wUnit(40);
|
|
10857
|
+
canvas.width = _state.cvsW * dpr;
|
|
10858
|
+
canvas.height = _state.cvsH * dpr;
|
|
10859
|
+
canvas.style.width = wUnit(_state.cvsW);
|
|
10860
|
+
canvas.style.height = wUnit(_state.cvsH);
|
|
10861
|
+
|
|
10862
|
+
const ctx = canvas.getContext(`2d`);
|
|
10863
|
+
ctx.scale(dpr, dpr);
|
|
10864
|
+
ctx.clearRect(0, 0, _state.cvsW, _state.cvsH);
|
|
10865
|
+
|
|
10866
|
+
// 優先度: ショートカット > メイン > 代替(後から描くほど優先)
|
|
10867
|
+
const drawKey = (fill, stroke, text) => rect => {
|
|
10868
|
+
const [primary, sub] = getKeyLabels(rect.kc, rect.label);
|
|
10869
|
+
roundRect(ctx, rect.x + 0.5, rect.y + 0.5, rect.w - 1, rect.h - 1, kr());
|
|
10870
|
+
ctx.fillStyle = fill;
|
|
10871
|
+
ctx.strokeStyle = stroke;
|
|
10872
|
+
ctx.lineWidth = 1.5;
|
|
10873
|
+
ctx.fill();
|
|
10874
|
+
ctx.stroke();
|
|
10875
|
+
drawKeyLabel(ctx, rect.x, rect.y, rect.w, rect.h, primary, sub, text, text);
|
|
10876
|
+
};
|
|
10877
|
+
|
|
10878
|
+
// 1. 代替キー(メイン・ショートカットと重複しない場合のみ)
|
|
10879
|
+
_state.keyRects
|
|
10880
|
+
.filter(rect => _state.altSet.has(rect.kc)
|
|
10881
|
+
&& !_state.mappedSet.has(rect.kc)
|
|
10882
|
+
&& !_state.shortcutSet.has(rect.kc))
|
|
10883
|
+
.forEach(drawKey(C_COLOR.altFill, C_COLOR.altStroke, C_COLOR.altText));
|
|
10884
|
+
|
|
10885
|
+
// 2. メインキー(ショートカットと重複しない場合のみ)
|
|
10886
|
+
_state.keyRects
|
|
10887
|
+
.filter(rect => _state.mappedSet.has(rect.kc) && !_state.shortcutSet.has(rect.kc))
|
|
10888
|
+
.forEach(drawKey(C_COLOR.mappedFill, C_COLOR.mappedStroke, C_COLOR.mappedText));
|
|
10889
|
+
|
|
10890
|
+
// 3. ショートカット(常に最前面)
|
|
10891
|
+
_state.keyRects
|
|
10892
|
+
.filter(rect => _state.shortcutSet.has(rect.kc))
|
|
10893
|
+
.forEach(drawKey(C_COLOR.shortcutFill, C_COLOR.shortcutStroke, C_COLOR.shortcutText));
|
|
10894
|
+
};
|
|
10895
|
+
|
|
10896
|
+
// -------------------------------------------------------------------------
|
|
10897
|
+
// 公開 API
|
|
10898
|
+
// -------------------------------------------------------------------------
|
|
10899
|
+
|
|
10900
|
+
/**
|
|
10901
|
+
* キーボードプレビューを初期化し、ボタンと Canvas コンテナを divRoot に追加する。
|
|
10902
|
+
*
|
|
10903
|
+
* @param {HTMLElement} divRoot - キーコンフィグ画面のルート div
|
|
10904
|
+
*/
|
|
10905
|
+
const init = divRoot => {
|
|
10906
|
+
calcScale();
|
|
10907
|
+
|
|
10908
|
+
// ボタン: キャンバス横幅中央に配置、小さいサイズ
|
|
10909
|
+
const btnW = 80;
|
|
10910
|
+
const btnX = Math.floor((g_btnWidth() - btnW) / 2);
|
|
10911
|
+
|
|
10912
|
+
// "↓ Preview" → 展開、"↑ Preview" → 閉じる のトグルボタン
|
|
10913
|
+
const btn = createCss2Button(C_BTN_ID, `↓ Preview`, () => {
|
|
10914
|
+
togglePreview();
|
|
10915
|
+
btn.textContent = _state.visible ? `↑ Preview` : `↓ Preview`;
|
|
10916
|
+
}, {
|
|
10917
|
+
x: btnX, y: BTN_Y, w: btnW, h: BTN_H,
|
|
10918
|
+
title: g_msgObj.kcPreview,
|
|
10919
|
+
}, g_cssObj.button_Setting);
|
|
10920
|
+
btn.style.fontSize = `${BTN_FS}px`;
|
|
10921
|
+
divRoot.appendChild(btn);
|
|
10922
|
+
|
|
10923
|
+
// プレビューエリア: 水平・垂直センタリング
|
|
10924
|
+
const areaX = Math.floor((g_btnWidth() - _state.cvsW) / 2);
|
|
10925
|
+
const areaY = 130;
|
|
10926
|
+
|
|
10927
|
+
const areaDiv = createEmptySprite(divRoot, C_PREVIEW_ID, {
|
|
10928
|
+
x: areaX, y: areaY - 60, w: _state.cvsW, h: _state.cvsH + 80,
|
|
10929
|
+
pointerEvents: C_DIS_AUTO, background: `#00000080`,
|
|
10930
|
+
});
|
|
10931
|
+
areaDiv.style.display = `none`;
|
|
10932
|
+
areaDiv.style.position = `absolute`;
|
|
10933
|
+
areaDiv.style.overflow = `hidden`;
|
|
10934
|
+
|
|
10935
|
+
const canvasBase = document.createElement(`canvas`);
|
|
10936
|
+
canvasBase.id = C_CANVAS_BASE_ID;
|
|
10937
|
+
canvasBase.style.cssText = `position:absolute;left:0;top:0;`;
|
|
10938
|
+
areaDiv.appendChild(canvasBase);
|
|
10939
|
+
_state.canvasBase = canvasBase;
|
|
10940
|
+
|
|
10941
|
+
const canvasMap = document.createElement(`canvas`);
|
|
10942
|
+
canvasMap.id = C_CANVAS_MAP_ID;
|
|
10943
|
+
canvasMap.style.cssText = `position:absolute;left:0;top:0;`;
|
|
10944
|
+
areaDiv.appendChild(canvasMap);
|
|
10945
|
+
_state.canvasMap = canvasMap;
|
|
10946
|
+
|
|
10947
|
+
drawBase();
|
|
10948
|
+
};
|
|
10949
|
+
|
|
10950
|
+
/**
|
|
10951
|
+
* プレビューの表示 / 非表示を切り替える。
|
|
10952
|
+
* 表示するたびにマッピングレイヤーを最新化する。
|
|
10953
|
+
*/
|
|
10954
|
+
const togglePreview = () => {
|
|
10955
|
+
const area = document.getElementById(C_PREVIEW_ID);
|
|
10956
|
+
if (!area) return;
|
|
10957
|
+
|
|
10958
|
+
_state.visible = !_state.visible;
|
|
10959
|
+
area.style.display = _state.visible ? `block` : `none`;
|
|
10960
|
+
|
|
10961
|
+
if (_state.visible) refresh();
|
|
10962
|
+
};
|
|
10963
|
+
|
|
10964
|
+
/**
|
|
10965
|
+
* g_keyObj から現在のキー割り当てを取得して mappedSet / altSet を更新し、
|
|
10966
|
+
* プレビューが表示中なら即時再描画する。
|
|
10967
|
+
*
|
|
10968
|
+
* g_keyObj[`keyCtrl${keyCtrlPtn}`] は二次元配列:
|
|
10969
|
+
* [ [矢印0のメインkeyCode, 代替keyCode, ...], [矢印1のメインkeyCode, ...], ... ]
|
|
10970
|
+
* 各サブ配列の index 0 がメインキー、index 1 以降が代替キー。
|
|
10971
|
+
*/
|
|
10972
|
+
const refresh = () => {
|
|
10973
|
+
const tkObj = getKeyInfo();
|
|
10974
|
+
const configKeyGroupList = g_headerObj.keyGroupOrder[g_stateObj.scoreId] ??
|
|
10975
|
+
g_keyObj[`keyGroupOrder${tkObj.keyCtrlPtn}`] ?? tkObj.keyGroupList;
|
|
10976
|
+
const ctrl = g_keyObj[`keyCtrl${tkObj.keyCtrlPtn}`]
|
|
10977
|
+
.filter((val, idx) => tkObj.keyGroupMaps[idx].includes(configKeyGroupList[g_keycons.keySwitchNum]));
|
|
10978
|
+
|
|
10979
|
+
_state.mappedSet = new Set(ctrl.map(arr => arr[0]).filter(v => v > 0));
|
|
10980
|
+
_state.altSet = new Set(ctrl.flatMap(arr => arr.slice(1)).filter(v => v > 0));
|
|
10981
|
+
// プレイ中ショートカット: keyRetry / keyTitleBack は g_headerObj から取得、PgDn(34) / PgUp(33) は固定
|
|
10982
|
+
_state.shortcutSet = new Set(
|
|
10983
|
+
[g_headerObj.keyRetry, g_headerObj.keyTitleBack, 34, 33].filter(v => v > 0)
|
|
10984
|
+
);
|
|
10985
|
+
if (_state.visible) drawMap();
|
|
10986
|
+
};
|
|
10987
|
+
|
|
10988
|
+
/**
|
|
10989
|
+
* プレビューを強制非表示にしてリセットする。
|
|
10990
|
+
* キーコンフィグ画面の離脱時に呼ぶ。
|
|
10991
|
+
*/
|
|
10992
|
+
const dispose = () => {
|
|
10993
|
+
_state.visible = false;
|
|
10994
|
+
_state.mappedSet = new Set();
|
|
10995
|
+
_state.altSet = new Set();
|
|
10996
|
+
_state.shortcutSet = new Set();
|
|
10997
|
+
_state.keyRects = [];
|
|
10998
|
+
_state.canvasBase = null;
|
|
10999
|
+
_state.canvasMap = null;
|
|
11000
|
+
};
|
|
11001
|
+
|
|
11002
|
+
return { init, refresh, togglePreview, dispose };
|
|
11003
|
+
|
|
11004
|
+
})();
|
|
11005
|
+
|
|
10345
11006
|
/**
|
|
10346
11007
|
* 回転できないオブジェクトの場合に設定の自動絞り込みを行う
|
|
10347
11008
|
*/
|
|
@@ -12593,7 +13254,7 @@ const getArrowSettings = () => {
|
|
|
12593
13254
|
if (g_workObj.stepX_df.length === 0) {
|
|
12594
13255
|
g_workObj.stepX_df = structuredClone(g_workObj.stepX);
|
|
12595
13256
|
}
|
|
12596
|
-
if (g_stateObj.swapping
|
|
13257
|
+
if (g_settings.swappingSubs.includes(g_stateObj.swapping)) {
|
|
12597
13258
|
|
|
12598
13259
|
// Swappingにおけるグループ単位での入れ替えでは、上下でステップゾーンが分かれている場合は分離してシャッフルする
|
|
12599
13260
|
let _style = structuredClone(Object.values(g_workObj.shuffleGroupMap));
|
|
@@ -12613,11 +13274,11 @@ const getArrowSettings = () => {
|
|
|
12613
13274
|
});
|
|
12614
13275
|
const _styleTransDf = structuredClone(Object.values(_styleTrans));
|
|
12615
13276
|
|
|
12616
|
-
if (g_stateObj.swapping === `Mirror`) {
|
|
13277
|
+
if (g_stateObj.swapping === `Mirror` || g_stateObj.swapping === `OuterSwap`) {
|
|
12617
13278
|
_styleTrans.map(_group => _group.reverse());
|
|
12618
|
-
|
|
12619
|
-
|
|
12620
|
-
//
|
|
13279
|
+
}
|
|
13280
|
+
if (g_stateObj.swapping.endsWith(`Swap`)) {
|
|
13281
|
+
// グループの内側だけ入れ替える
|
|
12621
13282
|
_styleTrans.forEach((group, i) => {
|
|
12622
13283
|
g_settings.swapPattern.forEach(val => {
|
|
12623
13284
|
swapGroupNums(_styleTrans, group, i, val);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Source by tickle
|
|
7
7
|
* Created : 2019/11/19
|
|
8
|
-
* Revised : 2026/05/
|
|
8
|
+
* Revised : 2026/05/13 (v47.6.1)
|
|
9
9
|
*
|
|
10
10
|
* https://github.com/cwtickle/danoniplus
|
|
11
11
|
*/
|
|
@@ -1396,9 +1396,11 @@ const g_settings = {
|
|
|
1396
1396
|
camoufrageTypes: [C_FLG_HYPHEN, `FrzArrow`],
|
|
1397
1397
|
camoufrageTypeNum: 0,
|
|
1398
1398
|
|
|
1399
|
-
swappings: [C_FLG_OFF, `
|
|
1399
|
+
swappings: [C_FLG_OFF, `InnerSwap`, `OuterSwap`, `Mirror`, `Mirror+`],
|
|
1400
1400
|
swappingNum: 0,
|
|
1401
1401
|
|
|
1402
|
+
swappingSubs: [`InnerSwap`, `OuterSwap`, `Mirror`],
|
|
1403
|
+
|
|
1402
1404
|
judgRanges: [`Normal`, `Narrow`, `Hard`, `ExHard`],
|
|
1403
1405
|
judgRangeNum: 0,
|
|
1404
1406
|
|
|
@@ -2292,6 +2294,7 @@ for (let j = 0; j < 260; j++) {
|
|
|
2292
2294
|
// キーボード配列の言語設定
|
|
2293
2295
|
const g_lang_kCd = {
|
|
2294
2296
|
Ja: {
|
|
2297
|
+
13: `Enter`,
|
|
2295
2298
|
48: `0`,
|
|
2296
2299
|
49: `1`,
|
|
2297
2300
|
50: `2`,
|
|
@@ -2317,6 +2320,7 @@ const g_lang_kCd = {
|
|
|
2317
2320
|
229: `IME`,
|
|
2318
2321
|
},
|
|
2319
2322
|
En: {
|
|
2323
|
+
13: `Return`,
|
|
2320
2324
|
48: `0 )`,
|
|
2321
2325
|
49: `1 !`,
|
|
2322
2326
|
50: `2 @`,
|
|
@@ -2433,6 +2437,7 @@ g_kCd[134] = `FN`;
|
|
|
2433
2437
|
g_kCd[144] = `NumLk`;
|
|
2434
2438
|
g_kCd[145] = `SL`;
|
|
2435
2439
|
g_kCd[240] = `CapsLk`;
|
|
2440
|
+
g_kCd[242] = `Kana`;
|
|
2436
2441
|
g_kCd[256] = `R)Shift`;
|
|
2437
2442
|
g_kCd[257] = `R)Ctrl`;
|
|
2438
2443
|
g_kCd[258] = `R)Alt`;
|
|
@@ -2552,6 +2557,7 @@ g_kCdN[222] = `Equal`;
|
|
|
2552
2557
|
g_kCdN[226] = `IntlRo`;
|
|
2553
2558
|
g_kCdN[229] = `Backquote`;
|
|
2554
2559
|
g_kCdN[240] = `CapsLock`;
|
|
2560
|
+
g_kCdN[242] = `KanaMode`;
|
|
2555
2561
|
g_kCdN[256] = `ShiftRight`;
|
|
2556
2562
|
g_kCdN[257] = `ControlRight`;
|
|
2557
2563
|
g_kCdN[258] = `AltRight`;
|
|
@@ -4554,6 +4560,8 @@ const g_lblNameObj = {
|
|
|
4554
4560
|
'u_Random+': `Random+`,
|
|
4555
4561
|
'u_S-Random': `S-Random`,
|
|
4556
4562
|
'u_S-Random+': `S-Random+`,
|
|
4563
|
+
'u_InnerSwap': `InnerSwap`,
|
|
4564
|
+
'u_OuterSwap': `OuterSwap`,
|
|
4557
4565
|
'u_Mirror+': `Mirror+`,
|
|
4558
4566
|
'u_(S)': `(S)`,
|
|
4559
4567
|
|
|
@@ -4732,6 +4740,11 @@ const g_lang_lblNameObj = {
|
|
|
4732
4740
|
'u_±120deg': `±120°`,
|
|
4733
4741
|
'u_±360deg': `±360°`,
|
|
4734
4742
|
|
|
4743
|
+
unallocated: `未割当`,
|
|
4744
|
+
allocated: `割当済`,
|
|
4745
|
+
altAllocated: `代替キー`,
|
|
4746
|
+
shortcutKey: `ショートカットキー`,
|
|
4747
|
+
|
|
4735
4748
|
j_ii: "(・∀・)イイ!!",
|
|
4736
4749
|
j_shakin: "(`・ω・)シャキン",
|
|
4737
4750
|
j_matari: "( ´∀`)マターリ",
|
|
@@ -4783,6 +4796,11 @@ const g_lang_lblNameObj = {
|
|
|
4783
4796
|
'u_±120deg': `±120deg`,
|
|
4784
4797
|
'u_±360deg': `±360deg`,
|
|
4785
4798
|
|
|
4799
|
+
unallocated: `Unallocated`,
|
|
4800
|
+
allocated: `Allocated`,
|
|
4801
|
+
altAllocated: `Alternate Keys`,
|
|
4802
|
+
shortcutKey: `Shortcut Keys`,
|
|
4803
|
+
|
|
4786
4804
|
j_ii: ":D Perfect!!",
|
|
4787
4805
|
j_shakin: ":) Great!",
|
|
4788
4806
|
j_matari: ":| Good",
|
|
@@ -4884,7 +4902,8 @@ const g_lang_msgObj = {
|
|
|
4884
4902
|
effect: `矢印・フリーズアローにエフェクトをかけます。\n[Dizzy/Spin] 矢印が回転します\n[Wave/Storm] 矢印の軌道が左右に揺れます\n[Blinking] 矢印が点滅します\n[Squids] 矢印が伸び縮みします`,
|
|
4885
4903
|
camoufrage: `ステップの見た目が配置は同じでランダムに変わります。`,
|
|
4886
4904
|
camoufrageType: `[FrzArrow] フリーズアローの帯部分を初期表示のみ非表示にし、矢印のみで表示します(ヒット/失敗時は帯を再表示)`,
|
|
4887
|
-
swapping: `ステップゾーンの位置を入れ替える設定です。\n[
|
|
4905
|
+
swapping: `ステップゾーンの位置を入れ替える設定です。\n[InnerSwap] ステップゾーンの中央部分のみグループ単位で入れ替えます。\n[OuterSwap] InnerSwapの逆側(外側)をグループ単位で入れ替えます。\n` +
|
|
4906
|
+
`[Mirror] ステップゾーンの位置をグループ単位で入れ替えます。\n[Mirror+] ステップゾーンの位置をグループに関係なく全体的に反転します。`,
|
|
4888
4907
|
judgRange: `判定の許容範囲を設定します。\n[Normal] 通常、[Narrow/Hard] 辛判定、[ExHard] 激辛判定`,
|
|
4889
4908
|
autoRetry: `自動リトライの条件を設定します。\n[Miss] ミス時、[Matari] マターリ時、[Shakin] シャキン時、[FS] Fast/Slow発生時`,
|
|
4890
4909
|
|
|
@@ -4907,6 +4926,7 @@ const g_lang_msgObj = {
|
|
|
4907
4926
|
shuffleGroup: `Mirror/X-Mirror/Turning/Random/S-Random選択時、シャッフルするグループを変更します。\n矢印の上にある同じ数字同士でシャッフルします。`,
|
|
4908
4927
|
stepRtnGroup: `矢印などノーツの種類、回転に関するパターンを切り替えます。\nあらかじめ設定されている場合のみ変更可能です。`,
|
|
4909
4928
|
kcReset: `対応するキーの割り当てを元に戻します。`,
|
|
4929
|
+
kcPreview: `キーボードレイアウトのプレビューを表示/非表示します。`,
|
|
4910
4930
|
|
|
4911
4931
|
pickArrow: `色番号ごとの矢印色(枠、塗りつぶし)、通常時のフリーズアロー色(枠、帯)を\nカラーピッカーから選んで変更できます。`,
|
|
4912
4932
|
pickColorR: `設定する矢印色の種類を切り替えます。`,
|
|
@@ -4986,7 +5006,8 @@ const g_lang_msgObj = {
|
|
|
4986
5006
|
effect: `Applies effects to the arrows and freeze arrows.\n[Dizzy/Spin] Arrows rotate.\n[Wave/Storm] Swing from left to right.\n[Blinking] Arrows blink.\n[Squids] Arrows stretch and shrink.`,
|
|
4987
5007
|
camoufrage: `The appearance of the steps changes randomly with the same placement.`,
|
|
4988
5008
|
camoufrageType: `[FrzArrow] Initially hides freeze-arrow bars and displays only the arrow portion (bars reappear on hit/failure)`,
|
|
4989
|
-
swapping: `This setting allows you to swap the positions of the step zones.\n[
|
|
5009
|
+
swapping: `This setting allows you to swap the positions of the step zones.\n[InnerSwap] Swaps only the inner portion of step zones within each shuffle group.\n[OuterSwap] Swaps the outer portion (inverse of InnerSwap) within each shuffle group.\n` +
|
|
5010
|
+
`[Mirror] Swaps the positions of step zones within each shuffle group. \n[Mirror+] Flips the position of all step zones, regardless of shuffle groups. `,
|
|
4990
5011
|
judgRange: `Set the allowable range of judgment.\n[Normal] Normal judgment, [Narrow/Hard] Hard judgment, [ExHard] Very hard judgment`,
|
|
4991
5012
|
autoRetry: `Set the conditions for automatic retry.\n[Miss] When missed, [Matari] When good, [Shakin] When great, [FS] When Fast/Slow occurs`,
|
|
4992
5013
|
|
|
@@ -5009,6 +5030,7 @@ const g_lang_msgObj = {
|
|
|
5009
5030
|
shuffleGroup: `Change the shuffle group when Mirror, X-Mirror, Turning, Random or S-Random are selected.\nShuffle with the same numbers listed above.`,
|
|
5010
5031
|
stepRtnGroup: `Switches the type of notes, such as arrows, and the pattern regarding rotation.\nThis can only be changed if it has been set in advance.`,
|
|
5011
5032
|
kcReset: `Restores the corresponding key assignments.`,
|
|
5033
|
+
kcPreview: `Show/hide the preview of the keyboard layout.`,
|
|
5012
5034
|
|
|
5013
5035
|
pickArrow: `Change the frame or fill of arrow color and the frame or bar of normal freeze-arrow color\nfor each color number from the color picker.`,
|
|
5014
5036
|
pickColorR: `Switches the arrow color type to be set.`,
|