Reveal Tutorial

This tutorial assumes your application has Reveal integrated as described in the integration section. T o be able to use Revael, you need to understand the folllowing three things:

How to reach Reveal
- How Reveal communicates with the game
- How to add menu items

How to reach Reveal

There are three ways to reach Reveal. Ask the person who integrated Reveal in your game what you should use.

1. The person who integrated Reveal has created a globally reachable instance of Reveal::Tweaker and you should use that. That person knows more, so ask him or her.

2. You #include "reveal/singleton.h" and reach the tweaker through Reveal::Singleton::Instance(). If you want to use the advanced callback features, you have to qualify it with the Reveal::Callback namespace. You will also have to include the appropriate headers like "reveal/callback/callback_0.h", "reveal/callback/callback_1.h", "reveal/callback/return_ref_adapter.h", "reveal/callback/assign_to_ref_adapter.h", and "reveal/callback/mem_fun_adapter.h",

3. You #include "reveal/reveal.h" and reach the tweaker through the global variable called gTweaker. Note that including "reveal/reveal.h" includes everything a client could possible need, which is ofen more than may be neccesary. It also pulls in all Reveal namespaces. This may make life easier, but it is not recommended.

If you're on the FIFA team, we are using method 3. So for all our purposes, just #include "reveal/reveal.h" and you're all set and ready to go to use all possible Reveal features.

From now on, this document assumes you have the Reveal and Reveal::Callback namespaces available.

How Reveal communicates with the game

If you want your life to be easier, it is worth it to take some time to understand how Reveal communicates with the game. This is done using a generic callback mechanism, that pulls up a Chinese wall in between the game and the tweaker. Understanding the callback mechanism will allow you to take full advantage of it. You can continue to use plain-function pointers for your callbacks if you want to, but there is often an easier way that requires less lines of code.

Let's assume that the game stores a certain value, say an integer called g (from game). If we want to tweak this, the easiest way would be to give Reveal a pointer or reference to g and be done with it. That way, Reveal can always update and change g whenever it wants to.

This scenario has several drawbacks.

1. It's unsafe, as the game has no control over when the value is changed, how it's changed, and to what value it's set.
2. Sometimes the game wants to do some things when a value is changed. For example, if one setting is changed, some other settings needs to be changed as well. This can't be done by using the direct pointer or reference approach.
3. Sometimes the game wants to expose a variable of a different type than the actual game is using. For example, the color pickers in Reveal use the Reveal::Color class to support HSV conversion. You don't want to use this class in your code. So a direct pointer to such a color instance is impossible. Instead, you want to convert from the Reveal::Color instance to your own color class instance every time the value changes.
4. Sometimes you want to have read-only or write-only controls.

All of the above problems could be fixed with a suitable work-around. However, I generalized the communication mechanism to solve all problems at once. To understand how this works, we need to take a look at the following image.

On one side we have the game, on the other side we have Reveal. On one side we have our variable called g, and on the other side we store a copy of g, called r (from reveal). Note that the game never knows anything about this copy, and it shouldn't have to.

For our system to work, we need two callbacks. One that goes from left to right, and one that goes from right to left. The first one is called CallbackFromGame and it is called whenever Reveal wants to know what the current value on the game side is. This is neccesary, for example when Reveal wants to draw that value in the GUI. The second one is called CallbackToGame and is called everytime Reveal wants to tell the game the value has changed, for example if the user pressed a checkbox, or dragged a slider.

Notice that CallbackFromGame takes no parameters, and returns an integer. And that CallbackToGame takes an integer, and returns nothing. For a moment, let's generalize the type were exposing (it could integers, floats, colors, booleans, whatever), and call it T. So in order to expose our variable, we need two callbacks:

1. CallbackFromGame, takes no parameters, and returns T.
2. CallbackToGame, takes a T, and returns nothing

Once you understand this, you're halfway,

The big question is, what can be a callback. As it turns out, things are not as easy as they used to be in old-scool C. We got plain-old-function pointers, but we also have member functions, functors, and other things. Furthermore, even though I make a case for not using pointers or references directly, sometimes it's the easiest thing, and perfectly fine.

There is a notion of a callable entity, which generalizes callbacks and can be defined as

anything that satisfies a certain signature, and becomes callable by adding two parantheses '()', is a compatible callable entity for a callback with that signature

This is really important. In old-scool systems, we would have used plain-old function pointers, and everything else would require a work-around. I will take you through a few use-cases, and demonstrate how having a generalized callback library makes our life a lot easier.

