Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Don't care if you call me stupid..

Credits go to Steve Terry for helping out!
This thread is locked; no one can reply to it. rss feed Print
Don't care if you call me stupid..
Kevin Epps
Member #5,856
May 2005
avatar

I just CANNOT think of how to do this for some reason. And since I don't really know the term for it, It's hard to search for what I'm looking for.

Does ANYONE know what it's called to pass several values in one argument of a function in c++?

Example:

void func(arg1, val1 | val2 | val3, arg3);

I think you're supposed to make the argument in question a type of unsigned. If that's so how do extract each value from that one argument?

Steve Terry
Member #1,989
March 2002
avatar

That's a binary OR operation.

1enum { val1 = 1, val2 = 2, val3 = 4 }val;
2 
3void func(val v)
4{
5 if(v & val1)
6 {
7 
8 }
9 if(v & val2)
10 {
11 
12 }
13}
14 
15int main(int argc, char **argv)
16{
17 func(val1 | val2);
18}

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

Kevin Epps
Member #5,856
May 2005
avatar

AHHH! ENUMERATION!!!

Thanks so much, Steve!

Thomas Fjellstrom
Member #476
June 2000
avatar

You dont even need the enum.

#define foo  1
#define bar  2
#define baz  4
#define frob 8

// or

const int foo  = 1;
const int bar  = 2;
const int baz  = 4;
const int frob = 8;

Notice the pattern. You can also use shifts to make the values, if you think it helps understanding..

const int foo  = 1; // << 0
const int bar  = 1     << 1;
const int baz  = 1     << 2;
const int frob = 1     << 3;

Basically "flags" need to have one bit in the integer set to on, and the rest off for this to work properly. Powers of two just happen to have this property.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Kevin Epps
Member #5,856
May 2005
avatar

Hey Thomas,

That really didn't help me much. I don't have a problem understanding that part, it's how to declare the function that's going to use the flags.

What I'm trying to do is make a function that's passed several flags that then write out a message based on the flags passed.

I tried Steve's approach, but I get an error message saying that I can't convert a const int to an enum.

Then I tried Thomas's approach somewhat, but I don't know if I'm declaring the function correctly.

1#define KEV 1
2#define A_H 2
3#define A_F 3
4#define JER 4
5#define STE 5
6#define MIK 6
7#define NAU 7
8#define DAN 8
9#define IV 9
10#define ROB 10
11 
12/*enum NAMES { KEV, A_H, A_F, JER, STE, MIK, NAU, DAN, IV, ROB };*/
13 
14#define KEVIN_E "Kevin Epps"
15#define ADAM_H "Adam Howard"
16#define ADAM_F "Adam Friday"
17#define JEREMY_L "Jeremy Landig"
18#define STEVEN_C "Steven Cooper"
19#define MIKE_P "Mike Phillips"
20#define NAUMAN_H "Nauman Hafiz"
21#define DANNY_L "Danny Luisi"
22#define IVAN_D "Ivan Dixon"
23#define ROBERT_P "Robert Parks"
24 
25void show_credits(BITMAP *buffer, char *category, const int nam, int y, int num_of_names)
26{
27 int new_y = y+text_height(money_fonts) + 5;
28 textprintf_centre_ex(buffer, money_fonts_2, 320, y, -1, -1, category);
29 if(nam == KEV)
30 {
31 textprintf_centre_ex(buffer, dialog_fonts, 320, new_y, -1, -1, "%s", KEVIN_E);
32 new_y+=text_height(dialog_fonts);
33 }
34 if(nam == A_H)
35 {
36 textprintf_centre_ex(buffer, dialog_fonts, 320, new_y, -1, -1, "%s", ADAM_H);
37 new_y+=text_height(dialog_fonts);
38 }
39 if(nam == A_F)
40 {
41 textprintf_centre_ex(buffer, dialog_fonts, 320, new_y, -1, -1, "%s", ADAM_F);
42 new_y+=text_height(dialog_fonts);
43 }
44}

And I called the function like this:

show_credits(fade_buffer, "Project Manager", KEV | A_F, 300, 2);
/*Is supposed to print out:
Project Manager
Kevin Epps
Adam Friday*/

But "Adam Friday"'s the only text shown under Project Manager.

