~ubuntu-branches/ubuntu/natty/vice/natty

« back to all changes in this revision

Viewing changes to src/arch/amigaos/joyai.c

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2010-02-11 18:30:16 UTC
  • mfrom: (1.1.8 upstream) (9.2.2 sid)
  • Revision ID: james.westby@ubuntu.com-20100211183016-f6n8usn3tzp0u6dp
Tags: 2.2.dfsg-1
* New upstream release, C64 DTV is included so update package description
  and add it to the menu.
* Drop patch fixing build failure with gcc-4.4 , applied upstream.
* Fix some lintian problems and clean up debian/rules .

Show diffs side-by-side

added added

removed removed

Lines of Context:
62
62
#define DoMethod IDoMethod
63
63
 
64
64
static const char *rawkeynames[] = {
65
 
  "~",
66
 
  "1",
67
 
  "2",
68
 
  "3",
69
 
  "4",
70
 
  "5",
71
 
  "6",
72
 
  "7",
73
 
  "8",
74
 
  "9",
75
 
  "0",
76
 
  "+",
77
 
  "=",
78
 
  "\\",
79
 
  "0x0E",
80
 
  "PAD 0",
81
 
/* 0x10 */
82
 
  "Q",
83
 
  "W",
84
 
  "E",
85
 
  "R",
86
 
  "T",
87
 
  "Y",
88
 
  "U",
89
 
  "I",
90
 
  "O",
91
 
  "P",
92
 
  ":",
93
 
  "\"",
94
 
  "0x1C",
95
 
  "PAD 1",
96
 
  "PAD 2",
97
 
  "PAD 3",
98
 
/* 0x20 */
99
 
  "A",
100
 
  "S",
101
 
  "D",
102
 
  "F",
103
 
  "G",
104
 
  "H",
105
 
  "J",
106
 
  "K",
107
 
  "L",
108
 
  "[",
109
 
  "]",
110
 
  "*",
111
 
  "0x2C",
112
 
  "PAD 4",
113
 
  "PAD 5",
114
 
  "PAD 6",
115
 
/* 0x30 */
116
 
  "<",
117
 
  "Z",
118
 
  "X",
119
 
  "C",
120
 
  "V",
121
 
  "B",
122
 
  "N",
123
 
  "M",
124
 
  ",",
125
 
  ".",
126
 
  "/",
127
 
  "0x3B",
128
 
  "PAD .",
129
 
  "PAD 7",
130
 
  "PAD 8",
131
 
  "PAD 9",
132
 
/* 0x40 */
133
 
  "SPACE",
134
 
  "BACKSPACE",
135
 
  "TAB",
136
 
  "PAD ENTER",
137
 
  "ENTER",
138
 
  "ESC",
139
 
  "DELETE",
140
 
  "INSERT", // NEW
141
 
  "PAGE UP", // NEW
142
 
  "PAGE DOWN", // NEW
143
 
  "PAD -",
144
 
  "F11", // NEW
145
 
  "UP",
146
 
  "DOWN",
147
 
  "RIGHT",
148
 
  "LEFT",
149
 
/* 0x50 */
150
 
  "F1",
151
 
  "F2",
152
 
  "F3",
153
 
  "F4",
154
 
  "F5",
155
 
  "F6",
156
 
  "F7",
157
 
  "F8",
158
 
  "F9",
159
 
  "F10",
160
 
  "PAD NUMLOCK",
161
 
  "PAD SCRLOCK",
162
 
  "PAD /",
163
 
  "PAD *",
164
 
  "PAD +",
165
 
  "HELP",
166
 
/* 0x60 */
167
 
  "LSHIFT",
168
 
  "RSHIFT",
169
 
  "CAPSLOCK",
170
 
  "CTRL", // L/R
171
 
  "LALT",
172
 
  "RALT",
173
 
  "LAMIGA",
174
 
  "RAMIGA",
175
 
  "0x68",
176
 
  "0x69",
177
 
  "0x6A",
178
 
  "MENU", // NEW
179
 
  "0x6C",
180
 
  "PRINT SCREEN", // NEW
181
 
  "PAUSE", // NEW
182
 
  "F12", // NEW
183
 
/* 0x70 */
184
 
  "HOME", // NEW
185
 
  "END", // NEW
186
 
  "STOP", // NEW
187
 
  "PLAY", // NEW
188
 
  "0x74",
189
 
  "0x75",
190
 
  "PREV", // NEW
191
 
  "NEXT", // NEW
192
 
  "0x78",
193
 
  "NUMLOCK", // NEW
194
 
  "0x7A",
195
 
  "0x7B",
196
 
  "0x7C",
197
 
  "0x7D",
198
 
  "0x7E",
199
 
  "0x7F",
 
65
    "~",
 
66
    "1",
 
67
    "2",
 
68
    "3",
 
69
    "4",
 
70
    "5",
 
71
    "6",
 
72
    "7",
 
73
    "8",
 
74
    "9",
 
75
    "0",
 
76
    "+",
 
77
    "=",
 
78
    "\\",
 
79
    "0x0E",
 
80
    "PAD 0",
 
81
    /* 0x10 */
 
82
    "Q",
 
83
    "W",
 
84
    "E",
 
85
    "R",
 
86
    "T",
 
87
    "Y",
 
88
    "U",
 
89
    "I",
 
90
    "O",
 
91
    "P",
 
92
    ":",
 
93
    "\"",
 
94
    "0x1C",
 
95
    "PAD 1",
 
96
    "PAD 2",
 
97
    "PAD 3",
 
98
    /* 0x20 */
 
99
    "A",
 
100
    "S",
 
101
    "D",
 
102
    "F",
 
103
    "G",
 
104
    "H",
 
105
    "J",
 
106
    "K",
 
107
    "L",
 
108
    "[",
 
109
    "]",
 
110
    "*",
 
111
    "0x2C",
 
112
    "PAD 4",
 
113
    "PAD 5",
 
114
    "PAD 6",
 
115
    /* 0x30 */
 
116
    "<",
 
117
    "Z",
 
118
    "X",
 
119
    "C",
 
120
    "V",
 
121
    "B",
 
122
    "N",
 
123
    "M",
 
124
    ",",
 
125
    ".",
 
126
    "/",
 
127
    "0x3B",
 
128
    "PAD .",
 
129
    "PAD 7",
 
130
    "PAD 8",
 
131
    "PAD 9",
 
132
    /* 0x40 */
 
133
    "SPACE",
 
134
    "BACKSPACE",
 
135
    "TAB",
 
136
    "PAD ENTER",
 
137
    "ENTER",
 
138
    "ESC",
 
139
    "DELETE",
 
140
    "INSERT", // NEW
 
141
    "PAGE UP", // NEW
 
142
    "PAGE DOWN", // NEW
 
143
    "PAD -",
 
144
    "F11", // NEW
 
145
    "UP",
 
146
    "DOWN",
 
147
    "RIGHT",
 
148
    "LEFT",
 
149
    /* 0x50 */
 
150
    "F1",
 
151
    "F2",
 
152
    "F3",
 
153
    "F4",
 
154
    "F5",
 
155
    "F6",
 
156
    "F7",
 
157
    "F8",
 
158
    "F9",
 
159
    "F10",
 
160
    "PAD NUMLOCK",
 
161
    "PAD SCRLOCK",
 
162
    "PAD /",
 
163
    "PAD *",
 
164
    "PAD +",
 
165
    "HELP",
 
166
    /* 0x60 */
 
167
    "LSHIFT",
 
168
    "RSHIFT",
 
169
    "CAPSLOCK",
 
170
    "CTRL", // L/R
 
171
    "LALT",
 
172
    "RALT",
 
173
    "LAMIGA",
 
174
    "RAMIGA",
 
175
    "0x68",
 
176
    "0x69",
 
177
    "0x6A",
 
178
    "MENU", // NEW
 
179
    "0x6C",
 
180
    "PRINT SCREEN", // NEW
 
181
    "PAUSE", // NEW
 
182
    "F12", // NEW
 
183
    /* 0x70 */
 
184
    "HOME", // NEW
 
185
    "END", // NEW
 
186
    "STOP", // NEW
 
187
    "PLAY", // NEW
 
188
    "0x74",
 
189
    "0x75",
 
190
    "PREV", // NEW
 
191
    "NEXT", // NEW
 
192
    "0x78",
 
193
    "NUMLOCK", // NEW
 
194
    "0x7A",
 
195
    "0x7B",
 
196
    "0x7C",
 
197
    "0x7D",
 
198
    "0x7E",
 
199
    "0x7F",
200
200
};
201
201
 
