PageRenderTime 21ms CodeModel.GetById 14ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Mixer/Effects.xs

http://github.com/PerlGameDev/SDL
Unknown | 261 lines | 209 code | 52 blank | 0 comment | 0 complexity | 05d61bb59d08deb2a7b13731fa3d6ded MD5 | raw file
  1#include "EXTERN.h"
  2#include "perl.h"
  3#include "XSUB.h"
  4#include "ppport.h"
  5
  6#ifndef SDL_PERL_DEFINES_H
  7#include "defines.h"
  8#endif
  9
 10#include <SDL.h>
 11
 12#ifdef HAVE_SDL_MIXER
 13#include <SDL_mixer.h>
 14
 15#define MAX_EFFECTS 31
 16
 17PerlInterpreter *context = NULL;
 18int registered_effects   = 0;
 19
 20void** effects = NULL;
 21void** effects_done = NULL;
 22
 23char* effect_func_cb = NULL;
 24char* effect_func_done_cb = NULL;
 25
 26void effect_func(int chan, void *stream, int len, void *udata)
 27{
 28	ENTER_TLS_CONTEXT;
 29	Sint16 *buf = (Sint16 *)stream;
 30
 31	len /= 2;            /* 2 bytes ber sample */
 32	
 33	dSP;                                       /* initialize stack pointer          */
 34	
 35	ENTER;                                     /* everything created after here     */
 36	SAVETMPS;                                  /* ...is a temporary variable.       */
 37
 38	PUSHMARK(SP);                              /* remember the stack pointer        */
 39	XPUSHs(sv_2mortal(newSViv(chan)));
 40	XPUSHs(sv_2mortal(newSViv(len)));
 41	XPUSHs(sv_2mortal(newSVsv(udata))); /* push something onto the stack     */
 42	int i;
 43	for(i = 0; i < len; i++)
 44		XPUSHs(sv_2mortal(newSViv(buf[i])));
 45	
 46	PUTBACK;                                   /* make local stack pointer global   */
 47
 48	/*if(cb != (SV*)NULL) */
 49	{
 50        int count = call_pv(effect_func_cb, G_ARRAY); /* call the function                 */
 51		SPAGAIN;                               /* refresh stack pointer             */
 52		
 53		if(count == len + 1)
 54			*(SV *)udata = *(newSVsv(POPs));
 55		
 56		if(count)
 57		{
 58			memset(buf, 0, len * 2); /* clear the buffer */
 59			
 60			for(i = len - 1; i >= 0; i--)
 61			{
 62				buf[i] = POPi;
 63			}
 64		}
 65
 66		PUTBACK;
 67	}
 68
 69	FREETMPS;                                  /* free that return value            */
 70	LEAVE;                                     /* ...and the XPUSHed "mortal" args. */
 71	LEAVE_TLS_CONTEXT;
 72}
 73
 74void effect_pm_func(void *udata, Uint8 *stream, int len)
 75{
 76	effect_func(-2, (void *)stream, len, udata);
 77}
 78
 79void effect_done(int chan, void *udata)
 80{
 81	ENTER_TLS_CONTEXT;
 82
 83	dSP;     /* initialize stack pointer          */
 84	PUSHMARK(SP);                              /* remember the stack pointer        */
 85
 86	/*if(fcb != (SV*)NULL) */
 87	/*warn ( "Called %s", effect_func_done_cb ); */
 88	
 89        call_pv(effect_func_done_cb, G_DISCARD|G_VOID);   /* call the function                 */
 90        
 91	LEAVE_TLS_CONTEXT;
 92}
 93
 94#endif
 95
 96MODULE = SDL::Mixer::Effects 	PACKAGE = SDL::Mixer::Effects    PREFIX = mixeff_
 97
 98#ifdef HAVE_SDL_MIXER
 99
