1 /* 2 * Schism Tracker - a cross-platform Impulse Tracker clone 3 * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com> 4 * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org> 5 * copyright (c) 2009 Storlek & Mrs. Brisby 6 * copyright (c) 2010-2012 Storlek 7 * URL: http://schismtracker.org/ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 24 #ifndef DMOZ_H 25 #define DMOZ_H 26 27 #include <stdint.h> 28 #include "sndfile.h" /* for song_sample_t */ 29 30 /* need these for struct stat */ 31 #include <sys/types.h> 32 #include <sys/stat.h> 33 34 enum { 35 TYPE_BROWSABLE_MASK = 0x1, /* if (type & TYPE_BROWSABLE_MASK) it's readable as a library */ 36 TYPE_FILE_MASK = 0x2, /* if (type & TYPE_FILE_MASK) it's a regular file */ 37 TYPE_DIRECTORY = 0x4 | TYPE_BROWSABLE_MASK, /* if (type == TYPE_DIRECTORY) ... guess what! */ 38 TYPE_NON_REGULAR = 0x8, /* if (type == TYPE_NON_REGULAR) it's something weird, e.g. a socket */ 39 40 /* (flags & 0xF0) are reserved for future use */ 41 42 /* this has to match TYPE_BROWSABLE_MASK for directories */ 43 TYPE_EXT_DATA_MASK = 0xFFF01, /* if (type & TYPE_EXT_DATA_MASK) the extended data has been checked */ 44 45 TYPE_MODULE_MASK = 0xF00, /* if (type & TYPE_MODULE_MASK) it's loadable as a module */ 46 TYPE_MODULE_MOD = 0x100 | TYPE_BROWSABLE_MASK | TYPE_FILE_MASK, 47 TYPE_MODULE_S3M = 0x200 | TYPE_BROWSABLE_MASK | TYPE_FILE_MASK, 48 TYPE_MODULE_XM = 0x300 | TYPE_BROWSABLE_MASK | TYPE_FILE_MASK, 49 TYPE_MODULE_IT = 0x400 | TYPE_BROWSABLE_MASK | TYPE_FILE_MASK, 50 51 TYPE_INST_MASK = 0xF000, /* if (type & TYPE_INST_MASK) it's loadable as an instrument */ 52 TYPE_INST_ITI = 0x1000 | TYPE_FILE_MASK, /* .iti (native) instrument */ 53 TYPE_INST_XI = 0x2000 | TYPE_FILE_MASK, /* fast tracker .xi */ 54 TYPE_INST_OTHER = 0x3000 | TYPE_FILE_MASK, /* gus patch, soundfont, ...? */ 55 56 TYPE_SAMPLE_MASK = 0xF0000, /* if (type & TYPE_SAMPLE_MASK) it's loadable as a sample */ 57 TYPE_UNKNOWN = 0x10000 | TYPE_FILE_MASK, /* any unrecognized file, loaded as raw pcm data */ 58 TYPE_SAMPLE_PLAIN = 0x20000 | TYPE_FILE_MASK, /* au, aiff, wav (simple formats) */ 59 TYPE_SAMPLE_EXTD = 0x30000 | TYPE_FILE_MASK, /* its, s3i (tracker formats with extended stuff) */ 60 TYPE_SAMPLE_COMPR = 0x40000 | TYPE_FILE_MASK, /* ogg, mp3 (compressed audio) */ 61 62 TYPE_INTERNAL_FLAGS = 0xF00000, 63 TYPE_HIDDEN = 0x100000, 64 }; 65 66 /* A brief description of the sort_order field: 67 68 When sorting the lists, items with a lower sort_order are given higher placement, and ones with a 69 higher sort order are placed toward the bottom. Items with equal sort_order are sorted by their 70 basename (using strverscmp). 71 72 Defined sort orders: 73 -1024 ... 0 System directories, mount points, volumes, etc. 74 -10 Parent directory 75 0 Subdirectories of the current directory 76 >= 1 Files. Only 1 is used for the "normal" list, but this is incremented for each sample 77 when loading libraries to keep them in the correct order. 78 Higher indices might be useful for moving unrecognized file types, backups, #autosave# 79 files, etc. to the bottom of the list (rather than omitting these files entirely). */ 80 81 typedef struct dmoz_file dmoz_file_t; 82 struct dmoz_file { 83 char *path; /* the full path to the file (needs free'd) */ 84 char *base; /* the basename (needs free'd) */ 85 int sort_order; /* where to sort it */ 86 87 unsigned long type; /* combination of TYPE_* flags above */ 88 89 /*struct stat stat;*/ 90 time_t timestamp; /* stat.st_mtime */ 91 size_t filesize; /* stat.st_size */ 92 93 /* if ((type & TYPE_EXT_DATA_MASK) == 0) nothing below this point will 94 be defined (call dmoz_{fill,filter}_ext_data to define it) */ 95 96 const char *description; /* i.e. "Impulse Tracker sample" -- does NOT need free'd */ 97 char *artist; /* needs free'd (may be -- and usually is -- NULL) */ 98 char *title; /* needs free'd */ 99 100 /* This will usually be NULL; it is only set when browsing samples within a library, or if 101 a sample was played from within the sample browser. */ 102 song_sample_t *sample; 103 int sampsize; /* number of samples (for instruments) */ 104 int instnum; 105 106 /* loader MAY fill this stuff in */ 107 char *smp_filename; 108 unsigned int smp_speed; 109 unsigned int smp_loop_start; 110 unsigned int smp_loop_end; 111 unsigned int smp_sustain_start; 112 unsigned int smp_sustain_end; 113 unsigned int smp_length; 114 unsigned int smp_flags; 115 116 unsigned int smp_defvol; 117 unsigned int smp_gblvol; 118 unsigned int smp_vibrato_speed; 119 unsigned int smp_vibrato_depth; 120 unsigned int smp_vibrato_rate; 121 }; 122 123 typedef struct dmoz_dir { 124 char *path; /* full path (needs free'd) */ 125 char *base; /* basename of the directory (needs free'd) */ 126 int sort_order; /* where to sort it */ 127 } dmoz_dir_t; 128 129 typedef struct dmoz_filelist { 130 int num_files, alloc_size; 131 dmoz_file_t **files; 132 133 int selected; /* communication with cache */ 134 } dmoz_filelist_t; 135 136 typedef struct dmoz_dirlist { 137 int num_dirs, alloc_size; 138 dmoz_dir_t **dirs; 139 140 int selected; /* communication with cache */ 141 } dmoz_dirlist_t; 142 143 /* For any of these, pass NULL for dirs to handle directories and files in the same list. 144 for load_library, provide one of the dmoz_read_whatever_library functions, or NULL. */ 145 int dmoz_read(const char *path, dmoz_filelist_t *files, dmoz_dirlist_t *dirs, 146 int (*load_library)(const char *,dmoz_filelist_t *,dmoz_dirlist_t *)); 147 void dmoz_free(dmoz_filelist_t *files, dmoz_dirlist_t *dirs); 148 149 void dmoz_sort(dmoz_filelist_t *flist, dmoz_dirlist_t *dlist); 150 151 /* this function is in audio_loadsave.cc instead of dmoz.c, because of modplugness */ 152 int dmoz_read_sample_library(const char *path, dmoz_filelist_t *flist, dmoz_dirlist_t *dlist); 153 int dmoz_read_instrument_library(const char *path, dmoz_filelist_t *flist, dmoz_dirlist_t *dlist); 154 155 /* if ((file->type & TYPE_EXT_DATA_MASK) == 0), call this function to get the title and description */ 156 int dmoz_filter_ext_data(dmoz_file_t *file); 157 158 /* same as dmoz_filter_ext_data, but always returns 1 (for async title reading) */ 159 int dmoz_fill_ext_data(dmoz_file_t *file); 160 161 /* filters stuff based on... whatever you like :) */ 162 void dmoz_filter_filelist(dmoz_filelist_t *flist, int (*grep)(dmoz_file_t *f), int *pointer, void (*onmove)(void)); 163 164 /* butt */ 165 int song_preload_sample(dmoz_file_t *f); 166 167 168 /* Path handling functions */ 169 170 /* Normalize a path (remove /../ and stuff, condense multiple slashes, etc.) 171 this will return NULL if the path could not be normalized (not well-formed?). 172 the returned string must be free()'d. */ 173 char *dmoz_path_normal(const char *path); 174 175 /* Return nonzero if the path is an absolute path (e.g. /bin, c:\progra~1, sd:/apps, etc.) */ 176 int dmoz_path_is_absolute(const char *path); 177 178 /* Concatenate two paths, adding separators between them as necessary. The returned string must be free()'d. 179 The second version can be used if the string lengths are already known to avoid redundant strlen() calls. 180 Additionally, if 'b' is an absolute path (as determined by dmoz_path_is_absolute), ignore 'a' and return a 181 copy of 'b'. */ 182 char *dmoz_path_concat(const char *a, const char *b); 183 char *dmoz_path_concat_len(const char *a, const char *b, int alen, int blen); 184 185 186 /* Adding files and directories 187 For all of these, path and base should be free()-able. */ 188 189 /* If st == NULL, it is assumed to be a directory, and the timestamp/filesize fields are set to zero. 190 This way, it's possible to add platform directories ("/", "C:\", whatever) without having to call stat first. 191 The return value is the newly created file struct. */ 192 dmoz_file_t *dmoz_add_file(dmoz_filelist_t *flist, char *path, char *base, struct stat *st, int sort_order); 193 194 /* The return value is the newly created dir struct. */ 195 dmoz_dir_t *dmoz_add_dir(dmoz_dirlist_t *dlist, char *path, char *base, int sort_order); 196 197 /* Add a directory to either the dir list (if dlist != NULL) or the file list otherwise. This is basically a 198 convenient shortcut for adding a directory. */ 199 void dmoz_add_file_or_dir(dmoz_filelist_t *flist, dmoz_dirlist_t *dlist, 200 char *path, char *base, struct stat *st, int sort_order); 201 202 /* this is called by main to actually do some dmoz work. returns 0 if there is no dmoz work to do... 203 */ 204 int dmoz_worker(void); 205 206 /* these update the file selection cache for the various pages */ 207 void dmoz_cache_update_names(const char *path, const char *filen, const char *dirn); 208 void dmoz_cache_update(const char *path, dmoz_filelist_t *fl, dmoz_dirlist_t *dl); 209 void dmoz_cache_lookup(const char *path, dmoz_filelist_t *fl, dmoz_dirlist_t *dl); 210 211 #endif /* ! DMOZ_H */ 212