| version 1.6, 2005/03/18 09:23:11 | version 1.13, 2011/02/04 00:39:34 | 
| Line 1 | Line 1 | 
| #include        "compiler.h" | #include        "compiler.h" | 
| #include        "strres.h" | #include        "strres.h" | 
| #include        "dosio.h" | #include        "dosio.h" | 
| #include        "textfile.h" | #include        "textfile.h" | 
| #include        "midiout.h" | #include        "midiout.h" | 
|  | #if defined(SUPPORT_ARC) | 
|  | #include        "arc.h" | 
| #define CFG_MAXAMP              400 | #endif | 
| #define MAX_NAME                64 |  | 
|  |  | 
| enum { | #define CFG_MAXAMP              400 | 
| CFG_DIR          = 0, | #define MAX_NAME                64 | 
| CFG_SOURCE, |  | 
| CFG_DEFAULT, | enum { | 
| CFG_BANK, | CFG_DIR          = 0, | 
| CFG_DRUM | CFG_SOURCE, | 
| }; | CFG_DEFAULT, | 
|  | CFG_BANK, | 
| static const OEMCHAR str_dir[] = OEMTEXT("dir"); | CFG_DRUM | 
| static const OEMCHAR str_source[] = OEMTEXT("source"); | }; | 
| static const OEMCHAR str_default[] = OEMTEXT("default"); |  | 
| static const OEMCHAR str_bank[] = OEMTEXT("bank"); | static const OEMCHAR str_dir[] = OEMTEXT("dir"); | 
| static const OEMCHAR str_drumset[] = OEMTEXT("drumset"); | static const OEMCHAR str_source[] = OEMTEXT("source"); | 
| static const OEMCHAR *cfgstr[] = {str_dir, str_source, str_default, | static const OEMCHAR str_default[] = OEMTEXT("default"); | 
| str_bank, str_drumset}; | static const OEMCHAR str_bank[] = OEMTEXT("bank"); | 
|  | static const OEMCHAR str_drumset[] = OEMTEXT("drumset"); | 
| static const OEMCHAR str_amp[] = OEMTEXT("amp"); | static const OEMCHAR *cfgstr[] = {str_dir, str_source, str_default, | 
| static const OEMCHAR str_keep[] = OEMTEXT("keep"); | str_bank, str_drumset}; | 
| static const OEMCHAR str_note[] = OEMTEXT("note"); |  | 
| static const OEMCHAR str_pan[] = OEMTEXT("pan"); | static const OEMCHAR str_amp[] = OEMTEXT("amp"); | 
| static const OEMCHAR str_strip[] = OEMTEXT("strip"); | static const OEMCHAR str_keep[] = OEMTEXT("keep"); | 
| static const OEMCHAR str_left[] = OEMTEXT("left"); | static const OEMCHAR str_note[] = OEMTEXT("note"); | 
| static const OEMCHAR str_center[] = OEMTEXT("center"); | static const OEMCHAR str_pan[] = OEMTEXT("pan"); | 
| static const OEMCHAR str_right[] = OEMTEXT("right"); | static const OEMCHAR str_strip[] = OEMTEXT("strip"); | 
| static const OEMCHAR str_env[] = OEMTEXT("env"); | static const OEMCHAR str_left[] = OEMTEXT("left"); | 
| static const OEMCHAR str_loop[] = OEMTEXT("loop"); | static const OEMCHAR str_center[] = OEMTEXT("center"); | 
| static const OEMCHAR str_tail[] = OEMTEXT("tail"); | static const OEMCHAR str_right[] = OEMTEXT("right"); | 
| static const OEMCHAR file_timiditycfg[] = OEMTEXT("timidity.cfg"); | static const OEMCHAR str_env[] = OEMTEXT("env"); | 
|  | static const OEMCHAR str_loop[] = OEMTEXT("loop"); | 
|  | static const OEMCHAR str_tail[] = OEMTEXT("tail"); | 
| static void pathadd(MIDIMOD mod, const OEMCHAR *path) { | static const OEMCHAR file_timiditycfg[] = OEMTEXT("timidity.cfg"); | 
|  | static const OEMCHAR str_basedir[] = OEMTEXT("${basedir}"); | 
| _PATHLIST       pl; |  | 
| PATHLIST        p; |  | 
|  | static void VERMOUTHCL pathadd(MIDIMOD mod, const OEMCHAR *path) { | 
| ZeroMemory(&pl, sizeof(pl)); |  | 
| if (path) { | _PATHLIST       pl; | 
| pl.path[0] = '\0'; | PATHLIST        p; | 
| // separator change! |  | 
| file_catname(pl.path, path, NELEMENTS(pl.path)); | ZeroMemory(&pl, sizeof(pl)); | 
| if (path[0]) { | if (path) { | 
| file_setseparator(pl.path, NELEMENTS(pl.path)); | pl.path[0] = '\0'; | 
| } | // separator change! | 
| } | file_catname(pl.path, path, NELEMENTS(pl.path)); | 
|  | if (path[0]) { | 
| pl.next = mod->pathlist; | #if defined(SUPPORT_ARC) | 
| p = pl.next; | if (milstr_chr(pl.path, '#') == NULL) | 
| while(p) { | #endif | 
| if (!file_cmpname(p->path, pl.path)) { | file_setseparator(pl.path, NELEMENTS(pl.path)); | 
| return; | } | 
| } | } | 
| p = p->next; |  | 
| } | pl.next = mod->pathlist; | 
| p = (PATHLIST)listarray_append(mod->pathtbl, &pl); | p = pl.next; | 
| if (p) { | while(p) { | 
| mod->pathlist = p; | if (!file_cmpname(p->path, pl.path)) { | 
| } | return; | 
| } | } | 
|  | p = p->next; | 
| static int cfggetarg(OEMCHAR *str, OEMCHAR *arg[], int maxarg) { | } | 
|  | p = (PATHLIST)listarray_append(mod->pathtbl, &pl); | 
| int             ret; | if (p) { | 
| BOOL    quot; | mod->pathlist = p; | 
| OEMCHAR *p; | } | 
| OEMCHAR c; | } | 
|  |  | 
| ret = 0; | static void VERMOUTHCL pathaddex(MIDIMOD mod, const OEMCHAR *path) { | 
| while(maxarg--) { |  | 
| quot = FALSE; | OEMCHAR _path[MAX_PATH]; | 
| while(1) { |  | 
| c = *str; | if (milstr_memcmp(path, str_basedir)) { | 
| if ((c == 0) || (c == 0x23)) { | pathadd(mod, path); | 
| goto cga_done; | } | 
| } | else { | 
| if ((c < 0) || (c > 0x20)) { | file_cpyname(_path, file_getcd(str_null), NELEMENTS(_path)); | 
| break; | file_cutseparator(_path); | 
| } | file_catname(_path, path + 10, NELEMENTS(_path)); | 
| str++; | pathadd(mod, _path); | 
| } | } | 
| arg[ret++] = str; | } | 
| p = str; |  | 
| while(1) { | static int VERMOUTHCL cfggetarg(OEMCHAR *str, OEMCHAR *arg[], int maxarg) { | 
| c = *str; |  | 
| if (c == 0) { | int             ret; | 
| break; | BOOL    quot; | 
| } | OEMCHAR *p; | 
| str++; | OEMCHAR c; | 
| if (c == 0x22) { |  | 
| quot = !quot; | ret = 0; | 
| } | while(maxarg--) { | 
| else if (quot) { | quot = FALSE; | 
| *p++ = c; | while(1) { | 
| } | c = *str; | 
| else if (c == 0x23) { | if ((c == 0) || (c == 0x23)) { | 
| *p = '\0'; | goto cga_done; | 
| goto cga_done; | } | 
| } | if ((c < 0) || (c > 0x20)) { | 
| else if ((c < 0) || (c > 0x20)) { | break; | 
| *p++ = c; | } | 
| } | str++; | 
| else { | } | 
| break; | arg[ret++] = str; | 
| } | p = str; | 
| } | while(1) { | 
| *p = '\0'; | c = *str; | 
| } | if (c == 0) { | 
|  | break; | 
| cga_done: | } | 
| return(ret); | str++; | 
| } | if (c == 0x22) { | 
|  | quot = !quot; | 
| static OEMCHAR *seachr(const OEMCHAR *str, OEMCHAR sepa) { | } | 
|  | else if (quot) { | 
| OEMCHAR c; | *p++ = c; | 
|  | } | 
| while(1) { | else if (c == 0x23) { | 
| c = *str; | *p = '\0'; | 
| if (c == '\0') { | goto cga_done; | 
| break; | } | 
| } | else if ((c < 0) || (c > 0x20)) { | 
| if (c == sepa) { | *p++ = c; | 
| return((OEMCHAR *)str); | } | 
| } | else { | 
| str++; | break; | 
| } | } | 
| return(NULL); | } | 
| } | *p = '\0'; | 
|  | } | 
| enum { |  | 
| VAL_EXIST       = 1, | cga_done: | 
| VAL_SIGN        = 2 | return(ret); | 
| }; | } | 
|  |  | 
| static BRESULT cfggetval(const OEMCHAR *str, int *val) { | static OEMCHAR *VERMOUTHCL seachr(const OEMCHAR *str, OEMCHAR sepa) { | 
|  |  | 
| int             ret; | OEMCHAR c; | 
| int             flag; |  | 
| int             c; | while(1) { | 
|  | c = *str; | 
| ret = 0; | if (c == '\0') { | 
| flag = 0; | break; | 
| c = *str; | } | 
| if (c == '+') { | if (c == sepa) { | 
| str++; | return((OEMCHAR *)str); | 
| } | } | 
| else if (c == '-') { | str++; | 
| str++; | } | 
| flag |= VAL_SIGN; | return(NULL); | 
| } | } | 
| while(1) { |  | 
| c = *str++; | enum { | 
| c -= '0'; | VAL_EXIST       = 1, | 
| if ((unsigned)c < 10) { | VAL_SIGN        = 2 | 
| ret *= 10; | }; | 
| ret += c; |  | 
| flag |= VAL_EXIST; | static BRESULT VERMOUTHCL cfggetval(const OEMCHAR *str, int *val) { | 
| } |  | 
| else { | int             ret; | 
| break; | int             flag; | 
| } | int             c; | 
| } |  | 
| if (flag & VAL_EXIST) { | ret = 0; | 
| if (flag & VAL_SIGN) { | flag = 0; | 
| ret *= -1; | c = *str; | 
| } | if (c == '+') { | 
| if (val) { | str++; | 
| *val = ret; | } | 
| } | else if (c == '-') { | 
| return(SUCCESS); | str++; | 
| } | flag |= VAL_SIGN; | 
| else { | } | 
| return(FAILURE); | while(1) { | 
| } | c = *str++; | 
| } | c -= '0'; | 
|  | if ((unsigned)c < 10) { | 
|  | ret *= 10; | 
| // ---- | ret += c; | 
|  | flag |= VAL_EXIST; | 
| static void settone(MIDIMOD mod, int bank, int argc, OEMCHAR *argv[]) { | } | 
|  | else { | 
| int             val; | break; | 
| TONECFG tone; | } | 
| OEMCHAR *name; | } | 
| int             i; | if (flag & VAL_EXIST) { | 
| OEMCHAR *key; | if (flag & VAL_SIGN) { | 
| OEMCHAR *data; | ret *= -1; | 
| UINT8   flag; | } | 
|  | if (val) { | 
| if ((bank < 0) || (bank >= (MIDI_BANKS * 2)) || (argc < 2) || | *val = ret; | 
| (cfggetval(argv[0], &val) != SUCCESS) || (val < 0) || (val >= 128)) { | } | 
| return; | return(SUCCESS); | 
| } | } | 
| tone = mod->tonecfg[bank]; | else { | 
| if (tone == NULL) { | return(FAILURE); | 
| tone = (TONECFG)_MALLOC(sizeof(_TONECFG) * 128, "tone cfg"); | } | 
| if (tone == NULL) { | } | 
| return; |  | 
| } |  | 
| mod->tonecfg[bank] = tone; | // ---- | 
| ZeroMemory(tone, sizeof(_TONECFG) * 128); |  | 
| } | static void VERMOUTHCL settone(MIDIMOD mod, int bank, int argc, | 
| tone += val; | OEMCHAR *argv[]) { | 
| name = tone->name; |  | 
| if (name == NULL) { | int             val; | 
| name = (OEMCHAR *)listarray_append(mod->namelist, NULL); | TONECFG tone; | 
| tone->name = name; | OEMCHAR *name; | 
| } | int             i; | 
| if (name) { | OEMCHAR *key; | 
| name[0] = '\0'; | OEMCHAR *data; | 
| file_catname(name, argv[1], MAX_NAME);          // separator change! | UINT8   flag; | 
| } |  | 
| flag = TONECFG_EXIST; | if ((bank < 0) || (bank >= (MIDI_BANKS * 2)) || (argc < 2) || | 
| tone->amp = TONECFG_AUTOAMP; | (cfggetval(argv[0], &val) != SUCCESS) || (val < 0) || (val >= 128)) { | 
| tone->pan = TONECFG_VARIABLE; | return; | 
|  | } | 
| if (!(bank & 1)) {                                      // for tone | tone = mod->tonecfg[bank]; | 
| tone->note = TONECFG_VARIABLE; | if (tone == NULL) { | 
| } | tone = (TONECFG)_MALLOC(sizeof(_TONECFG) * 128, "tone cfg"); | 
| else {                                                          // for drums | if (tone == NULL) { | 
| flag |= TONECFG_NOLOOP | TONECFG_NOENV; | return; | 
| tone->note = (UINT8)val; | } | 
| } | mod->tonecfg[bank] = tone; | 
|  | ZeroMemory(tone, sizeof(_TONECFG) * 128); | 
| for (i=2; i<argc; i++) { | } | 
| key = argv[i]; | tone += val; | 
| data = seachr(key, '='); | name = tone->name; | 
| if (data == NULL) { | if (name == NULL) { | 
| continue; | name = (OEMCHAR *)listarray_append(mod->namelist, NULL); | 
| } | tone->name = name; | 
| *data++ = '\0'; | } | 
| if (!milstr_cmp(key, str_amp)) { | if (name) { | 
| if (cfggetval(data, &val) == SUCCESS) { | name[0] = '\0'; | 
| if (val < 0) { | file_catname(name, argv[1], MAX_NAME);          // separator change! | 
| val = 0; | } | 
| } | flag = TONECFG_EXIST; | 
| else if (val > CFG_MAXAMP) { | tone->amp = TONECFG_AUTOAMP; | 
| val = CFG_MAXAMP; | tone->pan = TONECFG_VARIABLE; | 
| } |  | 
| tone->amp = val; | if (!(bank & 1)) {                                      // for tone | 
| } | tone->note = TONECFG_VARIABLE; | 
| } | } | 
| else if (!milstr_cmp(key, str_keep)) { | else {                                                          // for drums | 
| if (!milstr_cmp(data, str_env)) { | flag |= TONECFG_NOLOOP | TONECFG_NOENV; | 
| flag &= ~TONECFG_NOENV; | tone->note = (UINT8)val; | 
| flag |= TONECFG_KEEPENV; | } | 
| } |  | 
| else if (!milstr_cmp(data, str_loop)) { | for (i=2; i<argc; i++) { | 
| flag &= ~TONECFG_NOLOOP; | key = argv[i]; | 
| } | data = seachr(key, '='); | 
| } | if (data == NULL) { | 
| else if (!milstr_cmp(key, str_note)) { | continue; | 
| if ((cfggetval(data, &val) == SUCCESS) && | } | 
| (val >= 0) && (val < 128)) { | *data++ = '\0'; | 
| tone->note = (UINT8)val; | if (!milstr_cmp(key, str_amp)) { | 
| } | if (cfggetval(data, &val) == SUCCESS) { | 
| } | if (val < 0) { | 
| else if (!milstr_cmp(key, str_pan)) { | val = 0; | 
| if (!milstr_cmp(data, str_left)) { | } | 
| val = 0; | else if (val > CFG_MAXAMP) { | 
| } | val = CFG_MAXAMP; | 
| else if (!milstr_cmp(data, str_center)) { | } | 
| val = 64; | tone->amp = val; | 
| } | } | 
| else if (!milstr_cmp(data, str_right)) { | } | 
| val = 127; | else if (!milstr_cmp(key, str_keep)) { | 
| } | if (!milstr_cmp(data, str_env)) { | 
| else if (cfggetval(data, &val) == SUCCESS) { | flag &= ~TONECFG_NOENV; | 
| if (val < -100) { | flag |= TONECFG_KEEPENV; | 
| val = -100; | } | 
| } | else if (!milstr_cmp(data, str_loop)) { | 
| else if (val > 100) { | flag &= ~TONECFG_NOLOOP; | 
| val = 100; | } | 
| } | } | 
| val = val + 100; | else if (!milstr_cmp(key, str_note)) { | 
| val *= 127; | if ((cfggetval(data, &val) == SUCCESS) && | 
| val += 100; | (val >= 0) && (val < 128)) { | 
| val /= 200; | tone->note = (UINT8)val; | 
| } | } | 
| else { | } | 
| continue; | else if (!milstr_cmp(key, str_pan)) { | 
| } | if (!milstr_cmp(data, str_left)) { | 
| tone->pan = (UINT8)val; | val = 0; | 
| } | } | 
| else if (!milstr_cmp(key, str_strip)) { | else if (!milstr_cmp(data, str_center)) { | 
| if (!milstr_cmp(data, str_env)) { | val = 64; | 
| flag &= ~TONECFG_KEEPENV; | } | 
| flag |= TONECFG_NOENV; | else if (!milstr_cmp(data, str_right)) { | 
| } | val = 127; | 
| else if (!milstr_cmp(data, str_loop)) { | } | 
| flag |= TONECFG_NOLOOP; | else if (cfggetval(data, &val) == SUCCESS) { | 
| } | if (val < -100) { | 
| else if (!milstr_cmp(data, str_tail)) { | val = -100; | 
| flag |= TONECFG_NOTAIL; | } | 
| } | else if (val > 100) { | 
| } | val = 100; | 
| } | } | 
| tone->flag = flag; | val = val + 100; | 
| } | val *= 127; | 
|  | val += 100; | 
|  | val /= 200; | 
| // ---- | } | 
|  | else { | 
| BRESULT cfgfile_getfile(MIDIMOD mod, const OEMCHAR *filename, | continue; | 
| OEMCHAR *path, int size) { | } | 
|  | tone->pan = (UINT8)val; | 
| PATHLIST        p; | } | 
| short           attr; | else if (!milstr_cmp(key, str_strip)) { | 
|  | if (!milstr_cmp(data, str_env)) { | 
| if ((filename == NULL) || (filename[0] == '\0') || | flag &= ~TONECFG_KEEPENV; | 
| (path == NULL) || (size == 0)) { | flag |= TONECFG_NOENV; | 
| goto fpgf_exit; | } | 
| } | else if (!milstr_cmp(data, str_loop)) { | 
| p = mod->pathlist; | flag |= TONECFG_NOLOOP; | 
| while(p) { | } | 
| file_cpyname(path, p->path, size); | else if (!milstr_cmp(data, str_tail)) { | 
| file_catname(path, filename, size); | flag |= TONECFG_NOTAIL; | 
| attr = file_attr(path); | } | 
| if (attr != -1) { | } | 
| return(SUCCESS); | } | 
| } | tone->flag = flag; | 
| p = p->next; | } | 
| } |  | 
|  |  | 
| fpgf_exit: | // ---- | 
| return(FAILURE); |  | 
| } | BRESULT VERMOUTHCL midimod_getfile(MIDIMOD mod, const OEMCHAR *filename, | 
|  | OEMCHAR *path, int size) { | 
| BRESULT cfgfile_load(MIDIMOD mod, const OEMCHAR *filename, int depth) { |  | 
|  | PATHLIST        p; | 
| TEXTFILEH       tfh; | short           attr; | 
| OEMCHAR         buf[1024]; |  | 
| int                     bank; | if ((filename == NULL) || (filename[0] == '\0') || | 
| int                     i; | (path == NULL) || (size == 0)) { | 
| int                     argc; | goto fpgf_exit; | 
| OEMCHAR         *argv[16]; | } | 
| int                     val; | p = mod->pathlist; | 
| UINT            cfg; | while(p) { | 
|  | file_cpyname(path, p->path, size); | 
| bank = -1; | file_catname(path, filename, size); | 
|  | #if defined(SUPPORT_ARC) | 
| if ((depth >= 16) || | attr = arcex_attr(path); | 
| (cfgfile_getfile(mod, filename, buf, NELEMENTS(buf)) != SUCCESS)) { | #else | 
| goto cfl_err; | attr = file_attr(path); | 
| } | #endif | 
| //      TRACEOUT(("open: %s", buf)); | if (attr != -1) { | 
| tfh = textfile_open(buf, 0x1000); | return(SUCCESS); | 
| if (tfh == NULL) { | } | 
| goto cfl_err; | p = p->next; | 
| } | } | 
| while(textfile_read(tfh, buf, NELEMENTS(buf)) == SUCCESS) { |  | 
| argc = cfggetarg(buf, argv, NELEMENTS(argv)); | fpgf_exit: | 
| if (argc < 2) { | return(FAILURE); | 
| continue; | } | 
| } |  | 
| cfg = 0; | static BRESULT VERMOUTHCL cfgfile_load(MIDIMOD mod, const OEMCHAR *filename, | 
| while(cfg < NELEMENTS(cfgstr)) { | int depth) { | 
| if (!milstr_cmp(argv[0], cfgstr[cfg])) { |  | 
| break; | TEXTFILEH       tfh; | 
| } | OEMCHAR         buf[1024]; | 
| cfg++; | int                     bank; | 
| } | int                     i; | 
| switch(cfg) { | int                     argc; | 
| case CFG_DIR: | OEMCHAR         *argv[16]; | 
| for (i=1; i<argc; i++) { | int                     val; | 
| pathadd(mod, argv[i]); | UINT            cfg; | 
| } |  | 
| break; | bank = -1; | 
|  |  | 
| case CFG_SOURCE: | if ((depth >= 16) || | 
| for (i=1; i<argc; i++) { | (midimod_getfile(mod, filename, buf, NELEMENTS(buf)) != SUCCESS)) { | 
| depth++; | goto cfl_err; | 
| cfgfile_load(mod, argv[i], depth); | } | 
| depth--; | // TRACEOUT(("open: %s", buf)); | 
| } | tfh = textfile_open(buf, 0x1000); | 
| break; | if (tfh == NULL) { | 
|  | goto cfl_err; | 
| case CFG_DEFAULT: | } | 
| break; | while(textfile_read(tfh, buf, NELEMENTS(buf)) == SUCCESS) { | 
|  | argc = cfggetarg(buf, argv, NELEMENTS(argv)); | 
| case CFG_BANK: | if (argc < 2) { | 
| case CFG_DRUM: | continue; | 
| if ((cfggetval(argv[1], &val) == SUCCESS) && | } | 
| (val >= 0) && (val < 128)) { | cfg = 0; | 
| val <<= 1; | while(cfg < NELEMENTS(cfgstr)) { | 
| if (cfg == CFG_DRUM) { | if (!milstr_cmp(argv[0], cfgstr[cfg])) { | 
| val++; | break; | 
| } | } | 
| bank = val; | cfg++; | 
| } | } | 
| break; | switch(cfg) { | 
|  | case CFG_DIR: | 
| default: | for (i=1; i<argc; i++) { | 
| settone(mod, bank, argc, argv); | pathaddex(mod, argv[i]); | 
| break; | } | 
| } | break; | 
| } |  | 
| textfile_close(tfh); | case CFG_SOURCE: | 
| return(SUCCESS); | for (i=1; i<argc; i++) { | 
|  | depth++; | 
| cfl_err: | cfgfile_load(mod, argv[i], depth); | 
| return(FAILURE); | depth--; | 
| } | } | 
|  | break; | 
|  |  | 
| // ---- | case CFG_DEFAULT: | 
|  | break; | 
| MIDIMOD midimod_create(UINT samprate) { |  | 
|  | case CFG_BANK: | 
| UINT    size; | case CFG_DRUM: | 
| MIDIMOD ret; | if ((cfggetval(argv[1], &val) == SUCCESS) && | 
| BRESULT r; | (val >= 0) && (val < 128)) { | 
|  | val <<= 1; | 
| size = sizeof(_MIDIMOD); | if (cfg == CFG_DRUM) { | 
| size += sizeof(INSTRUMENT) * 128 * 2; | val++; | 
| size += sizeof(_TONECFG) * 128 * 2; | } | 
| ret = (MIDIMOD)_MALLOC(size, "MIDIMOD"); | bank = val; | 
| if (ret == NULL) { | } | 
| goto mmcre_err1; | break; | 
| } |  | 
| ZeroMemory(ret, size); | default: | 
| ret->samprate = samprate; | settone(mod, bank, argc, argv); | 
| ret->tone[0] = (INSTRUMENT *)(ret + 1); | break; | 
| ret->tone[1] = ret->tone[0] + 128; | } | 
| ret->tonecfg[0] = (TONECFG)(ret->tone[1] + 128); | } | 
| ret->tonecfg[1] = ret->tonecfg[0] + 128; | textfile_close(tfh); | 
| ret->pathtbl = listarray_new(sizeof(_PATHLIST), 64); | return(SUCCESS); | 
| pathadd(ret, NULL); |  | 
| pathadd(ret, file_getcd(str_null)); | cfl_err: | 
| ret->namelist = listarray_new(MAX_NAME, 128); | return(FAILURE); | 
| r = cfgfile_load(ret, file_timiditycfg, 0); | } | 
| #if defined(TIMIDITY_CFGFILE) |  | 
| if (r != SUCCESS) { |  | 
| r = cfgfile_load(ret, TIMIDITY_CFGFILE, 0); | // ---- | 
| } |  | 
| #endif | VEXTERN MIDIMOD VEXPORT midimod_create(UINT samprate) { | 
| if (r != SUCCESS) { |  | 
| goto mmcre_err2; | UINT    size; | 
| } | MIDIMOD ret; | 
| return(ret); | BRESULT r; | 
|  |  | 
| mmcre_err2: | size = sizeof(_MIDIMOD); | 
| listarray_destroy(ret->namelist); | size += sizeof(INSTRUMENT) * 128 * 2; | 
| listarray_destroy(ret->pathtbl); | size += sizeof(_TONECFG) * 128 * 2; | 
| _MFREE(ret); | ret = (MIDIMOD)_MALLOC(size, "MIDIMOD"); | 
|  | if (ret == NULL) { | 
| mmcre_err1: | goto mmcre_err1; | 
| return(NULL); | } | 
| } | ZeroMemory(ret, size); | 
|  | ret->samprate = samprate; | 
| void midimod_destroy(MIDIMOD hdl) { | ret->tone[0] = (INSTRUMENT *)(ret + 1); | 
|  | ret->tone[1] = ret->tone[0] + 128; | 
| UINT    r; | ret->tonecfg[0] = (TONECFG)(ret->tone[1] + 128); | 
| TONECFG bank; | ret->tonecfg[1] = ret->tonecfg[0] + 128; | 
|  | ret->pathtbl = listarray_new(sizeof(_PATHLIST), 16); | 
| if (hdl) { | pathadd(ret, NULL); | 
| r = 128; | pathadd(ret, file_getcd(str_null)); | 
| do { | ret->namelist = listarray_new(MAX_NAME, 128); | 
| r--; | r = cfgfile_load(ret, file_timiditycfg, 0); | 
| inst_bankfree(hdl, r); | #if defined(TIMIDITY_CFGFILE) | 
| } while(r > 0); | if (r != SUCCESS) { | 
| for (r=2; r<(MIDI_BANKS*2); r++) { | r = cfgfile_load(ret, TIMIDITY_CFGFILE, 0); | 
| bank = hdl->tonecfg[r]; | } | 
| if (bank) { | #endif | 
| _MFREE(bank); | if (r != SUCCESS) { | 
| } | goto mmcre_err2; | 
| } | } | 
| listarray_destroy(hdl->namelist); | midimod_lock(ret); | 
| listarray_destroy(hdl->pathtbl); | return(ret); | 
| _MFREE(hdl); |  | 
| } | mmcre_err2: | 
| } | listarray_destroy(ret->namelist); | 
|  | listarray_destroy(ret->pathtbl); | 
| void midimod_loadprogram(MIDIMOD hdl, UINT num) { | _MFREE(ret); | 
|  |  | 
| UINT    bank; | mmcre_err1: | 
|  | return(NULL); | 
| if (hdl != NULL) { | } | 
| bank = (num >> 8) & 0x7f; |  | 
| num &= 0x7f; | void VERMOUTHCL midimod_lock(MIDIMOD mod) { | 
| if (inst_singleload(hdl, bank << 1, num) != MIDIOUT_SUCCESS) { |  | 
| inst_singleload(hdl, 0, num); | mod->lockcount++; | 
| } | } | 
| } |  | 
| } | void VERMOUTHCL midimod_unlock(MIDIMOD mod) { | 
|  |  | 
| void midimod_loadrhythm(MIDIMOD hdl, UINT num) { | UINT    r; | 
|  | TONECFG bank; | 
| UINT    bank; |  | 
|  | if (!mod->lockcount) { | 
| if (hdl != NULL) { | return; | 
| bank = (num >> 8) & 0x7f; | } | 
| num &= 0x7f; | mod->lockcount--; | 
| if (inst_singleload(hdl, (bank << 1) + 1, num) != MIDIOUT_SUCCESS) { | if (mod->lockcount) { | 
| inst_singleload(hdl, 1, num); | return; | 
| } | } | 
| } |  | 
| } | r = 128; | 
|  | do { | 
| void midimod_loadgm(MIDIMOD hdl) { | r--; | 
|  | inst_bankfree(mod, r); | 
| if (hdl) { | } while(r > 0); | 
| inst_bankload(hdl, 0); | for (r=2; r<(MIDI_BANKS*2); r++) { | 
| inst_bankload(hdl, 1); | bank = mod->tonecfg[r]; | 
| } | if (bank) { | 
| } | _MFREE(bank); | 
|  | } | 
| void midimod_loadall(MIDIMOD hdl) { | } | 
|  | listarray_destroy(mod->namelist); | 
| UINT    b; | listarray_destroy(mod->pathtbl); | 
|  | _MFREE(mod); | 
| if (hdl) { | } | 
| for (b=0; b<(MIDI_BANKS*2); b++) { |  | 
| inst_bankload(hdl, b); | VEXTERN void VEXPORT midimod_destroy(MIDIMOD mod) { | 
| } |  | 
| } | if (mod) { | 
| } | midimod_unlock(mod); | 
|  | } | 
|  | } | 
|  |  | 
|  | VEXTERN BRESULT VEXPORT midimod_cfgload(MIDIMOD mod, | 
|  | const OEMCHAR *filename) { | 
|  |  | 
|  | return(cfgfile_load(mod, filename, 0)); | 
|  | } | 
|  |  | 
|  | VEXTERN void VEXPORT midimod_loadprogram(MIDIMOD mod, UINT num) { | 
|  |  | 
|  | UINT    bank; | 
|  |  | 
|  | if (mod != NULL) { | 
|  | bank = (num >> 8) & 0x7f; | 
|  | num &= 0x7f; | 
|  | if (inst_singleload(mod, bank << 1, num) != MIDIOUT_SUCCESS) { | 
|  | inst_singleload(mod, 0, num); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | VEXTERN void VEXPORT midimod_loadrhythm(MIDIMOD mod, UINT num) { | 
|  |  | 
|  | UINT    bank; | 
|  |  | 
|  | if (mod != NULL) { | 
|  | bank = (num >> 8) & 0x7f; | 
|  | num &= 0x7f; | 
|  | if (inst_singleload(mod, (bank << 1) + 1, num) != MIDIOUT_SUCCESS) { | 
|  | inst_singleload(mod, 1, num); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | VEXTERN void VEXPORT midimod_loadgm(MIDIMOD mod) { | 
|  |  | 
|  | if (mod) { | 
|  | inst_bankload(mod, 0); | 
|  | inst_bankload(mod, 1); | 
|  | } | 
|  | } | 
|  |  | 
|  | VEXTERN void VEXPORT midimod_loadall(MIDIMOD mod) { | 
|  |  | 
|  | UINT    b; | 
|  |  | 
|  | if (mod) { | 
|  | for (b=0; b<(MIDI_BANKS*2); b++) { | 
|  | inst_bankload(mod, b); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | VEXTERN int VEXPORT midimod_loadallex(MIDIMOD mod, FNMIDIOUTLAEXCB cb, | 
|  | void *userdata) { | 
|  |  | 
|  | int                                     result; | 
|  | MIDIOUTLAEXPARAM        param; | 
|  | UINT                            b; | 
|  |  | 
|  | result = MIDIOUT_SUCCESS; | 
|  | if (mod) { | 
|  | ZeroMemory(¶m, sizeof(param)); | 
|  | param.userdata = userdata; | 
|  | for (b=0; b<(MIDI_BANKS*2); b++) { | 
|  | param.totaltones += inst_gettones(mod, b); | 
|  | } | 
|  | for (b=0; b<(MIDI_BANKS*2); b++) { | 
|  | param.bank = b; | 
|  | result = inst_bankloadex(mod, b, cb, ¶m); | 
|  | if (result != MIDIOUT_SUCCESS) | 
|  | { | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  | return result; | 
|  | } | 
|  |  |