~ubuntu-branches/debian/experimental/mednafen/experimental

« back to all changes in this revision

Viewing changes to src/psx/input/dualshock.cpp

  • Committer: Package Import Robot
  • Author(s): Stephen Kitt
  • Date: 2012-11-19 07:00:37 UTC
  • mfrom: (1.2.12)
  • Revision ID: package-import@ubuntu.com-20121119070037-jvknrm13zvim88oc
Tags: 0.9.26-1
* New upstream WIP version.
* Change priority to "extra" to match libvorbisidec1's.
* Drop "DM-Upload-Allowed" since it is no longer appropriate.
* Refresh patches, replacing MPC_STATUS_FAIL constant from older mpcdec
  versions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Mednafen - Multi-system Emulator
 
2
 *
 
3
 * This program is free software; you can redistribute it and/or modify
 
4
 * it under the terms of the GNU General Public License as published by
 
5
 * the Free Software Foundation; either version 2 of the License, or
 
6
 * (at your option) any later version.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program; if not, write to the Free Software
 
15
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 */
 
17
 
 
18
#include "../psx.h"
 
19
#include "../frontio.h"
 
20
#include "dualshock.h"
 
21
 
 
22
/*
 
23
   TODO:
 
24
        If we ever call Update() more than once per video frame(IE 50/60Hz), we'll need to add debounce logic to the analog mode button evaluation code.
 
25
*/
 
26
 
 
27
/* Notes:
 
28
 
 
29
     Both DA and DS style rumblings work in both analog and digital modes.
 
30
 
 
31
     Regarding getting Dual Shock style rumble working, Sony is evil and/or mean.  The owl tells me to burn Sony with boiling oil.
 
32
 
 
33
     To enable Dual Shock-style rumble, the game has to at least enter MAD MUNCHKINS MODE with command 0x43, and send the appropriate data(not the actual rumble type data per-se)
 
34
     with command 0x4D.
 
35
 
 
36
     DualAnalog-style rumble support seems to be borked until power loss if MAD MUNCHKINS MODE is even entered once...investigate further.
 
37
 
 
38
     Command 0x44 in MAD MUNCHKINS MODE can turn on/off analog mode(and the light with it).
 
39
 
 
40
     Command 0x42 in MAD MUNCHKINS MODE will return the analog mode style gamepad data, even when analog mode is off.  In combination with command 0x44, this could hypothetically
 
41
     be used for using the light in the gamepad as some kind of game mechanic).
 
42
 
 
43
     Dual Analog-style rumble notes(some of which may apply to DS too):
 
44
        Rumble appears to stop if you hold DTR active(TODO: for how long? instant?). (TODO: investigate if it's still stopped even if a memory card device number is sent.  It may be, since rumble may
 
45
                                                              cause excessive current draw in combination with memory card access)
 
46
 
 
47
        Rumble will work even if you interrupt the communication process after you've sent the rumble data(via command 0x42).
 
48
                Though if you interrupt it when you've only sent partial rumble data, dragons will eat you and I don't know(seems to have timing-dependent or random effects or something;
 
49
                based on VERY ROUGH testing).
 
50
*/
 
51
 
 
52
namespace MDFN_IEN_PSX
 
