~ubuntu-branches/ubuntu/wily/mupen64plus/wily-proposed

« back to all changes in this revision

Viewing changes to .pc/correct_security_printf.patch/blight_input/plugin.c

  • Committer: Bazaar Package Importer
  • Author(s): Sven Eckelmann
  • Date: 2011-02-06 11:57:54 UTC
  • mfrom: (10.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20110206115754-t3abbdfr1q3brszp
Tags: 1.5+dfsg1-15
* Upload to unstable
* Updated my maintainer e-mail address
* debian/patches:
  - Add inline_header.patch, Move inline list_empty to header to make it
    inlineable
* Keep dependencies on separate lines in debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
2
 *   Mupen64plus - plugin.c                                                *
 
3
 *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
 
4
 *   Copyright (C) 2008 Richard42 Tillin9                                  *
 
5
 *   Copyright (C) 2002 Blight                                             *
 
6
 *                                                                         *
 
7
 *   This program is free software; you can redistribute it and/or modify  *
 
8
 *   it under the terms of the GNU General Public License as published by  *
 
9
 *   the Free Software Foundation; either version 2 of the License, or     *
 
10
 *   (at your option) any later version.                                   *
 
11
 *                                                                         *
 
12
 *   This program is distributed in the hope that it will be useful,       *
 
13
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
14
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
15
 *   GNU General Public License for more details.                          *
 
16
 *                                                                         *
 
17
 *   You should have received a copy of the GNU General Public License     *
 
18
 *   along with this program; if not, write to the                         *
 
19
 *   Free Software Foundation, Inc.,                                       *
 
20
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
 
21
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
22
 
 
23
#include <stdio.h>
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include <fcntl.h>
 
27
#include <unistd.h>
 
28
#include <dirent.h>
 
29
 
 
30
#include <sys/types.h>
 
31
#include <sys/stat.h>
 
32
 
 
33
#include "SDL.h"
 
34
 
 
35
#include "../main/winlnxdefs.h"
 
36
#include "plugin.h"
 
37
 
 
38
#ifdef GUI_SDL
 
39
# include "configdialog_sdl.h"
 
40
#elif defined(GUI_GTK)
 
41
# include "configdialog_gtk.h"
 
42
#endif
 
43
 
 
44
#ifdef GUI_GTK
 
45
# include <gtk/gtk.h>
 
46
#endif
 
47
 
 
48
#ifdef __linux__
 
49
#include <linux/input.h>
 
50
#endif /* __linux__ */
 
51
 
 
52
#include <errno.h>
 
53
 
 
54
/* defines for the force feedback rumble support */
 
55
#ifdef __linux__
 
56
#define BITS_PER_LONG (sizeof(long) * 8)
 
57
#define OFF(x)  ((x)%BITS_PER_LONG)
 
58
#define BIT(x)  (1UL<<OFF(x))
 
59
#define LONG(x) ((x)/BITS_PER_LONG)
 
60
#define test_bit(bit, array)    ((array[LONG(bit)] >> OFF(bit)) & 1)
 
61
#endif //__linux__
 
62
 
 
63
#include "winuser.h"
 
64
 
 
65
static unsigned short button_bits[] = {
 
66
    0x0001,  // R_DPAD
 
67
    0x0002,  // L_DPAD
 
68
    0x0004,  // D_DPAD
 
69
    0x0008,  // U_DPAD
 
70
    0x0010,  // START_BUTTON
 
71
    0x0020,  // Z_TRIG
 
72
    0x0040,  // B_BUTTON
 
73
    0x0080,  // A_BUTTON
 
74
    0x0100,  // R_CBUTTON
 
75
    0x0200,  // L_CBUTTON
 
76
    0x0400,  // D_CBUTTON
 
77
    0x0800,  // U_CBUTTON
 
78
    0x1000,  // R_TRIG
 
79
    0x2000,  // L_TRIG
 
80
    0x4000,  // Mempak switch
 
81
    0x8000   // Rumblepak switch
 
82
};
 
83
 
 
84
static SController controller[4];   // 4 controllers
 
85
static int romopen = 0;         // is a rom opened
 
86
static char configdir[PATH_MAX] = {0};  // holds config dir path
 
87
 
 
88
Uint8 myKeyState[SDLK_LAST];
 
89
 
 
90
static const char *button_names[] = {
 
91
    "DPad R",       // R_DPAD
 
92
    "DPad L",       // L_DPAD
 
93
    "DPad D",       // D_DPAD
 
94
    "DPad U",       // U_DPAD
 
95
    "Start",        // START_BUTTON
 
96
    "Z Trig",       // Z_TRIG
 
97
    "B Button",     // B_BUTTON
 
98
    "A Button",     // A_BUTTON
 
99
    "C Button R",   // R_CBUTTON
 
100
    "C Button L",   // L_CBUTTON
 
101
    "C Button D",   // D_CBUTTON
 
102
    "C Button U",   // U_CBUTTON
 
103
    "R Trig",       // R_TRIG
 
104
    "L Trig",       // L_TRIG
 
105
    "Mempak switch",
 
106
    "Rumblepak switch",
 
107
    "Y Axis",       // Y_AXIS
 
108
    "X Axis"        // X_AXIS
 
109
};
 
110
 
 
111
static int
 
112
get_button_num_by_name( const char *name )
 
113
{
 
114
    int i;
 
115
 
 
116
    for( i = 0; i < NUM_BUTTONS; i++ )
 
117
        if( !strncasecmp( name, button_names[i], strlen( button_names[i] ) ) )
 
118
        {
 
119
#ifdef _DEBUG
 
120
            printf( "%s, %d: name = %s, button = %d\n", __FILE__, __LINE__, name, i );
 
121
#endif
 
122
            return i;
 
123
        }
 
124
 
 
125
#ifdef _DEBUG
 
126
    printf( "%s, %d: button '%s' unknown\n", __FILE__, __LINE__, name );
 
127
#endif
 
128
    return -1;
 
129
}
 
130
/*
 
131
static SDLKey
 
132
get_key_by_name( const char *name )
 
133
{
 
134
    int i;
 
135
 
 
136
    for( i = 0; i < SDLK_LAST; i++ )
 
137
        if( !strncasecmp( name, SDL_GetKeyName( i ), strlen( SDL_GetKeyName( i ) ) ) )
 
138
        {
 
139
#ifdef _DEBUG
 
140
            printf( "%s, %d: name = %s, key = %d\n", __FILE__, __LINE__, name, i );
 
141
#endif
 
142
            return i;
 
143
        }
 
144
 
 
145
#ifdef _DEBUG
 
146
    printf( "%s, %d: key '%s' unknown\n", __FILE__, __LINE__, name );
 
147
#endif
 
148
    return SDLK_UNKNOWN;
 
149
}
 
150
*/
 
151
static int
 
152
get_hat_pos_by_name( const char *name )
 
153
{
 
154
    if( !strcasecmp( name, "up" ) )
 
155
        return SDL_HAT_UP;
 
156
    if( !strcasecmp( name, "down" ) )
 
157
        return SDL_HAT_DOWN;
 
158
    if( !strcasecmp( name, "left" ) )
 
159
        return SDL_HAT_LEFT;
 
160
    if( !strcasecmp( name, "right" ) )
 
161
        return SDL_HAT_RIGHT;
 
162
    return -1;
 
163
}
 
164
 
 
165
void read_configuration( void )
 
166
{
 
167
    FILE *f;
 
168
    int cont, plugged, plugin, mouse, i, b, dev;
 
169
    char line[200], device[200], key_a[200], key_b[200], button_a[200], button_b[200],
 
170
             axis[200], axis_a[200], axis_b[200], button[200], hat[200], hat_pos_a[200], hat_pos_b[200], mbutton[200];
 
171
    char chAxisDir;
 
172
    const char *p;
 
173
    char path[PATH_MAX];
 
174
 
 
175
    for( i = 0; i < 4; i++ )
 
176
    {
 
177
        controller[i].device = DEVICE_NONE;
 
178
        controller[i].control.Present = FALSE;
 
179
        controller[i].control.RawData = FALSE;
 
180
        controller[i].control.Plugin = PLUGIN_NONE;
 
181
        for( b = 0; b < 16; b++ )
 
182
        {
 
183
            controller[i].button[b].button = -1;
 
184
            controller[i].button[b].key = SDLK_UNKNOWN;
 
185
            controller[i].button[b].axis = -1;
 
186
            controller[i].button[b].hat = -1;
 
187
            controller[i].button[b].hat_pos = -1;
 
188
            controller[i].button[b].mouse = -1;
 
189
        }
 
190
        for( b = 0; b < 2; b++ )
 
191
        {
 
192
            controller[i].axis[b].button_a = controller[i].axis[b].button_b = -1;
 
193
            controller[i].axis[b].key_a = controller[i].axis[b].key_a = SDLK_UNKNOWN;
 
194
            controller[i].axis[b].axis_a = -1;
 
195
            controller[i].axis[b].axis_dir_a = 1;
 
196
            controller[i].axis[b].axis_b = -1;
 
197
            controller[i].axis[b].axis_dir_b = 1;
 
198
            controller[i].axis[b].hat = -1;
 
199
            controller[i].axis[b].hat_pos_a = -1;
 
200
            controller[i].axis[b].hat_pos_b = -1;
 
201
        }
 
202
    }
 
203
 
 
204
    path[0] = '\0';
 
205
    if(strlen(configdir) > 0)
 
206
        strncpy(path, configdir, PATH_MAX);
 
207
    strncat(path, "blight_input.conf", PATH_MAX - strlen(path));
 
208
    f = fopen( path, "r" );
 
209
    if( f == NULL )
 
210
    {
 
211
        fprintf( stderr, "["PLUGIN_NAME"]: Couldn't open blight_input.conf for reading: %s\n", strerror( errno ) );
 
212
        return;
 
213
    }
 
214
    while( !feof( f ) )
 
215
    {
 
216
        if( fgets( line, 200, f ) == NULL )
 
217
            break;
 
218
        if( line[0] == '\n' || line[0] == '\0' )
 
219
            continue;
 
220
        if( sscanf( line, "[controller %d]", &cont ) == 1 )
 
221
            continue;
 
222
        if( sscanf( line, "plugged=%d", &plugged ) == 1 )
 
223
        {
 
224
            controller[cont].control.Present = plugged;
 
225
            continue;
 
226
        }
 
227
        if( sscanf( line, "plugin=%d", &plugin ) == 1 )
 
228
        {
 
229
            controller[cont].control.Plugin = plugin;
 
230
            continue;
 
231
        }
 
232
        if( sscanf( line, "mouse=%d", &mouse ) == 1 )
 
233
        {
 
234
            controller[cont].mouse = mouse;
 
235
            continue;
 
236
        }
 
237
        if( sscanf( line, "device=%200s", device ) == 1 )
 
238
        {
 
239
            dev = DEVICE_NONE;
 
240
            if( !strcasecmp( device, "keyboard" ) )
 
241
                dev = DEVICE_KEYBOARD;
 
242
            else if( sscanf( device, "%d", &i ) == 1 )
 
243
                dev = i;
 
244
            controller[cont].device = dev;
 
245
            continue;
 
246
        }
 
247
        p = strchr( line, '=' );
 
248
        if( p )
 
249
        {
 
250
            int len = p - line;
 
251
            int num;
 
252
 
 
253
            strncpy( button, line, len );
 
254
            button[len] = '\0';
 
255
            p++;
 
256
 
 
257
            b = get_button_num_by_name( button );
 
258
            if( (b == X_AXIS) || (b == Y_AXIS) )
 
259
            {
 
260
                num = sscanf( p, "key( %s , %s ); button( %s , %s ); axis( %s , %s ); hat( %s , %s , %s )",
 
261
                    key_a, key_b, button_a, button_b, axis_a, axis_b, hat, hat_pos_a, hat_pos_b );
 
262
 
 
263
#ifdef _DEBUG
 
264
                printf( "%s, %d: num = %d, key_a = %s, key_b = %s, button_a = %s, button_b = %s, axis_a = %s, axis_b = %s, hat = %s, hat_pos_a = %s, hat_pos_b = %s\n", __FILE__, __LINE__, num,
 
265
                        key_a, key_b, button_a, button_b, axis_a, axis_b, hat, hat_pos_a, hat_pos_b );
 
266
#endif
 
267
                if( sscanf( key_a, "%d", (int *)&controller[cont].axis[b - Y_AXIS].key_a ) != 1 )
 
268
                    controller[cont].axis[b - Y_AXIS].key_a = -1;
 
269
                if( sscanf( key_b, "%d", (int *)&controller[cont].axis[b - Y_AXIS].key_b ) != 1 )
 
270
                    controller[cont].axis[b - Y_AXIS].key_b = -1;
 
271
                if( sscanf( button_a, "%d", &controller[cont].axis[b - Y_AXIS].button_a ) != 1 )
 
272
                    controller[cont].axis[b - Y_AXIS].button_a = -1;
 
273
                if( sscanf( button_b, "%d", &controller[cont].axis[b - Y_AXIS].button_b ) != 1 )
 
274
                    controller[cont].axis[b - Y_AXIS].button_b = -1;
 
275
                num = sscanf( axis_a, "%d%c", &controller[cont].axis[b - Y_AXIS].axis_a, &chAxisDir );
 
276
                if( num != 2 )
 
277
                {
 
278
                    controller[cont].axis[b - Y_AXIS].axis_a = -1;
 
279
                    controller[cont].axis[b - Y_AXIS].axis_dir_a = 0;
 
280
                }
 
281
                else
 
282
                {
 
283
                    if( chAxisDir == '+' )
 
284
                        controller[cont].axis[b - Y_AXIS].axis_dir_a = 1;
 
285
                    else if( chAxisDir == '-' )
 
286
                        controller[cont].axis[b - Y_AXIS].axis_dir_a = -1;
 
287
                    else
 
288
                        controller[cont].axis[b - Y_AXIS].axis_dir_a = 0;
 
289
                }
 
290
              
 
291
                num = sscanf( axis_b, "%d%c", &controller[cont].axis[b - Y_AXIS].axis_b, &chAxisDir);
 
292
                if( num != 2 )
 
293
                {
 
294
                    controller[cont].axis[b - Y_AXIS].axis_b = -1;
 
295
                    controller[cont].axis[b - Y_AXIS].axis_dir_b = 0;
 
296
                }
 
297
                else
 
298
                {
 
299
                    if( chAxisDir == '+' )
 
300
                        controller[cont].axis[b - Y_AXIS].axis_dir_b = 1;
 
301
                    else if( chAxisDir == '-' )
 
302
                        controller[cont].axis[b - Y_AXIS].axis_dir_b = -1;
 
303
                    else
 
304
                        controller[cont].axis[b - Y_AXIS].axis_dir_b = 0;
 
305
                }
 
306
                if( sscanf( hat, "%d", &controller[cont].axis[b - Y_AXIS].hat ) != 1 )
 
307
                    controller[cont].axis[b - Y_AXIS].hat = -1;
 
308
                controller[cont].axis[b - Y_AXIS].hat_pos_a = get_hat_pos_by_name( hat_pos_a );
 
309
                controller[cont].axis[b - Y_AXIS].hat_pos_b = get_hat_pos_by_name( hat_pos_b );
 
310
            }
 
311
            else
 
312
            {
 
313
                num = sscanf( p, "key( %s ); button( %s ); axis( %s ); hat( %s , %s ); mouse( %s )",
 
314
                        key_a,
 
315
                        button_a,
 
316
                        axis,
 
317
                        hat,
 
318
                        hat_pos_a,
 
319
                        mbutton );
 
320
#ifdef _DEBUG
 
321
                printf( "%s, %d: num = %d, key = %s, button = %s, axis = %s, hat = %s, hat_pos = %s, mbutton = %s\n", __FILE__, __LINE__, num, key_a, button_a, axis, hat, hat_pos_a, mbutton );
 
322
#endif
 
323
                num = sscanf( axis, "%d%c", &controller[cont].button[b].axis, &chAxisDir );
 
324
                if( num != 2 )
 
325
                {
 
326
                    controller[cont].button[b].axis = -1;
 
327
                    controller[cont].button[b].axis_dir = 0;
 
328
                }
 
329
                else
 
330
                {
 
331
                    if( chAxisDir == '+' )
 
332
                        controller[cont].button[b].axis_dir = 1;
 
333
                    else if( chAxisDir == '-' )
 
334
                        controller[cont].button[b].axis_dir = -1;
 
335
                    else
 
336
                        controller[cont].button[b].axis_dir = 0;
 
337
                }
 
338
                if( sscanf( key_a, "%d", (int *)&controller[cont].button[b].key ) != 1 )
 
339
                    controller[cont].button[b].key = -1;
 
340
                if( sscanf( button_a, "%d", &controller[cont].button[b].button ) != 1 )
 
341
                    controller[cont].button[b].button = -1;
 
342
                if( sscanf( hat, "%d", &controller[cont].button[b].hat ) != 1 )
 
343
                    controller[cont].button[b].hat = -1;
 
344
                controller[cont].button[b].hat_pos = get_hat_pos_by_name( hat_pos_a );
 
345
                if( sscanf( mbutton, "%d", &controller[cont].button[b].mouse ) != 1 )
 
346
                    controller[cont].button[b].mouse = -1;
 
347
            }
 
348
            continue;
 
349
        }
 
350
        fprintf( stderr, "["PLUGIN_NAME"]: Unknown config line: %s\n", line );
 
351
    }
 
352
    fclose( f );
 
353
}
 
354
 
 
355
#define HAT_POS_NAME( hat )         \
 
356
       ((hat == SDL_HAT_UP) ? "Up" :        \
 
357
       ((hat == SDL_HAT_DOWN) ? "Down" :    \
 
358
       ((hat == SDL_HAT_LEFT) ? "Left" :    \
 
359
       ((hat == SDL_HAT_RIGHT) ? "Right" :  \
 
360
         "None"))))
 
361
 
 
362
int
 
363
write_configuration( void )
 
364
{
 
365
    FILE *f;
 
366
    int i, b;
 
367
    char cKey_a[100], cKey_b[100];
 
368
    char cButton_a[100], cButton_b[100], cAxis[100], cAxis_a[100], cAxis_b[100];
 
369
    char cHat[100];
 
370
    char cMouse[100];
 
371
    char path[PATH_MAX];
 
372
 
 
373
    path[0] = '\0';
 
374
    if(strlen(configdir) > 0)
 
375
        strncpy(path, configdir, PATH_MAX);
 
376
    strncat(path, "blight_input.conf", PATH_MAX - strlen(path));
 
377
    f = fopen( path, "w" );
 
378
    if( f == NULL )
 
379
    {
 
380
        fprintf( stderr, "["PLUGIN_NAME"]: Couldn't open blight_input.conf for writing: %s\n", strerror( errno ) );
 
381
        return -1;
 
382
    }
 
383
 
 
384
    for( i = 0; i < 4; i++ )
 
385
    {
 
386
        fprintf( f, "[controller %d]\n", i );
 
387
        fprintf( f, "plugged=%d\n", controller[i].control.Present );
 
388
        fprintf( f, "plugin=%d\n", controller[i].control.Plugin );
 
389
        fprintf( f, "mouse=%d\n", controller[i].mouse );
 
390
        if( controller[i].device == DEVICE_KEYBOARD )
 
391
            fprintf( f, "device=Keyboard\n" );
 
392
        else if( controller[i].device >= 0 )
 
393
            fprintf( f, "device=%d\n", controller[i].device );
 
394
        else
 
395
            fprintf( f, "device=None\n" );
 
396
 
 
397
        for( b = 0; b < 16; b++ )
 
398
        {
 
399
//          cKey_a = (controller[i].button[b].key == SDLK_UNKNOWN) ? "None" : SDL_GetKeyName( controller[i].button[b].key );
 
400
            if( controller[i].button[b].key >= 0 )
 
401
                sprintf( cKey_a, "%d", controller[i].button[b].key );
 
402
            else
 
403
                strcpy( cButton_a, "None" );
 
404
 
 
405
            if( controller[i].button[b].button >= 0 )
 
406
                sprintf( cButton_a, "%d", controller[i].button[b].button );
 
407
            else
 
408
                strcpy( cButton_a, "None" );
 
409
 
 
410
            if( controller[i].button[b].axis >= 0 )
 
411
                sprintf( cAxis, "%d%c", controller[i].button[b].axis, (controller[i].button[b].axis_dir == -1) ? '-' : '+' );
 
412
            else
 
413
                strcpy( cAxis, "None" );
 
414
 
 
415
            if( controller[i].button[b].hat >= 0 )
 
416
                sprintf( cHat, "%d", controller[i].button[b].hat );
 
417
            else
 
418
                strcpy( cHat, "None" );
 
419
 
 
420
            if( controller[i].button[b].mouse >= 0 )
 
421
                sprintf( cMouse, "%d", controller[i].button[b].mouse );
 
422
            else
 
423
                strcpy( cMouse, "None" );
 
424
 
 
425
            fprintf( f, "%s=key( %s ); button( %s ); axis( %s ); hat( %s , %s ); mouse( %s )\n", button_names[b],
 
426
                    cKey_a, cButton_a, cAxis, cHat, HAT_POS_NAME(controller[i].button[b].hat_pos), cMouse );
 
427
        }
 
428
        for( b = 0; b < 2; b++ )
 
429
        {
 
430
//          cKey_a = (controller[i].axis[b].key_a == SDLK_UNKNOWN) ? "None" : SDL_GetKeyName( controller[i].axis[b].key_a );
 
431
//          cKey_b = (controller[i].axis[b].key_b == SDLK_UNKNOWN) ? "None" : SDL_GetKeyName( controller[i].axis[b].key_b );
 
432
            if( controller[i].axis[b].key_a >= 0 )
 
433
                sprintf( cKey_a, "%d", controller[i].axis[b].key_a );
 
434
            else
 
435
                strcpy( cKey_a, "None" );
 
436
            if( controller[i].axis[b].key_b >= 0 )
 
437
                sprintf( cKey_b, "%d", controller[i].axis[b].key_b );
 
438
            else
 
439
                strcpy( cKey_b, "None" );
 
440
 
 
441
            if( controller[i].axis[b].button_a >= 0 )
 
442
                sprintf( cButton_a, "%d", controller[i].axis[b].button_a );
 
443
            else
 
444
                strcpy( cButton_a, "None" );
 
445
 
 
446
            if( controller[i].axis[b].button_b >= 0 )
 
447
                sprintf( cButton_b, "%d", controller[i].axis[b].button_b );
 
448
            else
 
449
                strcpy( cButton_b, "None" );
 
450
 
 
451
            if( controller[i].axis[b].axis_a >= 0 )
 
452
                sprintf( cAxis_a, "%d%c", controller[i].axis[b].axis_a, (controller[i].axis[b].axis_dir_a <= 0) ? '-' : '+' );
 
453
            else
 
454
                strcpy( cAxis_a, "None" );
 
455
                
 
456
            if( controller[i].axis[b].axis_b >= 0 )
 
457
                sprintf( cAxis_b, "%d%c", controller[i].axis[b].axis_b, (controller[i].axis[b].axis_dir_b <= 0) ? '-' : '+' );
 
458
            else
 
459
                strcpy( cAxis_b, "None" );
 
460
           
 
461
            if( controller[i].axis[b].hat >= 0 )
 
462
                sprintf( cHat, "%d", controller[i].axis[b].hat );
 
463
            else
 
464
                strcpy( cHat, "None" );
 
465
 
 
466
            fprintf( f, "%s=key( %s , %s ); button( %s , %s ); axis( %s , %s ); hat( %s , %s , %s )\n", button_names[b+16],
 
467
                        cKey_a, cKey_b, cButton_a, cButton_b, cAxis_a, cAxis_b, cHat, HAT_POS_NAME(controller[i].axis[b].hat_pos_a), HAT_POS_NAME(controller[i].axis[b].hat_pos_b) );
 
468
        }
 
469
        fprintf( f, "\n" );
 
470
    }
 
471
 
 
472
    fclose( f );
 
473
    return 0;
 
474
}
 
475
 
 
476
BYTE lastCommand[6];
 
477
 
 
478
#ifdef __linux__
 
479
 
 
480
struct ff_effect ffeffect[3];
 
481
struct ff_effect ffstrong[3];
 
482
struct ff_effect ffweak[3];
 
483
 
 
484
#endif //__linux__
 
485
BYTE DataCRC( BYTE *Data, int iLenght )
 
486
{
 
487
    register BYTE Remainder = Data[0];
 
488
 
 
489
    int iByte = 1;
 
490
    BYTE bBit = 0;
 
491
 
 
492
    while( iByte <= iLenght )
 
493
    {
 
494
        BOOL HighBit = ((Remainder & 0x80) != 0);
 
495
        Remainder = Remainder << 1;
 
496
 
 
497
        Remainder += ( iByte < iLenght && Data[iByte] & (0x80 >> bBit )) ? 1 : 0;
 
498
 
 
499
        Remainder ^= (HighBit) ? 0x85 : 0;
 
500
 
 
501
        bBit++;
 
502
        iByte += bBit/8;
 
503
        bBit %= 8;
 
504
    }
 
505
 
 
506
    return Remainder;
 
507
}
 
508
 
 
509
/******************************************************************
 
510
  Function: CloseDLL
 
511
  Purpose:  This function is called when the emulator is closing
 
512
            down allowing the dll to de-initialise.
 
513
  input:    none
 
514
  output:   none
 
515
*******************************************************************/
 
516
void
 
517
CloseDLL( void )
 
518
{
 
519
    printf( "["PLUGIN_NAME"]: Closing...\n" );
 
520
}
 
521
 
 
522
/******************************************************************
 
523
  Function: ControllerCommand
 
524
  Purpose:  To process the raw data that has just been sent to a
 
525
            specific controller.
 
526
  input:    - Controller Number (0 to 3) and -1 signalling end of
 
527
              processing the pif ram.
 
528
            - Pointer of data to be processed.
 
529
  output:   none
 
530
 
 
531
  note:     This function is only needed if the DLL is allowing raw
 
532
            data, or the plugin is set to raw
 
533
 
 
534
            the data that is being processed looks like this:
 
535
            initilize controller: 01 03 00 FF FF FF
 
536
            read controller:      01 04 01 FF FF FF FF
 
537
*******************************************************************/
 
538
void ControllerCommand(int Control, BYTE *Command)
 
539
{
 
540
    BYTE *Data = &Command[5];
 
541
 
 
542
    if (Control == -1)
 
543
        return;
 
544
 
 
545
    switch (Command[2])
 
546
    {
 
547
        case RD_GETSTATUS:
 
548
            /*printf( "Get status\n" );*/
 
549
            break;
 
550
        case RD_READKEYS:
 
551
            /*printf( "Read keys\n" );*/
 
552
            break;
 
553
        case RD_READPAK:
 
554
            /*printf( "Read pak\n" );*/
 
555
            if (controller[Control].control.Plugin == PLUGIN_RAW)
 
556
            {
 
557
                DWORD dwAddress = (Command[3] << 8) + (Command[4] & 0xE0);
 
558
 
 
559
                if(( dwAddress >= 0x8000 ) && ( dwAddress < 0x9000 ) )
 
560
                    memset( Data, 0x80, 32 );
 
561
                else
 
562
                    memset( Data, 0x00, 32 );
 
563
 
 
564
                Data[32] = DataCRC( Data, 32 );
 
565
                break;
 
566
                }
 
567
        case RD_WRITEPAK:
 
568
            /*printf( "Write pak\n" );*/
 
569
            if (controller[Control].control.Plugin == PLUGIN_RAW)
 
570
            {
 
571
                DWORD dwAddress = (Command[3] << 8) + (Command[4] & 0xE0);
 
572
                /*Uncomment to test rumble on systems without necessary hardware.
 
573
              if(dwAddress==PAK_IO_RUMBLE&&*Data)
 
574
                    printf("Triggering rumble pack.\n");*/
 
575
 
 
576
#ifdef __linux__
 
577
                struct input_event play;
 
578
                if( dwAddress == PAK_IO_RUMBLE && controller[Control].event_joystick != 0)
 
579
                {
 
580
                    if( *Data )
 
581
                    {
 
582
                        play.type = EV_FF;
 
583
                        play.code = ffeffect[Control].id;
 
584
                        play.value = 1;
 
585
 
 
586
                        if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1)
 
587
                            perror("Error starting rumble effect");
 
588
 
 
589
                    }
 
590
                    else
 
591
                    {
 
592
                        play.type = EV_FF;
 
593
                        play.code = ffeffect[Control].id;
 
594
                        play.value = 0;
 
595
 
 
596
                        if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1)
 
597
                            perror("Error stopping rumble effect");
 
598
                    }
 
599
                }
 
600
#endif //__linux__
 
601
                Data[32] = DataCRC( Data, 32 );
 
602
            }
 
603
            break;
 
604
        case RD_RESETCONTROLLER:
 
605
            /*printf( "Reset controller\n" );*/
 
606
            break;
 
607
        case RD_READEEPROM:
 
608
            /*printf( "Read eeprom\n" );*/
 
609
            break;
 
610
        case RD_WRITEEPROM:
 
611
            /*printf( "Write eeprom\n" );*/
 
612
            break;
 
613
        }
 
