mirror of
https://github.com/dhewm/dhewm3.git
synced 2025-02-07 17:01:21 +00:00
Merge branch 'aros': Support for the AROS operating system
See www.aros.org, it's an OS aiming to be compatible with AmigaOS
This commit is contained in:
commit
cd8c3662e2
30 changed files with 3607 additions and 33 deletions
|
@ -30,6 +30,8 @@ endif()
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/sys/cmake")
|
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/sys/cmake")
|
||||||
set(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip RPATH" FORCE)
|
set(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip RPATH" FORCE)
|
||||||
|
|
||||||
|
set(DHEWM3BINARY "dhewm3")
|
||||||
|
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
include(GNUInstallDirs OPTIONAL RESULT_VARIABLE GNUINSTALLDIRS)
|
include(GNUInstallDirs OPTIONAL RESULT_VARIABLE GNUINSTALLDIRS)
|
||||||
|
|
||||||
|
@ -108,8 +110,10 @@ include_directories(${VORBISFILE_INCLUDE_DIR})
|
||||||
find_package(OpenAL REQUIRED)
|
find_package(OpenAL REQUIRED)
|
||||||
include_directories(${OPENAL_INCLUDE_DIR})
|
include_directories(${OPENAL_INCLUDE_DIR})
|
||||||
|
|
||||||
find_package(X11 REQUIRED)
|
if(NOT AROS)
|
||||||
include_directories(${X11_INCLUDE_DIR})
|
find_package(X11 REQUIRED)
|
||||||
|
include_directories(${X11_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
if (SDL2)
|
if (SDL2)
|
||||||
# skip SDL2main
|
# skip SDL2main
|
||||||
|
@ -162,11 +166,13 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
|
|
||||||
add_compile_options(-fno-strict-aliasing)
|
add_compile_options(-fno-strict-aliasing)
|
||||||
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-fvisibility=hidden" cxx_has_fvisibility)
|
if(NOT AROS)
|
||||||
if(NOT cxx_has_fvisibility)
|
CHECK_CXX_COMPILER_FLAG("-fvisibility=hidden" cxx_has_fvisibility)
|
||||||
message(FATAL_ERROR "Compiler does not support -fvisibility")
|
if(NOT cxx_has_fvisibility)
|
||||||
|
message(FATAL_ERROR "Compiler does not support -fvisibility")
|
||||||
|
endif()
|
||||||
|
add_compile_options(-fvisibility=hidden)
|
||||||
endif()
|
endif()
|
||||||
add_compile_options(-fvisibility=hidden)
|
|
||||||
|
|
||||||
# TODO fix these warnings
|
# TODO fix these warnings
|
||||||
add_compile_options(-Wno-sign-compare)
|
add_compile_options(-Wno-sign-compare)
|
||||||
|
@ -178,7 +184,10 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
add_compile_options(-Woverloaded-virtual)
|
add_compile_options(-Woverloaded-virtual)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
if(AROS)
|
||||||
|
set(CMAKE_SHARED_LIBRARY_SUFFIX ".aros-${cpu}")
|
||||||
|
add_definitions(-DIOAPI_NO_64)
|
||||||
|
elseif(APPLE)
|
||||||
add_definitions(-DMACOS_X=1)
|
add_definitions(-DMACOS_X=1)
|
||||||
|
|
||||||
if(cpu STREQUAL "x86_64")
|
if(cpu STREQUAL "x86_64")
|
||||||
|
@ -679,7 +688,31 @@ set(src_core
|
||||||
set(src_stub_openal sys/stub/openal_stub.cpp)
|
set(src_stub_openal sys/stub/openal_stub.cpp)
|
||||||
set(src_stub_gl sys/stub/stub_gl.cpp)
|
set(src_stub_gl sys/stub/stub_gl.cpp)
|
||||||
|
|
||||||
if(APPLE)
|
if(AROS)
|
||||||
|
set(DHEWM3BINARY "ADoom3")
|
||||||
|
set(sys_libs ${sys_libs} dll)
|
||||||
|
|
||||||
|
set(src_arosdll
|
||||||
|
sys/aros/dll/dllstartup.c
|
||||||
|
sys/aros/dll/dll.c
|
||||||
|
sys/aros/dll/dllimport.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(src_sys_base
|
||||||
|
sys/cpu.cpp
|
||||||
|
sys/threads.cpp
|
||||||
|
sys/events.cpp
|
||||||
|
sys/sys_local.cpp
|
||||||
|
sys/aros/aros_net.cpp
|
||||||
|
sys/aros/aros_signal.cpp
|
||||||
|
sys/aros/aros_main.cpp
|
||||||
|
sys/aros/aros_dos.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(src_sys_core
|
||||||
|
sys/glimp.cpp
|
||||||
|
)
|
||||||
|
elseif(APPLE)
|
||||||
set(OSX_RESOURCE_FILES
|
set(OSX_RESOURCE_FILES
|
||||||
"${CMAKE_SOURCE_DIR}/sys/osx/Doom3.icns"
|
"${CMAKE_SOURCE_DIR}/sys/osx/Doom3.icns"
|
||||||
"${CMAKE_SOURCE_DIR}/sys/osx/Doom 3.rsrc"
|
"${CMAKE_SOURCE_DIR}/sys/osx/Doom 3.rsrc"
|
||||||
|
@ -745,27 +778,36 @@ include_directories(${CMAKE_BINARY_DIR})
|
||||||
include_directories(${CMAKE_SOURCE_DIR})
|
include_directories(${CMAKE_SOURCE_DIR})
|
||||||
|
|
||||||
add_library(idlib STATIC ${src_idlib})
|
add_library(idlib STATIC ${src_idlib})
|
||||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT MINGW)
|
if (AROS)
|
||||||
set_target_properties(idlib PROPERTIES COMPILE_FLAGS "-fPIC")
|
add_library(dll STATIC ${src_arosdll})
|
||||||
|
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "i386")
|
||||||
|
set(AROS_ARCH "x86")
|
||||||
|
else()
|
||||||
|
set(AROS_ARCH ${CMAKE_SYSTEM_PROCESSOR})
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT MINGW)
|
||||||
|
set_target_properties(idlib PROPERTIES COMPILE_FLAGS "-fPIC")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CORE)
|
if(CORE)
|
||||||
add_executable(dhewm3 WIN32 MACOSX_BUNDLE
|
add_executable(${DHEWM3BINARY} WIN32 MACOSX_BUNDLE
|
||||||
${src_core}
|
${src_core}
|
||||||
${src_sys_base}
|
${src_sys_base}
|
||||||
${src_sys_core}
|
${src_sys_core}
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(dhewm3 PROPERTIES COMPILE_DEFINITIONS "__DOOM_DLL__")
|
set_target_properties(${DHEWM3BINARY} PROPERTIES COMPILE_DEFINITIONS "__DOOM_DLL__")
|
||||||
set_target_properties(dhewm3 PROPERTIES LINK_FLAGS "${ldflags}")
|
set_target_properties(${DHEWM3BINARY} PROPERTIES LINK_FLAGS "${ldflags}")
|
||||||
set_target_properties(dhewm3 PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/sys/osx/Info.plist)
|
set_target_properties(${DHEWM3BINARY} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/sys/osx/Info.plist)
|
||||||
|
|
||||||
target_link_libraries(dhewm3
|
target_link_libraries(${DHEWM3BINARY}
|
||||||
idlib
|
idlib
|
||||||
${OPENAL_LIBRARY}
|
${OPENAL_LIBRARY}
|
||||||
${OGG_LIBRARIES}
|
|
||||||
${VORBISFILE_LIBRARIES}
|
${VORBISFILE_LIBRARIES}
|
||||||
${VORBIS_LIBRARIES}
|
${VORBIS_LIBRARIES}
|
||||||
|
${OGG_LIBRARIES}
|
||||||
${CURL_LIBRARY}
|
${CURL_LIBRARY}
|
||||||
${JPEG_LIBRARY}
|
${JPEG_LIBRARY}
|
||||||
${ZLIB_LIBRARY}
|
${ZLIB_LIBRARY}
|
||||||
|
@ -774,7 +816,7 @@ if(CORE)
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT APPLE AND NOT WIN32)
|
if(NOT APPLE AND NOT WIN32)
|
||||||
install(TARGETS dhewm3
|
install(TARGETS ${DHEWM3BINARY}
|
||||||
RUNTIME DESTINATION "${bindir}"
|
RUNTIME DESTINATION "${bindir}"
|
||||||
LIBRARY DESTINATION "${libdir}"
|
LIBRARY DESTINATION "${libdir}"
|
||||||
ARCHIVE DESTINATION "${libdir}"
|
ARCHIVE DESTINATION "${libdir}"
|
||||||
|
@ -783,19 +825,20 @@ if(CORE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(DEDICATED)
|
if(DEDICATED)
|
||||||
add_executable(dhewm3ded WIN32 MACOSX_BUNDLE
|
add_executable(${DHEWM3BINARY}ded WIN32 MACOSX_BUNDLE
|
||||||
${src_core}
|
${src_core}
|
||||||
${src_stub_openal}
|
${src_stub_openal}
|
||||||
${src_stub_gl}
|
${src_stub_gl}
|
||||||
${src_sys_base}
|
${src_sys_base}
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(dhewm3ded PROPERTIES COMPILE_DEFINITIONS "ID_DEDICATED;__DOOM_DLL__")
|
set_target_properties(${DHEWM3BINARY}ded PROPERTIES COMPILE_DEFINITIONS "ID_DEDICATED;__DOOM_DLL__")
|
||||||
set_target_properties(dhewm3ded PROPERTIES LINK_FLAGS "${ldflags}")
|
set_target_properties(${DHEWM3BINARY}ded PROPERTIES LINK_FLAGS "${ldflags}")
|
||||||
target_link_libraries(dhewm3ded
|
target_link_libraries(${DHEWM3BINARY}ded
|
||||||
idlib
|
idlib
|
||||||
${VORBISFILE_LIBRARIES}
|
${VORBISFILE_LIBRARIES}
|
||||||
${VORBIS_LIBRARIES}
|
${VORBIS_LIBRARIES}
|
||||||
|
${OGG_LIBRARIES}
|
||||||
${CURL_LIBRARY}
|
${CURL_LIBRARY}
|
||||||
${JPEG_LIBRARY}
|
${JPEG_LIBRARY}
|
||||||
${ZLIB_LIBRARY}
|
${ZLIB_LIBRARY}
|
||||||
|
@ -804,7 +847,7 @@ if(DEDICATED)
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT APPLE AND NOT WIN32)
|
if(NOT APPLE AND NOT WIN32)
|
||||||
install(TARGETS dhewm3ded
|
install(TARGETS ${DHEWM3BINARY}ded
|
||||||
RUNTIME DESTINATION "${bindir}"
|
RUNTIME DESTINATION "${bindir}"
|
||||||
LIBRARY DESTINATION "${libdir}"
|
LIBRARY DESTINATION "${libdir}"
|
||||||
ARCHIVE DESTINATION "${libdir}"
|
ARCHIVE DESTINATION "${libdir}"
|
||||||
|
@ -813,13 +856,22 @@ if(DEDICATED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(BASE)
|
if(BASE)
|
||||||
add_library(base SHARED ${src_game})
|
if (AROS)
|
||||||
|
add_executable(base sys/aros/dll/dllglue.c ${src_game})
|
||||||
|
set_target_properties(base PROPERTIES OUTPUT_NAME "base.aros-${AROS_ARCH}")
|
||||||
|
else()
|
||||||
|
add_library(base SHARED ${src_game})
|
||||||
|
endif()
|
||||||
set_target_properties(base PROPERTIES PREFIX "")
|
set_target_properties(base PROPERTIES PREFIX "")
|
||||||
set_target_properties(base PROPERTIES COMPILE_DEFINITIONS "GAME_DLL")
|
set_target_properties(base PROPERTIES COMPILE_DEFINITIONS "GAME_DLL")
|
||||||
set_target_properties(base PROPERTIES COMPILE_FLAGS "-I${CMAKE_SOURCE_DIR}/game")
|
set_target_properties(base PROPERTIES COMPILE_FLAGS "-I${CMAKE_SOURCE_DIR}/game")
|
||||||
set_target_properties(base PROPERTIES LINK_FLAGS "${ldflags}")
|
set_target_properties(base PROPERTIES LINK_FLAGS "${ldflags}")
|
||||||
set_target_properties(base PROPERTIES INSTALL_NAME_DIR "@executable_path")
|
set_target_properties(base PROPERTIES INSTALL_NAME_DIR "@executable_path")
|
||||||
target_link_libraries(base idlib)
|
if (AROS)
|
||||||
|
target_link_libraries(base idlib dll)
|
||||||
|
else()
|
||||||
|
target_link_libraries(base idlib)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT APPLE AND NOT WIN32)
|
if(NOT APPLE AND NOT WIN32)
|
||||||
install(TARGETS base
|
install(TARGETS base
|
||||||
|
@ -831,13 +883,22 @@ if(BASE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(D3XP)
|
if(D3XP)
|
||||||
add_library(d3xp SHARED ${src_d3xp})
|
if (AROS)
|
||||||
|
add_executable(d3xp sys/aros/dll/dllglue.c ${src_d3xp})
|
||||||
|
set_target_properties(d3xp PROPERTIES OUTPUT_NAME "d3xp.aros-${AROS_ARCH}")
|
||||||
|
else()
|
||||||
|
add_library(d3xp SHARED ${src_d3xp})
|
||||||
|
endif()
|
||||||
set_target_properties(d3xp PROPERTIES PREFIX "")
|
set_target_properties(d3xp PROPERTIES PREFIX "")
|
||||||
set_target_properties(d3xp PROPERTIES COMPILE_DEFINITIONS "GAME_DLL;_D3XP;CTF")
|
set_target_properties(d3xp PROPERTIES COMPILE_DEFINITIONS "GAME_DLL;_D3XP;CTF")
|
||||||
set_target_properties(d3xp PROPERTIES COMPILE_FLAGS "-I${CMAKE_SOURCE_DIR}/d3xp")
|
set_target_properties(d3xp PROPERTIES COMPILE_FLAGS "-I${CMAKE_SOURCE_DIR}/d3xp")
|
||||||
set_target_properties(d3xp PROPERTIES LINK_FLAGS "${ldflags}")
|
set_target_properties(d3xp PROPERTIES LINK_FLAGS "${ldflags}")
|
||||||
set_target_properties(d3xp PROPERTIES INSTALL_NAME_DIR "@executable_path")
|
set_target_properties(d3xp PROPERTIES INSTALL_NAME_DIR "@executable_path")
|
||||||
target_link_libraries(d3xp idlib)
|
if (AROS)
|
||||||
|
target_link_libraries(d3xp idlib dll)
|
||||||
|
else()
|
||||||
|
target_link_libraries(d3xp idlib)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT APPLE AND NOT WIN32)
|
if(NOT APPLE AND NOT WIN32)
|
||||||
install(TARGETS d3xp
|
install(TARGETS d3xp
|
||||||
|
|
|
@ -476,7 +476,7 @@ idCVar idFileSystemLocal::fs_cdpath( "fs_cdpath", "", CVAR_SYSTEM | CVAR_INIT, "
|
||||||
idCVar idFileSystemLocal::fs_devpath( "fs_devpath", "", CVAR_SYSTEM | CVAR_INIT, "" );
|
idCVar idFileSystemLocal::fs_devpath( "fs_devpath", "", CVAR_SYSTEM | CVAR_INIT, "" );
|
||||||
idCVar idFileSystemLocal::fs_game( "fs_game", "", CVAR_SYSTEM | CVAR_INIT | CVAR_SERVERINFO, "mod path" );
|
idCVar idFileSystemLocal::fs_game( "fs_game", "", CVAR_SYSTEM | CVAR_INIT | CVAR_SERVERINFO, "mod path" );
|
||||||
idCVar idFileSystemLocal::fs_game_base( "fs_game_base", "", CVAR_SYSTEM | CVAR_INIT | CVAR_SERVERINFO, "alternate mod path, searched after the main fs_game path, before the basedir" );
|
idCVar idFileSystemLocal::fs_game_base( "fs_game_base", "", CVAR_SYSTEM | CVAR_INIT | CVAR_SERVERINFO, "alternate mod path, searched after the main fs_game path, before the basedir" );
|
||||||
#ifdef WIN32
|
#if defined(__AROS__) || defined(WIN32)
|
||||||
idCVar idFileSystemLocal::fs_caseSensitiveOS( "fs_caseSensitiveOS", "0", CVAR_SYSTEM | CVAR_BOOL, "" );
|
idCVar idFileSystemLocal::fs_caseSensitiveOS( "fs_caseSensitiveOS", "0", CVAR_SYSTEM | CVAR_BOOL, "" );
|
||||||
#else
|
#else
|
||||||
idCVar idFileSystemLocal::fs_caseSensitiveOS( "fs_caseSensitiveOS", "1", CVAR_SYSTEM | CVAR_BOOL, "" );
|
idCVar idFileSystemLocal::fs_caseSensitiveOS( "fs_caseSensitiveOS", "1", CVAR_SYSTEM | CVAR_BOOL, "" );
|
||||||
|
|
|
@ -34,15 +34,23 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
===============================================================================
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(__AROS__)
|
||||||
|
#define GAME_NAME "ADoom3" // appears on window titles and errors
|
||||||
|
#define ENGINE_VERSION "dhewm3 1.4.1" // printed in console
|
||||||
|
#define CONFIG_FILE "adoom3.cfg"
|
||||||
|
#else
|
||||||
#define GAME_NAME "dhewm 3" // appears on window titles and errors
|
#define GAME_NAME "dhewm 3" // appears on window titles and errors
|
||||||
|
|
||||||
#define ENGINE_VERSION "dhewm 3 1.4.1" // printed in console
|
#define ENGINE_VERSION "dhewm 3 1.4.1" // printed in console
|
||||||
|
#endif
|
||||||
|
|
||||||
// paths
|
// paths
|
||||||
#define BASE_GAMEDIR "base"
|
#define BASE_GAMEDIR "base"
|
||||||
|
|
||||||
// filenames
|
// filenames
|
||||||
|
#ifndef CONFIG_FILE
|
||||||
#define CONFIG_FILE "dhewm.cfg"
|
#define CONFIG_FILE "dhewm.cfg"
|
||||||
|
#endif
|
||||||
|
|
||||||
// base folder where the source code lives
|
// base folder where the source code lives
|
||||||
#define SOURCE_CODE_BASE_FOLDER "neo"
|
#define SOURCE_CODE_BASE_FOLDER "neo"
|
||||||
|
|
|
@ -37,6 +37,14 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
|
|
||||||
#include "framework/Session_local.h"
|
#include "framework/Session_local.h"
|
||||||
|
|
||||||
|
#if defined(__AROS__)
|
||||||
|
#define CDKEY_FILEPATH CDKEY_FILE
|
||||||
|
#define XPKEY_FILEPATH XPKEY_FILE
|
||||||
|
#else
|
||||||
|
#define CDKEY_FILEPATH "../" BASE_GAMEDIR "/" CDKEY_FILE
|
||||||
|
#define XPKEY_FILEPATH "../" BASE_GAMEDIR "/" XPKEY_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
idCVar idSessionLocal::com_showAngles( "com_showAngles", "0", CVAR_SYSTEM | CVAR_BOOL, "" );
|
idCVar idSessionLocal::com_showAngles( "com_showAngles", "0", CVAR_SYSTEM | CVAR_BOOL, "" );
|
||||||
idCVar idSessionLocal::com_minTics( "com_minTics", "1", CVAR_SYSTEM, "" );
|
idCVar idSessionLocal::com_minTics( "com_minTics", "1", CVAR_SYSTEM, "" );
|
||||||
idCVar idSessionLocal::com_showTics( "com_showTics", "0", CVAR_SYSTEM | CVAR_BOOL, "" );
|
idCVar idSessionLocal::com_showTics( "com_showTics", "0", CVAR_SYSTEM | CVAR_BOOL, "" );
|
||||||
|
@ -2961,7 +2969,7 @@ void idSessionLocal::ReadCDKey( void ) {
|
||||||
|
|
||||||
cdkey_state = CDKEY_UNKNOWN;
|
cdkey_state = CDKEY_UNKNOWN;
|
||||||
|
|
||||||
filename = "../" BASE_GAMEDIR "/" CDKEY_FILE;
|
filename = CDKEY_FILEPATH;
|
||||||
f = fileSystem->OpenExplicitFileRead( fileSystem->RelativePathToOSPath( filename, "fs_configpath" ) );
|
f = fileSystem->OpenExplicitFileRead( fileSystem->RelativePathToOSPath( filename, "fs_configpath" ) );
|
||||||
|
|
||||||
// try the install path, which is where the cd installer and steam put it
|
// try the install path, which is where the cd installer and steam put it
|
||||||
|
@ -2980,7 +2988,7 @@ void idSessionLocal::ReadCDKey( void ) {
|
||||||
|
|
||||||
xpkey_state = CDKEY_UNKNOWN;
|
xpkey_state = CDKEY_UNKNOWN;
|
||||||
|
|
||||||
filename = "../" BASE_GAMEDIR "/" XPKEY_FILE;
|
filename = XPKEY_FILEPATH;
|
||||||
f = fileSystem->OpenExplicitFileRead( fileSystem->RelativePathToOSPath( filename, "fs_configpath" ) );
|
f = fileSystem->OpenExplicitFileRead( fileSystem->RelativePathToOSPath( filename, "fs_configpath" ) );
|
||||||
|
|
||||||
// try the install path, which is where the cd installer and steam put it
|
// try the install path, which is where the cd installer and steam put it
|
||||||
|
@ -3008,7 +3016,7 @@ void idSessionLocal::WriteCDKey( void ) {
|
||||||
idFile *f;
|
idFile *f;
|
||||||
const char *OSPath;
|
const char *OSPath;
|
||||||
|
|
||||||
filename = "../" BASE_GAMEDIR "/" CDKEY_FILE;
|
filename = CDKEY_FILEPATH;
|
||||||
// OpenFileWrite advertises creating directories to the path if needed, but that won't work with a '..' in the path
|
// OpenFileWrite advertises creating directories to the path if needed, but that won't work with a '..' in the path
|
||||||
// occasionally on windows, but mostly on Linux and OSX, the fs_configpath/base may not exist in full
|
// occasionally on windows, but mostly on Linux and OSX, the fs_configpath/base may not exist in full
|
||||||
OSPath = fileSystem->BuildOSPath( cvarSystem->GetCVarString( "fs_configpath" ), BASE_GAMEDIR, CDKEY_FILE );
|
OSPath = fileSystem->BuildOSPath( cvarSystem->GetCVarString( "fs_configpath" ), BASE_GAMEDIR, CDKEY_FILE );
|
||||||
|
@ -3021,7 +3029,7 @@ void idSessionLocal::WriteCDKey( void ) {
|
||||||
f->Printf( "%s%s", cdkey, CDKEY_TEXT );
|
f->Printf( "%s%s", cdkey, CDKEY_TEXT );
|
||||||
fileSystem->CloseFile( f );
|
fileSystem->CloseFile( f );
|
||||||
|
|
||||||
filename = "../" BASE_GAMEDIR "/" XPKEY_FILE;
|
filename = XPKEY_FILEPATH;
|
||||||
f = fileSystem->OpenFileWrite( filename, "fs_configpath" );
|
f = fileSystem->OpenFileWrite( filename, "fs_configpath" );
|
||||||
if ( !f ) {
|
if ( !f ) {
|
||||||
common->Printf( "Couldn't write %s.\n", filename.c_str() );
|
common->Printf( "Couldn't write %s.\n", filename.c_str() );
|
||||||
|
|
|
@ -36,6 +36,8 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
|
|
||||||
#include "ai/AI.h"
|
#include "ai/AI.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
|
||||||
|
@ -604,12 +606,14 @@ pathNode_t *BuildPathTree( const obstacle_t *obstacles, int numObstacles, const
|
||||||
pathNode_t *root, *node, *child;
|
pathNode_t *root, *node, *child;
|
||||||
// gcc 4.0
|
// gcc 4.0
|
||||||
idQueueTemplate<pathNode_t, offsetof( pathNode_t, next ) > pathNodeQueue, treeQueue;
|
idQueueTemplate<pathNode_t, offsetof( pathNode_t, next ) > pathNodeQueue, treeQueue;
|
||||||
|
|
||||||
root = pathNodeAllocator.Alloc();
|
root = pathNodeAllocator.Alloc();
|
||||||
root->Init();
|
root->Init();
|
||||||
root->pos = startPos;
|
root->pos = startPos;
|
||||||
|
|
||||||
root->delta = seekPos - root->pos;
|
root->delta = seekPos - root->pos;
|
||||||
root->numNodes = 0;
|
root->numNodes = 0;
|
||||||
|
|
||||||
pathNodeQueue.Add( root );
|
pathNodeQueue.Add( root );
|
||||||
|
|
||||||
for ( node = pathNodeQueue.Get(); node && pathNodeAllocator.GetAllocCount() < MAX_PATH_NODES; node = pathNodeQueue.Get() ) {
|
for ( node = pathNodeQueue.Get(); node && pathNodeAllocator.GetAllocCount() < MAX_PATH_NODES; node = pathNodeQueue.Get() ) {
|
||||||
|
|
|
@ -817,7 +817,11 @@ idStr::DefaultPath
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
idStr &idStr::DefaultPath( const char *basepath ) {
|
idStr &idStr::DefaultPath( const char *basepath ) {
|
||||||
|
#if defined(__AROS__)
|
||||||
|
if ( ( ( *this )[ 0 ] == '/' ) || ( ( *this )[ 0 ] == '\\' ) || ( ( *this )[ 0 ] == ':' ) ) {
|
||||||
|
#else
|
||||||
if ( ( ( *this )[ 0 ] == '/' ) || ( ( *this )[ 0 ] == '\\' ) ) {
|
if ( ( ( *this )[ 0 ] == '/' ) || ( ( *this )[ 0 ] == '\\' ) ) {
|
||||||
|
#endif
|
||||||
// absolute path location
|
// absolute path location
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -840,11 +844,19 @@ void idStr::AppendPath( const char *text ) {
|
||||||
EnsureAlloced( len + strlen( text ) + 2 );
|
EnsureAlloced( len + strlen( text ) + 2 );
|
||||||
|
|
||||||
if ( pos ) {
|
if ( pos ) {
|
||||||
|
#if defined(__AROS__)
|
||||||
|
if (( data[ pos-1 ] != '/' ) || ( data[ pos-1 ] != ':' )) {
|
||||||
|
#else
|
||||||
if ( data[ pos-1 ] != '/' ) {
|
if ( data[ pos-1 ] != '/' ) {
|
||||||
|
#endif
|
||||||
data[ pos++ ] = '/';
|
data[ pos++ ] = '/';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if defined(__AROS__)
|
||||||
|
if (( text[i] == '/' ) || ( text[i] == ':' )) {
|
||||||
|
#else
|
||||||
if ( text[i] == '/' ) {
|
if ( text[i] == '/' ) {
|
||||||
|
#endif
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -869,7 +881,11 @@ idStr &idStr::StripFilename( void ) {
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
pos = Length() - 1;
|
pos = Length() - 1;
|
||||||
|
#if defined(__AROS__)
|
||||||
|
while( ( pos > 0 ) && ( ( *this )[ pos ] != '/' ) && ( ( *this )[ pos ] != '\\' ) && ( ( *this )[ pos ] != ':' ) ) {
|
||||||
|
#else
|
||||||
while( ( pos > 0 ) && ( ( *this )[ pos ] != '/' ) && ( ( *this )[ pos ] != '\\' ) ) {
|
while( ( pos > 0 ) && ( ( *this )[ pos ] != '/' ) && ( ( *this )[ pos ] != '\\' ) ) {
|
||||||
|
#endif
|
||||||
pos--;
|
pos--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -890,7 +906,11 @@ idStr &idStr::StripPath( void ) {
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
pos = Length();
|
pos = Length();
|
||||||
|
#if defined(__AROS__)
|
||||||
|
while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) && ( ( *this )[ pos - 1 ] != ':' ) ) {
|
||||||
|
#else
|
||||||
while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) {
|
while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) {
|
||||||
|
#endif
|
||||||
pos--;
|
pos--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -910,7 +930,11 @@ void idStr::ExtractFilePath( idStr &dest ) const {
|
||||||
// back up until a \ or the start
|
// back up until a \ or the start
|
||||||
//
|
//
|
||||||
pos = Length();
|
pos = Length();
|
||||||
|
#if defined(__AROS__)
|
||||||
|
while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) && ( ( *this )[ pos - 1 ] != ':' ) ) {
|
||||||
|
#else
|
||||||
while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) {
|
while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) {
|
||||||
|
#endif
|
||||||
pos--;
|
pos--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -929,7 +953,11 @@ void idStr::ExtractFileName( idStr &dest ) const {
|
||||||
// back up until a \ or the start
|
// back up until a \ or the start
|
||||||
//
|
//
|
||||||
pos = Length() - 1;
|
pos = Length() - 1;
|
||||||
|
#if defined(__AROS__)
|
||||||
|
while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) && ( ( *this )[ pos - 1 ] != ':' ) ) {
|
||||||
|
#else
|
||||||
while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) {
|
while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) {
|
||||||
|
#endif
|
||||||
pos--;
|
pos--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -949,7 +977,11 @@ void idStr::ExtractFileBase( idStr &dest ) const {
|
||||||
// back up until a \ or the start
|
// back up until a \ or the start
|
||||||
//
|
//
|
||||||
pos = Length() - 1;
|
pos = Length() - 1;
|
||||||
|
#if defined(__AROS__)
|
||||||
|
while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) && ( ( *this )[ pos - 1 ] != ':' ) ) {
|
||||||
|
#else
|
||||||
while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) {
|
while( ( pos > 0 ) && ( ( *this )[ pos - 1 ] != '/' ) && ( ( *this )[ pos - 1 ] != '\\' ) ) {
|
||||||
|
#endif
|
||||||
pos--;
|
pos--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,12 +64,18 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#endif
|
#endif
|
||||||
#define StrCmpNI use_idStr_Icmpn
|
#define StrCmpNI use_idStr_Icmpn
|
||||||
|
|
||||||
|
#if defined( stricmp )
|
||||||
|
#undef stricmp
|
||||||
|
#endif
|
||||||
#define stricmp idStr::Icmp // use_idStr_Icmp
|
#define stricmp idStr::Icmp // use_idStr_Icmp
|
||||||
#define _stricmp use_idStr_Icmp
|
#define _stricmp use_idStr_Icmp
|
||||||
#if defined( strcasecmp )
|
#if defined( strcasecmp )
|
||||||
#undef strcasecmp
|
#undef strcasecmp
|
||||||
#endif
|
#endif
|
||||||
#define strcasecmp use_idStr_Icmp
|
#define strcasecmp use_idStr_Icmp
|
||||||
|
#if defined( strnicmp )
|
||||||
|
#undef strnicmp
|
||||||
|
#endif
|
||||||
#define strnicmp use_idStr_Icmpn
|
#define strnicmp use_idStr_Icmpn
|
||||||
#define _strnicmp use_idStr_Icmpn
|
#define _strnicmp use_idStr_Icmpn
|
||||||
#define _memicmp use_idStr_Icmpn
|
#define _memicmp use_idStr_Icmpn
|
||||||
|
|
54
neo/mmakefile.src
Normal file
54
neo/mmakefile.src
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# Copyright © 2012-2017, Nick "Kalamatee" Andrews.
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
#
|
||||||
|
# This is the AROS specific top level mmakefile to build
|
||||||
|
# dhewm3. It correctly configures/invokes cmake to
|
||||||
|
# build the AROS ARM, i386 and x86_64 ports.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(SRCDIR)/config/aros.cfg
|
||||||
|
|
||||||
|
DOOM3_EXEDIR := $(AROS_CONTRIB)/Games/Fps/ADoom3
|
||||||
|
DOOM3_GAMEDIR := base
|
||||||
|
|
||||||
|
GRAPHITE_CFLAGS := \
|
||||||
|
-ftree-loop-linear $(CFLAGS_LOOP_STRIP_MINE) $(CFLAGS_LOOP_BLOCK)
|
||||||
|
|
||||||
|
NOWARN_FLAGS := $(NOWARN_ERROR) $(NOWARN_MISLEADING_INDENTATION) $(NOWARN_MAYBE_UNINITIALIZED) $(NOWARN_NONNULL_COMPARE) $(NOWARN_ENUM_COMPARE)
|
||||||
|
|
||||||
|
USER_CFLAGS := $(NOWARN_FLAGS)
|
||||||
|
USER_CXXFLAGS := \
|
||||||
|
$(CFLAGS_FAST_MATH) -fomit-frame-pointer -fexceptions $(NOWARN_FLAGS)
|
||||||
|
USER_LDFLAGS := -static-libstdc++
|
||||||
|
|
||||||
|
#MM- aros-doom3-libs : workbench-libs-jpeg-linklib contrib-openal-linklib development-libogg development-libvorbis
|
||||||
|
#MM- aros-doom3-libs : contrib-curl contrib-sdl development-SDL_gfx-quick
|
||||||
|
|
||||||
|
#MM aros-doom3 : aros-doom3-libs iconset-Gorilla-contrib-icons-extras-games-adoom3 iconset-Gorilla-contrib-games-doom3game
|
||||||
|
|
||||||
|
DOOM3_OPTIONS := -DCORE=ON -DDEDICATED=ON -DBASE=ON -DSDL2=OFF \
|
||||||
|
-DCMAKE_INSTALL_BINDIR= \
|
||||||
|
-DCMAKE_INSTALL_LIBDIR= \
|
||||||
|
-DZLIB_LIBRARY=$(AROS_DEVELOPER)/lib/libz.a \
|
||||||
|
-DZLIB_INCLUDE_DIR=$(AROS_DEVELOPER)/include \
|
||||||
|
-DJPEG_LIBRARY=$(AROS_DEVELOPER)/lib/libjpeg.a \
|
||||||
|
-DJPEG_INCLUDE_DIR=$(AROS_DEVELOPER)/include \
|
||||||
|
-DOPENAL_INCLUDE_DIR=$(AROS_DEVELOPER)/include \
|
||||||
|
-DOPENAL_LIBRARY="$(AROS_DEVELOPER)/lib/libopenal.a;$(AROS_DEVELOPER)/lib/libpthread.a;" \
|
||||||
|
-DOGG_LIBRARY=$(AROS_DEVELOPER)/lib/libogg.a \
|
||||||
|
-DOGG_INCLUDE_DIR=$(AROS_DEVELOPER)/include \
|
||||||
|
-DVORBIS_LIBRARY=$(AROS_DEVELOPER)/lib/libvorbis.a \
|
||||||
|
-DVORBIS_INCLUDE_DIR=$(AROS_DEVELOPER)/include \
|
||||||
|
-DVORBISFILE_LIBRARY=$(AROS_DEVELOPER)/lib/libvorbisfile.a \
|
||||||
|
-DVORBISFILE_INCLUDE_DIR=$(AROS_DEVELOPER)/include \
|
||||||
|
-DCURL_LIBRARY="$(AROS_DEVELOPER)/lib/libcurl.a;$(AROS_DEVELOPER)/lib/libiconv.a;$(AROS_DEVELOPER)/lib/libz.a;$(AROS_DEVELOPER)/lib/libssl.a;$(AROS_DEVELOPER)/lib/libcrypto.a;" \
|
||||||
|
-DCURL_INCLUDE_DIR=$(AROS_DEVELOPER)/include \
|
||||||
|
-DSDL_LIBRARY=$(AROS_DEVELOPER)/lib/libSDL.a \
|
||||||
|
-DSDL_INCLUDE_DIR=$(AROS_DEVELOPER)/include/SDL
|
||||||
|
|
||||||
|
%build_with_cmake mmake=aros-doom3 \
|
||||||
|
prefix="$(DOOM3_EXEDIR)" \
|
||||||
|
extraoptions="$(DOOM3_OPTIONS)"
|
||||||
|
|
||||||
|
%common
|
|
@ -1309,7 +1309,7 @@ thousands of shots
|
||||||
void R_ScreenshotFilename( int &lastNumber, const char *base, idStr &fileName ) {
|
void R_ScreenshotFilename( int &lastNumber, const char *base, idStr &fileName ) {
|
||||||
int a,b,c,d, e;
|
int a,b,c,d, e;
|
||||||
|
|
||||||
bool restrict = cvarSystem->GetCVarBool( "fs_restrict" );
|
bool fsrestrict = cvarSystem->GetCVarBool( "fs_restrict" );
|
||||||
cvarSystem->SetCVarBool( "fs_restrict", false );
|
cvarSystem->SetCVarBool( "fs_restrict", false );
|
||||||
|
|
||||||
lastNumber++;
|
lastNumber++;
|
||||||
|
@ -1339,7 +1339,7 @@ void R_ScreenshotFilename( int &lastNumber, const char *base, idStr &fileName )
|
||||||
}
|
}
|
||||||
// check again...
|
// check again...
|
||||||
}
|
}
|
||||||
cvarSystem->SetCVarBool( "fs_restrict", restrict );
|
cvarSystem->SetCVarBool( "fs_restrict", fsrestrict );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
2
neo/sys/aros/ADoom3.info.src
Normal file
2
neo/sys/aros/ADoom3.info.src
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
TYPE = TOOL
|
||||||
|
STACK = 10000000
|
BIN
neo/sys/aros/ADoom3.png
Normal file
BIN
neo/sys/aros/ADoom3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
2
neo/sys/aros/ROE.info.src
Normal file
2
neo/sys/aros/ROE.info.src
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
TYPE = PROJECT
|
||||||
|
DEFAULTTOOL = C:IconX
|
BIN
neo/sys/aros/ROE.png
Normal file
BIN
neo/sys/aros/ROE.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
46
neo/sys/aros/aros_dedicated.cpp
Normal file
46
neo/sys/aros/aros_dedicated.cpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 GPL Source Code
|
||||||
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
||||||
|
|
||||||
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sys/platform.h"
|
||||||
|
#include "renderer/tr_local.h"
|
||||||
|
#include "sys/aros/aros_public.h"
|
||||||
|
|
||||||
|
#include "sys/aros/aros_local.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_GetVideoRam
|
||||||
|
returns in megabytes
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct Library *MesaBase;
|
||||||
|
|
||||||
|
int Sys_GetVideoRam( void ) {
|
||||||
|
return 64;
|
||||||
|
}
|
516
neo/sys/aros/aros_dos.cpp
Normal file
516
neo/sys/aros/aros_dos.cpp
Normal file
|
@ -0,0 +1,516 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 GPL Source Code
|
||||||
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
||||||
|
|
||||||
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
|
||||||
|
#include <aros/debug.h>
|
||||||
|
#undef ASSERT
|
||||||
|
|
||||||
|
#include <proto/alib.h>
|
||||||
|
#include <proto/intuition.h>
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#include <proto/dos.h>
|
||||||
|
#include <proto/iffparse.h>
|
||||||
|
#include <proto/socket.h>
|
||||||
|
#include <proto/openurl.h>
|
||||||
|
|
||||||
|
#include <dos/dos.h>
|
||||||
|
#include <dos/dosextens.h>
|
||||||
|
|
||||||
|
#include <proto/icon.h>
|
||||||
|
#include <intuition/intuition.h>
|
||||||
|
#include <workbench/startup.h>
|
||||||
|
|
||||||
|
// undefine - conflict with ID functions
|
||||||
|
#undef Remove
|
||||||
|
#undef Insert
|
||||||
|
#undef Read
|
||||||
|
#undef Write
|
||||||
|
#undef Seek
|
||||||
|
#undef Flush
|
||||||
|
#undef Close
|
||||||
|
#undef Allocate
|
||||||
|
#undef Printf
|
||||||
|
#undef VPrintf
|
||||||
|
|
||||||
|
#include "sys/platform.h"
|
||||||
|
#include "idlib/containers/StrList.h"
|
||||||
|
#include "framework/Licensee.h"
|
||||||
|
#include "sys/sys_local.h"
|
||||||
|
|
||||||
|
#define ID_FTXT MAKE_ID('F','T','X','T')
|
||||||
|
#define ID_CHRS MAKE_ID('C','H','R','S')
|
||||||
|
|
||||||
|
extern idCVar com_pid;
|
||||||
|
|
||||||
|
struct Library *MiamiBase;
|
||||||
|
struct Library *OpenURLBase;
|
||||||
|
|
||||||
|
char chunk_buffer[1024];
|
||||||
|
|
||||||
|
idStr adoom3_basepath;
|
||||||
|
idStr adoom3_savepath;
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_GetSystemRam
|
||||||
|
returns in megabytes rounded to the nearest 16Mb
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
int Sys_GetSystemRam( void ) {
|
||||||
|
int mb;
|
||||||
|
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
mb = ( ( AvailMem( MEMF_ANY ) / ( 1024 * 1024 ) ) + 8 ) & ~15;
|
||||||
|
|
||||||
|
return mb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_LockMemory
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
bool Sys_LockMemory( void *ptr, int bytes ) {
|
||||||
|
D(bug("[ADoom3] Sys_LockMemory( 0x%p, %u )\n", ptr, bytes));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_UnlockMemory
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
bool Sys_UnlockMemory( void *ptr, int bytes ) {
|
||||||
|
D(bug("[ADoom3] Sys_UnlockMemory( 0x%p, %u )\n", ptr, bytes));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_ListFiles
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
int Sys_ListFiles( const char *directory, const char *extension, idStrList &list ) {
|
||||||
|
BPTR dirlock;
|
||||||
|
struct FileInfoBlock *fib;
|
||||||
|
char search[1024];
|
||||||
|
|
||||||
|
bool dironly = false;
|
||||||
|
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
list.Clear();
|
||||||
|
|
||||||
|
if (!extension)
|
||||||
|
extension = "";
|
||||||
|
|
||||||
|
// passing a slash as extension will find directories
|
||||||
|
if (extension[0] == '/' && extension[1] == 0) {
|
||||||
|
extension = "";
|
||||||
|
dironly = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// search
|
||||||
|
// NOTE: case sensitivity of directory path can screw us up here
|
||||||
|
if ((dirlock = Lock(directory, SHARED_LOCK)) == BNULL) {
|
||||||
|
D(bug("[ADoom3] Sys_ListFiles: opendir '%s' failed\n", directory));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL)) != (struct FileInfoBlock *)NULL)
|
||||||
|
{
|
||||||
|
if (Examine(dirlock, fib))
|
||||||
|
{
|
||||||
|
while(ExNext(dirlock, fib))
|
||||||
|
{
|
||||||
|
idStr filename((const char *)fib->fib_FileName);
|
||||||
|
|
||||||
|
idStr::snPrintf(search, sizeof(search), "%s/%s", directory, fib->fib_FileName);
|
||||||
|
if (!dironly) {
|
||||||
|
idStr look(search);
|
||||||
|
idStr ext;
|
||||||
|
look.ExtractFileExtension(ext);
|
||||||
|
if (extension[0] != '\0' && ext.Icmp(&extension[1]) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((dironly && (fib->fib_DirEntryType != ST_USERDIR)) ||
|
||||||
|
(!dironly && (fib->fib_DirEntryType == ST_USERDIR)))
|
||||||
|
continue;
|
||||||
|
D(bug("[ADoom3] Sys_ListFiles:\tadding %s to list\n", filename.c_str()));
|
||||||
|
list.Append(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreeDosObject(DOS_FIB, fib);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnLock(dirlock);
|
||||||
|
|
||||||
|
D(bug( "[ADoom3] Sys_ListFiles: %d entries in %s\n", list.Num(), directory ));
|
||||||
|
|
||||||
|
return list.Num();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_Mkdir
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Sys_Mkdir( const char *path ) {
|
||||||
|
BPTR dirlock;
|
||||||
|
|
||||||
|
D(bug("[ADoom3] Sys_Mkdir('%s')\n", path));
|
||||||
|
|
||||||
|
if ((dirlock = CreateDir(path)) != BNULL)
|
||||||
|
{
|
||||||
|
D(bug("[ADoom3] Sys_Mkdir: created\n"));
|
||||||
|
UnLock(dirlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *Sys_GetClipboardData(void) {
|
||||||
|
struct IFFHandle *IFFHandle;
|
||||||
|
struct ContextNode *cn;
|
||||||
|
ULONG error, read = 0;
|
||||||
|
|
||||||
|
D(bug("[ADoom3] Sys_GetClipboardData()\n"));
|
||||||
|
|
||||||
|
if ((IFFHandle = AllocIFF()))
|
||||||
|
{
|
||||||
|
if ((IFFHandle->iff_Stream = (IPTR)OpenClipboard(0)))
|
||||||
|
{
|
||||||
|
InitIFFasClip(IFFHandle);
|
||||||
|
|
||||||
|
if (!OpenIFF(IFFHandle, IFFF_READ))
|
||||||
|
{
|
||||||
|
if (!StopChunk(IFFHandle, ID_FTXT, ID_CHRS))
|
||||||
|
{
|
||||||
|
if (!(error = ParseIFF(IFFHandle, IFFPARSE_SCAN)))
|
||||||
|
{
|
||||||
|
cn = CurrentChunk(IFFHandle);
|
||||||
|
|
||||||
|
if (cn && (cn->cn_Type == ID_FTXT) && (cn->cn_ID == ID_CHRS))
|
||||||
|
{
|
||||||
|
read = ReadChunkBytes(IFFHandle, chunk_buffer, 1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseIFF(IFFHandle);
|
||||||
|
}
|
||||||
|
CloseClipboard((struct ClipboardHandle *)IFFHandle->iff_Stream);
|
||||||
|
}
|
||||||
|
FreeIFF(IFFHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (read > 0)
|
||||||
|
{
|
||||||
|
return chunk_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sys_SetClipboardData( const char *string ) {
|
||||||
|
struct IFFHandle *IFFHandle;
|
||||||
|
BOOL written = FALSE;
|
||||||
|
|
||||||
|
D(bug("[ADoom3] Sys_SetClipboardData('%s')\n", string));
|
||||||
|
|
||||||
|
if ((string) && (strlen(string) > 0))
|
||||||
|
{
|
||||||
|
if((IFFHandle = AllocIFF()))
|
||||||
|
{
|
||||||
|
if((IFFHandle->iff_Stream = (IPTR)OpenClipboard(0)))
|
||||||
|
{
|
||||||
|
InitIFFasClip(IFFHandle);
|
||||||
|
|
||||||
|
if(!OpenIFF(IFFHandle, IFFF_WRITE))
|
||||||
|
{
|
||||||
|
if(!PushChunk(IFFHandle, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN))
|
||||||
|
{
|
||||||
|
if(!PushChunk(IFFHandle, 0, ID_CHRS, IFFSIZE_UNKNOWN))
|
||||||
|
{
|
||||||
|
if(WriteChunkBytes(IFFHandle, (char *)string, strlen(string)) == strlen(string))
|
||||||
|
{
|
||||||
|
if(!PopChunk(IFFHandle))
|
||||||
|
written = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(written)
|
||||||
|
PopChunk(IFFHandle);
|
||||||
|
}
|
||||||
|
CloseIFF(IFFHandle);
|
||||||
|
}
|
||||||
|
CloseClipboard((struct ClipboardHandle *)IFFHandle->iff_Stream);
|
||||||
|
}
|
||||||
|
FreeIFF(IFFHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===========
|
||||||
|
Sys_GetDriveFreeSpace
|
||||||
|
return in MegaBytes
|
||||||
|
===========
|
||||||
|
*/
|
||||||
|
int Sys_GetDriveFreeSpace( const char *path ) {
|
||||||
|
D(bug("[ADoom3] Sys_GetDriveFreeSpace('%s')\n", path));
|
||||||
|
|
||||||
|
D(bug("[ADoom3] ** TODO: Sys_GetDriveFreeSpace\n"));
|
||||||
|
|
||||||
|
return 1000 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
AROS_InitLibs
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void AROS_InitLibs( void ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
MiamiBase = OpenLibrary("miami.library", 0);
|
||||||
|
OpenURLBase = OpenLibrary("openurl.library", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (0)
|
||||||
|
/*
|
||||||
|
==============
|
||||||
|
Sys_EXEPath
|
||||||
|
==============
|
||||||
|
*/
|
||||||
|
const char *Sys_EXEPath( void ) {
|
||||||
|
static char buf[ 1024 ];
|
||||||
|
BPTR pathlock;
|
||||||
|
|
||||||
|
D(bug("[ADoom3] Sys_EXEPath()\n"));
|
||||||
|
|
||||||
|
if ((pathlock = Lock("PROGDIR:", SHARED_LOCK)) != BNULL)
|
||||||
|
{
|
||||||
|
if ( NameFromLock( pathlock, buf, sizeof( buf ) ) )
|
||||||
|
{
|
||||||
|
UnLock(pathlock);
|
||||||
|
struct Node *thisTask = (struct Node *)FindTask(NULL);
|
||||||
|
|
||||||
|
AddPart(buf, thisTask->ln_Name, 1024);
|
||||||
|
|
||||||
|
D(bug("[ADoom3] Sys_EXEPath: using '%s'\n", buf));
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
UnLock(pathlock);
|
||||||
|
}
|
||||||
|
D(bug("[ADoom3] Sys_EXEPath: faling back to PROGDIR\n"));
|
||||||
|
|
||||||
|
return "PROGDIR:ADoom3";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
AROS_Cwd
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
const char *AROS_Cwd( void ) {
|
||||||
|
static char buf[ 1024 ];
|
||||||
|
struct Process *thisTask = (struct Process *)FindTask(NULL);
|
||||||
|
D(bug("[ADoom3] AROS_Cwd()\n"));
|
||||||
|
|
||||||
|
if (thisTask->pr_CurrentDir != BNULL)
|
||||||
|
{
|
||||||
|
if ( NameFromLock( thisTask->pr_CurrentDir, buf, sizeof( buf ) ) )
|
||||||
|
{
|
||||||
|
D(bug("[ADoom3] AROS_Cwd: '%s'\n", buf));
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "PROGDIR:";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_DefaultBasePath
|
||||||
|
|
||||||
|
Get the default base path
|
||||||
|
- binary image path
|
||||||
|
- current directory
|
||||||
|
- hardcoded
|
||||||
|
Try to be intelligent: if there is no BASE_GAMEDIR, try the next path
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
const char *Sys_DefaultBasePath(void) {
|
||||||
|
struct FileInfoBlock *fib;
|
||||||
|
BPTR pathLock = BNULL;
|
||||||
|
idStr testbase;
|
||||||
|
|
||||||
|
D(bug("[ADoom3] Sys_DefaultBasePath()\n"));
|
||||||
|
|
||||||
|
adoom3_basepath = Sys_EXEPath();
|
||||||
|
if ( adoom3_basepath.Length() ) {
|
||||||
|
adoom3_basepath.StripFilename();
|
||||||
|
testbase = adoom3_basepath; testbase += "/"; testbase += BASE_GAMEDIR;
|
||||||
|
if ((fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL)) != (struct FileInfoBlock *)NULL)
|
||||||
|
{
|
||||||
|
if ((pathLock = Lock(testbase.c_str(), SHARED_LOCK)) != BNULL)
|
||||||
|
{
|
||||||
|
if (Examine(pathLock, fib))
|
||||||
|
{
|
||||||
|
if (fib->fib_DirEntryType == ST_USERDIR)
|
||||||
|
{
|
||||||
|
UnLock(pathLock);
|
||||||
|
FreeDosObject(DOS_FIB, fib);
|
||||||
|
return adoom3_basepath.c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnLock(pathLock);
|
||||||
|
}
|
||||||
|
FreeDosObject(DOS_FIB, fib);
|
||||||
|
}
|
||||||
|
D(bug( "[ADoom3] Sys_DefaultBasePath: no '%s' directory in exe path %s, skipping\n", BASE_GAMEDIR, adoom3_basepath.c_str() ));
|
||||||
|
}
|
||||||
|
if ( adoom3_basepath != AROS_Cwd() ) {
|
||||||
|
adoom3_basepath = AROS_Cwd();
|
||||||
|
testbase = adoom3_basepath; testbase += "/"; testbase += BASE_GAMEDIR;
|
||||||
|
if ((fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL)) != (struct FileInfoBlock *)NULL)
|
||||||
|
{
|
||||||
|
if ((pathLock = Lock(testbase.c_str(), SHARED_LOCK)) != BNULL)
|
||||||
|
{
|
||||||
|
if (Examine(pathLock, fib))
|
||||||
|
{
|
||||||
|
if (fib->fib_DirEntryType == ST_USERDIR)
|
||||||
|
{
|
||||||
|
UnLock(pathLock);
|
||||||
|
FreeDosObject(DOS_FIB, fib);
|
||||||
|
return adoom3_basepath.c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnLock(pathLock);
|
||||||
|
}
|
||||||
|
FreeDosObject(DOS_FIB, fib);
|
||||||
|
}
|
||||||
|
D(bug( "[ADoom3] Sys_DefaultBasePath: no '%s' directory in cwd path %s, skipping\n", BASE_GAMEDIR, adoom3_basepath.c_str()));
|
||||||
|
}
|
||||||
|
return "PROGDIR:";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==============
|
||||||
|
Sys_DefaultSavePath
|
||||||
|
==============
|
||||||
|
*/
|
||||||
|
const char *Sys_DefaultSavePath(void) {
|
||||||
|
static char buf[ 1024 ];
|
||||||
|
BPTR pathlock;
|
||||||
|
|
||||||
|
D(bug("[ADoom3] Sys_DefaultSavePath()\n"));
|
||||||
|
|
||||||
|
if ((pathlock = Lock("ENVARC:", SHARED_LOCK)) != BNULL)
|
||||||
|
{
|
||||||
|
if ( NameFromLock( pathlock, buf, sizeof( buf ) ) )
|
||||||
|
{
|
||||||
|
UnLock(pathlock);
|
||||||
|
|
||||||
|
#if defined( ID_DEMO_BUILD )
|
||||||
|
AddPart(buf, ".doom3-demo", sizeof( buf ));
|
||||||
|
#else
|
||||||
|
AddPart(buf, ".doom3", sizeof( buf ));
|
||||||
|
#endif
|
||||||
|
D(bug("[ADoom3] Sys_DefaultSavePath: using '%s'\n", buf));
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
UnLock(pathlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
D(bug("[ADoom3] Sys_DefaultSavePath: faling back to DefaultBasePath\n"));
|
||||||
|
|
||||||
|
sprintf(buf, "%s/.doom3", Sys_DefaultBasePath());
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Sys_OpenURL
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void AROS_OpenURL( const char *url ) {
|
||||||
|
struct TagItem tags[2];
|
||||||
|
|
||||||
|
tags[0].ti_Tag = TAG_DONE; tags[0].ti_Data = 0;
|
||||||
|
|
||||||
|
D(bug("[ADoom3] OpenURL( '%s' )\n", url));
|
||||||
|
|
||||||
|
URL_OpenA( (char *)url, tags );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sys_GetPath(sysPath_t type, idStr &path) {
|
||||||
|
char buf[1024];
|
||||||
|
BPTR pathlock;
|
||||||
|
|
||||||
|
D(bug("[ADoom3] Sys_GetPath(%d)\n", type));
|
||||||
|
|
||||||
|
path.Clear();
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case PATH_BASE:
|
||||||
|
case PATH_CONFIG:
|
||||||
|
case PATH_SAVE:
|
||||||
|
if ((pathlock = Lock("PROGDIR:", SHARED_LOCK)) != BNULL)
|
||||||
|
{
|
||||||
|
if ( NameFromLock( pathlock, buf, sizeof( buf ) ) )
|
||||||
|
{
|
||||||
|
D(bug("[ADoom3] Sys_GetPath: using '%s'\n", buf));
|
||||||
|
path = buf;
|
||||||
|
}
|
||||||
|
UnLock(pathlock);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case PATH_EXE:
|
||||||
|
if ((pathlock = Lock("PROGDIR:", SHARED_LOCK)) != BNULL)
|
||||||
|
{
|
||||||
|
if ( NameFromLock( pathlock, buf, sizeof( buf ) ) )
|
||||||
|
{
|
||||||
|
struct Node *thisTask = (struct Node *)FindTask(NULL);
|
||||||
|
|
||||||
|
AddPart(buf, thisTask->ln_Name, 1024);
|
||||||
|
|
||||||
|
D(bug("[ADoom3] Sys_GetPath: using '%s'\n", buf));
|
||||||
|
path = buf;
|
||||||
|
}
|
||||||
|
UnLock(pathlock);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
43
neo/sys/aros/aros_local.h
Normal file
43
neo/sys/aros/aros_local.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 GPL Source Code
|
||||||
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
||||||
|
|
||||||
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
#ifndef __AROS_LOCAL_H__
|
||||||
|
#define __AROS_LOCAL_H__
|
||||||
|
|
||||||
|
#include "renderer/RenderSystem.h"
|
||||||
|
#include "renderer/tr_local.h"
|
||||||
|
|
||||||
|
// input.cpp
|
||||||
|
void Sys_XEvents();
|
||||||
|
void Sys_XUninstallGrabs();
|
||||||
|
|
||||||
|
|
||||||
|
#define KEY_MASK (1 << 0)
|
||||||
|
#define MOUSE_MASK (1 << 1)
|
||||||
|
#define X_MASK (KEY_MASK | MOUSE_MASK | 1 << 2)
|
||||||
|
|
||||||
|
#endif
|
897
neo/sys/aros/aros_main.cpp
Normal file
897
neo/sys/aros/aros_main.cpp
Normal file
|
@ -0,0 +1,897 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 GPL Source Code
|
||||||
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
||||||
|
|
||||||
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
|
||||||
|
#include <aros/debug.h>
|
||||||
|
#undef ASSERT
|
||||||
|
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#include <proto/dos.h>
|
||||||
|
|
||||||
|
// undefine - conflict with ID functions
|
||||||
|
#undef Remove
|
||||||
|
#undef Insert
|
||||||
|
#undef Read
|
||||||
|
#undef Write
|
||||||
|
#undef Seek
|
||||||
|
#undef Flush
|
||||||
|
#undef Close
|
||||||
|
#undef Allocate
|
||||||
|
#undef Printf
|
||||||
|
#undef VPrintf
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <SDL_main.h>
|
||||||
|
|
||||||
|
#include "dll/dll.h"
|
||||||
|
|
||||||
|
#include "sys/platform.h"
|
||||||
|
#include "idlib/containers/StrList.h"
|
||||||
|
#include "framework/FileSystem.h"
|
||||||
|
#include "framework/KeyInput.h"
|
||||||
|
#include "framework/EditField.h"
|
||||||
|
#include "sys/sys_local.h"
|
||||||
|
|
||||||
|
#include "sys/aros/aros_public.h"
|
||||||
|
|
||||||
|
#define COMMAND_HISTORY 64
|
||||||
|
|
||||||
|
extern idStr adoom3_basepath;
|
||||||
|
extern idStr adoom3_savepath;
|
||||||
|
|
||||||
|
static int input_hide = 0;
|
||||||
|
|
||||||
|
idEditField input_field;
|
||||||
|
static char input_ret[256];
|
||||||
|
|
||||||
|
static idStr history[ COMMAND_HISTORY ]; // cycle buffer
|
||||||
|
static int history_count = 0; // buffer fill up
|
||||||
|
static int history_start = 0; // current history start
|
||||||
|
static int history_current = 0; // goes back in history
|
||||||
|
idEditField history_backup; // the base edit line
|
||||||
|
|
||||||
|
// terminal support
|
||||||
|
idCVar in_tty( "in_tty", "1", CVAR_BOOL | CVAR_INIT | CVAR_SYSTEM, "terminal tab-completion and history" );
|
||||||
|
|
||||||
|
static bool tty_enabled = false;
|
||||||
|
static struct termios tty_tc;
|
||||||
|
|
||||||
|
// pid - useful when you attach to gdb..
|
||||||
|
idCVar com_pid( "com_pid", "0", CVAR_INTEGER | CVAR_INIT | CVAR_SYSTEM, "process id" );
|
||||||
|
|
||||||
|
// exit - quit - error --------------------------------------------------------
|
||||||
|
|
||||||
|
static int set_exit = 0;
|
||||||
|
static char exit_spawn[ 1024 ];
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
AROS_Exit
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void AROS_Exit(int ret) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
if ( tty_enabled ) {
|
||||||
|
Sys_Printf( "shutdown terminal support\n" );
|
||||||
|
#if (0)
|
||||||
|
if ( tcsetattr( 0, TCSADRAIN, &tty_tc ) == -1 ) {
|
||||||
|
Sys_Printf( "tcsetattr failed: %s\n", strerror( errno ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
// at this point, too late to catch signals
|
||||||
|
AROS_ClearSigs();
|
||||||
|
|
||||||
|
// process spawning. it's best when it happens after everything has shut down
|
||||||
|
if ( exit_spawn[0] ) {
|
||||||
|
Sys_DoStartProcess( exit_spawn, false );
|
||||||
|
}
|
||||||
|
// in case of signal, handler tries a common->Quit
|
||||||
|
// we use set_exit to maintain a correct exit code
|
||||||
|
if ( set_exit ) {
|
||||||
|
exit( set_exit );
|
||||||
|
}
|
||||||
|
exit( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
AROS_SetExit
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void AROS_SetExit(int ret) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
set_exit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
AROS_SetExitSpawn
|
||||||
|
set the process to be spawned when we quit
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void AROS_SetExitSpawn( const char *exeName ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
idStr::Copynz( exit_spawn, exeName, 1024 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idSysLocal::StartProcess
|
||||||
|
if !quit, start the process asap
|
||||||
|
otherwise, push it for execution at exit
|
||||||
|
(i.e. let complete shutdown of the game and freeing of resources happen)
|
||||||
|
NOTE: might even want to add a small delay?
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void idSysLocal::StartProcess( const char *exeName, bool quit ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
if ( quit ) {
|
||||||
|
common->DPrintf( "Sys_StartProcess %s (delaying until final exit)\n", exeName );
|
||||||
|
AROS_SetExitSpawn( exeName );
|
||||||
|
cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
common->DPrintf( "Sys_StartProcess %s\n", exeName );
|
||||||
|
Sys_DoStartProcess( exeName );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_Quit
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Sys_Quit(void) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
AROS_Exit( EXIT_SUCCESS );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Sys_Init
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void Sys_Init( void ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
AROS_InitConsoleInput();
|
||||||
|
com_pid.SetString( (char *)FindTask(NULL) );
|
||||||
|
common->Printf( "pid: %p\n", com_pid.GetString() );
|
||||||
|
common->Printf( "%d MB System Memory\n", Sys_GetSystemRam() );
|
||||||
|
#if (0)
|
||||||
|
#ifndef ID_DEDICATED
|
||||||
|
common->Printf( "%d MB Video Memory\n", Sys_GetVideoRam() );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
AROS_Shutdown
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void AROS_Shutdown( void ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
for ( int i = 0; i < COMMAND_HISTORY; i++ ) {
|
||||||
|
history[ i ].Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Sys_DLL_Load
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
uintptr_t Sys_DLL_Load( const char *path ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
void *handle = dllLoadLibrary( (char *)path, FilePart(path) );
|
||||||
|
if ( !handle ) {
|
||||||
|
Sys_Printf( "dllLoadLibrary '%s' failed\n", path );
|
||||||
|
}
|
||||||
|
return (uintptr_t)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Sys_DLL_GetProcAddress
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void* Sys_DLL_GetProcAddress( uintptr_t handle, const char *sym ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
//const char *error;
|
||||||
|
void *ret = dllGetProcAddress( (void *)handle, (char *)sym);
|
||||||
|
if (ret == NULL) {
|
||||||
|
Sys_Printf( "dllGetProcAddress '%s' failed\n", sym );
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Sys_DLL_Unload
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void Sys_DLL_Unload( uintptr_t handle ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
dllFreeLibrary( (void *)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_ShowConsole
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Sys_ShowConsole( int visLevel, bool quitOnClose ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ID_TIME_T Sys_FileTimeStamp(FILE * fp) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
fstat(fileno(fp), &st);
|
||||||
|
return st.st_mtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sys_FPU_StackIsEmpty( void ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Sys_FPU_GetState( void ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sys_FPU_SetPrecision( int precision ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_SetPhysicalWorkMemory
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Sys_SetPhysicalWorkMemory( int minBytes, int maxBytes ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
common->DPrintf( "TODO: Sys_SetPhysicalWorkMemory\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
AROS_EarlyInit
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void AROS_EarlyInit( void ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
exit_spawn[0] = '\0';
|
||||||
|
AROS_InitLibs();
|
||||||
|
AROS_InitSigs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
AROS_InitConsoleInput
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void AROS_InitConsoleInput( void ) {
|
||||||
|
struct termios tc;
|
||||||
|
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
|
||||||
|
if ( in_tty.GetBool() ) {
|
||||||
|
if ( isatty( STDIN_FILENO ) != 1 ) {
|
||||||
|
Sys_Printf( "terminal support disabled: stdin is not a tty\n" );
|
||||||
|
in_tty.SetBool( false );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if !defined(__AROS__)
|
||||||
|
if ( tcgetattr( 0, &tty_tc ) == -1 ) {
|
||||||
|
Sys_Printf( "tcgetattr failed. disabling terminal support: %s\n", strerror( errno ) );
|
||||||
|
in_tty.SetBool( false );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// make the input non blocking
|
||||||
|
if ( fcntl( STDIN_FILENO, F_SETFL, fcntl( STDIN_FILENO, F_GETFL, 0 ) | O_NONBLOCK ) == -1 ) {
|
||||||
|
Sys_Printf( "fcntl STDIN non blocking failed. disabling terminal support: %s\n", strerror( errno ) );
|
||||||
|
in_tty.SetBool( false );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
tc = tty_tc;
|
||||||
|
/*
|
||||||
|
ECHO: don't echo input characters
|
||||||
|
ICANON: enable canonical mode. This enables the special
|
||||||
|
characters EOF, EOL, EOL2, ERASE, KILL, REPRINT,
|
||||||
|
STATUS, and WERASE, and buffers by lines.
|
||||||
|
ISIG: when any of the characters INTR, QUIT, SUSP, or
|
||||||
|
DSUSP are received, generate the corresponding signal
|
||||||
|
*/
|
||||||
|
tc.c_lflag &= ~(ECHO | ICANON);
|
||||||
|
/*
|
||||||
|
ISTRIP strip off bit 8
|
||||||
|
INPCK enable input parity checking
|
||||||
|
*/
|
||||||
|
tc.c_iflag &= ~(ISTRIP | INPCK);
|
||||||
|
tc.c_cc[VMIN] = 1;
|
||||||
|
tc.c_cc[VTIME] = 0;
|
||||||
|
|
||||||
|
#if !defined(__AROS__)
|
||||||
|
if ( tcsetattr( 0, TCSADRAIN, &tc ) == -1 ) {
|
||||||
|
Sys_Printf( "tcsetattr failed: %s\n", strerror( errno ) );
|
||||||
|
Sys_Printf( "terminal support may not work correctly. Use +set in_tty 0 to disable it\n" );
|
||||||
|
}
|
||||||
|
// make the output non blocking
|
||||||
|
if ( fcntl( STDOUT_FILENO, F_SETFL, fcntl( STDOUT_FILENO, F_GETFL, 0 ) | O_NONBLOCK ) == -1 ) {
|
||||||
|
Sys_Printf( "fcntl STDOUT non blocking failed: %s\n", strerror( errno ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
tty_enabled = true;
|
||||||
|
// check the terminal type for the supported ones
|
||||||
|
char *term = getenv( "TERM" );
|
||||||
|
if ( term ) {
|
||||||
|
if ( strcmp( term, "linux" ) && strcmp( term, "xterm" ) && strcmp( term, "xterm-color" ) && strcmp( term, "screen" ) ) {
|
||||||
|
Sys_Printf( "WARNING: terminal type '%s' is unknown. terminal support may not work correctly\n", term );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sys_Printf( "terminal support enabled ( use +set in_tty 0 to disabled )\n" );
|
||||||
|
} else {
|
||||||
|
Sys_Printf( "terminal support disabled\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
terminal support utilities
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
|
||||||
|
void tty_Del() {
|
||||||
|
putchar('\b');
|
||||||
|
putchar(' ');
|
||||||
|
putchar('\b');
|
||||||
|
}
|
||||||
|
|
||||||
|
void tty_Left() {
|
||||||
|
putchar('\b');
|
||||||
|
}
|
||||||
|
|
||||||
|
void tty_Right() {
|
||||||
|
putchar(27);
|
||||||
|
putchar('[');
|
||||||
|
putchar('C');
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear the display of the line currently edited
|
||||||
|
// bring cursor back to beginning of line
|
||||||
|
void tty_Hide() {
|
||||||
|
int len, buf_len;
|
||||||
|
|
||||||
|
if ( !tty_enabled ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( input_hide ) {
|
||||||
|
input_hide++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// clear after cursor
|
||||||
|
len = strlen( input_field.GetBuffer() ) - input_field.GetCursor();
|
||||||
|
while ( len > 0 ) {
|
||||||
|
tty_Right();
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
buf_len = strlen( input_field.GetBuffer() );
|
||||||
|
while ( buf_len > 0 ) {
|
||||||
|
tty_Del();
|
||||||
|
buf_len--;
|
||||||
|
}
|
||||||
|
input_hide++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// show the current line
|
||||||
|
void tty_Show() {
|
||||||
|
// int i;
|
||||||
|
if ( !tty_enabled ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert( input_hide > 0 );
|
||||||
|
input_hide--;
|
||||||
|
if ( input_hide == 0 ) {
|
||||||
|
char *buf = input_field.GetBuffer();
|
||||||
|
size_t len = strlen(buf);
|
||||||
|
if ( len < 1 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
len = write( STDOUT_FILENO, buf, len );
|
||||||
|
if ( len < 1 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
len -= input_field.GetCursor();
|
||||||
|
while ( len > 0 ) {
|
||||||
|
tty_Left();
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tty_FlushIn() {
|
||||||
|
char key;
|
||||||
|
while ( ( key = getchar() ) != EOF ) {
|
||||||
|
Sys_Printf( "'%d' ", key );
|
||||||
|
}
|
||||||
|
Sys_Printf( "\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_ConsoleInput
|
||||||
|
Checks for a complete line of text typed in at the console.
|
||||||
|
Return NULL if a complete line is not ready.
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
char *Sys_ConsoleInput( void ) {
|
||||||
|
/*
|
||||||
|
if ( tty_enabled ) {
|
||||||
|
char key;
|
||||||
|
bool hidden = false;
|
||||||
|
while ( ( key = getchar() ) != EOF ) {
|
||||||
|
if ( !hidden ) {
|
||||||
|
tty_Hide();
|
||||||
|
hidden = true;
|
||||||
|
}
|
||||||
|
switch ( key ) {
|
||||||
|
case 1:
|
||||||
|
input_field.SetCursor( 0 );
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
input_field.SetCursor( strlen( input_field.GetBuffer() ) );
|
||||||
|
break;
|
||||||
|
case 127:
|
||||||
|
case 8:
|
||||||
|
input_field.CharEvent( K_BACKSPACE );
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
idStr::Copynz( input_ret, input_field.GetBuffer(), sizeof( input_ret ) );
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
putchar(key);
|
||||||
|
input_field.Clear();
|
||||||
|
if ( history_count < CMD_HIST ) {
|
||||||
|
history[ history_count ] = input_ret;
|
||||||
|
history_count++;
|
||||||
|
} else {
|
||||||
|
history[ history_start ] = input_ret;
|
||||||
|
history_start++;
|
||||||
|
history_start %= CMD_HIST;
|
||||||
|
}
|
||||||
|
history_current = 0;
|
||||||
|
return input_ret;
|
||||||
|
case '\t':
|
||||||
|
input_field.AutoComplete();
|
||||||
|
break;
|
||||||
|
case 27: {
|
||||||
|
// enter escape sequence mode
|
||||||
|
if ( ( key = getchar() ) == EOF ) {
|
||||||
|
Sys_Printf( "dropping sequence: '27' " );
|
||||||
|
tty_FlushIn();
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
switch ( key ) {
|
||||||
|
case 79:
|
||||||
|
if ( ( key = getchar() ) == EOF ) {
|
||||||
|
Sys_Printf( "dropping sequence: '27' '79' " );
|
||||||
|
tty_FlushIn();
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
switch ( key ) {
|
||||||
|
case 72:
|
||||||
|
// xterm only
|
||||||
|
input_field.SetCursor( 0 );
|
||||||
|
break;
|
||||||
|
case 70:
|
||||||
|
// xterm only
|
||||||
|
input_field.SetCursor( strlen( input_field.GetBuffer() ) );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Sys_Printf( "dropping sequence: '27' '79' '%d' ", key );
|
||||||
|
tty_FlushIn();
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 91: {
|
||||||
|
if ( ( key = getchar() ) == EOF ) {
|
||||||
|
Sys_Printf( "dropping sequence: '27' '91' " );
|
||||||
|
tty_FlushIn();
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
switch ( key ) {
|
||||||
|
case 49: {
|
||||||
|
if ( ( key = getchar() ) == EOF || key != 126 ) {
|
||||||
|
Sys_Printf( "dropping sequence: '27' '91' '49' '%d' ", key );
|
||||||
|
tty_FlushIn();
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// only screen and linux terms
|
||||||
|
input_field.SetCursor( 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 50: {
|
||||||
|
if ( ( key = getchar() ) == EOF || key != 126 ) {
|
||||||
|
Sys_Printf( "dropping sequence: '27' '91' '50' '%d' ", key );
|
||||||
|
tty_FlushIn();
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// all terms
|
||||||
|
input_field.KeyDownEvent( K_INS );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 52: {
|
||||||
|
if ( ( key = getchar() ) == EOF || key != 126 ) {
|
||||||
|
Sys_Printf( "dropping sequence: '27' '91' '52' '%d' ", key );
|
||||||
|
tty_FlushIn();
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// only screen and linux terms
|
||||||
|
input_field.SetCursor( strlen( input_field.GetBuffer() ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 51: {
|
||||||
|
if ( ( key = getchar() ) == EOF ) {
|
||||||
|
Sys_Printf( "dropping sequence: '27' '91' '51' " );
|
||||||
|
tty_FlushIn();
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if ( key == 126 ) {
|
||||||
|
input_field.KeyDownEvent( K_DEL );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Sys_Printf( "dropping sequence: '27' '91' '51' '%d'", key );
|
||||||
|
tty_FlushIn();
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
case 65:
|
||||||
|
case 66: {
|
||||||
|
// history
|
||||||
|
if ( history_current == 0 ) {
|
||||||
|
history_backup = input_field;
|
||||||
|
}
|
||||||
|
if ( key == 65 ) {
|
||||||
|
// up
|
||||||
|
history_current++;
|
||||||
|
} else {
|
||||||
|
// down
|
||||||
|
history_current--;
|
||||||
|
}
|
||||||
|
// history_current cycle:
|
||||||
|
// 0: current edit
|
||||||
|
// 1 .. Min( CMD_HIST, history_count ): back in history
|
||||||
|
if ( history_current < 0 ) {
|
||||||
|
history_current = Min( CMD_HIST, history_count );
|
||||||
|
} else {
|
||||||
|
history_current %= Min( CMD_HIST, history_count ) + 1;
|
||||||
|
}
|
||||||
|
int index = -1;
|
||||||
|
if ( history_current == 0 ) {
|
||||||
|
input_field = history_backup;
|
||||||
|
} else {
|
||||||
|
index = history_start + Min( CMD_HIST, history_count ) - history_current;
|
||||||
|
index %= CMD_HIST;
|
||||||
|
assert( index >= 0 && index < CMD_HIST );
|
||||||
|
input_field.SetBuffer( history[ index ] );
|
||||||
|
}
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
case 67:
|
||||||
|
input_field.KeyDownEvent( K_RIGHTARROW );
|
||||||
|
break;
|
||||||
|
case 68:
|
||||||
|
input_field.KeyDownEvent( K_LEFTARROW );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Sys_Printf( "dropping sequence: '27' '91' '%d' ", key );
|
||||||
|
tty_FlushIn();
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
Sys_Printf( "dropping sequence: '27' '%d' ", key );
|
||||||
|
tty_FlushIn();
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if ( key >= ' ' ) {
|
||||||
|
input_field.CharEvent( key );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Sys_Printf( "dropping sequence: '%d' ", key );
|
||||||
|
tty_FlushIn();
|
||||||
|
assert( hidden );
|
||||||
|
tty_Show();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( hidden ) {
|
||||||
|
tty_Show();
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
// no terminal support - read only complete lines
|
||||||
|
int len;
|
||||||
|
fd_set fdset;
|
||||||
|
struct timeval timeout;
|
||||||
|
|
||||||
|
FD_ZERO( &fdset );
|
||||||
|
FD_SET( STDIN_FILENO, &fdset );
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
if ( select( 1, &fdset, NULL, NULL, &timeout ) == -1 || !FD_ISSET( 0, &fdset ) ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = read( 0, input_ret, sizeof( input_ret ) );
|
||||||
|
if ( len == 0 ) {
|
||||||
|
// EOF
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( len < 1 ) {
|
||||||
|
Sys_Printf( "read failed: %s\n", strerror( errno ) ); // something bad happened, cancel this line and print an error
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( len == sizeof( input_ret ) ) {
|
||||||
|
Sys_Printf( "read overflow\n" ); // things are likely to break, as input will be cut into pieces
|
||||||
|
}
|
||||||
|
|
||||||
|
input_ret[ len-1 ] = '\0'; // rip off the \n and terminate
|
||||||
|
return input_ret;
|
||||||
|
}*/
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
low level output
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Sys_DebugPrintf( const char *fmt, ... ) {
|
||||||
|
va_list argptr;
|
||||||
|
|
||||||
|
tty_Hide();
|
||||||
|
va_start( argptr, fmt );
|
||||||
|
vprintf( fmt, argptr );
|
||||||
|
va_end( argptr );
|
||||||
|
tty_Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sys_DebugVPrintf( const char *fmt, va_list arg ) {
|
||||||
|
tty_Hide();
|
||||||
|
vprintf( fmt, arg );
|
||||||
|
tty_Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sys_Printf(const char *msg, ...) {
|
||||||
|
va_list argptr;
|
||||||
|
|
||||||
|
tty_Hide();
|
||||||
|
va_start( argptr, msg );
|
||||||
|
vprintf( msg, argptr );
|
||||||
|
va_end( argptr );
|
||||||
|
tty_Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sys_VPrintf(const char *msg, va_list arg) {
|
||||||
|
tty_Hide();
|
||||||
|
vprintf(msg, arg);
|
||||||
|
tty_Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_Error
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Sys_Error(const char *error, ...) {
|
||||||
|
va_list argptr;
|
||||||
|
|
||||||
|
Sys_Printf( "Sys_Error: " );
|
||||||
|
va_start( argptr, error );
|
||||||
|
Sys_DebugVPrintf( error, argptr );
|
||||||
|
va_end( argptr );
|
||||||
|
Sys_Printf( "\n" );
|
||||||
|
|
||||||
|
AROS_Exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_Shutdown
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Sys_Shutdown( void ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
adoom3_basepath.Clear();
|
||||||
|
adoom3_savepath.Clear();
|
||||||
|
AROS_Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_FPU_EnableExceptions
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Sys_FPU_EnableExceptions( int exceptions ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_FPE_handler
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Sys_FPE_handler( int signum, siginfo_t *info, void *context ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
assert( signum == SIGFPE );
|
||||||
|
Sys_Printf( "FPE\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_DoStartProcess
|
||||||
|
if we don't fork, this function never returns
|
||||||
|
the no-fork lets you keep the terminal when you're about to spawn an installer
|
||||||
|
|
||||||
|
if the command contains spaces, system() is used. Otherwise the more straightforward execl ( system() blows though )
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void Sys_DoStartProcess( const char *exeName, bool dofork ) {
|
||||||
|
bool use_system = false;
|
||||||
|
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
if ( strchr( exeName, ' ' ) ) {
|
||||||
|
use_system = true;
|
||||||
|
} else {
|
||||||
|
// set exec rights when it's about a single file to execute
|
||||||
|
struct stat buf;
|
||||||
|
if ( stat( exeName, &buf ) == -1 ) {
|
||||||
|
printf( "stat %s failed: %s\n", exeName, strerror( errno ) );
|
||||||
|
} else {
|
||||||
|
if ( chmod( exeName, buf.st_mode | S_IXUSR ) == -1 ) {
|
||||||
|
printf( "cmod +x %s failed: %s\n", exeName, strerror( errno ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( use_system ) {
|
||||||
|
printf( "system %s\n", exeName );
|
||||||
|
if (system( exeName ) == -1)
|
||||||
|
printf( "system failed: %s\n", strerror( errno ) );
|
||||||
|
else
|
||||||
|
sleep( 1 ); // on some systems I've seen that starting the new process and exiting this one should not be too close
|
||||||
|
} else {
|
||||||
|
printf( "execl %s\n", exeName );
|
||||||
|
execl( exeName, exeName, 0 );
|
||||||
|
printf( "execl failed: %s\n", strerror( errno ) );
|
||||||
|
}
|
||||||
|
// terminate
|
||||||
|
_exit( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Sys_OpenURL
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void idSysLocal::OpenURL( const char *url, bool quit ) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
AROS_OpenURL( url );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
main
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
bug("[ADoom3] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
AROS_EarlyInit( );
|
||||||
|
|
||||||
|
if ( argc > 1 ) {
|
||||||
|
common->Init( argc-1, &argv[1] );
|
||||||
|
} else {
|
||||||
|
common->Init( 0, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
Sys_Init( );
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
common->Frame();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
759
neo/sys/aros/aros_net.cpp
Normal file
759
neo/sys/aros/aros_net.cpp
Normal file
|
@ -0,0 +1,759 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 GPL Source Code
|
||||||
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
||||||
|
|
||||||
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <proto/socket.h>
|
||||||
|
#include <proto/miami.h>
|
||||||
|
#include <bsdsocket/socketbasetags.h>
|
||||||
|
#ifndef INADDR_LOOPBACK
|
||||||
|
# define INADDR_LOOPBACK ((unsigned long int) 0x7f000001)
|
||||||
|
#endif /* INADDR_LOOPBACK */
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "sys/platform.h"
|
||||||
|
#include "framework/Common.h"
|
||||||
|
#include "framework/CVarSystem.h"
|
||||||
|
#include "sys/sys_public.h"
|
||||||
|
|
||||||
|
#include "sys/aros/aros_public.h"
|
||||||
|
|
||||||
|
idPort clientPort, serverPort;
|
||||||
|
|
||||||
|
idCVar net_ip( "net_ip", "localhost", CVAR_SYSTEM, "local IP address" );
|
||||||
|
idCVar net_port( "net_port", "", CVAR_SYSTEM | CVAR_INTEGER, "local IP port number" );
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int ip;
|
||||||
|
unsigned int mask;
|
||||||
|
} net_interface;
|
||||||
|
|
||||||
|
#define MAX_INTERFACES 32
|
||||||
|
int num_interfaces = 0;
|
||||||
|
net_interface netint[MAX_INTERFACES];
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
NetadrToSockadr
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
static void NetadrToSockadr( const netadr_t * a, struct sockaddr_in *s ) {
|
||||||
|
memset(s, 0, sizeof(*s));
|
||||||
|
|
||||||
|
if ( a->type == NA_BROADCAST ) {
|
||||||
|
s->sin_family = AF_INET;
|
||||||
|
|
||||||
|
s->sin_port = htons( (short)a->port );
|
||||||
|
*(int *) &s->sin_addr = -1;
|
||||||
|
} else if ( a->type == NA_IP || a->type == NA_LOOPBACK ) {
|
||||||
|
s->sin_family = AF_INET;
|
||||||
|
|
||||||
|
*(int *) &s->sin_addr = *(int *) &a->ip;
|
||||||
|
s->sin_port = htons( (short)a->port );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
SockadrToNetadr
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
static void SockadrToNetadr(struct sockaddr_in *s, netadr_t * a) {
|
||||||
|
unsigned int ip = *(int *)&s->sin_addr;
|
||||||
|
*(int *)&a->ip = ip;
|
||||||
|
a->port = ntohs( s->sin_port );
|
||||||
|
// we store in network order, that loopback test is host order..
|
||||||
|
ip = ntohl( ip );
|
||||||
|
if ( ip == INADDR_LOOPBACK ) {
|
||||||
|
a->type = NA_LOOPBACK;
|
||||||
|
} else {
|
||||||
|
a->type = NA_IP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
ExtractPort
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
static bool ExtractPort( const char *src, char *buf, int bufsize, int *port ) {
|
||||||
|
char *p;
|
||||||
|
strncpy( buf, src, bufsize );
|
||||||
|
p = buf; p += Min( bufsize - 1, (int)strlen( src ) ); *p = '\0';
|
||||||
|
p = strchr( buf, ':' );
|
||||||
|
if ( !p ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
*port = strtol( p+1, NULL, 10 );
|
||||||
|
if ( ( *port == 0 && errno == EINVAL ) ||
|
||||||
|
( ( *port == INT_MIN || *port == INT_MAX ) && errno == ERANGE ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
StringToSockaddr
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
static bool StringToSockaddr( const char *s, struct sockaddr_in *sadr, bool doDNSResolve ) {
|
||||||
|
struct hostent *h;
|
||||||
|
char buf[256];
|
||||||
|
int port;
|
||||||
|
|
||||||
|
memset( sadr, 0, sizeof( *sadr ) );
|
||||||
|
sadr->sin_family = AF_INET;
|
||||||
|
|
||||||
|
sadr->sin_port = 0;
|
||||||
|
|
||||||
|
if (s[0] >= '0' && s[0] <= '9') {
|
||||||
|
if ( !inet_aton( (char *)s, &sadr->sin_addr ) ) {
|
||||||
|
// check for port
|
||||||
|
if ( !ExtractPort( s, buf, sizeof( buf ), &port ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( !inet_aton( buf, &sadr->sin_addr ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sadr->sin_port = htons( port );
|
||||||
|
}
|
||||||
|
} else if ( doDNSResolve ) {
|
||||||
|
// try to remove the port first, otherwise the DNS gets confused into multiple timeouts
|
||||||
|
// failed or not failed, buf is expected to contain the appropriate host to resolve
|
||||||
|
if ( ExtractPort( s, buf, sizeof( buf ), &port ) ) {
|
||||||
|
sadr->sin_port = htons( port );
|
||||||
|
}
|
||||||
|
if ( !( h = gethostbyname( buf ) ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*(int *) &sadr->sin_addr =
|
||||||
|
*(int *) h->h_addr_list[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
Sys_StringToAdr
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
bool Sys_StringToNetAdr( const char *s, netadr_t * a, bool doDNSResolve ) {
|
||||||
|
struct sockaddr_in sadr;
|
||||||
|
|
||||||
|
if ( !StringToSockaddr( s, &sadr, doDNSResolve ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SockadrToNetadr( &sadr, a );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============
|
||||||
|
Sys_NetAdrToString
|
||||||
|
=============
|
||||||
|
*/
|
||||||
|
const char *Sys_NetAdrToString( const netadr_t a ) {
|
||||||
|
static char s[64];
|
||||||
|
|
||||||
|
if ( a.type == NA_LOOPBACK ) {
|
||||||
|
if ( a.port ) {
|
||||||
|
idStr::snPrintf( s, sizeof(s), "localhost:%i", a.port );
|
||||||
|
} else {
|
||||||
|
idStr::snPrintf( s, sizeof(s), "localhost" );
|
||||||
|
}
|
||||||
|
} else if ( a.type == NA_IP ) {
|
||||||
|
idStr::snPrintf( s, sizeof(s), "%i.%i.%i.%i:%i",
|
||||||
|
a.ip[0], a.ip[1], a.ip[2], a.ip[3], a.port );
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_IsLANAddress
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
bool Sys_IsLANAddress( const netadr_t adr ) {
|
||||||
|
int i;
|
||||||
|
unsigned int ip;
|
||||||
|
|
||||||
|
#if ID_NOLANADDRESS
|
||||||
|
common->Printf( "Sys_IsLANAddress: ID_NOLANADDRESS\n" );
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( adr.type == NA_LOOPBACK ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( adr.type != NA_IP ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !num_interfaces ) {
|
||||||
|
return false; // well, if there's no networking, there are no LAN addresses, right
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < num_interfaces; i++ ) {
|
||||||
|
ip = ntohl( adr.ip[0] );
|
||||||
|
if( ( netint[i].ip & netint[i].mask ) == ( ip & netint[i].mask ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================
|
||||||
|
Sys_CompareNetAdrBase
|
||||||
|
|
||||||
|
Compares without the port
|
||||||
|
===================
|
||||||
|
*/
|
||||||
|
bool Sys_CompareNetAdrBase( const netadr_t a, const netadr_t b ) {
|
||||||
|
if ( a.type != b.type ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( a.type == NA_LOOPBACK ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( a.type == NA_IP ) {
|
||||||
|
if ( a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] && a.ip[3] == b.ip[3] ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
common->Printf( "Sys_CompareNetAdrBase: bad address type\n" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
====================
|
||||||
|
NET_InitNetworking
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
void Sys_InitNetworking(void)
|
||||||
|
{
|
||||||
|
// haven't been able to clearly pinpoint which standards or RFCs define SIOCGIFCONF, SIOCGIFADDR, SIOCGIFNETMASK ioctls
|
||||||
|
// it seems fairly widespread, in Linux kernel ioctl, and in BSD .. so let's assume it's always available on our targets
|
||||||
|
|
||||||
|
int s;
|
||||||
|
char buf[ MAX_INTERFACES*sizeof( ifreq ) ];
|
||||||
|
struct ifconf ifc;
|
||||||
|
struct ifreq *ifr;
|
||||||
|
int ifindex;
|
||||||
|
unsigned int ip, mask;
|
||||||
|
|
||||||
|
num_interfaces = 0;
|
||||||
|
|
||||||
|
s = socket( AF_INET, SOCK_DGRAM, 0 );
|
||||||
|
|
||||||
|
memset (buf, 0, MAX_INTERFACES*sizeof( struct ifreq ));
|
||||||
|
memset (&ifc, 0, sizeof(struct ifconf));
|
||||||
|
|
||||||
|
ifc.ifc_len = MAX_INTERFACES*sizeof( struct ifreq );
|
||||||
|
ifc.ifc_buf = buf;
|
||||||
|
|
||||||
|
if ( IoctlSocket( s, SIOCGIFCONF, (char *)&ifc ) < 0 ) {
|
||||||
|
common->FatalError( "InitNetworking: SIOCGIFCONF error - %s\n", strerror( errno ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ifindex = 0;
|
||||||
|
|
||||||
|
common->Printf( "Dumping SIOCGIFCONF data -:\n");
|
||||||
|
|
||||||
|
int var1, var2;
|
||||||
|
for (var1 = 0; var1 < ifc.ifc_len; var1 += 10)
|
||||||
|
{
|
||||||
|
common->Printf( "%p: ", ((caddr_t)&ifc + var1) );
|
||||||
|
for (var2 = 0; var2 < 10; var2 ++)
|
||||||
|
{
|
||||||
|
common->Printf( " %02X", *((char *)((caddr_t)&ifc + var1 + var2)));
|
||||||
|
}
|
||||||
|
common->Printf( "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( ifindex < ifc.ifc_len ) {
|
||||||
|
// find the type - ignore interfaces for which we can find we can't get IP and mask ( not configured )
|
||||||
|
ifr = (struct ifreq *)((caddr_t)ifc.ifc_buf + ifindex );
|
||||||
|
|
||||||
|
common->Printf( "interface @ %p '%s' - ", ifr, ifr->ifr_name );
|
||||||
|
if ( IoctlSocket( s, SIOCGIFADDR, (char *)ifr ) < 0 ) {
|
||||||
|
common->Printf( "SIOCGIFADDR failed: %s\n", strerror( errno ) );
|
||||||
|
} else {
|
||||||
|
if ( ifr->ifr_addr.sa_family != AF_INET ) {
|
||||||
|
common->Printf( "not AF_INET\n" );
|
||||||
|
} else {
|
||||||
|
ip = ntohl( *( unsigned int *)&ifr->ifr_addr.sa_data[2] );
|
||||||
|
if ( ip == INADDR_LOOPBACK ) {
|
||||||
|
common->Printf( "loopback\n" );
|
||||||
|
} else {
|
||||||
|
common->Printf( "%d.%d.%d.%d",
|
||||||
|
(unsigned char)ifr->ifr_addr.sa_data[2],
|
||||||
|
(unsigned char)ifr->ifr_addr.sa_data[3],
|
||||||
|
(unsigned char)ifr->ifr_addr.sa_data[4],
|
||||||
|
(unsigned char)ifr->ifr_addr.sa_data[5] );
|
||||||
|
}
|
||||||
|
if ( IoctlSocket( s, SIOCGIFNETMASK, (char *)ifr ) < 0 ) {
|
||||||
|
common->Printf( " SIOCGIFNETMASK failed: %s\n", strerror( errno ) );
|
||||||
|
} else {
|
||||||
|
mask = ntohl( *( unsigned int *)&ifr->ifr_addr.sa_data[2] );
|
||||||
|
if ( ip != INADDR_LOOPBACK ) {
|
||||||
|
common->Printf( "/%d.%d.%d.%d\n",
|
||||||
|
(unsigned char)ifr->ifr_addr.sa_data[2],
|
||||||
|
(unsigned char)ifr->ifr_addr.sa_data[3],
|
||||||
|
(unsigned char)ifr->ifr_addr.sa_data[4],
|
||||||
|
(unsigned char)ifr->ifr_addr.sa_data[5] );
|
||||||
|
}
|
||||||
|
netint[ num_interfaces ].ip = ip;
|
||||||
|
netint[ num_interfaces ].mask = mask;
|
||||||
|
num_interfaces++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ifindex += sizeof(ifr->ifr_name) +
|
||||||
|
(ifr->ifr_addr.sa_len > sizeof(struct sockaddr)
|
||||||
|
? ifr->ifr_addr.sa_len
|
||||||
|
: sizeof(struct sockaddr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
====================
|
||||||
|
IPSocket
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
static int IPSocket( const char *net_interface, int port, netadr_t *bound_to = NULL ) {
|
||||||
|
int newsocket;
|
||||||
|
struct sockaddr_in address;
|
||||||
|
int i = 1;
|
||||||
|
|
||||||
|
if ( net_interface ) {
|
||||||
|
common->Printf( "Opening IP socket: %s:%i\n", net_interface, port );
|
||||||
|
} else {
|
||||||
|
common->Printf( "Opening IP socket: localhost:%i\n", port );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ( newsocket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == -1 ) {
|
||||||
|
common->Printf( "ERROR: IPSocket: socket: %s", strerror( errno ) );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// make it non-blocking
|
||||||
|
int on = 1;
|
||||||
|
if ( IoctlSocket( newsocket, FIONBIO, (char *)&on ) < 0 ) {
|
||||||
|
common->Printf( "ERROR: IPSocket: ioctl FIONBIO:%s\n",
|
||||||
|
strerror( errno ) );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// make it broadcast capable
|
||||||
|
if ( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, (char *) &i, sizeof(i) ) == -1 ) {
|
||||||
|
common->Printf( "ERROR: IPSocket: setsockopt SO_BROADCAST:%s\n", strerror( errno ) );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !net_interface || !net_interface[ 0 ]
|
||||||
|
|| !idStr::Icmp( net_interface, "localhost" ) ) {
|
||||||
|
address.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
} else {
|
||||||
|
StringToSockaddr( net_interface, &address, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( port == PORT_ANY ) {
|
||||||
|
address.sin_port = 0;
|
||||||
|
} else {
|
||||||
|
address.sin_port = htons((short) port);
|
||||||
|
}
|
||||||
|
|
||||||
|
address.sin_family = AF_INET;
|
||||||
|
|
||||||
|
if ( bind( newsocket, (struct sockaddr *)&address, sizeof( address ) ) == -1 ) {
|
||||||
|
common->Printf( "ERROR: IPSocket: bind: %s\n", strerror( errno ) );
|
||||||
|
CloseSocket( newsocket );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bound_to ) {
|
||||||
|
socklen_t len = sizeof( address );
|
||||||
|
if ( (unsigned int)(getsockname( newsocket, (struct sockaddr *)&address, &len )) == -1 ) {
|
||||||
|
common->Printf( "ERROR: IPSocket: getsockname: %s\n", strerror( errno ) );
|
||||||
|
CloseSocket( newsocket );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SockadrToNetadr( &address, bound_to );
|
||||||
|
}
|
||||||
|
|
||||||
|
return newsocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idPort::idPort
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
idPort::idPort() {
|
||||||
|
netSocket = 0;
|
||||||
|
memset( &bound_to, 0, sizeof( bound_to ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idPort::~idPort
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
idPort::~idPort() {
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idPort::Close
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void idPort::Close() {
|
||||||
|
if ( netSocket ) {
|
||||||
|
CloseSocket(netSocket);
|
||||||
|
netSocket = 0;
|
||||||
|
memset( &bound_to, 0, sizeof( bound_to ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idPort::GetPacket
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
bool idPort::GetPacket( netadr_t &net_from, void *data, int &size, int maxSize ) {
|
||||||
|
int ret;
|
||||||
|
struct sockaddr_in from;
|
||||||
|
socklen_t fromlen;
|
||||||
|
|
||||||
|
if ( !netSocket ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fromlen = sizeof( from );
|
||||||
|
ret = recvfrom( netSocket, data, maxSize, 0, (struct sockaddr *) &from, &fromlen );
|
||||||
|
|
||||||
|
if ( ret == -1 ) {
|
||||||
|
if (errno == EWOULDBLOCK || errno == ECONNREFUSED) {
|
||||||
|
// those commonly happen, don't verbose
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
common->DPrintf( "idPort::GetPacket recvfrom(): %s\n", strerror( errno ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( ret < maxSize );
|
||||||
|
|
||||||
|
SockadrToNetadr( &from, &net_from );
|
||||||
|
size = ret;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idPort::GetPacketBlocking
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
bool idPort::GetPacketBlocking( netadr_t &net_from, void *data, int &size, int maxSize, int timeout ) {
|
||||||
|
fd_set set;
|
||||||
|
struct timeval tv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if ( !netSocket ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( timeout < 0 ) {
|
||||||
|
return GetPacket( net_from, data, size, maxSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
FD_ZERO( &set );
|
||||||
|
FD_SET( netSocket, &set );
|
||||||
|
|
||||||
|
tv.tv_sec = timeout / 1000;
|
||||||
|
tv.tv_usec = ( timeout % 1000 ) * 1000;
|
||||||
|
ret = WaitSelect( netSocket+1, &set, NULL, NULL, &tv, NULL );
|
||||||
|
if ( ret == -1 ) {
|
||||||
|
if ( errno == EINTR ) {
|
||||||
|
common->DPrintf( "idPort::GetPacketBlocking: select EINTR\n" );
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
common->Error( "idPort::GetPacketBlocking: select failed: %s\n", strerror( errno ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ret == 0 ) {
|
||||||
|
// timed out
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
struct sockaddr_in from;
|
||||||
|
socklen_t fromlen;
|
||||||
|
fromlen = sizeof( from );
|
||||||
|
ret = recvfrom( netSocket, data, maxSize, 0, (struct sockaddr *)&from, &fromlen );
|
||||||
|
if ( ret == -1 ) {
|
||||||
|
// there should be no blocking errors once select declares things are good
|
||||||
|
common->DPrintf( "idPort::GetPacketBlocking: %s\n", strerror( errno ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
assert( ret < maxSize );
|
||||||
|
SockadrToNetadr( &from, &net_from );
|
||||||
|
size = ret;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idPort::SendPacket
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void idPort::SendPacket( const netadr_t to, const void *data, int size ) {
|
||||||
|
int ret;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
if ( to.type == NA_BAD ) {
|
||||||
|
common->Warning( "idPort::SendPacket: bad address type NA_BAD - ignored" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !netSocket ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetadrToSockadr( &to, &addr );
|
||||||
|
|
||||||
|
ret = sendto( netSocket, data, size, 0, (struct sockaddr *) &addr, sizeof(addr) );
|
||||||
|
if ( ret == -1 ) {
|
||||||
|
common->Printf( "idPort::SendPacket ERROR: to %s: %s\n", Sys_NetAdrToString( to ), strerror( errno ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idPort::InitForPort
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
bool idPort::InitForPort( int portNumber ) {
|
||||||
|
netSocket = IPSocket( net_ip.GetString(), portNumber, &bound_to );
|
||||||
|
if ( netSocket <= 0 ) {
|
||||||
|
netSocket = 0;
|
||||||
|
memset( &bound_to, 0, sizeof( bound_to ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idTCP::idTCP
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
idTCP::idTCP() {
|
||||||
|
fd = 0;
|
||||||
|
memset(&address, 0, sizeof(address));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idTCP::~idTCP
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
idTCP::~idTCP() {
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idTCP::Init
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
bool idTCP::Init( const char *host, short port ) {
|
||||||
|
struct sockaddr_in sadr;
|
||||||
|
if ( !Sys_StringToNetAdr( host, &address, true ) ) {
|
||||||
|
common->Printf( "Couldn't resolve server name \"%s\"\n", host );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
address.type = NA_IP;
|
||||||
|
if (!address.port) {
|
||||||
|
address.port = port;
|
||||||
|
}
|
||||||
|
common->Printf( "\"%s\" resolved to %i.%i.%i.%i:%i\n", host,
|
||||||
|
address.ip[0], address.ip[1], address.ip[2], address.ip[3], address.port );
|
||||||
|
NetadrToSockadr(&address, &sadr);
|
||||||
|
|
||||||
|
if (fd) {
|
||||||
|
common->Warning("idTCP::Init: already initialized?\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
|
||||||
|
fd = 0;
|
||||||
|
common->Printf("ERROR: idTCP::Init: socket: %s\n", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( connect( fd, (sockaddr *)&sadr, sizeof( sadr ) ) == -1 ) {
|
||||||
|
common->Printf( "ERROR: idTCP::Init: connect: %s\n", strerror( errno ) );
|
||||||
|
CloseSocket( fd );
|
||||||
|
fd = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int status;
|
||||||
|
if ((status = fcntl(fd, F_GETFL, 0)) != -1) {
|
||||||
|
status |= O_NONBLOCK; /* POSIX */
|
||||||
|
status = fcntl(fd, F_SETFL, status);
|
||||||
|
}
|
||||||
|
if (status == -1) {
|
||||||
|
common->Printf("ERROR: idTCP::Init: fcntl / O_NONBLOCK: %s\n", strerror(errno));
|
||||||
|
CloseSocket(fd);
|
||||||
|
fd = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
common->DPrintf("Opened TCP connection\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idTCP::Close
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void idTCP::Close() {
|
||||||
|
if (fd) {
|
||||||
|
CloseSocket(fd);
|
||||||
|
}
|
||||||
|
fd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idTCP::Read
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
int idTCP::Read(void *data, int size) {
|
||||||
|
int nbytes;
|
||||||
|
|
||||||
|
if (!fd) {
|
||||||
|
common->Printf("idTCP::Read: not initialized\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
nbytes = recv( fd, data, size, 0 );
|
||||||
|
} while ( nbytes == -1 && errno == EINTR );
|
||||||
|
if ( nbytes == -1 ) {
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
common->Printf("ERROR: idTCP::Read: %s\n", strerror(errno));
|
||||||
|
Close();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a successful read of 0 bytes indicates remote has closed the connection
|
||||||
|
if ( nbytes == 0 ) {
|
||||||
|
common->DPrintf( "idTCP::Read: read 0 bytes - assume connection closed\n" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
idTCP::Write
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void got_SIGPIPE( int signum ) {
|
||||||
|
common->Printf( "idTCP: SIGPIPE\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
int idTCP::Write(void *data, int size) {
|
||||||
|
int nbytes;
|
||||||
|
|
||||||
|
if ( !fd ) {
|
||||||
|
common->Printf( "idTCP::Write: not initialized\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sigaction bak_action;
|
||||||
|
struct sigaction action;
|
||||||
|
|
||||||
|
action.sa_handler = got_SIGPIPE;
|
||||||
|
sigemptyset( &action.sa_mask );
|
||||||
|
action.sa_flags = 0;
|
||||||
|
|
||||||
|
if ( sigaction( SIGPIPE, &action, &bak_action ) != 0 ) {
|
||||||
|
common->Printf( "ERROR: idTCP::Write: failed to set temporary SIGPIPE handler\n" );
|
||||||
|
Close();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
nbytes = send( fd, data, size, 0 );
|
||||||
|
} while ( nbytes == -1 && errno == EINTR );
|
||||||
|
if ( nbytes == -1 ) {
|
||||||
|
common->Printf( "ERROR: idTCP::Write: %s\n", strerror( errno ) );
|
||||||
|
Close();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( sigaction( SIGPIPE, &bak_action, NULL ) != 0 ) {
|
||||||
|
common->Printf( "ERROR: idTCP::Write: failed to reset SIGPIPE handler\n" );
|
||||||
|
Close();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nbytes;
|
||||||
|
}
|
59
neo/sys/aros/aros_public.h
Normal file
59
neo/sys/aros/aros_public.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 GPL Source Code
|
||||||
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
||||||
|
|
||||||
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SYS_AROS__
|
||||||
|
#define __SYS_AROS__
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "sys/sys_public.h"
|
||||||
|
|
||||||
|
const char* AROS_Cwd( void );
|
||||||
|
|
||||||
|
// called first thing. does InitSigs and various things
|
||||||
|
void AROS_EarlyInit( );
|
||||||
|
// called after common has been initialized
|
||||||
|
void AROS_LateInit( );
|
||||||
|
|
||||||
|
void AROS_InitLibs( );
|
||||||
|
void AROS_InitSigs( );
|
||||||
|
void AROS_ClearSigs( );
|
||||||
|
|
||||||
|
void AROS_Exit( int ret );
|
||||||
|
void AROS_SetExit(int ret); // override the exit code
|
||||||
|
void AROS_SetExitSpawn( const char *exeName ); // set the process to be spawned when we quit
|
||||||
|
|
||||||
|
void AROS_InitConsoleInput( void );
|
||||||
|
void AROS_Shutdown( void );
|
||||||
|
|
||||||
|
void AROS_OpenURL( const char *url );
|
||||||
|
|
||||||
|
void Sys_FPE_handler( int signum, siginfo_t *info, void *context );
|
||||||
|
void Sys_DoStartProcess( const char *exeName, bool dofork = true ); // if not forking, current process gets replaced
|
||||||
|
|
||||||
|
#endif
|
174
neo/sys/aros/aros_signal.cpp
Normal file
174
neo/sys/aros/aros_signal.cpp
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 GPL Source Code
|
||||||
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
||||||
|
|
||||||
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "sys/platform.h"
|
||||||
|
#include "framework/Common.h"
|
||||||
|
|
||||||
|
#include "sys/aros/aros_public.h"
|
||||||
|
|
||||||
|
const int siglist[] = {
|
||||||
|
SIGHUP,
|
||||||
|
SIGQUIT,
|
||||||
|
SIGILL,
|
||||||
|
SIGTRAP,
|
||||||
|
#if !defined(__AROS__)
|
||||||
|
SIGIOT,
|
||||||
|
#endif
|
||||||
|
SIGBUS,
|
||||||
|
SIGFPE,
|
||||||
|
SIGSEGV,
|
||||||
|
SIGPIPE,
|
||||||
|
SIGABRT,
|
||||||
|
// SIGTTIN,
|
||||||
|
// SIGTTOU,
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *signames[] = {
|
||||||
|
"SIGHUP",
|
||||||
|
"SIGQUIT",
|
||||||
|
"SIGILL",
|
||||||
|
"SIGTRAP",
|
||||||
|
#if !defined(__AROS__)
|
||||||
|
"SIGIOT",
|
||||||
|
#endif
|
||||||
|
"SIGBUS",
|
||||||
|
"SIGFPE",
|
||||||
|
"SIGSEGV",
|
||||||
|
"SIGPIPE",
|
||||||
|
"SIGABRT",
|
||||||
|
// "SIGTTIN",
|
||||||
|
// "SIGTTOUT"
|
||||||
|
};
|
||||||
|
|
||||||
|
static char fatalError[ 1024 ];
|
||||||
|
|
||||||
|
#if defined(__AROS__)
|
||||||
|
#define strsignal(x) signames[x]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
AROS_ClearSigs
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void AROS_ClearSigs( ) {
|
||||||
|
struct sigaction action;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Set up the structure */
|
||||||
|
action.sa_handler = SIG_DFL;
|
||||||
|
sigemptyset( &action.sa_mask );
|
||||||
|
action.sa_flags = 0;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while ( siglist[ i ] != -1 ) {
|
||||||
|
if ( sigaction( siglist[ i ], &action, NULL ) != 0 ) {
|
||||||
|
Sys_Printf( "Failed to reset %s handler: %s\n", signames[ i ], strerror( errno ) );
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
sig_handler
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
static void sig_handler( int signum, siginfo_t *info, void *context ) {
|
||||||
|
static bool double_fault = false;
|
||||||
|
|
||||||
|
if ( double_fault ) {
|
||||||
|
Sys_Printf( "double fault %s, bailing out\n", strsignal( signum ) );
|
||||||
|
_exit( signum );
|
||||||
|
}
|
||||||
|
|
||||||
|
double_fault = true;
|
||||||
|
|
||||||
|
// NOTE: see sigaction man page, could verbose the whole siginfo_t and print human readable si_code
|
||||||
|
Sys_Printf( "signal caught: %s\nsi_code %d\n", strsignal( signum ), info->si_code );
|
||||||
|
|
||||||
|
if ( fatalError[ 0 ] ) {
|
||||||
|
Sys_Printf( "Was in fatal error shutdown: %s\n", fatalError );
|
||||||
|
}
|
||||||
|
|
||||||
|
Sys_Printf( "Trying to exit gracefully..\n" );
|
||||||
|
|
||||||
|
AROS_SetExit( signum );
|
||||||
|
|
||||||
|
common->Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
AROS_InitSigs
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void AROS_InitSigs( ) {
|
||||||
|
struct sigaction action;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
fatalError[0] = '\0';
|
||||||
|
|
||||||
|
/* Set up the structure */
|
||||||
|
action.sa_sigaction = sig_handler;
|
||||||
|
sigemptyset( &action.sa_mask );
|
||||||
|
action.sa_flags = SA_SIGINFO | SA_NODEFER;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while ( siglist[ i ] != -1 ) {
|
||||||
|
if ( siglist[ i ] == SIGFPE ) {
|
||||||
|
action.sa_sigaction = Sys_FPE_handler;
|
||||||
|
if ( sigaction( siglist[ i ], &action, NULL ) != 0 ) {
|
||||||
|
Sys_Printf( "Failed to set SIGFPE handler: %s\n", strerror( errno ) );
|
||||||
|
}
|
||||||
|
action.sa_sigaction = sig_handler;
|
||||||
|
} else if ( sigaction( siglist[ i ], &action, NULL ) != 0 ) {
|
||||||
|
Sys_Printf( "Failed to set %s handler: %s\n", signames[ i ], strerror( errno ) );
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the process is backgrounded (running non interactively)
|
||||||
|
// then SIGTTIN or SIGTOU could be emitted, if not caught, turns into a SIGSTP
|
||||||
|
signal( SIGTTIN, SIG_IGN );
|
||||||
|
signal( SIGTTOU, SIG_IGN );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_SetFatalError
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void Sys_SetFatalError( const char *error ) {
|
||||||
|
strncpy( fatalError, error, sizeof( fatalError ) );
|
||||||
|
}
|
368
neo/sys/aros/dll/dll.c
Normal file
368
neo/sys/aros/dll/dll.c
Normal file
|
@ -0,0 +1,368 @@
|
||||||
|
/*
|
||||||
|
** This file contains the runtime usable DLL functions, like LoadLibrary, GetProcAddress etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
|
||||||
|
#include <aros/debug.h>
|
||||||
|
|
||||||
|
#define __DLL_LIB_BUILD
|
||||||
|
|
||||||
|
#include "dll.h"
|
||||||
|
#include <dos/dos.h>
|
||||||
|
#include <dos/dostags.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#include <proto/dos.h>
|
||||||
|
|
||||||
|
void dllInternalFreeLibrary(int);
|
||||||
|
|
||||||
|
#define DLLOPENDLLS_MAX 20
|
||||||
|
static int dllsopened = 0;
|
||||||
|
|
||||||
|
struct dllOpenedDLL
|
||||||
|
{
|
||||||
|
struct dll_sInstance *inst;
|
||||||
|
int usecount;
|
||||||
|
char name[100];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dllOpenedDLL dllOpenedDLLs[DLLOPENDLLS_MAX]; //Maybe better use a linked list, but should work for now
|
||||||
|
|
||||||
|
void dllCleanup()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
bug("[DynLink] %s()\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
for(i=0;i<DLLOPENDLLS_MAX;i++)
|
||||||
|
if(dllOpenedDLLs[i].inst)
|
||||||
|
dllInternalFreeLibrary(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *dllLoadLibrary(char *filename,char *portname)
|
||||||
|
{
|
||||||
|
int (*Entry)(void *, long, void *);
|
||||||
|
void *hinst;
|
||||||
|
|
||||||
|
bug("[DynLink] %s('%s','%s')\n", __PRETTY_FUNCTION__, filename, portname);
|
||||||
|
|
||||||
|
hinst = dllInternalLoadLibrary(filename, portname, 1L);
|
||||||
|
|
||||||
|
if (!hinst) return NULL;
|
||||||
|
|
||||||
|
// Check for an entry point
|
||||||
|
Entry = dllGetProcAddress(hinst, "DllEntryPoint");
|
||||||
|
if (Entry)
|
||||||
|
{
|
||||||
|
int ret = Entry(hinst, 0, NULL);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
// if we get non-null here, assume the initialisation worked
|
||||||
|
return hinst;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// the entry point reported an error
|
||||||
|
dllFreeLibrary(hinst);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hinst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *dllInternalLoadLibrary(char *filename,char *portname,int raiseusecount)
|
||||||
|
{
|
||||||
|
struct dll_sInstance *inst;
|
||||||
|
struct MsgPort *dllport;
|
||||||
|
struct MsgPort *myport;
|
||||||
|
dll_tMessage msg,*reply;
|
||||||
|
static int cleanupflag=0;
|
||||||
|
BPTR handle;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
bug("[DynLink] %s('%s','%s')\n", __PRETTY_FUNCTION__, filename, portname);
|
||||||
|
|
||||||
|
if(!cleanupflag)
|
||||||
|
{
|
||||||
|
bzero(&dllOpenedDLLs, sizeof(dllOpenedDLLs));
|
||||||
|
|
||||||
|
if(atexit((void *)dllCleanup))
|
||||||
|
return 0L;
|
||||||
|
else
|
||||||
|
cleanupflag=1L;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!filename)
|
||||||
|
return 0L; //Paranoia
|
||||||
|
|
||||||
|
if(!(handle=Open(filename, MODE_OLDFILE)))
|
||||||
|
return 0L;
|
||||||
|
|
||||||
|
Close(handle);
|
||||||
|
|
||||||
|
if(!portname)
|
||||||
|
portname=filename;
|
||||||
|
|
||||||
|
// Search for already opened DLLs
|
||||||
|
for(i=0;i<DLLOPENDLLS_MAX;i++)
|
||||||
|
{
|
||||||
|
if(dllOpenedDLLs[i].inst)
|
||||||
|
{
|
||||||
|
if(strcmp(dllOpenedDLLs[i].name,portname)==0)
|
||||||
|
{
|
||||||
|
if(raiseusecount)
|
||||||
|
dllOpenedDLLs[i].usecount++;
|
||||||
|
return dllOpenedDLLs[i].inst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bug("[DynLink] %s: not opened yet\n", __PRETTY_FUNCTION__);
|
||||||
|
// Not opened yet, search for a free slot
|
||||||
|
|
||||||
|
for(i=0;i<DLLOPENDLLS_MAX;i++)
|
||||||
|
if(!dllOpenedDLLs[i].inst)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(i==DLLOPENDLLS_MAX)
|
||||||
|
return 0L; // No free slot available
|
||||||
|
|
||||||
|
bug("[DynLink] %s: using slot %u\n", __PRETTY_FUNCTION__, i);
|
||||||
|
|
||||||
|
if(!(inst=malloc(sizeof(struct dll_sInstance))))
|
||||||
|
return 0L;
|
||||||
|
|
||||||
|
bug("[DynLink] %s: instance @ 0x%p\n", __PRETTY_FUNCTION__, inst);
|
||||||
|
|
||||||
|
if(!(myport=CreateMsgPort()))
|
||||||
|
{
|
||||||
|
free(inst);
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
bug("[DynLink] %s: port @ 0x%p\n", __PRETTY_FUNCTION__, myport);
|
||||||
|
|
||||||
|
if(!(dllport=FindPort(portname)))
|
||||||
|
{
|
||||||
|
BPTR output = Open("CON:0/0/800/600/DLL_OUTPUT/AUTO/CLOSE/WAIT", MODE_NEWFILE);
|
||||||
|
char commandline[1024];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sprintf(commandline,"\"%s\" \"%s\"", filename, portname);
|
||||||
|
|
||||||
|
bug("[DynLink] %s: calling '%s', output @ 0x%p\n", __PRETTY_FUNCTION__, commandline, output);
|
||||||
|
|
||||||
|
SystemTags(commandline,
|
||||||
|
SYS_Asynch, TRUE,
|
||||||
|
SYS_Output, output,
|
||||||
|
SYS_Input, NULL, //FIXME: some dll's might need stdin
|
||||||
|
NP_StackSize, 10000, //Messagehandler doesn't need a big stack (FIXME: but DLL_(De)Init might)
|
||||||
|
TAG_DONE);
|
||||||
|
|
||||||
|
bug("[DynLink] %s: waiting for load ...\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
for (i=0; i<20; i++)
|
||||||
|
{
|
||||||
|
dllport = FindPort(portname);
|
||||||
|
if (dllport) break;
|
||||||
|
//printf("Delaying...\n");
|
||||||
|
Delay(25L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!dllport)
|
||||||
|
{
|
||||||
|
DeleteMsgPort(myport);
|
||||||
|
free(inst);
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
bug("[DynLink] %s: found port for '%s' @ 0x%p\n", __PRETTY_FUNCTION__, portname, dllport);
|
||||||
|
|
||||||
|
inst->dllPort=dllport;
|
||||||
|
inst->StackType=DLLSTACK_DEFAULT;
|
||||||
|
|
||||||
|
bzero(&msg, sizeof(msg));
|
||||||
|
|
||||||
|
msg.dllMessageType=DLLMTYPE_Open;
|
||||||
|
msg.dllMessageData.dllOpen.StackType = inst->StackType;
|
||||||
|
|
||||||
|
msg.Message.mn_ReplyPort = myport;
|
||||||
|
PutMsg(dllport, (struct Message *)&msg);
|
||||||
|
WaitPort(myport);
|
||||||
|
reply=(dll_tMessage *)GetMsg(myport);
|
||||||
|
|
||||||
|
if (reply)
|
||||||
|
{
|
||||||
|
if(reply->dllMessageData.dllOpen.ErrorCode!=DLLERR_NoError)
|
||||||
|
{
|
||||||
|
DeleteMsgPort(myport);
|
||||||
|
free(inst);
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Obligatory symbol exports
|
||||||
|
inst->FindResource = dllGetProcAddress(inst,"dllFindResource");
|
||||||
|
inst->LoadResource = dllGetProcAddress(inst,"dllLoadResource");
|
||||||
|
inst->FreeResource = dllGetProcAddress(inst,"dllFreeResource");
|
||||||
|
|
||||||
|
if((inst->FindResource==0L)||
|
||||||
|
(inst->LoadResource==0L)||
|
||||||
|
(inst->FreeResource==0L))
|
||||||
|
{
|
||||||
|
DeleteMsgPort(myport);
|
||||||
|
dllOpenedDLLs[i].inst=inst;
|
||||||
|
dllInternalFreeLibrary(i);
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//FIXME: Must/Can I send a Close message here ??
|
||||||
|
DeleteMsgPort(myport);
|
||||||
|
free(inst);
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteMsgPort(myport);
|
||||||
|
|
||||||
|
dllOpenedDLLs[i].inst=inst;
|
||||||
|
dllOpenedDLLs[i].usecount=1;
|
||||||
|
strcpy(dllOpenedDLLs[i].name,portname);
|
||||||
|
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dllFreeLibrary(void *hinst)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
bug("[DynLink] %s(0x%p)\n", __PRETTY_FUNCTION__, hinst);
|
||||||
|
|
||||||
|
for(i=0;i<DLLOPENDLLS_MAX;i++)
|
||||||
|
if(dllOpenedDLLs[i].inst==hinst)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(i==DLLOPENDLLS_MAX)
|
||||||
|
return; // ?????
|
||||||
|
|
||||||
|
dllOpenedDLLs[i].usecount--;
|
||||||
|
|
||||||
|
if(dllOpenedDLLs[i].usecount<=0)
|
||||||
|
dllInternalFreeLibrary(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dllInternalFreeLibrary(int i)
|
||||||
|
{
|
||||||
|
dll_tMessage msg,*reply;
|
||||||
|
struct MsgPort *myport;
|
||||||
|
struct dll_sInstance *inst=(struct dll_sInstance *) dllOpenedDLLs[i].inst;
|
||||||
|
|
||||||
|
bug("[DynLink] %s(%u)\n", __PRETTY_FUNCTION__, i);
|
||||||
|
|
||||||
|
if(!inst)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!(myport=CreateMsgPort()))
|
||||||
|
{
|
||||||
|
exit(0L); //Arghh
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero(&msg, sizeof(msg));
|
||||||
|
|
||||||
|
msg.dllMessageType=DLLMTYPE_Close;
|
||||||
|
|
||||||
|
msg.Message.mn_ReplyPort = myport;
|
||||||
|
|
||||||
|
if(FindPort(dllOpenedDLLs[i].name)==inst->dllPort)
|
||||||
|
{
|
||||||
|
PutMsg(inst->dllPort, (struct Message *)&msg);
|
||||||
|
/*WaitPort(myport);*/
|
||||||
|
while(!(reply=(dll_tMessage *)GetMsg(myport)))
|
||||||
|
{
|
||||||
|
Delay(2);
|
||||||
|
if(FindPort(dllOpenedDLLs[i].name)!=inst->dllPort)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteMsgPort(myport);
|
||||||
|
free(inst);
|
||||||
|
|
||||||
|
bzero(&dllOpenedDLLs[i],sizeof(dllOpenedDLLs[i]));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *dllGetProcAddress(void *hinst,char *name)
|
||||||
|
{
|
||||||
|
dll_tMessage msg,*reply;
|
||||||
|
struct MsgPort *myport;
|
||||||
|
struct dll_sInstance *inst=(struct dll_sInstance *) hinst;
|
||||||
|
void *sym;
|
||||||
|
|
||||||
|
bug("[DynLink] %s(0x%p, '%s')\n", __PRETTY_FUNCTION__, hinst, name);
|
||||||
|
|
||||||
|
if(!hinst)
|
||||||
|
return 0L;
|
||||||
|
|
||||||
|
if(!(myport=CreateMsgPort()))
|
||||||
|
{
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero(&msg, sizeof(msg));
|
||||||
|
|
||||||
|
msg.dllMessageType=DLLMTYPE_SymbolQuery;
|
||||||
|
msg.dllMessageData.dllSymbolQuery.StackType=inst->StackType;
|
||||||
|
msg.dllMessageData.dllSymbolQuery.SymbolName=name;
|
||||||
|
msg.dllMessageData.dllSymbolQuery.SymbolPointer=&sym;
|
||||||
|
|
||||||
|
msg.Message.mn_ReplyPort = myport;
|
||||||
|
PutMsg(inst->dllPort, (struct Message *)&msg);
|
||||||
|
WaitPort(myport);
|
||||||
|
reply=(dll_tMessage *)GetMsg(myport);
|
||||||
|
|
||||||
|
DeleteMsgPort(myport);
|
||||||
|
|
||||||
|
if(reply)
|
||||||
|
return(sym);
|
||||||
|
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dllKillLibrary(char *portname)
|
||||||
|
{
|
||||||
|
dll_tMessage msg,*reply;
|
||||||
|
struct MsgPort *myport;
|
||||||
|
struct MsgPort *dllport;
|
||||||
|
|
||||||
|
bug("[DynLink] %s('%s')\n", __PRETTY_FUNCTION__, portname);
|
||||||
|
|
||||||
|
if(!(myport=CreateMsgPort()))
|
||||||
|
exit(0L); //Arghh
|
||||||
|
|
||||||
|
bzero(&msg, sizeof(msg));
|
||||||
|
|
||||||
|
msg.dllMessageType=DLLMTYPE_Kill;
|
||||||
|
|
||||||
|
msg.Message.mn_ReplyPort = myport;
|
||||||
|
|
||||||
|
if((dllport=FindPort(portname)))
|
||||||
|
{
|
||||||
|
PutMsg(dllport, (struct Message *)&msg);
|
||||||
|
/*WaitPort(myport);*/
|
||||||
|
while(!(reply=(dll_tMessage *)GetMsg(myport)))
|
||||||
|
{
|
||||||
|
Delay(2);
|
||||||
|
if(FindPort(portname)!=dllport)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteMsgPort(myport);
|
||||||
|
|
||||||
|
return (dllport?1:0);
|
||||||
|
}
|
212
neo/sys/aros/dll/dll.h
Normal file
212
neo/sys/aros/dll/dll.h
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
#ifndef __DLL_H
|
||||||
|
#define __DLL_H
|
||||||
|
|
||||||
|
#ifdef __DLL_LIB_BUILD
|
||||||
|
#include <exec/exec.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* External structures
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
typedef struct dll_sExportSymbol
|
||||||
|
{
|
||||||
|
void * SymbolAddress;
|
||||||
|
char * SymbolName;
|
||||||
|
} dll_tExportSymbol;
|
||||||
|
|
||||||
|
typedef struct dll_sImportSymbol
|
||||||
|
{
|
||||||
|
void ** SymbolPointer;
|
||||||
|
char * SymbolName;
|
||||||
|
char * DLLFileName;
|
||||||
|
char * DLLPortName;
|
||||||
|
} dll_tImportSymbol;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int dllImportSymbols(void);
|
||||||
|
void * dllLoadLibrary(char *name,char *portname);
|
||||||
|
void dllFreeLibrary(void *hinst);
|
||||||
|
void * dllGetProcAddress(void *hinst,char *name);
|
||||||
|
int dllKillLibrary(char *portname);
|
||||||
|
|
||||||
|
int DLL_Init(void);
|
||||||
|
void DLL_DeInit(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prototypes for DLL implementations
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern dll_tExportSymbol DLL_ExportSymbols[];
|
||||||
|
extern dll_tImportSymbol DLL_ImportSymbols[];
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Internal structures
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
void *dllInternalLoadLibrary(char *filename,char *portname,int raiseusecount);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Typedefs for function vectors.
|
||||||
|
** Any DLL implementor must deliver these functions.
|
||||||
|
*/
|
||||||
|
typedef void* (*dll_tFindResourceFn)(int, char*);
|
||||||
|
typedef void* (*dll_tLoadResourceFn)(void*);
|
||||||
|
typedef void (*dll_tFreeResourceFn)(void*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The stack type the application using the DLL prefers.
|
||||||
|
** If there is no support for this type in your DLL, return
|
||||||
|
** DLLERR_StackNotSupported.
|
||||||
|
**
|
||||||
|
** Implementation note: In the startup code, return different
|
||||||
|
** function pointers depending on the stack frame. This is
|
||||||
|
** the preferred method. Some of the stack frames might be
|
||||||
|
** identical, for example, since there is not UBYTE passing
|
||||||
|
** on the stack for the different DLL interface functions,
|
||||||
|
** using the same stack from for all 68k stack types is safe.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DLLSTACK_STORM = 0x01, // 68k, StormC
|
||||||
|
DLLSTACK_EGCS = 0x02, // 68k, GCC or egcs
|
||||||
|
DLLSTACK_SAS = 0x04, // 68k, SAS/C
|
||||||
|
DLLSTACK_VBCC = 0x08, // 68k, vbcc
|
||||||
|
DLLSTACK_POWEROPEN = 0x10, // PPC, StormC or vbcc
|
||||||
|
DLLSTACK_SYSV = 0x20 // PPC, egcs
|
||||||
|
//..
|
||||||
|
} dll_tStackType;
|
||||||
|
|
||||||
|
#ifdef __STORM__
|
||||||
|
#ifdef __PPC__
|
||||||
|
#define DLLSTACK_DEFAULT DLLSTACK_POWEROPEN
|
||||||
|
#else
|
||||||
|
#define DLLSTACK_DEFAULT DLLSTACK_STORM
|
||||||
|
#endif
|
||||||
|
#else //not Storm
|
||||||
|
#ifdef __VBCC__
|
||||||
|
#ifdef __PPC__
|
||||||
|
#define DLLSTACK_DEFAULT DLLSTACK_POWEROPEN
|
||||||
|
#else
|
||||||
|
#define DLLSTACK_DEFAULT DLLSTACK_VBCC
|
||||||
|
#endif
|
||||||
|
#else //not VBCC
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#ifdef __PPC
|
||||||
|
#define DLLSTACK_DEFAULT DLLSTACK_SYSV
|
||||||
|
#else
|
||||||
|
#define DLLSTACK_DEFAULT DLLSTACK_EGCS
|
||||||
|
#endif
|
||||||
|
#else //not GCC
|
||||||
|
#ifdef __SASC__
|
||||||
|
#define DLLSTACK_DEFAULT DLLSTACK_SAS
|
||||||
|
#endif
|
||||||
|
#endif //GCC
|
||||||
|
#endif //VBCC
|
||||||
|
#endif //STORMC
|
||||||
|
|
||||||
|
#ifdef __DLL_LIB_BUILD
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DLLERR_NoError = 0, // No error occured
|
||||||
|
DLLERR_StackNotSupported = 1, // Illegal stack frame
|
||||||
|
DLLERR_OutOfMemory = 2 // Init failed due to memory shortage
|
||||||
|
} dll_tErrorCode;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DLLMTYPE_Open = 0,
|
||||||
|
DLLMTYPE_Close = 1,
|
||||||
|
DLLMTYPE_SymbolQuery = 2,
|
||||||
|
DLLMTYPE_Kill = 3
|
||||||
|
} dll_tMessageType;
|
||||||
|
|
||||||
|
typedef struct dll_sSymbolQuery
|
||||||
|
{
|
||||||
|
// Preferred stack type of the main program
|
||||||
|
dll_tStackType StackType;
|
||||||
|
|
||||||
|
// Name of the Symbol
|
||||||
|
char * SymbolName;
|
||||||
|
|
||||||
|
// Where to put the Symbol Address
|
||||||
|
void ** SymbolPointer;
|
||||||
|
} dll_tSymbolQuery;
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
typedef struct dll_sMessage
|
||||||
|
{
|
||||||
|
// Message for sending
|
||||||
|
struct Message Message;
|
||||||
|
|
||||||
|
dll_tMessageType dllMessageType;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
// Preferred stack type of the main program
|
||||||
|
dll_tStackType StackType;
|
||||||
|
|
||||||
|
// Initialization error code
|
||||||
|
dll_tErrorCode ErrorCode;
|
||||||
|
} dllOpen;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
//Empty for now
|
||||||
|
} dllClose;
|
||||||
|
|
||||||
|
dll_tSymbolQuery dllSymbolQuery;
|
||||||
|
|
||||||
|
} dllMessageData;
|
||||||
|
|
||||||
|
// ... Might grow
|
||||||
|
} dll_tMessage;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This structure is returned by the LoadLibrary() call. It is strictly
|
||||||
|
** Off-Limits for both the caller and the DLL but rather used internally
|
||||||
|
** to for tracking resources and other stuff for the DLL. This structure
|
||||||
|
** may change at any time.
|
||||||
|
*/
|
||||||
|
struct dll_sInstance
|
||||||
|
{
|
||||||
|
struct MsgPort *dllPort;
|
||||||
|
dll_tStackType StackType;
|
||||||
|
dll_tFindResourceFn FindResource;
|
||||||
|
dll_tLoadResourceFn LoadResource;
|
||||||
|
dll_tFreeResourceFn FreeResource;
|
||||||
|
// ... Might grow
|
||||||
|
};
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Misc
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DLL_LIB_BUILD
|
||||||
|
|
||||||
|
#ifndef HINSTANCE
|
||||||
|
typedef void * HINSTANCE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#ifdef __PPC
|
||||||
|
#define __saveds
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
50
neo/sys/aros/dll/dllglue.c
Normal file
50
neo/sys/aros/dll/dllglue.c
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
** This file contains glue linked into the "shared" object
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
|
||||||
|
#include <aros/debug.h>
|
||||||
|
#include <exec/types.h>
|
||||||
|
|
||||||
|
#include "sys/aros/dll/dll.h"
|
||||||
|
|
||||||
|
extern void *GetGameAPI(void *);
|
||||||
|
|
||||||
|
void* dllFindResource(int id, char *pType)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* dllLoadResource(void *pHandle)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dllFreeResource(void *pHandle)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dll_tExportSymbol DLL_ExportSymbols[] =
|
||||||
|
{
|
||||||
|
{dllFindResource, "dllFindResource"},
|
||||||
|
{dllLoadResource, "dllLoadResource"},
|
||||||
|
{dllFreeResource, "dllFreeResource"},
|
||||||
|
{(void *)GetGameAPI, "GetGameAPI"},
|
||||||
|
{0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
dll_tImportSymbol DLL_ImportSymbols[] =
|
||||||
|
{
|
||||||
|
{0,0,0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
int DLL_Init(void)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DLL_DeInit(void)
|
||||||
|
{
|
||||||
|
}
|
37
neo/sys/aros/dll/dllimport.c
Normal file
37
neo/sys/aros/dll/dllimport.c
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
** This file handles the implicit (loadtime) imports.
|
||||||
|
** For a DLL its called automatically but a normal executable must call it manually
|
||||||
|
** if it wants to import symbols from a DLL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __DLL_LIB_BUILD
|
||||||
|
|
||||||
|
#include "dll.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int dllImportSymbols()
|
||||||
|
{
|
||||||
|
dll_tImportSymbol *symtable=DLL_ImportSymbols; //reference caller's import symbol table
|
||||||
|
|
||||||
|
while(symtable->SymbolPointer) //End of table ??
|
||||||
|
{
|
||||||
|
void *sym;
|
||||||
|
void *h=dllInternalLoadLibrary(symtable->DLLFileName,symtable->DLLPortName,0L);
|
||||||
|
|
||||||
|
if(!h)
|
||||||
|
return 0L;
|
||||||
|
|
||||||
|
sym=dllGetProcAddress(h,symtable->SymbolName);
|
||||||
|
|
||||||
|
if(!sym)
|
||||||
|
return 0L;
|
||||||
|
|
||||||
|
*symtable->SymbolPointer=sym;
|
||||||
|
|
||||||
|
symtable++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 1L; //Success
|
||||||
|
}
|
177
neo/sys/aros/dll/dllstartup.c
Normal file
177
neo/sys/aros/dll/dllstartup.c
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
/* DLL Startup function
|
||||||
|
* This file gets linked in when the user does not define a main function
|
||||||
|
* that is, if he wants to compile a dll
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
|
||||||
|
#include <aros/debug.h>
|
||||||
|
|
||||||
|
#define __DLL_LIB_BUILD
|
||||||
|
|
||||||
|
#include <exec/exec.h>
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#include <proto/dos.h>
|
||||||
|
#include <clib/alib_protos.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "dll.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only DLL's can export symbols so this function is defined here.
|
||||||
|
* Note that on the other hand normal executables *can* have a symbolimport table,
|
||||||
|
* so dllImportSymbols is defined elsewhere.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void dllExportSymbol(dll_tSymbolQuery *sym)
|
||||||
|
{
|
||||||
|
dll_tExportSymbol *symtable=DLL_ExportSymbols; //reference DLL's export symbol table
|
||||||
|
|
||||||
|
if(!sym->SymbolPointer)
|
||||||
|
return; //Paranoia
|
||||||
|
|
||||||
|
while(symtable->SymbolAddress) //End of table ??
|
||||||
|
{
|
||||||
|
if(strcmp(symtable->SymbolName,sym->SymbolName)==0)
|
||||||
|
{
|
||||||
|
//FIXME: Stackframe handling
|
||||||
|
*sym->SymbolPointer=symtable->SymbolAddress;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
symtable++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*sym->SymbolPointer=0L; //Symbol not found
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The actual main function of a DLL
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct MsgPort *myport;
|
||||||
|
char PortName[255];
|
||||||
|
dll_tMessage *msg;
|
||||||
|
int expunge=0L;
|
||||||
|
int opencount=0L;
|
||||||
|
|
||||||
|
bug("[DynFile] %s('%s')\n", __PRETTY_FUNCTION__, argv[0]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If an argument was passed, use it as the port name,
|
||||||
|
* otherwise use the program name
|
||||||
|
*/
|
||||||
|
if (argc>1)
|
||||||
|
{
|
||||||
|
char *argPort = argv[1];
|
||||||
|
|
||||||
|
if (argPort[0] == '"')
|
||||||
|
strncpy(PortName, &argPort[1], strlen(argPort) - 2);
|
||||||
|
else
|
||||||
|
strcpy(PortName, argPort);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(PortName, argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bug("[DynFile] %s: Portname '%s'\n", __PRETTY_FUNCTION__, PortName);
|
||||||
|
/*
|
||||||
|
* Process symbol import table
|
||||||
|
*/
|
||||||
|
if(!dllImportSymbols())
|
||||||
|
exit(0L);
|
||||||
|
|
||||||
|
bug("[DynFile] %s: symbols imported\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call DLL specific constructor
|
||||||
|
*/
|
||||||
|
if(!DLL_Init())
|
||||||
|
exit(0L);
|
||||||
|
|
||||||
|
bug("[DynFile] %s: initialised\n", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a (public) message port
|
||||||
|
*/
|
||||||
|
myport = CreatePort(PortName,0);
|
||||||
|
if (!myport)
|
||||||
|
exit(0l);
|
||||||
|
|
||||||
|
bug("[DynFile] %s: port @ 0x%p\n", __PRETTY_FUNCTION__, myport);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Loop until DLL expunges (that is if a CloseMessage leads to opencount==0)
|
||||||
|
** and no pending Messages are left
|
||||||
|
*/
|
||||||
|
while((msg=(dll_tMessage *)GetMsg(myport))||(!expunge))
|
||||||
|
{
|
||||||
|
if (msg)
|
||||||
|
{
|
||||||
|
switch(msg->dllMessageType)
|
||||||
|
{
|
||||||
|
case DLLMTYPE_Open:
|
||||||
|
bug("[DynFile] %s: DLLMTYPE_Open\n", __PRETTY_FUNCTION__);
|
||||||
|
/*
|
||||||
|
* Stack type checking should go here. Might be ommited for strictly
|
||||||
|
* private DLLs, or when stack frame compatibility can be 100% assured.
|
||||||
|
* FIXME: Not handled for now
|
||||||
|
*/
|
||||||
|
opencount++;
|
||||||
|
if(opencount>0)
|
||||||
|
expunge=0L;
|
||||||
|
msg->dllMessageData.dllOpen.ErrorCode=DLLERR_NoError;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DLLMTYPE_Close:
|
||||||
|
bug("[DynFile] %s: DLLMTYPE_Close\n", __PRETTY_FUNCTION__);
|
||||||
|
opencount--;
|
||||||
|
if(opencount<=0L) // <0 ????
|
||||||
|
expunge=1L;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DLLMTYPE_SymbolQuery:
|
||||||
|
bug("[DynFile] %s: DLLMTYPE_SymbolQuery\n", __PRETTY_FUNCTION__);
|
||||||
|
dllExportSymbol(&msg->dllMessageData.dllSymbolQuery);
|
||||||
|
//printf("Symbol Query for %s : %p\n",msg->dllMessageData.dllSymbolQuery.SymbolName,
|
||||||
|
// *msg->dllMessageData.dllSymbolQuery.SymbolPointer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DLLMTYPE_Kill:
|
||||||
|
bug("[DynFile] %s: DLLMTYPE_Kill\n", __PRETTY_FUNCTION__);
|
||||||
|
expunge=1L;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send the message back
|
||||||
|
*/
|
||||||
|
ReplyMsg((struct Message *)msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for messages to pop up
|
||||||
|
* Note that if the DLL is expunged it doesn't wait anymore,
|
||||||
|
* but it still processes all pending messages (including open messages
|
||||||
|
* which can disable the expunge flag).
|
||||||
|
* FIXME: Is this multithread safe ??
|
||||||
|
*/
|
||||||
|
if(!expunge)
|
||||||
|
WaitPort(myport);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete public port
|
||||||
|
*/
|
||||||
|
DeletePort(myport);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call DLL specific destructor
|
||||||
|
*/
|
||||||
|
DLL_DeInit();
|
||||||
|
|
||||||
|
return 0L;
|
||||||
|
}
|
10
neo/sys/aros/mmakefile.src
Normal file
10
neo/sys/aros/mmakefile.src
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Copyright © 2004, The AROS Development Team. All rights reserved.
|
||||||
|
# $Id: mmakefile.src 33489 2010-06-07 23:03:12Z mazze $
|
||||||
|
|
||||||
|
include $(TOP)/config/make.cfg
|
||||||
|
|
||||||
|
#MM- iconset-Gorilla-contrib-games-doom3game : doom3-gorillaicons-game
|
||||||
|
|
||||||
|
DOOM3_EXEDIR := $(AROS_CONTRIB)/Games/Fps/ADoom3
|
||||||
|
DOOM3_ICONS := ADoom3 ROE
|
||||||
|
%build_icons mmake=doom3-gorillaicons-game icons="$(DOOM3_ICONS)" dir=$(DOOM3_EXEDIR)
|
1
neo/sys/aros/setup/ADoom3.info.src
Normal file
1
neo/sys/aros/setup/ADoom3.info.src
Normal file
|
@ -0,0 +1 @@
|
||||||
|
TYPE = DRAWER
|
BIN
neo/sys/aros/setup/ADoom3.png
Normal file
BIN
neo/sys/aros/setup/ADoom3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.7 KiB |
20
neo/sys/aros/setup/mmakefile.src
Normal file
20
neo/sys/aros/setup/mmakefile.src
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
include $(TOP)/config/make.cfg
|
||||||
|
|
||||||
|
#MM- aros-doom3 : aros-doom3-defconfig
|
||||||
|
|
||||||
|
#MM aros-doom3-defconfig : aros-doom3-dirs
|
||||||
|
|
||||||
|
aros-doom3-defconfig: $(AROS_CONTRIB)/Games/Fps/ADoom3/base/default.cfg
|
||||||
|
|
||||||
|
$(AROS_CONTRIB)/Games/ADoom3/base/default.cfg: $(SRCDIR)/$(CURDIR)/default.cfg
|
||||||
|
@$(CP) $< $@
|
||||||
|
|
||||||
|
%build_icons mmake=iconset-Gorilla-contrib-icons-extras-games-adoom3 icons=ADoom3 dir=$(AROS_CONTRIB)/Games/Fps
|
||||||
|
|
||||||
|
#MM
|
||||||
|
aros-doom3-dirs :
|
||||||
|
%mkdirs_q $(AROS_CONTRIB)/Fps/Games/ADoom3/base
|
||||||
|
|
||||||
|
%common
|
|
@ -40,6 +40,34 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
===============================================================================
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Win32
|
||||||
|
#if defined(__AROS__)
|
||||||
|
|
||||||
|
#define _alloca alloca
|
||||||
|
#define _alloca16( x ) ((void *)((((uintptr_t)alloca( (x)+15 )) + 15) & ~15))
|
||||||
|
|
||||||
|
#ifdef GAME_DLL
|
||||||
|
#define ID_GAME_API __attribute__((visibility ("default")))
|
||||||
|
#else
|
||||||
|
#define ID_GAME_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ALIGN16( x ) x __attribute__ ((aligned (16)))
|
||||||
|
#define PACKED __attribute__((packed))
|
||||||
|
|
||||||
|
#define PATHSEPERATOR_STR "/"
|
||||||
|
#define PATHSEPERATOR_CHAR '/'
|
||||||
|
|
||||||
|
#define __cdecl
|
||||||
|
#define ASSERT assert
|
||||||
|
|
||||||
|
#define ID_INLINE inline
|
||||||
|
#define ID_STATIC_TEMPLATE
|
||||||
|
|
||||||
|
#define assertmem( x, y )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// Win32
|
// Win32
|
||||||
#if defined(WIN32) || defined(_WIN32)
|
#if defined(WIN32) || defined(_WIN32)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue