@c -*-texinfo-*-
@node The Basics, Tutorials, Using Crystal Space, Using Crystal Space
@section Basics and Overview
@cindex Object Registry
@cindex Plugin Manager
@cindex Plugin Loader
@cindex @code{csLoadPlugin}
@cindex @code{csPluginLoader}
@cindex @code{csInitializer}

Crystal Space is a highly modular framework. As such it is more complex
then many other game engines or renderers you might encounter. The advantage
of this complexity is that it offers you a lot of power in what you do and
how you use it. This section tries to explain the basic ideas behind the
Crystal Space phylosophy.

@menu
* TutIntro Plugins and Modules:: Plugins and Modules
* TutIntro Plugin Overview:: Plugin Overview
* TutIntro Basic Concepts:: Basic Crystal Space Concepts
* TutIntro Basic Engine Concepts:: Basic Engine Concepts
* TutIntro Minimum Requirements:: Minimum Application Requirements
* TutIntro Compilation:: Compiling the Application
@end menu

@node TutIntro Plugins and Modules, TutIntro Plugin Overview, The Basics, The Basics
@subsection Plugins and Modules
@cindex Plugins and Modules

Crystal Space is a package of components and libraries which can all be useful
for creating computer games.  Although some of the packages are intended more
for 3D gaming this is not as such a restriction of the package.  Components
such as the sound driver function just as well in a 2D gaming environment, and
the Virtual File System plugin (@pxref{VFS}) can be used in non-graphical
applications.  This highlights one of the important characteristics of Crystal
Space: the components and libraries are more or less independent of each other.
If you do not want ``real'' physics, then just don't use the physics plugin.
If you don't want scripting then don't include that.  All packages are designed
to be functional on their own or with a minimal number of other packages.
There are some dependencies of course.  For example, the 3D engine requires a
3D renderer to display its output, and a renderer requires a canvas onto which
to draw.  On the other hand, you could very well use the 3D renderer without
the 3D engine.

Although there is a high level of independence, there is also a high level of
integration.  The components and libraries were also designed to be used
together and as such offer a flexible scheme of integration.

If you are interested in developing a program using Crystal Space, then it is
important to understand that Crystal Space is not a single monolithic library,
but instead consists of several @dfn{libraries} and @dfn{plug-in modules}.
This manual uses the term @dfn{module} for both libraries and plug-ins when
the distinction between the two is not important.

A plug-in module is similar to a library, but has some advantages over a
library.  All plug-ins can be accessed in a common fashion.  They have a pure
interface, and they can provide this interface even if they are extracted to a
dynamic load library.  So, they are the better solution as long as speed is not
the dictator of all decisions as in the math library (access to plug-in
functions uses virtual methods).  The main difference between the interface of
a library and a plug-in is that a library may use @sc{scf}, the Shared Class
Facility (@pxref{SCF}), and C++ classes; plug-ins may only use @sc{scf}.

@itemize @bullet
@item
What is @sc{scf}?

The main @sc{scf} object is the @dfn{interface}.  An interface is the
solution to strictly decouple the public methods of an object from their
implementation.  You only get a pointer to an abstract class with only virtual
methods, called the interface, so your program doesn't know about the actual
object behind the pointer.  This object is called an @dfn{implementation} of
the interface.  You as the user of Crystal Space will call functions that
create the actual object, but only return the interface.  After that you can
use the interface like a C++ object.  When you don't need it anymore, don't
@samp{delete} it, but call @code{DecRef()}.  When you pass a pointer to the
interface to anywhere, call @code{IncRef()} from there, and @code{DecRef()}
when you don't need the interface there anymore.

Starting with Crystal Space version 0.95 we also have smart pointers.
A smart pointer is an instance of the class @code{csRef}. This class takes
care of @code{IncRef()} and @code{DecRef()} for you
(@pxref{Smart Pointers}). It is very important to use smart pointers
now. They are making life a lot easier and in the future they may become
required usage (i.e. no longer optional).

As the user you'll only have to include a header that defines the interface,
but not the implementation.  Despite the obvious advantage of having a very
clear structure in your code, there is the advantage that linking the
interface to the implementation can be done at run-time, but more about this
later.

@item
What are the characteristics of a library?

A library is just a normal C++ library as you know them.  A library can
optionally provide @sc{scf} interfaces.  In the case of a library this is just
a way to define a clear structure.  But as their main interface, libraries
provide C++ classes.

@item
What are the characteristics of a plug-in?

A plug-in, on the other hand, will only provide @sc{scf} interfaces, no normal
C++ classes. The plug-in itself will also appear as an @sc{scf} interface.
This is part of the definition of a plug-in.  A plug-in can be organized as
static library or @sc{dll}; this only makes a small difference in how you use
it in your program.

As the user of Crystal Space, you have to do
the following steps to use a plug-in:

@itemize @minus
@item
First, do all these steps for the dependencies (other plug-ins) that this
plug-in relies on.

@item
Register the library that contains the plug-in.

@item
Load the plug-in.  This will also initialize the plug-in.  It will fail if you
forgot any dependencies.

@item
Query the plug-in interface.  This is an @sc{scf} interface, so you now have
access to the functions of the plug-in.
@end itemize

@item
How can I register the plug-in library?

@dfn{Registering} means to tell @sc{scf} the name of the plug-in that was given
to it by its author, and a class or a dynamic library to associate it with.
Plugin libraries can contain multiple named @sc{scf} classes.  For example, to
use the null graphics renderer @sc{scf} must know that the @sc{scf} class
@samp{crystalspace.graphics3d.null} can be found in @file{null3d.dll}
(Windows) or @file{null3d.so} (Unix).  @sc{scf} determines dynamically which
plugin libraries contain which @sc{scf} classes by consulting meta-information
associated with each plugin.  Depending upon the platform, the associated
meta-information may be bundled into the plugin itself, or it might exist in a
separate file with a @file{.csplugin} extension alongside the plugin module.

How you register a library depends on whether it is a static library or a
dynamic library (@file{.dll} or @file{.so}).  For a static library, that is,
one which is linked directly into the application rather than loaded
dynamically at run-time, put the following macro invocation at top-level in one
of your C++ files once for each @sc{scf} class contained in your library:

@example
SCF_REGISTER_STATIC_CLASS(
  @var{cxx-class},
  @var{scf-name},
  @var{description},
  @var{dependencies})
@end example

Here, @var{cxx-class} is the name of the C++ class which implements the
factory for this particular @sc{scf} class.  @var{cxx-class} is the same name
given to the @code{SCF_IMPLEMENT_FACTORY()} macro.  @var{scf-name} is the
@sc{scf} class name corrsponding to @var{cxx-class}, @var{description} is a
human-readable string describing the purpose of the class, and
@var{dependencies} is a comma-separated list of other @sc{scf} class upon which
this class depends.

For a dynamic library, @sc{scf} will discover the plugin and register the
contained classes automatically by consulting the associated meta-information.

@item
How can I load the plug-in?

To load a plug-in, you must tell the plug-in manager the name
of the plug-in as it was registered in the previous step. In the most
common case you will probably use the plug-in loader to load the plug-in.
This is a convenience class that is able to load plug-in as specified
in a config file, from the commandline, or as requested by the application
programmer. In addition to loading the plug-in (the plug-in loader will
use the plug-in manager to do that), the plug-in loader will optionally
also register the plug-in with the @dfn{Object Registry}.

The object registry is a central location in the Crystal Space framework
where any module can register @sc{scf} objects. The object registry is not
only for plug-ins. It can contain any @sc{scf} object. Objects in the
object registry also have a tag name associated with them. By convention
the @emph{default} object for a given @sc{scf} interface will be
added to the object registry with the tag name equal to the interface
name. For example, a 3D renderer is a plug-in module that
implements (among others) the @samp{iGraphics3D} interface. At the same
time there can be multiple 3D renderers in memory (for example, for
procedural textures). But the default 3D renderer will be registered
with the tag name @samp{iGraphics3D}.

Note that the decision which graphics driver you use (e.g. Null or
OpenGL) is done at the time you load the plug-in by passing the name of
that driver. At the time you ask for the plug-in interface and use it in
your program, this does not make a difference anymore. This makes it possible
to exchange the driver simply by loading another driver, but without changing
your main program.

The Crystal Space modules themselves will use the standard plug-ins with the
default tag name as explained above. For example, the 3d engine looks
for the graphics driver by looking in the object registry for an object
with the tag @samp{iGraphics3D}.

