Mercurial > sdl-ios-xcode
annotate src/audio/baudio/SDL_beaudio.cc @ 563:04dcaf3da918
Massive Quartz input enhancements from Darrell Walisser. His email:
Enclosed is a patch that addresses the following:
--Various minor cleanups.
Removed dead/obsolete code, made some style cleanups
--Mouse Events
Now keep track of what button(s) were pressed so we know when to send
the mouse up event. This fixes the case where the mouse is dragged
outside of the game window and released (in which case we want to send
the mouse up event even though the mouse is outside the game window).
--Input Grabbing
Here is my take on the grabbing situation, which is the basis for the
new implementation.
There are 3 grab states, ungrabbed (UG), visible (VG), and invisible
(IG). Both VG and IG keep the mouse constrained to the window and
produce relative motion events. In VG the cursor is visible (duh), in
IG it is not. In VG, absolute motion events also work.
There are 6 actions that can affect grabbing:
1. Set Fullscreen/Window (F/W). In fullscreen, a visible grab should do
nothing. However, a fullscreen visible grab can be treated just like a
windowed visible grab, which is what I have done to help simplify
things.
2. Cursor hide/show (H/S). If the cursor is hidden when grabbing, the
grab is an invisible grab. If the cursor is visible, the grab should
just constrain the mouse to the window.
3. Input grab/ungrab(G/U). If grabbed, the cursor should be confined to
the window as should the keyboard input. On Mac OS X, the keyboard
input is implicitly grabbed by confining the cursor, except for
command-tab which can switch away from the application. Should the
window come to the foreground if the application is deactivated and
grab input is called? This isn't necessary in this implementation
because the grab state will be asserted upon activation.
Using my notation, these are all the cases that need to be handled
(state + action = new state).
UG+U = UG
UG+G = VG or IG, if cursor is visible or not
UG+H = UG
UG+S = UG
VG+U = UG
VG+G = VG
VG+H = IG
VG+S = VG
IG+U = UG
IG+G = IG
IG+H = IG
IG+S = VG
The cases that result in the same state can be ignored in the code,
which cuts it down to just 5 cases.
Another issue is what happens when the app loses/gains input focus from
deactivate/activate or iconify/deiconify. I think that if input focus
is ever lost (outside of SDL's control), the grab state should be
suspended and the cursor should become visible and active again. When
regained, the cursor should reappear in its original location and/or
grab state. This way, when reactivating the cursor is still in the same
position as before so apps shouldn't get confused when the next motion
event comes in. This is what I've done in this patch.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Fri, 27 Dec 2002 20:52:41 +0000 |
parents | e8157fcb3114 |
children | c9b51268668f |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997 Sam Lantinga | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
114
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* Allow access to the audio stream on BeOS */ | |
29 | |
30 #include <stdlib.h> | |
31 #include <stdio.h> | |
32 #include <string.h> | |
33 #include <SoundPlayer.h> | |
34 | |
35 #include "SDL_BeApp.h" | |
36 | |
37 extern "C" { | |
38 | |
39 #include "SDL_audio.h" | |
40 #include "SDL_audio_c.h" | |
41 #include "SDL_sysaudio.h" | |
42 #include "SDL_systhread_c.h" | |
43 #include "SDL_beaudio.h" | |
44 | |
45 | |
46 /* Audio driver functions */ | |
47 static int BE_OpenAudio(_THIS, SDL_AudioSpec *spec); | |
48 static void BE_WaitAudio(_THIS); | |
49 static void BE_PlayAudio(_THIS); | |
50 static Uint8 *BE_GetAudioBuf(_THIS); | |
51 static void BE_CloseAudio(_THIS); | |
52 | |
53 /* Audio driver bootstrap functions */ | |
54 | |
55 static int Audio_Available(void) | |
56 { | |
57 return(1); | |
58 } | |
59 | |
60 static void Audio_DeleteDevice(SDL_AudioDevice *device) | |
61 { | |
62 free(device->hidden); | |
63 free(device); | |
64 } | |
65 | |
66 static SDL_AudioDevice *Audio_CreateDevice(int devindex) | |
67 { | |
68 SDL_AudioDevice *device; | |
69 | |
70 /* Initialize all variables that we clean on shutdown */ | |
71 device = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice)); | |
72 if ( device ) { | |
73 memset(device, 0, (sizeof *device)); | |
74 device->hidden = (struct SDL_PrivateAudioData *) | |
75 malloc((sizeof *device->hidden)); | |
76 } | |
77 if ( (device == NULL) || (device->hidden == NULL) ) { | |
78 SDL_OutOfMemory(); | |
79 if ( device ) { | |
80 free(device); | |
81 } | |
82 return(0); | |
83 } | |
84 memset(device->hidden, 0, (sizeof *device->hidden)); | |
85 | |
86 /* Set the function pointers */ | |
87 device->OpenAudio = BE_OpenAudio; | |
88 device->WaitAudio = BE_WaitAudio; | |
89 device->PlayAudio = BE_PlayAudio; | |
90 device->GetAudioBuf = BE_GetAudioBuf; | |
91 device->CloseAudio = BE_CloseAudio; | |
92 | |
93 device->free = Audio_DeleteDevice; | |
94 | |
95 return device; | |
96 } | |
97 | |
98 AudioBootStrap BAUDIO_bootstrap = { | |
99 "baudio", "BeOS BSoundPlayer", | |
100 Audio_Available, Audio_CreateDevice | |
101 }; | |
102 | |
103 /* The BeOS callback for handling the audio buffer */ | |
104 static void FillSound(void *device, void *stream, size_t len, | |
105 const media_raw_audio_format &format) | |
106 { | |
107 SDL_AudioDevice *audio = (SDL_AudioDevice *)device; | |
108 | |
109 /* Silence the buffer, since it's ours */ | |
110 memset(stream, audio->spec.silence, len); | |
111 | |
112 /* Only do soemthing if audio is enabled */ | |
113 if ( ! audio->enabled ) | |
114 return; | |
115 | |
116 if ( ! audio->paused ) { | |
117 if ( audio->convert.needed ) { | |
118 SDL_mutexP(audio->mixer_lock); | |
119 (*audio->spec.callback)(audio->spec.userdata, | |
120 (Uint8 *)audio->convert.buf,audio->convert.len); | |
121 SDL_mutexV(audio->mixer_lock); | |
122 SDL_ConvertAudio(&audio->convert); | |
123 memcpy(stream,audio->convert.buf,audio->convert.len_cvt); | |
124 } else { | |
125 SDL_mutexP(audio->mixer_lock); | |
126 (*audio->spec.callback)(audio->spec.userdata, | |
127 (Uint8 *)stream, len); | |
128 SDL_mutexV(audio->mixer_lock); | |
129 } | |
130 } | |
131 return; | |
132 } | |
133 | |
134 /* Dummy functions -- we don't use thread-based audio */ | |
135 void BE_WaitAudio(_THIS) | |
136 { | |
137 return; | |
138 } | |
139 void BE_PlayAudio(_THIS) | |
140 { | |
141 return; | |
142 } | |
143 Uint8 *BE_GetAudioBuf(_THIS) | |
144 { | |
145 return(NULL); | |
146 } | |
147 | |
148 void BE_CloseAudio(_THIS) | |
149 { | |
150 if ( audio_obj ) { | |
151 audio_obj->Stop(); | |
152 delete audio_obj; | |
153 audio_obj = NULL; | |
154 } | |
155 | |
156 /* Quit the Be Application, if there's nothing left to do */ | |
157 SDL_QuitBeApp(); | |
158 } | |
159 | |
160 int BE_OpenAudio(_THIS, SDL_AudioSpec *spec) | |
161 { | |
162 media_raw_audio_format format; | |
163 | |
164 /* Initialize the Be Application, if it's not already started */ | |
165 if ( SDL_InitBeApp() < 0 ) { | |
166 return(-1); | |
167 } | |
168 | |
169 /* Parse the audio format and fill the Be raw audio format */ | |
170 format.frame_rate = (float)spec->freq; | |
171 format.channel_count = spec->channels; | |
172 switch (spec->format&~0x1000) { | |
173 case AUDIO_S8: | |
174 /* Signed 8-bit audio unsupported, convert to U8 */ | |
175 spec->format = AUDIO_U8; | |
176 case AUDIO_U8: | |
177 format.format = media_raw_audio_format::B_AUDIO_UCHAR; | |
178 format.byte_order = 0; | |
179 break; | |
180 case AUDIO_U16: | |
181 /* Unsigned 16-bit audio unsupported, convert to S16 */ | |
182 spec->format ^= 0x8000; | |
183 case AUDIO_S16: | |
184 format.format = media_raw_audio_format::B_AUDIO_SHORT; | |
185 if ( spec->format & 0x1000 ) { | |
186 format.byte_order = 1; /* Big endian */ | |
187 } else { | |
188 format.byte_order = 2; /* Little endian */ | |
189 } | |
190 break; | |
191 } | |
192 format.buffer_size = spec->samples; | |
193 | |
194 /* Calculate the final parameters for this audio specification */ | |
195 SDL_CalculateAudioSpec(spec); | |
196 | |
197 /* Subscribe to the audio stream (creates a new thread) */ | |
198 { sigset_t omask; | |
199 SDL_MaskSignals(&omask); | |
200 audio_obj = new BSoundPlayer(&format, "SDL Audio", FillSound, | |
201 NULL, _this); | |
202 SDL_UnmaskSignals(&omask); | |
203 } | |
114
dabc453ce7f7
Now returns an error if unable to open audio on BeOS
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
204 if ( audio_obj->Start() == B_NO_ERROR ) { |
dabc453ce7f7
Now returns an error if unable to open audio on BeOS
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
205 audio_obj->SetHasData(true); |
dabc453ce7f7
Now returns an error if unable to open audio on BeOS
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
206 } else { |
dabc453ce7f7
Now returns an error if unable to open audio on BeOS
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
207 SDL_SetError("Unable to start Be audio"); |
dabc453ce7f7
Now returns an error if unable to open audio on BeOS
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
208 return(-1); |
dabc453ce7f7
Now returns an error if unable to open audio on BeOS
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
209 } |
0 | 210 |
211 /* We're running! */ | |
212 return(1); | |
213 } | |
214 | |
215 }; /* Extern C */ |