Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Frage bzgl. der Sache mit Bitmasks

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
16.05.2008, 17:43 Uhr
FunnyDingo



Hallo zusammen,

ich habe die Sache mit den Bitmasks noch immer nocht ganz verstanden, daher muss ich mal nachfragen. Ich habe eine Lib in deren Header folgendes zu finden ist:

C++:
// button state:
    struct buttons
        {
        // convenience accessors
        inline bool A        () const    { return (Bits & _A)    != 0; }
        inline bool B        () const    { return (Bits & _B)    != 0; }
        inline bool Plus    () const    { return (Bits & PLUS)  != 0; }
        inline bool Home    () const    { return (Bits & HOME)  != 0; }
        inline bool Minus    () const    { return (Bits & MINUS) != 0; }
        inline bool One        () const    { return (Bits & ONE)   != 0; }
        inline bool Two        () const    { return (Bits & TWO)   != 0; }
        inline bool Up        () const    { return (Bits & UP)    != 0; }
        inline bool Down    () const    { return (Bits & DOWN)  != 0; }
        inline bool Left    () const    { return (Bits & LEFT)  != 0; }
        inline bool Right    () const    { return (Bits & RIGHT) != 0; }

        // all 11 buttons stored as bits (set = pressed)
         WORD Bits;

        // button bit masks (little-endian order)
        enum mask
            {
            LEFT    = 0x0001,
            RIGHT    = 0x0002,
            DOWN    = 0x0004,
            UP        = 0x0008,
            PLUS    = 0x0010,
            TWO        = 0x0100,
            ONE        = 0x0200,
            _B        = 0x0400,    // ie. trigger
            _A        = 0x0800,
            MINUS    = 0x1000,
            HOME    = 0x8000,
            //
            ALL        = LEFT|RIGHT|DOWN|UP|PLUS|TWO|ONE|_A|_B|MINUS|HOME,
            };
        } Button;

Wie kann ich denn am schlausten prüfen, ob mehr als ein Button gedrückt ist (welcher ist erstmal egal).

Ich glaube ich würde ein ganz wildes if machen in etwa so:

C++:
if (x.Button.Bits != x.Button.LEFT && x.Button.Bits != x.Button.RIGHT...)

Wenn nur ein Button gedrückt ist, müsste ja bei irendeine True rauskommen, wenn mehrere gedrückt sind, sind alle false.

Komische Lösung oder?

Gruß,
Funny
--
"Der Computer ist die logische Weiterentwicklung des Menschen: Intelligenz ohne Moral." (John James Osborne)

Meine Website: http://www.funnydingo.de
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
17.05.2008, 10:42 Uhr
~willy
Gast



C++:
struct buttons
{
        // convenience accessors
        inline bool A        () const    { return (Bits & _A)    != 0; }
        inline bool B        () const    { return (Bits & _B)    != 0; }
        inline bool Plus     () const    { return (Bits & PLUS)  != 0; }
        inline bool Home     () const    { return (Bits & HOME)  != 0; }
        inline bool Minus    () const    { return (Bits & MINUS) != 0; }
        inline bool One      () const    { return (Bits & ONE)   != 0; }
        inline bool Two      () const    { return (Bits & TWO)   != 0; }
        inline bool Up       () const    { return (Bits & UP)    != 0; }
        inline bool Down     () const    { return (Bits & DOWN)  != 0; }
        inline bool Left     () const    { return (Bits & LEFT)  != 0; }
        inline bool Right    () const    { return (Bits & RIGHT) != 0; }

        // all 11 buttons stored as bits (set = pressed)
        short Bits;

        enum mask
        {
            LEFT    = 0x0001,
            RIGHT   = 0x0002,
            DOWN    = 0x0004,
            UP      = 0x0008,
            PLUS    = 0x0010,
            TWO     = 0x0100,
            ONE     = 0x0200,
            _B      = 0x0400,    // ie. trigger
            _A      = 0x0800,
            MINUS   = 0x1000,
            HOME    = 0x8000,
            ALL     = LEFT|RIGHT|DOWN|UP|PLUS|TWO|ONE|_A|_B|MINUS|HOME,
        };
} Button;  

#include <iostream>

int main()
{
    
    // Button.Bits = 0;
    // z.B.:
    Button.Bits |= 3;  // d.h. LEFT && RIGTH == pressed!
    
    if (Button.Left())
        if (Button.Bits^Button.LEFT)
            std::cout << "Mehrere Button gedrueckt!" << std::endl;
}


 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
18.05.2008, 12:40 Uhr
FunnyDingo



OK, das funktioniert aber nur, wenn ich auf den einzelnen Button prüfe. Ich hatte eigentlich gehofft, dass es etwas schickes gibt, um das einmal zu prüfen. Aber ich könnte ja so etwas machen:

