Navigating The Playground SDK - Tim Mensch
Navigating The Playground SDK - Tim Mensch
by Tim Mensch
Navigating the Playground SDK™
America Online®, AOL.com®, and AOL® are registered trademarks of AOL LLC.
This book is an independent publication and is not affiliated with, nor has it been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
Printed by http://LuLu.com.
I User’s Guide 1
1 Introduction 3
1.1 Welcome to the Playground SDK™! . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 What’s on the Playground? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 Getting Started 7
2.1 How to Play on the Playground . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 A First Example Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3 Game Assets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.4 The Game Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.5 Dealing With User Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.6 Why Modal Windows Are Your Friend . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.7 How to use Playground SDK™ features. . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.8 What is Lua? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.9 Lua Makes it Easy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.10 What About Speed? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.11 What are the pitfalls? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3 Playground Fundamentals 25
3.1 Dynamic Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.2 RTTI in TWindow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.3 How to Share and Play Well With Others . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.4 Using shared_ptr (TClassRef) Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
ii CONTENTS
4 Beta Versions 39
4.1 How to Create Limited Builds for Beta Testers . . . . . . . . . . . . . . . . . . . . . . 39
4.2 Tracking Game Metrics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.3 Writing Status on Elapsed Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.4 FirstPeek Module Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5 Lua 47
5.1 About Lua . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.2 Using Lua to Script Your Game . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.3 How do I get Lua data in my C++ code? . . . . . . . . . . . . . . . . . . . . . . . . . 55
6 Particle System 57
6.1 Particles in a Scripting Language? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
8 Game Footprint 69
8.1 Smaller is Better . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
8.2 Shrinking Your Game . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
9 Utilities 71
9.1 FirstStage: The Playground Resource Editor . . . . . . . . . . . . . . . . . . . . . . . 71
9.2 FluidFX 2.0: Interactive Particle System Editor . . . . . . . . . . . . . . . . . . . . . . 90
9.3 sidewalk: Command Line Animation Creation . . . . . . . . . . . . . . . . . . . . . . 92
9.4 Filmstrip: Creating and Editing Animations . . . . . . . . . . . . . . . . . . . . . . . 95
9.5 3dsconvert: Creating 3d Models For Playground . . . . . . . . . . . . . . . . . . . . . 104
9.6 Creating a Playground Font . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
9.7 axtool: Testing Your Game in a Browser . . . . . . . . . . . . . . . . . . . . . . . . . . 105
9.8 xml2anm: Convert XML to ANM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
II Reference 115
Playground 4.0.17.1
iv CONTENTS
Playground 4.0.17.1
vi CONTENTS
Playground 4.0.17.1
0.1 Playground SDK™ Documentation ix
Playground 4.0.17.1
x CONTENTS
User’s Guide
Chapter 1
Introduction
The Playground SDK™ is designed to provide all of the core features you’ll need to create a pol-
ished, successful downloadable game while handling many of the distractions that would other-
wise slow you down. A game written in Playground will run on multiple platforms, including
Windows, Windows-ActiveX, and Mac OS X 10.4. Playground is an object-oriented C++ library
that relies on Lua for scripting support. Familiarity with Lua is helpful, but not a requirement,
since most of the game is written in C++. Like C++ itself, Playground exposes both low-level
and high-level functionality, giving you the ability to directly modify textures and map them on
polygons at the lowest level, and a game-centric GUI/windowing system at the highest level.
While the Playground team has its own ideas as to how Playground should be used, we’ve tried
not to overly restrict the number of development paradigms that make sense. For example, button
messages can be set up to run entirely in Lua, or you can ignore Lua and simply process button
messages in C++. Dialogs can easily be specified in a human-friendly format based on Lua, or they
can be completely constructed by hand. Some developers are using their own custom libraries to
do just about everything, handing only polygons to Playground to render, though in those cases
it’s often harder to guarantee cross-platform portability.
We’re also constantly working on the Playground SDK™ to improve it; if you have a suggestion,
idea, or complaint about the SDK, please let us know so that we can address it! Internally the code
has been written for easy modification, so we’re not afraid to add new features if they seem useful.
You can learn more about Playground and share your ideas with others at the developer web
site and forum at https://developer.playfirst.com. Between active discussions, important an-
nouncements, and the latest released version of the SDK, it’s a place any active Playground devel-
oper should visit frequently.
4 Introduction
page is a living document—developers are a creative bunch, and from time to time they come up
with new and interesting ways to write code that’s not portable. As that happens, we add new
standards. In addition, in order to ensure that the Playground SDK™ is portable, all platform-
specific functionality you should need resides in the library. If there’s anything missing, please
ask for it!
All APIs exposed by the SDK hide platform-specific complexity behind an abstraction that spec-
ifies the intent of the request rather than the specific platform feature you need. For example,
application configuration data should be managed by the library with no reference in the API to
application-specific information such as a path. The TFile (p. 233) file abstraction allows you to
read and write files with no knowledge of the local file-system topology.
Playground 4.0.17.1
6 Introduction
Getting Started
The easiest way to get started with the Playground SDK™ is to start with the skeleton application,
modifying the window name and splash screen sequence as appropriate for your product. Most of
the substance of your application will live in, or be spawned from, a class derived from TWindow
(p. 496)—the skeleton application creates several TWindow-derived classes.
The TWindow base class provides the functionality you would expect of a hierarchical window
class: Add children, set a position, draw, send and respond to messages or events, and other
standard supporting members and interfaces. Generic messages can be handled using TWin-
dow::OnMessage() (p. 511); other events trigger specific On∗() calls: TWindow::OnChar() (p. 513),
TWindow::OnMouseDown() (p. 512), etc. Note that your window will only get keyboard events
if the window currently has focus; see TWindowManager::SetFocus() (p. 525).
Custom windows are created from Lua resource files using dynamic creation; since C++ doesn’t
support named dynamic creation natively, we’ve added some support macros to enable that func-
tionality. Here’s an example of what that looks like:
Among other things, these macros will declare a ClassId() function that will return the unique
class of the window type. To add a new window type, you register it by passing the ClassId() of
the window to TWindowManager::AddWindowType (p. 526). From main.cpp in the skeleton:
This sequence allows you to specify the position and size of the game window in a Lua resource
file, which (minimally) looks something like this:
GameWindow Lua
{
x=20, y=20, w=600, h=600
}
In this file you would also define any buttons that are children of that window, or alternately any
background or status windows that are separate from the game window. The hierarchy can work
however you like—a bunch of sibling windows that sit exactly next to each other, a strict hierarchy,
or a hybrid. See Using TWindows (p. 20) for more information on deriving a class from TWindow.
A number of window types are defined for you by Playground, including buttons (TButton
(p. 202)), text (TText (p. 433)), editable text (TTextEdit (p. 440)), and bitmaps (TImage (p. 249)).
Look at the derived classes in the TWindow documentation to see a complete list.
Assets are loaded and managed by Playground in reference-counted containers. The T∗Ref classes
are the containers, e.g., a TTextureRef (p. 548) holds a TTexture (p. 463) that you acquire from
TTexture::Get() (p. 465). See Game Assets (p. 13) for more information.
See TTexture::Draw and TTexture::DrawSprite (p. 467) for ways to draw your texture on the
screen. These draw calls should only be called in your derived TWindow::Draw() (p. 503) func-
tion, in a TBegin2d (p. 200) block.
3d models and sounds are handled similarly to textures: A TSound (p. 409) is acquired with
TSound::Get() (p. 410) and stored in a TSoundRef, and a TModel (p. 304) is acquired using
TModel::Get() (p. 306) and is stored in a TModelRef. You can play a TSound (p. 409) with
TSound::Play() (p. 410). Drawing the TModel (p. 304) is done with TModel::Draw() (p. 305) after
setting up the model’s texture, matrices, and lighting. See the section in TRenderer (p. 370) on
3d-related functions for more information.
C++
void Main(TPlatform* pPlatform, const char* /*cmdLine*/ )
{
InitializeGameState();
TSettings::CreateSettings();
TSettings::GetInstance()->InitGameToSettings();
This code is from main.cpp in the skeleton project. The functions are straightforward: The window
title is the text that appears in the bar at the top of the window. The InitGameToSettings() call
loads the application’s saved settings and initializes the window to full screen or windowed mode,
depending on the user’s saved preferences.
TWindowManager * wm = TWindowManager::GetInstance();
wm->AddWindowType("GameWindow",TGame::ClassId());
wm->AddWindowType("MainMenu",TMainMenu::ClassId());
wm->AddWindowType("OptionsWindow",TOptions::ClassId());
wm->AddWindowType("HiscoreWindow",THiscore::ClassId());
wm->AddWindowType("ChoosePlayerWindow",TChoosePlayer::ClassId());
wm->AddWindowType("CreditsWindow",TCredits::ClassId());
wm->AddWindowType("Swarm", TSwarm::ClassId());
wm->AddWindowType("ChessPiece", TChessPiece::ClassId());
Here we set up a custom cursor for the application. Then, for convenience, we grab a pointer to
the window manager. Then we register several window creation commands, which will allow us
to easily specify our custom windows later.
// Start the Lua GUI script; this script will never exit C++
// in a typical Playground application.
wm->GetScript()->RunScript("scripts/mainloop.lua");
This last call to TScript::RunScript() (p. 392) causes our Lua main loop to begin.
Playground 4.0.17.1
10 Getting Started
that dance around in response to user interaction. You can have more than one of these window
classes in your application, and you can even specify that several coexist on the same screen—but
in order for the screen building code to know how to create your custom window, your window
needs to have dynamic creation (p. 25) enabled.
First, in the class definition:
PFTYPEIMPL_DC(TGame); C++
Pretty simple. If something needs to happen after the window has been created, you can override
either the TWindow::Init (p. 501) function, or the TWindow::PostChildrenInit (p. 502) function,
depending on when it needs to happen.
To enable the custom window in the window scripts, you just need to call TWindowMan-
ager::AddWindowType() (p. 526) with the window name and class id:
wm->AddWindowType("GameWindow",TGame::ClassId()); C++
And then the window will be created in the script with a simple:
... Lua
GameWindow
{
x=300,y=100,w=400,h=400
},
...
2.2.3 Lua Main Loop? Custom Window Creation? What’s this about?
The Playground SDK™ uses Lua as a way to achieve light cooperative multithreading, as well as
for dialog/window layout. In the Lua main loop script, you can specify the order of windows you
want to display, or a simple animation sequence, or pop up a modal dialog. When it’s time for the
script to pause (to wait for an animation or user input), you call a command that returns control to
the C++ code. Some commands, like DisplaySplash() (p. 144), implicitly return control and wait
for a specified amount of time before continuing. Others, like DoModal() (p. 145), pause to wait
for a particular event, such as the closing of a window. Here is the main Lua GUI loop:
DisplaySplash(
"splash/playfirst_animated_logo.swf",
"splash/playfirst_logo",4000
);
DisplaySplash("", "splash/distributor_logo",4000);
while true do
DoMainWindow("scripts/mainmenu.lua");
-- DoMainWindow will exit only if there are NO windows pushed on the stack, so
-- a PopModal()/PushModal() combination will not cause this to loop.
end
end
That last return statement is important: When you call TScript::RunScript (p. 392), it just runs
through the script once and returns. What we want to happen is for it to be able to run in a
threaded manner. So TScript::RunScript (p. 392) watches for a return value from the script that it
just ran, and if it finds one that’s a function, it runs the function as a thread.
So what’s happening here? First, a call to DisplaySplash() (p. 144) displays a splash screen for
4000ms (or until the user hits a key). A second call to DisplaySplash() (p. 144) brings up the
second screen for 2000ms. Then an endless loop starts that consists entirely of bringing up the
game selection screen. Why is it an endless loop? Because the game selection screen destroys itself
when someone selects a game, and so when the user is done playing and the DoModal() (p. 145)
subroutine finally exits, the game will need to create a new game selection screen.
if (event.mType == TEvent::kClose)
{
TWindowManager::GetInstance()->GetScript()->RunScript("scripts/quitverify.lua");
}
if (event.mType == TEvent::kFullScreenToggle)
{
TSettings::GetInstance()->UpdateFullScreen();
}
Here we have our "message pump," the place where top level application messages get processed.
This code is pretty straightforward: Get an event, do something if we know how to react to it (i.e.,
if it’s a kClose event), and pass the event on to TWindowManager::HandleEvent() (p. 524) for
further processing. TWindowManagerHandleEvent() then propagates events appropriately; for
Playground 4.0.17.1
12 Getting Started
Game assets are loaded and managed by the library. Internally, they are reference counted, but
the reference count is updated entirely by C++ container classes. To use a bitmap texture loaded
from disk, for instance, you would acquire it from the library using TTextureGet() and keep it in a
TTextureRef (p. 548) instance. The TTextureRef handles the reference counting.
Here’s some code to illustrate:
...
void LoadAssets()
{
// Load myimage.png or myimage.jpg
mMyImage = TTexture::Get("images/myimage");
}
void Draw()
{
// Draw the image to the middle of an 800x600 screen
mMyImage->DrawSprite(400,300);
}
TTextureRef mMyImage ;
}
The basic idea is that you keep around a persistent TTextureRef for each image you need. If you
call TTextureGet more than once for the image you’ve already loaded, it will hand you a second
reference to the same image. When the last TTextureRef to a particular image is destroyed, the
image will be deallocated. Note that when you destroy a window and create a new window, as
when you are switching between game modes, it doesn’t actually delete the old window until you
have created the new window—so any assets in common are simply referenced and won’t need to
be reloaded.
A TTexture can currently be loaded from a JPG or a PNG file, and will be auto-converted to a bit
depth compatible with the current screen resolution. A TTextureRef acts like a pointer:
The example with TTexture (p. 463) above works similarly for TModel/TModelRef, if you plan to
use 3d models.
The skeleton is built of a number of custom window classes derived from TWindow (p. 496). In
a real game, each of these windows could be used to display a different part of the game or user
interface.
Playground 4.0.17.1
14 Getting Started
For example, in the Playground skeleton application the TSwarm class draws a swarm of but-
terflies. The butterflies are managed as sprites; here we create the sprites and assign them to a
container:
TSwarm::TSwarm() : C++
mLastUpdate(0),
mLevel(1)
{
mSpriteHolder = TSprite::Create();
if (at)
{
for (int i = 0 ;i<kNumSprites; ++i)
{
mSprites[i] = TAnimatedSprite::Create(i);
mSprites[i]->SetTexture(at);
mSprites[i]->Play();
TDrawSpec drawSpec(
TVec2( (float)((float)kBoundary+i*(float)(kWidth-kBoundary*2)/10.0F),
(float)((float)kBoundary+i*(float)(kHeight-kBoundary*2)/10.0F) ),
1,0.8F
);
drawSpec.mMatrix.Scale( 0.5F + TPlatform::GetInstance()->Rand()%1000/1000.0F );
mSprites[i]->GetDrawSpec()= drawSpec;
mVelocity[i]= TVec2(0,0);
mSpriteHolder->AddChild(mSprites[i]);
}
}
mHitCount = 0;
}
The member mSpriteHolder is a sprite itself, though it doesn’t have a texture assigned—rather it’s
only being used as a container. The same TAnimatedTexture (p. 182) is being assigned to each
sprite, but since each TAnimatedSprite (p. 175) keeps track of its frames independently, and the
script throws in some randomness, each butterfly flaps its wings independently.
Now that we have a bunch of butterfly sprites, let’s draw them. Here’s the start of the skeleton
application’s TSwarm::Draw:
mSpriteHolder->Draw();
That’s it—now the sprites are drawn on the screen. The particles (p. 57) also get drawn here. We’ll
go into more detail about them later.
Timed event processing is easy in Playground: You can either derive a class from TAnim-
Task (p. 191) and hand it to the current top modal window, or simply activate the internal
TWindow (p. 496) animation timer. Moving the sprites around in the skeleton is handled in
TSwarm::OnTaskAnimate–here is a simplified version for illustrative purposes:
Here TSwarm::OnTaskAnimate() iterates through the sprites and performs some simple math to
move the sprites around. Then it calls TLuaParticleSystemUpdate() on each particle system to
process their animation. Note that it’s calling those systems with a constant value; this tends to
keep the particle system looking more consistent.
To enable OnTaskAnimate(), you have to do one more thing:
The excerpt above is a simplified version of the code in the skeleton application (which also
bounces the butterflies off the edge, damps the velocity, and tries to prevent the butterflies from
clustering).
This is where the ongoing game logic typically takes place: In a routine that’s called at a particular
rate, so your game can always run at the same speed.
Be careful not to put more processing in a call like this than can comfortably be crunched in its
given time slot. If this call were to take longer than 15ms, for instance, then it would be executed
Playground 4.0.17.1
16 Getting Started
again on the very next update pass, and the game would slow down. You can prevent this and
keep your game at a constant speed by increasing the delay step so that it’s always longer than the
call takes.
Here’s the start of a function in the skeleton responsible for rendering the chess piece window,
TChessPiece::Draw.
{
TBegin3d begin3d;
So far it sets up a perspective projection matrix, a default texture, and a default material. Next it
needs to set up the world matrix and a light:
C++
TMat4 localMatrix ;
localMatrix.Identity();
localMatrix = pitch*localMatrix ;
localMatrix[3][0] = 0;
localMatrix[3][1] = -0.75;
localMatrix[3][2] = 3;
mSpinLight.mDir.x = cos(mYaw*2) ;
mSpinLight.mDir.y = sin(mYaw*3) ;
mSpinLight.mDir.z = cos(mYaw*2) ;
mSpinLight.mDir.Normalize();
We’re spinning our chess piece around to mYaw radians and setting up a light at some other orbit
for interesting reflections here. Next we do the actual drawing of the model:
C++
if (mModel)
{
mModel->Draw();
}
begin3d.Done();
}
Note the TBegin3d (p. 201): It’s necessary to tell Playground whether you want it to be in 2d
or 3d mode before you actually do any drawing. This allows us to optimize certain aspects of
set-up, and makes this necessary overhead more explicit so that a game programmer knows that
switching between these modes is expensive.
Finally, we’re simply drawing a box around the window. Not brain surgery. Note TBegin2d
(p. 200), which is analogous to the TBegin3d (p. 201) above. TBegin2d (p. 200) and TBegin3d
(p. 201) are helper classes that automatically release the state on close of scope.
That’s all there is to it. So where did mModel come from? It was initialized in the TChessPiece
constructor along with mTexture:
C++
And there you have it!
Playground 4.0.17.1
18 Getting Started
as boundaries to the game context, and input never travels past them on the stack. In fact, the
TWindowManager (p. 519) maintains a stack of just TModalWindows, and you can query the top
modal window using TWindowManager::GetTopModalWindow() (p. 523).
When Playground starts up, it pushes a special modal window called TScreen (p. 387) on the top
of the window stack. This window must never be popped from the stack, or the game will exit.
The standard paradigm when switching between game modes is to pop the current modal win-
dow off the stack and push your new window; alternately, you can use the Lua function SwapTo-
Modal() (p. 151) if you are not creating custom-derived TModalWindows.
If you need to bring up a game-pausing event ("Are you sure you want to quit?"), you can push
another modal window onto the stack, and pop it when you’re finished. If you have a game with
sub-games, you can push a sub-game window onto the stack. When a new modal window is on
the stack, the previous window gets no messages, its TTask (p. 429) events stop firing, and its clock
stops. Messages and TTask (p. 429) events resume when the child modal window closes. Note
that in order to take advantage of its clock you need to explicitly assign the clock to the class that
needs it, e.g., TAnimTask (p. 191) or TAnimatedSprite (p. 175).
Modal window have no technical limit as to their depth; however it’s probably not wise to push
more than two to three levels, just from a user interface perspective.
• A texture to render.
• A layer value.
• A list of children.
When you create a TSprite you give it a layer, which is used only for sorting relative to its siblings
and parent: Higher numbered layers appear in front of lower numbered layers among siblings,
and negative layers appear behind the parent TSprite.
Each TSprite has an associated TTexture (p. 463), and an inherent TDrawSpec. The latter is used
to position and orient the sprite relative to its parent, and in general to determine how to draw the
texture. See the documentation on TDrawSpec (p. 223) for more details.
A related object, the TAnimatedSprite (p. 175), is identical to the TSprite with two exceptions:
It’s designed to be able to handle TAnimatedTexture (p. 182) particularly well, and it contains a
TScript (p. 389) for animating the TAnimatedTexture. A normal TSprite can have a TAnimated-
Texture assigned to it, since TAnimatedTexture inherits the TTexture interface, and therefore in
object-oriented terms is-a TTexture. However, since TAnimatedTexture objects can be reused, any
animation state has to be kept with each instance–in this case with the TAnimatedSprite object.
• A position.
• An orientation/scaling matrix
Playground 4.0.17.1
20 Getting Started
There are two overloaded versions of TTexture::DrawSprite (p. 467). The first takes a set of sim-
plified parameters, and the second takes a TDrawSpec for increased control over how the image is
drawn. TDrawSpec (p. 223) comes with a convenience constructor that will allow you to set most
common values in-place. After it’s constructed, you can modify it with much more sophisticated
requests if you need to.
There were three reasons for the decision to migrate to a TDrawSpec-style interface: One, TTex-
ture::DrawSprite (p. 467) was really getting over-overloaded with confusingly similar parameter
lists. Two, the parameter lists were getting so long that it became quite annoying to set the ones
later in the list if you just needed to set one or two. And third, the DrawSprite parameters simply
weren’t flexible enough to do full inheritance of rotation/scale matrices, which is what we wanted
for the sprite system.
The process is simple enough. Create a TTask-derived class and override DoTask:
Then call:
Now any time that your texture needs to be redrawn (because of lost surfaces), your function
RenderMyPrivateTextures() will be called.
TTextGraphic * tg = TTextGraphic::Create(
"<outline color=\\"000000\\" size=\\"3\\">SWEET PAUSE</outline>",
512,512,TTextGraphic::kHAlignCenter,"fonts/arial.mvec", 60, TColor(1, 1, 1, 1) );
tg->SetNoBlend();
tg->Draw( TRect(0,0,512,512), 1, 0, 1, mTextTexture );
tg->Destroy();
When this is complete, mTextTexture ends up with SWEET PAUSE rendered in Arial font and a
black outline in a texture that’s transparent except for the text itself which is opaque. The TRect
(p. 364) in TTextGraphic::Draw (p. 449) can be used to position the text: Just bump down the top
Y coordinate for each successive render. The text size is determined in the TTextGraphic::Create
(p. 449) call–I arbitrarily chose 60 pixels tall, but feel free to customize to the appropriate height.
Playground 4.0.17.1
22 Getting Started
Lua is a compact, fast, flexible, and extendable scripting language that is included as part of the
Playground SDK™. Its syntax has a few quirks that we put up with because we love it so much.
You can read more about Lua at http://www.lua.org. We’re currently using version 5.0x of Lua
in Playground, though we’re investigating an upgrade to the latest, 5.1.
Using a scripting language to write the basic control flow of a game is a very powerful technique.
Take, for example the following code:
DisplaySplash(
"splash/playfirst_animated_logo.swf",
"splash/playfirst_logo",4000
);
DisplaySplash("", "splash/distributor_logo",4000);
Here the sequence is clear: Display one splash screen, then another, then enter main options loop.
There’s no jumping around from one place to another to see what happens next; it’s right there in
front of you. If you want to change the sequence, it’s a simple matter of adding or moving a line
of Lua code.
Or this code excerpt from a window definition:
Button Lua
{
x=40, y=40, -- Position of the button
label="Start Game", -- Button text
command=function()
SwapToModal("gamescreen.lua"); -- switch to the game screen
end;
}
Curly-braces in Lua define a table—they’re not used for scope, though they may appear to in the
previous example. The above syntax is a shortcut for calling the function "Button" with a single
table as the only parameter: Button( { x=40 ... } ).
In this table we’re setting a few button characteristics, including its position, label, and a command
to execute when it’s pressed. The Lua command "function" actually defines a function right there
in the Button definition. It’s an anonymous function, in that it doesn’t have a name of its own, but
that’s OK, because in Lua functions are first-class data: You can assign them to variables, return
them from functions, or, as in the case above, add them to a table entry.
If the above example used DoModal() (p. 145) instead of SwapToModal() (p. 151), it would have
simply brought a window up on top of the current window—a standard "Modal" dialog, possibly
asking for user input. And that window could have its own actions embedded in its buttons.
Playground 4.0.17.1
24 Getting Started
with whatever payload you want, and trigger complex events in your game using those messages
rather than just calling the necessary code directly. By "complex", I mean events that themselves
may rely on the Lua interpreter to do something that might require a Yield or Resume.
Playground Fundamentals
Most of the time you’ll probably need to get a TButton directly. That’s where GetCast() comes in–it
works like dynamic_cast to cast our TWindow∗ to an appropriate type, returning a NULL pointer
if the cast is inappropriate:
if (button)
{
// Our window is a button, and now we have a button to play with
}
When writing a game, some objects have clear owners: In the case of a button, it’s fine to allow
the enclosing window to own it and clean it up when it’s destroyed. But there are some situations
where an object or resource has no clear owner. The texture to draw on the button is one simple
example: You wouldn’t want the button to destroy the texture when it’s deleted for fear another
button on the screen is still using it.
One solution to this problem is to use reference-counted pointers: Smart containers that keep track
of how many references are currently held to them. The above example would keep the button
texture around until the last button window holding the texture container was deleted. Additional
tricks can allow you to keep a list of currently loaded textures, so that when each button requests
its texture they all get shared instances of the same texture.
You can use reference-counted pointers to manage your own game objects as well, but it’s impor-
tant to thoroughly understand the implications of using smart pointers before using them. It’s not
really that difficult, but there are a few common traps that you need to be aware of in order to
avoid stumbling into them.
When you include pf/ref.h, you gain access to the shared_ptr template class. Several Playground
classes use shared_ptr internally, and provide convenience typedefs of the form TFooRef, indicat-
ing that it’s a reference-counted container for a Foo. A few common examples include:
• TTextureRef
• TModelRef
• TSoundRef
• TSpriteRef
The full set of Playground shared_ptr typedefs is defined in pf/forward.h (p. 547). In each case
where Playground intends you to use shared_ptrs, the associated class has a static member factory
named Get() (or prefixed by Get) when the class manages sharing of instances of the asset, or
Create() for when you need a new, unique item. See TTexture::Get() (p. 465) or TTexture::Create()
(p. 466) for two examples.
Part of the reason to have factories like this instead of allowing you to new objects and assign them
to shared_ptrs is to help avoid common reference-counted-pointer errors by never encouraging
you to operate on the raw pointers. If you always hold one of these objects in an appropriate Ref
(e.g., TTextureRef) container for as long as you intend to use it, passing it from place to place as a
Ref, and never converting it to a pointer at all, then it’s really hard to make a mistake that would
cause the reference counting mechanism to fail.
Playground 4.0.17.1
28 Playground Fundamentals
Assuming the texture isn’t referenced elsewhere, the code above will assign a dangling pointer to
someTexture. By the time the assignment occurs, the texture object will have been destroyed.
// Correct C++
TTextureRef someTexture = TTexture::Get("foo.png");
Keeping it in a TTextureRef ensures that you keep a reference to it when the temporary on the
right hand side of the assignment operator is destroyed.
In the example above, when someTexture leaves scope, it will delete the texture. Funny thing is,
when textureRef leaves scope, it will also delete the texture. This is not considered a good thing. If
you have a good memory debug tool in place, you’ll find this right away because it will alert you
right when it happens. Without malloc debugging active, some time later, in an unrelated part
of your game, it will probably crash when allocating or freeing memory. And where it crashes
may change between debug and release builds, because the memory allocators work differently
in debug and release. In other words, this is a bug you never want to lay the groundwork for by
// Correct C++
void Foo( TTextureRef texture )
{
...
}
Playground 4.0.17.1
30 Playground Fundamentals
The game name on Windows is extracted from the program’s resource: look in the project’s .RC
file for the ProductName to set the name.
1. Place the pfservlet_stub.dll in the same folder you are loading the pfhiscore.dll from (or in
the same folder as your .exe if you are using a static lib). The system will detect the existence
of this dll, and if it can find it, it will use a local server instead of connecting to one over the
Internet.
2. Make sure that you are correctly setting up the TPlatform::SetConfig (p. 340) settings for
kPFGameHandle, kPFGameModeName, and kEncryptionKey. This is done in Playgroun-
dInit() (p. 544) in the Playground Skeleton sample application.
3. You are now set up to use the hiscore system without connecting to a server. Note that
this will create a file called "serverdata.txt" file in the same folder as the dll that will store
information between executions so you can test building up long lists of scores. Also, note
that this local server does not contain all the functionality as the real online server (i.e. it does
not contain the profanity name filter and it will also not correctly filter the scores by "daily",
"weekly", etc.) but it does have enough functionality for you to fully test your game.
4. The pfservlet_stub.dll comes with 2 user accounts created for testing PlayFirst user submis-
sions. They are "testname" with password "testpass" and "testname2" with "testpass2".
5. Refer to the values recorded in "serverdata.txt" to verify that your score and medals submis-
sions were successful.
// Log a score of 500 points, replace existing score by this player, C++
// and pass in the GAMEDATA string defined elsewhere...
pHiscores->KeepScore(500, true, GAMEDATA);
pHiscores->GetScoreCount(true); C++
for (int i = 0; i < numScores; i++)
{
int rank;
char name[16];
bool anon;
Playground 4.0.17.1
32 Playground Fundamentals
int score;
char gameData[64];
In the local scores screen, you can also change the game mode by setting the game mode property,
and then recalling the code above for the new game mode.
{
if (qualified)
{
// inform user of qualified score
}
else
{
// inform user that score did not qualify
}
pHiscores->RequestCategoryInformation(); C++
TPfHiscores::EStatus status;
char errorMsg[256];
status = mpHiscores->GetServerRequestStatus(errorMsg, 256, NULL);
while (status == TPfHiscores::ePending)
{
status = mpHiscores->GetServerRequestStatus(errorMsg, 256, NULL);
}
if (status == TPfHiscores::eError)
{
DEBUG_WRITE((errorMsg));
}
else if (status == TPfHiscores::eSuccess)
{
int numTables = pHiscores->GetCategoryCount();
Now that you’ve obtained the categories, you can request scores for a specific category. Note that
before you call RequestScores() you must have set a proper game mode with SetProperty() and
you must have received the category information with RequestCategoryInformation().
pHiscores->RequestScores(CATEGORYNUM); C++
TPfHiscores::EStatus status;
char errorMsg[256];
Playground 4.0.17.1
34 Playground Fundamentals
Finally, you can determine the user’s current ranking in the currently fetched table from:
Question: How can I connect to the PlayFirst hiscore server to test my implementation?
Answer: You should be able to fully test your hiscore implementation against the pfservlet_stub.
If it works with this stub (and you have configured TPlatform::SetConfig (p. 340) just like the
Playground Skeleton does in PlaygroundInit() (p. 544)), it will work when your game goes "live".
Question: Hiscores is not working. Can I get any information about why it is failing?
Answer: You should check your logfile. Depending on the error, some information may be dis-
played in the logfile which may make it obvious why your hiscore submission is failing.
Question: QA is telling me that hiscores fail on their server, but they work fine on my stub. What
is the difference?
Answer: Make sure that you are using the PlayFirst provided key.h file, which correctly specifies
the exact names for:
• The game handle (in Windows, this is set in the resource file)
• The encryption key
• The game modes
• The medal names
Question: I can view global hiscores, but all the submissions fail. What is wrong?
Answer: If you can successfully view hiscores but not submit them, then your encryption key is
incorrect.
Question: When I submit a hiscore with medals in it, I get an error in my logfile about invalid
XML. What does that mean?
Answer: (This question involves an older version of the API that is being deprecated - use Keep-
Score/KeepMedals/SubmitData to avoid this problem). XML must be "well-formed". A common
mistake is to forget to close the XML tag with a forward slash. Note that using XML is no longer
necessary for submitting medals - use the KeepMedals and SubmitData calls and this will be han-
dled automatically.
Question: I am seeing weird results when I submit a score and medals. Sometimes I see the "Did
Not Qualify" response, but then the score gets recorded anyway. Other times the system lets me
submit the same score over and over again. What is going on?
Answer: (This question involves an older version of the API that is being deprecated - use Keep-
Score/KeepMedals/SubmitData to avoid this problem). This is most likely because you are issu-
ing several server requests but only looking for one response. Each call to the server must then
poll GetServerRequestStatus() before the next call should take place. One specific situation that
can cause this behavior is if you submit a score, then submit medals, and then poll the server.
The response you get back from the server will be the response to the medals submission only.
Therefore, the response to the score submission is lost completely. The correct thing to do in this
situation would be to submit a score, then poll the server. Once a response is received, a medal
submission could continue, polling for a response to that as well.
Question: Why are there 2 different ways of submitting medals?
Answer: (This question involves an older version of the API that is being deprecated - use Keep-
Score/KeepMedals/SubmitData to avoid this problem). Medals can be associated with a score
(by using the serverData parameter in TPfHiscores::LogScore() (p. 333)), or they can be submit-
ted independently by using TPfHiscores::SubmitMedals() (p. 335). In some games, you can only
earn a new medal at the same time you earn a new hiscore (i.e. you can only earn a medal by
beating a new level, which also means your total score goes up). In this case, by associating a
medal with a score in TPfHiscores::LogScore() (p. 333), you don’t have to worry about how to
submit medals - they will be submitted when the user submits their score. In other games, you
Playground 4.0.17.1
36 Playground Fundamentals
can earn a medal without earning a new score (i.e. by replaying a previous level and completing a
series of events that unlocks a new medal). In this case, the user needs to submit their medals sep-
arately from their hiscore, because they may not have any hiscores to submit. In this case, more
UI needs to be added to the game to inform the user when they have a medal to submit, since
you cannot depend on the existence of a submittable hiscore in order to submit medals. Note that
TPfHiscores::submitScore() and TPfHiscores::SubmitMedals() (p. 335) should never be called im-
mediately one after the other - you always need to poll TPfHiscores::GetServerRequestStatus()
(p. 330) after each hiscore server call.
Question: How do I know if I should be running in full hiscore mode, anonymous hiscore mode,
or local hiscore mode?
Answer: You can use the following to determine which mode to run in:
Question: What is the difference between the full, anonymous, and local hiscore modes?
Answer: This is described in the Production Guidelines document, and your PlayFirst producer
can provide you with the full details about this. Additionally, the Playground Skeleton application
demonstrates each of these 3 modes, which you can test by changing the settings.xml file. The basic
differences between the modes are:
• In "full" mode the user can use a PlayFirst account and password to submit their hiscore.
Scores associated with a PlayFirst account have a special icon displayed next to them. There
is a text description about the PlayFirst global hiscores system, and a description of how to
register for an account.
• In "anonymous" mode users can submit hiscores only with an "anonymous" account. There
is no mention of PlayFirst in the hiscore system, though some text about a Privacy Policy
may be displayed. Please contact your producer for the exact text.
• In "local" mode there is no way to submit a hiscore to the global hiscore system. The user
can only see scores that they have earned on their local computer. There is no mention of the
PlayFirst hiscore system in this mode.
• DEBUG_WRITE() (p. 538) Writes messages to the debug log in debug builds.
• ERROR_WRITE() (p. 539) Writes messages to the debug log in debug and release builds.
• TRACE_WRITE() (p. 539) Writes the current line, function, and file to the debug log (in
debug builds only).
• ASSERT() (p. 538) Breaks in debug builds and prints ASSERT condition to the debug log;
removed in release build.
• VERIFY() (p. 539) Breaks in debug builds and prints VERIFY condition to the debug log; just
prints the condition to the log in release build. Guaranteed NOT to be removed in release
build. Useful for evaluating a function return value where the function has side effects (it
does something important).
On Windows, all printing to the log is mirrored in the debugger output window in debug build.
In release builds, the debug log is capped at 100k, but in debug build it is not limited in size.
• Alt-F1 Bring up a display that includes current game vital statistics, including Playground
build version, frames-per-second, allocated memory, and allocated texture memory. This
works even in release builds.
• F2 Dump a window hierarchy to the debug log.
• Shift-F2 Draw a yellow rectangle on the border of the window the mouse is currently rolling
over.
• F3 Dump all currently allocated assets to the debug log.
Playground 4.0.17.1
38 Playground Fundamentals
You may change the version information defined in version.h for your own purposes, as long as
you keep to the same format. However, please remember that for games released through Play-
First, this file is overwritten by PlayFirst’s release engineering process. This means that the build
numbers that your game has for your own builds will differ from the official builds that PlayFirst
generates. This is by design. If you violate the guidelines here, you will be asked to change your
code back, so that your game source code will not break the PlayFirst release engineering process.
Beta Versions
...or if you already have one, then just add the <firstpeek> line above.
If it isn’t obvious, the number should be ’1’ for FirstPeek and ’0’ for the normal release build. This
file goes in the assets folder next to strings.xml.
In the folder that CONTAINS assets you need two more files:
final.txt firstpeek.txt
These files list asset filenames or that should be EXCLUDED from each view. This way you can
exclude files or folders from FirstPeek using firstpeek.txt, and you can exclude FirstPeek-only
40 Beta Versions
The C++ examples below assume a TGameState (p. 242) pointer called gs. On the other hand,
the Lua examples don’t need one! From within the Lua GUI script, SetState() and GetState() are
available directly:
Lua
Navigating the Playground SDK
4.2 Tracking Game Metrics 41
SetState("MyState", "1" );
The above line sets a state variable named "MyState" to the value "1". Later you can retrieve that
value:
Note that you can call TGameState::SetState() (p. 243) regardless of whether it’s a FirstPeek ver-
sion. In a normal release of your game, the call will simply do (almost) nothing.
Sometimes you just want to record that someone has done something, like the fact that they started
story mode. In that case, you can just call:
gs->SetState("StartedStoryMode",1); C++
If you have a state that keeps track of how many times a user does something, you can prefix it
with the ++ operator:
A state starts out with value 0, so you can use the above line to count how many times the player
uses a lemonade power-up.
Later you will be able to write the state value to the FirstPeek log file, either immediately on
request, at a particular time delay, or at the end of the game, as I will describe below.
Setting the state of any variable to "1" starts a timer with that name, and setting it to "0" pauses that
timer. The overhead is minimal, so don’t worry about setting a variable to "1" even if you don’t
intend to use it as a timer.
If you want to start and stop a timer that keeps track of the time spent in the main menu, you
could use the following code.
...
Playground 4.0.17.1
42 Beta Versions
Button
{
name = "startthegame";
command = function() LeaveMainMenu(); StartGame(); end;
}
...
Sometimes you’ll want to restart a timer so you can use it again. In that case you can set it to the
special value "restart".
gs->SetState("LevelPlayTime","restart"); Lua
It’s OK to set a timer to "restart" even if it’s never been used before. You can stop the timer normally
by setting it to "0".
To write out stats during gameplay, such as at the end of a level, you start by naming the status
line block, and then adding status arguments to it one at a time until you’re done, at which point
you end the status line.
A simple example:
A few things here. First, the block is defined between a "begin-status" and an "end-status" com-
mand. Every value you add between those commands will be added to the status line.
The "add-state" command takes the name of a state that you’ve defined earlier, and it writes out
the current value of that state. You need to have previously set that state to some value, or it will
just write out an empty string.
There are two other commands you can use to add entries to the log line:
The "add-timer" command writes out the value of a state variable that’s being used as a timer.
It needs a different command than "add-state" because its state value is simply "1" or "0"–and
that’s not what you want. To reiterate, when you SetState("LevelPlayTime",1), it effectively
starts an internal timer associated with the key "LevelPlayTime", and later when you call Set-
State("LevelPlayTime",0), that timer is paused.
Finally, "add-value" adds the constant you give it in the second parameter directly. There’s no
lookup performed–in the example above, it simply writes the score (presumably an integer) to the
log file line directly.
A frequent need is to write a status line when the game exits. You could use the above "begin-
status"/"end-status" calls to write the line as your game quits, but we’ve made it even easier.
Instead you can set up a block at the start of the game that it holds onto until the game is being
quit, and on exit it will write out this status line with the values of the states at that time.
A simple example:
gs->SetState("begin-session","SessionData"); Lua
gs->SetState("add-timer","SessionTime"); // Add the session timer to the output
gs->SetState("add-timer","StoryModeSessionTime"); // Add a story mode timer
gs->SetState("add-timer","MainMenuScreenTime"); // How much time spent on the main menu?
gs->SetState("add-timer","ComicScreenTime"); // And how much on the comics?
gs->SetState("add-timer","HelpScreenTime"); // And how much on the help screen?
gs->SetState("add-state","LemonadeUsed"); // Add the current state of LemonadeUsed
gs->SetState("end-session","SessionData"); // Finish recording SessionData output
When the game exits, it will automatically write a SessionData line to the FirstPeek data file with
the final results of the states and timers listed. You can also use "add-value", but keep in mind
that you’re sending it a constant, and that the constant will therefore be defined at the start of the
game rather than later on. If you want to add a variable, then you should set it using SetState()
instead–that’s what it’s for!
Keep in mind that you should only call "begin-session"/"end-session" once during your game. If
you call it more than once, the results are undefined.
You can create status lines that write their output at specific elapsed times. This is similar to
"begin-session", but instead of at the end of a game session, it writes its data after a certain elapsed
time.
The elapsed time calculation is cumulative across sessions: Once they’ve played the game for 15
minutes TOTAL, the 15-minute timer will fire and write the data. It doesn’t matter if they play it
in one sitting or play 5 3-minute games–it keeps track of the cumulative elapsed time.
For example:
Obviously the "15" above is the number of minutes of cumulative gameplay to compare with. If
the game has been played for more than 15 cumulative minutes on launch, this log file line will be
silently ignored.
Playground 4.0.17.1
44 Beta Versions
4.4.1 begin-status/end-status
Parameters:
value The name of the output line.
Begin and end a status line. The status line is written to metrics.txt immediately on receiving the
end-status command.
The line is written in CSV format, with the name, date, time, and cumulative elapsed time as the
first four parameters. Additional parameters can be added with the various add-∗ keys, below.
4.4.2 begin-session/end-session
Parameters:
value The name of the output line.
Begin and end a session line. The session block is written to metrics.txt when the game exits, using
the status variables as they are defined at that point.
See begin-status/end-status (this page) above for details status line format.
4.4.3 begin-elapsed(time)/end-elapsed(time)
Parameters:
time The number of elapsed minutes to use.
value The name of the output line.
Begin and end an elapsed-time data block. The elapsed time block is written to metrics.txt when
the game has been played (cumulatively across all sessions) the number of minutes given as time.
See begin-status/end-status (this page) above for details status line format.
4.4.4 add-timer
Parameters:
value Name of the key to time.
Add the elapsed time that a key has been set to a non-zero value as a parameter to the current
status line block. The value is queried when the status line block is actually written.
4.4.5 add-timer
Parameters:
value Name of the key to query.
Add the value of the given key as a parameter to the current status line block. The value is queried
when the status line block is actually written.
Must be within a status line block (begin-status/end-status (opposite), begin-session/end-session
(opposite), begin-elapsed(time)/end-elapsed(time) (opposite)) to have any effect; an error other-
wise.
4.4.6 add-timer
Parameters:
value Constant value to add.
Add the given value (literal) as a parameter to the current status line block. This value is set
immediately, and not queried when the block is actually written.
Must be within a status line block (begin-status/end-status (opposite), begin-session/end-session
(opposite), begin-elapsed(time)/end-elapsed(time) (opposite)) to have any effect; an error other-
wise.
Playground 4.0.17.1
46 Beta Versions
Lua
• Single or double quotes can be used to frame a string. [[ and ]] will frame a multi-lined string.
You can read more about Lua syntax at http://www.lua.org . We’re linking with the base library,
the string library, and the table manipulation library at present. In debug builds of the library,
the debug library is also linked in. TLuaParticleSystem (p. 264) additionally links with the math
library.
At the most basic level, you need to create a TScript-derived class with your added functionality.
Here is an example:
...
ScriptRegisterMemberDirect(
script, "LuaNameForMyMemberFunction", myClass, MyClass::MyMemberFunction );
See how the constructor binds the C++ member functions directly to Lua functions. See Reg-
isterMemberDirect() for a list of the valid parameter types you can use. For an explanation of
TMessage (p. 294), see the advanced topic Sending Custom Application Messages (p. 111).
The Lua interpreter supports cooperative multithreading. In practice, this means that a script
that is going to persist needs to explicitly or implicitly yield periodically. The most basic yield
command is Yield, which returns control to the C++ code immeidately.
But that doesn’t take into account when your script may want to be run next; TScript (p. 389)
derives from TAnimTask (p. 191) so that it can resume running on a schedule. You can register
your TScript as a task, either at the TModalWindow (p. 298) level or at a global level in TPlatform
(p. 336). Conceptually the difference is that TModalWindow tasks are only executed when the
TModalWindow is the top modal window; another modal window will pause the tasks of any
windows beneath it. Note that the "Adopt" symantics (TPlatform::AdoptTask (p. 345)) means that
you are relinquishing control of the script. It won’t be deleted when it’s done executing, because it
never flags itself as "done" animating, but if the context that owns it is destroyed (i.e., the TPlatform
or TModalWindow), it will be deleted at that point.
To subclass from an existing window type (for example, if you want to have a button that has
some custom behavior in it), all you need to do is be sure that your derived class calls the base
class for any virtual functions it overrides. For example, if you derive from TButton (p. 202) and
create a PostChildrenInit() call in your derived class, you’ll need to call TButtonPostChildrenInit()
to ensure that the base class gets properly initialized.
Here is a brief description of the syntax of the internals of dialog-description Lua files. The first
thing to note is that instead of calling functions with ordered parameter lists, which is the norm in
Lua, we’re calling with the table (Lua’s map/hash/dictionary) syntax: Function{}. This allows us
to have both positional and named parameters.
At the most basic, in the Lua script you need to use the function MakeDialog:
MakeDialog Lua
{
...
}
Inside the body of MakeDialog is a list of (potentially nested) window creation commands. A
typical window will start with an image background:
MakeDialog Lua
{
Bitmap
{
image="background.png"
}
}
This is pretty simple so far. The Bitmap command will create a TImage (p. 249) window scaled to
the size of background.png. There are ways to override this, but we’ll get to that later.
Now say that you also want a button:
PropFont = { Lua
"fonts/prop.mvec",
15,
Color(0,0,91,255)
};
BasicButtonGraphics =
{
"controls/lozengeup.png",
"controls/lozengedown.png",
"controls/lozengeover.png"
};
MakeDialog
{
Bitmap
{
image="background.png", -- Note that this is a list, and needs commas
Button
{
x=kCenter, y=-40, -- See below for coordinate options
name="button3", -- The name used to look up the button
Playground 4.0.17.1
50 Lua
There are several new things here worth mentioning. We’ve added a font for the button text, and
graphic images for the various button states. Note that the graphics entry is a table with three
items: The first is the "up" image, the second is the "down" image, and the third is the roll-over
image. You can skip the third image if the down and roll-over image should be the same.
The font itself is a table with three entries: The font filename (relative to the assets directory), the
font height in pixels, and the font color.
The x and y coordinates can be simple coordinates from the upper left corner of their window, but
there are also other convenient options:
... Lua
Text
{
x=0,y=kMax-80,w=kMax,h=-kMax, -- The entire dialog, minus the bottom 80 pixels
font=PropFont, -- The text font
label="This is text"
},
The x and y coordinates work the same for the text field as above. We’ve chosen not to name this
field, which is okay since it’s just static text (it will get a window id of -1). But we have two new
fields: w and h for width and height. Similar to x and y, a positive number is a number of pixels.
In addition:
• A constant, kMax, specifies that the rectangle should grow to fill available space.
• A positive width or height grows from the right of or down from the corresponding position,
while a negative width or height grows the opposite direction.
• The kMax constant can be negated as well, filling to the left or up from the x,y coordinate.
5.2.4 Styles
Repeating information for each and every widget is tiresome and mistake prone. To address this,
there is a concept of a current style. It’s recommended that most features in your project are
defined using styles.
PropFont = { Lua
"fonts/prop.mvec",
15,
Color(0,0,91,255)
};
BasicButtonGraphics = {
"controls/lozengeup.png",
"controls/lozengedown.png",
"controls/lozengeover.png"
};
DefaultStyle = {
font=PropFont,
graphics=BasicButtonGraphics,
x=0,y=0,w=kMax,h=kMax
}
BottomEdgeButton = {
parent = DefaultStyle,
y=-40
}
BodyText= {
parent = DefaultStyle,
y=-80,h=-kMax
}
MakeDialog
{
SetStyle(DefaultStyle),
Bitmap
{
image="background.png",
SetStyle(BodyText),
Text
{
label="This is text that goes in the body"
},
SetStyle(BottomEdgeButton),
Playground 4.0.17.1
52 Lua
Button
{
x=kCenter, -- The y coordinate is set already.
name="button3", -- The name used to look up the button
label="foo" -- The default button label
sound="click.ogg" -- Sound to play when button is clicked
rolloversound="over.ogg", -- Sound to play when button is rolled over
},
TextEdit -- creates a user editable text edit field
{
password=true, -- "*" instead of letters to hide passwords
length=26 -- max characters user can type into edit field
ignore="#!@" -- ignore ’#’,’!’, and ’@’ if typed by the user
};
}
}
There are several new things in this example: The styles are also Lua tables, with one notable extra
field: "parent" refers to the parent of a style. When MakeDialog is looking for a property, it looks
first in the table passed to the creator function (e.g., Bitmap{}), and then in the current style, and
then in the parent style(s).
The current style only exists in the "scope" of the list it’s defined in.
So we start by setting the DefaultStyle, because that’s just a good habit to have. Next we set a style
for the BodyText, and the Text{} creator function suddenly gets much simpler. Finally we set the
style for the Button, and it also ends up simpler.
There are two notable advantages to styles: One is that you can apply one style to many widgets,
and then when you change the style it affects all of the widgets. Another is that you can then move
these styles to another file entirely and apply them to all of the dialogs in your entire project. See
the Lua command "require", which includes another Lua file in the current file.
If you want buttons that are radio or toggle style, you can specify those as follows:
... Lua
Button
{
type=kToggle,
graphics= {
"offImage.png",
"onImage.png",
"offRolloverImage.png",
"onRolloverImage.png"
}
},
-- Mark the start of a new radio group. Every radio button from this
-- tag to the next BeginGroup() will be in the same group.
BeginGroup(),
Button
{
type=kRadio,
graphics= {
"offImage.png",
"onImage.png",
"offRolloverImage.png",
"onRolloverImage.png"
}
}
Playground 4.0.17.1
54 Lua
Lua is a language that’s designed to be easy to edit and to have flexible data representations.
As such, it makes a great place to put data that you need for your game. It’s easy enough to
understand that your game designers/level editors can easily tweak parameters for various levels.
If you have an in-game level editor, it might make more sense to have it save out XML, since then
it can read and write exactly the same file, as well as retain human readability.
On the other hand, if your game needs scripted actions to occur, scripting those actions in Lua is
very attractive. But how much Lua is appropriate? More the point, how much Lua can you use
and still expect to be supported by PlayFirst? The answer, approximately, is a lot—as long as the
usage falls into a few patterns:
1. Retrieving data. You can have as many Lua files containing game data as you want.
2. Game-play subroutines that execute and quit. This is the classic scripted action. When some
event in the game occurs, then you call a Lua function that determines what happens.
3. Simple animation behaviors. Animations in the Playground SDK™ are handled via Lua
scripts, and the animations can call very simple C++ functions or set Lua variables at specific
points.
The main game thread shouldn’t live in Lua—yet. There isn’t enough support for our engineers
to track what’s going on if there’s a problem that we need to diagnose. When would we be fixing
problems in your game? PlayFirst frequently assigns engineers to fix compatibility problems that
crop up on a system in our lab—if you can’t reproduce the problem on your system, how can you
fix it?
In addition, we’re missing one of the most important game development tools in Lua at the mo-
ment: A profiler. Lua is fast for a scripting language, but still much slower than C++. If a lot of
your game is written in Lua, you’ll likely eventually need to optimize it. The first step in optimiza-
tion should always be to profile, and we have no way to profile your Lua code yet.
One more problematic issue occurs when you end up with a stack that looks like: C->Lua->C-
>Lua and the Lua code tries to yield control back to C. The problem appears when your Lua code
calls a C function that then calls more Lua code that tries to yield. Since pushing a modal dialog
within Lua has an implicit yield, this happens more often than you’d expect. This won’t happen
in Lua code that doesn’t use Lua threads, but the Lua UI thread in the Playground SDK™ depends
on Lua threads to function, and the logical place for your game code to exist would be in the same
engine as the UI thread—and that would require you to yield execution from time to time for the
UI thread to function. We’re investigating Lua Coco to see if it will work with Playground on the
PC and Mac, which, if it works as advertised, will eliminate this issue. Again, stay tuned.
So, while we encourage you to use Lua for the three patterns listed above, we ask that the majority
of the game logic exist in C++ until our Lua tools improve.
Playground 4.0.17.1
56 Lua
Particle System
--------------------------- Lua
-- Initialization phase
---------------------------
-- Action phase
So far our particle system isn’t very interesting. It creates one particle in the middle of the screen
that just sits there. Let’s make it fall:
--------------------------- Lua
-- Initialization phase
---------------------------
-- Action Phase
There are two new things here. First, we’re allocating a velocity. While we can move the parti-
cle without giving it a velocity (by adding a constant value to the pPosition property), it’s more
interesting if each particle can keep track of a velocity value.
Second, we add two animation lines. These add actions to the particles that occur in declaration
order to every particle on every TLuaParticleSystem::Update() (p. 265) call. Let’s break down one
of these lines more carefully:
Translated into English, this says: On each step of the animation, assign the property pVelocity the
value (pVelocity + fTimeScale (p. 139)(Vec2 (p. 139)(0,800)). The part with fTimeScale (p. 139)(
Vec2 (p. 139)(0,800)) says to scale the value Vec2 (p. 139)(0,800) by the current elapsed time, so you
can give it a number in units/second and it will scale the value appropriately.
Similarly, the next line adds a time-scaled pVelocity to pPosition. What is a pPosition? I’m glad
you asked...
Each particle in a system has a number of programmable properties. Each property is a set of
one to four floating point values. The default particle type is a T2dParticle (p. 171), which has a
number of innate properties, listed below along with their Lua names and sizes:
The actual texture isn’t a particle property in the same sense, in that all of the particles in a system
share the same texture. The texture can be a TAnimatedTexture (p. 182) to allow for animated
particles, but it has to be one texture shared by all the particles due to the nature of the rendering.
The basic idea is that the particle script sets down how to initialize these properties for each particle
as it’s created, and then how to animate these properties on each frame.
The order of the first three operations above is strict; the rest are just by convention. In addition to
the innate properties of a 2d particle, you can create custom properties and use them however you
like. A common property to create would be a particle velocity, for instance, to give each particle
its own motion. Another common property is an age: Some animated effects rely on a particle’s
age to calculate, so that a particle can, for example, fade from one color to another.
But not all particle systems need velocity (a set of twinkling stars wouldn’t move, for example),
and simple particles don’t need an age, so you can add just the extra values you need. When you
do need a custom particle property, you can name it however you like—this is Lua, after all.
Playground 4.0.17.1
60 Particle System
The equation pVelocity = pVelocity + f TimeScale(Vec2(0, 800)) is then executed every frame. This
is a standard equation that applies gravity to every particle.
-- ------------------------------------------------------------ Lua
-- Initialization phase
Here we create more particle members; first the familiar pVelocity, and then three others. pAge
keeps track of the age of a particle, pSpin keeps track of an initial orientation, and pSpinSpeed
keeps track of a particle’s rotational velocity. These elements are each unique for each particle in
this particle system.
-- dLocus is a data source. The new FluidFX 2.0 defines dLocus for us, Lua
-- but in case you want to load this particle system in a context
-- where you have no data source defined, this code will give dLocus
-- a default value.
if not dLocus then
dLocus= Vec2(0,0) ;
end
In the sample application we add a data source to the particle system and call it dLocus. We still
want the sample to work in FluidFX, however, since we don’t want to give up the ability to edit
the particle system in real time, so we add these lines of code to conditionally define dLocus to
just be Vec2 (p. 139)(0,0) when it hasn’t been defined already.
SetNumParticles(400);
Here we’re setting the blend mode, though it’s not necessary since kBlendNormal is the default.
See the section on TRenderer::SetBlendMode() (p. 377) for more information on blend modes.
We’re also setting the number of available particles in the pool to a higher number so that we
don’t run out too quickly.
-- ------------------------------------------------------------ Lua
-- Action Phase
Here we set the initialize function for pPosition to select a point 10 pixels to the left or 10 pixels to
the right of the mouse, which is retrieved from the data source dLocus. Then we select a velocity in
the given range: the fRange() (p. 138) function will take its arguments and return values randomly
within the range in each dimension. So for a Vec2 (p. 139)() with the parameters above, it will
return -200...200 in the X direction and -300...120 in the Y direction.
The function fRange() (p. 138) will work with scalars, Vec3() (p. 139) and Color() (p. 143) values
similarly.
These are simple enough: Set the initial pColor to a constant white color value, the initial pScale
to a constant 0.5, and the initial pAge to 0 seconds.
Here we’re again using fRange() (p. 138), this time with scalars, to initialize the particle parameters
with values within a range.
-- ------------------------------------------------------------ Lua
-- Particle Parameter Animation Functions
First we see the familiar velocity and position equations. Then we see something new: Animating
the scale value. This equation will add one to scale per second: fTimeScale() (p. 139) again scales
Playground 4.0.17.1
62 Particle System
its parameter to the fraction of time that’s passed, so after a second pScale will go from 0.5 to 1.5.
Three new functions here. First is fAge() (p. 135), which takes no parameters. Instead it just returns
the amount of time in the current update step in milliseconds, so with the equation above the pAge
parameter will always equal the particle’s age in milliseconds.
The second new function is fFade() (p. 137), which performs a linear interpolation between multi-
ple values. The first parameter to fFade() (p. 137) is the current age in milliseconds, the next is the
initial value, and following that are pairs of deltas and values to interpolate between. In this case,
it starts with Color(1,1,1,1) (p. 143), and then over the next 500ms interpolates to Color(1,0,0,1)
(p. 143), then over the next 1000ms interpolates to Color(1,1,1,0) (p. 143). There isn’t a limit to how
main pairs you can add to this sequence, as long as you end with a value and not a delta.
The next line calculates a new pSpin value by using fTimeScale() (p. 139) to increment pSpin by
the value of pSpinSpeed once per second. The last new function is f2dRotation() (p. 135), which
produces a 2d vector based on a value in radians, which is what we’ve been calculating in pSpin.
Here’s a different concept: A function that doesn’t return a value. Each of the functions so far has
been implicitly assigned to a particle parameter. This one just executes its function and ignores
any return value.
Which is fine, because it is a function with a side effect. From the inside of the parenthesis:
fGreater() (p. 137) returns true (a non-zero value) if its first parameter is greater than its second.
Then the function fExpire() (p. 136) tests its parameter, and if true, flags the particle for destruction.
In other words: If the particle’s age parameter exceeds 2500ms, kill it.
What’s all this then? OK, more fun stuff. First, we’re setting a global Lua variable. There’s nothing
magical about this—nothing you can’t read about in a Lua manual, anyway. We’re just setting
the variable gActive to a value of 1. Thing is, from C++ you can use TScript::SetGlobalNumber
(p. 395)("gActive",0) to turn of new particle generation without stopping the animation.
It’s important not to add any more animation or initialization rules in the Update() function. Every
time you call Anim() or Init() it adds another animation or initialization function to the particle
processing chain, so if you add additional functions in Update() the processing chain will get
longer and longer, and your particle processing will get slower and slower.
Playground ships with a particle editor to help test and refine your particle systems. For informa-
tion about the particle editor see FluidFX 2.0: Interactive Particle System Editor (p. 90).
This code will take the value in pSpinSpeen and multiply it by the constant 0.5 before running it
through the fTimeScale function. In this case, you could just as easily have written:
-- ERROR: Lua can’t handle multiplying a number by a USERDATA in this case Lua
pSpin:Anim( pSpin + fTimeScale( 0.5*pSpinSpeed ) );
Obviously, in this case you could simply change the constant 250 to 2500, but if you’ve assembled
a vector from several values and want to scale the entire result, you can do that.
The order of operands is important here: It always needs to be Vector∗Scalar, even if the scalar is
already a Lua userdata that represents a value.
Playground 4.0.17.1
64 Particle System
<Row> XML
<Cell><Data>title</Data></Cell>
<Cell><Data>My Game Title</Data></Cell>
</Row>
The file is expected in the root of the assets folder, and should be called strings.xml.
See TStringTable (p. 427) for more information. The global string table is available from TPlat-
form::GetStringTable() (p. 341).
66 Localization and Web Versions
• It is important that your web version not have a completely functional game executable. It
is not enough to remove data from your game and use the same executable as the download
version. This would allow users to simply copy over their web version executable and un-
lock a full version of the download game. Please make sure to limit the functionality of your
web game with code changes as well as data changes.
• Playground will automatically resize your game to fit in whatever window the website puts
your game in. An average window size is 480x360, though some sites will use smaller win-
dows and others will use larger windows. You do not have to do any extra work to get
your game to show up properly in that size window. However, because your game will be
running in a smaller window, you may want to shrink your assets and then scale them up
dynamically in-game (i.e. using the scale parameter in DrawSprite). For example, if you
shrink your assets by 25% and then scale them up in code by 25%, your game will run in a
600x450 window with no visual loss. If you do the same thing by 40%, your game will run
in a 480x360 window with no visual loss. Shrinking your assets in this manner can help you
reduce the size of your web game download.
• To implement the "Download" button functionality, you need to do two things:
– The download URL will be available in TPlatform::GetConfig( TPlat-
form::kDownloadURL ).
– To launch the download page, use TPlatform::OpenBrowser() (p. 341).
• If your game uses the hiscore system, it is important that your game be allowed to run in
"anonymous" hiscore mode. The command line to main() will contain a -anon # parameter,
which you need to parse. If # is 0, you can run the full hiscore system. If it is 1, you need to
run anonymous mode. If it is 2, you need to run in local high score mode.
• If your game displays the PlayFirst logo anywhere aside from the splash screen, you need
to look for the "-hidelogo 1" parameter being passed into the command line. If this value is
present, you need to hide these logos on every screen except the main menu screen, where
this logo is allowed to remain.
• Avoid saving data between sessions. The TPrefs (p. 352) and TPfHiscores (p. 325) construc-
tors have optional arguments that will disable session data saving.
• You will likely need to revisit some of your UI and increase the size of text to make sure it is
readable in the small 480x360 windows.
• If your game uses the PlayFirst Hiscore System (p. 30), you will want to add separate hiscore
modes for your web game, but make sure the web game can still view the downloadable
game modes hiscores when connected to the global hiscore system.
• In order for your game to be accepted for use on MSN, you need to:
– Implement all the functionality appropriate to your game described in gamestate.h. See
some examples in the sample application.
– Submit two builds of your game, one with cheats on, one with cheats off, so it is easy to
test the web functionality.
– Detect if the game is an MSN build by checking for the string "msn" in TGameS-
tate::GetState(TGameState::kSystemMode).
– When in MSN mode:
1. Instead of calling TPlatform::OpenBrowser() (p. 341) to launch a download, you
need to call TGameState::SetState( TGameState::kDownloadButton ).
2. Remove all "Try Again" buttons from your game - at the end of your game the only
option should be to quit.
3. Because MSN has their own high score system, you should not go to the high score
screen in game. Instead, you should either go to an upsell screen if the user presses
the high score button, or you should remove the high score buttons from your
game.
4. Your game score needs to be sent to TGameState::SetState( TGameState::kScore,
score ) at least prior to the end of the game, but more often is better.
5. Whenever a game ends (either by being over or by the user quitting the
game in progress), call TGameState::SetState(TGameState::kGameOver). At this
point, MSN zone may switch to an upsell screen and then redirect your game
to either go to the main menu, or possibly restart the current game mode
(you need to poll the TGameState::QueryRestartMode() (p. 243) and TGameS-
tate::QueryJumpToMenu() (p. 244) functions to determine whether or not to do
this).
• In order for your game to be accepted for use on the AOL.com® site, you will need to do the
following:
– Detect for the string "aol" in TGameState::GetState(TGameState::kSystemMode), which
means you are running an AOL service build.
– If you are in AOL service mode, you need to:
1. Display the AOL logo on the splash screen. An AOL logo has been included with
your Playground delivery, and is located in the addons/webgames/AOL folder
(two logos have been provided, one that is baked onto the PlayFirst splash screen,
and one that is seperate - you can use whichever file is easier for you). If you are
using the DisplaySplash() (p. 144) Lua function to display your splash screen, you
can put logic in the Lua script to determine which splash screen to display. For in-
structions on how to use an overlay with DisplaySplash, refer to the DisplaySplash
documentation.
2. Only have download buttons on 2 screens: the main menu, and the upsell screen.
Playground 4.0.17.1
68 Localization and Web Versions
Game Footprint
become 1/4 of their previous size, with no change of source code; the disadvantage that they’re
reduced to an 8-bit palette, so if the image consists of many different color gradients, it may hurt
image quality.
It’s easy enough to experiment and figure out which of these two techniques works with each of
your image types.
Utilities
If this is the first time you have run FirstStage, then you will be presented with a folder selector
asking you to select your game folder. Go ahead and point it to your game folder. For the skeleton
project, this is usually
[PlaygroundSDK folder]\skeleton.
Once this is done, it will give confirmation of the assets folder in the output window. Check that
it is correct before you proceed.
PLEASE NOTE: For this example, we are going to be using assets from the skeleton folder which
is included with the Playground SDK distribution. You are free to substitute your own assets in
this example if you already have them prepared.
If you want to follow this example and use the skeleton’s assets, make sure your game folder is
pointing to the skeleton application game folder by selecting Extra/Select game folder... in the
menu.
Click on the Bitmap button in the tool bar. An image selector dialog will appear with the game
folders on the left and thumbnail pictures of your assets on the right.
Go into the backgrounds folder and select dialog.png. Your cursor will change and there will be a
rectangle that follows your mouse cursor. This rectangle represents the size of the image.
Move the box until it is properly on screen and click the left mouse button to place the bitmap. A
dialog box will then pop up asking you to enter a unique name for this new bitmap. Let’s just call
it TestWindow.
Press ok and you see your bitmap appear on screen. This bitmap will be our background for the
dialog box.
If you move your mouse over the bitmap, you will see that it has a yellow focus rectangle around
it. Select the bitmap by clicking on it. It should now have a red box surrounding it indicating
that it has been selected. You should also notice that the bitmap code in the Lua window has been
highlighted. This is to show you what code is involved in making this window.
Next, let’s add some text to the window.
Click on the Text tool in the tool bar. The cursor should change to a text image.
Move the cursor to somewhere inside your bitmap and click and drag out a box. This will be the
dimensions of our new text box.
When you release the mouse, a dialog box will appear.
Set the ID Name to gTextBox.
Set the label to HelloMsg. The Label is actually a unique identifier for the translations file which
we will explain in more detail below.
Click on the middle button in the Text Alignment and then press OK.
One great feature about the Playground SDK is that it can do automatic translating of strings
for you. This means that when you create a text control in FirstStage, you also have to add a
translation entry for the new string. Luckily, FirstStage makes this process easy by displaying a
translations editor each time you create a control that has text. You will notice that a new entry
has been created and selected in the translations table which corresponds with your new text. Go
ahead and change the text in the translations column to "Hello There" (without the quotes) and
press enter. Then press the OK button to save your new entry.
Your new text box should appear. If you move your mouse over the text area, a highlight rectangle
should appear around the area that you specified for the text.
You should have something similar to this on screen:
Playground 4.0.17.1
74 Utilities
You have just created your first dialog box. Click on the Save button and save your new dialog as
my_dialog.lua.
This will create a new blank script. The current list of scripts can be seen in the Scripts window.
Playground 4.0.17.1
76 Utilities
This will load a script from disk and add it to the Scripts window.
If you type in any changes in the script window, you will need to press the Run Script button to
refresh the changes in the visual display.
FirstStage can be in either of two states when building a dialog. Firstly, there is Select mode which
allows you to create new windows and move windows. The other state is Scale Mode which
allows you to scale the size of any selected windows.
If you need to change the size of a window control, like an image, click the Scale Mode button,
then select the window(s) that you want to resize, then click and drag the left mouse button to
resize the window.
If you want to add a push button, a check box, or something similar use the Add Button tool. For
more information on the use of Add Button, see Add Button Control (p. 79).
Most dialog boxes start with a bitmap as the background and then you layer buttons and text
boxes on top of the bitmap. So, adding an image can be seen as the first step in building a new
dialog. For more information on the use of Add Image, see Add Bitmap Control (p. 80).
Playground 4.0.17.1
78 Utilities
You use a static text box when you want to display information to the user. Text is automatically
translated through Playground SDK, so all you need to do is enter the text ID and then fill in the
translation XML file with the correct translation. For more information on the use of Add Static
Text, see Add Static Text Control (p. 81)
If you want the user to be able to type some input on the screen, use a Text Edit control. You
can adjust a lot of parameters for the use of the Text Edit when placing the control. For more
information on the use of Add Text Edit, see Add Text Edit Control (p. 82).
Custom windows are the basic building blocks of any Playground derived game. In C++, all of
your game code resides inside a custom window (a TWindow (p. 496)) so that it can be visual-
ized on screen. Using the custom window tool, you can define the size and position of a custom
window which can later be referenced inside your game. For more information, see Add Custom
Window Control (p. 84).
Grid snapping is very useful when you have a lot of controls on your screen and you want to
align them so that it looks neat and professional. Pressing the Grid Snapping button will toggle
the use of grid snapping on/off. If you want to adjust any aspect of the grid snapping properties,
for instance the grid size, just right click the Grid Snapping button and the Grid Properties dialog
will be displayed. For more information on the grid properties, see Grid Properties (p. 85).
To change the background of the screen, click the Bkg tool button. You will be asked for a valid
bitmap. Bitmaps can be any JPG or PNG file. To remove the bitmap from the screen, go to Extra/-
Clear Background.
Clicking this button will display the help that you are reading now.
If you want to add a button to your screen, press the Button tool. You will be presented with the
button properties screen.
Playground 4.0.17.1
80 Utilities
The ID name is a unique name to give to this new control so that Lua can differentiate between
the different windows. Typical IDs are names like gOkButton, gFullScreenCheckBox, etc.
The Label is the text identifier for this label. Common identifiers can be "OK", "Cancel", "Hel-
loMsg", etc. If the identifier does not exist in the translations file, you will be presented with the
translations editor once you hit ok. At that point, you can type in the English equivalent for your
identifier. See The Translations Editor (p. 88) for more information.
The Close Modal checkbox will tell your game that you want to close the parent dialog when the
window is closed.
The Default checkbox will tell the game that this is the default button.
The Cancel checkbox will tell the game to abort the window.
The Style drop down list holds a list of all the global styles for this Lua file. Pick a style that
suites the type of button that you want to create. Commonly used styles are "ButtonStyle" and
"LongButtonStyle". You can make your own custom button styles which will also show up in this
list.
Press the OK button once you have filled in the details.
As mentioned, you wil be taken to the translations editor if your label doesn’t already exist.
The cursor will then change to indicate that you are in the Add Button mode. Move your mouse
to where you would like to place your button. Use the box outline that is following your mouse as
a guide to where you would like to place your button.
Bitmaps are very important to the look and feel of your dialog. Typically, you would use a bitmap
for the background of your dialog.
To place a bitmap onto the canvas, first select the Bitmap tool button.
You will be presented with an image selector window. Use the folder tree on the left to navigate
to your image. If your folder is not in the tree list, then you possibly may not have configured
FirstStage to be pointing to your game folder. Use the menu option Extra/Select Game to Modify...
to change to the proper game folder and try again. Select the image you want to use and press OK.
Once you have selected your bitmap, move your mouse around the screen. You will notice that the
mouse cursor has changed to a bitmap icon and there is a rectangle following your cursor. This
rectangle represents the dimensions of your new bitmap. You now have an idea how big your
bitmap will be on screen.
At this point, you have two options:
1. If you are happy with the size and position of the bitmap on screen, then press the left mouse
You only have one parameter that you need to fill in which is the Name for this image. Type in a
unique name for the image and press OK to see your image on screen.
Text boxes are great for displaying information to the user. The text displayed in a text box is
automatically translated via Playground into the correct language.
To create a text area on screen, click on the Text tool button. The cursor will change to indicate you
are in this mode.
Next, with your left mouse button, click and drag out a box where you want your text to be
displayed.
You will then be presented with the Text Properties dialog:
Playground 4.0.17.1
82 Utilities
The ID name is a unique name to give to this new control so that Lua can differentiate between
the different windows. Typical IDs are names like gTextBox, gInfoBox1, etc.
The Label is an identifier into the translations file for the text you want displayed. See The Trans-
lations Editor (p. 88) for more information on the translation file editor.
The Text Alignment is where you want the text displayed in relation to the boundaries of your box
dimensions. Use the grid of buttons to pick how you want your text aligned. The top left button
will mean that your text is aligned to the top left of your text box. The middle button would mean
your text is aligned to the middle of your text box, etc.
Press the OK button to see your new text box on screen.
A TextEdit control is typically used to allow the user to type a response for use in game. A typical
example is a user’s name or password.
To create a text edit area on screen, click on the TextEdit tool button. The cursor will change to
indicate you are in this mode.
Next, with your left mouse button, click and drag out a box where you want your input box to be
displayed.
You will then be presented with the TextEdit Properties dialog:
The ID name is a unique name to give to this new control so that Lua can differentiate between
the different windows. Typical IDs are names like gPasswordInput, gUserNameInput, etc.
The Label is the default text that should be displayed in the edit field.
The Length is the maximum number of characters that can be entered.
The Ignore chars is a list of letters that you do NOT want the user to be able to use.
The Password entry checkbox can be set if you want the user’s typed text to be masked for privacy.
The Text Alignment is where you want the text displayed in relation to the boundaries of your box
Playground 4.0.17.1
84 Utilities
dimensions. Use the grid of buttons to pick how you want your text aligned. The top left button
will mean that your text is aligned to the top left of your text box. The middle button would mean
your text is aligned to the middle of your text box, etc.
Press the OK button to see your new TextEdit box on screen.
Custom windows are used as a canvas for your TWindow (p. 496) derived classes in your game.
You need to create a custom window to be able to see your game on screen.
Click on the custom window button and left click and drag out a box on screen in the position and
size that you want for your custom window.
You will then be presented with the Custom Window Properties dialog:
The Class name is the name of your c++ TWindow (p. 496) derived class that you have defined in
game.
The Window Name is the unique ID that you want to give to this window.
Press the OK button to add your custom window.
The grid snapping properties can be accessed by right clicking the Grid tool button in the tool bar
or by selecting Extra/Change Grid Properties... in the menu.
The following dialog box will be displayed:
The Enable Horizontal Snapping checkbox allows you to enable/disable snapping in the hori-
zontal direction. The text field following this option is the distance in pixels between each column.
The Enable Vertical Snapping checkbox allows you to enable/disable snapping in the vertical
direction. The text field following this option is the distance in pixels between each row.
The Window Snapping Alignment is the edge that you which your windows to be snapped to.
By default, windows will snap to grid lines using the top left edge of the window.
The Display Snapping Grid on Screen checkbox allows you to toggle the visibility of the grid on
screen. This does not disable snapping.
Playground 4.0.17.1
86 Utilities
If you hover over a window, for instance a bitmap or a button on the canvas, and you click your
right mouse button, a small popup menu will be displayed similar to this one:
When working with a lot of window’s controls, like buttons, it is important to have the ability to
align a certain edge of these controls so that they look neat. This is very simple to do with the
alignment dialog. To access the alignment dialog, first select the windows that you want to align,
then either right click on one of the windows and select "Align..." or select Edit/Align selected
objects... in the menu.
Playground 4.0.17.1
88 Utilities
The Distribute dialog is very similar to the alignment dialog but with a slight difference. If you
distribute the windows, you are affectively spacing the windows out evenly along a certain axis.
Typically, you might have three buttons that you want spaced evenly along the bottom of the
screen. You would select all three windows and then use the distribute tool to space them out
correctly.
Left, Center, Right, Top and Bottom refer to the edge of the controls which you want to distribute.
For instance, if you selected to distribute "Top", then all the controls would be evenly spaced based
on the tops of the controls.
If you select, "Spacing" as an option, then FirstStage will make sure that the space between each
control is exactly the same.
The translation editor is a dialog that allows you to enter new values or modify old values of
strings which are found inside the strings.xml file located in your assets folder.
String entries are always defined as a key/value pair. So, you will always start with a key string
that is a unique identifier for the value string which is the normal text. For example, "HelloMsg"
would be the key and "Hello there everybody!" would be the value. The key string is what you
enter into your label section when creating a button or text control. The text will then automatically
be replaced with the value for that key when it is displayed on screen.
The translations editor can be activated in two ways. Firstly, if you were to create a new button
or text control and you entered a label that currently doesn’t exist in the strings.xml file, then the
translations editor will automatically be opened and your new value added. Alternatively, you
can access the editor at any time by selecting View/Show Strings Editor... from the main menu.
The editor is broken up into three sections. At the top, you have a filter search box. If you start
typing in the mask field, you should notice that your list of displayed strings will be reduced to
only those strings that match your typed text. This is a very quick way of finding a string in a
huge list of items. The "Filter on ID" option (default) means that it will try and match your mask
string with a string in the identifier field and similarly, the "Filter on Translation" will search on the
translation field. If you select "Substring" matching (default) then your mask must exist inside the
field. Example, if your mask was "ing", it would match strings with "fishing", "cooking", etc. The
wildcard search is a bit different. Using wildcard searches allows you to be more precise with your
selections. You could enter a mask like "c∗ing" and it would match "cooking" but not "fishing".
The next section is the key/value cells where you can edit your data. The left column is the index
number for the key/value in the xml file. The next column is the key and the last column is the
translation for that key. All of the columns can be resized by dragging the splitter area between
each column. You can double click on a column header to change the sorting order. Double click
once for ascending and double click it again for descending order. Double click on a cell to edit
the contents of that cell.
The last section has some buttons which help manage your strings. Currently, you can Add and
Delete key/value items. Click Add to add a new key/value to the end of the list. If you want to
delete an item, first click on either the key or the translation part of the item and then press the
delete button.
Once you have finished with your strings, press the OK button to save your changes or press
Cancel to abort your changes.
The Image Selector Dialog is a visual way of being able to navigate your game folders for assets.
The dialog is automatically triggered when you create a new Bitmap control.
The column on the left side of the dialog is a list of all of the folders in your game. Whenever you
click on one of these folders, the images in that folder are displayed in the column on the right of
the dialog.
Once you have found the image that you want to use, you can either double click on the icon to
choose it or you can click once on the icon and then press the OK button.
Playground 4.0.17.1
90 Utilities
FluidFX to tweak the code without ever seeing the code–so a programmer can create a template
particle system with the appropriate parameters and then let and artist run with it.
The first value is the variable name that’s used in the script. Technically you don’t need to change
this, but it’s certainly good practice. The Label field is the label that’s displayed by the slider in
the properties window. The default value is the value that the slider will be set to initially–more
on that in a bit. Then the range that the slider will set the value to at each extreme. Press OK.
If you look, there’s no slider yet on the properties tab, since the new script code that’s been created
hasn’t been executed yet. Scroll to the top of the script pane for a moment to look at it.
Playground 4.0.17.1
92 Utilities
That code is what, in FluidFX, will create a slider control. The variable, gGravity, will be modified
as you move the slider. In fact, The first value, 400, is actually the value assigned to gGravity, and
will be changed in the Lua file as you move the slider. Try it now to see what I mean: Hit the "Go"
button, switch to the Properties tab, move the slider, and then switch back to the Script tab. The
new value should be visible there in the script.
You can also create a multiple-selection control, and a texture-selection control. Examples of both
of these are present in fire.lua, though the principle is the same for both.
For more information on writing new particle systems, see A Lua-Driven Particle System (p. 57).
sidewalk v4.0.17.1011
Usage 1/Create XML animation:
sidewalk [options] animdesc.xml [ folder/fileroot* ]
Options:
--mask : Separate output into two layers, image and mask
--opaque : No transparency in PNG file.
--reg=x,y : Force registration point to x,y.
--scale=# : Scale an animation by #, where 1.0 means no change.
--filter=type : Set the scaling filter type. Options are:
Box
Triangle
Hermite
Hanning
Hamming
Blackman
Gaussian
Quadratic
Cubic
Mitchell [default]
Lanczos
Bessel
-8 : Output 8 bit png
-f # : ’fuzzy’ bounding box value, between 0 and 1.
-o : Output individual frames as well as combined frames into
’frames’ folder.
-p : Reorder frames for optimal packing. This does not .
reorder the way frames are indexed, only reorders them in
the output file.
-i : Ignore size restrictions. This disables the requirement that
all images fit into a 1024x1024 texture. Note that if you use
this flag, the resulting image cannot be used directly to draw
in a game, but it may be used to hold data, etc.
-v : Verbose output
--noclear : Don’t clear transparent pixels to adjacent color.
For a new animdesc.xml file, you need to specify the source file
wildcard or name.
Options:
--nochanges : Just walk through the tree and report what would be
done.
--summary : Provide simple summary.
--fullcsv : Provide detailed CSV report, including files that can’t
be optimized.
--csv : Provide detailed CSV report of files that can be
optimized
--jpegquality=## : Set maximum JPEG quality: Any JPEG currently of higher
than this will be recompressed to the given quality.
Default is 85.
--jp2rate=## : Set JPEG2000 rate, 0.0-100.0, where 100 is lossless.
Default is 4.0. The meaning is different than for JPEG quality.
At 50, the file will be 50% of original size, and at 4, it will be 4%.
--samplefactor=## : PNG8 resampling factor. Smaller for higher quality.
Valid values are [1-10].
--splitmask : Split PNG RGBA files into JPG/PNG files. As of
Playground 4.0.16, now automatically supported.
[default on]
--nosplitmask : Disable splitmask feature.
--norecurse : Don’t recurse into subfolders.
--splitonly : Only split images to .jpg/.mask.png.
--png8only : Only compress images to png8.
--jp2only : Only compress images to JPEG2000 .jp2 format.
--mirror : Copy all files that do not need processing to output folder.
--output=folder : Set output folder (for new images) to folder. Defaults
to "crunched".
-v : Verbose output
--quality-threshold=## : Optimize JP2 output to ## quality. 1.0=good, 5.0=extreme compression. Note! CPU intensive.
Playground 4.0.17.1
94 Utilities
To create a new animation, you need to start with a sequence of frames; PNG files are best, because
they can have an embedded transparency layer. Note that if they are PNG files stored with an
embedded transparency layer, that layer needs to be non-empty or the resulting PNG file will be
completely empty. They should also all be the same size; if your animation moves, the initial
frame should be large enough to encompass the entire animation, unless you want the motion to
be handled at runtime.
Once you have this sequence, save it in a folder by itself. The frames should alphabetize to be the
correct sequence; if they’re numbered, the numbers should have leading zeros (0001,0002, etc.) to
ensure they come out in the right order if there are more than 10 frames.
Let’s say we want to create an animation out of a series of PNG files: frame00.png, frame01.png,
etc. To convert these files to a new animation control file "myanim.xml", you would call:
09/12/2006 03:42 PM 2,
270 myanim.png
09/12/2006 03:42 PM 497 myanim.xml
2 File(s) 2,
767 bytes
You can see above that it created myanim.xml and myanim.png. You need to copy these to the
same folder in your assets/ tree. All you need to do to load the file is reference myanim.xml,
however–it knows what its external files are called.
Here we assume that both of the above files are copied to "assets/anim":
As of v4.0.14, sidewalk now modifies transparent pixels to match adjacent non-transparent colors.
As transparent pixels shouldn’t actually render, this may seem like a strange feature, but it turns
out that these transparent pixels can "bleed" into their adjacent non-transparent pixels.
Remember that the renderer, when given a non-exact pixel location, will average adjacent pixels
to determine what color values to draw at a particular location. Say you have a pixel that’s com-
pletely transparent, with alpha value 0. It still has RGB values of course, but you don’t intend
them to render. Say the RGB values are 0,0,0, complete black. Also, let’s assume that your object
is white, RGBA 1,1,1,1.
Now when it attempts to render your object offset by 0.5 pixels, the first pixel it draws will be
an average of the transparent pixel, 0,0,0,0, and the opaque one, 1,1,1,1. So you end up with
0.5,0.5,0.5,0.5. This sounds fine–unless the background you’re rendering to is a very light color.
Then your white object rendered to a white background will have a 50% transparent, 50% grey
border.
Sidewalk corrects for this by taking that 0,0,0,0 and looking for an adjacent non-transparent pixel.
It then takes the color from that pixel– in our case it would become 1,1,1,0. Now when it averages
with its adjacent pixel, it will be come 1,1,1,0.5, which is really what you wanted.
If you don’t want this behavior, the option –noclear will disable this clearing of transparent pixels.
Filmstrip is Playground’s animation frame sequencer. You can create new animations or load
existing xml or anm animation files.
Playground 4.0.17.1
96 Utilities
A variety of animations can be defined using the Lua scripting language to specify the name of the
animation and the order of frames to play for that animation.
Also, for each frame, you can adjust a multitude of properties including rotation, scale, alpha and
more.
Filmstrip has a group of dockable windows that allow you to control all aspects of the editor.
Below is an explanation of each window:
The script window holds the Lua script which defines the animations that make up the animation
file. A typical script might look like this.
function DoAnim()
delay(20);
while true do
frames{
1,1,1,1,2,2,2,3,4,5,7,4,3,2
};
end
end
For more information on how to control animation through Lua, see the "Animation Script Func-
tions" section.
When you define new animations in the script window, the animation names will automatically
be displayed in the Animations Window. To play an animation, either click on the name of the
animation and press the play button in the window’s toolbar, or just double click the animation
name. To stop the animation from playing, press the stop button in the window’s toolbar. You can
advance one frame at a time by pressing the frame advance button and likewise play frames in
reverse by pressing the reverse button in the toolbar.
This window holds a list of frame numbers that make up the loaded sprite sheet. All animations
are composed from these frames. To see a particular frame, click on the frame number in the list.
You can also display multiple frames at once by clicking on the first frame in the sequence and
then holding down shift and clicking the last frame in the sequence. On screen, you will see all the
frames in the sequence being drawn at once but they will all be ghosted apart from the last frame.
The ghost effect is called "onion skinning". More on onion skinning later.
The Animation Frames toolbar has some buttons which can help in modifying your animation
frames.
• Insert Blank Before - Insert a blank frame before the currently selected frame.
Playground 4.0.17.1
98 Utilities
• Insert Blank After - Insert a blank frame after the currently selected frame.
• Insert Before "x" - Create a blank key frame before the specified frame.
• Append Blank Frame - Add a blank frame to the end of the list of frames.
• Duplicate Frame - Make a copy and insert right after the current frame. You will end up with
two exact frames together.
• Insert Duplicate Before "x" - Make a copy of the current frame and insert the new frame
before frame "x".
• Append Duplicate - Make a copy of the current frame and add it to the end of the list of
frames.
When dealing with animations, anchors are a great way of retrieving reference points for each
frame. See Anchors (p. 103) for more information on anchors. The Anchors Window allows you
to manage your anchors. All of the anchors for the loaded animation are displayed as a tree list in
the Anchors Window. If you click on the name of the anchor, it will select it. You can then use the
Delete button in the toolbar to delete the anchor or press the Rename button to rename the anchor.
There are a couple of ways to create new anchors. One way is to press the New Anchor button in
the tool bar. It will pop up a dialog asking for a name for this new anchor.
The History Window displays all actions that have been performed inside the editor. You can
either use Ctrl-Z and Ctrl-Y to undo and redo or you can click on any item in the history to revert
back to when that action was created. This allows you to do a block of undos in one go.
This window gives you access to all of the editable properties for each frame on your sprite sheet.
Click on any frame number in the Animation Frames window and you will see the properties for
that frame updated in the Frame Inspector. It might look something like this:
• The Name field can be used as an identifier for this frame. For instance, instead of frame 10
just being called 10, you could type in "WalkStart" and then in your Lua script, you could
refer to this frame as WalkStart.
• The Image Details section is only for display purposes and shows the pixel offset information
for this frame in the sprite sheet.
• The x Reg and y Reg fields are the registration values (or offsets) for this frame.
• The Alpha field represents the alpha level for this frame. You can adjust the alpha by using
the slider or by typing in a value in the edit box.
• The next section is the matrix for this frame. It is made up of a rotation and translation
section. Normally, you would adjust the matrix for a frame by using the Move, Rotate, and
Scale tools rather than hand typing in values into the Inspector but if you want to enter exact
numbers, you can use these matrix entries to do so.
Playground 4.0.17.1
100 Utilities
New - Create a new sprite sheet from a series of images. See Creating a New Animation (opposite)
for more information.
Open - Open an XML animation or an ANM animation. ANM files are the binary version of the
XML file which helps if you have a lot of data to load. If you want to create an ANM file, first load
your XML animation and then choose File/Export to ANM from the main menu.
Save - Save the current animation file back to disk. If you want to save your animation to a
different file, choose File/Save as from the main menu.
Undo/Redo - These buttons are the standard button to allow you to undo any mistakes you make.
Select/Move/Rotate/Scale - These buttons are "state" buttons and are used to manipulate the cur-
rent frame of animation. If you click on either Move, Rotate, or Scale buttons, you will notice that
the cursor will change to match the mode that you selected. The move button allows you to move
the position of the current frame. Select the move button and then click and drag the left mouse
button around the screen. You will notice the frame moves position. The rotate button will rotate
the frame. Similar to move, press the rotate button and then click and drag the left mouse button
left and right to rotate the image. The scale button will scale the image in both width and height.
Click on the scale button and then click and drag the left mouse button to see the image scale. If
you hold down the control key, the image will scale uniformly in width and height. Use the Select
button when you don’t want to make any more modifications to the frame.
Move/Rotate/Scale data entry - If you want to type in exact values for a particular mode, right
click on the button and a data entry dialog will appear. Say, for instance, that you want to move
the image ten pixels to the left. Right click on the Move tool button and a dialog will appear. Click
on the Relative radio button because you want to move the position based on the current position.
Type -10 in the x field and press OK. You will notice that the frame has jumped ten pixels to the
left.
Onion - This toggles onion skinning mode. Onion skinning was a term adopted by traditional cell
animators a long time ago and it means when you can see the last couple of frames of animation
while you are editing the current frame. It is most helpful when you are trying to adjust details of
the current frame and you need a reference of the last frame to compare it to. If you right click on
the Onion toolbar button, you will get a dialog with settings you can adjust.
• Previous frames to show is how many frames you want to see before the current frame.
• Subsequent frames to show is how many frames to draw past the current frame.
• Ramp alpha values means that the previous and subsequent frames will have gradually less
alpha the further they are away (in frames) from the current frame number.
• Wrap onion display means that the display of the frames will wrap around the end frames of
your animation. For example, say you had an animation with 10 frames and you had your
onion skin previous frames set to 5. If you were on frame 2, you would see frames 2,1,10,9,8,
and 7. If you had Wrap turned off, you would only see frames 2 and 1.
Grid - Toggle frame grid view. The frame grid view will display all of the current frames in a 2D
grid. If there are more frames than can fit on screen, move your mouse to the right of the game
window and a vertical scroll bar will appear. Depending on the grid options set, you can also move
the mouse to the bottom of the game window and a frame scale slider will appear which allows
you to change the display scale for the frames. The current frame has a highlighted background
and you can change the current frame by clicking on the cell of the frame you want.
The frame grid settings can be accessed by right clicking the grid tool bar button. Click Grid
Settings (next page) for more information.
Bkg - This allows you to set a background image for the screen so that you can test your animations
against a background.
Playground 4.0.17.1
102 Utilities
Create a new sprite sheet from a series of images. The result will then be loaded into Filmstrip for
you to add your animations. When you press New, it will bring up the Create New Animation
dialog box which looks like this:
• Path is the path to one of the images that will be in the new animation. If you select the
button to the right, you can browse to the folder with your images. Select any one of the
images in the sequence you want to build and press Open.
• The Options are the same as the options in Sidewalk which is explained here sidewalk:
Command Line Animation Creation (p. 92)
• Clear Old XML button will delete any xml file of the same name before it begins compiling
the new images. This is helpful if you want to make sure that the XML has been built from
scratch rather than just updated.
• The Create button will start the build process. When you press the Create button, a window
will appear on screen which is sidewalk being activated to build your new animation file.
Once the process have been completed, the result will appear in the Output Window at the
bottom of the screen.
Grid Size represents the width and height of each cell of the grid.
Scale Mode specifies how to scale each frame in the cell. The options are:
• Don’t Scale Don’t use any automatic scaling technique. The user can manually change the
scale with the scale slider.
• Scale Down to Fit Reduce the size of the frame only if it doesn’t fit inside the cell.
• Always Scale to Fit Always rescale the frame so that it fills the cell.
Show Frame Numbers will display the frame number in the top left of each cell.
9.4.11 Anchors
Anchor points are used to track animated offsets; for instance, the hand of a character that needs
to have an object attached might get an animated anchor. There are a couple of ways to create an
anchor in Filmstrip. One way is to move your mouse where you want to create an anchor and then
click the right mouse button. A menu will pop up. Select "Add anchor here" to create an anchor at
that point. The other way to create an anchor is to use the "Add new Anchor" button in the toolbar
of your anchors window. You will be prompted for the name of the new anchor. Enter a name and
press OK. A new anchor is created and will be automatically located at the top left of the game
screen. You will then need to move it to where you want on your animation.
To move an anchor, simply move your mouse until it is over the anchor and then click and drag
with your left mouse button to the new location.
If you want to delete an anchor, you can either right click on the anchor and select "Delete this
anchor" or you can select the anchor in the Anchors Window and press the delete button in the
Anchors window toolbar.
When you move an anchor, it only moves the position of the anchor for the current frame you are
on. If you want to move the anchor to a new position for ALL frames, hold down the ALT key
while dragging your anchor.
Playground 4.0.17.1
104 Utilities
• -o [outputfile]: name of file to output (default uses name of .3ds file) If there is more than
one mesh in the file, and -m is not used, the files will be named [outputfile]1.mesh [output-
file]2.mesh ...
• -m: use names of .3ds meshes for output file name if both -m and -o are used, output names
will be of form [outputfile]_[meshname].mesh.
• -center [xyz]: recenter across an axis - specify any combination of xyz. This happens before
the yzflip.
• -invert [xyz]: invert across an axis - specify any combination of xyz. This happens before the
yz flip, so -invert z first inverts the z axis, then flips it with y.
• -uvflip [uv]: This will flip texture coordinates from 0-1 to 1-0 - specify any combination of
uv.
2. Select the text field and change it to be the font you want.
After you’ve completed the above, you need to drag and drop the resulting swf file onto the
swf2mvec.exe program, also within the bin distribution. That program will emit an mvec file
next to the swf file. Name that mvec file and add it to your assets folder, and then you can load it
as a font.
1. Create two files in your game build directory, activex.bat and activextest.bat, based on the
example files included under the bin\axtool\samplefiles folder. Copy these files into your
game folder and add the appropriate information for your game. You can generate the
GUIDs using a tool that ships with the Microsoft® Developer Studio® development sys-
tem called guidgen.exe, which is installed in the Common7\Tools folder in your Developer
Studio installation folder.
Playground 4.0.17.1
106 Utilities
2. Create an empty text file at c:\pfaxdebug.txt. Without this text file at the root of your C drive,
the game will not run.
3. Open up a command prompt window (in Vista, ensure that you’re running the command
prompt as administrator).
4. Run the axtool.bat script that is in your utilities\bin\axtool folder. Run the utility like this:
• The gamefolder should be the path to your gamefolder (the folder that contains the
activex.bat file, etc.)
• test and debug are required parameters for testing the game locally.
• Note that this script assumes you have Visual Studio® 2005 installed in the default
location. If you do not, you can override where it looks for Visual Studio by defining a
VSNETPATH environment variable to the path. For example:
or
After you’ve completed the above steps, you’ll have an html file in your game folder. To test your
game in a window:
1. Open up the html file in Internet Explorer (it will not run in other browsers).
2. Internet Explorer may ask you if you want to install the ActiveX® control; allow it to install.
3. A window will appear that will say something like "Run with -wnd=123456." This means
your game is now ready to run in the window. You can now launch your game in the de-
bugger, and instead of running in its own window, it will show up in the Internet Explorer
window.
Playground 4.0.17.1
108 Utilities
Advanced Features
public:
// Destructor.
virtual ~TTextSprite();
// Factory method
static TTextSpriteRef Create(int32_t layer=0);
private:
TTextGraphic mTextGraphic ;
TRect mTextRect;
}
PFTYPEIMPL(TTextSprite); C++
// Call the protected TSprite constructor
TTextSprite::TTextSprite( int32_t layer ) : TSprite( layer )
{
}
return ref ;
}
// This assumes you have an mTextRect which is the desired rectangle size
// for your text.
TRect rect = mTextRect+TPoint(localSpec.mMatrix[2].x,localSpec.mMatrix[2].y) ;
mTextGraphic->Draw( rect, 1, 0, localSpec.mAlpha );
TSprite::Draw(drawSpec,depth);
}
Note that I didn’t include the math for extracting the rotation from the matrix, so this text will
draw at the location but not the rotation of a sprite. I leave the extraction of the rotation as an
exercise for the reader.
The TMessage (p. 294) type is intended to encapsulate any complex client message. The Play-
ground SDK™ encapsulates TMessage (p. 294) as a Lua user-type, so you can pass a TMessage
(p. 294) object around within Lua. If you want to have Lua pass complex message objects back to
your C++ game, you can easily have a Lua object send a message to your game window where
you can interpret its contents and trigger the correct game actions.
To start, derive your message type from TMessage (p. 294) and add any extra information to your
derived class. For example, say you have a script that triggers an explosion animation that requires
some additional processing in C++ code:
...
Now we have a new custom message type, and we need a way to create it from within Lua. Since
we can use ScriptRegisterDirect() (p. 120) to expose a C++ function to Lua, we can create an
instance in C++ and return it to Lua directly:
The TMessage∗ will be deleted by the Lua garbage collection when it is no longer used, so you
won’t need to delete it yourself.
Here’s how you might use the above code:
Playground 4.0.17.1
112 Advanced Features
"NewExplosion",
NewExplosion);
// ...
virtual bool OnMessage(TMessage * message)
{
TriggerExplosion * te = message->GetCast<TriggerExplosion>() ;
// ...
This will send a message that will be delivered to the "default focus" window (see TModalWin-
dow::SetDefaultFocus (p. 300)), and from there can be handled by your custom game window
class. If you need a message to go to more than one destination, then you should set up a de-
fault focus window that can dispatch the message to the appropriate destination. The TMessage
(p. 294) will be deleted by Lua in a normal garbage collection pass.
Foo = { fn=DoSomething };
TWindowManager::GetInstance()->GetScript()->RunScript("test.lua"); C++
This prints out "Lua: I’ve been called" in the debug log. You should be able to keep around the fn
pointer indefinitely–I just delete it here since I’m creating it in a local pointer.
If your routine returns values, they will be pushed onto the stack in order–and this Call function
only supports one result, so you’ll only get the first one. You can use the TScript::PopString()
(p. 392), TScript::PopNumber() (p. 392), or direct Lua C stack access functions to extract the return
value from the stack.
Then you need a piece of code that acts like the Lua version of PushModal() (p. 149):
return window->GetID();
}
Once you have that function set up, you simply need to register it:
Once you’ve done that, then every TModalWindow (p. 298) created by Lua will instead be one of
your derived TModalWindow (p. 298) classes.
Like most of the advanced tips, this one comes with caveats. Be careful having your window draw
anything–the current TModalWindow (p. 298) is intentionally invisible. And for obvious reasons,
Playground 4.0.17.1
114 Advanced Features
the class TDialog (p. 221) will not suddenly derive from your TModalWindow–and the function
TWindowManager::DisplayDialog() (p. 523) creates a TDialog (p. 221) window, so any dialogs
created using that function won’t use your new TModalWindow (p. 298).
The other reason this is in the advanced section is that it really would be a bad idea to abuse this
trick: One might be tempted to swap in various kinds of TModalWindows depending on what
game mode you were currently in, for example. And that might even work. But considering that
Lua executes effectively as a "light" thread, and it’s hard to know what its current state is at any
one time–and things can synchronize differently depending on the speed of your computer. So
use caution.
Reference
Chapter 11
Windowing Reference
Modules
• Ignore This Group Please
Classes
• class TButton
• class TDialog
• class TImage
• class TLayeredWindow
• class TScreen
• class TText
• class TTextEdit
• class TWindow
• class TWindowSpider
• class TWindowHoverHandler
• class TWindowManager
118 Windowing Reference
Lua Reference
Documentation on predefined Lua constants and functions, as well as C++ interfaces to Lua.
See the section on Lua Scripting (p. 47) for more information.
Files
• file luapluscd.h
Classes
• class TLuaTable
• class TScript
• class TScriptCode
Defines
Functions
• template<typename Func>
void lua_pushdirectclosure (lua_State ∗L, Func func, unsigned int nupvalues)
• template<typename Callee, typename Func>
void lua_pushdirectclosure (lua_State ∗L, Callee ∗callee, Func func, unsigned int nupvalues)
• template<typename Callee>
void lua_pushfunctorclosure (lua_State ∗L, Callee ∗callee, int(Callee::∗func)(lua_State ∗),
unsigned int nupvalues)
• bool
• [unsigned] char
• [unsigned] [short] int (unsigned and short are optional)
• [unsigned] long
• lua_Number
• float
• const char∗
• str (p. 161)
• const LuaNil&
• lua_CFunction
• TLuaTable (p. 269) ∗ (see below for important notes)
• TMessage∗
• const void∗ (return from Lua only)
• const LuaLightUserData& (return from Lua only)
For TLuaTable ∗ as parameter, the pointer will exist for the duration of your function, but will be
deleted in the next application event loop, so don’t keep it around.
For TLuaTable ∗ as a return type, you will need to return a TLuaTable (p. 269) pointer that persists
past the end of the function; you are still responsible for deleting the pointer.
See also:
Using Lua to Script Your Game (p. 47)
Register a "Direct" called function: A function that will be called by Lua directly with appropriate
parameters.
Parameters:
script Script to add functor to.
name Lua name of function.
ptr Pointer to "this" in the class we’re binding to.
directfunctor The member function to call.
Playground 4.0.17.1
122 Lua Reference
Playground 4.0.17.1
124 Lua Reference
Constants
• luaConstant kCheatMode
• luaConstant kComputerId
• luaConstant kInstallKey
• luaConstant kGameName
• luaConstant kGameVersion
• luaConstant kEncryptionKey
• luaConstant kHiscoreLocalOnly
• luaConstant kHiscoreAnonymous
luaConstant kComputerId
This computer’s unique ID.
luaConstant kEncryptionKey
The encryption key.
luaConstant kGameName
The name of the game.
luaConstant kGameVersion
The version number of this build.
luaConstant kHiscoreAnonymous
This is an anonymous hiscore build
luaConstant kHiscoreLocalOnly
This is a local hiscore build
luaConstant kInstallKey
The key that indicates how this game was installed.
Playground 4.0.17.1
126 Lua Reference
Constants
• luaConstant kPush
• luaConstant kToggle
• luaConstant kRadio
• luaConstant kAllLayers
• luaConstant kCenter
• luaConstant kMax
• luaConstant kDefault
luaConstant kCenter
Position-relative-to-center: Add this constant to an x/y position to make it relative to a centered
object. In other words, if you make x=kCenter, the object will be centered horizontally. If you add
one (x=kCenter+1), the object will be one pixel to the right of where it would have been centered.
luaConstant kDefault
Button Text Alignment: Default for type of button.
luaConstant kMax
Width or position maximum. In the case of position, you can subtract an amount from kMax to
make the position relative to the opposite edge. For a width or height, you can use -kMax to
indicate the window should "grow" in the opposite direction of the x or y position: w=-kMax
means that x specifies the right edge of the window, and that it should grow to the left edge of the
parent.
luaConstant kPush
Button Type: Push button.
luaConstant kRadio
Button Type: Radio button.
luaConstant kToggle
Button Type: Toggle button.
Playground 4.0.17.1
128 Lua Reference
Constants
• luaConstant kHAlignLeft
• luaConstant kHAlignCenter
• luaConstant kHAlignRight
• luaConstant kVAlignTop
• luaConstant kVAlignCenter
• luaConstant kVAlignBottom
luaConstant kHAlignLeft
Horizontal alignment: Left.
luaConstant kHAlignRight
Horizonal alignment: Right.
luaConstant kVAlignBottom
Vertical alignment: Bottom.
luaConstant kVAlignCenter
Vertical alignment: Center.
luaConstant kVAlignTop
Vertical alignment: Top.
Constants
• luaConstant kGeneric
• luaConstant kCloseWindow
• luaConstant kDefaultAction
• luaConstant kButtonPress
• luaConstant kPressAnyKey
• luaConstant kQuitNow
• luaConstant kModalClosed
• luaConstant kTextEditChanged
• luaConstant kCommandOnly
• luaConstant kSliderValChanged
• luaConstant kSliderMouseUp
• luaConstant kSliderPageUp
• luaConstant kSliderPageDown
• luaConstant kUserMessageBase
luaConstant kCloseWindow
A request to close a window. Name of message must be window ID to close (TWindow::GetID()
(p. 515))
luaConstant kCommandOnly
This message is empty; it’s being sent to run the accompanying command.
luaConstant kDefaultAction
A request for the default window action.
luaConstant kGeneric
A generic message
luaConstant kModalClosed
A notification that a modal window was closed.
Playground 4.0.17.1
130 Lua Reference
luaConstant kPressAnyKey
An "any key" was pressed.
luaConstant kQuitNow
A request to terminate the application with prejudice.
luaConstant kSliderMouseUp
The mouse has been released on a slider
luaConstant kSliderPageDown
Someone clicked below the slider handle to create a virtual page-down.
luaConstant kSliderPageUp
Someone clicked above the slider handle to create a virtual page-up.
luaConstant kSliderValChanged
A slider value changed
luaConstant kTextEditChanged
New information has been typed into/removed from a text edit field
luaConstant kUserMessageBase
First ID available for client applications.
Functions
function die ()
Kill this animation. The sprite still exists, but with no running script.
Playground 4.0.17.1
132 Lua Reference
function halt ()
Pause the script indefinitely: The script and animation still exists, but won’t be updated again until
an external event changes its state to non-paused.
function showFrame ()
Show the current frame and pause for the delay given in the last call to delay() (p. 131)
Playground 4.0.17.1
134 Lua Reference
Modules
• Blending Constants.
Functions
• function fDistance (a, b)
• function fOpenCycle (lower, upper, steps)
• function fClosedCycle (lower, upper, steps)
• function fAlpha (color, alpha)
• function fDebug (...)
• function fFade (age, state1, time1, state2,{time2, state3,...})
• function fPick (value1{, value2...})
• function fRange (value1, value2)
• function fExpire (value)
• function f2dRadius (radius{, center})
• function f2dRotation (radians)
• function fAge ()
• function fTimeScale (value)
• function fLess (a, b)
• function fLessEqual (a, b)
• function fGreater (a, b)
• function fGreaterEqual (a, b)
• function Done ()
• function RandomFloat ()
• function RandomRange (low, high)
• function Allocate (size)
• function CreateParticles (particles)
• function Value (x)
• function Vec2 (x, y)
• function Vec3 (x, y, z)
• function Color (r, g, b, a)
• function NewParticleGenerator ()
function Done ()
Signal to the Lua particle engine that this particle system considers itself to be done.
function f2dRadius ()
Pick a random point on a circle with a given radius.
function fAge ()
Return elapsed time.
Playground 4.0.17.1
136 Lua Reference
fClosedCycle(0,1,3) Lua
Very slow–there is even overhead in a release build! You’ll want to comment these out before
shipping your game.
• Return an interpolated value. Value will have the same dimensions as input.
• a First operand.
• b Second operand.
• a First operand.
• b Second operand.
• a First operand.
• b Second operand.
• a First operand.
• b Second operand.
Playground 4.0.17.1
138 Lua Reference
fOpenCycle(0,1,3) Lua
function fPick ()
Pick one of several values randomly.
• Return a value within the range of given values, with the same dimensionality.
function NewParticleGenerator ()
Return a new particle-time calculator. Returns a function that can be used as follows:
function RandomFloat ()
Return a random floating point value, 0-1
Playground 4.0.17.1
140 Lua Reference
Functions
• function Color (r, g, b, a)
• function FColor (r, g, b, a)
• function DoWindow (window)
• function MakeDialog (dialogcommands)
• function Window (table)
• function Text (table)
• function TextEdit (table)
• function StripKeyFromLabel (label)
• function Button (window)
• function Bitmap (table)
• function EnableWindow (name, enable)
• function BeginGroup ()
• function GetTag (tab, tag,...)
• function SetDefaultStyle (style)
• function SetStyle (style)
• function AppendStyle (style)
• function SetFocus (name)
• function WaitForCloseMessage (id)
• function DoModal (fileToRead)
• function ModalReturn (value)
• function DisplaySplash (splashMovie, splashGraphic, time)
• function Yield ()
• function ReadFile (fileToRead)
• function CloseWindow (param)
• function CustomCreator (s)
• function GetString (id, p1, p2, p3, p4, p5)
• function CreateNamedMessage (type, name)
• function PostMessage (message)
• function PostMessageToParent (message)
• function GetTimer ()
• function PushModal (name)
• function GetLabel (name)
• function SetLabel (name, label)
• function SetCommand (name, command)
• function GetButtonToggleState (name)
The added elements are only added locally; when another style is selected, the appended elements
are discarded.
If you want to permanently change a named style, it’s actually pretty easy: Styles are actually Lua
tables, which are passed around as references, so modifications are always to the original table.
So, to add a trait to a style MyDefaultStyle, you would just use the Lua member accessor:
...or...
Parameters:
style (table) A table that describes a style.
function BeginGroup ()
Begin a group of radio buttons. Use before the first radio button in a group.
Playground 4.0.17.1
142 Lua Reference
• alpha (boolean) True to force the image to have an alpha channel. (default=false)
• hflip (boolean) True to horizontally flip the image. (default=false)
• image (string) Name of the file to load.
• mask (string) Optional image mask (transparency layer) to apply.
• mipmap (boolean) True to force the image to be created with mipmaps. (default=false)
• rotate (boolean) Rotate the image by 90 degrees.
• scale (number) Scale to apply to the image. 1.0==normal image size. (default=1.0)
• vflip (boolean) True to vertically flip the image. (default=false)
• Other generic window tags.
See also:
Window() (p. 153)
Parameters:
table (table) The table that describes the bitmap.
Returns:
A function that does the actual window creation.
Playground 4.0.17.1
144 Lua Reference
Parameters:
type (number) The integer type of the message.
name (string) The name of the message.
Returns:
A TMessage (p. 294) ∗ wrapped as a Lua object. Pass to PostMessage or PostMessageToParent.
See also:
PostMessage (p. 148)
kCloseWindow (p. 129)
kDefaultAction (p. 129)
kButtonPress (p. 129)
kPressAnyKey (p. 130)
kQuitNow (p. 130)
kModalClosed (p. 129)
SplashOverlayStyle = { Lua
splashoverlay= Bitmap{ x=30, y=50, image="playfirstlogo" };
};
Then before you call DisplaySplash, call:
SetDefaultStyle(SplashOverlayStyle);
Note that you can also use the default style to control the overall scale of your splash screen graphic
(i.e. scale it up or down):
SplashOverlayStyle = { Lua
splashoverlay= Bitmap{ x=30, y=50, image="playfirstlogo" };
scale=1.3333333
};
There are three tags you can specify in the style before displaying a splash: disableAbort - (default
is false) - if this is true, the user cannot click through the splash screen. translate - (default is
false) - if this is true, the movie will trigger the Flash translation pipeline (see TFlashHost::Play).
allowInput - (default is false) - if this is true, the flash movie will display the system cursor and
accept mouse clicks.
Parameters:
splashMovie (string) Name of SWF file to play.
splashGraphic (string) Name of bitmap to display if Flash fails.
time (number) Time to show bitmap.
Internal function that actually creates the window. This is the function that the script commands
ultimately call to create the window.
Parameters:
window (table) Table that describes the window.
Playground 4.0.17.1
146 Lua Reference
function FitToChildren ()
Cause a window to be resize to encompass current children
Intended to be used in a MakeDialog() (p. 148) context: Actually returns a function that, when
called, will resize the top window on the stack.
function GetTimer ()
Get the global timer value (TPlatform::Timer (p. 344))
Returns:
Number of milliseconds since the game was started.
Example
Parameters:
t (table) A table of window-creation command results.
Playground 4.0.17.1
148 Lua Reference
Playground 4.0.17.1
150 Lua Reference
MyStyle = Lua
{
parent=DefaultStyle, --- Optionally inherit from style table "DefaultStyle".
tag=value, --- Set tag to value. Any window tag can be set in a style.
tag2=value2, --- etc...
tag3=value3,
};
When the window creation code searches for a tag, it first searches the window creation script
table, then the current style, then parent of the style, and so forth until it finds the tag. Most tags
have a default value that they fall back to when not defined.
Parameters:
style (table) A table that describes a style.
Playground 4.0.17.1
152 Lua Reference
Parameters:
hotkey (string) The key to find.
label (string) The label to add an underline tag to.
Returns:
The label with markup to underline the appropriate hot key.
Returns:
A function that does the actual window creation.
See also:
Text() (opposite)
Window() (this page)
GUI-Related Constants in Lua. (p. 126)
• name Window name (used as a handle to search for window and identify it at runtime).
• align Window alignment: A combination of horizontal and vertical alignment flags. See Text
and Window Alignment. (p. 128). Disables special processing of negative position values.
Playground 4.0.17.1
154 Lua Reference
Parameters:
table (table) The table that describes the control.
Returns:
A function that does the actual window creation.
See also:
kCenter (p. 126)
kMax (p. 126)
function Yield ()
Yield control to C++ code. Returns any parameters passed to Resume().
Returns:
Any values passed to Resume()
Classes
• struct TVert
• struct TLitVert
• struct TTransformedLitVert
• class TVertexSet
Functions
• void CreateVertsFromRect (const TVec2 &pos, TTransformedLitVert ∗vertices, TVec2
∗corners, const TVec2 ∗uv, const TMat3 &matrix, float alpha, const TColor &tint)
Parameters:
pos Position on screen to anchor rectangle.
vertices An array of four vertices to fill.
corners An array of four corners (first is upper left, then clockwise) relative to x,y that define
the rectangle to create vertices for. Will be transformed by CreateVertsFromRect.
uv An array of two uv coordinates (upper left/lower right).
matrix A transformation matrix to apply to the rectangle.
alpha An alpha value to encode in the vertices.
tint A tint value to encode into the vertices.
Font Reference
14.1 Introduction
The MVEC File Format is Playground SDK’s font file format. Each glyph is stored as a series of
vector line and curve drawing commands. Because of the vector representation, the glyphs can be
smoothly scaled to many sizes.
Playground’s font rendering is somewhat unconventional, but is designed to make it easy to get
predictable results with a wide variety of fonts and when localizing games to many languages.
MVEC’s use quadric Bezier curves, which are defined by 3 control points. The CURVETO com-
mand uses p0 as the current point, and takes additional points as data used as p1 and p2 . The
path of the curve B(t) is defined by:
BYTE 1 byte
ULONG 4 bytes: a 32-bit unsigned long in little-endian
byte order
USHORT 2 bytes: a 16-bit unsigned short in
little-endian byte order
VALUE 2 bytes: a 16-bit signed short in little-endian
byte order used to represent a real number.
It’s a 16-bit fixed point representation with
9-bits of integer and 7-bits of decimal. So, if x
is float, then VALUE = (short)(x∗128).
MVC4
USHORT
UNUSED VALUES (6-bytes) reserved for future use
The remainder of the file is the vector commands for each glyph.
Note: The "advance" value is similar to "kerning" but rather than it being the space between ad-
jacent Glyphs, it’s the space between the starting points for adjacent glyphs. MVEC currently
does not support Kerning tables where character spacing is specialized based on which glyphs are
neighboring each other.
When drawing a glyph, the vectors are rasterized and then filled in using an odd/even fill rule.
That is, for each scan line, from left to right, the first scan line encountered starts the fill, the next
scan line stops the fill, and so on.
Fonts are a whole world in and of themselves. There is a rich history and great reasons for a wealth
of complexity. Playground SDK tries to simplify and make fonts practical from the perspective of
a programmer who thinks about fonts as "text that fits in a rectangle".
As such, Playground SDK makes the notion of "line height" primary. All scaling issues are derived
from that constraint. The concepts of "point size" and "leading" are therefore secondary. So in
Playground SDK, the size at which a font is rendered is specified as its line height, where line
height is the exact height in pixels needed to display a line of text at that size, including line-
spacing. (Note a feature is provided to add additional line-spacing when desired for visual effect,
but it is not necessary to use this for text to be adequately spaced).
Playground defines the "tallest" ascender as the glyph for the letter "W".
It defines the "deepest" descender as the deepest descender in the set of "low-ASCII" (UNICODE
values < 128) excluding the glyph for underscore (glyph 95: _).
A line is then defined as follows, 15% of the line will be "above the W", and 5% of the line will
be below the deepest descender (frequently this is "y"). Note that some novelty fonts don’t have
typical descenders (e.g. they are all caps style) — thus, the more algorithmic approach to selecting
the deepest descender. In the other direction, due to more variability in styles, "W" proves to be a
more reliable option.
Playground 4.0.17.1
160 Font Reference
Given this definition, a scale factor is selected to be applied to the font’s glyphs for the requested
line-height.
After these determinations are made, all glyphs in the font are analyzed. If a particular glyph
would ascend past the top of the line, or descend past the bottom of the line, it is assigned a
y-axis-only scale-factor that will "squish" it to fit.
This scaling approach shows an English language bias, but has been proven to yield beautifully
localized games in languages including Western and Eastern European languages (e.g. Dutch,
Russian) to Asian languages (e.g. Japanese, Korean) to Middle Eastern Languages (e.g. Arabic.
Note that for Arabic, Playground has a string table pre-processing tool to handle UNISCRIBE
issues for right-to-left and cursive texts.)
This scaling approach was derived experimentally, so it "just works" by taking into account things
that were actually encountered across many fonts and many games. For example, the top margin
is bigger than the bottom margin to better accommodate Western European extended glyphs, e.g.,
Á or Ė.
Operator Definitions
• const char operator[ ] (uint32_t i) const
• str & operator= (const str &s)
• str & operator= (const char ∗p)
• str operator+ (const str &) const
• str operator+ (char) const
• bool operator== (const str &) const
• bool operator< (const str &) const
• bool operator> (const str &) const
• bool operator<= (const str &) const
• bool operator>= (const str &) const
• bool operator!= (const str &s) const
• str & operator+= (const str &s)
• str & operator+= (const char c)
Public Types
• enum eFlags { kCaseInsensitive, kReplaceAll, kReverse }
162 Class and File Reference
Classes
• class TStringData
enum str::eFlags
Flags for str::find (p. 168) and str::replace (p. 168).
Enumerator:
kCaseInsensitive Case insensitive search.
kReplaceAll Replace all instead of just the first match.
kReverse Search starting from end of string and working backwards. start in this case means
characters from end of string.
str::str ()
Create an empty string.
Playground 4.0.17.1
164 Class and File Reference
str::∼str ()
Destructor.
Playground 4.0.17.1
166 Class and File Reference
Returns:
A reference to this.
Referenced by TScript::PopBool().
Referenced by TWindow::GetID().
Playground 4.0.17.1
168 Class and File Reference
Parameters:
formatstring Format string.
va var-args argument list.
str& str::replace (str searchString, str replaceString, uint32_t flags = 0, uint32_t start = 0)
Search-and-replace a substring.
Parameters:
searchString String to find.
replaceString String to replace found string with (can be empty).
flags eFlags for options.
start Search start.
Returns:
A reference to this str (p. 161).
void str::unique ()
Force this instance of this string to be unique; prepare for modification.
uint32_t str::overlay (int32_t start, const char ∗ buffer, uint32_t count, bool bTerminate = true)
Overlay a string into the current string.
Parameters:
start Start of the new overlay as an index into the current string. Can be (or extend) beyond
the end of the string. Can also be npos, to indicate the end of the string.
buffer String to overlay. Is 8-bit safe (can contain NULL bytes).
count Size of string to overlay.
bTerminate True to add a NULL character in the str (p. 161) at the end of this overlay.
Returns:
The character index past the end of the overlayed characters.
void str::downcase ()
Convert this string to lower-case in place.
Playground 4.0.17.1
170 Class and File Reference
Parameters:
s Pointer to the character.
Returns:
Number of bytes in this character. Zero if the character is a null terminator.
Referenced by utf8length().
References sizeof_utf8_char().
Public Attributes
• TVec2 mPosition
• TVec2 mUp
• TReal mScale
• TColor mColor
• TReal mFrame
TVec2 T2dParticle::mUp
Current up vector of particle. Referenced as pUp.
TReal T2dParticle::mScale
Current scale of particle. Referenced as pScale.
TColor T2dParticle::mColor
Current particle color. Referenced as pColor.
TReal T2dParticle::mFrame
Current frame of the particle animation (as int). Referenced as pFrame.
Playground 4.0.17.1
172 Class and File Reference
TParticleRenderer
T2dParticleRenderer
• mFrame [1] The current particle frame (when using a TAnimatedTexture (p. 182)).
See also:
T2dParticle (previous page)
TLuaParticleSystem (p. 264)
virtual T2dParticleRenderer::∼T2dParticleRenderer ()
Destructor.
Playground 4.0.17.1
174 Class and File Reference
TSprite
TAnimatedSprite
A TSprite (p. 419) with an attached TScript (p. 389). Similar to TSprite (p. 419), a TAnimated-
Sprite (this page) should only ever be stored as a reference, but it will work to store one in either
a TAnimatedSpriteRef or a TSpriteRef.
Typically you will assign a TAnimatedTexture (p. 182) to a TAnimatedSprite (this page); however,
it is legal to assign a normal TTexture (p. 463) to a TAnimatedSprite (this page) instead. Obviously
the animation script will be unable to change "frames" if a normal TTexture (p. 463) is attached,
however.
Initialization/Destruction
Drawing
Animation Control
Playground 4.0.17.1
176 Class and File Reference
Frame Access
• void SetCurrentFrame (int32_t frame)
• int32_t GetCurrentFrame ()
Utility
• TAnimatedSpriteRef GetRef ()
virtual TAnimatedSprite::∼TAnimatedSprite ()
Destructor.
Playground 4.0.17.1
178 Class and File Reference
Parameters:
clock Clock to use for timing. If NULL, then the global timer is used.
void TAnimatedSprite::Stop ()
Stops an animation script that’s already playing.
Scripts will retain global variable settings even after they’re stopped.
void TAnimatedSprite::Die ()
Stop and eradicate the script associated with an animation.
Any variables saved in the global environment will be erased. The next time you call Play() (this
page) or GetScript() (opposite) it will reload any associated TAnimatedTexture() script.
int32_t TAnimatedSprite::GetCurrentFrame ()
Get the current animation frame.
Returns:
Current animation frame number.
TScript∗ TAnimatedSprite::GetScript ()
Gets the current script associated with this animation. Creates a script if one doesn’t exist already.
DO NOT CACHE this pointer: this script can change over time. As long as you don’t call Die()
(opposite) on this animation or reload it from a file, it will copy its environment across scripts,
so you can set global variables and be reasonably assured that when you hit "Play" it will retain
them–even if it’s running in a different TScript (p. 389) (technically a different thread).
Returns:
The current script.
Playground 4.0.17.1
180 Class and File Reference
TScriptCodeRef TAnimatedSprite::GetScriptCode ()
Get a reference to the compiled script code, to allow you to keep a reference to it so that it won’t
be reloaded next time you run the same animation.
Returns:
A reference to the loaded script, or an empty reference if no script was loaded, or if the script
was run from a string or XML file.
void TAnimatedSprite::NewScript ()
Reset the script to a virgin one that has been initialized with the proper animation functions.
Not necessary to call prior to LoadScript or InitXML, as these functions will call it if no script has
been loaded. However, if you want a clean interpreter state, you can call this function.
TAnimatedTextureRef TAnimatedSprite::GetAnimatedTexture ()
Return an animated texture, if one is attached. If no texture is attached, or if a normal TTexture
(p. 463) is attached, return an empty reference.
Returns:
A TAnimatedTextureRef, if one is bound to this sprite.
uint32_t TAnimatedSprite::GetNumAnchors ()
Get the number of anchors in the bound animation.
Returns:
Number of anchors. Returns zero if there is no animated texture attached.
uint32_t TAnimatedSprite::GetNumFrames ()
Get the number of frames in the bound animation.
Returns:
Number of frames in the animation. Returns one (1) if there is no animated texture attached.
TAnimatedSpriteRef TAnimatedSprite::GetRef ()
Get the TAnimatedSpriteRef for this TAnimatedSprite (p. 175).
Playground 4.0.17.1
182 Class and File Reference
TAsset
TTexture
TAnimatedTexture
Factory Methods/Destruction
Drawing Methods
• virtual void CopyPixels (int32_t x, int32_t y, const TRect ∗sourceRect, TTextureRef _dst)
• virtual void DrawSprite (TReal x, TReal y, TReal alpha, TReal scale, TReal rotRad, uint32_t
flags)
• virtual void DrawSprite (const TDrawSpec &drawSpec)
• TPoint GetRegistrationPoint ()
• TPoint GetRegistrationPoint (int32_t frame)
• virtual uint32_t GetWidth ()
• virtual uint32_t GetHeight ()
Utility Functions
• str GetScript ()
• str GetPath ()
• TAnimatedTextureRef GetRef ()
Playground 4.0.17.1
184 Class and File Reference
Public Types
• enum { kNoFrame }
Protected Attributes
• TAnimatedTextureData ∗ mATData
virtual TAnimatedTexture::∼TAnimatedTexture ()
Destructor.
Parameters:
assetName Name of asset.
imageOverride Image Override (if any)
maskOverride Mask Override (if any)
Returns:
A string that represents the handle of the object.
Delegates to TTexture::CopyPixels() (p. 468), which means that it will copy from the multi-frame
source image, not from the individual frame.
Parameters:
x Left side of resulting rectangle.
y Top edge of resulting rectangle.
sourceRect Source rectangle to blit. NULL to blit the entire surface.
_dst Destination texture. NULL to draw to back buffer.
See also:
TTexture::CopyPixels (p. 468)
Playground 4.0.17.1
186 Class and File Reference
uint32_t TAnimatedTexture::GetNumFrames ()
Get number of frames in this animation
Returns:
Number of frames in animation.
int32_t TAnimatedTexture::GetCurrentFrame ()
Get the current frame of the animation
Returns:
frame Current frame of animation, from 0 to n-1, where n is the number of frames.
TRect TAnimatedTexture::GetAnimationBoundingBox ()
Get the bounding rectangle for this animation.
Returns:
a TRect (p. 364) that would contain the entire animation.
Playground 4.0.17.1
188 Class and File Reference
uint32_t TAnimatedTexture::GetNumAnchors ()
Get number of anchors in this frame of animation
Returns:
Number of anchors in this frame of animation.
TPoint TAnimatedTexture::GetRegistrationPoint ()
Get the initial image registration point.
The registration point is point from which the image coordinates are calculated.
Returns:
Registration point
Returns:
Registration point
str TAnimatedTexture::GetScript ()
Get the animation script that was embedded in the XML file.
Returns:
Animation script
str TAnimatedTexture::GetPath ()
Get the path to the source data file.
Returns:
A string that represents the path to the source data file.
TAnimatedTextureRef TAnimatedTexture::GetRef ()
Get a shared pointer (TAnimatedTextureRef) to this texture.
Returns:
A TAnimatedTextureRef that shares ownership with other Refs to this texture.
Playground 4.0.17.1
190 Class and File Reference
TTask
TAnimTask
TScript
Playground 4.0.17.1
192 Class and File Reference
Parameters:
clock Clock that this anim task uses to determine how much time has passed. If this parame-
ter is null then the global clock is used.
void TAnimTask::SetDelay (uint32_t delay, bool autoRepeat = true, bool resetTime = true,
bool forceFrequency = false)
Set the animation delay.
Parameters:
delay Number of milliseconds to wait to call DoTask().
autoRepeat Repeat this delay after every task.
resetTime Reset the time so that the (initial) delay is counted from now rather than from the
last task event time.
forceFrequency Force the frequency to be the same as the delay implies; will run the Ani-
mate() (this page) call multiple times if more than twice the time of delay has elapsed
since the last call.
Will not work if resetTime is also true, since resetTime causes the time to be set to the now+delay
after the first call, and as such forceFrequency will never cause it to loop.
void TAnimTask::Pause ()
Pause the current task. Prevents the Animate task from being called.
Resume by calling SetDelay() (this page) or RunOnDraw() (opposite), as appropriate.
uint32_t TAnimTask::GetTimeUntilReady ()
Get the number of milliseconds before this task will be ready to trigger again.
Returns a negative number if the next call to Ready() would be true immediately.
Returns:
Number of milliseconds before this task is ready. Returns UINT_MAX if task is disabled.
TClock∗ TAnimTask::GetClock ()
Get the reference clock.
Returns:
A pointer to the currently associated clock.
uint32_t TAnimTask::GetTime ()
Get the current elapsed time of the attached clock.
Returns:
Current elapsed time.
Playground 4.0.17.1
194 Class and File Reference
TAsset
TAnimatedTexture
• virtual ∼TAsset ()
• TAssetRef GetRef ()
Friends
• class TAssetManager
virtual TAsset::∼TAsset ()
Destructor.
Playground 4.0.17.1
196 Class and File Reference
After you’ve referenced an image, calling TTexture::Get() (p. 465) on that image will retrieve the
reference; however, calling TAssetMap::GetTexture (p. 198) will help you in one of two ways,
depending on the state of TAssetMap::SetAutoLoad() (opposite):
• If SetAutoLoad is false (default), it will ASSERT in debug build that the texture isn’t found if
you forgot to add it to the map.
• If SetAutoLoad is true, it will load it and hold the reference until the map is destroyed. That
way the next time you reference it, it will be able to retrieve the already loaded version, even
if you’ve released the in-game reference.
See also:
Game Assets (p. 13)
TAsset (p. 194)
virtual TAssetMap::∼TAssetMap ()
Destructor.
Playground 4.0.17.1
198 Class and File Reference
"checkers/helium",
"checkers/rowClear",
NULL
}
TAssetMap map;
map.AddAssets(assets);
Note you can add flags to TSound (p. 409) and TTexture (p. 463) references. See TSound::Get()
(p. 410) and TTexture::Get() (p. 465) for details.
Parameters:
assets Array of assets to add.
void TAssetMap::Release ()
Release ALL managed assets. All previously added assets are released and their records are
purged. After calling this you can again add assets as usual.
Note that assets that are still referenced elsewhere in your code (or by, e.g., existing TSpriteRefs)
will not be destroyed.
A release will happen implicitly on destruction of the TAssetMap (p. 196).
Playground 4.0.17.1
200 Class and File Reference
TBegin2d::∼TBegin2d ()
Destructor.
References Done().
TBegin3d::∼TBegin3d ()
Destructor.
References Done().
Playground 4.0.17.1
202 Class and File Reference
TWindow
TLayeredWindow
TButton
Public Types
• enum EButtonType { kPush, kToggle, kRadio, kNumTypes }
• enum EButtonLayer { kUp, kDown, kOver, kOverOn }
• enum EMouseState { kMouseIdle, kMousePush, kMouseOver, kMouseActivated }
• enum EButtonCreateFlags { kGroupStart, kSendMessageToParent, kCloseWindow, kDe-
faultButton, kCancelButton }
Classes
• class Action
An abstract action class for button actions.
• class LuaAction
A class that wraps a Lua command in an action.
Playground 4.0.17.1
204 Class and File Reference
kRadio One of several "radio" buttons in a group. Must call BeginGroup() (p. 141) before the
first button in the Lua script, or call TButton::AddFlags(kGroupStart) on the first button
in the group.
kNumTypes Number of button types (not a real type).
enum TButton::EButtonLayer
The button layers.
Enumerator:
kUp Button is in "up" or "off" state.
kDown Button is in "down" or "on" state.
kOver Button is in roll-over state (and is off for toggles and radio buttons).
kOverOn Button is in roll-over state and is "on".
enum TButton::EMouseState
TButton (p. 202) internal dynamic state.
Enumerator:
kMouseIdle Button mouse state is idle.
kMousePush Button is being pushed by a mouse click.
kMouseOver Button is being rolled over by the mouse.
kMouseActivated A transient state indicating that the button has been activated. Reverts
immediately to kMouseIdle.
enum TButton::EButtonCreateFlags
Button creation flags.
Enumerator:
kGroupStart This button is the first in a group.
kSendMessageToParent Send the button’s message to the parent modal.
kCloseWindow Automatically send the parent TModalWindow (p. 298) a close message
when this button is pushed.
kDefaultButton This button is default button in the local context.
kCancelButton This button is a cancel button in the local context.
TButton::∼TButton ()
Destructor.
void TButton::Toggle ()
Toggle the button’s state. Button must be of type kToggle, or this method will ASSERT.
EButtonType TButton::GetType ()
Get the button’s type.
Returns:
Type of the button.
EMouseState TButton::GetState ()
Get the current mouse state of the button.
Returns:
The state of the button with regards to the mouse.
bool TButton::GetOn ()
Return whether a particular radio button is on.
Returns:
True for on.
bool TButton::IsDefault ()
Return true if this is a default button.
Returns:
True if default.
Playground 4.0.17.1
206 Class and File Reference
bool TButton::IsCancel ()
Return if this is a cancel button.
Returns:
True if this button should abort the window.
str TButton::GetLabel ()
Get the label for this button.
Returns:
The button’s label.
Parameters:
point Mouse position.
bool TButton::DoCommand ()
Do the command associated with this button
Returns:
True if the window was deleted as a result of the command.
Playground 4.0.17.1
208 Class and File Reference
• graphics (table) An array of up to four images for the button: Three for push-buttons (Up,
RollOver, Down), Four for toggle and radio buttons (Up, RollOver-Up, Down, RollOver-
Down). If the array has fewer than 3 or 4 images, additional images are duplicated from the
last given image.
• rolloversound (string) Name of sound to play when mouse rolls over the button.
Remember to always call the base class if you’re overriding this function.
Parameters:
style Current style environment that this window was created in.
Playground 4.0.17.1
210 Class and File Reference
TButton::Action
TButton::LuaAction
TButton::Action
TButton::LuaAction
Public Attributes
• TLuaFunction ∗ mAction
TButton::LuaAction::∼LuaAction ()
Destructor.
Playground 4.0.17.1
212 Class and File Reference
Parameters:
button A pointer to the button triggering the action.
Returns:
• TClock ()
• virtual ∼TClock ()
• void Start (void)
• bool Pause (void)
• void Reset (void)
• uint32_t GetTime (void)
• void SetTime (uint32_t t)
• bool GetPaused ()
virtual TClock::∼TClock ()
Destructor.
Playground 4.0.17.1
214 Class and File Reference
bool TClock::GetPaused ()
Return whether the clock is paused.
Returns:
True if paused.
• TColor ()
• TColor (TReal R, TReal G, TReal B, TReal A)
• void Init (uint32_t R, uint32_t G, uint32_t B, uint32_t A)
• bool operator== (const TColor &color) const
• bool operator!= (const TColor &color) const
Public Attributes
• TReal r
• TReal g
• TReal b
• TReal a
Playground 4.0.17.1
216 Class and File Reference
References a, b, g, and r.
TReal TColor::r
Red value, 0-1.
Referenced by operator==().
TReal TColor::g
Green value, 0-1.
Referenced by operator==().
TReal TColor::b
Blue value, 0-1.
Referenced by operator==().
TReal TColor::a
Alpha value, 0-1.
Referenced by operator==().
Playground 4.0.17.1
218 Class and File Reference
• TColor32 ()
• TColor32 (const TColor &c)
• TColor32 (uint8_t r, uint8_t g, uint8_t b, uint8_t a)
• TColor32 (uint32_t c)
• uint8_t Alpha () const
• uint8_t Red () const
• uint8_t Green () const
• uint8_t Blue () const
• void SetAlpha (uint8_t a)
• void SetRed (uint8_t r)
• void SetGreen (uint8_t g)
• void SetBlue (uint8_t b)
Public Attributes
• uint32_t color
TColor32::TColor32 (uint32_t c)
Build a TColor32 (opposite) from an unsigned long ARGB (A is highest byte).
Parameters:
c An "ARGB"-order packed color.
Playground 4.0.17.1
220 Class and File Reference
Do not modify directly! The meaning of this value may change from video card to video card,
or from OS X to Windows, or from Intel to PowerPC Macs.
TWindow
TModalWindow
TDialog
Public Types
• enum { kResponseOK }
Protected Types
• enum { kHttpLink }
Playground 4.0.17.1
222 Class and File Reference
virtual TDialog::∼TDialog ()
Destructor.
Public Attributes
• TMat3 mMatrix
• TVec2 mCenter
• TColor mTint
• TReal mAlpha
• TRect mSourceRect
• uint32_t mFlags
• TRenderer::EBlendMode mBlendMode
Playground 4.0.17.1
224 Class and File Reference
If you set kUseCenter on the TDrawSpec (previous page) of a TAnimatedSprite (p. 175), you
will disable the automatic positioning of the TAnimatedSprite (p. 175), and the animation
will no longer work as expected.
TMat3 TDrawSpec::mMatrix
3x3 matrix including the offset and relative orientation (and scaling) of the sprite.
Use mMatrix[2] to set the position where the center of sprite is to be drawn.
Use mMatrix.Scale() to set the scale of the sprite.
Referenced by GetRelative(), and TDrawSpec().
TVec2 TDrawSpec::mCenter
Logical center of the texture in pixels; can be outside of the texture. Drawing of the texture will be
done relative to this point: If this point is (0,0), it will draw relative to the upper left corner of the
image, for instance.
This is not the parameter to use to set the position of an object; for that, see TDrawSpec::mMatrix
(this page). If you misuse the mCenter field to position a sprite, you will likely run into problems
with inherited positions and TAnimatedTexture (p. 182) drawing. The mCenter field isn’t inher-
ited (as it’s intended to specify the reference point of this sprite), and TAnimatedTexture (p. 182)
uses mCenter internally to properly position the animation after sidewalk has cropped all of the
frames.
This parameter is not inherited when used with TSprite::Draw() (p. 422), so if you want to modify
the center of a sprite you need to modify the sprite’s TSprite::GetDrawSpec() (p. 425) and not the
environment passed in to TSprite::Draw() (p. 422).
mFlags must have kUseCenter set to cause this field to be valid. Otherwise the actual center of the
texture is used.
See also:
kUseCenter (opposite)
TColor TDrawSpec::mTint
Vertex coloring for the texture. The alpha channel of this color is ignored. Default value on con-
struction is pure white.
Applies only to this object–for sprites, does NOT get inherited by child sprites.
TReal TDrawSpec::mAlpha
Alpha to use to draw sprite. Zero is completely transparent and one is completely opaque (subject
to blend mode and texture alpha values).
This value is multiplicatively inherited in child sprites using GetRelative() (opposite).
Referenced by GetRelative().
TRect TDrawSpec::mSourceRect
Source rectangle to extract image from.
Playground 4.0.17.1
226 Class and File Reference
This parameter is NOT inherited when used with TSprite::Draw() (p. 422), so if you want to mod-
ify the source rectangle of a sprite you need to modify the sprite’s TSprite::GetDrawSpec() (p. 425)
and not the environment passed in to TSprite::Draw() (p. 422).
mFlags must have kUseSourceRect set to activate.
uint32_t TDrawSpec::mFlags
Options for drawing. Inherits flip flags with an XOR, so if a parent and child are, e.g., both hori-
zontally flipped, the child will be drawn normally.
Options include kFlipHorizontal (p. 224), kFlipVertical (p. 224), kUseSourceRect (p. 224), and
kUseCenter (p. 224).
Referenced by GetRelative().
TRenderer::EBlendMode TDrawSpec::mBlendMode
Blend mode to use, if any; set to TRenderer::kBlendINVALID (p. 373) to use current mode (de-
fault). Inherited when parent mode set and child is kBlendINVALID.
Referenced by GetRelative().
TEncrypt::∼TEncrypt ()
Destructor
Playground 4.0.17.1
228 Class and File Reference
uint32_t TEncrypt::GetLastSize ()
Get the last decrypted or encrypted data size.
Returns:
Size of last encrypted or decrypted data.
Key Codes
Use these constants to refer to the given keys in your code when processing an OnKeyDown()
message.
See also:
TWindow::OnKeyDown (p. 514)
Public Types
• enum EEventCode { kIdle, kNull, kClose, kQuit, kMouseDown, kExtendedMouseEvent,
kMouseUp, kMouseMove, kMouseLeave, kMouseHover, kKeyDown, kKeyUp, kChar,
kUTF32Char, kRedraw, kTimer, kDisplayModeChange, kActivate, kFullScreenToggle }
• enum EKeyFlags { kShift, kControl, kAlt, kExtended }
Public Attributes
• int32_t mType
• int32_t mKey
• TPoint mPoint
• EKeyFlags mKeyFlags
Playground 4.0.17.1
230 Class and File Reference
enum TEvent::EEventCode
Event codes.
Enumerator:
kIdle Idle event processing time.
kNull EMPTY event.
kClose A close request (Alt-F4, clicking close button).
kQuit A QUIT NOW event.
kMouseDown Mouse down.
kExtendedMouseEvent Right Mouse Button/Wheel down.
kMouseUp Mouse up.
kMouseMove Mouse move.
kMouseLeave Mouse has left the window. You must TWindowMan-
ager::AddMouseListener() (p. 524) the mouse to receive this message; note that
TButton-derived classes automatically capture the mouse on mouse-over.
kMouseHover Mouse has hovered over a point on the window.
kKeyDown Key down.
kKeyUp Key up.
kChar translated character event
kUTF32Char translated utf32 event
kRedraw Redraw the screen now.
kTimer A timer has triggered.
kDisplayModeChange The display mode has changed.
kActivate Our application has activated/deactivated. mKey is set to 0 on deactivate, or 1 on
activate.
kFullScreenToggle The user has toggled full screen mode. mKey is set to 0 on windowed
mode, or non-zero on full screen mode.
enum TEvent::EKeyFlags
int32_t TEvent::kUp
Up arrow key.
int32_t TEvent::kDown
Down arrow key.
int32_t TEvent::kLeft
Left arrow key.
int32_t TEvent::kRight
Right arrow key.
int32_t TEvent::kEnter
Enter key. On keyboards with more than one key of this description, the same constant is returned
for both.
int32_t TEvent::kEscape
The "Esc" key.
int32_t TEvent::kTab
The Tab key.
int32_t TEvent::kPaste
The "Paste" keyboard combination. Typically Control-V on Windows, Command-V on OS X.
int32_t TEvent::kPageUp
The Page-Up key.
int32_t TEvent::kPageDown
The Page-Down key.
int32_t TEvent::kBackspace
The backspace key.
int32_t TEvent::kDelete
The Delete key.
Playground 4.0.17.1
232 Class and File Reference
int32_t TEvent::mType
Type of event
See also:
EEventCode (p. 230)
int32_t TEvent::mKey
Key for keyboard events.
TPoint TEvent::mPoint
Point for mouse events.
EKeyFlags TEvent::mKeyFlags
Flags for key events.
Paths must be separated by forward slash ("/"). All files must be specified without a leading slash.
A file in "assets/bitmaps/" called "my.png" would be loaded with the handle "bitmaps/my.png".
To access a writable folder, prefix the file name with either user:, common:, or desktop: to get to
either the user’s personal data folder, the system’s common data folder, or the desktop folder. You
may NOT write to the assets folder during the game –it will ASSERT in debug build if you try.
There is a set of C stdio-compatible routines that you can use to port existing fopen-style interfaces:
• pf_open()
• pf_close()
• pf_seek()
• pf_tell()
• pf_getc()
• pf_gets()
• pf_read()
• pf_write() (only to user:, common: and desktop: folders)
• pf_eof()
• pf_error()
• pf_ungetc()
If you absolutely must use fscanf(), you can use pf_fgets to get a line of text, and then use sscanf()
to parse the line. However, in general it is be much better to read and write the data as XML using
TXmlNode (p. 532).
Playground 4.0.17.1
234 Class and File Reference
• TFile ()
• ∼TFile ()
• bool Open (str path, eFileMode mode=kReadBinary)
• bool IsValid () const
• bool AtEOF ()
• void Close ()
• void Seek (long offset, eFileSeek seek)
• long Tell ()
• long Size ()
• long Read (void ∗buffer, unsigned long bytes)
• long Write (const void ∗buffer, unsigned long bytes)
• void Unget ()
Friends
• class TPlatformData
TFile::∼TFile ()
Destructor.
bool TFile::AtEOF ()
Return true if the file is at the EOF.
Returns:
True on EOF.
void TFile::Close ()
Close a file. Optional; file is automatically closed on destruction of the TFile (p. 233)
long TFile::Tell ()
Get the current file position.
Returns:
Current offset into the file.
Playground 4.0.17.1
236 Class and File Reference
long TFile::Size ()
Get the file’s size.
Returns:
File size in bytes.
void TFile::Unget ()
"Unget" one character. Semantics are similar to ungetc, in that you can only ever "unget" one
character.
Unlike ungetc, it will only unget exactly the previous character you just read–there is no option to
select a character to unget.
Ungetting past the beginning of the file is not allowed.
static bool TFile::GetNextFile (str folder, str ∗ file, bool subfolders = false)
Iterate through the files in a folder.
Parameters:
folder Folder to search. File globs are NOT supported currently.
file Pointer to a string to receive each file name.
Start iteration with an empty string, and pass the value you received previously to get the next
value in the iteration.
Parameters:
subfolders True to return files in subfolders as well.
Returns:
True if successful; false to signal end of iteration.
Playground 4.0.17.1
238 Class and File Reference
Parameters:
folder Folder to scan.
prefix File system prefix to expect.
1. Have an 800x600 stage in your Flash content (assuming your display resolution is 800x600).
2. Have an empty first frame, and then place an 800x10 rectangle shape cast member at (0,-30).
(Again, assuming that 800 is the display width.)
This will guarantee that the Flash stage size is calculated correctly by Playground. The Mac version
of Playground uses WebKit to load an HTML file that loads an SWF file that loads the Flash content
(it’s complicated, but necessary). Flash does not have a method to determine the stage size of the
loaded clip, however. You can get the dimensions of the movie clip, but these are computed as the
bounding box of the objects onstage, and this is what we are using when we decide how much we
need to scale the loaded content to fit 800x600.
This is why the rectangle shape is necessary: So that Playground can retrieve the 800 width and
determine that it doesn’t need to scale the resulting Flash file.
Playground 4.0.17.1
240 Class and File Reference
TFlashHost::∼TFlashHost ()
Destructor.
void TFlashHost::Stop ()
Stop playing file.
long TFlashHost::GetTotalFrames ()
Get the total number of frames.
Returns:
Number of frames.
long TFlashHost::GetFrameNum ()
Get the current frame number.
Returns:
Frame number.
bool TFlashHost::IsPlaying ()
Test to see whether the animation is playing.
Returns:
True if playing.
Playground 4.0.17.1
242 Class and File Reference
bool TGameState::QueryRestartMode ()
Query this function frequently; if it ever returns true, immediately restart the current game mode
at level 1.
Returns:
true to restart game mode.
Playground 4.0.17.1
244 Class and File Reference
bool TGameState::QueryJumpToMenu ()
Query this function frequently; if it ever returns true, immediately exit the current game mode and
bring up the main menu.
Returns:
true to go to menu.
bool TGameState::QueryMuteGame ()
Query this function to determine the mute state displayed in the game.
As your user modifies the mute state within the game, you should call SetState() (previous page)
with kMute to notify the system of the change.
Returns:
true to mute game.
bool TGameState::QueryPauseGame ()
TPlatform::GetEvent() (p. 341) will handle QueryPauseGame() (this page); no user code is re-
quired to handle it correctly.
Returns:
True to pause game; false otherwise.
Playground 4.0.17.1
246 Class and File Reference
virtual const char∗ TGameStateHandler::GetState (const char ∗ key, const char ∗ value)
Get the value of a state.
Parameters:
key Value to retrieve.
Playground 4.0.17.1
248 Class and File Reference
TWindow
TImage
The TImage (this page) class is a TWindow (p. 496) that contains and draws a TTexture (p. 463).
It is not intended that the windowing system be used to render sprites in your game–that’s what
the sprite system is for. Among other things, there is a limited flexibility in rendering options.
A TImage (this page) will automatically set its kOpaque flag based on SetAlpha() (next page)–a
SetAlpha() (next page) of less than 1 will reset the flag. In Lua initialization you can also use
"alpha=true" to reset the flag.
Event Handlers
Playground 4.0.17.1
250 Class and File Reference
Create a TImage (previous page) with staticImage set to false for an image that will change fre-
quently.
virtual TImage::∼TImage ()
Destructor.
TTextureRef TImage::GetTexture ()
Get the current image texture.
Returns:
A reference to the bound image.
TReal TImage::GetAlpha ()
Get the current alpha of this image.
Returns:
A value from 0 (transparent) to 1 (opaque).
TReal TImage::GetScale ()
Get the current scale of this TImage (p. 249)
Returns:
Scale from 0 - 1
Playground 4.0.17.1
252 Class and File Reference
TWindow
TLayeredWindow
TButton
Public Types
• enum { kAll }
virtual TLayeredWindow::∼TLayeredWindow ()
Destructor.
int32_t TLayeredWindow::GetCurrentLayer ()
Get the current active layer.
Returns:
An zero-based index to the current active layer.
uint32_t TLayeredWindow::GetNumLayers ()
Get the number of layers.
Returns:
The number of layers associated with this window.
Playground 4.0.17.1
254 Class and File Reference
initWindow Whether to run the init function OnNewParent() (p. 501) on this window.
Returns:
True if successful. False if OnNewParent() (p. 501) returned false, in which case child was
NOT added.
See also:
TWindow::AdoptChild (p. 503)
A 3d light.
Public Types
• TLight ()
Public Attributes
• ELightType mType
• TColor mDiff
• TColor mSpec
• TColor mAmb
• TVec3 mPos
• TVec3 mDir
• TReal mRange
• TReal mAttenuation [3]
• TReal mTheta
• TReal mPhi
enum TLight::ELightType
Light types.
Enumerator:
kDirectional A directional light source.
kPointSource A point source light.
kSpotLight A spotlight.
Playground 4.0.17.1
256 Class and File Reference
TColor TLight::mDiff
Diffuse value.
TColor TLight::mSpec
Specular value.
TColor TLight::mAmb
Ambient value.
TVec3 TLight::mPos
Position of light. No meaning for directional light sources.
TVec3 TLight::mDir
Direction of light. No meaning for point source light sources.
TReal TLight::mRange
Effective range of light. No meaning for directional light sources.
TReal TLight::mAttenuation[3]
Attenuation factors: Constant, Linear, and Quadratic. Attenuation is calculated based on the fol-
lowing equation:
1
A=
a 0 + a 1 D + a 2 D2
Referenced by TLight().
TReal TLight::mTheta
Angle of inner cone of spotlight, in radians.
TReal TLight::mPhi
Angle of outer edge of spotlight dropoff, in radians.
Playground 4.0.17.1
258 Class and File Reference
Public Attributes
• TVec3 pos
• uint32_t RESERVED
• TColor32 color
• TColor32 specular
• TVec2 uv
uint32_t TLitVert::RESERVED
UNUSED (must be zero).
TColor32 TLitVert::color
Vertex color.
TColor32 TLitVert::specular
Vertex specular component.
TVec2 TLitVert::uv
Vertex texture coordinate.
TLuaObjectWrapper
TLuaFunction
bool TLuaFunction::IsFunction ()
Test to verify that we’re actually bound to a function.
Returns:
True if our bound object is a Lua function.
Playground 4.0.17.1
260 Class and File Reference
References TLuaObjectWrapper::Push().
TLuaObjectWrapper
TLuaFunction TLuaTable
Protected Attributes
• lua_State ∗ mState
Playground 4.0.17.1
262 Class and File Reference
References Push().
virtual TLuaObjectWrapper::∼TLuaObjectWrapper ()
Destructor.
bool TLuaObjectWrapper::IsString ()
Is this object a string?
Returns:
True if it is a string.
bool TLuaObjectWrapper::IsNumber ()
Is the object a number?
Returns:
True if the object is a number.
bool TLuaObjectWrapper::IsTable ()
Is the object a table?
Returns:
True if a table
Referenced by TLuaTable::TLuaTable().
str TLuaObjectWrapper::AsString ()
Convert the object to a string.
Returns:
A string representation of the object, if one is available.
lua_Number TLuaObjectWrapper::AsNumber ()
Convert the object to a number.
Returns:
A numeric representation of the object, if one is available.
lua_State∗ TLuaObjectWrapper::GetState ()
Get the current state associated with this object.
Returns:
A Lua state.
Playground 4.0.17.1
264 Class and File Reference
Classes
• struct PInstruction
virtual TLuaParticleSystem::∼TLuaParticleSystem ()
Destructor.
void TLuaParticleSystem::NewScript ()
Reset the script to a virgin state.
Playground 4.0.17.1
266 Class and File Reference
Parameters:
name Name of process to use (or to replace).
processId The PFClassId of the class that provides the function. See Type Information and
Casting (p. 25) for more information.
See also:
AdoptFunctionInstance (this page)
Parameters:
name Name of process to use (or to replace).
function A new instance of the class that provides the function. The TLuaParticleSystem
(p. 264) will delete this function on destruction.
See also:
RegisterFunction (previous page)
TScript∗ TLuaParticleSystem::GetScript ()
Get a pointer to the attached particle system script.
Returns:
A pointer to the current script.
TScriptCodeRef TLuaParticleSystem::GetScriptCode ()
Get a reference to the asset-type TScriptCodeRef. This allows Lua scripts to be pre-loaded once
and maintained in the asset system.
Returns:
A reference to the TScriptCode (p. 398) object that contains the (compiled) Lua code.
bool TLuaParticleSystem::IsDone ()
Is the particle system done?
Returns:
True if done; false otherwise.
void TLuaParticleSystem::SetDone ()
Flag the particle system as done.
Playground 4.0.17.1
268 Class and File Reference
void TLuaParticleSystem::ResetDone ()
Not done any more!
uint32_t TLuaParticleSystem::GetParticleCount ()
Get number of current active particles.
Returns:
The current number of particles active.
TParticleRenderer∗ TLuaParticleSystem::GetParticleRenderer ()
Get the embedded particle renderer.
Returns:
A pointer to the TParticleRenderer (p. 320) associated with this particle system.
TLuaObjectWrapper
TLuaTable
Playground 4.0.17.1
270 Class and File Reference
uint32_t TLuaTable::GetSize ()
How many elements in the indexed portion of the table?
Returns:
Number of elements in the array portion of the table.
References TLuaObjectWrapper::Push().
Parameters:
key The key to the string.
defaultValue Default value if key isn’t found.
Returns:
A copy of the string, if one exists at that key. Otherwise an empty string.
Playground 4.0.17.1
272 Class and File Reference
Playground 4.0.17.1
274 Class and File Reference
TColor TLuaTable::GetColor (str key, const TColor & defaultValue = TColor(0, 0, 0, 0))
Get a TColor (p. 215) from a table of four values.
In Lua, if you define a color using the Color() (p. 143) function, you define it using values from
0-255. If you define using FColor() (p. 146), the values are from 0-1.
Parameters:
key Key of table.
defaultValue Default value to return if no table found.
Returns:
A TColor (p. 215).
If you stop an iteration in the middle, you’re responsible for deleting the last key you’ve
received in addition to the normal deletion of the last value.
Example Usage
Parameters:
key Pointer to variable to receive next key. Initialize it to NULL to start the iteration, and
leave the previous key in place to iterate.
Returns:
A pointer to a TLuaObjectWrapper (p. 261). You must delete this pointer when you’re done
with it. Returns NULL after the last table item.
Playground 4.0.17.1
276 Class and File Reference
• TMat3 ()
• TMat3 (TReal m00, TReal m01, TReal m02, TReal m10, TReal m11, TReal m12, TReal m20,
TReal m21, TReal m22)
• TMat3 (TVec3 v0, TVec3 v1, TVec3 v2)
• TMat3 (const TMat3 &rhs)
• TMat3 & operator= (const TMat3 &rhs)
• TMat3 & Identity ()
Accessors
Assignment Operators
Related Functions
(Note that these are not member functions.)
TMat3::TMat3 (TReal m00, TReal m01, TReal m02, TReal m10, TReal m11, TReal m12, TReal
m20, TReal m21, TReal m22)
Construct from individual values.
Playground 4.0.17.1
278 Class and File Reference
TMat3& TMat3::Identity ()
Initialize to an identity.
Referenced by TDrawSpec::TDrawSpec().
Playground 4.0.17.1
280 Class and File Reference
Parameters:
s Amount to scale X and Y axes.
Returns:
this matrix.
bool operator!= (const TMat3 & lhs, const TMat3 & rhs) [related]
Inequality.
Returns:
True on not equal.
TVec3 operator∗ (const TMat3 & lhs, const TVec3 & rhs) [related]
Matrix multiplication with a vector.
Returns:
M∗v
TVec2 operator∗ (const TMat3 & lhs, const TVec2 & rhs) [related]
Matrix multiplication with a vector.
Returns:
M∗v
TVec3 operator∗ (const TVec3 & lhs, const TMat3 & rhs) [related]
Matrix multiplication with a vector.
Returns:
vT ∗ M
TVec2 operator∗ (const TVec2 & lhs, const TMat3 & rhs) [related]
Matrix multiplication with a vector.
Returns:
vT ∗ M
TVec2 Multiply2x2 (const TMat3 & lhs, const TVec2 & rhs) [related]
A restricted 2x2 matrix vector multiply. Does the rotation/scaling but no translation of the vector.
Parameters:
lhs Matrix left-hand-side of the multiply
rhs Vector right-hand-side.
Returns:
Matrix[2x2]∗Vector
Referenced by operator%().
Playground 4.0.17.1
282 Class and File Reference
TVec2 Multiply2x2 (const TVec2 & lhs, const TMat3 & rhs) [related]
A restricted 2x2 matrix vector multiply. Does the rotation/scaling but no translation of the vector.
Parameters:
lhs Vector left-hand-side of the multiply
rhs Matrix right-hand-side.
Returns:
Vector∗Matrix[2x2]
TMat3 Multiply2x2 (const TMat3 & lhs, const TMat3 & rhs) [related]
TVec2 operator% (const TVec2 & lhs, const TMat3 & rhs) [related]
Restricted-multiply operator.
See also:
Multiply2x2() (previous page)
Returns:
Multiply2x2(lhs,rhs)
References Multiply2x2().
TVec2 operator% (const TMat3 & lhs, const TVec2 & rhs) [related]
Restricted-multiply operator.
See also:
Multiply2x2() (previous page)
Returns:
Multiply2x2(lhs,rhs)
References Multiply2x2().
TMat3 operator% (const TMat3 & lhs, const TMat3 & rhs) [related]
Restricted-multiply operator.
See also:
Multiply2x2() (p. 281)
Returns:
Multiply2x2(lhs,rhs)
References Multiply2x2().
TVec3 operator∗ (const TVec3 & lhs, const TMat4 & rhs) [related]
Matrix multiplication with a vector.
Returns:
vT ∗ M
Playground 4.0.17.1
284 Class and File Reference
Accessors
• TVec4 & operator[ ] (TIndex i)
• const TVec4 & operator[ ] (TIndex i) const
Assignment operators.
• TMat4 & operator+= (const TMat4 &rhs)
• TMat4 & operator-= (const TMat4 &rhs)
• TMat4 & operator∗= (const TMat4 &rhs)
• TMat4 & operator∗= (TReal rhs)
• TMat4 & operator/= (TReal rhs)
Initializers.
• TMat4 & Identity ()
• TMat4 & LookAt (const TVec3 &pos, const TVec3 &at, const TVec3 &up)
• TMat4 & Perspective (TReal nearPlane, TReal farPlane, TReal fov, TReal aspect)
• TMat4 & OffsetPerspective (TReal nearPlane, TReal farPlane, TReal fov, TReal aspect,
const TVec2 &offsets)
• TMat4 & Orthogonal (TReal left, TReal right, TReal bottom, TReal top, TReal zNear, TReal
zFar)
Manipulators
Utility Mmbers
Public Types
• enum { kDIM }
Related Functions
(Note that these are not member functions.)
Playground 4.0.17.1
286 Class and File Reference
TMat4::TMat4 (TReal m00, TReal m01, TReal m02, TReal m03, TReal m10, TReal m11, TReal
m12, TReal m13, TReal m20, TReal m21, TReal m22, TReal m23, TReal m30, TReal m31,
TReal m32, TReal m33)
Construct from individual values.
TMat4::∼TMat4 ()
Destruction.
Returns:
a reference to the TVec4 (p. 487) that represents the row.
TMat4& TMat4::Identity ()
Make this matrix the identity.
Returns:
A reference to this.
TMat4& TMat4::LookAt (const TVec3 & pos, const TVec3 & at, const TVec3 & up)
Change this matrix to be a view matrix that’s oriented to "look at" a point.
Parameters:
pos Viewer position.
at Point we’re looking at.
up Local "up" vector.
Returns:
A reference to this.
TMat4& TMat4::Perspective (TReal nearPlane, TReal farPlane, TReal fov, TReal aspect)
Make this matrix a perspective matrix.
Playground 4.0.17.1
288 Class and File Reference
Parameters:
nearPlane Distance from viewer to the near plane.
farPlane Distance from viewer to the far plane. The smaller your ratio of far to near, the
higher Z-buffer resolution you get.
fov The field of view in radians.
aspect The aspect ratio of the resulting view.
Returns:
A reference to this.
TMat4& TMat4::Orthogonal (TReal left, TReal right, TReal bottom, TReal top, TReal zNear,
TReal zFar)
Make this matrix an orthogonal projection matrix that transforms objects within the given box into
view coordinates.
Parameters:
left Left side of box.
right Right side of box.
bottom Bottom of box.
top Top of box.
zNear Near side of box.
zFar Far side of box.
Returns:
A reference to this.
Playground 4.0.17.1
290 Class and File Reference
Returns:
A reference to this.
Returns:
The determinant.
bool operator== (const TMat4 & lhs, const TMat4 & rhs) [related]
Equality.
Returns:
True on equal.
bool operator!= (const TMat4 & lhs, const TMat4 & rhs) [related]
Inequality.
Returns:
True on not equal.
TMat4 operator∗ (const TMat4 & lhs, const TMat4 & rhs) [related]
Matrix multiplication.
Returns:
M1 ∗ M2
TVec4 operator∗ (const TMat4 & lhs, const TVec4 & rhs) [related]
Matrix multiplication with a vector.
Returns:
M∗v
TVec3 operator∗ (const TMat4 & lhs, const TVec3 & rhs) [related]
Matrix multiplication with a vector.
Returns:
M∗v
Playground 4.0.17.1
292 Class and File Reference
TVec4 operator∗ (const TVec4 & lhs, const TMat4 & rhs) [related]
Matrix multiplication with a vector.
Returns:
M∗v
Public Attributes
• TColor mcDiff
• TColor mcAmb
• TColor mcSpec
• TColor mcEmit
• TReal mfPower
TColor TMaterial::mcAmb
Ambient value.
TColor TMaterial::mcSpec
Specular value.
TColor TMaterial::mcEmit
Emit (glow) value.
TReal TMaterial::mfPower
Specular reflectance. Zero to disable specular.
Playground 4.0.17.1
294 Class and File Reference
Never use C++ or C style casting to coerce a TMessage (this page) to another type; always
use GetCast<>() (p. 296). When a message is sent from Lua, it is wrapped in a TLuaMes-
sageWrapper, which will report the mType of the contained TMessage-derived message–and
it has a GetCast operator that will give you the actual contained message. But casting it to
your target object will result in undefined (and certainly incorrect) behavior, so it’s best to
always use GetCast.
• PFClassId ClassId ()
• virtual bool IsKindOf (PFClassId type)
• template<class TO>
TO ∗ GetCast ()
Public Types
Public Attributes
• int32_t mType
• str mName
• TWindow ∗ mDestination
virtual TMessage::∼TMessage ()
Destructor.
Playground 4.0.17.1
296 Class and File Reference
str TMessage::mName
Name of this message.
For a button message, this is the name of the button that is sending the message.
TWindow∗ TMessage::mDestination
Optional TWindow (p. 496) destination.
Playground 4.0.17.1
298 Class and File Reference
TWindow
TModalWindow
TDialog TScreen
• Manages a TClock (p. 213) that automatically gets paused when the modal is covered by
another modal.
• Does some internal bookeeping relevant to the window stack and opaque full-screen win-
dows.
Construction/destruction
• TModalWindow ()
• virtual ∼TModalWindow ()
Message handlers
TModalWindow handles these messages for you.
virtual TModalWindow::∼TModalWindow ()
Destructor.
Playground 4.0.17.1
300 Class and File Reference
Parameters:
task Task to remove.
Returns:
true if task was removed, false if task was not found
void TModalWindow::DestroyTasks ()
Destroy all tasks this window owns. Used when the window is about to be destroyed.
Destruction is "safe"–tasks will be added to a destroy list if the list is being iterated.
TWindow∗ TModalWindow::GetDefaultFocus ()
Get the current default focus
If the key starts with ’@’, then ANY modifiers will be accepted, e.g., "@A" would work for an
(uncaptured) "A", "Ctrl-A", "Alt-A", etc.
Parameters:
buttonToPress The name of the button to press. An empty string will delete the key associa-
tion.
* alt-SHIFT-Ctrl-f
*
would return
* shift-ctrl-alt-F
*
The normalized string always sorts the operators in the order shift, ctrl, alt, and presents them in
lower case. The key name itself is capitalized.
This function is used internally to normalize the key string in AddHotkey() (opposite) and
TModalWindow::OnKeyDown() (this page)–there’s no need for you to call it yourself unless
you’re extending TModalWindow (p. 298).
Parameters:
key Key to normalize.
Returns:
A normalized string.
Playground 4.0.17.1
302 Class and File Reference
TClock∗ TModalWindow::GetClock ()
Get a reference to the clock associated with this modal window. This clock will be automatically
paused and unpaused when other modal windows hide and reveal this modal window.
Returns:
A pointer to the clock.
Remember to always call the base class if you’re overriding this function.
Parameters:
style Current style environment that this window was created in.
Playground 4.0.17.1
304 Class and File Reference
TAsset
TModel
• void Draw ()
• bool Pick (uint32_t iWndX, uint32_t iWndY, TReal ∗pfPickDist, TVec3 ∗pvHit)
• str GetName ()
• long GetPolyCount ()
• uint32_t GetTriangleCount ()
• const uint16_t ∗ GetTriangles ()
• const TVert ∗ GetVertices ()
• uint32_t GetVertexCount ()
• TModelRef GetRef ()
Public Attributes
• TModelData ∗ mData
bool TModel::Pick (uint32_t iWndX, uint32_t iWndY, TReal ∗ pfPickDist, TVec3 ∗ pvHit)
Cast a ray at the model and determine whether it’s been hit. Uses current transformation matrix
to position model.
Parameters:
iWndX X in TScreen (p. 387) coordinates.
iWndY Y in TScreen (p. 387) coordinates.
pfPickDist Pointer to a float that starts out initialized to the maximum distance the cast ray
should collide with polygons. On return contains the actual distance from the screen to
the model.
pvHit The 3d point where the cast ray intersects the model.
Returns:
True if model hit; false otherwise.
str TModel::GetName ()
Get the name of the asset as it was created.
Returns:
The name of the asset.
long TModel::GetPolyCount ()
Get the number of polygons (triangles) in the model
Deprecated
uint32_t TModel::GetTriangleCount ()
Get the number of triangles in the triangle array.
Returns:
Number of triangles.
Playground 4.0.17.1
306 Class and File Reference
uint32_t TModel::GetVertexCount ()
Get the number of vertices in the model.
Returns:
A count of vertices in the vertex array.
See also:
GetVertices (this page)
TModelRef TModel::GetRef ()
Get a reference to this asset. Do not call in a constructor!
Reimplemented from TAsset (p. 195).
Playground 4.0.17.1
308 Class and File Reference
TParamSet
TParticleState
References Reset().
References ResetPartial().
Referenced by TParamSet().
uint8_t TParamSet::GetCount ()
Get the current parameter count
Returns:
Number of parameters in the set.
Playground 4.0.17.1
310 Class and File Reference
Referenced by TParticleMachineState::GetSize().
Returns:
A value in the set.
Playground 4.0.17.1
312 Class and File Reference
Public Attributes
• str mName
PFClassId TParticleFunction::ClassId ()
The class id of this class.
Playground 4.0.17.1
314 Class and File Reference
Playground 4.0.17.1
316 Class and File Reference
Parameters:
Type Type of parameter to extract.
param Parameter base (which parameter number this is)
Returns:
A Type reference that can be read or written to.
Parameters:
Type
value
References Push().
void TParticleMachineState::Leave ()
Exit a function (removes any remaining parameters; a NOP if the function pushed any return
values).
uint8_t TParticleMachineState::GetCount ()
Get the local parameter count
Returns:
Number of parameters in the set.
References TParamSet::GetOffset().
References TParamSet::ResetPartial().
Playground 4.0.17.1
318 Class and File Reference
uint8_t TParticleMachineState::GetNumParams ()
Get the number of parameters passed.
Returns:
The number of incoming parameters.
Public Attributes
• int16_t mBase
• uint16_t mSize
uint16_t ParticleMember::mSize
Size of this member.
Playground 4.0.17.1
320 Class and File Reference
TParticleRenderer
T2dParticleRenderer
The abstract particle renderer class: This class is used by TLuaParticleSystem (p. 264) to wrap an
actual particle renderer. This way you can use TLuaParticleSystem (p. 264) to drive the default 2d
particle system or other more complex systems.
• virtual void Draw (const TVec3 &at, TReal alpha, const ParticleList &particles, int maxPar-
ticles)=0
• virtual void SetTexture (TTextureRef texture)=0
• virtual void SetRendererOption (str option, const TReal(&value)[4])=0
• virtual TReal ∗ GetPrototypeParticle ()=0
• virtual uint32_t GetPrototypeParticleSize ()=0
• virtual str GetLuaInitString ()=0
virtual void TParticleRenderer::Draw (const TVec3 & at, TReal alpha, const ParticleList &
particles, int maxParticles)
Render the particles.
Parameters:
at Location to render particles.
alpha Alpha to render particles with.
particles The list of particles to render.
maxParticles The maximum number of particles this particle system is expecting to render.
MUST be greater than the number of particles or Bad Things will happen.
Playground 4.0.17.1
322 Class and File Reference
TParamSet
TParticleState
Playground 4.0.17.1
324 Class and File Reference
uint32_t TParticleState::GetCount ()
Get the current parameter count
Returns:
Number of parameters in the set.
uint32_t TParticleState::GetMS ()
Get the number of milliseconds being processed.
Returns:
Time elapsed in milliseconds.
bool TParticleState::GetAlive ()
Query whether this particle is still alive.
Returns:
True if alive.
void TParticleState::KillParticle ()
Kill this particle (mark for destruction).
<hiscore> XML
<language>en</language>
<defaulterror>Unable to connect to server. Please try again later.</defaulterror>
</hiscore>
The language parameter will override any setting used with eLanguage property in SetProperty()
(p. 327). Language should be ISO-639 (e.g. "en", "jp", "fr", "en_CA"). The default error string is
what is displayed in the case of not being able to connect to the server.
Public Types
• enum EStatus { eSuccess, ePending, eError }
• enum EProperty { eLanguage, ePlayerName, eGameMode }
• enum EMedalType { eMedalType_Game, eMedalType_Mode }
• enum EUserScore { eLocalEligible, eGlobalBest }
• enum ESubmitMode { kSubmitScore, kSubmitMedal, kSubmitAll }
Playground 4.0.17.1
326 Class and File Reference
enum TPfHiscores::EProperty
The various properties that can be set for the hiscore module.
enum TPfHiscores::EMedalType
The various medal types for use in KeepMedal() (p. 328)
Enumerator:
eMedalType_Game Medals that are awarded for the entire game, regardless of what mode
the user is in.
eMedalType_Mode Medals that are awarded per game mode (the user can earn this medal
once in each game mode).
enum TPfHiscores::EUserScore
The various modes for calling GetUserBestScore() (p. 331)
enum TPfHiscores::ESubmitMode
Submit modes
Controls what type of data is submitted
Enumerator:
kSubmitScore Submit the user’s best score to the server.
kSubmitMedal Submit the user’s medals to the server.
kSubmitAll Submit all available data to the server. It is recommended that this mode be used
whenever the UI permits - that way all of the user’s data is submitted with one call.
TPfHiscores::∼TPfHiscores ()
Default destructor
Playground 4.0.17.1
328 Class and File Reference
Returns:
- if the user/pass have been saved, this returns true and fills in the user/pass. if it has not
been saved, it returns false and does nothing to username and password.
If the user/pass have been saved, this returns tru and fills in the user/pass. If it has not been
saved, it returns false and does nothing to the username and password.
void TPfHiscores::RequestCategoryInformation ()
Submit a request to the server to retreive category information.
After calling this function, GetServerRequestStatus() (next page) must be polled until a result is
ready.
int32_t TPfHiscores::GetCategoryCount ()
Return the number of categories available for hiscores.
You must have retrieved the category information with RequestCategoryInformation() (this page)
first.
Returns:
Number of categories available.
Playground 4.0.17.1
330 Class and File Reference
bool TPfHiscores::GetScore (bool local, int32_t n, int32_t ∗ pRank, char ∗ name, uint32_t
bufSize, bool ∗ pAnonymous, int32_t ∗ pScore, char ∗ gameData, uint32_t gameDataBufferSize)
Fill in all the various score information for a given score.
To retrieve a server score, you must have retrieved the score information with RequestScores()
(this page) first.
Parameters:
local True for local high scores, false for global.
int TPfHiscores::GetNumMedalsToSubmit ()
Returns the number of medals that a user has earned but has not submitted to the server with
SubmitData() (next page).
This call does not return the total number of medals a user has earned, only the number of medals
that have not yet been submitted.
This result of this call is not dependent on the current game mode - it returns a total number of
medals across all game modes.
int TPfHiscores::GetNumMedalsEarned ()
Returns the number of medals that a user has earned, regardless of whether or not they have been
submitted.
This only reflects the number of medals that the user has earned according to locally saved data.
It does not fetch anything from the server.
Playground 4.0.17.1
332 Class and File Reference
This result of this call is not dependent on the current game mode - it returns a total number of
medals across all game modes.
The result from this call can be used to index into GetEarnedMedalInfo() (this page).
Returns stored medal info for the current user. Calling GetNumMedalsEarned() (previous page)
will let you know how many medals can be retrieved.
Parameters:
index Index of medal to be retrieved.
→ medalName Fills in the name of the medal (if medalName is not NULL).
→ type Fills in the type of the medal (if type is not NULL)
→ gameMode Fills in the gameMode that the medal was earned in (if gameMode is not
NULL).
→ gameData Fills in the gameData associated with the medal (if gameData is not NULL).
Returns:
Returns false if the passed in index is out of range. Otherwise returns true
Submit the current user’s best score and medals to the server.
After calling this, you should poll GetServerRequestStatus() (p. 330) to check for errors or suc-
cessful submission.
Only one call to SubmitData() (this page) can be made at a time. You can not issue a second
call until GetServerRequestStatus() (p. 330) has returned a result. Issuing a second call before
GetServerRequestStatus() (p. 330) returns a result may result in undefined behavior.
Medals will only be submitted if a password is used. If a password is not used, then medals will
be saved until the next time a password-enabled submission is made.
All of a user’s available medals are submitted - the types of medals are not filtered by the current
game mode.
Parameters:
username Name to submit the score under.
password The user’s playfirst password. If this is NULL or "", then an anonymous submis-
sion is issued.
bRemember If this is true, then the module saves the username and password for future use.
If it is false, it deletes any previously saved username and password.
submitMode What data to submit. When possible kSubmitAll should be used so that all user
data is submitted. However, in certain UI presentations, it may only be appropriate to
submit medals but not scores, or vice versa.
Returns:
If score submission is not possible, this returns false (i.e. the player has already submitted
their best score, or if they do not have any scores or medals for this game mode, etc.).
void TPfHiscores::ClearScores ()
Clear the local scores for the current game mode.
This will delete the current local scores for the current game mode. It cannot be undone.
uint32_t TPfHiscores::EncryptData (const void ∗ toEncrypt, uint32_t len, char ∗ buf, uint32_t
bufLen)
Encrypt a byte stream.
This will encrypt the passed in byte stream, and returns a string encoded in base64 (so it can be
passed around like a string).
Parameters:
toEncrypt The bytestream that is to be encrypted.
len The length of data to encrypt - note that if you are encrypting a text string you will want
to encrypt the null terminator too, so you should pass in strlen(toEncrypt) + 1.
→ buf The buffer to fill in with the encrypted string.
bufLen The size of the buffer. If this is too small, the function will return the size needed to
encrypt the string, and will not fill in buf at all.
Returns:
0 on success, or else returns the length of the buffer needed to encrypt this string.
void TPfHiscores::LogScore (int32_t score, bool replaceExisting, const char ∗ gameData, const
char ∗ serverData = NULL)
Deprecated
This function has been replaced by KeepScore() (p. 328). Please use that instead.
Playground 4.0.17.1
334 Class and File Reference
This function has been replaced by SubmitData() (p. 332). Please use that instead.
their best score, or if they do not have any scores for this game mode, etc.).
bool TPfHiscores::SubmitMedals (const char ∗ medalsData, str username, str password, bool
bRemember)
Deprecated
This function has been replaced by SubmitData() (p. 332). Please use that instead.
Medals are awards given to users that complete certain tasks in the game. A medal has two pa-
rameters. The "name" parameter is the identification name of the medal. The "per" parameter can
either be "type" or "game" - "type" means that this medal is specific to the current game mode,
whereas "game" means that this medal is a global medal awarded across all game modes.
Examples:
Playground 4.0.17.1
336 Class and File Reference
Configuration values
Use these values in GetConfig() to get the related setting, or with SetConfig() to change the related
setting (for writable values).
See also:
TPlatform::GetConfig (p. 339)
TPlatform::SetConfig (p. 340)
System Commands
Commands that interact with the operating system.
Playground 4.0.17.1
338 Class and File Reference
• uint32_t Timer ()
• void Sleep (uint32_t ms)
• bool OrphanTask (TTask ∗task)
• void AdoptTask (TTask ∗task)
Randomness
/∗∗ Return a random integer. Clients are encouraged to use this as opposed to the stdlib version
for maximum compatibility, and this random number generator is randomly seeded at application
startup.
Returns:
A random integer from 0 to 0xFFFFFFFF.
• uint32_t Rand ()
Public Types
enum TPlatform::ECursorMode
These mouse button constants are here to allow you to respond to the use of other mouse buttons.
PlayFirst game design constraints forbid the use of any other than the left mouse button as a
"necessary" part of the user interface. In other words, any other buttons on the mouse or mouse
wheel needs to be a supplemental interface for convenience of power users.
During normal game operation, it can be assumed that TPlatform (p. 336) always exists.
Playground 4.0.17.1
340 Class and File Reference
TTaskList∗ TPlatform::GetTaskList ()
Get the application task list.
Returns:
The TTaskList (p. 431) that holds the system’s tasks.
str TPlatform::StringFromClipboard ()
Retrieve a string, if any, from the current clipboard.
Returns:
A string representation of the current copy buffer.
Playground 4.0.17.1
342 Class and File Reference
You should always supply both a software cursor and a hardware cursor if you want a custom
cursor to be available.
Parameters:
hotSpot Point within texture that the hot spot should be (i.e., the point where the clicking
happens).
hardware True to set the hardware cursor, false to set the software cursor.
This API doesn’t quite work as expected on the Mac, and so will be removed from a fu-
ture version of Playground. To achieve relative cursor functionality, please use SetCursor-
Mode(TPlatform::kCursorModeDelta) instead.
Parameters:
at Position to set mouse cursor, in application window coordinates.
bool TPlatform::IsForeground ()
Return true if the application is currently the foreground window.
Returns:
True if application is in the foreground.
void TPlatform::SetForeground ()
Set the game window to the foreground. On some systems, this is more of a request than an action,
but it will get the user’s attention.
Playground 4.0.17.1
344 Class and File Reference
Returns:
True on success.
bool TPlatform::IsFullscreen ()
True if the window is full screen.
Returns:
True on full screen.
uint32_t TPlatform::Timer ()
A count in milliseconds since the program has initialized,
Returns:
Time value in milliseconds.
Playground 4.0.17.1
346 Class and File Reference
See also:
PlaygroundInit (p. 544)
Playground 4.0.17.1
348 Class and File Reference
skip frames when the time to compute core logic and render a frame takes slightly longer than one
video frame to calculate.
For instance, if the game takes 1/60 of a second (16.66ms) to perform all calculations and finish
rendering, but the monitor is set to a 70Hz update, setting this flag will cause the screen to update
at only 35FPS (half of 70FPS), since by the time one frame is complete, it will have already missed
the next video synchronization. As a result, the game will need to wait for the following frame
vertical refresh to draw. If you can only draw once every two frames at 70Hz, you’ll get a 35Hz
(35FPS) update.
Set the value to "1" to enable, or "0" to disable this feature. Defaults to being disabled.
• When enabled, OnChar() will only be called for low-ASCII characters, and only if no
OnUTF8Char() has already handled the character.
Warning:
This mode has not yet been approved for use in PlayFirst-developed games.
Must be enabled in PlaygroundInit() (p. 544) section.
Playground 4.0.17.1
350 Class and File Reference
• TPoint ()
• TPoint (int32_t x, int32_t y)
• bool operator== (const TPoint &point) const
• bool operator!= (const TPoint &point) const
• TPoint & operator+= (const TPoint &point)
• TPoint operator+ (const TPoint &point) const
• TPoint & operator-= (const TPoint &point)
• TPoint operator- (const TPoint &point) const
• TPoint operator- ()
Public Attributes
• int32_t x
• int32_t y
TPoint TPoint::operator- ()
Negation.
int32_t TPoint::y
Vertical coordinate.
Referenced by TRect::Contains(), operator+=(), operator-=(), and operator==().
Playground 4.0.17.1
352 Class and File Reference
Be sure to save the game periodically during play. Any time the user has, e.g., gained a new
level, or any other significant event the game should remember, you should tell it to write a
save file. The reason is that, when your game is wrapped in DRM, when the DRM expires it
will often directly send a kQuit message, which terminates the (default) game loop.
If there are performance reasons you don’t want to write the file frequently, you can use the
option in SetInt() (next page) and SetStr() (p. 355) to NOT write the file immediately; as long
as the setting has been given to TPrefs (opposite), it will be written on game exit.
Selecting a Specific Configuration
In order to prevent games from being downloaded multiple times and being able to use the same
saved games, a TPrefs (opposite) object attempts to distinguish between unique installs of the
game. It does this by looking at the directory the game is running from.
Therefore, for debugging purposes, if you want your game to always be treated as the same install,
you can hand create an install.txt file in the assets folder. This file can do two things:
1) If the file is empty, TPrefs (opposite) will load/save preferences as if it was running from the
most recently created preferences location (or create a new location if one doesn’t exist).
2) If the file is not empty, it will treat the contents of this file as the install path, and read/save
games as if it was that install. (example: putting C:/game/mygame in the install.txt file will make
the TPrefs (opposite) object pretend the game is running from c:/game/mygame
Parameters:
saveData Whether or not data should be saved between sessions, default is true. For exam-
ple, in a web game you might not want scores to persist between sessions, in which case
saveData should be false.
TPrefs::∼TPrefs ()
Destructor
uint32_t TPrefs::GetNumUsers ()
Get the number of users. Users must be numbered sequentially, and there may not be more than
1023 users.
Returns:
The number of currently created users in the preferences.
Playground 4.0.17.1
354 Class and File Reference
Parameters:
userNum Which user to delete
void TPrefs::SetInt (str prefName, int32_t value, int32_t userIndex = kGlobalIndex, bool save
= true)
void TPrefs::SetStr (str prefName, str value, int32_t userIndex = kGlobalIndex, bool save =
true)
Sets a str (p. 161) in the preferences.
String length is limited to 4Mb-16 bytes.
Parameters:
prefName Name of preference to set.
value Value to set preference to.
userIndex Which user to set, or if this is kGlobalIndex then set a global preference. Users must
be numbered sequentially, and there may not be more than 1023 users.
save If this is true, commits preferences to disk. if false, preferences are changed in memory
only, until a different preference is set with save set to true, or until SavePrefs() (next
page) is called.
int32_t TPrefs::GetBinary (str prefName, void ∗ buffer, uint32_t bufferLen, int32_t userIndex =
kGlobalIndex)
Gets a binary block from the preferences.
Parameters:
prefName Name of preference to get.
buffer Address of location to store data in.
bufferLen Size of buffer in bytes.
userIndex Which user to get from, or if this is kGlobalIndex then get from the global pref-
erences. Users must be numbered sequentially, and there may not be more than 1023
users.
Returns:
If the preference does not exist, -1 is returned. If buffer is successfully filled in with the pref-
erence, 0 is returned. If the preference exists and buffer is NULL or bufferLen is too small to
store the data, then the size that the buffer needs to be is returned.
void TPrefs::SetBinary (str prefName, const void ∗ data, uint32_t dataLength, int32_t
userIndex = kGlobalIndex, bool save = true)
Sets a block of binary data in the preferences.
Binary data size is limited to 4Mb-16 bytes.
Parameters:
prefName Name of preference to set.
data Address of data to set in preferences.
dataLength Size of data in bytes.
userIndex Which user to set, or if this is kGlobalIndex then set a global preference. Users must
be numbered sequentially, and there may not be more than 1023 users.
save If this is true, commits preferences to disk. If false, preferences are changed in memory
only, until a different preference is set with save set to true, or until SavePrefs() (next
page) is called.
Playground 4.0.17.1
356 Class and File Reference
void TPrefs::SavePrefs ()
Commit preferences to permanent storage.
Playground 4.0.17.1
358 Class and File Reference
Parameters:
saveData Whether or not data should be saved between sessions, default is true. For exam-
ple, in a web game you might not want scores to persist between sessions, in which case
saveData should be false.
TPrefsDB::∼TPrefsDB ()
Destructor
void TPrefsDB::SetInt (str prefName, int32_t value, int32_t userIndex = kGlobalIndex, bool
save = true)
Sets an int in the preferences.
Parameters:
prefName Name of preference to set.
value Value to set preference to.
userIndex Which user to set, or if this is kGlobalIndex then set a global preference. Users must
be numbered sequentially, and there may not be more than 1023 users.
save If this is true, commits preferences to disk. if false, preferences are changed in memory
only, until a different preference is set with save set to true, or until SavePrefsdb() is
called.
void TPrefsDB::SetStr (str prefName, str value, int32_t userIndex = kGlobalIndex, bool save =
true)
Sets a str (p. 161) in the preferences.
String length is limited to 4Mb-16 bytes.
Parameters:
prefName Name of preference to set.
value Value to set preference to.
userIndex Which user to set, or if this is kGlobalIndex then set a global preference. Users must
be numbered sequentially, and there may not be more than 1023 users.
save If this is true, commits preferences to disk. if false, preferences are changed in memory
only, until a different preference is set with save set to true, or until SavePrefsdb() is
called.
int32_t TPrefsDB::GetBinary (str prefName, void ∗ buffer, uint32_t bufferLen, int32_t userIndex
= kGlobalIndex)
Gets a binary block from the preferences.
Parameters:
prefName Name of preference to get.
buffer Address of location to store data in.
bufferLen Size of buffer in bytes.
Playground 4.0.17.1
360 Class and File Reference
userIndex Which user to get from, or if this is kGlobalIndex then get from the global pref-
erences. Users must be numbered sequentially, and there may not be more than 1023
users.
Returns:
If the preference does not exist, -1 is returned. If buffer is successfully filled in with the pref-
erence, 0 is returned. If the preference exists and buffer is NULL or bufferLen is too small to
store the data, then the size that the buffer needs to be is returned.
void TPrefsDB::SetBinary (str prefName, const void ∗ data, uint32_t dataLength, int32_t
userIndex = kGlobalIndex, bool save = true)
Sets a block of binary data in the preferences.
Binary data size is limited to 4Mb-16 bytes.
Parameters:
prefName Name of preference to set.
data Address of data to set in preferences.
dataLength Size of data in bytes.
userIndex Which user to set, or if this is kGlobalIndex then set a global preference. Users must
be numbered sequentially, and there may not be more than 1023 users.
save If this is true, commits preferences to disk. If false, preferences are changed in memory
only, until a different preference is set with save set to true, or until SavePrefsdb() is
called.
void TPrefsDB::SavePrefs ()
Commit preferences to permanent storage.
Playground 4.0.17.1
362 Class and File Reference
TReal TRandom::RandFloat ()
Generates a random number on [0,1)-real-interval
Returns:
A number between zero and one, never equalling 1.0
double TRandom::RandDouble ()
Generates a random number on [0,1)-real-interval, that is random out to double-precision granu-
larity. Since a double has (on the Wintel reference platform) more bits of precision than an int/long,
it takes two calls from Rand32 and combines them into a double precision random number.
Returns:
A number between zero and one, never equalling 1.0
Parameters:
bottom Lowest number that will be returned.
top Highest number that will be returned.
Returns:
A random integer.
Playground 4.0.17.1
364 Class and File Reference
TRect
TURect
Public Attributes
• int32_t x1
• int32_t y1
• int32_t x2
• int32_t y2
Playground 4.0.17.1
366 Class and File Reference
Referenced by TTextGraphic::Draw().
This function is going to be deleted in favor of the more clearly named TRect::Contains()
(opposite).
Parameters:
p Point to test.
Returns:
True if inside. If p.x==x2 or p.y==y2, the test fails.
void TRect::Union (const TRect & rect1, const TRect & rect2)
Make this rectangle the union of the two parameter rectangles. Can pass this rectangle as either
parameter.
Parameters:
rect1 First
Playground 4.0.17.1
368 Class and File Reference
rect2 Second
void TRect::Intersect (const TRect & rect1, const TRect & rect2)
Make this rectangle the intersection of the two parameter rectangles. Can pass this rectangle as
either parameter.
Warning:
Assumes the two rectangles overlap. Resulting value is undefined if the original rectangles
do not overlap.
Parameters:
rect1 First
rect2 Second
TPoint& TRect::GetTopLeft ()
Get a TPoint (p. 350) that represents the upper left corner of the rectangle.
Returns:
Corner point
TPoint& TRect::GetBottomRight ()
Get a TPoint (p. 350) that represents the lower right corner of the rectangle.
Returns:
Corner point
int32_t TRect::y1
Upper left corner y coordinate.
Referenced by Contains(), TTextGraphic::Draw(), operator==(), and Overlaps().
int32_t TRect::x2
Lower right corner x coordinate.
Referenced by Contains(), operator==(), and Overlaps().
int32_t TRect::y2
Lower right corner y coordinate.
Referenced by Contains(), operator==(), and Overlaps().
Playground 4.0.17.1
370 Class and File Reference
3d-Related functions
• enum ECullMode { kCullNone, kCullCW, kCullCCW }
• void SetWorldMatrix (TMat4 ∗pMatrix)
• void SetViewMatrix (TMat4 ∗pMatrix)
• void SetProjectionMatrix (TMat4 ∗pMatrix)
• void SetView (const TVec3 &eye, const TVec3 &at, const TVec3 &up)
• void SetPerspectiveProjection (TReal nearPlane, TReal farPlane, TReal fov=PI/4.0f, TReal
aspect=0)
• void SetOrthogonalProjection (TReal nearPlane, TReal farPlane)
• void GetWorldMatrix (TMat4 ∗m)
• void GetViewMatrix (TMat4 ∗m)
• void GetProjectionMatrix (TMat4 ∗m)
• void SetAmbientColor (const TColor &color)
• void SetCullMode (ECullMode cullMode)
• void SetMaterial (TMaterial ∗mat)
• void SetLight (uint32_t index, TLight ∗light)
• bool ToggleHUD ()
Playground 4.0.17.1
372 Class and File Reference
Information
• str GetSystemData ()
• bool GetTextureSquareFlag ()
2d-Related Functions
• void FillRect (const TURect &rect, const TColor &color, TTextureRef dst=TTextureRef())
• bool IsCapturePending ()
• void SetCaptureTexture (TTextureRef texture)
• TTextureRef GetCaptureTexture ()
enum TRenderer::EShadeMode
Shading modes.
See also:
TRenderer::SetShadeMode (p. 376)
Enumerator:
kShadeFlat Flat shading with no shading across a polygon.
kShadeGouraud Gouraud shading with smooth shading across a polygon.
enum TRenderer::EBlendMode
Blending modes for SetBlendMode() (p. 377)
Enumerator:
kBlendNormal Normal alpha drawing.
kBlendOpaque Draw with no alpha. This mode requires your texture to be square and each
side be a power of two in order to work consistently.
kBlendAdditiveAlpha Additive drawing, respecting source alpha. Useful for "glowing" ef-
fects.
kBlendSubtractive Subtractive drawing; useful for shadows or special effects.
kBlendMultiplicative Multiplicative drawing; can also be used for shadows or special ef-
fects.
kBlendINVALID Invalid blend mode.
enum TRenderer::EFilteringMode
Filtering modes.
See also:
SetFilteringMode (p. 377)
Enumerator:
kFilterPoint Point-filtering: Select the nearest pixel.
kFilterLinear Bilinear (or trilinear for MIPMAPs) filtering: Blend the nearest pixels.
enum TRenderer::ETextureMapMode
The various texture map modes.
See also:
TRenderer::SetTextureMapMode() (p. 377)
Playground 4.0.17.1
374 Class and File Reference
Enumerator:
kMapClamp Clamp the texture to 0,1.
kMapWrap Repeat texture coordinates. Uses the fractional part of the texture coordinates
only. Do not expect wrap to work with arbitrarily large numbers, as some video cards
limit wrapping to as little as ±4.
kMapMirror Mirror coordinate: 0->1->0->1.
enum TRenderer::ERenderTargetMode
Modes for TRenderer::BeginRenderTarget (p. 379).
Enumerator:
kFullRenderRGB1 Render RGB with an opaque alpha. Does not preserve the current texture
contents.
kFullRenderRGBX Render RGB with an undefined alpha. Does not preserve the current
texture contents. Alpha contents are undefined.
kMergeRenderRGB1 Render RGB with an opaque alpha, preserving the current texture con-
tents; entire final surface (not just areas that are overdrawn) will get an opaque alpha.
Note that this call is actually slower than kFullRenderRGB1, since the existing texture
data needs to be copied to the render surface.
kMergeRenderRGBX Render RGB with an opaque alpha, preserving the current texture con-
tents; final surface alpha is unchanged. Note that this call is actually slower than kFull-
RenderRGBX, since the existing texture data needs to be copied to the render surface.
kMergeRenderXXXA Render Alpha without modifying RGB pixels. RGB of original image
will be preserved.
enum TRenderer::ECullMode
Possible cull modes.
Enumerator:
kCullNone No culling.
kCullCW Cull faces with clockwise vertices.
kCullCCW Cull faces with counterclockwise vertices.
TRenderer::∼TRenderer ()
Destructor
TRect TRenderer::GetClippingRectangle ()
Get the current screen clipping rectangle.
void TRenderer::PopClippingRectangle ()
Pop a clipping rectangle from the internal stack.
Playground 4.0.17.1
376 Class and File Reference
void TRenderer::PopViewport ()
Restore a viewport from the viewport stack.
bool TRenderer::RenderTargetIsScreen ()
Query as to whether the current render target is the screen.
TTextureRef TRenderer::GetTexture ()
Get the currently assigned texture.
Returns:
The current texture.
Playground 4.0.17.1
378 Class and File Reference
bool TRenderer::GetColorWrite ()
Get the current "color write" state.
Returns:
True if color writing is enabled.
See also:
SetColorWrite (this page)
void TRenderer::ClearZBuffer ()
Clear the ZBuffer. Done automatically by BeginDraw() (p. 380) and BeginRenderTarget() (oppo-
site).
bool TRenderer::GetZBufferWrite ()
Query ZBuffer-write state.
Returns:
True if ZBuffer writing is enabled; false otherwise.
See also:
SetZBufferWrite (previous page)
bool TRenderer::GetZBufferTest ()
Query ZBuffer-test state.
Returns:
True if ZBuffer testing is enabled; false otherwise.
See also:
SetZBufferTest (previous page)
str TRenderer::GetSystemData ()
Get data about the current system.
Returns:
A system data string.
bool TRenderer::GetTextureSquareFlag ()
Query whether textures on this computer will be created as square internally. You can always
create textures of any shape, but internally a texture may be extended to the next power-of-two,
square size that will fit your requested texture size.
Note that texture dimensions will be rounded up to the next power-of-two on cards that require
it; always query TTexture::GetInternalSize() (p. 469) if the exact texture dimensions are relevant.
Returns:
True if textures will always be square, internally.
if (r->BeginRenderTarget(myTexture,TRenderer::kMergeRenderXXXA))
{
DoRendering(); // Paint the full texture again, this time
r->EndRenderTarget(); // to get alpha information
}
Warning:
Will not render to areas of a surface beyond the extents of the screen surface (800x600 by
default). This allows us to use the most compatible render-to-surface modes.
Playground 4.0.17.1
380 Class and File Reference
Additionally, by using the most compatible modes, this is not a fast operation. It is best used to
pre-render an image that will be used multiple times rather than attempting to execute it every
frame.
Parameters:
texture Texture to render to.
mode Render target mode.
Returns:
True on success.
void TRenderer::EndRenderTarget ()
Complete the rendering to a texture.
See also:
BeginRenderTarget (previous page)
bool TRenderer::Begin2d ()
Begin 2d rendering. Any calls to TTexture::Draw∗() functions should happen between a Begin2d()
(this page) and End2d() (opposite) call.
It’s a good idea to minimize renderer state changes, as they can be expensive on some cards. Try
to group most of your 2d rendering together in as few Begin2d() (this page) groups as possible.
Clears all 3d matrices when called. You can set the view and world matrix between Begin2d() (this
page) and End2d() (opposite), but they will be cleared again on End2d() (opposite).
You can use the helper class TBegin2d (p. 200) to automatically close the block on exiting the
scope.
Returns:
True on success. False on failure, which can mean that you are already in a Begin2d() (op-
posite) state, you are in a Begin3d() (this page) state, or some other aspect of the engine has
gotten into a bad state. Check log file messages for details.
See also:
TBegin2d (p. 200)
Referenced by TBegin2d::TBegin2d().
void TRenderer::End2d ()
Finish a 2d rendering set.
See also:
Begin2d (opposite)
Referenced by TBegin2d::Done().
bool TRenderer::Begin3d ()
Begin 3d rendering. Any calls to TModel::Draw (p. 305)∗() functions should happen between a
Begin3d() (this page) and End3d() (this page) call. Also, calls to DrawVertices() (p. 376) with
vertex types TLitVert (p. 258) or TVert (p. 493) should be within a Begin3d() (this page) block.
It’s a good idea to minimize renderer state changes, as they can be expensive on some cards. Try
to group most of your 3d rendering together in as few Begin3d() (this page) groups as possible.
You can use the helper class TBegin3d (p. 201) to automatically close the block on exiting the
scope.
Returns:
True on success. False on failure, which can mean that you are already in a Begin3d() (this
page) state, you are in a Begin2d() (opposite) state, or some other aspect of the engine has
gotten into a bad state. Check log file messages for details.
See also:
TBegin3d (p. 201)
Referenced by TBegin3d::TBegin3d().
void TRenderer::End3d ()
Finish a 3d rendering set.
Playground 4.0.17.1
382 Class and File Reference
See also:
Begin3d (previous page)
Referenced by TBegin3d::Done().
void TRenderer::FillRect (const TURect & rect, const TColor & color, TTextureRef dst =
TTextureRef())
Fill a rectangle, optionally specifying a destination texture.
Unlike TTexture::Draw∗() calls, FillRect can be used to draw a rectangle in any texture type, and
does not depend on the Begin2d/End2d state. Will not blend using the alpha value; instead
it writes the alpha value as part of the color into the destination, when the destination texture
supports alpha.
In the case of screen fills, the alpha value is never used, since to draw an alpha value to the screen
is meaningless (the screen surface is never used as a source texture).
Parameters:
rect Rectangle to fill; this rectangle is either relative to the upper left corner of the current
viewport or window (when dst is NULL), or is relative to the upper left corner of the
texture.
color Color to draw–this color (RGBA) will be written verbatim into the surface across the
rectangle with no blending, such that all pixels in the rectangle will exactly equal the
RGBA color specified.
dst Optional destination texture. Current viewport and window coordinates are ignored
when dst is non-NULL.
bool TRenderer::IsCapturePending ()
Query as to whether the previously set capture texture is still waiting to be filled with the screen
render.
Returns:
True if the capture texture is still pending.
The capture texture MUST be exactly the size of the screen, or SetCaptureTexture() (opposite) will
silently fail (or ASSERT in debug builds).
Parameters:
texture Texture to fill.
TTextureRef TRenderer::GetCaptureTexture ()
Get the current capture texture from the renderer.
After a texture is filled, this function will return an empty texture.
Returns:
The texture that’s waiting to be filled with the results of a screen render. An empty TTextur-
eRef if SetCaptureTexture() (opposite) hasn’t been called, or after the texture has been filled.
Playground 4.0.17.1
384 Class and File Reference
Parameters:
pMatrix New projection matrix.
void TRenderer::SetView (const TVec3 & eye, const TVec3 & at, const TVec3 & up)
Set the view matrix based on the viewer location, a target location, and an up vector.
Parameters:
eye The viewer’s location.
at The target location.
up Up vector.
bool TRenderer::ToggleHUD ()
Toggle the HUD
Returns:
true if HUD was previously active.
Playground 4.0.17.1
386 Class and File Reference
Returns:
True if in Begin2d mode.
TWindow
TModalWindow
TScreen
Playground 4.0.17.1
388 Class and File Reference
Parameters:
neverClear True to never clear the background.
TColor TScreen::GetBackgroundColor ()
Get the current background color.
Returns:
The current background color.
TTask
TAnimTask
TScript
• toparams() will take a table as a parameter and return the indexed members as multiple
return values. You can use this to pass the members of a table to a vararg function, for
instance.
See also:
Lua Scripting (p. 47)
http://www.lua.org
Playground 4.0.17.1
390 Class and File Reference
Construction/Destruction
• TScript (lua_State ∗luaState=NULL)
• virtual ∼TScript ()
• lua_State ∗ GetState ()
• TColor PopColor ()
• class TFont PopFont ()
• str PopString ()
• TRect PopRect ()
• lua_Number PopNumber ()
• bool PopBool ()
Client Interface
Functions that are commonly used by a client.
TTask Overrides
Functions that handle TTask (p. 429) behavior.
virtual TScript::∼TScript ()
Destructor.
lua_State∗ TScript::GetState ()
Get the current Lua state.
TColor TScript::PopColor ()
Pop a TColor (p. 215) from the stack
Returns:
A TColor (p. 215) from the top of the Lua stack.
Playground 4.0.17.1
392 Class and File Reference
str TScript::PopString ()
Pop a string from the stack
Returns:
A string from the top of the Lua stack.
TRect TScript::PopRect ()
Pop a TRect (p. 364) off the top of the stack.
Returns:
A TRect (p. 364)
lua_Number TScript::PopNumber ()
Pop a number from the stack
Returns:
A number from the top of the Lua stack.
bool TScript::PopBool ()
Pop a boolean from the stack.
Returns:
A bool from the top of the Lua stack.
TScript∗ TScript::NewThread ()
Create a new TScript-derived class of the same type as this class, but running in a new Lua thread.
Lua threading is cooperative multithreading: It is non-preemptive, and as such requires that you
"yield" to pause processing.
Returns:
A TScript-derived class constructed with similar parameters as the host class.
Inject a function into a running Lua script. Default implementation is empty, but the TWindow-
Manager::GetScript() (p. 525) script has a derived implementation.
Attempts to inject the function on the top of the Lua stack into the current coroutine.
The Lua function can take parameters, but is assumed to not return any results.
Returns:
True on success, false on failure.
See also:
TScript::RunScript (opposite)
Playground 4.0.17.1
394 Class and File Reference
Playground 4.0.17.1
396 Class and File Reference
See Lua API documentation from http://www.lua.org for more information on lua_getglobal,
lua_pushnumber, and the rest of the internal Lua API.
Warning:
If you need more than one return value from your function, it cannot yield control, nor call
any function that yields control of the coroutine. A single return value is supported by the
current API.
15.55.4 Details
When Lua has paused a script using the "coroutine.yield" function or the C call lua_yield, it re-
mains in a suspended state until one calls lua_resume or coroutine.resume. In this state you can
actually still use the same interpreter to execute Lua functions, but those functions may not them-
selves yield, nor can a Lua function that was called via C resume the previous Lua coroutine.
To allow arbitrary function execution from C, the Playground Lua "message loop" takes an extra
parameter which is a function to call. In other words, whenever the Lua message loop has yielded
to wait for a message, you can pass it in a message and/or a command to execute. The TWin-
dowManager (p. 519) version of InjectFunction calls Resume with that command as a parameter,
and it’s executed as part of the main thread–so it can therefore enter its own wait loops, call other
script functions, etc. However, that function that’s passed in as a parameter can take no parame-
ters of its own; RunFunction uses a Playground Lua call GetClosure to wrap your function plus
any parameters in a Lua closure, and then passes that closure in to be executed.
In the case that a coroutine is not currently active, RunFunction does the trivial thing and calls
lua_pcall with the standard error handler.
Note that the base class implementation of InjectFunction does nothing, and it’s only the derived
window UI script that InjectFunction will work.
This is not to hide the implementation, but instead because the injection relies on how the Lua
script that yielded treats the return values of the yield statement. We can’t make any assumptions
about how your own custom scripts will process yield results; if you want to create your own
version of InjectFunction, derive from TScript (p. 389) and add your own implementation. As an
example:
This would assume that your Lua code interpreted the first return value from yield as a function,
and then ran the function:
f = yield(); Lua
if (f) then
f();
end
That way, the function is executed as part of your thread, rather than outside of it. If you need
multiple threads, see TScript::NewThread() (p. 393).
Parameters:
nargs Number of arguments.
nresults Number of results. If there’s a chance your function will be executed during a paused
coroutine, and your function needs to be able to yield, then this number should be zero
or one.
Returns:
0 on success. Lua error code otherwise.
Playground 4.0.17.1
398 Class and File Reference
TAsset
TScriptCode
• str GetCode ()
• uint32_t GetCodeLength ()
static TScriptCodeRef TScriptCode::Get (str handle, str luaPath = "", str ∗ error = NULL)
Accessor function for Lua script-code asset.
Internally, when loading a Lua script from a file, the internal routines use TScriptCode::Get()
(this page) to load it. If you keep a reference to the TScriptCode (this page), then when the routine
calls TScriptCode::Get() (this page), it will retrieve the cached (and precompiled) copy rather than
reloading it from disk.
Parameters:
handle File handle to load.
luaPath Any additional Lua search path necessary.
error An optional str (p. 161) that gets set with an error string.
Returns:
A reference to the compiled code object.
str TScriptCode::GetCode ()
Get the (compiled) script code.
Returns:
A pre-compiled Lua block. Can have embedded null characters; use TScript-
Code::GetCodeLength() (this page) to determine the length.
uint32_t TScriptCode::GetCodeLength ()
Get the length of the compiled code block.
Returns:
Code block length.
Playground 4.0.17.1
400 Class and File Reference
Public Types
• TSimpleHttp ()
• virtual ∼TSimpleHttp ()
• void Init (const char ∗url, bool bPost=false, const char ∗path=NULL)
• void AddArg (const char ∗name, const char ∗value)
• void AddArg (const char ∗name, int32_t value)
• void DoRequest (int32_t flags)
• EStatus GetStatus ()
• unsigned long GetContentLengthHeader ()
• unsigned long GetBytesReceived ()
• char ∗ GetContents ()
enum TSimpleHttp::EStatus
Status enumeration.
Enumerator:
eNetWait Waiting for a reply.
eNetDone Reply complete and successful.
eNetError Error communicating with server.
eFileError Error writing file.
virtual TSimpleHttp::∼TSimpleHttp ()
Destruction.
Playground 4.0.17.1
402 Class and File Reference
EStatus TSimpleHttp::GetStatus ()
Get the current status.
Returns:
The status.
char∗ TSimpleHttp::GetContents ()
Get the content of the reply.
Available only if downloading to memory: Will fail until status is eNetDone.
Playground 4.0.17.1
404 Class and File Reference
TWindow
TSlider
Public Types
• enum ESliderState { eIdle, eMoving }
Playground 4.0.17.1
406 Class and File Reference
Parameters:
top Top of the slider.
mid Middle of the slider. This one gets stretched out to make the slider the right height or
width.
bot Bottom of the slider.
TReal TSlider::GetValue ()
Get the current slider handle position.
Returns:
The position as a value from 0 to 1.
TReal TSlider::GetScale ()
Get the current slider scale.
Returns:
Slider scale.
Parameters:
alpha Alpha of the slider.
TReal TSlider::GetAlpha ()
Get the current slider alpha.
Returns:
The slider alpha.
Playground 4.0.17.1
408 Class and File Reference
ESliderState TSlider::GetState ()
Get the current slider state (whether it’s moving or idle).
Returns:
The state of the slider.
TAsset
TSound
// In PlaygroundInit()
TSpeex::Register();
This will cause TSound::Get() (next page) to handle .spx files correctly. Speex files only support
streamed playback, and do not support seeking to an arbitrary offset. You can, however, pause,
resume, and reset a Speex sound to the beginning, and you can loop a Speex sound.
Factory Methods
• static TSoundRef Get (str filename, bool bInMemory=true, int32_t type=-1)
Public Types
• enum { kButtonSound, kUserSoundBase }
Playground 4.0.17.1
410 Class and File Reference
• bool Kill ()
• TReal GetSoundLength ()
• TSoundRef GetRef ()
• str GetName ()
Friends
• class TSoundInstance
Returns:
true on success, false on failure
bool TSound::Kill ()
Kill all instances of this sound - once a sound is killed it must be restarted with Play() (opposite),
it cannot be unpaused.
If a sound is set as a "continuation" of a sound that is killed, it will also be killed, even if it hasn’t
started yet.
Returns:
true if any sounds were killed, false otherwise.
TReal TSound::GetSoundLength ()
Get the length of the sound in seconds.
Returns:
Number of seconds.
TSoundRef TSound::GetRef ()
Get a reference to this sound.
Returns:
A reference to this.
str TSound::GetName ()
Get the file handle used to create the sound.
Returns:
The sound file handle.
Playground 4.0.17.1
412 Class and File Reference
Friends
• class TSound
• class TSoundData
virtual TSoundCallBack::∼TSoundCallBack ()
Destructor.
Friends
• class TSound
• class TSoundData
• class TSoundStream
Playground 4.0.17.1
414 Class and File Reference
void TSoundInstance::Kill ()
Kill the sound instance. Sound instances normally live until they complete or until they are killed.
Simply releasing the TSoundInstanceRef will not itself kill a sound.
int TSoundInstance::GetGroupId ()
Get the group this stream belongs to.
Returns:
The current group id.
Warning:
When queueing up sounds with the next parameter, the sound must be of the same number
of channels (i.e. mono or stereo).
If you queue up a sound with a different number of channels, an ASSERT will trigger in a debug
build. In a release build, the resulting sound will likely be incorrect.
Parameters:
pCallback Pointer to callback object that will be called when the sound is done. This param-
eter can be NULL if the client just wants to setup a playNext sound.
playNext - what sound to play after the current sound finishes. Default is a NULL
TSoundRef() (p. 548). (See note above about playNext restrictions)
TSoundRef TSoundInstance::GetSound ()
Get a reference to the original sound that spawned this instance.
Returns:
A sound reference, or NULL if the sound has been deleted.
TSoundRef TSoundInstance::GetNextSound ()
Get a reference to the next sound to be streamed after the current one completes.
Playground 4.0.17.1
416 Class and File Reference
Friends
• class TSoundStream
• class TLockSoundMutex
Playground 4.0.17.1
418 Class and File Reference
TSprite
TAnimatedSprite TTextSprite
A TSprite (this page) is always stored in the client as a TSpriteRef—it’s a reference counted
object. To destroy a TSprite (this page), simply call reset() on the last TSpriteRef that refers to
that sprite.
It’s worth noting that a TSprite (this page) holds a reference to any of its children, so you don’t
need to worry about keeping an external reference to a child sprite that can be passively attached
to an object. An example of this usage would be a shadow that stays at a constant offset from the
parent sprite. To make the shadow appear behind the parent you can give it a negative "layer"
when you create it.
Design Concerns
Because it’s convenient, many people tend to want to use TSprite (this page) as a game object.
It’s not designed that way, however, and you’ll quickly run into limitations if you try. For
instance, there’s no way to enumerate children of a TSprite (this page). There’s also no way
to name a TSprite (this page), and then look up a child by name.
This is intentional. TSprite (this page) was designed as a very light class, and adding strings and
the ability to iterate would weigh it down.
Another option you might consider is deriving your own class from TSprite (this page). It has been
requested by developers so often, that it’s used as an example in the docs. I’ve come to believe that
creating a game object that way is categorically a bad idea. As Playground has grown, new child
classes of TSprite (this page) have been created, so if you derive a game object from TSprite (this
page), you won’t be able to have a game object that is, say, a TFxSprite or a TTextSprite (p. 454).
Aside from that, a TSprite (this page) really is all about rendering a TTexture (p. 463), and mixing
game code with your rendering code is poor design when it can be avoided.
If your game objects exist in their own hierarchy, however, and they just own a reference to the
TSprite (this page) that represents them in the game, then your game objects can be represented
by whatever TSprite-derived object we (or you) devise, and the design of your game will now be
Playground 4.0.17.1
420 Class and File Reference
cleaner, since the details of the rendering of your game objects will be properly encapsulated in its
own class and not mixed willy-nilly in the game object behavior classes.
So that’s why you should create your own hierarchy of game objects distinct from the TSprite (pre-
vious page) hierarchy. Having two parallel hierarchies is not ideal, but weighing down TSprite
(previous page) with the plumbing required to promote it to a full-fledged game object is even less
desirable.
How Sprites are Drawn
A TSprite (previous page) has a concept of a layer which indicates how it will be rendered
relative to its siblings. For the top sprite in a hierarchy (the one you’re calling Draw on your-
self), the layer parameter is meaningless—it only applies to sprites with siblings or a parent.
The layer determines the relative order of drawing of a sprite with its siblings and parent.
• When siblings have the same layer, they will render in an arbitrary order—it is assumed not
to matter what order they’re in.
• When siblings have different layers, the higher layered siblings will be rendered above the
lower layered siblings.
• When a child sprite has a negative layer, it will be rendered behind its parent; otherwise it
will be rendered in front of its parent.
Changing the layer of a sprite requires that the parent’s child list be resorted. In other words, it’s
a relatively heavy operation if there are a lot of siblings, so try not to do it frequently.
See also:
TAnimatedSprite (p. 175)
Initialization/Destruction
• static TSpriteRef Create (int32_t layer=0, TTextureRef texture=TTextureRef())
• virtual ∼TSprite ()
Public Types
Protected Attributes
• SpriteList mChildren
Friends
• class TSpriteManager
• bool operator< (TSpriteRef first, TSpriteRef second)
Playground 4.0.17.1
422 Class and File Reference
virtual TSprite::∼TSprite ()
Destructor.
Defaults to a default-constructed TDrawSpec (p. 223). See TDrawSpec (p. 223) for more details
on what is inherited.
Parameters:
depth How many generations of children to draw; -1 means all children.
See also:
TDrawSpec (p. 223)
int32_t TSprite::GetLayer ()
Get the current sprite layer.
void TSprite::RemoveChildren ()
Release all children of the sprite.
Playground 4.0.17.1
424 Class and File Reference
virtual TRect TSprite::GetRect (const TDrawSpec & parentContext, int32_t depth = -1)
virtual bool TSprite::HitTest (const TPoint & at, const TDrawSpec & parentContext, int32_t
opacity = -1, int32_t depth = -1)
Test to see if a point is within our sprite. Will test children as well, unless depth is set to zero.
By default will not test children unless the TPlatform (p. 336) setting TPlat-
form::kSpriteAlwaysTestChildren (p. 349) is enabled with TPlatform::SetConfig() (p. 340).
Parameters:
at Point to test.
parentContext The parent context to test within—where is this sprite being drawn, and with
what matrix? Alpha and color information is ignored.
opacity Level of opacity to test for; -1 for a simple bounding box test, or 0-255 for alpha color
value, where 0 is transparent (and will therefore always succeed).
depth Depth of children to test. Zero means only test this sprite. -1 means recurse children as
deep as they go.
Returns:
true if point hits us.
TTextureRef TSprite::GetTexture ()
Get the current texture.
Returns:
A reference to the current texture.
TDrawSpec& TSprite::GetDrawSpec ()
Get the associated TDrawSpec (p. 223).
Returns:
A modifiable reference to the TDrawSpec (p. 223) associated with this sprite.
bool TSprite::IsVisible ()
Is the sprite visible/enabled?
Returns:
True if it’s enabled.
TSprite∗ TSprite::GetParent ()
Get the current parent of this sprite.
Returns:
A pointer to the current parent, or NULL if this sprite is free.
Playground 4.0.17.1
426 Class and File Reference
Playground 4.0.17.1
428 Class and File Reference
TTask
TAnimTask
TScript
Public Types
• enum ETaskContext { eNormal, eOnDraw }
Playground 4.0.17.1
430 Class and File Reference
Public Types
• typedef std::list< TTask ∗ > TaskList
Playground 4.0.17.1
432 Class and File Reference
void TTaskList::DestroyAll ()
Destroy all the tasks in the list.
TWindow
TText
TTextEdit
Public Types
• enum EFlags { kHAlignLeft, kHAlignCenter, kHAlignRight, kVAlignTop, kVAlignCen-
ter, kVAlignBottom }
Playground 4.0.17.1
434 Class and File Reference
TText::∼TText ()
Destructor.
Parameters:
text Initial text for window.
w Width of client rectangle.
h Height of client rectangle.
flags Flags from TText::EFlags (opposite)
fontFilename Font name.
lineHeight Font size.
textColor Font color.
Returns:
True on success.
uint32_t TText::GetLineCount ()
Get the number of lines in the text output.
Returns:
Number of lines.
Playground 4.0.17.1
436 Class and File Reference
TTextGraphic∗ TText::GetTextGraphic ()
Get the associated TTextGraphic (p. 447) object.
Returns:
The TTextGraphic (p. 447) that draws this window’s text.
Used to detect clicks on embedded text links. Returns false if no text link was previously clicked
on.
Parameters:
point Location of mouse release in client coordinates.
Returns:
true if message was handled, false to keep searching for a handler.
This message is only sent if TWindowManager::AddMouseListener() (p. 524) has been called
for this window previously.
Returns:
True if handled.
Playground 4.0.17.1
438 Class and File Reference
uint32_t TText::GetMaxScroll ()
Get the maximum line you need to scroll the text to in order to display the last line of text.
Returns:
The highest integer you need to set the top line to.
Playground 4.0.17.1
440 Class and File Reference
TWindow
TText
TTextEdit
Once this class finds an ancestor modal window, it will register itself with the modal and link
itself to any other TTextEdit (this page) windows it finds under that modal window. If you
then remove it (or a parent) from the hierarchy without destroying it or calling Unregister()
(p. 444), the resulting behavior is undefined.
Public Types
• enum eKeyType { kKeyChar, kKeyMove, kKeyEnter, kKeyTab, kKeyPaste, kKeyIllegal }
Protected Attributes
• uint32_t mMaxLength
Friends
• class TextSpider
Playground 4.0.17.1
442 Class and File Reference
TTextEdit::TTextEdit ()
Default Constructor.
virtual TTextEdit::∼TTextEdit ()
Destructor.
See also:
Init (this page)
PostChildrenInit (p. 502)
Playground 4.0.17.1
444 Class and File Reference
See also:
TPlatform::kUTF8Mode (p. 348)
void TTextEdit::Unregister ()
Tell this TTextEdit (p. 440) that it should unlink itself from its parent modal window and any
related TTextEdit (p. 440) windows in its tab ring.
bool TTextEdit::GetEditable ()
Query as to whether this TTextEdit (p. 440) is currently editable.
Returns:
True if editable.
void TTextEdit::UpdateText ()
Update the text in the text field.
void TTextEdit::Backspace ()
Call this function to simulate pressing "Backspace" in the text field.
str TTextEdit::GetIgnoreChars ()
Get the characters this TTextEdit (p. 440) is ignoring.
Returns:
A string that contains the characters to ignore.
Playground 4.0.17.1
446 Class and File Reference
Parameters:
maxLength Maximum number of characters you can type.
• <p></p> Paragraph
• <b></b> Bold
• <i></i> Italic
• <u></u> Underline
• <center></center> Center
• <a id=’buttonname’></a> Trigger a button named ’buttonname’ when clicking this text.
Text can be rendered directly to screen. For text that is automatically rendered in a window, use
the TText (p. 433) class.
Use the static function TTextGraphic::Create (p. 449) to create a new instance of a TTextGraphic
(this page).
See also:
TText (p. 433)
Public Types
Playground 4.0.17.1
448 Class and File Reference
void TTextGraphic::Destroy ()
Call to destroy a TTextGraphic (p. 447). Deletes the object and releases all resources.
void TTextGraphic::Draw (const TRect & destRect, TReal scale = 1.0, int32_t linePadding = 0,
TReal alpha = 1.0, TTextureRef target = TTextureRef())
Draw the text to a rectangle on the screen.
Deprecated
This overload uses an older, more confusing, syntax, and doesn’t allow for sub-pixel place-
ment.
Playground 4.0.17.1
450 Class and File Reference
void TTextGraphic::Draw (const TVec2 & at, uint32_t height, TReal scale = 1.0, int32_t
linePadding = 0, TReal alpha = 1.0, TTextureRef target = TTextureRef())
Draw the text to the screen.
Must be called between a TRenderer::Begin2d (p. 380)/TRendererEnd2d pair.
Parameters:
at Location to draw the text.
height Height of text region in pixels. Used to determine how many lines of text to draw.
scale Scale factor - useful for zooming effects.
linePadding Additional spacing between text lines.
alpha Alpha multiplier. 1.0 is opaque.
target [optional] Target texture to draw to. Leave as default to draw to current context.
void TTextGraphic::SetNoBlend ()
When drawing to an offscreen texture, copy pixels to the texture, instead of alpha blending them.
Does not work with text outlines, since the text and outline need to be blended with each other.
The default state is to blend the pixels into the destination texture, leaving alpha alone. If you call
SetNoBlend() (this page), then pixels will be set directly to the colors and alpha values, so that the
texture can then be used blended with an arbitrary background. TTextGraphic::SetAlphaBlend()
(this page) is similar, but uses a more complex (i.e., slower) blend algorithm that supports text
outlines.
This setting has no effect when drawing to the screen.
See also:
TTextGraphic::SetAlphaBlend() (this page)
void TTextGraphic::SetAlphaBlend ()
When drawing to an offscreen texture, blend pixels into the texture and accumulate alpha. Se-
tAlphaBlend() (this page) uses a more sophisticated (and slower) blend algorithm than TText-
Graphic::SetNoBlend() (this page) that causes it to work correctly with text outlines, as well as
blending the text in with other translucent layers.
This setting has no effect when drawing to the screen.
See also:
TTextGraphic::SetNoBlend() (opposite)
uint32_t TTextGraphic::GetLineCount ()
Get the number of lines in the text output.
Returns:
Number of lines.
TReal TTextGraphic::GetStartLine ()
Get the index of the first line of text output.
Returns:
An index between 0 and GetLineCount() (this page)-1.
Playground 4.0.17.1
452 Class and File Reference
str TTextGraphic::GetFont ()
Get the current font.
Returns:
The current font name.
Parameters:
degrees rotation angle in degrees (not radians because degrees are friendlier)
originX offset from left of text rect to use as center point of rotation
originY offset from top of text rect to use as center point of rotation
Playground 4.0.17.1
454 Class and File Reference
TSprite
TTextSprite
Initialization/Destruction
• static TTextSpriteRef Create (uint32_t width, uint32_t height, uint32_t justify=0, const
char ∗fontFilename="", uint32_t lineHeight=10, const TColor &textColor=TColor(0, 0, 0, 1),
int32_t layer=0)
• virtual ∼TTextSprite ()
Drawing
• virtual void Draw (const TDrawSpec &environmentSpec=TDrawSpec(), int32_t depth=-1)
• void SetNoBlend ()
• void SetAlphaBlend ()
Embedded Links
• str Pick (const TPoint &point)
• bool Rollover (const TPoint ∗pPoint)
Text Parameters
• void SetTextRect (uint32_t w, uint32_t h)
• void SetFont (const char ∗fontFilename)
• void SetFlags (uint32_t flags)
• uint32_t GetFlags ()
• void SetColor (const TColor &color)
• const TColor & GetColor () const
• str GetText () const
• void SetText (str text)
• void SetLineHeight (uint32_t newHeight)
• uint32_t GetTextHeight () const
• uint32_t GetTextWidth () const
• TRect GetTextBounds (const TDrawSpec &environmentSpec=TDrawSpec()) const
• uint32_t GetMaxScroll (const TDrawSpec &environmentSpec=TDrawSpec()) const
• uint32_t GetLineCount () const
• void SetStartLine (TReal startLine)
• TReal GetStartLine () const
• void SetLinePadding (int32_t padding)
• void SetDrawingOrigin (const TVec2 &origin)
Public Types
• enum EFlags { kHAlignLeft, kHAlignCenter, kHAlignRight, kVAlignTop, kVAlignCen-
ter, kVAlignBottom }
Playground 4.0.17.1
456 Class and File Reference
kHAlignCenter Align text horizontally with the center the virtual space; text will be centered
on the drawing location horizontally.
kHAlignRight Align text horizontally with the right edge of the virtual space; text will
"grow" to the left from the drawing location.
kVAlignTop Align text vertically with the top edge of the virtual space; text will "grow" down
from the drawing location.
kVAlignCenter Align text vertically with the center the virtual space; text will be centered on
the drawing location vertically.
kVAlignBottom Align text vertically with the bottom of the virtual space; text will "grow" up
from the drawing location.
virtual TTextSprite::∼TTextSprite ()
Destructor.
Defaults to a default-constructed TDrawSpec (p. 223). See TDrawSpec (p. 223) for more details
on what is inherited.
Parameters:
depth How many generations of children to draw; -1 means all children.
See also:
TDrawSpec (p. 223)
void TTextSprite::SetNoBlend ()
When drawing to an offscreen texture, copy pixels to the texture, instead of alpha blending them.
Does not work with text outlines, since the text and outline need to be blended with each other.
The default state is to blend the pixels into the destination texture, leaving alpha alone. If you call
SetNoBlend() (this page), then pixels will be set directly to the colors and alpha values, so that the
texture can then be used blended with an arbitrary background. TTextGraphic::SetAlphaBlend()
(p. 450) is similar, but uses a more complex (i.e., slower) blend algorithm that supports text out-
lines.
This setting has no effect when drawing to the screen.
See also:
TTextSprite::SetAlphaBlend() (this page)
void TTextSprite::SetAlphaBlend ()
When drawing to an offscreen texture, blend pixels into the texture and accumulate alpha. Se-
tAlphaBlend() (this page) uses a more sophisticated (and slower) blend algorithm than TText-
Graphic::SetNoBlend() (p. 450) that causes it to work correctly with text outlines, as well as blend-
Playground 4.0.17.1
458 Class and File Reference
virtual TRect TTextSprite::GetRect (const TDrawSpec & parentContext, int32_t depth = -1)
Get the bounding rectangle of this sprite.
Parameters:
parentContext The parent context to test within—where is this sprite being drawn, and with
what matrix? Alpha and color information is ignored.
depth Depth of children to test
Returns:
Rectangle that includes this sprite.
virtual bool TTextSprite::HitTest (const TPoint & at, const TDrawSpec & parentContext,
int32_t opacity = -1, int32_t depth = -1)
Test to see if a point is within our sprite.
Parameters:
at Point to test.
parentContext The parent context to test within–where is this sprite being drawn, and with
what matrix? Alpha and color information is ignored.
opacity Level of opacity to test for; -1 for a simple bounding box test, or 0-255 for alpha color
value, where 0 is transparent (and will therefore always succeed).
depth Depth of children to test. Zero means only test this sprite. -1 means test
Returns:
true if point hits us.
Parameters:
point Point to test within text.
Returns:
A button name to trigger, if one is found. An empty string if no button is found.
uint32_t TTextSprite::GetFlags ()
Get the current sprite flags.
Returns:
Current flags.
Playground 4.0.17.1
460 Class and File Reference
Returns:
The virtual text region width.
Playground 4.0.17.1
462 Class and File Reference
TAsset
TTexture
TAnimatedTexture
• Draw a sprite
Texture size is limited to 1024x1024 for textures that are in video RAM (i.e., any texture that isn’t
created as "slow").
Additionally, some textures are created from bitmaps, and those bitmaps can be dynamically
MIPMAPped. Bitmaps can be read from JPG or PNG files, and the PNG files will correctly read
the transparency information, if present.
The image extension can be omitted to allow the decision between JPG and PNG to be made on a
an image-by-image basis without needing to change code.
Drawing Methods
• virtual void DrawSprite (TReal x, TReal y, TReal alpha=1, TReal scale=1, TReal rotRad=0,
uint32_t flags=0)
• virtual void DrawSprite (const TDrawSpec &drawSpec)
• virtual void CopyPixels (int32_t x, int32_t y, const TRect ∗sourceRect=NULL, TTextureRef
_dst=TTextureRef())
Playground 4.0.17.1
464 Class and File Reference
Surface access.
Information Query.
Factory Methods
Public Types
Public Attributes
• TTextureData ∗ mData
• slow - Load this texture into slow system RAM. Allows for non-square, non-power-of-two
textures, as well as textures larger than 1024x1024. This flag implies "simple"–no direct draw-
ing from this surface is allowed.
• simple - Create this texture as a simple surface. See GetSimple() (next page) for an explana-
tion.
Playground 4.0.17.1
466 Class and File Reference
See TTexture::Get() (previous page) for information on passing flags inside of asset names.
Note that eForceNoAlpha has no effect, since the point of this function is to add an alpha channel.
Warning:
The two assets must be the same dimensions, or the alpha map will not show up correctly.
Parameters:
colorAssetName Name of the asset used for the color map.File extension (.jpg, .png) is not
necessary. Supports "?" flags like TTexture::Get() (previous page), but only include those
options on the colorAssetName parameter.
alphaAssetName Name of the asset used for the alpha map. File extension (.jpg, .png) is not
necessary. Do not use "?" flags on alphaAssetName.
flags ETextureCreateFlags
Returns:
A TTextureRef to the texture.
Parameters:
assetName Name of the asset to load or acquire a reference to. File extension (.jpg, .png) is
not necessary.
See also:
TTexture::Get() (p. 465)
Returns:
A TTextureRef to the texture.
virtual void TTexture::DrawSprite (TReal x, TReal y, TReal alpha = 1, TReal scale = 1, TReal
rotRad = 0, uint32_t flags = 0)
Draw a normal texture to a render target surface as a sprite. This draws a texture with optional
rotation and scaling. Only capable of drawing an entire surface–not a sub-rectangle. See TTex-
ture::DrawSprite(const TDrawSpec&) (next page) for more drawing control.
Will draw the sprite within the currently active viewport. X and Y are relative to the upper left
corner of the current viewport.
DrawSprite can be called inside TWindow::Draw() (p. 503) or a BeginRenderTarget/EndRender-
Target block.
Parameters:
x X of Center.
Playground 4.0.17.1
468 Class and File Reference
y Y of Center.
alpha Alpha to apply to the entire texture. Set to a negative value to entirely disable alpha
during blit, including alpha within the source TTexture (p. 463).
scale Scaling to apply to the texture. 1.0 is no scaling.
rotRad Rotation in radians around center point.
flags Define how textures are drawn. Use ETextureDrawFlags for the flags. Default behavior
is eDefaultDraw.
Draw a normal texture to a render target surface or backbuffer as a sprite. Uses the TDrawSpec to
decide where to put the texture and how to draw it. See TDrawSpec (p. 223) for details.
Will draw the sprite within the currently active viewport. TDrawSpec position is relative to the
upper left corner of the current viewport.
DrawSprite can be called inside TWindow::Draw() (p. 503) or a TRenderer::BeginRenderTarget()
(p. 379)/EndRenderTarget block.
Parameters:
drawSpec The TDrawSpec to use to draw the sprite.
Draw a normal or simple texture to any target TTexture (p. 463) surface with the same alpha as
this surface. In other words, CopyPixels can go from an alpha surface to another alpha surface, or
to a non-alpha to another non-alpha surface, but not between the two.
There are no restrictions on the blit source rectangle or the destination of the blit within the target
surface.
CopyPixels() (this page) does not respect alpha in its copy; it performs a bitwise, opaque copy
only.
Unlike the other texture calls, CopyPixels() (this page) can be called outside of a TWin-
dow::Draw() (p. 503) or a BeginRenderTarget/EndRenderTarget block.
Parameters:
x Left side of resulting rectangle.
y Top edge of resulting rectangle.
sourceRect Source rectangle to blit. NULL to blit the entire surface.
_dst Destination texture. NULL to draw to back buffer.
void TTexture::Unlock ()
Unlock a surface
TPoint TTexture::GetInternalSize ()
Gets the internal width and height of the texture in pixels, rather than the requested width and
height. Relevant if you’re using the texture as a texture source for TRenderer::DrawVertices
(p. 376).
The texture coordinates that you set in vertices that refer to this texture need to be calculated
based on the internal representation size, and not the "logical" size that GetWidth() (this page)
and GetHeight() (this page) return. In other words, if the original width is 800, and the internal
width is 1024, then your U coordinate for the right edge would be 800.0F/1024.0F.
Playground 4.0.17.1
470 Class and File Reference
If your textures are always powers of two and square in size (equal width and height), GetInter-
nalSize should always return the same values as GetWidth() (previous page) and GetHeight()
(previous page).
Returns:
A point with width and height of the internal texture size, in pixels.
str TTexture::GetName ()
Get the name of the texture.
Returns:
The handle of the image used to create the texture, along with any alpha texture handle.
bool TTexture::IsSimple ()
Query whether this texture is a "simple" type; simple textures can not be used in DrawSprite()
(p. 467), but can be locked and can be used in CopyPixels() (p. 468).
See also:
TTexture::GetSimple (p. 466)
Returns:
True if simple
bool TTexture::IsSlow ()
Query whether this texture is a "slow" texture, i.e. one that’s been allocated in system RAM.
Returns:
True if slow.
bool TTexture::HasAlpha ()
Query whether this texture has an alpha channel.
Returns:
True if the texture has an alpha channel, false otherwise.
void TTexture::Clear ()
Clear the texture to black and transparent alpha.
Parameters:
fileName path of file to create including extension that defines what format to save the file as.
Currently supported file extensions are: ".jpg" and ".png".
quality For file formats that use image compression, this specifies what level of compression
to use (1.0 means highest quality, 0.0 means lowest quality) .png files currently ignore
the quality parameterT
Returns:
true if file was successfully saved, false otherwise.
TTextureRef TTexture::GetRef ()
Get a shared pointer (TTextureRef) to this texture.
Returns:
A TTextureRef that shares ownership with other Refs to this texture.
Playground 4.0.17.1
472 Class and File Reference
Public Attributes
• TVec3 pos
• TReal rhw
• TColor32 color
• TColor32 specular
• TVec2 uv
TReal TTransformedLitVert::rhw
RESERVED; must set to 0.5F.
TColor32 TTransformedLitVert::color
Vertex color.
TColor32 TTransformedLitVert::specular
Vertex specular component.
TVec2 TTransformedLitVert::uv
Vertex texture coordinate.
TRect
TURect
Playground 4.0.17.1
474 Class and File Reference
Public Attributes
• TReal x
• TReal y
Related Functions
(Note that these are not member functions.)
Playground 4.0.17.1
476 Class and File Reference
Playground 4.0.17.1
478 Class and File Reference
Parameters:
s Scale factor.
Returns:
A reference to this, scaled as (x ∗ s, y ∗ s)
TVec2& TVec2::Normalize ()
Normalize this vector.
Changes this vector to (x/Length(), y/Length())
Returns:
A reference to this.
bool operator!= (const TVec2 & lhs, const TVec2 & rhs) [related]
Inequality operator.
Returns:
True if not equal.
TVec2 operator+ (const TVec2 & lhs, const TVec2 & rhs) [related]
Addition operator.
Returns:
(x1 + x2 , y1 + y2 )
TVec2 operator- (const TVec2 & lhs, const TVec2 & rhs) [related]
Subtraction operator.
Returns:
(x1 − x2 , y1 − y2 )
TReal DotProduct (const TVec2 & lhs, const TVec2 & rhs) [related]
Dot product function.
Parameters:
lhs Left-hand side of the dot product.
rhs Right-hand side of the dot product.
Returns:
The dot product of the two vectors: (x1 ∗ x2 + y1 ∗ y2).
Playground 4.0.17.1
480 Class and File Reference
TReal TVec2::y
Public Y dimension.
Public Attributes
• TReal x
• TReal y
• TReal z
Related Functions
(Note that these are not member functions.)
Playground 4.0.17.1
482 Class and File Reference
TVec3::TVec3 ()
Constructor.
Playground 4.0.17.1
484 Class and File Reference
TVec3& TVec3::Normalize ()
Normalize this vector.
Changes this vector to (x/Length(), y/Length(), z/Length())
Returns:
A reference to this.
bool operator!= (const TVec3 & lhs, const TVec3 & rhs) [related]
Inequality operator.
Returns:
True if not equal.
TVec3 operator+ (const TVec3 & lhs, const TVec3 & rhs) [related]
Addition operator.
Returns:
(x1 + x2 , y1 + y2 , z1 + z2 )
TVec3 operator- (const TVec3 & lhs, const TVec3 & rhs) [related]
Subtraction operator.
Returns:
(x1 − x2 , y1 − y2 , z1 − z2 )
Playground 4.0.17.1
486 Class and File Reference
Returns:
(x/s, y/s, z/s)
TReal DotProduct (const TVec3 & lhs, const TVec3 & rhs) [related]
Dot product function.
Returns:
The dot product of the two vectors: (x1 ∗ x2 + y1 ∗ y2 + z1 ∗ z2 ).
TVec3 CrossProduct (const TVec3 & lhs, const TVec3 & rhs) [related]
Cross product function.
Returns:
The cross product of the two vectors.
bool IntersectTriangle (const TVec3 & pvOrig, const TVec3 & pvDir, const TVec3 & pv0, const
TVec3 & pv1, const TVec3 & pv2, TReal ∗ pfDist, TVec3 ∗ pvHit) [related]
Detects if a ray intersects a triangle.
Parameters:
← pvOrig Points to ray origin.
← pvDir Points to ray direction from origin.
← pv0 Points to triangle vertex0.
← pv1 Points to triangle vertex1.
← pv2 Points to triangle vertex2.
→ pfDist Points to where the distance from vOrig to the point of intersection gets stored.
→ pvHit Points to where the actual point of intersection gets stored.
Returns:
true if ray intersects triangle.
TReal TVec3::y
Y dimension.
TReal TVec3::z
Z dimension.
Public Attributes
• TReal x
• TReal y
• TReal z
• TReal w
Related Functions
(Note that these are not member functions.)
Playground 4.0.17.1
488 Class and File Reference
TVec4::TVec4 ()
Constructor.
TVec4& TVec4::Normalize ()
Normalize this vector. Changes vector to (x/Length(), y/Length(), z/Length(), w/Length())
Returns:
A reference to this.
Playground 4.0.17.1
490 Class and File Reference
bool operator== (const TVec4 & lhs, const TVec4 & rhs) [related]
Equality operator.
Returns:
True if equal.
bool operator!= (const TVec4 & lhs, const TVec4 & rhs) [related]
Inequality operator.
Returns:
True if not equal.
TVec4 operator+ (const TVec4 & lhs, const TVec4 & rhs) [related]
Addition operator.
Returns:
(x1 + x2 , y1 + y2 , z1 + z2 , w1 + w2 )
TVec4 operator- (const TVec4 & lhs, const TVec4 & rhs) [related]
Subtraction operator.
Returns:
(x1 − x2 , y1 − y2 , z1 − z2 , w1 − w2 )
Playground 4.0.17.1
492 Class and File Reference
TReal DotProduct (const TVec4 & lhs, const TVec4 & rhs) [related]
Dot product function.
Returns:
The dot product of the two vectors: (x1 ∗ x2 + y1 ∗ y2 + z1 ∗ z2 + w1 ∗ w ∗ 2).
TVec4 CrossProduct (const TVec4 & a, const TVec4 & b, const TVec4 & c) [related]
Cross product function.
Returns:
The cross product of the two vectors.
TReal TVec4::y
Y dimension.
TReal TVec4::z
Z dimension.
TReal TVec4::w
W dimension.
Public Attributes
• TVec3 pos
• TVec3 normal
• TVec2 uv
TVec3 TVert::normal
Vertex normal. Must not be (0,0,0), and must be normalized.
TVec2 TVert::uv
Vertex texture coordinate.
Playground 4.0.17.1
494 Class and File Reference
TVertexSet::∼TVertexSet ()
Destructor.
Playground 4.0.17.1
496 Class and File Reference
TWindow
Update Functions
Functions related to the drawing of windows.
Playground 4.0.17.1
498 Class and File Reference
Event Handlers
Functions to override to handle events in a window, and functions to trigger events on a window.
Protected Attributes
• WindowList mChildren
Friends
• class TWindowAnim
Playground 4.0.17.1
500 Class and File Reference
enum TWindow::EDepth
Position constants for SetWindowDepth
See also:
TWindow::SetWindowDepth (p. 506)
Enumerator:
kBackMost Set this window to be the backmost window.
kFrontMost Set this window to be the frontmost window.
kOneHigher Set this window to be one higher than its current position.
kOneLower Set this window to be one lower than its current position.
kDepthCount Number of depth options.
enum TWindow::EStateFlags
Dynamic Window States
States that may change frequently after window creation.
Enumerator:
kEnabled This window is enabled, and therefore can be rendered to and clicked upon.
kChecked This window is in its "selected" or "checked" state.
kCached This window is rendered to the cache.
kOpaque This window uses no alpha blending when it draws itself, and covers its rectangle
completely. It’s important to set this flag on a window when it’s full screen and should
completely obscure the windows behind it–this will allow Playground to prevent the
deeper window from drawing.
kStateMask A flag mask that isolates the window states.
enum TWindow::EDrawMode
Window drawing mode.
Enumerator:
eAll Draw all layers.
eCached Draw only cacheable layers.
eDynamic Draw only dynamic layers.
virtual TWindow::∼TWindow ()
Destructor.
Reimplemented in TButton (p. 209), TDialog (p. 222), TModalWindow (p. 302), and TTextEdit
(p. 442).
Playground 4.0.17.1
502 Class and File Reference
Reimplemented in TButton (p. 208), TImage (p. 251), TSlider (p. 408), TText (p. 438), and TTextE-
dit (p. 443).
Remember to always call the base class if you’re overriding this function.
Parameters:
style Current style environment that this window was created in.
Since some windows set their size based on their calculated children’s sizes (using TWin-
dow::FitToChildren (p. 504)), TWindow::PostChildrenInit() (this page) needs to call this to adjust
the position after the size has been calculated. Since other windows must have their full position
and size specified in order to properly initialize, TWindow::Init() needs to call this function.
Parameters:
style The style of the window to apply.
PFClassId TWindow::ClassId ()
Get the ClassId.
Returns:
A ClassId that can be passed to IsKindOf.
See also:
Type Information and Casting (p. 25)
If you override this in a derived class, be sure to call the base class to actually add the child
from the list of children.
Parameters:
child Child that’s being added.
initWindow True to call OnNewParent() (p. 501).
Returns:
True if successful. On false, the window has NOT been adopted and the calling class still has
responsibility for destruction.
Playground 4.0.17.1
504 Class and File Reference
If you override this in a derived class, be sure to call the base class to actually remove the child
from the list of children.
Parameters:
child Child that’s being removed.
void TWindow::DestroyAllChildren ()
Destroy (delete) all child windows. Those windows will destroy their own children. Actual dele-
tion is deferred using TWindowManager::SafeDestroyWindow() (p. 527), so the windows will be
actually deleted in the next event loop.
void TWindow::FitToChildren ()
Fit this window to its childrens’ sizes.
TModalWindow∗ TWindow::FindParentModal ()
Find the nearest direct-ancestor modal window.
Returns:
A pointer to a modal window, or NULL if none is found.
bool TWindow::HasChildren ()
Return true if this window has children.
Returns:
True if we’re parents; false otherwise.
TWindow∗ TWindow::GetParent ()
Get the current window parent
Returns:
A shared pointer to the current parent window.
Note:
This will return NULL if the current window has no parent.
Playground 4.0.17.1
506 Class and File Reference
SetWindowDepth (opposite)
uint32_t TWindow::GetWindowWidth ()
Get the width of the client area of this window.
Returns:
Window client width in pixels.
uint32_t TWindow::GetWindowHeight ()
Get the height of the client area of this window.
Returns:
Window client height in pixels.
Playground 4.0.17.1
508 Class and File Reference
Playground 4.0.17.1
510 Class and File Reference
str TWindow::GetName ()
Get the window name, if any.
Returns:
A str (p. 161) containing the window’s name.
bool TWindow::IsOpaque ()
Query this window’s opacity.
Returns:
true if the window is "opaque": When it draws, none of the background will show through. If
any part of the window is transparent, it should not have the kOpaque style set.
bool TWindow::IsModal ()
Query this window’s modal status.
A modal window blocks further event handling by its parent and receives DoModalProcess() calls.
Returns:
Return true if this is a modal window, false if it is not.
bool TWindow::IsEnabled ()
Return whether this window and all of its ancestors are enabled.
Returns:
True if this window is really enabled and (eventual) child of a TModalWindow (p. 298).
Parameters:
message Message to send, including potential payload. Will be deleted after delivery.
Start a window animation. Can be called to reset an animation delay. The virtual function On-
TaskAnimate() (next page) will be called at the frequency given by the parameters to StartWin-
dowAnimation until StopWindowAnimation is called or this window is destroyed.
This window must already be in a hierarchy and have a parent TModalWindow (p. 298) to attach
its animation to, or StartWindowAnimation() (this page) will ASSERT (or crash in release build).
In other words, you cannot call this function in a constructor.
Parameters:
delay Delay, in ms., before OnTaskAnimate will be called.
autoRepeat True to cause delay to be auto-reset, i.e., to call OnTaskAnimate every delay ms.
instead of just once.
resetTime Reset the time after each call. See TAnimTask::SetDelay (p. 192) for details.
forceFrequency Force the animation frequency. See TAnimTask::SetDelay (p. 192) for details.
See also:
TWindow::StopWindowAnimation (this page)
TWindow::OnTaskAnimate (next page)
void TWindow::StopWindowAnimation ()
Handle a message.
Parameters:
message Payload of message.
Returns:
True if message handled; false otherwise.
Playground 4.0.17.1
512 Class and File Reference
Reimplemented in TButton (p. 207), TSlider (p. 407), and TText (p. 437).
Reimplemented in TButton (p. 206), TSlider (p. 407), and TText (p. 436).
Parameters:
point Location of mouse in client coordinates.
Returns:
true if message was handled, false to keep searching for a handler.
Reimplemented in TButton (p. 207), TSlider (p. 407), and TText (p. 437).
This message is only sent if TWindowManager::AddMouseListener() (p. 524) has been called
for this window previously.
Returns:
True if handled.
Reimplemented in TButton (p. 206), TSlider (p. 408), and TText (p. 437).
Playground 4.0.17.1
514 Class and File Reference
Returns:
True if processed; false to keep looking.
str TWindow::GetID ()
Get a unique window identifier.
Returns:
The ID of the window.
References str::getFormatted().
Playground 4.0.17.1
516 Class and File Reference
Function that allows a derived window to add type flags to the TWindow (p. 496). This isn’t
public because in most circumstances a window’s type should be invariant once created.
Parameters:
type Flags to add.
Playground 4.0.17.1
518 Class and File Reference
Message handling.
• void PostWindowMessage (TMessage ∗message)
• void AdoptMessageListener (TMessageListener ∗messageListener)
• bool OrphanMessageListener (TMessageListener ∗messageListener)
Playground 4.0.17.1
520 Class and File Reference
• TScript ∗ GetScript ()
• void RunScript (TWindow ∗window, const char ∗filename)
• void DoLuaString (TWindow ∗window, str script)
• void OnScriptMessage (TMessage ∗message, TLuaFunction ∗command=NULL)
• void AddWindowType (str command, PFClassId classId)
• bool EnableStringTable (bool bEnable)
Utility Functions
• void AddText (TWindow ∗window, str bodyText, str style)
• void SafeDestroyWindow (TWindow ∗window)
Friends
• class TPlatform
virtual TWindowManager::∼TWindowManager ()
Destructor.
Playground 4.0.17.1
522 Class and File Reference
void TWindowManager::InvalidateScreen ()
Mark the current screen as needing to be redrawn.
str TWindowManager::GetModalReturnStr ()
Get the return value from a modal window.
Returns:
A string return value.
int32_t TWindowManager::GetModalReturnInt ()
Get the return value from a modal window.
Returns:
An integer return value.
class TDialog∗ TWindowManager::DisplayDialog (str dialogSpec, str body, str title, str name
= "")
Display a modal dialog box.
Parameters:
dialogSpec Handle to a Lua dialog specification file.
body String to be placed in the dialog body. Selects style DialogBodyText and sets gDi-
alogTable.body to the given body. The Lua dialog specification can then use gDi-
alogTable.body to set the text of the body of the dialog.
title Title of dialog. Selects style DialogTitleText and adds the text to the dialog as gDi-
alogTable.title.
name The name to be given to the resulting dialog window.
Returns:
A pointer to the dialog. The dialog will already have been pushed as the top modal window,
but you may need this pointer to set additional fields.
Playground 4.0.17.1
524 Class and File Reference
TWindowHoverHandler∗ TWindowManager::GetHoverHandler ()
Get the current pop-up help handler.
Returns:
A pointer to the current handler, if any.
TPlatform::SetConfig(TPlatform::kOverlayWindowMouseEvents,"1"); C++
...and this will flag that window as being able to accept focus when clicked. Otherwise focus goes
it its nearest kFocusTarget ancestor, or is delegated to the default-focus defined by the window’s
parent modal.
Parameters:
focus New focus window.
References TWindow::OnSetFocus().
TWindow∗ TWindowManager::GetFocus ()
Get the window that is currently receiving keyboard events.
Returns:
A reference to the current focused window.
TScript∗ TWindowManager::GetScript ()
Get the current TWindowManager (p. 519) GUI script.
Playground 4.0.17.1
526 Class and File Reference
Returns:
A pointer to the current script.
Returns:
returns true if string table was previously enabled, false otherwise
Playground 4.0.17.1
528 Class and File Reference
Local Types
Playground 4.0.17.1
530 Class and File Reference
virtual TWindowStyle::∼TWindowStyle ()
Destructor.
Parameters:
key Name of the parameter to query.
defaultValue Default if parameter value not found.
Returns:
Value if found; defaultValue otherwise.
Playground 4.0.17.1
532 Class and File Reference
• TXmlNode ()
• TXmlNode (const char ∗name)
• virtual ∼TXmlNode ()
• uint32_t ParseStream (const char ∗data, uint32_t len, bool bOneTag=false)
• void ParseString (const char ∗data)
• void ParseFile (const char ∗filename)
• void Clear ()
• bool HasChildren () const
• TXmlNode ∗ GetChild (const char ∗name)
• void OrphanChild (TXmlNode ∗child)
• void DeleteChild (TXmlNode ∗child)
• void ResetChildren ()
• bool GetNextChild (str ∗pName, TXmlNode ∗∗pChild)
• TXmlNode ∗ CreateChild (const char ∗name)
• void SetName (const char ∗name)
• str GetName () const
• str GetContent ()
• void SetContent (const char ∗content)
• str GetAttribute (const char ∗name, bool ∗pbQuoted=NULL)
• void SetAttribute (const char ∗name, const char ∗value)
• void SetAttribute (const char ∗name, int32_t value)
• void ResetAttributes ()
• bool GetNextAttribute (str ∗pName, str ∗pValue)
• str GetChildContent (const char ∗name)
• str AsString ()
TXmlNode::TXmlNode ()
Default constructor.
virtual TXmlNode::∼TXmlNode ()
Destructor.
uint32_t TXmlNode::ParseStream (const char ∗ data, uint32_t len, bool bOneTag = false)
Parse a stream as XML, loading contents as children of this node. Does not consume all data.
Consumes a balanced open/close tag (and everything in between)
Parameters:
data buffer to parse
len length of buffer
bOneTag normally false, set to true to consume just one tag, not a balanced open/close
Returns:
Number of Characters consumed from the buffer - will be 0, if not enough data available
Playground 4.0.17.1
534 Class and File Reference
void TXmlNode::Clear ()
Remove all children and attributes.
void TXmlNode::ResetChildren ()
Reset internal child iterator.
See also:
GetNextChild (this page)
Parameters:
pName Pointer to str (p. 161) to receive name of child that was found
pChild Pointer to receive next child in iteration.
Returns:
str TXmlNode::GetContent ()
Get the content of this node (the part between the opening and closing tags).
Returns:
The node content.
Playground 4.0.17.1
536 Class and File Reference
Parameters:
name Name of attribute to query.
pbQuoted Whether the attribute’s value is surrounded by quotes.
Returns:
The value of the attribute, if found. Otherwise an empty string.
void TXmlNode::ResetAttributes ()
Reset the internal attribute iterator.
str TXmlNode::AsString ()
Parse the XML tree into an XML formatted string that can be written to a file.
Returns:
The data as a string.
Playground 4.0.17.1
538 Class and File Reference
Defines
• #define ERROR_WRITE(OUT_STATEMENT)
• #define TRACE_WRITE()
• #define ASSERT(STATEMENT)
• #define VERIFY(STATEMENT)
• #define DEBUG_WRITE(OUT_STATEMENT)
• #define VERBOSE_ERROR(X)
• #define VERBOSE_DEBUG(X)
• #define VERBOSE_TRACE()
#define DEBUG_WRITE(OUT_STATEMENT)
In debug builds (when _DEBUG is 1), this function will send the contained printf-style string and
parameters to the debug log, and to the debug monitor.
#define ERROR_WRITE(OUT_STATEMENT)
In all builds, this function will write the contained printf-style string and parameters to the debug
log, and also to the debug monitor in debug builds.
Note you need to enclose the parameters in a second pair of parenthesis:
#define TRACE_WRITE()
When INCLUDE_TRACE_STATEMENTS in debug.h (opposite) is set to 1, this function will out-
put the name of the function, file, and line to the debug log.
#define VERBOSE_DEBUG(X)
This macro will write an error string to the debug log in debug builds if you enable verbose de-
bugging by calling TPlatform::SetConfig( TPlatform::kVerboseDebug );
See also:
DEBUG_WRITE (opposite)
#define VERBOSE_ERROR(X)
This macro will write an error string to the debug log in debug and release builds if you enable
verbose debugging by calling TPlatform::SetConfig( TPlatform::kVerboseDebug );
See also:
DEBUG_WRITE (opposite)
#define VERBOSE_TRACE()
This macro will write an error string to the debug log in debug builds indicating the name of
the function, file, and line to the debug log if you enable verbose debugging by calling TPlat-
form::SetConfig( TPlatform::kVerboseDebug );
See also:
DEBUG_WRITE (opposite)
#define VERIFY(STATEMENT)
Verify that a statement is returning non-zero.
Acts like ASSERT, only STATEMENT is always included in the program.
Playground 4.0.17.1
540 Class and File Reference
Parameters:
STATEMENT Statement to test.
Defines
• #define PFTYPEDEF(THISCLASS, BASECLASS)
• #define PFTYPEDEF_DC(THISCLASS, BASECLASS)
• #define PFSHAREDTYPEDEF(BASECLASS)
• #define PFSHAREDTYPEDEF_DC(THISCLASS, BASECLASS)
• #define PFTYPEDEFBASE()
• #define PFTYPEDEFBASE_DC(THISCLASS)
• #define PFSHAREDTYPEDEFBASE(THISCLASS)
• #define PFSHAREDTYPEDEFBASE_DC(THISCLASS)
• #define PFTYPEIMPL(THISCLASS)
• #define PFTYPEIMPL_DC(THISCLASS)
• #define PFTYPEIMPL_DCA(THISCLASS)
Playground 4.0.17.1
542 Class and File Reference
Putting this macro in a class will declare and define IsKindOf(), GetCast() and ClassId() for that
class.
Parameters:
BASECLASS Our base class.
See also:
Type Information and Casting (p. 25)
#define PFSHAREDTYPEDEFBASE(THISCLASS)
Additional definitions for the base class of a polymorphic type that needs run time type informa-
tion, and that will be stored in shared pointers (reference counted, like TTextureRef).
Putting this macro in a class will declare and define IsKindOf(), GetCast() and ClassId() for that
class.
Parameters:
THISCLASS The current class to declare.
#define PFSHAREDTYPEDEFBASE_DC(THISCLASS)
Additional definitions for the base class of a polymorphic type that needs run time type infor-
mation and dynamic creation, and that will be stored in shared pointers (reference counted, like
TTextureRef).
Putting this macro in a class will declare and define IsKindOf(), GetCast() and ClassId() for that
class.
See also:
Type Information and Casting (p. 25)
#define PFTYPEDEFBASE()
Additional definitions for the base class of a polymorphic type that needs run time type informa-
tion.
Putting this macro in a class will declare and define IsKindOf(), GetCast() and ClassId() for that
class.
#define PFTYPEDEFBASE_DC(THISCLASS)
Additional definitions for the base class of a polymorphic type that needs run time type informa-
tion and dynamic creation.
Putting this macro in a class definition file will declare and define IsKindOf(), GetCast() and Clas-
sId() for that class.
Parameters:
THISCLASS The current class to declare.
#define PFTYPEIMPL(THISCLASS)
Implementation for run time type information.
Use this macro in the implementation file.
#define PFTYPEIMPL_DC(THISCLASS)
Implementation for run time type information for a class with dynamic creation.
Use this macro in the implementation file.
#define PFTYPEIMPL_DCA(THISCLASS)
Implementation for run time type information for an abstract class, descendents of which will
require dynamic creation.
Use this macro in the implementation file.
Playground 4.0.17.1
544 Class and File Reference
Functions
• void PlaygroundInit ()
Appendix
Appendix A
Forward Declarations
Typedefs
• typedef shared_ptr< TTexture > TTextureRef
• typedef shared_ptr< TAnimatedTexture > TAnimatedTextureRef
• typedef shared_ptr< TSprite > TSpriteRef
• typedef shared_ptr< TTextSprite > TTextSpriteRef
• typedef shared_ptr< TAnimatedSprite > TAnimatedSpriteRef
• typedef shared_ptr< TScriptCode > TScriptCodeRef
• typedef shared_ptr< TSound > TSoundRef
• typedef shared_ptr< TSoundInstance > TSoundInstanceRef
• typedef shared_ptr< TModel > TModelRef
• typedef shared_ptr< TAsset > TAssetRef
TLitVert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
TLuaFunction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
TLuaObjectWrapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
TLuaParticleSystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
TLuaTable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
TMat3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
TMat4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
TMaterial (A rendering material ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
TMessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
TMessageListener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
TModalWindow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
TModel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
TParamSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
TParticleFunction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
TParticleMachineState . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
TParticleRenderer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
TParticleState . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
TPfHiscores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
TPlatform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
TPoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
TPrefs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
TPrefsDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
TRandom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
TRect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
TRenderer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
TScreen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
TScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
TScriptCode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
TSimpleHttp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400
TSlider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
TSound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
TSoundCallBack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
TSoundInstance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
TSoundManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416
TSpeex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
TSprite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
TStringTable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
TTask . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
TTaskList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
TText . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
TTextEdit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440
TTextGraphic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
TTextSprite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
TTexture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
TTransformedLitVert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472
TURect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
TVec2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
TVec3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
TVec4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
TVert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
TVertexSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
TWindow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
TWindowHoverHandler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
TWindowManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
TWindowSpider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
TWindowStyle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529
TXmlNode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532
Playground 4.0.17.1
552
Playground 4.0.17.1