os2.c
changeset 810 7c51ba5a4368
parent 801 bfa47ec110b0
child 818 906f21e653b2
equal deleted inserted replaced
809:86cc46f97149 810:7c51ba5a4368
     4 #include "hal.h"
     4 #include "hal.h"
     5 
     5 
     6 #include <direct.h>
     6 #include <direct.h>
     7 #include <unistd.h>
     7 #include <unistd.h>
     8 #include <sys/stat.h>
     8 #include <sys/stat.h>
       
     9 #include <stdarg.h>
     9 #include <time.h>
    10 #include <time.h>
    10 #include <dos.h>
    11 #include <dos.h>
    11 
    12 
       
    13 #define INCL_DOS
       
    14 #define INCL_WINDIALOGS
       
    15 #define INCL_OS2MM
       
    16 
    12 #include <os2.h>
    17 #include <os2.h>
       
    18 #include <os2me.h>
    13 
    19 
    14 #if defined(WITH_SDL)
    20 #if defined(WITH_SDL)
    15 #include <SDL.h>
    21 #include <SDL.h>
    16 #endif
    22 #endif
    17 
    23 
    25 {
    31 {
    26 	if (_fios_count == _fios_alloc) {
    32 	if (_fios_count == _fios_alloc) {
    27 		_fios_alloc += 256;
    33 		_fios_alloc += 256;
    28 		_fios_items = realloc(_fios_items, _fios_alloc * sizeof(FiosItem));
    34 		_fios_items = realloc(_fios_items, _fios_alloc * sizeof(FiosItem));
    29 	}
    35 	}
       
    36 
    30 	return &_fios_items[_fios_count++];
    37 	return &_fios_items[_fios_count++];
    31 }
    38 }
    32 
    39 
    33 int compare_FiosItems (const void *a, const void *b) {
    40 int compare_FiosItems (const void *a, const void *b) {
    34 	const FiosItem *da = (const FiosItem *) a;
    41 	const FiosItem *da = (const FiosItem *) a;
    42 
    49 
    43 	if (_savegame_sort_order & 1) r = -r;
    50 	if (_savegame_sort_order & 1) r = -r;
    44 	return r;
    51 	return r;
    45 }
    52 }
    46 
    53 
       
    54 
       
    55 static DIR *my_opendir(char *path, char *file)
       
    56 {
       
    57 	char paths[MAX_PATH];
       
    58 
       
    59 	append_path(paths, path, file);		
       
    60 	return opendir(paths);
       
    61 }
       
    62 
       
    63 static void append_path(char *out, char *path, char *file)
       
    64 {
       
    65 	if ((path[2] == '\\') && (path[3] == 0))
       
    66 		sprintf(out, "%s%s", path, file);
       
    67 	else
       
    68 		sprintf(out, "%s\\%s", path, file);
       
    69 }
    47 
    70 
    48 // Get a list of savegames
    71 // Get a list of savegames
    49 FiosItem *FiosGetSavegameList(int *num, int mode)
    72 FiosItem *FiosGetSavegameList(int *num, int mode)
    50 {
    73 {
    51 	FiosItem *fios;
    74 	FiosItem *fios;
    58 	if (_fios_save_path == NULL) {
    81 	if (_fios_save_path == NULL) {
    59 		_fios_save_path = malloc(MAX_PATH);
    82 		_fios_save_path = malloc(MAX_PATH);
    60 		strcpy(_fios_save_path, _path.save_dir);
    83 		strcpy(_fios_save_path, _path.save_dir);
    61 	}
    84 	}
    62 
    85 
    63 	if(_game_mode==GM_EDITOR)
    86 	if (_game_mode == GM_EDITOR)
    64 		_fios_path = _fios_scn_path;
    87 		_fios_path = _fios_scn_path;
    65 	else
    88 	else
    66 		_fios_path = _fios_save_path;
    89 		_fios_path = _fios_save_path;
    67 
    90 
    68 	// Parent directory, only if not in root already.
    91 	// Parent directory, only if not of the type C:\.
    69 	if (_fios_path[1] != 0) {
    92 	if (_fios_path[3] != 0) {
    70 		fios = FiosAlloc();
    93 		fios = FiosAlloc();
    71 		fios->type = FIOS_TYPE_PARENT;
    94 		fios->type = FIOS_TYPE_PARENT;
    72 		fios->mtime = 0;
    95 		strcpy(fios->title, ".. (Parent directory)");
    73 		sprintf(fios->title, ".. (Parent directory)");
       
    74 	}
    96 	}
    75 
    97 
    76 	// Show subdirectories first
    98 	// Show subdirectories first
    77 	dir = opendir(_fios_path[0] ? _fios_path : "C:\\");
    99 	dir = my_opendir(_fios_path, "*.*");
    78 	if (dir != NULL) {
   100 	if (dir != NULL) {
    79 		while ((dirent = readdir(dir))) {
   101 		while ((dirent = readdir(dir))) {
    80 			sprintf (filename, "%s\\%s", _fios_path, dirent->d_name);
   102 			append_path(filename, _fios_path, dirent->d_name);
    81 			if (!stat(filename, &sb)) {
   103 			if (!stat(filename, &sb)) {
    82 				if (S_ISDIR(sb.st_mode)) {
   104 				if (S_ISDIR(sb.st_mode)) {
    83 					if (dirent->d_name[0] != '.') {
   105 					if (!(dirent->d_name[0] == '.' && (dirent->d_name[1] == 0 || (dirent->d_name[1] == '.' && dirent->d_name[2] == 0))))
       
   106 					{
    84 						fios = FiosAlloc();
   107 						fios = FiosAlloc();
    85 						fios->mtime = 0;
       
    86 						fios->type = FIOS_TYPE_DIR;
   108 						fios->type = FIOS_TYPE_DIR;
    87 						fios->title[0] = 0;
   109 						strcpy(fios->name, dirent->d_name);
    88 						sprintf(fios->name, "%s\\ (Directory)", dirent->d_name);
   110 						sprintf(fios->title, "%s\\ (Directory)", dirent->d_name);
    89 					}
   111 					}
    90 				}
   112 				}
    91 			}
   113 			}
    92 		}
   114 		}
    93 		closedir(dir);
   115 		closedir(dir);
   108 	 *      .SAV    OpenTTD saved game
   130 	 *      .SAV    OpenTTD saved game
   109 	 *      .SS1    Transport Tycoon Deluxe preset game
   131 	 *      .SS1    Transport Tycoon Deluxe preset game
   110 	 *      .SV1    Transport Tycoon Deluxe (Patch) saved game
   132 	 *      .SV1    Transport Tycoon Deluxe (Patch) saved game
   111 	 *      .SV2    Transport Tycoon Deluxe (Patch) saved 2-player game
   133 	 *      .SV2    Transport Tycoon Deluxe (Patch) saved 2-player game
   112 	 */
   134 	 */
   113 	dir = opendir(_fios_path[0] ? _fios_path : "C:\\");
   135 	dir = my_opendir(_fios_path, "*.*");
   114 	if (dir != NULL) {
   136 	if (dir != NULL) {
   115 		while ((dirent = readdir(dir))) {
   137 		while ((dirent = readdir(dir))) {
   116 			sprintf (filename, "%s\\%s", _fios_path, dirent->d_name);
   138 			append_path(filename, _fios_path, dirent->d_name);
   117 			if (!stat(filename, &sb)) {
   139 			if (!stat(filename, &sb)) {
   118 				if (!S_ISDIR(sb.st_mode)) {
   140 				if (!S_ISDIR(sb.st_mode)) {
   119 					char *t = strrchr(dirent->d_name, '.');
   141 					char *t = strrchr(dirent->d_name, '.');
   120 					if (t && !stricmp(t, ".sav")) { // OpenTTD
   142 					if (t && !stricmp(t, ".sav")) { // OpenTTD
   121 						*t = 0; // cut extension
   143 						*t = 0; // cut extension
   183 	struct dirent *dirent;
   205 	struct dirent *dirent;
   184 	struct stat sb;
   206 	struct stat sb;
   185 	int sort_start;
   207 	int sort_start;
   186 	char filename[MAX_PATH];
   208 	char filename[MAX_PATH];
   187 
   209 
   188 	if (_fios_scn_path == NULL) {
   210 	if (mode == SLD_NEW_GAME || _fios_scn_path == NULL) {
   189 		_fios_scn_path = malloc(MAX_PATH);
   211 		if (_fios_scn_path == NULL)
       
   212 			_fios_scn_path = malloc(MAX_PATH);
   190 		strcpy(_fios_scn_path, _path.scenario_dir);
   213 		strcpy(_fios_scn_path, _path.scenario_dir);
   191 	}
   214 	}
       
   215 
   192 	_fios_path = _fios_scn_path;
   216 	_fios_path = _fios_scn_path;
   193 
   217 
       
   218 	// Parent directory, only if not of the type C:\.
       
   219 	if (_fios_path[3] != 0 && mode != SLD_NEW_GAME) {
       
   220 		fios = FiosAlloc();
       
   221 		fios->type = FIOS_TYPE_PARENT;
       
   222 		strcpy(fios->title, ".. (Parent directory)");
       
   223 	}
       
   224 
   194 	// Show subdirectories first
   225 	// Show subdirectories first
   195 	dir = opendir(_fios_path[0] ? _fios_path : "C:\\");
   226 	dir = my_opendir(_fios_path, "*.*");
   196 	if (dir != NULL) {
   227 	if (dir != NULL) {
   197 		while ((dirent = readdir(dir))) {
   228 		while ((dirent = readdir(dir))) {
   198 			sprintf (filename, "%s\\%s", _fios_path, dirent->d_name);
   229 			append_path(filename, _fios_path, dirent->d_name);
   199 			if (!stat(filename, &sb)) {
   230 			if (!stat(filename, &sb)) {
   200 				if (S_ISDIR(sb.st_mode)) {
   231 				if (S_ISDIR(sb.st_mode)) {
   201 					if (dirent->d_name[0] != '.') {
   232 					if (!(dirent->d_name[0] == '.' && (dirent->d_name[1] == 0 || (dirent->d_name[1] == '.' && dirent->d_name[2] == 0))))
       
   233 					{
   202 						fios = FiosAlloc();
   234 						fios = FiosAlloc();
   203 						fios->mtime = 0;
   235 						fios->mtime = 0;
   204 						fios->type = FIOS_TYPE_DIR;
   236 						fios->type = FIOS_TYPE_DIR;
   205 						fios->title[0] = 0;
   237 						strcpy(fios->name, dirent->d_name);
   206 						sprintf(fios->name, "%s\\ (Directory)", dirent->d_name);
   238 						sprintf(fios->title, "%s\\ (Directory)", dirent->d_name);
   207 					}
   239 					}
   208 				}
   240 				}
   209 			}
   241 			}
   210 		}
   242 		}
   211 		closedir(dir);
   243 		closedir(dir);
   217 	/*      Show scenario files
   249 	/*      Show scenario files
   218 	 *      .SCN    OpenTTD style scenario file
   250 	 *      .SCN    OpenTTD style scenario file
   219 	 *      .SV0    Transport Tycoon Deluxe (Patch) scenario
   251 	 *      .SV0    Transport Tycoon Deluxe (Patch) scenario
   220 	 *      .SS0    Transport Tycoon Deluxe preset scenario
   252 	 *      .SS0    Transport Tycoon Deluxe preset scenario
   221 	 */
   253 	 */
   222 	dir = opendir(_fios_path[0] ? _fios_path : "C:\\");
   254 	dir = my_opendir(_fios_path, "*.*");
   223 	if (dir != NULL) {
   255 	if (dir != NULL) {
   224 		while ((dirent = readdir(dir))) {
   256 		while ((dirent = readdir(dir))) {
   225 			sprintf (filename, "%s\\%s", _fios_path, dirent->d_name);
   257 			append_path(filename, _fios_path, dirent->d_name);
   226 			if (!stat(filename, &sb)) {
   258 			if (!stat(filename, &sb)) {
   227 				if (!S_ISDIR(sb.st_mode)) {
   259 				if (!S_ISDIR(sb.st_mode)) {
   228 					char *t = strrchr(dirent->d_name, '.');
   260 					char *t = strrchr(dirent->d_name, '.');
   229 					if (t && !stricmp(t, ".scn")) { // OpenTTD
   261 					if (t && !stricmp(t, ".scn")) { // OpenTTD
   230 						*t = 0; // cut extension
   262 						*t = 0; // cut extension
   299 {
   331 {
   300 	char *path = _fios_path;
   332 	char *path = _fios_path;
   301 	char *s;
   333 	char *s;
   302 
   334 
   303 	switch(item->type) {
   335 	switch(item->type) {
       
   336 	case FIOS_TYPE_DRIVE:
       
   337 		sprintf(path, "%c:\\", item->title[0]);
       
   338 		break;
       
   339 
   304 	case FIOS_TYPE_PARENT:
   340 	case FIOS_TYPE_PARENT:
   305 		s = strrchr(path, '\\');
   341 		// Skip drive part
   306 		if (s != NULL) *s = 0;
   342 		path += 3;
       
   343 		s = path;
       
   344 		while (*path) {
       
   345 			if (*path== '\\')
       
   346 				s = path;
       
   347 			path++;
       
   348 		}
       
   349 		*s = 0;
   307 		break;
   350 		break;
   308 
   351 
   309 	case FIOS_TYPE_DIR:
   352 	case FIOS_TYPE_DIR:
   310 		s = strchr((char*)item->name, '\\');
   353 		// Scan to end
   311 		if (s) *s = 0;
   354 		while (*++path);
   312 		while (*path) path++;
   355 		// Add backslash?
   313 		*path++ = '\\';
   356 		if (path[-1] != '\\') *path++ = '\\';
       
   357 
   314 		strcpy(path, item->name);
   358 		strcpy(path, item->name);
   315 		break;
   359 		break;
   316 
   360 
   317 	case FIOS_TYPE_FILE:
   361 	case FIOS_TYPE_FILE:
   318 		FiosMakeSavegameName(str_buffr, item->name);
   362 		FiosMakeSavegameName(str_buffr, item->name);
   323 		return str_buffr;
   367 		return str_buffr;
   324 
   368 
   325 	case FIOS_TYPE_SCENARIO:
   369 	case FIOS_TYPE_SCENARIO:
   326 		sprintf(str_buffr, "%s\\%s.scn", path, item->name);
   370 		sprintf(str_buffr, "%s\\%s.scn", path, item->name);
   327 		return str_buffr;
   371 		return str_buffr;
   328 
       
   329 	case FIOS_TYPE_OLD_SCENARIO:
   372 	case FIOS_TYPE_OLD_SCENARIO:
   330 		sprintf(str_buffr, "%s\\%s.%s", path, item->name, _old_extensions[item->old_extension]);
   373 		sprintf(str_buffr, "%s\\%s.%s", path, item->name, _old_extensions[item->old_extension]);
   331 		return str_buffr;
   374 		return str_buffr;
   332 	}
   375 	}
   333 
   376 
   340 StringID FiosGetDescText(const char **path)
   383 StringID FiosGetDescText(const char **path)
   341 {
   384 {
   342 	struct diskfree_t free;
   385 	struct diskfree_t free;
   343 	char drive;
   386 	char drive;
   344 	
   387 	
   345 	*path = _fios_path[0] ? _fios_path : "C:\\";
   388 	*path = _fios_path;
   346 	drive = 'B' - *path[0];
   389 	drive = *path[0] - 'A'+1;
   347 
   390 
   348 	_getdiskfree(drive, &free);
   391 	_getdiskfree(drive, &free);
   349 		
   392 
   350 	SetDParam(0, free.avail_clusters * free.sectors_per_cluster * free.bytes_per_sector);
   393 	SetDParam(0, free.avail_clusters * free.sectors_per_cluster * free.bytes_per_sector);
   351 	return STR_4005_BYTES_FREE;
   394 	return STR_4005_BYTES_FREE;
   352 }
   395 }
   353 
   396 
   354 void FiosMakeSavegameName(char *buf, const char *name)
   397 void FiosMakeSavegameName(char *buf, const char *name)
   365 	FiosMakeSavegameName(path, name);
   408 	FiosMakeSavegameName(path, name);
   366 	unlink(path);
   409 	unlink(path);
   367 }
   410 }
   368 
   411 
   369 const DriverDesc _video_driver_descs[] = {
   412 const DriverDesc _video_driver_descs[] = {
   370 	{"null",	"Null Video Driver",    &_null_video_driver,    0},
   413 	{	"null",			"Null Video Driver",		&_null_video_driver,		0},
   371 #if defined(WITH_SDL)
   414 #if defined(WITH_SDL)
   372 	{ "sdl",	"SDL Video Driver",	     &_sdl_video_driver,	     1},
   415 	{	"sdl",			"SDL Video Driver",			&_sdl_video_driver,			1},
   373 #endif
   416 #endif
   374 	{ "dedicated", "Dedicated Video Driver", &_dedicated_video_driver, 0},
   417 	{	"dedicated",	"Dedicated Video Driver",	&_dedicated_video_driver,	0},
   375 	{ NULL,	 NULL,								   NULL,								   0}
   418 	{	NULL,			NULL,						NULL,						0}
   376 };
   419 };
   377 
   420 
   378 const DriverDesc _sound_driver_descs[] = {
   421 const DriverDesc _sound_driver_descs[] = {
   379 	{"null",	"Null Sound Driver",    &_null_sound_driver,	    0},
   422 	{	"null",	"Null Sound Driver",	&_null_sound_driver,		0},
   380 #if defined(WITH_SDL)
   423 #if defined(WITH_SDL)
   381 	{ "sdl",	"SDL Sound Driver",	     &_sdl_sound_driver,		     1},
   424 	{	"sdl",	"SDL Sound Driver",		&_sdl_sound_driver,			1},
   382 #endif
   425 #endif
   383 	{ NULL,	 NULL,								   NULL,									   0}
   426 	{	NULL,	NULL,					NULL,						0}
   384 };
   427 };
   385 
   428 
   386 const DriverDesc _music_driver_descs[] = {
   429 const DriverDesc _music_driver_descs[] = {
   387 	{   "null",     "Null Music Driver",	    &_null_music_driver,	    0},
   430 	{	"os2",		"OS/2 Music Driver",		&_os2_music_driver,			0},
   388 	{     NULL,     NULL,									   NULL,									   0}
   431 	{   "null",     "Null Music Driver",	    &_null_music_driver,	    1},
       
   432 	{	NULL,		NULL,						NULL,						0}
   389 };
   433 };
   390 
   434 
   391 /* GetOSVersion returns the minimal required version of OS to be able to use that driver.
   435 /* GetOSVersion returns the minimal required version of OS to be able to use that driver.
   392 	 Not needed for *nix. */
   436 	 Not needed for OS/2. */
   393 byte GetOSVersion()
   437 byte GetOSVersion()
   394 {
   438 {
   395 	return 2;  // any arbitrary number bigger then 0
   439 	return 2;  // any arbitrary number bigger then 0
   396 				// numbers lower than 2 breaks default music selection on mac
       
   397 }
   440 }
   398 
   441 
   399 bool FileExists(const char *filename)
   442 bool FileExists(const char *filename)
   400 {
   443 {
   401 	return access(filename, 0) == 0;
   444 	return access(filename, 0) == 0;
   436 		chdir(exe);
   479 		chdir(exe);
   437 		*s = '\\';
   480 		*s = '\\';
   438 	}
   481 	}
   439 }
   482 }
   440 
   483 
       
   484 // for some reason these calls don't actually work properly :/
   441 void ShowInfo(const char *str)
   485 void ShowInfo(const char *str)
   442 {
   486 {
   443 	puts(str);
   487 	WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, str, "OpenTTD", 0, MB_OK | MB_SYSTEMMODAL | MB_MOVEABLE | MB_INFORMATION);
   444 }
   488 }
   445 
   489 
   446 void ShowOSErrorBox(const char *buf)
   490 void ShowOSErrorBox(const char *buf)
   447 {
   491 {
   448 	WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, buf, "OpenTTD", 263, MB_OK | MB_APPLMODAL | MB_MOVEABLE | MB_ERROR);
   492 	WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, buf, "OpenTTD", 0, MB_OK | MB_SYSTEMMODAL | MB_MOVEABLE | MB_ERROR);
   449 // TODO: FIX, doesn't always appear
       
   450 }
   493 }
   451 
   494 
   452 int CDECL main(int argc, char* argv[])
   495 int CDECL main(int argc, char* argv[])
   453 {
   496 {
   454 	// change the working directory to enable doubleclicking in UIs
   497 	// change the working directory to enable doubleclicking in UIs
   527 	mkdir(_path.save_dir);
   570 	mkdir(_path.save_dir);
   528 	mkdir(_path.autosave_dir);
   571 	mkdir(_path.autosave_dir);
   529 	mkdir(_path.scenario_dir);
   572 	mkdir(_path.scenario_dir);
   530 }
   573 }
   531 
   574 
       
   575 // FUNCTION: OS2_SwitchToConsoleMode
       
   576 //
       
   577 // Switches OpenTTD to a console app at run-time, instead of a PM app
       
   578 // Necessary to see stdout, etc
       
   579 
       
   580 void OS2_SwitchToConsoleMode()
       
   581 {
       
   582 	PPIB pib;
       
   583 	PTIB tib;
       
   584 
       
   585 	DosGetInfoBlocks(&tib, &pib);
       
   586 
       
   587 	// Change flag from PM to VIO
       
   588 	pib->pib_ultype = 3;
       
   589 }
       
   590 
       
   591 
       
   592 /**********************
       
   593  * OS/2 MIDI PLAYER
       
   594  **********************/
       
   595 
       
   596 /* Interesting how similar the MCI API in OS/2 is to the Win32 MCI API,
       
   597  * eh? Anyone would think they both came from the same place originally! ;)
       
   598  */
       
   599 
       
   600 static long CDECL MidiSendCommand(const char *cmd, ...)
       
   601 {
       
   602 	va_list va;
       
   603 	char buf[512];
       
   604 	va_start(va, cmd);
       
   605 	vsprintf(buf, cmd, va);
       
   606 	va_end(va);
       
   607 	return mciSendString(buf, NULL, 0, NULL, 0);
       
   608 }
       
   609 
       
   610 static void OS2MidiPlaySong(const char *filename)
       
   611 {
       
   612 	MidiSendCommand("close all");
       
   613 
       
   614 	if (MidiSendCommand("open %s type sequencer alias song", filename) != 0)
       
   615 		return;
       
   616 
       
   617 	MidiSendCommand("play song from 0");
       
   618 }
       
   619 
       
   620 static void OS2MidiStopSong()
       
   621 {
       
   622 	MidiSendCommand("close all");
       
   623 }
       
   624 
       
   625 static void OS2MidiSetVolume(byte vol)
       
   626 {
       
   627 	MidiSendCommand("set song audio volume %d", ((vol/127)*100));
       
   628 }
       
   629 
       
   630 static bool OS2MidiIsSongPlaying()
       
   631 {
       
   632 	char buf[16];
       
   633 	mciSendString("status song mode", buf, sizeof(buf), NULL, 0);
       
   634 	return strcmp(buf, "playing") == 0 || strcmp(buf, "seeking") == 0;
       
   635 }
       
   636 
       
   637 static char *OS2MidiStart(char **parm)
       
   638 {
       
   639 	return 0;
       
   640 }
       
   641 
       
   642 static void OS2MidiStop()
       
   643 {
       
   644 	MidiSendCommand("close all");
       
   645 }
       
   646 
       
   647 const HalMusicDriver _os2_music_driver = {
       
   648 	OS2MidiStart,
       
   649 	OS2MidiStop,
       
   650 	OS2MidiPlaySong,
       
   651 	OS2MidiStopSong,
       
   652 	OS2MidiIsSongPlaying,
       
   653 	OS2MidiSetVolume,
       
   654 };
       
   655 
       
   656