心血來潮归敬,突然想看Quake 2的代碼,折騰一下硕勿,終于在VS 2015編譯成功哨毁,項(xiàng)目在oraoto/quake2-vs2015。
這篇文章記錄一下實(shí)現(xiàn)的過程源武。
下載Quake 2源碼
Quake 2代碼已經(jīng)開源扼褪,可以在Github或id Software的FTP下載想幻。我從FTP下的,所以沒fork Github上的倉庫话浇。
升級(jí)項(xiàng)目
解壓后找到quake2.dsw
脏毯,這是VC++ 6的項(xiàng)目,用VS 2015打開會(huì)提示升級(jí)項(xiàng)目:
確認(rèn)升級(jí)即可幔崖。
修復(fù)編譯錯(cuò)誤
先嘗試在Debug模式下編譯食店,會(huì)有很多錯(cuò)誤,這些錯(cuò)誤都是升級(jí)項(xiàng)目過程中產(chǎn)生的赏寇。
- '/ZI' and '/Gy-' command-line options are incompatible
每個(gè)項(xiàng)目都打開Enable function-level Linking
即可叛买。 - LNK1181 cannot open input file '...\debug\.obj'
編譯ref_soft
軟件渲染器時(shí)會(huì)出現(xiàn)這個(gè)錯(cuò)誤,沒有正確輸出匯編的編譯結(jié)果蹋订,要打開ref_soft.vcxproj
手工修改
找到CustomBuild
率挣,里面有些這樣的項(xiàng):
把<Outputs Condition="...">$(OUTDIR)\$(InputName).obj;%(Outputs)</Outputs>
$(InputName)
改成%(Filename)
就可以了 - LNK 2026 module unsafe for SAFESEH image
把ref_soft
項(xiàng)目的Linker->Advanced->Image Has Safe Exception Handlers
改成No即可。 - 關(guān)閉DEP
把每個(gè)項(xiàng)目的Linker->Advanced->Data Execuation Prevention
關(guān)掉露戒。
經(jīng)過這些修改椒功,就能正常跑起軟件渲染器了。
支持OpenGL渲染器
不管是Steam上賣的Quake 2和上面編譯的都跑不了OpenGL智什,調(diào)試發(fā)現(xiàn)是在打印日志的時(shí)候出錯(cuò)动漾。
在初始化OpenGL的時(shí)候有這么兩句(在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擴(kuò)展,然后打印≤В現(xiàn)在的顯卡都支持很多擴(kuò)展旱眯,我的有300多個(gè),整個(gè)字符串就超過了打印函數(shù)定義的4096字節(jié)证九,就溢出了删豺。
所以把vid_dll.c
里的MAXPRINTMSG
和qcommon/common.c
的MAXPRINTMSG
改到足夠大就可以了。也可以去掉打印語句愧怜,更簡單呀页。
重新編譯后就可以用OpenGL了:
回顧
做了很多第一次做的事,有時(shí)只是憑感覺去嘗試拥坛。
例如改DEP設(shè)置蓬蝶,是因?yàn)榭吹藉e(cuò)誤信息:Access violation **executing** location
,我猜是程序去執(zhí)行了非代碼的內(nèi)存猜惋,去看觸發(fā)的代碼是這樣的:
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著摔,于是試一試缓窜,發(fā)現(xiàn)可以。
再說OpenGL,起初怕有很復(fù)雜的原因?qū)е屡懿涣吮⑾矗徽{(diào)試才發(fā)現(xiàn)居然只是普通的內(nèi)存溢出。
試一試總比直接放棄好卧波。
接下來就要看代碼了时肿,感覺自己水平不夠,好難啊……