100#ifdef USE_THREADS
101
102int
103mixeff_register(channel, func, done, arg)
104	int channel
105	char *func
106	char *done
107	SV *arg
108	CODE:
109		if(effects == NULL)
110		{
111			effects = safemalloc(MAX_EFFECTS* sizeof(void*));
112		}
113		if(effects_done == NULL)
114		{
115			effects_done = safemalloc(MAX_EFFECTS* sizeof(void*));
116		}
117
118		GET_TLS_CONTEXT;
119
120		effect_func_cb = func;
121		effect_func_done_cb = done;
122		if(registered_effects <= MAX_EFFECTS )
123		{
124			effects[registered_effects] = (void*)&effect_func;
125			effects_done[registered_effects] = (void*)&effect_done;
126			if(0 != Mix_RegisterEffect(channel, effects[registered_effects], effects_done[registered_effects], arg))
127			{
128				/*warn( "Registered %d %p %p", registered_effects, effects[registered_effects], effects_done[registered_effects]); */
129				
130				RETVAL = registered_effects;
131				registered_effects++;
132			}
133			else
134			{
135				warn( "Maximum effects allowed is 32 " );
136				RETVAL = -1;
137			}
138		}
139		else
140		{
141			RETVAL = -1;
142		}
143	OUTPUT:
144		RETVAL
145
146#else
147
148int
149mixeff_register(channel, func, done, arg)
150	int channel
151	char *func
152	char *done
153	SV *arg
154	CODE:
155		warn("Perl need to be compiled with 'useithreads' for SDL::Mixer::Effects::register( channel, func, done, arg )");
156		XSRETURN_UNDEF;
157	OUTPUT:
158		RETVAL
159
160#endif
161
162int
163mixeff_unregister( channel, func )
164	int channel
165	int func
166	CODE:
167		
168
169		int check;
170		if( func <= registered_effects)
171		{
172			check = Mix_UnregisterEffect(channel, effects[func]);			
173			if (check == 0 )	
174			{
175			  warn ("Error unregistering: %s", Mix_GetError() );
176			}
177		}
178		else
179		{
180			warn (" Invalid effect id %d, currently %d effects registered", func, registered_effects);
181			check = 0;
182		}
183		
184		RETVAL = check;		
185	OUTPUT:
186		RETVAL
187
188int
189mixeff_unregister_all( channel )
190	int channel
191	CODE:
192		RETVAL = Mix_UnregisterAllEffects(channel);
193	OUTPUT:
194		RETVAL
195
196int
197mixeff_set_panning( channel, left, right )
198	int channel
199	int left
200	int right
201	CODE:
202		RETVAL = Mix_SetPanning(channel, left, right);
203	OUTPUT:
204		RETVAL
205
206int
207mixeff_set_position( channel, angle, distance )
208	int channel
209	Sint16 angle
210	Uint8 distance
211	CODE:
212		RETVAL = Mix_SetPosition(channel, angle, distance);
213	OUTPUT:
214		RETVAL
215
216int
217mixeff_set_distance( channel, distance )
218	int channel
219	Uint8 distance
220	CODE:
221		RETVAL = Mix_SetDistance(channel, distance);
222	OUTPUT:
223		RETVAL
224
225int
226mixeff_set_reverse_stereo( channel, flip )
227	int channel
228	Uint8 flip
229	CODE:
230		RETVAL = Mix_SetReverseStereo(channel, flip);
231	OUTPUT:
232		RETVAL
233
234#ifdef USE_THREADS
235
236void
237mixeff_set_post_mix(func = NULL, arg = NULL)
238	SV *func
239	SV *arg
240	CODE:
241		GET_TLS_CONTEXT;
242
243		if(func != (SV *)NULL)
244		{
245			Mix_SetPostMix(&effect_pm_func, arg);
246		}
247		else
248			Mix_SetPostMix(NULL, NULL);
249
250#else
251
252void
253mixeff_set_post_mix(func = NULL, arg = NULL)
254	SV *func
255	SV *arg
256	CODE:
257		warn("Perl need to be compiled with 'useithreads' for SDL::Mixer::Effects::set_post_mix( func, arg )");
258
259#endif
260
261#endif