FAQ

1. How do I expose a checkbox control?
2. What if I want to control a boolean variable instead?
3. How do I expose a range control over integers?
4. What if I want to control an integer variable instead?
5. How do I expose a range control over floats?
6. How do I expose a button?
7. How do I expose a color control?
8. How do I expose an option control?
9. What if my options are regular integers?
10. What if I don't know the options in advance, or want to add remove them on the fly?
11. How do I expose a variable directly without using a callback?
12. How do I expose a member function as a callback?
13. Why are the range control min and max values inclusive?
14. Why am I getting weird compiler errors if I try to expose something?
15. Why are the name and path parameters seperated?
16. How do I use functors as callbacks?
17. Why does everything except the range and option controls work?
18. How do I enable and disable Reveal?
19. Why does the font not line up in the menu's?
20. How do I change Reveal's color scheme?
21. How does Reveal use the GuiColors structure members?
22. How can I minimize menu overlap?

1. How do I expose a checkbox control?

If SetBool is a function taking a boolean and returning void:

void SetBool ( bool b );

We can expose this callback as a checkbox like this:

gT weaker . AddCheckBoxControl ( "something/something/something", "name of checkbox", &SetBool );

If you want to have a live-update as well, e.g. the checkbox is updated if a boolean changes in the game, you need another function. One that tells the game the current value of the boolean, like so:

bool GetBool( );

And use it like this:

gT weaker . AddCheckBoxControl ( "something/something/something", "name of checkbox", &SetB ool, &GetBool );

2. What if I want to control a boolean variable instead of using functions?

If foo is a boolean or integer variable:

bool foo;

We can expose this variable as a checkbox like this:

gT weaker . AddCheckBoxControl ( "something/something/something", "name of checkbox", AssignToRefAdapter( foo ), ReturnRefAdapter( foo ) );

3. How do I expose a range control over integers?

If you have the following two functions:

void SetInt ( int i ); // a <= i <= b; int GetInt( );

We can expose this callback as a range control like this:

tweaker . AddRangeControl ( "something/something/something", "name of range", a, b, &SetInt, &GetInt );

4. What if I want to control an integer variable instead?

Again, use the reference adapters. So if you have an integer called foo in your code, do the following:

tweaker . AddRangeControl ( "something/something/something", "name of range", a, b, AssignToRefAdapter( foo ), ReturnRefAdapter( foo ) );

5. How do I expose a range control over floats?

If you have the following two functions:

void SetFloat ( float f ); // a <= f <= b; float G etFloat () ;

We can expose these callbacks as a range control like this:

tweaker . AddRangeControl ( "something/something/something", "name of range", a, b, &S etFloat, &GetFloat );

Note that a and bmust be of floating point type.

If you have a floating point variable instead of two functions, just use the reference adapters, like you did with booleans and integers before.

6. How do I expose a button?

If foo is a function taking voidand returning void:

void foo ( );

We can expose this callback as a button like this:

tweaker . AddButtonControl ( "something/something/something", "name of button", & foo );

7. How do I expose a color control?

If you have the following two functions:

void SetColor ( const Reveal::Color& c ); Reveal::Color GetColor ( );

We can expose this callback as a color-picker like this:

tweaker . AddColorControl ( "something/something/something", "name of color control", & SetColor, &GetColor );

The Reveal::Color class is really simple, so in your color callback, simply extract the RGBA values using the Reveal::Color::A(), Reveal::Color::R(), Reveal::Color::G() and Reveal::Color::B() methods, which return values in between zero and one.

8. How do I expose an option control?

If you have an enum as follows:

typedef enum { OPTION_1, OPTION_2, OPTION_3
} SomeEnum;

And the following two functions:

void SetOption ( SomeEnum e ); SomeEnum GetOption ( );

You can expose this as an option control like this:

Reveal :: Option< SomeEnum > enumeration [ 3 ] = { { OPTION_1 , "Description of option 1" }, { OPTION_2 , "Description of option 2" }, { OPTION_3 , "Description of option 3" },
};

tweaker . AddOptionControl ( "something/something/something", "name of color control", &SetOption, &GetOption, enumeration, enumeration + 3 );

9. What if my options are regular integers?

Sometimes don't typedef their enumerations, but they use them as integer variables. In that case, the code would look like this:

