danoniplus 51.2.2 → 51.4.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 +3 -3
- package/js/lib/danoni_constants.js +23 -11
- package/js/lib/dataLoader.js +13 -1
- package/js/lib/dosConverter.js +9 -4
- package/js/lib/keyconfig.js +308 -37
- package/js/lib/settings.js +15 -58
- 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/10/
|
|
7
|
+
* Revised : 2026/10/12
|
|
8
8
|
*
|
|
9
9
|
* https://github.com/cwtickle/danoniplus
|
|
10
10
|
*/
|
|
11
|
-
const g_version = `Ver 51.
|
|
12
|
-
const g_revisedDate = `2026/10/
|
|
11
|
+
const g_version = `Ver 51.4.0`;
|
|
12
|
+
const g_revisedDate = `2026/10/12`;
|
|
13
13
|
|
|
14
14
|
// カスタム用バージョン (danoni_custom.js 等で指定可)
|
|
15
15
|
let g_localVersion = ``;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Source by tickle
|
|
7
7
|
* Created : 2019/11/19
|
|
8
|
-
* Revised : 2026/10/
|
|
8
|
+
* Revised : 2026/10/12 (v51.4.0)
|
|
9
9
|
*
|
|
10
10
|
* https://github.com/cwtickle/danoniplus
|
|
11
11
|
*/
|
|
@@ -1406,7 +1406,7 @@ const g_settings = {
|
|
|
1406
1406
|
},
|
|
1407
1407
|
environments: [`adjustment`, `volume`, `colorType`, `appearance`, `opacity`, `hitPosition`,
|
|
1408
1408
|
`arrowJdgX`, `arrowJdgY`, `frzJdgX`, `frzJdgY`, `shortcutX`, `shortcutY`],
|
|
1409
|
-
keyStorages: [`reverse`, `keyCtrl`, `keyCtrlPtn`, `shuffle`, `color`, `stepRtn`],
|
|
1409
|
+
keyStorages: [`reverse`, `keyCtrl`, `keyCtrlPtn`, `shuffle`, `color`, `stepRtn`, `shortcut`],
|
|
1410
1410
|
colorStorages: [`setColor`, `setShadowColor`, `frzColor`, `frzShadowColor`],
|
|
1411
1411
|
|
|
1412
1412
|
mSelectableTerms: 3,
|
|
@@ -1551,6 +1551,12 @@ g_settings.volumeNum = g_settings.volumes.length - 1;
|
|
|
1551
1551
|
g_settings.bgmVolumeNum = roundZero(g_settings.volumes.findIndex(v => v === g_stateObj.bgmVolume));
|
|
1552
1552
|
g_settings.opacityNum = g_settings.opacitys.length - 1;
|
|
1553
1553
|
|
|
1554
|
+
const g_settingWindowTitleKeys = new Map([
|
|
1555
|
+
[optionInit, `Option`],
|
|
1556
|
+
[settingsDisplayInit, `Display`],
|
|
1557
|
+
[exSettingInit, `Settings`],
|
|
1558
|
+
]);
|
|
1559
|
+
|
|
1554
1560
|
/**
|
|
1555
1561
|
* 設定画面間移動
|
|
1556
1562
|
*/
|
|
@@ -2353,6 +2359,9 @@ const g_keycons = {
|
|
|
2353
2359
|
cursorNum: 0,
|
|
2354
2360
|
keySwitchNum: 0,
|
|
2355
2361
|
colorCursorNum: 0,
|
|
2362
|
+
|
|
2363
|
+
shortcutTypes: [`Retry`, `TitleBack`, `Pause`],
|
|
2364
|
+
defaultShortCuts: { Retry: C_KEY_RETRY, TitleBack: C_KEY_TITLEBACK, Pause: C_KEY_PAUSE },
|
|
2356
2365
|
};
|
|
2357
2366
|
|
|
2358
2367
|
let g_displays = [`stepZone`, `judgment`, `lifeGauge`, `score`, `musicInfo`, `filterLine`,
|
|
@@ -2913,7 +2922,7 @@ const g_shortcutObj = {
|
|
|
2913
2922
|
NumpadEnter: { id: `btnPlay` },
|
|
2914
2923
|
ShiftLeft_Tab: { id: `btnBack` },
|
|
2915
2924
|
ShiftRight_Tab: { id: `btnBack` },
|
|
2916
|
-
Tab: { id: `
|
|
2925
|
+
Tab: { id: `btnNextSetting` },
|
|
2917
2926
|
KeyU: { id: `btnSettingSummary` },
|
|
2918
2927
|
},
|
|
2919
2928
|
difSelector: {
|
|
@@ -2948,7 +2957,7 @@ const g_shortcutObj = {
|
|
|
2948
2957
|
NumpadEnter: { id: `lnkDifficulty` },
|
|
2949
2958
|
ShiftLeft_Tab: { id: `btnBack` },
|
|
2950
2959
|
ShiftRight_Tab: { id: `btnBack` },
|
|
2951
|
-
Tab: { id: `
|
|
2960
|
+
Tab: { id: `btnNextSetting` },
|
|
2952
2961
|
KeyU: { id: `btnSettingSummary` },
|
|
2953
2962
|
},
|
|
2954
2963
|
scoreDetail: {
|
|
@@ -2997,7 +3006,7 @@ const g_shortcutObj = {
|
|
|
2997
3006
|
NumpadEnter: { id: `btnPlay` },
|
|
2998
3007
|
ShiftLeft_Tab: { id: `btnBack` },
|
|
2999
3008
|
ShiftRight_Tab: { id: `btnBack` },
|
|
3000
|
-
Tab: { id: `
|
|
3009
|
+
Tab: { id: `btnNextSetting` },
|
|
3001
3010
|
KeyU: { id: `btnSettingSummary` },
|
|
3002
3011
|
},
|
|
3003
3012
|
settingsDisplay: {
|
|
@@ -3094,7 +3103,7 @@ const g_shortcutObj = {
|
|
|
3094
3103
|
NumpadEnter: { id: `btnPlay` },
|
|
3095
3104
|
ShiftLeft_Tab: { id: `btnBack` },
|
|
3096
3105
|
ShiftRight_Tab: { id: `btnBack` },
|
|
3097
|
-
Tab: { id: `
|
|
3106
|
+
Tab: { id: `btnNextSetting` },
|
|
3098
3107
|
KeyU: { id: `btnSettingSummary` },
|
|
3099
3108
|
},
|
|
3100
3109
|
displayPreview: {
|
|
@@ -3113,7 +3122,7 @@ const g_shortcutObj = {
|
|
|
3113
3122
|
NumpadEnter: { id: `btnPlay` },
|
|
3114
3123
|
ShiftLeft_Tab: { id: `btnBack` },
|
|
3115
3124
|
ShiftRight_Tab: { id: `btnBack` },
|
|
3116
|
-
Tab: { id: `
|
|
3125
|
+
Tab: { id: `btnNextSetting` },
|
|
3117
3126
|
},
|
|
3118
3127
|
exSetting: {
|
|
3119
3128
|
ShiftLeft_KeyP: { id: `lnkPlayWindowL` },
|
|
@@ -3154,7 +3163,7 @@ const g_shortcutObj = {
|
|
|
3154
3163
|
Enter: { id: `btnPlay` },
|
|
3155
3164
|
ShiftLeft_Tab: { id: `btnBack` },
|
|
3156
3165
|
ShiftRight_Tab: { id: `btnBack` },
|
|
3157
|
-
Tab: { id: `
|
|
3166
|
+
Tab: { id: `btnNextSetting` },
|
|
3158
3167
|
KeyU: { id: `btnSettingSummary` },
|
|
3159
3168
|
},
|
|
3160
3169
|
keyConfig: {
|
|
@@ -3217,11 +3226,11 @@ const g_btnPatterns = {
|
|
|
3217
3226
|
title: { Start: 0, Comment: -10, MusicSelectRandom: -10 },
|
|
3218
3227
|
dataMgt: { Back: 0, Environment: -35, Highscores: -35, CustomKey: -35, Others: -35 },
|
|
3219
3228
|
precondition: { Back: 0 },
|
|
3220
|
-
option: { Back: 0, KeyConfig: 0, Play: 0,
|
|
3229
|
+
option: { Back: 0, KeyConfig: 0, Play: 0, NextSetting: -5, Save: -10, Graph: -25, SettingSummary: -10 },
|
|
3221
3230
|
difSelector: {},
|
|
3222
3231
|
scoreDetail: {},
|
|
3223
|
-
settingsDisplay: { Back: 0, KeyConfig: 0, Play: 0, Save: -10,
|
|
3224
|
-
exSetting: { Back: 0, KeyConfig: 0, Play: 0,
|
|
3232
|
+
settingsDisplay: { Back: 0, KeyConfig: 0, Play: 0, Save: -10, NextSetting: -5, SettingSummary: -10 },
|
|
3233
|
+
exSetting: { Back: 0, KeyConfig: 0, Play: 0, NextSetting: -5, Save: -10, SettingSummary: -10 },
|
|
3225
3234
|
loadingIos: { Play: 0 },
|
|
3226
3235
|
keyConfig: { Back: -3, Play: 0 },
|
|
3227
3236
|
result: { Back: -5, Copy: -5, Tweet: -5, Gitter: -5, Retry: 0, GaugeTransition: -15 },
|
|
@@ -4655,6 +4664,7 @@ const g_lblNameObj = {
|
|
|
4655
4664
|
b_cReset: `Reset`,
|
|
4656
4665
|
b_precond: `Precondition`,
|
|
4657
4666
|
b_keyLock: `KeyLock`,
|
|
4667
|
+
b_kbLane: `Group Color`,
|
|
4658
4668
|
|
|
4659
4669
|
Difficulty: `Difficulty`,
|
|
4660
4670
|
Speed: `Speed`,
|
|
@@ -5087,6 +5097,7 @@ const g_lang_msgObj = {
|
|
|
5087
5097
|
|
|
5088
5098
|
graph: `譜面密度や速度変化状況、\n譜面の難易度などの情報を表示します。`,
|
|
5089
5099
|
dataSave: `ハイスコア、リバース設定、\nキーコンフィグの保存の有無を設定します。`,
|
|
5100
|
+
toOption: `譜面、速度、ゲージなどの基本設定を設定します。`,
|
|
5090
5101
|
toDisplay: `プレイ画面上のオブジェクトの\n表示・非表示(一部透明度)を設定します。`,
|
|
5091
5102
|
toSettings: `その他の拡張設定を設定します。`,
|
|
5092
5103
|
|
|
@@ -5197,6 +5208,7 @@ const g_lang_msgObj = {
|
|
|
5197
5208
|
|
|
5198
5209
|
graph: `Displays detailed information about the chart, such as chart's density status, sequences' velocity changes, and chart's difficulty.`,
|
|
5199
5210
|
dataSave: `Set whether to save the high score, reverse setting, and key config.`,
|
|
5211
|
+
toOption: `Set basic settings such as chart, speed, and gauge.`,
|
|
5200
5212
|
toDisplay: `Set the display or non-display (partial transparency) of objects on the play screen.`,
|
|
5201
5213
|
toSettings: `Set other extended settings.`,
|
|
5202
5214
|
|
package/js/lib/dataLoader.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Source by tickle
|
|
7
7
|
* Created : 2026/09/13
|
|
8
|
-
* Revised : 2026/10/
|
|
8
|
+
* Revised : 2026/10/10 (v51.3.0)
|
|
9
9
|
*
|
|
10
10
|
* https://github.com/cwtickle/danoniplus
|
|
11
11
|
*/
|
|
@@ -2580,10 +2580,22 @@ const getArrowSettings = (_retryFlg = false) => {
|
|
|
2580
2580
|
storageObj[`keyCtrl${addKey}`] = setKeyCtrl(g_localKeyStorage, keyNum, keyCtrlPtn);
|
|
2581
2581
|
if (g_keyObj.currentPtn !== -1) {
|
|
2582
2582
|
storageObj[`keyCtrlPtn${addKey}`] = g_keyObj.currentPtn;
|
|
2583
|
+
g_keyObj.storagePtn = g_keyObj.currentPtn;
|
|
2583
2584
|
g_keyCtrlBackup[keyCtrlPtn] = structuredClone(g_keyObj[`keyCtrl${keyCtrlPtn}`]);
|
|
2584
2585
|
g_keyObj[`keyCtrl${keyCtrlPtn}`] = structuredClone(g_keyObj[`keyCtrl${keyCtrlPtn}d`]);
|
|
2585
2586
|
}
|
|
2586
2587
|
|
|
2588
|
+
// ショートカットキーの保存(基盤パターンのデフォルトと異なるものだけ)
|
|
2589
|
+
const savedShortcut = {};
|
|
2590
|
+
const isDefaultShortcut = _type => g_headerObj[`key${_type}`] === getDefaultShortcut(_type);
|
|
2591
|
+
g_keycons.shortcutTypes.filter(type => !isDefaultShortcut(type))
|
|
2592
|
+
.forEach(type => savedShortcut[type] = g_headerObj[`key${type}`]);
|
|
2593
|
+
if (Object.keys(savedShortcut).length > 0) {
|
|
2594
|
+
storageObj[`shortcut${addKey}`] = savedShortcut;
|
|
2595
|
+
} else {
|
|
2596
|
+
delete storageObj[`shortcut${addKey}`];
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2587
2599
|
// カラーセットの保存(キー別)
|
|
2588
2600
|
if (!g_keycons.colorDefTypes.includes(g_colorType)) {
|
|
2589
2601
|
|
package/js/lib/dosConverter.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Source by tickle
|
|
7
7
|
* Created : 2026/09/13
|
|
8
|
-
* Revised : 2026/
|
|
8
|
+
* Revised : 2026/10/12 (v51.4.0)
|
|
9
9
|
*
|
|
10
10
|
* https://github.com/cwtickle/danoniplus
|
|
11
11
|
*/
|
|
@@ -1182,13 +1182,10 @@ const headerConvert = _dosObj => {
|
|
|
1182
1182
|
|
|
1183
1183
|
// プレイ中のショートカットキー
|
|
1184
1184
|
obj.keyRetry = setIntVal(getKeyCtrlVal(_dosObj.keyRetry), C_KEY_RETRY);
|
|
1185
|
-
obj.keyRetryDef = obj.keyRetry;
|
|
1186
1185
|
obj.keyRetryDef2 = obj.keyRetry;
|
|
1187
1186
|
obj.keyTitleBack = setIntVal(getKeyCtrlVal(_dosObj.keyTitleBack), C_KEY_TITLEBACK);
|
|
1188
|
-
obj.keyTitleBackDef = obj.keyTitleBack;
|
|
1189
1187
|
obj.keyTitleBackDef2 = obj.keyTitleBack;
|
|
1190
1188
|
obj.keyPause = setIntVal(getKeyCtrlVal(_dosObj.keyPause), C_KEY_PAUSE);
|
|
1191
|
-
obj.keyPauseDef = obj.keyPause;
|
|
1192
1189
|
obj.keyPauseDef2 = obj.keyPause;
|
|
1193
1190
|
|
|
1194
1191
|
// フリーズアローの許容フレーム数設定
|
|
@@ -1668,6 +1665,14 @@ const headerConvert = _dosObj => {
|
|
|
1668
1665
|
g_canDisabledSettings.forEach(option =>
|
|
1669
1666
|
obj[`${option}Use`] = setBoolVal(_dosObj[`${option}Use`] ?? g_presetObj.settingUse?.[option], true));
|
|
1670
1667
|
|
|
1668
|
+
// 拡張機能の無効設定
|
|
1669
|
+
if (!setBoolVal(_dosObj.displayWindowUse, true)) {
|
|
1670
|
+
g_settings.settingWindows = g_settings.settingWindows.filter(option => option !== settingsDisplayInit);
|
|
1671
|
+
}
|
|
1672
|
+
if (!setBoolVal(_dosObj.exSettingWindowUse, true)) {
|
|
1673
|
+
g_settings.settingWindows = g_settings.settingWindows.filter(option => option !== exSettingInit);
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1671
1676
|
let interlockingErrorFlg = false;
|
|
1672
1677
|
g_displays.forEach((option, j) => {
|
|
1673
1678
|
|
package/js/lib/keyconfig.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Source by tickle
|
|
7
7
|
* Created : 2026/09/13
|
|
8
|
-
* Revised : 2026/
|
|
8
|
+
* Revised : 2026/10/12 (v51.4.0)
|
|
9
9
|
*
|
|
10
10
|
* https://github.com/cwtickle/danoniplus
|
|
11
11
|
*/
|
|
@@ -33,6 +33,7 @@ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
|
|
|
33
33
|
if (_initFlg) {
|
|
34
34
|
g_stateObj.keyLockFlg = false;
|
|
35
35
|
g_stateObj.kbPreviewFlg = false;
|
|
36
|
+
g_stateObj.kbLaneFlg = false;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
multiAppend(divRoot,
|
|
@@ -400,6 +401,9 @@ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
|
|
|
400
401
|
viewGroup(_type);
|
|
401
402
|
if (_type === `stepRtn`) {
|
|
402
403
|
keyConfigInit(g_kcType);
|
|
404
|
+
} else if (_type === `color`) {
|
|
405
|
+
// カラーグループ変更時はレーン色分けプレビューへ反映
|
|
406
|
+
keyconfigKeyboardPreview.refresh();
|
|
403
407
|
}
|
|
404
408
|
};
|
|
405
409
|
|
|
@@ -480,6 +484,21 @@ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
|
|
|
480
484
|
viewGroup(_type);
|
|
481
485
|
};
|
|
482
486
|
|
|
487
|
+
/**
|
|
488
|
+
* ショートカットキーボタンの表示更新
|
|
489
|
+
* @param {string} _type Retry / TitleBack / Pause
|
|
490
|
+
*/
|
|
491
|
+
const updateScButton = _type => {
|
|
492
|
+
const siz = wUnit(getFontSize2(getScMsg[_type](), g_btnWidth(1 / 4) - 40, { maxSiz: g_limitObj.mainSiz }));
|
|
493
|
+
document.getElementById(`sc${_type}`).textContent = getScMsg[_type]();
|
|
494
|
+
document.getElementById(`sc${_type}`).style.fontSize = siz;
|
|
495
|
+
if (g_isMac) {
|
|
496
|
+
scTitleBack.textContent = getScMsg.TitleBack();
|
|
497
|
+
scTitleBack.style.fontSize = wUnit(getFontSize2(getScMsg.TitleBack(), g_btnWidth(1 / 4) - 40, { maxSiz: g_limitObj.mainSiz }));
|
|
498
|
+
}
|
|
499
|
+
changeConfigColor(document.getElementById(`sc${_type}`), getScButtonColor(_type));
|
|
500
|
+
};
|
|
501
|
+
|
|
483
502
|
const kcSubX = parseFloat(keyconSprite.style.width) * ((1 - g_keyObj.scale) / 4);
|
|
484
503
|
const kcSubY = parseFloat(keyconSprite.style.height) / ((1 + g_keyObj.scale) / 2) - parseFloat(keyconSprite.style.height);
|
|
485
504
|
multiAppend(divRoot,
|
|
@@ -494,27 +513,21 @@ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
|
|
|
494
513
|
cursor.style.top = wUnit(g_sHeight - 160 + kcSubY);
|
|
495
514
|
selectedKc = `TitleBack`;
|
|
496
515
|
}
|
|
497
|
-
}, g_lblPosObj.scTitleBack, g_cssObj.button_Default_NoColor,
|
|
498
|
-
g_headerObj.keyTitleBack === g_headerObj.keyTitleBackDef2 ?
|
|
499
|
-
g_cssObj.title_base : g_cssObj.keyconfig_Changekey),
|
|
516
|
+
}, g_lblPosObj.scTitleBack, g_cssObj.button_Default_NoColor, getScButtonColor(`TitleBack`)),
|
|
500
517
|
|
|
501
518
|
// リトライのショートカットキー変更
|
|
502
519
|
createCss2Button(`scRetry`, getScMsg.Retry(), () => {
|
|
503
520
|
cursor.style.left = wUnit(g_btnX(1 / 2) + kcSubX);
|
|
504
521
|
cursor.style.top = wUnit(g_sHeight - 160 + kcSubY);
|
|
505
522
|
selectedKc = `Retry`;
|
|
506
|
-
}, g_lblPosObj.scRetry, g_cssObj.button_Default_NoColor,
|
|
507
|
-
g_headerObj.keyRetry === g_headerObj.keyRetryDef2 ?
|
|
508
|
-
g_cssObj.title_base : g_cssObj.keyconfig_Changekey),
|
|
523
|
+
}, g_lblPosObj.scRetry, g_cssObj.button_Default_NoColor, getScButtonColor(`Retry`)),
|
|
509
524
|
|
|
510
525
|
// ポーズのショートカットキー変更
|
|
511
526
|
createCss2Button(`scPause`, getScMsg.Pause(), () => {
|
|
512
527
|
cursor.style.left = wUnit(g_btnX(3 / 4) + kcSubX);
|
|
513
528
|
cursor.style.top = wUnit(g_sHeight - 160 + kcSubY);
|
|
514
529
|
selectedKc = `Pause`;
|
|
515
|
-
}, g_lblPosObj.scPause, g_cssObj.button_Default_NoColor,
|
|
516
|
-
g_headerObj.keyPause === g_headerObj.keyPauseDef2 ?
|
|
517
|
-
g_cssObj.title_base : g_cssObj.keyconfig_Changekey),
|
|
530
|
+
}, g_lblPosObj.scPause, g_cssObj.button_Default_NoColor, getScButtonColor(`Pause`)),
|
|
518
531
|
|
|
519
532
|
// 別キーモード警告メッセージ
|
|
520
533
|
createDivCss2Label(
|
|
@@ -571,6 +584,11 @@ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
|
|
|
571
584
|
|
|
572
585
|
// 次の位置が見えなくなったらkeyconSpriteの位置を調整する
|
|
573
586
|
adjustScrollPoint(nextLeft);
|
|
587
|
+
|
|
588
|
+
// レーン色分けプレビュー中はカーソルレーンの強調を更新
|
|
589
|
+
if (g_stateObj.kbLaneFlg) {
|
|
590
|
+
keyconfigKeyboardPreview.refresh();
|
|
591
|
+
}
|
|
574
592
|
};
|
|
575
593
|
|
|
576
594
|
/**
|
|
@@ -973,6 +991,10 @@ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
|
|
|
973
991
|
changeKeyConfigColor(j, k, g_keyObj.currentPtn === -1 ? g_cssObj.keyconfig_Defaultkey : g_cssObj.title_base);
|
|
974
992
|
}
|
|
975
993
|
}
|
|
994
|
+
g_keycons.shortcutTypes.forEach(type => {
|
|
995
|
+
g_headerObj[`key${type}`] = getDefaultShortcut(type);
|
|
996
|
+
updateScButton(type);
|
|
997
|
+
});
|
|
976
998
|
changeConfigCursor(0);
|
|
977
999
|
}
|
|
978
1000
|
}, g_lblPosObj.btnKcReset, g_cssObj.button_Reset),
|
|
@@ -1035,17 +1057,7 @@ const keyConfigInit = (_kcType = g_kcType, _initFlg = false) => {
|
|
|
1035
1057
|
}
|
|
1036
1058
|
// プレイ中ショートカットキー変更
|
|
1037
1059
|
g_headerObj[`key${selectedKc}`] = setKey;
|
|
1038
|
-
|
|
1039
|
-
document.getElementById(`sc${selectedKc}`).textContent = getScMsg[selectedKc]();
|
|
1040
|
-
document.getElementById(`sc${selectedKc}`).style.fontSize =
|
|
1041
|
-
wUnit(getFontSize2(getScMsg[selectedKc](), g_btnWidth(1 / 4) - 40, { maxSiz: g_limitObj.mainSiz }));
|
|
1042
|
-
if (g_isMac) {
|
|
1043
|
-
scTitleBack.textContent = getScMsg.TitleBack();
|
|
1044
|
-
scTitleBack.style.fontSize = wUnit(getFontSize2(getScMsg.TitleBack(), g_btnWidth(1 / 4) - 40, { maxSiz: g_limitObj.mainSiz }));
|
|
1045
|
-
}
|
|
1046
|
-
changeConfigColor(document.getElementById(`sc${selectedKc}`),
|
|
1047
|
-
g_headerObj[`key${selectedKc}`] === g_headerObj[`key${selectedKc}Def2`] ?
|
|
1048
|
-
g_cssObj.title_base : g_cssObj.keyconfig_Changekey);
|
|
1060
|
+
updateScButton(selectedKc);
|
|
1049
1061
|
return;
|
|
1050
1062
|
}
|
|
1051
1063
|
|
|
@@ -1131,6 +1143,61 @@ const completeTransKeyPtn = (_keyList) => {
|
|
|
1131
1143
|
});
|
|
1132
1144
|
};
|
|
1133
1145
|
|
|
1146
|
+
/**
|
|
1147
|
+
* 別キーモード時、移行先キーが保持するSelf保存パターンの取得可否チェック
|
|
1148
|
+
* @param {string} _keyCtrlPtn 例: "7_2"
|
|
1149
|
+
* @returns {number[][]|undefined} 適用可能な場合はSelf保存済みkeyCtrl配列、不可ならundefined
|
|
1150
|
+
*/
|
|
1151
|
+
const getTransKeySelfCtrl = (_keyCtrlPtn) => {
|
|
1152
|
+
const transKeyName = g_keyObj[`transKey${_keyCtrlPtn}`];
|
|
1153
|
+
const transKeyPtn = g_keyObj[`transKeyPtn${_keyCtrlPtn}`];
|
|
1154
|
+
if (!hasVal(transKeyName) || transKeyPtn === undefined) {
|
|
1155
|
+
return undefined;
|
|
1156
|
+
}
|
|
1157
|
+
const [storageObj, addKey] = getKeyStorageObjByName(transKeyName);
|
|
1158
|
+
const savedCtrl = storageObj[`keyCtrl${addKey}`];
|
|
1159
|
+
const savedPtn = storageObj[`keyCtrlPtn${addKey}`];
|
|
1160
|
+
|
|
1161
|
+
if (savedPtn !== transKeyPtn) {
|
|
1162
|
+
return undefined;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
// 現在のキー配置(基準形状)とレーン数・各レーン長が完全一致することを確認
|
|
1166
|
+
const baseCtrl = g_keyObj[`keyCtrl${_keyCtrlPtn}`];
|
|
1167
|
+
const isValidShape = hasArrayList(savedCtrl, baseCtrl.length) &&
|
|
1168
|
+
savedCtrl.length === baseCtrl.length &&
|
|
1169
|
+
baseCtrl.every((lane, j) => hasArrayList(savedCtrl[j], lane.length) && savedCtrl[j].length === lane.length);
|
|
1170
|
+
|
|
1171
|
+
return isValidShape ? savedCtrl : undefined;
|
|
1172
|
+
};
|
|
1173
|
+
|
|
1174
|
+
/**
|
|
1175
|
+
* 別キーモードの移行先Selfパターンを現在のキー配置へ反映(保存はしない)
|
|
1176
|
+
*/
|
|
1177
|
+
const applyTransKeySelfPattern = () => {
|
|
1178
|
+
const keyCtrlPtn = `${g_keyObj.currentKey}_${g_keyObj.currentPtn}`;
|
|
1179
|
+
const savedCtrl = getTransKeySelfCtrl(keyCtrlPtn);
|
|
1180
|
+
if (savedCtrl === undefined) {
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
const baseKeyNum = g_keyObj[`${g_keyObj.defaultProp}${keyCtrlPtn}`].length;
|
|
1184
|
+
for (let j = 0; j < baseKeyNum; j++) {
|
|
1185
|
+
for (let k = 0; k < (savedCtrl[j]?.length ?? 0); k++) {
|
|
1186
|
+
g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k] = setIntVal(savedCtrl[j][k], 0);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
// ショートカットも取込元の保存内容で上書き(レーンキーと重複するものは無視)
|
|
1190
|
+
const [storageObj, addKey] = getKeyStorageObjByName(g_keyObj[`transKey${keyCtrlPtn}`]);
|
|
1191
|
+
const savedShortcut = storageObj[`shortcut${addKey}`] ?? {};
|
|
1192
|
+
const usedKeys = g_keyObj[`keyCtrl${keyCtrlPtn}`].flat();
|
|
1193
|
+
g_keycons.shortcutTypes.forEach(type => {
|
|
1194
|
+
const savedKey = savedShortcut[type];
|
|
1195
|
+
g_headerObj[`key${type}`] = (savedKey !== undefined && !usedKeys.includes(savedKey))
|
|
1196
|
+
? savedKey : getDefaultShortcut(type);
|
|
1197
|
+
});
|
|
1198
|
+
keyConfigInit();
|
|
1199
|
+
};
|
|
1200
|
+
|
|
1134
1201
|
// KeyLockボタンを押したときの表示切替
|
|
1135
1202
|
const toggleKcDesc = () => {
|
|
1136
1203
|
if (document.getElementById(`kcDesc`) !== null) {
|
|
@@ -1152,6 +1219,44 @@ const getKcDescMsg = () =>
|
|
|
1152
1219
|
const getKeyLockName = () =>
|
|
1153
1220
|
`${g_lblNameObj.b_keyLock}${g_stateObj.keyLockFlg ? g_emojiObj.locked : g_emojiObj.unlocked}`;
|
|
1154
1221
|
|
|
1222
|
+
/** 保存・Self時に基準とするキーパターン番号 */
|
|
1223
|
+
const getBasePtn = () => g_keyObj.currentPtn === -1 ? g_keyObj.storagePtn : g_keyObj.currentPtn;
|
|
1224
|
+
|
|
1225
|
+
/**
|
|
1226
|
+
* ショートカットキーのデフォルト値(基盤パターン基準)
|
|
1227
|
+
* 優先順: ヘッダー指定 > パターン別定義(keyRetryX_Y等) > 定数
|
|
1228
|
+
* @params {string} _type Retry / TitleBack / Pause
|
|
1229
|
+
* @returns {number}
|
|
1230
|
+
*/
|
|
1231
|
+
const getDefaultShortcut = _type => {
|
|
1232
|
+
const baseVal = g_keycons.defaultShortCuts[_type];
|
|
1233
|
+
const headerVal = g_headerObj[`key${_type}Def2`];
|
|
1234
|
+
if (headerVal !== baseVal) {
|
|
1235
|
+
return headerVal;
|
|
1236
|
+
}
|
|
1237
|
+
return setIntVal(getKeyCtrlVal(g_keyObj[`key${_type}${g_keyObj.currentKey}_${getBasePtn()}`]), headerVal);
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1240
|
+
/**
|
|
1241
|
+
* ショートカットキーボタンの色クラスを取得
|
|
1242
|
+
* - ロード済みの保存値(Self)と同じ: Defaultkey
|
|
1243
|
+
* - 基準値(保存値 or パターンのデフォルト)と違う: Changekey
|
|
1244
|
+
* - 通常パターンでデフォルトのまま: title_base
|
|
1245
|
+
* @param {string} _type Retry / TitleBack / Pause
|
|
1246
|
+
* @returns {string}
|
|
1247
|
+
*/
|
|
1248
|
+
const getScButtonColor = _type => {
|
|
1249
|
+
const current = g_headerObj[`key${_type}`];
|
|
1250
|
+
const loaded = g_keyObj.currentPtn === -1
|
|
1251
|
+
? g_keyObj[`shortcut${g_keyObj.currentKey}_-1`]?.[_type] : undefined;
|
|
1252
|
+
|
|
1253
|
+
// ロード済みの保存値のまま
|
|
1254
|
+
if (loaded !== undefined && current === loaded) {
|
|
1255
|
+
return g_cssObj.keyconfig_Defaultkey;
|
|
1256
|
+
}
|
|
1257
|
+
// 本当のデフォルト(BackSpace/Delete/Pause)と違う場合は、変更の経緯を問わずChangekey
|
|
1258
|
+
return current !== g_keycons.defaultShortCuts[_type] ? g_cssObj.keyconfig_Changekey : g_cssObj.title_base;
|
|
1259
|
+
};
|
|
1155
1260
|
/**
|
|
1156
1261
|
* キーボードレイアウトプレビュー(Canvas版)
|
|
1157
1262
|
*
|
|
@@ -1215,11 +1320,22 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1215
1320
|
},
|
|
1216
1321
|
bgFill: `#0d0d1a`, // Canvas 背景
|
|
1217
1322
|
legendText: `#cccccc`, // 凡例テキスト
|
|
1323
|
+
|
|
1324
|
+
// レーン色分けモード用(凡例と文字色。レーン色自体は g_dfColorObj.setColorType2 を使用)
|
|
1325
|
+
// 枠線は未割当キーと同色に統一し、メイン/代替は塗りのアルファのみで区別する
|
|
1326
|
+
laneMain: { fill: `#cccccc`, stroke: `#555577` },
|
|
1327
|
+
laneAlt: { fill: `rgba(204,204,204,0.35)`, stroke: `#555577` },
|
|
1328
|
+
laneAltBright: { fill: `rgba(204,204,204,0.6)`, stroke: `#555577` },
|
|
1329
|
+
laneStroke: `#555577`,
|
|
1330
|
+
laneText: `#111111`,
|
|
1218
1331
|
};
|
|
1219
1332
|
|
|
1220
1333
|
// 凡例エリアの高さ
|
|
1221
1334
|
const LEGEND_H = 25;
|
|
1222
1335
|
|
|
1336
|
+
// レーン色分けモードで、同一キーに割り当てられた色を分割描画する上限数
|
|
1337
|
+
const C_LANE_SPLIT_MAX = 3;
|
|
1338
|
+
|
|
1223
1339
|
// -------------------------------------------------------------------------
|
|
1224
1340
|
// キーレイアウト定義
|
|
1225
1341
|
//
|
|
@@ -1379,6 +1495,7 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1379
1495
|
mappedSet: new Set(), // メインキー(code文字列)
|
|
1380
1496
|
altSet: new Set(), // 代替キー(code文字列)
|
|
1381
1497
|
shortcutSet: new Set(), // ショートカットキー(code文字列)
|
|
1498
|
+
laneMap: new Map(), // code文字列 → { entries: [{ colorPos, alt }], cursor: boolean }
|
|
1382
1499
|
canvasBase: null,
|
|
1383
1500
|
canvasMap: null,
|
|
1384
1501
|
keyDataList: [], // { code, x, y, w, h, label } — drawMap で照合するキャッシュ
|
|
@@ -1524,13 +1641,16 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1524
1641
|
* @param {Object} keyData - 位置・サイズ・キーコードを含むキー情報
|
|
1525
1642
|
* @param {Object} style - fill, stroke, text 等の色セット
|
|
1526
1643
|
* @param {number} lw - 枠線の太さ(lineWidth)
|
|
1644
|
+
* @param {boolean} shapeFlg - 枠線・背景を描画するかどうか(false の場合はテキストのみ描画)
|
|
1527
1645
|
*/
|
|
1528
|
-
const drawOneKey = (ctx, { keyData, style, lw = 1 }) => {
|
|
1646
|
+
const drawOneKey = (ctx, { keyData, style, lw = 1, shapeFlg = true }) => {
|
|
1529
1647
|
const { x, y, w: keyW, h: keyH, code, label } = keyData;
|
|
1530
1648
|
|
|
1531
1649
|
// 1. キーの枠線・背景を描画
|
|
1532
|
-
|
|
1533
|
-
|
|
1650
|
+
if (shapeFlg) {
|
|
1651
|
+
roundRect(ctx, x + 0.5, y + 0.5, keyW - 1, keyH - 1, kr());
|
|
1652
|
+
fillStrokeShape(ctx, { fill: style.fill, stroke: style.stroke, lineWidth: lw });
|
|
1653
|
+
}
|
|
1534
1654
|
|
|
1535
1655
|
// 2. キー内部のテキスト(メイン・サブ)を描画
|
|
1536
1656
|
const [primary, sub] = getKeyLabels(code, label);
|
|
@@ -1648,9 +1768,13 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1648
1768
|
|
|
1649
1769
|
const legends = [
|
|
1650
1770
|
{ style: C_COLOR.normal, label: g_lblNameObj.unallocated },
|
|
1651
|
-
{ style: C_COLOR.mapped, label: g_lblNameObj.allocated },
|
|
1652
|
-
{
|
|
1653
|
-
|
|
1771
|
+
{ style: g_stateObj.kbLaneFlg ? C_COLOR.laneMain : C_COLOR.mapped, label: g_lblNameObj.allocated },
|
|
1772
|
+
{
|
|
1773
|
+
style: g_stateObj.kbLaneFlg
|
|
1774
|
+
? (g_headerObj.baseBrightFlg ? C_COLOR.laneAltBright : C_COLOR.laneAlt) : C_COLOR.alt,
|
|
1775
|
+
label: g_lblNameObj.altAllocated,
|
|
1776
|
+
},
|
|
1777
|
+
{ style: C_COLOR.shortcut, label: g_lblNameObj.shortcutKey },
|
|
1654
1778
|
];
|
|
1655
1779
|
|
|
1656
1780
|
let lx = 8;
|
|
@@ -1665,6 +1789,111 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1665
1789
|
});
|
|
1666
1790
|
};
|
|
1667
1791
|
|
|
1792
|
+
/**
|
|
1793
|
+
* 明度が低い色を、未割当キーと区別できる下限まで持ち上げる
|
|
1794
|
+
* @param {string} _hex #rrggbb 形式の色
|
|
1795
|
+
* @param {number} _minLum 下限値(RGBの最大成分で判定)
|
|
1796
|
+
* @returns {string}
|
|
1797
|
+
*/
|
|
1798
|
+
const liftDarkColor = (_hex, _minLum = 0x66) => {
|
|
1799
|
+
const n = parseInt(_hex.slice(1, 7), 16);
|
|
1800
|
+
const [r, g, b] = [(n >> 16) & 255, (n >> 8) & 255, n & 255];
|
|
1801
|
+
const lum = Math.max(r, g, b);
|
|
1802
|
+
if (lum >= _minLum) {
|
|
1803
|
+
return _hex;
|
|
1804
|
+
}
|
|
1805
|
+
const d = _minLum - lum;
|
|
1806
|
+
return `#${[r, g, b].map(v => (v + d).toString(16).padStart(2, `0`)).join(``)}`;
|
|
1807
|
+
};
|
|
1808
|
+
|
|
1809
|
+
/**
|
|
1810
|
+
* #rrggbb 形式の色にアルファ値を付与する
|
|
1811
|
+
* @param {string} _hex
|
|
1812
|
+
* @param {number} _alpha
|
|
1813
|
+
* @returns {string}
|
|
1814
|
+
*/
|
|
1815
|
+
const hexToRgba = (_hex, _alpha) => {
|
|
1816
|
+
const n = parseInt(_hex.slice(1, 7), 16);
|
|
1817
|
+
return `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${_alpha})`;
|
|
1818
|
+
};
|
|
1819
|
+
|
|
1820
|
+
/**
|
|
1821
|
+
* レーン色分けモードのスタイル取得(色は譜面ミニマップと同じ setColorType2 固定)
|
|
1822
|
+
* @param {number} _colorPos カラーグループ番号
|
|
1823
|
+
* @param {boolean} _altFlg 代替キーか
|
|
1824
|
+
*/
|
|
1825
|
+
const getLaneStyle = (_colorPos, _altFlg) => {
|
|
1826
|
+
const brightFlg = g_headerObj.baseBrightFlg;
|
|
1827
|
+
const baseColor = g_dfColorObj.setColorType2[_colorPos] ?? `#ffffff`;
|
|
1828
|
+
|
|
1829
|
+
// 明背景のみ、黒に近い色を未割当キーと区別できる明るさまで持ち上げる
|
|
1830
|
+
const color = brightFlg ? liftDarkColor(baseColor) : baseColor;
|
|
1831
|
+
// 明背景では暗色セットが使われるため、文字は白にする
|
|
1832
|
+
const mainText = brightFlg ? `#ffffff` : C_COLOR.laneText;
|
|
1833
|
+
if (!_altFlg) {
|
|
1834
|
+
return { fill: color, text: mainText };
|
|
1835
|
+
}
|
|
1836
|
+
return brightFlg
|
|
1837
|
+
? { fill: hexToRgba(color, 0.6), text: `#ffffff` }
|
|
1838
|
+
: { fill: hexToRgba(color, 0.35), text: color };
|
|
1839
|
+
};
|
|
1840
|
+
|
|
1841
|
+
/**
|
|
1842
|
+
* レーン色分けモードでの単一キー描画
|
|
1843
|
+
* - 複数色の場合は縦方向に等分割して塗り分ける
|
|
1844
|
+
* @param {CanvasRenderingContext2D} ctx
|
|
1845
|
+
* @param {Object} keyData
|
|
1846
|
+
* @param {{colorPos: number, alt: boolean}[]} entries
|
|
1847
|
+
* @param {boolean} cursorFlg カーソル中のレーンか
|
|
1848
|
+
*/
|
|
1849
|
+
const drawLaneKey = (ctx, keyData, entries, cursorFlg) => {
|
|
1850
|
+
const { x, y, w: keyW, h: keyH } = keyData;
|
|
1851
|
+
const styles = entries.map(val => getLaneStyle(val.colorPos, val.alt));
|
|
1852
|
+
const segW = keyW / styles.length;
|
|
1853
|
+
|
|
1854
|
+
styles.forEach((style, i) => {
|
|
1855
|
+
ctx.save();
|
|
1856
|
+
ctx.beginPath();
|
|
1857
|
+
ctx.rect(x + segW * i, y, segW, keyH);
|
|
1858
|
+
ctx.clip();
|
|
1859
|
+
roundRect(ctx, x + 0.5, y + 0.5, keyW - 1, keyH - 1, kr());
|
|
1860
|
+
fillStrokeShape(ctx, { fill: style.fill });
|
|
1861
|
+
ctx.restore();
|
|
1862
|
+
});
|
|
1863
|
+
|
|
1864
|
+
// 枠線はキー全体に対して1回だけ、全キー共通の色で描画
|
|
1865
|
+
roundRect(ctx, x + 0.5, y + 0.5, keyW - 1, keyH - 1, kr());
|
|
1866
|
+
fillStrokeShape(ctx, { stroke: C_COLOR.laneStroke, lineWidth: 1.5 });
|
|
1867
|
+
|
|
1868
|
+
// 文字は全体に1回だけ描画(メインが含まれる場合はメインの文字色)
|
|
1869
|
+
const mainIdx = entries.findIndex(val => !val.alt);
|
|
1870
|
+
const textColor = styles[mainIdx >= 0 ? mainIdx : 0].text;
|
|
1871
|
+
drawOneKey(ctx, { keyData, style: { text: textColor }, shapeFlg: false });
|
|
1872
|
+
|
|
1873
|
+
// カーソル中のレーンは白枠で強調
|
|
1874
|
+
if (cursorFlg) {
|
|
1875
|
+
roundRect(ctx, x + 0.5, y + 0.5, keyW - 1, keyH - 1, kr());
|
|
1876
|
+
fillStrokeShape(ctx, { stroke: `#ffffff`, lineWidth: 2.5 });
|
|
1877
|
+
}
|
|
1878
|
+
};
|
|
1879
|
+
|
|
1880
|
+
/**
|
|
1881
|
+
* レーン色分けモードのマッピング描画(ショートカットキーは専用色で最優先)
|
|
1882
|
+
* @param {CanvasRenderingContext2D} ctx
|
|
1883
|
+
*/
|
|
1884
|
+
const drawLaneMap = ctx => {
|
|
1885
|
+
_state.keyDataList.forEach(keyData => {
|
|
1886
|
+
if (_state.shortcutSet.has(keyData.code)) {
|
|
1887
|
+
drawOneKey(ctx, { keyData, style: C_COLOR.shortcut, lw: 1.5 });
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1890
|
+
const info = _state.laneMap.get(keyData.code);
|
|
1891
|
+
if (info !== undefined) {
|
|
1892
|
+
drawLaneKey(ctx, keyData, info.entries, info.cursor);
|
|
1893
|
+
}
|
|
1894
|
+
});
|
|
1895
|
+
};
|
|
1896
|
+
|
|
1668
1897
|
/**
|
|
1669
1898
|
* マッピング強調レイヤーを再描画する。
|
|
1670
1899
|
* メインキー(mappedSet)を青系、代替キー(altSet)を黄系で色分けする。
|
|
@@ -1675,6 +1904,11 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1675
1904
|
|
|
1676
1905
|
ctx.clearRect(0, 0, _state.cvsW, _state.cvsH);
|
|
1677
1906
|
|
|
1907
|
+
if (g_stateObj.kbLaneFlg) {
|
|
1908
|
+
drawLaneMap(ctx);
|
|
1909
|
+
return;
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1678
1912
|
// キー状態に応じた色取得ロジック(優先度: ショートカット > メイン > 代替)
|
|
1679
1913
|
const getKeyStyle = (code) => {
|
|
1680
1914
|
if (_state.shortcutSet.has(code)) return C_COLOR.shortcut;
|
|
@@ -1719,6 +1953,16 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1719
1953
|
pointerEvents: C_DIS_AUTO, background: `#00000080`, display: C_DIS_NONE, overflow: `hidden`,
|
|
1720
1954
|
});
|
|
1721
1955
|
|
|
1956
|
+
// レーン色分け表示の切替ボタン(プレビューエリア内の上部余白に配置)
|
|
1957
|
+
const getLaneBtnName = () => `${g_lblNameObj.b_kbLane ?? `Lane Color`}: ${boolToSwitch(!!g_stateObj.kbLaneFlg)}`;
|
|
1958
|
+
const btnLane = createCss2Button(`btnKbLane`, getLaneBtnName(), () => {
|
|
1959
|
+
g_stateObj.kbLaneFlg = !g_stateObj.kbLaneFlg;
|
|
1960
|
+
btnLane.textContent = getLaneBtnName();
|
|
1961
|
+
drawBase(); // 凡例の切替
|
|
1962
|
+
refresh();
|
|
1963
|
+
}, { x: _state.cvsW - 130, y: 10, w: 120, h: 22, siz: 12 }, g_cssObj.button_Mini);
|
|
1964
|
+
areaDiv.appendChild(btnLane);
|
|
1965
|
+
|
|
1722
1966
|
/**
|
|
1723
1967
|
* プレビュー用canvasを生成しareaDivに追加、_stateに登録する
|
|
1724
1968
|
* @param {string} _id
|
|
@@ -1777,6 +2021,33 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1777
2021
|
[g_headerObj.keyRetry, g_headerObj.keyTitleBack, g_headerObj.keyPause, 34, 33].map(toCodeStr).filter(v => v !== ``)
|
|
1778
2022
|
);
|
|
1779
2023
|
|
|
2024
|
+
// レーン色分け用: キーコード → 割り当て先レーンのカラーグループ情報
|
|
2025
|
+
const colorList = g_keyObj[`color${tkObj.keyCtrlPtn}`];
|
|
2026
|
+
_state.laneMap = new Map();
|
|
2027
|
+
g_keyObj[`keyCtrl${tkObj.keyCtrlPtn}`].forEach((arr, j) => {
|
|
2028
|
+
if (!tkObj.keyGroupMaps[j].includes(configKeyGroupList[g_keycons.keySwitchNum])) {
|
|
2029
|
+
return;
|
|
2030
|
+
}
|
|
2031
|
+
arr.forEach((num, k) => {
|
|
2032
|
+
const code = toCodeStr(num);
|
|
2033
|
+
if (code === ``) {
|
|
2034
|
+
return;
|
|
2035
|
+
}
|
|
2036
|
+
const info = _state.laneMap.get(code) ?? { entries: [], cursor: false };
|
|
2037
|
+
const [colorPos, alt] = [colorList[j], k > 0];
|
|
2038
|
+
if (!info.entries.some(val => val.colorPos === colorPos && val.alt === alt)) {
|
|
2039
|
+
info.entries.push({ colorPos, alt });
|
|
2040
|
+
}
|
|
2041
|
+
info.cursor ||= (j === g_currentj);
|
|
2042
|
+
_state.laneMap.set(code, info);
|
|
2043
|
+
});
|
|
2044
|
+
});
|
|
2045
|
+
// メイン優先で並べ、分割数は上限まで
|
|
2046
|
+
_state.laneMap.forEach(info => {
|
|
2047
|
+
info.entries.sort((a, b) => Number(a.alt) - Number(b.alt));
|
|
2048
|
+
info.entries = info.entries.slice(0, C_LANE_SPLIT_MAX);
|
|
2049
|
+
});
|
|
2050
|
+
|
|
1780
2051
|
if (_state.visible) drawMap();
|
|
1781
2052
|
};
|
|
1782
2053
|
|
|
@@ -1789,6 +2060,7 @@ const keyconfigKeyboardPreview = (() => {
|
|
|
1789
2060
|
_state.mappedSet = new Set();
|
|
1790
2061
|
_state.altSet = new Set();
|
|
1791
2062
|
_state.shortcutSet = new Set();
|
|
2063
|
+
_state.laneMap = new Map();
|
|
1792
2064
|
_state.keyDataList = [];
|
|
1793
2065
|
_state.canvasBase = null;
|
|
1794
2066
|
_state.canvasMap = null;
|
|
@@ -1826,19 +2098,18 @@ const getShadowColor = (_colorPos, _arrowColor) => g_headerObj.setShadowColor[_c
|
|
|
1826
2098
|
|
|
1827
2099
|
/**
|
|
1828
2100
|
* デフォルトの曲中ショートカットをキー数・キーパターンにより切り替え
|
|
1829
|
-
* -
|
|
2101
|
+
* - Self(-1)のときは保存済みの値を優先(レーンキーと重複する場合は無視)
|
|
2102
|
+
* - それ以外はパターンのデフォルトへ戻す
|
|
1830
2103
|
*/
|
|
1831
2104
|
const setPlayingShortcut = () => {
|
|
1832
2105
|
const keyCtrlPtn = `${g_keyObj.currentKey}_${g_keyObj.currentPtn}`;
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
g_headerObj
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
g_headerObj.keyPause = setIntVal(getKeyCtrlVal(g_keyObj[`keyPause${keyCtrlPtn}`]), g_headerObj.keyPauseDef);
|
|
1841
|
-
}
|
|
2106
|
+
const saved = g_keyObj.currentPtn === -1 ? g_keyObj[`shortcut${g_keyObj.currentKey}_-1`] : undefined;
|
|
2107
|
+
const usedKeys = (g_keyObj[`keyCtrl${keyCtrlPtn}`] ?? []).flat();
|
|
2108
|
+
g_keycons.shortcutTypes.forEach(type => {
|
|
2109
|
+
const savedKey = saved?.[type];
|
|
2110
|
+
g_headerObj[`key${type}`] = (savedKey !== undefined && !usedKeys.includes(savedKey))
|
|
2111
|
+
? savedKey : getDefaultShortcut(type);
|
|
2112
|
+
});
|
|
1842
2113
|
};
|
|
1843
2114
|
|
|
1844
2115
|
/**
|
package/js/lib/settings.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Source by tickle
|
|
7
7
|
* Created : 2026/09/13
|
|
8
|
-
* Revised : 2026/
|
|
8
|
+
* Revised : 2026/10/12 (v51.4.0)
|
|
9
9
|
*
|
|
10
10
|
* https://github.com/cwtickle/danoniplus
|
|
11
11
|
*/
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
/* Scene : SETTINGS [lime] */
|
|
15
15
|
/*-----------------------------------------------------------*/
|
|
16
16
|
|
|
17
|
-
const commonSettingBtn =
|
|
17
|
+
const commonSettingBtn = () => {
|
|
18
18
|
|
|
19
19
|
const switchSave = evt => {
|
|
20
20
|
const from = boolToSwitch(g_stateObj.dataSaveFlg);
|
|
@@ -24,6 +24,8 @@ const commonSettingBtn = _labelName => {
|
|
|
24
24
|
const to = boolToSwitch(g_stateObj.dataSaveFlg);
|
|
25
25
|
evt.target.classList.replace(g_cssObj[`button_${from}`], g_cssObj[`button_${to}`]);
|
|
26
26
|
};
|
|
27
|
+
const nextPageNum = nextPos(g_settings.settingWindowNum, 1, g_settings.settingWindows.length);
|
|
28
|
+
const labelName = g_settingWindowTitleKeys.get(g_settings.settingWindows[nextPageNum]);
|
|
27
29
|
|
|
28
30
|
multiAppend(divRoot,
|
|
29
31
|
|
|
@@ -42,18 +44,19 @@ const commonSettingBtn = _labelName => {
|
|
|
42
44
|
// プレイ開始
|
|
43
45
|
makePlayButton(() => loadMusic()),
|
|
44
46
|
|
|
45
|
-
//
|
|
46
|
-
createCss2Button(`
|
|
47
|
+
// 次の設定へ移動
|
|
48
|
+
createCss2Button(`btnNextSetting`, `>`, () => true, {
|
|
47
49
|
...g_lblPosObj.btnSwitchSetting,
|
|
48
|
-
title: g_msgObj[`to${
|
|
50
|
+
title: g_msgObj[`to${labelName}`], resetFunc: () => g_moveSettingWindow(),
|
|
49
51
|
cxtFunc: () => g_moveSettingWindow(true, -1),
|
|
52
|
+
display: g_settings.settingWindows.length > 1 ? C_DIS_INHERIT : C_DIS_NONE,
|
|
50
53
|
}, g_cssObj.button_Mini),
|
|
51
54
|
|
|
52
55
|
// データセーブフラグの切替
|
|
53
56
|
createCss2Button(`btnSave`, g_lblNameObj.dataSave, evt => switchSave(evt), {
|
|
54
57
|
...g_lblPosObj.btnSave,
|
|
55
58
|
cxtFunc: evt => switchSave(evt),
|
|
56
|
-
|
|
59
|
+
display: g_langStorage.safeMode === C_FLG_OFF ? C_DIS_INHERIT : C_DIS_NONE,
|
|
57
60
|
}, g_cssObj.button_Default, (g_stateObj.dataSaveFlg ? g_cssObj.button_ON : g_cssObj.button_OFF)),
|
|
58
61
|
|
|
59
62
|
// データ管理画面へ移動
|
|
@@ -170,7 +173,7 @@ const optionInit = () => {
|
|
|
170
173
|
safeExecuteCustomHooks(`g_customJsObj.option`, g_customJsObj.option);
|
|
171
174
|
|
|
172
175
|
// ボタン描画
|
|
173
|
-
commonSettingBtn(
|
|
176
|
+
commonSettingBtn();
|
|
174
177
|
|
|
175
178
|
// キー操作イベント(デフォルト)
|
|
176
179
|
setShortcutEvent(g_currentPage, () => true, { dfEvtFlg: true });
|
|
@@ -1274,52 +1277,6 @@ const getKeyStorageObjByName = (_keyName) => {
|
|
|
1274
1277
|
}), ``];
|
|
1275
1278
|
};
|
|
1276
1279
|
|
|
1277
|
-
/**
|
|
1278
|
-
* 別キーモード時、移行先キーが保持するSelf保存パターンの取得可否チェック
|
|
1279
|
-
* @param {string} _keyCtrlPtn 例: "7_2"
|
|
1280
|
-
* @returns {number[][]|undefined} 適用可能な場合はSelf保存済みkeyCtrl配列、不可ならundefined
|
|
1281
|
-
*/
|
|
1282
|
-
const getTransKeySelfCtrl = (_keyCtrlPtn) => {
|
|
1283
|
-
const transKeyName = g_keyObj[`transKey${_keyCtrlPtn}`];
|
|
1284
|
-
const transKeyPtn = g_keyObj[`transKeyPtn${_keyCtrlPtn}`];
|
|
1285
|
-
if (!hasVal(transKeyName) || transKeyPtn === undefined) {
|
|
1286
|
-
return undefined;
|
|
1287
|
-
}
|
|
1288
|
-
const [storageObj, addKey] = getKeyStorageObjByName(transKeyName);
|
|
1289
|
-
const savedCtrl = storageObj[`keyCtrl${addKey}`];
|
|
1290
|
-
const savedPtn = storageObj[`keyCtrlPtn${addKey}`];
|
|
1291
|
-
|
|
1292
|
-
if (savedPtn !== transKeyPtn) {
|
|
1293
|
-
return undefined;
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
// 現在のキー配置(基準形状)とレーン数・各レーン長が完全一致することを確認
|
|
1297
|
-
const baseCtrl = g_keyObj[`keyCtrl${_keyCtrlPtn}`];
|
|
1298
|
-
const isValidShape = hasArrayList(savedCtrl, baseCtrl.length) &&
|
|
1299
|
-
savedCtrl.length === baseCtrl.length &&
|
|
1300
|
-
baseCtrl.every((lane, j) => hasArrayList(savedCtrl[j], lane.length) && savedCtrl[j].length === lane.length);
|
|
1301
|
-
|
|
1302
|
-
return isValidShape ? savedCtrl : undefined;
|
|
1303
|
-
};
|
|
1304
|
-
|
|
1305
|
-
/**
|
|
1306
|
-
* 別キーモードの移行先Selfパターンを現在のキー配置へ反映(保存はしない)
|
|
1307
|
-
*/
|
|
1308
|
-
const applyTransKeySelfPattern = () => {
|
|
1309
|
-
const keyCtrlPtn = `${g_keyObj.currentKey}_${g_keyObj.currentPtn}`;
|
|
1310
|
-
const savedCtrl = getTransKeySelfCtrl(keyCtrlPtn);
|
|
1311
|
-
if (savedCtrl === undefined) {
|
|
1312
|
-
return;
|
|
1313
|
-
}
|
|
1314
|
-
const baseKeyNum = g_keyObj[`${g_keyObj.defaultProp}${keyCtrlPtn}`].length;
|
|
1315
|
-
for (let j = 0; j < baseKeyNum; j++) {
|
|
1316
|
-
for (let k = 0; k < (savedCtrl[j]?.length ?? 0); k++) {
|
|
1317
|
-
g_keyObj[`keyCtrl${keyCtrlPtn}`][j][k] = setIntVal(savedCtrl[j][k], 0);
|
|
1318
|
-
}
|
|
1319
|
-
}
|
|
1320
|
-
keyConfigInit();
|
|
1321
|
-
};
|
|
1322
|
-
|
|
1323
1280
|
/**
|
|
1324
1281
|
* 譜面初期化処理
|
|
1325
1282
|
* - 譜面の基本設定(キー数、初期速度、リバース、ゲージ設定)をここで行う
|
|
@@ -1371,6 +1328,7 @@ const setDifficulty = (_chartChangeFlg) => {
|
|
|
1371
1328
|
storageObj[`keyCtrlPtn${addKey}`] = 0;
|
|
1372
1329
|
}
|
|
1373
1330
|
getKeyCtrl(storageObj, addKey);
|
|
1331
|
+
g_keyObj[`shortcut${g_keyObj.currentKey}_-1`] = structuredClone(storageObj[`shortcut${addKey}`] ?? {});
|
|
1374
1332
|
|
|
1375
1333
|
// カラーセット初期値設定
|
|
1376
1334
|
if (storageObj[`setColor${addKey}`] === undefined) {
|
|
@@ -1401,10 +1359,9 @@ const setDifficulty = (_chartChangeFlg) => {
|
|
|
1401
1359
|
g_keyObj[`${type}${keyCtrlPtn}`] = structuredClone(g_keyObj[`${type}${keyCtrlPtn}_0`]);
|
|
1402
1360
|
}
|
|
1403
1361
|
});
|
|
1404
|
-
|
|
1362
|
+
// 曲中ショートカットキーの切り替え
|
|
1363
|
+
setPlayingShortcut();
|
|
1405
1364
|
}
|
|
1406
|
-
// 曲中ショートカットキーの切り替え
|
|
1407
|
-
setPlayingShortcut();
|
|
1408
1365
|
}
|
|
1409
1366
|
|
|
1410
1367
|
// スクロール設定用の配列を入れ替え
|
|
@@ -2449,7 +2406,7 @@ const settingsDisplayInit = () => {
|
|
|
2449
2406
|
safeExecuteCustomHooks(`g_customJsObj.settingsDisplay`, g_customJsObj.settingsDisplay);
|
|
2450
2407
|
|
|
2451
2408
|
// ボタン描画
|
|
2452
|
-
commonSettingBtn(
|
|
2409
|
+
commonSettingBtn();
|
|
2453
2410
|
|
|
2454
2411
|
// キー操作イベント(デフォルト)
|
|
2455
2412
|
setShortcutEvent(g_currentPage);
|
|
@@ -3288,7 +3245,7 @@ const exSettingInit = () => {
|
|
|
3288
3245
|
safeExecuteCustomHooks(`g_customJsObj.exSetting`, g_customJsObj.exSetting);
|
|
3289
3246
|
|
|
3290
3247
|
// 設定系のボタン群をまとめて作成(Data Save, Display切替, Back, KeyConfig, Playボタン)
|
|
3291
|
-
commonSettingBtn(
|
|
3248
|
+
commonSettingBtn();
|
|
3292
3249
|
|
|
3293
3250
|
// キー操作イベント(デフォルト)
|
|
3294
3251
|
setShortcutEvent(g_currentPage, () => true, { dfEvtFlg: true });
|