v1.1.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Modules Pages
Macros
Macros

Utility, logging, and scripting macros. More...

Macros

#define ALWAYS_INLINE
 Always enable inlining for one function. More...
 
#define arraysize(a)
 
#define ASSERT(_x)
 Runtime debug assertion. More...
 
#define CUBE_ALLOCATION   12
 Compile-time cube limit for the current application. More...
 
#define DEBUG_ONLY(_x)
 Mark a chunk of code as debug-only. More...
 
#define LOG(...)
 Smart printf-like logging macro. More...
 
#define LOG_FLOAT(_x)
 
#define LOG_FLOAT2(_x)
 
#define LOG_HEX(_x)
 
#define LOG_INT(_x)
 
#define LOG_INT2(_x)
 
#define LOG_INT3(_x)
 
#define LOG_STR(_x)
 
#define MAX(a, b)
 
#define MIN(a, b)
 
#define NOINLINE
 Disable automatic inlining for one function. More...
 
#define NULL
 
#define offsetof(t, m)
 
#define SCRIPT(_type, _code)
 Inline emulator scripting, for automated testing and more. More...
 
#define SCRIPT_FMT(_type,...)
 Like SCRIPT(), but this variant supports format specifiers. More...
 
#define SCRIPT_TYPE(_type)
 
#define SRCLINE
 
#define STATIC_ASSERT(_x)
 
#define STRINGIFY(_x)
 
#define TOSTRING(_x)
 A second-level wrapper around the C preprocessor stringification operator. More...
 

Detailed Description

Utility, logging, and scripting macros.

This section includes common C++ utility macros, as well as macros which implement platform-specific logging and debugging support.

Macro Definition Documentation

#define ALWAYS_INLINE

Always enable inlining for one function.

For example:

void ALWAYS_INLINE myFunction() {
    // Must be inlined
}

This attribute may be useful in cases where a function would normally not be inlined, but for either performance or correctness reasons you need it to be. Inlined functions are just as fast as macros.

#define arraysize (   a)

Calculate the number of elements in a C++ array, using sizeof.

#define ASSERT (   _x)

Runtime debug assertion.

On release builds, ASSERT has no effect. On debug builds, the argument is evaluated, and if it is False, the current program aborts with an Abort fault, after logging the text of the failed test, along with the line number and file where it occurred.

Normally you would disable ASSERT by linking your binary as a release build. However, sometimes it can be useful to have a build with symbols but without assertions. For example, this can be used to isolate problems that, for whatever reason, only show up with assertions disabled. You can do this by setting the -DNO_ASSERT compiler option.

#define CUBE_ALLOCATION   12

Compile-time cube limit for the current application.

These SDK headers use CUBE_ALLOCATION to size many internal arrays, such as the array of loading FIFOs in AssetLoader, or the array of base addresses in an AssetGroup. You

Every game can individually define a compile-time limit for the number of supported cubes, by supplying their own value for CUBE_ALLOCATION in their Makefile or with a preprocessor definition that is always included above the SDK headers.

It must be less than or equal to the firmware limit of 24. Many data structures are statically allocated using this number, so if a game is running low on RAM it can decrease the limit, or if it needs more cubes it can be increased.

#define DEBUG_ONLY (   _x)

Mark a chunk of code as debug-only.

This code will be disabled at link-time on release builds. For example:

DEBUG_ONLY(doDebugStuff());

DEBUG_ONLY({
    // Do some inlined debug stuff here.
});

This macro acts like a C statement, and it may include any C statement or block. The supplied code is not removed at compile-time, so any compile-time side effects (such as using the value of a variable) always occur. The argument is wrapped in a _SYS_lti_isDebug() test. This function evaluates to either true or false at link-time. So, at link-time, if the -g flag was not passed to Slinky, the enclosed code is optimized out.

#define LOG (   ...)

Smart printf-like logging macro.

This macro acts like printf(), but with some important differences:

  • Most but not all standard format specifiers are supported.
  • Many new format specifiers are available, as listed below.
  • Like the DEBUG_ONLY macro, these macros always generate code at compile-time, but they are fully optimized out at link-time when linking a release binary.
  • Any parameters which are known to be constant at link-time are expanded right away, and no corresponding code is generated. This also means that string literals inserted with %s behave exactly the same as if the corresponding string had been escaped properly and included as part of the format string.

In fact, the linker does a lot of work to support these logging macros in the most efficient way possible. The format string is parsed by Slinky, and a sequence of logging packets are generated. These log packets may contain raw binary data (for strings, hex dumps) or they may contain a set of unformatted printf()-like parameters, along with a reference to a format string in an external string table.

The format string is not stored in your game's read-only data segment. Instead, it is part of your game's debug symbols. This means that when running a debug build on real hardware, the format strings never have to be installed on the Base. Instead, your PC uses the binary's debug symbols to decode very terse un-formatted log packets back into the full text output.

