yksoft1 |
2010-03-03 23:06 |
Visual C++ 和微软的其他开发工具一样有很长的历史,其第一个32位版本早在NT 3.1的1993年就正式出现了。Mini vMac 是我在开放源代码的模拟器中所见过代码最为精炼、简洁的,这也使得它具有相当好的移植性。上次搞到32位版本的VC++ 1.10,于是就准备拿这个Mini vMac来玩玩。 首先使用Mini vMac的源代码镜像,在Mini vMac环境中运行Build,用-e msv -ev 6000参数生成一个适合于Visual C++6.0的完整源码zip文档。 把该zip解压开,打开Visual C++ 1.1,在这个源码所在的目录新建一个工程文件。把源码目录下src子目录下的所有.c和.rc添加到工程中。 由于Visual C++ 1.1环境出现在Windows 95之前,和VC6相比,它具有很多限制: 1.shlobj.h不存在。所有和Explorer相关API和ActiveX相关API都不可用。 2.许多Win32的常数宏定义在自带头文件中不存在。 3.OLE2相关的均不可用。 4.winmm API中的一些参数与VC6有很大差别,比如WAVEFORMATEX结构不能用等等。 5.内联函数定义只有__inline。 6.使用IDE生成的makefile中,rc编译器的路径只包括工程文件所在路径。 7.编译器只支持WinMain为Windows应用程序主函数名。 这里仅仅提到了与Mini vMac相关的一些。因此,必须进行修改,才能编译成功。 我大概具体修改了这么一些地方: 1、CNFGGLOB.h中,#define MayInline __forceinline 改为 __inline。 2、MYOSGLUE.c中
1)必须加入常量VK_APPS、VK_LWIN、VK_RWIN、SPI_SCREENSAVERRUNNING、_MAX_PATH、等一大堆东西(记不清,自己根据错误内容去看吧。。) 2) typedef HRESULT (WINAPI *SHGetSpecialFolderPathProcPtr) ( HWND hwndOwner, LPTSTR lpszPath, int nFolder, BOOL fCreate ); LOCALVAR SHGetSpecialFolderPathProcPtr MySHGetSpecialFolderPath = NULL; 注释掉,加一行LOCALVAR long MySHGetSpecialFolderPath = NULL; LOCALFUNC blnr HaveMySHGetSpecialFolderPath(void) { 下面 if (! DidSHGetSpecialFolderPath) { HMODULE hLibModule = LoadLibrary(TEXT("shell32.dll")); if (NULL != hLibModule) { MySHGetSpecialFolderPath = (SHGetSpecialFolderPathProcPtr) GetProcAddress(hLibModule, #if MyUseUni TEXT("SHGetSpecialFolderPathW") #else TEXT("SHGetSpecialFolderPathA") #endif ); FreeLibrary(hLibModule); } DidSHGetSpecialFolderPath = trueblnr; } 也注释掉。这是因为VC1.1不存在shlobj.h,无法使用这些API,而且也不能使用typedef HRESULT (WINAPI *SHGetSpecialFolderPathProcPtr) 这样的方法来自己定义个函数指针,只有干掉了。 3) #ifndef EnableShellLinks #define EnableShellLinks 1 改成 0 #endif 快捷方式相关的VC1.1不能用,没办法。 4) LOCALPROC MySound_Start(void) 中的 WAVEFORMATEX wfex; 改成 PCMWAVEFORMAT wfex; 其初始化部分 wfex.wFormatTag = WAVE_FORMAT_PCM; wfex.nChannels = 1; wfex.nSamplesPerSec = SOUND_SAMPLERATE; wfex.nAvgBytesPerSec = SOUND_SAMPLERATE; wfex.nBlockAlign = 1; wfex.wBitsPerSample = 8; wfex.cbSize = 0; 改成 wfex.wf.wFormatTag = WAVE_FORMAT_PCM; wfex.wf.nChannels = 1; wfex.wf.nSamplesPerSec = SOUND_SAMPLERATE; wfex.wf.nAvgBytesPerSec = SOUND_SAMPLERATE; wfex.wf.nBlockAlign = 1; wfex.wBitsPerSample=8; 5) LOCALPROC MyAppendSubmenuConvertName(HMENU hMenu, HMENU hSubMenu, char *s) 中, MENUITEMINFO mii; 注释掉 #if 0改成1 下面的 memset(&mii, 0, sizeof(MENUITEMINFO)); mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_TYPE | MIIM_SUBMENU; mii.fType = MFT_STRING; mii.hSubMenu = hSubMenu; mii.dwTypeData = ts; mii.cch = (UINT)_tcslen(ts); (void) InsertMenuItem(hMenu, (UINT) -1, TRUE, &mii); 注释掉 VC1.1没有InsertMenuItem这个API和MENUITEMINFO结构。 6)int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) 改成 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
3、CNFGRAPI.h的#include <shlobj.h>注释掉。 令人惊奇的是,我们修改的仅仅是Mini vMac与系统结合的那一部分,其模拟代码根本没有必要修改。 这样修改后,工程设置把警告级别再改下,编译可以得到这样的结果。
经过我的测试,编译出的MVMAC.exe的链接器版本号为3.10,实际可以在Windows NT 3.5以上的系统运行。
VC2.0和VC1.1的SDK差不多,基本可以如法炮制。 目前还有一些问题点: 1、VC1.1(CL 8.0)、VC 2.0(CL 9.0)都不支持__int64,这是Mini vMac II浮点模拟库必须的,因此目前VC1.1无法简单地编译具有FPU模拟功能的Mini vMac II。 2、这样编译的Mini vMac关闭较慢,还没搞清楚怎么回事, 3、VC1.1的链接器在高版本NT系统(如NT4、2000、XP)下工作不正常,生成特别大的exe,需要使用2.0版本的替换。 另外,某论坛上有洋大人问是否能够把这个编译到16位的Windows平台,或者把这个在Win3.1+Win32s上运行,我只能说,前者需要进行大幅修改(程序中大量直接使用int,大量使用32位内存模型的内存分配),而后者据我的测试,连找不到ROM的错误信息都显示不出来,估计是DIB不支持之类的问题。 |
|