diff --git a/c/jintellitype/JIntellitype.cpp b/c/jintellitype/JIntellitype.cpp new file mode 100644 index 0000000..060b2d5 --- /dev/null +++ b/c/jintellitype/JIntellitype.cpp @@ -0,0 +1,157 @@ +/* + JIntellitype (http://www.melloware.com/) + Java JNI API for Windows Intellitype commands and global keystrokes. + + Copyright (C) 1999, 2008 Emil A. Lefkof III, info@melloware.com + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Compiled with Mingw port of GCC, + Bloodshed Dev-C++ IDE (http://www.bloodshed.net/devcpp.html) +*/ +#include "stdafx.h" +#include "com_melloware_jintellitype_JIntellitype.h" +#include "JIntellitypeHandler.h" + +HINSTANCE g_instance = NULL; + + +BOOL WINAPI DllMain +( + HINSTANCE hinstDLL, // handle to DLL module + DWORD fdwReason, // reason for calling function + LPVOID lpvReserved // reserved +) +{ + switch( fdwReason ) + { + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + + case DLL_PROCESS_ATTACH: + g_instance = hinstDLL; + + break; + } + return TRUE; +} + + +extern "C" +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: initializeLibrary + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_initializeLibrary + (JNIEnv *env, jobject object) +{ + // Get handler + JIntellitypeHandler *l_handler = JIntellitypeHandler::extract( env, object ); + + // Create our handler + l_handler = new JIntellitypeHandler( env, object ); + + // Enable it + if( l_handler ) + l_handler->initialize(env, g_instance); +} + +extern "C" +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: regHotKey + * Signature: (III)V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_regHotKey + (JNIEnv *env, jobject object, jint identifier, jint modifier, jint keycode) +{ + // Get handler + JIntellitypeHandler *l_handler = JIntellitypeHandler::extract( env, object ); + + if( l_handler ) + { + l_handler->regHotKey(identifier, modifier, keycode); + } + else + { + // throw exception + jclass JIntellitypeException = env->FindClass("com/melloware/jintellitype/JIntellitypeException"); + env->ThrowNew(JIntellitypeException,"JIntellitype was not initialized properly."); + } +} + +extern "C" +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: unregHotKey + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_unregHotKey + (JNIEnv *env, jobject object, jint identifier) +{ + // Get handler + JIntellitypeHandler *l_handler = JIntellitypeHandler::extract( env, object ); + + if( l_handler ) + { + l_handler->unregHotKey(identifier); + } + else + { + // throw exception + jclass JIntellitypeException = env->FindClass("com/melloware/jintellitype/JIntellitypeException"); + env->ThrowNew(JIntellitypeException,"JIntellitype was not initialized properly."); + } + +} + +extern "C" +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: terminate + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_terminate + (JNIEnv *env, jobject object) +{ + // Get handler + JIntellitypeHandler *l_handler = JIntellitypeHandler::extract( env, object ); + + // Clean up all resources allocated by this API + if( l_handler ) + l_handler->terminate(); + +} + +extern "C" +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: isRunning + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_com_melloware_jintellitype_JIntellitype_isRunning + (JNIEnv *env, jclass, jstring wndName) +{ + // App name for the hidden window's registered class + CHAR szAppName[] = "SunAwtFrame"; + const char *cWndName = env->GetStringUTFChars(wndName, 0); + // Find out if there's a hidden window with the given title + HWND mHwnd = FindWindow(szAppName, cWndName); + env->ReleaseStringUTFChars(wndName, cWndName); + // If there is, another instance of our app is already running + return mHwnd != NULL; +} + diff --git a/c/jintellitype/JIntellitype.dev b/c/jintellitype/JIntellitype.dev new file mode 100644 index 0000000..62fa7e1 --- /dev/null +++ b/c/jintellitype/JIntellitype.dev @@ -0,0 +1,149 @@ +[Project] +FileName=JIntellitype.dev +Name=JIntellitype +Ver=1 +IsCpp=1 +Type=3 +Compiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -DBUILDING_DLL=1_@@_ +CppCompiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL_@@_ +Includes=c:\java\jdk1.2.2\include;c:\java\jdk1.2.2\include\win32 +Linker=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 --no-export-all-symbols --add-stdcall-alias_@@_ +Libs= +UnitCount=8 +Folders="Header Files","Resource Files","Source Files" +ObjFiles= +PrivateResource=JIntellitype_private.rc +ResourceIncludes= +MakeIncludes= +Icon= +ExeOutput=..\..\..\..\jintellitype +ObjectOutput=..\..\..\target +OverrideOutput=0 +OverrideOutputName=JIntellitype.dll +HostApplication= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=1 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000001001000000100 + +[Unit1] +FileName=JIntellitypeThread.cpp +Folder="Source Files" +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=JIntellitype.cpp +Folder="Source Files" +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=JIntellitypeHandler.cpp +Folder="Source Files" +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=JIntellitypeHandler.h +Folder="Header Files" +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=StdAfx.h +Folder="Header Files" +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=com_melloware_jintellitype_JIntellitype.h +Folder=Header Files +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=465 +LanguageID=1033 +CharsetID=1252 +CompanyName=Melloware Inc (www.melloware.com) +FileVersion=1.0 +FileDescription=Java JNI bridge to MS Intellitype commands +InternalName= +LegalCopyright=Copyright 2006 Melloware Inc +LegalTrademarks=Copyright 2006 Melloware Inc +OriginalFilename= +ProductName=JIntellitype +ProductVersion=1.0 +AutoIncBuildNr=1 + +[Unit11] +FileName=com_melloware_jintellitype_JIntellitype.h +CompileCpp=1 +Folder=Header Files +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=com_melloware_jintellitype_JIntellitype.h +CompileCpp=1 +Folder=Header Files +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=StdAfx.cpp +CompileCpp=1 +Folder="Source Files" +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=JIntellitypeThread.h +CompileCpp=1 +Folder="Header Files" +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/c/jintellitype/JIntellitype.layout b/c/jintellitype/JIntellitype.layout new file mode 100644 index 0000000..6956056 --- /dev/null +++ b/c/jintellitype/JIntellitype.layout @@ -0,0 +1,76 @@ +[Editor_9] +CursorCol=1 +CursorRow=20 +TopLine=1 +LeftChar=1 +Open=0 +Top=0 +[Editors] +Focused=2 +Order=1,2,0,7,4 +[Editor_0] +Open=1 +Top=0 +CursorCol=5 +CursorRow=118 +TopLine=71 +LeftChar=1 +[Editor_1] +Open=1 +Top=0 +CursorCol=36 +CursorRow=149 +TopLine=75 +LeftChar=1 +[Editor_2] +Open=1 +Top=1 +CursorCol=14 +CursorRow=209 +TopLine=162 +LeftChar=1 +[Editor_3] +Open=0 +Top=0 +CursorCol=23 +CursorRow=3 +TopLine=1 +LeftChar=1 +[Editor_4] +Open=1 +Top=0 +CursorCol=1 +CursorRow=27 +TopLine=1 +LeftChar=1 +[Editor_5] +Open=0 +Top=0 +CursorCol=3 +CursorRow=24 +TopLine=11 +LeftChar=1 +[Editor_6] +Open=0 +Top=0 +CursorCol=1 +CursorRow=16 +TopLine=1 +LeftChar=1 +[Editor_7] +Open=1 +Top=0 +CursorCol=54 +CursorRow=35 +TopLine=3 +LeftChar=1 +[Editor_8] +Open=0 +Top=0 +CursorCol=1 +CursorRow=3 +TopLine=1 +LeftChar=1 +[Editor_10] +Open=0 +Top=0 diff --git a/c/jintellitype/JIntellitypeHandler.cpp b/c/jintellitype/JIntellitypeHandler.cpp new file mode 100644 index 0000000..666fc5d --- /dev/null +++ b/c/jintellitype/JIntellitypeHandler.cpp @@ -0,0 +1,279 @@ +/* + JIntellitype (http://www.melloware.com/) + Java JNI API for Windows Intellitype commands and global keystrokes. + + Copyright (C) 1999, 2008 Emil A. Lefkof III, info@melloware.com + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Compiled with Mingw port of GCC, + Bloodshed Dev-C++ IDE (http://www.bloodshed.net/devcpp.html) +*/ +#include "stdafx.h" +#include "JIntellitypeHandler.h" +#include "JIntellitypeThread.h" +#include + + +UINT WM_SHELLHOOK = 0; + +/* + * Extract the unique handlerID from the java object + */ +JIntellitypeHandler *JIntellitypeHandler::extract( JNIEnv *env, jobject object ) +{ + // Get field ID + jfieldID l_handlerId = env->GetFieldID( env->GetObjectClass( object ), "handler", "I" ); + + // Get field + JIntellitypeHandler *l_handler = (JIntellitypeHandler *) env->GetIntField( object, l_handlerId ); + + return l_handler; +} + +/* + * Constructor + */ +JIntellitypeHandler::JIntellitypeHandler( JNIEnv *env, jobject object ) +{ + m_window = NULL; + + // Reference object + m_object = env->NewGlobalRef(object ); + + // Get method IDs + m_fireHotKey = env->GetMethodID( env->GetObjectClass( m_object ) , "onHotKey", "(I)V" ); + m_fireIntellitype = env->GetMethodID( env->GetObjectClass( m_object ) , "onIntellitype", "(I)V" ); + + // Get field ID + jfieldID l_handlerId = env->GetFieldID( env->GetObjectClass( m_object ) , "handler", "I" ); + + // Set field + env->SetIntField( m_object, l_handlerId, (jint) this ); +} + +/* + * Destructor + */ +JIntellitypeHandler::~JIntellitypeHandler() +{ + // Get field ID + jfieldID l_handlerId = g_JIntellitypeThread.m_env->GetFieldID( g_JIntellitypeThread.m_env->GetObjectClass( m_object ), "handler", "I" ); + + // Set field + g_JIntellitypeThread.m_env->SetIntField( m_object, l_handlerId, 0 ); + + // Release our reference + g_JIntellitypeThread.m_env->DeleteGlobalRef( m_object ); + + // unregister the shell hook + DeregisterShellHookWindow( m_window ); + + // Destroy window + DestroyWindow( m_window ); +} + + +/* + * Perform initialization of the object and thread. + */ +void JIntellitypeHandler::initialize( JNIEnv *env, HINSTANCE instance ) +{ + m_instance = instance; + g_JIntellitypeThread.MakeSureThreadIsUp( env ); + while( !PostThreadMessage( g_JIntellitypeThread, WM_JINTELLITYPE, INITIALIZE_CODE, (LPARAM) this ) ) + Sleep( 0 ); +} + +/* + * Callback method that creates the hidden window on initialization to receive + * any WM_HOTKEY messages and process them. + */ +void JIntellitypeHandler::doInitialize() +{ + // Register window class + WNDCLASSEX l_Class; + l_Class.cbSize = sizeof( l_Class ); + l_Class.style = CS_HREDRAW | CS_VREDRAW; + l_Class.lpszClassName = TEXT( "JIntellitypeHandlerClass" ); + l_Class.lpfnWndProc = WndProc; + l_Class.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + l_Class.hCursor = NULL; + l_Class.hIcon = NULL; + l_Class.hIconSm = NULL; + l_Class.lpszMenuName = NULL; + l_Class.cbClsExtra = 0; + l_Class.cbWndExtra = 0; + l_Class.hInstance = m_instance; + + if( !RegisterClassEx( &l_Class ) ) + return; + + // Create window + m_window = CreateWindow + ( + TEXT( "JIntellitypeHandlerClass" ), + TEXT( "JIntellitypeHandler" ), + WS_OVERLAPPEDWINDOW, + 0, 0, 0, 0, + NULL, + NULL, + m_instance, + NULL + ); + + if( !m_window ) + return; + + //Set pointer to this object inside the Window's USERDATA section + SetWindowLong( m_window, GWL_USERDATA, (LONG) this ); + + // hide the window + ShowWindow(m_window, SW_HIDE); + UpdateWindow(m_window); + + //register this window as a shell hook to intercept WM_APPCOMMAND messages + WM_SHELLHOOK = RegisterWindowMessage(TEXT("SHELLHOOK")); + BOOL (__stdcall *RegisterShellHookWindow)(HWND) = NULL; + RegisterShellHookWindow = (BOOL (__stdcall *)(HWND))GetProcAddress(GetModuleHandle("USER32.DLL"), "RegisterShellHookWindow"); + + //make sure it worked + if (!RegisterShellHookWindow(m_window)) { + // throw exception + jclass JIntellitypeException = g_JIntellitypeThread.m_env->FindClass("com/melloware/jintellitype/JIntellitypeException"); + g_JIntellitypeThread.m_env->ThrowNew(JIntellitypeException,"Could not register window as a shell hook window."); + } +} + +/* + * Registers a hotkey. + * identifier - unique identifier assigned to this key comination + * modifier - ALT, SHIFT, CTRL, WIN or combination of + * keycode- Ascii keycode, 65 for A, 66 for B etc + */ +void JIntellitypeHandler::regHotKey( jint identifier, jint modifier, jint keycode ) +{ + JIntellitypeHandlerCallback *callback = (JIntellitypeHandlerCallback*) malloc(sizeof(JIntellitypeHandlerCallback)); + callback->identifier = identifier; + callback->modifier = modifier; + callback->keycode = keycode; + callback->handler = this; + PostThreadMessage( g_JIntellitypeThread, WM_JINTELLITYPE, REGISTER_HOTKEY_CODE, (LPARAM) callback ); +} + +/* + * Actually registers the hotkey using the Win32API RegisterHotKey call. + */ +void JIntellitypeHandler::doRegHotKey(LPARAM callback_) +{ + JIntellitypeHandlerCallback *callback = (JIntellitypeHandlerCallback*) callback_; + RegisterHotKey(m_window, callback->identifier, callback->modifier, callback->keycode); + free(callback); +} + +/* + * Unregisters a previously assigned hotkey. + * identifier - unique identifier assigned to this key comination + */ +void JIntellitypeHandler::unregHotKey( jint identifier ) +{ + JIntellitypeHandlerCallback *callback = (JIntellitypeHandlerCallback*) malloc(sizeof(JIntellitypeHandlerCallback)); + callback->identifier = identifier; + callback->handler = this; + PostThreadMessage( g_JIntellitypeThread, WM_JINTELLITYPE, UNREGISTER_HOTKEY_CODE, (LPARAM) callback ); +} + +/* + * Actually unregisters the hotkey using the Win32API UnregisterHotKey call. + */ +void JIntellitypeHandler::doUnregisterHotKey(LPARAM callback_) +{ + JIntellitypeHandlerCallback *callback = (JIntellitypeHandlerCallback*) callback_; + UnregisterHotKey(m_window, callback->identifier); + free(callback); +} + +/* + * When an intellitype command is recieved by the JFrame this method is called + * to perform a callback to the Intellitype java listeners. + * commandId - the unique command Id from the WM_APPCOMMAND listings + */ +void JIntellitypeHandler::intellitype( jint commandId ) +{ + JIntellitypeHandlerCallback *callback = (JIntellitypeHandlerCallback*) malloc(sizeof(JIntellitypeHandlerCallback)); + callback->command = commandId; + callback->handler = this; + PostThreadMessage( g_JIntellitypeThread, WM_JINTELLITYPE, INTELLITYPE_CODE, (LPARAM) callback ); +} + +/* + * Call the correct JVM with the intellitype command for the listeners listening. + */ +void JIntellitypeHandler::doIntellitype(LPARAM callback_) +{ + JIntellitypeHandlerCallback *callback = (JIntellitypeHandlerCallback*) callback_; + g_JIntellitypeThread.m_env->CallVoidMethod(m_object, m_fireIntellitype, callback->command); + free(callback); +} + +/* + * Cleans up resources allocated by JIntellitype. + */ +void JIntellitypeHandler::terminate() +{ + PostThreadMessage( g_JIntellitypeThread, WM_JINTELLITYPE, TERMINATE_CODE, (LPARAM) this ); +} + +/* + * Callback method to send hotkey to the Java HotKeyListeners registered. + */ +void JIntellitypeHandler::fireHotKey(jint hotkeyId) +{ + g_JIntellitypeThread.m_env->CallVoidMethod(m_object, m_fireHotKey, hotkeyId); +} + + +/* + * WndProc method registered to the hidden window to listen for WM_HOTKEY + * messages and send them back to the Java listeners. + */ +LRESULT CALLBACK JIntellitypeHandler::WndProc( HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam ) +{ + + // check for Intellitype messages and if found send them to Intellitype listeners + if (uMessage == WM_SHELLHOOK) { + if (wParam == HSHELL_APPCOMMAND) { + jint cmd = GET_APPCOMMAND_LPARAM(lParam); + JIntellitypeHandler *l_this = (JIntellitypeHandler *) GetWindowLong( hWnd, GWL_USERDATA ); + l_this->intellitype(cmd); + } + return TRUE; + } + + // check for registered hotkey messages and send them to HotKeyListeners + switch( uMessage ) { + case WM_HOTKEY: { + JIntellitypeHandler *l_this = (JIntellitypeHandler *) GetWindowLong( hWnd, GWL_USERDATA ); + l_this->fireHotKey(wParam); + return TRUE; + break; + } + default: + return DefWindowProc( hWnd, uMessage, wParam, lParam ); + } + +} + + + diff --git a/c/jintellitype/JIntellitypeHandler.h b/c/jintellitype/JIntellitypeHandler.h new file mode 100644 index 0000000..d003ff9 --- /dev/null +++ b/c/jintellitype/JIntellitypeHandler.h @@ -0,0 +1,93 @@ +/* + JIntellitype (http://www.melloware.com/) + Java JNI API for Windows Intellitype commands and global keystrokes. + + Copyright (C) 1999, 2008 Emil A. Lefkof III, info@melloware.com + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Compiled with Mingw port of GCC, + Bloodshed Dev-C++ IDE (http://www.bloodshed.net/devcpp.html) +*/ +#ifndef __JIntellitypeHandler_h__ +#define __JIntellitypeHandler_h__ + +#include "JIntellitypeThread.h" + +class JIntellitypeHandler +{ + friend DWORD WINAPI JIntellitypeThread::ThreadProc( LPVOID lpParameter ); + +public: + + static JIntellitypeHandler *extract( JNIEnv *env, jobject object ); + + JIntellitypeHandler( JNIEnv *env, jobject object ); + + void initialize( JNIEnv *env, HINSTANCE instance ); + void regHotKey( jint identifier, jint modifier, jint keycode ); + void unregHotKey( jint identifier ); + void intellitype( jint commandId ); + void terminate(); + +private: + + enum + { + INITIALIZE_CODE = 1, + REGISTER_HOTKEY_CODE = 2, + UNREGISTER_HOTKEY_CODE = 3, + TERMINATE_CODE = 4, + INTELLITYPE_CODE = 5 + }; + + ~JIntellitypeHandler(); + + void createHiddenWindow(); + void doInitialize(); + void doRegHotKey(LPARAM callback); + void doUnregisterHotKey(LPARAM callback); + void doIntellitype(LPARAM callback); + void fireHotKey(jint hotkeyId); + void fireIntellitype(jint commandId); + + HINSTANCE m_instance; + HWND m_window; + jobject m_object; + jmethodID m_fireHotKey; + jmethodID m_fireIntellitype; + + static LRESULT CALLBACK WndProc( HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam ); + static DWORD WINAPI ThreadProc( LPVOID lpParameter ); +}; + +typedef struct { + JIntellitypeHandler *handler; + jint identifier; + jint modifier; + jint keycode; + jint command; +} JIntellitypeHandlerCallback; + + +#ifndef WM_APPCOMMAND +#define WM_APPCOMMAND 0x319 +#define FAPPCOMMAND_MASK 0x8000 +#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK)) +#define HSHELL_APPCOMMAND 12 + +#endif + + +#endif diff --git a/c/jintellitype/JIntellitypeThread.cpp b/c/jintellitype/JIntellitypeThread.cpp new file mode 100644 index 0000000..dc55048 --- /dev/null +++ b/c/jintellitype/JIntellitypeThread.cpp @@ -0,0 +1,133 @@ +/* + JIntellitype (http://www.melloware.com/) + Java JNI API for Windows Intellitype commands and global keystrokes. + + Copyright (C) 1999, 2008 Emil A. Lefkof III, info@melloware.com + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Compiled with Mingw port of GCC, + Bloodshed Dev-C++ IDE (http://www.bloodshed.net/devcpp.html) +*/ +#include "stdafx.h" +#include "JIntellitypeThread.h" +#include "JIntellitypeHandler.h" + +JIntellitypeThread g_JIntellitypeThread; + + +JIntellitypeThread::JIntellitypeThread() +{ + m_env = NULL; + m_thread = 0; + m_vm = NULL; + m_handlerCount = 0; +} + + +void JIntellitypeThread::MakeSureThreadIsUp( JNIEnv *env ) +{ + if( !m_thread ) + { + // Get VM + env->GetJavaVM( &m_vm ); + + // Start "native" thread + CreateThread + ( + NULL, + 0, + ThreadProc, + this, + 0, + &m_thread + ); + } +} + + +JIntellitypeThread::operator DWORD () +{ + return m_thread; +} + + +DWORD WINAPI JIntellitypeThread::ThreadProc( LPVOID lpParameter ) +{ + JIntellitypeThread *l_this = (JIntellitypeThread *) lpParameter; + + // Attach the thread to the VM + l_this->m_vm->AttachCurrentThread( (void**) &l_this->m_env, NULL ); + + MSG msg; + while( GetMessage( &msg, NULL, 0, 0 ) ) + { + if( msg.message == WM_JINTELLITYPE ) + { + // Extract handler + JIntellitypeHandler *l_handler; + + switch( msg.wParam ) + { + case JIntellitypeHandler::INITIALIZE_CODE: + l_handler = (JIntellitypeHandler*) msg.lParam; + l_this->m_handlerCount++; + l_handler->doInitialize(); + break; + case JIntellitypeHandler::REGISTER_HOTKEY_CODE: + l_handler = ((JIntellitypeHandlerCallback*) msg.lParam)->handler; + l_handler->doRegHotKey(msg.lParam); + break; + + case JIntellitypeHandler::UNREGISTER_HOTKEY_CODE: + l_handler = ((JIntellitypeHandlerCallback*) msg.lParam)->handler; + l_handler->doUnregisterHotKey(msg.lParam); + break; + case JIntellitypeHandler::INTELLITYPE_CODE: + l_handler = ((JIntellitypeHandlerCallback*) msg.lParam)->handler; + l_handler->doIntellitype(msg.lParam); + break; + + case JIntellitypeHandler::TERMINATE_CODE: + l_handler = (JIntellitypeHandler*) msg.lParam; + + // Destroy it! + delete l_handler; + + // No more handlers? + if( !--l_this->m_handlerCount ) + { + l_this->m_thread = 0; + + // Detach thread from VM + l_this->m_vm->DetachCurrentThread(); + + // Time to die + ExitThread( 0 ); + } + break; + } + } + else + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + } + + // Detach thread from VM + l_this->m_vm->DetachCurrentThread(); + + return 0; +} diff --git a/c/jintellitype/JIntellitypeThread.h b/c/jintellitype/JIntellitypeThread.h new file mode 100644 index 0000000..10b09f9 --- /dev/null +++ b/c/jintellitype/JIntellitypeThread.h @@ -0,0 +1,55 @@ +/* + JIntellitype (http://www.melloware.com/) + Java JNI API for Windows Intellitype commands and global keystrokes. + + Copyright (C) 1999, 2008 Emil A. Lefkof III, info@melloware.com + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Compiled with Mingw port of GCC, + Bloodshed Dev-C++ IDE (http://www.bloodshed.net/devcpp.html) +*/ +#ifndef __JIntellitypeThread_h__ +#define __JIntellitypeThread_h__ + + +class JIntellitypeThread +{ +public: + + JIntellitypeThread(); + + void MakeSureThreadIsUp( JNIEnv *env ); + + JNIEnv *m_env; + static DWORD WINAPI ThreadProc( LPVOID lpParameter ); + + operator DWORD (); + +private: + + DWORD m_thread; + JavaVM *m_vm; + int m_handlerCount; + + +}; + +extern JIntellitypeThread g_JIntellitypeThread; + + +#define WM_JINTELLITYPE (WM_USER+1) + + +#endif diff --git a/c/jintellitype/JIntellitype_private.h b/c/jintellitype/JIntellitype_private.h new file mode 100644 index 0000000..1c7f45e --- /dev/null +++ b/c/jintellitype/JIntellitype_private.h @@ -0,0 +1,23 @@ +/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */ +/* DO NOT EDIT ! */ + +#ifndef JINTELLITYPE_PRIVATE_H +#define JINTELLITYPE_PRIVATE_H + +/* VERSION DEFINITIONS */ +#define VER_STRING "1.0.0.465" +#define VER_MAJOR 1 +#define VER_MINOR 0 +#define VER_RELEASE 0 +#define VER_BUILD 465 +#define COMPANY_NAME "Melloware Inc (www.melloware.com)" +#define FILE_VERSION "1.0" +#define FILE_DESCRIPTION "Java JNI bridge to MS Intellitype commands" +#define INTERNAL_NAME "" +#define LEGAL_COPYRIGHT "Copyright 2006 Melloware Inc" +#define LEGAL_TRADEMARKS "Copyright 2006 Melloware Inc" +#define ORIGINAL_FILENAME "" +#define PRODUCT_NAME "JIntellitype" +#define PRODUCT_VERSION "1.0" + +#endif /*JINTELLITYPE_PRIVATE_H*/ diff --git a/c/jintellitype/JIntellitype_private.rc b/c/jintellitype/JIntellitype_private.rc new file mode 100644 index 0000000..77374f8 --- /dev/null +++ b/c/jintellitype/JIntellitype_private.rc @@ -0,0 +1,35 @@ +/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */ +/* DO NOT EDIT! */ + +#include // include for version info constants + + +// +// TO CHANGE VERSION INFORMATION, EDIT PROJECT OPTIONS... +// +1 VERSIONINFO +FILEVERSION 1,0,0,465 +PRODUCTVERSION 1,0,0,465 +FILETYPE VFT_DLL +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "CompanyName", "Melloware Inc (www.melloware.com)" + VALUE "FileVersion", "1.0" + VALUE "FileDescription", "Java JNI bridge to MS Intellitype commands" + VALUE "InternalName", "" + VALUE "LegalCopyright", "Copyright 2006 Melloware Inc" + VALUE "LegalTrademarks", "Copyright 2006 Melloware Inc" + VALUE "OriginalFilename", "" + VALUE "ProductName", "JIntellitype" + VALUE "ProductVersion", "1.0" + } + } + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x0409, 1252 + } +} + diff --git a/c/jintellitype/Makefile.win b/c/jintellitype/Makefile.win new file mode 100644 index 0000000..0ad1b2c --- /dev/null +++ b/c/jintellitype/Makefile.win @@ -0,0 +1,46 @@ +# Project: JIntellitype +# Makefile created by Dev-C++ 4.9.9.2 + +CPP = g++.exe +CC = gcc.exe +WINDRES = windres.exe +RES = ../../../target/JIntellitype_private.res +OBJ = ../../../target/JIntellitypeThread.o ../../../target/JIntellitype.o ../../../target/JIntellitypeHandler.o ../../../target/StdAfx.o $(RES) +LINKOBJ = ../../../target/JIntellitypeThread.o ../../../target/JIntellitype.o ../../../target/JIntellitypeHandler.o ../../../target/StdAfx.o $(RES) +LIBS = -L"C:/Dev-Cpp/lib" -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 --no-export-all-symbols --add-stdcall-alias -s +INCS = -I"C:/Dev-Cpp/include" +CXXINCS = -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include" +BIN = ../../../../jintellitype/JIntellitype.dll +CXXFLAGS = $(CXXINCS) -D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -fexpensive-optimizations -O3 +CFLAGS = $(INCS) -D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -DBUILDING_DLL=1 -fexpensive-optimizations -O3 +RM = rm -f + +.PHONY: all all-before all-after clean clean-custom + +all: all-before ../../../../jintellitype/JIntellitype.dll all-after + + +clean: clean-custom + ${RM} $(OBJ) $(BIN) + +DLLWRAP=dllwrap.exe +DEFFILE=../../../../jintellitype/libJIntellitype.def +STATICLIB=../../../../jintellitype/libJIntellitype.a + +$(BIN): $(LINKOBJ) + $(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN) + +../../../target/JIntellitypeThread.o: JIntellitypeThread.cpp + $(CPP) -c JIntellitypeThread.cpp -o ../../../target/JIntellitypeThread.o $(CXXFLAGS) + +../../../target/JIntellitype.o: JIntellitype.cpp + $(CPP) -c JIntellitype.cpp -o ../../../target/JIntellitype.o $(CXXFLAGS) + +../../../target/JIntellitypeHandler.o: JIntellitypeHandler.cpp + $(CPP) -c JIntellitypeHandler.cpp -o ../../../target/JIntellitypeHandler.o $(CXXFLAGS) + +../../../target/StdAfx.o: StdAfx.cpp + $(CPP) -c StdAfx.cpp -o ../../../target/StdAfx.o $(CXXFLAGS) + +../../../target/JIntellitype_private.res: JIntellitype_private.rc + $(WINDRES) -i JIntellitype_private.rc --input-format=rc -o ../../../target/JIntellitype_private.res -O coff diff --git a/c/jintellitype/StdAfx.cpp b/c/jintellitype/StdAfx.cpp new file mode 100644 index 0000000..a10ee7b --- /dev/null +++ b/c/jintellitype/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// win32.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/c/jintellitype/StdAfx.h b/c/jintellitype/StdAfx.h new file mode 100644 index 0000000..7203ae8 --- /dev/null +++ b/c/jintellitype/StdAfx.h @@ -0,0 +1,24 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__1F571525_24C2_11D3_B0CF_0000E85D9A83__INCLUDED_) +#define AFX_STDAFX_H__1F571525_24C2_11D3_B0CF_0000E85D9A83__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +// Insert your headers here +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include +#include + +#include + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__1F571525_24C2_11D3_B0CF_0000E85D9A83__INCLUDED_) diff --git a/c/jintellitype/com_melloware_jintellitype_JIntellitype.h b/c/jintellitype/com_melloware_jintellitype_JIntellitype.h new file mode 100644 index 0000000..2394ca6 --- /dev/null +++ b/c/jintellitype/com_melloware_jintellitype_JIntellitype.h @@ -0,0 +1,53 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_melloware_jintellitype_JIntellitype */ + +#ifndef _Included_com_melloware_jintellitype_JIntellitype +#define _Included_com_melloware_jintellitype_JIntellitype +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: initializeLibrary + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_initializeLibrary + (JNIEnv *, jobject); + +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: regHotKey + * Signature: (III)V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_regHotKey + (JNIEnv *, jobject, jint, jint, jint); + +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: terminate + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_terminate + (JNIEnv *, jobject); + +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: unregHotKey + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_com_melloware_jintellitype_JIntellitype_unregHotKey + (JNIEnv *, jobject, jint); + +/* + * Class: com_melloware_jintellitype_JIntellitype + * Method: isRunning + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_com_melloware_jintellitype_JIntellitype_isRunning + (JNIEnv *, jclass, jstring); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/c/wiiuse/classic.c b/c/wiiuse/classic.c new file mode 100644 index 0000000..1d2c3ab --- /dev/null +++ b/c/wiiuse/classic.c @@ -0,0 +1,190 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Classic controller expansion device. + */ + +#include +#include +#include + +#ifdef WIN32 + #include +#endif + +#include "definitions.h" +#include "wiiuse_internal.h" +#include "dynamics.h" +#include "events.h" +#include "classic.h" + +static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now); + +/** + * @brief Handle the handshake data from the classic controller. + * + * @param cc A pointer to a classic_ctrl_t structure. + * @param data The data read in from the device. + * @param len The length of the data block, in bytes. + * + * @return Returns 1 if handshake was successful, 0 if not. + */ +int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte* data, unsigned short len) { + int i; + int offset = 0; + + cc->btns = 0; + cc->btns_held = 0; + cc->btns_released = 0; + cc->r_shoulder = 0; + cc->l_shoulder = 0; + + /* decrypt data */ + for (i = 0; i < len; ++i) + data[i] = (data[i] ^ 0x17) + 0x17; + + if (data[offset] == 0xFF) { + /* + * Sometimes the data returned here is not correct. + * This might happen because the wiimote is lagging + * behind our initialization sequence. + * To fix this just request the handshake again. + * + * Other times it's just the first 16 bytes are 0xFF, + * but since the next 16 bytes are the same, just use + * those. + */ + if (data[offset + 16] == 0xFF) { + /* get the calibration data */ + byte* handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte)); + + WIIUSE_DEBUG("Classic controller handshake appears invalid, trying again."); + wiiuse_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN); + + return 0; + } else + offset += 16; + } + + + /* joystick stuff */ + cc->ljs.max.x = data[0 + offset] / 4; + cc->ljs.min.x = data[1 + offset] / 4; + cc->ljs.center.x = data[2 + offset] / 4; + cc->ljs.max.y = data[3 + offset] / 4; + cc->ljs.min.y = data[4 + offset] / 4; + cc->ljs.center.y = data[5 + offset] / 4; + + cc->rjs.max.x = data[6 + offset] / 8; + cc->rjs.min.x = data[7 + offset] / 8; + cc->rjs.center.x = data[8 + offset] / 8; + cc->rjs.max.y = data[9 + offset] / 8; + cc->rjs.min.y = data[10 + offset] / 8; + cc->rjs.center.y = data[11 + offset] / 8; + + /* handshake done */ + wm->exp.type = EXP_CLASSIC; + + #ifdef WIN32 + wm->timeout = WIIMOTE_DEFAULT_TIMEOUT; + #endif + + return 1; +} + + +/** + * @brief The classic controller disconnected. + * + * @param cc A pointer to a classic_ctrl_t structure. + */ +void classic_ctrl_disconnected(struct classic_ctrl_t* cc) { + memset(cc, 0, sizeof(struct classic_ctrl_t)); +} + + + +/** + * @brief Handle classic controller event. + * + * @param cc A pointer to a classic_ctrl_t structure. + * @param msg The message specified in the event packet. + */ +void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg) { + int i, lx, ly, rx, ry; + byte l, r; + + /* decrypt data */ + for (i = 0; i < 6; ++i) + msg[i] = (msg[i] ^ 0x17) + 0x17; + + classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 4))); + + /* left/right buttons */ + l = (((msg[2] & 0x60) >> 2) | ((msg[3] & 0xE0) >> 5)); + r = (msg[3] & 0x1F); + + /* + * TODO - LR range hardcoded from 0x00 to 0x1F. + * This is probably in the calibration somewhere. + */ + cc->r_shoulder = ((float)r / 0x1F); + cc->l_shoulder = ((float)l / 0x1F); + + /* calculate joystick orientation */ + lx = (msg[0] & 0x3F); + ly = (msg[1] & 0x3F); + rx = ((msg[0] & 0xC0) >> 3) | ((msg[1] & 0xC0) >> 5) | ((msg[2] & 0x80) >> 7); + ry = (msg[2] & 0x1F); + + calc_joystick_state(&cc->ljs, lx, ly); + calc_joystick_state(&cc->rjs, rx, ry); +} + + +/** + * @brief Find what buttons are pressed. + * + * @param cc A pointer to a classic_ctrl_t structure. + * @param msg The message byte specified in the event packet. + */ +static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now) { + /* message is inverted (0 is active, 1 is inactive) */ + now = ~now & CLASSIC_CTRL_BUTTON_ALL; + + /* pressed now & were pressed, then held */ + cc->btns_held = (now & cc->btns); + + /* were pressed or were held & not pressed now, then released */ + cc->btns_released = ((cc->btns | cc->btns_held) & ~now); + + /* buttons pressed now */ + cc->btns = now; +} diff --git a/c/wiiuse/classic.h b/c/wiiuse/classic.h new file mode 100644 index 0000000..356f6a4 --- /dev/null +++ b/c/wiiuse/classic.h @@ -0,0 +1,53 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Classic controller expansion device. + */ + +#ifndef CLASSIC_H_INCLUDED +#define CLASSIC_H_INCLUDED + +#include "wiiuse_internal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte* data, unsigned short len); + +void classic_ctrl_disconnected(struct classic_ctrl_t* cc); + +void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg); + +#ifdef __cplusplus +} +#endif + +#endif // CLASSIC_H_INCLUDED diff --git a/c/wiiuse/definitions.h b/c/wiiuse/definitions.h new file mode 100644 index 0000000..5a8da85 --- /dev/null +++ b/c/wiiuse/definitions.h @@ -0,0 +1,79 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief General definitions. + */ + +#ifndef DEFINITIONS_H_INCLUDED +#define DEFINITIONS_H_INCLUDED + +/* this is wiiuse - used to distinguish from third party programs using wiiuse.h */ +#include "os.h" + +#define WIIMOTE_PI 3.14159265f + +//#define WITH_WIIUSE_DEBUG + +/* Error output macros */ +#define WIIUSE_ERROR(fmt, ...) fprintf(stderr, "[ERROR] " fmt "\n", ##__VA_ARGS__) + +/* Warning output macros */ +#define WIIUSE_WARNING(fmt, ...) fprintf(stderr, "[WARNING] " fmt "\n", ##__VA_ARGS__) + +/* Information output macros */ +#define WIIUSE_INFO(fmt, ...) fprintf(stderr, "[INFO] " fmt "\n", ##__VA_ARGS__) + +#ifdef WITH_WIIUSE_DEBUG + #ifdef WIN32 + #define WIIUSE_DEBUG(fmt, ...) do { \ + char* file = __FILE__; \ + int i = strlen(file) - 1; \ + for (; i && (file[i] != '\\'); --i); \ + fprintf(stderr, "[DEBUG] %s:%i: " fmt "\n", file+i+1, __LINE__, ##__VA_ARGS__); \ + } while (0) + #else + #define WIIUSE_DEBUG(fmt, ...) fprintf(stderr, "[DEBUG] " __FILE__ ":%i: " fmt "\n", __LINE__, ##__VA_ARGS__) + #endif +#else + #define WIIUSE_DEBUG(fmt, ...) +#endif + +/* Convert between radians and degrees */ +#define RAD_TO_DEGREE(r) ((r * 180.0f) / WIIMOTE_PI) +#define DEGREE_TO_RAD(d) (d * (WIIMOTE_PI / 180.0f)) + +/* Convert to big endian */ +#define BIG_ENDIAN_LONG(i) (htonl(i)) +#define BIG_ENDIAN_SHORT(i) (htons(i)) + +#define absf(x) ((x >= 0) ? (x) : (x * -1.0f)) +#define diff_f(x, y) ((x >= y) ? (absf(x - y)) : (absf(y - x))) + +#endif // DEFINITIONS_H_INCLUDED diff --git a/c/wiiuse/dynamics.c b/c/wiiuse/dynamics.c new file mode 100644 index 0000000..53612a6 --- /dev/null +++ b/c/wiiuse/dynamics.c @@ -0,0 +1,228 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Handles the dynamics of the wiimote. + * + * The file includes functions that handle the dynamics + * of the wiimote. Such dynamics include orientation and + * motion sensing. + */ + +#include +#include +#include + +#ifdef WIN32 + #include +#endif + +#include "definitions.h" +#include "wiiuse_internal.h" +#include "ir.h" +#include "dynamics.h" + +/** + * @brief Calculate the roll, pitch, yaw. + * + * @param ac An accelerometer (accel_t) structure. + * @param accel [in] Pointer to a vec3b_t structure that holds the raw acceleration data. + * @param orient [out] Pointer to a orient_t structure that will hold the orientation data. + * @param rorient [out] Pointer to a orient_t structure that will hold the non-smoothed orientation data. + * @param smooth If smoothing should be performed on the angles calculated. 1 to enable, 0 to disable. + * + * Given the raw acceleration data from the accelerometer struct, calculate + * the orientation of the device and set it in the \a orient parameter. + */ +void calculate_orientation(struct accel_t* ac, struct vec3b_t* accel, struct orient_t* orient, int smooth) { + float xg, yg, zg; + float x, y, z; + + /* + * roll - use atan(z / x) [ ranges from -180 to 180 ] + * pitch - use atan(z / y) [ ranges from -180 to 180 ] + * yaw - impossible to tell without IR + */ + + /* yaw - set to 0, IR will take care of it if it's enabled */ + orient->yaw = 0.0f; + + /* find out how much it has to move to be 1g */ + xg = (float)ac->cal_g.x; + yg = (float)ac->cal_g.y; + zg = (float)ac->cal_g.z; + + /* find out how much it actually moved and normalize to +/- 1g */ + x = ((float)accel->x - (float)ac->cal_zero.x) / xg; + y = ((float)accel->y - (float)ac->cal_zero.y) / yg; + z = ((float)accel->z - (float)ac->cal_zero.z) / zg; + + /* make sure x,y,z are between -1 and 1 for the tan functions */ + if (x < -1.0f) x = -1.0f; + else if (x > 1.0f) x = 1.0f; + if (y < -1.0f) y = -1.0f; + else if (y > 1.0f) y = 1.0f; + if (z < -1.0f) z = -1.0f; + else if (z > 1.0f) z = 1.0f; + + /* if it is over 1g then it is probably accelerating and not reliable */ + if (abs(accel->x - ac->cal_zero.x) <= ac->cal_g.x) { + /* roll */ + x = RAD_TO_DEGREE(atan2f(x, z)); + + orient->roll = x; + orient->a_roll = x; + } + + if (abs(accel->y - ac->cal_zero.y) <= ac->cal_g.y) { + /* pitch */ + y = RAD_TO_DEGREE(atan2f(y, z)); + + orient->pitch = y; + orient->a_pitch = y; + } + + /* smooth the angles if enabled */ + if (smooth) { + apply_smoothing(ac, orient, SMOOTH_ROLL); + apply_smoothing(ac, orient, SMOOTH_PITCH); + } +} + + +/** + * @brief Calculate the gravity forces on each axis. + * + * @param ac An accelerometer (accel_t) structure. + * @param accel [in] Pointer to a vec3b_t structure that holds the raw acceleration data. + * @param gforce [out] Pointer to a gforce_t structure that will hold the gravity force data. + */ +void calculate_gforce(struct accel_t* ac, struct vec3b_t* accel, struct gforce_t* gforce) { + float xg, yg, zg; + + /* find out how much it has to move to be 1g */ + xg = (float)ac->cal_g.x; + yg = (float)ac->cal_g.y; + zg = (float)ac->cal_g.z; + + /* find out how much it actually moved and normalize to +/- 1g */ + gforce->x = ((float)accel->x - (float)ac->cal_zero.x) / xg; + gforce->y = ((float)accel->y - (float)ac->cal_zero.y) / yg; + gforce->z = ((float)accel->z - (float)ac->cal_zero.z) / zg; +} + + +/** + * @brief Calculate the angle and magnitude of a joystick. + * + * @param js [out] Pointer to a joystick_t structure. + * @param x The raw x-axis value. + * @param y The raw y-axis value. + */ +void calc_joystick_state(struct joystick_t* js, float x, float y) { + float rx, ry, ang; + + /* + * Since the joystick center may not be exactly: + * (min + max) / 2 + * Then the range from the min to the center and the center to the max + * may be different. + * Because of this, depending on if the current x or y value is greater + * or less than the assoicated axis center value, it needs to be interpolated + * between the center and the minimum or maxmimum rather than between + * the minimum and maximum. + * + * So we have something like this: + * (x min) [-1] ---------*------ [0] (x center) [0] -------- [1] (x max) + * Where the * is the current x value. + * The range is therefore -1 to 1, 0 being the exact center rather than + * the middle of min and max. + */ + if (x == js->center.x) + rx = 0; + else if (x >= js->center.x) + rx = ((float)(x - js->center.x) / (float)(js->max.x - js->center.x)); + else + rx = ((float)(x - js->min.x) / (float)(js->center.x - js->min.x)) - 1.0f; + + if (y == js->center.y) + ry = 0; + else if (y >= js->center.y) + ry = ((float)(y - js->center.y) / (float)(js->max.y - js->center.y)); + else + ry = ((float)(y - js->min.y) / (float)(js->center.y - js->min.y)) - 1.0f; + + /* calculate the joystick angle and magnitude */ + ang = RAD_TO_DEGREE(atanf(ry / rx)); + ang -= 90.0f; + if (rx < 0.0f) + ang -= 180.0f; + js->ang = absf(ang); + js->mag = (float) sqrt((rx * rx) + (ry * ry)); +} + + +void apply_smoothing(struct accel_t* ac, struct orient_t* orient, int type) { + switch (type) { + case SMOOTH_ROLL: + { + /* it's possible last iteration was nan or inf, so set it to 0 if that happened */ + if (isnan(ac->st_roll) || isinf(ac->st_roll)) + ac->st_roll = 0.0f; + + /* + * If the sign changes (which will happen if going from -180 to 180) + * or from (-1 to 1) then don't smooth, just use the new angle. + */ + if (((ac->st_roll < 0) && (orient->roll > 0)) || ((ac->st_roll > 0) && (orient->roll < 0))) { + ac->st_roll = orient->roll; + } else { + orient->roll = ac->st_roll + (ac->st_alpha * (orient->a_roll - ac->st_roll)); + ac->st_roll = orient->roll; + } + + return; + } + + case SMOOTH_PITCH: + { + if (isnan(ac->st_pitch) || isinf(ac->st_pitch)) + ac->st_pitch = 0.0f; + + if (((ac->st_pitch < 0) && (orient->pitch > 0)) || ((ac->st_pitch > 0) && (orient->pitch < 0))) { + ac->st_pitch = orient->pitch; + } else { + orient->pitch = ac->st_pitch + (ac->st_alpha * (orient->a_pitch - ac->st_pitch)); + ac->st_pitch = orient->pitch; + } + + return; + } + } +} diff --git a/c/wiiuse/dynamics.h b/c/wiiuse/dynamics.h new file mode 100644 index 0000000..2a8f965 --- /dev/null +++ b/c/wiiuse/dynamics.h @@ -0,0 +1,56 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Handles the dynamics of the wiimote. + * + * The file includes functions that handle the dynamics + * of the wiimote. Such dynamics include orientation and + * motion sensing. + */ + +#ifndef DYNAMICS_H_INCLUDED +#define DYNAMICS_H_INCLUDED + +#include "wiiuse_internal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void calculate_orientation(struct accel_t* ac, struct vec3b_t* accel, struct orient_t* orient, int smooth); +void calculate_gforce(struct accel_t* ac, struct vec3b_t* accel, struct gforce_t* gforce); +void calc_joystick_state(struct joystick_t* js, float x, float y); +void apply_smoothing(struct accel_t* ac, struct orient_t* orient, int type); + +#ifdef __cplusplus +} +#endif + +#endif // DYNAMICS_H_INCLUDED diff --git a/c/wiiuse/events.c b/c/wiiuse/events.c new file mode 100644 index 0000000..6668eda --- /dev/null +++ b/c/wiiuse/events.c @@ -0,0 +1,878 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Handles wiimote events. + * + * The file includes functions that handle the events + * that are sent from the wiimote to us. + */ + +#include + +#ifndef WIN32 + #include + #include + #include +#else + #include +#endif + +#include +#include +#include + +#include "definitions.h" +#include "io.h" +#include "wiiuse_internal.h" +#include "dynamics.h" +#include "ir.h" +#include "nunchuk.h" +#include "classic.h" +#include "guitar_hero_3.h" +#include "events.h" + +static void idle_cycle(struct wiimote_t* wm); +static void clear_dirty_reads(struct wiimote_t* wm); +static void propagate_event(struct wiimote_t* wm, byte event, byte* msg); +static void event_data_read(struct wiimote_t* wm, byte* msg); +static void event_status(struct wiimote_t* wm, byte* msg); +static void handle_expansion(struct wiimote_t* wm, byte* msg); + +static void save_state(struct wiimote_t* wm); +static int state_changed(struct wiimote_t* wm); + +/** + * @brief Poll the wiimotes for any events. + * + * @param wm An array of pointers to wiimote_t structures. + * @param wiimotes The number of wiimote_t structures in the \a wm array. + * + * @return Returns number of wiimotes that an event has occured on. + * + * It is necessary to poll the wiimote devices for events + * that occur. If an event occurs on a particular wiimote, + * the event variable will be set. + */ +int wiiuse_poll(struct wiimote_t** wm, int wiimotes) { + int evnt = 0; + + #ifndef WIN32 + /* + * *nix + */ + struct timeval tv; + fd_set fds; + int r; + int i; + int highest_fd = -1; + + if (!wm) return 0; + + /* block select() for 1/2000th of a second */ + tv.tv_sec = 0; + tv.tv_usec = 500; + + FD_ZERO(&fds); + + for (i = 0; i < wiimotes; ++i) { + /* only poll it if it is connected */ + if (WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_CONNECTED)) { + FD_SET(wm[i]->in_sock, &fds); + + /* find the highest fd of the connected wiimotes */ + if (wm[i]->in_sock > highest_fd) + highest_fd = wm[i]->in_sock; + } + + wm[i]->event = WIIUSE_NONE; + } + + if (highest_fd == -1) + /* nothing to poll */ + return 0; + + if (select(highest_fd + 1, &fds, NULL, NULL, &tv) == -1) { + WIIUSE_ERROR("Unable to select() the wiimote interrupt socket(s)."); + perror("Error Details"); + return 0; + } + + /* check each socket for an event */ + for (i = 0; i < wiimotes; ++i) { + /* if this wiimote is not connected, skip it */ + if (!WIIMOTE_IS_CONNECTED(wm[i])) + continue; + + if (FD_ISSET(wm[i]->in_sock, &fds)) { + /* clear out the event buffer */ + memset(wm[i]->event_buf, 0, sizeof(wm[i]->event_buf)); + + /* clear out any old read requests */ + clear_dirty_reads(wm[i]); + + /* read the pending message into the buffer */ + r = read(wm[i]->in_sock, wm[i]->event_buf, sizeof(wm[i]->event_buf)); + if (r == -1) { + /* error reading data */ + WIIUSE_ERROR("Receiving wiimote data (id %i).", wm[i]->unid); + perror("Error Details"); + + if (errno == ENOTCONN) { + /* this can happen if the bluetooth dongle is disconnected */ + WIIUSE_ERROR("Bluetooth appears to be disconnected. Wiimote unid %i will be disconnected.", wm[i]->unid); + wiiuse_disconnect(wm[i]); + wm[i]->event = WIIUSE_UNEXPECTED_DISCONNECT; + } + + continue; + } + if (!r) { + /* remote disconnect */ + wiiuse_disconnected(wm[i]); + evnt = 1; + continue; + } + + /* propagate the event */ + propagate_event(wm[i], wm[i]->event_buf[1], wm[i]->event_buf+2); + evnt += (wm[i]->event != WIIUSE_NONE); + } else { + idle_cycle(wm[i]); + } + } + #else + /* + * Windows + */ + int i; + + if (!wm) return 0; + + for (i = 0; i < wiimotes; ++i) { + wm[i]->event = WIIUSE_NONE; + + if (wiiuse_io_read(wm[i])) { + /* propagate the event */ + propagate_event(wm[i], wm[i]->event_buf[0], wm[i]->event_buf+1); + evnt += (wm[i]->event != WIIUSE_NONE); + + /* clear out the event buffer */ + memset(wm[i]->event_buf, 0, sizeof(wm[i]->event_buf)); + } else { + idle_cycle(wm[i]); + } + } + #endif + + return evnt; +} + + +/** + * @brief Called on a cycle where no significant change occurs. + * + * @param wm Pointer to a wiimote_t structure. + */ +static void idle_cycle(struct wiimote_t* wm) { + /* + * Smooth the angles. + * + * This is done to make sure that on every cycle the orientation + * angles are smoothed. Normally when an event occurs the angles + * are updated and smoothed, but if no packet comes in then the + * angles remain the same. This means the angle wiiuse reports + * is still an old value. Smoothing needs to be applied in this + * case in order for the angle it reports to converge to the true + * angle of the device. + */ + if (WIIUSE_USING_ACC(wm) && WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING)) { + apply_smoothing(&wm->accel_calib, &wm->orient, SMOOTH_ROLL); + apply_smoothing(&wm->accel_calib, &wm->orient, SMOOTH_PITCH); + } + + /* clear out any old read requests */ + clear_dirty_reads(wm); +} + + +/** + * @brief Clear out all old 'dirty' read requests. + * + * @param wm Pointer to a wiimote_t structure. + */ +static void clear_dirty_reads(struct wiimote_t* wm) { + struct read_req_t* req = wm->read_req; + + while (req && req->dirty) { + WIIUSE_DEBUG("Cleared old read request for address: %x", req->addr); + + wm->read_req = req->next; + free(req); + req = wm->read_req; + } +} + + +/** + * @brief Analyze the event that occured on a wiimote. + * + * @param wm An array of pointers to wiimote_t structures. + * @param event The event that occured. + * @param msg The message specified in the event packet. + * + * Pass the event to the registered event callback. + */ +static void propagate_event(struct wiimote_t* wm, byte event, byte* msg) { + save_state(wm); + + switch (event) { + case WM_RPT_BTN: + { + /* button */ + wiiuse_pressed_buttons(wm, msg); + break; + } + case WM_RPT_BTN_ACC: + { + /* button - motion */ + wiiuse_pressed_buttons(wm, msg); + + wm->accel.x = msg[2]; + wm->accel.y = msg[3]; + wm->accel.z = msg[4]; + + /* calculate the remote orientation */ + calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING)); + + /* calculate the gforces on each axis */ + calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce); + + break; + } + case WM_RPT_READ: + { + /* data read */ + event_data_read(wm, msg); + + /* yeah buttons may be pressed, but this wasn't an "event" */ + return; + } + case WM_RPT_CTRL_STATUS: + { + /* controller status */ + event_status(wm, msg); + + /* don't execute the event callback */ + return; + } + case WM_RPT_BTN_EXP: + { + /* button - expansion */ + wiiuse_pressed_buttons(wm, msg); + handle_expansion(wm, msg+2); + + break; + } + case WM_RPT_BTN_ACC_EXP: + { + /* button - motion - expansion */ + wiiuse_pressed_buttons(wm, msg); + + wm->accel.x = msg[2]; + wm->accel.y = msg[3]; + wm->accel.z = msg[4]; + + calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING)); + calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce); + + handle_expansion(wm, msg+5); + + break; + } + case WM_RPT_BTN_ACC_IR: + { + /* button - motion - ir */ + wiiuse_pressed_buttons(wm, msg); + + wm->accel.x = msg[2]; + wm->accel.y = msg[3]; + wm->accel.z = msg[4]; + + calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING)); + calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce); + + /* ir */ + calculate_extended_ir(wm, msg+5); + + break; + } + case WM_RPT_BTN_IR_EXP: + { + /* button - ir - expansion */ + wiiuse_pressed_buttons(wm, msg); + handle_expansion(wm, msg+12); + + /* ir */ + calculate_basic_ir(wm, msg+2); + + break; + } + case WM_RPT_BTN_ACC_IR_EXP: + { + /* button - motion - ir - expansion */ + wiiuse_pressed_buttons(wm, msg); + + wm->accel.x = msg[2]; + wm->accel.y = msg[3]; + wm->accel.z = msg[4]; + + calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING)); + calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce); + + handle_expansion(wm, msg+15); + + /* ir */ + calculate_basic_ir(wm, msg+5); + + break; + } + case WM_RPT_WRITE: + { + /* write feedback - safe to skip */ + break; + } + default: + { + WIIUSE_WARNING("Unknown event, can not handle it [Code 0x%x].", event); + return; + } + } + + /* was there an event? */ + if (state_changed(wm)) + wm->event = WIIUSE_EVENT; +} + + +/** + * @brief Find what buttons are pressed. + * + * @param wm Pointer to a wiimote_t structure. + * @param msg The message specified in the event packet. + */ +void wiiuse_pressed_buttons(struct wiimote_t* wm, byte* msg) { + short now; + + /* convert to big endian */ + now = BIG_ENDIAN_SHORT(*(short*)msg) & WIIMOTE_BUTTON_ALL; + + /* pressed now & were pressed, then held */ + wm->btns_held = (now & wm->btns); + + /* were pressed or were held & not pressed now, then released */ + wm->btns_released = ((wm->btns | wm->btns_held) & ~now); + + /* buttons pressed now */ + wm->btns = now; +} + + +/** + * @brief Received a data packet from a read request. + * + * @param wm Pointer to a wiimote_t structure. + * @param msg The message specified in the event packet. + * + * Data from the wiimote comes in packets. If the requested + * data segment size is bigger than one packet can hold then + * several packets will be received. These packets are first + * reassembled into one, then the registered callback function + * that handles data reads is invoked. + */ +static void event_data_read(struct wiimote_t* wm, byte* msg) { + /* we must always assume the packet received is from the most recent request */ + byte err; + byte len; + unsigned short offset; + struct read_req_t* req = wm->read_req; + + wiiuse_pressed_buttons(wm, msg); + + /* find the next non-dirty request */ + while (req && req->dirty) + req = req->next; + + /* if we don't have a request out then we didn't ask for this packet */ + if (!req) { + WIIUSE_WARNING("Received data packet when no request was made."); + return; + } + + err = msg[2] & 0x0F; + + if (err == 0x08) + WIIUSE_WARNING("Unable to read data - address does not exist."); + else if (err == 0x07) + WIIUSE_WARNING("Unable to read data - address is for write-only registers."); + else if (err) + WIIUSE_WARNING("Unable to read data - unknown error code %x.", err); + + if (err) { + /* this request errored out, so skip it and go to the next one */ + + /* delete this request */ + wm->read_req = req->next; + free(req); + + /* if another request exists send it to the wiimote */ + if (wm->read_req) + wiiuse_send_next_pending_read_request(wm); + + return; + } + + len = ((msg[2] & 0xF0) >> 4) + 1; + offset = BIG_ENDIAN_SHORT(*(unsigned short*)(msg + 3)); + req->addr = (req->addr & 0xFFFF); + + req->wait -= len; + if (req->wait >= req->size) + /* this should never happen */ + req->wait = 0; + + WIIUSE_DEBUG("Received read packet:"); + WIIUSE_DEBUG(" Packet read offset: %i bytes", offset); + WIIUSE_DEBUG(" Request read offset: %i bytes", req->addr); + WIIUSE_DEBUG(" Read offset into buf: %i bytes", offset - req->addr); + WIIUSE_DEBUG(" Read data size: %i bytes", len); + WIIUSE_DEBUG(" Still need: %i bytes", req->wait); + + /* reconstruct this part of the data */ + memcpy((req->buf + offset - req->addr), (msg + 5), len); + + #ifdef WITH_WIIUSE_DEBUG + { + int i = 0; + printf("Read: "); + for (; i < req->size - req->wait; ++i) + printf("%x ", req->buf[i]); + printf("\n"); + } + #endif + + /* if all data has been received, execute the read event callback or generate event */ + if (!req->wait) { + if (req->cb) { + /* this was a callback, so invoke it now */ + req->cb(wm, req->buf, req->size); + + /* delete this request */ + wm->read_req = req->next; + free(req); + } else { + /* + * This should generate an event. + * We need to leave the event in the array so the client + * can access it still. We'll flag is as being 'dirty' + * and give the client one cycle to use it. Next event + * we will remove it from the list. + */ + wm->event = WIIUSE_READ_DATA; + req->dirty = 1; + } + + /* if another request exists send it to the wiimote */ + if (wm->read_req) + wiiuse_send_next_pending_read_request(wm); + } +} + + +/** + * @brief Read the controller status. + * + * @param wm Pointer to a wiimote_t structure. + * @param msg The message specified in the event packet. + * + * Read the controller status and execute the registered status callback. + */ +static void event_status(struct wiimote_t* wm, byte* msg) { + int led[4] = {0}; + int attachment = 0; + int ir = 0; + int exp_changed = 0; + + /* + * An event occured. + * This event can be overwritten by a more specific + * event type during a handshake or expansion removal. + */ + wm->event = WIIUSE_STATUS; + + wiiuse_pressed_buttons(wm, msg); + + /* find what LEDs are lit */ + if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_1) led[0] = 1; + if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_2) led[1] = 1; + if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_3) led[2] = 1; + if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_4) led[3] = 1; + + /* is an attachment connected to the expansion port? */ + if ((msg[2] & WM_CTRL_STATUS_BYTE1_ATTACHMENT) == WM_CTRL_STATUS_BYTE1_ATTACHMENT) + attachment = 1; + + /* is the speaker enabled? */ + if ((msg[2] & WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED) == WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED) + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_SPEAKER); + + /* is IR sensing enabled? */ + if ((msg[2] & WM_CTRL_STATUS_BYTE1_IR_ENABLED) == WM_CTRL_STATUS_BYTE1_IR_ENABLED) + ir = 1; + + /* find the battery level and normalize between 0 and 1 */ + wm->battery_level = (msg[5] / (float)WM_MAX_BATTERY_CODE); + + /* expansion port */ + if (attachment && !WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) { + /* send the initialization code for the attachment */ + handshake_expansion(wm, NULL, 0); + exp_changed = 1; + } else if (!attachment && WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) { + /* attachment removed */ + disable_expansion(wm); + exp_changed = 1; + } + + #ifdef WIN32 + if (!attachment) { + WIIUSE_DEBUG("Setting timeout to normal %i ms.", wm->normal_timeout); + wm->timeout = wm->normal_timeout; + } + #endif + + /* + * From now on the remote will only send status packets. + * We need to send a WIIMOTE_CMD_REPORT_TYPE packet to + * reenable other incoming reports. + */ + if (exp_changed && WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) { + /* + * Since the expansion status changed IR needs to + * be reset for the new IR report mode. + */ + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR); + wiiuse_set_ir(wm, 1); + } else + wiiuse_set_report_type(wm); +} + + +/** + * @brief Handle data from the expansion. + * + * @param wm A pointer to a wiimote_t structure. + * @param msg The message specified in the event packet for the expansion. + */ +static void handle_expansion(struct wiimote_t* wm, byte* msg) { + switch (wm->exp.type) { + case EXP_NUNCHUK: + nunchuk_event(&wm->exp.nunchuk, msg); + break; + case EXP_CLASSIC: + classic_ctrl_event(&wm->exp.classic, msg); + break; + case EXP_GUITAR_HERO_3: + guitar_hero_3_event(&wm->exp.gh3, msg); + break; + default: + break; + } +} + + +/** + * @brief Handle the handshake data from the expansion device. + * + * @param wm A pointer to a wiimote_t structure. + * @param data The data read in from the device. + * @param len The length of the data block, in bytes. + * + * Tries to determine what kind of expansion was attached + * and invoke the correct handshake function. + * + * If the data is NULL then this function will try to start + * a handshake with the expansion. + */ +void handshake_expansion(struct wiimote_t* wm, byte* data, unsigned short len) { + int id; + + if (!data) { + byte* handshake_buf; + byte buf = 0x00; + + if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) + disable_expansion(wm); + + /* increase the timeout until the handshake completes */ + #ifdef WIN32 + WIIUSE_DEBUG("Setting timeout to expansion %i ms.", wm->exp_timeout); + wm->timeout = wm->exp_timeout; + #endif + + wiiuse_write_data(wm, WM_EXP_MEM_ENABLE, &buf, 1); + + /* get the calibration data */ + handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte)); + wiiuse_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN); + + /* tell the wiimote to send expansion data */ + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP); + + return; + } + + id = BIG_ENDIAN_LONG(*(int*)(data + 220)); + + /* call the corresponding handshake function for this expansion */ + switch (id) { + case EXP_ID_CODE_NUNCHUK: + { + if (nunchuk_handshake(wm, &wm->exp.nunchuk, data, len)) + wm->event = WIIUSE_NUNCHUK_INSERTED; + break; + } + case EXP_ID_CODE_CLASSIC_CONTROLLER: + { + if (classic_ctrl_handshake(wm, &wm->exp.classic, data, len)) + wm->event = WIIUSE_CLASSIC_CTRL_INSERTED; + break; + } + case EXP_ID_CODE_GUITAR: + { + if (guitar_hero_3_handshake(wm, &wm->exp.gh3, data, len)) + wm->event = WIIUSE_GUITAR_HERO_3_CTRL_INSERTED; + break; + } + default: + { + WIIUSE_WARNING("Unknown expansion type. Code: 0x%x", id); + break; + } + } + + free(data); +} + + + +/** + * @brief Disable the expansion device if it was enabled. + * + * @param wm A pointer to a wiimote_t structure. + * @param data The data read in from the device. + * @param len The length of the data block, in bytes. + * + * If the data is NULL then this function will try to start + * a handshake with the expansion. + */ +void disable_expansion(struct wiimote_t* wm) { + if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) + return; + + /* tell the assoicated module the expansion was removed */ + switch (wm->exp.type) { + case EXP_NUNCHUK: + nunchuk_disconnected(&wm->exp.nunchuk); + wm->event = WIIUSE_NUNCHUK_REMOVED; + break; + case EXP_CLASSIC: + classic_ctrl_disconnected(&wm->exp.classic); + wm->event = WIIUSE_CLASSIC_CTRL_REMOVED; + break; + case EXP_GUITAR_HERO_3: + guitar_hero_3_disconnected(&wm->exp.gh3); + wm->event = WIIUSE_GUITAR_HERO_3_CTRL_REMOVED; + break; + default: + break; + } + + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP); + wm->exp.type = EXP_NONE; +} + + +/** + * @brief Save important state data. + * @param wm A pointer to a wiimote_t structure. + */ +static void save_state(struct wiimote_t* wm) { + /* wiimote */ + wm->lstate.btns = wm->btns; + wm->lstate.accel = wm->accel; + + /* ir */ + if (WIIUSE_USING_IR(wm)) { + wm->lstate.ir_ax = wm->ir.ax; + wm->lstate.ir_ay = wm->ir.ay; + wm->lstate.ir_distance = wm->ir.distance; + } + + /* expansion */ + switch (wm->exp.type) { + case EXP_NUNCHUK: + wm->lstate.exp_ljs_ang = wm->exp.nunchuk.js.ang; + wm->lstate.exp_ljs_mag = wm->exp.nunchuk.js.mag; + wm->lstate.exp_btns = wm->exp.nunchuk.btns; + wm->lstate.exp_accel = wm->exp.nunchuk.accel; + break; + + case EXP_CLASSIC: + wm->lstate.exp_ljs_ang = wm->exp.classic.ljs.ang; + wm->lstate.exp_ljs_mag = wm->exp.classic.ljs.mag; + wm->lstate.exp_rjs_ang = wm->exp.classic.rjs.ang; + wm->lstate.exp_rjs_mag = wm->exp.classic.rjs.mag; + wm->lstate.exp_r_shoulder = wm->exp.classic.r_shoulder; + wm->lstate.exp_l_shoulder = wm->exp.classic.l_shoulder; + wm->lstate.exp_btns = wm->exp.classic.btns; + break; + + case EXP_GUITAR_HERO_3: + wm->lstate.exp_ljs_ang = wm->exp.gh3.js.ang; + wm->lstate.exp_ljs_mag = wm->exp.gh3.js.mag; + wm->lstate.exp_r_shoulder = wm->exp.gh3.whammy_bar; + wm->lstate.exp_btns = wm->exp.gh3.btns; + break; + + case EXP_NONE: + break; + } +} + + +/** + * @brief Determine if the current state differs significantly from the previous. + * @param wm A pointer to a wiimote_t structure. + * @return 1 if a significant change occured, 0 if not. + */ +static int state_changed(struct wiimote_t* wm) { + #define STATE_CHANGED(a, b) if (a != b) return 1 + + #define CROSS_THRESH(last, now, thresh) \ + do { \ + if (WIIMOTE_IS_FLAG_SET(wm, WIIUSE_ORIENT_THRESH)) { \ + if ((diff_f(last.roll, now.roll) >= thresh) || \ + (diff_f(last.pitch, now.pitch) >= thresh) || \ + (diff_f(last.yaw, now.yaw) >= thresh)) \ + { \ + last = now; \ + return 1; \ + } \ + } else { \ + if (last.roll != now.roll) return 1; \ + if (last.pitch != now.pitch) return 1; \ + if (last.yaw != now.yaw) return 1; \ + } \ + } while (0) + + #define CROSS_THRESH_XYZ(last, now, thresh) \ + do { \ + if (WIIMOTE_IS_FLAG_SET(wm, WIIUSE_ORIENT_THRESH)) { \ + if ((diff_f(last.x, now.x) >= thresh) || \ + (diff_f(last.y, now.y) >= thresh) || \ + (diff_f(last.z, now.z) >= thresh)) \ + { \ + last = now; \ + return 1; \ + } \ + } else { \ + if (last.x != now.x) return 1; \ + if (last.y != now.y) return 1; \ + if (last.z != now.z) return 1; \ + } \ + } while (0) + + /* ir */ + if (WIIUSE_USING_IR(wm)) { + STATE_CHANGED(wm->lstate.ir_ax, wm->ir.ax); + STATE_CHANGED(wm->lstate.ir_ay, wm->ir.ay); + STATE_CHANGED(wm->lstate.ir_distance, wm->ir.distance); + } + + /* accelerometer */ + if (WIIUSE_USING_ACC(wm)) { + /* raw accelerometer */ + CROSS_THRESH_XYZ(wm->lstate.accel, wm->accel, wm->accel_threshold); + + /* orientation */ + CROSS_THRESH(wm->lstate.orient, wm->orient, wm->orient_threshold); + } + + /* expansion */ + switch (wm->exp.type) { + case EXP_NUNCHUK: + { + STATE_CHANGED(wm->lstate.exp_ljs_ang, wm->exp.nunchuk.js.ang); + STATE_CHANGED(wm->lstate.exp_ljs_mag, wm->exp.nunchuk.js.mag); + STATE_CHANGED(wm->lstate.exp_btns, wm->exp.nunchuk.btns); + + CROSS_THRESH(wm->lstate.exp_orient, wm->exp.nunchuk.orient, wm->exp.nunchuk.orient_threshold); + CROSS_THRESH_XYZ(wm->lstate.exp_accel, wm->exp.nunchuk.accel, wm->exp.nunchuk.accel_threshold); + break; + } + case EXP_CLASSIC: + { + STATE_CHANGED(wm->lstate.exp_ljs_ang, wm->exp.classic.ljs.ang); + STATE_CHANGED(wm->lstate.exp_ljs_mag, wm->exp.classic.ljs.mag); + STATE_CHANGED(wm->lstate.exp_rjs_ang, wm->exp.classic.rjs.ang); + STATE_CHANGED(wm->lstate.exp_rjs_mag, wm->exp.classic.rjs.mag); + STATE_CHANGED(wm->lstate.exp_r_shoulder, wm->exp.classic.r_shoulder); + STATE_CHANGED(wm->lstate.exp_l_shoulder, wm->exp.classic.l_shoulder); + STATE_CHANGED(wm->lstate.exp_btns, wm->exp.classic.btns); + break; + } + case EXP_GUITAR_HERO_3: + { + STATE_CHANGED(wm->lstate.exp_ljs_ang, wm->exp.gh3.js.ang); + STATE_CHANGED(wm->lstate.exp_ljs_mag, wm->exp.gh3.js.mag); + STATE_CHANGED(wm->lstate.exp_r_shoulder, wm->exp.gh3.whammy_bar); + STATE_CHANGED(wm->lstate.exp_btns, wm->exp.gh3.btns); + break; + } + case EXP_NONE: + { + break; + } + } + + STATE_CHANGED(wm->lstate.btns, wm->btns); + + return 0; +} diff --git a/c/wiiuse/events.h b/c/wiiuse/events.h new file mode 100644 index 0000000..5e9b955 --- /dev/null +++ b/c/wiiuse/events.h @@ -0,0 +1,54 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Handles wiimote events. + * + * The file includes functions that handle the events + * that are sent from the wiimote to us. + */ + +#ifndef EVENTS_H_INCLUDED +#define EVENTS_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +void wiiuse_pressed_buttons(struct wiimote_t* wm, byte* msg); + +void handshake_expansion(struct wiimote_t* wm, byte* data, unsigned short len); +void disable_expansion(struct wiimote_t* wm); + +#ifdef __cplusplus +} +#endif + + +#endif // EVENTS_H_INCLUDED diff --git a/c/wiiuse/guitar_hero_3.c b/c/wiiuse/guitar_hero_3.c new file mode 100644 index 0000000..5837dc0 --- /dev/null +++ b/c/wiiuse/guitar_hero_3.c @@ -0,0 +1,172 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Guitar Hero 3 expansion device. + */ + +#include +#include +#include + +#ifdef WIN32 + #include +#endif + +#include "definitions.h" +#include "wiiuse_internal.h" +#include "dynamics.h" +#include "events.h" +#include "guitar_hero_3.h" + +static void guitar_hero_3_pressed_buttons(struct guitar_hero_3_t* gh3, short now); + +/** + * @brief Handle the handshake data from the guitar. + * + * @param cc A pointer to a classic_ctrl_t structure. + * @param data The data read in from the device. + * @param len The length of the data block, in bytes. + * + * @return Returns 1 if handshake was successful, 0 if not. + */ +int guitar_hero_3_handshake(struct wiimote_t* wm, struct guitar_hero_3_t* gh3, byte* data, unsigned short len) { + int i; + int offset = 0; + + /* + * The good fellows that made the Guitar Hero 3 controller + * failed to factory calibrate the devices. There is no + * calibration data on the device. + */ + + gh3->btns = 0; + gh3->btns_held = 0; + gh3->btns_released = 0; + gh3->whammy_bar = 0.0f; + + /* decrypt data */ + for (i = 0; i < len; ++i) + data[i] = (data[i] ^ 0x17) + 0x17; + + if (data[offset] == 0xFF) { + /* + * Sometimes the data returned here is not correct. + * This might happen because the wiimote is lagging + * behind our initialization sequence. + * To fix this just request the handshake again. + * + * Other times it's just the first 16 bytes are 0xFF, + * but since the next 16 bytes are the same, just use + * those. + */ + if (data[offset + 16] == 0xFF) { + /* get the calibration data */ + byte* handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte)); + + WIIUSE_DEBUG("Guitar Hero 3 handshake appears invalid, trying again."); + wiiuse_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN); + + return 0; + } else + offset += 16; + } + + /* joystick stuff */ + gh3->js.max.x = GUITAR_HERO_3_JS_MAX_X; + gh3->js.min.x = GUITAR_HERO_3_JS_MIN_X; + gh3->js.center.x = GUITAR_HERO_3_JS_CENTER_X; + gh3->js.max.y = GUITAR_HERO_3_JS_MAX_Y; + gh3->js.min.y = GUITAR_HERO_3_JS_MIN_Y; + gh3->js.center.y = GUITAR_HERO_3_JS_CENTER_Y; + + /* handshake done */ + wm->exp.type = EXP_GUITAR_HERO_3; + + #ifdef WIN32 + wm->timeout = WIIMOTE_DEFAULT_TIMEOUT; + #endif + + return 1; +} + + +/** + * @brief The guitar disconnected. + * + * @param cc A pointer to a classic_ctrl_t structure. + */ +void guitar_hero_3_disconnected(struct guitar_hero_3_t* gh3) { + memset(gh3, 0, sizeof(struct guitar_hero_3_t)); +} + + + +/** + * @brief Handle guitar event. + * + * @param cc A pointer to a classic_ctrl_t structure. + * @param msg The message specified in the event packet. + */ +void guitar_hero_3_event(struct guitar_hero_3_t* gh3, byte* msg) { + int i; + + /* decrypt data */ + for (i = 0; i < 6; ++i) + msg[i] = (msg[i] ^ 0x17) + 0x17; + + guitar_hero_3_pressed_buttons(gh3, BIG_ENDIAN_SHORT(*(short*)(msg + 4))); + + /* whammy bar */ + gh3->whammy_bar = (msg[3] - GUITAR_HERO_3_WHAMMY_BAR_MIN) / (float)(GUITAR_HERO_3_WHAMMY_BAR_MAX - GUITAR_HERO_3_WHAMMY_BAR_MIN); + + /* joy stick */ + calc_joystick_state(&gh3->js, msg[0], msg[1]); +} + + +/** + * @brief Find what buttons are pressed. + * + * @param cc A pointer to a classic_ctrl_t structure. + * @param msg The message byte specified in the event packet. + */ +static void guitar_hero_3_pressed_buttons(struct guitar_hero_3_t* gh3, short now) { + /* message is inverted (0 is active, 1 is inactive) */ + now = ~now & GUITAR_HERO_3_BUTTON_ALL; + + /* pressed now & were pressed, then held */ + gh3->btns_held = (now & gh3->btns); + + /* were pressed or were held & not pressed now, then released */ + gh3->btns_released = ((gh3->btns | gh3->btns_held) & ~now); + + /* buttons pressed now */ + gh3->btns = now; +} diff --git a/c/wiiuse/guitar_hero_3.h b/c/wiiuse/guitar_hero_3.h new file mode 100644 index 0000000..024d603 --- /dev/null +++ b/c/wiiuse/guitar_hero_3.h @@ -0,0 +1,62 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Guitar Hero 3 expansion device. + */ + +#ifndef GUITAR_HERO_3_H_INCLUDED +#define GUITAR_HERO_3_H_INCLUDED + +#include "wiiuse_internal.h" + +#define GUITAR_HERO_3_JS_MIN_X 0xC5 +#define GUITAR_HERO_3_JS_MAX_X 0xFC +#define GUITAR_HERO_3_JS_CENTER_X 0xE0 +#define GUITAR_HERO_3_JS_MIN_Y 0xC5 +#define GUITAR_HERO_3_JS_MAX_Y 0xFA +#define GUITAR_HERO_3_JS_CENTER_Y 0xE0 +#define GUITAR_HERO_3_WHAMMY_BAR_MIN 0xEF +#define GUITAR_HERO_3_WHAMMY_BAR_MAX 0xFA + +#ifdef __cplusplus +extern "C" { +#endif + +int guitar_hero_3_handshake(struct wiimote_t* wm, struct guitar_hero_3_t* gh3, byte* data, unsigned short len); + +void guitar_hero_3_disconnected(struct guitar_hero_3_t* gh3); + +void guitar_hero_3_event(struct guitar_hero_3_t* gh3, byte* msg); + +#ifdef __cplusplus +} +#endif + +#endif // GUITAR_HERO_3_H_INCLUDED diff --git a/c/wiiuse/io.c b/c/wiiuse/io.c new file mode 100644 index 0000000..ae420b9 --- /dev/null +++ b/c/wiiuse/io.c @@ -0,0 +1,119 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Handles device I/O (non-OS specific). + */ + +#include +#include + +#include "definitions.h" +#include "wiiuse_internal.h" +#include "io.h" + + + /** + * @brief Get initialization data from the wiimote. + * + * @param wm Pointer to a wiimote_t structure. + * @param data unused + * @param len unused + * + * When first called for a wiimote_t structure, a request + * is sent to the wiimote for initialization information. + * This includes factory set accelerometer data. + * The handshake will be concluded when the wiimote responds + * with this data. + */ +void wiiuse_handshake(struct wiimote_t* wm, byte* data, unsigned short len) { + if (!wm) return; + + switch (wm->handshake_state) { + case 0: + { + /* send request to wiimote for accelerometer calibration */ + byte* buf; + + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); + wiiuse_set_leds(wm, WIIMOTE_LED_NONE); + + buf = (byte*)malloc(sizeof(byte) * 8); + wiiuse_read_data_cb(wm, wiiuse_handshake, buf, WM_MEM_OFFSET_CALIBRATION, 7); + wm->handshake_state++; + + wiiuse_set_leds(wm, WIIMOTE_LED_NONE); + + break; + } + case 1: + { + struct read_req_t* req = wm->read_req; + struct accel_t* accel = &wm->accel_calib; + + /* received read data */ + accel->cal_zero.x = req->buf[0]; + accel->cal_zero.y = req->buf[1]; + accel->cal_zero.z = req->buf[2]; + + accel->cal_g.x = req->buf[4] - accel->cal_zero.x; + accel->cal_g.y = req->buf[5] - accel->cal_zero.y; + accel->cal_g.z = req->buf[6] - accel->cal_zero.z; + + /* done with the buffer */ + free(req->buf); + + /* handshake is done */ + WIIUSE_DEBUG("Handshake finished. Calibration: Idle: X=%x Y=%x Z=%x\t+1g: X=%x Y=%x Z=%x", + accel->cal_zero.x, accel->cal_zero.y, accel->cal_zero.z, + accel->cal_g.x, accel->cal_g.y, accel->cal_g.z); + + + /* request the status of the wiimote to see if there is an expansion */ + wiiuse_status(wm); + + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE); + wm->handshake_state++; + + /* now enable IR if it was set before the handshake completed */ + if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) { + WIIUSE_DEBUG("Handshake finished, enabling IR."); + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR); + wiiuse_set_ir(wm, 1); + } + + break; + } + default: + { + break; + } + } +} diff --git a/c/wiiuse/io.h b/c/wiiuse/io.h new file mode 100644 index 0000000..7a683e4 --- /dev/null +++ b/c/wiiuse/io.h @@ -0,0 +1,56 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Handles device I/O. + */ + +#ifndef CONNECT_H_INCLUDED +#define CONNECT_H_INCLUDED + +#ifndef WIN32 + #include +#endif + +#include "wiiuse_internal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void wiiuse_handshake(struct wiimote_t* wm, byte* data, unsigned short len); + +int wiiuse_io_read(struct wiimote_t* wm); +int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len); + +#ifdef __cplusplus +} +#endif + +#endif // CONNECT_H_INCLUDED diff --git a/c/wiiuse/io_nix.c b/c/wiiuse/io_nix.c new file mode 100644 index 0000000..ec4e0e1 --- /dev/null +++ b/c/wiiuse/io_nix.c @@ -0,0 +1,270 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Handles device I/O for *nix. + */ + +#ifndef WIN32 + +#include +#include +#include + +#include +#include +#include +#include + +#include "definitions.h" +#include "wiiuse_internal.h" +#include "io.h" + +static int wiiuse_connect_single(struct wiimote_t* wm, char* address); + +/** + * @brief Find a wiimote or wiimotes. + * + * @param wm An array of wiimote_t structures. + * @param max_wiimotes The number of wiimote structures in \a wm. + * @param timeout The number of seconds before the search times out. + * + * @return The number of wiimotes found. + * + * @see wiimote_connect() + * + * This function will only look for wiimote devices. \n + * When a device is found the address in the structures will be set. \n + * You can then call wiimote_connect() to connect to the found \n + * devices. + */ +int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout) { + int device_id; + int device_sock; + int found_devices; + int found_wiimotes; + + /* reset all wiimote bluetooth device addresses */ + for (found_wiimotes = 0; found_wiimotes < max_wiimotes; ++found_wiimotes) + wm[found_wiimotes]->bdaddr = *BDADDR_ANY; + found_wiimotes = 0; + + /* get the id of the first bluetooth device. */ + device_id = hci_get_route(NULL); + if (device_id < 0) { + perror("hci_get_route"); + return 0; + } + + /* create a socket to the device */ + device_sock = hci_open_dev(device_id); + if (device_sock < 0) { + perror("hci_open_dev"); + return 0; + } + + inquiry_info scan_info_arr[128]; + inquiry_info* scan_info = scan_info_arr; + memset(&scan_info_arr, 0, sizeof(scan_info_arr)); + + /* scan for bluetooth devices for 'timeout' seconds */ + found_devices = hci_inquiry(device_id, timeout, 128, NULL, &scan_info, IREQ_CACHE_FLUSH); + if (found_devices < 0) { + perror("hci_inquiry"); + return 0; + } + + WIIUSE_INFO("Found %i bluetooth device(s).", found_devices); + + int i = 0; + + /* display discovered devices */ + for (; (i < found_devices) && (found_wiimotes < max_wiimotes); ++i) { + if ((scan_info[i].dev_class[0] == WM_DEV_CLASS_0) && + (scan_info[i].dev_class[1] == WM_DEV_CLASS_1) && + (scan_info[i].dev_class[2] == WM_DEV_CLASS_2)) + { + /* found a device */ + ba2str(&scan_info[i].bdaddr, wm[found_wiimotes]->bdaddr_str); + + WIIUSE_INFO("Found wiimote (%s) [id %i].", wm[found_wiimotes]->bdaddr_str, wm[found_wiimotes]->unid); + + wm[found_wiimotes]->bdaddr = scan_info[i].bdaddr; + WIIMOTE_ENABLE_STATE(wm[found_wiimotes], WIIMOTE_STATE_DEV_FOUND); + ++found_wiimotes; + } + } + + close(device_sock); + return found_wiimotes; +} + + +/** + * @brief Connect to a wiimote or wiimotes once an address is known. + * + * @param wm An array of wiimote_t structures. + * @param wiimotes The number of wiimote structures in \a wm. + * + * @return The number of wiimotes that successfully connected. + * + * @see wiiuse_find() + * @see wiiuse_connect_single() + * @see wiiuse_disconnect() + * + * Connect to a number of wiimotes when the address is already set + * in the wiimote_t structures. These addresses are normally set + * by the wiiuse_find() function, but can also be set manually. + */ +int wiiuse_connect(struct wiimote_t** wm, int wiimotes) { + int connected = 0; + int i = 0; + + for (; i < wiimotes; ++i) { + if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND)) + /* if the device address is not set, skip it */ + continue; + + if (wiiuse_connect_single(wm[i], NULL)) + ++connected; + } + + return connected; +} + + +/** + * @brief Connect to a wiimote with a known address. + * + * @param wm Pointer to a wiimote_t structure. + * @param address The address of the device to connect to. + * If NULL, use the address in the struct set by wiiuse_find(). + * + * @return 1 on success, 0 on failure + */ +static int wiiuse_connect_single(struct wiimote_t* wm, char* address) { + struct sockaddr_l2 addr; + + if (!wm || WIIMOTE_IS_CONNECTED(wm)) + return 0; + + addr.l2_family = AF_BLUETOOTH; + + if (address) + /* use provided address */ + str2ba(address, &addr.l2_bdaddr); + else + /* use address of device discovered */ + addr.l2_bdaddr = wm->bdaddr; + + /* + * OUTPUT CHANNEL + */ + wm->out_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (wm->out_sock == -1) + return 0; + + addr.l2_psm = htobs(WM_OUTPUT_CHANNEL); + + /* connect to wiimote */ + if (connect(wm->out_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + perror("connect() output sock"); + return 0; + } + + /* + * INPUT CHANNEL + */ + wm->in_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (wm->in_sock == -1) { + close(wm->out_sock); + wm->out_sock = -1; + return 0; + } + + addr.l2_psm = htobs(WM_INPUT_CHANNEL); + + /* connect to wiimote */ + if (connect(wm->in_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + perror("connect() interrupt sock"); + close(wm->out_sock); + wm->out_sock = -1; + return 0; + } + + WIIUSE_INFO("Connected to wiimote [id %i].", wm->unid); + + /* do the handshake */ + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED); + wiiuse_handshake(wm, NULL, 0); + + wiiuse_set_report_type(wm); + + return 1; +} + + +/** + * @brief Disconnect a wiimote. + * + * @param wm Pointer to a wiimote_t structure. + * + * @see wiiuse_connect() + * + * Note that this will not free the wiimote structure. + */ +void wiiuse_disconnect(struct wiimote_t* wm) { + if (!wm || WIIMOTE_IS_CONNECTED(wm)) + return; + + close(wm->out_sock); + close(wm->in_sock); + + wm->out_sock = -1; + wm->in_sock = -1; + wm->event = WIIUSE_NONE; + + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED); + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); +} + + +int wiiuse_io_read(struct wiimote_t* wm) { + /* not used */ + return 0; +} + + +int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len) { + return write(wm->out_sock, buf, len); +} + + + +#endif /* ifndef WIN32 */ diff --git a/c/wiiuse/io_win.c b/c/wiiuse/io_win.c new file mode 100644 index 0000000..17fac36 --- /dev/null +++ b/c/wiiuse/io_win.c @@ -0,0 +1,247 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Handles device I/O for Windows. + */ + +#ifdef WIN32 + +#include +#include + +#include +#include +#include + +#include "definitions.h" +#include "wiiuse_internal.h" +#include "io.h" + + +int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout) { + GUID device_id; + HANDLE dev; + HDEVINFO device_info; + int i, index; + DWORD len; + SP_DEVICE_INTERFACE_DATA device_data; + PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; + HIDD_ATTRIBUTES attr; + int found = 0; + + (void) timeout; // unused + + device_data.cbSize = sizeof(device_data); + index = 0; + + /* get the device id */ + HidD_GetHidGuid(&device_id); + + /* get all hid devices connected */ + device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); + + for (;; ++index) { + + if (detail_data) { + free(detail_data); + detail_data = NULL; + } + + /* query the next hid device info */ + if (!SetupDiEnumDeviceInterfaces(device_info, NULL, &device_id, index, &device_data)) + break; + + /* get the size of the data block required */ + i = SetupDiGetDeviceInterfaceDetail(device_info, &device_data, NULL, 0, &len, NULL); + detail_data = malloc(len); + detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + + /* query the data for this device */ + if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL)) + continue; + + /* open the device */ + dev = CreateFile(detail_data->DevicePath, + (GENERIC_READ | GENERIC_WRITE), + (FILE_SHARE_READ | FILE_SHARE_WRITE), + NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + if (dev == INVALID_HANDLE_VALUE) + continue; + + /* get device attributes */ + attr.Size = sizeof(attr); + i = HidD_GetAttributes(dev, &attr); + + if ((attr.VendorID == WM_VENDOR_ID) && (attr.ProductID == WM_PRODUCT_ID)) { + /* this is a wiimote */ + wm[found]->dev_handle = dev; + + wm[found]->hid_overlap.hEvent = CreateEvent(NULL, 1, 1, ""); + wm[found]->hid_overlap.Offset = 0; + wm[found]->hid_overlap.OffsetHigh = 0; + + WIIMOTE_ENABLE_STATE(wm[found], WIIMOTE_STATE_DEV_FOUND); + WIIMOTE_ENABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED); + + /* try to set the output report to see if the device is actually connected */ + if (!wiiuse_set_report_type(wm[found])) { + WIIMOTE_DISABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED); + continue; + } + + /* do the handshake */ + wiiuse_handshake(wm[found], NULL, 0); + + WIIUSE_INFO("Connected to wiimote [id %i].", wm[found]->unid); + + ++found; + if (found >= max_wiimotes) + break; + } else { + /* not a wiimote */ + CloseHandle(dev); + } + } + + if (detail_data) + free(detail_data); + + SetupDiDestroyDeviceInfoList(device_info); + + return found; +} + + +int wiiuse_connect(struct wiimote_t** wm, int wiimotes) { + int connected = 0; + int i = 0; + + for (; i < wiimotes; ++i) { + if (WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_CONNECTED)) + ++connected; + } + + return connected; +} + + +void wiiuse_disconnect(struct wiimote_t* wm) { + if (!wm || WIIMOTE_IS_CONNECTED(wm)) + return; + + CloseHandle(wm->dev_handle); + wm->dev_handle = 0; + + ResetEvent(&wm->hid_overlap); + + wm->event = WIIUSE_NONE; + + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED); + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); +} + + +int wiiuse_io_read(struct wiimote_t* wm) { + DWORD b, r; + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return 0; + + if (!ReadFile(wm->dev_handle, wm->event_buf, sizeof(wm->event_buf), &b, &wm->hid_overlap)) { + /* partial read */ + b = GetLastError(); + + if ((b == ERROR_HANDLE_EOF) || (b == ERROR_DEVICE_NOT_CONNECTED)) { + /* remote disconnect */ + wiiuse_disconnected(wm); + return 0; + } + + r = WaitForSingleObject(wm->hid_overlap.hEvent, wm->timeout); + if (r == WAIT_TIMEOUT) { + /* timeout - cancel and continue */ + + if (*wm->event_buf) + WIIUSE_WARNING("Packet ignored. This may indicate a problem (timeout is %i ms).", wm->timeout); + + CancelIo(wm->dev_handle); + ResetEvent(wm->hid_overlap.hEvent); + return 0; + } else if (r == WAIT_FAILED) { + WIIUSE_WARNING("A wait error occured on reading from wiimote %i.", wm->unid); + return 0; + } + + if (!GetOverlappedResult(wm->dev_handle, &wm->hid_overlap, &b, 0)) + return 0; + } + + ResetEvent(wm->hid_overlap.hEvent); + return 1; +} + + +int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len) { + DWORD bytes; + int i; + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return 0; + + switch (wm->stack) { + case WIIUSE_STACK_UNKNOWN: + { + /* try to auto-detect the stack type */ + if (i = WriteFile(wm->dev_handle, buf, 22, &bytes, &wm->hid_overlap)) { + /* bluesoleil will always return 1 here, even if it's not connected */ + wm->stack = WIIUSE_STACK_BLUESOLEIL; + return i; + } + + if (i = HidD_SetOutputReport(wm->dev_handle, buf, len)) { + wm->stack = WIIUSE_STACK_MS; + return i; + } + + WIIUSE_ERROR("Unable to determine bluetooth stack type."); + return 0; + } + + case WIIUSE_STACK_MS: + return HidD_SetOutputReport(wm->dev_handle, buf, len); + + case WIIUSE_STACK_BLUESOLEIL: + return WriteFile(wm->dev_handle, buf, 22, &bytes, &wm->hid_overlap); + } + + return 0; +} + +#endif /* ifdef WIN32 */ diff --git a/c/wiiuse/ir.c b/c/wiiuse/ir.c new file mode 100644 index 0000000..7a9bb68 --- /dev/null +++ b/c/wiiuse/ir.c @@ -0,0 +1,748 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Handles IR data. + */ + +#include +#include + +#ifndef WIN32 + #include +#endif + +#include "definitions.h" +#include "wiiuse_internal.h" +#include "ir.h" + +static int get_ir_sens(struct wiimote_t* wm, char** block1, char** block2); +static void interpret_ir_data(struct wiimote_t* wm); +static void fix_rotated_ir_dots(struct ir_dot_t* dot, float ang); +static void get_ir_dot_avg(struct ir_dot_t* dot, int* x, int* y); +static void reorder_ir_dots(struct ir_dot_t* dot); +static float ir_distance(struct ir_dot_t* dot); +static int ir_correct_for_bounds(int* x, int* y, enum aspect_t aspect, int offset_x, int offset_y); +static void ir_convert_to_vres(int* x, int* y, enum aspect_t aspect, int vx, int vy); + + +/** + * @brief Set if the wiimote should track IR targets. + * + * @param wm Pointer to a wiimote_t structure. + * @param status 1 to enable, 0 to disable. + */ +void wiiuse_set_ir(struct wiimote_t* wm, int status) { + byte buf; + char* block1 = NULL; + char* block2 = NULL; + int ir_level; + + if (!wm) + return; + + /* + * Wait for the handshake to finish first. + * When it handshake finishes and sees that + * IR is enabled, it will call this function + * again to actually enable IR. + */ + if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE)) { + WIIUSE_DEBUG("Tried to enable IR, will wait until handshake finishes."); + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR); + return; + } + + /* + * Check to make sure a sensitivity setting is selected. + */ + ir_level = get_ir_sens(wm, &block1, &block2); + if (!ir_level) { + WIIUSE_ERROR("No IR sensitivity setting selected."); + return; + } + + if (status) { + /* if already enabled then stop */ + if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) + return; + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR); + } else { + /* if already disabled then stop */ + if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) + return; + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR); + } + + /* set camera 1 and 2 */ + buf = (status ? 0x04 : 0x00); + wiiuse_send(wm, WM_CMD_IR, &buf, 1); + wiiuse_send(wm, WM_CMD_IR_2, &buf, 1); + + if (!status) { + WIIUSE_DEBUG("Disabled IR cameras for wiimote id %i.", wm->unid); + wiiuse_set_report_type(wm); + return; + } + + /* enable IR, set sensitivity */ + buf = 0x08; + wiiuse_write_data(wm, WM_REG_IR, &buf, 1); + + /* wait for the wiimote to catch up */ + #ifndef WIN32 + usleep(50000); + #else + Sleep(50); + #endif + + /* write sensitivity blocks */ + wiiuse_write_data(wm, WM_REG_IR_BLOCK1, (byte*)block1, 9); + wiiuse_write_data(wm, WM_REG_IR_BLOCK2, (byte*)block2, 2); + + /* set the IR mode */ + if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) + buf = WM_IR_TYPE_BASIC; + else + buf = WM_IR_TYPE_EXTENDED; + wiiuse_write_data(wm, WM_REG_IR_MODENUM, &buf, 1); + + #ifndef WIN32 + usleep(50000); + #else + Sleep(50); + #endif + + /* set the wiimote report type */ + wiiuse_set_report_type(wm); + + WIIUSE_DEBUG("Enabled IR camera for wiimote id %i (sensitivity level %i).", wm->unid, ir_level); +} + + +/** + * @brief Get the IR sensitivity settings. + * + * @param wm Pointer to a wiimote_t structure. + * @param block1 [out] Pointer to where block1 will be set. + * @param block2 [out] Pointer to where block2 will be set. + * + * @return Returns the sensitivity level. + */ +static int get_ir_sens(struct wiimote_t* wm, char** block1, char** block2) { + if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL1)) { + *block1 = WM_IR_BLOCK1_LEVEL1; + *block2 = WM_IR_BLOCK2_LEVEL1; + return 1; + } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL2)) { + *block1 = WM_IR_BLOCK1_LEVEL2; + *block2 = WM_IR_BLOCK2_LEVEL2; + return 2; + } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL3)) { + *block1 = WM_IR_BLOCK1_LEVEL3; + *block2 = WM_IR_BLOCK2_LEVEL3; + return 3; + } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL4)) { + *block1 = WM_IR_BLOCK1_LEVEL4; + *block2 = WM_IR_BLOCK2_LEVEL4; + return 4; + } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL5)) { + *block1 = WM_IR_BLOCK1_LEVEL5; + *block2 = WM_IR_BLOCK2_LEVEL5; + return 5; + } + + *block1 = NULL; + *block2 = NULL; + return 0; +} + + +/** + * @brief Set the virtual screen resolution for IR tracking. + * + * @param wm Pointer to a wiimote_t structure. + * @param status 1 to enable, 0 to disable. + */ +void wiiuse_set_ir_vres(struct wiimote_t* wm, unsigned int x, unsigned int y) { + if (!wm) return; + + wm->ir.vres[0] = (x-1); + wm->ir.vres[1] = (y-1); +} + + +/** + * @brief Set the XY position for the IR cursor. + * + * @param wm Pointer to a wiimote_t structure. + */ +void wiiuse_set_ir_position(struct wiimote_t* wm, enum ir_position_t pos) { + if (!wm) return; + + wm->ir.pos = pos; + + switch (pos) { + + case WIIUSE_IR_ABOVE: + wm->ir.offset[0] = 0; + + if (wm->ir.aspect == WIIUSE_ASPECT_16_9) + wm->ir.offset[1] = WM_ASPECT_16_9_Y/2 - 70; + else if (wm->ir.aspect == WIIUSE_ASPECT_4_3) + wm->ir.offset[1] = WM_ASPECT_4_3_Y/2 - 100; + + return; + + case WIIUSE_IR_BELOW: + wm->ir.offset[0] = 0; + + if (wm->ir.aspect == WIIUSE_ASPECT_16_9) + wm->ir.offset[1] = -WM_ASPECT_16_9_Y/2 + 100; + else if (wm->ir.aspect == WIIUSE_ASPECT_4_3) + wm->ir.offset[1] = -WM_ASPECT_4_3_Y/2 + 70; + + return; + + default: + return; + }; +} + + +/** + * @brief Set the aspect ratio of the TV/monitor. + * + * @param wm Pointer to a wiimote_t structure. + * @param aspect Either WIIUSE_ASPECT_16_9 or WIIUSE_ASPECT_4_3 + */ +void wiiuse_set_aspect_ratio(struct wiimote_t* wm, enum aspect_t aspect) { + if (!wm) return; + + wm->ir.aspect = aspect; + + if (aspect == WIIUSE_ASPECT_4_3) { + wm->ir.vres[0] = WM_ASPECT_4_3_X; + wm->ir.vres[1] = WM_ASPECT_4_3_Y; + } else { + wm->ir.vres[0] = WM_ASPECT_16_9_X; + wm->ir.vres[1] = WM_ASPECT_16_9_Y; + } + + /* reset the position offsets */ + wiiuse_set_ir_position(wm, wm->ir.pos); +} + + +/** + * @brief Set the IR sensitivity. + * + * @param wm Pointer to a wiimote_t structure. + * @param level 1-5, same as Wii system sensitivity setting. + * + * If the level is < 1, then level will be set to 1. + * If the level is > 5, then level will be set to 5. + */ +void wiiuse_set_ir_sensitivity(struct wiimote_t* wm, int level) { + char* block1 = NULL; + char* block2 = NULL; + + if (!wm) return; + + if (level > 5) level = 5; + if (level < 1) level = 1; + + WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_IR_SENS_LVL1 | + WIIMOTE_STATE_IR_SENS_LVL2 | + WIIMOTE_STATE_IR_SENS_LVL3 | + WIIMOTE_STATE_IR_SENS_LVL4 | + WIIMOTE_STATE_IR_SENS_LVL5)); + + switch (level) { + case 1: + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL1); + break; + case 2: + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL2); + break; + case 3: + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL3); + break; + case 4: + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL4); + break; + case 5: + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL5); + break; + default: + return; + } + + /* set the new sensitivity */ + get_ir_sens(wm, &block1, &block2); + + wiiuse_write_data(wm, WM_REG_IR_BLOCK1, (byte*)block1, 9); + wiiuse_write_data(wm, WM_REG_IR_BLOCK2, (byte*)block2, 2); + + WIIUSE_DEBUG("Set IR sensitivity to level %i (unid %i)", level, wm->unid); +} + + +/** + * @brief Calculate the data from the IR spots. Basic IR mode. + * + * @param wm Pointer to a wiimote_t structure. + * @param data Data returned by the wiimote for the IR spots. + */ +void calculate_basic_ir(struct wiimote_t* wm, byte* data) { + struct ir_dot_t* dot = wm->ir.dot; + int i; + + dot[0].rx = 1023 - (data[0] | ((data[2] & 0x30) << 4)); + dot[0].ry = data[1] | ((data[2] & 0xC0) << 2); + + dot[1].rx = 1023 - (data[3] | ((data[2] & 0x03) << 8)); + dot[1].ry = data[4] | ((data[2] & 0x0C) << 6); + + dot[2].rx = 1023 - (data[5] | ((data[7] & 0x30) << 4)); + dot[2].ry = data[6] | ((data[7] & 0xC0) << 2); + + dot[3].rx = 1023 - (data[8] | ((data[7] & 0x03) << 8)); + dot[3].ry = data[9] | ((data[7] & 0x0C) << 6); + + /* set each IR spot to visible if spot is in range */ + for (i = 0; i < 4; ++i) { + if (dot[i].ry == 1023) + dot[i].visible = 0; + else { + dot[i].visible = 1; + dot[i].size = 0; /* since we don't know the size, set it as 0 */ + } + } + + interpret_ir_data(wm); +} + + +/** + * @brief Calculate the data from the IR spots. Extended IR mode. + * + * @param wm Pointer to a wiimote_t structure. + * @param data Data returned by the wiimote for the IR spots. + */ +void calculate_extended_ir(struct wiimote_t* wm, byte* data) { + struct ir_dot_t* dot = wm->ir.dot; + int i; + + for (i = 0; i < 4; ++i) { + dot[i].rx = 1023 - (data[3*i] | ((data[(3*i)+2] & 0x30) << 4)); + dot[i].ry = data[(3*i)+1] | ((data[(3*i)+2] & 0xC0) << 2); + + dot[i].size = data[(3*i)+2] & 0x0F; + + /* if in range set to visible */ + if (dot[i].ry == 1023) + dot[i].visible = 0; + else + dot[i].visible = 1; + } + + interpret_ir_data(wm); +} + + +/** + * @brief Interpret IR data into more user friendly variables. + * + * @param wm Pointer to a wiimote_t structure. + */ +static void interpret_ir_data(struct wiimote_t* wm) { + struct ir_dot_t* dot = wm->ir.dot; + int i; + float roll = 0.0f; + int last_num_dots = wm->ir.num_dots; + + if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_ACC)) + roll = wm->orient.roll; + + /* count visible dots */ + wm->ir.num_dots = 0; + for (i = 0; i < 4; ++i) { + if (dot[i].visible) + wm->ir.num_dots++; + } + + switch (wm->ir.num_dots) { + case 0: + { + wm->ir.state = 0; + + /* reset the dot ordering */ + for (i = 0; i < 4; ++i) + dot[i].order = 0; + + wm->ir.x = 0; + wm->ir.y = 0; + wm->ir.z = 0.0f; + + return; + } + case 1: + { + fix_rotated_ir_dots(wm->ir.dot, roll); + + if (wm->ir.state < 2) { + /* + * Only 1 known dot, so use just that. + */ + for (i = 0; i < 4; ++i) { + if (dot[i].visible) { + wm->ir.x = dot[i].x; + wm->ir.y = dot[i].y; + + wm->ir.ax = wm->ir.x; + wm->ir.ay = wm->ir.y; + + /* can't calculate yaw because we don't have the distance */ + //wm->orient.yaw = calc_yaw(&wm->ir); + + ir_convert_to_vres(&wm->ir.x, &wm->ir.y, wm->ir.aspect, wm->ir.vres[0], wm->ir.vres[1]); + break; + } + } + } else { + /* + * Only see 1 dot but know theres 2. + * Try to estimate where the other one + * should be and use that. + */ + for (i = 0; i < 4; ++i) { + if (dot[i].visible) { + int ox = 0; + int x, y; + + if (dot[i].order == 1) + /* visible is the left dot - estimate where the right is */ + ox = dot[i].x + wm->ir.distance; + else if (dot[i].order == 2) + /* visible is the right dot - estimate where the left is */ + ox = dot[i].x - wm->ir.distance; + + x = ((signed int)dot[i].x + ox) / 2; + y = dot[i].y; + + wm->ir.ax = x; + wm->ir.ay = y; + wm->orient.yaw = calc_yaw(&wm->ir); + + if (ir_correct_for_bounds(&x, &y, wm->ir.aspect, wm->ir.offset[0], wm->ir.offset[1])) { + ir_convert_to_vres(&x, &y, wm->ir.aspect, wm->ir.vres[0], wm->ir.vres[1]); + wm->ir.x = x; + wm->ir.y = y; + } + + break; + } + } + } + + break; + } + case 2: + case 3: + case 4: + { + /* + * Two (or more) dots known and seen. + * Average them together to estimate the true location. + */ + int x, y; + wm->ir.state = 2; + + fix_rotated_ir_dots(wm->ir.dot, roll); + + /* if there is at least 1 new dot, reorder them all */ + if (wm->ir.num_dots > last_num_dots) { + reorder_ir_dots(dot); + wm->ir.x = 0; + wm->ir.y = 0; + } + + wm->ir.distance = ir_distance(dot); + wm->ir.z = 1023 - wm->ir.distance; + + get_ir_dot_avg(wm->ir.dot, &x, &y); + + wm->ir.ax = x; + wm->ir.ay = y; + wm->orient.yaw = calc_yaw(&wm->ir); + + if (ir_correct_for_bounds(&x, &y, wm->ir.aspect, wm->ir.offset[0], wm->ir.offset[1])) { + ir_convert_to_vres(&x, &y, wm->ir.aspect, wm->ir.vres[0], wm->ir.vres[1]); + wm->ir.x = x; + wm->ir.y = y; + } + + break; + } + default: + { + break; + } + } + + #ifdef WITH_WIIUSE_DEBUG + { + int ir_level; + WIIUSE_GET_IR_SENSITIVITY(wm, &ir_level); + WIIUSE_DEBUG("IR sensitivity: %i", ir_level); + WIIUSE_DEBUG("IR visible dots: %i", wm->ir.num_dots); + for (i = 0; i < 4; ++i) + if (dot[i].visible) + WIIUSE_DEBUG("IR[%i][order %i] (%.3i, %.3i) -> (%.3i, %.3i)", i, dot[i].order, dot[i].rx, dot[i].ry, dot[i].x, dot[i].y); + WIIUSE_DEBUG("IR[absolute]: (%i, %i)", wm->ir.x, wm->ir.y); + } + #endif +} + + + +/** + * @brief Fix the rotation of the IR dots. + * + * @param dot An array of 4 ir_dot_t objects. + * @param ang The roll angle to correct by (-180, 180) + * + * If there is roll then the dots are rotated + * around the origin and give a false cursor + * position. Correct for the roll. + * + * If the accelerometer is off then obviously + * this will not do anything and the cursor + * position may be inaccurate. + */ +static void fix_rotated_ir_dots(struct ir_dot_t* dot, float ang) { + float s, c; + int x, y; + int i; + + if (!ang) { + for (i = 0; i < 4; ++i) { + dot[i].x = dot[i].rx; + dot[i].y = dot[i].ry; + } + return; + } + + s = sin(DEGREE_TO_RAD(ang)); + c = cos(DEGREE_TO_RAD(ang)); + + /* + * [ cos(theta) -sin(theta) ][ ir->rx ] + * [ sin(theta) cos(theta) ][ ir->ry ] + */ + + for (i = 0; i < 4; ++i) { + if (!dot[i].visible) + continue; + + x = dot[i].rx - (1024/2); + y = dot[i].ry - (768/2); + + dot[i].x = (c * x) + (-s * y); + dot[i].y = (s * x) + (c * y); + + dot[i].x += (1024/2); + dot[i].y += (768/2); + } +} + + +/** + * @brief Average IR dots. + * + * @param dot An array of 4 ir_dot_t objects. + * @param x [out] Average X + * @param y [out] Average Y + */ +static void get_ir_dot_avg(struct ir_dot_t* dot, int* x, int* y) { + int vis = 0, i = 0; + + *x = 0; + *y = 0; + + for (; i < 4; ++i) { + if (dot[i].visible) { + *x += dot[i].x; + *y += dot[i].y; + ++vis; + } + } + + *x /= vis; + *y /= vis; +} + + +/** + * @brief Reorder the IR dots. + * + * @param dot An array of 4 ir_dot_t objects. + */ +static void reorder_ir_dots(struct ir_dot_t* dot) { + int i, j, order; + + /* reset the dot ordering */ + for (i = 0; i < 4; ++i) + dot[i].order = 0; + + for (order = 1; order < 5; ++order) { + i = 0; + + for (; !dot[i].visible || dot[i].order; ++i) + if (i > 4) + return; + + for (j = 0; j < 4; ++j) { + if (dot[j].visible && !dot[j].order && (dot[j].x < dot[i].x)) + i = j; + } + + dot[i].order = order; + } +} + + +/** + * @brief Calculate the distance between the first 2 visible IR dots. + * + * @param dot An array of 4 ir_dot_t objects. + */ +static float ir_distance(struct ir_dot_t* dot) { + int i1, i2; + int xd, yd; + + for (i1 = 0; i1 < 4; ++i1) + if (dot[i1].visible) + break; + if (i1 == 4) + return 0.0f; + + for (i2 = i1+1; i2 < 4; ++i2) + if (dot[i2].visible) + break; + if (i2 == 4) + return 0.0f; + + xd = dot[i2].x - dot[i1].x; + yd = dot[i2].y - dot[i1].y; + + return sqrt(xd*xd + yd*yd); +} + + +/** + * @brief Correct for the IR bounding box. + * + * @param x [out] The current X, it will be updated if valid. + * @param y [out] The current Y, it will be updated if valid. + * @param aspect Aspect ratio of the screen. + * @param offset_x The X offset of the bounding box. + * @param offset_y The Y offset of the bounding box. + * + * @return Returns 1 if the point is valid and was updated. + * + * Nintendo was smart with this bit. They sacrifice a little + * precision for a big increase in usability. + */ +static int ir_correct_for_bounds(int* x, int* y, enum aspect_t aspect, int offset_x, int offset_y) { + int x0, y0; + int xs, ys; + + if (aspect == WIIUSE_ASPECT_16_9) { + xs = WM_ASPECT_16_9_X; + ys = WM_ASPECT_16_9_Y; + } else { + xs = WM_ASPECT_4_3_X; + ys = WM_ASPECT_4_3_Y; + } + + x0 = ((1024 - xs) / 2) + offset_x; + y0 = ((768 - ys) / 2) + offset_y; + + if ((*x >= x0) + && (*x <= (x0 + xs)) + && (*y >= y0) + && (*y <= (y0 + ys))) + { + *x -= offset_x; + *y -= offset_y; + + return 1; + } + + return 0; +} + + +/** + * @brief Interpolate the point to the user defined virtual screen resolution. + */ +static void ir_convert_to_vres(int* x, int* y, enum aspect_t aspect, int vx, int vy) { + int xs, ys; + + if (aspect == WIIUSE_ASPECT_16_9) { + xs = WM_ASPECT_16_9_X; + ys = WM_ASPECT_16_9_Y; + } else { + xs = WM_ASPECT_4_3_X; + ys = WM_ASPECT_4_3_Y; + } + + *x -= ((1024-xs)/2); + *y -= ((768-ys)/2); + + *x = (*x / (float)xs) * vx; + *y = (*y / (float)ys) * vy; +} + + +/** + * @brief Calculate yaw given the IR data. + * + * @param ir IR data structure. + */ +float calc_yaw(struct ir_t* ir) { + float x; + + x = ir->ax - 512; + x = x * (ir->z / 1024.0f); + + return RAD_TO_DEGREE( atanf(x / ir->z) ); +} diff --git a/c/wiiuse/ir.h b/c/wiiuse/ir.h new file mode 100644 index 0000000..9082492 --- /dev/null +++ b/c/wiiuse/ir.h @@ -0,0 +1,56 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Handles IR data. + */ + +#ifndef IR_H_INCLUDED +#define IR_H_INCLUDED + +#include "wiiuse_internal.h" + +#define WII_VRES_X 560 +#define WII_VRES_Y 340 + +#ifdef __cplusplus +extern "C" { +#endif + +void calculate_basic_ir(struct wiimote_t* wm, byte* data); +void calculate_extended_ir(struct wiimote_t* wm, byte* data); +float calc_yaw(struct ir_t* ir); + +#ifdef __cplusplus +} +#endif + +#endif // IR_H_INCLUDED + + diff --git a/c/wiiuse/nunchuk.c b/c/wiiuse/nunchuk.c new file mode 100644 index 0000000..48dbe6a --- /dev/null +++ b/c/wiiuse/nunchuk.c @@ -0,0 +1,210 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Nunchuk expansion device. + */ + +#include +#include +#include + +#include "definitions.h" +#include "wiiuse_internal.h" +#include "dynamics.h" +#include "events.h" +#include "nunchuk.h" + +static void nunchuk_pressed_buttons(struct nunchuk_t* nc, byte now); + +/** + * @brief Handle the handshake data from the nunchuk. + * + * @param nc A pointer to a nunchuk_t structure. + * @param data The data read in from the device. + * @param len The length of the data block, in bytes. + * + * @return Returns 1 if handshake was successful, 0 if not. + */ +int nunchuk_handshake(struct wiimote_t* wm, struct nunchuk_t* nc, byte* data, unsigned short len) { + int i; + int offset = 0; + + nc->btns = 0; + nc->btns_held = 0; + nc->btns_released = 0; + + /* set the smoothing to the same as the wiimote */ + nc->flags = &wm->flags; + nc->accel_calib.st_alpha = wm->accel_calib.st_alpha; + + /* decrypt data */ + for (i = 0; i < len; ++i) + data[i] = (data[i] ^ 0x17) + 0x17; + + if (data[offset] == 0xFF) { + /* + * Sometimes the data returned here is not correct. + * This might happen because the wiimote is lagging + * behind our initialization sequence. + * To fix this just request the handshake again. + * + * Other times it's just the first 16 bytes are 0xFF, + * but since the next 16 bytes are the same, just use + * those. + */ + if (data[offset + 16] == 0xFF) { + /* get the calibration data */ + byte* handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte)); + + WIIUSE_DEBUG("Nunchuk handshake appears invalid, trying again."); + wiiuse_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN); + + return 0; + } else + offset += 16; + } + + nc->accel_calib.cal_zero.x = data[offset + 0]; + nc->accel_calib.cal_zero.y = data[offset + 1]; + nc->accel_calib.cal_zero.z = data[offset + 2]; + nc->accel_calib.cal_g.x = data[offset + 4]; + nc->accel_calib.cal_g.y = data[offset + 5]; + nc->accel_calib.cal_g.z = data[offset + 6]; + nc->js.max.x = data[offset + 8]; + nc->js.min.x = data[offset + 9]; + nc->js.center.x = data[offset + 10]; + nc->js.max.y = data[offset + 11]; + nc->js.min.y = data[offset + 12]; + nc->js.center.y = data[offset + 13]; + + /* default the thresholds to the same as the wiimote */ + nc->orient_threshold = wm->orient_threshold; + nc->accel_threshold = wm->accel_threshold; + + /* handshake done */ + wm->exp.type = EXP_NUNCHUK; + + #ifdef WIN32 + wm->timeout = WIIMOTE_DEFAULT_TIMEOUT; + #endif + + return 1; +} + + +/** + * @brief The nunchuk disconnected. + * + * @param nc A pointer to a nunchuk_t structure. + */ +void nunchuk_disconnected(struct nunchuk_t* nc) { + memset(nc, 0, sizeof(struct nunchuk_t)); +} + + + +/** + * @brief Handle nunchuk event. + * + * @param nc A pointer to a nunchuk_t structure. + * @param msg The message specified in the event packet. + */ +void nunchuk_event(struct nunchuk_t* nc, byte* msg) { + int i; + + /* decrypt data */ + for (i = 0; i < 6; ++i) + msg[i] = (msg[i] ^ 0x17) + 0x17; + + /* get button states */ + nunchuk_pressed_buttons(nc, msg[5]); + + /* calculate joystick state */ + calc_joystick_state(&nc->js, msg[0], msg[1]); + + /* calculate orientation */ + nc->accel.x = msg[2]; + nc->accel.y = msg[3]; + nc->accel.z = msg[4]; + + calculate_orientation(&nc->accel_calib, &nc->accel, &nc->orient, NUNCHUK_IS_FLAG_SET(nc, WIIUSE_SMOOTHING)); + calculate_gforce(&nc->accel_calib, &nc->accel, &nc->gforce); +} + + +/** + * @brief Find what buttons are pressed. + * + * @param nc Pointer to a nunchuk_t structure. + * @param msg The message byte specified in the event packet. + */ +static void nunchuk_pressed_buttons(struct nunchuk_t* nc, byte now) { + /* message is inverted (0 is active, 1 is inactive) */ + now = ~now & NUNCHUK_BUTTON_ALL; + + /* pressed now & were pressed, then held */ + nc->btns_held = (now & nc->btns); + + /* were pressed or were held & not pressed now, then released */ + nc->btns_released = ((nc->btns | nc->btns_held) & ~now); + + /* buttons pressed now */ + nc->btns = now; +} + + +/** + * @brief Set the orientation event threshold for the nunchuk. + * + * @param wm Pointer to a wiimote_t structure with a nunchuk attached. + * @param threshold The decimal place that should be considered a significant change. + * + * See wiiuse_set_orient_threshold() for details. + */ +void wiiuse_set_nunchuk_orient_threshold(struct wiimote_t* wm, float threshold) { + if (!wm) return; + + wm->exp.nunchuk.orient_threshold = threshold; +} + + +/** + * @brief Set the accelerometer event threshold for the nunchuk. + * + * @param wm Pointer to a wiimote_t structure with a nunchuk attached. + * @param threshold The decimal place that should be considered a significant change. + * + * See wiiuse_set_orient_threshold() for details. + */ +void wiiuse_set_nunchuk_accel_threshold(struct wiimote_t* wm, int threshold) { + if (!wm) return; + + wm->exp.nunchuk.accel_threshold = threshold; +} diff --git a/c/wiiuse/nunchuk.h b/c/wiiuse/nunchuk.h new file mode 100644 index 0000000..f036073 --- /dev/null +++ b/c/wiiuse/nunchuk.h @@ -0,0 +1,53 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief Nunchuk expansion device. + */ + +#ifndef NUNCHUK_H_INCLUDED +#define NUNCHUK_H_INCLUDED + +#include "wiiuse_internal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int nunchuk_handshake(struct wiimote_t* wm, struct nunchuk_t* nc, byte* data, unsigned short len); + +void nunchuk_disconnected(struct nunchuk_t* nc); + +void nunchuk_event(struct nunchuk_t* nc, byte* msg); + +#ifdef __cplusplus +} +#endif + +#endif // NUNCHUK_H_INCLUDED diff --git a/c/wiiuse/os.h b/c/wiiuse/os.h new file mode 100644 index 0000000..53b80f5 --- /dev/null +++ b/c/wiiuse/os.h @@ -0,0 +1,56 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + + +/** + * @file + * @brief Operating system related definitions. + * + * This file is an attempt to separate operating system + * dependent functions and choose what should be used + * at compile time. + */ + +#ifndef OS_H_INCLUDED +#define OS_H_INCLUDED + +#ifdef WIN32 + /* windows */ + #define isnan(x) _isnan(x) + #define isinf(x) !_finite(x) + + /* disable warnings I don't care about */ + #pragma warning(disable:4244) /* possible loss of data conversion */ + #pragma warning(disable:4273) /* inconsistent dll linkage */ + #pragma warning(disable:4217) +#else + /* nix */ +#endif + + +#endif // OS_H_INCLUDED diff --git a/c/wiiuse/wiiuse.c b/c/wiiuse/wiiuse.c new file mode 100644 index 0000000..8d4b763 --- /dev/null +++ b/c/wiiuse/wiiuse.c @@ -0,0 +1,764 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief General wiimote operations. + * + * The file includes functions that handle general + * tasks. Most of these are functions that are part + * of the API. + */ + +#include +#include + +#ifndef WIN32 + #include +#else + #include +#endif + +#include "definitions.h" +#include "wiiuse_internal.h" +#include "events.h" +#include "io.h" + +static int g_banner = 0; + +/** + * @breif Returns the version of the library. + */ +const char* wiiuse_version() { + return WIIUSE_VERSION; +} + + +/** + * @brief Clean up wiimote_t array created by wiiuse_init() + */ +void wiiuse_cleanup(struct wiimote_t** wm, int wiimotes) { + int i = 0; + + if (!wm) + return; + + WIIUSE_INFO("wiiuse clean up..."); + + for (; i < wiimotes; ++i) { + wiiuse_disconnect(wm[i]); + free(wm[i]); + } + + free(wm); + + return; +} + + +/** + * @brief Initialize an array of wiimote structures. + * + * @param wiimotes Number of wiimote_t structures to create. + * + * @return An array of initialized wiimote_t structures. + * + * @see wiiuse_connect() + * + * The array returned by this function can be passed to various + * functions, including wiiuse_connect(). + */ +struct wiimote_t** wiiuse_init(int wiimotes) { + int i = 0; + struct wiimote_t** wm = NULL; + + /* + * Please do not remove this banner. + * GPL asks that you please leave output credits intact. + * Thank you. + * + * This banner is only displayed once so that if you need + * to call this function again it won't be intrusive. + */ + if (!g_banner) { + printf( "wiiuse v" WIIUSE_VERSION " loaded.\n" + " By: Michael Laforest \n" + " http://wiiuse.net http://wiiuse.sf.net\n"); + g_banner = 1; + } + + if (!wiimotes) + return NULL; + + wm = malloc(sizeof(struct wiimote_t*) * wiimotes); + + for (i = 0; i < wiimotes; ++i) { + wm[i] = malloc(sizeof(struct wiimote_t)); + memset(wm[i], 0, sizeof(struct wiimote_t)); + + wm[i]->unid = i+1; + + #ifndef WIN32 + wm[i]->bdaddr = *BDADDR_ANY; + wm[i]->out_sock = -1; + wm[i]->in_sock = -1; + #else + wm[i]->dev_handle = 0; + wm[i]->stack = WIIUSE_STACK_UNKNOWN; + wm[i]->normal_timeout = WIIMOTE_DEFAULT_TIMEOUT; + wm[i]->exp_timeout = WIIMOTE_EXP_TIMEOUT; + wm[i]->timeout = wm[i]->normal_timeout; + #endif + + wm[i]->state = WIIMOTE_INIT_STATES; + wm[i]->flags = WIIUSE_INIT_FLAGS; + + wm[i]->event = WIIUSE_NONE; + + wm[i]->exp.type = EXP_NONE; + + wiiuse_set_aspect_ratio(wm[i], WIIUSE_ASPECT_4_3); + wiiuse_set_ir_position(wm[i], WIIUSE_IR_ABOVE); + + wm[i]->orient_threshold = 0.5f; + wm[i]->accel_threshold = 5; + + wm[i]->accel_calib.st_alpha = WIIUSE_DEFAULT_SMOOTH_ALPHA; + } + + return wm; +} + + +/** + * @brief The wiimote disconnected. + * + * @param wm Pointer to a wiimote_t structure. + */ +void wiiuse_disconnected(struct wiimote_t* wm) { + if (!wm) return; + + WIIUSE_INFO("Wiimote disconnected [id %i].", wm->unid); + + /* disable the connected flag */ + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED); + + /* reset a bunch of stuff */ + #ifndef WIN32 + wm->out_sock = -1; + wm->in_sock = -1; + #else + wm->dev_handle = 0; + #endif + + wm->leds = 0; + wm->state = WIIMOTE_INIT_STATES; + wm->read_req = NULL; + wm->handshake_state = 0; + wm->btns = 0; + wm->btns_held = 0; + wm->btns_released = 0; + memset(wm->event_buf, 0, sizeof(wm->event_buf)); + + wm->event = WIIUSE_DISCONNECT; +} + + +/** + * @brief Enable or disable the rumble. + * + * @param wm Pointer to a wiimote_t structure. + * @param status 1 to enable, 0 to disable. + */ +void wiiuse_rumble(struct wiimote_t* wm, int status) { + byte buf; + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return; + + /* make sure to keep the current lit leds */ + buf = wm->leds; + + if (status) { + WIIUSE_DEBUG("Starting rumble..."); + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_RUMBLE); + buf |= 0x01; + } else { + WIIUSE_DEBUG("Stopping rumble..."); + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_RUMBLE); + } + + /* preserve IR state */ + if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) + buf |= 0x04; + + wiiuse_send(wm, WM_CMD_RUMBLE, &buf, 1); +} + + +/** + * @brief Toggle the state of the rumble. + * + * @param wm Pointer to a wiimote_t structure. + */ +void wiiuse_toggle_rumble(struct wiimote_t* wm) { + if (!wm) return; + + wiiuse_rumble(wm, !WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE)); +} + + +/** + * @brief Set the enabled LEDs. + * + * @param wm Pointer to a wiimote_t structure. + * @param leds What LEDs to enable. + * + * \a leds is a bitwise or of WIIMOTE_LED_1, WIIMOTE_LED_2, WIIMOTE_LED_3, or WIIMOTE_LED_4. + */ +void wiiuse_set_leds(struct wiimote_t* wm, int leds) { + byte buf; + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return; + + /* remove the lower 4 bits because they control rumble */ + wm->leds = (leds & 0xF0); + + /* make sure if the rumble is on that we keep it on */ + if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE)) + wm->leds |= 0x01; + + buf = wm->leds; + + wiiuse_send(wm, WM_CMD_LED, &buf, 1); +} + + +/** + * @brief Set if the wiimote should report motion sensing. + * + * @param wm Pointer to a wiimote_t structure. + * @param status 1 to enable, 0 to disable. + * + * Since reporting motion sensing sends a lot of data, + * the wiimote saves power by not transmitting it + * by default. + */ +void wiiuse_motion_sensing(struct wiimote_t* wm, int status) { + if (status) + WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_ACC); + else + WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_ACC); + + wiiuse_set_report_type(wm); +} + + +/** + * @brief Set the report type based on the current wiimote state. + * + * @param wm Pointer to a wiimote_t structure. + * + * @return The report type sent. + * + * The wiimote reports formatted packets depending on the + * report type that was last requested. This function will + * update the type of report that should be sent based on + * the current state of the device. + */ +int wiiuse_set_report_type(struct wiimote_t* wm) { + byte buf[2]; + int motion, exp, ir; + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return 0; + + buf[0] = (WIIMOTE_IS_FLAG_SET(wm, WIIUSE_CONTINUOUS) ? 0x04 : 0x00); /* set to 0x04 for continuous reporting */ + buf[1] = 0x00; + + /* if rumble is enabled, make sure we keep it */ + if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE)) + buf[0] |= 0x01; + + motion = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_ACC); + exp = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP); + ir = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR); + + if (motion && ir && exp) buf[1] = WM_RPT_BTN_ACC_IR_EXP; + else if (motion && exp) buf[1] = WM_RPT_BTN_ACC_EXP; + else if (motion && ir) buf[1] = WM_RPT_BTN_ACC_IR; + else if (ir && exp) buf[1] = WM_RPT_BTN_IR_EXP; + else if (ir) buf[1] = WM_RPT_BTN_ACC_IR; + else if (exp) buf[1] = WM_RPT_BTN_EXP; + else if (motion) buf[1] = WM_RPT_BTN_ACC; + else buf[1] = WM_RPT_BTN; + + WIIUSE_DEBUG("Setting report type: 0x%x", buf[1]); + + exp = wiiuse_send(wm, WM_CMD_REPORT_TYPE, buf, 2); + if (exp <= 0) + return exp; + + return buf[1]; +} + + +/** + * @brief Read data from the wiimote (callback version). + * + * @param wm Pointer to a wiimote_t structure. + * @param read_cb Function pointer to call when the data arrives from the wiimote. + * @param buffer An allocated buffer to store the data as it arrives from the wiimote. + * Must be persistent in memory and large enough to hold the data. + * @param addr The address of wiimote memory to read from. + * @param len The length of the block to be read. + * + * The library can only handle one data read request at a time + * because it must keep track of the buffer and other + * events that are specific to that request. So if a request + * has already been made, subsequent requests will be added + * to a pending list and be sent out when the previous + * finishes. + */ +int wiiuse_read_data_cb(struct wiimote_t* wm, wiiuse_read_cb read_cb, byte* buffer, unsigned int addr, unsigned short len) { + struct read_req_t* req; + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return 0; + if (!buffer || !len || !read_cb) + return 0; + + /* make this request structure */ + req = (struct read_req_t*)malloc(sizeof(struct read_req_t)); + req->cb = read_cb; + req->buf = buffer; + req->addr = addr; + req->size = len; + req->wait = len; + req->dirty = 0; + req->next = NULL; + + /* add this to the request list */ + if (!wm->read_req) { + /* root node */ + wm->read_req = req; + + WIIUSE_DEBUG("Data read request can be sent out immediately."); + + /* send the request out immediately */ + wiiuse_send_next_pending_read_request(wm); + } else { + struct read_req_t* nptr = wm->read_req; + for (; nptr->next; nptr = nptr->next); + nptr->next = req; + + WIIUSE_DEBUG("Added pending data read request."); + } + + return 1; +} + + +/** + * @brief Read data from the wiimote (event version). + * + * @param wm Pointer to a wiimote_t structure. + * @param buffer An allocated buffer to store the data as it arrives from the wiimote. + * Must be persistent in memory and large enough to hold the data. + * @param addr The address of wiimote memory to read from. + * @param len The length of the block to be read. + * + * The library can only handle one data read request at a time + * because it must keep track of the buffer and other + * events that are specific to that request. So if a request + * has already been made, subsequent requests will be added + * to a pending list and be sent out when the previous + * finishes. + */ +int wiiuse_read_data(struct wiimote_t* wm, byte* buffer, unsigned int addr, unsigned short len) { + struct read_req_t* req; + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return 0; + if (!buffer || !len) + return 0; + + /* make this request structure */ + req = (struct read_req_t*)malloc(sizeof(struct read_req_t)); + req->cb = NULL; + req->buf = buffer; + req->addr = addr; + req->size = len; + req->wait = len; + req->dirty = 0; + req->next = NULL; + + /* add this to the request list */ + if (!wm->read_req) { + /* root node */ + wm->read_req = req; + + WIIUSE_DEBUG("Data read request can be sent out immediately."); + + /* send the request out immediately */ + wiiuse_send_next_pending_read_request(wm); + } else { + struct read_req_t* nptr = wm->read_req; + for (; nptr->next; nptr = nptr->next); + nptr->next = req; + + WIIUSE_DEBUG("Added pending data read request."); + } + + return 1; +} + + +/** + * @brief Send the next pending data read request to the wiimote. + * + * @param wm Pointer to a wiimote_t structure. + * + * @see wiiuse_read_data() + * + * This function is not part of the wiiuse API. + */ +void wiiuse_send_next_pending_read_request(struct wiimote_t* wm) { + byte buf[6]; + struct read_req_t* req; + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return; + if (!wm->read_req) return; + + /* skip over dirty ones since they have already been read */ + req = wm->read_req; + while (req && req->dirty) + req = req->next; + if (!req) + return; + + /* the offset is in big endian */ + *(int*)(buf) = BIG_ENDIAN_LONG(req->addr); + + /* the length is in big endian */ + *(short*)(buf + 4) = BIG_ENDIAN_SHORT(req->size); + + WIIUSE_DEBUG("Request read at address: 0x%x length: %i", req->addr, req->size); + wiiuse_send(wm, WM_CMD_READ_DATA, buf, 6); +} + + +/** + * @brief Request the wiimote controller status. + * + * @param wm Pointer to a wiimote_t structure. + * + * Controller status includes: battery level, LED status, expansions + */ +void wiiuse_status(struct wiimote_t* wm) { + byte buf = 0; + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return; + + WIIUSE_DEBUG("Requested wiimote status."); + + wiiuse_send(wm, WM_CMD_CTRL_STATUS, &buf, 1); +} + + +/** + * @brief Find a wiimote_t structure by its unique identifier. + * + * @param wm Pointer to a wiimote_t structure. + * @param wiimotes The number of wiimote_t structures in \a wm. + * @param unid The unique identifier to search for. + * + * @return Pointer to a wiimote_t structure, or NULL if not found. + */ +struct wiimote_t* wiiuse_get_by_id(struct wiimote_t** wm, int wiimotes, int unid) { + int i = 0; + + for (; i < wiimotes; ++i) { + if (wm[i]->unid == unid) + return wm[i]; + } + + return NULL; +} + + +/** + * @brief Write data to the wiimote. + * + * @param wm Pointer to a wiimote_t structure. + * @param addr The address to write to. + * @param data The data to be written to the memory location. + * @param len The length of the block to be written. + */ +int wiiuse_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len) { + byte buf[21] = {0}; /* the payload is always 23 */ + + if (!wm || !WIIMOTE_IS_CONNECTED(wm)) + return 0; + if (!data || !len) + return 0; + + WIIUSE_DEBUG("Writing %i bytes to memory location 0x%x...", len, addr); + + #ifdef WITH_WIIUSE_DEBUG + { + int i = 0; + printf("Write data is: "); + for (; i < len; ++i) + printf("%x ", data[i]); + printf("\n"); + } + #endif + + /* the offset is in big endian */ + *(int*)(buf) = BIG_ENDIAN_LONG(addr); + + /* length */ + *(byte*)(buf + 4) = len; + + /* data */ + memcpy(buf + 5, data, len); + + wiiuse_send(wm, WM_CMD_WRITE_DATA, buf, 21); + return 1; +} + + +/** + * @brief Send a packet to the wiimote. + * + * @param wm Pointer to a wiimote_t structure. + * @param report_type The report type to send (WIIMOTE_CMD_LED, WIIMOTE_CMD_RUMBLE, etc). Found in wiiuse.h + * @param msg The payload. + * @param len Length of the payload in bytes. + * + * This function should replace any write()s directly to the wiimote device. + */ +int wiiuse_send(struct wiimote_t* wm, byte report_type, byte* msg, int len) { + byte buf[32]; /* no payload is better than this */ + int rumble = 0; + + #ifndef WIN32 + buf[0] = WM_SET_REPORT | WM_BT_OUTPUT; + buf[1] = report_type; + #else + buf[0] = report_type; + #endif + + switch (report_type) { + case WM_CMD_LED: + case WM_CMD_RUMBLE: + case WM_CMD_CTRL_STATUS: + { + /* Rumble flag for: 0x11, 0x13, 0x14, 0x15, 0x19 or 0x1a */ + if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE)) + rumble = 1; + break; + } + default: + break; + } + + #ifndef WIN32 + memcpy(buf+2, msg, len); + if (rumble) + buf[2] |= 0x01; + #else + memcpy(buf+1, msg, len); + if (rumble) + buf[1] |= 0x01; + #endif + + #ifdef WITH_WIIUSE_DEBUG + { + int x = 2; + printf("[DEBUG] (id %i) SEND: (%x) %.2x ", wm->unid, buf[0], buf[1]); + #ifndef WIN32 + for (; x < len+2; ++x) + #else + for (; x < len+1; ++x) + #endif + printf("%.2x ", buf[x]); + printf("\n"); + } + #endif + + #ifndef WIN32 + return wiiuse_io_write(wm, buf, len+2); + #else + return wiiuse_io_write(wm, buf, len+1); + #endif +} + + +/** + * @brief Set flags for the specified wiimote. + * + * @param wm Pointer to a wiimote_t structure. + * @param enable Flags to enable. + * @param disable Flags to disable. + * + * @return The flags set after 'enable' and 'disable' have been applied. + * + * The values 'enable' and 'disable' may be any flags OR'ed together. + * Flags are defined in wiiuse.h. + */ +int wiiuse_set_flags(struct wiimote_t* wm, int enable, int disable) { + if (!wm) return 0; + + /* remove mutually exclusive flags */ + enable &= ~disable; + disable &= ~enable; + + wm->flags |= enable; + wm->flags &= ~disable; + + return wm->flags; +} + + +/** + * @brief Set the wiimote smoothing alpha value. + * + * @param wm Pointer to a wiimote_t structure. + * @param alpha The alpha value to set. Between 0 and 1. + * + * @return Returns the old alpha value. + * + * The alpha value is between 0 and 1 and is used in an exponential + * smoothing algorithm. + * + * Smoothing is only performed if the WIIMOTE_USE_SMOOTHING is set. + */ +float wiiuse_set_smooth_alpha(struct wiimote_t* wm, float alpha) { + float old; + + if (!wm) return 0.0f; + + old = wm->accel_calib.st_alpha; + + wm->accel_calib.st_alpha = alpha; + + /* if there is a nunchuk set that too */ + if (wm->exp.type == EXP_NUNCHUK) + wm->exp.nunchuk.accel_calib.st_alpha = alpha; + + return old; +} + + +/** + * @brief Set the bluetooth stack type to use. + * + * @param wm Array of wiimote_t structures. + * @param wiimotes Number of objects in the wm array. + * @param type The type of bluetooth stack to use. + */ +void wiiuse_set_bluetooth_stack(struct wiimote_t** wm, int wiimotes, enum win_bt_stack_t type) { + #ifdef WIN32 + int i; + + if (!wm) return; + + for (i = 0; i < wiimotes; ++i) + wm[i]->stack = type; + #endif +} + + +/** + * @brief Set the orientation event threshold. + * + * @param wm Pointer to a wiimote_t structure. + * @param threshold The decimal place that should be considered a significant change. + * + * If threshold is 0.01, and any angle changes by 0.01 then a significant change + * has occured and the event callback will be invoked. If threshold is 1 then + * the angle has to change by a full degree to generate an event. + */ +void wiiuse_set_orient_threshold(struct wiimote_t* wm, float threshold) { + if (!wm) return; + + wm->orient_threshold = threshold; +} + + +/** + * @brief Set the accelerometer event threshold. + * + * @param wm Pointer to a wiimote_t structure. + * @param threshold The decimal place that should be considered a significant change. + */ +void wiiuse_set_accel_threshold(struct wiimote_t* wm, int threshold) { + if (!wm) return; + + wm->accel_threshold = threshold; +} + + +/** + * @brief Try to resync with the wiimote by starting a new handshake. + * + * @param wm Pointer to a wiimote_t structure. + */ +void wiiuse_resync(struct wiimote_t* wm) { + if (!wm) return; + + wm->handshake_state = 0; + wiiuse_handshake(wm, NULL, 0); +} + + +/** + * @brief Set the normal and expansion handshake timeouts. + * + * @param wm Array of wiimote_t structures. + * @param wiimotes Number of objects in the wm array. + * @param normal_timeout The timeout in milliseconds for a normal read. + * @param exp_timeout The timeout in millisecondsd to wait for an expansion handshake. + */ +void wiiuse_set_timeout(struct wiimote_t** wm, int wiimotes, byte normal_timeout, byte exp_timeout) { + #ifdef WIN32 + int i; + + if (!wm) return; + + for (i = 0; i < wiimotes; ++i) { + wm[i]->normal_timeout = normal_timeout; + wm[i]->exp_timeout = exp_timeout; + } + #endif +} diff --git a/c/wiiuse/wiiuse.h b/c/wiiuse/wiiuse.h new file mode 100644 index 0000000..9dff81c --- /dev/null +++ b/c/wiiuse/wiiuse.h @@ -0,0 +1,653 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * + * @brief API header file. + * + * If this file is included from inside the wiiuse source + * and not from a third party program, then wiimote_internal.h + * is also included which extends this file. + */ + +#ifndef WIIUSE_H_INCLUDED +#define WIIUSE_H_INCLUDED + +#ifdef _WIN32 + /* windows */ + #include +#else + /* nix */ + #include +#endif + +#ifdef WIIUSE_INTERNAL_H_INCLUDED + #define WCONST +#else + #define WCONST const +#endif + +/* led bit masks */ +#define WIIMOTE_LED_NONE 0x00 +#define WIIMOTE_LED_1 0x10 +#define WIIMOTE_LED_2 0x20 +#define WIIMOTE_LED_3 0x40 +#define WIIMOTE_LED_4 0x80 + +/* button codes */ +#define WIIMOTE_BUTTON_TWO 0x0001 +#define WIIMOTE_BUTTON_ONE 0x0002 +#define WIIMOTE_BUTTON_B 0x0004 +#define WIIMOTE_BUTTON_A 0x0008 +#define WIIMOTE_BUTTON_MINUS 0x0010 +#define WIIMOTE_BUTTON_ZACCEL_BIT6 0x0020 +#define WIIMOTE_BUTTON_ZACCEL_BIT7 0x0040 +#define WIIMOTE_BUTTON_HOME 0x0080 +#define WIIMOTE_BUTTON_LEFT 0x0100 +#define WIIMOTE_BUTTON_RIGHT 0x0200 +#define WIIMOTE_BUTTON_DOWN 0x0400 +#define WIIMOTE_BUTTON_UP 0x0800 +#define WIIMOTE_BUTTON_PLUS 0x1000 +#define WIIMOTE_BUTTON_ZACCEL_BIT4 0x2000 +#define WIIMOTE_BUTTON_ZACCEL_BIT5 0x4000 +#define WIIMOTE_BUTTON_UNKNOWN 0x8000 +#define WIIMOTE_BUTTON_ALL 0x1F9F + +/* nunchul button codes */ +#define NUNCHUK_BUTTON_Z 0x01 +#define NUNCHUK_BUTTON_C 0x02 +#define NUNCHUK_BUTTON_ALL 0x03 + +/* classic controller button codes */ +#define CLASSIC_CTRL_BUTTON_UP 0x0001 +#define CLASSIC_CTRL_BUTTON_LEFT 0x0002 +#define CLASSIC_CTRL_BUTTON_ZR 0x0004 +#define CLASSIC_CTRL_BUTTON_X 0x0008 +#define CLASSIC_CTRL_BUTTON_A 0x0010 +#define CLASSIC_CTRL_BUTTON_Y 0x0020 +#define CLASSIC_CTRL_BUTTON_B 0x0040 +#define CLASSIC_CTRL_BUTTON_ZL 0x0080 +#define CLASSIC_CTRL_BUTTON_FULL_R 0x0200 +#define CLASSIC_CTRL_BUTTON_PLUS 0x0400 +#define CLASSIC_CTRL_BUTTON_HOME 0x0800 +#define CLASSIC_CTRL_BUTTON_MINUS 0x1000 +#define CLASSIC_CTRL_BUTTON_FULL_L 0x2000 +#define CLASSIC_CTRL_BUTTON_DOWN 0x4000 +#define CLASSIC_CTRL_BUTTON_RIGHT 0x8000 +#define CLASSIC_CTRL_BUTTON_ALL 0xFEFF + +/* guitar hero 3 button codes */ +#define GUITAR_HERO_3_BUTTON_STRUM_UP 0x0001 +#define GUITAR_HERO_3_BUTTON_YELLOW 0x0008 +#define GUITAR_HERO_3_BUTTON_GREEN 0x0010 +#define GUITAR_HERO_3_BUTTON_BLUE 0x0020 +#define GUITAR_HERO_3_BUTTON_RED 0x0040 +#define GUITAR_HERO_3_BUTTON_ORANGE 0x0080 +#define GUITAR_HERO_3_BUTTON_PLUS 0x0400 +#define GUITAR_HERO_3_BUTTON_MINUS 0x1000 +#define GUITAR_HERO_3_BUTTON_STRUM_DOWN 0x4000 +#define GUITAR_HERO_3_BUTTON_ALL 0xFEFF + + +/* wiimote option flags */ +#define WIIUSE_SMOOTHING 0x01 +#define WIIUSE_CONTINUOUS 0x02 +#define WIIUSE_ORIENT_THRESH 0x04 +#define WIIUSE_INIT_FLAGS (WIIUSE_SMOOTHING | WIIUSE_ORIENT_THRESH) + +#define WIIUSE_ORIENT_PRECISION 100.0f + +/* expansion codes */ +#define EXP_NONE 0 +#define EXP_NUNCHUK 1 +#define EXP_CLASSIC 2 +#define EXP_GUITAR_HERO_3 3 + +/* IR correction types */ +typedef enum ir_position_t { + WIIUSE_IR_ABOVE, + WIIUSE_IR_BELOW +} ir_position_t; + +/** + * @brief Check if a button is pressed. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is pressed, 0 if not. + */ +#define IS_PRESSED(dev, button) ((dev->btns & button) == button) + +/** + * @brief Check if a button is being held. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is held, 0 if not. + */ +#define IS_HELD(dev, button) ((dev->btns_held & button) == button) + +/** + * @brief Check if a button is released on this event. \n\n + * This does not mean the button is not pressed, it means \n + * this button was just now released. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is released, 0 if not. + * + */ +#define IS_RELEASED(dev, button) ((dev->btns_released & button) == button) + +/** + * @brief Check if a button has just been pressed this event. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is pressed, 0 if not. + */ +#define IS_JUST_PRESSED(dev, button) (IS_PRESSED(dev, button) && !IS_HELD(dev, button)) + +/** + * @brief Return the IR sensitivity level. + * @param wm Pointer to a wiimote_t structure. + * @param lvl [out] Pointer to an int that will hold the level setting. + * If no level is set 'lvl' will be set to 0. + */ +#define WIIUSE_GET_IR_SENSITIVITY(dev, lvl) \ + do { \ + if ((wm->state & 0x0200) == 0x0200) *lvl = 1; \ + else if ((wm->state & 0x0400) == 0x0400) *lvl = 2; \ + else if ((wm->state & 0x0800) == 0x0800) *lvl = 3; \ + else if ((wm->state & 0x1000) == 0x1000) *lvl = 4; \ + else if ((wm->state & 0x2000) == 0x2000) *lvl = 5; \ + else *lvl = 0; \ + } while (0) + +#define WIIUSE_USING_ACC(wm) ((wm->state & 0x020) == 0x020) +#define WIIUSE_USING_EXP(wm) ((wm->state & 0x040) == 0x040) +#define WIIUSE_USING_IR(wm) ((wm->state & 0x080) == 0x080) +#define WIIUSE_USING_SPEAKER(wm) ((wm->state & 0x100) == 0x100) + +#define WIIUSE_IS_LED_SET(wm, num) ((wm->leds & WIIMOTE_LED_##num) == WIIMOTE_LED_##num) + +/* + * Largest known payload is 21 bytes. + * Add 2 for the prefix and round up to a power of 2. + */ +#define MAX_PAYLOAD 32 + +/* + * This is left over from an old hack, but it may actually + * be a useful feature to keep so it wasn't removed. + */ +#ifdef WIN32 + #define WIIMOTE_DEFAULT_TIMEOUT 10 + #define WIIMOTE_EXP_TIMEOUT 10 +#endif + +typedef unsigned char byte; +typedef char sbyte; + +struct wiimote_t; +struct vec3b_t; +struct orient_t; +struct gforce_t; + + +/** + * @brief Callback that handles a read event. + * + * @param wm Pointer to a wiimote_t structure. + * @param data Pointer to the filled data block. + * @param len Length in bytes of the data block. + * + * @see wiiuse_init() + * + * A registered function of this type is called automatically by the wiiuse + * library when the wiimote has returned the full data requested by a previous + * call to wiiuse_read_data(). + */ +typedef void (*wiiuse_read_cb)(struct wiimote_t* wm, byte* data, unsigned short len); + + +/** + * @struct read_req_t + * @brief Data read request structure. + */ +struct read_req_t { + wiiuse_read_cb cb; /**< read data callback */ + byte* buf; /**< buffer where read data is written */ + unsigned int addr; /**< the offset that the read started at */ + unsigned short size; /**< the length of the data read */ + unsigned short wait; /**< num bytes still needed to finish read */ + byte dirty; /**< set to 1 if not using callback and needs to be cleaned up */ + + struct read_req_t* next; /**< next read request in the queue */ +}; + + +/** + * @struct vec2b_t + * @brief Unsigned x,y byte vector. + */ +typedef struct vec2b_t { + byte x, y; +} vec2b_t; + + +/** + * @struct vec3b_t + * @brief Unsigned x,y,z byte vector. + */ +typedef struct vec3b_t { + byte x, y, z; +} vec3b_t; + + +/** + * @struct vec3f_t + * @brief Signed x,y,z float struct. + */ +typedef struct vec3f_t { + float x, y, z; +} vec3f_t; + + +/** + * @struct orient_t + * @brief Orientation struct. + * + * Yaw, pitch, and roll range from -180 to 180 degrees. + */ +typedef struct orient_t { + float roll; /**< roll, this may be smoothed if enabled */ + float pitch; /**< pitch, this may be smoothed if enabled */ + float yaw; + + float a_roll; /**< absolute roll, unsmoothed */ + float a_pitch; /**< absolute pitch, unsmoothed */ +} orient_t; + + +/** + * @struct gforce_t + * @brief Gravity force struct. + */ +typedef struct gforce_t { + float x, y, z; +} gforce_t; + + +/** + * @struct accel_t + * @brief Accelerometer struct. For any device with an accelerometer. + */ +typedef struct accel_t { + struct vec3b_t cal_zero; /**< zero calibration */ + struct vec3b_t cal_g; /**< 1g difference around 0cal */ + + float st_roll; /**< last smoothed roll value */ + float st_pitch; /**< last smoothed roll pitch */ + float st_alpha; /**< alpha value for smoothing [0-1] */ +} accel_t; + + +/** + * @struct ir_dot_t + * @brief A single IR source. + */ +typedef struct ir_dot_t { + byte visible; /**< if the IR source is visible */ + + unsigned int x; /**< interpolated X coordinate */ + unsigned int y; /**< interpolated Y coordinate */ + + short rx; /**< raw X coordinate (0-1023) */ + short ry; /**< raw Y coordinate (0-767) */ + + byte order; /**< increasing order by x-axis value */ + + byte size; /**< size of the IR dot (0-15) */ +} ir_dot_t; + + +/** + * @enum aspect_t + * @brief Screen aspect ratio. + */ +typedef enum aspect_t { + WIIUSE_ASPECT_4_3, + WIIUSE_ASPECT_16_9 +} aspect_t; + + +/** + * @struct ir_t + * @brief IR struct. Hold all data related to the IR tracking. + */ +typedef struct ir_t { + struct ir_dot_t dot[4]; /**< IR dots */ + byte num_dots; /**< number of dots at this time */ + + enum aspect_t aspect; /**< aspect ratio of the screen */ + + enum ir_position_t pos; /**< IR sensor bar position */ + + unsigned int vres[2]; /**< IR virtual screen resolution */ + int offset[2]; /**< IR XY correction offset */ + int state; /**< keeps track of the IR state */ + + int ax; /**< absolute X coordinate */ + int ay; /**< absolute Y coordinate */ + + int x; /**< calculated X coordinate */ + int y; /**< calculated Y coordinate */ + + float distance; /**< pixel distance between first 2 dots*/ + float z; /**< calculated distance */ +} ir_t; + + +/** + * @struct joystick_t + * @brief Joystick calibration structure. + * + * The angle \a ang is relative to the positive y-axis into quadrant I + * and ranges from 0 to 360 degrees. So if the joystick is held straight + * upwards then angle is 0 degrees. If it is held to the right it is 90, + * down is 180, and left is 270. + * + * The magnitude \a mag is the distance from the center to where the + * joystick is being held. The magnitude ranges from 0 to 1. + * If the joystick is only slightly tilted from the center the magnitude + * will be low, but if it is closer to the outter edge the value will + * be higher. + */ +typedef struct joystick_t { + struct vec2b_t max; /**< maximum joystick values */ + struct vec2b_t min; /**< minimum joystick values */ + struct vec2b_t center; /**< center joystick values */ + + float ang; /**< angle the joystick is being held */ + float mag; /**< magnitude of the joystick (range 0-1) */ +} joystick_t; + + +/** + * @struct nunchuk_t + * @brief Nunchuk expansion device. + */ +typedef struct nunchuk_t { + struct accel_t accel_calib; /**< nunchuk accelerometer calibration */ + struct joystick_t js; /**< joystick calibration */ + + int* flags; /**< options flag (points to wiimote_t.flags) */ + + byte btns; /**< what buttons have just been pressed */ + byte btns_held; /**< what buttons are being held down */ + byte btns_released; /**< what buttons were just released this */ + + float orient_threshold; /**< threshold for orient to generate an event */ + int accel_threshold; /**< threshold for accel to generate an event */ + + struct vec3b_t accel; /**< current raw acceleration data */ + struct orient_t orient; /**< current orientation on each axis */ + struct gforce_t gforce; /**< current gravity forces on each axis */ +} nunchuk_t; + + +/** + * @struct classic_ctrl_t + * @brief Classic controller expansion device. + */ +typedef struct classic_ctrl_t { + short btns; /**< what buttons have just been pressed */ + short btns_held; /**< what buttons are being held down */ + short btns_released; /**< what buttons were just released this */ + + float r_shoulder; /**< right shoulder button (range 0-1) */ + float l_shoulder; /**< left shoulder button (range 0-1) */ + + struct joystick_t ljs; /**< left joystick calibration */ + struct joystick_t rjs; /**< right joystick calibration */ +} classic_ctrl_t; + + +/** + * @struct guitar_hero_3_t + * @brief Guitar Hero 3 expansion device. + */ +typedef struct guitar_hero_3_t { + short btns; /**< what buttons have just been pressed */ + short btns_held; /**< what buttons are being held down */ + short btns_released; /**< what buttons were just released this */ + + float whammy_bar; /**< whammy bar (range 0-1) */ + + struct joystick_t js; /**< joystick calibration */ +} guitar_hero_3_t; + + +/** + * @struct expansion_t + * @brief Generic expansion device plugged into wiimote. + */ +typedef struct expansion_t { + int type; /**< type of expansion attached */ + + union { + struct nunchuk_t nunchuk; + struct classic_ctrl_t classic; + struct guitar_hero_3_t gh3; + }; +} expansion_t; + + +/** + * @enum win32_bt_stack_t + * @brief Available bluetooth stacks for Windows. + */ +typedef enum win_bt_stack_t { + WIIUSE_STACK_UNKNOWN, + WIIUSE_STACK_MS, + WIIUSE_STACK_BLUESOLEIL +} win_bt_stack_t; + + +/** + * @struct wiimote_state_t + * @brief Significant data from the previous event. + */ +typedef struct wiimote_state_t { + /* expansion_t */ + float exp_ljs_ang; + float exp_rjs_ang; + float exp_ljs_mag; + float exp_rjs_mag; + unsigned short exp_btns; + struct orient_t exp_orient; + struct vec3b_t exp_accel; + float exp_r_shoulder; + float exp_l_shoulder; + + /* ir_t */ + int ir_ax; + int ir_ay; + float ir_distance; + + struct orient_t orient; + unsigned short btns; + + struct vec3b_t accel; +} wiimote_state_t; + + +/** + * @enum WIIUSE_EVENT_TYPE + * @brief Events that wiiuse can generate from a poll. + */ +typedef enum WIIUSE_EVENT_TYPE { + WIIUSE_NONE = 0, + WIIUSE_EVENT, + WIIUSE_STATUS, + WIIUSE_CONNECT, + WIIUSE_DISCONNECT, + WIIUSE_UNEXPECTED_DISCONNECT, + WIIUSE_READ_DATA, + WIIUSE_NUNCHUK_INSERTED, + WIIUSE_NUNCHUK_REMOVED, + WIIUSE_CLASSIC_CTRL_INSERTED, + WIIUSE_CLASSIC_CTRL_REMOVED, + WIIUSE_GUITAR_HERO_3_CTRL_INSERTED, + WIIUSE_GUITAR_HERO_3_CTRL_REMOVED +} WIIUSE_EVENT_TYPE; + +/** + * @struct wiimote_t + * @brief Wiimote structure. + */ +typedef struct wiimote_t { + WCONST int unid; /**< user specified id */ + + #ifndef WIN32 + WCONST bdaddr_t bdaddr; /**< bt address */ + WCONST char bdaddr_str[18]; /**< readable bt address */ + WCONST int out_sock; /**< output socket */ + WCONST int in_sock; /**< input socket */ + #else + WCONST HANDLE dev_handle; /**< HID handle */ + WCONST OVERLAPPED hid_overlap; /**< overlap handle */ + WCONST enum win_bt_stack_t stack; /**< type of bluetooth stack to use */ + WCONST int timeout; /**< read timeout */ + WCONST byte normal_timeout; /**< normal timeout */ + WCONST byte exp_timeout; /**< timeout for expansion handshake */ + #endif + + WCONST int state; /**< various state flags */ + WCONST byte leds; /**< currently lit leds */ + WCONST float battery_level; /**< battery level */ + + WCONST int flags; /**< options flag */ + + WCONST byte handshake_state; /**< the state of the connection handshake */ + + WCONST struct read_req_t* read_req; /**< list of data read requests */ + WCONST struct accel_t accel_calib; /**< wiimote accelerometer calibration */ + WCONST struct expansion_t exp; /**< wiimote expansion device */ + + WCONST struct vec3b_t accel; /**< current raw acceleration data */ + WCONST struct orient_t orient; /**< current orientation on each axis */ + WCONST struct gforce_t gforce; /**< current gravity forces on each axis */ + + WCONST struct ir_t ir; /**< IR data */ + + WCONST unsigned short btns; /**< what buttons have just been pressed */ + WCONST unsigned short btns_held; /**< what buttons are being held down */ + WCONST unsigned short btns_released; /**< what buttons were just released this */ + + WCONST float orient_threshold; /**< threshold for orient to generate an event */ + WCONST int accel_threshold; /**< threshold for accel to generate an event */ + + WCONST struct wiimote_state_t lstate; /**< last saved state */ + + WCONST WIIUSE_EVENT_TYPE event; /**< type of event that occured */ + WCONST byte event_buf[MAX_PAYLOAD]; /**< event buffer */ +} wiimote; + + +/***************************************** + * + * Include API specific stuff + * + *****************************************/ + +#ifdef _WIN32 + #define WIIUSE_EXPORT_DECL __declspec(dllexport) + #define WIIUSE_IMPORT_DECL __declspec(dllimport) +#else + #define WIIUSE_EXPORT_DECL + #define WIIUSE_IMPORT_DECL +#endif + +#ifdef WIIUSE_COMPILE_LIB + #define WIIUSE_EXPORT WIIUSE_EXPORT_DECL +#else + #define WIIUSE_EXPORT WIIUSE_IMPORT_DECL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* wiiuse.c */ +WIIUSE_EXPORT extern const char* wiiuse_version(); + +WIIUSE_EXPORT extern struct wiimote_t** wiiuse_init(int wiimotes); +WIIUSE_EXPORT extern void wiiuse_disconnected(struct wiimote_t* wm); +WIIUSE_EXPORT extern void wiiuse_cleanup(struct wiimote_t** wm, int wiimotes); +WIIUSE_EXPORT extern void wiiuse_rumble(struct wiimote_t* wm, int status); +WIIUSE_EXPORT extern void wiiuse_toggle_rumble(struct wiimote_t* wm); +WIIUSE_EXPORT extern void wiiuse_set_leds(struct wiimote_t* wm, int leds); +WIIUSE_EXPORT extern void wiiuse_motion_sensing(struct wiimote_t* wm, int status); +WIIUSE_EXPORT extern int wiiuse_read_data(struct wiimote_t* wm, byte* buffer, unsigned int offset, unsigned short len); +WIIUSE_EXPORT extern int wiiuse_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len); +WIIUSE_EXPORT extern void wiiuse_status(struct wiimote_t* wm); +WIIUSE_EXPORT extern struct wiimote_t* wiiuse_get_by_id(struct wiimote_t** wm, int wiimotes, int unid); +WIIUSE_EXPORT extern int wiiuse_set_flags(struct wiimote_t* wm, int enable, int disable); +WIIUSE_EXPORT extern float wiiuse_set_smooth_alpha(struct wiimote_t* wm, float alpha); +WIIUSE_EXPORT extern void wiiuse_set_bluetooth_stack(struct wiimote_t** wm, int wiimotes, enum win_bt_stack_t type); +WIIUSE_EXPORT extern void wiiuse_set_orient_threshold(struct wiimote_t* wm, float threshold); +WIIUSE_EXPORT extern void wiiuse_resync(struct wiimote_t* wm); +WIIUSE_EXPORT extern void wiiuse_set_timeout(struct wiimote_t** wm, int wiimotes, byte normal_timeout, byte exp_timeout); +WIIUSE_EXPORT extern void wiiuse_set_accel_threshold(struct wiimote_t* wm, int threshold); + +/* connect.c */ +WIIUSE_EXPORT extern int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout); +WIIUSE_EXPORT extern int wiiuse_connect(struct wiimote_t** wm, int wiimotes); +WIIUSE_EXPORT extern void wiiuse_disconnect(struct wiimote_t* wm); + +/* events.c */ +WIIUSE_EXPORT extern int wiiuse_poll(struct wiimote_t** wm, int wiimotes); + +/* ir.c */ +WIIUSE_EXPORT extern void wiiuse_set_ir(struct wiimote_t* wm, int status); +WIIUSE_EXPORT extern void wiiuse_set_ir_vres(struct wiimote_t* wm, unsigned int x, unsigned int y); +WIIUSE_EXPORT extern void wiiuse_set_ir_position(struct wiimote_t* wm, enum ir_position_t pos); +WIIUSE_EXPORT extern void wiiuse_set_aspect_ratio(struct wiimote_t* wm, enum aspect_t aspect); +WIIUSE_EXPORT extern void wiiuse_set_ir_sensitivity(struct wiimote_t* wm, int level); + +/* nunchuk.c */ +WIIUSE_EXPORT extern void wiiuse_set_nunchuk_orient_threshold(struct wiimote_t* wm, float threshold); +WIIUSE_EXPORT extern void wiiuse_set_nunchuk_accel_threshold(struct wiimote_t* wm, int threshold); + + +#ifdef __cplusplus +} +#endif + + +#endif /* WIIUSE_H_INCLUDED */ + diff --git a/c/wiiuse/wiiuse_internal.h b/c/wiiuse/wiiuse_internal.h new file mode 100644 index 0000000..1b2f423 --- /dev/null +++ b/c/wiiuse/wiiuse_internal.h @@ -0,0 +1,226 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header$ + * + */ + +/** + * @file + * @brief General internal wiiuse stuff. + * + * Since Wiiuse is a library, wiiuse.h is a duplicate + * of the API header. + * + * The code that would normally go in that file, but + * which is not needed by third party developers, + * is put here. + * + * So wiiuse_internal.h is included by other files + * internally, wiiuse.h is included only here. + */ + +#ifndef WIIUSE_INTERNAL_H_INCLUDED +#define WIIUSE_INTERNAL_H_INCLUDED + +#ifndef WIN32 + #include /* htons() */ + #include +#endif + +#include "definitions.h" + +/* wiiuse version */ +#define WIIUSE_VERSION "0.12" + +/******************** + * + * Wiimote internal codes + * + ********************/ + +/* Communication channels */ +#define WM_OUTPUT_CHANNEL 0x11 +#define WM_INPUT_CHANNEL 0x13 + +#define WM_SET_REPORT 0x50 + +/* commands */ +#define WM_CMD_LED 0x11 +#define WM_CMD_REPORT_TYPE 0x12 +#define WM_CMD_RUMBLE 0x13 +#define WM_CMD_IR 0x13 +#define WM_CMD_CTRL_STATUS 0x15 +#define WM_CMD_WRITE_DATA 0x16 +#define WM_CMD_READ_DATA 0x17 +#define WM_CMD_IR_2 0x1A + +/* input report ids */ +#define WM_RPT_CTRL_STATUS 0x20 +#define WM_RPT_READ 0x21 +#define WM_RPT_WRITE 0x22 +#define WM_RPT_BTN 0x30 +#define WM_RPT_BTN_ACC 0x31 +#define WM_RPT_BTN_ACC_IR 0x33 +#define WM_RPT_BTN_EXP 0x34 +#define WM_RPT_BTN_ACC_EXP 0x35 +#define WM_RPT_BTN_IR_EXP 0x36 +#define WM_RPT_BTN_ACC_IR_EXP 0x37 + +#define WM_BT_INPUT 0x01 +#define WM_BT_OUTPUT 0x02 + +/* Identify the wiimote device by its class */ +#define WM_DEV_CLASS_0 0x04 +#define WM_DEV_CLASS_1 0x25 +#define WM_DEV_CLASS_2 0x00 +#define WM_VENDOR_ID 0x057E +#define WM_PRODUCT_ID 0x0306 + +/* controller status stuff */ +#define WM_MAX_BATTERY_CODE 0xC8 + +/* offsets in wiimote memory */ +#define WM_MEM_OFFSET_CALIBRATION 0x16 +#define WM_EXP_MEM_BASE 0x04A40000 +#define WM_EXP_MEM_ENABLE 0x04A40040 +#define WM_EXP_MEM_CALIBR 0x04A40020 + +#define WM_REG_IR 0x04B00030 +#define WM_REG_IR_BLOCK1 0x04B00000 +#define WM_REG_IR_BLOCK2 0x04B0001A +#define WM_REG_IR_MODENUM 0x04B00033 + +/* ir block data */ +#define WM_IR_BLOCK1_LEVEL1 "\x02\x00\x00\x71\x01\x00\x64\x00\xfe" +#define WM_IR_BLOCK2_LEVEL1 "\xfd\x05" +#define WM_IR_BLOCK1_LEVEL2 "\x02\x00\x00\x71\x01\x00\x96\x00\xb4" +#define WM_IR_BLOCK2_LEVEL2 "\xb3\x04" +#define WM_IR_BLOCK1_LEVEL3 "\x02\x00\x00\x71\x01\x00\xaa\x00\x64" +#define WM_IR_BLOCK2_LEVEL3 "\x63\x03" +#define WM_IR_BLOCK1_LEVEL4 "\x02\x00\x00\x71\x01\x00\xc8\x00\x36" +#define WM_IR_BLOCK2_LEVEL4 "\x35\x03" +#define WM_IR_BLOCK1_LEVEL5 "\x07\x00\x00\x71\x01\x00\x72\x00\x20" +#define WM_IR_BLOCK2_LEVEL5 "\x1f\x03" + +#define WM_IR_TYPE_BASIC 0x01 +#define WM_IR_TYPE_EXTENDED 0x03 + +/* controller status flags for the first message byte */ +/* bit 1 is unknown */ +#define WM_CTRL_STATUS_BYTE1_ATTACHMENT 0x02 +#define WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED 0x04 +#define WM_CTRL_STATUS_BYTE1_IR_ENABLED 0x08 +#define WM_CTRL_STATUS_BYTE1_LED_1 0x10 +#define WM_CTRL_STATUS_BYTE1_LED_2 0x20 +#define WM_CTRL_STATUS_BYTE1_LED_3 0x40 +#define WM_CTRL_STATUS_BYTE1_LED_4 0x80 + +/* aspect ratio */ +#define WM_ASPECT_16_9_X 660 +#define WM_ASPECT_16_9_Y 370 +#define WM_ASPECT_4_3_X 560 +#define WM_ASPECT_4_3_Y 420 + + +/** + * Expansion stuff + */ + +/* encrypted expansion id codes (located at 0x04A400FC) */ +#define EXP_ID_CODE_NUNCHUK 0x9A1EFEFE +#define EXP_ID_CODE_CLASSIC_CONTROLLER 0x9A1EFDFD +#define EXP_ID_CODE_GUITAR 0x9A1EFDFB + +#define EXP_HANDSHAKE_LEN 224 + +/******************** + * + * End Wiimote internal codes + * + ********************/ + +/* wiimote state flags - (some duplicated in wiiuse.h)*/ +#define WIIMOTE_STATE_DEV_FOUND 0x0001 +#define WIIMOTE_STATE_HANDSHAKE 0x0002 /* actual connection exists but no handshake yet */ +#define WIIMOTE_STATE_HANDSHAKE_COMPLETE 0x0004 /* actual connection exists but no handshake yet */ +#define WIIMOTE_STATE_CONNECTED 0x0008 +#define WIIMOTE_STATE_RUMBLE 0x0010 +#define WIIMOTE_STATE_ACC 0x0020 +#define WIIMOTE_STATE_EXP 0x0040 +#define WIIMOTE_STATE_IR 0x0080 +#define WIIMOTE_STATE_SPEAKER 0x0100 +#define WIIMOTE_STATE_IR_SENS_LVL1 0x0200 +#define WIIMOTE_STATE_IR_SENS_LVL2 0x0400 +#define WIIMOTE_STATE_IR_SENS_LVL3 0x0800 +#define WIIMOTE_STATE_IR_SENS_LVL4 0x1000 +#define WIIMOTE_STATE_IR_SENS_LVL5 0x2000 + +#define WIIMOTE_INIT_STATES (WIIMOTE_STATE_IR_SENS_LVL3) + +/* macro to manage states */ +#define WIIMOTE_IS_SET(wm, s) ((wm->state & (s)) == (s)) +#define WIIMOTE_ENABLE_STATE(wm, s) (wm->state |= (s)) +#define WIIMOTE_DISABLE_STATE(wm, s) (wm->state &= ~(s)) +#define WIIMOTE_TOGGLE_STATE(wm, s) ((wm->state & (s)) ? WIIMOTE_DISABLE_STATE(wm, s) : WIIMOTE_ENABLE_STATE(wm, s)) + +#define WIIMOTE_IS_FLAG_SET(wm, s) ((wm->flags & (s)) == (s)) +#define WIIMOTE_ENABLE_FLAG(wm, s) (wm->flags |= (s)) +#define WIIMOTE_DISABLE_FLAG(wm, s) (wm->flags &= ~(s)) +#define WIIMOTE_TOGGLE_FLAG(wm, s) ((wm->flags & (s)) ? WIIMOTE_DISABLE_FLAG(wm, s) : WIIMOTE_ENABLE_FLAG(wm, s)) + +#define NUNCHUK_IS_FLAG_SET(wm, s) ((*(wm->flags) & (s)) == (s)) + +/* misc macros */ +#define WIIMOTE_ID(wm) (wm->unid) +#define WIIMOTE_IS_CONNECTED(wm) (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_CONNECTED)) + +/* + * Smooth tilt calculations are computed with the + * exponential moving average formula: + * St = St_last + (alpha * (tilt - St_last)) + * alpha is between 0 and 1 + */ +#define WIIUSE_DEFAULT_SMOOTH_ALPHA 0.07f + +#define SMOOTH_ROLL 0x01 +#define SMOOTH_PITCH 0x02 + +#include "wiiuse.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* not part of the api */ +int wiiuse_set_report_type(struct wiimote_t* wm); +void wiiuse_send_next_pending_read_request(struct wiimote_t* wm); +int wiiuse_send(struct wiimote_t* wm, byte report_type, byte* msg, int len); +int wiiuse_read_data_cb(struct wiimote_t* wm, wiiuse_read_cb read_cb, byte* buffer, unsigned int offset, unsigned short len); + +#ifdef __cplusplus +} +#endif + +#endif /* WIIUSE_INTERNAL_H_INCLUDED */ diff --git a/c/wiiusej/wiiusej_WiiUseApi.c b/c/wiiusej/wiiusej_WiiUseApi.c new file mode 100644 index 0000000..6031191 --- /dev/null +++ b/c/wiiusej/wiiusej_WiiUseApi.c @@ -0,0 +1,669 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +#ifndef WIN32 +#include +#else + +#endif + +#include "wiiusej_WiiUseApi.h" +#include "wiiuse.h" +/* + * These are some identifiers for wiimotes + * + * See below in main() for what they are used for. + */ +#define WIIMOTE_STATE_RUMBLE 0x0010 +#define WIIMOTE_STATE_CONNECTED 0x0008 +#define WIIMOTE_IS_SET(wm, s) ((wm->state & (s)) == (s)) +#define WIIMOTE_IS_FLAG_SET(wm, s) ((wm->flags & (s)) == (s)) +#define WIIUSE_GET_IR_SENSITIVITY_CORRECTED(wm, lvl) \ + do { \ + if ((wm->state & 0x0200) == 0x0200) *lvl = 1; \ + else if ((wm->state & 0x0400) == 0x0400) *lvl = 2; \ + else if ((wm->state & 0x0800) == 0x0800) *lvl = 3; \ + else if ((wm->state & 0x1000) == 0x1000) *lvl = 4; \ + else if ((wm->state & 0x2000) == 0x2000) *lvl = 5; \ + else *lvl = 0; \ + } while (0) + +/********************* VARIABLES DECLARATIONS *****************************/ + +/* + * Make a temp array of wiimote ids. + * Here I only anticipate connecting up to + * two wiimotes. Each wiimote connected + * will get one of these ids. + */ +static wiimote** wiimotes; +static int nbMaxWiimotes; + +/****************** GENERAL FUNCTIONS DEFINITIONS *************************/ + +/** + * Connect to a wiimote or wiimotes once an address is known. + * @param nbWiimotes The number of wiimotes. + * @return The number of wiimotes that successfully connected. + */ +JNIEXPORT jint JNICALL Java_wiiusej_WiiUseApi_connect +(JNIEnv *env, jobject obj, jint nbWiimotes) { + return wiiuse_connect(wiimotes, nbWiimotes); +} + +/** + * Find a wiimote or wiimotes. + * @param nbMaxWiimotes The number of wiimotes. + * @param timeout The number of seconds before the search times out. + * @return The number of wiimotes found. + */ +JNIEXPORT jint JNICALL Java_wiiusej_WiiUseApi_find +(JNIEnv *env, jobject obj, jint nbMaxWiimotes, jint timeout) { + return wiiuse_find(wiimotes, nbMaxWiimotes, timeout); +} + +/** + * Initialize an array of wiimote structures (for the C side of the library). + * @param nbPossibleWiimotes size of the array. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_init +(JNIEnv *env, jobject obj, jint nbPossibleWiimotes) { + wiimotes = wiiuse_init(nbPossibleWiimotes); + nbMaxWiimotes = nbPossibleWiimotes; +} + +/** + * Close connection to the wiimote with the given id. + * + * @param id the id of the wiimote to disconnect.Must be 1 or 2. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_closeConnection +(JNIEnv *env, jobject obj, jint id) { + wiiuse_disconnect(wiimotes[id]); +} + +/** + * Get unique id of a wiimote in the wiimotes array. + * Please make sure you call an existing index with a + * wiimote initialized at this index, + * other wise you'll get a wrong value. + * @param index index of the wiimote in the wiimotes array. + */ +JNIEXPORT jint JNICALL Java_wiiusej_WiiUseApi_getUnId +(JNIEnv *env, jobject obj, jint index) { + return wiimotes[index]->unid; +} + +/** + * Shutdown api. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_cleanUp +(JNIEnv *env, jobject obj) { + wiiuse_cleanup(wiimotes, nbMaxWiimotes); +} + +/** + * Activate rumble for the wiimote with the given id. + * @param id the id of the wiimote.Must be 1 or 2. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_activateRumble +(JNIEnv *env, jobject obj, jint id) { + wiiuse_rumble(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), 1); +} + +/** + * Deactivate rumble for the wiimote with the given id. + * @param id the id of the wiimote.Must be 1 or 2. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_deactivateRumble +(JNIEnv *env, jobject obj, jint id) { + wiiuse_rumble(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), 0); +} + +/** + * Activate IR TRacking for the wiimote with the given id. + * @param id the id of the wiimote. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_activateIRTracking +(JNIEnv *env, jobject obj, jint id) { + wiiuse_set_ir(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), 1); +} + +/** + * Deactivate IR TRacking for the wiimote with the given id. + * @param id the id of the wiimote.Must be 1 or 2. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_deactivateIRTracking +(JNIEnv *env, jobject obj, jint id) { + wiiuse_set_ir(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), 0); +} + +/** + * Activate Motion Sensing for the wiimote with the given id. + * @param id the id of the wiimote.Must be 1 or 2. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_activateMotionSensing +(JNIEnv *env, jobject obj, jint id) { + wiiuse_motion_sensing(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), 1); +} + +/** + * Deactivate Motion Sensing for the wiimote with the given id. + * @param id the id of the wiimote.Must be 1 or 2. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_deactivateMotionSensing +(JNIEnv *env, jobject obj, jint id) { + wiiuse_motion_sensing(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), 0); +} + +/** + * Set wiimote leds status. + * @param id the id of the wiimote concerned + * @param led1 status of led1: True=ON, False=OFF + * @param led2 status of led2: True=ON, False=OFF + * @param led3 status of led3: True=ON, False=OFF + * @param led4 status of led4: True=ON, False=OFF + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setLeds +(JNIEnv *env, jobject obj, jint id, jboolean led1, jboolean led2, jboolean led3, jboolean led4) { + int leds = 0; + + if (led1) leds |= WIIMOTE_LED_1; + if (led2) leds |= WIIMOTE_LED_2; + if (led3) leds |= WIIMOTE_LED_3; + if (led4) leds |= WIIMOTE_LED_4; + + wiiuse_set_leds(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), leds); +} + +/** + * Set how many degrees an angle must change to generate an event. + * @param id id of the wiimote concerned + * @param thresh minimum angle detected by an event + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setOrientThreshold +(JNIEnv *env, jobject obj, jint id, jfloat thresh) { + wiiuse_set_orient_threshold(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), thresh); +} + +/** + * Set how much acceleration must change to generate an event. + * @param id id of the wiimote concerned + * @param val minimum value detected by an event + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setAccelThreshold +(JNIEnv *env, jobject obj, jint id, jint val) { + wiiuse_set_accel_threshold(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), val); +} + +/** + * Set alpha smoothing parameter for the given id. + * @param id id of the wiimote concerned + * @param value alpha smoothing value + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setAlphaSmoothing +(JNIEnv *env, jobject obj, jint id, jfloat val) { + wiiuse_set_smooth_alpha(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), val); +} + +/** + * Try to resync with the wiimote by starting a new handshake. + * @param id id of the wiimote concerned + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_reSync +(JNIEnv *env, jobject obj, jint id) { + wiiuse_resync(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id)); +} + +/** + * Make the the accelerometers give smoother results. + * This is set by default. + * @param id the id of the wiimote concerned + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_activateSmoothing +(JNIEnv *env, jobject obj, jint id) { + wiiuse_set_flags(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), WIIUSE_SMOOTHING, 0); +} + +/** + * Make the the accelerometers give raw results. + * @param id the id of the wiimote concerned + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_deactivateSmoothing +(JNIEnv *env, jobject obj, jint id) { + wiiuse_set_flags(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), 0, WIIUSE_SMOOTHING); +} + +/** + * Make the wiimote generate an event each time we poll. + * Not set by default. + * @param id the id of the wiimote concerned + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_activateContinuous +(JNIEnv *env, jobject obj, jint id) { + wiiuse_set_flags(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), WIIUSE_CONTINUOUS, 0); +} + +/** + * Make the wiimote generate an event only when there is one. + * (default behavior) + * @param id the id of the wiimote concerned + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_deactivateContinuous +(JNIEnv *env, jobject obj, jint id) { + wiiuse_set_flags(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), 0, WIIUSE_CONTINUOUS); +} + +/** + * Notify wiiuse that your screen has an aspect ratio of 4/3. + * @param id the id of the wiimote concerned + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setScreenRatio43 +(JNIEnv *env, jobject obj, jint id) { + wiiuse_set_aspect_ratio(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), WIIUSE_ASPECT_4_3); +} + +/** + * Notify wiiuse that your screen has an aspect ratio of 16/9. + * @param id the id of the wiimote concerned + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setScreenRatio169 +(JNIEnv *env, jobject obj, jint id) { + wiiuse_set_aspect_ratio(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), WIIUSE_ASPECT_4_3); +} + +/** + * Notify wiiuse that the sensor bar is above your screen. + * @param id the id of the wiimote concerned + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setSensorBarAboveScreen +(JNIEnv *env, jobject obj, jint id) { + wiiuse_set_ir_position(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), WIIUSE_IR_ABOVE); +} + +/** + * Notify wiiuse that the sensor bar is below your screen. + * @param id the id of the wiimote concerned + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setSensorBarBelowScreen +(JNIEnv *env, jobject obj, jint id) { + wiiuse_set_ir_position(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), WIIUSE_IR_BELOW); +} + +/** + * Set virtual screen resolution. It is used to automatically + * compute the position of a cursor on this virtual screen + * using the sensor bar. These results come in the IREvent. + * @param id the id of the wiimote concerned + * @param x x resolution. + * @param y y resolution. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setVirtualScreenResolution +(JNIEnv *env, jobject obj, jint id, jint x, jint y) { + wiiuse_set_ir_vres(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), x, y); +} + +/** + * Get status from the wiimotes and send it through call backs. + * + * @param id the id of the wiimote. Must be 1 or 2. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_getStatus +(JNIEnv *env, jobject obj, jint id) { + wiiuse_status(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id)); +} + +/** + * Set the normal and expansion handshake timeouts. + * + * @param id + * the id of the wiimote concerned. + * @param normalTimeout + * The timeout in milliseconds for a normal read. + * @param expansionTimeout + * The timeout in millisecondsd to wait for an expansion + * handshake. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setTimeout +(JNIEnv *env, jobject obj, jint id, jshort normalTimeout, jshort expansionTimeout) { + wiiuse_set_timeout(wiimotes, nbMaxWiimotes, normalTimeout, expansionTimeout); +} + +/** + * Set the IR sensitivity. + * + * @param id + * the id of the wiimote concerned. + * @param level + * 1-5, same as Wii system sensitivity setting. If the level is < + * 1, then level will be set to 1. If the level is > 5, then + * level will be set to 5. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setIrSensitivity +(JNIEnv *env, jobject obj, jint id, jint level) { + wiiuse_set_ir_sensitivity(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), level); +} + +/** + * Set how many degrees an angle must change to generate an event for the nunchuk. + * @param id id of the wiimote concerned + * @param thresh minimum angle detected by an event + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setNunchukOrientationThreshold +(JNIEnv *env, jobject obj, jint id, jfloat thresh) { + wiiuse_set_nunchuk_orient_threshold(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), thresh); +} + +/** + * Set how much acceleration must change to generate an event for the nunchuk. + * @param id id of the wiimote concerned + * @param val minimum value detected by an event + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setNunchukAccelerationThreshold +(JNIEnv *env, jobject obj, jint id, jint val) { + wiiuse_set_nunchuk_accel_threshold(wiiuse_get_by_id(wiimotes, nbMaxWiimotes, id), val); +} + +/** + * Force the bluetooth stack type.(useful only for windows) + * + * @param bluetoothStackType + * must be WiiUseApi.WIIUSE_STACK_UNKNOWN or WiiUseApi.WIIUSE_STACK_MS or + * WiiUseApi.WIIUSE_STACK_BLUESOLEIL. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_windowsSetBluetoothStack +(JNIEnv *env, jobject obj, jint bluetoothStackType) { + if (bluetoothStackType == 0) { + wiiuse_set_bluetooth_stack(wiimotes, nbMaxWiimotes, WIIUSE_STACK_UNKNOWN); + } else if (bluetoothStackType == 1) { + wiiuse_set_bluetooth_stack(wiimotes, nbMaxWiimotes, WIIUSE_STACK_MS); + } else if (bluetoothStackType == 2) { + wiiuse_set_bluetooth_stack(wiimotes, nbMaxWiimotes, WIIUSE_STACK_BLUESOLEIL); + } +} + +/** + * Get status and values from the wiimotes and send it through callbacks. + * @param wim the wiimote object to fill with the datas. + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_specialPoll +(JNIEnv *env, jobject obj, jobject gath) { + + /* Variables Declarations */ + int i; + short leds = 0; + jclass cls = (*env)->GetObjectClass(env, gath); + jmethodID mid; + printf("avant poll, nbMaxwiimotes : %i \n",nbMaxWiimotes); + if (wiiuse_poll(wiimotes, nbMaxWiimotes)) { + /* + * This happens if something happened on any wiimote. + * So go through each one and check if anything happened. + */ + printf("il y a des events\n"); + for (i=0; i < nbMaxWiimotes; ++i) { + printf("recupe events wiimote : %i\n",nbMaxWiimotes); + switch (wiimotes[i]->event) { + case WIIUSE_EVENT: + /* a generic event occured */ + + printf("Generic event\n"); + mid = (*env)->GetMethodID(env, cls, "prepareWiiMoteEvent", "(ISSS)V"); + if (mid == 0) { + return; + } + (*env)->CallVoidMethod(env, gath, mid, wiimotes[i]->unid, wiimotes[i]->btns, + wiimotes[i]->btns_released, wiimotes[i]->btns_held); + /* + * If IR tracking is enabled then print the coordinates + * on the virtual screen that the wiimote is pointing to. + * + * Also make sure that we see at least 1 dot. + */ + if (WIIUSE_USING_IR(wiimotes[i])) { + printf("IR event\n"); + int a; + WIIUSE_GET_IR_SENSITIVITY_CORRECTED(wiimotes[i], &a); + + mid = (*env)->GetMethodID(env, cls, "prepareIRevent", + "(IIFIIIIIISSSF)V"); + if (mid == 0) { + return; + } + (*env)->CallVoidMethod(env, gath, mid, + wiimotes[i]->ir.x, wiimotes[i]->ir.y, wiimotes[i]->ir.z, + wiimotes[i]->ir.ax, wiimotes[i]->ir.ay, + wiimotes[i]->ir.vres[0], wiimotes[i]->ir.vres[1], + wiimotes[i]->ir.offset[0], wiimotes[i]->ir.offset[1], + wiimotes[i]->ir.pos, wiimotes[i]->ir.aspect, + a , wiimotes[i]->ir.distance); + + mid = (*env)->GetMethodID(env, cls, "addIRPointToPreparedWiiMoteEvent", + "(IISSS)V"); + if (mid == 0) { + return; + } + /* go through each of the 4 possible IR sources */ + for (a=0; a < 4; a++) { + /* check if the source is visible */ + if (wiimotes[i]->ir.dot[a].visible) { + (*env)->CallVoidMethod(env, gath, mid, + wiimotes[i]->ir.dot[a].x, wiimotes[i]->ir.dot[a].y, + wiimotes[i]->ir.dot[a].rx, wiimotes[i]->ir.dot[a].ry, + wiimotes[i]->ir.dot[a].size); + } + } + } + + /* Motion Sensing */ + if (WIIUSE_USING_ACC(wiimotes[i])) { + printf("acc event\n"); + /* set orientation and gravity force */ + mid = (*env)->GetMethodID(env, cls, + "addMotionSensingValues", "(FIZFFFFFFFFFSSS)V"); + if (mid == 0) { + return; + } + (*env)->CallVoidMethod(env, gath, mid, + wiimotes[i]->orient_threshold, wiimotes[i]->accel_threshold, + WIIMOTE_IS_FLAG_SET(wiimotes[i],WIIUSE_SMOOTHING), wiimotes[i]->accel_calib.st_alpha, + wiimotes[i]->orient.roll, wiimotes[i]->orient.pitch, wiimotes[i]->orient.yaw, + wiimotes[i]->orient.a_roll, wiimotes[i]->orient.a_pitch, + wiimotes[i]->gforce.x, wiimotes[i]->gforce.y, wiimotes[i]->gforce.z, + wiimotes[i]->accel.x, wiimotes[i]->accel.y, wiimotes[i]->accel.z); + } + + /* Expansions support support*/ + if (WIIUSE_USING_EXP(wiimotes[i])) { + /* Nunchuk support */ + if (wiimotes[i]->exp.type == EXP_NUNCHUK) { + /* put nunchuk values in wiimote generic event */ + mid = (*env)->GetMethodID(env, cls, + "addNunchunkEventToPreparedWiimoteEvent", "(SSSFIZFFFFFFFFFSSSFFSSSSSS)V"); + if (mid == 0) { + return; + } + struct nunchuk_t* nc = (nunchuk_t*)&wiimotes[i]->exp.nunchuk; + + (*env)->CallVoidMethod(env, gath, mid, + /* buttons */ + nc->btns,nc->btns_released,nc->btns_held, + /* motion sensing */ + nc->orient_threshold,nc->accel_threshold, + WIIMOTE_IS_FLAG_SET(wiimotes[i],WIIUSE_SMOOTHING),nc->accel_calib.st_alpha, + nc->orient.roll, nc->orient.pitch, nc->orient.yaw, + nc->orient.a_roll, nc->orient.a_pitch, + nc->gforce.x, nc->gforce.y, nc->gforce.z, + nc->accel.x, nc->accel.y, nc->accel.z, + /* joystick */ + nc->js.ang,nc->js.mag, + nc->js.max.x,nc->js.max.y, + nc->js.min.x,nc->js.min.y, + nc->js.center.x,nc->js.center.y); + } + else if (wiimotes[i]->exp.type == EXP_GUITAR_HERO_3) { + /* put guitar hero values in wiimote generic event */ + mid = (*env)->GetMethodID(env, cls, + "addGuitarHeroEventToPreparedWiimoteEvent", "(SSSFFFSSSSSS)V"); + if (mid == 0) { + return; + } + struct guitar_hero_3_t* gh = (guitar_hero_3_t*)&wiimotes[i]->exp.gh3; + + (*env)->CallVoidMethod(env, gath, mid, + /* buttons */ + gh->btns,gh->btns_released,gh->btns_held, + /* whammy bar */ + gh->whammy_bar, + /* joystick */ + gh->js.ang,gh->js.mag, + gh->js.max.x,gh->js.max.y, + gh->js.min.x,gh->js.min.y, + gh->js.center.x,gh->js.center.y); + }if (wiimotes[i]->exp.type == EXP_CLASSIC) { + /* put classic controller values in wiimote generic event */ + mid = (*env)->GetMethodID(env, cls, + "addClassicControllerEventToPreparedWiimoteEvent", "(SSSFFFFSSSSSSFFSSSSSS)V"); + if (mid == 0) { + return; + } + struct classic_ctrl_t* cl = (classic_ctrl_t*)&wiimotes[i]->exp.classic; + + (*env)->CallVoidMethod(env, gath, mid, + /* buttons */ + cl->btns,cl->btns_released,cl->btns_held, + /* shoulder buttons */ + cl->r_shoulder,cl->l_shoulder, + /* joystick left*/ + cl->ljs.ang,cl->ljs.mag, + cl->ljs.max.x,cl->ljs.max.y, + cl->ljs.min.x,cl->ljs.min.y, + cl->ljs.center.x,cl->ljs.center.y, + /* joystick right */ + cl->rjs.ang,cl->rjs.mag, + cl->rjs.max.x,cl->rjs.max.y, + cl->rjs.min.x,cl->rjs.min.y, + cl->rjs.center.x,cl->rjs.center.y); + } + } + + /* add generic event to java object used to gather events in c environment */ + mid = (*env)->GetMethodID(env, cls, "addWiimoteEvent", + "()V"); + if (mid == 0) { + return; + } + (*env)->CallVoidMethod(env, gath, mid); + break; + + case WIIUSE_DISCONNECT: + /* the wiimote disconnected */ + mid = (*env)->GetMethodID(env, cls, "addDisconnectionEvent", "(I)V"); + if (mid == 0) { + return; + } + (*env)->CallVoidMethod(env, gath, mid, wiimotes[i]->unid); + break; + + case WIIUSE_UNEXPECTED_DISCONNECT: + /* the wimote disconnected */ + mid = (*env)->GetMethodID(env, cls, "addDisconnectionEvent", "(I)V"); + if (mid == 0) { + return; + } + (*env)->CallVoidMethod(env, gath, mid, wiimotes[i]->unid); + break; + + case WIIUSE_NUNCHUK_INSERTED: + /* the nunchuk was just connected */ + mid = (*env)->GetMethodID(env, cls, "addNunchukInsertedEvent", "(I)V"); + if (mid == 0) { + return; + } + (*env)->CallVoidMethod(env, gath, mid, wiimotes[i]->unid); + break; + + case WIIUSE_NUNCHUK_REMOVED: + /* the nunchuk disconnected */ + mid = (*env)->GetMethodID(env, cls, "addNunchukRemovedEvent", "(I)V"); + if (mid == 0) { + return; + } + (*env)->CallVoidMethod(env, gath, mid, wiimotes[i]->unid); + break; + + case WIIUSE_GUITAR_HERO_3_CTRL_INSERTED: + /* the guitar hero was just connected */ + mid = (*env)->GetMethodID(env, cls, "addGuitarHeroInsertedEvent", "(I)V"); + if (mid == 0) { + return; + } + (*env)->CallVoidMethod(env, gath, mid, wiimotes[i]->unid); + break; + + case WIIUSE_GUITAR_HERO_3_CTRL_REMOVED: + /* the guitar hero disconnected */ + mid = (*env)->GetMethodID(env, cls, "addGuitarHeroRemovedEvent", "(I)V"); + if (mid == 0) { + return; + } + (*env)->CallVoidMethod(env, gath, mid, wiimotes[i]->unid); + break; + + case WIIUSE_CLASSIC_CTRL_INSERTED: + /* the classic controller was just connected */ + mid = (*env)->GetMethodID(env, cls, "addClassicControllerInsertedEvent", "(I)V"); + if (mid == 0) { + return; + } + (*env)->CallVoidMethod(env, gath, mid, wiimotes[i]->unid); + break; + + case WIIUSE_CLASSIC_CTRL_REMOVED: + /* the classic controller disconnected */ + mid = (*env)->GetMethodID(env, cls, "addClassicControllerRemovedEvent", "(I)V"); + if (mid == 0) { + return; + } + (*env)->CallVoidMethod(env, gath, mid, wiimotes[i]->unid); + break; + + case WIIUSE_STATUS: + /* a status event occured */ + mid = (*env)->GetMethodID(env, cls, "addStatusEvent", "(IZFSZIZZZZ)V"); + if (mid == 0) { + return; + } + /* LEDS */ + if (WIIUSE_IS_LED_SET(wiimotes[i], 1)) leds += 1; + if (WIIUSE_IS_LED_SET(wiimotes[i], 2)) leds += 2; + if (WIIUSE_IS_LED_SET(wiimotes[i], 3)) leds += 4; + if (WIIUSE_IS_LED_SET(wiimotes[i], 4)) leds += 8; + + (*env)->CallVoidMethod(env, gath, mid, + wiimotes[i]->unid, WIIMOTE_IS_SET(wiimotes[i], WIIMOTE_STATE_CONNECTED), + wiimotes[i]->battery_level, leds, WIIUSE_USING_SPEAKER(wiimotes[i]), + wiimotes[i]->exp.type,WIIMOTE_IS_SET(wiimotes[i], WIIMOTE_STATE_RUMBLE), + WIIMOTE_IS_FLAG_SET(wiimotes[i],WIIUSE_CONTINUOUS), + WIIUSE_USING_IR(wiimotes[i]),WIIUSE_USING_ACC(wiimotes[i])); + break; + + default: + break; + } + } + } +} diff --git a/c/wiiusej/wiiusej_WiiUseApi.def b/c/wiiusej/wiiusej_WiiUseApi.def new file mode 100644 index 0000000..e7aebd3 --- /dev/null +++ b/c/wiiusej/wiiusej_WiiUseApi.def @@ -0,0 +1,34 @@ +EXPORTS +Java_wiiusej_WiiUseApi_connect +Java_wiiusej_WiiUseApi_find +Java_wiiusej_WiiUseApi_init +Java_wiiusej_WiiUseApi_closeConnection +Java_wiiusej_WiiUseApi_getUnId +Java_wiiusej_WiiUseApi_cleanUp +Java_wiiusej_WiiUseApi_activateRumble +Java_wiiusej_WiiUseApi_deactivateRumble +Java_wiiusej_WiiUseApi_activateIRTracking +Java_wiiusej_WiiUseApi_deactivateIRTracking +Java_wiiusej_WiiUseApi_activateMotionSensing +Java_wiiusej_WiiUseApi_deactivateMotionSensing +Java_wiiusej_WiiUseApi_setLeds +Java_wiiusej_WiiUseApi_setOrientThreshold +Java_wiiusej_WiiUseApi_setAccelThreshold +Java_wiiusej_WiiUseApi_setAlphaSmoothing +Java_wiiusej_WiiUseApi_reSync +Java_wiiusej_WiiUseApi_activateSmoothing +Java_wiiusej_WiiUseApi_deactivateSmoothing +Java_wiiusej_WiiUseApi_activateContinuous +Java_wiiusej_WiiUseApi_deactivateContinuous +Java_wiiusej_WiiUseApi_setScreenRatio43 +Java_wiiusej_WiiUseApi_setScreenRatio169 +Java_wiiusej_WiiUseApi_setSensorBarAboveScreen +Java_wiiusej_WiiUseApi_setSensorBarBelowScreen +Java_wiiusej_WiiUseApi_setVirtualScreenResolution +Java_wiiusej_WiiUseApi_getStatus +Java_wiiusej_WiiUseApi_setTimeout +Java_wiiusej_WiiUseApi_setIrSensitivity +Java_wiiusej_WiiUseApi_setNunchukOrientationThreshold +Java_wiiusej_WiiUseApi_setNunchukAccelerationThreshold +Java_wiiusej_WiiUseApi_windowsSetBluetoothStack +Java_wiiusej_WiiUseApi_specialPoll diff --git a/c/wiiusej/wiiusej_WiiUseApi.h b/c/wiiusej/wiiusej_WiiUseApi.h new file mode 100644 index 0000000..3680631 --- /dev/null +++ b/c/wiiusej/wiiusej_WiiUseApi.h @@ -0,0 +1,277 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class wiiusej_WiiUseApi */ + +#ifndef _Included_wiiusej_WiiUseApi +#define _Included_wiiusej_WiiUseApi +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: wiiusej_WiiUseApi + * Method: connect + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_wiiusej_WiiUseApi_connect + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: find + * Signature: (II)I + */ +JNIEXPORT jint JNICALL Java_wiiusej_WiiUseApi_find + (JNIEnv *, jobject, jint, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: init + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_init + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: closeConnection + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_closeConnection + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: getUnId + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_wiiusej_WiiUseApi_getUnId + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: cleanUp + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_cleanUp + (JNIEnv *, jobject); + +/* + * Class: wiiusej_WiiUseApi + * Method: activateRumble + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_activateRumble + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: deactivateRumble + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_deactivateRumble + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: activateIRTracking + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_activateIRTracking + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: deactivateIRTracking + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_deactivateIRTracking + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: activateMotionSensing + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_activateMotionSensing + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: deactivateMotionSensing + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_deactivateMotionSensing + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: setLeds + * Signature: (IZZZZ)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setLeds + (JNIEnv *, jobject, jint, jboolean, jboolean, jboolean, jboolean); + +/* + * Class: wiiusej_WiiUseApi + * Method: setOrientThreshold + * Signature: (IF)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setOrientThreshold + (JNIEnv *, jobject, jint, jfloat); + +/* + * Class: wiiusej_WiiUseApi + * Method: setAccelThreshold + * Signature: (II)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setAccelThreshold + (JNIEnv *, jobject, jint, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: setAlphaSmoothing + * Signature: (IF)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setAlphaSmoothing + (JNIEnv *, jobject, jint, jfloat); + +/* + * Class: wiiusej_WiiUseApi + * Method: reSync + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_reSync + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: activateSmoothing + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_activateSmoothing + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: deactivateSmoothing + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_deactivateSmoothing + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: activateContinuous + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_activateContinuous + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: deactivateContinuous + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_deactivateContinuous + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: setScreenRatio43 + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setScreenRatio43 + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: setScreenRatio169 + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setScreenRatio169 + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: setSensorBarAboveScreen + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setSensorBarAboveScreen + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: setSensorBarBelowScreen + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setSensorBarBelowScreen + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: setVirtualScreenResolution + * Signature: (III)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setVirtualScreenResolution + (JNIEnv *, jobject, jint, jint, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: getStatus + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_getStatus + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: setTimeout + * Signature: (ISS)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setTimeout + (JNIEnv *, jobject, jint, jshort, jshort); + +/* + * Class: wiiusej_WiiUseApi + * Method: setIrSensitivity + * Signature: (II)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setIrSensitivity + (JNIEnv *, jobject, jint, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: setNunchukOrientationThreshold + * Signature: (IF)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setNunchukOrientationThreshold + (JNIEnv *, jobject, jint, jfloat); + +/* + * Class: wiiusej_WiiUseApi + * Method: setNunchukAccelerationThreshold + * Signature: (II)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_setNunchukAccelerationThreshold + (JNIEnv *, jobject, jint, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: windowsSetBluetoothStack + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_windowsSetBluetoothStack + (JNIEnv *, jobject, jint); + +/* + * Class: wiiusej_WiiUseApi + * Method: specialPoll + * Signature: (Lwiiusej/wiiusejevents/utils/EventsGatherer;)V + */ +JNIEXPORT void JNICALL Java_wiiusej_WiiUseApi_specialPoll + (JNIEnv *, jobject, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/java/src/com/melloware/jintellitype/HotkeyListener.java b/java/src/com/melloware/jintellitype/HotkeyListener.java new file mode 100644 index 0000000..c7bef85 --- /dev/null +++ b/java/src/com/melloware/jintellitype/HotkeyListener.java @@ -0,0 +1,46 @@ +/** + * JIntellitype + * ----------------- + * Copyright 2005-2008 Emil A. Lefkof III, Melloware Inc. + * + * I always give it my best shot to make a program useful and solid, but + * remeber that there is absolutely no warranty for using this program as + * stated in the following terms: + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.melloware.jintellitype; + + +/** + * Listener interface for Windows Hotkey events registered using the + * Windows API call RegisterHotKey to globally listen for a key combination + * regardless if your application has focus or not. + *

+ * Copyright (c) 1999-2008 + * Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.3.1 + * + * @see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/registerhotkey.asp + */ +public interface HotkeyListener +{ + /** + * Event fired when a WM_HOTKEY message is received that was initiated + * by this application. + *

+ * @param identifier the unique Identifer the Hotkey was assigned + */ + void onHotKey( int identifier ); +} \ No newline at end of file diff --git a/java/src/com/melloware/jintellitype/IntellitypeListener.java b/java/src/com/melloware/jintellitype/IntellitypeListener.java new file mode 100644 index 0000000..4fa5ede --- /dev/null +++ b/java/src/com/melloware/jintellitype/IntellitypeListener.java @@ -0,0 +1,51 @@ +/** + * JIntellitype + * ----------------- + * Copyright 2005-2008 Emil A. Lefkof III, Melloware Inc. + * + * I always give it my best shot to make a program useful and solid, but + * remeber that there is absolutely no warranty for using this program as + * stated in the following terms: + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.melloware.jintellitype; + + +/** + * Listener interface for Windows Intellitype events. Intellitype are Windows + * App Commands that are specialand were introduced with Microsoft Keyboards + * that had special keys for Play, Pause, Stop, Next etc for controlling + * Media applications like Windows Media Player, Itunes, and Winamp. + *

+ * If you have ever wanted your Swing/SWT application to respond to these global + * events you now can with JIntellitype. Just implement this interface and + * you can now take action when those special Media keys are pressed. + *

+ * Copyright (c) 1999-2008 + * Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.3.1 + * + * @see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputmessages/wm_appcommand.asp + */ +public interface IntellitypeListener +{ + /** + * Event fired when a WM_APPCOMMAND message is received that was initiated + * by this application. + *

+ * @param command the WM_APPCOMMAND that was pressed + */ + void onIntellitype( int command ); +} \ No newline at end of file diff --git a/java/src/com/melloware/jintellitype/JIntellitype.java b/java/src/com/melloware/jintellitype/JIntellitype.java new file mode 100644 index 0000000..afc40b7 --- /dev/null +++ b/java/src/com/melloware/jintellitype/JIntellitype.java @@ -0,0 +1,665 @@ +/** + * JIntellitype ----------------- Copyright 2005-2008 Emil A. Lefkof III, + * Melloware Inc. I always give it my best shot to make a program useful and + * solid, but remeber that there is absolutely no warranty for using this + * program as stated in the following terms: Licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law + * or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +package com.melloware.jintellitype; + +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import javax.swing.SwingUtilities; + +/** + * JIntellitype A Java Implementation for using the Windows API Intellitype + * commands and the RegisterHotKey and UnRegisterHotkey API calls for globally + * responding to key events. Intellitype are commands that are using for Play, + * Stop, Next on Media keyboards or some laptops that have those special keys. + *

+ * JIntellitype class that is used to call Windows API calls using the + * JIntellitype.dll. + *

+ * This file comes with native code in JINTELLITYPE.DLL The DLL should go in + * C:/WINDOWS/SYSTEM or in your current directory + *

+ *

+ * Copyright (c) 1999-2008 Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.3.1 + */ +public final class JIntellitype implements JIntellitypeConstants { + + /** + * Static variable to hold singleton. + */ + private static JIntellitype jintellitype = null; + + /** + * Static variable for double checked thread safety. + */ + private static boolean isInitialized = false; + + /** + * Static variable to hold the libary location if set + */ + private static String libraryLocation = null; + + /** + * Listeners collection for Hotkey events + */ + private final List hotkeyListeners = Collections + .synchronizedList(new CopyOnWriteArrayList()); + + /** + * Listeners collection for Hotkey events + */ + private final List intellitypeListeners = Collections + .synchronizedList(new CopyOnWriteArrayList()); + + /** + * Handler is used by JNI code to keep different JVM instances separate + */ + @SuppressWarnings("unused") + private final int handler = 0; + + /** + * Map containing key->keycode mapping + * @see #registerHotKey(int, String) + * @see #getKey2KeycodeMapping() + */ + private final HashMap keycodeMap; + + /** + * Private Constructor to prevent instantiation. Initialize the library for + * calling. + */ + private JIntellitype() { + try { + // Load JNI library + System.loadLibrary("JIntellitype"); + } catch (Throwable ex) { + try { + if (getLibraryLocation() != null) { + System.load(getLibraryLocation()); + } else { + String jarPath = "com/melloware/jintellitype/"; + String tmpDir = System.getProperty("java.io.tmpdir"); + try { + String dll = "JIntellitype.dll"; + fromJarToFs(jarPath + dll, tmpDir + dll); + System.load(tmpDir + dll); + } catch (UnsatisfiedLinkError e) { + String dll = "JIntellitype64.dll"; + fromJarToFs(jarPath + dll, tmpDir + dll); + System.load(tmpDir + dll); + } + } + } catch (Throwable ex2) { + throw new JIntellitypeException( + "Could not load JIntellitype.dll from local file system or from inside JAR", ex2); + } + } + + initializeLibrary(); + this.keycodeMap = getKey2KeycodeMapping(); + } + + /** + * Pulls a file out of the JAR and puts it on the File Path. + *

+ * @param jarPath the path to the JAR + * @param filePath the file path to extract to + * @throws IOException if any IO error occurs + */ + private void fromJarToFs(String jarPath, String filePath) throws IOException { + File file = new File(filePath); + if (file.exists()) { + boolean success = file.delete(); + if (!success) { + throw new IOException("couldn't delete " + filePath); + } + } + InputStream is = null; + OutputStream os = null; + try { + is = ClassLoader.getSystemClassLoader().getResourceAsStream(jarPath); + os = new FileOutputStream(filePath); + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) { + os.write(buffer, 0, bytesRead); + } + } finally { + if (is != null) { + is.close(); + } + if (os != null) { + os.close(); + } + } + } + + /** + * Gets the singleton instance of the JIntellitype object. + *

+ * But the possibility of creation of more instance is only before the + * instance is created. Since all code defined inside getInstance method is + * in the synchronized block, even the subsequent requests will also come and + * wait in the synchronized block. This is a performance issue. The same can + * be solved using double-checked lock. Following is the implementation of + * Singleton with lazy initialization and double-checked lock. + *

+ * @return an instance of JIntellitype class + */ + public static JIntellitype getInstance() { + if (!isInitialized) { + synchronized (JIntellitype.class) { + if (!isInitialized) { + jintellitype = new JIntellitype(); + isInitialized = true; + } + } + } + return jintellitype; + } + + /** + * Adds a listener for hotkeys. + *

+ * @param listener the HotKeyListener to be added + */ + public void addHotKeyListener(HotkeyListener listener) { + hotkeyListeners.add(listener); + } + + /** + * Adds a listener for intellitype commands. + *

+ * @param listener the IntellitypeListener to be added + */ + public void addIntellitypeListener(IntellitypeListener listener) { + intellitypeListeners.add(listener); + } + + /** + * Cleans up all resources used by JIntellitype. + */ + public void cleanUp() { + try { + terminate(); + } catch (UnsatisfiedLinkError ex) { + throw new JIntellitypeException(ERROR_MESSAGE, ex); + } catch (RuntimeException ex) { + throw new JIntellitypeException(ex); + } + } + + /** + * Registers a Hotkey with windows. This combination will be responded to by + * all registered HotKeyListeners. Uses the JIntellitypeConstants for MOD, + * ALT, CTRL, and WINDOWS keys. + *

+ * @param identifier a unique identifier for this key combination + * @param modifier MOD_SHIFT, MOD_ALT, MOD_CONTROL, MOD_WIN from + * JIntellitypeConstants, or 0 if no modifier needed + * @param keycode the key to respond to in Ascii integer, 65 for A + */ + public void registerHotKey(int identifier, int modifier, int keycode) { + try { + int modifiers = swingToIntelliType(modifier); + if (modifiers == 0) { + modifiers = modifier; + } + regHotKey(identifier, modifier, keycode); + } catch (UnsatisfiedLinkError ex) { + throw new JIntellitypeException(ERROR_MESSAGE, ex); + } catch (RuntimeException ex) { + throw new JIntellitypeException(ex); + } + } + + /** + * Registers a Hotkey with windows. This combination will be responded to by + * all registered HotKeyListeners. Use the Swing InputEvent constants from + * java.awt.InputEvent. + *

+ * @param identifier a unique identifier for this key combination + * @param modifier InputEvent.SHIFT_MASK, InputEvent.ALT_MASK, + * InputEvent.CTRL_MASK, or 0 if no modifier needed + * @param keycode the key to respond to in Ascii integer, 65 for A + */ + public void registerSwingHotKey(int identifier, int modifier, int keycode) { + try { + regHotKey(identifier, swingToIntelliType(modifier), keycode); + } catch (UnsatisfiedLinkError ex) { + throw new JIntellitypeException(ERROR_MESSAGE, ex); + } catch (RuntimeException ex) { + throw new JIntellitypeException(ex); + } + } + + /** + * Registers a Hotkey with windows. This combination will be responded to by + * all registered HotKeyListeners. Use the identifiers CTRL, SHIFT, ALT + * and/or WIN. + *

+ * @param identifier a unique identifier for this key combination + * @param modifierAndKeyCode String with modifiers separated by + and keycode + * (e.g. CTRL+SHIFT+A) + * @see #registerHotKey(int, int, int) + * @see #registerSwingHotKey(int, int, int) + */ + public void registerHotKey(int identifier, String modifierAndKeyCode) { + String[] split = modifierAndKeyCode.split("\\+"); + int mask = 0; + int keycode = 0; + + for (int i = 0; i < split.length; i++) { + if ("ALT".equalsIgnoreCase(split[i])) { + mask += JIntellitype.MOD_ALT; + } else if ("CTRL".equalsIgnoreCase(split[i]) || "CONTROL".equalsIgnoreCase(split[i])) { + mask += JIntellitype.MOD_CONTROL; + } else if ("SHIFT".equalsIgnoreCase(split[i])) { + mask += JIntellitype.MOD_SHIFT; + } else if ("WIN".equalsIgnoreCase(split[i])) { + mask += JIntellitype.MOD_WIN; + } else if (keycodeMap.containsKey(split[i].toLowerCase())) { + keycode = keycodeMap.get(split[i].toLowerCase()); + } + } + registerHotKey(identifier, mask, keycode); + } + + /** + * Removes a listener for hotkeys. + */ + public void removeHotKeyListener(HotkeyListener listener) { + hotkeyListeners.remove(listener); + } + + /** + * Removes a listener for intellitype commands. + */ + public void removeIntellitypeListener(IntellitypeListener listener) { + intellitypeListeners.remove(listener); + } + + /** + * Unregisters a previously registered Hotkey identified by its unique + * identifier. + *

+ * @param identifier the unique identifer of this Hotkey + */ + public void unregisterHotKey(int identifier) { + try { + unregHotKey(identifier); + } catch (UnsatisfiedLinkError ex) { + throw new JIntellitypeException(ERROR_MESSAGE, ex); + } catch (RuntimeException ex) { + throw new JIntellitypeException(ex); + } + } + + /** + * Checks to see if this application is already running. + *

+ * @param appTitle the name of the application to check for + * @return true if running, false if not running + */ + public static boolean checkInstanceAlreadyRunning(String appTitle) { + return getInstance().isRunning(appTitle); + } + + /** + * Checks to make sure the OS is a Windows flavor and that the JIntellitype + * DLL is found in the path and the JDK is 32 bit not 64 bit. The DLL + * currently only supports 32 bit JDK. + *

+ * @return true if Jintellitype may be used, false if not + */ + public static boolean isJIntellitypeSupported() { + boolean result = false; + String os = "none"; + + try { + os = System.getProperty("os.name").toLowerCase(); + } catch (SecurityException ex) { + // we are not allowed to look at this property + System.err.println("Caught a SecurityException reading the system property " + + "'os.name'; the SystemUtils property value will default to null."); + } + + // only works on Windows OS currently + if (os.startsWith("windows")) { + // try an get the instance and if it succeeds then return true + try { + getInstance(); + result = true; + } catch (Exception e) { + result = false; + } + } + + return result; + } + + /** + * Gets the libraryLocation. + *

+ * @return Returns the libraryLocation. + */ + public static String getLibraryLocation() { + return libraryLocation; + } + + /** + * Sets the libraryLocation. + *

+ * @param libraryLocation The libraryLocation to set. + */ + public static void setLibraryLocation(String libraryLocation) { + final File dll = new File(libraryLocation); + if (!dll.isAbsolute()) { + JIntellitype.libraryLocation = dll.getAbsolutePath(); + } else { + // absolute path, no further calculation needed + JIntellitype.libraryLocation = libraryLocation; + } + } + + /** + * Notifies all listeners that Hotkey was pressed. + *

+ * @param identifier the unique identifier received + */ + protected void onHotKey(final int identifier) { + for (final HotkeyListener hotkeyListener : hotkeyListeners) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + hotkeyListener.onHotKey(identifier); + } + }); + } + } + + /** + * Notifies all listeners that Intellitype command was received. + *

+ * @param command the unique WM_APPCOMMAND received + */ + protected void onIntellitype(final int command) { + for (final IntellitypeListener intellitypeListener : intellitypeListeners) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + intellitypeListener.onIntellitype(command); + } + }); + } + } + + /** + * Swing modifier value to Jintellipad conversion. If no conversion needed + * just return the original value. This lets users pass either the original + * JIntellitype constants or Swing InputEvent constants. + *

+ * @param swingKeystrokeModifier the Swing KeystrokeModifier to check + * @return Jintellitype the JIntellitype modifier value + */ + protected static int swingToIntelliType(int swingKeystrokeModifier) { + int mask = 0; + if ((swingKeystrokeModifier & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK) { + mask += JIntellitype.MOD_SHIFT; + } + if ((swingKeystrokeModifier & InputEvent.ALT_MASK) == InputEvent.ALT_MASK) { + mask += JIntellitype.MOD_ALT; + } + if ((swingKeystrokeModifier & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK) { + mask += JIntellitype.MOD_CONTROL; + } + if ((swingKeystrokeModifier & InputEvent.SHIFT_DOWN_MASK) == InputEvent.SHIFT_DOWN_MASK) { + mask += JIntellitype.MOD_SHIFT; + } + if ((swingKeystrokeModifier & InputEvent.ALT_DOWN_MASK) == InputEvent.ALT_DOWN_MASK) { + mask += JIntellitype.MOD_ALT; + } + if ((swingKeystrokeModifier & InputEvent.CTRL_DOWN_MASK) == InputEvent.CTRL_DOWN_MASK) { + mask += JIntellitype.MOD_CONTROL; + } + return mask; + } + + /** + * Puts all constants from {@link java.awt.event.KeyEvent} in a keycodeMap. + * The key is the lower case form of it. + * @return Map containing key->keycode mapping DOCU Now enables the user to + * use all keys specified here instead of just [A-Z],[0-9] as before + */ + private HashMap getKey2KeycodeMapping() { + HashMap map = new HashMap(); + + map.put("first", KeyEvent.KEY_FIRST); + map.put("last", KeyEvent.KEY_LAST); + map.put("typed", KeyEvent.KEY_TYPED); + map.put("pressed", KeyEvent.KEY_PRESSED); + map.put("released", KeyEvent.KEY_RELEASED); + map.put("enter", 13); + map.put("back_space", KeyEvent.VK_BACK_SPACE); + map.put("tab", KeyEvent.VK_TAB); + map.put("cancel", KeyEvent.VK_CANCEL); + map.put("clear", KeyEvent.VK_CLEAR); + map.put("pause", KeyEvent.VK_PAUSE); + map.put("caps_lock", KeyEvent.VK_CAPS_LOCK); + map.put("escape", KeyEvent.VK_ESCAPE); + map.put("space", KeyEvent.VK_SPACE); + map.put("page_up", KeyEvent.VK_PAGE_UP); + map.put("page_down", KeyEvent.VK_PAGE_DOWN); + map.put("end", KeyEvent.VK_END); + map.put("home", KeyEvent.VK_HOME); + map.put("left", KeyEvent.VK_LEFT); + map.put("up", KeyEvent.VK_UP); + map.put("right", KeyEvent.VK_RIGHT); + map.put("down", KeyEvent.VK_DOWN); + map.put("comma", 188); + map.put("minus", 109); + map.put("period", 110); + map.put("slash", 191); + map.put("0", KeyEvent.VK_0); + map.put("1", KeyEvent.VK_1); + map.put("2", KeyEvent.VK_2); + map.put("3", KeyEvent.VK_3); + map.put("4", KeyEvent.VK_4); + map.put("5", KeyEvent.VK_5); + map.put("6", KeyEvent.VK_6); + map.put("7", KeyEvent.VK_7); + map.put("8", KeyEvent.VK_8); + map.put("9", KeyEvent.VK_9); + map.put("semicolon", 186); + map.put("equals", 187); + map.put("a", KeyEvent.VK_A); + map.put("b", KeyEvent.VK_B); + map.put("c", KeyEvent.VK_C); + map.put("d", KeyEvent.VK_D); + map.put("e", KeyEvent.VK_E); + map.put("f", KeyEvent.VK_F); + map.put("g", KeyEvent.VK_G); + map.put("h", KeyEvent.VK_H); + map.put("i", KeyEvent.VK_I); + map.put("j", KeyEvent.VK_J); + map.put("k", KeyEvent.VK_K); + map.put("l", KeyEvent.VK_L); + map.put("m", KeyEvent.VK_M); + map.put("n", KeyEvent.VK_N); + map.put("o", KeyEvent.VK_O); + map.put("p", KeyEvent.VK_P); + map.put("q", KeyEvent.VK_Q); + map.put("r", KeyEvent.VK_R); + map.put("s", KeyEvent.VK_S); + map.put("t", KeyEvent.VK_T); + map.put("u", KeyEvent.VK_U); + map.put("v", KeyEvent.VK_V); + map.put("w", KeyEvent.VK_W); + map.put("x", KeyEvent.VK_X); + map.put("y", KeyEvent.VK_Y); + map.put("z", KeyEvent.VK_Z); + map.put("open_bracket", 219); + map.put("back_slash", 220); + map.put("close_bracket", 221); + map.put("numpad0", KeyEvent.VK_NUMPAD0); + map.put("numpad1", KeyEvent.VK_NUMPAD1); + map.put("numpad2", KeyEvent.VK_NUMPAD2); + map.put("numpad3", KeyEvent.VK_NUMPAD3); + map.put("numpad4", KeyEvent.VK_NUMPAD4); + map.put("numpad5", KeyEvent.VK_NUMPAD5); + map.put("numpad6", KeyEvent.VK_NUMPAD6); + map.put("numpad7", KeyEvent.VK_NUMPAD7); + map.put("numpad8", KeyEvent.VK_NUMPAD8); + map.put("numpad9", KeyEvent.VK_NUMPAD9); + map.put("multiply", KeyEvent.VK_MULTIPLY); + map.put("add", KeyEvent.VK_ADD); + map.put("separator", KeyEvent.VK_SEPARATOR); + map.put("subtract", KeyEvent.VK_SUBTRACT); + map.put("decimal", KeyEvent.VK_DECIMAL); + map.put("divide", KeyEvent.VK_DIVIDE); + map.put("delete", 46); + map.put("num_lock", KeyEvent.VK_NUM_LOCK); + map.put("scroll_lock", KeyEvent.VK_SCROLL_LOCK); + map.put("f1", KeyEvent.VK_F1); + map.put("f2", KeyEvent.VK_F2); + map.put("f3", KeyEvent.VK_F3); + map.put("f4", KeyEvent.VK_F4); + map.put("f5", KeyEvent.VK_F5); + map.put("f6", KeyEvent.VK_F6); + map.put("f7", KeyEvent.VK_F7); + map.put("f8", KeyEvent.VK_F8); + map.put("f9", KeyEvent.VK_F9); + map.put("f10", KeyEvent.VK_F10); + map.put("f11", KeyEvent.VK_F11); + map.put("f12", KeyEvent.VK_F12); + map.put("f13", KeyEvent.VK_F13); + map.put("f14", KeyEvent.VK_F14); + map.put("f15", KeyEvent.VK_F15); + map.put("f16", KeyEvent.VK_F16); + map.put("f17", KeyEvent.VK_F17); + map.put("f18", KeyEvent.VK_F18); + map.put("f19", KeyEvent.VK_F19); + map.put("f20", KeyEvent.VK_F20); + map.put("f21", KeyEvent.VK_F21); + map.put("f22", KeyEvent.VK_F22); + map.put("f23", KeyEvent.VK_F23); + map.put("f24", KeyEvent.VK_F24); + map.put("printscreen", 44); + map.put("insert", 45); + map.put("help", 47); + map.put("meta", KeyEvent.VK_META); + map.put("back_quote", KeyEvent.VK_BACK_QUOTE); + map.put("quote", KeyEvent.VK_QUOTE); + map.put("kp_up", KeyEvent.VK_KP_UP); + map.put("kp_down", KeyEvent.VK_KP_DOWN); + map.put("kp_left", KeyEvent.VK_KP_LEFT); + map.put("kp_right", KeyEvent.VK_KP_RIGHT); + map.put("dead_grave", KeyEvent.VK_DEAD_GRAVE); + map.put("dead_acute", KeyEvent.VK_DEAD_ACUTE); + map.put("dead_circumflex", KeyEvent.VK_DEAD_CIRCUMFLEX); + map.put("dead_tilde", KeyEvent.VK_DEAD_TILDE); + map.put("dead_macron", KeyEvent.VK_DEAD_MACRON); + map.put("dead_breve", KeyEvent.VK_DEAD_BREVE); + map.put("dead_abovedot", KeyEvent.VK_DEAD_ABOVEDOT); + map.put("dead_diaeresis", KeyEvent.VK_DEAD_DIAERESIS); + map.put("dead_abovering", KeyEvent.VK_DEAD_ABOVERING); + map.put("dead_doubleacute", KeyEvent.VK_DEAD_DOUBLEACUTE); + map.put("dead_caron", KeyEvent.VK_DEAD_CARON); + map.put("dead_cedilla", KeyEvent.VK_DEAD_CEDILLA); + map.put("dead_ogonek", KeyEvent.VK_DEAD_OGONEK); + map.put("dead_iota", KeyEvent.VK_DEAD_IOTA); + map.put("dead_voiced_sound", KeyEvent.VK_DEAD_VOICED_SOUND); + map.put("dead_semivoiced_sound", KeyEvent.VK_DEAD_SEMIVOICED_SOUND); + map.put("ampersand", KeyEvent.VK_AMPERSAND); + map.put("asterisk", KeyEvent.VK_ASTERISK); + map.put("quotedbl", KeyEvent.VK_QUOTEDBL); + map.put("less", KeyEvent.VK_LESS); + map.put("greater", KeyEvent.VK_GREATER); + map.put("braceleft", KeyEvent.VK_BRACELEFT); + map.put("braceright", KeyEvent.VK_BRACERIGHT); + map.put("at", KeyEvent.VK_AT); + map.put("colon", KeyEvent.VK_COLON); + map.put("circumflex", KeyEvent.VK_CIRCUMFLEX); + map.put("dollar", KeyEvent.VK_DOLLAR); + map.put("euro_sign", KeyEvent.VK_EURO_SIGN); + map.put("exclamation_mark", KeyEvent.VK_EXCLAMATION_MARK); + map.put("inverted_exclamation_mark", KeyEvent.VK_INVERTED_EXCLAMATION_MARK); + map.put("left_parenthesis", KeyEvent.VK_LEFT_PARENTHESIS); + map.put("number_sign", KeyEvent.VK_NUMBER_SIGN); + map.put("plus", KeyEvent.VK_PLUS); + map.put("right_parenthesis", KeyEvent.VK_RIGHT_PARENTHESIS); + map.put("underscore", KeyEvent.VK_UNDERSCORE); + map.put("context_menu", KeyEvent.VK_CONTEXT_MENU); + map.put("final", KeyEvent.VK_FINAL); + map.put("convert", KeyEvent.VK_CONVERT); + map.put("nonconvert", KeyEvent.VK_NONCONVERT); + map.put("accept", KeyEvent.VK_ACCEPT); + map.put("modechange", KeyEvent.VK_MODECHANGE); + map.put("kana", KeyEvent.VK_KANA); + map.put("kanji", KeyEvent.VK_KANJI); + map.put("alphanumeric", KeyEvent.VK_ALPHANUMERIC); + map.put("katakana", KeyEvent.VK_KATAKANA); + map.put("hiragana", KeyEvent.VK_HIRAGANA); + map.put("full_width", KeyEvent.VK_FULL_WIDTH); + map.put("half_width", KeyEvent.VK_HALF_WIDTH); + map.put("roman_characters", KeyEvent.VK_ROMAN_CHARACTERS); + map.put("all_candidates", KeyEvent.VK_ALL_CANDIDATES); + map.put("previous_candidate", KeyEvent.VK_PREVIOUS_CANDIDATE); + map.put("code_input", KeyEvent.VK_CODE_INPUT); + map.put("japanese_katakana", KeyEvent.VK_JAPANESE_KATAKANA); + map.put("japanese_hiragana", KeyEvent.VK_JAPANESE_HIRAGANA); + map.put("japanese_roman", KeyEvent.VK_JAPANESE_ROMAN); + map.put("kana_lock", KeyEvent.VK_KANA_LOCK); + map.put("input_method_on_off", KeyEvent.VK_INPUT_METHOD_ON_OFF); + map.put("cut", KeyEvent.VK_CUT); + map.put("copy", KeyEvent.VK_COPY); + map.put("paste", KeyEvent.VK_PASTE); + map.put("undo", KeyEvent.VK_UNDO); + map.put("again", KeyEvent.VK_AGAIN); + map.put("find", KeyEvent.VK_FIND); + map.put("props", KeyEvent.VK_PROPS); + map.put("stop", KeyEvent.VK_STOP); + map.put("compose", KeyEvent.VK_COMPOSE); + map.put("alt_graph", KeyEvent.VK_ALT_GRAPH); + map.put("begin", KeyEvent.VK_BEGIN); + + return map; + } + + private synchronized native void initializeLibrary() throws UnsatisfiedLinkError; + + private synchronized native void regHotKey(int identifier, int modifier, int keycode) throws UnsatisfiedLinkError; + + private synchronized native void terminate() throws UnsatisfiedLinkError; + + private synchronized native void unregHotKey(int identifier) throws UnsatisfiedLinkError; + + /** + * Checks if there's an instance with hidden window title = appName running + * Can be used to detect that another instance of your app is already running + * (so exit..) + *

+ * @param appName = the title of the hidden window to search for + */ + private synchronized native boolean isRunning(String appName); +} \ No newline at end of file diff --git a/java/src/com/melloware/jintellitype/JIntellitypeConstants.java b/java/src/com/melloware/jintellitype/JIntellitypeConstants.java new file mode 100644 index 0000000..d2bb3f6 --- /dev/null +++ b/java/src/com/melloware/jintellitype/JIntellitypeConstants.java @@ -0,0 +1,182 @@ +/** + * JIntellitype + * ----------------- + * Copyright 2005-2008 Emil A. Lefkof III, Melloware Inc. + * + * I always give it my best shot to make a program useful and solid, but + * remeber that there is absolutely no warranty for using this program as + * stated in the following terms: + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.melloware.jintellitype; + +/** + * Constants from the Windows API used in JIntellitype. + *

+ * Message information can be found on MSDN here: + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputmessages/wm_appcommand.asp + *

+ * Copyright (c) 1999-2008 + * Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.3.1 + */ +public interface JIntellitypeConstants { + + public static final String ERROR_MESSAGE = "JIntellitype DLL Error"; + + // Modifier keys, can be added together + + /** + * ALT key for registering Hotkeys. + */ + public static final int MOD_ALT = 1; + + /** + * CONTROL key for registering Hotkeys. + */ + public static final int MOD_CONTROL = 2; + + /** + * SHIFT key for registering Hotkeys. + */ + public static final int MOD_SHIFT = 4; + + /** + * WINDOWS key for registering Hotkeys. + */ + public static final int MOD_WIN = 8; + + + // Intellitype Virtual Key Constants from MSDN + + /** + * Browser Navigate backward + */ + public static final int APPCOMMAND_BROWSER_BACKWARD = 1; + + /** + * Browser Navigate forward + */ + public static final int APPCOMMAND_BROWSER_FORWARD = 2; + + /** + * Browser Refresh page + */ + public static final int APPCOMMAND_BROWSER_REFRESH = 3; + + /** + * Browser Stop download + */ + public static final int APPCOMMAND_BROWSER_STOP = 4; + + /** + * Browser Open search + */ + public static final int APPCOMMAND_BROWSER_SEARCH = 5; + + /** + * Browser Open favorites + */ + public static final int APPCOMMAND_BROWSER_FAVOURITES = 6; + + /** + * Browser Navigate home + */ + public static final int APPCOMMAND_BROWSER_HOME = 7; + + /** + * Mute the volume + */ + public static final int APPCOMMAND_VOLUME_MUTE = 8; + + /** + * Lower the volume + */ + public static final int APPCOMMAND_VOLUME_DOWN = 9; + + /** + * Raise the volume + */ + public static final int APPCOMMAND_VOLUME_UP = 10; + + /** + * Media application go to next track. + */ + public static final int APPCOMMAND_MEDIA_NEXTTRACK = 11; + + /** + * Media application Go to previous track. + */ + public static final int APPCOMMAND_MEDIA_PREVIOUSTRACK = 12; + + /** + * Media application Stop playback. + */ + public static final int APPCOMMAND_MEDIA_STOP = 13; + + /** + * Media application Play or pause playback. + */ + public static final int APPCOMMAND_MEDIA_PLAY_PAUSE = 14; + + /** + * Open mail application + */ + public static final int APPCOMMAND_LAUNCH_MAIL = 15; + + /** + * Go to Media Select mode. + */ + public static final int APPCOMMAND_LAUNCH_MEDIA_SELECT = 16; + + /** + * Start App1. + */ + public static final int APPCOMMAND_LAUNCH_APP1 = 17; + + /** + * Start App2. + */ + public static final int APPCOMMAND_LAUNCH_APP2 = 18; + + public static final int APPCOMMAND_BASS_DOWN = 19; + public static final int APPCOMMAND_BASS_BOOST = 20; + public static final int APPCOMMAND_BASS_UP = 21; + public static final int APPCOMMAND_TREBLE_DOWN = 22; + public static final int APPCOMMAND_TREBLE_UP = 23; + public static final int APPCOMMAND_MICROPHONE_VOLUME_MUTE = 24; + public static final int APPCOMMAND_MICROPHONE_VOLUME_DOWN = 25; + public static final int APPCOMMAND_MICROPHONE_VOLUME_UP = 26; + public static final int APPCOMMAND_HELP = 27; + public static final int APPCOMMAND_FIND = 28; + public static final int APPCOMMAND_NEW = 29; + public static final int APPCOMMAND_OPEN = 30; + public static final int APPCOMMAND_CLOSE = 31; + public static final int APPCOMMAND_SAVE = 32; + public static final int APPCOMMAND_PRINT = 33; + public static final int APPCOMMAND_UNDO = 34; + public static final int APPCOMMAND_REDO = 35; + public static final int APPCOMMAND_COPY = 36; + public static final int APPCOMMAND_CUT = 37; + public static final int APPCOMMAND_PASTE = 38; + public static final int APPCOMMAND_REPLY_TO_MAIL = 39; + public static final int APPCOMMAND_FORWARD_MAIL = 40; + public static final int APPCOMMAND_SEND_MAIL = 41; + public static final int APPCOMMAND_SPELL_CHECK = 42; + public static final int APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE = 43; + public static final int APPCOMMAND_MIC_ON_OFF_TOGGLE = 44; + public static final int APPCOMMAND_CORRECTION_LIST = 45; + +} diff --git a/java/src/com/melloware/jintellitype/JIntellitypeException.java b/java/src/com/melloware/jintellitype/JIntellitypeException.java new file mode 100644 index 0000000..a4fa36b --- /dev/null +++ b/java/src/com/melloware/jintellitype/JIntellitypeException.java @@ -0,0 +1,55 @@ +/** + * JIntellitype + * ----------------- + * Copyright 2005-2008 Emil A. Lefkof III, Melloware Inc. + * + * I always give it my best shot to make a program useful and solid, but + * remeber that there is absolutely no warranty for using this program as + * stated in the following terms: + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.melloware.jintellitype; + + +/** + * Exception class for all JIntellitype Exceptions. + *

+ * Copyright (c) 1999-2008 + * Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.3.1 + */ +public class JIntellitypeException extends RuntimeException { + + + public JIntellitypeException() { + super(); + } + + + public JIntellitypeException(String aMessage, Throwable aCause) { + super(aMessage, aCause); + } + + + public JIntellitypeException(String aMessage) { + super(aMessage); + } + + + public JIntellitypeException(Throwable aCause) { + super(aCause); + } + +} diff --git a/java/src/com/melloware/jintellitype/Main.java b/java/src/com/melloware/jintellitype/Main.java new file mode 100644 index 0000000..b579745 --- /dev/null +++ b/java/src/com/melloware/jintellitype/Main.java @@ -0,0 +1,80 @@ +/** + * JIntellitype + * ----------------- + * Copyright 2005-2008 Emil A. Lefkof III, Melloware Inc. + * + * I always give it my best shot to make a program useful and solid, but + * remeber that there is absolutely no warranty for using this program as + * stated in the following terms: + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.melloware.jintellitype; + +import java.util.Properties; + +/** + * Simple executable class that is used as the Main-Class in the JIntellitype + * jar. Outputs version information and other information about the environment + * on which the jar is being executed. + *

+ * Copyright (c) 1999-2008 + * Melloware, Inc. + * @author Emil A. Lefkof III + * @version 1.3.1 + */ +@SuppressWarnings("") +public final class Main { + + /** + * Private constructor to make sure this class is never instantiated. + * + */ + private Main() { + // private constructor to make singleton. + } + + /** Main method that does what the class level javadoc states. */ + public static void main(String[] argv) { + System.out.println("JIntellitype version \"" + getProjectVersion() + "\""); + System.out.println(" "); + + System.out.println("Running on java version \"" + System.getProperty("java.version") + "\"" + + " (build " + System.getProperty("java.runtime.version") + ")" + + " from " + System.getProperty("java.vendor")); + + System.out.println("Operating environment \"" + System.getProperty("os.name") + "\"" + + " version " + System.getProperty("os.version") + " on " + System.getProperty("os.arch")); + + System.out.println("For more information on JIntellitype please visit http://www.melloware.com"); + } + + /** + * Attempts to read the version number out of the pom.properties. If not found + * then RUNNING.IN.IDE.FULL is returned as the version. + *

+ * @return the full version number of this application + */ + private static String getProjectVersion() { + String version; + + try { + final Properties pomProperties = new Properties(); + pomProperties.load(Main.class.getResourceAsStream("/META-INF/maven/com.melloware/jintellitype/pom.properties")); + version = pomProperties.getProperty("version"); + } catch (Exception e) { + version = "RUNNING.IN.IDE.FULL"; + } + return version; + } +} \ No newline at end of file diff --git a/java/src/wiiusej/WiiUseApi.java b/java/src/wiiusej/WiiUseApi.java new file mode 100644 index 0000000..428f522 --- /dev/null +++ b/java/src/wiiusej/WiiUseApi.java @@ -0,0 +1,351 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej; + +import wiiusej.wiiusejevents.utils.EventsGatherer; + +/** + * Singleton used to manipulate WiiUse Api. + * + * @author guiguito + */ +public class WiiUseApi { + + static { + System.loadLibrary("WiiuseJ"); + } + + private static WiiUseApi instance = new WiiUseApi(); + + /** + * Get the only instance of WiiUseApi. + * + * @return the only instace of WiiUseApi. + */ + protected static WiiUseApi getInstance() { + return instance; + } + + /** + * Connect to a wiimote or wiimotes once an address is known. + * + * @param nbWiimotes + * The number of wiimotes. + * @return The number of wiimotes that successfully connected. + */ + synchronized native int connect(int nbWiimotes); + + /** + * Find a wiimote or wiimotes. + * + * @param nbMaxWiimotes + * The number of wiimotes. + * @param timeout + * The number of seconds before the search times out. + * @return The number of wiimotes found. + */ + synchronized native int find(int nbMaxWiimotes, int timeout); + + /** + * Initialize an array of wiimote structures (for the C side of the + * library). + * + * @param nbPossibleWiimotes + * size of the array. + */ + synchronized native void init(int nbPossibleWiimotes); + + /** + * Close connection to the wiimote with the given id. + * + */ + synchronized native void closeConnection(int id); + + /** + * Get unique id of a wiimote in the wiimotes array. Please make sure you + * call an existing index with a wiimote initialized at this index, other + * wise you'll get a wrong value. + * + * @param index + * index of the wiimote in the wiimotes array. + * @return the unid of the wiimote, or a wrong value if the index was false. + * + */ + synchronized native int getUnId(int index); + + /** + * CleanUp Wiiuse API. + */ + synchronized native void cleanUp(); + + /** + * Activate rumble on the wiimote with the given id. + * + * @param id + * the id of the wiimote. + */ + synchronized native void activateRumble(int id); + + /** + * Deactivate rumble on the wiimote with the given id. + * + * @param id + * the id of the wiimote. + */ + synchronized native void deactivateRumble(int id); + + /** + * Activate IR Tracking on the wiimote with the given id. + * + * @param id + * the id of the wiimote. + */ + synchronized native void activateIRTracking(int id); + + /** + * Deactivate IR Tracking on the wiimote with the given id. + * + * @param id + * the id of the wiimote. + */ + synchronized native void deactivateIRTracking(int id); + + /** + * Activate motion sensing on the wiimote with the given id. + * + * @param id + * the id of the wiimote. + */ + synchronized native void activateMotionSensing(int id); + + /** + * Deactivate motion sensing on the wiimote with the given id. + * + * @param id + * the id of the wiimote. + */ + synchronized native void deactivateMotionSensing(int id); + + /** + * Set wiimote leds status. + * + * @param id + * the id of the wiimote concerned. + * @param led1 + * status of led1: True=ON, False=OFF. + * @param led2 + * status of led2: True=ON, False=OFF. + * @param led3 + * status of led3: True=ON, False=OFF. + * @param led4 + * status of led4: True=ON, False=OFF. + */ + synchronized native void setLeds(int id, boolean led1, boolean led2, + boolean led3, boolean led4); + + /** + * Set how many degrees an angle must change to generate an event. + * + * @param id + * id of the wiimote concerned. + * @param angle + * minimum angle detected by an event. + */ + synchronized native void setOrientThreshold(int id, float angle); + + /** + * Set how much acceleration must change to generate an event. + * + * @param id + * id of the wiimote concerned. + * @param value + * minimum value detected by an event. + */ + synchronized native void setAccelThreshold(int id, int value); + + /** + * Set alpha smoothing parameter for the given id. + * + * @param id + * id of the wiimote concerned. + * @param value + * alpha smoothing value. + */ + synchronized native void setAlphaSmoothing(int id, float value); + + /** + * Try to resync with the wiimote by starting a new handshake. + * + * @param id + * id of the wiimote concerned. + */ + synchronized native void reSync(int id); + + /** + * Make the the accelerometers give smoother results. This is set by + * default. + * + * @param id + * the id of the wiimote concerned. + */ + synchronized native void activateSmoothing(int id); + + /** + * Make the the accelerometers give raw results. + * + * @param id + * the id of the wiimote concerned. + */ + synchronized native void deactivateSmoothing(int id); + + /** + * Make the wiimote generate an event each time we poll. Not set by default. + * + * @param id + * the id of the wiimote concerned. + */ + synchronized native void activateContinuous(int id); + + /** + * Make the wiimote generate an event only when there is one. + * + * @param id + * the id of the wiimote concerned. + */ + synchronized native void deactivateContinuous(int id); + + /** + * Notify wiiuse that your screen has an aspect ratio of 4/3. + * + * @param id + * the id of the wiimote of which we want the status. + */ + synchronized native void setScreenRatio43(int id); + + /** + * Notify wiiuse that your screen has an aspect ratio of 16/9. + * + * @param id + * the id of the wiimote of which we want the status. + */ + synchronized native void setScreenRatio169(int id); + + /** + * Notify wiiuse that the sensor bar is above your screen. + * + * @param id + * the id of the wiimote of which we want the status. + */ + synchronized native void setSensorBarAboveScreen(int id); + + /** + * Notify wiiuse that the sensor bar is below your screen. + * + * @param id + * the id of the wiimote of which we want the status. + */ + synchronized native void setSensorBarBelowScreen(int id); + + /** + * Set virtual screen resolution. It is used to automatically compute the + * position of a cursor on this virtual screen using the sensor bar. These + * results come in the IREvent. + * + * @param id + * the id of the wiimote of which we want the status. + * @param x + * x resolution. + * @param y + * y resolution. + */ + synchronized native void setVirtualScreenResolution(int id, int x, int y); + + /** + * Get status and values from the wiimotes and send it through callbacks. + * + * @param id + * the id of the wiimote of which we want the status. + */ + synchronized native void getStatus(int id); + + /** + * Set the normal and expansion handshake timeouts. + * + * @param id + * the id of the wiimote concerned. + * @param normalTimeout + * The timeout in milliseconds for a normal read. + * @param expansionTimeout + * The timeout in millisecondsd to wait for an expansion + * handshake. + */ + synchronized native void setTimeout(int id, short normalTimeout, + short expansionTimeout); + + /** + * Set the IR sensitivity. + * + * @param id + * the id of the wiimote concerned. + * @param level + * 1-5, same as Wii system sensitivity setting. If the level is < + * 1, then level will be set to 1. If the level is > 5, then + * level will be set to 5. + */ + synchronized native void setIrSensitivity(int id, int level); + + /** + * Set how many degrees an angle must change to generate an event for the + * nunchuk. + * + * @param id + * id of the wiimote concerned. + * @param angle + * minimum angle detected by an event. + */ + synchronized native void setNunchukOrientationThreshold(int id, float angle); + + /** + * Set how much acceleration must change to generate an event for the + * nunchuk. + * + * @param id + * id of the wiimote concerned. + * @param value + * minimum value detected by an event. + */ + synchronized native void setNunchukAccelerationThreshold(int id, int value); + + /** + * Force the bluetooth stack type.(useful only for windows) + * + * @param bluetoothStackType + * must be WiiUseApi.WIIUSE_STACK_UNKNOWN or + * WiiUseApi.WIIUSE_STACK_MS or + * WiiUseApi.WIIUSE_STACK_BLUESOLEIL. + */ + native void windowsSetBluetoothStack(int bluetoothStackType); + + /** + * Check for new Events and Get it. + * + * @param gath + * the object where we store all the new events. + */ + native void specialPoll(EventsGatherer gath); + +} diff --git a/java/src/wiiusej/WiiUseApiManager.java b/java/src/wiiusej/WiiUseApiManager.java new file mode 100644 index 0000000..05797c5 --- /dev/null +++ b/java/src/wiiusej/WiiUseApiManager.java @@ -0,0 +1,664 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.swing.event.EventListenerList; + +import wiiusej.wiiusejevents.utils.EventsGatherer; +import wiiusej.wiiusejevents.utils.WiiUseApiListener; +import wiiusej.wiiusejevents.wiiuseapievents.WiiUseApiEvent; + +/** + * Class that manages the use of Wiiuse API. + * + * @author guiguito + */ +public class WiiUseApiManager extends Thread { + + private static WiiUseApiManager instance = new WiiUseApiManager(); + + private final EventListenerList listeners = new EventListenerList(); + + private Semaphore semaphore = new Semaphore(0); + + private Wiimote[] wiimotes; + + private WiiUseApi wiiuse = WiiUseApi.getInstance(); + + private int connected = -1; + + private AtomicBoolean running = new AtomicBoolean(false); + + private boolean leave = false; + + public static int WIIUSE_STACK_UNKNOWN = 0; + public static int WIIUSE_STACK_MS = 1; + public static int WIIUSE_STACK_BLUESOLEIL = 2; + + public static WiiUseApiManager getInstance() { + return instance; + } + + /** + * Get wiimotes. Load library if necessary. Connect to wiimotes if + * necessary. Start polling if necessary. Return an array with the connected + * wiimotes. + * + * @param nb + * try to connect nb wiimotes. + * @param rumble + * make the connected wiimotes rumble. + * + * @return an array with connected wiimotes or NULL. + */ + public static Wiimote[] getWiimotes(int nb, boolean rumble) { + return getWiimotesPrivate(nb, rumble, false, WIIUSE_STACK_UNKNOWN); + } + + /** + * Get wiimotes. Load library if necessary. Connect to wiimotes if + * necessary. Start polling if necessary. Return an array with the connected + * wiimotes. + * + * @param nb + * try to connect nb wiimotes. + * @param rumble + * make the connected wiimotes rumble.* + * @param stackType + * the stack type : WiiUseApiManager.WIIUSE_STACK_UNKNOWN or + * WiiUseApiManager.WIIUSE_STACK_MS or + * WiiUseApiManager.WIIUSE_STACK_BLUESOLEIL + * + * @return an array with connected wiimotes or NULL. + */ + public static Wiimote[] getWiimotes(int nb, boolean rumble, int stackType) { + return getWiimotesPrivate(nb, rumble, true, stackType); + } + + /** + * Get wiimotes. Load library if necessary. Connect to wiimotes if + * necessary. Start polling if necessary. Return an array with the connected + * wiimotes. + * + * @param nb + * try to connect nb wiimotes. + * @param rumble + * make the connected wiimotes rumble.* + * @param forceStackType + * true if we want to force the stack type. + * @param stackType + * the stack type : WiiUseApiManager.WIIUSE_STACK_UNKNOWN or + * WiiUseApiManager.WIIUSE_STACK_MS or + * WiiUseApiManager.WIIUSE_STACK_BLUESOLEIL + * + * @return an array with connected wiimotes or NULL. + */ + private synchronized static Wiimote[] getWiimotesPrivate(int nb, + boolean rumble, boolean forceStackType, int stackType) { + WiiUseApiManager manager = getInstance(); + + if (manager.leave) + return null;// wiiusej definitively stopped + + if (manager.connected <= 0 && !manager.running.get()) { + // connect wiimotes. + int nbWiimotes = manager.connectWiimotes(nb, rumble, + forceStackType, stackType); + manager.wiimotes = new Wiimote[nbWiimotes]; + for (int i = 0; i < nbWiimotes; i++) { + Wiimote wim = new Wiimote(WiiUseApi.getInstance().getUnId(i), + manager); + manager.wiimotes[i] = wim; + manager.addWiiUseApiListener(wim); + } + // Set leds on wiimote + for (Wiimote wiimote : manager.wiimotes) { + int id = wiimote.getId(); + if (id % 4 == 0) { + wiimote.setLeds(true, true, true, true); + } else if (id % 4 == 1) { + wiimote.setLeds(true, false, false, false); + } else if (id % 4 == 2) { + wiimote.setLeds(true, true, false, false); + } else if (id % 4 == 3) { + wiimote.setLeds(true, true, true, false); + } + } + // make the connected wiimotes rumble + if (rumble) { + for (Wiimote wiimote : manager.wiimotes) { + wiimote.activateRumble(); + } + try { + sleep(500); + } catch (InterruptedException e) { + } + for (Wiimote wiimote : manager.wiimotes) { + wiimote.deactivateRumble(); + } + } + } + + if (manager.connected == 0) {// no wiimote connected + // return empty array + return new Wiimote[0]; + } + + if (!manager.isAlive())// start wiiuseJ polling + manager.start(); + + manager.semaphore.release(1); + + return manager.wiimotes; + } + + /** + * Connect wiimote and get the number of wiimotes connected. Supposed to be + * used once. + * + * @param nb + * try to connect nb wiimotes + * @param rumble + * make the connected wiimotes rumble + * @param forceStackType + * true if we want to force the stack type. + * @param stackType + * the stack type : WiiUseApiManager.WIIUSE_STACK_UNKNOWN or + * WiiUseApiManager.WIIUSE_STACK_MS or + * WiiUseApiManager.WIIUSE_STACK_BLUESOLEIL + * @return 0 if nothing connected or the number of wiimotes connected. + */ + private int connectWiimotes(int nb, boolean rumble, boolean forceStackType, + int stackType) { + if (connected <= 0) { + int nbWiimotesFound; + wiiuse.init(nb); + // force bluetooth stack type ? + if (forceStackType) + setBlueToothstackType(stackType); + nbWiimotesFound = wiiuse.find(nb, 3); + connected = wiiuse.connect(nbWiimotesFound); + return connected; + } else {// library not loaded, no wiimotes connected + return 0; + } + } + + /** + * Ask the thread to close a connection. + * + * @param id + * id of the wiimote to disconnect. + */ + protected void closeConnection(int id) { + int index = 0; + boolean found = false; + while (index < wiimotes.length && !found) { + if (wiimotes[index]!=null && wiimotes[index].getId() == id) {// we have a wiimote with this + // id + // remove the wiimote + removeWiiUseApiListener(wiimotes[index]); + wiimotes[index] = null; + connected--; + if (connected == 0) {// stop this thread if there is + // no more wiimotes connected. + // stop thread + running.set(false); + } + /* Close connection in wiiuse */ + wiiuse.closeConnection(index); + } + index++; + } + } + + /** + * Get the number of wiimotes connected. + * + * @return the number of wiimotes connected. + */ + public static int getNbConnectedWiimotes() { + return getInstance().connected; + } + + /** + * Stop thread and shutdown wiiuse Api. + */ + public static void shutdown() { + WiiUseApiManager manager = getInstance(); + int pastConnected = manager.connected; + if (manager.connected > 0) { + for (Wiimote wim : manager.wiimotes) { + if (wim != null) + wim.disconnect(); + } + } + manager.running.set(false); + if (pastConnected > 0) { + manager.wiiuse.cleanUp(); + } + } + + /** + * Stop wiiuseJ definitively for this program. It finishes Wiiusej thread + * and shutdown wiiuse API. + */ + public static void definitiveShutdown() { + getInstance().leave = true; + shutdown(); + } + + /** + * Activate the rumble for the wiimote with the given id. + * + * @param id + * id of the wiimote. + */ + protected void activateRumble(int id) { + wiiuse.activateRumble(id); + } + + /** + * Deactivate the rumble for the wiimote with the given id. + * + * @param id + * id of the wiimote. + */ + protected void deactivateRumble(int id) { + wiiuse.deactivateRumble(id); + } + + /** + * Activate IR Tracking for the wiimote with the given id. + * + * @param id + * id of the wiimote. + */ + protected void activateIRTRacking(int id) { + wiiuse.activateIRTracking(id); + } + + /** + * Deactivate IR Tracking for the wiimote with the given id. + * + * @param id + * id of the wiimote. + */ + protected void deactivateIRTRacking(int id) { + wiiuse.deactivateIRTracking(id); + } + + /** + * Activate motion sensing for the wiimote with the given id. + * + * @param id + * id of the wiimote. + */ + protected void activateMotionSensing(int id) { + wiiuse.activateMotionSensing(id); + } + + /** + * Deactivate motion sensing for the wiimoter with the given id. + * + * @param id + * id of the wiimote. + */ + protected void deactivateMotionSensing(int id) { + wiiuse.deactivateMotionSensing(id); + } + + /** + * Activate smoothing the wiimotes with the given id. + * + * @param id + * id of the wiimote. + */ + protected void activateSmoothing(int id) { + wiiuse.activateSmoothing(id); + } + + /** + * Deactivate smoothing the wiimotes with the given id. + * + * @param id + * id of the wiimote. + */ + protected void deactivateSmoothing(int id) { + wiiuse.deactivateSmoothing(id); + } + + /** + * Activate continuous for the wiimotes with the given id. + * + * @param id + * id of the wiimote. + */ + protected void activateContinuous(int id) { + wiiuse.activateContinuous(id); + } + + /** + * Deactivate continuous for the wiimotes with the given id. + * + * @param id + * id of the wiimote. + */ + protected void deactivateContinuous(int id) { + wiiuse.deactivateContinuous(id); + } + + /** + * Set leds for the wiimotes with the given id. + * + * @param id + * id of the wiimote + * @param l1 + * status of led1. True : ON, False : OFF. + * @param l2 + * status of led2. True : ON, False : OFF. + * @param l3 + * status of led3. True : ON, False : OFF. + * @param l4 + * status of led4. True : ON, False : OFF. + */ + protected void setLeds(int id, boolean l1, boolean l2, boolean l3, + boolean l4) { + wiiuse.setLeds(id, l1, l2, l3, l4); + } + + /** + * Set the orientation threshold for the given id. (minimum angle between + * two events) + * + * @param id + * id of the wiimote. + * @param th + * threshold in degrees. + */ + protected void setOrientationThreshold(int id, float th) { + wiiuse.setOrientThreshold(id, th); + } + + /** + * Set the acceleration threshold for the given id. (minimum angle between + * two events) + * + * @param id + * id of the wiimote. + * @param th + * threshold. + */ + protected void setAccelerationThreshold(int id, int th) { + wiiuse.setAccelThreshold(id, th); + } + + /** + * Set alpha smoothing for the given id. + * + * @param id + * id of the wiimote. + * @param th + * threshold. + */ + protected void setAlphaSmoothing(int id, float th) { + wiiuse.setAlphaSmoothing(id, th); + } + + /** + * Try to resync with the wiimote by starting a new handshake. + * + * @param id + * id of the wiimote. + */ + protected void reSync(int id) { + wiiuse.reSync(id); + } + + /** + * Set screen aspect ratio to 4/3 for the given id. + * + * @param id + * id of the wiimote. + */ + protected void setScreenAspectRatio43(int id) { + wiiuse.setScreenRatio43(id); + } + + /** + * Set screen aspect ratio to 16/9 for the given id. + * + * @param id + * id of the wiimote. + */ + protected void setScreenAspectRatio169(int id) { + wiiuse.setScreenRatio169(id); + } + + /** + * Set the sensor bar to be above the screen. + * + * @param id + * id of the wiimote. + */ + protected void setSensorBarAboveScreen(int id) { + wiiuse.setSensorBarAboveScreen(id); + } + + /** + * Set the sensor bar to be below the screen. + * + * @param id + * id of the wiimote. + */ + protected void setSensorBarBelowScreen(int id) { + wiiuse.setSensorBarBelowScreen(id); + } + + /** + * Set virtual resolution. It is used to automatically compute the position + * of a cursor on this virtual screen using the sensor bar. These results + * come in the IREvent. + * + * @param id + * id of the wiimote. + * @param x + * x resolution. + * @param y + * y resolution. + */ + protected void setVirtualResolution(int id, int x, int y) { + wiiuse.setVirtualScreenResolution(id, x, y); + } + + /** + * Get Status for the wiimote for the given id. + * + * @param id + * id of the wiimote. + */ + protected void getStatus(int id) { + wiiuse.getStatus(id); + } + + /** + * Set the normal and expansion handshake timeouts. + * + * @param id + * the id of the wiimote concerned. + * @param normalTimeout + * The timeout in milliseconds for a normal read. + * @param expansionTimeout + * The timeout in millisecondsd to wait for an expansion + * handshake. + */ + protected void setTimeout(int id, short normalTimeout, + short expansionTimeout) { + wiiuse.setTimeout(id, normalTimeout, expansionTimeout); + } + + /** + * Set the IR sensitivity. + * + * @param id + * the id of the wiimote concerned. + * @param level + * 1-5, same as Wii system sensitivity setting. If the level is < + * 1, then level will be set to 1. If the level is > 5, then + * level will be set to 5. + */ + protected void setIrSensitivity(int id, int level) { + wiiuse.setIrSensitivity(id, level); + } + + /** + * Set the nunchuk orientation threshold for the given id. (minimum angle + * between two events) + * + * @param id + * id of the wiimote. + * @param th + * threshold in degrees. + */ + protected void setNunchukOrientationThreshold(int id, float th) { + wiiuse.setNunchukOrientationThreshold(id, th); + } + + /** + * Set the nunchuk acceleration threshold for the given id. (minimum angle + * between two events) + * + * @param id + * id of the wiimote. + * @param th + * threshold. + */ + protected void setNunchukAccelerationThreshold(int id, int th) { + wiiuse.setNunchukAccelerationThreshold(id, th); + } + + /** + * Force the bluetooth stack type.(useful only for windows) + * + * @param type + * must be WIIUSE_STACK_UNKNOWN or WIIUSE_STACK_MS or + * WIIUSE_STACK_BLUESOLEIL. + */ + private void setBlueToothstackType(int type) { + wiiuse.windowsSetBluetoothStack(type); + } + + @Override + public void run() { + + while (!leave) { + try { + semaphore.acquire(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + if (connected > 0) { + running.set(true); + + EventsGatherer gather = new EventsGatherer(connected); + + // Start polling and tell the observers when there are Wiimote + // events + while (running.get() && connected > 0) { + + /* Polling */ + wiiuse.specialPoll(gather); + + /* deal with events gathered in Wiiuse API */ + for (WiiUseApiEvent evt : gather.getEvents()) { + if (evt.getWiimoteId() != -1) {// event filled + // there is an event notify observers + notifyWiiUseApiListener(evt); + if (evt.getEventType() == WiiUseApiEvent.DISCONNECTION_EVENT) { + // check if it was a disconnection + // in this case disconnect the wiimote + closeConnection(evt.getWiimoteId()); + } + } else { + System.out + .println("There is an event with id == -1 ??? there is a problem !!! : " + + evt); + } + } + gather.clearEvents(); + } + }/* else { + if (connected <= 0) { + System.out.println("No wiimotes connected !"); + } + }*/ + }// end while true + } + + /** + * Add WiiUseApiListener to the listeners list. + * + * @param listener + * a WiiUseApiListener + */ + protected void addWiiUseApiListener(WiiUseApiListener listener) { + listeners.add(WiiUseApiListener.class, listener); + } + + /** + * Remove WiiUseApiListener from the listeners list. + * + * @param listener + * a WiiUseApiListener + */ + protected void removeWiiUseApiListener(WiiUseApiListener listener) { + listeners.remove(WiiUseApiListener.class, listener); + } + + /** + * Get the list of WiiUseApiListeners. + * + * @return the list of WiiUseApiListeners. + */ + protected WiiUseApiListener[] getWiiUseApiListeners() { + return listeners.getListeners(WiiUseApiListener.class); + } + + /** + * Notify WiiUseApiListeners that an event occured. + * + * @param evt + * GenericEvent occured + */ + private void notifyWiiUseApiListener(WiiUseApiEvent evt) { + for (WiiUseApiListener listener : getWiiUseApiListeners()) { + listener.onWiiUseApiEvent(evt); + } + } + + /** + * Called by the garbage collector at the end. + */ + protected void finalize() throws Throwable { + shutdown(); + } + +} diff --git a/java/src/wiiusej/Wiimote.java b/java/src/wiiusej/Wiimote.java new file mode 100644 index 0000000..aabb0f0 --- /dev/null +++ b/java/src/wiiusej/Wiimote.java @@ -0,0 +1,495 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej; + +import javax.swing.event.EventListenerList; + +import wiiusej.wiiusejevents.utils.WiiUseApiListener; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; +import wiiusej.wiiusejevents.wiiuseapievents.WiiUseApiEvent; +import wiiusej.wiiusejevents.wiiuseapievents.WiimoteEvent; + +/** + * Class that represents a wiimote. You can register as an observer of this + * wiimote to listen events from it. You manage it. + * + * @author guiguito + */ +public class Wiimote implements WiiUseApiListener { + + private int id = -1;// wiimote id + + private EventListenerList listeners = new EventListenerList(); + + private WiiUseApiManager manager; + + /** + * Constructor. + * + * @param idd + * id of the wiimote + * @param manager + * manager wo built it. + */ + public Wiimote(int idd, WiiUseApiManager manager) { + id = idd; + this.manager = manager; + } + + /** + * Get the unique id of the wiimote. + * + * @return the id + */ + public int getId() { + return id; + } + + /** + * Disconnect this wiimote. + */ + public void disconnect() { + deactivateIRTRacking(); + deactivateMotionSensing(); + deactivateRumble(); + manager.closeConnection(id); + } + + /** + * Activate the rumble. + */ + public void activateRumble() { + manager.activateRumble(id); + } + + /** + * Deactivate the rumble. + */ + public void deactivateRumble() { + manager.deactivateRumble(id); + } + + /** + * Activate IR Tracking. + */ + public void activateIRTRacking() { + manager.activateIRTRacking(id); + } + + /** + * Deactivate IR Tracking. + */ + public void deactivateIRTRacking() { + manager.deactivateIRTRacking(id); + } + + /** + * Activate motion sensing. + */ + public void activateMotionSensing() { + manager.activateMotionSensing(id); + } + + /** + * Deactivate motion sensing. + */ + public void deactivateMotionSensing() { + manager.deactivateMotionSensing(id); + } + + /** + * Activate smoothing. + */ + public void activateSmoothing() { + manager.activateSmoothing(id); + } + + /** + * Deactivate smoothing. + */ + public void deactivateSmoothing() { + manager.deactivateSmoothing(id); + } + + /** + * Activate continuous. + */ + public void activateContinuous() { + manager.activateContinuous(id); + } + + /** + * Deactivate continuous. + */ + public void deactivateContinuous() { + manager.deactivateContinuous(id); + + } + + /** + * Set leds status. + * + * @param l1 + * status of led1. True : ON, False : OFF + * @param l2 + * status of led2. True : ON, False : OFF + * @param l3 + * status of led3. True : ON, False : OFF + * @param l4 + * status of led4. True : ON, False : OFF + */ + public void setLeds(boolean l1, boolean l2, boolean l3, boolean l4) { + manager.setLeds(id, l1, l2, l3, l4); + } + + /** + * Set the orientation threshold (minimum angle between two degrees with + * accelerometer). + * + * @param th + * threshold in degrees + */ + public void setOrientationThreshold(float th) { + manager.setOrientationThreshold(id, th); + } + + /** + * Set the acceleration threshold(minimum angle between two degrees with + * accelerometer). + * + * @param th + * threshold + */ + public void setAccelerationThreshold(int th) { + manager.setAccelerationThreshold(id, th); + } + + /** + * Set the alpha smoothing value. + * + * @param th + * threshold + */ + public void setAlphaSmoothingValue(float th) { + manager.setAlphaSmoothing(id, th); + } + + /** + * Set the screen aspect ratio to be considered as 4/3. + */ + public void setScreenAspectRatio43() { + manager.setScreenAspectRatio43(id); + } + + /** + * Set the screen aspect ratio to be considered as 16/9. + */ + public void setScreenAspectRatio169() { + manager.setScreenAspectRatio169(id); + } + + /** + * Set the sensor bar to be considered above the screen. + */ + public void setSensorBarAboveScreen() { + manager.setSensorBarAboveScreen(id); + } + + /** + * Set the sensor bar to be considered below the screen. + */ + public void setSensorBarBelowScreen() { + manager.setSensorBarBelowScreen(id); + } + + /** + * Set the screen resolution of the you are pointing at with your wiimote. + * + * @param x + * x resolution. + * @param y + * y resolution. + */ + public void setVirtualResolution(int x, int y) { + manager.setVirtualResolution(id, x, y); + } + + /** + * Set the nunchuk orientation threshold for the given id. (minimum angle + * between two events) + * + * @param th + * threshold in degrees. + */ + public void setNunchukOrientationThreshold(float th) { + manager.setNunchukOrientationThreshold(id, th); + } + + /** + * Set the nunchuk acceleration threshold for the given id. (minimum angle + * between two events) + * + * @param th + * threshold. + */ + public void setNunchukAccelerationThreshold(int th) { + manager.setNunchukAccelerationThreshold(id, th); + } + + /** + * Try to resync the wiimote by starting a new handshake. + */ + public void reSync() { + manager.reSync(id); + } + + /** + * Ask for the status of the wiimote. The result will be received in a + * status event object. Implements onStatusEvent on wiimote listener to get + * it. + */ + public void getStatus() { + manager.getStatus(id); + } + + /** + * Set the normal and expansion handshake timeouts for this wiimote. Normal + * time out is for classic polling. The expansion timeout is used when an + * expansion is detected until the expansion successfully handshakes. + * + * @param normalTimeout + * The timeout in milliseconds for a normal read. + * @param expansionTimeout + * The timeout in millisecondsd to wait for an expansion + * handshake. + */ + public void setTimeout(short normalTimeout, short expansionTimeout) { + manager.setTimeout(id, normalTimeout, expansionTimeout); + } + + /** + * Set the IR sensitivity. + * + * @param level + * 1-5, same as Wii system sensitivity setting. If the level is < + * 1, then level will be set to 1. If the level is > 5, then + * level will be set to 5. + */ + public void setIrSensitivity(int level) { + manager.setIrSensitivity(id, level); + } + + /** + * Method called when a WiiUseApiEvent occurs. + * + * @param e + * the WiiUseApiEvent. + */ + public void onWiiUseApiEvent(WiiUseApiEvent e) { + if (e.getWiimoteId() == id) { + if (e.getEventType() == WiiUseApiEvent.GENERIC_EVENT) { + notifyWiiMoteEventListeners((WiimoteEvent) e); + } else if (e.getEventType() == WiiUseApiEvent.STATUS_EVENT) { + notifyStatusEventListeners((StatusEvent) e); + } else if (e.getEventType() == WiiUseApiEvent.DISCONNECTION_EVENT) { + notifyDisconnectionEventListeners((DisconnectionEvent) e); + } else if (e.getEventType() == WiiUseApiEvent.WIIUSE_NUNCHUK_INSERTED) { + notifyNunchukInsertedEventListeners((NunchukInsertedEvent) e); + } else if (e.getEventType() == WiiUseApiEvent.WIIUSE_NUNCHUK_REMOVED) { + notifyNunchukRemovedEventListeners((NunchukRemovedEvent) e); + } else if (e.getEventType() == WiiUseApiEvent.WIIUSE_GUITAR_HERO_3_CTRL_INSERTED) { + notifyGuitarHeroInsertedEventListeners((GuitarHeroInsertedEvent) e); + } else if (e.getEventType() == WiiUseApiEvent.WIIUSE_GUITAR_HERO_3_CTRL_REMOVED) { + notifyGuitarHeroRemovedEventListeners((GuitarHeroRemovedEvent) e); + } else if (e.getEventType() == WiiUseApiEvent.WIIUSE_CLASSIC_CTRL_INSERTED) { + notifyClassicControllerInsertedEventListeners((ClassicControllerInsertedEvent) e); + } else if (e.getEventType() == WiiUseApiEvent.WIIUSE_CLASSIC_CTRL_REMOVED) { + notifyClassicControllerRemovedEventListeners((ClassicControllerRemovedEvent) e); + } + /* + * events not managed yet || e.getEventType() == WIIUSE_READ_DATA + * WiiUseApiEvent.WIIUSE_CLASSIC_CTRL_INSERTED || e.getEventType() == + * WiiUseApiEvent.WIIUSE_CLASSIC_CTRL_REMOVED || e.getEventType() == + * WiiUseApiEvent.WIIUSE_GUITAR_HERO_3_CTRL_INSERTED || + * e.getEventType() == + * WiiUseApiEvent.WIIUSE_GUITAR_HERO_3_CTRL_REMOVED + */ + } + } + + /** + * Add a WiimoteListener to the listeners list. + * + * @param listener + * a WiimoteListener + */ + public void addWiiMoteEventListeners(WiimoteListener listener) { + listeners.add(WiimoteListener.class, listener); + } + + /** + * Remove a WiimoteListener from the listeners list. + * + * @param listener + * a WiimoteListener + */ + public void removeWiiMoteEventListeners(WiimoteListener listener) { + listeners.remove(WiimoteListener.class, listener); + } + + /** + * Get the list of WiimoteListener. + * + * @return the list of WiimoteListener. + */ + public WiimoteListener[] getWiiMoteEventListeners() { + return listeners.getListeners(WiimoteListener.class); + } + + /** + * Notify WiimoteListeners that an event occured. Notify in first the + * listeners for Buttons Events. In second the listeners for IR Events. In + * third the listeners for Motion sensing events. + * + * @param evt + * GenericEvent occured + */ + private void notifyWiiMoteEventListeners(WiimoteEvent evt) { + for (WiimoteListener listener : getWiiMoteEventListeners()) { + listener.onButtonsEvent(evt.getButtonsEvent()); + if (evt.isThereIrEvent()) { + listener.onIrEvent(evt.getIREvent()); + } + if (evt.isThereMotionSensingEvent()) { + listener.onMotionSensingEvent(evt.getMotionSensingEvent()); + } + if (evt.isThereExpansionEvent()) { + listener.onExpansionEvent(evt.getExpansionEvent()); + } + } + } + + /** + * Notify WiimoteListener that a status event occured. + * + * @param evt + * status event occured + */ + private void notifyStatusEventListeners(StatusEvent evt) { + for (WiimoteListener listener : getWiiMoteEventListeners()) { + listener.onStatusEvent(evt); + } + } + + /** + * Notify WiimoteListener that a disconnection event occured. + * + * @param evt + * disconnection event occured + */ + private void notifyDisconnectionEventListeners(DisconnectionEvent evt) { + for (WiimoteListener listener : getWiiMoteEventListeners()) { + listener.onDisconnectionEvent(evt); + } + } + + /** + * Notify WiimoteListener that a NunchukInserted Event occured. + * + * @param evt + * NunchukInserted Event occured + */ + private void notifyNunchukInsertedEventListeners(NunchukInsertedEvent evt) { + for (WiimoteListener listener : getWiiMoteEventListeners()) { + listener.onNunchukInsertedEvent(evt); + } + } + + /** + * Notify WiimoteListener that a NunchukRemoved Event occured. + * + * @param evt + * NunchukRemoved Event occured + */ + private void notifyNunchukRemovedEventListeners(NunchukRemovedEvent evt) { + for (WiimoteListener listener : getWiiMoteEventListeners()) { + listener.onNunchukRemovedEvent(evt); + } + } + + /** + * Notify WiimoteListener that a GuitarHeroInserted Event occured. + * + * @param evt + * GuitarHeroInserted Event occured + */ + private void notifyGuitarHeroInsertedEventListeners(GuitarHeroInsertedEvent evt) { + for (WiimoteListener listener : getWiiMoteEventListeners()) { + listener.onGuitarHeroInsertedEvent(evt); + } + } + + /** + * Notify WiimoteListener that a GuitarHeroRemoved Event occured. + * + * @param evt + * GuitarHeroRemoved Event occured + */ + private void notifyGuitarHeroRemovedEventListeners(GuitarHeroRemovedEvent evt) { + for (WiimoteListener listener : getWiiMoteEventListeners()) { + listener.onGuitarHeroRemovedEvent(evt); + } + } + + /** + * Notify WiimoteListener that a ClassicControllerInserted Event occured. + * + * @param evt + * ClassicControllerInserted Event occured + */ + private void notifyClassicControllerInsertedEventListeners(ClassicControllerInsertedEvent evt) { + for (WiimoteListener listener : getWiiMoteEventListeners()) { + listener.onClassicControllerInsertedEvent(evt); + } + } + + /** + * Notify WiimoteListener that a ClassicControllerRemoved Event occured. + * + * @param evt + * ClassicControllerRemoved Event occured + */ + private void notifyClassicControllerRemovedEventListeners(ClassicControllerRemovedEvent evt) { + for (WiimoteListener listener : getWiiMoteEventListeners()) { + listener.onClassicControllerRemovedEvent(evt); + } + } + + @Override + public String toString() { + return "Wiimote with ID : " + id; + } + +} diff --git a/java/src/wiiusej/test/ClassicControllerGuiTest.java b/java/src/wiiusej/test/ClassicControllerGuiTest.java new file mode 100644 index 0000000..4e55b90 --- /dev/null +++ b/java/src/wiiusej/test/ClassicControllerGuiTest.java @@ -0,0 +1,179 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.test; + +import wiiusej.WiiUseApiManager; +import wiiusej.Wiimote; +import wiiusej.utils.ClassicControllerButtonsEventPanel; +import wiiusej.wiiusejevents.physicalevents.ClassicControllerEvent; +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * This frame is used to display events from a classic controller. + * + * @author guiguito + */ +public class ClassicControllerGuiTest extends javax.swing.JFrame implements WiimoteListener { + + private Wiimote wiimote; + private static int MAX_SHOULDER = 100; + + /** Creates new form ClassicControllerGuiTest */ + public ClassicControllerGuiTest(Wiimote wiimote) { + initComponents(); + this.wiimote = wiimote; + registerListeners(); + leftShoulderBar.setMaximum(MAX_SHOULDER); + rightShoulderBar.setMaximum(MAX_SHOULDER); + } + + private void registerListeners() { + wiimote.addWiiMoteEventListeners(this); + wiimote.addWiiMoteEventListeners((ClassicControllerButtonsEventPanel) classicControllerPanel); + } + + public void unRegisterListeners() { + wiimote.removeWiiMoteEventListeners(this); + wiimote.removeWiiMoteEventListeners((ClassicControllerButtonsEventPanel) classicControllerPanel); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + shouldersPanel = new javax.swing.JPanel(); + leftShoulderBar = new javax.swing.JProgressBar(); + rightShoulderBar = new javax.swing.JProgressBar(); + classicControllerPanel = new wiiusej.utils.ClassicControllerButtonsEventPanel(); + + setTitle("WiiuseJ Classic Controller Test GUI"); + setResizable(false); + getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.Y_AXIS)); + + shouldersPanel.setMaximumSize(new java.awt.Dimension(350, 16)); + shouldersPanel.setMinimumSize(new java.awt.Dimension(350, 16)); + shouldersPanel.setPreferredSize(new java.awt.Dimension(350, 16)); + shouldersPanel.setLayout(new javax.swing.BoxLayout(shouldersPanel, javax.swing.BoxLayout.LINE_AXIS)); + shouldersPanel.add(leftShoulderBar); + shouldersPanel.add(rightShoulderBar); + + getContentPane().add(shouldersPanel); + + classicControllerPanel.setMaximumSize(new java.awt.Dimension(350, 182)); + classicControllerPanel.setMinimumSize(new java.awt.Dimension(350, 182)); + + javax.swing.GroupLayout classicControllerPanelLayout = new javax.swing.GroupLayout(classicControllerPanel); + classicControllerPanel.setLayout(classicControllerPanelLayout); + classicControllerPanelLayout.setHorizontalGroup( + classicControllerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 350, Short.MAX_VALUE) + ); + classicControllerPanelLayout.setVerticalGroup( + classicControllerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 182, Short.MAX_VALUE) + ); + + getContentPane().add(classicControllerPanel); + + pack(); + }// //GEN-END:initComponents + public void onButtonsEvent(WiimoteButtonsEvent arg0) { + // nothing to do + } + + public void onIrEvent(IREvent arg0) { + // nothing to do + } + + public void onMotionSensingEvent(MotionSensingEvent arg0) { + // nothing to do + } + + public void onExpansionEvent(ExpansionEvent arg0) { + if (arg0 instanceof ClassicControllerEvent) { + ClassicControllerEvent classicController = (ClassicControllerEvent) arg0; + float leftShoulder = classicController.getLeftShoulder(); + float rightShoulder = classicController.getRightShoulder(); + leftShoulderBar.setValue(Math.round(leftShoulder * MAX_SHOULDER)); + rightShoulderBar.setValue(Math.round(rightShoulder * MAX_SHOULDER)); + } + } + + public void onStatusEvent(StatusEvent arg0) { + // nothing to do + } + + public void onDisconnectionEvent(DisconnectionEvent arg0) { + // nothing to do + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent arg0) { + // nothing to do + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent arg0) { + // nothing to do + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) { + // nothing to do + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) { + // nothing to do + } + + public void onClassicControllerInsertedEvent(ClassicControllerInsertedEvent arg0) { + // nothing to do + } + + public void onClassicControllerRemovedEvent(ClassicControllerRemovedEvent arg0) { + // nothing to do + } + + public static void main(String[] args) { + Wiimote[] wiimotes = WiiUseApiManager.getWiimotes(1, true); + ClassicControllerGuiTest gui = null; + if (wiimotes.length > 0) { + gui = new ClassicControllerGuiTest(wiimotes[0]); + } + gui.setDefaultCloseOperation(WiiuseJGuiTest.EXIT_ON_CLOSE); + gui.setVisible(true); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel classicControllerPanel; + private javax.swing.JProgressBar leftShoulderBar; + private javax.swing.JProgressBar rightShoulderBar; + private javax.swing.JPanel shouldersPanel; + // End of variables declaration//GEN-END:variables +} diff --git a/java/src/wiiusej/test/CloseGuiTestCleanly.java b/java/src/wiiusej/test/CloseGuiTestCleanly.java new file mode 100644 index 0000000..584f2d9 --- /dev/null +++ b/java/src/wiiusej/test/CloseGuiTestCleanly.java @@ -0,0 +1,58 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.test; + +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import wiiusej.WiiUseApiManager; + +/** + * This class is used to close wiiusej cleanly. + * + * @author guiguito + */ +public class CloseGuiTestCleanly implements WindowListener { + + public void windowOpened(WindowEvent e) { + // nothing + } + + public void windowClosing(WindowEvent e) { + WiiUseApiManager.definitiveShutdown(); + } + + public void windowClosed(WindowEvent e) { + // nothing + } + + public void windowIconified(WindowEvent e) { + // nothing + } + + public void windowDeiconified(WindowEvent e) { + // nothing + } + + public void windowActivated(WindowEvent e) { + // nothing + } + + public void windowDeactivated(WindowEvent e) { + // nothing + } + +} diff --git a/java/src/wiiusej/test/GuitarHero3GuiTest.java b/java/src/wiiusej/test/GuitarHero3GuiTest.java new file mode 100644 index 0000000..b0f1dd4 --- /dev/null +++ b/java/src/wiiusej/test/GuitarHero3GuiTest.java @@ -0,0 +1,168 @@ +/* + * GuitarHeroGUITest.java + * + * Created on 12 juin 2008, 23:10 + */ +package wiiusej.test; + +import wiiusej.Wiimote; +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.GuitarHeroEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * This frame is used to display events from a Guitar Hero 3. + * @author guiguito + */ +public class GuitarHero3GuiTest extends javax.swing.JFrame implements WiimoteListener { + + private Wiimote wiimote; + private static int MAX_WHAMMY_BAR = 100; + + /** Creates new form GuitarHeroGUITest */ + public GuitarHero3GuiTest(Wiimote wiimote) { + initComponents(); + this.wiimote = wiimote; + whammyProgressBar.setMaximum(MAX_WHAMMY_BAR); + registerListeners(); + } + + private void registerListeners() { + wiimote.addWiiMoteEventListeners(this); + //register panel buttons + wiimote.addWiiMoteEventListeners(guitarHero3ButtonsEventPanel); + //register joystick panel + wiimote.addWiiMoteEventListeners(guitarHero3JoystickPanel); + } + + public void unRegisterListeners() { + wiimote.removeWiiMoteEventListeners(this); + wiimote.removeWiiMoteEventListeners(guitarHero3ButtonsEventPanel); + wiimote.removeWiiMoteEventListeners(guitarHero3JoystickPanel); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + buttonsEventPanel = new javax.swing.JPanel(); + guitarHero3ButtonsEventPanel = new wiiusej.utils.GuitarHero3ButtonsEventPanel(); + bottomPanel = new javax.swing.JPanel(); + guitarHero3JoystickPanel = new wiiusej.utils.GuitarHeroJoystickEventPanel(); + whammyProgressBar = new javax.swing.JProgressBar(); + + setTitle("WiiuseJ Guitar Hero 3 Test GUI"); + getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.Y_AXIS)); + + buttonsEventPanel.setBackground(new java.awt.Color(0, 0, 0)); + + javax.swing.GroupLayout buttonsEventPanelLayout = new javax.swing.GroupLayout(buttonsEventPanel); + buttonsEventPanel.setLayout(buttonsEventPanelLayout); + buttonsEventPanelLayout.setHorizontalGroup( + buttonsEventPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 526, Short.MAX_VALUE) + .addGroup(buttonsEventPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(buttonsEventPanelLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(guitarHero3ButtonsEventPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE))) + ); + buttonsEventPanelLayout.setVerticalGroup( + buttonsEventPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 96, Short.MAX_VALUE) + .addGroup(buttonsEventPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(buttonsEventPanelLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(guitarHero3ButtonsEventPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE))) + ); + + getContentPane().add(buttonsEventPanel); + + bottomPanel.setBackground(new java.awt.Color(0, 0, 0)); + bottomPanel.setLayout(new javax.swing.BoxLayout(bottomPanel, javax.swing.BoxLayout.X_AXIS)); + bottomPanel.add(guitarHero3JoystickPanel); + + whammyProgressBar.setBackground(new java.awt.Color(255, 255, 255)); + whammyProgressBar.setForeground(new java.awt.Color(255, 0, 255)); + bottomPanel.add(whammyProgressBar); + + getContentPane().add(bottomPanel); + + pack(); + }// //GEN-END:initComponents + public void onButtonsEvent(WiimoteButtonsEvent arg0) { + // nothing to do + } + + public void onIrEvent(IREvent arg0) { + // nothing to do + } + + public void onMotionSensingEvent(MotionSensingEvent arg0) { + // nothing to do + } + + public void onExpansionEvent(ExpansionEvent arg0) { + if (arg0 instanceof GuitarHeroEvent) { + GuitarHeroEvent guitar = (GuitarHeroEvent) arg0; + //move progress bar for whammy bar + whammyProgressBar.setValue(Math.round(MAX_WHAMMY_BAR*guitar.getWhammyBar())); + } + + } + + public void onStatusEvent(StatusEvent arg0) { + // nothing to do + } + + public void onDisconnectionEvent(DisconnectionEvent arg0) { + // nothing to do + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent arg0) { + // nothing to do + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent arg0) { + // nothing to do + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) { + // nothing to do + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) { + // nothing to do + } + + public void onClassicControllerInsertedEvent(ClassicControllerInsertedEvent arg0) { + // nothing to do + } + + public void onClassicControllerRemovedEvent(ClassicControllerRemovedEvent arg0) { + // nothing to do + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel bottomPanel; + private javax.swing.JPanel buttonsEventPanel; + private wiiusej.utils.GuitarHero3ButtonsEventPanel guitarHero3ButtonsEventPanel; + private wiiusej.utils.GuitarHeroJoystickEventPanel guitarHero3JoystickPanel; + private javax.swing.JProgressBar whammyProgressBar; + // End of variables declaration//GEN-END:variables +} diff --git a/java/src/wiiusej/test/Main.java b/java/src/wiiusej/test/Main.java new file mode 100644 index 0000000..67ef279 --- /dev/null +++ b/java/src/wiiusej/test/Main.java @@ -0,0 +1,45 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.test; + +import wiiusej.WiiUseApiManager; +import wiiusej.Wiimote; + +/** + * Main Class to launch WiiuseJ GUI Test. + * + * @author guiguito + */ +public class Main { + + /** + * @param args + * the command line arguments + */ + public static void main(String[] args) { + Wiimote[] wiimotes = WiiUseApiManager.getWiimotes(1, true); + WiiuseJGuiTest gui = null; + if (wiimotes.length > 0) { + gui = new WiiuseJGuiTest(wiimotes[0]); + } else { + gui = new WiiuseJGuiTest(); + } + gui.setDefaultCloseOperation(WiiuseJGuiTest.EXIT_ON_CLOSE); + gui.setVisible(true); + } + +} diff --git a/java/src/wiiusej/test/NunchukGuiTest.java b/java/src/wiiusej/test/NunchukGuiTest.java new file mode 100644 index 0000000..d7f284f --- /dev/null +++ b/java/src/wiiusej/test/NunchukGuiTest.java @@ -0,0 +1,450 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.test; + +import wiiusej.Wiimote; +import wiiusej.utils.AccelerationExpansionEventPanel; +import wiiusej.utils.AccelerationPanel; +import wiiusej.utils.GForceExpansionEventPanel; +import wiiusej.utils.GForcePanel; +import wiiusej.utils.NunchukJoystickEventPanel; +import wiiusej.utils.OrientationExpansionEventPanel; +import wiiusej.utils.OrientationPanel; +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.NunchukButtonsEvent; +import wiiusej.wiiusejevents.physicalevents.NunchukEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * This frame is used to display events from a nunchuk. + * + * @author guiguito + */ +public class NunchukGuiTest extends javax.swing.JFrame implements + WiimoteListener { + + private Wiimote wiimote; + private boolean isThresholdsRequested = true; + + /** Creates new form NunchukGuiTest */ + public NunchukGuiTest(Wiimote wiimote) { + initComponents(); + this.wiimote = wiimote; + registerListeners(); + } + + private void registerListeners() { + wiimote.addWiiMoteEventListeners(this); + wiimote.addWiiMoteEventListeners((OrientationPanel) orientationPanel); + wiimote.addWiiMoteEventListeners((GForcePanel) gForcePanel); + wiimote + .addWiiMoteEventListeners((AccelerationPanel) rawAccelerationPanel); + wiimote + .addWiiMoteEventListeners((NunchukJoystickEventPanel) joystickEventsPanel); + } + + public void unRegisterListeners() { + wiimote + .removeWiiMoteEventListeners((OrientationPanel) orientationPanel); + wiimote.removeWiiMoteEventListeners((GForcePanel) gForcePanel); + wiimote + .removeWiiMoteEventListeners((AccelerationPanel) rawAccelerationPanel); + wiimote + .removeWiiMoteEventListeners((NunchukJoystickEventPanel) joystickEventsPanel); + wiimote.removeWiiMoteEventListeners(this); + } + + public void requestThresholdsUpdate() { + isThresholdsRequested = true; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + topPanels = new javax.swing.JPanel(); + joystickEventsPanel = new NunchukJoystickEventPanel(); + motionSensingEventsPanel = new javax.swing.JPanel(); + motionSensingEventsTabbedPanels = new javax.swing.JTabbedPane(); + rawAccelerationPanel = new AccelerationExpansionEventPanel(); + orientationPanel = new OrientationExpansionEventPanel(); + gForcePanel = new GForceExpansionEventPanel(); + setNunchukValuesPanel = new javax.swing.JPanel(); + nunchukButtonsEventPanel = new javax.swing.JPanel(); + cButton = new javax.swing.JButton(); + zButton = new javax.swing.JButton(); + nunchukOrientationPanel = new javax.swing.JPanel(); + nunchukOrientationTextField = new javax.swing.JTextField(); + nunchukOrientationButton = new javax.swing.JButton(); + nunchukAccelerationPanel = new javax.swing.JPanel(); + nunchukAccelerationTextField = new javax.swing.JTextField(); + nunchukAccelerationButton = new javax.swing.JButton(); + messagePanel = new javax.swing.JPanel(); + messageText = new javax.swing.JLabel(); + + setTitle("WiiuseJ Nunchuk Test GUI"); + setMinimumSize(new java.awt.Dimension(400, 400)); + getContentPane().setLayout( + new javax.swing.BoxLayout(getContentPane(), + javax.swing.BoxLayout.Y_AXIS)); + + topPanels.setMinimumSize(new java.awt.Dimension(400, 200)); + topPanels.setPreferredSize(new java.awt.Dimension(400, 200)); + topPanels.setLayout(new javax.swing.BoxLayout(topPanels, + javax.swing.BoxLayout.LINE_AXIS)); + + joystickEventsPanel.setBackground(new java.awt.Color(0, 0, 0)); + joystickEventsPanel.setBorder(javax.swing.BorderFactory + .createTitledBorder(new javax.swing.border.LineBorder( + new java.awt.Color(51, 153, 0), 2, true), + "Joystick View", + javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, + javax.swing.border.TitledBorder.DEFAULT_POSITION, + new java.awt.Font("Tahoma", 0, 11), new java.awt.Color( + 204, 102, 0))); + joystickEventsPanel.setToolTipText("JoystickEvent"); + joystickEventsPanel.setMinimumSize(new java.awt.Dimension(200, 200)); + + javax.swing.GroupLayout joystickEventsPanelLayout = new javax.swing.GroupLayout( + joystickEventsPanel); + joystickEventsPanel.setLayout(joystickEventsPanelLayout); + joystickEventsPanelLayout.setHorizontalGroup(joystickEventsPanelLayout + .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 601, Short.MAX_VALUE)); + joystickEventsPanelLayout.setVerticalGroup(joystickEventsPanelLayout + .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 174, Short.MAX_VALUE)); + + topPanels.add(joystickEventsPanel); + joystickEventsPanel.getAccessibleContext() + .setAccessibleName("Joystick"); + + motionSensingEventsPanel + .setMinimumSize(new java.awt.Dimension(200, 200)); + + rawAccelerationPanel.setToolTipText("Nunchuk MotionSensingEvent"); + + javax.swing.GroupLayout rawAccelerationPanelLayout = new javax.swing.GroupLayout( + rawAccelerationPanel); + rawAccelerationPanel.setLayout(rawAccelerationPanelLayout); + rawAccelerationPanelLayout + .setHorizontalGroup(rawAccelerationPanelLayout + .createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 597, Short.MAX_VALUE)); + rawAccelerationPanelLayout.setVerticalGroup(rawAccelerationPanelLayout + .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 175, Short.MAX_VALUE)); + + motionSensingEventsTabbedPanels.addTab("RawAcceleration", + rawAccelerationPanel); + + javax.swing.GroupLayout orientationPanelLayout = new javax.swing.GroupLayout( + orientationPanel); + orientationPanel.setLayout(orientationPanelLayout); + orientationPanelLayout.setHorizontalGroup(orientationPanelLayout + .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 597, Short.MAX_VALUE)); + orientationPanelLayout.setVerticalGroup(orientationPanelLayout + .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 175, Short.MAX_VALUE)); + + motionSensingEventsTabbedPanels.addTab("Orientation", orientationPanel); + + javax.swing.GroupLayout gForcePanelLayout = new javax.swing.GroupLayout( + gForcePanel); + gForcePanel.setLayout(gForcePanelLayout); + gForcePanelLayout.setHorizontalGroup(gForcePanelLayout + .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 597, Short.MAX_VALUE)); + gForcePanelLayout.setVerticalGroup(gForcePanelLayout + .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 175, Short.MAX_VALUE)); + + motionSensingEventsTabbedPanels.addTab("GForce", gForcePanel); + + javax.swing.GroupLayout motionSensingEventsPanelLayout = new javax.swing.GroupLayout( + motionSensingEventsPanel); + motionSensingEventsPanel.setLayout(motionSensingEventsPanelLayout); + motionSensingEventsPanelLayout + .setHorizontalGroup(motionSensingEventsPanelLayout + .createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(motionSensingEventsTabbedPanels, + javax.swing.GroupLayout.DEFAULT_SIZE, 602, + Short.MAX_VALUE)); + motionSensingEventsPanelLayout + .setVerticalGroup(motionSensingEventsPanelLayout + .createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(motionSensingEventsTabbedPanels, + javax.swing.GroupLayout.DEFAULT_SIZE, 200, + Short.MAX_VALUE)); + + topPanels.add(motionSensingEventsPanel); + + getContentPane().add(topPanels); + + setNunchukValuesPanel.setMinimumSize(new java.awt.Dimension(400, 200)); + setNunchukValuesPanel + .setPreferredSize(new java.awt.Dimension(400, 200)); + setNunchukValuesPanel.setLayout(new javax.swing.BoxLayout( + setNunchukValuesPanel, javax.swing.BoxLayout.Y_AXIS)); + + nunchukButtonsEventPanel.setToolTipText("Nunchuk ButtonsEvent"); + nunchukButtonsEventPanel + .setMinimumSize(new java.awt.Dimension(100, 100)); + nunchukButtonsEventPanel.setPreferredSize(new java.awt.Dimension(100, + 100)); + nunchukButtonsEventPanel.setLayout(new javax.swing.BoxLayout( + nunchukButtonsEventPanel, javax.swing.BoxLayout.LINE_AXIS)); + + cButton.setText("C"); + cButton.setMaximumSize(new java.awt.Dimension(50, 50)); + cButton.setMinimumSize(new java.awt.Dimension(50, 50)); + cButton.setPreferredSize(new java.awt.Dimension(50, 50)); + nunchukButtonsEventPanel.add(cButton); + + zButton.setText("Z"); + zButton.setMaximumSize(new java.awt.Dimension(50, 50)); + zButton.setMinimumSize(new java.awt.Dimension(50, 50)); + zButton.setPreferredSize(new java.awt.Dimension(50, 50)); + nunchukButtonsEventPanel.add(zButton); + + setNunchukValuesPanel.add(nunchukButtonsEventPanel); + + nunchukOrientationTextField.setPreferredSize(new java.awt.Dimension(60, + 20)); + nunchukOrientationPanel.add(nunchukOrientationTextField); + + nunchukOrientationButton.setText("Set Orientation Threshold"); + nunchukOrientationButton + .addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + nunchukOrientationButtonMousePressed(evt); + } + }); + nunchukOrientationPanel.add(nunchukOrientationButton); + + setNunchukValuesPanel.add(nunchukOrientationPanel); + + nunchukAccelerationTextField.setPreferredSize(new java.awt.Dimension( + 60, 20)); + nunchukAccelerationPanel.add(nunchukAccelerationTextField); + + nunchukAccelerationButton.setText("Set Acceleration Threshold"); + nunchukAccelerationButton + .addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + nunchukAccelerationButtonMousePressed(evt); + } + }); + nunchukAccelerationPanel.add(nunchukAccelerationButton); + + setNunchukValuesPanel.add(nunchukAccelerationPanel); + + messageText.setText("Message:"); + + javax.swing.GroupLayout messagePanelLayout = new javax.swing.GroupLayout( + messagePanel); + messagePanel.setLayout(messagePanelLayout); + messagePanelLayout + .setHorizontalGroup(messagePanelLayout + .createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 1216, Short.MAX_VALUE) + .addGroup( + messagePanelLayout + .createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING) + .addGroup( + messagePanelLayout + .createSequentialGroup() + .addGap(0, 0, + Short.MAX_VALUE) + .addComponent( + messageText) + .addGap(0, 0, + Short.MAX_VALUE)))); + messagePanelLayout + .setVerticalGroup(messagePanelLayout + .createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 34, Short.MAX_VALUE) + .addGroup( + messagePanelLayout + .createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING) + .addGroup( + messagePanelLayout + .createSequentialGroup() + .addGap(0, 0, + Short.MAX_VALUE) + .addComponent( + messageText) + .addGap(0, 0, + Short.MAX_VALUE)))); + + setNunchukValuesPanel.add(messagePanel); + + getContentPane().add(setNunchukValuesPanel); + + pack(); + }// //GEN-END:initComponents + + private void nunchukOrientationButtonMousePressed( + java.awt.event.MouseEvent evt) {// GEN-FIRST:event_nunchukOrientationButtonMousePressed + try { + float nb = Float.parseFloat(nunchukOrientationTextField.getText()); + wiimote.setNunchukOrientationThreshold(nb); + messageText.setText("Nunchuk orientation threshold set to " + nb); + } catch (NumberFormatException e) { + messageText + .setText("Number is not an integer, nunchuk orientation threshold not set !"); + } + }// GEN-LAST:event_nunchukOrientationButtonMousePressed + + private void nunchukAccelerationButtonMousePressed( + java.awt.event.MouseEvent evt) {// GEN-FIRST:event_nunchukAccelerationButtonMousePressed + try { + int nb = Integer.parseInt(nunchukAccelerationTextField.getText()); + wiimote.setNunchukAccelerationThreshold(nb); + messageText.setText("Nunchuk acceleration threshold set to " + nb); + } catch (NumberFormatException e) { + messageText + .setText("Number is not an integer, nunchuk acceleration threshold not set !"); + } + }// GEN-LAST:event_nunchukAccelerationButtonMousePressed + + public void onButtonsEvent(WiimoteButtonsEvent arg0) { + // nothing to do + } + + public void onIrEvent(IREvent arg0) { + // nothing to do + } + + public void onMotionSensingEvent(MotionSensingEvent arg0) { + // nothing to do + } + + public void onExpansionEvent(ExpansionEvent arg0) { + if (arg0 instanceof NunchukEvent) { + NunchukEvent nunchuk = (NunchukEvent) arg0; + NunchukButtonsEvent buttons = nunchuk.getButtonsEvent(); + + //C button + if (buttons.isButtonCJustPressed()) { + cButton.setEnabled(false); + }else if (buttons.isButtonCJustReleased()) { + cButton.setEnabled(true); + } + + //Z button + if(buttons.isButtonZJustPressed()) { + zButton.setEnabled(false); + }else if (buttons.isButtonZJustReleased()) { + zButton.setEnabled(true); + } + + + if (isThresholdsRequested) { + MotionSensingEvent evt = nunchuk.getNunchukMotionSensingEvent(); + nunchukAccelerationTextField.setText(evt + .getAccelerationThreshold() + + ""); + nunchukOrientationTextField.setText(evt + .getOrientationThreshold() + + ""); + isThresholdsRequested = false; + } + } + } + + public void onStatusEvent(StatusEvent arg0) { + // nothing to do + } + + public void onDisconnectionEvent(DisconnectionEvent arg0) { + // nothing + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent arg0) { + // nothing + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent arg0) { + // nothing + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) { + // nothing + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) { + // nothing + } + + public void onClassicControllerInsertedEvent( + ClassicControllerInsertedEvent arg0) { + // nothing + } + + public void onClassicControllerRemovedEvent( + ClassicControllerRemovedEvent arg0) { + // nothing + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton cButton; + private javax.swing.JPanel gForcePanel; + private javax.swing.JPanel joystickEventsPanel; + private javax.swing.JPanel messagePanel; + private javax.swing.JLabel messageText; + private javax.swing.JPanel motionSensingEventsPanel; + private javax.swing.JTabbedPane motionSensingEventsTabbedPanels; + private javax.swing.JButton nunchukAccelerationButton; + private javax.swing.JPanel nunchukAccelerationPanel; + private javax.swing.JTextField nunchukAccelerationTextField; + private javax.swing.JPanel nunchukButtonsEventPanel; + private javax.swing.JButton nunchukOrientationButton; + private javax.swing.JPanel nunchukOrientationPanel; + private javax.swing.JTextField nunchukOrientationTextField; + private javax.swing.JPanel orientationPanel; + private javax.swing.JPanel rawAccelerationPanel; + private javax.swing.JPanel setNunchukValuesPanel; + private javax.swing.JPanel topPanels; + private javax.swing.JButton zButton; + // End of variables declaration//GEN-END:variables +} diff --git a/java/src/wiiusej/test/Tests.java b/java/src/wiiusej/test/Tests.java new file mode 100644 index 0000000..fcd4ef0 --- /dev/null +++ b/java/src/wiiusej/test/Tests.java @@ -0,0 +1,389 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.test; + +import java.awt.AWTException; +import java.awt.Robot; +import java.awt.event.InputEvent; + +import wiiusej.WiiUseApiManager; +import wiiusej.Wiimote; +import wiiusej.values.IRSource; +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * This class used to test WiiuseJ in text mode. + * + * @author guiguito + */ +public class Tests implements WiimoteListener { + + Robot robot; + + private static int DISPLAY_EACH_VALUE = 1; + private static int DUMP = 2; + private static int MOVE_MOUSE = 3; + private static int TEST_LEDS = 5; + + private Wiimote wiimote; + + int dump = DISPLAY_EACH_VALUE; + + public Tests(Wiimote wim) { + wiimote = wim; + wiimote.addWiiMoteEventListeners(this); + try { + robot = new Robot(); + } catch (AWTException e) { + e.printStackTrace(); + } + } + + public void onButtonsEvent(WiimoteButtonsEvent e) { + if (dump == DISPLAY_EACH_VALUE) { + // System.out.println("*********** WIIMOTE ID : "+ + // e.getWiimoteId() + " **************"); + /* button ONE */ + if (e.isButtonOneJustPressed()) { + System.out.println("button one pressed"); + } + if (e.isButtonOneHeld()) { + System.out.println("button one held"); + } + if (e.isButtonOneJustReleased()) { + System.out.println("button one released"); + } + + /* button TWO */ + if (e.isButtonTwoJustPressed()) { + System.out.println("button two pressed"); + } + if (e.isButtonTwoHeld()) { + System.out.println("button two held"); + } + if (e.isButtonTwoJustReleased()) { + System.out.println("button two released"); + } + + /* button A */ + if (e.isButtonAJustPressed()) { + System.out.println("button A pressed"); + } + if (e.isButtonAHeld()) { + System.out.println("button A held"); + } + if (e.isButtonAJustReleased()) { + System.out.println("button A released"); + } + + /* button B */ + if (e.isButtonBJustPressed()) { + System.out.println("button B pressed"); + } + if (e.isButtonBHeld()) { + System.out.println("button B held"); + } + if (e.isButtonBJustReleased()) { + System.out.println("button B released"); + } + + /* button LEFT */ + if (e.isButtonLeftJustPressed()) { + System.out.println("button Left pressed"); + } + if (e.isButtonLeftHeld()) { + System.out.println("button Left held"); + } + if (e.isButtonLeftJustReleased()) { + System.out.println("button Left released"); + } + + /* button RIGHT */ + if (e.isButtonRightJustPressed()) { + System.out.println("button Right pressed"); + } + if (e.isButtonRightHeld()) { + System.out.println("button Right held"); + } + if (e.isButtonRightJustReleased()) { + System.out.println("button Right released"); + } + + /* button UP */ + if (e.isButtonUpJustPressed()) { + System.out.println("button UP pressed"); + } + if (e.isButtonUpHeld()) { + System.out.println("button UP held"); + } + if (e.isButtonUpJustReleased()) { + System.out.println("button UP released"); + } + + /* button DOWN */ + if (e.isButtonDownJustPressed()) { + System.out.println("button DOWN pressed"); + } + if (e.isButtonDownHeld()) { + System.out.println("button DOWN held"); + } + if (e.isButtonDownJustReleased()) { + System.out.println("button DOWN released"); + } + + /* button MINUS */ + if (e.isButtonMinusJustPressed()) { + System.out.println("button MINUS pressed"); + } + if (e.isButtonMinusHeld()) { + System.out.println("button MINUS held"); + } + if (e.isButtonMinusJustReleased()) { + System.out.println("button MINUS released"); + } + + /* button PLUS */ + if (e.isButtonPlusJustPressed()) { + System.out.println("button PLUS pressed"); + } + if (e.isButtonPlusHeld()) { + System.out.println("button PLUS held"); + } + if (e.isButtonPlusJustReleased()) { + System.out.println("button PLUS released"); + } + + /* button HOME */ + if (e.isButtonHomeJustPressed()) { + System.out.println("button HOME pressed"); + } + if (e.isButtonHomeHeld()) { + System.out.println("button HOME held"); + } + if (e.isButtonHomeJustReleased()) { + System.out.println("button HOME released"); + } + + /* get status */ + if (e.isButtonUpJustPressed()) { + wiimote.getStatus(); + } + + /* Activate rumble */ + if (e.isButtonOneJustPressed()) { + System.out.println("Rumble Activated"); + wiimote.activateRumble(); + } + if (e.isButtonTwoJustPressed()) { + System.out.println("Rumble Deactivated"); + wiimote.deactivateRumble(); + } + + /* Activate IR Tracking */ + if (e.isButtonAJustPressed()) { + System.out.println("IR Activated"); + wiimote.activateIRTRacking(); + } + if (e.isButtonBJustPressed()) { + System.out.println("IR Deactivated"); + wiimote.deactivateIRTRacking(); + } + + /* Activate Motion sensing */ + if (e.isButtonPlusJustPressed()) { + System.out.println("Motion sensing Activated"); + wiimote.activateMotionSensing(); + } + if (e.isButtonMinusJustPressed()) { + System.out.println("Motion sensing Deactivated"); + wiimote.deactivateMotionSensing(); + } + + /* leave test */ + if (e.isButtonHomeJustPressed()) { + System.out.println("LEAVING TEST"); + wiimote.disconnect(); + WiiUseApiManager.definitiveShutdown(); + } + + } else if (dump == DUMP) { + System.out.println(e); + /* Activate all */ + if (e.isButtonAJustPressed()) { + System.out.println("IR, rumble and motion sensing Activated"); + wiimote.activateIRTRacking(); + wiimote.activateMotionSensing(); + wiimote.activateRumble(); + } + if (e.isButtonBJustPressed()) { + System.out.println("IR, rumble and motion sensing Deactivated"); + wiimote.deactivateIRTRacking(); + wiimote.deactivateMotionSensing(); + wiimote.deactivateRumble(); + } + + /* leave test */ + if (e.isButtonHomeJustPressed()) { + System.out.println("LEAVING TEST"); + wiimote.disconnect(); + } + } else if (dump == MOVE_MOUSE) { + /* Activate IR Tracking */ + if (e.isButtonOneJustPressed()) { + System.out.println("IR Activated"); + wiimote.activateIRTRacking(); + } + if (e.isButtonTwoJustPressed()) { + System.out.println("IR Deactivated"); + wiimote.deactivateIRTRacking(); + } + + /* button A */ + if (e.isButtonAJustPressed()) { + robot.mousePress(InputEvent.BUTTON1_MASK); + } + if (e.isButtonAJustReleased()) { + robot.mouseRelease(InputEvent.BUTTON1_MASK); + } + + /* button B */ + if (e.isButtonBJustPressed()) { + robot.mousePress(InputEvent.BUTTON2_MASK); + } + if (e.isButtonBJustReleased()) { + robot.mouseRelease(InputEvent.BUTTON2_MASK); + } + + /* leave test */ + if (e.isButtonHomeJustPressed()) { + System.out.println("LEAVING TEST"); + wiimote.disconnect(); + } + } else if (dump == TEST_LEDS) { + wiimote.activateMotionSensing(); + if (e.isButtonUpJustPressed()) { + wiimote.setLeds(true, false, false, false); + } + if (e.isButtonDownJustPressed()) { + wiimote.setLeds(false, true, false, false); + } + if (e.isButtonLeftJustPressed()) { + wiimote.setLeds(false, false, true, false); + } + if (e.isButtonRightJustPressed()) { + wiimote.setLeds(false, false, false, true); + } + + /* leave test */ + if (e.isButtonHomeJustPressed()) { + System.out.println("LEAVING TEST"); + wiimote.disconnect(); + } + } + + } + + public void onIrEvent(IREvent e) { + if (dump == MOVE_MOUSE) { + IRSource[] list = e.getIRPoints(); + if (list.length > 0) { + int x1 = (int) list[0].getX(); + int y1 = (int) list[0].getY(); + + int mousex = (int) Math.round(((double) x1 / 1024.0) * 1280.0); + int mousey = (int) Math.round(((double) y1 / 768.0) * 1024.0); + robot.mouseMove(mousex, mousey); + } + } else { + System.out.println(e); + } + } + + public void onMotionSensingEvent(MotionSensingEvent e) { + /* display motion sensing */ + System.out.println(e); + } + + public void onExpansionEvent(ExpansionEvent e) { + System.out.println(e); + } + + public void onStatusEvent(StatusEvent e) { + // Display status variables + System.out.println(e); + } + + public void onDisconnectionEvent(DisconnectionEvent e) { + System.out.println(" wiimote " + e.getWiimoteId() + + "has been disconnected !!"); + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent e) { + System.out.println(e); + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent e) { + System.out.println(e); + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent e) { + System.out.println(e); + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent e) { + System.out.println(e); + } + + public void onClassicControllerInsertedEvent( + ClassicControllerInsertedEvent e) { + System.out.println(e); + } + + public void onClassicControllerRemovedEvent(ClassicControllerRemovedEvent e) { + System.out.println(e); + } + + /** + * @param args + */ + public static void main(String[] args) { + Wiimote[] wiimotes = WiiUseApiManager.getWiimotes(1, true); + if (wiimotes.length > 0) { + System.out.println(wiimotes[0]); + new Tests(wiimotes[0]); + } else { + System.out.println("No wiimotes found !!!"); + } + + // java.util.Timer timer = new java.util.Timer(); + // timer.scheduleAtFixedRate(new LedsTask(), 0, 100); + + } + +} diff --git a/java/src/wiiusej/test/WiiuseJGuiTest.java b/java/src/wiiusej/test/WiiuseJGuiTest.java new file mode 100644 index 0000000..54dc777 --- /dev/null +++ b/java/src/wiiusej/test/WiiuseJGuiTest.java @@ -0,0 +1,1379 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.test; + +import java.awt.AWTException; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.swing.JFrame; +import wiiusej.WiiUseApiManager; +import wiiusej.Wiimote; +import wiiusej.utils.AccelerationPanel; +import wiiusej.utils.AccelerationWiimoteEventPanel; +import wiiusej.utils.ButtonsEventPanel; +import wiiusej.utils.GForcePanel; +import wiiusej.utils.IRPanel; +import wiiusej.utils.OrientationPanel; +import wiiusej.utils.OrientationWiimoteEventPanel; +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * Gui class to test WiiuseJ. + * + * @author guiguito + */ +public class WiiuseJGuiTest extends javax.swing.JFrame implements + WiimoteListener { + + private Wiimote wiimote; + private Robot robot = null; + private boolean statusMotionRequested = false; + private boolean statusIRRequested = false; + private JFrame expansionFrame = null; + private boolean isFirstStatusGot = false; + private WindowListener buttonSetter = new WindowListener() { + + public void windowOpened(WindowEvent e) { + // nothing + } + + public void windowClosing(WindowEvent e) { + // nothing + } + + public void windowClosed(WindowEvent e) { + // nothing + } + + public void windowIconified(WindowEvent e) { + // nothing + } + + public void windowDeiconified(WindowEvent e) { + // nothing + } + + public void windowActivated(WindowEvent e) { + showExpansionWiimoteButton.setEnabled(false); + if (expansionFrame instanceof NunchukGuiTest){ + showExpansionWiimoteButton.setText("Hide Nunchuk"); + }else if(expansionFrame instanceof GuitarHero3GuiTest){ + showExpansionWiimoteButton.setText("Hide Guitar"); + }else if(expansionFrame instanceof ClassicControllerGuiTest){ + showExpansionWiimoteButton.setText("Hide Classic Controller"); + } + } + + public void windowDeactivated(WindowEvent e) { + showExpansionWiimoteButton.setEnabled(true); + if (expansionFrame instanceof NunchukGuiTest){ + showExpansionWiimoteButton.setText("Show Nunchuk"); + }else if(expansionFrame instanceof GuitarHero3GuiTest){ + showExpansionWiimoteButton.setText("Show Guitar"); + }else if(expansionFrame instanceof ClassicControllerGuiTest){ + showExpansionWiimoteButton.setText("Show Classic controller"); + } + } + }; + + /** + * default constructor + */ + public WiiuseJGuiTest() { + initComponents(); + this.addWindowListener(new CloseGuiTestCleanly()); + } + + /** + * Creates new form WiiuseJGuiTest + */ + public WiiuseJGuiTest(Wiimote wiimote) { + initComponents(); + this.addWindowListener(new CloseGuiTestCleanly()); + if (wiimote != null) { + this.wiimote = wiimote; + registerListeners(); + initWiimote(); + isFirstStatusGot = false; + getStatusButtonMousePressed(null); + } + } + + /** + * Clear all views + */ + private void clearViews() { + ((IRPanel) irViewPanel).clearView(); + ((ButtonsEventPanel) buttonsPanel).clearView(); + ((OrientationPanel) motionSensingPanel).clearView(); + ((GForcePanel) gForcePanel).clearView(); + ((AccelerationPanel) accelerationPanel).clearView(); + } + + /** + * Unregister all listeners. + */ + private void unregisterListeners() { + wiimote.removeWiiMoteEventListeners((IRPanel) irViewPanel); + wiimote.removeWiiMoteEventListeners((ButtonsEventPanel) buttonsPanel); + wiimote + .removeWiiMoteEventListeners((OrientationPanel) motionSensingPanel); + wiimote.removeWiiMoteEventListeners((GForcePanel) gForcePanel); + wiimote + .removeWiiMoteEventListeners((AccelerationPanel) accelerationPanel); + wiimote.removeWiiMoteEventListeners(this); + } + + private void initWiimote() { + wiimote.deactivateContinuous(); + wiimote.deactivateSmoothing(); + wiimote.setScreenAspectRatio169(); + wiimote.setSensorBarBelowScreen(); + } + + /** + * Register all listeners + */ + private void registerListeners() { + wiimote.addWiiMoteEventListeners((IRPanel) irViewPanel); + wiimote.addWiiMoteEventListeners((ButtonsEventPanel) buttonsPanel); + wiimote.addWiiMoteEventListeners((OrientationPanel) motionSensingPanel); + wiimote.addWiiMoteEventListeners((GForcePanel) gForcePanel); + wiimote.addWiiMoteEventListeners((AccelerationPanel) accelerationPanel); + wiimote.addWiiMoteEventListeners(this); + + } + + public void onButtonsEvent(WiimoteButtonsEvent arg0) { + if (robot != null) { + if (arg0.isButtonAPressed()) { + robot.mousePress(InputEvent.BUTTON1_MASK); + + } + if (arg0.isButtonBPressed()) { + robot.mousePress(InputEvent.BUTTON2_MASK); + + } + if (arg0.isButtonOnePressed()) { + robot.mousePress(InputEvent.BUTTON3_MASK); + + } + if (arg0.isButtonAJustReleased()) { + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + } + if (arg0.isButtonBJustReleased()) { + robot.mouseRelease(InputEvent.BUTTON2_MASK); + + } + if (arg0.isButtonOneJustReleased()) { + robot.mouseRelease(InputEvent.BUTTON3_MASK); + + } + if (arg0.isButtonUpPressed()) {// mouse wheel up + robot.mouseWheel(-1); + } + if (arg0.isButtonDownPressed()) {// mouse wheel down + robot.mouseWheel(1); + } + + if (arg0.isButtonTwoPressed()) {// stop mouse control + mouseIRControlButtonMousePressed(null); + } + } + } + + public void onIrEvent(IREvent arg0) { + if (robot != null) {// if mouse control activated + robot.mouseMove(arg0.getX(), arg0.getY()); + } + if (statusIRRequested) { + xResolutionTextField.setText("" + arg0.getXVRes()); + yResolutionTextField.setText("" + arg0.getYVRes()); + statusIRRequested = false; + } + } + + public void onMotionSensingEvent(MotionSensingEvent arg0) { + if (statusMotionRequested) {// Status requested + accelerationThresholdTextField.setText("" + + arg0.getAccelerationThreshold()); + orientationThresholdTextField.setText("" + + arg0.getOrientationThreshold()); + alphaSmoothingTextField.setText("" + arg0.getAlphaSmoothing()); + statusMotionRequested = false; + } + } + + public void onExpansionEvent(ExpansionEvent e) { + // nothing yet + } + + public void onStatusEvent(StatusEvent arg0) { + if (!isFirstStatusGot) { + if (arg0.isNunchukConnected()) { + showExpansionWiimoteButton.setEnabled(true); + showExpansionWiimoteButton.setText("Show Nunchuk"); + expansionFrame = new NunchukGuiTest(wiimote); + expansionFrame + .setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + expansionFrame.addWindowListener(buttonSetter); + isFirstStatusGot = true; + }else if(arg0.isClassicControllerConnected()){ + showExpansionWiimoteButton.setEnabled(true); + showExpansionWiimoteButton.setText("Show Classic Controller"); + expansionFrame = new ClassicControllerGuiTest(wiimote); + expansionFrame + .setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + expansionFrame.addWindowListener(buttonSetter); + isFirstStatusGot = true; + } + else if(arg0.isGuitarHeroConnected()){ + showExpansionWiimoteButton.setEnabled(true); + showExpansionWiimoteButton.setText("Show Guitar Hero 3 Controller"); + expansionFrame = new GuitarHero3GuiTest(wiimote); + expansionFrame + .setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + expansionFrame.addWindowListener(buttonSetter); + isFirstStatusGot = true; + } + } + messageText.setText("Status received !"); + batteryLevelText.setText(arg0.getBatteryLevel() + " %"); + led1Button.setEnabled(arg0.isLed1Set()); + led2Button.setEnabled(arg0.isLed2Set()); + led3Button.setEnabled(arg0.isLed3Set()); + led4Button.setEnabled(arg0.isLed4Set()); + if (arg0.isNunchukConnected()) { + ((NunchukGuiTest) expansionFrame).requestThresholdsUpdate(); + } + // attachments + int eventType = arg0.getEventType(); + if (eventType == StatusEvent.WIIUSE_CLASSIC_CTRL_INSERTED) { + expansionText.setText("Classic control connected."); + } else if (eventType == StatusEvent.WIIUSE_CLASSIC_CTRL_REMOVED) { + expansionText.setText("Classic control removed."); + } else if (eventType == StatusEvent.WIIUSE_NUNCHUK_INSERTED) { + expansionText.setText("Nunchuk connected."); + } else if (eventType == StatusEvent.WIIUSE_NUNCHUK_REMOVED) { + expansionText.setText("Nunchuk removed."); + } else if (eventType == StatusEvent.WIIUSE_GUITAR_HERO_3_CTRL_INSERTED) { + expansionText.setText("Guitar Hero 3 control connected."); + } else if (eventType == StatusEvent.WIIUSE_GUITAR_HERO_3_CTRL_REMOVED) { + expansionText.setText("Guitar Hero 3 control removed."); + } + } + + public void onDisconnectionEvent(DisconnectionEvent arg0) { + messageText.setText("Wiimote Disconnected !"); + unregisterListeners(); + clearViews(); + isFirstStatusGot = false; + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent e) { + messageText.setText("Nunchuk connected !"); + expansionText.setText("Expansion connected : Nunchuk."); + showExpansionWiimoteButton.setEnabled(true); + showExpansionWiimoteButton.setText("Show nunchuk"); + expansionFrame = new NunchukGuiTest(wiimote); + expansionFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + expansionFrame.addWindowListener(buttonSetter); + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent e) { + messageText.setText("Nunchuk disconnected !"); + expansionText.setText("No expansion connected."); + showExpansionWiimoteButton.setEnabled(false); + showExpansionWiimoteButton.setText("No expansion"); + if (expansionFrame != null) { + if (expansionFrame instanceof NunchukGuiTest) { + ((NunchukGuiTest) expansionFrame).unRegisterListeners(); + } + expansionFrame.setEnabled(false); + expansionFrame.dispose(); + expansionFrame = null; + } + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) { + messageText.setText("Guitar Hero 3 connected !"); + expansionText.setText("Expansion connected : Guitar Hero 3."); + showExpansionWiimoteButton.setEnabled(true); + showExpansionWiimoteButton.setText("Show Guitar Hero 3"); + expansionFrame = new GuitarHero3GuiTest(wiimote); + expansionFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + expansionFrame.addWindowListener(buttonSetter); + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) { + messageText.setText("Guitar Hero 3 disconnected !"); + expansionText.setText("No expansion connected."); + showExpansionWiimoteButton.setEnabled(false); + showExpansionWiimoteButton.setText("No expansion"); + if (expansionFrame != null) { + if (expansionFrame instanceof GuitarHero3GuiTest) { + ((GuitarHero3GuiTest) expansionFrame).unRegisterListeners(); + } + expansionFrame.setEnabled(false); + expansionFrame.dispose(); + expansionFrame = null; + } + } + + public void onClassicControllerInsertedEvent( + ClassicControllerInsertedEvent arg0) { + messageText.setText("Classic controller connected !"); + expansionText.setText("Expansion connected : Classic Controller."); + showExpansionWiimoteButton.setEnabled(true); + showExpansionWiimoteButton.setText("Show Classic Controller"); + expansionFrame = new ClassicControllerGuiTest(wiimote); + expansionFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + expansionFrame.addWindowListener(buttonSetter); + } + + public void onClassicControllerRemovedEvent( + ClassicControllerRemovedEvent arg0) { + messageText.setText("Classic controller disconnected !"); + expansionText.setText("No expansion connected."); + showExpansionWiimoteButton.setEnabled(false); + showExpansionWiimoteButton.setText("No expansion"); + if (expansionFrame != null) { + if (expansionFrame instanceof ClassicControllerGuiTest) { + ((ClassicControllerGuiTest) expansionFrame).unRegisterListeners(); + } + expansionFrame.setEnabled(false); + expansionFrame.dispose(); + expansionFrame = null; + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + leftPanel = new javax.swing.JPanel(); + irViewPanel = new IRPanel(); + jTabbedPane1 = new javax.swing.JTabbedPane(); + accelerationPanel = new AccelerationWiimoteEventPanel(); + motionSensingPanel = new OrientationWiimoteEventPanel(); + gForcePanel = new wiiusej.utils.GForceWiimoteEventPanel(); + rightPanel = new javax.swing.JPanel(); + fixedWiimotePanel = new javax.swing.JPanel(); + buttonsPanel = new ButtonsEventPanel(); + controlsPanel = new javax.swing.JPanel(); + activateRumbleIRPanel = new javax.swing.JPanel(); + toggleRumbleButton = new javax.swing.JButton(); + toggleIRTrackingButton = new javax.swing.JButton(); + activateMotionSensingPanel = new javax.swing.JPanel(); + toggleMotionSensingTrackingButton = new javax.swing.JButton(); + activateSmoothingContinuousPanel = new javax.swing.JPanel(); + toggleSmoothingButton = new javax.swing.JButton(); + toggleContinuousButton = new javax.swing.JButton(); + setLedsPanel = new javax.swing.JPanel(); + led1Button = new javax.swing.JButton(); + led2Button = new javax.swing.JButton(); + led3Button = new javax.swing.JButton(); + led4Button = new javax.swing.JButton(); + setLedsButton = new javax.swing.JButton(); + setAlphaSmoothingPanel = new javax.swing.JPanel(); + alphaSmoothingTextField = new javax.swing.JTextField(); + alphaSmoothingButton = new javax.swing.JButton(); + setOrientationThresholdPanel = new javax.swing.JPanel(); + orientationThresholdTextField = new javax.swing.JTextField(); + orientationThresholdButton = new javax.swing.JButton(); + setAccelerationThresholdPanel = new javax.swing.JPanel(); + accelerationThresholdTextField = new javax.swing.JTextField(); + accelerationThresholdButton = new javax.swing.JButton(); + getStatusPanel = new javax.swing.JPanel(); + getStatusButton = new javax.swing.JButton(); + batteryText = new javax.swing.JLabel(); + batteryLevelText = new javax.swing.JLabel(); + setIrSensitivyPanel = new javax.swing.JPanel(); + setIrSensitivySpinner = new javax.swing.JSpinner(); + setIrSensitivyButton = new javax.swing.JButton(); + setTimeoutButton = new javax.swing.JButton(); + setTimeoutPanel = new javax.swing.JPanel(); + normalTimeoutSpinner = new javax.swing.JSpinner(); + normalTimeoutText = new javax.swing.JLabel(); + expansionHandshakeTimeoutSpinner = new javax.swing.JSpinner(); + expansionHandshakeTimeoutText = new javax.swing.JLabel(); + setIRConfPanel = new javax.swing.JPanel(); + toggleSensorBarPositionButton = new javax.swing.JButton(); + toggleScreenAspectRatioButton = new javax.swing.JButton(); + setVirtualResolutionPanel = new javax.swing.JPanel(); + xLabel = new javax.swing.JLabel(); + xResolutionTextField = new javax.swing.JTextField(); + yLabel = new javax.swing.JLabel(); + yResolutionTextField = new javax.swing.JTextField(); + setVirtualResolutionButton = new javax.swing.JButton(); + startMouseControlPanel = new javax.swing.JPanel(); + mouseIRControlButton = new javax.swing.JButton(); + exPansionPanel = new javax.swing.JPanel(); + expansionText = new javax.swing.JLabel(); + expansionButtonPanel = new javax.swing.JPanel(); + showExpansionWiimoteButton = new javax.swing.JButton(); + showExpansionWiimoteButton.setEnabled(false); + messagesPanel = new javax.swing.JPanel(); + reconnectWiimotesButton = new javax.swing.JButton(); + messageLabelText = new javax.swing.JLabel(); + messageText = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setTitle("WiiuseJ Test GUI"); + setName("WiiuseJ Test GUI"); // NOI18N + + leftPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + + irViewPanel.setBackground(new java.awt.Color(0, 0, 0)); + irViewPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 153, 153), 2, true), "IR View", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 11), new java.awt.Color(255, 0, 51))); + irViewPanel.setToolTipText("IREvent"); + + javax.swing.GroupLayout irViewPanelLayout = new javax.swing.GroupLayout(irViewPanel); + irViewPanel.setLayout(irViewPanelLayout); + irViewPanelLayout.setHorizontalGroup( + irViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 272, Short.MAX_VALUE) + ); + irViewPanelLayout.setVerticalGroup( + irViewPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 299, Short.MAX_VALUE) + ); + + accelerationPanel.setToolTipText("MotionSensingEvent"); + + javax.swing.GroupLayout accelerationPanelLayout = new javax.swing.GroupLayout(accelerationPanel); + accelerationPanel.setLayout(accelerationPanelLayout); + accelerationPanelLayout.setHorizontalGroup( + accelerationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 279, Short.MAX_VALUE) + ); + accelerationPanelLayout.setVerticalGroup( + accelerationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 213, Short.MAX_VALUE) + ); + + jTabbedPane1.addTab("Acceleration", accelerationPanel); + + javax.swing.GroupLayout motionSensingPanelLayout = new javax.swing.GroupLayout(motionSensingPanel); + motionSensingPanel.setLayout(motionSensingPanelLayout); + motionSensingPanelLayout.setHorizontalGroup( + motionSensingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 279, Short.MAX_VALUE) + ); + motionSensingPanelLayout.setVerticalGroup( + motionSensingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 213, Short.MAX_VALUE) + ); + + jTabbedPane1.addTab("Orientation", motionSensingPanel); + + javax.swing.GroupLayout gForcePanelLayout = new javax.swing.GroupLayout(gForcePanel); + gForcePanel.setLayout(gForcePanelLayout); + gForcePanelLayout.setHorizontalGroup( + gForcePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 279, Short.MAX_VALUE) + ); + gForcePanelLayout.setVerticalGroup( + gForcePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 213, Short.MAX_VALUE) + ); + + jTabbedPane1.addTab("GForce", gForcePanel); + + javax.swing.GroupLayout leftPanelLayout = new javax.swing.GroupLayout(leftPanel); + leftPanel.setLayout(leftPanelLayout); + leftPanelLayout.setHorizontalGroup( + leftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(irViewPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 284, Short.MAX_VALUE) + ); + leftPanelLayout.setVerticalGroup( + leftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, leftPanelLayout.createSequentialGroup() + .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 238, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(irViewPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jTabbedPane1.getAccessibleContext().setAccessibleName("Orientation"); + + rightPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + rightPanel.setLayout(new javax.swing.BoxLayout(rightPanel, javax.swing.BoxLayout.LINE_AXIS)); + + fixedWiimotePanel.setMaximumSize(new java.awt.Dimension(120, 32767)); + fixedWiimotePanel.setMinimumSize(new java.awt.Dimension(120, 100)); + fixedWiimotePanel.setPreferredSize(new java.awt.Dimension(120, 100)); + fixedWiimotePanel.setRequestFocusEnabled(false); + fixedWiimotePanel.setLayout(null); + + buttonsPanel.setMaximumSize(new java.awt.Dimension(120, 484)); + buttonsPanel.setMinimumSize(new java.awt.Dimension(120, 484)); + buttonsPanel.setOpaque(false); + buttonsPanel.setPreferredSize(new java.awt.Dimension(120, 484)); + + javax.swing.GroupLayout buttonsPanelLayout = new javax.swing.GroupLayout(buttonsPanel); + buttonsPanel.setLayout(buttonsPanelLayout); + buttonsPanelLayout.setHorizontalGroup( + buttonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 120, Short.MAX_VALUE) + ); + buttonsPanelLayout.setVerticalGroup( + buttonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 484, Short.MAX_VALUE) + ); + + fixedWiimotePanel.add(buttonsPanel); + buttonsPanel.setBounds(0, 0, 120, 484); + + rightPanel.add(fixedWiimotePanel); + + controlsPanel.setMinimumSize(new java.awt.Dimension(100, 264)); + controlsPanel.setPreferredSize(new java.awt.Dimension(190, 264)); + controlsPanel.setLayout(new java.awt.GridLayout(16, 1)); + + toggleRumbleButton.setText("Activate Rumble"); + toggleRumbleButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + toggleRumbleButtonMousePressed(evt); + } + }); + activateRumbleIRPanel.add(toggleRumbleButton); + + toggleIRTrackingButton.setText("Activate IR Tracking"); + toggleIRTrackingButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + toggleIRTrackingButtonMousePressed(evt); + } + }); + activateRumbleIRPanel.add(toggleIRTrackingButton); + + controlsPanel.add(activateRumbleIRPanel); + + toggleMotionSensingTrackingButton.setText("Activate motion sensing Tracking"); + toggleMotionSensingTrackingButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + toggleMotionSensingTrackingButtonMousePressed(evt); + } + }); + activateMotionSensingPanel.add(toggleMotionSensingTrackingButton); + + controlsPanel.add(activateMotionSensingPanel); + + toggleSmoothingButton.setText("Activate Smoothing"); + toggleSmoothingButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + toggleSmoothingButtonMousePressed(evt); + } + }); + activateSmoothingContinuousPanel.add(toggleSmoothingButton); + + toggleContinuousButton.setText("Activate Continuous"); + toggleContinuousButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + toggleContinuousButtonMousePressed(evt); + } + }); + activateSmoothingContinuousPanel.add(toggleContinuousButton); + + controlsPanel.add(activateSmoothingContinuousPanel); + + led1Button.setText("Led1"); + led1Button.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + led1ButtonMousePressed(evt); + } + }); + setLedsPanel.add(led1Button); + + led2Button.setText("Led2"); + led2Button.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + led2ButtonMousePressed(evt); + } + }); + setLedsPanel.add(led2Button); + + led3Button.setText("Led3"); + led3Button.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + led3ButtonMousePressed(evt); + } + }); + setLedsPanel.add(led3Button); + + led4Button.setText("Led4"); + led4Button.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + led4ButtonMousePressed(evt); + } + }); + setLedsPanel.add(led4Button); + + setLedsButton.setText("Set leds"); + setLedsButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + setLedsButtonMousePressed(evt); + } + }); + setLedsPanel.add(setLedsButton); + + controlsPanel.add(setLedsPanel); + + alphaSmoothingTextField.setMinimumSize(new java.awt.Dimension(100, 20)); + alphaSmoothingTextField.setPreferredSize(new java.awt.Dimension(100, 20)); + setAlphaSmoothingPanel.add(alphaSmoothingTextField); + + alphaSmoothingButton.setText("Set alpha smoothing"); + alphaSmoothingButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + alphaSmoothingButtonMousePressed(evt); + } + }); + setAlphaSmoothingPanel.add(alphaSmoothingButton); + + controlsPanel.add(setAlphaSmoothingPanel); + + orientationThresholdTextField.setMinimumSize(new java.awt.Dimension(100, 20)); + orientationThresholdTextField.setPreferredSize(new java.awt.Dimension(100, 20)); + setOrientationThresholdPanel.add(orientationThresholdTextField); + + orientationThresholdButton.setText("Set orientation threshold"); + orientationThresholdButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + orientationThresholdButtonMousePressed(evt); + } + }); + setOrientationThresholdPanel.add(orientationThresholdButton); + + controlsPanel.add(setOrientationThresholdPanel); + + accelerationThresholdTextField.setPreferredSize(new java.awt.Dimension(100, 20)); + setAccelerationThresholdPanel.add(accelerationThresholdTextField); + + accelerationThresholdButton.setText("Set acceleration threshold"); + accelerationThresholdButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + accelerationThresholdButtonMousePressed(evt); + } + }); + setAccelerationThresholdPanel.add(accelerationThresholdButton); + + controlsPanel.add(setAccelerationThresholdPanel); + + getStatusButton.setText("Get status"); + getStatusButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + getStatusButtonMousePressed(evt); + } + }); + getStatusPanel.add(getStatusButton); + + batteryText.setFont(new java.awt.Font("Tahoma", 0, 14)); + batteryText.setText("Battery level :"); + getStatusPanel.add(batteryText); + + batteryLevelText.setFont(new java.awt.Font("Arial", 0, 14)); + batteryLevelText.setText(" %"); + getStatusPanel.add(batteryLevelText); + + controlsPanel.add(getStatusPanel); + + setIrSensitivySpinner.setPreferredSize(new java.awt.Dimension(50, 18)); + setIrSensitivySpinner.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + setIrSensitivySpinnerStateChanged(evt); + } + }); + setIrSensitivyPanel.add(setIrSensitivySpinner); + + setIrSensitivyButton.setText("SetIrSensivity"); + setIrSensitivyButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + setIrSensitivyButtonMousePressed(evt); + } + }); + setIrSensitivyPanel.add(setIrSensitivyButton); + + setTimeoutButton.setText("Set timeouts in ms"); + setTimeoutButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + setTimeoutButtonMousePressed(evt); + } + }); + setIrSensitivyPanel.add(setTimeoutButton); + + controlsPanel.add(setIrSensitivyPanel); + + normalTimeoutSpinner.setPreferredSize(new java.awt.Dimension(40, 18)); + normalTimeoutSpinner.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + normalTimeoutSpinnerStateChanged(evt); + } + }); + setTimeoutPanel.add(normalTimeoutSpinner); + + normalTimeoutText.setText("Normal timeout"); + setTimeoutPanel.add(normalTimeoutText); + + expansionHandshakeTimeoutSpinner.setPreferredSize(new java.awt.Dimension(40, 18)); + expansionHandshakeTimeoutSpinner.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + expansionHandshakeTimeoutSpinnerStateChanged(evt); + } + }); + setTimeoutPanel.add(expansionHandshakeTimeoutSpinner); + + expansionHandshakeTimeoutText.setText("Expansion handshake timeout"); + setTimeoutPanel.add(expansionHandshakeTimeoutText); + + controlsPanel.add(setTimeoutPanel); + + toggleSensorBarPositionButton.setText("Set sensor bar above"); + toggleSensorBarPositionButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + toggleSensorBarPositionButtonMousePressed(evt); + } + }); + setIRConfPanel.add(toggleSensorBarPositionButton); + + toggleScreenAspectRatioButton.setText("Set screen aspect ratio 4/3"); + toggleScreenAspectRatioButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + toggleScreenAspectRatioButtonMousePressed(evt); + } + }); + setIRConfPanel.add(toggleScreenAspectRatioButton); + + controlsPanel.add(setIRConfPanel); + + xLabel.setText("X"); + setVirtualResolutionPanel.add(xLabel); + + xResolutionTextField.setMinimumSize(new java.awt.Dimension(40, 20)); + xResolutionTextField.setPreferredSize(new java.awt.Dimension(40, 20)); + setVirtualResolutionPanel.add(xResolutionTextField); + + yLabel.setText("Y"); + setVirtualResolutionPanel.add(yLabel); + + yResolutionTextField.setFocusTraversalPolicyProvider(true); + yResolutionTextField.setMinimumSize(new java.awt.Dimension(40, 20)); + yResolutionTextField.setPreferredSize(new java.awt.Dimension(40, 20)); + setVirtualResolutionPanel.add(yResolutionTextField); + + setVirtualResolutionButton.setText("Set virtual resolution"); + setVirtualResolutionButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + setVirtualResolutionButtonMousePressed(evt); + } + }); + setVirtualResolutionPanel.add(setVirtualResolutionButton); + + controlsPanel.add(setVirtualResolutionPanel); + + mouseIRControlButton.setText("Start infrared mouse control"); + mouseIRControlButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + mouseIRControlButtonMousePressed(evt); + } + }); + startMouseControlPanel.add(mouseIRControlButton); + + controlsPanel.add(startMouseControlPanel); + + expansionText.setText("No expansion connected."); + exPansionPanel.add(expansionText); + + controlsPanel.add(exPansionPanel); + + showExpansionWiimoteButton.setText("No expansion connected"); + showExpansionWiimoteButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + showExpansionWiimoteButtonMousePressed(evt); + } + }); + expansionButtonPanel.add(showExpansionWiimoteButton); + + controlsPanel.add(expansionButtonPanel); + + reconnectWiimotesButton.setText("Reconnect wiimote"); + reconnectWiimotesButton.addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + reconnectWiimotesButtonMousePressed(evt); + } + }); + messagesPanel.add(reconnectWiimotesButton); + + messageLabelText.setFont(new java.awt.Font("Tahoma", 0, 14)); + messageLabelText.setText("Message : "); + messagesPanel.add(messageLabelText); + + messageText.setFont(new java.awt.Font("Arial", 0, 14)); + messageText.setText("None"); + messagesPanel.add(messageText); + + controlsPanel.add(messagesPanel); + + rightPanel.add(controlsPanel); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(leftPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(rightPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 498, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(leftPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(rightPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 573, Short.MAX_VALUE) + ); + + java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); + setBounds((screenSize.width-800)/2, (screenSize.height-600)/2, 800, 600); + }// //GEN-END:initComponents + + private void toggleRumbleButtonMousePressed(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_toggleRumbleButtonMousePressed + if (toggleRumbleButton.isEnabled()) { + wiimote.activateRumble(); + toggleRumbleButton.setEnabled(false); + toggleRumbleButton.setText("Deactivate Rumble"); + messageText.setText("Rumble activated"); + } else { + wiimote.deactivateRumble(); + toggleRumbleButton.setEnabled(true); + toggleRumbleButton.setText("Activate Rumble"); + messageText.setText("Rumble deactivated"); + } + }// GEN-LAST:event_toggleRumbleButtonMousePressed + + private void toggleIRTrackingButtonMousePressed( + java.awt.event.MouseEvent evt) {// GEN-FIRST:event_toggleIRTrackingButtonMousePressed + if (toggleIRTrackingButton.isEnabled()) { + wiimote.activateIRTRacking(); + toggleIRTrackingButton.setEnabled(false); + toggleIRTrackingButton.setText("Deactivate IR Tracking"); + messageText.setText("IR Tracking activated"); + } else { + wiimote.deactivateIRTRacking(); + toggleIRTrackingButton.setEnabled(true); + toggleIRTrackingButton.setText("Activate IR Tracking"); + ((IRPanel) irViewPanel).onDisconnectionEvent(null); + messageText.setText("IR Tracking deactivated"); + } + }// GEN-LAST:event_toggleIRTrackingButtonMousePressed + + private void toggleMotionSensingTrackingButtonMousePressed( + java.awt.event.MouseEvent evt) {// GEN-FIRST:event_toggleMotionSensingTrackingButtonMousePressed + if (toggleMotionSensingTrackingButton.isEnabled()) { + wiimote.activateMotionSensing(); + toggleMotionSensingTrackingButton.setEnabled(false); + toggleMotionSensingTrackingButton + .setText("Deactivate Motion Sensing"); + messageText.setText("Motion Sensing activated"); + } else { + wiimote.deactivateMotionSensing(); + toggleMotionSensingTrackingButton.setEnabled(true); + toggleMotionSensingTrackingButton + .setText("Activate Motion Sensing"); + ((OrientationPanel) motionSensingPanel).onDisconnectionEvent(null); + ((GForcePanel) gForcePanel).onDisconnectionEvent(null); + messageText.setText("Motion Sensing deactivated"); + } + }// GEN-LAST:event_toggleMotionSensingTrackingButtonMousePressed + + private void toggleSmoothingButtonMousePressed(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_toggleSmoothingButtonMousePressed + if (toggleSmoothingButton.isEnabled()) { + wiimote.activateSmoothing(); + toggleSmoothingButton.setEnabled(false); + toggleSmoothingButton.setText("Deactivate Alpha Smoothing"); + messageText.setText("Alpha Smoothing activated"); + } else { + wiimote.deactivateSmoothing(); + toggleSmoothingButton.setEnabled(true); + toggleSmoothingButton.setText("Activate Alpha Smoothing"); + messageText.setText("Alpha Smoothing deactivated"); + } + }// GEN-LAST:event_toggleSmoothingButtonMousePressed + + private void toggleContinuousButtonMousePressed( + java.awt.event.MouseEvent evt) {// GEN-FIRST:event_toggleContinuousButtonMousePressed + if (toggleContinuousButton.isEnabled()) { + wiimote.activateContinuous(); + toggleContinuousButton.setEnabled(false); + toggleContinuousButton.setText("Deactivate Continuous"); + messageText.setText("Continuous activated"); + } else { + wiimote.deactivateContinuous(); + toggleContinuousButton.setEnabled(true); + toggleContinuousButton.setText("Activate Continuous"); + messageText.setText("Continuous deactivated"); + } + }// GEN-LAST:event_toggleContinuousButtonMousePressed + + private void led1ButtonMousePressed(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_led1ButtonMousePressed + if (led1Button.isEnabled()) { + led1Button.setEnabled(false); + } else { + led1Button.setEnabled(true); + } + }// GEN-LAST:event_led1ButtonMousePressed + + private void led2ButtonMousePressed(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_led2ButtonMousePressed + if (led2Button.isEnabled()) { + led2Button.setEnabled(false); + } else { + led2Button.setEnabled(true); + } + }// GEN-LAST:event_led2ButtonMousePressed + + private void led3ButtonMousePressed(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_led3ButtonMousePressed + if (led3Button.isEnabled()) { + led3Button.setEnabled(false); + } else { + led3Button.setEnabled(true); + } + }// GEN-LAST:event_led3ButtonMousePressed + + private void led4ButtonMousePressed(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_led4ButtonMousePressed + if (led4Button.isEnabled()) { + led4Button.setEnabled(false); + } else { + led4Button.setEnabled(true); + } + }// GEN-LAST:event_led4ButtonMousePressed + + private void setLedsButtonMousePressed(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_setLedsButtonMousePressed + wiimote.setLeds(led1Button.isEnabled(), led2Button.isEnabled(), + led3Button.isEnabled(), led4Button.isEnabled()); + messageText.setText("Leds set"); + }// GEN-LAST:event_setLedsButtonMousePressed + + private void alphaSmoothingButtonMousePressed(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_alphaSmoothingButtonMousePressed + try { + float nb = Float.parseFloat(alphaSmoothingTextField.getText()); + wiimote.setAlphaSmoothingValue(nb); + messageText.setText("Alpha smoothing set to " + nb); + } catch (NumberFormatException e) { + messageText + .setText("Number is not a float, alpha smoothing not set !"); + } + }// GEN-LAST:event_alphaSmoothingButtonMousePressed + + private void orientationThresholdButtonMousePressed( + java.awt.event.MouseEvent evt) {// GEN-FIRST:event_orientationThresholdButtonMousePressed + try { + float nb = Float + .parseFloat(orientationThresholdTextField.getText()); + wiimote.setOrientationThreshold(nb); + messageText.setText("Orientation threshold set to " + nb); + } catch (NumberFormatException e) { + messageText + .setText("Number is not a float, orientation threshold not set !"); + } + }// GEN-LAST:event_orientationThresholdButtonMousePressed + + private void accelerationThresholdButtonMousePressed( + java.awt.event.MouseEvent evt) {// GEN-FIRST:event_accelerationThresholdButtonMousePressed + try { + int nb = Integer.parseInt(accelerationThresholdTextField.getText()); + wiimote.setAccelerationThreshold(nb); + messageText.setText("Acceleration threshold set to " + nb); + } catch (NumberFormatException e) { + messageText + .setText("Number is not an integer, acceleration threshold not set !"); + } + }// GEN-LAST:event_accelerationThresholdButtonMousePressed + + private void getStatusButtonMousePressed(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_getStatusButtonMousePressed + wiimote.getStatus(); + statusMotionRequested = true; + statusIRRequested = true; + if (expansionFrame instanceof NunchukGuiTest) { + ((NunchukGuiTest) expansionFrame).requestThresholdsUpdate(); + } + }// GEN-LAST:event_getStatusButtonMousePressed + + private void toggleSensorBarPositionButtonMousePressed( + java.awt.event.MouseEvent evt) {// GEN-FIRST:event_toggleSensorBarPositionButtonMousePressed + if (toggleSensorBarPositionButton.isEnabled()) { + wiimote.setSensorBarBelowScreen(); + toggleSensorBarPositionButton.setEnabled(false); + toggleSensorBarPositionButton.setText("Set sensor bar below"); + messageText.setText("Sensor bar set above"); + } else { + wiimote.setSensorBarAboveScreen(); + toggleSensorBarPositionButton.setEnabled(true); + toggleSensorBarPositionButton.setText("Set sensor bar above"); + messageText.setText("Sensor bar set below"); + } + }// GEN-LAST:event_toggleSensorBarPositionButtonMousePressed + + private void toggleScreenAspectRatioButtonMousePressed( + java.awt.event.MouseEvent evt) {// GEN-FIRST:event_toggleScreenAspectRatioButtonMousePressed + if (toggleScreenAspectRatioButton.isEnabled()) { + wiimote.setScreenAspectRatio43(); + toggleScreenAspectRatioButton.setEnabled(false); + toggleScreenAspectRatioButton + .setText("Set screen aspect ratio 16/9"); + messageText.setText("creen aspect ratio to 4/3"); + } else { + wiimote.setScreenAspectRatio169(); + toggleScreenAspectRatioButton.setEnabled(true); + toggleScreenAspectRatioButton + .setText("Set screen aspect ratio 4/3"); + messageText.setText("Screen aspect ratio to 16/9"); + } + }// GEN-LAST:event_toggleScreenAspectRatioButtonMousePressed + + private void setVirtualResolutionButtonMousePressed( + java.awt.event.MouseEvent evt) {// GEN-FIRST:event_setVirtualResolutionButtonMousePressed + try { + int xres = Integer.parseInt(xResolutionTextField.getText()); + int yres = Integer.parseInt(yResolutionTextField.getText()); + wiimote.setVirtualResolution(xres, yres); + messageText.setText("Virtual resolution set to " + xres + "X" + + yres); + } catch (NumberFormatException e) { + messageText + .setText("A number in the virtual resolution is not an integer. Virtual resolution not set!"); + } + }// GEN-LAST:event_setVirtualResolutionButtonMousePressed + + private void mouseIRControlButtonMousePressed(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_mouseIRControlButtonMousePressed + if (mouseIRControlButton.isEnabled()) { + try { + mouseIRControlButton.setEnabled(false); + mouseIRControlButton.setText("Stop infrared mouse control"); + robot = new Robot(); + messageText.setText("Infrared mouse control started"); + } catch (AWTException ex) { + Logger.getLogger(WiiuseJGuiTest.class.getName()).log( + Level.SEVERE, null, ex); + } + } else { + mouseIRControlButton.setEnabled(true); + mouseIRControlButton.setText("Start infrared mouse control"); + robot = null; + messageText.setText("Infrared mouse control stopped"); + } + }// GEN-LAST:event_mouseIRControlButtonMousePressed + + private void normalTimeoutSpinnerStateChanged( + javax.swing.event.ChangeEvent evt) {// GEN-FIRST:event_normalTimeoutSpinnerStateChanged + String value = normalTimeoutSpinner.getValue().toString(); + boolean isInt = true; + int valueInt = 0; + try { + valueInt = Integer.parseInt(value); + } catch (NumberFormatException e) { + isInt = false; + messageText.setText("Wrong value for normal timeout."); + } + if (isInt) { + if (valueInt > 1000) { + normalTimeoutSpinner.setValue("1000"); + } else if (valueInt < 0) { + normalTimeoutSpinner.setValue("0"); + } + } + }// GEN-LAST:event_normalTimeoutSpinnerStateChanged + + private void expansionHandshakeTimeoutSpinnerStateChanged( + javax.swing.event.ChangeEvent evt) {// GEN-FIRST:event_expansionHandshakeTimeoutSpinnerStateChanged + String value = expansionHandshakeTimeoutSpinner.getValue().toString(); + boolean isInt = true; + int valueInt = 0; + try { + valueInt = Integer.parseInt(value); + } catch (NumberFormatException e) { + isInt = false; + messageText.setText("Wrong value for expansion handshake timeout."); + } + if (isInt) { + if (valueInt > 1000) { + expansionHandshakeTimeoutSpinner.setValue("1000"); + } else if (valueInt < 0) { + expansionHandshakeTimeoutSpinner.setValue("0"); + } + } + }// GEN-LAST:event_expansionHandshakeTimeoutSpinnerStateChanged + + private void setIrSensitivySpinnerStateChanged( + javax.swing.event.ChangeEvent evt) {// GEN-FIRST:event_setIrSensitivySpinnerStateChanged + String value = setIrSensitivySpinner.getValue().toString(); + boolean isInt = true; + int valueInt = 0; + try { + valueInt = Integer.parseInt(value); + } catch (NumberFormatException e) { + isInt = false; + messageText.setText("Wrong value for IR senstivity."); + } + if (isInt) { + if (valueInt > 5) { + setIrSensitivySpinner.setValue("1000"); + } else if (valueInt < 0) { + setIrSensitivySpinner.setValue("0"); + } + } + }// GEN-LAST:event_setIrSensitivySpinnerStateChanged + + private void setIrSensitivyButtonMousePressed(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_setIrSensitivyButtonMousePressed + String value = setIrSensitivySpinner.getValue().toString(); + boolean isInt = true; + int valueInt = 0; + try { + valueInt = Integer.parseInt(value); + } catch (NumberFormatException e) { + isInt = false; + messageText + .setText("Wrong value for IR sensitivity. It must be an int !"); + } + if (isInt) { + if (valueInt >= 1 && valueInt <= 5) { + wiimote.setIrSensitivity(valueInt); + messageText.setText("IR senstivity set to: " + valueInt + "."); + } else { + messageText + .setText("Wrong value for IR senstivity. It muset be between 1 and 5 !"); + } + } + }// GEN-LAST:event_setIrSensitivyButtonMousePressed + + private void setTimeoutButtonMousePressed(java.awt.event.MouseEvent evt) {// GEN-FIRST:event_setTimeoutButtonMousePressed + // get normal timeout + String value = normalTimeoutSpinner.getValue().toString(); + boolean isInt = true; + short valueInt = 0; + try { + valueInt = Short.parseShort(value); + } catch (NumberFormatException e) { + isInt = false; + messageText + .setText("Wrong value for normal timeout. It must be an int !"); + } + // get expansion handshake timeout + String value2 = expansionHandshakeTimeoutSpinner.getValue().toString(); + boolean isInt2 = true; + short valueInt2 = 0; + try { + valueInt2 = Short.parseShort(value2); + } catch (NumberFormatException e) { + isInt2 = false; + messageText + .setText("Wrong value for expansion handshake timeout. It must be an int !"); + } + if (isInt && isInt2) { + if (valueInt > 0 && valueInt2 > 0) { + wiimote.setTimeout(valueInt, valueInt2); + messageText.setText("Normal timeout set to: " + valueInt + + " and expansion handshake timeout set to: " + + valueInt2 + "!"); + } else { + messageText + .setText("Wrong value for one of the timeout value. It must be an integer > 0 !"); + } + } + }// GEN-LAST:event_setTimeoutButtonMousePressed + + private void reconnectWiimotesButtonMousePressed( + java.awt.event.MouseEvent evt) {// GEN-FIRST:event_reconnectWiimotesButtonMousePressed + // stop manager + WiiUseApiManager.shutdown(); + + // unregister previous wiimote + if (wiimote != null) { + onDisconnectionEvent(null); + } + + // Reset Gui + // remove frame for expansion + if (expansionFrame != null) { + if (expansionFrame instanceof NunchukGuiTest) { + ((NunchukGuiTest) expansionFrame).unRegisterListeners(); + }else if (expansionFrame instanceof ClassicControllerGuiTest) { + ((ClassicControllerGuiTest) expansionFrame).unRegisterListeners(); + } + expansionFrame.setEnabled(false); + expansionFrame.dispose(); + expansionFrame = null; + } + + // setup buttons In first state + toggleRumbleButton.setText("Activate Rumble"); + toggleRumbleButton.setEnabled(true); + toggleMotionSensingTrackingButton + .setText("Activate motion sensing Tracking"); + toggleMotionSensingTrackingButton.setEnabled(true); + toggleIRTrackingButton.setText("Activate IR Tracking"); + toggleIRTrackingButton.setEnabled(true); + toggleContinuousButton.setText("Activate Continuous"); + toggleContinuousButton.setEnabled(true); + toggleScreenAspectRatioButton.setText("Set screen aspect ratio 4/3"); + toggleScreenAspectRatioButton.setEnabled(true); + toggleSensorBarPositionButton.setText("Set sensor bar above"); + toggleSensorBarPositionButton.setEnabled(true); + toggleSmoothingButton.setText("Activate Smoothing"); + toggleSmoothingButton.setEnabled(true); + mouseIRControlButton.setText("Start infrared mouse control"); + mouseIRControlButton.setEnabled(true); + + // get wiimote + Wiimote[] listWiimote = WiiUseApiManager.getWiimotes(1, true); + if (listWiimote != null && listWiimote.length > 0) { + wiimote = listWiimote[0]; + + // registers listeners + registerListeners(); + initWiimote(); + + isFirstStatusGot = false; + getStatusButtonMousePressed(null); + } + }// GEN-LAST:event_reconnectWiimotesButtonMousePressed + + private void showExpansionWiimoteButtonMousePressed( + java.awt.event.MouseEvent evt) {// GEN-FIRST:event_showExpansionWiimoteButtonMousePressed + if (expansionFrame != null) { + if (showExpansionWiimoteButton.isEnabled()) {// expansion frame + // not shown + // show it + expansionFrame.setEnabled(true); + expansionFrame.setVisible(true); + showExpansionWiimoteButton.setEnabled(false); + if (expansionFrame instanceof NunchukGuiTest){ + showExpansionWiimoteButton.setText("Hide Nunchuk"); + messageText.setText("Nunchuk displayed !"); + }else if(expansionFrame instanceof GuitarHero3GuiTest){ + showExpansionWiimoteButton.setText("Hide Guitar"); + messageText.setText("Guitar displayed !"); + }else if(expansionFrame instanceof ClassicControllerGuiTest){ + showExpansionWiimoteButton.setText("Hide Classic controller"); + messageText.setText("Classic controller displayed !"); + } + } else {// already being shown + expansionFrame.setEnabled(false); + expansionFrame.setVisible(false); + showExpansionWiimoteButton.setEnabled(true); + if (expansionFrame instanceof NunchukGuiTest){ + showExpansionWiimoteButton.setText("Show Nunchuk"); + messageText.setText("Nunchuk hidden !"); + }else if(expansionFrame instanceof GuitarHero3GuiTest){ + showExpansionWiimoteButton.setText("Show Guitar"); + messageText.setText("Guitar hidden !"); + }else if(expansionFrame instanceof ClassicControllerGuiTest){ + showExpansionWiimoteButton.setText("Show Classic controller"); + messageText.setText("Classic controller hidden !"); + } + } + } + }// GEN-LAST:event_showExpansionWiimoteButtonMousePressed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel accelerationPanel; + private javax.swing.JButton accelerationThresholdButton; + private javax.swing.JTextField accelerationThresholdTextField; + private javax.swing.JPanel activateMotionSensingPanel; + private javax.swing.JPanel activateRumbleIRPanel; + private javax.swing.JPanel activateSmoothingContinuousPanel; + private javax.swing.JButton alphaSmoothingButton; + private javax.swing.JTextField alphaSmoothingTextField; + private javax.swing.JLabel batteryLevelText; + private javax.swing.JLabel batteryText; + private javax.swing.JPanel buttonsPanel; + private javax.swing.JPanel controlsPanel; + private javax.swing.JPanel exPansionPanel; + private javax.swing.JPanel expansionButtonPanel; + private javax.swing.JSpinner expansionHandshakeTimeoutSpinner; + private javax.swing.JLabel expansionHandshakeTimeoutText; + private javax.swing.JLabel expansionText; + private javax.swing.JPanel fixedWiimotePanel; + private javax.swing.JPanel gForcePanel; + private javax.swing.JButton getStatusButton; + private javax.swing.JPanel getStatusPanel; + private javax.swing.JPanel irViewPanel; + private javax.swing.JTabbedPane jTabbedPane1; + private javax.swing.JButton led1Button; + private javax.swing.JButton led2Button; + private javax.swing.JButton led3Button; + private javax.swing.JButton led4Button; + private javax.swing.JPanel leftPanel; + private javax.swing.JLabel messageLabelText; + private javax.swing.JLabel messageText; + private javax.swing.JPanel messagesPanel; + private javax.swing.JPanel motionSensingPanel; + private javax.swing.JButton mouseIRControlButton; + private javax.swing.JSpinner normalTimeoutSpinner; + private javax.swing.JLabel normalTimeoutText; + private javax.swing.JButton orientationThresholdButton; + private javax.swing.JTextField orientationThresholdTextField; + private javax.swing.JButton reconnectWiimotesButton; + private javax.swing.JPanel rightPanel; + private javax.swing.JPanel setAccelerationThresholdPanel; + private javax.swing.JPanel setAlphaSmoothingPanel; + private javax.swing.JPanel setIRConfPanel; + private javax.swing.JButton setIrSensitivyButton; + private javax.swing.JPanel setIrSensitivyPanel; + private javax.swing.JSpinner setIrSensitivySpinner; + private javax.swing.JButton setLedsButton; + private javax.swing.JPanel setLedsPanel; + private javax.swing.JPanel setOrientationThresholdPanel; + private javax.swing.JButton setTimeoutButton; + private javax.swing.JPanel setTimeoutPanel; + private javax.swing.JButton setVirtualResolutionButton; + private javax.swing.JPanel setVirtualResolutionPanel; + private javax.swing.JButton showExpansionWiimoteButton; + private javax.swing.JPanel startMouseControlPanel; + private javax.swing.JButton toggleContinuousButton; + private javax.swing.JButton toggleIRTrackingButton; + private javax.swing.JButton toggleMotionSensingTrackingButton; + private javax.swing.JButton toggleRumbleButton; + private javax.swing.JButton toggleScreenAspectRatioButton; + private javax.swing.JButton toggleSensorBarPositionButton; + private javax.swing.JButton toggleSmoothingButton; + private javax.swing.JLabel xLabel; + private javax.swing.JTextField xResolutionTextField; + private javax.swing.JLabel yLabel; + private javax.swing.JTextField yResolutionTextField; + // End of variables declaration//GEN-END:variables +} diff --git a/java/src/wiiusej/utils/AccelerationExpansionEventPanel.java b/java/src/wiiusej/utils/AccelerationExpansionEventPanel.java new file mode 100644 index 0000000..cb3021f --- /dev/null +++ b/java/src/wiiusej/utils/AccelerationExpansionEventPanel.java @@ -0,0 +1,39 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import wiiusej.values.RawAcceleration; +import wiiusej.wiiusejevents.GenericEvent; +import wiiusej.wiiusejevents.physicalevents.NunchukEvent; + +/** + * Panel to display Acceleration in a MotionSensingEvent from an expansion. + * + * @author guiguito + */ +public class AccelerationExpansionEventPanel extends AccelerationPanel { + + @Override + public RawAcceleration getRawAccelerationValue(GenericEvent e) { + if (e instanceof NunchukEvent) { + return ((NunchukEvent) e).getNunchukMotionSensingEvent() + .getRawAcceleration(); + } + return null; + } + +} diff --git a/java/src/wiiusej/utils/AccelerationPanel.java b/java/src/wiiusej/utils/AccelerationPanel.java new file mode 100644 index 0000000..15f1551 --- /dev/null +++ b/java/src/wiiusej/utils/AccelerationPanel.java @@ -0,0 +1,303 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.util.ArrayList; + +import wiiusej.values.RawAcceleration; +import wiiusej.wiiusejevents.GenericEvent; +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * This panel is used to watch raw acceleration values from a + * MotionSensingEvent. + * + * @author guiguito + */ +public abstract class AccelerationPanel extends javax.swing.JPanel implements + WiimoteListener { + + private Image mImage;// image for double buffering + private Color xColor = Color.RED; + private Color yColor = Color.GREEN; + private Color zColor = Color.BLUE; + private Color backgroundColor = Color.WHITE; + private Color lineColor = Color.BLACK; + private ArrayList values = new ArrayList(); + + /** Creates new form AccelerationPanel */ + public AccelerationPanel() { + initComponents(); + } + + /** + * Constructor used to choose the colors used by the AccelerationPanel. + * + * @param bgColor + * background color. + * @param xColor + * x color. + * @param yColor + * y color. + * @param zColor + * z color. + * @param lColor + * line color. + */ + public AccelerationPanel(Color bgColor, Color xColor, Color yColor, + Color zColor, Color lColor) { + backgroundColor = bgColor; + this.xColor = xColor; + this.yColor = yColor; + this.zColor = zColor; + lineColor = lColor; + initComponents(); + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Dimension d = getSize(); + checkOffScreenImage(); + Graphics offG = mImage.getGraphics(); + offG.setColor(backgroundColor); + offG.fillRect(0, 0, d.width, d.height); + Graphics2D g2 = (Graphics2D) mImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + // draw medium line + int yLine = getHeight() - 25; + + g2.setPaint(lineColor); + g2.drawLine(0, yLine, getWidth(), yLine); + + RawAcceleration[] valuesArray = values.toArray(new RawAcceleration[0]); + + double unit = yLine / 255.0; + int previousX = 0; + int previousY = 0; + int previousZ = 0; + // draw curves + for (int i = 0; i < valuesArray.length && i < getWidth(); i++) { + RawAcceleration acceleration = valuesArray[i]; + // draw X + g2.setPaint(xColor); + int yDelta = (int) Math.round(unit * acceleration.getX()); + int y = -1 * yDelta + yLine; + g2.drawLine(i - 1, previousX, i, y); + g2.setTransform(new AffineTransform()); + previousX = y; + // draw Y + g2.setPaint(yColor); + yDelta = (int) Math.round(unit * acceleration.getY()); + y = -1 * yDelta + yLine; + g2.drawLine(i - 1, previousY, i, y); + g2.setTransform(new AffineTransform()); + previousY = y; + // draw Z + g2.setPaint(zColor); + yDelta = (int) Math.round(unit * acceleration.getZ()); + y = -1 * yDelta + yLine; + g2.drawLine(i - 1, previousZ, i, y); + g2.setTransform(new AffineTransform()); + previousZ = y; + } + + // draw legend + g2.setPaint(xColor); + g2.drawLine(5, getHeight() - 10, 25, getHeight() - 10); + g2.setPaint(yColor); + g2.drawLine(60, getHeight() - 10, 80, getHeight() - 10); + g2.setPaint(zColor); + g2.drawLine(120, getHeight() - 10, 140, getHeight() - 10); + + g2.setPaint(lineColor); + g2.drawString("X", 30, getHeight() - 5); + g2.drawString("Y", 85, getHeight() - 5); + g2.drawString("Z", 145, getHeight() - 5); + g2.drawString("0", 2, yLine - 5); + g2.drawString("255", 2, 15); + // put offscreen image on the screen + g.drawImage(mImage, 0, 0, null); + } + + /** + * check if the mImage variable has been initialized. If it's not the case + * it initializes it with the dimensions of the panel. mImage is for double + * buffering. + */ + private void checkOffScreenImage() { + Dimension d = getSize(); + if (mImage == null || mImage.getWidth(null) != d.width + || mImage.getHeight(null) != d.height) { + mImage = createImage(d.width, d.height); + } + } + + public void onButtonsEvent(WiimoteButtonsEvent arg0) { + // nothing + } + + public void onIrEvent(IREvent arg0) { + // nothing + } + + public void onMotionSensingEvent(MotionSensingEvent arg0) { + draw(arg0); + } + + public void onExpansionEvent(ExpansionEvent arg0) { + draw(arg0); + } + + public void onStatusEvent(StatusEvent arg0) { + // nothing + } + + public void onDisconnectionEvent(DisconnectionEvent arg0) { + // Clear points. + values.clear(); + repaint(); + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent arg0) { + // nothing + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent arg0) { + // nothing + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) { + // nothing + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) { + // nothing + } + + public void onClassicControllerInsertedEvent( + ClassicControllerInsertedEvent arg0) { + // nothing + } + + public void onClassicControllerRemovedEvent( + ClassicControllerRemovedEvent arg0) { + // nothing + } + + private void draw(GenericEvent arg0) { + if (values.size() >= getWidth()) { + // if there are as many values as pixels in the width + // clear points + values.clear(); + } + RawAcceleration rawAcceleration = getRawAccelerationValue(arg0); + if (rawAcceleration != null) + values.add(rawAcceleration); + repaint(); + } + + public abstract RawAcceleration getRawAccelerationValue(GenericEvent e); + + public Color getBackgroundColor() { + return backgroundColor; + } + + public Color getLineColor() { + return lineColor; + } + + public Color getXColor() { + return xColor; + } + + public Color getYColor() { + return yColor; + } + + public Color getZColor() { + return zColor; + } + + public void setBackgroundColor(Color backgroundColor) { + this.backgroundColor = backgroundColor; + } + + public void setLineColor(Color lineColor) { + this.lineColor = lineColor; + } + + public void setXColor(Color xColor) { + this.xColor = xColor; + } + + public void setYColor(Color yColor) { + this.yColor = yColor; + } + + public void setZColor(Color zColor) { + this.zColor = zColor; + } + + public void clearView() { + values.clear(); + repaint(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 400, + Short.MAX_VALUE)); + layout.setVerticalGroup(layout.createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 300, + Short.MAX_VALUE)); + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} diff --git a/java/src/wiiusej/utils/AccelerationWiimoteEventPanel.java b/java/src/wiiusej/utils/AccelerationWiimoteEventPanel.java new file mode 100644 index 0000000..4e716de --- /dev/null +++ b/java/src/wiiusej/utils/AccelerationWiimoteEventPanel.java @@ -0,0 +1,37 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import wiiusej.values.RawAcceleration; +import wiiusej.wiiusejevents.GenericEvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; + +/** + * Panel to display Acceleration in a MotionSensingEvent from a wiimote. + * @author guiguito + */ +public class AccelerationWiimoteEventPanel extends AccelerationPanel { + + @Override + public RawAcceleration getRawAccelerationValue(GenericEvent e) { + if (e instanceof MotionSensingEvent) { + return ((MotionSensingEvent) e).getRawAcceleration(); + } + return null; + } + +} diff --git a/java/src/wiiusej/utils/ButtonsEventPanel.java b/java/src/wiiusej/utils/ButtonsEventPanel.java new file mode 100644 index 0000000..97f9b19 --- /dev/null +++ b/java/src/wiiusej/utils/ButtonsEventPanel.java @@ -0,0 +1,382 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Toolkit; +import java.awt.geom.AffineTransform; + +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * This panel is used to see what buttons are pressed on the wiimote. It + * displays the result of last ButtonsEvent. + * + * @author guiguito + */ +public class ButtonsEventPanel extends javax.swing.JPanel implements + WiimoteListener { + + private Image mImage;// image for double buffering + private Image wiimoteImage;// image for double buffering + private WiimoteButtonsEvent buttons; + private Color pressedColor = Color.RED; + private Color heldColor = Color.ORANGE; + private Color releasedColor = Color.YELLOW; + private Shape shape = new java.awt.geom.Ellipse2D.Double(0, 0, 13, 13); + + /** + * Default constructor. Red : button just pressed. Orange : button held. + * Yellow : button just released. + */ + public ButtonsEventPanel() { + Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit(); + java.net.URL url = ButtonsEventPanel.class + .getResource("/img/wiimote.png"); + wiimoteImage = toolkit.createImage(url); + initComponents(); + } + + /** + * Constructor used to set colors and shape used. + * + * @param pressColor + * color of a button just pressed. + * @param hColor + * color of a button held. + * @param relColor + * color of a button just released. + * @param sh + * shape draw on the buttons. + */ + public ButtonsEventPanel(Color pressColor, Color hColor, Color relColor, + Shape sh) { + pressedColor = pressColor; + heldColor = hColor; + releasedColor = relColor; + shape = sh; + Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit(); + wiimoteImage = toolkit.createImage("img\\wiimote.png"); + initComponents(); + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Dimension d = getSize(); + checkOffScreenImage(); + Graphics offG = mImage.getGraphics(); + // offG.setColor(backgroundColor); + offG.fillRect(0, 0, d.width, d.height); + Graphics2D g2 = (Graphics2D) mImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + // draw buttons pushed + g2.drawImage(wiimoteImage, 0, 0, this); + g2.setTransform(new AffineTransform()); + + if (buttons != null) { + /* button ONE */ + if (buttons.isButtonOneJustPressed()) { + drawFunction(g2, pressedColor, 53, 353); + } + if (buttons.isButtonOneHeld()) { + drawFunction(g2, heldColor, 53, 353); + } + if (buttons.isButtonOneJustReleased()) { + drawFunction(g2, releasedColor, 53, 353); + } + + /* button TWO */ + if (buttons.isButtonTwoJustPressed()) { + drawFunction(g2, pressedColor, 53, 395); + } + if (buttons.isButtonTwoHeld()) { + drawFunction(g2, heldColor, 53, 395); + } + if (buttons.isButtonTwoJustReleased()) { + drawFunction(g2, releasedColor, 53, 395); + } + + /* button A */ + if (buttons.isButtonAJustPressed()) { + drawFunction(g2, pressedColor, 53, 150); + } + if (buttons.isButtonAHeld()) { + drawFunction(g2, heldColor, 53, 150); + } + if (buttons.isButtonAJustReleased()) { + drawFunction(g2, releasedColor, 53, 150); + } + + /* button B */ + if (buttons.isButtonBJustPressed()) { + drawFunction(g2, pressedColor, 16, 149); + } + if (buttons.isButtonBHeld()) { + drawFunction(g2, heldColor, 16, 149); + } + if (buttons.isButtonBJustReleased()) { + drawFunction(g2, releasedColor, 16, 149); + } + + /* button LEFT */ + if (buttons.isButtonLeftJustPressed()) { + drawFunction(g2, pressedColor, 33, 77); + } + if (buttons.isButtonLeftHeld()) { + drawFunction(g2, heldColor, 33, 77); + } + if (buttons.isButtonLeftJustReleased()) { + drawFunction(g2, releasedColor, 33, 77); + } + + /* button RIGHT */ + if (buttons.isButtonRightJustPressed()) { + drawFunction(g2, pressedColor, 73, 77); + } + if (buttons.isButtonRightHeld()) { + drawFunction(g2, heldColor, 73, 77); + } + if (buttons.isButtonRightJustReleased()) { + drawFunction(g2, releasedColor, 73, 77); + } + + /* button UP */ + if (buttons.isButtonUpJustPressed()) { + drawFunction(g2, pressedColor, 54, 60); + } + if (buttons.isButtonUpHeld()) { + drawFunction(g2, heldColor, 54, 60); + } + if (buttons.isButtonUpJustReleased()) { + drawFunction(g2, releasedColor, 54, 60); + } + + /* button DOWN */ + if (buttons.isButtonDownJustPressed()) { + drawFunction(g2, pressedColor, 54, 97); + } + if (buttons.isButtonDownHeld()) { + drawFunction(g2, heldColor, 54, 97); + } + if (buttons.isButtonDownJustReleased()) { + drawFunction(g2, releasedColor, 54, 97); + } + + /* button MINUS */ + if (buttons.isButtonMinusJustPressed()) { + drawFunction(g2, pressedColor, 20, 230); + } + if (buttons.isButtonMinusHeld()) { + drawFunction(g2, heldColor, 20, 230); + } + if (buttons.isButtonMinusJustReleased()) { + drawFunction(g2, releasedColor, 20, 230); + } + + /* button PLUS */ + if (buttons.isButtonPlusJustPressed()) { + drawFunction(g2, pressedColor, 86, 230); + } + if (buttons.isButtonPlusHeld()) { + drawFunction(g2, heldColor, 86, 230); + } + if (buttons.isButtonPlusJustReleased()) { + drawFunction(g2, releasedColor, 86, 230); + } + + /* button HOME */ + if (buttons.isButtonHomeJustPressed()) { + drawFunction(g2, pressedColor, 53, 230); + } + if (buttons.isButtonHomeHeld()) { + drawFunction(g2, heldColor, 53, 230); + } + if (buttons.isButtonHomeJustReleased()) { + drawFunction(g2, releasedColor, 53, 230); + } + + buttons = null; + } + + // put offscreen image on the screen + g.drawImage(mImage, 0, 0, null); + } + + /** + * Function used to factorize code. + * + * @param g2 + * where to draw a shape. + * @param col + * color to use. + * @param x + * x coordinates. + * @param y + * y coordinates. + */ + private void drawFunction(Graphics2D g2, Color col, int x, int y) { + g2.setPaint(col); + g2.translate(x, y); + g2.draw(shape); + g2.fill(shape); + g2.setTransform(new AffineTransform()); + } + + /** + * check if the mImage variable has been initialized. If it's not the case + * it initializes it with the dimensions of the panel. mImage is for double + * buffering. + */ + private void checkOffScreenImage() { + Dimension d = getSize(); + if (mImage == null || mImage.getWidth(null) != d.width + || mImage.getHeight(null) != d.height) { + mImage = createImage(d.width, d.height); + } + } + + public void onButtonsEvent(WiimoteButtonsEvent arg0) { + setSize(wiimoteImage.getWidth(this), wiimoteImage.getHeight(this)); + buttons = arg0; + repaint(); + } + + public void onIrEvent(IREvent arg0) { + // nothing + } + + public void onMotionSensingEvent(MotionSensingEvent arg0) { + // nothing + } + + public void onExpansionEvent(ExpansionEvent e) { + // nothing + } + + public void onStatusEvent(StatusEvent arg0) { + // nothing + } + + public void onDisconnectionEvent(DisconnectionEvent arg0) { + clearView(); + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent e) { + // nothing + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent e) { + // nothing + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) { + // nothing + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) { + // nothing + } + + public void onClassicControllerInsertedEvent( + ClassicControllerInsertedEvent arg0) { + // nothing + } + + public void onClassicControllerRemovedEvent( + ClassicControllerRemovedEvent arg0) { + // nothing + } + + public Color getHeldColor() { + return heldColor; + } + + public Color getPressedColor() { + return pressedColor; + } + + public Color getReleasedColor() { + return releasedColor; + } + + public Shape getShape() { + return shape; + } + + public void setHeldColor(Color heldColor) { + this.heldColor = heldColor; + } + + public void setPressedColor(Color pressedColor) { + this.pressedColor = pressedColor; + } + + public void setReleasedColor(Color releasedColor) { + this.releasedColor = releasedColor; + } + + public void setShape(Shape shape) { + this.shape = shape; + } + + public void clearView() { + buttons = null; + repaint(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 400, + Short.MAX_VALUE)); + layout.setVerticalGroup(layout.createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 300, + Short.MAX_VALUE)); + }// //GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} diff --git a/java/src/wiiusej/utils/ClassicControllerButtonsEventPanel.java b/java/src/wiiusej/utils/ClassicControllerButtonsEventPanel.java new file mode 100644 index 0000000..9bec5a9 --- /dev/null +++ b/java/src/wiiusej/utils/ClassicControllerButtonsEventPanel.java @@ -0,0 +1,500 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Toolkit; +import java.awt.geom.AffineTransform; +import wiiusej.wiiusejevents.physicalevents.ClassicControllerButtonsEvent; +import wiiusej.wiiusejevents.physicalevents.ClassicControllerEvent; +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.JoystickEvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * This panel is used to display what happens on the classic controller. + * + * @author guiguito + */ +public class ClassicControllerButtonsEventPanel extends javax.swing.JPanel implements WiimoteListener { + + private Image mImage;// image for double buffering + private Image wiimoteImage;// image for double buffering + private ClassicControllerEvent event; + private Color pressedColor = Color.RED; + private Color heldColor = Color.ORANGE; + private Color releasedColor = Color.YELLOW; + private Color joystickColor = Color.PINK; + private Color shoulderColor = Color.BLUE; + private Shape shapeJoystick = new java.awt.geom.Ellipse2D.Double(0, 0, 15, 15); + private Shape shapeButton = new java.awt.geom.Ellipse2D.Double(0, 0, 20, 20); + private static int xAmplitude = 20; + private static int yAmplitude = 20; + + /** + * Default constructor. Red : button just pressed. Orange : button held. + * Yellow : button just released. + */ + public ClassicControllerButtonsEventPanel() { + Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit(); + java.net.URL url = ButtonsEventPanel.class.getResource("/img/classiccontroller.png"); + wiimoteImage = toolkit.createImage(url); + initComponents(); + } + + /** + * Constructor used to set colors and shape used. + * + * @param pressColor + * color of a button just pressed. + * @param hColor + * color of a button held. + * @param relColor + * color of a button just released. + * @param jsColor + * color of the joysticks. + * @param shouldColor + * color of the shoulders. + * @param js + * shape drawn on the joysticks. + * @param sh + * shape drawn on the buttons. + */ + public ClassicControllerButtonsEventPanel(Color pressColor, Color hColor, Color relColor, + Color jsColor, Color shouldColor, Shape js, Shape sh) { + pressedColor = pressColor; + heldColor = hColor; + releasedColor = relColor; + shapeButton = sh; + shapeJoystick = js; + joystickColor = jsColor; + shoulderColor = shouldColor; + Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit(); + wiimoteImage = toolkit.createImage("img\\wiimote.png"); + initComponents(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 400, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 300, Short.MAX_VALUE) + ); + }// //GEN-END:initComponents + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Dimension d = getSize(); + checkOffScreenImage(); + Graphics offG = mImage.getGraphics(); + // offG.setColor(backgroundColor); + offG.fillRect(0, 0, d.width, d.height); + Graphics2D g2 = (Graphics2D) mImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + //draw classic controller + g2.drawImage(wiimoteImage, 0, 0, this); + g2.setTransform(new AffineTransform()); + + if (event != null) { + // draw buttons pushed + ClassicControllerButtonsEvent buttons = event.getButtonsEvent(); + + /* button A */ + if (buttons.isButtonAJustPressed()) { + drawFunction(g2, pressedColor, 304, 76, shapeButton); + } + if (buttons.isButtonAHeld()) { + drawFunction(g2, heldColor, 304, 76, shapeButton); + } + if (buttons.isButtonAJustReleased()) { + drawFunction(g2, releasedColor, 304, 76, shapeButton); + } + + /* button B */ + if (buttons.isButtonBJustPressed()) { + drawFunction(g2, pressedColor, 269, 98, shapeButton); + } + if (buttons.isButtonBHeld()) { + drawFunction(g2, heldColor, 269, 98, shapeButton); + } + if (buttons.isButtonBJustReleased()) { + drawFunction(g2, releasedColor, 269, 98, shapeButton); + } + + /* button Down */ + if (buttons.isButtonDownJustPressed()) { + drawFunction(g2, pressedColor, 60, 97, shapeButton); + } + if (buttons.isButtonDownHeld()) { + drawFunction(g2, heldColor, 60, 97, shapeButton); + } + if (buttons.isButtonDownJustReleased()) { + drawFunction(g2, releasedColor, 60, 97, shapeButton); + } + + /* button FullLeft */ + if (buttons.isButtonFullLeftJustPressed()) { + drawFunction(g2, pressedColor, 55, 4, shapeButton); + } + if (buttons.isButtonFullLeftHeld()) { + drawFunction(g2, heldColor, 55, 4, shapeButton); + } + if (buttons.isButtonFullLeftJustReleased()) { + drawFunction(g2, releasedColor, 55, 4, shapeButton); + } + + /* button FullRight */ + if (buttons.isButtonFullRightJustPressed()) { + drawFunction(g2, pressedColor, 276, 4, shapeButton); + } + if (buttons.isButtonFullRightHeld()) { + drawFunction(g2, heldColor, 276, 4, shapeButton); + } + if (buttons.isButtonFullRightJustReleased()) { + drawFunction(g2, releasedColor, 276, 4, shapeButton); + } + + /* button Home */ + if (buttons.isButtonHomeJustPressed()) { + drawFunction(g2, pressedColor, 166, 76, shapeButton); + } + if (buttons.isButtonHomeHeld()) { + drawFunction(g2, heldColor, 166, 76, shapeButton); + } + if (buttons.isButtonHomeJustReleased()) { + drawFunction(g2, releasedColor, 166, 76, shapeButton); + } + + /* button Left */ + if (buttons.isButtonLeftJustPressed()) { + drawFunction(g2, pressedColor, 34, 75, shapeButton); + } + if (buttons.isButtonLeftHeld()) { + drawFunction(g2, heldColor, 34, 75, shapeButton); + } + if (buttons.isButtonLeftJustReleased()) { + drawFunction(g2, releasedColor, 34, 75, shapeButton); + } + + /* button Minus */ + if (buttons.isButtonMinusJustPressed()) { + drawFunction(g2, pressedColor, 140, 76, shapeButton); + } + if (buttons.isButtonMinusHeld()) { + drawFunction(g2, heldColor, 140, 76, shapeButton); + } + if (buttons.isButtonMinusJustReleased()) { + drawFunction(g2, releasedColor, 140, 76, shapeButton); + } + + /* button Plus */ + if (buttons.isButtonPlusJustPressed()) { + drawFunction(g2, pressedColor, 191, 76, shapeButton); + } + if (buttons.isButtonPlusHeld()) { + drawFunction(g2, heldColor, 191, 76, shapeButton); + } + if (buttons.isButtonPlusJustReleased()) { + drawFunction(g2, releasedColor, 191, 76, shapeButton); + } + + /* button Right */ + if (buttons.isButtonRightJustPressed()) { + drawFunction(g2, pressedColor, 86, 75, shapeButton); + } + if (buttons.isButtonRightHeld()) { + drawFunction(g2, heldColor, 86, 75, shapeButton); + } + if (buttons.isButtonRightJustReleased()) { + drawFunction(g2, releasedColor, 86, 353, shapeButton); + } + + /* button Up */ + if (buttons.isButtonUpJustPressed()) { + drawFunction(g2, pressedColor, 60, 50, shapeButton); + } + if (buttons.isButtonUpHeld()) { + drawFunction(g2, heldColor, 60, 50, shapeButton); + } + if (buttons.isButtonUpJustReleased()) { + drawFunction(g2, releasedColor, 60, 50, shapeButton); + } + + /* button X */ + if (buttons.isButtonXJustPressed()) { + drawFunction(g2, pressedColor, 271, 53, shapeButton); + } + if (buttons.isButtonXHeld()) { + drawFunction(g2, heldColor, 271, 53, shapeButton); + } + if (buttons.isButtonXJustReleased()) { + drawFunction(g2, releasedColor, 271, 53, shapeButton); + } + + /* button Y */ + if (buttons.isButtonYJustPressed()) { + drawFunction(g2, pressedColor, 237, 76, shapeButton); + } + if (buttons.isButtonYHeld()) { + drawFunction(g2, heldColor, 237, 76, shapeButton); + } + if (buttons.isButtonYJustReleased()) { + drawFunction(g2, releasedColor, 237, 76, shapeButton); + } + + /* button ZL */ + if (buttons.isButtonZLJustPressed()) { + drawFunction(g2, pressedColor, 123, 4, shapeButton); + } + if (buttons.isButtonZLHeld()) { + drawFunction(g2, heldColor, 123, 4, shapeButton); + } + if (buttons.isButtonZLJustReleased()) { + drawFunction(g2, releasedColor, 123, 4, shapeButton); + } + + /* button ZR */ + if (buttons.isButtonZRJustPressed()) { + drawFunction(g2, pressedColor, 208, 4, shapeButton); + } + if (buttons.isButtonZRHeld()) { + drawFunction(g2, heldColor, 208, 4, shapeButton); + } + if (buttons.isButtonZRJustReleased()) { + drawFunction(g2, releasedColor, 208, 4, shapeButton); + } + + //joysticks + int halfWidth = (int) Math.round(shapeJoystick.getBounds().getWidth() / 2); + int halfHeight = (int) Math.round(shapeJoystick.getBounds().getHeight() / 2); + + // left joystick + JoystickEvent jl = event.getClassicControllerLeftJoystickEvent(); + int xCenter1 = 121; + int yCenter1 = 125; + + double xAng1 = Math.sin(jl.getAngle() * Math.PI / 180.0) * jl.getMagnitude(); + double yAng1 = Math.cos(jl.getAngle() * Math.PI / 180.0) * jl.getMagnitude(); + + int xShift1 = (int) Math.round(xAng1 * xAmplitude); + int yShift1 = (int) Math.round(yAng1 * yAmplitude); + int x1 = xCenter1 + xShift1 - halfWidth; + int y1 = yCenter1 - yShift1 - halfHeight; + // draw shape + drawFunction(g2, joystickColor, x1, y1, shapeJoystick); + + //Right joystick + JoystickEvent jr = event.getClassicControllerRightJoystickEvent(); + int xCenter2 = 213; + int yCenter2 = 125; + + double xAng2 = Math.sin(jr.getAngle() * Math.PI / 180.0) * jr.getMagnitude(); + double yAng2 = Math.cos(jr.getAngle() * Math.PI / 180.0) * jr.getMagnitude(); + + int xShift2 = (int) Math.round(xAng2 * xAmplitude); + int yShift2 = (int) Math.round(yAng2 * yAmplitude); + int x2 = xCenter2 + xShift2 - halfWidth; + int y2 = yCenter2 - yShift2 - halfHeight; + // draw shape + drawFunction(g2, joystickColor, x2, y2, shapeJoystick); + + event = null; + } + + // put offscreen image on the screen + g.drawImage(mImage, 0, 0, null); + } + + /** + * Function used to factorize code. + * + * @param g2 + * where to draw a shape. + * @param col + * color to use. + * @param x + * x coordinates. + * @param y + * y coordinates. + * @param sh + * shape to draw. + */ + private void drawFunction(Graphics2D g2, Color col, int x, int y, Shape sh) { + g2.setPaint(col); + g2.translate(x, y); + g2.draw(sh); + g2.fill(sh); + g2.setTransform(new AffineTransform()); + } + + /** + * check if the mImage variable has been initialized. If it's not the case + * it initializes it with the dimensions of the panel. mImage is for double + * buffering. + */ + private void checkOffScreenImage() { + Dimension d = getSize(); + if (mImage == null || mImage.getWidth(null) != d.width || mImage.getHeight(null) != d.height) { + mImage = createImage(d.width, d.height); + } + } + + public void onButtonsEvent(WiimoteButtonsEvent arg0) { + //do nothing + } + + public void onIrEvent(IREvent arg0) { + //do nothing + } + + public void onMotionSensingEvent(MotionSensingEvent arg0) { + //do nothing + } + + public void onExpansionEvent(ExpansionEvent arg0) { + if (arg0 instanceof ClassicControllerEvent) { + event = (ClassicControllerEvent) arg0; + } + repaint(); + } + + public void onStatusEvent(StatusEvent arg0) { + //do nothing + } + + public void onDisconnectionEvent(DisconnectionEvent arg0) { + //do nothing + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent arg0) { + //do nothing + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent arg0) { + //do nothing + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) { + //do nothing + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) { + //do nothing + } + + public void onClassicControllerInsertedEvent(ClassicControllerInsertedEvent arg0) { + //do nothing + } + + public void onClassicControllerRemovedEvent(ClassicControllerRemovedEvent arg0) { + clearView(); + } + + public Color getHeldColor() { + return heldColor; + } + + public Color getJoystickColor() { + return joystickColor; + } + + public Color getPressedColor() { + return pressedColor; + } + + public Color getReleasedColor() { + return releasedColor; + } + + public Color getShoulderColor() { + return shoulderColor; + } + + public Shape getShapeButton() { + return shapeButton; + } + + public Shape getShapeJoystick() { + return shapeJoystick; + } + + public void setHeldColor(Color heldColor) { + this.heldColor = heldColor; + } + + public void setJoystickColor(Color joystickColor) { + this.joystickColor = joystickColor; + } + + public void setPressedColor(Color pressedColor) { + this.pressedColor = pressedColor; + } + + public void setReleasedColor(Color releasedColor) { + this.releasedColor = releasedColor; + } + + public void setShoulderColor(Color shoulderColor) { + this.shoulderColor = shoulderColor; + } + + public void setShapeButton(Shape shapeButton) { + this.shapeButton = shapeButton; + } + + public void setShapeJoystick(Shape shapeJoystick) { + this.shapeJoystick = shapeJoystick; + } + + public void clearView() { + event = null; + repaint(); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} diff --git a/java/src/wiiusej/utils/GForceExpansionEventPanel.java b/java/src/wiiusej/utils/GForceExpansionEventPanel.java new file mode 100644 index 0000000..d5852b0 --- /dev/null +++ b/java/src/wiiusej/utils/GForceExpansionEventPanel.java @@ -0,0 +1,38 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import wiiusej.values.GForce; +import wiiusej.wiiusejevents.GenericEvent; +import wiiusej.wiiusejevents.physicalevents.NunchukEvent; + +/** + * Panel to display GForce in a MotionSensingEvent from an expansion. + * + * @author guiguito + */ +public class GForceExpansionEventPanel extends GForcePanel{ + + @Override + public GForce getGForceValue(GenericEvent e) { + if (e instanceof NunchukEvent){ + return ((NunchukEvent)e).getNunchukMotionSensingEvent().getGforce(); + } + return null; + } + +} diff --git a/java/src/wiiusej/utils/GForcePanel.java b/java/src/wiiusej/utils/GForcePanel.java new file mode 100644 index 0000000..dc57b30 --- /dev/null +++ b/java/src/wiiusej/utils/GForcePanel.java @@ -0,0 +1,304 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.util.ArrayList; + +import wiiusej.values.GForce; +import wiiusej.wiiusejevents.GenericEvent; +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * This panel is used to watch gravity force values from a MotionSensingEvent. + * + * @author guiguito + */ +public abstract class GForcePanel extends javax.swing.JPanel implements + WiimoteListener { + + private Image mImage;// image for double buffering + private Color xColor = Color.RED; + private Color yColor = Color.GREEN; + private Color zColor = Color.BLUE; + private Color backgroundColor = Color.WHITE; + private Color lineColor = Color.BLACK; + private ArrayList values = new ArrayList(); + + /** + * Default constructor of the AccelerationPanel. + */ + public GForcePanel() { + initComponents(); + } + + /** + * Constructor used to choose the colors used by the AccelerationPanel. + * + * @param bgColor + * background color. + * @param xxColor + * color of the acceleration on X axis. + * @param yyColor + * color of the acceleration on Y axis. + * @param zzColor + * color of the acceleration on Z axis. + * @param lColor + * line color. + */ + public GForcePanel(Color bgColor, Color xxColor, Color yyColor, + Color zzColor, Color lColor) { + backgroundColor = bgColor; + xColor = xxColor; + yColor = yyColor; + zColor = zzColor; + lineColor = lColor; + initComponents(); + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Dimension d = getSize(); + checkOffScreenImage(); + Graphics offG = mImage.getGraphics(); + offG.setColor(backgroundColor); + offG.fillRect(0, 0, d.width, d.height); + Graphics2D g2 = (Graphics2D) mImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + // draw medium line + double yMiddleFloat = getHeight() / 2.0; + int yMiddle = (int) Math.round(yMiddleFloat); + + g2.setPaint(lineColor); + g2.drawLine(0, yMiddle, getWidth(), yMiddle); + + GForce[] valuesArray = values.toArray(new GForce[0]); + double unit = yMiddleFloat / 5.0; + int previousX = 0; + int previousY = 0; + int previousZ = 0; + // draw curves + for (int i = 0; i < valuesArray.length && i < getWidth(); i++) { + GForce gforce = valuesArray[i]; + // draw X + g2.setPaint(xColor); + int yDelta = (int) Math.round(unit * gforce.getX()); + int y = -1 * yDelta + yMiddle; + g2.drawLine(i - 1, previousX, i, y); + g2.setTransform(new AffineTransform()); + previousX = y; + // draw Y + g2.setPaint(yColor); + yDelta = (int) Math.round(unit * gforce.getY()); + y = -1 * yDelta + yMiddle; + g2.drawLine(i - 1, previousY, i, y); + g2.setTransform(new AffineTransform()); + previousY = y; + // draw Z + g2.setPaint(zColor); + yDelta = (int) Math.round(unit * gforce.getZ()); + y = -1 * yDelta + yMiddle; + g2.drawLine(i - 1, previousZ, i, y); + g2.setTransform(new AffineTransform()); + previousZ = y; + } + + // draw legend + g2.setPaint(xColor); + g2.drawLine(5, getHeight() - 10, 25, getHeight() - 10); + g2.setPaint(yColor); + g2.drawLine(60, getHeight() - 10, 80, getHeight() - 10); + g2.setPaint(zColor); + g2.drawLine(120, getHeight() - 10, 140, getHeight() - 10); + + g2.setPaint(lineColor); + g2.drawString("X", 30, getHeight() - 5); + g2.drawString("Y", 85, getHeight() - 5); + g2.drawString("Z", 145, getHeight() - 5); + g2.drawString("0", 2, yMiddle - 5); + g2.drawString("5", 2, 10); + g2.drawString("-5", 2, getHeight() - 15); + // put offscreen image on the screen + g.drawImage(mImage, 0, 0, null); + } + + /** + * check if the mImage variable has been initialized. If it's not the case + * it initializes it with the dimensions of the panel. mImage is for double + * buffering. + */ + private void checkOffScreenImage() { + Dimension d = getSize(); + if (mImage == null || mImage.getWidth(null) != d.width + || mImage.getHeight(null) != d.height) { + mImage = createImage(d.width, d.height); + } + } + + public void onButtonsEvent(WiimoteButtonsEvent arg0) { + // nothing + } + + public void onIrEvent(IREvent arg0) { + // nothing + } + + public void onMotionSensingEvent(MotionSensingEvent arg0) { + draw(arg0); + } + + public void onExpansionEvent(ExpansionEvent arg0) { + draw(arg0); + } + + public void onStatusEvent(StatusEvent arg0) { + // nothing + } + + public void onDisconnectionEvent(DisconnectionEvent arg0) { + // Clear points. + values.clear(); + repaint(); + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent arg0) { + // nothing + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent arg0) { + // nothing + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) { + // nothing + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) { + // nothing + } + + public void onClassicControllerInsertedEvent( + ClassicControllerInsertedEvent arg0) { + // nothing + } + + public void onClassicControllerRemovedEvent( + ClassicControllerRemovedEvent arg0) { + // nothing + } + + private void draw(GenericEvent arg0) { + if (values.size() >= getWidth()) { + // if there are as many values as pixels in the width + // clear points + values.clear(); + } + GForce gforce = getGForceValue(arg0); + if (gforce != null) + values.add(gforce); + repaint(); + } + + public abstract GForce getGForceValue(GenericEvent e); + + public Color getBackgroundColor() { + return backgroundColor; + } + + public Color getLineColor() { + return lineColor; + } + + public Color getXColor() { + return xColor; + } + + public Color getYColor() { + return yColor; + } + + public Color getZColor() { + return zColor; + } + + public void setBackgroundColor(Color backgroundColor) { + this.backgroundColor = backgroundColor; + } + + public void setLineColor(Color lineColor) { + this.lineColor = lineColor; + } + + public void setXColor(Color xColor) { + this.xColor = xColor; + } + + public void setYColor(Color yColor) { + this.yColor = yColor; + } + + public void setZColor(Color zColor) { + this.zColor = zColor; + } + + public void clearView() { + values.clear(); + repaint(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 400, + Short.MAX_VALUE)); + layout.setVerticalGroup(layout.createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 300, + Short.MAX_VALUE)); + }// //GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} diff --git a/java/src/wiiusej/utils/GForceWiimoteEventPanel.java b/java/src/wiiusej/utils/GForceWiimoteEventPanel.java new file mode 100644 index 0000000..1ae710e --- /dev/null +++ b/java/src/wiiusej/utils/GForceWiimoteEventPanel.java @@ -0,0 +1,37 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import wiiusej.values.GForce; +import wiiusej.wiiusejevents.GenericEvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; + +/** + * Panel to display GForce in a MotionSensingEvent from a wiimote. + * + * @author guiguito + */ +public class GForceWiimoteEventPanel extends GForcePanel { + + @Override + public GForce getGForceValue(GenericEvent e) { + if (e instanceof MotionSensingEvent) { + return ((MotionSensingEvent) e).getGforce(); + } + return null; + } +} diff --git a/java/src/wiiusej/utils/GuitarHero3ButtonsEventPanel.java b/java/src/wiiusej/utils/GuitarHero3ButtonsEventPanel.java new file mode 100644 index 0000000..fe03337 --- /dev/null +++ b/java/src/wiiusej/utils/GuitarHero3ButtonsEventPanel.java @@ -0,0 +1,274 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.GuitarHeroButtonsEvent; +import wiiusej.wiiusejevents.physicalevents.GuitarHeroEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * This panel is used to display what happens on the buttons of the + * Guitar Hero 3 controller. + * @author guiguito + */ +public class GuitarHero3ButtonsEventPanel extends javax.swing.JPanel implements WiimoteListener { + + /** Creates new form GuitarHero3ButtonsEventPanel */ + public GuitarHero3ButtonsEventPanel() { + initComponents(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + leftPanel = new javax.swing.JPanel(); + plusButton = new javax.swing.JToggleButton(); + minusButton = new javax.swing.JToggleButton(); + strumPanel = new javax.swing.JPanel(); + strumUpButton = new javax.swing.JToggleButton(); + strumDownButton = new javax.swing.JToggleButton(); + RightPanel = new javax.swing.JPanel(); + coloredButtonsPanel = new javax.swing.JPanel(); + orangeButton = new javax.swing.JToggleButton(); + blueButton = new javax.swing.JToggleButton(); + yellowButton = new javax.swing.JToggleButton(); + redButton = new javax.swing.JToggleButton(); + greenButton = new javax.swing.JToggleButton(); + + setBackground(new java.awt.Color(0, 0, 0)); + setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.X_AXIS)); + + leftPanel.setBackground(new java.awt.Color(0, 0, 0)); + leftPanel.setLayout(new javax.swing.BoxLayout(leftPanel, javax.swing.BoxLayout.LINE_AXIS)); + + plusButton.setBackground(new java.awt.Color(255, 255, 255)); + plusButton.setFont(new java.awt.Font("Arial", 1, 24)); + plusButton.setText("+"); + leftPanel.add(plusButton); + + minusButton.setBackground(new java.awt.Color(255, 255, 255)); + minusButton.setFont(new java.awt.Font("Arial", 1, 24)); + minusButton.setText("-"); + leftPanel.add(minusButton); + + strumPanel.setBackground(new java.awt.Color(0, 0, 0)); + strumPanel.setLayout(new javax.swing.BoxLayout(strumPanel, javax.swing.BoxLayout.Y_AXIS)); + + strumUpButton.setBackground(new java.awt.Color(255, 255, 255)); + strumUpButton.setFont(new java.awt.Font("Arial", 1, 24)); + strumUpButton.setText("Strum UP"); + strumPanel.add(strumUpButton); + + strumDownButton.setBackground(new java.awt.Color(255, 255, 255)); + strumDownButton.setFont(new java.awt.Font("Arial", 1, 24)); + strumDownButton.setText("Strum DOWN"); + strumPanel.add(strumDownButton); + + leftPanel.add(strumPanel); + + add(leftPanel); + + RightPanel.setBackground(new java.awt.Color(0, 0, 0)); + RightPanel.setLayout(new javax.swing.BoxLayout(RightPanel, javax.swing.BoxLayout.LINE_AXIS)); + + coloredButtonsPanel.setLayout(new javax.swing.BoxLayout(coloredButtonsPanel, javax.swing.BoxLayout.LINE_AXIS)); + + orangeButton.setBackground(new java.awt.Color(255, 153, 0)); + orangeButton.setFont(new java.awt.Font("Arial", 1, 24)); + orangeButton.setText("O"); + coloredButtonsPanel.add(orangeButton); + + blueButton.setBackground(new java.awt.Color(0, 0, 204)); + blueButton.setFont(new java.awt.Font("Arial", 1, 24)); + blueButton.setText("O"); + coloredButtonsPanel.add(blueButton); + + yellowButton.setBackground(new java.awt.Color(255, 255, 0)); + yellowButton.setFont(new java.awt.Font("Arial", 1, 24)); + yellowButton.setText("O"); + coloredButtonsPanel.add(yellowButton); + + redButton.setBackground(new java.awt.Color(255, 0, 0)); + redButton.setFont(new java.awt.Font("Arial", 1, 24)); + redButton.setText("O"); + coloredButtonsPanel.add(redButton); + + greenButton.setBackground(new java.awt.Color(51, 255, 0)); + greenButton.setFont(new java.awt.Font("Arial", 1, 24)); + greenButton.setText("O"); + coloredButtonsPanel.add(greenButton); + + RightPanel.add(coloredButtonsPanel); + + add(RightPanel); + }// //GEN-END:initComponents + public void onButtonsEvent(WiimoteButtonsEvent arg0) { + //do nothing + } + + public void onIrEvent(IREvent arg0) { + //do nothing + } + + public void onMotionSensingEvent(MotionSensingEvent arg0) { + //do nothing + } + + public void onExpansionEvent(ExpansionEvent arg0) { + if (arg0 instanceof GuitarHeroEvent) { + GuitarHeroEvent guitar = (GuitarHeroEvent) arg0; + GuitarHeroButtonsEvent buttons = guitar.getButtonsEvent(); + + //orange button + if (buttons.isButtonOrangeJustPressed()) { + orangeButton.setSelected(true); + orangeButton.setText("X"); + } else if (buttons.isButtonOrangeJustReleased()) { + orangeButton.setSelected(false); + orangeButton.setText("O"); + } + + //blue button + if (buttons.isButtonBlueJustPressed()) { + blueButton.setSelected(true); + blueButton.setText("X"); + } else if (buttons.isButtonBlueJustReleased()) { + blueButton.setSelected(false); + blueButton.setText("O"); + } + + //Yellow button + if (buttons.isButtonYellowJustPressed()) { + yellowButton.setSelected(true); + yellowButton.setText("X"); + } else if (buttons.isButtonYellowJustReleased()) { + yellowButton.setSelected(false); + yellowButton.setText("O"); + } + + //Red button + if (buttons.isButtonRedJustPressed()) { + redButton.setSelected(true); + redButton.setText("X"); + } else if (buttons.isButtonRedJustReleased()) { + redButton.setSelected(false); + redButton.setText("O"); + } + + //Green button + if (buttons.isButtonGreenJustPressed()) { + greenButton.setSelected(true); + greenButton.setText("X"); + } else if (buttons.isButtonGreenJustReleased()) { + greenButton.setSelected(false); + greenButton.setText("O"); + } + + //Plus button + if (buttons.isButtonPlusJustPressed()) { + plusButton.setSelected(true); + } else if (buttons.isButtonPlusJustReleased()) { + plusButton.setSelected(false); + } + + //Minus button + if (buttons.isButtonMinusJustPressed()) { + minusButton.setSelected(true); + } else if (buttons.isButtonMinusJustReleased()) { + minusButton.setSelected(false); + } + + //Strum up button + if (buttons.isButtonStrumUpJustPressed()) { + strumUpButton.setSelected(true); + } else if (buttons.isButtonStrumUpJustReleased()) { + strumUpButton.setSelected(false); + } + + //Strum down button + if (buttons.isButtonStrumDownJustPressed()) { + strumDownButton.setSelected(true); + } else if (buttons.isButtonStrumDownJustReleased()) { + strumDownButton.setSelected(false); + } + } + } + + public void onStatusEvent(StatusEvent arg0) { + //do nothing + } + + public void onDisconnectionEvent(DisconnectionEvent arg0) { + //do nothing + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent arg0) { + //do nothing + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent arg0) { + //do nothing + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) { + //do nothing + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) { + //do nothing + } + + public void onClassicControllerInsertedEvent(ClassicControllerInsertedEvent arg0) { + //do nothing + } + + public void onClassicControllerRemovedEvent(ClassicControllerRemovedEvent arg0) { + //do nothing + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel RightPanel; + private javax.swing.JToggleButton blueButton; + private javax.swing.JPanel coloredButtonsPanel; + private javax.swing.JToggleButton greenButton; + private javax.swing.JPanel leftPanel; + private javax.swing.JToggleButton minusButton; + private javax.swing.JToggleButton orangeButton; + private javax.swing.JToggleButton plusButton; + private javax.swing.JToggleButton redButton; + private javax.swing.JToggleButton strumDownButton; + private javax.swing.JPanel strumPanel; + private javax.swing.JToggleButton strumUpButton; + private javax.swing.JToggleButton yellowButton; + // End of variables declaration//GEN-END:variables +} diff --git a/java/src/wiiusej/utils/GuitarHeroJoystickEventPanel.java b/java/src/wiiusej/utils/GuitarHeroJoystickEventPanel.java new file mode 100644 index 0000000..6fd906f --- /dev/null +++ b/java/src/wiiusej/utils/GuitarHeroJoystickEventPanel.java @@ -0,0 +1,39 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.GuitarHeroEvent; +import wiiusej.wiiusejevents.physicalevents.JoystickEvent; + +/** + * Panel to display Guitar Hero 3 controller joystick events. + * + * @author guiguito + */ +public class GuitarHeroJoystickEventPanel extends JoystickEventPanel{ + + @Override + public JoystickEvent getJoystickEvent(ExpansionEvent e) { + if (e instanceof GuitarHeroEvent){ + return ((GuitarHeroEvent)e).getGuitarHeroJoystickEvent(); + } + return null; + } + +} diff --git a/java/src/wiiusej/utils/IRPanel.java b/java/src/wiiusej/utils/IRPanel.java new file mode 100644 index 0000000..9d4cf79 --- /dev/null +++ b/java/src/wiiusej/utils/IRPanel.java @@ -0,0 +1,275 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.geom.AffineTransform; + +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * This panel is used to see what the IR camera of the wiimote sees. + * + * @author guiguito + */ +public class IRPanel extends javax.swing.JPanel implements WiimoteListener { + + private static int MAX_NB_POINTS = 4; + private Color color = Color.YELLOW; + private Color backgroundColor = Color.BLACK; + private Color borderColor = Color.BLUE; + private Shape shape; + private Image mImage;// image for double buffering + private int[] xCoordinates; + private int[] yCoordinates; + private int nbPoints = -1; + + /** + * Default constructor for IR Panel. Background color : black. IR sources + * color : yellow. Border color of IR sources : blue. Shape of the IR + * sources : circle with a diameter of 10. + */ + public IRPanel() { + shape = new java.awt.geom.Ellipse2D.Double(0, 0, 10, 10); + initArrays(); + initComponents(); + } + + /** + * Constructor used to parameterize the IR panel. + * + * @param bgColor + * color. + * @param ptColor + * IR sources color. + * @param bdColor + * border color of IR sources. + * @param sh + * Shape of the IR sources. + */ + public IRPanel(Color bgColor, Color ptColor, Color bdColor, Shape sh) { + backgroundColor = bgColor; + color = ptColor; + borderColor = bdColor; + shape = sh; + initArrays(); + initComponents(); + } + + private void initArrays() { + xCoordinates = new int[MAX_NB_POINTS]; + yCoordinates = new int[MAX_NB_POINTS]; + for (int i = 0; i < MAX_NB_POINTS; i++) { + xCoordinates[i] = -1; + yCoordinates[i] = -1; + } + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Dimension d = getSize(); + checkOffScreenImage(); + Graphics offG = mImage.getGraphics(); + offG.setColor(backgroundColor); + offG.fillRect(0, 0, d.width, d.height); + Graphics2D g2 = (Graphics2D) mImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + // draw points + int i = 0; + while (i < nbPoints) { + double x = xCoordinates[i]; + double y = yCoordinates[i]; + + long xx = getWidth() - Math.round((double) getWidth() * x / 1024.0); + long yy = getHeight() + - Math.round((double) getHeight() * y / 768.0); + g2.translate(xx, yy); + + g2.setPaint(borderColor); + g2.draw(shape); + g2.setPaint(color); + g2.fill(shape); + + g2.setTransform(new AffineTransform()); + i++; + } + // put offscreen image on the screen + g.drawImage(mImage, 0, 0, null); + } + + /** + * check if the mImage variable has been initialized. If it's not the case + * it initializes it with the dimensions of the panel. mImage is for double + * buffering. + */ + private void checkOffScreenImage() { + Dimension d = getSize(); + if (mImage == null || mImage.getWidth(null) != d.width + || mImage.getHeight(null) != d.height) { + mImage = createImage(d.width, d.height); + } + } + + public void onButtonsEvent(WiimoteButtonsEvent arg0) { + // nothing + repaint(); + } + + public void onIrEvent(IREvent arg0) { + // transfer points + wiiusej.values.IRSource[] points = arg0.getIRPoints(); + nbPoints = points.length; + for (int i = 0; i < points.length; i++) { + xCoordinates[i] = (int) points[i].getRx(); + yCoordinates[i] = (int) points[i].getRy(); + } + for (int i = points.length; i < MAX_NB_POINTS; i++) { + xCoordinates[i] = -1; + yCoordinates[i] = -1; + } + + // redraw panel + repaint(); + } + + public void onMotionSensingEvent(MotionSensingEvent arg0) { + // nothing + } + + public void onExpansionEvent(ExpansionEvent e) { + // nothing + } + + public void onStatusEvent(StatusEvent arg0) { + // nothing + } + + public void onDisconnectionEvent(DisconnectionEvent arg0) { + // clear previous points + for (int i = 0; i < MAX_NB_POINTS; i++) { + xCoordinates[i] = -1; + yCoordinates[i] = -1; + } + // redraw panel + repaint(); + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent e) { + // nothing + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent e) { + // nothing + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) { + // nothing + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) { + // nothing + } + + public void onClassicControllerInsertedEvent( + ClassicControllerInsertedEvent arg0) { + // nothing + } + + public void onClassicControllerRemovedEvent( + ClassicControllerRemovedEvent arg0) { + // nothing + } + + public Color getBackgroundColor() { + return backgroundColor; + } + + public Color getBorderColor() { + return borderColor; + } + + public Color getColor() { + return color; + } + + public Shape getShape() { + return shape; + } + + public void setBackgroundColor(Color backgroundColor) { + this.backgroundColor = backgroundColor; + } + + public void setBorderColor(Color borderColor) { + this.borderColor = borderColor; + } + + public void setColor(Color color) { + this.color = color; + } + + public void setShape(Shape shape) { + this.shape = shape; + } + + public void clearView() { + initArrays(); + repaint(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 400, + Short.MAX_VALUE)); + layout.setVerticalGroup(layout.createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 300, + Short.MAX_VALUE)); + }// //GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} diff --git a/java/src/wiiusej/utils/JoystickEventPanel.java b/java/src/wiiusej/utils/JoystickEventPanel.java new file mode 100644 index 0000000..2883216 --- /dev/null +++ b/java/src/wiiusej/utils/JoystickEventPanel.java @@ -0,0 +1,248 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.JoystickEvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * Panel to display joystick events. + * + * @author guiguito + */ +public abstract class JoystickEventPanel extends javax.swing.JPanel implements + WiimoteListener { + + private Image mImage;// image for double buffering + private Color backgroundColor = Color.BLACK; + private Color borderColor = Color.RED; + private Color pointColor = Color.RED; + private Shape shape = new java.awt.geom.Ellipse2D.Double(0, 0, 30, 30); + private JoystickEvent lastJoystickEvent = null; + + /** Creates new form JoystickPanel */ + public JoystickEventPanel() { + initComponents(); + } + + /** + * Constructor used to choose the colors used by the JoystickPanel. + * + * @param bgColor + * background color. + * @param pColor + * point color. + * @param bdColor + * border color for the shape. + * @param sh + * shape of what is drawn. + */ + public JoystickEventPanel(Color bgColor, Color pColor, Color bdColor, + Shape sh) { + backgroundColor = bgColor; + pointColor = pColor; + shape = sh; + borderColor = bdColor; + initComponents(); + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Dimension d = getSize(); + checkOffScreenImage(); + Graphics offG = mImage.getGraphics(); + offG.setColor(backgroundColor); + offG.fillRect(0, 0, d.width, d.height); + Graphics2D g2 = (Graphics2D) mImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g2.setTransform(new AffineTransform()); + + // compute center + int xCenter = (int) Math.round(d.getWidth() / 2.0); + int yCenter = (int) Math.round(d.getHeight() / 2.0); + + // compute coordinates + if (lastJoystickEvent != null) { + double xAng = Math.sin(lastJoystickEvent.getAngle() * Math.PI + / 180.0) + * lastJoystickEvent.getMagnitude(); + double yAng = Math.cos(lastJoystickEvent.getAngle() * Math.PI + / 180.0) + * lastJoystickEvent.getMagnitude(); + int halfWidth = (int) Math.round(shape.getBounds().getWidth() / 2); + int halHeight = (int) Math.round(shape.getBounds().getHeight() / 2); + int xAmplitude = (int) Math.round(xCenter - shape.getBounds().getWidth()); + int yAmplitude = (int) Math.round(xCenter - shape.getBounds().getHeight()); + int xShift = (int) Math.round(xAng * xAmplitude); + int yShift = (int) Math.round(yAng * yAmplitude); + int x = xCenter + xShift - halfWidth; + int y = yCenter - yShift - halHeight; + // shape + g2.translate(x, y); + g2.setPaint(borderColor); + g2.draw(shape); + g2.setPaint(pointColor); + g2.fill(shape); + } + // put offscreen image on the screen + g.drawImage(mImage, 0, 0, null); + } + + /** + * check if the mImage variable has been initialized. If it's not the case + * it initializes it with the dimensions of the panel. mImage is for double + * buffering. + */ + private void checkOffScreenImage() { + Dimension d = getSize(); + if (mImage == null || mImage.getWidth(null) != d.width + || mImage.getHeight(null) != d.height) { + mImage = createImage(d.width, d.height); + } + } + + public void onButtonsEvent(WiimoteButtonsEvent arg0) { + // nothing + } + + public void onIrEvent(IREvent arg0) { + // nothing + } + + public void onMotionSensingEvent(MotionSensingEvent arg0) { + // nothing + } + + public void onExpansionEvent(ExpansionEvent arg0) { + JoystickEvent joy = getJoystickEvent(arg0); + if (joy != null) { + lastJoystickEvent = joy; + } + repaint(); + } + + public void onStatusEvent(StatusEvent arg0) { + // nothing + } + + public void onDisconnectionEvent(DisconnectionEvent arg0) { + // nothing + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent arg0) { + // nothing + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent arg0) { + // nothing + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) { + // nothing + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) { + // nothing + } + + public void onClassicControllerInsertedEvent( + ClassicControllerInsertedEvent arg0) { + // nothing + } + + public void onClassicControllerRemovedEvent( + ClassicControllerRemovedEvent arg0) { + // nothing + } + + public Color getBackgroundColor() { + return backgroundColor; + } + + public Color getPointColor() { + return pointColor; + } + + public Color getBorderColor() { + return borderColor; + } + + public Shape getShape() { + return shape; + } + + public void setBackgroundColor(Color backgroundColor) { + this.backgroundColor = backgroundColor; + } + + public void setPointColor(Color pointColor) { + this.pointColor = pointColor; + } + + public void setBorderColor(Color borderColor) { + this.borderColor = borderColor; + } + + public void setShape(Shape shape) { + this.shape = shape; + } + + public abstract JoystickEvent getJoystickEvent(ExpansionEvent e); + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 400, + Short.MAX_VALUE)); + layout.setVerticalGroup(layout.createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 300, + Short.MAX_VALUE)); + }// //GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} diff --git a/java/src/wiiusej/utils/NunchukJoystickEventPanel.java b/java/src/wiiusej/utils/NunchukJoystickEventPanel.java new file mode 100644 index 0000000..9d088bc --- /dev/null +++ b/java/src/wiiusej/utils/NunchukJoystickEventPanel.java @@ -0,0 +1,38 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.JoystickEvent; +import wiiusej.wiiusejevents.physicalevents.NunchukEvent; + +/** + * Panel to display nunchuk joystick events. + * + * @author guiguito + */ +public class NunchukJoystickEventPanel extends JoystickEventPanel { + + @Override + public JoystickEvent getJoystickEvent(ExpansionEvent e) { + if (e instanceof NunchukEvent) { + return ((NunchukEvent) e).getNunchukJoystickEvent(); + } + return null; + } +} diff --git a/java/src/wiiusej/utils/OrientationExpansionEventPanel.java b/java/src/wiiusej/utils/OrientationExpansionEventPanel.java new file mode 100644 index 0000000..f5e3856 --- /dev/null +++ b/java/src/wiiusej/utils/OrientationExpansionEventPanel.java @@ -0,0 +1,38 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import wiiusej.values.Orientation; +import wiiusej.wiiusejevents.GenericEvent; +import wiiusej.wiiusejevents.physicalevents.NunchukEvent; + +/** + * Panel to display Orientation in a MotionSensingEvent from an expansion. + * + * @author guiguito + */ +public class OrientationExpansionEventPanel extends OrientationPanel { + + @Override + public Orientation getOrientationValue(GenericEvent e) { + if (e instanceof NunchukEvent) { + return ((NunchukEvent) e).getNunchukMotionSensingEvent() + .getOrientation(); + } + return null; + } +} diff --git a/java/src/wiiusej/utils/OrientationPanel.java b/java/src/wiiusej/utils/OrientationPanel.java new file mode 100644 index 0000000..839fdfd --- /dev/null +++ b/java/src/wiiusej/utils/OrientationPanel.java @@ -0,0 +1,305 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.util.ArrayList; + +import wiiusej.values.Orientation; +import wiiusej.wiiusejevents.GenericEvent; +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.utils.WiimoteListener; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * This panel is used to watch orientation values from a MotionSensingEvent. + * + * @author guiguito + */ +public abstract class OrientationPanel extends javax.swing.JPanel implements + WiimoteListener { + + private Image mImage;// image for double buffering + private Color rollColor = Color.RED; + private Color pitchColor = Color.GREEN; + private Color yawColor = Color.BLUE; + private Color backgroundColor = Color.WHITE; + private Color lineColor = Color.BLACK; + private ArrayList values = new ArrayList(); + + /** + * Default constructor. Background color : White. Roll color : Red. Pitch + * color : Green. Yaw color : Blue. + */ + public OrientationPanel() { + initComponents(); + } + + /** + * Constructor used to choose the colors used by the OrientationPanel. + * + * @param bgColor + * background color. + * @param rColor + * roll color. + * @param pColor + * pitch color. + * @param yColor + * yaw color. + * @param lColor + * line color. + */ + public OrientationPanel(Color bgColor, Color rColor, Color pColor, + Color yColor, Color lColor) { + backgroundColor = bgColor; + rollColor = rColor; + pitchColor = pColor; + yawColor = yColor; + lineColor = lColor; + initComponents(); + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Dimension d = getSize(); + checkOffScreenImage(); + Graphics offG = mImage.getGraphics(); + offG.setColor(backgroundColor); + offG.fillRect(0, 0, d.width, d.height); + Graphics2D g2 = (Graphics2D) mImage.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + // draw medium line + double yMiddleFloat = getHeight() / 2.0; + int yMiddle = (int) Math.round(yMiddleFloat); + + g2.setPaint(lineColor); + g2.drawLine(0, yMiddle, getWidth(), yMiddle); + + Orientation[] valuesArray = values.toArray(new Orientation[0]); + double unit = yMiddleFloat / 180.0; + int previousRoll = 0; + int previousPitch = 0; + int previousYaw = 0; + // draw curves + for (int i = 0; i < valuesArray.length && i < getWidth(); i++) { + Orientation orientation = valuesArray[i]; + // draw roll + g2.setPaint(rollColor); + int yDelta = (int) Math.round(unit * orientation.getRoll()); + int y = -1 * yDelta + yMiddle; + g2.drawLine(i - 1, previousRoll, i, y); + g2.setTransform(new AffineTransform()); + previousRoll = y; + // draw pitch + g2.setPaint(pitchColor); + yDelta = (int) Math.round(unit * orientation.getPitch()); + y = -1 * yDelta + yMiddle; + g2.drawLine(i - 1, previousPitch, i, y); + g2.setTransform(new AffineTransform()); + previousPitch = y; + // draw yaw + g2.setPaint(yawColor); + yDelta = (int) Math.round(unit * orientation.getYaw()); + y = -1 * yDelta + yMiddle; + g2.drawLine(i - 1, previousYaw, i, y); + g2.setTransform(new AffineTransform()); + previousYaw = y; + } + + // draw legend + g2.setPaint(rollColor); + g2.drawLine(5, getHeight() - 10, 25, getHeight() - 10); + g2.setPaint(pitchColor); + g2.drawLine(60, getHeight() - 10, 80, getHeight() - 10); + g2.setPaint(yawColor); + g2.drawLine(120, getHeight() - 10, 140, getHeight() - 10); + + g2.setPaint(lineColor); + g2.drawString("Roll", 30, getHeight() - 5); + g2.drawString("Pitch", 85, getHeight() - 5); + g2.drawString("Yaw", 145, getHeight() - 5); + g2.drawString("0", 2, yMiddle - 5); + g2.drawString("180", 2, 10); + g2.drawString("-180", 2, getHeight() - 15); + // put offscreen image on the screen + g.drawImage(mImage, 0, 0, null); + } + + /** + * check if the mImage variable has been initialized. If it's not the case + * it initializes it with the dimensions of the panel. mImage is for double + * buffering. + */ + private void checkOffScreenImage() { + Dimension d = getSize(); + if (mImage == null || mImage.getWidth(null) != d.width + || mImage.getHeight(null) != d.height) { + mImage = createImage(d.width, d.height); + } + } + + public void onButtonsEvent(WiimoteButtonsEvent arg0) { + // nothing + } + + public void onIrEvent(IREvent arg0) { + // nothing + } + + public void onMotionSensingEvent(MotionSensingEvent arg0) { + draw(arg0); + } + + public void onExpansionEvent(ExpansionEvent arg0) { + draw(arg0); + } + + public void onStatusEvent(StatusEvent arg0) { + // nothing + } + + public void onDisconnectionEvent(DisconnectionEvent arg0) { + // Clear points. + values.clear(); + repaint(); + } + + public void onNunchukInsertedEvent(NunchukInsertedEvent arg0) { + // nothing + } + + public void onNunchukRemovedEvent(NunchukRemovedEvent arg0) { + // nothing + } + + public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) { + // nothing + } + + public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) { + // nothing + } + + public void onClassicControllerInsertedEvent( + ClassicControllerInsertedEvent arg0) { + // nothing + } + + public void onClassicControllerRemovedEvent( + ClassicControllerRemovedEvent arg0) { + // nothing + } + + private void draw(GenericEvent arg0) { + if (values.size() >= getWidth()) { + // if there are as many values as pixels in the width + // clear points + values.clear(); + } + Orientation orientation = getOrientationValue(arg0); + if (orientation != null) + values.add(orientation); + repaint(); + } + + public abstract Orientation getOrientationValue(GenericEvent e); + + public Color getBackgroundColor() { + return backgroundColor; + } + + public Color getLineColor() { + return lineColor; + } + + public Color getPitchColor() { + return pitchColor; + } + + public Color getRollColor() { + return rollColor; + } + + public Color getYawColor() { + return yawColor; + } + + public void setBackgroundColor(Color backgroundColor) { + this.backgroundColor = backgroundColor; + } + + public void setLineColor(Color lineColor) { + this.lineColor = lineColor; + } + + public void setPitchColor(Color pitchColor) { + this.pitchColor = pitchColor; + } + + public void setRollColor(Color rollColor) { + this.rollColor = rollColor; + } + + public void setYawColor(Color yawColor) { + this.yawColor = yawColor; + } + + public void clearView() { + values.clear(); + repaint(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 400, + Short.MAX_VALUE)); + layout.setVerticalGroup(layout.createParallelGroup( + javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 300, + Short.MAX_VALUE)); + }// //GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} diff --git a/java/src/wiiusej/utils/OrientationWiimoteEventPanel.java b/java/src/wiiusej/utils/OrientationWiimoteEventPanel.java new file mode 100644 index 0000000..e38f3c9 --- /dev/null +++ b/java/src/wiiusej/utils/OrientationWiimoteEventPanel.java @@ -0,0 +1,38 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.utils; + +import wiiusej.values.Orientation; +import wiiusej.wiiusejevents.GenericEvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; + +/** + * Panel to display Orientation in a MotionSensingEvent from a wiimote. + * + * @author guiguito + */ +public class OrientationWiimoteEventPanel extends OrientationPanel { + + @Override + public Orientation getOrientationValue(GenericEvent e) { + if (e instanceof MotionSensingEvent) { + return ((MotionSensingEvent) e).getOrientation(); + } + return null; + } + +} diff --git a/java/src/wiiusej/values/GForce.java b/java/src/wiiusej/values/GForce.java new file mode 100644 index 0000000..da79ed2 --- /dev/null +++ b/java/src/wiiusej/values/GForce.java @@ -0,0 +1,80 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.values; + +/** + * Represents gravity force on each axis. + * + * @author guiguito + */ +public class GForce { + + private float x; + private float y; + private float z; + + /** + * Default constructor; + */ + public GForce() { + x = 0; + y = 0; + z = 0; + } + + /** + * Constructor with gravity force on each axis. + * + * @param xx + * x value + * @param yy + * x value + * @param zz + * x value + */ + public GForce(float xx, float yy, float zz) { + x = xx; + y = yy; + z = zz; + } + + /** + * @return the x + */ + public float getX() { + return x; + } + + /** + * @return the y + */ + public float getY() { + return y; + } + + /** + * @return the z + */ + public float getZ() { + return z; + } + + @Override + public String toString() { + return "Gravity force : (" + x + ", " + y + "," + z + ")"; + } +} diff --git a/java/src/wiiusej/values/IRSource.java b/java/src/wiiusej/values/IRSource.java new file mode 100644 index 0000000..a738c05 --- /dev/null +++ b/java/src/wiiusej/values/IRSource.java @@ -0,0 +1,106 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.values; + +/** + * Class used for IR sources. + * + * @author guiguito + */ +public class IRSource { + + private int x; + private int y; + private short rx; + private short ry; + private short size; + + /** + * Build an IR source with all details. + * + * @param xx + * xx interpolated coordinates. + * @param yy + * yy interpolated coordinates. + * @param rxx + * raw X coordinate (0-1023). + * @param ryy + * raw Y coordinate (0-1023). + * @param si + * size of the IR dot (0-15). + */ + public IRSource(int xx, int yy, short rxx, short ryy, short si) { + x = xx; + y = yy; + rx = rxx; + ry = ryy; + size = si; + } + + /** + * Return x interpolated coordinates. + * + * @return the x + */ + public int getX() { + return x; + } + + /** + * Return y interpolated coordinates. + * + * @return the y + */ + public int getY() { + return y; + } + + /** + * Return raw X coordinate (0-1023). + * + * @return the rx + */ + public short getRx() { + return rx; + } + + /** + * Return raw Y coordinate (0-1023). + * + * @return the ry + */ + public short getRy() { + return ry; + } + + /** + * Return size of the IR dot (0-15). + * + * @return the size + */ + public short getSize() { + return size; + } + + @Override + public String toString() { + return "Interpolated coordinates (" + x + "," + y + + "), Raw coordinates(" + rx + "," + ry + "), source size : " + + size + ")"; + } + +} diff --git a/java/src/wiiusej/values/Orientation.java b/java/src/wiiusej/values/Orientation.java new file mode 100644 index 0000000..124d890 --- /dev/null +++ b/java/src/wiiusej/values/Orientation.java @@ -0,0 +1,117 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.values; + +/** + * Class that represents the orientation of the wiimote. + * + * @author guiguito + */ +public class Orientation { + + private float roll; + private float pitch; + private float yaw; + private float a_roll; + private float a_pitch; + + /** + * Default constructor. + */ + public Orientation() { + roll = 0; + pitch = 0; + yaw = 0; + a_roll = 0; + a_pitch = 0; + } + + /** + * Contructor with raw, pitch , yaw. + * + * @param r + * roll (can be smoothed) + * @param p + * pitch (can be smoothed) + * @param y + * yaw + * @param ar + * absolute roll + * @param ap + * absolute pitch + */ + public Orientation(float r, float p, float y, float ar, float ap) { + roll = r; + pitch = p; + yaw = y; + a_roll = ar; + a_pitch = ap; + } + + /** + * Get the roll (can be smoothed). + * + * @return the roll + */ + public float getRoll() { + return roll; + } + + /** + * Get the pitch (can be smoothed). + * + * @return the pitch + */ + public float getPitch() { + return pitch; + } + + /** + * Get the yaw. + * + * @return the yaw + */ + public float getYaw() { + return yaw; + } + + /** + * Get absolute roll (can not be smoothed). + * + * @return the a_roll + */ + public float getARoll() { + return a_roll; + } + + /** + * Get absolute pitch (can not be smoothed). + * + * @return the a_pitch + */ + public float getAPitch() { + return a_pitch; + } + + @Override + public String toString() { + return "Orientation : (roll: " + roll + ", pitch: " + pitch + ", yaw: " + + yaw + ", absolute roll: " + a_roll + ", absolute pitch: " + + a_pitch + ")"; + } + +} diff --git a/java/src/wiiusej/values/RawAcceleration.java b/java/src/wiiusej/values/RawAcceleration.java new file mode 100644 index 0000000..83f9578 --- /dev/null +++ b/java/src/wiiusej/values/RawAcceleration.java @@ -0,0 +1,81 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.values; + +/** + * Represents raw acceleration on each axis. + * + * @author guiguito + */ +public class RawAcceleration { + + private short x; + private short y; + private short z; + + /** + * Default constructor; + */ + public RawAcceleration() { + x = 0; + y = 0; + z = 0; + } + + /** + * Constructor with raw acceleration on each axis. + * + * @param xx + * x value + * @param yy + * x value + * @param zz + * x value + */ + public RawAcceleration(short xx, short yy, short zz) { + x = xx; + y = yy; + z = zz; + } + + /** + * @return the x + */ + public short getX() { + return x; + } + + /** + * @return the y + */ + public short getY() { + return y; + } + + /** + * @return the z + */ + public short getZ() { + return z; + } + + @Override + public String toString() { + return "Raw acceleration : (" + x + ", " + y + "," + z + ")"; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/GenericEvent.java b/java/src/wiiusej/wiiusejevents/GenericEvent.java new file mode 100644 index 0000000..18d8429 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/GenericEvent.java @@ -0,0 +1,59 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents; + +/** + * Abstract mother class representing an event with a wiimote id. + * + * @author guiguito + */ +public abstract class GenericEvent { + + /* ID */ + private int wiimoteId = -1; + + /** + * Construct the WiiUseApiEvent setting up the id. + * + * @param id + * the Wiimote id + */ + public GenericEvent(int id) { + wiimoteId = id; + } + + /** + * Get Wiimote ID + * + * @return the wiimote id. + */ + public int getWiimoteId() { + return wiimoteId; + } + + /** + * Set Wiimote ID + * + * @param wiimoteId + * id of the wiimote + */ + void setWiimoteId(int wiimoteId) { + this.wiimoteId = wiimoteId; + } + + public abstract String toString(); +} diff --git a/java/src/wiiusej/wiiusejevents/physicalevents/ButtonsEvent.java b/java/src/wiiusej/wiiusejevents/physicalevents/ButtonsEvent.java new file mode 100644 index 0000000..b07aa43 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/physicalevents/ButtonsEvent.java @@ -0,0 +1,128 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.physicalevents; + +import wiiusej.wiiusejevents.GenericEvent; + +/** + * Class which represents a buttons event. + * + * @author guiguito + */ +public abstract class ButtonsEvent extends GenericEvent { + + /* Buttons */ + private short buttonsJustPressed = 0; + private short buttonsJustReleased = 0; + private short buttonsHeld = 0; + + /** + * Constructor of the button Event. + * + * @param id + * id of the wiimote concerned. + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just held. + */ + public ButtonsEvent(int id, short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld) { + super(id); + setAllButtons(buttonsJustPressed, buttonsJustReleased, buttonsHeld); + } + + /** + * Set all buttons in one method. + * + * @param buttonsJustPressed + * @param buttonsJustReleased + * @param buttonsHeld + */ + private void setAllButtons(short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld) { + this.buttonsJustPressed = buttonsJustPressed; + this.buttonsJustReleased = buttonsJustReleased; + this.buttonsHeld = buttonsHeld; + } + + /** + * Get the short storing the buttons just pressed + * + * @return the short storing the buttons just pressed + */ + public short getButtonsJustPressed() { + return buttonsJustPressed; + } + + /** + * Get the short storing the buttons just released + * + * @return the short storing the buttons just released + */ + public short getButtonsJustReleased() { + return buttonsJustReleased; + } + + /** + * get the short storing the buttons held + * + * @return the short storing the buttons held + */ + public short getButtonsHeld() { + return buttonsHeld; + } + + /** **************** BUTTONS Methods ***************** */ + /* generic button functions */ + + protected boolean buttonTest(int buttonBitsDefinition, int buttons) { + return (buttons & buttonBitsDefinition) == buttonBitsDefinition; + } + + protected boolean isButtonJustPressed(int buttonBitsDefinition) { + return buttonTest(buttonBitsDefinition, buttonsJustPressed) + && !isButtonHeld(buttonBitsDefinition); + } + + protected boolean isButtonJustReleased(int buttonBitsDefinition) { + return buttonTest(buttonBitsDefinition, buttonsJustReleased); + } + + protected boolean isButtonHeld(int buttonBitsDefinition) { + return buttonTest(buttonBitsDefinition, buttonsHeld); + } + + protected boolean isButtonPressed(int buttonBitsDefinition) { + return isButtonHeld(buttonBitsDefinition) + || isButtonJustPressed(buttonBitsDefinition); + } + + @Override + public String toString() { + String out = ""; + /* Display buttons */ + out += "/******** Buttons ********/\n"; + out += "--- Buttons just pressed : " + buttonsJustPressed + "\n"; + out += "--- Buttons just released : " + buttonsJustReleased + "\n"; + out += "--- Buttons held : " + buttonsHeld + "\n"; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/physicalevents/ClassicControllerButtonsEvent.java b/java/src/wiiusej/wiiusejevents/physicalevents/ClassicControllerButtonsEvent.java new file mode 100644 index 0000000..347e27c --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/physicalevents/ClassicControllerButtonsEvent.java @@ -0,0 +1,329 @@ +/* This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.physicalevents; + +/** + * Class which represents a buttons event from a Classic controller. + * + * @author guiguito + */ +public class ClassicControllerButtonsEvent extends ButtonsEvent{ + + private static short CLASSIC_CTRL_BUTTON_UP = 0x0001; + private static short CLASSIC_CTRL_BUTTON_LEFT = 0x0002; + private static short CLASSIC_CTRL_BUTTON_ZR = 0x0004; + private static short CLASSIC_CTRL_BUTTON_X = 0x0008; + private static short CLASSIC_CTRL_BUTTON_A = 0x0010; + private static short CLASSIC_CTRL_BUTTON_Y = 0x0020; + private static short CLASSIC_CTRL_BUTTON_B = 0x0040; + private static short CLASSIC_CTRL_BUTTON_ZL = 0x0080; + private static short CLASSIC_CTRL_BUTTON_FULL_R = 0x0200; + private static short CLASSIC_CTRL_BUTTON_PLUS = 0x0400; + private static short CLASSIC_CTRL_BUTTON_HOME = 0x0800; + private static short CLASSIC_CTRL_BUTTON_MINUS = 0x1000; + private static short CLASSIC_CTRL_BUTTON_FULL_L = 0x2000; + private static short CLASSIC_CTRL_BUTTON_DOWN = 0x4000; + private static int CLASSIC_CTRL_BUTTON_RIGHT = 0x8000; + private static int CLASSIC_CTRL_BUTTON_ALL = 0xFEFF; + + /** + * Constructor of the classic controller buttons Event. + * + * @param id + * id of the wiimote. + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just pressed. + */ + public ClassicControllerButtonsEvent(int id, short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld) { + super(id, buttonsJustPressed, buttonsJustReleased, buttonsHeld); + } + + /* Button LEFT */ + + public boolean isButtonLeftJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_LEFT); + } + + public boolean isButtonLeftJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_LEFT); + } + + public boolean isButtonLeftHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_LEFT); + } + + public boolean isButtonLeftPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_LEFT); + } + + /* Button RIGHT */ + + public boolean isButtonRightJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_RIGHT); + } + + public boolean isButtonRightJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_RIGHT); + } + + public boolean isButtonRightHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_RIGHT); + } + + public boolean isButtonRightPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_RIGHT); + } + + /* Button UP */ + + public boolean isButtonUpJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_UP); + } + + public boolean isButtonUpJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_UP); + } + + public boolean isButtonUpHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_UP); + } + + public boolean isButtonUpPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_UP); + } + + /* Button DOWN */ + + public boolean isButtonDownJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_DOWN); + } + + public boolean isButtonDownJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_DOWN); + } + + public boolean isButtonDownHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_DOWN); + } + + public boolean isButtonDownPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_DOWN); + } + + /* Button A */ + + public boolean isButtonAJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_A); + } + + public boolean isButtonAJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_A); + } + + public boolean isButtonAHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_A); + } + + public boolean isButtonAPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_A); + } + + /* Button B */ + + public boolean isButtonBJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_B); + } + + public boolean isButtonBJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_B); + } + + public boolean isButtonBHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_B); + } + + public boolean isButtonBPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_B); + } + + /* Button X */ + + public boolean isButtonXJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_X); + } + + public boolean isButtonXJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_X); + } + + public boolean isButtonXHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_X); + } + + public boolean isButtonXPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_X); + } + + /* Button Y */ + + public boolean isButtonYJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_Y); + } + + public boolean isButtonYJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_Y); + } + + public boolean isButtonYHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_Y); + } + + public boolean isButtonYPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_Y); + } + + /* Button FullLeft */ + + public boolean isButtonFullLeftJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_FULL_L); + } + + public boolean isButtonFullLeftJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_FULL_L); + } + + public boolean isButtonFullLeftHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_FULL_L); + } + + public boolean isButtonFullLeftPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_FULL_L); + } + + /* Button FullRight */ + + public boolean isButtonFullRightJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_FULL_R); + } + + public boolean isButtonFullRightJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_FULL_R); + } + + public boolean isButtonFullRightHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_FULL_R); + } + + public boolean isButtonFullRightPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_FULL_R); + } + + /* Button Home */ + + public boolean isButtonHomeJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_HOME); + } + + public boolean isButtonHomeJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_HOME); + } + + public boolean isButtonHomeHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_HOME); + } + + public boolean isButtonHomePressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_HOME); + } + + /* Button Minus */ + + public boolean isButtonMinusJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_MINUS); + } + + public boolean isButtonMinusJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_MINUS); + } + + public boolean isButtonMinusHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_MINUS); + } + + public boolean isButtonMinusPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_MINUS); + } + + /* Button Plus */ + + public boolean isButtonPlusJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_PLUS); + } + + public boolean isButtonPlusJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_PLUS); + } + + public boolean isButtonPlusHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_PLUS); + } + + public boolean isButtonPlusPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_PLUS); + } + + /* Button ZL */ + + public boolean isButtonZLJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_ZL); + } + + public boolean isButtonZLJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_ZL); + } + + public boolean isButtonZLHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_ZL); + } + + public boolean isButtonZLPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_ZL); + } + + /* Button ZR */ + + public boolean isButtonZRJustPressed() { + return isButtonJustPressed(CLASSIC_CTRL_BUTTON_ZR); + } + + public boolean isButtonZRJustReleased() { + return isButtonJustReleased(CLASSIC_CTRL_BUTTON_ZR); + } + + public boolean isButtonZRHeld() { + return isButtonHeld(CLASSIC_CTRL_BUTTON_ZR); + } + + public boolean isButtonZRPressed() { + return isButtonPressed(CLASSIC_CTRL_BUTTON_ZR); + } + +} diff --git a/java/src/wiiusej/wiiusejevents/physicalevents/ClassicControllerEvent.java b/java/src/wiiusej/wiiusejevents/physicalevents/ClassicControllerEvent.java new file mode 100644 index 0000000..ce04bd7 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/physicalevents/ClassicControllerEvent.java @@ -0,0 +1,177 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.physicalevents; + +/** + * This class represents the values from the classic controller and its events. + * + * @author guiguito + */ +public class ClassicControllerEvent extends ExpansionEvent { + + private float rightShoulder; + private float leftShoulder; + private ClassicControllerButtonsEvent buttonsEvent; + private JoystickEvent classicControllerRightJoystickEvent; + private JoystickEvent classicControllerLeftJoystickEvent; + + /** + * Constructor of ClassicControllerEvent. + * + * @param id + * id of the wiimote. + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just pressed. + * @param rightShoulder + * right shoulder button (range 0-1). + * @param leftShoulder + * left shoulder button (range 0-1). + * @param langle + * angle the left joystick is being held. + * @param lmagnitude + * magnitude of the left joystick (range 0-1). + * @param lmax1 + * maximum left joystick value 1. + * @param lmax2 + * maximum left joystick value 2. + * @param lmin1 + * minimum left joystick value 1. + * @param lmin2 + * minimum left joystick value 2. + * @param lcenter1 + * center left joystick value 1. + * @param lcenter2 + * center left joystick value 2. + * @param rangle + * angle the right joystick is being held. + * @param rmagnitude + * magnitude of the right joystick (range 0-1). + * @param rmax1 + * maximum right joystick value 1. + * @param rmax2 + * maximum right joystick value 2. + * @param rmin1 + * minimum right joystick value 1. + * @param rmin2 + * minimum right joystick value 2. + * @param rcenter1 + * center right joystick value 1. + * @param rcenter2 + * center right joystick value 2. + */ + public ClassicControllerEvent(int id, short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld, float rightShoulder, + float leftShoulder, float langle, float lmagnitude, short lmax1, + short lmax2, short lmin1, short lmin2, short lcenter1, + short lcenter2, float rangle, float rmagnitude, short rmax1, + short rmax2, short rmin1, short rmin2, short rcenter1, + short rcenter2) { + super(id); + this.leftShoulder = leftShoulder; + this.rightShoulder = rightShoulder; + buttonsEvent = new ClassicControllerButtonsEvent(id, + buttonsJustPressed, buttonsJustReleased, buttonsHeld); + classicControllerLeftJoystickEvent = new JoystickEvent(id, langle, + lmagnitude, lmax1, lmax2, lmin1, lmin2, lcenter1, lcenter2); + classicControllerRightJoystickEvent = new JoystickEvent(id, rangle, + rmagnitude, rmax1, rmax2, rmin1, rmin2, rcenter1, rcenter2); + } + + /** + * Tell if there is a classic controller left joystick event. + * + * @return TRUE if there is a classic controller left joystick event, false + * otherwise. + */ + public boolean isThereClassicControllerLeftJoystickEvent() { + return classicControllerLeftJoystickEvent != null; + } + + /** + * Tell if there is a classic controller right joystick event. + * + * @return TRUE if there is a classic controller right joystick event, false + * otherwise. + */ + public boolean isThereClassicControllerRightJoystickEvent() { + return classicControllerRightJoystickEvent != null; + } + + /** + * Get the right shoulder button(range 0-1). + * + * @return value of the rightShoulder button. + */ + public float getRightShoulder() { + return rightShoulder; + } + + /** + * Get the left shoulder button(range 0-1). + * + * @return value of the leftShoulder button. + */ + public float getLeftShoulder() { + return leftShoulder; + } + + /** + * Get buttons event for the classic controller. + * + * @return the classic controller buttons event if there is one or null. + */ + public ClassicControllerButtonsEvent getButtonsEvent() { + return buttonsEvent; + } + + /** + * Get event from the right joystick of the classic controller. + * + * @return the classic controller right Joystick Event if there is one or null. + */ + public JoystickEvent getClassicControllerRightJoystickEvent() { + return classicControllerRightJoystickEvent; + } + + /** + * Get event from the left joystick of the classic controller. + * + * @return the classic controller left Joystick Event if there is one or null. + */ + public JoystickEvent getClassicControllerLeftJoystickEvent() { + return classicControllerLeftJoystickEvent; + } + + @Override + public String toString() { + String out = ""; + /* Status */ + out += "/*********** Classic Controller EVENT : WIIMOTE ID :" + + getWiimoteId() + " ********/\n"; + out += buttonsEvent; + out += "Left shoulder : " + leftShoulder + "\n"; + out += "Right shoulder : " + rightShoulder + "\n"; + out += classicControllerLeftJoystickEvent; + out += classicControllerRightJoystickEvent; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/physicalevents/ExpansionEvent.java b/java/src/wiiusej/wiiusejevents/physicalevents/ExpansionEvent.java new file mode 100644 index 0000000..868f33c --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/physicalevents/ExpansionEvent.java @@ -0,0 +1,40 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.physicalevents; + +import wiiusej.wiiusejevents.GenericEvent; + +/** + * Mother Class of all expansions event. + * + * @author guiguito + */ +public abstract class ExpansionEvent extends GenericEvent { + + /** + * Constructor of an ExpansionEvent. + * + * @param id + * id of the wiimote to which the expansion is connected. + */ + public ExpansionEvent(int id) { + super(id); + } + + public abstract String toString(); + +} diff --git a/java/src/wiiusej/wiiusejevents/physicalevents/GuitarHeroButtonsEvent.java b/java/src/wiiusej/wiiusejevents/physicalevents/GuitarHeroButtonsEvent.java new file mode 100644 index 0000000..df04048 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/physicalevents/GuitarHeroButtonsEvent.java @@ -0,0 +1,214 @@ +/* This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.physicalevents; + +/** + * Class which represents a buttons event from a Guitar Hero controller. + * + * @author guiguito + */ +public class GuitarHeroButtonsEvent extends ButtonsEvent { + + private static short GUITAR_HERO_3_BUTTON_STRUM_UP = 0x0001; + private static short GUITAR_HERO_3_BUTTON_YELLOW = 0x0008; + private static short GUITAR_HERO_3_BUTTON_GREEN = 0x0010; + private static short GUITAR_HERO_3_BUTTON_BLUE = 0x0020; + private static short GUITAR_HERO_3_BUTTON_RED = 0x0040; + private static short GUITAR_HERO_3_BUTTON_ORANGE = 0x0080; + private static short GUITAR_HERO_3_BUTTON_PLUS = 0x0400; + private static short GUITAR_HERO_3_BUTTON_MINUS = 0x1000; + private static short GUITAR_HERO_3_BUTTON_STRUM_DOWN = 0x4000; + private static int GUITAR_HERO_3_BUTTON_ALL = 0xFEFF; + + /** + * Constructor of the guitar hero buttons Event. + * + * @param id + * id of the wiimote. + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just pressed. + */ + public GuitarHeroButtonsEvent(int id, short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld) { + super(id, buttonsJustPressed, buttonsJustReleased, buttonsHeld); + } + + /* Button Strum Up */ + + public boolean isButtonStrumUpJustPressed() { + return isButtonJustPressed(GUITAR_HERO_3_BUTTON_STRUM_UP); + } + + public boolean isButtonStrumUpJustReleased() { + return isButtonJustReleased(GUITAR_HERO_3_BUTTON_STRUM_UP); + } + + public boolean isButtonStrumUpeHeld() { + return isButtonHeld(GUITAR_HERO_3_BUTTON_STRUM_UP); + } + + public boolean isButtonStrumUpPressed() { + return isButtonPressed(GUITAR_HERO_3_BUTTON_STRUM_UP); + } + + /* Button Strum Down */ + + public boolean isButtonStrumDownJustPressed() { + return isButtonJustPressed(GUITAR_HERO_3_BUTTON_STRUM_DOWN); + } + + public boolean isButtonStrumDownJustReleased() { + return isButtonJustReleased(GUITAR_HERO_3_BUTTON_STRUM_DOWN); + } + + public boolean isButtonStrumDowneHeld() { + return isButtonHeld(GUITAR_HERO_3_BUTTON_STRUM_DOWN); + } + + public boolean isButtonStrumDownPressed() { + return isButtonPressed(GUITAR_HERO_3_BUTTON_STRUM_DOWN); + } + + /* Button blue */ + + public boolean isButtonBlueJustPressed() { + return isButtonJustPressed(GUITAR_HERO_3_BUTTON_BLUE); + } + + public boolean isButtonBlueJustReleased() { + return isButtonJustReleased(GUITAR_HERO_3_BUTTON_BLUE); + } + + public boolean isButtonBlueHeld() { + return isButtonHeld(GUITAR_HERO_3_BUTTON_BLUE); + } + + public boolean isButtonBluePressed() { + return isButtonPressed(GUITAR_HERO_3_BUTTON_BLUE); + } + + /* Button Green */ + + public boolean isButtonGreenJustPressed() { + return isButtonJustPressed(GUITAR_HERO_3_BUTTON_GREEN); + } + + public boolean isButtonGreenJustReleased() { + return isButtonJustReleased(GUITAR_HERO_3_BUTTON_GREEN); + } + + public boolean isButtonGreenHeld() { + return isButtonHeld(GUITAR_HERO_3_BUTTON_GREEN); + } + + public boolean isButtonGreenPressed() { + return isButtonPressed(GUITAR_HERO_3_BUTTON_GREEN); + } + + /* Button Minus */ + + public boolean isButtonMinusJustPressed() { + return isButtonJustPressed(GUITAR_HERO_3_BUTTON_MINUS); + } + + public boolean isButtonMinusJustReleased() { + return isButtonJustReleased(GUITAR_HERO_3_BUTTON_MINUS); + } + + public boolean isButtonMinusHeld() { + return isButtonHeld(GUITAR_HERO_3_BUTTON_MINUS); + } + + public boolean isButtonMinusPressed() { + return isButtonPressed(GUITAR_HERO_3_BUTTON_MINUS); + } + + /* Button Orange */ + + public boolean isButtonOrangeJustPressed() { + return isButtonJustPressed(GUITAR_HERO_3_BUTTON_ORANGE); + } + + public boolean isButtonOrangeJustReleased() { + return isButtonJustReleased(GUITAR_HERO_3_BUTTON_ORANGE); + } + + public boolean isButtonOrangeHeld() { + return isButtonHeld(GUITAR_HERO_3_BUTTON_ORANGE); + } + + public boolean isButtonOrangePressed() { + return isButtonPressed(GUITAR_HERO_3_BUTTON_ORANGE); + } + + /* Button Plus */ + + public boolean isButtonPlusJustPressed() { + return isButtonJustPressed(GUITAR_HERO_3_BUTTON_PLUS); + } + + public boolean isButtonPlusJustReleased() { + return isButtonJustReleased(GUITAR_HERO_3_BUTTON_PLUS); + } + + public boolean isButtonPlusHeld() { + return isButtonHeld(GUITAR_HERO_3_BUTTON_PLUS); + } + + public boolean isButtonPlusPressed() { + return isButtonPressed(GUITAR_HERO_3_BUTTON_PLUS); + } + + /* Button Red */ + + public boolean isButtonRedJustPressed() { + return isButtonJustPressed(GUITAR_HERO_3_BUTTON_RED); + } + + public boolean isButtonRedJustReleased() { + return isButtonJustReleased(GUITAR_HERO_3_BUTTON_RED); + } + + public boolean isButtonRedHeld() { + return isButtonHeld(GUITAR_HERO_3_BUTTON_RED); + } + + public boolean isButtonRedPressed() { + return isButtonPressed(GUITAR_HERO_3_BUTTON_RED); + } + + /* Button Yellow */ + + public boolean isButtonYellowJustPressed() { + return isButtonJustPressed(GUITAR_HERO_3_BUTTON_YELLOW); + } + + public boolean isButtonYellowJustReleased() { + return isButtonJustReleased(GUITAR_HERO_3_BUTTON_YELLOW); + } + + public boolean isButtonYellowHeld() { + return isButtonHeld(GUITAR_HERO_3_BUTTON_YELLOW); + } + + public boolean isButtonYellowPressed() { + return isButtonPressed(GUITAR_HERO_3_BUTTON_YELLOW); + } +} diff --git a/java/src/wiiusej/wiiusejevents/physicalevents/GuitarHeroEvent.java b/java/src/wiiusej/wiiusejevents/physicalevents/GuitarHeroEvent.java new file mode 100644 index 0000000..d4796a3 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/physicalevents/GuitarHeroEvent.java @@ -0,0 +1,119 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.physicalevents; + +/** + * This class represents the values from the GuitarHero and its events. + * + * @author guiguito + */ +public class GuitarHeroEvent extends ExpansionEvent{ + + private float whammyBar; + private GuitarHeroButtonsEvent buttonsEvent; + private JoystickEvent guitarHeroJoystickEvent; + + /** + * Constructor of GuitarHeroEvent. + * + * @param id + * id of the wiimote. + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just pressed. + * @param whammyBar + * whammy bar (range 0-1). + * @param angle + * angle the joystick is being held. + * @param magnitude + * magnitude of the joystick (range 0-1). + * @param max1 + * maximum joystick value 1. + * @param max2 + * maximum joystick value 2. + * @param min1 + * minimum joystick value 1. + * @param min2 + * minimum joystick value 2. + * @param center1 + * center joystick value 1. + * @param center2 + * center joystick value 2. + */ + public GuitarHeroEvent(int id, short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld, float whammyBar, + float angle, float magnitude, short max1, + short max2, short min1, short min2, short center1, + short center2) { + super(id); + this.whammyBar = whammyBar; + buttonsEvent = new GuitarHeroButtonsEvent(id, + buttonsJustPressed, buttonsJustReleased, buttonsHeld); + guitarHeroJoystickEvent = new JoystickEvent(id, angle, + magnitude, max1, max2, min1, min2, center1, center2); + + } + + /** + * Tell if there is a Guitar Hero joystick event. + * + * @return TRUE if there is a Guitar Hero joystick event, false otherwise. + */ + public boolean isThereGuitarHeroJoystickEvent() { + return guitarHeroJoystickEvent != null; + } + + /** + * Whammy bar (range 0-1). + * @return the whammyBar value. + */ + public float getWhammyBar() { + return whammyBar; + } + + /** + * Get buttons event for the guitar hero controller. + * @return the guitar hero controller buttons event if there is one or null. + */ + public GuitarHeroButtonsEvent getButtonsEvent() { + return buttonsEvent; + } + + /** + * Get event from the joystick of the guitar hero controller. + * @return the guitar hero controller joystick Event if there is one or null. + */ + public JoystickEvent getGuitarHeroJoystickEvent() { + return guitarHeroJoystickEvent; + } + + @Override + public String toString() { + String out = ""; + /* Status */ + out += "/*********** Guitar Hero 3 EVENT : WIIMOTE ID :" + getWiimoteId() + + " ********/\n"; + out += buttonsEvent; + out += "Whammy Bar : "+whammyBar+"\n"; + out += guitarHeroJoystickEvent; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/physicalevents/IREvent.java b/java/src/wiiusej/wiiusejevents/physicalevents/IREvent.java new file mode 100644 index 0000000..06648a1 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/physicalevents/IREvent.java @@ -0,0 +1,319 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.physicalevents; + +import wiiusej.values.IRSource; +import wiiusej.wiiusejevents.GenericEvent; + +/** + * Class which represents an IR event. + * + * @author guiguito + */ +public class IREvent extends GenericEvent { + + /* IR Tracking */ + private IRSource[] IRPoints; + private short indexPoints = 0; + private int x; + private int y; + private float z;// distance from the sensor bar + private int ax; + private int ay; + private int xVRes; + private int yVRes; + private int xOffset; + private int yOffset; + private short sensorBarPostion; + private short screenAsPectRatio; + private short irSensitivity; + private float distance; + + static private short WIIUSE_IR_ABOVE = 0; + static private short WIIUSE_IR_BELOW = 1; + static private short WIIUSE_SCREEN_RATIO_4_3 = 0; + static private short WIIUSE_SCREEN_RATIO_16_9 = 1; + + private static short NB_POINTS = 4;// number of points IR can track + + /** + * Constructor of IREvent with full infos. + * + * @param id + * d of the wiimote concerned. + * @param x + * calculated X coordinate. + * @param y + * calculated Y coordinate. + * @param z + * calculated distance. + * @param ax + * absolute X coordinate. + * @param ay + * absolute Y coordinate + * @param xVRes + * IR virtual screen x resolution. + * @param yVRes + * IR virtual screen y resolution. + * @param xOffset + * IR X correction offset. + * @param yOffset + * IR Y correction offset. + * @param sensorBarPostion + * aspect ratio of the screen. + * @param screenAsPectRatio + * IR sensor bar position. + * @param irSensitivity + * Sensitivity of the infrared camera. + * @param distance + * Pixel Distance between first two dots + */ + public IREvent(int id, int x, int y, float z, int ax, int ay, int xVRes, + int yVRes, int xOffset, int yOffset, short sensorBarPostion, + short screenAsPectRatio, short irSensitivity, float distance) { + super(id); + this.x = x; + this.y = y; + this.z = z; + this.ax = ax; + this.ay = ay; + this.xVRes = xVRes; + this.yVRes = yVRes; + this.xOffset = xOffset; + this.yOffset = yOffset; + this.sensorBarPostion = sensorBarPostion; + this.screenAsPectRatio = screenAsPectRatio; + this.irSensitivity = irSensitivity; + this.distance = distance; + IRPoints = new IRSource[NB_POINTS]; + } + + /** + * Get list of IR points. + * + * @return the list of 2D points + */ + public IRSource[] getIRPoints() { + IRSource[] ir = new IRSource[indexPoints]; + System.arraycopy(IRPoints, 0, ir, 0, indexPoints); + return ir; + } + + /** + * Add IR Point in the list (Max 4 points) + * + * @param x + * x value + * @param y + * y value + * @param rx + * raw X coordinate (0-1023). + * @param ry + * raw Y coordinate (0-1023). + * @param size + * size of the IR dot (0-15). + */ + public void addIRpoint(int x, int y, short rx, short ry, short size) { + IRPoints[indexPoints] = new IRSource(x, y, rx, ry, size); + indexPoints++; + return; + } + + /** + * Return calculated X coordinate. + * + * @return the x + */ + public int getX() { + return x; + } + + /** + * Return calculated Y coordinate. + * + * @return the y + */ + public int getY() { + return y; + } + + /** + * Return calculated distance. + * + * @return the z + */ + public float getZ() { + return z; + } + + /** + * Return absolute X coordinate. + * + * @return the ax + */ + public int getAx() { + return ax; + } + + /** + * Return absolute Y coordinate. + * + * @return the ay + */ + public int getAy() { + return ay; + } + + /** + * Return IR virtual screen x resolution. + * + * @return the xVRes + */ + public int getXVRes() { + return xVRes; + } + + /** + * Return IR virtual screen y resolution. + * + * @return the yVRes + */ + public int getYVRes() { + return yVRes; + } + + /** + * Return IR X correction offset. + * + * @return the xOffset + */ + public int getXOffset() { + return xOffset; + } + + /** + * Return IR Y correction offset. + * + * @return the yOffset + */ + public int getYOffset() { + return yOffset; + } + + /** + * Return true if the sensor bar is above. + * + * @return true if the sensor bar is above. + */ + public boolean isSensorBarAbove() { + return sensorBarPostion == WIIUSE_IR_ABOVE; + } + + /** + * Return true if the sensor bar is below. + * + * @return true if the sensor bar is below. + */ + public boolean isSensorBarBelow() { + return sensorBarPostion == WIIUSE_IR_BELOW; + } + + /** + * Return true if screen aspect ratio set is 4/3. + * + * @return true if screen aspect ratio set is 4/3. + */ + public boolean isScreenAspectRatio43() { + return screenAsPectRatio == WIIUSE_SCREEN_RATIO_4_3; + } + + /** + * Return true if screen aspect ratio set is 16/9. + * + * @return true if screen aspect ratio set is 16/9. + */ + public boolean isScreenAspectRatio169() { + return screenAsPectRatio == WIIUSE_SCREEN_RATIO_16_9; + } + + /** + * Return aspect ratio of the screen. + * + * @return the screenAsPectRatio + */ + public short getScreenAsPectRatio() { + return screenAsPectRatio; + } + + /** + * The sensitivity of the IR camera can be turned up or down depending on + * your needs. Like the Wii, wiiusej and wiiuse can set the camera + * sensitivity to a degree between 1 (lowest) and 5 (highest). The default + * is 3. + * + * @return the irSensitivity + */ + public short getIrSensitivity() { + return irSensitivity; + } + + /** + * Pixel distance between first 2 dots. + * + * @return the distance between first 2 dots. + */ + public float getDistance() { + return distance; + } + + @Override + public String toString() { + String out = ""; + /* Display IR Tracking */ + out += "/******** IR Tracking ********/\n"; + out += "--- Active : true\n"; + out += "--- calculated X coordinate : " + x + "\n"; + out += "--- calculated Y coordinate : " + y + "\n"; + out += "--- calculated Z coordinate : " + z + "\n"; + out += "--- calculated distance : " + distance + "\n"; + out += "--- absolute X coordinate : " + ax + "\n"; + out += "--- absolute Y coordinate : " + ay + "\n"; + out += "--- IR virtual screen x resolution : " + xVRes + "\n"; + out += "--- IR virtual screen y resolution : " + yVRes + "\n"; + out += "--- IR X correction offset : " + xOffset + "\n"; + out += "--- IR Y correction offset : " + yOffset + "\n"; + out += "--- IR Sensitivity (between 1-5) : " + irSensitivity + "\n"; + if (isScreenAspectRatio43()) { + out += "--- aspect ratio of the screen : 4/3\n"; + } else if (isScreenAspectRatio169()) { + out += "--- aspect ratio of the screen : 16/9\n"; + } + if (isSensorBarAbove()) { + out += "--- IR sensor bar position. : Above\n"; + } else if (isSensorBarBelow()) { + out += "--- IR sensor bar position. : Below\n"; + } + out += "--- Seen points\n"; + for (int i = 0; i < IRPoints.length; i++) { + if (IRPoints[i] != null) { + out += IRPoints[i].toString(); + } + } + out += "\n"; + return out; + } +} diff --git a/java/src/wiiusej/wiiusejevents/physicalevents/JoystickEvent.java b/java/src/wiiusej/wiiusejevents/physicalevents/JoystickEvent.java new file mode 100644 index 0000000..5dc7f2f --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/physicalevents/JoystickEvent.java @@ -0,0 +1,135 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.physicalevents; + +import wiiusej.wiiusejevents.GenericEvent; + +/** + * Class that stores values on a joystick Event. + * + * @author guiguito + */ +public class JoystickEvent extends GenericEvent { + + private float angle; + private float magnitude; + private short[] max; + private short[] min; + private short[] center; + + /** + * Constructor of a JoystickEvent. + * + * @param id + * id of the wiimote connected. + * @param angle + * angle the joystick is being held. + * @param magnitude + * magnitude of the joystick (range 0-1). + * @param max1 + * maximum joystick value 1. + * @param max2 + * maximum joystick value 2. + * @param min1 + * minimum joystick value 1. + * @param min2 + * minimum joystick value 2. + * @param center1 + * center joystick value 1. + * @param center2 + * center joystick value 2. + */ + public JoystickEvent(int id, float angle, float magnitude, short max1, + short max2, short min1, short min2, short center1, short center2) { + super(id); + this.angle = angle; + this.magnitude = magnitude; + max = new short[2]; + max[0] = max1; + max[1] = max2; + min = new short[2]; + min[0] = min1; + min[1] = min2; + center = new short[2]; + center[0] = center1; + center[1] = center2; + } + + /** + * Get angle the joystick is being held. + * + * @return the angle angle the joystick. + */ + public float getAngle() { + return angle; + } + + /** + * Get magnitude of the joystick (range 0-1). + * + * @return the magnitude magnitude of the joystick. + */ + public float getMagnitude() { + return magnitude; + } + + /** + * Maximum joystick values. + * + * @return the max + */ + public short[] getMax() { + return max; + } + + /** + * Minimum joystick values. + * + * @return the min + */ + public short[] getMin() { + return min; + } + + /** + * Center joystick values. + * + * @return the center + */ + public short[] getCenter() { + return center; + } + + /* + * (non-Javadoc) + * + * @see wiiusej.wiiusejevents.GenericEvent#toString() + */ + @Override + public String toString() { + String out = ""; + /* Display IR Tracking */ + out += "/******** Joystick ********/\n"; + out += "--- angle : " + angle + "\n"; + out += "--- magnitude : " + magnitude + "\n"; + out += "--- maximum values : " + max[0] + "," + max[1] + "\n"; + out += "--- minimum values : " + min[0] + "," + min[1] + "\n"; + out += "--- center values : " + center[0] + "," + center[1] + "\n"; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/physicalevents/MotionSensingEvent.java b/java/src/wiiusej/wiiusejevents/physicalevents/MotionSensingEvent.java new file mode 100644 index 0000000..0945a48 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/physicalevents/MotionSensingEvent.java @@ -0,0 +1,203 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.physicalevents; + +import wiiusej.values.GForce; +import wiiusej.values.Orientation; +import wiiusej.values.RawAcceleration; +import wiiusej.wiiusejevents.GenericEvent; + +/** + * Class which represents a motion sensing event. + * + * @author guiguito + */ +public class MotionSensingEvent extends GenericEvent { + + /* Motion Sensing */ + private Orientation orientation; + private GForce gforce; + private RawAcceleration acceleration; + + private float orientationThreshold = 0; + private int accelerationThreshold = 0; + private float alphaSmoothing = 0; + private boolean isSmoothingActive = false; + + /** + * Constructor for a Motion Sensing Event. + * + * @param id + * id of the wiimote concerned. + * @param orientationThreshold + * value of the minimum angle between two events with the + * accelerometer. + * @param accelerationThreshold + * value of the value variation between two events with the + * accelerometer. + * @param smoothingState + * true if smoothing flag is activated. + * @param alphaSmooth + * value of the alpha smoothing parameter. + * @param r + * roll. + * @param p + * pitch. + * @param ya + * yaw. + * @param ar + * absolute roll. + * @param ap + * absolute pitch. + * @param x + * gravity force on x axis. + * @param y + * gravity force on y axis. + * @param z + * gravity force on z axis. + * @param xx + * raw acceleration on x axis. + * @param yy + * raw acceleration on y axis. + * @param zz + * raw acceleration on z axis. + */ + public MotionSensingEvent(int id, float orientationThreshold, + int accelerationThreshold, boolean smoothingState, + float alphaSmooth, float r, float p, float ya, float ar, float ap, + float x, float y, float z, short xx, short yy, short zz) { + super(id); + this.orientationThreshold = orientationThreshold; + this.accelerationThreshold = accelerationThreshold; + this.isSmoothingActive = smoothingState; + this.alphaSmoothing = alphaSmooth; + setOrientationAndGforce(r, p, ya, ar, ap, x, y, z, xx, yy, zz); + } + + /** + * Set orientation, gravity force and raw acceleration. + * + * @param r + * roll + * @param p + * pitch + * @param ya + * yaw + * @param ar + * absolute roll + * @param ap + * absolute pitch + * @param x + * gravity force on x axis + * @param y + * gravity force on y axis + * @param z + * gravity force on z axis + * @param xx + * raw acceleration on x axis + * @param yy + * raw acceleration on y axis + * @param zz + * raw acceleration on z axis + */ + private void setOrientationAndGforce(float r, float p, float ya, float ar, + float ap, float x, float y, float z, short xx, short yy, short zz) { + this.orientation = new Orientation(r, p, ya, ar, ap); + this.gforce = new GForce(x, y, z); + this.acceleration = new RawAcceleration(xx, yy, zz); + } + + /** + * @return the orientation + */ + public Orientation getOrientation() { + return orientation; + } + + /** + * Get the gravity force. + * + * @return the gforce + */ + public GForce getGforce() { + return gforce; + } + + /** + * Get the raw acceleration. + * + * @return the raw acceleration + */ + public RawAcceleration getRawAcceleration() { + return acceleration; + } + + /** + * Get orientation threshold. + * + * @return the orientationThreshold + */ + public float getOrientationThreshold() { + return orientationThreshold; + } + + /** + * Get acceleration threshold. + * + * @return the accelerationThreshold + */ + public int getAccelerationThreshold() { + return accelerationThreshold; + } + + /** + * Get alpha smoothing. + * + * @return the alphaSmoothing + */ + public float getAlphaSmoothing() { + return alphaSmoothing; + } + + /** + * Tell if the option SMOOTHING is activated. + * + * @return the isSmoothingActive + */ + public boolean isSmoothingActive() { + return isSmoothingActive; + } + + @Override + public String toString() { + String out = ""; + /* Motion sensing */ + out += "/******** Motion sensing ********/\n"; + out += "--- Motion sensing : true \n"; + out += "--- Orientation threshold value ? : " + orientationThreshold + + "\n"; + out += "--- Acceleration threshold value ? : " + accelerationThreshold + + "\n"; + out += "--- Alpha smoothing threshold value ? : " + alphaSmoothing + + "\n"; + out += "--- Smoothing ? : " + isSmoothingActive + "\n"; + out += "--- " + orientation + "\n"; + out += "--- " + gforce + "\n"; + out += "--- " + acceleration + "\n"; + return out; + } +} diff --git a/java/src/wiiusej/wiiusejevents/physicalevents/NunchukButtonsEvent.java b/java/src/wiiusej/wiiusejevents/physicalevents/NunchukButtonsEvent.java new file mode 100644 index 0000000..d1af6af --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/physicalevents/NunchukButtonsEvent.java @@ -0,0 +1,89 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.physicalevents; + +/** + * Class which represents a buttons event from a Nunchuk. + * + * @author guiguito + */ +public class NunchukButtonsEvent extends ButtonsEvent { + + private static short NUNCHUK_BUTTON_Z = 0x01; + private static short NUNCHUK_BUTTON_C = 0x02; + private static short NUNCHUK_BUTTON_ALL = 0x03; + + /** + * Constructor of the nunchuk buttons Event. + * + * @param id + * id of the wiimote. + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just pressed. + */ + public NunchukButtonsEvent(int id, short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld) { + super(id, buttonsJustPressed, buttonsJustReleased, buttonsHeld); + } + + /* Button Z */ + + public boolean isButtonZJustPressed() { + return isButtonJustPressed(NUNCHUK_BUTTON_Z); + } + + public boolean isButtonZJustReleased() { + return isButtonJustReleased(NUNCHUK_BUTTON_Z); + } + + public boolean isButtonZeHeld() { + return isButtonHeld(NUNCHUK_BUTTON_Z); + } + + public boolean isButtonZPressed() { + return isButtonPressed(NUNCHUK_BUTTON_Z); + } + + /* Button Z */ + + public boolean isButtonCJustPressed() { + return isButtonJustPressed(NUNCHUK_BUTTON_C); + } + + public boolean isButtonCJustReleased() { + return isButtonJustReleased(NUNCHUK_BUTTON_C); + } + + public boolean isButtonCHeld() { + return isButtonHeld(NUNCHUK_BUTTON_C); + } + + public boolean isButtonCPressed() { + return isButtonPressed(NUNCHUK_BUTTON_C); + } + + @Override + public String toString() { + return "/******** Buttons for Nunchuk Event ********/\n" + + super.toString(); + } + +} diff --git a/java/src/wiiusej/wiiusejevents/physicalevents/NunchukEvent.java b/java/src/wiiusej/wiiusejevents/physicalevents/NunchukEvent.java new file mode 100644 index 0000000..d990f60 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/physicalevents/NunchukEvent.java @@ -0,0 +1,169 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.physicalevents; + +/** + * This class represents the values from the joystick and its events. + * + * @author guiguito + */ +public class NunchukEvent extends ExpansionEvent { + + private NunchukButtonsEvent buttonsEvent; + private MotionSensingEvent nunchukMotionSensingEvent; + private JoystickEvent nunchukJoystickEvent; + + /** + * Constructor of NunchukEvent. + * + * @param id + * id of the wiimote. + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just pressed. + * @param orientationThreshold + * value of the minimum angle between two events with the + * accelerometer. + * @param accelerationThreshold + * value of the value variation between two events with the + * accelerometer. + * @param smoothingState + * true if smoothing flag is activated. + * @param alphaSmooth + * value of the alpha smoothing parameter. + * @param r + * roll. + * @param p + * pitch. + * @param ya + * yaw. + * @param ar + * absolute roll. + * @param ap + * absolute pitch. + * @param x + * gravity force on x axis. + * @param y + * gravity force on y axis. + * @param z + * gravity force on z axis. + * @param xx + * raw acceleration on x axis. + * @param yy + * raw acceleration on y axis. + * @param zz + * raw acceleration on z axis. + * @param angle + * angle the joystick is being held. + * @param magnitude + * magnitude of the joystick (range 0-1). + * @param max1 + * maximum joystick value 1. + * @param max2 + * maximum joystick value 2. + * @param min1 + * minimum joystick value 1. + * @param min2 + * minimum joystick value 2. + * @param center1 + * center joystick value 1. + * @param center2 + * center joystick value 2. + */ + public NunchukEvent(int id, short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld, + float orientationThreshold, int accelerationThreshold, + boolean smoothingState, float alphaSmooth, float r, float p, + float ya, float ar, float ap, float x, float y, float z, short xx, + short yy, short zz, float angle, float magnitude, short max1, + short max2, short min1, short min2, short center1, short center2) { + super(id); + buttonsEvent = new NunchukButtonsEvent(id, buttonsJustPressed, + buttonsJustReleased, buttonsHeld); + nunchukMotionSensingEvent = new MotionSensingEvent(id, + orientationThreshold, accelerationThreshold, smoothingState, + alphaSmooth, r, p, ya, ar, ap, x, y, z, xx, yy, zz); + nunchukJoystickEvent = new JoystickEvent(id, angle, magnitude, max1, + max2, min1, min2, center1, center2); + } + + /** + * Tell if there is a nunchuk motion sensing Event. + * + * @return TRUE if there is a nunchuk motion sensing event, false otherwise. + */ + public boolean isThereMotionSensingEvent() { + return nunchukMotionSensingEvent != null; + } + + /** + * Tell if there is a nunchuk joystick event. + * + * @return TRUE if there is a nunchuk joystick event, false otherwise. + */ + public boolean isThereNunchukJoystickEvent() { + return nunchukJoystickEvent != null; + } + + /** + * Get nunchuk buttons event. + * + * @return the nunchuk buttons event if there is one or null. + */ + public NunchukButtonsEvent getButtonsEvent() { + return buttonsEvent; + } + + /** + * Get the nunchuk motion sensing event. + * + * @return the nunchuk motion sensing event if there is one or null. + */ + public MotionSensingEvent getNunchukMotionSensingEvent() { + return nunchukMotionSensingEvent; + } + + /** + * Get the nunchuk joystick event. + * + * @return the nunchuk Joystick Event if there is one or null. + */ + public JoystickEvent getNunchukJoystickEvent() { + return nunchukJoystickEvent; + } + + /* + * (non-Javadoc) + * + * @see wiiusej.wiiusejevents.GenericEvent#toString() + */ + @Override + public String toString() { + String out = ""; + /* Status */ + out += "/*********** Nunchuk EVENT : WIIMOTE ID :" + getWiimoteId() + + " ********/\n"; + out += buttonsEvent; + out += nunchukJoystickEvent; + out += nunchukMotionSensingEvent; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/physicalevents/WiimoteButtonsEvent.java b/java/src/wiiusej/wiiusejevents/physicalevents/WiimoteButtonsEvent.java new file mode 100644 index 0000000..106fc1c --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/physicalevents/WiimoteButtonsEvent.java @@ -0,0 +1,267 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.physicalevents; + +/** + * Class which represents a buttons event for a generic event. It means buttons + * from a wiimote. + * + * @author guiguito + */ +public class WiimoteButtonsEvent extends ButtonsEvent { + + /* Buttons MACRO */ + private static short WIIMOTE_BUTTON_TWO = 0x0001; + private static short WIIMOTE_BUTTON_ONE = 0x0002; + private static short WIIMOTE_BUTTON_B = 0x0004; + private static short WIIMOTE_BUTTON_A = 0x0008; + private static short WIIMOTE_BUTTON_MINUS = 0x0010; + private static short WIIMOTE_BUTTON_ZACCEL_BIT6 = 0x0020; + private static short WIIMOTE_BUTTON_ZACCEL_BIT7 = 0x0040; + private static short WIIMOTE_BUTTON_HOME = 0x0080; + private static short WIIMOTE_BUTTON_LEFT = 0x0100; + private static short WIIMOTE_BUTTON_RIGHT = 0x0200; + private static short WIIMOTE_BUTTON_DOWN = 0x0400; + private static short WIIMOTE_BUTTON_UP = 0x0800; + private static short WIIMOTE_BUTTON_PLUS = 0x1000; + private static short WIIMOTE_BUTTON_ZACCEL_BIT4 = 0x2000; + private static short WIIMOTE_BUTTON_ZACCEL_BIT5 = 0x4000; + private static int WIIMOTE_BUTTON_UNKNOWN = 0x8000; + private static short WIIMOTE_BUTTON_ALL = 0x1F9F; + + /** + * Constructor of the wiimote button Event. + * + * @param id + * id of the wiimote. + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons held. + */ + public WiimoteButtonsEvent(int id, short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld) { + super(id, buttonsJustPressed, buttonsJustReleased, buttonsHeld); + } + + /* Button ONE */ + + public boolean isButtonOneJustPressed() { + return isButtonJustPressed(WIIMOTE_BUTTON_ONE); + } + + public boolean isButtonOneJustReleased() { + return isButtonJustReleased(WIIMOTE_BUTTON_ONE); + } + + public boolean isButtonOneHeld() { + return isButtonHeld(WIIMOTE_BUTTON_ONE); + } + + public boolean isButtonOnePressed() { + return isButtonPressed(WIIMOTE_BUTTON_ONE); + } + + /* Button TWO */ + + public boolean isButtonTwoJustPressed() { + return isButtonJustPressed(WIIMOTE_BUTTON_TWO); + } + + public boolean isButtonTwoJustReleased() { + return isButtonJustReleased(WIIMOTE_BUTTON_TWO); + } + + public boolean isButtonTwoHeld() { + return isButtonHeld(WIIMOTE_BUTTON_TWO); + } + + public boolean isButtonTwoPressed() { + return isButtonPressed(WIIMOTE_BUTTON_TWO); + } + + /* Button A */ + + public boolean isButtonAJustPressed() { + return isButtonJustPressed(WIIMOTE_BUTTON_A); + } + + public boolean isButtonAJustReleased() { + return isButtonJustReleased(WIIMOTE_BUTTON_A); + } + + public boolean isButtonAHeld() { + return isButtonHeld(WIIMOTE_BUTTON_A); + } + + public boolean isButtonAPressed() { + return isButtonPressed(WIIMOTE_BUTTON_A); + } + + /* Button B */ + + public boolean isButtonBJustPressed() { + return isButtonJustPressed(WIIMOTE_BUTTON_B); + } + + public boolean isButtonBJustReleased() { + return isButtonJustReleased(WIIMOTE_BUTTON_B); + } + + public boolean isButtonBHeld() { + return isButtonHeld(WIIMOTE_BUTTON_B); + } + + public boolean isButtonBPressed() { + return isButtonPressed(WIIMOTE_BUTTON_B); + } + + /* Button LEFT */ + + public boolean isButtonLeftJustPressed() { + return isButtonJustPressed(WIIMOTE_BUTTON_LEFT); + } + + public boolean isButtonLeftJustReleased() { + return isButtonJustReleased(WIIMOTE_BUTTON_LEFT); + } + + public boolean isButtonLeftHeld() { + return isButtonHeld(WIIMOTE_BUTTON_LEFT); + } + + public boolean isButtonLeftPressed() { + return isButtonPressed(WIIMOTE_BUTTON_LEFT); + } + + /* Button RIGHT */ + + public boolean isButtonRightJustPressed() { + return isButtonJustPressed(WIIMOTE_BUTTON_RIGHT); + } + + public boolean isButtonRightJustReleased() { + return isButtonJustReleased(WIIMOTE_BUTTON_RIGHT); + } + + public boolean isButtonRightHeld() { + return isButtonHeld(WIIMOTE_BUTTON_RIGHT); + } + + public boolean isButtonRightPressed() { + return isButtonPressed(WIIMOTE_BUTTON_RIGHT); + } + + /* Button UP */ + + public boolean isButtonUpJustPressed() { + return isButtonJustPressed(WIIMOTE_BUTTON_UP); + } + + public boolean isButtonUpJustReleased() { + return isButtonJustReleased(WIIMOTE_BUTTON_UP); + } + + public boolean isButtonUpHeld() { + return isButtonHeld(WIIMOTE_BUTTON_UP); + } + + public boolean isButtonUpPressed() { + return isButtonPressed(WIIMOTE_BUTTON_UP); + } + + /* Button DOWN */ + + public boolean isButtonDownJustPressed() { + return isButtonJustPressed(WIIMOTE_BUTTON_DOWN); + } + + public boolean isButtonDownJustReleased() { + return isButtonJustReleased(WIIMOTE_BUTTON_DOWN); + } + + public boolean isButtonDownHeld() { + return isButtonHeld(WIIMOTE_BUTTON_DOWN); + } + + public boolean isButtonDownPressed() { + return isButtonPressed(WIIMOTE_BUTTON_DOWN); + } + + /* Button - */ + + public boolean isButtonMinusJustPressed() { + return isButtonJustPressed(WIIMOTE_BUTTON_MINUS); + } + + public boolean isButtonMinusJustReleased() { + return isButtonJustReleased(WIIMOTE_BUTTON_MINUS); + } + + public boolean isButtonMinusHeld() { + return isButtonHeld(WIIMOTE_BUTTON_MINUS); + } + + public boolean isButtonMinusPressed() { + return isButtonPressed(WIIMOTE_BUTTON_MINUS); + } + + /* Button + */ + + public boolean isButtonPlusJustPressed() { + return isButtonJustPressed(WIIMOTE_BUTTON_PLUS); + } + + public boolean isButtonPlusJustReleased() { + return isButtonJustReleased(WIIMOTE_BUTTON_PLUS); + } + + public boolean isButtonPlusHeld() { + return isButtonHeld(WIIMOTE_BUTTON_PLUS); + } + + public boolean isButtonPlusPressed() { + return isButtonPressed(WIIMOTE_BUTTON_PLUS); + } + + /* Button HOME */ + + public boolean isButtonHomeJustPressed() { + return isButtonJustPressed(WIIMOTE_BUTTON_HOME); + } + + public boolean isButtonHomeJustReleased() { + return isButtonJustReleased(WIIMOTE_BUTTON_HOME); + } + + public boolean isButtonHomeHeld() { + return isButtonHeld(WIIMOTE_BUTTON_HOME); + } + + public boolean isButtonHomePressed() { + return isButtonPressed(WIIMOTE_BUTTON_HOME); + } + + @Override + public String toString() { + return "/******** Buttons for Wiimote generic Event ********/\n" + + super.toString(); + } + +} diff --git a/java/src/wiiusej/wiiusejevents/utils/EventsGatherer.java b/java/src/wiiusej/wiiusejevents/utils/EventsGatherer.java new file mode 100644 index 0000000..d89c994 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/utils/EventsGatherer.java @@ -0,0 +1,509 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.utils; + +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; +import wiiusej.wiiusejevents.wiiuseapievents.WiiUseApiEvent; +import wiiusej.wiiusejevents.wiiuseapievents.WiimoteEvent; + +/** + * This class is used to gather events during a call to the Wiiuse API. + * + * @author guiguito + */ +public class EventsGatherer { + + private WiiUseApiEvent[] events; + private int index = 0; + private WiimoteEvent genericEvent = null; + + /** + * Create EventsGatherer. + * + * @param nbWiimotes + * nb wiimotes (nb a of events possible in a call to Wiiuse API). + */ + public EventsGatherer(int nbWiimotes) { + events = new WiiUseApiEvent[nbWiimotes]; + } + + /** + * Add an event to the array. + * + * @param e + * the event to add. + */ + private void addEvent(WiiUseApiEvent e) { + events[index] = e; + index++; + } + + /** + * Prepare a wiimote event to add. + * + * @param id + * id of the wiimote. + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons held. + */ + public void prepareWiiMoteEvent(int id, short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld) { + genericEvent = new WiimoteEvent(id, buttonsJustPressed, + buttonsJustReleased, buttonsHeld); + } + + /** + * Prepare an IR event to populate. + * + * @param x + * calculated X coordinate. + * @param y + * calculated Y coordinate. + * @param z + * calculated distance. + * @param ax + * absolute X coordinate. + * @param ay + * absolute Y coordinate. + * @param xVRes + * IR virtual screen x resolution. + * @param yVRes + * IR virtual screen y resolution. + * @param xOffset + * IR X correction offset. + * @param yOffset + * IR Y correction offset. + * @param sensorBarPostion + * aspect ratio of the screen. + * @param screenAsPectRatio + * IR sensor bar position. + * @param irSensitivity + * Sensitivity of the infrared camera. + * @param distance + * Pixel Distance between first two dots. + */ + public void prepareIRevent(int x, int y, float z, int ax, int ay, + int xVRes, int yVRes, int xOffset, int yOffset, + short sensorBarPostion, short screenAsPectRatio, + short irSensitivity, float distance) { + genericEvent.prepareIRevent(x, y, z, ax, ay, xVRes, yVRes, xOffset, + yOffset, sensorBarPostion, screenAsPectRatio, irSensitivity, + distance); + + } + + /** + * Add an IR point to the WiiMoteEvent prepared. + * + * @param x + * x coordinates. + * @param y + * y coordinates. + * @param rx + * raw X coordinate (0-1023). + * @param ry + * raw Y coordinate (0-1023). + * @param size + * size of the IR dot (0-15). + */ + public void addIRPointToPreparedWiiMoteEvent(int x, int y, short rx, + short ry, short size) { + if (genericEvent != null) { + genericEvent.addIRpoint(x, y, rx, ry, size); + } + } + + /** + * Set orientation and gravity force of the prepared event. + * + * @param orientationThreshold + * value of the minimum angle between two events with the + * accelerometer. + * @param accelerationThreshold + * value of the value variation between two events with the + * accelerometer. + * @param smoothingState + * true if smoothing flag is activated. + * @param alphaSmooth + * value of the alpha smoothing parameter. + * @param r + * roll. + * @param p + * pitch. + * @param ya + * yaw. + * @param ar + * absolute roll. + * @param ap + * absolute pitch. + * @param x + * gravity force on x axis. + * @param y + * gravity force on y axis. + * @param z + * gravity force on z axis. + * @param xx + * raw acceleration on x axis. + * @param yy + * raw acceleration on y axis. + * @param zz + * raw acceleration on z axis. + */ + public void addMotionSensingValues(float orientationThreshold, + int accelerationThreshold, boolean smoothingState, + float alphaSmooth, float r, float p, float ya, float ar, float ap, + float x, float y, float z, short xx, short yy, short zz) { + if (genericEvent != null) { + genericEvent.setMotionSensingEvent(orientationThreshold, + accelerationThreshold, smoothingState, alphaSmooth, r, p, + ya, ar, ap, x, y, z, xx, yy, zz); + } + } + + /** + * Set a NunchukEvent to the prepared WiimoteEvent. + * + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just pressed. + * @param orientationThreshold + * value of the minimum angle between two events with the + * accelerometer. + * @param accelerationThreshold + * value of the value variation between two events with the + * accelerometer. + * @param smoothingState + * true if smoothing flag is activated. + * @param alphaSmooth + * value of the alpha smoothing parameter. + * @param r + * roll. + * @param p + * pitch. + * @param ya + * yaw. + * @param ar + * absolute roll. + * @param ap + * absolute pitch. + * @param x + * gravity force on x axis. + * @param y + * gravity force on y axis. + * @param z + * gravity force on z axis. + * @param xx + * raw acceleration on x axis. + * @param yy + * raw acceleration on y axis. + * @param zz + * raw acceleration on z axis. + * @param angle + * angle the joystick is being held. + * @param magnitude + * magnitude of the joystick (range 0-1). + * @param max1 + * maximum joystick value 1. + * @param max2 + * maximum joystick value 2. + * @param min1 + * minimum joystick value 1. + * @param min2 + * minimum joystick value 2. + * @param center1 + * center joystick value 1. + * @param center2 + * center joystick value 2. + */ + public void addNunchunkEventToPreparedWiimoteEvent( + short buttonsJustPressed, short buttonsJustReleased, + short buttonsHeld, float orientationThreshold, + int accelerationThreshold, boolean smoothingState, + float alphaSmooth, float r, float p, float ya, float ar, float ap, + float x, float y, float z, short xx, short yy, short zz, + float angle, float magnitude, short max1, short max2, short min1, + short min2, short center1, short center2) { + if (genericEvent != null) { + genericEvent.setNunchukEvent(buttonsJustPressed, + buttonsJustReleased, buttonsHeld, orientationThreshold, + accelerationThreshold, smoothingState, alphaSmooth, r, p, + ya, ar, ap, x, y, z, xx, yy, zz, angle, magnitude, max1, + max2, min1, min2, center1, center2); + } + } + + /** + * Set a GuitarHeroEvent to the prepared WiimoteEvent. + * + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just pressed. + * @param whammyBar + * whammy bar (range 0-1). + * @param angle + * angle the joystick is being held. + * @param magnitude + * magnitude of the joystick (range 0-1). + * @param max1 + * maximum joystick value 1. + * @param max2 + * maximum joystick value 2. + * @param min1 + * minimum joystick value 1. + * @param min2 + * minimum joystick value 2. + * @param center1 + * center joystick value 1. + * @param center2 + * center joystick value 2. + */ + public void addGuitarHeroEventToPreparedWiimoteEvent( + short buttonsJustPressed, short buttonsJustReleased, + short buttonsHeld, float whammyBar, float angle, float magnitude, + short max1, short max2, short min1, short min2, short center1, + short center2) { + if (genericEvent != null) { + genericEvent.setGuitarHeroEvent(buttonsJustPressed, + buttonsJustReleased, buttonsHeld, whammyBar, angle, + magnitude, max1, max2, min1, min2, center1, center2); + } + } + + /** + * Set a ClassicControllerEvent to the prepared WiimoteEvent. + * + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just pressed. + * @param rightShoulder + * right shoulder button (range 0-1). + * @param leftShoulder + * left shoulder button (range 0-1). + * @param langle + * angle the left joystick is being held. + * @param lmagnitude + * magnitude of the left joystick (range 0-1). + * @param lmax1 + * maximum left joystick value 1. + * @param lmax2 + * maximum left joystick value 2. + * @param lmin1 + * minimum left joystick value 1. + * @param lmin2 + * minimum left joystick value 2. + * @param lcenter1 + * center left joystick value 1. + * @param lcenter2 + * center left joystick value 2. + * @param rangle + * angle the right joystick is being held. + * @param rmagnitude + * magnitude of the right joystick (range 0-1). + * @param rmax1 + * maximum right joystick value 1. + * @param rmax2 + * maximum right joystick value 2. + * @param rmin1 + * minimum right joystick value 1. + * @param rmin2 + * minimum right joystick value 2. + * @param rcenter1 + * center right joystick value 1. + * @param rcenter2 + * center right joystick value 2. + */ + public void addClassicControllerEventToPreparedWiimoteEvent(short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld, float rightShoulder, + float leftShoulder, float langle, float lmagnitude, short lmax1, + short lmax2, short lmin1, short lmin2, short lcenter1, + short lcenter2, float rangle, float rmagnitude, short rmax1, + short rmax2, short rmin1, short rmin2, short rcenter1, + short rcenter2) { + if (genericEvent != null) { + genericEvent.setClassicControllerEvent(buttonsJustPressed, + buttonsJustReleased, buttonsHeld, rightShoulder, + leftShoulder, langle, lmagnitude, lmax1, lmax2, lmin1, + lmin2, lcenter1, lcenter2, rangle, rmagnitude, rmax1, + rmax2, rmin1, rmin2, rcenter1, rcenter2); + } + } + + /** + * Add the prepared WiimoteEvent to the gatherer. + */ + public void addWiimoteEvent() { + if (genericEvent != null) { + addEvent(genericEvent); + genericEvent = null; + } + } + + /** + * Add a StatusEvent to the gatherer. + * + * @param id + * id of the wiimote. + * @param connect + * true if the wiimote is connected. + * @param batt + * battery level. + * @param led + * status of leds. + * @param speak + * speakers status. + * @param attach + * attachment status. + * @param rumbleState + * true if rumble is active. + * @param continuousState + * true if continuous flag is activated. + * @param irState + * true if ir is active. + * @param motionSensingState + * true if accelerometer is active. + */ + public void addStatusEvent(int id, boolean connect, float batt, short led, + boolean speak, int attach, boolean rumbleState, + boolean continuousState, boolean irState, boolean motionSensingState) { + StatusEvent evt = new StatusEvent(id, connect, batt, led, speak, + attach, rumbleState, continuousState, irState, + motionSensingState); + addEvent(evt); + } + + /** + * Add a DisconnectionEvent to the gatherer. + * + * @param id + * id of the wiimote. + */ + public void addDisconnectionEvent(int id) { + DisconnectionEvent evt = new DisconnectionEvent(id); + addEvent(evt); + } + + /** + * Add a NunchukInsertedEvent to the gatherer. + * + * @param id + * id of the wiimote. + */ + public void addNunchukInsertedEvent(int id) { + NunchukInsertedEvent evt = new NunchukInsertedEvent(id); + addEvent(evt); + } + + /** + * Add a NunchukRemovedEvent to the gatherer. + * + * @param id + * id of the wiimote. + */ + public void addNunchukRemovedEvent(int id) { + NunchukRemovedEvent evt = new NunchukRemovedEvent(id); + addEvent(evt); + } + + /** + * Add a GuitarHeroInsertedEvent to the gatherer. + * + * @param id + * id of the wiimote. + */ + public void addGuitarHeroInsertedEvent(int id) { + GuitarHeroInsertedEvent evt = new GuitarHeroInsertedEvent(id); + addEvent(evt); + } + + /** + * Add a GuitarHeroRemovedEvent to the gatherer. + * + * @param id + * id of the wiimote. + */ + public void addGuitarHeroRemovedEvent(int id) { + GuitarHeroRemovedEvent evt = new GuitarHeroRemovedEvent(id); + addEvent(evt); + } + + /** + * Add a ClassicControllerInsertedEvent to the gatherer. + * + * @param id + * id of the wiimote. + */ + public void addClassicControllerInsertedEvent(int id) { + ClassicControllerInsertedEvent evt = new ClassicControllerInsertedEvent( + id); + addEvent(evt); + } + + /** + * Add a ClassicControllerRemovedEvent to the gatherer. + * + * @param id + * id of the wiimote. + */ + public void addClassicControllerRemovedEvent(int id) { + ClassicControllerRemovedEvent evt = new ClassicControllerRemovedEvent( + id); + addEvent(evt); + } + + /** + * Return an array containing the events. + * + * @return events received. + */ + public WiiUseApiEvent[] getEvents() { + WiiUseApiEvent[] ev = new WiiUseApiEvent[index]; + System.arraycopy(events, 0, ev, 0, index); + return ev; + } + + /** + * Clear the gatherer and remove objects. + */ + public void clearEvents() { + for (int i = 0; i < events.length; i++) { + events[i] = null; + } + genericEvent = null; + index = 0; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/utils/WiiUseApiListener.java b/java/src/wiiusej/wiiusejevents/utils/WiiUseApiListener.java new file mode 100644 index 0000000..ee1ce80 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/utils/WiiUseApiListener.java @@ -0,0 +1,37 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.utils; + +import wiiusej.wiiusejevents.wiiuseapievents.WiiUseApiEvent; + +/** + * This is the interface to implement to listen to events from the wiiuse API. + * + * @author guiguito + */ +public interface WiiUseApiListener extends java.util.EventListener { + + /** + * Method called when a WiiUseApiEvent occurs. A WiiUseApiEvent can be : - + * WiimoteEvent (Storing ButtonsEvent and eventually IREvent and + * MotionSensingEvent) - StatusEvent - DisconnectionEvent + * + * @param e + */ + void onWiiUseApiEvent(WiiUseApiEvent e); + +} diff --git a/java/src/wiiusej/wiiusejevents/utils/WiimoteListener.java b/java/src/wiiusej/wiiusejevents/utils/WiimoteListener.java new file mode 100644 index 0000000..fd1017f --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/utils/WiimoteListener.java @@ -0,0 +1,145 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.utils; + +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent; +import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent; + +/** + * This is the interface to implement to listen to events from wiimotes. The + * differents methods are called in this order : onButtonsEvent, onIrEvent, + * onMotionSensingEvent, onExpansionEvent, onStatusEvent, onDisconnectionEvent + * onNunchukInsertedEvent, onNunchukRemovedEvent. + * + * @author guiguito + */ +public interface WiimoteListener extends java.util.EventListener { + + /** + * Method called on a button Event. + * + * @param e + * the buttonEvent with the last informations about the buttons + * of the wiimote. + */ + void onButtonsEvent(WiimoteButtonsEvent e); + + /** + * Method called when an IR event occurs. + * + * @param e + * the IREvent with the IR points seen. + */ + void onIrEvent(IREvent e); + + /** + * Method called when a motion sensing event occurs. + * + * @param e + * the motion sensing event with orientation and acceleration. + */ + void onMotionSensingEvent(MotionSensingEvent e); + + /** + * Method called when an expansion event occurs. + * + * @param e + * the expansion event occured. + */ + void onExpansionEvent(ExpansionEvent e); + + /** + * Method called on a status event. A status event occurs when : - we ask it - + * an expansion controller has been plugged - an expansion controller has + * been unplugged This is where you can get the different values of the + * parameters setup on your wiimote. + * + * @param e + * the status event. + */ + void onStatusEvent(StatusEvent e); + + /** + * This is the method called when a disconnection event occurs. A + * disconnection event happens when : - there are no battery left - the + * wiimote has just been turned off - the connection is dropped + * + * @param e + * the disconnection event. + */ + void onDisconnectionEvent(DisconnectionEvent e); + + /** + * This is the method called when a NunchukInsertedEvent occurs. + * + * @param e + * the NunchukInsertedEvent. + */ + void onNunchukInsertedEvent(NunchukInsertedEvent e); + + /** + * This is the method called when a NunchukRemovedEvent occurs. + * + * @param e + * the NunchukRemovedEvent. + */ + void onNunchukRemovedEvent(NunchukRemovedEvent e); + + + /** + * This is the method called when a GuitarHeroInsertedEvent occurs. + * + * @param e + * the GuitarHeroInsertedEvent. + */ + void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent e); + + /** + * This is the method called when a GuitarHeroRemovedEvent occurs. + * + * @param e + * the GuitarHeroRemovedEvent. + */ + void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent e); + + /** + * This is the method called when a ClassicControllerInsertedEvent occurs. + * + * @param e + * the ClassicControllerInsertedEvent. + */ + void onClassicControllerInsertedEvent(ClassicControllerInsertedEvent e); + + /** + * This is the method called when a ClassicControllerRemovedEvent occurs. + * + * @param e + * the ClassicControllerRemovedEvent. + */ + void onClassicControllerRemovedEvent(ClassicControllerRemovedEvent e); + +} diff --git a/java/src/wiiusej/wiiusejevents/wiiuseapievents/ClassicControllerInsertedEvent.java b/java/src/wiiusej/wiiusejevents/wiiuseapievents/ClassicControllerInsertedEvent.java new file mode 100644 index 0000000..5480c04 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/wiiuseapievents/ClassicControllerInsertedEvent.java @@ -0,0 +1,46 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.wiiuseapievents; + +/** + * Event that represents the connection of a classic controller to a wiimote. + * + * @author guiguito + * + */ +public class ClassicControllerInsertedEvent extends WiiUseApiEvent { + + /** + * Construct the ClassicControllerInsertedEvent setting up the id. + * + * @param id + * id of the wiimote. + */ + public ClassicControllerInsertedEvent(int id) { + super(id, WIIUSE_CLASSIC_CTRL_INSERTED); + } + + @Override + public String toString() { + String out = ""; + /* Status */ + out += "/*********** CLASSIC CONTROLLER INSERTED EVENT : WIIMOTE ID :" + + super.getWiimoteId() + " ********/\n"; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/wiiuseapievents/ClassicControllerRemovedEvent.java b/java/src/wiiusej/wiiusejevents/wiiuseapievents/ClassicControllerRemovedEvent.java new file mode 100644 index 0000000..c0c72b2 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/wiiuseapievents/ClassicControllerRemovedEvent.java @@ -0,0 +1,47 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.wiiuseapievents; + +/** + * Event that represents the disconnection of a classic controller from a + * wiimote. + * + * @author guiguito + * + */ +public class ClassicControllerRemovedEvent extends WiiUseApiEvent { + + /** + * Construct the ClassicControllerRemovedEvent setting up the id. + * + * @param id + * id of the wiimote. + */ + public ClassicControllerRemovedEvent(int id) { + super(id, WIIUSE_CLASSIC_CTRL_REMOVED); + } + + @Override + public String toString() { + String out = ""; + /* Status */ + out += "/*********** CLASSIC CONTROLLER REMOVED EVENT : WIIMOTE ID :" + + super.getWiimoteId() + " ********/\n"; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/wiiuseapievents/DisconnectionEvent.java b/java/src/wiiusej/wiiusejevents/wiiuseapievents/DisconnectionEvent.java new file mode 100644 index 0000000..1c844c7 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/wiiuseapievents/DisconnectionEvent.java @@ -0,0 +1,45 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.wiiuseapievents; + +/** + * Class representing a disconnection event. + * + * @author guiguito + */ +public class DisconnectionEvent extends WiiUseApiEvent { + + /** + * Construct the DisconnectionEvent setting up the id. + * + * @param id + * the Wiimote id + */ + public DisconnectionEvent(int id) { + super(id, WiiUseApiEvent.DISCONNECTION_EVENT); + } + + @Override + public String toString() { + String out = ""; + /* Status */ + out += "/*********** DISCONNECTION EVENT : WIIMOTE ID :" + + super.getWiimoteId() + " ********/\n"; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/wiiuseapievents/GuitarHeroInsertedEvent.java b/java/src/wiiusej/wiiusejevents/wiiuseapievents/GuitarHeroInsertedEvent.java new file mode 100644 index 0000000..18eda40 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/wiiuseapievents/GuitarHeroInsertedEvent.java @@ -0,0 +1,47 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.wiiuseapievents; + +/** + * Event that represents the connection of a Guitar hero controller to a + * wiimote. + * + * @author guiguito + * + */ +public class GuitarHeroInsertedEvent extends WiiUseApiEvent { + + /** + * Construct the GuitarHeroInsertedEvent setting up the id. + * + * @param id + * id of the wiimote. + */ + public GuitarHeroInsertedEvent(int id) { + super(id, WIIUSE_GUITAR_HERO_3_CTRL_INSERTED); + } + + @Override + public String toString() { + String out = ""; + /* Status */ + out += "/*********** GUITAR HERO INSERTED EVENT : WIIMOTE ID :" + + super.getWiimoteId() + " ********/\n"; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/wiiuseapievents/GuitarHeroRemovedEvent.java b/java/src/wiiusej/wiiusejevents/wiiuseapievents/GuitarHeroRemovedEvent.java new file mode 100644 index 0000000..e5ab258 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/wiiuseapievents/GuitarHeroRemovedEvent.java @@ -0,0 +1,47 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.wiiuseapievents; + +/** + * Event that represents the disconnection of a guitar hero controller from a + * wiimote. + * + * @author guiguito + * + */ +public class GuitarHeroRemovedEvent extends WiiUseApiEvent { + + /** + * Construct the GuitarHeroRemovedEvent setting up the id. + * + * @param id + * id of the wiimote. + */ + public GuitarHeroRemovedEvent(int id) { + super(id, WIIUSE_GUITAR_HERO_3_CTRL_REMOVED); + } + + @Override + public String toString() { + String out = ""; + /* Status */ + out += "/*********** GUITAR HERO REMOVED EVENT : WIIMOTE ID :" + + super.getWiimoteId() + " ********/\n"; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/wiiuseapievents/NunchukInsertedEvent.java b/java/src/wiiusej/wiiusejevents/wiiuseapievents/NunchukInsertedEvent.java new file mode 100644 index 0000000..6aff636 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/wiiuseapievents/NunchukInsertedEvent.java @@ -0,0 +1,51 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.wiiuseapievents; + +/** + * Event that represents the connection of a nunchuk to a wiimote. + * + * @author guiguito + * + */ +public class NunchukInsertedEvent extends WiiUseApiEvent { + + /** + * Construct the NunchukInsertedEvent setting up the id. + * + * @param id + * id of the wiimote. + */ + public NunchukInsertedEvent(int id) { + super(id, WIIUSE_NUNCHUK_INSERTED); + } + + /* + * (non-Javadoc) + * + * @see wiiusej.wiiusejevents.WiiUseApiEvent#toString() + */ + @Override + public String toString() { + String out = ""; + /* Status */ + out += "/*********** NUNCHUK INSERTED EVENT : WIIMOTE ID :" + + super.getWiimoteId() + " ********/\n"; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/wiiuseapievents/NunchukRemovedEvent.java b/java/src/wiiusej/wiiusejevents/wiiuseapievents/NunchukRemovedEvent.java new file mode 100644 index 0000000..869207a --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/wiiuseapievents/NunchukRemovedEvent.java @@ -0,0 +1,50 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.wiiuseapievents; + +/** + * Event that represents the disconnection of a nunchuk from a wiimote. + * + * @author guiguito + */ +public class NunchukRemovedEvent extends WiiUseApiEvent { + + /** + * Construct the NunchukInsertedEvent setting up the id. + * + * @param id + * id of the wiimote. + */ + public NunchukRemovedEvent(int id) { + super(id, WIIUSE_NUNCHUK_REMOVED); + } + + /* + * (non-Javadoc) + * + * @see wiiusej.wiiusejevents.WiiUseApiEvent#toString() + */ + @Override + public String toString() { + String out = ""; + /* Status */ + out += "/*********** NUNCHUK REMOVED EVENT : WIIMOTE ID :" + + super.getWiimoteId() + " ********/\n"; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/wiiuseapievents/StatusEvent.java b/java/src/wiiusej/wiiusejevents/wiiuseapievents/StatusEvent.java new file mode 100644 index 0000000..d200bb7 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/wiiuseapievents/StatusEvent.java @@ -0,0 +1,293 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.wiiuseapievents; + +/** + * Class used to represent a status event. This class is used to know what are + * the settings of the wiimote. + * + * @author guiguito + */ +public class StatusEvent extends WiiUseApiEvent { + + protected static short WIIMOTE_LED_1 = 1; + protected static short WIIMOTE_LED_2 = 2; + protected static short WIIMOTE_LED_3 = 4; + protected static short WIIMOTE_LED_4 = 8; + + /* ATTACHMENT CONSTANTS */ + + private static short EXP_NONE = 0; + private static short EXP_NUNCHUK = 1; + private static short EXP_CLASSIC = 2; + private static short EXP_GUITAR_HERO_3 = 3; + + /* Status variables */ + private boolean connected = false; + + private float batteryLevel = -1; + + private short leds = 0; + + private boolean isSpeakerEnabled = false; + + private int attachment = 0; + + private boolean isRumbleActive = false; + + private boolean isContinuousActive = false; + + private boolean isIrActive = false; + + private boolean isMotionSensingActive = false; + + /** + * Construct the StatusEvent setting up the id. + * + * @param id + * the Wiimote id + */ + public StatusEvent(int id) { + super(id, WiiUseApiEvent.STATUS_EVENT); + } + + /** + * Build a StatusEvent with all fields set. + * + * @param id + * id of the wiimote + * @param connect + * true if the wiimote is connected + * @param batt + * battery level + * @param led + * status of leds + * @param speak + * speakers status + * @param attach + * attachment status + * @param rumbleState + * true if rumble is active + * @param continuousState + * true if continuous flag is activated + * @param irState + * true if ir is active + * @param motionSensingState + * true if accelerometer is active + */ + public StatusEvent(int id, boolean connect, float batt, short led, + boolean speak, int attach, boolean rumbleState, + boolean continuousState, boolean irState, boolean motionSensingState) { + super(id, WiiUseApiEvent.STATUS_EVENT); + connected = connect; + this.batteryLevel = batt; + this.leds = led; + this.isSpeakerEnabled = speak; + this.attachment = attach; + isRumbleActive = rumbleState; + isContinuousActive = continuousState; + isIrActive = irState; + isMotionSensingActive = motionSensingState; + } + + /** + * True if the wiimote is connected false otherwise. + * + * @return return the connected status. + */ + public boolean isConnected() { + return connected; + } + + /** + * Get battery level. + * + * @return battery level. 1 = 100% + */ + public float getBatteryLevel() { + return batteryLevel; + } + + /** + * Get status of the leds . + * + * @return a short representing LEDS turned on. + */ + public short getLeds() { + return leds; + } + + /** + * Tells if the given led is turned on according to the leds status int. + * + * @param led + * the int encoding a led. + * @return true if the led is turned on false otherwise. + */ + private boolean ledStatusCheck(short led) { + if ((leds & led) > 0) { + return true; + } else { + return false; + } + } + + /** + * Get led1 status. + * + * @return true if the led is set. + */ + public boolean isLed1Set() { + return ledStatusCheck(WIIMOTE_LED_1); + } + + /** + * Get led2 status. + * + * @return true if the led is set. + */ + public boolean isLed2Set() { + return ledStatusCheck(WIIMOTE_LED_2); + } + + /** + * Get led3 status. + * + * @return true if the led is set. + */ + public boolean isLed3Set() { + return ledStatusCheck(WIIMOTE_LED_3); + } + + /** + * Get led4 status. + * + * @return true if the led is set. + */ + public boolean isLed4Set() { + return ledStatusCheck(WIIMOTE_LED_4); + } + + /** + * Tell if the speaker is enable for this wiimote + * + * @return TRUE if it enabled false otherwise + */ + public boolean isSpeakerEnabled() { + return isSpeakerEnabled; + } + + /** + * Get the int representing the attachment type. + * + * @return value of the Attachment Type + */ + public int getAttachment() { + return attachment; + } + + /** + * Get the status of rumble. + * + * @return true if the rumble is active false otherwise + */ + public boolean isRumbleActive() { + return isRumbleActive; + } + + /** + * Tell if the CONTINUOUS option is activated. + * + * @return the isContinuousActive + */ + public boolean isContinuousActive() { + return isContinuousActive; + } + + /** + * Tell if the IR Tracking is active. + * + * @return TRUE if it is active or false otherwise. + */ + public boolean isIrActive() { + return isIrActive; + } + + /** + * Get the flag indicating if the motion sensing is active. + * + * @return true if the motion sensing is active false otherwise + */ + public boolean isMotionSensingActive() { + return isMotionSensingActive; + } + + /** + * Tells if an attachment is connected. + * + * @return true if anything is connected to the wiimote false otherwise. + */ + public boolean isAttachmentConnected() { + return attachment == EXP_NONE; + } + + /** + * Tells if a nunchuk is connected. + * + * @return true if a nunchuk is connected to the wiimote false otherwise. + */ + public boolean isNunchukConnected() { + return attachment == EXP_NUNCHUK; + } + + /** + * Tells if a classic controller is connected. + * + * @return true if a classic controller is connected to the wiimote false otherwise. + */ + public boolean isClassicControllerConnected() { + return attachment == EXP_CLASSIC; + } + + /** + * Tells if a guitar hero controller is connected. + * + * @return true if a guitar hero controllerr is connected to the wiimote false otherwise. + */ + public boolean isGuitarHeroConnected() { + return attachment == EXP_GUITAR_HERO_3; + } + + @Override + public String toString() { + String out = ""; + /* Status */ + out += "/*********** STATUS EVENT : WIIMOTE ID :" + + super.getWiimoteId() + " ********/\n"; + out += "--- connected : " + connected + "\n"; + out += "--- Battery level : " + batteryLevel + "\n"; + out += "--- Leds : " + leds + "\n"; + out += "--- Speaker enabled : " + isSpeakerEnabled + "\n"; + out += "--- Attachment ? : " + attachment + "\n"; + out += "--- Rumble ? : " + isRumbleActive + "\n"; + out += "--- Continuous ? : " + isContinuousActive + "\n"; + out += "--- IR active ? : " + isIrActive + "\n"; + out += "--- Motion sensing active ? : " + isMotionSensingActive + "\n"; + return out; + } + +} diff --git a/java/src/wiiusej/wiiusejevents/wiiuseapievents/WiiUseApiEvent.java b/java/src/wiiusej/wiiusejevents/wiiuseapievents/WiiUseApiEvent.java new file mode 100644 index 0000000..0527b13 --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/wiiuseapievents/WiiUseApiEvent.java @@ -0,0 +1,66 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.wiiuseapievents; + +import wiiusej.wiiusejevents.GenericEvent; + +/** + * This class describes the structure of an event from the WiiUse API event. + * + * @author guiguito + */ +public abstract class WiiUseApiEvent extends GenericEvent{ + + public static int NONE_EVENT = 0; + public static int GENERIC_EVENT = 1; + public static int STATUS_EVENT = 2; + public static int DISCONNECTION_EVENT = 3; + public static int WIIUSE_READ_DATA = 4; + public static int WIIUSE_NUNCHUK_INSERTED = 5; + public static int WIIUSE_NUNCHUK_REMOVED = 6; + public static int WIIUSE_CLASSIC_CTRL_INSERTED = 7; + public static int WIIUSE_CLASSIC_CTRL_REMOVED = 8; + public static int WIIUSE_GUITAR_HERO_3_CTRL_INSERTED = 9; + public static int WIIUSE_GUITAR_HERO_3_CTRL_REMOVED = 10; + + /* Event Type */ + private int eventType; + + /** + * Construct the WiiUseApiEvent setting up the id. + * + * @param id + * the Wiimote id + * @param type + * type of the event + */ + public WiiUseApiEvent(int id, int type) { + super(id); + eventType = type; + } + + /** + * Get the event type. + * @return the eventType + */ + public int getEventType() { + return eventType; + } + + public abstract String toString(); + +} diff --git a/java/src/wiiusej/wiiusejevents/wiiuseapievents/WiimoteEvent.java b/java/src/wiiusej/wiiusejevents/wiiuseapievents/WiimoteEvent.java new file mode 100644 index 0000000..d1dfb7e --- /dev/null +++ b/java/src/wiiusej/wiiusejevents/wiiuseapievents/WiimoteEvent.java @@ -0,0 +1,441 @@ +/** + * This file is part of WiiuseJ. + * + * WiiuseJ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WiiuseJ 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WiiuseJ. If not, see . + */ +package wiiusej.wiiusejevents.wiiuseapievents; + +import wiiusej.wiiusejevents.physicalevents.ClassicControllerEvent; +import wiiusej.wiiusejevents.physicalevents.ExpansionEvent; +import wiiusej.wiiusejevents.physicalevents.GuitarHeroEvent; +import wiiusej.wiiusejevents.physicalevents.IREvent; +import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent; +import wiiusej.wiiusejevents.physicalevents.NunchukEvent; +import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent; + +/** + * Class that is a bean to be filled by the wiiuse API on an event that occurs + * on a wiimote. + * + * @author guiguito + */ +public class WiimoteEvent extends WiiUseApiEvent { + + private WiimoteButtonsEvent buttonsEvent = null; + private IREvent infraredEvent = null; + private MotionSensingEvent motionSensingEvent = null; + private ExpansionEvent expansionEvent = null; + + /** + * Construct the Wiimote setting up the id. + * + * @param id + * the Wiimote id + */ + public WiimoteEvent(int id) { + super(id, WiiUseApiEvent.GENERIC_EVENT); + } + + /** + * Construct the Wiimote setting up the id and the buttons. + * + * @param id + * the Wiimote id + * @param buttonsJustPressed + * buttons just pressed + * @param buttonsJustReleased + * buttons just released + * @param buttonsHeld + * buttons held + */ + public WiimoteEvent(int id, short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld) { + super(id, WiiUseApiEvent.GENERIC_EVENT); + buttonsEvent = new WiimoteButtonsEvent(id, buttonsJustPressed, + buttonsJustReleased, buttonsHeld); + } + + /** + * Tell if there is an IR Event. + * + * @return TRUE if there is an IR event. + */ + public boolean isThereIrEvent() { + return infraredEvent != null; + } + + /** + * Tell if there is a motion sensing Event. + * + * @return TRUE if there is a motion sensing event. + */ + public boolean isThereMotionSensingEvent() { + return motionSensingEvent != null; + } + + /** + * Tell if there is an expansion Event. + * + * @return TRUE if there is an expansion event. + */ + public boolean isThereExpansionEvent() { + return expansionEvent != null; + } + + /** + * Get buttons event. + * + * @return the buttons event. + */ + public WiimoteButtonsEvent getButtonsEvent() { + return buttonsEvent; + } + + /** + * Get the IR event. + * + * @return the IR event if there is one or null. + */ + public IREvent getIREvent() { + return infraredEvent; + } + + /** + * Get the motion sensing event. + * + * @return the motion sensing event if there is one or null. + */ + public MotionSensingEvent getMotionSensingEvent() { + return motionSensingEvent; + } + + /** + * Get the expansion event. + * + * @return the expansion event if there is one or null. + */ + public ExpansionEvent getExpansionEvent() { + return expansionEvent; + } + + /** + * Prepare an IR event to populate. + * + * @param x + * calculated X coordinate. + * @param y + * calculated Y coordinate. + * @param z + * calculated distance. + * @param ax + * absolute X coordinate. + * @param ay + * absolute Y coordinate + * @param xVRes + * IR virtual screen x resolution. + * @param yVRes + * IR virtual screen y resolution. + * @param xOffset + * IR X correction offset. + * @param yOffset + * IR Y correction offset. + * @param sensorBarPostion + * aspect ratio of the screen. + * @param screenAsPectRatio + * IR sensor bar position. + * @param irSensitivity + * Sensitivity of the infrared camera. + * @param distance + * Pixel Distance between first two dots + */ + public void prepareIRevent(int x, int y, float z, int ax, int ay, + int xVRes, int yVRes, int xOffset, int yOffset, + short sensorBarPostion, short screenAsPectRatio, + short irSensitivity, float distance) { + if (infraredEvent == null) { + infraredEvent = new IREvent(getWiimoteId(), x, y, z, ax, ay, xVRes, + yVRes, xOffset, yOffset, sensorBarPostion, + screenAsPectRatio, irSensitivity, distance); + } + } + + /** + * Add an IR point to the generic event. Create an IR Event if it's not + * created yet. + * + * @param x + * x coordinates. + * @param y + * y coordinates + * @param rx + * raw X coordinate (0-1023). + * @param ry + * raw Y coordinate (0-1023). + * @param size + * size of the IR dot (0-15). + */ + public void addIRpoint(int x, int y, short rx, short ry, short size) { + if (infraredEvent != null) + infraredEvent.addIRpoint(x, y, rx, ry, size); + } + + /** + * Set the Motion Sensing Event. + * + * @param orientationThreshold + * value of the minimum angle between two events with the + * accelerometer. + * @param accelerationThreshold + * value of the value variation between two events with the + * accelerometer. + * @param smoothingState + * true if smoothing flag is activated. + * @param alphaSmooth + * value of the alpha smoothing parameter. + * @param r + * roll. + * @param p + * pitch. + * @param ya + * yaw. + * @param ar + * absolute roll. + * @param ap + * absolute pitch. + * @param x + * gravity force on x axis. + * @param y + * gravity force on y axis. + * @param z + * gravity force on z axis. + * @param xx + * raw acceleration on x axis. + * @param yy + * raw acceleration on y axis. + * @param zz + * raw acceleration on z axis. + */ + public void setMotionSensingEvent(float orientationThreshold, + int accelerationThreshold, boolean smoothingState, + float alphaSmooth, float r, float p, float ya, float ar, float ap, + float x, float y, float z, short xx, short yy, short zz) { + motionSensingEvent = new MotionSensingEvent(getWiimoteId(), + orientationThreshold, accelerationThreshold, smoothingState, + alphaSmooth, r, p, ya, ar, ap, x, y, z, xx, yy, zz); + } + + /** + * Set a NunchukEvent for the expansion event. + * + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just pressed. + * @param orientationThreshold + * value of the minimum angle between two events with the + * accelerometer. + * @param accelerationThreshold + * value of the value variation between two events with the + * accelerometer. + * @param smoothingState + * true if smoothing flag is activated. + * @param alphaSmooth + * value of the alpha smoothing parameter. + * @param r + * roll. + * @param p + * pitch. + * @param ya + * yaw. + * @param ar + * absolute roll. + * @param ap + * absolute pitch. + * @param x + * gravity force on x axis. + * @param y + * gravity force on y axis. + * @param z + * gravity force on z axis. + * @param xx + * raw acceleration on x axis. + * @param yy + * raw acceleration on y axis. + * @param zz + * raw acceleration on z axis. + * @param angle + * angle the joystick is being held. + * @param magnitude + * magnitude of the joystick (range 0-1). + * @param max1 + * maximum joystick value 1. + * @param max2 + * maximum joystick value 2. + * @param min1 + * minimum joystick value 1. + * @param min2 + * minimum joystick value 2. + * @param center1 + * center joystick value 1. + * @param center2 + * center joystick value 2. + */ + public void setNunchukEvent(short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld, + float orientationThreshold, int accelerationThreshold, + boolean smoothingState, float alphaSmooth, float r, float p, + float ya, float ar, float ap, float x, float y, float z, short xx, + short yy, short zz, float angle, float magnitude, short max1, + short max2, short min1, short min2, short center1, short center2) { + expansionEvent = new NunchukEvent(getWiimoteId(), buttonsJustPressed, + buttonsJustReleased, buttonsHeld, orientationThreshold, + accelerationThreshold, smoothingState, alphaSmooth, r, p, ya, + ar, ap, x, y, z, xx, yy, zz, angle, magnitude, max1, max2, + min1, min2, center1, center2); + } + + /** + * Set a ClassicControllerEvent for the expansionEvent. + * + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just pressed. + * @param rightShoulder + * right shoulder button (range 0-1). + * @param leftShoulder + * left shoulder button (range 0-1). + * @param langle + * angle the left joystick is being held. + * @param lmagnitude + * magnitude of the left joystick (range 0-1). + * @param lmax1 + * maximum left joystick value 1. + * @param lmax2 + * maximum left joystick value 2. + * @param lmin1 + * minimum left joystick value 1. + * @param lmin2 + * minimum left joystick value 2. + * @param lcenter1 + * center left joystick value 1. + * @param lcenter2 + * center left joystick value 2. + * @param rangle + * angle the right joystick is being held. + * @param rmagnitude + * magnitude of the right joystick (range 0-1). + * @param rmax1 + * maximum right joystick value 1. + * @param rmax2 + * maximum right joystick value 2. + * @param rmin1 + * minimum right joystick value 1. + * @param rmin2 + * minimum right joystick value 2. + * @param rcenter1 + * center right joystick value 1. + * @param rcenter2 + * center right joystick value 2. + */ + public void setClassicControllerEvent(short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld, float rightShoulder, + float leftShoulder, float langle, float lmagnitude, short lmax1, + short lmax2, short lmin1, short lmin2, short lcenter1, + short lcenter2, float rangle, float rmagnitude, short rmax1, + short rmax2, short rmin1, short rmin2, short rcenter1, + short rcenter2) { + expansionEvent = new ClassicControllerEvent(getWiimoteId(), + buttonsJustPressed, buttonsJustReleased, buttonsHeld, + rightShoulder, leftShoulder, langle, lmagnitude, lmax1, lmax2, + lmin1, lmin2, lcenter1, lcenter2, rangle, rmagnitude, rmax1, + rmax2, rmin1, rmin2, rcenter1, rcenter2); + } + + /** + * Set a GuitarHeroEvent for the expansionEvent. + * + * @param buttonsJustPressed + * buttons just pressed. + * @param buttonsJustReleased + * buttons just released. + * @param buttonsHeld + * buttons just pressed. + * @param whammyBar + * whammy bar (range 0-1). + * @param angle + * angle the joystick is being held. + * @param magnitude + * magnitude of the joystick (range 0-1). + * @param max1 + * maximum joystick value 1. + * @param max2 + * maximum joystick value 2. + * @param min1 + * minimum joystick value 1. + * @param min2 + * minimum joystick value 2. + * @param center1 + * center joystick value 1. + * @param center2 + * center joystick value 2. + */ + public void setGuitarHeroEvent(short buttonsJustPressed, + short buttonsJustReleased, short buttonsHeld, float whammyBar, + float angle, float magnitude, short max1, short max2, short min1, + short min2, short center1, short center2) { + expansionEvent = new GuitarHeroEvent(getWiimoteId(), + buttonsJustPressed, buttonsJustReleased, buttonsHeld, + whammyBar, angle, magnitude, max1, max2, min1, min2, center1, + center2); + } + + @Override + public String toString() { + String out = ""; + /* Status */ + out += "/*********** GENERIC EVENT : WIIMOTE ID :" + getWiimoteId() + + " ********/\n"; + + out += buttonsEvent; + + if (infraredEvent != null) { + out += infraredEvent; + } else { + out += "/******** IR Tracking ********/\n"; + out += "--- Active : false\n"; + } + + if (motionSensingEvent != null) { + out += motionSensingEvent; + } else { + out += "/******** Motion sensing ********/\n"; + out += "--- Motion sensing : false \n"; + } + + if (expansionEvent != null) { + out += expansionEvent; + } else { + out += "/******** Expansion ********/\n"; + out += "--- No expansion connected \n"; + } + + return out; + } + +}