diff options
| author | Takamichi Horikawa <takamichiho@gmail.com> | 2017-03-17 22:33:37 +0900 | 
|---|---|---|
| committer | Takamichi Horikawa <takamichiho@gmail.com> | 2017-03-17 22:33:37 +0900 | 
| commit | 7fff156b574d3d1671c1d9f246b85007b08275da (patch) | |
| tree | 4fc918020304077289dcc086075efc6e83407e99 | |
| parent | 893a411ff3eb6ffdeba62acae34ac5511466599f (diff) | |
win32: add toneviewer
| -rw-r--r-- | win32/fmplayer.mak | 3 | ||||
| -rw-r--r-- | win32/main.c | 219 | ||||
| -rw-r--r-- | win32/toneview.c | 218 | ||||
| -rw-r--r-- | win32/toneview.h | 16 | ||||
| -rw-r--r-- | win32/x86/Makefile | 1 | 
5 files changed, 424 insertions, 33 deletions
| diff --git a/win32/fmplayer.mak b/win32/fmplayer.mak index 11f98f2..c71ef6a 100644 --- a/win32/fmplayer.mak +++ b/win32/fmplayer.mak @@ -20,7 +20,9 @@ LIBOPNA_OBJS=opna \  FMDSP_OBJS=fmdsp \             font_rom \             font_fmdsp_small +TONEDATA_OBJS=tonedata  OBJBASE=main \ +        toneview \          soundout \          dsoundout \          waveout \ @@ -29,6 +31,7 @@ OBJBASE=main \          guid \          $(FMDRIVER_OBJS) \          $(LIBOPNA_OBJS) \ +        $(TONEDATA_OBJS) \          $(FMDSP_OBJS)  RESBASE=lnf  LIBBASE=user32 \ diff --git a/win32/main.c b/win32/main.c index 16d2f3e..9cef778 100644 --- a/win32/main.c +++ b/win32/main.c @@ -12,10 +12,14 @@  #include "fmdsp/fmdsp.h"  #include "soundout.h"  #include "winfont.h" +#include "version.h" +#include "toneview.h"  enum {    ID_OPENFILE = 0x10,    ID_PAUSE, +  ID_2X, +  ID_TONEVIEW,  };  #define FMPLAYER_CLASSNAME L"myon_fmplayer_ym2608_win32" @@ -55,10 +59,15 @@ static struct {    uint8_t opna_adpcm_ram[OPNA_ADPCM_RAM_SIZE];    void *ppz8_buf;    bool paused; +  HWND mainwnd; +  WNDPROC btn_defproc;    HWND driverinfo; +  HWND button_2x;    const wchar_t *lastopenpath; +  bool fmdsp_2x;  } g; +HWND g_currentdlg;  static void opna_int_cb(void *userptr) {    struct fmdriver_work *work = (struct fmdriver_work *)userptr; @@ -93,6 +102,11 @@ static void sound_cb(void *p, int16_t *buf, unsigned frames) {    struct opna_timer *timer = (struct opna_timer *)p;    ZeroMemory(buf, sizeof(int16_t)*frames*2);    opna_timer_mix(timer, buf, frames); +  if (!atomic_flag_test_and_set_explicit( +      &toneview_g.flag, memory_order_acquire)) { +    tonedata_from_opna(&toneview_g.tonedata, &g.opna); +    atomic_flag_clear_explicit(&toneview_g.flag, memory_order_release); +  }    }  static void on_timer(HWND hwnd, UINT id) { @@ -302,7 +316,9 @@ static void openfile(HWND hwnd, const wchar_t *path) {    g.driver = driver;    if (g.data) HeapFree(g.heap, 0, g.data);    g.data = data; +  unsigned mask = opna_get_mask(&g.opna);    opna_reset(&g.opna); +  opna_set_mask(&g.opna, mask);    if (g.drum_rom) opna_drum_set_rom(&g.opna.drum, g.drum_rom);    opna_adpcm_set_ram_256k(&g.opna.adpcm, g.opna_adpcm_ram);    opna_timer_reset(&g.opna_timer, &g.opna); @@ -314,6 +330,7 @@ static void openfile(HWND hwnd, const wchar_t *path) {    g.work.opna = &g.opna_timer;    g.work.ppz8 = &g.ppz8;    g.work.ppz8_functbl = &ppz8_functbl; +  WideCharToMultiByte(932, WC_NO_BEST_FIT_CHARS, path, -1, g.work.filename, sizeof(g.work.filename), 0, 0);    opna_timer_set_int_callback(&g.opna_timer, opna_int_cb, &g.work);    opna_timer_set_mix_callback(&g.opna_timer, opna_mix_cb, &g.ppz8);    if (driver_type == DRIVER_PMD) { @@ -430,6 +447,118 @@ static void on_dropfiles(HWND hwnd, HDROP hdrop) {  }  #endif // ENABLE_WM_DROPFILES +static void mask_set(unsigned mask, bool shift) { +  if (shift) { +    opna_set_mask(&g.opna, ~mask); +  } else { +    opna_set_mask(&g.opna, opna_get_mask(&g.opna) ^ mask); +  } +} + +static void toggle_2x(HWND hwnd) { +  g.fmdsp_2x ^= 1; +  RECT wr; +  wr.left = 0; +  wr.right = 640; +  wr.top = 0; +  wr.bottom = 480; +  if (g.fmdsp_2x) { +    wr.right = 1280; +    wr.bottom = 880; +  } +  DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE); +  DWORD exstyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); +  AdjustWindowRectEx(&wr, style, 0, exstyle); +  SetWindowPos(hwnd, HWND_TOP, 0, 0, wr.right-wr.left, wr.bottom-wr.top, +                SWP_NOZORDER | SWP_NOMOVE); +} + +static bool proc_key(UINT vk, bool down, int repeat) { +  if (down) { +    if (VK_F1 <= vk && vk <= VK_F12) { +      if (GetKeyState(VK_CONTROL) & 0x8000U) { +        fmdsp_palette_set(&g.fmdsp, vk - VK_F1); +        return true; +      } else { +        switch (vk) { +        case VK_F6: +          if (g.lastopenpath) { +            openfile(g.mainwnd, g.lastopenpath); +          } +          return true; +        case VK_F7: +          if (g.sound) { +            g.paused = !g.paused; +            g.sound->pause(g.sound, g.paused); +          } +          return true; +        case VK_F11: +          fmdsp_dispstyle_set(&g.fmdsp, (g.fmdsp.style+1) % FMDSP_DISPSTYLE_CNT); +          return true; +        case VK_F12: +          toggle_2x(g.mainwnd); +        } +      } +    } else { +      bool shift = GetKeyState(VK_SHIFT) & 0x8000U; +      switch (vk) { +      case '1': +        mask_set(LIBOPNA_CHAN_FM_1, shift); +        return true; +      case '2': +        mask_set(LIBOPNA_CHAN_FM_2, shift); +        return true; +      case '3': +        mask_set(LIBOPNA_CHAN_FM_3, shift); +        return true; +      case '4': +        mask_set(LIBOPNA_CHAN_FM_4, shift); +        return true; +      case '5': +        mask_set(LIBOPNA_CHAN_FM_5, shift); +        return true; +      case '6': +        mask_set(LIBOPNA_CHAN_FM_6, shift); +        return true; +      case '7': +        mask_set(LIBOPNA_CHAN_SSG_1, shift); +        return true; +      case '8': +        mask_set(LIBOPNA_CHAN_SSG_2, shift); +        return true; +      case '9': +        mask_set(LIBOPNA_CHAN_SSG_3, shift); +        return true; +      case '0': +        mask_set(LIBOPNA_CHAN_DRUM_ALL, shift); +        return true; +      case VK_OEM_MINUS: +        mask_set(LIBOPNA_CHAN_ADPCM, shift); +        return true; +      case VK_OEM_PLUS: +        opna_set_mask(&g.opna, ~opna_get_mask(&g.opna)); +        return true; +      case VK_OEM_5: +        opna_set_mask(&g.opna, 0); +        return true; +      } +    } +  } +  return false; +} + +static LRESULT CALLBACK btn_wndproc( +  HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam +) { +  switch (msg) { +  case WM_KEYDOWN: +  case WM_KEYUP: +    if (proc_key((UINT)wParam, msg == WM_KEYDOWN, (int)(short)LOWORD(lParam))) return 0; +    break; +  } +  return CallWindowProc(g.btn_defproc, hwnd, msg, wParam, lParam); +} +  static bool on_create(HWND hwnd, CREATESTRUCT *cs) {    (void)cs;    HWND button = CreateWindowEx( @@ -459,6 +588,29 @@ static bool on_create(HWND hwnd, CREATESTRUCT *cs) {      100, 25,      hwnd, 0, g.hinst, 0    ); +  g.button_2x = CreateWindowEx( +    0, +    L"BUTTON", +    L"2&x", +    WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_CHECKBOX | BS_PUSHLIKE, +    215, 10, +    30, 25, +    hwnd, (HMENU)ID_2X, g.hinst, 0 +  ); +  HWND button_toneview = CreateWindowEx( +    0, +    L"BUTTON", +    L"Tone &viewer", +    WS_TABSTOP | WS_VISIBLE | WS_CHILD, +    250, 10, +    100, 25, +    hwnd, (HMENU)ID_TONEVIEW, g.hinst, 0 +  ); +  g.btn_defproc = (WNDPROC)GetWindowLongPtr(button, GWLP_WNDPROC); +  SetWindowLongPtr(button, GWLP_WNDPROC, (intptr_t)btn_wndproc); +  SetWindowLongPtr(pbutton, GWLP_WNDPROC, (intptr_t)btn_wndproc); +  SetWindowLongPtr(g.button_2x, GWLP_WNDPROC, (intptr_t)btn_wndproc); +  SetWindowLongPtr(button_toneview, GWLP_WNDPROC, (intptr_t)btn_wndproc);    NONCLIENTMETRICS ncm;    ncm.cbSize = sizeof(ncm);    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0); @@ -466,6 +618,8 @@ static bool on_create(HWND hwnd, CREATESTRUCT *cs) {    SetWindowFont(button, font, TRUE);    SetWindowFont(pbutton, font, TRUE);    SetWindowFont(g.driverinfo, font, TRUE); +  SetWindowFont(g.button_2x, font, TRUE); +  SetWindowFont(button_toneview, font, TRUE);    loadrom();    loadfont();    fmdsp_init(&g.fmdsp, g.font_loaded ? &g.font : 0); @@ -489,6 +643,14 @@ static void on_command(HWND hwnd, int id, HWND hwnd_c, UINT code) {        g.paused = !g.paused;        g.sound->pause(g.sound, g.paused);      } +    break; +  case ID_2X: +    toggle_2x(hwnd); +    Button_SetCheck(g.button_2x, g.fmdsp_2x); +    break; +  case ID_TONEVIEW: +    show_toneview(g.hinst, hwnd); +    break;    }  } @@ -531,7 +693,11 @@ static void on_paint(HWND hwnd) {      g.vram,      bi, DIB_RGB_COLORS);    SelectObject(mdc, bitmap); -  BitBlt(dc, 0, 80, 640, 400, mdc, 0, 0, SRCCOPY); +  if (g.fmdsp_2x) { +    StretchBlt(dc, 0, 80, 1280, 800, mdc, 0, 0, 640, 400, SRCCOPY); +  } else { +    BitBlt(dc, 0, 80, 640, 400, mdc, 0, 0, SRCCOPY); +  }    DeleteDC(mdc);    DeleteObject(bitmap);    EndPaint(hwnd, &ps); @@ -559,36 +725,20 @@ static void on_syskey(HWND hwnd, UINT vk, BOOL down, int repeat, UINT scan) {  }  static void on_key(HWND hwnd, UINT vk, BOOL down, int repeat, UINT scan) { -  if (down) { -    if (VK_F1 <= vk && vk <= VK_F12) { -      if (GetKeyState(VK_CONTROL) & 0x8000U) { -        fmdsp_palette_set(&g.fmdsp, vk - VK_F1); -        return; -      } else { -        switch (vk) { -        case VK_F6: -          if (g.lastopenpath) { -            openfile(hwnd, g.lastopenpath); -          } -          break; -        case VK_F7: -          if (g.sound) { -            g.paused = !g.paused; -            g.sound->pause(g.sound, g.paused); -          } -          break; -        case VK_F11: -          fmdsp_dispstyle_set(&g.fmdsp, (g.fmdsp.style+1) % FMDSP_DISPSTYLE_CNT); -          break; -        } -      } +  if (!proc_key(vk, down, repeat)) { +    if (down) { +      FORWARD_WM_KEYDOWN(hwnd, vk, repeat, scan, DefWindowProc); +    } else { +      FORWARD_WM_KEYUP(hwnd, vk, repeat, scan, DefWindowProc);      } -    FORWARD_WM_KEYDOWN(hwnd, vk, repeat, scan, DefWindowProc); -  } else { -    FORWARD_WM_KEYUP(hwnd, vk, repeat, scan, DefWindowProc);    }  } +static void on_activate(HWND hwnd, bool activate, HWND targetwnd, WINBOOL state) { +  if (activate) g_currentdlg = hwnd; +  else g_currentdlg = 0; +} +  static LRESULT CALLBACK wndproc(    HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam  ) { @@ -607,6 +757,7 @@ static LRESULT CALLBACK wndproc(    HANDLE_MSG(hwnd, WM_KEYUP, on_key);    HANDLE_MSG(hwnd, WM_SYSKEYDOWN, on_syskey);    HANDLE_MSG(hwnd, WM_SYSKEYUP, on_syskey); +  HANDLE_MSG(hwnd, WM_ACTIVATE, on_activate);    }    return DefWindowProc(hwnd, msg, wParam, lParam);  } @@ -665,24 +816,26 @@ int CALLBACK wWinMain(HINSTANCE hinst, HINSTANCE hpinst,    wr.top = 0;    wr.bottom = 480;    AdjustWindowRectEx(&wr, style, 0, exStyle); -  HWND hwnd = CreateWindowEx( +  g.mainwnd = CreateWindowEx(      exStyle, -    (wchar_t*)((uintptr_t)wcatom), L"FMPlayer/Win32", +    (wchar_t*)((uintptr_t)wcatom), L"FMPlayer/Win32 v" FMPLAYER_VERSION_STR,      style,      CW_USEDEFAULT, CW_USEDEFAULT,      wr.right-wr.left, wr.bottom-wr.top,      0, 0, g.hinst, 0    ); -  ShowWindow(hwnd, cmdshow); +  ShowWindow(g.mainwnd, cmdshow);    if (argfile) { -    openfile(hwnd, argfile); +    openfile(g.mainwnd, argfile);    }    MSG msg = {0};    while (GetMessage(&msg, 0, 0, 0)) { -    TranslateMessage(&msg); -    DispatchMessage(&msg); +    if (!g_currentdlg || !IsDialogMessage(g_currentdlg, &msg)) { +      TranslateMessage(&msg); +      DispatchMessage(&msg); +    }    }    return msg.wParam;  } diff --git a/win32/toneview.c b/win32/toneview.c new file mode 100644 index 0000000..a0a920a --- /dev/null +++ b/win32/toneview.c @@ -0,0 +1,218 @@ +#include "toneview.h" +#include <stdbool.h> +#include <windowsx.h> + +enum { +  TIMER_UPDATE = 1 +}; + +enum { +  ID_COPY0 = 0x10, +  ID_COPY1, +  ID_COPY2, +  ID_COPY3, +  ID_COPY4, +  ID_COPY5, +  ID_NORMALIZE, +  ID_LIST, +}; + +struct toneview_g toneview_g = { +  .flag = ATOMIC_FLAG_INIT +}; + +static struct { +  HINSTANCE hinst; +  HWND toneviewer; +  HWND tonelabel[6]; +  ATOM toneviewer_class; +  struct fmplayer_tonedata tonedata; +  struct fmplayer_tonedata tonedata_n; +  char strbuf[FMPLAYER_TONEDATA_STR_SIZE]; +  wchar_t strbuf_w[FMPLAYER_TONEDATA_STR_SIZE]; +  enum fmplayer_tonedata_format format; +  bool normalize; +  HFONT font; +  HFONT font_mono; +  HWND checkbox; +  HWND formatlist; +} g = { +  .normalize = true +}; + +extern HWND g_currentdlg; + +static void on_destroy(HWND hwnd) { +  for (int i = 0; i < 6; i++) { +    DestroyWindow(g.tonelabel[i]); +  } +  DestroyWindow(g.checkbox); +  DestroyWindow(g.formatlist); +  g.toneviewer = 0; +} + +enum { +  LIST_W = 200, +  NORMALIZE_X = 10 + LIST_W + 5, +  NORMALIZE_W = 200, +  TOP_H = 25, +  TONELABEL_X = 10, +  TONELABEL_H = 100, +  TONELABEL_W = 300, +  COPY_X = TONELABEL_X + TONELABEL_W + 5, +  COPY_W = 100, +  WIN_H = 10 + TOP_H + 5 + TONELABEL_H*6 + 5*5 + 10, +  WIN_W = 10 + TONELABEL_W + 5 + COPY_W + 10, +}; + +static void on_command(HWND hwnd, int id, HWND hwnd_c, UINT code) { +  if (code == BN_CLICKED && ((ID_COPY0 <= id) && (id <= ID_COPY5))) { +    int i = id - ID_COPY0; +    HGLOBAL gmem = GlobalAlloc(GMEM_MOVEABLE, FMPLAYER_TONEDATA_STR_SIZE*sizeof(wchar_t)); +    if (!gmem) return; +    wchar_t *buf = GlobalLock(gmem); +    GetWindowText(g.tonelabel[i], buf, FMPLAYER_TONEDATA_STR_SIZE*sizeof(wchar_t)); +    GlobalUnlock(gmem); +    if (!OpenClipboard(hwnd)) return; +    EmptyClipboard(); +    SetClipboardData(CF_UNICODETEXT, gmem); +    CloseClipboard(); +  } else if (id == ID_NORMALIZE && code == BN_CLICKED) { +    g.normalize ^= 1; +    Button_SetCheck(hwnd_c, g.normalize); +  } else if (id == ID_LIST && code == CBN_SELCHANGE) { +    g.format = ComboBox_GetCurSel(g.formatlist); +  } +} + +static bool on_create(HWND hwnd, const CREATESTRUCT *cs) { +  RECT wr; +  wr.left = 0; +  wr.right = WIN_W; +  wr.top = 0; +  wr.bottom = WIN_H; +  DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE); +  DWORD exstyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); +  AdjustWindowRectEx(&wr, style, 0, exstyle); +  SetWindowPos(hwnd, HWND_TOP, 0, 0, wr.right-wr.left, wr.bottom-wr.top, +                SWP_NOZORDER | SWP_NOMOVE); + +  if (!g.font_mono) { +    g.font_mono = CreateFont( +      16, 0, 0, 0, +      FW_NORMAL, FALSE, FALSE, FALSE, +      ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, +      CLEARTYPE_QUALITY, FIXED_PITCH, 0); +  } + +  if (!g.font) { +    NONCLIENTMETRICS ncm; +    ncm.cbSize = sizeof(ncm); +    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0); +    g.font = CreateFontIndirect(&ncm.lfMessageFont); +  } +  g.formatlist = CreateWindowEx(0, L"combobox", 0, +                                   WS_TABSTOP | WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, +                                   10, 10, LIST_W, 100, +                                   hwnd, (HMENU)ID_LIST, g.hinst, 0); +  SetWindowFont(g.formatlist, g.font, TRUE); +  ComboBox_AddString(g.formatlist, L"PMD"); +  ComboBox_AddString(g.formatlist, L"FMP"); +  ComboBox_SetCurSel(g.formatlist, 0); +  g.checkbox = CreateWindowEx(0, L"button", +                                 L"&Normalize", +                                 WS_CHILD | WS_VISIBLE | BS_CHECKBOX | WS_TABSTOP, +                                 NORMALIZE_X, 10, NORMALIZE_W, 25, +                                 hwnd, (HMENU)ID_NORMALIZE, g.hinst, 0 +                                ); +  Button_SetCheck(g.checkbox, g.normalize); +  SetWindowFont(g.checkbox, g.font, TRUE); +  for (int i = 0; i < 6; i++) { +    g.tonelabel[i] = CreateWindowEx(WS_EX_CLIENTEDGE, L"static", +                                 L"@ 0\n123 123", +                                 WS_VISIBLE | WS_CHILD, +                                 10, 40 + (TONELABEL_H+5)*i, TONELABEL_W, TONELABEL_H, +                                 hwnd, 0, g.hinst, 0); +    SetWindowFont(g.tonelabel[i], g.font_mono, TRUE); +    wchar_t text[] = L"Copy (& )"; +    text[7] = L'1' + i; +    HWND copybutton = CreateWindowEx(0, L"button", +                                     text, +                                     WS_VISIBLE | WS_CHILD | WS_TABSTOP, +                                     COPY_X, 40 + (TONELABEL_H+5)*i, 100, TONELABEL_H, +                                     hwnd, (HMENU)(ID_COPY0+i), g.hinst, 0); +    SetWindowFont(copybutton, g.font, TRUE); +  } +  ShowWindow(hwnd, SW_SHOW); +  SetTimer(hwnd, TIMER_UPDATE, 16, 0); +  return true; +} + +static void on_timer(HWND hwnd, UINT id) { +  if (id == TIMER_UPDATE) { +    if (!atomic_flag_test_and_set_explicit( +        &toneview_g.flag, memory_order_acquire)) { +      g.tonedata = toneview_g.tonedata; +      atomic_flag_clear_explicit(&toneview_g.flag, memory_order_release); +    } +    g.tonedata_n = g.tonedata; +    for (int c = 0; c < 6; c++) { +      if (g.normalize) { +        tonedata_ch_normalize_tl(&g.tonedata_n.ch[c]); +      } +      tonedata_ch_string(g.format, g.strbuf, &g.tonedata_n.ch[c], 0); +      for (int i = 0; i < FMPLAYER_TONEDATA_STR_SIZE; i++) { +        g.strbuf_w[i] = g.strbuf[i]; +      } +     // RedrawWindow(g.tonelabel[c], 0, 0, RDW_ERASE); +      SetWindowText(g.tonelabel[c], g.strbuf_w); +    } +  } +} + +static void on_activate(HWND hwnd, bool activate, HWND targetwnd, WINBOOL state) { +  if (activate) g_currentdlg = hwnd; +  else g_currentdlg = 0; +} + +static LRESULT CALLBACK wndproc( +  HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam +) { +  switch (msg) { +  HANDLE_MSG(hwnd, WM_DESTROY, on_destroy); +  HANDLE_MSG(hwnd, WM_CREATE, on_create); +  HANDLE_MSG(hwnd, WM_TIMER, on_timer); +  HANDLE_MSG(hwnd, WM_COMMAND, on_command); +  HANDLE_MSG(hwnd, WM_ACTIVATE, on_activate); +  } +  return DefWindowProc(hwnd, msg, wParam, lParam); +} + +void show_toneview(HINSTANCE hinst, HWND parent) { +  g.hinst = hinst; +  if (!g.toneviewer) { +    if (!g.toneviewer_class) { +      WNDCLASS wc = {0}; +      wc.style = CS_HREDRAW | CS_VREDRAW; +      wc.lpfnWndProc = wndproc; +      wc.hInstance = hinst; +      wc.hIcon = LoadIcon(g.hinst, MAKEINTRESOURCE(1)); +      wc.hCursor = LoadCursor(NULL, IDC_ARROW); +      wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); +      wc.lpszClassName = L"myon_fmplayer_ym2608_toneviewer"; +      g.toneviewer_class = RegisterClass(&wc); +    } +    if (!g.toneviewer_class) { +      MessageBox(parent, L"Cannot register class", L"Error", MB_ICONSTOP); +      return; +    } +    g.toneviewer = CreateWindowEx(0, +                                  MAKEINTATOM(g.toneviewer_class), +                                  L"FMPlayer Tone Viewer", +                                  WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, +                                  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, +                                  parent, 0, g.hinst, 0); +  } else { +    SetForegroundWindow(g.toneviewer); +  } +} diff --git a/win32/toneview.h b/win32/toneview.h new file mode 100644 index 0000000..32f402b --- /dev/null +++ b/win32/toneview.h @@ -0,0 +1,16 @@ +#ifndef MYON_FMPLAYER_WIN32_TONEVIEW_H_INCLUDED +#define MYON_FMPLAYER_WIN32_TONEVIEW_H_INCLUDED + +#include "tonedata/tonedata.h" +#include <stdatomic.h> +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +extern struct toneview_g { +  struct fmplayer_tonedata tonedata; +  atomic_flag flag; +} toneview_g; + +void show_toneview(HINSTANCE hinst, HWND parent); + +#endif // MYON_FMPLAYER_WIN32_TONEVIEW_H_INCLUDED diff --git a/win32/x86/Makefile b/win32/x86/Makefile index 2f523a3..1a4c6d8 100644 --- a/win32/x86/Makefile +++ b/win32/x86/Makefile @@ -2,6 +2,7 @@ vpath %.c ../  vpath %.c ../../fmdriver  vpath %.c ../../libopna  vpath %.c ../../fmdsp +vpath %.c ../../tonedata  vpath %.rc ..  include ../fmplayer.mak | 
