danoniplus 48.4.1 → 48.5.0

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 CHANGED
@@ -4,12 +4,12 @@
4
4
  *
5
5
  * Source by tickle
6
6
  * Created : 2018/10/08
7
- * Revised : 2026/06/05
7
+ * Revised : 2026/06/14
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 48.4.1`;
12
- const g_revisedDate = `2026/06/05`;
11
+ const g_version = `Ver 48.5.0`;
12
+ const g_revisedDate = `2026/06/14`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -2763,6 +2763,10 @@ const initialControl = async () => {
2763
2763
  .sort((a, b) => parseInt(a) - parseInt(b));
2764
2764
  }
2765
2765
 
2766
+ // ラベルテキスト、オンマウステキスト、確認メッセージ定義の上書き設定
2767
+ Object.assign(g_lblNameObj, g_lang_lblNameObj[g_localeObj.val], g_presetObj.lblName?.[g_localeObj.val]);
2768
+ Object.assign(g_msgObj, g_lang_msgObj[g_localeObj.val], g_presetObj.msg?.[g_localeObj.val]);
2769
+
2766
2770
  // デフォルトのカラー・シャッフルグループ設定を退避
2767
2771
  g_keycons.groups.forEach(type =>
2768
2772
  Object.keys(g_keyObj).filter(val => val.startsWith(type))
@@ -3933,10 +3937,6 @@ const headerConvert = _dosObj => {
3933
3937
  g_imgObj.titleArrow = C_IMG_ARROW;
3934
3938
  }
3935
3939
 
3936
- // ラベルテキスト、オンマウステキスト、確認メッセージ定義の上書き設定
3937
- Object.assign(g_lblNameObj, g_lang_lblNameObj[g_localeObj.val], g_presetObj.lblName?.[g_localeObj.val]);
3938
- Object.assign(g_msgObj, g_lang_msgObj[g_localeObj.val], g_presetObj.msg?.[g_localeObj.val]);
3939
-
3940
3940
  // 自動横幅拡張設定
3941
3941
  obj.autoSpread = setBoolVal(_dosObj.autoSpread, g_presetObj.autoSpread ?? true);
3942
3942
 
@@ -5447,6 +5447,10 @@ const keysConvert = (_dosObj, { keyExtraList = _dosObj.keyExtraList?.split(`,`)
5447
5447
  // 位置マニュアル化 (initManualX)
5448
5448
  g_keyObj[`initManual${newKey}`] = setBoolVal(_dosObj[`initManual${newKey}`] ?? g_keyObj[`initManual${newKey}`], false);
5449
5449
 
5450
+ // カスタムキーの説明ページ(keyHelpJaX / keyHelpEnX)
5451
+ Object.keys(g_lang_lblNameObj).forEach(lang =>
5452
+ g_lang_lblNameObj[lang][`keyHelp${newKey}`] = _dosObj[`keyHelp${lang}${newKey}`] ?? _dosObj[`keyHelp${newKey}`] ?? ``);
5453
+
5450
5454
  // キーコンフィグ (keyCtrlX_Y)
5451
5455
  g_keyObj.minPatterns = newKeyMultiParam(newKey, `keyCtrl`, toKeyCtrlArray, {
5452
5456
  errCd: `E_0104`, baseCopyFlg: true,
@@ -8013,6 +8017,10 @@ const setDifficulty = (_initFlg) => {
8013
8017
  }
8014
8018
  // 特殊キーフラグ
8015
8019
  g_stateObj.extraKeyFlg = g_headerObj.keyExtraList.includes(g_keyObj.currentKey);
8020
+ btnKeymodeHelp.style.display = (
8021
+ g_keyObj.defaultKeyList.includes(g_keyObj.currentKey) || g_lblNameObj[`keyHelp${g_keyObj.currentKey}`]
8022
+ ? `` : C_DIS_NONE
8023
+ );
8016
8024
 
8017
8025
  // ---------------------------------------------------
8018
8026
  // 2. 初期化設定
@@ -8225,8 +8233,15 @@ const createOptionWindow = _sprite => {
8225
8233
  );
8226
8234
  createScText(spriteList.difficulty, `Difficulty`);
8227
8235
  if (g_headerObj.difSelectorUse) {
8228
- createScText(spriteList.difficulty, `DifficultyList`, { x: 147, y: -10, targetLabel: `lnkDifficulty` });
8236
+ createScText(spriteList.difficulty, `DifficultyList`, { x: 154, y: -10, targetLabel: `lnkDifficulty` });
8229
8237
  }
8238
+ multiAppend(difficultySprite,
8239
+ createCss2Button(`btnKeymodeHelp`, `?`, () => {
8240
+ openLink(g_keyObj.defaultKeyList.includes(g_keyObj.currentKey)
8241
+ ? g_lblNameObj.keymodeUrl + g_keyObj.currentKey
8242
+ : g_lblNameObj[`keyHelp${g_keyObj.currentKey}`]);
8243
+ }, g_lblPosObj.btnKeymodeHelp, g_cssObj.button_Setting),
8244
+ )
8230
8245
 
8231
8246
  // ---------------------------------------------------
8232
8247
  // ハイスコア機能実装時に使用予定のスペース
@@ -8462,13 +8477,19 @@ const createOptionWindow = _sprite => {
8462
8477
 
8463
8478
  const viewAdjustment = () => {
8464
8479
  if (g_headerObj.playbackRate !== 1) {
8465
- const adjustmentVal = isLocalMusicFile(g_stateObj.scoreId) ?
8466
- Math.round(g_stateObj.adjustment / g_headerObj.playbackRate) :
8467
- (g_stateObj.adjustment / g_headerObj.playbackRate).toFixed(1);
8468
- document.getElementById(`lnkAdjustment`).innerHTML = `${adjustmentVal}${g_lblNameObj.frame}`
8469
- + `<span style="font-size:${g_limitObj.adjustmentViewOrgSiz}px"> (${g_stateObj.adjustment.toFixed(1)}${g_localStorage.adjustment === g_stateObj.adjustment ? '*' : ''})</span>`;
8470
- document.getElementById(`lnkAdjustment`).style.fontSize = `${g_limitObj.adjustmentViewSiz}px`;
8471
- document.getElementById(`lnkAdjustment`).style.lineHeight = `${g_limitObj.adjustmentLineHeight}px`;
8480
+ const adjustmentVal = isLocalMusicFile(g_stateObj.scoreId)
8481
+ ? Math.round(g_stateObj.adjustment / g_headerObj.playbackRate)
8482
+ : (g_stateObj.adjustment / g_headerObj.playbackRate).toFixed(1);
8483
+ document.getElementById(`lnkAdjustment`).textContent = ``;
8484
+ if (document.getElementById(`lnkAdjustment1`) === null) {
8485
+ multiAppend(
8486
+ adjustmentSprite,
8487
+ createDivCss2Label(`lnkAdjustment1`, ``, g_lblPosObj.lnkAdjustment1),
8488
+ createDivCss2Label(`lnkAdjustment2`, ``, g_lblPosObj.lnkAdjustment2),
8489
+ );
8490
+ }
8491
+ document.getElementById(`lnkAdjustment1`).textContent = `${adjustmentVal}${g_lblNameObj.frame}`;
8492
+ document.getElementById(`lnkAdjustment2`).textContent = `(${g_stateObj.adjustment.toFixed(1)}${g_localStorage.adjustment === g_stateObj.adjustment ? '*' : ''})`;
8472
8493
  }
8473
8494
  };
8474
8495
  viewAdjustment();
@@ -9070,14 +9091,15 @@ const resetGroupList = (_type, _keyCtrlPtn) => {
9070
9091
  let k = 1;
9071
9092
  g_keycons[`${_type}Groups`] = [0];
9072
9093
 
9073
- if (g_keyObj.currentPtn === -1) {
9074
- g_keycons[`${_type}Groups`] = addValtoArray(g_keycons[`${_type}Groups`], -1);
9075
- }
9076
- g_keycons[`${_type}GroupNum`] = Math.min(g_keyObj.currentPtn, 0);
9077
9094
  while (g_keyObj[`${_type}${_keyCtrlPtn}_${k}`] !== undefined) {
9078
9095
  g_keycons[`${_type}Groups`].push(k);
9079
9096
  k++;
9080
9097
  }
9098
+ if (g_keyObj.currentPtn === -1
9099
+ && (_type !== `stepRtn` || (_type === `stepRtn` && g_keycons[`${_type}Groups`].length > 1))) {
9100
+ g_keycons[`${_type}Groups`] = addValtoArray(g_keycons[`${_type}Groups`], -1);
9101
+ }
9102
+ g_keycons[`${_type}GroupNum`] = Math.min(g_keyObj.currentPtn, 0);
9081
9103
  };
9082
9104
 
9083
9105
  /*-----------------------------------------------------------*/
@@ -10627,7 +10649,7 @@ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
10627
10649
  * ColorPicker(一式)の切替
10628
10650
  */
10629
10651
  const changeColorPickers = () => {
10630
- lnkColorR.innerHTML = `[${g_keycons.colorCursorNum + 1} /`;
10652
+ lnkColorR.textContent = `[${g_keycons.colorCursorNum + 1} /`;
10631
10653
  for (let j = 0; j < g_limitObj.kcColorPickerNum; j++) {
10632
10654
  const m = getGroupNum(j);
10633
10655
  changeColorPicker(j, `arrow`, g_headerObj.setColor[m]);
@@ -11042,27 +11064,31 @@ const keyconfigKeyboardPreview = (() => {
11042
11064
 
11043
11065
  // 色定義(既存ゲームの配色に合わせたダーク系)
11044
11066
  const C_COLOR = {
11045
- keyFill: `#1a1a2e`, // 通常キー背景
11046
- keyStroke: `#555577`, // 通常キー枠
11047
- keyText: `#ccccdd`, // 通常キー文字
11048
- keySubText: `#888899`, // サブラベル(Shift面)
11049
- mappedFill: `#003366`, // メインキー背景
11050
- mappedStroke: `#4488ff`, // メインキー枠
11051
- mappedText: `#aaddff`, // メインキー文字
11052
- altFill: `#3e3e1a`, // 代替キー背景
11053
- altStroke: `#777755`, // 代替キー枠
11054
- altText: `#eeeecc`, // 代替キー文字
11055
- shortcutFill: `#330011`, // ショートカットキー背景
11056
- shortcutStroke: `#ff4466`, // ショートカットキー枠
11057
- shortcutText: `#ffaacc`, // ショートカットキー文字
11058
- bgFill: `#0d0d1a`, // Canvas 背景
11059
- legendText: `#cccccc`, // 凡例テキスト
11067
+ normal: {
11068
+ fill: `#1a1a2e`, // 通常キー背景
11069
+ stroke: `#555577`, // 通常キー枠
11070
+ text: `#ccccdd`, // 通常キー文字
11071
+ subText: `#888899`, // サブラベル(Shift面)
11072
+ },
11073
+ mapped: {
11074
+ fill: `#003366`, // メインキー背景
11075
+ stroke: `#4488ff`, // メインキー枠
11076
+ text: `#aaddff`, // メインキー文字
11077
+ },
11078
+ alt: {
11079
+ fill: `#3e3e1a`, // 代替キー背景
11080
+ stroke: `#777755`, // 代替キー枠
11081
+ text: `#eeeecc`, // 代替キー文字
11082
+ },
11083
+ shortcut: {
11084
+ fill: `#330011`, // ショートカットキー背景
11085
+ stroke: `#ff4466`, // ショートカットキー枠
11086
+ text: `#ffaacc`, // ショートカットキー文字
11087
+ },
11088
+ bgFill: `#0d0d1a`, // Canvas 背景
11089
+ legendText: `#cccccc`, // 凡例テキスト
11060
11090
  };
11061
11091
 
11062
- // プレビューエリア
11063
- // X: canvas を divRoot 内で水平センタリング(init で動的計算)
11064
- // Y: g_sHeight に対して垂直センタリング(init で動的計算)
11065
-
11066
11092
  // 凡例エリアの高さ
11067
11093
  const LEGEND_H = 25;
11068
11094
 
@@ -11073,15 +11099,12 @@ const keyconfigKeyboardPreview = (() => {
11073
11099
  // offsetX : 行左端の水平オフセット(単位: BASE_KEY_W)。未指定時は0
11074
11100
  // keys : キー定義の配列
11075
11101
  //
11076
- // 各キー: { kc, w?, h?, label? }
11077
- // kc : keyCode(数値)。-1 はスペーサー(描画・キャッシュなし)。
11078
- // w : 幅倍率(BASE_KEY_W 基準。省略時 1)
11079
- // h : 高さ倍率(BASE_KEY_H 基準。省略時 1)
11080
- // label : 省略時は g_kCd[kc] を参照。g_kCd が空文字のキーや
11081
- // 左右を区別したいキーに指定する。
11082
- //
11083
- // 右Shift/Ctrl/Alt は danoniplus 独自コード 256〜258 を使用。
11084
- // Appli キーは 93 を使用(g_kCd[93] = `Appli`)。
11102
+ // 各キー: { code, w?, h?, label? }
11103
+ // code : KeyboardEvent.code(文字列)。空文字 "" はスペーサー(描画・キャッシュなし)。
11104
+ // w : 幅倍率(BASE_KEY_W 基準。省略時 1)
11105
+ // h : 高さ倍率(BASE_KEY_H 基準。省略時 1)
11106
+ // label : 省略時は g_kCd[keyCode] を参照。g_kCd が空文字のキーや
11107
+ // 左右を区別したいキーに指定する。
11085
11108
  // -------------------------------------------------------------------------
11086
11109
  /**
11087
11110
  * g_localeObj.val に応じた MAIN_ROWS を生成して返す。
@@ -11095,106 +11118,106 @@ const keyconfigKeyboardPreview = (() => {
11095
11118
  // Row0: Fn キー行(JIS/US 共通)
11096
11119
  {
11097
11120
  keys: [
11098
- { kc: 27 }, // Esc
11099
- { kc: -1, w: 0.5 }, // スペーサー
11100
- { kc: 112 }, { kc: 113 }, { kc: 114 }, { kc: 115 },
11101
- { kc: -1, w: 0.25 }, // スペーサー
11102
- { kc: 116 }, { kc: 117 }, { kc: 118 }, { kc: 119 },
11103
- { kc: -1, w: 0.25 }, // スペーサー
11104
- { kc: 120 }, { kc: 121 }, { kc: 122 }, { kc: 123 },
11121
+ { code: `Escape` },
11122
+ { code: ``, w: 0.5 }, // スペーサー
11123
+ { code: `F1` }, { code: `F2` }, { code: `F3` }, { code: `F4` },
11124
+ { code: ``, w: 0.25 }, // スペーサー
11125
+ { code: `F5` }, { code: `F6` }, { code: `F7` }, { code: `F8` },
11126
+ { code: ``, w: 0.25 }, // スペーサー
11127
+ { code: `F9` }, { code: `F10` }, { code: `F11` }, { code: `F12` },
11105
11128
  ],
11106
11129
  },
11107
11130
  // Row1: 数字行
11108
- // JIS: ..., 220(intlYen), BS
11109
- // US : ..., BS
11131
+ // JIS: ..., Minus, Equal, IntlYen, BS
11132
+ // US : ..., Minus, Equal, BS
11110
11133
  {
11111
11134
  keys: [
11112
- { kc: 229 },
11113
- { kc: 49 }, { kc: 50 }, { kc: 51 }, { kc: 52 }, { kc: 53 }, { kc: 54 },
11114
- { kc: 55 }, { kc: 56 }, { kc: 57 }, { kc: 48 }, { kc: 189 }, { kc: 222 },
11135
+ { code: `Backquote` },
11136
+ { code: `Digit1` }, { code: `Digit2` }, { code: `Digit3` }, { code: `Digit4` }, { code: `Digit5` }, { code: `Digit6` },
11137
+ { code: `Digit7` }, { code: `Digit8` }, { code: `Digit9` }, { code: `Digit0` }, { code: `Minus` }, { code: `Equal` },
11115
11138
  ...(isJa
11116
- ? [{ kc: 220, w: 0.75 }, { kc: 8, label: `Back\nSpace` }] // JIS: intlYen + BS
11117
- : [{ kc: 8, w: 1.7 }] // US : BS のみ(広い)
11139
+ ? [{ code: `IntlYen`, w: 0.75 }, { code: `Backspace`, label: `Back\nSpace` }] // JIS: IntlYen + BS
11140
+ : [{ code: `Backspace`, w: 1.7 }] // US : BS のみ(広い)
11118
11141
  ),
11119
11142
  ],
11120
11143
  },
11121
11144
  // Row2: QWERTY
11122
- // JIS: ..., [, Enter(13)
11123
- // US : ..., [, ]
11145
+ // JIS: ..., BracketLeft, BracketRight, Enter(縦長)
11146
+ // US : ..., BracketLeft, BracketRight, Backslash
11124
11147
  {
11125
11148
  keys: [
11126
- { kc: 9, w: 1.5 },
11127
- { kc: 81 }, { kc: 87 }, { kc: 69 }, { kc: 82 }, { kc: 84 }, { kc: 89 },
11128
- { kc: 85 }, { kc: 73 }, { kc: 79 }, { kc: 80 }, { kc: 192 },
11149
+ { code: `Tab`, w: 1.5 },
11150
+ { code: `KeyQ` }, { code: `KeyW` }, { code: `KeyE` }, { code: `KeyR` }, { code: `KeyT` }, { code: `KeyY` },
11151
+ { code: `KeyU` }, { code: `KeyI` }, { code: `KeyO` }, { code: `KeyP` }, { code: `BracketLeft` },
11129
11152
  ...(isJa
11130
- ? [{ kc: 219 }, { kc: 13, w: 1.25, h: 2 }] // JIS: [, Enter縦長
11131
- : [{ kc: 219 }, { kc: 221, w: 1.2 }] // US : [, ]
11153
+ ? [{ code: `BracketRight` }, { code: `Enter`, w: 1.25, h: 2 }] // JIS: BracketRight + Enter縦長
11154
+ : [{ code: `BracketRight` }, { code: `Backslash`, w: 1.2 }] // US : BracketRight + Backslash
11132
11155
  ),
11133
11156
  ],
11134
11157
  },
11135
11158
  // Row3: ASDF
11136
- // JIS: ..., L, ;, ', ¥(221)
11137
- // US : ..., L, ;, ', Enter(13)
11159
+ // JIS: ..., KeyL, Semicolon, Quote, Backslash
11160
+ // US : ..., KeyL, Semicolon, Quote, Enter(横長)
11138
11161
  {
11139
11162
  keys: [
11140
- { kc: 20, w: 1.75, label: `Caps\nLock` },
11141
- { kc: 65 }, { kc: 83 }, { kc: 68 }, { kc: 70 }, { kc: 71 }, { kc: 72 },
11142
- { kc: 74 }, { kc: 75 }, { kc: 76 }, { kc: 187 }, { kc: 186 },
11163
+ { code: `CapsLock`, w: 1.75, label: `Caps\nLock` },
11164
+ { code: `KeyA` }, { code: `KeyS` }, { code: `KeyD` }, { code: `KeyF` }, { code: `KeyG` }, { code: `KeyH` },
11165
+ { code: `KeyJ` }, { code: `KeyK` }, { code: `KeyL` }, { code: `Semicolon` }, { code: `Quote` },
11143
11166
  ...(isJa
11144
- ? [{ kc: 221 }] // JIS: ¥
11145
- : [{ kc: 13, w: 1.9 }] // US : Enter横長
11167
+ ? [{ code: `Backslash` }] // JIS: Backslash(¥)
11168
+ : [{ code: `Enter`, w: 1.9 }] // US : Enter横長
11146
11169
  ),
11147
11170
  ],
11148
11171
  },
11149
11172
  // Row4: ZXCV
11150
11173
  // L)Shift の幅で行頭位置を揃える
11151
- // JIS: L)Shift, ..., intlRo(226), R)Shift
11152
- // US : L)Shift, ..., R)Shift
11174
+ // JIS: L)Shift, ..., IntlRo, R)Shift
11175
+ // US : L)Shift, ..., R)Shift
11153
11176
  {
11154
11177
  keys: [
11155
- { kc: 16, w: 2.25 },
11156
- { kc: 90 }, { kc: 88 }, { kc: 67 }, { kc: 86 }, { kc: 66 }, { kc: 78 },
11157
- { kc: 77 }, { kc: 188 }, { kc: 190 }, { kc: 191 },
11178
+ { code: `ShiftLeft`, w: 2.25 },
11179
+ { code: `KeyZ` }, { code: `KeyX` }, { code: `KeyC` }, { code: `KeyV` }, { code: `KeyB` }, { code: `KeyN` },
11180
+ { code: `KeyM` }, { code: `Comma` }, { code: `Period` }, { code: `Slash` },
11158
11181
  ...(isJa
11159
- ? [{ kc: 226 }, { kc: 256, w: 1.5 }] // JIS: intlRo + R)Shift
11160
- : [{ kc: 256, w: 2.4 }] // US : R)Shift のみ(広い)
11182
+ ? [{ code: `IntlRo` }, { code: `ShiftRight`, w: 1.5 }] // JIS: IntlRo + R)Shift
11183
+ : [{ code: `ShiftRight`, w: 2.4 }] // US : R)Shift のみ(広い)
11161
11184
  ),
11162
11185
  ],
11163
11186
  },
11164
11187
  // Row5: スペースバー行
11165
- // JIS: ..., NoConv(29), Space, Conv(28), カタカナひらがな(242), ...
11188
+ // JIS: ..., NonConvert, Space, Convert, KanaMode, ...
11166
11189
  // US : ..., Space, ...
11167
11190
  {
11168
11191
  keys: [
11169
- { kc: 17, w: 1.25 }, { kc: 91 }, { kc: 18 },
11192
+ { code: `ControlLeft`, w: 1.25 }, { code: `MetaLeft` }, { code: `AltLeft` },
11170
11193
  ...(isJa
11171
- // JIS: NoConv + Space + Conv + カタカナひらがな
11172
- ? [{ kc: 29 }, { kc: 32, w: 5.25 }, { kc: 28 }, { kc: 242 }]
11194
+ // JIS: NonConvert + Space + Convert + KanaMode
11195
+ ? [{ code: `NonConvert` }, { code: `Space`, w: 5.25 }, { code: `Convert` }, { code: `KanaMode` }]
11173
11196
  // US : Space のみ(広い)
11174
- : [{ kc: 32, w: 8.25 }]
11197
+ : [{ code: `Space`, w: 8.25 }]
11175
11198
  ),
11176
- { kc: 258 }, { kc: 93 },
11199
+ { code: `AltRight` }, { code: `ContextMenu` },
11177
11200
  ...(isJa
11178
- ? [{ kc: 257, w: 1.2 }]
11179
- : [{ kc: 257, w: 1.05 }]
11201
+ ? [{ code: `ControlRight`, w: 1.2 }]
11202
+ : [{ code: `ControlRight`, w: 1.05 }]
11180
11203
  ),
11181
11204
  ],
11182
11205
  },
11183
11206
  ];
11184
11207
  };
11208
+
11185
11209
  // 編集キークラスター(PrintSc/ScrollLk/Pause/Insert/Delete/Home/End/PgUp/PgDn + 矢印キー)
11186
11210
  // MAIN_ROWS と行インデックスを揃えて配置する。空行はスキップされる。
11187
11211
  const NAV_ROWS = [
11188
- { keys: [{ kc: 44, label: `Print\nScreen` }, { kc: 145, label: `Scroll\nLock` }, { kc: 19 }] },
11189
- { keys: [{ kc: 45 }, { kc: 36 }, { kc: 33, label: `Page\nUp` }] }, // Insert Home PgUp
11190
- { keys: [{ kc: 46 }, { kc: 35 }, { kc: 34, label: `Page\nDown` }] }, // Delete End PgDn
11191
- { keys: [] }, // ASDF行:空
11192
- { keys: [{ kc: -1 }, { kc: 38 }, { kc: -1 }] }, // ↑
11193
- { keys: [{ kc: 37 }, { kc: 40 }, { kc: 39 }] }, // ← ↓ →
11212
+ { keys: [{ code: `PrintScreen`, label: `Print\nScreen` }, { code: `ScrollLock`, label: `Scroll\nLock` }, { code: `Pause` }] },
11213
+ { keys: [{ code: `Insert` }, { code: `Home` }, { code: `PageUp`, label: `Page\nUp` }] }, // Insert Home PgUp
11214
+ { keys: [{ code: `Delete` }, { code: `End` }, { code: `PageDown`, label: `Page\nDown` }] }, // Delete End PgDn
11215
+ { keys: [] }, // ASDF行:空
11216
+ { keys: [{ code: `` }, { code: `ArrowUp` }, { code: `` }] }, // ↑
11217
+ { keys: [{ code: `ArrowLeft` }, { code: `ArrowDown` }, { code: `ArrowRight` }] }, // ← ↓ →
11194
11218
  ];
11195
11219
 
11196
11220
  // テンキー(MAIN_ROWS と行インデックスを揃えて配置。1行目は空行で Fn行に揃える)
11197
- // kc は g_kCd 定義に従う: 96〜111=テンキー各種, 144=NumLk
11198
11221
  // 標準テンキーレイアウト(2行目から):
11199
11222
  // [NumLk] [T/] [T*] [T-]
11200
11223
  // [T7][T8][T9] [T+]
@@ -11203,11 +11226,11 @@ const keyconfigKeyboardPreview = (() => {
11203
11226
  // [ T0 ][T.] [TEnter] ← T0 は横2u、TEnter は縦2u
11204
11227
  const NUM_ROWS = [
11205
11228
  { keys: [] },
11206
- { keys: [{ kc: 144, label: `Num\nLock` }, { kc: 111 }, { kc: 106 }, { kc: 109 }] }, // NumLk T/ T* T-
11207
- { keys: [{ kc: 103 }, { kc: 104 }, { kc: 105 }, { kc: 107, h: 2 }] }, // T7 T8 T9 T+(縦2u)
11208
- { keys: [{ kc: 100 }, { kc: 101 }, { kc: 102 }] }, // T4 T5 T6
11209
- { keys: [{ kc: 97 }, { kc: 98 }, { kc: 99 }, { kc: 108, h: 2 }] }, // T1 T2 T3 TEnter(縦2u)
11210
- { keys: [{ kc: 96, w: 2 }, { kc: 110 }] }, // T0(横2u) T.
11229
+ { keys: [{ code: `NumLock`, label: `Num\nLock` }, { code: `NumpadDivide` }, { code: `NumpadMultiply` }, { code: `NumpadSubtract` }] }, // NumLk T/ T* T-
11230
+ { keys: [{ code: `Numpad7` }, { code: `Numpad8` }, { code: `Numpad9` }, { code: `NumpadAdd`, h: 2 }] }, // T7 T8 T9 T+(縦2u)
11231
+ { keys: [{ code: `Numpad4` }, { code: `Numpad5` }, { code: `Numpad6` }] }, // T4 T5 T6
11232
+ { keys: [{ code: `Numpad1` }, { code: `Numpad2` }, { code: `Numpad3` }, { code: `NumpadEnter`, h: 2 }] }, // T1 T2 T3 TEnter(縦2u)
11233
+ { keys: [{ code: `Numpad0`, w: 2 }, { code: `NumpadDecimal` }] }, // T0(横2u) T.
11211
11234
  ];
11212
11235
 
11213
11236
  // -------------------------------------------------------------------------
@@ -11215,12 +11238,12 @@ const keyconfigKeyboardPreview = (() => {
11215
11238
  // -------------------------------------------------------------------------
11216
11239
  const _state = {
11217
11240
  visible: false,
11218
- mappedSet: new Set(), // メインキー(各矢印の index 0)
11219
- altSet: new Set(), // 代替キー(各矢印の index 1 以降)
11220
- shortcutSet: new Set(), // プレイ中ショートカット(keyRetry / keyTitleBack / PgDn / PgUp)
11241
+ mappedSet: new Set(), // メインキー(code文字列)
11242
+ altSet: new Set(), // 代替キー(code文字列)
11243
+ shortcutSet: new Set(), // ショートカットキー(code文字列)
11221
11244
  canvasBase: null,
11222
11245
  canvasMap: null,
11223
- keyRects: [], // { kc, x, y, w, h, label } — drawMap で照合するキャッシュ
11246
+ keyDataList: [], // { code, x, y, w, h, label } — drawMap で照合するキャッシュ
11224
11247
  scale: 1, // BASE_KEY_W/H に掛けるスケール係数
11225
11248
  cvsW: 500, // 実際の Canvas 幅(スケール計算後)
11226
11249
  cvsH: 240, // 実際の Canvas 高さ(スケール計算後)
@@ -11282,22 +11305,24 @@ const keyconfigKeyboardPreview = (() => {
11282
11305
  // -------------------------------------------------------------------------
11283
11306
 
11284
11307
  /**
11285
- * keyCode に対応する [primaryLabel, subLabel] を返す。
11286
- * kc が -1(スペーサー)の場合は [``, ``] を返す。
11287
- * g_kCd の値は `"primary"` または `"primary sub"` 形式の文字列。
11308
+ * code に対応する [primaryLabel, subLabel] を返す。
11288
11309
  *
11289
- * @param {number} kc
11310
+ * @param {string} code
11290
11311
  * @param {string|undefined} forcedLabel - ROWS の label 指定がある場合に優先
11291
11312
  * @returns {string[]} [primary, sub]
11292
11313
  */
11293
- const getKeyLabels = (kc, forcedLabel) => {
11294
- if (kc < 0) return [``, ``];
11314
+ const getKeyLabels = (code, forcedLabel) => {
11315
+ if (!code) return [``, ``];
11295
11316
  if (forcedLabel !== undefined) return [forcedLabel, ``];
11296
11317
 
11297
- const raw = g_kCd[kc];
11298
- if (raw && raw !== g_kCd[0] && raw !== g_kCd[1]) {
11299
- const parts = raw.split(` `);
11300
- return [parts[0] || ``, parts[1] || ``];
11318
+ // code 文字列から従来の keyCode を逆引きして g_kCd から取得
11319
+ const kc = g_kCdN.indexOf(code);
11320
+ if (kc >= 0) {
11321
+ const raw = g_kCd[kc];
11322
+ if (raw && raw !== g_kCd[0] && raw !== g_kCd[1]) {
11323
+ const parts = raw.split(` `);
11324
+ return [parts[0] || ``, parts[1] || ``];
11325
+ }
11301
11326
  }
11302
11327
  return [`?`, ``];
11303
11328
  };
@@ -11312,6 +11337,22 @@ const keyconfigKeyboardPreview = (() => {
11312
11337
  const kg = () => Math.max(1, Math.round(BASE_KEY_GAP * _state.scale));
11313
11338
  const kr = () => Math.max(2, Math.round(4 * _state.scale));
11314
11339
 
11340
+ /**
11341
+ * Canvasの共通初期化処理
11342
+ */
11343
+ const setupCanvasContext = (canvas) => {
11344
+ if (!canvas) return null;
11345
+ canvas.style.top = wUnit(40);
11346
+ canvas.width = _state.cvsW * g_dpr;
11347
+ canvas.height = _state.cvsH * g_dpr;
11348
+ canvas.style.width = wUnit(_state.cvsW);
11349
+ canvas.style.height = wUnit(_state.cvsH);
11350
+
11351
+ const ctx = canvas.getContext(`2d`);
11352
+ ctx.scale(g_dpr, g_dpr);
11353
+ return ctx;
11354
+ };
11355
+
11315
11356
  const roundRect = (ctx, x, y, w, h, r) => {
11316
11357
  ctx.beginPath();
11317
11358
  ctx.moveTo(x + r, y);
@@ -11326,23 +11367,47 @@ const keyconfigKeyboardPreview = (() => {
11326
11367
  ctx.closePath();
11327
11368
  };
11328
11369
 
11329
- const drawKeyLabel = (ctx, x, y, keyW, keyH, primary, sub, textColor, subColor) => {
11370
+ /**
11371
+ * 単一キーを描画する(枠の描画と内部テキストの書き込みを一括化)
11372
+ * @param {CanvasRenderingContext2D} ctx
11373
+ * @param {Object} keyData - 位置・サイズ・キーコードを含むキー情報
11374
+ * @param {Object} style - fill, stroke, text 等の色セット
11375
+ * @param {number} lw - 枠線の太さ(lineWidth)
11376
+ */
11377
+ const drawOneKey = (ctx, { keyData, style, lw = 1 }) => {
11378
+ const { x, y, w: keyW, h: keyH, code, label } = keyData;
11379
+
11380
+ // 1. キーの枠線・背景を描画
11381
+ roundRect(ctx, x + 0.5, y + 0.5, keyW - 1, keyH - 1, kr());
11382
+ ctx.fillStyle = style.fill;
11383
+ ctx.strokeStyle = style.stroke;
11384
+ ctx.lineWidth = lw;
11385
+ ctx.fill();
11386
+ ctx.stroke();
11387
+
11388
+ // 2. キー内部のテキスト(メイン・サブ)を描画
11389
+ const [primary, sub] = getKeyLabels(code, label);
11390
+
11330
11391
  const fs = (_textLen) => _textLen >= 5 * keyW / BASE_KEY_W
11331
11392
  ? Math.max(6, Math.floor(9 * _state.scale))
11332
11393
  : Math.max(7, Math.floor(11 * _state.scale));
11333
11394
 
11395
+ // サブラベル(Shift面などの表記)がある場合
11334
11396
  if (sub) {
11335
- ctx.fillStyle = subColor;
11397
+ ctx.fillStyle = style.subText || style.text;
11336
11398
  ctx.font = `bold ${Math.max(6, Math.floor(9 * _state.scale))}px monospace`;
11337
11399
  ctx.textAlign = `right`;
11338
11400
  ctx.textBaseline = `top`;
11339
11401
  ctx.fillText(sub, x + keyW - 2, y + 2);
11340
11402
  }
11403
+
11404
+ // メインラベルの描画(改行表記に対応)
11341
11405
  const [primary1, primary2] = primary.split(`\n`);
11342
- ctx.fillStyle = textColor;
11406
+ ctx.fillStyle = style.text;
11343
11407
  ctx.textAlign = `center`;
11344
11408
  ctx.textBaseline = `middle`;
11345
11409
  const subDiff = sub ? 2 : 0;
11410
+
11346
11411
  if (primary2) {
11347
11412
  const siz = fs(Math.max(primary1.length, primary2.length));
11348
11413
  ctx.font = `bold ${siz}px monospace`;
@@ -11354,23 +11419,13 @@ const keyconfigKeyboardPreview = (() => {
11354
11419
  }
11355
11420
  };
11356
11421
 
11357
- const drawOneKey = (ctx, x, y, keyW, keyH, fill, stroke, lw, primary, sub, textColor, subColor) => {
11358
- roundRect(ctx, x + 0.5, y + 0.5, keyW - 1, keyH - 1, kr());
11359
- ctx.fillStyle = fill;
11360
- ctx.strokeStyle = stroke;
11361
- ctx.lineWidth = lw;
11362
- ctx.fill();
11363
- ctx.stroke();
11364
- drawKeyLabel(ctx, x, y, keyW, keyH, primary, sub, textColor, subColor);
11365
- };
11366
-
11367
11422
  // -------------------------------------------------------------------------
11368
11423
  // レイアウト計算・描画
11369
11424
  // -------------------------------------------------------------------------
11370
11425
 
11371
11426
  /**
11372
11427
  * rows 配列から各キーの矩形座標を計算し、
11373
- * canvas に描画しながら keyRects へキャッシュする。
11428
+ * canvas に描画しながら keyDataList へキャッシュする。
11374
11429
  *
11375
11430
  * @param {CanvasRenderingContext2D} ctx
11376
11431
  * @param {Array} rows - MAIN_ROWS または NAV_ROWS({offsetX, keys} 形式)
@@ -11392,21 +11447,17 @@ const keyconfigKeyboardPreview = (() => {
11392
11447
  const keyW = kw(keyDef.w || 1);
11393
11448
  const keyH = kh(keyDef.h || 1);
11394
11449
 
11395
- if (keyDef.kc >= 0) {
11396
- _state.keyRects.push({
11397
- kc: keyDef.kc,
11450
+ if (keyDef.code !== ``) {
11451
+ const keyData = {
11452
+ code: keyDef.code,
11398
11453
  x: curX,
11399
11454
  y: rowY,
11400
11455
  w: keyW,
11401
11456
  h: keyH,
11402
11457
  label: keyDef.label,
11403
- });
11404
- const [primary, sub] = getKeyLabels(keyDef.kc, keyDef.label);
11405
- drawOneKey(
11406
- ctx, curX, rowY, keyW, keyH,
11407
- C_COLOR.keyFill, C_COLOR.keyStroke, 1,
11408
- primary, sub, C_COLOR.keyText, C_COLOR.keySubText
11409
- );
11458
+ };
11459
+ _state.keyDataList.push(keyData);
11460
+ drawOneKey(ctx, { keyData, style: C_COLOR.normal, lw: 1 });
11410
11461
  }
11411
11462
 
11412
11463
  curX += keyW + gap;
@@ -11415,26 +11466,18 @@ const keyconfigKeyboardPreview = (() => {
11415
11466
  };
11416
11467
 
11417
11468
  /**
11418
- * キーボード背景レイヤーを描画し keyRects をキャッシュする。
11469
+ * キーボード背景レイヤーを描画し keyDataList をキャッシュする。
11419
11470
  * init 時に呼ぶ。
11420
11471
  */
11421
11472
  const drawBase = () => {
11422
- const canvas = _state.canvasBase;
11423
- if (!canvas) return;
11473
+ const ctx = setupCanvasContext(_state.canvasBase);
11474
+ if (!ctx) return;
11424
11475
 
11425
- canvas.style.top = wUnit(40);
11426
- canvas.width = _state.cvsW * g_dpr;
11427
- canvas.height = _state.cvsH * g_dpr;
11428
- canvas.style.width = wUnit(_state.cvsW);
11429
- canvas.style.height = wUnit(_state.cvsH);
11430
-
11431
- const ctx = canvas.getContext(`2d`);
11432
- ctx.scale(g_dpr, g_dpr);
11433
11476
  ctx.clearRect(0, 0, _state.cvsW, _state.cvsH);
11434
11477
  ctx.fillStyle = C_COLOR.bgFill;
11435
11478
  ctx.fillRect(0, 0, _state.cvsW, _state.cvsH);
11436
11479
 
11437
- _state.keyRects = [];
11480
+ _state.keyDataList = [];
11438
11481
 
11439
11482
  const mainRows = buildMainRows();
11440
11483
  const gap = kg();
@@ -11456,25 +11499,26 @@ const keyconfigKeyboardPreview = (() => {
11456
11499
 
11457
11500
  // 凡例
11458
11501
  const ly = _state.cvsH - 10;
11459
- const fnt = `${Math.max(9, Math.floor(12 * _state.scale))}px ${getBasicFont()}`;
11460
- ctx.font = fnt;
11502
+ ctx.font = `${Math.max(9, Math.floor(12 * _state.scale))}px ${getBasicFont()}`;
11461
11503
  ctx.textAlign = `left`;
11462
11504
  ctx.textBaseline = `middle`;
11463
11505
 
11464
- const drawLegend = (x, fill, stroke, label) => {
11465
- roundRect(ctx, x, ly - 5, 10, 10, 2);
11466
- ctx.fillStyle = fill; ctx.fill();
11467
- ctx.strokeStyle = stroke; ctx.lineWidth = 1; ctx.stroke();
11468
- ctx.fillStyle = C_COLOR.legendText;
11469
- ctx.fillText(label, x + 14, ly);
11506
+ const legends = [
11507
+ { style: C_COLOR.normal, label: g_lblNameObj.unallocated },
11508
+ { style: C_COLOR.mapped, label: g_lblNameObj.allocated },
11509
+ { style: C_COLOR.alt, label: g_lblNameObj.altAllocated },
11510
+ { style: C_COLOR.shortcut, label: g_lblNameObj.shortcutKey }
11511
+ ];
11470
11512
 
11471
- return 14 + ctx.measureText(label).width + 14;
11472
- };
11473
11513
  let lx = 8;
11474
- lx += drawLegend(lx, C_COLOR.keyFill, C_COLOR.keyStroke, g_lblNameObj.unallocated);
11475
- lx += drawLegend(lx, C_COLOR.mappedFill, C_COLOR.mappedStroke, g_lblNameObj.allocated);
11476
- lx += drawLegend(lx, C_COLOR.altFill, C_COLOR.altStroke, g_lblNameObj.altAllocated);
11477
- lx += drawLegend(lx, C_COLOR.shortcutFill, C_COLOR.shortcutStroke, g_lblNameObj.shortcutKey);
11514
+ legends.forEach(item => {
11515
+ roundRect(ctx, lx, ly - 5, 10, 10, 2);
11516
+ ctx.fillStyle = item.style.fill; ctx.fill();
11517
+ ctx.strokeStyle = item.style.stroke; ctx.lineWidth = 1; ctx.stroke();
11518
+ ctx.fillStyle = C_COLOR.legendText;
11519
+ ctx.fillText(item.label, lx + 14, ly);
11520
+ lx += ctx.measureText(item.label).width + 28;
11521
+ });
11478
11522
  };
11479
11523
 
11480
11524
  /**
@@ -11483,47 +11527,25 @@ const keyconfigKeyboardPreview = (() => {
11483
11527
  * 同一キーにメインと代替が重なる場合はメインを優先する。
11484
11528
  */
11485
11529
  const drawMap = () => {
11486
- const canvas = _state.canvasMap;
11487
- if (!canvas) return;
11488
-
11489
- canvas.style.top = wUnit(40);
11490
- canvas.width = _state.cvsW * g_dpr;
11491
- canvas.height = _state.cvsH * g_dpr;
11492
- canvas.style.width = wUnit(_state.cvsW);
11493
- canvas.style.height = wUnit(_state.cvsH);
11530
+ const ctx = setupCanvasContext(_state.canvasMap);
11531
+ if (!ctx) return;
11494
11532
 
11495
- const ctx = canvas.getContext(`2d`);
11496
- ctx.scale(g_dpr, g_dpr);
11497
11533
  ctx.clearRect(0, 0, _state.cvsW, _state.cvsH);
11498
11534
 
11499
- // 優先度: ショートカット > メイン > 代替(後から描くほど優先)
11500
- const drawKey = (fill, stroke, text) => rect => {
11501
- const [primary, sub] = getKeyLabels(rect.kc, rect.label);
11502
- roundRect(ctx, rect.x + 0.5, rect.y + 0.5, rect.w - 1, rect.h - 1, kr());
11503
- ctx.fillStyle = fill;
11504
- ctx.strokeStyle = stroke;
11505
- ctx.lineWidth = 1.5;
11506
- ctx.fill();
11507
- ctx.stroke();
11508
- drawKeyLabel(ctx, rect.x, rect.y, rect.w, rect.h, primary, sub, text, text);
11535
+ // キー状態に応じた色取得ロジック(優先度: ショートカット > メイン > 代替)
11536
+ const getKeyStyle = (code) => {
11537
+ if (_state.shortcutSet.has(code)) return C_COLOR.shortcut;
11538
+ if (_state.mappedSet.has(code)) return C_COLOR.mapped;
11539
+ if (_state.altSet.has(code)) return C_COLOR.alt;
11540
+ return null;
11509
11541
  };
11510
11542
 
11511
- // 1. 代替キー(メイン・ショートカットと重複しない場合のみ)
11512
- _state.keyRects
11513
- .filter(rect => _state.altSet.has(rect.kc)
11514
- && !_state.mappedSet.has(rect.kc)
11515
- && !_state.shortcutSet.has(rect.kc))
11516
- .forEach(drawKey(C_COLOR.altFill, C_COLOR.altStroke, C_COLOR.altText));
11517
-
11518
- // 2. メインキー(ショートカットと重複しない場合のみ)
11519
- _state.keyRects
11520
- .filter(rect => _state.mappedSet.has(rect.kc) && !_state.shortcutSet.has(rect.kc))
11521
- .forEach(drawKey(C_COLOR.mappedFill, C_COLOR.mappedStroke, C_COLOR.mappedText));
11522
-
11523
- // 3. ショートカット(常に最前面)
11524
- _state.keyRects
11525
- .filter(rect => _state.shortcutSet.has(rect.kc))
11526
- .forEach(drawKey(C_COLOR.shortcutFill, C_COLOR.shortcutStroke, C_COLOR.shortcutText));
11543
+ _state.keyDataList.forEach(keyData => {
11544
+ const style = getKeyStyle(keyData.code);
11545
+ if (style) {
11546
+ drawOneKey(ctx, { keyData, style, lw: 1.5 });
11547
+ }
11548
+ });
11527
11549
  };
11528
11550
 
11529
11551
  // -------------------------------------------------------------------------
@@ -11596,12 +11618,17 @@ const keyconfigKeyboardPreview = (() => {
11596
11618
  const ctrl = g_keyObj[`keyCtrl${tkObj.keyCtrlPtn}`]
11597
11619
  .filter((val, idx) => tkObj.keyGroupMaps[idx].includes(configKeyGroupList[g_keycons.keySwitchNum]));
11598
11620
 
11599
- _state.mappedSet = new Set(ctrl.map(arr => arr[0]).filter(v => v > 0));
11600
- _state.altSet = new Set(ctrl.flatMap(arr => arr.slice(1)).filter(v => v > 0));
11621
+ // 数値から code 文字列へ安全に変換するヘルパー
11622
+ const toCodeStr = (num) => g_kCdN[num] || ``;
11623
+
11624
+ _state.mappedSet = new Set(ctrl.map(arr => toCodeStr(arr[0])).filter(v => v !== ``));
11625
+ _state.altSet = new Set(ctrl.flatMap(arr => arr.slice(1)).map(toCodeStr).filter(v => v !== ``));
11626
+
11601
11627
  // プレイ中ショートカット: keyRetry / keyTitleBack は g_headerObj から取得、PgDn(34) / PgUp(33) は固定
11602
11628
  _state.shortcutSet = new Set(
11603
- [g_headerObj.keyRetry, g_headerObj.keyTitleBack, 34, 33].filter(v => v > 0)
11629
+ [g_headerObj.keyRetry, g_headerObj.keyTitleBack, 34, 33].map(toCodeStr).filter(v => v !== ``)
11604
11630
  );
11631
+
11605
11632
  if (_state.visible) drawMap();
11606
11633
  };
11607
11634
 
@@ -11614,7 +11641,7 @@ const keyconfigKeyboardPreview = (() => {
11614
11641
  _state.mappedSet = new Set();
11615
11642
  _state.altSet = new Set();
11616
11643
  _state.shortcutSet = new Set();
11617
- _state.keyRects = [];
11644
+ _state.keyDataList = [];
11618
11645
  _state.canvasBase = null;
11619
11646
  _state.canvasMap = null;
11620
11647
  };
@@ -16276,23 +16303,41 @@ const judgeArrow = _j => {
16276
16303
  * @param {number} _justFrames Fast/Slowの表示条件フレーム数
16277
16304
  */
16278
16305
  const displayDiff = (_difFrame, _fjdg = ``, _justFrames = g_headerObj.justFrames) => {
16279
- let diffJDisp = ``;
16280
16306
  g_workObj.diffList.push(_difFrame);
16307
+
16281
16308
  const difCnt = Math.abs(_difFrame);
16309
+ const diffJ = document.getElementById(`diff${_fjdg}J`);
16310
+
16311
+ let text = ``;
16312
+ let activeClass = ``;
16313
+
16314
+ // 1. 各条件の処理
16282
16315
  if (_difFrame > g_judgObj.arrowJ[g_judgPosObj.shobon]) {
16283
- diffJDisp = `<span class="common_excessive">Excessive</span>`;
16316
+ text = `Excessive`;
16317
+ activeClass = g_cssObj.common_Excessive;
16284
16318
  g_resultObj.excessive++;
16285
16319
  lifeDamage(true);
16320
+
16286
16321
  } else if (_difFrame > _justFrames) {
16287
- diffJDisp = `<span class="common_diffFast">Fast ${difCnt} Frames</span>`;
16322
+ text = `Fast ${difCnt} Frames`;
16323
+ activeClass = g_cssObj.common_diffFast;
16288
16324
  g_resultObj.fast++;
16289
16325
  quickRetry(`Fast/Slow`);
16290
- } else if (_difFrame < _justFrames * (-1)) {
16291
- diffJDisp = `<span class="common_diffSlow">Slow ${difCnt} Frames</span>`;
16326
+
16327
+ } else if (_difFrame < _justFrames * -1) {
16328
+ text = `Slow ${difCnt} Frames`;
16329
+ activeClass = g_cssObj.common_diffSlow;
16292
16330
  g_resultObj.slow++;
16293
16331
  quickRetry(`Fast/Slow`);
16332
+
16333
+ }
16334
+
16335
+ // 2. DOMへの反映
16336
+ diffJ.textContent = text;
16337
+ diffJ.classList.value = ``;
16338
+ if (activeClass) {
16339
+ diffJ.classList.add(activeClass);
16294
16340
  }
16295
- document.getElementById(`diff${_fjdg}J`).innerHTML = diffJDisp;
16296
16341
  };
16297
16342
 
16298
16343
  /**
@@ -16362,8 +16407,11 @@ const lifeDamage = (_excessive = false) => {
16362
16407
  const changeJudgeCharacter = (_name, _character, _fjdg = ``) => {
16363
16408
  g_resultObj[_name]++;
16364
16409
  g_currentArrows++;
16365
- document.getElementById(`chara${_fjdg}J`).innerHTML = `<span class="common_${_name}">${_character}</span>`;
16366
- document.getElementById(`chara${_fjdg}J`).setAttribute(`cnt`, C_FRM_JDGMOTION);
16410
+ const jdgJ = document.getElementById(`chara${_fjdg}J`);
16411
+ jdgJ.classList.value = ``;
16412
+ jdgJ.classList.add(g_cssObj[`common_${_name}`]);
16413
+ jdgJ.textContent = _character;
16414
+ jdgJ.setAttribute(`cnt`, C_FRM_JDGMOTION);
16367
16415
  document.getElementById(`lbl${toCapitalize(_name)}`).textContent = g_resultObj[_name];
16368
16416
  };
16369
16417
 
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2019/11/19
8
- * Revised : 2026/06/02 (v48.4.0)
8
+ * Revised : 2026/06/14 (v48.5.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -424,6 +424,10 @@ const updateWindowSiz = () => {
424
424
  x: 70, y: 65, w: g_btnWidth() - 120, h: 20, siz: 12, align: C_ALIGN_LEFT,
425
425
  },
426
426
 
427
+ btnKeymodeHelp: {
428
+ x: 150, y: -10, w: 15, h: 30, siz: 16, title: g_msgObj.keymodeHelp,
429
+ border: `solid 1px #666666`, borderRadius: 5,
430
+ },
427
431
  lblMusicInfo: {
428
432
  x: g_btnX(1 / 4), y: 0, w: g_btnWidth(3 / 4), h: 20, align: C_ALIGN_RIGHT
429
433
  },
@@ -449,6 +453,14 @@ const updateWindowSiz = () => {
449
453
  lblFadeinBar: {
450
454
  x: g_limitObj.setLblLeft, y: 0, type: `range`,
451
455
  },
456
+ lnkAdjustment1: {
457
+ x: g_limitObj.setLblLeft, y: -3, w: g_limitObj.setLblWidth, h: g_limitObj.setLblHeight,
458
+ siz: g_limitObj.adjustmentViewSiz,
459
+ },
460
+ lnkAdjustment2: {
461
+ x: g_limitObj.setLblLeft, y: 10, w: g_limitObj.setLblWidth, h: g_limitObj.setLblHeight,
462
+ siz: g_limitObj.adjustmentViewOrgSiz,
463
+ },
452
464
 
453
465
  /** 設定: 譜面明細子画面 */
454
466
  lblTooldif: {
@@ -2717,6 +2729,8 @@ const g_shortcutObj = {
2717
2729
  ShiftLeft_KeyD: { id: `lnkDifficultyL` },
2718
2730
  ShiftRight_KeyD: { id: `lnkDifficultyL` },
2719
2731
  KeyD: { id: `lnkDifficultyR` },
2732
+ Slash: { id: `btnKeymodeHelp`, reset: true },
2733
+ F1: { id: `btnKeymodeHelp`, reset: true },
2720
2734
 
2721
2735
  ShiftLeft_ArrowRight: { id: `lnkSpeedR` },
2722
2736
  ShiftRight_ArrowRight: { id: `lnkSpeedR` },
@@ -4860,6 +4874,7 @@ const g_lang_lblNameObj = {
4860
4874
 
4861
4875
  helpUrl: `https://github.com/cwtickle/danoniplus/wiki/AboutGameSystem`,
4862
4876
  securityUrl: `https://github.com/cwtickle/danoniplus/security/policy`,
4877
+ keymodeUrl: `https://github.com/cwtickle/danoniplus/wiki/Keys-`,
4863
4878
  },
4864
4879
  En: {
4865
4880
  dataDeleteOFFDesc: `Select the type of data you wish to delete and press "Reset".`,
@@ -4922,6 +4937,7 @@ const g_lang_lblNameObj = {
4922
4937
 
4923
4938
  helpUrl: `https://github.com/cwtickle/danoniplus-docs/wiki/AboutGameSystem`,
4924
4939
  securityUrl: `https://github.com/cwtickle/danoniplus-docs/wiki/SecurityPolicy`,
4940
+ keymodeUrl: `https://github.com/cwtickle/danoniplus-docs/wiki/Keys-`,
4925
4941
  },
4926
4942
  };
4927
4943
 
@@ -4972,6 +4988,8 @@ const g_lang_msgObj = {
4972
4988
  fadein: `譜面を途中から再生します。\n途中から開始した場合はハイスコアを保存しません。`,
4973
4989
  volume: `ゲーム内の音量を設定します。`,
4974
4990
 
4991
+ keymodeHelp: `現在選択中の譜面のキータイプの説明ページへリンクします(外部リンク)`,
4992
+
4975
4993
  graph: `譜面密度や速度変化状況、\n譜面の難易度などの情報を表示します。`,
4976
4994
  dataSave: `ハイスコア、リバース設定、\nキーコンフィグの保存の有無を設定します。`,
4977
4995
  toDisplay: `プレイ画面上のオブジェクトの\n表示・非表示(一部透明度)を設定します。`,
@@ -5078,6 +5096,8 @@ const g_lang_msgObj = {
5078
5096
  fadein: `Plays the chart from the middle.\nIf you start in the middle, the high score will not be saved.`,
5079
5097
  volume: `Set the in-game volume.`,
5080
5098
 
5099
+ keymodeHelp: `Go to the explanation page for the key type of the currently selected chart (External Link).`,
5100
+
5081
5101
  graph: `Displays detailed information about the chart, such as chart's density status, sequences' velocity changes, and chart's difficulty.`,
5082
5102
  dataSave: `Set whether to save the high score, reverse setting, and key config.`,
5083
5103
  toDisplay: `Set the display or non-display (partial transparency) of objects on the play screen.`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "48.4.1",
3
+ "version": "48.5.0",
4
4
  "description": "Dancing☆Onigiri (CW Edition) - Web-based Rhythm Game",
5
5
  "main": "./js/danoni_main.js",
6
6
  "jsdelivr": "./js/danoni_main.js",