Normal2ButtonPad.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26: package xeij;
27:
28: import java.awt.*;
29: import java.awt.event.*;
30: import java.util.*;
31: import javax.swing.*;
32: import javax.swing.event.*;
33:
34:
35:
36: public class Normal2ButtonPad extends Joystick implements ActionListener, ChangeListener, FocusListener, XInput.GamepadListener, KeyListener {
37:
38: protected static final int UP_BIT = 0;
39: protected static final int DOWN_BIT = 1;
40: protected static final int LEFT_BIT = 2;
41: protected static final int RIGHT_BIT = 3;
42: protected static final int A_BIT = 4;
43: protected static final int B_BIT = 5;
44: protected static final int SELECT_BIT = 6;
45: protected static final int RUN_START_BIT = 7;
46: protected static final int BUTTONS = 8;
47:
48: protected static final int UP_MASK = (1 << UP_BIT);
49: protected static final int DOWN_MASK = (1 << DOWN_BIT);
50: protected static final int LEFT_MASK = (1 << LEFT_BIT);
51: protected static final int RIGHT_MASK = (1 << RIGHT_BIT);
52: protected static final int A_MASK = (1 << A_BIT);
53: protected static final int B_MASK = (1 << B_BIT);
54: protected static final int SELECT_MASK = (1 << SELECT_BIT);
55: protected static final int RUN_START_MASK = (1 << RUN_START_BIT);
56:
57: protected static final String[] BIT_TO_TEXT = {
58: "↑",
59: "↓",
60: "←",
61: "→",
62: "A",
63: "B",
64: "SELECT",
65: "RUN/START",
66: };
67:
68: protected static final boolean[] BIT_TO_REPEATABLE = {
69: false,
70: false,
71: false,
72: false,
73: true,
74: true,
75: false,
76: false,
77: };
78:
79: protected static final int MAP_CODE = BUTTONS * 0;
80: protected static final int MAP_REPEAT = BUTTONS * 1;
81: protected static final int MAP_DELAY = BUTTONS * 2;
82: protected static final int MAP_INTERVAL = BUTTONS * 3;
83: protected static final int MAP_LENGTH = BUTTONS * 4;
84: protected int[] map;
85:
86: protected int xinputFocusedButton;
87: protected long[] startTimeOf;
88: protected int lastButtons;
89: protected int keyButtons;
90:
91: protected JTextField[] xinputTextFieldOf = new JTextField[BUTTONS];
92: protected JTextField[] keyTextFieldOf = new JTextField[BUTTONS];
93: protected JCheckBox[] repeatCheckBoxOf = new JCheckBox[BUTTONS];
94: protected SpinnerNumberModel[] delayModelOf = new SpinnerNumberModel[BUTTONS];
95: protected JSpinner[] delaySpinnerOf = new JSpinner[BUTTONS];
96: protected SpinnerNumberModel[] intervalModelOf = new SpinnerNumberModel[BUTTONS];
97: protected JSpinner[] intervalSpinnerOf = new JSpinner[BUTTONS];
98:
99:
100:
101:
102:
103:
104:
105: protected final int[][] defaultMaps = new int[][] {
106: {
107: (128 | 0 << 5 | XInput.UP_BIT ) << 16 | KeyEvent.VK_UP,
108: (128 | 0 << 5 | XInput.DOWN_BIT ) << 16 | KeyEvent.VK_DOWN,
109: (128 | 0 << 5 | XInput.LEFT_BIT ) << 16 | KeyEvent.VK_LEFT,
110: (128 | 0 << 5 | XInput.RIGHT_BIT ) << 16 | KeyEvent.VK_RIGHT,
111: (128 | 0 << 5 | XInput.A_BIT ) << 16 | KeyEvent.VK_Z,
112: (128 | 0 << 5 | XInput.B_BIT ) << 16 | KeyEvent.VK_X,
113: (128 | 0 << 5 | XInput.BACK_BIT ) << 16 | KeyEvent.VK_E,
114: (128 | 0 << 5 | XInput.START_BIT ) << 16 | KeyEvent.VK_R,
115: 0, 0, 0, 0, 0, 0, 0, 0,
116: 0, 0, 0, 0, 50, 50, 0, 0,
117: 0, 0, 0, 0, 100, 100, 0, 0,
118: },
119: {
120: (128 | 1 << 5 | XInput.UP_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
121: (128 | 1 << 5 | XInput.DOWN_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
122: (128 | 1 << 5 | XInput.LEFT_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
123: (128 | 1 << 5 | XInput.RIGHT_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
124: (128 | 1 << 5 | XInput.A_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
125: (128 | 1 << 5 | XInput.B_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
126: (128 | 1 << 5 | XInput.BACK_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
127: (128 | 1 << 5 | XInput.START_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
128: 0, 0, 0, 0, 0, 0, 0, 0,
129: 0, 0, 0, 0, 50, 50, 0, 0,
130: 0, 0, 0, 0, 100, 100, 0, 0,
131: },
132: };
133:
134:
135:
136:
137: public Normal2ButtonPad (int number) {
138: this.number = number;
139: id = "normal2button" + number;
140: nameEn = "Normal 2 button pad #" + number;
141: nameJa = "ノーマル 2 ボタンパッド #" + number;
142: map = new int[MAP_LENGTH];
143: int[] tempMap = Settings.sgsGetIntArray (id);
144: if (0 < tempMap.length && 0 <= tempMap[0]) {
145: for (int i = 0; i < MAP_LENGTH; i++) {
146: map[i] = i < tempMap.length ? tempMap[i] : 0;
147: }
148:
149: for (int i = 0; i < MAP_LENGTH; i += BUTTONS) {
150: int t = map[i + A_BIT];
151: map[i + A_BIT] = map[i + B_BIT];
152: map[i + B_BIT] = t;
153: }
154:
155: for (int i = 0; i < BUTTONS; i++) {
156: map[MAP_INTERVAL + i] = Math.min (INTERVAL_MAX, map[MAP_INTERVAL + i] << 1);
157: }
158: } else if (0 < tempMap.length && tempMap[0] == -2) {
159: for (int i = 0; i < MAP_LENGTH; i++) {
160: map[i] = i + 1 < tempMap.length ? tempMap[i + 1] : 0;
161: }
162: } else {
163: System.arraycopy (defaultMaps[number - 1], 0,
164: map, 0,
165: MAP_LENGTH);
166: }
167: if (PPI.PPI_XINPUT_ON) {
168: xinputFocusedButton = -1;
169: }
170: startTimeOf = new long[BUTTONS];
171: reset ();
172: configurationPanel = null;
173: }
174:
175:
176:
177: @Override public void tini () {
178: if (true &&
179: Arrays.equals (map, defaultMaps[number - 1])) {
180: Settings.sgsPutIntArray (id, new int[0]);
181: } else {
182: int[] tempMap = new int[1 + MAP_LENGTH];
183: tempMap[0] = -2;
184: for (int i = 0; i < MAP_LENGTH; i++) {
185: tempMap[1 + i] = map[i];
186: }
187: Settings.sgsPutIntArray (id, tempMap);
188: }
189: }
190:
191:
192:
193: @Override public final void reset () {
194: lastButtons = 0;
195: keyButtons = 0;
196: }
197:
198: private void updateText () {
199: for (int i = 0; i < BUTTONS; i++) {
200: String text;
201: int xCode = map[MAP_CODE + i] >>> 16;
202: if (xCode == 0) {
203: text = Multilingual.mlnJapanese ? "なし" : "none";
204: } else {
205: int xIndex = (xCode >> 5) & 3;
206: int xBit = xCode & 31;
207: text = "#" + xIndex + " " + XInput.BIT_TO_TEXT[xBit];
208: }
209: xinputTextFieldOf[i].setText (text);
210: int keyCode = map[MAP_CODE + i] & 65535;
211: if (keyCode == 0) {
212: text = Multilingual.mlnJapanese ? "なし" : "none";
213: } else {
214: text = KeyEvent.getKeyText (keyCode);
215: }
216: keyTextFieldOf[i].setText (text);
217: }
218: }
219:
220:
221:
222: @Override public void actionPerformed (ActionEvent ae) {
223: Object source = ae.getSource ();
224: String command = ae.getActionCommand ();
225: if (command.equals ("Reset to default values")) {
226: if (Arrays.equals (map, defaultMaps[number - 1])) {
227: JOptionPane.showMessageDialog (
228: null,
229: Multilingual.mlnJapanese ? nameJa + " の設定は初期値と同じです" : nameEn + " settings are equals to default values",
230: Multilingual.mlnJapanese ? "確認" : "Confirmation",
231: JOptionPane.PLAIN_MESSAGE);
232: return;
233: }
234: if (JOptionPane.showConfirmDialog (
235: null,
236: Multilingual.mlnJapanese ? nameJa + " の設定を初期値に戻しますか?" : "Do you want to reset " + nameEn + " settings to default values?",
237: Multilingual.mlnJapanese ? "確認" : "Confirmation",
238: JOptionPane.YES_NO_OPTION,
239: JOptionPane.PLAIN_MESSAGE) != JOptionPane.YES_OPTION) {
240: return;
241: }
242: System.arraycopy (defaultMaps[number - 1], 0,
243: map, 0,
244: MAP_LENGTH);
245: updateText ();
246: for (int i = 0; i < BUTTONS; i++) {
247: if (BIT_TO_REPEATABLE[i]) {
248: repeatCheckBoxOf[i].setSelected (map[MAP_REPEAT + i] != 0);
249: delayModelOf[i].setValue (Math.max (DELAY_MIN, Math.min (DELAY_MAX, map[MAP_DELAY + i])));
250: intervalModelOf[i].setValue (Math.max (INTERVAL_MIN, Math.min (INTERVAL_MAX, map[MAP_INTERVAL + i])));
251: }
252: }
253: } else if (command.startsWith ("Repeat ")) {
254: int i = Integer.parseInt (command.substring (7));
255: map[MAP_REPEAT + i] = repeatCheckBoxOf[i].isSelected () ? 1 : 0;
256: } else {
257: System.out.println ("unknown action command " + command);
258: }
259: }
260:
261:
262:
263: @Override public void stateChanged (ChangeEvent ce) {
264: JSpinner spinner = (JSpinner) ce.getSource ();
265: String name = spinner.getName ();
266: if (name.startsWith ("Delay ")) {
267: int i = Integer.parseInt (name.substring (6));
268: map[MAP_DELAY + i] = delayModelOf[i].getNumber ().intValue ();
269: } else if (name.startsWith ("Interval ")) {
270: int i = Integer.parseInt (name.substring (9));
271: map[MAP_INTERVAL + i] = intervalModelOf[i].getNumber ().intValue ();
272: } else {
273: System.out.println ("unknown spinner name " + name);
274: }
275: }
276:
277:
278:
279: @Override public void focusGained (FocusEvent fe) {
280: Component component = fe.getComponent ();
281: String componentName = component.getName ();
282: int type = componentName.charAt (0);
283: int i = Integer.parseInt (componentName.substring (1));
284:
285: component.setBackground (new Color (LnF.lnfRGB[6]));
286: if (PPI.PPI_XINPUT_ON && type == 'x') {
287:
288: xinputFocusedButton = i;
289: if (PPI.ppiXInput != null) {
290: PPI.ppiXInput.addGamepadListener (this);
291: }
292: } else if (type == 'k') {
293: } else {
294: System.out.println ("unknown component name " + componentName);
295: }
296: }
297: @Override public void focusLost (FocusEvent fe) {
298: Component component = fe.getComponent ();
299: String componentName = component.getName ();
300: int type = componentName.charAt (0);
301: int i = Integer.parseInt (componentName.substring (1));
302:
303: component.setBackground (null);
304: if (PPI.PPI_XINPUT_ON && type == 'x') {
305:
306: if (PPI.ppiXInput != null) {
307: PPI.ppiXInput.removeGamepadListeners ();
308: }
309: xinputFocusedButton = -1;
310: } else if (type == 'k') {
311: } else {
312: System.out.println ("unknown component name " + componentName);
313: }
314: }
315:
316:
317:
318: @Override public void connected (XInput.Gamepad gamepad) {
319: }
320: @Override public void disconnected (XInput.Gamepad gamepad) {
321: }
322: @Override public void buttonPressed (XInput.Gamepad gamepad, int buttonMasks) {
323: if (buttonMasks == 0) {
324: return;
325: }
326: if (PPI.PPI_XINPUT_ON && 0 <= xinputFocusedButton) {
327: int xIndex = gamepad.getIndex ();
328: int xBit = Integer.numberOfTrailingZeros (buttonMasks);
329: int xCode = 128 | xIndex << 5 | xBit;
330: int keyCode = map[MAP_CODE + xinputFocusedButton] & 65535;
331: map[MAP_CODE + xinputFocusedButton] = xCode << 16 | keyCode;
332:
333:
334: for (int i = 0; i < BUTTONS; i++) {
335: int xCode2 = map[MAP_CODE + i] >>> 16;
336: if (xCode2 != 0) {
337: int keyCode2 = map[MAP_CODE + i] & 65535;
338: map[MAP_CODE + i] = ((xCode2 & ~(3 << 5)) | xIndex << 5) << 16 | keyCode2;
339: }
340: }
341: updateText ();
342: }
343: }
344: @Override public void buttonReleased (XInput.Gamepad gamepad, int buttonMasks) {
345: }
346: @Override public void leftStickMovedX (XInput.Gamepad gamepad) {
347: }
348: @Override public void leftStickMovedY (XInput.Gamepad gamepad) {
349: }
350: @Override public void leftTriggerMoved (XInput.Gamepad gamepad) {
351: }
352: @Override public void rightStickMovedX (XInput.Gamepad gamepad) {
353: }
354: @Override public void rightStickMovedY (XInput.Gamepad gamepad) {
355: }
356: @Override public void rightTriggerMoved (XInput.Gamepad gamepad) {
357: }
358:
359:
360:
361: @Override public void keyPressed (KeyEvent ke) {
362: Component component = ke.getComponent ();
363: String componentName = component.getName ();
364: int type = componentName.charAt (0);
365: int i = Integer.parseInt (componentName.substring (1));
366: int xCode = map[MAP_CODE + i] >>> 16;
367: int keyCode = map[MAP_CODE + i] & 65535;
368: if (PPI.PPI_XINPUT_ON && type == 'x') {
369: if (ke.getKeyCode () == KeyEvent.VK_ESCAPE) {
370: xCode = 0;
371: }
372: } else if (type == 'k') {
373: if (ke.getKeyCode () == KeyEvent.VK_ESCAPE) {
374: keyCode = KeyEvent.VK_UNDEFINED;
375: } else {
376: keyCode = ke.getKeyCode ();
377: }
378: } else {
379: System.out.println ("unknown component name " + componentName);
380: }
381: map[MAP_CODE + i] = xCode << 16 | keyCode;
382: updateText ();
383: ke.consume ();
384: }
385: @Override public void keyReleased (KeyEvent ke) {
386: ke.consume ();
387: }
388: @Override public void keyTyped (KeyEvent ke) {
389: ke.consume ();
390: }
391:
392:
393:
394:
395: @Override public JComponent getConfigurationPanel () {
396:
397: if (configurationPanel != null) {
398: return configurationPanel;
399: }
400:
401: for (int i = 0; i < BUTTONS; i++) {
402: xinputTextFieldOf[i] =
403: ComponentFactory.setEnabled (
404: ComponentFactory.addListener (
405: ComponentFactory.addListener (
406: ComponentFactory.setHorizontalAlignment (
407: ComponentFactory.setName (
408: ComponentFactory.createTextField ("", 8),
409: "x" + i),
410: JTextField.CENTER),
411: (KeyListener) this),
412: (FocusListener) this),
413: PPI.PPI_XINPUT_ON && XEiJ.prgWindllLoaded);
414: keyTextFieldOf[i] =
415: ComponentFactory.addListener (
416: ComponentFactory.addListener (
417: ComponentFactory.setHorizontalAlignment (
418: ComponentFactory.setName (
419: ComponentFactory.createTextField ("", 8),
420: "k" + i),
421: JTextField.CENTER),
422: (KeyListener) this),
423: (FocusListener) this);
424: if (BIT_TO_REPEATABLE[i]) {
425: repeatCheckBoxOf[i] =
426: ComponentFactory.setText (
427: ComponentFactory.createCheckBox (map[MAP_REPEAT + i] != 0, "Repeat " + i, (ActionListener) this),
428: "");
429: delayModelOf[i] =
430: new SpinnerNumberModel (Math.max (DELAY_MIN, Math.min (DELAY_MAX, map[MAP_DELAY + i])),
431: DELAY_MIN, DELAY_MAX, DELAY_STEP);
432: delaySpinnerOf[i] =
433: ComponentFactory.setName (
434: ComponentFactory.createNumberSpinner (delayModelOf[i], 4, (ChangeListener) this),
435: "Delay " + i);
436: intervalModelOf[i] =
437: new SpinnerNumberModel (Math.max (INTERVAL_MIN, Math.min (INTERVAL_MAX, map[MAP_INTERVAL + i])),
438: INTERVAL_MIN, INTERVAL_MAX, INTERVAL_STEP);
439: intervalSpinnerOf[i] =
440: ComponentFactory.setName (
441: ComponentFactory.createNumberSpinner (intervalModelOf[i], 4, (ChangeListener) this),
442: "Interval " + i);
443: }
444: }
445: updateText ();
446:
447:
448:
449:
450:
451: ArrayList<Object> cellList = new ArrayList<Object> ();
452:
453: cellList.add (null);
454: cellList.add (Multilingual.mlnText (ComponentFactory.createLabel ("Button"), "ja", "ボタン"));
455: cellList.add (ComponentFactory.createLabel ("XInput"));
456: cellList.add (Multilingual.mlnText (ComponentFactory.createLabel ("Keyboard"), "ja", "キーボード"));
457: cellList.add (Multilingual.mlnText (ComponentFactory.createLabel ("Burst"), "ja", "連射"));
458: cellList.add (Multilingual.mlnText (ComponentFactory.createLabel ("Delay (ms)"), "ja", "開始 (ms)"));
459: cellList.add (Multilingual.mlnText (ComponentFactory.createLabel ("Interval (ms)"), "ja", "間隔 (ms)"));
460:
461: cellList.add (ComponentFactory.createHorizontalSeparator ());
462:
463: for (int i = 0; i < BUTTONS; i++) {
464: cellList.add (String.valueOf (1 + i));
465: cellList.add (BIT_TO_TEXT[i]);
466: cellList.add (xinputTextFieldOf[i]);
467: cellList.add (keyTextFieldOf[i]);
468: cellList.add (BIT_TO_REPEATABLE[i] ? repeatCheckBoxOf[i] : null);
469: cellList.add (BIT_TO_REPEATABLE[i] ? delaySpinnerOf[i] : null);
470: cellList.add (BIT_TO_REPEATABLE[i] ? intervalSpinnerOf[i] : null);
471: }
472:
473: configurationPanel =
474: ComponentFactory.createVerticalBox (
475: Box.createVerticalStrut (5),
476: ComponentFactory.createHorizontalBox (
477: Box.createHorizontalGlue (),
478: Multilingual.mlnText (ComponentFactory.createLabel (getNameEn ()), "ja", getNameJa ()),
479: Box.createHorizontalGlue ()),
480: Box.createVerticalStrut (5),
481: ComponentFactory.createHorizontalBox (
482: ComponentFactory.createGridPanel (
483: 7,
484: 2 + BUTTONS,
485: "paddingLeft=3,paddingRight=3,center",
486: "",
487: "italic;colSpan=7,widen",
488: "",
489: cellList.toArray (new Object[0]))),
490: Box.createVerticalStrut (5),
491: ComponentFactory.createHorizontalBox (
492: Box.createHorizontalGlue (),
493: Multilingual.mlnText (ComponentFactory.createButton ("Reset to default values", (ActionListener) this), "ja", "初期値に戻す"),
494: Box.createHorizontalGlue ()),
495: Box.createVerticalStrut (5));
496:
497: return configurationPanel;
498: }
499:
500:
501:
502:
503:
504:
505: @Override public boolean input (KeyEvent ke, boolean pressed) {
506: int keyCode = ke.getKeyCode ();
507:
508: for (int i = 0; i < BUTTONS; i++) {
509: if (keyCode == (map[MAP_CODE + i] & 65535)) {
510: if (pressed) {
511: keyButtons |= 1 << i;
512: } else {
513: keyButtons &= ~(1 << i);
514: }
515: return true;
516: }
517: }
518: return false;
519: }
520:
521:
522:
523:
524:
525: @Override public int readByte () {
526:
527: int currentButtons = keyButtons;
528: int lastIndex = -1;
529: int lastMasks = 0;
530: for (int i = 0; i < BUTTONS; i++) {
531: int xCode = map[MAP_CODE + i] >>> 16;
532: if (xCode != 0) {
533: int xIndex = (xCode >> 5) & 3;
534: int xBit = xCode & 31;
535: if (lastIndex != xIndex) {
536: lastIndex = xIndex;
537: lastMasks = PPI.ppiXInput == null ? 0 : PPI.ppiXInput.getButtonMasks (lastIndex);
538: }
539: if ((lastMasks & (1 << xBit)) != 0) {
540: currentButtons |= 1 << i;
541: }
542: }
543: }
544: int pressedButtons = ~lastButtons & currentButtons;
545: lastButtons = currentButtons;
546: int outputButtons = 0;
547: for (int i = 0; i < BUTTONS; i++) {
548: if ((pressedButtons & (1 << i)) != 0 &&
549: map[MAP_REPEAT + i] != 0) {
550: startTimeOf[i] = XEiJ.mpuClockTime + map[MAP_DELAY + i] * (XEiJ.TMR_FREQ / 1000);
551: }
552: if ((currentButtons & (1 << i)) != 0 &&
553: (map[MAP_REPEAT + i] == 0 ||
554: XEiJ.mpuClockTime < startTimeOf[i] ||
555: ((int) ((XEiJ.mpuClockTime - startTimeOf[i]) /
556: ((map[MAP_INTERVAL + i] >> 1) * (XEiJ.TMR_FREQ / 1000)))
557: & 1) != 0)) {
558: outputButtons |= 1 << i;
559: }
560: }
561:
562: return (0b11111111 &
563: ((outputButtons & (UP_MASK | DOWN_MASK)) == UP_MASK ? ~0b00000001 : -1) &
564: ((outputButtons & (DOWN_MASK | UP_MASK)) == DOWN_MASK ? ~0b00000010 : -1) &
565: ((outputButtons & SELECT_MASK) != 0 ? ~0b00000011 : -1) &
566: ((outputButtons & (LEFT_MASK | RIGHT_MASK)) == LEFT_MASK ? ~0b00000100 : -1) &
567: ((outputButtons & (RIGHT_MASK | LEFT_MASK)) == RIGHT_MASK ? ~0b00001000 : -1) &
568: ((outputButtons & RUN_START_MASK) != 0 ? ~0b00001100 : -1) &
569: ((outputButtons & A_MASK) != 0 ? ~0b00100000 : -1) &
570: ((outputButtons & B_MASK) != 0 ? ~0b01000000 : -1));
571: }
572:
573: }