⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 4 页
字号:
{----------------------------------------------------------------------------}
{                                                                            }
{ 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.                                         }
{                                                                            }
{----------------------------------------------------------------------------}

{.$DEFINE PARANOID}//Clootie: just to debug

// qcommon.h -- definitions common between client and server, but not game.dll
{$IFDEF WIN32}
{$INCLUDE ..\Jedi.inc}
{$ELSE}
{$INCLUDE ../Jedi.inc}
{$ENDIF}

unit Common;

interface

uses
  SysUtils,
  q_shared,
  q_shared_add,
  CVar
{$IFNDEF COMPILER6_UP}
{$IFDEF WIN32}
  ,Windows
{$ENDIF}
{$ENDIF};

const
  VERSION = 3.21;

  //Clootie: This is substitute for C predefined macro
  __DATE__ = '01 Feb 2002';

  BASEDIRNAME = 'baseq2';

{$IFDEF WIN32}
const
{$IFNDEF DEBUG}
  BUILDSTRING = 'Win32 RELEASE';
{$ELSE}
  BUILDSTRING = 'Win32 DEBUG';
{$ENDIF}

const
  CPUSTRING = 'i386';

{$ENDIF}

{$IFDEF LINUX}
const
  BUILDSTRING = 'Linux';

const
  CPUSTRING = 'i386';
{$ENDIF}

  //============================================================================

type
  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_t; const cmd: usercmd_t);
procedure MSG_WriteDeltaEntity(const from, to_: entity_state_t; 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 = (
  {$IFDEF WIN32}
  {$INCLUDE '..\client\anorms.inc'}
  {$ELSE}
  {$INCLUDE '../client/anorms.inc'}
  {$ENDIF}
    );

  //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

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,
  sys_linux,
  q_shlinux
{$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 = 0;

  server_state: Integer;

{*
============================================================================

CLIENT / SERVER interactions

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -