2003-10-11 12:29:40 -04:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2002 Light Weight Java Game Library Project
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are
|
|
|
|
* met:
|
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* * Neither the name of 'Light Weight Java Game Library' nor the names of
|
|
|
|
* its contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* @author elias_naur <elias_naur@users.sourceforge.net>
|
|
|
|
* @version $Revision$
|
|
|
|
*/
|
|
|
|
|
2004-03-09 04:25:10 -05:00
|
|
|
#include <stdlib.h>
|
2003-10-11 12:29:40 -04:00
|
|
|
#include "common_tools.h"
|
|
|
|
|
2004-03-27 09:09:55 -05:00
|
|
|
static bool debug = false;
|
|
|
|
static const char* VERSION = "0.9pre";
|
|
|
|
|
|
|
|
jstring getVersionString(JNIEnv *env) {
|
|
|
|
return env->NewStringUTF(VERSION);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isDebugEnabled(void) {
|
|
|
|
return debug;
|
|
|
|
}
|
2003-12-15 06:49:17 -05:00
|
|
|
|
2003-12-20 17:03:25 -05:00
|
|
|
void setDebugEnabled(bool enable) {
|
|
|
|
debug = enable;
|
2003-12-15 06:49:17 -05:00
|
|
|
}
|
|
|
|
|
2003-12-20 17:03:25 -05:00
|
|
|
void printfDebug(const char *format, ...) {
|
2003-12-15 06:49:17 -05:00
|
|
|
va_list ap;
|
|
|
|
va_start(ap, format);
|
2004-03-27 09:09:55 -05:00
|
|
|
if (isDebugEnabled())
|
2003-12-24 02:32:03 -05:00
|
|
|
vfprintf(stderr, format, ap);
|
2003-12-15 06:49:17 -05:00
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
2003-10-29 11:21:42 -05:00
|
|
|
static void incListStart(event_queue_t *queue) {
|
|
|
|
queue->list_start = (queue->list_start + 1)%EVENT_BUFFER_SIZE;
|
|
|
|
}
|
|
|
|
|
2003-10-11 12:29:40 -04:00
|
|
|
void initEventQueue(event_queue_t *event_queue) {
|
|
|
|
event_queue->list_start = 0;
|
|
|
|
event_queue->list_end = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void putEventElement(event_queue_t *queue, unsigned char byte) {
|
|
|
|
int next_index = (queue->list_end + 1)%EVENT_BUFFER_SIZE;
|
|
|
|
if (next_index == queue->list_start) {
|
2003-12-20 17:03:25 -05:00
|
|
|
printfDebug("Event buffer overflow!\n");
|
2003-10-11 12:29:40 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
queue->input_event_buffer[queue->list_end] = byte;
|
|
|
|
queue->list_end = next_index;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool hasMoreEvents(event_queue_t *queue) {
|
|
|
|
return queue->list_start != queue->list_end;
|
|
|
|
}
|
|
|
|
|
2004-03-26 16:11:20 -05:00
|
|
|
static void copyEvent(event_queue_t *queue, unsigned char *output_event_buffer, int output_index, int event_size) {
|
2003-10-11 12:29:40 -04:00
|
|
|
for (int i = 0; i < event_size; i++) {
|
2004-03-26 16:11:20 -05:00
|
|
|
output_event_buffer[output_index] = queue->input_event_buffer[queue->list_start];
|
2003-10-29 11:21:42 -05:00
|
|
|
incListStart(queue);
|
2003-10-11 12:29:40 -04:00
|
|
|
output_index++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-03-26 16:11:20 -05:00
|
|
|
int copyEvents(event_queue_t *event_queue, unsigned char *output_event_buffer, int buffer_size, int event_size) {
|
2003-10-11 12:29:40 -04:00
|
|
|
int num_events = 0;
|
2004-03-26 16:11:20 -05:00
|
|
|
int index = 0;
|
|
|
|
while (index + event_size <= buffer_size && hasMoreEvents(event_queue)) {
|
|
|
|
copyEvent(event_queue, output_event_buffer, index, event_size);
|
2003-10-11 12:29:40 -04:00
|
|
|
num_events++;
|
2004-03-26 16:11:20 -05:00
|
|
|
index += event_size;
|
2003-10-11 12:29:40 -04:00
|
|
|
}
|
|
|
|
return num_events;
|
|
|
|
}
|
|
|
|
|
2003-10-22 06:57:19 -04:00
|
|
|
static void throwGeneralException(JNIEnv * env, const char *exception_name, const char * err) {
|
2004-04-09 17:52:42 -04:00
|
|
|
if (env->ExceptionCheck() == JNI_TRUE)
|
|
|
|
return; // The JVM crashes if we try to throw two exceptions from one native call
|
2003-10-22 06:57:19 -04:00
|
|
|
jclass cls = env->FindClass(exception_name);
|
2003-10-11 12:29:40 -04:00
|
|
|
env->ThrowNew(cls, err);
|
|
|
|
env->DeleteLocalRef(cls);
|
|
|
|
}
|
2003-10-22 06:57:19 -04:00
|
|
|
|
|
|
|
void throwOpenALException(JNIEnv * env, const char * err) {
|
|
|
|
throwGeneralException(env, "org/lwjgl/openal/OpenALException", err);
|
|
|
|
}
|
|
|
|
|
2004-05-23 09:50:08 -04:00
|
|
|
void throwFMODException(JNIEnv * env, const char * err) {
|
|
|
|
throwGeneralException(env, "org/lwjgl/fmod/FMODException", err);
|
|
|
|
}
|
|
|
|
|
2003-10-22 06:57:19 -04:00
|
|
|
void throwException(JNIEnv * env, const char * err) {
|
2004-03-27 10:05:24 -05:00
|
|
|
throwGeneralException(env, "org/lwjgl/LWJGLException", err);
|
2003-10-22 06:57:19 -04:00
|
|
|
}
|
2004-03-09 04:25:10 -05:00
|
|
|
|
|
|
|
void doExtension(JNIEnv *env, jobject ext_set, const char *method_name, const char *ext) {
|
|
|
|
jclass clazz = env->GetObjectClass(ext_set);
|
|
|
|
jmethodID id = env->GetMethodID(clazz, method_name, "(Ljava/lang/Object;)Z");
|
|
|
|
if (id == NULL)
|
|
|
|
return;
|
|
|
|
jstring ext_string = env->NewStringUTF(ext);
|
|
|
|
if (ext_string == NULL) {
|
2004-05-23 14:57:04 -04:00
|
|
|
printfDebug("Could not allocate java string from %s\n", ext);
|
2004-03-09 04:25:10 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
env->CallBooleanMethod(ext_set, id, ext_string);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ext_removeExtension(JNIEnv *env, jobject ext_set, const char *ext) {
|
|
|
|
doExtension(env, ext_set, "remove", ext);
|
|
|
|
}
|
|
|
|
|
|
|
|
jclass ext_ResetClass(JNIEnv *env, const char *class_name) {
|
|
|
|
jclass clazz = env->FindClass(class_name);
|
2004-05-23 14:57:04 -04:00
|
|
|
if (clazz == NULL)
|
|
|
|
return NULL;
|
2004-03-09 04:25:10 -05:00
|
|
|
jint result = env->UnregisterNatives(clazz);
|
|
|
|
if (result != 0)
|
|
|
|
printfDebug("Could not unregister natives for class %s\n", class_name);
|
|
|
|
return clazz;
|
|
|
|
}
|
|
|
|
|
2004-03-11 07:38:13 -05:00
|
|
|
bool ext_InitializeFunctions(ExtGetProcAddressPROC gpa, int num_functions, ExtFunction *functions) {
|
|
|
|
for (int i = 0; i < num_functions; i++) {
|
|
|
|
ExtFunction *function = functions + i;
|
|
|
|
if (function->ext_function_name != NULL) {
|
|
|
|
void *ext_func_pointer = gpa(function->ext_function_name);
|
|
|
|
if (ext_func_pointer == NULL)
|
|
|
|
return false;
|
|
|
|
void **ext_function_pointer_pointer = function->ext_function_pointer;
|
|
|
|
*ext_function_pointer_pointer = ext_func_pointer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2004-03-09 06:03:10 -05:00
|
|
|
bool ext_InitializeClass(JNIEnv *env, jclass clazz, jobject ext_set, const char *ext_name, ExtGetProcAddressPROC gpa, int num_functions, JavaMethodAndExtFunction *functions) {
|
2004-05-23 14:57:04 -04:00
|
|
|
if (clazz == NULL)
|
|
|
|
return false;
|
2004-03-09 04:25:10 -05:00
|
|
|
JNINativeMethod *methods = (JNINativeMethod *)malloc(num_functions*sizeof(JNINativeMethod));
|
|
|
|
for (int i = 0; i < num_functions; i++) {
|
|
|
|
JavaMethodAndExtFunction *function = functions + i;
|
|
|
|
if (function->ext_function_name != NULL) {
|
|
|
|
void *ext_func_pointer = gpa(function->ext_function_name);
|
|
|
|
if (ext_func_pointer == NULL) {
|
2004-04-09 17:52:42 -04:00
|
|
|
if (ext_name != NULL) {
|
|
|
|
printfDebug("NOTICE: %s disabled because of missing driver symbols\n", ext_name);
|
|
|
|
if (ext_set != NULL)
|
|
|
|
ext_removeExtension(env, ext_set, ext_name);
|
|
|
|
}
|
2004-03-09 04:25:10 -05:00
|
|
|
free(methods);
|
2004-03-09 06:03:10 -05:00
|
|
|
return false;
|
2004-03-09 04:25:10 -05:00
|
|
|
}
|
|
|
|
void **ext_function_pointer_pointer = function->ext_function_pointer;
|
|
|
|
*ext_function_pointer_pointer = ext_func_pointer;
|
|
|
|
}
|
|
|
|
JNINativeMethod *method = methods + i;
|
|
|
|
method->name = function->method_name;
|
|
|
|
method->signature = function->signature;
|
|
|
|
method->fnPtr = function->method_pointer;
|
|
|
|
}
|
|
|
|
jint result = env->RegisterNatives(clazz, methods, num_functions);
|
|
|
|
free(methods);
|
2004-04-09 17:52:42 -04:00
|
|
|
if (result != 0) {
|
|
|
|
if (ext_name != NULL)
|
|
|
|
printfDebug("Could not register natives for extension %s\n", ext_name);
|
|
|
|
return false;
|
|
|
|
} else
|
|
|
|
return true;
|
2004-03-09 04:25:10 -05:00
|
|
|
}
|
|
|
|
|
2004-03-11 16:30:48 -05:00
|
|
|
bool getBooleanProperty(JNIEnv *env, const char* propertyName) {
|
|
|
|
jstring property = env->NewStringUTF(propertyName);
|
|
|
|
jclass booleanClass = env->FindClass("java/lang/Boolean");
|
|
|
|
jmethodID getBoolean = env->GetStaticMethodID(booleanClass, "getBoolean", "(Ljava/lang/String;)Z");
|
2004-03-23 05:19:20 -05:00
|
|
|
return env->CallStaticBooleanMethod(booleanClass, getBoolean, property)? true : false;
|
2004-03-11 16:30:48 -05:00
|
|
|
}
|