614
}
 
615
 
 
616
/******************************************************************
 
617
  Function: DllAbout
 
618
  Purpose:  This function is optional function that is provided
 
619
            to give further information about the DLL.
 
620
  input:    a handle to the window that calls this function
 
621
  output:   none
 
622
*******************************************************************/
 
623
#ifdef GUI_SDL
 
624
# include "SDL_ttf.h"
 
625
# include "arial.ttf.h" // arial font
 
626
# include <stdarg.h>
 
627
 
 
628
# define FONT_SIZEPT 15
 
629
# define ABOUT_DIALOG_WIDTH 300
 
630
# define ABOUT_DIALOG_HEIGHT    145
 
631
 
 
632
// render text
 
633
static inline SDL_Surface *
 
634
render_text( TTF_Font *font, SDL_Color fg, SDL_Color bg, const char *fmt, ... )
 
635
{
 
636
    va_list ap;
 
637
    char buf[2049];
 
638
 
 
639
    va_start( ap, fmt );
 
640
    vsnprintf( buf, 2048, fmt, ap );
 
641
    va_end( ap );
 
642
 
 
643
    if( *buf == '\0' )
 
644
        return NULL;
 
645
 
 
646
    return( TTF_RenderText_Shaded( font, buf, fg, bg ) );
 
647
}
 
