From 87450e320f7e44850e28ec1ad9faf7b0f0b26bbd Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Sat, 12 May 2018 12:28:07 +0200 Subject: [PATCH] preliminary libretro GLSL shader support https://github.com/libretro/glsl-shaders --- inc/main.h | 1 + inc/opengl.h | 12 ++- src/main.c | 5 +- src/opengl.c | 54 ++++++++++- src/render.c | 239 +++++++++++++++++++++++++++++++++++++++++----- src/render_soft.c | 7 +- 6 files changed, 284 insertions(+), 34 deletions(-) diff --git a/inc/main.h b/inc/main.h index 8b7aadb..da98fea 100644 --- a/inc/main.h +++ b/inc/main.h @@ -90,6 +90,7 @@ typedef struct IDirectDrawImpl BOOL maintas; BOOL fakecursorpos; BOOL noactivateapp; + char shader[MAX_PATH]; } IDirectDrawImpl; diff --git a/inc/opengl.h b/inc/opengl.h index 806f53c..cca8c4d 100644 --- a/inc/opengl.h +++ b/inc/opengl.h @@ -5,7 +5,8 @@ void OpenGL_Init(); BOOL OpenGL_ExtExists(char *ext); -GLuint OpenGL_BuildProgram(const GLchar **vertSource, const GLchar **fragSource); +GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource); +GLuint OpenGL_BuildProgramFromFile(const char *filePath); // Program extern PFNGLCREATEPROGRAMPROC glCreateProgram; @@ -27,6 +28,7 @@ extern PFNGLUNIFORM1FVPROC glUniform1fv; extern PFNGLUNIFORM2FVPROC glUniform2fv; extern PFNGLUNIFORM3FVPROC glUniform3fv; extern PFNGLUNIFORM4FVPROC glUniform4fv; +extern PFNGLUNIFORM4FPROC glUniform4f; extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; extern PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f; @@ -51,6 +53,7 @@ extern PFNGLGENBUFFERSPROC glGenBuffers; extern PFNGLBINDBUFFERPROC glBindBuffer; extern PFNGLBUFFERDATAPROC glBufferData; extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; +extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; extern PFNGLGENBUFFERSARBPROC glGenBuffersARB; extern PFNGLBINDBUFFERARBPROC glBindBufferARB; @@ -62,3 +65,10 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB; extern PFNGLACTIVETEXTUREARBPROC glActiveTexture; extern PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture; extern PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f; + +extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; +extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; +extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; +extern PFNGLDRAWBUFFERSPROC glDrawBuffers; +extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; +extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; diff --git a/src/main.c b/src/main.c index a53e45f..c9cbfa4 100644 --- a/src/main.c +++ b/src/main.c @@ -978,7 +978,7 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk "adjmouse=false\n" "; enable C&C video resize hack, auto = auto-detect game, true = forced, false = disabled\n" "vhack=false\n" - "; switch between OpenGL (opengl) and software (gdi) renderers, latter supports less features but might be faster depending on the GPU\n" + "; switch between OpenGL (opengl) and software (gdi) renderers\n" "renderer=gdi\n" "; force CPU0 affinity, avoids crashes with RA, *might* have a performance impact\n" "singlecpu=true\n" @@ -1146,6 +1146,9 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk This->renderer = render_main; } + // to do: read .glslp config file instead of the shader and apply the correct settings + GetPrivateProfileStringA("ddraw", "shader", "", This->shader, sizeof(This->shader), SettingsIniPath); + GetPrivateProfileStringA("ddraw", "singlecpu", "true", tmp, sizeof(tmp), SettingsIniPath); if (tolower(tmp[0]) == 'y' || tolower(tmp[0]) == 't' || tolower(tmp[0]) == 'e' || tmp[0] == '1') { diff --git a/src/opengl.c b/src/opengl.c index 0e2259d..fccc1a7 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -23,6 +23,7 @@ PFNGLUNIFORM1FVPROC glUniform1fv = NULL; PFNGLUNIFORM2FVPROC glUniform2fv = NULL; PFNGLUNIFORM3FVPROC glUniform3fv = NULL; PFNGLUNIFORM4FVPROC glUniform4fv = NULL; +PFNGLUNIFORM4FPROC glUniform4f = NULL; PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = NULL; PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = NULL; PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f = NULL; @@ -47,6 +48,7 @@ PFNGLGENBUFFERSPROC glGenBuffers = NULL; PFNGLBINDBUFFERPROC glBindBuffer = NULL; PFNGLBUFFERDATAPROC glBufferData = NULL; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL; +PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL; PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL; PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL; @@ -59,6 +61,13 @@ PFNGLACTIVETEXTUREARBPROC glActiveTexture = NULL; PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture = NULL; PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f = NULL; +PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = NULL; +PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = NULL; +PFNGLDRAWBUFFERSPROC glDrawBuffers = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = NULL; +PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = NULL; + void OpenGL_Init() { // Program @@ -81,6 +90,7 @@ void OpenGL_Init() glUniform2fv = (PFNGLUNIFORM2FVPROC)wglGetProcAddress("glUniform2fv"); glUniform3fv = (PFNGLUNIFORM3FVPROC)wglGetProcAddress("glUniform3fv"); glUniform4fv = (PFNGLUNIFORM4FVPROC)wglGetProcAddress("glUniform4fv"); + glUniform4f = (PFNGLUNIFORM4FPROC)wglGetProcAddress("glUniform4f"); glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv"); glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)wglGetProcAddress("glGetAttribLocation"); glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)wglGetProcAddress("glVertexAttrib1f"); @@ -103,6 +113,7 @@ void OpenGL_Init() glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer"); glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData"); glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer"); + glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers"); glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB"); glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB"); @@ -114,6 +125,13 @@ void OpenGL_Init() glActiveTexture = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTexture"); glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)wglGetProcAddress("glClientActiveTexture"); glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)wglGetProcAddress("glMultiTexCoord2f"); + + glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers"); + glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"); + glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D"); + glDrawBuffers = (PFNGLDRAWBUFFERSPROC)wglGetProcAddress("glDrawBuffers"); + glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatus"); + glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffers"); } BOOL OpenGL_ExtExists(char *ext) @@ -127,7 +145,7 @@ BOOL OpenGL_ExtExists(char *ext) return FALSE; } -GLuint OpenGL_BuildProgram(const GLchar **vertSource, const GLchar **fragSource) +GLuint OpenGL_BuildProgram(const GLchar *vertSource, const GLchar *fragSource) { if (!glCreateShader || !glShaderSource || !glCompileShader || !glCreateProgram || !glAttachShader || !glLinkProgram || !glUseProgram || !glDetachShader) @@ -139,8 +157,11 @@ GLuint OpenGL_BuildProgram(const GLchar **vertSource, const GLchar **fragSource) if (!vertShader || !fragShader) return 0; - glShaderSource(vertShader, 1, vertSource, NULL); - glShaderSource(fragShader, 1, fragSource, NULL); + const GLchar *vertSrc[2] = { "#define VERTEX\n", vertSource }; + const GLchar *fragSrc[2] = { "#define FRAGMENT\n", fragSource }; + + glShaderSource(vertShader, 2, vertSrc, NULL); + glShaderSource(fragShader, 2, fragSrc, NULL); GLint isCompiled = 0; @@ -199,3 +220,30 @@ GLuint OpenGL_BuildProgram(const GLchar **vertSource, const GLchar **fragSource) return program; } + +GLuint OpenGL_BuildProgramFromFile(const char *filePath) +{ + GLuint program = 0; + + FILE *file = fopen(filePath, "rb"); + if (file) + { + fseek(file, 0, SEEK_END); + long fileSize = ftell(file); + fseek(file, 0, SEEK_SET); + + char *source = malloc(fileSize + 1); + if (source) + { + fread(source, fileSize, 1, file); + fclose(file); + + source[fileSize] = 0; + + program = OpenGL_BuildProgram(source, source); + free(source); + } + } + + return program; +} diff --git a/src/render.c b/src/render.c index a9c9d66..c0dba40 100644 --- a/src/render.c +++ b/src/render.c @@ -21,7 +21,7 @@ #include "main.h" #include "surface.h" -const GLchar *PaletteVertShaderSrc = +const GLchar *PassthroughVertShaderSrc = "//Vertex shader\n" "#version 110\n" "varying vec2 TexCoord0; \n" @@ -80,6 +80,9 @@ DWORD WINAPI render_main(void) if (ddraw->render.maxfps == 0) ddraw->render.maxfps = 125; + if (ddraw->render.maxfps >= 1000) + ddraw->render.maxfps = 0; + if (ddraw->render.maxfps > 0) frame_len = 1000.0f / ddraw->render.maxfps; @@ -90,7 +93,14 @@ DWORD WINAPI render_main(void) GLuint paletteConvProgram = 0; if (glGetUniformLocation && glActiveTexture && glUniform1i) - paletteConvProgram = OpenGL_BuildProgram(&PaletteVertShaderSrc, &PaletteFragShaderSrc); + paletteConvProgram = OpenGL_BuildProgram(PassthroughVertShaderSrc, PaletteFragShaderSrc); + + GLuint scaleProgram = 0; + if (glGenFramebuffers && glBindFramebuffer && glFramebufferTexture2D && glDrawBuffers && + glCheckFramebufferStatus && glUniform4f && glActiveTexture && glUniform1i && + glGetAttribLocation && glGenBuffers && glBindBuffer && glBufferData && glVertexAttribPointer && + glEnableVertexAttribArray && glUniform2fv && glUniformMatrix4fv) + scaleProgram = OpenGL_BuildProgramFromFile(ddraw->shader); // primary surface texture GLuint surfaceTexId = 0; @@ -125,22 +135,122 @@ DWORD WINAPI render_main(void) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + while (glGetError() != GL_NO_ERROR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + if (glGetError() != GL_NO_ERROR) + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glViewport( ddraw->render.viewport.x, ddraw->render.viewport.y, ddraw->render.viewport.width, ddraw->render.viewport.height); - glBindTexture(GL_TEXTURE_2D, 0); - GLint surfaceUniLoc = 0, paletteUniLoc = 0; if (paletteConvProgram) { - glUseProgram(paletteConvProgram); surfaceUniLoc = glGetUniformLocation(paletteConvProgram, "SurfaceTex"); paletteUniLoc = glGetUniformLocation(paletteConvProgram, "PaletteTex"); } + GLint textureUniLoc = -1, texCoordUniLoc = -1, frameCountUniLoc = -1; + GLuint frameBufferId = 0; + GLuint frameBufferTexId = 0; + GLuint vboBuffers[3]; + + if (scaleProgram) + { + glUseProgram(scaleProgram); + + GLint vertexCoordUniLoc = glGetAttribLocation(scaleProgram, "VertexCoord"); + texCoordUniLoc = glGetAttribLocation(scaleProgram, "TexCoord"); + textureUniLoc = glGetUniformLocation(scaleProgram, "Texture"); + frameCountUniLoc = glGetUniformLocation(scaleProgram, "FrameCount"); + + glGenBuffers(3, vboBuffers); + + glBindBuffer(GL_ARRAY_BUFFER, vboBuffers[0]); + static const GLfloat vertexCoord[] = { + -1.0f, 1.0f, + 1.0f, 1.0f, + 1.0f,-1.0f, + -1.0f,-1.0f, + }; + glBufferData(GL_ARRAY_BUFFER, sizeof(vertexCoord), vertexCoord, GL_STATIC_DRAW); + glVertexAttribPointer(vertexCoordUniLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(vertexCoordUniLoc); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboBuffers[2]); + static const GLushort indices[] = + { + 0, 1, 2, + 0, 2, 3, + }; + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + float inputSize[2], outputSize[2], textureSize[2]; + + inputSize[0] = ddraw->width; + inputSize[1] = ddraw->height; + textureSize[0] = tex_width; + textureSize[1] = tex_height; + outputSize[0] = ddraw->render.viewport.width; + outputSize[1] = ddraw->render.viewport.height; + + glUniform2fv(glGetUniformLocation(scaleProgram, "OutputSize"), 1, outputSize); + glUniform2fv(glGetUniformLocation(scaleProgram, "TextureSize"), 1, textureSize); + glUniform2fv(glGetUniformLocation(scaleProgram, "InputSize"), 1, inputSize); + + glUniform4f(glGetAttribLocation(scaleProgram, "Color"), 1, 1, 1, 1); + glUniform1i(glGetUniformLocation(scaleProgram, "FrameDirection"), 1); + + const float mvpMatrix[16] = { + 1,0,0,0, + 0,1,0,0, + 0,0,1,0, + 0,0,0,1, + }; + glUniformMatrix4fv(glGetUniformLocation(scaleProgram, "MVPMatrix"), 1, GL_FALSE, mvpMatrix); + + glGenFramebuffers(1, &frameBufferId); + glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId); + + glGenTextures(1, &frameBufferTexId); + glBindTexture(GL_TEXTURE_2D, frameBufferTexId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, tex_width, tex_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, frameBufferTexId, 0); + + GLenum drawBuffers[1] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers(1, drawBuffers); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { + glDeleteTextures(1, &frameBufferTexId); + + if (glDeleteFramebuffers) + glDeleteFramebuffers(1, &frameBufferId); + + if (glDeleteProgram) + glDeleteProgram(scaleProgram); + + scaleProgram = 0; + + if (glDeleteBuffers) + glDeleteBuffers(3, vboBuffers); + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + glBindTexture(GL_TEXTURE_2D, 0); + + glEnable(GL_TEXTURE_2D); while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED) @@ -164,19 +274,6 @@ DWORD WINAPI render_main(void) if (ddraw->render.maxfps > 0) tick_start = timeGetTime(); - if (paletteConvProgram) - { - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, paletteTexId); - glUniform1i(paletteUniLoc, 0); - - glActiveTexture(GL_TEXTURE1); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, surfaceTexId); - glUniform1i(surfaceUniLoc, 1); - } - EnterCriticalSection(&ddraw->cs); if (ddraw->primary && ddraw->primary->palette) @@ -230,12 +327,90 @@ DWORD WINAPI render_main(void) glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ddraw->width, ddraw->height, GL_RGBA, GL_UNSIGNED_BYTE, tex); } - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(0, 0); glVertex2f(-1, 1); - glTexCoord2f(scale_w, 0); glVertex2f(1, 1); - glTexCoord2f(scale_w, scale_h); glVertex2f(1, -1); - glTexCoord2f(0, scale_h); glVertex2f(-1, -1); - glEnd(); + if (paletteConvProgram) + { + glUseProgram(paletteConvProgram); + + glActiveTexture(GL_TEXTURE0); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, paletteTexId); + glUniform1i(paletteUniLoc, 0); + + glActiveTexture(GL_TEXTURE1); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, surfaceTexId); + glUniform1i(surfaceUniLoc, 1); + + glActiveTexture(GL_TEXTURE0); + } + + if (scaleProgram) + { + // draw surface into framebuffer + + glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId); + + glPushAttrib(GL_VIEWPORT_BIT); + glViewport(0, 0, tex_width, tex_height); + + glBegin(GL_TRIANGLE_FAN); + glTexCoord2f(0, 0); glVertex2f(-1, -1); + glTexCoord2f(0, 1); glVertex2f(-1, 1); + glTexCoord2f(1, 1); glVertex2f(1, 1); + glTexCoord2f(1, 0); glVertex2f(1, -1); + glEnd(); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glPopAttrib(); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, 0); + + // apply filter + + glBindBuffer(GL_ARRAY_BUFFER, vboBuffers[1]); + + GLfloat texCoord[] = { + 0.0f, 0.0f, + scale_w, 0.0f, + scale_w, scale_h, + 0, scale_h, + }; + + glBufferData(GL_ARRAY_BUFFER, sizeof(texCoord), texCoord, GL_STATIC_DRAW); + glVertexAttribPointer(texCoordUniLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(texCoordUniLoc); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboBuffers[2]); + + glUseProgram(scaleProgram); + glActiveTexture(GL_TEXTURE0); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, frameBufferTexId); + glUniform1i(textureUniLoc, 0); + + static int frames = 1; + if (frameCountUniLoc != -1) + glUniform1i(frameCountUniLoc, frames++); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + else + { + glBegin(GL_TRIANGLE_FAN); + glTexCoord2f(0, 0); glVertex2f(-1, 1); + glTexCoord2f(scale_w, 0); glVertex2f(1, 1); + glTexCoord2f(scale_w, scale_h); glVertex2f(1, -1); + glTexCoord2f(0, scale_h); glVertex2f(-1, -1); + glEnd(); + } + + if (scaleProgram && !paletteConvProgram) + glUseProgram(0); glBindTexture(GL_TEXTURE_2D, 0); @@ -253,14 +428,28 @@ DWORD WINAPI render_main(void) HeapFree(GetProcessHeap(), 0, tex); glDeleteTextures(1, &surfaceTexId); glDeleteTextures(1, &paletteTexId); - + if (glUseProgram) glUseProgram(0); + if (scaleProgram) + { + glDeleteTextures(1, &frameBufferTexId); + + if (glDeleteBuffers) + glDeleteBuffers(3, vboBuffers); + + if (glDeleteFramebuffers) + glDeleteFramebuffers(1, &frameBufferId); + } + if (glDeleteProgram) { if (paletteConvProgram) glDeleteProgram(paletteConvProgram); + + if (scaleProgram) + glDeleteProgram(scaleProgram); } wglMakeCurrent(NULL, NULL); diff --git a/src/render_soft.c b/src/render_soft.c index 3e54212..fed76c1 100644 --- a/src/render_soft.c +++ b/src/render_soft.c @@ -72,14 +72,13 @@ DWORD WINAPI render_soft_main(void) DWORD frame_len = 0; if(ddraw->render.maxfps < 0) - { ddraw->render.maxfps = ddraw->mode.dmDisplayFrequency; - } + + if (ddraw->render.maxfps >= 1000) + ddraw->render.maxfps = 0; if(ddraw->render.maxfps > 0) - { frame_len = 1000.0f / ddraw->render.maxfps; - } while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED) {