added d2demo.mn2
[btb/d2x.git] / unused / ui / file.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14 #pragma off (unreferenced)
15 static char rcsid[] = "$Id: file.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $";
16 #pragma on (unreferenced)
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <direct.h>
22 #include <dos.h>
23 #include <ctype.h>
24 #include <conio.h>
25 #include <fcntl.h>
26 #include <io.h>
27 #include <sys\types.h>
28 #include <sys\stat.h>
29
30 #include "fix.h"
31 #include "types.h"
32 #include "gr.h"
33 #include "key.h"
34
35 #include "ui.h"
36 #include "mono.h"
37
38 #include "mem.h"
39
40 #define TICKER (*(volatile int *)0x46C)
41
42 char filename_list[300][13];
43 char directory_list[100][13];
44
45 static char *Message[] = {
46         "Disk is write protected",
47         "Unknown unit",
48         "Drive not ready",
49         "Unknown command",
50         "CRC error in data",
51         "Bad drive-request stuct length",
52         "Seek error",
53         "Unknown media type",
54         "Sector not found",
55         "Printer out of paper",
56         "Write fault",
57         "Read fault",
58         "General Failure" };
59
60 static int error_mode = 0;
61
62 int __far critical_error_handler( unsigned deverr, unsigned errcode, unsigned far * devhdr )
63 {
64         int x;
65
66         devhdr = devhdr; deverr = deverr; 
67
68         if (error_mode==1) return _HARDERR_FAIL;
69
70         x = MessageBox( -2, -2, 2, Message[errcode], "Retry", "Fail" );
71
72         switch (x)
73         {
74         case 1: return _HARDERR_RETRY;
75         case 2: return _HARDERR_FAIL;
76         default: return _HARDERR_FAIL;
77         }
78 }
79
80 void InstallErrorHandler()
81 {
82         _harderr( critical_error_handler );
83 }
84
85 void file_sort( int n, char list[][13] )
86 {
87         int i, j, incr;
88         char t[14];
89
90         incr = n / 2;
91         while( incr > 0 )
92         {
93                 for (i=incr; i<n; i++ )
94                 {
95                         j = i - incr;
96                         while (j>=0 )
97                         {
98                                 if (strncmp(list[j], list[j+incr], 12) > 0)
99                                 {
100                                         memcpy( t, list[j], 13 );
101                                         memcpy( list[j], list[j+incr], 13 );
102                                         memcpy( list[j+incr], t, 13 );
103                                         j -= incr;
104                                 }
105                                 else
106                                         break;
107                         }
108                 }
109                 incr = incr / 2;
110         }
111 }
112
113
114 int SingleDrive()
115 {
116         int FloppyPresent, FloppyNumber;
117         unsigned char b;
118
119         b = *((unsigned char *)0x410);
120
121         FloppyPresent = b & 1;
122         FloppyNumber = ((b&0xC0)>>6)+1;
123         if (FloppyPresent && (FloppyNumber==1) )
124                 return 1;
125         else
126                 return 0;
127 }
128
129 void SetFloppy(int d)
130 {
131         if (SingleDrive())
132         {
133         if (d==1)
134                 *((unsigned char *)0x504) = 0;
135         else if (d==2)
136                 *((unsigned char *)0x504) = 1;
137         }
138 }
139
140
141 void file_capitalize( char * s )
142 {
143         while( *s++ = toupper(*s) );
144 }
145
146
147 // Changes to a drive if valid.. 1=A, 2=B, etc
148 // If flag, then changes to it.
149 // Returns 0 if not-valid, 1 if valid.
150 int file_chdrive( int DriveNum, int flag )
151 {
152         unsigned NumDrives, n, org;
153         int Valid = 0;
154
155         if (!flag)
156                 _dos_getdrive( &org );
157
158         _dos_setdrive( DriveNum, &NumDrives );
159         _dos_getdrive( &n );
160
161         if (n == DriveNum )
162                 Valid = 1;
163
164         if ( (!flag) && (n != org) )
165                 _dos_setdrive( org, &NumDrives );
166
167         return Valid;
168 }
169
170
171 // Changes to directory in dir.  Even drive is changed.
172 // Returns 1 if failed.
173 //  0 = Changed ok.
174 //  1 = Invalid disk drive.
175 //  2 = Invalid directory.
176
177 int file_chdir( char * dir )
178 {
179         int e;
180         char OriginalDirectory[100];
181         char * Drive, * Path;
182         char NoDir[] = "\.";
183
184         getcwd( OriginalDirectory, 100 );
185
186         file_capitalize( dir );
187
188         Drive = strchr(dir, ':');
189
190         if (Drive)
191         {
192                 if (!file_chdrive( *(Drive - 1) - 'A' + 1, 1))
193                         return 1;
194
195                 Path = Drive+1;
196
197                 SetFloppy(*(Drive - 1) - 'A' + 1);
198         }
199         else
200         {
201                 Path = dir;
202
203         }
204
205         if (!(*Path))
206         {
207                 Path = NoDir;
208         }
209
210         // This chdir might get a critical error!
211         e = chdir( Path );
212         if (e)
213         {
214                 file_chdrive( OriginalDirectory[0] - 'A'+1, 1 );
215                 return 2;
216         }
217
218         return 0;
219
220 }
221
222
223 int file_getdirlist( int MaxNum, char list[][13] )
224 {
225         struct find_t find;
226         int NumDirs = 0, i, CurDrive;
227         char cwd[129];
228         MaxNum = MaxNum;
229
230         getcwd(cwd, 128 );
231
232         if (strlen(cwd) >= 4)
233         {
234                 sprintf( list[NumDirs++], ".." );
235         }
236
237         CurDrive = cwd[0] - 'A' + 1;
238
239         if( !_dos_findfirst( "*.", _A_SUBDIR, &find ) )
240         {
241                 if ( find.attrib & _A_SUBDIR )  {
242                         if (strcmp( "..", find.name) && strcmp( ".", find.name))
243                                 strncpy(list[NumDirs++], find.name, 13 );
244                 }
245
246                 while( !_dos_findnext( &find ) )
247                 {
248                         if ( find.attrib & _A_SUBDIR )  {
249                                 if (strcmp( "..", find.name) && strcmp( ".", find.name))
250                                 {
251                                         if (NumDirs==74)
252                                         {
253                                                 MessageBox( -2,-2, 1, "Only the first 74 directories will be displayed.", "Ok" );
254                                                 break;
255                                         } else {
256                                                 strncpy(list[NumDirs++], find.name, 13 );
257                                         }
258                                 }
259                         }
260                 }
261         }
262
263         file_sort( NumDirs, list );
264
265         for (i=1; i<=26; i++ )
266         {
267                 if (file_chdrive(i,0) && (i!=CurDrive))
268                 {
269                         if (!((i==2) && SingleDrive()))
270                                 sprintf( list[NumDirs++], "%c:", i+'A'-1 );
271                 }
272         }
273
274         return NumDirs;
275 }
276
277 int file_getfilelist( int MaxNum, char list[][13], char * filespec )
278 {
279         struct find_t find;
280         int NumFiles = 0;
281
282         MaxNum = MaxNum;
283
284         if( !_dos_findfirst( filespec, 0, &find ) )
285         {
286                 //if ( !(find.attrib & _A_SUBDIR) )
287                         strncpy(list[NumFiles++], find.name, 13 );
288
289                 while( !_dos_findnext( &find ) )
290                 {
291                         //if ( !(find.attrib & _A_SUBDIR) )
292                         //{
293                                 if (NumFiles==300)
294                                 {
295                                         MessageBox( -2,-2, 1, "Only the first 300 files will be displayed.", "Ok" );
296                                         break;
297                                 } else {
298                                         strncpy(list[NumFiles++], find.name, 13 );
299                                 }
300                         //}
301
302                 }
303         }
304
305         file_sort( NumFiles, list );
306
307         return NumFiles;
308 }
309
310 static int FirstTime = 1;
311 static char CurDir[128];
312
313 int ui_get_filename( char * filename, char * Filespec, char * message  )
314 {
315         FILE * TempFile;
316         int NumFiles, NumDirs,i;
317         char InputText[100];
318         char Spaces[35];
319         char ErrorMessage[100];
320         UI_WINDOW * wnd;
321         UI_GADGET_BUTTON * Button1, * Button2, * HelpButton;
322         UI_GADGET_LISTBOX * ListBox1;
323         UI_GADGET_LISTBOX * ListBox2;
324         UI_GADGET_INPUTBOX * UserFile;
325         int new_listboxes;
326
327         char drive[ _MAX_DRIVE ];
328         char dir[ _MAX_DIR ];
329         char fname[ _MAX_FNAME ];
330         char ext[ _MAX_EXT ];
331         char fulldir[ _MAX_DIR + _MAX_DRIVE ];
332         char fullfname[ _MAX_FNAME + _MAX_EXT ];
333
334
335         char OrgDir[128];
336
337         getcwd( OrgDir, 128 );
338
339         if (FirstTime)
340                 getcwd( CurDir, 128 );
341         FirstTime=0;
342
343         file_chdir( CurDir );
344         
345         //MessageBox( -2,-2, 1,"DEBUG:0", "Ok" );
346         for (i=0; i<35; i++)
347                 Spaces[i] = ' ';
348         Spaces[34] = 0;
349
350         NumFiles = file_getfilelist( 300, filename_list, Filespec );
351
352         NumDirs = file_getdirlist( 100, directory_list );
353
354         wnd = ui_open_window( 200, 100, 400, 370, WIN_DIALOG );
355
356         ui_wprintf_at( wnd, 10, 5, message );
357
358         _splitpath( filename, drive, dir, fname, ext );
359
360         sprintf( InputText, "%s%s", fname, ext );
361
362         ui_wprintf_at( wnd, 20, 32,"N&ame" );
363         UserFile  = ui_add_gadget_inputbox( wnd, 60, 30, 40, 40, InputText );
364
365         ui_wprintf_at( wnd, 20, 86,"&Files" );
366         ui_wprintf_at( wnd, 210, 86,"&Dirs" );
367
368         ListBox1 = ui_add_gadget_listbox( wnd,  20, 110, 125, 200, NumFiles, filename_list, 13 );
369         ListBox2 = ui_add_gadget_listbox( wnd, 210, 110, 100, 200, NumDirs, directory_list, 13 );
370
371         Button1 = ui_add_gadget_button( wnd,     20, 330, 60, 25, "Ok", NULL );
372         Button2 = ui_add_gadget_button( wnd,    100, 330, 60, 25, "Cancel", NULL );
373         HelpButton = ui_add_gadget_button( wnd, 180, 330, 60, 25, "Help", NULL );
374
375         wnd->keyboard_focus_gadget = (UI_GADGET *)UserFile;
376
377         Button1->hotkey = KEY_CTRLED + KEY_ENTER;
378         Button2->hotkey = KEY_ESC;
379         HelpButton->hotkey = KEY_F1;
380         ListBox1->hotkey = KEY_ALTED + KEY_F;
381         ListBox2->hotkey = KEY_ALTED + KEY_D;
382         UserFile->hotkey = KEY_ALTED + KEY_A;
383
384         ui_gadget_calc_keys(wnd);
385
386         ui_wprintf_at( wnd, 20, 60, "%s", Spaces );
387         ui_wprintf_at( wnd, 20, 60, "%s", CurDir );
388
389         new_listboxes = 0;
390
391         while( 1 )
392         {
393                 ui_mega_process();
394                 ui_window_do_gadgets(wnd);
395
396                 if ( Button2->pressed )
397                 {
398                         file_chdir( OrgDir );
399                         ui_close_window(wnd);
400                         return 0;
401                 }
402
403                 if ( HelpButton->pressed )
404                         MessageBox( -1, -1, 1, "Sorry, no help is available!", "Ok" );
405
406                 if (ListBox1->moved || new_listboxes)
407                 {
408                         if (ListBox1->current_item >= 0 )
409                         {
410                                 strcpy(UserFile->text, filename_list[ListBox1->current_item] );
411                                 UserFile->position = strlen(UserFile->text);
412                                 UserFile->oldposition = UserFile->position;
413                                 UserFile->status=1;
414                                 UserFile->first_time = 1;
415                         }
416                 }
417
418                 if (ListBox2->moved || new_listboxes)
419                 {
420                         if (ListBox2->current_item >= 0 )
421                         {
422                                 if (strrchr( directory_list[ListBox2->current_item], ':' ))
423                                         sprintf( UserFile->text, "%s%s", directory_list[ListBox2->current_item], Filespec );
424                                 else
425                                         sprintf( UserFile->text, "%s\\%s", directory_list[ListBox2->current_item], Filespec );
426                                 UserFile->position = strlen(UserFile->text);
427                                 UserFile->oldposition = UserFile->position;
428                                 UserFile->status=1;
429                                 UserFile->first_time = 1;
430                         }
431                 }
432                 new_listboxes = 0;
433
434                 if (Button1->pressed || UserFile->pressed || (ListBox1->selected_item > -1 ) || (ListBox2->selected_item > -1 ))
435                 {
436                         ui_mouse_hide();
437
438                         if (ListBox2->selected_item > -1 )      {
439                                 if (strrchr( directory_list[ListBox2->selected_item], ':' ))
440                                         sprintf( UserFile->text, "%s%s", directory_list[ListBox2->selected_item], Filespec );
441                                 else
442                                         sprintf( UserFile->text, "%s\\%s", directory_list[ListBox2->selected_item], Filespec );
443                         }
444
445                         error_mode = 1; // Critical error handler automatically fails.
446
447                         TempFile = fopen( UserFile->text, "r" );
448                         if (TempFile)
449                         {
450                                 // Looks like a valid filename that already exists!
451                                 fclose( TempFile );
452                                 break;
453                         }
454
455                         // File doesn't exist, but can we create it?
456                         TempFile = fopen( UserFile->text, "w" );
457                         if (TempFile)
458                         {
459                                 // Looks like a valid filename!
460                                 fclose( TempFile );
461                                 remove( UserFile->text );
462                                 break;
463                         }
464
465                         _splitpath( UserFile->text, drive, dir, fname, ext );
466                         sprintf( fullfname, "%s%s", fname, ext );
467
468                         //mprintf( 0, "----------------------------\n" );
469                         //mprintf( 0, "Full text: '%s'\n", UserFile->text );
470                         //mprintf( 0, "Drive: '%s'\n", drive );
471                         //mprintf( 0, "Dir: '%s'\n", dir );
472                         //mprintf( 0, "Filename: '%s'\n", fname );
473                         //mprintf( 0, "Extension: '%s'\n", ext );
474                         //mprintf( 0, "Full dir: '%s'\n", fulldir );
475                         //mprintf( 0, "Full fname: '%s'\n", fname );
476
477                         if (strrchr( fullfname, '?' ) || strrchr( fullfname, '*' ) )    
478                         {
479                                 sprintf( fulldir, "%s%s.", drive, dir );
480                         } else {
481                                 sprintf( fullfname, "%s", Filespec );
482                                 sprintf( fulldir, "%s", UserFile->text );
483                         }
484
485                         //mprintf( 0, "----------------------------\n" );
486                         //mprintf( 0, "Full dir: '%s'\n", fulldir );
487                         //mprintf( 0, "Full fname: '%s'\n", fullfname );
488
489                         if (file_chdir( fulldir )==0)
490                         {
491                                 NumFiles = file_getfilelist( 300, filename_list, fullfname );
492
493                                 strcpy(UserFile->text, fullfname );
494                                 UserFile->position = strlen(UserFile->text);
495                                 UserFile->oldposition = UserFile->position;
496                                 UserFile->status=1;
497                                 UserFile->first_time = 1;
498
499                                 NumDirs = file_getdirlist( 100, directory_list );
500
501                                 ui_listbox_change( wnd, ListBox1, NumFiles, filename_list, 13 );
502                                 ui_listbox_change( wnd, ListBox2, NumDirs, directory_list, 13 );
503                                 new_listboxes = 0;
504
505                                 getcwd( CurDir, 35 );
506                                 ui_wprintf_at( wnd, 20, 60, "%s", Spaces );
507                                 ui_wprintf_at( wnd, 20, 60, "%s", CurDir );
508
509                                 i = TICKER;
510                                 while ( TICKER < i+2 );
511
512                         }else {
513                                 sprintf(ErrorMessage, "Error changing to directory '%s'", fulldir );
514                                 MessageBox( -2, -2, 1, ErrorMessage, "Ok" );
515                                 UserFile->first_time = 1;
516
517                         }
518
519                         error_mode = 0;
520
521                         ui_mouse_show();
522
523                 }
524         }
525
526         //key_flush();
527
528         _splitpath( UserFile->text, drive, dir, fname, ext );
529         sprintf( fulldir, "%s%s.", drive, dir );
530         sprintf( fullfname, "%s%s", fname, ext );
531         
532         if ( strlen(fulldir) > 1 )
533                 file_chdir( fulldir );
534         
535         getcwd( CurDir, 35 );
536                 
537         if ( strlen(CurDir) > 0 )
538         {
539                         if ( CurDir[strlen(CurDir)-1] == '\\' )
540                                 CurDir[strlen(CurDir)-1] = 0;
541         }
542                 
543         sprintf( filename, "%s\\%s", CurDir, fullfname );
544         //MessageBox( -2, -2, 1, filename, "Ok" );
545         
546         file_chdir( OrgDir );
547                 
548         ui_close_window(wnd);
549
550         return 1;
551 }
552
553
554
555 int ui_get_file( char * filename, char * Filespec  )
556 {
557         int x, i, NumFiles;
558         char * text[200];
559
560         NumFiles = file_getfilelist( 200, filename_list, Filespec );
561
562         for (i=0; i< NumFiles; i++ )
563         {
564                 MALLOC( text[i], char, 15 );
565                 strcpy(text[i], filename_list[i] );
566         }
567
568         x = MenuX( -1, -1, NumFiles, text );
569
570         if ( x > 0 )
571                 strcpy(filename, filename_list[x-1] );
572
573         for (i=0; i< NumFiles; i++ )
574         {
575                 free( text[i] );
576         }
577
578         if ( x>0 )
579                 return 1;
580         else
581                 return 0;
582
583 }
584