648
 
 
649
// write text
 
650
static inline void
 
651
write_text( SDL_Surface *dst, TTF_Font *font, int x, int y, SDL_Color fg, SDL_Color bg, const char *fmt, ... )
 
652
{
 
653
    SDL_Surface *text;
 
654
    SDL_Rect dstrect;
 
655
    va_list ap;
 
656
    char buf[2049];
 
657
 
 
658
    va_start( ap, fmt );
 
659
    vsnprintf( buf, 2048, fmt, ap );
 
660
    va_end( ap );
 
661
 
 
662
    if( *buf == '\0' )
 
663
        return;
 
664
 
 
665
    text = render_text( font, fg, bg, buf );
 
666
    if( text == NULL )
 
667
    {
 
668
        fprintf( stderr, "["PLUGIN_NAME"]: Couldn't render text: %s\n", SDL_GetError() );
 
669
        return;
 
670
    }
 
671
 
 
672
    dstrect.x = x;
 
673
    dstrect.y = y;
 
674
    dstrect.w = text->w;
 
675
    dstrect.h = text->h;
 
676
    SDL_BlitSurface( text, NULL, dst, &dstrect );
 
677
    SDL_FreeSurface( text );
 
678
}
 
679
 
 
680
void
 
681
DllAbout( HWND hParent )
 
682
{
 
683
    SDL_RWops *rw;
 
684
    TTF_Font *font;
 
685
    SDL_Surface *screen;
 
686
    SDL_Rect rect;
 
687
    // colors
 
688
    Uint32 u32black, u32gray, u32dark_gray;
 
689
    SDL_Color black      = { 0x00, 0x00, 0x00, 0 };
 
690
    SDL_Color gray       = { 0xAA, 0xAA, 0xAA, 0 };
 
691
    SDL_Color dark_gray  = { 0x66, 0x66, 0x66, 0 };
 
692
 
 
693
    // init sdl
 
694
    if( !SDL_WasInit( SDL_INIT_VIDEO ) )
 
695
        if( SDL_InitSubSystem( SDL_INIT_VIDEO ) < 0 )
 
696
        {
 
697
            fprintf( stderr, "["PLUGIN_NAME"]: Couldn't init SDL video subsystem: %s\n", SDL_GetError() );
 
698
            return;
 
699
        }
 
700
 
 
701
    // init sdl_ttf2
 
702
    if( !TTF_WasInit() )
 
703
        if( TTF_Init() < 0 )
 
704
        {
 
705
            fprintf( stderr, "["PLUGIN_NAME"]: Couldn't init TTF library: %s\n", SDL_GetError() );
 
706
            SDL_QuitSubSystem( SDL_INIT_VIDEO );
 
707
            return;
 
708
        }
 
709
 
 
710
    // open font
 
711
    rw = SDL_RWFromMem( (char *)arial.data, arial.size );
 
712
    font = TTF_OpenFontRW( rw, 0, FONT_SIZEPT );
 
713
    if( font == NULL )
 
714
    {
 
715
        fprintf( stderr, "["PLUGIN_NAME"]: Couldn't load %d pt font: %s\n", FONT_SIZEPT, SDL_GetError() );
 
716
        TTF_Quit();
 
717
        SDL_QuitSubSystem( SDL_INIT_VIDEO );
 
718
        return;
 
719
    }
 
720
    TTF_SetFontStyle( font, TTF_STYLE_NORMAL );
 
721
 
 
722
    // display dialog (set video mode)
 
723
    screen = SDL_SetVideoMode( ABOUT_DIALOG_WIDTH, ABOUT_DIALOG_HEIGHT, 0, SDL_SWSURFACE );
 
724
    if( !screen )
 
725
    {
 
726
        fprintf( stderr, "["PLUGIN_NAME"]: Couldn't set video mode %dx%d: %s\n", ABOUT_DIALOG_WIDTH, ABOUT_DIALOG_HEIGHT, SDL_GetError() );
 
727
        TTF_Quit();
 
728
        SDL_QuitSubSystem( SDL_INIT_VIDEO );
 
729
        return;
 
730
    }
 
731
    SDL_WM_SetCaption( PLUGIN_NAME" "PLUGIN_VERSION, NULL );
 
732
 
 
733
    // create colors
 
734
    u32black      = SDL_MapRGBA( screen->format, black.r, black.g, black.b, 0 );
 
735
    u32gray       = SDL_MapRGBA( screen->format, gray.r, gray.g, gray.b, 0 );
 
736
    u32dark_gray  = SDL_MapRGBA( screen->format, dark_gray.r, dark_gray.g, dark_gray.b, 0 );
 
737
 
 
738
    // draw dialog
 
739
    SDL_FillRect( screen, NULL, u32dark_gray );
 
740
 
 
741
    rect.x = rect.y = 5; rect.w = ABOUT_DIALOG_WIDTH - 10; rect.h = ABOUT_DIALOG_HEIGHT - 40;
 
742
    SDL_FillRect( screen, &rect, u32black );
 
743
    rect.x += 1; rect.y += 1; rect.w -= 2; rect.h -= 2;
 
744
    SDL_FillRect( screen, &rect, u32gray );
 
745
 
 
746
    write_text( screen, font, 15, 15, black, gray, PLUGIN_NAME" v"PLUGIN_VERSION":" );
 
747
    write_text( screen, font, 15, 35, black, gray, "coded by blight" );
 
748
    write_text( screen, font, 15, 55, black, gray, "This plugin uses the SDL library for input." );
 
749
    write_text( screen, font, 15, 75, black, gray, "Go to www.libsdl.org for more information." );
 
750
 
 
751
    rect.x = (ABOUT_DIALOG_WIDTH - 90) / 2; rect.y = ABOUT_DIALOG_HEIGHT - 30; rect.w = 90; rect.h = 25;
 
752
    SDL_FillRect( screen, &rect, u32black );
 
753
    rect.x += 1; rect.y += 1; rect.w -= 2; rect.h -= 2;
 
754
    SDL_FillRect( screen, &rect, u32gray );
 
755
    
 
756
    write_text( screen, font, rect.x + 33, rect.y + 2, black, gray, "Ok" );
 
757
 
 
758
    for(;;)
 
759
    {
 
760
        SDL_Event event;
 
761
        SDL_Flip( screen );
 
762
        if( SDL_PollEvent( &event ) )
 
763
        {
 
764
            if( event.type == SDL_KEYDOWN )
 
765
            {
 
766
                if( event.key.keysym.sym == SDLK_ESCAPE )
 
767
                    break;
 
768
            }
 
769
            else if( event.type == SDL_MOUSEBUTTONDOWN )
 
770
            {
 
771
                if( event.button.button == SDL_BUTTON_LEFT )
 
772
                {
 
773
                    if( event.button.x >= rect.x && event.button.x <= rect.x + rect.w &&
 
774
                        event.button.y >= rect.y && event.button.y <= rect.y + rect.h )
 
775
                        break;
 
776
                }
 
777
            }
 
778
        }
 
779
    }
 
780
    TTF_Quit();
 
781
    SDL_FreeSurface( screen );
 
782
    SDL_QuitSubSystem( SDL_INIT_VIDEO );
 
783
}
 