202
202
#define NUMKEYS (sizeof(rawkeynames) / sizeof(char *))
203
203
 
204
204
static const char *rawkey_to_name(unsigned long rawkey)
205
205
{
206
 
  const char *name;
207
 
  if (rawkey >= NUMKEYS) {
208
 
    name = "";
209
 
  } else {
210
 
    name = rawkeynames[rawkey];
211
 
  }
 
206
    const char *name;
 
207
    if (rawkey >= NUMKEYS) {
 
208
        name = "";
 
209
    } else {
 
210
        name = rawkeynames[rawkey];
 
211
    }
212
212
 
213
 
  return name;
 
213
    return name;
214
214
}
215
215
 
216
216
//-----------------------------------------------------------------
231
231
#define TYPE_HAT    (3)
232
232
 
233
233
typedef struct {
234
 
  char *label;
235
 
  int bitnum;
236
 
  int rawkey;
237
 
  int type;
238
 
  int offset;
239
 
  char *resource;
 
234
    char *label;
 
235
    int bitnum;
 
236
    int rawkey;
 
237
    int type;
 
238
    int offset;
 
239
    char *resource;
240
240
} keysym_type;
241
241
 
242
242
static keysym_type keysym_1[] = {
243
 
  /* Digital */
244
 
  { "Up",    DIGITAL_UP,    -1, TYPE_NONE, 0, NULL },
245
 
  { "Down",  DIGITAL_DOWN,  -1, TYPE_NONE, 0, NULL },
246
 
  { "Left",  DIGITAL_LEFT,  -1, TYPE_NONE, 0, NULL },
247
 
  { "Right", DIGITAL_RIGHT, -1, TYPE_NONE, 0, NULL },
248
 
  { "Fire",  DIGITAL_FIRE,  -1, TYPE_NONE, 0, NULL },
 
243
    /* Digital */
 
244
    { "Up", DIGITAL_UP, -1, TYPE_NONE, 0, NULL },
 
245
    { "Down", DIGITAL_DOWN, -1, TYPE_NONE, 0, NULL },
 
246
    { "Left", DIGITAL_LEFT,  -1, TYPE_NONE, 0, NULL },
 
247
    { "Right", DIGITAL_RIGHT, -1, TYPE_NONE, 0, NULL },
 
248
    { "Fire", DIGITAL_FIRE, -1, TYPE_NONE, 0, NULL },
249
249
};
250
250
 
251
251
static keysym_type keysym_2[] = {
252
 
  /* Digital */
253
 
  { "Up",    DIGITAL_UP,    -1, TYPE_NONE, 0, NULL },
254
 
  { "Down",  DIGITAL_DOWN,  -1, TYPE_NONE, 0, NULL },
255
 
  { "Left",  DIGITAL_LEFT,  -1, TYPE_NONE, 0, NULL },
256
 
  { "Right", DIGITAL_RIGHT, -1, TYPE_NONE, 0, NULL },
257
 
  { "Fire",  DIGITAL_FIRE,  -1, TYPE_NONE, 0, NULL },
 
252
    /* Digital */
 
253
    { "Up", DIGITAL_UP, -1, TYPE_NONE, 0, NULL },
 
254
    { "Down", DIGITAL_DOWN, -1, TYPE_NONE, 0, NULL },
 
255
    { "Left", DIGITAL_LEFT, -1, TYPE_NONE, 0, NULL },
 
256
    { "Right",DIGITAL_RIGHT, -1, TYPE_NONE, 0, NULL },
 
257
    { "Fire", DIGITAL_FIRE, -1, TYPE_NONE, 0, NULL },
258
258
};
259
259
 
260
 
static AIN_DeviceID joy_id[2] = { -1, -1 };
 
260
static AIN_DeviceID joy_id[2] = {-1, -1};
261
261
 
262
262
static char *joy_resource[2] = { NULL, NULL };
263
263
 
264
 
#define NUM_KEYSYM ( (sizeof(keysym_1)) / (sizeof(keysym_type)) )
 
264
#define NUM_KEYSYM ((sizeof(keysym_1)) / (sizeof(keysym_type)))
265
265
 
266
266
static AIN_DeviceID default_id = -1, default_count = 0;
267
267
 
277
277
static int set_JOYAI_resource(const char *name, void *param)
278
278
{
279
279
    char **ptr = (char **)param;
280
 
    if (*ptr != NULL && name != NULL)
281
 
        if (strcmp(name, *ptr) == 0)
 
280
    if (*ptr != NULL && name != NULL) {
 
281
        if (strcmp(name, *ptr) == 0) {
282
282
            return 0;
 
283
        }
 
284
    }
283
285
    util_string_set(ptr, name ? name : "");
284
286
    return 0;
285
287
}
286
288
 
287
 
#define MYRES(res, def, name) \
288
 
  { name, def, RES_EVENT_NO, NULL, &res, set_JOYAI_resource, (void *)&res },
 
289
#define MYRES(res, def, name) { name, def, RES_EVENT_NO, NULL, &res, set_JOYAI_resource, (void *)&res },
289
290
 
290
291
static const resource_string_t resources_string[] = {
291
292
    MYRES(joy_resource[0], "-1", "JOYAI1_ID")
310
311
 
311
312
static void get_cfg(int joy)
312
313
{
313
 
  keysym_type *keysym = (joy == 2) ? keysym_2 : keysym_1;
314
 
  char *tmp, txt[256];
315
 
  unsigned int i;
316
 
 
317
 
  sprintf(txt, "JOYAI%d_ID", joy);
318
 
  tmp = NULL;
319
 
  resources_get_value(txt, (void *)&tmp);
320
 
  if (tmp != NULL) {
321
 
    joy_id[joy-1] = atoi(tmp);
322
 
  }
323
 
 
324
 
  for (i=0; i<NUM_KEYSYM; i++) {
325
 
    sprintf(txt, "JOYAI%d_%s", joy, keysym[i].label);
 
314
    keysym_type *keysym = (joy == 2) ? keysym_2 : keysym_1;
 
315
    char *tmp, txt[256];
 
316
    unsigned int i;
 
317
 
 
318
    sprintf(txt, "JOYAI%d_ID", joy);
326
319
    tmp = NULL;
327
320
    resources_get_value(txt, (void *)&tmp);
328
321
    if (tmp != NULL) {
329
 
      sscanf(tmp, "%d,%d,%d", &keysym[i].type, &keysym[i].offset, &keysym[i].rawkey);
330
 
    }
331
 
  }
 
322
        joy_id[joy - 1] = atoi(tmp);
 
323
    }
 
324
 
 
325
    for (i = 0; i < NUM_KEYSYM; i++) {
 
326
        sprintf(txt, "JOYAI%d_%s", joy, keysym[i].label);
 
327
        tmp = NULL;
 
328
        resources_get_value(txt, (void *)&tmp);
 
329
        if (tmp != NULL) {
 
330
            sscanf(tmp, "%d,%d,%d", &keysym[i].type, &keysym[i].offset, &keysym[i].rawkey);
 
331
        }
 
332
    }
332
333
}
333
334
 
334
335
static void set_cfg(int joy)
335
336
{
336
 
  keysym_type *keysym = (joy == 2) ? keysym_2 : keysym_1;
337
 
  char tmp[256], txt[256];
338
 
  unsigned int i;
339
 
 
340
 
  sprintf(txt, "JOYAI%d_ID", joy);
341
 
  sprintf(tmp, "%lu", joy_id[joy-1]);
342
 
  resources_set_value(txt, tmp);
343
 
 
344
 
  for (i=0; i<NUM_KEYSYM; i++) {
345
 
    sprintf(txt, "JOYAI%d_%s", joy, keysym[i].label);
346
 
    sprintf(tmp, "%d,%d,%d", keysym[i].type,keysym[i].offset,keysym[i].rawkey);
 
337
    keysym_type *keysym = (joy == 2) ? keysym_2 : keysym_1;
 
338
    char tmp[256], txt[256];
 
339
    unsigned int i;
 
340
 
 
341
    sprintf(txt, "JOYAI%d_ID", joy);
 
342
    sprintf(tmp, "%lu", joy_id[joy - 1]);
347
343
    resources_set_value(txt, tmp);
348
 
  }
 
344
 
 
345
    for (i = 0; i < NUM_KEYSYM; i++) {
 
346
        sprintf(txt, "JOYAI%d_%s", joy, keysym[i].label);
 
347
        sprintf(tmp, "%d,%d,%d", keysym[i].type,keysym[i].offset,keysym[i].rawkey);
 
348
        resources_set_value(txt, tmp);
 
349
    }
349
350
}
350
351
 
