File: GameApp.cpp

package info (click to toggle)
libtuxcap 1.4.0.dfsg2-2.1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 4,176 kB
  • sloc: cpp: 43,203; ansic: 3,095; python: 774; objc: 242; makefile: 100; xml: 87
file content (327 lines) | stat: -rw-r--r-- 13,358 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
#include "GameApp.h"
#include "Board.h"
#include "WidgetManager.h"

// Why are we including ImageFont.h and not Font.h? Font.h is just a generic
// base class. ImageFont creates fonts from an image that contains all the
// text characters as well as a text file that indicates character widths
// and kerning information, as well as some more advanced features not used
// in this tutorial such as font layers, etc.
#include "ImageFont.h"

// The Image.h file just declares basic functions. All images are either of 
// the DDImage or MemoryImage type. For this demo, we will use DDImage
// types, as they are the type returned by the image loading code.
// A DDImage is actually derived from MemoryImage, so where an Image or
// MemoryImage is required, a DDImage will suffice as well. A DDImage
// contains optimized code for use with DirectX 7+.

#include "DDImage.h"
// This will let us load sounds
#include "SoundManager.h"

// The SexyAppFramework resides in the "Sexy" namespace. As a convenience,
// you'll see in all the .cpp files "using namespace Sexy" to avoid
// having to prefix everything with Sexy::
using namespace Sexy;


