1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 extern "C" {
7 #include <lua.h>
8 #include <lualib.h>
9 #include <lauxlib.h>
10 }
11
12 #include "script.h"
13
14 #include "../core/system.h"
15 #include "../core/console.h"
16 #include "../audio/audio.h"
17
18 #include "../gameflow.h"
19 #include "../engine.h"
20 #include "../world.h"
21
22
Script_ParseAudio(lua_State * lua,struct audio_settings_s * as)23 int Script_ParseAudio(lua_State *lua, struct audio_settings_s *as)
24 {
25 if(lua)
26 {
27 int top = lua_gettop(lua);
28
29 lua_getglobal(lua, "audio");
30 lua_getfield(lua, -1, "music_volume");
31 as->music_volume = lua_tonumber(lua, -1);
32 lua_pop(lua, 1);
33
34 lua_getfield(lua, -1, "sound_volume");
35 as->sound_volume = lua_tonumber(lua, -1);
36 lua_pop(lua, 1);
37
38 lua_getfield(lua, -1, "use_effects");
39 as->use_effects = lua_tointeger(lua, -1);
40 lua_pop(lua, 1);
41
42 lua_getfield(lua, -1, "listener_is_player");
43 as->listener_is_player = lua_tointeger(lua, -1);
44 lua_pop(lua, 1);
45
46 lua_settop(lua, top);
47 return 1;
48 }
49
50 return -1;
51 }
52
53 /*
54 * Specific functions to get specific parameters from script.
55 */
Script_GetGlobalSound(lua_State * lua,int global_sound_id)56 int Script_GetGlobalSound(lua_State *lua, int global_sound_id)
57 {
58 int sound_id = 0;
59
60 if(lua)
61 {
62 int top = lua_gettop(lua);
63 lua_getglobal(lua, "getGlobalSound");
64
65 if(lua_isfunction(lua, -1))
66 {
67 lua_pushinteger(lua, World_GetVersion());
68 lua_pushinteger(lua, global_sound_id);
69 if(lua_CallAndLog(lua, 2, 1, 0))
70 {
71 sound_id = lua_tointeger(lua, -1);
72 }
73 }
74 lua_settop(lua, top);
75 }
76
77 return sound_id;
78 }
79
80
Script_GetSecretTrackNumber(lua_State * lua)81 int Script_GetSecretTrackNumber(lua_State *lua)
82 {
83 lua_Integer track_number = 0;
84
85 if(lua)
86 {
87 int top = lua_gettop(lua);
88 lua_getglobal(lua, "getSecretTrackNumber");
89
90 if(lua_isfunction(lua, -1))
91 {
92 lua_pushinteger(lua, World_GetVersion());
93 if(lua_CallAndLog(lua, 1, 1, 0))
94 {
95 track_number = lua_tointeger(lua, -1);
96 }
97 }
98 lua_settop(lua, top);
99 }
100
101 return (int)track_number;
102 }
103
104
Script_GetNumTracks(lua_State * lua)105 int Script_GetNumTracks(lua_State *lua)
106 {
107 lua_Integer num_tracks = 0;
108
109 if(lua)
110 {
111 int top = lua_gettop(lua);
112 lua_getglobal(lua, "getNumTracks");
113
114 if(lua_isfunction(lua, -1))
115 {
116 lua_pushinteger(lua, World_GetVersion());
117 if(lua_CallAndLog(lua, 1, 1, 0))
118 {
119 num_tracks = lua_tointeger(lua, -1);
120 }
121 }
122 lua_settop(lua, top);
123 }
124
125 return (int)num_tracks;
126 }
127
128
Script_GetOverridedSamplesInfo(lua_State * lua,int * num_samples,int * num_sounds,char * sample_name_mask)129 bool Script_GetOverridedSamplesInfo(lua_State *lua, int *num_samples, int *num_sounds, char *sample_name_mask)
130 {
131 bool result = false;
132
133 if(lua)
134 {
135 int top = lua_gettop(lua);
136 lua_getglobal(lua, "getOverridedSamplesInfo");
137 const char *real_path;
138
139 if(lua_isfunction(lua, -1))
140 {
141 lua_pushinteger(lua, World_GetVersion());
142 if(lua_CallAndLog(lua, 1, 3, 0))
143 {
144 size_t string_length = 0;
145 real_path = lua_tolstring(lua, -1, &string_length);
146 *num_sounds = lua_tointeger(lua, -2);
147 *num_samples = lua_tointeger(lua, -3);
148 strncpy(sample_name_mask, real_path, string_length);
149 result = ((*num_sounds != -1) && (*num_samples != -1) && (strcmp(real_path, "NONE") != 0));
150 }
151 }
152 lua_settop(lua, top);
153 }
154
155 // If Lua environment doesn't exist or script function returned -1 in one of the
156 // fields, it means that corresponding sample override table is missing or not
157 // valid - hence, return false.
158
159 return result;
160 }
161
162
Script_GetOverridedSample(lua_State * lua,int sound_id,int * first_sample_number,int * samples_count)163 bool Script_GetOverridedSample(lua_State *lua, int sound_id, int *first_sample_number, int *samples_count)
164 {
165 bool result = false;
166
167 if(lua)
168 {
169 int top = lua_gettop(lua);
170 lua_getglobal(lua, "getOverridedSample");
171
172 if(lua_isfunction(lua, -1))
173 {
174 lua_pushinteger(lua, World_GetVersion());
175 lua_pushinteger(lua, Gameflow_GetCurrentLevelID());
176 lua_pushinteger(lua, sound_id);
177 if(lua_CallAndLog(lua, 3, 2, 0))
178 {
179 *first_sample_number = (int)lua_tointeger(lua, -2);
180 *samples_count = (int)lua_tointeger(lua, -1);
181 result = ((*first_sample_number != -1) && (*samples_count != -1));
182 }
183 }
184 lua_settop(lua, top);
185 }
186
187 return result;
188 }
189
190
Script_GetSoundtrack(lua_State * lua,int track_index,char * file_path,int file_path_len,int * load_method,int * stream_type)191 bool Script_GetSoundtrack(lua_State *lua, int track_index, char *file_path, int file_path_len, int *load_method, int *stream_type)
192 {
193 bool result = false;
194
195 if(lua)
196 {
197 int top = lua_gettop(lua);
198 const char *real_path;
199
200 lua_getglobal(lua, "getTrackInfo");
201
202 if(lua_isfunction(lua, -1))
203 {
204 lua_pushinteger(lua, World_GetVersion());
205 lua_pushinteger(lua, track_index);
206 if(lua_CallAndLog(lua, 2, 3, 0))
207 {
208 size_t string_length = 0;
209 real_path = lua_tolstring(lua, -3, &string_length);
210 *stream_type = (int)lua_tointeger(lua, -2);
211 *load_method = (int)lua_tointeger(lua, -1);
212
213 // Lua returns constant string pointer, which we can't assign to
214 // provided argument; so we need to straightly copy it.
215
216 strncpy(file_path, Engine_GetBasePath(), file_path_len);
217 strncat(file_path, real_path, file_path_len);
218 result = (*stream_type != -1);
219 }
220 }
221 lua_settop(lua, top);
222 }
223
224 // If Lua wasn't able to extract file path from the script, most likely it means
225 // that entry is broken or missing, or wrong track ID was specified. So we return
226 // FALSE in such cases.
227
228 return result;
229 }
230
231
232 /*
233 * General gameplay functions
234 */
lua_PlayStream(lua_State * lua)235 int lua_PlayStream(lua_State *lua)
236 {
237 int top = lua_gettop(lua);
238
239 if(top >= 1)
240 {
241 int id = lua_tointeger(lua, 1);
242 if(id >= 0)
243 {
244 uint8_t mask = (top >= 2) ? (lua_tointeger(lua, 2)) : (0);
245 Audio_StreamPlay(id, mask);
246 }
247 else
248 {
249 Con_Warning("wrong stream id");
250 }
251 }
252 else
253 {
254 Con_Warning("playStream: expecting arguments (stream_id, (mask))");
255 }
256
257 return 0;
258 }
259
260
lua_PlaySound(lua_State * lua)261 int lua_PlaySound(lua_State *lua)
262 {
263 int top = lua_gettop(lua);
264
265 if(top >= 1)
266 {
267 uint32_t id = lua_tointeger(lua, 1); // uint_t can't been less zero, reduce number of comparations
268 int ent_id = -1;
269 if((top >= 2) && World_GetEntityByID(ent_id = lua_tointeger(lua, 2)) == NULL)
270 {
271 ent_id = -1;
272 }
273
274 int result;
275
276 if(ent_id >= 0)
277 {
278 result = Audio_Send(id, TR_AUDIO_EMITTER_ENTITY, ent_id);
279 }
280 else
281 {
282 result = Audio_Send(id, TR_AUDIO_EMITTER_GLOBAL);
283 }
284
285 if(result < 0)
286 {
287 switch(result)
288 {
289 case TR_AUDIO_SEND_NOCHANNEL:
290 Con_Warning("send ignored: no free channels");
291 break;
292
293 case TR_AUDIO_SEND_NOSAMPLE:
294 Con_Warning("send ignored: no sample");
295 break;
296 }
297 }
298 }
299 else
300 {
301 Con_Warning("playSound: expecting arguments (sound_id, (entity_id))");
302 }
303
304 return 0;
305 }
306
307
lua_StopSound(lua_State * lua)308 int lua_StopSound(lua_State *lua)
309 {
310 int top = lua_gettop(lua);
311
312 if(top >= 1)
313 {
314 uint32_t id = lua_tointeger(lua, 1);
315 int ent_id = -1;
316 if((top >= 2) && World_GetEntityByID(ent_id = lua_tointeger(lua, 2)) == NULL)
317 {
318 ent_id = -1;
319 }
320
321 int result;
322
323 if(ent_id == -1)
324 {
325 result = Audio_Kill(id, TR_AUDIO_EMITTER_GLOBAL);
326 }
327 else
328 {
329 result = Audio_Kill(id, TR_AUDIO_EMITTER_ENTITY, ent_id);
330 }
331
332 if(result < 0)
333 {
334 Con_Warning("audio with id = %d not played", id);
335 }
336 }
337 else
338 {
339 Con_Warning("stopSound: expecting arguments (sound_id, (entity_id))");
340 }
341
342 return 0;
343 }
344
345
Script_LuaRegisterAudioFuncs(lua_State * lua)346 void Script_LuaRegisterAudioFuncs(lua_State *lua)
347 {
348 lua_register(lua, "playSound", lua_PlaySound);
349 lua_register(lua, "stopSound", lua_StopSound);
350 lua_register(lua, "playStream", lua_PlayStream);
351 }
352