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 /*
24  * This code is based on original Tony Tough source code
25  *
26  * Copyright (c) 1997-2003 Nayma Software
27  */
28 
29 #ifndef TONY_LOC_H
30 #define TONY_LOC_H
31 
32 #include "common/scummsys.h"
33 #include "common/system.h"
34 #include "common/file.h"
35 #include "tony/sound.h"
36 #include "tony/utils.h"
37 
38 namespace Tony {
39 
40 /****************************************************************************\
41 *       Various defines
42 \****************************************************************************/
43 
44 /**
45  * Valid color modes
46  */
47 typedef enum {
48 	CM_256,
49 	CM_65K
50 } RMColorMode;
51 
52 /****************************************************************************\
53 *       Class declarations
54 \****************************************************************************/
55 
56 /**
57  * Generic palette
58  */
59 class RMPalette {
60 public:
61 	byte _data[1024];
62 
63 public:
64 	void readFromStream(Common::ReadStream &ds);
65 };
66 
67 /**
68  * Sound effect of an object
69  */
70 class RMSfx {
71 public:
72 	Common::String _name;
73 	FPSfx *_fx;
74 	bool _bPlayingLoop;
75 
76 public:
77 	RMSfx();
78 	virtual ~RMSfx();
79 
80 	void play(bool bLoop = false);
81 	void setVolume(int vol);
82 	void pause(bool bPause);
83 	void stop();
84 
85 	void readFromStream(Common::ReadStream &ds, bool bLOX = false);
86 };
87 
88 /**
89  * Object pattern
90  */
91 class RMPattern {
92 public:
93 	// Type of slot
94 	enum RMSlotType {
95 		DUMMY1 = 0,
96 		DUMMY2,
97 		SPRITE,
98 		SOUND,
99 		COMMAND,
100 		SPECIAL
101 	};
102 
103 	// Class slot
104 	class RMSlot {
105 	private:
106 		RMPoint _pos; // Child co-ordinates
107 
108 	public:
109 		RMSlotType _type;
110 		int _data;
111 		byte _flag;
112 
113 	public:
pos()114 		RMPoint pos() {
115 			return _pos;
116 		}
117 
118 		void readFromStream(Common::ReadStream &ds, bool bLOX = false);
119 	};
120 
121 public:
122 	Common::String _name;
123 
124 private:
125 	int _speed;
126 	RMPoint _pos; // Parent coordinates
127 	RMPoint _curPos; // Parent + child coordinates
128 	int _bLoop;
129 	int _nSlots;
130 	int _nCurSlot;
131 	int _nCurSprite;
132 
133 	RMSlot *_slots;
134 
135 	uint32 _nStartTime;
136 
137 public:
138 	RMPattern();
139 	virtual ~RMPattern();
140 
141 	// A warning that the pattern now and the current
142 	int init(RMSfx *sfx, bool bPlayP0 = false, byte *bFlag = NULL);
143 
144 	// Update the pattern, checking to see if it's time to change slot and executing
145 	// any associated commands
146 	int update(uint32 hEndPattern, byte &bFlag, RMSfx *sfx);
147 
148 	// Stop a sound effect
149 	void stopSfx(RMSfx *sfx);
150 
151 	// Reads the position of the pattern
152 	RMPoint pos();
153 
154 	void readFromStream(Common::ReadStream &ds, bool bLOX);
155 
156 private:
157 	void updateCoord();
158 };
159 
160 /**
161  * Sprite (frame) animation of an item
162  */
163 class RMSprite : public RMGfxTask {
164 public:
165 	Common::String _name;
166 	RMRect _rcBox;
167 
168 protected:
169 	RMGfxSourceBuffer *_buf;
170 
171 public:
172 	RMSprite();
173 	virtual ~RMSprite();
174 
175 	void init(RMGfxSourceBuffer *buf);
176 	virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
177 	void setPalette(byte *lpBuf);
178 	void getSizeFromStream(Common::SeekableReadStream &ds, int *dimx, int *dimy);
179 	void LOXGetSizeFromStream(Common::SeekableReadStream &ds, int *dimx, int *dimy);
180 
181 	void readFromStream(Common::SeekableReadStream &ds, bool bLOX = false);
182 };
183 
184 /**
185  * Data on an item
186  */
187 class RMItem : public RMGfxTask {
188 public:
189 	Common::String _name;
190 
191 protected:
192 	int _z;
193 	RMPoint _pos; // Coordinate ancestor
194 	RMColorMode _cm;
195 	RMPoint _curScroll;
196 
197 	byte _FX;
198 	byte _FXparm;
199 
200 	virtual int getCurPattern();
201 
202 private:
203 	int _nCurPattern;
204 	int _mpalCode;
205 	RMPoint _hot;
206 	RMRect _rcBox;
207 	int _nSprites, _nSfx, _nPatterns;
208 	byte _bPal;
209 	RMPalette _pal;
210 
211 	RMSprite *_sprites;
212 	RMSfx *_sfx;
213 	RMPattern *_patterns;
214 
215 	byte _bCurFlag;
216 	int _nCurSprite;
217 	bool _bIsActive;
218 	uint32 _hEndPattern;
219 	bool _bInitCurPattern;
220 
221 public:
222 	RMPoint calculatePos();
223 
224 public:
225 	RMItem();
226 	virtual ~RMItem();
227 
228 	// Process to make the object move on any animations.
229 	// Returns TRUE if it should be redrawn on the next frame
230 	bool doFrame(RMGfxTargetBuffer *bigBuf, bool bAddToList = true);
231 
232 	// Sets the current scrolling position
233 	void setScrollPosition(const RMPoint &scroll);
234 
235 	// Overloading of check whether to remove from active list
236 	virtual void removeThis(CORO_PARAM, bool &result);
237 
238 	// Overloaded Draw
239 	virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
240 
241 	// Overloaded priority: it's based on Z ordering
242 	virtual int priority();
243 
244 	// Pattern number
245 	int numPattern();
246 
247 	// Set anew animation pattern, changing abruptly from the current
248 	virtual void setPattern(int nPattern, bool bPlayP0 = false);
249 
250 	// Set a new status
251 	void setStatus(int nStatus);
252 
253 	bool isIn(const RMPoint &pt, int *size = NULL);
254 	RMPoint getHotspot();
255 	bool getName(Common::String &name);
256 	int mpalCode();
257 
258 	// Unload
259 	void unload();
260 
261 	// Wait for the end of the current pattern
262 	void waitForEndPattern(CORO_PARAM, uint32 hCustomSkip = CORO_INVALID_PID_VALUE);
263 
264 	// Sets a new hotspot fro the object
265 	void changeHotspot(const RMPoint &pt);
266 
267 	void setInitCurPattern(bool status);
268 
269 	void playSfx(int nSfx);
270 
271 	void readFromStream(Common::SeekableReadStream &ds, bool bLOX = false);
272 
273 	void pauseSound(bool bPause);
274 
275 protected:
276 	// Create a primitive that has as it's task this item
277 	virtual RMGfxPrimitive *newItemPrimitive();
278 
279 	// Allocate memory for the sprites
280 	virtual RMGfxSourceBuffer *newItemSpriteBuffer(int dimx, int dimy, bool bPreRLE);
281 };
282 
283 #define MAXBOXES 50 // Maximum number of allowed boxes
284 #define MAXHOTSPOT 20 // Maximum nimber of allowed hotspots
285 
286 class RMBox {
287 public:
288 	struct Hotspot {
289 		int _hotx, _hoty; // Hotspot coordinates
290 		int _destination; // Hotspot destination
291 	};
292 
293 public:
294 	int _left, _top, _right, _bottom; // Vertici bounding boxes
295 	int _adj[MAXBOXES];               // List of adjacent bounding boxes
296 	int _numHotspot;                  // Hotspot number
297 	uint8 _destZ;                     // Z value for the bounding box
298 	Hotspot _hotspot[MAXHOTSPOT];     // List of hotspots
299 
300 	bool _bActive;
301 	bool _bReversed;
302 
303 	void readFromStream(Common::ReadStream &ds);
304 };
305 
306 class RMBoxLoc {
307 public:
308 	int _numbBox;
309 	RMBox *_boxes;
310 
311 	void readFromStream(Common::ReadStream &ds);
312 
313 public:
314 	RMBoxLoc();
315 	virtual ~RMBoxLoc();
316 
317 	void recalcAllAdj();
318 };
319 
320 #define GAME_BOXES_SIZE 200
321 
322 class RMGameBoxes {
323 protected:
324 	RMBoxLoc *_allBoxes[GAME_BOXES_SIZE];
325 	int _nLocBoxes;
326 
327 public:
328 	RMGameBoxes();
329 	~RMGameBoxes();
330 
331 	void init();
332 	void close();
333 
334 	// Get binding boxes for a given location
335 	RMBoxLoc *getBoxes(int nLoc);
336 	int getLocBoxesCount() const;
337 
338 	// Return the box which contains a given point
339 	int whichBox(int nLoc, const RMPoint &pt);
340 
341 	// Check whether a point is inside a given box
342 	bool isInBox(int nLoc, int nBox, const RMPoint &pt);
343 
344 	// Change the status of a box
345 	void changeBoxStatus(int nLoc, int nBox, int status);
346 
347 	// Save state handling
348 	int getSaveStateSize();
349 	void saveState(byte *buf);
350 	void loadState(byte *buf);
351 };
352 
353 class RMCharacter : protected RMItem {
354 public:
355 	enum Patterns {
356 		PAT_STANDUP = 1,
357 		PAT_STANDDOWN,
358 		PAT_STANDLEFT,
359 		PAT_STANDRIGHT,
360 		PAT_WALKUP,
361 		PAT_WALKDOWN,
362 		PAT_WALKLEFT,
363 		PAT_WALKRIGHT
364 	};
365 
366 private:
367 	enum CharacterStatus {
368 		STAND,
369 		WALK
370 	};
371 
372 	signed short _walkCount;
373 	int _dx, _dy, _olddx, _olddy;
374 	float _fx, _fy, _slope;
375 	RMPoint _lineStart, _lineEnd, _pathEnd;
376 	signed char _walkSpeed, _walkStatus;
377 	char _minPath;
378 	short _nextBox;
379 	short _path[MAXBOXES];
380 	short _pathLength, _pathCount;
381 	int _curBox;
382 
383 	CharacterStatus _status;
384 	int _curSpeed;
385 	bool _bEndOfPath;
386 	uint32 _hEndOfPath;
387 	OSystem::MutexRef _csMove;
388 	int _curLocation;
389 	bool _bRemoveFromOT;
390 	bool _bMovingWithoutMinpath;
391 	RMGameBoxes *_theBoxes;
392 
393 	RMPoint _fixedScroll;
394 
395 private:
396 	int inWhichBox(const RMPoint &pt);
397 
398 	bool findPath(short source, short destination);
399 	RMPoint searching(char UP, char DOWN, char RIGHT, char LEFT, RMPoint point);
400 	RMPoint nearestPoint(const RMPoint &punto);
401 
402 	void goTo(CORO_PARAM, RMPoint destcoord, bool bReversed = false);
403 	short scanLine(const RMPoint &point);
404 	RMPoint invScanLine(const RMPoint &point);
405 	RMPoint nearestHotSpot(int sourcebox, int destbox);
406 
407 	void newBoxEntered(int nBox);
408 
409 protected:
410 	bool _bMoving;
411 	bool _bDrawNow;
412 	bool _bNeedToStop;
413 
414 public:
415 	RMCharacter();
416 	virtual ~RMCharacter();
417 
418 	void linkToBoxes(RMGameBoxes *theBoxes);
419 
420 	virtual void removeThis(CORO_PARAM, bool &result);
421 
422 	// Update the position of a character
423 	void doFrame(CORO_PARAM, RMGfxTargetBuffer *bigBuf, int loc);
424 
425 	// Overloaded draw
426 	virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
427 
428 	// TRUE if you just stopped
429 	bool endOfPath();
430 
431 	// Change the pattern of a character to STOP
432 	virtual void stop(CORO_PARAM);
433 
434 	// Check if the character is moving
435 	bool isMoving();
436 
437 	// Move the character to a certain position
438 	void move(CORO_PARAM, RMPoint pt, bool *result = NULL);
439 
440 	// Place the character in a certain position WITHOUT moving
441 	void setPosition(const RMPoint &pt, int newloc = -1);
442 
443 	// Wait for the end of movement
444 	void waitForEndMovement(CORO_PARAM);
445 
446 	void setFixedScroll(const RMPoint &fix);
447 	void setSpeed(int speed);
448 };
449 
450 class RMWipe : public RMGfxTask {
451 private:
452 	bool _bFading;
453 	bool _bEndFade;
454 	bool _bUnregister;
455 	uint32 _hUnregistered;
456 	int _nFadeStep;
457 	uint32 _hEndOfFade;
458 	bool _bMustRegister;
459 
460 	RMItem _wip0r;
461 
462 public:
463 	RMWipe();
464 	virtual ~RMWipe();
465 
466 	void doFrame(RMGfxTargetBuffer &bigBuf);
467 	virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
468 
469 	void initFade(int type);
470 	void closeFade();
471 	void waitForFadeEnd(CORO_PARAM);
472 
473 	virtual void unregister();
474 	virtual void removeThis(CORO_PARAM, bool &result);
475 	virtual int priority();
476 };
477 
478 /**
479  * Location
480  */
481 class RMLocation : public RMGfxTaskSetPrior {
482 public:
483 	Common::String _name; // Name
484 
485 private:
486 	RMColorMode _cmode;      // Color mode
487 	RMGfxSourceBuffer *_buf; // Location picture
488 
489 	int _nItems;             // Number of objects
490 	RMItem *_items;          // Objects
491 
492 	RMPoint _curScroll;      // Current scroll position
493 	RMPoint _fixedScroll;
494 
495 	RMPoint _prevScroll;     // Previous scroll position
496 	RMPoint _prevFixedScroll;
497 
498 public:
499 	// @@@@@@@@@@@@@@@@@@@@@@@
500 
501 	RMPoint TEMPTonyStart;
502 	RMPoint TEMPGetTonyStart();
503 
504 	int TEMPNumLoc;
505 	int TEMPGetNumLoc();
506 
507 public:
508 	RMLocation();
509 	virtual ~RMLocation();
510 
511 	// Load variations
512 	bool load(Common::SeekableReadStream &ds);
513 	bool loadLOX(Common::SeekableReadStream &ds);
514 
515 	// Unload
516 	void unload();
517 
518 	// Overloaded draw
519 	virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
520 
521 	// Prepare a frame by drawing the location and all it's items
522 	void doFrame(RMGfxTargetBuffer *bigBuf);
523 
524 	// Return the item at a given point
525 	RMItem *whichItemIsIn(const RMPoint &pt);
526 
527 	// Return the item based on it's MPAL code
528 	RMItem *getItemFromCode(uint32 dwCode);
529 
530 	// Set the current scroll position
531 	void setScrollPosition(const RMPoint &scroll);
532 
533 	// Sets an additinal offset for scrolling
534 	void setFixedScroll(const RMPoint &scroll);
535 
536 	// Update the scrolling coordinates to display the specified point
537 	void updateScrolling(const RMPoint &ptShowThis);
538 
539 	// Read the current scroll position
540 	RMPoint scrollPosition();
541 
542 	// Pause sound
543 	void pauseSound(bool bPause);
544 };
545 
546 /**
547  * MPAL message, composed of more ASCIIZ
548  */
549 class RMMessage {
550 private:
551 	char *_lpMessage;
552 	char *_lpPeriods[256];
553 	int _nPeriods;
554 
555 private:
556 	void parseMessage();
557 
558 public:
559 	RMMessage();
560 	RMMessage(uint32 dwId);
561 	virtual ~RMMessage();
562 
563 	void load(uint32 dwId);
564 	bool isValid();
565 	int numPeriods();
566 	char *period(int num);
567 	char *operator[](int num);
568 };
569 
570 } // End of namespace Tony
571 
572 #endif /* TONY_H */
573