home *** CD-ROM | disk | FTP | other *** search
- //
- // GOATTRACKER v2 file selector
- //
-
- #define GFILE_C
-
- #ifdef __WIN32__
- #include <windows.h>
- #endif
-
- #include "goattrk2.h"
-
- DIRENTRY direntry[MAX_DIRFILES];
-
- void initpaths(void)
- {
- int c;
-
- for (c = 0; c < MAX_DIRFILES; c++)
- direntry[c].name = NULL;
-
- memset(loadedsongfilename, 0, sizeof loadedsongfilename);
- memset(songfilename, 0, sizeof songfilename);
- memset(instrfilename, 0, sizeof instrfilename);
- memset(songpath, 0, sizeof songpath);
- memset(instrpath, 0, sizeof instrpath);
- memset(packedpath, 0, sizeof packedpath);
- strcpy(songfilter, "*.sng");
- strcpy(instrfilter, "*.ins");
-
- getcwd(songpath, MAX_PATHNAME);
- strcpy(instrpath, songpath);
- strcpy(packedpath, songpath);
- }
-
- int fileselector(char *name, char *path, char *filter, char *title, int filemode)
- {
- int c, d, scrrep;
- int color;
- int files;
- int filepos = 0;
- int fileview = 0;
- int lastclick = 0;
- int lastfile = 0;
- int lowest;
- int exitfilesel;
-
- DIR *dir;
- struct dirent *de;
- struct stat st;
- #ifdef __WIN32__
- char drivestr[] = "A:\\";
- char driveexists[26];
- #endif
- char cmpbuf[MAX_PATHNAME];
- char tempname[MAX_PATHNAME];
-
- // Set initial path (if any)
- if (strlen(path)) chdir(path);
-
- // Scan for all existing drives
- #ifdef __WIN32__
- for (c = 0; c < 26; c++)
- {
- drivestr[0] = 'A'+c;
- if (GetDriveType(drivestr) > 1) driveexists[c] = 1;
- else driveexists[c] = 0;
- }
- #endif
-
- // Read new directory
- NEWPATH:
- getcwd(path, MAX_PATHNAME);
- files = 0;
- // Deallocate old names
- for (c = 0; c < MAX_DIRFILES; c++)
- {
- if (direntry[c].name)
- {
- free(direntry[c].name);
- direntry[c].name = NULL;
- }
- }
- #ifdef __WIN32__
- // Create drive letters
- for (c = 0; c < 26; c++)
- {
- if (driveexists[c])
- {
- drivestr[0] = 'A'+c;
- direntry[files].name = strdup(drivestr);
- direntry[files].attribute = 2;
- files++;
- }
- }
- #endif
-
- // Process directory
- dir = opendir(".");
- if (dir)
- {
- char *filtptr = strstr(filter, "*");
- if (!filtptr) filtptr = filter;
- else filtptr++;
- for (c = 0; c < strlen(filter); c++)
- filter[c] = tolower(filter[c]);
-
- while ((de = readdir(dir)))
- {
- if ((files < MAX_DIRFILES) && (strlen(de->d_name) < MAX_FILENAME))
- {
- direntry[files].name = strdup(de->d_name);
- direntry[files].attribute = 0;
- stat(de->d_name, &st);
- if (st.st_mode & S_IFDIR)
- {
- direntry[files].attribute = 1;
- files++;
- }
- else
- {
- int c;
- // If a file, must match filter
- strcpy(cmpbuf, de->d_name);
- if ((!strcmp(filtptr, "*")) || (!strcmp(filtptr, ".*")))
- files++;
- else
- {
- for (c = 0; c < strlen(cmpbuf); c++)
- cmpbuf[c] = tolower(cmpbuf[c]);
- if (strstr(cmpbuf, filtptr))
- files++;
- else
- {
- free(direntry[files].name);
- direntry[files].name = NULL;
- }
- }
- }
- }
- }
- closedir(dir);
- }
- // Sort the filelist in a most horrible fashion
- for (c = 0; c < files; c++)
- {
- lowest = c;
- for (d = c+1; d < files; d++)
- {
- if (direntry[d].attribute < direntry[lowest].attribute)
- {
- lowest = d;
- }
- else
- {
- if (direntry[d].attribute == direntry[lowest].attribute)
- {
- if (cmpname(direntry[d].name, direntry[lowest].name) < 0)
- {
- lowest = d;
- }
- }
- }
- }
- if (lowest != c)
- {
- DIRENTRY swaptemp = direntry[c];
- direntry[c] = direntry[lowest];
- direntry[lowest] = swaptemp;
- }
- }
-
- // Search for the current filename
- fileview = 0;
- filepos = 0;
- for (c = 0; c < files; c++)
- {
- if ((!direntry[c].attribute) && (!cmpname(name, direntry[c].name)))
- {
- filepos = c;
- }
- }
-
- exitfilesel = -1;
- while (exitfilesel < 0)
- {
- int cc = cursorcolortable[cursorflash];
- if (cursorflashdelay >= 6)
- {
- cursorflashdelay %= 6;
- cursorflash++;
- cursorflash &= 3;
- }
- fliptoscreen();
- getkey();
- if (lastclick) lastclick--;
-
- if (win_quitted)
- {
- exitprogram = 1;
- for (c = 0; c < MAX_DIRFILES; c++)
- {
- if (direntry[c].name)
- {
- free(direntry[c].name);
- direntry[c].name = NULL;
- }
- }
- return 0;
- }
-
- if (mouseb)
- {
- // Cancel (click outside)
- if ((mousey < 3) || (mousey > 3+VISIBLEFILES+6) || (mousex <= 4+10) || (mousex >= 75+10))
- {
- if ((!prevmouseb) && (lastclick)) exitfilesel = 0;
- }
-
- // Select dir,name,filter
- if ((mousey >= 3+VISIBLEFILES+3) && (mousey <= 3+VISIBLEFILES+5) && (mousex >= 14+10) && (mousex <= 73+10))
- {
- filemode = mousey - (3+VISIBLEFILES+3) + 1;
- if ((filemode == 3) && (!prevmouseb) && (lastclick)) goto ENTERFILE;
- }
-
- // Select file from list
- if ((mousey >= 3) && (mousey <= 3+VISIBLEFILES+2) && (mousex >= 6+10) && (mousex <= 73+10))
- {
- filemode = 0;
- filepos = mousey - 4 - 1 + fileview;
- if (filepos < 0) filepos = 0;
- if (filepos > files-1) filepos = files - 1;
-
- if (!direntry[filepos].attribute)
- strcpy(name, direntry[filepos].name);
-
- if ((!prevmouseb) && (lastclick) && (lastfile == filepos)) goto ENTERFILE;
- }
- }
-
- if (!filemode)
- {
- if (((key >= '0') && (key <= '0')) || ((key >= 'a') && (key <= 'z')) || ((key >= 'A') && (key <= 'Z')))
- {
- char k = tolower(key);
- int oldfilepos = filepos;
-
- for (filepos = oldfilepos + 1; filepos < files; filepos++)
- if (tolower(direntry[filepos].name[0]) == k) break;
- if (filepos >= files)
- {
- for (filepos = 0; filepos < oldfilepos; filepos++)
- if (tolower(direntry[filepos].name[0]) == k) break;
- }
-
- if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name);
- }
- }
-
- switch(rawkey)
- {
- case KEY_ESC:
- exitfilesel = 0;
- break;
-
- case KEY_BACKSPACE:
- if (!filemode)
- {
- chdir("..");
- goto NEWPATH;
- }
- break;
-
- case KEY_HOME:
- if (!filemode)
- {
- filepos = 0;
- if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name);
- }
- break;
-
- case KEY_END:
- if (!filemode)
- {
- filepos = files-1;
- if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name);
- }
- break;
-
- case KEY_PGUP:
- for (scrrep = PGUPDNREPEAT; scrrep; scrrep--)
- {
- if ((!filemode) && (filepos > 0))
- {
- filepos--;
- if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name);
- }
- }
- break;
-
- case KEY_UP:
- if ((!filemode) && (filepos > 0))
- {
- filepos--;
- if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name);
- }
- break;
-
- case KEY_PGDN:
- for (scrrep = PGUPDNREPEAT; scrrep; scrrep--)
- {
- if ((!filemode) && (filepos < files-1))
- {
- filepos++;
- if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name);
- }
- }
- break;
-
- case KEY_DOWN:
- if ((!filemode) && (filepos < files-1))
- {
- filepos++;
- if (!direntry[filepos].attribute) strcpy(name, direntry[filepos].name);
- }
- break;
-
- case KEY_TAB:
- if (!shiftpressed)
- {
- filemode++;
- if (filemode > 3) filemode = 0;
- }
- else
- {
- filemode--;
- if (filemode < 0) filemode = 3;
- }
- break;
-
- case KEY_ENTER:
- ENTERFILE:
- switch(filemode)
- {
- case 0:
- switch (direntry[filepos].attribute)
- {
- case 0:
- strcpy(name, direntry[filepos].name);
- exitfilesel = 1;
- break;
-
- case 1:
- chdir(direntry[filepos].name);
- goto NEWPATH;
-
- case 2:
- strcpy(tempname, direntry[filepos].name);
- if (strlen(tempname))
- {
- if (tempname[strlen(tempname)-1] != '\\')
- strcat(tempname, "\\");
- }
- chdir(tempname);
- goto NEWPATH;
- }
- break;
-
- case 1:
- chdir(path);
- case 2:
- filemode = 0;
- goto NEWPATH;
-
- case 3:
- exitfilesel = 1;
- break;
- }
- break;
- }
-
- switch(filemode)
- {
- case 1:
- editstring(path, MAX_PATHNAME);
- break;
-
- case 2:
- editstring(filter, MAX_FILENAME);
- break;
-
- case 3:
- editstring(name, MAX_FILENAME);
- break;
- }
-
- // Validate filelist view
- if (filepos < fileview) fileview = filepos;
- if (filepos - fileview >= VISIBLEFILES) fileview = filepos - VISIBLEFILES + 1;
-
- // Refresh fileselector display
- if (isplaying()) printstatus();
- for (c = 0; c < VISIBLEFILES+7; c++)
- {
- printblank(50-(MAX_FILENAME+10)/2, 3+c, MAX_FILENAME+10);
- }
- drawbox(50-(MAX_FILENAME+10)/2, 3, 15, MAX_FILENAME+10, VISIBLEFILES+7);
- printblankc(50-(MAX_FILENAME+10)/2+1, 4, 15+16,MAX_FILENAME+8);
- printtext(50-(MAX_FILENAME+10)/2+1, 4, 15+16, title);
-
- for (c = 0; c < VISIBLEFILES; c++)
- {
- if ((fileview+c >= 0) && (fileview+c < files))
- {
- switch (direntry[fileview+c].attribute)
- {
- case 0:
- sprintf(textbuffer, "%-60s ", direntry[fileview+c].name);
- break;
-
- case 1:
- sprintf(textbuffer, "%-60s <DIR>", direntry[fileview+c].name);
- break;
-
- case 2:
- sprintf(textbuffer, "%-60s <DRV>", direntry[fileview+c].name);
- break;
- }
- }
- else
- {
- sprintf(textbuffer, " ");
- }
- color = CNORMAL;
- if ((fileview+c) == filepos) color = CEDIT;
- textbuffer[68] = 0;
- printtext(50-(MAX_FILENAME+10)/2+1, 5+c, color, textbuffer);
- if ((!filemode) && ((fileview+c) == filepos)) printbg(50-(MAX_FILENAME+10)/2+1, 5+c, cc, 68);
- }
-
- printtext(50-(MAX_FILENAME+10)/2+1, 6+VISIBLEFILES, 15, "PATH: ");
- sprintf(textbuffer, "%-60s", path);
- textbuffer[MAX_FILENAME] = 0;
- color = CNORMAL;
- if (filemode == 1) color = CEDIT;
- printtext(50-(MAX_FILENAME+10)/2+9, 6+VISIBLEFILES, color, textbuffer);
- if ((filemode == 1) && (strlen(path) < MAX_FILENAME)) printbg(50-(MAX_FILENAME+10)/2+9+strlen(path), 6+VISIBLEFILES, cc, 1);
-
- printtext(50-(MAX_FILENAME+10)/2+1, 7+VISIBLEFILES, 15, "FILTER: ");
- sprintf(textbuffer, "%-60s", filter);
- textbuffer[MAX_FILENAME] = 0;
- color = CNORMAL;
- if (filemode == 2) color = CEDIT;
- printtext(50-(MAX_FILENAME+10)/2+9, 7+VISIBLEFILES, color, textbuffer);
- if (filemode == 2) printbg(50-(MAX_FILENAME+10)/2+9+strlen(filter), 7+VISIBLEFILES, cc, 1);
-
- printtext(50-(MAX_FILENAME+10)/2+1, 8+VISIBLEFILES, 15, "NAME: ");
- sprintf(textbuffer, "%-60s", name);
- textbuffer[MAX_FILENAME] = 0;
- color = CNORMAL;
- if (filemode == 3) color = CEDIT;
- printtext(50-(MAX_FILENAME+10)/2+9, 8+VISIBLEFILES, color, textbuffer);
- if (filemode == 3) printbg(50-(MAX_FILENAME+10)/2+9+strlen(name), 8+VISIBLEFILES, cc, 1);
-
- if (win_quitted) exitfilesel = 0;
-
- if ((mouseb) && (!prevmouseb))
- {
- lastclick = DOUBLECLICKDELAY;
- lastfile = filepos;
- }
- }
-
- // Deallocate all used names
- for (c = 0; c < MAX_DIRFILES; c++)
- {
- if (direntry[c].name)
- {
- free(direntry[c].name);
- direntry[c].name = NULL;
- }
- }
-
- // Restore screen & exit
- printmainscreen();
- return exitfilesel;
- }
-
- void editstring(char *buffer, int maxlength)
- {
- int len = strlen(buffer);
-
- if (key)
- {
- if ((key >= 32) && (key < 256))
- {
- if (len < maxlength-1)
- {
- buffer[len] = key;
- buffer[len+1] = 0;
- }
- }
- if ((key == 8) && (len > 0))
- {
- buffer[len-1] = 0;
- }
- }
- }
-
- int cmpname(char *string1, char *string2)
- {
- for (;;)
- {
- unsigned char char1 = tolower(*string1++);
- unsigned char char2 = tolower(*string2++);
- if (char1 < char2) return -1;
- if (char1 > char2) return 1;
- if ((!char1) || (!char2)) return 0;
- }
- }
-
-
-