diff options
author | rubidium <rubidium@openttd.org> | 2007-01-02 19:19:48 +0000 |
---|---|---|
committer | rubidium <rubidium@openttd.org> | 2007-01-02 19:19:48 +0000 |
commit | 013df98f79866a75f367853c9e436f3c5c79f645 (patch) | |
tree | ad4a63860df2626b22f77e7dac712e958bea54cb /src/os2.c | |
parent | 3d32fd3f4bfaceb8a48530fbc2f4bd5db2752596 (diff) | |
download | openttd-013df98f79866a75f367853c9e436f3c5c79f645.tar.xz |
(svn r7759) -Merge: makefile rewrite. This merge features:
- A proper ./configure, so everything needs to be configured only once, not for every make.
- Usage of makedepend when available. This greatly reduces the time needed for generating the dependencies.
- A generator for all project files. There is a single file with sources, which is used to generate Makefiles and the project files for MSVC.
- Proper support for OSX universal binaries.
- Object files for non-MSVC compiles are also placed in separate directories, making is faster to switch between debug and release compiles and it does not touch the directory with the source files.
- Functionality to make a bundle of all needed files for for example a nightly or distribution of a binary with all needed GRFs and language files.
Note: as this merge moves almost all files, it is recommended to make a backup of your working copy before updating your working copy.
Diffstat (limited to 'src/os2.c')
-rw-r--r-- | src/os2.c | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/src/os2.c b/src/os2.c new file mode 100644 index 000000000..e01d7c0d2 --- /dev/null +++ b/src/os2.c @@ -0,0 +1,266 @@ +/* $Id$ */ + +#include "stdafx.h" +#include "openttd.h" +#include "variables.h" +#include "string.h" +#include "table/strings.h" +#include "gfx.h" +#include "gui.h" +#include "functions.h" +#include "macros.h" + +#include <direct.h> +#include <unistd.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <time.h> +#include <dos.h> + +#define INCL_WIN +#define INCL_WINCLIPBOARD + +#include <os2.h> +#include <i86.h> + +bool FiosIsRoot(const char *file) +{ + return path[3] == '\0'; +} + +void FiosGetDrives(void) +{ + FiosItem *fios; + unsigned disk, disk2, save, total; + + _dos_getdrive(&save); // save original drive + + /* get an available drive letter */ + for (disk = 1;; disk++) { + _dos_setdrive(disk, &total); + if (disk >= total) return; + _dos_getdrive(&disk2); + + if (disk == disk2) { + FiosItem *fios = FiosAlloc(); + fios->type = FIOS_TYPE_DRIVE; + fios->mtime = 0; + snprintf(fios->name, lengthof(fios->name), "%c:", 'A' + disk - 1); + ttd_strlcpy(fios->title, fios->name, lengthof(fios->title)); + } + } + + _dos_setdrive(save, &total); // restore the original drive +} + +bool FiosGetDiskFreeSpace(const char *path, uint32 *tot) +{ + struct diskfree_t free; + char drive = path[0] - 'A' + 1; + + if (tot != NULL && _getdiskfree(drive, &free) == 0) { + *tot = free.avail_clusters * free.sectors_per_cluster * free.bytes_per_sector; + return true; + } + + return false; +} + +bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb) +{ + char filename[MAX_PATH]; + + snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, ent->d_name); + if (stat(filename, sb) != 0) return false; + + return (ent->d_name[0] != '.'); // hidden file +} + +static void ChangeWorkingDirectory(char *exe) +{ + char *s = strrchr(exe, '\\'); + if (s != NULL) { + *s = '\0'; + chdir(exe); + *s = '\\'; + } +} + +void ShowInfo(const char *str) +{ + HAB hab; + HMQ hmq; + ULONG rc; + + // init PM env. + hmq = WinCreateMsgQueue((hab = WinInitialize(0)), 0); + + // display the box + rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, str, "OpenTTD", 0, MB_OK | MB_MOVEABLE | MB_INFORMATION); + + // terminate PM env. + WinDestroyMsgQueue(hmq); + WinTerminate(hab); +} + +void ShowOSErrorBox(const char *buf) +{ + HAB hab; + HMQ hmq; + ULONG rc; + + // init PM env. + hmq = WinCreateMsgQueue((hab = WinInitialize(0)), 0); + + // display the box + rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, buf, "OpenTTD", 0, MB_OK | MB_MOVEABLE | MB_ERROR); + + // terminate PM env. + WinDestroyMsgQueue(hmq); + WinTerminate(hab); +} + +int CDECL main(int argc, char* argv[]) +{ + // change the working directory to enable doubleclicking in UIs + ChangeWorkingDirectory(argv[0]); + + _random_seeds[1][1] = _random_seeds[1][0] = _random_seeds[0][1] = _random_seeds[0][0] = time(NULL); + + return ttd_main(argc, argv); +} + +void DeterminePaths(void) +{ + char *s; + + _paths.game_data_dir = malloc(MAX_PATH); + ttd_strlcpy(_paths.game_data_dir, GAME_DATA_DIR, MAX_PATH); + #if defined SECOND_DATA_DIR + _paths.second_data_dir = malloc(MAX_PATH); + ttd_strlcpy(_paths.second_data_dir, SECOND_DATA_DIR, MAX_PATH); + #endif + +#if defined(USE_HOMEDIR) + { + const char *homedir = getenv("HOME"); + + if (homedir == NULL) { + const struct passwd *pw = getpwuid(getuid()); + if (pw != NULL) homedir = pw->pw_dir; + } + + _paths.personal_dir = str_fmt("%s" PATHSEP "%s", homedir, PERSONAL_DIR); + } + +#else /* not defined(USE_HOMEDIR) */ + + _paths.personal_dir = malloc(MAX_PATH); + ttd_strlcpy(_paths.personal_dir, PERSONAL_DIR, MAX_PATH); + + // check if absolute or relative path + s = strchr(_paths.personal_dir, '\\'); + + // add absolute path + if (s == NULL || _paths.personal_dir != s) { + getcwd(_paths.personal_dir, MAX_PATH); + s = strchr(_paths.personal_dir, 0); + *s++ = '\\'; + ttd_strlcpy(s, PERSONAL_DIR, MAX_PATH); + } + +#endif /* defined(USE_HOMEDIR) */ + + s = strchr(_paths.personal_dir, 0); + + // append a / ? + if (s[-1] != '\\') strcpy(s, "\\"); + + _paths.save_dir = str_fmt("%ssave", _paths.personal_dir); + _paths.autosave_dir = str_fmt("%s\\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); + + if (_config_file == NULL) + _config_file = str_fmt("%sopenttd.cfg", _paths.personal_dir); + + _highscore_file = str_fmt("%shs.dat", _paths.personal_dir); + _log_file = str_fmt("%sopenttd.log", _paths.personal_dir); + +#if defined CUSTOM_LANG_DIR + // sets the search path for lng files to the custom one + _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); +#endif + + // create necessary folders + mkdir(_paths.personal_dir); + mkdir(_paths.save_dir); + mkdir(_paths.autosave_dir); + mkdir(_paths.scenario_dir); + mkdir(_paths.heightmap_dir); +} + +/** + * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard + * and append this up to the maximum length (either absolute or screenlength). If maxlength + * is zero, we don't care about the screenlength but only about the physical length of the string + * @param tb @Textbuf type to be changed + * @return Return true on successfull change of Textbuf, or false otherwise + */ +bool InsertTextBufferClipboard(Textbuf *tb) +{ + HAB hab = 0; + + if (WinOpenClipbrd(hab)) + { + const char* text = (const char*)WinQueryClipbrdData(hab, CF_TEXT); + + if (text != NULL) + { + uint length = 0; + uint width = 0; + const char* i; + + for (i = text; IsValidAsciiChar(*i); i++) + { + uint w; + + if (tb->length + length >= tb->maxlength - 1) break; + + w = GetCharacterWidth(FS_NORMAL, (byte)*i); + if (tb->maxwidth != 0 && width + tb->width + w > tb->maxwidth) break; + + width += w; + length++; + } + + memmove(tb->buf + tb->caretpos + length, tb->buf + tb->caretpos, tb->length - tb->caretpos + 1); + memcpy(tb->buf + tb->caretpos, text, length); + tb->width += width; + tb->caretxoffs += width; + tb->length += length; + tb->caretpos += length; + + WinCloseClipbrd(hab); + return true; + } + + WinCloseClipbrd(hab); + } + + return false; +} + + +void CSleep(int milliseconds) +{ + delay(milliseconds); +} + +const char *FS2OTTD(const char *name) {return name;} +const char *OTTD2FS(const char *name) {return name;} |