Added support for Alien Swarm (bug 4529, r=dvander).

This commit is contained in:
Scott Ehlert 2010-07-28 01:35:40 -05:00
parent 6646ae8a84
commit 10ff866969
9 changed files with 74 additions and 18 deletions

View File

@ -21,6 +21,8 @@ class MMS:
'name': 'LEFT4DEAD2', 'platform': ['windows', 'linux']}
self.sdkInfo['darkm'] = {'sdk': 'HL2SDK-DARKM', 'ext': '2.darkm', 'def': '2',
'name': 'DARKMESSIAH', 'platform': ['windows']}
self.sdkInfo['swarm'] = {'sdk': 'HL2SDK-SWARM', 'ext': '2.swarm', 'def': '7',
'name': 'ALIENSWARM', 'platform': ['windows']}
if AMBuild.mode == 'config':
#Detect compilers
@ -39,6 +41,7 @@ class MMS:
#Dark Messiah is Windows-only
if AMBuild.target['platform'] == 'windows':
envvars['HL2SDK-DARKM'] = 'hl2sdk-darkm'
envvars['HL2SDK-SWARM'] = 'hl2sdk-swarm'
#Must have a path for each envvar (file a bug if you don't like this)
for i in envvars:
@ -90,6 +93,7 @@ class MMS:
self.vendor = 'msvc'
if AMBuild.options.debug == '1':
self.compiler.AddToListVar('CFLAGS', '/MTd')
self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
else:
self.compiler.AddToListVar('CFLAGS', '/MT')
self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
@ -241,7 +245,10 @@ class MMS:
except:
job.AddCommand(SymlinkCommand(link, target))
elif AMBuild.target['platform'] == 'windows':
for lib in ['tier0', 'tier1', 'vstdlib']:
libs = ['tier0', 'tier1', 'vstdlib']
if sdk == 'swarm':
libs.append('interfaces')
for lib in libs:
libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
builder.RebuildIfNewer(libPath)
builder['POSTLINKFLAGS'].append(libPath)
@ -275,6 +282,9 @@ class MMS:
compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
if sdk == 'swarm' and AMBuild.target['platform'] == 'windows':
compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
if sdk == 'ep1':
if AMBuild.target['platform'] == 'linux':
staticLibs = os.path.join(sdkPath, 'linux_sdk')

View File

@ -43,6 +43,7 @@
#define SOURCE_ENGINE_DARKMESSIAH 5 /**< Dark Messiah Multiplayer (based on original engine) */
#define SOURCE_ENGINE_ORANGEBOXVALVE 6 /**< Orange Box Source Engine for Valve games (TF2/DOD:S) */
#define SOURCE_ENGINE_LEFT4DEAD2 7 /**< Left 4 Dead 2 */
#define SOURCE_ENGINE_ALIENSWARM 8 /**< Alien Swarm */
#define METAMOD_PLAPI_VERSION 15 /**< Version of this header file */
#define METAMOD_PLAPI_NAME "ISmmPlugin" /**< Name of the plugin interface */

View File

@ -111,7 +111,9 @@ bool Command_Meta(IMetamodSourceCommandInfo *info)
}
#endif
#if SOURCE_ENGINE == SE_LEFT4DEAD2
#if SOURCE_ENGINE == SE_ALIENSWARM
CONMSG(" Engine: Alien Swarm (2010)\n");
#elif SOURCE_ENGINE == SE_LEFT4DEAD2
CONMSG(" Engine: Left 4 Dead 2 (2009)\n");
#elif SOURCE_ENGINE == SE_LEFT4DEAD
CONMSG(" Engine: Left 4 Dead (2008)\n");

View File

