欢迎光临
我们一直在努力

quake2源码分析(一)_delphi教程

建站超值云服务器,限时71元/月

 

quake2源码分析(一)



我希望通过quake2的源码分析来理解这个优秀引擎的动作方式。
由于我比较熟悉delphi的代码组织方式,故从http://www.sourceforge.net/quake2delphi/下载了quake2的delphi代码来进行分析。
说明:为了描述的简单化,我没有对细节方面进行描述。


下面让我们进入正题:
起始点:
sys_win: WinMain 这是我们非常熟悉的windows入点


  Qcommon_Init  //qcommon是通用模块,进行通用模块的初始化,这个步骤处理的东西相当多,下一步会详细讲解
  while(true)
   Qcommon_Frame(time) //绘制每一帧


简单地说WinMain要处理的主要就是这两步操作



下面让我们分析一下初始化操作:
 Qcommon_Init的内容


//一 初始化z_chain
    z_chain.prev := @z_chain;
    z_chain.next := z_chain.prev;
//二 初始化参数
    COM_InitArgv(argc, argv);
//三 初始化交换算法及命令行缓冲区
    Swap_Init;
    Cbuf_Init;
//四 命令解释器的初始化
    Cmd_Init;
//五 变量操作的初始化
    Cvar_Init;
//六 键盘映射表初始化
    Key_Init;


//七 初始化命令行,然后初始化文件系统
    Cbuf_AddEarlyCommands(False);
    Cbuf_Execute;


    FS_InitFilesystem;
//八 运行脚本
    Cbuf_AddText(exec default.cfg#10);
    Cbuf_AddText(exec config.cfg#10);


    Cbuf_AddEarlyCommands(True);//添加命令行并将参数清空
    Cbuf_Execute;
//九 初始化变量
    Cmd_AddCommand(z_stats, Z_Stats_f);
    Cmd_AddCommand(error, Com_Error_f);


    host_speeds := Cvar_Get(host_speeds, 0, 0);
    log_stats := Cvar_Get(log_stats, 0, 0);
    developer := Cvar_Get(developer, 0, 0);
    timescale := Cvar_Get(timescale, 1, 0);
    fixedtime := Cvar_Get(fixedtime, 0, 0);
    logfile_active := Cvar_Get(logfile, 0, 0);
    showtrace := Cvar_Get(showtrace, 0, 0);
{$IFDEF DEDICATED_ONLY}
    dedicated := Cvar_Get(dedicated, 1, CVAR_NOSET);
{$ELSE}
    dedicated := Cvar_Get(dedicated, 0, CVAR_NOSET);
{$ENDIF}
//十 设置版本
    s := va(%4.2f %s %s %s, [VERSION, CPUSTRING, __DATE__, BUILDSTRING]);
    Cvar_Get(version, s, CVAR_SERVERINFO or CVAR_NOSET);


    if (dedicated.value <> 0) then
      Cmd_AddCommand(quit, Com_Quit);
//十一:初始化系统(控制台)
    Sys_Init;
//十二:初始化网络 及 端口
    NET_Init;
    Netchan_Init;
//十三 初始化服务端
    SV_Init;
//十四 初始化客户端
    CL_Init;


//十五:如果用户没有输入+命令,而且没有要显示“献给”标志,则显示演示程序
  // add + commands from command line
    if not Cbuf_AddLateCommands then
    begin                               // if the user didnt give any commands, run default action
      if (dedicated.value = 0) then
        Cbuf_AddText(d1#10)
      else
        Cbuf_AddText(dedicated_start#10);
      Cbuf_Execute;
    end
    else
    begin                               // the user asked for something explicit
      // so drop the loading plaque
      SCR_EndLoadingPlaque;
    end;
十六  结束
    Com_Printf(====== Quake2 Initialized ======#10#10, []);


 


接下来对qcommon_init的十六步操作进一步分析


一:初始化z_chain
这就引出了对z_chain的理解,z_chain是quake独创的一种数据链表,用以管理分配的内存空间,以保证临时申请的内存能正确地释放。
每一次内存分配请求会调用common的z_malloc来分配,z_malloc调用Z_TagMalloc来分配带标志的内存空间。
我们来看一下z_chain的类型zhead_t的定义
  zhead_s = record
    prev, next: zhead_p;//典型的链表
    magic: SmallInt; //一个标志位,保留const Z_MAGIC = $1D1D;
    tag: SmallInt;      // 用以成批释放,看来类似于gc的概念
    size: Integer; //所分配的内存块的大小(包括zhead_s的大小)
  end;
  zhead_t = zhead_s;
二 初始化参数
 将命令行数据存入 com_argc_ 及com_argv_[]


三 初始化交换算法及命令行缓冲区
 为了适应不同的cpu结构,在程序中判断是否大印第安格式还是小印第安格式,我的p4 cpu上是小印第安格式。
 给命令行缓冲区分配内存



四 命令解释器的初始化
初始化命令解释器。quake有一个很独特的模式,就是采用的是命令行配合全局变量驱动方式。这让我想起了古老的dos操作系统。
这种方式的优点是模块之间的耦合度可以很低。也很容易配置。
这一步中添加了以下几条默认命令
cmdlist:列出所有可用的命令
exec:运行脚本
echo: 显示文本
alias 显示别名
wait  等待



五 变量操作的初始化
添加了以下用于操作变量的命令
set  设置变量
cvarlist 列出变量



六 键盘映射表初始化
定义了默认的键盘映射表
添加了用于操作键盘映射表的命令
bind 将一个键绑定到一个字符上
unbind 取消一个键的绑定
unbindall 取消所有键的绑定
bindlist  显示绑定列表



七 初始化命令行,然后初始化文件系统
将命令行参数传入,设置好初始化文件系统所需的变量,然后初始化文件系统


八 运行脚本
   运行default.cfg 
   运行config.cfg  
   用命令行传入的参数覆盖现有变量,也就是说命令行传入的参数有较高的优先级


九 初始化变量
   添加命令:
     z_stats: 显示分配的内存大小及块数
     error:抛出一个异常,估计用于测试异常


    添加以下变量: 
    host_speeds 主机程度
    log_stats   日志状态
    developer   开发?
    timescale   时间刻度
    fixedtime   固定时间?
    logfile_active 日志是否活动
    showtrace  是否显示跟踪信息
{$IFDEF DEDICATED_ONLY}  是否是献词版本
    dedicated := Cvar_Get(dedicated, 1, CVAR_NOSET);
{$ELSE}
    dedicated := Cvar_Get(dedicated, 0, CVAR_NOSET);
{$ENDIF}
十 设置版本
   设置软件版本变量
十一:初始化系统(控制台)
   这步操作是为了能像dos窗口一下输入命令


十二:初始化网络 及 端口
 这里初始化端口有一个小技巧,采用了毫秒的最后四位作为端口,不过我没有看到端口冲突的解决方法。大概因为这个概率很小的原因吧。


十三 初始化服务端
添加了服务端要用到的命令及变量


十四 初始化客户端
初始化控制台
初始化渲染模块vid_dll
初始化声音模块
初始化视图用的命令
初始化菜单
初始化屏幕
初始化cd声音
初始化本地操作命令
初始化 input
运行autoexec.cfg脚本



十五:如果用户没有输入+命令,而且没有要显示“献给”标志,则显示演示程序


至此,第一阶段分析告一段落。

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » quake2源码分析(一)_delphi教程
分享到: 更多 (0)