Changeset - r5591:5085a131bcc8
[Not reviewed]
master
0 3 0
orudge - 18 years ago 2007-01-10 19:39:54
orudge@openttd.org
(svn r8042) - Fix: OS/2 compilation with GCC (thanks to Paul Smedley and TrueBrain for their help)
3 files changed with 114 insertions and 64 deletions:
0 comments (0 inline, 0 general)
docs/Readme_OS2.txt
Show inline comments
 
@@ -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):
 

	
 
   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'.
 

	
 
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.
 
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,41 +96,22 @@ to an IDE project file and built a libra
 
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
 
http://sourceforge.net/projects/openttd/ - see "os2-useful-v1.1.zip".
 

	
 
A Note About Subversion Revision Numbers
 
----------------------------------------
 
- Freetype
 
  http://freetype.sourceforge.net/
 

	
 
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.
 
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".
 

	
 
Contact Information
 
-------------------
 
@@ -130,4 +120,6 @@ If you have any questions regarding OS/2
 
(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
src/os2.cpp
Show inline comments
 
@@ -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 *pa
 
	}
 

	
 
	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, c
 

	
 
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 *
 

	
 
		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;}
src/stdafx.h
Show inline comments
 
@@ -183,7 +183,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
0 comments (0 inline, 0 general)