mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-31 04:50:48 +00:00
Merge branch 'master' into scripting
Conflicts: src/actor.h src/g_doom/a_archvile.cpp src/g_shared/a_morph.cpp src/p_enemy.h src/p_local.h src/p_mobj.cpp src/sc_man_tokens.h src/thingdef/thingdef_codeptr.cpp src/thingdef/thingdef_exp.h src/thingdef/thingdef_expression.cpp src/thingdef/thingdef_states.cpp wadsrc/static/actors/actor.txt
This commit is contained in:
commit
775e33ede7
106 changed files with 8867 additions and 13603 deletions
180
FindSDL2.cmake
Normal file
180
FindSDL2.cmake
Normal file
|
@ -0,0 +1,180 @@
|
|||
# Locate SDL2 library
|
||||
# This module defines
|
||||
# SDL2_LIBRARY, the name of the library to link against
|
||||
# SDL2_FOUND, if false, do not try to link to SDL2
|
||||
# SDL2_INCLUDE_DIR, where to find SDL.h
|
||||
#
|
||||
# This module responds to the the flag:
|
||||
# SDL2_BUILDING_LIBRARY
|
||||
# If this is defined, then no SDL2_main will be linked in because
|
||||
# only applications need main().
|
||||
# Otherwise, it is assumed you are building an application and this
|
||||
# module will attempt to locate and set the the proper link flags
|
||||
# as part of the returned SDL2_LIBRARY variable.
|
||||
#
|
||||
# Don't forget to include SDL2main.h and SDL2main.m your project for the
|
||||
# OS X framework based version. (Other versions link to -lSDL2main which
|
||||
# this module will try to find on your behalf.) Also for OS X, this
|
||||
# module will automatically add the -framework Cocoa on your behalf.
|
||||
#
|
||||
#
|
||||
# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration
|
||||
# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library
|
||||
# (SDL2.dll, libsdl2.so, SDL2.framework, etc).
|
||||
# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again.
|
||||
# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value
|
||||
# as appropriate. These values are used to generate the final SDL2_LIBRARY
|
||||
# variable, but when these values are unset, SDL2_LIBRARY does not get created.
|
||||
#
|
||||
#
|
||||
# $SDL2DIR is an environment variable that would
|
||||
# correspond to the ./configure --prefix=$SDL2DIR
|
||||
# used in building SDL2.
|
||||
# l.e.galup 9-20-02
|
||||
#
|
||||
# Modified by Eric Wing.
|
||||
# Added code to assist with automated building by using environmental variables
|
||||
# and providing a more controlled/consistent search behavior.
|
||||
# Added new modifications to recognize OS X frameworks and
|
||||
# additional Unix paths (FreeBSD, etc).
|
||||
# Also corrected the header search path to follow "proper" SDL2 guidelines.
|
||||
# Added a search for SDL2main which is needed by some platforms.
|
||||
# Added a search for threads which is needed by some platforms.
|
||||
# Added needed compile switches for MinGW.
|
||||
#
|
||||
# On OSX, this will prefer the Framework version (if found) over others.
|
||||
# People will have to manually change the cache values of
|
||||
# SDL2_LIBRARY to override this selection or set the CMake environment
|
||||
# CMAKE_INCLUDE_PATH to modify the search paths.
|
||||
#
|
||||
# Note that the header path has changed from SDL2/SDL.h to just SDL.h
|
||||
# This needed to change because "proper" SDL2 convention
|
||||
# is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability
|
||||
# reasons because not all systems place things in SDL2/ (see FreeBSD).
|
||||
#
|
||||
# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake
|
||||
# module with the minor edit of changing "SDL" to "SDL2" where necessary. This
|
||||
# was not created for redistribution, and exists temporarily pending official
|
||||
# SDL2 CMake modules.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2003-2009 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
FIND_PATH(SDL2_INCLUDE_DIR SDL.h
|
||||
HINTS
|
||||
$ENV{SDL2DIR}
|
||||
PATH_SUFFIXES include/SDL2 include
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local/include/SDL2
|
||||
/usr/include/SDL2
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
#MESSAGE("SDL2_INCLUDE_DIR is ${SDL2_INCLUDE_DIR}")
|
||||
|
||||
FIND_LIBRARY(SDL2_LIBRARY_TEMP
|
||||
NAMES SDL2
|
||||
HINTS
|
||||
$ENV{SDL2DIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATHS
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
|
||||
#MESSAGE("SDL2_LIBRARY_TEMP is ${SDL2_LIBRARY_TEMP}")
|
||||
|
||||
IF(NOT SDL2_BUILDING_LIBRARY)
|
||||
IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
|
||||
# Non-OS X framework versions expect you to also dynamically link to
|
||||
# SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
|
||||
# seem to provide SDL2main for compatibility even though they don't
|
||||
# necessarily need it.
|
||||
FIND_LIBRARY(SDL2MAIN_LIBRARY
|
||||
NAMES SDL2main
|
||||
HINTS
|
||||
$ENV{SDL2DIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATHS
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
|
||||
ENDIF(NOT SDL2_BUILDING_LIBRARY)
|
||||
|
||||
# SDL2 may require threads on your system.
|
||||
# The Apple build may not need an explicit flag because one of the
|
||||
# frameworks may already provide it.
|
||||
# But for non-OSX systems, I will use the CMake Threads package.
|
||||
IF(NOT APPLE)
|
||||
FIND_PACKAGE(Threads)
|
||||
ENDIF(NOT APPLE)
|
||||
|
||||
# MinGW needs an additional library, mwindows
|
||||
# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows
|
||||
# (Actually on second look, I think it only needs one of the m* libraries.)
|
||||
IF(MINGW)
|
||||
SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
|
||||
ENDIF(MINGW)
|
||||
|
||||
SET(SDL2_FOUND "NO")
|
||||
IF(SDL2_LIBRARY_TEMP)
|
||||
# For SDL2main
|
||||
IF(NOT SDL2_BUILDING_LIBRARY)
|
||||
IF(SDL2MAIN_LIBRARY)
|
||||
SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP})
|
||||
ENDIF(SDL2MAIN_LIBRARY)
|
||||
ENDIF(NOT SDL2_BUILDING_LIBRARY)
|
||||
|
||||
# For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
|
||||
# CMake doesn't display the -framework Cocoa string in the UI even
|
||||
# though it actually is there if I modify a pre-used variable.
|
||||
# I think it has something to do with the CACHE STRING.
|
||||
# So I use a temporary variable until the end so I can set the
|
||||
# "real" variable in one-shot.
|
||||
IF(APPLE)
|
||||
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa")
|
||||
ENDIF(APPLE)
|
||||
|
||||
# For threads, as mentioned Apple doesn't need this.
|
||||
# In fact, there seems to be a problem if I used the Threads package
|
||||
# and try using this line, so I'm just skipping it entirely for OS X.
|
||||
IF(NOT APPLE)
|
||||
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
|
||||
ENDIF(NOT APPLE)
|
||||
|
||||
# For MinGW library
|
||||
IF(MINGW)
|
||||
SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP})
|
||||
ENDIF(MINGW)
|
||||
|
||||
# Set the final string here so the GUI reflects the final state.
|
||||
SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found")
|
||||
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
|
||||
SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "")
|
||||
|
||||
SET(SDL2_FOUND "YES")
|
||||
ENDIF(SDL2_LIBRARY_TEMP)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2
|
||||
REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR)
|
|
@ -1,7 +1,7 @@
|
|||
cmake_minimum_required( VERSION 2.4 )
|
||||
add_library( output_sdl MODULE output_sdl.c )
|
||||
include_directories( ${FMOD_INCLUDE_DIR} ${SDL_INCLUDE_DIR} )
|
||||
target_link_libraries( output_sdl SDL )
|
||||
include_directories( ${FMOD_INCLUDE_DIR} ${SDL2_INCLUDE_DIR} )
|
||||
target_link_libraries( output_sdl ${SDL2_LIBRARY} )
|
||||
|
||||
FILE( WRITE ${CMAKE_CURRENT_BINARY_DIR}/link-make "if [ ! -e ${ZDOOM_OUTPUT_DIR}/liboutput_sdl.so ]; then ln -sf output_sdl/liboutput_sdl.so ${ZDOOM_OUTPUT_DIR}/liboutput_sdl.so; fi" )
|
||||
add_custom_command( TARGET output_sdl POST_BUILD
|
||||
|
|
|
@ -191,19 +191,6 @@ else( WIN32 )
|
|||
set( NO_GTK ON )
|
||||
endif( GTK2_FOUND )
|
||||
endif( NOT NO_GTK )
|
||||
|
||||
# Check for Xcursor library and header files
|
||||
find_library( XCURSOR_LIB Xcursor )
|
||||
if( XCURSOR_LIB )
|
||||
find_file( XCURSOR_HEADER "X11/Xcursor/Xcursor.h" )
|
||||
if( XCURSOR_HEADER )
|
||||
add_definitions( -DUSE_XCURSOR=1 )
|
||||
message( STATUS "Found Xcursor at ${XCURSOR_LIB}" )
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} ${XCURSOR_LIB} )
|
||||
else( XCURSOR_HEADER )
|
||||
unset( XCURSOR_LIB )
|
||||
endif( XCURSOR_HEADER )
|
||||
endif( XCURSOR_LIB )
|
||||
endif( APPLE )
|
||||
set( NASM_NAMES nasm )
|
||||
|
||||
|
@ -211,15 +198,12 @@ else( WIN32 )
|
|||
add_definitions( -DNO_GTK=1 )
|
||||
endif( NO_GTK )
|
||||
|
||||
# Non-Windows version also needs SDL
|
||||
find_package( SDL )
|
||||
if( NOT SDL_FOUND )
|
||||
message( SEND_ERROR "SDL is required for building." )
|
||||
endif( NOT SDL_FOUND )
|
||||
# Non-Windows version also needs SDL except native OS X backend
|
||||
if( NOT APPLE OR NOT OSX_COCOA_BACKEND )
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} "${SDL_LIBRARY}" )
|
||||
find_package( SDL2 REQUIRED )
|
||||
include_directories( "${SDL2_INCLUDE_DIR}" )
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} "${SDL2_LIBRARY}" )
|
||||
endif( NOT APPLE OR NOT OSX_COCOA_BACKEND )
|
||||
include_directories( "${SDL_INCLUDE_DIR}" )
|
||||
|
||||
find_path( FPU_CONTROL_DIR fpu_control.h )
|
||||
if( FPU_CONTROL_DIR )
|
||||
|
@ -563,57 +547,36 @@ set( PLAT_WIN32_SOURCES
|
|||
win32/i_system.cpp
|
||||
win32/st_start.cpp
|
||||
win32/win32video.cpp )
|
||||
set( PLAT_SDL_SYSTEM_SOURCES
|
||||
sdl/crashcatcher.c
|
||||
sdl/hardware.cpp
|
||||
sdl/i_cd.cpp
|
||||
sdl/i_main.cpp
|
||||
sdl/i_movie.cpp
|
||||
sdl/i_steam.cpp
|
||||
sdl/i_system.cpp
|
||||
sdl/sdlvideo.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
|
||||
sdl/iwadpicker_cocoa.mm
|
||||
sdl/i_system_cocoa.mm )
|
||||
set( PLAT_POSIX_SOURCES
|
||||
posix/i_cd.cpp
|
||||
posix/i_movie.cpp
|
||||
posix/i_steam.cpp
|
||||
posix/i_system.cpp
|
||||
posix/st_start.cpp )
|
||||
set( PLAT_SDL_SOURCES
|
||||
posix/sdl/crashcatcher.c
|
||||
posix/sdl/hardware.cpp
|
||||
posix/sdl/i_gui.cpp
|
||||
posix/sdl/i_input.cpp
|
||||
posix/sdl/i_joystick.cpp
|
||||
posix/sdl/i_main.cpp
|
||||
posix/sdl/i_timer.cpp
|
||||
posix/sdl/sdlvideo.cpp )
|
||||
set( PLAT_OSX_SOURCES
|
||||
posix/osx/iwadpicker_cocoa.mm
|
||||
posix/osx/zdoom.icns )
|
||||
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 )
|
||||
posix/cocoa/critsec.cpp
|
||||
posix/cocoa/i_input.mm
|
||||
posix/cocoa/i_joystick.cpp
|
||||
posix/cocoa/i_main.mm
|
||||
posix/cocoa/i_timer.cpp
|
||||
posix/cocoa/i_video.mm )
|
||||
|
||||
if( WIN32 )
|
||||
set( SYSTEM_SOURCES_DIR win32 )
|
||||
set( SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} )
|
||||
set( OTHER_SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ${PLAT_MAC_SOURCES} )
|
||||
set( OTHER_SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} ${PLAT_OSX_SOURCES} ${PLAT_COCOA_SOURCES} )
|
||||
|
||||
if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||
# CMake is not set up to compile and link rc files with GCC. :(
|
||||
|
@ -624,15 +587,26 @@ if( WIN32 )
|
|||
else( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||
set( SYSTEM_SOURCES ${SYSTEM_SOURCES} win32/zdoom.rc )
|
||||
endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||
else( WIN32 )
|
||||
set( SYSTEM_SOURCES_DIR sdl )
|
||||
elseif( APPLE )
|
||||
if( OSX_COCOA_BACKEND )
|
||||
set( SYSTEM_SOURCES_DIR posix posix/cocoa )
|
||||
set( SYSTEM_SOURCES ${PLAT_COCOA_SOURCES} )
|
||||
set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_SDL_SOURCES} )
|
||||
else( OSX_COCOA_BACKEND )
|
||||
set( SYSTEM_SOURCES_DIR posix posix/sdl )
|
||||
set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} )
|
||||
if( APPLE )
|
||||
set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_MAC_SOURCES} )
|
||||
set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} )
|
||||
else( APPLE )
|
||||
set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_MAC_SOURCES} )
|
||||
endif( APPLE )
|
||||
set( PLAT_OSX_SOURCES ${PLAT_OSX_SOURCES} posix/sdl/i_system.mm )
|
||||
set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_COCOA_SOURCES} )
|
||||
endif( OSX_COCOA_BACKEND )
|
||||
|
||||
set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_POSIX_SOURCES} ${PLAT_OSX_SOURCES} "${FMOD_LIBRARY}" )
|
||||
|
||||
set_source_files_properties( posix/osx/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources )
|
||||
set_source_files_properties( "${FMOD_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks )
|
||||
else( WIN32 )
|
||||
set( SYSTEM_SOURCES_DIR posix posix/sdl )
|
||||
set( SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} )
|
||||
set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_OSX_SOURCES} ${PLAT_COCOA_SOURCES} )
|
||||
endif( WIN32 )
|
||||
|
||||
if( NOT ASM_SOURCES )
|
||||
|
@ -696,8 +670,14 @@ endif( DYN_FLUIDSYNTH )
|
|||
# there's generally a new cpp for every header so this file will get changed
|
||||
if( WIN32 )
|
||||
set( EXTRA_HEADER_DIRS win32/*.h )
|
||||
elseif( APPLE )
|
||||
if( OSX_COCOA_BACKEND )
|
||||
set( EXTRA_HEADER_DIRS posix/*.h posix/cocoa/*.h )
|
||||
else( OSX_COCOA_BACKEND )
|
||||
set( EXTRA_HEADER_DIRS posix/*.h posix/sdl/*.h )
|
||||
endif( OSX_COCOA_BACKEND )
|
||||
else( WIN32 )
|
||||
set( EXTRA_HEADER_DIRS sdl/*.h )
|
||||
set( EXTRA_HEADER_DIRS posix/*.h posix/sdl/*.h )
|
||||
endif( WIN32 )
|
||||
file( GLOB HEADER_FILES
|
||||
${EXTRA_HEADER_DIRS}
|
||||
|
@ -712,9 +692,11 @@ file( GLOB HEADER_FILES
|
|||
menu/*.h
|
||||
oplsynth/*.h
|
||||
oplsynth/dosbox/*.h
|
||||
posix/*.h
|
||||
posix/cocoa/*.h
|
||||
posix/sdl/*.h
|
||||
r_data/*.h
|
||||
resourcefiles/*.h
|
||||
sdl/*.h
|
||||
sfmt/*.h
|
||||
sound/*.h
|
||||
textures/*.h
|
||||
|
@ -1226,7 +1208,7 @@ 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" )
|
||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/posix/osx/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" )
|
||||
|
@ -1249,7 +1231,6 @@ 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\\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("Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/cocoa/.+")
|
||||
source_group("Decorate++" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/thingdef/.+")
|
||||
source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fragglescript/.+")
|
||||
source_group("Games\\Doom Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_doom/.+")
|
||||
|
@ -1266,7 +1247,10 @@ source_group("Render Data\\Resource Sources" REGULAR_EXPRESSION "^${CMAKE_CURREN
|
|||
source_group("Render Data\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/.+")
|
||||
source_group("Render Interface" FILES r_defs.h r_renderer.h r_sky.cpp r_sky.h r_state.h r_utility.cpp r_utility.h)
|
||||
source_group("Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/.+")
|
||||
source_group("SDL Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sdl/.+")
|
||||
source_group("POSIX Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/.+")
|
||||
source_group("Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/cocoa/.+")
|
||||
source_group("OS X Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/osx/.+")
|
||||
source_group("SDL Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/sdl/.+")
|
||||
source_group("SFMT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+")
|
||||
source_group("Shared Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_shared/.+")
|
||||
source_group("Versioning" FILES version.h win32/zdoom.rc)
|
||||
|
|
|
@ -752,6 +752,7 @@ public:
|
|||
// These also set CF_INTERPVIEW for players.
|
||||
void SetPitch(int p, bool interpolate);
|
||||
void SetAngle(angle_t ang, bool interpolate);
|
||||
void SetRoll(angle_t roll, bool interpolate);
|
||||
|
||||
PClassActor *GetBloodType(int type = 0) const
|
||||
{
|
||||
|
@ -955,6 +956,9 @@ public:
|
|||
FNameNoInit DeathType;
|
||||
PClassActor *TeleFogSourceType;
|
||||
PClassActor *TeleFogDestType;
|
||||
int RipperLevel;
|
||||
int RipLevelMin;
|
||||
int RipLevelMax;
|
||||
|
||||
FState *SpawnState;
|
||||
FState *SeeState;
|
||||
|
|
|
@ -130,7 +130,6 @@ private:
|
|||
|
||||
protected:
|
||||
bool ctf;
|
||||
int loaded_bots;
|
||||
int t_join;
|
||||
bool observer; //Consoleplayer is observer.
|
||||
};
|
||||
|
@ -188,12 +187,12 @@ public:
|
|||
fixed_t oldy;
|
||||
|
||||
private:
|
||||
//(B_think.cpp)
|
||||
//(b_think.cpp)
|
||||
void Think ();
|
||||
void ThinkForMove (ticcmd_t *cmd);
|
||||
void Set_enemy ();
|
||||
|
||||
//(B_func.cpp)
|
||||
//(b_func.cpp)
|
||||
bool Reachable (AActor *target);
|
||||
void Dofire (ticcmd_t *cmd);
|
||||
AActor *Choose_Mate ();
|
||||
|
|
|
@ -177,9 +177,12 @@ void FCajunMaster::End ()
|
|||
if (deathmatch)
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (players[i].Bot != NULL)
|
||||
{
|
||||
getspawned.Push(players[i].userinfo.GetName());
|
||||
}
|
||||
}
|
||||
|
||||
wanted_botnum = botnum;
|
||||
}
|
||||
|
@ -216,19 +219,16 @@ bool FCajunMaster::SpawnBot (const char *name, int color)
|
|||
"\\color\\cf df 90" //10 = Bleached Bone
|
||||
};
|
||||
|
||||
botinfo_t *thebot;
|
||||
int botshift;
|
||||
botinfo_t *thebot = botinfo;
|
||||
int botshift = 0;
|
||||
|
||||
if (name)
|
||||
{
|
||||
thebot = botinfo;
|
||||
|
||||
// Check if exist or already in the game.
|
||||
botshift = 0;
|
||||
while (thebot && stricmp (name, thebot->name))
|
||||
{
|
||||
thebot = thebot->next;
|
||||
botshift++;
|
||||
thebot = thebot->next;
|
||||
}
|
||||
|
||||
if (thebot == NULL)
|
||||
|
@ -246,29 +246,38 @@ bool FCajunMaster::SpawnBot (const char *name, int color)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
else if (botnum < loaded_bots)
|
||||
{
|
||||
bool vacant = false; //Spawn a random bot from bots.cfg if no name given.
|
||||
while (!vacant)
|
||||
{
|
||||
int rnum = (pr_botspawn() % loaded_bots);
|
||||
thebot = botinfo;
|
||||
botshift = 0;
|
||||
while (rnum)
|
||||
{
|
||||
--rnum, thebot = thebot->next;
|
||||
botshift++;
|
||||
}
|
||||
if (thebot->inuse == BOTINUSE_No)
|
||||
vacant = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Spawn a random bot from bots.cfg if no name given.
|
||||
TArray<botinfo_t *> BotInfoAvailable;
|
||||
|
||||
while (thebot)
|
||||
{
|
||||
if (thebot->inuse == BOTINUSE_No)
|
||||
BotInfoAvailable.Push (thebot);
|
||||
|
||||
thebot = thebot->next;
|
||||
}
|
||||
|
||||
if (BotInfoAvailable.Size () == 0)
|
||||
{
|
||||
Printf ("Couldn't spawn bot; no bot left in %s\n", BOTFILENAME);
|
||||
return false;
|
||||
}
|
||||
|
||||
thebot = BotInfoAvailable[pr_botspawn() % BotInfoAvailable.Size ()];
|
||||
|
||||
botinfo_t *thebot2 = botinfo;
|
||||
while (thebot2)
|
||||
{
|
||||
if (thebot == thebot2)
|
||||
break;
|
||||
|
||||
botshift++;
|
||||
thebot2 = thebot2->next;
|
||||
}
|
||||
}
|
||||
|
||||
thebot->inuse = BOTINUSE_Waiting;
|
||||
|
||||
Net_WriteByte (DEM_ADDBOT);
|
||||
|
@ -478,7 +487,6 @@ void FCajunMaster::ForgetBots ()
|
|||
}
|
||||
|
||||
botinfo = NULL;
|
||||
loaded_bots = 0;
|
||||
}
|
||||
|
||||
bool FCajunMaster::LoadBots ()
|
||||
|
@ -486,6 +494,7 @@ bool FCajunMaster::LoadBots ()
|
|||
FScanner sc;
|
||||
FString tmp;
|
||||
bool gotteam = false;
|
||||
int loaded_bots = 0;
|
||||
|
||||
bglobal.ForgetBots ();
|
||||
tmp = M_GetCajunPath(BOTFILENAME);
|
||||
|
@ -602,9 +611,9 @@ bool FCajunMaster::LoadBots ()
|
|||
newinfo->next = bglobal.botinfo;
|
||||
newinfo->lastteam = TEAM_NONE;
|
||||
bglobal.botinfo = newinfo;
|
||||
bglobal.loaded_bots++;
|
||||
loaded_bots++;
|
||||
}
|
||||
Printf ("%d bots read from %s\n", bglobal.loaded_bots, BOTFILENAME);
|
||||
Printf ("%d bots read from %s\n", loaded_bots, BOTFILENAME);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -898,8 +898,8 @@ CCMD(info)
|
|||
linetarget->SpawnHealth());
|
||||
PrintMiscActorInfo(linetarget);
|
||||
}
|
||||
else Printf("No target found. Info cannot find actors that have\
|
||||
the NOBLOCKMAP flag or have height/radius of 0.\n");
|
||||
else Printf("No target found. Info cannot find actors that have "
|
||||
"the NOBLOCKMAP flag or have height/radius of 0.\n");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -185,6 +185,9 @@ static const char *KeyConfCommands[] =
|
|||
"clearplayerclasses"
|
||||
};
|
||||
|
||||
static TArray<FString> StoredStartupSets;
|
||||
static bool RunningStoredStartups;
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLASS (DWaitingCommand)
|
||||
|
@ -537,6 +540,18 @@ void ResetButtonStates ()
|
|||
}
|
||||
}
|
||||
|
||||
void C_ExecStoredSets()
|
||||
{
|
||||
assert(!RunningStoredStartups);
|
||||
RunningStoredStartups = true;
|
||||
for (unsigned i = 0; i < StoredStartupSets.Size(); ++i)
|
||||
{
|
||||
C_DoCommand(StoredStartupSets[i]);
|
||||
}
|
||||
StoredStartupSets.Clear();
|
||||
RunningStoredStartups = false;
|
||||
}
|
||||
|
||||
void C_DoCommand (const char *cmd, int keynum)
|
||||
{
|
||||
FConsoleCommand *com;
|
||||
|
@ -612,7 +627,22 @@ void C_DoCommand (const char *cmd, int keynum)
|
|||
|
||||
if ( (com = FindNameInHashTable (Commands, beg, len)) )
|
||||
{
|
||||
if (gamestate != GS_STARTUP || ParsingKeyConf ||
|
||||
if (gamestate == GS_STARTUP && !RunningStoredStartups &&
|
||||
len == 3 && strnicmp(beg, "set", 3) == 0)
|
||||
{
|
||||
// Save setting of unknown cvars for later, in case a loaded wad has a
|
||||
// CVARINFO that defines it.
|
||||
FCommandLine args(beg);
|
||||
if (args.argc() > 1 && FindCVar(args[1], NULL) == NULL)
|
||||
{
|
||||
StoredStartupSets.Push(beg);
|
||||
}
|
||||
else
|
||||
{
|
||||
com->Run(args, players[consoleplayer].mo, keynum);
|
||||
}
|
||||
}
|
||||
else if (gamestate != GS_STARTUP || ParsingKeyConf ||
|
||||
(len == 3 && strnicmp (beg, "set", 3) == 0) ||
|
||||
(len == 7 && strnicmp (beg, "logfile", 7) == 0) ||
|
||||
(len == 9 && strnicmp (beg, "unbindall", 9) == 0) ||
|
||||
|
@ -657,12 +687,15 @@ void C_DoCommand (const char *cmd, int keynum)
|
|||
}
|
||||
else
|
||||
{ // We don't know how to handle this command
|
||||
char cmdname[64];
|
||||
size_t minlen = MIN<size_t> (len, 63);
|
||||
|
||||
memcpy (cmdname, beg, minlen);
|
||||
cmdname[len] = 0;
|
||||
Printf ("Unknown command \"%s\"\n", cmdname);
|
||||
if (gamestate == GS_STARTUP && !RunningStoredStartups)
|
||||
{
|
||||
// Save it for later, in case a CVARINFO defines it.
|
||||
StoredStartupSets.Push(beg);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf ("Unknown command \"%.*s\"\n", len, beg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ class APlayerPawn;
|
|||
extern bool CheckCheatmode (bool printmsg = true);
|
||||
|
||||
void C_ExecCmdLineParams ();
|
||||
void C_ExecStoredSets();
|
||||
|
||||
// Add commands to the console as if they were typed in. Can handle wait
|
||||
// and semicolon-separated commands. This function may modify the source
|
||||
|
|
|
@ -1,926 +0,0 @@
|
|||
// 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
|
|
@ -1,108 +0,0 @@
|
|||
// 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
|
File diff suppressed because it is too large
Load diff
|
@ -1,361 +0,0 @@
|
|||
// 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
|
File diff suppressed because it is too large
Load diff
|
@ -1,417 +0,0 @@
|
|||
// 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_
|
|
@ -1,619 +0,0 @@
|
|||
// 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
|
|
@ -1,422 +0,0 @@
|
|||
// 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__ //
|
|
@ -1,509 +0,0 @@
|
|||
// 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
|
|
@ -1,339 +0,0 @@
|
|||
// 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___ //
|
|
@ -1,111 +0,0 @@
|
|||
// 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___
|
|
@ -1,108 +0,0 @@
|
|||
// 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
|
|
@ -1,50 +0,0 @@
|
|||
// 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);
|
File diff suppressed because it is too large
Load diff
|
@ -1,830 +0,0 @@
|
|||
/*
|
||||
** 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 )
|
||||
{
|
||||
assert(NULL != device);
|
||||
assert(IOHIDDeviceGetTypeID() == CFGetTypeID(device));
|
||||
|
||||
CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
|
||||
assert(NULL != elements);
|
||||
assert(CFArrayGetTypeID() == CFGetTypeID(elements));
|
||||
|
||||
for (CFIndex i = 0, count = CFArrayGetCount(elements); i < count; ++i)
|
||||
{
|
||||
const IOHIDElementRef element =
|
||||
static_cast<IOHIDElementRef>(const_cast<void*>(CFArrayGetValueAtIndex(elements, i)));
|
||||
assert(NULL != element);
|
||||
assert(IOHIDElementGetTypeID() == CFGetTypeID(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 );
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(elements);
|
||||
|
||||
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
|
|
@ -343,6 +343,10 @@ static void CT_ClearChatMessage ()
|
|||
|
||||
static void ShoveChatStr (const char *str, BYTE who)
|
||||
{
|
||||
// Don't send empty messages
|
||||
if (str == NULL || str[0] == '\0')
|
||||
return;
|
||||
|
||||
FString substBuff;
|
||||
|
||||
if (str[0] == '/' &&
|
||||
|
|
|
@ -2275,6 +2275,8 @@ void D_DoomMain (void)
|
|||
execFiles = Args->GatherFiles ("-exec");
|
||||
D_MultiExec (execFiles, true);
|
||||
|
||||
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
|
||||
|
||||
CopyFiles(allwads, pwads);
|
||||
|
||||
// Since this function will never leave we must delete this array here manually.
|
||||
|
@ -2290,7 +2292,8 @@ void D_DoomMain (void)
|
|||
// Now that wads are loaded, define mod-specific cvars.
|
||||
ParseCVarInfo();
|
||||
|
||||
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
|
||||
// Try setting previously unknown cvars again, as a CVARINFO may have made them known.
|
||||
C_ExecStoredSets();
|
||||
|
||||
// [RH] Initialize localizable strings.
|
||||
GStrings.LoadStrings (false);
|
||||
|
|
|
@ -185,7 +185,7 @@ static struct TicSpecial
|
|||
size_t used[BACKUPTICS];
|
||||
BYTE *streamptr;
|
||||
size_t streamoffs;
|
||||
int specialsize;
|
||||
size_t specialsize;
|
||||
int lastmaketic;
|
||||
bool okay;
|
||||
|
||||
|
@ -224,11 +224,11 @@ static struct TicSpecial
|
|||
}
|
||||
|
||||
// Make more room for special commands.
|
||||
void GetMoreSpace ()
|
||||
void GetMoreSpace (size_t needed)
|
||||
{
|
||||
int i;
|
||||
|
||||
specialsize <<= 1;
|
||||
specialsize = MAX(specialsize * 2, needed + 30);
|
||||
|
||||
DPrintf ("Expanding special size to %d\n", specialsize);
|
||||
|
||||
|
@ -240,8 +240,8 @@ static struct TicSpecial
|
|||
|
||||
void CheckSpace (size_t needed)
|
||||
{
|
||||
if (streamoffs >= specialsize - needed)
|
||||
GetMoreSpace ();
|
||||
if (streamoffs + needed >= specialsize)
|
||||
GetMoreSpace (streamoffs + needed);
|
||||
|
||||
streamoffs += needed;
|
||||
}
|
||||
|
@ -669,9 +669,8 @@ void PlayerIsGone (int netnode, int netconsole)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (!nodeingame[netnode])
|
||||
return;
|
||||
|
||||
if (nodeingame[netnode])
|
||||
{
|
||||
for (i = netnode + 1; i < doomcom.numnodes; ++i)
|
||||
{
|
||||
if (nodeingame[i])
|
||||
|
@ -688,6 +687,20 @@ void PlayerIsGone (int netnode, int netconsole)
|
|||
}
|
||||
nodeingame[netnode] = false;
|
||||
nodejustleft[netnode] = false;
|
||||
}
|
||||
else if (nodejustleft[netnode]) // Packet Server
|
||||
{
|
||||
if (netnode + 1 == doomcom.numnodes)
|
||||
{
|
||||
doomcom.numnodes = netnode;
|
||||
}
|
||||
if (playeringame[netconsole])
|
||||
{
|
||||
players[netconsole].playerstate = PST_GONE;
|
||||
}
|
||||
nodejustleft[netnode] = false;
|
||||
}
|
||||
else return;
|
||||
|
||||
if (netconsole == Net_Arbitrator)
|
||||
{
|
||||
|
@ -790,7 +803,6 @@ void GetPackets (void)
|
|||
else
|
||||
{
|
||||
nodeingame[netnode] = false;
|
||||
playeringame[netconsole] = false;
|
||||
nodejustleft[netnode] = true;
|
||||
}
|
||||
continue;
|
||||
|
@ -1064,16 +1076,16 @@ void NetUpdate (void)
|
|||
|
||||
if (consoleplayer == Net_Arbitrator)
|
||||
{
|
||||
for (j = 0; j < doomcom.numnodes; j++)
|
||||
if (NetMode == NET_PacketServer)
|
||||
{
|
||||
if (nodeingame[j] && NetMode == NET_PacketServer)
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
{
|
||||
if (playeringame[j] && players[j].Bot == NULL)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (NetMode == NET_PacketServer)
|
||||
{
|
||||
// The loop above added the local player to the count a second time,
|
||||
// and it also added the player being sent the packet to the count.
|
||||
count -= 2;
|
||||
|
@ -1203,12 +1215,15 @@ void NetUpdate (void)
|
|||
netbuffer[0] |= NCMD_MULTI;
|
||||
netbuffer[k++] = count;
|
||||
|
||||
for (l = 1, j = 0; j < doomcom.numnodes; j++)
|
||||
if (NetMode == NET_PacketServer)
|
||||
{
|
||||
if (nodeingame[j] && j != i && j != nodeforplayer[consoleplayer] && NetMode == NET_PacketServer)
|
||||
for (l = 1, j = 0; j < MAXPLAYERS; j++)
|
||||
{
|
||||
playerbytes[l++] = playerfornode[j];
|
||||
netbuffer[k++] = playerfornode[j];
|
||||
if (playeringame[j] && players[j].Bot == NULL && j != playerfornode[i] && j != consoleplayer)
|
||||
{
|
||||
playerbytes[l++] = j;
|
||||
netbuffer[k++] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,6 +160,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
|
|||
|
||||
P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, 0);
|
||||
}
|
||||
if (!(target->flags7 & MF7_DONTTHRUST))
|
||||
{
|
||||
target->velz = Scale(thrust, 1000, target->Mass);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1287,6 +1287,7 @@ void G_InitLevelLocals ()
|
|||
level.teamdamage = teamdamage;
|
||||
level.flags = 0;
|
||||
level.flags2 = 0;
|
||||
level.flags3 = 0;
|
||||
|
||||
info = FindLevelInfo (level.MapName);
|
||||
|
||||
|
@ -1340,6 +1341,7 @@ void G_InitLevelLocals ()
|
|||
level.clusterflags = clus ? clus->flags : 0;
|
||||
level.flags |= info->flags;
|
||||
level.flags2 |= info->flags2;
|
||||
level.flags3 |= info->flags3;
|
||||
level.levelnum = info->levelnum;
|
||||
level.Music = info->Music;
|
||||
level.musicorder = info->musicorder;
|
||||
|
|
|
@ -214,6 +214,9 @@ enum ELevelFlags
|
|||
LEVEL2_ENDGAME = 0x20000000, // This is an epilogue level that cannot be quit.
|
||||
LEVEL2_NOAUTOSAVEHINT = 0x40000000, // tell the game that an autosave for this level does not need to be kept
|
||||
LEVEL2_FORGETSTATE = 0x80000000, // forget this map's state in a hub
|
||||
|
||||
// More flags!
|
||||
LEVEL3_FORCEFAKECONTRAST = 0x00000001, // forces fake contrast even with fog enabled
|
||||
};
|
||||
|
||||
|
||||
|
@ -283,6 +286,8 @@ struct level_info_t
|
|||
int sucktime;
|
||||
DWORD flags;
|
||||
DWORD flags2;
|
||||
DWORD flags3;
|
||||
|
||||
FString Music;
|
||||
FString LevelName;
|
||||
SBYTE WallVertLight, WallHorizLight;
|
||||
|
@ -396,6 +401,7 @@ struct FLevelLocals
|
|||
|
||||
DWORD flags;
|
||||
DWORD flags2;
|
||||
DWORD flags3;
|
||||
|
||||
DWORD fadeto; // The color the palette fades to (usually black)
|
||||
DWORD outsidefog; // The fog for sectors with sky ceilings
|
||||
|
|
|
@ -1190,6 +1190,9 @@ enum EMIType
|
|||
MITYPE_SETFLAG2,
|
||||
MITYPE_CLRFLAG2,
|
||||
MITYPE_SCFLAGS2,
|
||||
MITYPE_SETFLAG3,
|
||||
MITYPE_CLRFLAG3,
|
||||
MITYPE_SCFLAGS3,
|
||||
MITYPE_COMPATFLAG,
|
||||
};
|
||||
|
||||
|
@ -1275,6 +1278,7 @@ MapFlagHandlers[] =
|
|||
{ "rememberstate", MITYPE_CLRFLAG2, LEVEL2_FORGETSTATE, 0 },
|
||||
{ "unfreezesingleplayerconversations",MITYPE_SETFLAG2, LEVEL2_CONV_SINGLE_UNFREEZE, 0 },
|
||||
{ "spawnwithweaponraised", MITYPE_SETFLAG2, LEVEL2_PRERAISEWEAPON, 0 },
|
||||
{ "forcefakecontrast", MITYPE_SETFLAG3, LEVEL3_FORCEFAKECONTRAST, 0 },
|
||||
{ "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes
|
||||
{ "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 0 },
|
||||
{ "compat_stairs", MITYPE_COMPATFLAG, COMPATF_STAIRINDEX, 0 },
|
||||
|
@ -1372,6 +1376,20 @@ void FMapInfoParser::ParseMapDefinition(level_info_t &info)
|
|||
info.flags2 = (info.flags2 & handler->data2) | handler->data1;
|
||||
break;
|
||||
|
||||
case MITYPE_SETFLAG3:
|
||||
info.flags3 |= handler->data1;
|
||||
info.flags3 |= handler->data2;
|
||||
break;
|
||||
|
||||
case MITYPE_CLRFLAG3:
|
||||
info.flags3 &= ~handler->data1;
|
||||
info.flags3 |= handler->data2;
|
||||
break;
|
||||
|
||||
case MITYPE_SCFLAGS3:
|
||||
info.flags3 = (info.flags3 & handler->data2) | handler->data1;
|
||||
break;
|
||||
|
||||
case MITYPE_COMPATFLAG:
|
||||
{
|
||||
int set = 1;
|
||||
|
|
|
@ -529,9 +529,10 @@ bool P_MorphedDeath(AActor *actor, AActor **morphed, int *morphedstyle, int *mor
|
|||
{
|
||||
AMorphedMonster *fakeme = static_cast<AMorphedMonster *>(actor);
|
||||
AActor *realme = fakeme->UnmorphedMe;
|
||||
if (realme != NULL)
|
||||
{
|
||||
if ((fakeme->UnmorphTime) &&
|
||||
(fakeme->MorphStyle & MORPH_UNDOBYDEATH) &&
|
||||
(realme))
|
||||
(fakeme->MorphStyle & MORPH_UNDOBYDEATH))
|
||||
{
|
||||
int realstyle = fakeme->MorphStyle;
|
||||
int realhealth = fakeme->health;
|
||||
|
@ -551,6 +552,7 @@ bool P_MorphedDeath(AActor *actor, AActor **morphed, int *morphedstyle, int *mor
|
|||
VMValue params[3] = { realme, realme, VMValue(NULL, ATAG_STATE) };
|
||||
stack.Call(A_BossDeath_VMPtr, params, countof(params), NULL, 0, NULL);
|
||||
}
|
||||
}
|
||||
fakeme->flags3 |= MF3_STAYMORPHED; // moved here from AMorphedMonster::Die()
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1215,7 +1215,11 @@ public:
|
|||
if(Scaled)
|
||||
{
|
||||
if(cx != 0 || cy != 0)
|
||||
{
|
||||
screen->VirtualToRealCoords(dcx, dcy, tmp, tmp, script->resW, script->resH, true);
|
||||
if (cx == 0) dcx = 0;
|
||||
if (cy == 0) dcy = 0;
|
||||
}
|
||||
if(cr != 0 || cb != 0 || clearDontDraw)
|
||||
screen->VirtualToRealCoords(dcr, dcb, tmp, tmp, script->resW, script->resH, true);
|
||||
screen->VirtualToRealCoords(dx, dy, w, h, script->resW, script->resH, true);
|
||||
|
@ -1276,8 +1280,8 @@ public:
|
|||
|
||||
// We can't use DTA_HUDRules since it forces a width and height.
|
||||
// Translation: No high res.
|
||||
bool xright = rx < 0;
|
||||
bool ybot = ry < 0;
|
||||
bool xright = *x < 0 && !x.RelCenter();
|
||||
bool ybot = *y < 0 && !y.RelCenter();
|
||||
|
||||
w = (forceWidth < 0 ? texture->GetScaledWidthDouble() : forceWidth);
|
||||
h = (forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight);
|
||||
|
|
|
@ -14,27 +14,27 @@ class ALoreShot : public AActor
|
|||
{
|
||||
DECLARE_CLASS (ALoreShot, AActor)
|
||||
public:
|
||||
int DoSpecialDamage (AActor *target, int damage, FName damagetype);
|
||||
int DoSpecialDamage (AActor *victim, int damage, FName damagetype);
|
||||
};
|
||||
|
||||
IMPLEMENT_CLASS (ALoreShot)
|
||||
|
||||
int ALoreShot::DoSpecialDamage (AActor *target, int damage, FName damagetype)
|
||||
int ALoreShot::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
|
||||
{
|
||||
FVector3 thrust;
|
||||
|
||||
if (this->target != NULL)
|
||||
if (victim != NULL && target != NULL && !(victim->flags7 & MF7_DONTTHRUST))
|
||||
{
|
||||
thrust.X = float(this->target->x - target->x);
|
||||
thrust.Y = float(this->target->y - target->y);
|
||||
thrust.Z = float(this->target->z - target->z);
|
||||
thrust.X = float(target->x - victim->x);
|
||||
thrust.Y = float(target->y - victim->y);
|
||||
thrust.Z = float(target->z - victim->z);
|
||||
|
||||
thrust.MakeUnit();
|
||||
thrust *= float((255*50*FRACUNIT) / (target->Mass ? target->Mass : 1));
|
||||
thrust *= float((255*50*FRACUNIT) / (victim->Mass ? victim->Mass : 1));
|
||||
|
||||
target->velx += fixed_t(thrust.X);
|
||||
target->vely += fixed_t(thrust.Y);
|
||||
target->velz += fixed_t(thrust.Z);
|
||||
victim->velx += fixed_t(thrust.X);
|
||||
victim->vely += fixed_t(thrust.Y);
|
||||
victim->velz += fixed_t(thrust.Z);
|
||||
}
|
||||
return damage;
|
||||
}
|
||||
|
|
|
@ -601,7 +601,7 @@ private:
|
|||
screen->DrawText(SmallFont2, CR_UNTRANSLATED, left + 210 * xscale, top + 8 * yscale, buff,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
|
||||
if (CPlayer->LogText != NULL)
|
||||
if (CPlayer->LogText.IsNotEmpty())
|
||||
{
|
||||
FBrokenLines *lines = V_BreakLines(SmallFont2, 272, CPlayer->LogText);
|
||||
for (i = 0; lines[i].Width >= 0; ++i)
|
||||
|
|
|
@ -300,7 +300,12 @@ void FListMenuItem::DrawSelector(int xofs, int yofs, FTextureID tex)
|
|||
if ((DMenu::MenuTime%8) < 6)
|
||||
{
|
||||
screen->DrawText(ConFont, OptionSettings.mFontColorSelection,
|
||||
mXpos + xofs, mYpos + yofs, "\xd", DTA_Clean, true, TAG_DONE);
|
||||
(mXpos + xofs - 160) * CleanXfac + screen->GetWidth() / 2,
|
||||
(mYpos + yofs - 100) * CleanYfac + screen->GetHeight() / 2,
|
||||
"\xd",
|
||||
DTA_CellX, 8 * CleanXfac,
|
||||
DTA_CellY, 8 * CleanYfac,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -247,8 +247,12 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits)
|
|||
if (Video != NULL)
|
||||
{
|
||||
while ((haveMode = Video->NextMode (&width, &height, &letterbox)) &&
|
||||
(ratiomatch >= 0 && CheckRatio (width, height) != ratiomatch))
|
||||
ratiomatch >= 0)
|
||||
{
|
||||
int ratio;
|
||||
CheckRatio (width, height, &ratio);
|
||||
if (ratio == ratiomatch)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -968,10 +968,12 @@ CCMD (dump3df)
|
|||
fixed_t height=ffloors[i]->top.plane->ZatPoint(CenterSpot(sector));
|
||||
fixed_t bheight=ffloors[i]->bottom.plane->ZatPoint(CenterSpot(sector));
|
||||
|
||||
IGNORE_FORMAT_PRE
|
||||
Printf("FFloor %d @ top = %f (model = %d), bottom = %f (model = %d), flags = %B, alpha = %d %s %s\n",
|
||||
i, height / 65536., ffloors[i]->top.model->sectornum,
|
||||
bheight / 65536., ffloors[i]->bottom.model->sectornum,
|
||||
ffloors[i]->flags, ffloors[i]->alpha, (ffloors[i]->flags&FF_EXISTS)? "Exists":"", (ffloors[i]->flags&FF_DYNAMIC)? "Dynamic":"");
|
||||
IGNORE_FORMAT_POST
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2393,7 +2393,7 @@ void FBehavior::LoadScriptsDirectory ()
|
|||
int size = LittleLong(scripts.dw[1]);
|
||||
if (size >= 6)
|
||||
{
|
||||
int script_num = LittleShort(scripts.w[4]);
|
||||
int script_num = LittleShort(scripts.sw[4]);
|
||||
ScriptPtr *ptr = const_cast<ScriptPtr *>(FindScript(script_num));
|
||||
if (ptr != NULL)
|
||||
{
|
||||
|
@ -4439,6 +4439,9 @@ enum EACSFunctions
|
|||
ACSF_CanRaiseActor,
|
||||
ACSF_SetActorTeleFog, // 86
|
||||
ACSF_SwapActorTeleFog,
|
||||
ACSF_SetActorRoll,
|
||||
ACSF_ChangeActorRoll,
|
||||
ACSF_GetActorRoll,
|
||||
|
||||
/* Zandronum's - these must be skipped when we reach 99!
|
||||
-100:ResetMap(0),
|
||||
|
@ -4743,6 +4746,27 @@ static void SetActorPitch(AActor *activator, int tid, int angle, bool interpolat
|
|||
}
|
||||
}
|
||||
|
||||
static void SetActorRoll(AActor *activator, int tid, int angle, bool interpolate)
|
||||
{
|
||||
if (tid == 0)
|
||||
{
|
||||
if (activator != NULL)
|
||||
{
|
||||
activator->SetRoll(angle << 16, interpolate);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FActorIterator iterator(tid);
|
||||
AActor *actor;
|
||||
|
||||
while ((actor = iterator.Next()))
|
||||
{
|
||||
actor->SetRoll(angle << 16, interpolate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SetActorTeleFog(AActor *activator, int tid, FName telefogsrc, FName telefogdest)
|
||||
{
|
||||
//Simply put, if it doesn't exist, it won't change. One can use "" in this scenario.
|
||||
|
@ -5824,6 +5848,26 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
}
|
||||
break;
|
||||
|
||||
// [Nash] Actor roll functions. Let's roll!
|
||||
case ACSF_SetActorRoll:
|
||||
actor = SingleActorFromTID(args[0], activator);
|
||||
if (actor != NULL)
|
||||
{
|
||||
actor->SetRoll(args[1] << 16, false);
|
||||
}
|
||||
return 0;
|
||||
|
||||
case ACSF_ChangeActorRoll:
|
||||
if (argCount >= 2)
|
||||
{
|
||||
SetActorRoll(activator, args[0], args[1], argCount > 2 ? !!args[2] : false);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACSF_GetActorRoll:
|
||||
actor = SingleActorFromTID(args[0], activator);
|
||||
return actor != NULL? actor->roll >> 16 : 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -7488,22 +7532,9 @@ scriptwait:
|
|||
break;
|
||||
|
||||
case PCD_PRINTBINARY:
|
||||
#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 6)))) || defined(__clang__)
|
||||
#define HAS_DIAGNOSTIC_PRAGMA
|
||||
#endif
|
||||
#ifdef HAS_DIAGNOSTIC_PRAGMA
|
||||
#pragma GCC diagnostic push
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wformat-invalid-specifier"
|
||||
#else
|
||||
#pragma GCC diagnostic ignored "-Wformat="
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wformat-extra-args"
|
||||
#endif
|
||||
IGNORE_FORMAT_PRE
|
||||
work.AppendFormat ("%B", STACK(1));
|
||||
#ifdef HAS_DIAGNOSTIC_PRAGMA
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
IGNORE_FORMAT_POST
|
||||
--sp;
|
||||
break;
|
||||
|
||||
|
|
|
@ -72,7 +72,8 @@ DECLARE_ACTION(A_FreezeDeathChunks)
|
|||
void A_BossDeath(AActor *self);
|
||||
|
||||
void A_Chase(VMFrameStack *stack, AActor *self);
|
||||
void A_FaceTarget (AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270);
|
||||
void A_FaceTarget(AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270);
|
||||
void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270);
|
||||
|
||||
bool A_RaiseMobj (AActor *, fixed_t speed);
|
||||
bool A_SinkMobj (AActor *, fixed_t speed);
|
||||
|
|
|
@ -1273,7 +1273,10 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
|
|||
if (!(flags & DMG_NO_ARMOR) && player->mo->Inventory != NULL)
|
||||
{
|
||||
int newdam = damage;
|
||||
if (damage > 0)
|
||||
{
|
||||
player->mo->Inventory->AbsorbDamage(damage, mod, newdam);
|
||||
}
|
||||
if (damage < TELEFRAG_DAMAGE)
|
||||
{
|
||||
// if we are telefragging don't let the damage value go below that magic value. Some further checks would fail otherwise.
|
||||
|
|
|
@ -519,19 +519,19 @@ FUNC(LS_Generic_Stairs)
|
|||
FUNC(LS_Pillar_Build)
|
||||
// Pillar_Build (tag, speed, height)
|
||||
{
|
||||
return EV_DoPillar (DPillar::pillarBuild, arg0, SPEED(arg1), arg2*FRACUNIT, 0, -1, false);
|
||||
return EV_DoPillar (DPillar::pillarBuild, ln, arg0, SPEED(arg1), arg2*FRACUNIT, 0, -1, false);
|
||||
}
|
||||
|
||||
FUNC(LS_Pillar_BuildAndCrush)
|
||||
// Pillar_BuildAndCrush (tag, speed, height, crush, crushtype)
|
||||
{
|
||||
return EV_DoPillar (DPillar::pillarBuild, arg0, SPEED(arg1), arg2*FRACUNIT, 0, arg3, CRUSHTYPE(arg4));
|
||||
return EV_DoPillar (DPillar::pillarBuild, ln, arg0, SPEED(arg1), arg2*FRACUNIT, 0, arg3, CRUSHTYPE(arg4));
|
||||
}
|
||||
|
||||
FUNC(LS_Pillar_Open)
|
||||
// Pillar_Open (tag, speed, f_height, c_height)
|
||||
{
|
||||
return EV_DoPillar (DPillar::pillarOpen, arg0, SPEED(arg1), arg2*FRACUNIT, arg3*FRACUNIT, -1, false);
|
||||
return EV_DoPillar (DPillar::pillarOpen, ln, arg0, SPEED(arg1), arg2*FRACUNIT, arg3*FRACUNIT, -1, false);
|
||||
}
|
||||
|
||||
FUNC(LS_Ceiling_LowerByValue)
|
||||
|
|
|
@ -133,7 +133,7 @@ enum EPuffFlags
|
|||
PF_NORANDOMZ = 16
|
||||
};
|
||||
|
||||
AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0);
|
||||
AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0, AActor *vict = NULL);
|
||||
void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator);
|
||||
void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator);
|
||||
void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator);
|
||||
|
|
|
@ -887,6 +887,20 @@ bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Isolated to keep the code readable and fix the logic
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static bool CheckRipLevel(AActor *victim, AActor *projectile)
|
||||
{
|
||||
if (victim->RipLevelMin > 0 && projectile->RipperLevel < victim->RipLevelMin) return false;
|
||||
if (victim->RipLevelMax > 0 && projectile->RipperLevel > victim->RipLevelMax) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PIT_CheckThing
|
||||
|
@ -1207,7 +1221,8 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
if (tm.DoRipping && !(thing->flags5 & MF5_DONTRIP))
|
||||
|
||||
if ((tm.DoRipping && !(thing->flags5 & MF5_DONTRIP)) && CheckRipLevel(thing, tm.thing))
|
||||
{
|
||||
if (!(tm.thing->flags6 & MF6_NOBOSSRIP) || !(thing->flags2 & MF2_BOSS))
|
||||
{
|
||||
|
@ -3761,14 +3776,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
|
|||
puffFlags |= PF_HITTHINGBLEED;
|
||||
|
||||
// We must pass the unreplaced puff type here
|
||||
puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING);
|
||||
}
|
||||
|
||||
if (puffDefaults != NULL && trace.Actor != NULL && puff != NULL)
|
||||
{
|
||||
if (puffDefaults->flags7 && MF7_HITTARGET) puff->target = trace.Actor;
|
||||
if (puffDefaults->flags7 && MF7_HITMASTER) puff->master = trace.Actor;
|
||||
if (puffDefaults->flags7 && MF7_HITTRACER) puff->tracer = trace.Actor;
|
||||
puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING, trace.Actor);
|
||||
}
|
||||
|
||||
// Allow puffs to inflict poison damage, so that hitscans can poison, too.
|
||||
|
@ -4214,14 +4222,9 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
|
|||
}
|
||||
if (spawnpuff)
|
||||
{
|
||||
P_SpawnPuff(source, puffclass, x, y, z, (source->angle + angleoffset) - ANG90, 1, puffflags);
|
||||
}
|
||||
if (hitactor != NULL && puffDefaults != NULL && thepuff != NULL)
|
||||
{
|
||||
if (puffDefaults->flags7 & MF7_HITTARGET) thepuff->target = hitactor;
|
||||
if (puffDefaults->flags7 & MF7_HITMASTER) thepuff->master = hitactor;
|
||||
if (puffDefaults->flags7 & MF7_HITTRACER) thepuff->tracer = hitactor;
|
||||
P_SpawnPuff(source, puffclass, x, y, z, (source->angle + angleoffset) - ANG90, 1, puffflags, hitactor);
|
||||
}
|
||||
|
||||
if (puffDefaults && puffDefaults->PoisonDamage > 0 && puffDefaults->PoisonDuration != INT_MIN)
|
||||
{
|
||||
P_PoisonMobj(hitactor, thepuff ? thepuff : source, source, puffDefaults->PoisonDamage, puffDefaults->PoisonDuration, puffDefaults->PoisonPeriod, puffDefaults->PoisonDamageType);
|
||||
|
@ -4282,7 +4285,7 @@ CVAR(Float, chase_dist, 90.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
|||
|
||||
void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &CameraZ, sector_t *&CameraSector)
|
||||
{
|
||||
fixed_t distance = (fixed_t)(chase_dist * FRACUNIT);
|
||||
fixed_t distance = (fixed_t)(clamp<double>(chase_dist, 0, 30000) * FRACUNIT);
|
||||
angle_t angle = (t1->angle - ANG180) >> ANGLETOFINESHIFT;
|
||||
angle_t pitch = (angle_t)(t1->pitch) >> ANGLETOFINESHIFT;
|
||||
FTraceResults trace;
|
||||
|
@ -4292,7 +4295,7 @@ void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &Camera
|
|||
vy = FixedMul(finecosine[pitch], finesine[angle]);
|
||||
vz = finesine[pitch];
|
||||
|
||||
sz = t1->z - t1->floorclip + t1->height + (fixed_t)(chase_height * FRACUNIT);
|
||||
sz = t1->z - t1->floorclip + t1->height + (fixed_t)(clamp<double>(chase_height, -1000, 1000) * FRACUNIT);
|
||||
|
||||
if (Trace(t1->x, t1->y, sz, t1->Sector,
|
||||
vx, vy, vz, distance, 0, 0, NULL, trace) &&
|
||||
|
@ -4768,7 +4771,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo
|
|||
points *= thing->GetClass()->RDFactor / (float)FRACUNIT;
|
||||
|
||||
// points and bombdamage should be the same sign
|
||||
if ((points * bombdamage) > 0 && P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))
|
||||
if (((bombspot->flags7 & MF7_CAUSEPAIN) || (points * bombdamage) > 0) && P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))
|
||||
{ // OK to damage; target is in direct path
|
||||
double velz;
|
||||
double thrust;
|
||||
|
|
103
src/p_mobj.cpp
103
src/p_mobj.cpp
|
@ -423,6 +423,13 @@ void AActor::Serialize (FArchive &arc)
|
|||
arc << TeleFogSourceType
|
||||
<< TeleFogDestType;
|
||||
}
|
||||
if (SaveVersion >= 4518)
|
||||
{
|
||||
arc << RipperLevel
|
||||
<< RipLevelMin
|
||||
<< RipLevelMax;
|
||||
}
|
||||
|
||||
{
|
||||
FString tagstr;
|
||||
if (arc.IsStoring() && Tag != NULL && Tag->Len() > 0) tagstr = *Tag;
|
||||
|
@ -2056,48 +2063,46 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
|
|||
// Don't change the angle if there's THRUREFLECT on the monster.
|
||||
if (!(BlockingMobj->flags7 & MF7_THRUREFLECT))
|
||||
{
|
||||
int dir;
|
||||
angle_t delta;
|
||||
|
||||
if (BlockingMobj->flags7 & MF7_MIRRORREFLECT)
|
||||
angle = mo->angle + ANG180;
|
||||
else
|
||||
//int dir;
|
||||
//angle_t delta;
|
||||
angle = R_PointToAngle2(BlockingMobj->x, BlockingMobj->y, mo->x, mo->y);
|
||||
|
||||
bool dontReflect = (mo->AdjustReflectionAngle(BlockingMobj, angle));
|
||||
// Change angle for deflection/reflection
|
||||
// AIMREFLECT calls precedence so make sure not to bother with adjusting here if declared.
|
||||
if (!(BlockingMobj->flags7 & MF7_AIMREFLECT) && (mo->AdjustReflectionAngle(BlockingMobj, angle)))
|
||||
{
|
||||
goto explode;
|
||||
}
|
||||
|
||||
// Reflect the missile along angle
|
||||
if (BlockingMobj->flags7 & MF7_AIMREFLECT)
|
||||
if (!dontReflect)
|
||||
{
|
||||
dir = P_FaceMobj(mo, mo->target, &delta);
|
||||
if (dir)
|
||||
{ // Turn clockwise
|
||||
mo->angle += delta;
|
||||
}
|
||||
else
|
||||
{ // Turn counter clockwise
|
||||
mo->angle -= delta;
|
||||
}
|
||||
angle = mo->angle >> ANGLETOFINESHIFT;
|
||||
mo->velx = FixedMul(mo->Speed, finecosine[angle]);
|
||||
mo->vely = FixedMul(mo->Speed, finesine[angle]);
|
||||
mo->velz = -mo->velz;
|
||||
bool tg = (mo->target != NULL);
|
||||
bool blockingtg = (BlockingMobj->target != NULL);
|
||||
if (BlockingMobj->flags7 & MF7_AIMREFLECT && (tg || blockingtg))
|
||||
{
|
||||
AActor *origin;
|
||||
if (tg)
|
||||
origin = mo->target;
|
||||
else if (blockingtg)
|
||||
origin = BlockingMobj->target;
|
||||
|
||||
float speed = (float)(mo->Speed);
|
||||
//dest->x - source->x
|
||||
FVector3 velocity(origin->x - mo->x, origin->y - mo->y, (origin->z + (origin->height/2)) - mo->z);
|
||||
velocity.Resize(speed);
|
||||
mo->velx = (fixed_t)(velocity.X);
|
||||
mo->vely = (fixed_t)(velocity.Y);
|
||||
mo->velz = (fixed_t)(velocity.Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
mo->angle = angle;
|
||||
angle >>= ANGLETOFINESHIFT;
|
||||
mo->velx = FixedMul(mo->Speed >> 1, finecosine[angle]);
|
||||
mo->vely = FixedMul(mo->Speed >> 1, finesine[angle]);
|
||||
mo->velz = -mo->velz / 2;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
goto explode;
|
||||
}
|
||||
}
|
||||
if (mo->flags2 & MF2_SEEKERMISSILE)
|
||||
{
|
||||
|
@ -3036,8 +3041,10 @@ bool AActor::AdjustReflectionAngle (AActor *thing, angle_t &angle)
|
|||
if (flags2 & MF2_DONTREFLECT) return true;
|
||||
if (thing->flags7 & MF7_THRUREFLECT) return false;
|
||||
|
||||
if (thing->flags7 & MF7_MIRRORREFLECT)
|
||||
angle += ANGLE_180;
|
||||
// Change angle for reflection
|
||||
if (thing->flags4&MF4_SHIELDREFLECT)
|
||||
else if (thing->flags4&MF4_SHIELDREFLECT)
|
||||
{
|
||||
// Shield reflection (from the Centaur
|
||||
if (abs (angle - thing->angle)>>24 > 45)
|
||||
|
@ -3060,6 +3067,13 @@ bool AActor::AdjustReflectionAngle (AActor *thing, angle_t &angle)
|
|||
else
|
||||
angle -= ANG45;
|
||||
}
|
||||
else if (thing->flags7 & MF7_AIMREFLECT)
|
||||
{
|
||||
if (this->target != NULL)
|
||||
A_Face(this, this->target);
|
||||
else if (thing->target != NULL)
|
||||
A_Face(this, thing->target);
|
||||
}
|
||||
else
|
||||
angle += ANGLE_1 * ((pr_reflect()%16)-8);
|
||||
return false;
|
||||
|
@ -3167,6 +3181,18 @@ void AActor::SetAngle(angle_t ang, bool interpolate)
|
|||
}
|
||||
}
|
||||
|
||||
void AActor::SetRoll(angle_t r, bool interpolate)
|
||||
{
|
||||
if (r != roll)
|
||||
{
|
||||
roll = r;
|
||||
if (player != NULL && interpolate)
|
||||
{
|
||||
player->cheats |= CF_INTERPVIEW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_MobjThinker
|
||||
//
|
||||
|
@ -5029,7 +5055,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
|
|||
// P_SpawnPuff
|
||||
//
|
||||
|
||||
AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags)
|
||||
AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags, AActor *vict)
|
||||
{
|
||||
AActor *puff;
|
||||
|
||||
|
@ -5039,10 +5065,25 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y
|
|||
puff = Spawn (pufftype, x, y, z, ALLOW_REPLACE);
|
||||
if (puff == NULL) return NULL;
|
||||
|
||||
if ((puff->flags4 & MF4_RANDOMIZE) && puff->tics > 0)
|
||||
{
|
||||
puff->tics -= pr_spawnpuff() & 3;
|
||||
if (puff->tics < 1)
|
||||
puff->tics = 1;
|
||||
}
|
||||
|
||||
//Moved puff creation and target/master/tracer setting to here.
|
||||
if (puff && vict)
|
||||
{
|
||||
if (puff->flags7 & MF7_HITTARGET) puff->target = vict;
|
||||
if (puff->flags7 & MF7_HITMASTER) puff->master = vict;
|
||||
if (puff->flags7 & MF7_HITTRACER) puff->tracer = vict;
|
||||
}
|
||||
// [BB] If the puff came from a player, set the target of the puff to this player.
|
||||
if ( puff && (puff->flags5 & MF5_PUFFGETSOWNER))
|
||||
puff->target = source;
|
||||
|
||||
|
||||
if (source != NULL) puff->angle = R_PointToAngle2(x, y, source->x, source->y);
|
||||
|
||||
// If a puff has a crash state and an actor was not hit,
|
||||
|
|
|
@ -212,16 +212,28 @@ DPillar::DPillar (sector_t *sector, EPillar type, fixed_t speed,
|
|||
}
|
||||
}
|
||||
|
||||
bool EV_DoPillar (DPillar::EPillar type, int tag, fixed_t speed, fixed_t height,
|
||||
fixed_t height2, int crush, bool hexencrush)
|
||||
bool EV_DoPillar (DPillar::EPillar type, line_t *line, int tag,
|
||||
fixed_t speed, fixed_t height, fixed_t height2, int crush, bool hexencrush)
|
||||
{
|
||||
int secnum;
|
||||
sector_t *sec;
|
||||
bool rtn = false;
|
||||
int secnum = -1;
|
||||
|
||||
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
|
||||
// check if a manual trigger; if so do just the sector on the backside
|
||||
if (tag == 0)
|
||||
{
|
||||
sector_t *sec = §ors[secnum];
|
||||
if (!line || !(sec = line->backsector))
|
||||
return rtn;
|
||||
secnum = (int)(sec-sectors);
|
||||
goto manual_pillar;
|
||||
}
|
||||
|
||||
secnum = -1;
|
||||
while (tag && (secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
|
||||
manual_pillar:
|
||||
if (sec->PlaneMoving(sector_t::floor) || sec->PlaneMoving(sector_t::ceiling))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -566,7 +566,7 @@ void P_SerializePolyobjs (FArchive &arc)
|
|||
I_Error ("UnarchivePolyobjs: Invalid polyobj tag");
|
||||
}
|
||||
arc << angle;
|
||||
po->RotatePolyobj (angle);
|
||||
po->RotatePolyobj (angle, true);
|
||||
arc << deltaX << deltaY << po->interpolation;
|
||||
deltaX -= po->StartSpot.x;
|
||||
deltaY -= po->StartSpot.y;
|
||||
|
|
|
@ -965,7 +965,7 @@ int side_t::GetLightLevel (bool foggy, int baselight, bool noabsolute, int *pfak
|
|||
*pfakecontrast = 0;
|
||||
}
|
||||
|
||||
if (!foggy) // Don't do relative lighting in foggy sectors
|
||||
if (!foggy || level.flags3 & LEVEL3_FORCEFAKECONTRAST) // Don't do relative lighting in foggy sectors
|
||||
{
|
||||
if (!(Flags & WALLF_NOFAKECONTRAST) && r_fakecontrast != 0)
|
||||
{
|
||||
|
|
|
@ -515,8 +515,8 @@ private:
|
|||
DPillar ();
|
||||
};
|
||||
|
||||
bool EV_DoPillar (DPillar::EPillar type, int tag, fixed_t speed, fixed_t height,
|
||||
fixed_t height2, int crush, bool hexencrush);
|
||||
bool EV_DoPillar (DPillar::EPillar type, line_t *line, int tag,
|
||||
fixed_t speed, fixed_t height, fixed_t height2, int crush, bool hexencrush);
|
||||
|
||||
//
|
||||
// P_DOORS
|
||||
|
|
|
@ -49,11 +49,13 @@ public:
|
|||
|
||||
WORD operator [](FTextureID tex) const
|
||||
{
|
||||
if ((unsigned)tex.GetIndex() >= Types.Size()) return DefaultTerrainType;
|
||||
WORD type = Types[tex.GetIndex()];
|
||||
return type == 0xffff? DefaultTerrainType : type;
|
||||
}
|
||||
WORD operator [](int texnum) const
|
||||
{
|
||||
if ((unsigned)texnum >= Types.Size()) return DefaultTerrainType;
|
||||
WORD type = Types[texnum];
|
||||
return type == 0xffff? DefaultTerrainType : type;
|
||||
}
|
||||
|
|
|
@ -1444,7 +1444,7 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor, int dmgflags)
|
|||
weap->SpawnState != ::GetDefault<AActor>()->SpawnState)
|
||||
{
|
||||
item = P_DropItem (this, weap->GetClass(), -1, 256);
|
||||
if (item != NULL)
|
||||
if (item != NULL && item->IsKindOf(RUNTIME_CLASS(AWeapon)))
|
||||
{
|
||||
if (weap->AmmoGive1 && weap->Ammo1)
|
||||
{
|
||||
|
|
|
@ -1051,7 +1051,7 @@ static void RotatePt (int an, fixed_t *x, fixed_t *y, fixed_t startSpotX, fixed_
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FPolyObj::RotatePolyobj (angle_t angle)
|
||||
bool FPolyObj::RotatePolyobj (angle_t angle, bool fromsave)
|
||||
{
|
||||
int an;
|
||||
bool blocked;
|
||||
|
@ -1073,7 +1073,10 @@ bool FPolyObj::RotatePolyobj (angle_t angle)
|
|||
validcount++;
|
||||
UpdateBBox();
|
||||
|
||||
for(unsigned i=0;i < Sidedefs.Size(); i++)
|
||||
// If we are loading a savegame we do not really want to damage actors and be blocked by them. This can also cause crashes when trying to damage incompletely deserialized player pawns.
|
||||
if (!fromsave)
|
||||
{
|
||||
for (unsigned i = 0; i < Sidedefs.Size(); i++)
|
||||
{
|
||||
if (CheckMobjBlocking(Sidedefs[i]))
|
||||
{
|
||||
|
@ -1091,6 +1094,7 @@ bool FPolyObj::RotatePolyobj (angle_t angle)
|
|||
LinkPolyobj();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this->angle += angle;
|
||||
LinkPolyobj();
|
||||
ClearSubsectorLinks();
|
||||
|
|
|
@ -74,7 +74,7 @@ struct FPolyObj
|
|||
|
||||
int GetMirror();
|
||||
bool MovePolyobj (int x, int y, bool force = false);
|
||||
bool RotatePolyobj (angle_t angle);
|
||||
bool RotatePolyobj (angle_t angle, bool fromsave = false);
|
||||
void ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy, side_t **side) const;
|
||||
void LinkPolyobj ();
|
||||
void RecalcActorFloorCeil(FBoundingBox bounds) const;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** i_rbopts.h
|
||||
** critsec.cpp
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2014 Alexey Lysiuk
|
||||
|
@ -31,22 +31,32 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#ifndef SRC_COCOA_I_RBOPTS_H_INCLUDED
|
||||
#define SRC_COCOA_I_RBOPTS_H_INCLUDED
|
||||
#include "critsec.h"
|
||||
|
||||
struct RenderBufferOptions
|
||||
// TODO: add error handling
|
||||
|
||||
FCriticalSection::FCriticalSection()
|
||||
{
|
||||
float pixelScale;
|
||||
pthread_mutexattr_t attributes;
|
||||
pthread_mutexattr_init(&attributes);
|
||||
pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE);
|
||||
|
||||
float shiftX;
|
||||
float shiftY;
|
||||
pthread_mutex_init(&m_mutex, &attributes);
|
||||
|
||||
float width;
|
||||
float height;
|
||||
pthread_mutexattr_destroy(&attributes);
|
||||
}
|
||||
|
||||
bool dirty;
|
||||
};
|
||||
FCriticalSection::~FCriticalSection()
|
||||
{
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
}
|
||||
|
||||
extern RenderBufferOptions rbOpts;
|
||||
void FCriticalSection::Enter()
|
||||
{
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
}
|
||||
|
||||
#endif // SRC_COCOA_I_RBOPTS_H_INCLUDED
|
||||
void FCriticalSection::Leave()
|
||||
{
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
}
|
26
src/cocoa/i_osversion.h → src/posix/cocoa/critsec.h
Executable file → Normal file
26
src/cocoa/i_osversion.h → src/posix/cocoa/critsec.h
Executable file → Normal file
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
** i_osversion.h
|
||||
** critsec.h
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2012-2014 Alexey Lysiuk
|
||||
** Copyright 2014 Alexey Lysiuk
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
|
@ -31,13 +31,23 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#ifndef CRITSEC_H
|
||||
#define CRITSEC_H
|
||||
|
||||
struct DarwinVersion
|
||||
#include <pthread.h>
|
||||
|
||||
class FCriticalSection
|
||||
{
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
uint16_t bugfix;
|
||||
public:
|
||||
FCriticalSection();
|
||||
~FCriticalSection();
|
||||
|
||||
void Enter();
|
||||
void Leave();
|
||||
|
||||
private:
|
||||
pthread_mutex_t m_mutex;
|
||||
|
||||
};
|
||||
|
||||
extern const DarwinVersion darwinVersion;
|
||||
#endif
|
168
src/posix/cocoa/i_common.h
Normal file
168
src/posix/cocoa/i_common.h
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
** i_common.h
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2012-2015 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.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
|
||||
struct RenderBufferOptions
|
||||
{
|
||||
float pixelScale;
|
||||
|
||||
float shiftX;
|
||||
float shiftY;
|
||||
|
||||
float width;
|
||||
float height;
|
||||
|
||||
bool dirty;
|
||||
};
|
||||
|
||||
extern RenderBufferOptions rbOpts;
|
||||
|
||||
|
||||
inline bool I_IsHiDPISupported()
|
||||
{
|
||||
// The following value shoud be equal to NSAppKitVersionNumber10_7
|
||||
// and it's hard-coded in order to build on earlier SDKs
|
||||
|
||||
return NSAppKitVersionNumber >= 1138;
|
||||
}
|
||||
|
||||
void I_ProcessEvent(NSEvent* event);
|
||||
|
||||
void I_ProcessJoysticks();
|
||||
|
||||
NSSize I_GetContentViewSize(const NSWindow* window);
|
||||
void I_SetMainWindowVisible(bool visible);
|
||||
void I_SetNativeMouse(bool wantNative);
|
||||
|
||||
|
||||
// The following definitions are required to build with older OS X SDKs
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
|
||||
|
||||
typedef unsigned int NSUInteger;
|
||||
typedef int NSInteger;
|
||||
|
||||
typedef float CGFloat;
|
||||
|
||||
// From HIToolbox/Events.h
|
||||
enum
|
||||
{
|
||||
kVK_Return = 0x24,
|
||||
kVK_Tab = 0x30,
|
||||
kVK_Space = 0x31,
|
||||
kVK_Delete = 0x33,
|
||||
kVK_Escape = 0x35,
|
||||
kVK_Command = 0x37,
|
||||
kVK_Shift = 0x38,
|
||||
kVK_CapsLock = 0x39,
|
||||
kVK_Option = 0x3A,
|
||||
kVK_Control = 0x3B,
|
||||
kVK_RightShift = 0x3C,
|
||||
kVK_RightOption = 0x3D,
|
||||
kVK_RightControl = 0x3E,
|
||||
kVK_Function = 0x3F,
|
||||
kVK_F17 = 0x40,
|
||||
kVK_VolumeUp = 0x48,
|
||||
kVK_VolumeDown = 0x49,
|
||||
kVK_Mute = 0x4A,
|
||||
kVK_F18 = 0x4F,
|
||||
kVK_F19 = 0x50,
|
||||
kVK_F20 = 0x5A,
|
||||
kVK_F5 = 0x60,
|
||||
kVK_F6 = 0x61,
|
||||
kVK_F7 = 0x62,
|
||||
kVK_F3 = 0x63,
|
||||
kVK_F8 = 0x64,
|
||||
kVK_F9 = 0x65,
|
||||
kVK_F11 = 0x67,
|
||||
kVK_F13 = 0x69,
|
||||
kVK_F16 = 0x6A,
|
||||
kVK_F14 = 0x6B,
|
||||
kVK_F10 = 0x6D,
|
||||
kVK_F12 = 0x6F,
|
||||
kVK_F15 = 0x71,
|
||||
kVK_Help = 0x72,
|
||||
kVK_Home = 0x73,
|
||||
kVK_PageUp = 0x74,
|
||||
kVK_ForwardDelete = 0x75,
|
||||
kVK_F4 = 0x76,
|
||||
kVK_End = 0x77,
|
||||
kVK_F2 = 0x78,
|
||||
kVK_PageDown = 0x79,
|
||||
kVK_F1 = 0x7A,
|
||||
kVK_LeftArrow = 0x7B,
|
||||
kVK_RightArrow = 0x7C,
|
||||
kVK_DownArrow = 0x7D,
|
||||
kVK_UpArrow = 0x7E
|
||||
};
|
||||
|
||||
#endif // prior to 10.5
|
||||
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
|
||||
|
||||
enum
|
||||
{
|
||||
NSApplicationActivationPolicyRegular
|
||||
};
|
||||
|
||||
typedef NSInteger NSApplicationActivationPolicy;
|
||||
|
||||
@interface NSApplication(ActivationPolicy)
|
||||
- (BOOL)setActivationPolicy:(NSApplicationActivationPolicy)activationPolicy;
|
||||
@end
|
||||
|
||||
@interface NSWindow(SetStyleMask)
|
||||
- (void)setStyleMask:(NSUInteger)styleMask;
|
||||
@end
|
||||
|
||||
#endif // prior to 10.6
|
||||
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
|
||||
|
||||
@interface NSView(HiDPIStubs)
|
||||
- (NSPoint)convertPointToBacking:(NSPoint)aPoint;
|
||||
- (NSSize)convertSizeToBacking:(NSSize)aSize;
|
||||
- (NSSize)convertSizeFromBacking:(NSSize)aSize;
|
||||
|
||||
- (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag;
|
||||
@end
|
||||
|
||||
@interface NSScreen(HiDPIStubs)
|
||||
- (NSRect)convertRectToBacking:(NSRect)aRect;
|
||||
@end
|
||||
|
||||
#endif // prior to 10.7
|
740
src/posix/cocoa/i_input.mm
Normal file
740
src/posix/cocoa/i_input.mm
Normal file
|
@ -0,0 +1,740 @@
|
|||
/*
|
||||
** i_input.mm
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2012-2015 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 "i_common.h"
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
// Avoid collision between DObject class and Objective-C
|
||||
#define Class ObjectClass
|
||||
|
||||
#include "c_console.h"
|
||||
#include "c_cvars.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "d_event.h"
|
||||
#include "d_gui.h"
|
||||
#include "dikeys.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "v_video.h"
|
||||
|
||||
#undef Class
|
||||
|
||||
|
||||
EXTERN_CVAR(Int, m_use_mouse)
|
||||
|
||||
CVAR(Bool, use_mouse, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, m_noprescale, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, m_filter, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
CUSTOM_CVAR(Int, mouse_capturemode, 1, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
|
||||
{
|
||||
if (self < 0)
|
||||
{
|
||||
self = 0;
|
||||
}
|
||||
else if (self > 2)
|
||||
{
|
||||
self = 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern int paused, chatmodeon;
|
||||
extern constate_e ConsoleState;
|
||||
|
||||
bool GUICapture;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// TODO: remove this magic!
|
||||
size_t s_skipMouseMoves;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
void CheckGUICapture()
|
||||
{
|
||||
const bool wantCapture = (MENU_Off == menuactive)
|
||||
? (c_down == ConsoleState || c_falling == ConsoleState || chatmodeon)
|
||||
: (MENU_On == menuactive || MENU_OnNoPause == menuactive);
|
||||
|
||||
if (wantCapture != GUICapture)
|
||||
{
|
||||
GUICapture = wantCapture;
|
||||
|
||||
ResetButtonStates();
|
||||
}
|
||||
}
|
||||
|
||||
void CenterCursor()
|
||||
{
|
||||
NSWindow* window = [NSApp keyWindow];
|
||||
if (nil == window)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const NSRect displayRect = [[window screen] frame];
|
||||
const NSRect windowRect = [window frame];
|
||||
const CGPoint centerPoint = CGPointMake(NSMidX(windowRect), displayRect.size.height - NSMidY(windowRect));
|
||||
|
||||
CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
|
||||
|
||||
if (NULL != eventSource)
|
||||
{
|
||||
CGEventRef mouseMoveEvent = CGEventCreateMouseEvent(eventSource,
|
||||
kCGEventMouseMoved, centerPoint, kCGMouseButtonLeft);
|
||||
|
||||
if (NULL != mouseMoveEvent)
|
||||
{
|
||||
CGEventPost(kCGHIDEventTap, mouseMoveEvent);
|
||||
CFRelease(mouseMoveEvent);
|
||||
}
|
||||
|
||||
CFRelease(eventSource);
|
||||
}
|
||||
|
||||
// TODO: remove this magic!
|
||||
s_skipMouseMoves = 2;
|
||||
}
|
||||
|
||||
|
||||
bool IsInGame()
|
||||
{
|
||||
switch (mouse_capturemode)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
return gamestate == GS_LEVEL;
|
||||
|
||||
case 1:
|
||||
return gamestate == GS_LEVEL
|
||||
|| gamestate == GS_INTERMISSION
|
||||
|| gamestate == GS_FINALE;
|
||||
|
||||
case 2:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckNativeMouse()
|
||||
{
|
||||
const bool windowed = (NULL == screen) || !screen->IsFullscreen();
|
||||
bool wantNative;
|
||||
|
||||
if (windowed)
|
||||
{
|
||||
if (![NSApp isActive] || !use_mouse)
|
||||
{
|
||||
wantNative = true;
|
||||
}
|
||||
else if (MENU_WaitKey == menuactive)
|
||||
{
|
||||
wantNative = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
wantNative = (!m_use_mouse || MENU_WaitKey != menuactive)
|
||||
&& (!IsInGame() || GUICapture || paused || demoplayback);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ungrab mouse when in the menu with mouse control on.
|
||||
wantNative = m_use_mouse
|
||||
&& (MENU_On == menuactive || MENU_OnNoPause == menuactive);
|
||||
}
|
||||
|
||||
I_SetNativeMouse(wantNative);
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
void I_GetEvent()
|
||||
{
|
||||
[[NSRunLoop currentRunLoop] limitDateForMode:NSDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
void I_StartTic()
|
||||
{
|
||||
CheckGUICapture();
|
||||
CheckNativeMouse();
|
||||
|
||||
I_ProcessJoysticks();
|
||||
I_GetEvent();
|
||||
}
|
||||
|
||||
void I_StartFrame()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void I_SetMouseCapture()
|
||||
{
|
||||
}
|
||||
|
||||
void I_ReleaseMouseCapture()
|
||||
{
|
||||
}
|
||||
|
||||
void I_SetNativeMouse(bool wantNative)
|
||||
{
|
||||
static bool nativeMouse = true;
|
||||
|
||||
if (wantNative != nativeMouse)
|
||||
{
|
||||
nativeMouse = wantNative;
|
||||
|
||||
if (!wantNative)
|
||||
{
|
||||
CenterCursor();
|
||||
}
|
||||
|
||||
CGAssociateMouseAndMouseCursorPosition(wantNative);
|
||||
|
||||
if (wantNative)
|
||||
{
|
||||
[NSCursor unhide];
|
||||
}
|
||||
else
|
||||
{
|
||||
[NSCursor hide];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const size_t KEY_COUNT = 128;
|
||||
|
||||
|
||||
// See Carbon -> HIToolbox -> Events.h for kVK_ constants
|
||||
|
||||
const uint8_t KEYCODE_TO_DIK[KEY_COUNT] =
|
||||
{
|
||||
DIK_A, DIK_S, DIK_D, DIK_F, DIK_H, DIK_G, DIK_Z, DIK_X, // 0x00 - 0x07
|
||||
DIK_C, DIK_V, 0, DIK_B, DIK_Q, DIK_W, DIK_E, DIK_R, // 0x08 - 0x0F
|
||||
DIK_Y, DIK_T, DIK_1, DIK_2, DIK_3, DIK_4, DIK_6, DIK_5, // 0x10 - 0x17
|
||||
DIK_EQUALS, DIK_9, DIK_7, DIK_MINUS, DIK_8, DIK_0, DIK_RBRACKET, DIK_O, // 0x18 - 0x1F
|
||||
DIK_U, DIK_LBRACKET, DIK_I, DIK_P, DIK_RETURN, DIK_L, DIK_J, DIK_APOSTROPHE, // 0x20 - 0x27
|
||||
DIK_K, DIK_SEMICOLON, DIK_BACKSLASH, DIK_COMMA, DIK_SLASH, DIK_N, DIK_M, DIK_PERIOD, // 0x28 - 0x2F
|
||||
DIK_TAB, DIK_SPACE, DIK_GRAVE, DIK_BACK, 0, DIK_ESCAPE, 0, DIK_LWIN, // 0x30 - 0x37
|
||||
DIK_LSHIFT, DIK_CAPITAL, DIK_LMENU, DIK_LCONTROL, DIK_RSHIFT, DIK_RMENU, DIK_RCONTROL, 0, // 0x38 - 0x3F
|
||||
0, DIK_DECIMAL, 0, DIK_MULTIPLY, 0, DIK_ADD, 0, 0, // 0x40 - 0x47
|
||||
DIK_VOLUMEUP, DIK_VOLUMEDOWN, DIK_MUTE, DIK_SLASH, DIK_NUMPADENTER, 0, DIK_SUBTRACT, 0, // 0x48 - 0x4F
|
||||
0, DIK_NUMPAD_EQUALS, DIK_NUMPAD0, DIK_NUMPAD1, DIK_NUMPAD2, DIK_NUMPAD3, DIK_NUMPAD4, DIK_NUMPAD5, // 0x50 - 0x57
|
||||
DIK_NUMPAD6, DIK_NUMPAD7, 0, DIK_NUMPAD8, DIK_NUMPAD9, 0, 0, 0, // 0x58 - 0x5F
|
||||
DIK_F5, DIK_F6, DIK_F7, DIK_F3, DIK_F8, DIK_F9, 0, DIK_F11, // 0x60 - 0x67
|
||||
0, DIK_F13, 0, DIK_F14, 0, DIK_F10, 0, DIK_F12, // 0x68 - 0x6F
|
||||
0, DIK_F15, 0, DIK_HOME, 0, DIK_DELETE, DIK_F4, DIK_END, // 0x70 - 0x77
|
||||
DIK_F2, 0, DIK_F1, DIK_LEFT, DIK_RIGHT, DIK_DOWN, DIK_UP, 0, // 0x78 - 0x7F
|
||||
};
|
||||
|
||||
const uint8_t KEYCODE_TO_ASCII[KEY_COUNT] =
|
||||
{
|
||||
'a', 's', 'd', 'f', 'h', 'g', 'z', 'x', // 0x00 - 0x07
|
||||
'c', 'v', 0, 'b', 'q', 'w', 'e', 'r', // 0x08 - 0x0F
|
||||
'y', 't', '1', '2', '3', '4', '6', '5', // 0x10 - 0x17
|
||||
'=', '9', '7', '-', '8', '0', ']', 'o', // 0x18 - 0x1F
|
||||
'u', '[', 'i', 'p', 13, 'l', 'j', '\'', // 0x20 - 0x27
|
||||
'k', ';', '\\', ',', '/', 'n', 'm', '.', // 0x28 - 0x2F
|
||||
9, ' ', '`', 12, 0, 27, 0, 0, // 0x30 - 0x37
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 0x38 - 0x3F
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x47
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 0x48 - 0x4F
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x57
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 0x58 - 0x5F
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 0x60 - 0x67
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 0x68 - 0x6F
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 0x70 - 0x77
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // 0x78 - 0x7F
|
||||
};
|
||||
|
||||
|
||||
uint8_t ModifierToDIK(const uint32_t modifier)
|
||||
{
|
||||
switch (modifier)
|
||||
{
|
||||
case NSAlphaShiftKeyMask: return DIK_CAPITAL;
|
||||
case NSShiftKeyMask: return DIK_LSHIFT;
|
||||
case NSControlKeyMask: return DIK_LCONTROL;
|
||||
case NSAlternateKeyMask: return DIK_LMENU;
|
||||
case NSCommandKeyMask: return DIK_LWIN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SWORD ModifierFlagsToGUIKeyModifiers(NSEvent* theEvent)
|
||||
{
|
||||
const NSUInteger modifiers([theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask);
|
||||
return ((modifiers & NSShiftKeyMask ) ? GKM_SHIFT : 0)
|
||||
| ((modifiers & NSControlKeyMask ) ? GKM_CTRL : 0)
|
||||
| ((modifiers & NSAlternateKeyMask) ? GKM_ALT : 0)
|
||||
| ((modifiers & NSCommandKeyMask ) ? GKM_META : 0);
|
||||
}
|
||||
|
||||
bool ShouldGenerateGUICharEvent(NSEvent* theEvent)
|
||||
{
|
||||
const NSUInteger modifiers([theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask);
|
||||
return !(modifiers & NSControlKeyMask)
|
||||
&& !(modifiers & NSAlternateKeyMask)
|
||||
&& !(modifiers & NSCommandKeyMask)
|
||||
&& !(modifiers & NSFunctionKeyMask);
|
||||
}
|
||||
|
||||
|
||||
NSStringEncoding GetEncodingForUnicodeCharacter(const unichar character)
|
||||
{
|
||||
if (character >= L'\u0100' && character <= L'\u024F')
|
||||
{
|
||||
return NSWindowsCP1250StringEncoding; // Central and Eastern Europe
|
||||
}
|
||||
else if (character >= L'\u0370' && character <= L'\u03FF')
|
||||
{
|
||||
return NSWindowsCP1253StringEncoding; // Greek
|
||||
}
|
||||
else if (character >= L'\u0400' && character <= L'\u04FF')
|
||||
{
|
||||
return NSWindowsCP1251StringEncoding; // Cyrillic
|
||||
}
|
||||
|
||||
// TODO: add handling for other characters
|
||||
// TODO: Turkish should use NSWindowsCP1254StringEncoding
|
||||
|
||||
return NSWindowsCP1252StringEncoding;
|
||||
}
|
||||
|
||||
unsigned char GetCharacterFromNSEvent(NSEvent* theEvent)
|
||||
{
|
||||
const NSString* unicodeCharacters = [theEvent characters];
|
||||
|
||||
if (0 == [unicodeCharacters length])
|
||||
{
|
||||
return '\0';
|
||||
}
|
||||
|
||||
const unichar unicodeCharacter = [unicodeCharacters characterAtIndex:0];
|
||||
const NSStringEncoding encoding = GetEncodingForUnicodeCharacter(unicodeCharacter);
|
||||
|
||||
unsigned char character = '\0';
|
||||
|
||||
if (NSWindowsCP1252StringEncoding == encoding)
|
||||
{
|
||||
// TODO: make sure that the following is always correct
|
||||
character = unicodeCharacter & 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
const NSData* const characters =
|
||||
[[theEvent characters] dataUsingEncoding:encoding];
|
||||
|
||||
character = [characters length] > 0
|
||||
? *static_cast<const unsigned char*>([characters bytes])
|
||||
: '\0';
|
||||
}
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
void ProcessKeyboardEventInMenu(NSEvent* theEvent)
|
||||
{
|
||||
event_t event = {};
|
||||
|
||||
event.type = EV_GUI_Event;
|
||||
event.subtype = NSKeyDown == [theEvent type] ? EV_GUI_KeyDown : EV_GUI_KeyUp;
|
||||
event.data2 = GetCharacterFromNSEvent(theEvent);
|
||||
event.data3 = ModifierFlagsToGUIKeyModifiers(theEvent);
|
||||
|
||||
if (EV_GUI_KeyDown == event.subtype && [theEvent isARepeat])
|
||||
{
|
||||
event.subtype = EV_GUI_KeyRepeat;
|
||||
}
|
||||
|
||||
const unsigned short keyCode = [theEvent keyCode];
|
||||
|
||||
switch (keyCode)
|
||||
{
|
||||
case kVK_Return: event.data1 = GK_RETURN; break;
|
||||
case kVK_PageUp: event.data1 = GK_PGUP; break;
|
||||
case kVK_PageDown: event.data1 = GK_PGDN; break;
|
||||
case kVK_End: event.data1 = GK_END; break;
|
||||
case kVK_Home: event.data1 = GK_HOME; break;
|
||||
case kVK_LeftArrow: event.data1 = GK_LEFT; break;
|
||||
case kVK_RightArrow: event.data1 = GK_RIGHT; break;
|
||||
case kVK_UpArrow: event.data1 = GK_UP; break;
|
||||
case kVK_DownArrow: event.data1 = GK_DOWN; break;
|
||||
case kVK_Delete: event.data1 = GK_BACKSPACE; break;
|
||||
case kVK_ForwardDelete: event.data1 = GK_DEL; break;
|
||||
case kVK_Escape: event.data1 = GK_ESCAPE; break;
|
||||
case kVK_F1: event.data1 = GK_F1; break;
|
||||
case kVK_F2: event.data1 = GK_F2; break;
|
||||
case kVK_F3: event.data1 = GK_F3; break;
|
||||
case kVK_F4: event.data1 = GK_F4; break;
|
||||
case kVK_F5: event.data1 = GK_F5; break;
|
||||
case kVK_F6: event.data1 = GK_F6; break;
|
||||
case kVK_F7: event.data1 = GK_F7; break;
|
||||
case kVK_F8: event.data1 = GK_F8; break;
|
||||
case kVK_F9: event.data1 = GK_F9; break;
|
||||
case kVK_F10: event.data1 = GK_F10; break;
|
||||
case kVK_F11: event.data1 = GK_F11; break;
|
||||
case kVK_F12: event.data1 = GK_F12; break;
|
||||
default:
|
||||
event.data1 = KEYCODE_TO_ASCII[keyCode];
|
||||
break;
|
||||
}
|
||||
|
||||
if (event.data1 < 128)
|
||||
{
|
||||
event.data1 = toupper(event.data1);
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
if (!iscntrl(event.data2)
|
||||
&& EV_GUI_KeyUp != event.subtype
|
||||
&& ShouldGenerateGUICharEvent(theEvent))
|
||||
{
|
||||
event.subtype = EV_GUI_Char;
|
||||
event.data1 = event.data2;
|
||||
event.data2 = event.data3 & GKM_ALT;
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NSEventToGameMousePosition(NSEvent* inEvent, event_t* outEvent)
|
||||
{
|
||||
const NSWindow* window = [inEvent window];
|
||||
const NSView* view = [window contentView];
|
||||
|
||||
const NSPoint screenPos = [NSEvent mouseLocation];
|
||||
const NSPoint windowPos = [window convertScreenToBase:screenPos];
|
||||
|
||||
const NSPoint viewPos = I_IsHiDPISupported()
|
||||
? [view convertPointToBacking:windowPos]
|
||||
: [view convertPoint:windowPos fromView:nil];
|
||||
|
||||
const CGFloat frameHeight = I_GetContentViewSize(window).height;
|
||||
|
||||
const CGFloat posX = ( viewPos.x - rbOpts.shiftX) / rbOpts.pixelScale;
|
||||
const CGFloat posY = (frameHeight - viewPos.y - rbOpts.shiftY) / rbOpts.pixelScale;
|
||||
|
||||
outEvent->data1 = static_cast<int>(posX);
|
||||
outEvent->data2 = static_cast<int>(posY);
|
||||
}
|
||||
|
||||
void ProcessMouseMoveInMenu(NSEvent* theEvent)
|
||||
{
|
||||
event_t event = {};
|
||||
|
||||
event.type = EV_GUI_Event;
|
||||
event.subtype = EV_GUI_MouseMove;
|
||||
|
||||
NSEventToGameMousePosition(theEvent, &event);
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
void ProcessMouseMoveInGame(NSEvent* theEvent)
|
||||
{
|
||||
if (!use_mouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: remove this magic!
|
||||
|
||||
if (s_skipMouseMoves > 0)
|
||||
{
|
||||
--s_skipMouseMoves;
|
||||
return;
|
||||
}
|
||||
|
||||
int x([theEvent deltaX]);
|
||||
int y(-[theEvent deltaY]);
|
||||
|
||||
if (0 == x && 0 == y)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_noprescale)
|
||||
{
|
||||
x *= 3;
|
||||
y *= 2;
|
||||
}
|
||||
|
||||
event_t event = {};
|
||||
|
||||
static int lastX = 0, lastY = 0;
|
||||
|
||||
if (m_filter)
|
||||
{
|
||||
event.x = (x + lastX) / 2;
|
||||
event.y = (y + lastY) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
event.x = x;
|
||||
event.y = y;
|
||||
}
|
||||
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
|
||||
if (0 != event.x | 0 != event.y)
|
||||
{
|
||||
event.type = EV_Mouse;
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ProcessKeyboardEvent(NSEvent* theEvent)
|
||||
{
|
||||
const unsigned short keyCode = [theEvent keyCode];
|
||||
if (keyCode >= KEY_COUNT)
|
||||
{
|
||||
assert(!"Unknown keycode");
|
||||
return;
|
||||
}
|
||||
|
||||
if (GUICapture)
|
||||
{
|
||||
ProcessKeyboardEventInMenu(theEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
event_t event = {};
|
||||
|
||||
event.type = NSKeyDown == [theEvent type] ? EV_KeyDown : EV_KeyUp;
|
||||
event.data1 = KEYCODE_TO_DIK[ keyCode ];
|
||||
|
||||
if (0 != event.data1)
|
||||
{
|
||||
event.data2 = KEYCODE_TO_ASCII[ keyCode ];
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessKeyboardFlagsEvent(NSEvent* theEvent)
|
||||
{
|
||||
static const uint32_t FLAGS_MASK =
|
||||
NSDeviceIndependentModifierFlagsMask & ~NSNumericPadKeyMask;
|
||||
|
||||
const uint32_t modifiers = [theEvent modifierFlags] & FLAGS_MASK;
|
||||
static uint32_t oldModifiers = 0;
|
||||
const uint32_t deltaModifiers = modifiers ^ oldModifiers;
|
||||
|
||||
if (0 == deltaModifiers)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
event_t event = {};
|
||||
|
||||
event.type = modifiers > oldModifiers ? EV_KeyDown : EV_KeyUp;
|
||||
event.data1 = ModifierToDIK(deltaModifiers);
|
||||
|
||||
oldModifiers = modifiers;
|
||||
|
||||
// Caps Lock is a modifier key which generates one event per state change
|
||||
// but not per actual key press or release. So treat any event as key down
|
||||
// Also its event should be not be posted in menu and console
|
||||
|
||||
if (DIK_CAPITAL == event.data1)
|
||||
{
|
||||
if (GUICapture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
event.type = EV_KeyDown;
|
||||
}
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
|
||||
void ProcessMouseMoveEvent(NSEvent* theEvent)
|
||||
{
|
||||
if (GUICapture)
|
||||
{
|
||||
ProcessMouseMoveInMenu(theEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessMouseMoveInGame(theEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessMouseButtonEvent(NSEvent* theEvent)
|
||||
{
|
||||
event_t event = {};
|
||||
|
||||
const NSEventType cocoaEventType = [theEvent type];
|
||||
|
||||
if (GUICapture)
|
||||
{
|
||||
event.type = EV_GUI_Event;
|
||||
|
||||
switch (cocoaEventType)
|
||||
{
|
||||
case NSLeftMouseDown: event.subtype = EV_GUI_LButtonDown; break;
|
||||
case NSRightMouseDown: event.subtype = EV_GUI_RButtonDown; break;
|
||||
case NSOtherMouseDown: event.subtype = EV_GUI_MButtonDown; break;
|
||||
case NSLeftMouseUp: event.subtype = EV_GUI_LButtonUp; break;
|
||||
case NSRightMouseUp: event.subtype = EV_GUI_RButtonUp; break;
|
||||
case NSOtherMouseUp: event.subtype = EV_GUI_MButtonUp; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
NSEventToGameMousePosition(theEvent, &event);
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (cocoaEventType)
|
||||
{
|
||||
case NSLeftMouseDown:
|
||||
case NSRightMouseDown:
|
||||
case NSOtherMouseDown:
|
||||
event.type = EV_KeyDown;
|
||||
break;
|
||||
|
||||
case NSLeftMouseUp:
|
||||
case NSRightMouseUp:
|
||||
case NSOtherMouseUp:
|
||||
event.type = EV_KeyUp;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
event.data1 = MIN(KEY_MOUSE1 + [theEvent buttonNumber], NSInteger(KEY_MOUSE8));
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessMouseWheelEvent(NSEvent* theEvent)
|
||||
{
|
||||
const CGFloat delta = [theEvent deltaY];
|
||||
const bool isZeroDelta = fabs(delta) < 1.0E-5;
|
||||
|
||||
if (isZeroDelta && GUICapture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
event_t event = {};
|
||||
|
||||
if (GUICapture)
|
||||
{
|
||||
event.type = EV_GUI_Event;
|
||||
event.subtype = delta > 0.0f ? EV_GUI_WheelUp : EV_GUI_WheelDown;
|
||||
event.data3 = delta;
|
||||
event.data3 = ModifierFlagsToGUIKeyModifiers(theEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
event.type = isZeroDelta ? EV_KeyUp : EV_KeyDown;
|
||||
event.data1 = delta > 0.0f ? KEY_MWHEELUP : KEY_MWHEELDOWN;
|
||||
}
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
void I_ProcessEvent(NSEvent* event)
|
||||
{
|
||||
const NSEventType eventType = [event type];
|
||||
|
||||
switch (eventType)
|
||||
{
|
||||
case NSMouseMoved:
|
||||
ProcessMouseMoveEvent(event);
|
||||
break;
|
||||
|
||||
case NSLeftMouseDown:
|
||||
case NSLeftMouseUp:
|
||||
case NSRightMouseDown:
|
||||
case NSRightMouseUp:
|
||||
case NSOtherMouseDown:
|
||||
case NSOtherMouseUp:
|
||||
ProcessMouseButtonEvent(event);
|
||||
break;
|
||||
|
||||
case NSLeftMouseDragged:
|
||||
case NSRightMouseDragged:
|
||||
case NSOtherMouseDragged:
|
||||
ProcessMouseButtonEvent(event);
|
||||
ProcessMouseMoveEvent(event);
|
||||
break;
|
||||
|
||||
case NSScrollWheel:
|
||||
ProcessMouseWheelEvent(event);
|
||||
break;
|
||||
|
||||
case NSKeyDown:
|
||||
case NSKeyUp:
|
||||
ProcessKeyboardEvent(event);
|
||||
break;
|
||||
|
||||
case NSFlagsChanged:
|
||||
ProcessKeyboardFlagsEvent(event);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
1252
src/posix/cocoa/i_joystick.cpp
Normal file
1252
src/posix/cocoa/i_joystick.cpp
Normal file
File diff suppressed because it is too large
Load diff
551
src/posix/cocoa/i_main.mm
Normal file
551
src/posix/cocoa/i_main.mm
Normal file
|
@ -0,0 +1,551 @@
|
|||
/*
|
||||
** i_main.mm
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2012-2015 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 "i_common.h"
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Avoid collision between DObject class and Objective-C
|
||||
#define Class ObjectClass
|
||||
|
||||
#include "c_console.h"
|
||||
#include "c_cvars.h"
|
||||
#include "cmdlib.h"
|
||||
#include "d_main.h"
|
||||
#include "doomerrors.h"
|
||||
#include "i_system.h"
|
||||
#include "m_argv.h"
|
||||
#include "s_sound.h"
|
||||
#include "version.h"
|
||||
|
||||
#undef Class
|
||||
|
||||
|
||||
#define ZD_UNUSED(VARIABLE) ((void)(VARIABLE))
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
EXTERN_CVAR(Int, vid_defwidth )
|
||||
EXTERN_CVAR(Int, vid_defheight)
|
||||
EXTERN_CVAR(Bool, vid_vsync )
|
||||
EXTERN_CVAR(Bool, fullscreen )
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// The maximum number of functions that can be registered with atterm.
|
||||
const size_t MAX_TERMS = 64;
|
||||
|
||||
void (*TermFuncs[MAX_TERMS])();
|
||||
const char *TermNames[MAX_TERMS];
|
||||
size_t NumTerms;
|
||||
|
||||
void call_terms()
|
||||
{
|
||||
while (NumTerms > 0)
|
||||
{
|
||||
TermFuncs[--NumTerms]();
|
||||
}
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
void addterm(void (*func)(), const char *name)
|
||||
{
|
||||
// Make sure this function wasn't already registered.
|
||||
|
||||
for (size_t i = 0; i < NumTerms; ++i)
|
||||
{
|
||||
if (TermFuncs[i] == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (NumTerms == MAX_TERMS)
|
||||
{
|
||||
func();
|
||||
I_FatalError("Too many exit functions registered.");
|
||||
}
|
||||
|
||||
TermNames[NumTerms] = name;
|
||||
TermFuncs[NumTerms] = func;
|
||||
|
||||
++NumTerms;
|
||||
}
|
||||
|
||||
void popterm()
|
||||
{
|
||||
if (NumTerms)
|
||||
{
|
||||
--NumTerms;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Mac_I_FatalError(const char* const message)
|
||||
{
|
||||
I_SetMainWindowVisible(false);
|
||||
|
||||
const CFStringRef errorString = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,
|
||||
message, kCFStringEncodingASCII, kCFAllocatorNull);
|
||||
|
||||
if (NULL != errorString)
|
||||
{
|
||||
CFOptionFlags dummy;
|
||||
|
||||
CFUserNotificationDisplayAlert( 0, kCFUserNotificationStopAlertLevel, NULL, NULL, NULL,
|
||||
CFSTR("Fatal Error"), errorString, CFSTR("Exit"), NULL, NULL, &dummy);
|
||||
|
||||
CFRelease(errorString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DArgs* Args; // command line arguments
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const int ARGC_MAX = 64;
|
||||
|
||||
int s_argc;
|
||||
char* s_argv[ARGC_MAX];
|
||||
|
||||
TArray<FString> s_argvStorage;
|
||||
|
||||
bool s_restartedFromWADPicker;
|
||||
|
||||
|
||||
void NewFailure()
|
||||
{
|
||||
I_FatalError("Failed to allocate memory from system heap");
|
||||
}
|
||||
|
||||
|
||||
int OriginalMain(int argc, char** argv)
|
||||
{
|
||||
printf(GAMENAME" %s - %s - Cocoa version\nCompiled on %s\n\n",
|
||||
GetVersionString(), GetGitTime(), __DATE__);
|
||||
|
||||
seteuid(getuid());
|
||||
std::set_new_handler(NewFailure);
|
||||
|
||||
// Set LC_NUMERIC environment variable in case some library decides to
|
||||
// clear the setlocale call at least this will be correct.
|
||||
// Note that the LANG environment variable is overridden by LC_*
|
||||
setenv("LC_NUMERIC", "C", 1);
|
||||
setlocale(LC_ALL, "C");
|
||||
|
||||
// Set reasonable default values for video settings
|
||||
|
||||
const NSSize screenSize = [[NSScreen mainScreen] frame].size;
|
||||
vid_defwidth = static_cast<int>(screenSize.width);
|
||||
vid_defheight = static_cast<int>(screenSize.height);
|
||||
vid_vsync = true;
|
||||
fullscreen = true;
|
||||
|
||||
try
|
||||
{
|
||||
Args = new DArgs(argc, argv);
|
||||
|
||||
/*
|
||||
killough 1/98:
|
||||
|
||||
This fixes some problems with exit handling
|
||||
during abnormal situations.
|
||||
|
||||
The old code called I_Quit() to end program,
|
||||
while now I_Quit() is installed as an exit
|
||||
handler and exit() is called to exit, either
|
||||
normally or abnormally. Seg faults are caught
|
||||
and the error handler is used, to prevent
|
||||
being left in graphics mode or having very
|
||||
loud SFX noise because the sound card is
|
||||
left in an unstable state.
|
||||
*/
|
||||
|
||||
atexit(call_terms);
|
||||
atterm(I_Quit);
|
||||
|
||||
NSString* exePath = [[NSBundle mainBundle] executablePath];
|
||||
progdir = [[exePath stringByDeletingLastPathComponent] UTF8String];
|
||||
progdir += "/";
|
||||
|
||||
C_InitConsole(80 * 8, 25 * 8, false);
|
||||
D_DoomMain();
|
||||
}
|
||||
catch(const CDoomError& error)
|
||||
{
|
||||
const char* const message = error.GetMessage();
|
||||
|
||||
if (NULL != message)
|
||||
{
|
||||
fprintf(stderr, "%s\n", message);
|
||||
Mac_I_FatalError(message);
|
||||
}
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
call_terms();
|
||||
throw;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@interface ApplicationController : NSResponder
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||
<NSFileManagerDelegate>
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent*)theEvent;
|
||||
- (void)keyUp:(NSEvent*)theEvent;
|
||||
|
||||
- (void)applicationDidBecomeActive:(NSNotification*)aNotification;
|
||||
- (void)applicationWillResignActive:(NSNotification*)aNotification;
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification*)aNotification;
|
||||
|
||||
- (BOOL)application:(NSApplication*)theApplication openFile:(NSString*)filename;
|
||||
|
||||
- (void)processEvents:(NSTimer*)timer;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
ApplicationController* appCtrl;
|
||||
|
||||
|
||||
@implementation ApplicationController
|
||||
|
||||
- (void)keyDown:(NSEvent*)theEvent
|
||||
{
|
||||
// Empty but present to avoid playing of 'beep' alert sound
|
||||
|
||||
ZD_UNUSED(theEvent);
|
||||
}
|
||||
|
||||
- (void)keyUp:(NSEvent*)theEvent
|
||||
{
|
||||
// Empty but present to avoid playing of 'beep' alert sound
|
||||
|
||||
ZD_UNUSED(theEvent);
|
||||
}
|
||||
|
||||
|
||||
- (void)applicationDidBecomeActive:(NSNotification*)aNotification
|
||||
{
|
||||
ZD_UNUSED(aNotification);
|
||||
|
||||
S_SetSoundPaused(1);
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(NSNotification*)aNotification
|
||||
{
|
||||
ZD_UNUSED(aNotification);
|
||||
|
||||
S_SetSoundPaused(0);
|
||||
}
|
||||
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification*)aNotification
|
||||
{
|
||||
// When starting from command line with real executable path, e.g. ZDoom.app/Contents/MacOS/ZDoom
|
||||
// application remains deactivated for an unknown reason.
|
||||
// The following call resolves this issue
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
// Setup timer for custom event loop
|
||||
|
||||
NSTimer* timer = [NSTimer timerWithTimeInterval:0
|
||||
target:self
|
||||
selector:@selector(processEvents:)
|
||||
userInfo:nil
|
||||
repeats:YES];
|
||||
[[NSRunLoop currentRunLoop] addTimer:timer
|
||||
forMode:NSDefaultRunLoopMode];
|
||||
|
||||
exit(OriginalMain(s_argc, s_argv));
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)application:(NSApplication*)theApplication openFile:(NSString*)filename
|
||||
{
|
||||
ZD_UNUSED(theApplication);
|
||||
|
||||
if (s_restartedFromWADPicker
|
||||
|| 0 == [filename length]
|
||||
|| s_argc + 2 >= ARGC_MAX)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Some parameters from command line are passed to this function
|
||||
// These parameters need to be skipped to avoid duplication
|
||||
// Note: SDL has different approach to fix this issue, see the same method in SDLMain.m
|
||||
|
||||
const char* const charFileName = [filename UTF8String];
|
||||
|
||||
for (int i = 0; i < s_argc; ++i)
|
||||
{
|
||||
if (0 == strcmp(s_argv[i], charFileName))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
s_argvStorage.Push("-file");
|
||||
s_argv[s_argc++] = s_argvStorage.Last().LockBuffer();
|
||||
|
||||
s_argvStorage.Push([filename UTF8String]);
|
||||
s_argv[s_argc++] = s_argvStorage.Last().LockBuffer();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
- (void)processEvents:(NSTimer*)timer
|
||||
{
|
||||
ZD_UNUSED(timer);
|
||||
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
while (true)
|
||||
{
|
||||
NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:[NSDate dateWithTimeIntervalSinceNow:0]
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES];
|
||||
if (nil == event)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
I_ProcessEvent(event);
|
||||
|
||||
[NSApp sendEvent:event];
|
||||
}
|
||||
|
||||
[NSApp updateWindows];
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
NSMenuItem* CreateApplicationMenu()
|
||||
{
|
||||
NSMenu* menu = [NSMenu new];
|
||||
|
||||
[menu addItemWithTitle:[@"About " stringByAppendingString:@GAMENAME]
|
||||
action:@selector(orderFrontStandardAboutPanel:)
|
||||
keyEquivalent:@""];
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
[menu addItemWithTitle:[@"Hide " stringByAppendingString:@GAMENAME]
|
||||
action:@selector(hide:)
|
||||
keyEquivalent:@"h"];
|
||||
[[menu addItemWithTitle:@"Hide Others"
|
||||
action:@selector(hideOtherApplications:)
|
||||
keyEquivalent:@"h"]
|
||||
setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask];
|
||||
[menu addItemWithTitle:@"Show All"
|
||||
action:@selector(unhideAllApplications:)
|
||||
keyEquivalent:@""];
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
[menu addItemWithTitle:[@"Quit " stringByAppendingString:@GAMENAME]
|
||||
action:@selector(terminate:)
|
||||
keyEquivalent:@"q"];
|
||||
|
||||
NSMenuItem* menuItem = [NSMenuItem new];
|
||||
[menuItem setSubmenu:menu];
|
||||
|
||||
if ([NSApp respondsToSelector:@selector(setAppleMenu:)])
|
||||
{
|
||||
[NSApp performSelector:@selector(setAppleMenu:) withObject:menu];
|
||||
}
|
||||
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
NSMenuItem* CreateEditMenu()
|
||||
{
|
||||
NSMenu* menu = [[NSMenu alloc] initWithTitle:@"Edit"];
|
||||
|
||||
[menu addItemWithTitle:@"Undo"
|
||||
action:@selector(undo:)
|
||||
keyEquivalent:@"z"];
|
||||
[menu addItemWithTitle:@"Redo"
|
||||
action:@selector(redo:)
|
||||
keyEquivalent:@"Z"];
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
[menu addItemWithTitle:@"Cut"
|
||||
action:@selector(cut:)
|
||||
keyEquivalent:@"x"];
|
||||
[menu addItemWithTitle:@"Copy"
|
||||
action:@selector(copy:)
|
||||
keyEquivalent:@"c"];
|
||||
[menu addItemWithTitle:@"Paste"
|
||||
action:@selector(paste:)
|
||||
keyEquivalent:@"v"];
|
||||
[menu addItemWithTitle:@"Delete"
|
||||
action:@selector(delete:)
|
||||
keyEquivalent:@""];
|
||||
[menu addItemWithTitle:@"Select All"
|
||||
action:@selector(selectAll:)
|
||||
keyEquivalent:@"a"];
|
||||
|
||||
NSMenuItem* menuItem = [NSMenuItem new];
|
||||
[menuItem setSubmenu:menu];
|
||||
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
NSMenuItem* CreateWindowMenu()
|
||||
{
|
||||
NSMenu* menu = [[NSMenu alloc] initWithTitle:@"Window"];
|
||||
[NSApp setWindowsMenu:menu];
|
||||
|
||||
[menu addItemWithTitle:@"Minimize"
|
||||
action:@selector(performMiniaturize:)
|
||||
keyEquivalent:@"m"];
|
||||
[menu addItemWithTitle:@"Zoom"
|
||||
action:@selector(performZoom:)
|
||||
keyEquivalent:@""];
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
[menu addItemWithTitle:@"Bring All to Front"
|
||||
action:@selector(arrangeInFront:)
|
||||
keyEquivalent:@""];
|
||||
|
||||
NSMenuItem* menuItem = [NSMenuItem new];
|
||||
[menuItem setSubmenu:menu];
|
||||
|
||||
return menuItem;
|
||||
}
|
||||
|
||||
void CreateMenu()
|
||||
{
|
||||
NSMenu* menuBar = [NSMenu new];
|
||||
[menuBar addItem:CreateApplicationMenu()];
|
||||
[menuBar addItem:CreateEditMenu()];
|
||||
[menuBar addItem:CreateWindowMenu()];
|
||||
|
||||
[NSApp setMainMenu:menuBar];
|
||||
}
|
||||
|
||||
void ReleaseApplicationController()
|
||||
{
|
||||
if (NULL != appCtrl)
|
||||
{
|
||||
[NSApp setDelegate:nil];
|
||||
[NSApp deactivate];
|
||||
|
||||
[appCtrl release];
|
||||
appCtrl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
for (int i = 0; i <= argc; ++i)
|
||||
{
|
||||
const char* const argument = argv[i];
|
||||
|
||||
if (NULL == argument || '\0' == argument[0])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (0 == strcmp(argument, "-wad_picker_restart"))
|
||||
{
|
||||
s_restartedFromWADPicker = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_argvStorage.Push(argument);
|
||||
s_argv[s_argc++] = s_argvStorage.Last().LockBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
// The following code isn't mandatory,
|
||||
// but it enables to run the application without a bundle
|
||||
if ([NSApp respondsToSelector:@selector(setActivationPolicy:)])
|
||||
{
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
}
|
||||
|
||||
CreateMenu();
|
||||
|
||||
atterm(ReleaseApplicationController);
|
||||
|
||||
appCtrl = [ApplicationController new];
|
||||
[NSApp setDelegate:appCtrl];
|
||||
[NSApp run];
|
||||
|
||||
[pool release];
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,11 +1,42 @@
|
|||
/*
|
||||
** i_timer.cpp
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2012-2015 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 <assert.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "basictypes.h"
|
||||
#include "basicinlines.h"
|
||||
#include "doomdef.h"
|
||||
|
@ -13,23 +44,25 @@
|
|||
#include "templates.h"
|
||||
|
||||
|
||||
unsigned int I_MSTime()
|
||||
{
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
|
||||
unsigned int I_FPSTime()
|
||||
{
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
|
||||
|
||||
bool g_isTicFrozen;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
timeval s_gameStartTicks;
|
||||
timeval s_systemBootTicks;
|
||||
|
||||
unsigned int GetMillisecondsSince(const timeval& time)
|
||||
{
|
||||
timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
return static_cast<unsigned int>(
|
||||
(now.tv_sec - time.tv_sec ) * 1000
|
||||
+ (now.tv_usec - time.tv_usec) / 1000);
|
||||
}
|
||||
|
||||
|
||||
bool s_isTicFrozen;
|
||||
|
||||
timespec GetNextTickTime()
|
||||
{
|
||||
static const long MILLISECONDS_IN_SECOND = 1000;
|
||||
|
@ -91,7 +124,7 @@ void* TimerThreadFunc(void*)
|
|||
pthread_mutex_lock(&s_timerMutex);
|
||||
pthread_cond_timedwait(&s_timerEvent, &s_timerMutex, &timeToNextTick);
|
||||
|
||||
if (!g_isTicFrozen)
|
||||
if (!s_isTicFrozen)
|
||||
{
|
||||
// The following GCC/Clang intrinsic can be used instead of OS X specific function:
|
||||
// __sync_add_and_fetch(&s_tics, 1);
|
||||
|
@ -101,7 +134,7 @@ void* TimerThreadFunc(void*)
|
|||
OSAtomicIncrement32(&s_tics);
|
||||
}
|
||||
|
||||
s_timerStart = SDL_GetTicks();
|
||||
s_timerStart = I_MSTime();
|
||||
|
||||
pthread_cond_broadcast(&s_timerEvent);
|
||||
pthread_mutex_unlock(&s_timerMutex);
|
||||
|
@ -122,7 +155,7 @@ int GetTimeThreaded(bool saveMS)
|
|||
|
||||
int WaitForTicThreaded(int prevTic)
|
||||
{
|
||||
assert(!g_isTicFrozen);
|
||||
assert(!s_isTicFrozen);
|
||||
|
||||
while (s_tics <= prevTic)
|
||||
{
|
||||
|
@ -136,15 +169,26 @@ int WaitForTicThreaded(int prevTic)
|
|||
|
||||
void FreezeTimeThreaded(bool frozen)
|
||||
{
|
||||
g_isTicFrozen = frozen;
|
||||
s_isTicFrozen = frozen;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
unsigned int I_MSTime()
|
||||
{
|
||||
return GetMillisecondsSince(s_gameStartTicks);
|
||||
}
|
||||
|
||||
unsigned int I_FPSTime()
|
||||
{
|
||||
return GetMillisecondsSince(s_systemBootTicks);
|
||||
}
|
||||
|
||||
|
||||
fixed_t I_GetTimeFrac(uint32* ms)
|
||||
{
|
||||
const uint32_t now = SDL_GetTicks();
|
||||
const uint32_t now = I_MSTime();
|
||||
|
||||
if (NULL != ms)
|
||||
{
|
||||
|
@ -157,11 +201,18 @@ fixed_t I_GetTimeFrac(uint32* ms)
|
|||
}
|
||||
|
||||
|
||||
void I_InitTimer ()
|
||||
void I_InitTimer()
|
||||
{
|
||||
assert(!s_timerInitialized);
|
||||
s_timerInitialized = true;
|
||||
|
||||
gettimeofday(&s_gameStartTicks, NULL);
|
||||
|
||||
int mib[2] = { CTL_KERN, KERN_BOOTTIME };
|
||||
size_t len = sizeof s_systemBootTicks;
|
||||
|
||||
sysctl(mib, 2, &s_systemBootTicks, &len, NULL, 0);
|
||||
|
||||
pthread_cond_init (&s_timerEvent, NULL);
|
||||
pthread_mutex_init(&s_timerMutex, NULL);
|
||||
|
||||
|
@ -172,7 +223,7 @@ void I_InitTimer ()
|
|||
I_FreezeTime = FreezeTimeThreaded;
|
||||
}
|
||||
|
||||
void I_ShutdownTimer ()
|
||||
void I_ShutdownTimer()
|
||||
{
|
||||
if (!s_timerInitialized)
|
||||
{
|
1232
src/posix/cocoa/i_video.mm
Normal file
1232
src/posix/cocoa/i_video.mm
Normal file
File diff suppressed because it is too large
Load diff
|
@ -34,6 +34,10 @@
|
|||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif // __APPLE__
|
||||
|
||||
#include "doomerrors.h"
|
||||
#include "d_main.h"
|
||||
#include "zstring.h"
|
||||
|
@ -167,9 +171,20 @@ TArray<FString> I_GetSteamPath()
|
|||
// we need to figure out on an app-by-app basis where the game is installed.
|
||||
// To do so, we read the virtual registry.
|
||||
#ifdef __APPLE__
|
||||
FString OSX_FindApplicationSupport();
|
||||
FString appSupportPath;
|
||||
|
||||
FString regPath = OSX_FindApplicationSupport() + "/Steam/config/config.vdf";
|
||||
{
|
||||
char cpath[PATH_MAX];
|
||||
FSRef folder;
|
||||
|
||||
if (noErr == FSFindFolder(kUserDomain, kApplicationSupportFolderType, kCreateFolder, &folder) &&
|
||||
noErr == FSRefMakePath(&folder, (UInt8*)cpath, PATH_MAX))
|
||||
{
|
||||
appSupportPath = cpath;
|
||||
}
|
||||
}
|
||||
|
||||
FString regPath = appSupportPath + "/Steam/config/config.vdf";
|
||||
try
|
||||
{
|
||||
SteamInstallFolders = ParseSteamRegistry(regPath);
|
||||
|
@ -180,7 +195,7 @@ TArray<FString> I_GetSteamPath()
|
|||
return result;
|
||||
}
|
||||
|
||||
SteamInstallFolders.Push(OSX_FindApplicationSupport() + "/Steam/SteamApps/common");
|
||||
SteamInstallFolders.Push(appSupportPath + "/Steam/SteamApps/common");
|
||||
#else
|
||||
char* home = getenv("HOME");
|
||||
if(home != NULL && *home != '\0')
|
|
@ -41,7 +41,6 @@
|
|||
#include "doomerrors.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "SDL.h"
|
||||
#include "doomtype.h"
|
||||
#include "doomstat.h"
|
||||
#include "version.h"
|
|
@ -408,21 +408,28 @@ static void RestartWithParameters(const char* iwadPath, NSString* parameters)
|
|||
|
||||
@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];
|
||||
NSMutableArray* const arguments = [[NSMutableArray alloc] init];
|
||||
|
||||
// The following value shoud be equal to NSAppKitVersionNumber10_5
|
||||
// It's hard-coded in order to build with earlier SDKs
|
||||
const bool canSelectArchitecture = NSAppKitVersionNumber >= 949;
|
||||
|
||||
if (canSelectArchitecture)
|
||||
{
|
||||
[arguments addObject:@"-arch"];
|
||||
[arguments addObject:architecture];
|
||||
[arguments addObject:GetArchitectureString()];
|
||||
[arguments addObject:executablePath];
|
||||
|
||||
executablePath = @"/usr/bin/arch";
|
||||
}
|
||||
|
||||
[arguments addObject:@"-wad_picker_restart"];
|
||||
[arguments addObject:@"-iwad"];
|
||||
[arguments addObject:[NSString stringWithUTF8String:iwadPath]];
|
||||
|
||||
for (int i = 1; i < commandLineParametersCount; ++i)
|
||||
for (int i = 1, count = Args->NumArgs(); i < count; ++i)
|
||||
{
|
||||
NSString* currentParameter = [NSString stringWithUTF8String:Args->GetArg(i)];
|
||||
[arguments addObject:currentParameter];
|
||||
|
@ -442,7 +449,8 @@ static void RestartWithParameters(const char* iwadPath, NSString* parameters)
|
|||
wordfree(&expansion);
|
||||
}
|
||||
|
||||
[NSTask launchedTaskWithLaunchPath:@"/usr/bin/arch" arguments:arguments];
|
||||
[NSTask launchedTaskWithLaunchPath:executablePath
|
||||
arguments:arguments];
|
||||
|
||||
_exit(0); // to avoid atexit()'s functions
|
||||
}
|
6
src/posix/readme.md
Normal file
6
src/posix/readme.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
This directory contains files required to support POSIX-compatible OSes, like GNU/Linux, OS X or BSD.
|
||||
|
||||
Common files are placed in this directory directly.
|
||||
SDL backend files are in `sdl` subdirectory.
|
||||
Native OS X backend files are in `cocoa` subdirectory.
|
||||
Shared files for both OS X backends are in `osx` subdirectory.
|
61
src/posix/sdl/i_gui.cpp
Normal file
61
src/posix/sdl/i_gui.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
|
||||
// Moved from sdl/i_system.cpp
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "bitmap.h"
|
||||
#include "v_palette.h"
|
||||
#include "textures.h"
|
||||
|
||||
bool I_SetCursor(FTexture *cursorpic)
|
||||
{
|
||||
static SDL_Cursor *cursor;
|
||||
static SDL_Surface *cursorSurface;
|
||||
|
||||
if (cursorpic != NULL && cursorpic->UseType != FTexture::TEX_Null)
|
||||
{
|
||||
// Must be no larger than 32x32.
|
||||
if (cursorpic->GetWidth() > 32 || cursorpic->GetHeight() > 32)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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_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);
|
||||
|
||||
if (cursor)
|
||||
SDL_FreeCursor (cursor);
|
||||
cursor = SDL_CreateColorCursor (cursorSurface, 0, 0);
|
||||
SDL_SetCursor (cursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cursor)
|
||||
{
|
||||
SDL_SetCursor (NULL);
|
||||
SDL_FreeCursor (cursor);
|
||||
cursor = NULL;
|
||||
}
|
||||
if (cursorSurface != NULL)
|
||||
{
|
||||
SDL_FreeSurface(cursorSurface);
|
||||
cursorSurface = NULL;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void I_SetMainWindowVisible(bool visible)
|
||||
{
|
||||
|
||||
}
|
514
src/posix/sdl/i_input.cpp
Normal file
514
src/posix/sdl/i_input.cpp
Normal file
|
@ -0,0 +1,514 @@
|
|||
#include <SDL.h>
|
||||
#include <ctype.h>
|
||||
#include "doomtype.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "m_argv.h"
|
||||
#include "i_input.h"
|
||||
#include "v_video.h"
|
||||
|
||||
#include "d_main.h"
|
||||
#include "d_event.h"
|
||||
#include "d_gui.h"
|
||||
#include "c_console.h"
|
||||
#include "c_cvars.h"
|
||||
#include "i_system.h"
|
||||
#include "dikeys.h"
|
||||
#include "templates.h"
|
||||
#include "s_sound.h"
|
||||
|
||||
void ScaleWithAspect (int &w, int &h, int Width, int Height);
|
||||
|
||||
static void I_CheckGUICapture ();
|
||||
static void I_CheckNativeMouse ();
|
||||
|
||||
bool GUICapture;
|
||||
static bool NativeMouse = true;
|
||||
|
||||
extern int paused;
|
||||
|
||||
CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
EXTERN_CVAR (Bool, fullscreen)
|
||||
|
||||
extern int WaitingForKey, chatmodeon;
|
||||
extern constate_e ConsoleState;
|
||||
|
||||
static bool DownState[SDL_NUM_SCANCODES];
|
||||
|
||||
static const SDL_Keycode DIKToKeySym[256] =
|
||||
{
|
||||
0, SDLK_ESCAPE, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6,
|
||||
SDLK_7, SDLK_8, SDLK_9, SDLK_0,SDLK_MINUS, SDLK_EQUALS, SDLK_BACKSPACE, SDLK_TAB,
|
||||
SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i,
|
||||
SDLK_o, SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, SDLK_RETURN, SDLK_LCTRL, SDLK_a, SDLK_s,
|
||||
SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l, SDLK_SEMICOLON,
|
||||
SDLK_QUOTE, SDLK_BACKQUOTE, SDLK_LSHIFT, SDLK_BACKSLASH, SDLK_z, SDLK_x, SDLK_c, SDLK_v,
|
||||
SDLK_b, SDLK_n, SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH, SDLK_RSHIFT, SDLK_KP_MULTIPLY,
|
||||
SDLK_LALT, SDLK_SPACE, SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5,
|
||||
SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCKCLEAR, SDLK_SCROLLLOCK, SDLK_KP_7,
|
||||
SDLK_KP_8, SDLK_KP_9, SDLK_KP_MINUS, SDLK_KP_4, SDLK_KP_5, SDLK_KP_6, SDLK_KP_PLUS, SDLK_KP_1,
|
||||
SDLK_KP_2, SDLK_KP_3, SDLK_KP_0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11,
|
||||
SDLK_F12, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, SDLK_F13, SDLK_F14, SDLK_F15, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, SDLK_KP_EQUALS, 0, 0,
|
||||
0, SDLK_AT, SDLK_COLON, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, SDLK_KP_ENTER, SDLK_RCTRL, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, SDLK_KP_COMMA, 0, SDLK_KP_DIVIDE, 0, SDLK_SYSREQ,
|
||||
SDLK_RALT, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, SDLK_PAUSE, 0, SDLK_HOME,
|
||||
SDLK_UP, SDLK_PAGEUP, 0, SDLK_LEFT, 0, SDLK_RIGHT, 0, SDLK_END,
|
||||
SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, 0, 0, 0, 0,
|
||||
0, 0, 0, SDLK_LGUI, SDLK_RGUI, SDLK_MENU, SDLK_POWER, SDLK_SLEEP,
|
||||
0, 0, 0, 0, 0, SDLK_AC_SEARCH, SDLK_AC_BOOKMARKS, SDLK_AC_REFRESH,
|
||||
SDLK_AC_STOP, SDLK_AC_FORWARD, SDLK_AC_BACK, SDLK_COMPUTER, SDLK_MAIL, SDLK_MEDIASELECT, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const SDL_Scancode DIKToKeyScan[256] =
|
||||
{
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6,
|
||||
SDL_SCANCODE_7, SDL_SCANCODE_8, SDL_SCANCODE_9, SDL_SCANCODE_0 ,SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS, SDL_SCANCODE_BACKSPACE, SDL_SCANCODE_TAB,
|
||||
SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_E, SDL_SCANCODE_R, SDL_SCANCODE_T, SDL_SCANCODE_Y, SDL_SCANCODE_U, SDL_SCANCODE_I,
|
||||
SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_LEFTBRACKET, SDL_SCANCODE_RIGHTBRACKET, SDL_SCANCODE_RETURN, SDL_SCANCODE_LCTRL, SDL_SCANCODE_A, SDL_SCANCODE_S,
|
||||
SDL_SCANCODE_D, SDL_SCANCODE_F, SDL_SCANCODE_G, SDL_SCANCODE_H, SDL_SCANCODE_J, SDL_SCANCODE_K, SDL_SCANCODE_L, SDL_SCANCODE_SEMICOLON,
|
||||
SDL_SCANCODE_APOSTROPHE, SDL_SCANCODE_GRAVE, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_BACKSLASH, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_C, SDL_SCANCODE_V,
|
||||
SDL_SCANCODE_B, SDL_SCANCODE_N, SDL_SCANCODE_M, SDL_SCANCODE_COMMA, SDL_SCANCODE_PERIOD, SDL_SCANCODE_SLASH, SDL_SCANCODE_RSHIFT, SDL_SCANCODE_KP_MULTIPLY,
|
||||
SDL_SCANCODE_LALT, SDL_SCANCODE_SPACE, SDL_SCANCODE_CAPSLOCK, SDL_SCANCODE_F1, SDL_SCANCODE_F2, SDL_SCANCODE_F3, SDL_SCANCODE_F4, SDL_SCANCODE_F5,
|
||||
SDL_SCANCODE_F6, SDL_SCANCODE_F7, SDL_SCANCODE_F8, SDL_SCANCODE_F9, SDL_SCANCODE_F10, SDL_SCANCODE_NUMLOCKCLEAR, SDL_SCANCODE_SCROLLLOCK, SDL_SCANCODE_KP_7,
|
||||
SDL_SCANCODE_KP_8, SDL_SCANCODE_KP_9, SDL_SCANCODE_KP_MINUS, SDL_SCANCODE_KP_4, SDL_SCANCODE_KP_5, SDL_SCANCODE_KP_6, SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_KP_1,
|
||||
SDL_SCANCODE_KP_2, SDL_SCANCODE_KP_3, SDL_SCANCODE_KP_0, SDL_SCANCODE_KP_PERIOD, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_F11,
|
||||
SDL_SCANCODE_F12, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_F13, SDL_SCANCODE_F14, SDL_SCANCODE_F15, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_EQUALS, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_ENTER, SDL_SCANCODE_RCTRL, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_COMMA, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_DIVIDE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_SYSREQ,
|
||||
SDL_SCANCODE_RALT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_PAUSE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_HOME,
|
||||
SDL_SCANCODE_UP, SDL_SCANCODE_PAGEUP, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_END,
|
||||
SDL_SCANCODE_DOWN, SDL_SCANCODE_PAGEDOWN, SDL_SCANCODE_INSERT, SDL_SCANCODE_DELETE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_LGUI, SDL_SCANCODE_RGUI, SDL_SCANCODE_MENU, SDL_SCANCODE_POWER, SDL_SCANCODE_SLEEP,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_AC_SEARCH, SDL_SCANCODE_AC_BOOKMARKS, SDL_SCANCODE_AC_REFRESH,
|
||||
SDL_SCANCODE_AC_STOP, SDL_SCANCODE_AC_FORWARD, SDL_SCANCODE_AC_BACK, SDL_SCANCODE_COMPUTER, SDL_SCANCODE_MAIL, SDL_SCANCODE_MEDIASELECT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN
|
||||
};
|
||||
|
||||
static TMap<SDL_Keycode, BYTE> InitKeySymMap ()
|
||||
{
|
||||
TMap<SDL_Keycode, BYTE> KeySymToDIK;
|
||||
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
KeySymToDIK[DIKToKeySym[i]] = i;
|
||||
}
|
||||
KeySymToDIK[0] = 0;
|
||||
KeySymToDIK[SDLK_RSHIFT] = DIK_LSHIFT;
|
||||
KeySymToDIK[SDLK_RCTRL] = DIK_LCONTROL;
|
||||
KeySymToDIK[SDLK_RALT] = DIK_LMENU;
|
||||
// Depending on your Linux flavor, you may get SDLK_PRINT or SDLK_SYSREQ
|
||||
KeySymToDIK[SDLK_PRINTSCREEN] = DIK_SYSRQ;
|
||||
|
||||
return KeySymToDIK;
|
||||
}
|
||||
static const TMap<SDL_Keycode, BYTE> KeySymToDIK(InitKeySymMap());
|
||||
|
||||
static TMap<SDL_Scancode, BYTE> InitKeyScanMap ()
|
||||
{
|
||||
TMap<SDL_Scancode, BYTE> KeyScanToDIK;
|
||||
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
KeyScanToDIK[DIKToKeyScan[i]] = i;
|
||||
}
|
||||
|
||||
return KeyScanToDIK;
|
||||
}
|
||||
static const TMap<SDL_Scancode, BYTE> KeyScanToDIK(InitKeyScanMap());
|
||||
|
||||
static void I_CheckGUICapture ()
|
||||
{
|
||||
bool wantCapt;
|
||||
|
||||
if (menuactive == MENU_Off)
|
||||
{
|
||||
wantCapt = ConsoleState == c_down || ConsoleState == c_falling || chatmodeon;
|
||||
}
|
||||
else
|
||||
{
|
||||
wantCapt = (menuactive == MENU_On || menuactive == MENU_OnNoPause);
|
||||
}
|
||||
|
||||
if (wantCapt != GUICapture)
|
||||
{
|
||||
GUICapture = wantCapt;
|
||||
if (wantCapt)
|
||||
{
|
||||
memset (DownState, 0, sizeof(DownState));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void I_SetMouseCapture()
|
||||
{
|
||||
// Clear out any mouse movement.
|
||||
SDL_GetRelativeMouseState (NULL, NULL);
|
||||
SDL_SetRelativeMouseMode (SDL_TRUE);
|
||||
}
|
||||
|
||||
void I_ReleaseMouseCapture()
|
||||
{
|
||||
SDL_SetRelativeMouseMode (SDL_FALSE);
|
||||
}
|
||||
|
||||
static void PostMouseMove (int x, int y)
|
||||
{
|
||||
static int lastx = 0, lasty = 0;
|
||||
event_t ev = { 0,0,0,0,0,0,0 };
|
||||
|
||||
if (m_filter)
|
||||
{
|
||||
ev.x = (x + lastx) / 2;
|
||||
ev.y = (y + lasty) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ev.x = x;
|
||||
ev.y = y;
|
||||
}
|
||||
lastx = x;
|
||||
lasty = y;
|
||||
if (ev.x | ev.y)
|
||||
{
|
||||
ev.type = EV_Mouse;
|
||||
D_PostEvent (&ev);
|
||||
}
|
||||
}
|
||||
|
||||
static void MouseRead ()
|
||||
{
|
||||
int x, y;
|
||||
|
||||
if (NativeMouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_GetRelativeMouseState (&x, &y);
|
||||
if (!m_noprescale)
|
||||
{
|
||||
x *= 3;
|
||||
y *= 2;
|
||||
}
|
||||
if (x | y)
|
||||
{
|
||||
PostMouseMove (x, -y);
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, mouse_capturemode, 1, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
|
||||
{
|
||||
if (self < 0) self = 0;
|
||||
else if (self > 2) self = 2;
|
||||
}
|
||||
|
||||
static bool inGame()
|
||||
{
|
||||
switch (mouse_capturemode)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
return gamestate == GS_LEVEL;
|
||||
case 1:
|
||||
return gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_FINALE;
|
||||
case 2:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static void I_CheckNativeMouse ()
|
||||
{
|
||||
bool focus = SDL_GetKeyboardFocus() != NULL;
|
||||
bool fs = screen->IsFullscreen();
|
||||
|
||||
bool wantNative = !focus || (!use_mouse || GUICapture || paused || demoplayback || !inGame());
|
||||
|
||||
if (wantNative != NativeMouse)
|
||||
{
|
||||
NativeMouse = wantNative;
|
||||
SDL_ShowCursor (wantNative);
|
||||
if (wantNative)
|
||||
I_ReleaseMouseCapture ();
|
||||
else
|
||||
I_SetMouseCapture ();
|
||||
}
|
||||
}
|
||||
|
||||
void MessagePump (const SDL_Event &sev)
|
||||
{
|
||||
static int lastx = 0, lasty = 0;
|
||||
int x, y;
|
||||
event_t event = { 0,0,0,0,0,0,0 };
|
||||
|
||||
switch (sev.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
exit (0);
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
switch (sev.window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
S_SetSoundPaused(sev.window.event == SDL_WINDOWEVENT_FOCUS_GAINED);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
case SDL_MOUSEMOTION:
|
||||
if (!GUICapture || sev.button.button == 4 || sev.button.button == 5)
|
||||
{
|
||||
if(sev.type != SDL_MOUSEMOTION)
|
||||
{
|
||||
event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp;
|
||||
/* These button mappings work with my Gentoo system using the
|
||||
* evdev driver and a Logitech MX510 mouse. Whether or not they
|
||||
* carry over to other Linux systems, I have no idea, but I sure
|
||||
* hope so. (Though buttons 11 and 12 are kind of useless, since
|
||||
* they also trigger buttons 4 and 5.)
|
||||
*/
|
||||
switch (sev.button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT: event.data1 = KEY_MOUSE1; break;
|
||||
case SDL_BUTTON_MIDDLE: event.data1 = KEY_MOUSE3; break;
|
||||
case SDL_BUTTON_RIGHT: event.data1 = KEY_MOUSE2; break;
|
||||
case 8: event.data1 = KEY_MOUSE4; break; // For whatever reason my side mouse buttons are here.
|
||||
case 9: event.data1 = KEY_MOUSE5; break;
|
||||
case SDL_BUTTON_X1: event.data1 = KEY_MOUSE6; break; // And these don't exist
|
||||
case SDL_BUTTON_X2: event.data1 = KEY_MOUSE7; break;
|
||||
case 6: event.data1 = KEY_MOUSE8; break;
|
||||
default: printf("SDL mouse button %s %d\n",
|
||||
sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break;
|
||||
}
|
||||
if (event.data1 != 0)
|
||||
{
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sev.type == SDL_MOUSEMOTION || (sev.button.button >= 1 && sev.button.button <= 3))
|
||||
{
|
||||
int x, y;
|
||||
SDL_GetMouseState (&x, &y);
|
||||
|
||||
// Detect if we're doing scaling in the Window and adjust the mouse
|
||||
// coordinates accordingly. This could be more efficent, but I
|
||||
// don't think performance is an issue in the menus.
|
||||
SDL_Window *focus;
|
||||
if (screen->IsFullscreen() && (focus = SDL_GetMouseFocus ()))
|
||||
{
|
||||
int w, h;
|
||||
SDL_GetWindowSize (focus, &w, &h);
|
||||
int realw = w, realh = h;
|
||||
ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT);
|
||||
if (realw != SCREENWIDTH || realh != SCREENHEIGHT)
|
||||
{
|
||||
double xratio = (double)SCREENWIDTH/realw;
|
||||
double yratio = (double)SCREENHEIGHT/realh;
|
||||
if (realw < w)
|
||||
{
|
||||
x = (x - (w - realw)/2)*xratio;
|
||||
y *= yratio;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = (y - (h - realh)/2)*yratio;
|
||||
x *= xratio;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event.data1 = x;
|
||||
event.data2 = y;
|
||||
event.type = EV_GUI_Event;
|
||||
if(sev.type == SDL_MOUSEMOTION)
|
||||
event.subtype = EV_GUI_MouseMove;
|
||||
else
|
||||
{
|
||||
event.subtype = sev.type == SDL_MOUSEBUTTONDOWN ? EV_GUI_LButtonDown : EV_GUI_LButtonUp;
|
||||
event.subtype += (sev.button.button - 1) * 3;
|
||||
}
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
if (GUICapture)
|
||||
{
|
||||
event.type = EV_GUI_Event;
|
||||
event.subtype = sev.wheel.y > 0 ? EV_GUI_WheelUp : EV_GUI_WheelDown;
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
else
|
||||
{
|
||||
event.type = EV_KeyDown;
|
||||
event.data1 = sev.wheel.y > 0 ? KEY_MWHEELUP : KEY_MWHEELDOWN;
|
||||
D_PostEvent (&event);
|
||||
event.type = EV_KeyUp;
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
if (!GUICapture)
|
||||
{
|
||||
event.type = sev.type == SDL_KEYDOWN ? EV_KeyDown : EV_KeyUp;
|
||||
|
||||
// Try to look up our key mapped key for conversion to DirectInput.
|
||||
// If that fails, then we'll do a lookup against the scan code,
|
||||
// which may not return the right key, but at least the key should
|
||||
// work in the game.
|
||||
if (const BYTE *dik = KeySymToDIK.CheckKey (sev.key.keysym.sym))
|
||||
event.data1 = *dik;
|
||||
else if (const BYTE *dik = KeyScanToDIK.CheckKey (sev.key.keysym.scancode))
|
||||
event.data1 = *dik;
|
||||
|
||||
if (event.data1)
|
||||
{
|
||||
if (sev.key.keysym.sym < 256)
|
||||
{
|
||||
event.data2 = sev.key.keysym.sym;
|
||||
}
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
event.type = EV_GUI_Event;
|
||||
event.subtype = sev.type == SDL_KEYDOWN ? EV_GUI_KeyDown : EV_GUI_KeyUp;
|
||||
event.data3 = ((sev.key.keysym.mod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
|
||||
((sev.key.keysym.mod & KMOD_CTRL) ? GKM_CTRL : 0) |
|
||||
((sev.key.keysym.mod & KMOD_ALT) ? GKM_ALT : 0);
|
||||
|
||||
if (event.subtype == EV_GUI_KeyDown)
|
||||
{
|
||||
if (DownState[sev.key.keysym.scancode])
|
||||
{
|
||||
event.subtype = EV_GUI_KeyRepeat;
|
||||
}
|
||||
DownState[sev.key.keysym.scancode] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DownState[sev.key.keysym.scancode] = 0;
|
||||
}
|
||||
|
||||
switch (sev.key.keysym.sym)
|
||||
{
|
||||
case SDLK_KP_ENTER: event.data1 = GK_RETURN; break;
|
||||
case SDLK_PAGEUP: event.data1 = GK_PGUP; break;
|
||||
case SDLK_PAGEDOWN: event.data1 = GK_PGDN; break;
|
||||
case SDLK_END: event.data1 = GK_END; break;
|
||||
case SDLK_HOME: event.data1 = GK_HOME; break;
|
||||
case SDLK_LEFT: event.data1 = GK_LEFT; break;
|
||||
case SDLK_RIGHT: event.data1 = GK_RIGHT; break;
|
||||
case SDLK_UP: event.data1 = GK_UP; break;
|
||||
case SDLK_DOWN: event.data1 = GK_DOWN; break;
|
||||
case SDLK_DELETE: event.data1 = GK_DEL; break;
|
||||
case SDLK_ESCAPE: event.data1 = GK_ESCAPE; break;
|
||||
case SDLK_F1: event.data1 = GK_F1; break;
|
||||
case SDLK_F2: event.data1 = GK_F2; break;
|
||||
case SDLK_F3: event.data1 = GK_F3; break;
|
||||
case SDLK_F4: event.data1 = GK_F4; break;
|
||||
case SDLK_F5: event.data1 = GK_F5; break;
|
||||
case SDLK_F6: event.data1 = GK_F6; break;
|
||||
case SDLK_F7: event.data1 = GK_F7; break;
|
||||
case SDLK_F8: event.data1 = GK_F8; break;
|
||||
case SDLK_F9: event.data1 = GK_F9; break;
|
||||
case SDLK_F10: event.data1 = GK_F10; break;
|
||||
case SDLK_F11: event.data1 = GK_F11; break;
|
||||
case SDLK_F12: event.data1 = GK_F12; break;
|
||||
default:
|
||||
if (sev.key.keysym.sym < 256)
|
||||
{
|
||||
event.data1 = sev.key.keysym.sym;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (event.data1 < 128)
|
||||
{
|
||||
event.data1 = toupper(event.data1);
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
if (GUICapture)
|
||||
{
|
||||
event.type = EV_GUI_Event;
|
||||
event.subtype = EV_GUI_Char;
|
||||
event.data1 = sev.text.text[0];
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP:
|
||||
if (!GUICapture)
|
||||
{
|
||||
event.type = sev.type == SDL_JOYBUTTONDOWN ? EV_KeyDown : EV_KeyUp;
|
||||
event.data1 = KEY_FIRSTJOYBUTTON + sev.jbutton.button;
|
||||
if(event.data1 != 0)
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void I_GetEvent ()
|
||||
{
|
||||
SDL_Event sev;
|
||||
|
||||
while (SDL_PollEvent (&sev))
|
||||
{
|
||||
MessagePump (sev);
|
||||
}
|
||||
if (use_mouse)
|
||||
{
|
||||
MouseRead ();
|
||||
}
|
||||
}
|
||||
|
||||
void I_StartTic ()
|
||||
{
|
||||
I_CheckGUICapture ();
|
||||
I_CheckNativeMouse ();
|
||||
I_GetEvent ();
|
||||
}
|
||||
|
||||
void I_ProcessJoysticks ();
|
||||
void I_StartFrame ()
|
||||
{
|
||||
I_ProcessJoysticks();
|
||||
}
|
|
@ -35,7 +35,7 @@ public:
|
|||
|
||||
FString GetName()
|
||||
{
|
||||
return SDL_JoystickName(DeviceIndex);
|
||||
return SDL_JoystickName(Device);
|
||||
}
|
||||
float GetSensitivity()
|
||||
{
|
|
@ -85,10 +85,6 @@ void Mac_I_FatalError(const char* errortext);
|
|||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
#ifdef USE_XCURSOR
|
||||
extern bool UseXCursor;
|
||||
#endif
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
#ifndef NO_GTK
|
||||
|
@ -239,8 +235,6 @@ static void unprotect_rtext()
|
|||
void I_StartupJoysticks();
|
||||
void I_ShutdownJoysticks();
|
||||
|
||||
const char* I_GetBackEndName();
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
#if !defined (__APPLE__)
|
||||
|
@ -250,8 +244,8 @@ int main (int argc, char **argv)
|
|||
}
|
||||
#endif // !__APPLE__
|
||||
|
||||
printf(GAMENAME" %s - %s - %s version\nCompiled on %s\n",
|
||||
GetVersionString(), GetGitTime(), I_GetBackEndName(), __DATE__);
|
||||
printf(GAMENAME" %s - %s - SDL version\nCompiled on %s\n",
|
||||
GetVersionString(), GetGitTime(), __DATE__);
|
||||
|
||||
seteuid (getuid ());
|
||||
std::set_new_handler (NewFailure);
|
||||
|
@ -278,42 +272,8 @@ int main (int argc, char **argv)
|
|||
}
|
||||
atterm (SDL_Quit);
|
||||
|
||||
{
|
||||
char viddriver[80];
|
||||
|
||||
if (SDL_VideoDriverName(viddriver, sizeof(viddriver)) != NULL)
|
||||
{
|
||||
printf("Using video driver %s\n", viddriver);
|
||||
#ifdef USE_XCURSOR
|
||||
UseXCursor = (strcmp(viddriver, "x11") == 0);
|
||||
#endif
|
||||
}
|
||||
printf("Using video driver %s\n", SDL_GetCurrentVideoDriver());
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
char caption[100];
|
||||
mysnprintf(caption, countof(caption), GAMESIG " %s (%s)", GetVersionString(), GetGitTime());
|
||||
SDL_WM_SetCaption(caption, caption);
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();
|
||||
if ( NULL != videoInfo )
|
||||
{
|
||||
EXTERN_CVAR( Int, vid_defwidth )
|
||||
EXTERN_CVAR( Int, vid_defheight )
|
||||
EXTERN_CVAR( Int, vid_defbits )
|
||||
EXTERN_CVAR( Bool, vid_vsync )
|
||||
EXTERN_CVAR( Bool, fullscreen )
|
||||
|
||||
vid_defwidth = videoInfo->current_w;
|
||||
vid_defheight = videoInfo->current_h;
|
||||
vid_defbits = videoInfo->vfmt->BitsPerPixel;
|
||||
vid_vsync = true;
|
||||
fullscreen = true;
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
try
|
||||
{
|
|
@ -12,6 +12,7 @@
|
|||
#include "v_palette.h"
|
||||
#include "sdlvideo.h"
|
||||
#include "r_swrenderer.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
|
@ -42,6 +43,7 @@ public:
|
|||
bool SetGamma (float gamma);
|
||||
bool SetFlash (PalEntry rgb, int amount);
|
||||
void GetFlash (PalEntry &rgb, int &amount);
|
||||
void SetFullscreen (bool fullscreen);
|
||||
int GetPageCount ();
|
||||
bool IsFullscreen ();
|
||||
|
||||
|
@ -57,13 +59,22 @@ private:
|
|||
float Gamma;
|
||||
bool UpdatePending;
|
||||
|
||||
SDL_Surface *Screen;
|
||||
SDL_Window *Screen;
|
||||
SDL_Renderer *Renderer;
|
||||
union
|
||||
{
|
||||
SDL_Texture *Texture;
|
||||
SDL_Surface *Surface;
|
||||
};
|
||||
SDL_Rect UpdateRect;
|
||||
|
||||
bool UsingRenderer;
|
||||
bool NeedPalUpdate;
|
||||
bool NeedGammaUpdate;
|
||||
bool NotPaletted;
|
||||
|
||||
void UpdateColors ();
|
||||
void ResetSDLRenderer ();
|
||||
|
||||
SDLFB () {}
|
||||
};
|
||||
|
@ -83,9 +94,6 @@ struct MiniModeInfo
|
|||
extern IVideo *Video;
|
||||
extern bool GUICapture;
|
||||
|
||||
SDL_Surface *cursorSurface = NULL;
|
||||
SDL_Rect cursorBlit = {0, 0, 32, 32};
|
||||
|
||||
EXTERN_CVAR (Float, Gamma)
|
||||
EXTERN_CVAR (Int, vid_maxfps)
|
||||
EXTERN_CVAR (Bool, cl_capfps)
|
||||
|
@ -93,11 +101,11 @@ EXTERN_CVAR (Bool, vid_vsync)
|
|||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
CVAR (Int, vid_displaybits, 8, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
// vid_asyncblit needs a restart to work. SDL doesn't seem to change if the
|
||||
// frame buffer is changed at run time.
|
||||
CVAR (Bool, vid_asyncblit, 1, CVAR_NOINITCALL|CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR (Int, vid_displaybits, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
CVAR (Bool, vid_forcesurface, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
CUSTOM_CVAR (Float, rgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
|
@ -140,12 +148,14 @@ static MiniModeInfo WinModes[] =
|
|||
{ 720, 480 }, // 16:10
|
||||
{ 720, 540 },
|
||||
{ 800, 450 }, // 16:9
|
||||
{ 800, 480 },
|
||||
{ 800, 500 }, // 16:10
|
||||
{ 800, 600 },
|
||||
{ 848, 480 }, // 16:9
|
||||
{ 960, 600 }, // 16:10
|
||||
{ 960, 720 },
|
||||
{ 1024, 576 }, // 16:9
|
||||
{ 1024, 600 }, // 17:10
|
||||
{ 1024, 640 }, // 16:10
|
||||
{ 1024, 768 },
|
||||
{ 1088, 612 }, // 16:9
|
||||
|
@ -153,16 +163,33 @@ static MiniModeInfo WinModes[] =
|
|||
{ 1152, 720 }, // 16:10
|
||||
{ 1152, 864 },
|
||||
{ 1280, 720 }, // 16:9
|
||||
{ 1280, 854 },
|
||||
{ 1280, 800 }, // 16:10
|
||||
{ 1280, 960 },
|
||||
{ 1280, 1024 }, // 5:4
|
||||
{ 1360, 768 }, // 16:9
|
||||
{ 1366, 768 },
|
||||
{ 1400, 787 }, // 16:9
|
||||
{ 1400, 875 }, // 16:10
|
||||
{ 1400, 1050 },
|
||||
{ 1440, 900 },
|
||||
{ 1440, 960 },
|
||||
{ 1440, 1080 },
|
||||
{ 1600, 900 }, // 16:9
|
||||
{ 1600, 1000 }, // 16:10
|
||||
{ 1600, 1200 },
|
||||
{ 1920, 1080 },
|
||||
{ 1920, 1200 },
|
||||
{ 2048, 1536 },
|
||||
{ 2560, 1440 },
|
||||
{ 2560, 1600 },
|
||||
{ 2560, 2048 },
|
||||
{ 2880, 1800 },
|
||||
{ 3200, 1800 },
|
||||
{ 3840, 2160 },
|
||||
{ 3840, 2400 },
|
||||
{ 4096, 2160 },
|
||||
{ 5120, 2880 }
|
||||
};
|
||||
|
||||
static cycle_t BlitCycles;
|
||||
|
@ -170,10 +197,34 @@ static cycle_t SDLFlipCycles;
|
|||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
void ScaleWithAspect (int &w, int &h, int Width, int Height)
|
||||
{
|
||||
int resRatio = CheckRatio (Width, Height);
|
||||
int screenRatio;
|
||||
CheckRatio (w, h, &screenRatio);
|
||||
if (resRatio == screenRatio)
|
||||
return;
|
||||
|
||||
double yratio;
|
||||
switch(resRatio)
|
||||
{
|
||||
case 0: yratio = 4./3.; break;
|
||||
case 1: yratio = 16./9.; break;
|
||||
case 2: yratio = 16./10.; break;
|
||||
case 3: yratio = 17./10.; break;
|
||||
case 4: yratio = 5./4.; break;
|
||||
default: return;
|
||||
}
|
||||
double y = w/yratio;
|
||||
if (y > h)
|
||||
w = h*yratio;
|
||||
else
|
||||
h = y;
|
||||
}
|
||||
|
||||
SDLVideo::SDLVideo (int parm)
|
||||
{
|
||||
IteratorBits = 0;
|
||||
IteratorFS = false;
|
||||
}
|
||||
|
||||
SDLVideo::~SDLVideo ()
|
||||
|
@ -184,7 +235,6 @@ void SDLVideo::StartModeIterator (int bits, bool fs)
|
|||
{
|
||||
IteratorMode = 0;
|
||||
IteratorBits = bits;
|
||||
IteratorFS = fs;
|
||||
}
|
||||
|
||||
bool SDLVideo::NextMode (int *width, int *height, bool *letterbox)
|
||||
|
@ -192,8 +242,6 @@ bool SDLVideo::NextMode (int *width, int *height, bool *letterbox)
|
|||
if (IteratorBits != 8)
|
||||
return false;
|
||||
|
||||
if (!IteratorFS)
|
||||
{
|
||||
if ((unsigned)IteratorMode < sizeof(WinModes)/sizeof(WinModes[0]))
|
||||
{
|
||||
*width = WinModes[IteratorMode].Width;
|
||||
|
@ -201,18 +249,6 @@ bool SDLVideo::NextMode (int *width, int *height, bool *letterbox)
|
|||
++IteratorMode;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_Rect **modes = SDL_ListModes (NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
|
||||
if (modes != NULL && modes[IteratorMode] != NULL)
|
||||
{
|
||||
*width = modes[IteratorMode]->w;
|
||||
*height = modes[IteratorMode]->h;
|
||||
++IteratorMode;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -230,11 +266,11 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree
|
|||
if (fb->Width == width &&
|
||||
fb->Height == height)
|
||||
{
|
||||
bool fsnow = (fb->Screen->flags & SDL_FULLSCREEN) != 0;
|
||||
bool fsnow = (SDL_GetWindowFlags (fb->Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
|
||||
|
||||
if (fsnow != fullscreen)
|
||||
{
|
||||
SDL_WM_ToggleFullScreen (fb->Screen);
|
||||
fb->SetFullscreen (fullscreen);
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
@ -250,7 +286,6 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree
|
|||
}
|
||||
|
||||
SDLFB *fb = new SDLFB (width, height, fullscreen);
|
||||
retry = 0;
|
||||
|
||||
// If we could not create the framebuffer, try again with slightly
|
||||
// different parameters in this order:
|
||||
|
@ -291,6 +326,7 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree
|
|||
++retry;
|
||||
fb = static_cast<SDLFB *>(CreateFrameBuffer (width, height, fullscreen, NULL));
|
||||
}
|
||||
retry = 0;
|
||||
|
||||
fb->SetFlash (flashColor, flashAmount);
|
||||
|
||||
|
@ -313,32 +349,48 @@ SDLFB::SDLFB (int width, int height, bool fullscreen)
|
|||
UpdatePending = false;
|
||||
NotPaletted = false;
|
||||
FlashAmount = 0;
|
||||
Screen = SDL_SetVideoMode (width, height, vid_displaybits,
|
||||
(vid_asyncblit ? SDL_ASYNCBLIT : 0)|SDL_HWSURFACE|SDL_HWPALETTE|SDL_DOUBLEBUF|SDL_ANYFORMAT|
|
||||
(fullscreen ? SDL_FULLSCREEN : 0));
|
||||
|
||||
FString caption;
|
||||
caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime());
|
||||
|
||||
Screen = SDL_CreateWindow (caption,
|
||||
SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter),
|
||||
width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0));
|
||||
|
||||
if (Screen == NULL)
|
||||
return;
|
||||
|
||||
Renderer = NULL;
|
||||
Texture = NULL;
|
||||
ResetSDLRenderer ();
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
GammaTable[0][i] = GammaTable[1][i] = GammaTable[2][i] = i;
|
||||
}
|
||||
if (Screen->format->palette == NULL)
|
||||
{
|
||||
NotPaletted = true;
|
||||
GPfx.SetFormat (Screen->format->BitsPerPixel,
|
||||
Screen->format->Rmask,
|
||||
Screen->format->Gmask,
|
||||
Screen->format->Bmask);
|
||||
}
|
||||
|
||||
memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256);
|
||||
UpdateColors ();
|
||||
|
||||
#ifdef __APPLE__
|
||||
SetVSync (vid_vsync);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
SDLFB::~SDLFB ()
|
||||
{
|
||||
if(Screen)
|
||||
{
|
||||
if (Renderer)
|
||||
{
|
||||
if (Texture)
|
||||
SDL_DestroyTexture (Texture);
|
||||
SDL_DestroyRenderer (Renderer);
|
||||
}
|
||||
|
||||
SDL_DestroyWindow (Screen);
|
||||
}
|
||||
}
|
||||
|
||||
bool SDLFB::IsValid ()
|
||||
|
@ -403,41 +455,60 @@ void SDLFB::Update ()
|
|||
SDLFlipCycles.Reset();
|
||||
BlitCycles.Clock();
|
||||
|
||||
if (SDL_LockSurface (Screen) == -1)
|
||||
void *pixels;
|
||||
int pitch;
|
||||
if (UsingRenderer)
|
||||
{
|
||||
if (SDL_LockTexture (Texture, NULL, &pixels, &pitch))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SDL_LockSurface (Surface))
|
||||
return;
|
||||
|
||||
pixels = Surface->pixels;
|
||||
pitch = Surface->pitch;
|
||||
}
|
||||
|
||||
if (NotPaletted)
|
||||
{
|
||||
GPfx.Convert (MemBuffer, Pitch,
|
||||
Screen->pixels, Screen->pitch, Width, Height,
|
||||
pixels, pitch, Width, Height,
|
||||
FRACUNIT, FRACUNIT, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Screen->pitch == Pitch)
|
||||
if (pitch == Pitch)
|
||||
{
|
||||
memcpy (Screen->pixels, MemBuffer, Width*Height);
|
||||
memcpy (pixels, MemBuffer, Width*Height);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int y = 0; y < Height; ++y)
|
||||
{
|
||||
memcpy ((BYTE *)Screen->pixels+y*Screen->pitch, MemBuffer+y*Pitch, Width);
|
||||
memcpy ((BYTE *)pixels+y*pitch, MemBuffer+y*Pitch, Width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockSurface (Screen);
|
||||
|
||||
if (cursorSurface != NULL && GUICapture)
|
||||
if (UsingRenderer)
|
||||
{
|
||||
// SDL requires us to draw a surface to get true color cursors.
|
||||
SDL_BlitSurface(cursorSurface, NULL, Screen, &cursorBlit);
|
||||
}
|
||||
SDL_UnlockTexture (Texture);
|
||||
|
||||
SDLFlipCycles.Clock();
|
||||
SDL_Flip (Screen);
|
||||
SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect);
|
||||
SDL_RenderPresent(Renderer);
|
||||
SDLFlipCycles.Unclock();
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_UnlockSurface (Surface);
|
||||
|
||||
SDLFlipCycles.Clock();
|
||||
SDL_UpdateWindowSurface (Screen);
|
||||
SDLFlipCycles.Unclock();
|
||||
}
|
||||
|
||||
BlitCycles.Unclock();
|
||||
|
||||
|
@ -494,7 +565,7 @@ void SDLFB::UpdateColors ()
|
|||
256, GammaTable[2][Flash.b], GammaTable[1][Flash.g], GammaTable[0][Flash.r],
|
||||
FlashAmount);
|
||||
}
|
||||
SDL_SetPalette (Screen, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, 256);
|
||||
SDL_SetPaletteColors (Surface->format->palette, colors, 0, 256);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -539,9 +610,95 @@ void SDLFB::GetFlashedPalette (PalEntry pal[256])
|
|||
}
|
||||
}
|
||||
|
||||
void SDLFB::SetFullscreen (bool fullscreen)
|
||||
{
|
||||
SDL_SetWindowFullscreen (Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||
if (!fullscreen)
|
||||
{
|
||||
// Restore proper window size
|
||||
SDL_SetWindowSize (Screen, Width, Height);
|
||||
}
|
||||
|
||||
ResetSDLRenderer ();
|
||||
}
|
||||
|
||||
bool SDLFB::IsFullscreen ()
|
||||
{
|
||||
return (Screen->flags & SDL_FULLSCREEN) != 0;
|
||||
return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
|
||||
}
|
||||
|
||||
void SDLFB::ResetSDLRenderer ()
|
||||
{
|
||||
if (Renderer)
|
||||
{
|
||||
if (Texture)
|
||||
SDL_DestroyTexture (Texture);
|
||||
SDL_DestroyRenderer (Renderer);
|
||||
}
|
||||
|
||||
UsingRenderer = !vid_forcesurface;
|
||||
if (UsingRenderer)
|
||||
{
|
||||
Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE|
|
||||
(vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0));
|
||||
if (!Renderer)
|
||||
return;
|
||||
|
||||
Uint32 fmt;
|
||||
switch(vid_displaybits)
|
||||
{
|
||||
default: fmt = SDL_PIXELFORMAT_ARGB8888; break;
|
||||
case 30: fmt = SDL_PIXELFORMAT_ARGB2101010; break;
|
||||
case 24: fmt = SDL_PIXELFORMAT_RGB888; break;
|
||||
case 16: fmt = SDL_PIXELFORMAT_RGB565; break;
|
||||
case 15: fmt = SDL_PIXELFORMAT_ARGB1555; break;
|
||||
}
|
||||
Texture = SDL_CreateTexture (Renderer, fmt, SDL_TEXTUREACCESS_STREAMING, Width, Height);
|
||||
|
||||
{
|
||||
NotPaletted = true;
|
||||
|
||||
Uint32 format;
|
||||
SDL_QueryTexture(Texture, &format, NULL, NULL, NULL);
|
||||
|
||||
Uint32 Rmask, Gmask, Bmask, Amask;
|
||||
int bpp;
|
||||
SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
|
||||
GPfx.SetFormat (bpp, Rmask, Gmask, Bmask);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Surface = SDL_GetWindowSurface (Screen);
|
||||
|
||||
if (Surface->format->palette == NULL)
|
||||
{
|
||||
NotPaletted = true;
|
||||
GPfx.SetFormat (Surface->format->BitsPerPixel, Surface->format->Rmask, Surface->format->Gmask, Surface->format->Bmask);
|
||||
}
|
||||
else
|
||||
NotPaletted = false;
|
||||
}
|
||||
|
||||
// Calculate update rectangle
|
||||
if (IsFullscreen ())
|
||||
{
|
||||
int w, h;
|
||||
SDL_GetWindowSize (Screen, &w, &h);
|
||||
UpdateRect.w = w;
|
||||
UpdateRect.h = h;
|
||||
ScaleWithAspect (UpdateRect.w, UpdateRect.h, Width, Height);
|
||||
UpdateRect.x = (w - UpdateRect.w)/2;
|
||||
UpdateRect.y = (h - UpdateRect.h)/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In windowed mode we just update the whole window.
|
||||
UpdateRect.x = 0;
|
||||
UpdateRect.y = 0;
|
||||
UpdateRect.w = Width;
|
||||
UpdateRect.h = Height;
|
||||
}
|
||||
}
|
||||
|
||||
void SDLFB::SetVSync (bool vsync)
|
||||
|
@ -561,6 +718,8 @@ void SDLFB::SetVSync (bool vsync)
|
|||
const GLint value = vsync ? 1 : 0;
|
||||
CGLSetParameter(context, kCGLCPSwapInterval, &value);
|
||||
}
|
||||
#else
|
||||
ResetSDLRenderer ();
|
||||
#endif // __APPLE__
|
||||
}
|
||||
|
||||
|
@ -568,6 +727,6 @@ ADD_STAT (blit)
|
|||
{
|
||||
FString out;
|
||||
out.Format ("blit=%04.1f ms flip=%04.1f ms",
|
||||
BlitCycles.Time() * 1e-3, SDLFlipCycles.TimeMS());
|
||||
BlitCycles.TimeMS(), SDLFlipCycles.TimeMS());
|
||||
return out;
|
||||
}
|
|
@ -18,5 +18,4 @@ class SDLVideo : public IVideo
|
|||
private:
|
||||
int IteratorMode;
|
||||
int IteratorBits;
|
||||
bool IteratorFS;
|
||||
};
|
|
@ -150,11 +150,28 @@ void FResourceLump::LumpNameSetup(const char *iname)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static bool IsWadInFolder(const FResourceFile* const archive, const char* const resPath)
|
||||
{
|
||||
// Checks a special case when <somefile.wad> was put in
|
||||
// <myproject> directory inside <myproject.zip>
|
||||
|
||||
if (NULL == archive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const FString dirName = ExtractFileBase(archive->Filename);
|
||||
const FString fileName = ExtractFileBase(resPath, true);
|
||||
const FString filePath = dirName + '/' + fileName;
|
||||
|
||||
return 0 == filePath.CompareNoCase(resPath);
|
||||
}
|
||||
|
||||
void FResourceLump::CheckEmbedded()
|
||||
{
|
||||
// Checks for embedded archives
|
||||
const char *c = strstr(FullName, ".wad");
|
||||
if (c && strlen(c) == 4 && !strchr(FullName, '/'))
|
||||
if (c && strlen(c) == 4 && (!strchr(FullName, '/') || IsWadInFolder(Owner, FullName)))
|
||||
{
|
||||
// Mark all embedded WADs
|
||||
Flags |= LUMPF_EMBEDDED;
|
||||
|
|
|
@ -185,7 +185,7 @@ std2:
|
|||
'random' { RET(TK_Random); }
|
||||
'random2' { RET(TK_Random2); }
|
||||
'frandom' { RET(TK_FRandom); }
|
||||
'pick' { RET(TK_Pick); }
|
||||
'randompick' { RET(TK_RandomPick); }
|
||||
|
||||
L (L|D)* { RET(TK_Identifier); }
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ xx(TK_Array, "'array'")
|
|||
xx(TK_In, "'in'")
|
||||
xx(TK_SizeOf, "'sizeof'")
|
||||
xx(TK_AlignOf, "'alignof'")
|
||||
xx(TK_RandomPick, "'randompick'")
|
||||
xx(TK_States, "'states'")
|
||||
xx(TK_Loop, "'loop'")
|
||||
xx(TK_Fail, "'fail'")
|
||||
|
|
|
@ -1,387 +0,0 @@
|
|||
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
|
||||
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
|
||||
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
|
||||
|
||||
Feel free to customize this file to suit your needs
|
||||
*/
|
||||
|
||||
#import "SDL.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <sys/param.h> /* for MAXPATHLEN */
|
||||
#import <unistd.h>
|
||||
|
||||
@interface SDLMain : NSObject
|
||||
@end
|
||||
|
||||
/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
|
||||
but the method still is there and works. To avoid warnings, we declare
|
||||
it ourselves here. */
|
||||
@interface NSApplication(SDL_Missing_Methods)
|
||||
- (void)setAppleMenu:(NSMenu *)menu;
|
||||
@end
|
||||
|
||||
/* Use this flag to determine whether we use SDLMain.nib or not */
|
||||
#define SDL_USE_NIB_FILE 0
|
||||
|
||||
/* Use this flag to determine whether we use CPS (docking) or not */
|
||||
#define SDL_USE_CPS 1
|
||||
#ifdef SDL_USE_CPS
|
||||
/* Portions of CPS.h */
|
||||
typedef struct CPSProcessSerNum
|
||||
{
|
||||
UInt32 lo;
|
||||
UInt32 hi;
|
||||
} CPSProcessSerNum;
|
||||
|
||||
extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
|
||||
extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
|
||||
extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
|
||||
|
||||
#endif /* SDL_USE_CPS */
|
||||
|
||||
static int gArgc;
|
||||
static char **gArgv;
|
||||
static BOOL gFinderLaunch;
|
||||
static BOOL gCalledAppMainline = FALSE;
|
||||
|
||||
static NSString *getApplicationName(void)
|
||||
{
|
||||
NSDictionary *dict;
|
||||
NSString *appName = 0;
|
||||
|
||||
/* Determine the application name */
|
||||
dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
|
||||
if (dict)
|
||||
appName = [dict objectForKey: @"CFBundleName"];
|
||||
|
||||
if (![appName length])
|
||||
appName = [[NSProcessInfo processInfo] processName];
|
||||
|
||||
return appName;
|
||||
}
|
||||
|
||||
#if SDL_USE_NIB_FILE
|
||||
/* A helper category for NSString */
|
||||
@interface NSString (ReplaceSubString)
|
||||
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
|
||||
@end
|
||||
#endif
|
||||
|
||||
@interface SDLApplication : NSApplication
|
||||
@end
|
||||
|
||||
@implementation SDLApplication
|
||||
/* Invoked from the Quit menu item */
|
||||
- (void)terminate:(id)sender
|
||||
{
|
||||
/* Post a SDL_QUIT event */
|
||||
SDL_Event event;
|
||||
event.type = SDL_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
@end
|
||||
|
||||
/* The main class of the application, the application's delegate */
|
||||
@implementation SDLMain
|
||||
|
||||
/* Set the working directory to the .app's parent directory */
|
||||
- (void) setupWorkingDirectory:(BOOL)shouldChdir
|
||||
{
|
||||
if (shouldChdir)
|
||||
{
|
||||
char parentdir[MAXPATHLEN];
|
||||
CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
|
||||
CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
|
||||
if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) {
|
||||
assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
|
||||
}
|
||||
CFRelease(url);
|
||||
CFRelease(url2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if SDL_USE_NIB_FILE
|
||||
|
||||
/* Fix menu to contain the real app name instead of "SDL App" */
|
||||
- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
|
||||
{
|
||||
NSRange aRange;
|
||||
NSEnumerator *enumerator;
|
||||
NSMenuItem *menuItem;
|
||||
|
||||
aRange = [[aMenu title] rangeOfString:@"SDL App"];
|
||||
if (aRange.length != 0)
|
||||
[aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
|
||||
|
||||
enumerator = [[aMenu itemArray] objectEnumerator];
|
||||
while ((menuItem = [enumerator nextObject]))
|
||||
{
|
||||
aRange = [[menuItem title] rangeOfString:@"SDL App"];
|
||||
if (aRange.length != 0)
|
||||
[menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
|
||||
if ([menuItem hasSubmenu])
|
||||
[self fixMenu:[menuItem submenu] withAppName:appName];
|
||||
}
|
||||
[ aMenu sizeToFit ];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void setApplicationMenu(void)
|
||||
{
|
||||
/* warning: this code is very odd */
|
||||
NSMenu *appleMenu;
|
||||
NSMenuItem *menuItem;
|
||||
NSString *title;
|
||||
NSString *appName;
|
||||
|
||||
appName = getApplicationName();
|
||||
appleMenu = [[NSMenu alloc] initWithTitle:@""];
|
||||
|
||||
/* Add menu items */
|
||||
title = [@"About " stringByAppendingString:appName];
|
||||
[appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
|
||||
|
||||
[appleMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
title = [@"Hide " stringByAppendingString:appName];
|
||||
[appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
|
||||
|
||||
menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
|
||||
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
|
||||
|
||||
[appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
|
||||
|
||||
[appleMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
title = [@"Quit " stringByAppendingString:appName];
|
||||
[appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
|
||||
|
||||
|
||||
/* Put menu into the menubar */
|
||||
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
|
||||
[menuItem setSubmenu:appleMenu];
|
||||
[[NSApp mainMenu] addItem:menuItem];
|
||||
|
||||
/* Tell the application object that this is now the application menu */
|
||||
[NSApp setAppleMenu:appleMenu];
|
||||
|
||||
/* Finally give up our references to the objects */
|
||||
[appleMenu release];
|
||||
[menuItem release];
|
||||
}
|
||||
|
||||
/* Create a window menu */
|
||||
static void setupWindowMenu(void)
|
||||
{
|
||||
NSMenu *windowMenu;
|
||||
NSMenuItem *windowMenuItem;
|
||||
NSMenuItem *menuItem;
|
||||
|
||||
windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
|
||||
|
||||
/* "Minimize" item */
|
||||
menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
|
||||
[windowMenu addItem:menuItem];
|
||||
[menuItem release];
|
||||
|
||||
/* Put menu into the menubar */
|
||||
windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
|
||||
[windowMenuItem setSubmenu:windowMenu];
|
||||
[[NSApp mainMenu] addItem:windowMenuItem];
|
||||
|
||||
/* Tell the application object that this is now the window menu */
|
||||
[NSApp setWindowsMenu:windowMenu];
|
||||
|
||||
/* Finally give up our references to the objects */
|
||||
[windowMenu release];
|
||||
[windowMenuItem release];
|
||||
}
|
||||
|
||||
/* Replacement for NSApplicationMain */
|
||||
static void CustomApplicationMain (int argc, char **argv)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
SDLMain *sdlMain;
|
||||
|
||||
/* Ensure the application object is initialised */
|
||||
[SDLApplication sharedApplication];
|
||||
|
||||
#ifdef SDL_USE_CPS
|
||||
{
|
||||
CPSProcessSerNum PSN;
|
||||
/* Tell the dock about us */
|
||||
if (!CPSGetCurrentProcess(&PSN))
|
||||
if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
|
||||
if (!CPSSetFrontProcess(&PSN))
|
||||
[SDLApplication sharedApplication];
|
||||
}
|
||||
#endif /* SDL_USE_CPS */
|
||||
|
||||
/* Set up the menubar */
|
||||
[NSApp setMainMenu:[[NSMenu alloc] init]];
|
||||
setApplicationMenu();
|
||||
setupWindowMenu();
|
||||
|
||||
/* Create SDLMain and make it the app delegate */
|
||||
sdlMain = [[SDLMain alloc] init];
|
||||
[NSApp setDelegate:sdlMain];
|
||||
|
||||
/* Start the main event loop */
|
||||
[NSApp run];
|
||||
|
||||
[sdlMain release];
|
||||
[pool release];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Catch document open requests...this lets us notice files when the app
|
||||
* was launched by double-clicking a document, or when a document was
|
||||
* dragged/dropped on the app's icon. You need to have a
|
||||
* CFBundleDocumentsType section in your Info.plist to get this message,
|
||||
* apparently.
|
||||
*
|
||||
* Files are added to gArgv, so to the app, they'll look like command line
|
||||
* arguments. Previously, apps launched from the finder had nothing but
|
||||
* an argv[0].
|
||||
*
|
||||
* This message may be received multiple times to open several docs on launch.
|
||||
*
|
||||
* This message is ignored once the app's mainline has been called.
|
||||
*/
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
|
||||
{
|
||||
const char *temparg;
|
||||
size_t arglen;
|
||||
char *arg;
|
||||
char **newargv;
|
||||
|
||||
if (!gFinderLaunch) /* MacOS is passing command line args. */
|
||||
return FALSE;
|
||||
|
||||
if (gCalledAppMainline) /* app has started, ignore this document. */
|
||||
return FALSE;
|
||||
|
||||
temparg = [filename UTF8String];
|
||||
arglen = SDL_strlen(temparg) + 1;
|
||||
arg = (char *) SDL_malloc(arglen);
|
||||
if (arg == NULL)
|
||||
return FALSE;
|
||||
|
||||
newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
|
||||
if (newargv == NULL)
|
||||
{
|
||||
SDL_free(arg);
|
||||
return FALSE;
|
||||
}
|
||||
gArgv = newargv;
|
||||
|
||||
SDL_strlcpy(arg, temparg, arglen);
|
||||
gArgv[gArgc++] = arg;
|
||||
gArgv[gArgc] = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Called when the internal event loop has just started running */
|
||||
- (void) applicationDidFinishLaunching: (NSNotification *) note
|
||||
{
|
||||
int status;
|
||||
|
||||
/* Set the working directory to the .app's parent directory */
|
||||
[self setupWorkingDirectory:gFinderLaunch];
|
||||
|
||||
#if SDL_USE_NIB_FILE
|
||||
/* Set the main menu to contain the real app name instead of "SDL App" */
|
||||
[self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
|
||||
#endif
|
||||
|
||||
/* Hand off to main application code */
|
||||
gCalledAppMainline = TRUE;
|
||||
status = SDL_main (gArgc, gArgv);
|
||||
|
||||
/* We're done, thank you for playing */
|
||||
exit(status);
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSString (ReplaceSubString)
|
||||
|
||||
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
|
||||
{
|
||||
unsigned int bufferSize;
|
||||
unsigned int selfLen = [self length];
|
||||
unsigned int aStringLen = [aString length];
|
||||
unichar *buffer;
|
||||
NSRange localRange;
|
||||
NSString *result;
|
||||
|
||||
bufferSize = selfLen + aStringLen - aRange.length;
|
||||
buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
|
||||
|
||||
/* Get first part into buffer */
|
||||
localRange.location = 0;
|
||||
localRange.length = aRange.location;
|
||||
[self getCharacters:buffer range:localRange];
|
||||
|
||||
/* Get middle part into buffer */
|
||||
localRange.location = 0;
|
||||
localRange.length = aStringLen;
|
||||
[aString getCharacters:(buffer+aRange.location) range:localRange];
|
||||
|
||||
/* Get last part into buffer */
|
||||
localRange.location = aRange.location + aRange.length;
|
||||
localRange.length = selfLen - localRange.location;
|
||||
[self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
|
||||
|
||||
/* Build output string */
|
||||
result = [NSString stringWithCharacters:buffer length:bufferSize];
|
||||
|
||||
NSDeallocateMemoryPages(buffer, bufferSize);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
#ifdef main
|
||||
# undef main
|
||||
#endif
|
||||
|
||||
|
||||
/* Main entry point to executable - should *not* be SDL_main! */
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* Copy the arguments into a global variable */
|
||||
/* This is passed if we are launched by double-clicking */
|
||||
if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
|
||||
gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
|
||||
gArgv[0] = argv[0];
|
||||
gArgv[1] = NULL;
|
||||
gArgc = 1;
|
||||
gFinderLaunch = YES;
|
||||
} else {
|
||||
int i;
|
||||
gArgc = argc;
|
||||
gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
|
||||
for (i = 0; i <= argc; i++)
|
||||
gArgv[i] = argv[i];
|
||||
gFinderLaunch = NO;
|
||||
}
|
||||
|
||||
#if SDL_USE_NIB_FILE
|
||||
[SDLApplication poseAsClass:[NSApplication class]];
|
||||
NSApplicationMain (argc, argv);
|
||||
#else
|
||||
CustomApplicationMain (argc, argv);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
|
||||
// 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";
|
||||
}
|
|
@ -1,505 +0,0 @@
|
|||
#include <SDL.h>
|
||||
#include <ctype.h>
|
||||
#include "doomtype.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "m_argv.h"
|
||||
#include "i_input.h"
|
||||
#include "v_video.h"
|
||||
|
||||
#include "d_main.h"
|
||||
#include "d_event.h"
|
||||
#include "d_gui.h"
|
||||
#include "c_console.h"
|
||||
#include "c_cvars.h"
|
||||
#include "i_system.h"
|
||||
#include "dikeys.h"
|
||||
#include "templates.h"
|
||||
#include "s_sound.h"
|
||||
|
||||
static void I_CheckGUICapture ();
|
||||
static void I_CheckNativeMouse ();
|
||||
|
||||
bool GUICapture;
|
||||
static bool NativeMouse = true;
|
||||
|
||||
extern int paused;
|
||||
|
||||
CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR (Bool, sdl_nokeyrepeat, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
EXTERN_CVAR (Bool, fullscreen)
|
||||
|
||||
extern int WaitingForKey, chatmodeon;
|
||||
extern constate_e ConsoleState;
|
||||
|
||||
extern SDL_Surface *cursorSurface;
|
||||
extern SDL_Rect cursorBlit;
|
||||
|
||||
static BYTE KeySymToDIK[SDLK_LAST], DownState[SDLK_LAST];
|
||||
|
||||
static WORD DIKToKeySym[256] =
|
||||
{
|
||||
0, SDLK_ESCAPE, '1', '2', '3', '4', '5', '6',
|
||||
'7', '8', '9', '0', '-', '=', SDLK_BACKSPACE, SDLK_TAB,
|
||||
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
|
||||
'o', 'p', '[', ']', SDLK_RETURN, SDLK_LCTRL, 'a', 's',
|
||||
'd', 'f', 'g', 'h', 'j', 'k', 'l', SDLK_SEMICOLON,
|
||||
'\'', '`', SDLK_LSHIFT, '\\', 'z', 'x', 'c', 'v',
|
||||
'b', 'n', 'm', ',', '.', '/', SDLK_RSHIFT, SDLK_KP_MULTIPLY,
|
||||
SDLK_LALT, ' ', SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5,
|
||||
SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCK, SDLK_SCROLLOCK, SDLK_KP7,
|
||||
SDLK_KP8, SDLK_KP9, SDLK_KP_MINUS, SDLK_KP4, SDLK_KP5, SDLK_KP6, SDLK_KP_PLUS, SDLK_KP1,
|
||||
SDLK_KP2, SDLK_KP3, SDLK_KP0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11,
|
||||
SDLK_F12, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, SDLK_F13, SDLK_F14, SDLK_F15, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, SDLK_KP_EQUALS, 0, 0,
|
||||
0, SDLK_AT, SDLK_COLON, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, SDLK_KP_ENTER, SDLK_RCTRL, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, SDLK_KP_DIVIDE, 0, SDLK_SYSREQ,
|
||||
SDLK_RALT, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, SDLK_PAUSE, 0, SDLK_HOME,
|
||||
SDLK_UP, SDLK_PAGEUP, 0, SDLK_LEFT, 0, SDLK_RIGHT, 0, SDLK_END,
|
||||
SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, 0, 0, 0, 0,
|
||||
0, 0, 0, SDLK_LSUPER, SDLK_RSUPER, SDLK_MENU, SDLK_POWER, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static void FlushDIKState (int low=0, int high=NUM_KEYS-1)
|
||||
{
|
||||
}
|
||||
|
||||
static void InitKeySymMap ()
|
||||
{
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
KeySymToDIK[DIKToKeySym[i]] = i;
|
||||
}
|
||||
KeySymToDIK[0] = 0;
|
||||
KeySymToDIK[SDLK_RSHIFT] = DIK_LSHIFT;
|
||||
KeySymToDIK[SDLK_RCTRL] = DIK_LCONTROL;
|
||||
KeySymToDIK[SDLK_RALT] = DIK_LMENU;
|
||||
// Depending on your Linux flavor, you may get SDLK_PRINT or SDLK_SYSREQ
|
||||
KeySymToDIK[SDLK_PRINT] = DIK_SYSRQ;
|
||||
}
|
||||
|
||||
static void I_CheckGUICapture ()
|
||||
{
|
||||
bool wantCapt;
|
||||
bool repeat;
|
||||
int oldrepeat, interval;
|
||||
|
||||
SDL_GetKeyRepeat(&oldrepeat, &interval);
|
||||
|
||||
if (menuactive == MENU_Off)
|
||||
{
|
||||
wantCapt = ConsoleState == c_down || ConsoleState == c_falling || chatmodeon;
|
||||
}
|
||||
else
|
||||
{
|
||||
wantCapt = (menuactive == MENU_On || menuactive == MENU_OnNoPause);
|
||||
}
|
||||
|
||||
if (wantCapt != GUICapture)
|
||||
{
|
||||
GUICapture = wantCapt;
|
||||
if (wantCapt)
|
||||
{
|
||||
int x, y;
|
||||
SDL_GetMouseState (&x, &y);
|
||||
cursorBlit.x = x;
|
||||
cursorBlit.y = y;
|
||||
|
||||
FlushDIKState ();
|
||||
memset (DownState, 0, sizeof(DownState));
|
||||
repeat = !sdl_nokeyrepeat;
|
||||
SDL_EnableUNICODE (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
repeat = false;
|
||||
SDL_EnableUNICODE (0);
|
||||
}
|
||||
}
|
||||
if (wantCapt)
|
||||
{
|
||||
repeat = !sdl_nokeyrepeat;
|
||||
}
|
||||
else
|
||||
{
|
||||
repeat = false;
|
||||
}
|
||||
if (repeat != (oldrepeat != 0))
|
||||
{
|
||||
if (repeat)
|
||||
{
|
||||
SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_EnableKeyRepeat (0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void I_SetMouseCapture()
|
||||
{
|
||||
}
|
||||
|
||||
void I_ReleaseMouseCapture()
|
||||
{
|
||||
}
|
||||
|
||||
static void CenterMouse ()
|
||||
{
|
||||
SDL_WarpMouse (screen->GetWidth()/2, screen->GetHeight()/2);
|
||||
SDL_PumpEvents ();
|
||||
SDL_GetRelativeMouseState (NULL, NULL);
|
||||
}
|
||||
|
||||
static void PostMouseMove (int x, int y)
|
||||
{
|
||||
static int lastx = 0, lasty = 0;
|
||||
event_t ev = { 0,0,0,0,0,0,0 };
|
||||
|
||||
if (m_filter)
|
||||
{
|
||||
ev.x = (x + lastx) / 2;
|
||||
ev.y = (y + lasty) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ev.x = x;
|
||||
ev.y = y;
|
||||
}
|
||||
lastx = x;
|
||||
lasty = y;
|
||||
if (ev.x | ev.y)
|
||||
{
|
||||
ev.type = EV_Mouse;
|
||||
D_PostEvent (&ev);
|
||||
}
|
||||
}
|
||||
|
||||
static void MouseRead ()
|
||||
{
|
||||
int x, y;
|
||||
|
||||
if (NativeMouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_GetRelativeMouseState (&x, &y);
|
||||
if (!m_noprescale)
|
||||
{
|
||||
x *= 3;
|
||||
y *= 2;
|
||||
}
|
||||
if (x | y)
|
||||
{
|
||||
CenterMouse ();
|
||||
PostMouseMove (x, -y);
|
||||
}
|
||||
}
|
||||
|
||||
static void WheelMoved(event_t *event)
|
||||
{
|
||||
if (GUICapture)
|
||||
{
|
||||
if (event->type != EV_KeyUp)
|
||||
{
|
||||
SDLMod mod = SDL_GetModState();
|
||||
event->type = EV_GUI_Event;
|
||||
event->subtype = event->data1 == KEY_MWHEELUP ? EV_GUI_WheelUp : EV_GUI_WheelDown;
|
||||
event->data1 = 0;
|
||||
event->data3 = ((mod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
|
||||
((mod & KMOD_CTRL) ? GKM_CTRL : 0) |
|
||||
((mod & KMOD_ALT) ? GKM_ALT : 0);
|
||||
D_PostEvent(event);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
D_PostEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, mouse_capturemode, 1, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
|
||||
{
|
||||
if (self < 0) self = 0;
|
||||
else if (self > 2) self = 2;
|
||||
}
|
||||
|
||||
static bool inGame()
|
||||
{
|
||||
switch (mouse_capturemode)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
return gamestate == GS_LEVEL;
|
||||
case 1:
|
||||
return gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_FINALE;
|
||||
case 2:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static void I_CheckNativeMouse ()
|
||||
{
|
||||
bool focus = (SDL_GetAppState() & (SDL_APPINPUTFOCUS|SDL_APPACTIVE))
|
||||
== (SDL_APPINPUTFOCUS|SDL_APPACTIVE);
|
||||
bool fs = (SDL_GetVideoSurface ()->flags & SDL_FULLSCREEN) != 0;
|
||||
|
||||
bool wantNative = !focus || (!use_mouse || GUICapture || paused || demoplayback || !inGame());
|
||||
|
||||
if (wantNative != NativeMouse)
|
||||
{
|
||||
NativeMouse = wantNative;
|
||||
SDL_ShowCursor (wantNative ? cursorSurface == NULL : 0);
|
||||
if (wantNative)
|
||||
{
|
||||
SDL_WM_GrabInput (SDL_GRAB_OFF);
|
||||
FlushDIKState (KEY_MOUSE1, KEY_MOUSE8);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_WM_GrabInput (SDL_GRAB_ON);
|
||||
CenterMouse ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessagePump (const SDL_Event &sev)
|
||||
{
|
||||
static int lastx = 0, lasty = 0;
|
||||
int x, y;
|
||||
event_t event = { 0,0,0,0,0,0,0 };
|
||||
|
||||
switch (sev.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
exit (0);
|
||||
|
||||
case SDL_ACTIVEEVENT:
|
||||
if (sev.active.state == SDL_APPINPUTFOCUS)
|
||||
{
|
||||
if (sev.active.gain == 0)
|
||||
{ // kill focus
|
||||
FlushDIKState ();
|
||||
}
|
||||
S_SetSoundPaused(sev.active.gain);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
case SDL_MOUSEMOTION:
|
||||
if (!GUICapture || sev.button.button == 4 || sev.button.button == 5)
|
||||
{
|
||||
if(sev.type != SDL_MOUSEMOTION)
|
||||
{
|
||||
event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp;
|
||||
/* These button mappings work with my Gentoo system using the
|
||||
* evdev driver and a Logitech MX510 mouse. Whether or not they
|
||||
* carry over to other Linux systems, I have no idea, but I sure
|
||||
* hope so. (Though buttons 11 and 12 are kind of useless, since
|
||||
* they also trigger buttons 4 and 5.)
|
||||
*/
|
||||
switch (sev.button.button)
|
||||
{
|
||||
case 1: event.data1 = KEY_MOUSE1; break;
|
||||
case 2: event.data1 = KEY_MOUSE3; break;
|
||||
case 3: event.data1 = KEY_MOUSE2; break;
|
||||
case 4: event.data1 = KEY_MWHEELUP; break;
|
||||
case 5: event.data1 = KEY_MWHEELDOWN; break;
|
||||
case 6: event.data1 = KEY_MOUSE4; break; /* dunno; not generated by my mouse */
|
||||
case 7: event.data1 = KEY_MOUSE5; break; /* ditto */
|
||||
case 8: event.data1 = KEY_MOUSE4; break;
|
||||
case 9: event.data1 = KEY_MOUSE5; break;
|
||||
case 10: event.data1 = KEY_MOUSE6; break;
|
||||
case 11: event.data1 = KEY_MOUSE7; break;
|
||||
case 12: event.data1 = KEY_MOUSE8; break;
|
||||
default: printf("SDL mouse button %s %d\n",
|
||||
sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break;
|
||||
}
|
||||
if (event.data1 != 0)
|
||||
{
|
||||
//DIKState[ActiveDIKState][event.data1] = (event.type == EV_KeyDown);
|
||||
if (event.data1 == KEY_MWHEELUP || event.data1 == KEY_MWHEELDOWN)
|
||||
{
|
||||
WheelMoved(&event);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sev.type == SDL_MOUSEMOTION || (sev.button.button >= 1 && sev.button.button <= 3))
|
||||
{
|
||||
int x, y;
|
||||
SDL_GetMouseState (&x, &y);
|
||||
|
||||
cursorBlit.x = event.data1 = x;
|
||||
cursorBlit.y = event.data2 = y;
|
||||
event.type = EV_GUI_Event;
|
||||
if(sev.type == SDL_MOUSEMOTION)
|
||||
event.subtype = EV_GUI_MouseMove;
|
||||
else
|
||||
{
|
||||
event.subtype = sev.type == SDL_MOUSEBUTTONDOWN ? EV_GUI_LButtonDown : EV_GUI_LButtonUp;
|
||||
event.subtype += (sev.button.button - 1) * 3;
|
||||
}
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
if (sev.key.keysym.sym >= SDLK_LAST)
|
||||
break;
|
||||
|
||||
if (!GUICapture)
|
||||
{
|
||||
event.type = sev.type == SDL_KEYDOWN ? EV_KeyDown : EV_KeyUp;
|
||||
event.data1 = KeySymToDIK[sev.key.keysym.sym];
|
||||
if (event.data1)
|
||||
{
|
||||
if (sev.key.keysym.sym < 256)
|
||||
{
|
||||
event.data2 = sev.key.keysym.sym;
|
||||
}
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
event.type = EV_GUI_Event;
|
||||
event.subtype = sev.type == SDL_KEYDOWN ? EV_GUI_KeyDown : EV_GUI_KeyUp;
|
||||
event.data3 = ((sev.key.keysym.mod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
|
||||
((sev.key.keysym.mod & KMOD_CTRL) ? GKM_CTRL : 0) |
|
||||
((sev.key.keysym.mod & KMOD_ALT) ? GKM_ALT : 0);
|
||||
|
||||
if (sev.key.keysym.sym < SDLK_LAST)
|
||||
{
|
||||
if (event.subtype == EV_GUI_KeyDown)
|
||||
{
|
||||
if (DownState[sev.key.keysym.sym])
|
||||
{
|
||||
event.subtype = EV_GUI_KeyRepeat;
|
||||
}
|
||||
DownState[sev.key.keysym.sym] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DownState[sev.key.keysym.sym] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (sev.key.keysym.sym)
|
||||
{
|
||||
case SDLK_KP_ENTER: event.data1 = GK_RETURN; break;
|
||||
case SDLK_PAGEUP: event.data1 = GK_PGUP; break;
|
||||
case SDLK_PAGEDOWN: event.data1 = GK_PGDN; break;
|
||||
case SDLK_END: event.data1 = GK_END; break;
|
||||
case SDLK_HOME: event.data1 = GK_HOME; break;
|
||||
case SDLK_LEFT: event.data1 = GK_LEFT; break;
|
||||
case SDLK_RIGHT: event.data1 = GK_RIGHT; break;
|
||||
case SDLK_UP: event.data1 = GK_UP; break;
|
||||
case SDLK_DOWN: event.data1 = GK_DOWN; break;
|
||||
case SDLK_DELETE: event.data1 = GK_DEL; break;
|
||||
case SDLK_ESCAPE: event.data1 = GK_ESCAPE; break;
|
||||
case SDLK_F1: event.data1 = GK_F1; break;
|
||||
case SDLK_F2: event.data1 = GK_F2; break;
|
||||
case SDLK_F3: event.data1 = GK_F3; break;
|
||||
case SDLK_F4: event.data1 = GK_F4; break;
|
||||
case SDLK_F5: event.data1 = GK_F5; break;
|
||||
case SDLK_F6: event.data1 = GK_F6; break;
|
||||
case SDLK_F7: event.data1 = GK_F7; break;
|
||||
case SDLK_F8: event.data1 = GK_F8; break;
|
||||
case SDLK_F9: event.data1 = GK_F9; break;
|
||||
case SDLK_F10: event.data1 = GK_F10; break;
|
||||
case SDLK_F11: event.data1 = GK_F11; break;
|
||||
case SDLK_F12: event.data1 = GK_F12; break;
|
||||
default:
|
||||
if (sev.key.keysym.sym < 256)
|
||||
{
|
||||
event.data1 = sev.key.keysym.sym;
|
||||
}
|
||||
break;
|
||||
}
|
||||
event.data2 = sev.key.keysym.unicode & 0xff;
|
||||
if (event.data1 < 128)
|
||||
{
|
||||
event.data1 = toupper(event.data1);
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
if (!iscntrl(event.data2) && event.subtype != EV_GUI_KeyUp)
|
||||
{
|
||||
event.subtype = EV_GUI_Char;
|
||||
event.data1 = event.data2;
|
||||
event.data2 = sev.key.keysym.mod & KMOD_ALT;
|
||||
event.data3 = 0;
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP:
|
||||
if (!GUICapture)
|
||||
{
|
||||
event.type = sev.type == SDL_JOYBUTTONDOWN ? EV_KeyDown : EV_KeyUp;
|
||||
event.data1 = KEY_FIRSTJOYBUTTON + sev.jbutton.button;
|
||||
if(event.data1 != 0)
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void I_GetEvent ()
|
||||
{
|
||||
SDL_Event sev;
|
||||
|
||||
while (SDL_PollEvent (&sev))
|
||||
{
|
||||
MessagePump (sev);
|
||||
}
|
||||
if (use_mouse)
|
||||
{
|
||||
MouseRead ();
|
||||
}
|
||||
}
|
||||
|
||||
void I_StartTic ()
|
||||
{
|
||||
I_CheckGUICapture ();
|
||||
I_CheckNativeMouse ();
|
||||
I_GetEvent ();
|
||||
}
|
||||
|
||||
void I_ProcessJoysticks ();
|
||||
void I_StartFrame ()
|
||||
{
|
||||
if (KeySymToDIK[SDLK_BACKSPACE] == 0)
|
||||
{
|
||||
InitKeySymMap ();
|
||||
}
|
||||
|
||||
I_ProcessJoysticks();
|
||||
}
|
|
@ -37,7 +37,6 @@
|
|||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// Returns a file name suitable for use as a temp file.
|
||||
// If you create a file with this name (and presumably you
|
||||
// will), it will be deleted automatically by this class's
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -369,7 +369,7 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
|
|||
|
||||
return new FxRandom(rng, min, max, sc);
|
||||
}
|
||||
else if (sc.CheckToken(TK_Pick))
|
||||
else if (sc.CheckToken(TK_RandomPick))
|
||||
{
|
||||
FRandom *rng;
|
||||
TArray<FxExpression*> list;
|
||||
|
@ -396,7 +396,7 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
|
|||
break;
|
||||
sc.MustGetToken(',');
|
||||
}
|
||||
return new FxPick(rng, list, sc);
|
||||
return new FxRandomPick(rng, list, sc);
|
||||
}
|
||||
else if (sc.CheckToken(TK_FRandom))
|
||||
{
|
||||
|
|
|
@ -636,7 +636,7 @@ public:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class FxPick : public FxExpression
|
||||
class FxRandomPick : public FxExpression
|
||||
{
|
||||
protected:
|
||||
FRandom *rng;
|
||||
|
@ -644,8 +644,8 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
FxPick(FRandom *, TArray<FxExpression*> &expr, const FScriptPosition &pos);
|
||||
~FxPick();
|
||||
FxRandomPick(FRandom *, TArray<FxExpression*> &expr, const FScriptPosition &pos);
|
||||
~FxRandomPick();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
|
||||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
|
|
|
@ -88,6 +88,7 @@ DEFINE_MEMBER_VARIABLE(radius, AActor)
|
|||
DEFINE_MEMBER_VARIABLE(reactiontime, AActor)
|
||||
DEFINE_MEMBER_VARIABLE(meleerange, AActor)
|
||||
DEFINE_MEMBER_VARIABLE(Speed, AActor)
|
||||
DEFINE_MEMBER_VARIABLE(roll, AActor)
|
||||
|
||||
ExpEmit::ExpEmit(VMFunctionBuilder *build, int type)
|
||||
: RegNum(build->Registers[type].Get(1)), RegType(type), Konst(false), Fixed(false)
|
||||
|
@ -2104,7 +2105,7 @@ ExpEmit FxRandom::Emit(VMFunctionBuilder *build)
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
FxPick::FxPick(FRandom *r, TArray<FxExpression*> &expr, const FScriptPosition &pos)
|
||||
FxRandomPick::FxRandomPick(FRandom *r, TArray<FxExpression*> &expr, const FScriptPosition &pos)
|
||||
: FxExpression(pos)
|
||||
{
|
||||
assert(expr.Size() > 0);
|
||||
|
@ -2123,7 +2124,7 @@ FxPick::FxPick(FRandom *r, TArray<FxExpression*> &expr, const FScriptPosition &p
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FxPick::~FxPick()
|
||||
FxRandomPick::~FxRandomPick()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2133,7 +2134,7 @@ FxPick::~FxPick()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FxExpression *FxPick::Resolve(FCompileContext &ctx)
|
||||
FxExpression *FxRandomPick::Resolve(FCompileContext &ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
for (unsigned int index = 0; index < choices.Size(); index++)
|
||||
|
@ -2165,7 +2166,7 @@ FxExpression *FxPick::Resolve(FCompileContext &ctx)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
ExpEmit FxPick::Emit(VMFunctionBuilder *build)
|
||||
ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
|
|
|
@ -1485,6 +1485,45 @@ DEFINE_PROPERTY(telefogdesttype, S, Actor)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(ripperlevel, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
if (id < 0)
|
||||
{
|
||||
I_Error ("RipperLevel must not be negative");
|
||||
}
|
||||
defaults->RipperLevel = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(riplevelmin, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
if (id < 0)
|
||||
{
|
||||
I_Error ("RipLevelMin must not be negative");
|
||||
}
|
||||
defaults->RipLevelMin = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(riplevelmax, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
if (id < 0)
|
||||
{
|
||||
I_Error ("RipLevelMax must not be negative");
|
||||
}
|
||||
defaults->RipLevelMax = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Special inventory properties
|
||||
|
|
|
@ -485,7 +485,7 @@ fail:
|
|||
sample_t *tmp;
|
||||
for (i = sp->data_length, tmp = sp->data; i; --i)
|
||||
{
|
||||
a = abs(*tmp++);
|
||||
a = fabsf(*tmp++);
|
||||
if (a > maxamp)
|
||||
maxamp = a;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue