This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_android.cpp
248 lines (199 loc) · 7.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
24
25
#include "SDL_android.h"
26
27
28
extern "C" {
#include "events/SDL_events_c.h"
#include "video/android/SDL_androidkeyboard.h"
29
#include "video/android/SDL_androidvideo.h"
30
31
32
33
/* Impelemented in audio/android/SDL_androidaudio.c */
extern void Android_RunAudioThread();
} // C
34
35
36
37
38
39
40
41
42
43
44
/*******************************************************************************
This file links the Java side of Android with libsdl
*******************************************************************************/
#include <jni.h>
#include <android/log.h>
/*******************************************************************************
Globals
*******************************************************************************/
45
46
47
static JavaVM* mVM = NULL;
static JNIEnv* mEnv = NULL;
static JNIEnv* mAudioEnv = NULL;
48
49
50
// Main activity
static jclass mActivityInstance;
51
52
53
54
55
56
57
// method signatures
static jmethodID midCreateGLContext;
static jmethodID midFlipBuffers;
static jmethodID midAudioInit;
static jmethodID midAudioWriteShortBuffer;
static jmethodID midAudioWriteByteBuffer;
58
59
// Accelerometer data storage
60
61
62
63
64
float fLastAccelerometer[3];
/*******************************************************************************
Functions called by JNI
65
*******************************************************************************/
66
67
68
69
70
// Library init
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
mVM = vm;
71
72
73
return JNI_VERSION_1_4;
}
74
75
76
77
// Called before SDL_main() to initialize JNI bindings
extern "C" void SDL_Android_Init(JNIEnv* env)
{
78
79
mEnv = env;
80
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()");
81
82
83
84
85
jclass cls = mEnv->FindClass ("org/libsdl/app/SDLActivity");
mActivityInstance = cls;
midCreateGLContext = mEnv->GetStaticMethodID(cls,"createGLContext","()V");
midFlipBuffers = mEnv->GetStaticMethodID(cls,"flipBuffers","()V");
86
87
88
midAudioInit = mEnv->GetStaticMethodID(cls, "audioInit", "(IZZI)Ljava/lang/Object;");
midAudioWriteShortBuffer = mEnv->GetStaticMethodID(cls, "audioWriteShortBuffer", "([S)V");
midAudioWriteByteBuffer = mEnv->GetStaticMethodID(cls, "audioWriteByteBuffer", "([B)V");
89
90
91
92
if(!midCreateGLContext || !midFlipBuffers || !midAudioInit ||
!midAudioWriteShortBuffer || !midAudioWriteByteBuffer) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly");
93
94
95
}
}
96
97
98
99
100
101
102
103
// Resize
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeResize(
JNIEnv* env, jobject obj,
jint width, jint height, jint format)
{
Android_SetScreenResolution(width, height, format);
}
104
// Keydown
105
106
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyDown(
JNIEnv* env, jobject obj, jint keycode)
107
{
108
Android_OnKeyDown(keycode);
109
110
}
111
// Keyup
112
113
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyUp(
JNIEnv* env, jobject obj, jint keycode)
114
{
115
Android_OnKeyUp(keycode);
116
117
}
118
// Touch
119
120
121
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(
JNIEnv* env, jobject obj,
jint action, jfloat x, jfloat y, jfloat p)
122
{
123
124
125
126
127
128
129
130
131
#ifdef DEBUG
__android_log_print(ANDROID_LOG_INFO, "SDL",
"SDL: native touch event %d @ %f/%f, pressure %f\n",
action, x, y, p);
#endif
//TODO: Pass this off to the SDL multitouch stuff
}
132
133
134
135
136
137
138
139
140
141
// Accelerometer
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeAccel(
JNIEnv* env, jobject obj,
jfloat x, jfloat y, jfloat z)
{
fLastAccelerometer[0] = x;
fLastAccelerometer[1] = y;
fLastAccelerometer[2] = z;
}
142
// Quit
143
144
extern "C" void Java_org_libsdl_app_SDLActivity_nativeQuit(
JNIEnv* env, jobject obj)
145
146
147
{
// Inject a SDL_QUIT event
SDL_SendQuit();
148
149
}
150
151
extern "C" void Java_org_libsdl_app_SDLActivity_nativeRunAudioThread(
JNIEnv* env)
152
{
153
154
mVM->AttachCurrentThread(&mAudioEnv, NULL);
Android_RunAudioThread();
155
156
157
158
159
160
}
/*******************************************************************************
Functions called by SDL into Java
*******************************************************************************/
161
extern "C" void Android_JNI_CreateContext()
162
{
163
mEnv->CallStaticVoidMethod(mActivityInstance, midCreateGLContext);
164
165
}
166
extern "C" void Android_JNI_SwapWindow()
167
168
{
mEnv->CallStaticVoidMethod(mActivityInstance, midFlipBuffers);
169
170
}
171
172
173
174
175
176
177
178
179
180
181
//
// Audio support
//
static jint audioBufferFrames = 0;
static bool audioBuffer16Bit = false;
static bool audioBufferStereo = false;
static jobject audioBuffer;
static void * audioPinnedBuffer;
extern "C" int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
182
{
183
184
185
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
audioBuffer16Bit = is16Bit;
audioBufferStereo = channelCount > 1;
186
187
188
audioBuffer = mEnv->CallStaticObjectMethod(mActivityInstance, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
audioBuffer = mEnv->NewGlobalRef(audioBuffer);
189
190
191
192
193
if (audioBuffer == NULL) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: didn't get back a good audio buffer!");
return 0;
}
194
195
196
197
198
199
if (audioBufferStereo) {
audioBufferFrames = mEnv->GetArrayLength((jshortArray)audioBuffer) / 2;
} else {
audioBufferFrames = mEnv->GetArrayLength((jbyteArray)audioBuffer);
}
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
return audioBufferFrames;
}
extern "C" void * Android_JNI_PinAudioBuffer()
{
jboolean isCopy = JNI_FALSE;
if (audioPinnedBuffer != NULL) {
return audioPinnedBuffer;
}
if (audioBuffer16Bit) {
audioPinnedBuffer = mAudioEnv->GetShortArrayElements((jshortArray)audioBuffer, &isCopy);
} else {
audioPinnedBuffer = mAudioEnv->GetByteArrayElements((jbyteArray)audioBuffer, &isCopy);
}
return audioPinnedBuffer;
}
extern "C" void Android_JNI_WriteAudioBufferAndUnpin()
{
if (audioPinnedBuffer == NULL) {
return;
}
if (audioBuffer16Bit) {
mAudioEnv->ReleaseShortArrayElements((jshortArray)audioBuffer, (jshort *)audioPinnedBuffer, JNI_COMMIT);
mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
} else {
mAudioEnv->ReleaseByteArrayElements((jbyteArray)audioBuffer, (jbyte *)audioPinnedBuffer, JNI_COMMIT);
mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
}
audioPinnedBuffer = NULL;
}
extern "C" void Android_JNI_CloseAudioDevice()
{
if (audioBuffer) {
mEnv->DeleteGlobalRef(audioBuffer);
audioBuffer = NULL;
}
244
245
// TODO: Implement
246
}
247
248
/* vi: set ts=4 sw=4 expandtab: */