"蕃茄超人"在VC下的编译与调试经验
by -zh1110 2007.9.10
蕃茄炸弹超人(I've no
Tomatoes)是一个典型的智力游戏,Linux开源项目多数是由GCC编译的,它也由GCC开发,其用到的开发库有:SDL,SDL_Image、OpenGL,FMOD
我现在讲述将其移植到VC6下的编译过程:
安装SDL引擎:
首先首先必须下载SDL函数库,现在SDL的最高版本是1.2.
到官方网站http://www.libsdl.org
,然后你会在网页的左下脚发现一个叫下载(Download)的栏目,点击

将我们刚才解压后lib下的SDL.lib,SDLmain.lib拷贝到一个新的目录:D:\GAMEDEV\lib.
或VC6所在的lib子目录下:C:Program FilesMicrosoft Visual StudioVC98Lib
然后建立一个新文件夹,D:\GAMEDEV\include\SDL,解压的目录include中的文件拷贝到SDL目录中,或VC6的include目录
如果用DEV C++还要将SDL文件中子目录bin里的全部文件拷贝到DEV
C++的bin目录中,地址应该在c:dev-cppbin
安装SDL扩展函数库SDL image(读取PNG文件)
到下面的地址下载:
http://www.libsdl.org/projects/SDL_image/

然后按上面类似进行操作.
声音库:
到FMOD的网站下载开发包
http://www.fmod.org/index.php/download

将解压后的fmod.h,fmoddyn.h等头文件放到include目录
如果是VC++则fmodvc.lib放到lib目录,
如果是DEV C++则libfmod.a放到DEV C++的lib目录下
到炸弹超人主页下载执行文件和源代码
http://tomatoes.sourceforge.net/
http://sourceforge.net/project/showfiles.php?group_id=110031

选择一个下载速度较快的服务器。

将蕃茄炸弹超人运行文件和源代码解压到D:\GAMEDEV\tomatoes
注意保持开发包的版本与运行库版本一致
将运行库SDL.dll,SDL_image.dll,libpng12-0.dll,fmod.dll文件拷贝到
程序目录和WINDOWS目录。
右键Adds File To
Folder 将tomatoes所有源代码(*.C ,*.H)加入工程:

打开VC6,打开”file”->Projects选项,建立一个空白的Win32
CONSOLE 项目,目录就是D:\GAMEDEV\tomatoes:
下面我们对工程设置:
在VC6主面板中选择“Project”->”Setting”选项。在C/C++表,在“Category"中设置成"Code
Generation",在"Use run-time library"下设置成multithreaded dll。

选择“Link”表,在Object/Library
modules添加静态库
fmodvc.lib
SDL.lib SDLmain.lib SDL_image.lib opengl32.lib glu32.lib glaux.lib

Tools-Options 添加头文件,静态库文件
的查找目录,否则VC6提示无法找到文件:

由于VC对 ANSI C++ Standard 支持很低,所以对源文件做许多的修改才可以正确编译.
现在编译,出现多处错误:
|
错误提示1:
config.cpp(98) error C2065: 'CONFIG_DIR' : undeclared identifier
找到原句:
return (CONFIG_DIR "config.cfg");//返回配置文件的目录
CONFIG_DIR 就是宏定义的字符串,因为C++有一种很少用的字符串定义写法,在串常量很长时可以这样初始化:
char buff[] = "line1""line2";
等价于:
char buff[] = "line1line2";
打开makefile,查找到定义,将它们手动加到config.h的宏定义中.