C++:
bool IsOnlyOneButtonPressed(Button &Button)
{
  if (Button.Left())
  {
    if (Button.Bits^Button.LEFT)
      return false;
    else
      return true;
  else if (Button.Right())
  {
    if (Button.Bits^Button.RIGHT)
      return false;
    return true;
  }
  ...
}

If (IsOnlyOneButtonPressed(Button))
  DoOneButtonActions(Button);
else
  DoMoreButtonActions(Button);


Ich muss mir das mit dem Bitoperating unbedingt mal ansehen. Ich habe immer gedacht, dass ich das nicht brauche, aber ich stoße immer häufiger darauf und dann sollte man das doch besser beherschen.

Dank dir dafür ;-)
--
"Der Computer ist die logische Weiterentwicklung des Menschen: Intelligenz ohne Moral." (John James Osborne)

Meine Website: http://www.funnydingo.de
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
18.05.2008, 20:07 Uhr
Hans
Library Walker
(Operator)


Hi,

hier mal unabhängig von dem obigen Problem eine Variante zum prüfen, ob mehr als ein Bit gesetzt ist:

C++:
/* bitsset.c
  
   Zum Prüfen, ob in einem ganzzahligen Typ mehr als 1 Bit gesetzt ist.
*/


#include <stdio.h>

int main()
{
  int bc, i;
  unsigned int mask, m1, cf;

  mask = m1 = 0x8020;
  bc = 0; /* bit-count */
  cf = 0; /* carry-flag */

  for (i=0; i<(sizeof(unsigned int)*8); i++)
    { cf = (mask >>= 1) & 1;
      if (cf != 0)
         bc +=1;
    }  
  mask = m1;
  printf ("mask = %0x, %d Bits gesetzt.\n", mask, bc);

  return 0;
}



Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
19.05.2008, 14:54 Uhr
xXx
Devil



C++:
bool IsOnlyOneButtonPressed(Button &Button)
{
  if (Button.Left())
  {
    if (Button.Bits^Button.LEFT)
      return false;
    else
      return true;
  else if (Button.Right())
  {
    if (Button.Bits^Button.RIGHT)
      return false;
    return true;
  }
  ...
}
sowas ... ma ey

C++:
const bool IsOnlyOneButtonPressed(Button const& button)
{
    if (button.Left()) return !(button.Bits^button.LEFT);
    else if (button.Right()) return !(button.Bits ^ button.RIGHT);
    // ..
}
... den rest hab ich jetzt noch net gelesen
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
19.05.2008, 16:25 Uhr
mmc20
puss in boots


hi, man könnte auch folgendes machen...

C++:
#include <iostream>

enum mask
{
    LEFT    = 0x0001,
    RIGHT   = 0x0002,
    DOWN    = 0x0004,
    UP      = 0x0008,
    PLUS    = 0x0010,
    TWO     = 0x0100,
    ONE     = 0x0200,
    _B      = 0x0400,    // ie. trigger
    _A      = 0x0800,
    MINUS   = 0x1000,
    HOME    = 0x8000,
    ALL     = LEFT|RIGHT|DOWN|UP|PLUS|TWO|ONE|_A|_B|MINUS|HOME,
};

void LeftButtonPressed()
{
    std::cout << "LeftButton" << std::endl;
};

void RightButtonPressed()
{
    std::cout << "RightButton" << std::endl;
};

unsigned int testBits(unsigned int bits)
{
    if (bits & LEFT) {
        LeftButtonPressed();
        // ...
        return ( bits &= ~LEFT );
    }
    if (bits & RIGHT) {
        RightButtonPressed();
        // ...
        return ( bits &= ~RIGHT );
    }
    return 0;
};

int main(int argc, char* argv[])
{
    unsigned int test = 3;

    while ( test )
        test = testBits( test );    
    
    return 0;
}


oder man erstellt ein array mit funktionszeigern, und geht das dann mit ner schleife durch.


Bearbeitung:

hab gerade gelesen das du ja nur wissen willst wie viele (bzw ob überhaupt welche) gleichzeigtig gesetzt sind. dann ist natürlich hans's variante zu benutzen



C++:
    unsigned int test = 11;
    int count(0);
    for ( unsigned int i = test; i > 0; i>>=1 )
        if ( i%2 )
            count++;
    std::cout << "count: " << count << std::endl;


Dieser Post wurde am 19.05.2008 um 16:41 Uhr von mmc20 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
19.05.2008, 22:57 Uhr
FunnyDingo



Ui, so viel Code Da sollte ich aber was passendes finden und gute Beispiel zum einarbeiten haben ;-)

Dank euch!
--
"Der Computer ist die logische Weiterentwicklung des Menschen: Intelligenz ohne Moral." (John James Osborne)

Meine Website: http://www.funnydingo.de
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: