mirror of
https://github.com/rehlds/revoice.git
synced 2025-03-29 05:39:19 +03:00
Fixed some bugs.
Add "rev status" to print detailed info Update rehlsdk
This commit is contained in:
parent
d271a42878
commit
2f2b7fe48a
164
dep/rehlsdk/common/BaseSystemModule.cpp
Normal file
164
dep/rehlsdk/common/BaseSystemModule.cpp
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
BaseSystemModule::BaseSystemModule()
|
||||||
|
{
|
||||||
|
m_System = nullptr;
|
||||||
|
m_Serial = 0;
|
||||||
|
m_SystemTime = 0;
|
||||||
|
m_State = MODULE_UNDEFINED;
|
||||||
|
|
||||||
|
Q_memset(m_Name, 0, sizeof(m_Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
char *BaseSystemModule::GetName()
|
||||||
|
{
|
||||||
|
return m_Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *BaseSystemModule::GetType()
|
||||||
|
{
|
||||||
|
return "GenericModule";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *BaseSystemModule::GetStatusLine()
|
||||||
|
{
|
||||||
|
return "No status available.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseSystemModule::ExecuteCommand(int commandID, char *commandLine)
|
||||||
|
{
|
||||||
|
m_System->DPrintf("WARNING! Undeclared ExecuteCommand().\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int COM_BuildNumber();
|
||||||
|
|
||||||
|
int BaseSystemModule::GetVersion()
|
||||||
|
{
|
||||||
|
return COM_BuildNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
int BaseSystemModule::GetSerial()
|
||||||
|
{
|
||||||
|
return m_Serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
IBaseSystem *BaseSystemModule::GetSystem()
|
||||||
|
{
|
||||||
|
return m_System;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseSystemModule::Init(IBaseSystem *system, int serial, char *name)
|
||||||
|
{
|
||||||
|
if (!system)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_State = MODULE_INITIALIZING;
|
||||||
|
m_System = system;
|
||||||
|
m_Serial = serial;
|
||||||
|
m_SystemTime = 0;
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
Q_strlcpy(m_Name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseSystemModule::RunFrame(double time)
|
||||||
|
{
|
||||||
|
m_SystemTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseSystemModule::ShutDown()
|
||||||
|
{
|
||||||
|
if (m_State == MODULE_DISCONNECTED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_Listener.Clear();
|
||||||
|
m_State = MODULE_DISCONNECTED;
|
||||||
|
|
||||||
|
if (!m_System->RemoveModule(this))
|
||||||
|
{
|
||||||
|
m_System->DPrintf("ERROR! BaseSystemModule::ShutDown: faild to remove module %s.\n", m_Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseSystemModule::RegisterListener(ISystemModule *module)
|
||||||
|
{
|
||||||
|
ISystemModule *listener = (ISystemModule *)m_Listener.GetFirst();
|
||||||
|
while (listener)
|
||||||
|
{
|
||||||
|
if (listener->GetSerial() == module->GetSerial())
|
||||||
|
{
|
||||||
|
m_System->DPrintf("WARNING! BaseSystemModule::RegisterListener: module %s already added.\n", module->GetName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
listener = (ISystemModule *)m_Listener.GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Listener.Add(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseSystemModule::RemoveListener(ISystemModule *module)
|
||||||
|
{
|
||||||
|
ISystemModule *listener = (ISystemModule *)m_Listener.GetFirst();
|
||||||
|
while (listener)
|
||||||
|
{
|
||||||
|
if (listener->GetSerial() == module->GetSerial())
|
||||||
|
{
|
||||||
|
m_Listener.Remove(module);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
listener = (ISystemModule *)m_Listener.GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseSystemModule::FireSignal(unsigned int signal, void *data)
|
||||||
|
{
|
||||||
|
ISystemModule *listener = (ISystemModule *)m_Listener.GetFirst();
|
||||||
|
while (listener)
|
||||||
|
{
|
||||||
|
listener->ReceiveSignal(this, signal, data);
|
||||||
|
listener = (ISystemModule *)m_Listener.GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseSystemModule::ReceiveSignal(ISystemModule *module, unsigned int signal, void *data)
|
||||||
|
{
|
||||||
|
m_System->DPrintf("WARNING! Unhandled signal (%i) from module %s.\n", signal, module->GetName());
|
||||||
|
}
|
||||||
|
|
||||||
|
int BaseSystemModule::GetState()
|
||||||
|
{
|
||||||
|
return m_State;
|
||||||
|
}
|
75
dep/rehlsdk/common/BaseSystemModule.h
Normal file
75
dep/rehlsdk/common/BaseSystemModule.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ObjectList.h"
|
||||||
|
#include "IBaseSystem.h"
|
||||||
|
|
||||||
|
// C4250 - 'class1' : inherits 'BaseSystemModule::member' via dominance
|
||||||
|
#pragma warning(disable:4250)
|
||||||
|
|
||||||
|
class BaseSystemModule: virtual public ISystemModule {
|
||||||
|
public:
|
||||||
|
BaseSystemModule();
|
||||||
|
virtual ~BaseSystemModule() {}
|
||||||
|
|
||||||
|
EXT_FUNC virtual bool Init(IBaseSystem *system, int serial, char *name);
|
||||||
|
EXT_FUNC virtual void RunFrame(double time);
|
||||||
|
EXT_FUNC virtual void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data);
|
||||||
|
EXT_FUNC virtual void ExecuteCommand(int commandID, char *commandLine);
|
||||||
|
EXT_FUNC virtual void RegisterListener(ISystemModule *module);
|
||||||
|
EXT_FUNC virtual void RemoveListener(ISystemModule *module);
|
||||||
|
EXT_FUNC virtual IBaseSystem *GetSystem();
|
||||||
|
EXT_FUNC virtual int GetSerial();
|
||||||
|
EXT_FUNC virtual char *GetStatusLine();
|
||||||
|
EXT_FUNC virtual char *GetType();
|
||||||
|
EXT_FUNC virtual char *GetName();
|
||||||
|
|
||||||
|
enum ModuleState {
|
||||||
|
MODULE_UNDEFINED = 0,
|
||||||
|
MODULE_INITIALIZING,
|
||||||
|
MODULE_CONNECTING,
|
||||||
|
MODULE_RUNNING,
|
||||||
|
MODULE_DISCONNECTED
|
||||||
|
};
|
||||||
|
|
||||||
|
EXT_FUNC virtual int GetState();
|
||||||
|
EXT_FUNC virtual int GetVersion();
|
||||||
|
EXT_FUNC virtual void ShutDown();
|
||||||
|
EXT_FUNC virtual char *GetBaseDir() { return ""; }
|
||||||
|
void FireSignal(unsigned int signal, void *data = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
IBaseSystem *m_System;
|
||||||
|
ObjectList m_Listener;
|
||||||
|
char m_Name[255];
|
||||||
|
unsigned int m_State;
|
||||||
|
unsigned int m_Serial;
|
||||||
|
double m_SystemTime;
|
||||||
|
};
|
54
dep/rehlsdk/common/IAdminServer.h
Normal file
54
dep/rehlsdk/common/IAdminServer.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "interface.h"
|
||||||
|
|
||||||
|
// handle to a game window
|
||||||
|
typedef unsigned int ManageServerUIHandle_t;
|
||||||
|
class IManageServer;
|
||||||
|
|
||||||
|
// Purpose: Interface to server administration functions
|
||||||
|
class IAdminServer: public IBaseInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// opens a manage server dialog for a local server
|
||||||
|
virtual ManageServerUIHandle_t OpenManageServerDialog(const char *serverName, const char *gameDir) = 0;
|
||||||
|
|
||||||
|
// opens a manage server dialog to a remote server
|
||||||
|
virtual ManageServerUIHandle_t OpenManageServerDialog(unsigned int gameIP, unsigned int gamePort, const char *password) = 0;
|
||||||
|
|
||||||
|
// forces the game info dialog closed
|
||||||
|
virtual void CloseManageServerDialog(ManageServerUIHandle_t gameDialog) = 0;
|
||||||
|
|
||||||
|
// Gets a handle to the interface
|
||||||
|
virtual IManageServer *GetManageServerInterface(ManageServerUIHandle_t handle) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ADMINSERVER_INTERFACE_VERSION "AdminServer002"
|
91
dep/rehlsdk/common/IBaseSystem.h
Normal file
91
dep/rehlsdk/common/IBaseSystem.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#define LIBRARY_PREFIX "dll"
|
||||||
|
#elif defined(OSX)
|
||||||
|
#define LIBRARY_PREFIX "dylib"
|
||||||
|
#else
|
||||||
|
#define LIBRARY_PREFIX "so"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ISystemModule.h"
|
||||||
|
#include "IVGuiModule.h"
|
||||||
|
|
||||||
|
class Panel;
|
||||||
|
class ObjectList;
|
||||||
|
class IFileSystem;
|
||||||
|
|
||||||
|
class IBaseSystem: virtual public ISystemModule {
|
||||||
|
public:
|
||||||
|
virtual ~IBaseSystem() {}
|
||||||
|
|
||||||
|
virtual double GetTime() = 0;
|
||||||
|
virtual unsigned int GetTick() = 0;
|
||||||
|
virtual void SetFPS(float fps) = 0;
|
||||||
|
|
||||||
|
virtual void Printf(char *fmt, ...) = 0;
|
||||||
|
virtual void DPrintf(char *fmt, ...) = 0;
|
||||||
|
|
||||||
|
virtual void RedirectOutput(char *buffer = nullptr, int maxSize = 0) = 0;
|
||||||
|
|
||||||
|
virtual IFileSystem *GetFileSystem() = 0;
|
||||||
|
virtual unsigned char *LoadFile(const char *name, int *length = nullptr) = 0;
|
||||||
|
virtual void FreeFile(unsigned char *fileHandle) = 0;
|
||||||
|
|
||||||
|
virtual void SetTitle(char *text) = 0;
|
||||||
|
virtual void SetStatusLine(char *text) = 0;
|
||||||
|
|
||||||
|
virtual void ShowConsole(bool visible) = 0;
|
||||||
|
virtual void LogConsole(char *filename) = 0;
|
||||||
|
|
||||||
|
virtual bool InitVGUI(IVGuiModule *module) = 0;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
virtual Panel *GetPanel() = 0;
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
virtual bool RegisterCommand(char *name, ISystemModule *module, int commandID) = 0;
|
||||||
|
virtual void GetCommandMatches(char *string, ObjectList *pMatchList) = 0;
|
||||||
|
virtual void ExecuteString(char *commands) = 0;
|
||||||
|
virtual void ExecuteFile(char *filename) = 0;
|
||||||
|
virtual void Errorf(char *fmt, ...) = 0;
|
||||||
|
|
||||||
|
virtual char *CheckParam(char *param) = 0;
|
||||||
|
|
||||||
|
virtual bool AddModule(ISystemModule *module, char *name) = 0;
|
||||||
|
virtual ISystemModule *GetModule(char *interfacename, char *library, char *instancename = nullptr) = 0;
|
||||||
|
virtual bool RemoveModule(ISystemModule *module) = 0;
|
||||||
|
|
||||||
|
virtual void Stop() = 0;
|
||||||
|
virtual char *GetBaseDir() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BASESYSTEM_INTERFACE_VERSION "basesystem002"
|
93
dep/rehlsdk/common/IDemoPlayer.h
Normal file
93
dep/rehlsdk/common/IDemoPlayer.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ref_params.h"
|
||||||
|
|
||||||
|
class IWorld;
|
||||||
|
class IProxy;
|
||||||
|
class DirectorCmd;
|
||||||
|
class IBaseSystem;
|
||||||
|
class ISystemModule;
|
||||||
|
class IObjectContainer;
|
||||||
|
|
||||||
|
class IDemoPlayer {
|
||||||
|
public:
|
||||||
|
virtual ~IDemoPlayer() {}
|
||||||
|
|
||||||
|
virtual bool Init(IBaseSystem *system, int serial, char *name) = 0;
|
||||||
|
virtual void RunFrame(double time) = 0;
|
||||||
|
virtual void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data) = 0;
|
||||||
|
virtual void ExecuteCommand(int commandID, char *commandLine) = 0;
|
||||||
|
virtual void RegisterListener(ISystemModule *module) = 0;
|
||||||
|
virtual void RemoveListener(ISystemModule *module) = 0;
|
||||||
|
virtual IBaseSystem *GetSystem() = 0;
|
||||||
|
virtual int GetSerial() = 0;
|
||||||
|
virtual char *GetStatusLine() = 0;
|
||||||
|
virtual char *GetType() = 0;
|
||||||
|
virtual char *GetName() = 0;
|
||||||
|
virtual int GetState() = 0;
|
||||||
|
virtual int GetVersion() = 0;
|
||||||
|
virtual void ShutDown() = 0;
|
||||||
|
|
||||||
|
virtual void NewGame(IWorld *world, IProxy *proxy = nullptr) = 0;
|
||||||
|
virtual char *GetModName() = 0;
|
||||||
|
virtual void WriteCommands(BitBuffer *stream, float startTime, float endTime) = 0;
|
||||||
|
virtual int AddCommand(DirectorCmd *cmd) = 0;
|
||||||
|
virtual bool RemoveCommand(int index) = 0;
|
||||||
|
virtual DirectorCmd *GetLastCommand() = 0;
|
||||||
|
virtual IObjectContainer *GetCommands() = 0;
|
||||||
|
virtual void SetWorldTime(double time, bool relative) = 0;
|
||||||
|
virtual void SetTimeScale(float scale) = 0;
|
||||||
|
virtual void SetPaused(bool state) = 0;
|
||||||
|
virtual void SetEditMode(bool state) = 0;
|
||||||
|
virtual void SetMasterMode(bool state) = 0;
|
||||||
|
virtual bool IsPaused() = 0;
|
||||||
|
virtual bool IsLoading() = 0;
|
||||||
|
virtual bool IsActive() = 0;
|
||||||
|
virtual bool IsEditMode() = 0;
|
||||||
|
virtual bool IsMasterMode() = 0;
|
||||||
|
virtual void RemoveFrames(double starttime, double endtime) = 0;
|
||||||
|
virtual void ExecuteDirectorCmd(DirectorCmd *cmd) = 0;
|
||||||
|
virtual double GetWorldTime() = 0;
|
||||||
|
virtual double GetStartTime() = 0;
|
||||||
|
virtual double GetEndTime() = 0;
|
||||||
|
virtual float GetTimeScale() = 0;
|
||||||
|
virtual IWorld *GetWorld() = 0;
|
||||||
|
virtual char *GetFileName() = 0;
|
||||||
|
virtual bool SaveGame(char *filename) = 0;
|
||||||
|
virtual bool LoadGame(char *filename) = 0;
|
||||||
|
virtual void Stop() = 0;
|
||||||
|
virtual void ForceHLTV(bool state) = 0;
|
||||||
|
virtual void GetDemoViewInfo(ref_params_t *rp, float *view, int *viewmodel) = 0;
|
||||||
|
virtual int ReadDemoMessage(unsigned char *buffer, int size) = 0;
|
||||||
|
virtual void ReadNetchanState(int *incoming_sequence, int *incoming_acknowledged, int *incoming_reliable_acknowledged, int *incoming_reliable_sequence, int *outgoing_sequence, int *reliable_sequence, int *last_reliable_sequence) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEMOPLAYER_INTERFACE_VERSION "demoplayer001"
|
56
dep/rehlsdk/common/IEngineWrapper.h
Normal file
56
dep/rehlsdk/common/IEngineWrapper.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "event_args.h"
|
||||||
|
#include "vmodes.h"
|
||||||
|
#include "cdll_int.h"
|
||||||
|
|
||||||
|
class IBaseSystem;
|
||||||
|
class ISystemModule;
|
||||||
|
|
||||||
|
class IEngineWrapper: virtual public ISystemModule {
|
||||||
|
public:
|
||||||
|
virtual ~IEngineWrapper() {}
|
||||||
|
|
||||||
|
virtual bool GetViewOrigin(float *origin) = 0;
|
||||||
|
virtual bool GetViewAngles(float *angles) = 0;
|
||||||
|
virtual int GetTraceEntity() = 0;
|
||||||
|
virtual float GetCvarFloat(char *szName) = 0;
|
||||||
|
virtual char *GetCvarString(char *szName) = 0;
|
||||||
|
virtual void SetCvar(char *szName, char *szValue) = 0;
|
||||||
|
virtual void Cbuf_AddText(char *text) = 0;
|
||||||
|
virtual void DemoUpdateClientData(client_data_t *cdat) = 0;
|
||||||
|
virtual void CL_QueueEvent(int flags, int index, float delay, event_args_t *pargs) = 0;
|
||||||
|
virtual void HudWeaponAnim(int iAnim, int body) = 0;
|
||||||
|
virtual void CL_DemoPlaySound(int channel, char *sample, float attenuation, float volume, int flags, int pitch) = 0;
|
||||||
|
virtual void ClientDLL_ReadDemoBuffer(int size, unsigned char *buffer) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ENGINEWRAPPER_INTERFACE_VERSION "enginewrapper001"
|
47
dep/rehlsdk/common/IObjectContainer.h
Normal file
47
dep/rehlsdk/common/IObjectContainer.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class IObjectContainer {
|
||||||
|
public:
|
||||||
|
virtual ~IObjectContainer() {}
|
||||||
|
|
||||||
|
virtual void Init() = 0;
|
||||||
|
|
||||||
|
virtual bool Add(void *newObject) = 0;
|
||||||
|
virtual bool Remove(void *object) = 0;
|
||||||
|
virtual void Clear(bool freeElementsMemory) = 0;
|
||||||
|
|
||||||
|
virtual void *GetFirst() = 0;
|
||||||
|
virtual void *GetNext() = 0;
|
||||||
|
|
||||||
|
virtual int CountElements() = 0;
|
||||||
|
virtual bool Contains(void *object) = 0;
|
||||||
|
virtual bool IsEmpty() = 0;
|
||||||
|
};
|
57
dep/rehlsdk/common/ISystemModule.h
Normal file
57
dep/rehlsdk/common/ISystemModule.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "interface.h"
|
||||||
|
|
||||||
|
class IBaseSystem;
|
||||||
|
class ISystemModule;
|
||||||
|
|
||||||
|
class ISystemModule: public IBaseInterface {
|
||||||
|
public:
|
||||||
|
virtual ~ISystemModule() {}
|
||||||
|
virtual bool Init(IBaseSystem *system, int serial, char *name) = 0;
|
||||||
|
|
||||||
|
virtual void RunFrame(double time) = 0;
|
||||||
|
virtual void ReceiveSignal(ISystemModule *module, unsigned int signal, void *data = nullptr) = 0;
|
||||||
|
virtual void ExecuteCommand(int commandID, char *commandLine) = 0;
|
||||||
|
virtual void RegisterListener(ISystemModule *module) = 0;
|
||||||
|
virtual void RemoveListener(ISystemModule *module) = 0;
|
||||||
|
|
||||||
|
virtual IBaseSystem *GetSystem() = 0;
|
||||||
|
|
||||||
|
virtual int GetSerial() = 0;
|
||||||
|
virtual char *GetStatusLine() = 0;
|
||||||
|
virtual char *GetType() = 0;
|
||||||
|
virtual char *GetName() = 0;
|
||||||
|
|
||||||
|
virtual int GetState() = 0;
|
||||||
|
virtual int GetVersion() = 0;
|
||||||
|
virtual void ShutDown() = 0;
|
||||||
|
};
|
76
dep/rehlsdk/common/IVGuiModule.h
Normal file
76
dep/rehlsdk/common/IVGuiModule.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vgui/VGUI.h>
|
||||||
|
#include "interface.h"
|
||||||
|
|
||||||
|
// Purpose: Standard interface to loading vgui modules
|
||||||
|
class IVGuiModule: public IBaseInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// called first to setup the module with the vgui
|
||||||
|
// returns true on success, false on failure
|
||||||
|
virtual bool Initialize(CreateInterfaceFn *vguiFactories, int factoryCount) = 0;
|
||||||
|
|
||||||
|
// called after all the modules have been initialized
|
||||||
|
// modules should use this time to link to all the other module interfaces
|
||||||
|
virtual bool PostInitialize(CreateInterfaceFn *modules = nullptr, int factoryCount = 0) = 0;
|
||||||
|
|
||||||
|
// called when the module is selected from the menu or otherwise activated
|
||||||
|
virtual bool Activate() = 0;
|
||||||
|
|
||||||
|
// returns true if the module is successfully initialized and available
|
||||||
|
virtual bool IsValid() = 0;
|
||||||
|
|
||||||
|
// requests that the UI is temporarily disabled and all data files saved
|
||||||
|
virtual void Deactivate() = 0;
|
||||||
|
|
||||||
|
// restart from a Deactivate()
|
||||||
|
virtual void Reactivate() = 0;
|
||||||
|
|
||||||
|
// called when the module is about to be shutdown
|
||||||
|
virtual void Shutdown() = 0;
|
||||||
|
|
||||||
|
// returns a handle to the main module panel
|
||||||
|
virtual vgui2::VPANEL GetPanel() = 0;
|
||||||
|
|
||||||
|
// sets the parent of the main module panel
|
||||||
|
virtual void SetParent(vgui2::VPANEL parent) = 0;
|
||||||
|
|
||||||
|
// messages sent through through the panel returned by GetPanel():
|
||||||
|
//
|
||||||
|
// "ConnectedToGame" "ip" "port" "gamedir"
|
||||||
|
// "DisconnectedFromGame"
|
||||||
|
// "ActiveGameName" "name"
|
||||||
|
// "LoadingStarted" "type" "name"
|
||||||
|
// "LoadingFinished" "type" "name"
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VGUIMODULE_INTERFACE_VERSION "VGuiModuleAdminServer001"
|
515
dep/rehlsdk/common/ObjectDictionary.cpp
Normal file
515
dep/rehlsdk/common/ObjectDictionary.cpp
Normal file
@ -0,0 +1,515 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
ObjectDictionary::ObjectDictionary()
|
||||||
|
{
|
||||||
|
m_currentEntry = 0;
|
||||||
|
m_findKey = 0;
|
||||||
|
m_entries = nullptr;
|
||||||
|
|
||||||
|
Q_memset(m_cache, 0, sizeof(m_cache));
|
||||||
|
|
||||||
|
m_cacheIndex = 0;
|
||||||
|
m_size = 0;
|
||||||
|
m_maxSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectDictionary::~ObjectDictionary()
|
||||||
|
{
|
||||||
|
if (m_entries) {
|
||||||
|
Mem_Free(m_entries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectDictionary::Clear(bool freeObjectssMemory)
|
||||||
|
{
|
||||||
|
if (freeObjectssMemory)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
void *obj = m_entries[i].object;
|
||||||
|
if (obj) {
|
||||||
|
Mem_Free(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_size = 0;
|
||||||
|
CheckSize();
|
||||||
|
ClearCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectDictionary::Add(void *object, float key)
|
||||||
|
{
|
||||||
|
if (m_size == m_maxSize && !CheckSize())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
entry_t *p;
|
||||||
|
if (m_size && key < m_entries[m_size - 1].key)
|
||||||
|
{
|
||||||
|
p = &m_entries[FindClosestAsIndex(key)];
|
||||||
|
|
||||||
|
entry_t *e1 = &m_entries[m_size];
|
||||||
|
entry_t *e2 = &m_entries[m_size - 1];
|
||||||
|
|
||||||
|
while (p->key <= key) { p++; }
|
||||||
|
while (p != e1)
|
||||||
|
{
|
||||||
|
e1->object = e2->object;
|
||||||
|
e1->key = e2->key;
|
||||||
|
|
||||||
|
e1--;
|
||||||
|
e2--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p = &m_entries[m_size];
|
||||||
|
|
||||||
|
p->key = key;
|
||||||
|
p->object = object;
|
||||||
|
m_size++;
|
||||||
|
|
||||||
|
ClearCache();
|
||||||
|
AddToCache(p);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ObjectDictionary::FindClosestAsIndex(float key)
|
||||||
|
{
|
||||||
|
if (m_size <= 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (key <= m_entries->key)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int index = FindKeyInCache(key);
|
||||||
|
if (index >= 0) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int middle;
|
||||||
|
int first = 0;
|
||||||
|
int last = m_size - 1;
|
||||||
|
float keyMiddle, keyNext;
|
||||||
|
|
||||||
|
if (key < m_entries[last].key)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
middle = (last + first) >> 1;
|
||||||
|
keyMiddle = m_entries[middle].key;
|
||||||
|
|
||||||
|
if (keyMiddle == key)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (keyMiddle < key)
|
||||||
|
{
|
||||||
|
if (m_entries[middle + 1].key >= key)
|
||||||
|
{
|
||||||
|
if (m_entries[middle + 1].key - key < key - keyMiddle)
|
||||||
|
++middle;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
first = (last + first) >> 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last = (last + first) >> 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
middle = last;
|
||||||
|
}
|
||||||
|
|
||||||
|
keyNext = m_entries[middle - 1].key;
|
||||||
|
while (keyNext == key) {
|
||||||
|
keyNext = m_entries[middle--].key;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddToCache(&m_entries[middle], key);
|
||||||
|
return middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectDictionary::ClearCache()
|
||||||
|
{
|
||||||
|
Q_memset(m_cache, 0, sizeof(m_cache));
|
||||||
|
m_cacheIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectDictionary::RemoveIndex(int index, bool freeObjectMemory)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= m_size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
entry_t *p = &m_entries[m_size - 1];
|
||||||
|
entry_t *e1 = &m_entries[index];
|
||||||
|
entry_t *e2 = &m_entries[index + 1];
|
||||||
|
|
||||||
|
if (freeObjectMemory && e1->object)
|
||||||
|
Mem_Free(e1->object);
|
||||||
|
|
||||||
|
while (p != e1)
|
||||||
|
{
|
||||||
|
e1->object = e2->object;
|
||||||
|
e1->key = e2->key;
|
||||||
|
|
||||||
|
e1++;
|
||||||
|
e2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->object = nullptr;
|
||||||
|
p->key = 0;
|
||||||
|
m_size--;
|
||||||
|
|
||||||
|
CheckSize();
|
||||||
|
ClearCache();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectDictionary::RemoveIndexRange(int minIndex, int maxIndex)
|
||||||
|
{
|
||||||
|
if (minIndex > maxIndex)
|
||||||
|
{
|
||||||
|
if (maxIndex < 0)
|
||||||
|
maxIndex = 0;
|
||||||
|
|
||||||
|
if (minIndex >= m_size)
|
||||||
|
minIndex = m_size - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (minIndex < 0)
|
||||||
|
minIndex = 0;
|
||||||
|
|
||||||
|
if (maxIndex >= m_size)
|
||||||
|
maxIndex = m_size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = minIndex + maxIndex - 1;
|
||||||
|
m_size -= offset;
|
||||||
|
CheckSize();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectDictionary::Remove(void *object)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
for (int i = 0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
if (m_entries[i].object == object) {
|
||||||
|
RemoveIndex(i);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectDictionary::RemoveSingle(void *object)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
if (m_entries[i].object == object) {
|
||||||
|
RemoveIndex(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectDictionary::RemoveKey(float key)
|
||||||
|
{
|
||||||
|
int i = FindClosestAsIndex(key);
|
||||||
|
if (m_entries[i].key == key)
|
||||||
|
{
|
||||||
|
int j = i;
|
||||||
|
do {
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
while (key == m_entries[j + 1].key);
|
||||||
|
|
||||||
|
return RemoveIndexRange(i, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectDictionary::CheckSize()
|
||||||
|
{
|
||||||
|
int newSize = m_maxSize;
|
||||||
|
if (m_size == m_maxSize)
|
||||||
|
{
|
||||||
|
newSize = 1 - (int)(m_maxSize * -1.25f);
|
||||||
|
}
|
||||||
|
else if (m_maxSize * 0.5f > m_size)
|
||||||
|
{
|
||||||
|
newSize = (int)(m_maxSize * 0.75f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newSize != m_maxSize)
|
||||||
|
{
|
||||||
|
entry_t *newEntries = (entry_t *)Mem_Malloc(sizeof(entry_t) * newSize);
|
||||||
|
if (!newEntries)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Q_memset(&newEntries[m_size], 0, sizeof(entry_t) * (newSize - m_size));
|
||||||
|
|
||||||
|
if (m_entries && m_size)
|
||||||
|
{
|
||||||
|
Q_memcpy(newEntries, m_entries, sizeof(entry_t) * m_size);
|
||||||
|
Mem_Free(m_entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_entries = newEntries;
|
||||||
|
m_maxSize = newSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectDictionary::Init()
|
||||||
|
{
|
||||||
|
m_size = 0;
|
||||||
|
m_maxSize = 0;
|
||||||
|
m_entries = nullptr;
|
||||||
|
|
||||||
|
CheckSize();
|
||||||
|
ClearCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectDictionary::Init(int baseSize)
|
||||||
|
{
|
||||||
|
m_size = 0;
|
||||||
|
m_maxSize = 0;
|
||||||
|
m_entries = (entry_t *)Mem_ZeroMalloc(sizeof(entry_t) * baseSize);
|
||||||
|
|
||||||
|
if (m_entries) {
|
||||||
|
m_maxSize = baseSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectDictionary::Add(void *object)
|
||||||
|
{
|
||||||
|
return Add(object, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ObjectDictionary::CountElements()
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectDictionary::IsEmpty()
|
||||||
|
{
|
||||||
|
return (m_size == 0) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectDictionary::Contains(void *object)
|
||||||
|
{
|
||||||
|
if (FindObjectInCache(object) >= 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_size; i++)
|
||||||
|
{
|
||||||
|
entry_t *e = &m_entries[i];
|
||||||
|
if (e->object == object) {
|
||||||
|
AddToCache(e);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ObjectDictionary::GetFirst()
|
||||||
|
{
|
||||||
|
m_currentEntry = 0;
|
||||||
|
return GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ObjectDictionary::GetLast()
|
||||||
|
{
|
||||||
|
return (m_size > 0) ? m_entries[m_size - 1].object : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectDictionary::ChangeKey(void *object, float newKey)
|
||||||
|
{
|
||||||
|
int pos = FindObjectInCache(object);
|
||||||
|
if (pos < 0)
|
||||||
|
{
|
||||||
|
for (pos = 0; pos < m_size; pos++)
|
||||||
|
{
|
||||||
|
if (m_entries[pos].object == object) {
|
||||||
|
AddToCache(&m_entries[pos]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos == m_size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_t *p, *e;
|
||||||
|
|
||||||
|
p = &m_entries[pos];
|
||||||
|
if (p->key == newKey)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int newpos = FindClosestAsIndex(newKey);
|
||||||
|
e = &m_entries[newpos];
|
||||||
|
if (pos < newpos)
|
||||||
|
{
|
||||||
|
if (e->key > newKey)
|
||||||
|
e--;
|
||||||
|
|
||||||
|
entry_t *e2 = &m_entries[pos + 1];
|
||||||
|
while (p < e)
|
||||||
|
{
|
||||||
|
p->object = e2->object;
|
||||||
|
p->key = e2->key;
|
||||||
|
|
||||||
|
p++;
|
||||||
|
e2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pos > newpos)
|
||||||
|
{
|
||||||
|
if (e->key > newKey)
|
||||||
|
e++;
|
||||||
|
|
||||||
|
entry_t *e2 = &m_entries[pos - 1];
|
||||||
|
while (p > e)
|
||||||
|
{
|
||||||
|
p->object = e2->object;
|
||||||
|
p->key = e2->key;
|
||||||
|
|
||||||
|
p--;
|
||||||
|
e2--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p->object = object;
|
||||||
|
p->key = newKey;
|
||||||
|
ClearCache();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectDictionary::UnsafeChangeKey(void *object, float newKey)
|
||||||
|
{
|
||||||
|
int pos = FindObjectInCache(object);
|
||||||
|
if (pos < 0)
|
||||||
|
{
|
||||||
|
for (pos = 0; pos < m_size; pos++)
|
||||||
|
{
|
||||||
|
if (m_entries[pos].object == object) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos == m_size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_entries[pos].key = newKey;
|
||||||
|
ClearCache();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectDictionary::AddToCache(entry_t *entry)
|
||||||
|
{
|
||||||
|
int i = (m_cacheIndex % MAX_OBJECT_CACHE);
|
||||||
|
|
||||||
|
m_cache[i].object = entry;
|
||||||
|
m_cache[i].key = entry->key;
|
||||||
|
m_cacheIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectDictionary::AddToCache(entry_t *entry, float key)
|
||||||
|
{
|
||||||
|
int i = (m_cacheIndex % MAX_OBJECT_CACHE);
|
||||||
|
|
||||||
|
m_cache[i].object = entry;
|
||||||
|
m_cache[i].key = key;
|
||||||
|
m_cacheIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ObjectDictionary::FindKeyInCache(float key)
|
||||||
|
{
|
||||||
|
for (auto& ch : m_cache)
|
||||||
|
{
|
||||||
|
if (ch.object && ch.key == key) {
|
||||||
|
return (entry_t *)ch.object - m_entries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ObjectDictionary::FindObjectInCache(void *object)
|
||||||
|
{
|
||||||
|
for (auto& ch : m_cache)
|
||||||
|
{
|
||||||
|
if (ch.object && ch.object == object) {
|
||||||
|
return (entry_t *)ch.object - m_entries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ObjectDictionary::FindClosestKey(float key)
|
||||||
|
{
|
||||||
|
m_currentEntry = FindClosestAsIndex(key);
|
||||||
|
return GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ObjectDictionary::GetNext()
|
||||||
|
{
|
||||||
|
if (m_currentEntry < 0 || m_currentEntry >= m_size)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return m_entries[m_currentEntry++].object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ObjectDictionary::FindExactKey(float key)
|
||||||
|
{
|
||||||
|
if ((m_currentEntry = FindClosestAsIndex(key)) < 0)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return (m_entries[m_currentEntry].key == key) ? GetNext() : nullptr;
|
||||||
|
}
|
94
dep/rehlsdk/common/ObjectDictionary.h
Normal file
94
dep/rehlsdk/common/ObjectDictionary.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IObjectContainer.h"
|
||||||
|
|
||||||
|
class ObjectDictionary: public IObjectContainer {
|
||||||
|
public:
|
||||||
|
ObjectDictionary();
|
||||||
|
virtual ~ObjectDictionary();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Init(int baseSize);
|
||||||
|
|
||||||
|
bool Add(void *object);
|
||||||
|
bool Contains(void *object);
|
||||||
|
bool IsEmpty();
|
||||||
|
int CountElements();
|
||||||
|
|
||||||
|
void Clear(bool freeObjectssMemory = false);
|
||||||
|
|
||||||
|
bool Add(void *object, float key);
|
||||||
|
bool ChangeKey(void *object, float newKey);
|
||||||
|
bool UnsafeChangeKey(void *object, float newKey);
|
||||||
|
|
||||||
|
bool Remove(void *object);
|
||||||
|
bool RemoveSingle(void *object);
|
||||||
|
bool RemoveKey(float key);
|
||||||
|
bool RemoveRange(float startKey, float endKey);
|
||||||
|
|
||||||
|
void *FindClosestKey(float key);
|
||||||
|
void *FindExactKey(float key);
|
||||||
|
|
||||||
|
void *GetFirst();
|
||||||
|
void *GetLast();
|
||||||
|
void *GetNext();
|
||||||
|
|
||||||
|
int FindKeyInCache(float key);
|
||||||
|
int FindObjectInCache(void *object);
|
||||||
|
|
||||||
|
void ClearCache();
|
||||||
|
bool CheckSize();
|
||||||
|
|
||||||
|
typedef struct entry_s {
|
||||||
|
void *object;
|
||||||
|
float key;
|
||||||
|
} entry_t;
|
||||||
|
|
||||||
|
void AddToCache(entry_t *entry);
|
||||||
|
void AddToCache(entry_t *entry, float key);
|
||||||
|
|
||||||
|
bool RemoveIndex(int index, bool freeObjectMemory = false);
|
||||||
|
bool RemoveIndexRange(int minIndex, int maxIndex);
|
||||||
|
int FindClosestAsIndex(float key);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int m_currentEntry;
|
||||||
|
float m_findKey;
|
||||||
|
|
||||||
|
enum { MAX_OBJECT_CACHE = 32 };
|
||||||
|
|
||||||
|
entry_t *m_entries;
|
||||||
|
entry_t m_cache[MAX_OBJECT_CACHE];
|
||||||
|
|
||||||
|
int m_cacheIndex;
|
||||||
|
int m_size;
|
||||||
|
int m_maxSize;
|
||||||
|
};
|
259
dep/rehlsdk/common/ObjectList.cpp
Normal file
259
dep/rehlsdk/common/ObjectList.cpp
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
ObjectList::ObjectList()
|
||||||
|
{
|
||||||
|
m_head = m_tail = m_current = nullptr;
|
||||||
|
m_number = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectList::~ObjectList()
|
||||||
|
{
|
||||||
|
Clear(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectList::AddHead(void *newObject)
|
||||||
|
{
|
||||||
|
// create new element
|
||||||
|
element_t *newElement = (element_t *)Mem_ZeroMalloc(sizeof(element_t));
|
||||||
|
|
||||||
|
// out of memory
|
||||||
|
if (!newElement)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// insert element
|
||||||
|
newElement->object = newObject;
|
||||||
|
|
||||||
|
if (m_head)
|
||||||
|
{
|
||||||
|
newElement->next = m_head;
|
||||||
|
m_head->prev = newElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_head = newElement;
|
||||||
|
|
||||||
|
// if list was empty set new m_tail
|
||||||
|
if (!m_tail)
|
||||||
|
m_tail = m_head;
|
||||||
|
|
||||||
|
m_number++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ObjectList::RemoveHead()
|
||||||
|
{
|
||||||
|
void *retObj;
|
||||||
|
|
||||||
|
// check m_head is present
|
||||||
|
if (m_head)
|
||||||
|
{
|
||||||
|
retObj = m_head->object;
|
||||||
|
element_t *newHead = m_head->next;
|
||||||
|
if (newHead)
|
||||||
|
newHead->prev = nullptr;
|
||||||
|
|
||||||
|
// if only one element is in list also update m_tail
|
||||||
|
// if we remove this prev element
|
||||||
|
if (m_tail == m_head)
|
||||||
|
m_tail = nullptr;
|
||||||
|
|
||||||
|
Mem_Free(m_head);
|
||||||
|
m_head = newHead;
|
||||||
|
|
||||||
|
m_number--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retObj = nullptr;
|
||||||
|
|
||||||
|
return retObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectList::AddTail(void *newObject)
|
||||||
|
{
|
||||||
|
// create new element
|
||||||
|
element_t *newElement = (element_t *)Mem_ZeroMalloc(sizeof(element_t));
|
||||||
|
|
||||||
|
// out of memory
|
||||||
|
if (!newElement)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// insert element
|
||||||
|
newElement->object = newObject;
|
||||||
|
|
||||||
|
if (m_tail)
|
||||||
|
{
|
||||||
|
newElement->prev = m_tail;
|
||||||
|
m_tail->next = newElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_tail = newElement;
|
||||||
|
|
||||||
|
// if list was empty set new m_tail
|
||||||
|
if (!m_head)
|
||||||
|
m_head = m_tail;
|
||||||
|
|
||||||
|
m_number++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ObjectList::RemoveTail()
|
||||||
|
{
|
||||||
|
void *retObj;
|
||||||
|
|
||||||
|
// check m_tail is present
|
||||||
|
if (m_tail)
|
||||||
|
{
|
||||||
|
retObj = m_tail->object;
|
||||||
|
element_t *newTail = m_tail->prev;
|
||||||
|
if (newTail)
|
||||||
|
newTail->next = nullptr;
|
||||||
|
|
||||||
|
// if only one element is in list also update m_tail
|
||||||
|
// if we remove this prev element
|
||||||
|
if (m_head == m_tail)
|
||||||
|
m_head = nullptr;
|
||||||
|
|
||||||
|
Mem_Free(m_tail);
|
||||||
|
m_tail = newTail;
|
||||||
|
|
||||||
|
m_number--;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retObj = nullptr;
|
||||||
|
|
||||||
|
return retObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectList::IsEmpty()
|
||||||
|
{
|
||||||
|
return (m_head == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ObjectList::CountElements()
|
||||||
|
{
|
||||||
|
return m_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectList::Contains(void *object)
|
||||||
|
{
|
||||||
|
element_t *e = m_head;
|
||||||
|
|
||||||
|
while (e && e->object != object) { e = e->next; }
|
||||||
|
|
||||||
|
if (e)
|
||||||
|
{
|
||||||
|
m_current = e;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectList::Clear(bool freeElementsMemory)
|
||||||
|
{
|
||||||
|
element_t *ne;
|
||||||
|
element_t *e = m_head;
|
||||||
|
|
||||||
|
while (e)
|
||||||
|
{
|
||||||
|
ne = e->next;
|
||||||
|
|
||||||
|
if (freeElementsMemory && e->object)
|
||||||
|
Mem_Free(e->object);
|
||||||
|
|
||||||
|
Mem_Free(e);
|
||||||
|
e = ne;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_head = m_tail = m_current = nullptr;
|
||||||
|
m_number = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectList::Remove(void *object)
|
||||||
|
{
|
||||||
|
element_t *e = m_head;
|
||||||
|
|
||||||
|
while (e && e->object != object) { e = e->next; }
|
||||||
|
|
||||||
|
if (e)
|
||||||
|
{
|
||||||
|
if (e->prev) e->prev->next = e->next;
|
||||||
|
if (e->next) e->next->prev = e->prev;
|
||||||
|
|
||||||
|
if (m_head == e) m_head = e->next;
|
||||||
|
if (m_tail == e) m_tail = e->prev;
|
||||||
|
if (m_current == e) m_current= e->next;
|
||||||
|
|
||||||
|
Mem_Free(e);
|
||||||
|
m_number--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (e != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectList::Init()
|
||||||
|
{
|
||||||
|
m_head = m_tail = m_current = nullptr;
|
||||||
|
m_number = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ObjectList::GetFirst()
|
||||||
|
{
|
||||||
|
if (m_head)
|
||||||
|
{
|
||||||
|
m_current = m_head->next;
|
||||||
|
return m_head->object;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_current = nullptr;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ObjectList::GetNext()
|
||||||
|
{
|
||||||
|
void *retObj = nullptr;
|
||||||
|
if (m_current)
|
||||||
|
{
|
||||||
|
retObj = m_current->object;
|
||||||
|
m_current = m_current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectList::Add(void *newObject)
|
||||||
|
{
|
||||||
|
return AddTail(newObject);
|
||||||
|
}
|
65
dep/rehlsdk/common/ObjectList.h
Normal file
65
dep/rehlsdk/common/ObjectList.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IObjectContainer.h"
|
||||||
|
|
||||||
|
class ObjectList: public IObjectContainer {
|
||||||
|
public:
|
||||||
|
EXT_FUNC void Init();
|
||||||
|
EXT_FUNC bool Add(void *newObject);
|
||||||
|
EXT_FUNC void *GetFirst();
|
||||||
|
EXT_FUNC void *GetNext();
|
||||||
|
|
||||||
|
ObjectList();
|
||||||
|
virtual ~ObjectList();
|
||||||
|
|
||||||
|
EXT_FUNC void Clear(bool freeElementsMemory = false);
|
||||||
|
EXT_FUNC int CountElements();
|
||||||
|
void *RemoveTail();
|
||||||
|
void *RemoveHead();
|
||||||
|
|
||||||
|
bool AddTail(void *newObject);
|
||||||
|
bool AddHead(void *newObject);
|
||||||
|
EXT_FUNC bool Remove(void *object);
|
||||||
|
EXT_FUNC bool Contains(void *object);
|
||||||
|
EXT_FUNC bool IsEmpty();
|
||||||
|
|
||||||
|
typedef struct element_s {
|
||||||
|
struct element_s *prev; // pointer to the last element or NULL
|
||||||
|
struct element_s *next; // pointer to the next elemnet or NULL
|
||||||
|
void *object; // the element's object
|
||||||
|
} element_t;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
element_t *m_head; // first element in list
|
||||||
|
element_t *m_tail; // last element in list
|
||||||
|
element_t *m_current; // current element in list
|
||||||
|
int m_number;
|
||||||
|
};
|
211
dep/rehlsdk/common/SteamAppStartUp.cpp
Normal file
211
dep/rehlsdk/common/SteamAppStartUp.cpp
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "SteamAppStartup.h"
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <assert.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <process.h>
|
||||||
|
#include <direct.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#define STEAM_PARM "-steam"
|
||||||
|
|
||||||
|
bool FileExists(const char *fileName)
|
||||||
|
{
|
||||||
|
struct _stat statbuf;
|
||||||
|
return (_stat(fileName, &statbuf) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles launching the game indirectly via steam
|
||||||
|
void LaunchSelfViaSteam(const char *params)
|
||||||
|
{
|
||||||
|
// calculate the details of our launch
|
||||||
|
char appPath[MAX_PATH];
|
||||||
|
::GetModuleFileName((HINSTANCE)GetModuleHandle(NULL), appPath, sizeof(appPath));
|
||||||
|
|
||||||
|
// strip out the exe name
|
||||||
|
char *slash = Q_strrchr(appPath, '\\');
|
||||||
|
if (slash)
|
||||||
|
{
|
||||||
|
*slash = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// save out our details to the registry
|
||||||
|
HKEY hKey;
|
||||||
|
if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, "Software\\Valve\\Steam", &hKey))
|
||||||
|
{
|
||||||
|
DWORD dwType = REG_SZ;
|
||||||
|
DWORD dwSize = static_cast<DWORD>(Q_strlen(appPath) + 1);
|
||||||
|
RegSetValueEx(hKey, "TempAppPath", NULL, dwType, (LPBYTE)appPath, dwSize);
|
||||||
|
dwSize = static_cast<DWORD>(Q_strlen(params) + 1);
|
||||||
|
RegSetValueEx(hKey, "TempAppCmdLine", NULL, dwType, (LPBYTE)params, dwSize);
|
||||||
|
// clear out the appID (since we don't know it yet)
|
||||||
|
dwType = REG_DWORD;
|
||||||
|
int appID = -1;
|
||||||
|
RegSetValueEx(hKey, "TempAppID", NULL, dwType, (LPBYTE)&appID, sizeof(appID));
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
// search for an active steam instance
|
||||||
|
HWND hwnd = ::FindWindow("Valve_SteamIPC_Class", "Hidden Window");
|
||||||
|
if (hwnd)
|
||||||
|
{
|
||||||
|
::PostMessage(hwnd, WM_USER + 3, 0, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// couldn't find steam, find and launch it
|
||||||
|
|
||||||
|
// first, search backwards through our current set of directories
|
||||||
|
char steamExe[MAX_PATH] = "";
|
||||||
|
char dir[MAX_PATH];
|
||||||
|
|
||||||
|
if (::GetCurrentDirectoryA(sizeof(dir), dir))
|
||||||
|
{
|
||||||
|
char *slash = Q_strrchr(dir, '\\');
|
||||||
|
while (slash)
|
||||||
|
{
|
||||||
|
// see if steam_dev.exe is in the directory first
|
||||||
|
slash[1] = '\0';
|
||||||
|
Q_strcat(slash, "steam_dev.exe");
|
||||||
|
FILE *f = fopen(dir, "rb");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
// found it
|
||||||
|
fclose(f);
|
||||||
|
Q_strcpy(steamExe, dir);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// see if steam.exe is in the directory
|
||||||
|
slash[1] = '\0';
|
||||||
|
Q_strcat(slash, "steam.exe");
|
||||||
|
f = fopen(dir, "rb");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
// found it
|
||||||
|
fclose(f);
|
||||||
|
Q_strcpy(steamExe, dir);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// kill the string at the slash
|
||||||
|
slash[0] = '\0';
|
||||||
|
|
||||||
|
// move to the previous slash
|
||||||
|
slash = Q_strrchr(dir, '\\');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!steamExe[0])
|
||||||
|
{
|
||||||
|
// still not found, use the one in the registry
|
||||||
|
HKEY hKey;
|
||||||
|
if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, "Software\\Valve\\Steam", &hKey))
|
||||||
|
{
|
||||||
|
DWORD dwType;
|
||||||
|
DWORD dwSize = sizeof(steamExe);
|
||||||
|
RegQueryValueEx(hKey, "SteamExe", NULL, &dwType, (LPBYTE)steamExe, &dwSize);
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!steamExe[0])
|
||||||
|
{
|
||||||
|
// still no path, error
|
||||||
|
::MessageBox(NULL, "Error running game: could not find steam.exe to launch", "Fatal Error", MB_OK | MB_ICONERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix any slashes
|
||||||
|
for (char *slash = steamExe; *slash; slash++)
|
||||||
|
{
|
||||||
|
if (*slash == '/')
|
||||||
|
{
|
||||||
|
*slash = '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// change to the steam directory
|
||||||
|
Q_strcpy(dir, steamExe);
|
||||||
|
char *delimiter = Q_strrchr(dir, '\\');
|
||||||
|
if (delimiter)
|
||||||
|
{
|
||||||
|
*delimiter = '\0';
|
||||||
|
_chdir(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
// exec steam.exe, in silent mode, with the launch app param
|
||||||
|
char *args[4] = { steamExe, "-silent", "-applaunch", '\0' };
|
||||||
|
_spawnv(_P_NOWAIT, steamExe, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Launches steam if necessary
|
||||||
|
bool ShouldLaunchAppViaSteam(const char *lpCmdLine, const char *steamFilesystemDllName, const char *stdioFilesystemDllName)
|
||||||
|
{
|
||||||
|
// see if steam is on the command line
|
||||||
|
const char *steamStr = Q_strstr(lpCmdLine, STEAM_PARM);
|
||||||
|
|
||||||
|
// check the character following it is a whitespace or null
|
||||||
|
if (steamStr)
|
||||||
|
{
|
||||||
|
const char *postChar = steamStr + Q_strlen(STEAM_PARM);
|
||||||
|
if (*postChar == 0 || isspace(*postChar))
|
||||||
|
{
|
||||||
|
// we're running under steam already, let the app continue
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we're not running under steam, see which filesystems are available
|
||||||
|
if (FileExists(stdioFilesystemDllName))
|
||||||
|
{
|
||||||
|
// we're being run with a stdio filesystem, so we can continue without steam
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure we have a steam filesystem available
|
||||||
|
if (!FileExists(steamFilesystemDllName))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we have the steam filesystem, and no stdio filesystem, so we must need to be run under steam
|
||||||
|
// launch steam
|
||||||
|
LaunchSelfViaSteam(lpCmdLine);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _WIN32
|
37
dep/rehlsdk/common/SteamAppStartUp.h
Normal file
37
dep/rehlsdk/common/SteamAppStartUp.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Call this first thing at startup
|
||||||
|
// Works out if the app is a steam app that is being ran outside of steam,
|
||||||
|
// and if so, launches steam and tells it to run us as a steam app
|
||||||
|
//
|
||||||
|
// if it returns true, then exit
|
||||||
|
// if it ruturns false, then continue with normal startup
|
||||||
|
bool ShouldLaunchAppViaSteam(const char *cmdLine, const char *steamFilesystemDllName, const char *stdioFilesystemDllName);
|
@ -36,7 +36,7 @@ extern "C"
|
|||||||
#if defined ( _WIN32 )
|
#if defined ( _WIN32 )
|
||||||
|
|
||||||
#ifdef STEAM_EXPORTS
|
#ifdef STEAM_EXPORTS
|
||||||
#define STEAM_API __declspec(dllexport)
|
#define STEAM_API __declspec(dllexport) EXT_FUNC
|
||||||
#else
|
#else
|
||||||
#define STEAM_API __declspec(dllimport)
|
#define STEAM_API __declspec(dllimport)
|
||||||
#endif
|
#endif
|
||||||
@ -45,7 +45,11 @@ extern "C"
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#ifdef STEAM_EXPORTS
|
||||||
|
#define STEAM_API EXT_FUNC
|
||||||
|
#else
|
||||||
#define STEAM_API /* */
|
#define STEAM_API /* */
|
||||||
|
#endif
|
||||||
#define STEAM_CALL /* */
|
#define STEAM_CALL /* */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
324
dep/rehlsdk/common/TextConsoleUnix.cpp
Normal file
324
dep/rehlsdk/common/TextConsoleUnix.cpp
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
|
||||||
|
#include "TextConsoleUnix.h"
|
||||||
|
#include "icommandline.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
CTextConsoleUnix console;
|
||||||
|
|
||||||
|
CTextConsoleUnix::~CTextConsoleUnix()
|
||||||
|
{
|
||||||
|
CTextConsoleUnix::ShutDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTextConsoleUnix::Init(IBaseSystem *system)
|
||||||
|
{
|
||||||
|
static struct termios termNew;
|
||||||
|
sigset_t block_ttou;
|
||||||
|
|
||||||
|
sigemptyset(&block_ttou);
|
||||||
|
sigaddset(&block_ttou, SIGTTOU);
|
||||||
|
sigprocmask(SIG_BLOCK, &block_ttou, NULL);
|
||||||
|
|
||||||
|
tty = stdout;
|
||||||
|
|
||||||
|
// this code is for echo-ing key presses to the connected tty
|
||||||
|
// (which is != STDOUT)
|
||||||
|
if (isatty(STDIN_FILENO))
|
||||||
|
{
|
||||||
|
tty = fopen(ctermid(NULL), "w+");
|
||||||
|
if (!tty)
|
||||||
|
{
|
||||||
|
printf("Unable to open tty(%s) for output\n", ctermid(NULL));
|
||||||
|
tty = stdout;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// turn buffering off
|
||||||
|
setbuf(tty, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tty = fopen("/dev/null", "w+");
|
||||||
|
if (!tty)
|
||||||
|
{
|
||||||
|
tty = stdout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tcgetattr(STDIN_FILENO, &termStored);
|
||||||
|
|
||||||
|
Q_memcpy(&termNew, &termStored, sizeof(struct termios));
|
||||||
|
|
||||||
|
// Disable canonical mode, and set buffer size to 1 byte
|
||||||
|
termNew.c_lflag &= (~ICANON);
|
||||||
|
termNew.c_cc[ VMIN ] = 1;
|
||||||
|
termNew.c_cc[ VTIME ] = 0;
|
||||||
|
|
||||||
|
// disable echo
|
||||||
|
termNew.c_lflag &= (~ECHO);
|
||||||
|
|
||||||
|
tcsetattr(STDIN_FILENO, TCSANOW, &termNew);
|
||||||
|
sigprocmask(SIG_UNBLOCK, &block_ttou, NULL);
|
||||||
|
|
||||||
|
return CTextConsole::Init(system);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsoleUnix::ShutDown()
|
||||||
|
{
|
||||||
|
sigset_t block_ttou;
|
||||||
|
|
||||||
|
sigemptyset(&block_ttou);
|
||||||
|
sigaddset(&block_ttou, SIGTTOU);
|
||||||
|
sigprocmask(SIG_BLOCK, &block_ttou, NULL);
|
||||||
|
tcsetattr(STDIN_FILENO, TCSANOW, &termStored);
|
||||||
|
sigprocmask(SIG_UNBLOCK, &block_ttou, NULL);
|
||||||
|
|
||||||
|
CTextConsole::ShutDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// return 0 if the kb isn't hit
|
||||||
|
int CTextConsoleUnix::kbhit()
|
||||||
|
{
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
// Watch stdin (fd 0) to see when it has input.
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(STDIN_FILENO, &rfds);
|
||||||
|
|
||||||
|
// Return immediately.
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
// Must be in raw or cbreak mode for this to work correctly.
|
||||||
|
return select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv) != -1 && FD_ISSET(STDIN_FILENO, &rfds);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *CTextConsoleUnix::GetLine()
|
||||||
|
{
|
||||||
|
// early return for 99.999% case :)
|
||||||
|
if (!kbhit())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
escape_sequence_t es;
|
||||||
|
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
sigset_t block_ttou;
|
||||||
|
|
||||||
|
sigemptyset(&block_ttou);
|
||||||
|
sigaddset(&block_ttou, SIGTTOU);
|
||||||
|
sigaddset(&block_ttou, SIGTTIN);
|
||||||
|
sigprocmask(SIG_BLOCK, &block_ttou, NULL);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!kbhit())
|
||||||
|
break;
|
||||||
|
|
||||||
|
int nLen;
|
||||||
|
char ch = 0;
|
||||||
|
int numRead = read(STDIN_FILENO, &ch, 1);
|
||||||
|
if (!numRead)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case '\n': // Enter
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
|
||||||
|
nLen = ReceiveNewline();
|
||||||
|
if (nLen)
|
||||||
|
{
|
||||||
|
sigprocmask(SIG_UNBLOCK, &block_ttou, NULL);
|
||||||
|
return m_szConsoleText;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 127: // Backspace
|
||||||
|
case '\b': // Backspace
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
ReceiveBackspace();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\t': // TAB
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
ReceiveTab();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 27: // Escape character
|
||||||
|
es = ESCAPE_RECEIVED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '[': // 2nd part of escape sequence
|
||||||
|
case 'O':
|
||||||
|
case 'o':
|
||||||
|
switch (es)
|
||||||
|
{
|
||||||
|
case ESCAPE_CLEAR:
|
||||||
|
case ESCAPE_BRACKET_RECEIVED:
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
ReceiveStandardChar(ch);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ESCAPE_RECEIVED:
|
||||||
|
es = ESCAPE_BRACKET_RECEIVED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
if (es == ESCAPE_BRACKET_RECEIVED)
|
||||||
|
{
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
ReceiveUpArrow();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
ReceiveStandardChar(ch);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
if (es == ESCAPE_BRACKET_RECEIVED)
|
||||||
|
{
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
ReceiveDownArrow();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
ReceiveStandardChar(ch);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
if (es == ESCAPE_BRACKET_RECEIVED)
|
||||||
|
{
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
ReceiveRightArrow();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
ReceiveStandardChar(ch);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
if (es == ESCAPE_BRACKET_RECEIVED)
|
||||||
|
{
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
ReceiveLeftArrow();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
ReceiveStandardChar(ch);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Just eat this char if it's an unsupported escape
|
||||||
|
if (es != ESCAPE_BRACKET_RECEIVED)
|
||||||
|
{
|
||||||
|
// dont' accept nonprintable chars
|
||||||
|
if ((ch >= ' ') && (ch <= '~'))
|
||||||
|
{
|
||||||
|
es = ESCAPE_CLEAR;
|
||||||
|
ReceiveStandardChar(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
sigprocmask(SIG_UNBLOCK, &block_ttou, NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsoleUnix::PrintRaw(char *pszMsg, int nChars)
|
||||||
|
{
|
||||||
|
if (nChars == 0)
|
||||||
|
{
|
||||||
|
printf("%s", pszMsg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int nCount = 0; nCount < nChars; nCount++)
|
||||||
|
{
|
||||||
|
putchar(pszMsg[ nCount ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsoleUnix::Echo(char *pszMsg, int nChars)
|
||||||
|
{
|
||||||
|
if (nChars == 0)
|
||||||
|
{
|
||||||
|
fputs(pszMsg, tty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int nCount = 0; nCount < nChars; nCount++)
|
||||||
|
{
|
||||||
|
fputc(pszMsg[ nCount ], tty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int CTextConsoleUnix::GetWidth()
|
||||||
|
{
|
||||||
|
struct winsize ws;
|
||||||
|
int nWidth = 0;
|
||||||
|
|
||||||
|
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0)
|
||||||
|
{
|
||||||
|
nWidth = (int)ws.ws_col;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nWidth <= 1)
|
||||||
|
{
|
||||||
|
nWidth = 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !defined(_WIN32)
|
59
dep/rehlsdk/common/TextConsoleUnix.h
Normal file
59
dep/rehlsdk/common/TextConsoleUnix.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <termios.h>
|
||||||
|
#include "textconsole.h"
|
||||||
|
|
||||||
|
enum escape_sequence_t
|
||||||
|
{
|
||||||
|
ESCAPE_CLEAR,
|
||||||
|
ESCAPE_RECEIVED,
|
||||||
|
ESCAPE_BRACKET_RECEIVED
|
||||||
|
};
|
||||||
|
|
||||||
|
class CTextConsoleUnix: public CTextConsole {
|
||||||
|
public:
|
||||||
|
virtual ~CTextConsoleUnix();
|
||||||
|
|
||||||
|
bool Init(IBaseSystem *system = nullptr);
|
||||||
|
void ShutDown();
|
||||||
|
void PrintRaw(char *pszMsg, int nChars = 0);
|
||||||
|
void Echo(char *pszMsg, int nChars = 0);
|
||||||
|
char *GetLine();
|
||||||
|
int GetWidth();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int kbhit();
|
||||||
|
|
||||||
|
struct termios termStored;
|
||||||
|
FILE *tty;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern CTextConsoleUnix console;
|
282
dep/rehlsdk/common/TextConsoleWin32.cpp
Normal file
282
dep/rehlsdk/common/TextConsoleWin32.cpp
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
|
||||||
|
CTextConsoleWin32 console;
|
||||||
|
#pragma comment(lib, "user32.lib")
|
||||||
|
|
||||||
|
BOOL WINAPI ConsoleHandlerRoutine(DWORD CtrlType)
|
||||||
|
{
|
||||||
|
// TODO ?
|
||||||
|
/*if (CtrlType != CTRL_C_EVENT && CtrlType != CTRL_BREAK_EVENT)
|
||||||
|
{
|
||||||
|
// don't quit on break or ctrl+c
|
||||||
|
m_System->Stop();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConsoleHwnd() helper function from MSDN Knowledge Base Article Q124103
|
||||||
|
// needed, because HWND GetConsoleWindow(VOID) is not avaliable under Win95/98/ME
|
||||||
|
HWND GetConsoleHwnd()
|
||||||
|
{
|
||||||
|
HWND hwndFound; // This is what is returned to the caller.
|
||||||
|
char pszNewWindowTitle[1024]; // Contains fabricated WindowTitle
|
||||||
|
char pszOldWindowTitle[1024]; // Contains original WindowTitle
|
||||||
|
|
||||||
|
// Fetch current window title.
|
||||||
|
GetConsoleTitle(pszOldWindowTitle, sizeof(pszOldWindowTitle));
|
||||||
|
|
||||||
|
// Format a "unique" NewWindowTitle.
|
||||||
|
wsprintf(pszNewWindowTitle, "%d/%d", GetTickCount(), GetCurrentProcessId());
|
||||||
|
|
||||||
|
// Change current window title.
|
||||||
|
SetConsoleTitle(pszNewWindowTitle);
|
||||||
|
|
||||||
|
// Ensure window title has been updated.
|
||||||
|
Sleep(40);
|
||||||
|
|
||||||
|
// Look for NewWindowTitle.
|
||||||
|
hwndFound = FindWindow(nullptr, pszNewWindowTitle);
|
||||||
|
|
||||||
|
// Restore original window title.
|
||||||
|
SetConsoleTitle(pszOldWindowTitle);
|
||||||
|
|
||||||
|
return hwndFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
CTextConsoleWin32::~CTextConsoleWin32()
|
||||||
|
{
|
||||||
|
CTextConsoleWin32::ShutDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTextConsoleWin32::Init(IBaseSystem *system)
|
||||||
|
{
|
||||||
|
if (!AllocConsole())
|
||||||
|
m_System = system;
|
||||||
|
|
||||||
|
SetTitle(m_System ? m_System->GetName() : "Console");
|
||||||
|
|
||||||
|
hinput = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
houtput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
if (!SetConsoleCtrlHandler(&ConsoleHandlerRoutine, TRUE)) {
|
||||||
|
Print("WARNING! TextConsole::Init: Could not attach console hook.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Attrib = FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
|
||||||
|
SetWindowPos(GetConsoleHwnd(), HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION | SWP_SHOWWINDOW);
|
||||||
|
|
||||||
|
return CTextConsole::Init(system);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsoleWin32::ShutDown()
|
||||||
|
{
|
||||||
|
FreeConsole();
|
||||||
|
CTextConsole::ShutDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsoleWin32::SetVisible(bool visible)
|
||||||
|
{
|
||||||
|
ShowWindow(GetConsoleHwnd(), visible ? SW_SHOW : SW_HIDE);
|
||||||
|
m_ConsoleVisible = visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *CTextConsoleWin32::GetLine()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
INPUT_RECORD recs[1024];
|
||||||
|
unsigned long numread;
|
||||||
|
unsigned long numevents;
|
||||||
|
|
||||||
|
if (!GetNumberOfConsoleInputEvents(hinput, &numevents))
|
||||||
|
{
|
||||||
|
if (m_System) {
|
||||||
|
m_System->Errorf("CTextConsoleWin32::GetLine: !GetNumberOfConsoleInputEvents\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numevents <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!ReadConsoleInput(hinput, recs, ARRAYSIZE(recs), &numread))
|
||||||
|
{
|
||||||
|
if (m_System) {
|
||||||
|
m_System->Errorf("CTextConsoleWin32::GetLine: !ReadConsoleInput\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numread == 0)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)numread; i++)
|
||||||
|
{
|
||||||
|
INPUT_RECORD *pRec = &recs[i];
|
||||||
|
if (pRec->EventType != KEY_EVENT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (pRec->Event.KeyEvent.bKeyDown)
|
||||||
|
{
|
||||||
|
// check for cursor keys
|
||||||
|
if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_UP)
|
||||||
|
{
|
||||||
|
ReceiveUpArrow();
|
||||||
|
}
|
||||||
|
else if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)
|
||||||
|
{
|
||||||
|
ReceiveDownArrow();
|
||||||
|
}
|
||||||
|
else if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_LEFT)
|
||||||
|
{
|
||||||
|
ReceiveLeftArrow();
|
||||||
|
}
|
||||||
|
else if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_RIGHT)
|
||||||
|
{
|
||||||
|
ReceiveRightArrow();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int nLen;
|
||||||
|
char ch = pRec->Event.KeyEvent.uChar.AsciiChar;
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case '\r': // Enter
|
||||||
|
nLen = ReceiveNewline();
|
||||||
|
if (nLen)
|
||||||
|
{
|
||||||
|
return m_szConsoleText;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\b': // Backspace
|
||||||
|
ReceiveBackspace();
|
||||||
|
break;
|
||||||
|
case '\t': // TAB
|
||||||
|
ReceiveTab();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// dont' accept nonprintable chars
|
||||||
|
if ((ch >= ' ') && (ch <= '~'))
|
||||||
|
{
|
||||||
|
ReceiveStandardChar(ch);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsoleWin32::PrintRaw(char *pszMsg, int nChars)
|
||||||
|
{
|
||||||
|
#ifdef LAUNCHER_FIXES
|
||||||
|
char outputStr[2048];
|
||||||
|
WCHAR unicodeStr[1024];
|
||||||
|
|
||||||
|
DWORD nSize = MultiByteToWideChar(CP_UTF8, 0, pszMsg, -1, NULL, 0);
|
||||||
|
if (nSize > sizeof(unicodeStr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, pszMsg, -1, unicodeStr, nSize);
|
||||||
|
DWORD nLength = WideCharToMultiByte(CP_OEMCP, 0, unicodeStr, -1, 0, 0, NULL, NULL);
|
||||||
|
if (nLength > sizeof(outputStr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
WideCharToMultiByte(CP_OEMCP, 0, unicodeStr, -1, outputStr, nLength, NULL, NULL);
|
||||||
|
WriteFile(houtput, outputStr, nChars ? nChars : Q_strlen(outputStr), NULL, NULL);
|
||||||
|
#else
|
||||||
|
WriteFile(houtput, pszMsg, nChars ? nChars : Q_strlen(pszMsg), NULL, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsoleWin32::Echo(char *pszMsg, int nChars)
|
||||||
|
{
|
||||||
|
PrintRaw(pszMsg, nChars);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CTextConsoleWin32::GetWidth()
|
||||||
|
{
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||||
|
int nWidth = 0;
|
||||||
|
|
||||||
|
if (GetConsoleScreenBufferInfo(houtput, &csbi)) {
|
||||||
|
nWidth = csbi.dwSize.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nWidth <= 1)
|
||||||
|
nWidth = 80;
|
||||||
|
|
||||||
|
return nWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsoleWin32::SetStatusLine(char *pszStatus)
|
||||||
|
{
|
||||||
|
Q_strncpy(statusline, pszStatus, sizeof(statusline) - 1);
|
||||||
|
statusline[sizeof(statusline) - 2] = '\0';
|
||||||
|
UpdateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsoleWin32::UpdateStatus()
|
||||||
|
{
|
||||||
|
COORD coord;
|
||||||
|
DWORD dwWritten = 0;
|
||||||
|
WORD wAttrib[ 80 ];
|
||||||
|
|
||||||
|
for (int i = 0; i < 80; i++)
|
||||||
|
{
|
||||||
|
wAttrib[i] = Attrib; // FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
coord.X = coord.Y = 0;
|
||||||
|
|
||||||
|
WriteConsoleOutputAttribute(houtput, wAttrib, 80, coord, &dwWritten);
|
||||||
|
WriteConsoleOutputCharacter(houtput, statusline, 80, coord, &dwWritten);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsoleWin32::SetTitle(char *pszTitle)
|
||||||
|
{
|
||||||
|
SetConsoleTitle(pszTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsoleWin32::SetColor(WORD attrib)
|
||||||
|
{
|
||||||
|
Attrib = attrib;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // defined(_WIN32)
|
62
dep/rehlsdk/common/TextConsoleWin32.h
Normal file
62
dep/rehlsdk/common/TextConsoleWin32.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||||
|
#include <windows.h>
|
||||||
|
#include "TextConsole.h"
|
||||||
|
|
||||||
|
class CTextConsoleWin32: public CTextConsole {
|
||||||
|
public:
|
||||||
|
virtual ~CTextConsoleWin32();
|
||||||
|
|
||||||
|
bool Init(IBaseSystem *system = nullptr);
|
||||||
|
void ShutDown();
|
||||||
|
|
||||||
|
void SetTitle(char *pszTitle);
|
||||||
|
void SetStatusLine(char *pszStatus);
|
||||||
|
void UpdateStatus();
|
||||||
|
|
||||||
|
void PrintRaw(char * pszMsz, int nChars = 0);
|
||||||
|
void Echo(char * pszMsz, int nChars = 0);
|
||||||
|
char *GetLine();
|
||||||
|
int GetWidth();
|
||||||
|
|
||||||
|
void SetVisible(bool visible);
|
||||||
|
void SetColor(WORD);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE hinput; // standard input handle
|
||||||
|
HANDLE houtput; // standard output handle
|
||||||
|
WORD Attrib; // attrib colours for status bar
|
||||||
|
|
||||||
|
char statusline[81]; // first line in console is status line
|
||||||
|
};
|
||||||
|
|
||||||
|
extern CTextConsoleWin32 console;
|
132
dep/rehlsdk/common/TokenLine.cpp
Normal file
132
dep/rehlsdk/common/TokenLine.cpp
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
TokenLine::TokenLine()
|
||||||
|
{
|
||||||
|
Q_memset(m_token, 0, sizeof(m_token));
|
||||||
|
Q_memset(m_fullLine, 0, sizeof(m_fullLine));
|
||||||
|
Q_memset(m_tokenBuffer, 0, sizeof(m_tokenBuffer));
|
||||||
|
|
||||||
|
m_tokenNumber = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenLine::TokenLine(char *string)
|
||||||
|
{
|
||||||
|
SetLine(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenLine::~TokenLine()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TokenLine::SetLine(const char *newLine)
|
||||||
|
{
|
||||||
|
m_tokenNumber = 0;
|
||||||
|
|
||||||
|
if (!newLine || (Q_strlen(newLine) >= (MAX_LINE_CHARS - 1)))
|
||||||
|
{
|
||||||
|
Q_memset(m_fullLine, 0, sizeof(m_fullLine));
|
||||||
|
Q_memset(m_tokenBuffer, 0, sizeof(m_tokenBuffer));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_strlcpy(m_fullLine, newLine);
|
||||||
|
Q_strlcpy(m_tokenBuffer, newLine);
|
||||||
|
|
||||||
|
// parse tokens
|
||||||
|
char *charPointer = m_tokenBuffer;
|
||||||
|
while (*charPointer && (m_tokenNumber < MAX_LINE_TOKENS))
|
||||||
|
{
|
||||||
|
// skip nonprintable chars
|
||||||
|
while (*charPointer && ((*charPointer <= ' ') || (*charPointer > '~')))
|
||||||
|
charPointer++;
|
||||||
|
|
||||||
|
if (*charPointer)
|
||||||
|
{
|
||||||
|
m_token[m_tokenNumber] = charPointer;
|
||||||
|
|
||||||
|
// special treatment for quotes
|
||||||
|
if (*charPointer == '\"')
|
||||||
|
{
|
||||||
|
charPointer++;
|
||||||
|
m_token[m_tokenNumber] = charPointer;
|
||||||
|
while (*charPointer && (*charPointer != '\"'))
|
||||||
|
charPointer++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_token[m_tokenNumber] = charPointer;
|
||||||
|
while (*charPointer && ((*charPointer > 32) && (*charPointer <= 126)))
|
||||||
|
charPointer++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_tokenNumber++;
|
||||||
|
|
||||||
|
if (*charPointer)
|
||||||
|
{
|
||||||
|
*charPointer = '\0';
|
||||||
|
charPointer++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (m_tokenNumber != MAX_LINE_TOKENS);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *TokenLine::GetLine()
|
||||||
|
{
|
||||||
|
return m_fullLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *TokenLine::GetToken(int i)
|
||||||
|
{
|
||||||
|
if (i >= m_tokenNumber)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return m_token[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the given parm is not present return NULL
|
||||||
|
// otherwise return the address of the following token, or an empty string
|
||||||
|
char *TokenLine::CheckToken(char *parm)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_tokenNumber; i++)
|
||||||
|
{
|
||||||
|
if (!m_token[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!Q_strcmp(parm, m_token[i]))
|
||||||
|
{
|
||||||
|
char *ret = m_token[i + 1];
|
||||||
|
|
||||||
|
// if this token doesn't exist, since index i was the last
|
||||||
|
// return an empty string
|
||||||
|
if (m_tokenNumber == (i + 1))
|
||||||
|
ret = "";
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TokenLine::CountToken()
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
for (int i = 0; i < m_tokenNumber; i++)
|
||||||
|
{
|
||||||
|
if (m_token[i])
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *TokenLine::GetRestOfLine(int i)
|
||||||
|
{
|
||||||
|
if (i >= m_tokenNumber)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return m_fullLine + (m_token[i] - m_tokenBuffer);
|
||||||
|
}
|
51
dep/rehlsdk/common/TokenLine.h
Normal file
51
dep/rehlsdk/common/TokenLine.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class TokenLine {
|
||||||
|
public:
|
||||||
|
TokenLine();
|
||||||
|
TokenLine(char *string);
|
||||||
|
virtual ~TokenLine();
|
||||||
|
|
||||||
|
char *GetRestOfLine(int i); // returns all chars after token i
|
||||||
|
int CountToken(); // returns number of token
|
||||||
|
char *CheckToken(char *parm); // returns token after token parm or ""
|
||||||
|
char *GetToken(int i); // returns token i
|
||||||
|
char *GetLine(); // returns full line
|
||||||
|
bool SetLine(const char *newLine); // set new token line and parses it
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum { MAX_LINE_CHARS = 2048, MAX_LINE_TOKENS = 128 };
|
||||||
|
|
||||||
|
char m_tokenBuffer[MAX_LINE_CHARS];
|
||||||
|
char m_fullLine[MAX_LINE_CHARS];
|
||||||
|
char *m_token[MAX_LINE_TOKENS];
|
||||||
|
int m_tokenNumber;
|
||||||
|
};
|
356
dep/rehlsdk/common/commandline.cpp
Normal file
356
dep/rehlsdk/common/commandline.cpp
Normal file
@ -0,0 +1,356 @@
|
|||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
class CCommandLine: public ICommandLine {
|
||||||
|
public:
|
||||||
|
CCommandLine();
|
||||||
|
virtual ~CCommandLine();
|
||||||
|
|
||||||
|
void CreateCmdLine(const char *commandline);
|
||||||
|
void CreateCmdLine(int argc, const char *argv[]);
|
||||||
|
const char *GetCmdLine() const;
|
||||||
|
|
||||||
|
// Check whether a particular parameter exists
|
||||||
|
const char *CheckParm(const char *psz, char **ppszValue = nullptr) const;
|
||||||
|
void RemoveParm(const char *pszParm);
|
||||||
|
void AppendParm(const char *pszParm, const char *pszValues);
|
||||||
|
|
||||||
|
void SetParm(const char *pszParm, const char *pszValues);
|
||||||
|
void SetParm(const char *pszParm, int iValue);
|
||||||
|
|
||||||
|
// When the commandline contains @name, it reads the parameters from that file
|
||||||
|
void LoadParametersFromFile(const char *&pSrc, char *&pDst, int maxDestLen);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Copy of actual command line
|
||||||
|
char *m_pszCmdLine;
|
||||||
|
};
|
||||||
|
|
||||||
|
CCommandLine g_CmdLine;
|
||||||
|
ICommandLine *cmdline = &g_CmdLine;
|
||||||
|
|
||||||
|
ICommandLine *CommandLine()
|
||||||
|
{
|
||||||
|
return &g_CmdLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCommandLine::CCommandLine()
|
||||||
|
{
|
||||||
|
m_pszCmdLine = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCommandLine::~CCommandLine()
|
||||||
|
{
|
||||||
|
if (m_pszCmdLine)
|
||||||
|
{
|
||||||
|
delete [] m_pszCmdLine;
|
||||||
|
m_pszCmdLine = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *CopyString(const char *src)
|
||||||
|
{
|
||||||
|
if (!src)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
char *out = (char *)new char[Q_strlen(src) + 1];
|
||||||
|
Q_strcpy(out, src);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a command line from the arguments passed in
|
||||||
|
void CCommandLine::CreateCmdLine(int argc, const char *argv[])
|
||||||
|
{
|
||||||
|
char cmdline[4096] = "";
|
||||||
|
const int MAX_CHARS = sizeof(cmdline) - 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < argc; ++i)
|
||||||
|
{
|
||||||
|
if (Q_strchr(argv[i], ' '))
|
||||||
|
{
|
||||||
|
Q_strlcat(cmdline, "\"");
|
||||||
|
Q_strlcat(cmdline, argv[i]);
|
||||||
|
Q_strlcat(cmdline, "\"");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Q_strlcat(cmdline, argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_strlcat(cmdline, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdline[Q_strlen(cmdline)] = '\0';
|
||||||
|
CreateCmdLine(cmdline);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCommandLine::LoadParametersFromFile(const char *&pSrc, char *&pDst, int maxDestLen)
|
||||||
|
{
|
||||||
|
// Suck out the file name
|
||||||
|
char szFileName[ MAX_PATH ];
|
||||||
|
char *pOut;
|
||||||
|
char *pDestStart = pDst;
|
||||||
|
|
||||||
|
// Skip the @ sign
|
||||||
|
pSrc++;
|
||||||
|
pOut = szFileName;
|
||||||
|
|
||||||
|
while (*pSrc && *pSrc != ' ')
|
||||||
|
{
|
||||||
|
*pOut++ = *pSrc++;
|
||||||
|
#if 0
|
||||||
|
if ((pOut - szFileName) >= (MAX_PATH - 1))
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
*pOut = '\0';
|
||||||
|
|
||||||
|
// Skip the space after the file name
|
||||||
|
if (*pSrc)
|
||||||
|
pSrc++;
|
||||||
|
|
||||||
|
// Now read in parameters from file
|
||||||
|
FILE *fp = fopen(szFileName, "r");
|
||||||
|
if (fp)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
c = (char)fgetc(fp);
|
||||||
|
while (c != EOF)
|
||||||
|
{
|
||||||
|
// Turn return characters into spaces
|
||||||
|
if (c == '\n')
|
||||||
|
c = ' ';
|
||||||
|
|
||||||
|
*pDst++ = c;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Don't go past the end, and allow for our terminating space character AND a terminating null character.
|
||||||
|
if ((pDst - pDestStart) >= (maxDestLen - 2))
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get the next character, if there are more
|
||||||
|
c = (char)fgetc(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a terminating space character
|
||||||
|
*pDst++ = ' ';
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Parameter file '%s' not found, skipping...", szFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Purpose: Create a command line from the passed in string
|
||||||
|
// Note that if you pass in a @filename, then the routine will read settings from a file instead of the command line
|
||||||
|
void CCommandLine::CreateCmdLine(const char *commandline)
|
||||||
|
{
|
||||||
|
if (m_pszCmdLine)
|
||||||
|
{
|
||||||
|
delete[] m_pszCmdLine;
|
||||||
|
m_pszCmdLine = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
char szFull[4096];
|
||||||
|
|
||||||
|
char *pDst = szFull;
|
||||||
|
const char *pSrc = commandline;
|
||||||
|
|
||||||
|
bool allowAtSign = true;
|
||||||
|
|
||||||
|
while (*pSrc)
|
||||||
|
{
|
||||||
|
if (*pSrc == '@')
|
||||||
|
{
|
||||||
|
if (allowAtSign)
|
||||||
|
{
|
||||||
|
LoadParametersFromFile(pSrc, pDst, sizeof(szFull) - (pDst - szFull));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allowAtSign = isspace(*pSrc) != 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Don't go past the end.
|
||||||
|
if ((pDst - szFull) >= (sizeof(szFull) - 1))
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
*pDst++ = *pSrc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pDst = '\0';
|
||||||
|
|
||||||
|
int len = Q_strlen(szFull) + 1;
|
||||||
|
m_pszCmdLine = new char[len];
|
||||||
|
Q_memcpy(m_pszCmdLine, szFull, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Purpose: Remove specified string ( and any args attached to it ) from command line
|
||||||
|
void CCommandLine::RemoveParm(const char *pszParm)
|
||||||
|
{
|
||||||
|
if (!m_pszCmdLine)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pszParm || *pszParm == '\0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Search for first occurrence of pszParm
|
||||||
|
char *p, *found;
|
||||||
|
char *pnextparam;
|
||||||
|
int n;
|
||||||
|
int curlen;
|
||||||
|
|
||||||
|
p = m_pszCmdLine;
|
||||||
|
while (*p)
|
||||||
|
{
|
||||||
|
curlen = Q_strlen(p);
|
||||||
|
found = Q_strstr(p, pszParm);
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pnextparam = found + 1;
|
||||||
|
while (pnextparam && *pnextparam && (*pnextparam != '-') && (*pnextparam != '+'))
|
||||||
|
pnextparam++;
|
||||||
|
|
||||||
|
if (pnextparam && *pnextparam)
|
||||||
|
{
|
||||||
|
// We are either at the end of the string, or at the next param. Just chop out the current param.
|
||||||
|
// # of characters after this param.
|
||||||
|
n = curlen - (pnextparam - p);
|
||||||
|
|
||||||
|
Q_memcpy(found, pnextparam, n);
|
||||||
|
found[n] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Clear out rest of string.
|
||||||
|
n = pnextparam - found;
|
||||||
|
Q_memset(found, 0, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip and trailing ' ' characters left over.
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int curpos = Q_strlen(m_pszCmdLine);
|
||||||
|
if (curpos == 0 || m_pszCmdLine[ curpos - 1 ] != ' ')
|
||||||
|
break;
|
||||||
|
|
||||||
|
m_pszCmdLine[curpos - 1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Purpose: Append parameter and argument values to command line
|
||||||
|
void CCommandLine::AppendParm(const char *pszParm, const char *pszValues)
|
||||||
|
{
|
||||||
|
int nNewLength = 0;
|
||||||
|
char *pCmdString;
|
||||||
|
|
||||||
|
// Parameter.
|
||||||
|
nNewLength = Q_strlen(pszParm);
|
||||||
|
|
||||||
|
// Values + leading space character.
|
||||||
|
if (pszValues)
|
||||||
|
nNewLength += Q_strlen(pszValues) + 1;
|
||||||
|
|
||||||
|
// Terminal 0;
|
||||||
|
nNewLength++;
|
||||||
|
|
||||||
|
if (!m_pszCmdLine)
|
||||||
|
{
|
||||||
|
m_pszCmdLine = new char[ nNewLength ];
|
||||||
|
Q_strcpy(m_pszCmdLine, pszParm);
|
||||||
|
if (pszValues)
|
||||||
|
{
|
||||||
|
Q_strcat(m_pszCmdLine, " ");
|
||||||
|
Q_strcat(m_pszCmdLine, pszValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove any remnants from the current Cmd Line.
|
||||||
|
RemoveParm(pszParm);
|
||||||
|
|
||||||
|
nNewLength += Q_strlen(m_pszCmdLine) + 1 + 1;
|
||||||
|
|
||||||
|
pCmdString = new char[ nNewLength ];
|
||||||
|
Q_memset(pCmdString, 0, nNewLength);
|
||||||
|
|
||||||
|
Q_strcpy(pCmdString, m_pszCmdLine); // Copy old command line.
|
||||||
|
Q_strcat(pCmdString, " "); // Put in a space
|
||||||
|
Q_strcat(pCmdString, pszParm);
|
||||||
|
|
||||||
|
if (pszValues)
|
||||||
|
{
|
||||||
|
Q_strcat(pCmdString, " ");
|
||||||
|
Q_strcat(pCmdString, pszValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kill off the old one
|
||||||
|
delete[] m_pszCmdLine;
|
||||||
|
|
||||||
|
// Point at the new command line.
|
||||||
|
m_pszCmdLine = pCmdString;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCommandLine::SetParm(const char *pszParm, const char *pszValues)
|
||||||
|
{
|
||||||
|
RemoveParm(pszParm);
|
||||||
|
AppendParm(pszParm, pszValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCommandLine::SetParm(const char *pszParm, int iValue)
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
Q_snprintf(buf, sizeof(buf), "%d", iValue);
|
||||||
|
SetParm(pszParm, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Purpose: Search for the parameter in the current commandline
|
||||||
|
const char *CCommandLine::CheckParm(const char *psz, char **ppszValue) const
|
||||||
|
{
|
||||||
|
static char sz[128] = "";
|
||||||
|
|
||||||
|
if (!m_pszCmdLine)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (ppszValue)
|
||||||
|
*ppszValue = nullptr;
|
||||||
|
|
||||||
|
char *pret = Q_strstr(m_pszCmdLine, psz);
|
||||||
|
if (!pret || !ppszValue)
|
||||||
|
return pret;
|
||||||
|
|
||||||
|
// find the next whitespace
|
||||||
|
char *p1 = pret;
|
||||||
|
do {
|
||||||
|
++p1;
|
||||||
|
} while (*p1 != ' ' && *p1);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
char *p2 = p1 + 1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (p2[i] == '\0' || p2[i] == ' ')
|
||||||
|
break;
|
||||||
|
|
||||||
|
sz[i] = p2[i];
|
||||||
|
i++;
|
||||||
|
} while (i < sizeof(sz));
|
||||||
|
|
||||||
|
sz[i] = '\0';
|
||||||
|
*ppszValue = sz;
|
||||||
|
|
||||||
|
return pret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *CCommandLine::GetCmdLine() const
|
||||||
|
{
|
||||||
|
return m_pszCmdLine;
|
||||||
|
}
|
@ -17,17 +17,8 @@
|
|||||||
|
|
||||||
#include "quakedef.h"
|
#include "quakedef.h"
|
||||||
|
|
||||||
// MD5 Hash
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned int buf[4];
|
|
||||||
unsigned int bits[2];
|
|
||||||
unsigned char in[64];
|
|
||||||
} MD5Context_t;
|
|
||||||
|
|
||||||
typedef unsigned int CRC32_t;
|
typedef unsigned int CRC32_t;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@ -45,11 +36,3 @@ BOOL CRC_File(CRC32_t *crcvalue, char *pszFileName);
|
|||||||
|
|
||||||
byte COM_BlockSequenceCRCByte(byte *base, int length, int sequence);
|
byte COM_BlockSequenceCRCByte(byte *base, int length, int sequence);
|
||||||
int CRC_MapFile(CRC32_t *crcvalue, char *pszFileName);
|
int CRC_MapFile(CRC32_t *crcvalue, char *pszFileName);
|
||||||
|
|
||||||
void MD5Init(MD5Context_t *ctx);
|
|
||||||
void MD5Update(MD5Context_t *ctx, const unsigned char *buf, unsigned int len);
|
|
||||||
void MD5Final(unsigned char digest[16], MD5Context_t *ctx);
|
|
||||||
void MD5Transform(unsigned int buf[4], const unsigned int in[16]);
|
|
||||||
|
|
||||||
BOOL MD5_Hash_File(unsigned char digest[16], char *pszFileName, BOOL bUsefopen, BOOL bSeed, unsigned int seed[4]);
|
|
||||||
char *MD5_Print(unsigned char hash[16]);
|
|
||||||
|
@ -36,4 +36,15 @@ typedef struct cvar_s
|
|||||||
struct cvar_s *next;
|
struct cvar_s *next;
|
||||||
} cvar_t;
|
} cvar_t;
|
||||||
|
|
||||||
|
using cvar_callback_t = void (*)(const char *pszNewValue);
|
||||||
|
|
||||||
|
struct cvar_listener_t
|
||||||
|
{
|
||||||
|
cvar_listener_t(const char *var_name, cvar_callback_t handler) :
|
||||||
|
func(handler), name(var_name) {}
|
||||||
|
|
||||||
|
cvar_callback_t func;
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // CVARDEF_H
|
#endif // CVARDEF_H
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
// For entityType below
|
// For entityType below
|
||||||
#define ENTITY_NORMAL (1<<0)
|
#define ENTITY_NORMAL (1<<0)
|
||||||
#define ENTITY_BEAM (1<<1)
|
#define ENTITY_BEAM (1<<1)
|
||||||
|
#define ENTITY_UNINITIALIZED (1<<30)
|
||||||
|
|
||||||
// Entity state is used for the baseline and for delta compression of a packet of
|
// Entity state is used for the baseline and for delta compression of a packet of
|
||||||
// entities that is sent to a client.
|
// entities that is sent to a client.
|
||||||
|
@ -16,12 +16,13 @@
|
|||||||
#ifndef ENUMS_H
|
#ifndef ENUMS_H
|
||||||
#define ENUMS_H
|
#define ENUMS_H
|
||||||
|
|
||||||
|
// Used as array indexer
|
||||||
typedef enum netsrc_s
|
typedef enum netsrc_s
|
||||||
{
|
{
|
||||||
NS_CLIENT,
|
NS_CLIENT = 0,
|
||||||
NS_SERVER,
|
NS_SERVER,
|
||||||
NS_MULTICAST // xxxMO
|
NS_MULTICAST, // xxxMO
|
||||||
|
NS_MAX
|
||||||
} netsrc_t;
|
} netsrc_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
|
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
|
||||||
//
|
//
|
||||||
// Purpose:
|
// Purpose:
|
||||||
//
|
//
|
||||||
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#define TYPE_CLIENT 0 // client is a normal HL client (default)
|
#define TYPE_CLIENT 0 // client is a normal HL client (default)
|
||||||
#define TYPE_PROXY 1 // client is another proxy
|
#define TYPE_PROXY 1 // client is another proxy
|
||||||
|
#define TYPE_DIRECTOR 2
|
||||||
#define TYPE_COMMENTATOR 3 // client is a commentator
|
#define TYPE_COMMENTATOR 3 // client is a commentator
|
||||||
#define TYPE_DEMO 4 // client is a demo file
|
#define TYPE_DEMO 4 // client is a demo file
|
||||||
|
|
||||||
@ -41,7 +42,6 @@
|
|||||||
|
|
||||||
#define DRC_CMD_LAST 15
|
#define DRC_CMD_LAST 15
|
||||||
|
|
||||||
|
|
||||||
// DRC_CMD_EVENT event flags
|
// DRC_CMD_EVENT event flags
|
||||||
#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important)
|
#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important)
|
||||||
#define DRC_FLAG_SIDE (1<<4) //
|
#define DRC_FLAG_SIDE (1<<4) //
|
||||||
@ -52,7 +52,6 @@
|
|||||||
#define DRC_FLAG_FINAL (1<<9) // is a final scene
|
#define DRC_FLAG_FINAL (1<<9) // is a final scene
|
||||||
#define DRC_FLAG_NO_RANDOM (1<<10) // don't randomize event data
|
#define DRC_FLAG_NO_RANDOM (1<<10) // don't randomize event data
|
||||||
|
|
||||||
|
|
||||||
// DRC_CMD_WAYPOINT flags
|
// DRC_CMD_WAYPOINT flags
|
||||||
#define DRC_FLAG_STARTPATH 1 // end with speed 0.0
|
#define DRC_FLAG_STARTPATH 1 // end with speed 0.0
|
||||||
#define DRC_FLAG_SLOWSTART 2 // start with speed 0.0
|
#define DRC_FLAG_SLOWSTART 2 // start with speed 0.0
|
||||||
|
@ -65,32 +65,31 @@ typedef union DLONG_u
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T min(T a, T b) {
|
inline T min(T a, T b)
|
||||||
|
{
|
||||||
return (a < b) ? a : b;
|
return (a < b) ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T max(T a, T b) {
|
inline T max(T a, T b)
|
||||||
|
{
|
||||||
return (a < b) ? b : a;
|
return (a < b) ? b : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T clamp(T a, T min, T max) {
|
inline T clamp(T a, T min, T max)
|
||||||
|
{
|
||||||
return (a > max) ? max : (a < min) ? min : a;
|
return (a > max) ? max : (a < min) ? min : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T bswap(T s) {
|
inline T bswap(T s)
|
||||||
switch (sizeof(T)) {
|
{
|
||||||
#ifdef _WIN32
|
switch (sizeof(T))
|
||||||
case 2: {auto res = _byteswap_ushort(*(uint16 *)&s); return *(T *)&res;}
|
{
|
||||||
case 4: {auto res = _byteswap_ulong(*(uint32 *)(&s)); return *(T *)&res;}
|
case 2: {auto res = __builtin_bswap16(*(uint16 *)&s); return *(T *)&res; }
|
||||||
case 8: {auto res = _byteswap_uint64(*(uint64 *)&s); return *(T *)&res;}
|
case 4: {auto res = __builtin_bswap32(*(uint32 *)&s); return *(T *)&res; }
|
||||||
#else
|
case 8: {auto res = __builtin_bswap64(*(uint64 *)&s); return *(T *)&res; }
|
||||||
case 2: {auto res = _bswap16(*(uint16 *)&s); return *(T *)&res;}
|
|
||||||
case 4: {auto res = _bswap(*(uint32 *)&s); return *(T *)&res;}
|
|
||||||
case 8: {auto res = _bswap64(*(uint64 *)&s); return *(T *)&res;}
|
|
||||||
#endif
|
|
||||||
default: return s;
|
default: return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
34
dep/rehlsdk/common/md5.h
Normal file
34
dep/rehlsdk/common/md5.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/***
|
||||||
|
*
|
||||||
|
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||||
|
*
|
||||||
|
* This product contains software technology licensed from Id
|
||||||
|
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use, distribution, and modification of this source code and/or resulting
|
||||||
|
* object code is restricted to non-commercial enhancements to products from
|
||||||
|
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||||
|
* without written permission from Valve LLC.
|
||||||
|
*
|
||||||
|
****/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <quakedef.h>
|
||||||
|
|
||||||
|
// MD5 Hash
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int buf[4];
|
||||||
|
unsigned int bits[2];
|
||||||
|
unsigned char in[64];
|
||||||
|
} MD5Context_t;
|
||||||
|
|
||||||
|
void MD5Init(MD5Context_t *ctx);
|
||||||
|
void MD5Update(MD5Context_t *ctx, const unsigned char *buf, unsigned int len);
|
||||||
|
void MD5Final(unsigned char digest[16], MD5Context_t *ctx);
|
||||||
|
void MD5Transform(unsigned int buf[4], const unsigned int in[16]);
|
||||||
|
|
||||||
|
BOOL MD5_Hash_File(unsigned char digest[16], char *pszFileName, BOOL bUsefopen, BOOL bSeed, unsigned int seed[4]);
|
||||||
|
char *MD5_Print(unsigned char hash[16]);
|
208
dep/rehlsdk/common/netapi.cpp
Normal file
208
dep/rehlsdk/common/netapi.cpp
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "winsock.h"
|
||||||
|
#else
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
#include "netapi.h"
|
||||||
|
|
||||||
|
class CNetAPI: public INetAPI {
|
||||||
|
public:
|
||||||
|
virtual void NetAdrToSockAddr(netadr_t *a, struct sockaddr *s);
|
||||||
|
virtual void SockAddrToNetAdr(struct sockaddr *s, netadr_t *a);
|
||||||
|
|
||||||
|
virtual char *AdrToString(netadr_t *a);
|
||||||
|
virtual bool StringToAdr(const char *s, netadr_t *a);
|
||||||
|
|
||||||
|
virtual void GetSocketAddress(int socket, netadr_t *a);
|
||||||
|
virtual bool CompareAdr(netadr_t *a, netadr_t *b);
|
||||||
|
virtual void GetLocalIP(netadr_t *a);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Expose interface
|
||||||
|
CNetAPI g_NetAPI;
|
||||||
|
INetAPI *net = (INetAPI *)&g_NetAPI;
|
||||||
|
|
||||||
|
void CNetAPI::NetAdrToSockAddr(netadr_t *a, struct sockaddr *s)
|
||||||
|
{
|
||||||
|
memset(s, 0, sizeof(*s));
|
||||||
|
|
||||||
|
if (a->type == NA_BROADCAST)
|
||||||
|
{
|
||||||
|
((struct sockaddr_in *)s)->sin_family = AF_INET;
|
||||||
|
((struct sockaddr_in *)s)->sin_port = a->port;
|
||||||
|
((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST;
|
||||||
|
}
|
||||||
|
else if (a->type == NA_IP)
|
||||||
|
{
|
||||||
|
((struct sockaddr_in *)s)->sin_family = AF_INET;
|
||||||
|
((struct sockaddr_in *)s)->sin_addr.s_addr = *(int *)&a->ip;
|
||||||
|
((struct sockaddr_in *)s)->sin_port = a->port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNetAPI::SockAddrToNetAdr(struct sockaddr *s, netadr_t *a)
|
||||||
|
{
|
||||||
|
if (s->sa_family == AF_INET)
|
||||||
|
{
|
||||||
|
a->type = NA_IP;
|
||||||
|
*(int *)&a->ip = ((struct sockaddr_in *)s)->sin_addr.s_addr;
|
||||||
|
a->port = ((struct sockaddr_in *)s)->sin_port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *CNetAPI::AdrToString(netadr_t *a)
|
||||||
|
{
|
||||||
|
static char s[64];
|
||||||
|
memset(s, 0, sizeof(s));
|
||||||
|
|
||||||
|
if (a)
|
||||||
|
{
|
||||||
|
if (a->type == NA_LOOPBACK)
|
||||||
|
{
|
||||||
|
sprintf(s, "loopback");
|
||||||
|
}
|
||||||
|
else if (a->type == NA_IP)
|
||||||
|
{
|
||||||
|
sprintf(s, "%i.%i.%i.%i:%i", a->ip[0], a->ip[1], a->ip[2], a->ip[3], ntohs(a->port));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StringToSockaddr(const char *s, struct sockaddr *sadr)
|
||||||
|
{
|
||||||
|
struct hostent *h;
|
||||||
|
char *colon;
|
||||||
|
char copy[128];
|
||||||
|
struct sockaddr_in *p;
|
||||||
|
|
||||||
|
memset(sadr, 0, sizeof(*sadr));
|
||||||
|
|
||||||
|
p = (struct sockaddr_in *)sadr;
|
||||||
|
p->sin_family = AF_INET;
|
||||||
|
p->sin_port = 0;
|
||||||
|
|
||||||
|
strcpy(copy, s);
|
||||||
|
|
||||||
|
// strip off a trailing :port if present
|
||||||
|
for (colon = copy ; *colon ; colon++)
|
||||||
|
{
|
||||||
|
if (*colon == ':')
|
||||||
|
{
|
||||||
|
// terminate
|
||||||
|
*colon = '\0';
|
||||||
|
|
||||||
|
// Start at next character
|
||||||
|
p->sin_port = htons((short)atoi(colon + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Numeric IP, no DNS
|
||||||
|
if (copy[0] >= '0' && copy[0] <= '9' && strstr(copy, "."))
|
||||||
|
{
|
||||||
|
*(int *)&p->sin_addr = inet_addr(copy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// DNS it
|
||||||
|
if (!(h = gethostbyname(copy)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use first result
|
||||||
|
*(int *)&p->sin_addr = *(int *)h->h_addr_list[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CNetAPI::StringToAdr(const char *s, netadr_t *a)
|
||||||
|
{
|
||||||
|
struct sockaddr sadr;
|
||||||
|
if (!strcmp(s, "localhost"))
|
||||||
|
{
|
||||||
|
memset(a, 0, sizeof(*a));
|
||||||
|
a->type = NA_LOOPBACK;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringToSockaddr(s, &sadr))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SockAddrToNetAdr(&sadr, a);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup the IP address for the specified IP socket
|
||||||
|
void CNetAPI::GetSocketAddress(int socket, netadr_t *a)
|
||||||
|
{
|
||||||
|
char buff[512];
|
||||||
|
struct sockaddr_in address;
|
||||||
|
int namelen;
|
||||||
|
|
||||||
|
memset(a, 0, sizeof(*a));
|
||||||
|
gethostname(buff, sizeof(buff));
|
||||||
|
|
||||||
|
// Ensure that it doesn't overrun the buffer
|
||||||
|
buff[sizeof buff - 1] = '\0';
|
||||||
|
StringToAdr(buff, a);
|
||||||
|
|
||||||
|
namelen = sizeof(address);
|
||||||
|
if (getsockname(socket, (struct sockaddr *)&address, (int *)&namelen) == 0)
|
||||||
|
{
|
||||||
|
a->port = address.sin_port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CNetAPI::CompareAdr(netadr_t *a, netadr_t *b)
|
||||||
|
{
|
||||||
|
if (a->type != b->type)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->type == NA_LOOPBACK)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->type == NA_IP &&
|
||||||
|
a->ip[0] == b->ip[0] &&
|
||||||
|
a->ip[1] == b->ip[1] &&
|
||||||
|
a->ip[2] == b->ip[2] &&
|
||||||
|
a->ip[3] == b->ip[3] &&
|
||||||
|
a->port == b->port)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNetAPI::GetLocalIP(netadr_t *a)
|
||||||
|
{
|
||||||
|
char s[64];
|
||||||
|
if(!::gethostname(s, 64))
|
||||||
|
{
|
||||||
|
struct hostent *localip = ::gethostbyname(s);
|
||||||
|
if(localip)
|
||||||
|
{
|
||||||
|
a->type = NA_IP;
|
||||||
|
a->port = 0;
|
||||||
|
memcpy(a->ip, localip->h_addr_list[0], 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
dep/rehlsdk/common/netapi.h
Normal file
25
dep/rehlsdk/common/netapi.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef NETAPI_H
|
||||||
|
#define NETAPI_H
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "netadr.h"
|
||||||
|
|
||||||
|
class INetAPI {
|
||||||
|
public:
|
||||||
|
virtual void NetAdrToSockAddr(netadr_t *a, struct sockaddr *s) = 0; // Convert a netadr_t to sockaddr
|
||||||
|
virtual void SockAddrToNetAdr(struct sockaddr *s, netadr_t *a) = 0; // Convert a sockaddr to netadr_t
|
||||||
|
|
||||||
|
virtual char *AdrToString(netadr_t *a) = 0; // Convert a netadr_t to a string
|
||||||
|
virtual bool StringToAdr(const char *s, netadr_t *a) = 0; // Convert a string address to a netadr_t, doing DNS if needed
|
||||||
|
virtual void GetSocketAddress(int socket, netadr_t *a) = 0; // Look up IP address for socket
|
||||||
|
virtual bool CompareAdr(netadr_t *a, netadr_t *b) = 0;
|
||||||
|
|
||||||
|
// return the IP of the local host
|
||||||
|
virtual void GetLocalIP(netadr_t *a) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern INetAPI *net;
|
||||||
|
|
||||||
|
#endif // NETAPI_H
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#define MAX_LIGHTSTYLE_INDEX_BITS 6
|
#define MAX_LIGHTSTYLE_INDEX_BITS 6
|
||||||
#define MAX_LIGHTSTYLES (1<<MAX_LIGHTSTYLE_INDEX_BITS)
|
#define MAX_LIGHTSTYLES (1<<MAX_LIGHTSTYLE_INDEX_BITS)
|
||||||
|
constexpr auto MAX_LIGHTSTYLE_SIZE = size_t{64};
|
||||||
|
|
||||||
// Resource counts
|
// Resource counts
|
||||||
#define MAX_MODEL_INDEX_BITS 9 // sent as a short
|
#define MAX_MODEL_INDEX_BITS 9 // sent as a short
|
||||||
|
33
dep/rehlsdk/common/stdc++compat.cpp
Normal file
33
dep/rehlsdk/common/stdc++compat.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
void NORETURN Sys_Error(const char *error, ...);
|
||||||
|
|
||||||
|
// This file adds the necessary compatibility tricks to avoid symbols with
|
||||||
|
// version GLIBCXX_3.4.16 and bigger, keeping binary compatibility with libstdc++ 4.6.1.
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
// We shouldn't be throwing exceptions at all, but it sadly turns out we call STL (inline) functions that do.
|
||||||
|
void __throw_out_of_range_fmt(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
char buf[1024]; // That should be big enough.
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
Sys_Error(buf);
|
||||||
|
}
|
||||||
|
}; // namespace std
|
||||||
|
|
||||||
|
// Technically, this symbol is not in GLIBCXX_3.4.20, but in CXXABI_1.3.8,
|
||||||
|
// but that's equivalent, version-wise. Those calls are added by the compiler
|
||||||
|
// itself on `new Class[n]` calls.
|
||||||
|
extern "C"
|
||||||
|
void __cxa_throw_bad_array_new_length()
|
||||||
|
{
|
||||||
|
Sys_Error("Bad array new length.");
|
||||||
|
}
|
||||||
|
#endif // !defined(_WIN32)
|
392
dep/rehlsdk/common/textconsole.cpp
Normal file
392
dep/rehlsdk/common/textconsole.cpp
Normal file
@ -0,0 +1,392 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
bool CTextConsole::Init(IBaseSystem *system)
|
||||||
|
{
|
||||||
|
// NULL or a valid base system interface
|
||||||
|
m_System = system;
|
||||||
|
|
||||||
|
Q_memset(m_szConsoleText, 0, sizeof(m_szConsoleText));
|
||||||
|
m_nConsoleTextLen = 0;
|
||||||
|
m_nCursorPosition = 0;
|
||||||
|
|
||||||
|
Q_memset(m_szSavedConsoleText, 0, sizeof(m_szSavedConsoleText));
|
||||||
|
m_nSavedConsoleTextLen = 0;
|
||||||
|
|
||||||
|
Q_memset(m_aszLineBuffer, 0, sizeof(m_aszLineBuffer));
|
||||||
|
m_nTotalLines = 0;
|
||||||
|
m_nInputLine = 0;
|
||||||
|
m_nBrowseLine = 0;
|
||||||
|
|
||||||
|
// these are log messages, not related to console
|
||||||
|
Sys_Printf("\n");
|
||||||
|
Sys_Printf("Console initialized.\n");
|
||||||
|
|
||||||
|
m_ConsoleVisible = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsole::InitSystem(IBaseSystem *system)
|
||||||
|
{
|
||||||
|
m_System = system;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsole::SetVisible(bool visible)
|
||||||
|
{
|
||||||
|
m_ConsoleVisible = visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTextConsole::IsVisible()
|
||||||
|
{
|
||||||
|
return m_ConsoleVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsole::ShutDown()
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsole::Print(char *pszMsg)
|
||||||
|
{
|
||||||
|
if (m_nConsoleTextLen)
|
||||||
|
{
|
||||||
|
int nLen = m_nConsoleTextLen;
|
||||||
|
while (nLen--)
|
||||||
|
{
|
||||||
|
PrintRaw("\b \b");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintRaw(pszMsg);
|
||||||
|
|
||||||
|
if (m_nConsoleTextLen)
|
||||||
|
{
|
||||||
|
PrintRaw(m_szConsoleText, m_nConsoleTextLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CTextConsole::ReceiveNewline()
|
||||||
|
{
|
||||||
|
int nLen = 0;
|
||||||
|
|
||||||
|
Echo("\n");
|
||||||
|
|
||||||
|
if (m_nConsoleTextLen)
|
||||||
|
{
|
||||||
|
nLen = m_nConsoleTextLen;
|
||||||
|
|
||||||
|
m_szConsoleText[ m_nConsoleTextLen ] = '\0';
|
||||||
|
m_nConsoleTextLen = 0;
|
||||||
|
m_nCursorPosition = 0;
|
||||||
|
|
||||||
|
// cache line in buffer, but only if it's not a duplicate of the previous line
|
||||||
|
if ((m_nInputLine == 0) || (Q_strcmp(m_aszLineBuffer[ m_nInputLine - 1 ], m_szConsoleText)))
|
||||||
|
{
|
||||||
|
Q_strncpy(m_aszLineBuffer[ m_nInputLine ], m_szConsoleText, MAX_CONSOLE_TEXTLEN);
|
||||||
|
m_nInputLine++;
|
||||||
|
|
||||||
|
if (m_nInputLine > m_nTotalLines)
|
||||||
|
m_nTotalLines = m_nInputLine;
|
||||||
|
|
||||||
|
if (m_nInputLine >= MAX_BUFFER_LINES)
|
||||||
|
m_nInputLine = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nBrowseLine = m_nInputLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsole::ReceiveBackspace()
|
||||||
|
{
|
||||||
|
int nCount;
|
||||||
|
|
||||||
|
if (m_nCursorPosition == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nConsoleTextLen--;
|
||||||
|
m_nCursorPosition--;
|
||||||
|
|
||||||
|
Echo("\b");
|
||||||
|
|
||||||
|
for (nCount = m_nCursorPosition; nCount < m_nConsoleTextLen; ++nCount)
|
||||||
|
{
|
||||||
|
m_szConsoleText[ nCount ] = m_szConsoleText[ nCount + 1 ];
|
||||||
|
Echo(m_szConsoleText + nCount, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Echo(" ");
|
||||||
|
|
||||||
|
nCount = m_nConsoleTextLen;
|
||||||
|
while (nCount >= m_nCursorPosition)
|
||||||
|
{
|
||||||
|
Echo("\b");
|
||||||
|
nCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nBrowseLine = m_nInputLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsole::ReceiveTab()
|
||||||
|
{
|
||||||
|
if (!m_System)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ObjectList matches;
|
||||||
|
m_szConsoleText[ m_nConsoleTextLen ] = '\0';
|
||||||
|
m_System->GetCommandMatches(m_szConsoleText, &matches);
|
||||||
|
|
||||||
|
if (matches.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (matches.CountElements() == 1)
|
||||||
|
{
|
||||||
|
char *pszCmdName = (char *)matches.GetFirst();
|
||||||
|
char *pszRest = pszCmdName + Q_strlen(m_szConsoleText);
|
||||||
|
|
||||||
|
if (pszRest)
|
||||||
|
{
|
||||||
|
Echo(pszRest);
|
||||||
|
Q_strlcat(m_szConsoleText, pszRest);
|
||||||
|
m_nConsoleTextLen += Q_strlen(pszRest);
|
||||||
|
|
||||||
|
Echo(" ");
|
||||||
|
Q_strlcat(m_szConsoleText, " ");
|
||||||
|
m_nConsoleTextLen++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int nLongestCmd = 0;
|
||||||
|
int nSmallestCmd = 0;
|
||||||
|
int nCurrentColumn;
|
||||||
|
int nTotalColumns;
|
||||||
|
char szCommonCmd[256]; // Should be enough.
|
||||||
|
char szFormatCmd[256];
|
||||||
|
char *pszSmallestCmd;
|
||||||
|
char *pszCurrentCmd = (char *)matches.GetFirst();
|
||||||
|
nSmallestCmd = Q_strlen(pszCurrentCmd);
|
||||||
|
pszSmallestCmd = pszCurrentCmd;
|
||||||
|
while (pszCurrentCmd)
|
||||||
|
{
|
||||||
|
if ((int)Q_strlen(pszCurrentCmd) > nLongestCmd)
|
||||||
|
{
|
||||||
|
nLongestCmd = Q_strlen(pszCurrentCmd);
|
||||||
|
}
|
||||||
|
if ((int)Q_strlen(pszCurrentCmd) < nSmallestCmd)
|
||||||
|
{
|
||||||
|
nSmallestCmd = Q_strlen(pszCurrentCmd);
|
||||||
|
pszSmallestCmd = pszCurrentCmd;
|
||||||
|
}
|
||||||
|
pszCurrentCmd = (char *)matches.GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
nTotalColumns = (GetWidth() - 1) / (nLongestCmd + 1);
|
||||||
|
nCurrentColumn = 0;
|
||||||
|
|
||||||
|
Echo("\n");
|
||||||
|
Q_strcpy(szCommonCmd, pszSmallestCmd);
|
||||||
|
|
||||||
|
// Would be nice if these were sorted, but not that big a deal
|
||||||
|
pszCurrentCmd = (char *)matches.GetFirst();
|
||||||
|
while (pszCurrentCmd)
|
||||||
|
{
|
||||||
|
if (++nCurrentColumn > nTotalColumns)
|
||||||
|
{
|
||||||
|
Echo("\n");
|
||||||
|
nCurrentColumn = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_snprintf(szFormatCmd, sizeof(szFormatCmd), "%-*s ", nLongestCmd, pszCurrentCmd);
|
||||||
|
Echo(szFormatCmd);
|
||||||
|
for (char *pCur = pszCurrentCmd, *pCommon = szCommonCmd; (*pCur && *pCommon); pCur++, pCommon++)
|
||||||
|
{
|
||||||
|
if (*pCur != *pCommon)
|
||||||
|
{
|
||||||
|
*pCommon = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pszCurrentCmd = (char *)matches.GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
Echo("\n");
|
||||||
|
if (Q_strcmp(szCommonCmd, m_szConsoleText))
|
||||||
|
{
|
||||||
|
Q_strcpy(m_szConsoleText, szCommonCmd);
|
||||||
|
m_nConsoleTextLen = Q_strlen(szCommonCmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
Echo(m_szConsoleText);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nCursorPosition = m_nConsoleTextLen;
|
||||||
|
m_nBrowseLine = m_nInputLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsole::ReceiveStandardChar(const char ch)
|
||||||
|
{
|
||||||
|
int nCount;
|
||||||
|
|
||||||
|
// If the line buffer is maxed out, ignore this char
|
||||||
|
if (m_nConsoleTextLen >= (sizeof(m_szConsoleText) - 2))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nCount = m_nConsoleTextLen;
|
||||||
|
while (nCount > m_nCursorPosition)
|
||||||
|
{
|
||||||
|
m_szConsoleText[ nCount ] = m_szConsoleText[ nCount - 1 ];
|
||||||
|
nCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_szConsoleText[ m_nCursorPosition ] = ch;
|
||||||
|
|
||||||
|
Echo(m_szConsoleText + m_nCursorPosition, m_nConsoleTextLen - m_nCursorPosition + 1);
|
||||||
|
|
||||||
|
m_nConsoleTextLen++;
|
||||||
|
m_nCursorPosition++;
|
||||||
|
|
||||||
|
nCount = m_nConsoleTextLen;
|
||||||
|
while (nCount > m_nCursorPosition)
|
||||||
|
{
|
||||||
|
Echo("\b");
|
||||||
|
nCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nBrowseLine = m_nInputLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsole::ReceiveUpArrow()
|
||||||
|
{
|
||||||
|
int nLastCommandInHistory = m_nInputLine + 1;
|
||||||
|
if (nLastCommandInHistory > m_nTotalLines)
|
||||||
|
nLastCommandInHistory = 0;
|
||||||
|
|
||||||
|
if (m_nBrowseLine == nLastCommandInHistory)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_nBrowseLine == m_nInputLine)
|
||||||
|
{
|
||||||
|
if (m_nConsoleTextLen > 0)
|
||||||
|
{
|
||||||
|
// Save off current text
|
||||||
|
Q_strncpy(m_szSavedConsoleText, m_szConsoleText, m_nConsoleTextLen);
|
||||||
|
// No terminator, it's a raw buffer we always know the length of
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nSavedConsoleTextLen = m_nConsoleTextLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nBrowseLine--;
|
||||||
|
if (m_nBrowseLine < 0)
|
||||||
|
{
|
||||||
|
m_nBrowseLine = m_nTotalLines - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete old line
|
||||||
|
while (m_nConsoleTextLen--)
|
||||||
|
{
|
||||||
|
Echo("\b \b");
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy buffered line
|
||||||
|
Echo(m_aszLineBuffer[ m_nBrowseLine ]);
|
||||||
|
|
||||||
|
Q_strncpy(m_szConsoleText, m_aszLineBuffer[ m_nBrowseLine ], MAX_CONSOLE_TEXTLEN);
|
||||||
|
|
||||||
|
m_nConsoleTextLen = Q_strlen(m_aszLineBuffer[ m_nBrowseLine ]);
|
||||||
|
m_nCursorPosition = m_nConsoleTextLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsole::ReceiveDownArrow()
|
||||||
|
{
|
||||||
|
if (m_nBrowseLine == m_nInputLine)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (++m_nBrowseLine > m_nTotalLines)
|
||||||
|
m_nBrowseLine = 0;
|
||||||
|
|
||||||
|
// delete old line
|
||||||
|
while (m_nConsoleTextLen--)
|
||||||
|
{
|
||||||
|
Echo("\b \b");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_nBrowseLine == m_nInputLine)
|
||||||
|
{
|
||||||
|
if (m_nSavedConsoleTextLen > 0)
|
||||||
|
{
|
||||||
|
// Restore current text
|
||||||
|
Q_strncpy(m_szConsoleText, m_szSavedConsoleText, m_nSavedConsoleTextLen);
|
||||||
|
// No terminator, it's a raw buffer we always know the length of
|
||||||
|
|
||||||
|
Echo(m_szConsoleText, m_nSavedConsoleTextLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nConsoleTextLen = m_nSavedConsoleTextLen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// copy buffered line
|
||||||
|
Echo(m_aszLineBuffer[ m_nBrowseLine ]);
|
||||||
|
Q_strncpy(m_szConsoleText, m_aszLineBuffer[ m_nBrowseLine ], MAX_CONSOLE_TEXTLEN);
|
||||||
|
m_nConsoleTextLen = Q_strlen(m_aszLineBuffer[ m_nBrowseLine ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nCursorPosition = m_nConsoleTextLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsole::ReceiveLeftArrow()
|
||||||
|
{
|
||||||
|
if (m_nCursorPosition == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Echo("\b");
|
||||||
|
m_nCursorPosition--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTextConsole::ReceiveRightArrow()
|
||||||
|
{
|
||||||
|
if (m_nCursorPosition == m_nConsoleTextLen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Echo(m_szConsoleText + m_nCursorPosition, 1);
|
||||||
|
m_nCursorPosition++;
|
||||||
|
}
|
95
dep/rehlsdk/common/textconsole.h
Normal file
95
dep/rehlsdk/common/textconsole.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IBaseSystem.h"
|
||||||
|
|
||||||
|
#define MAX_CONSOLE_TEXTLEN 256
|
||||||
|
#define MAX_BUFFER_LINES 30
|
||||||
|
|
||||||
|
class CTextConsole {
|
||||||
|
public:
|
||||||
|
virtual ~CTextConsole() {}
|
||||||
|
|
||||||
|
virtual bool Init(IBaseSystem *system = nullptr);
|
||||||
|
virtual void ShutDown();
|
||||||
|
virtual void Print(char *pszMsg);
|
||||||
|
|
||||||
|
virtual void SetTitle(char *pszTitle) {}
|
||||||
|
virtual void SetStatusLine(char *pszStatus) {}
|
||||||
|
virtual void UpdateStatus() {}
|
||||||
|
|
||||||
|
// Must be provided by children
|
||||||
|
virtual void PrintRaw(char *pszMsg, int nChars = 0) = 0;
|
||||||
|
virtual void Echo(char *pszMsg, int nChars = 0) = 0;
|
||||||
|
virtual char *GetLine() = 0;
|
||||||
|
virtual int GetWidth() = 0;
|
||||||
|
|
||||||
|
virtual void SetVisible(bool visible);
|
||||||
|
virtual bool IsVisible();
|
||||||
|
|
||||||
|
void InitSystem(IBaseSystem *system);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
char m_szConsoleText[MAX_CONSOLE_TEXTLEN]; // console text buffer
|
||||||
|
int m_nConsoleTextLen; // console textbuffer length
|
||||||
|
int m_nCursorPosition; // position in the current input line
|
||||||
|
|
||||||
|
// Saved input data when scrolling back through command history
|
||||||
|
char m_szSavedConsoleText[MAX_CONSOLE_TEXTLEN]; // console text buffer
|
||||||
|
int m_nSavedConsoleTextLen; // console textbuffer length
|
||||||
|
|
||||||
|
char m_aszLineBuffer[MAX_BUFFER_LINES][MAX_CONSOLE_TEXTLEN]; // command buffer last MAX_BUFFER_LINES commands
|
||||||
|
int m_nInputLine; // Current line being entered
|
||||||
|
int m_nBrowseLine; // current buffer line for up/down arrow
|
||||||
|
int m_nTotalLines; // # of nonempty lines in the buffer
|
||||||
|
|
||||||
|
bool m_ConsoleVisible;
|
||||||
|
|
||||||
|
IBaseSystem *m_System;
|
||||||
|
|
||||||
|
int ReceiveNewline();
|
||||||
|
void ReceiveBackspace();
|
||||||
|
void ReceiveTab();
|
||||||
|
void ReceiveStandardChar(const char ch);
|
||||||
|
void ReceiveUpArrow();
|
||||||
|
void ReceiveDownArrow();
|
||||||
|
void ReceiveLeftArrow();
|
||||||
|
void ReceiveRightArrow();
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "SteamAppStartUp.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include "TextConsoleWin32.h"
|
||||||
|
#else
|
||||||
|
#include "TextConsoleUnix.h"
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
void Sys_Printf(char *fmt, ...);
|
@ -54,9 +54,9 @@ CBaseEntity
|
|||||||
|
|
||||||
#ifndef CBASE_DLLEXPORT
|
#ifndef CBASE_DLLEXPORT
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define CBASE_DLLEXPORT _declspec( dllexport )
|
#define CBASE_DLLEXPORT _declspec( dllexport ) EXT_FUNC
|
||||||
#else
|
#else
|
||||||
#define CBASE_DLLEXPORT __attribute__ ((visibility("default")))
|
#define CBASE_DLLEXPORT __attribute__ ((visibility("default"))) EXT_FUNC
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -85,9 +85,9 @@ typedef int BOOL;
|
|||||||
|
|
||||||
#ifndef UTIL_DLLEXPORT
|
#ifndef UTIL_DLLEXPORT
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define UTIL_DLLEXPORT _declspec( dllexport )
|
#define UTIL_DLLEXPORT _declspec( dllexport ) EXT_FUNC
|
||||||
#else
|
#else
|
||||||
#define UTIL_DLLEXPORT __attribute__ ((visibility("default")))
|
#define UTIL_DLLEXPORT __attribute__ ((visibility("default"))) EXT_FUNC
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ typedef void(*xcommand_t)(void);
|
|||||||
typedef struct cmd_function_s
|
typedef struct cmd_function_s
|
||||||
{
|
{
|
||||||
struct cmd_function_s *next;
|
struct cmd_function_s *next;
|
||||||
char *name;
|
const char *name;
|
||||||
xcommand_t function;
|
xcommand_t function;
|
||||||
int flags;
|
int flags;
|
||||||
} cmd_function_t;
|
} cmd_function_t;
|
||||||
|
@ -115,10 +115,12 @@ uint32 crc32c_t_nosse(uint32 iCRC, const uint8 *buf, int len) {
|
|||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FUNC_TARGET("sse4.2")
|
||||||
uint32 crc32c_t8_sse(uint32 iCRC, uint8 u8) {
|
uint32 crc32c_t8_sse(uint32 iCRC, uint8 u8) {
|
||||||
return _mm_crc32_u8(iCRC, u8);
|
return _mm_crc32_u8(iCRC, u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FUNC_TARGET("sse4.2")
|
||||||
uint32 crc32c_t_sse(uint32 iCRC, const uint8 *buf, unsigned int len) {
|
uint32 crc32c_t_sse(uint32 iCRC, const uint8 *buf, unsigned int len) {
|
||||||
uint32 crc32cval = iCRC;
|
uint32 crc32cval = iCRC;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
@ -63,7 +63,14 @@ typedef struct resourceinfo_s
|
|||||||
|
|
||||||
typedef struct resource_s
|
typedef struct resource_s
|
||||||
{
|
{
|
||||||
|
#ifdef HOOK_HLTV
|
||||||
|
// NOTE HLTV: array szFileName declared on 260 cell,
|
||||||
|
// this changes necessary for compatibility hookers.
|
||||||
|
char szFileName[MAX_PATH];
|
||||||
|
#else
|
||||||
char szFileName[MAX_QPATH]; // File name to download/precache.
|
char szFileName[MAX_QPATH]; // File name to download/precache.
|
||||||
|
#endif // HOOK_HLTV
|
||||||
|
|
||||||
resourcetype_t type; // t_sound, t_skin, t_model, t_decal.
|
resourcetype_t type; // t_sound, t_skin, t_model, t_decal.
|
||||||
int nIndex; // For t_decals
|
int nIndex; // For t_decals
|
||||||
int nDownloadSize; // Size in Bytes if this must be downloaded.
|
int nDownloadSize; // Size in Bytes if this must be downloaded.
|
||||||
@ -75,7 +82,12 @@ typedef struct resource_s
|
|||||||
|
|
||||||
unsigned char rguc_reserved[ 32 ]; // For future expansion
|
unsigned char rguc_reserved[ 32 ]; // For future expansion
|
||||||
struct resource_s *pNext; // Next in chain.
|
struct resource_s *pNext; // Next in chain.
|
||||||
|
|
||||||
|
#if !defined(HLTV)
|
||||||
struct resource_s *pPrev;
|
struct resource_s *pPrev;
|
||||||
|
#else
|
||||||
|
unsigned char *data;
|
||||||
|
#endif // !defined(HLTV)
|
||||||
} resource_t;
|
} resource_t;
|
||||||
|
|
||||||
typedef struct customization_s
|
typedef struct customization_s
|
||||||
|
@ -37,9 +37,9 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define DLLEXPORT __stdcall
|
#define DLLEXPORT __stdcall EXT_FUNC
|
||||||
#else
|
#else
|
||||||
#define DLLEXPORT __attribute__ ((visibility("default")))
|
#define DLLEXPORT __attribute__ ((visibility("default"))) EXT_FUNC
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -144,11 +144,11 @@ typedef struct enginefuncs_s
|
|||||||
const char *(*pfnTraceTexture) (edict_t *pTextureEntity, const float *v1, const float *v2 );
|
const char *(*pfnTraceTexture) (edict_t *pTextureEntity, const float *v1, const float *v2 );
|
||||||
void (*pfnTraceSphere) (const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr);
|
void (*pfnTraceSphere) (const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr);
|
||||||
void (*pfnGetAimVector) (edict_t* ent, float speed, float *rgflReturn);
|
void (*pfnGetAimVector) (edict_t* ent, float speed, float *rgflReturn);
|
||||||
void (*pfnServerCommand) (char* str);
|
void (*pfnServerCommand) (const char* str);
|
||||||
void (*pfnServerExecute) (void);
|
void (*pfnServerExecute) (void);
|
||||||
void (*pfnClientCommand) (edict_t* pEdict, char* szFmt, ...);
|
void (*pfnClientCommand) (edict_t* pEdict, const char* szFmt, ...);
|
||||||
void (*pfnParticleEffect) (const float *org, const float *dir, float color, float count);
|
void (*pfnParticleEffect) (const float *org, const float *dir, float color, float count);
|
||||||
void (*pfnLightStyle) (int style, char* val);
|
void (*pfnLightStyle) (int style, const char* val);
|
||||||
int (*pfnDecalIndex) (const char *name);
|
int (*pfnDecalIndex) (const char *name);
|
||||||
int (*pfnPointContents) (const float *rgflVector);
|
int (*pfnPointContents) (const float *rgflVector);
|
||||||
void (*pfnMessageBegin) (int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
|
void (*pfnMessageBegin) (int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
|
||||||
@ -200,7 +200,7 @@ typedef struct enginefuncs_s
|
|||||||
void (*pfnSetView) (const edict_t *pClient, const edict_t *pViewent );
|
void (*pfnSetView) (const edict_t *pClient, const edict_t *pViewent );
|
||||||
float (*pfnTime) ( void );
|
float (*pfnTime) ( void );
|
||||||
void (*pfnCrosshairAngle) (const edict_t *pClient, float pitch, float yaw);
|
void (*pfnCrosshairAngle) (const edict_t *pClient, float pitch, float yaw);
|
||||||
byte * (*pfnLoadFileForMe) (char *filename, int *pLength);
|
byte * (*pfnLoadFileForMe) (const char *filename, int *pLength);
|
||||||
void (*pfnFreeFile) (void *buffer);
|
void (*pfnFreeFile) (void *buffer);
|
||||||
void (*pfnEndSection) (const char *pszSectionName); // trigger_endsection
|
void (*pfnEndSection) (const char *pszSectionName); // trigger_endsection
|
||||||
int (*pfnCompareFileTime) (char *filename1, char *filename2, int *iCompare);
|
int (*pfnCompareFileTime) (char *filename1, char *filename2, int *iCompare);
|
||||||
@ -215,9 +215,9 @@ typedef struct enginefuncs_s
|
|||||||
char* (*pfnInfoKeyValue) (char *infobuffer, const char *key);
|
char* (*pfnInfoKeyValue) (char *infobuffer, const char *key);
|
||||||
void (*pfnSetKeyValue) (char *infobuffer, const char *key, const char *value);
|
void (*pfnSetKeyValue) (char *infobuffer, const char *key, const char *value);
|
||||||
void (*pfnSetClientKeyValue) (int clientIndex, char *infobuffer, const char *key, const char *value);
|
void (*pfnSetClientKeyValue) (int clientIndex, char *infobuffer, const char *key, const char *value);
|
||||||
int (*pfnIsMapValid) (char *filename);
|
int (*pfnIsMapValid) (const char *filename);
|
||||||
void (*pfnStaticDecal) ( const float *origin, int decalIndex, int entityIndex, int modelIndex );
|
void (*pfnStaticDecal) ( const float *origin, int decalIndex, int entityIndex, int modelIndex );
|
||||||
int (*pfnPrecacheGeneric) (char* s);
|
int (*pfnPrecacheGeneric) (const char* s);
|
||||||
int (*pfnGetPlayerUserId) (edict_t *e ); // returns the server assigned userid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
|
int (*pfnGetPlayerUserId) (edict_t *e ); // returns the server assigned userid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
|
||||||
void (*pfnBuildSoundMsg) (edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
|
void (*pfnBuildSoundMsg) (edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
|
||||||
int (*pfnIsDedicatedServer) (void);// is this a dedicated server?
|
int (*pfnIsDedicatedServer) (void);// is this a dedicated server?
|
||||||
@ -239,7 +239,7 @@ typedef struct enginefuncs_s
|
|||||||
|
|
||||||
void (*pfnDeltaSetField) ( struct delta_s *pFields, const char *fieldname );
|
void (*pfnDeltaSetField) ( struct delta_s *pFields, const char *fieldname );
|
||||||
void (*pfnDeltaUnsetField) ( struct delta_s *pFields, const char *fieldname );
|
void (*pfnDeltaUnsetField) ( struct delta_s *pFields, const char *fieldname );
|
||||||
void (*pfnDeltaAddEncoder) ( char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) );
|
void (*pfnDeltaAddEncoder) ( const char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) );
|
||||||
int (*pfnGetCurrentPlayer) ( void );
|
int (*pfnGetCurrentPlayer) ( void );
|
||||||
int (*pfnCanSkipPlayer) ( const edict_t *player );
|
int (*pfnCanSkipPlayer) ( const edict_t *player );
|
||||||
int (*pfnDeltaFindField) ( struct delta_s *pFields, const char *fieldname );
|
int (*pfnDeltaFindField) ( struct delta_s *pFields, const char *fieldname );
|
||||||
@ -258,7 +258,7 @@ typedef struct enginefuncs_s
|
|||||||
|
|
||||||
void (*pfnGetPlayerStats) ( const edict_t *pClient, int *ping, int *packet_loss );
|
void (*pfnGetPlayerStats) ( const edict_t *pClient, int *ping, int *packet_loss );
|
||||||
|
|
||||||
void (*pfnAddServerCommand) ( char *cmd_name, void (*function) (void) );
|
void (*pfnAddServerCommand) ( const char *cmd_name, void (*function) (void) );
|
||||||
|
|
||||||
// For voice communications, set which clients hear eachother.
|
// For voice communications, set which clients hear eachother.
|
||||||
// NOTE: these functions take player entity indices (starting at 1).
|
// NOTE: these functions take player entity indices (starting at 1).
|
||||||
@ -274,7 +274,7 @@ typedef struct enginefuncs_s
|
|||||||
sentenceEntry_s* (*pfnSequencePickSentence) ( const char* groupName, int pickMethod, int *picked );
|
sentenceEntry_s* (*pfnSequencePickSentence) ( const char* groupName, int pickMethod, int *picked );
|
||||||
|
|
||||||
// LH: Give access to filesize via filesystem
|
// LH: Give access to filesize via filesystem
|
||||||
int (*pfnGetFileSize) ( char *filename );
|
int (*pfnGetFileSize) ( const char *filename );
|
||||||
|
|
||||||
unsigned int (*pfnGetApproxWavePlayLen) (const char *filepath);
|
unsigned int (*pfnGetApproxWavePlayLen) (const char *filepath);
|
||||||
// MDC: Added for CZ career-mode
|
// MDC: Added for CZ career-mode
|
||||||
|
@ -32,11 +32,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "osconfig.h"
|
#include "osconfig.h"
|
||||||
#include "mathlib.h"
|
#include "mathlib.h"
|
||||||
|
|
||||||
|
|
||||||
// Has no references on server side.
|
// Has no references on server side.
|
||||||
#define NOXREF
|
#define NOXREF
|
||||||
// Function body is not implemented.
|
// Function body is not implemented.
|
||||||
@ -44,9 +42,29 @@
|
|||||||
// Function is not tested at all.
|
// Function is not tested at all.
|
||||||
#define UNTESTED
|
#define UNTESTED
|
||||||
|
|
||||||
|
#define CONST_INTEGER_AS_STRING(x) #x //Wraps the integer in quotes, allowing us to form constant strings with it
|
||||||
|
#define __HACK_LINE_AS_STRING__(x) CONST_INTEGER_AS_STRING(x) //__LINE__ can only be converted to an actual number by going through this, otherwise the output is literally "__LINE__"
|
||||||
|
#define __LINE__AS_STRING __HACK_LINE_AS_STRING__(__LINE__) //Gives you the line number in constant string form
|
||||||
|
|
||||||
|
#if defined _MSC_VER || defined __INTEL_COMPILER
|
||||||
|
#define NOXREFCHECK int __retAddr; __asm { __asm mov eax, [ebp + 4] __asm mov __retAddr, eax }; Sys_Error("[NOXREFCHECK]: %s: (" __FILE__ ":" __LINE__AS_STRING ") NOXREF, but called from 0x%.08x", __func__, __retAddr)
|
||||||
|
#else
|
||||||
|
// For EBP based stack (older gcc) (uncomment version apropriate for your compiler)
|
||||||
|
//#define NOXREFCHECK int __retAddr; __asm__ __volatile__("movl 4(%%ebp), %%eax;" "movl %%eax, %0":"=r"(__retAddr)::"%eax"); Sys_Error("[NOXREFCHECK]: %s: (" __FILE__ ":" __LINE__AS_STRING ") NOXREF, but called from 0x%.08x", __func__, __retAddr);
|
||||||
|
// For ESP based stack (newer gcc) (uncomment version apropriate for your compiler)
|
||||||
|
#define NOXREFCHECK int __retAddr; __asm__ __volatile__("movl 16(%%esp), %%eax;" "movl %%eax, %0":"=r"(__retAddr)::"%eax"); Sys_Error("[NOXREFCHECK]: %s: (" __FILE__ ":" __LINE__AS_STRING ") NOXREF, but called from 0x%.08x", __func__, __retAddr);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BIT(n) (1<<(n))
|
#define BIT(n) (1<<(n))
|
||||||
|
|
||||||
|
// From engine/pr_comp.h;
|
||||||
|
typedef unsigned int string_t;
|
||||||
|
|
||||||
typedef unsigned int string_t; // from engine's pr_comp.h;
|
// From engine/server.h
|
||||||
|
typedef enum sv_delta_s
|
||||||
|
{
|
||||||
|
sv_packet_nodelta,
|
||||||
|
sv_packet_delta,
|
||||||
|
} sv_delta_t;
|
||||||
|
|
||||||
#endif // MAINTYPES_H
|
#endif // MAINTYPES_H
|
||||||
|
@ -74,7 +74,7 @@ typedef struct texture_s
|
|||||||
char name[16];
|
char name[16];
|
||||||
unsigned width, height;
|
unsigned width, height;
|
||||||
|
|
||||||
#ifndef SWDS
|
#if !defined(SWDS) && !defined(HLTV)
|
||||||
int gl_texturenum;
|
int gl_texturenum;
|
||||||
struct msurface_s * texturechain;
|
struct msurface_s * texturechain;
|
||||||
#endif
|
#endif
|
||||||
@ -85,7 +85,7 @@ typedef struct texture_s
|
|||||||
struct texture_s *alternate_anims; // bmodels in frame 1 use these
|
struct texture_s *alternate_anims; // bmodels in frame 1 use these
|
||||||
unsigned offsets[MIPLEVELS]; // four mip maps stored
|
unsigned offsets[MIPLEVELS]; // four mip maps stored
|
||||||
|
|
||||||
#ifdef SWDS
|
#if defined(SWDS) || defined(HLTV)
|
||||||
unsigned paloffset;
|
unsigned paloffset;
|
||||||
#else
|
#else
|
||||||
byte *pPal;
|
byte *pPal;
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#ifdef _WIN32 // WINDOWS
|
#ifdef _WIN32 // WINDOWS
|
||||||
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
#include <wsipx.h> // for support IPX
|
#include <wsipx.h> // for support IPX
|
||||||
@ -79,9 +80,6 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
// Deail with stupid macro in kernel.h
|
|
||||||
#undef __FUNCTION__
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -92,19 +90,32 @@
|
|||||||
#include <smmintrin.h>
|
#include <smmintrin.h>
|
||||||
#include <xmmintrin.h>
|
#include <xmmintrin.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32 // WINDOWS
|
#ifdef _WIN32 // WINDOWS
|
||||||
|
// Define __func__ on VS less than 2015
|
||||||
|
#if _MSC_VER < 1900
|
||||||
|
#define __func__ __FUNCTION__
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
#ifndef CDECL
|
#ifndef CDECL
|
||||||
#define CDECL __cdecl
|
#define CDECL __cdecl
|
||||||
#endif
|
#endif
|
||||||
|
#define FASTCALL __fastcall
|
||||||
#define STDCALL __stdcall
|
#define STDCALL __stdcall
|
||||||
#define HIDDEN
|
#define HIDDEN
|
||||||
|
#define FORCEINLINE __forceinline
|
||||||
#define NOINLINE __declspec(noinline)
|
#define NOINLINE __declspec(noinline)
|
||||||
#define ALIGN16 __declspec(align(16))
|
#define ALIGN16 __declspec(align(16))
|
||||||
#define NORETURN __declspec(noreturn)
|
#define NORETURN __declspec(noreturn)
|
||||||
#define FORCE_STACK_ALIGN
|
#define FORCE_STACK_ALIGN
|
||||||
|
#define FUNC_TARGET(x)
|
||||||
|
|
||||||
|
#define __builtin_bswap16 _byteswap_ushort
|
||||||
|
#define __builtin_bswap32 _byteswap_ulong
|
||||||
|
#define __builtin_bswap64 _byteswap_uint64
|
||||||
|
|
||||||
//inline bool SOCKET_FIONBIO(SOCKET s, int m) { return (ioctlsocket(s, FIONBIO, (u_long*)&m) == 0); }
|
//inline bool SOCKET_FIONBIO(SOCKET s, int m) { return (ioctlsocket(s, FIONBIO, (u_long*)&m) == 0); }
|
||||||
//inline int SOCKET_MSGLEN(SOCKET s, u_long& r) { return ioctlsocket(s, FIONREAD, (u_long*)&r); }
|
//inline int SOCKET_MSGLEN(SOCKET s, u_long& r) { return ioctlsocket(s, FIONREAD, (u_long*)&r); }
|
||||||
@ -124,11 +135,6 @@
|
|||||||
VirtualFree(ptr, 0, MEM_RELEASE);
|
VirtualFree(ptr, 0, MEM_RELEASE);
|
||||||
}
|
}
|
||||||
#else // _WIN32
|
#else // _WIN32
|
||||||
#ifdef __FUNCTION__
|
|
||||||
#undef __FUNCTION__
|
|
||||||
#endif
|
|
||||||
#define __FUNCTION__ __func__
|
|
||||||
|
|
||||||
#ifndef PAGESIZE
|
#ifndef PAGESIZE
|
||||||
#define PAGESIZE 4096
|
#define PAGESIZE 4096
|
||||||
#endif
|
#endif
|
||||||
@ -144,14 +150,26 @@
|
|||||||
typedef unsigned short WORD;
|
typedef unsigned short WORD;
|
||||||
typedef unsigned int UNINT32;
|
typedef unsigned int UNINT32;
|
||||||
|
|
||||||
|
#define FASTCALL
|
||||||
#define CDECL __attribute__ ((cdecl))
|
#define CDECL __attribute__ ((cdecl))
|
||||||
#define STDCALL __attribute__ ((stdcall))
|
#define STDCALL __attribute__ ((stdcall))
|
||||||
#define HIDDEN __attribute__((visibility("hidden")))
|
#define HIDDEN __attribute__((visibility("hidden")))
|
||||||
|
#define FORCEINLINE inline
|
||||||
#define NOINLINE __attribute__((noinline))
|
#define NOINLINE __attribute__((noinline))
|
||||||
#define ALIGN16 __attribute__((aligned(16)))
|
#define ALIGN16 __attribute__((aligned(16)))
|
||||||
#define NORETURN __attribute__((noreturn))
|
#define NORETURN __attribute__((noreturn))
|
||||||
#define FORCE_STACK_ALIGN __attribute__((force_align_arg_pointer))
|
#define FORCE_STACK_ALIGN __attribute__((force_align_arg_pointer))
|
||||||
|
|
||||||
|
#if defined __INTEL_COMPILER
|
||||||
|
#define FUNC_TARGET(x)
|
||||||
|
|
||||||
|
#define __builtin_bswap16 _bswap16
|
||||||
|
#define __builtin_bswap32 _bswap
|
||||||
|
#define __builtin_bswap64 _bswap64
|
||||||
|
#else
|
||||||
|
#define FUNC_TARGET(x) __attribute__((target(x)))
|
||||||
|
#endif // __INTEL_COMPILER
|
||||||
|
|
||||||
//inline bool SOCKET_FIONBIO(SOCKET s, int m) { return (ioctl(s, FIONBIO, (int*)&m) == 0); }
|
//inline bool SOCKET_FIONBIO(SOCKET s, int m) { return (ioctl(s, FIONBIO, (int*)&m) == 0); }
|
||||||
//inline int SOCKET_MSGLEN(SOCKET s, u_long& r) { return ioctl(s, FIONREAD, (int*)&r); }
|
//inline int SOCKET_MSGLEN(SOCKET s, u_long& r) { return ioctl(s, FIONREAD, (int*)&r); }
|
||||||
typedef int SOCKET;
|
typedef int SOCKET;
|
||||||
@ -164,6 +182,10 @@
|
|||||||
#define SOCKET_AGAIN() (errno == EAGAIN)
|
#define SOCKET_AGAIN() (errno == EAGAIN)
|
||||||
#define SOCKET_ERROR -1
|
#define SOCKET_ERROR -1
|
||||||
|
|
||||||
|
inline int ioctlsocket(int fd, int cmd, unsigned int *argp) { return ioctl(fd, cmd, argp); }
|
||||||
|
inline int closesocket(int fd) { return close(fd); }
|
||||||
|
inline int WSAGetLastError() { return errno; }
|
||||||
|
|
||||||
inline void* sys_allocmem(unsigned int size) {
|
inline void* sys_allocmem(unsigned int size) {
|
||||||
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
}
|
}
|
||||||
@ -191,4 +213,8 @@
|
|||||||
|
|
||||||
#define EXT_FUNC FORCE_STACK_ALIGN
|
#define EXT_FUNC FORCE_STACK_ALIGN
|
||||||
|
|
||||||
|
// Used to obtain the string name of a variable.
|
||||||
|
#define nameof_variable(name) template_nameof_variable(name, #name)
|
||||||
|
template <typename T> const char* template_nameof_variable(const T& /*validate_type*/, const char* name) { return name; }
|
||||||
|
|
||||||
#endif // _OSCONFIG_H
|
#endif // _OSCONFIG_H
|
||||||
|
51
dep/rehlsdk/engine/pr_dlls.h
Normal file
51
dep/rehlsdk/engine/pr_dlls.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* This program 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 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "maintypes.h"
|
||||||
|
#include "eiface.h"
|
||||||
|
|
||||||
|
const int MAX_EXTENSION_DLL = 50;
|
||||||
|
|
||||||
|
typedef struct functiontable_s
|
||||||
|
{
|
||||||
|
uint32 pFunction;
|
||||||
|
char *pFunctionName;
|
||||||
|
} functiontable_t;
|
||||||
|
|
||||||
|
typedef struct extensiondll_s
|
||||||
|
{
|
||||||
|
void *lDLLHandle;
|
||||||
|
functiontable_t *functionTable;
|
||||||
|
int functionCount;
|
||||||
|
} extensiondll_t;
|
||||||
|
|
||||||
|
typedef void(*ENTITYINIT)(struct entvars_s *);
|
||||||
|
typedef void(*DISPATCHFUNCTION)(struct entvars_s *, void *);
|
||||||
|
typedef void(*FIELDIOFUNCTION)(SAVERESTOREDATA *, const char *, void *, TYPEDESCRIPTION *, int);
|
@ -33,9 +33,11 @@
|
|||||||
#include "FlightRecorder.h"
|
#include "FlightRecorder.h"
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
#include "ObjectList.h"
|
||||||
|
#include "pr_dlls.h"
|
||||||
|
|
||||||
#define REHLDS_API_VERSION_MAJOR 3
|
#define REHLDS_API_VERSION_MAJOR 3
|
||||||
#define REHLDS_API_VERSION_MINOR 0
|
#define REHLDS_API_VERSION_MINOR 3
|
||||||
|
|
||||||
//Steam_NotifyClientConnect hook
|
//Steam_NotifyClientConnect hook
|
||||||
typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect;
|
typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect;
|
||||||
@ -189,6 +191,10 @@ typedef IHookChainRegistry<int, enum sv_delta_s, IGameClient *, struct packet_en
|
|||||||
typedef IHookChain<bool, edict_t *, IGameClient *, int, const char*, float, float, int, int, int, const float*> IRehldsHook_SV_EmitSound2;
|
typedef IHookChain<bool, edict_t *, IGameClient *, int, const char*, float, float, int, int, int, const float*> IRehldsHook_SV_EmitSound2;
|
||||||
typedef IHookChainRegistry<bool, edict_t *, IGameClient *, int, const char*, float, float, int, int, int, const float*> IRehldsHookRegistry_SV_EmitSound2;
|
typedef IHookChainRegistry<bool, edict_t *, IGameClient *, int, const char*, float, float, int, int, int, const float*> IRehldsHookRegistry_SV_EmitSound2;
|
||||||
|
|
||||||
|
//CreateFakeClient hook
|
||||||
|
typedef IHookChain<edict_t *, const char *> IRehldsHook_CreateFakeClient;
|
||||||
|
typedef IHookChainRegistry<edict_t *, const char *> IRehldsHookRegistry_CreateFakeClient;
|
||||||
|
|
||||||
class IRehldsHookchains {
|
class IRehldsHookchains {
|
||||||
public:
|
public:
|
||||||
virtual ~IRehldsHookchains() { }
|
virtual ~IRehldsHookchains() { }
|
||||||
@ -231,6 +237,7 @@ public:
|
|||||||
virtual IRehldsHookRegistry_SV_Spawn_f* SV_Spawn_f() = 0;
|
virtual IRehldsHookRegistry_SV_Spawn_f* SV_Spawn_f() = 0;
|
||||||
virtual IRehldsHookRegistry_SV_CreatePacketEntities* SV_CreatePacketEntities() = 0;
|
virtual IRehldsHookRegistry_SV_CreatePacketEntities* SV_CreatePacketEntities() = 0;
|
||||||
virtual IRehldsHookRegistry_SV_EmitSound2* SV_EmitSound2() = 0;
|
virtual IRehldsHookRegistry_SV_EmitSound2* SV_EmitSound2() = 0;
|
||||||
|
virtual IRehldsHookRegistry_CreateFakeClient* CreateFakeClient() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RehldsFuncs_t {
|
struct RehldsFuncs_t {
|
||||||
@ -267,7 +274,7 @@ struct RehldsFuncs_t {
|
|||||||
cvar_t*(*GetCvarVars)();
|
cvar_t*(*GetCvarVars)();
|
||||||
int (*SV_GetChallenge)(const netadr_t& adr);
|
int (*SV_GetChallenge)(const netadr_t& adr);
|
||||||
void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
|
void (*SV_AddResource)(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
|
||||||
int(*MSG_ReadShort)(void);
|
int(*MSG_ReadShort)();
|
||||||
int(*MSG_ReadBuf)(int iSize, void *pbuf);
|
int(*MSG_ReadBuf)(int iSize, void *pbuf);
|
||||||
void(*MSG_WriteBuf)(sizebuf_t *sb, int iSize, void *buf);
|
void(*MSG_WriteBuf)(sizebuf_t *sb, int iSize, void *buf);
|
||||||
void(*MSG_WriteByte)(sizebuf_t *sb, int c);
|
void(*MSG_WriteByte)(sizebuf_t *sb, int c);
|
||||||
@ -282,6 +289,13 @@ struct RehldsFuncs_t {
|
|||||||
bool(*SV_EmitSound2)(edict_t *entity, IGameClient *receiver, int channel, const char *sample, float volume, float attenuation, int flags, int pitch, int emitFlags, const float *pOrigin);
|
bool(*SV_EmitSound2)(edict_t *entity, IGameClient *receiver, int channel, const char *sample, float volume, float attenuation, int flags, int pitch, int emitFlags, const float *pOrigin);
|
||||||
void(*SV_UpdateUserInfo)(IGameClient *pGameClient);
|
void(*SV_UpdateUserInfo)(IGameClient *pGameClient);
|
||||||
bool(*StripUnprintableAndSpace)(char *pch);
|
bool(*StripUnprintableAndSpace)(char *pch);
|
||||||
|
void(*Cmd_RemoveCmd)(const char *cmd_name);
|
||||||
|
void(*GetCommandMatches)(const char *string, ObjectList *pMatchList);
|
||||||
|
bool(*AddExtDll)(void *hModule);
|
||||||
|
void(*AddCvarListener)(const char *var_name, cvar_callback_t func);
|
||||||
|
void(*RemoveExtDll)(void *hModule);
|
||||||
|
void(*RemoveCvarListener)(const char *var_name, cvar_callback_t func);
|
||||||
|
ENTITYINIT(*GetEntityInit)(char *pszClassName);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IRehldsApi {
|
class IRehldsApi {
|
||||||
|
@ -44,7 +44,7 @@ private:
|
|||||||
// this was a root node
|
// this was a root node
|
||||||
unsigned int rootId = GetRoodNodeId(node->key);
|
unsigned int rootId = GetRoodNodeId(node->key);
|
||||||
if (m_RootNodes[rootId] != node) {
|
if (m_RootNodes[rootId] != node) {
|
||||||
Sys_Error(__FUNCTION__ ": invalid root node");
|
Sys_Error("%s: invalid root node", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#include <cpuid.h>
|
#include <cpuid.h>
|
||||||
|
#elif _MSC_VER >= 1400 && !defined(ASMLIB_H)
|
||||||
|
#include <intrin.h> // __cpuidex
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SSE3_FLAG (1<<0)
|
#define SSE3_FLAG (1<<0)
|
||||||
|
@ -208,7 +208,7 @@ typedef struct playermove_s
|
|||||||
void (*PM_GetModelBounds)( struct model_s *mod, float *mins, float *maxs );
|
void (*PM_GetModelBounds)( struct model_s *mod, float *mins, float *maxs );
|
||||||
void *(*PM_HullForBsp)( physent_t *pe, float *offset );
|
void *(*PM_HullForBsp)( physent_t *pe, float *offset );
|
||||||
float (*PM_TraceModel)( physent_t *pEnt, float *start, float *end, trace_t *trace );
|
float (*PM_TraceModel)( physent_t *pEnt, float *start, float *end, trace_t *trace );
|
||||||
int (*COM_FileSize)(char *filename);
|
int (*COM_FileSize)(const char *filename);
|
||||||
byte *(*COM_LoadFile) (const char *path, int usehunk, int *pLength);
|
byte *(*COM_LoadFile) (const char *path, int usehunk, int *pLength);
|
||||||
void (*COM_FreeFile) ( void *buffer );
|
void (*COM_FreeFile) ( void *buffer );
|
||||||
char *(*memfgets)( byte *pMemFile, int fileSize, int *pFilePos, char *pBuffer, int bufferSize );
|
char *(*memfgets)( byte *pMemFile, int fileSize, int *pFilePos, char *pBuffer, int bufferSize );
|
||||||
|
@ -51,10 +51,20 @@ void Revoice_Init_Cvars()
|
|||||||
g_pcv_sv_voiceenable = g_engfuncs.pfnCVarGetPointer("sv_voiceenable");
|
g_pcv_sv_voiceenable = g_engfuncs.pfnCVarGetPointer("sv_voiceenable");
|
||||||
g_pcv_rev_hltv_codec = g_engfuncs.pfnCVarGetPointer(g_cv_rev_hltv_codec.name);
|
g_pcv_rev_hltv_codec = g_engfuncs.pfnCVarGetPointer(g_cv_rev_hltv_codec.name);
|
||||||
g_pcv_rev_default_codec = g_engfuncs.pfnCVarGetPointer(g_cv_rev_default_codec.name);
|
g_pcv_rev_default_codec = g_engfuncs.pfnCVarGetPointer(g_cv_rev_default_codec.name);
|
||||||
|
|
||||||
|
g_RehldsFuncs->AddCvarListener(g_cv_rev_hltv_codec.name, Revoice_Update_Hltv);
|
||||||
|
g_RehldsFuncs->AddCvarListener(g_cv_rev_default_codec.name, Revoice_Update_Players);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Revoice_DeInit_Cvars()
|
||||||
|
{
|
||||||
|
g_RehldsFuncs->RemoveCvarListener(g_cv_rev_hltv_codec.name, Revoice_Update_Hltv);
|
||||||
|
g_RehldsFuncs->RemoveCvarListener(g_cv_rev_default_codec.name, Revoice_Update_Players);
|
||||||
}
|
}
|
||||||
|
|
||||||
REVCmds g_revoice_cmds[] = {
|
REVCmds g_revoice_cmds[] = {
|
||||||
{ "version", Cmd_REV_Version }
|
{ "version", Cmd_REV_Version },
|
||||||
|
{ "status", Cmd_REV_Status }
|
||||||
};
|
};
|
||||||
|
|
||||||
void Revoice_Cmds_Handler()
|
void Revoice_Cmds_Handler()
|
||||||
@ -75,3 +85,23 @@ void Cmd_REV_Version()
|
|||||||
g_engfuncs.pfnServerPrint("Build date: " APP_COMMIT_TIME " " APP_COMMIT_DATE "\n");
|
g_engfuncs.pfnServerPrint("Build date: " APP_COMMIT_TIME " " APP_COMMIT_DATE "\n");
|
||||||
g_engfuncs.pfnServerPrint("Build from: " APP_COMMIT_URL APP_COMMIT_SHA "\n");
|
g_engfuncs.pfnServerPrint("Build from: " APP_COMMIT_URL APP_COMMIT_SHA "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cmd_REV_Status()
|
||||||
|
{
|
||||||
|
int nUsers = 0;
|
||||||
|
UTIL_ServerPrintf("\n%-5s %-32s %-6s %-4s %5s", "#", "name", "codec", "rate", "proto");
|
||||||
|
|
||||||
|
for (int i = 0; i < g_RehldsSvs->GetMaxClients(); i++) {
|
||||||
|
auto plr = &g_Players[i];
|
||||||
|
if (plr->IsConnected()) {
|
||||||
|
printf("#%-4i %-32s %-6s %-4i %-2i %-3s", i + 1, UTIL_VarArgs("\"%s\"", plr->GetClient()->GetName()), plr->GetCodecTypeToString(), plr->GetVoiceRate(), plr->GetProtocol(), plr->IsHLTV() ? " (HLTV)" : "");
|
||||||
|
nUsers++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nUsers) {
|
||||||
|
UTIL_ServerPrintf("0 users");
|
||||||
|
}
|
||||||
|
|
||||||
|
UTIL_ServerPrintf("\n");
|
||||||
|
}
|
||||||
|
@ -10,8 +10,11 @@ struct REVCmds {
|
|||||||
void Revoice_Exec_Config();
|
void Revoice_Exec_Config();
|
||||||
bool Revoice_Init_Config();
|
bool Revoice_Init_Config();
|
||||||
void Revoice_Init_Cvars();
|
void Revoice_Init_Cvars();
|
||||||
|
void Revoice_DeInit_Cvars();
|
||||||
|
|
||||||
void Revoice_Cmds_Handler();
|
void Revoice_Cmds_Handler();
|
||||||
|
|
||||||
|
void Cmd_REV_Status();
|
||||||
void Cmd_REV_Version();
|
void Cmd_REV_Version();
|
||||||
|
|
||||||
extern cvar_t *g_pcv_sv_voiceenable;
|
extern cvar_t *g_pcv_sv_voiceenable;
|
||||||
|
@ -216,16 +216,6 @@ void SV_WriteVoiceCodec_hooked(IRehldsHook_SV_WriteVoiceCodec *chain, sizebuf_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cvar_DirectSet_hooked(IRehldsHook_Cvar_DirectSet *chain, cvar_t *var, const char *value)
|
|
||||||
{
|
|
||||||
chain->callNext(var, value);
|
|
||||||
|
|
||||||
if (g_pcv_rev_hltv_codec == var
|
|
||||||
|| g_pcv_rev_default_codec == var) {
|
|
||||||
Revoice_Update_Players();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Revoice_Load()
|
bool Revoice_Load()
|
||||||
{
|
{
|
||||||
if (!Revoice_Utils_Init())
|
if (!Revoice_Utils_Init())
|
||||||
@ -256,7 +246,6 @@ bool Revoice_Main_Init()
|
|||||||
g_RehldsHookchains->SV_DropClient()->registerHook(&SV_DropClient_hook, HC_PRIORITY_DEFAULT + 1);
|
g_RehldsHookchains->SV_DropClient()->registerHook(&SV_DropClient_hook, HC_PRIORITY_DEFAULT + 1);
|
||||||
g_RehldsHookchains->HandleNetCommand()->registerHook(&Rehlds_HandleNetCommand, HC_PRIORITY_DEFAULT + 1);
|
g_RehldsHookchains->HandleNetCommand()->registerHook(&Rehlds_HandleNetCommand, HC_PRIORITY_DEFAULT + 1);
|
||||||
g_RehldsHookchains->SV_WriteVoiceCodec()->registerHook(&SV_WriteVoiceCodec_hooked, HC_PRIORITY_DEFAULT + 1);
|
g_RehldsHookchains->SV_WriteVoiceCodec()->registerHook(&SV_WriteVoiceCodec_hooked, HC_PRIORITY_DEFAULT + 1);
|
||||||
g_RehldsHookchains->Cvar_DirectSet()->registerHook(&Cvar_DirectSet_hooked, HC_PRIORITY_DEFAULT + 1);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -266,5 +255,6 @@ void Revoice_Main_DeInit()
|
|||||||
g_RehldsHookchains->SV_DropClient()->unregisterHook(&SV_DropClient_hook);
|
g_RehldsHookchains->SV_DropClient()->unregisterHook(&SV_DropClient_hook);
|
||||||
g_RehldsHookchains->HandleNetCommand()->unregisterHook(&Rehlds_HandleNetCommand);
|
g_RehldsHookchains->HandleNetCommand()->unregisterHook(&Rehlds_HandleNetCommand);
|
||||||
g_RehldsHookchains->SV_WriteVoiceCodec()->unregisterHook(&SV_WriteVoiceCodec_hooked);
|
g_RehldsHookchains->SV_WriteVoiceCodec()->unregisterHook(&SV_WriteVoiceCodec_hooked);
|
||||||
g_RehldsHookchains->Cvar_DirectSet()->unregisterHook(&Cvar_DirectSet_hooked);
|
|
||||||
|
Revoice_DeInit_Cvars();
|
||||||
}
|
}
|
||||||
|
@ -81,9 +81,12 @@ void CRevoicePlayer::OnDisconnected()
|
|||||||
|
|
||||||
void CRevoicePlayer::Update()
|
void CRevoicePlayer::Update()
|
||||||
{
|
{
|
||||||
m_CodecType = GetCodecTypeByString(((m_HLTV) ?
|
if (m_HLTV) {
|
||||||
g_pcv_rev_hltv_codec : g_pcv_rev_default_codec)->string);
|
m_CodecType = GetCodecTypeByString(g_pcv_rev_hltv_codec->string);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_CodecType = GetCodecTypeByString(g_pcv_rev_default_codec->string);
|
||||||
m_RequestId = MAKE_REQUESTID(PLID);
|
m_RequestId = MAKE_REQUESTID(PLID);
|
||||||
|
|
||||||
if (m_Protocol == 48) {
|
if (m_Protocol == 48) {
|
||||||
@ -91,16 +94,6 @@ void CRevoicePlayer::Update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Revoice_Update_Players()
|
|
||||||
{
|
|
||||||
int maxclients = g_RehldsSvs->GetMaxClients();
|
|
||||||
for (int i = 0; i < maxclients; i++) {
|
|
||||||
if (g_Players[i].IsConnected()) {
|
|
||||||
g_Players[i].Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Revoice_Init_Players()
|
void Revoice_Init_Players()
|
||||||
{
|
{
|
||||||
int maxclients = g_RehldsSvs->GetMaxClients();
|
int maxclients = g_RehldsSvs->GetMaxClients();
|
||||||
@ -109,6 +102,27 @@ void Revoice_Init_Players()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Revoice_Update_Players(const char *pszNewValue)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < g_RehldsSvs->GetMaxClients(); i++) {
|
||||||
|
auto plr = &g_Players[i];
|
||||||
|
if (plr->IsConnected()) {
|
||||||
|
plr->Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Revoice_Update_Hltv(const char *pszNewValue)
|
||||||
|
{
|
||||||
|
int maxclients = g_RehldsSvs->GetMaxClients();
|
||||||
|
for (int i = 0; i < g_RehldsSvs->GetMaxClients(); i++) {
|
||||||
|
auto plr = &g_Players[i];
|
||||||
|
if (plr->IsConnected() && plr->IsHLTV()) {
|
||||||
|
plr->Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CRevoicePlayer *GetPlayerByClientPtr(IGameClient *cl)
|
CRevoicePlayer *GetPlayerByClientPtr(IGameClient *cl)
|
||||||
{
|
{
|
||||||
return &g_Players[ cl->GetId() ];
|
return &g_Players[ cl->GetId() ];
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
CodecType GetCodecTypeByString(const char *codec);
|
CodecType GetCodecTypeByString(const char *codec);
|
||||||
const char *GetCodecTypeToString();
|
const char *GetCodecTypeToString();
|
||||||
|
|
||||||
|
int GetProtocol() const { return m_Protocol; }
|
||||||
int GetVoiceRate() const { return m_VoiceRate; }
|
int GetVoiceRate() const { return m_VoiceRate; }
|
||||||
int GetRequestId() const { return m_RequestId; }
|
int GetRequestId() const { return m_RequestId; }
|
||||||
bool IsConnected() const { return m_Connected; }
|
bool IsConnected() const { return m_Connected; }
|
||||||
@ -53,4 +54,5 @@ CRevoicePlayer *GetPlayerByClientPtr(IGameClient *cl);
|
|||||||
CRevoicePlayer *GetPlayerByEdict(const edict_t *ed);
|
CRevoicePlayer *GetPlayerByEdict(const edict_t *ed);
|
||||||
|
|
||||||
void Revoice_Init_Players();
|
void Revoice_Init_Players();
|
||||||
void Revoice_Update_Players();
|
void Revoice_Update_Players(const char *pszNewValue);
|
||||||
|
void Revoice_Update_Hltv(const char *pszNewValue);
|
||||||
|
@ -36,21 +36,6 @@ enum svc_messages {
|
|||||||
svc_voicedata = 53
|
svc_voicedata = 53
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T _min(T a, T b) {
|
|
||||||
return (a < b) ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T _max(T a, T b) {
|
|
||||||
return (a < b) ? b : a;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T clamp(T a, T min, T max) {
|
|
||||||
return (a > max) ? max : (a < min) ? min : a;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern char* trimbuf(char *str);
|
extern char* trimbuf(char *str);
|
||||||
extern void NormalizePath(char *path);
|
extern void NormalizePath(char *path);
|
||||||
extern bool IsFileExists(const char *path);
|
extern bool IsFileExists(const char *path);
|
||||||
|
@ -43,3 +43,35 @@ void UTIL_LogPrintf(char *fmt, ...)
|
|||||||
// Print to server console
|
// Print to server console
|
||||||
ALERT(at_logged, "%s", string);
|
ALERT(at_logged, "%s", string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *UTIL_VarArgs(char *format, ...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
static char string[1024];
|
||||||
|
|
||||||
|
va_start(argptr, format);
|
||||||
|
vsprintf(string, format, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UTIL_ServerPrintf(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
// Check is null, test the demo started before than searches pointer to refs
|
||||||
|
if (&g_engfuncs == nullptr || g_engfuncs.pfnServerPrint == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static char string[1024];
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vsnprintf(string, sizeof(string), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (strlen(string) < sizeof(string) - 2)
|
||||||
|
strcat(string, "\n");
|
||||||
|
else
|
||||||
|
string[strlen(string) - 1] = '\n';
|
||||||
|
|
||||||
|
SERVER_PRINT(string);
|
||||||
|
}
|
||||||
|
@ -59,7 +59,7 @@ int VoiceCodec_Frame::Compress(const char *pUncompressedBytes, int nSamples, cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store the remaining samples.
|
// Store the remaining samples.
|
||||||
int nNewSamples = _min(nSamples, _min(m_nRawSamples - m_nEncodeBufferSamples, m_nRawSamples));
|
int nNewSamples = min(nSamples, min(m_nRawSamples - m_nEncodeBufferSamples, m_nRawSamples));
|
||||||
if (nNewSamples) {
|
if (nNewSamples) {
|
||||||
memcpy(&m_EncodeBuffer[m_nEncodeBufferSamples], &pUncompressed[nSamples - nNewSamples], nNewSamples * BYTES_PER_SAMPLE);
|
memcpy(&m_EncodeBuffer[m_nEncodeBufferSamples], &pUncompressed[nSamples - nNewSamples], nNewSamples * BYTES_PER_SAMPLE);
|
||||||
m_nEncodeBufferSamples += nNewSamples;
|
m_nEncodeBufferSamples += nNewSamples;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user