VS2015编译和运行Quake 2

心血来潮,突然想看Quake 2的代码,折腾一下,终于在VS 2015编译成功,项目在oraoto/quake2-vs2015。

这篇文章记录一下实现的过程。

下载Quake 2源码

Quake 2代码已经开源,可以在Github或id Software的FTP下载。我从FTP下的,所以没fork Github上的仓库。

升级项目

解压后找到quake2.dsw,这是VC++ 6的项目,用VS 2015打开会提示升级项目:

VS2015编译和运行Quake 2_第1张图片
升级项目.png

确认升级即可。

修复编译错误

先尝试在Debug模式下编译,会有很多错误,这些错误都是升级项目过程中产生的。

  1. '/ZI' and '/Gy-' command-line options are incompatible
    每个项目都打开Enable function-level Linking即可。
  2. LNK1181 cannot open input file '...\debug\.obj'
    编译ref_soft软件渲染器时会出现这个错误,没有正确输出汇编的编译结果,要打开ref_soft.vcxproj手工修改
    找到CustomBuild,里面有些这样的项:
    $(OUTDIR)\$(InputName).obj;%(Outputs)
    
    $(InputName)改成%(Filename)就可以了
  3. LNK 2026 module unsafe for SAFESEH image
    ref_soft项目的Linker->Advanced->Image Has Safe Exception Handlers改成No即可。
  4. 关闭DEP
    把每个项目的Linker->Advanced->Data Execuation Prevention关掉。

经过这些修改,就能正常跑起软件渲染器了。

支持OpenGL渲染器

不管是Steam上卖的Quake 2和上面编译的都跑不了OpenGL,调试发现是在打印日志的时候出错。

在初始化OpenGL的时候有这么两句(在ref_gl/gl_rmain.c/R_Init):

gl_config.extensions_string = qglGetString (GL_EXTENSIONS);
ri.Con_Printf (PRINT_ALL, "GL_EXTENSIONS: %s\n", gl_config.extensions_string );

就是获取显卡支持的OpenGL扩展,然后打印。现在的显卡都支持很多扩展,我的有300多个,整个字符串就超过了打印函数定义的4096字节,就溢出了。

所以把vid_dll.c里的MAXPRINTMSGqcommon/common.cMAXPRINTMSG改到足够大就可以了。也可以去掉打印语句,更简单。

重新编译后就可以用OpenGL了:

VS2015编译和运行Quake 2_第2张图片
OpenGL下的Quake 2

回顾

做了很多第一次做的事,有时只是凭感觉去尝试。

例如改DEP设置,是因为看到错误信息:Access violation **executing** location,我猜是程序去执行了非代码的内存,去看触发的代码是这样的:

 align 4
 public _R_Surf8Patch
_R_Surf8Patch:
 push ebx

 mov eax,ds:dword ptr[_colormap]
 mov ebx,offset LPatchTable8
 mov ecx,32
LPatchLoop8:
 mov edx,ds:dword ptr[ebx]
 add ebx,4
 mov ds:dword ptr[edx],eax
 dec ecx
 jnz LPatchLoop8

 pop ebx

 ret

居然是汇编,一脸懵逼啊。还好想到ASLR和DEP,于是试一试,发现可以。

再说OpenGL,起初怕有很复杂的原因导致跑不了,一调试才发现居然只是普通的内存溢出。

试一试总比直接放弃好。

接下来就要看代码了,感觉自己水平不够,好难啊……

你可能感兴趣的:(VS2015编译和运行Quake 2)