These instructions implement support for 5 mouse buttons in Windows both without and with -dinput (DirectInput) turned on.
1. keys.c - Add the yellow or change to make like the yellow. Yes add even MOUSE6, MOUSE7, MOUSE8 even though there is no way known to me to get more than 5 mouse buttons to work through the Windows API.
2. keys.h - You have to change all teh numbers as a result of inserting these new ones.{"MOUSE1", K_MOUSE1},
{"MOUSE2", K_MOUSE2},
{"MOUSE3", K_MOUSE3},
{"MOUSE4", K_MOUSE4}, // Baker: 5 button support
{"MOUSE5", K_MOUSE5},
{"MOUSE6", K_MOUSE6},
{"MOUSE7", K_MOUSE7},
{"MOUSE8", K_MOUSE8},
3. in_win.c#define K_MOUSE4 203 // Baker - begin 8 button support
#define K_MOUSE5 204
#define K_MOUSE6 205
#define K_MOUSE7 206
#define K_MOUSE8 207 // Baker: end 8 button support
//
// joystick buttons
//
#define K_JOY1 208
#define K_JOY2 209
#define K_JOY3 210
#define K_JOY4 211
//
// aux keys are for multi-buttoned joysticks to generate so they can use
// the normal binding process
//
#define K_AUX1 213
#define K_AUX2 214
#define K_AUX3 215
#define K_AUX4 216
#define K_AUX5 217
#define K_AUX6 218
#define K_AUX7 219
#define K_AUX8 220
#define K_AUX9 221
#define K_AUX10 222
#define K_AUX11 223
#define K_AUX12 224
#define K_AUX13 225
#define K_AUX14 226
#define K_AUX15 227
#define K_AUX16 228
#define K_AUX17 229
#define K_AUX18 230
#define K_AUX19 231
#define K_AUX20 232
#define K_AUX21 233
#define K_AUX22 234
#define K_AUX23 235
#define K_AUX24 236
#define K_AUX25 237
#define K_AUX26 238
#define K_AUX27 239
#define K_AUX28 240
#define K_AUX29 241
#define K_AUX30 242
#define K_AUX31 243
#define K_AUX32 244
// JACK: Intellimouse(c) Mouse Wheel Support
#define K_MWHEELUP 245
#define K_MWHEELDOWN 246
and ...*/
// in_win.c -- windows 95 mouse and joystick code
// 02/21/97 JCB Added extended DirectInput code to support external controllers.
#define DIRECTINPUT_VERSION 0x0700
#include <dinput.h>
#include "quakedef.h"
#include "winquake.h"
typedef struct MYDATA {
LONG lX; // X axis goes here
LONG lY; // Y axis goes here
LONG lZ; // Z axis goes here
BYTE bButtonA; // One button goes here
BYTE bButtonB; // Another button goes here
BYTE bButtonC; // Another button goes here
BYTE bButtonD; // Another button goes here
BYTE bButtonE; // Baker: DINPUT fix for 8 buttons
BYTE bButtonF; // Baker: DINPUT fix for 8 buttons
BYTE bButtonG; // Baker: DINPUT fix for 8 buttons
BYTE bButtonH; // Baker: DINPUT fix for 8 buttons
} MYDATA;
static DIOBJECTDATAFORMAT rgodf[] = {
{ &GUID_XAxis, FIELD_OFFSET(MYDATA, lX), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,},
{ &GUID_YAxis, FIELD_OFFSET(MYDATA, lY), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,},
{ &GUID_ZAxis, FIELD_OFFSET(MYDATA, lZ), 0x80000000 | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,},
{ 0, FIELD_OFFSET(MYDATA, bButtonA), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
{ 0, FIELD_OFFSET(MYDATA, bButtonB), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
{ 0, FIELD_OFFSET(MYDATA, bButtonC), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
{ 0, FIELD_OFFSET(MYDATA, bButtonD), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
{ 0, FIELD_OFFSET(MYDATA, bButtonE), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
{ 0, FIELD_OFFSET(MYDATA, bButtonF), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
{ 0, FIELD_OFFSET(MYDATA, bButtonG), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
{ 0, FIELD_OFFSET(MYDATA, bButtonH), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
};
mouse_buttons = 8;
// if a fullscreen video mode was set before the mouse was initialized,
// set the mouse state appropriately
if (mouseactivatetoggle)
IN_ActivateMouse ();
4. gl_vidnt.c or vid_wgl.c (depending on the engine -- most use those names)case DIMOFS_BUTTON2:
if (od.dwData & 0x80)
mstate_di |= (1<<2);
else
mstate_di &= ~(1<<2);
break;
case DIMOFS_BUTTON3:
if (od.dwData & 0x80)
mstate_di |= (1<<3);
else
mstate_di &= ~(1<<3);
break;
case DIMOFS_BUTTON4:
if (od.dwData & 0x80)
mstate_di |= (1<<4);
else
mstate_di &= ~(1<<4);
break;
// this is complicated because Win32 seems to pack multiple mouse events into
// one update sometimes, so we always check all states and look for events
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MOUSEMOVE:
temp = 0;
if (wParam & MK_LBUTTON)
temp |= 1;
if (wParam & MK_RBUTTON)
temp |= 2;
if (wParam & MK_MBUTTON)
temp |= 4;
// Baker: these defines are so that an engine
// compiles using the gcc compiler that comes with MinGW
// which apparently doesn't have them defined in windows.h
// Really these defines should be placed in winquake.h
// But for the sake of a simpler tutorial, you can put 'em here
// MK_XBUTTON1 and MK_XBUTTON2 are already defined in
// windows.h if using Visual Studio but why not write the tutorial
// for usage with either compiler I say.
#ifndef MK_XBUTTON1
#define MK_XBUTTON1 0x0020
#endif
#ifndef MK_XBUTTON2
#define MK_XBUTTON2 0x0040
#endif
if (wParam & MK_XBUTTON1)
temp |= 8;
if (wParam & MK_XBUTTON2)
temp |= 16;
IN_MouseEvent (temp);