Patch to change license to GPL only, from GSR.
[blender.git] / source / gameengine / Ketsji / KX_SoundActuator.cpp
1 /**
2  * KX_SoundActuator.cpp
3  *
4  * $Id$
5  *
6  * ***** BEGIN GPL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL LICENSE BLOCK *****
30  *
31  */
32
33 #include "KX_SoundActuator.h"
34 #include "SND_SoundObject.h"
35 #include "KX_GameObject.h"
36 #include "SND_SoundObject.h"
37 #include "SND_Scene.h" // needed for replication
38 #include <iostream>
39
40 #ifdef HAVE_CONFIG_H
41 #include <config.h>
42 #endif
43
44 /* ------------------------------------------------------------------------- */
45 /* Native functions                                                          */
46 /* ------------------------------------------------------------------------- */
47 KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj,
48                                                                    SND_SoundObject* sndobj,
49                                                                    SND_Scene*   sndscene,
50                                                                    KX_SOUNDACT_TYPE type,
51                                                                    short start,
52                                                                    short end,
53                                                                    PyTypeObject* T)
54                                                                    : SCA_IActuator(gameobj,T)
55 {
56         m_soundObject = sndobj;
57         m_soundScene = sndscene;
58         m_type = type;
59         m_lastEvent = true;
60         m_isplaying = false;
61         m_startFrame = start;
62         m_endFrame = end;
63         m_pino = false;
64         
65
66 }
67
68
69
70 KX_SoundActuator::~KX_SoundActuator()
71 {
72         //m_soundScene->RemoveObject(this->m_soundObject);
73         //(this->m_soundObject)->DeleteWhenFinished();
74         m_soundScene->RemoveActiveObject(m_soundObject);
75 //      m_soundScene->DeleteObjectWhenFinished(m_soundObject);
76         m_soundScene->DeleteObject(m_soundObject);
77 }
78
79
80
81 CValue* KX_SoundActuator::GetReplica()
82 {
83         KX_SoundActuator* replica = new KX_SoundActuator(*this);
84         replica->ProcessReplica();
85         SND_SoundObject* soundobj = new SND_SoundObject(*m_soundObject);
86         replica->setSoundObject(soundobj);
87         m_soundScene->AddObject(soundobj);
88         
89         // this will copy properties and so on...
90         CValue::AddDataToReplica(replica);
91         return replica;
92 };
93
94
95
96 bool KX_SoundActuator::Update(double curtime, bool frame)
97 {
98         if (!frame)
99                 return true;
100         bool result = false;
101
102         // do nothing on negative events, otherwise sounds are played twice!
103         bool bNegativeEvent = IsNegativeEvent();
104
105         RemoveAllEvents();
106
107         if (m_pino)
108         {
109                 bNegativeEvent = true;
110                 m_pino = false;
111         }
112
113         if (bNegativeEvent)
114         {       
115                 // here must be a check if it is still playing
116                 m_isplaying = false;
117
118                 switch (m_type)
119                 {
120                 case KX_SOUNDACT_PLAYSTOP:
121                 case KX_SOUNDACT_LOOPSTOP:
122                 case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
123                         {
124                                 m_soundScene->RemoveActiveObject(m_soundObject);
125                                 break;
126                         }
127                 case KX_SOUNDACT_PLAYEND:
128                         {
129                                 m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED);
130                                 break;
131                         }
132                 default:
133                         // implement me !!
134                         break;
135                 }
136         }
137         else
138         {
139                 if (m_soundObject && !m_isplaying)
140                 {
141                         switch (m_type)
142                         {
143                         case KX_SOUNDACT_LOOPBIDIRECTIONAL:
144                         case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
145                                 {
146                                         m_soundObject->SetLoopMode(SND_LOOP_BIDIRECTIONAL);
147                                         m_soundScene->AddActiveObject(m_soundObject, curtime);
148                                         m_isplaying = true;
149                                         result = true;
150                                         break;
151                                 }
152                         case KX_SOUNDACT_LOOPEND:
153                         case KX_SOUNDACT_LOOPSTOP:
154                                 {
155                                         m_soundObject->SetLoopMode(SND_LOOP_NORMAL);
156                                         m_soundScene->AddActiveObject(m_soundObject, curtime);
157                                         m_isplaying = true;
158                                         result = true;
159                                         break;
160                                 }
161                         case KX_SOUNDACT_PLAYSTOP:
162                         case KX_SOUNDACT_PLAYEND:
163                                 {
164                                         m_soundObject->SetLoopMode(SND_LOOP_OFF);
165                                         m_soundScene->AddActiveObject(m_soundObject, curtime);
166                                         m_isplaying = true;
167                                         result = true;
168                                         break;
169                                 }
170                         default:
171                                 // implement me !!
172                                 break;
173                         }
174                 }
175         }
176
177         if (m_isplaying)
178         {
179                 m_soundObject->SetPosition(((KX_GameObject*)this->GetParent())->NodeGetWorldPosition());
180                 m_soundObject->SetVelocity(((KX_GameObject*)this->GetParent())->GetLinearVelocity());
181                 m_soundObject->SetOrientation(((KX_GameObject*)this->GetParent())->NodeGetWorldOrientation());
182                 result = true;
183         }
184         else
185         {
186                 result = false;
187         }
188
189         if (result && (m_soundObject->IsLifeSpanOver(curtime)) && ((m_type == KX_SOUNDACT_PLAYEND) || (m_type == KX_SOUNDACT_PLAYSTOP)))
190         {
191                 m_pino = true;
192         }
193
194         return result;
195 }
196
197
198
199 void KX_SoundActuator::setSoundObject(class SND_SoundObject* soundobject)
200 {
201         m_soundObject = soundobject;
202 }
203
204
205
206 /* ------------------------------------------------------------------------- */
207 /* Python functions                                                          */
208 /* ------------------------------------------------------------------------- */
209
210
211
212 /* Integration hooks ------------------------------------------------------- */
213 PyTypeObject KX_SoundActuator::Type = {
214         PyObject_HEAD_INIT(&PyType_Type)
215                 0,
216                 "KX_SoundActuator",
217                 sizeof(KX_SoundActuator),
218                 0,
219                 PyDestructor,
220                 0,
221                 __getattr,
222                 __setattr,
223                 0, //&MyPyCompare,
224                 __repr,
225                 0, //&cvalue_as_number,
226                 0,
227                 0,
228                 0,
229                 0
230 };
231
232
233
234 PyParentObject KX_SoundActuator::Parents[] = {
235         &KX_SoundActuator::Type,
236                 &SCA_IActuator::Type,
237                 &SCA_ILogicBrick::Type,
238                 &CValue::Type,
239                 NULL
240 };
241
242
243
244 PyMethodDef KX_SoundActuator::Methods[] = {
245         {"setFilename", (PyCFunction) KX_SoundActuator::sPySetFilename, METH_VARARGS,NULL},
246         {"getFilename", (PyCFunction) KX_SoundActuator::sPyGetFilename, METH_VARARGS,NULL},
247         {"startSound",(PyCFunction) KX_SoundActuator::sPyStartSound,METH_VARARGS,NULL},
248         {"pauseSound",(PyCFunction) KX_SoundActuator::sPyPauseSound,METH_VARARGS,NULL},
249         {"stopSound",(PyCFunction) KX_SoundActuator::sPyStopSound,METH_VARARGS,NULL},
250         {"setGain",(PyCFunction) KX_SoundActuator::sPySetGain,METH_VARARGS,NULL},
251         {"getGain",(PyCFunction) KX_SoundActuator::sPyGetGain,METH_VARARGS,NULL},
252         {"setPitch",(PyCFunction) KX_SoundActuator::sPySetPitch,METH_VARARGS,NULL},
253         {"getPitch",(PyCFunction) KX_SoundActuator::sPyGetPitch,METH_VARARGS,NULL},
254         {"setRollOffFactor",(PyCFunction) KX_SoundActuator::sPySetRollOffFactor,METH_VARARGS,NULL},
255         {"getRollOffFactor",(PyCFunction) KX_SoundActuator::sPyGetRollOffFactor,METH_VARARGS,NULL},
256         {"setLooping",(PyCFunction) KX_SoundActuator::sPySetLooping,METH_VARARGS,NULL},
257         {"getLooping",(PyCFunction) KX_SoundActuator::sPyGetLooping,METH_VARARGS,NULL},
258         {"setPosition",(PyCFunction) KX_SoundActuator::sPySetPosition,METH_VARARGS,NULL},
259         {"setVelocity",(PyCFunction) KX_SoundActuator::sPySetVelocity,METH_VARARGS,NULL},
260         {"setOrientation",(PyCFunction) KX_SoundActuator::sPySetOrientation,METH_VARARGS,NULL},
261         {"setType",(PyCFunction) KX_SoundActuator::sPySetType,METH_VARARGS,NULL},
262         {"getType",(PyCFunction) KX_SoundActuator::sPyGetType,METH_VARARGS,NULL},
263         {NULL,NULL,NULL,NULL} //Sentinel
264 };
265
266
267
268 PyObject* KX_SoundActuator::_getattr(const STR_String& attr)
269 {
270         _getattr_up(SCA_IActuator);
271 }
272
273
274
275 PyObject* KX_SoundActuator::PySetFilename(PyObject* self, PyObject* args, PyObject* kwds)
276 {
277         char *soundName = NULL;
278         // void *soundPointer = NULL; /*unused*/
279         
280         if (!PyArg_ParseTuple(args, "s", &soundName))
281                 return NULL;
282
283         Py_Return;
284 }
285
286
287
288 PyObject* KX_SoundActuator::PyGetFilename(PyObject* self, PyObject* args, PyObject* kwds)
289 {
290         STR_String objectname = m_soundObject->GetObjectName();
291         char* name = objectname.Ptr();
292         
293         if (!name) {
294                 Py_Return;                                      /* internal error */
295         } else
296                 return PyString_FromString(name);
297 }
298
299
300
301 PyObject* KX_SoundActuator::PyStartSound(PyObject* self, PyObject* args, PyObject* kwds)
302 {
303         m_soundObject->StartSound();    
304         Py_Return;
305 }         
306
307
308
309 PyObject* KX_SoundActuator::PyPauseSound(PyObject* self, PyObject* args, PyObject* kwds)
310 {
311         m_soundObject->PauseSound();    
312         Py_Return;
313
314
315
316
317 PyObject* KX_SoundActuator::PyStopSound(PyObject* self, PyObject* args, PyObject* kwds)
318 {
319         m_soundObject->StopSound();     
320         Py_Return;
321 }
322
323
324
325 PyObject* KX_SoundActuator::PySetGain(PyObject* self, PyObject* args, PyObject* kwds)
326 {
327         float gain = 1.0;
328         if (!PyArg_ParseTuple(args, "f", &gain))
329                 return NULL;
330         
331         m_soundObject->SetGain(gain);
332         
333         Py_Return;
334 }         
335
336
337
338 PyObject* KX_SoundActuator::PyGetGain(PyObject* self, PyObject* args, PyObject* kwds)
339 {
340         float gain = m_soundObject->GetGain();
341         PyObject* result = PyFloat_FromDouble(gain);
342         
343         return result;
344 }
345
346
347
348 PyObject* KX_SoundActuator::PySetPitch(PyObject* self, PyObject* args, PyObject* kwds)
349 {
350         float pitch = 1.0;
351         if (!PyArg_ParseTuple(args, "f", &pitch))
352                 return NULL;
353         
354         m_soundObject->SetPitch(pitch);
355         
356         Py_Return;
357 }         
358
359
360
361 PyObject* KX_SoundActuator::PyGetPitch(PyObject* self, PyObject* args, PyObject* kwds)
362 {
363         float pitch = m_soundObject->GetPitch();
364         PyObject* result = PyFloat_FromDouble(pitch);
365         
366         return result;
367 }
368
369
370
371 PyObject* KX_SoundActuator::PySetRollOffFactor(PyObject* self, PyObject* args, PyObject* kwds)
372 {
373         float rollofffactor = 1.0;
374         if (!PyArg_ParseTuple(args, "f", &rollofffactor))
375                 return NULL;
376         
377         m_soundObject->SetRollOffFactor(rollofffactor);
378
379         Py_Return;
380 }         
381
382
383
384 PyObject* KX_SoundActuator::PyGetRollOffFactor(PyObject* self, PyObject* args, PyObject* kwds)
385 {
386         float rollofffactor = m_soundObject->GetRollOffFactor();
387         PyObject* result = PyFloat_FromDouble(rollofffactor);
388         
389         return result;
390 }
391
392
393
394 PyObject* KX_SoundActuator::PySetLooping(PyObject* self, PyObject* args, PyObject* kwds)
395 {
396         bool looping = 1;
397         if (!PyArg_ParseTuple(args, "i", &looping))
398                 return NULL;
399         
400         m_soundObject->SetLoopMode(looping);
401         
402         Py_Return;
403 }         
404
405
406
407 PyObject* KX_SoundActuator::PyGetLooping(PyObject* self, PyObject* args, PyObject* kwds)
408 {
409         int looping = m_soundObject->GetLoopMode();
410         PyObject* result = PyInt_FromLong(looping);
411         
412         return result;
413 }
414
415
416
417 PyObject* KX_SoundActuator::PySetPosition(PyObject* self, PyObject* args, PyObject* kwds)
418 {
419         MT_Point3 pos;
420         pos[0] = 0.0;
421         pos[1] = 0.0;
422         pos[2] = 0.0;
423
424         if (!PyArg_ParseTuple(args, "fff", &pos[0], &pos[1], &pos[2]))
425                 return NULL;
426         
427         m_soundObject->SetPosition(pos);
428         
429         Py_Return;
430 }         
431
432
433
434 PyObject* KX_SoundActuator::PySetVelocity(PyObject* self, PyObject* args, PyObject* kwds)
435 {
436         MT_Vector3 vel;
437         vel[0] = 0.0;
438         vel[1] = 0.0;
439         vel[2] = 0.0;
440
441         if (!PyArg_ParseTuple(args, "fff", &vel[0], &vel[1], &vel[2]))
442                 return NULL;
443         
444         m_soundObject->SetVelocity(vel);
445         
446         Py_Return;
447 }         
448
449
450
451 PyObject* KX_SoundActuator::PySetOrientation(PyObject* self, PyObject* args, PyObject* kwds)
452 {
453         MT_Matrix3x3 ori;
454         ori[0][0] = 1.0;
455         ori[0][1] = 0.0;
456         ori[0][2] = 0.0;
457         ori[1][0] = 0.0;
458         ori[1][1] = 1.0;
459         ori[1][2] = 0.0;
460         ori[2][0] = 0.0;
461         ori[2][1] = 0.0;
462         ori[2][2] = 1.0;
463
464         if (!PyArg_ParseTuple(args, "fffffffff", &ori[0][0], &ori[0][1], &ori[0][2], &ori[1][0], &ori[1][1], &ori[1][2], &ori[2][0], &ori[2][1], &ori[2][2]))
465                 return NULL;
466         
467         m_soundObject->SetOrientation(ori);
468         
469         Py_Return;
470 }
471
472 PyObject* KX_SoundActuator::PySetType(PyObject* self, PyObject* args, PyObject* kwds)
473 {
474         int typeArg;
475
476         if (!PyArg_ParseTuple(args, "i", &typeArg)) {
477                 return NULL;
478         }
479
480         if ( (typeArg > KX_SOUNDACT_NODEF)
481           && (typeArg < KX_SOUNDACT_MAX) ) {
482                 m_type = (KX_SOUNDACT_TYPE) typeArg;
483         }
484
485         Py_Return;
486 }
487
488 PyObject* KX_SoundActuator::PyGetType(PyObject* self, PyObject* args, PyObject* kwds)
489 {
490         return PyInt_FromLong(m_type);
491 }
492
493
494