]> icculus.org git repositories - theoddone33/hhexen.git/blob - base/i_cyber.c
Round 5: Warn those using 1.0 wadfiles to quit it.
[theoddone33/hhexen.git] / base / i_cyber.c
1 // I_cyber.c
2
3 #ifndef __linux
4 #include <dos.h>
5 #endif
6 #include <stdlib.h>
7 #include <string.h>
8 #include "st_start.h"   // For ST_Message()
9
10
11 // Prototypes
12 unsigned char *I_AllocLow (int length);
13
14
15 /*
16 ====================================================
17
18 Doom control structure
19
20 The keybaord and joystick will add to the values set by the cyberman,
21 to a maximum of 0x19000 for forwardmove and sidemove.  Angleturn is
22 not bounded at all.
23
24 parm                    normal          fast
25 -----           ------          ----
26 forwardmove             0xc800          0x19000
27 sidemove                0xc000          0x14000
28 angleturn               0x2800000       0x5000000
29
30 The keyboard and joystick have a 1/3 second slow turn of 0x1400000 under
31 normal speed to help aiming.
32
33
34
35 ====================================================
36 */
37 /* old ticcmd_t
38 typedef struct
39 {
40         char            forwardmove;            // *2048 for move
41         char            sidemove;                       // *2048 for move
42         short           angleturn;                      // <<16 for angle delta
43         short           consistancy;            // checks for net game
44         unsigned char            chatchar;
45         unsigned char           buttons;
46 } ticcmd_t;
47 */
48 // ticcmd_t as it appears in h2def.h
49 typedef struct
50 {
51         char forwardmove;
52         char sidemove;
53         short angleturn;
54         short consistancy;
55         unsigned char chatchar;
56         unsigned char buttons;
57         unsigned char lookfly;
58         unsigned char arti;
59 }ticcmd_t;
60
61
62 #define BT_ATTACK               1
63 #define BT_USE                  2
64 #define BT_CHANGE               4                       // if true, the next 3 bits hold weapon num
65 #define BT_WEAPONMASK   (8+16+32)
66 #define BT_WEAPONSHIFT  3
67
68 //==================================================
69 //
70 // CyberMan detection and usage info
71 //
72 //==================================================
73 #define DPMI_INT        0x31
74 #define MOUSE_INT       0x33
75
76 #define DOSMEMSIZE      64      // enough for any SWIFT structure
77
78 typedef struct {
79    short        x;
80    short        y;
81    short        z;
82    short        pitch;
83    short        roll;
84    short        yaw;
85    short        buttons;
86 } SWIFT_3DStatus;
87
88 // DPMI real mode interrupt structure
89 /*
90 static struct rminfo {
91         long EDI;
92         long ESI;
93         long EBP;
94         long reserved_by_system;
95         long EBX;
96         long EDX;
97         long ECX;
98         long EAX;
99         short flags;
100         short ES,DS,FS,GS,IP,CS,SP,SS;
101 } RMI;
102 */
103 typedef struct {
104    unsigned char        deviceType;
105    unsigned char        majorVersion;
106    unsigned char        minorVersion;
107    unsigned char        absRelFlags;
108    unsigned char        centeringFlags;
109    unsigned char        reserved[5];
110 } StaticDeviceData;
111
112 // values for deviceType:
113 #define DEVTYPE_CYBERMAN        1
114
115 short                   selector;
116 unsigned short  segment;                // segment of DOS memory block
117 SWIFT_3DStatus  *cyberstat;
118 int                             isCyberPresent;         // is CyberMan present?
119
120
121 #ifndef __linux
122 static  union REGS regs;
123 static  struct SREGS sregs;
124 #endif
125
126
127 extern  int mousepresent;
128
129 //===========================================================
130 //
131 // I_StartupCyberMan
132 //
133 // If a cyberman is present, init it and set isCyberPresent to 1
134 //===========================================================
135 void I_StartupCyberMan(void)
136 {
137 #ifdef __linux
138   isCyberPresent = 0;
139 #else
140    StaticDeviceData *pbuf;
141
142    ST_Message("  CyberMan: ");
143    isCyberPresent = 0;
144
145    cyberstat = (SWIFT_3DStatus *)I_AllocLow (DOSMEMSIZE);
146    segment = (int)cyberstat>>4;
147
148    pbuf = (StaticDeviceData *)cyberstat;
149    memset(pbuf, 0, sizeof (StaticDeviceData));
150
151
152    // Use DPMI call 300h to issue mouse interrupt
153    memset(&RMI, 0, sizeof(RMI));
154    RMI.EAX = 0x53C1;            // SWIFT: Get Static Device Data
155    RMI.ES = segment;
156    RMI.EDX = 0;
157    memset(&sregs, 0, sizeof (sregs));
158    regs.w.ax = 0x0300;          // DPMI: simulate interrupt
159    regs.w.bx = MOUSE_INT;
160    regs.w.cx = 0;
161    regs.x.edi = FP_OFF(&RMI);
162    sregs.es = FP_SEG(&RMI);
163    int386x( DPMI_INT, &regs, &regs, &sregs );
164
165    if ((short)RMI.EAX != 1)
166    {
167           // SWIFT functions not present
168           ST_Message("Wrong mouse driver - no SWIFT support (AX=%04x).\n",
169                          (unsigned)(short)RMI.EAX);
170    }
171    else if (pbuf->deviceType != DEVTYPE_CYBERMAN)
172    {
173           // no SWIFT device, or not CyberMan
174           if (pbuf->deviceType == 0)
175           {
176                  ST_Message("no SWIFT device connected.\n");
177           }
178           else
179           {
180                  ST_Message("SWIFT device is not a CyberMan! (type=%d)\n",
181                                 pbuf->deviceType);
182           }
183    }
184    else
185    {
186           ST_Message("CyberMan %d.%02d connected.\n",
187                          pbuf->majorVersion, pbuf->minorVersion);
188           isCyberPresent = 1;
189           mousepresent = 0;
190    }
191 #endif
192 }
193
194
195
196 /*
197 ===============
198 =
199 = I_ReadCyberCmds
200 =
201 ===============
202 */
203
204
205 int             oldpos;
206
207 void I_ReadCyberCmd (ticcmd_t *cmd)
208 {
209 #ifdef __linux
210     return;
211 #else
212         int             delta;
213
214         // Use DPMI call 300h to issue mouse interrupt
215         memset(&RMI, 0, sizeof(RMI));
216         RMI.EAX = 0x5301;            // SWIFT: Get Position and Buttons
217         RMI.ES = segment;
218         RMI.EDX = 0;
219         memset(&sregs, 0, sizeof (sregs));
220         regs.w.ax = 0x0300;          // DPMI: simulate interrupt
221         regs.w.bx = MOUSE_INT;
222         regs.w.cx = 0;
223         regs.x.edi = FP_OFF(&RMI);
224         sregs.es = FP_SEG(&RMI);
225         int386x( DPMI_INT, &regs, &regs, &sregs );
226
227         if (cyberstat->y < -7900)
228                 cmd->forwardmove = 0xc800/2048;
229         else if (cyberstat->y > 7900)
230                 cmd->forwardmove = -0xc800/2048;
231
232         if (cyberstat->buttons & 4)
233                 cmd->buttons |= BT_ATTACK;
234         if (cyberstat->buttons & 2)
235                 cmd->buttons |= BT_USE;
236
237         delta = cyberstat->x - oldpos;
238         oldpos = cyberstat->x;
239
240         if (cyberstat->buttons & 1)
241         {       // strafe
242                 if (cyberstat->x < -7900)
243                         cmd->sidemove = -0xc800/2048;
244                 else if (cyberstat->x > 7900)
245                         cmd->sidemove = 0xc800/2048;
246                 else
247                         cmd->sidemove = delta*40/2048;
248         }
249         else
250         {
251                 if (cyberstat->x < -7900)
252                         cmd->angleturn = 0x280;
253                 else if (cyberstat->x > 7900)
254                         cmd->angleturn = -0x280;
255                 else
256                         cmd->angleturn = -delta*0xa/16;
257
258         }
259
260 #endif
261 }
262
263
264 void I_Tactile (int on, int off, int total)
265 {
266 #ifdef __linux
267     return;
268 #else
269         if (!isCyberPresent)
270                 return;
271
272         on /= 5;
273         off /= 5;
274         total /= 40;
275         if (on > 255)
276                 on = 255;
277         if (off > 255)
278                 off = 255;
279         if (total > 255)
280                 total = 255;
281
282         memset(&RMI, 0, sizeof(RMI));
283         RMI.EAX = 0x5330;            // SWIFT: Get Position and Buttons
284         RMI.EBX = on*256+off;
285         RMI.ECX = total;
286         memset(&sregs, 0, sizeof (sregs));
287         regs.w.ax = 0x0300;          // DPMI: simulate interrupt
288         regs.w.bx = MOUSE_INT;
289         regs.w.cx = 0;
290         regs.x.edi = FP_OFF(&RMI);
291         sregs.es = FP_SEG(&RMI);
292         int386x( DPMI_INT, &regs, &regs, &sregs );
293 #endif
294 }