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:
Randy Heit 2015-01-29 20:53:08 -06:00
commit 775e33ede7
106 changed files with 8867 additions and 13603 deletions

180
FindSDL2.cmake Normal file
View 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)

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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 ();

View file

@ -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;
}

View file

@ -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");
}
//-----------------------------------------------------------------------------

View file

@ -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);
}
}
}
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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_

View file

@ -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

View file

@ -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__ //

View file

@ -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

View file

@ -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___ //

View file

@ -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___

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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] == '/' &&

View file

@ -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);

View file

@ -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;
}
}
}
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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)

View file

@ -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

View file

@ -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;
}
}

View file

@ -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
}
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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.

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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,

View file

@ -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 = &sectors[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 = &sectors[secnum];
manual_pillar:
if (sec->PlaneMoving(sector_t::floor) || sec->PlaneMoving(sector_t::ceiling))
continue;

View file

@ -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;

View file

@ -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)
{

View file

@ -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

View file

@ -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;
}

View file

@ -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)
{

View file

@ -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();

View file

@ -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;

View file

@ -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
View 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
View 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
View 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;
}
}

File diff suppressed because it is too large Load diff

551
src/posix/cocoa/i_main.mm Normal file
View 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;
}

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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')

View file

@ -41,7 +41,6 @@
#include "doomerrors.h"
#include <math.h>
#include "SDL.h"
#include "doomtype.h"
#include "doomstat.h"
#include "version.h"

View file

@ -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
View 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
View 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
View 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();
}

View file

@ -35,7 +35,7 @@ public:
FString GetName()
{
return SDL_JoystickName(DeviceIndex);
return SDL_JoystickName(Device);
}
float GetSensitivity()
{

View file

@ -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
{

View file

@ -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;
}

View file

@ -18,5 +18,4 @@ class SDLVideo : public IVideo
private:
int IteratorMode;
int IteratorBits;
bool IteratorFS;
};

View file

@ -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;

View file

@ -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); }

View file

@ -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'")

View file

@ -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;
}

View file

@ -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";
}

View file

@ -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();
}

View file

@ -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>

View file

@ -13,7 +13,6 @@
#include <windows.h>
#include <mmsystem.h>
#else
#include <SDL.h>
#define FALSE 0
#define TRUE 1
#endif

View file

@ -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

View file

@ -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))
{

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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