784
 
 
785
#elif defined( GUI_GTK )
 
786
static int about_shown = 0;
 
787
 
 
788
static void
 
789
about_ok_clicked(   GtkWidget *widget,
 
790
            gpointer   data )
 
791
{
 
792
    gtk_widget_hide_all( GTK_WIDGET(data) );
 
793
    gtk_widget_destroy( GTK_WIDGET(data) );
 
794
    about_shown = 0;
 
795
}
 
796
 
 
797
void
 
798
DllAbout( HWND hParent )
 
799
{
 
800
    GtkWidget *window;
 
801
    GtkWidget *vbox;
 
802
    GtkWidget *label;
 
803
    GtkWidget *button;
 
804
 
 
805
    if( about_shown )
 
806
        return;
 
807
 
 
808
    window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
 
809
    gtk_window_set_title( GTK_WINDOW(window), PLUGIN_NAME );
 
810
    gtk_container_set_border_width( GTK_CONTAINER(window), 10 );
 
811
    gtk_window_set_policy( GTK_WINDOW(window), FALSE, FALSE, TRUE );
 
812
 
 
813
    vbox = gtk_vbox_new( FALSE, 10 );
 
814
    label = gtk_label_new( PLUGIN_NAME" version "PLUGIN_VERSION"\n\n"
 
815
                "This is a N64 input plugin using SDL.\n"
 
816
                "(c) 2002 by blight" );
 
817
    button = gtk_button_new_with_label( "Ok" );
 
818
 
 
819
    gtk_container_add( GTK_CONTAINER(window), GTK_WIDGET(vbox) );
 
820
    gtk_box_pack_start( GTK_BOX(vbox), GTK_WIDGET(label), TRUE, FALSE, 0 );
 
821
    gtk_box_pack_start( GTK_BOX(vbox), GTK_WIDGET(button), TRUE, FALSE, 0 );
 
822
 
 
823
    gtk_signal_connect( GTK_OBJECT(button), "clicked",
 
824
            GTK_SIGNAL_FUNC(about_ok_clicked), (gpointer) window);
 
825
 
 
826
    // show the window
 
827
    about_shown = 1;
 
828
    gtk_widget_show_all( GTK_WIDGET(window) );
 
829
}
 
830
#endif
 
831
 
 
832
/******************************************************************
 
833
  Function: DllConfig
 
834
  Purpose:  This function is optional function that is provided
 
835
            to allow the user to configure the dll
 
836
  input:    a handle to the window that calls this function
 
837
  output:   none
 
838
*******************************************************************/
 
839
void
 
840
DllConfig( HWND hParent )
 
841
{
 
842
    if( !romopen )
 
843
    {
 
844
        read_configuration();
 
845
#ifdef GUI_SDL
 
846
        configure_sdl( controller );
 
847
#elif defined( GUI_GTK )
 
848
        configure_gtk( controller );
 
849
#endif
 
850
        /* write_configuration() should be called in the configure_ function above */
 
851
    }
 
852
}
 
853
 
 
854
/******************************************************************
 
855
  Function: DllTest
 
856
  Purpose:  This function is optional function that is provided
 
857
            to allow the user to test the dll
 
858
  input:    a handle to the window that calls this function
 
859
  output:   none
 
860
*******************************************************************/
 
861
void
 
862
DllTest( HWND hParent )
 
863
{
 
864
}
 
865
 
 
866
/******************************************************************
 
867
  Function: GetDllInfo
 
868
  Purpose:  This function allows the emulator to gather information
 
869
            about the dll by filling in the PluginInfo structure.
 
870
  input:    a pointer to a PLUGIN_INFO stucture that needs to be
 
871
            filled by the function. (see def above)
 
872
  output:   none
 
873
*******************************************************************/
 
874
void
 
875
GetDllInfo( PLUGIN_INFO *PluginInfo )
 
876
{
 
877
    strncpy( PluginInfo->Name, PLUGIN_NAME" "PLUGIN_VERSION, 100 );
 
878
    PluginInfo->Name[99] = '\0';
 
879
    PluginInfo->Version = 0x0101;
 
880
    PluginInfo->Type = PLUGIN_TYPE_CONTROLLER;
 
881
}
 
882
 
 
883
/* Helper function to handle the SDL keys */
 
884
static void
 
885
doSdlKeys(Uint8* keystate)
 
