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