diff -urN ./configure.in ./configure.in --- ./configure.in 2012-11-07 23:05:29 +0900 +++ ./configure.in 2012-11-07 23:30:28 +0900 @@ -2876,6 +2876,11 @@ dnl Do this on all platforms, after everything else. CheckWarnAll +if test \( x$enable_video = xyes -a x$enable_video_opengl = xyes \) -o x$video_opengl = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_OPENGLHQ) + SOURCES="$SOURCES $srcdir/src/video/openglhq/SDL*.c" +fi + # Verify that we have all the platform specific files we need if test x$enable_joystick = xyes; then diff -urN ./include/SDL_config.h.in ./include/SDL_config.h.in --- ./include/SDL_config.h.in 2012-11-07 23:05:31 +0900 +++ ./include/SDL_config.h.in 2012-11-07 23:30:28 +0900 @@ -269,6 +269,7 @@ #undef SDL_VIDEO_DRIVER_GGI #undef SDL_VIDEO_DRIVER_IPOD #undef SDL_VIDEO_DRIVER_NANOX +#undef SDL_VIDEO_DRIVER_OPENGLHQ #undef SDL_VIDEO_DRIVER_OS2FS #undef SDL_VIDEO_DRIVER_PHOTON #undef SDL_VIDEO_DRIVER_PICOGUI diff -urN ./include/SDL_video.h ./include/SDL_video.h --- ./include/SDL_video.h 2012-11-07 23:05:32 +0900 +++ ./include/SDL_video.h 2012-11-07 23:30:28 +0900 @@ -324,6 +324,14 @@ extern DECLSPEC SDL_Rect ** SDLCALL SDL_ListModes(SDL_PixelFormat *format, Uint32 flags); /** + * If possible, retrieves the current resolution of the user's display. If this + * operation is supported and succeeds, the width and height are written to the + * values pointed to by the parameters and 1 is returned. If unsupported or + * unsuccessful, the pointed to values are not touched and 0 is returned. + */ +extern DECLSPEC int SDLCALL SDL_GetDesktopMode(int *width, int *height); + +/** * Set up a video mode with the specified width, height and bits-per-pixel. * * If 'bpp' is 0, it is treated as the current display bits per pixel. diff -urN ./src/events/SDL_keyboard.c ./src/events/SDL_keyboard.c --- ./src/events/SDL_keyboard.c 2012-11-07 23:05:32 +0900 +++ ./src/events/SDL_keyboard.c 2012-11-07 23:19:00 +0900 @@ -32,6 +32,7 @@ /* Global keystate information */ static Uint8 SDL_KeyState[SDLK_LAST]; static SDLMod SDL_ModState; +static int SDL_UseLockKeys; int SDL_TranslateUNICODE = 0; static const char *keynames[SDLK_LAST]; /* Array of keycode names */ @@ -71,6 +72,7 @@ video->InitOSKeymap(this); SDL_EnableKeyRepeat(0, 0); + SDL_UseLockKeys = getenv ("SDL_DISABLE_LOCK_KEYS") == NULL; /* Allow environment override to disable special lock-key behavior */ SDL_NoLockKeys = 0; @@ -401,6 +403,7 @@ SDL_Event event; int posted, repeatable; Uint16 modstate; + int use_lock_keys; SDL_memset(&event, 0, sizeof(event)); @@ -412,6 +415,7 @@ modstate = (Uint16)SDL_ModState; repeatable = 0; + use_lock_keys = SDL_UseLockKeys; if ( state == SDL_PRESSED ) { keysym->mod = (SDLMod)modstate; @@ -419,6 +423,8 @@ case SDLK_UNKNOWN: break; case SDLK_NUMLOCK: + if (!use_lock_keys) + break; modstate ^= KMOD_NUM; if ( SDL_NoLockKeys & SDL_NLK_NUM ) break; @@ -427,6 +433,8 @@ keysym->mod = (SDLMod)modstate; break; case SDLK_CAPSLOCK: + if (!use_lock_keys) + break; modstate ^= KMOD_CAPS; if ( SDL_NoLockKeys & SDL_NLK_CAPS ) break; @@ -470,11 +478,15 @@ case SDLK_UNKNOWN: break; case SDLK_NUMLOCK: + if (!use_lock_keys) + break; if ( SDL_NoLockKeys & SDL_NLK_NUM ) break; /* Only send keydown events */ return(0); case SDLK_CAPSLOCK: + if (!use_lock_keys) + break; if ( SDL_NoLockKeys & SDL_NLK_CAPS ) break; /* Only send keydown events */ diff -urN ./src/events/SDL_mouse.c ./src/events/SDL_mouse.c --- ./src/events/SDL_mouse.c 2012-11-07 23:05:32 +0900 +++ ./src/events/SDL_mouse.c 2012-11-07 23:30:28 +0900 @@ -109,6 +109,8 @@ SDL_MouseMaxY = (Sint16)maxY; } +void (*SDL_MouseFilter)(int relative, Sint16 *x, Sint16 *y) = NULL; + /* These are global for SDL_eventloop.c */ int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x, Sint16 y) { @@ -122,6 +124,8 @@ buttonstate = SDL_ButtonState; } + if (SDL_MouseFilter != NULL) SDL_MouseFilter(relative, &x, &y); + Xrel = x; Yrel = y; if ( relative ) { @@ -203,6 +207,8 @@ SDL_memset(&event, 0, sizeof(event)); + if (SDL_MouseFilter != NULL) SDL_MouseFilter(0, &x, &y); + /* Check parameters */ if ( x || y ) { ClipOffset(&x, &y); diff -urN ./src/main/macosx/SDLMain.m ./src/main/macosx/SDLMain.m --- ./src/main/macosx/SDLMain.m 2012-11-07 23:05:33 +0900 +++ ./src/main/macosx/SDLMain.m 2012-11-07 23:30:28 +0900 @@ -354,6 +354,9 @@ /* Main entry point to executable - should *not* be SDL_main! */ int main (int argc, char **argv) { + /* Enable multithreading as early as possible */ + [NSThread detachNewThreadSelector:@selector(self) toTarget:[NSString string] withObject:nil]; + /* Copy the arguments into a global variable */ /* This is passed if we are launched by double-clicking */ if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { diff -urN ./src/thread/pthread/SDL_systhread.c ./src/thread/pthread/SDL_systhread.c --- ./src/thread/pthread/SDL_systhread.c 2012-11-07 23:05:34 +0900 +++ ./src/thread/pthread/SDL_systhread.c 2012-11-07 23:30:28 +0900 @@ -44,7 +44,18 @@ static void *RunThread(void *data) { +#ifdef SDL_VIDEO_DRIVER_QUARTZ + extern void* QZ_allocPool(); + extern void QZ_freePool(void *p); + void *pool = QZ_allocPool(); +#endif + SDL_RunThread(data); + +#ifdef SDL_VIDEO_DRIVER_QUARTZ + QZ_freePool(pool); +#endif + pthread_exit((void*)0); return((void *)0); /* Prevent compiler warning */ } diff -urN ./src/thread/win32/SDL_sysmutex.c ./src/thread/win32/SDL_sysmutex.c --- ./src/thread/win32/SDL_sysmutex.c 2012-11-07 23:05:34 +0900 +++ ./src/thread/win32/SDL_sysmutex.c 2012-11-07 23:20:30 +0900 @@ -30,7 +30,7 @@ struct SDL_mutex { - HANDLE id; + CRITICAL_SECTION cs; }; /* Create a mutex */ @@ -42,12 +42,7 @@ mutex = (SDL_mutex *)SDL_malloc(sizeof(*mutex)); if ( mutex ) { /* Create the mutex, with initial value signaled */ - mutex->id = CreateMutex(NULL, FALSE, NULL); - if ( ! mutex->id ) { - SDL_SetError("Couldn't create mutex"); - SDL_free(mutex); - mutex = NULL; - } + InitializeCriticalSection(&mutex->cs); } else { SDL_OutOfMemory(); } @@ -58,10 +53,7 @@ void SDL_DestroyMutex(SDL_mutex *mutex) { if ( mutex ) { - if ( mutex->id ) { - CloseHandle(mutex->id); - mutex->id = 0; - } + DeleteCriticalSection(&mutex->cs); SDL_free(mutex); } } @@ -73,10 +65,7 @@ SDL_SetError("Passed a NULL mutex"); return -1; } - if ( WaitForSingleObject(mutex->id, INFINITE) == WAIT_FAILED ) { - SDL_SetError("Couldn't wait on mutex"); - return -1; - } + EnterCriticalSection(&mutex->cs); return(0); } @@ -87,9 +76,6 @@ SDL_SetError("Passed a NULL mutex"); return -1; } - if ( ReleaseMutex(mutex->id) == FALSE ) { - SDL_SetError("Couldn't release mutex"); - return -1; - } + LeaveCriticalSection(&mutex->cs); return(0); } diff -urN ./src/video/SDL_glfuncs.h ./src/video/SDL_glfuncs.h --- ./src/video/SDL_glfuncs.h 2012-11-07 23:05:34 +0900 +++ ./src/video/SDL_glfuncs.h 2012-11-07 23:36:45 +0900 @@ -4,6 +4,7 @@ */ #define SDL_PROC_UNUSED(ret,func,params) SDL_PROC_UNUSED(void,glAccum,(GLenum,GLfloat)) +SDL_PROC(void,glActiveTexture,(GLenum)) SDL_PROC_UNUSED(void,glAlphaFunc,(GLenum,GLclampf)) SDL_PROC_UNUSED(GLboolean,glAreTexturesResident,(GLsizei,const GLuint*,GLboolean*)) SDL_PROC_UNUSED(void,glArrayElement,(GLint)) @@ -11,11 +12,11 @@ SDL_PROC(void,glBindTexture,(GLenum,GLuint)) SDL_PROC_UNUSED(void,glBitmap,(GLsizei,GLsizei,GLfloat,GLfloat,GLfloat,GLfloat,const GLubyte*)) SDL_PROC(void,glBlendFunc,(GLenum,GLenum)) -SDL_PROC_UNUSED(void,glCallList,(GLuint)) +SDL_PROC(void,glCallList,(GLuint)) SDL_PROC_UNUSED(void,glCallLists,(GLsizei,GLenum,const GLvoid*)) -SDL_PROC_UNUSED(void,glClear,(GLbitfield)) +SDL_PROC(void,glClear,(GLbitfield)) SDL_PROC_UNUSED(void,glClearAccum,(GLfloat,GLfloat,GLfloat,GLfloat)) -SDL_PROC_UNUSED(void,glClearColor,(GLclampf,GLclampf,GLclampf,GLclampf)) +SDL_PROC(void,glClearColor,(GLclampf,GLclampf,GLclampf,GLclampf)) SDL_PROC_UNUSED(void,glClearDepth,(GLclampd)) SDL_PROC_UNUSED(void,glClearIndex,(GLfloat)) SDL_PROC_UNUSED(void,glClearStencil,(GLint)) @@ -57,28 +58,28 @@ SDL_PROC_UNUSED(void,glColorPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) SDL_PROC_UNUSED(void,glCopyPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)) SDL_PROC_UNUSED(void,glCopyTexImage1D,(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)) -SDL_PROC_UNUSED(void,glCopyTexImage2D,(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)) +SDL_PROC(void,glCopyTexImage2D,(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)) SDL_PROC_UNUSED(void,glCopyTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)) -SDL_PROC_UNUSED(void,glCopyTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)) +SDL_PROC(void,glCopyTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)) SDL_PROC_UNUSED(void,glCullFace,(GLenum mode)) -SDL_PROC_UNUSED(void,glDeleteLists,(GLuint list, GLsizei range)) -SDL_PROC_UNUSED(void,glDeleteTextures,(GLsizei n, const GLuint *textures)) +SDL_PROC(void,glDeleteLists,(GLuint list, GLsizei range)) +SDL_PROC(void,glDeleteTextures,(GLsizei n, const GLuint *textures)) SDL_PROC_UNUSED(void,glDepthFunc,(GLenum func)) SDL_PROC_UNUSED(void,glDepthMask,(GLboolean flag)) SDL_PROC_UNUSED(void,glDepthRange,(GLclampd zNear, GLclampd zFar)) SDL_PROC(void,glDisable,(GLenum cap)) SDL_PROC_UNUSED(void,glDisableClientState,(GLenum array)) SDL_PROC_UNUSED(void,glDrawArrays,(GLenum mode, GLint first, GLsizei count)) -SDL_PROC_UNUSED(void,glDrawBuffer,(GLenum mode)) +SDL_PROC(void,glDrawBuffer,(GLenum mode)) SDL_PROC_UNUSED(void,glDrawElements,(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)) -SDL_PROC_UNUSED(void,glDrawPixels,(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) +SDL_PROC(void,glDrawPixels,(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) SDL_PROC_UNUSED(void,glEdgeFlag,(GLboolean flag)) SDL_PROC_UNUSED(void,glEdgeFlagPointer,(GLsizei stride, const GLvoid *pointer)) SDL_PROC_UNUSED(void,glEdgeFlagv,(const GLboolean *flag)) SDL_PROC(void,glEnable,(GLenum cap)) -SDL_PROC_UNUSED(void,glEnableClientState,(GLenum array)) +SDL_PROC(void,glEnableClientState,(GLenum array)) SDL_PROC(void,glEnd,(void)) -SDL_PROC_UNUSED(void,glEndList,(void)) +SDL_PROC(void,glEndList,(void)) SDL_PROC_UNUSED(void,glEvalCoord1d,(GLdouble u)) SDL_PROC_UNUSED(void,glEvalCoord1dv,(const GLdouble *u)) SDL_PROC_UNUSED(void,glEvalCoord1f,(GLfloat u)) @@ -92,7 +93,7 @@ SDL_PROC_UNUSED(void,glEvalPoint1,(GLint i)) SDL_PROC_UNUSED(void,glEvalPoint2,(GLint i, GLint j)) SDL_PROC_UNUSED(void,glFeedbackBuffer,(GLsizei size, GLenum type, GLfloat *buffer)) -SDL_PROC_UNUSED(void,glFinish,(void)) +SDL_PROC(void,glFinish,(void)) SDL_PROC(void,glFlush,(void)) SDL_PROC_UNUSED(void,glFogf,(GLenum pname, GLfloat param)) SDL_PROC_UNUSED(void,glFogfv,(GLenum pname, const GLfloat *params)) @@ -100,14 +101,14 @@ SDL_PROC_UNUSED(void,glFogiv,(GLenum pname, const GLint *params)) SDL_PROC_UNUSED(void,glFrontFace,(GLenum mode)) SDL_PROC_UNUSED(void,glFrustum,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) -SDL_PROC_UNUSED(GLuint,glGenLists,(GLsizei range)) +SDL_PROC(GLuint,glGenLists,(GLsizei range)) SDL_PROC(void,glGenTextures,(GLsizei n, GLuint *textures)) SDL_PROC_UNUSED(void,glGetBooleanv,(GLenum pname, GLboolean *params)) SDL_PROC_UNUSED(void,glGetClipPlane,(GLenum plane, GLdouble *equation)) SDL_PROC_UNUSED(void,glGetDoublev,(GLenum pname, GLdouble *params)) SDL_PROC_UNUSED(GLenum,glGetError,(void)) SDL_PROC_UNUSED(void,glGetFloatv,(GLenum pname, GLfloat *params)) -SDL_PROC_UNUSED(void,glGetIntegerv,(GLenum pname, GLint *params)) +SDL_PROC(void,glGetIntegerv,(GLenum pname, GLint *params)) SDL_PROC_UNUSED(void,glGetLightfv,(GLenum light, GLenum pname, GLfloat *params)) SDL_PROC_UNUSED(void,glGetLightiv,(GLenum light, GLenum pname, GLint *params)) SDL_PROC_UNUSED(void,glGetMapdv,(GLenum target, GLenum query, GLdouble *v)) @@ -180,7 +181,7 @@ SDL_PROC(void,glMatrixMode,(GLenum mode)) SDL_PROC_UNUSED(void,glMultMatrixd,(const GLdouble *m)) SDL_PROC_UNUSED(void,glMultMatrixf,(const GLfloat *m)) -SDL_PROC_UNUSED(void,glNewList,(GLuint list, GLenum mode)) +SDL_PROC(void,glNewList,(GLuint list, GLenum mode)) SDL_PROC_UNUSED(void,glNormal3b,(GLbyte nx, GLbyte ny, GLbyte nz)) SDL_PROC_UNUSED(void,glNormal3bv,(const GLbyte *v)) SDL_PROC_UNUSED(void,glNormal3d,(GLdouble nx, GLdouble ny, GLdouble nz)) @@ -219,7 +220,7 @@ SDL_PROC_UNUSED(void,glRasterPos2dv,(const GLdouble *v)) SDL_PROC_UNUSED(void,glRasterPos2f,(GLfloat x, GLfloat y)) SDL_PROC_UNUSED(void,glRasterPos2fv,(const GLfloat *v)) -SDL_PROC_UNUSED(void,glRasterPos2i,(GLint x, GLint y)) +SDL_PROC(void,glRasterPos2i,(GLint x, GLint y)) SDL_PROC_UNUSED(void,glRasterPos2iv,(const GLint *v)) SDL_PROC_UNUSED(void,glRasterPos2s,(GLshort x, GLshort y)) SDL_PROC_UNUSED(void,glRasterPos2sv,(const GLshort *v)) @@ -239,8 +240,8 @@ SDL_PROC_UNUSED(void,glRasterPos4iv,(const GLint *v)) SDL_PROC_UNUSED(void,glRasterPos4s,(GLshort x, GLshort y, GLshort z, GLshort w)) SDL_PROC_UNUSED(void,glRasterPos4sv,(const GLshort *v)) -SDL_PROC_UNUSED(void,glReadBuffer,(GLenum mode)) -SDL_PROC_UNUSED(void,glReadPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)) +SDL_PROC(void,glReadBuffer,(GLenum mode)) +SDL_PROC(void,glReadPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)) SDL_PROC_UNUSED(void,glRectd,(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)) SDL_PROC_UNUSED(void,glRectdv,(const GLdouble *v1, const GLdouble *v2)) SDL_PROC_UNUSED(void,glRectf,(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)) @@ -252,11 +253,11 @@ SDL_PROC_UNUSED(GLint,glRenderMode,(GLenum mode)) SDL_PROC_UNUSED(void,glRotated,(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)) SDL_PROC_UNUSED(void,glRotatef,(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) -SDL_PROC_UNUSED(void,glScaled,(GLdouble x, GLdouble y, GLdouble z)) +SDL_PROC(void,glScaled,(GLdouble x, GLdouble y, GLdouble z)) SDL_PROC_UNUSED(void,glScalef,(GLfloat x, GLfloat y, GLfloat z)) SDL_PROC_UNUSED(void,glScissor,(GLint x, GLint y, GLsizei width, GLsizei height)) SDL_PROC_UNUSED(void,glSelectBuffer,(GLsizei size, GLuint *buffer)) -SDL_PROC_UNUSED(void,glShadeModel,(GLenum mode)) +SDL_PROC(void,glShadeModel,(GLenum mode)) SDL_PROC_UNUSED(void,glStencilFunc,(GLenum func, GLint ref, GLuint mask)) SDL_PROC_UNUSED(void,glStencilMask,(GLuint mask)) SDL_PROC_UNUSED(void,glStencilOp,(GLenum fail, GLenum zfail, GLenum zpass)) @@ -295,7 +296,7 @@ SDL_PROC_UNUSED(void,glTexCoordPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) SDL_PROC(void,glTexEnvf,(GLenum target, GLenum pname, GLfloat param)) SDL_PROC_UNUSED(void,glTexEnvfv,(GLenum target, GLenum pname, const GLfloat *params)) -SDL_PROC_UNUSED(void,glTexEnvi,(GLenum target, GLenum pname, GLint param)) +SDL_PROC(void,glTexEnvi,(GLenum target, GLenum pname, GLint param)) SDL_PROC_UNUSED(void,glTexEnviv,(GLenum target, GLenum pname, const GLint *params)) SDL_PROC_UNUSED(void,glTexGend,(GLenum coord, GLenum pname, GLdouble param)) SDL_PROC_UNUSED(void,glTexGendv,(GLenum coord, GLenum pname, const GLdouble *params)) @@ -305,17 +306,18 @@ SDL_PROC_UNUSED(void,glTexGeniv,(GLenum coord, GLenum pname, const GLint *params)) SDL_PROC_UNUSED(void,glTexImage1D,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) SDL_PROC(void,glTexImage2D,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +SDL_PROC(void,glTexImage3D,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) SDL_PROC_UNUSED(void,glTexParameterf,(GLenum target, GLenum pname, GLfloat param)) SDL_PROC_UNUSED(void,glTexParameterfv,(GLenum target, GLenum pname, const GLfloat *params)) SDL_PROC(void,glTexParameteri,(GLenum target, GLenum pname, GLint param)) SDL_PROC_UNUSED(void,glTexParameteriv,(GLenum target, GLenum pname, const GLint *params)) SDL_PROC_UNUSED(void,glTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)) SDL_PROC(void,glTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) -SDL_PROC_UNUSED(void,glTranslated,(GLdouble x, GLdouble y, GLdouble z)) +SDL_PROC(void,glTranslated,(GLdouble x, GLdouble y, GLdouble z)) SDL_PROC_UNUSED(void,glTranslatef,(GLfloat x, GLfloat y, GLfloat z)) SDL_PROC_UNUSED(void,glVertex2d,(GLdouble x, GLdouble y)) SDL_PROC_UNUSED(void,glVertex2dv,(const GLdouble *v)) -SDL_PROC_UNUSED(void,glVertex2f,(GLfloat x, GLfloat y)) +SDL_PROC(void,glVertex2f,(GLfloat x, GLfloat y)) SDL_PROC_UNUSED(void,glVertex2fv,(const GLfloat *v)) SDL_PROC(void,glVertex2i,(GLint x, GLint y)) SDL_PROC_UNUSED(void,glVertex2iv,(const GLint *v)) diff -urN ./src/video/SDL_sysvideo.h ./src/video/SDL_sysvideo.h --- ./src/video/SDL_sysvideo.h 2012-11-07 23:05:34 +0900 +++ ./src/video/SDL_sysvideo.h 2012-11-07 23:36:45 +0900 @@ -63,6 +63,9 @@ */ SDL_Rect **(*ListModes)(_THIS, SDL_PixelFormat *format, Uint32 flags); + /* Get the current resolution of the user's display. */ + int (*GetDesktopMode)(_THIS, int *width, int *height); + /* Set the requested video mode, returning a surface which will be set to the SDL_VideoSurface. The width and height will already be verified by ListModes(), and the video subsystem is free to @@ -413,6 +416,9 @@ #if SDL_VIDEO_DRIVER_DUMMY extern VideoBootStrap DUMMY_bootstrap; #endif +//#if SDL_VIDEO_DRIVER_OPENGLHQ +extern VideoBootStrap OPENGLHQ_bootstrap; +//#endif /* This is the current video device */ extern SDL_VideoDevice *current_video; diff -urN ./src/video/SDL_video.c ./src/video/SDL_video.c --- ./src/video/SDL_video.c 2012-11-07 23:05:34 +0900 +++ ./src/video/SDL_video.c 2012-11-07 23:36:45 +0900 @@ -78,12 +78,12 @@ #if SDL_VIDEO_DRIVER_GAPI &GAPI_bootstrap, #endif -#if SDL_VIDEO_DRIVER_WINDIB - &WINDIB_bootstrap, -#endif #if SDL_VIDEO_DRIVER_DDRAW &DIRECTX_bootstrap, #endif +#if SDL_VIDEO_DRIVER_WINDIB + &WINDIB_bootstrap, +#endif #if SDL_VIDEO_DRIVER_BWINDOW &BWINDOW_bootstrap, #endif @@ -129,6 +129,9 @@ #if SDL_VIDEO_DRIVER_DUMMY &DUMMY_bootstrap, #endif +//#if SDL_VIDEO_DRIVER_OPENGLHQ + &OPENGLHQ_bootstrap, +//#endif NULL }; @@ -345,6 +348,24 @@ } /* + * If possible, retrieves the current resolution of the user's display. If this + * operation is supported and succeeds, the width and height are written to the + * values pointed to by the parameters and 1 is returned. If unsupported or + * unsuccessful, the pointed to values are not touched and 0 is returned. + */ +int SDL_GetDesktopMode(int *width, int *height) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if (video && video->GetDesktopMode) { + return video->GetDesktopMode(this, width, height); + } else { + return 0; + } +} + +/* * Check to see if a particular video mode is supported. * It returns 0 if the requested mode is not supported under any bit depth, * or returns the bits-per-pixel of the closest available mode with the @@ -706,7 +727,7 @@ */ SDL_VideoSurface = (mode != NULL) ? mode : prev_mode; - if ( (mode != NULL) && (!is_opengl) ) { + if ( (mode != NULL) && (!is_opengl) && !(flags&0x40) ) { /* Sanity check */ if ( (mode->w < width) || (mode->h < height) ) { SDL_SetError("Video mode smaller than requested"); diff -urN ./src/video/openglhq/Makefile ./src/video/openglhq/Makefile --- ./src/video/openglhq/Makefile 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/Makefile 2012-10-17 05:38:26 +0900 @@ -0,0 +1,35 @@ +## Makefile.am for SDL using OpenGL hardware HQ scaling + +all: SDL_openglhq_pass1.h SDL_openglhq_pass2.h SDL_openglhq_pass3.h SDL_openglhq_table.h + +patch: + ( cd ../../..; patch -sp1 < src/video/openglhq/SDL-1.2.diff && ./autogen.sh; ) + touch patch + +clean: + -rm tablebuilder SDL_openglhq_pass1.h SDL_openglhq_pass2.h SDL_openglhq_pass3.h SDL_openglhq_table.h hexdump asciidump + +zip: clean + (cd ..; zip -9 ~/SDL-1.2-openglhq-`date +%Y-%m-%d`.zip openglhq/{Makefile,README,*.diff,*.c,*.h,*.ui,*.fp,*.dat,*.DLL}) + +tablebuilder: tablebuilder.ui tablebuilder.ui.h + { echo '#!/usr/bin/python'; echo 'from qtcanvas import *'; pyuic -x $<; } > tablebuilder + chmod 755 tablebuilder + +HOSTCC=gcc + +asciidump: asciidump.c + $(HOSTCC) -o $(@F) $< + +hexdump: hexdump.c + $(HOSTCC) -o $(@F) $< + +test: test.c + gcc -o test test.c `sdl-config --cflags` `sdl-config --libs` + +%.h: %.fp asciidump + ./asciidump $< $@ + +%.h: %.dat hexdump + ./hexdump $< $@ + diff -urN ./src/video/openglhq/README ./src/video/openglhq/README --- ./src/video/openglhq/README 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/README 2012-10-17 10:42:18 +0900 @@ -0,0 +1,333 @@ +OpenGL-HQ for SDL +================= + +This readme documents version 2012-10-17 of OpenGL-HQ, if you got +a later version there's a slim chance I forgot to update this :) +The current version and screenshots can be downloaded from +http://www.syntax-k.de/projekte/sdl-opengl-hq/ + +OpenGL-HQ is a video "driver" for SDL that uses your graphics hardware +to scale the output to any size you want. It was originally written for +2D games/emulators like dosbox, scummvm or exult. + +WARNING: This is beta quality software. While it works nicely for me +and several other people, expect bugs to be present. If something +doesn't work, first check for a new version. Please mail me if you +encounter anything that's not yet listed in the README. + +Features: + - uses your hardware to get fast scaling + - scales any 2D SDL program + - scales with any scaling factor, even fractional ones + - switches back to the native driver if an app tries to use OpenGL + - portable + - configurable like SDL + - see the screenshots at the URL above, really + +Requirements: + - a Radeon 9600, GeForce 5700 or higher with current driver; + OpenGL extension ARB_fragment_program must be hardware + accelerated, EXT_framebuffer_object is recommended + -- Note: Since 2012, the fragment programs may no longer be + compatible with an acutal 9600. In case of problems + use an older version of *_pass3.fp + - OpenGL-support for your OS in SDL (which means Windows, + Linux/X11 or MacOS X) + +Limitations: + - may show bad performance with programs that already provide + high-resolution output or with high-quality driver settings + (Radeon 9600-9800 class chips are driven at their limits) + - might not work with FSAA enabled + - MacOS X untested (but should work) + - it has become very unlikely, but it is still possible that desktop + resolution is not autodetected correctly; use SDL_OPENGLHQ_FULLRES + in that case + - untested on non-x86 processors/non-mainstream graphics cards, + notably embedded/mobile platforms + +Bugs unlikely to be fixed, or of unknown origin: + - ATI's Triple-Buffering feature interferes with some apps; if you see + lockups or similar, try setting SDL_OPENGLHQ_DOUBLEBUF as shown below + -- needs to be confirmed against current drivers + +Bugs to be fixed: + +none known + +If you see any problems, CHECK THE TROUBLESHOOTING SECTION BELOW. +If your problem is not solved there, please write as detailed as you can: +Tell me what you did (exactly!), what you expected to happen, what +happened instead, and include screen shots of the problem. Include any +relevant config files as well (dosbox.conf for dosxbox, for example). + + + + +How to use (Quickstart) +======================= + +This is a MS Windows quickstart guide. Other systems adjust as needed. + +1) Copy SDL.DLL into the application's directory, overwriting the shipped + version + +2) Create a batch file (using Notepad) with these contents: + +set SDL_VIDEODRIVER=openglhq +set SDL_OPENGLHQ_WINRES=800x600 +.exe + +3) Save the file as .bat in the same directory + as the EXE file is + +4) Double-click this batch file to start the application; Create a shortcut + or adjust existing shortcuts to use this batch file + + + + +Configuration +============= + +Configuration is done via environment variables (just like the rest of SDL). It +is recommended to set these options in a batch file (see previous section). + +SDL_VIDEODRIVER - set it to openglhq to use OpenGL-HQ +SDL_OPENGLHQ_WINRES +SDL_OPENGLHQ_FULLRES - set to a resolution like "960x720" to set the windowed/ + fullscreen size in all windowed/fullscreen modes; you may + add a bit depth as in "960x720-16"; alternatively, you can + specify a fixed scaling factor (like "2.5") + default: windowed: "1", fullscreen: your desktop resolution +SDL_OPENGLHQ_VIDEODRIVER - set to the name of your SDL video device (the one you'd + normally use for SDL_VIDEODRIVER) +SDL_OPENGLHQ_DOUBLEBUF - override application's choice of doublebuffering; if set + to 1, doublebuffering is always on, if set to 0, doublebuffering + is always off; if unset, the application's choice is respected +SDL_OPENGLHQ_STATIC +SDL_OPENGLHQ_DYNAMIC - two parameters which tweak the HQ calculation; the defaults + (static 10, dynamic 33) are fine in most cases; to optimize + rendering, play with these values (static 0-255, dynamic 0-100) +SDL_OPENGLHQ_SHOWFPS - print average FPS to the console every ten seconds; this + only counts frames actually rendered. See FAQ below. +SDL_OPENGLHQ_DATA - a directory with data files for OpenGL-HQ; You can use this + to load your own fragment programs or edge detect table. + Currently, you will have to read the source code for details. + +You must set SDL_VIDEODRIVER to get any effect at all. If you want windowed +applications to be scaled, set SDL_OPENGLHQ_WINRES. Everything else is usually not +neccessary, the settings are autodetected. + +If you want to set options for ALL SDL apps, you can do so: + +Windows: Control Panel -> System Properties -> Advanced -> Environment Variables +Unix-like systems: add "export =" to ~/.profile + + +Performance +=========== + +To put it short: Absolutely great. + +On hardware barely meeting the minimal requirements, running a demanding +protected-mode high-resolution SVGA program in DOSBox with frameskip 0 and +scaling by a factor of 2, performance drops by just 20%. At frameskip 4, +performance difference is at 5-10%. + +At VGA resolution scaling by 4, the difference is reduced even more: +12% performance loss at frameskip 0. Software scaling is far worse: Normal2x +costs about 20%, advmame2x is at 25%, hq2x (not my optimized version, but the +slower HiEnd3D version) about 40%. + +Above measurements done on a single-core Athlon 3700+. On a dual-core processor, +there is no noticeable speed impact, since OpenGL-HQ uses a second core if +available. + + +Troubleshooting +=============== + +Q: Something doesn't work or looks weird. + +A: Check that you are running the latest official video drivers. It has not been + tested with hacked drivers, and old drivers are known to fail. + +Q: DosBox crashes. + +A: DosBox has bad error handling at video initialization. Until that's fixed, + a crash most probably means your hardware doesn't support OpenGL-HQ. + +Q: DosBox locks up when trying to go fullscreen + +A: ATI driver issue. Set "fulldouble=false" in your dosbox.conf, or set + SDL_OPENGLHQ_DOUBLEBUF + +Q: Performance is terrible! + +A: You've probably set forced vsync-waiting in Catalsyst Control Center and your + app wants double buffering (like "fulldouble=true" in DosBox). On a Radeon + 9600-9800 class chip, that's simply too much at higher resolutions. These + first fully programmable chips are used to their limits, so that's barely + surprising. + +Q: It works partly, but some video modes look exactly like before. +Q: Output looks much worse than in your screenshots, blurry and not sharp at all. +Q: WTF? I did everything as shown, and nothing changed? + +A: Disable all software scaling in your program. Many emulators default to some + kind of scaling, but OpenglHQ can only work with x1 (no) scaling. Moreover, + if the program's output is larger than the selected window size, the output + is scaled down using traditional bilinear filtering. + +Q: My mouse is slow! How can I speed it up? +A: This should mostly be fixed in the last release, but your backend video driver + might change acceleration setting when grabbing the mouse. At least the x11 + driver does that, and you can configure it using environment variables. + +Q: I only get 8 FPS! What crap is this software? +A: The screen is not continuously rendered like in native 3D programs. If the + emulator/emulated program only updates the screen 8 times per second, + OpenGL-HQ will show just 8 FPS. If you want to test how fast OpenGL-HQ can + go on your machine, use a program that does frequent screen updates. + +For more help, contact me at info@syntax-k.de. + +Please DO NOT mail Sam Lantinga or the SDL team about this, they aren't involved in this +in any way at all. + + + +Developer info +============== + +If you are an application developer, you can use the "putenv" (POSIX) / "_putenv" +(MSVC) call to change these settings from within your program. For example, if you +want to enable openglhq, just use: + + putenv("SDL_VIDEODRIVER=openglhq"); + +Of course, to be a fair player, you'd want to save the old value of SDL_VIDEODRIVER +first and set SDL_OPENGLHQ_VIDEODRIVER to that value, like this: + +void EnableOpenglHQ() +{ + static char entry[1024], *oldentry; + oldentry = getenv("SDL_VIDEODRIVER"); + if (oldentry != NULL) { + strcpy(entry, "SDL_OPENGLHQ_VIDEODRIVER="); + strcat(entry, oldentry); + putenv(entry); + } + putenv("SDL_VIDEODRIVER=openglhq"); +} + +void DisableOpenglHQ() +{ + static char entry[1024], *oldentry; + oldentry = getenv("SDL_OPENGLHQ_VIDEODRIVER"); + if (oldentry != NULL) { + strcpy(entry, "SDL_VIDEODRIVER="); + strcat(entry, oldentry); + putenv(entry); + } else { + putenv("SDL_VIDEODRIVER"); + } +} + +Do the same for other configuration variables. One exception is SDL_OPENGLHQ_DOUBLEBUF, +this is intended for users only - developers should use the SDL_DOUBLEBUF flag as usual. + +I've included a DosBox patch for those that want to enable openglhq in +dosbox.conf. It applies to a fairly old version of DOSBox, so you may want to +use the DOSBox build from http://ykhwong.x-y.net/ instead, which is kept up to +date and includes OpenGL-HQ support. + + + + +How to compile +============== + +This assumes you know how to compile C programs under a GNUish environment +(Linux, MingW, MacOS X with extra GNU tools). If you never used "cvs", "patch" +or "make" before, try to get a guide on these topics first. [some helpful soul +please send me a link] + +First, get and extract a copy of the SDL-1.2.15 sources. Other versions have not +been tested. + +Then, move the directory "openglhq" (the one this README is in) below src/video + +Then, patch SDL and create needed data files. cd into the SDL directory and run + +make -C src/video/openglhq + +Watch closely for errors! If you see any, check that you have a recent autoconf +and automake installed, and that you are indeed using a clean source tree of +SDL. + +Now run configuration: + +./configure + +Check that it found your OpenGL libraries and headers. If it doesn't, this code +is automatically disabled. Check "./configure --help" to see how to tell SDL the +location of your GL libraries and headers. + +Finally, compile and install: + +make && make install + +The resulting library should be a drop-in replacement for your existing +libSDL.so/SDL.DLL. It should be binary compatible, meaning that none of the apps +using it must be recompiled. + + + + +License +======= + + SDL OpenGL-HQ - Simple DirectMedia Layer high quality hardware scaling + Copyright (C) 2005, 2006, 2012 JΓΆrg Walter + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +The SDL patch uses code published on the SDL mailing list in January 2005 for +desktop resolution autodetect. + +Credits +======= + +Many thanks to all VOGONS users who assited in testing and providing windows +builds. Even more thanks to gulikoza from the VOGONS forums for porting the code +to EXT_framebuffer_object. + + +History +======= + +2012-10-17 fix/improve math precision for modern screen resolutions, fix + partial screen update bug in (default) fast mode, add optional + FPS output +2006-12-15 fix a subtle mouse movemement bug mainly observable in fullscreen + apps, improve API compatibility, reduce needless pixel copying, + working MacOS X support +2006-11-22 fix 16-bit video modes on ATI cards, improve compilation sequence, + improve rendering accuracy and speed by reducing complexity +2006-11-21 use EXT_framebuffer_object extension for rendering, fix threading + issues, improve performance, port to SDL-1.2, make 64-bit-clean + diff -urN ./src/video/openglhq/SDL_ohqthread.h ./src/video/openglhq/SDL_ohqthread.h --- ./src/video/openglhq/SDL_ohqthread.h 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/SDL_ohqthread.h 2012-11-08 00:19:38 +0900 @@ -0,0 +1,1127 @@ +/* + * OpenGL-HQ rendering code Copyright (C) 2004-2005 JΓΆrg Walter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +/* $Id$ */ +/*--------------------------------------------------------------------- + This code implements a hardware-accelerated, cross-platform OpenGL + based scaler quite similar to the well known Hq2x..Hq4x suite of + software scalers. The general idea is exactly the same, but nothing + else remains: in contrast to my software-hq2x scaler for dosbox, not + even the interpolation rules have been used. Instead, they were + designed from scratch to look well even on high scaling factors. + + Some compromises had to be taken, and it is indeed possible that + my choice of rules don't fit some particular game. For this reason, + the built-in table can be overridden by placing a file called + "openglhq_table.dat" into the working directory. It will + be loaded instead of the shipped table. Use the tablebuilder to + edit the table file. Likewise, you can change the fragment programs + used by creating files called "openglhq_passN.fp" for + N = 1..3. + + As with the software hq2x scaler, the difference calculation is + based on the algorithm described in + http://www.compuphase.com/cmetric.htm, and the edge threshold + calculation has entirely been conceived by me. + + Limitations: + + - None. + + - No really, there are none. + + - Believe me, absolutely none. Even performance is great, current + builds use about as much CPU as software normal2x scaling in dosbox, + and that's on a low-end Mobility Radeon 9700. + + - Everything said applies to a Mobility Radeon 9700. Faster cards + might yield the previous statement untrue, I don't own an Nvidia + card, etc. While I tried to create a universal high-performance, + high-quality scaler, YMMV and Send Patches(tm). + +*/ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "SDL.h" +#include "SDL_ohqvideo.h" + +#include +#include +#include +#ifndef _MSC_VER +#include +#endif +#include +#include +#include +#include +#include + +#ifndef _MSC_VER +#include +#include +#include +#endif +#ifndef SCHED_IDLE +#define SCHED_IDLE 5 +#endif + +#include "SDL_opengl.h" + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef O_BINARY +#define O_BINARY (0) +#endif + +#define OHQNAME(x) x +/*SDL_OHQ_ ## x*/ + +typedef void * (APIENTRY * OHQ_malloc_t) (int size, float readfreq, float writefreq, float priority); +typedef void (APIENTRY * OHQ_free_t) (void *pointer); + +static OHQ_malloc_t OHQ_malloc = NULL; +static OHQ_free_t OHQ_free = NULL; + +static PFNGLPIXELDATARANGENVPROC OHQNAME(glPixelDataRangeNV) = NULL; + +/* supported only on fairly recent video cards (somewhere around ATI Radeon 9500 or a similar NVidia card) */ +static PFNGLPROGRAMSTRINGARBPROC OHQNAME(glProgramStringARB) = NULL; +static PFNGLBINDPROGRAMARBPROC OHQNAME(glBindProgramARB) = NULL; +static PFNGLGENPROGRAMSARBPROC OHQNAME(glGenProgramsARB) = NULL; +static PFNGLDELETEPROGRAMSARBPROC OHQNAME(glDeleteProgramsARB) = NULL; +static PFNGLGETPROGRAMIVARBPROC OHQNAME(glGetProgramivARB) = NULL; +static PFNGLPROGRAMLOCALPARAMETER4DARBPROC OHQNAME(glProgramLocalParameter4dARB) = NULL; +static PFNGLPROGRAMENVPARAMETER4DARBPROC OHQNAME(glProgramEnvParameter4dARB) = NULL; +static PFNGLCOLORTABLEEXTPROC OHQNAME(glColorTableEXT) = NULL; + +#include "SDL_openglhq_pass1.h" +#include "SDL_openglhq_pass2.h" +#include "SDL_openglhq_pass3.h" +#include "SDL_openglhq_table.h" + +/* framebuffer object extension */ +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 +typedef void (APIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); +typedef void (APIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); +typedef GLenum (APIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); + +// Constants +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 + +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#endif + +static PFNGLGENFRAMEBUFFERSEXTPROC OHQNAME(glGenFramebuffersEXT) = NULL; +static PFNGLBINDFRAMEBUFFEREXTPROC OHQNAME(glBindFramebufferEXT) = NULL; +static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC OHQNAME(glCheckFramebufferStatusEXT) = NULL; +static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC OHQNAME(glFramebufferTexture2DEXT) = NULL; +static PFNGLDELETEFRAMEBUFFERSEXTPROC OHQNAME(glDeleteFramebuffersEXT) = NULL; + +#define OHQ_RESOLUTION 16 +//#define OGL_DEBUG_HQ +//#define OGL_DEBUG_HQ_MAX +#define OHQ_FAST + +#define fmax(x,y) ((x)>(y)?(x):(y)) +#define fmin(x,y) ((x)<(y)?(x):(y)) + +static int safe_semwait(SDL_sem *sem) { + while (SDL_SemWait(sem) != 0) SDL_Delay(1); + return 0; +} +#define SDL_SemWait safe_semwait + +static int int_log2 (int val) { + int log = 0; + while ((val >>= 1) != 0) + log++; + return log; +} + +/* instead of a plain malloc, we try to be nice to DMA-using hardware */ +#define MALLOC_ALIGN 4096 +#define align_upwards(x) ((void *)((intptr_t)((x) + MALLOC_ALIGN - 1) & ~(MALLOC_ALIGN-1))) +static void * APIENTRY default_malloc(int size, float readfreq, float writefreq, float priority) { + char *ptr = (char *)malloc(size+sizeof(void*)+MALLOC_ALIGN-1); + char *retval = (char *)align_upwards(ptr + sizeof(void*)); + void **real_ptr = (void **)(retval-sizeof(void*)); + *real_ptr = ptr; + return retval; +} + +static void APIENTRY default_free(void *pointer) { + void **real_ptr = (void **)((char *)pointer-sizeof(void*)); + free(*real_ptr); +} + +static unsigned int LoadNativeFragmentProgram(_THIS, const char *program, const char *filename) { + GLuint name; + int errorPos, isNative, programFd; + char programString[65536] = ""; + const char *dir; + + OHQNAME(glGenProgramsARB)(1,&name); + OHQNAME(glBindProgramARB)(GL_FRAGMENT_PROGRAM_ARB,name); + if ((dir = getenv("SDL_OPENGLHQ_DATA")) != NULL) { + strcpy(programString,dir); + strcat(programString,filename); + strcat(programString,".fp"); + + if ((programFd = open(programString,O_RDONLY)) >= 0) { + read(programFd,programString,sizeof(programString)); + close(programFd); + program = programString; + } + } + OHQNAME(glProgramStringARB)(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(program), program); + + this->hidden->real_video->glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos); + OHQNAME(glGetProgramivARB)(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &isNative); + if (errorPos >= 0) { + SDL_SetError("OPENGLHQ: Failed to load fragment program: %s",this->hidden->real_video->glGetString(GL_PROGRAM_ERROR_STRING_ARB)); + OHQNAME(glDeleteProgramsARB)(1,&name); + return 0; + } else if (!isNative) { + SDL_SetError("OPENGLHQ: Hardware doesn't support this fragment program"); + OHQNAME(glDeleteProgramsARB)(1,&name); + return 0; + } + return name; +} + +static double sign(double a) { + return (a < 0?-1:1); +} + +/* + This function calculates what percentage of a rectangle intersected by a line lies near the center of the + cordinate system. It is mathematically exact, and well-tested for xcenter > 0 and ycenter > 0 (it's only + used that way). It should be correct for other cases as well, but well... famous last words :) +*/ +static double intersect_any(double xcenter, double ycenter, double xsize, double ysize, double yoffset, double gradient) { + double g = fabs(gradient)*xsize/ysize; + double o = -((yoffset-ycenter) + gradient*xcenter)/ysize*sign(ycenter)*sign(yoffset)-g*0.5+0.5; + double yl = o, yr = o+g, xb = -o/g, xt = (1-o)/g; + double area = 1.0; + + if (yl >= 1.0) xt = xb = area = 0.0; + else if (yl > 0.0) { + area = 1.0-yl; + xb = 0.0; + } + else if (yr <= 0.0) yl = yr = area = 1.0; + else yl = o+xb*g; + + if (xt <= 0.0) yr = yl = area = 0.0; + else if (xt < 1.0) { + area *= xt; + yr = 1.0; + } + else if (xb >= 1.0) xb = xt = area = 1.0; + else xt = (yr-o)/g; + + area -= (xt-xb)*(yr-yl)/2; + + return area; +} + +static double intersect_h(double xcenter, double ycenter, double xsize, double ysize) { + return fmax(0.0,fmin(1.0,(.55-fabs(xcenter)+xsize/2.0)/xsize)); + //return fmax(0.0,fmin(1.0,(.50-fabs(xcenter)+xsize/2.0)/xsize)); +} + +static double intersect_any_h(double xcenter, double ycenter, double xsize, double ysize, double yoffset, double gradient) { + double hinside = intersect_h(xcenter,ycenter,xsize,ysize); + return hinside*hinside*intersect_any(xcenter,ycenter,xsize,ysize,yoffset,gradient); +} + +static double intersect_v(double xcenter, double ycenter, double xsize, double ysize) { + return fmax(0.0,fmin(1.0,(.55-fabs(ycenter)+ysize/2.0)/ysize)); + //return fmax(0.0,fmin(1.0,(.50-fabs(ycenter)+ysize/2.0)/ysize)); +} + +static double intersect_any_v(double xcenter, double ycenter, double xsize, double ysize, double yoffset, double gradient) { + double vinside = intersect_v(xcenter,ycenter,xsize,ysize); + return vinside*vinside*intersect_any(xcenter,ycenter,xsize,ysize,yoffset,gradient); +} + +static double intersect_hv(double xcenter, double ycenter, double xsize, double ysize) { + double hinside = intersect_h(xcenter,ycenter,xsize,ysize); + double vinside = intersect_v(xcenter,ycenter,xsize,ysize); + return (1-hinside)*(1-vinside)+hinside*vinside; +} + +/* FIXME: not sure if this is correct, but it is rare enough and most likely near enough. fixes welcome :) */ +static double intersect_any_hv(double xcenter, double ycenter, double xsize, double ysize, double yoffset, double gradient) { + double hvinside = intersect_hv(xcenter,ycenter,xsize,ysize); + return hvinside*hvinside*intersect_any(xcenter,ycenter,xsize,ysize,yoffset,gradient); +} + +static double intersect_hvd(double xcenter, double ycenter, double xsize, double ysize) { + return intersect_h(xcenter,ycenter,xsize,ysize)*intersect_v(xcenter,ycenter,xsize,ysize); +} + +static void setinterp(double xcenter, double ycenter, double percentage_inside, int i1, int i2, int i3, int o1, int o2, int o3, unsigned char *factors) { + double d0, d1, d2, d3, percentage_outside, totaldistance_i, totaldistance_o; + xcenter = fabs(xcenter); + ycenter = fabs(ycenter); + d0 = (1-xcenter)*(1-ycenter); + d1 = xcenter*(1-ycenter); + d2 = (1-xcenter)*ycenter; + d3 = xcenter*ycenter; + if (i1 && i2) i3 = 0; + if (o1 && o2) o3 = 0; + percentage_outside = 1.0-percentage_inside; + totaldistance_i = d0+i1*d1+i2*d2+i3*d3; + totaldistance_o = o1*d1+o2*d2+o3*d3+1e-12; /* +1e-12: prevent division by zero */ + + factors[1] = (unsigned char)(((d1/totaldistance_i*percentage_inside*i1)+(d1/totaldistance_o*percentage_outside*o1))*255+.5); + factors[2] = (unsigned char)(((d2/totaldistance_i*percentage_inside*i2)+(d2/totaldistance_o*percentage_outside*o2))*255+.5); + factors[3] = (unsigned char)(((d3/totaldistance_i*percentage_inside*i3)+(d3/totaldistance_o*percentage_outside*o3))*255+.5); + factors[0] = 255-factors[1]-factors[2]-factors[3];/*(unsigned char)((d0/totaldistance_i*percentage_inside)*255+.5);*/ +} + +/* Wanna have gcc fun? #define this as a macro, get a fast machine and go fetch a coffe or two. See how it is used to get an idea why. + I aborted compilation after 5 minutes of CPU time on an Athlon64 3700+. */ +static int swap_bits(int num, int bit1, int bit2) { + return ((num & ~(bit1|bit2))|((num&bit1)?bit2:0)|((num&bit2)?bit1:0)); +} + +/* +static void WaitCommand(_THIS) { + if (this->hidden->busy) SDL_SemWait(this->hidden->render_thread_ack); + this->hidden->busy = 0; +} +*/ + +static void SendAsyncCommand(_THIS, enum OGL_CMD command) { + if (this->hidden->busy) SDL_SemWait(this->hidden->render_thread_ack); + this->hidden->busy = 1; + this->hidden->cmd = command; + SDL_SemPost(this->hidden->render_thread_signal); +} +static int TryWaitCommand(_THIS) { + if (this->hidden->busy && SDL_SemTryWait(this->hidden->render_thread_ack) != 0) return 0; + this->hidden->busy = 0; + return 1; +} + +static int SendSyncCommand(_THIS, enum OGL_CMD command) { + + if (this->hidden->busy) SDL_SemWait(this->hidden->render_thread_ack); + this->hidden->busy = 1; + this->hidden->cmd = command; + SDL_SemPost(this->hidden->render_thread_signal); + SDL_SemWait(this->hidden->render_thread_ack); + + this->hidden->busy = 0; + return (int)(this->hidden->status != OGL_ERROR); +} + +static void Finish(_THIS, GLuint fbo) { + if (fbo) OHQNAME(glBindFramebufferEXT)(GL_FRAMEBUFFER_EXT, fbo); + this->hidden->real_video->glFinish(); + + OHQNAME(glBindProgramARB)(GL_FRAGMENT_PROGRAM_ARB,0); + this->hidden->real_video->glDisable(GL_FRAGMENT_PROGRAM_ARB); + + this->hidden->real_video->glActiveTexture(GL_TEXTURE2); + this->hidden->real_video->glBindTexture(GL_TEXTURE_2D,0); + this->hidden->real_video->glBindTexture(GL_TEXTURE_3D,0); + this->hidden->real_video->glActiveTexture(GL_TEXTURE1); + this->hidden->real_video->glBindTexture(GL_TEXTURE_2D,0); + this->hidden->real_video->glBindTexture(GL_TEXTURE_3D,0); + this->hidden->real_video->glActiveTexture(GL_TEXTURE0); + this->hidden->real_video->glBindTexture(GL_TEXTURE_2D,0); + this->hidden->real_video->glBindTexture(GL_TEXTURE_3D,0); + + this->hidden->real_video->glDisable(GL_TEXTURE_2D); + this->hidden->real_video->glDisable(GL_TEXTURE_3D); + + this->hidden->real_video->glFinish(); + if (fbo) OHQNAME(glBindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0); +} + +static void DeinitOpenGL(_THIS) { + int i; + + if (this->hidden->real_video->glFinish != NULL) { + Finish(this,0); + if (this->hidden->fbo[0]) { + Finish(this,this->hidden->fbo[0]); + Finish(this,this->hidden->fbo[1]); + } + } + + for (i = 0; i < sizeof(this->hidden->program_name)/sizeof(this->hidden->program_name[0]); i++) { + if (this->hidden->program_name[i] != 0) { + OHQNAME(glDeleteProgramsARB)(1,&this->hidden->program_name[i]); + this->hidden->program_name[i] = 0; + } + } + if (this->hidden->texture[0] != 0) { + this->hidden->real_video->glDeleteTextures(4,this->hidden->texture); + this->hidden->real_video->glDeleteLists(this->hidden->pbuffer_displaylist, 1); + this->hidden->real_video->glDeleteLists(this->hidden->displaylist, 1); + this->hidden->texture[0] = 0; + } + + if (this->hidden->fbo[0] != 0) { + OHQNAME(glDeleteFramebuffersEXT)(2, this->hidden->fbo); + this->hidden->fbo[0] = this->hidden->fbo[1] = 0; + } + + if (this->hidden->framebuf != NULL) { + OHQ_free(this->hidden->framebuf); + } +} + +static int showfps = 0; +static int RenderFrame(_THIS, int ack) { + static time_t lasttime = 0; + static int framecnt = 0; +#ifdef OHQ_FAST + static int lastx = 0, lasty = 0, lastex = 0, lastey = 0; + static int tmpx = 0, tmpy = 0, tmpex = 0, tmpey = 0; + int xe, ye, ox, oy, ocw, och, otw, oth; + int x = this->hidden->clip.x-1, y = this->hidden->clip.y-1, cw = this->hidden->clip.w+2, ch = this->hidden->clip.h+2, tw = this->hidden->width, th = this->hidden->height; + int dbuf = (this->hidden->flags&SDL_DOUBLEBUF) != 0; + + if (dbuf) { + tmpx = fmin(x, lastx); + tmpy = fmin(y, lasty); + tmpex = fmax(x+cw, lastex); + tmpey = fmax(y+ch, lastey); + lastx = x; + lasty = y; + lastex = x+cw; + lastey = y+ch; + x = tmpx; + y = tmpy; + cw = tmpex-x; + ch = tmpey-y; + } + + if (x < 0) x = 0; + if (y < 0) y = 0; + if (x+cw > this->hidden->width) cw = this->hidden->width-x; + if (y+ch > this->hidden->height) ch = this->hidden->height-y; + +#else + int dbuf = (this->hidden->flags&SDL_DOUBLEBUF) != 0; + int x = 0, y = 0, cw = this->hidden->width, ch = this->hidden->height, tw = cw, th = ch; +#endif + + this->hidden->real_video->glActiveTexture(GL_TEXTURE0); + this->hidden->real_video->glBindTexture(GL_TEXTURE_2D, this->hidden->texture[0]); + this->hidden->postponed = 0; + this->hidden->real_video->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y, + tw, ch, this->hidden->framebuf_format, + this->hidden->framebuf_datatype, (int)this->hidden->framebuf+y*this->hidden->pitch); + + if (ack) SDL_SemPost(this->hidden->render_thread_ack); + +#ifdef OGL_DEBUG_HQ_MAX + GLubyte buffer[this->hidden->width*this->hidden->height*4]; + int fd = open("framebuf.pam",O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666); + sprintf((char *)buffer,"P7\nWIDTH %i\nHEIGHT %i\nMAXVAL 255\nDEPTH 4\nTUPLTYPE RGB_ALPHA\nENDHDR\n",this->hidden->width,this->hidden->height); + write(fd,buffer,strlen((char *)buffer)); + write(fd,this->hidden->framebuf,this->hidden->pitch*this->hidden->height*2); + close(fd); +#endif + + /* align clip rectangle to reduce render errors due to rounding of coordinates, and add some padding */ + // seems not neccessary anymore + xe = x+cw+30+2; + ye = y+ch+30+2; + ox = x-2; + oy = y-2; + ox = ((int)(x/30))*30; + oy = ((int)(y/30))*30; + xe = ((int)(xe/30))*30; + ye = ((int)(ye/30))*30; + if (ox < 0) ox = 0; + if (oy < 0) oy = 0; + if (xe > tw) xe = tw; + if (ye > th) ye = th; + ocw = xe-ox; + och = ye-oy; + + otw = this->hidden->outwidth; + oth = this->hidden->outheight; + ox = floor(ox*otw/(double)tw); + oy = floor((th-oy-och)*oth/(double)th); + //oy = floor(oy*oth/(double)th); + ocw = ceil(ocw*otw/(double)tw); + och = ceil(och*oth/(double)th); + + if (!this->hidden->nohq) { + this->hidden->real_video->glPushMatrix(); + if (this->hidden->fbo[0]) { + OHQNAME(glBindFramebufferEXT)(GL_FRAMEBUFFER_EXT, this->hidden->fbo[0]); + this->hidden->real_video->glViewport(x,y,cw,ch); + } else { + // "failsafe" fallback for drivers without EXT_framebuffer_object, also see below + // Performance and visual experience is degraded, but still enjoyable. + if (!dbuf) { + this->hidden->real_video->glDrawBuffer(GL_BACK); + this->hidden->real_video->glReadBuffer(GL_BACK); + } + this->hidden->real_video->glViewport(ox,oy,cw,ch); + } + + this->hidden->real_video->glTranslated(-1,-1,0); + this->hidden->real_video->glScaled(tw/(double)cw,th/(double)ch,1); + this->hidden->real_video->glTranslated(1.0-(x/(double)tw*2),1.0-(y/(double)th*2),0); + + OHQNAME(glBindProgramARB)(GL_FRAGMENT_PROGRAM_ARB,this->hidden->program_name[0]); + OHQNAME(glProgramLocalParameter4dARB)(GL_FRAGMENT_PROGRAM_ARB, 0, + ((double)this->hidden->static_threshold)/255.0, 0.0, + 0.0, ((double)this->hidden->dynamic_threshold)/100.0); + OHQNAME(glProgramEnvParameter4dARB)(GL_FRAGMENT_PROGRAM_ARB, 0, + //1.0d/this->hidden->texsize-1.0d/4096, + //1.0d/this->hidden->texsize-1.0d/4096, + 1.0/this->hidden->texsize-1.0/4096, + 1.0/this->hidden->texsize-1.0/4096, + this->hidden->texsize, this->hidden->texsize); + + this->hidden->real_video->glCallList(this->hidden->pbuffer_displaylist); + this->hidden->real_video->glFinish(); + + this->hidden->real_video->glBindTexture(GL_TEXTURE_2D,this->hidden->texture[1]); + if (this->hidden->fbo[0]) OHQNAME(glBindFramebufferEXT)(GL_FRAMEBUFFER_EXT, this->hidden->fbo[1]); + else this->hidden->real_video->glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x, y, ox, oy, cw, ch); + +#ifdef OGL_DEBUG_HQ_MAX + fd = open("diff1.pam",O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666); + sprintf((char *)buffer,"P7\nWIDTH %i\nHEIGHT %i\nMAXVAL 255\nDEPTH 4\nTUPLTYPE RGB_ALPHA\nENDHDR\n",this->hidden->width,this->hidden->height); + write(fd,buffer,strlen((char *)buffer)); + this->hidden->real_video->glReadPixels(0,0,this->hidden->width,this->hidden->height,GL_RGBA,GL_UNSIGNED_BYTE,buffer); + write(fd,buffer,sizeof(buffer)); + close(fd); +#endif + + OHQNAME(glBindProgramARB)(GL_FRAGMENT_PROGRAM_ARB,this->hidden->program_name[1]); + OHQNAME(glProgramLocalParameter4dARB)(GL_FRAGMENT_PROGRAM_ARB, 0, + ((double)this->hidden->static_threshold)/255.0, 0.0, + 0.0, ((double)this->hidden->dynamic_threshold)/100.0); + + this->hidden->real_video->glCallList(this->hidden->pbuffer_displaylist); + this->hidden->real_video->glFinish(); + + this->hidden->real_video->glBindTexture(GL_TEXTURE_2D,this->hidden->texture[0]); + + this->hidden->real_video->glActiveTexture(GL_TEXTURE1); + this->hidden->real_video->glBindTexture(GL_TEXTURE_2D,this->hidden->texture[2]); + + if (this->hidden->fbo[0]) OHQNAME(glBindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0); + else { + this->hidden->real_video->glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x, y, ox, oy, cw, ch); + if (!dbuf) { + this->hidden->real_video->glDrawBuffer(GL_FRONT); + this->hidden->real_video->glReadBuffer(GL_FRONT); + } + } + +#ifdef OGL_DEBUG_HQ_MAX + fd = open("diff2.pam",O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666); + sprintf((char *)buffer,"P7\nWIDTH %i\nHEIGHT %i\nMAXVAL 255\nDEPTH 4\nTUPLTYPE RGB_ALPHA\nENDHDR\n",this->hidden->width,this->hidden->height); + write(fd,buffer,strlen((char *)buffer)); + this->hidden->real_video->glReadPixels(0,0,this->hidden->width,this->hidden->height,GL_RGBA,GL_UNSIGNED_BYTE,buffer); + write(fd,buffer,sizeof(buffer)); + close(fd); +#endif + + this->hidden->real_video->glActiveTexture(GL_TEXTURE0); + + OHQNAME(glBindProgramARB)(GL_FRAGMENT_PROGRAM_ARB,this->hidden->program_name[2]); + OHQNAME(glProgramEnvParameter4dARB)(GL_FRAGMENT_PROGRAM_ARB, 0, + //1.0d/this->hidden->texsize, 1.0d/this->hidden->texsize, + 1.0/this->hidden->texsize, 1.0/this->hidden->texsize, + this->hidden->texsize, this->hidden->texsize); + + this->hidden->real_video->glPopMatrix(); + } + + this->hidden->real_video->glViewport(ox,oy,ocw,och); + this->hidden->real_video->glPushMatrix(); + this->hidden->real_video->glTranslated(-1,-1,0); + this->hidden->real_video->glScaled(otw/(double)ocw,oth/(double)och,1); + this->hidden->real_video->glTranslated(1.0-(ox/(double)otw*2),1.0-(oy/(double)oth*2),0); + this->hidden->real_video->glCallList(this->hidden->displaylist); + this->hidden->real_video->glPopMatrix(); + + if (dbuf) this->hidden->real_video->GL_SwapBuffers(this->hidden->real_video); + + if (showfps) { + time_t now = time(NULL); + framecnt++; + + if (lasttime == 0) { + lasttime = now; + } else if (now > lasttime+10) { + fprintf(stderr, "SDL OpenGL-HQ FPS: %li\n", framecnt/(now-lasttime)); + lasttime = now; + framecnt = 0; + } + } + this->hidden->real_video->glFlush(); + + return 1; +} + +static int InitOpenGL(_THIS) { + int w, h, bpp; + int border, x, y, texsize; + SDL_Surface *surface; + GLfloat tex_width, tex_height; + GLubyte *texture; + double xsize, ysize; + unsigned char table[4096] = SDL_openglhq_table_dat; + int has_fbo = 1; +// double adjust = 0; + + showfps = getenv("SDL_OPENGLHQ_SHOWFPS") != NULL; + + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);//(this->hidden->flags&SDL_DOUBLEBUF)!=0); + if (this->hidden->flags & SDL_FULLSCREEN) { + const char *res, *res2; + if ((res = getenv("SDL_OPENGLHQ_FULLRES")) != NULL) { + w = atoi(res); + res2 = strchr(res,'x'); + if (res2 == NULL) { + double scale = strtod(res,NULL); + w = (int)(this->hidden->width*scale); + h = (int)(this->hidden->height*scale); + bpp = this->hidden->format.BitsPerPixel; + } else { + h = atoi(res2+1); + res = strchr(res,'-'); + if (res != NULL) { + bpp = atoi(res+1); + } else { + bpp = this->hidden->format.BitsPerPixel; + } + } + } else { + w = this->hidden->screen_width; + h = this->hidden->screen_height; + bpp = this->hidden->format.BitsPerPixel; + } + } else { + const char *res, *res2; + if ((res = getenv("SDL_OPENGLHQ_WINRES")) != NULL) { + w = atoi(res); + res2 = strchr(res,'x'); + if (res2 == NULL) { + double scale = strtod(res,NULL); + w = (int)(this->hidden->width*scale); + h = (int)(this->hidden->height*scale); + bpp = this->hidden->format.BitsPerPixel; + } else { + h = atoi(res2+1); + res = strchr(res,'-'); + if (res != NULL) { + bpp = atoi(res+1); + } else { + bpp = this->hidden->format.BitsPerPixel; + } + } + } else { + w = this->hidden->width; + h = this->hidden->height; + bpp = this->hidden->format.BitsPerPixel; + } + } + + if (w <= 0 || h <= 0) { + SDL_SetError("Invalid mode specification in SDL_OPENGLHQ_WINRES/SDL_OPENGLHQ_FULLRES"); + return 0; + } + if (w > this->hidden->screen_width || h > this->hidden->screen_height) { + w = this->hidden->screen_width; + h = this->hidden->screen_height; + } + + surface = SDL_SetVideoMode(w,h,bpp,SDL_OPENGL|(this->hidden->flags&SDL_FULLSCREEN)); + if (surface == NULL) { + SDL_SetError("OPENGLHQ: Can't open drawing surface, are you running in 16bpp (or higher) mode?"); + return 0; + } + this->hidden->outwidth = surface->w; + this->hidden->outheight = surface->h; + + if (this->hidden->max_texsize == 0) { + const char * gl_ext = (const char *)this->hidden->real_video->glGetString(GL_EXTENSIONS); + + if (getenv("SDL_OPENGLHQ_STATIC") != NULL) this->hidden->static_threshold = atoi(getenv("SDL_OPENGLHQ_STATIC")); + else this->hidden->static_threshold = 10; + if (this->hidden->static_threshold > 255) this->hidden->static_threshold = 255; + if (this->hidden->static_threshold < 0) this->hidden->static_threshold = 0; + if (getenv("SDL_OPENGLHQ_DYNAMIC") != NULL) this->hidden->dynamic_threshold = atoi(getenv("SDL_OPENGLHQ_DYNAMIC")); + else this->hidden->dynamic_threshold = 33; + if (this->hidden->dynamic_threshold > 100) this->hidden->dynamic_threshold = 100; + if (this->hidden->dynamic_threshold < 0) this->hidden->dynamic_threshold = 0; + + this->hidden->real_video->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &this->hidden->max_texsize); + OHQNAME(glPixelDataRangeNV) = (PFNGLPIXELDATARANGENVPROC)SDL_GL_GetProcAddress("glPixelDataRangeNV"); + OHQNAME(glColorTableEXT) = (PFNGLCOLORTABLEEXTPROC)SDL_GL_GetProcAddress("glColorTableEXT"); + + if (gl_ext != NULL && *gl_ext) { + this->hidden->has_pixel_data_range=(strstr(gl_ext,"GL_NV_pixel_data_range") != NULL) && OHQNAME(glPixelDataRangeNV) != NULL; + this->hidden->allow_paletted_texture=(strstr(gl_ext,"EXT_paletted_texture") != NULL) && OHQNAME(glColorTableEXT) != NULL; + + } + + if (this->hidden->has_pixel_data_range) { + OHQ_malloc = (OHQ_malloc_t)SDL_GL_GetProcAddress("wglAllocateMemoryNV"); + if (OHQ_malloc == NULL) OHQ_malloc = (OHQ_malloc_t)SDL_GL_GetProcAddress("glXAllocateMemoryNV"); + OHQ_free = (OHQ_free_t)SDL_GL_GetProcAddress("wglFreeMemoryNV"); + if (OHQ_free == NULL) OHQ_free = (OHQ_free_t)SDL_GL_GetProcAddress("glXFreeMemoryNV"); + } + if (OHQ_malloc == NULL) OHQ_malloc = (OHQ_malloc_t)default_malloc; + if (OHQ_free == NULL) OHQ_free = (OHQ_free_t)default_free; + + OHQNAME(glProgramStringARB) = (PFNGLPROGRAMSTRINGARBPROC)SDL_GL_GetProcAddress("glProgramStringARB"); + OHQNAME(glBindProgramARB) = (PFNGLBINDPROGRAMARBPROC)SDL_GL_GetProcAddress("glBindProgramARB"); + OHQNAME(glGenProgramsARB) = (PFNGLGENPROGRAMSARBPROC)SDL_GL_GetProcAddress("glGenProgramsARB"); + OHQNAME(glDeleteProgramsARB) = (PFNGLDELETEPROGRAMSARBPROC)SDL_GL_GetProcAddress("glDeleteProgramsARB"); + OHQNAME(glGetProgramivARB) = (PFNGLGETPROGRAMIVARBPROC)SDL_GL_GetProcAddress("glGetProgramivARB"); + OHQNAME(glProgramLocalParameter4dARB) = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC)SDL_GL_GetProcAddress("glProgramLocalParameter4dARB"); + OHQNAME(glProgramEnvParameter4dARB) = (PFNGLPROGRAMENVPARAMETER4DARBPROC)SDL_GL_GetProcAddress("glProgramEnvParameter4dARB"); + + if (!gl_ext || !*gl_ext || !((strstr(gl_ext,"ARB_fragment_program") != NULL) && + OHQNAME(glProgramStringARB) && OHQNAME(glBindProgramARB) && OHQNAME(glGenProgramsARB) && OHQNAME(glDeleteProgramsARB) && + OHQNAME(glGetProgramivARB) && OHQNAME(glProgramLocalParameter4dARB) && OHQNAME(glProgramEnvParameter4dARB))) { + SDL_SetError("OPENGLHQ: Video driver doesn't support fragment programs"); + return 0; + } + + OHQNAME(glGenFramebuffersEXT) = (PFNGLGENFRAMEBUFFERSEXTPROC)SDL_GL_GetProcAddress("glGenFramebuffersEXT"); + OHQNAME(glBindFramebufferEXT) = (PFNGLBINDFRAMEBUFFEREXTPROC)SDL_GL_GetProcAddress("glBindFramebufferEXT"); + OHQNAME(glCheckFramebufferStatusEXT) = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT"); + OHQNAME(glFramebufferTexture2DEXT) = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)SDL_GL_GetProcAddress("glFramebufferTexture2DEXT"); + OHQNAME(glDeleteFramebuffersEXT) = (PFNGLDELETEFRAMEBUFFERSEXTPROC)SDL_GL_GetProcAddress("glDeleteFramebuffersEXT"); + + if(!OHQNAME(glGenFramebuffersEXT) || !OHQNAME(glBindFramebufferEXT) || + !OHQNAME(glFramebufferTexture2DEXT) || !OHQNAME(glDeleteFramebuffersEXT) || + (strstr(gl_ext,"GL_EXT_framebuffer_object") == NULL)) { + has_fbo = 0; + fprintf(stderr, "OPENGLHQ: Video driver doesn't support framebuffer objects. Using slow fallback renderer.\n"); + } + + } + + this->hidden->framebuf_format = GL_BGRA_EXT; + this->hidden->framebuf_datatype = GL_UNSIGNED_BYTE; + if (this->hidden->bpp == 8 && !this->hidden->allow_paletted_texture) { + this->hidden->bpp = this->hidden->format.BitsPerPixel; + } + if (this->hidden->bpp == 8) { + this->hidden->framebuf_format = GL_COLOR_INDEX8_EXT; + OHQNAME(glColorTableEXT)(GL_TEXTURE_2D,GL_RGBA8,256,GL_RGBA,GL_UNSIGNED_BYTE,this->hidden->pal); + } else if (this->hidden->bpp == 15) { + this->hidden->framebuf_format = GL_BGRA_EXT; + this->hidden->framebuf_datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV; + } else if (this->hidden->bpp == 16) { + this->hidden->framebuf_format = GL_RGB; + this->hidden->framebuf_datatype = GL_UNSIGNED_SHORT_5_6_5; + } else { + this->hidden->bpp = 32; + } + + texsize=this->hidden->texsize=2 << int_log2(this->hidden->width > this->hidden->height ? this->hidden->width : this->hidden->height); + texsize=this->hidden->texsize=2 << int_log2(this->hidden->width > this->hidden->height ? this->hidden->width : this->hidden->height); + tex_width=((GLfloat)(this->hidden->width)/(GLfloat)texsize); + tex_height=((GLfloat)(this->hidden->height)/(GLfloat)texsize); + + if (texsize>this->hidden->max_texsize) { + SDL_SetError("OPENGLHQ: No support for texturesize of %d, falling back to surface",texsize); + return 0; + } + + /* Create the texture and display list */ + this->hidden->real_video->glMatrixMode(GL_PROJECTION); + this->hidden->real_video->glGenTextures(4,this->hidden->texture); + + this->hidden->pitch=this->hidden->width*((this->hidden->bpp+7)/8); + this->hidden->framebuf = OHQ_malloc(this->hidden->pitch*this->hidden->height+MALLOC_ALIGN,0.0,1.0,1.0);; + + if (this->hidden->has_pixel_data_range) { + OHQNAME(glPixelDataRangeNV)(GL_WRITE_PIXEL_DATA_RANGE_NV,this->hidden->width*this->hidden->height*4,this->hidden->framebuf); + this->hidden->real_video->glEnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV); + } + + if ((this->hidden->program_name[0] = LoadNativeFragmentProgram(this, SDL_openglhq_pass1_fp,"SDL_openglhq_pass1")) == 0 || + (this->hidden->program_name[1] = LoadNativeFragmentProgram(this, SDL_openglhq_pass2_fp,"SDL_openglhq_pass2")) == 0 || + (this->hidden->program_name[2] = LoadNativeFragmentProgram(this, SDL_openglhq_pass3_fp,"SDL_openglhq_pass3")) == 0) { + SDL_SetError("OPENGLHQ: Hardware doesn't support this output"); + return 0; + } + + this->hidden->nohq = 1; + this->hidden->fbo[0] = this->hidden->fbo[1] = 0; + if (this->hidden->width < this->hidden->outwidth && this->hidden->height < this->hidden->outheight) { + this->hidden->nohq = 0; + + this->hidden->real_video->glBindTexture(GL_TEXTURE_2D, this->hidden->texture[1]); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + this->hidden->real_video->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + this->hidden->real_video->glBindTexture(GL_TEXTURE_2D, this->hidden->texture[2]); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + this->hidden->real_video->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + if (has_fbo) { + OHQNAME(glGenFramebuffersEXT)(2, this->hidden->fbo); + + OHQNAME(glBindFramebufferEXT)(GL_FRAMEBUFFER_EXT, this->hidden->fbo[0]); + OHQNAME(glFramebufferTexture2DEXT)(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, this->hidden->texture[1], 0); + + OHQNAME(glBindFramebufferEXT)(GL_FRAMEBUFFER_EXT, this->hidden->fbo[1]); + OHQNAME(glFramebufferTexture2DEXT)(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, this->hidden->texture[2], 0); + + OHQNAME(glBindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0); + } + } + + if ((this->hidden->flags&SDL_DOUBLEBUF) == 0) { + this->hidden->real_video->glDrawBuffer(GL_FRONT); + this->hidden->real_video->glReadBuffer(GL_FRONT); + } + this->hidden->real_video->glActiveTexture(GL_TEXTURE2); + this->hidden->real_video->glEnable(GL_TEXTURE_3D); + this->hidden->real_video->glBindTexture(GL_TEXTURE_3D, this->hidden->texture[3]); + this->hidden->real_video->glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE); + this->hidden->real_video->glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_REPLACE); + this->hidden->real_video->glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA,GL_REPLACE); + this->hidden->real_video->glTexEnvi(GL_TEXTURE_ENV,GL_SRC0_RGB,GL_TEXTURE0); + this->hidden->real_video->glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB,GL_SRC_COLOR); + this->hidden->real_video->glTexEnvi(GL_TEXTURE_ENV,GL_SRC0_ALPHA,GL_TEXTURE0); + this->hidden->real_video->glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA,GL_SRC_ALPHA); + + texture = (GLubyte *)malloc(OHQ_RESOLUTION*OHQ_RESOLUTION*4096*4); + xsize = (double)this->hidden->width/(double)this->hidden->outwidth; + ysize = (double)this->hidden->height/(double)this->hidden->outheight; + + /* + Table layout is a bit convoluted to be better processable in + fragment programs and to save space. Use the table builder + to modify it. If you are interested in details, read its source. + */ + if (getenv("SDL_OPENGLHQ_DATA")) { + char file[4096]; + int tablefd; + strcpy(file,getenv("SDL_OPENGLHQ_DATA")); + strcat(file,"openglhq_table.dat"); + if ((tablefd = open(file,O_RDONLY|O_BINARY)) >= 0) { + read(tablefd,table,sizeof(table)); + close(tablefd); + } + } + +#define R 1 +#define T 2 +#define RT 4 +#define RT2 8 +#define L 16 +#define LB2 32 +#define LT2 64 +#define LT 128 +#define LB 256 +#define B 512 +#define RB2 1024 +#define RB 2048 + +#define NODIAG 0x90 +#define H 1 +#define V 2 +#define D 4 + +#define hmirror(p) swap_bits(swap_bits(swap_bits(swap_bits(swap_bits(p,R,L),RT,LT),RT2,LT2),RB,LB),RB2,LB2) +#define vmirror(p) swap_bits(swap_bits(swap_bits(swap_bits(swap_bits(p,T,B),RT,RB),RT2,RB2),LT,LB),LT2,LB2) +#define NO_BORDER(x) ((b&(x)) == 0) +#define IS_BORDER(x) ((b&(x)) == (x)) +#define SETINTERP(percentage_inside) setinterp(xcenter,ycenter,percentage_inside, \ + NO_BORDER(R),NO_BORDER(T),NO_BORDER(RT), \ + IS_BORDER(R),IS_BORDER(T),IS_BORDER(RT), \ + texture+((x+(border%16)*OHQ_RESOLUTION+y*16*OHQ_RESOLUTION+(border&~15)*OHQ_RESOLUTION*OHQ_RESOLUTION)*4)) + +/* if (getenv("SDL_OPENGLHQ_ADJUST")) + adjust = atof(getenv("SDL_OPENGLHQ_ADJUST")); + if (adjust == 0) adjust = 1.025; //1.0438 = ATI fglrx; 1.025 = generic +*/ +#define adjust 1 + //OHQNAME(glProgramEnvParameter4dARB)(GL_FRAGMENT_PROGRAM_ARB, 1, 1.0d/.875d, -(1.0d/.875d-1.0d)/2, .875/adjust, (1-.875/adjust)/2); + OHQNAME(glProgramEnvParameter4dARB)(GL_FRAGMENT_PROGRAM_ARB, 1, 1.0/.875, -(1.0/.875-1.0)/2, .875/adjust, (1-.875/adjust)/2); + + for (border = 0; border < 4096; border++) { + for (y = 0; y < OHQ_RESOLUTION; y++) { + for (x = 0; x < OHQ_RESOLUTION; x++) { + double xcenter = fabs((((double)x)+.5)/(double)(OHQ_RESOLUTION)-.5)*adjust; + double ycenter = fabs((((double)y)+.5)/(double)(OHQ_RESOLUTION)-.5)*adjust; + int sx = (x < OHQ_RESOLUTION/2?-1:1); + int sy = (y < OHQ_RESOLUTION/2?-1:1); + int b = (sy > 0?(sx > 0?border:hmirror(border)):(sx > 0?vmirror(border):vmirror(hmirror(border)))); + + if ((table[b] & NODIAG) == NODIAG) { + if (table[b] & H) { + if (table[b] & V) { + if (table[b] & D) SETINTERP(intersect_hvd(xcenter,ycenter,xsize,ysize)); + else SETINTERP(intersect_hv(xcenter,ycenter,xsize,ysize)); + } else { + SETINTERP(intersect_h(xcenter,ycenter,xsize,ysize)); + } + } else if (table[b] & V) { + SETINTERP(intersect_v(xcenter,ycenter,xsize,ysize)); + } else { + SETINTERP(1.0); + } + } else { + double yoff = (table[b]&4?1:-1)*(((table[b] >> 3) & 3) + 1)/4.0; + double grad = (table[b]&32?1:-1)*(((table[b] >> 6) & 3) + 1)/2.0; + if (table[b] & H) { + if (table[b] & V) { + SETINTERP(intersect_any_hv(xcenter,ycenter,xsize,ysize,yoff,grad)); + } else { + SETINTERP(intersect_any_h(xcenter,ycenter,xsize,ysize,yoff,grad)); + } + } else if (table[b] & V) { + SETINTERP(intersect_any_v(xcenter,ycenter,xsize,ysize,yoff,grad)); + } else { + SETINTERP(intersect_any(xcenter,ycenter,xsize,ysize,yoff,grad)); + } + } + + } + } + } +#ifdef OGL_DEBUG_HQ_MAX + int fd = open("texture.pam",O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666); + sprintf((char *)table,"P7\nWIDTH %i\nHEIGHT %i\nMAXVAL 255\nDEPTH 4\nTUPLTYPE RGB_ALPHA\nENDHDR\n",16*OHQ_RESOLUTION,4096/16*OHQ_RESOLUTION); + write(fd,table,strlen((char *)table)); + write(fd,texture,OHQ_RESOLUTION*OHQ_RESOLUTION*4096*4); + close(fd); +#endif + + this->hidden->real_video->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 16*OHQ_RESOLUTION, OHQ_RESOLUTION, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture); + free(texture); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + this->hidden->real_video->glActiveTexture(GL_TEXTURE0); + this->hidden->real_video->glBindTexture(GL_TEXTURE_2D,this->hidden->texture[0]); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (this->hidden->nohq?GL_LINEAR:GL_NEAREST)); + this->hidden->real_video->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->hidden->nohq?GL_LINEAR:GL_NEAREST)); + + this->hidden->real_video->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, 0, this->hidden->framebuf_format, GL_UNSIGNED_BYTE, NULL); + this->hidden->real_video->glFinish(); + + this->hidden->real_video->glShadeModel(GL_FLAT); + this->hidden->real_video->glDisable(GL_DEPTH_TEST); + this->hidden->real_video->glDisable(GL_ALPHA_TEST); + this->hidden->real_video->glDisable(GL_STENCIL_TEST); + this->hidden->real_video->glDisable(GL_SCISSOR_TEST); + this->hidden->real_video->glDisable(GL_BLEND); + this->hidden->real_video->glDisable(GL_DITHER); + this->hidden->real_video->glDisable(GL_INDEX_LOGIC_OP); + this->hidden->real_video->glDisable(GL_COLOR_LOGIC_OP); + this->hidden->real_video->glDisable(GL_LIGHTING); + this->hidden->real_video->glDisable(GL_CULL_FACE); + this->hidden->real_video->glDisable(GL_FOG); + this->hidden->real_video->glEnable(GL_TEXTURE_2D); + if (this->hidden->nohq) { + this->hidden->real_video->glDisable(GL_FRAGMENT_PROGRAM_ARB); + } else { + this->hidden->real_video->glEnable(GL_FRAGMENT_PROGRAM_ARB); + } + this->hidden->real_video->glMatrixMode(GL_MODELVIEW); + this->hidden->real_video->glLoadIdentity(); + + this->hidden->pbuffer_displaylist = this->hidden->real_video->glGenLists(1); + this->hidden->real_video->glNewList(this->hidden->pbuffer_displaylist, GL_COMPILE); + this->hidden->real_video->glBegin(GL_QUADS); + this->hidden->real_video->glTexCoord2f(0,0); this->hidden->real_video->glVertex2f(-1.0f,-1.0f); + this->hidden->real_video->glTexCoord2f(tex_width,0); this->hidden->real_video->glVertex2f(1.0f, -1.0f); + this->hidden->real_video->glTexCoord2f(tex_width,tex_height); this->hidden->real_video->glVertex2f(1.0f, 1.0f); + this->hidden->real_video->glTexCoord2f(0,tex_height); this->hidden->real_video->glVertex2f(-1.0f, 1.0f); + this->hidden->real_video->glEnd(); + this->hidden->real_video->glEndList(); + + this->hidden->displaylist = this->hidden->real_video->glGenLists(1); + this->hidden->real_video->glNewList(this->hidden->displaylist, GL_COMPILE); + this->hidden->real_video->glBindTexture(GL_TEXTURE_2D, this->hidden->texture[0]); + this->hidden->real_video->glBegin(GL_QUADS); + this->hidden->real_video->glTexCoord2f(0,tex_height); this->hidden->real_video->glVertex2f(-1.0f,-1.0f); + this->hidden->real_video->glTexCoord2f(tex_width,tex_height); this->hidden->real_video->glVertex2f(1.0f, -1.0f); + this->hidden->real_video->glTexCoord2f(tex_width,0); this->hidden->real_video->glVertex2f(1.0f, 1.0f); + this->hidden->real_video->glTexCoord2f(0,0); this->hidden->real_video->glVertex2f(-1.0f, 1.0f); + this->hidden->real_video->glEnd(); + this->hidden->real_video->glEndList(); + this->hidden->real_video->glFinish(); + return 1; +} + +static int RenderThread(void *data) { + SDL_VideoDevice *this = (SDL_VideoDevice *)data; + SDL_Rect **modes; + const char *driver; + this->hidden->status = OGL_DONE; + current_video = NULL; + if ((driver = getenv("SDL_OPENGLHQ_VIDEODRIVER")) != NULL && !strcmp(driver,"openglhq")) driver = NULL; + SDL_VideoInit(driver, 0); + if (current_video == NULL) { + SDL_SetError("Unable to initialize backend video device, check SDL_OPENGLHQ_VIDEODRIVER"); + this->hidden->status = OGL_ERROR; + } else { + current_video->GL_LoadLibrary(current_video,NULL); + if (current_video->GetDesktopMode != NULL) { + current_video->GetDesktopMode(current_video,&this->hidden->screen_width,&this->hidden->screen_height); + } else { + modes = SDL_ListModes(NULL,SDL_OPENGL|SDL_FULLSCREEN); + if (((intptr_t)modes) != -1 && modes && *modes) { + this->hidden->screen_width = modes[0]->w; + this->hidden->screen_height = modes[0]->h; + } + } + } + SDL_SemPost(this->hidden->render_thread_ack); + + while (SDL_SemWait(this->hidden->render_thread_signal) >= 0) { + if (this->hidden->postponed && this->hidden->cmd != OGL_FRAME) { + RenderFrame(this, 0); + } + + this->hidden->status = OGL_DONE; + + if (this->hidden->cmd == OGL_CALL) { + switch (this->hidden->call.type) { + case OGL_CALL_P: + this->hidden->call.func.p(this->hidden->real_video); + break; + case OGL_CALL_PII: + this->hidden->call.func.pii(this->hidden->real_video,(int)this->hidden->call.args[0],(int)this->hidden->call.args[1]); + break; + case OGL_CALL_PPP: + this->hidden->call.func.ppp(this->hidden->real_video,(const void*)this->hidden->call.args[0],(const void*)this->hidden->call.args[1]); + break; + case OGL_CALL_PP: + this->hidden->call.func.pp(this->hidden->real_video,(const void*)this->hidden->call.args[0]); + break; + case OGL_CALL_PPPIIII_P: + this->hidden->call.result = (intptr_t)this->hidden->call.func.pppiiii_p(this->hidden->real_video,(const void*)this->hidden->call.args[0],(const void*)this->hidden->call.args[1], + (int)this->hidden->call.args[2],(int)this->hidden->call.args[3],(int)this->hidden->call.args[4],(int)this->hidden->call.args[5]); + break; + case OGL_CALL_PP_I: + this->hidden->call.result = (intptr_t)this->hidden->call.func.pp_i(this->hidden->real_video,(const void*)this->hidden->call.args[0]); + break; + case OGL_CALL_P_I: + this->hidden->call.result = (intptr_t)this->hidden->call.func.p_i(this->hidden->real_video); + break; + case OGL_CALL_PI_I: + this->hidden->call.result = (intptr_t)this->hidden->call.func.pi_i(this->hidden->real_video,(int)this->hidden->call.args[0]); + break; + default: + this->hidden->status = OGL_ERROR; + } + + } else if (this->hidden->cmd == OGL_INIT) { + if (!InitOpenGL(this)) { + this->hidden->status = OGL_ERROR; + DeinitOpenGL(this); + } + +#ifndef __WIN32__ + // FIXME: ugly hack that probably only works on Linux, improves app responsiveness + setpriority(PRIO_PROCESS, getpid()+1, 19); + { // This is a bit more portable (should work on any POSIX/pthreads system), but SCHED_IDLE is ineffective on unpatched Linux + struct sched_param param = { 0 }; + pthread_setschedparam(pthread_self(), SCHED_IDLE, ¶m); + } +#endif + } else if (this->hidden->cmd == OGL_DEINIT) { + DeinitOpenGL(this); + + } else if (this->hidden->cmd == OGL_FRAME) { + if (!RenderFrame(this, 1)) this->hidden->status = OGL_ERROR; + + } else if (this->hidden->cmd == OGL_PALETTE && this->hidden->allow_paletted_texture) { + this->hidden->real_video->glActiveTexture(GL_TEXTURE0); + OHQNAME(glColorTableEXT)(GL_TEXTURE_2D, GL_RGBA8, 256, GL_RGBA, GL_UNSIGNED_BYTE, this->hidden->pal); + + } else if (this->hidden->cmd == OGL_NONE) { + + } else if (this->hidden->cmd == OGL_QUIT) { + break; + + } else { + this->hidden->status = OGL_ERROR; + } + SDL_SemPost(this->hidden->render_thread_ack); + } + SDL_VideoQuit(); + SDL_SemPost(this->hidden->render_thread_ack); + return 0; +} + +static void StartRenderThread(_THIS) { + this->hidden->cmd = OGL_DONE; + this->hidden->render_thread_signal = SDL_CreateSemaphore(0); + this->hidden->render_thread_ack = SDL_CreateSemaphore(0); + this->hidden->render_thread = SDL_CreateThread(&RenderThread,this); + SDL_SemWait(this->hidden->render_thread_ack); +} + +static void ShutdownRenderThread(_THIS) { + if (this->hidden->render_thread != NULL) { + SendSyncCommand(this,OGL_DEINIT); + SendSyncCommand(this,OGL_QUIT); + SDL_WaitThread(this->hidden->render_thread, NULL); + SDL_DestroySemaphore(this->hidden->render_thread_signal); + SDL_DestroySemaphore(this->hidden->render_thread_ack); + this->hidden->render_thread = NULL; + } +} + diff -urN ./src/video/openglhq/SDL_ohqvideo.c ./src/video/openglhq/SDL_ohqvideo.c --- ./src/video/openglhq/SDL_ohqvideo.c 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/SDL_ohqvideo.c 2012-11-08 00:20:30 +0900 @@ -0,0 +1,581 @@ +/* + SDL - Simple DirectMedia Layer OpenGL-HQ scaling + Copyright (C) 1997-2004 Sam Lantinga + Copyright (C) 2005 JΓΆrg Walter + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* SDL video driver implementation which outputs onto a scaled OpenGL-surface + with high quality scaling optimized for framebuffer based games +*/ + +#define TRACE //do { fprintf(stderr,"%s:%i: %p->%s(...)\n",__FILE__,__LINE__,SDL_ThreadID(),__FUNCTION__); } while (0) +#include +#include +#include +#include +#ifndef _MSC_VER +#include +#endif +#include "SDL.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_opengl.h" +#include "../SDL_pixels_c.h" +#include "../SDL_cursor_c.h" +#include "../SDL_sysvideo.h" +#include "../../events/SDL_events_c.h" +#include "SDL_ohqvideo.h" + +#include "SDL_ohqthread.h" + +#ifndef SDL_memcpy +#define SDL_memcpy memcpy +#endif + +static void OHQ_MouseFilter(int relative, Sint16 *x, Sint16 *y); +extern void (*SDL_MouseFilter)(int relative, Sint16 *x, Sint16 *y); +static void (*OHQ_NextMouseFilter)(int relative, Sint16 *x, Sint16 *y) = (void *)-1; +static SDL_VideoDevice* filter_video = NULL; +static int OHQ_VideoInit(_THIS, SDL_PixelFormat *vformat); + +/* OHQ driver bootstrap functions */ + +static int OHQ_Available(void) +{ + return 1; +} + +static void OHQ_DeleteDevice(SDL_VideoDevice *device) +{ + free(device->hidden); + free(device); +} + +static void OHQ_Call(_THIS, void (*func)(SDL_VideoDevice*)) +{ + if (this->VideoInit != OHQ_VideoInit) { + func(this); + } else if (SDL_ThreadID() == SDL_GetThreadID(this->hidden->render_thread)) { + func(this->hidden->real_video); + } else { + this->hidden->call.type = OGL_CALL_P; + this->hidden->call.func.p = func; + SendSyncCommand(this,OGL_CALL); + } +} + +static void OHQ_Call_ii(_THIS, void (*func)(SDL_VideoDevice*,int,int), int arg1, int arg2) +{ + if (this->VideoInit != OHQ_VideoInit) { + func(this,arg1,arg2); + } else if (SDL_ThreadID() == SDL_GetThreadID(this->hidden->render_thread)) { + func(this->hidden->real_video,arg1,arg2); + } else { + this->hidden->call.type = OGL_CALL_PII; + this->hidden->call.func.pii = func; + this->hidden->call.args[0] = (intptr_t)arg1; + this->hidden->call.args[1] = (intptr_t)arg2; + SendSyncCommand(this,OGL_CALL); + } +} + +static void OHQ_Call_pp(_THIS, void (*func)(SDL_VideoDevice*,const void*,const void*), const void* arg1, const void* arg2) +{ + if (this->VideoInit != OHQ_VideoInit) { + func(this,arg1,arg2); + } else if (SDL_ThreadID() == SDL_GetThreadID(this->hidden->render_thread)) { + func(this->hidden->real_video,arg1,arg2); + } else { + this->hidden->call.type = OGL_CALL_PPP; + this->hidden->call.func.ppp = func; + this->hidden->call.args[0] = (intptr_t)arg1; + this->hidden->call.args[1] = (intptr_t)arg2; + SendSyncCommand(this,OGL_CALL); + } +} + +static void OHQ_Call_p(_THIS, void (*func)(SDL_VideoDevice*,const void*), const void* arg1) +{ + if (this->VideoInit != OHQ_VideoInit) { + func(this,arg1); + } else if (SDL_ThreadID() == SDL_GetThreadID(this->hidden->render_thread)) { + func(this->hidden->real_video,arg1); + } else { + this->hidden->call.type = OGL_CALL_PP; + this->hidden->call.func.pp = func; + this->hidden->call.args[0] = (intptr_t)arg1; + SendSyncCommand(this,OGL_CALL); + } +} + +static int OHQ_Call_p_i(_THIS, int (*func)(SDL_VideoDevice*,const void*), const void* arg1) +{ + if (this->VideoInit != OHQ_VideoInit) { + return func(this,arg1); + } else if (SDL_ThreadID() == SDL_GetThreadID(this->hidden->render_thread)) { + return func(this->hidden->real_video,arg1); + } else { + this->hidden->call.type = OGL_CALL_PP_I; + this->hidden->call.func.pp_i = func; + this->hidden->call.args[0] = (intptr_t)arg1; + SendSyncCommand(this,OGL_CALL); + return (int)this->hidden->call.result; + } +} + +static int OHQ_Call__i(_THIS, int (*func)(SDL_VideoDevice*)) +{ + if (this->VideoInit != OHQ_VideoInit) { + return func(this); + } else if (SDL_ThreadID() == SDL_GetThreadID(this->hidden->render_thread)) { + return func(this->hidden->real_video); + } else { + this->hidden->call.type = OGL_CALL_P_I; + this->hidden->call.func.p_i = func; + SendSyncCommand(this,OGL_CALL); + return (int)this->hidden->call.result; + } +} + +static int OHQ_Call_i_i(_THIS, int (*func)(SDL_VideoDevice*,int), int arg1) +{ + if (this->VideoInit != OHQ_VideoInit) { + return func(this,arg1); + } else if (SDL_ThreadID() == SDL_GetThreadID(this->hidden->render_thread)) { + return func(this->hidden->real_video,arg1); + } else { + this->hidden->call.type = OGL_CALL_PI_I; + this->hidden->call.func.pi_i = func; + this->hidden->call.args[0] = (intptr_t)arg1; + SendSyncCommand(this,OGL_CALL); + return (int)this->hidden->call.result; + } +} + +static void* OHQ_Call_ppiiii_p(_THIS, void* (*func)(SDL_VideoDevice*,const void*,const void*,int,int,int,int), const void* arg1, const void* arg2, int arg3, int arg4, int arg5, int arg6) +{ + if (this->VideoInit != OHQ_VideoInit) { + return func(this,arg1,arg2,arg3,arg4,arg5,arg6); + } else if (SDL_ThreadID() == SDL_GetThreadID(this->hidden->render_thread)) { + return func(this->hidden->real_video,arg1,arg2,arg3,arg4,arg5,arg6); + } else { + this->hidden->call.type = OGL_CALL_PPPIIII_P; + this->hidden->call.func.pppiiii_p = func; + this->hidden->call.args[0] = (intptr_t)arg1; + this->hidden->call.args[1] = (intptr_t)arg2; + this->hidden->call.args[2] = (intptr_t)arg3; + this->hidden->call.args[3] = (intptr_t)arg4; + this->hidden->call.args[4] = (intptr_t)arg5; + this->hidden->call.args[5] = (intptr_t)arg6; + SendSyncCommand(this,OGL_CALL); + return (void*)this->hidden->call.result; + } +} + +#define SAVE_VIDEO { SDL_VideoDevice *saved_video = current_video; current_video = this->hidden->real_video; +#define RESTORE_VIDEO current_video = saved_video; } +#define SAVE_SCREEN { SDL_Surface *saved_screen = this->hidden->real_video->screen; this->hidden->real_video->screen = this->screen; +#define RESTORE_SCREEN this->hidden->real_video->screen = saved_screen; } + +static int OHQ_VideoInit(_THIS, SDL_PixelFormat *vformat) +{ + const SDL_VideoInfo *vinfo; + + SAVE_VIDEO; + + StartRenderThread(this); + this->hidden->real_video = current_video; + vinfo = SDL_GetVideoInfo(); + SDL_memcpy(vformat,(SDL_PixelFormat*)vinfo->vfmt,sizeof(*vinfo->vfmt)); + SDL_memcpy((void *)&this->hidden->format,(SDL_PixelFormat*)vinfo->vfmt,sizeof(*vinfo->vfmt)); + + RESTORE_VIDEO; + + return(0); +} + +static void OHQ_SwitchOff(_THIS) { + static char env[1024] = "SDL_VIDEODRIVER="; + SendSyncCommand(this,OGL_NONE); + current_video = this->hidden->real_video; + strcat(env,current_video->name); + ShutdownRenderThread(this); + putenv(env); + SDL_VideoInit(NULL,0); + free(this->hidden); + SDL_memcpy(this, current_video, sizeof(*current_video)); + current_video = this; + if (OHQ_NextMouseFilter != (void *)-1) { + SDL_MouseFilter = OHQ_NextMouseFilter; + OHQ_NextMouseFilter = (void *)-1; + } +} + +static SDL_Rect **OHQ_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) { + if (flags & SDL_OPENGL) { + OHQ_SwitchOff(this); + return current_video->ListModes(current_video, format, flags); + } + return (SDL_Rect **)(intptr_t)(format->BitsPerPixel == 8 && !this->hidden->allow_paletted_texture?0:-1); +} + +static SDL_Surface *OHQ_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { + if (flags & SDL_OPENGL) { + OHQ_SwitchOff(this); + return current_video->SetVideoMode(current_video,current,width,height,bpp,flags); + } + + SDL_UnlockCursor(); + + SendSyncCommand(this,OGL_NONE); + filter_video = current_video; + SAVE_VIDEO; + if (!SendSyncCommand(this,OGL_DEINIT)) return NULL; + if (this->hidden->surface == NULL) { + this->hidden->surface = malloc(sizeof(*current)); + SDL_memcpy((SDL_Surface *)this->hidden->surface,current,sizeof(*current)); + } + flags &= ~(SDL_HWPALETTE|SDL_HWSURFACE|SDL_ASYNCBLIT); + + // some video drivers can't handle odd widths properly + width = (width+1)&~1; + + this->hidden->width = width; + this->hidden->height = height; + this->hidden->flags = flags; + if (getenv("SDL_OPENGLHQ_DOUBLEBUF")) { + if (getenv("SDL_OPENGLHQ_DOUBLEBUF")[0] == '1') this->hidden->flags |= SDL_DOUBLEBUF; + else this->hidden->flags &= ~(SDL_DOUBLEBUF); + } + this->hidden->bpp = bpp; + this->hidden->postponed = 0; + if (!SendSyncCommand(this,OGL_INIT)) return NULL; + if (OHQ_NextMouseFilter == (void *)-1) { + OHQ_NextMouseFilter = SDL_MouseFilter; + SDL_MouseFilter = OHQ_MouseFilter; + } + bpp = this->hidden->bpp; + + if (!SDL_ReallocFormat(current, bpp, (bpp==32?0xff0000:bpp==16?0xf800:0x7c00), (bpp==32?0xff00:bpp==16?0x7e0:0x3e0), (bpp==32?0xff:0x1f), 0)) { + return NULL; + } + + current->w = this->hidden->width; + current->h = this->hidden->height; + current->pitch = this->hidden->pitch; + current->flags = flags|SDL_PREALLOC; + if (bpp == 8) current->flags |= SDL_HWPALETTE; + current->pixels = this->hidden->framebuf; + this->input_grab = this->hidden->real_video->input_grab; + + this->hidden->clip.x = 0; + this->hidden->clip.y = 0; + this->hidden->clip.w = current->w; + this->hidden->clip.h = current->h; + + RESTORE_VIDEO; + + return current; +} + +static void OHQ_UpdateMouse(_THIS) { + SAVE_VIDEO; + //SAVE_SCREEN; + OHQ_Call(this,this->hidden->real_video->UpdateMouse); + //RESTORE_SCREEN; + RESTORE_VIDEO; +} + +static int OHQ_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) { + int i, end = firstcolor+ncolors; + if (end > 256) return 0; + for (i = firstcolor; i < end; i++) { + this->hidden->pal[i].r = colors[i].r; + this->hidden->pal[i].g = colors[i].g; + this->hidden->pal[i].b = colors[i].b; + this->hidden->pal[i].a = 255; + } + SendSyncCommand(this,OGL_PALETTE); + return 1; +} + +static int OHQ_FlipHWSurface(_THIS, SDL_Surface *surface) +{ +TRACE; + if (!this->hidden->dirty) { + if (surface->flags&SDL_DOUBLEBUF) SDL_UpdateRect(surface, 0, 0, 0, 0); + return 0; + } + this->hidden->dirty = 0; + if (!TryWaitCommand(this)) { + this->hidden->postponed = 1; + return 0; + } + + SAVE_VIDEO; + SendAsyncCommand(this,OGL_FRAME); + SDL_SemWait(this->hidden->render_thread_ack); + RESTORE_VIDEO; + return 0; +} + +static void OHQ_UpdateRects(_THIS, int numrects, SDL_Rect *rects) { +//TRACE; + int i, minx = this->hidden->width, miny = this->hidden->height, maxx = 0, maxy = 0; + if (!numrects) return; + + if (this->hidden->postponed) { + minx = this->hidden->clip.x; + miny = this->hidden->clip.y; + maxx = minx+this->hidden->clip.w; + maxy = miny+this->hidden->clip.h; + } + + for (i = 0; i < numrects; i++) { + if (rects[i].x < minx) minx = rects[i].x; + if (rects[i].y < miny) miny = rects[i].y; + if (rects[i].x+rects[i].w > maxx) maxx = rects[i].x+rects[i].w; + if (rects[i].y+rects[i].h > maxy) maxy = rects[i].y+rects[i].h; + } + + this->hidden->clip.x = minx; + this->hidden->clip.y = miny; + this->hidden->clip.w = maxx-minx; + this->hidden->clip.h = maxy-miny; + this->hidden->dirty = 1; + + if (!(this->screen->flags&SDL_DOUBLEBUF)) OHQ_FlipHWSurface(this, this->screen); + return; +} + +static void OHQ_VideoQuit(_THIS) { + SAVE_VIDEO; + ShutdownRenderThread(this); + if (OHQ_NextMouseFilter != (void *)-1) { + SDL_MouseFilter = OHQ_NextMouseFilter; + OHQ_NextMouseFilter = (void *)-1; + } + RESTORE_VIDEO; +} + +static int OHQ_AllocHWSurface(_THIS, SDL_Surface *surface) +{ + return -1; +} + +static void OHQ_FreeHWSurface(_THIS, SDL_Surface *surface) +{ + return; +} + +static int OHQ_LockHWSurface(_THIS, SDL_Surface *surface) +{ +TRACE; + return 0; +} + +static void OHQ_UnlockHWSurface(_THIS, SDL_Surface *surface) +{ +TRACE; + if (surface->flags&SDL_DOUBLEBUF) SDL_UpdateRect(surface, 0, 0, 0, 0); + return; +} + + +static void OHQ_SetCaption(_THIS, const char *title, const char *icon) { + SAVE_VIDEO; + OHQ_Call_pp(this, (void (*)(SDL_VideoDevice*,const void*,const void*))this->hidden->real_video->SetCaption, title, icon); + RESTORE_VIDEO; +} + +static void OHQ_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask) { + SAVE_VIDEO; + OHQ_Call_pp(this, (void (*)(SDL_VideoDevice*,const void*,const void*))this->hidden->real_video->SetIcon, icon, mask); + RESTORE_VIDEO; +} + +static int OHQ_IconifyWindow(_THIS) { + int result; + SAVE_VIDEO; + result = OHQ_Call__i(this, this->hidden->real_video->IconifyWindow); + RESTORE_VIDEO; + return result; +} + +static SDL_GrabMode OHQ_GrabInput(_THIS, SDL_GrabMode mode) { + int result; + SAVE_VIDEO; + result = OHQ_Call_i_i(this, this->hidden->real_video->GrabInput,mode); + current_video->input_grab = result; + RESTORE_VIDEO; + return result; +} + +static int OHQ_GetWMInfo(_THIS, SDL_SysWMinfo *info) { + int result; + SAVE_VIDEO; + result = OHQ_Call_p_i(this, (int (*)(SDL_VideoDevice*,const void*))this->hidden->real_video->GetWMInfo, info); + RESTORE_VIDEO; + return result; +} + +static void OHQ_FreeWMCursor(_THIS, WMcursor *cursor) { + SAVE_VIDEO; + OHQ_Call_p(this, (void (*)(SDL_VideoDevice*,const void*))this->hidden->real_video->FreeWMCursor, cursor); + RESTORE_VIDEO; +} + +static WMcursor *OHQ_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) { + void *result; + SAVE_VIDEO; + result = OHQ_Call_ppiiii_p(this, (void* (*)(SDL_VideoDevice*,const void*,const void*,int,int,int,int))this->hidden->real_video->CreateWMCursor, data, mask, w, h, hot_x, hot_y); + RESTORE_VIDEO; + return result; +} + +static int OHQ_ShowWMCursor(_THIS, WMcursor *cursor) { + int result; + SAVE_VIDEO; + result = OHQ_Call_p_i(this, (int (*)(SDL_VideoDevice*,const void*))this->hidden->real_video->ShowWMCursor, cursor); + RESTORE_VIDEO; + return result; +} + +static void OHQ_WarpWMCursor(_THIS, Uint16 x, Uint16 y) { + SAVE_VIDEO; + OHQ_Call_ii(this, (void (*)(SDL_VideoDevice*,int,int))this->hidden->real_video->WarpWMCursor, x*this->hidden->outwidth/this->hidden->width, y*this->hidden->outheight/this->hidden->height); + RESTORE_VIDEO; +} + +static void OHQ_MoveWMCursor(_THIS, int x, int y) { + if (!this->hidden->real_video->MoveWMCursor) return; + SAVE_VIDEO; + OHQ_Call_ii(this, this->hidden->real_video->MoveWMCursor, x*this->hidden->outwidth/this->hidden->width, y*this->hidden->outheight/this->hidden->height); + RESTORE_VIDEO; +} + +static void OHQ_CheckMouseMode(_THIS) { + SAVE_VIDEO; + OHQ_Call(this, this->hidden->real_video->CheckMouseMode); + RESTORE_VIDEO; +} + +static void OHQ_InitOSKeymap(_THIS) { + SAVE_VIDEO; + OHQ_Call(this, this->hidden->real_video->InitOSKeymap); + RESTORE_VIDEO; +} + +static void OHQ_MouseFilter(int relative, Sint16 *x, Sint16 *y) +{ + if (!relative) { + *x = (*x*filter_video->hidden->width)/filter_video->hidden->outwidth; + *y = (*y*filter_video->hidden->height)/filter_video->hidden->outheight; + } + if (OHQ_NextMouseFilter != NULL) OHQ_NextMouseFilter(relative,x,y); +} + +static void OHQ_PumpEvents(_THIS) { + SAVE_VIDEO; + +#ifdef WIN32 + OHQ_Call(this, this->hidden->real_video->PumpEvents); +#else + this->hidden->real_video->PumpEvents(this->hidden->real_video); + if (this->hidden->postponed && !(this->hidden->postponed++ & 255) && TryWaitCommand(this)) SendSyncCommand(this,OGL_NONE); +#endif + + RESTORE_VIDEO; +} + +static SDL_VideoDevice *OHQ_CreateDevice(int devindex) +{ + SDL_VideoDevice *this; + + /* Initialize all variables that we clean on shutdown */ + this = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); + if (this) { + memset(this, 0, (sizeof *this)); + this->hidden = (struct SDL_PrivateVideoData *)malloc((sizeof *this->hidden)); + } + if ( (this == NULL) || (this->hidden == NULL) ) { + SDL_OutOfMemory(); + if (this) free(this); + return(0); + } + memset(this->hidden, 0, (sizeof *this->hidden)); + + /* Set the function pointers */ + this->VideoInit = OHQ_VideoInit; + this->ListModes = OHQ_ListModes; + this->SetVideoMode = OHQ_SetVideoMode; + this->ToggleFullScreen = NULL; + this->UpdateMouse = OHQ_UpdateMouse; + this->CreateYUVOverlay = NULL; + this->SetColors = OHQ_SetColors; + this->UpdateRects = OHQ_UpdateRects; + this->VideoQuit = OHQ_VideoQuit; + this->AllocHWSurface = OHQ_AllocHWSurface; + this->CheckHWBlit = NULL; + this->FillHWRect = NULL; + this->SetHWColorKey = NULL; + this->SetHWAlpha = NULL; + this->LockHWSurface = OHQ_LockHWSurface; + this->UnlockHWSurface = OHQ_UnlockHWSurface; + this->FlipHWSurface = OHQ_FlipHWSurface; + this->FreeHWSurface = OHQ_FreeHWSurface; + this->SetGamma = NULL; + this->GetGamma = NULL; + this->SetGammaRamp = NULL; + this->GetGammaRamp = NULL; + this->GL_LoadLibrary = NULL; + this->GL_GetProcAddress = NULL; + this->GL_GetAttribute = NULL; + this->GL_MakeCurrent = NULL; + this->GL_SwapBuffers = NULL; + this->SetCaption = OHQ_SetCaption; + this->SetIcon = OHQ_SetIcon; + this->IconifyWindow = OHQ_IconifyWindow; + this->GrabInput = OHQ_GrabInput; + this->GetWMInfo = OHQ_GetWMInfo; + this->FreeWMCursor = OHQ_FreeWMCursor; + this->CreateWMCursor = OHQ_CreateWMCursor; + this->ShowWMCursor = OHQ_ShowWMCursor; + this->WarpWMCursor = OHQ_WarpWMCursor; + this->MoveWMCursor = OHQ_MoveWMCursor; + this->CheckMouseMode = OHQ_CheckMouseMode; + this->InitOSKeymap = OHQ_InitOSKeymap; + this->PumpEvents = OHQ_PumpEvents; + this->free = OHQ_DeleteDevice; + + this->info.wm_available = 1; + + return this; +} + +VideoBootStrap OPENGLHQ_bootstrap = { + "openglhq", "OpenGL-HQ scaling", + OHQ_Available, OHQ_CreateDevice +}; diff -urN ./src/video/openglhq/SDL_ohqvideo.h ./src/video/openglhq/SDL_ohqvideo.h --- ./src/video/openglhq/SDL_ohqvideo.h 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/SDL_ohqvideo.h 2012-10-16 22:40:42 +0900 @@ -0,0 +1,134 @@ +/* + SDL - Simple DirectMedia Layer OpenGL-HQ scaling + Copyright (C) 2005 JΓΆrg Walter + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2004 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#ifndef _SDL_ohqvideo_h +#define _SDL_ohqvideo_h + +#include +#include + +#include "SDL_mutex.h" +#include "../SDL_sysvideo.h" +#include "SDL_thread.h" + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_VideoDevice *this + +enum OGL_CMD { + OGL_NONE, + OGL_CALL, + OGL_INIT, + OGL_DEINIT, + OGL_FRAME, + OGL_PALETTE, + OGL_QUIT +}; + +enum OGL_STATUS { + OGL_DONE, + OGL_ERROR +}; + +/* Private display data */ +struct SDL_PrivateVideoData { + SDL_VideoDevice *real_video; + volatile SDL_Surface *volatile surface; + int screen_width, screen_height; + + volatile int width; + volatile int height; + volatile int pitch; + volatile int outwidth; + volatile int outheight; + volatile int flags; + volatile int bpp; + volatile SDL_PixelFormat format; + volatile SDL_Rect clip; + + int busy; + + struct { + enum { + OGL_CALL_P, + OGL_CALL_P_I, + OGL_CALL_PP, + OGL_CALL_PP_I, + OGL_CALL_PI_I, + OGL_CALL_PII, + OGL_CALL_PPP, + OGL_CALL_PPPIIII_P + } type; + intptr_t args[6]; + union { + void (*p)(SDL_VideoDevice*); + void (*pii)(SDL_VideoDevice*, int, int); + void (*pp)(SDL_VideoDevice*, const void*); + int (*pp_i)(SDL_VideoDevice*, const void*); + int (*p_i)(SDL_VideoDevice *); + int (*pi_i)(SDL_VideoDevice *, int); + void (*ppp)(SDL_VideoDevice *, const void*, const void*); + void* (*pppiiii_p)(SDL_VideoDevice *, const void*, const void*, int, int, int, int); + } func; + intptr_t result; + } call; + + volatile GLenum framebuf_format; + volatile GLenum framebuf_datatype; + + GLuint texture[4]; + GLuint displaylist; + GLint texsize, max_texsize; + int has_pixel_data_range; + int allow_paletted_texture; + + struct { + GLubyte r, g, b, a; + } pal[256]; + + GLuint program_name[3]; + GLuint fbo[2]; + GLuint pbuffer_displaylist; + + SDL_sem *render_thread_signal; + SDL_sem *render_thread_ack; + SDL_mutex *render_frame_lock; + SDL_Thread *render_thread; + + void * volatile framebuf; + int static_threshold; + int dynamic_threshold; + volatile int postponed; + int nohq; + int dirty; + + volatile enum OGL_CMD cmd; + volatile enum OGL_STATUS status; +}; + +#endif /* _SDL_ohqvideo_h */ diff -urN ./src/video/openglhq/SDL_openglhq_pass1.fp ./src/video/openglhq/SDL_openglhq_pass1.fp --- ./src/video/openglhq/SDL_openglhq_pass1.fp 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/SDL_openglhq_pass1.fp 2012-10-16 22:40:42 +0900 @@ -0,0 +1,81 @@ +!!ARBfp1.0 + +# +# Copyright (C) 2004 JΓΆrg Walter +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +TEMP pixel0, pixel1, pixel2, pixel3; +ALIAS coord1 = pixel1; +ALIAS coord2 = pixel2; +ALIAS coord3 = pixel3; +ALIAS rmean = pixel3; +TEMP diff; + +PARAM pixel_size = program.env[0]; +ATTRIB coord0 = fragment.texcoord[0]; +OUTPUT res = result.color; + +PARAM coordmask = { 1, 0, 1, 0 }; +PARAM weight = { 1.884313725490196078431372549, 3.768627450980392156862745098, 2.822790287990196078431372548, 0 }; +PARAM mask = { 0.4710784313725490196078431372, 0, -0.4710784313725490196078431372, 0 }; + +MAD coord1.xy, pixel_size, coordmask, coord0; +MAD coord2.xy, pixel_size, coordmask.gbra, coord0; +ADD coord3.xy, pixel_size, coord0; + +TEX pixel0.rgb, coord0, texture[0], 2D; +TEX pixel1.rgb, coord1, texture[0], 2D; +TEX pixel2.rgb, coord2, texture[0], 2D; +TEX pixel3.rgb, coord3, texture[0], 2D; + +# +# Original formula, [0;255] per component, result range [0;764.83]: +# sqrt( (2+rmean/256)*r*r + 4*g*g + (2.99609375-rmean/256)*b*b ) +# (see http://www.compuphase.com/cmetric.htm) +# +# Formula used in software hq2x scaler, range [0;31] per component, result range [0;2161.31] clamped to [0;255]: +# (0.5+(2*rmean/2048))*r*r + g*g + (0.7490234375-(2*rmean/2048))*b*b +# +# This code uses this formula, range [0;1] per component, result range [0;2161.31/255] clamped to [0;1]: +# (1.884313725490196078431372549+(2*rmean*0.4710784313725490196078431372))*r*r + 3.768627450980392156862745098*g*g + (2.822790287990196078431372548-(2*rmean*0.4710784313725490196078431372))*b*b +# (which means that the same trigger values can be used for both) +# + +SUB diff.rgb, pixel0, pixel3; +ADD rmean.a, pixel0.r, pixel3.r; +MAD rmean.rgb, rmean.a, mask, weight; +MUL diff.rgb, diff, diff; +DP3_SAT res.b, rmean, diff; + +SUB diff.rgb, pixel0, pixel1; +ADD rmean.a, pixel0.r, pixel1.r; +MAD rmean.rgb, rmean.a, mask, weight; +MUL diff.rgb, diff, diff; +DP3_SAT res.r, rmean, diff; + +SUB diff.rgb, pixel0, pixel2; +ADD rmean.a, pixel0.r, pixel2.r; +MAD rmean.rgb, rmean.a, mask, weight; +MUL diff.rgb, diff, diff; +DP3_SAT res.g, rmean, diff; + +SUB diff.rgb, pixel1, pixel2; +ADD rmean.a, pixel1.r, pixel2.r; +MAD rmean.rgb, rmean.a, mask, weight; +MUL diff.rgb, diff, diff; +DP3_SAT res.a, rmean, diff; + +END diff -urN ./src/video/openglhq/SDL_openglhq_pass1.h ./src/video/openglhq/SDL_openglhq_pass1.h --- ./src/video/openglhq/SDL_openglhq_pass1.h 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/SDL_openglhq_pass1.h 2012-10-02 00:46:56 +0900 @@ -0,0 +1,43 @@ +#define SDL_openglhq_pass1_fp \ +"!!ARBfp1.0\n" \ +"TEMP pixel0, pixel1, pixel2, pixel3;\n" \ +"ALIAS coord1 = pixel1;\n" \ +"ALIAS coord2 = pixel2;\n" \ +"ALIAS coord3 = pixel3;\n" \ +"ALIAS rmean = pixel3;\n" \ +"TEMP diff;\n" \ +"PARAM pixel_size = program.env[0];\n" \ +"ATTRIB coord0 = fragment.texcoord[0];\n" \ +"OUTPUT res = result.color;\n" \ +"PARAM coordmask = { 1, 0, 1, 0 };\n" \ +"PARAM weight = { 1.884313725490196078431372549, 3.768627450980392156862745098, 2.822790287990196078431372548, 0 };\n" \ +"PARAM mask = { 0.4710784313725490196078431372, 0, -0.4710784313725490196078431372, 0 };\n" \ +"MAD coord1.xy, pixel_size, coordmask, coord0;\n" \ +"MAD coord2.xy, pixel_size, coordmask.gbra, coord0;\n" \ +"ADD coord3.xy, pixel_size, coord0;\n" \ +"TEX pixel0.rgb, coord0, texture[0], 2D;\n" \ +"TEX pixel1.rgb, coord1, texture[0], 2D;\n" \ +"TEX pixel2.rgb, coord2, texture[0], 2D;\n" \ +"TEX pixel3.rgb, coord3, texture[0], 2D;\n" \ +"SUB diff.rgb, pixel0, pixel3;\n" \ +"ADD rmean.a, pixel0.r, pixel3.r;\n" \ +"MAD rmean.rgb, rmean.a, mask, weight;\n" \ +"MUL diff.rgb, diff, diff;\n" \ +"DP3_SAT res.b, rmean, diff;\n" \ +"SUB diff.rgb, pixel0, pixel1;\n" \ +"ADD rmean.a, pixel0.r, pixel1.r;\n" \ +"MAD rmean.rgb, rmean.a, mask, weight;\n" \ +"MUL diff.rgb, diff, diff;\n" \ +"DP3_SAT res.r, rmean, diff;\n" \ +"SUB diff.rgb, pixel0, pixel2;\n" \ +"ADD rmean.a, pixel0.r, pixel2.r;\n" \ +"MAD rmean.rgb, rmean.a, mask, weight;\n" \ +"MUL diff.rgb, diff, diff;\n" \ +"DP3_SAT res.g, rmean, diff;\n" \ +"SUB diff.rgb, pixel1, pixel2;\n" \ +"ADD rmean.a, pixel1.r, pixel2.r;\n" \ +"MAD rmean.rgb, rmean.a, mask, weight;\n" \ +"MUL diff.rgb, diff, diff;\n" \ +"DP3_SAT res.a, rmean, diff;\n" \ +"END\n" \ + diff -urN ./src/video/openglhq/SDL_openglhq_pass2.fp ./src/video/openglhq/SDL_openglhq_pass2.fp --- ./src/video/openglhq/SDL_openglhq_pass2.fp 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/SDL_openglhq_pass2.fp 2012-10-17 05:44:18 +0900 @@ -0,0 +1,69 @@ +!!ARBfp1.0 + +# +# Copyright (C) 2004 JΓΆrg Walter +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +TEMP pixel0, pixel1, pixel2, pixel3; +TEMP max; +ALIAS coord0 = pixel0; +ALIAS coord1 = pixel1; +ALIAS coord2 = pixel2; +TEMP min; +TEMP current_trigger; + +PARAM pixel_size = program.env[0]; +PARAM trigger = program.local[0]; +ATTRIB coord3 = fragment.texcoord[0]; + +PARAM coordmask = { 0, -1, 0, .0625 }; +PARAM factors = { 0.0627450980392157, 0.125490196078431, 0.250980392156863, 0.501960784313725 }; +PARAM const = { 65536, 0.1666666666666666, 1, 0 }; +ALIAS one_sixteenth = coordmask; + +SUB coord0.xy, coord3, pixel_size; +MAD coord1.xy, pixel_size.y, coordmask, coord3; +MAD coord2.xy, pixel_size.x, coordmask.gbra, coord3; + +TEX pixel0, coord0, texture[0], 2D; +TEX pixel1, coord1, texture[0], 2D; +TEX pixel2, coord2, texture[0], 2D; +TEX pixel3, coord3, texture[0], 2D; + +MOV pixel1.r, pixel0.b; +MOV pixel2.g, pixel0.a; + +ADD min, pixel1, pixel2; +ADD min, min, pixel3; +DP3 current_trigger.a, min, const.g; +MUL_SAT current_trigger.a, current_trigger.a, trigger.a; +MAX current_trigger.a, current_trigger.a, trigger.r; + +MUL current_trigger.a, current_trigger.a, const.r; +MAD_SAT pixel1, pixel1, const.r, -current_trigger.a; +MAD_SAT pixel2, pixel2, const.r, -current_trigger.a; +MAD_SAT pixel3, pixel3, const.r, -current_trigger.a; + +# on a Radeon 9500, these three expand to 6 native insns +#SLT pixel1, current_trigger.a, pixel1; +#SLT pixel2, current_trigger.a, pixel2; +#SLT pixel3, current_trigger.a, pixel3; + +DP4 result.color.a, pixel3, factors; +MAD pixel2, pixel2, one_sixteenth.a, pixel1; +DP4 result.color.rgb, pixel2, factors; + +END diff -urN ./src/video/openglhq/SDL_openglhq_pass2.h ./src/video/openglhq/SDL_openglhq_pass2.h --- ./src/video/openglhq/SDL_openglhq_pass2.h 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/SDL_openglhq_pass2.h 2012-10-02 00:46:56 +0900 @@ -0,0 +1,39 @@ +#define SDL_openglhq_pass2_fp \ +"!!ARBfp1.0\n" \ +"TEMP pixel0, pixel1, pixel2, pixel3;\n" \ +"TEMP max;\n" \ +"ALIAS coord0 = pixel0;\n" \ +"ALIAS coord1 = pixel1;\n" \ +"ALIAS coord2 = pixel2;\n" \ +"TEMP min;\n" \ +"TEMP current_trigger;\n" \ +"PARAM pixel_size = program.env[0];\n" \ +"PARAM trigger = program.local[0];\n" \ +"ATTRIB coord3 = fragment.texcoord[0];\n" \ +"PARAM coordmask = { 0, -1, 0, .0625 };\n" \ +"PARAM factors = { 0.0627450980392157, 0.125490196078431, 0.250980392156863, 0.501960784313725 };\n" \ +"PARAM const = { 65536, 0.1666666666666666, 1, 0 };\n" \ +"ALIAS one_sixteenth = coordmask;\n" \ +"SUB coord0.xy, coord3, pixel_size;\n" \ +"MAD coord1.xy, pixel_size.x, coordmask, coord3;\n" \ +"MAD coord2.xy, pixel_size.x, coordmask.gbra, coord3;\n" \ +"TEX pixel0, coord0, texture[0], 2D;\n" \ +"TEX pixel1, coord1, texture[0], 2D;\n" \ +"TEX pixel2, coord2, texture[0], 2D;\n" \ +"TEX pixel3, coord3, texture[0], 2D;\n" \ +"MOV pixel1.r, pixel0.b;\n" \ +"MOV pixel2.g, pixel0.a;\n" \ +"ADD min, pixel1, pixel2;\n" \ +"ADD min, min, pixel3;\n" \ +"DP3 current_trigger.a, min, const.g;\n" \ +"MUL_SAT current_trigger.a, current_trigger.a, trigger.a;\n" \ +"MAX current_trigger.a, current_trigger.a, trigger.r;\n" \ +"MUL current_trigger.a, current_trigger.a, const.r;\n" \ +"MAD_SAT pixel1, pixel1, const.r, -current_trigger.a;\n" \ +"MAD_SAT pixel2, pixel2, const.r, -current_trigger.a;\n" \ +"MAD_SAT pixel3, pixel3, const.r, -current_trigger.a;\n" \ +"DP4 result.color.a, pixel3, factors;\n" \ +"MAD pixel2, pixel2, one_sixteenth.a, pixel1;\n" \ +"DP4 result.color.rgb, pixel2, factors;\n" \ +"END\n" \ + diff -urN ./src/video/openglhq/SDL_openglhq_pass3.fp ./src/video/openglhq/SDL_openglhq_pass3.fp --- ./src/video/openglhq/SDL_openglhq_pass3.fp 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/SDL_openglhq_pass3.fp 2012-10-17 10:04:12 +0900 @@ -0,0 +1,115 @@ +!!ARBfp1.0 + +# +# Copyright (C) 2004 JΓΆrg Walter +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +TEMP coord1, coord2, coord3, pixel0; +ALIAS pixel1 = coord1; +ALIAS pixel2 = coord2; +ALIAS pixel3 = coord3; +TEMP diff; +TEMP center_offset; +TEMP factors; +TEMP coord0; + +PARAM pixel_size = program.env[0]; + +# 1/16, 1/2, 1-1/256, 1/512 +PARAM const = { .0625, .5, .99609375, .001953125 }; + +ATTRIB coord0hw = fragment.texcoord[0]; + +# 1/.875, (1/.875-1)/2, .875/adjust, (1-.875/adjust)/2 +#PARAM cap = { 1.142857142857142857127368540393064222371, -0.07142857142857143002735720305196309709572, .83825, .080875 }; +#PARAM cap = { 1.142857142857142857127368540393064222371, -0.07142857142857143002735720305196309709572, .875, .0625 }; +PARAM cap = program.env[1]; + +# normalize coordinates to eliminate FP precision errors +MUL center_offset.xy, coord0hw, pixel_size.abgr; +FLR coord0.xy, center_offset; +ADD coord0.xy, coord0, const.g; +MUL coord0.xy, coord0, pixel_size; + +# sub-pixel offset +FRC center_offset.xy, center_offset; + +# fetch interpolation mask coordinates +TEX diff, coord0, texture[1], 2D; + +# calculate neighbour pixel coordinates +SUB coord3.xy, center_offset, const.g; +CMP coord3.xy, coord3, -pixel_size, pixel_size; +ADD coord3.xy, coord0, coord3; +MOV coord1.x, coord3; +MOV coord1.y, coord0; +MOV coord2.x, coord0; +MOV coord2.y, coord3; + +# The interpolation mask 3D texture is arranged +# as 16x1x256 masks like this: +# +# +--+--+--+-- --+--+ +-> x +# | | | | ... 16 masks ... | |+ |\ +# +--+--+--+-- --+--+|+ V \| +# +--+--+--+-- --+--+| y z +# +--+--+--+-- --+--+ +# . +# . 256 masks +# . +# +# This is more robust across GPUs than an 1x1x4096 arrangement. + +# Clamp x offset to a reduced interval. This is required since +# otherwise precision errors will make the final coordinate wrap +# into the opposite end of the next mask. +MAD_SAT center_offset.x, center_offset, cap.r, cap.g; +MAD center_offset.x, center_offset, cap.b, cap.a; + +# This could be used if wrapping occurs on the z coordinate, which +# should not happen. +#MAD center_offset.z, diff, const.b, const.a; + +# final coordinate calculation: +# x = x_offset/16 + mask_x; y = y_offset; z = mask_z; +MAD center_offset.x, center_offset, const, diff.a; +MOV center_offset.z, diff; + +# fetch color values +TEX pixel0, coord0, texture[0], 2D; +TEX pixel1, coord1, texture[0], 2D; +TEX pixel2, coord2, texture[0], 2D; +TEX pixel3, coord3, texture[0], 2D; + +# fetch pixel weights from mask +TEX factors, center_offset, texture[2], 3D; + +# apply mask factors +MUL pixel0, pixel0, factors.r; +MAD pixel0, pixel1, factors.g, pixel0; +MAD pixel0, pixel2, factors.b, pixel0; +MAD result.color, pixel3, factors.a, pixel0; + +# debugging +#MOV result.color, pixel0; +#MOV result.color, diff; +#MOV result.color, factors; +#MOV result.color.g, test.y; +#MOV result.color.r, test.z; +#SUB test.z, test, const.b; +#CMP result.color.r, test.z, const.r, const.b; + +END diff -urN ./src/video/openglhq/SDL_openglhq_pass3.h ./src/video/openglhq/SDL_openglhq_pass3.h --- ./src/video/openglhq/SDL_openglhq_pass3.h 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/SDL_openglhq_pass3.h 2012-10-02 00:46:56 +0900 @@ -0,0 +1,38 @@ +#define SDL_openglhq_pass3_fp \ +"!!ARBfp1.0\n" \ +"TEMP coord1, coord2, coord3, pixel0;\n" \ +"ALIAS pixel1 = coord1;\n" \ +"ALIAS pixel2 = coord2;\n" \ +"ALIAS pixel3 = coord3;\n" \ +"TEMP diff;\n" \ +"TEMP center_offset;\n" \ +"TEMP factors;\n" \ +"PARAM pixel_size = program.env[0];\n" \ +"PARAM const = { .0625, .5, .99609375, .001953125 };\n" \ +"ATTRIB coord0 = fragment.texcoord[0];\n" \ +"PARAM cap = program.env[1];\n" \ +"TEX diff, coord0, texture[1], 2D;\n" \ +"MUL center_offset.xy, coord0, pixel_size.abgr;\n" \ +"FRC center_offset.xy, center_offset;\n" \ +"SUB coord3.xy, center_offset, const.g;\n" \ +"CMP coord3.xy, coord3, -pixel_size, pixel_size;\n" \ +"ADD coord3.xy, coord0, coord3;\n" \ +"MOV coord1.x, coord3;\n" \ +"MOV coord1.y, coord0;\n" \ +"MOV coord2.x, coord0;\n" \ +"MOV coord2.y, coord3;\n" \ +"MAD_SAT center_offset.xy, center_offset, cap.r, cap.g;\n" \ +"MAD center_offset.xy, center_offset, cap.b, cap.a;\n" \ +"MAD center_offset.x, center_offset, const, diff.a;\n" \ +"MAD center_offset.z, diff, const.b, const.a;\n" \ +"TEX pixel0, coord0, texture[0], 2D;\n" \ +"TEX pixel1, coord1, texture[0], 2D;\n" \ +"TEX pixel2, coord2, texture[0], 2D;\n" \ +"TEX pixel3, coord3, texture[0], 2D;\n" \ +"TEX factors, center_offset, texture[2], 3D;\n" \ +"MUL pixel0, pixel0, factors.r;\n" \ +"MAD pixel0, pixel1, factors.g, pixel0;\n" \ +"MAD pixel0, pixel2, factors.b, pixel0;\n" \ +"MAD result.color, pixel3, factors.a, pixel0;\n" \ +"END\n" \ + diff -urN ./src/video/openglhq/SDL_openglhq_table.dat ./src/video/openglhq/SDL_openglhq_table.dat --- ./src/video/openglhq/SDL_openglhq_table.dat 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/SDL_openglhq_table.dat 2012-10-16 22:40:42 +0900 @@ -0,0 +1 @@ +‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘$$‘’“”‘’L‘’“”‘’—‘’“”‘’L‘l“”‘$$‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘l“”‘’—‘ll”‘nL‘ll”‘$$‘’“”‘’L‘l“”‘’—‘ll”‘nL‘ll”‘$$‘’”‘’‘l“”‘–—‘’”‘’‘’“”‘’—‘’”‘’‘l“”‘’—‘’”‘’‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘μμ”‘μ쐑μμ”‘μ쐑’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘l“”‘’—‘lL”‘nL‘ll”‘nl‘’“”‘’L‘l“”‘’—‘lL”‘nL‘ll”‘’l‘’”‘’‘l“”‘’—‘’L”‘’L‘’“”‘’—‘’”‘’‘l“”‘’—‘’L”‘’L‘’“”‘’—‘’“”‘’L‘’“”θ’萑’“”‘’L‘’“”θ’—‘’“”‘’Lh’“”θ’萑’“”‘’L‘’“”θ’—‘’“”‘’L‘’“”θ’萑’“”‘’L‘’“”‘’—‘’L”‘’L‘’“”θ’萑’L”‘’L‘’“”θ’—‘’“”‘’l‘l“”θ’萑ll”‘lL‘l“”θl—‘’“”‘’l‘l“”θ’萑ll”‘nL‘l“”θ$—‘’“”‘’l‘l“”θ’萑’“”‘l‘’“”‘l—‘’“”‘’L‘l“”θ’萑’“”‘’‘’“”θ’—‘’“”‘’L‘’“”‘’—HHHHHHHLHHH“HHH— ’ ” ’  ’ ” ’  μμ” μμ μ“” 에‘’“”‘’L‘’“”‘’—HHHHHHHLH‘H“HHH— ’“” ’L ’ ” ’  ’ ” ’L ’“” ’L‘’“”‘’L‘l“”‘’—HHllHHlLHHl“HHl— ’ ” ’  l ” ’  l ” n  l“” nL‘’”‘’‘l“”‘’—HHHHHlHhH“HμlL ’“” ’ l ” ’  ’” ’ ’“” ’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘$$‘’“”‘’L‘’“”‘’—‘’L”‘’L‘’“”‘$$‘’L”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’L”‘’L‘’“”‘’—‘’“”‘’L‘l“”‘’—‘ll”‘nL‘ll”‘$$‘’“”‘’L‘l“”‘’—‘lh”‘nL‘ll”‘$$‘’”‘’‘l“”‘’—‘’”‘’‘’“”‘’—‘’”‘’‘l“”‘’—‘’”‘’‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘μ“”‘μL‘μμ”‘μ쐑’L”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’L”‘’L‘’“”‘’—‘’“”‘’L‘l“”‘’—‘lL”‘nL‘ll”‘nl‘’“”‘’L‘l“”‘’—‘l“”‘nL‘lh”‘nl‘’”‘’‘l“”‘’—‘’L”‘’L‘’“”‘’—‘’”‘’‘l“”‘’—‘’”‘’L‘’—”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’L”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’L”‘’L‘’“”‘’—‘’L”‘’L‘’“”‘’—‘’“”‘’L‘’“”‘’—‘’“”‘’l‘l“”‘’—‘ll”‘lL‘l“”‘’—‘’“”‘’l‘l“”‘’—‘ll”‘nL‘l“”‘$—‘’“”‘’‘l“”‘’—‘’“”‘l‘’“”‘l—‘’L”‘’‘l“”‘’—‘’“”‘’‘’“”‘’—‘’“”‘’L‘’“”‘’—HHHHHHHLHH’“HHH—‘’“”‘’L‘’“”‘’—‘μμ”‘μL‘μ“”‘μL‘’“”‘’L‘’“”‘’—HHHLHHHLHHH“HHH—‘’L”‘’L‘’“”‘’—‘’L”‘’L‘’“”‘’L‘’“”‘’L‘l“”‘’—HHllHHlLHHl“HH–—‘’“”‘’L‘l“”‘’—‘ll”‘nL‘l“”‘n—‘’”‘’‘l“”‘’—HHHHHlHHH“HHl—‘’”‘’‘l“”‘’—‘’”‘’‘’“”‘’—‘’“”‘’Lh’“”‘’—‘’“”‘’lh’“”‘$$‘’“”‘’Lh’“”‘’—‘’“”‘’lh’“”‘$$‘’“”‘’Lh’“”‘’—‘’“”‘’lh’“”‘’—‘’“”‘’Lh’“”‘’—‘’“”‘’lh’“”‘’—‘’“”‘’—hl“”‘’—‘ll”‘nlhll”‘$$‘’“”‘’—hl“”‘’—‘ll”‘nlhll”‘$$‘’“”‘’—hl“”‘’—‘’“”‘’lh’“”‘’—‘’“”‘’—hl“”‘’—‘’“”‘’lh’“”‘’—‘’“”‘’Lh’“”‘’—‘’“”‘’Lh’“”‘’—‘’“”‘’Lh’“”‘’—‘μμ”‘μμhμμ”‘μ쐑’“”‘’Lh’“”‘’—‘’“”‘’Lh’“”‘’—‘’“”‘’Lh’“”‘’—‘’“”‘’Lh’“”‘’—‘’“”‘’—hl“”‘’—‘ll”‘nlhll”‘nl‘’“”‘’—hl“”‘’—‘ll”‘nlhll”‘nl‘’“”‘’—hl“”‘’—‘’“”‘’—h’“”‘’—‘’“”‘’—hl“”‘’—‘’“”‘’—h’“”‘’—h’h”i’Lh’h”θ’θh’h”l’Lh’“”l$—h’h”i’Lh’h”θ’θh’h”i’Lh’“”θ$—h’h”i’Lh’h”θ’θh’h”l’Lh’“”‘’—h’l”i’Lh’h”θ’θh’h”i’Lh’“”θ’—h’h”i’lhlh”θ’θhl”inlhl“”θ$—h’h”i’lhlh”θ’θhll”inlhl“”θ$—h’h”i’lhlh”θ’θh’h”i’hh’”θ’—h’h”i’—hlh”θ’θh’”i’hh’“”θ’—h’L”i’Lh’h”i’hHhHhHlHLHhH“HlH—h’L”i’Lh’h”‘’hhμμ”iμμhμ“”iμLh’L”i’Lh’h”i’hHhHhHlHLHhH“H•H—h’“”i’Lh’l”i’hh’h”i’Lh’“”i’—h’h”i’hhlh”i’hHhllHinHhl“Hin—h’h”i’hhlh”i’hhll”inlhl“”in—h’h”i’hhlh”i’hHhHhHiHhHhH“H‘H—h’ ”i’“hl ”i’hh’h”i’hh’“”i’—‘’Μ”‘’̐h’“”•’—‘’“”‘’lh’“”‘$$‘’Μ”‘’̐h’“”‘’—‘’“”‘’Lh’“”‘$$‘’Μ”‘’̐h’“”‘’—‘’“”‘’̐h’“”‘’—‘’Μ”‘’̐h’“”‘’—‘’L”‘’̐h’“”‘’—‘’“”‘’—hl“”‘’—‘ll”‘nlhll”‘$$‘’“”‘’—hl“”‘’—‘ll”‘n—hll”‘$$‘’“”‘’—hl“”‘’—‘’“”‘’—h’“”‘’—‘’“”‘’—hl“”‘’—‘’“”‘’—h’“”‘’—‘’Μ”‘’̐h’“”‘’—‘’Μ”‘’̐h’“”‘’—‘’Μ”‘’̐h’“”‘’—‘μ“”‘μ̐hμμ”‘μ쐑’Μ”‘’̐h’“”‘’—‘’Μ”‘’̐h’“”‘’—‘’Μ”‘’̐h’“”‘’—‘’Μ”‘’̐h’“”‘’—‘’“”‘’—hl“”‘’—‘ll”‘nlhll”‘nl‘’“”‘’—hl“”‘’—‘lμ”‘n“hlμ”‘nl‘’“”‘’—hl“”‘’—‘’“”‘’—h’“”‘’—‘’“”‘’—hl“”‘’—‘’μ”‘’̐h’“”‘’—‘’Μ”‘’̐‘’“”‘’—‘’“”l’̐‘’“”l’—‘’Μ”‘’̐‘’“”‘’—‘’“”‘’̐‘’“”‘$—‘’Μ”‘’̐‘’“”‘’—‘’“”l’̐‘’“”l’—‘’Μ”‘’̐‘’“”‘’—‘’“”‘’̐‘’“”‘’—‘’“”‘’l‘l“”‘’—‘ll”‘nl‘l”‘$—‘’“”‘’l‘l“”‘’—‘l”‘nl‘l“”‘$—‘’“”‘’—‘l“”‘’—‘’”‘’—‘’“”‘’—‘’“”‘’—‘l“”‘’—‘’“”‘’—‘’“”‘’—‘’L”‘’L‘’“”‘’—HHHΜHlHΜHHl“HlL‘’L”‘’L‘’“”‘’—‘μΜ”‘μ̐‘μ“”‘에‘’L”‘’L‘’“”‘’—HHHΜHlHΜHHH“HlH—‘’Μ”‘’L‘’—”‘’—‘’Μ”‘’̐‘’“”‘’—‘’“”‘’—‘l“”‘’—HHllHHnlHHl“HH’—‘’“”‘’—‘l“”‘’—‘ll”‘nl‘l“”‘n—‘’“”‘’—‘l“”‘’—HHH—HHH—HHH“HHH—‘’ ”‘’‘l“”‘’—‘’“”‘’—‘’“”‘’— \ No newline at end of file diff -urN ./src/video/openglhq/SDL_openglhq_table.h ./src/video/openglhq/SDL_openglhq_table.h --- ./src/video/openglhq/SDL_openglhq_table.h 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/SDL_openglhq_table.h 2012-10-02 00:46:56 +0900 @@ -0,0 +1,258 @@ +#define SDL_openglhq_table_dat { \ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x4c,0x90,0x91,0x6c,0x6c,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x4c,0x90,0x91,0x6c,0x6c,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x96,0x97,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0xec,0xec,0x94,0x91,0xec,0xec,0x90,0x91,0xec,0xec,0x94,0x91,0xec,0xec,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x4c,0x94,0x91,0x6e,0x4c,0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x6c,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x4c,0x94,0x91,0x6e,0x4c,0x90,0x91,0x6c,0x6c,0x94,0x91,0x92,0x6c,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0xe8,0x92,0xe8,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0xe8,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0xe8,0x92,0xe8,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0xe8,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0xe8,0x92,0xe8,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0xe8,0x92,0xe8,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0xe8,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x91,0x6c,0x93,0x94,0xe8,0x92,0xe8,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6c,0x4c,0x90,0x91,0x6c,0x93,0x94,0xe8,0x6c,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x91,0x6c,0x93,0x94,0xe8,0x92,0xe8,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x4c,0x90,0x91,0x6c,0x93,0x94,0xe8,0x24,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x91,0x6c,0x93,0x94,0xe8,0x92,0xe8,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x6c,0x04,0x90,0x91,0x92,0x93,0x94,0x91,0x6c,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0xe8,0x92,0xe8,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x04,0x90,0x91,0x92,0x93,0x94,0xe8,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x4c,0x48,0x48,0x48,0x93,0x48,0x48,0x48,0x97,\ +0x90,0x20,0x92,0x20,0x94,0x20,0x92,0x20,0x90,0x20,0x92,0x20,0x94,0x20,0x92,0x20,\ +0x90,0x20,0xec,0xec,0x94,0x20,0xec,0xec,0x90,0x20,0xec,0x93,0x94,0x20,0xec,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x4c,0x48,0x91,0x48,0x93,0x48,0x48,0x48,0x97,\ +0x90,0x20,0x92,0x93,0x94,0x20,0x92,0x4c,0x90,0x20,0x92,0x20,0x94,0x20,0x92,0x20,\ +0x90,0x20,0x92,0x20,0x94,0x20,0x92,0x4c,0x90,0x20,0x92,0x93,0x94,0x20,0x92,0x4c,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x48,0x48,0x6c,0x6c,0x48,0x48,0x6c,0x4c,0x48,0x48,0x6c,0x93,0x48,0x48,0x6c,0x97,\ +0x90,0x20,0x92,0x20,0x94,0x20,0x92,0x20,0x90,0x20,0x6c,0x20,0x94,0x20,0x92,0x20,\ +0x90,0x20,0x6c,0x20,0x94,0x20,0x6e,0x20,0x90,0x20,0x6c,0x93,0x94,0x20,0x6e,0x4c,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x48,0x48,0x48,0x04,0x48,0x48,0x6c,0x04,0x48,0x68,0x48,0x93,0x48,0xec,0x6c,0x4c,\ +0x90,0x20,0x92,0x93,0x94,0x20,0x92,0x04,0x90,0x20,0x6c,0x20,0x94,0x20,0x92,0x20,\ +0x90,0x20,0x92,0x04,0x94,0x20,0x92,0x04,0x90,0x20,0x92,0x93,0x94,0x20,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x4c,0x90,0x91,0x6c,0x6c,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x68,0x94,0x91,0x6e,0x4c,0x90,0x91,0x6c,0x6c,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0xec,0x93,0x94,0x91,0xec,0x4c,0x90,0x91,0xec,0xec,0x94,0x91,0xec,0xec,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x4c,0x94,0x91,0x6e,0x4c,0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x6c,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x93,0x94,0x91,0x6e,0x4c,0x90,0x91,0x6c,0x68,0x94,0x91,0x6e,0x6c,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x97,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6c,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x24,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x6c,0x04,0x90,0x91,0x92,0x93,0x94,0x91,0x6c,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x04,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x4c,0x48,0x48,0x92,0x93,0x48,0x48,0x48,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0xec,0xec,0x94,0x91,0xec,0x4c,0x90,0x91,0xec,0x93,0x94,0x91,0xec,0x4c,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x48,0x48,0x48,0x4c,0x48,0x48,0x48,0x4c,0x48,0x48,0x48,0x93,0x48,0x48,0x48,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x48,0x48,0x6c,0x6c,0x48,0x48,0x6c,0x4c,0x48,0x48,0x6c,0x93,0x48,0x48,0x96,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x4c,0x90,0x91,0x6c,0x93,0x94,0x91,0x6e,0x97,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x48,0x48,0x48,0x04,0x48,0x48,0x6c,0x04,0x48,0x48,0x48,0x93,0x48,0x48,0x6c,0x97,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x04,0x94,0x91,0x92,0x04,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x68,0x92,0x93,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x68,0x92,0x93,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x6c,0x90,0x68,0x6c,0x6c,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x6c,0x90,0x68,0x6c,0x6c,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0xec,0xec,0x94,0x91,0xec,0xec,0x90,0x68,0xec,0xec,0x94,0x91,0xec,0xec,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x6c,0x90,0x68,0x6c,0x6c,0x94,0x91,0x6e,0x6c,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x6c,0x90,0x68,0x6c,0x6c,0x94,0x91,0x6e,0x6c,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x4c,0x90,0x68,0x92,0x68,0x94,0xe8,0x92,0xe8,\ +0x90,0x68,0x92,0x68,0x94,0x6c,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x6c,0x24,0x97,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x4c,0x90,0x68,0x92,0x68,0x94,0xe8,0x92,0xe8,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0xe8,0x24,0x97,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x4c,0x90,0x68,0x92,0x68,0x94,0xe8,0x92,0xe8,\ +0x90,0x68,0x92,0x68,0x94,0x6c,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x68,0x92,0x6c,0x94,0x69,0x92,0x4c,0x90,0x68,0x92,0x68,0x94,0xe8,0x92,0xe8,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0xe8,0x92,0x97,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x6c,0x90,0x68,0x6c,0x68,0x94,0xe8,0x92,0xe8,\ +0x90,0x68,0x6c,0x90,0x94,0x69,0x6e,0x6c,0x90,0x68,0x6c,0x93,0x94,0xe8,0x24,0x97,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x6c,0x90,0x68,0x6c,0x68,0x94,0xe8,0x92,0xe8,\ +0x90,0x68,0x6c,0x6c,0x94,0x69,0x6e,0x6c,0x90,0x68,0x6c,0x93,0x94,0xe8,0x24,0x97,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x6c,0x90,0x68,0x6c,0x68,0x94,0xe8,0x92,0xe8,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x68,0x90,0x68,0x92,0x90,0x94,0xe8,0x92,0x97,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x97,0x90,0x68,0x6c,0x68,0x94,0xe8,0x92,0xe8,\ +0x90,0x68,0x92,0x90,0x94,0x69,0x92,0x68,0x90,0x68,0x92,0x93,0x94,0xe8,0x92,0x97,\ +0x90,0x68,0x92,0x4c,0x94,0x69,0x92,0x4c,0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x68,\ +0x48,0x68,0x48,0x68,0x48,0x6c,0x48,0x4c,0x48,0x68,0x48,0x93,0x48,0x6c,0x48,0x97,\ +0x90,0x68,0x92,0x4c,0x94,0x69,0x92,0x4c,0x90,0x68,0x92,0x68,0x94,0x91,0x92,0x68,\ +0x90,0x68,0xec,0xec,0x94,0x69,0xec,0xec,0x90,0x68,0xec,0x93,0x94,0x69,0xec,0x4c,\ +0x90,0x68,0x92,0x4c,0x94,0x69,0x92,0x4c,0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x68,\ +0x48,0x68,0x48,0x68,0x48,0x6c,0x48,0x4c,0x48,0x68,0x48,0x93,0x48,0x95,0x48,0x97,\ +0x90,0x68,0x92,0x93,0x94,0x69,0x92,0x4c,0x90,0x68,0x92,0x6c,0x94,0x69,0x92,0x68,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x69,0x92,0x97,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x68,0x90,0x68,0x6c,0x68,0x94,0x69,0x92,0x68,\ +0x48,0x68,0x6c,0x6c,0x48,0x69,0x6e,0x90,0x48,0x68,0x6c,0x93,0x48,0x69,0x6e,0x97,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x68,0x90,0x68,0x6c,0x68,0x94,0x69,0x92,0x68,\ +0x90,0x68,0x6c,0x6c,0x94,0x69,0x6e,0x6c,0x90,0x68,0x6c,0x93,0x94,0x69,0x6e,0x97,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x68,0x90,0x68,0x6c,0x68,0x94,0x69,0x92,0x68,\ +0x48,0x68,0x48,0x68,0x48,0x69,0x48,0x68,0x48,0x68,0x48,0x93,0x48,0x91,0x48,0x97,\ +0x90,0x68,0x92,0x20,0x94,0x69,0x92,0x93,0x90,0x68,0x6c,0x20,0x94,0x69,0x92,0x68,\ +0x90,0x68,0x92,0x68,0x94,0x69,0x92,0x68,0x90,0x68,0x92,0x93,0x94,0x69,0x92,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x95,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x68,0x92,0x93,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x4c,0x90,0x68,0x92,0x93,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x6c,0x90,0x68,0x6c,0x6c,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x97,0x90,0x68,0x6c,0x6c,0x94,0x91,0x24,0x24,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0xec,0x93,0x94,0x91,0xec,0xcc,0x90,0x68,0xec,0xec,0x94,0x91,0xec,0xec,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x6c,0x90,0x68,0x6c,0x6c,0x94,0x91,0x6e,0x6c,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0xec,0x94,0x91,0x6e,0x93,0x90,0x68,0x6c,0xec,0x94,0x91,0x6e,0x6c,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x68,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0xec,0x94,0x91,0x92,0xcc,0x90,0x68,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x6c,0x92,0xcc,0x90,0x91,0x92,0x93,0x94,0x6c,0x92,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0xcc,0x90,0x91,0x92,0x93,0x94,0x91,0x24,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x6c,0x92,0xcc,0x90,0x91,0x92,0x93,0x94,0x6c,0x92,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0xcc,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x6c,0x90,0x91,0x6c,0x90,0x94,0x91,0x24,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x6c,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x90,0x94,0x91,0x6e,0x6c,0x90,0x91,0x6c,0x93,0x94,0x91,0x24,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x90,0x94,0x91,0x92,0x97,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x48,0x48,0x48,0xcc,0x48,0x6c,0x48,0xcc,0x48,0x48,0x6c,0x93,0x48,0x6c,0x14,0x4c,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0xec,0xcc,0x94,0x91,0xec,0xcc,0x90,0x91,0xec,0x93,0x94,0x91,0xec,0x97,\ +0x90,0x91,0x92,0x4c,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x48,0x48,0x48,0xcc,0x48,0x6c,0x48,0xcc,0x48,0x48,0x48,0x93,0x48,0x6c,0x48,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0x4c,0x90,0x91,0x92,0x97,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0xcc,0x94,0x91,0x92,0xcc,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x48,0x48,0x6c,0x6c,0x48,0x48,0x6e,0x6c,0x48,0x48,0x6c,0x93,0x48,0x48,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x6c,0x6c,0x94,0x91,0x6e,0x6c,0x90,0x91,0x6c,0x93,0x94,0x91,0x6e,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x48,0x48,0x48,0x97,0x48,0x48,0x48,0x97,0x48,0x48,0x48,0x93,0x48,0x48,0x48,0x97,\ +0x90,0x91,0x92,0x20,0x94,0x91,0x92,0x04,0x90,0x91,0x6c,0x93,0x94,0x91,0x92,0x97,\ +0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,0x90,0x91,0x92,0x93,0x94,0x91,0x92,0x97,\ +} diff -urN ./src/video/openglhq/asciidump.c ./src/video/openglhq/asciidump.c --- ./src/video/openglhq/asciidump.c 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/asciidump.c 2012-10-16 22:40:42 +0900 @@ -0,0 +1,51 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + FILE *dat, *hdr; + char buffer[256], *name; + int i; + + if (argc != 3) { + fprintf(stderr,"wrong number of arguments\n"); + exit(1); + } + + dat = fopen(argv[1],"rb"); + hdr = fopen(argv[2],"w"); + if (dat == NULL || hdr == NULL) { + perror("file open"); + exit(2); + } + +#if defined (_MSC_VER) + name = strrchr(argv[1],'\\'); +#else + name = strrchr(argv[1],'/'); +#endif + if (name == NULL) name=argv[1]; + else name++; + name = strdup(name); + + for (i = 0; name[i]; i++) + if (!((name[i]>='a' && name[i]<='z') || (name[i]>='A' && name[i]<='Z') || (name[i]>='0' && name[i]<='9'))) + name[i] = '_'; + + fprintf(hdr,"#define %s \\\n", name); + while (!feof(dat) && fgets(buffer,256,dat)) { + buffer[strlen(buffer)-1] = 0; + + name = buffer; + while (*name == ' ' || *name == '\t') name++; + if (*name == 0 || *name == '#') continue; + + fprintf(hdr,"\"%s\\n\" \\\n",name); + } + fprintf(hdr,"\n"); + fclose(hdr); + fclose(dat); + + return 0; +} diff -urN ./src/video/openglhq/hexdump.c ./src/video/openglhq/hexdump.c --- ./src/video/openglhq/hexdump.c 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/hexdump.c 2012-10-16 22:40:42 +0900 @@ -0,0 +1,48 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + FILE *dat, *hdr; + char buffer[16], *name; + int i; + + if (argc != 3) { + fprintf(stderr,"wrong number of arguments\n"); + exit(1); + } + + dat = fopen(argv[1],"rb"); + hdr = fopen(argv[2],"w"); + if (dat == NULL || hdr == NULL) { + perror("file open"); + exit(2); + } + +#if defined (_MSC_VER) + name = strrchr(argv[1],'\\'); +#else + name = strrchr(argv[1],'/'); +#endif + if (name == NULL) name=argv[1]; + else name++; + name = strdup(name); + + for (i = 0; name[i]; i++) + if (!((name[i]>='a' && name[i]<='z') || (name[i]>='A' && name[i]<='Z') || (name[i]>='0' && name[i]<='9'))) + name[i] = '_'; + + fprintf(hdr,"#define %s { \\\n", name); + while (!feof(dat) && fread(buffer,16,1,dat)) { + for (i = 0; i < 16; i++) { + fprintf(hdr,"0x%02x,",(unsigned char)buffer[i]); + } + fprintf(hdr,"\\\n"); + } + fprintf(hdr,"}\n"); + fclose(hdr); + fclose(dat); + + return 0; +} diff -urN ./src/video/openglhq/tablebuilder.ui ./src/video/openglhq/tablebuilder.ui --- ./src/video/openglhq/tablebuilder.ui 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/tablebuilder.ui 2012-10-16 23:04:33 +0900 @@ -0,0 +1,1038 @@ + + + JΓΆrg Walter <jwalt@garni.ch> + Builds scaling tables for the DosBox OpenGL-HQ renderer + + TableBuilder + + + + 0 + 0 + 762 + 516 + + + + DosBox OpenGL-HQ Table Builder + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 44 + 20 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 43 + 20 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 44 + 20 + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 40 + + + + + + + + + 1 + 1 + + + + Resulting Borders + + + + + + + + + 0 + 0 + + + + diagonal: + + + + + + + + + + 0 + 0 + + + + Y<sub>0</sub> + + + false + + + + + + + false + + + + 0 + 0 + + + + /4 + + + -4 + + + 4 + + + 1 + + + 0 + + + + + + + + + + + + 0 + 0 + + + + grad. + + + false + + + + + + + false + + + + 0 + 0 + + + + /2 + + + -4 + + + 4 + + + + + + + + + + + + + + 0 + 0 + + + + &Reset + + + Alt+R + + + + + + + + 0 + 0 + + + + &Save + + + Alt+S + + + true + + + true + + + + + + + + + + + Mirror: + + + false + + + + + + + H/V + + + + + + + H+V + + + + + + + + + + 0 + 0 + + + + + + + true + + + true + + + + + + + + 0 + 0 + + + + + + + true + + + true + + + + + + + + 200 + 200 + + + + + 200 + 200 + + + + + + + + + 0 + 0 + + + + + 40 + 40 + + + + + 40 + 40 + + + + + + + true + + + true + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 16 + + + + + + + + + 1 + 1 + + + + Source Pixels + + + + + + Reset all + + + + + + + + 1 + 1 + + + + C + + + + + + + + 1 + 1 + + + + DH + + + + + + + + 1 + 1 + + + + D + + + + + + + + 1 + 1 + + + + H + + + + + + + + 1 + 1 + + + + HB + + + + + + + + 1 + 1 + + + + DB + + + + + + + + 1 + 1 + + + + VB + + + + + + + + 1 + 1 + + + + DV + + + + + + + + 1 + 1 + + + + V + + + + + + + + + + + + 0 + 0 + 762 + 21 + + + + + &File + + + + + + + + + + + + + + image1image1 + + + &New + + + New + + + Ctrl+N + + + fileNewAction + + + + + + image2image2 + + + &Open... + + + Open + + + Ctrl+O + + + fileOpenAction + + + + + + image3image3 + + + &Save + + + Save + + + Ctrl+S + + + fileSaveAction + + + + + Save &As... + + + Save As + + + + + + fileSaveAsAction + + + + + E&xit + + + Exit + + + + + + fileExitAction + + + + + + + QCanvasView + QWidget +
qcanvasview.h
+
+
+ + qcanvasview.h + + + + + fileNewAction + activated() + TableBuilder + file_new() + + + -1 + -1 + + + 20 + 20 + + + + + fileExitAction + activated() + TableBuilder + close() + + + -1 + -1 + + + 20 + 20 + + + + + sourceReset + clicked() + TableBuilder + sourceReset_clicked() + + + 20 + 20 + + + 20 + 20 + + + + + resultReset + clicked() + TableBuilder + resultReset_clicked() + + + 20 + 20 + + + 20 + 20 + + + + + dEnabled + toggled(bool) + dGrad + setEnabled(bool) + + + 20 + 20 + + + 20 + 20 + + + + + dEnabled + toggled(bool) + dY0 + setEnabled(bool) + + + 20 + 20 + + + 20 + 20 + + + + + resultSave + clicked() + TableBuilder + resultSave_clicked() + + + 20 + 20 + + + 20 + 20 + + + + + dhColor + clicked() + TableBuilder + dhColor_clicked() + + + 20 + 20 + + + 20 + 20 + + + + + vColor + clicked() + TableBuilder + vColor_clicked() + + + 20 + 20 + + + 20 + 20 + + + + + dColor + clicked() + TableBuilder + dColor_clicked() + + + 20 + 20 + + + 20 + 20 + + + + + hbColor + clicked() + TableBuilder + hbColor_clicked() + + + 20 + 20 + + + 20 + 20 + + + + + cColor + clicked() + TableBuilder + cColor_clicked() + + + 20 + 20 + + + 20 + 20 + + + + + hColor + clicked() + TableBuilder + hColor_clicked() + + + 20 + 20 + + + 20 + 20 + + + + + dbColor + clicked() + TableBuilder + dbColor_clicked() + + + 20 + 20 + + + 20 + 20 + + + + + vbColor + clicked() + TableBuilder + vbColor_clicked() + + + 20 + 20 + + + 20 + 20 + + + + + dvColor + clicked() + TableBuilder + dvColor_clicked() + + + 20 + 20 + + + 20 + 20 + + + + + vBorder + toggled(bool) + TableBuilder + result_changed() + + + 20 + 20 + + + 20 + 20 + + + + + dBorder + toggled(bool) + TableBuilder + result_changed() + + + 20 + 20 + + + 20 + 20 + + + + + hBorder + toggled(bool) + TableBuilder + result_changed() + + + 20 + 20 + + + 20 + 20 + + + + + dEnabled + toggled(bool) + TableBuilder + result_changed() + + + 20 + 20 + + + 20 + 20 + + + + + dY0 + valueChanged(int) + TableBuilder + result_changed() + + + 20 + 20 + + + 20 + 20 + + + + + dGrad + valueChanged(int) + TableBuilder + result_changed() + + + 20 + 20 + + + 20 + 20 + + + + + fileOpenAction + activated() + TableBuilder + fileOpenAction_activated() + + + -1 + -1 + + + 20 + 20 + + + + + fileSaveAction + activated() + TableBuilder + fileSaveAction_activated() + + + -1 + -1 + + + 20 + 20 + + + + + fileSaveAsAction + activated() + TableBuilder + fileSaveAsAction_activated() + + + -1 + -1 + + + 20 + 20 + + + + +
diff -urN ./src/video/openglhq/test.c ./src/video/openglhq/test.c --- ./src/video/openglhq/test.c 1970-01-01 09:00:00 +0900 +++ ./src/video/openglhq/test.c 2012-10-16 22:40:42 +0900 @@ -0,0 +1,77 @@ +#include +#include "SDL.h" + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) + +int main(int argc, char *argv[]) +{ + int w = 0, h = 0; + int c1 = 0x00ffffff, c2 = 0x00000000, c3 = 0x00ff0000; + int once = 0; + + if (argc > 1 && !strcmp(argv[0], "--once")) { + once = 1; + argv++; + argc--; + } + if (argc > 1) w = atoi(argv[1]); + if (argc > 2) h = atoi(argv[2]); + if (argc > 3) c1 = atoi(argv[3]); + if (argc > 4) c2 = atoi(argv[4]); + if (w <= 0) w = 160; + if (h <= 0) h = 120; + + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0) { + fprintf(stderr, "SDL error: %s\n", SDL_GetError()); + exit(1); + } + atexit(SDL_Quit); + + SDL_Surface *display; +#define SET(x,y,c) do { uint32_t *line = display->pixels+(y)*display->pitch; line[(x)] = (c); } while (0) + + display = SDL_SetVideoMode(w, h, 0,0);//32, SDL_SWSURFACE); + if (display == NULL) { + fprintf(stderr, "SDL error: %s\n", SDL_GetError()); + exit(1); + } + + SDL_Event event; + int end = 0; + int mx = 0, my = 0, i; + + while (!end) { + SDL_FillRect(display, NULL, c2); + + SDL_Rect r = { 3, 0, w-3, 1 }; + for (; r.y < h; r.y += 2, r.x += 2, r.w -= 2) SDL_FillRect(display, &r, c1); + r.x = 0; + r.y = 3; + r.w = 1; + r.h = h-3; + for (; r.x < w; r.x += 2, r.y += 2, r.h -= 2) SDL_FillRect(display, &r, c1); + + for (i = 0; i < w && i < h; i++) SET(i, i, c1); + + SET(mx, my, c3); + SDL_UpdateRect(display, max(0,mx-10), max(0,my-10), min(w-mx+10,20), min(h-my+10,20)); + + end = !SDL_WaitEvent(&event) || once; + switch (event.type) { + case SDL_QUIT: + end = 1; + break; + case SDL_MOUSEMOTION: + SET(mx, my, (mx&1 && my&1?c2:c1)); + SDL_UpdateRect(display, max(0,mx-10), max(0,my-10), min(w-mx+10,20), min(h-my+10,20)); + mx = event.motion.x; + my = event.motion.y; + break; + default: + break; + } + } + + return 0; +} diff -urN ./src/video/quartz/SDL_QuartzVideo.m ./src/video/quartz/SDL_QuartzVideo.m --- ./src/video/quartz/SDL_QuartzVideo.m 2012-11-07 23:05:35 +0900 +++ ./src/video/quartz/SDL_QuartzVideo.m 2012-11-07 23:36:45 +0900 @@ -24,6 +24,18 @@ #include "SDL_QuartzVideo.h" #include "SDL_QuartzWindow.h" +/* functions called in RunThread */ +void* QZ_allocPool() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + return (void *)pool; +} + +void QZ_freePool(void *p) { + NSAutoreleasePool *pool = (NSAutoreleasePool *)p; + [pool release]; +} + + /* These APIs aren't just deprecated; they're gone from the headers in the 10.7 SDK. If we're using a >= 10.7 SDK, but targeting < 10.7, then we force these function declarations. */ diff -urN ./src/video/wincommon/SDL_lowvideo.h ./src/video/wincommon/SDL_lowvideo.h --- ./src/video/wincommon/SDL_lowvideo.h 2012-11-07 23:05:35 +0900 +++ ./src/video/wincommon/SDL_lowvideo.h 2012-11-07 23:22:06 +0900 @@ -67,6 +67,7 @@ SDL_VideoSurface && \ FULLSCREEN() && \ ((SDL_VideoSurface->flags & SDL_OPENGL ) != SDL_OPENGL ) && \ + ((SDL_VideoSurface->flags & 0x40 ) != 0x40 ) && \ (SDL_strcmp(this->name, "directx") == 0) \ ) diff -urN ./src/video/wincommon/SDL_sysevents.c ./src/video/wincommon/SDL_sysevents.c --- ./src/video/wincommon/SDL_sysevents.c 2012-11-07 23:05:35 +0900 +++ ./src/video/wincommon/SDL_sysevents.c 2012-11-07 23:22:26 +0900 @@ -643,7 +643,8 @@ hdc = BeginPaint(SDL_Window, &ps); if ( current_video->screen && - !(current_video->screen->flags & SDL_OPENGL) ) { + !(current_video->screen->flags & SDL_OPENGL) && + !(current_video->screen->flags & 0x40) ) { WIN_WinPAINT(current_video, hdc); } EndPaint(SDL_Window, &ps); diff -urN ./src/video/wincommon/SDL_syswm.c ./src/video/wincommon/SDL_syswm.c --- ./src/video/wincommon/SDL_syswm.c 2012-11-07 23:05:35 +0900 +++ ./src/video/wincommon/SDL_syswm.c 2012-11-07 23:36:45 +0900 @@ -295,3 +295,15 @@ return(-1); } } + +int WIN_GetDesktopMode(_THIS, int *width, int *height) +{ + DEVMODE dm; + if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm)) { + *width = dm.dmPelsWidth; + *height = dm.dmPelsHeight; + return 1; + } else { + return 0; + } +} diff -urN ./src/video/wincommon/SDL_syswm_c.h ./src/video/wincommon/SDL_syswm_c.h --- ./src/video/wincommon/SDL_syswm_c.h 2012-11-07 23:05:35 +0900 +++ ./src/video/wincommon/SDL_syswm_c.h 2012-11-07 23:36:45 +0900 @@ -32,4 +32,4 @@ extern int WIN_IconifyWindow(_THIS); extern SDL_GrabMode WIN_GrabInput(_THIS, SDL_GrabMode mode); extern int WIN_GetWMInfo(_THIS, SDL_SysWMinfo *info); - +extern int WIN_GetDesktopMode(_THIS, int *width, int *height); diff -urN ./src/video/windib/SDL_dibvideo.c ./src/video/windib/SDL_dibvideo.c --- ./src/video/windib/SDL_dibvideo.c 2012-11-07 23:05:35 +0900 +++ ./src/video/windib/SDL_dibvideo.c 2012-11-07 23:36:45 +0900 @@ -176,6 +176,7 @@ /* Set the function pointers */ device->VideoInit = DIB_VideoInit; device->ListModes = DIB_ListModes; + device->GetDesktopMode = WIN_GetDesktopMode; device->SetVideoMode = DIB_SetVideoMode; device->UpdateMouse = WIN_UpdateMouse; device->SetColors = DIB_SetColors; diff -urN ./src/video/windx5/SDL_dx5video.c ./src/video/windx5/SDL_dx5video.c --- ./src/video/windx5/SDL_dx5video.c 2012-11-07 23:05:37 +0900 +++ ./src/video/windx5/SDL_dx5video.c 2012-11-07 23:36:45 +0900 @@ -599,6 +599,7 @@ /* Set the function pointers */ device->VideoInit = DX5_VideoInit; device->ListModes = DX5_ListModes; + device->GetDesktopMode = WIN_GetDesktopMode; device->SetVideoMode = DX5_SetVideoMode; device->UpdateMouse = WIN_UpdateMouse; device->CreateYUVOverlay = DX5_CreateYUVOverlay; @@ -1030,6 +1031,9 @@ static void DX5_WindowUpdate(_THIS, int numrects, SDL_Rect *rects); static void DX5_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); +/* Bah...HW surfaces won't work after OpenGL was active */ +static char OGL_WasUsed = 0; + SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { @@ -1065,8 +1069,9 @@ #ifndef NO_CHANGEDISPLAYSETTINGS /* Unset any previous OpenGL fullscreen mode */ - if ( (current->flags & (SDL_OPENGL|SDL_FULLSCREEN)) == - (SDL_OPENGL|SDL_FULLSCREEN) ) { + if ( ((current->flags & (SDL_OPENGL|SDL_FULLSCREEN)) == + (SDL_OPENGL|SDL_FULLSCREEN)) || + (current->flags & 0x40) ) { ChangeDisplaySettings(NULL, 0); } #endif @@ -1077,11 +1082,12 @@ } /* If we are setting a GL mode, use GDI, not DirectX (yuck) */ - if ( flags & SDL_OPENGL ) { + /* Sometimes this is usefull... */ + if ( (flags & SDL_OPENGL) || (flags & 0x40) ) { Uint32 Rmask, Gmask, Bmask; /* Recalculate the bitmasks if necessary */ - if ( bpp == current->format->BitsPerPixel ) { + if ( (bpp == current->format->BitsPerPixel) || (flags & 0x40) ) { video = current; } else { switch (bpp) { @@ -1248,10 +1254,13 @@ SDL_resizing = 0; /* Set up for OpenGL */ - if ( WIN_GL_SetupWindow(this) < 0 ) { - return(NULL); - } - video->flags |= SDL_OPENGL; + if ( flags & SDL_OPENGL ) { + if ( WIN_GL_SetupWindow(this) < 0 ) { + return(NULL); + } + OGL_WasUsed = 1; + video->flags |= SDL_OPENGL; + } else video->flags |= SDL_SWSURFACE|0x40; return(video); } @@ -1513,7 +1522,7 @@ } } dd_surface3 = NULL; -#if 0 /* FIXME: enable this when SDL consistently reports lost surfaces */ +#if 1 /* FIXME: enable this when SDL consistently reports lost surfaces */ if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { video->flags |= SDL_HWSURFACE; } else { @@ -1649,7 +1658,7 @@ Flush the message loop or this can cause big problems later Especially if the user decides to use dialog boxes or assert()! */ - WIN_FlushMessageQueue(); + //WIN_FlushMessageQueue(); /* We're live! */ return(video); @@ -1658,6 +1667,7 @@ struct private_hwdata { LPDIRECTDRAWSURFACE3 dd_surface; LPDIRECTDRAWSURFACE3 dd_writebuf; + void *buffer; }; static int DX5_AllocDDSurface(_THIS, SDL_Surface *surface, @@ -1835,6 +1845,7 @@ } } surface->hwdata->dd_writebuf = dd_surface3; + surface->hwdata->buffer = NULL; /* We're ready to go! */ return(0); @@ -2084,6 +2095,9 @@ ((ddsd.dwWidth-surface->w)/2)* surface->format->BytesPerPixel; } + if ( !surface->hwdata->buffer && surface->pixels ) { + surface->hwdata->buffer = surface->pixels; + } surface->pixels = ddsd.lpSurface; return(0); } @@ -2125,6 +2139,9 @@ if ( surface->hwdata->dd_surface != SDL_primary ) { IDirectDrawSurface3_Release(surface->hwdata->dd_surface); } + if ( surface->hwdata->buffer ) { + SDL_free(surface->hwdata->buffer); + } SDL_free(surface->hwdata); surface->hwdata = NULL; } @@ -2401,8 +2418,9 @@ /* If we're fullscreen GL, we need to reset the display */ if ( this->screen != NULL ) { #ifndef NO_CHANGEDISPLAYSETTINGS - if ( (this->screen->flags & (SDL_OPENGL|SDL_FULLSCREEN)) == - (SDL_OPENGL|SDL_FULLSCREEN) ) { + if ( ((this->screen->flags & (SDL_OPENGL|SDL_FULLSCREEN)) == + (SDL_OPENGL|SDL_FULLSCREEN)) || + (this->screen->flags & 0x40) ) { ChangeDisplaySettings(NULL, 0); ShowWindow(SDL_Window, SW_HIDE); } diff -urN ./src/video/x11/SDL_x11modes.c ./src/video/x11/SDL_x11modes.c --- ./src/video/x11/SDL_x11modes.c 2012-11-07 23:05:38 +0900 +++ ./src/video/x11/SDL_x11modes.c 2012-11-07 23:36:45 +0900 @@ -928,6 +928,13 @@ #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ } +int X11_GetDesktopMode(_THIS, int *width, int *height) +{ + *width = DisplayWidth(SDL_Display, SDL_Screen); + *height = DisplayHeight(SDL_Display, SDL_Screen); + return 1; +} + int X11_ResizeFullScreen(_THIS) { int x = 0, y = 0; diff -urN ./src/video/x11/SDL_x11modes_c.h ./src/video/x11/SDL_x11modes_c.h --- ./src/video/x11/SDL_x11modes_c.h 2012-11-07 23:05:38 +0900 +++ ./src/video/x11/SDL_x11modes_c.h 2012-11-07 23:36:46 +0900 @@ -35,6 +35,7 @@ extern int X11_GetVideoModes(_THIS); extern SDL_Rect **X11_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); extern void X11_FreeVideoModes(_THIS); +extern int X11_GetDesktopMode(_THIS, int *width, int *height); extern int X11_ResizeFullScreen(_THIS); extern void X11_WaitMapped(_THIS, Window win); extern void X11_WaitUnmapped(_THIS, Window win); diff -urN ./src/video/x11/SDL_x11video.c ./src/video/x11/SDL_x11video.c --- ./src/video/x11/SDL_x11video.c 2012-11-07 23:05:38 +0900 +++ ./src/video/x11/SDL_x11video.c 2012-11-07 23:36:46 +0900 @@ -131,6 +131,7 @@ /* Set the function pointers */ device->VideoInit = X11_VideoInit; device->ListModes = X11_ListModes; + device->GetDesktopMode = X11_GetDesktopMode; device->SetVideoMode = X11_SetVideoMode; device->ToggleFullScreen = X11_ToggleFullScreen; device->UpdateMouse = X11_UpdateMouse;