This one works as intended:
if (clu.raw.butsnum) {
int i;
for (i=0;i<clu.raw.butsnum;i++){
if (clu.raw.buts[i] & RI_MOUSE_BUTTON_1_DOWN)
Com_QueueEvent( 0, SE_KEY, K_MOUSE1, qtrue, 0, NULL );
if (clu.raw.buts[i] & RI_MOUSE_BUTTON_2_DOWN)
Com_QueueEvent( 0, SE_KEY, K_MOUSE2, qtrue, 0, NULL );
if (clu.raw.buts[i] & RI_MOUSE_BUTTON_3_DOWN)
Com_QueueEvent( 0, SE_KEY, K_MOUSE3, qtrue, 0, NULL );
if (clu.raw.buts[i] & RI_MOUSE_BUTTON_4_DOWN)
Com_QueueEvent( 0, SE_KEY, K_MOUSE4, qtrue, 0, NULL );
if (clu.raw.buts[i] & RI_MOUSE_BUTTON_5_DOWN)
开发者_如何学Go Com_QueueEvent( 0, SE_KEY, K_MOUSE5, qtrue, 0, NULL );
if (clu.raw.buts[i] & RI_MOUSE_BUTTON_1_UP)
Com_QueueEvent( 0, SE_KEY, K_MOUSE1, qfalse, 0, NULL );
if (clu.raw.buts[i] & RI_MOUSE_BUTTON_2_UP)
Com_QueueEvent( 0, SE_KEY, K_MOUSE2, qfalse, 0, NULL );
if (clu.raw.buts[i] & RI_MOUSE_BUTTON_3_UP)
Com_QueueEvent( 0, SE_KEY, K_MOUSE3, qfalse, 0, NULL );
if (clu.raw.buts[i] & RI_MOUSE_BUTTON_4_UP)
Com_QueueEvent( 0, SE_KEY, K_MOUSE4, qfalse, 0, NULL );
if (clu.raw.buts[i] & RI_MOUSE_BUTTON_5_UP)
Com_QueueEvent( 0, SE_KEY, K_MOUSE5, qfalse, 0, NULL );
}
clu.raw.butsnum = 0;
but this one,
if (clu.raw.butsnum) {
short int down = qfalse;
int but = 0, i;
for (i = 0; i < clu.raw.butsnum; i++) {
switch( clu.raw.buts[i]) {
case RI_MOUSE_BUTTON_1_DOWN: down = qtrue; but = K_MOUSE1; break;
case RI_MOUSE_BUTTON_2_DOWN: down = qtrue; but = K_MOUSE2; break;
case RI_MOUSE_BUTTON_3_DOWN: down = qtrue; but = K_MOUSE3; break;
case RI_MOUSE_BUTTON_4_DOWN: down = qtrue; but = K_MOUSE4; break;
case RI_MOUSE_BUTTON_5_DOWN: down = qtrue; but = K_MOUSE5; break;
case RI_MOUSE_BUTTON_1_UP: down = qfalse; but = K_MOUSE1; break;
case RI_MOUSE_BUTTON_2_UP: down = qfalse; but = K_MOUSE2; break;
case RI_MOUSE_BUTTON_3_UP: down = qfalse; but = K_MOUSE3; break;
case RI_MOUSE_BUTTON_4_UP: down = qfalse; but = K_MOUSE4; break;
case RI_MOUSE_BUTTON_5_UP: down = qfalse; but = K_MOUSE5; break;
}
Com_QueueEvent( 0, SE_KEY, but, down, 0, NULL );
}
}
clu.raw.butsnum = 0;
..sometimes "loses it" and if some of the "mouse buttons" (in that code) aren't pressed if they are hit too fast.
Anyway, the relevance of the code itself I guess is little.
Why do those pieces of code don't do exactly the same thing?
The switch is like writing
if ( clu.raw.buts[i] == VALUE )
which is different from
if ( clu.raw.buts[i] & VALUE )
Clearly the first "catchs" VALUE iff it is the only event kept in clu.raw.buts[i]
. Instead all the RI_stuffs are bits or-ed in clu.raw.buts[i]
, so the only way to see if they are set (to 1) or clear (0) is the &
(bitwise and) operator.
E.g. if clu.raw.buts[i]
is 0100 and VALUE is 0100, you catch it. If clu.raw.buts[i]
is 0110 you won't "see" 0100 with ==, while you will "see" it with & 0100
.
Code #1 allows for multiple bits in the clu.raw.buts[i]
entry to be 1
, by using a binary AND operator and checking each bit individually.
Code #2 allows only one bit to be 1
(as it compares to specific case
s value in the select
), thus missing cases where two or more events occur at once.
With the if's, you are examining each individual bit. With the switch, you are effectively looking at all the bits OR'd together, so no individual case ever hits.
With the switch version, only one case can be matched per iteration. In the if version, each statement is evaluated in turn, meaning more than one of the statements can be executed each iteration.
精彩评论