aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakamichi Horikawa <takamichiho@gmail.com>2017-10-24 21:40:45 +0900
committerTakamichi Horikawa <takamichiho@gmail.com>2017-10-24 21:40:45 +0900
commite1e9b6ef1c460da98bde3c0de179bd6a7790d3dd (patch)
treec45e470022a75ed67debc663e4e166ba98064c4e
parent6ab52ffca0262bde8b3ab858fa63db8369874ff4 (diff)
win32: recover from D3DERR_DEVICELOST
-rw-r--r--pacc/pacc-d3d9.c47
-rw-r--r--pacc/pacc-win.h2
-rw-r--r--win32/about.c9
-rw-r--r--win32/fmplayer.mak3
-rw-r--r--win32/main.c52
5 files changed, 78 insertions, 35 deletions
diff --git a/pacc/pacc-d3d9.c b/pacc/pacc-d3d9.c
index e645366..df78f6a 100644
--- a/pacc/pacc-d3d9.c
+++ b/pacc/pacc-d3d9.c
@@ -412,23 +412,39 @@ static void pacc_delete(struct pacc_ctx *pc) {
static DWORD WINAPI pacc_renderproc(void *ptr) {
struct pacc_ctx *pc = ptr;
+ bool waitdevice = false;
while (!atomic_load_explicit(&pc->killthread, memory_order_relaxed)) {
if (WaitForSingleObject(pc->rendermtx, INFINITE) == WAIT_OBJECT_0) {
- if (SUCCEEDED(pc->d3d9d->lpVtbl->BeginScene(pc->d3d9d))) {
- if (pc->render_enabled) {
- pc->rendercb(pc->renderptr);
+ if (!waitdevice) {
+ HRESULT r = pc->d3d9d->lpVtbl->TestCooperativeLevel(pc->d3d9d);
+ if (r != D3D_OK) {
+ waitdevice = true;
} else {
- pc->d3d9d->lpVtbl->Clear(
- pc->d3d9d,
- 0, 0, D3DCLEAR_TARGET,
- D3DCOLOR_RGBA(0x00, 0x00, 0x00, 0xff),
- 1.0, 0);
+ if (SUCCEEDED(pc->d3d9d->lpVtbl->BeginScene(pc->d3d9d))) {
+ if (pc->render_enabled) {
+ pc->rendercb(pc->renderptr);
+ } else {
+ pc->d3d9d->lpVtbl->Clear(
+ pc->d3d9d,
+ 0, 0, D3DCLEAR_TARGET,
+ D3DCOLOR_RGBA(0x00, 0x00, 0x00, 0xff),
+ 1.0, 0);
+ }
+ pc->d3d9d->lpVtbl->EndScene(pc->d3d9d);
+ HRESULT res = pc->d3d9d->lpVtbl->Present(pc->d3d9d, 0, 0, 0, 0);
+ if (res == D3DERR_DEVICELOST) {
+ waitdevice = true;
+ }
+ }
}
- pc->d3d9d->lpVtbl->EndScene(pc->d3d9d);
- HRESULT res = pc->d3d9d->lpVtbl->Present(pc->d3d9d, 0, 0, 0, 0);
- if (res == D3DERR_DEVICELOST) {
+ } else {
+ HRESULT r = pc->d3d9d->lpVtbl->TestCooperativeLevel(pc->d3d9d);
+ if (r == D3DERR_DEVICENOTRESET) {
PostMessage(pc->msg_wnd, pc->msg_reset, 0, 0);
+ ReleaseMutex(pc->rendermtx);
+ return 0;
}
+ Sleep(100);
}
ReleaseMutex(pc->rendermtx);
}
@@ -467,16 +483,15 @@ struct pacc_win_vtable pacc_win_vtable = {
struct pacc_ctx *pacc_init_d3d9(
HWND hwnd,
+ int w, int h,
pacc_rendercb *rendercb, void *renderptr,
struct pacc_vtable *vt, struct pacc_win_vtable *winvt,
UINT msg_reset, HWND msg_wnd) {
struct pacc_ctx *pc = malloc(sizeof(*pc));
if (!pc) goto err;
- RECT wr;
- if (!GetClientRect(hwnd, &wr)) goto err;
*pc = (struct pacc_ctx) {
- .w = wr.right - wr.left,
- .h = wr.bottom - wr.top,
+ .w = w,
+ .h = h,
.hwnd = hwnd,
.rendercb = rendercb,
.renderptr = renderptr,
@@ -540,6 +555,8 @@ struct pacc_ctx *pacc_init_d3d9(
&pc->tex_pal,
0);
if (res != D3D_OK) goto err;
+ res = pc->d3d9d->lpVtbl->TestCooperativeLevel(pc->d3d9d);
+ if (res != D3D_OK) goto err;
D3DVERTEXELEMENT9 vertexdecls[] = {
{
diff --git a/pacc/pacc-win.h b/pacc/pacc-win.h
index e8bacc1..e96010a 100644
--- a/pacc/pacc-win.h
+++ b/pacc/pacc-win.h
@@ -15,7 +15,7 @@ struct pacc_win_vtable {
void (*renderctrl)(struct pacc_ctx *ctx, bool enable);
};
-struct pacc_ctx *pacc_init_d3d9(HWND hwnd, pacc_rendercb *rendercb, void *renderptr, struct pacc_vtable *vt, struct pacc_win_vtable *winvt, UINT msg_reset, HWND msg_wnd);
+struct pacc_ctx *pacc_init_d3d9(HWND hwnd, int w, int h, pacc_rendercb *rendercb, void *renderptr, struct pacc_vtable *vt, struct pacc_win_vtable *winvt, UINT msg_reset, HWND msg_wnd);
#endif // MYON_PACC_WIN_H_INCLUDED
diff --git a/win32/about.c b/win32/about.c
index b2013a1..c6c1e7c 100644
--- a/win32/about.c
+++ b/win32/about.c
@@ -41,13 +41,11 @@ static void update_status(void) {
L"Audio API: %ls\r\n"
"ym2608_adpcm_rom.bin: %lsavailable\r\n"
"font.rom: %ls\r\n"
- "SSE2 (for SIMD SSG resampling): %lsavailable\r\n"
- "SSSE3 (for SIMD FMDSP palette lookup): %lsavailable",
+ "SSE2 (for SIMD SSG resampling): %lsavailable",
g.soundapiname ? g.soundapiname : L"",
g.adpcm_rom ? L"" : L"un",
g.font_rom ? L"available" : L"unavailable, using MS Gothic",
- __builtin_cpu_supports("sse2") ? L"" : L"un",
- __builtin_cpu_supports("ssse3") ? L"" : L"un");
+ __builtin_cpu_supports("sse2") ? L"" : L"un");
SetWindowText(g.static_info, buf);
}
@@ -95,6 +93,7 @@ static bool on_create(HWND hwnd, const CREATESTRUCT *cs) {
update_status();
g.static_help = CreateWindowEx(0, L"static",
L"F11: toggle track display page\r\n"
+ "Shift+F11: toggle right display page\r\n"
"F12: display FMDSP at 2x\r\n"
"Ctrl+F1-F10: FMDSP color palette\r\n\r\n"
"1-9,0,-: toggle track mask (Ctrl: PPZ8)\r\n"
@@ -102,7 +101,7 @@ static bool on_create(HWND hwnd, const CREATESTRUCT *cs) {
"=: invert all mask\r\n"
"\\: all tracks on",
WS_CHILD | WS_VISIBLE,
- 75, 165, 400, 200,
+ 75, 150, 400, 215,
hwnd, 0, g.hinst, 0);
SetWindowFont(g.static_help, g.font, TRUE);
g.static_main = CreateWindowEx(0, L"static",
diff --git a/win32/fmplayer.mak b/win32/fmplayer.mak
index 87c9c41..1fc8d7c 100644
--- a/win32/fmplayer.mak
+++ b/win32/fmplayer.mak
@@ -23,8 +23,7 @@ FMDSP_OBJS=fmdsp-pacc \
fmdsp_platform_win \
font_fmdsp_small
TONEDATA_OBJS=tonedata
-SSEOBJBASE=opnassg-sinc-sse2 \
- fmdsp-vramlookup-ssse3
+SSEOBJBASE=opnassg-sinc-sse2
OBJBASE=main \
fft \
toneview \
diff --git a/win32/main.c b/win32/main.c
index e3fb702..8bee805 100644
--- a/win32/main.c
+++ b/win32/main.c
@@ -40,7 +40,7 @@ enum {
};
enum {
- WM_PACC_RESET = WM_USER,
+ WM_PACC_RESET = WM_APP,
};
#define FMPLAYER_CLASSNAME L"myon_fmplayer_ym2608_win32"
@@ -70,6 +70,7 @@ static struct {
bool paused;
HWND mainwnd;
HWND fmdspwnd;
+ ATOM fmdspwndclass;
WNDPROC btn_defproc;
HWND button_2x, button_toneview, button_oscilloview, button_about, button_config;
bool toneview_on, oscilloview_on, about_on, config_on;
@@ -428,7 +429,7 @@ static LRESULT CALLBACK btn_wndproc(
static bool on_create(HWND hwnd, CREATESTRUCT *cs) {
(void)cs;
g.fmdspwnd = CreateWindowEx(
- 0, L"static", 0,
+ 0, MAKEINTATOM(g.fmdspwndclass), 0,
WS_VISIBLE | WS_CHILD,
0, 80,
PC98_W, PC98_H,
@@ -685,6 +686,16 @@ static void on_activate(HWND hwnd, bool activate, HWND targetwnd, WINBOOL state)
else g_currentdlg = 0;
}
+static void render_cb(void *ptr) {
+ (void)ptr;
+ if (!atomic_flag_test_and_set_explicit(
+ &g.at_fftdata_flag, memory_order_acquire)) {
+ memcpy(&g.fftdata.fdata, &g.at_fftdata, sizeof(g.fftdata.fdata));
+ atomic_flag_clear_explicit(&g.at_fftdata_flag, memory_order_release);
+ }
+ fmdsp_pacc_render(g.fp);
+}
+
static LRESULT CALLBACK wndproc(
HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam
) {
@@ -708,7 +719,22 @@ static LRESULT CALLBACK wndproc(
}
break;
case WM_PACC_RESET:
- // TODO
+ if (g.pc) {
+ g.pacc_win.renderctrl(g.pc, false);
+ fmdsp_pacc_deinit(g.fp);
+ g.pacc.pacc_delete(g.pc);
+ g.pc = 0;
+ }
+ g.pc = pacc_init_d3d9(g.fmdspwnd, PC98_W, PC98_H, render_cb, 0, &g.pacc, &g.pacc_win, WM_PACC_RESET, g.mainwnd);
+ if (!g.pc) {
+ break;
+ }
+ if (!fmdsp_pacc_init(g.fp, g.pc, &g.pacc)) {
+ break;
+ }
+ fmdsp_pacc_set_font16(g.fp, &g.font);
+ fmdsp_pacc_set(g.fp, &g.work, &g.opna, &g.fftdata);
+ g.pacc_win.renderctrl(g.pc, true);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
@@ -726,14 +752,15 @@ static ATOM register_class(HINSTANCE hinst) {
return RegisterClass(&wc);
}
-static void render_cb(void *ptr) {
- (void)ptr;
- if (!atomic_flag_test_and_set_explicit(
- &g.at_fftdata_flag, memory_order_acquire)) {
- memcpy(&g.fftdata.fdata, &g.at_fftdata, sizeof(g.fftdata.fdata));
- atomic_flag_clear_explicit(&g.at_fftdata_flag, memory_order_release);
- }
- fmdsp_pacc_render(g.fp);
+static ATOM register_fmdsp_class(HINSTANCE hinst) {
+ WNDCLASS wc = {0};
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = DefWindowProc;
+ wc.hInstance = hinst;
+ wc.hCursor = LoadCursor(0, IDC_ARROW);
+ wc.hbrBackground = 0;
+ wc.lpszClassName = FMPLAYER_CLASSNAME "fmdsp";
+ return RegisterClass(&wc);
}
int CALLBACK wWinMain(HINSTANCE hinst, HINSTANCE hpinst,
@@ -775,6 +802,7 @@ int CALLBACK wWinMain(HINSTANCE hinst, HINSTANCE hpinst,
g.hinst = hinst;
g.heap = GetProcessHeap();
ATOM wcatom = register_class(g.hinst);
+ g.fmdspwndclass = register_fmdsp_class(g.hinst);
DWORD style = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CLIPCHILDREN;
DWORD exStyle = 0;
RECT wr;
@@ -796,7 +824,7 @@ int CALLBACK wWinMain(HINSTANCE hinst, HINSTANCE hpinst,
wr.right-wr.left, wr.bottom-wr.top,
0, 0, g.hinst, 0
);
- g.pc = pacc_init_d3d9(g.fmdspwnd, render_cb, 0, &g.pacc, &g.pacc_win, WM_PACC_RESET, g.mainwnd);
+ g.pc = pacc_init_d3d9(g.fmdspwnd, PC98_W, PC98_H, render_cb, 0, &g.pacc, &g.pacc_win, WM_PACC_RESET, g.mainwnd);
if (!g.pc) {
MessageBox(g.mainwnd, L"Error", L"Cannot initialize Direct3D", MB_ICONSTOP);
return 0;