|
|
错误提示2:
vect.h(103) : fatal error C1001: INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 1786)
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
找到原句:
friend VECT operator + (const VECT &v) {
return v;
}
friend VECT operator - (const VECT &v) {
return VECT(-v.x, -v.y, -v.z);
}
friend VECT operator + (const VECT &v1, const VECT &v2) {
return VECT(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}
friend VECT operator - (const VECT &v1, const VECT &v2) {
return VECT(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
}
friend VECT operator * (const VECT &v, float s) {
return VECT(v.x * s, v.y * s, v.z * s);
}
friend VECT operator * (float s, const VECT &v) {
return VECT(v.x * s, v.y * s, v.z * s);
}
friend VECT operator / (const VECT &v, float s) {
return VECT(v.x / s, v.y / s, v.z / s);
}
因为VC6对于+,-,*的运算符重载,如果是定义在类内部的话,只能
带一个函数参数.
修改这些函数,移至VECT类外部,并内联:
class VECT {
......
};
inline VECT operator + (const VECT &v) {
return v;
}
inline VECT operator - (const VECT &v) {
return VECT(-v.x, -v.y, -v.z);
}
inline VECT operator + (const VECT &v1, const VECT &v2) {
return VECT(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}
inline VECT operator - (const VECT &v1, const VECT &v2) {
return VECT(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
}
inline VECT operator * (const VECT &v, float s) {
return VECT(v.x * s, v.y * s, v.z * s);
}
inline VECT operator * (float s, const VECT &v) {
return VECT(v.x * s, v.y * s, v.z * s);
}
inline VECT operator / (const VECT &v, float s) {
return VECT(v.x / s, v.y / s, v.z / s);
}
|
|
错误提示3:
effects.cpp(169) : error C2374: 'f' : redefinition; multiple
initialization
see declaration of 'f'
找到原句:
for(int f=1; f < points-1; f++) {
......
}
......
for(int f=0; f<points; f++) {
......
}
因为对于for循环,ANSI
C++规定f变量的作用域仅在for内部 ,VC6编译为for外层为f变量的作用域,所以出现重两个f重定义的错误.VC.NET可通过开关控制.
修改为:
int f;
for( f=1; f < points-1; f++) {
......
}
......
for( f=0; f<points; f++) {
......
}
|
|
错误提示4:
menu.h(66) : error C2955: 'list' : use of class template
requires template argument list
c:\program files\microsoft visual studio\vc98\include\list(415) : see
declaration of 'list'
找到原句:
void draw_menu(int menu_id, int menu_item, int place, float fade,
HISCORE_LIST *list) {
if(place != -1 && list != NULL)
list->draw(place, 1.0f);
因为参数HISCORE_LIST *list与STL::list名字相同导致冲突.
修改为:
void draw_menu(int menu_id, int menu_item, int place, float fade,
HISCORE_LIST *list1) {
if(place != -1 && list1 != NULL)
list1->draw(place, 1.0f);
|
|
错误提示5:
soundmusic.cpp(35) : fatal error C1083: Cannot open include
file: 'dirent.h': No such file or directory
dirent.h是Linux下目录查找
函数,VC6不包含,将其及search_music()屏蔽即可.
|
|
错误提示6:
texture.cpp(111) : error C2143: syntax error : missing ';'
before '['
texture.cpp(111) : error C2143: syntax error : missing ';' before '['
找到原句:
Uint8 *line = new (Uint8)[img->w*img->format->BytesPerPixel];
因为
new内存申请,VC6不支持带有括号,它认为这是两句:
Uint8 *line = new (Uint8);
[img->w*img->format->BytesPerPixel];
修改
Uint8 *line = new Uint8[img->w*img->format->BytesPerPixel];
修改后问题解除
|
|
错误提示7:
mymath.cpp(52) : error C2065: 'M_PI' : undeclared identifier
这是作者将M_PI屏蔽了,mymath.h恢复既可:
//PI....
#ifndef M_PI
#define M_PI 3.1415926536f
#endif
|
如果要稳定的编译推崇使用DEV C++,这款IDE所使用的编译程序就是 GCC的Win32版本 Mingw32。下载一个Dev-CPP的安装程序http://www.bloodshed.net/dev/devcpp.html
最新版本应该是Dev-Cpp
4.9.9地址是
http://umn.dl.sourceforge.net/sourceforge/dev-cpp/devcpp4990setup.exe
Dev-C的开发环境:

连接静态库设置(参考makefile)

编译成功后截图:

最后可以随意修改调试程序了.
1.修改宝物的数量:
在
levels.cpp 128行:
// Set the bonus system
for(int f=0; f<NUM_ICONS; f++)
icon_menu.count[f] = 300; //修改此行
next_bonus[BONUS_RED] = RED_POWER_TRAP;
2.释放资源包中的图片:
//texture.cpp Ln96:
FILE *fin = pakfile.open_file(file);
pakfile.extract_file(file);
//加入此行
......
总结:经过一定修改使GUN项目能够在VC6下编译,有利我以后的调试. |