(svn r8176) -Backport from trunk (r8042, r8089, r8090, r8112):

- OS/2 compilation with GCC (thanks to Paul Smedley and TrueBrain for help) (r8042)
 - [win32] *nprintf functions are broken, 'len = count' wasn't handled (r8089, r8090)
 - MSVC solution files will make openttd THE startup project (r8112)
This commit is contained in:
Darkvater 2007-01-17 00:38:27 +00:00
parent a4bab5f17f
commit 1778566ab8
6 changed files with 126 additions and 71 deletions

View File

@ -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

View File

@ -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}

View File

@ -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}

110
os2.c
View File

@ -9,52 +9,81 @@
#include "gui.h"
#include "functions.h"
#include "macros.h"
#include "fios.h"
#include <direct.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <time.h>
#include <dos.h>
#ifndef __INNOTEK_LIBC__
#include <dos.h>
#endif
#define INCL_WIN
#define INCL_WINCLIPBOARD
#include <os2.h>
#include <i86.h>
#ifndef __INNOTEK_LIBC__
#include <i86.h>
#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;}

View File

@ -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

View File

@ -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 */