CyberStickAnalog.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:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58: package xeij;
59:
60: import java.awt.*;
61: import java.awt.event.*;
62: import java.util.*;
63: import javax.swing.*;
64: import javax.swing.event.*;
65:
66:
67:
68: public class CyberStickAnalog extends Joystick implements ActionListener, ChangeListener, FocusListener, XInput.GamepadListener, KeyListener {
69:
70: protected static final int SUP_BIT = 0;
71: protected static final int SLEFT_BIT = 1;
72: protected static final int TUP_BIT = 2;
73: protected static final int OLEFT_BIT = 3;
74: protected static final int STICKS = 4;
75: protected static final int A_BIT = 4;
76: protected static final int APRIME_BIT = 5;
77: protected static final int B_BIT = 6;
78: protected static final int BPRIME_BIT = 7;
79: protected static final int C_BIT = 8;
80: protected static final int D_BIT = 9;
81: protected static final int E1_BIT = 10;
82: protected static final int E2_BIT = 11;
83: protected static final int SELECT_BIT = 12;
84: protected static final int START_BIT = 13;
85: protected static final int STICK_AND_BUTTONS = 14;
86:
87: protected static final int SUP_MASK = (1 << SUP_BIT);
88: protected static final int SLEFT_MASK = (1 << SLEFT_BIT);
89: protected static final int TUP_MASK = (1 << TUP_BIT);
90: protected static final int OLEFT_MASK = (1 << OLEFT_BIT);
91: protected static final int A_MASK = (1 << A_BIT);
92: protected static final int APRIME_MASK = (1 << APRIME_BIT);
93: protected static final int B_MASK = (1 << B_BIT);
94: protected static final int BPRIME_MASK = (1 << BPRIME_BIT);
95: protected static final int C_MASK = (1 << C_BIT);
96: protected static final int D_MASK = (1 << D_BIT);
97: protected static final int E1_MASK = (1 << E1_BIT);
98: protected static final int E2_MASK = (1 << E2_BIT);
99: protected static final int SELECT_MASK = (1 << SELECT_BIT);
100: protected static final int START_MASK = (1 << START_BIT);
101:
102: protected static final String[] BIT_TO_TEXT = {
103: "STICK ↑",
104: "STICK ←",
105: "THROTTLE ↑",
106: "OPTION ←",
107: "A",
108: "A'",
109: "B",
110: "B'",
111: "C",
112: "D",
113: "E1",
114: "E2",
115: "SELECT",
116: "START",
117: };
118:
119: protected static final boolean[] BIT_TO_REPEATABLE = {
120: false,
121: false,
122: false,
123: false,
124: true,
125: true,
126: true,
127: true,
128: true,
129: true,
130: true,
131: true,
132: false,
133: false,
134: };
135:
136: protected static final int MAP_CODE = STICK_AND_BUTTONS * 0;
137: protected static final int MAP_REPEAT = STICK_AND_BUTTONS * 1;
138: protected static final int MAP_DELAY = STICK_AND_BUTTONS * 2;
139: protected static final int MAP_INTERVAL = STICK_AND_BUTTONS * 3;
140: protected static final int MAP_LENGTH = STICK_AND_BUTTONS * 4;
141: protected int[] map;
142:
143: protected int xinputFocusedButton;
144: protected long[] startTimeOf;
145: protected int lastButtons;
146:
147: protected int req;
148: protected long transferStartTime;
149: protected static final int TRANSFER_STEPS = 12;
150: protected int[] transferData;
151:
152: protected JTextField[] xinputTextFieldOf = new JTextField[STICK_AND_BUTTONS];
153: protected JCheckBox[] repeatCheckBoxOf = new JCheckBox[STICK_AND_BUTTONS];
154: protected SpinnerNumberModel[] delayModelOf = new SpinnerNumberModel[STICK_AND_BUTTONS];
155: protected JSpinner[] delaySpinnerOf = new JSpinner[STICK_AND_BUTTONS];
156: protected SpinnerNumberModel[] intervalModelOf = new SpinnerNumberModel[STICK_AND_BUTTONS];
157: protected JSpinner[] intervalSpinnerOf = new JSpinner[STICK_AND_BUTTONS];
158:
159:
160:
161:
162:
163:
164:
165: protected final int[][] defaultMaps = new int[][] {
166: {
167: (128 | 0 << 5 | XInput.RSUP_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
168: (128 | 0 << 5 | XInput.RSLEFT_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
169: (128 | 0 << 5 | XInput.LSUP_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
170: (128 | 0 << 5 | XInput.LSLEFT_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
171: (128 | 0 << 5 | XInput.RSTICK_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
172: (128 | 0 << 5 | XInput.A_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
173: (128 | 0 << 5 | XInput.X_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
174: (128 | 0 << 5 | XInput.B_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
175: (128 | 0 << 5 | XInput.Y_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
176: (128 | 0 << 5 | XInput.LSTICK_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
177: (128 | 0 << 5 | XInput.LB_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
178: (128 | 0 << 5 | XInput.RB_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
179: (128 | 0 << 5 | XInput.BACK_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
180: (128 | 0 << 5 | XInput.START_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
181: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
182: 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0,
183: 0, 0, 0, 0, 100, 100, 100, 100, 100, 100, 100, 100, 0, 0,
184: },
185: {
186: (128 | 1 << 5 | XInput.RSUP_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
187: (128 | 1 << 5 | XInput.RSLEFT_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
188: (128 | 1 << 5 | XInput.LSUP_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
189: (128 | 1 << 5 | XInput.LSLEFT_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
190: (128 | 1 << 5 | XInput.RSTICK_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
191: (128 | 1 << 5 | XInput.A_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
192: (128 | 1 << 5 | XInput.X_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
193: (128 | 1 << 5 | XInput.B_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
194: (128 | 1 << 5 | XInput.Y_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
195: (128 | 1 << 5 | XInput.LSTICK_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
196: (128 | 1 << 5 | XInput.LB_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
197: (128 | 1 << 5 | XInput.RB_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
198: (128 | 1 << 5 | XInput.BACK_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
199: (128 | 1 << 5 | XInput.START_BIT ) << 16 | KeyEvent.VK_UNDEFINED,
200: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
201: 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0,
202: 0, 0, 0, 0, 100, 100, 100, 100, 100, 100, 100, 100, 0, 0,
203: },
204: };
205:
206:
207:
208:
209: public CyberStickAnalog (int number) {
210: this.number = number;
211: id = "cyberstickanalog" + number;
212: nameEn = "CYBER STICK (analog) #" + number;
213: nameJa = "サイバースティック (アナログ) #" + number;
214: map = new int[MAP_LENGTH];
215: int[] tempMap = Settings.sgsGetIntArray (id);
216: if (0 < tempMap.length && tempMap[0] == -2) {
217: for (int i = 0; i < MAP_LENGTH; i++) {
218: map[i] = i + 1 < tempMap.length ? tempMap[i + 1] : 0;
219: }
220: } else {
221: System.arraycopy (defaultMaps[number - 1], 0,
222: map, 0,
223: MAP_LENGTH);
224: }
225: if (PPI.PPI_XINPUT_ON) {
226: xinputFocusedButton = -1;
227: }
228: startTimeOf = new long[STICK_AND_BUTTONS];
229: transferData = new int[TRANSFER_STEPS + 1];
230: Arrays.fill (transferData, 0b11111111);
231: reset ();
232: configurationPanel = null;
233: }
234:
235:
236:
237: @Override public void tini () {
238: if (true &&
239: Arrays.equals (map, defaultMaps[number - 1])) {
240: Settings.sgsPutIntArray (id, new int[0]);
241: } else {
242: int[] tempMap = new int[1 + MAP_LENGTH];
243: tempMap[0] = -2;
244: for (int i = 0; i < MAP_LENGTH; i++) {
245: tempMap[1 + i] = map[i];
246: }
247: Settings.sgsPutIntArray (id, tempMap);
248: }
249: }
250:
251:
252:
253: @Override public final void reset () {
254: lastButtons = 0;
255: req = 0;
256: transferStartTime = 0L;
257: }
258:
259: private void updateText () {
260: for (int i = 0; i < STICK_AND_BUTTONS; i++) {
261: String text;
262: int xCode = map[MAP_CODE + i] >>> 16;
263: if (xCode == 0) {
264: text = Multilingual.mlnJapanese ? "なし" : "none";
265: } else {
266: int xIndex = (xCode >> 5) & 3;
267: int xBit = xCode & 31;
268: text = "#" + xIndex + " " + XInput.BIT_TO_TEXT[xBit];
269: }
270: xinputTextFieldOf[i].setText (text);
271: }
272: }
273:
274:
275:
276: @Override public void actionPerformed (ActionEvent ae) {
277: Object source = ae.getSource ();
278: String command = ae.getActionCommand ();
279: if (command.equals ("Reset to default values")) {
280: if (Arrays.equals (map, defaultMaps[number - 1])) {
281: JOptionPane.showMessageDialog (
282: null,
283: Multilingual.mlnJapanese ? nameJa + " の設定は初期値と同じです" : nameEn + " settings are equals to default values",
284: Multilingual.mlnJapanese ? "確認" : "Confirmation",
285: JOptionPane.PLAIN_MESSAGE);
286: return;
287: }
288: if (JOptionPane.showConfirmDialog (
289: null,
290: Multilingual.mlnJapanese ? nameJa + " の設定を初期値に戻しますか?" : "Do you want to reset " + nameEn + " settings to default values?",
291: Multilingual.mlnJapanese ? "確認" : "Confirmation",
292: JOptionPane.YES_NO_OPTION,
293: JOptionPane.PLAIN_MESSAGE) != JOptionPane.YES_OPTION) {
294: return;
295: }
296: System.arraycopy (defaultMaps[number - 1], 0,
297: map, 0,
298: MAP_LENGTH);
299: updateText ();
300: for (int i = 0; i < STICK_AND_BUTTONS; i++) {
301: if (BIT_TO_REPEATABLE[i]) {
302: repeatCheckBoxOf[i].setSelected (map[MAP_REPEAT + i] != 0);
303: delayModelOf[i].setValue (Math.max (DELAY_MIN, Math.min (DELAY_MAX, map[MAP_DELAY + i])));
304: intervalModelOf[i].setValue (Math.max (INTERVAL_MIN, Math.min (INTERVAL_MAX, map[MAP_INTERVAL + i])));
305: }
306: }
307: } else if (command.startsWith ("Repeat ")) {
308: int i = Integer.parseInt (command.substring (7));
309: map[MAP_REPEAT + i] = repeatCheckBoxOf[i].isSelected () ? 1 : 0;
310: } else {
311: System.out.println ("unknown action command " + command);
312: }
313: }
314:
315:
316:
317: @Override public void stateChanged (ChangeEvent ce) {
318: JSpinner spinner = (JSpinner) ce.getSource ();
319: String name = spinner.getName ();
320: if (name.startsWith ("Delay ")) {
321: int i = Integer.parseInt (name.substring (6));
322: map[MAP_DELAY + i] = delayModelOf[i].getNumber ().intValue ();
323: } else if (name.startsWith ("Interval ")) {
324: int i = Integer.parseInt (name.substring (9));
325: map[MAP_INTERVAL + i] = intervalModelOf[i].getNumber ().intValue ();
326: } else {
327: System.out.println ("unknown spinner name " + name);
328: }
329: }
330:
331:
332:
333: @Override public void focusGained (FocusEvent fe) {
334: Component component = fe.getComponent ();
335: String componentName = component.getName ();
336: int type = componentName.charAt (0);
337: int i = Integer.parseInt (componentName.substring (1));
338:
339: component.setBackground (new Color (LnF.lnfRGB[6]));
340: if (PPI.PPI_XINPUT_ON && type == 'x') {
341:
342: xinputFocusedButton = i;
343: if (PPI.ppiXInput != null) {
344: PPI.ppiXInput.addGamepadListener (this);
345: }
346: } else if (type == 'k') {
347: } else {
348: System.out.println ("unknown component name " + componentName);
349: }
350: }
351: @Override public void focusLost (FocusEvent fe) {
352: Component component = fe.getComponent ();
353: String componentName = component.getName ();
354: int type = componentName.charAt (0);
355: int i = Integer.parseInt (componentName.substring (1));
356:
357: component.setBackground (null);
358: if (PPI.PPI_XINPUT_ON && type == 'x') {
359:
360: if (PPI.ppiXInput != null) {
361: PPI.ppiXInput.removeGamepadListeners ();
362: }
363: xinputFocusedButton = -1;
364: } else if (type == 'k') {
365: } else {
366: System.out.println ("unknown component name " + componentName);
367: }
368: }
369:
370:
371:
372: @Override public void connected (XInput.Gamepad gamepad) {
373: }
374: @Override public void disconnected (XInput.Gamepad gamepad) {
375: }
376: @Override public void buttonPressed (XInput.Gamepad gamepad, int buttonMasks) {
377: if (buttonMasks == 0) {
378: return;
379: }
380: if (PPI.PPI_XINPUT_ON && 0 <= xinputFocusedButton) {
381: int xIndex = gamepad.getIndex ();
382: int xBit = Integer.numberOfTrailingZeros (buttonMasks);
383: int xCode = 128 | xIndex << 5 | xBit;
384: if (STICKS <= xinputFocusedButton ||
385: ((1 << xBit) & (XInput.LSUP_MASK |
386: XInput.LSDOWN_MASK |
387: XInput.LSLEFT_MASK |
388: XInput.LSRIGHT_MASK |
389: XInput.RSUP_MASK |
390: XInput.RSDOWN_MASK |
391: XInput.RSLEFT_MASK |
392: XInput.RSRIGHT_MASK)) != 0) {
393: map[MAP_CODE + xinputFocusedButton] = xCode << 16;
394:
395:
396: for (int i = 0; i < STICK_AND_BUTTONS; i++) {
397: int xCode2 = map[MAP_CODE + i] >>> 16;
398: if (xCode2 != 0) {
399: map[MAP_CODE + i] = ((xCode2 & ~(3 << 5)) | xIndex << 5) << 16;
400: }
401: }
402: updateText ();
403: }
404: }
405: }
406: @Override public void buttonReleased (XInput.Gamepad gamepad, int buttonMasks) {
407: }
408: @Override public void leftStickMovedX (XInput.Gamepad gamepad) {
409: }
410: @Override public void leftStickMovedY (XInput.Gamepad gamepad) {
411: }
412: @Override public void leftTriggerMoved (XInput.Gamepad gamepad) {
413: }
414: @Override public void rightStickMovedX (XInput.Gamepad gamepad) {
415: }
416: @Override public void rightStickMovedY (XInput.Gamepad gamepad) {
417: }
418: @Override public void rightTriggerMoved (XInput.Gamepad gamepad) {
419: }
420:
421:
422:
423: @Override public void keyPressed (KeyEvent ke) {
424: Component component = ke.getComponent ();
425: String componentName = component.getName ();
426: int type = componentName.charAt (0);
427: int i = Integer.parseInt (componentName.substring (1));
428: int xCode = map[MAP_CODE + i] >>> 16;
429: int keyCode = map[MAP_CODE + i] & 65535;
430: if (PPI.PPI_XINPUT_ON && type == 'x') {
431: if (ke.getKeyCode () == KeyEvent.VK_ESCAPE) {
432: xCode = 0;
433: }
434: } else if (type == 'k') {
435: } else {
436: System.out.println ("unknown component name " + componentName);
437: }
438: map[MAP_CODE + i] = xCode << 16 | keyCode;
439: updateText ();
440: ke.consume ();
441: }
442: @Override public void keyReleased (KeyEvent ke) {
443: ke.consume ();
444: }
445: @Override public void keyTyped (KeyEvent ke) {
446: ke.consume ();
447: }
448:
449:
450:
451:
452: @Override public JComponent getConfigurationPanel () {
453:
454: if (configurationPanel != null) {
455: return configurationPanel;
456: }
457:
458: for (int i = 0; i < STICK_AND_BUTTONS; i++) {
459: xinputTextFieldOf[i] =
460: ComponentFactory.setEnabled (
461: ComponentFactory.addListener (
462: ComponentFactory.addListener (
463: ComponentFactory.setHorizontalAlignment (
464: ComponentFactory.setName (
465: ComponentFactory.createTextField ("", 8),
466: "x" + i),
467: JTextField.CENTER),
468: (KeyListener) this),
469: (FocusListener) this),
470: PPI.PPI_XINPUT_ON && XEiJ.prgWindllLoaded);
471: if (BIT_TO_REPEATABLE[i]) {
472: repeatCheckBoxOf[i] =
473: ComponentFactory.setText (
474: ComponentFactory.createCheckBox (map[MAP_REPEAT + i] != 0, "Repeat " + i, (ActionListener) this),
475: "");
476: delayModelOf[i] =
477: new SpinnerNumberModel (Math.max (DELAY_MIN, Math.min (DELAY_MAX, map[MAP_DELAY + i])),
478: DELAY_MIN, DELAY_MAX, DELAY_STEP);
479: delaySpinnerOf[i] =
480: ComponentFactory.setName (
481: ComponentFactory.createNumberSpinner (delayModelOf[i], 4, (ChangeListener) this),
482: "Delay " + i);
483: intervalModelOf[i] =
484: new SpinnerNumberModel (Math.max (INTERVAL_MIN, Math.min (INTERVAL_MAX, map[MAP_INTERVAL + i])),
485: INTERVAL_MIN, INTERVAL_MAX, INTERVAL_STEP);
486: intervalSpinnerOf[i] =
487: ComponentFactory.setName (
488: ComponentFactory.createNumberSpinner (intervalModelOf[i], 4, (ChangeListener) this),
489: "Interval " + i);
490: }
491: }
492: updateText ();
493:
494:
495:
496:
497:
498: ArrayList<Object> cellList = new ArrayList<Object> ();
499:
500: cellList.add (null);
501: cellList.add (Multilingual.mlnText (ComponentFactory.createLabel ("Stick/Button"), "ja", "スティック/ボタン"));
502: cellList.add (ComponentFactory.createLabel ("XInput"));
503: cellList.add (Multilingual.mlnText (ComponentFactory.createLabel ("Burst"), "ja", "連射"));
504: cellList.add (Multilingual.mlnText (ComponentFactory.createLabel ("Delay (ms)"), "ja", "開始 (ms)"));
505: cellList.add (Multilingual.mlnText (ComponentFactory.createLabel ("Interval (ms)"), "ja", "間隔 (ms)"));
506:
507: cellList.add (ComponentFactory.createHorizontalSeparator ());
508:
509: for (int i = 0; i < STICK_AND_BUTTONS; i++) {
510: cellList.add (String.valueOf (1 + i));
511: cellList.add (BIT_TO_TEXT[i]);
512: cellList.add (xinputTextFieldOf[i]);
513: cellList.add (BIT_TO_REPEATABLE[i] ? repeatCheckBoxOf[i] : null);
514: cellList.add (BIT_TO_REPEATABLE[i] ? delaySpinnerOf[i] : null);
515: cellList.add (BIT_TO_REPEATABLE[i] ? intervalSpinnerOf[i] : null);
516: }
517:
518: configurationPanel =
519: ComponentFactory.createVerticalBox (
520: Box.createVerticalStrut (5),
521: ComponentFactory.createHorizontalBox (
522: Box.createHorizontalGlue (),
523: Multilingual.mlnText (ComponentFactory.createLabel (getNameEn ()), "ja", getNameJa ()),
524: Box.createHorizontalGlue ()),
525: Box.createVerticalStrut (5),
526: ComponentFactory.createHorizontalBox (
527: ComponentFactory.createGridPanel (
528: 6,
529: 2 + STICK_AND_BUTTONS,
530: "paddingLeft=3,paddingRight=3,center",
531: "",
532: "italic;colSpan=6,widen",
533: "",
534: cellList.toArray (new Object[0]))),
535: Box.createVerticalStrut (5),
536: ComponentFactory.createHorizontalBox (
537: Box.createHorizontalGlue (),
538: Multilingual.mlnText (ComponentFactory.createButton ("Reset to default values", (ActionListener) this), "ja", "初期値に戻す"),
539: Box.createHorizontalGlue ()),
540: Box.createVerticalStrut (5));
541:
542: return configurationPanel;
543: }
544:
545:
546:
547:
548:
549:
550: @Override public boolean input (KeyEvent ke, boolean pressed) {
551: return false;
552: }
553:
554:
555:
556:
557:
558: @Override public void setPin8 (int pin8) {
559: if (!(PPI.PPI_XINPUT_ON && XEiJ.prgWindllLoaded)) {
560: req = pin8;
561: return;
562: }
563: if ((req & ~pin8) == 0) {
564: req = pin8;
565: return;
566: }
567:
568: req = 0;
569:
570: transferStartTime = XEiJ.mpuClockTime;
571:
572: int outputSticks = 0;
573: if (PPI.ppiXInput != null) {
574: for (int i = 0; i < STICKS; i++) {
575: int xCode = map[MAP_CODE + i] >>> 16;
576: if (xCode != 0) {
577: int xIndex = (xCode >> 5) & 3;
578: int xBit = xCode & 31;
579:
580: int t = (xBit == XInput.LSUP_BIT ? -PPI.ppiXInput.getLeftStickY (xIndex) :
581: xBit == XInput.LSDOWN_BIT ? PPI.ppiXInput.getLeftStickY (xIndex) :
582: xBit == XInput.LSLEFT_BIT ? PPI.ppiXInput.getLeftStickX (xIndex) :
583: xBit == XInput.LSRIGHT_BIT ? -PPI.ppiXInput.getLeftStickX (xIndex) :
584: xBit == XInput.RSUP_BIT ? -PPI.ppiXInput.getRightStickY (xIndex) :
585: xBit == XInput.RSDOWN_BIT ? PPI.ppiXInput.getRightStickY (xIndex) :
586: xBit == XInput.RSLEFT_BIT ? PPI.ppiXInput.getRightStickX (xIndex) :
587: xBit == XInput.RSRIGHT_BIT ? -PPI.ppiXInput.getRightStickX (xIndex) :
588: 0);
589:
590: t >>= 8;
591:
592: t = Math.max (0, Math.min (255, 128 + t));
593: outputSticks |= t << (8 * i);
594: }
595: }
596: }
597:
598: int currentButtons = 0;
599: int lastIndex = -1;
600: int lastMasks = 0;
601: for (int i = STICKS; i < STICK_AND_BUTTONS; i++) {
602: int xCode = map[MAP_CODE + i] >>> 16;
603: if (xCode != 0) {
604: int xIndex = (xCode >> 5) & 3;
605: int xBit = xCode & 31;
606: if (lastIndex != xIndex) {
607: lastIndex = xIndex;
608: lastMasks = PPI.ppiXInput == null ? 0 : PPI.ppiXInput.getButtonMasks (lastIndex);
609: }
610: if ((lastMasks & (1 << xBit)) != 0) {
611: currentButtons |= 1 << i;
612: }
613: }
614: }
615: int pressedButtons = ~lastButtons & currentButtons;
616: lastButtons = currentButtons;
617: int outputButtons = 0;
618: for (int i = STICKS; i < STICK_AND_BUTTONS; i++) {
619: if ((pressedButtons & (1 << i)) != 0 &&
620: map[MAP_REPEAT + i] != 0) {
621: startTimeOf[i] = XEiJ.mpuClockTime + map[MAP_DELAY + i] * (XEiJ.TMR_FREQ / 1000);
622: }
623: if ((currentButtons & (1 << i)) != 0 &&
624: (map[MAP_REPEAT + i] == 0 ||
625: XEiJ.mpuClockTime < startTimeOf[i] ||
626: ((int) ((XEiJ.mpuClockTime - startTimeOf[i]) /
627: ((map[MAP_INTERVAL + i] >> 1) * (XEiJ.TMR_FREQ / 1000)))
628: & 1) != 0)) {
629: outputButtons |= 1 << i;
630: }
631: }
632:
633: transferData[0] = (0b10010000 |
634: ((outputButtons & (A_MASK | APRIME_MASK)) != 0 ? 0 : 0b00001000) |
635: ((outputButtons & (B_MASK | BPRIME_MASK)) != 0 ? 0 : 0b00000100) |
636: ((outputButtons & C_MASK ) != 0 ? 0 : 0b00000010) |
637: ((outputButtons & D_MASK ) != 0 ? 0 : 0b00000001));
638: transferData[1] = (0b10110000 |
639: ((outputButtons & E1_MASK ) != 0 ? 0 : 0b00001000) |
640: ((outputButtons & E2_MASK ) != 0 ? 0 : 0b00000100) |
641: ((outputButtons & START_MASK ) != 0 ? 0 : 0b00000010) |
642: ((outputButtons & SELECT_MASK) != 0 ? 0 : 0b00000001));
643: transferData[2] = 0b10010000 | ((outputSticks >>> (8 * SUP_BIT + 4)) & 0b00001111);
644: transferData[3] = 0b10110000 | ((outputSticks >>> (8 * SLEFT_BIT + 4)) & 0b00001111);
645: transferData[4] = 0b10010000 | ((outputSticks >>> (8 * TUP_BIT + 4)) & 0b00001111);
646: transferData[5] = 0b10110000 | ((outputSticks >>> (8 * OLEFT_BIT + 4)) & 0b00001111);
647: transferData[6] = 0b10010000 | ((outputSticks >>> (8 * SUP_BIT )) & 0b00001111);
648: transferData[7] = 0b10110000 | ((outputSticks >>> (8 * SLEFT_BIT )) & 0b00001111);
649: transferData[8] = 0b10010000 | ((outputSticks >>> (8 * TUP_BIT )) & 0b00001111);
650: transferData[9] = 0b10110000 | ((outputSticks >>> (8 * OLEFT_BIT )) & 0b00001111);
651: transferData[10] = (0b10010000 |
652: ((outputButtons & A_MASK ) != 0 ? 0 : 0b00001000) |
653: ((outputButtons & B_MASK ) != 0 ? 0 : 0b00000100) |
654: ((outputButtons & APRIME_MASK) != 0 ? 0 : 0b00000010) |
655: ((outputButtons & BPRIME_MASK) != 0 ? 0 : 0b00000001));
656: transferData[11] = 0b10111111;
657: }
658:
659:
660:
661:
662: @Override public int readByte () {
663: long t = XEiJ.mpuClockTime - transferStartTime;
664: t /= XEiJ.TMR_FREQ / 20000L;
665: int step = (int) Math.max (0L, Math.min ((long) TRANSFER_STEPS, t));
666: return transferData[step];
667: }
668:
669: }