351
352
static void ai_exit(void)
352
353
{
353
 
  if (CTX != NULL) {
354
 
    AIN_DeleteContext(CTX);
355
 
    CTX = NULL;
356
 
  }
357
 
  if (ai_port != NULL) {
358
 
    DeleteMsgPort(ai_port);
359
 
    ai_port = NULL;
360
 
  }
361
 
  if (IAIN) {
362
 
    DropInterface((struct Interface *)IAIN);
363
 
    IAIN = NULL;
364
 
  }
365
 
  if (AIN_Base) {
366
 
    CloseLibrary(AIN_Base);
367
 
    AIN_Base = NULL;
368
 
  }
 
354
    if (CTX != NULL) {
 
355
        AIN_DeleteContext(CTX);
 
356
        CTX = NULL;
 
357
    }
 
358
    if (ai_port != NULL) {
 
359
        DeleteMsgPort(ai_port);
 
360
        ai_port = NULL;
 
361
    }
 
362
    if (IAIN) {
 
363
        DropInterface((struct Interface *)IAIN);
 
364
        IAIN = NULL;
 
365
    }
 
366
    if (AIN_Base) {
 
367
        CloseLibrary(AIN_Base);
 
368
        AIN_Base = NULL;
 
369
    }
369
370
}
370
371
 