886
{
 
887
    int c, b, axis_val, axis_max_val, axis_val_tmp;
 
888
    int grabmouse = -1;
 
889
 
 
890
    axis_max_val = 80;
 
891
    if (keystate[SDLK_LCTRL])
 
892
        axis_max_val -= 40;
 
893
    if (keystate[SDLK_LSHIFT])
 
894
        axis_max_val -= 20;
 
895
 
 
896
    for( c = 0; c < 4; c++ )
 
897
    {
 
898
        for( b = 0; b < 16; b++ )
 
899
        {
 
900
            if( controller[c].button[b].key == SDLK_UNKNOWN || ((int) controller[c].button[b].key) < 0)
 
901
                continue;
 
902
            if( keystate[controller[c].button[b].key] )
 
903
                controller[c].buttons.Value |= button_bits[b];
 
904
        }
 
905
        for( b = 0; b < 2; b++ )
 
906
        {
 
907
            // from the N64 func ref: The 3D Stick data is of type signed char and in
 
908
            // the range between 80 and -80. (32768 / 409 = ~80.1)
 
909
            if( b == 0 )
 
910
                axis_val = controller[c].buttons.X_AXIS;
 
911
            else
 
912
                axis_val = -controller[c].buttons.Y_AXIS;
 
913
 
 
914
            if( controller[c].axis[b].key_a != SDLK_UNKNOWN && ((int) controller[c].axis[b].key_a) > 0)
 
915
                if( keystate[controller[c].axis[b].key_a] )
 
916
                    axis_val = axis_max_val;
 
917
            if( controller[c].axis[b].key_b != SDLK_UNKNOWN && ((int) controller[c].axis[b].key_b) > 0)
 
918
                if( keystate[controller[c].axis[b].key_b] )
 
919
                    axis_val = -axis_max_val;
 
920
 
 
921
            if( b == 0 )
 
922
                controller[c].buttons.X_AXIS = axis_val;
 
923
            else
 
924
                controller[c].buttons.Y_AXIS = -axis_val;
 
925
        }
 
926
        if (controller[c].mouse)
 
927
        {
 
928
            if (keystate[SDLK_LCTRL] && keystate[SDLK_LALT])
 
929
            {
 
930
                grabmouse = 0;
 
931
            }
 
932
            if (grabmouse >= 0)
 
933
            {
 
934
                // grab/ungrab mouse
 
935
                SDL_WM_GrabInput( grabmouse ? SDL_GRAB_ON : SDL_GRAB_OFF );
 
936
                SDL_ShowCursor( grabmouse ? 0 : 1 );
 
937
            }
 
938
        }
 
939
    }
 
940
}
 
941
 
 
942
/******************************************************************
 
943
  Function: GetKeys
 
944
  Purpose:  To get the current state of the controllers buttons.
 
945
  input:    - Controller Number (0 to 3)
 
946
            - A pointer to a BUTTONS structure to be filled with
 
947
            the controller state.
 
948
  output:   none
 
949
*******************************************************************/
 
950
void
 
951
GetKeys( int Control, BUTTONS *Keys )
 
952
{
 
953
    int b, axis_val, axis_max_val, axis_val_tmp;
 
954
    SDL_Event event;
 
955
 
 
956
    // Handle keyboard input first
 
957
    doSdlKeys( SDL_GetKeyState( NULL ) );
 
958
    doSdlKeys( myKeyState );
 
959
 
 
960
    // read joystick state
 
961
    SDL_JoystickUpdate();
 
962
 
 
963
    if( controller[Control].device >= 0 )
 
964
    {
 
965
        for( b = 0; b < 16; b++ )
 
966
        {
 
967
            if( controller[Control].button[b].button >= 0 )
 
968
                if( SDL_JoystickGetButton( controller[Control].joystick, controller[Control].button[b].button ) )
 
969
                    controller[Control].buttons.Value |= button_bits[b];
 
970
 
 
971
            if( controller[Control].button[b].axis >= 0 )
 
972
            {
 
973
                axis_val = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].button[b].axis );
 
974
                if( (controller[Control].button[b].axis_dir < 0) && (axis_val <= -6000) )
 
975
                    controller[Control].buttons.Value |= button_bits[b];
 
976
                else if( (controller[Control].button[b].axis_dir > 0) && (axis_val >= 6000) )
 
977
                    controller[Control].buttons.Value |= button_bits[b];
 
978
            }
 
979
 
 
980
            if( controller[Control].button[b].hat >= 0 )
 
981
            {
 
982
                if( controller[Control].button[b].hat_pos > 0 )
 
983
                    if( SDL_JoystickGetHat( controller[Control].joystick, controller[Control].button[b].hat ) & controller[Control].button[b].hat_pos )
 
984
                        controller[Control].buttons.Value |= button_bits[b];
 
985
            }
 
986
        }
 
987
        for( b = 0; b < 2; b++ )
 
988
        {
 
989
            // from the N64 func ref: The 3D Stick data is of type signed char and in
 
990
            // the range between 80 and -80. (32768 / 409 = ~80.1)
 
991
            axis_val = 0;
 
992
            axis_val_tmp = 0;
 
993
            
 
994
            
 
995
            if( controller[Control].axis[b].axis_a >= 0 )
 
996
            {
 
997
                axis_val_tmp = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].axis[b].axis_a );
 
998
                // if you push a positive axis... and your directions are flipped...
 
999
                if( (controller[Control].axis[b].axis_dir_a < 0) && (axis_val_tmp <= -6000) )
 
1000
                {
 
1001
                    if (b == 0)
 
1002
                    {
 
1003
                        axis_val = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].axis[b].axis_a ) / -409;
 
1004
                    }
 
1005
                    else
 
1006
                    {
 
1007
                        axis_val = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].axis[b].axis_a ) / 409;
 
1008
                    }
 
1009
                }
 
1010
                else if( (controller[Control].axis[b].axis_dir_a > 0) && (axis_val_tmp >= 6000) )
 
1011
                {
 
1012
                    if (b == 1)
 
1013
                    {
 
1014
                        axis_val = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].axis[b].axis_a ) / -409;
 
1015
                    }
 
1016
                    else
 
1017
                    {
 
1018
                        axis_val = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].axis[b].axis_a ) / 409;
 
1019
                    }
 
1020
                }
 
1021
            }
 
1022
            // up and left
 
1023
            if( controller[Control].axis[b].axis_b >= 0 )
 
1024
            {
 
1025
                axis_val_tmp = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].axis[b].axis_b );
 
1026
                // if you push a positive axis... and your directions are flipped...
 
1027
                if( (controller[Control].axis[b].axis_dir_b < 0) && (axis_val_tmp <= -6000) )
 
1028
                {
 
1029
                    if (b == 1)
 
1030
                    {
 
1031
                        axis_val = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].axis[b].axis_b ) / -409;
 
1032
                    }
 
1033
                    else
 
1034
                    {
 
1035
                        axis_val = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].axis[b].axis_b ) / 409;
 
1036
                    }
 
1037
                }
 
1038
                else if( (controller[Control].axis[b].axis_dir_b > 0) && (axis_val_tmp >= 6000) )
 
1039
                {
 
1040
                    if (b == 0)
 
1041
                    {
 
1042
                        axis_val = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].axis[b].axis_b ) / -409;
 
1043
                    }
 
1044
                    else
 
1045
                    {
 
1046
                        axis_val = SDL_JoystickGetAxis( controller[Control].joystick, controller[Control].axis[b].axis_b ) / 409;
 
1047
                    }
 
1048
                }
 
1049
            }
 
1050
            if( controller[Control].axis[b].hat >= 0 )
 
1051
            {
 
1052
                if( controller[Control].axis[b].hat_pos_a >= 0 )
 
1053
                    if( SDL_JoystickGetHat( controller[Control].joystick, controller[Control].axis[b].hat ) & controller[Control].axis[b].hat_pos_a )
 
1054
                        axis_val = 80;
 
1055
                if( controller[Control].axis[b].hat_pos_b >= 0 )
 
1056
                    if( SDL_JoystickGetHat( controller[Control].joystick, controller[Control].axis[b].hat ) & controller[Control].axis[b].hat_pos_b )
 
1057
                        axis_val = -80;
 
1058
            }
 
1059
 
 
1060
            if( controller[Control].axis[b].button_a >= 0 )
 
1061
                if( SDL_JoystickGetButton( controller[Control].joystick, controller[Control].axis[b].button_a ) )
 
1062
                    axis_val = 80;
 
1063
            if( controller[Control].axis[b].button_b >= 0 )
 
1064
                if( SDL_JoystickGetButton( controller[Control].joystick, controller[Control].axis[b].button_b ) )
 
1065
                    axis_val = -80;
 
1066
 
 
1067
            if( b == 0 )
 
1068
                controller[Control].buttons.X_AXIS = axis_val;
 
1069
            else
 
1070
                controller[Control].buttons.Y_AXIS = axis_val;
 
1071
        }
 
1072
    }
 
1073
 
 
1074
    // process mouse events
 
1075
    {
 
1076
        Uint8 mstate = SDL_GetMouseState( NULL, NULL );
 
1077
 
 
1078
        for( b = 0; b < 16; b++ )
 
1079
        {
 
1080
            if( controller[Control].button[b].mouse < 1 )
 
1081
                continue;
 
1082
            if( mstate & SDL_BUTTON(controller[Control].button[b].mouse) )
 
1083
                controller[Control].buttons.Value |= button_bits[b];
 
1084
        }
 
1085
    }
 
1086
 
 
1087
    if (controller[Control].mouse)
 
1088
    {
 
1089
        int grabmouse = -1;
 
1090
        while (SDL_PollEvent(&event))
 
1091
        {
 
1092
            if (event.type == SDL_MOUSEMOTION && SDL_WM_GrabInput( SDL_GRAB_QUERY ) == SDL_GRAB_ON)
 
1093
            {
 
1094
                if (event.motion.xrel)
 
1095
                {
 
1096
                    axis_val = (event.motion.xrel * 10);
 
1097
                    if (axis_val < -80)
 
1098
                        axis_val = -80;
 
1099
                    else if (axis_val > 80)
 
1100
                        axis_val = 80;
 
1101
                    controller[Control].buttons.Y_AXIS = axis_val;
 
1102
                }
 
1103
                if (event.motion.yrel)
 
1104
                {
 
1105
                    axis_val = (event.motion.yrel * 10);
 
1106
                    if (axis_val < -80)
 
1107
                        axis_val = -80;
 
1108
                    else if (axis_val > 80)
 
1109
                        axis_val = 80;
 
1110
                    controller[Control].buttons.X_AXIS = -axis_val;
 
1111
                }
 
1112
            }
 
1113
            else if (event.type == SDL_MOUSEBUTTONUP)
 
1114
            {
 
1115
                if (event.button.button == SDL_BUTTON_LEFT)
 
1116
                {
 
1117
                    grabmouse = 1;
 
1118
                }
 
1119
            }
 
1120
        }
 
1121
    }
 
1122
 
 
1123
#ifdef _DEBUG
 
1124
    printf( "Controller #%d value: 0x%8.8X\n", Control, *(int *)&controller[Control].buttons );
 
1125
#endif
 
1126
    *Keys = controller[Control].buttons;
 
1127
 
 
1128
    /* handle mempack / rumblepak switching (only if rumble is active on joystick) */
 
1129
#ifdef __linux__
 
1130
    if (controller[Control].event_joystick != 0)
 
1131
    {
 
1132
        struct input_event play;
 
1133
        if (controller[Control].buttons.Value & button_bits[14])
 
1134
        {
 
1135
            controller[Control].control.Plugin = PLUGIN_MEMPAK;
 
1136
            play.type = EV_FF;
 
1137
            play.code = ffweak[Control].id;
 
1138
            play.value = 1;
 
1139
            if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1)
 
1140
                perror("Error starting rumble effect");
 
1141
        }
 
1142
        if (controller[Control].buttons.Value & button_bits[15])
 
1143
        {
 
1144
            controller[Control].control.Plugin = PLUGIN_RAW;
 
1145
            play.type = EV_FF;
 
1146
            play.code = ffstrong[Control].id;
 
1147
            play.value = 1;
 
1148
            if (write(controller[Control].event_joystick, (const void*) &play, sizeof(play)) == -1)
 
1149
                perror("Error starting rumble effect");
 
1150
        }
 
1151
    }
 
1152
#endif /* __linux__ */
 
1153
 
 
1154
    controller[Control].buttons.Value = 0;
 
1155
    //controller[Control].buttons.stick_x = 0;
 
1156
    //controller[Control].buttons.stick_y = 0;
 
1157
}
 
1158
 
 
1159
static void InitiateRumble(int cntrl)
 
1160
{
 
1161
#ifdef __linux__
 
1162
    DIR* dp;
 
1163
    struct dirent* ep;
 
1164
    unsigned long features[4];
 
1165
    char temp[128];
 
1166
    char temp2[128];
 
1167
    int iFound = 0;
 
1168
 
 
1169
    controller[cntrl].event_joystick = 0;
 
1170
 
 
1171
    sprintf(temp,"/sys/class/input/js%d/device", controller[cntrl].device);
 
1172
    dp = opendir(temp);
 
1173
 
 
1174
    if(dp==NULL)
 
1175
        return;
 
1176
 
 
1177
    while ((ep=readdir(dp)))
 
1178
        {
 
1179
        if (strncmp(ep->d_name, "event",5)==0)
 
1180
            {
 
1181
            sprintf(temp, "/dev/input/%s", ep->d_name);
 
1182
            iFound = 1;
 
1183
            break;
 
1184
            }
 
1185
        else if(strncmp(ep->d_name,"input:event", 11)==0)
 
1186
            {
 
1187
            sscanf(ep->d_name, "input:%s", temp2);
 
1188
            sprintf(temp, "/dev/input/%s", temp2);
 
1189
            iFound = 1;
 
1190
            break;
 
1191
            }
 
1192
        else if(strncmp(ep->d_name,"input:input", 11)==0)
 
1193
            {
 
1194
            strcat(temp, "/");
 
1195
            strcat(temp, ep->d_name);
 
1196
            closedir (dp);
 
1197
            dp = opendir(temp);
 
1198
            if(dp==NULL)
 
1199
                return;
 
1200
            }
 
1201
       }
 
1202
 
 
1203
    closedir(dp);
 
1204
 
 
1205
    if(!iFound)
 
1206
        {
 
1207
        printf("["PLUGIN_NAME"]: Couldn't find input event for rumble support.\n");
 
1208
        return;
 
1209
        }
 
1210
 
 
1211
    controller[cntrl].event_joystick = open(temp, O_RDWR);
 
1212
    if(controller[cntrl].event_joystick==-1)
 
1213
        {
 
1214
        printf("["PLUGIN_NAME"]: Couldn't open device file '%s' for rumble support.\n", temp);
 
1215
        controller[cntrl].event_joystick = 0;
 
1216
        return;
 
1217
        }
 
1218
 
 
1219
    if(ioctl(controller[cntrl].event_joystick, EVIOCGBIT(EV_FF, sizeof(unsigned long) * 4), features)==-1)
 
1220
        {
 
1221
        printf("["PLUGIN_NAME"]: Linux kernel communication failed for force feedback (rumble).\n");
 
1222
        controller[cntrl].event_joystick = 0;
 
1223
        return;
 
1224
        }
 
1225
 
 
1226
    if(!test_bit(FF_RUMBLE, features))
 
1227
        {
 
1228
        printf("["PLUGIN_NAME"]: No rumble supported on N64 joystick #%i\n", cntrl + 1);
 
1229
        controller[cntrl].event_joystick = 0;
 
1230
        return;
 
1231
        }
 
1232
 
 
1233
    ffeffect[cntrl].type = FF_RUMBLE;
 
1234
    ffeffect[cntrl].id = -1;
 
1235
    ffeffect[cntrl].u.rumble.strong_magnitude = 0xFFFF;
 
1236
    ffeffect[cntrl].u.rumble.weak_magnitude = 0xFFFF;
 
1237
 
 
1238
    ioctl(controller[cntrl].event_joystick, EVIOCSFF, &ffeffect[cntrl]);
 
1239
 
 
1240
    ffstrong[cntrl].type = FF_RUMBLE;
 
1241
    ffstrong[cntrl].id = -1;
 
1242
    ffstrong[cntrl].u.rumble.strong_magnitude = 0xFFFF;
 
1243
    ffstrong[cntrl].u.rumble.weak_magnitude = 0x0000;
 
1244
    ffstrong[cntrl].replay.length = 500;
 
1245
    ffstrong[cntrl].replay.delay = 0;
 
1246
 
 
1247
    ioctl(controller[cntrl].event_joystick, EVIOCSFF, &ffstrong[cntrl]);
 
1248
 
 
1249
    ffweak[cntrl].type = FF_RUMBLE;
 
1250
    ffweak[cntrl].id = -1;
 
1251
    ffweak[cntrl].u.rumble.strong_magnitude = 0x0000;
 
1252
    ffweak[cntrl].u.rumble.weak_magnitude = 0xFFFF;
 
1253
    ffweak[cntrl].replay.length = 500;
 
1254
    ffweak[cntrl].replay.delay = 0;
 
1255
 
 
1256
    ioctl(controller[cntrl].event_joystick, EVIOCSFF, &ffweak[cntrl]);
 
1257
 
 
1258
    printf("["PLUGIN_NAME"]: Rumble activated on N64 joystick #%i\n", cntrl + 1);
 
1259
#endif /* __linux__ */
 
1260
}
 
1261
 
 
1262
/******************************************************************
 
1263
  Function: InitiateControllers
 
1264
  Purpose:  This function initialises how each of the controllers
 
1265
            should be handled.
 
1266
  input:    - The handle to the main window.
 
1267
            - A controller structure that needs to be filled for
 
1268
              the emulator to know how to handle each controller.
 
1269
  output:   none
 
1270
*******************************************************************/
 