53
{
 
54
 
 
55
class InputDevice_DualShock : public InputDevice
 
56
{
 
57
 public:
 
58
 
 
59
 InputDevice_DualShock(const std::string &arg_name);
 
60
 virtual ~InputDevice_DualShock();
 
61
 
 
62
 virtual void Power(void);
 
63
 virtual void Update(const pscpu_timestamp_t timestamp);
 
64
 virtual void ResetTS(void);
 
65
 virtual void UpdateInput(const void *data);
 
66
 
 
67
 virtual void SetAMCT(bool enabled);
 
68
 //
 
69
 //
 
70
 //
 
71
 virtual void SetDTR(bool new_dtr);
 
72
 virtual bool GetDSR(void);
 
73
 virtual bool Clock(bool TxD, int32 &dsr_pulse_delay);
 
74
 
 
75
 private:
 
76
 
 
77
 void CheckManualAnaModeChange(void);
 
78
 
 
79
 //
 
80
 //
 
81
 bool cur_ana_button_state;
 
82
 bool prev_ana_button_state;
 
83
 int64 combo_anatoggle_counter;
 
84
 //
 
85
 
 
86
 bool da_rumble_compat;
 
87
 
 
88
 bool analog_mode;
 
89
 bool analog_mode_locked;
 
90
 
 
91
 bool mad_munchkins;
 
92
 uint8 rumble_magic[6];
 
93
 
 
94
 uint8 rumble_param[2];
 
95
 
 
96
 bool dtr;
 
97
 
 
98
 uint8 buttons[2];
 
99
 uint8 axes[2][2];
 
100
 
 
101
 int32 command_phase;
 
102
 uint32 bitpos;
 
103
 uint8 receive_buffer;
 
104
 
 
105
 uint8 command;
 
106
 
 
107
 uint8 transmit_buffer[8];
 
108
 uint32 transmit_pos;
 
109
 uint32 transmit_count;
 
110
 
 
111
 //
 
112
 //
 
113
 //
 
114
 bool am_prev_info;
 
115
 bool aml_prev_info;
 
116
 std::string gp_name;
 
117
 pscpu_timestamp_t lastts;
 
118
 
 
119
 //
 
120
 //
 
121
 bool amct_enabled;
 
122
};
 
123
 
 
124
InputDevice_DualShock::InputDevice_DualShock(const std::string &name)
 
125
{
 
126
 gp_name = name;
 
127
 Power();
 
128
 am_prev_info = analog_mode;
 
129
 aml_prev_info = analog_mode_locked;
 
130
 amct_enabled = false;
 
131
}
 
132
 
 
133
InputDevice_DualShock::~InputDevice_DualShock()
 
134
{
 
135
 
 
136
}
 
137
 
 
138
void InputDevice_DualShock::Update(const pscpu_timestamp_t timestamp)
 
139
{
 
140
 lastts = timestamp;
 
141
}
 
142
 
 
143
void InputDevice_DualShock::ResetTS(void)
 
144
{
 
145
 //printf("%lld\n", combo_anatoggle_counter);
 
146
 if(combo_anatoggle_counter >= 0)
 
147
  combo_anatoggle_counter += lastts;
 
148
 lastts = 0;
 
149
}
 
150
 
 
151
void InputDevice_DualShock::SetAMCT(bool enabled)
 
152
{
 
153
 amct_enabled = enabled;
 
154
}
 
155
 
 
156
//
 
157
// This simulates the behavior of the actual DualShock(analog toggle button evaluation is suspended while DTR is active).
 
158
// Call in Update(), and whenever dtr goes inactive in the port access code.
 
159
void InputDevice_DualShock::CheckManualAnaModeChange(void)
 
160
{
 
161
 if(!dtr)
 
162
 {
 
163
  bool need_mode_toggle = false;
 
164
 
 
165
  if(amct_enabled)
 
166
  {
 
167
   if(buttons[0] == 0x09 && buttons[1] == 0x0f)
 
168
   {
 
169
    if(combo_anatoggle_counter == -1)
 
170
     combo_anatoggle_counter = 0;
 
171
    else if(combo_anatoggle_counter >= (44100 * 768))
 
172
    {
 
173
     need_mode_toggle = true;
 
174
     combo_anatoggle_counter = -2;
 
175
    }
 
176
   }
 
177
   else
 
178
    combo_anatoggle_counter = -1;
 
179
  }  
 
180
  else
 
181
  {
 
182
   combo_anatoggle_counter = -1;
 
183
   if(cur_ana_button_state && (cur_ana_button_state != prev_ana_button_state))
 
184
   {
 
185
    need_mode_toggle = true;
 
186
   }
 
187
  }
 
188
 
 
189
  if(need_mode_toggle)
 
190
  {
 
191
   if(analog_mode_locked)
 
192
   {
 
193
    MDFN_DispMessage(_("%s: Analog mode is locked %s."), gp_name.c_str(), analog_mode ? _("on") : _("off"));
 
194
   }
 
195
   else
 
196
    analog_mode = !analog_mode;
 
197
  }
 
198
 
 
199
  prev_ana_button_state = cur_ana_button_state;         // Don't move this outside of the if(!dtr) block!
 
200
 }
 
201
}
 
202
 
 
203
void InputDevice_DualShock::Power(void)
 
204
{
 
205
 combo_anatoggle_counter = -2;
 
206
 lastts = 0;
 
207
 //
 
208
 //
 
209
 
 
210
 dtr = 0;
 
211
 
 
212
 buttons[0] = buttons[1] = 0;
 
213
 
 
214
 command_phase = 0;
 
215
 
 
216
 bitpos = 0;
 
217
 
 
218
 receive_buffer = 0;
 
219
 
 
220
 command = 0;
 
221
 
 
222
 memset(transmit_buffer, 0, sizeof(transmit_buffer));
 
223
 
 
224
 transmit_pos = 0;
 
225
 transmit_count = 0;
 
226
 
 
227
 analog_mode = false;
 
228
 analog_mode_locked = false;
 
229
 
 
230
 mad_munchkins = false;
 
231
 memset(rumble_magic, 0, sizeof(rumble_magic));
 
232
 memset(rumble_param, 0, sizeof(rumble_param));
 
233
 
 
234
 da_rumble_compat = true;
 
235
 
 
236
 prev_ana_button_state = false;
 
237
}
 
238
 
 
239
void InputDevice_DualShock::UpdateInput(const void *data)
 
240
{
 
241
 uint8 *d8 = (uint8 *)data;
 
242
 
 
243
 buttons[0] = d8[0];
 
244
 buttons[1] = d8[1];
 
245
 cur_ana_button_state = d8[2] & 0x01;
 
246
 
 
247
 for(int stick = 0; stick < 2; stick++)
 
248
 {
 
249
  for(int axis = 0; axis < 2; axis++)
 
250
  {
 
251
   int32 tmp;
 
252
 
 
253
   tmp = 32768 + MDFN_de32lsb((const uint8 *)data + stick * 16 + axis * 8 + 4) - ((int32)MDFN_de32lsb((const uint8 *)data + stick * 16 + axis * 8 + 8) * 32768 / 32767);
 
254
   tmp >>= 8;
 
255
 
 
256
   axes[stick][axis] = tmp;
 
257
  }
 
258
 }
 
259
 
 
260
 if(da_rumble_compat == false)
 
261
 {
 
262
  uint8 sneaky_weaky = 0;
 
263
 
 
264
  if(rumble_param[0] == 0x01)
 
265
   sneaky_weaky = 0xFF;
 
266
 
 
267
  MDFN_en32lsb(&d8[4 + 32 + 0], (sneaky_weaky << 0) | (rumble_param[1] << 8));
 
268
 }
 
269
 else
 
270
 {
 
271
  uint8 sneaky_weaky = 0;
 
272
 
 
273
  if(((rumble_param[0] & 0xC0) == 0x40) && ((rumble_param[1] & 0x01) == 0x01))
 
274
   sneaky_weaky = 0xFF;
 
275
 
 
276
  MDFN_en32lsb(&d8[4 + 32 + 0], sneaky_weaky << 0);
 
277
 }
 
278
 
 
279
 //printf("%d %d %d %d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]);
 
280
 
 
281
 //
 
282
 //
 
283
 //
 
284
 CheckManualAnaModeChange();
 
285
 
 
286
 if(am_prev_info != analog_mode || aml_prev_info != analog_mode_locked)
 
287
 {
 
288
  MDFN_DispMessage(_("%s: Analog mode is %s(%s)."), gp_name.c_str(), analog_mode ? _("on") : _("off"), analog_mode_locked ? _("locked") : _("unlocked"));
 
289
 }
 
290
 am_prev_info = analog_mode;
 
291
 aml_prev_info = analog_mode_locked;
 
292
}
 
293
 
 
294
 
 
295
void InputDevice_DualShock::SetDTR(bool new_dtr)
 
296
{
 
297
 const bool old_dtr = dtr;
 
298
 dtr = new_dtr; // Set it to new state before we call CheckManualAnaModeChange().
 
299
 
 
300
 if(!old_dtr && dtr)
 
301
 {
 
302
  command_phase = 0;
 
303
  bitpos = 0;
 
304
  transmit_pos = 0;
 
305
  transmit_count = 0;
 
306
 }
 
307
 else if(old_dtr && !dtr)
 
308
 {
 
309
  CheckManualAnaModeChange();
 
310
  //if(bitpos || transmit_count)
 
311
  // printf("[PAD] Abort communication!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
 
312
 }
 
313
}
 
314
 
 
315
bool InputDevice_DualShock::GetDSR(void)
 
316
{
 
317
 if(!dtr)
 
318
  return(0);
 
319
 
 
320
 if(!bitpos && transmit_count)
 
321
  return(1);
 
322
 
 
323
 return(0);
 
324
}
 
325
 
 
326
bool InputDevice_DualShock::Clock(bool TxD, int32 &dsr_pulse_delay)
 
327
{
 
328
 bool ret = 1;
 
329
 
 
330
 dsr_pulse_delay = 0;
 
331
 
 
332
 if(!dtr)
 
333
  return(1);
 
334
 
 
335
 if(transmit_count)
 
336
  ret = (transmit_buffer[transmit_pos] >> bitpos) & 1;
 
337
 
 
338
 receive_buffer &= ~(1 << bitpos);
 
339
 receive_buffer |= TxD << bitpos;
 
340
 bitpos = (bitpos + 1) & 0x7;
 
341
 
 
342
 if(!bitpos)
 
343
 {
 
344
  //if(command == 0x44)
 
345
  //if(mad_munchkins || command == 0x43)
 
346
  // fprintf(stderr, "[PAD] Receive: %02x -- command=%02x, command_phase=%d, transmit_pos=%d\n", receive_buffer, command, command_phase, transmit_pos);
 
347
 
 
348
  if(transmit_count)
 
349
  {
 
350
   transmit_pos++;
 
351
   transmit_count--;
 
352
  }
 
353
 
 
354
  switch(command_phase)
 
355
  {
 
356
   case 0:
 
357
          if(receive_buffer != 0x01)
 
358
            command_phase = -1;
 
359
          else
 
360
          {
 
361
           if(mad_munchkins)
 
362
           {
 
363
            transmit_buffer[0] = 0xF3;
 
364
            transmit_pos = 0;
 
365
            transmit_count = 1;
 
366
            command_phase = 101;
 
367
           }
 
368
           else
 
369
           {
 
370
            transmit_buffer[0] = analog_mode ? 0x73 : 0x41;
 
371
            transmit_pos = 0;
 
372
            transmit_count = 1;
 
373
            command_phase++;
 
374
           }
 
375
          }
 
376
          break;
 
377
 
 
378
   case 1:
 
379
        command = receive_buffer;
 
380
        command_phase++;
 
381
 
 
382
        transmit_buffer[0] = 0x5A;
 
383
 
 
384
        //fprintf(stderr, "Gamepad command: 0x%02x\n", command);
 
385
        //if(command != 0x42 && command != 0x43)
 
386
        // fprintf(stderr, "Gamepad unhandled command: 0x%02x\n", command);
 
387
 
 
388
        if(command == 0x42)
 
389
        {
 
390
         transmit_buffer[0] = 0x5A;
 
391
         transmit_pos = 0;
 
392
         transmit_count = 1;
 
393
         command_phase = (command << 8) | 0x00;
 
394
        }
 
395
        else if(command == 0x43)
 
396
        {
 
397
         transmit_pos = 0;
 
398
         if(analog_mode)
 
399
         {
 
400
          transmit_buffer[1] = 0xFF ^ buttons[0];
 
401
          transmit_buffer[2] = 0xFF ^ buttons[1];
 
402
          transmit_buffer[3] = axes[0][0];
 
403
          transmit_buffer[4] = axes[0][1];
 
404
          transmit_buffer[5] = axes[1][0];
 
405
          transmit_buffer[6] = axes[1][1];
 
406
          transmit_count = 7;
 
407
         }
 
408
         else
 
409
         {
 
410
          transmit_buffer[1] = 0xFF ^ buttons[0];
 
411
          transmit_buffer[2] = 0xFF ^ buttons[1];
 
412
          transmit_count = 3;
 
413
         }
 
414
        }
 
415
        else
 
416
        {
 
417
         command_phase = -1;
 
418
         transmit_buffer[1] = 0;
 
419
         transmit_buffer[2] = 0;
 
420
         transmit_pos = 0;
 
421
         transmit_count = 0;
 
422
        }
 
423
        break;
 
424
 
 
425
   case 2:
 
426
        {
 
427
         if(command == 0x43 && transmit_pos == 2 && (receive_buffer == 0x01))
 
428
         {
 
429
          //fprintf(stderr, "Mad Munchkins mode entered!\n");
 
430
          mad_munchkins = true;
 
431
 
 
432
          if(da_rumble_compat)
 
433
          {
 
434
           rumble_param[0] = 0;
 
435
           rumble_param[1] = 0;
 
436
           da_rumble_compat = false;
 
437
          }
 
438
          command_phase = -1;
 
439
         }
 
440
        }
 
441
        break;
 
442
 
 
443
   case 101:
 
444
        command = receive_buffer;
 
445
 
 
446
        //fprintf(stderr, "Mad Munchkins DualShock command: 0x%02x\n", command);
 
447
 
 
448
        if(command >= 0x40 && command <= 0x4F)
 
449
        {
 
450
         transmit_buffer[0] = 0x5A;
 
451
         transmit_pos = 0;
 
452
         transmit_count = 1;
 
453
         command_phase = (command << 8) | 0x00;
 
454
        }
 
455
        else
 
456
        {
 
457
         transmit_count = 0;
 
458
         command_phase = -1;
 
459
        }
 
460
        break;
 
461
 
 
462
  /************************/
 
463
  /* MMMode 1, Command 0x40 */
 
464
  /************************/
 
465
  case 0x4000:
 
466
        if(receive_buffer == 0x00)
 
467
        {
 
468
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
469
         command_phase++;
 
470
        }
 
471
        else
 
472
         command_phase = -1;
 
473
        break;
 
474
 
 
475
  case 0x4001:
 
476
        transmit_buffer[0] = 0x00;
 
477
        transmit_buffer[1] = 0x00;
 
478
        transmit_buffer[2] = 0x00;
 
479
        transmit_buffer[3] = 0x00;
 
480
        transmit_buffer[4] = 0x00;
 
481
        transmit_pos = 0;
 
482
        transmit_count = 5;
 
483
        command_phase = -1;
 
484
        break;
 
485
 
 
486
 
 
487
  /************************/
 
488
  /* MMMode 1, Command 0x41 */
 
489
  /************************/
 
490
  case 0x4100:
 
491
        if(receive_buffer == 0x00)
 
492
        {
 
493
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
494
         command_phase++;
 
495
        }
 
496
        else
 
497
         command_phase = -1;
 
498
        break;
 
499
 
 
500
  case 0x4101:
 
501
        transmit_buffer[0] = 0x00;
 
502
        transmit_buffer[1] = 0x00;
 
503
        transmit_buffer[2] = 0x00;
 
504
        transmit_buffer[3] = 0x00;
 
505
        transmit_buffer[4] = 0x00;
 
506
        transmit_pos = 0;
 
507
        transmit_count = 5;
 
508
        command_phase = -1;
 
509
        break;
 
510
 
 
511
  /**************************/
 
512
  /* MMMode 0&1, Command 0x42 */
 
513
  /**************************/
 
514
  case 0x4200:
 
515
        transmit_pos = 0;
 
516
        if(analog_mode || mad_munchkins)
 
517
        {
 
518
         transmit_buffer[0] = 0xFF ^ buttons[0];
 
519
         transmit_buffer[1] = 0xFF ^ buttons[1];
 
520
         transmit_buffer[2] = axes[0][0];
 
521
         transmit_buffer[3] = axes[0][1];
 
522
         transmit_buffer[4] = axes[1][0];
 
523
         transmit_buffer[5] = axes[1][1];
 
524
         transmit_count = 6;
 
525
        }
 
526
        else
 
527
        {
 
528
         transmit_buffer[0] = 0xFF ^ buttons[0];
 
529
         transmit_buffer[1] = 0xFF ^ buttons[1];
 
530
         transmit_count = 2;
 
531
        }
 
532
        command_phase++;
 
533
        break;
 
534
 
 
535
  case 0x4201:                  // Weak(in DS mode)
 
536
        if(da_rumble_compat || (rumble_magic[0] == 0x00 && rumble_magic[2] != 0x00 && rumble_magic[3] != 0x00 && rumble_magic[4] != 0x00 && rumble_magic[5] != 0x00))
 
537
         rumble_param[0] = receive_buffer;
 
538
        command_phase++;
 
539
        break;
 
540
 
 
541
  case 0x4202:                  // Strong(in DS mode)
 
542
        if(da_rumble_compat || rumble_magic[1] == 0x01)
 
543
         rumble_param[1] = receive_buffer;
 
544
        command_phase++;        // Nowhere here we come!
 
545
        break;
 
546
 
 
547
  /************************/
 
548
  /* MMMode 1, Command 0x43 */
 
549
  /************************/
 
550
  case 0x4300:
 
551
        if(receive_buffer == 0x00)
 
552
        {
 
553
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
554
         command_phase++;
 
555
        }
 
556
        else
 
557
         command_phase = -1;
 
558
        break;
 
559
 
 
560
  case 0x4301:
 
561
        if(receive_buffer == 0x00)
 
562
        {
 
563
         //fprintf(stderr, "Mad Munchkins mode left!\n");
 
564
         mad_munchkins = false;
 
565
        }
 
566
        transmit_buffer[0] = 0x00;
 
567
        transmit_buffer[1] = 0x00;
 
568
        transmit_buffer[2] = 0x00;
 
569
        transmit_buffer[3] = 0x00;
 
570
        transmit_buffer[4] = 0x00;
 
571
        transmit_pos = 0;
 
572
        transmit_count = 5;
 
573
        command_phase = -1;
 
574
        break;
 
575
 
 
576
  /************************/
 
577
  /* MMMode 1, Command 0x44 */
 
578
  /************************/
 
579
  case 0x4400:
 
580
        if(receive_buffer == 0x00)
 
581
        {
 
582
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
583
         command_phase++;
 
584
        }
 
585
        else
 
586
         command_phase = -1;
 
587
        break;
 
588
 
 
589
  case 0x4401:
 
590
        transmit_buffer[0] = 0x00;
 
591
        transmit_buffer[1] = 0x00;
 
592
        transmit_buffer[2] = 0x00;
 
593
        transmit_buffer[3] = 0x00;
 
594
        transmit_buffer[4] = 0x00;
 
595
        transmit_pos = 0;
 
596
        transmit_count = 5;
 
597
        command_phase++;
 
598
 
 
599
        // Ignores locking state.
 
600
        switch(receive_buffer)
 
601
        {
 
602
         case 0x00:
 
603
                analog_mode = false;
 
604
                //fprintf(stderr, "Analog mode disabled\n");
 
605
                break;
 
606
 
 
607
         case 0x01:
 
608
                analog_mode = true;
 
609
                //fprintf(stderr, "Analog mode enabled\n");
 
610
                break;
 
611
        }
 
612
        break;
 
613
 
 
614
  case 0x4402:
 
615
        switch(receive_buffer)
 
616
        {
 
617
         case 0x02:
 
618
                analog_mode_locked = false;
 
619
                break;
 
620
 
 
621
         case 0x03:
 
622
                analog_mode_locked = true;
 
623
                break;
 
624
        }
 
625
        command_phase = -1;
 
626
        break;
 
627
 
 
628
  /************************/
 
629
  /* MMMode 1, Command 0x45 */
 
630
  /************************/
 
631
  case 0x4500:
 
632
        if(receive_buffer == 0x00)
 
633
        {
 
634
         transmit_buffer[0] = 0x01; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
635
         command_phase++;
 
636
        }
 
637
        else
 
638
         command_phase = -1;
 
639
        break;
 
640
 
 
641
  case 0x4501:
 
642
        transmit_buffer[0] = 0x02;
 
643
        transmit_buffer[1] = analog_mode ? 0x01 : 0x00;
 
644
        transmit_buffer[2] = 0x02;
 
645
        transmit_buffer[3] = 0x01;
 
646
        transmit_buffer[4] = 0x00;
 
647
        transmit_pos = 0;
 
648
        transmit_count = 5;
 
649
        command_phase = -1;
 
650
        break;
 
651
 
 
652
 
 
653
  /************************/
 
654
  /* MMMode 1, Command 0x46 */
 
655
  /************************/
 
656
  case 0x4600:
 
657
        if(receive_buffer == 0x00)
 
658
        {
 
659
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
660
         command_phase++;
 
661
        }
 
662
        else
 
663
         command_phase = -1;
 
664
        break;
 
665
 
 
666
  case 0x4601:
 
667
        if(receive_buffer == 0x00)
 
668
        {
 
669
         transmit_buffer[0] = 0x00;
 
670
         transmit_buffer[1] = 0x01;
 
671
         transmit_buffer[2] = 0x02;
 
672
         transmit_buffer[3] = 0x00;
 
673
         transmit_buffer[4] = 0x0A;
 
674
        }
 
675
        else if(receive_buffer == 0x01)
 
676
        {
 
677
         transmit_buffer[0] = 0x00;
 
678
         transmit_buffer[1] = 0x01;
 
679
         transmit_buffer[2] = 0x01;
 
680
         transmit_buffer[3] = 0x01;
 
681
         transmit_buffer[4] = 0x14;
 
682
        }
 
683
        else
 
684
        {
 
685
         transmit_buffer[0] = 0x00;
 
686
         transmit_buffer[1] = 0x00;
 
687
         transmit_buffer[2] = 0x00;
 
688
         transmit_buffer[3] = 0x00;
 
689
         transmit_buffer[4] = 0x00;
 
690
        }
 
691
        transmit_pos = 0;
 
692
        transmit_count = 5;
 
693
        command_phase = -1;
 
694
        break;
 
695
 
 
696
  /************************/
 
697
  /* MMMode 1, Command 0x47 */
 
698
  /************************/
 
699
  case 0x4700:
 
700
        if(receive_buffer == 0x00)
 
701
        {
 
702
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
703
         command_phase++;
 
704
        }
 
705
        else
 
706
         command_phase = -1;
 
707
        break;
 
708
 
 
709
  case 0x4701:
 
710
        if(receive_buffer == 0x00)
 
711
        {
 
712
         transmit_buffer[0] = 0x00;
 
713
         transmit_buffer[1] = 0x02;
 
714
         transmit_buffer[2] = 0x00;
 
715
         transmit_buffer[3] = 0x01;
 
716
         transmit_buffer[4] = 0x00;
 
717
        }
 
718
        else
 
719
        {
 
720
         transmit_buffer[0] = 0x00;
 
721
         transmit_buffer[1] = 0x00;
 
722
         transmit_buffer[2] = 0x00;
 
723
         transmit_buffer[3] = 0x00;
 
724
         transmit_buffer[4] = 0x00;
 
725
        }
 
726
        transmit_pos = 0;
 
727
        transmit_count = 5;
 
728
        command_phase = -1;
 
729
        break;
 
730
 
 
731
  /************************/
 
732
  /* MMMode 1, Command 0x48 */
 
733
  /************************/
 
734
  case 0x4800:
 
735
        if(receive_buffer == 0x00)
 
736
        {
 
737
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
738
         command_phase++;
 
739
        }
 
740
        else
 
741
         command_phase = -1;
 
742
        break;
 
743
 
 
744
  case 0x4801:
 
745
        if(receive_buffer == 0x00)
 
746
        {
 
747
         transmit_buffer[0] = 0x00;
 
748
         transmit_buffer[1] = 0x00;
 
749
         transmit_buffer[2] = 0x00;
 
750
         transmit_buffer[3] = 0x01;
 
751
         transmit_buffer[4] = rumble_param[0];
 
752
        }
 
753
        else if(receive_buffer == 0x01)
 
754
        {
 
755
         transmit_buffer[0] = 0x00;
 
756
         transmit_buffer[1] = 0x00;
 
757
         transmit_buffer[2] = 0x00;
 
758
         transmit_buffer[3] = 0x01;
 
759
         transmit_buffer[4] = rumble_param[1];
 
760
        }
 
761
        else
 
762
        {
 
763
         transmit_buffer[0] = 0x00;
 
764
         transmit_buffer[1] = 0x00;
 
765
         transmit_buffer[2] = 0x00;
 
766
         transmit_buffer[3] = 0x00;
 
767
         transmit_buffer[4] = 0x00;
 
768
        }
 
769
        transmit_pos = 0;
 
770
        transmit_count = 5;
 
771
        command_phase = -1;
 
772
        break;
 
773
 
 
774
  /************************/
 
775
  /* MMMode 1, Command 0x49 */
 
776
  /************************/
 
777
  case 0x4900:
 
778
        if(receive_buffer == 0x00)
 
779
        {
 
780
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
781
         command_phase++;
 
782
        }
 
783
        else
 
784
         command_phase = -1;
 
785
        break;
 
786
 
 
787
  case 0x4901:
 
788
        transmit_buffer[0] = 0x00;
 
789
        transmit_buffer[1] = 0x00;
 
790
        transmit_buffer[2] = 0x00;
 
791
        transmit_buffer[3] = 0x00;
 
792
        transmit_buffer[4] = 0x00;
 
793
        transmit_pos = 0;
 
794
        transmit_count = 5;
 
795
        command_phase = -1;
 
796
        break;
 
797
 
 
798
  /************************/
 
799
  /* MMMode 1, Command 0x4A */
 
800
  /************************/
 
801
  case 0x4A00:
 
802
        if(receive_buffer == 0x00)
 
803
        {
 
804
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
805
         command_phase++;
 
806
        }
 
807
        else
 
808
         command_phase = -1;
 
809
        break;
 
810
 
 
811
  case 0x4A01:
 
812
        transmit_buffer[0] = 0x00;
 
813
        transmit_buffer[1] = 0x00;
 
814
        transmit_buffer[2] = 0x00;
 
815
        transmit_buffer[3] = 0x00;
 
816
        transmit_buffer[4] = 0x00;
 
817
        transmit_pos = 0;
 
818
        transmit_count = 5;
 
819
        command_phase = -1;
 
820
        break;
 
821
 
 
822
  /************************/
 
823
  /* MMMode 1, Command 0x4B */
 
824
  /************************/
 
825
  case 0x4B00:
 
826
        if(receive_buffer == 0x00)
 
827
        {
 
828
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
829
         command_phase++;
 
830
        }
 
831
        else
 
832
         command_phase = -1;
 
833
        break;
 
834
 
 
835
  case 0x4B01:
 
836
        transmit_buffer[0] = 0x00;
 
837
        transmit_buffer[1] = 0x00;
 
838
        transmit_buffer[2] = 0x00;
 
839
        transmit_buffer[3] = 0x00;
 
840
        transmit_buffer[4] = 0x00;
 
841
        transmit_pos = 0;
 
842
        transmit_count = 5;
 
843
        command_phase = -1;
 
844
        break;
 
845
 
 
846
  /************************/
 
847
  /* MMMode 1, Command 0x4C */
 
848
  /************************/
 
849
  case 0x4C00:
 
850
        if(receive_buffer == 0x00)
 
851
        {
 
852
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
853
         command_phase++;
 
854
        }
 
855
        else
 
856
         command_phase = -1;
 
857
        break;
 
858
 
 
859
  case 0x4C01:
 
860
        if(receive_buffer == 0x00)
 
861
        {
 
862
         transmit_buffer[0] = 0x00;
 
863
         transmit_buffer[1] = 0x00;
 
864
         transmit_buffer[2] = 0x04;
 
865
         transmit_buffer[3] = 0x00;
 
866
         transmit_buffer[4] = 0x00;
 
867
        }
 
868
        else if(receive_buffer == 0x01)
 
869
        {
 
870
         transmit_buffer[0] = 0x00;
 
871
         transmit_buffer[1] = 0x00;
 
872
         transmit_buffer[2] = 0x07;
 
873
         transmit_buffer[3] = 0x00;
 
874
         transmit_buffer[4] = 0x00;
 
875
        }
 
876
        else
 
877
        {
 
878
         transmit_buffer[0] = 0x00;
 
879
         transmit_buffer[1] = 0x00;
 
880
         transmit_buffer[2] = 0x00;
 
881
         transmit_buffer[3] = 0x00;
 
882
         transmit_buffer[4] = 0x00;
 
883
        }
 
884
 
 
885
        transmit_pos = 0;
 
886
        transmit_count = 5;
 
887
        command_phase = -1;
 
888
        break;
 
889
 
 
890
  /************************/
 
891
  /* MMMode 1, Command 0x4D */
 
892
  /************************/
 
893
  case 0x4D00:
 
894
        if(receive_buffer == 0x00)
 
895
        {
 
896
         transmit_buffer[0] = rumble_magic[0]; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
897
         command_phase++;
 
898
        }
 
899
        else
 
900
         command_phase = -1;
 
901
        break;
 
902
 
 
903
  case 0x4D01:
 
904
  case 0x4D02:
 
905
  case 0x4D03:
 
906
  case 0x4D04:
 
907
  case 0x4D05:
 
908
  case 0x4D06:
 
909
        {
 
910
         unsigned index = command_phase - 0x4D01;
 
911
 
 
912
         if(index < 5)
 
913
         {
 
914
          transmit_buffer[0] = rumble_magic[1 + index];
 
915
          transmit_pos = 0;
 
916
          transmit_count = 1;
 
917
          command_phase++;
 
918
         }
 
919
         else
 
920
          command_phase = -1;
 
921
 
 
922
         rumble_magic[index] = receive_buffer;   
 
923
        }
 
924
        break;
 
925
 
 
926
  /************************/
 
927
  /* MMMode 1, Command 0x4E */
 
928
  /************************/
 
929
  case 0x4E00:
 
930
        if(receive_buffer == 0x00)
 
931
        {
 
932
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
933
         command_phase++;
 
934
        }
 
935
        else
 
936
         command_phase = -1;
 
937
        break;
 
938
 
 
939
  case 0x4E01:
 
940
        transmit_buffer[0] = 0x00;
 
941
        transmit_buffer[1] = 0x00;
 
942
        transmit_buffer[2] = 0x00;
 
943
        transmit_buffer[3] = 0x00;
 
944
        transmit_buffer[4] = 0x00;
 
945
        transmit_pos = 0;
 
946
        transmit_count = 5;
 
947
        command_phase = -1;
 
948
        break;
 
949
 
 
950
 
 
951
  /************************/
 
952
  /* MMMode 1, Command 0x4F */
 
953
  /************************/
 
954
  case 0x4F00:
 
955
        if(receive_buffer == 0x00)
 
956
        {
 
957
         transmit_buffer[0] = 0; /**/ transmit_pos = 0; transmit_count = 1; /**/
 
958
         command_phase++;
 
959
        }
 
960
        else
 
961
         command_phase = -1;
 
962
        break;
 
963
 
 
964
  case 0x4F01:
 
965
        transmit_buffer[0] = 0x00;
 
966
        transmit_buffer[1] = 0x00;
 
967
        transmit_buffer[2] = 0x00;
 
968
        transmit_buffer[3] = 0x00;
 
969
        transmit_buffer[4] = 0x00;
 
970
        transmit_pos = 0;
 
971
        transmit_count = 5;
 
972
        command_phase = -1;
 
973
        break;
 
974
  }
 
975
 }
 
976
 
 
977
 if(!bitpos && transmit_count)
 
978
  dsr_pulse_delay = 0x40; //0x100;
 
979
 
 
980
 return(ret);
 
981
}
 
982
 
 
983
InputDevice *Device_DualShock_Create(const std::string &name)
 
984
{
 
985
 return new InputDevice_DualShock(name);
 
986
}
 
987
 
 
988
 
 
989
InputDeviceInputInfoStruct Device_DualShock_IDII[26] =
 
990
{
 
991
 { "select", "SELECT", 4, IDIT_BUTTON, NULL },
 
992
 { "l3", "Left Stick, Button(L3)", 18, IDIT_BUTTON, NULL },
 
993
 { "r3", "Right stick, Button(R3)", 23, IDIT_BUTTON, NULL },
 
994
 { "start", "START", 5, IDIT_BUTTON, NULL },
 
995
 { "up", "D-Pad UP ↑", 0, IDIT_BUTTON, "down" },
 
996
 { "right", "D-Pad RIGHT →", 3, IDIT_BUTTON, "left" },
 
997
 { "down", "D-Pad DOWN ↓", 1, IDIT_BUTTON, "up" },
 
998
 { "left", "D-Pad LEFT ←", 2, IDIT_BUTTON, "right" },
 
999
 
 
1000
 { "l2", "L2 (rear left shoulder)", 11, IDIT_BUTTON, NULL },
 
1001
 { "r2", "R2 (rear right shoulder)", 13, IDIT_BUTTON, NULL },
 
1002
 { "l1", "L1 (front left shoulder)", 10, IDIT_BUTTON, NULL },
 
1003
 { "r1", "R1 (front right shoulder)", 12, IDIT_BUTTON, NULL },
 
1004
 
 
1005
 { "triangle", "△ (upper)", 6, IDIT_BUTTON_CAN_RAPID, NULL },
 
1006
 { "circle", "○ (right)", 9, IDIT_BUTTON_CAN_RAPID, NULL },
 
1007
 { "cross", "x (lower)", 7, IDIT_BUTTON_CAN_RAPID, NULL },
 
1008
 { "square", "□ (left)", 8, IDIT_BUTTON_CAN_RAPID, NULL },
 
1009
 
 
1010
 { "analog", "Analog(mode toggle)", 24, IDIT_BUTTON, NULL },
 
1011
 
 
1012
 { "rstick_right", "Right Stick RIGHT →", 22, IDIT_BUTTON_ANALOG },
 
1013
 { "rstick_left", "Right Stick LEFT ←", 21, IDIT_BUTTON_ANALOG },
 
1014
 { "rstick_down", "Right Stick DOWN ↓", 20, IDIT_BUTTON_ANALOG },
 
1015
 { "rstick_up", "Right Stick UP ↑", 19, IDIT_BUTTON_ANALOG },
 
1016
 
 
1017
 { "lstick_right", "Left Stick RIGHT →", 17, IDIT_BUTTON_ANALOG },
 
1018
 { "lstick_left", "Left Stick LEFT ←", 16, IDIT_BUTTON_ANALOG },
 
1019
 { "lstick_down", "Left Stick DOWN ↓", 15, IDIT_BUTTON_ANALOG },
 
1020
 { "lstick_up", "Left Stick UP ↑", 14, IDIT_BUTTON_ANALOG },
 
1021
 
 
1022
 { "rumble", "RUMBLE MONSTER RUMBA", 100, IDIT_RUMBLE },
 
1023
};
 
1024
 
 
1025
}