Now how can you actually load the plug-in? You can either load them
manually in the code using the @code{csLoadPlugin} function or else
you can use the plugin loader. As explained above, the plugin loader
can load plugins specified on the commandline, a config file, or else
explicitly requested in the code. This is done in a specific way:
The commandline has highest priority. i.e. if the user specified the
OpenGL video driver on the commandline then this will be the plugin that
is loaded on the @samp{iGraphics3D} tag. The config file and plugins requested
from the code are ignored then (for that tag at least). The plugins
requested from the code have lowest priority and only serve as a default
if neither the commandline nor the config file specified a plug-in for
the given tag.

There is a class called @code{csInitializer()} which contains various
convenience routines to help initialize a Crystal Space application.
This class also contains a routine (@code{RequestPlugins()}) which will
use the plugin loader automatically.

There are several advantages to using the plugin loader as opposed
to manually loading plug-ins using @code{csLoadPlugin}:

@itemize @minus
@item
The plugin loader will sort all plug-ins based on dependencies.
For example, the engine depends on a 3D rasterizer so the plugin
loader will make sure that the engine is loaded later. If you manually
load plugins you risk that the loading will fail because a plugin
that it needs is not yet present.
@item
The user is able to override the plug-ins loaded by the plugin loader.
He or she can modify the config file or specify an alternative
plug-in on the commandline. There is no way to change what plugin is
loaded using @code{csLoadPlugin} unless by recompilation (unless of course
you use some other way to read the config file and find out what plugin
to load).
@end itemize

@item
How can I query the plug-in interface?

This is the last step before you can use the plug-in. It means that inside
your program you ask the object registry for an object registered with
the desired tag. The easiest way to do this is as follows:
@code{csQueryRegistry<iInterface>(@var{object_reg})}.
This macro will search the object registry for the default object
implementing the given interface (i.e. the object registered with the
tag equal to the interface name). Alternatively you can also use
@code{csQueryRegistryTag} to get an object with a specific tag.

@item
Conclusion

To sum it up, @sc{scf} is mainly used to provide common interfaces for
@sc{dll}s, but it can also be used by statically linked libraries. If you
want to know how to write a plug-in yourself, you should read the complete
@sc{scf} documentation. @xref{SCF}.
@end itemize

For further information about modules and plug-in drivers, see the sections
on using Crystal Space (@pxref{Using Crystal Space}).

Now that you have learned some basics about the Crystal Space environment,
you can try writing your first program.

@node TutIntro Plugin Overview, TutIntro Basic Concepts, TutIntro Plugins and Modules, The Basics
@subsection Plugin Overview
@cindex Plugin List
@cindex Plugin Overview

This section presents a quick overview of the plug-ins provided by Crystal
Space. More detailed descriptions of these facilities may be found in later
sections.

@itemize @bullet
@item
@emph{VFS} (Virtual File System)

@sc{vfs} serves as the basic module for file access for all parts of Crystal
Space.  It allows one to map ``virtual'' directories to ``real'' ones; to map
several real directories together as a single virtual directory; and to treat
@file{.zip} files like subdirectories.  @xref{VFS}.

@item
@emph{Graphics Drivers}

The graphics modules provide ``low-level'' graphics output. This includes
drawing pixels, lines and text, but also drawing polygons and polygon meshes
to support hardware acceleration. @xref{3D Renderer}. The graphics
drivers themselves uses a ``canvas'' plugin specific to the operating
system and/or the graphics driver in order to open a window or setup the
graphics base system.

@item
@emph{Sound Drivers}

The sound modules allow you to load and play sound effects and music. 3d
effects are supported, as well as different ways to the same sound file.
@xref{Sound Drivers}.

@item
@emph{3D Engine}

This is the core of Crystal Space. It is the main driving force behind
CS. @xref{Engine}.

@item
@emph{Mesh Objects}

Mesh objects are 3D objects that can be used and displayed by the engine.
Examples are 3D sprites, 2D sprites, particle systems, terrain mesh, ....
This functionality used to be in the engine but has been removed from the
engine for greater flexibility. @xref{MeshObject}.

@item
@emph{Map Loader}

This plug-in provides map loading capabilities for your game. In addition
it also contains functions to load mesh objects, textures, and sounds.
@xref{Map Loader}.

@item
@emph{Image Loaders}

In many cases you don't have to use these plugins directly as they
are used automatically by the Map Loader. However in some cases you
might want to access the image loaders in your own application. These
plugins are responsible for loading various types of images (GIF,
PNG, JPG, ...).

@item
@emph{Collision Detection}

There is currently one collision plug-in using @sc{opcode}.
Collision is based on testing for intersection of two objects.

@item
@emph{Console Output} and @emph{Console Input}

These plug-in modules can be used for console-like text input and output,
similar to the console in Quake.

@item
@emph{Scripting}

The scripting plug-in modules allow support for Python, Java, and Perl.

@item
@emph{Font Server}

The font server can be used to display different fonts in your application.

@item
@emph{Reporter}

The reporter plugin is used by all plugins in Crystal Space to report
about errors, warnings, and other notification messages. A game or
application can also use the reporter to report messages. You can set up
a listener to listen to messages that arrive on the reporter or you can
use the standard reporter listener plugin below.

@item
@emph{Standard Reporter Listener}

This plugin listens to messages that arrive at the reporter and
displays them in some manner. It is the easiest way to handle
messages from the reporter. You can control what should happen with
each type of message and to what output device it should go (i.e. things
like output console, standard output, and so on).

@end itemize

@node TutIntro Basic Concepts, TutIntro Basic Engine Concepts, TutIntro Plugin Overview, The Basics
@subsection Basic Crystal Space Concepts
@cindex Basic Crystal Space Concepts
@cindex Simple Tutorial

In order to write a Crystal Space application there are several concepts
that you need to know about. Here we will give a quick overview of all
important things you need to know about when writing Crystal Space
applications. This section explains the concepts from the perspective
of using Crystal Space as a framework. Read the next section to learn
about engine concepts.

@subsubheading The @sc{scf} Facility
@cindex @sc{scf}

The @sc{scf} (@pxref{SCF}) system is the core low-level memory framework
for Crystal Space. You must initialize this before doing anything else
(one way is to use @code{csInitializer::InitializeSCF()}).

@subsubheading Reference Counting
@cindex reference counting

Reference counting is a very important part of the Crystal Space
framework. Read the @sc{scf} (@pxref{SCF}) documentation for more information
about this but keep in mind that it is very important and try to make
sure you manage references correctly in your own code. Missing a
@code{DecRef()} can cause big memory leaks.

@subsubheading The Object Registry
@cindex @code{iObjectRegistry}
@cindex Object Registry

The object registry is the central repository for all objects in
Crystal Space. Everything in Crystal Space will use the object registry
to get the pointer to the objects it is interested in. One of the first
tasks a Crystal Space application has to do is to create the object
registry. You can create an object registry using
@code{csInitializer::CreateObjectRegistry()} or
@code{csInitializer::CreateEnvironment()}.

@subsubheading The Plugin Manager
@cindex @code{iPluginManager}
@cindex Plugin Manager

The plugin manager is responsible for loading and unloading plugins. A
plugin is a shared library of functions that can be loaded dynamically
into a running Crystal Space application. On Unix a plugin has the @file{.so}
extension and on Windows the @file{.dll} extension is used. Almost everything
in the Crystal Space framework is itself a plugin. So the plugin manager
is an important object. You can create the plugin manager with
@code{csInitializer::CreatePluginManager()} or
@code{csInitializer::CreateEnvironment()}.

@subsubheading The Event Queue
@cindex @code{iEventQueue}
@cindex The Event Queue
@cindex @code{iEventHandler}
@cindex @code{cscmdProcess}

Crystal Space is an event-driven framework. So a Crystal Space application
will also be event driven. The event queue manages the event system and
sends events to listeners. Every module or plugin that implements
@samp{iEventHandler} can register itself with the event queue so it gets
notified when certain events happen. You can create the event queue
with @code{csInitializer::CreateEventQueue()} or
@code{csInitializer::CreateEnvironment()}.

A Crystal Space application will also have to create an event handler
on its own in order to actually be able to do something. This event handler
will be responsible for actually rendering to the screen (this has to be
done in response to the @code{cscmdProcess} event) and also catching
keyboard/mouse input. But there is much more. To setup an event handler
for the application you can use @code{csInitializer::SetupEventHandler()}.

@subsubheading The Virtual Clock
@cindex @code{iVirtualClock}
@cindex Virtual Clock

