+++ /dev/null
-/* Base definitions file for a LightsDriver_Dynamic module.
- * This file contains all the definitions you'll want, or at least
- * need. If not, let me know and we can update the API. -- Vyhd */
-
-/* API overview, version 1.1:
- *
- * int Load():
- * Called on initialization. This must return 0 on successful init,
- * or nonzero for failure. Return value will be used to retrieve an
- * error message, if you have one defined.
- *
- * void Unload():
- * Called on de-initialization. All library cleanup must be done here.
- *
- * int Update( struct CLightsState *state ):
- * Called on lights update. CLightsState and its component enums are
- * defined below, so you can see that on how the structure is handled.
- * Returns 0 on successful update, or nonzero for failure. If the
- * returned error code is < 0, the device is presumed lost and the
- * driver is unloaded.
- *
- * const LightsModuleInfo* GetModuleInfo():
- * Returns a pointer to a const LightsModuleInfo struct. This is used to
- * check the API version and make sure that the binary is compatible
- * as well as retrieve a description for the logs.
- *
- * const char *GetError( int code ):
- * Returns a pointer to an error message corresponding to the given
- * code. This is used to retrieve errors obtained during Init() and
- * Update().
- *
- * If you're still confused, check out an example .so in Docs.
- */
-
-
-#ifndef LIGHTSDRIVER_MODULE_DEFS_H
-#define LIGHTSDRIVER_MODULE_DEFS_H
-
-#define LIGHTS_API_VERSION_MAJOR 1 // incremented whenever the API breaks old versions
-#define LIGHTS_API_VERSION_MINOR 1 // incremented whenever new calls are added
-
-/* we need a uint8_t type for CLightsState, but we don't
- * want to require stdint, especially not for Windows. */
-#ifndef GLOBAL_H
- #ifdef _MSC_VER
- typedef unsigned __int8 uint8_t;
- #else
- typedef unsigned char uint8_t;
- #endif
-#endif
-
-/* forward struct declarations */
-struct CLightsState;
-struct LightsModuleInfo;
-
-/* typedefs for function casting, placed here for consistency */
-typedef int (*LoadFn)();
-typedef int (*UnloadFn)();
-typedef int (*UpdateFn)(struct CLightsState*);
-typedef const struct LightsModuleInfo* (*GetLightsModuleInfoFn)();
-typedef const char* (*GetErrorFn)(int);
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/* contains all the info we need to have about a module. this can be extended
- * but any old variables must remain in place to maintain compatibility. */
-struct LightsModuleInfo
-{
- short mi_api_ver_major;
- short mi_api_ver_minor;
- short mi_lights_ver_major;
- short mi_lights_ver_minor;
- const char *mi_name;
- const char *mi_author;
-};
-
-/* Enumeration definitions that you will definitely want
- * for handling lights within the given CLightsState. */
-
-#ifndef GLOBAL_H
-enum CabinetLight
-{
- LIGHT_MARQUEE_UP_LEFT,
- LIGHT_MARQUEE_UP_RIGHT,
- LIGHT_MARQUEE_LR_LEFT,
- LIGHT_MARQUEE_LR_RIGHT,
- LIGHT_BUTTONS_LEFT,
- LIGHT_BUTTONS_RIGHT,
- LIGHT_BASS_LEFT,
- LIGHT_BASS_RIGHT,
- NUM_CABINET_LIGHTS,
- LIGHT_INVALID
-};
-
-enum GameController
-{
- GAME_CONTROLLER_1, // left controller
- GAME_CONTROLLER_2, // right controller
- MAX_GAME_CONTROLLERS, // leave this at the end
- GAME_CONTROLLER_INVALID,
-};
-
-enum GameButton
-{
- GAME_BUTTON_MENULEFT,
- GAME_BUTTON_MENURIGHT,
- GAME_BUTTON_MENUUP,
- GAME_BUTTON_MENUDOWN,
- GAME_BUTTON_START,
- GAME_BUTTON_SELECT,
- GAME_BUTTON_BACK,
- GAME_BUTTON_COIN,
- GAME_BUTTON_OPERATOR,
- GAME_BUTTON_CUSTOM_01,
- GAME_BUTTON_CUSTOM_02,
- GAME_BUTTON_CUSTOM_03,
- GAME_BUTTON_CUSTOM_04,
- GAME_BUTTON_CUSTOM_05,
- GAME_BUTTON_CUSTOM_06,
- GAME_BUTTON_CUSTOM_07,
- GAME_BUTTON_CUSTOM_08,
- GAME_BUTTON_CUSTOM_09,
- GAME_BUTTON_CUSTOM_10,
- GAME_BUTTON_CUSTOM_11,
- GAME_BUTTON_CUSTOM_12,
- GAME_BUTTON_CUSTOM_13,
- GAME_BUTTON_CUSTOM_14,
- GAME_BUTTON_CUSTOM_15,
- GAME_BUTTON_CUSTOM_16,
- GAME_BUTTON_CUSTOM_17,
- GAME_BUTTON_CUSTOM_18,
- GAME_BUTTON_CUSTOM_19,
-
- MAX_GAME_BUTTONS,
- GAME_BUTTON_INVALID,
-};
-
-/* convenience macros for enumeration loops. Remember that this
- * is C, so you'll need to define your variables beforehand. */
-#define FOREACH_ENUM(t,var,start,max) for( var = start; var < max; var = (enum t)(var+1) )
-
-#define FOREACH_CabinetLight( cl ) FOREACH_ENUM( CabinetLight, cl, LIGHT_MARQUEE_UP_LEFT, NUM_CABINET_LIGHTS )
-
-#define FOREACH_GameController( gc ) FOREACH_ENUM( GameController, gc, GAME_CONTROLLER_1, MAX_GAME_CONTROLLERS )
-#define FOREACH_GameButton( gb ) FOREACH_ENUM( GameButton, gb, GAME_BUTTON_MENULEFT, MAX_GAME_BUTTONS )
-#define FOREACH_GameButton_Custom( gb ) FOREACH_ENUM( GameButton, gb, GAME_BUTTON_CUSTOM_01, MAX_GAME_BUTTONS )
-
-#endif // !GLOBAL_H
-
-/* This is a C-struct of LightsState, since bool isn't a native type and
- * can vary in size between implementations. uint8_t fixes those both. */
-struct CLightsState
-{
- uint8_t m_bCabinetLights[NUM_CABINET_LIGHTS];
- uint8_t m_bGameButtonLights[MAX_GAME_CONTROLLERS][MAX_GAME_BUTTONS];
-
- // This isn't actually a light, but if you're paying attention, you know that already.
- uint8_t m_bCoinCounter;
-};
-
-#if defined(__cplusplus)
-}
-#endif // __cplusplus
-
-#endif // LIGHTSDRIVER_MODULE_DEFS_H
+++ /dev/null
-/* Example LightsDriver, shared library, using printf().
- * Compile with:
- * gcc -O2 -Wall -fPIC -shared LightsDriver_Stdout.c -o LightsDriver_Stdout.so
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "LightsDriver_ModuleDefs.h"
-
-struct LightsModuleInfo info =
-{
- LIGHTS_API_VERSION_MAJOR, /* API major version */
- LIGHTS_API_VERSION_MINOR, /* API minor version */
- 1, /* Lib major version */
- 0, /* Lib minor version */
- "Stdout", /* Driver description */
- "Vyhd", /* Driver author */
-};
-
-const struct LightsModuleInfo* GetModuleInfo()
-{
- return &info;
-}
-
-const char *GetError( int code )
-{
- switch( code )
- {
- case 1:
- return "You got rand()'d (equal to zero)!";
- };
-
- return NULL;
-}
-
-int Load()
-{
- printf( "Stdout init\n" );
-
- if( rand() % 5 == 0 )
- return 1;
-
- return 0;
-}
-
-void Unload()
-{
- printf( "Stdout de-init\n" );
-}
-
-int Update( struct CLightsState *state )
-{
- enum CabinetLight cl = (enum CabinetLight) 0;
- enum GameController gc = (enum GameController) 0;
- enum GameButton gb = (enum GameButton) 0;
-
- FOREACH_CabinetLight( cl )
- printf( "%c", (state->m_bCabinetLights[cl]) == 0 ? '0' : '1' );
- printf( " " );
-
- FOREACH_GameController( gc )
- {
- FOREACH_GameButton( gb )
- printf( "%c", (state->m_bGameButtonLights[gc][gb]) == 0 ? '0' : '1' );
-
- printf( " " );
- }
-
- printf( "\n" );
- return 0;
-}
+++ /dev/null
-These modules are not sandboxed or really checked for safety. They CAN
-and WILL crash the game if they aren't well written. Only use modules
-that you wrote yourself or that you know you can trust.
-
-To call this feature 'experimental' is almost an insult to experimental
-works. The downside is that it'll behave in wacky ways. The upside is
-that you're in an excellent shape to help us develop it, if that's your
-thing.
-
-Compiled modules go in Data/Modules/. The appropriate name (i.e. the
-second part of "LightsDriver_blah") should be inserted into LightsDriver=
-in StepMania.ini (don't worry, it'll use more than one). This is currently
-case sensitive, i.e. "stdout" won't work for the given Stdout driver. I'm
-working on that.
-
-Cheers, have fun!
-- vyhd
Lights = arch/Lights/LightsDriver.cpp arch/Lights/LightsDriver.h \
arch/Lights/LightsDriver_SystemMessage.cpp arch/Lights/LightsDriver_SystemMessage.h \
arch/Lights/LightsDriver_External.cpp arch/Lights/LightsDriver_External.h \
- arch/Lights/LightsDriver_Dynamic.cpp arch/Lights/LightsDriver_Dynamic.h \
- arch/Lights/LightsDriver_Dynamic_Unix.cpp arch/Lights/LightsDriver_Dynamic_Unix.h \
arch/Lights/LightsDriver_PacDrive.cpp arch/Lights/LightsDriver_PacDrive.h \
arch/Lights/LightsDriver_G15.cpp arch/Lights/LightsDriver_G15.h
#include "Foreach.h"
#include "arch/arch_default.h"
-#include "arch/Lights/LightsDriver_Dynamic.h"
-#include "arch/Lights/LightsDriver_Dynamic_Unix.h"
-
#include "arch/Lights/LightsDriver_SystemMessage.h"
#include "arch/Lights/LightsDriver_External.h"
#include "RageFileManager.h"
#include "RageUtil.h"
-#if defined(_WINDOWS)
-#define LIB_EXTENSION ".dll"
-#elif defined(LINUX)
-#define LIB_EXTENSION ".so"
-#endif
-
-const CString GetModuleDir()
-{
- static CString sModulePath;
-
- if( !sModulePath.empty() )
- return sModulePath;
-
- vector<RageFileManager::DriverLocation> mountpoints;
- FILEMAN->GetLoadedDrivers( mountpoints );
-
- for( unsigned i = 0; i < mountpoints.size(); ++i )
- {
- RageFileManager::DriverLocation *l = &mountpoints[i];
-
- if( l->Type != "dir" )
- continue;
-
- if( l->MountPoint == "/" )
- sModulePath = l->Root + "/Data/Modules/";
- else if( l->MountPoint == "/Data" )
- sModulePath = l->Root + "/Modules/";
-
- if( !sModulePath.empty() )
- break;
- }
-
- // extraneous dots will screw up the system-level paths.
- CollapsePath(sModulePath);
-
- LOG->Debug( "GetModuleDir(): returning %s", sModulePath.c_str() );
- return sModulePath;
-}
-
-/* XXX: can we find a better place for this? */
-static LightsDriver *TryModuleDriver( const CString &sName )
-{
- /* e.g. "stdout" looks for "LightsDriver_Stdout.so" */
- CString sDriverName = "LightsDriver_" + sName + LIB_EXTENSION;
-
- CString sRagePath = "Data/Modules/" + sDriverName;
- CString sRealPath = GetModuleDir() + sDriverName;
-
- if( !IsAFile(sRagePath) )
- return NULL;
-
-#if defined(LINUX)
- LightsDriver_Dynamic *ret = new LightsDriver_Dynamic_Unix( sRealPath );
-#else
- LightsDriver_Dynamic *ret = NULL;
- // TODO: LightsDriver_Dynamic_Win32
- return NULL;
-#endif
-
- ret->Load();
-
- /* if this module couldn't actually load, don't return it. */
- if( !ret->IsLoaded() )
- SAFE_DELETE( ret );
-
- return ret;
-}
-
void LightsDriver::Create( const CString &sDrivers, vector<LightsDriver *> &Add )
{
LOG->Trace( "Initializing lights drivers: %s", sDrivers.c_str() );
vector<CString> asDriversToTry;
split( sDrivers, ",", asDriversToTry, true );
-
+
FOREACH_CONST( CString, asDriversToTry, Driver )
{
RageDriver *pRet = m_pDriverList.Create( *Driver );
if( pRet == NULL )
{
- /* no built-in driver was found. See if any modules match this name. */
- pRet = TryModuleDriver( *Driver );
-
- if( pRet == NULL )
- {
- LOG->Trace( "Unknown lights driver: %s", Driver->c_str() );
- continue;
- }
+ LOG->Trace( "Unknown lights driver: %s", Driver->c_str() );
+ continue;
}
LightsDriver *pDriver = dynamic_cast<LightsDriver *>( pRet );
+++ /dev/null
-#include "global.h"
-#include "RageLog.h"
-#include "RageUtil.h"
-#include "LightsDriver_Dynamic.h"
-
-CLightsState LightsDriver_Dynamic::m_CLightsState;
-
-LightsDriver_Dynamic::LightsDriver_Dynamic( const CString &sLibPath )
-{
- m_bLoaded = false;
- m_sLibraryPath = sLibPath;
-}
-
-bool LightsDriver_Dynamic::LoadInternal()
-{
- ASSERT( !m_sLibraryPath.empty() );
-
- const struct LightsModuleInfo *info = Module_GetModuleInfo();
- CHECKPOINT;
-
- if( info == NULL )
- {
- LOG->Warn( "Could not get LightsModuleInfo from LightsDriver \"%s\".", m_sLibraryPath.c_str() );
- return false;
- }
-
- CHECKPOINT;
- if( LIGHTS_API_VERSION_MAJOR != info->mi_api_ver_major ||
- LIGHTS_API_VERSION_MINOR != info->mi_api_ver_minor )
- {
- LOG->Warn( "LightsDriver \"%s\" uses API version %d.%d, binary uses %d.%d. Disabled.",
- info->mi_name, info->mi_api_ver_major, info->mi_api_ver_minor,
- LIGHTS_API_VERSION_MAJOR, LIGHTS_API_VERSION_MINOR );
- return false;
- }
- CHECKPOINT;
-
- LOG->Trace( "%s: attempting to load LightsDriver \"%s\".", __FUNCTION__, info->mi_name );
- CHECKPOINT;
- int iError = Module_Load();
- CHECKPOINT;
-
- CHECKPOINT;
- if( iError != 0 )
- {
- CHECKPOINT;
- CString sError = ssprintf( "Error initializing LightsDriver \"%s\": %s", info->mi_name,
- (Module_GetError != NULL) ? Module_GetError(iError) : "(no error message)" );
- LOG->Warn( sError );
- CHECKPOINT;
- Module_Unload();
- CHECKPOINT;
- return false;
- }
-
- CHECKPOINT;
- LOG->Debug( "Established connection with LightsDriver \"%s\".", info->mi_name );
- LOG->Info( "LightsDriver module: %s, author: %s, version: %d.%d",
- info->mi_name, info->mi_author, info->mi_api_ver_major, info->mi_api_ver_minor );
-
- m_bLoaded = true;
- CHECKPOINT;
-
- return true;
-}
-
-LightsDriver_Dynamic::~LightsDriver_Dynamic()
-{
- /* bit of a hack. force all lights off. */
- if( m_bLoaded )
- {
- CLightsState blank;
- ZERO( blank );
- Module_Update( &blank );
- Module_Unload();
- }
-}
-
-void LightsDriver_Dynamic::Set( const LightsState *ls )
-{
- if( !m_bLoaded )
- return;
-
- MakeCLightsState( ls );
- Module_Update( &m_CLightsState );
-}
-
-void LightsDriver_Dynamic::MakeCLightsState( const LightsState *ls )
-{
- FOREACH_CabinetLight( cl )
- m_CLightsState.m_bCabinetLights[cl] = uint8_t(ls->m_bCabinetLights[cl]);
-
- FOREACH_GameController( gc )
- FOREACH_GameButton( gb )
- m_CLightsState.m_bGameButtonLights[gc][gb] = uint8_t(ls->m_bGameButtonLights[gc][gb]);
-}
+++ /dev/null
-#ifndef LIGHTS_DRIVER_DYNAMIC
-#define LIGHTS_DRIVER_DYNAMIC
-
-#include "LightsDriver.h"
-
-/* included because we need CLightsState and API data. */
-#include "../../../Docs/LightsDriver-API/LightsDriver_ModuleDefs.h"
-
-class LightsDriver_Dynamic: public LightsDriver
-{
-public:
- LightsDriver_Dynamic( const CString &sLibPath );
- ~LightsDriver_Dynamic();
-
- void Set( const LightsState *ls );
-
- virtual bool Load() = 0;
- bool IsLoaded() { return m_bLoaded; }
-protected:
- virtual bool LoadInternal();
-
- LoadFn Module_Load;
- UnloadFn Module_Unload;
- UpdateFn Module_Update;
- GetErrorFn Module_GetError;
- GetLightsModuleInfoFn Module_GetModuleInfo;
-
- CString m_sLibraryPath;
-private:
- bool m_bLoaded;
-
- static void MakeCLightsState( const LightsState *ls );
-
- static LightsState m_LastState;
- static CLightsState m_CLightsState;
-};
-
-#endif // LIGHTS_DRIVER_DYNAMIC
+++ /dev/null
-#include "global.h"
-#include "LightsDriver_Dynamic_Unix.h"
-#include "RageLog.h"
-
-#include <dlfcn.h>
-
-bool LightsDriver_Dynamic_Unix::Load()
-{
- CHECKPOINT;
- LOG->Debug( "Loading LightsDriver_Dynamic_Unix (%s)", m_sLibraryPath.c_str() );
-
- CHECKPOINT;
- pLib = dlopen( m_sLibraryPath.c_str(), RTLD_LOCAL | RTLD_NOW );
- CHECKPOINT;
-
- if( pLib == NULL )
- {
- CHECKPOINT;
- const char *error = dlerror();
- CString sError = ssprintf( "Error loading \"%s\": %s", m_sLibraryPath.c_str(), (error != NULL) ? error : "(none)" );
- LOG->Warn( sError );
- CHECKPOINT;
- return false;
- }
-
- CHECKPOINT;
- Module_Load = (LoadFn) dlsym( pLib, "Load" );
- Module_Unload = (UnloadFn) dlsym( pLib, "Unload" );
- Module_Update = (UpdateFn) dlsym( pLib, "Update" );
-
- Module_GetError = (GetErrorFn) dlsym( pLib, "GetError" );
- Module_GetModuleInfo = (GetLightsModuleInfoFn) dlsym( pLib, "GetModuleInfo" );
- CHECKPOINT;
-
- if( !Module_Load || !Module_Unload || !Module_Update || !Module_GetModuleInfo )
- {
- #define PRINT_POS(blah) LOG->Debug( "%s: %p", #blah, blah )
-
- PRINT_POS( Module_Load );
- PRINT_POS( Module_Unload );
- PRINT_POS( Module_Update );
- PRINT_POS( Module_GetError );
- PRINT_POS( Module_GetModuleInfo );
-
- CHECKPOINT;
- LOG->Warn( "Necessary module functions are missing. Cannot load." );
- CHECKPOINT;
- dlclose( pLib );
- return false;
- }
- CHECKPOINT;
-
- /* once the low-level operations have been completed,
- * start processing at the abstracted driver level. */
- return LightsDriver_Dynamic::LoadInternal();
-}
+++ /dev/null
-#ifndef LIGHTS_DRIVER_DYNAMIC_UNIX_H
-#define LIGHTS_DRIVER_DYNAMIC_UNIX_H
-
-#include "LightsDriver_Dynamic.h"
-
-class LightsDriver_Dynamic_Unix: public LightsDriver_Dynamic
-{
-public:
- LightsDriver_Dynamic_Unix( const CString &sLibPath ) : LightsDriver_Dynamic( sLibPath ) { }
- bool Load();
-
-private:
- void *pLib;
-};
-
-#endif // LIGHTS_DRIVER_DYNAMIC_UNIX_H