371
372
static int ai_init(void)
372
373
{
373
 
  if ((AIN_Base = OpenLibrary("AmigaInput.library", 51))) {
374
 
    if ((IAIN = (struct AIN_IFace *)GetInterface(AIN_Base, "main", 1, NULL))) {
375
 
      if ((ai_port = CreateMsgPort())) {
376
 
        struct TagItem tags[] = { { AINCC_Port, (ULONG)ai_port }, { TAG_DONE, TAG_DONE } };
377
 
        CTX = AIN_CreateContext(1, tags);
378
 
        if (CTX != NULL) {
379
 
          return 0;
 
374
    if ((AIN_Base = OpenLibrary("AmigaInput.library", 51))) {
 
375
        if ((IAIN = (struct AIN_IFace *)GetInterface(AIN_Base, "main", 1, NULL))) {
 
376
            if ((ai_port = CreateMsgPort())) {
 
377
                struct TagItem tags[] = { { AINCC_Port, (ULONG)ai_port}, { TAG_DONE, TAG_DONE } };
 
378
 
 
379
                CTX = AIN_CreateContext(1, tags);
 
380
                if (CTX != NULL) {
 
381
                    return 0;
 
382
                }
 
383
            }
380
384
        }
381
 
      }
382
385
    }
383
 
  }
384
 
 
385
 
  ai_exit();
386
 
 
387
 
  return -1;
 
386
 
 
387
    ai_exit();
 
388
 
 
389
    return -1;
388
390
}
389
391
 
390
392
static void ai_release(void)
391
393
{
392
 
  int i;
393
 
  for (i=0; i<2; i++) {
394
 
    if ((CTX != NULL) && (ai_handle[i] != NULL)) {
395
 
      AIN_ReleaseDevice(CTX, ai_handle[i]);
396
 
      ai_handle[i] = NULL;
 
394
    int i;
 
395
 
 
396
    for (i = 0; i < 2; i++) {
 
397
        if ((CTX != NULL) && (ai_handle[i] != NULL)) {
 
398
            AIN_ReleaseDevice(CTX, ai_handle[i]);
 
399
            ai_handle[i] = NULL;
 
400
        }
397
401
    }
398
 
  }
399
402
}
400
403
 
401
404
static void ai_attach(void)
402
405
{
403
 
  unsigned int i;
404
 
  for (i=0; i<2; i++) {
405
 
    get_cfg(i+1);
406
 
    if ((CTX != NULL) && (joy_id[i] != -1)) {
407
 
      ai_handle[i] = AIN_ObtainDevice(CTX, joy_id[i]);
 
406
    unsigned int i;
 
407
 
 
408
    for (i = 0; i < 2; i++) {
 
409
        get_cfg(i + 1);
 
410
        if ((CTX != NULL) && (joy_id[i] != -1)) {
 
411
            ai_handle[i] = AIN_ObtainDevice(CTX, joy_id[i]);
 
412
        }
408
413
    }
409
 
  }
410
414
}
411
415
 
412
416
void joyai_close(void)
413
417
{
414
 
  ai_release();
415
 
  ai_exit();
 
418
    ai_release();
 
419
    ai_exit();
416
420
}
417
421
 
418
422
int joyai_open(void)
419
423
{
420
 
  if (ai_init() == -1) {
421
 
    return -1;
422
 
  }
423
 
 
424
 
  ai_attach();
425
 
 
426
 
  return 0;
 
424
    if (ai_init() == -1) {
 
425
        return -1;
 
426
    }
 
427
 
 
428
    ai_attach();
 
429
 
 
430
    return 0;
427
431
}
428
432
 
429
433
static int get_key(AIN_DeviceID ID, int *keycode, int *offset)
430
434
{
431
 
  static char *window_text;
432
 
  struct Window *window;
433
 
  AIN_InputEvent *event;
434
 
  int done = 0;
435
 
 
436
 
  window_text = translate_text(IDS_PRESS_KEY_BUTTON);
437
 
  *keycode = *offset = -1; /* no key */
438
 
 
439
 
  if (ID != -1) {
440
 
    ai_handle[0] = AIN_ObtainDevice(CTX, ID);
 
435
    static char *window_text;
 
436
    struct Window *window;
 
437
    AIN_InputEvent *event;
 
438
    int done = 0;
 
439
 
 
440
    window_text = translate_text(IDS_PRESS_KEY_BUTTON);
 
441
    *keycode = *offset = -1; /* no key */
 
442
 
 
443
    if (ID != -1) {
 
444
        ai_handle[0] = AIN_ObtainDevice(CTX, ID);
 
445
        if (ai_handle[0] != NULL) {
 
446
            AIN_SetDeviceParameter(CTX, ai_handle[0], AINDP_EVENT, TRUE);
 
447
        }
 
448
    }
 
449
 
 
450
    window = OpenWindowTags(NULL,
 
451
                            WA_Title, (ULONG)"",
 
452
                            WA_Flags, WFLG_NOCAREREFRESH|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_RMBTRAP|WFLG_GIMMEZEROZERO,
 
453
                            WA_IDCMP, IDCMP_CLOSEWINDOW|WFLG_REPORTMOUSE|IDCMP_RAWKEY|IDCMP_CHANGEWINDOW,
 
454
                            WA_Left, 100,
 
455
                            WA_Top, 100,
 
456
                            WA_Width, 100,
 
457
                            WA_Height, 40,
 
458
                            WA_Activate, TRUE,
 
459
                            TAG_DONE);
 
460
 
 
461
    if (window != NULL) {
 
462
        struct IntuiMessage *imsg = NULL;
 
463
        ULONG imCode, imClass;
 
464
 
 
465
        /* Resize window and set pens */
 
466
        int length = TextLength(window->RPort, window_text, strlen(window_text));
 
467
 
 
468
        ChangeWindowBox(window, 100, 100, window->BorderLeft+length+window->BorderRight+8, window->BorderTop+window->IFont->tf_YSize*2+window->BorderBottom);
 
469
        SetAPen(window->RPort, 1);
 
470
        SetBPen(window->RPort, 0);
 
471
 
 
472
        /* Wait until window has been resized */
 
473
        while (done == 0) {
 
474
            /* Wait for messages */
 
475
            Wait((1L << window->UserPort->mp_SigBit) | (1L << ai_port->mp_SigBit));
 
476
 
 
477
            /* Check for IDCMP messages */
 
478
            while ((imsg = (struct IntuiMessage *)GetMsg(window->UserPort))) {
 
479
                imClass = imsg->Class;
 
480
                imCode = imsg->Code;
 
481
 
 
482
                ReplyMsg((struct Message *)imsg);
 
483
 
 
484
                if (imClass == IDCMP_CHANGEWINDOW) {
 
485
                    Move(window->RPort, 4, window->IFont->tf_YSize);
 
486
                    Text(window->RPort, window_text, strlen(window_text));
 
487
                } else if (imClass == IDCMP_RAWKEY) {
 
488
                    imCode &= 0x7f;
 
489
                    if (imCode != 69) {
 
490
                        *keycode = imCode;
 
491
                    }
 
492
                    done = 1; /* KEY ok */
 
493
                } else if (imClass == IDCMP_CLOSEWINDOW) {
 
494
                    done = -1; /* cancel */
 
495
                }
 
496
            }
 
497
 
 
498
            /* Check for AI messages */
 
499
            if (ai_handle[0] != NULL) {
 
500
                while ((event = AIN_GetEvent(CTX))) {
 
501
                    switch(event->Type) {
 
502
                        case AINET_AXIS:
 
503
                            if ((event->Value >= (ONOFF_VALUE)) || (event->Value <= (-(ONOFF_VALUE)))) {
 
504
                                *offset = event->Index;
 
505
                                done = 2; /* AI ok */
 
506
                            }
 
507
                            break;
 
508
                        case AINET_BUTTON:
 
509
                            *offset = event->Index;
 
510
                            done = 2; /* AI ok */
 
511
                            break;
 
512
                        case AINET_HAT:
 
513
                            *offset = event->Index;
 
514
                            done = 2; /* AI ok */
 
515
                            break;
 
516
                        default:
 
517
                            break;
 
518
                    }
 
519
 
 
520
                    AIN_FreeEvent(CTX, event);
 
521
                }
 
522
            }
 
523
        }
 
524
        CloseWindow(window);
 
525
    }
 
526
 
441
527
    if (ai_handle[0] != NULL) {
442
 
      AIN_SetDeviceParameter(CTX, ai_handle[0], AINDP_EVENT, TRUE);
443
 
    }
444
 
  }
445
 
 
446
 
  window = OpenWindowTags(NULL,
447
 
                          WA_Title, (ULONG)"",
448
 
                          WA_Flags, WFLG_NOCAREREFRESH|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_RMBTRAP|WFLG_GIMMEZEROZERO,
449
 
                          WA_IDCMP, IDCMP_CLOSEWINDOW|WFLG_REPORTMOUSE|IDCMP_RAWKEY|IDCMP_CHANGEWINDOW,
450
 
                          WA_Left, 100,
451
 
                          WA_Top, 100,
452
 
                          WA_Width, 100,
453
 
                          WA_Height, 40,
454
 
                          WA_Activate, TRUE,
455
 
                          TAG_DONE);
456
 
 
457
 
  if (window != NULL) {
458
 
    struct IntuiMessage *imsg = NULL;
459
 
    ULONG imCode, imClass;
460
 
 
461
 
    /* Resize window and set pens */
462
 
    int length = TextLength(window->RPort, window_text, strlen(window_text));
463
 
    ChangeWindowBox(window, 100, 100, window->BorderLeft+length+window->BorderRight+8, window->BorderTop+window->IFont->tf_YSize*2+window->BorderBottom);
464
 
    SetAPen(window->RPort, 1);
465
 
    SetBPen(window->RPort, 0);
466
 
 
467
 
    /* Wait until window has been resized */
468
 
    while (done == 0) {
469
 
      /* Wait for messages */
470
 
      Wait((1L << window->UserPort->mp_SigBit) | (1L << ai_port->mp_SigBit));
471
 
 
472
 
      /* Check for IDCMP messages */
473
 
      while ((imsg = (struct IntuiMessage *)GetMsg(window->UserPort))) {
474
 
        imClass = imsg->Class;
475
 
        imCode = imsg->Code;
476
 
 
477
 
        ReplyMsg((struct Message *)imsg);
478
 
 
479
 
        if (imClass == IDCMP_CHANGEWINDOW) {
480
 
          Move(window->RPort, 4, window->IFont->tf_YSize);
481
 
          Text(window->RPort, window_text, strlen(window_text));
482
 
        }
483
 
        else if (imClass == IDCMP_RAWKEY) {
484
 
          imCode &= 0x7f;
485
 
          if (imCode != 69) {
486
 
            *keycode = imCode;
487
 
          }
488
 
          done = 1; /* KEY ok */
489
 
        }
490
 
        else if (imClass == IDCMP_CLOSEWINDOW) {
491
 
          done = -1; /* cancel */
492
 
        }
493
 
      }
494
 
 
495
 
      /* Check for AI messages */
496
 
      if (ai_handle[0] != NULL) {
 
528
        AIN_SetDeviceParameter(CTX, ai_handle[0], AINDP_EVENT, FALSE);
 
529
        /* Remove pending AI messages */
497
530
        while ((event = AIN_GetEvent(CTX))) {
498
 
          switch(event->Type) {
499
 
            case AINET_AXIS:
500
 
              if ((event->Value >= (ONOFF_VALUE)) || (event->Value <= (-(ONOFF_VALUE)))) {
501
 
                *offset = event->Index;
502
 
                done = 2; /* AI ok */
503
 
              }
504
 
              break;
505
 
 
506
 
            case AINET_BUTTON:
507
 
              *offset = event->Index;
508
 
              done = 2; /* AI ok */
509
 
              break;
510
 
 
511
 
            case AINET_HAT:
512
 
              *offset = event->Index;
513
 
              done = 2; /* AI ok */
514
 
              break;
515
 
 
516
 
            default:
517
 
              break;
518
 
          }
519
 
 
520
 
          AIN_FreeEvent(CTX, event);
 
531
            AIN_FreeEvent(CTX, event);
521
532
        }
522
 
      }
523
 
    }
524
 
    CloseWindow(window);
525
 
  }
526
 
 
527
 
  if (ai_handle[0] != NULL) {
528
 
    AIN_SetDeviceParameter(CTX, ai_handle[0], AINDP_EVENT, FALSE);
529
 
    /* Remove pending AI messages */
530
 
    while ((event = AIN_GetEvent(CTX))) {
531
 
      AIN_FreeEvent(CTX, event);
532
 
    }
533
 
    AIN_ReleaseDevice(CTX, ai_handle[0]);
534
 
    ai_handle[0] = NULL;
535
 
  }
536
 
 
537
 
  return done;
 
533
        AIN_ReleaseDevice(CTX, ai_handle[0]);
 
534
        ai_handle[0] = NULL;
 
535
    }
 
536
 
 
537
    return done;
538
538
}
539
539
 
540
540
static struct {
541
 
  ULONG count;
542
 
  AIN_DeviceID ids[256];
543
 
  char *names[256];
 
541
    ULONG count;
 
542
    AIN_DeviceID ids[256];
 
543
    char *names[256];
544
544
} devices;
545
545
 
546
546
static struct {
547
 
  ULONG count;
548
 
  int offsets[256];
549
 
  char *names[256];
550
 
  int types[256];
 
547
    ULONG count;
 
548
    int offsets[256];
 
549
    char *names[256];
 
550
    int types[256];
551
551
} inputs;
552
552
 
553
553
static void update_inputs(ULONG ID)
554
554
{
555
 
  char name[256];
556
 
  unsigned int i;
557
 
  int num, offset;
558
 
 
559
 
  for (i=0; i<inputs.count; i++) {
560
 
    if (inputs.names[i] != NULL) {
561
 
      lib_free(inputs.names[i]);
562
 
    }
563
 
  }
564
 
  memset(&inputs, 0, sizeof(inputs));
565
 
 
566
 
  inputs.offsets[0] = 0;
567
 
  inputs.names[0] = lib_stralloc("-");
568
 
  inputs.types[0] = TYPE_NONE;
569
 
  inputs.count++;
570
 
 
571
 
  if (ID == -1) {
572
 
    return;
573
 
  }
574
 
 
575
 
  /* BUTTON */
576
 
  AIN_Query(CTX, ID, AINQ_NUMBUTTONS, 0, &num, sizeof(num));
577
 
  AIN_Query(CTX, ID, AINQ_BUTTON_OFFSET, 0, &offset, sizeof(offset));
578
 
  for (i=0; i<num; i++) {
579
 
    name[0] = '\0';
580
 
    AIN_Query(CTX, ID, AINQ_BUTTONNAME, i, name, sizeof(name));
581
 
    if (name[0] != '\0') {
582
 
      inputs.offsets[inputs.count] = offset + i;
583
 
      inputs.names[inputs.count] = lib_stralloc(name);
584
 
      inputs.types[inputs.count] = TYPE_BUTTON;
585
 
      inputs.count++;
586
 
    }
587
 
  }
588
 
 
589
 
  /* AXES */
590
 
  AIN_Query(CTX, ID, AINQ_NUMAXES, 0, &num, sizeof(num));
591
 
  AIN_Query(CTX, ID, AINQ_AXIS_OFFSET, 0, &offset, sizeof(offset));
592
 
  for (i=0; i<num; i++) {
593
 
    name[0] = '\0';
594
 
    AIN_Query(CTX, ID, AINQ_AXISNAME, i, name, sizeof(name));
595
 
    if (name[0] != '\0') {
596
 
      inputs.offsets[inputs.count] = offset + i;
597
 
      inputs.names[inputs.count] = lib_stralloc(name);
598
 
      inputs.types[inputs.count] = TYPE_AXES;
599
 
      inputs.count++;
600
 
    }
601
 
  }
602
 
 
603
 
  /* HATS */
604
 
  AIN_Query(CTX, ID, AINQ_NUMHATS, 0, &num, sizeof(num));
605
 
  AIN_Query(CTX, ID, AINQ_HAT_OFFSET, 0, &offset, sizeof(offset));
606
 
  for (i=0; i<num; i++) {
607
 
    name[0] = '\0';
608
 
    AIN_Query(CTX, ID, AINQ_HATNAME, i, name, sizeof(name));
609
 
    if (name[0] != '\0') {
610
 
      inputs.offsets[inputs.count] = offset + i;
611
 
      inputs.names[inputs.count] = lib_stralloc(name);
612
 
      inputs.types[inputs.count] = TYPE_HAT;
613
 
      inputs.count++;
614
 
    }
615
 
  }
 
555
    char name[256];
 
556
    unsigned int i;
 
557
    int num, offset;
 
558
 
 
559
    for (i = 0; i < inputs.count; i++) {
 
560
        lib_free(inputs.names[i]);
 
561
    }
 
562
    memset(&inputs, 0, sizeof(inputs));
 
563
 
 
564
    inputs.offsets[0] = 0;
 
565
    inputs.names[0] = lib_stralloc("-");
 
566
    inputs.types[0] = TYPE_NONE;
 
567
    inputs.count++;
 
568
 
 
569
    if (ID == -1) {
 
570
        return;
 
571
    }
 
572
 
 
573
    /* BUTTON */
 
574
    AIN_Query(CTX, ID, AINQ_NUMBUTTONS, 0, &num, sizeof(num));
 
575
    AIN_Query(CTX, ID, AINQ_BUTTON_OFFSET, 0, &offset, sizeof(offset));
 
576
    for (i = 0; i < num; i++) {
 
577
        name[0] = '\0';
 
578
        AIN_Query(CTX, ID, AINQ_BUTTONNAME, i, name, sizeof(name));
 
579
        if (name[0] != '\0') {
 
580
            inputs.offsets[inputs.count] = offset + i;
 
581
            inputs.names[inputs.count] = lib_stralloc(name);
 
582
            inputs.types[inputs.count] = TYPE_BUTTON;
 
583
            inputs.count++;
 
584
        }
 
585
    }
 
586
 
 
587
    /* AXES */
 
588
    AIN_Query(CTX, ID, AINQ_NUMAXES, 0, &num, sizeof(num));
 
589
    AIN_Query(CTX, ID, AINQ_AXIS_OFFSET, 0, &offset, sizeof(offset));
 
590
    for (i = 0; i < num; i++) {
 
591
        name[0] = '\0';
 
592
        AIN_Query(CTX, ID, AINQ_AXISNAME, i, name, sizeof(name));
 
593
        if (name[0] != '\0') {
 
594
            inputs.offsets[inputs.count] = offset + i;
 
595
            inputs.names[inputs.count] = lib_stralloc(name);
 
596
            inputs.types[inputs.count] = TYPE_AXES;
 
597
            inputs.count++;
 
598
        }
 
599
    }
 
600
 
 
601
    /* HATS */
 
602
    AIN_Query(CTX, ID, AINQ_NUMHATS, 0, &num, sizeof(num));
 
603
    AIN_Query(CTX, ID, AINQ_HAT_OFFSET, 0, &offset, sizeof(offset));
 
604
    for (i = 0; i < num; i++) {
 
605
        name[0] = '\0';
 
606
        AIN_Query(CTX, ID, AINQ_HATNAME, i, name, sizeof(name));
 
607
        if (name[0] != '\0') {
 
608
            inputs.offsets[inputs.count] = offset + i;
 
609
            inputs.names[inputs.count] = lib_stralloc(name);
 
610
            inputs.types[inputs.count] = TYPE_HAT;
 
611
            inputs.count++;
 
612
        }
 
613
    }
616
614
}
617
615
 
618
616
static int offset_to_index(int offset)
619
617
{
620
 
  unsigned int i;
 
618
    unsigned int i;
621
619
 
622
 
  for (i=0; i<inputs.count; i++) {
623
 
    if ((inputs.types[i] != TYPE_NONE) && (inputs.offsets[i] == offset)) {
624
 
      return i;
 
620
    for (i = 0; i < inputs.count; i++) {
 
621
        if ((inputs.types[i] != TYPE_NONE) && (inputs.offsets[i] == offset)) {
 
622
            return i;
 
623
        }
625
624
    }
626
 
  }
627
 
  return -1;
 
625
    return -1;
628
626
}
629
627
 
630
628
BOOL enumfunc(AIN_Device *device, void *UserData)
631
629
{
632
 
  devices.ids[devices.count] = device->DeviceID;
633
 
  devices.names[devices.count] = lib_stralloc(device->DeviceName);
 
630
    devices.ids[devices.count] = device->DeviceID;
 
631
    devices.names[devices.count] = lib_stralloc(device->DeviceName);
634
632
 
635
 
  if (default_id != -1) {
636
 
    if (default_id == device->DeviceID) {
637
 
      default_count = devices.count;
 
633
    if (default_id != -1) {
 
634
        if (default_id == device->DeviceID) {
 
635
            default_count = devices.count;
 
636
        }
638
637
    }
639
 
  }
640
 
 
641
 
  devices.count++;
642
 
 
643
 
  return FALSE;
 
638
 
 
639
    devices.count++;
 
640
 
 
641
    return FALSE;
644
642
}
645
643
 
646
644
static int offset_to_active(int type, int offset)
647
645
{
648
 
  unsigned int i;
 
646
    unsigned int i;
649
647
 
650
 
  for (i=0; i<inputs.count; i++) {
651
 
    if ((inputs.types[i] == type) && (inputs.offsets[i] == offset)) {
652
 
      return i;
 
648
    for (i = 0; i < inputs.count; i++) {
 
649
        if ((inputs.types[i] == type) && (inputs.offsets[i] == offset)) {
 
650
            return i;
 
651
        }
653
652
    }
654
 
  }
655
 
  return 0;
 
653
    return 0;
656
654
}
657
655
 
 
656
#define BTN_OK (32)
 
657
#define DEV_CHANGE (33)
 
658
#define KEYNAME "VICE"
 
659
 
658
660
int joyai_config(int joy)
659
661
{
660
 
  BOOL running = TRUE;
661
 
  keysym_type *keysym = (joy == 2) ? keysym_2 : keysym_1;
662
 
  ULONG signals;
663
 
 
664
 
  if (CTX == NULL) {
665
 
    return -1;
666
 
  }
667
 
 
668
 
  get_cfg(joy);
669
 
  ai_release();
670
 
 
671
 
  #define BTN_OK (32)
672
 
  #define DEV_CHANGE (33)
673
 
  #define KEYNAME "VICE"
674
 
 
675
 
  memset(&devices, 0, sizeof(devices));
676
 
  memset(&inputs, 0, sizeof(inputs));
677
 
 
678
 
  if (joy_id[joy-1] != -1) {
679
 
    ai_handle[0] = AIN_ObtainDevice(CTX, joy_id[joy-1]);
680
 
    if (ai_handle[0] != NULL) {
681
 
      AIN_ReleaseDevice(CTX, ai_handle[0]);
682
 
      ai_handle[0] = NULL;
683
 
    } else {
684
 
      joy_id[joy-1] = -1;
685
 
    }
686
 
  }
687
 
 
688
 
  devices.ids[devices.count] = -1;
689
 
  devices.names[devices.count] = lib_stralloc("-");
690
 
  devices.count++;
691
 
 
692
 
  default_id = joy_id[joy-1];
693
 
  default_count = 0;
694
 
 
695
 
  AIN_EnumDevices(CTX, enumfunc, &devices);
696
 
 
697
 
  update_inputs(joy_id[joy-1]);
698
 
 
699
 
{
700
 
    APTR label, text[NUM_KEYSYM], button, app, main_group, window, ok, cancel, Odevice, Oinput[NUM_KEYSYM];
701
 
 
702
 
        app = ApplicationObject,
703
 
        MUIA_Application_Author, "Mathias Roslund",
704
 
        MUIA_Application_Base, KEYNAME,
705
 
        MUIA_Application_Title, KEYNAME,
706
 
        MUIA_Application_Version, "$VER: " KEYNAME " v1.0",
707
 
        MUIA_Application_Copyright, "Mathias Roslund",
708
 
        MUIA_Application_Description, KEYNAME,
709
 
        SubWindow, window = WindowObject,
710
 
        MUIA_Window_Title, KEYNAME,
711
 
        MUIA_Window_ID, MAKE_ID('0', 'W', 'I', 'N'),
712
 
    MUIA_Window_Screen, canvaslist->os->screen,
713
 
        WindowContents, VGroup,
714
 
 
715
 
Child, HGroup,
716
 
     Child, TextObject,
717
 
          MUIA_Text_PreParse, "\033r",
718
 
          MUIA_Text_Contents, "AI Device",
719
 
          MUIA_Weight, 0,
720
 
          MUIA_InnerLeft, 0,
721
 
          MUIA_InnerRight, 0,
722
 
     End,
723
 
 
724
 
     Child, Odevice = CycleObject,
725
 
          MUIA_Cycle_Entries, devices.names,
726
 
        MUIA_Cycle_Active, default_count,
727
 
     End,
728
 
End,
729
 
 
730
 
        Child, main_group = ColGroup(4), End,
731
 
        Child, HGroup,
732
 
        Child, ok = TextObject,
733
 
        ButtonFrame,
734
 
        MUIA_Background, MUII_ButtonBack,
735
 
        MUIA_Text_Contents, "Ok",
736
 
        MUIA_Text_PreParse, "\033c",
737
 
        MUIA_InputMode, MUIV_InputMode_RelVerify,
738
 
        End,
739
 
        Child, cancel = TextObject,
740
 
        ButtonFrame,
741
 
        MUIA_Background, MUII_ButtonBack,
742
 
        MUIA_Text_Contents, "Cancel",
743
 
        MUIA_Text_PreParse, "\033c",
744
 
        MUIA_InputMode, MUIV_InputMode_RelVerify,
745
 
        End,
746
 
 
747
 
        End,
748
 
        End,
749
 
        End,
750
 
         End;
751
 
 
752
 
      if (app) {
753
 
        unsigned int i;
754
 
 
755
 
        DoMethod(window,
756
 
        MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
757
 
        app,
758
 
        2,
759
 
        MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit
760
 
        );
761
 
 
762
 
        DoMethod(Odevice,
763
 
        MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
764
 
        app,
765
 
        2,
766
 
        MUIM_Application_ReturnID, DEV_CHANGE
767
 
        );
768
 
 
769
 
        DoMethod(cancel,
770
 
        MUIM_Notify, MUIA_Pressed, FALSE,
771
 
        app,
772
 
        2,
773
 
        MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit
774
 
        );
775
 
 
776
 
        DoMethod(ok,
777
 
        MUIM_Notify, MUIA_Pressed, FALSE,
778
 
        app,
779
 
        2,
780
 
        MUIM_Application_ReturnID, BTN_OK
781
 
        );
782
 
 
783
 
      for (i=0; i<NUM_KEYSYM; i++) {
784
 
 
785
 
/* label */
786
 
        label = TextObject,
787
 
        MUIA_Text_PreParse, "\033r",
788
 
        MUIA_Text_Contents, keysym[i].label,
789
 
        MUIA_InnerLeft, 0,
790
 
        MUIA_InnerRight, 0,
791
 
        End;
792
 
 
793
 
        Oinput[i] = CycleObject,
794
 
        MUIA_Cycle_Entries, inputs.names,
795
 
        MUIA_Cycle_Active, offset_to_active(keysym[i].type, keysym[i].offset),
796
 
        End,
797
 
 
798
 
        text[i] = TextObject,
799
 
        MUIA_Background, MUII_TextBack,
800
 
        MUIA_Frame, MUIV_Frame_Text,
801
 
        MUIA_Text_Contents, rawkey_to_name(keysym[i].rawkey),
802
 
        End;
803
 
 
804
 
        button = TextObject,
805
 
        ButtonFrame,
806
 
        MUIA_Background, MUII_ButtonBack,
807
 
        MUIA_Text_Contents, "Change",
808
 
        MUIA_Text_PreParse, "\033c",
809
 
        MUIA_InputMode, MUIV_InputMode_RelVerify,
810
 
        End;
811
 
 
812
 
        DoMethod(button,
813
 
        MUIM_Notify, MUIA_Pressed, FALSE,
814
 
        app,
815
 
        2,
816
 
        MUIM_Application_ReturnID, (i + 1)
817
 
        );
818
 
 
819
 
/* add to window */
820
 
 
821
 
        DoMethod(main_group, OM_ADDMEMBER, label);
822
 
        DoMethod(main_group, OM_ADDMEMBER, Oinput[i]);
823
 
        DoMethod(main_group, OM_ADDMEMBER, text[i]);
824
 
        DoMethod(main_group, OM_ADDMEMBER, button);
825
 
 
826
 
        }
827
 
       }
828
 
 
829
 
      if (app) {
830
 
        unsigned int i;
831
 
        set(window, MUIA_Window_Open, TRUE);
832
 
        while (running) {
833
 
          unsigned long retval = DoMethod(app, MUIM_Application_Input, &signals);
834
 
          switch (retval) {
835
 
            case MUIV_Application_ReturnID_Quit:
836
 
              running = FALSE;
837
 
              break;
838
 
 
839
 
            case BTN_OK:
840
 
              for (i=0; i<NUM_KEYSYM; i++) {
841
 
                ULONG active;
842
 
                get(Oinput[i], MUIA_Cycle_Active, &active);
843
 
                keysym[i].type = inputs.types[active];
844
 
                keysym[i].offset = inputs.offsets[active];
845
 
              }
846
 
              set_cfg(joy);
847
 
              running = FALSE;
848
 
              break;
849
 
 
850
 
            case DEV_CHANGE: {
851
 
                ULONG active;
852
 
                get(Odevice, MUIA_Cycle_Active, &active);
853
 
                joy_id[joy-1] = devices.ids[active];
854
 
                update_inputs(joy_id[joy-1]);
855
 
                for (i=0; i<NUM_KEYSYM; i++) {
856
 
                  set(Oinput[i], MUIA_Cycle_Entries, inputs.names);
857
 
                  set(Oinput[i], MUIA_Cycle_Active, 0);
858
 
                }
859
 
              } break;
860
 
 
861
 
            default:
862
 
              if ((retval >= 1) && (retval <= (1+NUM_KEYSYM))) {
863
 
                int keycode, index, result;
864
 
                result = get_key(joy_id[joy-1], &keycode, &index);
865
 
                if (result == 1) { /* KEY */
866
 
                  keysym[retval - 1].rawkey = keycode;
867
 
                  set(text[retval - 1], MUIA_Text_Contents, rawkey_to_name(keycode));
868
 
                } else if (result == 2) { /* AI */
869
 
                  index = offset_to_index(index);
870
 
                  if (index >= 0) {
871
 
                    set(Oinput[retval - 1], MUIA_Cycle_Active, index);
872
 
                  }
873
 
                }
874
 
              }
875
 
              break;
876
 
          }
877
 
          if (running && signals) {
878
 
            Wait(signals);
879
 
          }
880
 
        }
881
 
        MUI_DisposeObject(app);
882
 
      }  
883
 
}
884
 
 
885
 
  #undef DEV_CHANGE
886
 
  #undef BTN_OK
887
 
 
888
 
  ai_attach();
889
 
 
890
 
  return 0;
 
662
    BOOL running = TRUE;
 
663
    keysym_type *keysym = (joy == 2) ? keysym_2 : keysym_1;
 
664
    ULONG signals;
 
665
 
 
666
    if (CTX == NULL) {
 
667
        return -1;
 
668
    }
 
669
 
 
670
    get_cfg(joy);
 
671
    ai_release();
 
672
 
 
673
    memset(&devices, 0, sizeof(devices));
 
674
    memset(&inputs, 0, sizeof(inputs));
 
675
 
 
676
    if (joy_id[joy - 1] != -1) {
 
677
        ai_handle[0] = AIN_ObtainDevice(CTX, joy_id[joy - 1]);
 
678
        if (ai_handle[0] != NULL) {
 
679
            AIN_ReleaseDevice(CTX, ai_handle[0]);
 
680
            ai_handle[0] = NULL;
 
681
        } else {
 
682
            joy_id[joy - 1] = -1;
 
683
        }
 
684
    }
 
685
 
 
686
    devices.ids[devices.count] = -1;
 
687
    devices.names[devices.count] = lib_stralloc("-");
 
688
    devices.count++;
 
689
 
 
690
    default_id = joy_id[joy - 1];
 
691
    default_count = 0;
 
692
 
 
693
    AIN_EnumDevices(CTX, enumfunc, &devices);
 
694
 
 
695
    update_inputs(joy_id[joy - 1]);
 
696
 
 
697
    {
 
698
        APTR label, text[NUM_KEYSYM], button, app, main_group, window, ok, cancel, Odevice, Oinput[NUM_KEYSYM];
 
699
 
 
700
        app = ApplicationObject,
 
701
                MUIA_Application_Author, "Mathias Roslund & Marco van den Heuvel",
 
702
                MUIA_Application_Base, KEYNAME,
 
703
                MUIA_Application_Title, KEYNAME,
 
704
                MUIA_Application_Version, "$VER: " KEYNAME " v1.0",
 
705
                MUIA_Application_Copyright, "Mathias Roslund & Marco van den Heuvel",
 
706
                MUIA_Application_Description, KEYNAME,
 
707
                SubWindow, window = WindowObject,
 
708
                MUIA_Window_Title, KEYNAME,
 
709
                MUIA_Window_ID, MAKE_ID('0', 'W', 'I', 'N'),
 
710
                MUIA_Window_Screen, canvaslist->os->screen,
 
711
                WindowContents, VGroup,
 
712
                Child, HGroup,
 
713
                Child, TextObject,
 
714
                MUIA_Text_PreParse, "\033r",
 
715
                MUIA_Text_Contents, "AI Device",
 
716
                MUIA_Weight, 0,
 
717
                MUIA_InnerLeft, 0,
 
718
                MUIA_InnerRight, 0,
 
719
                End,
 
720
                Child, Odevice = CycleObject,
 
721
                MUIA_Cycle_Entries, devices.names,
 
722
                  MUIA_Cycle_Active, default_count,
 
723
                End,
 
724
                End,
 
725
                Child, main_group = ColGroup(4),
 
726
                End,
 
727
                Child, HGroup,
 
728
                Child, ok = TextObject,
 
729
                ButtonFrame,
 
730
                MUIA_Background, MUII_ButtonBack,
 
731
                MUIA_Text_Contents, "Ok",
 
732
                MUIA_Text_PreParse, "\033c",
 
733
                MUIA_InputMode, MUIV_InputMode_RelVerify,
 
734
                End,
 
735
                Child, cancel = TextObject,
 
736
                ButtonFrame,
 
737
                MUIA_Background, MUII_ButtonBack,
 
738
                MUIA_Text_Contents, "Cancel",
 
739
                MUIA_Text_PreParse, "\033c",
 
740
                MUIA_InputMode, MUIV_InputMode_RelVerify,
 
741
                End,
 
742
                End,
 
743
                End,
 
744
                End,
 
745
                End;
 
746
 
 
747
        if (app) {
 
748
            unsigned int i;
 
749
 
 
750
            DoMethod(window, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
 
751
                     app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
 
752
 
 
753
            DoMethod(Odevice, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
 
754
                     app, 2, MUIM_Application_ReturnID, DEV_CHANGE);
 
755
 
 
756
            DoMethod(cancel, MUIM_Notify, MUIA_Pressed, FALSE,
 
757
                     app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
 
758
 
 
759
            DoMethod(ok, MUIM_Notify, MUIA_Pressed, FALSE,
 
760
                     app, 2, MUIM_Application_ReturnID, BTN_OK);
 
761
 
 
762
            for (i = 0; i < NUM_KEYSYM; i++) {
 
763
 
 
764
                /* label */
 
765
                label = TextObject,
 
766
                          MUIA_Text_PreParse, "\033r",
 
767
                          MUIA_Text_Contents, keysym[i].label,
 
768
                          MUIA_InnerLeft, 0,
 
769
                          MUIA_InnerRight, 0,
 
770
                        End;
 
771
 
 
772
                Oinput[i] = CycleObject,
 
773
                              MUIA_Cycle_Entries, inputs.names,
 
774
                              MUIA_Cycle_Active, offset_to_active(keysym[i].type, keysym[i].offset),
 
775
                            End,
 
776
 
 
777
                text[i] = TextObject,
 
778
                            MUIA_Background, MUII_TextBack,
 
779
                            MUIA_Frame, MUIV_Frame_Text,
 
780
                            MUIA_Text_Contents, rawkey_to_name(keysym[i].rawkey),
 
781
                          End;
 
782
 
 
783
                button = TextObject,
 
784
                           ButtonFrame,
 
785
                           MUIA_Background, MUII_ButtonBack,
 
786
                           MUIA_Text_Contents, "Change",
 
787
                           MUIA_Text_PreParse, "\033c",
 
788
                           MUIA_InputMode, MUIV_InputMode_RelVerify,
 
789
                         End;
 
790
 
 
791
                DoMethod(button, MUIM_Notify, MUIA_Pressed, FALSE,
 
792
                         app, 2, MUIM_Application_ReturnID, (i + 1));
 
793
 
 
794
                /* add to window */
 
795
 
 
796
                DoMethod(main_group, OM_ADDMEMBER, label);
 
797
                DoMethod(main_group, OM_ADDMEMBER, Oinput[i]);
 
798
                DoMethod(main_group, OM_ADDMEMBER, text[i]);
 
799
                DoMethod(main_group, OM_ADDMEMBER, button);
 
800
 
 
801
            }
 
802
        }
 
803
 
 
804
        if (app) {
 
805
            unsigned int i;
 
806
 
 
807
            set(window, MUIA_Window_Open, TRUE);
 
808
            while (running) {
 
809
                unsigned long retval = DoMethod(app, MUIM_Application_Input, &signals);
 
810
 
 
811
                switch (retval) {
 
812
                    case MUIV_Application_ReturnID_Quit:
 
813
                        running = FALSE;
 
814
                        break;
 
815
                    case BTN_OK:
 
816
                        for (i = 0; i < NUM_KEYSYM; i++) {
 
817
                            ULONG active;
 
818
 
 
819
                            get(Oinput[i], MUIA_Cycle_Active, &active);
 
820
                            keysym[i].type = inputs.types[active];
 
821
                            keysym[i].offset = inputs.offsets[active];
 
822
                        }
 
823
                        set_cfg(joy);
 
824
                        running = FALSE;
 
825
                        break;
 
826
                    case DEV_CHANGE:
 
827
                        {
 
828
                            ULONG active;
 
829
 
 
830
                            get(Odevice, MUIA_Cycle_Active, &active);
 
831
                            joy_id[joy - 1] = devices.ids[active];
 
832
                            update_inputs(joy_id[joy - 1]);
 
833
                            for (i = 0; i < NUM_KEYSYM; i++) {
 
834
                                set(Oinput[i], MUIA_Cycle_Entries, inputs.names);
 
835
                                set(Oinput[i], MUIA_Cycle_Active, 0);
 
836
                            }
 
837
                        }
 
838
                        break;
 
839
                    default:
 
840
                        if ((retval >= 1) && (retval <= (1 + NUM_KEYSYM))) {
 
841
                            int keycode, index, result;
 
842
                            result = get_key(joy_id[joy - 1], &keycode, &index);
 
843
                            if (result == 1) { /* KEY */
 
844
                                keysym[retval - 1].rawkey = keycode;
 
845
                                set(text[retval - 1], MUIA_Text_Contents, rawkey_to_name(keycode));
 
846
                            } else if (result == 2) { /* AI */
 
847
                                index = offset_to_index(index);
 
848
                                if (index >= 0) {
 
849
                                    set(Oinput[retval - 1], MUIA_Cycle_Active, index);
 
850
                                }
 
851
                            }
 
852
                        }
 
853
                        break;
 
854
                }
 
855
                if (running && signals) {
 
856
                    Wait(signals);
 
857
                }
 
858
            }
 
859
            MUI_DisposeObject(app);
 
860
        }  
 
861
    }
 
862
 
 
863
#undef DEV_CHANGE
 
864
#undef BTN_OK
 
865
 
 
866
    ai_attach();
 
867
 
 
868
    return 0;
891
869
}
892
870
 
893
871
int joyai_update(int joy, int dst)
896
874
    keysym_type *keysym = (joy == 2) ? keysym_2 : keysym_1;
897
875
    BYTE value = 0;
898
876
 
899
 
    if ((CTX == NULL) || (ai_handle[joy-1] == NULL)) {
900
 
      return -1;
901
 
    }
902
 
 
903
 
    if (AIN_ReadDevice(CTX, ai_handle[joy-1], &ptr) == TRUE) {
904
 
      unsigned int i, *data = ptr;
905
 
 
906
 
      for (i=0; i<NUM_KEYSYM; i++) {
907
 
        switch (keysym[i].type) {
908
 
 
909
 
/* Axis and hats use values between -32768 and 32767. Digital Buttons use
910
 
 * values between 0 and 1 (1 is "pressed"), while analog buttons use
911
 
 * values between 0 and 32767.
912
 
 */
913
 
          case TYPE_BUTTON:
 
877
    if ((CTX == NULL) || (ai_handle[joy - 1] == NULL)) {
 
878
        return -1;
 
879
    }
 
880
 
 
881
    if (AIN_ReadDevice(CTX, ai_handle[joy - 1], &ptr) == TRUE) {
 
882
        unsigned int i, *data = ptr;
 
883
 
 
884
        for (i = 0; i < NUM_KEYSYM; i++) {
 
885
            switch (keysym[i].type) {
 
886
 
 
887
                /* Axis and hats use values between -32768 and 32767. Digital Buttons use
 
888
                 * values between 0 and 1 (1 is "pressed"), while analog buttons use
 
889
                 * values between 0 and 32767.
 
890
                 */
 
891
                case TYPE_BUTTON:
 
892
                    value = (1 << keysym[i].bitnum);
 
893
                    if (data[keysym[i].offset]) {
 
894
                        joystick_set_value_or(dst, value);
 
895
                    } else {
 
896
                        joystick_set_value_and(dst, (BYTE) ~value);
 
897
                    }
 
898
                    break;
 
899
                case TYPE_AXES:
 
900
                    value = (1 << keysym[i].bitnum);
 
901
                    switch (keysym[i].bitnum) {
 
902
                        case DIGITAL_UP: /* neg value */
 
903
                        case DIGITAL_LEFT: /* neg value */
 
904
                            if (data[keysym[i].offset] <= (-(ONOFF_VALUE))) {
 
905
                                joystick_set_value_or(dst, value);
 
906
                            } else {
 
907
                                joystick_set_value_and(dst, (BYTE) ~value);
 
908
                            }
 
909
                            break;
 
910
                        case DIGITAL_DOWN: /* pos value */
 
911
                        case DIGITAL_RIGHT: /* pos value */
 
912
                            if (data[keysym[i].offset] >= (ONOFF_VALUE)) {
 
913
                                joystick_set_value_or(dst, value);
 
914
                            } else {
 
915
                                joystick_set_value_and(dst, (BYTE) ~value);
 
916
                            }
 
917
                            break;
 
918
                        default:
 
919
                            break;
 
920
                    }
 
921
                    break;
 
922
                case TYPE_HAT:
 
923
                    value = 0;
 
924
                    switch (data[keysym[i].offset]) {
 
925
                        case 1: /* N */
 
926
                            value = (1 << DIGITAL_UP);
 
927
                            break;
 
928
                        case 2: /* NE */
 
929
                            value = ((1 << DIGITAL_UP) | (1 << DIGITAL_RIGHT));
 
930
                            break;
 
931
                        case 3: /* E */
 
932
                            value = (1 << DIGITAL_RIGHT);
 
933
                            break;
 
934
                        case 4: /* SE */
 
935
                            value = ((1 << DIGITAL_DOWN) | (1 << DIGITAL_RIGHT));
 
936
                            break;
 
937
                        case 5: /* S */
 
938
                            value = (1 << DIGITAL_DOWN);
 
939
                            break;
 
940
                        case 6: /* SW */
 
941
                            value = ((1 << DIGITAL_DOWN) | (1 << DIGITAL_LEFT));
 
942
                            break;
 
943
                        case 7: /* W */
 
944
                            value = (1 << DIGITAL_LEFT);
 
945
                            break;
 
946
                        case 8: /* NW */
 
947
                            value = ((1 << DIGITAL_UP) | (1 << DIGITAL_LEFT));
 
948
                            break;
 
949
                        default: /* none */
 
950
                            break;
 
951
                    }
 
952
 
 
953
                    joystick_set_value_absolute(dst, value);
 
954
                    break;
 
955
                default:
 
956
                    break;
 
957
            }
 
958
        }
 
959
 
 
960
        return 0;
 
961
    }
 
962
 
 
963
    return -1;
 
964
}
 
965
 
 
966
int joyai_key(int joy, int dst, unsigned long kcode, int pressed)
 
967
{
 
968
    BYTE value = 0;
 
969
    keysym_type *keysym = (joy == 2) ? keysym_2 : keysym_1;
 
970
    unsigned int i;
 
971
 
 
972
    for (i = 0; i < NUM_KEYSYM; i++) {
 
973
        if ((keysym[i].type == TYPE_NONE) && (keysym[i].rawkey == kcode)) {
914
974
            value = (1 << keysym[i].bitnum);
915
 
            if (data[keysym[i].offset]) {
 
975
            if (pressed) {
916
976
                joystick_set_value_or(dst, value);
917
977
            } else {
918
978
                joystick_set_value_and(dst, (BYTE) ~value);
919
979
            }
920
 
            break;
921
 
 
922
 
          case TYPE_AXES:
923
 
            value = (1 << keysym[i].bitnum);
924
 
            switch (keysym[i].bitnum) {
925
 
              case DIGITAL_UP: /* neg value */
926
 
              case DIGITAL_LEFT: /* neg value */
927
 
                if (data[keysym[i].offset] <= (-(ONOFF_VALUE))) {
928
 
                    joystick_set_value_or(dst, value);
929
 
                } else {
930
 
                    joystick_set_value_and(dst, (BYTE) ~value);
931
 
                }
932
 
                break;
933
 
 
934
 
              case DIGITAL_DOWN: /* pos value */
935
 
              case DIGITAL_RIGHT: /* pos value */
936
 
                if (data[keysym[i].offset] >= (ONOFF_VALUE)) {
937
 
                    joystick_set_value_or(dst, value);
938
 
                } else {
939
 
                    joystick_set_value_and(dst, (BYTE) ~value);
940
 
                }
941
 
                break;
942
 
 
943
 
              default:
944
 
                break;
945
 
            }
946
 
            break;
947
 
 
948
 
          case TYPE_HAT:
949
 
            value = 0;
950
 
            switch (data[keysym[i].offset]) {
951
 
              case 1: /* N */
952
 
                value = (1 << DIGITAL_UP);
953
 
                break;
954
 
 
955
 
              case 2: /* NE */
956
 
                value = ((1 << DIGITAL_UP) | (1 << DIGITAL_RIGHT));
957
 
                break;
958
 
 
959
 
              case 3: /* E */
960
 
                value = (1 << DIGITAL_RIGHT);
961
 
                break;
962
 
 
963
 
              case 4: /* SE */
964
 
                value = ((1 << DIGITAL_DOWN) | (1 << DIGITAL_RIGHT));
965
 
                break;
966
 
 
967
 
              case 5: /* S */
968
 
                value = (1 << DIGITAL_DOWN);
969
 
                break;
970
 
 
971
 
              case 6: /* SW */
972
 
                value = ((1 << DIGITAL_DOWN) | (1 << DIGITAL_LEFT));
973
 
                break;
974
 
 
975
 
              case 7: /* W */
976
 
                value = (1 << DIGITAL_LEFT);
977
 
                break;
978
 
 
979
 
              case 8: /* NW */
980
 
                value = ((1 << DIGITAL_UP) | (1 << DIGITAL_LEFT));
981
 
                break;
982
 
 
983
 
              default: /* none */
984
 
                break;
985
 
            }
986
 
 
987
 
            joystick_set_value_absolute(dst, value);
988
 
            break;
989
 
 
990
 
          default:
991
 
            break;
992
 
        }
993
 
      }
994
 
 
995
 
      return 0;
996
 
    }
997
 
 
998
 
    return -1;
999
 
}
1000
 
 
1001
 
int joyai_key(int joy, int dst, unsigned long kcode, int pressed)
1002
 
{
1003
 
    BYTE value = 0;
1004
 
    keysym_type *keysym = (joy == 2) ? keysym_2 : keysym_1;
1005
 
    unsigned int i;
1006
 
 
1007
 
    for (i=0; i<NUM_KEYSYM; i++) {
1008
 
        if ((keysym[i].type == TYPE_NONE) && (keysym[i].rawkey == kcode)) {
1009
 
              value = (1 << keysym[i].bitnum);
1010
 
              if (pressed) {
1011
 
                  joystick_set_value_or(dst, value);
1012
 
              } else {
1013
 
                  joystick_set_value_and(dst, (BYTE) ~value);
1014
 
              }
1015
980
        }
1016
981
    }
1017
982