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  * aint32 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  * Based on the original sources
23  *   Faery Tale II -- The Halls of the Dead
24  *   (c) 1993-1996 The Wyrmkeep Entertainment Co.
25  */
26 
27 #ifndef SAGA2_SPEECH_H
28 #define SAGA2_SPEECH_H
29 
30 #include "saga2/objects.h"
31 
32 namespace Saga2 {
33 
34 #define MAX_SPEECH_PTRS 20
35 #define MAX_SAMPLES     50
36 #define CHARSPERSECOND  22
37 #define SHORTEST_DURATION   TICKSPERSECOND
38 
39 void    TileToScreenCoords(const TilePoint &tp, Point16 &p);
40 void    TileToScreenCoords(const TilePoint &tp, StaticPoint16 &p);
41 void    updateSpeech();
42 extern  TilePoint centerActorCoords(void);
43 bool    isVisible(GameObject *obj);
44 
45 #ifdef FRANKC
46 void    sentenceGenerator(char *);
47 void    abortSpeech(void);
48 void    abortAllSpeeches(void);
49 void    queueActorSpeech(
50     GameObject          *obj,
51     char                *text,
52     int                 count,
53     int32               sampleID,
54     int                 flags
55 );
56 #endif
57 
58 bool sayVoice(uint32 s[]);
59 
60 //  REM: This function is no longer used by the speech code,
61 //  but it may be useful for other things.
62 
63 extern int16        speechButtonCount;      // count of speech buttons
64 
65 //  Actor speech enums -- move these to include file
66 
67 enum {
68 	speakContinued  = (1 << 0),         // Append next speech
69 	speakNoAnimate  = (1 << 1),         // Don't animate speaking
70 	speakWait       = (1 << 2),         // wait until speech finished
71 	speakLock       = (1 << 3)          // lock UI while speech in progress
72 };
73 
74 class Speech {
75 private:
76 	friend class SpeechTaskList;
77 	friend void setNextActive();
78 	friend void deleteSpeech(ObjectID id);          // voice sound sample ID
79 	friend void updateSpeech();
80 	friend void queueActorSpeech(
81 	    GameObject          *obj,
82 	    char                *text,
83 	    int                 count,
84 	    int32               sampleID,
85 	    int                 flags
86 	);
87 
88 	int16               sampleCount,        // number of sound samples
89 	                    charCount;          // number of characters in buffer
90 
91 	Rect16              bounds;             // bounds of speech.
92 	uint16              penColor,           // penColor to draw in
93 	                    outlineColor;       // pen color for outline
94 
95 	ObjectID            objID;              // ID of speaking object
96 	ThreadID            thread;             // SAGA thread to wake up when done
97 
98 	int16               speechFlags;        // flags from speaking
99 	uint32              sampleID[MAX_SAMPLES];// voice sound sample ID
100 	char                speechBuffer[512];// longest possible speech
101 
102 public:
103 	int16               selectedButton;     // which button was hit
104 	gPixelMap           _speechImage;
105 	gPort               _textPort;
106 
107 private:
108 	//  Reconstruct this SpeechTask from an archive buffer
109 	void read(Common::InSaveFile *in);
110 
111 	//  Return the number of bytes needed to archive this SpeechTask
112 	int32 archiveSize(void);
113 
114 	//  Archive this SpeechTask in a buffer
115 	void *archive(void *buf);
116 
117 	void write(Common::MemoryWriteStreamDynamic *out);
118 
119 	bool setupActive(void);                  // render speech into temp image
120 	bool displayText(void);
121 	int16 fits(int16 space);
122 	void setWidth(void);
123 	bool calcPosition(StaticPoint16 &p);       // calculate position
124 	void remove(void);                   //  Remove from active list
125 
126 public:
127 
128 	enum SpeechFlags {
129 		spNoAnimate     = (1 << 0),         //  Don't animate actor
130 		spHasVoice      = (1 << 1),         //  The audio interface is playing this voice
131 		spQueued        = (1 << 2),         //  In active queue
132 		spActive        = (1 << 3),         //  Is current active speech
133 		spLock          = (1 << 4)          //  Lock UI while speaking
134 	};
135 
136 	// remove speech, dealloc resources
137 	void dispose(void);
138 
139 	//  Append text and samples to speech
140 	bool append(char *text, int32 sampID);
141 
142 	//  Move speech to active list
143 	bool activate(void);
144 
145 	//  Set speech to wake up thread when done
setWakeUp(ThreadID th)146 	void setWakeUp(ThreadID th) {
147 		thread = th;
148 	}
149 
150 	//  See if its time to kill it
151 	bool longEnough(void);
152 
153 	//  Abort the current speech.
154 	void abortSpeech(void);
155 };
156 
157 class SpeechTaskList {
158 	friend void setNextActive();
159 	friend void deleteSpeech(ObjectID id);          // voice sound sample ID
160 	friend void updateSpeech();
161 	friend class    Speech;
162 	friend void queueActorSpeech(
163 	    GameObject          *obj,
164 	    char                *text,
165 	    int                 count,
166 	    int32               sampleID,
167 	    int                 flags
168 	);
169 
170 	Common::List<Speech *> _list,
171 	                       _inactiveList;
172 
173 	int8            lockFlag;
174 
175 	void SetLock(int newState);
176 
177 public:
178 
179 	//  Constructor
180 	SpeechTaskList(void);
181 
182 	//  Constructor -- reconstruct from archive buffer
183 	SpeechTaskList(void **buf);
184 
185 	SpeechTaskList(Common::InSaveFile *in);
186 
187 	//  Return the number of bytes needed to archive the speech tasks
188 	int32 archiveSize(void);
189 
190 	//  Create an archive of the speech tasks in an archive buffer
191 	void *archive(void *buf);
192 
193 	void write(Common::MemoryWriteStreamDynamic *out);
194 
195 	//  Cleanup the speech tasks
196 	void cleanup(void);
197 
198 	//  Allocate a new speech task
199 	Speech *newTask(ObjectID id, uint16 flags);
200 
201 	//  Find a non-active speech for a given actor
202 	Speech *findSpeech(ObjectID id);
203 
currentActive(void)204 	Speech *currentActive(void) {
205 		if (_list.size() > 0)
206 			return _list.front();
207 		return nullptr;
208 	}
209 
activeCount(void)210 	int32 activeCount(void) {
211 		return _list.size();
212 	}
213 
speechCount(void)214 	int speechCount(void) {
215 		return _list.size() + _inactiveList.size();
216 	}
217 
218 	void remove(Speech *p);
219 };
220 
221 extern SpeechTaskList &speechList;
222 
223 
224 //  Initialize the speech task list
225 void initSpeechTasks(void);
226 
227 //  Save the speech tasks in a save file
228 void saveSpeechTasks(Common::OutSaveFile *outS);
229 void loadSpeechTasks(Common::InSaveFile *in, int32 chunkSize);
230 
231 //  Cleanup the speech task list
232 void cleanupSpeechTasks(void);
233 
234 } // end of namespace Saga2
235 
236 #endif
237