1 #ifndef __TALKING_H_
2 #define __TALKING_H_
3 
4 #include "JA2Types.h"
5 #include "Types.h"
6 #include <string_theory/string>
7 
8 class SGPVObject;
9 class SGPVSurface;
10 struct GROUP;
11 struct SOLDIERTYPE;
12 struct VIDEO_OVERLAY;
13 
14 #define NO_EXPRESSION				0
15 #define BLINKING				1
16 #define ANGRY					2
17 #define SURPRISED				3
18 
19 // Defines
20 #define NUM_FACE_SLOTS				50
21 
22 #define FACE_AUTO_DISPLAY_BUFFER		0
23 #define FACE_AUTO_RESTORE_BUFFER		0
24 
25 // FLAGS....
26 #define FACE_BIGFACE				0x00000001 // A BIGFACE instead of small face
27 #define FACE_POTENTIAL_KEYWAIT			0x00000002 // If the option is set, will not stop face until key pressed
28 #define FACE_PCTRIGGER_NPC			0x00000004 // This face has to trigger an NPC after being done
29 #define FACE_INACTIVE_HANDLED_ELSEWHERE	0x00000008	// This face has been setup and any disable should be done
30 								// Externally
31 #define FACE_TRIGGER_PREBATTLE_INT		0x00000010
32 #define FACE_SHOW_WHITE_HILIGHT		0x00000020 // Show highlight around face
33 #define FACE_FORCE_SMALL			0x00000040 // force to small face
34 #define FACE_MODAL				0x00000080 // make game modal
35 #define FACE_MAKEACTIVE_ONCE_DONE		0x00000100
36 #define FACE_SHOW_MOVING_HILIGHT		0x00000200
37 #define FACE_REDRAW_WHOLE_FACE_NEXT_FRAME	0x00000400	// Redraw the complete face next frame
38 
39 #define FACE_DRAW_TEXT_OVER			2
40 #define FACE_ERASE_TEXT_OVER			1
41 #define FACE_NO_TEXT_OVER			0
42 
43 
44 struct AUDIO_GAP
45 {
46 	UINT32 start;
47 	UINT32 end;
48 };
49 
50 // This is a structure that will contain data about the gaps in a particular
51 // wave file
52 struct AudioGapList
53 {
54 	AUDIO_GAP*       gaps; // Pointer to gap array
55 	const AUDIO_GAP* end;  // Pointer one past the end of the gap array
56 };
57 
58 
59 struct FACETYPE
60 {
61 	UINT32  uiFlags; // Basic flags
62 	BOOLEAN fAllocated; //Allocated or not
63 	BOOLEAN fTalking; //Set to true if face is talking ( can be sitting for user input to esc )
64 	BOOLEAN fAnimatingTalking; // Set if the face is animating right now
65 	BOOLEAN fDisabled; // Not active
66 	BOOLEAN fValidSpeech;
67 	BOOLEAN fInvalidAnim;
68 
69 	UINT32  uiTalkingDuration; // A delay based on text length for how long to talk if no speech
70 	UINT32  uiTalkingTimer; // A timer to handle delay when no speech file
71 	UINT32  uiTalkingFromVeryBeginningTimer; // Timer from very beginning of talking...
72 
73 	BOOLEAN fFinishTalking; // A flag to indicate we want to delay after speech done
74 
75 	VIDEO_OVERLAY* video_overlay; // Value for video overlay ( not used too much )
76 
77 	UINT32  uiSoundID; // Sound ID if one being played
78 	SOLDIERTYPE* soldier;                     // Soldier if one specified
79 	UINT8   ubCharacterNum; // Profile ID num
80 
81 	UINT16  usFaceX; // X location to render face
82 	UINT16  usFaceY; // Y location to render face
83 	UINT16  usFaceWidth;
84 	UINT16  usFaceHeight;
85 	SGPVSurface* uiAutoDisplayBuffer; // Display buffer for face
86 	SGPVSurface* uiAutoRestoreBuffer; // Restore buffer
87 	BOOLEAN fAutoRestoreBuffer; // Flag to indicate our own restorebuffer or not
88 	BOOLEAN fAutoDisplayBuffer; // Flag to indicate our own display buffer or not
89 	BOOLEAN fDisplayTextOver; // Boolean indicating to display text on face
90 	BOOLEAN fCanHandleInactiveNow;
91 	ST::string zDisplayText; // String of text that can be displayed
92 
93 	UINT16  usEyesX;
94 	UINT16  usEyesY;
95 	UINT16  usEyesOffsetX;
96 	UINT16  usEyesOffsetY;
97 
98 	UINT16  usEyesWidth;
99 	UINT16  usEyesHeight;
100 
101 	UINT16  usMouthX;
102 	UINT16  usMouthY;
103 	UINT16  usMouthOffsetX;
104 	UINT16  usMouthOffsetY;
105 	UINT16  usMouthWidth;
106 	UINT16  usMouthHeight;
107 
108 	UINT16  sEyeFrame;
109 	INT8    ubEyeWait;
110 	UINT32  uiEyelast;
111 	UINT32  uiEyeDelay;
112 	UINT32  uiBlinkFrequency;
113 	UINT32  uiExpressionFrequency;
114 
115 	UINT8   ubExpression;
116 
117 	INT8    bOldSoldierLife;
118 	INT8    bOldActionPoints;
119 	INT8    bOldAssignment;
120 	INT8    ubOldServiceCount;
121 	const SOLDIERTYPE* old_service_partner;
122 
123 	UINT16   sMouthFrame;
124 	UINT32   uiMouthlast;
125 	UINT32   uiMouthDelay;
126 
127 	UINT32   uiLastBlink;
128 	UINT32   uiLastExpression;
129 
130 	SGPVObject* uiVideoObject;
131 
132 	BOOLEAN fCompatibleItems;
133 	BOOLEAN fOldCompatibleItems;
134 	BOOLEAN bOldStealthMode;
135 	INT8    bOldOppCnt;
136 
137 	AudioGapList GapList;
138 
139 	union // XXX TODO001E ugly
140 	{
141 		struct // Used for FACE_PCTRIGGER_NPC
142 		{
143 			ProfileID npc;
144 			UINT8     record;
145 		} trigger;
146 		struct // Used for FACE_TRIGGER_PREBATTLE_INT
147 		{
148 			GROUP* group;
149 		} initiating_battle;
150 	} u;
151 };
152 
153 // FACE HANDLING
154 //
155 // Faces are done like this: Call
156 FACETYPE& InitFace(ProfileID id, SOLDIERTYPE* s, UINT32 uiInitFlags);
157 // The first parameter is the profile ID and the second is the soldier (which
158 // for most cases will be NULL if the face is not created from a SOLDIERTYPE).
159 // This function allocates a slot in the table for the face, loads its STI file,
160 // sets some values for X,Y locations of eyes from the profile. Does not make
161 // the face visible or anything like that
162 
163 
164 // Removes the face from the internal table, deletes any memory allocated if any.
165 void DeleteFace(FACETYPE*);
166 
167 // IF you want to setup the face for automatic eye blinking, mouth movement, you need to call
168 void SetAutoFaceActive(SGPVSurface* display, SGPVSurface* restore, FACETYPE&, UINT16 usFaceX, UINT16 usFaceY);
169 // The first paramter is the display buffer you wish the face to be rendered on. The second is the
170 // Internal savebuffer which is used to facilitate the rendering of only things which have changed when
171 // blinking. IF the value of FACE_AUTO_RESTORE_BUFFER is given, the system will allocate it's own memory for
172 // a saved buffer and will delete it when finished with it. This function also takes an XY location
173 
174 
175 // To begin rendering of the face sprite, call this function once:
176 void RenderAutoFace(FACETYPE&);
177 // This will draw the face into it's saved buffer and then display it on the display buffer. If the display
178 // buffer given is FRAME_BUFFER, the regions will automatically be dirtied, so no calls to InvalidateRegion()
179 // should be nessesary.
180 
181 // If you want to setup the face to talking, ( most times this call is done in JA2 by other functions, not
182 //directly), you call
183 void SetFaceTalking(FACETYPE& f, const char* zSoundFile, const ST::string& zTextString);
184 // This function will setup appropriate face data and begin the speech process. It can fail if the sound
185 //cannot be played for any reason.
186 
187 // Set some face talking flags without need to play sound
188 void ExternSetFaceTalking(FACETYPE&, UINT32 sound_id);
189 
190 // Once this is done, this function must be called overy gameloop that you want to handle the sprite:
191 void HandleAutoFaces(void);
192 // This will handle all faces set to be auto mamaged by SetAutoFaceActive(). What is does is determines
193 // the best mouth and eye graphic to use. It then renders only the rects nessessary into the display buffer.
194 
195 // If you need to shutoff the face from talking, use the function
196 void ShutupaYoFace(FACETYPE*);
197 void InternalShutupaYoFace(FACETYPE*, BOOLEAN fForce);
198 
199 // This can be used to times when you need process the user hitting <ESC> to cancel the speech, etc. It will
200 // shutoff any playing sound sample
201 
202 // If you still want the face in memory but want to stop if from being
203 // displayed, or handled call
204 void SetAutoFaceInActive(FACETYPE&);
205 
206 // To set all currently allocated faces to either active or incactive, call these
207 void SetAllAutoFacesInactive(void);
208 
209 // FUnctions usually not needed for most uses, but give a finer control over rendering if needed
210 void HandleTalkingAutoFaces(void);
211 
212 
213 
214 
215 // Same Functions but taking soldier first to get profile
216 void InitSoldierFace(SOLDIERTYPE&);
217 void DeleteSoldierFace( SOLDIERTYPE *pSoldier );
218 
219 // To render an allocated face, but one that is independent of its active
220 // status and does not require eye blinking or mouth movements, call
221 void ExternRenderFace(SGPVSurface* buffer, FACETYPE&, INT16 x, INT16 y);
222 
223 void LoadFacesGraphics();
224 void DeleteFacesGraphics();
225 
226 #endif
227