~ubuntu-branches/ubuntu/quantal/vice/quantal

« back to all changes in this revision

Viewing changes to src/mouse.c

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2009-03-31 00:37:15 UTC
  • mfrom: (1.1.7 upstream) (9.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20090331003715-i5yisvcfv7mgz3eh
Tags: 2.1.dfsg-1
* New major upstream release (closes: #495937).
* Add desktop files (closes: #501181).

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 * Written by
5
5
 *  Andreas Boose <viceteam@t-online.de>
6
6
 *
 
7
 * NEOS and Amiga mouse support by
 
8
 *  H.Nuotio <hannu.nuotio@pp.inet.fi>
 
9
 *
7
10
 * This file is part of VICE, the Versatile Commodore Emulator.
8
11
 * See README for copyright notice.
9
12
 *
28
31
 
29
32
#include <stdio.h>
30
33
 
 
34
#include "alarm.h"
31
35
#include "cmdline.h"
32
36
#include "joystick.h"
 
37
#include "maincpu.h"
33
38
#include "mouse.h"
34
39
#include "mousedrv.h"
35
40
#include "resources.h"
36
 
#ifdef HAS_TRANSLATION
37
41
#include "translate.h"
38
 
#endif
 
42
 
 
43
#define NEOS_RESET_CLK 100
 
44
struct alarm_s *neosmouse_alarm;
39
45
 
40
46
int _mouse_enabled = 0;
41
47
 
42
 
static int mouse_port;
43
 
 
 
48
int mouse_port;
 
49
int mouse_type;
 
50
 
 
51
int neos_and_amiga_buttons;
 
52
int neos_prev;
 
53
 
 
54
BYTE neos_x;
 
55
BYTE neos_y;
 
56
BYTE neos_lastx;
 
57
BYTE neos_lasty;
 
58
 
 
59
enum {
 
60
    NEOS_IDLE = 0,
 
61
    NEOS_XH,
 
62
    NEOS_XL,
 
63
    NEOS_YH,
 
64
    NEOS_YL,
 
65
    NEOS_DONE
 
66
} neos_state = NEOS_IDLE;
 
67
 
 
68
void neos_get_new_movement(void)
 
69
{
 
70
    BYTE new_x, new_y;
 
71
    
 
72
    new_x = mousedrv_get_x();
 
73
    new_y = mousedrv_get_y();
 
74
    neos_x = new_x - neos_lastx;
 
75
    if (new_x < neos_lastx)
 
76
    {
 
77
        if (neos_lastx > 0x6f && new_x < 0x10)
 
78
        {
 
79
            neos_x += 0x80;
 
80
        }
 
81
    }
 
82
    else if (new_x > neos_lastx)
 
83
    {
 
84
        if(neos_lastx < 0x10 && new_x > 0x6f)
 
85
        {
 
86
            neos_x += 0x80;
 
87
        }
 
88
    }
 
89
    neos_lastx = new_x;
 
90
 
 
91
    neos_y = new_y - neos_lasty;
 
92
    if (new_y < neos_lasty)
 
93
    {
 
94
        if (neos_lasty > 0x6f && new_y < 0x10)
 
95
        {
 
96
            neos_y += 0x80;
 
97
        }
 
98
    }
 
99
    else if (new_y > neos_lasty)
 
100
    {
 
101
        if (neos_lasty < 0x10 && new_y > 0x6f)
 
102
        {
 
103
            neos_y += 0x80;
 
104
        }
 
105
    }
 
106
    neos_lasty = new_y;
 
107
 
 
108
    neos_x = (neos_x & 0x80) ? (neos_x / 2) | 0x80 : neos_x / 2;
 
109
    neos_y = (neos_y & 0x80) ? (neos_y / 2) | 0x80 : neos_y / 2;
 
110
    neos_x = -neos_x;
 
111
}
 
112
 
 
113
void neos_mouse_store(BYTE val) 
 
114
{
 
115
    switch (neos_state)
 
116
    {
 
117
        case NEOS_IDLE:
 
118
            if (((val & 16) ^ (neos_prev & 16)) && ((val & 16)==0))
 
119
            {
 
120
                ++neos_state;
 
121
                neos_get_new_movement();
 
122
            }
 
123
            break;
 
124
        case NEOS_XH:
 
125
            if (((val & 16) ^ (neos_prev & 16)) && ((val & 16)!=0))
 
126
                ++neos_state;
 
127
            break;
 
128
        case NEOS_XL:
 
129
            if (((val & 16) ^ (neos_prev & 16)) && ((val & 16)==0))
 
130
                ++neos_state;
 
131
            break;
 
132
        case NEOS_YH:
 
133
            if (((val & 16) ^ (neos_prev & 16)) && ((val & 16)!=0))
 
134
            {
 
135
                ++neos_state;
 
136
                alarm_set(neosmouse_alarm, maincpu_clk + NEOS_RESET_CLK);
 
137
            }
 
138
            break;
 
139
        case NEOS_YL:
 
140
            ++neos_state;
 
141
            break;
 
142
        case NEOS_DONE:
 
143
        default:
 
144
            break;
 
145
    }
 
146
    neos_prev = val;
 
147
}
 
148
 
 
149
BYTE neos_mouse_read(void)
 
150
{
 
151
    switch (neos_state)
 
152
    {
 
153
        case NEOS_XH:
 
154
            return ((neos_x >> 4) & 0xf) | 0xf0;
 
155
            break;
 
156
        case NEOS_XL:
 
157
            return (neos_x & 0xf) | 0xf0;
 
158
            break;
 
159
        case NEOS_YH:
 
160
            return ((neos_y >> 4) & 0xf) | 0xf0;
 
161
            break;
 
162
        case NEOS_YL:
 
163
            return (neos_y & 0xf) | 0xf0;
 
164
            break;
 
165
        case NEOS_IDLE:
 
166
        case NEOS_DONE:
 
167
        default:
 
168
            return 0xff;
 
169
            break;
 
170
    }
 
171
}
 
172
 
 
173
 
 
174
void neosmouse_alarm_handler(CLOCK offset, void *data)
 
175
{
 
176
    alarm_unset(neosmouse_alarm);
 
177
    neos_state = NEOS_IDLE;
 
178
}
 
179
 
 
180
/* Amiga mouse support is currently experimental */
 
181
 
 
182
BYTE amiga_mouse_table[4] = { 0x0, 0x1, 0x5, 0x4 };
 
183
 
 
184
/* the method below results in alot of overflows */
 
185
#if 0
 
186
BYTE amiga_mouse_read(void)
 
187
{
 
188
    BYTE new_x, new_y;
 
189
    
 
190
    new_x = mousedrv_get_x()/2;
 
191
    new_y = (-mousedrv_get_y())/2;
 
192
 
 
193
    return (amiga_mouse_table[new_x & 3] << 1) | amiga_mouse_table[new_y & 
 
194
3] | 0xf0;
 
195
}
 
196
#endif
 
197
 
 
198
/* the alternate method below doesn't keep track of the speed of
 
199
   the mouse movements, just the direction.
 
200
 */
 
201
 
 
202
static BYTE old_x = 0;
 
203
static BYTE old_y = 0;
 
204
static BYTE x_count = 0;
 
205
static BYTE y_count = 0;
 
206
 
 
207
BYTE amiga_mouse_read(void)
 
208
{
 
209
    BYTE new_x, new_y;
 
210
    signed char dir_x, dir_y;
 
211
    
 
212
    /* get the new mouse values */
 
213
    new_x = mousedrv_get_x();
 
214
    new_y = (-mousedrv_get_y());
 
215
 
 
216
    /* find out the x direction */
 
217
    if (new_x == old_x)
 
218
    {
 
219
        /* no direction, 0 */
 
220
        dir_x = 0;
 
221
    }
 
222
    else
 
223
    {
 
224
        if (new_x > old_x)
 
225
        {
 
226
            if ((new_x - old_x) < (old_x + 256 - new_x))
 
227
            {
 
228
                /* right, +1 */
 
229
                dir_x = 1;
 
230
            }
 
231
            else
 
232
            {
 
233
                /* left underflow, -1 */
 
234
                dir_x = -1;
 
235
            }
 
236
        }
 
237
        else
 
238
        {
 
239
            if ((old_x - new_x) < (new_x + 256 - old_x))
 
240
            {
 
241
                /* left, -1 */
 
242
                dir_x = -1;
 
243
            }
 
244
            else
 
245
            {
 
246
                /* right overflow, +1 */
 
247
                dir_x = 1;
 
248
            }
 
249
        }
 
250
    }
 
251
 
 
252
    /* find out the y direction */
 
253
    if (new_y == old_y)
 
254
    {
 
255
        dir_y = 0;
 
256
    }
 
257
    else
 
258
    {
 
259
        if (new_y > old_y)
 
260
        {
 
261
            if ((new_y - old_y) < (old_y + 256 - new_y))
 
262
            {
 
263
                dir_y = 1;
 
264
            }
 
265
            else
 
266
            {
 
267
                dir_y = -1;
 
268
            }
 
269
        }
 
270
        else
 
271
        {
 
272
            if ((old_y - new_y) < (new_y + 256 - old_y))
 
273
            {
 
274
                dir_y = -1;
 
275
            }
 
276
            else
 
277
            {
 
278
                dir_y = 1;
 
279
            }
 
280
        }
 
281
    }
 
282
 
 
283
    /* store new values as old values */
 
284
    old_x = new_x;
 
285
    old_y = new_y;
 
286
 
 
287
    /* add x direction to x counter */
 
288
    x_count += dir_x;
 
289
 
 
290
    /* add y direction to y counter */
 
291
    y_count += dir_y;
 
292
 
 
293
    return (amiga_mouse_table[x_count & 3] << 1) | amiga_mouse_table[y_count & 3] | 0xf0;
 
294
}
44
295
 
45
296
static int set_mouse_enabled(int val, void *param)
46
297
{
59
310
    return 0;
60
311
}
61
312
 
 
313
static int set_mouse_type(int val, void *param)
 
314
{
 
315
    if (!((val >= 0) && (val <= 2)))
 
316
        return -1;
 
317
 
 
318
    mouse_type = val;
 
319
 
 
320
    return 0;
 
321
}
 
322
 
62
323
static const resource_int_t resources_int[] = {
63
324
    { "Mouse", 0, RES_EVENT_SAME, NULL,
64
325
      &_mouse_enabled, set_mouse_enabled, NULL },
65
326
    { "Mouseport", 1, RES_EVENT_SAME, NULL,
66
327
      &mouse_port, set_mouse_port, NULL },
 
328
    { "Mousetype", MOUSE_TYPE_1351, RES_EVENT_SAME, NULL,
 
329
      &mouse_type, set_mouse_type, NULL },
67
330
    { NULL }
68
331
};
69
332
 
75
338
    return mousedrv_resources_init();
76
339
}
77
340
 
78
 
#ifdef HAS_TRANSLATION
79
 
static const cmdline_option_t cmdline_options[] = {
80
 
    { "-mouse", SET_RESOURCE, 1, NULL, NULL,
81
 
      "Mouse", NULL, 0, IDCLS_ENABLE_1351_MOUSE },
82
 
    { "+mouse", SET_RESOURCE, 0, NULL, NULL,
83
 
      "Mouse", NULL, 0, IDCLS_DISABLE_1351_MOUSE },
84
 
    { "-mouseport", SET_RESOURCE, 1, NULL, NULL,
85
 
      "Mouseport", NULL, IDCLS_P_VALUE, IDCLS_SELECT_MOUSE_JOY_PORT },
86
 
    { NULL }
87
 
};
88
 
#else
89
 
static const cmdline_option_t cmdline_options[] = {
90
 
    { "-mouse", SET_RESOURCE, 1, NULL, NULL,
91
 
      "Mouse", NULL, NULL, N_("Enable emulation of the 1351 proportional mouse") },
92
 
    { "+mouse", SET_RESOURCE, 0, NULL, NULL,
93
 
      "Mouse", NULL, NULL, N_("Disable emulation of the 1351 proportional mouse") },
94
 
    { "-mouseport", SET_RESOURCE, 1, NULL, NULL,
95
 
      "Mouseport", NULL, N_("<value>"), N_("Select the joystick port the mouse is attached to") },
96
 
    { NULL }
97
 
};
98
 
#endif
 
341
static const cmdline_option_t cmdline_options[] = {
 
342
    { "-mouse", SET_RESOURCE, 0,
 
343
      NULL, NULL, "Mouse", (void *)1,
 
344
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
345
      IDCLS_UNUSED, IDCLS_ENABLE_MOUSE_GRAB,
 
346
      NULL, NULL },
 
347
    { "+mouse", SET_RESOURCE, 0,
 
348
      NULL, NULL, "Mouse", (void *)0,
 
349
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
350
      IDCLS_UNUSED, IDCLS_DISABLE_MOUSE_GRAB,
 
351
      NULL, NULL },
 
352
    { "-mouseport", SET_RESOURCE, 1,
 
353
      NULL, NULL, "Mouseport", NULL,
 
354
      USE_PARAM_ID, USE_DESCRIPTION_ID,
 
355
      IDCLS_P_VALUE, IDCLS_SELECT_MOUSE_JOY_PORT,
 
356
      NULL, NULL },
 
357
    { "-mousetype", SET_RESOURCE, 1,
 
358
      NULL, NULL, "Mousetype", NULL,
 
359
      USE_PARAM_ID, USE_DESCRIPTION_ID,
 
360
      IDCLS_P_VALUE, IDCLS_SELECT_MOUSE_TYPE,
 
361
      NULL, NULL },
 
362
    { NULL }
 
363
};
99
364
 
100
365
int mouse_cmdline_options_init(void)
101
366
{
107
372
 
108
373
void mouse_init(void)
109
374
{
 
375
    neos_and_amiga_buttons = 0;
 
376
    neos_prev = 0xff;
 
377
    neosmouse_alarm = alarm_new(maincpu_alarm_context, "NEOSMOUSEAlarm", neosmouse_alarm_handler, NULL);
110
378
    mousedrv_init();
111
379
}
112
380
 
121
389
 
122
390
void mouse_button_right(int pressed)
123
391
{
124
 
    if (pressed) {
125
 
        joystick_set_value_or(mouse_port, 1);
126
 
    } else {
127
 
        joystick_set_value_and(mouse_port, ~1);
 
392
    if (mouse_type != MOUSE_TYPE_1351)
 
393
    {
 
394
        if (pressed)
 
395
        {
 
396
            neos_and_amiga_buttons |= 1;
 
397
        }
 
398
        else
 
399
        {
 
400
            neos_and_amiga_buttons &= ~1;
 
401
        }
 
402
    }
 
403
    else
 
404
    {
 
405
        if (pressed)
 
406
        {
 
407
            joystick_set_value_or(mouse_port, 1);
 
408
        }
 
409
        else
 
410
        {
 
411
            joystick_set_value_and(mouse_port, ~1);
 
412
        }
128
413
    }
129
414
}
130
415
 
131
416
BYTE mouse_get_x(void)
132
417
{
133
 
    return mousedrv_get_x();
 
418
    return ((mouse_type == MOUSE_TYPE_1351) ? mousedrv_get_x() : (neos_and_amiga_buttons & 1) ? 0xff : 0);
134
419
}
135
420
 
136
421
BYTE mouse_get_y(void)
137
422
{
138
 
    return mousedrv_get_y();
 
423
    return ((mouse_type == MOUSE_TYPE_1351) ? mousedrv_get_y() : 0xff);
139
424
}
140