|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Input devices
5: *
6: * Copyright 1995-2004 Bernd Schmidt
7: * Copyright 1995 Alessandro Bissacco
8: * Copyright 2000-2004 Toni Wilen
9: */
10:
11: #include "sysconfig.h"
12: #include "sysdeps.h"
13:
14: #include <ctype.h>
15: #include <assert.h>
16:
17: #include "config.h"
18: #include "options.h"
19: #include "threaddep/thread.h"
20: #include "uae.h"
21: #include "custom.h"
22: #include "xwin.h"
23: #include "memory.h"
24: #include "newcpu.h"
25: #include "drawing.h"
26: #include "picasso96.h"
27: #include "inputdevice.h"
28:
29: /* Mouse and joystick emulation */
30:
31: int buttonstate[3];
32: int mouse_x, mouse_y;
33: int joy0button, joy1button;
34: unsigned int joy0dir, joy1dir;
35:
36: /* Mousehack stuff */
37:
38: #define defstepx (1<<16)
39: #define defstepy (1<<16)
40: #define defxoffs 0
41: #define defyoffs 0
42:
43: static const int docal = 60, xcaloff = 40, ycaloff = 20;
44: static const int calweight = 3;
45: static int lastsampledmx, lastsampledmy;
46: static int lastspr0x,lastspr0y,lastdiffx,lastdiffy,spr0pos,spr0ctl;
47: static int mstepx,mstepy,xoffs=defxoffs,yoffs=defyoffs;
48: static int sprvbfl;
49:
50: int lastmx, lastmy;
51: int newmousecounters;
52: int ievent_alive = 0;
53:
54: enum mousestate mousestate;
55:
56: void mousehack_setdontcare (void)
57: {
58: if (mousestate == dont_care_mouse)
59: return;
60:
61: write_log ("Don't care mouse mode set\n");
62: mousestate = dont_care_mouse;
63: lastspr0x = lastmx; lastspr0y = lastmy;
64: mstepx = defstepx; mstepy = defstepy;
65: }
66:
67: void mousehack_setfollow (void)
68: {
69: if (mousestate == follow_mouse)
70: return;
71:
72: write_log ("Follow sprite mode set\n");
73: mousestate = follow_mouse;
74: lastdiffx = lastdiffy = 0;
75: sprvbfl = 0;
76: spr0ctl = spr0pos = 0;
77: mstepx = defstepx; mstepy = defstepy;
78: }
79:
80: uae_u32 mousehack_helper (void)
81: {
82: int mousexpos, mouseypos;
83:
84: #ifdef PICASSO96
85: if (picasso_on) {
86: picasso_clip_mouse (&lastmx, &lastmy);
87: mousexpos = lastmx;
88: mouseypos = lastmy;
89: } else
90: #endif
91: {
92: /* @@@ This isn't completely right, it doesn't deal with virtual
93: screen sizes larger than physical very well. */
94: if (lastmy >= gfxvidinfo.height)
95: lastmy = gfxvidinfo.height - 1;
96: if (lastmy < 0)
97: lastmy = 0;
98: if (lastmx < 0)
99: lastmx = 0;
100: if (lastmx >= gfxvidinfo.width)
101: lastmx = gfxvidinfo.width - 1;
102: mouseypos = coord_native_to_amiga_y (lastmy) << 1;
103: mousexpos = coord_native_to_amiga_x (lastmx);
104: }
105:
106: switch (m68k_dreg (regs, 0)) {
107: case 0:
108: return ievent_alive ? -1 : needmousehack ();
109: case 1:
110: ievent_alive = 10;
111: return mousexpos;
112: case 2:
113: return mouseypos;
114: }
115: return 0;
116: }
117:
118: void togglemouse (void)
119: {
120: switch (mousestate) {
121: case dont_care_mouse: mousehack_setfollow (); break;
122: case follow_mouse: mousehack_setdontcare (); break;
123: default: break; /* Nnnnnghh! */
124: }
125: }
126:
127: STATIC_INLINE int adjust (int val)
128: {
129: if (val > 127)
130: return 127;
131: else if (val < -127)
132: return -127;
133: return val;
134: }
135:
136: void do_mouse_hack (void)
137: {
138: int spr0x = ((spr0pos & 0xff) << 2) | ((spr0ctl & 1) << 1);
139: int spr0y = ((spr0pos >> 8) | ((spr0ctl & 4) << 6)) << 1;
140: int diffx, diffy;
141:
142: if (ievent_alive > 0) {
143: mouse_x = mouse_y = 0;
144: return;
145: }
146: switch (mousestate) {
147: case normal_mouse:
148: diffx = lastmx - lastsampledmx;
149: diffy = lastmy - lastsampledmy;
150: if (!newmousecounters) {
151: if (diffx > 127) diffx = 127;
152: if (diffx < -127) diffx = -127;
153: mouse_x += diffx;
154: if (diffy > 127) diffy = 127;
155: if (diffy < -127) diffy = -127;
156: mouse_y += diffy;
157: }
158: lastsampledmx += diffx; lastsampledmy += diffy;
159: break;
160:
161: case dont_care_mouse:
162: diffx = adjust (((lastmx - lastspr0x) * mstepx) >> 16);
163: diffy = adjust (((lastmy - lastspr0y) * mstepy) >> 16);
164: lastspr0x = lastmx; lastspr0y = lastmy;
165: mouse_x += diffx; mouse_y += diffy;
166: break;
167:
168: case follow_mouse:
169: if (sprvbfl && sprvbfl-- > 1) {
170: int mousexpos, mouseypos;
171:
172: if ((lastdiffx > docal || lastdiffx < -docal)
173: && lastspr0x != spr0x
174: && spr0x > plfstrt*4 + 34 + xcaloff
175: && spr0x < plfstop*4 - xcaloff)
176: {
177: int val = (lastdiffx << 16) / (spr0x - lastspr0x);
178: if (val >= 0x8000)
179: mstepx = (mstepx * (calweight - 1) + val) / calweight;
180: }
181: if ((lastdiffy > docal || lastdiffy < -docal)
182: && lastspr0y != spr0y
183: && spr0y > plffirstline + ycaloff
184: && spr0y < plflastline - ycaloff)
185: {
186: int val = (lastdiffy << 16) / (spr0y - lastspr0y);
187: if (val >= 0x8000)
188: mstepy = (mstepy * (calweight - 1) + val) / calweight;
189: }
190: if (lastmy >= gfxvidinfo.height)
191: lastmy = gfxvidinfo.height-1;
192: mouseypos = coord_native_to_amiga_y (lastmy) << 1;
193: mousexpos = coord_native_to_amiga_x (lastmx);
194: diffx = adjust ((((mousexpos + xoffs - spr0x) & ~1) * mstepx) >> 16);
195: diffy = adjust ((((mouseypos + yoffs - spr0y) & ~1) * mstepy) >> 16);
196: lastspr0x = spr0x; lastspr0y = spr0y;
197: lastdiffx = diffx; lastdiffy = diffy;
198: mouse_x += diffx; mouse_y += diffy;
199: }
200: break;
201:
202: default:
203: abort ();
204: }
205: }
206:
207: void mousehack_handle (int ctl, int pos)
208: {
209: if (!sprvbfl && ((pos & 0xff) << 2) > 2 * DISPLAY_LEFT_SHIFT) {
210: spr0ctl = ctl;
211: spr0pos = pos;
212: sprvbfl = 2;
213: }
214: }
215:
216: uae_u16 potgo_value;
217:
218: void POTGO (uae_u16 v)
219: {
220: potgo_value = v;
221: }
222:
223: uae_u16 POTGOR (void)
224: {
225: uae_u16 v = (potgo_value | (potgo_value >> 1)) & 0x5500;
226:
227: v |= (~potgo_value & 0xAA00) >> 1;
228:
229: if (JSEM_ISMOUSE (0, &currprefs)) {
230: if (buttonstate[2])
231: v &= 0xFBFF;
232:
233: if (buttonstate[1])
234: v &= 0xFEFF;
235: } else if (JSEM_ISJOY0 (0, &currprefs) || JSEM_ISJOY1 (0, &currprefs)) {
236: if (joy0button & 2) v &= 0xfbff;
237: if (joy0button & 4) v &= 0xfeff;
238: }
239:
240: if (JSEM_ISJOY0 (1, &currprefs) || JSEM_ISJOY1 (1, &currprefs)) {
241: if (joy1button & 2) v &= 0xbfff;
242: if (joy1button & 4) v &= 0xefff;
243: }
244:
245: return v;
246: }
247:
248: uae_u16 POT0DAT (void)
249: {
250: static uae_u16 cnt = 0;
251: if (JSEM_ISMOUSE (0, &currprefs)) {
252: if (buttonstate[2])
253: cnt = ((cnt + 1) & 0xFF) | (cnt & 0xFF00);
254: if (buttonstate[1])
255: cnt += 0x100;
256: }
257:
258: return cnt;
259: }
260: uae_u16 JOY0DAT (void)
261: {
262: if (JSEM_ISMOUSE (0, &currprefs)) {
263: do_mouse_hack ();
264: return ((uae_u8)mouse_x) + ((uae_u16)mouse_y << 8);
265: }
266: return joy0dir;
267: }
268: uae_u16 JOY1DAT (void)
269: {
270: if (JSEM_ISMOUSE (1, &currprefs)) {
271: do_mouse_hack ();
272: return ((uae_u8)mouse_x) + ((uae_u16)mouse_y << 8);
273: }
274: return joy1dir;
275: }
276: void JOYTEST (uae_u16 v)
277: {
278: if (JSEM_ISMOUSE (0, &currprefs)) {
279: mouse_x = v & 0xFC;
280: mouse_y = (v >> 8) & 0xFC;
281: }
282: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.