Normally you would disable debugging by linking your binary as a release build. However, sometimes it can be useful to have a build with symbols but without LOGs. For example, this can be used to isolate problems that, for whatever reason, only show up with LOGs disabled. You can do this by setting the -DNO_LOG compiler option.

Logging supports a variety of format specifiers. Most of the standard printf() specifiers are supported, plus we have several new ones:

  • Literal characters, and %%
  • Standard integer specifiers: %d, %i, %o, %u, %X, %x, %p, %c
  • Standard float specifiers: %f, %F, %e, %E, %g, %G
  • Four chars packed into a 32-bit integer: %C
  • Binary integers: %b
  • C-style strings: %s
  • Hex-dump of fixed width buffers: %(width in bytes)h
  • Pointer, printed as a resolved symbol when possible: %P
Note
In the siftulator, LOG() will write to your console or terminal. In order to access LOG() output on hardware, see the Logging section in the Device Management guide.
#define LOG_FLOAT (   _x)

Convenience macro for tracing the name and value of a floating point expression

#define LOG_FLOAT2 (   _x)

Convenience macro for tracing the name and value of a floating point 2-vector expression

#define LOG_HEX (   _x)

Convenience macro for tracing the name and value of an expression, in hexadecimal

#define LOG_INT (   _x)

Convenience macro for tracing the name and value of an integer expression

#define LOG_INT2 (   _x)

Convenience macro for tracing the name and value of an integer 2-vector expression

#define LOG_INT3 (   _x)

Convenience macro for tracing the name and value of an integer 3-vector expression

#define LOG_STR (   _x)

Convenience macro for tracing the name and value of a C-style string

#define MAX (   a,
 
)

Macro which returns the largest of two values. Values are evaluated twice.

#define MIN (   a,
 
)

Macro which returns the smallest of two values. Values are evaluated twice.

#define NOINLINE

Disable automatic inlining for one function.

For example:

void NOINLINE myFunction() {
    // Won't be inlined
}

This attribute may be useful in cases where you want to explicitly prevent a function's code from being included into its callers, for debugging or for cache optimization reasons.

#define NULL

Invalid pointer. Equal to zero.

#define offsetof (   t,
 
)

Calculate the byte offset from the beginning of structure t to member m

#define SCRIPT (   _type,
  _code 
)

Inline emulator scripting, for automated testing and more.

Scripting is a feature available only when running debug builds in Siftulator. All inline scripting is removed at link-time when building a Release binary.

This macro runs the specified 'code' in Siftulator's scripting environment. 'type' indicates which scripting language/environment the code is intended for. Right now the only supported type is LUA.

For example:

SCRIPT(LUA,
    package.path = package.path .. ";scripts/?.lua"
    require('my-test-library')
);

SCRIPT(LUA, invokeTest());

SCRIPT(LUA, System():setAssetLoaderBypass(true));

SCRIPT(LUA, Cube(0):saveScreenshot("myScreenshot.png"));

SCRIPT(LUA, Cube(0):testScreenshot("myScreenshot.png"));

These script fragments are all executed in the same global Lua context. Each script fragment executes synchronously with your game code.

See the Scripting documentation for more info.

#define SCRIPT_FMT (   _type,
  ... 
)

Like SCRIPT(), but this variant supports format specifiers.

This can be used to pass parameters back and forth between Lua code and your game's code, when running in Siftulator.

For example:

SCRIPT_FMT(LUA, "Frontend():postMessage('Power is >= %d')", 9000);

int luaGetInteger(const char *expr)
{
    int result;
    SCRIPT_FMT(LUA, "Runtime():poke(%p, %s)", &result, expr);
    return result;
}

void luaSetInteger(const char *varName, int value)
{
    SCRIPT_FMT(LUA, "%s = %d", varName, value);
}

This is implemented using the same formatter as LOG(), so all of the format specifiers and features described in LOG()'s documentation apply to SCRIPT_FMT() as well.

#define SCRIPT_TYPE (   _type)

This macro is used as part of the implementation of SCRIPT() and SCRIPT_FMT(), but it may also be useful on its own in special circumstances.

This macro sets the current scripting backend which receives log messages. If the scripting backend is set to NONE, LOG() messages behave normally. If a different scripting engine is specified, however, fully formatted LOG() text is accumulated in a buffer in Siftulator until such time as the scripting backend is set back to NONE. At that moment, the scripting backend has a chance to synchronously interpret the buffer of logged text.

#define SRCLINE

Expands to a string literal uniquely identifying the file and source line where it appears.

#define STATIC_ASSERT (   _x)

Produces a 'size of array is negative' compile error when the assert fails

#define STRINGIFY (   _x)

A macro wrapper for the C preprocessor stringification operator.

#define TOSTRING (   _x)

A second-level wrapper around the C preprocessor stringification operator.

Necessary if you wish to stringify tokens after macro expansion rather than before.