Skip to content

Commit 8bc3e7f

Browse files
authored
Merge pull request #435 from wcko87/analog_scratch_mode_2
Analog Scratch Revision
2 parents c330340 + 673fa6e commit 8bc3e7f

File tree

7 files changed

+249
-86
lines changed

7 files changed

+249
-86
lines changed

src/bms/player/beatoraja/PlayModeConfig.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ public void setDuration(int inputduration) {
254254
*/
255255
public static class ControllerConfig {
256256

257+
public static final int ANALOG_SCRATCH_VER_2 = 0;
258+
259+
public static final int ANALOG_SCRATCH_VER_1 = 1;
260+
257261
private String name = "";
258262

259263
private int[] keys;
@@ -271,6 +275,10 @@ public static class ControllerConfig {
271275
* アナログスクラッチを利用するか(INFINITASコントローラの場合true)
272276
*/
273277
private boolean analogScratch = false;
278+
/**
279+
* アナログスクラッチモード
280+
*/
281+
private int analogScratchMode = 0;
274282
/**
275283
* アナログスクラッチ停止閾値
276284
*/
@@ -416,6 +424,14 @@ public void setAnalogScratch(boolean analogScratch) {
416424
this.analogScratch = analogScratch;
417425
}
418426

427+
public int getAnalogScratchMode() {
428+
return analogScratchMode;
429+
}
430+
431+
public void setAnalogScratchMode(int analogScratchMode) {
432+
this.analogScratchMode = analogScratchMode;
433+
}
434+
419435
public int getAnalogScratchThreshold() {
420436
return this.analogScratchThreshold;
421437
}

src/bms/player/beatoraja/input/BMControllerInputProcessor.java

Lines changed: 207 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -64,29 +64,9 @@ public class BMControllerInputProcessor extends BMSPlayerInputDevice {
6464
*/
6565
private boolean jkoc;
6666
/**
67-
* アナログ皿かどうか
67+
* アナログ皿のアルゴリズム (null=アナログ皿を通用しない)
6868
*/
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;
9070

9171
public BMControllerInputProcessor(BMSPlayerInputProcessor bmsPlayerInputProcessor, String name, Controller controller,
9272
ControllerConfig controllerConfig) {
@@ -102,8 +82,18 @@ public void setConfig(ControllerConfig controllerConfig) {
10282
this.select = controllerConfig.getSelect();
10383
this.duration = controllerConfig.getDuration();
10484
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+
}
10797
}
10898

10999
public String getName() {
@@ -169,69 +159,26 @@ public void poll(final long presstime) {
169159
}
170160

171161
private boolean scratchInput(int button) {
172-
if(!analogScratch) {
162+
if (analogScratchAlgorithm == null) {
163+
// アナログ皿を使わない
173164
if(button == BMKeys.UP) {
174165
return (axis[1] < -0.9) || (axis[2] < -0.9);
175166
} else if(button == BMKeys.DOWN){
176167
return (axis[1] > 0.9) || (axis[2] > 0.9);
168+
} else {
169+
return false;
177170
}
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;
201179
}
202180
}
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);
235182
}
236183
}
237184

@@ -283,4 +230,184 @@ public static final String toString(int keycode) {
283230
}
284231
}
285232

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+
}
286413
}

0 commit comments

Comments
 (0)