Windows11 使用 VS2022 构建 Doom3-BFG 源码的失败记录

克隆原仓库

使用 VS2022 打开原仓库,首先将构建模式切换成 Release,为了构建游戏,我们不需要 Debug 模式

然后将所有项目在属性页把“警告视为错误”改为否,对照 https://github.com/AmbushedRaccoon/Doom3-BFG-Edition-VS-2019 里面的更改修改文件

这个时候剩下的报错应该只剩下缺少一些库文件 DxErr.h, dxsdkver.h, xma2defs.h

这需要下载 DirectX SDK June 2010,下载链接:

https://www.microsoft.com/en-hk/download/details.aspx?id=6812

直接安装会报错,别人的解决方法:

https://www.cnblogs.com/AI-Algorithms/p/3778527.html

要卸载以下两个程序:

Microsoft Visual C++ 2010 x86 Redistributable

Microsoft Visual C++ 2010 x64 Redistributable

即使下载了,Visual Studio 也不会直接找到 SDK 文件夹,我们我们需要手动配置

如果在安装 SDK 的时候没有更改下载位置,那么默认下载位置应该是 C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)

那么我们就要给项目附加目录

工具->选项->项目和解决方案->VC++ Directorise,然后在右方的 show directorise for 选项中选择include files 选项并把 C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include此路径加进一新行中,然后在 reference files 和library files 选项中将 C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x64

然后 DirectX 相关的库文件就能找到了,不会报错

接下来是提示找不到 afxres.h

我去看了 https://github.com/electronicarts/CnC_Remastered_Collection/issues/36

然后我尝试换成 #include 没用

尝试下载

C++ MGF v141 生成工具 (x86 & x64)

适用于 v142 生成工具的 C++ v14.29 (16.11) MFC (x86 和 x64)

都没有用

于是我找到了 https://www.moddb.com/tutorials/how-to-compile-doom-3-with-visual-studio-2010

根据这里写的,要解决这个问题,需要去 https://www.mediafire.com/?szgoccextjhpig3 下载这个包

然后解压到某个地方

比如我解压到 C:\Program Files (x86)\Microsoft Visual Studio

那么将 C:\Program Files (x86)\Microsoft Visual Studio\atlmfc\include 加入 Doom3BFG 项目的包含目录中,就 Ok 了

然后接下来的错误是

严重性	代码	说明	项目	文件	行	禁止显示状态
错误	RC2133	unexpected value in value data	Doom3BFG	E:\DOOM-3-BFG\neo\sys\win32\rc\doom.rc	86	
错误	RC2132	expected VALUE, BLOCK, or END keyword	Doom3BFG	E:\DOOM-3-BFG\neo\sys\win32\rc\doom.rc	86	

我不懂 RCDATA……不知道哪里错了……之后仔细看才发现,这里有个字符串的引号没了

我打开这个文件的时候,提示我,以简体中文编码打开文件,有的字符被 Unicode 符号替换,我觉得可能是这个引号被换掉了……?

    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "CompanyName", "id Software LLC, a ZeniMax Media company"
            VALUE "FileDescription", "DOOM 3: BFG Edition"
            VALUE "FileVersion", "1.0.0.1"
            VALUE "InternalName", "Doom3BFG"
            VALUE "LegalCopyright", "?1993-2012 id Software LLC, a ZeniMax Media company"
            VALUE "OriginalFilename", "Doom3BFG"
            VALUE "ProductName", "DOOM?3: BFG Edition?
            VALUE "ProductVersion", "1.0.0.1"
        END
    END

总之把那个缺少的引号加上,问号应该是识别不了的字符,那我就删掉了,然后就可以运行了

虽然可以运行了,但是 Doom3 窗口会报错 Couldn’t load default.cfg

然后我再看回 https://www.moddb.com/tutorials/how-to-compile-doom-3-with-visual-studio-2010

他说是要把源码目录下的 base 文件夹复制到构建目录中,我试了,复制到构建目录中没有用

于是我根据 Doom3 窗口中的提示,把 base 文件夹复制到了 C:\Users\UserName\Saved Games\id Software\DOOM 3 BFG 中,就可以了

