分享
 
 
 

quake2源码分析(一)

王朝delphi·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

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 didn't 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脚本

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

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有