mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 07:12:02 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
Conflicts: src/sdl/iwadpicker_cocoa.mm
This commit is contained in:
commit
a7a2d55695
61 changed files with 11883 additions and 482 deletions
|
@ -28,6 +28,8 @@ endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||||
|
|
||||||
option( DYN_FLUIDSYNTH "Dynamically load fluidsynth" ON )
|
option( DYN_FLUIDSYNTH "Dynamically load fluidsynth" ON )
|
||||||
|
|
||||||
|
option( OSX_COCOA_BACKEND "Use native Cocoa backend instead of SDL" ON )
|
||||||
|
|
||||||
if( CMAKE_SIZEOF_VOID_P MATCHES "8" )
|
if( CMAKE_SIZEOF_VOID_P MATCHES "8" )
|
||||||
set( X64 64 )
|
set( X64 64 )
|
||||||
endif( CMAKE_SIZEOF_VOID_P MATCHES "8" )
|
endif( CMAKE_SIZEOF_VOID_P MATCHES "8" )
|
||||||
|
@ -213,7 +215,9 @@ else( WIN32 )
|
||||||
if( NOT SDL_FOUND )
|
if( NOT SDL_FOUND )
|
||||||
message( SEND_ERROR "SDL is required for building." )
|
message( SEND_ERROR "SDL is required for building." )
|
||||||
endif( NOT SDL_FOUND )
|
endif( NOT SDL_FOUND )
|
||||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} "${SDL_LIBRARY}" )
|
if( NOT APPLE OR NOT OSX_COCOA_BACKEND )
|
||||||
|
set( ZDOOM_LIBS ${ZDOOM_LIBS} "${SDL_LIBRARY}" )
|
||||||
|
endif( NOT APPLE OR NOT OSX_COCOA_BACKEND )
|
||||||
include_directories( "${SDL_INCLUDE_DIR}" )
|
include_directories( "${SDL_INCLUDE_DIR}" )
|
||||||
|
|
||||||
find_path( FPU_CONTROL_DIR fpu_control.h )
|
find_path( FPU_CONTROL_DIR fpu_control.h )
|
||||||
|
@ -375,19 +379,19 @@ if( NOT NO_ASM )
|
||||||
set( ASM_FLAGS -f win32 -DWIN32 -i${CMAKE_CURRENT_SOURCE_DIR}/ )
|
set( ASM_FLAGS -f win32 -DWIN32 -i${CMAKE_CURRENT_SOURCE_DIR}/ )
|
||||||
endif( X64 )
|
endif( X64 )
|
||||||
endif( UNIX )
|
endif( UNIX )
|
||||||
if( WIN32 )
|
if( WIN32 AND NOT X64 )
|
||||||
set( FIXRTEXT fixrtext )
|
set( FIXRTEXT fixrtext )
|
||||||
else( WIN32 )
|
else( WIN32 AND NOT X64 )
|
||||||
set( FIXRTEXT "" )
|
set( FIXRTEXT "" )
|
||||||
endif( WIN32 )
|
endif( WIN32 AND NOT X64 )
|
||||||
message( STATUS "Selected assembler: ${ASSEMBLER}" )
|
message( STATUS "Selected assembler: ${ASSEMBLER}" )
|
||||||
MACRO( ADD_ASM_FILE indir infile )
|
MACRO( ADD_ASM_FILE indir infile )
|
||||||
set( ASM_OUTPUT_${infile} "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/zdoom.dir/${indir}/${infile}${ASM_OUTPUT_EXTENSION}" )
|
set( ASM_OUTPUT_${infile} "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/zdoom.dir/${indir}/${infile}${ASM_OUTPUT_EXTENSION}" )
|
||||||
if( WIN32 )
|
if( WIN32 AND NOT X64 )
|
||||||
set( FIXRTEXT_${infile} COMMAND ${FIXRTEXT} "${ASM_OUTPUT_${infile}}" )
|
set( FIXRTEXT_${infile} COMMAND ${FIXRTEXT} "${ASM_OUTPUT_${infile}}" )
|
||||||
else( WIN32 )
|
else( WIN32 AND NOT X64 )
|
||||||
set( FIXRTEXT_${infile} COMMAND "" )
|
set( FIXRTEXT_${infile} COMMAND "" )
|
||||||
endif( WIN32 )
|
endif( WIN32 AND NOT X64 )
|
||||||
add_custom_command( OUTPUT ${ASM_OUTPUT_${infile}}
|
add_custom_command( OUTPUT ${ASM_OUTPUT_${infile}}
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/zdoom.dir/${indir}
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/zdoom.dir/${indir}
|
||||||
COMMAND ${ASSEMBLER} ${ASM_FLAGS} -o"${ASM_OUTPUT_${infile}}" "${CMAKE_CURRENT_SOURCE_DIR}/${indir}/${infile}${ASM_SOURCE_EXTENSION}"
|
COMMAND ${ASSEMBLER} ${ASM_FLAGS} -o"${ASM_OUTPUT_${infile}}" "${CMAKE_CURRENT_SOURCE_DIR}/${indir}/${infile}${ASM_SOURCE_EXTENSION}"
|
||||||
|
@ -446,9 +450,10 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||||
endif( PROFILE )
|
endif( PROFILE )
|
||||||
|
|
||||||
set( REL_CXX_FLAGS "-fno-rtti" )
|
set( REL_CXX_FLAGS "-fno-rtti" )
|
||||||
if( NOT PROFILE )
|
if( NOT PROFILE AND NOT APPLE )
|
||||||
|
# On OS X frame pointers are required for exception handling, at least with Clang
|
||||||
set( REL_CXX_FLAGS "${REL_CXX_FLAGS} -fomit-frame-pointer" )
|
set( REL_CXX_FLAGS "${REL_CXX_FLAGS} -fomit-frame-pointer" )
|
||||||
endif( NOT PROFILE )
|
endif( NOT PROFILE AND NOT APPLE )
|
||||||
set( CMAKE_CXX_FLAGS_RELEASE "${REL_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}" )
|
set( CMAKE_CXX_FLAGS_RELEASE "${REL_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}" )
|
||||||
set( CMAKE_CXX_FLAGS_MINSIZEREL "${REL_CXX_FLAGS} ${CMAKE_CXX_FLAGS_MINSIZEREL}" )
|
set( CMAKE_CXX_FLAGS_MINSIZEREL "${REL_CXX_FLAGS} ${CMAKE_CXX_FLAGS_MINSIZEREL}" )
|
||||||
set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${REL_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" )
|
set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${REL_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" )
|
||||||
|
@ -579,22 +584,53 @@ set( PLAT_WIN32_SOURCES
|
||||||
win32/st_start.cpp
|
win32/st_start.cpp
|
||||||
win32/win32gliface.cpp
|
win32/win32gliface.cpp
|
||||||
win32/win32video.cpp )
|
win32/win32video.cpp )
|
||||||
set( PLAT_SDL_SOURCES
|
set( PLAT_SDL_SYSTEM_SOURCES
|
||||||
sdl/crashcatcher.c
|
sdl/crashcatcher.c
|
||||||
sdl/hardware.cpp
|
sdl/hardware.cpp
|
||||||
sdl/i_cd.cpp
|
sdl/i_cd.cpp
|
||||||
sdl/i_input.cpp
|
|
||||||
sdl/i_joystick.cpp
|
|
||||||
sdl/i_main.cpp
|
sdl/i_main.cpp
|
||||||
sdl/i_movie.cpp
|
sdl/i_movie.cpp
|
||||||
sdl/i_system.cpp
|
sdl/i_system.cpp
|
||||||
sdl/sdlvideo.cpp
|
sdl/sdlvideo.cpp
|
||||||
sdl/sdlglvideo.cpp
|
sdl/sdlglvideo.cpp
|
||||||
sdl/st_start.cpp )
|
sdl/st_start.cpp )
|
||||||
|
set( PLAT_SDL_SPECIAL_SOURCES
|
||||||
|
sdl/i_gui.cpp
|
||||||
|
sdl/i_input.cpp
|
||||||
|
sdl/i_joystick.cpp
|
||||||
|
sdl/i_timer.cpp )
|
||||||
set( PLAT_MAC_SOURCES
|
set( PLAT_MAC_SOURCES
|
||||||
sdl/SDLMain.m
|
|
||||||
sdl/iwadpicker_cocoa.mm
|
sdl/iwadpicker_cocoa.mm
|
||||||
sdl/i_system_cocoa.mm )
|
sdl/i_system_cocoa.mm )
|
||||||
|
set( PLAT_COCOA_SOURCES
|
||||||
|
cocoa/HID_Config_Utilities.c
|
||||||
|
cocoa/HID_Error_Handler.c
|
||||||
|
cocoa/HID_Name_Lookup.c
|
||||||
|
cocoa/HID_Queue_Utilities.c
|
||||||
|
cocoa/HID_Utilities.c
|
||||||
|
cocoa/IOHIDDevice_.c
|
||||||
|
cocoa/IOHIDElement_.c
|
||||||
|
cocoa/ImmrHIDUtilAddOn.c
|
||||||
|
cocoa/i_backend_cocoa.mm
|
||||||
|
cocoa/i_joystick.cpp
|
||||||
|
cocoa/i_timer.cpp
|
||||||
|
cocoa/zdoom.icns )
|
||||||
|
|
||||||
|
if( APPLE )
|
||||||
|
set( PLAT_SDL_SOURCES ${PLAT_SDL_SYSTEM_SOURCES} "${FMOD_LIBRARY}" )
|
||||||
|
|
||||||
|
if( OSX_COCOA_BACKEND )
|
||||||
|
set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} ${PLAT_COCOA_SOURCES} )
|
||||||
|
else( OSX_COCOA_BACKEND )
|
||||||
|
set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} ${PLAT_SDL_SPECIAL_SOURCES} sdl/SDLMain.m )
|
||||||
|
endif( OSX_COCOA_BACKEND )
|
||||||
|
|
||||||
|
set_source_files_properties( cocoa/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources )
|
||||||
|
set_source_files_properties( "${FMOD_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks )
|
||||||
|
else( APPLE )
|
||||||
|
set( PLAT_SDL_SOURCES ${PLAT_SDL_SYSTEM_SOURCES} ${PLAT_SDL_SPECIAL_SOURCES} )
|
||||||
|
endif( APPLE )
|
||||||
|
|
||||||
if( WIN32 )
|
if( WIN32 )
|
||||||
set( SYSTEM_SOURCES_DIR win32 )
|
set( SYSTEM_SOURCES_DIR win32 )
|
||||||
set( SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} )
|
set( SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} )
|
||||||
|
@ -810,7 +846,7 @@ set( NOT_COMPILED_SOURCE_FILES
|
||||||
asm_x86_64/tmap3.s
|
asm_x86_64/tmap3.s
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable( zdoom WIN32
|
add_executable( zdoom WIN32 MACOSX_BUNDLE
|
||||||
${HEADER_FILES}
|
${HEADER_FILES}
|
||||||
${NOT_COMPILED_SOURCE_FILES}
|
${NOT_COMPILED_SOURCE_FILES}
|
||||||
__autostart.cpp
|
__autostart.cpp
|
||||||
|
@ -1087,6 +1123,7 @@ add_executable( zdoom WIN32
|
||||||
oplsynth/opl_mus_player.cpp
|
oplsynth/opl_mus_player.cpp
|
||||||
oplsynth/dosbox/opl.cpp
|
oplsynth/dosbox/opl.cpp
|
||||||
oplsynth/OPL3.cpp
|
oplsynth/OPL3.cpp
|
||||||
|
oplsynth/nukedopl3.cpp
|
||||||
resourcefiles/ancientzip.cpp
|
resourcefiles/ancientzip.cpp
|
||||||
resourcefiles/file_7z.cpp
|
resourcefiles/file_7z.cpp
|
||||||
resourcefiles/file_grp.cpp
|
resourcefiles/file_grp.cpp
|
||||||
|
@ -1259,6 +1296,25 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||||
endif( SSE_MATTERS )
|
endif( SSE_MATTERS )
|
||||||
endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||||
|
|
||||||
|
if( APPLE )
|
||||||
|
set_target_properties(zdoom PROPERTIES
|
||||||
|
LINK_FLAGS "-framework Carbon -framework Cocoa -framework IOKit -framework OpenGL"
|
||||||
|
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/cocoa/zdoom-info.plist" )
|
||||||
|
|
||||||
|
# Fix fmod link so that it can be found in the app bundle.
|
||||||
|
find_program( OTOOL otool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin" )
|
||||||
|
find_program( INSTALL_NAME_TOOL install_name_tool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin" )
|
||||||
|
execute_process( COMMAND "${OTOOL}" -L "${FMOD_LIBRARY}"
|
||||||
|
COMMAND grep "libfmodex.dylib (compat"
|
||||||
|
COMMAND head -n1
|
||||||
|
COMMAND awk "{print $1}"
|
||||||
|
OUTPUT_VARIABLE FMOD_LINK
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||||
|
add_custom_command( TARGET zdoom POST_BUILD
|
||||||
|
COMMAND "${INSTALL_NAME_TOOL}" -change "${FMOD_LINK}" @executable_path/../Frameworks/libfmodex.dylib "$<TARGET_FILE:zdoom>"
|
||||||
|
COMMENT "Relinking FMOD Ex" )
|
||||||
|
endif( APPLE )
|
||||||
|
|
||||||
source_group("Assembly Files\\ia32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/asm_ia32/.+")
|
source_group("Assembly Files\\ia32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/asm_ia32/.+")
|
||||||
source_group("Assembly Files\\x86_64" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/asm_x86_64/.+")
|
source_group("Assembly Files\\x86_64" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/asm_x86_64/.+")
|
||||||
source_group("Audio Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/.+")
|
source_group("Audio Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/.+")
|
||||||
|
@ -1266,6 +1322,7 @@ source_group("Audio Files\\OPL Synth" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURC
|
||||||
source_group("Audio Files\\OPL Synth\\DOSBox" FILES oplsynth/dosbox/opl.cpp oplsynth/dosbox/opl.h)
|
source_group("Audio Files\\OPL Synth\\DOSBox" FILES oplsynth/dosbox/opl.cpp oplsynth/dosbox/opl.h)
|
||||||
source_group("Audio Files\\Timidity\\Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.h$")
|
source_group("Audio Files\\Timidity\\Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.h$")
|
||||||
source_group("Audio Files\\Timidity\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.cpp$")
|
source_group("Audio Files\\Timidity\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.cpp$")
|
||||||
|
source_group("Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/cocoa/.+")
|
||||||
source_group("Decorate++" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/thingdef/.+")
|
source_group("Decorate++" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/thingdef/.+")
|
||||||
source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fragglescript/.+")
|
source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fragglescript/.+")
|
||||||
source_group("Games\\Doom Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_doom/.+")
|
source_group("Games\\Doom Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_doom/.+")
|
||||||
|
|
|
@ -971,6 +971,7 @@ public:
|
||||||
FNameNoInit DamageType;
|
FNameNoInit DamageType;
|
||||||
FNameNoInit DamageTypeReceived;
|
FNameNoInit DamageTypeReceived;
|
||||||
fixed_t DamageFactor;
|
fixed_t DamageFactor;
|
||||||
|
fixed_t DamageMultiply;
|
||||||
|
|
||||||
FNameNoInit PainType;
|
FNameNoInit PainType;
|
||||||
FNameNoInit DeathType;
|
FNameNoInit DeathType;
|
||||||
|
|
|
@ -24,12 +24,14 @@ IMPLEMENT_POINTY_CLASS(DBot)
|
||||||
END_POINTERS
|
END_POINTERS
|
||||||
|
|
||||||
DBot::DBot ()
|
DBot::DBot ()
|
||||||
|
: DThinker(STAT_BOT)
|
||||||
{
|
{
|
||||||
Clear ();
|
Clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBot::Clear ()
|
void DBot::Clear ()
|
||||||
{
|
{
|
||||||
|
player = NULL;
|
||||||
angle = 0;
|
angle = 0;
|
||||||
dest = NULL;
|
dest = NULL;
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
|
@ -64,6 +66,10 @@ void DBot::Serialize (FArchive &arc)
|
||||||
arc << savedyaw
|
arc << savedyaw
|
||||||
<< savedpitch;
|
<< savedpitch;
|
||||||
}
|
}
|
||||||
|
else if (SaveVersion >= 4516)
|
||||||
|
{
|
||||||
|
arc << player;
|
||||||
|
}
|
||||||
|
|
||||||
arc << angle
|
arc << angle
|
||||||
<< dest
|
<< dest
|
||||||
|
@ -88,6 +94,22 @@ void DBot::Serialize (FArchive &arc)
|
||||||
<< oldy;
|
<< oldy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DBot::Tick ()
|
||||||
|
{
|
||||||
|
Super::Tick ();
|
||||||
|
|
||||||
|
if (player->mo == NULL || bglobal.freeze)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BotThinkCycles.Clock();
|
||||||
|
bglobal.m_Thinking = true;
|
||||||
|
bglobal.Think (player->mo, &netcmds[player - players][((gametic + 1)/ticdup)%BACKUPTICS]);
|
||||||
|
bglobal.m_Thinking = false;
|
||||||
|
BotThinkCycles.Unclock();
|
||||||
|
}
|
||||||
|
|
||||||
CVAR (Int, bot_next_color, 11, 0)
|
CVAR (Int, bot_next_color, 11, 0)
|
||||||
CVAR (Bool, bot_observer, false, 0)
|
CVAR (Bool, bot_observer, false, 0)
|
||||||
|
|
||||||
|
|
19
src/b_bot.h
19
src/b_bot.h
|
@ -14,6 +14,7 @@
|
||||||
#include "d_ticcmd.h"
|
#include "d_ticcmd.h"
|
||||||
#include "r_defs.h"
|
#include "r_defs.h"
|
||||||
#include "a_pickups.h"
|
#include "a_pickups.h"
|
||||||
|
#include "stats.h"
|
||||||
|
|
||||||
#define FORWARDWALK 0x1900
|
#define FORWARDWALK 0x1900
|
||||||
#define FORWARDRUN 0x3200
|
#define FORWARDRUN 0x3200
|
||||||
|
@ -89,20 +90,22 @@ public:
|
||||||
void ClearPlayer (int playernum, bool keepTeam);
|
void ClearPlayer (int playernum, bool keepTeam);
|
||||||
|
|
||||||
//(B_Game.c)
|
//(B_Game.c)
|
||||||
void Main (int buf);
|
void Main ();
|
||||||
void Init ();
|
void Init ();
|
||||||
void End();
|
void End();
|
||||||
bool SpawnBot (const char *name, int color = NOCOLOR);
|
bool SpawnBot (const char *name, int color = NOCOLOR);
|
||||||
bool LoadBots ();
|
|
||||||
void ForgetBots ();
|
|
||||||
void TryAddBot (BYTE **stream, int player);
|
void TryAddBot (BYTE **stream, int player);
|
||||||
void RemoveAllBots (bool fromlist);
|
void RemoveAllBots (bool fromlist);
|
||||||
void DestroyAllBots ();
|
bool LoadBots ();
|
||||||
|
void ForgetBots ();
|
||||||
|
|
||||||
//(B_Func.c)
|
//(B_Func.c)
|
||||||
bool Check_LOS (AActor *mobj1, AActor *mobj2, angle_t vangle);
|
bool Check_LOS (AActor *mobj1, AActor *mobj2, angle_t vangle);
|
||||||
|
void StartTravel ();
|
||||||
|
void FinishTravel ();
|
||||||
|
|
||||||
//(B_Think.c)
|
//(B_Think.c)
|
||||||
|
void Think (AActor *actor, ticcmd_t *cmd);
|
||||||
void WhatToGet (AActor *actor, AActor *item);
|
void WhatToGet (AActor *actor, AActor *item);
|
||||||
|
|
||||||
//(B_move.c)
|
//(B_move.c)
|
||||||
|
@ -144,7 +147,6 @@ private:
|
||||||
bool SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm);
|
bool SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm);
|
||||||
|
|
||||||
//(B_Think.c)
|
//(B_Think.c)
|
||||||
void Think (AActor *actor, ticcmd_t *cmd);
|
|
||||||
void ThinkForMove (AActor *actor, ticcmd_t *cmd);
|
void ThinkForMove (AActor *actor, ticcmd_t *cmd);
|
||||||
void Set_enemy (AActor *actor);
|
void Set_enemy (AActor *actor);
|
||||||
|
|
||||||
|
@ -155,16 +157,18 @@ protected:
|
||||||
bool observer; //Consoleplayer is observer.
|
bool observer; //Consoleplayer is observer.
|
||||||
};
|
};
|
||||||
|
|
||||||
class DBot : public DObject
|
class DBot : public DThinker
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(DBot,DObject)
|
DECLARE_CLASS(DBot,DThinker)
|
||||||
HAS_OBJECT_POINTERS
|
HAS_OBJECT_POINTERS
|
||||||
public:
|
public:
|
||||||
DBot ();
|
DBot ();
|
||||||
|
|
||||||
void Clear ();
|
void Clear ();
|
||||||
void Serialize (FArchive &arc);
|
void Serialize (FArchive &arc);
|
||||||
|
void Tick ();
|
||||||
|
|
||||||
|
player_t *player;
|
||||||
angle_t angle; // The wanted angle that the bot try to get every tic.
|
angle_t angle; // The wanted angle that the bot try to get every tic.
|
||||||
// (used to get a smooth view movement)
|
// (used to get a smooth view movement)
|
||||||
TObjPtr<AActor> dest; // Move Destination.
|
TObjPtr<AActor> dest; // Move Destination.
|
||||||
|
@ -205,6 +209,7 @@ public:
|
||||||
|
|
||||||
//Externs
|
//Externs
|
||||||
extern FCajunMaster bglobal;
|
extern FCajunMaster bglobal;
|
||||||
|
extern cycle_t BotThinkCycles, BotSupportCycles;
|
||||||
|
|
||||||
EXTERN_CVAR (Float, bot_flag_return_time)
|
EXTERN_CVAR (Float, bot_flag_return_time)
|
||||||
EXTERN_CVAR (Int, bot_next_color)
|
EXTERN_CVAR (Int, bot_next_color)
|
||||||
|
|
|
@ -402,7 +402,7 @@ AActor *FCajunMaster::Find_enemy (AActor *bot)
|
||||||
&& bot != client->mo)
|
&& bot != client->mo)
|
||||||
{
|
{
|
||||||
if (Check_LOS (bot, client->mo, vangle)) //Here's a strange one, when bot is standing still, the P_CheckSight within Check_LOS almost always returns false. tought it should be the same checksight as below but.. (below works) something must be fuckin wierd screded up.
|
if (Check_LOS (bot, client->mo, vangle)) //Here's a strange one, when bot is standing still, the P_CheckSight within Check_LOS almost always returns false. tought it should be the same checksight as below but.. (below works) something must be fuckin wierd screded up.
|
||||||
//if(P_CheckSight( bot, players[count].mo))
|
//if(P_CheckSight(bot, players[count].mo))
|
||||||
{
|
{
|
||||||
temp = P_AproxDistance (client->mo->x - bot->x,
|
temp = P_AproxDistance (client->mo->x - bot->x,
|
||||||
client->mo->y - bot->y);
|
client->mo->y - bot->y);
|
||||||
|
@ -552,3 +552,25 @@ bool FCajunMaster::SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FChec
|
||||||
actor->flags = savedFlags;
|
actor->flags = savedFlags;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FCajunMaster::StartTravel ()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||||
|
{
|
||||||
|
if (players[i].Bot != NULL)
|
||||||
|
{
|
||||||
|
players[i].Bot->ChangeStatNum (STAT_TRAVELLING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCajunMaster::FinishTravel ()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||||
|
{
|
||||||
|
if (players[i].Bot != NULL)
|
||||||
|
{
|
||||||
|
players[i].Bot->ChangeStatNum (STAT_BOT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
112
src/b_game.cpp
112
src/b_game.cpp
|
@ -94,71 +94,46 @@ FCajunMaster::~FCajunMaster()
|
||||||
ForgetBots();
|
ForgetBots();
|
||||||
}
|
}
|
||||||
|
|
||||||
//This function is called every tick (from g_game.c),
|
//This function is called every tick (from g_game.c).
|
||||||
//send bots into thinking (+more).
|
void FCajunMaster::Main ()
|
||||||
void FCajunMaster::Main (int buf)
|
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
BotThinkCycles.Reset();
|
BotThinkCycles.Reset();
|
||||||
|
|
||||||
if (demoplayback)
|
if (demoplayback || gamestate != GS_LEVEL || consoleplayer != Net_Arbitrator)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (gamestate != GS_LEVEL)
|
//Add new bots?
|
||||||
return;
|
if (wanted_botnum > botnum && !freeze)
|
||||||
|
|
||||||
m_Thinking = true;
|
|
||||||
|
|
||||||
//Think for bots.
|
|
||||||
if (botnum)
|
|
||||||
{
|
{
|
||||||
BotThinkCycles.Clock();
|
if (t_join == ((wanted_botnum - botnum) * SPAWN_DELAY))
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
|
||||||
{
|
{
|
||||||
if (playeringame[i] && players[i].mo && !freeze && players[i].Bot != NULL)
|
if (!SpawnBot (getspawned[spawn_tries]))
|
||||||
Think (players[i].mo, &netcmds[i][buf]);
|
wanted_botnum--;
|
||||||
|
spawn_tries++;
|
||||||
}
|
}
|
||||||
BotThinkCycles.Unclock();
|
|
||||||
|
t_join--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consoleplayer == Net_Arbitrator)
|
//Check if player should go observer. Or un observe
|
||||||
|
if (bot_observer && !observer && !netgame)
|
||||||
{
|
{
|
||||||
//Add new bots?
|
Printf ("%s is now observer\n", players[consoleplayer].userinfo.GetName());
|
||||||
if (wanted_botnum > botnum && !freeze)
|
observer = true;
|
||||||
{
|
players[consoleplayer].mo->UnlinkFromWorld ();
|
||||||
if (t_join == ((wanted_botnum - botnum) * SPAWN_DELAY))
|
players[consoleplayer].mo->flags = MF_DROPOFF|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOTDMATCH|MF_NOGRAVITY|MF_FRIENDLY;
|
||||||
{
|
players[consoleplayer].mo->flags2 |= MF2_FLY;
|
||||||
if (!SpawnBot (getspawned[spawn_tries]))
|
players[consoleplayer].mo->LinkToWorld ();
|
||||||
wanted_botnum--;
|
}
|
||||||
spawn_tries++;
|
else if (!bot_observer && observer && !netgame) //Go back
|
||||||
}
|
{
|
||||||
|
Printf ("%s returned to the fray\n", players[consoleplayer].userinfo.GetName());
|
||||||
t_join--;
|
observer = false;
|
||||||
}
|
players[consoleplayer].mo->UnlinkFromWorld ();
|
||||||
|
players[consoleplayer].mo->flags = MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY;
|
||||||
//Check if player should go observer. Or un observe
|
players[consoleplayer].mo->flags2 &= ~MF2_FLY;
|
||||||
if (bot_observer && !observer && !netgame)
|
players[consoleplayer].mo->LinkToWorld ();
|
||||||
{
|
|
||||||
Printf ("%s is now observer\n", players[consoleplayer].userinfo.GetName());
|
|
||||||
observer = true;
|
|
||||||
players[consoleplayer].mo->UnlinkFromWorld ();
|
|
||||||
players[consoleplayer].mo->flags = MF_DROPOFF|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOTDMATCH|MF_NOGRAVITY|MF_FRIENDLY;
|
|
||||||
players[consoleplayer].mo->flags2 |= MF2_FLY;
|
|
||||||
players[consoleplayer].mo->LinkToWorld ();
|
|
||||||
}
|
|
||||||
else if (!bot_observer && observer && !netgame) //Go back
|
|
||||||
{
|
|
||||||
Printf ("%s returned to the fray\n", players[consoleplayer].userinfo.GetName());
|
|
||||||
observer = false;
|
|
||||||
players[consoleplayer].mo->UnlinkFromWorld ();
|
|
||||||
players[consoleplayer].mo->flags = MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY;
|
|
||||||
players[consoleplayer].mo->flags2 &= ~MF2_FLY;
|
|
||||||
players[consoleplayer].mo->LinkToWorld ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Thinking = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCajunMaster::Init ()
|
void FCajunMaster::Init ()
|
||||||
|
@ -199,18 +174,13 @@ void FCajunMaster::End ()
|
||||||
|
|
||||||
//Arrange wanted botnum and their names, so they can be spawned next level.
|
//Arrange wanted botnum and their names, so they can be spawned next level.
|
||||||
getspawned.Clear();
|
getspawned.Clear();
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
|
||||||
{
|
|
||||||
if (playeringame[i] && players[i].Bot != NULL)
|
|
||||||
{
|
|
||||||
if (deathmatch)
|
|
||||||
{
|
|
||||||
getspawned.Push(players[i].userinfo.GetName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (deathmatch)
|
if (deathmatch)
|
||||||
{
|
{
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
getspawned.Push(players[i].userinfo.GetName());
|
||||||
|
}
|
||||||
|
|
||||||
wanted_botnum = botnum;
|
wanted_botnum = botnum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,7 +370,7 @@ bool FCajunMaster::DoAddBot (BYTE *info, botskill_t skill)
|
||||||
|
|
||||||
multiplayer = true; //Prevents cheating and so on; emulates real netgame (almost).
|
multiplayer = true; //Prevents cheating and so on; emulates real netgame (almost).
|
||||||
players[bnum].Bot = new DBot;
|
players[bnum].Bot = new DBot;
|
||||||
GC::WriteBarrier (players[bnum].Bot);
|
players[bnum].Bot->player = &players[bnum];
|
||||||
players[bnum].Bot->skill = skill;
|
players[bnum].Bot->skill = skill;
|
||||||
playeringame[bnum] = true;
|
playeringame[bnum] = true;
|
||||||
players[bnum].mo = NULL;
|
players[bnum].mo = NULL;
|
||||||
|
@ -426,7 +396,7 @@ void FCajunMaster::RemoveAllBots (bool fromlist)
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
for (i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
if (playeringame[i] && players[i].Bot != NULL)
|
if (players[i].Bot != NULL)
|
||||||
{
|
{
|
||||||
// If a player is looking through this bot's eyes, make him
|
// If a player is looking through this bot's eyes, make him
|
||||||
// look through his own eyes instead.
|
// look through his own eyes instead.
|
||||||
|
@ -456,18 +426,6 @@ void FCajunMaster::RemoveAllBots (bool fromlist)
|
||||||
botnum = 0;
|
botnum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FCajunMaster::DestroyAllBots ()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
|
||||||
{
|
|
||||||
if (players[i].Bot != NULL)
|
|
||||||
{
|
|
||||||
players[i].Bot->Destroy ();
|
|
||||||
players[i].Bot = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//------------------
|
//------------------
|
||||||
//Reads data for bot from
|
//Reads data for bot from
|
||||||
|
|
|
@ -230,7 +230,11 @@ const char *KeyNames[NUM_KEYS] =
|
||||||
NULL, NULL, NULL, NULL, NULL, "pause", NULL, "home", //C0
|
NULL, NULL, NULL, NULL, NULL, "pause", NULL, "home", //C0
|
||||||
"uparrow", "pgup", NULL, "leftarrow",NULL, "rightarrow",NULL, "end", //C8
|
"uparrow", "pgup", NULL, "leftarrow",NULL, "rightarrow",NULL, "end", //C8
|
||||||
"downarrow","pgdn", "ins", "del", NULL, NULL, NULL, NULL, //D0
|
"downarrow","pgdn", "ins", "del", NULL, NULL, NULL, NULL, //D0
|
||||||
|
#ifdef __APPLE__
|
||||||
|
NULL, NULL, NULL, "command", NULL, "apps", "power", "sleep", //D8
|
||||||
|
#else // !__APPLE__
|
||||||
NULL, NULL, NULL, "lwin", "rwin", "apps", "power", "sleep", //D8
|
NULL, NULL, NULL, "lwin", "rwin", "apps", "power", "sleep", //D8
|
||||||
|
#endif // __APPLE__
|
||||||
NULL, NULL, NULL, "wake", NULL, "search", "favorites","refresh", //E0
|
NULL, NULL, NULL, "wake", NULL, "search", "favorites","refresh", //E0
|
||||||
"webstop", "webforward","webback", "mycomputer","mail", "mediaselect",NULL, NULL, //E8
|
"webstop", "webforward","webback", "mycomputer","mail", "mediaselect",NULL, NULL, //E8
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //F0
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //F0
|
||||||
|
|
|
@ -1426,7 +1426,11 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len)
|
||||||
case 'V':
|
case 'V':
|
||||||
TabbedLast = false;
|
TabbedLast = false;
|
||||||
TabbedList = false;
|
TabbedList = false;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (ev->data3 & GKM_META)
|
||||||
|
#else // !__APPLE__
|
||||||
if (ev->data3 & GKM_CTRL)
|
if (ev->data3 & GKM_CTRL)
|
||||||
|
#endif // __APPLE__
|
||||||
{
|
{
|
||||||
if (data1 == 'C')
|
if (data1 == 'C')
|
||||||
{ // copy to clipboard
|
{ // copy to clipboard
|
||||||
|
|
926
src/cocoa/HID_Config_Utilities.c
Normal file
926
src/cocoa/HID_Config_Utilities.c
Normal file
|
@ -0,0 +1,926 @@
|
||||||
|
// File: HID_Config_Utilities.c
|
||||||
|
// Abstract: Implementation of the HID configuration utilities
|
||||||
|
// Version: 2.0
|
||||||
|
//
|
||||||
|
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||||
|
// Inc. ("Apple") in consideration of your agreement to the following
|
||||||
|
// terms, and your use, installation, modification or redistribution of
|
||||||
|
// this Apple software constitutes acceptance of these terms. If you do
|
||||||
|
// not agree with these terms, please do not use, install, modify or
|
||||||
|
// redistribute this Apple software.
|
||||||
|
//
|
||||||
|
// In consideration of your agreement to abide by the following terms, and
|
||||||
|
// subject to these terms, Apple grants you a personal, non-exclusive
|
||||||
|
// license, under Apple's copyrights in this original Apple software (the
|
||||||
|
// "Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||||
|
// Software, with or without modifications, in source and/or binary forms;
|
||||||
|
// provided that if you redistribute the Apple Software in its entirety and
|
||||||
|
// without modifications, you must retain this notice and the following
|
||||||
|
// text and disclaimers in all such redistributions of the Apple Software.
|
||||||
|
// Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||||
|
// be used to endorse or promote products derived from the Apple Software
|
||||||
|
// without specific prior written permission from Apple. Except as
|
||||||
|
// expressly stated in this notice, no other rights or licenses, express or
|
||||||
|
// implied, are granted by Apple herein, including but not limited to any
|
||||||
|
// patent rights that may be infringed by your derivative works or by other
|
||||||
|
// works in which the Apple Software may be incorporated.
|
||||||
|
//
|
||||||
|
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||||
|
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||||
|
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||||
|
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
//
|
||||||
|
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||||
|
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||||
|
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||||
|
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||||
|
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//*****************************************************
|
||||||
|
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||||
|
|
||||||
|
#define LOG_SCORING 0
|
||||||
|
|
||||||
|
#include <stdlib.h> // malloc
|
||||||
|
#include <time.h> // clock
|
||||||
|
|
||||||
|
#include <AssertMacros.h>
|
||||||
|
|
||||||
|
#include "HID_Utilities_External.h"
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
|
||||||
|
// polls single device's elements for a change greater than kPercentMove. Times out after given time
|
||||||
|
// returns 1 and pointer to element if found
|
||||||
|
// returns 0 and NULL for both parameters if not found
|
||||||
|
|
||||||
|
unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout) {
|
||||||
|
if ( !inIOHIDDeviceRef ) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if ( 0 == HIDHaveDeviceList() ) { // if we do not have a device list
|
||||||
|
return (0); // return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean found = FALSE;
|
||||||
|
|
||||||
|
// build list of device and elements to save current values
|
||||||
|
int maxElements = HIDCountDeviceElements(inIOHIDDeviceRef, kHIDElementTypeInput);
|
||||||
|
int *saveValueArray = (int *) calloc( maxElements, sizeof(int) ); // 2D array to save values
|
||||||
|
|
||||||
|
// store initial values on first pass / compare to initial value on subsequent passes
|
||||||
|
Boolean first = TRUE;
|
||||||
|
|
||||||
|
// get all the elements from this device
|
||||||
|
CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements(inIOHIDDeviceRef, NULL, kIOHIDOptionsTypeNone);
|
||||||
|
// if that worked...
|
||||||
|
if ( elementCFArrayRef ) {
|
||||||
|
clock_t start = clock(), end;
|
||||||
|
|
||||||
|
// poll all devices and elements
|
||||||
|
while ( !found ) {
|
||||||
|
int currElementIndex = 0;
|
||||||
|
CFIndex idx, cnt = CFArrayGetCount(elementCFArrayRef);
|
||||||
|
for ( idx = 0; idx < cnt; idx++ ) {
|
||||||
|
*outIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx);
|
||||||
|
if ( !*outIOHIDElementRef ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// is this an input element?
|
||||||
|
IOHIDElementType type = IOHIDElementGetType(*outIOHIDElementRef);
|
||||||
|
|
||||||
|
switch ( type ) {
|
||||||
|
// these types are inputs
|
||||||
|
case kIOHIDElementTypeInput_Misc:
|
||||||
|
case kIOHIDElementTypeInput_Button:
|
||||||
|
case kIOHIDElementTypeInput_Axis:
|
||||||
|
case kIOHIDElementTypeInput_ScanCodes:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kIOHIDElementTypeOutput:
|
||||||
|
case kIOHIDElementTypeFeature:
|
||||||
|
case kIOHIDElementTypeCollection:
|
||||||
|
{
|
||||||
|
*outIOHIDElementRef = NULL; // these types are not ( Skip them )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} /* switch */
|
||||||
|
if ( !*outIOHIDElementRef ) {
|
||||||
|
continue; // skip this element
|
||||||
|
}
|
||||||
|
|
||||||
|
// get this elements current value
|
||||||
|
int value = 0; // default value is zero
|
||||||
|
IOHIDValueRef tIOHIDValueRef;
|
||||||
|
IOReturn ioReturn = IOHIDDeviceGetValue(inIOHIDDeviceRef, *outIOHIDElementRef, &tIOHIDValueRef);
|
||||||
|
if ( kIOReturnSuccess == ioReturn ) {
|
||||||
|
value = IOHIDValueGetScaledValue(tIOHIDValueRef, kIOHIDValueScaleTypePhysical);
|
||||||
|
}
|
||||||
|
if ( first ) {
|
||||||
|
saveValueArray[currElementIndex] = value;
|
||||||
|
} else {
|
||||||
|
CFIndex min = IOHIDElementGetLogicalMin(*outIOHIDElementRef);
|
||||||
|
CFIndex max = IOHIDElementGetLogicalMax(*outIOHIDElementRef);
|
||||||
|
|
||||||
|
int initialValue = saveValueArray[currElementIndex];
|
||||||
|
int delta = (float)(max - min) * kPercentMove * 0.01;
|
||||||
|
// is the new value within +/- delta of the initial value?
|
||||||
|
if ( ( (initialValue + delta) < value ) || ( (initialValue - delta) > value ) ) {
|
||||||
|
found = 1; // ( yes! ) mark as found
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // if ( first )
|
||||||
|
|
||||||
|
currElementIndex++; // bump element index
|
||||||
|
} // next idx
|
||||||
|
|
||||||
|
first = FALSE; // no longer the first pass
|
||||||
|
|
||||||
|
// are we done?
|
||||||
|
end = clock();
|
||||||
|
double secs = (double)(end - start) / CLOCKS_PER_SEC;
|
||||||
|
if ( secs > timeout ) {
|
||||||
|
break; // ( yes ) timeout
|
||||||
|
}
|
||||||
|
} // while ( !found )
|
||||||
|
|
||||||
|
CFRelease(elementCFArrayRef);
|
||||||
|
} // if ( elementCFArrayRef )
|
||||||
|
// return device and element moved
|
||||||
|
if ( found ) {
|
||||||
|
return (1);
|
||||||
|
} else {
|
||||||
|
*outIOHIDElementRef = NULL;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
} // HIDConfigureSingleDeviceAction
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDConfigureAction( outIOHIDDeviceRef, outIOHIDElementRef, inTimeout )
|
||||||
|
//
|
||||||
|
// Purpose: polls all devices and elements for a change greater than kPercentMove.
|
||||||
|
// Times out after given time returns 1 and pointer to device and element
|
||||||
|
// if found; returns 0 and NULL for both parameters if not found
|
||||||
|
//
|
||||||
|
// Inputs: outIOHIDDeviceRef - address where to store the device
|
||||||
|
// outIOHIDElementRef - address where to store the element
|
||||||
|
// inTimeout - the timeout
|
||||||
|
// Returns: Boolean - if successful
|
||||||
|
// outIOHIDDeviceRef - the device
|
||||||
|
// outIOHIDElementRef - the element
|
||||||
|
//
|
||||||
|
|
||||||
|
Boolean HIDConfigureAction(IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float inTimeout) {
|
||||||
|
// param error?
|
||||||
|
if ( !outIOHIDDeviceRef || !outIOHIDElementRef ) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if ( !gDeviceCFArrayRef ) { // if we do not have a device list
|
||||||
|
// and we can't build another list
|
||||||
|
if ( !HIDBuildDeviceList(0, 0) || !gDeviceCFArrayRef ) {
|
||||||
|
return (FALSE); // bail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDDeviceRef tIOHIDDeviceRef;
|
||||||
|
IOHIDElementRef tIOHIDElementRef;
|
||||||
|
|
||||||
|
// remember when we start; used to calculate timeout
|
||||||
|
clock_t start = clock(), end;
|
||||||
|
|
||||||
|
// determine the maximum number of elements
|
||||||
|
CFIndex maxElements = 0;
|
||||||
|
CFIndex devIndex, devCount = CFArrayGetCount(gDeviceCFArrayRef);
|
||||||
|
for ( devIndex = 0; devIndex < devCount; devIndex++ ) {
|
||||||
|
tIOHIDDeviceRef = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDeviceCFArrayRef, devIndex);
|
||||||
|
if ( !tIOHIDDeviceRef ) {
|
||||||
|
continue; // skip this one
|
||||||
|
}
|
||||||
|
|
||||||
|
CFIndex count = HIDCountDeviceElements(tIOHIDDeviceRef, kHIDElementTypeInput);
|
||||||
|
if ( count > maxElements ) {
|
||||||
|
maxElements = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate an array of int's in which to store devCount * maxElements values
|
||||||
|
double *saveValueArray = (double *) calloc( devCount * maxElements, sizeof(double) ); // clear 2D array to save values
|
||||||
|
|
||||||
|
// on first pass store initial values / compare current values to initial values on subsequent passes
|
||||||
|
Boolean found = FALSE, first = TRUE;
|
||||||
|
|
||||||
|
while ( !found ) {
|
||||||
|
double maxDeltaPercent = 0; // we want to find the one that moves the most ( percentage wise )
|
||||||
|
for ( devIndex = 0; devIndex < devCount; devIndex++ ) {
|
||||||
|
tIOHIDDeviceRef = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDeviceCFArrayRef, devIndex);
|
||||||
|
if ( !tIOHIDDeviceRef ) {
|
||||||
|
continue; // skip this one
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
long vendorID = IOHIDDevice_GetVendorID(tIOHIDDeviceRef);
|
||||||
|
long productID = IOHIDDevice_GetProductID(tIOHIDDeviceRef);
|
||||||
|
#endif
|
||||||
|
gElementCFArrayRef = IOHIDDeviceCopyMatchingElements(tIOHIDDeviceRef, NULL, kIOHIDOptionsTypeNone);
|
||||||
|
if ( gElementCFArrayRef ) {
|
||||||
|
CFIndex eleIndex, eleCount = CFArrayGetCount(gElementCFArrayRef);
|
||||||
|
for ( eleIndex = 0; eleIndex < eleCount; eleIndex++ ) {
|
||||||
|
tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(gElementCFArrayRef, eleIndex);
|
||||||
|
if ( !tIOHIDElementRef ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDElementType tIOHIDElementType = IOHIDElementGetType(tIOHIDElementRef);
|
||||||
|
// only care about inputs (no outputs or features)
|
||||||
|
if ( tIOHIDElementType <= kIOHIDElementTypeInput_ScanCodes ) {
|
||||||
|
if ( IOHIDElementIsArray(tIOHIDElementRef) ) {
|
||||||
|
//printf( "ARRAY!\n" );
|
||||||
|
continue; // skip array elements
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t usagePage = IOHIDElementGetUsagePage(tIOHIDElementRef);
|
||||||
|
uint32_t usage = IOHIDElementGetUsage(tIOHIDElementRef);
|
||||||
|
uint32_t reportCount = IOHIDElementGetReportCount(tIOHIDElementRef);
|
||||||
|
#ifdef DEBUG
|
||||||
|
if ( first ) {
|
||||||
|
IOHIDElementCookie cookie = IOHIDElementGetCookie(tIOHIDElementRef);
|
||||||
|
printf("%s, dev: {ref:%p, ven: 0x%08lX, pro: 0x%08lX}, ele: {ref:%p, cookie: %p, usage:%04lX:%08lX}\n",
|
||||||
|
__PRETTY_FUNCTION__,
|
||||||
|
tIOHIDDeviceRef,
|
||||||
|
vendorID,
|
||||||
|
productID,
|
||||||
|
tIOHIDElementRef,
|
||||||
|
cookie,
|
||||||
|
(long unsigned int) usagePage,
|
||||||
|
(long unsigned int) usage);
|
||||||
|
fflush(stdout);
|
||||||
|
if ( (0x054C == vendorID) && (0x0268 == productID) && (0x001E == (UInt32) cookie) ) {
|
||||||
|
//printf( "DING!\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#if 1 // work-around for IOHIDValueGetScaledValue crash (when element report count > 1)
|
||||||
|
if ( reportCount > 1 ) {
|
||||||
|
//printf( "REPORT!\n" );
|
||||||
|
continue; // skip reports
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// ignore PID elements and arrays
|
||||||
|
if ( (kHIDPage_PID != usagePage) && (((uint32_t)-1) != usage) ) {
|
||||||
|
// get this elements current value
|
||||||
|
double value = 0.0; // default value is zero
|
||||||
|
IOHIDValueRef tIOHIDValueRef;
|
||||||
|
IOReturn ioReturn = IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &tIOHIDValueRef);
|
||||||
|
if ( kIOReturnSuccess == ioReturn ) {
|
||||||
|
value = IOHIDValueGetScaledValue(tIOHIDValueRef, kIOHIDValueScaleTypePhysical);
|
||||||
|
}
|
||||||
|
if ( first ) {
|
||||||
|
saveValueArray[(devIndex * maxElements) + eleIndex] = value;
|
||||||
|
} else {
|
||||||
|
double initialValue = saveValueArray[(devIndex * maxElements) + eleIndex];
|
||||||
|
|
||||||
|
CFIndex valueMin = IOHIDElementGetPhysicalMin(tIOHIDElementRef);
|
||||||
|
CFIndex valueMax = IOHIDElementGetPhysicalMax(tIOHIDElementRef);
|
||||||
|
|
||||||
|
double deltaPercent = fabs( (initialValue - value) * 100.0 / (valueMax - valueMin) );
|
||||||
|
#if 0 // debug code useful to dump out value info for specific (vendorID, productID, usagePage and usage) device
|
||||||
|
if ( !first ) {
|
||||||
|
// Device: 0x13b6a0 = { Logitech Inc. - WingMan Force 3D, vendorID: 0x046D, productID: 0xC283,
|
||||||
|
// usage: 0x0001:0x0004, "Generic Desktop Joystick"
|
||||||
|
if ( (vendorID == 0x046D) && (productID == 0xC283) ) {
|
||||||
|
if ( (kHIDPage_GenericDesktop == usagePage) && (kHIDUsage_GD_Rz == usage) ) {
|
||||||
|
printf("initial: %6.2f, value: %6.2f, diff: %6.2f, delta percent: %6.2f!\n",
|
||||||
|
initialValue,
|
||||||
|
value,
|
||||||
|
fabs(initialValue - value),
|
||||||
|
deltaPercent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deltaPercent = 0.0;
|
||||||
|
#endif
|
||||||
|
if ( deltaPercent >= kPercentMove ) {
|
||||||
|
found = TRUE;
|
||||||
|
if ( deltaPercent > maxDeltaPercent ) {
|
||||||
|
maxDeltaPercent = deltaPercent;
|
||||||
|
|
||||||
|
*outIOHIDDeviceRef = tIOHIDDeviceRef;
|
||||||
|
*outIOHIDElementRef = tIOHIDElementRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // if first
|
||||||
|
|
||||||
|
} // if usage
|
||||||
|
|
||||||
|
} // if type
|
||||||
|
|
||||||
|
} // for elements...
|
||||||
|
|
||||||
|
CFRelease(gElementCFArrayRef);
|
||||||
|
gElementCFArrayRef = NULL;
|
||||||
|
} // if ( gElementCFArrayRef )
|
||||||
|
if ( found ) {
|
||||||
|
// HIDDumpElementInfo( tIOHIDElementRef );
|
||||||
|
break; // DONE!
|
||||||
|
}
|
||||||
|
} // for devices
|
||||||
|
|
||||||
|
first = FALSE; // no longer the first pass
|
||||||
|
|
||||||
|
// are we done?
|
||||||
|
end = clock();
|
||||||
|
double secs = (double)(end - start) / CLOCKS_PER_SEC;
|
||||||
|
if ( secs > inTimeout ) {
|
||||||
|
break; // ( yes ) timeout
|
||||||
|
}
|
||||||
|
} // while ( !found )
|
||||||
|
// return device and element moved
|
||||||
|
if ( !found ) {
|
||||||
|
*outIOHIDDeviceRef = NULL;
|
||||||
|
*outIOHIDElementRef = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (found);
|
||||||
|
} // HIDConfigureAction
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inIOHIDDeviceRef, inIOHIDElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: Save the device & element values into the specified key in the specified applications preferences
|
||||||
|
//
|
||||||
|
// Inputs: inKeyCFStringRef - the preference key
|
||||||
|
// inAppCFStringRef - the application identifier
|
||||||
|
// inIOHIDDeviceRef - the device
|
||||||
|
// inIOHIDElementRef - the element
|
||||||
|
// Returns: Boolean - if successful
|
||||||
|
//
|
||||||
|
|
||||||
|
Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef,
|
||||||
|
CFStringRef inAppCFStringRef,
|
||||||
|
IOHIDDeviceRef inIOHIDDeviceRef,
|
||||||
|
IOHIDElementRef inIOHIDElementRef) {
|
||||||
|
Boolean success = FALSE;
|
||||||
|
if ( inKeyCFStringRef && inAppCFStringRef && inIOHIDDeviceRef && inIOHIDElementRef ) {
|
||||||
|
long vendorID = IOHIDDevice_GetVendorID(inIOHIDDeviceRef);
|
||||||
|
require(vendorID, Oops);
|
||||||
|
|
||||||
|
long productID = IOHIDDevice_GetProductID(inIOHIDDeviceRef);
|
||||||
|
require(productID, Oops);
|
||||||
|
|
||||||
|
long locID = IOHIDDevice_GetLocationID(inIOHIDDeviceRef);
|
||||||
|
require(locID, Oops);
|
||||||
|
|
||||||
|
uint32_t usagePage = IOHIDDevice_GetUsagePage(inIOHIDDeviceRef);
|
||||||
|
uint32_t usage = IOHIDDevice_GetUsage(inIOHIDDeviceRef);
|
||||||
|
if ( !usagePage || !usage ) {
|
||||||
|
usagePage = IOHIDDevice_GetPrimaryUsagePage(inIOHIDDeviceRef);
|
||||||
|
usage = IOHIDDevice_GetPrimaryUsage(inIOHIDDeviceRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
require(usagePage && usage, Oops);
|
||||||
|
|
||||||
|
uint32_t usagePageE = IOHIDElementGetUsagePage(inIOHIDElementRef);
|
||||||
|
uint32_t usageE = IOHIDElementGetUsage(inIOHIDElementRef);
|
||||||
|
IOHIDElementCookie eleCookie = IOHIDElementGetCookie(inIOHIDElementRef);
|
||||||
|
|
||||||
|
CFStringRef prefCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
|
||||||
|
CFSTR("d:{v:%ld, p:%ld, l:%ld, p:%ld, u:%ld}, e:{p:%ld, u:%ld, c:%ld}"),
|
||||||
|
vendorID, productID, locID, usagePage, usage,
|
||||||
|
usagePageE, usageE, eleCookie);
|
||||||
|
if ( prefCFStringRef ) {
|
||||||
|
CFPreferencesSetAppValue(inKeyCFStringRef, prefCFStringRef, inAppCFStringRef);
|
||||||
|
CFRelease(prefCFStringRef);
|
||||||
|
success = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Oops: ;
|
||||||
|
return (success);
|
||||||
|
} // HIDSaveElementPref
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outIOHIDDeviceRef, outIOHIDElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: Find the specified preference in the specified application
|
||||||
|
//
|
||||||
|
// Inputs: inKeyCFStringRef - the preference key
|
||||||
|
// inAppCFStringRef - the application identifier
|
||||||
|
// outIOHIDDeviceRef - address where to restore the device
|
||||||
|
// outIOHIDElementRef - address where to restore the element
|
||||||
|
// Returns: Boolean - if successful
|
||||||
|
// outIOHIDDeviceRef - the device
|
||||||
|
// outIOHIDElementRef - the element
|
||||||
|
//
|
||||||
|
|
||||||
|
Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef,
|
||||||
|
CFStringRef inAppCFStringRef,
|
||||||
|
IOHIDDeviceRef * outIOHIDDeviceRef,
|
||||||
|
IOHIDElementRef *outIOHIDElementRef) {
|
||||||
|
Boolean found = FALSE;
|
||||||
|
if ( inKeyCFStringRef && inAppCFStringRef && outIOHIDDeviceRef && outIOHIDElementRef ) {
|
||||||
|
CFPropertyListRef prefCFPropertyListRef = CFPreferencesCopyAppValue(inKeyCFStringRef, inAppCFStringRef);
|
||||||
|
if ( prefCFPropertyListRef ) {
|
||||||
|
if ( CFStringGetTypeID() == CFGetTypeID(prefCFPropertyListRef) ) {
|
||||||
|
char buffer[256];
|
||||||
|
if ( CFStringGetCString( (CFStringRef) prefCFPropertyListRef, buffer, sizeof(buffer),
|
||||||
|
kCFStringEncodingUTF8 ) )
|
||||||
|
{
|
||||||
|
HID_info_rec searchHIDInfo;
|
||||||
|
|
||||||
|
int count = sscanf(buffer,
|
||||||
|
"d:{v:%d, p:%d, l:%d, p:%d, u:%d}, e:{p:%d, u:%d, c:%ld}",
|
||||||
|
&searchHIDInfo.device.vendorID,
|
||||||
|
&searchHIDInfo.device.productID,
|
||||||
|
&searchHIDInfo.device.locID,
|
||||||
|
&searchHIDInfo.device.usagePage,
|
||||||
|
&searchHIDInfo.device.usage,
|
||||||
|
&searchHIDInfo.element.usagePage,
|
||||||
|
&searchHIDInfo.element.usage,
|
||||||
|
(long *) &searchHIDInfo.element.cookie);
|
||||||
|
if ( 8 == count ) { // if we found all eight parameters…
|
||||||
|
// and can find a device & element that matches these…
|
||||||
|
if ( HIDFindDeviceAndElement(&searchHIDInfo, outIOHIDDeviceRef, outIOHIDElementRef) ) {
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We found the entry with this key but it's the wrong type; delete it.
|
||||||
|
CFPreferencesSetAppValue(inKeyCFStringRef, NULL, inAppCFStringRef);
|
||||||
|
(void) CFPreferencesAppSynchronize(inAppCFStringRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(prefCFPropertyListRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (found);
|
||||||
|
} // HIDRestoreElementPref
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement )
|
||||||
|
//
|
||||||
|
// Purpose: find the closest matching device and element for this action
|
||||||
|
//
|
||||||
|
// Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage
|
||||||
|
// matches element: cookie, inUsagePage, usage,
|
||||||
|
//
|
||||||
|
// Inputs: inSearchInfo - the device & element info we searching for
|
||||||
|
// outFoundDevice - the address of the best matching device
|
||||||
|
// outFoundElement - the address of the best matching element
|
||||||
|
//
|
||||||
|
// Returns: Boolean - TRUE if we find a match
|
||||||
|
// outFoundDevice - the best matching device
|
||||||
|
// outFoundElement - the best matching element
|
||||||
|
//
|
||||||
|
|
||||||
|
Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef *outFoundDevice, IOHIDElementRef *outFoundElement) {
|
||||||
|
Boolean result = FALSE;
|
||||||
|
|
||||||
|
IOHIDDeviceRef bestIOHIDDeviceRef = NULL;
|
||||||
|
IOHIDElementRef bestIOHIDElementRef = NULL;
|
||||||
|
long bestScore = 0;
|
||||||
|
|
||||||
|
CFIndex devIndex, devCount = CFArrayGetCount(gDeviceCFArrayRef);
|
||||||
|
for ( devIndex = 0; devIndex < devCount; devIndex++ ) {
|
||||||
|
long deviceScore = 1;
|
||||||
|
|
||||||
|
IOHIDDeviceRef tIOHIDDeviceRef = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDeviceCFArrayRef, devIndex);
|
||||||
|
if ( !tIOHIDDeviceRef ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// match vendorID, productID (+10, +8)
|
||||||
|
if ( inSearchInfo->device.vendorID ) {
|
||||||
|
long vendorID = IOHIDDevice_GetVendorID(tIOHIDDeviceRef);
|
||||||
|
if ( vendorID ) {
|
||||||
|
if ( inSearchInfo->device.vendorID == vendorID ) {
|
||||||
|
deviceScore += 10;
|
||||||
|
if ( inSearchInfo->device.productID ) {
|
||||||
|
long productID = IOHIDDevice_GetProductID(tIOHIDDeviceRef);
|
||||||
|
if ( productID ) {
|
||||||
|
if ( inSearchInfo->device.productID == productID ) {
|
||||||
|
deviceScore += 8;
|
||||||
|
} // if ( inSearchInfo->device.productID == productID )
|
||||||
|
|
||||||
|
} // if ( productID )
|
||||||
|
|
||||||
|
} // if ( inSearchInfo->device.productID )
|
||||||
|
|
||||||
|
} // if (inSearchInfo->device.vendorID == vendorID)
|
||||||
|
|
||||||
|
} // if vendorID
|
||||||
|
|
||||||
|
} // if search->device.vendorID
|
||||||
|
// match usagePage & usage (+9)
|
||||||
|
if ( inSearchInfo->device.usagePage && inSearchInfo->device.usage ) {
|
||||||
|
uint32_t usagePage = IOHIDDevice_GetUsagePage(tIOHIDDeviceRef) ;
|
||||||
|
uint32_t usage = IOHIDDevice_GetUsage(tIOHIDDeviceRef);
|
||||||
|
if ( !usagePage || !usage ) {
|
||||||
|
usagePage = IOHIDDevice_GetPrimaryUsagePage(tIOHIDDeviceRef);
|
||||||
|
usage = IOHIDDevice_GetPrimaryUsage(tIOHIDDeviceRef);
|
||||||
|
}
|
||||||
|
if ( usagePage ) {
|
||||||
|
if ( inSearchInfo->device.usagePage == usagePage ) {
|
||||||
|
if ( usage ) {
|
||||||
|
if ( inSearchInfo->device.usage == usage ) {
|
||||||
|
deviceScore += 9;
|
||||||
|
} // if ( inSearchInfo->usage == usage )
|
||||||
|
|
||||||
|
} // if ( usage )
|
||||||
|
|
||||||
|
} // if ( inSearchInfo->usagePage == usagePage )
|
||||||
|
|
||||||
|
} // if ( usagePage )
|
||||||
|
|
||||||
|
} // if ( inSearchInfo->usagePage && inSearchInfo->usage )
|
||||||
|
// match location ID (+5)
|
||||||
|
if ( inSearchInfo->device.locID ) {
|
||||||
|
long locID = IOHIDDevice_GetLocationID(tIOHIDDeviceRef);
|
||||||
|
if ( locID ) {
|
||||||
|
if ( inSearchInfo->device.locID == locID ) {
|
||||||
|
deviceScore += 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate over all elements of this device
|
||||||
|
gElementCFArrayRef = IOHIDDeviceCopyMatchingElements(tIOHIDDeviceRef, NULL, 0);
|
||||||
|
if ( gElementCFArrayRef ) {
|
||||||
|
CFIndex eleIndex, eleCount = CFArrayGetCount(gElementCFArrayRef);
|
||||||
|
for ( eleIndex = 0; eleIndex < eleCount; eleIndex++ ) {
|
||||||
|
IOHIDElementRef tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(gElementCFArrayRef, eleIndex);
|
||||||
|
if ( !tIOHIDElementRef ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
long score = deviceScore;
|
||||||
|
// match usage page, usage & cookie
|
||||||
|
if ( inSearchInfo->element.usagePage && inSearchInfo->element.usage ) {
|
||||||
|
uint32_t usagePage = IOHIDElementGetUsagePage(tIOHIDElementRef);
|
||||||
|
if ( inSearchInfo->element.usagePage == usagePage ) {
|
||||||
|
uint32_t usage = IOHIDElementGetUsage(tIOHIDElementRef);
|
||||||
|
if ( inSearchInfo->element.usage == usage ) {
|
||||||
|
score += 5;
|
||||||
|
IOHIDElementCookie cookie = IOHIDElementGetCookie(tIOHIDElementRef);
|
||||||
|
if ( inSearchInfo->element.cookie == cookie ) {
|
||||||
|
score += 4;
|
||||||
|
} // cookies match
|
||||||
|
|
||||||
|
} else {
|
||||||
|
score = 0;
|
||||||
|
} // usages match
|
||||||
|
|
||||||
|
} else {
|
||||||
|
score = 0;
|
||||||
|
} // usage pages match
|
||||||
|
|
||||||
|
} // if ( search usage page & usage )
|
||||||
|
|
||||||
|
#if LOG_SCORING
|
||||||
|
if ( kHIDPage_KeyboardOrKeypad != tElementRef->usagePage ) { // skip keyboards here
|
||||||
|
printf("%s: ( %ld:%ld )-I-Debug, score: %ld\t",
|
||||||
|
__PRETTY_FUNCTION__,
|
||||||
|
inSearchInfo->element.usagePage,
|
||||||
|
inSearchInfo->element.usage,
|
||||||
|
score);
|
||||||
|
HIDPrintElement(tIOHIDElementRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // LOG_SCORING
|
||||||
|
if ( score > bestScore ) {
|
||||||
|
bestIOHIDDeviceRef = tIOHIDDeviceRef;
|
||||||
|
bestIOHIDElementRef = tIOHIDElementRef;
|
||||||
|
bestScore = score;
|
||||||
|
#if LOG_SCORING
|
||||||
|
printf("%s: ( %ld:%ld )-I-Debug, better score: %ld\t",
|
||||||
|
__PRETTY_FUNCTION__,
|
||||||
|
inSearchInfo->element.usagePage,
|
||||||
|
inSearchInfo->element.usage,
|
||||||
|
score);
|
||||||
|
HIDPrintElement(bestIOHIDElementRef);
|
||||||
|
#endif // LOG_SCORING
|
||||||
|
}
|
||||||
|
} // for elements...
|
||||||
|
|
||||||
|
CFRelease(gElementCFArrayRef);
|
||||||
|
gElementCFArrayRef = NULL;
|
||||||
|
} // if ( gElementCFArrayRef )
|
||||||
|
|
||||||
|
} // for ( devIndex = 0; devIndex < devCount; devIndex++ )
|
||||||
|
if ( bestIOHIDDeviceRef || bestIOHIDElementRef ) {
|
||||||
|
*outFoundDevice = bestIOHIDDeviceRef;
|
||||||
|
*outFoundElement = bestIOHIDElementRef;
|
||||||
|
#if LOG_SCORING
|
||||||
|
printf("%s: ( %ld:%ld )-I-Debug, best score: %ld\t",
|
||||||
|
__PRETTY_FUNCTION__,
|
||||||
|
inSearchInfo->element.usagePage,
|
||||||
|
inSearchInfo->element.usage,
|
||||||
|
bestScore);
|
||||||
|
HIDPrintElement(bestIOHIDElementRef);
|
||||||
|
#endif // LOG_SCORING
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // HIDFindDeviceAndElement
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
|
||||||
|
// takes input records, save required info
|
||||||
|
// assume file is open and at correct position.
|
||||||
|
// will always write to file (if file exists) size of HID_info_rec, even if device and or element is bad
|
||||||
|
|
||||||
|
void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef, int actionCookie) {
|
||||||
|
// must save:
|
||||||
|
// actionCookie
|
||||||
|
// Device: serial,vendorID, productID, location, usagePage, usage
|
||||||
|
// Element: cookie, usagePage, usage,
|
||||||
|
HID_info_rec hidInfoRec;
|
||||||
|
HIDSetElementConfig(&hidInfoRec, inIOHIDDeviceRef, inIOHIDElementRef, actionCookie);
|
||||||
|
// write to file
|
||||||
|
if ( fileRef ) {
|
||||||
|
fwrite( (void *)&hidInfoRec, sizeof(HID_info_rec), 1, fileRef );
|
||||||
|
}
|
||||||
|
} // HIDSaveElementConfig
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
|
||||||
|
// take file, read one record (assume file position is correct and file is open)
|
||||||
|
// search for matching device
|
||||||
|
// return pDevice, pElement and cookie for action
|
||||||
|
|
||||||
|
int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef) {
|
||||||
|
// Device: serial,vendorID, productID, location, usagePage, usage
|
||||||
|
// Element: cookie, usagePage, usage,
|
||||||
|
|
||||||
|
HID_info_rec hidInfoRec;
|
||||||
|
fread( (void *) &hidInfoRec, 1, sizeof(HID_info_rec), fileRef );
|
||||||
|
return ( HIDGetElementConfig(&hidInfoRec, outIOHIDDeviceRef, outIOHIDElementRef) );
|
||||||
|
} // HIDRestoreElementConfig
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
|
||||||
|
// Set up a config record for saving
|
||||||
|
// takes an input records, returns record user can save as they want
|
||||||
|
// Note: the save rec must be pre-allocated by the calling app and will be filled out
|
||||||
|
void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr,
|
||||||
|
IOHIDDeviceRef inIOHIDDeviceRef,
|
||||||
|
IOHIDElementRef inIOHIDElementRef,
|
||||||
|
int actionCookie) {
|
||||||
|
// must save:
|
||||||
|
// actionCookie
|
||||||
|
// Device: serial,vendorID, productID, location, usagePage, usage
|
||||||
|
// Element: cookie, usagePage, usage,
|
||||||
|
inHIDInfoPtr->actionCookie = actionCookie;
|
||||||
|
// device
|
||||||
|
// need to add serial number when I have a test case
|
||||||
|
if ( inIOHIDDeviceRef && inIOHIDElementRef ) {
|
||||||
|
inHIDInfoPtr->device.vendorID = IOHIDDevice_GetVendorID(inIOHIDDeviceRef);
|
||||||
|
inHIDInfoPtr->device.productID = IOHIDDevice_GetProductID(inIOHIDDeviceRef);
|
||||||
|
inHIDInfoPtr->device.locID = IOHIDDevice_GetLocationID(inIOHIDDeviceRef);
|
||||||
|
inHIDInfoPtr->device.usage = IOHIDDevice_GetUsage(inIOHIDDeviceRef);
|
||||||
|
inHIDInfoPtr->device.usagePage = IOHIDDevice_GetUsagePage(inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
inHIDInfoPtr->element.usagePage = IOHIDElementGetUsagePage(inIOHIDElementRef);
|
||||||
|
inHIDInfoPtr->element.usage = IOHIDElementGetUsage(inIOHIDElementRef);
|
||||||
|
inHIDInfoPtr->element.minReport = IOHIDElement_GetCalibrationSaturationMin(inIOHIDElementRef);
|
||||||
|
inHIDInfoPtr->element.maxReport = IOHIDElement_GetCalibrationSaturationMax(inIOHIDElementRef);
|
||||||
|
inHIDInfoPtr->element.cookie = IOHIDElementGetCookie(inIOHIDElementRef);
|
||||||
|
} else {
|
||||||
|
inHIDInfoPtr->device.vendorID = 0;
|
||||||
|
inHIDInfoPtr->device.productID = 0;
|
||||||
|
inHIDInfoPtr->device.locID = 0;
|
||||||
|
inHIDInfoPtr->device.usage = 0;
|
||||||
|
inHIDInfoPtr->device.usagePage = 0;
|
||||||
|
|
||||||
|
inHIDInfoPtr->element.usagePage = 0;
|
||||||
|
inHIDInfoPtr->element.usage = 0;
|
||||||
|
inHIDInfoPtr->element.minReport = 0;
|
||||||
|
inHIDInfoPtr->element.maxReport = 0;
|
||||||
|
inHIDInfoPtr->element.cookie = 0;
|
||||||
|
}
|
||||||
|
} // HIDSetElementConfig
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
#if 0 // debug utility function to dump config record
|
||||||
|
void HIDDumpConfig(HID_info_ptr inHIDInfoPtr) {
|
||||||
|
printf(
|
||||||
|
"Config Record for action: %d\n\t vendor: %d product: %d location: %d\n\t usage: %d usagePage: %d\n\t element.usagePage: %d element.usage: %d\n\t minReport: %d maxReport: %d\n\t cookie: %d\n",
|
||||||
|
inHIDInfoPtr->actionCookie,
|
||||||
|
inHIDInfoPtr->device.vendorID,
|
||||||
|
inHIDInfoPtr->device.productID,
|
||||||
|
inHIDInfoPtr->locID,
|
||||||
|
inHIDInfoPtr->usage,
|
||||||
|
inHIDInfoPtr->usagePage,
|
||||||
|
inHIDInfoPtr->element.usagePage,
|
||||||
|
inHIDInfoPtr->element.usage,
|
||||||
|
inHIDInfoPtr->minReport,
|
||||||
|
inHIDInfoPtr->maxReport,
|
||||||
|
inHIDInfoPtr->cookie);
|
||||||
|
} // HIDDumpConfig
|
||||||
|
#endif // 0
|
||||||
|
// ---------------------------------
|
||||||
|
|
||||||
|
// Get matching element from config record
|
||||||
|
// takes a pre-allocated and filled out config record
|
||||||
|
// search for matching device
|
||||||
|
// return pDevice, pElement and cookie for action
|
||||||
|
int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef) {
|
||||||
|
if ( !inHIDInfoPtr->device.locID && !inHIDInfoPtr->device.vendorID && !inHIDInfoPtr->device.productID && !inHIDInfoPtr->device.usage
|
||||||
|
&& !inHIDInfoPtr->device.usagePage ) //
|
||||||
|
{ //
|
||||||
|
// early out
|
||||||
|
*outIOHIDDeviceRef = NULL;
|
||||||
|
*outIOHIDElementRef = NULL;
|
||||||
|
return (inHIDInfoPtr->actionCookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDDeviceRef tIOHIDDeviceRef, foundIOHIDDeviceRef = NULL;
|
||||||
|
IOHIDElementRef tIOHIDElementRef, foundIOHIDElementRef = NULL;
|
||||||
|
|
||||||
|
CFIndex devIdx, devCnt, idx, cnt;
|
||||||
|
// compare to current device list for matches
|
||||||
|
// look for device
|
||||||
|
if ( inHIDInfoPtr->device.locID && inHIDInfoPtr->device.vendorID && inHIDInfoPtr->device.productID ) { // look for specific device
|
||||||
|
// type plug in to same port
|
||||||
|
devCnt = CFArrayGetCount(gDeviceCFArrayRef);
|
||||||
|
for ( devIdx = 0; devIdx < devCnt; devIdx++ ) {
|
||||||
|
tIOHIDDeviceRef = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDeviceCFArrayRef, devIdx);
|
||||||
|
if ( !tIOHIDDeviceRef ) {
|
||||||
|
continue; // skip this device
|
||||||
|
}
|
||||||
|
|
||||||
|
long locID = IOHIDDevice_GetLocationID(tIOHIDDeviceRef);
|
||||||
|
long vendorID = IOHIDDevice_GetVendorID(tIOHIDDeviceRef);
|
||||||
|
long productID = IOHIDDevice_GetProductID(tIOHIDDeviceRef);
|
||||||
|
if ( (inHIDInfoPtr->device.locID == locID)
|
||||||
|
&& (inHIDInfoPtr->device.vendorID == vendorID)
|
||||||
|
&& (inHIDInfoPtr->device.productID == productID) )
|
||||||
|
{
|
||||||
|
foundIOHIDDeviceRef = tIOHIDDeviceRef;
|
||||||
|
}
|
||||||
|
if ( foundIOHIDDeviceRef ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // next devIdx
|
||||||
|
if ( foundIOHIDDeviceRef ) {
|
||||||
|
CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements(foundIOHIDDeviceRef, NULL, kIOHIDOptionsTypeNone);
|
||||||
|
if ( elementCFArrayRef ) {
|
||||||
|
cnt = CFArrayGetCount(elementCFArrayRef);
|
||||||
|
for ( idx = 0; idx < cnt; idx++ ) {
|
||||||
|
tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx);
|
||||||
|
if ( !tIOHIDElementRef ) {
|
||||||
|
continue; // skip this element
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDElementCookie cookie = IOHIDElementGetCookie(tIOHIDElementRef);
|
||||||
|
if ( inHIDInfoPtr->element.cookie == cookie ) {
|
||||||
|
foundIOHIDElementRef = tIOHIDElementRef;
|
||||||
|
}
|
||||||
|
if ( foundIOHIDElementRef ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !foundIOHIDElementRef ) {
|
||||||
|
cnt = CFArrayGetCount(elementCFArrayRef);
|
||||||
|
for ( idx = 0; idx < cnt; idx++ ) {
|
||||||
|
tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx);
|
||||||
|
if ( !tIOHIDElementRef ) {
|
||||||
|
continue; // skip this element
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t usagePage = IOHIDElementGetUsagePage(tIOHIDElementRef);
|
||||||
|
uint32_t usage = IOHIDElementGetUsage(tIOHIDElementRef);
|
||||||
|
if ( (inHIDInfoPtr->element.usage == usage) && (inHIDInfoPtr->element.usagePage == usagePage) ) {
|
||||||
|
foundIOHIDElementRef = tIOHIDElementRef;
|
||||||
|
}
|
||||||
|
if ( foundIOHIDElementRef ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // next idx
|
||||||
|
|
||||||
|
} // if ( !foundIOHIDElementRef )
|
||||||
|
if ( foundIOHIDElementRef ) { // if same device
|
||||||
|
// setup the calibration
|
||||||
|
IOHIDElement_SetupCalibration(tIOHIDElementRef);
|
||||||
|
|
||||||
|
IOHIDElement_SetCalibrationSaturationMin(tIOHIDElementRef, inHIDInfoPtr->element.minReport);
|
||||||
|
IOHIDElement_SetCalibrationSaturationMax(tIOHIDElementRef, inHIDInfoPtr->element.maxReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(elementCFArrayRef);
|
||||||
|
} // if ( elementCFArrayRef )
|
||||||
|
|
||||||
|
} // if ( foundIOHIDDeviceRef )
|
||||||
|
// if we have not found a match, look at just vendor and product
|
||||||
|
if ( (!foundIOHIDDeviceRef) && (inHIDInfoPtr->device.vendorID && inHIDInfoPtr->device.productID) ) {
|
||||||
|
devCnt = CFArrayGetCount(gDeviceCFArrayRef);
|
||||||
|
for ( devIdx = 0; devIdx < devCnt; devIdx++ ) {
|
||||||
|
tIOHIDDeviceRef = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDeviceCFArrayRef, devIdx);
|
||||||
|
if ( !tIOHIDDeviceRef ) {
|
||||||
|
continue; // skip this device
|
||||||
|
}
|
||||||
|
|
||||||
|
long vendorID = IOHIDDevice_GetVendorID(tIOHIDDeviceRef);
|
||||||
|
long productID = IOHIDDevice_GetProductID(tIOHIDDeviceRef);
|
||||||
|
if ( (inHIDInfoPtr->device.vendorID == vendorID)
|
||||||
|
&& (inHIDInfoPtr->device.productID == productID) )
|
||||||
|
{
|
||||||
|
foundIOHIDDeviceRef = tIOHIDDeviceRef;
|
||||||
|
}
|
||||||
|
if ( foundIOHIDDeviceRef ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// match elements by cookie since same device type
|
||||||
|
if ( foundIOHIDDeviceRef ) {
|
||||||
|
CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements(foundIOHIDDeviceRef, NULL, kIOHIDOptionsTypeNone);
|
||||||
|
if ( elementCFArrayRef ) {
|
||||||
|
cnt = CFArrayGetCount(elementCFArrayRef);
|
||||||
|
for ( idx = 0; idx < cnt; idx++ ) {
|
||||||
|
tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx);
|
||||||
|
if ( !tIOHIDElementRef ) {
|
||||||
|
continue; // skip this element
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDElementCookie cookie = IOHIDElementGetCookie(tIOHIDElementRef);
|
||||||
|
if ( inHIDInfoPtr->element.cookie == cookie ) {
|
||||||
|
foundIOHIDElementRef = tIOHIDElementRef;
|
||||||
|
}
|
||||||
|
if ( foundIOHIDElementRef ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if no cookie match (should NOT occur) match on usage
|
||||||
|
if ( !foundIOHIDElementRef ) {
|
||||||
|
cnt = CFArrayGetCount(elementCFArrayRef);
|
||||||
|
for ( idx = 0; idx < cnt; idx++ ) {
|
||||||
|
tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx);
|
||||||
|
if ( !tIOHIDElementRef ) {
|
||||||
|
continue; // skip this element
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t usagePage = IOHIDElementGetUsagePage(tIOHIDElementRef);
|
||||||
|
uint32_t usage = IOHIDElementGetUsage(tIOHIDElementRef);
|
||||||
|
if ( (inHIDInfoPtr->element.usage == usage)
|
||||||
|
&& (inHIDInfoPtr->element.usagePage == usagePage) )
|
||||||
|
{
|
||||||
|
foundIOHIDElementRef = tIOHIDElementRef;
|
||||||
|
}
|
||||||
|
if ( foundIOHIDElementRef ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // next idx
|
||||||
|
|
||||||
|
} // if ( !foundIOHIDElementRef )
|
||||||
|
if ( foundIOHIDElementRef ) { // if same device
|
||||||
|
// setup the calibration
|
||||||
|
IOHIDElement_SetupCalibration(tIOHIDElementRef);
|
||||||
|
IOHIDElement_SetCalibrationSaturationMin(tIOHIDElementRef, inHIDInfoPtr->element.minReport);
|
||||||
|
IOHIDElement_SetCalibrationSaturationMax(tIOHIDElementRef, inHIDInfoPtr->element.maxReport);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(elementCFArrayRef);
|
||||||
|
} // if ( elementCFArrayRef )
|
||||||
|
|
||||||
|
} // if ( foundIOHIDDeviceRef )
|
||||||
|
|
||||||
|
} // if ( device not found & vendorID & productID )
|
||||||
|
|
||||||
|
} // if ( inHIDInfoPtr->locID && inHIDInfoPtr->device.vendorID && inHIDInfoPtr->device.productID )
|
||||||
|
// can't find matching device return NULL, do not return first device
|
||||||
|
if ( (!foundIOHIDDeviceRef) || (!foundIOHIDElementRef) ) {
|
||||||
|
// no HID device
|
||||||
|
*outIOHIDDeviceRef = NULL;
|
||||||
|
*outIOHIDElementRef = NULL;
|
||||||
|
return (inHIDInfoPtr->actionCookie);
|
||||||
|
} else {
|
||||||
|
// HID device
|
||||||
|
*outIOHIDDeviceRef = foundIOHIDDeviceRef;
|
||||||
|
*outIOHIDElementRef = foundIOHIDElementRef;
|
||||||
|
return (inHIDInfoPtr->actionCookie);
|
||||||
|
}
|
||||||
|
} // HIDGetElementConfig
|
||||||
|
|
||||||
|
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
108
src/cocoa/HID_Error_Handler.c
Normal file
108
src/cocoa/HID_Error_Handler.c
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
// File: HID_Error_Handler.c
|
||||||
|
// Abstract: Implementation of the HID utilities error handlers
|
||||||
|
// Version: 2.0
|
||||||
|
//
|
||||||
|
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||||
|
// Inc. ("Apple") in consideration of your agreement to the following
|
||||||
|
// terms, and your use, installation, modification or redistribution of
|
||||||
|
// this Apple software constitutes acceptance of these terms. If you do
|
||||||
|
// not agree with these terms, please do not use, install, modify or
|
||||||
|
// redistribute this Apple software.
|
||||||
|
//
|
||||||
|
// In consideration of your agreement to abide by the following terms, and
|
||||||
|
// subject to these terms, Apple grants you a personal, non-exclusive
|
||||||
|
// license, under Apple's copyrights in this original Apple software (the
|
||||||
|
// "Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||||
|
// Software, with or without modifications, in source and/or binary forms;
|
||||||
|
// provided that if you redistribute the Apple Software in its entirety and
|
||||||
|
// without modifications, you must retain this notice and the following
|
||||||
|
// text and disclaimers in all such redistributions of the Apple Software.
|
||||||
|
// Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||||
|
// be used to endorse or promote products derived from the Apple Software
|
||||||
|
// without specific prior written permission from Apple. Except as
|
||||||
|
// expressly stated in this notice, no other rights or licenses, express or
|
||||||
|
// implied, are granted by Apple herein, including but not limited to any
|
||||||
|
// patent rights that may be infringed by your derivative works or by other
|
||||||
|
// works in which the Apple Software may be incorporated.
|
||||||
|
//
|
||||||
|
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||||
|
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||||
|
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||||
|
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
//
|
||||||
|
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||||
|
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||||
|
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||||
|
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||||
|
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//*****************************************************
|
||||||
|
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||||
|
|
||||||
|
#ifdef DEBUG // not used in release
|
||||||
|
#if !defined (kBuildingLibrary)
|
||||||
|
#define kVerboseErrors
|
||||||
|
|
||||||
|
// system includes ----------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef kVerboseErrors
|
||||||
|
//#include <Carbon/Carbon.h>
|
||||||
|
#endif
|
||||||
|
#endif // not kBuildingLibrary
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// project includes ---------------------------------------------------------
|
||||||
|
|
||||||
|
#include "HID_Utilities_External.h"
|
||||||
|
|
||||||
|
// globals (internal/private) -----------------------------------------------
|
||||||
|
|
||||||
|
// prototypes (internal/private) --------------------------------------------
|
||||||
|
|
||||||
|
// functions (internal/private) ---------------------------------------------
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
// -------------------------------------
|
||||||
|
|
||||||
|
// central error reporting
|
||||||
|
|
||||||
|
void HIDReportErrorNum(const char *strError, int numError) {
|
||||||
|
char errMsgCStr[256];
|
||||||
|
|
||||||
|
sprintf(errMsgCStr, "%s #%d (0x%x)", strError, numError, numError);
|
||||||
|
|
||||||
|
// out as debug string
|
||||||
|
#ifdef kVerboseErrors
|
||||||
|
{
|
||||||
|
fputs(errMsgCStr, stderr);
|
||||||
|
}
|
||||||
|
#endif // kVerboseErrors
|
||||||
|
} // HIDReportErrorNum
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
|
||||||
|
void HIDReportError(const char *strError) {
|
||||||
|
char errMsgCStr[256];
|
||||||
|
|
||||||
|
sprintf(errMsgCStr, "%s", strError);
|
||||||
|
|
||||||
|
// out as debug string
|
||||||
|
#ifdef kVerboseErrors
|
||||||
|
{
|
||||||
|
fputs(errMsgCStr, stderr);
|
||||||
|
}
|
||||||
|
#endif // kVerboseErrors
|
||||||
|
} // HIDReportError
|
||||||
|
|
||||||
|
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
1210
src/cocoa/HID_Name_Lookup.c
Normal file
1210
src/cocoa/HID_Name_Lookup.c
Normal file
File diff suppressed because it is too large
Load diff
361
src/cocoa/HID_Queue_Utilities.c
Normal file
361
src/cocoa/HID_Queue_Utilities.c
Normal file
|
@ -0,0 +1,361 @@
|
||||||
|
// File: HID_Queue_Utilities.c
|
||||||
|
// Abstract: HID Queue Utilities.
|
||||||
|
// Version: 2.0
|
||||||
|
//
|
||||||
|
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||||
|
// Inc. ("Apple") in consideration of your agreement to the following
|
||||||
|
// terms, and your use, installation, modification or redistribution of
|
||||||
|
// this Apple software constitutes acceptance of these terms. If you do
|
||||||
|
// not agree with these terms, please do not use, install, modify or
|
||||||
|
// redistribute this Apple software.
|
||||||
|
//
|
||||||
|
// In consideration of your agreement to abide by the following terms, and
|
||||||
|
// subject to these terms, Apple grants you a personal, non-exclusive
|
||||||
|
// license, under Apple's copyrights in this original Apple software (the
|
||||||
|
// "Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||||
|
// Software, with or without modifications, in source and/or binary forms;
|
||||||
|
// provided that if you redistribute the Apple Software in its entirety and
|
||||||
|
// without modifications, you must retain this notice and the following
|
||||||
|
// text and disclaimers in all such redistributions of the Apple Software.
|
||||||
|
// Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||||
|
// be used to endorse or promote products derived from the Apple Software
|
||||||
|
// without specific prior written permission from Apple. Except as
|
||||||
|
// expressly stated in this notice, no other rights or licenses, express or
|
||||||
|
// implied, are granted by Apple herein, including but not limited to any
|
||||||
|
// patent rights that may be infringed by your derivative works or by other
|
||||||
|
// works in which the Apple Software may be incorporated.
|
||||||
|
//
|
||||||
|
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||||
|
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||||
|
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||||
|
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
//
|
||||||
|
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||||
|
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||||
|
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||||
|
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||||
|
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//*****************************************************
|
||||||
|
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||||
|
|
||||||
|
#include "HID_Utilities_External.h"
|
||||||
|
|
||||||
|
// ==================================
|
||||||
|
// private functions
|
||||||
|
|
||||||
|
// creates a queue for a device, creates and opens device interface if required
|
||||||
|
static IOReturn HIDCreateQueue(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
IOReturn result = kIOReturnSuccess;
|
||||||
|
if ( inIOHIDDeviceRef ) {
|
||||||
|
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||||
|
|
||||||
|
// do we already have a queue?
|
||||||
|
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||||
|
if ( tIOHIDQueueRef ) { // (yes)
|
||||||
|
assert( IOHIDQueueGetTypeID() == CFGetTypeID(tIOHIDQueueRef) );
|
||||||
|
} else {
|
||||||
|
tIOHIDQueueRef = IOHIDQueueCreate(kCFAllocatorDefault, inIOHIDDeviceRef, kDeviceQueueSize, kIOHIDOptionsTypeNone);
|
||||||
|
if ( tIOHIDQueueRef ) { // did that work
|
||||||
|
IOHIDDevice_SetQueue(inIOHIDDeviceRef, tIOHIDQueueRef);
|
||||||
|
result = kIOReturnSuccess;
|
||||||
|
} else {
|
||||||
|
HIDReportErrorNum("Failed to create queue via create", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HIDReportErrorNum("HID device ref does not exist for queue creation", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} /* HIDCreateQueue */
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
// returns true if queue is empty false otherwise
|
||||||
|
// error if no device, empty if no queue
|
||||||
|
static unsigned char HIDIsDeviceQueueEmpty(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
if ( inIOHIDDeviceRef ) { // need device and queue
|
||||||
|
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||||
|
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||||
|
if ( tIOHIDQueueRef ) {
|
||||||
|
IOHIDElementRef tIOHIDElementRef = HIDGetFirstDeviceElement(inIOHIDDeviceRef, kHIDElementTypeIO);
|
||||||
|
|
||||||
|
while ( tIOHIDElementRef ) {
|
||||||
|
if ( IOHIDQueueContainsElement(tIOHIDQueueRef, tIOHIDElementRef) ) {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
tIOHIDElementRef = HIDGetNextDeviceElement(tIOHIDElementRef, kHIDElementTypeIO);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HIDReportError("NULL device passed to HIDIsDeviceQueueEmpty.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HIDReportError("NULL device passed to HIDIsDeviceQueueEmpty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
} /* HIDIsDeviceQueueEmpty */
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
|
||||||
|
// disposes and releases queue, sets queue to NULL,.
|
||||||
|
// Note: will have no effect if device or queue do not exist
|
||||||
|
static IOReturn HIDDisposeReleaseQueue(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
IOReturn result = kIOReturnSuccess;
|
||||||
|
if ( inIOHIDDeviceRef ) {
|
||||||
|
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||||
|
if ( tIOHIDQueueRef ) {
|
||||||
|
// stop queue
|
||||||
|
IOHIDQueueStop(tIOHIDQueueRef);
|
||||||
|
|
||||||
|
// release the queue
|
||||||
|
CFRelease(tIOHIDQueueRef);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HIDReportError("NULL device passed to HIDDisposeReleaseQueue.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} /* HIDDisposeReleaseQueue */
|
||||||
|
|
||||||
|
// ==================================
|
||||||
|
// public functions
|
||||||
|
// ----------------------------------
|
||||||
|
|
||||||
|
// queues specific element, performing any device queue set up required
|
||||||
|
// queue is started and ready to return events on exit from this function
|
||||||
|
int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef) {
|
||||||
|
IOReturn result = kIOReturnSuccess;
|
||||||
|
if ( inIOHIDDeviceRef ) {
|
||||||
|
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||||
|
if ( inIOHIDElementRef ) {
|
||||||
|
assert( IOHIDElementGetTypeID() == CFGetTypeID(inIOHIDElementRef) );
|
||||||
|
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||||
|
if ( !tIOHIDQueueRef ) { // if no queue create queue
|
||||||
|
result = HIDCreateQueue(inIOHIDDeviceRef);
|
||||||
|
if ( kIOReturnSuccess == result ) {
|
||||||
|
tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( tIOHIDQueueRef ) {
|
||||||
|
// stop queue
|
||||||
|
IOHIDQueueStop(tIOHIDQueueRef);
|
||||||
|
// queue element
|
||||||
|
if ( !IOHIDQueueContainsElement(tIOHIDQueueRef, inIOHIDElementRef) ) {
|
||||||
|
IOHIDQueueAddElement(tIOHIDQueueRef, inIOHIDElementRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restart queue
|
||||||
|
IOHIDQueueStart(tIOHIDQueueRef);
|
||||||
|
} else {
|
||||||
|
HIDReportError("No queue for device passed to HIDQueueElement.");
|
||||||
|
if ( kIOReturnSuccess == result ) {
|
||||||
|
result = kIOReturnError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HIDReportError("NULL element passed to HIDQueueElement.");
|
||||||
|
result = kIOReturnBadArgument;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HIDReportError("NULL device passed to HIDQueueElement.");
|
||||||
|
result = kIOReturnBadArgument;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} /* HIDQueueElement */
|
||||||
|
// ---------------------------------
|
||||||
|
|
||||||
|
// adds all elements to queue, performing any device queue set up required
|
||||||
|
// queue is started and ready to return events on exit from this function
|
||||||
|
int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
IOReturn result = kIOReturnSuccess;
|
||||||
|
// error checking
|
||||||
|
if ( !inIOHIDDeviceRef ) {
|
||||||
|
HIDReportError("Device does not exist, cannot queue device.");
|
||||||
|
return (kIOReturnBadArgument);
|
||||||
|
}
|
||||||
|
if ( !inIOHIDDeviceRef ) { // must have interface
|
||||||
|
HIDReportError("Device does not have hid device ref, cannot queue device.");
|
||||||
|
return (kIOReturnError);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||||
|
if ( !tIOHIDQueueRef ) { // if no queue create queue
|
||||||
|
result = HIDCreateQueue(inIOHIDDeviceRef);
|
||||||
|
if ( kIOReturnSuccess == result ) {
|
||||||
|
tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( (kIOReturnSuccess != result) || (!tIOHIDQueueRef) ) {
|
||||||
|
HIDReportErrorNum("Could not queue device due to problem creating queue.", result);
|
||||||
|
if ( kIOReturnSuccess != result ) {
|
||||||
|
return (result);
|
||||||
|
} else {
|
||||||
|
return (kIOReturnError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop queue
|
||||||
|
IOHIDQueueStop(tIOHIDQueueRef);
|
||||||
|
|
||||||
|
// queue element
|
||||||
|
IOHIDElementRef tIOHIDElementRef = HIDGetFirstDeviceElement(inIOHIDDeviceRef, kHIDElementTypeIO);
|
||||||
|
|
||||||
|
while ( tIOHIDElementRef ) {
|
||||||
|
if ( !IOHIDQueueContainsElement(tIOHIDQueueRef, tIOHIDElementRef) ) {
|
||||||
|
IOHIDQueueAddElement(tIOHIDQueueRef, tIOHIDElementRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
tIOHIDElementRef = HIDGetNextDeviceElement(tIOHIDElementRef, kHIDElementTypeIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restart queue
|
||||||
|
IOHIDQueueStart(tIOHIDQueueRef);
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} /* HIDQueueDevice */
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
// removes element for queue, if last element in queue will release queue and closes device interface
|
||||||
|
int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef) {
|
||||||
|
IOReturn result = kIOReturnSuccess;
|
||||||
|
if ( inIOHIDDeviceRef ) {
|
||||||
|
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||||
|
if ( inIOHIDElementRef ) {
|
||||||
|
assert( IOHIDElementGetTypeID() == CFGetTypeID(inIOHIDElementRef) );
|
||||||
|
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||||
|
if ( tIOHIDQueueRef ) {
|
||||||
|
// stop queue
|
||||||
|
IOHIDQueueStop(tIOHIDQueueRef);
|
||||||
|
// de-queue element
|
||||||
|
if ( IOHIDQueueContainsElement(tIOHIDQueueRef, inIOHIDElementRef) ) {
|
||||||
|
IOHIDQueueRemoveElement(tIOHIDQueueRef, inIOHIDElementRef);
|
||||||
|
}
|
||||||
|
// release device queue and close interface if queue empty
|
||||||
|
if ( HIDIsDeviceQueueEmpty(inIOHIDDeviceRef) ) {
|
||||||
|
result = HIDDisposeReleaseQueue(inIOHIDDeviceRef);
|
||||||
|
if ( kIOReturnSuccess != result ) {
|
||||||
|
HIDReportErrorNum("Failed to dispose and release queue.", result);
|
||||||
|
}
|
||||||
|
} else { // not empty so restart queue
|
||||||
|
IOHIDQueueStart(tIOHIDQueueRef);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HIDReportError("No queue for device passed to HIDDequeueElement.");
|
||||||
|
if ( kIOReturnSuccess == result ) {
|
||||||
|
result = kIOReturnError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HIDReportError("NULL element passed to HIDDequeueElement.");
|
||||||
|
result = kIOReturnBadArgument;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HIDReportError("NULL device passed to HIDDequeueElement.");
|
||||||
|
result = kIOReturnBadArgument;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} /* HIDDequeueElement */
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
// completely removes all elements from queue and releases queue and closes device interface
|
||||||
|
// does not release device interfaces, application must call ReleaseHIDDeviceList on exit
|
||||||
|
int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
IOReturn result = kIOReturnSuccess;
|
||||||
|
// error checking
|
||||||
|
if ( !inIOHIDDeviceRef ) {
|
||||||
|
HIDReportError("Device does not exist, cannot queue device.");
|
||||||
|
return (kIOReturnBadArgument);
|
||||||
|
}
|
||||||
|
if ( !inIOHIDDeviceRef ) { // must have interface
|
||||||
|
HIDReportError("Device does not have hid device ref, cannot queue device.");
|
||||||
|
return (kIOReturnError);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||||
|
if ( tIOHIDQueueRef ) {
|
||||||
|
// iterate through elements and if queued, remove
|
||||||
|
IOHIDElementRef tIOHIDElementRef = HIDGetFirstDeviceElement(inIOHIDDeviceRef, kHIDElementTypeIO);
|
||||||
|
|
||||||
|
while ( tIOHIDElementRef ) {
|
||||||
|
// de-queue element
|
||||||
|
if ( IOHIDQueueContainsElement(tIOHIDQueueRef, tIOHIDElementRef) ) {
|
||||||
|
IOHIDQueueRemoveElement(tIOHIDQueueRef, tIOHIDElementRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
tIOHIDElementRef = HIDGetNextDeviceElement(tIOHIDElementRef, kHIDElementTypeIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure queue is disposed and released
|
||||||
|
result = HIDDisposeReleaseQueue(inIOHIDDeviceRef);
|
||||||
|
if ( kIOReturnSuccess != result ) {
|
||||||
|
HIDReportErrorNum("Failed to dispose and release queue.", result);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HIDReportError("No queue for device passed to HIDDequeueElement.");
|
||||||
|
if ( kIOReturnSuccess == result ) {
|
||||||
|
result = kIOReturnError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} /* HIDDequeueDevice */
|
||||||
|
// ---------------------------------
|
||||||
|
|
||||||
|
// releases all device queues for quit or rebuild (must be called)
|
||||||
|
// does not release device interfaces, application must call ReleaseHIDDeviceList on exit
|
||||||
|
IOReturn HIDReleaseAllDeviceQueues(void) {
|
||||||
|
IOReturn result = kIOReturnSuccess;
|
||||||
|
IOHIDDeviceRef tIOHIDDeviceRef = HIDGetFirstDevice();
|
||||||
|
|
||||||
|
while ( tIOHIDDeviceRef ) {
|
||||||
|
result = HIDDequeueDevice(tIOHIDDeviceRef);
|
||||||
|
if ( kIOReturnSuccess != result ) {
|
||||||
|
HIDReportErrorNum("Could not dequeue device.", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
tIOHIDDeviceRef = HIDGetNextDevice(tIOHIDDeviceRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} /* HIDReleaseAllDeviceQueues */
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
// Get the next event in the queue for a device
|
||||||
|
// elements or entire device should be queued prior to calling this with HIDQueueElement or HIDQueueDevice
|
||||||
|
// returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise
|
||||||
|
// Note: kIOReturnUnderrun returned from getNextEvent indicates an empty queue not an error condition
|
||||||
|
// Note: application should pass in a pointer to a IOHIDEventStruct cast to a void (for CFM compatibility)
|
||||||
|
unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef) {
|
||||||
|
if ( inIOHIDDeviceRef ) {
|
||||||
|
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||||
|
if ( tIOHIDQueueRef ) {
|
||||||
|
if ( pIOHIDValueRef ) {
|
||||||
|
*pIOHIDValueRef = IOHIDQueueCopyNextValueWithTimeout(tIOHIDQueueRef, 0.0);
|
||||||
|
if ( *pIOHIDValueRef ) {
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HIDReportError("Could not get HID event, hid queue reference does not exist.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HIDReportError("Could not get HID event, device does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (false); // did not get event
|
||||||
|
} /* HIDGetEvent */
|
||||||
|
|
||||||
|
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
1068
src/cocoa/HID_Utilities.c
Normal file
1068
src/cocoa/HID_Utilities.c
Normal file
File diff suppressed because it is too large
Load diff
417
src/cocoa/HID_Utilities_External.h
Normal file
417
src/cocoa/HID_Utilities_External.h
Normal file
|
@ -0,0 +1,417 @@
|
||||||
|
// File: HID_Utilities_External.h
|
||||||
|
// Abstract: External interface for HID Utilities, can be used with either library or source.
|
||||||
|
// Version: 2.0
|
||||||
|
//
|
||||||
|
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||||
|
// Inc. ("Apple") in consideration of your agreement to the following
|
||||||
|
// terms, and your use, installation, modification or redistribution of
|
||||||
|
// this Apple software constitutes acceptance of these terms. If you do
|
||||||
|
// not agree with these terms, please do not use, install, modify or
|
||||||
|
// redistribute this Apple software.
|
||||||
|
//
|
||||||
|
// In consideration of your agreement to abide by the following terms, and
|
||||||
|
// subject to these terms, Apple grants you a personal, non-exclusive
|
||||||
|
// license, under Apple's copyrights in this original Apple software (the
|
||||||
|
// "Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||||
|
// Software, with or without modifications, in source and/or binary forms;
|
||||||
|
// provided that if you redistribute the Apple Software in its entirety and
|
||||||
|
// without modifications, you must retain this notice and the following
|
||||||
|
// text and disclaimers in all such redistributions of the Apple Software.
|
||||||
|
// Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||||
|
// be used to endorse or promote products derived from the Apple Software
|
||||||
|
// without specific prior written permission from Apple. Except as
|
||||||
|
// expressly stated in this notice, no other rights or licenses, express or
|
||||||
|
// implied, are granted by Apple herein, including but not limited to any
|
||||||
|
// patent rights that may be infringed by your derivative works or by other
|
||||||
|
// works in which the Apple Software may be incorporated.
|
||||||
|
//
|
||||||
|
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||||
|
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||||
|
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||||
|
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
//
|
||||||
|
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||||
|
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||||
|
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||||
|
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||||
|
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//*****************************************************
|
||||||
|
#ifndef _HID_Utilities_External_h_
|
||||||
|
#define _HID_Utilities_External_h_
|
||||||
|
|
||||||
|
// ==================================
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ==================================
|
||||||
|
|
||||||
|
//includes
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "IOHIDLib_.h"
|
||||||
|
|
||||||
|
// ==================================
|
||||||
|
|
||||||
|
#ifndef _IOKIT_HID_IOHIDKEYS_H_
|
||||||
|
/*!
|
||||||
|
@typedef IOHIDElementCookie
|
||||||
|
@abstract Abstract data type used as a unique identifier for an element.
|
||||||
|
*/
|
||||||
|
#ifdef __LP64__
|
||||||
|
typedef uint32_t IOHIDElementCookie;
|
||||||
|
#else
|
||||||
|
typedef void *IOHIDElementCookie;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Device and Element Interfaces
|
||||||
|
|
||||||
|
enum HIDElementTypeMask {
|
||||||
|
kHIDElementTypeInput = 1 << 1,
|
||||||
|
kHIDElementTypeOutput = 1 << 2,
|
||||||
|
kHIDElementTypeFeature = 1 << 3,
|
||||||
|
kHIDElementTypeCollection = 1 << 4,
|
||||||
|
kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature,
|
||||||
|
kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection
|
||||||
|
};
|
||||||
|
typedef enum HIDElementTypeMask HIDElementTypeMask;
|
||||||
|
|
||||||
|
// ==================================
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - exported globals
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
extern IOHIDManagerRef gIOHIDManagerRef;
|
||||||
|
extern CFMutableArrayRef gDeviceCFArrayRef;
|
||||||
|
extern CFArrayRef gElementCFArrayRef;
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes )
|
||||||
|
//
|
||||||
|
// Purpose: builds list of devices with elements (allocates memory and captures devices) in which
|
||||||
|
// the devices could be of different types/usages list is allocated internally within HID
|
||||||
|
// Utilites and can be accessed via accessor functions structures within list are considered
|
||||||
|
// flat and user accessable, but not user modifiable can be called again to rebuild list to
|
||||||
|
// account for new devices (will do the right thing in case of disposing existing list)
|
||||||
|
// usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages
|
||||||
|
// returns true if succesful
|
||||||
|
//
|
||||||
|
// Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages
|
||||||
|
// inUsages - inNumDeviceTypes sized array of matching usages
|
||||||
|
// inNumDeviceTypes - number of usage pages & usages
|
||||||
|
//
|
||||||
|
// Returns: Boolean - if successful
|
||||||
|
//
|
||||||
|
extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes);
|
||||||
|
|
||||||
|
// same as above but this uses a single usagePage and usage
|
||||||
|
extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage);
|
||||||
|
|
||||||
|
// updates the current device list for any new/removed devices
|
||||||
|
// if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList
|
||||||
|
// usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages
|
||||||
|
// returns true if successful which means if any device were added or removed (the device config changed)
|
||||||
|
extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes);
|
||||||
|
|
||||||
|
// release list built by above function
|
||||||
|
// MUST be called prior to application exit to properly release devices
|
||||||
|
// if not called (or app crashes) devices can be recovered by pluging into different location in USB chain
|
||||||
|
extern void HIDReleaseDeviceList(void);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDRebuildDevices( )
|
||||||
|
//
|
||||||
|
// Purpose: rebuilds the (internal) list of devices
|
||||||
|
//
|
||||||
|
// Inputs: none
|
||||||
|
//
|
||||||
|
// Returns: none
|
||||||
|
//
|
||||||
|
|
||||||
|
extern void HIDRebuildDevices(void);
|
||||||
|
|
||||||
|
// does a device list exist
|
||||||
|
extern unsigned char HIDHaveDeviceList(void);
|
||||||
|
|
||||||
|
// how many HID devices have been found
|
||||||
|
// returns 0 if no device list exist
|
||||||
|
extern UInt32 HIDCountDevices(void);
|
||||||
|
|
||||||
|
// how many elements does a specific device have
|
||||||
|
// returns 0 if device is invalid or NULL
|
||||||
|
// uses mask of HIDElementTypeMask to restrict element found
|
||||||
|
// use kHIDElementTypeIO to get non-collection elements
|
||||||
|
extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask);
|
||||||
|
|
||||||
|
// get the first device in the device list
|
||||||
|
// returns NULL if no list exists
|
||||||
|
extern IOHIDDeviceRef HIDGetFirstDevice(void);
|
||||||
|
|
||||||
|
// get next device in list given current device as parameter
|
||||||
|
// returns NULL if end of list
|
||||||
|
extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
// get the first element of device passed in as parameter
|
||||||
|
// returns NULL if no list exists or device does not exists or is NULL
|
||||||
|
// uses mask of HIDElementTypeMask to restrict element found
|
||||||
|
// use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality
|
||||||
|
extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask);
|
||||||
|
|
||||||
|
// get next element of given device in list given current element as parameter
|
||||||
|
// will walk down each collection then to next element or collection (depthwise traverse)
|
||||||
|
// returns NULL if end of list
|
||||||
|
// uses mask of HIDElementTypeMask to restrict element found
|
||||||
|
// use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality
|
||||||
|
extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask);
|
||||||
|
|
||||||
|
// get previous element of given device in list given current element as parameter
|
||||||
|
// this walks directly up the tree to the top element and does not search at each level
|
||||||
|
// returns NULL if beginning of list
|
||||||
|
// uses mask of HIDElementTypeMask to restrict element found
|
||||||
|
// use kHIDElementTypeIO to get non-collection elements
|
||||||
|
extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask);
|
||||||
|
|
||||||
|
// returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h )
|
||||||
|
// returns empty string for invalid types
|
||||||
|
extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDCopyUsageName( inUsagePage, inUsage )
|
||||||
|
//
|
||||||
|
// Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h )
|
||||||
|
//
|
||||||
|
// Notes: returns usage page and usage values in CFString form for unknown values
|
||||||
|
//
|
||||||
|
// Inputs: inUsagePage - the usage page
|
||||||
|
// inUsage - the usage
|
||||||
|
//
|
||||||
|
// Returns: CFStringRef - the resultant string
|
||||||
|
//
|
||||||
|
|
||||||
|
extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage);
|
||||||
|
|
||||||
|
// ==================================
|
||||||
|
|
||||||
|
// Element Event Queue and Value Interfaces
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kDefaultUserMin = 0, // default user min and max used for scaling
|
||||||
|
kDefaultUserMax = 255
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible
|
||||||
|
// but should account for the maximum possible events in the queue
|
||||||
|
// USB updates will likely occur at 100 Hz so one must account for this rate of
|
||||||
|
// if states change quickly (updates are only posted on state changes)
|
||||||
|
};
|
||||||
|
|
||||||
|
// ==================================
|
||||||
|
|
||||||
|
// queues specific element, performing any device queue set up required
|
||||||
|
extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef);
|
||||||
|
|
||||||
|
// adds all elements to queue, performing any device queue set up required
|
||||||
|
extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
// removes element for queue, if last element in queue will release queue and device
|
||||||
|
extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef);
|
||||||
|
|
||||||
|
// completely removes all elements from queue and releases queue and device
|
||||||
|
extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
// releases all device queues for quit or rebuild (must be called)
|
||||||
|
extern int HIDReleaseAllDeviceQueues(void);
|
||||||
|
|
||||||
|
// returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise
|
||||||
|
// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
|
||||||
|
extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef);
|
||||||
|
|
||||||
|
// ==================================
|
||||||
|
|
||||||
|
// Conguration and Save Interfaces
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kPercentMove = 10 // precent of overall range a element must move to register
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct HID_info_struct {
|
||||||
|
int actionCookie;
|
||||||
|
// device
|
||||||
|
// need to add serial number when I have a test case
|
||||||
|
struct {
|
||||||
|
int vendorID, productID;
|
||||||
|
int locID;
|
||||||
|
uint32_t usagePage, usage;
|
||||||
|
} device;
|
||||||
|
// elements
|
||||||
|
struct {
|
||||||
|
uint32_t usagePage, usage;
|
||||||
|
int minReport, maxReport;
|
||||||
|
IOHIDElementCookie cookie; // always 32 bits
|
||||||
|
} element;
|
||||||
|
}HID_info_rec, *HID_info_ptr;
|
||||||
|
|
||||||
|
// get vendor name from vendor ID
|
||||||
|
extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName);
|
||||||
|
|
||||||
|
// get product name from vendor/product ID
|
||||||
|
extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName);
|
||||||
|
|
||||||
|
// get element name from vendor id/product id look up ( using element cookie )
|
||||||
|
extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID,
|
||||||
|
int inProductID,
|
||||||
|
IOHIDElementCookie inCookie,
|
||||||
|
char * outCStrName);
|
||||||
|
|
||||||
|
// get element name from vendor id/product id look up ( using element usage page & usage )
|
||||||
|
extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID,
|
||||||
|
long inProductID,
|
||||||
|
long inUsagePage,
|
||||||
|
long inUsage,
|
||||||
|
char *inCStrName);
|
||||||
|
|
||||||
|
// utility routines to dump device or element info
|
||||||
|
extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef);
|
||||||
|
extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef);
|
||||||
|
|
||||||
|
// polls single device's elements for a change greater than kPercentMove. Times out after given time
|
||||||
|
// returns 1 and pointer to element if found
|
||||||
|
// returns 0 and NULL for both parameters if not found
|
||||||
|
extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef,
|
||||||
|
IOHIDElementRef *outIOHIDElementRef,
|
||||||
|
float timeout);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDConfigureAction( outDeviceRef, outElementRef, inTimeout )
|
||||||
|
//
|
||||||
|
// Purpose: polls all devices and elements for a change greater than kPercentMove.
|
||||||
|
// Times out after given time returns 1 and pointer to device and element
|
||||||
|
// if found; returns 0 and NULL for both parameters if not found
|
||||||
|
//
|
||||||
|
// Inputs: outDeviceRef - address where to store the device
|
||||||
|
// outElementRef - address where to store the element
|
||||||
|
// inTimeout - the timeout
|
||||||
|
// Returns: Boolean - TRUE if successful
|
||||||
|
// outDeviceRef - the device
|
||||||
|
// outElementRef - the element
|
||||||
|
//
|
||||||
|
|
||||||
|
extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: Save the device & element values into the specified key in the specified applications preferences
|
||||||
|
//
|
||||||
|
// Inputs: inKeyCFStringRef - the preference key
|
||||||
|
// inAppCFStringRef - the application identifier
|
||||||
|
// inDeviceRef - the device
|
||||||
|
// inElementRef - the element
|
||||||
|
// Returns: Boolean - if successful
|
||||||
|
//
|
||||||
|
|
||||||
|
extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef,
|
||||||
|
CFStringRef inAppCFStringRef,
|
||||||
|
IOHIDDeviceRef inDeviceRef,
|
||||||
|
IOHIDElementRef inElementRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: Find the specified preference in the specified application
|
||||||
|
//
|
||||||
|
// Inputs: inKeyCFStringRef - the preference key
|
||||||
|
// inAppCFStringRef - the application identifier
|
||||||
|
// outDeviceRef - address where to restore the device
|
||||||
|
// outElementRef - address where to restore the element
|
||||||
|
// Returns: Boolean - if successful
|
||||||
|
// outDeviceRef - the device
|
||||||
|
// outElementRef - the element
|
||||||
|
//
|
||||||
|
|
||||||
|
extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef,
|
||||||
|
CFStringRef inAppCFStringRef,
|
||||||
|
IOHIDDeviceRef * outDeviceRef,
|
||||||
|
IOHIDElementRef *outElementRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement )
|
||||||
|
//
|
||||||
|
// Purpose: find the closest matching device and element for this action
|
||||||
|
//
|
||||||
|
// Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage
|
||||||
|
// matches element: cookie, inUsagePage, usage,
|
||||||
|
//
|
||||||
|
// Inputs: inSearchInfo - the device & element info we searching for
|
||||||
|
// outFoundDevice - the address of the best matching device
|
||||||
|
// outFoundElement - the address of the best matching element
|
||||||
|
//
|
||||||
|
// Returns: Boolean - TRUE if we find a match
|
||||||
|
// outFoundDevice - the best matching device
|
||||||
|
// outFoundElement - the best matching element
|
||||||
|
//
|
||||||
|
|
||||||
|
extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo,
|
||||||
|
IOHIDDeviceRef * outFoundDevice,
|
||||||
|
IOHIDElementRef * outFoundElement);
|
||||||
|
|
||||||
|
// -- These are routines to use if the applcationwants HID Utilities to do the file handling --
|
||||||
|
// Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type.
|
||||||
|
|
||||||
|
// take input records, save required info
|
||||||
|
// assume file is open and at correct position.
|
||||||
|
void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie);
|
||||||
|
|
||||||
|
// takes a file, reads one record (assume file position is correct and file is open)
|
||||||
|
// search for matching device
|
||||||
|
// return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action
|
||||||
|
int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef);
|
||||||
|
|
||||||
|
// -- These are routines to use if the client wants to use their own file handling --
|
||||||
|
|
||||||
|
// Set up a config record for saving
|
||||||
|
// takes an input records, returns record user can save as they want
|
||||||
|
// Note: the save rec must be pre-allocated by the calling app and will be filled out
|
||||||
|
void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr,
|
||||||
|
IOHIDDeviceRef inIOHIDDeviceRef,
|
||||||
|
IOHIDElementRef inIOHidElementRef,
|
||||||
|
int actionCookie);
|
||||||
|
|
||||||
|
// Get matching element from config record
|
||||||
|
// takes a pre-allocated and filled out config record
|
||||||
|
// search for matching device
|
||||||
|
// return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action
|
||||||
|
int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef);
|
||||||
|
|
||||||
|
// ==================================
|
||||||
|
|
||||||
|
// Error reporter, can be set to report however the application desires
|
||||||
|
extern void HIDReportError(const char *strError);
|
||||||
|
|
||||||
|
// Error with numeric code reporter, can be set to report however the application desires
|
||||||
|
extern void HIDReportErrorNum(const char *strError, int numError);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _HID_Utilities_External_h_
|
619
src/cocoa/IOHIDDevice_.c
Normal file
619
src/cocoa/IOHIDDevice_.c
Normal file
|
@ -0,0 +1,619 @@
|
||||||
|
// File: IOHIDDevice_.c
|
||||||
|
// Abstract: convieance functions for IOHIDDeviceGetProperty
|
||||||
|
// Version: 2.0 + 5.3
|
||||||
|
//
|
||||||
|
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||||
|
// Inc. ("Apple") in consideration of your agreement to the following
|
||||||
|
// terms, and your use, installation, modification or redistribution of
|
||||||
|
// this Apple software constitutes acceptance of these terms. If you do
|
||||||
|
// not agree with these terms, please do not use, install, modify or
|
||||||
|
// redistribute this Apple software.
|
||||||
|
//
|
||||||
|
// In consideration of your agreement to abide by the following terms, and
|
||||||
|
// subject to these terms, Apple grants you a personal, non-exclusive
|
||||||
|
// license, under Apple's copyrights in this original Apple software (the
|
||||||
|
// "Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||||
|
// Software, with or without modifications, in source and/or binary forms;
|
||||||
|
// provided that if you redistribute the Apple Software in its entirety and
|
||||||
|
// without modifications, you must retain this notice and the following
|
||||||
|
// text and disclaimers in all such redistributions of the Apple Software.
|
||||||
|
// Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||||
|
// be used to endorse or promote products derived from the Apple Software
|
||||||
|
// without specific prior written permission from Apple. Except as
|
||||||
|
// expressly stated in this notice, no other rights or licenses, express or
|
||||||
|
// implied, are granted by Apple herein, including but not limited to any
|
||||||
|
// patent rights that may be infringed by your derivative works or by other
|
||||||
|
// works in which the Apple Software may be incorporated.
|
||||||
|
//
|
||||||
|
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||||
|
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||||
|
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||||
|
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
//
|
||||||
|
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||||
|
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||||
|
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||||
|
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||||
|
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//*****************************************************
|
||||||
|
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||||
|
|
||||||
|
#pragma mark - includes & imports
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
#include "IOHIDDevice_.h"
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - typedef's, struct's, enums, defines, etc.
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
#define kIOHIDDevice_TransactionKey "DeviceTransactionRef"
|
||||||
|
#define kIOHIDDevice_QueueKey "DeviceQueueRef"
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - local (static) function prototypes
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
static Boolean IOHIDDevice_GetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef,
|
||||||
|
CFStringRef inKey,
|
||||||
|
uint32_t * outValue);
|
||||||
|
// static void IOHIDDevice_SetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey, uint32_t inValue);
|
||||||
|
|
||||||
|
static Boolean IOHIDDevice_GetPtrProperty(IOHIDDeviceRef inIOHIDDeviceRef,
|
||||||
|
CFStringRef inKey,
|
||||||
|
void ** outValue);
|
||||||
|
static void IOHIDDevice_SetPtrProperty(IOHIDDeviceRef inIOHIDDeviceRef,
|
||||||
|
CFStringRef inKey,
|
||||||
|
void * inValue);
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - exported globals
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - local (static) globals
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - exported function implementations
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDIsValidDevice( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: validate this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: Boolean - TRUE if we find the device in our( internal ) device list
|
||||||
|
//
|
||||||
|
|
||||||
|
Boolean HIDIsValidDevice(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
Boolean result = FALSE; // assume failure (pessimist!)
|
||||||
|
if ( inIOHIDDeviceRef ) {
|
||||||
|
if ( CFGetTypeID(inIOHIDDeviceRef) ==IOHIDDeviceGetTypeID() ) {
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // HIDIsValidDevice
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetTransport( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the Transport CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: CFStringRef - the Transport for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
CFStringRef IOHIDDevice_GetTransport(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||||
|
return ( IOHIDDeviceGetProperty( inIOHIDDeviceRef, CFSTR(kIOHIDTransportKey) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetVendorID( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the vendor ID for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the vendor ID for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetVendorID(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDVendorIDKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetVendorID
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetVendorIDSource( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the VendorIDSource for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the VendorIDSource for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetVendorIDSource(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDVendorIDSourceKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetVendorIDSource
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetProductID( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the product ID for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the product ID for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetProductID(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDProductIDKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetProductID
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetVersionNumber( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the VersionNumber CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the VersionNumber for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetVersionNumber(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDVersionNumberKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetVersionNumber
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetManufacturer( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the Manufacturer CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: CFStringRef - the Manufacturer for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
CFStringRef IOHIDDevice_GetManufacturer(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||||
|
return ( IOHIDDeviceGetProperty( inIOHIDDeviceRef, CFSTR(kIOHIDManufacturerKey) ) );
|
||||||
|
} // IOHIDDevice_GetManufacturer
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetProduct( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the Product CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: CFStringRef - the Product for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
CFStringRef IOHIDDevice_GetProduct(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||||
|
return ( IOHIDDeviceGetProperty( inIOHIDDeviceRef, CFSTR(kIOHIDProductKey) ) );
|
||||||
|
} // IOHIDDevice_GetProduct
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetSerialNumber( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the SerialNumber CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: CFStringRef - the SerialNumber for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
CFStringRef IOHIDDevice_GetSerialNumber(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||||
|
return ( IOHIDDeviceGetProperty( inIOHIDDeviceRef, CFSTR(kIOHIDSerialNumberKey) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetCountryCode( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the CountryCode CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the CountryCode for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetCountryCode(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDCountryCodeKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetCountryCode
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetLocationID( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the location ID for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the location ID for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetLocationID(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDLocationIDKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetLocationID
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetUsage( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the usage for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the usage for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetUsage(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDDeviceUsageKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetUsage
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetUsagePage( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the usage page for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the usage page for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetUsagePage(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDDeviceUsagePageKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetUsagePage
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetUsagePairs( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the UsagePairs CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: CFArrayRef - the UsagePairs for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
CFArrayRef IOHIDDevice_GetUsagePairs(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||||
|
return ( IOHIDDeviceGetProperty( inIOHIDDeviceRef, CFSTR(kIOHIDDeviceUsagePairsKey) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetPrimaryUsage( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the PrimaryUsage CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the PrimaryUsage for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetPrimaryUsage(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsageKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetPrimaryUsage
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetPrimaryUsagePage( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the PrimaryUsagePage CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the PrimaryUsagePage for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetPrimaryUsagePage(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsagePageKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetPrimaryUsagePage
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetMaxInputReportSize( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the MaxInputReportSize CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the MaxInputReportSize for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetMaxInputReportSize(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDMaxInputReportSizeKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetMaxInputReportSize
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetMaxOutputReportSize( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the MaxOutputReportSize for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the MaxOutput for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetMaxOutputReportSize(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDMaxOutputReportSizeKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetMaxOutputReportSize
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetMaxFeatureReportSize( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the MaxFeatureReportSize for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the MaxFeatureReportSize for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t IOHIDDevice_GetMaxFeatureReportSize(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDMaxFeatureReportSizeKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetMaxFeatureReportSize
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetReportInterval( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the ReportInterval for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the ReportInterval for this device
|
||||||
|
//
|
||||||
|
#ifndef kIOHIDReportIntervalKey
|
||||||
|
#define kIOHIDReportIntervalKey "ReportInterval"
|
||||||
|
#endif
|
||||||
|
uint32_t IOHIDDevice_GetReportInterval(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDReportIntervalKey), &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetReportInterval
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetQueue( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the Queue for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: IOHIDQueueRef - the Queue for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
IOHIDQueueRef IOHIDDevice_GetQueue(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
IOHIDQueueRef result = 0;
|
||||||
|
(void) IOHIDDevice_GetPtrProperty(inIOHIDDeviceRef, CFSTR(kIOHIDDevice_QueueKey), (void *) &result);
|
||||||
|
if ( result ) {
|
||||||
|
assert( IOHIDQueueGetTypeID() == CFGetTypeID(result) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetQueue
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_SetQueue( inIOHIDDeviceRef, inQueueRef )
|
||||||
|
//
|
||||||
|
// Purpose: Set the Queue for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
// inQueueRef - the Queue reference
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
void IOHIDDevice_SetQueue(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDQueueRef inQueueRef) {
|
||||||
|
IOHIDDevice_SetPtrProperty(inIOHIDDeviceRef, CFSTR(kIOHIDDevice_QueueKey), inQueueRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetTransaction( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the Transaction for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: IOHIDTransactionRef - the Transaction for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
IOHIDTransactionRef IOHIDDevice_GetTransaction(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
IOHIDTransactionRef result = 0;
|
||||||
|
(void) IOHIDDevice_GetPtrProperty(inIOHIDDeviceRef, CFSTR(kIOHIDDevice_TransactionKey), (void *) &result);
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetTransaction
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_SetTransaction( inIOHIDDeviceRef, inTransactionRef )
|
||||||
|
//
|
||||||
|
// Purpose: Set the Transaction for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
// inTransactionRef - the Transaction reference
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
void IOHIDDevice_SetTransaction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDTransactionRef inTransactionRef) {
|
||||||
|
IOHIDDevice_SetPtrProperty(inIOHIDDeviceRef, CFSTR(kIOHIDDevice_TransactionKey), inTransactionRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - local (static) function implementations
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetUInt32Property( inIOHIDDeviceRef, inKey, outValue )
|
||||||
|
//
|
||||||
|
// Purpose: convieance function to return a uint32_t property of a device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the device
|
||||||
|
// inKey - CFString for the
|
||||||
|
// outValue - address where to restore the element
|
||||||
|
// Returns: the action cookie
|
||||||
|
// outValue - the device
|
||||||
|
//
|
||||||
|
|
||||||
|
static Boolean IOHIDDevice_GetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey, uint32_t *outValue) {
|
||||||
|
Boolean result = FALSE;
|
||||||
|
if ( inIOHIDDeviceRef ) {
|
||||||
|
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||||
|
|
||||||
|
CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty(inIOHIDDeviceRef, inKey);
|
||||||
|
if ( tCFTypeRef ) {
|
||||||
|
// if this is a number
|
||||||
|
if ( CFNumberGetTypeID() == CFGetTypeID(tCFTypeRef) ) {
|
||||||
|
// get it's value
|
||||||
|
result = CFNumberGetValue( (CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, outValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetUInt32Property
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_SetUInt32Property( inIOHIDDeviceRef, inKey, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: convieance function to set a long property of an Device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the Device
|
||||||
|
// inKey - CFString for the key
|
||||||
|
// inValue - the value to set it to
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
#if 0 // unused
|
||||||
|
static void IOHIDDevice_SetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey, uint32_t inValue) {
|
||||||
|
CFNumberRef tCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &inValue);
|
||||||
|
if ( tCFNumberRef ) {
|
||||||
|
IOHIDDeviceSetProperty(inIOHIDDeviceRef, inKey, tCFNumberRef);
|
||||||
|
CFRelease(tCFNumberRef);
|
||||||
|
}
|
||||||
|
} // IOHIDDevice_SetUInt32Property
|
||||||
|
#endif
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetPtrProperty( inIOHIDDeviceRef, inKey, outValue )
|
||||||
|
//
|
||||||
|
// Purpose: convieance function to return a pointer property of a device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the device
|
||||||
|
// inKey - CFString for the
|
||||||
|
// outValue - address where to restore the element
|
||||||
|
// Returns: the action cookie
|
||||||
|
// outValue - the device
|
||||||
|
//
|
||||||
|
|
||||||
|
static Boolean IOHIDDevice_GetPtrProperty(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey, void **outValue) {
|
||||||
|
Boolean result = FALSE;
|
||||||
|
if ( inIOHIDDeviceRef ) {
|
||||||
|
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||||
|
|
||||||
|
CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty(inIOHIDDeviceRef, inKey);
|
||||||
|
if ( tCFTypeRef ) {
|
||||||
|
// if this is a number
|
||||||
|
if ( CFNumberGetTypeID() == CFGetTypeID(tCFTypeRef) ) {
|
||||||
|
// get it's value
|
||||||
|
#ifdef __LP64__
|
||||||
|
result = CFNumberGetValue( (CFNumberRef) tCFTypeRef, kCFNumberSInt64Type, outValue );
|
||||||
|
#else
|
||||||
|
result = CFNumberGetValue( (CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, outValue );
|
||||||
|
#endif // ifdef __LP64__
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // IOHIDDevice_GetPtrProperty
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_SetPtrProperty( inIOHIDDeviceRef, inKey, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: convieance function to set a long property of an Device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the Device
|
||||||
|
// inKey - CFString for the key
|
||||||
|
// inValue - the value to set it to
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
static void IOHIDDevice_SetPtrProperty(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey, void *inValue) {
|
||||||
|
#ifdef __LP64__
|
||||||
|
CFNumberRef tCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &inValue);
|
||||||
|
#else
|
||||||
|
CFNumberRef tCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &inValue);
|
||||||
|
#endif // ifdef __LP64__
|
||||||
|
if ( tCFNumberRef ) {
|
||||||
|
IOHIDDeviceSetProperty(inIOHIDDeviceRef, inKey, tCFNumberRef);
|
||||||
|
CFRelease(tCFNumberRef);
|
||||||
|
}
|
||||||
|
} // IOHIDDevice_SetPtrProperty
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
|
||||||
|
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
422
src/cocoa/IOHIDDevice_.h
Normal file
422
src/cocoa/IOHIDDevice_.h
Normal file
|
@ -0,0 +1,422 @@
|
||||||
|
// File: IOHIDDevice_.h
|
||||||
|
// Abstract: convieance functions for IOHIDDeviceGetProperty
|
||||||
|
// Version: 2.0 + 5.3
|
||||||
|
//
|
||||||
|
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||||
|
// Inc. ("Apple") in consideration of your agreement to the following
|
||||||
|
// terms, and your use, installation, modification or redistribution of
|
||||||
|
// this Apple software constitutes acceptance of these terms. If you do
|
||||||
|
// not agree with these terms, please do not use, install, modify or
|
||||||
|
// redistribute this Apple software.
|
||||||
|
//
|
||||||
|
// In consideration of your agreement to abide by the following terms, and
|
||||||
|
// subject to these terms, Apple grants you a personal, non-exclusive
|
||||||
|
// license, under Apple's copyrights in this original Apple software (the
|
||||||
|
// "Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||||
|
// Software, with or without modifications, in source and/or binary forms;
|
||||||
|
// provided that if you redistribute the Apple Software in its entirety and
|
||||||
|
// without modifications, you must retain this notice and the following
|
||||||
|
// text and disclaimers in all such redistributions of the Apple Software.
|
||||||
|
// Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||||
|
// be used to endorse or promote products derived from the Apple Software
|
||||||
|
// without specific prior written permission from Apple. Except as
|
||||||
|
// expressly stated in this notice, no other rights or licenses, express or
|
||||||
|
// implied, are granted by Apple herein, including but not limited to any
|
||||||
|
// patent rights that may be infringed by your derivative works or by other
|
||||||
|
// works in which the Apple Software may be incorporated.
|
||||||
|
//
|
||||||
|
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||||
|
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||||
|
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||||
|
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
//
|
||||||
|
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||||
|
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||||
|
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||||
|
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||||
|
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//*****************************************************
|
||||||
|
#ifndef __IOHIDDevice__
|
||||||
|
#define __IOHIDDevice__
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - includes & imports
|
||||||
|
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
|
||||||
|
#include "IOHIDLib_.h"
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#if PRAGMA_ONCE
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PRAGMA_IMPORT
|
||||||
|
#pragma import on
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PRAGMA_STRUCT_ALIGN
|
||||||
|
#pragma options align=mac68k
|
||||||
|
#elif PRAGMA_STRUCT_PACKPUSH
|
||||||
|
#pragma pack(push, 2)
|
||||||
|
#elif PRAGMA_STRUCT_PACK
|
||||||
|
#pragma pack(2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - typedef's, struct's, enums, defines, etc.
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - exported globals
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - exported function prototypes
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDIsValidDevice( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: validate this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: Boolean - TRUE if we find the device in our( internal ) device list
|
||||||
|
//
|
||||||
|
|
||||||
|
extern Boolean HIDIsValidDevice(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetTransport( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the Transport CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: CFStringRef - the Transport CFString for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern CFStringRef IOHIDDevice_GetTransport(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetVendorID( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the vendor ID for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the vendor ID for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetVendorID(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetVendorIDSource( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the VendorIDSource for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the VendorIDSource for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetVendorIDSource(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetProductID( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the product ID for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the product ID for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetProductID(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetVersionNumber( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the VersionNumber CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the VersionNumber for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetVersionNumber(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetManufacturer( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the Manufacturer CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: CFStringRef - the Manufacturer CFString for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern CFStringRef IOHIDDevice_GetManufacturer(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetProduct( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the Product CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: CFStringRef - the Product CFString for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern CFStringRef IOHIDDevice_GetProduct(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetSerialNumber( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the SerialNumber CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: CFStringRef - the SerialNumber CFString for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern CFStringRef IOHIDDevice_GetSerialNumber(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetCountryCode( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the CountryCode CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the CountryCode for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetCountryCode(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetLocationID( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the location ID for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the location ID for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetLocationID(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetUsage( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the usage for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the usage for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetUsage(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetUsagePage( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the usage page for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the usage page for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetUsagePage(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetUsagePairs( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the UsagePairs CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: CFArrayRef - the UsagePairs for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern CFArrayRef IOHIDDevice_GetUsagePairs(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetPrimaryUsage( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the PrimaryUsage CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: CFStringRef - the PrimaryUsage CFString for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetPrimaryUsage(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetPrimaryUsagePage( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the PrimaryUsagePage CFString for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: CFStringRef - the PrimaryUsagePage CFString for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetPrimaryUsagePage(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetMaxInputReportSize( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the MaxInputReportSize for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the MaxInputReportSize for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetMaxInputReportSize(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetMaxOutputReportSize( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the MaxOutputReportSize for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the MaxOutputReportSize for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetMaxOutputReportSize(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetMaxFeatureReportSize( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the MaxFeatureReportSize for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the MaxFeatureReportSize for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetMaxFeatureReportSize(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetReportInterval( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the ReportInterval for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: uint32_t - the ReportInterval for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern uint32_t IOHIDDevice_GetReportInterval(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetQueue( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the Queue for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: IOHIDQueueRef - the Queue for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern IOHIDQueueRef IOHIDDevice_GetQueue(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_SetQueue( inIOHIDDeviceRef, inQueueRef )
|
||||||
|
//
|
||||||
|
// Purpose: Set the Queue for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
// inQueueRef - the Queue
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
extern void IOHIDDevice_SetQueue(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDQueueRef inQueueRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_GetTransaction( inIOHIDDeviceRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the Transaction for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
//
|
||||||
|
// Returns: IOHIDTransactionRef - the Transaction for this device
|
||||||
|
//
|
||||||
|
|
||||||
|
extern IOHIDTransactionRef IOHIDDevice_GetTransaction(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDDevice_SetTransaction( inIOHIDDeviceRef, inTransactionRef )
|
||||||
|
//
|
||||||
|
// Purpose: Set the Transaction for this device
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||||
|
// inTransactionRef - the Transaction
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
extern void IOHIDDevice_SetTransaction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDTransactionRef inTransactionRef);
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#if PRAGMA_STRUCT_ALIGN
|
||||||
|
#pragma options align=reset
|
||||||
|
#elif PRAGMA_STRUCT_PACKPUSH
|
||||||
|
#pragma pack(pop)
|
||||||
|
#elif PRAGMA_STRUCT_PACK
|
||||||
|
#pragma pack()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PRAGMA_IMPORT_OFF
|
||||||
|
#pragma import off
|
||||||
|
#elif PRAGMA_IMPORT
|
||||||
|
#pragma import reset
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __IOHIDDevice__ //
|
509
src/cocoa/IOHIDElement_.c
Normal file
509
src/cocoa/IOHIDElement_.c
Normal file
|
@ -0,0 +1,509 @@
|
||||||
|
// File: IOHIDElement_.c
|
||||||
|
// Abstract: convieance functions for IOHIDElementGetProperty
|
||||||
|
// Version: 2.0
|
||||||
|
//
|
||||||
|
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||||
|
// Inc. ("Apple") in consideration of your agreement to the following
|
||||||
|
// terms, and your use, installation, modification or redistribution of
|
||||||
|
// this Apple software constitutes acceptance of these terms. If you do
|
||||||
|
// not agree with these terms, please do not use, install, modify or
|
||||||
|
// redistribute this Apple software.
|
||||||
|
//
|
||||||
|
// In consideration of your agreement to abide by the following terms, and
|
||||||
|
// subject to these terms, Apple grants you a personal, non-exclusive
|
||||||
|
// license, under Apple's copyrights in this original Apple software (the
|
||||||
|
// "Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||||
|
// Software, with or without modifications, in source and/or binary forms;
|
||||||
|
// provided that if you redistribute the Apple Software in its entirety and
|
||||||
|
// without modifications, you must retain this notice and the following
|
||||||
|
// text and disclaimers in all such redistributions of the Apple Software.
|
||||||
|
// Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||||
|
// be used to endorse or promote products derived from the Apple Software
|
||||||
|
// without specific prior written permission from Apple. Except as
|
||||||
|
// expressly stated in this notice, no other rights or licenses, express or
|
||||||
|
// implied, are granted by Apple herein, including but not limited to any
|
||||||
|
// patent rights that may be infringed by your derivative works or by other
|
||||||
|
// works in which the Apple Software may be incorporated.
|
||||||
|
//
|
||||||
|
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||||
|
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||||
|
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||||
|
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
//
|
||||||
|
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||||
|
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||||
|
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||||
|
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||||
|
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//*****************************************************
|
||||||
|
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||||
|
|
||||||
|
#pragma mark - includes & imports
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
#include "IOHIDElement_.h"
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - typedef's, struct's, enums, defines, etc.
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - local (static) function prototypes
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
// static Boolean IOHIDElement_GetLongProperty( IOHIDElementRef inElementRef, CFStringRef inKey, long * outValue );
|
||||||
|
// static void IOHIDElement_SetLongProperty( IOHIDElementRef inElementRef, CFStringRef inKey, long inValue );
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - exported globals
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - local (static) globals
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - exported function implementations
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDIsValidElement( inIOHIDElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: validate this element
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDElementRef - the element
|
||||||
|
//
|
||||||
|
// Returns: Boolean - TRUE if this is a valid element ref
|
||||||
|
//
|
||||||
|
Boolean HIDIsValidElement(IOHIDElementRef inIOHIDElementRef) {
|
||||||
|
Boolean result = FALSE; // assume failure (pessimist!)
|
||||||
|
if ( inIOHIDElementRef ) {
|
||||||
|
if ( CFGetTypeID(inIOHIDElementRef) ==IOHIDElementGetTypeID() ) {
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // HIDIsValidElement
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetValue( inElementRef, inIOHIDValueScaleType )
|
||||||
|
//
|
||||||
|
// Purpose: returns the current value for an element( polling )
|
||||||
|
//
|
||||||
|
// Notes: will return 0 on error conditions which should be accounted for by application
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the element
|
||||||
|
// inIOHIDValueScaleType - scale type ( calibrated or physical )
|
||||||
|
//
|
||||||
|
// Returns: double - current value for element
|
||||||
|
//
|
||||||
|
double IOHIDElement_GetValue(IOHIDElementRef inElementRef, IOHIDValueScaleType inIOHIDValueScaleType) {
|
||||||
|
long result = 0;
|
||||||
|
IOHIDValueRef tIOHIDValueRef;
|
||||||
|
if ( kIOReturnSuccess == IOHIDDeviceGetValue(IOHIDElementGetDevice(inElementRef), inElementRef, &tIOHIDValueRef) ) {
|
||||||
|
result = IOHIDValueGetScaledValue(tIOHIDValueRef, inIOHIDValueScaleType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // IOHIDElement_GetValue
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationMin( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the minimum bounds for a calibrated value for this element
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: CFIndex - the minimum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
CFIndex IOHIDElement_GetCalibrationMin(IOHIDElementRef inElementRef) {
|
||||||
|
CFIndex result;
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationMinKey), &result) ) {
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMaxKey), &result) ) {
|
||||||
|
result = 0x7FFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationMinKey), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // IOHIDElement_GetCalibrationMin
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationMin( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the minimum bounds for a calibrated value for this element
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the minimum bounds for a calibrated value for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
void IOHIDElement_SetCalibrationMin(IOHIDElementRef inElementRef, CFIndex inValue) {
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationMinKey), inValue);
|
||||||
|
} // IOHIDElement_SetCalibrationMin
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationMax( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the maximum bounds for a calibrated value for this element
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: CFIndex - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
CFIndex IOHIDElement_GetCalibrationMax(IOHIDElementRef inElementRef) {
|
||||||
|
CFIndex result;
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationMaxKey), &result) ) {
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMinKey), &result) ) {
|
||||||
|
result = -0x7FFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationMaxKey), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // IOHIDElement_GetCalibrationMax
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationMax( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the maximum bounds for a calibrated value for this element
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
void IOHIDElement_SetCalibrationMax(IOHIDElementRef inElementRef, CFIndex inValue) {
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationMaxKey), inValue);
|
||||||
|
} // IOHIDElement_SetCalibrationMax
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationSaturationMin( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the mininum tolerance to be used when calibrating a logical element value
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: CFIndex - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
CFIndex IOHIDElement_GetCalibrationSaturationMin(IOHIDElementRef inElementRef) {
|
||||||
|
CFIndex result;
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationSaturationMinKey), &result) ) {
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMinKey), &result) ) {
|
||||||
|
result = -0x7FFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationSaturationMinKey), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // IOHIDElement_GetCalibrationSaturationMin
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationSaturationMin( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the mininum tolerance to be used when calibrating a logical element value
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
void IOHIDElement_SetCalibrationSaturationMin(IOHIDElementRef inElementRef, CFIndex inValue) {
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationSaturationMinKey), inValue);
|
||||||
|
} // IOHIDElement_SetCalibrationSaturationMin
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationSaturationMax( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the maximum tolerance to be used when calibrating a logical element value
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: CFIndex - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
CFIndex IOHIDElement_GetCalibrationSaturationMax(IOHIDElementRef inElementRef) {
|
||||||
|
CFIndex result;
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationSaturationMaxKey), &result) ) {
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMinKey), &result) ) {
|
||||||
|
result = -0x7FFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationSaturationMaxKey), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // IOHIDElement_GetCalibrationSaturationMax
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationSaturationMax( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the maximum tolerance to be used when calibrating a logical element value
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
void IOHIDElement_SetCalibrationSaturationMax(IOHIDElementRef inElementRef, CFIndex inValue) {
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationSaturationMaxKey), inValue);
|
||||||
|
} // IOHIDElement_SetCalibrationSaturationMax
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationDeadZoneMin( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the minimum bounds near the midpoint of a logical value in which the value is ignored
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: CFIndex - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
CFIndex IOHIDElement_GetCalibrationDeadZoneMin(IOHIDElementRef inElementRef) {
|
||||||
|
CFIndex result;
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationDeadZoneMinKey), &result) ) {
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMinKey), &result) ) {
|
||||||
|
result = -0x7FFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationDeadZoneMinKey), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // IOHIDElement_GetCalibrationDeadZoneMin
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationDeadZoneMin( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the minimum bounds near the midpoint of a logical value in which the value is ignored
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
void IOHIDElement_SetCalibrationDeadZoneMin(IOHIDElementRef inElementRef, CFIndex inValue) {
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationDeadZoneMinKey), inValue);
|
||||||
|
} // IOHIDElement_SetCalibrationDeadZoneMin
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationDeadZoneMax( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the maximum bounds near the midpoint of a logical value in which the value is ignored
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: CFIndex - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
CFIndex IOHIDElement_GetCalibrationDeadZoneMax(IOHIDElementRef inElementRef) {
|
||||||
|
CFIndex result;
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationDeadZoneMaxKey), &result) ) {
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMinKey), &result) ) {
|
||||||
|
result = -0x7FFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationDeadZoneMaxKey), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // IOHIDElement_GetCalibrationDeadZoneMax
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationDeadZoneMax( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the maximum bounds near the midpoint of a logical value in which the value is ignored
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
void IOHIDElement_SetCalibrationDeadZoneMax(IOHIDElementRef inElementRef, CFIndex inValue) {
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationDeadZoneMaxKey), inValue);
|
||||||
|
} // IOHIDElement_SetCalibrationDeadZoneMax
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationGranularity( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the level of detail returned for a calibrated element value
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: double_t - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
double_t IOHIDElement_GetCalibrationGranularity(IOHIDElementRef inElementRef) {
|
||||||
|
CFIndex result;
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationGranularityKey), &result) ) {
|
||||||
|
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMinKey), &result) ) {
|
||||||
|
result = -0x7FFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationGranularityKey), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // IOHIDElement_GetCalibrationGranularity
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationGranularity( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the level of detail returned for a calibrated element value
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the the level of detail for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
void IOHIDElement_SetCalibrationGranularity(IOHIDElementRef inElementRef, double_t inValue) {
|
||||||
|
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationGranularityKey), inValue);
|
||||||
|
} // IOHIDElement_SetCalibrationGranularity
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetupCalibration( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: set default values for the element calibration parameters
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
void IOHIDElement_SetupCalibration(IOHIDElementRef inIOHIDElementRef) {
|
||||||
|
// these are the min/max values returned by IOHIDValueGetScaledValue( v, kIOHIDValueScaleTypeCalibrated );
|
||||||
|
IOHIDElement_SetCalibrationMin( inIOHIDElementRef, IOHIDElementGetLogicalMin(inIOHIDElementRef) );
|
||||||
|
IOHIDElement_SetCalibrationMax( inIOHIDElementRef, IOHIDElementGetLogicalMax(inIOHIDElementRef) );
|
||||||
|
|
||||||
|
// this is the granularity of the values returned by IOHIDValueGetScaledValue( v, kIOHIDValueScaleTypeCalibrated );
|
||||||
|
// for example if set to 0.1 the values returned will be multiples of 0.1 ( 0.1, 0.2, 0.3, etc. )
|
||||||
|
IOHIDElement_SetCalibrationGranularity(inIOHIDElementRef, 0.);
|
||||||
|
|
||||||
|
// these define the dead zone (like in the middel of joystick axis)
|
||||||
|
IOHIDElement_SetCalibrationDeadZoneMin(inIOHIDElementRef, 0);
|
||||||
|
IOHIDElement_SetCalibrationDeadZoneMax(inIOHIDElementRef, 0);
|
||||||
|
#if 1
|
||||||
|
// get the current value of this element
|
||||||
|
double value = IOHIDElement_GetValue(inIOHIDElementRef, kIOHIDValueScaleTypePhysical);
|
||||||
|
// use it as our min/mas saturation
|
||||||
|
IOHIDElement_SetCalibrationSaturationMin(inIOHIDElementRef, value);
|
||||||
|
IOHIDElement_SetCalibrationSaturationMax(inIOHIDElementRef, value);
|
||||||
|
#else
|
||||||
|
// calculate the middle physical value we would expect from this element
|
||||||
|
CFIndex valueMin = IOHIDElementGetPhysicalMin(inIOHIDElementRef);
|
||||||
|
CFIndex valueMax = IOHIDElementGetPhysicalMax(inIOHIDElementRef);
|
||||||
|
CFIndex valueMid = (valueMin + valueMax) / 2;
|
||||||
|
|
||||||
|
// use it as our min/mas saturation
|
||||||
|
// this value determines the min/max values that have been recieved from the device element
|
||||||
|
IOHIDElement_SetCalibrationSaturationMin(inIOHIDElementRef, valueMid);
|
||||||
|
IOHIDElement_SetCalibrationSaturationMax(inIOHIDElementRef, valueMid);
|
||||||
|
|
||||||
|
// get the current value of this element
|
||||||
|
double value = IOHIDElement_GetValue(inIOHIDElementRef, kIOHIDValueScaleTypePhysical);
|
||||||
|
// and use it to adjust the current saturation values if it's outside their range
|
||||||
|
if ( value < IOHIDElement_GetCalibrationSaturationMin(inIOHIDElementRef) ) {
|
||||||
|
IOHIDElement_SetCalibrationSaturationMin(inIOHIDElementRef, value);
|
||||||
|
}
|
||||||
|
if ( value > IOHIDElement_GetCalibrationSaturationMax(inIOHIDElementRef) ) {
|
||||||
|
IOHIDElement_SetCalibrationSaturationMax(inIOHIDElementRef, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
} // IOHIDElement_SetupCalibration
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - local (static) function implementations
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetLongProperty( inElementRef, inKey, outValue )
|
||||||
|
//
|
||||||
|
// Purpose: convieance function to return a long property of an element
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the element
|
||||||
|
// inKey - CFString for the key
|
||||||
|
// outValue - address where to store the value
|
||||||
|
// Returns: Boolean - TRUE if successful
|
||||||
|
// outValue - the long property's value
|
||||||
|
//
|
||||||
|
|
||||||
|
Boolean IOHIDElement_GetLongProperty(IOHIDElementRef inElementRef, CFStringRef inKey, long *outValue) {
|
||||||
|
Boolean result = FALSE;
|
||||||
|
|
||||||
|
CFTypeRef tCFTypeRef = IOHIDElementGetProperty(inElementRef, inKey);
|
||||||
|
if ( tCFTypeRef ) {
|
||||||
|
// if this is a number
|
||||||
|
if ( CFNumberGetTypeID() == CFGetTypeID(tCFTypeRef) ) {
|
||||||
|
// get it's value
|
||||||
|
result = CFNumberGetValue( (CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, outValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} /* IOHIDElement_GetLongProperty */
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetLongProperty( inElementRef, inKey, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: convieance function to set a long property of an element
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the element
|
||||||
|
// inKey - CFString for the key
|
||||||
|
// inValue - the value to set it to
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
void IOHIDElement_SetLongProperty(IOHIDElementRef inElementRef, CFStringRef inKey, long inValue) {
|
||||||
|
CFNumberRef tCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &inValue);
|
||||||
|
if ( tCFNumberRef ) {
|
||||||
|
IOHIDElementSetProperty(inElementRef, inKey, tCFNumberRef);
|
||||||
|
CFRelease(tCFNumberRef);
|
||||||
|
}
|
||||||
|
} // IOHIDElement_SetLongProperty
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
|
||||||
|
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
339
src/cocoa/IOHIDElement_.h
Normal file
339
src/cocoa/IOHIDElement_.h
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
// File: IOHIDElement_.h
|
||||||
|
// Abstract: convieance functions for IOHIDElementGetProperty
|
||||||
|
// Version: 2.0
|
||||||
|
//
|
||||||
|
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||||
|
// Inc. ("Apple") in consideration of your agreement to the following
|
||||||
|
// terms, and your use, installation, modification or redistribution of
|
||||||
|
// this Apple software constitutes acceptance of these terms. If you do
|
||||||
|
// not agree with these terms, please do not use, install, modify or
|
||||||
|
// redistribute this Apple software.
|
||||||
|
//
|
||||||
|
// In consideration of your agreement to abide by the following terms, and
|
||||||
|
// subject to these terms, Apple grants you a personal, non-exclusive
|
||||||
|
// license, under Apple's copyrights in this original Apple software (the
|
||||||
|
// "Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||||
|
// Software, with or without modifications, in source and/or binary forms;
|
||||||
|
// provided that if you redistribute the Apple Software in its entirety and
|
||||||
|
// without modifications, you must retain this notice and the following
|
||||||
|
// text and disclaimers in all such redistributions of the Apple Software.
|
||||||
|
// Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||||
|
// be used to endorse or promote products derived from the Apple Software
|
||||||
|
// without specific prior written permission from Apple. Except as
|
||||||
|
// expressly stated in this notice, no other rights or licenses, express or
|
||||||
|
// implied, are granted by Apple herein, including but not limited to any
|
||||||
|
// patent rights that may be infringed by your derivative works or by other
|
||||||
|
// works in which the Apple Software may be incorporated.
|
||||||
|
//
|
||||||
|
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||||
|
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||||
|
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||||
|
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
//
|
||||||
|
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||||
|
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||||
|
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||||
|
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||||
|
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//*****************************************************
|
||||||
|
#ifndef __IOHIDElement___
|
||||||
|
#define __IOHIDElement___
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - includes & imports
|
||||||
|
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
|
||||||
|
#include "IOHIDLib_.h"
|
||||||
|
//*****************************************************
|
||||||
|
#if PRAGMA_ONCE
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PRAGMA_IMPORT
|
||||||
|
#pragma import on
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PRAGMA_STRUCT_ALIGN
|
||||||
|
#pragma options align=mac68k
|
||||||
|
#elif PRAGMA_STRUCT_PACKPUSH
|
||||||
|
#pragma pack(push, 2)
|
||||||
|
#elif PRAGMA_STRUCT_PACK
|
||||||
|
#pragma pack(2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - typedef's, struct's, enums, defines, etc.
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - exported globals
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - exported function prototypes
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// HIDIsValidElement( inIOHIDElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: validate this element
|
||||||
|
//
|
||||||
|
// Inputs: inIOHIDElementRef - the element
|
||||||
|
//
|
||||||
|
// Returns: Boolean - TRUE if this is a valid element ref
|
||||||
|
//
|
||||||
|
extern Boolean HIDIsValidElement(IOHIDElementRef inIOHIDElementRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetValue( inElementRef, inIOHIDValueScaleType )
|
||||||
|
//
|
||||||
|
// Purpose: returns the current value for an element( polling )
|
||||||
|
//
|
||||||
|
// Notes: will return 0 on error conditions which should be accounted for by application
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the element
|
||||||
|
// inIOHIDValueScaleType - scale type ( calibrated or physical )
|
||||||
|
//
|
||||||
|
// Returns: double - current value for element
|
||||||
|
//
|
||||||
|
extern double IOHIDElement_GetValue(IOHIDElementRef inElementRef, IOHIDValueScaleType inIOHIDValueScaleType);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationMin( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the minimum bounds for a calibrated value for this element
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: CFIndex - the minimum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
extern CFIndex IOHIDElement_GetCalibrationMin(IOHIDElementRef inElementRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationMin( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the minimum bounds for a calibrated value for this element
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the minimum bounds for a calibrated value for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
extern void IOHIDElement_SetCalibrationMin(IOHIDElementRef inElementRef, CFIndex inValue);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationMax( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the maximum bounds for a calibrated value for this element
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: CFIndex - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
extern CFIndex IOHIDElement_GetCalibrationMax(IOHIDElementRef inElementRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationMax( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the maximum bounds for a calibrated value for this element
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
extern void IOHIDElement_SetCalibrationMax(IOHIDElementRef inElementRef, CFIndex inValue);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationSaturationMin( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the mininum tolerance to be used when calibrating a logical element value
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: CFIndex - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
extern CFIndex IOHIDElement_GetCalibrationSaturationMin(IOHIDElementRef inElementRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationSaturationMin( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the mininum tolerance to be used when calibrating a logical element value
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
extern void IOHIDElement_SetCalibrationSaturationMin(IOHIDElementRef inElementRef, CFIndex inValue);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationSaturationMax( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the maximum tolerance to be used when calibrating a logical element value
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: CFIndex - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
extern CFIndex IOHIDElement_GetCalibrationSaturationMax(IOHIDElementRef inElementRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationSaturationMax( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the maximum tolerance to be used when calibrating a logical element value
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
extern void IOHIDElement_SetCalibrationSaturationMax(IOHIDElementRef inElementRef, CFIndex inValue);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationDeadZoneMin( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the minimum bounds near the midpoint of a logical value in which the value is ignored
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: CFIndex - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
extern CFIndex IOHIDElement_GetCalibrationDeadZoneMin(IOHIDElementRef inElementRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationDeadZoneMin( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the minimum bounds near the midpoint of a logical value in which the value is ignored
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
extern void IOHIDElement_SetCalibrationDeadZoneMin(IOHIDElementRef inElementRef, CFIndex inValue);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationDeadZoneMax( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the maximum bounds near the midpoint of a logical value in which the value is ignored
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: CFIndex - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
extern CFIndex IOHIDElement_GetCalibrationDeadZoneMax(IOHIDElementRef inElementRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationDeadZoneMax( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the maximum bounds near the midpoint of a logical value in which the value is ignored
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
extern void IOHIDElement_SetCalibrationDeadZoneMax(IOHIDElementRef inElementRef, CFIndex inValue);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_GetCalibrationGranularity( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: get the level of detail returned for a calibrated element value
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: double_t - the maximum Calibration value for this element
|
||||||
|
//
|
||||||
|
|
||||||
|
extern double_t IOHIDElement_GetCalibrationGranularity(IOHIDElementRef inElementRef);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetCalibrationGranularity( inElementRef, inValue )
|
||||||
|
//
|
||||||
|
// Purpose: set the level of detail returned for a calibrated element value
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
// inValue - the the level of detail for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
extern void IOHIDElement_SetCalibrationGranularity(IOHIDElementRef inElementRef, double_t inValue);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// IOHIDElement_SetupCalibration( inElementRef )
|
||||||
|
//
|
||||||
|
// Purpose: set default values for the element calibration parameters
|
||||||
|
//
|
||||||
|
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||||
|
//
|
||||||
|
// Returns: nothing
|
||||||
|
//
|
||||||
|
|
||||||
|
extern void IOHIDElement_SetupCalibration(IOHIDElementRef inIOHIDElementRef);
|
||||||
|
|
||||||
|
extern Boolean IOHIDElement_GetLongProperty(IOHIDElementRef inElementRef, CFStringRef inKey, long *outValue);
|
||||||
|
extern void IOHIDElement_SetLongProperty(IOHIDElementRef inElementRef, CFStringRef inKey, long inValue);
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#if PRAGMA_STRUCT_ALIGN
|
||||||
|
#pragma options align=reset
|
||||||
|
#elif PRAGMA_STRUCT_PACKPUSH
|
||||||
|
#pragma pack(pop)
|
||||||
|
#elif PRAGMA_STRUCT_PACK
|
||||||
|
#pragma pack()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PRAGMA_IMPORT_OFF
|
||||||
|
#pragma import off
|
||||||
|
#elif PRAGMA_IMPORT
|
||||||
|
#pragma import reset
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __IOHIDElement___ //
|
111
src/cocoa/IOHIDLib_.h
Normal file
111
src/cocoa/IOHIDLib_.h
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
// File: IOHIDLib_.h
|
||||||
|
// Abstract: Single include file for all header files of IOHIDLib
|
||||||
|
// Version: 2.0
|
||||||
|
//
|
||||||
|
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||||
|
// Inc. ("Apple") in consideration of your agreement to the following
|
||||||
|
// terms, and your use, installation, modification or redistribution of
|
||||||
|
// this Apple software constitutes acceptance of these terms. If you do
|
||||||
|
// not agree with these terms, please do not use, install, modify or
|
||||||
|
// redistribute this Apple software.
|
||||||
|
//
|
||||||
|
// In consideration of your agreement to abide by the following terms, and
|
||||||
|
// subject to these terms, Apple grants you a personal, non-exclusive
|
||||||
|
// license, under Apple's copyrights in this original Apple software (the
|
||||||
|
// "Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||||
|
// Software, with or without modifications, in source and/or binary forms;
|
||||||
|
// provided that if you redistribute the Apple Software in its entirety and
|
||||||
|
// without modifications, you must retain this notice and the following
|
||||||
|
// text and disclaimers in all such redistributions of the Apple Software.
|
||||||
|
// Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||||
|
// be used to endorse or promote products derived from the Apple Software
|
||||||
|
// without specific prior written permission from Apple. Except as
|
||||||
|
// expressly stated in this notice, no other rights or licenses, express or
|
||||||
|
// implied, are granted by Apple herein, including but not limited to any
|
||||||
|
// patent rights that may be infringed by your derivative works or by other
|
||||||
|
// works in which the Apple Software may be incorporated.
|
||||||
|
//
|
||||||
|
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||||
|
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||||
|
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||||
|
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
//
|
||||||
|
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||||
|
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||||
|
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||||
|
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||||
|
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//*****************************************************
|
||||||
|
#ifndef __IOHIDLib___
|
||||||
|
#define __IOHIDLib___
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - includes & imports
|
||||||
|
//-----------------------------------------------------
|
||||||
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
|
|
||||||
|
#include "IOHIDDevice_.h"
|
||||||
|
#include "IOHIDElement_.h"
|
||||||
|
|
||||||
|
#include "ImmrHIDUtilAddOn.h"
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#if PRAGMA_ONCE
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PRAGMA_IMPORT
|
||||||
|
#pragma import on
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PRAGMA_STRUCT_ALIGN
|
||||||
|
#pragma options align=mac68k
|
||||||
|
#elif PRAGMA_STRUCT_PACKPUSH
|
||||||
|
#pragma pack(push, 2)
|
||||||
|
#elif PRAGMA_STRUCT_PACK
|
||||||
|
#pragma pack(2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - typedef's, struct's, enums, defines, etc.
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - exported globals
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#pragma mark - exported function prototypes
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
#if PRAGMA_STRUCT_ALIGN
|
||||||
|
#pragma options align=reset
|
||||||
|
#elif PRAGMA_STRUCT_PACKPUSH
|
||||||
|
#pragma pack(pop)
|
||||||
|
#elif PRAGMA_STRUCT_PACK
|
||||||
|
#pragma pack()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PRAGMA_IMPORT_OFF
|
||||||
|
#pragma import off
|
||||||
|
#elif PRAGMA_IMPORT
|
||||||
|
#pragma import reset
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __IOHIDLib___
|
108
src/cocoa/ImmrHIDUtilAddOn.c
Normal file
108
src/cocoa/ImmrHIDUtilAddOn.c
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
// File: ImmrHIDUtilAddOn.c
|
||||||
|
// Abstract: Glue code to convert IOHIDDeviceRef's to (FFB) io_object_t's
|
||||||
|
// Version: 2.0
|
||||||
|
//
|
||||||
|
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||||
|
// Inc. ("Apple") in consideration of your agreement to the following
|
||||||
|
// terms, and your use, installation, modification or redistribution of
|
||||||
|
// this Apple software constitutes acceptance of these terms. If you do
|
||||||
|
// not agree with these terms, please do not use, install, modify or
|
||||||
|
// redistribute this Apple software.
|
||||||
|
//
|
||||||
|
// In consideration of your agreement to abide by the following terms, and
|
||||||
|
// subject to these terms, Apple grants you a personal, non-exclusive
|
||||||
|
// license, under Apple's copyrights in this original Apple software (the
|
||||||
|
// "Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||||
|
// Software, with or without modifications, in source and/or binary forms;
|
||||||
|
// provided that if you redistribute the Apple Software in its entirety and
|
||||||
|
// without modifications, you must retain this notice and the following
|
||||||
|
// text and disclaimers in all such redistributions of the Apple Software.
|
||||||
|
// Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||||
|
// be used to endorse or promote products derived from the Apple Software
|
||||||
|
// without specific prior written permission from Apple. Except as
|
||||||
|
// expressly stated in this notice, no other rights or licenses, express or
|
||||||
|
// implied, are granted by Apple herein, including but not limited to any
|
||||||
|
// patent rights that may be infringed by your derivative works or by other
|
||||||
|
// works in which the Apple Software may be incorporated.
|
||||||
|
//
|
||||||
|
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||||
|
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||||
|
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||||
|
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
//
|
||||||
|
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||||
|
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||||
|
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||||
|
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||||
|
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//*****************************************************
|
||||||
|
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||||
|
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <mach/mach_error.h>
|
||||||
|
|
||||||
|
#include "ImmrHIDUtilAddOn.h"
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// AllocateHIDObjectFromIOHIDDeviceRef( )
|
||||||
|
//
|
||||||
|
// returns:
|
||||||
|
// NULL, or acceptable io_object_t
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
io_service_t AllocateHIDObjectFromIOHIDDeviceRef(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||||
|
io_service_t result = 0L;
|
||||||
|
if ( inIOHIDDeviceRef ) {
|
||||||
|
// Set up the matching criteria for the devices we're interested in.
|
||||||
|
// We are interested in instances of class IOHIDDevice.
|
||||||
|
// matchingDict is consumed below( in IOServiceGetMatchingService )
|
||||||
|
// so we have no leak here.
|
||||||
|
CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOHIDDeviceKey);
|
||||||
|
if ( matchingDict ) {
|
||||||
|
// Add a key for locationID to our matching dictionary. This works for matching to
|
||||||
|
// IOHIDDevices, so we will only look for a device attached to that particular port
|
||||||
|
// on the machine.
|
||||||
|
CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty( inIOHIDDeviceRef, CFSTR(kIOHIDLocationIDKey) );
|
||||||
|
if ( tCFTypeRef ) {
|
||||||
|
CFDictionaryAddValue(matchingDict, CFSTR(kIOHIDLocationIDKey), tCFTypeRef);
|
||||||
|
// CFRelease( tCFTypeRef ); // don't release objects that we "Get".
|
||||||
|
|
||||||
|
// IOServiceGetMatchingService assumes that we already know that there is only one device
|
||||||
|
// that matches. This way we don't have to do the whole iteration dance to look at each
|
||||||
|
// device that matches. This is a new API in 10.2
|
||||||
|
result = IOServiceGetMatchingService(kIOMasterPortDefault, matchingDict);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: We're not leaking the matchingDict.
|
||||||
|
// One reference is consumed by IOServiceGetMatchingServices
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
} // AllocateHIDObjectFromIOHIDDeviceRef
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// FreeHIDObject( )
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
bool FreeHIDObject(io_service_t inHIDObject) {
|
||||||
|
kern_return_t kr;
|
||||||
|
|
||||||
|
kr = IOObjectRelease(inHIDObject);
|
||||||
|
|
||||||
|
return (kIOReturnSuccess == kr);
|
||||||
|
} // FreeHIDObject
|
||||||
|
|
||||||
|
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
50
src/cocoa/ImmrHIDUtilAddOn.h
Normal file
50
src/cocoa/ImmrHIDUtilAddOn.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// File: ImmrHIDUtilAddOn.h
|
||||||
|
// Abstract: Glue code to convert IOHIDDeviceRef's to (FFB) io_object_t's
|
||||||
|
// Version: 2.0
|
||||||
|
//
|
||||||
|
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||||
|
// Inc. ("Apple") in consideration of your agreement to the following
|
||||||
|
// terms, and your use, installation, modification or redistribution of
|
||||||
|
// this Apple software constitutes acceptance of these terms. If you do
|
||||||
|
// not agree with these terms, please do not use, install, modify or
|
||||||
|
// redistribute this Apple software.
|
||||||
|
//
|
||||||
|
// In consideration of your agreement to abide by the following terms, and
|
||||||
|
// subject to these terms, Apple grants you a personal, non-exclusive
|
||||||
|
// license, under Apple's copyrights in this original Apple software (the
|
||||||
|
// "Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||||
|
// Software, with or without modifications, in source and/or binary forms;
|
||||||
|
// provided that if you redistribute the Apple Software in its entirety and
|
||||||
|
// without modifications, you must retain this notice and the following
|
||||||
|
// text and disclaimers in all such redistributions of the Apple Software.
|
||||||
|
// Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||||
|
// be used to endorse or promote products derived from the Apple Software
|
||||||
|
// without specific prior written permission from Apple. Except as
|
||||||
|
// expressly stated in this notice, no other rights or licenses, express or
|
||||||
|
// implied, are granted by Apple herein, including but not limited to any
|
||||||
|
// patent rights that may be infringed by your derivative works or by other
|
||||||
|
// works in which the Apple Software may be incorporated.
|
||||||
|
//
|
||||||
|
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||||
|
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||||
|
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||||
|
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
//
|
||||||
|
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||||
|
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||||
|
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||||
|
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||||
|
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//*****************************************************
|
||||||
|
#include <IOKit/IOKitLib.h>
|
||||||
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
|
|
||||||
|
extern io_service_t AllocateHIDObjectFromIOHIDDeviceRef(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||||
|
extern bool FreeHIDObject(io_object_t inHIDObject);
|
2171
src/cocoa/i_backend_cocoa.mm
Normal file
2171
src/cocoa/i_backend_cocoa.mm
Normal file
File diff suppressed because it is too large
Load diff
820
src/cocoa/i_joystick.cpp
Normal file
820
src/cocoa/i_joystick.cpp
Normal file
|
@ -0,0 +1,820 @@
|
||||||
|
/*
|
||||||
|
** i_joystick.cpp
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2012-2014 Alexey Lysiuk
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "m_joy.h"
|
||||||
|
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||||
|
|
||||||
|
#include "HID_Utilities_External.h"
|
||||||
|
|
||||||
|
#include "d_event.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "templates.h"
|
||||||
|
#include "i_osversion.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
FString ToFString( const CFStringRef string )
|
||||||
|
{
|
||||||
|
if ( NULL == string )
|
||||||
|
{
|
||||||
|
return FString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const CFIndex stringLength = CFStringGetLength( string );
|
||||||
|
|
||||||
|
if ( 0 == stringLength )
|
||||||
|
{
|
||||||
|
return FString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t bufferSize = CFStringGetMaximumSizeForEncoding( stringLength, kCFStringEncodingUTF8 ) + 1;
|
||||||
|
|
||||||
|
char buffer[ bufferSize ];
|
||||||
|
memset( buffer, 0, bufferSize );
|
||||||
|
|
||||||
|
CFStringGetCString( string, buffer, bufferSize, kCFStringEncodingUTF8 );
|
||||||
|
|
||||||
|
return FString( buffer );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class IOKitJoystick : public IJoystickConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit IOKitJoystick( IOHIDDeviceRef device );
|
||||||
|
virtual ~IOKitJoystick();
|
||||||
|
|
||||||
|
virtual FString GetName();
|
||||||
|
virtual float GetSensitivity();
|
||||||
|
virtual void SetSensitivity( float scale );
|
||||||
|
|
||||||
|
virtual int GetNumAxes();
|
||||||
|
virtual float GetAxisDeadZone( int axis );
|
||||||
|
virtual EJoyAxis GetAxisMap( int axis );
|
||||||
|
virtual const char* GetAxisName( int axis );
|
||||||
|
virtual float GetAxisScale( int axis );
|
||||||
|
|
||||||
|
virtual void SetAxisDeadZone( int axis, float deadZone );
|
||||||
|
virtual void SetAxisMap( int axis, EJoyAxis gameAxis );
|
||||||
|
virtual void SetAxisScale( int axis, float scale );
|
||||||
|
|
||||||
|
virtual bool IsSensitivityDefault();
|
||||||
|
virtual bool IsAxisDeadZoneDefault( int axis );
|
||||||
|
virtual bool IsAxisMapDefault( int axis );
|
||||||
|
virtual bool IsAxisScaleDefault( int axis );
|
||||||
|
|
||||||
|
virtual void SetDefaultConfig();
|
||||||
|
virtual FString GetIdentifier();
|
||||||
|
|
||||||
|
void AddAxes( float axes[ NUM_JOYAXIS ] ) const;
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
IOHIDDeviceRef m_device;
|
||||||
|
|
||||||
|
float m_sensitivity;
|
||||||
|
|
||||||
|
struct AxisInfo
|
||||||
|
{
|
||||||
|
char name[ 64 ];
|
||||||
|
|
||||||
|
float value;
|
||||||
|
|
||||||
|
float deadZone;
|
||||||
|
float defaultDeadZone;
|
||||||
|
float sensitivity;
|
||||||
|
float defaultSensitivity;
|
||||||
|
|
||||||
|
EJoyAxis gameAxis;
|
||||||
|
EJoyAxis defaultGameAxis;
|
||||||
|
|
||||||
|
IOHIDElementRef element;
|
||||||
|
};
|
||||||
|
|
||||||
|
TArray< AxisInfo > m_axes;
|
||||||
|
|
||||||
|
TArray< IOHIDElementRef > m_buttons;
|
||||||
|
TArray< IOHIDElementRef > m_POVs;
|
||||||
|
|
||||||
|
|
||||||
|
static const float DEFAULT_DEADZONE;
|
||||||
|
static const float DEFAULT_SENSITIVITY;
|
||||||
|
|
||||||
|
|
||||||
|
bool ProcessAxis ( const IOHIDValueRef value );
|
||||||
|
bool ProcessButton( const IOHIDValueRef value );
|
||||||
|
bool ProcessPOV ( const IOHIDValueRef value );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const float IOKitJoystick::DEFAULT_DEADZONE = 0.25f;
|
||||||
|
const float IOKitJoystick::DEFAULT_SENSITIVITY = 1.0f;
|
||||||
|
|
||||||
|
|
||||||
|
IOKitJoystick::IOKitJoystick( IOHIDDeviceRef device )
|
||||||
|
: m_device( device )
|
||||||
|
, m_sensitivity( DEFAULT_SENSITIVITY )
|
||||||
|
{
|
||||||
|
IOHIDElementRef element = HIDGetFirstDeviceElement( device, kHIDElementTypeInput );
|
||||||
|
|
||||||
|
while ( NULL != element )
|
||||||
|
{
|
||||||
|
const uint32_t usagePage = IOHIDElementGetUsagePage( element );
|
||||||
|
|
||||||
|
if ( kHIDPage_GenericDesktop == usagePage )
|
||||||
|
{
|
||||||
|
const uint32_t usage = IOHIDElementGetUsage( element );
|
||||||
|
|
||||||
|
if ( kHIDUsage_GD_Slider == usage
|
||||||
|
|| kHIDUsage_GD_X == usage || kHIDUsage_GD_Y == usage || kHIDUsage_GD_Z == usage
|
||||||
|
|| kHIDUsage_GD_Rx == usage || kHIDUsage_GD_Ry == usage || kHIDUsage_GD_Rz == usage )
|
||||||
|
{
|
||||||
|
AxisInfo axis;
|
||||||
|
memset( &axis, 0, sizeof( axis ) );
|
||||||
|
|
||||||
|
if ( const CFStringRef name = IOHIDElementGetName( element ) )
|
||||||
|
{
|
||||||
|
CFStringGetCString( name, axis.name, sizeof( axis.name ) - 1, kCFStringEncodingUTF8 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf( axis.name, sizeof( axis.name ), "Axis %i", m_axes.Size() + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
axis.element = element;
|
||||||
|
|
||||||
|
m_axes.Push( axis );
|
||||||
|
|
||||||
|
IOHIDElement_SetCalibrationMin( element, -1 );
|
||||||
|
IOHIDElement_SetCalibrationMax( element, 1 );
|
||||||
|
|
||||||
|
HIDQueueElement( m_device, element );
|
||||||
|
}
|
||||||
|
else if ( kHIDUsage_GD_Hatswitch == usage && m_POVs.Size() < 4 )
|
||||||
|
{
|
||||||
|
m_POVs.Push( element );
|
||||||
|
|
||||||
|
HIDQueueElement( m_device, element );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( kHIDPage_Button == usagePage )
|
||||||
|
{
|
||||||
|
m_buttons.Push( element );
|
||||||
|
|
||||||
|
HIDQueueElement( m_device, element );
|
||||||
|
}
|
||||||
|
|
||||||
|
element = HIDGetNextDeviceElement( element, kHIDElementTypeInput );
|
||||||
|
}
|
||||||
|
|
||||||
|
SetDefaultConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
IOKitJoystick::~IOKitJoystick()
|
||||||
|
{
|
||||||
|
M_SaveJoystickConfig( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FString IOKitJoystick::GetName()
|
||||||
|
{
|
||||||
|
FString result;
|
||||||
|
|
||||||
|
result += ToFString( IOHIDDevice_GetManufacturer( m_device ) );
|
||||||
|
result += " ";
|
||||||
|
result += ToFString( IOHIDDevice_GetProduct( m_device ) );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float IOKitJoystick::GetSensitivity()
|
||||||
|
{
|
||||||
|
return m_sensitivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOKitJoystick::SetSensitivity( float scale )
|
||||||
|
{
|
||||||
|
m_sensitivity = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int IOKitJoystick::GetNumAxes()
|
||||||
|
{
|
||||||
|
return static_cast< int >( m_axes.Size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IS_AXIS_VALID ( static_cast< unsigned int >( axis ) < m_axes.Size() )
|
||||||
|
|
||||||
|
float IOKitJoystick::GetAxisDeadZone( int axis )
|
||||||
|
{
|
||||||
|
return IS_AXIS_VALID ? m_axes[ axis ].deadZone : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
EJoyAxis IOKitJoystick::GetAxisMap( int axis )
|
||||||
|
{
|
||||||
|
return IS_AXIS_VALID ? m_axes[ axis ].gameAxis : JOYAXIS_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* IOKitJoystick::GetAxisName( int axis )
|
||||||
|
{
|
||||||
|
return IS_AXIS_VALID ? m_axes[ axis ].name : "Invalid";
|
||||||
|
}
|
||||||
|
|
||||||
|
float IOKitJoystick::GetAxisScale( int axis )
|
||||||
|
{
|
||||||
|
return IS_AXIS_VALID ? m_axes[ axis ].sensitivity : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOKitJoystick::SetAxisDeadZone( int axis, float deadZone )
|
||||||
|
{
|
||||||
|
if ( IS_AXIS_VALID )
|
||||||
|
{
|
||||||
|
m_axes[ axis ].deadZone = clamp( deadZone, 0.0f, 1.0f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOKitJoystick::SetAxisMap( int axis, EJoyAxis gameAxis )
|
||||||
|
{
|
||||||
|
if ( IS_AXIS_VALID )
|
||||||
|
{
|
||||||
|
m_axes[ axis ].gameAxis = ( gameAxis > JOYAXIS_None && gameAxis < NUM_JOYAXIS )
|
||||||
|
? gameAxis
|
||||||
|
: JOYAXIS_None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOKitJoystick::SetAxisScale( int axis, float scale )
|
||||||
|
{
|
||||||
|
if ( IS_AXIS_VALID )
|
||||||
|
{
|
||||||
|
m_axes[ axis ].sensitivity = scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IOKitJoystick::IsSensitivityDefault()
|
||||||
|
{
|
||||||
|
return DEFAULT_SENSITIVITY == m_sensitivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOKitJoystick::IsAxisDeadZoneDefault( int axis )
|
||||||
|
{
|
||||||
|
return IS_AXIS_VALID
|
||||||
|
? ( m_axes[ axis ].deadZone == m_axes[ axis ].defaultDeadZone )
|
||||||
|
: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOKitJoystick::IsAxisMapDefault( int axis )
|
||||||
|
{
|
||||||
|
return IS_AXIS_VALID
|
||||||
|
? ( m_axes[ axis ].gameAxis == m_axes[ axis ].defaultGameAxis )
|
||||||
|
: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOKitJoystick::IsAxisScaleDefault( int axis )
|
||||||
|
{
|
||||||
|
return IS_AXIS_VALID
|
||||||
|
? ( m_axes[ axis ].sensitivity == m_axes[ axis ].defaultSensitivity )
|
||||||
|
: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef IS_AXIS_VALID
|
||||||
|
|
||||||
|
void IOKitJoystick::SetDefaultConfig()
|
||||||
|
{
|
||||||
|
m_sensitivity = DEFAULT_SENSITIVITY;
|
||||||
|
|
||||||
|
const size_t axisCount = m_axes.Size();
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < axisCount; ++i )
|
||||||
|
{
|
||||||
|
m_axes[i].deadZone = DEFAULT_DEADZONE;
|
||||||
|
m_axes[i].sensitivity = DEFAULT_SENSITIVITY;
|
||||||
|
m_axes[i].gameAxis = JOYAXIS_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Two axes? Horizontal is yaw and vertical is forward.
|
||||||
|
|
||||||
|
if ( 2 == axisCount)
|
||||||
|
{
|
||||||
|
m_axes[0].gameAxis = JOYAXIS_Yaw;
|
||||||
|
m_axes[1].gameAxis = JOYAXIS_Forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Three axes? First two are movement, third is yaw.
|
||||||
|
|
||||||
|
else if ( axisCount >= 3 )
|
||||||
|
{
|
||||||
|
m_axes[0].gameAxis = JOYAXIS_Side;
|
||||||
|
m_axes[1].gameAxis = JOYAXIS_Forward;
|
||||||
|
m_axes[2].gameAxis = JOYAXIS_Yaw;
|
||||||
|
|
||||||
|
// Four axes? First two are movement, last two are looking around.
|
||||||
|
|
||||||
|
if ( axisCount >= 4 )
|
||||||
|
{
|
||||||
|
m_axes[3].gameAxis = JOYAXIS_Pitch;
|
||||||
|
// ??? m_axes[3].sensitivity = 0.75f;
|
||||||
|
|
||||||
|
// Five axes? Use the fifth one for moving up and down.
|
||||||
|
|
||||||
|
if ( axisCount >= 5 )
|
||||||
|
{
|
||||||
|
m_axes[4].gameAxis = JOYAXIS_Up;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is only one axis, then we make no assumptions about how
|
||||||
|
// the user might want to use it.
|
||||||
|
|
||||||
|
// Preserve defaults for config saving.
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < axisCount; ++i )
|
||||||
|
{
|
||||||
|
m_axes[i].defaultDeadZone = m_axes[i].deadZone;
|
||||||
|
m_axes[i].defaultSensitivity = m_axes[i].sensitivity;
|
||||||
|
m_axes[i].defaultGameAxis = m_axes[i].gameAxis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FString IOKitJoystick::GetIdentifier()
|
||||||
|
{
|
||||||
|
char identifier[ 32 ] = {0};
|
||||||
|
|
||||||
|
snprintf( identifier, sizeof( identifier ), "VID_%04x_PID_%04x",
|
||||||
|
IOHIDDevice_GetVendorID( m_device ), IOHIDDevice_GetProductID( m_device ) );
|
||||||
|
|
||||||
|
return FString( identifier );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IOKitJoystick::AddAxes( float axes[ NUM_JOYAXIS ] ) const
|
||||||
|
{
|
||||||
|
for ( size_t i = 0, count = m_axes.Size(); i < count; ++i )
|
||||||
|
{
|
||||||
|
const EJoyAxis axis = m_axes[i].gameAxis;
|
||||||
|
|
||||||
|
if ( JOYAXIS_None == axis )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
axes[ axis ] -= m_axes[i].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IOKitJoystick::Update()
|
||||||
|
{
|
||||||
|
IOHIDValueRef value = NULL;
|
||||||
|
|
||||||
|
while ( HIDGetEvent( m_device, &value ) && NULL != value )
|
||||||
|
{
|
||||||
|
ProcessAxis( value ) || ProcessButton( value ) || ProcessPOV( value );
|
||||||
|
|
||||||
|
CFRelease( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IOKitJoystick::ProcessAxis( const IOHIDValueRef value )
|
||||||
|
{
|
||||||
|
const IOHIDElementRef element = IOHIDValueGetElement( value );
|
||||||
|
|
||||||
|
if ( NULL == element )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( size_t i = 0, count = m_axes.Size(); i < count; ++i )
|
||||||
|
{
|
||||||
|
if ( element != m_axes[i].element )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AxisInfo& axis = m_axes[i];
|
||||||
|
|
||||||
|
const double scaledValue = IOHIDValueGetScaledValue( value, kIOHIDValueScaleTypeCalibrated );
|
||||||
|
const double filteredValue = Joy_RemoveDeadZone( scaledValue, axis.deadZone, NULL );
|
||||||
|
|
||||||
|
axis.value = static_cast< float >( filteredValue * m_sensitivity * axis.sensitivity );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOKitJoystick::ProcessButton( const IOHIDValueRef value )
|
||||||
|
{
|
||||||
|
const IOHIDElementRef element = IOHIDValueGetElement( value );
|
||||||
|
|
||||||
|
if ( NULL == element )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( size_t i = 0, count = m_buttons.Size(); i < count; ++i )
|
||||||
|
{
|
||||||
|
if ( element != m_buttons[i] )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int newButton = IOHIDValueGetIntegerValue( value ) & 1;
|
||||||
|
const int oldButton = ~newButton;
|
||||||
|
|
||||||
|
Joy_GenerateButtonEvents( oldButton, newButton, 1,
|
||||||
|
static_cast< int >( KEY_FIRSTJOYBUTTON + i ) );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOKitJoystick::ProcessPOV( const IOHIDValueRef value )
|
||||||
|
{
|
||||||
|
const IOHIDElementRef element = IOHIDValueGetElement( value );
|
||||||
|
|
||||||
|
if ( NULL == element )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( size_t i = 0, count = m_POVs.Size(); i < count; ++i )
|
||||||
|
{
|
||||||
|
if ( element != m_POVs[i] )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CFIndex direction = IOHIDValueGetIntegerValue( value );
|
||||||
|
|
||||||
|
// Default values is for Up/North
|
||||||
|
int oldButtons = 0;
|
||||||
|
int newButtons = 1;
|
||||||
|
int numButtons = 1;
|
||||||
|
int baseButton = KEY_JOYPOV1_UP;
|
||||||
|
|
||||||
|
switch ( direction )
|
||||||
|
{
|
||||||
|
case 0: // N
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: // NE
|
||||||
|
newButtons = 3;
|
||||||
|
numButtons = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // E
|
||||||
|
baseButton = KEY_JOYPOV1_RIGHT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // SE
|
||||||
|
newButtons = 3;
|
||||||
|
numButtons = 2;
|
||||||
|
baseButton = KEY_JOYPOV1_RIGHT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: // S
|
||||||
|
baseButton = KEY_JOYPOV1_DOWN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5: // SW
|
||||||
|
newButtons = 3;
|
||||||
|
numButtons = 2;
|
||||||
|
baseButton = KEY_JOYPOV1_DOWN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6: // W
|
||||||
|
baseButton = KEY_JOYPOV1_LEFT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7: // NW
|
||||||
|
newButtons = 9; // UP and LEFT
|
||||||
|
numButtons = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// release all four directions
|
||||||
|
oldButtons = 15;
|
||||||
|
newButtons = 0;
|
||||||
|
numButtons = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Joy_GenerateButtonEvents( oldButtons, newButtons, numButtons,
|
||||||
|
static_cast< int >( baseButton + i * 4 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
class IOKitJoystickManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IOKitJoystickManager();
|
||||||
|
~IOKitJoystickManager();
|
||||||
|
|
||||||
|
void GetJoysticks( TArray< IJoystickConfig* >& joysticks ) const;
|
||||||
|
|
||||||
|
void AddAxes( float axes[ NUM_JOYAXIS ] ) const;
|
||||||
|
|
||||||
|
// Updates axes/buttons states
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
// Rebuilds device list
|
||||||
|
void Rescan();
|
||||||
|
|
||||||
|
private:
|
||||||
|
TArray< IOKitJoystick* > m_joysticks;
|
||||||
|
|
||||||
|
static void OnDeviceChanged( void* context, IOReturn result, void* sender, IOHIDDeviceRef device );
|
||||||
|
|
||||||
|
void ReleaseJoysticks();
|
||||||
|
|
||||||
|
void EnableCallbacks();
|
||||||
|
void DisableCallbacks();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
IOKitJoystickManager::IOKitJoystickManager()
|
||||||
|
{
|
||||||
|
Rescan();
|
||||||
|
}
|
||||||
|
|
||||||
|
IOKitJoystickManager::~IOKitJoystickManager()
|
||||||
|
{
|
||||||
|
ReleaseJoysticks();
|
||||||
|
DisableCallbacks();
|
||||||
|
|
||||||
|
HIDReleaseDeviceList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IOKitJoystickManager::GetJoysticks( TArray< IJoystickConfig* >& joysticks ) const
|
||||||
|
{
|
||||||
|
const size_t joystickCount = m_joysticks.Size();
|
||||||
|
|
||||||
|
joysticks.Resize( joystickCount );
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < joystickCount; ++i )
|
||||||
|
{
|
||||||
|
M_LoadJoystickConfig( m_joysticks[i] );
|
||||||
|
|
||||||
|
joysticks[i] = m_joysticks[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOKitJoystickManager::AddAxes( float axes[ NUM_JOYAXIS ] ) const
|
||||||
|
{
|
||||||
|
for ( size_t i = 0, count = m_joysticks.Size(); i < count; ++i )
|
||||||
|
{
|
||||||
|
m_joysticks[i]->AddAxes( axes );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IOKitJoystickManager::Update()
|
||||||
|
{
|
||||||
|
for ( size_t i = 0, count = m_joysticks.Size(); i < count; ++i )
|
||||||
|
{
|
||||||
|
m_joysticks[i]->Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IOKitJoystickManager::Rescan()
|
||||||
|
{
|
||||||
|
ReleaseJoysticks();
|
||||||
|
DisableCallbacks();
|
||||||
|
|
||||||
|
const int usageCount = 2;
|
||||||
|
|
||||||
|
const UInt32 usagePages[ usageCount ] =
|
||||||
|
{
|
||||||
|
kHIDPage_GenericDesktop,
|
||||||
|
kHIDPage_GenericDesktop
|
||||||
|
};
|
||||||
|
|
||||||
|
const UInt32 usages[ usageCount ] =
|
||||||
|
{
|
||||||
|
kHIDUsage_GD_Joystick,
|
||||||
|
kHIDUsage_GD_GamePad
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( HIDUpdateDeviceList( usagePages, usages, usageCount ) )
|
||||||
|
{
|
||||||
|
IOHIDDeviceRef device = HIDGetFirstDevice();
|
||||||
|
|
||||||
|
while ( NULL != device )
|
||||||
|
{
|
||||||
|
IOKitJoystick* joystick = new IOKitJoystick( device );
|
||||||
|
m_joysticks.Push( joystick );
|
||||||
|
|
||||||
|
device = HIDGetNextDevice( device );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Printf( "IOKitJoystickManager: Failed to build gamepad/joystick device list.\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
EnableCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IOKitJoystickManager::OnDeviceChanged( void* context, IOReturn result, void* sender, IOHIDDeviceRef device )
|
||||||
|
{
|
||||||
|
event_t event;
|
||||||
|
|
||||||
|
memset( &event, 0, sizeof( event ) );
|
||||||
|
event.type = EV_DeviceChange;
|
||||||
|
|
||||||
|
D_PostEvent( &event );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IOKitJoystickManager::ReleaseJoysticks()
|
||||||
|
{
|
||||||
|
for ( size_t i = 0, count = m_joysticks.Size(); i < count; ++i )
|
||||||
|
{
|
||||||
|
delete m_joysticks[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_joysticks.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IOKitJoystickManager::EnableCallbacks()
|
||||||
|
{
|
||||||
|
if ( NULL == gIOHIDManagerRef )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDManagerRegisterDeviceMatchingCallback( gIOHIDManagerRef, OnDeviceChanged, this );
|
||||||
|
IOHIDManagerRegisterDeviceRemovalCallback ( gIOHIDManagerRef, OnDeviceChanged, this );
|
||||||
|
IOHIDManagerScheduleWithRunLoop( gIOHIDManagerRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode );
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOKitJoystickManager::DisableCallbacks()
|
||||||
|
{
|
||||||
|
if ( NULL == gIOHIDManagerRef )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDManagerUnscheduleFromRunLoop( gIOHIDManagerRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode );
|
||||||
|
IOHIDManagerRegisterDeviceMatchingCallback( gIOHIDManagerRef, NULL, NULL );
|
||||||
|
IOHIDManagerRegisterDeviceRemovalCallback ( gIOHIDManagerRef, NULL, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IOKitJoystickManager* s_joystickManager;
|
||||||
|
|
||||||
|
|
||||||
|
} // unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
void I_StartupJoysticks()
|
||||||
|
{
|
||||||
|
// HID Manager API is available on 10.5 (Darwin 9.x) or newer
|
||||||
|
|
||||||
|
if (darwinVersion.major >= 9)
|
||||||
|
{
|
||||||
|
s_joystickManager = new IOKitJoystickManager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ShutdownJoysticks()
|
||||||
|
{
|
||||||
|
delete s_joystickManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_GetJoysticks( TArray< IJoystickConfig* >& sticks )
|
||||||
|
{
|
||||||
|
if ( NULL != s_joystickManager )
|
||||||
|
{
|
||||||
|
s_joystickManager->GetJoysticks( sticks );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_GetAxes( float axes[ NUM_JOYAXIS ] )
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < NUM_JOYAXIS; ++i )
|
||||||
|
{
|
||||||
|
axes[i] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( use_joystick && NULL != s_joystickManager )
|
||||||
|
{
|
||||||
|
s_joystickManager->AddAxes( axes );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IJoystickConfig* I_UpdateDeviceList()
|
||||||
|
{
|
||||||
|
if ( use_joystick && NULL != s_joystickManager )
|
||||||
|
{
|
||||||
|
s_joystickManager->Rescan();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
void I_ProcessJoysticks()
|
||||||
|
{
|
||||||
|
if ( use_joystick && NULL != s_joystickManager )
|
||||||
|
{
|
||||||
|
s_joystickManager->Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // prior to 10.5
|
||||||
|
|
||||||
|
void I_StartupJoysticks()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ShutdownJoysticks()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_GetJoysticks(TArray<IJoystickConfig*>& sticks)
|
||||||
|
{
|
||||||
|
sticks.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_GetAxes(float axes[NUM_JOYAXIS])
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < NUM_JOYAXIS; ++i)
|
||||||
|
{
|
||||||
|
axes[i] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IJoystickConfig *I_UpdateDeviceList()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ProcessJoysticks()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // 10.5 or higher
|
43
src/cocoa/i_osversion.h
Executable file
43
src/cocoa/i_osversion.h
Executable file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
** i_osversion.h
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2012-2014 Alexey Lysiuk
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct DarwinVersion
|
||||||
|
{
|
||||||
|
uint16_t major;
|
||||||
|
uint16_t minor;
|
||||||
|
uint16_t bugfix;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const DarwinVersion darwinVersion;
|
52
src/cocoa/i_rbopts.h
Normal file
52
src/cocoa/i_rbopts.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
** i_rbopts.h
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2014 Alexey Lysiuk
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRC_COCOA_I_RBOPTS_H_INCLUDED
|
||||||
|
#define SRC_COCOA_I_RBOPTS_H_INCLUDED
|
||||||
|
|
||||||
|
struct RenderBufferOptions
|
||||||
|
{
|
||||||
|
float pixelScale;
|
||||||
|
|
||||||
|
float shiftX;
|
||||||
|
float shiftY;
|
||||||
|
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
|
||||||
|
bool dirty;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern RenderBufferOptions rbOpts;
|
||||||
|
|
||||||
|
#endif // SRC_COCOA_I_RBOPTS_H_INCLUDED
|
190
src/cocoa/i_timer.cpp
Normal file
190
src/cocoa/i_timer.cpp
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <libkern/OSAtomic.h>
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include "basictypes.h"
|
||||||
|
#include "basicinlines.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "templates.h"
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int I_MSTime()
|
||||||
|
{
|
||||||
|
return SDL_GetTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int I_FPSTime()
|
||||||
|
{
|
||||||
|
return SDL_GetTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool g_isTicFrozen;
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
timespec GetNextTickTime()
|
||||||
|
{
|
||||||
|
static const long MILLISECONDS_IN_SECOND = 1000;
|
||||||
|
static const long MICROSECONDS_IN_SECOND = 1000 * MILLISECONDS_IN_SECOND;
|
||||||
|
static const long NANOSECONDS_IN_SECOND = 1000 * MICROSECONDS_IN_SECOND;
|
||||||
|
|
||||||
|
static timespec ts = {};
|
||||||
|
|
||||||
|
if (__builtin_expect((0 == ts.tv_sec), 0))
|
||||||
|
{
|
||||||
|
timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
|
||||||
|
ts.tv_sec = tv.tv_sec;
|
||||||
|
ts.tv_nsec = (tv.tv_usec + MICROSECONDS_IN_SECOND / TICRATE) * MILLISECONDS_IN_SECOND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ts.tv_nsec += (MICROSECONDS_IN_SECOND / TICRATE) * MILLISECONDS_IN_SECOND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ts.tv_nsec >= NANOSECONDS_IN_SECOND)
|
||||||
|
{
|
||||||
|
ts.tv_sec++;
|
||||||
|
ts.tv_nsec -= NANOSECONDS_IN_SECOND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pthread_cond_t s_timerEvent;
|
||||||
|
pthread_mutex_t s_timerMutex;
|
||||||
|
pthread_t s_timerThread;
|
||||||
|
|
||||||
|
bool s_timerInitialized;
|
||||||
|
bool s_timerExitRequested;
|
||||||
|
|
||||||
|
uint32_t s_ticStart;
|
||||||
|
uint32_t s_timerStart;
|
||||||
|
|
||||||
|
int s_tics;
|
||||||
|
|
||||||
|
|
||||||
|
void* TimerThreadFunc(void*)
|
||||||
|
{
|
||||||
|
assert(s_timerInitialized);
|
||||||
|
assert(!s_timerExitRequested);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (s_timerExitRequested)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timespec timeToNextTick = GetNextTickTime();
|
||||||
|
|
||||||
|
pthread_mutex_lock(&s_timerMutex);
|
||||||
|
pthread_cond_timedwait(&s_timerEvent, &s_timerMutex, &timeToNextTick);
|
||||||
|
|
||||||
|
if (!g_isTicFrozen)
|
||||||
|
{
|
||||||
|
// The following GCC/Clang intrinsic can be used instead of OS X specific function:
|
||||||
|
// __sync_add_and_fetch(&s_tics, 1);
|
||||||
|
// Although it's not supported on all platform/compiler combination,
|
||||||
|
// e.g. GCC 4.0.1 with PowerPC target architecture
|
||||||
|
|
||||||
|
OSAtomicIncrement32(&s_tics);
|
||||||
|
}
|
||||||
|
|
||||||
|
s_timerStart = SDL_GetTicks();
|
||||||
|
|
||||||
|
pthread_cond_broadcast(&s_timerEvent);
|
||||||
|
pthread_mutex_unlock(&s_timerMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetTimeThreaded(bool saveMS)
|
||||||
|
{
|
||||||
|
if (saveMS)
|
||||||
|
{
|
||||||
|
s_ticStart = s_timerStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_tics;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WaitForTicThreaded(int prevTic)
|
||||||
|
{
|
||||||
|
assert(!g_isTicFrozen);
|
||||||
|
|
||||||
|
while (s_tics <= prevTic)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&s_timerMutex);
|
||||||
|
pthread_cond_wait(&s_timerEvent, &s_timerMutex);
|
||||||
|
pthread_mutex_unlock(&s_timerMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_tics;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreezeTimeThreaded(bool frozen)
|
||||||
|
{
|
||||||
|
g_isTicFrozen = frozen;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
|
fixed_t I_GetTimeFrac(uint32* ms)
|
||||||
|
{
|
||||||
|
const uint32_t now = SDL_GetTicks();
|
||||||
|
|
||||||
|
if (NULL != ms)
|
||||||
|
{
|
||||||
|
*ms = s_ticStart + 1000 / TICRATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0 == s_ticStart
|
||||||
|
? FRACUNIT
|
||||||
|
: clamp<fixed_t>( (now - s_ticStart) * FRACUNIT * TICRATE / 1000, 0, FRACUNIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void I_InitTimer ()
|
||||||
|
{
|
||||||
|
assert(!s_timerInitialized);
|
||||||
|
s_timerInitialized = true;
|
||||||
|
|
||||||
|
pthread_cond_init (&s_timerEvent, NULL);
|
||||||
|
pthread_mutex_init(&s_timerMutex, NULL);
|
||||||
|
|
||||||
|
pthread_create(&s_timerThread, NULL, TimerThreadFunc, NULL);
|
||||||
|
|
||||||
|
I_GetTime = GetTimeThreaded;
|
||||||
|
I_WaitForTic = WaitForTicThreaded;
|
||||||
|
I_FreezeTime = FreezeTimeThreaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ShutdownTimer ()
|
||||||
|
{
|
||||||
|
if (!s_timerInitialized)
|
||||||
|
{
|
||||||
|
// This might happen if Cancel button was pressed
|
||||||
|
// in the IWAD selector window
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_timerExitRequested = true;
|
||||||
|
|
||||||
|
pthread_join(s_timerThread, NULL);
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&s_timerMutex);
|
||||||
|
pthread_cond_destroy (&s_timerEvent);
|
||||||
|
}
|
47
src/cocoa/zdoom-info.plist
Normal file
47
src/cocoa/zdoom-info.plist
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>English</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>zdoom.icns</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>org.zdoom.zdoom</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>ZDoom</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>Version 2.8.0</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>LSApplicationCategoryType</key>
|
||||||
|
<string>public.app-category.action-games</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>10.4</string>
|
||||||
|
<key>CFBundleDocumentTypes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleTypeName</key>
|
||||||
|
<string>Doom Resource File</string>
|
||||||
|
<key>CFBundleTypeRole</key>
|
||||||
|
<string>Viewer</string>
|
||||||
|
<key>CFBundleTypeExtensions</key>
|
||||||
|
<array>
|
||||||
|
<string>wad</string>
|
||||||
|
<string>pk3</string>
|
||||||
|
<string>zip</string>
|
||||||
|
<string>pk7</string>
|
||||||
|
<string>7z</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string>NSApplication</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
BIN
src/cocoa/zdoom.icns
Normal file
BIN
src/cocoa/zdoom.icns
Normal file
Binary file not shown.
|
@ -145,12 +145,20 @@ bool CT_Responder (event_t *ev)
|
||||||
CT_BackSpace ();
|
CT_BackSpace ();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#ifdef __APPLE__
|
||||||
|
else if (ev->data1 == 'C' && (ev->data3 & GKM_META))
|
||||||
|
#else // !__APPLE__
|
||||||
else if (ev->data1 == 'C' && (ev->data3 & GKM_CTRL))
|
else if (ev->data1 == 'C' && (ev->data3 & GKM_CTRL))
|
||||||
|
#endif // __APPLE__
|
||||||
{
|
{
|
||||||
I_PutInClipboard ((char *)ChatQueue);
|
I_PutInClipboard ((char *)ChatQueue);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#ifdef __APPLE__
|
||||||
|
else if (ev->data1 == 'V' && (ev->data3 & GKM_META))
|
||||||
|
#else // !__APPLE__
|
||||||
else if (ev->data1 == 'V' && (ev->data3 & GKM_CTRL))
|
else if (ev->data1 == 'V' && (ev->data3 & GKM_CTRL))
|
||||||
|
#endif // __APPLE__
|
||||||
{
|
{
|
||||||
CT_PasteChat(I_GetFromClipboard(false));
|
CT_PasteChat(I_GetFromClipboard(false));
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,8 @@ enum GUIKeyModifiers
|
||||||
GKM_SHIFT = 1,
|
GKM_SHIFT = 1,
|
||||||
GKM_CTRL = 2,
|
GKM_CTRL = 2,
|
||||||
GKM_ALT = 4,
|
GKM_ALT = 4,
|
||||||
GKM_LBUTTON = 8
|
GKM_META = 8,
|
||||||
|
GKM_LBUTTON = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special codes for some GUI keys, including a few real ASCII codes.
|
// Special codes for some GUI keys, including a few real ASCII codes.
|
||||||
|
|
|
@ -1128,11 +1128,8 @@ void G_Ticker ()
|
||||||
// check, not just the player's x position like BOOM.
|
// check, not just the player's x position like BOOM.
|
||||||
DWORD rngsum = FRandom::StaticSumSeeds ();
|
DWORD rngsum = FRandom::StaticSumSeeds ();
|
||||||
|
|
||||||
if ((gametic % ticdup) == 0)
|
//Added by MC: For some of that bot stuff. The main bot function.
|
||||||
{
|
bglobal.Main ();
|
||||||
//Added by MC: For some of that bot stuff. The main bot function.
|
|
||||||
bglobal.Main (buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
@ -1395,7 +1392,6 @@ void G_PlayerReborn (int player)
|
||||||
|
|
||||||
if (gamestate != GS_TITLELEVEL)
|
if (gamestate != GS_TITLELEVEL)
|
||||||
{
|
{
|
||||||
|
|
||||||
// [GRB] Give inventory specified in DECORATE
|
// [GRB] Give inventory specified in DECORATE
|
||||||
actor->GiveDefaultInventory ();
|
actor->GiveDefaultInventory ();
|
||||||
p->ReadyWeapon = p->PendingWeapon;
|
p->ReadyWeapon = p->PendingWeapon;
|
||||||
|
@ -1406,6 +1402,7 @@ void G_PlayerReborn (int player)
|
||||||
{
|
{
|
||||||
botskill_t skill = p->Bot->skill;
|
botskill_t skill = p->Bot->skill;
|
||||||
p->Bot->Clear ();
|
p->Bot->Clear ();
|
||||||
|
p->Bot->player = p;
|
||||||
p->Bot->skill = skill;
|
p->Bot->skill = skill;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1164,6 +1164,8 @@ void G_StartTravel ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bglobal.StartTravel ();
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1261,6 +1263,8 @@ void G_FinishTravel ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bglobal.FinishTravel ();
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -52,7 +52,7 @@ class FScanner;
|
||||||
#define GCC_YSEG
|
#define GCC_YSEG
|
||||||
#else
|
#else
|
||||||
#define MSVC_YSEG
|
#define MSVC_YSEG
|
||||||
#define GCC_YSEG __attribute__((section(SECTION_YREG)))
|
#define GCC_YSEG __attribute__((section(SECTION_YREG))) __attribute__((used))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct FIntermissionDescriptor;
|
struct FIntermissionDescriptor;
|
||||||
|
|
|
@ -516,7 +516,14 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
||||||
// with the dragon skin bracers.
|
// with the dragon skin bracers.
|
||||||
if (damage < 10000)
|
if (damage < 10000)
|
||||||
{
|
{
|
||||||
|
#if __APPLE__ && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 1
|
||||||
|
// -O1 optimizer bug work around. Only needed for
|
||||||
|
// GCC 4.2.1 on OS X for 10.4/10.5 tools compatibility.
|
||||||
|
volatile fixed_t tmp = 300;
|
||||||
|
Slots[i] -= Scale (damage, SlotsIncrement[i], tmp);
|
||||||
|
#else
|
||||||
Slots[i] -= Scale (damage, SlotsIncrement[i], 300);
|
Slots[i] -= Scale (damage, SlotsIncrement[i], 300);
|
||||||
|
#endif
|
||||||
if (Slots[i] < 2*FRACUNIT)
|
if (Slots[i] < 2*FRACUNIT)
|
||||||
{
|
{
|
||||||
Slots[i] = 0;
|
Slots[i] = 0;
|
||||||
|
|
|
@ -1024,7 +1024,7 @@ void AInventory::Touch (AActor *toucher)
|
||||||
//Added by MC: Check if item taken was the roam destination of any bot
|
//Added by MC: Check if item taken was the roam destination of any bot
|
||||||
for (int i = 0; i < MAXPLAYERS; i++)
|
for (int i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (playeringame[i] && players[i].Bot != NULL && this == players[i].Bot->dest)
|
if (players[i].Bot != NULL && this == players[i].Bot->dest)
|
||||||
players[i].Bot->dest = NULL;
|
players[i].Bot->dest = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ static inline SDWORD Scale (SDWORD a, SDWORD b, SDWORD c)
|
||||||
: "a,a,a,a,a,a" (a),
|
: "a,a,a,a,a,a" (a),
|
||||||
"m,r,m,r,d,d" (b),
|
"m,r,m,r,d,d" (b),
|
||||||
"r,r,m,m,r,m" (c)
|
"r,r,m,m,r,m" (c)
|
||||||
: "%cc"
|
: "cc"
|
||||||
);
|
);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -59,7 +59,7 @@ static inline SDWORD MulScale (SDWORD a, SDWORD b, SDWORD c)
|
||||||
: "a,a,a,a" (a),
|
: "a,a,a,a" (a),
|
||||||
"m,r,m,r" (b),
|
"m,r,m,r" (b),
|
||||||
"c,c,I,I" (c)
|
"c,c,I,I" (c)
|
||||||
: "%cc"
|
: "cc"
|
||||||
);
|
);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ static inline SDWORD DivScale (SDWORD a, SDWORD b, SDWORD c)
|
||||||
: "a" (lo),
|
: "a" (lo),
|
||||||
"d" (hi),
|
"d" (hi),
|
||||||
"r" (b)
|
"r" (b)
|
||||||
: "%cc");
|
: "cc");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ static inline SDWORD DivScale1 (SDWORD a, SDWORD b)
|
||||||
"=&d,d" (dummy)
|
"=&d,d" (dummy)
|
||||||
: "a,a" (a),
|
: "a,a" (a),
|
||||||
"r,m" (b)
|
"r,m" (b)
|
||||||
: "%cc");
|
: "cc");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ static inline SDWORD DivScale1 (SDWORD a, SDWORD b)
|
||||||
: "a,a" (a<<s), \
|
: "a,a" (a<<s), \
|
||||||
"d,d" (a>>(32-s)), \
|
"d,d" (a>>(32-s)), \
|
||||||
"r,m" (b) \
|
"r,m" (b) \
|
||||||
: "%cc"); \
|
: "cc"); \
|
||||||
return result; \
|
return result; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ static inline SDWORD DivScale32 (SDWORD a, SDWORD b)
|
||||||
"=d,d" (dummy)
|
"=d,d" (dummy)
|
||||||
: "d,d" (a),
|
: "d,d" (a),
|
||||||
"r,m" (b)
|
"r,m" (b)
|
||||||
: "%cc");
|
: "cc");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ static inline void clearbufshort (void *buff, unsigned int count, WORD clear)
|
||||||
"rep stosw"
|
"rep stosw"
|
||||||
:"=D" (buff), "=c" (count)
|
:"=D" (buff), "=c" (count)
|
||||||
:"D" (buff), "c" (count), "a" (clear|(clear<<16))
|
:"D" (buff), "c" (count), "a" (clear|(clear<<16))
|
||||||
:"%cc");
|
:"cc");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline SDWORD ksgn (SDWORD a)
|
static inline SDWORD ksgn (SDWORD a)
|
||||||
|
@ -327,6 +327,6 @@ static inline SDWORD ksgn (SDWORD a)
|
||||||
"adc $0,%1"
|
"adc $0,%1"
|
||||||
:"=r" (dummy), "=r" (result)
|
:"=r" (dummy), "=r" (result)
|
||||||
:"0" (a)
|
:"0" (a)
|
||||||
:"%cc");
|
:"cc");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,13 @@ static const int PO_LINE_EXPLICIT = 5;
|
||||||
angle_t FNodeBuilder::PointToAngle (fixed_t x, fixed_t y)
|
angle_t FNodeBuilder::PointToAngle (fixed_t x, fixed_t y)
|
||||||
{
|
{
|
||||||
const double rad2bam = double(1<<30) / M_PI;
|
const double rad2bam = double(1<<30) / M_PI;
|
||||||
|
#if defined __APPLE__ && !defined __llvm__
|
||||||
|
// Work-around for vectorization issue in Apple's GCC 4.x
|
||||||
|
// See https://gcc.gnu.org/wiki/Math_Optimization_Flags for details
|
||||||
|
long double ang = atan2l (double(y), double(x));
|
||||||
|
#else // !__APPLE__ || __llvm__
|
||||||
double ang = atan2 (double(y), double(x));
|
double ang = atan2 (double(y), double(x));
|
||||||
|
#endif // __APPLE__ && !__llvm__
|
||||||
return angle_t(ang * rad2bam) << 1;
|
return angle_t(ang * rad2bam) << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -323,7 +323,7 @@ int OPLio::OPLinit(uint numchips, bool stereo, bool initopl3)
|
||||||
{
|
{
|
||||||
assert(numchips >= 1 && numchips <= countof(chips));
|
assert(numchips >= 1 && numchips <= countof(chips));
|
||||||
uint i;
|
uint i;
|
||||||
IsOPL3 = (opl_core == 1 || opl_core == 2);
|
IsOPL3 = (opl_core == 1 || opl_core == 2 || opl_core == 3);
|
||||||
|
|
||||||
memset(chips, 0, sizeof(chips));
|
memset(chips, 0, sizeof(chips));
|
||||||
if (IsOPL3)
|
if (IsOPL3)
|
||||||
|
@ -332,7 +332,7 @@ int OPLio::OPLinit(uint numchips, bool stereo, bool initopl3)
|
||||||
}
|
}
|
||||||
for (i = 0; i < numchips; ++i)
|
for (i = 0; i < numchips; ++i)
|
||||||
{
|
{
|
||||||
OPLEmul *chip = IsOPL3 ? (opl_core == 1 ? DBOPLCreate(stereo) : JavaOPLCreate(stereo)) : YM3812Create(stereo);
|
OPLEmul *chip = IsOPL3 ? (opl_core == 1 ? DBOPLCreate(stereo) : (opl_core == 2 ? JavaOPLCreate(stereo) : NukedOPL3Create(stereo))) : YM3812Create(stereo);
|
||||||
if (chip == NULL)
|
if (chip == NULL)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
1147
src/oplsynth/nukedopl3.cpp
Normal file
1147
src/oplsynth/nukedopl3.cpp
Normal file
File diff suppressed because it is too large
Load diff
120
src/oplsynth/nukedopl3.h
Normal file
120
src/oplsynth/nukedopl3.h
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013-2014 Nuke.YKT
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Nuked Yamaha YMF262(aka OPL3) emulator.
|
||||||
|
Thanks:
|
||||||
|
MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh):
|
||||||
|
Feedback and Rhythm part calculation information.
|
||||||
|
forums.submarine.org.uk(carbon14, opl3):
|
||||||
|
Tremolo and phase generator calculation information.
|
||||||
|
OPLx decapsulated(Matthew Gambrell and Olli Niemitalo):
|
||||||
|
OPL2 ROMs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//version 1.4.2
|
||||||
|
|
||||||
|
#include "opl.h"
|
||||||
|
#include "muslib.h"
|
||||||
|
|
||||||
|
typedef uintptr_t Bitu;
|
||||||
|
typedef intptr_t Bits;
|
||||||
|
typedef DWORD Bit32u;
|
||||||
|
typedef SDWORD Bit32s;
|
||||||
|
typedef WORD Bit16u;
|
||||||
|
typedef SWORD Bit16s;
|
||||||
|
typedef BYTE Bit8u;
|
||||||
|
typedef SBYTE Bit8s;
|
||||||
|
|
||||||
|
struct channel {
|
||||||
|
Bit8u con;
|
||||||
|
Bit8u chtype;
|
||||||
|
Bit8u alg;
|
||||||
|
Bit16u offset;
|
||||||
|
Bit8u feedback;
|
||||||
|
Bit16u cha, chb, chc, chd;
|
||||||
|
Bit16s out;
|
||||||
|
Bit16u f_number;
|
||||||
|
Bit8u block;
|
||||||
|
Bit8u ksv;
|
||||||
|
float panl;
|
||||||
|
float panr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct slot {
|
||||||
|
Bit32u PG_pos;
|
||||||
|
Bit32u PG_inc;
|
||||||
|
Bit16s EG_out;
|
||||||
|
Bit8u eg_inc;
|
||||||
|
Bit8u eg_gen;
|
||||||
|
Bit8u eg_gennext;
|
||||||
|
Bit16u EG_mout;
|
||||||
|
Bit8u EG_ksl;
|
||||||
|
Bit8u EG_ar;
|
||||||
|
Bit8u EG_dr;
|
||||||
|
Bit8u EG_sl;
|
||||||
|
Bit8u EG_rr;
|
||||||
|
Bit8u EG_state;
|
||||||
|
Bit8u EG_type;
|
||||||
|
Bit16s out;
|
||||||
|
Bit16s *mod;
|
||||||
|
Bit16s prevout[2];
|
||||||
|
Bit16s fbmod;
|
||||||
|
Bit16u offset;
|
||||||
|
Bit8u mult;
|
||||||
|
Bit8u vibrato;
|
||||||
|
Bit8u tremolo;
|
||||||
|
Bit8u ksr;
|
||||||
|
Bit8u EG_tl;
|
||||||
|
Bit8u ksl;
|
||||||
|
Bit8u key;
|
||||||
|
Bit8u waveform;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct chip {
|
||||||
|
Bit8u opl_memory[0x200];
|
||||||
|
Bit8u newm;
|
||||||
|
Bit8u nts;
|
||||||
|
Bit8u rhythm;
|
||||||
|
Bit8u dvb;
|
||||||
|
Bit8u dam;
|
||||||
|
Bit32u noise;
|
||||||
|
Bit16u vib_pos;
|
||||||
|
Bit16u timer;
|
||||||
|
Bit8u trem_inc;
|
||||||
|
Bit8u trem_tval;
|
||||||
|
Bit8u trem_dir;
|
||||||
|
Bit8u trem_val;
|
||||||
|
channel Channels[18];
|
||||||
|
slot OPs[36];
|
||||||
|
Bit16s zm;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NukedOPL3 : public OPLEmul {
|
||||||
|
private:
|
||||||
|
chip opl3;
|
||||||
|
bool FullPan;
|
||||||
|
public:
|
||||||
|
void Reset();
|
||||||
|
void Update(float* sndptr, int numsamples);
|
||||||
|
void WriteReg(int reg, int v);
|
||||||
|
void SetPanning(int c, float left, float right);
|
||||||
|
|
||||||
|
NukedOPL3(bool stereo);
|
||||||
|
};
|
|
@ -20,6 +20,7 @@ public:
|
||||||
OPLEmul *YM3812Create(bool stereo);
|
OPLEmul *YM3812Create(bool stereo);
|
||||||
OPLEmul *DBOPLCreate(bool stereo);
|
OPLEmul *DBOPLCreate(bool stereo);
|
||||||
OPLEmul *JavaOPLCreate(bool stereo);
|
OPLEmul *JavaOPLCreate(bool stereo);
|
||||||
|
OPLEmul *NukedOPL3Create(bool stereo);
|
||||||
|
|
||||||
#define OPL_SAMPLE_RATE 49716.0
|
#define OPL_SAMPLE_RATE 49716.0
|
||||||
#define CENTER_PANNING_POWER 0.70710678118 /* [RH] volume at center for EQP */
|
#define CENTER_PANNING_POWER 0.70710678118 /* [RH] volume at center for EQP */
|
||||||
|
|
|
@ -1581,20 +1581,28 @@ void FBehavior::StaticSerializeModuleStates (FArchive &arc)
|
||||||
for (modnum = 0; modnum < StaticModules.Size(); ++modnum)
|
for (modnum = 0; modnum < StaticModules.Size(); ++modnum)
|
||||||
{
|
{
|
||||||
FBehavior *module = StaticModules[modnum];
|
FBehavior *module = StaticModules[modnum];
|
||||||
|
int ModSize = module->GetDataSize();
|
||||||
|
|
||||||
if (arc.IsStoring())
|
if (arc.IsStoring())
|
||||||
{
|
{
|
||||||
arc.WriteString (module->ModuleName);
|
arc.WriteString (module->ModuleName);
|
||||||
|
if (SaveVersion >= 4516) arc << ModSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *modname = NULL;
|
char *modname = NULL;
|
||||||
arc << modname;
|
arc << modname;
|
||||||
|
if (SaveVersion >= 4516) arc << ModSize;
|
||||||
if (stricmp (modname, module->ModuleName) != 0)
|
if (stricmp (modname, module->ModuleName) != 0)
|
||||||
{
|
{
|
||||||
delete[] modname;
|
delete[] modname;
|
||||||
I_Error ("Level was saved with a different set of ACS modules.");
|
I_Error ("Level was saved with a different set of ACS modules.");
|
||||||
}
|
}
|
||||||
|
else if (ModSize != module->GetDataSize())
|
||||||
|
{
|
||||||
|
delete[] modname;
|
||||||
|
I_Error("ACS module %s has changed from what was saved. (Have %d bytes, save has %d bytes)", module->ModuleName, module->GetDataSize(), ModSize);
|
||||||
|
}
|
||||||
delete[] modname;
|
delete[] modname;
|
||||||
}
|
}
|
||||||
module->SerializeVars (arc);
|
module->SerializeVars (arc);
|
||||||
|
@ -1873,7 +1881,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
|
||||||
funcm->HasReturnValue = funcf->HasReturnValue;
|
funcm->HasReturnValue = funcf->HasReturnValue;
|
||||||
funcm->ImportNum = funcf->ImportNum;
|
funcm->ImportNum = funcf->ImportNum;
|
||||||
funcm->LocalCount = funcf->LocalCount;
|
funcm->LocalCount = funcf->LocalCount;
|
||||||
funcm->Address = funcf->Address;
|
funcm->Address = LittleLong(funcf->Address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2058,7 +2066,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
|
||||||
const char *const parse = (char *)&chunk[2];
|
const char *const parse = (char *)&chunk[2];
|
||||||
DWORD i;
|
DWORD i;
|
||||||
|
|
||||||
for (i = 0; i < chunk[1]; )
|
for (i = 0; i < LittleLong(chunk[1]); )
|
||||||
{
|
{
|
||||||
if (parse[i])
|
if (parse[i])
|
||||||
{
|
{
|
||||||
|
@ -2351,7 +2359,7 @@ void FBehavior::LoadScriptsDirectory ()
|
||||||
scripts.b = FindChunk (MAKE_ID('S','F','L','G'));
|
scripts.b = FindChunk (MAKE_ID('S','F','L','G'));
|
||||||
if (scripts.dw != NULL)
|
if (scripts.dw != NULL)
|
||||||
{
|
{
|
||||||
max = scripts.dw[1] / 4;
|
max = LittleLong(scripts.dw[1]) / 4;
|
||||||
scripts.dw += 2;
|
scripts.dw += 2;
|
||||||
for (i = max; i > 0; --i, scripts.w += 2)
|
for (i = max; i > 0; --i, scripts.w += 2)
|
||||||
{
|
{
|
||||||
|
@ -2367,7 +2375,7 @@ void FBehavior::LoadScriptsDirectory ()
|
||||||
scripts.b = FindChunk (MAKE_ID('S','V','C','T'));
|
scripts.b = FindChunk (MAKE_ID('S','V','C','T'));
|
||||||
if (scripts.dw != NULL)
|
if (scripts.dw != NULL)
|
||||||
{
|
{
|
||||||
max = scripts.dw[1] / 4;
|
max = LittleLong(scripts.dw[1]) / 4;
|
||||||
scripts.dw += 2;
|
scripts.dw += 2;
|
||||||
for (i = max; i > 0; --i, scripts.w += 2)
|
for (i = max; i > 0; --i, scripts.w += 2)
|
||||||
{
|
{
|
||||||
|
@ -2681,7 +2689,7 @@ BYTE *FBehavior::FindChunk (DWORD id) const
|
||||||
{
|
{
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
chunk += ((DWORD *)chunk)[1] + 8;
|
chunk += LittleLong(((DWORD *)chunk)[1]) + 8;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2689,14 +2697,14 @@ BYTE *FBehavior::FindChunk (DWORD id) const
|
||||||
BYTE *FBehavior::NextChunk (BYTE *chunk) const
|
BYTE *FBehavior::NextChunk (BYTE *chunk) const
|
||||||
{
|
{
|
||||||
DWORD id = *(DWORD *)chunk;
|
DWORD id = *(DWORD *)chunk;
|
||||||
chunk += ((DWORD *)chunk)[1] + 8;
|
chunk += LittleLong(((DWORD *)chunk)[1]) + 8;
|
||||||
while (chunk != NULL && chunk < Data + DataSize)
|
while (chunk != NULL && chunk < Data + DataSize)
|
||||||
{
|
{
|
||||||
if (((DWORD *)chunk)[0] == id)
|
if (((DWORD *)chunk)[0] == id)
|
||||||
{
|
{
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
chunk += ((DWORD *)chunk)[1] + 8;
|
chunk += LittleLong(((DWORD *)chunk)[1]) + 8;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -3673,6 +3681,7 @@ enum
|
||||||
APROP_AttackZOffset = 40,
|
APROP_AttackZOffset = 40,
|
||||||
APROP_StencilColor = 41,
|
APROP_StencilColor = 41,
|
||||||
APROP_Friction = 42,
|
APROP_Friction = 42,
|
||||||
|
APROP_DamageMultiplier=43,
|
||||||
};
|
};
|
||||||
|
|
||||||
// These are needed for ACS's APROP_RenderStyle
|
// These are needed for ACS's APROP_RenderStyle
|
||||||
|
@ -3862,6 +3871,10 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
|
||||||
actor->DamageFactor = value;
|
actor->DamageFactor = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case APROP_DamageMultiplier:
|
||||||
|
actor->DamageMultiply = value;
|
||||||
|
break;
|
||||||
|
|
||||||
case APROP_MasterTID:
|
case APROP_MasterTID:
|
||||||
AActor *other;
|
AActor *other;
|
||||||
other = SingleActorFromTID (value, NULL);
|
other = SingleActorFromTID (value, NULL);
|
||||||
|
@ -3933,6 +3946,7 @@ int DLevelScript::GetActorProperty (int tid, int property, const SDWORD *stack,
|
||||||
case APROP_Speed: return actor->Speed;
|
case APROP_Speed: return actor->Speed;
|
||||||
case APROP_Damage: return actor->Damage; // Should this call GetMissileDamage() instead?
|
case APROP_Damage: return actor->Damage; // Should this call GetMissileDamage() instead?
|
||||||
case APROP_DamageFactor:return actor->DamageFactor;
|
case APROP_DamageFactor:return actor->DamageFactor;
|
||||||
|
case APROP_DamageMultiplier: return actor->DamageMultiply;
|
||||||
case APROP_Alpha: return actor->alpha;
|
case APROP_Alpha: return actor->alpha;
|
||||||
case APROP_RenderStyle: for (int style = STYLE_None; style < STYLE_Count; ++style)
|
case APROP_RenderStyle: for (int style = STYLE_None; style < STYLE_Count; ++style)
|
||||||
{ // Check for a legacy render style that matches.
|
{ // Check for a legacy render style that matches.
|
||||||
|
|
|
@ -308,6 +308,7 @@ public:
|
||||||
int GetScriptIndex (const ScriptPtr *ptr) const { ptrdiff_t index = ptr - Scripts; return index >= NumScripts ? -1 : (int)index; }
|
int GetScriptIndex (const ScriptPtr *ptr) const { ptrdiff_t index = ptr - Scripts; return index >= NumScripts ? -1 : (int)index; }
|
||||||
ScriptPtr *GetScriptPtr(int index) const { return index >= 0 && index < NumScripts ? &Scripts[index] : NULL; }
|
ScriptPtr *GetScriptPtr(int index) const { return index >= 0 && index < NumScripts ? &Scripts[index] : NULL; }
|
||||||
int GetLumpNum() const { return LumpNum; }
|
int GetLumpNum() const { return LumpNum; }
|
||||||
|
int GetDataSize() const { return DataSize; }
|
||||||
const char *GetModuleName() const { return ModuleName; }
|
const char *GetModuleName() const { return ModuleName; }
|
||||||
ACSProfileInfo *GetFunctionProfileData(int index) { return index >= 0 && index < NumFunctions ? &FunctionProfileData[index] : NULL; }
|
ACSProfileInfo *GetFunctionProfileData(int index) { return index >= 0 && index < NumFunctions ? &FunctionProfileData[index] : NULL; }
|
||||||
ACSProfileInfo *GetFunctionProfileData(ScriptFunction *func) { return GetFunctionProfileData((int)(func - (ScriptFunction *)Functions)); }
|
ACSProfileInfo *GetFunctionProfileData(ScriptFunction *func) { return GetFunctionProfileData((int)(func - (ScriptFunction *)Functions)); }
|
||||||
|
|
|
@ -925,6 +925,11 @@ static inline bool MustForcePain(AActor *target, AActor *inflictor)
|
||||||
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS));
|
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool isFakePain(AActor *target, AActor *inflictor)
|
||||||
|
{
|
||||||
|
return ((target->flags7 & MF7_ALLOWPAIN) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns the amount of damage actually inflicted upon the target, or -1 if
|
// Returns the amount of damage actually inflicted upon the target, or -1 if
|
||||||
// the damage was cancelled.
|
// the damage was cancelled.
|
||||||
|
@ -940,6 +945,8 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
bool justhit = false;
|
bool justhit = false;
|
||||||
bool plrDontThrust = false;
|
bool plrDontThrust = false;
|
||||||
bool invulpain = false;
|
bool invulpain = false;
|
||||||
|
bool fakedPain = false;
|
||||||
|
bool forcedPain = false;
|
||||||
int fakeDamage = 0;
|
int fakeDamage = 0;
|
||||||
int holdDamage = 0;
|
int holdDamage = 0;
|
||||||
|
|
||||||
|
@ -948,6 +955,10 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Rather than unnecessarily call the function over and over again, let's be a little more efficient.
|
||||||
|
fakedPain = (isFakePain(target, inflictor));
|
||||||
|
forcedPain = (MustForcePain(target, inflictor));
|
||||||
|
|
||||||
// Spectral targets only take damage from spectral projectiles.
|
// Spectral targets only take damage from spectral projectiles.
|
||||||
if (target->flags4 & MF4_SPECTRAL && damage < TELEFRAG_DAMAGE)
|
if (target->flags4 & MF4_SPECTRAL && damage < TELEFRAG_DAMAGE)
|
||||||
{
|
{
|
||||||
|
@ -976,7 +987,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
{
|
{
|
||||||
if (inflictor == NULL || (!(inflictor->flags3 & MF3_FOILINVUL) && !(flags & DMG_FOILINVUL)))
|
if (inflictor == NULL || (!(inflictor->flags3 & MF3_FOILINVUL) && !(flags & DMG_FOILINVUL)))
|
||||||
{
|
{
|
||||||
if ((target->flags7 & MF7_ALLOWPAIN) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN)))
|
if (fakedPain)
|
||||||
{
|
{
|
||||||
invulpain = true; //This returns -1 later.
|
invulpain = true; //This returns -1 later.
|
||||||
fakeDamage = damage;
|
fakeDamage = damage;
|
||||||
|
@ -991,7 +1002,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
// Players are optionally excluded from getting thrust by damage.
|
// Players are optionally excluded from getting thrust by damage.
|
||||||
if (static_cast<APlayerPawn *>(target)->PlayerFlags & PPF_NOTHRUSTWHENINVUL)
|
if (static_cast<APlayerPawn *>(target)->PlayerFlags & PPF_NOTHRUSTWHENINVUL)
|
||||||
{
|
{
|
||||||
if ((target->flags7 & MF7_ALLOWPAIN) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN)))
|
if (fakedPain)
|
||||||
plrDontThrust = 1;
|
plrDontThrust = 1;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -999,7 +1010,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (((target->flags7 & MF7_ALLOWPAIN) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN))) && (damage < TELEFRAG_DAMAGE))
|
if ((fakedPain) && (damage < TELEFRAG_DAMAGE))
|
||||||
{
|
{
|
||||||
//Intentionally do not jump to fakepain because the damage hasn't been dished out yet.
|
//Intentionally do not jump to fakepain because the damage hasn't been dished out yet.
|
||||||
//Once it's dished out, THEN we can disregard damage factors affecting pain chances.
|
//Once it's dished out, THEN we can disregard damage factors affecting pain chances.
|
||||||
|
@ -1057,24 +1068,31 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
if (damage > 0)
|
if (damage > 0)
|
||||||
damage = inflictor->DoSpecialDamage (target, damage, mod);
|
damage = inflictor->DoSpecialDamage (target, damage, mod);
|
||||||
|
|
||||||
if (damage == -1)
|
if ((damage == -1) && (target->player == NULL)) //This isn't meant for the player.
|
||||||
{
|
{
|
||||||
if ((target->flags7 & MF7_ALLOWPAIN) || (inflictor->flags7 & MF7_CAUSEPAIN)) //Hold off ending the function before we can deal the pain chances.
|
if (fakedPain) //Hold off ending the function before we can deal the pain chances.
|
||||||
goto fakepain;
|
goto fakepain;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handle active damage modifiers (e.g. PowerDamage)
|
// Handle active damage modifiers (e.g. PowerDamage)
|
||||||
if (source != NULL && source->Inventory != NULL)
|
if (source != NULL)
|
||||||
{
|
{
|
||||||
int olddam = damage;
|
int olddam = damage;
|
||||||
source->Inventory->ModifyDamage(olddam, mod, damage, false);
|
|
||||||
if (olddam != damage && damage <= 0)
|
if (source->Inventory != NULL)
|
||||||
|
{
|
||||||
|
source->Inventory->ModifyDamage(olddam, mod, damage, false);
|
||||||
|
}
|
||||||
|
damage = FixedMul(damage, source->DamageMultiply);
|
||||||
|
|
||||||
|
if (((source->flags7 & MF7_CAUSEPAIN) && (fakeDamage <= 0)) || (olddam != damage && damage <= 0))
|
||||||
{ // Still allow FORCEPAIN
|
{ // Still allow FORCEPAIN
|
||||||
if (MustForcePain(target, inflictor))
|
if (forcedPain)
|
||||||
{
|
|
||||||
goto dopain;
|
goto dopain;
|
||||||
}
|
else if (fakedPain)
|
||||||
|
goto fakepain;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1083,13 +1101,11 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
{
|
{
|
||||||
int olddam = damage;
|
int olddam = damage;
|
||||||
target->Inventory->ModifyDamage(olddam, mod, damage, true);
|
target->Inventory->ModifyDamage(olddam, mod, damage, true);
|
||||||
if (((target->flags7 & MF7_ALLOWPAIN) && (fakeDamage <= 0)) || (olddam != damage && damage <= 0))
|
if ((olddam != damage && damage <= 0) && target->player == NULL)
|
||||||
{ // Still allow FORCEPAIN and make sure we're still passing along fake damage to hit enemies for their pain states.
|
{ // Still allow FORCEPAIN and make sure we're still passing along fake damage to hit enemies for their pain states.
|
||||||
if (MustForcePain(target, inflictor))
|
if (forcedPain)
|
||||||
{
|
|
||||||
goto dopain;
|
goto dopain;
|
||||||
}
|
else if (fakedPain)
|
||||||
else if ((target->flags7 & MF7_ALLOWPAIN) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN)))
|
|
||||||
goto fakepain;
|
goto fakepain;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1103,13 +1119,11 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
{
|
{
|
||||||
damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, mod, target->GetClass()->ActorInfo->DamageFactors);
|
damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, mod, target->GetClass()->ActorInfo->DamageFactors);
|
||||||
}
|
}
|
||||||
if (damage <= 0)
|
if (damage <= 0 && target->player == NULL)
|
||||||
{ // Still allow FORCEPAIN
|
{ // Still allow FORCEPAIN
|
||||||
if (MustForcePain(target, inflictor))
|
if (forcedPain)
|
||||||
{
|
|
||||||
goto dopain;
|
goto dopain;
|
||||||
}
|
else if (fakedPain)
|
||||||
else if ((target->flags7 & MF7_ALLOWPAIN) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN)))
|
|
||||||
goto fakepain;
|
goto fakepain;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1118,9 +1132,9 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
if (damage > 0)
|
if (damage > 0)
|
||||||
damage = target->TakeSpecialDamage (inflictor, source, damage, mod);
|
damage = target->TakeSpecialDamage (inflictor, source, damage, mod);
|
||||||
}
|
}
|
||||||
if (damage == -1)
|
if (damage == -1 && target->player == NULL) //Make sure it's not a player, the pain has yet to be processed with cheats.
|
||||||
{
|
{
|
||||||
if ((target->flags7 & MF7_ALLOWPAIN) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN)))
|
if (fakedPain)
|
||||||
goto fakepain;
|
goto fakepain;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1247,17 +1261,18 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
(player->cheats & CF_GODMODE2) || (player->mo->flags5 & MF5_NODAMAGE))
|
(player->cheats & CF_GODMODE2) || (player->mo->flags5 & MF5_NODAMAGE))
|
||||||
//Absolutely no hurting if NODAMAGE is involved. Same for GODMODE2.
|
//Absolutely no hurting if NODAMAGE is involved. Same for GODMODE2.
|
||||||
{ // player is invulnerable, so don't hurt him
|
{ // player is invulnerable, so don't hurt him
|
||||||
|
|
||||||
if (((!(player->cheats & CF_GODMODE)) && (!(player->cheats & CF_GODMODE2)) && (!(player->mo->flags5 & MF5_NOPAIN))) &&
|
|
||||||
(((player->mo->flags7 & MF7_ALLOWPAIN) || (player->mo->flags5 & MF5_NODAMAGE)) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN))))
|
|
||||||
//Make sure no godmodes and NOPAIN flags are found first.
|
//Make sure no godmodes and NOPAIN flags are found first.
|
||||||
//Then, check to see if the player has NODAMAGE or ALLOWPAIN, or inflictor has CAUSEPAIN.
|
//Then, check to see if the player has NODAMAGE or ALLOWPAIN, or inflictor has CAUSEPAIN.
|
||||||
{
|
if ((player->cheats & CF_GODMODE) || (player->cheats & CF_GODMODE2) || (player->mo->flags5 & MF5_NOPAIN))
|
||||||
|
return -1;
|
||||||
|
else if ((((player->mo->flags7 & MF7_ALLOWPAIN) || (player->mo->flags5 & MF5_NODAMAGE)) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN))))
|
||||||
|
{
|
||||||
invulpain = true;
|
invulpain = true;
|
||||||
fakeDamage = damage;
|
fakeDamage = damage;
|
||||||
goto fakepain;
|
goto fakepain;
|
||||||
}
|
}
|
||||||
return -1;
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(flags & DMG_NO_ARMOR) && player->mo->Inventory != NULL)
|
if (!(flags & DMG_NO_ARMOR) && player->mo->Inventory != NULL)
|
||||||
|
@ -1306,6 +1321,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
// telefrag him right? ;) (Unfortunately the damage is "absorbed" by armor,
|
// telefrag him right? ;) (Unfortunately the damage is "absorbed" by armor,
|
||||||
// but telefragging should still do enough damage to kill the player)
|
// but telefragging should still do enough damage to kill the player)
|
||||||
// Ignore players that are already dead.
|
// Ignore players that are already dead.
|
||||||
|
// [MC]Buddha2 absorbs telefrag damage, and anything else thrown their way.
|
||||||
if ((player->cheats & CF_BUDDHA2) || (((player->cheats & CF_BUDDHA) || (player->mo->flags7 & MF7_BUDDHA)) && (damage < TELEFRAG_DAMAGE)) && (player->playerstate != PST_DEAD))
|
if ((player->cheats & CF_BUDDHA2) || (((player->cheats & CF_BUDDHA) || (player->mo->flags7 & MF7_BUDDHA)) && (damage < TELEFRAG_DAMAGE)) && (player->playerstate != PST_DEAD))
|
||||||
{
|
{
|
||||||
// If this is a voodoo doll we need to handle the real player as well.
|
// If this is a voodoo doll we need to handle the real player as well.
|
||||||
|
@ -1339,7 +1355,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
damage = newdam;
|
damage = newdam;
|
||||||
if (damage <= 0)
|
if (damage <= 0)
|
||||||
{
|
{
|
||||||
if ((target->flags7 & MF7_ALLOWPAIN) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN)))
|
if (fakedPain)
|
||||||
goto fakepain;
|
goto fakepain;
|
||||||
else
|
else
|
||||||
return damage;
|
return damage;
|
||||||
|
@ -1370,6 +1386,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
||||||
|
|
||||||
if (target->health <= 0)
|
if (target->health <= 0)
|
||||||
{
|
{
|
||||||
|
//[MC]Buddha flag for monsters.
|
||||||
if ((target->flags7 & MF7_BUDDHA) && (damage < TELEFRAG_DAMAGE) && ((inflictor == NULL || !(inflictor->flags3 & MF7_FOILBUDDHA)) && !(flags & DMG_FOILBUDDHA)))
|
if ((target->flags7 & MF7_BUDDHA) && (damage < TELEFRAG_DAMAGE) && ((inflictor == NULL || !(inflictor->flags3 & MF7_FOILBUDDHA)) && !(flags & DMG_FOILBUDDHA)))
|
||||||
{ //FOILBUDDHA or Telefrag damage must kill it.
|
{ //FOILBUDDHA or Telefrag damage must kill it.
|
||||||
target->health = 1;
|
target->health = 1;
|
||||||
|
@ -1434,7 +1451,7 @@ fakepain: //Needed so we can skip the rest of the above, but still obey the orig
|
||||||
//CAUSEPAIN can always attempt to trigger the chances of pain.
|
//CAUSEPAIN can always attempt to trigger the chances of pain.
|
||||||
//ALLOWPAIN can do the same, only if the (unfiltered aka fake) damage is greater than 0.
|
//ALLOWPAIN can do the same, only if the (unfiltered aka fake) damage is greater than 0.
|
||||||
if ((((target->flags7 & MF7_ALLOWPAIN) && (fakeDamage > 0))
|
if ((((target->flags7 & MF7_ALLOWPAIN) && (fakeDamage > 0))
|
||||||
|| ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN))) && (fakeDamage != damage))
|
|| ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN))))
|
||||||
{
|
{
|
||||||
holdDamage = damage; //Store the modified damage away after factors are taken into account.
|
holdDamage = damage; //Store the modified damage away after factors are taken into account.
|
||||||
damage = fakeDamage; //Retrieve the original damage.
|
damage = fakeDamage; //Retrieve the original damage.
|
||||||
|
@ -1535,7 +1552,7 @@ dopain:
|
||||||
{
|
{
|
||||||
return -1; //NOW we return -1!
|
return -1; //NOW we return -1!
|
||||||
}
|
}
|
||||||
else if ((target->flags7 & MF7_ALLOWPAIN) || ((inflictor != NULL) && (inflictor->flags7 & MF7_CAUSEPAIN)))
|
else if (fakedPain)
|
||||||
{
|
{
|
||||||
return holdDamage; //This is the calculated damage after all is said and done.
|
return holdDamage; //This is the calculated damage after all is said and done.
|
||||||
}
|
}
|
||||||
|
|
|
@ -736,8 +736,18 @@ bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm)
|
||||||
else
|
else
|
||||||
{ // Find the point on the line closest to the actor's center, and use
|
{ // Find the point on the line closest to the actor's center, and use
|
||||||
// that to calculate openings
|
// that to calculate openings
|
||||||
SQWORD r_den = (SQWORD(ld->dx)*ld->dx + SQWORD(ld->dy)*ld->dy) / (1 << 24);
|
// [EP] Use 64 bit integers in order to keep the exact result of the
|
||||||
|
// multiplication, because in the worst case, which is by the map limit
|
||||||
|
// (32767 units, which is 2147418112 in fixed_t notation), the result
|
||||||
|
// would occupy 62 bits (if I consider also the addition with another
|
||||||
|
// and possible 62 bit value, it's 63 bits).
|
||||||
|
// This privilege could not be available if the starting data would be
|
||||||
|
// 64 bit long.
|
||||||
|
// With this, the division is exact as the 32 bit float counterpart,
|
||||||
|
// though I don't know why I had to discard the first 24 bits from the
|
||||||
|
// divisor.
|
||||||
SQWORD r_num = ((SQWORD(tm.x - ld->v1->x)*ld->dx) + (SQWORD(tm.y - ld->v1->y)*ld->dy));
|
SQWORD r_num = ((SQWORD(tm.x - ld->v1->x)*ld->dx) + (SQWORD(tm.y - ld->v1->y)*ld->dy));
|
||||||
|
SQWORD r_den = (SQWORD(ld->dx)*ld->dx + SQWORD(ld->dy)*ld->dy) / (1 << 24);
|
||||||
fixed_t r = (fixed_t)(r_num / r_den);
|
fixed_t r = (fixed_t)(r_num / r_den);
|
||||||
/* Printf ("%d:%d: %d (%d %d %d %d) (%d %d %d %d)\n", level.time, ld-lines, r,
|
/* Printf ("%d:%d: %d (%d %d %d %d) (%d %d %d %d)\n", level.time, ld-lines, r,
|
||||||
ld->frontsector->floorplane.a,
|
ld->frontsector->floorplane.a,
|
||||||
|
|
|
@ -84,7 +84,6 @@ static void PlayerLandedOnThing (AActor *mo, AActor *onmobj);
|
||||||
|
|
||||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||||
|
|
||||||
extern cycle_t BotSupportCycles;
|
|
||||||
extern int BotWTG;
|
extern int BotWTG;
|
||||||
EXTERN_CVAR (Int, cl_rockettrails)
|
EXTERN_CVAR (Int, cl_rockettrails)
|
||||||
|
|
||||||
|
@ -313,8 +312,16 @@ void AActor::Serialize (FArchive &arc)
|
||||||
}
|
}
|
||||||
arc << lastpush << lastbump
|
arc << lastpush << lastbump
|
||||||
<< PainThreshold
|
<< PainThreshold
|
||||||
<< DamageFactor
|
<< DamageFactor;
|
||||||
<< WeaveIndexXY << WeaveIndexZ
|
if (SaveVersion >= 4516)
|
||||||
|
{
|
||||||
|
arc << DamageMultiply;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DamageMultiply = FRACUNIT;
|
||||||
|
}
|
||||||
|
arc << WeaveIndexXY << WeaveIndexZ
|
||||||
<< PoisonDamageReceived << PoisonDurationReceived << PoisonPeriodReceived << Poisoner
|
<< PoisonDamageReceived << PoisonDurationReceived << PoisonPeriodReceived << Poisoner
|
||||||
<< PoisonDamage << PoisonDuration << PoisonPeriod;
|
<< PoisonDamage << PoisonDuration << PoisonPeriod;
|
||||||
if (SaveVersion >= 3235)
|
if (SaveVersion >= 3235)
|
||||||
|
@ -3868,6 +3875,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
|
||||||
actor->touching_sectorlist = NULL; // NULL head of sector list // phares 3/13/98
|
actor->touching_sectorlist = NULL; // NULL head of sector list // phares 3/13/98
|
||||||
if (G_SkillProperty(SKILLP_FastMonsters))
|
if (G_SkillProperty(SKILLP_FastMonsters))
|
||||||
actor->Speed = actor->GetClass()->Meta.GetMetaFixed(AMETA_FastSpeed, actor->Speed);
|
actor->Speed = actor->GetClass()->Meta.GetMetaFixed(AMETA_FastSpeed, actor->Speed);
|
||||||
|
actor->DamageMultiply = FRACUNIT;
|
||||||
|
|
||||||
|
|
||||||
// set subsector and/or block links
|
// set subsector and/or block links
|
||||||
|
|
|
@ -4175,7 +4175,6 @@ static void P_Shutdown ()
|
||||||
P_FreeLevelData ();
|
P_FreeLevelData ();
|
||||||
P_FreeExtraLevelData ();
|
P_FreeExtraLevelData ();
|
||||||
ST_Clear();
|
ST_Clear();
|
||||||
bglobal.DestroyAllBots ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -3066,7 +3066,6 @@ void player_t::Serialize (FArchive &arc)
|
||||||
if (SaveVersion < 4514 && IsBot)
|
if (SaveVersion < 4514 && IsBot)
|
||||||
{
|
{
|
||||||
Bot = new DBot;
|
Bot = new DBot;
|
||||||
GC::WriteBarrier (Bot);
|
|
||||||
|
|
||||||
arc << Bot->angle
|
arc << Bot->angle
|
||||||
<< Bot->dest
|
<< Bot->dest
|
||||||
|
@ -3089,6 +3088,12 @@ void player_t::Serialize (FArchive &arc)
|
||||||
<< Bot->oldx
|
<< Bot->oldx
|
||||||
<< Bot->oldy;
|
<< Bot->oldy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SaveVersion < 4516 && Bot != NULL)
|
||||||
|
{
|
||||||
|
Bot->player = this;
|
||||||
|
}
|
||||||
|
|
||||||
if (arc.IsLoading ())
|
if (arc.IsLoading ())
|
||||||
{
|
{
|
||||||
// If the player reloaded because they pressed +use after dying, we
|
// If the player reloaded because they pressed +use after dying, we
|
||||||
|
|
131
src/sdl/i_gui.cpp
Normal file
131
src/sdl/i_gui.cpp
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
|
||||||
|
// Moved from sdl/i_system.cpp
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include "bitmap.h"
|
||||||
|
#include "v_palette.h"
|
||||||
|
#include "textures.h"
|
||||||
|
|
||||||
|
extern SDL_Surface *cursorSurface;
|
||||||
|
extern SDL_Rect cursorBlit;
|
||||||
|
|
||||||
|
#ifdef USE_XCURSOR
|
||||||
|
// Xlib has its own GC, so don't let it interfere.
|
||||||
|
#define GC XGC
|
||||||
|
#include <X11/Xcursor/Xcursor.h>
|
||||||
|
#undef GC
|
||||||
|
|
||||||
|
bool UseXCursor;
|
||||||
|
SDL_Cursor *X11Cursor;
|
||||||
|
SDL_Cursor *FirstCursor;
|
||||||
|
|
||||||
|
// Hack! Hack! SDL does not provide a clean way to get the XDisplay.
|
||||||
|
// On the other hand, there are no more planned updates for SDL 1.2,
|
||||||
|
// so we should be fine making assumptions.
|
||||||
|
struct SDL_PrivateVideoData
|
||||||
|
{
|
||||||
|
int local_X11;
|
||||||
|
Display *X11_Display;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SDL_VideoDevice
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
int (*functions[9])();
|
||||||
|
SDL_VideoInfo info;
|
||||||
|
SDL_PixelFormat *displayformatalphapixel;
|
||||||
|
int (*morefuncs[9])();
|
||||||
|
Uint16 *gamma;
|
||||||
|
int (*somefuncs[9])();
|
||||||
|
unsigned int texture; // Only here if SDL was compiled with OpenGL support. Ack!
|
||||||
|
int is_32bit;
|
||||||
|
int (*itsafuncs[13])();
|
||||||
|
SDL_Surface *surfaces[3];
|
||||||
|
SDL_Palette *physpal;
|
||||||
|
SDL_Color *gammacols;
|
||||||
|
char *wm_strings[2];
|
||||||
|
int offsets[2];
|
||||||
|
SDL_GrabMode input_grab;
|
||||||
|
int handles_any_size;
|
||||||
|
SDL_PrivateVideoData *hidden; // Why did they have to bury this so far in?
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SDL_VideoDevice *current_video;
|
||||||
|
#define SDL_Display (current_video->hidden->X11_Display)
|
||||||
|
|
||||||
|
SDL_Cursor *CreateColorCursor(FTexture *cursorpic)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool I_SetCursor(FTexture *cursorpic)
|
||||||
|
{
|
||||||
|
if (cursorpic != NULL && cursorpic->UseType != FTexture::TEX_Null)
|
||||||
|
{
|
||||||
|
// Must be no larger than 32x32.
|
||||||
|
if (cursorpic->GetWidth() > 32 || cursorpic->GetHeight() > 32)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_XCURSOR
|
||||||
|
if (UseXCursor)
|
||||||
|
{
|
||||||
|
if (FirstCursor == NULL)
|
||||||
|
{
|
||||||
|
FirstCursor = SDL_GetCursor();
|
||||||
|
}
|
||||||
|
X11Cursor = CreateColorCursor(cursorpic);
|
||||||
|
if (X11Cursor != NULL)
|
||||||
|
{
|
||||||
|
SDL_SetCursor(X11Cursor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (cursorSurface == NULL)
|
||||||
|
cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0));
|
||||||
|
|
||||||
|
SDL_ShowCursor(0);
|
||||||
|
SDL_LockSurface(cursorSurface);
|
||||||
|
BYTE buffer[32*32*4];
|
||||||
|
memset(buffer, 0, 32*32*4);
|
||||||
|
FBitmap bmp(buffer, 32*4, 32, 32);
|
||||||
|
cursorpic->CopyTrueColorPixels(&bmp, 0, 0);
|
||||||
|
memcpy(cursorSurface->pixels, bmp.GetPixels(), 32*32*4);
|
||||||
|
SDL_UnlockSurface(cursorSurface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_ShowCursor(1);
|
||||||
|
|
||||||
|
if (cursorSurface != NULL)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(cursorSurface);
|
||||||
|
cursorSurface = NULL;
|
||||||
|
}
|
||||||
|
#ifdef USE_XCURSOR
|
||||||
|
if (X11Cursor != NULL)
|
||||||
|
{
|
||||||
|
SDL_SetCursor(FirstCursor);
|
||||||
|
SDL_FreeCursor(X11Cursor);
|
||||||
|
X11Cursor = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_SetMainWindowVisible(bool visible)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* I_GetBackEndName()
|
||||||
|
{
|
||||||
|
return "SDL";
|
||||||
|
}
|
|
@ -75,6 +75,10 @@
|
||||||
|
|
||||||
extern "C" int cc_install_handlers(int, char**, int, int*, const char*, int(*)(char*, char*));
|
extern "C" int cc_install_handlers(int, char**, int, int*, const char*, int(*)(char*, char*));
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
void Mac_I_FatalError(const char* errortext);
|
||||||
|
#endif
|
||||||
|
|
||||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||||
|
|
||||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||||
|
@ -235,6 +239,8 @@ static void unprotect_rtext()
|
||||||
void I_StartupJoysticks();
|
void I_StartupJoysticks();
|
||||||
void I_ShutdownJoysticks();
|
void I_ShutdownJoysticks();
|
||||||
|
|
||||||
|
const char* I_GetBackEndName();
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
#if !defined (__APPLE__)
|
#if !defined (__APPLE__)
|
||||||
|
@ -244,8 +250,8 @@ int main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
#endif // !__APPLE__
|
#endif // !__APPLE__
|
||||||
|
|
||||||
printf(GAMENAME" %s - %s - SDL version\nCompiled on %s\n",
|
printf(GAMENAME" %s - %s - %s version\nCompiled on %s\n",
|
||||||
GetVersionString(), GetGitTime(), __DATE__);
|
GetVersionString(), GetGitTime(), I_GetBackEndName(), __DATE__);
|
||||||
|
|
||||||
seteuid (getuid ());
|
seteuid (getuid ());
|
||||||
std::set_new_handler (NewFailure);
|
std::set_new_handler (NewFailure);
|
||||||
|
@ -356,6 +362,11 @@ int main (int argc, char **argv)
|
||||||
I_ShutdownJoysticks();
|
I_ShutdownJoysticks();
|
||||||
if (error.GetMessage ())
|
if (error.GetMessage ())
|
||||||
fprintf (stderr, "%s\n", error.GetMessage ());
|
fprintf (stderr, "%s\n", error.GetMessage ());
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
Mac_I_FatalError(error.GetMessage());
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
|
|
|
@ -71,12 +71,9 @@
|
||||||
#include "m_fixed.h"
|
#include "m_fixed.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
|
|
||||||
#ifdef USE_XCURSOR
|
#ifdef __APPLE__
|
||||||
// Xlib has its own GC, so don't let it interfere.
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
#define GC XGC
|
#endif // __APPLE__
|
||||||
#include <X11/Xcursor/Xcursor.h>
|
|
||||||
#undef GC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EXTERN_CVAR (String, language)
|
EXTERN_CVAR (String, language)
|
||||||
|
|
||||||
|
@ -91,11 +88,6 @@ extern bool GtkAvailable;
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad);
|
int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad);
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_XCURSOR
|
|
||||||
bool UseXCursor;
|
|
||||||
SDL_Cursor *X11Cursor;
|
|
||||||
SDL_Cursor *FirstCursor;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DWORD LanguageIDs[4];
|
DWORD LanguageIDs[4];
|
||||||
|
|
||||||
|
@ -122,185 +114,6 @@ void I_EndRead(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static DWORD TicStart;
|
|
||||||
static DWORD BaseTime;
|
|
||||||
static int TicFrozen;
|
|
||||||
|
|
||||||
// Signal based timer.
|
|
||||||
static Semaphore timerWait;
|
|
||||||
static int tics;
|
|
||||||
static DWORD sig_start;
|
|
||||||
|
|
||||||
void I_SelectTimer();
|
|
||||||
|
|
||||||
// [RH] Returns time in milliseconds
|
|
||||||
unsigned int I_MSTime (void)
|
|
||||||
{
|
|
||||||
unsigned int time = SDL_GetTicks ();
|
|
||||||
return time - BaseTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exactly the same thing, but based does no modification to the time.
|
|
||||||
unsigned int I_FPSTime()
|
|
||||||
{
|
|
||||||
return SDL_GetTicks();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// I_GetTime
|
|
||||||
// returns time in 1/35th second tics
|
|
||||||
//
|
|
||||||
int I_GetTimeSelect (bool saveMS)
|
|
||||||
{
|
|
||||||
I_SelectTimer();
|
|
||||||
return I_GetTime (saveMS);
|
|
||||||
}
|
|
||||||
|
|
||||||
int I_GetTimePolled (bool saveMS)
|
|
||||||
{
|
|
||||||
if (TicFrozen != 0)
|
|
||||||
{
|
|
||||||
return TicFrozen;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD tm = SDL_GetTicks();
|
|
||||||
|
|
||||||
if (saveMS)
|
|
||||||
{
|
|
||||||
TicStart = tm;
|
|
||||||
}
|
|
||||||
return Scale(tm - BaseTime, TICRATE, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
int I_GetTimeSignaled (bool saveMS)
|
|
||||||
{
|
|
||||||
if (saveMS)
|
|
||||||
{
|
|
||||||
TicStart = sig_start;
|
|
||||||
}
|
|
||||||
return tics;
|
|
||||||
}
|
|
||||||
|
|
||||||
int I_WaitForTicPolled (int prevtic)
|
|
||||||
{
|
|
||||||
int time;
|
|
||||||
|
|
||||||
assert (TicFrozen == 0);
|
|
||||||
while ((time = I_GetTimePolled(false)) <= prevtic)
|
|
||||||
;
|
|
||||||
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
int I_WaitForTicSignaled (int prevtic)
|
|
||||||
{
|
|
||||||
assert (TicFrozen == 0);
|
|
||||||
|
|
||||||
while(tics <= prevtic)
|
|
||||||
{
|
|
||||||
SEMAPHORE_WAIT(timerWait)
|
|
||||||
}
|
|
||||||
|
|
||||||
return tics;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_FreezeTimeSelect (bool frozen)
|
|
||||||
{
|
|
||||||
I_SelectTimer();
|
|
||||||
return I_FreezeTime (frozen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_FreezeTimePolled (bool frozen)
|
|
||||||
{
|
|
||||||
if (frozen)
|
|
||||||
{
|
|
||||||
assert(TicFrozen == 0);
|
|
||||||
TicFrozen = I_GetTimePolled(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(TicFrozen != 0);
|
|
||||||
int froze = TicFrozen;
|
|
||||||
TicFrozen = 0;
|
|
||||||
int now = I_GetTimePolled(false);
|
|
||||||
BaseTime += (now - froze) * 1000 / TICRATE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_FreezeTimeSignaled (bool frozen)
|
|
||||||
{
|
|
||||||
TicFrozen = frozen;
|
|
||||||
}
|
|
||||||
|
|
||||||
int I_WaitForTicSelect (int prevtic)
|
|
||||||
{
|
|
||||||
I_SelectTimer();
|
|
||||||
return I_WaitForTic (prevtic);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// I_HandleAlarm
|
|
||||||
// Should be called every time there is an alarm.
|
|
||||||
//
|
|
||||||
void I_HandleAlarm (int sig)
|
|
||||||
{
|
|
||||||
if(!TicFrozen)
|
|
||||||
tics++;
|
|
||||||
sig_start = SDL_GetTicks();
|
|
||||||
SEMAPHORE_SIGNAL(timerWait)
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// I_SelectTimer
|
|
||||||
// Sets up the timer function based on if we can use signals for efficent CPU
|
|
||||||
// usage.
|
|
||||||
//
|
|
||||||
void I_SelectTimer()
|
|
||||||
{
|
|
||||||
SEMAPHORE_INIT(timerWait, 0, 0)
|
|
||||||
#ifndef __sun
|
|
||||||
signal(SIGALRM, I_HandleAlarm);
|
|
||||||
#else
|
|
||||||
struct sigaction alrmaction;
|
|
||||||
sigaction(SIGALRM, NULL, &alrmaction);
|
|
||||||
alrmaction.sa_handler = I_HandleAlarm;
|
|
||||||
sigaction(SIGALRM, &alrmaction, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct itimerval itv;
|
|
||||||
itv.it_interval.tv_sec = itv.it_value.tv_sec = 0;
|
|
||||||
itv.it_interval.tv_usec = itv.it_value.tv_usec = 1000000/TICRATE;
|
|
||||||
|
|
||||||
if (setitimer(ITIMER_REAL, &itv, NULL) != 0)
|
|
||||||
{
|
|
||||||
I_GetTime = I_GetTimePolled;
|
|
||||||
I_FreezeTime = I_FreezeTimePolled;
|
|
||||||
I_WaitForTic = I_WaitForTicPolled;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
I_GetTime = I_GetTimeSignaled;
|
|
||||||
I_FreezeTime = I_FreezeTimeSignaled;
|
|
||||||
I_WaitForTic = I_WaitForTicSignaled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the fractional amount of a tic passed since the most recent tic
|
|
||||||
fixed_t I_GetTimeFrac (uint32 *ms)
|
|
||||||
{
|
|
||||||
DWORD now = SDL_GetTicks ();
|
|
||||||
if (ms) *ms = TicStart + (1000 / TICRATE);
|
|
||||||
if (TicStart == 0)
|
|
||||||
{
|
|
||||||
return FRACUNIT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fixed_t frac = clamp<fixed_t> ((now - TicStart)*FRACUNIT*TICRATE/1000, 0, FRACUNIT);
|
|
||||||
return frac;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_WaitVBL (int count)
|
void I_WaitVBL (int count)
|
||||||
{
|
{
|
||||||
// I_WaitVBL is never used to actually synchronize to the
|
// I_WaitVBL is never used to actually synchronize to the
|
||||||
|
@ -322,6 +135,9 @@ void SetLanguageIDs ()
|
||||||
LanguageIDs[3] = LanguageIDs[2] = LanguageIDs[1] = LanguageIDs[0] = lang;
|
LanguageIDs[3] = LanguageIDs[2] = LanguageIDs[1] = LanguageIDs[0] = lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void I_InitTimer ();
|
||||||
|
void I_ShutdownTimer ();
|
||||||
|
|
||||||
//
|
//
|
||||||
// I_Init
|
// I_Init
|
||||||
//
|
//
|
||||||
|
@ -330,11 +146,9 @@ void I_Init (void)
|
||||||
CheckCPUID (&CPU);
|
CheckCPUID (&CPU);
|
||||||
DumpCPUInfo (&CPU);
|
DumpCPUInfo (&CPU);
|
||||||
|
|
||||||
I_GetTime = I_GetTimeSelect;
|
|
||||||
I_WaitForTic = I_WaitForTicSelect;
|
|
||||||
I_FreezeTime = I_FreezeTimeSelect;
|
|
||||||
atterm (I_ShutdownSound);
|
atterm (I_ShutdownSound);
|
||||||
I_InitSound ();
|
I_InitSound ();
|
||||||
|
I_InitTimer ();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -350,6 +164,8 @@ void I_Quit (void)
|
||||||
G_CheckDemoStatus();
|
G_CheckDemoStatus();
|
||||||
|
|
||||||
C_DeinitConsole();
|
C_DeinitConsole();
|
||||||
|
|
||||||
|
I_ShutdownTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -785,6 +601,10 @@ int I_FindAttr (findstate_t *fileinfo)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
static PasteboardRef s_clipboard;
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
// Clipboard support requires GTK+
|
// Clipboard support requires GTK+
|
||||||
// TODO: GTK+ uses UTF-8. We don't, so some conversions would be appropriate.
|
// TODO: GTK+ uses UTF-8. We don't, so some conversions would be appropriate.
|
||||||
void I_PutInClipboard (const char *str)
|
void I_PutInClipboard (const char *str)
|
||||||
|
@ -805,6 +625,23 @@ void I_PutInClipboard (const char *str)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
#elif defined __APPLE__
|
||||||
|
if (NULL == s_clipboard)
|
||||||
|
{
|
||||||
|
PasteboardCreate(kPasteboardClipboard, &s_clipboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
PasteboardClear(s_clipboard);
|
||||||
|
PasteboardSynchronize(s_clipboard);
|
||||||
|
|
||||||
|
const CFDataRef textData = CFDataCreate(kCFAllocatorDefault,
|
||||||
|
reinterpret_cast<const UInt8*>(str), strlen(str));
|
||||||
|
|
||||||
|
if (NULL != textData)
|
||||||
|
{
|
||||||
|
PasteboardPutItemFlavor(s_clipboard, PasteboardItemID(1),
|
||||||
|
CFSTR("public.utf8-plain-text"), textData, 0);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -826,6 +663,61 @@ FString I_GetFromClipboard (bool use_primary_selection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined __APPLE__
|
||||||
|
FString result;
|
||||||
|
|
||||||
|
if (NULL == s_clipboard)
|
||||||
|
{
|
||||||
|
PasteboardCreate(kPasteboardClipboard, &s_clipboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
PasteboardSynchronize(s_clipboard);
|
||||||
|
|
||||||
|
ItemCount itemCount = 0;
|
||||||
|
PasteboardGetItemCount(s_clipboard, &itemCount);
|
||||||
|
|
||||||
|
if (0 == itemCount)
|
||||||
|
{
|
||||||
|
return FString();
|
||||||
|
}
|
||||||
|
|
||||||
|
PasteboardItemID itemID;
|
||||||
|
|
||||||
|
if (0 != PasteboardGetItemIdentifier(s_clipboard, 1, &itemID))
|
||||||
|
{
|
||||||
|
return FString();
|
||||||
|
}
|
||||||
|
|
||||||
|
CFArrayRef flavorTypeArray;
|
||||||
|
|
||||||
|
if (0 != PasteboardCopyItemFlavors(s_clipboard, itemID, &flavorTypeArray))
|
||||||
|
{
|
||||||
|
return FString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const CFIndex flavorCount = CFArrayGetCount(flavorTypeArray);
|
||||||
|
|
||||||
|
for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; ++flavorIndex)
|
||||||
|
{
|
||||||
|
const CFStringRef flavorType = static_cast<const CFStringRef>(
|
||||||
|
CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex));
|
||||||
|
|
||||||
|
if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text")))
|
||||||
|
{
|
||||||
|
CFDataRef flavorData;
|
||||||
|
|
||||||
|
if (0 == PasteboardCopyItemFlavorData(s_clipboard, itemID, flavorType, &flavorData))
|
||||||
|
{
|
||||||
|
result += reinterpret_cast<const char*>(CFDataGetBytePtr(flavorData));
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(flavorData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(flavorTypeArray);
|
||||||
|
|
||||||
|
return result;
|
||||||
#endif
|
#endif
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -851,104 +743,3 @@ unsigned int I_MakeRNGSeed()
|
||||||
}
|
}
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_XCURSOR
|
|
||||||
// Hack! Hack! SDL does not provide a clean way to get the XDisplay.
|
|
||||||
// On the other hand, there are no more planned updates for SDL 1.2,
|
|
||||||
// so we should be fine making assumptions.
|
|
||||||
struct SDL_PrivateVideoData
|
|
||||||
{
|
|
||||||
int local_X11;
|
|
||||||
Display *X11_Display;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SDL_VideoDevice
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
int (*functions[9])();
|
|
||||||
SDL_VideoInfo info;
|
|
||||||
SDL_PixelFormat *displayformatalphapixel;
|
|
||||||
int (*morefuncs[9])();
|
|
||||||
Uint16 *gamma;
|
|
||||||
int (*somefuncs[9])();
|
|
||||||
unsigned int texture; // Only here if SDL was compiled with OpenGL support. Ack!
|
|
||||||
int is_32bit;
|
|
||||||
int (*itsafuncs[13])();
|
|
||||||
SDL_Surface *surfaces[3];
|
|
||||||
SDL_Palette *physpal;
|
|
||||||
SDL_Color *gammacols;
|
|
||||||
char *wm_strings[2];
|
|
||||||
int offsets[2];
|
|
||||||
SDL_GrabMode input_grab;
|
|
||||||
int handles_any_size;
|
|
||||||
SDL_PrivateVideoData *hidden; // Why did they have to bury this so far in?
|
|
||||||
};
|
|
||||||
|
|
||||||
extern SDL_VideoDevice *current_video;
|
|
||||||
#define SDL_Display (current_video->hidden->X11_Display)
|
|
||||||
|
|
||||||
SDL_Cursor *CreateColorCursor(FTexture *cursorpic)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SDL_Surface *cursorSurface = NULL;
|
|
||||||
SDL_Rect cursorBlit = {0, 0, 32, 32};
|
|
||||||
bool I_SetCursor(FTexture *cursorpic)
|
|
||||||
{
|
|
||||||
if (cursorpic != NULL && cursorpic->UseType != FTexture::TEX_Null)
|
|
||||||
{
|
|
||||||
// Must be no larger than 32x32.
|
|
||||||
if (cursorpic->GetWidth() > 32 || cursorpic->GetHeight() > 32)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_XCURSOR
|
|
||||||
if (UseXCursor)
|
|
||||||
{
|
|
||||||
if (FirstCursor == NULL)
|
|
||||||
{
|
|
||||||
FirstCursor = SDL_GetCursor();
|
|
||||||
}
|
|
||||||
X11Cursor = CreateColorCursor(cursorpic);
|
|
||||||
if (X11Cursor != NULL)
|
|
||||||
{
|
|
||||||
SDL_SetCursor(X11Cursor);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (cursorSurface == NULL)
|
|
||||||
cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0));
|
|
||||||
|
|
||||||
SDL_ShowCursor(0);
|
|
||||||
SDL_LockSurface(cursorSurface);
|
|
||||||
BYTE buffer[32*32*4];
|
|
||||||
memset(buffer, 0, 32*32*4);
|
|
||||||
FBitmap bmp(buffer, 32*4, 32, 32);
|
|
||||||
cursorpic->CopyTrueColorPixels(&bmp, 0, 0);
|
|
||||||
memcpy(cursorSurface->pixels, bmp.GetPixels(), 32*32*4);
|
|
||||||
SDL_UnlockSurface(cursorSurface);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SDL_ShowCursor(1);
|
|
||||||
|
|
||||||
if (cursorSurface != NULL)
|
|
||||||
{
|
|
||||||
SDL_FreeSurface(cursorSurface);
|
|
||||||
cursorSurface = NULL;
|
|
||||||
}
|
|
||||||
#ifdef USE_XCURSOR
|
|
||||||
if (X11Cursor != NULL)
|
|
||||||
{
|
|
||||||
SDL_SetCursor(FirstCursor);
|
|
||||||
SDL_FreeCursor(X11Cursor);
|
|
||||||
X11Cursor = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
206
src/sdl/i_timer.cpp
Normal file
206
src/sdl/i_timer.cpp
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
|
||||||
|
// Moved from sdl/i_system.cpp
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include "basictypes.h"
|
||||||
|
#include "basicinlines.h"
|
||||||
|
#include "hardware.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "templates.h"
|
||||||
|
|
||||||
|
|
||||||
|
static DWORD TicStart;
|
||||||
|
static DWORD BaseTime;
|
||||||
|
static int TicFrozen;
|
||||||
|
|
||||||
|
// Signal based timer.
|
||||||
|
static Semaphore timerWait;
|
||||||
|
static int tics;
|
||||||
|
static DWORD sig_start;
|
||||||
|
|
||||||
|
void I_SelectTimer();
|
||||||
|
|
||||||
|
// [RH] Returns time in milliseconds
|
||||||
|
unsigned int I_MSTime (void)
|
||||||
|
{
|
||||||
|
unsigned int time = SDL_GetTicks ();
|
||||||
|
return time - BaseTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exactly the same thing, but based does no modification to the time.
|
||||||
|
unsigned int I_FPSTime()
|
||||||
|
{
|
||||||
|
return SDL_GetTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// I_GetTime
|
||||||
|
// returns time in 1/35th second tics
|
||||||
|
//
|
||||||
|
int I_GetTimeSelect (bool saveMS)
|
||||||
|
{
|
||||||
|
I_SelectTimer();
|
||||||
|
return I_GetTime (saveMS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int I_GetTimePolled (bool saveMS)
|
||||||
|
{
|
||||||
|
if (TicFrozen != 0)
|
||||||
|
{
|
||||||
|
return TicFrozen;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD tm = SDL_GetTicks();
|
||||||
|
|
||||||
|
if (saveMS)
|
||||||
|
{
|
||||||
|
TicStart = tm;
|
||||||
|
}
|
||||||
|
return Scale(tm - BaseTime, TICRATE, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
int I_GetTimeSignaled (bool saveMS)
|
||||||
|
{
|
||||||
|
if (saveMS)
|
||||||
|
{
|
||||||
|
TicStart = sig_start;
|
||||||
|
}
|
||||||
|
return tics;
|
||||||
|
}
|
||||||
|
|
||||||
|
int I_WaitForTicPolled (int prevtic)
|
||||||
|
{
|
||||||
|
int time;
|
||||||
|
|
||||||
|
assert (TicFrozen == 0);
|
||||||
|
while ((time = I_GetTimePolled(false)) <= prevtic)
|
||||||
|
;
|
||||||
|
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
int I_WaitForTicSignaled (int prevtic)
|
||||||
|
{
|
||||||
|
assert (TicFrozen == 0);
|
||||||
|
|
||||||
|
while(tics <= prevtic)
|
||||||
|
{
|
||||||
|
SEMAPHORE_WAIT(timerWait)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tics;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_FreezeTimeSelect (bool frozen)
|
||||||
|
{
|
||||||
|
I_SelectTimer();
|
||||||
|
return I_FreezeTime (frozen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_FreezeTimePolled (bool frozen)
|
||||||
|
{
|
||||||
|
if (frozen)
|
||||||
|
{
|
||||||
|
assert(TicFrozen == 0);
|
||||||
|
TicFrozen = I_GetTimePolled(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(TicFrozen != 0);
|
||||||
|
int froze = TicFrozen;
|
||||||
|
TicFrozen = 0;
|
||||||
|
int now = I_GetTimePolled(false);
|
||||||
|
BaseTime += (now - froze) * 1000 / TICRATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_FreezeTimeSignaled (bool frozen)
|
||||||
|
{
|
||||||
|
TicFrozen = frozen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int I_WaitForTicSelect (int prevtic)
|
||||||
|
{
|
||||||
|
I_SelectTimer();
|
||||||
|
return I_WaitForTic (prevtic);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// I_HandleAlarm
|
||||||
|
// Should be called every time there is an alarm.
|
||||||
|
//
|
||||||
|
void I_HandleAlarm (int sig)
|
||||||
|
{
|
||||||
|
if(!TicFrozen)
|
||||||
|
tics++;
|
||||||
|
sig_start = SDL_GetTicks();
|
||||||
|
SEMAPHORE_SIGNAL(timerWait)
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// I_SelectTimer
|
||||||
|
// Sets up the timer function based on if we can use signals for efficent CPU
|
||||||
|
// usage.
|
||||||
|
//
|
||||||
|
void I_SelectTimer()
|
||||||
|
{
|
||||||
|
SEMAPHORE_INIT(timerWait, 0, 0)
|
||||||
|
#ifndef __sun
|
||||||
|
signal(SIGALRM, I_HandleAlarm);
|
||||||
|
#else
|
||||||
|
struct sigaction alrmaction;
|
||||||
|
sigaction(SIGALRM, NULL, &alrmaction);
|
||||||
|
alrmaction.sa_handler = I_HandleAlarm;
|
||||||
|
sigaction(SIGALRM, &alrmaction, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct itimerval itv;
|
||||||
|
itv.it_interval.tv_sec = itv.it_value.tv_sec = 0;
|
||||||
|
itv.it_interval.tv_usec = itv.it_value.tv_usec = 1000000/TICRATE;
|
||||||
|
|
||||||
|
if (setitimer(ITIMER_REAL, &itv, NULL) != 0)
|
||||||
|
{
|
||||||
|
I_GetTime = I_GetTimePolled;
|
||||||
|
I_FreezeTime = I_FreezeTimePolled;
|
||||||
|
I_WaitForTic = I_WaitForTicPolled;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
I_GetTime = I_GetTimeSignaled;
|
||||||
|
I_FreezeTime = I_FreezeTimeSignaled;
|
||||||
|
I_WaitForTic = I_WaitForTicSignaled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the fractional amount of a tic passed since the most recent tic
|
||||||
|
fixed_t I_GetTimeFrac (uint32 *ms)
|
||||||
|
{
|
||||||
|
DWORD now = SDL_GetTicks ();
|
||||||
|
if (ms) *ms = TicStart + (1000 / TICRATE);
|
||||||
|
if (TicStart == 0)
|
||||||
|
{
|
||||||
|
return FRACUNIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fixed_t frac = clamp<fixed_t> ((now - TicStart)*FRACUNIT*TICRATE/1000, 0, FRACUNIT);
|
||||||
|
return frac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_InitTimer ()
|
||||||
|
{
|
||||||
|
I_GetTime = I_GetTimeSelect;
|
||||||
|
I_WaitForTic = I_WaitForTicSelect;
|
||||||
|
I_FreezeTime = I_FreezeTimeSelect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ShutdownTimer ()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -33,9 +33,29 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Avoid collision between DObject class and Objective-C
|
||||||
|
#define Class ObjectClass
|
||||||
|
|
||||||
|
#include "cmdlib.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
#include "c_cvars.h"
|
||||||
|
#include "m_argv.h"
|
||||||
|
#include "m_misc.h"
|
||||||
|
#include "gameconfigfile.h"
|
||||||
|
|
||||||
|
#undef Class
|
||||||
|
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
|
#include <wordexp.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
|
||||||
|
// Missing type definition for 10.4 and earlier
|
||||||
|
typedef unsigned int NSUInteger;
|
||||||
|
#endif // prior to 10.5
|
||||||
|
|
||||||
|
CVAR(String, osx_additional_parameters, "", CVAR_ARCHIVE | CVAR_NOSET | CVAR_GLOBALCONFIG);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -107,6 +127,45 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
static NSDictionary* GetKnownFileTypes()
|
||||||
|
{
|
||||||
|
return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
@"-file" , @"wad",
|
||||||
|
@"-file" , @"pk3",
|
||||||
|
@"-file" , @"zip",
|
||||||
|
@"-file" , @"pk7",
|
||||||
|
@"-file" , @"7z",
|
||||||
|
@"-deh" , @"deh",
|
||||||
|
@"-bex" , @"bex",
|
||||||
|
@"-exec" , @"cfg",
|
||||||
|
@"-playdemo", @"lmp",
|
||||||
|
nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
static NSArray* GetKnownExtensions()
|
||||||
|
{
|
||||||
|
return [GetKnownFileTypes() allKeys];
|
||||||
|
}
|
||||||
|
|
||||||
|
@interface NSMutableString(AppendKnownFileType)
|
||||||
|
- (void)appendKnownFileType:(NSString *)filePath;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NSMutableString(AppendKnownFileType)
|
||||||
|
- (void)appendKnownFileType:(NSString *)filePath
|
||||||
|
{
|
||||||
|
NSString* extension = [[filePath pathExtension] lowercaseString];
|
||||||
|
NSString* parameter = [GetKnownFileTypes() objectForKey:extension];
|
||||||
|
|
||||||
|
if (nil == parameter)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self appendFormat:@"%@ \"%@\" ", parameter, filePath];
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
// So we can listen for button actions and such we need to have an Obj-C class.
|
// So we can listen for button actions and such we need to have an Obj-C class.
|
||||||
@interface IWADPicker : NSObject
|
@interface IWADPicker : NSObject
|
||||||
{
|
{
|
||||||
|
@ -114,13 +173,18 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
||||||
NSWindow *window;
|
NSWindow *window;
|
||||||
NSButton *okButton;
|
NSButton *okButton;
|
||||||
NSButton *cancelButton;
|
NSButton *cancelButton;
|
||||||
|
NSButton *browseButton;
|
||||||
|
NSTextField *parametersTextField;
|
||||||
bool cancelled;
|
bool cancelled;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)buttonPressed:(id) sender;
|
- (void)buttonPressed:(id) sender;
|
||||||
|
- (void)browseButtonPressed:(id) sender;
|
||||||
- (void)doubleClicked:(id) sender;
|
- (void)doubleClicked:(id) sender;
|
||||||
- (void)makeLabel:(NSTextField *)label withString:(const char*) str;
|
- (void)makeLabel:(NSTextField *)label withString:(const char*) str;
|
||||||
- (int)pickIWad:(WadStuff *)wads num:(int) numwads showWindow:(bool) showwin defaultWad:(int) defaultiwad;
|
- (int)pickIWad:(WadStuff *)wads num:(int) numwads showWindow:(bool) showwin defaultWad:(int) defaultiwad;
|
||||||
|
- (NSString*)commandLineParameters;
|
||||||
|
- (void)menuActionSent:(NSNotification*)notification;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation IWADPicker
|
@implementation IWADPicker
|
||||||
|
@ -134,6 +198,52 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
||||||
[app stopModal];
|
[app stopModal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)browseButtonPressed:(id) sender
|
||||||
|
{
|
||||||
|
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
|
||||||
|
[openPanel setAllowsMultipleSelection:YES];
|
||||||
|
[openPanel setCanChooseFiles:YES];
|
||||||
|
[openPanel setCanChooseDirectories:YES];
|
||||||
|
[openPanel setResolvesAliases:YES];
|
||||||
|
[openPanel setAllowedFileTypes:GetKnownExtensions()];
|
||||||
|
|
||||||
|
if (NSOKButton == [openPanel runModal])
|
||||||
|
{
|
||||||
|
NSArray* files = [openPanel URLs];
|
||||||
|
NSMutableString* parameters = [NSMutableString string];
|
||||||
|
|
||||||
|
for (NSUInteger i = 0, ei = [files count]; i < ei; ++i)
|
||||||
|
{
|
||||||
|
NSString* filePath = [[files objectAtIndex:i] path];
|
||||||
|
BOOL isDirectory = false;
|
||||||
|
|
||||||
|
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory] && isDirectory)
|
||||||
|
{
|
||||||
|
[parameters appendFormat:@"-file \"%@\" ", filePath];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[parameters appendKnownFileType:filePath];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([parameters length] > 0)
|
||||||
|
{
|
||||||
|
NSString* newParameters = [parametersTextField stringValue];
|
||||||
|
|
||||||
|
if ([newParameters length] > 0
|
||||||
|
&& NO == [newParameters hasSuffix:@" "])
|
||||||
|
{
|
||||||
|
newParameters = [newParameters stringByAppendingString:@" "];
|
||||||
|
}
|
||||||
|
|
||||||
|
newParameters = [newParameters stringByAppendingString:parameters];
|
||||||
|
|
||||||
|
[parametersTextField setStringValue: newParameters];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)doubleClicked:(id) sender
|
- (void)doubleClicked:(id) sender
|
||||||
{
|
{
|
||||||
if ([sender clickedRow] >= 0)
|
if ([sender clickedRow] >= 0)
|
||||||
|
@ -159,20 +269,18 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
||||||
cancelled = false;
|
cancelled = false;
|
||||||
|
|
||||||
app = [NSApplication sharedApplication];
|
app = [NSApplication sharedApplication];
|
||||||
id windowTitle = [NSString stringWithFormat:@"%s %s", GAMESIG, GetVersionString()];
|
id windowTitle = [NSString stringWithFormat:@"%s %s", GAMENAME, GetVersionString()];
|
||||||
|
|
||||||
NSRect frame = NSMakeRect(0, 0, 440, 450);
|
NSRect frame = NSMakeRect(0, 0, 440, 450);
|
||||||
window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO];
|
window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO];
|
||||||
[window setTitle:windowTitle];
|
[window setTitle:windowTitle];
|
||||||
|
|
||||||
NSTextField *description = [[NSTextField alloc] initWithFrame:NSMakeRect(22, 379, 412, 50)];
|
NSTextField *description = [[NSTextField alloc] initWithFrame:NSMakeRect(18, 384, 402, 50)];
|
||||||
[self makeLabel:description withString:"GZDoom found more than one IWAD\nSelect from the list below to determine which one to use:"];
|
[self makeLabel:description withString:GAMENAME " found more than one IWAD\nSelect from the list below to determine which one to use:"];
|
||||||
[[window contentView] addSubview:description];
|
[[window contentView] addSubview:description];
|
||||||
[description release];
|
[description release];
|
||||||
|
|
||||||
// Commented out version would account for an additional parameters box.
|
NSScrollView *iwadScroller = [[NSScrollView alloc] initWithFrame:NSMakeRect(20, 135, 402, 256)];
|
||||||
//NSScrollView *iwadScroller = [[NSScrollView alloc] initWithFrame:NSMakeRect(20, 103, 412, 288)];
|
|
||||||
NSScrollView *iwadScroller = [[NSScrollView alloc] initWithFrame:NSMakeRect(20, 50, 412, 341)];
|
|
||||||
NSTableView *iwadTable = [[NSTableView alloc] initWithFrame:[iwadScroller bounds]];
|
NSTableView *iwadTable = [[NSTableView alloc] initWithFrame:[iwadScroller bounds]];
|
||||||
IWADTableData *tableData = [[IWADTableData alloc] init:wads num:numwads];
|
IWADTableData *tableData = [[IWADTableData alloc] init:wads num:numwads];
|
||||||
for(int i = 0;i < NUM_COLUMNS;i++)
|
for(int i = 0;i < NUM_COLUMNS;i++)
|
||||||
|
@ -200,11 +308,12 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
||||||
[iwadTable release];
|
[iwadTable release];
|
||||||
[iwadScroller release];
|
[iwadScroller release];
|
||||||
|
|
||||||
/*NSTextField *additionalParametersLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(17, 78, 144, 17)];
|
NSTextField *additionalParametersLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(18, 108, 144, 17)];
|
||||||
[self makeLabel:additionalParametersLabel:"Additional Parameters"];
|
[self makeLabel:additionalParametersLabel withString:"Additional Parameters:"];
|
||||||
[[window contentView] addSubview:additionalParametersLabel];
|
[[window contentView] addSubview:additionalParametersLabel];
|
||||||
NSTextField *additionalParameters = [[NSTextField alloc] initWithFrame:NSMakeRect(20, 48, 360, 22)];
|
parametersTextField = [[NSTextField alloc] initWithFrame:NSMakeRect(20, 48, 402, 54)];
|
||||||
[[window contentView] addSubview:additionalParameters];*/
|
[parametersTextField setStringValue:[NSString stringWithUTF8String:osx_additional_parameters]];
|
||||||
|
[[window contentView] addSubview:parametersTextField];
|
||||||
|
|
||||||
// Doesn't look like the SDL version implements this so lets not show it.
|
// Doesn't look like the SDL version implements this so lets not show it.
|
||||||
/*NSButton *dontAsk = [[NSButton alloc] initWithFrame:NSMakeRect(18, 18, 178, 18)];
|
/*NSButton *dontAsk = [[NSButton alloc] initWithFrame:NSMakeRect(18, 18, 178, 18)];
|
||||||
|
@ -213,39 +322,164 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
||||||
[dontAsk setState:(showwin ? NSOffState : NSOnState)];
|
[dontAsk setState:(showwin ? NSOffState : NSOnState)];
|
||||||
[[window contentView] addSubview:dontAsk];*/
|
[[window contentView] addSubview:dontAsk];*/
|
||||||
|
|
||||||
okButton = [[NSButton alloc] initWithFrame:NSMakeRect(236, 12, 96, 32)];
|
okButton = [[NSButton alloc] initWithFrame:NSMakeRect(236, 8, 96, 32)];
|
||||||
[okButton setTitle:[NSString stringWithUTF8String:"OK"]];
|
[okButton setTitle:@"OK"];
|
||||||
[okButton setBezelStyle:NSRoundedBezelStyle];
|
[okButton setBezelStyle:NSRoundedBezelStyle];
|
||||||
[okButton setAction:@selector(buttonPressed:)];
|
[okButton setAction:@selector(buttonPressed:)];
|
||||||
[okButton setTarget:self];
|
[okButton setTarget:self];
|
||||||
[okButton setKeyEquivalent:@"\r"];
|
[okButton setKeyEquivalent:@"\r"];
|
||||||
[[window contentView] addSubview:okButton];
|
[[window contentView] addSubview:okButton];
|
||||||
|
|
||||||
cancelButton = [[NSButton alloc] initWithFrame:NSMakeRect(332, 12, 96, 32)];
|
cancelButton = [[NSButton alloc] initWithFrame:NSMakeRect(332, 8, 96, 32)];
|
||||||
[cancelButton setTitle:[NSString stringWithUTF8String:"Cancel"]];
|
[cancelButton setTitle:@"Cancel"];
|
||||||
[cancelButton setBezelStyle:NSRoundedBezelStyle];
|
[cancelButton setBezelStyle:NSRoundedBezelStyle];
|
||||||
[cancelButton setAction:@selector(buttonPressed:)];
|
[cancelButton setAction:@selector(buttonPressed:)];
|
||||||
[cancelButton setTarget:self];
|
[cancelButton setTarget:self];
|
||||||
[cancelButton setKeyEquivalent:@"\033"];
|
[cancelButton setKeyEquivalent:@"\033"];
|
||||||
[[window contentView] addSubview:cancelButton];
|
[[window contentView] addSubview:cancelButton];
|
||||||
|
|
||||||
|
browseButton = [[NSButton alloc] initWithFrame:NSMakeRect(14, 8, 96, 32)];
|
||||||
|
[browseButton setTitle:@"Browse..."];
|
||||||
|
[browseButton setBezelStyle:NSRoundedBezelStyle];
|
||||||
|
[browseButton setAction:@selector(browseButtonPressed:)];
|
||||||
|
[browseButton setTarget:self];
|
||||||
|
[[window contentView] addSubview:browseButton];
|
||||||
|
|
||||||
|
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||||
|
[center addObserver:self selector:@selector(menuActionSent:) name:NSMenuDidSendActionNotification object:nil];
|
||||||
|
|
||||||
[window center];
|
[window center];
|
||||||
[app runModalForWindow:window];
|
[app runModalForWindow:window];
|
||||||
|
|
||||||
|
[center removeObserver:self name:NSMenuDidSendActionNotification object:nil];
|
||||||
|
|
||||||
[window release];
|
[window release];
|
||||||
[okButton release];
|
[okButton release];
|
||||||
[cancelButton release];
|
[cancelButton release];
|
||||||
|
[browseButton release];
|
||||||
|
|
||||||
return cancelled ? -1 : [iwadTable selectedRow];
|
return cancelled ? -1 : [iwadTable selectedRow];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString*)commandLineParameters
|
||||||
|
{
|
||||||
|
return [parametersTextField stringValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)menuActionSent:(NSNotification*)notification
|
||||||
|
{
|
||||||
|
NSDictionary* userInfo = [notification userInfo];
|
||||||
|
NSMenuItem* menuItem = [userInfo valueForKey:@"MenuItem"];
|
||||||
|
|
||||||
|
if ( @selector(terminate:) == [menuItem action] )
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_CVAR(String, defaultiwad)
|
||||||
|
|
||||||
|
static NSString* GetArchitectureString()
|
||||||
|
{
|
||||||
|
#ifdef __i386__
|
||||||
|
return @"i386";
|
||||||
|
#elif defined __x86_64__
|
||||||
|
return @"x86_64";
|
||||||
|
#elif defined __ppc__
|
||||||
|
return @"ppc";
|
||||||
|
#elif defined __ppc64__
|
||||||
|
return @"ppc64";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RestartWithParameters(const char* iwadPath, NSString* parameters)
|
||||||
|
{
|
||||||
|
assert(nil != parameters);
|
||||||
|
|
||||||
|
defaultiwad = ExtractFileBase(iwadPath);
|
||||||
|
|
||||||
|
GameConfig->DoGameSetup("Doom");
|
||||||
|
M_SaveDefaults(NULL);
|
||||||
|
|
||||||
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
@try
|
||||||
|
{
|
||||||
|
const int commandLineParametersCount = Args->NumArgs();
|
||||||
|
assert(commandLineParametersCount > 0);
|
||||||
|
|
||||||
|
NSString* executablePath = [NSString stringWithUTF8String:Args->GetArg(0)];
|
||||||
|
NSString* architecture = GetArchitectureString();
|
||||||
|
|
||||||
|
NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:commandLineParametersCount + 6];
|
||||||
|
[arguments addObject:@"-arch"];
|
||||||
|
[arguments addObject:architecture];
|
||||||
|
[arguments addObject:executablePath];
|
||||||
|
[arguments addObject:@"-wad_picker_restart"];
|
||||||
|
[arguments addObject:@"-iwad"];
|
||||||
|
[arguments addObject:[NSString stringWithUTF8String:iwadPath]];
|
||||||
|
|
||||||
|
for (int i = 1; i < commandLineParametersCount; ++i)
|
||||||
|
{
|
||||||
|
NSString* currentParameter = [NSString stringWithUTF8String:Args->GetArg(i)];
|
||||||
|
[arguments addObject:currentParameter];
|
||||||
|
}
|
||||||
|
|
||||||
|
wordexp_t expansion = {};
|
||||||
|
|
||||||
|
if (0 == wordexp([parameters UTF8String], &expansion, 0))
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < expansion.we_wordc; ++i)
|
||||||
|
{
|
||||||
|
NSString* argumentString = [NSString stringWithCString:expansion.we_wordv[i]
|
||||||
|
encoding:NSUTF8StringEncoding];
|
||||||
|
[arguments addObject:argumentString];
|
||||||
|
}
|
||||||
|
|
||||||
|
wordfree(&expansion);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NSTask launchedTaskWithLaunchPath:@"/usr/bin/arch" arguments:arguments];
|
||||||
|
|
||||||
|
_exit(0); // to avoid atexit()'s functions
|
||||||
|
}
|
||||||
|
@catch (NSException* e)
|
||||||
|
{
|
||||||
|
NSLog(@"Cannot restart: %@", [e reason]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[pool release];
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_SetMainWindowVisible(bool visible);
|
||||||
|
|
||||||
// Simple wrapper so we can call this from outside.
|
// Simple wrapper so we can call this from outside.
|
||||||
int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
|
int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
|
||||||
{
|
{
|
||||||
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
I_SetMainWindowVisible(false);
|
||||||
|
|
||||||
IWADPicker *picker = [IWADPicker alloc];
|
IWADPicker *picker = [IWADPicker alloc];
|
||||||
int ret = [picker pickIWad:wads num:numwads showWindow:showwin defaultWad:defaultiwad];
|
int ret = [picker pickIWad:wads num:numwads showWindow:showwin defaultWad:defaultiwad];
|
||||||
[picker release];
|
|
||||||
|
I_SetMainWindowVisible(true);
|
||||||
|
|
||||||
|
NSString* parametersToAppend = [picker commandLineParameters];
|
||||||
|
osx_additional_parameters = [parametersToAppend UTF8String];
|
||||||
|
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
if (0 != [parametersToAppend length])
|
||||||
|
{
|
||||||
|
RestartWithParameters(wads[ret].Path, parametersToAppend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[pool release];
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <OpenGL/OpenGL.h>
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
// TYPES -------------------------------------------------------------------
|
// TYPES -------------------------------------------------------------------
|
||||||
|
@ -43,6 +47,8 @@ public:
|
||||||
|
|
||||||
friend class SDLVideo;
|
friend class SDLVideo;
|
||||||
|
|
||||||
|
virtual void SetVSync (bool vsync);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PalEntry SourcePalette[256];
|
PalEntry SourcePalette[256];
|
||||||
BYTE GammaTable[3][256];
|
BYTE GammaTable[3][256];
|
||||||
|
@ -75,13 +81,15 @@ struct MiniModeInfo
|
||||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||||
|
|
||||||
extern IVideo *Video;
|
extern IVideo *Video;
|
||||||
extern SDL_Surface *cursorSurface;
|
|
||||||
extern SDL_Rect cursorBlit;
|
|
||||||
extern bool GUICapture;
|
extern bool GUICapture;
|
||||||
|
|
||||||
|
SDL_Surface *cursorSurface = NULL;
|
||||||
|
SDL_Rect cursorBlit = {0, 0, 32, 32};
|
||||||
|
|
||||||
EXTERN_CVAR (Float, Gamma)
|
EXTERN_CVAR (Float, Gamma)
|
||||||
EXTERN_CVAR (Int, vid_maxfps)
|
EXTERN_CVAR (Int, vid_maxfps)
|
||||||
EXTERN_CVAR (Bool, cl_capfps)
|
EXTERN_CVAR (Bool, cl_capfps)
|
||||||
|
EXTERN_CVAR (Bool, vid_vsync)
|
||||||
|
|
||||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||||
|
|
||||||
|
@ -326,6 +334,7 @@ SDLFB::SDLFB (int width, int height, bool fullscreen)
|
||||||
}
|
}
|
||||||
memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256);
|
memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256);
|
||||||
UpdateColors ();
|
UpdateColors ();
|
||||||
|
SetVSync (vid_vsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDLFB::~SDLFB ()
|
SDLFB::~SDLFB ()
|
||||||
|
@ -535,6 +544,26 @@ bool SDLFB::IsFullscreen ()
|
||||||
return (Screen->flags & SDL_FULLSCREEN) != 0;
|
return (Screen->flags & SDL_FULLSCREEN) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDLFB::SetVSync (bool vsync)
|
||||||
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (CGLContextObj context = CGLGetCurrentContext())
|
||||||
|
{
|
||||||
|
// Apply vsync for native backend only (where OpenGL context is set)
|
||||||
|
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
|
||||||
|
// Inconsistency between 10.4 and 10.5 SDKs:
|
||||||
|
// third argument of CGLSetParameter() is const long* on 10.4 and const GLint* on 10.5
|
||||||
|
// So, GLint typedef'ed to long instead of int to workaround this issue
|
||||||
|
typedef long GLint;
|
||||||
|
#endif // prior to 10.5
|
||||||
|
|
||||||
|
const GLint value = vsync ? 1 : 0;
|
||||||
|
CGLSetParameter(context, kCGLCPSwapInterval, &value);
|
||||||
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
}
|
||||||
|
|
||||||
ADD_STAT (blit)
|
ADD_STAT (blit)
|
||||||
{
|
{
|
||||||
FString out;
|
FString out;
|
||||||
|
|
|
@ -433,7 +433,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity ()
|
||||||
}
|
}
|
||||||
|
|
||||||
int forkres;
|
int forkres;
|
||||||
wordexp_t words;
|
wordexp_t words = {};
|
||||||
|
|
||||||
switch (wordexp (CommandLine.GetChars(), &words, 0))
|
switch (wordexp (CommandLine.GetChars(), &words, 0))
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,6 +63,7 @@ enum
|
||||||
STAT_SECTOREFFECT, // All sector effects that cause floor and ceiling movement
|
STAT_SECTOREFFECT, // All sector effects that cause floor and ceiling movement
|
||||||
STAT_ACTORMOVER, // actor movers
|
STAT_ACTORMOVER, // actor movers
|
||||||
STAT_SCRIPTS, // The ACS thinker. This is to ensure that it can't tick before all actors called PostBeginPlay
|
STAT_SCRIPTS, // The ACS thinker. This is to ensure that it can't tick before all actors called PostBeginPlay
|
||||||
|
STAT_BOT, // Bot thinker
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -266,11 +266,11 @@ enum EDefinitionType
|
||||||
#define GCC_MSEG
|
#define GCC_MSEG
|
||||||
#else
|
#else
|
||||||
#define MSVC_ASEG
|
#define MSVC_ASEG
|
||||||
#define GCC_ASEG __attribute__((section(SECTION_AREG)))
|
#define GCC_ASEG __attribute__((section(SECTION_AREG))) __attribute__((used))
|
||||||
#define MSVC_PSEG
|
#define MSVC_PSEG
|
||||||
#define GCC_PSEG __attribute__((section(SECTION_GREG)))
|
#define GCC_PSEG __attribute__((section(SECTION_GREG))) __attribute__((used))
|
||||||
#define MSVC_MSEG
|
#define MSVC_MSEG
|
||||||
#define GCC_MSEG __attribute__((section(SECTION_MREG)))
|
#define GCC_MSEG __attribute__((section(SECTION_MREG))) __attribute__((used))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ const char *GetVersionString();
|
||||||
|
|
||||||
// Use 4500 as the base git save version, since it's higher than the
|
// Use 4500 as the base git save version, since it's higher than the
|
||||||
// SVN revision ever got.
|
// SVN revision ever got.
|
||||||
#define SAVEVER 4515
|
#define SAVEVER 4516
|
||||||
|
|
||||||
#define SAVEVERSTRINGIFY2(x) #x
|
#define SAVEVERSTRINGIFY2(x) #x
|
||||||
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)
|
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)
|
||||||
|
|
|
@ -2,9 +2,9 @@ cmake_minimum_required( VERSION 2.4 )
|
||||||
|
|
||||||
add_subdirectory( lemon )
|
add_subdirectory( lemon )
|
||||||
add_subdirectory( re2c )
|
add_subdirectory( re2c )
|
||||||
if( WIN32 )
|
if( WIN32 AND NOT CMAKE_SIZEOF_VOID_P MATCHES "8" )
|
||||||
add_subdirectory( fixrtext )
|
add_subdirectory( fixrtext )
|
||||||
endif( WIN32 )
|
endif( WIN32 AND NOT CMAKE_SIZEOF_VOID_P MATCHES "8" )
|
||||||
add_subdirectory( updaterevision )
|
add_subdirectory( updaterevision )
|
||||||
add_subdirectory( zipdir )
|
add_subdirectory( zipdir )
|
||||||
|
|
||||||
|
|
|
@ -1478,6 +1478,7 @@ OptionValue OplCores
|
||||||
0, "MAME OPL2"
|
0, "MAME OPL2"
|
||||||
1, "DOSBox OPL3"
|
1, "DOSBox OPL3"
|
||||||
2, "Java OPL3"
|
2, "Java OPL3"
|
||||||
|
3, "Nuked OPL3"
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionMenu AdvSoundOptions
|
OptionMenu AdvSoundOptions
|
||||||
|
|
|
@ -2632,6 +2632,14 @@
|
||||||
RelativePath=".\src\oplsynth\opl_mus_player.h"
|
RelativePath=".\src\oplsynth\opl_mus_player.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\oplsynth\nukedopl3.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\oplsynth\nukedopl3.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<Filter
|
<Filter
|
||||||
Name="DOSBox"
|
Name="DOSBox"
|
||||||
>
|
>
|
||||||
|
|
Loading…
Reference in a new issue