- Use case 1: Making a read-only control.
  Say for example, that we are exposing a float , but we want it to be read-only (because it wouldn't make sense to change it). We can easily do this, by writing our CallbackToGame as follows:

void SomeFunctionTakingFloat( float f ) {}

That's right, our CallbackToGame simply doesn't do a thing, it ignores the value. Just implement the vice-versa CallbackFromGame so it returns the value of the float in the game, and you will always have up to date information, so you can use a control as a watch to see the current value. For example, if your CallbackFromGame looks as follows:

float GetFrameRate() {}

You can see the current framerate in a range-control (for example). Obviously, it wouldn't make sense to be able to change the frame-rate by hand.

- Use case 2: Using pointers or references directly.
  Even though sometimes you need callbacks that are actually functions, sometimes it's easier just to use a reference. The good thing is, this is easy to do. We use something called an adapter. For this example, let's consider we have an integer g in the game that we want to tweak. We can create the two callbacks as follows:

  AssignToRefAdapter( g );

  This creates an object that acts as a callback (a so called functor). It takes an integer, and assign it internally to the variable you pass in when you create it, g in this case. So what you should remember is that every time you need a callback that takes some type T, and returns nothing, and the only thing the callback is doing is assigning the incoming parameter to a variable, you can use AssignToRefAdapter instead.
  For the opposite thing, i.e. you want to return a variable from a function taking no parameters, you can use the ReturnRefAdapter.

  ReturnRefAdapter( g );

  This is in some ways the opposite of AssignToRefAdapter, as it doesn't assign, but returns the given variable instead. So what the above does, is create a callback that takes no parameter, but returns the current value of g everytime you call it.
  Conclusion: we can convert references to certain callable entities by using the adapters.

- Use case 3: Using functors
  Functor is the short word for function object. Basically, a function object is an object that supports the () operator, e.g. you can actually call the object as if it is a function, and it will do something for you. Let's look at how this is done first, after which we will see why this is useful. A simple functor could look like this:

  class SomeFunctor { public: void operator() () {
  printf( "Hello World" );
  }
  };

  Don't worry about those double brackets. The first pair just tells you it's operator() you're overloading. The second pair tells you what parameters this operator takes, in this case none. You would use this functor as follows:

  SomeFunctor foo; foo(); // Prints "Hellow World";

  So why is this useful? C++ has functions, it has classes that are objects when instantiated, and now all of sudden I'm using object as functions? Well, the big advantage that functors offer over functions, is that they can have state. Functions can have state by using static variables, but that's just cheating. With a functor, you can do the following:

  class SomeFunctor { int& mI; public: SomeFunctor( int& i ) : mI( i ) {}
  void operator() ( int i )
  {
  mI = i;
  }
  };

  And you could use this functor as follows:

  int i = 0; SomeFunctor foo( i ); foo( 3 ); assert( i == 3 );

  So, you're still wondering how this is useful. Well, for starters, this is exactly what I used to implement the AssignToRef and ReturnRef adapters. I added some C++ magic and a function overload to make it more generic (any type), and easier (automatic template deduction), but they are functors at heart.
  So it's useful for me. But how is it useful for you, in real life? Well, consider an example taken from the real world. An example where using pointers or references directly doesn't work, but plain old function pointers don't work either. We'll use a functor to combine them both. Consider the following. You have an array of 40 volume-settings. Each containing the volume for a different things (music, speech, sound-effects, etc.). Now you want to expose these, so what you can do is the following:

  for ( int i = 0; i < 40; ++i ) { gTweaker.AddRangeControl( "path", "name", 0, 16, AssignToRefAdapter( volumeSettings[ i ] ), ReturnRefAdapter( volumeSettings[ i ] );
  }

  Ignore the AddRangeControl function for now as we'll get to that later (it's the two callbacks at the end that are important).
  Potentially, this could work. But in our specific real world example, it didn't because not only did we want to set the specific elements in the volumeSetings array, we also needed to call an update whenever a change happened. Thus, our callback function would look like this:

  void SetVolume( int volume ) { volumeSetttings[ /* what to put here */ ] = volume; UpdateVolumes(); }

  Do you see the problem? We can't use this callback for every single element in the array, because we don't know which one is changed. There are three solutions for this. One solution is to extend the CallbackToGame signature so it has some sort of identification mechanism. This is ackward, because it forces people to always write wrappers, even if they don't need it. The second solution is to write 40 different functions, called SetVolume0, SetVolume1, SetVolume2, ..., SetVolume39, and give each element a different callback. Obviously that's not very intelligent. The third solution is to write a functor. Like this:

  class SetVolumeFunctor { int& mVolume; public: SomeFunctor( int& v ) : mVolume( v ) {}
  void operator() ( int v )
  {
  mVolume = v;
  UpdateVolumes();
  }
  };

  And then use it as follows:

  for ( int i = 0; i < 40; ++i ) { gTweaker.AddRangeControl( "path", "name", 0, 16, Callback1< void, int >( SetVolumeFunctor( volumeSettings[ i ] ) ), ReturnRefAdapter( volumeSettings[ i ] );
  }

  See what's going on here? We actually give the functor to the tweaker, wrapping it in a Callback1< void, int > (which says it's a callback returning void, and taking one parameter, which is an integer). Note that this wrapping in a callback shouldn't be neccesary on conforming C++ compilers (you could pass the functor directly), but unfortunately we have to deal with CodeWarrior, so the wrapping is necessary.
  Conclusion: we can use functors as callable entities by wrapping them in a Callback<> class.
  Use case 4: Using member functions
  What if you want to use a member function as a callback. Say for example, you want have the following class:

  class Player { string mName; float mHealth; public:
  ... snip ...
  void SetHealth( int f ) { mHealth = f; }
  float GetHealth() { return mHealth; }
  }

  Say for example that you want to expose the health for a specific player using a range control. Obviously the callback going to the game should take a float and return nothing, and the callback coming back should take void, and return a float. It seems that we can use SetHealth for the callback to the game, but there is an unfortunate problem. SetHealth is a member function, and thus takes an implicit this pointer. This means it has an incompatible signature, and can't be a callback. Or can it?
  Most people would make the function static, and use some sort of hack where they put the current this pointer in a global. We instead, will do it the clean way. Say we have an instance of Player, we could bind that instance to the member function, and make it a function that takes one parameter (float) instead of two (float and implicit this). The following code does exactly that:

  Player p; p.SetHealth( 30.0f ); Callback1< void, float > c( MemFunAdapter1( p, &Player::SetHealth ) ); c( 40.0f ); assert( p.GetHealth() == 40.0f );

  See how MemFunAdapter1 takes an instance and a pointer to the member function? Note that we use MemFunAdapter1 because the member function takes one parameter. The result is a callback that applies the member function to the object with the given parameter if it is called. In the context of exposing variables, we can do exactly that, like so:

  Player p; gTweaker.AddRangeControl( "path", "name", 0.0f, 12.0f, MemFunAdapter1( p, &Player::SetHealth ), MemFunAdapter0( p, &Player::GetHealth() ) ); // Or if you let Players expose themselves in a constructor for example, you would do:
  gTweaker.AddRangeControl( "path", "name", 0.0f, 12.0f,
  MemFunAdapter1( *this, &Player::SetHealth ),
  MemFunAdapter0( *this, &Player::GetHealth() ) );

  Here, we use MemFunAdapter0 for the callback that comes from the game, because it (GetHealth) takes no parameters.

At first, all of the above can look rather complicated. If you've always used plain function pointers as callbacks, you may need to become used to it. However, don't forget that nothing stops you from still using function pointers. You can forget about all of the above, and just assume that the AddControl methods take function pointers for callbacks. However, I strongly recommend taking some time to learn about functors, and adapters. You will need to write less code if you do. If you have some time to spare, I suggest reading the document found at http://www.tutok.sk/fastgl/callback.html. Not only does it contains an explanation for some of the design decisions I made, it's a very interesting read anyway. It talks about generic callbacks in C++. Its implementation is not like mine, but it gives you an idea on what's possible.

Summary

- There are two types of callbacks used in Reveal. One takes a type T and returns void. It's the callback that tells the game what the new value is. The other one takes void, and returns T, and it is used by Reveal to query the game for the current value.
- You can use function pointers, references, functors and member functions as callbacks.
- Function pointers can be passed directly, as long as their signature is correct.
- References can be passed using the ReturnRefAdapter (for CallbackFromGame) and AssignToRefAdapter (for CallbackToGame).
- Functors can be passed by wrapping them in a callback with the appropriate signature (Callback0< T > for CallbackFromGame and Callback1< void, T > for CallbackToGame).
- Member functions can be passed by using the MemFunAdapter giving it a pointer to a member function, and an instance to apply it to (bind it to).

How to add menu items

The last step to understanding is actually knowing how to expose your variables. You know that Reveal uses two callbacks to communicate with the game, but we still need to tell Reveal what the meaning of the callbacks is, and what it should do with it.

Reveal provides six different ways of exposing your stuff. A seventh way is to derive from Reveal::Widget and create new widgets through that, but that's too advanced for this tutorial.

The first five are listed in order of difficulty:

1. Exposing a button to trigger something
2. Exposing a check box
3. Exposing a range control
4. Exposing a color control
5. Exposing an option or enumeration control

The last one, using the pause and the auxillary buttons, is a bit different from the rest, so I'll talk about that later. For now, let's start easy.

Adding a button to the menu

Suppose we want a button in the menu, that acts as a trigger and will call a callback when it is clicked. This is the easiest thing you can do. The only odd thing worth mentioning is that it's the only widget-control that doesn't take two callbacks, but only one. This makes sense, because a button is a one-way mechanism. We tell the game when the button is pressed, but the button never needs to know anything. So, let's add a button to our game.

Consider the following function in our game:

void TriggerTransition();

We can expose it as follows:

gTweaker.AddButtonControl( "effects/transitions", "trigger", &TriggerTransitionCallback );

And the button will show up in the menu. It will be called trigger, and be in the transitions menu, as a submenu of the effects menu, which in turn is located under the start button.

Path and names

Let's take some time to talk about those first two parameters you saw in the last code example. Those are the path and name of the control you add to the menu. All the AddControl functions, take a path and a name.

The name is a string that defines what the control is called. It is wise to give it a meaingfull description of the value you are tweaking.

The path is a back-slash or slash divided string of names of submenus. This provides a windows-start-menu-like tree structure of menus. For example if you use "camera/effects/grain" the start menu will have a submenu called camera. That in turn will have a submenu called effects, and that will have a submenu called grain. It's that last menu that will contain the control.

Let's continue to expose some variables. Let's try something more difficult.

Exposing a boolean as a checkbox

We'll add a checkbox to the game. Whenever the user clicks the checkbox in the menu, a user supplied callback will be called with the current boolean value. Suppose we have the following function in our game code:

void SetGamePaused( bool paused );

We can expose this callback as a checkbox with just one line of code:

gTweaker.AddCheckBoxControl ( "game/pause", "enable", &SetGamePaused );

This will create a submenu in the start-menu called 'game'. This submenu will have another submenu called 'pause' and that will contain a checkbox control called 'enable'. Clicking this checkbox will call the given callback with the current setting of the checkbox (true or false).

But wait, you will say. Why does the AddCheckBoxControl only take one callback? Because we ignored the CallbackFromGame callback. We don't have to supply one per se. In that case, the control becomes write only. This may or may not be useful depending on your case, but in many cases you don't need to sync Reveal with the game per se, so you only have to supply the CallbackToGame. However, I can understand that you may want to add that second callback. Well, consider we have the following two functions:

void SetGamePaused( bool paused ); bool GetGamePaused();

We can then do:

gTweaker.AddCheckBoxControl ( "game/pause", "enable", &SetGamePaused, &GetGamePaused );

And now you will have the two-way communication.

What if you don't have such a function in your game? Maybe you have a global variable g_GamePaused instead. Well, as mentioned in the previous section on callback mechanisms, we should use the reference adapters to turn the references in callbacks. Thus, just do:

gTweaker .AddCheckBoxControl ( "game/pause", "enable", AssignToRef Adapter( g_GamePaused ), ReturnRefAdapter( g_GamePaused ) );

And you're all done. The tweaker will communicate with the global g_GamePaused variable directly.

So far, I don't think it's very hard. You should be able to expose buttons and checkboxes in five minutes or less. So, let's make it more challenging. Let's try range controls, a.k.a. slider boxes.

Exposing a variable as a range control (a slider box)

Consider the following two functions, somewhere in your game code:

void SetCameraFOV( float fov ); float G etCameraFOV();

We can easily expose the field of view of the camera as a range, by using the following code:

gTweaker.AddRangeControl( "camera/settings", "focus", 20.0f, 120.0f, &SetCameraFOV, &GetCameraFOV );

This call will create a range control called "focus", in a submenu called "settings", in a submenu called "camera " in the root menu called "start". The minimum value is 20.0f (inclusive), and the maximum value is 120.0f (inclusive). Whenever the value is changed using the range control SetCameraFOV will be called with the new value. If the value is required by the tweaker (to draw it on screen for example), GetCameraFOV is called. Again, if you don't neccessarily need the tweaker to know the latest value, you can ignore the CallbackFromGame, and only supply the first one.

So once again, the first two values are the path and the name.

The next two values are the minimum and maximum value of the range, inclusive. It is important that these values have the type of the range you are controlling. For example, if you want to control floating points, use 20.0f and 120.0f and not 20 and 120. Vice versa, if you want to control integers, use integers as the min and max values.

The last two values are the CallbackToGame and the CallbackFromGame. Again, if you only need a write-only control, you can ignore the last parameter.

Exposing a color control

Exposing a color picker is very easy. Simply do this:

gTweaker .AddColorControl ( "lighting/stadium/flares/color", "name", &SetColor, &GetColor );

Where SetColor is a callback that takes a const reference to a Reveal::Color instance.

void SetColor( const Reveal::Color& c ) { yourColor.alpha = c.A(); yourColor.red = c.R(); yourColor.green = c.G();
yourColor.blue = c.B();
}

And GetColor is a callback returning a color as follows

Reveal::Color S etColor() { Reveal::Color c; c.A( yourColor.alpha ); c.R( yourColor.red );
c.G( yourColor.green );
c.A( yourColor.blue );
return c;
}

Note the use of my own color-class. It's really lightweight, and I wrote it to reduce dependencies. It has support for HSV as well (which some of the artists requested). The components are stored in floating point format from 0.0 to 1.0. You should have no trouble using it.
Obviously, but just to be sure this is understood, you can also use the reference adapters, the member function adapter, or the functor approach. It's just like the other controls, with the only different that you're not tweaking floats, integers, booleans or whatever, but instances of Reveal::Color.

Exposing an enumeration as an option box

The last widget control is the hardest one to understand and use. Option boxes, or list boxes, or enumeration controls, or whatever you call them, are the most complicated. We'll start with a simple example, and build up from there, by showing you how powerful they are.

enum { CAMERA_TOWER, CAMERA_TELE, CAMERA_CLOSE_UP = 45,
CAMERA_FOO,
CAMERA_BAR = 100
};

void SetCameraPosition( int cameraEnum );
int GetCameraPosition();

We can expose this as follows:

Reveal::Option< int > enumeration[ 5 ] = { { CAMERA_TOWER, "Tower" }, { CAMERA_TELE, "Television" }, { CAMERA_CLOSE_UP, "Closeup" },
{ CAMERA_FOO, "Foo" },
{ CAMERA_BAR, "Bar" }
};
gTweaker.AddOptionControl ( "camera/settings", "position",
&SetCameraPosition, &GetCameraPosition,
enumeration, enumeration + 5 );

Notice that AddEnumControl() takes a range of the enumeration as its parameters, that is; a begin iterator, and a past-the-end iterator. The above example uses the hardcoded value of five, but it may be more elegant to use sizeof( enumeration ) / sizeof( Reveal::Option< int > )instead. Either way, the Reveal menu system will contain an option box in the "camera/settings" menu. There you can choose the camera position.

So, to start of with; the AddOptionControl function takes 6 parameters. The first two are the path and name. The second two are the two callbacks. The last two are a begin and past-the-end pointer pointing to an array of items.

What are these items? Well, they are instances of Reveal::Option< T > which is a templatized tuple that combines a instances of type T (which can be anything) with a const char* describing the option. You might wonder why we need those angle brackets (templates). Why not simply use integers? Well, that's what I did at first, but C++'s stronger type system introduces a problem. Most enums are not used as integers. Instead, they are typedef'ed as follows:

typedef enum { CAMERA_TOWER, CAMERA_TELE, CAMERA_CLOSE_UP = 45,
CAMERA_FOO,
CAMERA_BAR = 100
} CameraEnum;

void SetCameraPosition( CameraEnum cameraEnum );
CameraEnum GetCameraPosition ();

Ofcourse this is a good programming practice, that I would not want to discourage. The ugly old-skool solution is to use casts all over the place. This woulnd't be so bad if all casts could be contained on the library side. However, it would force the client to use casts as well, which should be avoided. A safer solution is to use templates, so the above could be exposed using the following code:

Reveal::Option< CameraEnum > enumeration[ 5 ] = { { CAMERA_TOWER, "Tower" }, { CAMERA_TELE, "Television" }, { CAMERA_CLOSE_UP, "Closeup" },
{ CAMERA_FOO, "Foo" },
{ CAMERA_BAR, "Bar" }
};
gTweaker.AddOptionControl ( "camera/settings", "position",
&SetCameraPosition, &GetCameraPosition,
enumeration, enumeration + 5 );

See how I create an array of EnumItem tuples, where the first item is not an integer but CameraEnum instead. This makes the system typesafe, and flexible. In fact, there is an added benefit because of the template approach. We can not only use enums or integers as options, but anything we want. For example, how about a couple of floats:

Reveal::Option< float > enumeration[ 3 ] = { { 0.2f, "Low Health" }, { 0.5f, "Medium Health" }, { 0.8f, "High Health" }
};
gTweaker.AddOptionControl( "enemy/health", "amount",
MemFunAdapter( currentEnemy, &Enemy::SetHealth ),
MemFunAdapter( currentEnemy, &Enemy::GetHealth ),
enumeration, enumeration + 3 );

Perhaps a range-control is more appropriate here. But the fun doesn't stop. Instead of built-in types (enums, integers, floats, whatever), we can use user-defined types. So what about a player, like this:

void SetCurrentPlayer( Player* p ); Player* GetCurrentPlayer(); Reveal::Option< Player* > enumeration[ 11 ] = { { & mPlayers[ 0 ], mPlayers[ 0 ].mName },
{ & mPlayers[ 1 ], mPlayers[ 1 ].mName },
{ & mPlayers[ 2 ], mPlayers[ 2 ].mName },
{ & mPlayers[ 3 ], mPlayers[ 3 ].mName },
{ & mPlayers[ 4 ], mPlayers[ 4 ].mName },
{ & mPlayers[ 5 ], mPlayers[ 5 ].mName },
{ & mPlayers[ 6 ], mPlayers[ 6 ].mName },
{ & mPlayers[ 7 ], mPlayers[ 7 ].mName },
{ & mPlayers[ 8 ], mPlayers[ 8 ].mName },
{ & mPlayers[ 9 ], mPlayers[ 9 ].mName },
{ & mPlayers[ 10 ], mPlayers[ 10 ].mName }
};
gTweaker.AddOptionControl( "players/select", "by name",
| &SetCurrentPlayer,&GetCurrentPlayer,
enumeration, enumeration + 11 );

In an old-scool system, you would have needed a map from integers or enums to players, to do a conversion, because the list boxes only support integers. In this system, you can use anything.
Adding and removing options on the fly
This is the most complicated thing you can do with Reveal. It involves some angle-brackets, so you can ignore this section if you want.
Sometimes it is necessary to remove options on the fly. In fact, sometimes you start out with an empty list box and only add options later. This possible by omitting the last two parameters of the AddOptionControl function. Note that I say omitting. Do not use NULL or 0 as the parameters, because your code won't compile that way. Just ommit them like so:

tweaker.AddOptionControl( "something/something/something", "name of option control", &callbackToGame, &callbackFromGame );

If you want to add options to the menu (whether it's empty or not, that doesn't matter) you need some way of telling which control to add it to. Well, let's just keep the control near by storing a pointer to it. The AddOptionControl function actually returns a pointer to the control that is added to the system. This is an instance of Reveal::Impl::OptionControl< T > where T is the type of the options (just as before with the Reveal::Option tuple). Thus, we can do the following:

#include "reveal/impl/option_control.h" Reveal::Impl::OptionControl< int > *option = tweaker.AddOptionControl( "something/something/something", "name of color control", &foo, &bar ); // 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 );

As with the AddOptionControl function, the AddOptions and RemoveOptions functions will take a begin, and a past-the-end pointer.

Notice how I check whether or not the pointer I get is NULL. This is because in release mode, all Reveal functions are just empty stubs. This means that in release mode, the AddOptionControl function returns NULL, because there is no option control. Thus, make sure you check the pointer before you use it.

Where from here

Ok, you've made it. This is it for this tutorial. Perhaps the FAQ has some more information you might in interested in. You can also take a look at the test.cpp file in the source/test/ directory for some examples. Of course, don't hesitate to ask me any questions you may have. I love to help out wherever necessary.
Finally, once you're familiar with the above basic usage of Reveal, you might be interested in the advanced features.