11 May 2012
This commit is contained in:
parent
93d3aecc01
commit
67f7709e29
@ -30,6 +30,7 @@ engine\common\soundlib\
|
||||
pm_shared\
|
||||
mainui\
|
||||
mainui\legacy
|
||||
unused\
|
||||
utils\
|
||||
utils\makefont\
|
||||
utils\vgui\
|
||||
|
@ -1,3 +1,7 @@
|
||||
build ????
|
||||
|
||||
Server: fix the sound problem with weapons
|
||||
|
||||
build 1905
|
||||
|
||||
Physic: fix trace bug when model is missing
|
||||
|
@ -229,7 +229,7 @@ void CL_TEntPlaySound( TEMPENTITY *pTemp, float damp )
|
||||
else pitch = PITCH_NORM;
|
||||
|
||||
handle = S_RegisterSound( soundname );
|
||||
S_StartSound( pTemp->entity.origin, 0, CHAN_STATIC, handle, fvol, ATTN_NORM, pitch, SND_STOP_LOOPING );
|
||||
S_StartSound( pTemp->entity.origin, -(pTemp - cl_tempents), CHAN_BODY, handle, fvol, ATTN_NORM, pitch, SND_STOP_LOOPING );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,6 +177,7 @@ void GL_TexFilter( gltexture_t *tex, qboolean update )
|
||||
pglTexParameteri( tex->target, GL_TEXTURE_MIN_FILTER, r_textureMinFilter );
|
||||
pglTexParameteri( tex->target, GL_TEXTURE_MAG_FILTER, r_textureMagFilter );
|
||||
}
|
||||
|
||||
// set texture anisotropy if available
|
||||
if( GL_Support( GL_ANISOTROPY_EXT ))
|
||||
pglTexParameterf( tex->target, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_anisotropy->value );
|
||||
@ -202,7 +203,7 @@ void GL_TexFilter( gltexture_t *tex, qboolean update )
|
||||
{
|
||||
pglTexParameteri( tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
||||
|
||||
if( tex->target == GL_TEXTURE_2D )
|
||||
if( tex->target != GL_TEXTURE_1D )
|
||||
pglTexParameteri( tex->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
||||
|
||||
if( tex->target == GL_TEXTURE_3D )
|
||||
@ -212,7 +213,7 @@ void GL_TexFilter( gltexture_t *tex, qboolean update )
|
||||
{
|
||||
pglTexParameteri( tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP );
|
||||
|
||||
if( tex->target == GL_TEXTURE_2D )
|
||||
if( tex->target != GL_TEXTURE_1D )
|
||||
pglTexParameteri( tex->target, GL_TEXTURE_WRAP_T, GL_CLAMP );
|
||||
|
||||
if( tex->target == GL_TEXTURE_3D )
|
||||
@ -223,7 +224,7 @@ void GL_TexFilter( gltexture_t *tex, qboolean update )
|
||||
{
|
||||
pglTexParameteri( tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER );
|
||||
|
||||
if( tex->target == GL_TEXTURE_2D )
|
||||
if( tex->target != GL_TEXTURE_1D )
|
||||
pglTexParameteri( tex->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER );
|
||||
|
||||
if( tex->target == GL_TEXTURE_3D )
|
||||
@ -233,7 +234,7 @@ void GL_TexFilter( gltexture_t *tex, qboolean update )
|
||||
{
|
||||
pglTexParameteri( tex->target, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
|
||||
if( tex->target == GL_TEXTURE_2D )
|
||||
if( tex->target != GL_TEXTURE_1D )
|
||||
pglTexParameteri( tex->target, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
|
||||
if( tex->target == GL_TEXTURE_3D )
|
||||
@ -1821,6 +1822,33 @@ static rgbdata_t *R_InitDlightCubemap( texFlags_t *flags )
|
||||
return &r_image;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
R_InitGrayCubemap
|
||||
==================
|
||||
*/
|
||||
static rgbdata_t *R_InitGrayCubemap( texFlags_t *flags )
|
||||
{
|
||||
int size = 4;
|
||||
byte *dataCM = data2D;
|
||||
|
||||
if( !GL_Support( GL_TEXTURECUBEMAP_EXT ))
|
||||
return NULL;
|
||||
|
||||
// gray cubemap - just stub for pointlights
|
||||
Q_memset( dataCM, 0x7F, size * size * 6 * 4 );
|
||||
|
||||
*flags = (TF_NOPICMIP|TF_NOMIPMAP|TF_UNCOMPRESSED|TF_CUBEMAP|TF_CLAMP);
|
||||
|
||||
r_image.width = r_image.height = size;
|
||||
r_image.size = r_image.width * r_image.height * 4 * 6;
|
||||
r_image.flags |= (IMAGE_CUBEMAP|IMAGE_HAS_COLOR); // yes it's cubemap
|
||||
r_image.buffer = data2D;
|
||||
r_image.type = PF_RGBA_32;
|
||||
|
||||
return &r_image;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
R_InitBuiltinTextures
|
||||
@ -1853,6 +1881,7 @@ static void R_InitBuiltinTextures( void )
|
||||
{ "*atten3", &tr.attenuationTexture3, R_InitAttenuationTexture3, TEX_SYSTEM },
|
||||
{ "*normalize", &tr.normalizeTexture, R_InitNormalizeCubemap, TEX_CUBEMAP },
|
||||
{ "*lightCube", &tr.dlightCubeTexture, R_InitDlightCubemap, TEX_CUBEMAP },
|
||||
{ "*grayCube", &tr.grayCubeTexture, R_InitGrayCubemap, TEX_CUBEMAP },
|
||||
{ "*atten3D", &tr.attenuationTexture3D, R_InitAttenTexture3D, TEX_SYSTEM },
|
||||
{ "*sky", &tr.skyTexture, R_InitSkyTexture, TEX_SYSTEM },
|
||||
{ NULL, NULL, NULL }
|
||||
|
@ -187,6 +187,7 @@ typedef struct
|
||||
int attenuationTexture3D;// 3D attenuation
|
||||
int normalizeTexture;
|
||||
int dlightCubeTexture; // dynamic cubemap
|
||||
int grayCubeTexture;
|
||||
int skyboxTextures[6]; // skybox sides
|
||||
int mirrorTextures[MAX_MIRRORS];
|
||||
int num_mirrors_used; // used mirror textures
|
||||
|
@ -340,6 +340,10 @@ sound_t S_RegisterSound( const char *name )
|
||||
return SENTENCE_INDEX;
|
||||
}
|
||||
|
||||
// some stupid mappers used leading '/' or '\' in path to models or sounds
|
||||
if( name[0] == '/' || name[0] == '\\' ) name++;
|
||||
if( name[0] == '/' || name[0] == '\\' ) name++;
|
||||
|
||||
sfx = S_FindName( name, NULL );
|
||||
if( !sfx ) return -1;
|
||||
|
||||
|
@ -2465,6 +2465,7 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath )
|
||||
else dllpath[i] = Q_tolower( dllname[i+start] );
|
||||
}
|
||||
dllpath[i] = '\0';
|
||||
|
||||
FS_DefaultExtension( dllpath, ".dll" ); // apply ext if forget
|
||||
search = FS_FindFile( dllpath, &index, false );
|
||||
|
||||
@ -2472,6 +2473,7 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath )
|
||||
{
|
||||
fs_ext_path = false;
|
||||
if( directpath ) return NULL; // direct paths fails here
|
||||
|
||||
// trying check also 'bin' folder for indirect paths
|
||||
Q_strncpy( dllpath, dllname, sizeof( dllpath ));
|
||||
search = FS_FindFile( dllpath, &index, false );
|
||||
|
@ -16,6 +16,466 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "library.h"
|
||||
|
||||
/*
|
||||
---------------------------------------------------------------
|
||||
|
||||
Custom dlls loader
|
||||
|
||||
---------------------------------------------------------------
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PIMAGE_NT_HEADERS headers;
|
||||
byte *codeBase;
|
||||
void **modules;
|
||||
int numModules;
|
||||
int initialized;
|
||||
} MEMORYMODULE, *PMEMORYMODULE;
|
||||
|
||||
// Protection flags for memory pages (Executable, Readable, Writeable)
|
||||
static int ProtectionFlags[2][2][2] =
|
||||
{
|
||||
{
|
||||
{ PAGE_NOACCESS, PAGE_WRITECOPY }, // not executable
|
||||
{ PAGE_READONLY, PAGE_READWRITE },
|
||||
},
|
||||
{
|
||||
{ PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY }, // executable
|
||||
{ PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE },
|
||||
},
|
||||
};
|
||||
|
||||
typedef BOOL (WINAPI *DllEntryProc)( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved );
|
||||
|
||||
#define GET_HEADER_DICTIONARY( module, idx ) &(module)->headers->OptionalHeader.DataDirectory[idx]
|
||||
#define CALCULATE_ADDRESS( base, offset ) (((DWORD)(base)) + (offset))
|
||||
|
||||
static void CopySections( const byte *data, PIMAGE_NT_HEADERS old_headers, PMEMORYMODULE module )
|
||||
{
|
||||
int i, size;
|
||||
byte *dest;
|
||||
byte *codeBase = module->codeBase;
|
||||
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION( module->headers );
|
||||
|
||||
for( i = 0; i < module->headers->FileHeader.NumberOfSections; i++, section++ )
|
||||
{
|
||||
if( section->SizeOfRawData == 0 )
|
||||
{
|
||||
// section doesn't contain data in the dll itself, but may define
|
||||
// uninitialized data
|
||||
size = old_headers->OptionalHeader.SectionAlignment;
|
||||
|
||||
if( size > 0 )
|
||||
{
|
||||
dest = (byte *)VirtualAlloc((byte *)CALCULATE_ADDRESS(codeBase, section->VirtualAddress), size, MEM_COMMIT, PAGE_READWRITE );
|
||||
section->Misc.PhysicalAddress = (DWORD)dest;
|
||||
Q_memset( dest, 0, size );
|
||||
}
|
||||
// section is empty
|
||||
continue;
|
||||
}
|
||||
|
||||
// commit memory block and copy data from dll
|
||||
dest = (byte *)VirtualAlloc((byte *)CALCULATE_ADDRESS(codeBase, section->VirtualAddress), section->SizeOfRawData, MEM_COMMIT, PAGE_READWRITE );
|
||||
Q_memcpy( dest, (byte *)CALCULATE_ADDRESS(data, section->PointerToRawData), section->SizeOfRawData );
|
||||
section->Misc.PhysicalAddress = (DWORD)dest;
|
||||
}
|
||||
}
|
||||
|
||||
static void FreeSections( PIMAGE_NT_HEADERS old_headers, PMEMORYMODULE module )
|
||||
{
|
||||
int i, size;
|
||||
byte *codeBase = module->codeBase;
|
||||
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
|
||||
|
||||
for( i = 0; i < module->headers->FileHeader.NumberOfSections; i++, section++ )
|
||||
{
|
||||
if( section->SizeOfRawData == 0 )
|
||||
{
|
||||
size = old_headers->OptionalHeader.SectionAlignment;
|
||||
if( size > 0 )
|
||||
{
|
||||
VirtualFree( codeBase + section->VirtualAddress, size, MEM_DECOMMIT );
|
||||
section->Misc.PhysicalAddress = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
VirtualFree( codeBase + section->VirtualAddress, section->SizeOfRawData, MEM_DECOMMIT );
|
||||
section->Misc.PhysicalAddress = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void FinalizeSections( MEMORYMODULE *module )
|
||||
{
|
||||
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION( module->headers );
|
||||
int i;
|
||||
|
||||
// loop through all sections and change access flags
|
||||
for( i = 0; i < module->headers->FileHeader.NumberOfSections; i++, section++ )
|
||||
{
|
||||
DWORD protect, oldProtect, size;
|
||||
int executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
|
||||
int readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0;
|
||||
int writeable = (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0;
|
||||
|
||||
if( section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE )
|
||||
{
|
||||
// section is not needed any more and can safely be freed
|
||||
VirtualFree((LPVOID)section->Misc.PhysicalAddress, section->SizeOfRawData, MEM_DECOMMIT);
|
||||
continue;
|
||||
}
|
||||
|
||||
// determine protection flags based on characteristics
|
||||
protect = ProtectionFlags[executable][readable][writeable];
|
||||
if( section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED )
|
||||
protect |= PAGE_NOCACHE;
|
||||
|
||||
// determine size of region
|
||||
size = section->SizeOfRawData;
|
||||
|
||||
if( size == 0 )
|
||||
{
|
||||
if( section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA )
|
||||
size = module->headers->OptionalHeader.SizeOfInitializedData;
|
||||
else if( section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA )
|
||||
size = module->headers->OptionalHeader.SizeOfUninitializedData;
|
||||
}
|
||||
|
||||
if( size > 0 )
|
||||
{
|
||||
// change memory access flags
|
||||
if( !VirtualProtect((LPVOID)section->Misc.PhysicalAddress, size, protect, &oldProtect ))
|
||||
Sys_Error( "Com_FinalizeSections: error protecting memory page\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PerformBaseRelocation( MEMORYMODULE *module, DWORD delta )
|
||||
{
|
||||
DWORD i;
|
||||
byte *codeBase = module->codeBase;
|
||||
PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY( module, IMAGE_DIRECTORY_ENTRY_BASERELOC );
|
||||
|
||||
if( directory->Size > 0 )
|
||||
{
|
||||
PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION)CALCULATE_ADDRESS( codeBase, directory->VirtualAddress );
|
||||
for( ; relocation->VirtualAddress > 0; )
|
||||
{
|
||||
byte *dest = (byte *)CALCULATE_ADDRESS( codeBase, relocation->VirtualAddress );
|
||||
word *relInfo = (word *)((byte *)relocation + IMAGE_SIZEOF_BASE_RELOCATION );
|
||||
|
||||
for( i = 0; i<((relocation->SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relInfo++ )
|
||||
{
|
||||
DWORD *patchAddrHL;
|
||||
int type, offset;
|
||||
|
||||
// the upper 4 bits define the type of relocation
|
||||
type = *relInfo >> 12;
|
||||
// the lower 12 bits define the offset
|
||||
offset = *relInfo & 0xfff;
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case IMAGE_REL_BASED_ABSOLUTE:
|
||||
// skip relocation
|
||||
break;
|
||||
case IMAGE_REL_BASED_HIGHLOW:
|
||||
// change complete 32 bit address
|
||||
patchAddrHL = (DWORD *)CALCULATE_ADDRESS( dest, offset );
|
||||
*patchAddrHL += delta;
|
||||
break;
|
||||
default:
|
||||
MsgDev( D_ERROR, "PerformBaseRelocation: unknown relocation: %d\n", type );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// advance to next relocation block
|
||||
relocation = (PIMAGE_BASE_RELOCATION)CALCULATE_ADDRESS( relocation, relocation->SizeOfBlock );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static FARPROC MemoryGetProcAddress( void *module, const char *name )
|
||||
{
|
||||
int idx = -1;
|
||||
DWORD i, *nameRef;
|
||||
WORD *ordinal;
|
||||
PIMAGE_EXPORT_DIRECTORY exports;
|
||||
byte *codeBase = ((PMEMORYMODULE)module)->codeBase;
|
||||
PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((MEMORYMODULE *)module, IMAGE_DIRECTORY_ENTRY_EXPORT );
|
||||
|
||||
if( directory->Size == 0 )
|
||||
{
|
||||
// no export table found
|
||||
return NULL;
|
||||
}
|
||||
|
||||
exports = (PIMAGE_EXPORT_DIRECTORY)CALCULATE_ADDRESS( codeBase, directory->VirtualAddress );
|
||||
|
||||
if( exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0 )
|
||||
{
|
||||
// DLL doesn't export anything
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// search function name in list of exported names
|
||||
nameRef = (DWORD *)CALCULATE_ADDRESS( codeBase, exports->AddressOfNames );
|
||||
ordinal = (WORD *)CALCULATE_ADDRESS( codeBase, exports->AddressOfNameOrdinals );
|
||||
|
||||
for( i = 0; i < exports->NumberOfNames; i++, nameRef++, ordinal++ )
|
||||
{
|
||||
// GetProcAddress case insensative ?????
|
||||
if( !Q_stricmp( name, (const char *)CALCULATE_ADDRESS( codeBase, *nameRef )))
|
||||
{
|
||||
idx = *ordinal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( idx == -1 )
|
||||
{
|
||||
// exported symbol not found
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((DWORD)idx > exports->NumberOfFunctions )
|
||||
{
|
||||
// name <-> ordinal number don't match
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// addressOfFunctions contains the RVAs to the "real" functions
|
||||
return (FARPROC)CALCULATE_ADDRESS( codeBase, *(DWORD *)CALCULATE_ADDRESS( codeBase, exports->AddressOfFunctions + (idx * 4)));
|
||||
}
|
||||
|
||||
static int BuildImportTable( MEMORYMODULE *module )
|
||||
{
|
||||
int result=1;
|
||||
byte *codeBase = module->codeBase;
|
||||
PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY( module, IMAGE_DIRECTORY_ENTRY_IMPORT );
|
||||
|
||||
if( directory->Size > 0 )
|
||||
{
|
||||
PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR)CALCULATE_ADDRESS( codeBase, directory->VirtualAddress );
|
||||
|
||||
for( ; !IsBadReadPtr( importDesc, sizeof( IMAGE_IMPORT_DESCRIPTOR )) && importDesc->Name; importDesc++ )
|
||||
{
|
||||
DWORD *thunkRef, *funcRef;
|
||||
LPCSTR libname;
|
||||
void *handle;
|
||||
|
||||
libname = (LPCSTR)CALCULATE_ADDRESS( codeBase, importDesc->Name );
|
||||
handle = Com_LoadLibraryExt( libname, false, true );
|
||||
|
||||
if( handle == NULL )
|
||||
{
|
||||
MsgDev( D_ERROR, "couldn't load library %s\n", libname );
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
module->modules = (void *)Mem_Realloc( host.mempool, module->modules, (module->numModules + 1) * (sizeof( void* )));
|
||||
module->modules[module->numModules++] = handle;
|
||||
|
||||
if( importDesc->OriginalFirstThunk )
|
||||
{
|
||||
thunkRef = (DWORD *)CALCULATE_ADDRESS( codeBase, importDesc->OriginalFirstThunk );
|
||||
funcRef = (DWORD *)CALCULATE_ADDRESS( codeBase, importDesc->FirstThunk );
|
||||
}
|
||||
else
|
||||
{
|
||||
// no hint table
|
||||
thunkRef = (DWORD *)CALCULATE_ADDRESS( codeBase, importDesc->FirstThunk );
|
||||
funcRef = (DWORD *)CALCULATE_ADDRESS( codeBase, importDesc->FirstThunk );
|
||||
}
|
||||
|
||||
for( ; *thunkRef; thunkRef++, funcRef++ )
|
||||
{
|
||||
if( IMAGE_SNAP_BY_ORDINAL( *thunkRef ))
|
||||
{
|
||||
LPCSTR funcName = (LPCSTR)IMAGE_ORDINAL( *thunkRef );
|
||||
*funcRef = (DWORD)Com_GetProcAddress( handle, funcName );
|
||||
}
|
||||
else
|
||||
{
|
||||
PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)CALCULATE_ADDRESS( codeBase, *thunkRef );
|
||||
LPCSTR funcName = (LPCSTR)&thunkData->Name;
|
||||
*funcRef = (DWORD)Com_GetProcAddress( handle, funcName );
|
||||
}
|
||||
|
||||
if( *funcRef == 0 )
|
||||
{
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !result ) break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void MemoryFreeLibrary( void *hInstance )
|
||||
{
|
||||
MEMORYMODULE *module = (MEMORYMODULE *)hInstance;
|
||||
|
||||
if( module != NULL )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( module->initialized != 0 )
|
||||
{
|
||||
// notify library about detaching from process
|
||||
DllEntryProc DllEntry = (DllEntryProc)CALCULATE_ADDRESS( module->codeBase, module->headers->OptionalHeader.AddressOfEntryPoint );
|
||||
(*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0 );
|
||||
module->initialized = 0;
|
||||
}
|
||||
|
||||
if( module->modules != NULL )
|
||||
{
|
||||
// free previously opened libraries
|
||||
for( i = 0; i < module->numModules; i++ )
|
||||
{
|
||||
if( module->modules[i] != NULL )
|
||||
{
|
||||
Com_FreeLibrary( module->modules[i] );
|
||||
}
|
||||
}
|
||||
Mem_Free( module->modules ); // Mem_Realloc end
|
||||
}
|
||||
|
||||
FreeSections( module->headers, module );
|
||||
|
||||
if( module->codeBase != NULL )
|
||||
{
|
||||
// release memory of library
|
||||
VirtualFree( module->codeBase, 0, MEM_RELEASE );
|
||||
}
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, module );
|
||||
}
|
||||
}
|
||||
|
||||
void *MemoryLoadLibrary( const char *name )
|
||||
{
|
||||
MEMORYMODULE *result;
|
||||
PIMAGE_DOS_HEADER dos_header;
|
||||
PIMAGE_NT_HEADERS old_header;
|
||||
byte *code, *headers;
|
||||
DWORD locationDelta;
|
||||
DllEntryProc DllEntry;
|
||||
string errorstring;
|
||||
qboolean successfull;
|
||||
void *data = NULL;
|
||||
|
||||
data = FS_LoadFile( name, NULL, false );
|
||||
|
||||
if( !data )
|
||||
{
|
||||
Q_sprintf( errorstring, "couldn't load %s", name );
|
||||
goto library_error;
|
||||
}
|
||||
|
||||
dos_header = (PIMAGE_DOS_HEADER)data;
|
||||
if( dos_header->e_magic != IMAGE_DOS_SIGNATURE )
|
||||
{
|
||||
Q_sprintf( errorstring, "%s it's not a valid executable file", name );
|
||||
goto library_error;
|
||||
}
|
||||
|
||||
old_header = (PIMAGE_NT_HEADERS)&((const byte *)(data))[dos_header->e_lfanew];
|
||||
if( old_header->Signature != IMAGE_NT_SIGNATURE )
|
||||
{
|
||||
Q_sprintf( errorstring, "%s missing PE header", name );
|
||||
goto library_error;
|
||||
}
|
||||
|
||||
// reserve memory for image of library
|
||||
code = (byte *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase), old_header->OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_READWRITE );
|
||||
|
||||
if( code == NULL )
|
||||
{
|
||||
// try to allocate memory at arbitrary position
|
||||
code = (byte *)VirtualAlloc( NULL, old_header->OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_READWRITE );
|
||||
}
|
||||
if( code == NULL )
|
||||
{
|
||||
Q_sprintf( errorstring, "%s can't reserve memory", name );
|
||||
goto library_error;
|
||||
}
|
||||
|
||||
result = (MEMORYMODULE *)HeapAlloc( GetProcessHeap(), 0, sizeof( MEMORYMODULE ));
|
||||
result->codeBase = code;
|
||||
result->numModules = 0;
|
||||
result->modules = NULL;
|
||||
result->initialized = 0;
|
||||
|
||||
// XXX: is it correct to commit the complete memory region at once?
|
||||
// calling DllEntry raises an exception if we don't...
|
||||
VirtualAlloc( code, old_header->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_READWRITE );
|
||||
|
||||
// commit memory for headers
|
||||
headers = (byte *)VirtualAlloc( code, old_header->OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE );
|
||||
|
||||
// copy PE header to code
|
||||
Q_memcpy( headers, dos_header, dos_header->e_lfanew + old_header->OptionalHeader.SizeOfHeaders );
|
||||
result->headers = (PIMAGE_NT_HEADERS)&((const byte *)(headers))[dos_header->e_lfanew];
|
||||
|
||||
// update position
|
||||
result->headers->OptionalHeader.ImageBase = (DWORD)code;
|
||||
|
||||
// copy sections from DLL file block to new memory location
|
||||
CopySections( data, old_header, result );
|
||||
|
||||
// adjust base address of imported data
|
||||
locationDelta = (DWORD)(code - old_header->OptionalHeader.ImageBase);
|
||||
if( locationDelta != 0 ) PerformBaseRelocation( result, locationDelta );
|
||||
|
||||
// load required dlls and adjust function table of imports
|
||||
if( !BuildImportTable( result ))
|
||||
{
|
||||
Q_sprintf( errorstring, "%s failed to build import table", name );
|
||||
goto library_error;
|
||||
}
|
||||
|
||||
// mark memory pages depending on section headers and release
|
||||
// sections that are marked as "discardable"
|
||||
FinalizeSections( result );
|
||||
|
||||
// get entry point of loaded library
|
||||
if( result->headers->OptionalHeader.AddressOfEntryPoint != 0 )
|
||||
{
|
||||
DllEntry = (DllEntryProc)CALCULATE_ADDRESS( code, result->headers->OptionalHeader.AddressOfEntryPoint );
|
||||
if( DllEntry == 0 )
|
||||
{
|
||||
Q_sprintf( errorstring, "%s has no entry point", name );
|
||||
goto library_error;
|
||||
}
|
||||
|
||||
// notify library about attaching to process
|
||||
successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0 );
|
||||
if( !successfull )
|
||||
{
|
||||
Q_sprintf( errorstring, "can't attach library %s", name );
|
||||
goto library_error;
|
||||
}
|
||||
result->initialized = 1;
|
||||
}
|
||||
|
||||
Mem_Free( data ); // release memory
|
||||
return (void *)result;
|
||||
library_error:
|
||||
// cleanup
|
||||
if( data ) Mem_Free( data );
|
||||
MemoryFreeLibrary( result );
|
||||
MsgDev( D_ERROR, "LoadLibrary: %s\n", errorstring );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
---------------------------------------------------------------
|
||||
|
||||
@ -312,9 +772,12 @@ void *Com_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolea
|
||||
if( hInst->custom_loader )
|
||||
{
|
||||
if( hInst->encrypted )
|
||||
{
|
||||
MsgDev( D_ERROR, "Sys_LoadLibrary: couldn't load encrypted library %s\n", dllname );
|
||||
else MsgDev( D_ERROR, "Sys_LoadLibrary: couldn't load library %s from packfile\n", dllname );
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hInst->hInstance = MemoryLoadLibrary( hInst->fullPath );
|
||||
}
|
||||
else hInst->hInstance = LoadLibrary( hInst->fullPath );
|
||||
|
||||
@ -352,9 +815,9 @@ void *Com_GetProcAddress( void *hInstance, const char *name )
|
||||
if( !hInst || !hInst->hInstance )
|
||||
return NULL;
|
||||
|
||||
if( !hInst->custom_loader )
|
||||
return GetProcAddress( hInst->hInstance, name );
|
||||
return NULL;
|
||||
if( hInst->custom_loader )
|
||||
return MemoryGetProcAddress( hInst->hInstance, name );
|
||||
return GetProcAddress( hInst->hInstance, name );
|
||||
}
|
||||
|
||||
void Com_FreeLibrary( void *hInstance )
|
||||
@ -372,8 +835,9 @@ void Com_FreeLibrary( void *hInstance )
|
||||
}
|
||||
else MsgDev( D_NOTE, "Sys_FreeLibrary: Unloading %s\n", hInst->dllName );
|
||||
|
||||
if( !hInst->custom_loader )
|
||||
FreeLibrary( hInst->hInstance );
|
||||
if( hInst->custom_loader )
|
||||
MemoryFreeLibrary( hInst->hInstance );
|
||||
else FreeLibrary( hInst->hInstance );
|
||||
|
||||
hInst->hInstance = NULL;
|
||||
|
||||
|
@ -972,6 +972,10 @@ static void Mod_CalcSurfaceExtents( msurface_t *surf )
|
||||
for( i = 0; i < surf->numedges; i++ )
|
||||
{
|
||||
e = loadmodel->surfedges[surf->firstedge + i];
|
||||
|
||||
if( e >= loadmodel->numedges || e <= -loadmodel->numedges )
|
||||
Host_Error( "Mod_CalcSurfaceBounds: bad edge\n" );
|
||||
|
||||
if( e >= 0 ) v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
|
||||
else v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
|
||||
|
||||
@ -1013,6 +1017,10 @@ static void Mod_CalcSurfaceBounds( msurface_t *surf, mextrasurf_t *info )
|
||||
for( i = 0; i < surf->numedges; i++ )
|
||||
{
|
||||
e = loadmodel->surfedges[surf->firstedge + i];
|
||||
|
||||
if( e >= loadmodel->numedges || e <= -loadmodel->numedges )
|
||||
Host_Error( "Mod_CalcSurfaceBounds: bad edge\n" );
|
||||
|
||||
if( e >= 0 ) v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
|
||||
else v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
|
||||
AddPointToBounds( v->position, info->mins, info->maxs );
|
||||
|
@ -54,7 +54,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /opt:nowin98
|
||||
# ADD LINK32 msvcrt.lib user32.lib gdi32.lib shell32.lib advapi32.lib winmm.lib mpeg.lib ../utils/vgui/lib/win32_vc6/vgui.lib /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /out:"..\temp\engine\!release/xash.dll" /libpath:"./common/soundlib" /opt:nowin98
|
||||
# ADD LINK32 msvcrt.lib user32.lib gdi32.lib shell32.lib advapi32.lib winmm.lib mpeg.lib ../utils/vgui/lib/win32_vc6/vgui.lib /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib:"libc" /out:"..\temp\engine\!release/xash.dll" /libpath:"./common/soundlib" /opt:nowin98
|
||||
# SUBTRACT LINK32 /debug /nodefaultlib
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\engine\!release
|
||||
|
@ -63,6 +63,8 @@ typedef struct physics_interface_s
|
||||
void ( *SV_UpdatePlayerBaseVelocity )( edict_t *ent );
|
||||
// The game .dll should return 1 if save game should be allowed
|
||||
int ( *SV_AllowSaveGame )( void );
|
||||
// override trigger area checking and touching
|
||||
int ( *SV_TriggerTouch )( edict_t *pent, edict_t *trigger );
|
||||
} physics_interface_t;
|
||||
|
||||
#endif//PHYSINT_H
|
@ -1746,7 +1746,11 @@ int SV_BuildSoundMsg( edict_t *ent, int chan, const char *samp, int vol, float a
|
||||
sound_idx = SV_SoundIndex( samp );
|
||||
}
|
||||
|
||||
entityIndex = NUM_FOR_EDICT( ent );
|
||||
if( !ent->v.modelindex || !ent->v.model )
|
||||
entityIndex = 0;
|
||||
else if( SV_IsValidEdict( ent->v.aiment ))
|
||||
entityIndex = NUM_FOR_EDICT( ent->v.aiment );
|
||||
else entityIndex = NUM_FOR_EDICT( ent );
|
||||
|
||||
if( vol != 255 ) flags |= SND_VOLUME;
|
||||
if( attn != ATTN_NONE ) flags |= SND_ATTENUATION;
|
||||
@ -1840,7 +1844,9 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
|
||||
sound_idx = SV_SoundIndex( sample );
|
||||
}
|
||||
|
||||
entityIndex = NUM_FOR_EDICT( ent );
|
||||
if( SV_IsValidEdict( ent->v.aiment ))
|
||||
entityIndex = NUM_FOR_EDICT( ent->v.aiment );
|
||||
else entityIndex = NUM_FOR_EDICT( ent );
|
||||
|
||||
if( sound_idx > 255 ) flags |= SND_LARGE_INDEX;
|
||||
|
||||
@ -1872,7 +1878,7 @@ pfnEmitAmbientSound
|
||||
*/
|
||||
void pfnEmitAmbientSound( edict_t *ent, float *pos, const char *sample, float vol, float attn, int flags, int pitch )
|
||||
{
|
||||
int number, sound_idx;
|
||||
int number = 0, sound_idx;
|
||||
int msg_dest = MSG_PAS_R;
|
||||
|
||||
if( !sample ) return;
|
||||
@ -1898,7 +1904,8 @@ void pfnEmitAmbientSound( edict_t *ent, float *pos, const char *sample, float vo
|
||||
msg_dest = MSG_INIT;
|
||||
else msg_dest = MSG_ALL;
|
||||
|
||||
number = NUM_FOR_EDICT( ent );
|
||||
if( SV_IsValidEdict( ent ))
|
||||
number = NUM_FOR_EDICT( ent );
|
||||
|
||||
// always sending stop sound command
|
||||
if( flags & SND_STOP ) msg_dest = MSG_ALL;
|
||||
|
@ -398,43 +398,52 @@ void SV_TouchLinks( edict_t *ent, areanode_t *node )
|
||||
next = l->next;
|
||||
touch = EDICT_FROM_AREA( l );
|
||||
|
||||
if( touch == ent || touch->v.solid != SOLID_TRIGGER ) // disabled ?
|
||||
continue;
|
||||
|
||||
if( touch->v.groupinfo && ent->v.groupinfo )
|
||||
if( svgame.physFuncs.SV_TriggerTouch != NULL )
|
||||
{
|
||||
if(( !svs.groupop && !(touch->v.groupinfo & ent->v.groupinfo)) ||
|
||||
(svs.groupop == 1 && (touch->v.groupinfo & ent->v.groupinfo)))
|
||||
// user dll can override trigger checking (Xash3D extension)
|
||||
if( !svgame.physFuncs.SV_TriggerTouch( ent, touch ))
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !BoundsIntersect( ent->v.absmin, ent->v.absmax, touch->v.absmin, touch->v.absmax ))
|
||||
continue;
|
||||
|
||||
// check brush triggers accuracy
|
||||
if( Mod_GetType( touch->v.modelindex ) == mod_brush )
|
||||
else
|
||||
{
|
||||
model_t *mod = Mod_Handle( touch->v.modelindex );
|
||||
|
||||
// force to select bsp-hull
|
||||
hull = SV_HullForBsp( touch, ent->v.mins, ent->v.maxs, offset );
|
||||
|
||||
// support for rotational triggers
|
||||
if( (mod->flags & MODEL_HAS_ORIGIN) && !VectorIsNull( touch->v.angles ))
|
||||
{
|
||||
matrix4x4 matrix;
|
||||
Matrix4x4_CreateFromEntity( matrix, touch->v.angles, offset, 1.0f );
|
||||
Matrix4x4_VectorITransform( matrix, ent->v.origin, test );
|
||||
}
|
||||
else
|
||||
{
|
||||
// offset the test point appropriately for this hull.
|
||||
VectorSubtract( ent->v.origin, offset, test );
|
||||
}
|
||||
|
||||
// test hull for intersection with this model
|
||||
if( PM_HullPointContents( hull, hull->firstclipnode, test ) != CONTENTS_SOLID )
|
||||
if( touch == ent || touch->v.solid != SOLID_TRIGGER ) // disabled ?
|
||||
continue;
|
||||
|
||||
if( touch->v.groupinfo && ent->v.groupinfo )
|
||||
{
|
||||
if(( !svs.groupop && !(touch->v.groupinfo & ent->v.groupinfo)) ||
|
||||
(svs.groupop == 1 && (touch->v.groupinfo & ent->v.groupinfo)))
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !BoundsIntersect( ent->v.absmin, ent->v.absmax, touch->v.absmin, touch->v.absmax ))
|
||||
continue;
|
||||
|
||||
// check brush triggers accuracy
|
||||
if( Mod_GetType( touch->v.modelindex ) == mod_brush )
|
||||
{
|
||||
model_t *mod = Mod_Handle( touch->v.modelindex );
|
||||
|
||||
// force to select bsp-hull
|
||||
hull = SV_HullForBsp( touch, ent->v.mins, ent->v.maxs, offset );
|
||||
|
||||
// support for rotational triggers
|
||||
if( (mod->flags & MODEL_HAS_ORIGIN) && !VectorIsNull( touch->v.angles ))
|
||||
{
|
||||
matrix4x4 matrix;
|
||||
Matrix4x4_CreateFromEntity( matrix, touch->v.angles, offset, 1.0f );
|
||||
Matrix4x4_VectorITransform( matrix, ent->v.origin, test );
|
||||
}
|
||||
else
|
||||
{
|
||||
// offset the test point appropriately for this hull.
|
||||
VectorSubtract( ent->v.origin, offset, test );
|
||||
}
|
||||
|
||||
// test hull for intersection with this model
|
||||
if( PM_HullPointContents( hull, hull->firstclipnode, test ) != CONTENTS_SOLID )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
svgame.globals->time = sv.time;
|
||||
|
74
unused/conprint.c
Normal file
74
unused/conprint.c
Normal file
@ -0,0 +1,74 @@
|
||||
dword g_color_table[8] =
|
||||
{
|
||||
FOREGROUND_INTENSITY, // black
|
||||
FOREGROUND_RED|FOREGROUND_INTENSITY, // red
|
||||
FOREGROUND_GREEN|FOREGROUND_INTENSITY, // green
|
||||
FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY, // yellow
|
||||
FOREGROUND_BLUE|FOREGROUND_INTENSITY, // blue
|
||||
FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY, // cyan
|
||||
FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY, // magenta
|
||||
FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE, // default color (white)
|
||||
};
|
||||
|
||||
/*
|
||||
================
|
||||
ConsolePrint
|
||||
|
||||
print into win32 console
|
||||
================
|
||||
*/
|
||||
void ConsolePrint( const char *pMsg )
|
||||
{
|
||||
const char *msg = pMsg;
|
||||
char buffer[32768];
|
||||
char logbuf[32768];
|
||||
char *b = buffer;
|
||||
char *c = logbuf;
|
||||
int i = 0;
|
||||
|
||||
char tmpBuf[8192];
|
||||
HANDLE hOut = GetStdHandle( STD_OUTPUT_HANDLE );
|
||||
char *pTemp = tmpBuf;
|
||||
dword cbWritten;
|
||||
|
||||
while( pMsg && *pMsg )
|
||||
{
|
||||
if( IsColorString( pMsg ))
|
||||
{
|
||||
if(( pTemp - tmpBuf ) > 0 )
|
||||
{
|
||||
// dump accumulated text before change color
|
||||
*pTemp = 0; // terminate string
|
||||
WriteFile( hOut, tmpBuf, Q_strlen( tmpBuf ), &cbWritten, 0 );
|
||||
PrintLog( tmpBuf );
|
||||
pTemp = tmpBuf;
|
||||
}
|
||||
|
||||
// set new color
|
||||
SetConsoleTextAttribute( hOut, g_color_table[ColorIndex( *(pMsg + 1))] );
|
||||
pMsg += 2; // skip color info
|
||||
}
|
||||
else if(( pTemp - tmpBuf ) < sizeof( tmpBuf ) - 1 )
|
||||
{
|
||||
*pTemp++ = *pMsg++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// temp buffer is full, dump it now
|
||||
*pTemp = 0; // terminate string
|
||||
WriteFile( hOut, tmpBuf, Q_strlen( tmpBuf ), &cbWritten, 0 );
|
||||
PrintLog( tmpBuf );
|
||||
pTemp = tmpBuf;
|
||||
}
|
||||
}
|
||||
|
||||
// check for last portion
|
||||
if(( pTemp - tmpBuf ) > 0 )
|
||||
{
|
||||
// dump accumulated text
|
||||
*pTemp = 0; // terminate string
|
||||
WriteFile( hOut, tmpBuf, Q_strlen( tmpBuf ), &cbWritten, 0 );
|
||||
PrintLog( tmpBuf );
|
||||
pTemp = tmpBuf;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user