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