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 #include "ags/shared/ac/common.h"
24 #include "ags/engine/ac/runtime_defines.h"
25 #include "ags/engine/ac/speech.h"
26 #include "ags/engine/debugging/debug_log.h"
27 #include "ags/shared/ac/game_setup_struct.h"
28 #include "ags/engine/ac/game_state.h"
29 #include "ags/engine/ac/global_audio.h"
30 #include "ags/engine/ac/global_display.h"
31 #include "ags/shared/debugging/out.h"
32 #include "ags/engine/script/script_api.h"
33 #include "ags/engine/script/script_runtime.h"
34 #include "ags/engine/ac/dynobj/script_overlay.h"
35 #include "ags/globals.h"
36 
37 namespace AGS3 {
38 
user_to_internal_skip_speech(SkipSpeechStyle userval)39 int user_to_internal_skip_speech(SkipSpeechStyle userval) {
40 	switch (userval) {
41 	case kSkipSpeechNone:
42 		return SKIP_NONE;
43 	case kSkipSpeechKeyMouseTime:
44 		return SKIP_AUTOTIMER | SKIP_KEYPRESS | SKIP_MOUSECLICK;
45 	case kSkipSpeechKeyTime:
46 		return SKIP_AUTOTIMER | SKIP_KEYPRESS;
47 	case kSkipSpeechTime:
48 		return SKIP_AUTOTIMER;
49 	case kSkipSpeechKeyMouse:
50 		return SKIP_KEYPRESS | SKIP_MOUSECLICK;
51 	case kSkipSpeechMouseTime:
52 		return SKIP_AUTOTIMER | SKIP_MOUSECLICK;
53 	case kSkipSpeechKey:
54 		return SKIP_KEYPRESS;
55 	case kSkipSpeechMouse:
56 		return SKIP_MOUSECLICK;
57 	default:
58 		quit("user_to_internal_skip_speech: unknown userval");
59 		return SKIP_NONE;
60 	}
61 }
62 
internal_skip_speech_to_user(int internal_val)63 SkipSpeechStyle internal_skip_speech_to_user(int internal_val) {
64 	if (internal_val & SKIP_AUTOTIMER) {
65 		internal_val &= ~SKIP_AUTOTIMER;
66 		if (internal_val == (SKIP_KEYPRESS | SKIP_MOUSECLICK)) {
67 			return kSkipSpeechKeyMouseTime;
68 		} else if (internal_val == SKIP_KEYPRESS) {
69 			return kSkipSpeechKeyTime;
70 		} else if (internal_val == SKIP_MOUSECLICK) {
71 			return kSkipSpeechMouseTime;
72 		}
73 		return kSkipSpeechTime;
74 	} else {
75 		if (internal_val == (SKIP_KEYPRESS | SKIP_MOUSECLICK)) {
76 			return kSkipSpeechKeyMouse;
77 		} else if (internal_val == SKIP_KEYPRESS) {
78 			return kSkipSpeechKey;
79 		} else if (internal_val == SKIP_MOUSECLICK) {
80 			return kSkipSpeechMouse;
81 		}
82 	}
83 	return kSkipSpeechNone;
84 }
85 
86 //=============================================================================
87 //
88 // Script API Functions
89 //
90 //=============================================================================
91 
Speech_GetTextOverlay()92 ScriptOverlay *Speech_GetTextOverlay() {
93 	return _GP(play).speech_text_scover;
94 }
95 
Speech_GetPortraitOverlay()96 ScriptOverlay *Speech_GetPortraitOverlay() {
97 	return _GP(play).speech_face_scover;
98 }
99 
Sc_Speech_GetAnimationStopTimeMargin(const RuntimeScriptValue * params,int32_t param_count)100 RuntimeScriptValue Sc_Speech_GetAnimationStopTimeMargin(const RuntimeScriptValue *params, int32_t param_count) {
101 	API_VARGET_INT(_GP(play).close_mouth_speech_time);
102 }
103 
Sc_Speech_SetAnimationStopTimeMargin(const RuntimeScriptValue * params,int32_t param_count)104 RuntimeScriptValue Sc_Speech_SetAnimationStopTimeMargin(const RuntimeScriptValue *params, int32_t param_count) {
105 	API_VARSET_PINT(_GP(play).close_mouth_speech_time);
106 }
107 
Sc_Speech_GetCustomPortraitPlacement(const RuntimeScriptValue * params,int32_t param_count)108 RuntimeScriptValue Sc_Speech_GetCustomPortraitPlacement(const RuntimeScriptValue *params, int32_t param_count) {
109 	API_VARGET_INT(_GP(play).speech_portrait_placement);
110 }
111 
Sc_Speech_SetCustomPortraitPlacement(const RuntimeScriptValue * params,int32_t param_count)112 RuntimeScriptValue Sc_Speech_SetCustomPortraitPlacement(const RuntimeScriptValue *params, int32_t param_count) {
113 	API_VARSET_PINT(_GP(play).speech_portrait_placement);
114 }
115 
Sc_Speech_GetDisplayPostTimeMs(const RuntimeScriptValue * params,int32_t param_count)116 RuntimeScriptValue Sc_Speech_GetDisplayPostTimeMs(const RuntimeScriptValue *params, int32_t param_count) {
117 	API_VARGET_INT(_GP(play).speech_display_post_time_ms);
118 }
119 
Sc_Speech_SetDisplayPostTimeMs(const RuntimeScriptValue * params,int32_t param_count)120 RuntimeScriptValue Sc_Speech_SetDisplayPostTimeMs(const RuntimeScriptValue *params, int32_t param_count) {
121 	API_VARSET_PINT(_GP(play).speech_display_post_time_ms);
122 }
123 
Sc_Speech_GetGlobalSpeechAnimationDelay(const RuntimeScriptValue * params,int32_t param_count)124 RuntimeScriptValue Sc_Speech_GetGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) {
125 	API_VARGET_INT(_GP(play).talkanim_speed);
126 }
127 
Sc_Speech_SetGlobalSpeechAnimationDelay(const RuntimeScriptValue * params,int32_t param_count)128 RuntimeScriptValue Sc_Speech_SetGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) {
129 	if (_GP(game).options[OPT_GLOBALTALKANIMSPD] == 0) {
130 		debug_script_warn("Speech.GlobalSpeechAnimationDelay cannot be set when global speech animation speed is not enabled; set Speech.UseGlobalSpeechAnimationDelay first!");
131 		return RuntimeScriptValue();
132 	}
133 	API_VARSET_PINT(_GP(play).talkanim_speed);
134 }
135 
Sc_Speech_GetPortraitXOffset(const RuntimeScriptValue * params,int32_t param_count)136 RuntimeScriptValue Sc_Speech_GetPortraitXOffset(const RuntimeScriptValue *params, int32_t param_count) {
137 	API_VARGET_INT(_GP(play).speech_portrait_x);
138 }
139 
Sc_Speech_SetPortraitXOffset(const RuntimeScriptValue * params,int32_t param_count)140 RuntimeScriptValue Sc_Speech_SetPortraitXOffset(const RuntimeScriptValue *params, int32_t param_count) {
141 	API_VARSET_PINT(_GP(play).speech_portrait_x);
142 }
143 
Sc_Speech_GetPortraitY(const RuntimeScriptValue * params,int32_t param_count)144 RuntimeScriptValue Sc_Speech_GetPortraitY(const RuntimeScriptValue *params, int32_t param_count) {
145 	API_VARGET_INT(_GP(play).speech_portrait_y);
146 }
147 
Sc_Speech_SetPortraitY(const RuntimeScriptValue * params,int32_t param_count)148 RuntimeScriptValue Sc_Speech_SetPortraitY(const RuntimeScriptValue *params, int32_t param_count) {
149 	API_VARSET_PINT(_GP(play).speech_portrait_y);
150 }
151 
Sc_Speech_GetStyle(const RuntimeScriptValue * params,int32_t param_count)152 RuntimeScriptValue Sc_Speech_GetStyle(const RuntimeScriptValue *params, int32_t param_count) {
153 	API_VARGET_INT(_GP(game).options[OPT_SPEECHTYPE]);
154 }
155 
156 extern RuntimeScriptValue Sc_SetSpeechStyle(const RuntimeScriptValue *params, int32_t param_count);
157 
Sc_Speech_GetSkipKey(const RuntimeScriptValue * params,int32_t param_count)158 RuntimeScriptValue Sc_Speech_GetSkipKey(const RuntimeScriptValue *params, int32_t param_count) {
159 	API_VARGET_INT(_GP(play).skip_speech_specific_key);
160 }
161 
Sc_Speech_SetSkipKey(const RuntimeScriptValue * params,int32_t param_count)162 RuntimeScriptValue Sc_Speech_SetSkipKey(const RuntimeScriptValue *params, int32_t param_count) {
163 	API_VARSET_PINT(_GP(play).skip_speech_specific_key);
164 }
165 
Sc_Speech_GetSkipStyle(const RuntimeScriptValue * params,int32_t param_count)166 RuntimeScriptValue Sc_Speech_GetSkipStyle(const RuntimeScriptValue *params, int32_t param_count) {
167 	API_SCALL_INT(GetSkipSpeech);
168 }
169 
170 extern RuntimeScriptValue Sc_SetSkipSpeech(const RuntimeScriptValue *params, int32_t param_count);
171 
Sc_Speech_GetTextAlignment(const RuntimeScriptValue * params,int32_t param_count)172 RuntimeScriptValue Sc_Speech_GetTextAlignment(const RuntimeScriptValue *params, int32_t param_count) {
173 	API_VARGET_INT(_GP(play).speech_text_align);
174 }
175 
Sc_Speech_SetTextAlignment_Old(const RuntimeScriptValue * params,int32_t param_count)176 RuntimeScriptValue Sc_Speech_SetTextAlignment_Old(const RuntimeScriptValue *params, int32_t param_count) {
177 	ASSERT_VARIABLE_VALUE(_GP(play).speech_text_align);
178 	_GP(play).speech_text_align = ReadScriptAlignment(params[0].IValue);
179 	return RuntimeScriptValue();
180 }
181 
Sc_Speech_SetTextAlignment(const RuntimeScriptValue * params,int32_t param_count)182 RuntimeScriptValue Sc_Speech_SetTextAlignment(const RuntimeScriptValue *params, int32_t param_count) {
183 	ASSERT_VARIABLE_VALUE(_GP(play).speech_text_align);
184 	_GP(play).speech_text_align = (HorAlignment)params[0].IValue;
185 	return RuntimeScriptValue();
186 }
187 
Sc_Speech_GetUseGlobalSpeechAnimationDelay(const RuntimeScriptValue * params,int32_t param_count)188 RuntimeScriptValue Sc_Speech_GetUseGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) {
189 	API_VARGET_INT(_GP(game).options[OPT_GLOBALTALKANIMSPD]);
190 }
191 
Sc_Speech_SetUseGlobalSpeechAnimationDelay(const RuntimeScriptValue * params,int32_t param_count)192 RuntimeScriptValue Sc_Speech_SetUseGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) {
193 	API_VARSET_PINT(_GP(game).options[OPT_GLOBALTALKANIMSPD]);
194 }
195 
Sc_Speech_GetVoiceMode(const RuntimeScriptValue * params,int32_t param_count)196 RuntimeScriptValue Sc_Speech_GetVoiceMode(const RuntimeScriptValue *params, int32_t param_count) {
197 	API_SCALL_INT(GetVoiceMode);
198 }
199 
Sc_Speech_GetTextOverlay(const RuntimeScriptValue * params,int32_t param_count)200 RuntimeScriptValue Sc_Speech_GetTextOverlay(const RuntimeScriptValue *params, int32_t param_count) {
201 	API_SCALL_OBJAUTO(ScriptOverlay, Speech_GetTextOverlay);
202 }
203 
Sc_Speech_GetPortraitOverlay(const RuntimeScriptValue * params,int32_t param_count)204 RuntimeScriptValue Sc_Speech_GetPortraitOverlay(const RuntimeScriptValue *params, int32_t param_count) {
205 	API_SCALL_OBJAUTO(ScriptOverlay, Speech_GetPortraitOverlay);
206 }
207 
208 extern RuntimeScriptValue Sc_SetVoiceMode(const RuntimeScriptValue *params, int32_t param_count);
209 
RegisterSpeechAPI(ScriptAPIVersion base_api,ScriptAPIVersion compat_api)210 void RegisterSpeechAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) {
211 	ccAddExternalStaticFunction("Speech::get_AnimationStopTimeMargin", Sc_Speech_GetAnimationStopTimeMargin);
212 	ccAddExternalStaticFunction("Speech::set_AnimationStopTimeMargin", Sc_Speech_SetAnimationStopTimeMargin);
213 	ccAddExternalStaticFunction("Speech::get_CustomPortraitPlacement", Sc_Speech_GetCustomPortraitPlacement);
214 	ccAddExternalStaticFunction("Speech::set_CustomPortraitPlacement", Sc_Speech_SetCustomPortraitPlacement);
215 	ccAddExternalStaticFunction("Speech::get_DisplayPostTimeMs", Sc_Speech_GetDisplayPostTimeMs);
216 	ccAddExternalStaticFunction("Speech::set_DisplayPostTimeMs", Sc_Speech_SetDisplayPostTimeMs);
217 	ccAddExternalStaticFunction("Speech::get_GlobalSpeechAnimationDelay", Sc_Speech_GetGlobalSpeechAnimationDelay);
218 	ccAddExternalStaticFunction("Speech::set_GlobalSpeechAnimationDelay", Sc_Speech_SetGlobalSpeechAnimationDelay);
219 	ccAddExternalStaticFunction("Speech::get_PortraitOverlay", Sc_Speech_GetPortraitOverlay);
220 	ccAddExternalStaticFunction("Speech::get_PortraitXOffset", Sc_Speech_GetPortraitXOffset);
221 	ccAddExternalStaticFunction("Speech::set_PortraitXOffset", Sc_Speech_SetPortraitXOffset);
222 	ccAddExternalStaticFunction("Speech::get_PortraitY", Sc_Speech_GetPortraitY);
223 	ccAddExternalStaticFunction("Speech::set_PortraitY", Sc_Speech_SetPortraitY);
224 	ccAddExternalStaticFunction("Speech::get_SkipKey", Sc_Speech_GetSkipKey);
225 	ccAddExternalStaticFunction("Speech::set_SkipKey", Sc_Speech_SetSkipKey);
226 	ccAddExternalStaticFunction("Speech::get_SkipStyle", Sc_Speech_GetSkipStyle);
227 	ccAddExternalStaticFunction("Speech::set_SkipStyle", Sc_SetSkipSpeech);
228 	ccAddExternalStaticFunction("Speech::get_Style", Sc_Speech_GetStyle);
229 	ccAddExternalStaticFunction("Speech::set_Style", Sc_SetSpeechStyle);
230 	ccAddExternalStaticFunction("Speech::get_TextAlignment", Sc_Speech_GetTextAlignment);
231 	if (base_api < kScriptAPI_v350)
232 		ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment_Old);
233 	else
234 		ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment);
235 	ccAddExternalStaticFunction("Speech::get_TextOverlay", Sc_Speech_GetTextOverlay);
236 	ccAddExternalStaticFunction("Speech::get_UseGlobalSpeechAnimationDelay", Sc_Speech_GetUseGlobalSpeechAnimationDelay);
237 	ccAddExternalStaticFunction("Speech::set_UseGlobalSpeechAnimationDelay", Sc_Speech_SetUseGlobalSpeechAnimationDelay);
238 	ccAddExternalStaticFunction("Speech::get_VoiceMode", Sc_Speech_GetVoiceMode);
239 	ccAddExternalStaticFunction("Speech::set_VoiceMode", Sc_SetVoiceMode);
240 
241 	/* -- Don't register more unsafe plugin symbols until new plugin interface is designed --*/
242 }
243 
244 } // namespace AGS3
245