[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

C.1 Release Notes from 0.98 to 1.00

This section documents the major changes between versions 0.98 and 1.00 of Crystal Space.

csArray<> Index and Size Type Change

csArray<> has been changed to use `size_t' instead of `int' for array sizes and indices. Probably, the most significant semantic difference of this change is that `size_t' is usually unsigned as opposed to `int' which is signed.

Read this paragraph carefully. In actual code, this change may result in nothing more than simple-looking compiler warnings. However, it may have caused semantics to change subtly.

This has the greatest impact in the following areas discussed below.

Iterating Over csArray<> Contents

For this purpose, usually, `int' typed variables were used for keeping track of the index of the current item of an array iteration. Fixing forward iteration over a csArray<> to instead use `size_t' is simple:

 
csArray<...> a;
for (int i = 0, n = a.Length(); i < n; i++)
{
  ...
}

Is changed to:

 
...
for (size_t i = 0, n = a.Length(); i < n; i++)
...

Backward iteration is a bit more problematic. As mentioned before, `size_t' typically is unsigned, so you do not have negative values. This can be a problem in constructs like:

 
csArray<...> a;
for (int i = a.Length() - 1; i >= 0; i--)
{
  ...
}

If the `int' is changed simply to a `size_t', this for-loop misbehaves unexpectedly. When `i' becomes 0, the body of the loop is executed correctly. However, decrementing `i' will not cause `i' to have a negative value--after all, `size_t' is unsigned. Instead, decrementing will make `i' wrap around from 0 to 0xffffffff (on 32-bit machines). Clearly, this is greater than 0, effectively causing an infinite loop. The same thing also happens when `a' has no items (i.e. `a.Length() == 0'). Here the -1 in the initialization of `i' causes wrap-around.

Possible solutions include:

Searching

Functions like csArray<>::FindSortedKey() and csArray<>::Find() used to return -1 to signify that an item was not found. This is still the case, but with a twist. Now, `(size_t)-1' is returned. For convenience, a constant, `csArrayItemNotFound', has been added, which has this exact value. It can be used in comparisons to make it clear what is actually being checked.

Apropros comparisons: Recall that `size_t' is unsigned, so checking whether an index returned by `FindSortedKey()' or `Find()' is actually a valid index by testing with `>= 0' no longer works since `(size_t)-1' is always >= 0. Replace such checks with tests of equality against `csArrayItemNotFound':

 
csArray<...> a;
int index = a.Find (...);
if (index >= 0)
{
  /* Item found */
  ...
}
else
{
  /* Item not found */
  ...
}

Must be replaced with:

 
csArray<...> a;
size_t index = a.Find (...);
if (index != csArrayItemNotFound)
{
  /* Item found */
  ...
}
else
{
  /* Item not found */
  ...
}

Texture and Material Preparation

Texture and material preparation is now fully automatic. It is no longer necessary to prepare a texture or a material before you can use it. It is sufficient simply to register the texture or material. This means that the following functions have been removed (and you can just remove invocations of them from your applications if you used them):

Input Definitions

The file `csutil/inpnames.h' has been renamed to `inputdef.h', and the following functions have been removed:

These functions allowed you to convert a string such as Ctrl+A, `JoystickX' or `Alt+Mouse1' into values describing input events and vice versa.

The way to do this is now, however, is to use `csInputDefinition', which resides in `csutil/inputdef.h'. The preferred way to convert a string to a definition is to construct a `csInputDefinition' from a `char const*'; and the preferred way to convert a definition back to a string (perhaps constructed some other way) is via csInputDefinition::ToString().

There are also static helper methods in `csInputDefinition' which accept arguments in a similar way to the old functions. These are convenience methods which perform the work of instantiating the object for you:

Pollution Reduction

In order to avoid polluting the top-level system include directory, the Crystal Space header tree is now installed (via `make install' or `jam install') in a subdirectory named `crystalspace', rather than being installed directly in the top-level system directory. For example, assuming the default installation location, the Crystal Space headers are now installed in `/usr/local/include/crystalspace'. Previously, they would have been deposited directly into `/usr/local/include'. The `cs-config' utility script properly returns the new header location in response to the `--includedir', `--cflags', and `--cxxflags' options, so this relocation should be mostly transparent to external projects.

The following global header files have been renamed in order to avoid possible conflict with headers installed by other packages.

The following symbols have been renamed in order to avoid pollution of the global namespace.

`cssysdef.h' Changes

The `CS_SYSDEF_PROVIDE_FACILITY' macros, which clients would #define before including `cssysdef.h' in order to alter the behavior of `cssysdef.h', have been removed. Retirement of these macros eliminates the polymorphic behavior of `cssysdef.h', thus helping to pave the way toward eventually pre-compiling Crystal Space's headers in order to reduce overall compilation time. In addition to removing these macros from your code, the following table explains what else (if anything) needs to be done to account for the removal.

CS_SYSDEF_PROVIDE_ACCESS
No additional changes.
CS_SYSDEF_PROVIDE_ALLOCA
Use the `CS_ALLOC_STACK_ARRAY()' macro, rather than alloca().
CS_SYSDEF_PROVIDE_CASE
No additional changes.
CS_SYSDEF_PROVIDE_DIR
No additional changes.
CS_SYSDEF_PROVIDE_EXPAND_PATH
No additional changes.
CS_SYSDEF_PROVIDE_GETCWD
No additional changes.
CS_SYSDEF_PROVIDE_GETOPT
Include `csutil/getopt.h'.
CS_SYSDEF_PROVIDE_MKDIR
Use the `CS_MKDIR(path)' macro to create the directory, rather than the obsolete `MKDIR()' macro.
CS_SYSDEF_PROVIDE_PATH
No additional changes.
CS_SYSDEF_PROVIDE_SELECT
No additional changes.
CS_SYSDEF_PROVIDE_SOCKETS
Include `csutil/sockets.h'.
CS_SYSDEF_PROVIDE_SOFTWARE2D
No additional changes.
CS_SYSDEF_PROVIDE_TEMP
Use the `CS_TEMP_DIR' and `CS_TEMP_FILE' macros, rather than the obsolete `TEMP_DIR' and `TEMP_FILE' macros.
CS_SYSDEF_PROVIDE_UNLINK
No additional changes.
CS_SYSDEF_VFS_PROVIDE_CHECK_VAR
No additional changes.

The age-old restriction that `cssysdef.h' could be included only by source files (`.cpp') has been lifted. This restriction was an unfortunate side-effect of the polymorphic behavior of `cssysdef.h' in the presence of various `CS_SYSDEF_PROVIDE_FACILITY' macros. It is now safe, even recommended, to include `cssysdef.h' in header files (`.h'). Doing so helps to make header files more self-contained, thus reducing the burden of clients of those headers.

Convenience Libraries

Crystal Space now publishes several convenience libraries which eliminate much of the drudgery associated with implementing SCF interfaces in certain types of common plugin modules. For example, the `csGraphics2D' class in the new `csplugincommon' library implements the `iGraphics2D' interface and provides much of the functionality common to most canvases. Likewise, the `csGraphics3D' class implements the `iGraphics3D' interface and provides much functionality common to renderers. You are not required to utilize these implementations when authoring your own plugins, but they are available for your convenience.

The new convenience libraries are:

csplugincommon
Canvas, image loader, particle system, renderer, shader, sound loader, and sound renderer support.
csplugincommon_dx
DirectX support.
csplugincommon_osx
MacOS/X canvas support.
csplugincommon_ogl
OpenGL support.
csplugincommon_w32
Windows support.

For a complete list of available convenience classes, consult the header files in the subdirectories of `CS/include/csplugincommon'.

Convenience Headers

For convenience, several top-level master header files have been added to the project. These should simplify client usage by allowing users to choose the level of granularity which suits them best. The list of new header files follows.

crystalspace.h
Nearly all public headers in entire Crystal Space SDK.
csgeom.h
Content of `CS/include/csgeom'.
csgfx.h
Content of `CS/include/csgfx'.
csplugincommon.h
Content of `CS/include/csplugincommon'.
cstool.h
Content of `CS/include/cstool'.
csutil.h
Content of `CS/include/csutil'.
csws.h
Content of `CS/include/csws'.
iaws.h
Content of `CS/include/iaws'.
iengine.h
Content of `CS/include/iengine'.
igeom.h
Content of `CS/include/igeom'.
igraphic.h
Content of `CS/include/igraphic'.
imap.h
Content of `CS/include/imap'.
imesh.h
Content of `CS/include/imesh'.
inetwork.h
Content of `CS/include/inetwork'.
isound.h
Content of `CS/include/isound'.
itexture.h
Content of `CS/include/itexture'.
iutil.h
Content of `CS/include/iutil'.
ivaria.h
Content of `CS/include/ivaria'.
ivideo.h
Content of `CS/include/ivideo'.

Users new to the SDK will probably want to include `crystalspace.h' since it is simplest; whereas more advanced users may want to include `csutil.h', `cstool.h', etc.; and power users can continue to include only the individual headers required by a particular piece of code.

As a corollary, the old `CS/include/css.h' header, which included many, though not all Crystal Space header files, has been removed. If you require this type functionality from a header, then include the new `crystalspace.h' instead.

Be aware that there is a very small set of public headers not included in any of the master headers. These are omitted from the master headers because they reference external resources which might not be known or available to all clients of the master headers. Clients requiring these special-case headers will need to include them manually, on an as-needed basis, and arrange that the build system has sufficient knowledge about the external resources to satisfy the dependencies at build time. The list of headers which are excluded from the master headers follows.

csplugincommon/directx/*.h
DirectX-specific.
csplugincommon/macosx/*.h
MacOS/X-specific.
csplugincommon/opengl/*.h
OpenGL-specific.
csplugincommon/win32/*.h
Windows-specific.
csutil/archive.h
Requires zlib indirectly via `csutil/zip.h'.
csutil/getopt.h
Conflicts with platform-supplied `<getopt.h>'.
csutil/zip.h
Requires zlib; http://www.gzip.org/zlib/
inetwork/vosapi.h
Requires VOS; http://www.interreality.org/
ivaria/ode.h
Requires ODE; http://www.ode.org/
ivideo/wxwin.h
Requires wxWidgets; http://www.wxwidgets.org/

As an example, if you need access to the `iWxWindow' interface, then you must include `ivideo/wxwin.h' manually; it will not be included as part of `crystalspace.h' or `ivideo.h'. Furthermore, you will need to let the build system know where it can find the wxWidgets resources (headers and libraries). Typically, this is done by adding a wxWidgets check to your project's `configure' script; emitting the results of the check to your `Jamconfig' file with the CS_EMIT_BUILD_RESULT() Autoconf macro; and finally utilizing the result of that check in your project's `Jamfile' by invoking the Jam rule `ExternalLibs'. For MSVC project files, the location of the wxWidgets resources will have to be added as additional include directories and additional library directories, in the project settings or globally, to ensure that MSVC will be able to find them.

Procedural Texture Relocation

Implementations of the standard procedural textures (dots, fire, plasma, etc.) now reside directly in the `stdpt' plugin (`CS/plugins/proctex/standard'), rather than in the `cstool' library. Consequently, the following previously public headers are no longer available: Likewise, procedural textures can no longer be allocated directly (for instance, via `new csProcFire'). Instead, you must now use the plugin system to create such textures. For example:
 
csRef<iPluginManager> plugin_mgr(
  CS_QUERY_REGISTRY(object_reg, iPluginManager));
csRef<iTextureType> type(CS_QUERY_PLUGIN_CLASS (plugin_mgr,
  "crystalspace.texture.type.fire", iTextureType));
if (!type)
{
  type = CS_LOAD_PLUGIN(plugin_mgr,
    "crystalspace.texture.type.fire", iTextureType);
}
csRef<iTextureFactory> fireFact = type->NewFactory();
csRef<iTextureWrapper> tex = fireFact->Generate();
csRef<iFireTexture> fire = SCF_QUERY_INTERFACE(tex, iFireTexture);
Various procedural textures may or may not implement their own custom SCF interfaces beyond the normal interfaces implemented by all procedural textures. In the example above, the "fire" texture implements the specialized `iFireTexture'.

Joystick Corrections

The implementation of `iJoystickDriver' has been fixed to treat joystick numbers consistently. Previously, on account of buggy implementation, some parts of the driver considered joystick numbers 0-based, while other parts considered them 1-based. It now uniformly treats joystick numbers as 1-based. This is consistent with button numbers for joysticks and mice, which are also 1-based.

iGraphics2D Alpha Color Support

`iGraphics2D' now supports an alpha channel. iGraphics2D::FindRGB() accepts an optional alpha value (0 being completely transparent, and 255 being fully opaque) which defaults to 255. All canvases will then blend the pixels appropriately if the color depth is 15 bpp or higher. Furthermore, as iGraphics2D::Write() also handles alpha in both foreground and background colors, it is recommended for transparent backgrounds, instead of using `-1' as the color value, to obtain a color value from FindRGB() that has the same R, G, B components as the foreground color, but an alpha component of 0.

`csutil/garray.h' Deprecated

The `csutil/garray.h' file, containing the class csDirtyAccessArray<>, has been deprecated in favor of the more sensible file name `csutil/dirtyaccessarray.h'. No functional changes have been made to the class.

csList<>::Iterator Normalization

The behavior of csList<>::Iterator has been normalized so that it functions identically to all other iterators in Crystal Space. In the past, a newly created csList<>::Iterator already pointed at the first element in the container. This differed from all other iterator implementations, in which the first element, like all other elements, is accessed by an invocation of Next().

Old code which accessed the elements of a csList<>::Iterator required a non-standard idiom, such as:

 
csList<sometype> list = ...;
csList<sometype>::Iterator it(list);
if (it.HasCurrent())
{
  do_something(*it);         // First value.
  while (it.HasNext())
  {
    do_something(it.Next()); // Remaining values.
  }
}

Or, the slightly less complicated, though still somewhat convoluted:

 
csList<sometype>::Iterator it(list);
while (it.HasCurrent())
{
  do_something(*it);
  it.Next();
}

Following normalization, csList<>::Iterator now works like all other iterators throughout the toolkit. In particular, for forward iteration, all elements can be accessed via the standard HasNext() / Next() idiom:

 
csList<sometype>::Iterator it(list);
while (it.HasNext())
{
  do_something(it.Next());
}

Likewise, for backward iteration, the HasPrevious() / Previous() idiom works in the obvious and expected inverse fashion.

Finally, csList<>::Iterator::Next() and Previous() now return references to contained elements, rather than pointers. This makes the interface of csList<>::Iterator internally consistent, as well as consistent with other iterators throughout the toolkit, in which these methods return references.

iDocument Changes

The iDocument::Parse() method now accepts an optional argument indicating whether or not extraneous whitespace in `CS_NODE_TEXT' nodes should be condensed. Most implementations of `iDocument' will attempt to respect this option if possible. For implementations where it does not make sense, the option will be ignored.

Previously, XML implementations of `iDocument' condensed whitespace in `CS_NODE_TEXT' nodes at Parse() time. This is no longer the case. Whitespace is now preserved by default. If the new behavior is unsuitable for your case, use the new argument to iDocument::Parse() to indicate that whitespace should be condensed. This change was made in order to conform to the latest XML specification which states that XML scanners must preserve whitespace by default. Consult the following documents for more information regarding this issue.

http://www.w3.org/TR/REC-xml/#sec-white-space
http://www.xml.com/axml/notes/AllWSAlways.html

Naming Normalization

The following SCF class names have been normalized in order to be consistent with the names of all other available "null" plugins:

For consistency with like-named methods in other SCF interfaces, the following `iImage' methods have been renamed:

For consistency with related methods (such as HasPrevious()) in the csList<> template, the following methods have been renamed:

For clarification, the following csHash<> methods have been renamed:

Various methods in `csIntersect3' have been renamed in order to improve consistency and clarity. In addition, some arguments have been reversed order so that, for example, a method named SegmentTriangle() will receive first the segment argument followed by the triangle argument.

The same improvements have been made to csIntersect2:

Default csHash<> (and csHashReversible<>) Table Size

The default hash table size and grow rate has been reduced from 257 and 64 to 23 and 5, respectively, to have hashes use less memory. If a hash is expected to contain a large quantity of elements, those two parameters can be tweaked upon construction of a csHash<> or csHashReversible<>. Consult the Public API Documentation of csHash<> for more information.

iTextureManager::FreeImages() Removal

iTextureManager::FreeImages() has been removed. It was used to release the `iImage' objects associated with textures with the purpose of freeing up memory. This happens automatically now; the images associated with a texture are released by the renderer as soon as the image data is converted into the internal texture format (that is, uploaded to the graphics hardware).

Java Bindings

The Java bindings for Crystal Space have been fully integrated into the project and are now well-supported. It is now possible to write Crystal Space program entirely in Java. See section 7.8.2 Java Bindings.

The Crystal Space Java classes now reside in a package named `org.crystalspace3d' in order to reflect Crystal Space's new official domain name "crystalspace3d.org". This replaces the older package name `com.crystalspace', which itself replaced the much older name `net.sourceforge.crystal'.

VFS Changes

At initialization time, VFS now merges all `vfs.cfg' files located during its start-up scan. Previously, VFS stopped scanning at the first discovered `vfs.cfg', and loaded only that file. During the start-up scan, it searches for a file named `vfs.cfg' in the application resource directory (csGetResourceDir()), then in the directory containing the application (csGetAppDir()), and finally in the Crystal Space installation directory (csGetConfigPath()). The full set of directories mounted by VFS following the initial configuration file scan is the union of the entries in all of the discovered `vfs.cfg' files. If there are conflicting entries, then mounts and variable assignments specified in configuration files discovered earlier in the scan take precedence over those discovered later.

iEvent Changes

The iEvent::Find() method was renamed to Retrieve() and exhibits different return value semantics. Rather than returning a mere boolean result, it now returns one of the `csEventError' enumeration constants. Of particular note, in the case of success, csEventErrNone is returned, which has a value of 0. This success value could be misinterpreted as "false" by the unwary when fixing code to deal with this semantic change. Conditionals which test if retrieval of an attribute succeeded must be changed to take this new semantic into account. For instance, code such as the following:

 
iEvent* ev = ...;
if (ev->Find(...))
{
  ...
}

must be changed to perform an explicit test on the return value of Retrieve(), rather than relying upon default boolean semantics:

 
if (ev->Retrieve(...) == csEventErrNone)
{
  ...
}

Old Renderer Architecture Removed

The old rendering architecture along with the old renderer plugins have been removed. Additionally, a few plugins, applications, classes, and methods have been deprecated because they are not applicable to the new rendering architecture. The results of the old renderer removal are summarized below.

Removed plugins

The following plugin modules have been removed:

Removed Application

The `perftest' application has been removed, since it is no longer has any purpose. For the future the `csbench' application should be extended to provide more information.

Removed and Renamed Files

The following files were removed:

The following files in `data/shader' were renamed:

Removed Methods and Classes

The following methods have been removed from the `iGraphics3D' interface:

From `iRenderView', the following fog-related methods have been removed. Fog is now calculated within the renderer.

From `iMeshObject' and `iParticle', the following rendering-related methods have been removed:

Apart from these methods, the following classes and structures have been removed or have become private, and are no longer available to client code:

Query Macros

The macro CS_QUERY_REGISTRY_PLUGIN() has been added to `iutil/plugin.h'. This is a convenience macro which embodies the common idiom of first querying the object-registry for an object implementing some interface, and then asking the plugin manager to load a plugin supplying the desired object if it was not found in the object-registry. It also registers the object with the object-registry if the plugin manager loads it successfully.

Random Number Generator Changes

The global function csFastRandFloat() has been retired. In its stead is the new instantiable class `csRandomFloatGen', which is modeled after the `csRandomGen' class. Unlike the old csFastRandFloat() function which was shared by all clients, instances of `csRandomFloatGen' can be controlled and seeded individually, thus making it far more flexible and useful. (Note that the more general-purpose `csRandomGen' class is also able to vend floating point numbers.)

`iImage' Changes

The `iImage' interface has been reduced to a level where it merely serves as a container for pixel data; however, the image editing functionality was only relocated, not removed.

Forbidding direct manipulation of an `iImage''s pixel data has the following consequences:

As a side-effect of these changes, the `csImageFile' and `csImageMemory' were merged and the former removed.

`iMaterialList' Change

The function iMaterialList::NewMaterial() now needs an additional name parameter. It is not recommended to change the name later.

iObjectModel Change

The function iObjectModel::GetObjectBoundingBox() only has one parameter now. The optional `type' parameter has been removed as it was not implemented anywhere. In addition to that the constants CS_BBOX_NORMAL, CS_BBOX_ACCURATE, and CS_BBOX_MAX are also removed.

iImageIO::Load() Parameter Change

iImageIO::Load() now requires the image source data in an `iDataBuffer' object, instead of separate `buffer' and `size' parameters.

`iRenderBuffer' Generalization

The `iRenderBuffer' interface was made renderer-independant. Consequently, creation was moved out of `iGraphics3D' and into `csRenderBuffer'. The semantics of the parameters have changed too: notably, instead of specifying the byte size of a buffer, the element count is specified. The same change has been made to CopyToBuffer() (which has been renamed to CopyInto() to enforce human correction of the parameters).

`iLight' Changes

The `iLight' and its implementation (`csLight') have been extended to also handle spot- and directional-lights. Note that the accual computation of lighting does not yet support these, however the engine can now store and handle the required data.

There have also been two smaller changes to the interface to make it more coherent. The influence radius have been renamed cut-off distance, and thus the methods GetInfluenceRadius() and SetInfluenceRadius() have been renamed accordingly to GetCutoffDistance() and SetCutoffDistance(), respectively. Also, SetAttenuation() has been renamed to SetAttenuationMode() in order to avoid confusion with other similary named methods. For the CS_ATTN_LINEAR attenuation type the specification has changed slightly. As a default, the distance where light goes out is same as the cut-off distance, but this can be changed by altering the first attenuation constant. See comments in `CS/include/iengine/light.h' for exact details of the different attenuation modes.

CS_DECLARE_OBJECT_ITERATOR() Removal

The `iObject' iterator creation macro CS_DECLARE_OBJECT_ITERATOR() has been replaced by the templated class csTypedObjectIterator<>. Given existing code, such as:

 
iObject* parent = ...;
CS_DECLARE_OBJECT_ITERATOR(MyFooIter, iFoo);
MyFooIter iter(parent);
while (iter.HasNext())
{
  iFoo* foo = iter.Next();
  ...
}

Revise the code by instantiating the new template class:

 
typedef csTypedObjectIterator<iFoo> MyFooIter;
MyFooIter iter(parent);
while (iter.HasNext())
{

Or, even simpler without the `typedef':

 
csTypedObjectIterator<iFoo> iter(parent);
while (iter.HasNext())
{

Reference Count Automation

For consistency with the bulk of the Crystal Space API, and in order to simplify reference-count management, the following methods have been changed to return csRef<> rather than raw pointers of which the client had to dispose manually via DecRef().

Render Buffer Changes

Previously meshes provided render buffers via name, and these were mapped using name <-> OpenGL name mapping. But most meshes only provided a few standard-named buffers (such as, `vertices', `texcoords', etc.) and the mapping itself took some time (5%+ per frame). This has been reworked.

Now, meshes can provide a set of 16 buffers in a fixed structure. Meshes can provide `index', `position' (vertices), `normal', `color', `color_lighting' (pre-lit colors), `texcoord0', `texcoord1', `texcoord2', `texcoord3', `texcoord_lightmap', `generic0', `generic1', `generic2', `generic3', `tangent' and `binormal' buffers. At the very least, meshes should provide `index', `position', and if possible `texcoordn'. The old system with custom named buffers is also supported.

Both kinds of buffers can be mapped, and the destinations for both kinds of buffers are the same (listed here): `position', `normal', `color', `primary color' (alias for `color'), `secondary color', `texture coordinate n' (where 0 <= n < texture units; `texture coordinate' is alias for n = 0), and `attribute n' (where 0 <= n < 16). Note that you can not map buffers of different kinds (the `normal' and the custom buffers) to same destination; the result is undefined).

The normal buffers are named `position', `normal', `color', `primary color', `lit color', `texture coordinate n' (where 0 <= n < 3), `texture coordinate lightmap', `generic n' (where 0 <= n < 3), `binormal', and `tangent'. These appear in the `source="..."' tag within the XML shader description.

Mapping of custom buffers is accomplished as so:

 
<buffer
  customsource="custombuffername"
  destination="texture coordinate 1"
/>

And, mapping of a normal buffer is done this way:

 
<buffer
  source="tangent"
  destination="texture coordinate 2"
/>

As a convenience, three buffers are mapped automatically by default (as long as the mesh provides them). They are:


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated using texi2html