@ -41,7 +41,9 @@ SMConVarAccessor g_SMConVarAccessor;
bool SMConVarAccessor::RegisterConCommandBase(ConCommandBase *pCommand)
{
m_RegisteredCommands.push_back(pCommand);
#if SOURCE_ENGINE != SE_ALIENSWARM
pCommand->SetNext(NULL);
#endif
icvar->RegisterConCommand(pCommand);
return true;
@ -49,7 +51,9 @@ bool SMConVarAccessor::RegisterConCommandBase(ConCommandBase *pCommand)
bool SMConVarAccessor::Register(ConCommandBase *pCommand)
{
#if SOURCE_ENGINE != SE_ALIENSWARM
pCommand->SetNext(NULL);
#endif
icvar->RegisterConCommand(pCommand);
return true;

View File

@ -28,18 +28,10 @@
#ifndef _INCLUDE_CONSOLE_MMS_H_
#define _INCLUDE_CONSOLE_MMS_H_
#if defined _DEBUG
#define DEBUG2
#undef _DEBUG
#endif
#include <interface.h>
#include "convar.h"
#include <eiface.h>
#include <sh_list.h>
#if defined DEBUG2
#undef DEBUG2
#define _DEBUG
#endif
class SMConVarAccessor : public IConCommandBaseAccessor
{

View File

@ -358,7 +358,9 @@ const char *BaseProvider::GetGameDescription()
int BaseProvider::DetermineSourceEngine(const char *game)
{
#if SOURCE_ENGINE == SE_LEFT4DEAD2
#if SOURCE_ENGINE == SE_ALIENSWARM
return SOURCE_ENGINE_ALIENSWARM;
#elif SOURCE_ENGINE == SE_LEFT4DEAD2
return SOURCE_ENGINE_LEFT4DEAD2;
#elif SOURCE_ENGINE == SE_LEFT4DEAD
return SOURCE_ENGINE_LEFT4DEAD;

View File

@ -75,7 +75,8 @@ static const char *backend_names[] =
"2.ep2",
"2.ep2v",
"2.l4d",
"2.l4d2"
"2.l4d2",
"2.swarm"
};
#if defined _WIN32
@ -212,6 +213,13 @@ mm_GetGameName()
}
valve_cmdline = (GetCommandLine)mm_GetLibAddress(lib, "CommandLine_Tier0");
/* '_Tier0' dropped on Alien Swarm version */
if (valve_cmdline == NULL)
{
valve_cmdline = (GetCommandLine)mm_GetLibAddress(lib, "CommandLine");
}
if (valve_cmdline == NULL)
{
/* We probably have a Ship engine. */
@ -257,7 +265,11 @@ mm_DetermineBackend(QueryValveInterface engineFactory, const char *game_name)
if (engineFactory("VEngineServer022", NULL) != NULL &&
engineFactory("VEngineCvar007", NULL) != NULL)
{
if (engineFactory("VPrecacheSystem001", NULL) != NULL)
if (engineFactory("EngineTraceServer004", NULL) != NULL)
{
return MMBackend_AlienSwarm;
}
else if (engineFactory("VPrecacheSystem001", NULL) != NULL)
{
return MMBackend_Left4Dead2;
}

View File

@ -86,6 +86,7 @@ enum MetamodBackend
MMBackend_Episode2Valve,
MMBackend_Left4Dead,
MMBackend_Left4Dead2,
MMBackend_AlienSwarm,
MMBackend_UNKNOWN
};

View File

@ -101,11 +101,14 @@ public:
mm_LogFatal("Could not detect engine version");
return false;
}
else if (mm_backend >= MMBackend_Episode2)
void **this_vtable;
this_vtable = (void **)*(void **)this;
if (mm_backend >= MMBackend_Episode2)
{
/* We need to insert the right type of call into this vtable */
void **vtable_src;
void **vtable_dest;
IRandomThings sample;
SourceHook::MemFuncInfo mfp_dest, mfp_src;
@ -123,13 +126,37 @@ public:
assert(mfp_src.vtbloffs == 0);
vtable_src = (void **)*(void **)&sample;
vtable_dest = (void **)*(void **)this;
SourceHook::SetMemAccess(&vtable_dest[mfp_dest.vtblindex],
SourceHook::SetMemAccess(&this_vtable[mfp_dest.vtblindex],
sizeof(void*),
SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC);
vtable_dest[mfp_dest.vtblindex] = vtable_src[mfp_src.vtblindex];
this_vtable[mfp_dest.vtblindex] = vtable_src[mfp_src.vtblindex];
}
#ifdef _WIN32
/* AS inserted ClientFullyConnect into vtable, so move entries up on older engines */
if (mm_backend != MMBackend_AlienSwarm)
{
SourceHook::MemFuncInfo mfp_fconnect;
mfp_fconnect.isVirtual = false;
SourceHook::GetFuncInfo(&ServerPlugin::ClientFullyConnect, mfp_fconnect);
assert(mfp_fconnect.isVirtual);
assert(mfp_fconnect.thisptroffs == 0);
assert(mfp_fconnect.vtbloffs == 0);
/* Shifting ClientDisconnect through OnQueryCvarValueFinished up into slot for
* ClientFullyConnect (8 entries)
*/
SourceHook::SetMemAccess(&this_vtable[mfp_fconnect.vtblindex],
sizeof(void *) * 8,
SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC);
memmove(&this_vtable[mfp_fconnect.vtblindex],
&this_vtable[mfp_fconnect.vtblindex + 1],
sizeof(void *) * 8);
}
#endif
char error[255];
if (gamedll_bridge == NULL)
{
@ -213,6 +240,11 @@ public:
virtual void ClientActive(edict_t *pEntity)
{
}
#ifdef _WIN32
virtual void ClientFullyConnect(edict_t *pEntity)
{
}
#endif
virtual void ClientDisconnect(edict_t *pEntity)
{
}