(Also, if I change the conditionals back to (nam & whatever), then the all print regardless of the flags passed thru.

Carrus85
Member #2,633
August 2002
avatar

Well, there are two problems with that code:
One, your enumeration values (or defines, in this case), need to be powers of two, not counting numbers.
Two, testing for equality directly is not going to work, you need to and the mask (code, in other words) with your nam variable:

1#define KEV 1
2#define A_H 2
3#define A_F 4
4#define JER 8
5#define STE 16
6#define MIK 32
7#define NAU 64
8#define DAN 128
9#define IV 256
10#define ROB 512
11 
12/*enum NAMES { KEV, A_H, A_F, JER, STE, MIK, NAU, DAN, IV, ROB };*/
13 
14#define KEVIN_E "Kevin Epps"
15#define ADAM_H "Adam Howard"
16#define ADAM_F "Adam Friday"
17#define JEREMY_L "Jeremy Landig"
18#define STEVEN_C "Steven Cooper"
19#define MIKE_P "Mike Phillips"
20#define NAUMAN_H "Nauman Hafiz"
21#define DANNY_L "Danny Luisi"
22#define IVAN_D "Ivan Dixon"
23#define ROBERT_P "Robert Parks"
24 
25void show_credits(BITMAP *buffer, char *category, const int nam, int y, int num_of_names)
26{
27 int new_y = y+text_height(money_fonts) + 5;
28 textprintf_centre_ex(buffer, money_fonts_2, 320, y, -1, -1, category);
29 if(nam & KEV)
30 {
31 textprintf_centre_ex(buffer, dialog_fonts, 320, new_y, -1, -1, "%s", KEVIN_E);
32 new_y+=text_height(dialog_fonts);
33 }
34 if(nam & A_H)
35 {
36 textprintf_centre_ex(buffer, dialog_fonts, 320, new_y, -1, -1, "%s", ADAM_H);
37 new_y+=text_height(dialog_fonts);
38 }
39 if(nam & A_F)
40 {
41 textprintf_centre_ex(buffer, dialog_fonts, 320, new_y, -1, -1, "%s", ADAM_F);
42 new_y+=text_height(dialog_fonts);
43 }
44}

Edit:

Ah, just noticed the last line of your post. Yes, the &'s are required. They just don't work if you don't set the nam value correctly! The codes must be powers of two in order to be set in the bitmask properly. Oh, and just as a note, it might be wise to make your function take a const unsigned int nam instead of a const int, to avoid any potential weirdness with the signs.

Kevin Epps
Member #5,856
May 2005
avatar

THERE we go!! It works now! I was missing the point about the powers of two bit. Thanks man.

Bob
Free Market Evangelist
September 2000
avatar

It sounds like you actually want a list of things in general, not just list of bits. What's wrong with passing an array (or vector) of string?

--
- Bob
[ -- All my signature links are 404 -- ]

Kris Asick
Member #1,424
July 2001

Think of it this way, Kevin:

Computers work on bits, 1's and 0's, thus each number is a combination of bits. For instance:

33 = 00100001, 145 = 10010001, 26710 = 0110100001010110

What you're doing is a form of "bitmasking" usually called "flags" or "tags". The idea is that one variable stores multiple true/false values in each bit. The reason why you need to use powers of 2 is because each power of 2 only touches one bit:

  1 = 00000001
  2 = 00000010
  4 = 00000100
  8 = 00001000
 16 = 00010000
 32 = 00100000
 64 = 01000000
128 = 10000000

So let's give these all values:

#define FLAG_SOLID  1
#define FLAG_PHASED  2
#define FLAG_IMMUNE  4
#define FLAG_SPHERICAL  8
#define FLAG_AI    16
#define FLAG_AUTOMOVE  32
#define FLAG_SPECIAL  64
#define FLAG_PLAYER  128

Now, you simply use a bit-wise OR operation, the | symbol, to combine them, which effectively does something like this:

0100101110100101 | 1010100101110100 = 1110101111110101

Thus if you did this:

variable = FLAG_PHASED | FLAG_AI | FLAG_SPECIAL

...the result is:

00000010 | 00010000 | 01000000 = 01010010

Then when you want to check if a particular flag is set or not, you use a bit-wise AND operation instead, which is the & symbol:

if (variable & FLAG_AI) ProcessAI();

if (variable & FLAG_SPECIAL) TriggerSpecial();

Make sense now? ;)

You'll also note that using '+' instead of '|' works the exact same under these circumstances, provided you don't accidentally add the same flag more than once. (But you can't use '-' in place of '&'!)

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Kevin Epps
Member #5,856
May 2005
avatar

thanks for the input. I got working after Carrus's explanation and I understand it now. I had just forgotten about setting up the flags to be powers of two. Thanks guys for you help.

Johan Halmén
Member #1,550
September 2001

Stupid! Couldn't resist. Actually you're not. That was a good question. And remember, there are no stupid questions, just a lot of inquisitive idiots... Sorry again.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

Fladimir da Gorf
Member #1,565
October 2001
avatar

class Clazz {
   Clazz operator | (const Clazz &other) {
      return //..
   }
};

const Clazz OPT1( ... );
const Clazz OPT2( ... );
const Clazz OPT3( ... );

callFunc( OPT1 | OPT2 | OPT3 );

Tee hee :)

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

KnightWhoSaysNi
Member #7,339
June 2006
avatar

Thank you for asking this question. It has helped me too. Before reading this I had a few functions that were something like this:

void drawtext(srting text, int size, bool bold, bool italic, bool underline, bool strikeout, bool etc...)

Go to: