Home - Forums - Documentation - Gallery - Bugs


Tutorial Zero: Hello World

This tutorial shows probably the simplest possible Crystal Space application which does not even show graphics.

To display fancy 3D images you need to load your data from the disk. To make this process easier Crystal Space provides virtual file system (VFS) support. VFS provides an abstraction layer which allows, among other things, to merge several real directories and archives into single directory virtually overwriting files if needed. It is very convenient when you want to add modifications to your game. Also CS loads files needed for 3D from VFS.

This tutorial is intended to be your first Crystal Space based program just like it was my first CS based "project".

The code


#ifndef __HELLO_H_
#define __HELLO_H_

#include <crystalspace.h>

class Hello: public csApplicationFramework
	csRef<iVFS> fs;
	csRef<iDataBuffer> data;
	bool OnInitialize (int argc, char* argv[]);
	bool Application ();



#include "hello.h"




bool Hello::OnInitialize (int argc, char* argv[])
  if (!csInitializer::RequestPlugins(GetObjectRegistry(),
    	return ReportError("Failed to initialize plugins!");
    return true;

bool Hello::Application()
	if (!OpenApplication(GetObjectRegistry()))
    	return ReportError("Error opening system!");
	fs = csQueryRegistry<iVFS> (GetObjectRegistry());
	if (!fs) 
		return ReportError("Failed to locate virtual file system!");
	if (!data.IsValid())
		return ReportError("Can not load hello.dat");
	return true;

int main (int argc, char* argv[])
  return csApplicationRunner<Hello>::Run (argc, argv);

Data and configuration files


VFS.Mount.hello = $*$/hellodata$/


Hello World!

Examining the code

The header file declares Hello class based on csApplicationFramework. It is the main class of our application we need to implement several virtual methods called by CS. We also declare variables that store file-system object and data retrieved from file. In real game your class would also derive from csBaseEventHandler to respond to user's actions, but since we do not handle any events in this small example we do not need it.

We declare two csRef<> members. These are smart pointers pointing to objects that store the number of pointers referencing them. When you assign new values to csRef<> variable it automatically recalculates the number of references to the object to automatically free the memory used by the object when it is no longer needed.

main() just calls csApplicationRunner<Hello>::Run(...). The Run method, among other things, handles command line parameters, creates Hello object and calls your object's OnInitialize() and Application() methods.

OnInitialize() uses csInitializer::RequestPlugins to tell CS what we need from it. We only ask for VFS, but serious projects will, surely, need more.

Application() checks that everything is initialized and attempts to load data from file on virtual file system and output it using fprintf(). In case of failure it displays an error message. In real program you place Run() which starts redraw and event handling loops, but we do not need it in program that simple.

Looking at VFS configuration and data files

As CS initializes VFS it search for vfs.cfg in executable's working directory. If it is missing vfs.cfg from CS directory is used. In our case the only line of configuration file maps real ./hellodata dir to virtual /hello dir. Let's looks closer at it. On the left size you see VFS.Mount.hello meaning /hello dir on virtual filesystem. On the right you see $*$/hellodata$/. $* means program directory, $/ reflects platform independent directory path separator. Path ending with $/ means directory, path ending with filename maos to zip-archive. You can specify several dirs separated by comas with higher priority sources coming first.

hello.dat is a plain text file with "Hello World!" we want to display. Put it to hellodata subdir of executable's directory and it will be on the VFS.


Now compile and run. You will see "Hello World!" in the terminal. Rename the data file to see, that errors are reported and identified correctly. Add more directories to vfs.cfg and see what happens.

| Article | Discussion | View source | History |