1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef PRINCE_PRINCE_H
24 #define PRINCE_PRINCE_H
25 
26 #include "common/random.h"
27 #include "common/system.h"
28 #include "common/debug.h"
29 #include "common/debug-channels.h"
30 #include "common/textconsole.h"
31 #include "common/rect.h"
32 #include "common/events.h"
33 #include "common/endian.h"
34 #include "common/savefile.h"
35 #include "common/serializer.h"
36 
37 #include "image/bmp.h"
38 
39 #include "gui/debugger.h"
40 
41 #include "engines/engine.h"
42 #include "engines/util.h"
43 
44 #include "audio/mixer.h"
45 
46 #include "video/flic_decoder.h"
47 
48 #include "prince/mob.h"
49 #include "prince/object.h"
50 #include "prince/pscr.h"
51 #include "prince/detection.h"
52 
53 namespace Prince {
54 
55 struct SavegameHeader;
56 
57 class PrinceEngine;
58 class GraphicsMan;
59 class Script;
60 class Interpreter;
61 class InterpreterFlags;
62 class Debugger;
63 class MusicPlayer;
64 class VariaTxt;
65 class Cursor;
66 class MhwanhDecoder;
67 class Font;
68 class Hero;
69 class Animation;
70 class Room;
71 class Pscr;
72 
73 struct SavegameHeader {
74 	uint8 version;
75 	Common::String saveName;
76 	Graphics::Surface *thumbnail;
77 	int16 saveYear, saveMonth, saveDay;
78 	int16 saveHour, saveMinutes;
79 	uint32 playTime;
80 };
81 
82 #define kSavegameStrSize 14
83 #define kSavegameStr "SCUMMVM_PRINCE"
84 
85 struct Text {
86 	const char *_str;
87 	uint16 _x, _y;
88 	uint16 _time;
89 	uint32 _color;
90 
TextText91 	Text() {
92 		clear();
93 	}
94 
clearText95 	void clear() {
96 		_str = nullptr;
97 		_x = 0;
98 		_y = 0;
99 		_time = 0;
100 		_color = 255;
101 	}
102 };
103 
104 struct AnimListItem {
105 	uint16 _type; // type of animation - for background anims RND of frame
106 	uint16 _fileNumber;
107 	uint16 _startPhase; // first phase number
108 	uint16 _endPhase;
109 	uint16 _loopPhase;
110 	int16 _x;
111 	int16 _y;
112 	uint16 _loopType;
113 	uint16 _nextAnim; // number of animation to do for loop = 3
114 	uint16 _flags; // byte 0 - draw masks, byte 1 - draw in front of mask, byte 2 - load but turn off drawing
115 	bool loadFromStream(Common::SeekableReadStream &stream);
116 };
117 
118 struct BAS {
119 	int32 _type; // type of sequence
120 	int32 _data; // additional data
121 	int32 _anims; // number of animations
122 	int32 _current; // actual number of animation
123 	int32 _counter; // time counter for animation
124 	int32 _currRelative; //actual relative number for animation
125 	int32 _data2; // additional data for measurements
126 };
127 
128 const int kStructSizeBAS = 28;
129 
130 struct BASA {
131 	int16 _num;	// animation number
132 	int16 _start;	// initial frame
133 	int16 _end;	// final frame
134 	//int16 _pad;	// fulfilment to 8 bytes
135 };
136 
137 const int kStructSizeBASA = 8;
138 
139 // background and normal animation
140 struct Anim {
141 	BASA _basaData;
142 	int32 _addr; //animation adress
143 	int16 _usage;
144 	int16 _state; // state of animation: 0 - turning on, 1 - turning off
145 	int16 _flags;
146 	int16 _frame; // number of phase to show
147 	int16 _lastFrame; // last phase
148 	int16 _loopFrame; // first frame of loop
149 	int16 _showFrame; // actual visible frame of animation
150 	int16 _loopType;	 // type of loop (0 - last frame; 1 - normal loop (begin from _loopFrame); 2 - no loop; 3 - load new animation)
151 	int16 _nextAnim; // number of next animation to load after actual
152 	int16 _x;
153 	int16 _y;
154 	int32 _currFrame;
155 	int16 _currX;
156 	int16 _currY;
157 	int16 _currW;
158 	int16 _currH;
159 	int16 _packFlag;
160 	int32 _currShadowFrame;
161 	int16 _packShadowFlag;
162 	int32 _shadowBack;
163 	int16 _relX;
164 	int16 _relY;
165 	Animation *_animData;
166 	Animation *_shadowData;
167 
168 	enum AnimOffsets {
169 		kAnimState = 10,
170 		kAnimFrame = 14,
171 		kAnimLastFrame = 16,
172 		kAnimX = 26
173 	};
174 
getAnimDataAnim175 	int16 getAnimData(Anim::AnimOffsets offset) {
176 		switch (offset) {
177 		case kAnimState:
178 			return _state;
179 		case kAnimFrame:
180 			return _frame + 1; // fix for location 30 - man with a dog animation
181 		case kAnimX:
182 			return _x;
183 		default:
184 			error("getAnimData() - Wrong offset type: %d", (int)offset);
185 		}
186 	}
187 
setAnimDataAnim188 	void setAnimData(Anim::AnimOffsets offset, int16 value) {
189 		if (offset == kAnimX) {
190 			_x = value;
191 		} else {
192 			error("setAnimData() - Wrong offset: %d, value: %d", (int)offset, value);
193 		}
194 	}
195 };
196 
197 struct BackgroundAnim {
198 	BAS _seq;
199 	Common::Array<Anim> backAnims;
200 };
201 
202 enum AnimType {
203 	kBackgroundAnimation,
204 	kNormalAnimation
205 };
206 
207 // Nak (PL - Nakladka)
208 struct Mask {
209 	uint16 _state; // visible / invisible
210 	int16 _flags; // turning on / turning off of an mask
211 	int16 _x1;
212 	int16 _y1;
213 	int16 _x2;
214 	int16 _y2;
215 	int16 _z;
216 	int16 _number; // number of mask for background recreating
217 	int16 _width;
218 	int16 _height;
219 	byte *_data;
220 
getXMask221 	int16 getX() const {
222 		return READ_LE_UINT16(_data);
223 	}
224 
getYMask225 	int16 getY() const {
226 		return READ_LE_UINT16(_data + 2);
227 	}
228 
getWidthMask229 	int16 getWidth() const {
230 		return READ_LE_UINT16(_data + 4);
231 	}
232 
getHeightMask233 	int16 getHeight() const {
234 		return READ_LE_UINT16(_data + 6);
235 	}
236 
getMaskMask237 	byte *getMask() const {
238 		return (byte *)(_data + 8);
239 	}
240 };
241 
242 struct InvItem {
243 	int _x;
244 	int _y;
245 	Graphics::Surface *_surface;
getSurfaceInvItem246 	Graphics::Surface *getSurface() const { return _surface; }
247 };
248 
249 struct DrawNode {
250 	int posX;
251 	int posY;
252 	int posZ;
253 	int32 width;
254 	int32 height;
255 	int32 scaleValue;
256 	Graphics::Surface *s;
257 	Graphics::Surface *originalRoomSurface;
258 	void *data;
259 	void (*drawFunction)(Graphics::Surface *, DrawNode *);
260 };
261 
262 struct DebugChannel {
263 
264 enum Type {
265 	kScript,
266 	kEngine
267 };
268 
269 };
270 
271 class PrinceEngine : public Engine {
272 protected:
273 	Common::Error run() override;
274 
275 public:
276 	PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc);
277 	~PrinceEngine() override;
278 
279 	bool scummVMSaveLoadDialog(bool isSave);
280 
281 	bool hasFeature(EngineFeature f) const override;
282 	void pauseEngineIntern(bool pause) override;
283 	bool canSaveGameStateCurrently() override;
284 	bool canLoadGameStateCurrently() override;
285 	Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
286 	Common::Error loadGameState(int slot) override;
287 
288 	void playVideo(Common::String videoFilename);
289 
290 	WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true);
291 	void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header);
292 	void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream);
293 	bool loadGame(int slotNumber);
294 	void resetGame();
295 
296 	int32 _creditsDataSize;
297 	byte *_creditsData;
298 	void scrollCredits();
299 
300 	int getGameType() const;
301 	const char *getGameId() const;
302 	uint32 getFeatures() const;
303 	Common::Language getLanguage() const;
304 
305 	const PrinceGameDescription *_gameDescription;
306 	Video::FlicDecoder _flicPlayer;
307 	const Graphics::Surface *_flcFrameSurface;
308 	VariaTxt *_variaTxt;
309 
310 	uint32 _talkTxtSize;
311 	byte *_talkTxt;
312 
313 	uint32 _mobTranslationSize;
314 	byte *_mobTranslationData;
315 
316 	bool _missingVoice;
317 
318 	bool loadLocation(uint16 locationNr);
319 	bool loadAnim(uint16 animNr, bool loop);
320 	bool loadVoice(uint32 textSlot, uint32 sampleSlot, const Common::String &name);
321 	bool loadSample(uint32 sampleSlot, const Common::String &name);
322 	bool loadZoom(byte *zoomBitmap, uint32 dataSize, const char *resourceName);
323 	bool loadShadow(byte *shadowBitmap, uint32 dataSize, const char *resourceName1, const char *resourceName2);
324 	bool loadTrans(byte *transTable, const char *resourceName);
325 	bool loadMobPriority(const char *resourceName);
326 
327 	void loadMobTranslationTexts();
328 	void setMobTranslationTexts();
329 
330 	bool loadMusic(int musNumber);
331 	void stopMusic();
332 
333 	void playSample(uint16 sampleId, uint16 loopType);
334 	void stopSample(uint16 sampleId);
335 	void stopAllSamples();
336 	void freeSample(uint16 sampleId);
337 	void freeAllSamples();
338 
339 	void setVoice(uint16 slot, uint32 sampleSlot, uint16 flag);
340 
341 	void changeCursor(uint16 curId);
342 	void printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y);
343 	int calcTextLines(const char *s);
344 	int calcTextTime(int numberOfLines);
345 	void correctStringDEU(char *s);
346 
347 	static const uint8 kMaxTexts = 32;
348 	Text _textSlots[kMaxTexts];
349 
350 	Hero *_mainHero;
351 	Hero *_secondHero;
352 
353 	enum HeroId {
354 		kMainHero,
355 		kSecondHero
356 	};
357 
358 	int _mouseFlag;
359 	uint32 _currentTime;
360 	uint16 _locationNr;
361 	uint16 _sceneWidth;
362 	int32 _picWindowX;
363 	int32 _picWindowY;
364 
365 	Image::BitmapDecoder *_roomBmp;
366 	MhwanhDecoder *_suitcaseBmp;
367 	Room *_room;
368 	Script *_script;
369 	InterpreterFlags *_flags;
370 	Interpreter *_interpreter;
371 	GraphicsMan *_graph;
372 	uint8 _currentMidi;
373 	byte *_zoomBitmap;
374 	byte *_shadowBitmap;
375 	byte *_transTable;
376 
377 	int16 _scaleValue; // scale for hero or special shadow animation
378 	int16 _lightX; // for hero shadow
379 	int16 _lightY;
380 	int32 _shadScaleValue;
381 	int32 _shadLineLen;
382 	byte *_shadowLine;
383 	void setShadowScale(int32 shadowScale);
384 	static void plotShadowLinePoint(int x, int y, int color, void *data);
385 
386 	static const int16 kFPS = 15;
387 	static const int32 kIntMax = 2147483647;
388 
389 	static const int16 kMaxPicWidth = 1280;
390 	static const int16 kMaxPicHeight = 480;
391 	static const int16 kZoomStep = 4;
392 	static const int32 kZoomBitmapLen = kMaxPicHeight / kZoomStep * kMaxPicWidth / kZoomStep;
393 	static const int32 kShadowBitmapSize = kMaxPicWidth * kMaxPicHeight / 8;
394 	static const int16 kShadowLineArraySize = 2 * 1280 * 4;
395 	static const int16 kZoomBitmapWidth = kMaxPicWidth / kZoomStep;
396 	static const int16 kZoomBitmapHeight = kMaxPicHeight / kZoomStep;
397 	static const int16 kNormalWidth = 640;
398 	static const int16 kNormalHeight = 480;
399 	static const uint32 kTransTableSize = 256 * 256;
400 
401 	static const int kMaxNormAnims = 64;
402 	static const int kMaxBackAnims = 64;
403 	static const int kMaxObjects = 64;
404 	static const int kMaxMobs = 64;
405 
406 	Common::Array<DrawNode> _drawNodeList;
407 	Common::Array<AnimListItem> _animList;
408 	Common::Array<BackgroundAnim> _backAnimList;
409 	Common::Array<Anim> _normAnimList;
410 	Common::Array<Mob> _mobList;
411 	Common::Array<uint32> _mobPriorityList;
412 	Common::Array<Mask> _maskList;
413 	Common::Array<Object *> _objList;
414 	uint16 *_objSlot;
415 
416 	void freeNormAnim(int slot);
417 	void freeAllNormAnims();
418 	void removeSingleBackAnim(int slot);
419 
420 	Common::RandomSource _randomSource;
421 
422 	void checkMasks(int x1, int y1, int sprWidth, int sprHeight, int z);
423 	void insertMasks(Graphics::Surface *originalRoomSurface);
424 	void showMask(int maskNr, Graphics::Surface *originalRoomSurface);
425 	void clsMasks();
426 
427 	void grabMap();
428 
429 	int _selectedMob; // number of selected Mob / inventory item
430 	int _selectedItem; // number of item on mouse cursor
431 	int _selectedMode;
432 	int _currentPointerNumber;
433 
434 	static const int16 kMaxInv = 90; // max amount of inventory items in whole game
435 	static const uint16 kMaxItems = 30; // size of inventory
436 
437 	uint32 _invTxtSize;
438 	byte *_invTxt;
439 
440 	Graphics::Surface *_optionsPic;
441 	Graphics::Surface *_optionsPicInInventory;
442 
443 	bool _optionsFlag;
444 	int _optionEnabled;
445 	int _optionsMob;
446 	int _optionsX;
447 	int _optionsY;
448 	int _optionsWidth;
449 	int _optionsHeight;
450 	int _invOptionsWidth;
451 	int _invOptionsHeight;
452 	int _optionsStep;
453 	int _invOptionsStep;
454 	int _optionsNumber;
455 	int _invOptionsNumber;
456 	int _optionsColor1; // color for non-selected options
457 	int _optionsColor2; // color for selected option
458 
459 	bool _showInventoryFlag;
460 	int _invExamY;
461 	bool _inventoryBackgroundRemember;
462 	int _invLineX;
463 	int _invLineY;
464 	int _invLine;  // number of items in one line
465 	int _invLines; // number of lines with inventory items
466 	int _invLineW;
467 	int _invLineH;
468 	int _maxInvW;
469 	int _maxInvH;
470 	int _invLineSkipX;
471 	int _invLineSkipY;
472 	int _invX1;
473 	int _invY1;
474 	int _invWidth;
475 	int _invHeight;
476 	bool _invCurInside;
477 	int _mst_shadow;
478 	int _mst_shadow2; // blinking after adding new item
479 	int _candleCounter; // special counter for candle inventory item
480 	int _invMaxCount; // time to turn inventory on
481 	int _invCounter; // turning on counter
482 
483 	void inventoryFlagChange(bool inventoryState);
484 	bool loadAllInv();
485 	void rememberScreenInv();
486 	void prepareInventoryToView();
487 	void drawInvItems();
488 	void displayInventory();
489 	void addInv(int heroId, int item, bool addItemQuiet);
490 	void remInv(int heroId, int item);
491 	void clearInv(int heroId);
492 	void swapInv(int heroId);
493 	void addInvObj();
494 	void makeInvCursor(int itemNr);
495 	void enableOptions(bool checkType);
496 	void checkOptions();
497 	void checkInvOptions();
498 	void openInventoryCheck();
499 
500 	void leftMouseButton();
501 	void rightMouseButton();
502 	void inventoryLeftMouseButton();
503 	void inventoryRightMouseButton();
504 	void dialogLeftMouseButton(byte *string, int dialogSelected);
505 
506 	uint32 _dialogDatSize;
507 	byte *_dialogDat;
508 	byte *_dialogData; // on, off flags for lines of dialog text
509 
510 	byte *_dialogBoxAddr[32]; // adresses of dialog windows
511 	byte *_dialogOptAddr[32]; // adresses of dialog options
512 	int _dialogOptLines[4 * 32]; // numbers of initial dialog lines
513 
514 	byte *_dialogText;
515 	int _dialogLines;
516 	bool _dialogFlag;
517 	int _dialogWidth;
518 	int _dialogHeight;
519 	int _dialogLineSpace;
520 	int _dialogColor1; // color for non-selected options
521 	int _dialogColor2; // color for selected option
522 	Graphics::Surface *_dialogImage;
523 
524 	void createDialogBox(int dialogBoxNr);
525 	void dialogRun();
526 	void talkHero(int slot);
527 	void doTalkAnim(int animNumber, int slot, AnimType animType);
528 
529 	static const uint8 zoomInStep = 8;
530 	void initZoomIn(int slot);
531 	void initZoomOut(int slot);
532 	void doZoomIn(int slot);
533 	void doZoomOut(int slot);
534 	void freeZoomObject(int slot);
535 
536 	static const uint8 kFadeStep = 4;
537 	void blackPalette();
538 	void setPalette(const byte *palette);
539 
540 	int getMob(Common::Array<Mob> &mobList, bool usePriorityList, int posX, int posY);
541 
542 	// 'Throw a rock' mini-game:
543 	static const int16 kCurveLen = 17;
544 	static const int kCelStep = 4;
545 	int16 *_curveData;
546 	int _curvPos;
547 	void makeCurve();
548 	void getCurve();
549 	void mouseWeirdo();
550 
551 	static const uint16 kPowerBarPosX = 288;
552 	static const uint16 kPowerBarPosY = 430;
553 	static const uint8 kPowerBarWidth = 64;
554 	static const uint8 kPowerBarHeight = 16;
555 	static const uint8 kPowerBarBackgroundColor = 0;
556 	static const uint16 kPowerBarGreenPosY = 434;
557 	static const uint8 kPowerBarGreenColor1 = 202;
558 	static const uint8 kPowerBarGreenColor2 = 235;
559 	static const uint8 kPowerBarGreenHeight = 8;
560 	void showPower();
561 
562 	// Pathfinding
563 	static const int16 kPathGridStep = 2;
564 	static const uint32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8;
565 	static const int32 kTracePts = 8000;
566 	static const int32 kPBW = kMaxPicWidth / 16; // PathBitmapWidth
567 	static const int kMinDistance = 2500;
568 
569 	byte *_roomPathBitmap; // PL - Sala
570 	byte *_roomPathBitmapTemp; // PL - SSala
571 	byte *_coordsBufEnd;
572 	byte *_coordsBuf; // optimal path
573 	byte *_coords; // last path point adress from coordsBuf
574 	byte *_coordsBuf2;
575 	byte *_coords2;
576 	byte *_coordsBuf3;
577 	byte *_coords3;
578 	int _traceLineLen;
579 	bool _traceLineFirstPointFlag; // if plotTraceLine after first point
580 	bool _tracePointFirstPointFlag; // if plotTracePoint after first point
581 	byte *_directionTable;
582 	int _shanLen;
583 
584 	byte *_checkBitmapTemp;
585 	byte *_checkBitmap;
586 	int _checkMask;
587 	int _checkX;
588 	int _checkY;
589 
590 	byte *_rembBitmapTemp;
591 	byte *_rembBitmap;
592 	int _rembMask;
593 	int _rembX;
594 	int _rembY;
595 
596 	int _fpX;
597 	int _fpY;
598 
599 	int drawLine(int x0, int y0, int x1, int y1, int (*plotProc)(int, int, void *), void *data);
600 	bool loadPath(const char *resourceName);
601 	byte *makePath(int heroId, int currX, int currY, int destX, int destY);
602 	void findPoint(int x, int y);
603 	int getPixelAddr(byte *pathBitmap, int x, int y);
604 	static int plotTraceLine(int x, int y, void *data);
605 	void specialPlotInside(int x, int y);
606 	bool tracePath(int x1, int y1, int x2, int y2);
607 	Direction makeDirection(int x1, int y1, int x2, int y2);
608 	void specialPlot(int x, int y);
609 	void specialPlot2(int x, int y);
610 	void allocCoords2();
611 	void freeCoords2();
612 	void freeCoords3();
613 	static int plotTracePoint(int x, int y, void *data);
614 	void specialPlotInside2(int x, int y);
615 	void approxPath();
616 	void freeDirectionTable();
617 	void scanDirections();
618 	int scanDirectionsFindNext(byte *coords, int xDiff, int yDiff);
619 	void moveShandria();
620 	void walkTo();
621 	void moveRunHero(int heroId, int x, int y, int dir, bool runHeroFlag);
622 
623 	int leftDownDir();
624 	int leftDir();
625 	int leftUpDir();
626 	int rightDownDir();
627 	int rightDir();
628 	int rightUpDir();
629 	int upLeftDir();
630 	int upDir();
631 	int upRightDir();
632 	int downLeftDir();
633 	int downDir();
634 	int downRightDir();
635 
636 	int cpe();
637 	int checkLeftDownDir();
638 	int checkLeftDir();
639 	int checkDownDir();
640 	int checkUpDir();
641 	int checkRightDir();
642 	int checkLeftUpDir();
643 	int checkRightDownDir();
644 	int checkRightUpDir();
645 
646 private:
647 	bool playNextFLCFrame();
648 	void keyHandler(Common::Event event);
649 	int checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobList, bool usePriorityList);
650 	void drawScreen();
651 	void showTexts(Graphics::Surface *screen);
652 	void init();
653 	void showLogo();
654 	void showAnim(Anim &anim);
655 	void showNormAnims();
656 	void setBackAnim(Anim &backAnim);
657 	void showBackAnims();
658 	void clearBackAnimList();
659 	bool spriteCheck(int sprWidth, int sprHeight, int destX, int destY);
660 	void showSprite(Graphics::Surface *spriteSurface, int destX, int destY, int destZ);
661 	void showSpriteShadow(Graphics::Surface *shadowSurface, int destX, int destY, int destZ);
662 	void showObjects();
663 	void showParallax();
664 	static bool compareDrawNodes(DrawNode d1, DrawNode d2);
665 	void runDrawNodes();
666 	void makeShadowTable(int brightness);
667 	void pausePrinceEngine(int fps = kFPS);
668 
669 	uint32 getTextWidth(const char *s);
670 	void debugEngine(const char *s, ...);
671 
672 	uint8 _cursorNr;
673 
674 	Common::RandomSource *_rnd;
675 	Cursor *_cursor1;
676 	Graphics::Surface *_cursor2;
677 	Cursor *_cursor3;
678 	Debugger *_debugger;
679 	Font *_font;
680 	MusicPlayer *_midiPlayer;
681 
682 	static const int kMaxSamples = 60;
683 	Audio::RewindableAudioStream *_audioStream[kMaxSamples];
684 	Audio::SoundHandle _soundHandle[kMaxSamples];
685 
686 	Common::Array<PScr *> _pscrList;
687 	Common::Array<InvItem> _allInvList;
688 	Common::Array<Mob> _invMobList;
689 
690 	bool _flicLooped;
691 
692 	void mainLoop();
693 
694 };
695 
696 } // End of namespace Prince
697 
698 #endif
699