//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
GameApp::GameApp()
{
	// mProdName is used for internal purposes to indicate the game that we're working on
	mProdName = "Demo 2";

	// For internal uses, indicates the current product version
	mProductVersion = "1.0";

	// This is the text that appears in the title bar of the application window
	mTitle = StringToSexyStringFast("TuxCap: " + mProdName + " - " + mProductVersion);

	// Indicates the registry location where all registry keys will be read from
	// and written to. This is stored under the HKEY_CURRENT_USER tree on 
	// Windows systems.
	mRegKey = "TuxCap\\Demo2";

	// Set the application width/height in terms of pixels here. Let's
	// use a different resolution from Demo 1 just for fun.
	mWidth = 640;
	mHeight = 480;

	mBoard = NULL;

	mTextFont = NULL;
	mNumberFont = NULL;
	mTurbotImg = NULL;
	mMoonImg = NULL;
	mOpaqueBeamImg = NULL;
}

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
GameApp::~GameApp()
{
	// Remove our "Board" class which was, in this particular demo,
	// responsible for all our game drawing and updating.
	// All widgets MUST be removed from the widget manager before deletion.
	// More information on the basics of widgets can be found in the Board
	// class file. If you tried to delete the Board widget before removing
	// it, you will get an assert.
	mWidgetManager->RemoveWidget(mBoard);
	delete mBoard;

	// We need to clean up after ourselves and delete the image and
	// font information.
	delete mTextFont;
	delete mNumberFont;
	delete mTurbotImg;
	delete mMoonImg;
	delete mOpaqueBeamImg;

	// We need to release the memory allocated to our sounds too.
	// This call frees up the memory for ALL sound effects.

	mSoundManager->ReleaseSounds();

}

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void GameApp::Init()
{
	// Let the parent class perform any needed initializations first.
	// This should always be done.
	SexyAppBase::Init();

	// In later demos, you will see more done with this function.
	// For now, we have nothing else to initialize, so we are done.
	// Once complete, the LoadingThreadProc function will automatically
	// start and we will begin loading all our needed resources.
}

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void GameApp::LoadingThreadProc()
{
	// This time, we have things to load. Let's load in our two fonts
	// and our three images.	
	// Besides loading data,
	// this thread can also update the progress indicator for the loading
	// screen, which you will see in later demos.
	// Once complete, the LoadingThreadCompleted function will be called.

	//		Loading images is easy: you don't have to specify the image type.
	// Depending on the file extension, the appropriate image decoder
	// will be used. The following image types are supported:
	// Targa (.tga), JPEG (.jpg), PNG (.png), GIF (.gif). You do NOT have
	// to specify the extension when loading the file if you don't want to.
	// In this case, all of the above extensions will be looked for.
	// A discussion of image formats is beyond the scope of this tutorial.
	//		There is some important information to know about images.
	//	You will notice in the "images" directory that for each image, 
	//	there is a black and white image with the same name but with
	//	an underscore ("_") at the end of it. By default, when you load
	//	and image, the code automatically looks for the presence of
	//	that file to use for the alpha information. Some file formats
	//	have the alpha channel built into them, like PNG files. But
	//	others, like JPEG or GIF files, do not. The purpose of the alpha
	//	file is of course to generate an image that doesn't have jagged
	//	lines, or to control the opacity of various parts of the image.
	//	As a side not, the alpha image file may also begin with the
	//	underscore instead of ending with it, it matters not, and again,
	//	is automatically loaded in by the image loading code.
	//	You need to clean up the memory allocated by these functions yourself.
	mOpaqueBeamImg = (Image*) GetImage("images/beam_opaque.jpg");

	// If the file was not found or couldn't be loaded (i.e. due to an
	// incompatible file format) the returned value will be NULL.
	// You should always check this, and if it occurs, display an error
	// message, then set mLoadingFailed to true, and then immediately return.
	if (mOpaqueBeamImg == NULL)
	{

		// The PopUp method displays a standard Windows message box.
		// If in full screen mode, this will appropriately handle things such
		// that the GDI surface is properly rendered and the dialog box appears
		// as expected.
#if 0
		Popup("There was an error loading the file: images/beam_opaque");
 #endif
	mLoadingFailed = true;

		return;
	}

	// Now load the other two images
	mMoonImg = (Image*) GetImage("images/moon.gif");
	if (mMoonImg == NULL)
	{
#if 0	
	Popup("There was an error loading the file: images/moon");
#endif
		mLoadingFailed = true;
		return;
	}

	mTurbotImg = (Image*) GetImage("images/turbot_worry.gif");
	if (mTurbotImg == NULL)
	{
#if 0	
		Popup("There was an error loading the file: images/turbot_worry");
#endif
		mLoadingFailed = true;
		return;
	}

	// So we've loaded the images, that's all there is right? Wrong.
	// If possible, we should try to palletize the images. An image that
	// contains 255 or fewer colors can be palletized. This results in
	// a memory savings of about 4x and doesn't affect the image quality
	// at all. It's the same principals that the GIF format uses: instead
	// of representing each red, green, blue, alpha value as a separate
	// quantity (1 byte each, 4 bytes in total per pixel), we represent
	// the actual combined RGBA value as a single number, from 0-255.
	// This number is an index into a lookup table. Thus, every time
	// the value (200,43,11,128), for example, is used, instead of
	// representing that value as a 4 byte value every time it
	// appears, we'd represent it with a 1 byte index into a lookup
	// table that contained the above RGBA value. Don't worry, you
	// don't have to really know or care about any of that if you
	// didn't understand it. What you need to know is that by calling the
	// Palletize() method on an image, you potentially can reduce the
	// amount of RAM it consumes by 4 times. The Palletize method
	// returns a boolean indicating if it could or couldn't be palletized.
	((DDImage*)mOpaqueBeamImg)->Palletize();
	((DDImage*)mMoonImg)->Palletize();
	((DDImage*)mTurbotImg)->Palletize();
	// Now let's load and create some fonts. A font consists of an 
	// image and a text file. The image works on the same principles
	// as a normal image file (like the ones above) works on. Except
	// that with fonts, there is only 1 image, the alpha image.
	// Thus, you will see in the "fonts" directory two images that
	// begin with the underscore prefix. If there isn't a file
	// of the same name without an underscore, then it is assumed that
	// the file is of the same dimensions as the underscore file and that
	// it is to be all white and fully opaque. This is done with fonts because
	// it's common to want to change the color of the font, and to change
	// the color, the base, original image color, should be white and
	// fully opaque. More information on colorizing fonts and images can
	// be found in Board.cpp, but for now know that the image in the fonts
	// directory contains the alpha information for your font, and that it
	// is assumed that the "main" image is pure white.
	//		The other file in the directory is a text file, commonly with the
	//	same name as the image, but without the underscore character, but
	//	not always. The file will define the name of the image to load.
	//	This file defines the characters, their widths, their offsets
	//	within the image, the point size, and any layers (which are not
	//	used or discussed in this demo). This is the data file and is
	//	how the font knows how to take a string and convert it into
	//	the proper images representing each character. A font is really
	//	just an image but with an extra data file that tells the program
	//	how to map strings to their image representation.
	//		You load a font by specifying the text data file.
	mTextFont = new ImageFont(this, "fonts/Kiloton9.txt");

	// We need to check to see if the font was properly initialized.
	// If it wasn't, then an error occurred and we need to abort.
	if (!mTextFont->mFontData->mInitialized)	
	{
		delete mTextFont;
#if 0
		Popup("There was an error loading fonts/Kiloton9.txt");
#endif
		mLoadingFailed = true;
		return;
	}

	mNumberFont = new ImageFont(this, "fonts/supernova20.txt");
	if (!mNumberFont->mFontData->mInitialized)	
	{
		delete mNumberFont;
#if 0
		Popup("There was an error loading fonts/supernova20.txt");
#endif
		mLoadingFailed = true;
		return;
	}

	// Let's load some sounds. You assign a unique unsigned integer ID to each
	// sound. It is with this ID that you indicate which sound you
	// want to play. Valid types of sounds to load are: 
	// WAV, OGG, AU, and if you have FMod and enable FMod: MP3. Although
	// you should probably not use MP3 due to patent/copyright issues
	// unless of course that either doesn't bother you or you happen
	// to have the legal right to do so. Like images, you don't have
	// to specify the file extension. LoadSound returns a boolean
	// indicating success or failure.

	if (!mSoundManager->LoadSound(1, "sounds/timer"))
	{

#if 0
		Popup("There was an error loading sounds/timer");
#endif
		mLoadingFailed = true;		
		return;
	}

	if (!mSoundManager->LoadSound(2, "sounds/mutator"))
	{
#if 0
		Popup("There was an error loading sounds/mutator");
#endif
		mLoadingFailed = true;
		return;
	}

}

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void GameApp::LoadingThreadCompleted()
{
	// Let the base app class also know that we have completed
	SexyAppBase::LoadingThreadCompleted();

	// When we're actually loading resources, we'll set the
	// mLoadingFailed variable to "true" if there were any problems
	// encountered along the way. If that is the case, just return
	// because we won't want the user to get to the main menu or any
	// other part of the game. We will want them to exit out.
	if (mLoadingFailed)
		return;

	// Now that we're done loading everything we need (which wasn't
	// anything in this particular demo), we need to get the main
	// game screen up and running: That is our "Board" class, and
	// it will handle all the drawing, updating, and input processing
	// for most of the game.
	mBoard = new Board(this);

	// This is a very important step: Because the Board class is a widget
	// (see Board.h/.cpp for more details) we need to tell it what
	// dimensions it has and where to place it. 
	// By default a widget is invisible because its
	// width/height are 0, 0. Since the Board class is our main
	// drawing area and game logic class, we want to make it the
	// same size as the application. For this particular demo, that means
	// 800x600. We will use mWidth and mHeight though, as those were
	// already set to the proper resolution in GameApp::Init().
	mBoard->Resize(0, 0, mWidth, mHeight);

	// Also an important step is to add the newly created Board widget to
	// the widget manager so that it will automatically have its update, draw,
	// and input processing methods called.
	mWidgetManager->AddWidget(mBoard);

	// And just to test out our sound playing abilities, let's play the
	// mutator sound to indicate that we're done loading.
	//  We do that by calling GameApp's PlaySample()
	// method and specifying the integral ID of the sound to play. This
	// ID is the same as we used when loading the sound in GameApp::LoadingThreadProc()

	PlaySample(2);

}