diff --git a/src/vid_cga.c b/src/vid_cga.c index 247dbf3..4f3d8c4 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -148,6 +148,7 @@ void cga_poll(void *p) if (cga->displine < cga->firstline) { cga->firstline = cga->displine; + video_wait_for_buffer(); // printf("Firstline %i\n",firstline); } cga->lastline = cga->displine; diff --git a/src/vid_ega.c b/src/vid_ega.c index 57880b5..61101eb 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -271,7 +271,10 @@ void ega_poll(void *p) if (ega->dispon) { if (ega->firstline == 2000) + { ega->firstline = ega->displine; + video_wait_for_buffer(); + } if (ega->scrblank) { diff --git a/src/vid_hercules.c b/src/vid_hercules.c index b9832f0..eb80b38 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -139,6 +139,7 @@ void hercules_poll(void *p) if (hercules->displine < hercules->firstline) { hercules->firstline = hercules->displine; + video_wait_for_buffer(); } hercules->lastline = hercules->displine; cols[0] = 0; diff --git a/src/vid_incolor.c b/src/vid_incolor.c index c7e2e5b..722bfe5 100644 --- a/src/vid_incolor.c +++ b/src/vid_incolor.c @@ -861,6 +861,7 @@ void incolor_poll(void *p) if (incolor->displine < incolor->firstline) { incolor->firstline = incolor->displine; + video_wait_for_buffer(); } incolor->lastline = incolor->displine; if ((incolor->ctrl & INCOLOR_CTRL_GRAPH) && (incolor->ctrl2 & INCOLOR_CTRL2_GRAPH)) diff --git a/src/vid_mda.c b/src/vid_mda.c index 3897624..5b5befc 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -123,7 +123,8 @@ void mda_poll(void *p) { if (mda->displine < mda->firstline) { - mda->firstline = mda->displine; + mda->firstline = mda->displine; + video_wait_for_buffer(); } mda->lastline = mda->displine; cols[0] = 0; diff --git a/src/vid_pc1512.c b/src/vid_pc1512.c index 9fd57e4..7f2c506 100644 --- a/src/vid_pc1512.c +++ b/src/vid_pc1512.c @@ -179,7 +179,10 @@ static void pc1512_poll(void *p) if (pc1512->dispon) { if (pc1512->displine < pc1512->firstline) + { pc1512->firstline = pc1512->displine; + video_wait_for_buffer(); + } pc1512->lastline = pc1512->displine; for (c = 0; c < 8; c++) { diff --git a/src/vid_pcjr.c b/src/vid_pcjr.c index 0183672..c6eae5f 100644 --- a/src/vid_pcjr.c +++ b/src/vid_pcjr.c @@ -217,7 +217,10 @@ void pcjr_poll(void *p) uint16_t mask = 0x1fff; if (pcjr->displine < pcjr->firstline) - pcjr->firstline = pcjr->displine; + { + pcjr->firstline = pcjr->displine; + video_wait_for_buffer(); + } pcjr->lastline = pcjr->displine; cols[0] = (pcjr->array[2] & 0xf) + 16; for (c = 0; c < 8; c++) diff --git a/src/vid_svga.c b/src/vid_svga.c index d691772..9bac226 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -484,8 +484,11 @@ void svga_poll(void *p) svga->hdisp_on=1; svga->ma &= svga->vrammask; - if (svga->firstline == 2000) + if (svga->firstline == 2000) + { svga->firstline = svga->displine; + video_wait_for_buffer(); + } if (svga->hwcursor_on || svga->overlay_on) svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] = 2; diff --git a/src/vid_tandy.c b/src/vid_tandy.c index 87b618a..c4b3112 100644 --- a/src/vid_tandy.c +++ b/src/vid_tandy.c @@ -236,6 +236,7 @@ void tandy_poll(void *p) if (tandy->displine < tandy->firstline) { tandy->firstline = tandy->displine; + video_wait_for_buffer(); // printf("Firstline %i\n",firstline); } tandy->lastline = tandy->displine; diff --git a/src/vid_tandysl.c b/src/vid_tandysl.c index cacc20b..3843a52 100644 --- a/src/vid_tandysl.c +++ b/src/vid_tandysl.c @@ -283,6 +283,7 @@ static void tandysl_poll(void *p) if (tandy->displine < tandy->firstline) { tandy->firstline = tandy->displine; + video_wait_for_buffer(); // printf("Firstline %i\n",firstline); } tandy->lastline = tandy->displine; diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 6d83fd3..2b0aa96 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -4202,7 +4202,10 @@ void voodoo_callback(void *p) voodoo->dirty_line[voodoo->line] = 0; if (voodoo->line < voodoo->dirty_line_low) + { voodoo->dirty_line_low = voodoo->line; + video_wait_for_buffer(); + } if (voodoo->line > voodoo->dirty_line_high) voodoo->dirty_line_high = voodoo->line; diff --git a/src/video.c b/src/video.c index eac9554..2ee75dc 100644 --- a/src/video.c +++ b/src/video.c @@ -9,6 +9,7 @@ #include "io.h" #include "cpu.h" #include "rom.h" +#include "thread.h" #include "timer.h" #include "vid_ati18800.h" @@ -213,8 +214,8 @@ int video_timing_b, video_timing_w, video_timing_l; int video_res_x, video_res_y, video_bpp; -void (*video_blit_memtoscreen)(int x, int y, int y1, int y2, int w, int h); -void (*video_blit_memtoscreen_8)(int x, int y, int w, int h); +void (*video_blit_memtoscreen_func)(int x, int y, int y1, int y2, int w, int h); +void (*video_blit_memtoscreen_8_func)(int x, int y, int w, int h); void video_init() { @@ -359,6 +360,19 @@ void loadfont(char *s, int format) fclose(f); } +static struct +{ + int x, y, y1, y2, w, h, blit8; + int busy; + int buffer_in_use; + + thread_t *blit_thread; + event_t *wake_blit_thread; + event_t *blit_complete; + event_t *buffer_not_in_use; +} blit_data; + +static void blit_thread(void *param); void initvideo() { @@ -413,12 +427,85 @@ void initvideo() for (c = 0; c < 65536; c++) video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19); + blit_data.wake_blit_thread = thread_create_event(); + blit_data.blit_complete = thread_create_event(); + blit_data.buffer_not_in_use = thread_create_event(); + blit_data.blit_thread = thread_create(blit_thread, NULL); } void closevideo() { + thread_kill(blit_data.blit_thread); + thread_destroy_event(blit_data.buffer_not_in_use); + thread_destroy_event(blit_data.blit_complete); + thread_destroy_event(blit_data.wake_blit_thread); + free(video_15to32); free(video_16to32); destroy_bitmap(buffer); destroy_bitmap(buffer32); } + + +static void blit_thread(void *param) +{ + while (1) + { + thread_wait_event(blit_data.wake_blit_thread, -1); + thread_reset_event(blit_data.wake_blit_thread); + + if (blit_data.blit8) + video_blit_memtoscreen_8_func(blit_data.x, blit_data.y, blit_data.w, blit_data.h); + else + video_blit_memtoscreen_func(blit_data.x, blit_data.y, blit_data.y1, blit_data.y2, blit_data.w, blit_data.h); + + blit_data.busy = 0; + thread_set_event(blit_data.blit_complete); + } +} + +void video_blit_complete() +{ + blit_data.buffer_in_use = 0; + thread_set_event(blit_data.buffer_not_in_use); +} + +void video_wait_for_blit() +{ + while (blit_data.busy) + thread_wait_event(blit_data.blit_complete, -1); + thread_reset_event(blit_data.blit_complete); +} +void video_wait_for_buffer() +{ + while (blit_data.buffer_in_use) + thread_wait_event(blit_data.buffer_not_in_use, -1); + thread_reset_event(blit_data.buffer_not_in_use); +} + +void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) +{ + video_wait_for_blit(); + blit_data.busy = 1; + blit_data.buffer_in_use = 1; + blit_data.x = x; + blit_data.y = y; + blit_data.y1 = y1; + blit_data.y2 = y2; + blit_data.w = w; + blit_data.h = h; + blit_data.blit8 = 0; + thread_set_event(blit_data.wake_blit_thread); +} + +void video_blit_memtoscreen_8(int x, int y, int w, int h) +{ + video_wait_for_blit(); + blit_data.busy = 1; + blit_data.x = x; + blit_data.y = y; + blit_data.w = w; + blit_data.h = h; + blit_data.blit8 = 1; + thread_set_event(blit_data.wake_blit_thread); +} diff --git a/src/video.h b/src/video.h index 9183e7d..9c8dd77 100644 --- a/src/video.h +++ b/src/video.h @@ -67,8 +67,11 @@ extern int readflash; extern void (*video_recalctimings)(); -extern void (*video_blit_memtoscreen)(int x, int y, int y1, int y2, int w, int h); -extern void (*video_blit_memtoscreen_8)(int x, int y, int w, int h); +void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); +void video_blit_memtoscreen_8(int x, int y, int w, int h); + +extern void (*video_blit_memtoscreen_func)(int x, int y, int y1, int y2, int w, int h); +extern void (*video_blit_memtoscreen_8_func)(int x, int y, int w, int h); extern int video_timing_b, video_timing_w, video_timing_l; extern int video_speed; @@ -76,3 +79,6 @@ extern int video_speed; extern int video_res_x, video_res_y, video_bpp; extern int vid_resize; + +void video_wait_for_blit(); +void video_wait_for_buffer(); diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index 4005cb5..9eeae57 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -17,6 +17,8 @@ static void d3d_fs_close_objects(); static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h); +extern "C" void video_blit_complete(); + static LPDIRECT3D9 d3d = NULL; static LPDIRECT3DDEVICE9 d3ddev = NULL; static LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; @@ -120,8 +122,8 @@ void d3d_fs_init(HWND h) d3d_fs_init_objects(); - video_blit_memtoscreen = d3d_fs_blit_memtoscreen; - video_blit_memtoscreen_8 = d3d_fs_blit_memtoscreen_8; + video_blit_memtoscreen_func = d3d_fs_blit_memtoscreen; + video_blit_memtoscreen_8_func = d3d_fs_blit_memtoscreen_8; } static void d3d_fs_close_objects() @@ -307,7 +309,31 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) double l, t, r, b; if (y1 == y2) + { + video_blit_complete(); return; /*Nothing to do*/ + } + + if (hr == D3D_OK && !(y1 == 0 && y2 == 0)) + { + RECT lock_rect; + + lock_rect.top = y1; + lock_rect.left = 0; + lock_rect.bottom = y2; + lock_rect.right = 2047; + + if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) + fatal("LockRect failed\n"); + + for (yy = y1; yy < y2; yy++) + memcpy(dr.pBits + ((yy - y1) * dr.Pitch), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + + video_blit_complete(); + d3dTexture->UnlockRect(0); + } + else + video_blit_complete(); d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; @@ -337,24 +363,6 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) if (hr == D3D_OK) hr = v_buffer->Unlock(); - if (hr == D3D_OK && !(y1 == 0 && y2 == 0)) - { - RECT lock_rect; - - lock_rect.top = y1; - lock_rect.left = 0; - lock_rect.bottom = y2; - lock_rect.right = 2047; - - if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) - fatal("LockRect failed\n"); - - for (yy = y1; yy < y2; yy++) - memcpy(dr.pBits + ((yy - y1) * dr.Pitch), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); - - d3dTexture->UnlockRect(0); - } - if (hr == D3D_OK) hr = d3ddev->BeginScene(); @@ -400,8 +408,40 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) double l, t, r, b; if (!h) + { + video_blit_complete(); return; /*Nothing to do*/ + } + if (hr == D3D_OK) + { + RECT lock_rect; + + lock_rect.top = 0; + lock_rect.left = 0; + lock_rect.bottom = 2047; + lock_rect.right = 2047; + + if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) + fatal("LockRect failed\n"); + + for (yy = 0; yy < h; yy++) + { + uint32_t *p = (uint32_t *)(dr.pBits + (yy * dr.Pitch)); + if ((y + yy) >= 0 && (y + yy) < buffer->h) + { + for (xx = 0; xx < w; xx++) + p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; + } + } + + video_blit_complete(); + + d3dTexture->UnlockRect(0); + } + else + video_blit_complete(); + d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; @@ -430,31 +470,6 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) if (hr == D3D_OK) hr = v_buffer->Unlock(); - if (hr == D3D_OK) - { - RECT lock_rect; - - lock_rect.top = 0; - lock_rect.left = 0; - lock_rect.bottom = 2047; - lock_rect.right = 2047; - - if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) - fatal("LockRect failed\n"); - - for (yy = 0; yy < h; yy++) - { - uint32_t *p = (uint32_t *)(dr.pBits + (yy * dr.Pitch)); - if ((y + yy) >= 0 && (y + yy) < buffer->h) - { - for (xx = 0; xx < w; xx++) - p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; - } - } - - d3dTexture->UnlockRect(0); - } - if (hr == D3D_OK) hr = d3ddev->BeginScene(); diff --git a/src/win-d3d.cc b/src/win-d3d.cc index d239c2c..c08f887 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -10,6 +10,7 @@ extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); extern "C" void device_force_redraw(); +extern "C" void video_blit_complete(); void d3d_init_objects(); void d3d_close_objects(); @@ -98,8 +99,8 @@ void d3d_init(HWND h) d3d_init_objects(); - video_blit_memtoscreen = d3d_blit_memtoscreen; - video_blit_memtoscreen_8 = d3d_blit_memtoscreen_8; + video_blit_memtoscreen_func = d3d_blit_memtoscreen; + video_blit_memtoscreen_8_func = d3d_blit_memtoscreen_8; } void d3d_close_objects() @@ -231,9 +232,31 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) RECT r; uint32_t *p, *src; int yy; - + if (y1 == y2) + { + video_blit_complete(); return; /*Nothing to do*/ + } + + r.top = y1; + r.left = 0; + r.bottom = y2; + r.right = 2047; + + if (hr == D3D_OK) + { + if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) + fatal("LockRect failed\n"); + + for (yy = y1; yy < y2; yy++) + memcpy(dr.pBits + ((yy - y1) * dr.Pitch), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + + video_blit_complete(); + d3dTexture->UnlockRect(0); + } + else + video_blit_complete(); d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; @@ -253,22 +276,6 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) if (hr == D3D_OK) hr = v_buffer->Unlock(); // unlock the vertex buffer - r.top = y1; - r.left = 0; - r.bottom = y2; - r.right = 2047; - - if (hr == D3D_OK) - { - if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) - fatal("LockRect failed\n"); - - for (yy = y1; yy < y2; yy++) - memcpy(dr.pBits + ((yy - y1) * dr.Pitch), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); - - d3dTexture->UnlockRect(0); - } - if (hr == D3D_OK) hr = d3ddev->BeginScene(); @@ -310,25 +317,10 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) HRESULT hr = D3D_OK; if (h == 0) + { + video_blit_complete(); return; /*Nothing to do*/ - - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; - - GetClientRect(d3d_hwnd, &r); - d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; - d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; - d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5; - d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5; - - if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer - if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer - if (hr == D3D_OK) - hr = v_buffer->Unlock(); // unlock the vertex buffer + } r.top = 0; r.left = 0; @@ -349,10 +341,31 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; } } + video_blit_complete(); d3dTexture->UnlockRect(0); } + else + video_blit_complete(); + d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; + d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; + d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; + d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; + + GetClientRect(d3d_hwnd, &r); + d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; + d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; + d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5; + d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5; + + if (hr == D3D_OK) + hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer + if (hr == D3D_OK) + memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer + if (hr == D3D_OK) + hr = v_buffer->Unlock(); // unlock the vertex buffer + if (hr == D3D_OK) hr = d3ddev->BeginScene(); diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index 4919dd7..993c397 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -13,6 +13,8 @@ extern "C" void device_force_redraw(); extern "C" void ddraw_fs_init(HWND h); extern "C" void ddraw_fs_close(); +extern "C" void video_blit_complete(); + static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h); @@ -105,8 +107,8 @@ void ddraw_fs_init(HWND h) pclog("DDRAW_INIT complete\n"); ddraw_hwnd = h; - video_blit_memtoscreen = ddraw_fs_blit_memtoscreen; - video_blit_memtoscreen_8 = ddraw_fs_blit_memtoscreen_8; + video_blit_memtoscreen_func = ddraw_fs_blit_memtoscreen; + video_blit_memtoscreen_8_func = ddraw_fs_blit_memtoscreen_8; } void ddraw_fs_close() @@ -207,9 +209,14 @@ static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); device_force_redraw(); } - if (!ddsd.lpSurface) return; + if (!ddsd.lpSurface) + { + video_blit_complete(); + return; + } for (yy = y1; yy < y2; yy++) memcpy(ddsd.lpSurface + (yy * ddsd.lPitch), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + video_blit_complete(); lpdds_back->Unlock(NULL); window_rect.left = 0; @@ -274,7 +281,11 @@ static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h) lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); device_force_redraw(); } - if (!ddsd.lpSurface) return; + if (!ddsd.lpSurface) + { + video_blit_complete(); + return; + } for (yy = 0; yy < h; yy++) { if ((y + yy) >= 0 && (y + yy) < buffer->h) @@ -284,6 +295,7 @@ static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h) p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; } } + video_blit_complete(); lpdds_back->Unlock(NULL); window_rect.left = 0; diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index 42df38f..c658a7a 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -13,6 +13,8 @@ extern "C" void device_force_redraw(); extern "C" void ddraw_init(HWND h); extern "C" void ddraw_close(); +extern "C" void video_blit_complete(); + static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h); @@ -109,8 +111,8 @@ void ddraw_init(HWND h) pclog("DDRAW_INIT complete\n"); ddraw_hwnd = h; - video_blit_memtoscreen = ddraw_blit_memtoscreen; - video_blit_memtoscreen_8 = ddraw_blit_memtoscreen_8; + video_blit_memtoscreen_func = ddraw_blit_memtoscreen; + video_blit_memtoscreen_8_func = ddraw_blit_memtoscreen_8; } void ddraw_close() @@ -150,7 +152,6 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) POINT po; uint32_t *p; HRESULT hr; - // pclog("Blit memtoscreen %i,%i %i %i %i,%i\n", x, y, y1, y2, w, h); memset(&ddsd, 0, sizeof(ddsd)); @@ -163,12 +164,17 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); device_force_redraw(); } - if (!ddsd.lpSurface) return; + if (!ddsd.lpSurface) + { + video_blit_complete(); + return; + } for (yy = y1; yy < y2; yy++) { if ((y + yy) >= 0 && (y + yy) < buffer->h) memcpy(ddsd.lpSurface + (yy * ddsd.lPitch), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); } + video_blit_complete(); lpdds_back->Unlock(NULL); po.x = po.y = 0; @@ -238,7 +244,11 @@ static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h) lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); device_force_redraw(); } - if (!ddsd.lpSurface) return; + if (!ddsd.lpSurface) + { + video_blit_complete(); + return; + } for (yy = 0; yy < h; yy++) { if ((y + yy) >= 0 && (y + yy) < buffer->h) @@ -250,7 +260,8 @@ static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h) } p = (uint32_t *)(ddsd.lpSurface + (4 * ddsd.lPitch)); lpdds_back->Unlock(NULL); - + video_blit_complete(); + po.x = po.y = 0; ClientToScreen(ddraw_hwnd, &po); diff --git a/src/win.c b/src/win.c index 8d6c972..8f383a0 100644 --- a/src/win.c +++ b/src/win.c @@ -181,6 +181,7 @@ void mainthread(LPVOID param) if (!video_fullscreen && win_doresize) { RECT r; + video_wait_for_blit(); GetWindowRect(ghwnd, &r); MoveWindow(ghwnd, r.left, r.top, winsizex + (GetSystemMetrics(SM_CXFIXEDFRAME) * 2), @@ -953,6 +954,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_VID_DDRAW: case IDM_VID_D3D: startblit(); + video_wait_for_blit(); CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED); vid_apis[0][vid_api].close(); vid_api = LOWORD(wParam) - IDM_VID_DDRAW; @@ -970,6 +972,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM MessageBox(hwnd, "Use CTRL + ALT + PAGE DOWN to return to windowed mode", "PCem", MB_OK); } startblit(); + video_wait_for_blit(); mouse_close(); vid_apis[0][vid_api].close(); video_fullscreen = 1; @@ -1268,6 +1271,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM if (vid_apis[video_fullscreen][vid_api].resize) { startblit(); + video_wait_for_blit(); vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); endblit(); }