@@ -64,29 +64,9 @@ public class BMControllerInputProcessor extends BMSPlayerInputDevice {
64
64
*/
65
65
private boolean jkoc ;
66
66
/**
67
- * アナログ皿かどうか
67
+ * アナログ皿のアルゴリズム (null=アナログ皿を通用しない)
68
68
*/
69
- private boolean analogScratch ;
70
- /**
71
- * アナログ皿の閾値
72
- */
73
- private int analogScratchThreshold ;
74
- /**
75
- * スクラッチ停止カウンタ
76
- */
77
- private long counter = 1 ;
78
- /**
79
- * アナログスクラッチ位置(-1<->0<->1)
80
- */
81
- private float oldAnalogScratchX = 10 ;
82
- /**
83
- * アナログスクラッチ 入力フラグ
84
- */
85
- private boolean activeAnalogScratch = false ;
86
- /**
87
- * アナログスクラッチ 右回転フラグ
88
- */
89
- private boolean rightMoveScratching = false ;
69
+ AnalogScratchAlgorithm analogScratchAlgorithm = null ;
90
70
91
71
public BMControllerInputProcessor (BMSPlayerInputProcessor bmsPlayerInputProcessor , String name , Controller controller ,
92
72
ControllerConfig controllerConfig ) {
@@ -102,8 +82,18 @@ public void setConfig(ControllerConfig controllerConfig) {
102
82
this .select = controllerConfig .getSelect ();
103
83
this .duration = controllerConfig .getDuration ();
104
84
this .jkoc = controllerConfig .getJKOC ();
105
- this .analogScratch = controllerConfig .isAnalogScratch ();
106
- this .analogScratchThreshold = controllerConfig .getAnalogScratchThreshold ();
85
+ analogScratchAlgorithm = null ;
86
+ if (controllerConfig .isAnalogScratch ()) {
87
+ int analogScratchThreshold = controllerConfig .getAnalogScratchThreshold ();
88
+ switch (controllerConfig .getAnalogScratchMode ()) {
89
+ case ControllerConfig .ANALOG_SCRATCH_VER_1 :
90
+ analogScratchAlgorithm = new AnalogScratchAlgorithmVersion1 (analogScratchThreshold );
91
+ break ;
92
+ case ControllerConfig .ANALOG_SCRATCH_VER_2 :
93
+ analogScratchAlgorithm = new AnalogScratchAlgorithmVersion2 (analogScratchThreshold );
94
+ break ;
95
+ }
96
+ }
107
97
}
108
98
109
99
public String getName () {
@@ -169,69 +159,26 @@ public void poll(final long presstime) {
169
159
}
170
160
171
161
private boolean scratchInput (int button ) {
172
- if (!analogScratch ) {
162
+ if (analogScratchAlgorithm == null ) {
163
+ // アナログ皿を使わない
173
164
if (button == BMKeys .UP ) {
174
165
return (axis [1 ] < -0.9 ) || (axis [2 ] < -0.9 );
175
166
} else if (button == BMKeys .DOWN ){
176
167
return (axis [1 ] > 0.9 ) || (axis [2 ] > 0.9 );
168
+ } else {
169
+ return false ;
177
170
}
178
- }
179
-
180
- // Linux : axis[0]
181
- // Windows : axis[1]
182
- float analogScratchX = File .separatorChar == '\\' ? axis [1 ] : axis [0 ];
183
- if (oldAnalogScratchX > 1 ) {
184
- oldAnalogScratchX = analogScratchX ;
185
- activeAnalogScratch = false ;
186
- return false ;
187
- }
188
-
189
- if (oldAnalogScratchX != analogScratchX ) {
190
- // アナログスクラッチ位置の移動が発生した場合
191
- boolean nowRight = false ;
192
- if (oldAnalogScratchX < analogScratchX ) {
193
- nowRight = true ;
194
- if ((analogScratchX - oldAnalogScratchX ) > (1 - analogScratchX + oldAnalogScratchX )) {
195
- nowRight = false ;
196
- }
197
- } else if (oldAnalogScratchX > analogScratchX ) {
198
- nowRight = false ;
199
- if ((oldAnalogScratchX - analogScratchX ) > ((analogScratchX + 1 ) - oldAnalogScratchX )) {
200
- nowRight = true ;
171
+ } else {
172
+ // アナログ皿
173
+ // Pick correct axis (axis[i] != 0)
174
+ float analogScratchX = 0f ;
175
+ for (int i = 0 ; i < 4 ; i ++) {
176
+ if (axis [i ] != 0f ) {
177
+ analogScratchX = axis [i ];
178
+ break ;
201
179
}
202
180
}
203
-
204
- if (activeAnalogScratch && !(rightMoveScratching == nowRight )) {
205
- // 左回転→右回転の場合(右回転→左回転は値の変更がない)
206
- rightMoveScratching = nowRight ;
207
- } else if (!activeAnalogScratch ) {
208
- // 移動無し→回転の場合
209
- activeAnalogScratch = true ;
210
- rightMoveScratching = nowRight ;
211
- }
212
-
213
- counter = 0 ;
214
- oldAnalogScratchX = analogScratchX ;
215
- }
216
-
217
- // counter > Threshold ... Stop Scratching.
218
- if (counter > this .analogScratchThreshold && activeAnalogScratch ) {
219
- activeAnalogScratch = false ;
220
- counter = 0 ;
221
- }
222
-
223
- if (counter == Long .MAX_VALUE ) {
224
- counter = 0 ;
225
- }
226
-
227
- counter ++;
228
-
229
- if (button == BMKeys .UP ) {
230
- return activeAnalogScratch && rightMoveScratching ;
231
- } else if (button == BMKeys .DOWN ){
232
- return activeAnalogScratch && !rightMoveScratching ;
233
- } else {
234
- return false ;
181
+ return analogScratchAlgorithm .analogScratchInput (button , analogScratchX );
235
182
}
236
183
}
237
184
@@ -283,4 +230,184 @@ public static final String toString(int keycode) {
283
230
}
284
231
}
285
232
233
+
234
+ private static interface AnalogScratchAlgorithm {
235
+ public boolean analogScratchInput (int button , float currentScratchX );
236
+ }
237
+
238
+ private static class AnalogScratchAlgorithmVersion1 implements AnalogScratchAlgorithm {
239
+ /**
240
+ * アナログ皿の閾値
241
+ */
242
+ private int analogScratchThreshold ;
243
+ /**
244
+ * スクラッチ停止カウンタ
245
+ */
246
+ private long counter = 1 ;
247
+ /**
248
+ * アナログスクラッチ位置(-1<->0<->1)
249
+ */
250
+ private float oldScratchX = 10 ;
251
+ /**
252
+ * アナログスクラッチ 入力フラグ
253
+ */
254
+ private boolean scratchActive = false ;
255
+ /**
256
+ * アナログスクラッチ 右回転フラグ
257
+ */
258
+ private boolean rightMoveScratching = false ;
259
+
260
+ public AnalogScratchAlgorithmVersion1 (int analogScratchThreshold ) {
261
+ this .analogScratchThreshold = analogScratchThreshold ;
262
+ }
263
+
264
+ public boolean analogScratchInput (int button , float currentScratchX ) {
265
+ if (oldScratchX > 1 ) {
266
+ oldScratchX = currentScratchX ;
267
+ scratchActive = false ;
268
+ return false ;
269
+ }
270
+
271
+ if (oldScratchX != currentScratchX ) {
272
+ // アナログスクラッチ位置の移動が発生した場合
273
+ boolean nowRight = false ;
274
+ if (oldScratchX < currentScratchX ) {
275
+ nowRight = true ;
276
+ if ((currentScratchX - oldScratchX ) > (1 - currentScratchX + oldScratchX )) {
277
+ nowRight = false ;
278
+ }
279
+ } else if (oldScratchX > currentScratchX ) {
280
+ nowRight = false ;
281
+ if ((oldScratchX - currentScratchX ) > ((currentScratchX + 1 ) - oldScratchX )) {
282
+ nowRight = true ;
283
+ }
284
+ }
285
+
286
+ if (scratchActive && !(rightMoveScratching == nowRight )) {
287
+ // 左回転→右回転の場合(右回転→左回転は値の変更がない)
288
+ rightMoveScratching = nowRight ;
289
+ } else if (!scratchActive ) {
290
+ // 移動無し→回転の場合
291
+ scratchActive = true ;
292
+ rightMoveScratching = nowRight ;
293
+ }
294
+
295
+ counter = 0 ;
296
+ oldScratchX = currentScratchX ;
297
+ }
298
+
299
+ // counter > Threshold ... Stop Scratching.
300
+ if (counter > this .analogScratchThreshold && scratchActive ) {
301
+ scratchActive = false ;
302
+ counter = 0 ;
303
+ }
304
+
305
+ if (counter == Long .MAX_VALUE ) {
306
+ counter = 0 ;
307
+ }
308
+
309
+ counter ++;
310
+
311
+ if (button == BMKeys .UP ) {
312
+ return scratchActive && rightMoveScratching ;
313
+ } else if (button == BMKeys .DOWN ){
314
+ return scratchActive && !rightMoveScratching ;
315
+ } else {
316
+ return false ;
317
+ }
318
+ }
319
+ }
320
+
321
+ private static class AnalogScratchAlgorithmVersion2 implements AnalogScratchAlgorithm {
322
+ /**
323
+ * アナログ皿の閾値
324
+ */
325
+ private int analogScratchThreshold ;
326
+ /**
327
+ * スクラッチ停止カウンタ
328
+ */
329
+ private long counter = 1 ;
330
+ /**
331
+ * (モード2)閾値以内の皿の移動数(2回->スクラッチ)
332
+ */
333
+ private int analogScratchTickCounter = 0 ;
334
+ /**
335
+ * アナログスクラッチ位置(-1<->0<->1)
336
+ */
337
+ private float oldScratchX = 10 ;
338
+ /**
339
+ * アナログスクラッチ 入力フラグ
340
+ */
341
+ private boolean scratchActive = false ;
342
+ /**
343
+ * アナログスクラッチ 右回転フラグ
344
+ */
345
+ private boolean rightMoveScratching = false ;
346
+
347
+ public AnalogScratchAlgorithmVersion2 (int analogScratchThreshold ) {
348
+ this .analogScratchThreshold = analogScratchThreshold ;
349
+ }
350
+
351
+ public boolean analogScratchInput (int button , float currentScratchX ) {
352
+ if (oldScratchX > 1 ) {
353
+ oldScratchX = currentScratchX ;
354
+ scratchActive = false ;
355
+ return false ;
356
+ }
357
+
358
+ if (oldScratchX != currentScratchX ) {
359
+ // アナログスクラッチ位置の移動が発生した場合
360
+
361
+ // tick: 皿の最小の動き
362
+ // INFINITAS, DAO, YuanCon -> 0.00787
363
+ // arcin board -> 0.00784
364
+ final float TICK_MAX_SIZE = 0.009f ;
365
+ float scratchDifferenceX = currentScratchX - oldScratchX ;
366
+ if (scratchDifferenceX > 1.0f ) {
367
+ scratchDifferenceX -= (2 + TICK_MAX_SIZE /2 );
368
+ } else if (scratchDifferenceX < -1.0f ) {
369
+ scratchDifferenceX += (2 + TICK_MAX_SIZE /2 );
370
+ }
371
+ boolean nowRight = (scratchDifferenceX > 0 );
372
+ int ticks = (int )Math .ceil (Math .abs (scratchDifferenceX )/TICK_MAX_SIZE );
373
+
374
+ if (scratchActive && !(rightMoveScratching == nowRight )) {
375
+ // 左回転→右回転の場合(右回転→左回転は値の変更がない)
376
+ rightMoveScratching = nowRight ;
377
+ scratchActive = false ;
378
+ analogScratchTickCounter = 0 ;
379
+ } else if (!scratchActive ) {
380
+ // 移動無し→回転の場合
381
+ if (analogScratchTickCounter == 0 || counter <= this .analogScratchThreshold ) {
382
+ analogScratchTickCounter += ticks ;
383
+ }
384
+ // scratchActive=true
385
+ if (analogScratchTickCounter >= 2 ) {
386
+ scratchActive = true ;
387
+ rightMoveScratching = nowRight ;
388
+ }
389
+ }
390
+
391
+ counter = 0 ;
392
+ oldScratchX = currentScratchX ;
393
+ }
394
+
395
+ // counter > 2*Threshold ... Stop Scratching.
396
+ if (counter > this .analogScratchThreshold *2 ) {
397
+ scratchActive = false ;
398
+ analogScratchTickCounter = 0 ;
399
+ counter = 0 ;
400
+ }
401
+
402
+ counter ++;
403
+
404
+ if (button == BMKeys .UP ) {
405
+ return scratchActive && rightMoveScratching ;
406
+ } else if (button == BMKeys .DOWN ){
407
+ return scratchActive && !rightMoveScratching ;
408
+ } else {
409
+ return false ;
410
+ }
411
+ }
412
+ }
286
413
}
0 commit comments