diff --git a/docs/Readme_OS2.txt b/docs/Readme_OS2.txt index 7a370385cc..d5641f9e45 100644 --- a/docs/Readme_OS2.txt +++ b/docs/Readme_OS2.txt @@ -67,16 +67,25 @@ BUILDING THE OS/2 VERSION Compiler -------- -Open Watcom 1.3 was used to build OpenTTD (earlier versions will -NOT work). See http://www.openwatcom.org/ to download it. It may -also be possible to build OpenTTD with GCC: I attempted this -before using Open Watcom, but found the tools available for OS/2 -at the time to be a bit more tricky to get working. +Innotek GCC, an OS/2 port of the popular GCC compiler, was used to build OpenTTD. +See www.innotek.de for more information. You WILL need a reasonably UNIX-like +build environment in order to build OpenTTD successfully - the following link +may help to set one up (although some of the links from that page are broken): -Due to complexities in my set-up, I actually used the Win32 version -of Open Watcom to initially compile OpenTTD for OS/2. There should -be no reason of course why the OS/2 version cannot be used, and I -have subsequently built OpenTTD successfully this way. + http://www.mozilla.org/ports/os2/gccsetup.html + +To build, you should, if your environment is set up well enough, be able to just +type `./configure' (or `sh configure' if you're using the OS/2 shell) and `make'. + +A note on Open Watcom +--------------------- + +Open Watcom C/C++ was previously used to build OpenTTD (version 0.4.x and earlier). +However, due to advanced C++ features used in the YAPF portion of OpenTTD 0.5 +in particular, the compiler is no longer able to build the game at the moment. +Hopefully one day Open Watcom will be able to catch up and we will be able to build +the game once again (it's easier than getting an OS/2 UNIX-like environment set up +in my opinion!), but until then, OpenTTD 0.5 and later can only be built with GCC. Libraries Required ------------------ @@ -87,42 +96,23 @@ to an IDE project file and built a library. Do not use the makefiles provided, they are not designed for Watcom (apart from SDL): - zlib - http://www.zlib.org/ - contains a makefile for OS/2, but is out - of date and uses EMX, ignore this + http://www.zlib.org/ - libpng - http://www.libpng.org/ - contains an EMX/gcc makefile, ignore this + http://www.libpng.org/ - SDL for OS/2 ftp://ftp.netlabs.org/pub/sdl/sdl-1.2.7-src-20051222.zip used for 0.4.7 -If you do not wish to build the libraries yourself, pre-built versions -can be downloaded from the Files section at +- Freetype + http://freetype.sourceforge.net/ + +Currently, there are no pre-built libraries available for GCC. If you manage to get +OpenTTD working on Watcom though (do let us know if this is the case!), pre-built +versions can be downloaded from the Files section at http://sourceforge.net/projects/openttd/ - see "os2-useful-v1.1.zip". -A Note About Subversion Revision Numbers ----------------------------------------- - -The project file uses a bit of a hack to find out the SVN revision number and -create an appropriate rev.c file. You'll need the SVN tools in your path -(specifically, "svnversion"). If "svnversion" can't be found, a generic rev.c -with the revision set to "norev000" will be created. To specifically force a -version number, set the environment variable "RELEASE" to the number (eg, "0.3.6") --before- starting the Open Watcom IDE (which must be launched from the same shell -session). Also, beware, as you WILL cause incompatibilities if you try to -play a multiplayer game with a different version. - -Compiling ---------- - -To compile, open the os/os2/openttd.wpj file in the IDE and first build -the strgen.exe target. This will build the .lng file generator, and will -also attempt to build all the language files (plus the table\strings.h -file which is required for openttd.exe to be built). Once strgen.exe and -the language files are built successfully, you can build the openttd.exe -target. - Contact Information ------------------- @@ -130,4 +120,6 @@ If you have any questions regarding OS/2 issues, please contact me (owen@owenrudge.net) and I'll try to help you out. For general OpenTTD issues, see the Contacting section of readme.txt. -- Owen Rudge +Thanks to Paul Smedley for his help with getting OpenTTD to compile under GCC on OS/2. + +- Owen Rudge, 8th January 2007 diff --git a/openttd.sln b/openttd.sln index c8072d9e9b..c2c4047207 100644 --- a/openttd.sln +++ b/openttd.sln @@ -1,14 +1,14 @@ Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "strgen", "strgen\strgen.vcproj", "{A133A442-BD0A-4ADE-B117-AD7545E4BDD1}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openttd", "openttd.vcproj", "{668328A0-B40E-4CDB-BD72-D0064424414A}" ProjectSection(ProjectDependencies) = postProject {0F066B23-18DF-4284-8265-F4A5E7E3B966} = {0F066B23-18DF-4284-8265-F4A5E7E3B966} {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} = {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "strgen", "strgen\strgen.vcproj", "{A133A442-BD0A-4ADE-B117-AD7545E4BDD1}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "langs", "langs.vcproj", "{0F066B23-18DF-4284-8265-F4A5E7E3B966}" ProjectSection(ProjectDependencies) = postProject {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} = {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} diff --git a/openttd_vs80.sln b/openttd_vs80.sln index f6434f8a4c..1f5b3102b5 100644 --- a/openttd_vs80.sln +++ b/openttd_vs80.sln @@ -1,13 +1,13 @@ Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "strgen", "strgen\strgen_vs80.vcproj", "{A133A442-BD0A-4ADE-B117-AD7545E4BDD1}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openttd", "openttd_vs80.vcproj", "{668328A0-B40E-4CDB-BD72-D0064424414A}" ProjectSection(ProjectDependencies) = postProject {0F066B23-18DF-4284-8265-F4A5E7E3B966} = {0F066B23-18DF-4284-8265-F4A5E7E3B966} {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} = {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "strgen", "strgen\strgen_vs80.vcproj", "{A133A442-BD0A-4ADE-B117-AD7545E4BDD1}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "langs", "langs_vs80.vcproj", "{0F066B23-18DF-4284-8265-F4A5E7E3B966}" ProjectSection(ProjectDependencies) = postProject {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} = {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} diff --git a/os2.c b/os2.c index e01d7c0d25..88ca2fddf6 100644 --- a/os2.c +++ b/os2.c @@ -9,52 +9,81 @@ #include "gui.h" #include "functions.h" #include "macros.h" +#include "fios.h" -#include +#include #include #include #include #include -#include +#ifndef __INNOTEK_LIBC__ + #include +#endif #define INCL_WIN #define INCL_WINCLIPBOARD #include -#include +#ifndef __INNOTEK_LIBC__ + #include +#endif bool FiosIsRoot(const char *file) { - return path[3] == '\0'; + return file[3] == '\0'; } void FiosGetDrives(void) { - FiosItem *fios; unsigned disk, disk2, save, total; +#ifndef __INNOTEK_LIBC__ _dos_getdrive(&save); // save original drive +#else + save = _getdrive(); // save original drive + total = 'z'; +#endif /* get an available drive letter */ +#ifndef __INNOTEK_LIBC__ for (disk = 1;; disk++) { _dos_setdrive(disk, &total); +#else + for (disk = 'A';; disk++) { + _chdrive(disk); +#endif if (disk >= total) return; + +#ifndef __INNOTEK_LIBC__ _dos_getdrive(&disk2); +#else + disk2 = _getdrive(); +#endif if (disk == disk2) { FiosItem *fios = FiosAlloc(); fios->type = FIOS_TYPE_DRIVE; fios->mtime = 0; +#ifndef __INNOTEK_LIBC__ snprintf(fios->name, lengthof(fios->name), "%c:", 'A' + disk - 1); +#else + snprintf(fios->name, lengthof(fios->name), "%c:", disk); +#endif ttd_strlcpy(fios->title, fios->name, lengthof(fios->title)); } } - _dos_setdrive(save, &total); // restore the original drive + /* Restore the original drive */ +#ifndef __INNOTEK_LIBC__ + _dos_setdrive(save, &total); +#else + _chdrive(save); +#endif } bool FiosGetDiskFreeSpace(const char *path, uint32 *tot) { +#ifndef __INNOTEK_LIBC__ struct diskfree_t free; char drive = path[0] - 'A' + 1; @@ -64,6 +93,20 @@ bool FiosGetDiskFreeSpace(const char *path, uint32 *tot) } return false; +#else + uint32 free = 0; + +#ifdef HAS_STATVFS + { + struct statvfs s; + + if (statvfs(path, &s) != 0) return false; + free = (uint64)s.f_frsize * s.f_bavail >> 20; + } +#endif + if (tot != NULL) *tot = free; + return true; +#endif } bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb) @@ -78,15 +121,16 @@ bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb static void ChangeWorkingDirectory(char *exe) { - char *s = strrchr(exe, '\\'); + char *s = strrchr(exe, PATHSEPCHAR); + if (s != NULL) { *s = '\0'; chdir(exe); - *s = '\\'; + *s = PATHSEPCHAR; } } -void ShowInfo(const char *str) +void ShowInfo(const unsigned char *str) { HAB hab; HMQ hmq; @@ -96,14 +140,14 @@ void ShowInfo(const char *str) hmq = WinCreateMsgQueue((hab = WinInitialize(0)), 0); // display the box - rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, str, "OpenTTD", 0, MB_OK | MB_MOVEABLE | MB_INFORMATION); + rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, str, (const unsigned char *)"OpenTTD", 0, MB_OK | MB_MOVEABLE | MB_INFORMATION); // terminate PM env. WinDestroyMsgQueue(hmq); WinTerminate(hab); } -void ShowOSErrorBox(const char *buf) +void ShowOSErrorBox(const unsigned char *buf) { HAB hab; HMQ hmq; @@ -113,7 +157,7 @@ void ShowOSErrorBox(const char *buf) hmq = WinCreateMsgQueue((hab = WinInitialize(0)), 0); // display the box - rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, buf, "OpenTTD", 0, MB_OK | MB_MOVEABLE | MB_ERROR); + rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, buf, (const unsigned char *)"OpenTTD", 0, MB_OK | MB_MOVEABLE | MB_ERROR); // terminate PM env. WinDestroyMsgQueue(hmq); @@ -134,12 +178,12 @@ void DeterminePaths(void) { char *s; - _paths.game_data_dir = malloc(MAX_PATH); + _paths.game_data_dir = (char *)malloc(MAX_PATH); ttd_strlcpy(_paths.game_data_dir, GAME_DATA_DIR, MAX_PATH); - #if defined SECOND_DATA_DIR +#if defined SECOND_DATA_DIR _paths.second_data_dir = malloc(MAX_PATH); ttd_strlcpy(_paths.second_data_dir, SECOND_DATA_DIR, MAX_PATH); - #endif +#endif #if defined(USE_HOMEDIR) { @@ -155,17 +199,17 @@ void DeterminePaths(void) #else /* not defined(USE_HOMEDIR) */ - _paths.personal_dir = malloc(MAX_PATH); + _paths.personal_dir = (char *)malloc(MAX_PATH); ttd_strlcpy(_paths.personal_dir, PERSONAL_DIR, MAX_PATH); // check if absolute or relative path - s = strchr(_paths.personal_dir, '\\'); + s = strchr(_paths.personal_dir, PATHSEPCHAR); // add absolute path if (s == NULL || _paths.personal_dir != s) { getcwd(_paths.personal_dir, MAX_PATH); s = strchr(_paths.personal_dir, 0); - *s++ = '\\'; + *s++ = PATHSEPCHAR; ttd_strlcpy(s, PERSONAL_DIR, MAX_PATH); } @@ -174,14 +218,14 @@ void DeterminePaths(void) s = strchr(_paths.personal_dir, 0); // append a / ? - if (s[-1] != '\\') strcpy(s, "\\"); + if (s[-1] != PATHSEPCHAR) strcpy(s, PATHSEP); _paths.save_dir = str_fmt("%ssave", _paths.personal_dir); - _paths.autosave_dir = str_fmt("%s\\autosave", _paths.save_dir); + _paths.autosave_dir = str_fmt("%s" PATHSEP "autosave", _paths.save_dir); _paths.scenario_dir = str_fmt("%sscenario", _paths.personal_dir); - _paths.heightmap_dir = str_fmt("%sscenario\\heightmap", _paths.personal_dir); - _paths.gm_dir = str_fmt("%sgm\\", _paths.game_data_dir); - _paths.data_dir = str_fmt("%sdata\\", _paths.game_data_dir); + _paths.heightmap_dir = str_fmt("%sscenario" PATHSEP "heightmap", _paths.personal_dir); + _paths.gm_dir = str_fmt("%sgm" PATHSEP, _paths.game_data_dir); + _paths.data_dir = str_fmt("%sdata" PATHSEP, _paths.game_data_dir); if (_config_file == NULL) _config_file = str_fmt("%sopenttd.cfg", _paths.personal_dir); @@ -194,15 +238,23 @@ void DeterminePaths(void) _paths.lang_dir = malloc( MAX_PATH ); ttd_strlcpy( _paths.lang_dir, CUSTOM_LANG_DIR, MAX_PATH); #else - _paths.lang_dir = str_fmt("%slang\\", _paths.game_data_dir); + _paths.lang_dir = str_fmt("%slang" PATHSEP, _paths.game_data_dir); #endif // create necessary folders +#ifndef __INNOTEK_LIBC__ mkdir(_paths.personal_dir); mkdir(_paths.save_dir); mkdir(_paths.autosave_dir); mkdir(_paths.scenario_dir); mkdir(_paths.heightmap_dir); +#else + mkdir(_paths.personal_dir, 0755); + mkdir(_paths.save_dir, 0755); + mkdir(_paths.autosave_dir, 0755); + mkdir(_paths.scenario_dir, 0755); + mkdir(_paths.heightmap_dir, 0755); +#endif } /** @@ -214,6 +266,8 @@ void DeterminePaths(void) */ bool InsertTextBufferClipboard(Textbuf *tb) { +/* XXX -- Currently no clipboard support implemented with GCC */ +#ifndef __INNOTEK_LIBC__ HAB hab = 0; if (WinOpenClipbrd(hab)) @@ -252,14 +306,18 @@ bool InsertTextBufferClipboard(Textbuf *tb) WinCloseClipbrd(hab); } - +#endif return false; } void CSleep(int milliseconds) { - delay(milliseconds); +#ifndef __INNOTEK_LIBC__ + delay(milliseconds); +#else + usleep(milliseconds * 1000); +#endif } const char *FS2OTTD(const char *name) {return name;} diff --git a/stdafx.h b/stdafx.h index 8504e585c7..a2c3f5d604 100644 --- a/stdafx.h +++ b/stdafx.h @@ -180,7 +180,7 @@ # endif #endif /* WIN32 || __OS2__ || WIN64 */ -#if defined(WIN32) || defined(WIN64) || defined(__OS2__) +#if defined(WIN32) || defined(WIN64) || defined(__OS2__) && !defined(__INNOTEK_LIBC__) # define PATHSEP "\\" # define PATHSEPCHAR '\\' #else diff --git a/string.c b/string.c index bac6ac8db0..dfa2d2b900 100644 --- a/string.c +++ b/string.c @@ -160,11 +160,16 @@ int CDECL snprintf(char *str, size_t size, const char *format, ...) } #ifdef _MSC_VER +/* *nprintf broken, not POSIX compliant, MSDN description + * - If len < count, then len characters are stored in buffer, a null-terminator is appended, and len is returned. + * - If len = count, then len characters are stored in buffer, no null-terminator is appended, and len is returned. + * - If len > count, then count characters are stored in buffer, no null-terminator is appended, and a negative value is returned + */ int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap) { int ret; ret = _vsnprintf(str, size, format, ap); - if (ret < 0) str[size - 1] = '\0'; + if (ret < 0 || ret == size) str[size - 1] = '\0'; return ret; } #endif /* _MSC_VER */