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