diff --git a/src/Makefile.mingw b/src/Makefile.mingw index ef0636e31..8c34794bb 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -203,6 +203,7 @@ SNDOBJ = sound.o \ wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ wave8580_PST.o wave.o \ midi.o \ + midi_fluidsynth.o \ midi_mt32.o \ Analog.o BReverbModel.o File.o FileStream.o LA32Ramp.o \ LA32FloatWaveGenerator.o LA32WaveGenerator.o \ @@ -262,7 +263,7 @@ LIBS = -mwindows \ -lopenal.dll \ -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 \ -lcomctl32 -lkernel32 -lwsock32 -lwinmm -liphlpapi -lpsapi \ - -static -lstdc++ -lgcc + -static -lstdc++ -lgcc -lfluidsynth -lfluidsynth.dll # Build rules. diff --git a/src/SOUND/midi.c b/src/SOUND/midi.c index 6f3de8fba..9a80e30f2 100644 --- a/src/SOUND/midi.c +++ b/src/SOUND/midi.c @@ -8,8 +8,9 @@ #include "../WIN/plat_midi.h" #include "../WIN/plat_ticks.h" -#include "midi_system.h" +#include "midi_fluidsynth.h" #include "midi_mt32.h" +#include "midi_system.h" int midi_device_current = 0; static int midi_device_last = 0; @@ -24,9 +25,10 @@ typedef struct static MIDI_DEVICE devices[] = { {"None", "none", NULL}, - {SYSTEM_MIDI_NAME, SYSTEM_MIDI_INTERNAL_NAME, &system_midi_device}, + {"FluidSynth", "fluidsynth", &fluidsynth_device}, {"Roland MT-32 Emulation", "mt32", &mt32_device}, {"Roland CM-32L Emulation", "cm32l", &cm32l_device}, + {SYSTEM_MIDI_NAME, SYSTEM_MIDI_INTERNAL_NAME, &system_midi_device}, {"", "", NULL} }; diff --git a/src/WIN/win_deviceconfig.c b/src/WIN/win_deviceconfig.c index 3cce23331..920595db0 100644 --- a/src/WIN/win_deviceconfig.c +++ b/src/WIN/win_deviceconfig.c @@ -35,10 +35,11 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam int val_int; int ret; int id; - device_config_t *config; int c; - int num; + int num; int changed; + int cid; + device_config_t *config; char s[80]; switch (message) @@ -94,6 +95,24 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; + case CONFIG_SPINNER: + val_int = config_get_int(config_device->name, config->name, config->default_int); + + sprintf(s, "%i", val_int); + SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); + + id += 2; + break; + + case CONFIG_FILE: + { + char* str = config_get_string(config_device->name, config->name, 0); + if (str) + SendMessage(h, WM_SETTEXT, 0, (LPARAM)str); + id += 3; + } + break; + case CONFIG_HEX16: val_int = config_get_hex16(config_device->name, config->name, config->default_int); @@ -132,13 +151,14 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam return TRUE; case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - { + { + cid = LOWORD(wParam); + if (cid == IDOK) + { id = IDC_CONFIG_BASE; config = config_device->config; changed = 0; + char s[512]; while (config->type != -1) { @@ -181,6 +201,33 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; + case CONFIG_FILE: + { + char* str = config_get_string(config_device->name, config->name, (char*)""); + SendMessage(h, WM_GETTEXT, 511, (LPARAM)s); + if (strcmp(str, s)) + changed = 1; + + id += 3; + } + break; + + case CONFIG_SPINNER: + val_int = config_get_int(config_device->name, config->name, config->default_int); + if (val_int > config->spinner.max) + val_int = config->spinner.max; + else if (val_int < config->spinner.min) + val_int = config->spinner.min; + + SendMessage(h, WM_GETTEXT, 79, (LPARAM)s); + sscanf(s, "%i", &c); + + if (val_int != c) + changed = 1; + + id += 2; + break; + case CONFIG_HEX16: val_int = config_get_hex16(config_device->name, config->name, config->default_int); @@ -218,16 +265,16 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam return TRUE; } - ret = msgbox_reset(ghwnd); - switch(ret) - { - case IDNO: - EndDialog(hdlg, 0); - return TRUE; - case IDCANCEL: - return FALSE; - default: - break; + ret = msgbox_reset(ghwnd); + switch(ret) + { + case IDNO: + EndDialog(hdlg, 0); + return TRUE; + case IDCANCEL: + return FALSE; + default: + break; } id = IDC_CONFIG_BASE; @@ -262,6 +309,27 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; + case CONFIG_FILE: + SendMessage(h, WM_GETTEXT, 511, (LPARAM)s); + + config_set_string(config_device->name, config->name, s); + + id += 3; + break; + + case CONFIG_SPINNER: + SendMessage(h, WM_GETTEXT, 79, (LPARAM)s); + sscanf(s, "%i", &c); + if (c > config->spinner.max) + c = config->spinner.max; + else if (c < config->spinner.min) + c = config->spinner.min; + + config_set_int(config_device->name, config->name, c); + + id += 2; + break; + case CONFIG_HEX16: c = SendMessage(h, CB_GETCURSEL, 0, 0); for (; c > 0; c--) @@ -289,12 +357,90 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam EndDialog(hdlg, 0); return TRUE; - } - case IDCANCEL: - EndDialog(hdlg, 0); - return TRUE; - } - break; + } + else if (cid == IDCANCEL) + { + EndDialog(hdlg, 0); + return TRUE; + } + else + { + int id = IDC_CONFIG_BASE; + device_config_t *config = config_device->config; + + while (config->type != -1) + { + switch (config->type) + { + case CONFIG_BINARY: + id++; + break; + + case CONFIG_SELECTION: + case CONFIG_MIDI: + case CONFIG_SPINNER: + id += 2; + break; + + case CONFIG_FILE: + { + if (cid == id+1) + { + char s[512]; + s[0] = 0; + int c, d; + HWND h = GetDlgItem(hdlg, id); + SendMessage(h, WM_GETTEXT, 511, (LPARAM)s); + char file_filter[512]; + file_filter[0] = 0; + + c = 0; + while (config->file_filter[c].description[0]) + { + if (c > 0) + strcat(file_filter, "|"); + strcat(file_filter, config->file_filter[c].description); + strcat(file_filter, " ("); + d = 0; + while (config->file_filter[c].extensions[d][0]) + { + if (d > 0) + strcat(file_filter, ";"); + strcat(file_filter, "*."); + strcat(file_filter, config->file_filter[c].extensions[d]); + d++; + } + strcat(file_filter, ")|"); + d = 0; + while (config->file_filter[c].extensions[d][0]) + { + if (d > 0) + strcat(file_filter, ";"); + strcat(file_filter, "*."); + strcat(file_filter, config->file_filter[c].extensions[d]); + d++; + } + c++; + } + strcat(file_filter, "|All files (*.*)|*.*|"); + d = strlen(file_filter); + + /* replace | with \0 */ + for (c = 0; c < d; ++c) + if (file_filter[c] == '|') + file_filter[c] = '\0'; + + if (!file_dlg_mb(hdlg, file_filter, s, 0)) + SendMessage(h, WM_SETTEXT, 0, (LPARAM)openfilestring); + } + } + break; + } + config++; + } + } + } + break; } return FALSE; } @@ -402,6 +548,122 @@ void deviceconfig_open(HWND hwnd, device_t *device) y += 20; break; + + case CONFIG_SPINNER: + /*Spinner*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 70; + item->y = y; + item->id = id++; + + item->cx = 140; + item->cy = 14; + + item->style = WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_NUMBER; + item->dwExtendedStyle = WS_EX_CLIENTEDGE; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0081; /* edit text class */ + + data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((uintptr_t)data) & 2) + data++; + + /* TODO: add up down class */ + /*Static text*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 10; + item->y = y; + item->id = id++; + + item->cx = 60; + item->cy = 15; + + item->style = WS_CHILD | WS_VISIBLE; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0082; /* static class */ + + data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((uintptr_t)data) & 2) + data++; + + y += 20; + break; + + case CONFIG_FILE: + /*File*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 70; + item->y = y; + item->id = id++; + + item->cx = 100; + item->cy = 14; + + item->style = WS_CHILD | WS_VISIBLE | ES_READONLY; + item->dwExtendedStyle = WS_EX_CLIENTEDGE; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0081; /* edit text class */ + + data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((uintptr_t)data) & 2) + data++; + + /* Button */ + item = (DLGITEMTEMPLATE *)data; + item->x = 175; + item->y = y; + item->id = id++; + + item->cx = 35; + item->cy = 14; + + item->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0080; /* button class */ + + data += MultiByteToWideChar(CP_ACP, 0, "Browse", -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((uintptr_t)data) & 2) + data++; + + /*Static text*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 10; + item->y = y; + item->id = id++; + + item->cx = 60; + item->cy = 15; + + item->style = WS_CHILD | WS_VISIBLE; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0082; /* static class */ + + data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((uintptr_t)data) & 2) + data++; + + y += 20; + break; } if (((unsigned long)data) & 2) diff --git a/src/WIN/win_language.c b/src/WIN/win_language.c index e2bf2b24a..4b83261ce 100644 --- a/src/WIN/win_language.c +++ b/src/WIN/win_language.c @@ -313,6 +313,15 @@ int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) return file_dlg_w(hwnd, f, ufn, save); } +int file_dlg_mb(HWND hwnd, char *f, char *fn, int save) +{ + WCHAR uf[512]; + WCHAR ufn[512]; + mbstowcs(uf, f, strlen(fn) + 1); + mbstowcs(ufn, fn, strlen(fn) + 1); + return file_dlg_w(hwnd, uf, ufn, save); +} + int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save) { return file_dlg_w(hwnd, win_language_get_string_from_id(i), fn, save); diff --git a/src/WIN/win_language.h b/src/WIN/win_language.h index 50b0105e3..053eabf0d 100644 --- a/src/WIN/win_language.h +++ b/src/WIN/win_language.h @@ -34,6 +34,7 @@ void msgbox_critical(HWND hwndParent, int i); int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save); int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save); +int file_dlg_mb(HWND hwnd, char *f, char *fn, int save); int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save); int file_dlg_st(HWND hwnd, int i, char *fn, int save); diff --git a/src/device.h b/src/device.h index 087c3464d..8948551fd 100644 --- a/src/device.h +++ b/src/device.h @@ -25,9 +25,11 @@ #define CONFIG_BINARY 2 #define CONFIG_SELECTION 3 #define CONFIG_MIDI 4 -#define CONFIG_HEX16 5 -#define CONFIG_HEX20 6 -#define CONFIG_MAC 7 +#define CONFIG_FILE 5 +#define CONFIG_SPINNER 6 +#define CONFIG_HEX16 7 +#define CONFIG_HEX20 8 +#define CONFIG_MAC 9 enum @@ -46,6 +48,19 @@ typedef struct device_config_selection_t int value; } device_config_selection_t; +typedef struct device_config_file_filter_t +{ + char description[256]; + char extensions[25][25]; +} device_config_file_filter_t; + +typedef struct device_config_spinner_t +{ + int min; + int max; + int step; +} device_config_spinner_t; + typedef struct device_config_t { char name[256]; @@ -54,6 +69,8 @@ typedef struct device_config_t char default_string[256]; int default_int; device_config_selection_t selection[16]; + device_config_file_filter_t file_filter[16]; + device_config_spinner_t spinner; } device_config_t; typedef struct device_t