enum { OPTION_1, OPTION_2, OPTION_3
};
void foo ( int e );

You can expose this as an option control like this:

Reveal ::Option< int > enumeration [ 3 ] = { { OPTION_1 , "Description of option 1" }, { OPTION_2 , "Description of option 2" }, { OPTION_3 , "Description of option 3" },
};

tweaker . AddOptionControl ( "something/something/something", "name of color control", &SetOption, &GetOption, enumenumeration, enumeration + 3 );

10. What if I don't know the options in advance, or want to add remove them on the fly?

You can make an empty option control by omitting the begin and past-the-end iterators.

tweaker . AddOptionControl ( "something/something/something", "name of color control", SetOption, &GetOption );

If you store a pointer to the option control you make (empty or not), as follows:

#include "reveal/impl/option_control.h" Reveal::Impl::OptionControl< int > *option = tweaker . AddOptionControl ( "something/something/something", "name of color control", & foo ); // Add three options; if ( option ) option->AddOptions( enumeration, enumeration + 3 );

// Add just one option;
if ( option ) option->AddOptions( enumeration, enumeration + 1 );

// Remove a bunch...
if ( option ) option->RemoveOptions( enumeration, enumeration + 2 );

Note that the pointer returned might be NULL. This happens in release mode (for obvious reasons), so don't rest assured that you'll always check the pointer before you use it.

11. How do I expose a variable directly without using a callback?

By using Callback::AssignToRefAdapter, which turns a reference into a callback that takes one parameter, and returns nothing. For example:

bool foo = false; AssignToRefAdapter( foo )( true ); assert( foo == true );

The other callback (the one returning something, and taking no parameter), can be made by using Callback::ReturnRefRefAdapter, which turns a reference into a callback that takes no parameter, and returns the latest value of the given reference. For example:

bool foo = false; Callback::ReturnRefAdapter callback( foo ); foo = true; assert( callback() == true );

12. How do I expose a member function as a callback?

By using Callback::MemFunAdapter, which turns a pointer to a member function and an associated object into a callback. Calling this callback calls the member function for that particular object. For example:

#include "reveal/callback/mem_fun_adapter.h" struct foo { void bar ( const char * s ) { std :: cout << s ; } };

foo o ;
o . bar ( "hello" );
// Does the same as:
Callback :: MemFunAdapter ( o , & foo :: bar )( "hello" );

13. Why are the range control min and max values inclusive?

Because that allows us to use unsigned chars in the range [0, 255] and floats in the range [0,1.0] and still specify the range using the actual value type.

14. Why am I getting weird compiler errors if I try to expose something?
If you get compiler errors that look something like one of the following:

cannot convert parameter 3 from 'void (void *)' to 'const Reveal::Callback::Callback &' with [ Result=void, Param=void * ] Context does not allow for disambiguation of overloaded function

Or even worse:

'Reveal::Impl::OptionControl *Reveal::Tweaker::AddOptionControl(const char *,const char *,const Reveal::Option *,const Reveal::Option *,const Reveal::Callback::Callback &)' : cannot convert parameter 5 from 'void (SomeEnumType)' to 'const Reveal::Callback::Callback &' with [ OptionType=SomeEnumType, T=SomeEnumType, Result=void, Param=SomeEnumType ] and [ Result=void, Param=SomeEnumType ] Context does not allow for disambiguation of overloaded function

...don't worry. Chances are you forgot an ampersand in front of the function-name. If you want to use a function-pointer to a function called foo() as a callback, you have to use &foo, and not just foo.

Other possibilities are that your callback doesn't match the requested signature. Make sure your callbacks are matching with the requested signature. If you need help, please contact me (jsuter@ea.com) and I'll fix it as quickly as possible.

15. Why are the name and path seperated?

Because very often you will add more than one control, to one and the same path. If the path is dynamically created it saves you a string concatenation.

16. How do I use functors as callbacks?

By wrapping them in their appropriate CallbackN<> type. If you have a functor that returns a type T1 and takes one parameter of type T2, you can use Callback1< T1, T2 >( functor ). If you have a functor that takes no parameters, and returns a type T, you can use Callback0< T >( functor ).

17. Why does everything except the range and option control work?

