fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/arch/macplus/adb_mouse.c *
7 * Created: 2010-11-04 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2010-2012 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include "main.h"
24#include "adb.h"
25#include "adb_mouse.h"
26
27#include <stdlib.h>
28
29
30static
31void adb_mouse_del (adb_dev_t *dev)
32{
33 free (dev->ext);
34}
35
36static
37void adb_mouse_reset (adb_dev_t *dev)
38{
39 adb_mouse_t *mse;
40
41 mse = dev->ext;
42
43 adb_dev_reset (dev);
44
45 mse->change = 0;
46
47 mse->button = 0;
48 mse->dx = 0;
49 mse->dy = 0;
50
51 mse->talk_button = 0;
52 mse->talk_dx = 0;
53 mse->talk_dy = 0;
54
55 dev->reg[0] = 0x8080;
56}
57
58static
59void adb_mouse_flush (adb_dev_t *dev)
60{
61 adb_mouse_t *mse;
62
63 mse = dev->ext;
64
65 adb_dev_flush (dev);
66
67 mse->change = 0;
68
69 mse->button = 0;
70 mse->dx = 0;
71 mse->dy = 0;
72
73 mse->talk_button = 0;
74 mse->talk_dx = 0;
75 mse->talk_dy = 0;
76}
77
78static
79unsigned adb_mouse_get_val (int val)
80{
81 unsigned r;
82
83 if (val < 0) {
84 if (val < -63) {
85 val = -63;
86 }
87
88 r = -val;
89 r = (~r + 1) & 0x7f;
90 }
91 else {
92 if (val > 63) {
93 val = 63;
94 }
95
96 r = val;
97 }
98
99 return (r);
100}
101
102static
103unsigned adb_mouse_talk_0 (adb_dev_t *dev, void *buf)
104{
105 unsigned v;
106 adb_mouse_t *mse;
107 unsigned char *dst;
108
109 mse = dev->ext;
110 dst = buf;
111
112 if (mse->change == 0) {
113 return (0);
114 }
115
116 mse->talking = 1;
117
118 mse->talk_button = mse->button;
119 mse->talk_dx = mse->dx;
120 mse->talk_dy = mse->dy;
121
122 dev->reg[0] = 0x8080;
123
124 if (mse->talk_button & 1) {
125 dev->reg[0] &= 0x7fff;
126 }
127
128 v = adb_mouse_get_val (mse->talk_dx);
129 dev->reg[0] = (dev->reg[0] & 0xff80) | v;
130
131 v = adb_mouse_get_val (mse->talk_dy);
132 dev->reg[0] = (dev->reg[0] & 0x80ff) | (v << 8);
133
134 dst[0] = (dev->reg[0] >> 8) & 0xff;
135 dst[1] = dev->reg[0] & 0xff;
136
137 return (2);
138}
139
140static
141unsigned adb_mouse_talk (adb_dev_t *dev, unsigned reg, void *buf)
142{
143 if (reg == 0) {
144 return (adb_mouse_talk_0 (dev, buf));
145 }
146
147 return (adb_dev_talk (dev, reg, buf));
148}
149
150static
151void adb_mouse_talk_done (adb_dev_t *dev, unsigned reg)
152{
153 adb_mouse_t *mse;
154
155 mse = dev->ext;
156
157 if (reg == 0) {
158 if (mse->talking == 0) {
159 return;
160 }
161
162 mse->talking = 0;
163
164 mse->change = 0;
165
166 if (mse->talk_button != mse->button) {
167 mse->change = 1;
168 }
169
170 mse->dx -= mse->talk_dx;
171 mse->dy -= mse->talk_dy;
172
173 if ((mse->dx != 0) || (mse->dy != 0)) {
174 mse->change = 1;
175 }
176
177 dev->service_request = mse->change;
178 }
179}
180
181void adb_mouse_move (adb_mouse_t *mse, unsigned button, int dx, int dy)
182{
183 if ((mse->button ^ button) & 1) {
184 mse->change = 1;
185 }
186
187 mse->button = button;
188
189 mse->dx += dx;
190 mse->dy += dy;
191
192 if ((mse->dx != 0) || (mse->dy != 0)) {
193 mse->change = 1;
194 }
195
196 mse->dev.service_request = mse->change;
197}
198
199void adb_mouse_init (adb_mouse_t *mse)
200{
201 adb_dev_init (&mse->dev, 3, 1);
202
203 mse->dev.ext = mse;
204
205 mse->dev.del = adb_mouse_del;
206
207 mse->dev.reset = adb_mouse_reset;
208 mse->dev.flush = adb_mouse_flush;
209 mse->dev.talk = adb_mouse_talk;
210 mse->dev.talk_done = adb_mouse_talk_done;
211
212 mse->change = 0;
213
214 mse->button = 0;
215 mse->dx = 0;
216 mse->dy = 0;
217
218 mse->talk_button = 0;
219 mse->talk_dx = 0;
220 mse->talk_dy = 0;
221}
222
223adb_mouse_t *adb_mouse_new (void)
224{
225 adb_mouse_t *mse;
226
227 mse = malloc (sizeof (adb_mouse_t));
228
229 if (mse == NULL) {
230 return (NULL);
231 }
232
233 adb_mouse_init (mse);
234
235 return (mse);
236}