Subversion Repositories shark

Rev

Rev 56 | Details | Compare with Previous | 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:");