Most Crystal Space applications will be time-based. The virtual clock
supports the notion of @sc{current time} and @sc{elapsed time}. It is
called a virtual clock because it doesn't necessarily have to correspond
with real time. For example, a game can be paused. Note that a well-behaved
game should always take elapsed time (between two frames) into consideration
for calculating what could have happened in that time. This is important
especially for physics calculations and also for speed of moving objects.
You want an object moving at some speed to move with the same speed on a
system with low framerates compared to a system with high framerates.
The virtual clock can be created with
@code{csInitializer::CreateVirtualClock()} or
@code{csInitializer::CreateEnvironment()}.

@subsubheading The Commandline Parser
@cindex @code{iCommandLineParser}
@cindex Commandline Parser

The commandline parser is responsible for parsing options from
the commandline. If you properly initialize it with @samp{argc} and
@samp{argv} then you can use it to query options that have been given
to the commandline. Several Crystal Space plugins and modules will also
query the commandline so it is important to have this object correctly
initialized. The commandline parser can be created with
@code{csInitializer::CreateCommandLineParser()} or
@code{csInitializer::CreateEnvironment()}.

@subsubheading The Configuration Manager
@cindex @code{iConfigManager}
@cindex Configuration Manager

The configuration manager is responsible for reading options from configuration
files.  All configuration files are put in a global pool which is managed by
the configuration manager.  Several Crystal Space plugins and modules will
query options from the configuration manager and Crystal Space applications can
also do that if they want.

You can create the configuration manager with:

@example
csInitializer::CreateConfigManager()
@end example

@noindent
or

@example
csInitializer::CreateEnvironment()
@end example

You can setup the configuration manager with:

@example
csInitializer::SetupConfigManager()
@end example

@subsubheading The Input Drivers
@cindex Input Drivers

There are three standard input drivers included with Crystal Space:
keyboard, mouse, and joystick. Calling:

@example
csInitializer::CreateInputDrivers()
@end example

@noindent
or

@example
csInitializer::CreateEnvironment()
@end example

@noindent
will create the drivers and publish them via the object registry.  These
drivers will post events to the global event queue.

@subsubheading The @code{csInitializer} class
@cindex @code{csInitializer}

We already mentioned several of the functions above. This class (for which
the definition can be found in @file{include/cstool/initapp.h}) is a
convenience class that can be used to help you setup everything needed to
get the application running. In the tutorial below we will use several of the
functions from @samp{csInitializer}. This class contains only static member
functions.

@node TutIntro Basic Engine Concepts, TutIntro Minimum Requirements, TutIntro Basic Concepts, The Basics
@subsection Basic Engine Concepts
@cindex Basic Engine Concepts
@cindex Simple Tutorial

In the previous section we explained the basic concepts of the Crystal Space
framework. In this section we explain the basic concepts of the engine. These
are the concepts that you have to work with to make your 3D game data.
(@pxref{World Components}).

@node TutIntro Minimum Requirements, TutIntro Compilation, TutIntro Basic Engine Concepts, The Basics
@subsection Minimum Application Requirements
@cindex Tutorial Minimum Application Requirements
@cindex Minimum Application Requirements, Tutorial

For an application to be considered a proper ``Crystal Space application'',
there are a few requirements.  These are:

@itemize @bullet
@item
Each and every source file (@file{.cpp}) must import @file{cssysdef.h} as the
very first included Crystal Space header files.  @file{cssysdef.h} should never
be included by a header file. The reason for this is that @file{cssysdef.h}
has modifiers which control what should be defined and what not. If a header
file would include @file{cssysdef.h} on its own the cpp file would not be
able to include it again (due to header protection) and would then not be
able to add the additional stuff that it may need.

@item
@code{CS_IMPLEMENT_APPLICATION} needs to be put in the beginning of
the file (@emph{after} the includes).

@item
The @code{main()} function must be declared with the following prototype:
@example
int main(int argc, char const* argv[]);
@end example
@end itemize

Following these guidelines will help to ensure that your application builds
and runs on all platforms supported by Crystal Space.

@node TutIntro Compilation, , TutIntro Minimum Requirements, The Basics
@subsection Compiling the Application
@cindex Compiling an Application, Tutorial

In order to compile a Crystal Space application I recommend you look at the
howto on compiling an external application. For @sc{msvc} 7 and later this 
tutorial can be found at @xref{HOWTO Creating External MSVC Application}, 
for other environments based on @sc{gnu} make you can look at
@xref{HOWTO CS Project}.

Additionally note that the source for some of these tutorials can be
found in the @file{CS/apps/tutorials} directory. There are also a few
additional tutorials there that are not (yet) covered in the documentation.
