diff --git a/main.c b/main.c index 17bbd29..3b4156b 100644 --- a/main.c +++ b/main.c @@ -16,6 +16,7 @@ #include #include +#include #include "ddraw.h" #include "main.h" @@ -272,6 +273,15 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD This->bpp = bpp; This->freq = mode.dmDisplayFrequency; + if(This->render->width < This->width) + { + This->render->width = This->width; + } + if(This->render->height < This->height) + { + This->render->height = This->height; + } + if(This->windowed) { mouse_unlock(); @@ -279,9 +289,9 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD SetWindowLong(This->hWnd, GWL_STYLE, GetWindowLong(This->hWnd, GWL_STYLE) | WS_CAPTION | WS_BORDER); /* center the window with correct dimensions */ - int x = (mode.dmPelsWidth / 2) - (This->width / 2); - int y = (mode.dmPelsHeight / 2) - (This->height / 2); - RECT dst = { x, y, This->width+x, This->height+y }; + int x = (mode.dmPelsWidth / 2) - (This->render->width / 2); + int y = (mode.dmPelsHeight / 2) - (This->render->height / 2); + RECT dst = { x, y, This->render->width+x, This->render->height+y }; AdjustWindowRect(&dst, GetWindowLong(This->hWnd, GWL_STYLE), FALSE); SetWindowPos(This->hWnd, HWND_TOPMOST, dst.left, dst.top, (dst.right - dst.left), (dst.bottom - dst.top), SWP_SHOWWINDOW); } @@ -384,8 +394,56 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk *lplpDD = (LPDIRECTDRAW)This; ddraw = This; - This->windowed = TRUE; - This->render = &render_ddraw; + /* load configuration options from ddraw.ini */ + char cwd[MAX_PATH]; + char ini_path[MAX_PATH]; + char tmp[256]; + GetCurrentDirectoryA(sizeof(cwd), cwd); + snprintf(ini_path, sizeof(ini_path), "%s\\ddraw.ini", cwd); + + GetPrivateProfileStringA("ddraw", "renderer", "ddraw", tmp, sizeof(tmp), ini_path); + if(tolower(tmp[0]) == 'o') + { + This->render = &render_opengl; + } + else + { + This->render = &render_ddraw; + } + + GetPrivateProfileStringA("ddraw", "windowed", "TRUE", tmp, sizeof(tmp), ini_path); + if(tolower(tmp[0]) == 'n' || tolower(tmp[0]) == 'f' || tmp[0] == '0') + { + This->windowed = FALSE; + } + else + { + This->windowed = TRUE; + } + + This->render->maxfps = GetPrivateProfileIntA("ddraw", "maxfps", -1, ini_path); + This->render->width = GetPrivateProfileIntA("ddraw", "width", 640, ini_path); + if(This->render->width < 640) + { + This->render->width = 640; + } + + This->render->height = GetPrivateProfileIntA("ddraw", "height", 400, ini_path); + if(This->render->height < 400) + { + This->render->height = 400; + } + + GetPrivateProfileStringA("ddraw", "filter", tmp, tmp, sizeof(tmp), ini_path); + if(tolower(tmp[0]) == 'l' || tolower(tmp[3]) == 'l') + { + This->render->filter = 1; + } + else + { + This->render->filter = 0; + } + This->render->Initialize(); This->Ref = 0; diff --git a/main.h b/main.h index 928af27..f9865ce 100644 --- a/main.h +++ b/main.h @@ -46,6 +46,11 @@ typedef struct IDirectDrawImpl HRESULT WINAPI (*SetDisplayMode)(DWORD width, DWORD height); HRESULT WINAPI (*RestoreDisplayMode)(void); + int maxfps; + int width; + int height; + int filter; + HANDLE thread; BOOL run; HANDLE ev; diff --git a/render_ddraw.c b/render_ddraw.c index 6cd9a0e..ce27296 100644 --- a/render_ddraw.c +++ b/render_ddraw.c @@ -27,6 +27,11 @@ struct render_ddraw_impl HRESULT WINAPI (*SetDisplayMode)(DWORD width, DWORD height); HRESULT WINAPI (*RestoreDisplayMode)(void); + int maxfps; + int width; + int height; + int filter; + HANDLE thread; BOOL run; HANDLE ev; @@ -46,6 +51,11 @@ struct render_ddraw_impl render_ddraw = render_ddraw_SetDisplayMode, render_ddraw_RestoreDisplayMode, + 0, + 0, + 0, + 0, + NULL, TRUE, NULL, @@ -134,11 +144,19 @@ DWORD WINAPI render_ddraw_main(IDirectDrawSurfaceImpl *surface) IDirectDrawClipper_SetHWnd(clipper, 0, ddraw->hWnd); IDirectDrawSurface_SetClipper(primary, clipper); -#ifdef FRAME_LIMIT DWORD tick_start; DWORD tick_end; - DWORD frame_len = 1000.0f / ddraw->freq; -#endif + DWORD frame_len; + + if(render_ddraw.maxfps < 0) + { + render_ddraw.maxfps = ddraw->freq; + } + + if(render_ddraw.maxfps > 0) + { + frame_len = 1000.0f / render_ddraw.maxfps; + } render_ddraw.ev = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -146,9 +164,11 @@ DWORD WINAPI render_ddraw_main(IDirectDrawSurfaceImpl *surface) { ResetEvent(render_ddraw.ev); -#ifdef FRAME_LIMIT - tick_start = GetTickCount(); -#endif + if(render_ddraw.maxfps > 0) + { + tick_start = GetTickCount(); + } + IDirectDrawSurface_Lock(primary, NULL, &ddsd, DDLOCK_WRITEONLY|DDLOCK_WAIT, NULL); if(surface->palette) @@ -164,14 +184,16 @@ DWORD WINAPI render_ddraw_main(IDirectDrawSurfaceImpl *surface) IDirectDrawSurface_Unlock(primary, NULL); -#ifdef FRAME_LIMIT - tick_end = GetTickCount(); - - if(tick_end - tick_start < frame_len) + if(render_ddraw.maxfps > 0) { - Sleep( frame_len - (tick_end - tick_start) ); + tick_end = GetTickCount(); + + if(tick_end - tick_start < frame_len) + { + Sleep( frame_len - (tick_end - tick_start) ); + } } -#endif + SetEvent(render_ddraw.ev); } diff --git a/render_opengl.c b/render_opengl.c index dcd0db9..e97d792 100644 --- a/render_opengl.c +++ b/render_opengl.c @@ -27,6 +27,11 @@ struct render_opengl_impl HRESULT WINAPI (*SetDisplayMode)(DWORD width, DWORD height); HRESULT WINAPI (*RestoreDisplayMode)(void); + int maxfps; + int width; + int height; + int filter; + HANDLE thread; BOOL run; HANDLE ev; @@ -44,6 +49,11 @@ struct render_opengl_impl render_opengl = render_opengl_SetDisplayMode, render_opengl_RestoreDisplayMode, + 0, + 0, + 0, + 0, + NULL, TRUE, NULL @@ -88,19 +98,28 @@ DWORD WINAPI render_opengl_main(IDirectDrawSurfaceImpl *surface) hRC = wglCreateContext( hDC ); wglMakeCurrent( hDC, hRC ); -#ifdef FRAME_LIMIT DWORD tick_start; DWORD tick_end; - DWORD frame_len = 1000.0f / ddraw->freq; -#endif + DWORD frame_len; + + if(render_opengl.maxfps < 0) + { + render_opengl.maxfps = ddraw->freq; + } + + if(render_opengl.maxfps > 0) + { + frame_len = 1000.0f / render_opengl.maxfps; + } render_opengl.ev = CreateEvent(NULL, TRUE, FALSE, NULL); while(render_opengl.run) { -#ifdef FRAME_LIMIT - tick_start = GetTickCount(); -#endif + if(render_opengl.maxfps > 0) + { + tick_start = GetTickCount(); + } /* convert ddraw surface to opengl texture */ for(i=0; iheight; i++) @@ -111,10 +130,20 @@ DWORD WINAPI render_opengl_main(IDirectDrawSurfaceImpl *surface) } } + glViewport(0, 0, render_opengl.width, render_opengl.height); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, surface->width, surface->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, glTex); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + if(render_opengl.filter) + { + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + } + else + { + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + } glEnable(GL_TEXTURE_2D); @@ -127,14 +156,15 @@ DWORD WINAPI render_opengl_main(IDirectDrawSurfaceImpl *surface) SwapBuffers(hDC); -#ifdef FRAME_LIMIT - tick_end = GetTickCount(); - - if(tick_end - tick_start < frame_len) + if(render_opengl.maxfps > 0) { - Sleep( frame_len - (tick_end - tick_start) ); + tick_end = GetTickCount(); + + if(tick_end - tick_start < frame_len) + { + Sleep( frame_len - (tick_end - tick_start) ); + } } -#endif SetEvent(render_opengl.ev); }