Game Development Reference
In-Depth Information
// Init audio
void jni_init_audio(int freq, int channels, int bits)
{
JNIEnv *env;
(*g_VM)->AttachCurrentThread ( g_VM, &env, NULL);
jmethodID mid = (*env)->GetStaticMethodID(env
, jNativesCls
, "OnInitAudio", "(III)V");
if ( mid) {
(*env)->CallStaticVoidMethod(env, jNativesCls, mid , freq, channels, bits);
}
}
Listing 2-5 also shows how you can call a Java method within C to initialize the audio. The
function
jni_init_audio
will be called by the engine on audio startup, which in turn calls
the Java method
OnInitAudio
with three arguments: frequency, number of channels, and
audio resolution. Note that this function is called from a separate thread (the game thread),
therefore it must attach to the current (Java) thread by calling.
(*g_VM)->AttachCurrentThread ( g_VM, &env, NULL);
Here
g_VM
is a global reference to the Java virtual machine, which must be saved the first
time you call JNI (when you call the game main function, for example).
jNativesCls
is a class
reference that points to the
NativeAudio
Java class obtained by doing a JNI class lookup
with
FindClass
and
NewGlobalRef
in the same spot, like so:
jclass clazz = (*env)->FindClass(env, "NativeAudio");
jNativesCls = (jclass)(*env)->NewGlobalRef(env, clazz);
Finally,
jni_init_audio
calls
OnInitAudio
in
NativeAudio.java
using JNI's
CallStaticVoidMethod
with the three arguments: frequency, channels, and bits. You have
effectively created a C to Java callback.
(*env)->CallStaticVoidMethod(env, jNativesCls, mid , freq, channels, bits);
This is the technique used to play audio in the Quake and Quake II engines demonstrated in
this topic. More details will be explained in those chapters. Now, let's tackle video buffers.
Cascading Video Events
When it comes to handling video, game engine designers typically decouple the rendering
process from the actual drawing. This keeps the engine modularized and makes it easy
to port to multiple platforms. For example, low-end devices may not support a graphics
processing unit (GPU), and thus decoupling the drawing and rendering will allow developers