虽然不报 Couldn’t load default.cfg 的错了,但是还有错误

void R_InitOpenGL() {
	...
	
	R_SetNewMode( true );

	glConfig.renderer_string = (const char *)qglGetString( GL_RENDERER );

qglGetString 是一个函数指针,它的地址为 0x0000 0000 所以报错

这就说明 OpenGL 的函数没有成功的初始化。之后我找到了 OpenGL 的函数在哪初始化了,在 R_SetNewMode 里面的 GLimp_Init,但是这首先要 R_SetNewMode 能够设置一个 mode,如果重复三次不能设置 mode 就会退出这个函数,OpenGL 函数就不能初始化了

// DOOM-3-BFG\neo\renderer\RenderSystem_init.cpp
void R_SetNewMode( const bool fullInit ) {
	// try up to three different configurations

	for ( int i = 0 ; i < 3 ; i++ ) {
		...

		if ( r_fullscreen.GetInteger() <= 0 ) {
			...
		} else {
			// get the mode list for this monitor
			idList<vidMode_t> modeList;
			if ( !R_GetModeListForDisplay( r_fullscreen.GetInteger()-1, modeList ) ) {
				idLib::Printf( "r_fullscreen reset from %i to 1 because mode list failed.", r_fullscreen.GetInteger() );
				r_fullscreen.SetInteger( 1 );
				R_GetModeListForDisplay( r_fullscreen.GetInteger()-1, modeList );
			}
			if ( modeList.Num() < 1 ) {
				idLib::Printf( "Going to safe mode because mode list failed." );
				goto safeMode;
			}

在这里,R_GetModeListForDisplay 一直不能返回一个非空的 modeList,导致一直进入 safeMode

我再进到 R_GetModeListForDisplay

// DOOM-3-BFG\neo\sys\win32\win_glimp.cpp
for ( int modeNum = 0 ; ; modeNum++ ) {
	if ( !EnumDisplaySettings( device.DeviceName,modeNum, &devmode ) ) {
		break;
	}

	if ( devmode.dmBitsPerPel != 32 ) {
		continue;
	}
	//if ( ( devmode.dmDisplayFrequency != 60 ) && ( devmode.dmDisplayFrequency != 120 ) ) {
	//	continue;
	//}
	//if ( devmode.dmPelsHeight < 720 ) {
	//	continue;
	//}
	if ( verbose ) {
		common->Printf( "          -------------------\n" );
		common->Printf( "          modeNum             : %i\n", modeNum );
		common->Printf( "          dmPosition.x        : %i\n", devmode.dmPosition.x );
		common->Printf( "          dmPosition.y        : %i\n", devmode.dmPosition.y );
		common->Printf( "          dmBitsPerPel        : %i\n", devmode.dmBitsPerPel );
		common->Printf( "          dmPelsWidth         : %i\n", devmode.dmPelsWidth );
		common->Printf( "          dmPelsHeight        : %i\n", devmode.dmPelsHeight );
		common->Printf( "          dmDisplayFlags      : 0x%x\n", devmode.dmDisplayFlags );
		common->Printf( "          dmDisplayFrequency  : %i\n", devmode.dmDisplayFrequency );
	}
	vidMode_t mode;
	mode.width = devmode.dmPelsWidth;
	mode.height = devmode.dmPelsHeight;
	// mode.displayHz = devmode.dmDisplayFrequency; // why devmode.dmDisplayFrequency = 0?
	mode.displayHz = 144; // hack
	modeList.AddUnique( mode );
}

我发现这里返回的 devmodedmDisplayFrequency, dmPelsHeight不会满足他的检查条件,并且 devmode.dmDisplayFrequency 还会是 0

我不知道是怎么回事……于是手动把那些条件检查注释掉了,然后用我自己的电脑的屏幕刷新率赋值上去

然后我开始可以进入游戏框了……但是还没运行游戏就开始报错 _default material not found

想设个断点看看哪里读取了 default 设置,没想到这个游戏是直接更改设备分辨率的,导致我断点是断了,但是我卡在那个未响应的游戏窗口那里,鼠标直接没了,Alt Tab 出来也切不到其他应用,更别说还没鼠标了

绝了……直接更改设备的设置,真是坏文明

后来开了第二个桌面,进到第二个桌面之后有鼠标了,才能改回分辨率,然后回到第一个桌面结束进程

通过项目内搜索,找到报错位置:

// DOOM-3-BFG\neo\renderer\RenderSystem_init.cpp
void R_InitMaterials() {
	tr.defaultMaterial = declManager->FindMaterial( "_default", false );
	if ( !tr.defaultMaterial ) {
		common->FatalError( "_default material not found" );
	}

这就很奇怪了……难道是我素材文件夹放的不对?

于是我继续看,发现神奇的是,这好像是必定要获得 NULL 的

// DOOM-3-BFG\neo\framework\DeclManager.cpp
const idMaterial *idDeclManagerLocal::FindMaterial( const char *name, bool makeDefault ) {
	return static_cast<const idMaterial *>( FindType( DECL_MATERIAL, name, makeDefault ) );
}

// DOOM-3-BFG\neo\framework\DeclManager.cpp
const idDecl *idDeclManagerLocal::FindType( declType_t type, const char *name, bool makeDefault ) {
	idDeclLocal *decl;

	...

	decl = FindTypeWithoutParsing( type, name, makeDefault );
	if ( !decl ) {
		return NULL;
	}	
	
	...
}
// DOOM-3-BFG\neo\framework\DeclManager.cpp
idDeclLocal *idDeclManagerLocal::FindTypeWithoutParsing( declType_t type, const char *name, bool makeDefault ) {
	...

	if ( !makeDefault ) {
		// int test = makeDefault;
		// common->FatalError("makeDefault: %d", test);

		return NULL;
	}
	
	...
}

这一路看下去就很神奇啊,只要设置了 makeDefault = false 的话,一定会得到一个 NULL 的

我不理解为什么会这么做……

于是我自己改成了 true

void R_InitMaterials() {
	// why set makeDefault = false? When makeDefault = false, it return NULL directly!?
	// tr.defaultMaterial = declManager->FindMaterial( "_default", false );
	tr.defaultMaterial = declManager->FindMaterial("_default", true);

然后是 Could not load default font 的报错

// DOOM-3-BFG\neo\renderer\Font.cpp
idFont::idFont( const char * n ) : name( n ) {
	...
	
	if ( !LoadFont() ) {
		if ( name.Icmp( DEFAULT_FONT ) == 0 ) {
			idLib::FatalError( "Could not load default font \"%s\"", DEFAULT_FONT );
		} else {
			idLib::Warning( "Could not load font %s", n );
			alias = renderSystem->RegisterFont( DEFAULT_FONT );
		}
	}

	...
}
	
// DOOM-3-BFG\neo\renderer\Font.cpp
bool idFont::LoadFont() {
	idStr fontName = va( "newfonts/%s/48.dat", GetName() );
	idFile * fd = fileSystem->OpenFileRead( fontName );
	if ( fd == NULL ) {
		// common->FatalError("bool idFont::LoadFont(): fd == NULL!");
		return false;
	}

	...
}

我搜了一下 C 盘和源码目录,都没有这个 newfonts 文件夹啊……我无语了……

为什么啊……我有点不理解,这种资源缺失的问题,如果确实有的这样的问题的话,别人应该十年前就会提出来的啊……为什么我完全没有看到这样的记录……

假设我把字体这部分注释掉,然后又有 ERROR: Couldn't load script/doom_main.script 的错误

我感觉好像就是我缺了游戏资产

其实一开始我是没有反应的,因为我看到了一些 shader,我还以为这些就够了,emmm,但是我确实没看到贴图什么的,是我大意了

之后看到 https://gamedev.stackexchange.com/questions/22802/how-can-i-build-and-run-doom-3-from-source-in-windows 才知道,我应该去 steam 购买游戏本体

但是等到我买完之后,我还是没有 newfonts 文件夹……还是没有办法运行……

所以我干脆就不搞了……

你可能感兴趣的:(GameEngineDev,游戏引擎)