1271
void InitiateControllers( CONTROL_INFO ControlInfo )
 
1272
{
 
1273
    int i;
 
1274
 
 
1275
    // reset controllers
 
1276
    memset( controller, 0, sizeof( SController ) * 4 );
 
1277
 
 
1278
    for ( i = 0; i < SDLK_LAST; i++)
 
1279
    {
 
1280
        myKeyState[i] = 0;
 
1281
    }
 
1282
 
 
1283
    // read configuration
 
1284
    read_configuration();
 
1285
 
 
1286
    for( i = 0; i < 4; i++ )
 
1287
    {
 
1288
        // test for rumble support for this joystick
 
1289
        InitiateRumble(i);
 
1290
        // if rumble not supported, switch to mempack
 
1291
        // Comment out if statement to test rumble on systems without necessary hardware.
 
1292
        if (controller[i].control.Plugin == PLUGIN_RAW && controller[i].event_joystick == 0)
 
1293
            controller[i].control.Plugin = PLUGIN_MEMPAK;
 
1294
        // copy control data struct to the core
 
1295
        memcpy( ControlInfo.Controls + i, &controller[i].control, sizeof( CONTROL ) );
 
1296
    }
 
1297
 
 
1298
    printf( "["PLUGIN_NAME"]: version "PLUGIN_VERSION" initialized.\n" );
 
1299
}
 
1300
 
 
1301
/******************************************************************
 
1302
  Function: ReadController
 
1303
  Purpose:  To process the raw data in the pif ram that is about to
 
1304
            be read.
 
1305
  input:    - Controller Number (0 to 3) and -1 signalling end of
 
1306
              processing the pif ram.
 
1307
            - Pointer of data to be processed.
 
1308
  output:   none
 
1309
  note:     This function is only needed if the DLL is allowing raw
 
1310
            data.
 
1311
*******************************************************************/
 
1312
void
 
1313
ReadController( int Control, BYTE *Command )
 
1314
{
 
1315
#if 0//def _DEBUG
 
1316
    printf( "\nRaw Read (cont=%d):\n", Control );
 
1317
    printf( "\t%02X %02X %02X %02X %02X %02X\n", Command[0], Command[1],
 
1318
            Command[2], Command[3], Command[4], Command[5]);//, Command[6], Command[7] );
 
1319
#endif
 
1320
}
 
1321
 
 
1322
/******************************************************************
 
1323
  Function: RomClosed
 
1324
  Purpose:  This function is called when a rom is closed.
 
1325
  input:    none
 
1326
  output:   none
 
1327
*******************************************************************/
 
1328
void
 
1329
RomClosed( void )
 
1330
{
 
1331
    int i;
 
1332
 
 
1333
    // close joysticks
 
1334
    for( i = 0; i < 4; i++ )
 
1335
        if( controller[i].joystick )
 
1336
        {
 
1337
            SDL_JoystickClose( controller[i].joystick );
 
1338
            controller[i].joystick = NULL;
 
1339
        }
 
1340
 
 
1341
    // quit SDL joystick subsystem
 
1342
    SDL_QuitSubSystem( SDL_INIT_JOYSTICK );
 
1343
 
 
1344
    // release/ungrab mouse
 
1345
    SDL_WM_GrabInput( SDL_GRAB_OFF );
 
1346
    SDL_ShowCursor( 1 );
 
1347
 
 
1348
    romopen = 0;
 
1349
}
 
1350
 
 
1351
/******************************************************************
 
1352
  Function: RomOpen
 
1353
  Purpose:  This function is called when a rom is open. (from the
 
1354
            emulation thread)
 
1355
  input:    none
 
1356
  output:   none
 
1357
*******************************************************************/
 
1358
void
 
1359
RomOpen( void )
 
1360
{
 
1361
    int i;
 
1362
 
 
1363
    // init SDL joystick subsystem
 
1364
    if( !SDL_WasInit( SDL_INIT_JOYSTICK ) )
 
1365
        if( SDL_InitSubSystem( SDL_INIT_JOYSTICK ) == -1 )
 
1366
        {
 
1367
            fprintf( stderr, "["PLUGIN_NAME"]: Couldn't init SDL joystick subsystem: %s\n", SDL_GetError() );
 
1368
            return;
 
1369
        }
 
1370
 
 
1371
    // open joysticks
 
1372
    for( i = 0; i < 4; i++ )
 
1373
        if( controller[i].device >= 0 )
 
1374
        {
 
1375
            controller[i].joystick = SDL_JoystickOpen( controller[i].device );
 
1376
            if( controller[i].joystick == NULL )
 
1377
                fprintf( stderr, "["PLUGIN_NAME"]: Couldn't open joystick for controller #%d: %s\n", i, SDL_GetError() );
 
1378
        }
 
1379
        else
 
1380
            controller[i].joystick = NULL;
 
1381
 
 
1382
    // grab mouse
 
1383
    if (controller[0].mouse || controller[1].mouse || controller[2].mouse || controller[3].mouse)
 
1384
    {
 
1385
        SDL_ShowCursor( 0 );
 
1386
        if (SDL_WM_GrabInput( SDL_GRAB_ON ) != SDL_GRAB_ON)
 
1387
        {
 
1388
            fprintf( stderr, "["PLUGIN_NAME"]: Couldn't grab input! Mouse support won't work!\n" );
 
1389
            fprintf( stderr, "["PLUGIN_NAME"]: Note: You have to set your graphics window fullscreen in order for this to work!\n" );
 
1390
        }
 
1391
    }
 
1392
 
 
1393
    romopen = 1;
 
1394
}
 
1395
 
 
1396
static SDLKey
 
1397
translateKey( WPARAM wParam )
 
1398
{
 
1399
    SDLKey key = 0;
 
1400
 
 
1401
    // for a-z and 0-9 keys windows provides no defines
 
1402
    if (wParam >= 0x41 && wParam <= 0x5a) {
 
1403
        key = wParam - 0x41 + SDLK_a;
 
1404
    } else if (wParam >= 0x30 && wParam <= 0x39) {
 
1405
        key = wParam - 0x30 + SDLK_0;
 
1406
    } else if (wParam == VK_RETURN) {
 
1407
        key = SDLK_RETURN;
 
1408
    } else if (wParam == VK_SPACE) {
 
1409
        key = SDLK_SPACE;
 
1410
    } else if (wParam == VK_LEFT) {
 
1411
        key = SDLK_LEFT;
 
1412
    } else if (wParam == VK_RIGHT) {
 
1413
        key = SDLK_RIGHT;
 
1414
    } else if (wParam == VK_UP) {
 
1415
        key = SDLK_UP;
 
1416
    } else if (wParam == VK_DOWN) {
 
1417
        key = SDLK_DOWN;
 
1418
    }
 
1419
 
 
1420
    return key;
 
1421
}
 
1422
 
 
1423
/******************************************************************
 
1424
  Function: WM_KeyDown
 
1425
  Purpose:  To pass the WM_KeyDown message from the emulator to the
 
1426
            plugin.
 
1427
  input:    wParam and lParam of the WM_KEYDOWN message.
 
1428
  output:   none
 
1429
*******************************************************************/
 
1430
void
 
1431
WM_KeyDown( WPARAM wParam, LPARAM lParam )
 
1432
{
 
1433
    myKeyState[translateKey(wParam)] = 1;
 
1434
}
 
1435
 
 
1436
/******************************************************************
 
1437
  Function: WM_KeyUp
 
1438
  Purpose:  To pass the WM_KEYUP message from the emulator to the
 
1439
            plugin.
 
1440
  input:    wParam and lParam of the WM_KEYDOWN message.
 
1441
  output:   none
 
1442
*******************************************************************/
 
1443
void
 
1444
WM_KeyUp( WPARAM wParam, LPARAM lParam )
 
1445
{
 
1446
    myKeyState[translateKey(wParam)] = 0;
 
1447
}
 
1448
 
 
1449
/******************************************************************
 
1450
   NOTE: THIS HAS BEEN ADDED FOR MUPEN64PLUS AND IS NOT PART OF THE
 
1451
         ORIGINAL SPEC
 
1452
  Function: SetConfigDir
 
1453
  Purpose:  To pass the location where config files should be read/
 
1454
            written to.
 
1455
  input:    path to config directory
 
1456
  output:   none
 
1457
*******************************************************************/
 
1458
void
 
1459
SetConfigDir( char *configDir )
 
1460
{
 
1461
    strncpy(configdir, configDir, PATH_MAX);
 
1462
}
 
1463