Configuring your game using ICF file settings

If you cast your mind back to the "Hello World" project in the very first chapter of this book, you will recall that we used the ICF file to display a different welcome message depending on which platform the code was being executed on. Don't worry if you've forgotten how all this works, as we'll be covering it again shortly.

This functionality proves extremely useful when we are trying to target as many different devices as possible, as there are built-in parameters that allow us to apply different settings for a range of things including memory usage, OpenGL ES graphics performance, splash screens, and much more.

Built-in ICF settings

ICF file settings are assigned to a section identifier which is defined by placing the name of the section in square brackets. When specifying a value for an ICF setting you must ensure that it appears after the correct section identifier, otherwise it will not be found at runtime and an assert will be raised. Here's an example:

[S3E]
MemSize=10000000
SysAppVersion="1.0.0"

There are far too many ICF settings to be able to cover all of them in this book, so instead we'll be taking a look at some of the more immediately useful ones. If you want to see a complete list, take a look in the Marmalade documentation, by going to Marmalade | Marmalade Development Tools Reference | ICF File Settings.

The following table shows a few of the settings that control Marmalade at its lowest level. The section identifier for these settings is [S3E]:

Setting

Value type

Description

MemSize

Integer

The size, in bytes, of the main memory heap available to an application. A Marmalade application can actually have up to ten memory heaps available, so there are also settings called MemSize0 through MemSize9, which allow the sizes of these heaps to be declared. MemSize0 is actually equivalent to using MemSize. For more information on memory heaps take a look at the s3eMemory API in the Marmalade documentation.

MemSizeDebug

Integer

The size, in bytes, of the debug memory heap when a Windows debug build is executed. This is a special block of memory that is used for tasks such as processing 3D models and converting textures to different formats during the resource building process.

SysAppVersion

String

Allows an application to access its version number. While this value can be set in the ICF file, it can also be set using the MKB deployment's version setting.

SysGlesVersion

Integer

Identifies whether the application should attempt to initialize an OpenGL ES 1.x or 2.x interface. Only the major version number (that is, 1 or 2) can be specified.

SysStackSize

Integer

The size of the stack available to the program, in bytes. It is useful, for example, when an application requires extra stack space (due to heavily recursive algorithms).

SplashScreenFile

String

The name of an image file that will be displayed while an application is loading. The filename is relative to the data directory.

SplashScreenBkR ,

SplashScreenBkG , and

SplashScreenBkB

Byte

A value from 0 through 255 to specify the red, green, and blue component values of the splash screen background color. This is the color that will be used to clear the screen before displaying the specified splash screen image, assuming the image is smaller than the screen size.

SplashScreenWidth and

SplashScreenHeight

Integer

The width and height that the splash screen image should be drawn at. If smaller than the screen size, the image will be centered.

AudioAllowBackground

0 or 1

When set to 1 this allows any audio track a user may have started (for example, through the iPod application on an iOS device) to continue playing when our application starts.

DispFixRot

String

Allows the screen to be locked to a particular orientation, rather than rotating when the user rotates the device. Can be set to one of the following values: Free, Portrait, Landscape, FixedPortrait, or FixedLandscape. The Free setting allows any device orientation, while FixedPortrait and FixedLandscape keep the screen orientation locked to a default portrait or landscape aspect, which can be very important to prevent unwanted screen rotations when using the accelerometer to control a game!

The following table lists some useful parameters for altering the initialization of OpenGL ES. These settings must occur after the section identifier [GL]:

Setting

Value type

Description

AlphaInFrameBuffer

0 or 1

When set to 1, this setting indicates that the frame buffer also includes the destination alpha channel.

EGL_RED_SIZE ,

EGL_GREEN_SIZE ,

EGL_BLUE_SIZE ,

EGL_ALPHA_SIZE

Integer

Indicates the number of bits to be used to store each of the red, green, blue, and alpha channels in the frame buffer. For best render quality, all of these settings would normally be given the value 8, yielding an RGBA8888 display. Most hardware can also support formats such as RGBA5551 and RGB565, which will use less video memory and may render faster at the expense of a drop in visual quality.

EGL_DEPTH_SIZE

Integer

The number of bits to use for the depth buffer. Valid values are 16, 24, and 32, with the latter giving the most precision and therefore least chance of Z-buffer clashes when rendering, at the expense of slower rendering and more memory usage.

We'll finish off with some settings related to resource management that we'll be looking at in more depth later in this chapter. They have been included here for easy reference. The settings reside in the ICF section [RESMANAGER]:

Setting

Value type

Description

ResBuild

0 or 1

When set to 1, the Windows debug build will load resources by parsing the original GROUP files and loading the source models, textures, and other resources. Once the data has been processed, it is saved to the data-ram directory in a binary format. If this setting is set to 0, the source assets will not be loaded and any existing binary-formatted data will be loaded directly. This can speed up testing when there have been no changes made to game data.

ResBuildStyle

String

Specifies the resource building style to use when the Windows debug build is processing the original source assets. As we will learn later in this chapter, this parameter allows us to provide different sets of resources to cater for devices of varying abilities.

Defining new ICF settings

One of the best things about ICF files is that we are able to make use of them ourselves by creating our own custom settings. To define new settings we just need to add them to the file app.config.txt, which is automatically generated for us when creating a new project using an MKB file.

When defining new settings, we can also provide a string of text that explains what this setting is for. While this description isn't actually used or needed by the Marmalade SDK, it's a good way of documenting what a setting is supposed to do!