Some people have experienced problems where everything works fine, except for the range and option controls. This has to do with the fact that the option and range control functionality are in header files, and hence compiled by your game, whereas the rest is in .cpp files and thus compiled in the library already. There are two possible situations that can cause this.

1. Your game doesn't define REVEAL. Make sure you define it.
2. You're compiling with GCC and you have the -wShadow option enabled. This one can be tricky to find, but luckily Andrew Hosfield find it for us. Make sure you disable it.
18. How do I disable and enable Reveal
Using the following two methods:

bool Reveal::Tweaker::Enabled() const; void Reveal::Tweaker::SetEnable( bool e );

19. Why does the font not line up in the menu's?

In order to minimize dependencies and maintain cross platform compatibility, Reveal does not provide a font, they are provided by the user. Depending on your particular font minor adjustments may be necessary in order for the text to appear correctly on the menus. This is usually accomplished by adjusting the text position in your implementation of the virtual DoString function in the Reveal::Renderer class.

20. How do I change Reveal's color scheme?

The colors of the various menus and controls can be easily modified by setting the desired color values in the Reveal::GuiColors. Once the colors have been set, pass them to Reveal via Reveal::SetGuiColors. Here is a sample color scheme:
//ALPHA = 0xFF000000
//RED = 0x00FF0000
//GRN = 0x0000FF00
//BLU = 0x000000FF
Reveal::GuiColors guiColors;
guiColors.mCursorColor = 0xFF00FFFF;
guiColors.mTextColor = 0xFFFFFFFF;
guiColors.mStatusBarColor = 0x66000000;
guiColors.mSliderColor = 0xFFFFFFFF;
guiColors.mBorderColor = 0xFFFFFFFF;
guiColors.mWidgetBackgroundColor = 0x66000000;
guiColors.mWidgetHighlightedBackgroundColor = 0xFFD0E0EF;
guiColors.mWidgetSameLevelBackgroundColor = 0x88000000;
guiColors.mMruButtonColor = 0x66000000;
guiColors.mHighlightedMruButtonColor = 0xFF777777;
guiColors.mInteractiveBackgroundColor = 0xFFAAAAAA;
guiColors.mInteractiveForegroundColor = 0xFF000000;
guiColors.mButtonColor = 0xFF444444;
guiColors.mButtonDownColor = 0xFFAAAAAA;
guiColors.mOptionBoxSelectionColor = 0xFF777777;
guiColors.mOptionBoxMouseOverColor = 0xFFD0E0EF;
guiColors.mMruUnlockedColor = 0xFF000000;
guiColors.mMruLockedColor = 0xFFD0E0EF;
// Pass the colors to Reveal
gTweaker.SetGuiColors( guiColors );

21. How does Reveal use the GuiColors structure members?

Reveal supports a wide variety of menu colors. Here is how the GuiColors are used:
mCursorColor - The cursor color.
mTextColor - The font color.
mStatusBarColor - Status Bar color (bar along bottom).
mSliderColor - Slider Control color.
mBorderColor - Menu Border color.
mWidgetBackgroundColor - Color of menus not currently active.
mWidgetHighlightedBackgroundColor - Active menu item selected color.
mWidgetSameLevelBackgroundColor - Active menu color.
mMruButtonColor - MRU button color.
mHighlightedMruButtonColor - Current MRU color.
mInteractiveBackgroundColor - Items that can be interacted with (i.e. push buttons on sliders).
mInteractiveForegroundColor - Color of interactive items when active.
mButtonColor - Button color (i.e. pause button).
mButtonDownColor - Button color when pushed.
mOptionBoxSelectionColor - Option Box color.
mOptionBoxMouseOverColor - Active Option Box color.
mMruUnlockedColor - MRU unlocked check box color.
mMruLockedColor - MRU locked check box color.

22. How can I minimize menu overlap?

With many menus and controls it can become difficult to navigate or even see the results of what you are tweaking. If you find that you have to traverse down multiple menus in order to get to a particular control, try using the Most Recently Used Menu feature. By clicking on a control, its menu will appear in one of the Most Recently Used Menu slots across the top. This is a shortcut to that menu. As you click on different controls these slots will change depending on how frequently they are used and what menu they are in. If you click on the box to the right of the Most Recently Used Menu slot, it will lock that menu in place and not allow it to be overridden by other frequently used menus. Clicking the box again will unlock that menu.