📄 common.pas
字号:
{----------------------------------------------------------------------------}
{ }
{ File(s): qcommon.h (part), Common.c }
{ Content: Quake2\QCommon\ common routines }
{ }
{ Initial conversion by : Clootie (Alexey Barkovoy) - clootie@reactor.ru }
{ Initial conversion on : 19-Jan-2002 }
{ }
{ This File contains part of convertion of Quake2 source to ObjectPascal. }
{ More information about this project can be found at: }
{ http://www.sulaco.co.za/quake2/ }
{ }
{ Copyright (C) 1997-2001 Id Software, Inc. }
{ }
{ 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. }
{ }
{----------------------------------------------------------------------------}
{ 1) 25-Feb-2002 - Clootie (clootie@reactor.ru) }
{ Some clean up of external dependencies. }
{ 3) 03-Mar-2002 - Clootie (clootie@reactor.ru) }
{ Compatibility with new g_local. }
{ }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on: }
{ 1) q_shared.pas }
{ }
{----------------------------------------------------------------------------}
{ * TODO: }
{ 1) Clootie: Resolve other unit dependencies }
{ }
{----------------------------------------------------------------------------}
{.$DEFINE PARANOID} //Clootie: just to debug
// qcommon.h -- definitions common between client and server, but not game.dll
{$Include ..\JEDI.inc}
unit Common;
interface
uses
SysUtils, q_shared, g_local, CVar{$IFNDEF COMPILER6_UP}, Windows{$ENDIF};
const
VERSION = 3.21;
//Clootie: This is substitute for C predefined macro
__DATE__ = '01 Feb 2002';
BASEDIRNAME = 'baseq2';
{$IFDEF WIN32}
const
{$IFDEF NDEBUG}
BUILDSTRING = 'Win32 RELEASE';
{$ELSE}
BUILDSTRING = 'Win32 DEBUG';
{$ENDIF}
const
CPUSTRING = 'i386';
{$ENDIF}
{$IFDEF LINUX}
const
BUILDSTRING = 'Linux';
const
CPUSTRING = 'i386';
{$ENDIF}
//============================================================================
type
tcdeclproc = procedure; cdecl;
sizebuf_p = ^sizebuf_t;
sizebuf_s = record
allowoverflow : qboolean; // if false, do a Com_Error
overflowed : qboolean; // set to true if the buffer size failed
data : PByteArray;
maxsize : Integer;
cursize : Integer;
readcount : Integer;
end;
sizebuf_t = sizebuf_s;
procedure SZ_Init(var buf: sizebuf_t; data: PByte; length: Integer);
procedure SZ_Clear(var buf: sizebuf_t);
function SZ_GetSpace(var buf: sizebuf_t; length: Integer): Pointer;
procedure SZ_Write(var buf: sizebuf_t; data: Pointer; length: Integer);
procedure SZ_Print(var buf: sizebuf_t; data: PChar); // strcats onto the sizebuf
//============================================================================
procedure MSG_WriteChar(var sb: sizebuf_t; c: ShortInt);
procedure MSG_WriteByte(var sb: sizebuf_t; c: Integer);
procedure MSG_WriteShort(var sb: sizebuf_t; c: Integer);
procedure MSG_WriteLong(var sb: sizebuf_t; c: Integer);
procedure MSG_WriteFloat(var sb: sizebuf_t; f: Single);
procedure MSG_WriteString(var sb: sizebuf_t; s: PChar);
procedure MSG_WriteCoord(var sb: sizebuf_t; f: Single);
procedure MSG_WritePos(var sb: sizebuf_t; const pos: vec3_t);
procedure MSG_WriteAngle(var sb: sizebuf_t; f: Single);
procedure MSG_WriteAngle16(var sb: sizebuf_t; f: Single);
procedure MSG_WriteDeltaUsercmd(var buf: sizebuf_t; const from: usercmd_s; const cmd: usercmd_s);
procedure MSG_WriteDeltaEntity(const from, to_: entity_state_s; var msg: sizebuf_t; force, newentity: qboolean);
procedure MSG_WriteDir(var sb: sizebuf_t; dir: vec3_p);
procedure MSG_BeginReading(var sb: sizebuf_t);
function MSG_ReadChar(var msg_read: sizebuf_t): ShortInt;
function MSG_ReadByte(var msg_read: sizebuf_t): Integer;
function MSG_ReadShort(var msg_read: sizebuf_t): Integer;
function MSG_ReadLong(var msg_read: sizebuf_t): Integer;
function MSG_ReadFloat(var msg_read: sizebuf_t): Single;
function MSG_ReadString(var msg_read: sizebuf_t): PChar;
function MSG_ReadStringLine(var msg_read: sizebuf_t): PChar;
function MSG_ReadCoord(var msg_read: sizebuf_t): Single;
procedure MSG_ReadPos(var msg_read: sizebuf_t; var pos: vec3_t);
function MSG_ReadAngle(var msg_read: sizebuf_t): Single;
function MSG_ReadAngle16(var msg_read: sizebuf_t): Single;
procedure MSG_ReadDeltaUsercmd(var msg_read: sizebuf_t; const from: usercmd_t; var move: usercmd_t);
procedure MSG_ReadDir(var sb: sizebuf_t; var dir: vec3_t);
procedure MSG_ReadData(var msg_read: sizebuf_t; data: Pointer; len: Integer);
const
MAX_NUM_ARGVS = 50;
type
//Clootie: Object Pascal introduced types
PComArgvArray = ^TComArgvArray;
TComArgvArray = array[0..MAX_NUM_ARGVS] of PChar;
function COM_Argc: Integer;
function COM_Argv(arg: Integer): PChar; // range and null checked
procedure COM_ClearArgv(arg: Integer);
function COM_CheckParm(parm: PChar): Integer;
procedure COM_AddParm(parm: PChar);
// procedure COM_Init; //Clootie: Not used in source base...
procedure COM_InitArgv(argc: Integer; argv: PComArgvArray);
function CopyString(in_: PChar): PChar;
//============================================================================
procedure Info_Print(s: PChar);
(*
==============================================================
PROTOCOL
==============================================================
*)
// protocol.h -- communications protocols
const
PROTOCOL_VERSION = 34;
//=========================================
PORT_MASTER = 27900;
PORT_CLIENT = 27901;
PORT_SERVER = 27910;
//=========================================
UPDATE_BACKUP = 16; // copies of entity_state_t to keep buffered
// must be power of two
UPDATE_MASK = (UPDATE_BACKUP-1);
//==================
// the svc_strings[] array in cl_parse.c should mirror this
//==================
//
// server to client
//
type
svc_ops_e = (
svc_bad,
// these ops are known to the game dll
svc_muzzleflash,
svc_muzzleflash2,
svc_temp_entity,
svc_layout,
svc_inventory,
// the rest are private to the client and server
svc_nop,
svc_disconnect,
svc_reconnect,
svc_sound, // <see code>
svc_print, // [byte] id [string] null terminated string
svc_stufftext, // [string] stuffed into client's console buffer, should be \n(#10) terminated
svc_serverdata, // [long] protocol ...
svc_configstring, // [short] [string]
svc_spawnbaseline,
svc_centerprint, // [string] to put in center of the screen
svc_download, // [short] size [size bytes]
svc_playerinfo, // variable
svc_packetentities, // [...]
svc_deltapacketentities, // [...]
svc_frame
);
//==============================================
//
// client to server
//
clc_ops_e = (
clc_bad,
clc_nop,
clc_move, // [[usercmd_t]
clc_userinfo, // [[userinfo string]
clc_stringcmd // [string] message
);
//==============================================
// plyer_state_t communication
const
PS_M_TYPE = (1 shl 0);
PS_M_ORIGIN = (1 shl 1);
PS_M_VELOCITY = (1 shl 2);
PS_M_TIME = (1 shl 3);
PS_M_FLAGS = (1 shl 4);
PS_M_GRAVITY = (1 shl 5);
PS_M_DELTA_ANGLES = (1 shl 6);
PS_VIEWOFFSET = (1 shl 7);
PS_VIEWANGLES = (1 shl 8);
PS_KICKANGLES = (1 shl 9);
PS_BLEND = (1 shl 10);
PS_FOV = (1 shl 11);
PS_WEAPONINDEX = (1 shl 12);
PS_WEAPONFRAME = (1 shl 13);
PS_RDFLAGS = (1 shl 14);
//==============================================
// user_cmd_t communication
// ms and light always sent, the others are optional
CM_ANGLE1 = (1 shl 0);
CM_ANGLE2 = (1 shl 1);
CM_ANGLE3 = (1 shl 2);
CM_FORWARD = (1 shl 3);
CM_SIDE = (1 shl 4);
CM_UP = (1 shl 5);
CM_BUTTONS = (1 shl 6);
CM_IMPULSE = (1 shl 7);
//==============================================
// a sound without an ent or pos will be a local only sound
SND_VOLUME = (1 shl 0); // a byte
SND_ATTENUATION = (1 shl 1); // a byte
SND_POS = (1 shl 2); // three coordinates
SND_ENT = (1 shl 3); // a short 0-2: channel, 3-12: entity
SND_OFFSET = (1 shl 4); // a byte, msec offset from frame start
DEFAULT_SOUND_PACKET_VOLUME = 1.0;
DEFAULT_SOUND_PACKET_ATTENUATION = 1.0;
//==============================================
// entity_state_t communication
// try to pack the common update flags into the first byte
U_ORIGIN1 = (1 shl 0);
U_ORIGIN2 = (1 shl 1);
U_ANGLE2 = (1 shl 2);
U_ANGLE3 = (1 shl 3);
U_FRAME8 = (1 shl 4); // frame is a byte
U_EVENT = (1 shl 5);
U_REMOVE = (1 shl 6); // REMOVE this entity, don't add it
U_MOREBITS1 = (1 shl 7); // read one additional byte
// second byte
U_NUMBER16 = (1 shl 8); // NUMBER8 is implicit if not set
U_ORIGIN3 = (1 shl 9);
U_ANGLE1 = (1 shl 10);
U_MODEL = (1 shl 11);
U_RENDERFX8 = (1 shl 12); // fullbright, etc
U_EFFECTS8 = (1 shl 14); // autorotate, trails, etc
U_MOREBITS2 = (1 shl 15); // read one additional byte
// third byte
U_SKIN8 = (1 shl 16);
U_FRAME16 = (1 shl 17); // frame is a short
U_RENDERFX16 = (1 shl 18); // 8 + 16 = 32
U_EFFECTS16 = (1 shl 19); // 8 + 16 = 32
U_MODEL2 = (1 shl 20); // weapons, flags, etc
U_MODEL3 = (1 shl 21);
U_MODEL4 = (1 shl 22);
U_MOREBITS3 = (1 shl 23); // read one additional byte
// fourth byte
U_OLDORIGIN = (1 shl 24); // FIXME: get rid of this
U_SKIN16 = (1 shl 25);
U_SOUND = (1 shl 26);
U_SOLID = (1 shl 27);
(*
==============================================================
NET
==============================================================
*)
// net.h -- quake's interface to the networking layer
const
PORT_ANY = -1;
MAX_MSGLEN = 1400; // max length of a message
PACKET_HEADER = 10; // two ints and a short
type
netadrtype_t = (NA_LOOPBACK, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX);
netsrc_t = (NS_CLIENT, NS_SERVER);
netadr_p = ^netadr_t;
netadr_t = record
type_ : netadrtype_t;
ip : array [0..3] of Byte;
ipx : array [0..9] of Byte;
port: Word;
end;
//============================================================================
const
OLD_AVG = 0.99; // total = oldtotal*OLD_AVG + new*(1-OLD_AVG)
MAX_LATENT = 32;
type
netchan_p = ^netchan_t;
netchan_t = record
fatal_error: qboolean;
sock: netsrc_t;
dropped: Integer; // between last packet and previous
last_received: Integer; // for timeouts
last_sent: Integer; // for retransmits
remote_address: netadr_t;
qport: Integer; // qport value to write when transmitting
// sequencing variables
incoming_sequence: Integer;
incoming_acknowledged: Integer;
incoming_reliable_acknowledged: Integer; // single bit
incoming_reliable_sequence: Integer; // single bit, maintained local
outgoing_sequence: Integer;
reliable_sequence: Integer; // single bit
last_reliable_sequence: Integer; // sequence number of last send
// reliable staging and holding areas
message: sizebuf_t; // writing buffer to send to server
message_buf: array [0..MAX_MSGLEN-16-1] of Byte; // leave space for header
// message is copied to this buffer when it is first transfered
reliable_length: Integer;
reliable_buf: array[0..MAX_MSGLEN-16-1] of Byte; // unacked reliable message
end;
(*
==============================================================
MISC
==============================================================
*)
const
ERR_FATAL = 0; // exit the entire game with a popup window
ERR_DROP = 1; // print to console and disconnect from game
ERR_QUIT = 2; // not an error, just a normal exit
EXEC_NOW = 0; // don't return until completed
EXEC_INSERT = 1; // insert at current position, but don't run yet
EXEC_APPEND = 2; // add to end of the command buffer
PRINT_ALL = 0;
PRINT_DEVELOPER = 1; // only print when "developer 1"
type
rd_flush_proc = procedure (target: Integer; buffer: PChar);
procedure Com_BeginRedirect(target: Integer; buffer: PChar; buffersize: Integer; flush: rd_flush_proc);
procedure Com_EndRedirect;
procedure Com_Printf(fmt: PChar; args: array of const); overload;
procedure Com_DPrintf(fmt: PChar; args: array of const); overload;
procedure Com_Error(code: Integer; fmt: PChar; args: array of const); overload;
procedure Com_Printf(fmt: PChar); overload;
procedure Com_DPrintf(fmt: PChar); overload;
procedure Com_Error(code: Integer; fmt: PChar); overload;
procedure Com_Quit; cdecl;
function Com_ServerState: Integer; // this should have just been a cvar...
procedure Com_SetServerState(state: Integer);
// function Com_BlockChecksum(buffer: Pointer; length: Integer): Cardinal; // in md4.pas
function COM_BlockSequenceCRCByte(base: PByte; length, sequence: Integer): Byte;
function rand: Integer; // 0 to $7FFF
function frand: Single; // 0 to 1
function crand: Single; // -1 to 1
function fmod(x, y: Single): Single;
var
developer : cvar_p;
dedicated : cvar_p;
host_speeds : cvar_p;
log_stats : cvar_p;
log_stats_file: integer;
// host_speeds times
var
time_before_game : Integer;
time_after_game : Integer;
time_before_ref : Integer;
time_after_ref : Integer;
procedure Z_Free(ptr: Pointer);cdecl;
function Z_Malloc(size: Integer): Pointer; cdecl; // returns 0 filled memory
function Z_TagMalloc(size: Integer; tag: Integer): Pointer; cdecl;
procedure Z_FreeTags(tag: Integer);cdecl;
procedure Qcommon_Init(argc: Integer; argv: PComArgvArray);
procedure Qcommon_Frame(msec: Integer);
procedure Qcommon_Shutdown;
const
NUMVERTEXNORMALS = 162;
var
bytedirs: array [0..NUMVERTEXNORMALS-1] of vec3_t = (
{$Include '..\client\anorms.inc'}
);
//todo: Don't know what to do
(*
// this is in the client code, but can be used for debugging from server
void SCR_DebugGraph (float value, int color); *)
var
//todo: Clootie: do we really need this variable at all
realtime: Integer;
implementation
{$I-} // Do not raise exceptions on I/O errors (need to check IOResult var)
uses
Files, crc, cmd, net_chan, cl_main, sv_main, cl_scrn, CModel
{$IFDEF WIN32}
, net_Wins, q_shwin, sys_win
{$ENDIF}
{$IFDEF LINUX}
, net_udp
{$ENDIF}
, Console, Keys, CPas;
// common.c -- misc functions used in client and server
const
MAXPRINTMSG = 4096;
// MAX_NUM_ARGVS = 50; //Clootie: Declared in interface part
var
com_argc_: Integer;
com_argv_: TComArgvArray; // array[0..MAX_NUM_ARGVS] of PChar;
//Clootie: "abortframe" is used in C for exception alike handling with
// "setjmp" and "longjmp" functions -> is replaced in ObjectPascal by exceptions
// abortframe: jmp_buf; // an ERR_DROP occured, exit the entire frame
type
ELongJump = Exception;
var
timescale : cvar_p;
fixedtime : cvar_p;
logfile_active: cvar_p; // 1 = buffer log, 2 = flush after each print
showtrace : cvar_p;
logfile : integer;
server_state : Integer;
(*
============================================================================
CLIENT / SERVER interactions
============================================================================
*)
var
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -