mirror of
https://github.com/dhewm/dhewm3.git
synced 2025-01-31 13:40:38 +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_SKIP_RPATH ON CACHE BOOL "Skip RPATH" FORCE)
|
||||
|
||||
set(DHEWM3BINARY "dhewm3")
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(GNUInstallDirs OPTIONAL RESULT_VARIABLE GNUINSTALLDIRS)
|
||||
|
||||
|
@ -108,8 +110,10 @@ include_directories(${VORBISFILE_INCLUDE_DIR})
|
|||
find_package(OpenAL REQUIRED)
|
||||
include_directories(${OPENAL_INCLUDE_DIR})
|
||||
|
||||
find_package(X11 REQUIRED)
|
||||
include_directories(${X11_INCLUDE_DIR})
|
||||
if(NOT AROS)
|
||||
find_package(X11 REQUIRED)
|
||||
include_directories(${X11_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if (SDL2)
|
||||
# skip SDL2main
|
||||
|
@ -162,11 +166,13 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
|||
|
||||
add_compile_options(-fno-strict-aliasing)
|
||||
|
||||
CHECK_CXX_COMPILER_FLAG("-fvisibility=hidden" cxx_has_fvisibility)
|
||||
if(NOT cxx_has_fvisibility)
|
||||
message(FATAL_ERROR "Compiler does not support -fvisibility")
|
||||
if(NOT AROS)
|
||||
CHECK_CXX_COMPILER_FLAG("-fvisibility=hidden" cxx_has_fvisibility)
|
||||
if(NOT cxx_has_fvisibility)
|
||||
message(FATAL_ERROR "Compiler does not support -fvisibility")
|
||||
endif()
|
||||
add_compile_options(-fvisibility=hidden)
|
||||
endif()
|
||||
add_compile_options(-fvisibility=hidden)
|
||||
|
||||
# TODO fix these warnings
|
||||
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)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
if(AROS)
|
||||
set(CMAKE_SHARED_LIBRARY_SUFFIX ".aros-${cpu}")
|
||||
add_definitions(-DIOAPI_NO_64)
|
||||
elseif(APPLE)
|
||||
add_definitions(-DMACOS_X=1)
|
||||
|
||||
if(cpu STREQUAL "x86_64")
|
||||
|
@ -679,7 +688,31 @@ set(src_core
|
|||
set(src_stub_openal sys/stub/openal_stub.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
|
||||
"${CMAKE_SOURCE_DIR}/sys/osx/Doom3.icns"
|
||||
"${CMAKE_SOURCE_DIR}/sys/osx/Doom 3.rsrc"
|
||||
|
@ -745,27 +778,36 @@ include_directories(${CMAKE_BINARY_DIR})
|
|||
include_directories(${CMAKE_SOURCE_DIR})
|
||||
|
||||
add_library(idlib STATIC ${src_idlib})
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT MINGW)
|
||||
set_target_properties(idlib PROPERTIES COMPILE_FLAGS "-fPIC")
|
||||
if (AROS)
|
||||
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()
|
||||
|
||||
if(CORE)
|
||||
add_executable(dhewm3 WIN32 MACOSX_BUNDLE
|
||||
add_executable(${DHEWM3BINARY} WIN32 MACOSX_BUNDLE
|
||||
${src_core}
|
||||
${src_sys_base}
|
||||
${src_sys_core}
|
||||
)
|
||||
|
||||
set_target_properties(dhewm3 PROPERTIES COMPILE_DEFINITIONS "__DOOM_DLL__")
|
||||
set_target_properties(dhewm3 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 COMPILE_DEFINITIONS "__DOOM_DLL__")
|
||||
set_target_properties(${DHEWM3BINARY} PROPERTIES LINK_FLAGS "${ldflags}")
|
||||
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
|
||||
${OPENAL_LIBRARY}
|
||||
${OGG_LIBRARIES}
|
||||
${VORBISFILE_LIBRARIES}
|
||||
${VORBIS_LIBRARIES}
|
||||
${OGG_LIBRARIES}
|
||||
${CURL_LIBRARY}
|
||||
${JPEG_LIBRARY}
|
||||
${ZLIB_LIBRARY}
|
||||
|
@ -774,7 +816,7 @@ if(CORE)
|
|||
)
|
||||
|
||||
if(NOT APPLE AND NOT WIN32)
|
||||
install(TARGETS dhewm3
|
||||
install(TARGETS ${DHEWM3BINARY}
|
||||
RUNTIME DESTINATION "${bindir}"
|
||||
LIBRARY DESTINATION "${libdir}"
|
||||
ARCHIVE DESTINATION "${libdir}"
|
||||
|
@ -783,19 +825,20 @@ if(CORE)
|
|||
endif()
|
||||
|
||||
if(DEDICATED)
|
||||
add_executable(dhewm3ded WIN32 MACOSX_BUNDLE
|
||||
add_executable(${DHEWM3BINARY}ded WIN32 MACOSX_BUNDLE
|
||||
${src_core}
|
||||
${src_stub_openal}
|
||||
${src_stub_gl}
|
||||
${src_sys_base}
|
||||
)
|
||||
|
||||
set_target_properties(dhewm3ded PROPERTIES COMPILE_DEFINITIONS "ID_DEDICATED;__DOOM_DLL__")
|
||||
set_target_properties(dhewm3ded PROPERTIES LINK_FLAGS "${ldflags}")
|
||||
target_link_libraries(dhewm3ded
|
||||
set_target_properties(${DHEWM3BINARY}ded PROPERTIES COMPILE_DEFINITIONS "ID_DEDICATED;__DOOM_DLL__")
|
||||
set_target_properties(${DHEWM3BINARY}ded PROPERTIES LINK_FLAGS "${ldflags}")
|
||||
target_link_libraries(${DHEWM3BINARY}ded
|
||||
idlib
|
||||
${VORBISFILE_LIBRARIES}
|
||||
${VORBIS_LIBRARIES}
|
||||
${OGG_LIBRARIES}
|
||||
${CURL_LIBRARY}
|
||||
${JPEG_LIBRARY}
|
||||
${ZLIB_LIBRARY}
|
||||
|
@ -804,7 +847,7 @@ if(DEDICATED)
|
|||
)
|
||||
|
||||
if(NOT APPLE AND NOT WIN32)
|
||||
install(TARGETS dhewm3ded
|
||||
install(TARGETS ${DHEWM3BINARY}ded
|
||||
RUNTIME DESTINATION "${bindir}"
|
||||
LIBRARY DESTINATION "${libdir}"
|
||||
ARCHIVE DESTINATION "${libdir}"
|
||||
|
@ -813,13 +856,22 @@ if(DEDICATED)
|
|||
endif()
|
||||
|
||||
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 COMPILE_DEFINITIONS "GAME_DLL")
|
||||
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 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)
|
||||
install(TARGETS base
|
||||
|
@ -831,13 +883,22 @@ if(BASE)
|
|||
endif()
|
||||
|
||||
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 COMPILE_DEFINITIONS "GAME_DLL;_D3XP;CTF")
|
||||
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 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)
|
||||
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_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" );
|
||||
#ifdef WIN32
|
||||
#if defined(__AROS__) || defined(WIN32)
|
||||
idCVar idFileSystemLocal::fs_caseSensitiveOS( "fs_caseSensitiveOS", "0", CVAR_SYSTEM | CVAR_BOOL, "" );
|
||||
#else
|
||||
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 ENGINE_VERSION "dhewm 3 1.4.1" // printed in console
|
||||
#endif
|
||||
|
||||
// paths
|
||||
#define BASE_GAMEDIR "base"
|
||||
|
||||
// filenames
|
||||
#ifndef CONFIG_FILE
|
||||
#define CONFIG_FILE "dhewm.cfg"
|
||||
#endif
|
||||
|
||||
// base folder where the source code lives
|
||||
#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"
|
||||
|
||||
#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_minTics( "com_minTics", "1", CVAR_SYSTEM, "" );
|
||||
idCVar idSessionLocal::com_showTics( "com_showTics", "0", CVAR_SYSTEM | CVAR_BOOL, "" );
|
||||
|
@ -2961,7 +2969,7 @@ void idSessionLocal::ReadCDKey( void ) {
|
|||
|
||||
cdkey_state = CDKEY_UNKNOWN;
|
||||
|
||||
filename = "../" BASE_GAMEDIR "/" CDKEY_FILE;
|
||||
filename = CDKEY_FILEPATH;
|
||||
f = fileSystem->OpenExplicitFileRead( fileSystem->RelativePathToOSPath( filename, "fs_configpath" ) );
|
||||
|
||||
// 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;
|
||||
|
||||
filename = "../" BASE_GAMEDIR "/" XPKEY_FILE;
|
||||
filename = XPKEY_FILEPATH;
|
||||
f = fileSystem->OpenExplicitFileRead( fileSystem->RelativePathToOSPath( filename, "fs_configpath" ) );
|
||||
|
||||
// try the install path, which is where the cd installer and steam put it
|
||||
|
@ -3008,7 +3016,7 @@ void idSessionLocal::WriteCDKey( void ) {
|
|||
idFile *f;
|
||||
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
|
||||
// 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 );
|
||||
|
@ -3021,7 +3029,7 @@ void idSessionLocal::WriteCDKey( void ) {
|
|||
f->Printf( "%s%s", cdkey, CDKEY_TEXT );
|
||||
fileSystem->CloseFile( f );
|
||||
|
||||
filename = "../" BASE_GAMEDIR "/" XPKEY_FILE;
|
||||
filename = XPKEY_FILEPATH;
|
||||
f = fileSystem->OpenFileWrite( filename, "fs_configpath" );
|
||||
if ( !f ) {
|
||||
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 <stddef.h>
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
@ -604,12 +606,14 @@ pathNode_t *BuildPathTree( const obstacle_t *obstacles, int numObstacles, const
|
|||
pathNode_t *root, *node, *child;
|
||||
// gcc 4.0
|
||||
idQueueTemplate<pathNode_t, offsetof( pathNode_t, next ) > pathNodeQueue, treeQueue;
|
||||
|
||||
root = pathNodeAllocator.Alloc();
|
||||
root->Init();
|
||||
root->pos = startPos;
|
||||
|
||||
root->delta = seekPos - root->pos;
|
||||
root->numNodes = 0;
|
||||
|
||||
pathNodeQueue.Add( root );
|
||||
|
||||
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 ) {
|
||||
#if defined(__AROS__)
|
||||
if ( ( ( *this )[ 0 ] == '/' ) || ( ( *this )[ 0 ] == '\\' ) || ( ( *this )[ 0 ] == ':' ) ) {
|
||||
#else
|
||||
if ( ( ( *this )[ 0 ] == '/' ) || ( ( *this )[ 0 ] == '\\' ) ) {
|
||||
#endif
|
||||
// absolute path location
|
||||
return *this;
|
||||
}
|
||||
|
@ -840,11 +844,19 @@ void idStr::AppendPath( const char *text ) {
|
|||
EnsureAlloced( len + strlen( text ) + 2 );
|
||||
|
||||
if ( pos ) {
|
||||
#if defined(__AROS__)
|
||||
if (( data[ pos-1 ] != '/' ) || ( data[ pos-1 ] != ':' )) {
|
||||
#else
|
||||
if ( data[ pos-1 ] != '/' ) {
|
||||
#endif
|
||||
data[ pos++ ] = '/';
|
||||
}
|
||||
}
|
||||
#if defined(__AROS__)
|
||||
if (( text[i] == '/' ) || ( text[i] == ':' )) {
|
||||
#else
|
||||
if ( text[i] == '/' ) {
|
||||
#endif
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -869,7 +881,11 @@ idStr &idStr::StripFilename( void ) {
|
|||
int pos;
|
||||
|
||||
pos = Length() - 1;
|
||||
#if defined(__AROS__)
|
||||
while( ( pos > 0 ) && ( ( *this )[ pos ] != '/' ) && ( ( *this )[ pos ] != '\\' ) && ( ( *this )[ pos ] != ':' ) ) {
|
||||
#else
|
||||
while( ( pos > 0 ) && ( ( *this )[ pos ] != '/' ) && ( ( *this )[ pos ] != '\\' ) ) {
|
||||
#endif
|
||||
pos--;
|
||||
}
|
||||
|
||||
|
@ -890,7 +906,11 @@ idStr &idStr::StripPath( void ) {
|
|||
int pos;
|
||||
|
||||
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 ] != '\\' ) ) {
|
||||
#endif
|
||||
pos--;
|
||||
}
|
||||
|
||||
|
@ -910,7 +930,11 @@ void idStr::ExtractFilePath( idStr &dest ) const {
|
|||
// back up until a \ or the start
|
||||
//
|
||||
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 ] != '\\' ) ) {
|
||||
#endif
|
||||
pos--;
|
||||
}
|
||||
|
||||
|
@ -929,7 +953,11 @@ void idStr::ExtractFileName( idStr &dest ) const {
|
|||
// back up until a \ or the start
|
||||
//
|
||||
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 ] != '\\' ) ) {
|
||||
#endif
|
||||
pos--;
|
||||
}
|
||||
|
||||
|
@ -949,7 +977,11 @@ void idStr::ExtractFileBase( idStr &dest ) const {
|
|||
// back up until a \ or the start
|
||||
//
|
||||
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 ] != '\\' ) ) {
|
||||
#endif
|
||||
pos--;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,12 +64,18 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#endif
|
||||
#define StrCmpNI use_idStr_Icmpn
|
||||
|
||||
#if defined( stricmp )
|
||||
#undef stricmp
|
||||
#endif
|
||||
#define stricmp idStr::Icmp // use_idStr_Icmp
|
||||
#define _stricmp use_idStr_Icmp
|
||||
#if defined( strcasecmp )
|
||||
#undef strcasecmp
|
||||
#endif
|
||||
#define strcasecmp use_idStr_Icmp
|
||||
#if defined( strnicmp )
|
||||
#undef strnicmp
|
||||
#endif
|
||||
#define strnicmp use_idStr_Icmpn
|
||||
#define _strnicmp 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 ) {
|
||||
int a,b,c,d, e;
|
||||
|
||||
bool restrict = cvarSystem->GetCVarBool( "fs_restrict" );
|
||||
bool fsrestrict = cvarSystem->GetCVarBool( "fs_restrict" );
|
||||
cvarSystem->SetCVarBool( "fs_restrict", false );
|
||||
|
||||
lastNumber++;
|
||||
|
@ -1339,7 +1339,7 @@ void R_ScreenshotFilename( int &lastNumber, const char *base, idStr &fileName )
|
|||
}
|
||||
// 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
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
|
||||
|
|
Loading…
Reference in a new issue