Note

It is, however, important to add definitions for all our settings to the app.config.txt file because it will prevent the application generating lots of asserts when it is executed. In a Windows Debug build, Marmalade checks to see if an ICF setting has been declared both when loading the ICF file at the start of execution and also whenever we try to access a setting from within our own code.

We can also define our own section identifiers in the app.config.txt file simply by listing the name of the section in square brackets and following it with the new setting definitions. Here's an example illustrating how to create new section identifiers and settings:

[GAME_DEBUG]
SkipToLevel      Skip to a level at game start

[GAME]
FrameRate        The frame rate we want the game to run at
MaximumHealth      Amount of energy the player has at game start

Defining our own section identifiers can be extremely useful when creating library modules, such as the GUI and Localise modules created in Chapter 6, Implementing Fonts, User Interfaces, and Localization. The only difference when creating a module is that the app.config.txt file changes to modulename.config.txt and it should reside in a subdirectory called docs in the module's main directory. As an example, if we were to add our own settings to the GUI module we would create a directory called GUIdocs, and the file that lists the settings would be called GUI.config.txt.

Accessing ICF settings in code

It's very little use to be able to provide settings in the ICF files without some way of accessing them. This is where the s3eConfig API comes into play and we can use it by just including the s3eConfig.h header file.

The first function we will look at is s3eConfigGetString, which takes the section identifier and setting name we want to access and also a pointer to an array of char that will be used to return the value of the setting when the function completes. Since the app.icf file is really little more than an ASCII text file, all this function does is return the string of text following the equals sign for the specified ICF setting.

The char array supplied to s3eConfigGetString should be at least of length S3E_CONFIG_STRING_MAX, as this is the largest string size the function can return. If the requested setting can't be found in the ICF file this buffer will not be changed, which is very useful as it allows us to set up a default value for the parameter in our code.

// Set default first level
char lLevelName[S3E_CONFIG_STRING_MAX];
strcpy(lLevelName, "level1");

s3eConfigGetString("GAME_DEBUG", "SkipToLevel", &lLevelName);
// lLevelName will still contain "level1" if the SkipToLevel setting 
// could not be found in the ICF file

Quite often we will want to specify ICF settings, which just need a numeric value. To make this easier for us, Marmalade provides another function called s3eConfigGetInt, which, instead of a pointer to a char array, takes a pointer to an int variable.

This function will read the setting string from the ICF file and then attempt to convert it into an integer value. If this fails (for example, the string contains non-numeric characters or is out of the range of an int) or the setting does not exist in the ICF file, the variable's current value will not be changed, thus allowing default values to be specified in code.

Both functions will return S3E_RESULT_SUCCESS if the setting value could be retrieved, or S3E_RESULT_ERROR if there was a problem. The function s3eConfigGetError will let us discover what the problem was by returning one of the following values:

Value

Description

S3E_CONFIG_ERR_NONE

No error occurred.

S3E_CONFIG_ERR_PARAM

One of the parameters to s3eConfigGetInt or s3eConfigGetString was not valid. For example, a NULL value passed in.

S3E_CONFIG_ERR_NOT_FOUND

The requested ICF setting could not be found.

S3E_CONFIG_ERR_PARSE

There was a problem converting the ICF setting value to an integer when using s3eConfigGetInt.

Limiting ICF settings by platform and device

When targeting a large number of different devices, it is not uncommon to have a situation where we want to be able to do different things depending on the device the application is running on.

The ICF filesystem makes handling this incredibly easy by allowing us to provide different values for parameters based on both the operating system of the device and even by individual device type.

To begin with, we can provide different settings on a platform-wide basis. The "Hello World" project from Chapter 1, Getting Started with Marmalade, has already demonstrated this, but to recap, we limit the settings to a particular operating system using the OS conditional. This is best illustrated by an example:

[GAME]
FrameRate=20

{OS=BADA}
FrameRate=15

{OS=IPHONE}
FrameRate=30
{}

This example sets a default value for the FrameRate setting of 20. It then overrides this value for Bada devices with a value of 15 and for iOS devices with a value of 30. Note that for legacy reasons the value IPHONE refers to all iOS devices (all versions of iPad and iPod touch as well as all iPhones).

Note

The earlier example ends with open and close braces. This returns all settings made after this point to being global settings that apply to all devices and platforms.

It is also possible to make settings that will only apply to a particular subset of devices on a particular platform. This is done using the ID conditional that first specifies the platform type and then has a comma-separated list of device identifiers that the setting should apply to. Here's another example:

[GAME]
FrameRate=30

{ID=ANDROID "HTC Hero", "T-Mobile G1"}
FrameRate=20
{}

Here we set a default value for the FrameRate setting of 30, then limit the value to just 20 if the game is running on either of the listed Android devices. Quote marks are only required on device names that contain spaces.

Wondering how to discover the device name? Often it is the name of the device, but this is not always the case. The easiest way to discover the device name for a particular device is to create a short test program that makes a call to s3eDeviceGetString, as follows:

const char* lpDeviceID = s3eDeviceGetString(S3E_DEVICE_ID);

Note

The s3eDeviceGetString function and its sibling s3eDeviceGetInt allow us to determine an awful lot of information about the device we're running on, including the operating system, processor type, phone number, current language settings, and much more. Take a look at the s3eDevice.h header file or the Marmalade documentation for more details.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.191.86