Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
56 | pj | 1 | /* |
2 | * PC/HW routine collection v1.2 for DOS/DJGPP |
||
3 | * |
||
4 | * Copyright (C) 2002 - Borca Daniel |
||
5 | * Email : dborca@yahoo.com |
||
6 | * Web : http://www.geocities.com/dborca |
||
7 | */ |
||
8 | |||
9 | |||
10 | #include <dpmi.h> |
||
11 | |||
12 | #include "pc_hw.h" |
||
13 | |||
14 | |||
15 | |||
16 | #define MOUSE_STACK_SIZE 16384 |
||
17 | |||
18 | #define CLEAR_MICKEYS() \ |
||
19 | do { \ |
||
20 | __asm __volatile ("movw $0xb, %%ax; int $0x33":::"%eax", "%ecx", "%edx"); \ |
||
21 | ox = oy = 0; \ |
||
22 | } while (0) |
||
23 | |||
24 | extern void mouse_wrapper (void); |
||
25 | extern void mouse_wrapper_end (void); |
||
26 | |||
27 | static MFUNC mouse_func; |
||
28 | static void *mouse_stack; |
||
29 | static long mouse_callback; |
||
30 | static __dpmi_regs mouse_regs; |
||
31 | |||
32 | static volatile int pc_mouse_x, pc_mouse_y, pc_mouse_b; |
||
33 | |||
34 | static int minx = 0; |
||
35 | static int maxx = 319; |
||
36 | static int miny = 0; |
||
37 | static int maxy = 199; |
||
38 | |||
39 | static int sx = 2; |
||
40 | static int sy = 2; |
||
41 | |||
42 | static int emulat3 = FALSE; |
||
43 | |||
44 | static int ox, oy; |
||
45 | |||
46 | static void mouse (__dpmi_regs *r) |
||
47 | { |
||
48 | int nx = (signed short)r->x.si / sx; |
||
49 | int ny = (signed short)r->x.di / sy; |
||
50 | int dx = nx - ox; |
||
51 | int dy = ny - oy; |
||
52 | ox = nx; |
||
53 | oy = ny; |
||
54 | |||
55 | pc_mouse_b = r->x.bx; |
||
56 | pc_mouse_x = MID(minx, pc_mouse_x + dx, maxx); |
||
57 | pc_mouse_y = MID(miny, pc_mouse_y + dy, maxy); |
||
58 | |||
59 | if (emulat3) { |
||
60 | if ((pc_mouse_b&3)==3) { |
||
61 | pc_mouse_b = 4; |
||
62 | } |
||
63 | } |
||
64 | |||
65 | if (mouse_func) { |
||
66 | mouse_func(pc_mouse_x, pc_mouse_y, pc_mouse_b); |
||
67 | } |
||
68 | } ENDOFUNC(mouse) |
||
69 | |||
70 | void pc_remove_mouse (void) |
||
71 | { |
||
72 | if (mouse_callback) { |
||
73 | pc_clexit(pc_remove_mouse); |
||
74 | __asm("\n\ |
||
75 | movl %%edx, %%ecx \n\ |
||
76 | shrl $16, %%ecx \n\ |
||
77 | movw $0x0304, %%ax \n\ |
||
78 | int $0x31 \n\ |
||
79 | movw $0x000c, %%ax \n\ |
||
80 | xorl %%ecx, %%ecx \n\ |
||
81 | int $0x33 \n\ |
||
82 | "::"d"(mouse_callback):"%eax", "%ecx"); |
||
83 | |||
84 | mouse_callback = 0; |
||
85 | |||
86 | free((void *)((unsigned long)mouse_stack-MOUSE_STACK_SIZE)); |
||
87 | } |
||
88 | } |
||
89 | |||
90 | int pc_install_mouse (void) |
||
91 | { |
||
92 | int buttons; |
||
93 | |||
94 | /* fail if already call-backed */ |
||
95 | if (mouse_callback) { |
||
96 | return 0; |
||
97 | } |
||
98 | |||
99 | /* reset mouse and get status */ |
||
100 | __asm("\n\ |
||
101 | xorl %%eax, %%eax \n\ |
||
102 | int $0x33 \n\ |
||
103 | andl %%ebx, %%eax \n\ |
||
104 | movl %%eax, %0 \n\ |
||
105 | ":"=g" (buttons)::"%eax", "%ebx"); |
||
106 | if (!buttons) { |
||
107 | return 0; |
||
108 | } |
||
109 | |||
110 | /* lock wrapper */ |
||
111 | LOCKDATA(mouse_func); |
||
112 | LOCKDATA(mouse_stack); |
||
113 | LOCKDATA(mouse_callback); |
||
114 | LOCKDATA(mouse_regs); |
||
115 | LOCKDATA(pc_mouse_x); |
||
116 | LOCKDATA(pc_mouse_y); |
||
117 | LOCKDATA(pc_mouse_b); |
||
118 | LOCKDATA(minx); |
||
119 | LOCKDATA(maxx); |
||
120 | LOCKDATA(miny); |
||
121 | LOCKDATA(maxy); |
||
122 | LOCKDATA(sx); |
||
123 | LOCKDATA(sy); |
||
124 | LOCKDATA(emulat3); |
||
125 | LOCKDATA(ox); |
||
126 | LOCKDATA(oy); |
||
127 | LOCKFUNC(mouse); |
||
128 | LOCKFUNC(mouse_wrapper); |
||
129 | |||
130 | /* grab a locked stack */ |
||
131 | if ((mouse_stack=pc_malloc(MOUSE_STACK_SIZE))==NULL) { |
||
132 | return 0; |
||
133 | } |
||
134 | |||
135 | /* try to hook a call-back */ |
||
136 | __asm("\n\ |
||
137 | pushl %%ds \n\ |
||
138 | pushl %%es \n\ |
||
139 | movw $0x0303, %%ax \n\ |
||
140 | pushl %%ds \n\ |
||
141 | pushl %%cs \n\ |
||
142 | popl %%ds \n\ |
||
143 | popl %%es \n\ |
||
144 | int $0x31 \n\ |
||
145 | popl %%es \n\ |
||
146 | popl %%ds \n\ |
||
147 | jc 0f \n\ |
||
148 | shll $16, %%ecx \n\ |
||
149 | movw %%dx, %%cx \n\ |
||
150 | movl %%ecx, %0 \n\ |
||
151 | 0: \n\ |
||
152 | ":"=g"(mouse_callback) |
||
153 | :"S" (mouse_wrapper), "D"(&mouse_regs) |
||
154 | :"%eax", "%ecx", "%edx"); |
||
155 | if (!mouse_callback) { |
||
156 | free(mouse_stack); |
||
157 | return 0; |
||
158 | } |
||
159 | |||
160 | /* adjust stack */ |
||
161 | mouse_stack = (void *)((unsigned long)mouse_stack + MOUSE_STACK_SIZE); |
||
162 | |||
163 | /* install the handler */ |
||
164 | mouse_regs.x.ax = 0x000c; |
||
165 | mouse_regs.x.cx = 0x007f; |
||
166 | mouse_regs.x.dx = mouse_callback&0xffff; |
||
167 | mouse_regs.x.es = mouse_callback>>16; |
||
168 | __dpmi_int(0x33, &mouse_regs); |
||
169 | |||
170 | CLEAR_MICKEYS(); |
||
171 | |||
172 | emulat3 = buttons<3; |
||
173 | pc_atexit(pc_remove_mouse); |
||
174 | return buttons; |
||
175 | } |
||
176 | |||
177 | MFUNC pc_install_mouse_handler (MFUNC handler) |
||
178 | { |
||
179 | MFUNC old; |
||
180 | |||
181 | if (!mouse_callback && !pc_install_mouse()) { |
||
182 | return NULL; |
||
183 | } |
||
184 | |||
185 | old = mouse_func; |
||
186 | mouse_func = handler; |
||
187 | return old; |
||
188 | } |
||
189 | |||
190 | void pc_mouse_area (int x1, int y1, int x2, int y2) |
||
191 | { |
||
192 | minx = x1; |
||
193 | maxx = x2; |
||
194 | miny = y1; |
||
195 | maxy = y2; |
||
196 | } |
||
197 | |||
198 | void pc_mouse_speed (int xspeed, int yspeed) |
||
199 | { |
||
200 | DISABLE(); |
||
201 | |||
202 | sx = MAX(1, xspeed); |
||
203 | sy = MAX(1, yspeed); |
||
204 | |||
205 | ENABLE(); |
||
206 | } |
||
207 | |||
208 | int pc_query_mouse (int *x, int *y) |
||
209 | { |
||
210 | *x = pc_mouse_x; |
||
211 | *y = pc_mouse_y; |
||
212 | return pc_mouse_b; |
||
213 | } |
||
214 | |||
215 | void pc_show_mouse (void) |
||
216 | { |
||
217 | /* not implemented */ |
||
218 | } |
||
219 | void pc_scare_mouse (void) |
||
220 | { |
||
221 | /* not implemented */ |
||
222 | } |
||
223 | void pc_unscare_mouse (void) |
||
224 | { |
||
225 | /* not implemented */ |
||
226 | } |
||
227 | |||
228 | __asm("\n\ |
||
229 | .text \n\ |
||
230 | .balign 4 \n\ |
||
231 | .global _mouse_wrapper \n\ |
||
232 | _mouse_wrapper: \n\ |
||
233 | cld \n\ |
||
234 | lodsl \n\ |
||
235 | movl %eax, %es:42(%edi) \n\ |
||
236 | addw $4, %es:46(%edi) \n\ |
||
237 | pushl %es \n\ |
||
238 | movl %ss, %ebx \n\ |
||
239 | movl %esp, %esi \n\ |
||
240 | movl %cs:___djgpp_ds_alias, %ss \n\ |
||
241 | movl %cs:_mouse_stack, %esp \n\ |
||
242 | pushl %ss \n\ |
||
243 | pushl %ss \n\ |
||
244 | popl %es \n\ |
||
245 | popl %ds \n\ |
||
246 | movl ___djgpp_dos_sel, %fs \n\ |
||
247 | pushl %fs \n\ |
||
248 | popl %gs \n\ |
||
249 | pushl %edi \n\ |
||
250 | call _mouse \n\ |
||
251 | popl %edi \n\ |
||
252 | movl %ebx, %ss \n\ |
||
253 | movl %esi, %esp \n\ |
||
254 | popl %es \n\ |
||
255 | iret \n\ |
||
256 | .balign 4 \n\ |
||
257 | .global _mouse_wrapper_end \n\ |
||
258 | _mouse_wrapper_end:"); |