tags:

views:

76

answers:

4

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)
                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?

+2  A: 

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 cases value in the select), thus missing cases where two or more events occur at once.

adamk
+2  A: 

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.

JustJeff
+7  A: 

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.

ShinTakezou
+1  A: 

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.

rmx