1 /*****************************************************************************
2 ** $Source: /cygdrive/d/Private/_SVNROOT/bluemsx/blueMSX/Src/Input/MsxMouse.c,v $
3 **
4 ** $Revision: 1.3 $
5 **
6 ** $Date: 2008-03-30 18:38:40 $
7 **
8 ** More info: http://www.bluemsx.com
9 **
10 ** Copyright (C) 2003-2006 Daniel Vik
11 **
12 ** This program is free software; you can redistribute it and/or modify
13 ** it under the terms of the GNU General Public License as published by
14 ** the Free Software Foundation; either version 2 of the License, or
15 ** (at your option) any later version.
16 **
17 ** This program is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ** GNU General Public License for more details.
21 **
22 ** You should have received a copy of the GNU General Public License
23 ** along with this program; if not, write to the Free Software
24 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 **
26 ******************************************************************************
27 */
28 #include "MsxMouse.h"
29 #include "InputEvent.h"
30 #include "ArchInput.h"
31 #include "Board.h"
32 #include "SaveState.h"
33
34 #include <stdlib.h>
35
36 struct MsxMouse {
37 MsxJoystickDevice joyDevice;
38 int dx;
39 int dy;
40 int count;
41 int mouseAsJoystick;
42 UInt8 oldValue;
43 UInt32 clock;
44 };
45
saveState(MsxMouse * mouse)46 static void saveState(MsxMouse* mouse)
47 {
48 SaveState* state = saveStateOpenForWrite("msxMouse");
49
50 saveStateSet(state, "dx", mouse->dx);
51 saveStateSet(state, "dy", mouse->dy);
52 saveStateSet(state, "count", mouse->count);
53 saveStateSet(state, "mouseAsJoystick", mouse->mouseAsJoystick);
54 saveStateSet(state, "oldValue", mouse->oldValue);
55 saveStateSet(state, "clock", mouse->clock);
56
57 saveStateClose(state);
58 }
59
loadState(MsxMouse * mouse)60 static void loadState(MsxMouse* mouse)
61 {
62 SaveState* state = saveStateOpenForRead("msxMouse");
63
64 mouse->dx = saveStateGet(state, "dx", 0);
65 mouse->dy = saveStateGet(state, "dy", 0);
66 mouse->count = saveStateGet(state, "count", 0);
67 mouse->mouseAsJoystick = saveStateGet(state, "mouseAsJoystick", 0);
68 mouse->oldValue = (UInt8)saveStateGet(state, "oldValue", 0);
69 mouse->clock = saveStateGet(state, "clock", 0);
70
71 saveStateClose(state);
72 }
73
read(MsxMouse * mouse)74 static UInt8 read(MsxMouse* mouse)
75 {
76 UInt8 state = 0x3f;
77 UInt32 systemTime = boardSystemTime();
78
79 if (mouse->mouseAsJoystick) {
80 if (systemTime - mouse->clock > boardFrequency() / 120) {
81 int dx;
82 int dy;
83
84 archMouseGetState(&dx, &dy);
85 mouse->clock = systemTime;
86
87 mouse->dx = (dx > 127 ? 127 : (dx < -127 ? -127 : dx));
88 mouse->dy = (dy > 127 ? 127 : (dy < -127 ? -127 : dy));
89 }
90
91 if ((mouse->oldValue & 0x04) == 0) {
92 state = ((mouse->dx / 3) ? ((mouse->dx > 0) ? 0x08 : 0x04) : 0x0c) |
93 ((mouse->dy / 3) ? ((mouse->dy > 0) ? 0x02 : 0x01) : 0x03);
94 }
95 }
96 else {
97 switch (mouse->count) {
98 case 0:
99 state = (mouse->dx >> 4) & 0x0f;
100 break;
101 case 1:
102 state = mouse->dx & 0x0f;
103 break;
104 case 2:
105 state =(mouse->dy >> 4) & 0x0f;
106 break;
107 case 3:
108 state = mouse->dy & 0x0f;
109 break;
110 }
111 }
112
113 state |= (~archMouseGetButtonState(0) << 4) & 0x30;
114
115 return state;
116 }
117
write(MsxMouse * mouse,UInt8 value)118 static void write(MsxMouse* mouse, UInt8 value)
119 {
120 UInt32 systemTime = boardSystemTime();
121
122 if (mouse->mouseAsJoystick) {
123 return;
124 }
125
126 if ((value ^ mouse->oldValue) & 0x04) {
127 if (systemTime - mouse->clock > boardFrequency() / 2500) {
128 mouse->count = 0;
129 }
130 else {
131 mouse->count = (mouse->count + 1) & 3;
132 }
133
134 mouse->clock = systemTime;
135
136 if (mouse->count == 0) {
137 int dx;
138 int dy;
139 archMouseGetState(&dx, &dy);
140 mouse->clock = systemTime;
141 mouse->dx = (dx > 127 ? 127 : (dx < -127 ? -127 : dx));
142 mouse->dy = (dy > 127 ? 127 : (dy < -127 ? -127 : dy));
143 }
144 }
145 mouse->oldValue = value;
146 }
147
reset(MsxMouse * mouse)148 static void reset(MsxMouse* mouse) {
149 mouse->dx = 0;
150 mouse->dy = 0;
151 mouse->count = 0;
152 mouse->clock = 0;
153 mouse->oldValue = 0;
154 }
155
msxMouseCreate()156 MsxJoystickDevice* msxMouseCreate()
157 {
158 MsxMouse* mouse = (MsxMouse*)calloc(1, sizeof(MsxMouse));
159 mouse->joyDevice.read = read;
160 mouse->joyDevice.write = write;
161 mouse->joyDevice.reset = reset;
162 mouse->joyDevice.loadState = loadState;
163 mouse->joyDevice.saveState = saveState;
164
165 reset(mouse);
166
167 return (MsxJoystickDevice*)mouse;
168 }