Mercurial > sdl-ios-xcode
view test/testwm.c @ 876:9e84d106ec19
(Said Max Horn on the SDL mailing list...)
Hi folks,
based on Eric Wing's patch, I created the attached patch which fixes
the OpenGL coordinate inversion bug in SDL. It works fine over here on
10.3 with Ryan's test program (which I also attached).
There is another change in it: I removed the "- 1" in the two lines
using CGDisplayPixelsHigh()... while I understand from a logical point
of view why they *should* be correct, I checked the actual values
computed that way, and they were off-by-one. After removing the " - 1",
the returned mouse coordinates are correct. I checked this by moving
the mouse to the screen top/bottom in fullscreen mode, BTW. With the
change, the proper values 0 and 479 are returned (in 640x480 mode).
Sam, you may still want to test on 10.1, it's very simple using Ryan's
minimal test code :-)
Cheers,
Max
(Here is the reproduction case for revision history's sake...)
/*
* To compile:
* gcc -o test test.c `sdl-config --cflags` `sdl-config --libs` -framework OpenGL
*
* --ryan.
*/
#include <stdio.h>
#include "SDL.h"
#include "SDL_opengl.h"
int main(int argc, char **argv)
{
Uint32 flags = SDL_OPENGL /* | SDL_FULLSCREEN */;
SDL_Surface *screen;
SDL_Event event;
int done = 0;
GLfloat ratio;
SDL_Init(SDL_INIT_VIDEO);
SDL_ShowCursor(0);
if ((argv[1]) && (strcmp(argv[1], "--grab") == 0))
SDL_WM_GrabInput(SDL_GRAB_ON);
screen = SDL_SetVideoMode(640, 480, 0, flags);
if (!screen)
return(42);
ratio = ((GLfloat) screen->w) / ((GLfloat) screen->h);
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClearDepth( 1.0f );
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
glViewport( 0, 0, screen->w, screen->h);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 45.0f, ratio, 0.1f, 100.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SDL_GL_SwapBuffers();
// eh, close enough.
#define MAX_X 6.12
#define MAX_Y 4.50
while (!done)
{
int x, y;
GLfloat glx, gly;
if (!SDL_WaitEvent(&event))
break;
switch (event.type)
{
case SDL_KEYUP:
if (event.key.keysym.sym == SDLK_ESCAPE)
done = 1;
break;
}
SDL_GetMouseState(&x, &y);
glx = ((((GLfloat) x) / ((GLfloat) screen->w)) - 0.5f) * MAX_X;
gly = ((((GLfloat) y) / ((GLfloat) screen->h)) - 0.5f) * MAX_Y;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(glx,-gly,-6.0f);
glBegin(GL_TRIANGLES);
glColor3f(1,0,0); glVertex3f( 0.00f, 0.25f, 0.00f);
glColor3f(0,1,0); glVertex3f(-0.25f, -0.25f, 0.00f);
glColor3f(0,0,1); glVertex3f( 0.25f, -0.25f, 0.00f);
glEnd();
SDL_GL_SwapBuffers();
}
SDL_Quit();
return(0);
}
/* end of test.c ... */
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Mon, 22 Mar 2004 09:38:20 +0000 |
parents | 3eddf51b649b |
children | be9c9c8f6d53 |
line wrap: on
line source
/* Test out the window manager interaction functions */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "SDL.h" /* Is the cursor visible? */ static int visible = 1; static Uint8 video_bpp; static Uint32 video_flags; int SetVideoMode(int w, int h) { SDL_Surface *screen; int i; Uint8 *buffer; SDL_Color palette[256]; screen = SDL_SetVideoMode(w, h, video_bpp, video_flags); if ( screen == NULL ) { fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n", w, h, video_bpp, SDL_GetError()); return(-1); } printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ? "fullscreen" : "windowed"); /* Set the surface pixels and refresh! */ for ( i=0; i<256; ++i ) { palette[i].r = 255-i; palette[i].g = 255-i; palette[i].b = 255-i; } SDL_SetColors(screen, palette, 0, 256); if ( SDL_LockSurface(screen) < 0 ) { fprintf(stderr, "Couldn't lock display surface: %s\n", SDL_GetError()); return(-1); } buffer = (Uint8 *)screen->pixels; for ( i=0; i<screen->h; ++i ) { memset(buffer,(i*255)/screen->h, screen->w*screen->format->BytesPerPixel); buffer += screen->pitch; } SDL_UnlockSurface(screen); SDL_UpdateRect(screen, 0, 0, 0, 0); return(0); } SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp) { SDL_Surface *icon; Uint8 *pixels; Uint8 *mask; int mlen, i, j; *maskp = NULL; /* Load the icon surface */ icon = SDL_LoadBMP(file); if ( icon == NULL ) { fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError()); return(NULL); } /* Check width and height if ( (icon->w%8) != 0 ) { fprintf(stderr, "Icon width must be a multiple of 8!\n"); SDL_FreeSurface(icon); return(NULL); } */ if ( icon->format->palette == NULL ) { fprintf(stderr, "Icon must have a palette!\n"); SDL_FreeSurface(icon); return(NULL); } /* Set the colorkey */ SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *)icon->pixels)); /* Create the mask */ pixels = (Uint8 *)icon->pixels; printf("Transparent pixel: (%d,%d,%d)\n", icon->format->palette->colors[*pixels].r, icon->format->palette->colors[*pixels].g, icon->format->palette->colors[*pixels].b); mlen = (icon->w*icon->h + 7) / 8; mask = (Uint8 *)malloc(mlen); if ( mask == NULL ) { fprintf(stderr, "Out of memory!\n"); SDL_FreeSurface(icon); return(NULL); } memset(mask, 0, mlen); for ( i=0; i < icon->h; i++) for (j=0; j < icon->w; j++) { int pindex = i * icon->pitch + j; int mindex = i * icon->w + j; if ( pixels[pindex] != *pixels ) mask[mindex>>3] |= 1 << (7 - (mindex & 7)); } *maskp = mask; return(icon); } void HotKey_ToggleFullScreen(void) { SDL_Surface *screen; screen = SDL_GetVideoSurface(); if ( SDL_WM_ToggleFullScreen(screen) ) { printf("Toggled fullscreen mode - now %s\n", (screen->flags&SDL_FULLSCREEN) ? "fullscreen" : "windowed"); } else { printf("Unable to toggle fullscreen mode\n"); video_flags ^= SDL_FULLSCREEN; SetVideoMode(screen->w, screen->h); } } void HotKey_ToggleGrab(void) { SDL_GrabMode mode; printf("Ctrl-G: toggling input grab!\n"); mode = SDL_WM_GrabInput(SDL_GRAB_QUERY); if ( mode == SDL_GRAB_ON ) { printf("Grab was on\n"); } else { printf("Grab was off\n"); } mode = SDL_WM_GrabInput(mode ? SDL_GRAB_OFF : SDL_GRAB_ON); if ( mode == SDL_GRAB_ON ) { printf("Grab is now on\n"); } else { printf("Grab is now off\n"); } } void HotKey_Iconify(void) { printf("Ctrl-Z: iconifying window!\n"); SDL_WM_IconifyWindow(); } void HotKey_Quit(void) { SDL_Event event; printf("Posting internal quit request\n"); event.type = SDL_USEREVENT; SDL_PushEvent(&event); } int FilterEvents(const SDL_Event *event) { static int reallyquit = 0; switch (event->type) { case SDL_ACTIVEEVENT: /* See what happened */ printf("App %s ", event->active.gain ? "gained" : "lost"); if ( event->active.state & SDL_APPACTIVE ) printf("active "); if ( event->active.state & SDL_APPMOUSEFOCUS ) printf("mouse "); if ( event->active.state & SDL_APPINPUTFOCUS ) printf("input "); printf("focus\n"); /* See if we are iconified or restored */ if ( event->active.state & SDL_APPACTIVE ) { printf("App has been %s\n", event->active.gain ? "restored" : "iconified"); } return(0); /* We want to toggle visibility on buttonpress */ case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: if ( event->button.state == SDL_PRESSED ) { visible = !visible; SDL_ShowCursor(visible); } printf("Mouse button %d has been %s\n", event->button.button, (event->button.state == SDL_PRESSED) ? "pressed" : "released"); return(0); /* Show relative mouse motion */ case SDL_MOUSEMOTION: #if 0 printf("Mouse relative motion: {%d,%d}\n", event->motion.xrel, event->motion.yrel); #endif return(0); case SDL_KEYDOWN: if ( event->key.keysym.sym == SDLK_ESCAPE ) { HotKey_Quit(); } if ( (event->key.keysym.sym == SDLK_g) && (event->key.keysym.mod & KMOD_CTRL) ) { HotKey_ToggleGrab(); } if ( (event->key.keysym.sym == SDLK_z) && (event->key.keysym.mod & KMOD_CTRL) ) { HotKey_Iconify(); } if ( (event->key.keysym.sym == SDLK_RETURN) && (event->key.keysym.mod & KMOD_ALT) ) { HotKey_ToggleFullScreen(); } return(0); /* Pass the video resize event through .. */ case SDL_VIDEORESIZE: return(1); /* This is important! Queue it if we want to quit. */ case SDL_QUIT: if ( ! reallyquit ) { reallyquit = 1; printf("Quit requested\n"); return(0); } printf("Quit demanded\n"); return(1); /* This will never happen because events queued directly to the event queue are not filtered. */ case SDL_USEREVENT: return(1); /* Drop all other events */ default: return(0); } } int main(int argc, char *argv[]) { SDL_Event event; char *title; SDL_Surface *icon; Uint8 *icon_mask; int parsed; int w, h; if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); exit(1); } atexit(SDL_Quit); /* Check command line arguments */ w = 640; h = 480; video_bpp = 8; video_flags = SDL_SWSURFACE; parsed = 1; while ( parsed ) { if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) { video_flags |= SDL_FULLSCREEN; argc -= 1; argv += 1; } else if ( (argc >= 2) && (strcmp(argv[1], "-resize") == 0) ) { video_flags |= SDL_RESIZABLE; argc -= 1; argv += 1; } else if ( (argc >= 2) && (strcmp(argv[1], "-noframe") == 0) ) { video_flags |= SDL_NOFRAME; argc -= 1; argv += 1; } else if ( (argc >= 3) && (strcmp(argv[1], "-width") == 0) ) { w = atoi(argv[2]); argc -= 2; argv += 2; } else if ( (argc >= 3) && (strcmp(argv[1], "-height") == 0) ) { h = atoi(argv[2]); argc -= 2; argv += 2; } else if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) { video_bpp = atoi(argv[2]); argc -= 2; argv += 2; } else { parsed = 0; } } /* Set the icon -- this must be done before the first mode set */ icon = LoadIconSurface("icon.bmp", &icon_mask); if ( icon != NULL ) { SDL_WM_SetIcon(icon, icon_mask); } if ( icon_mask != NULL ) free(icon_mask); /* Set the title bar */ if ( argv[1] == NULL ) title = "Testing 1.. 2.. 3..."; else title = argv[1]; SDL_WM_SetCaption(title, "testwm"); /* See if it's really set */ SDL_WM_GetCaption(&title, NULL); if ( title ) printf("Title was set to: %s\n", title); else printf("No window title was set!\n"); /* Initialize the display */ if ( SetVideoMode(w, h) < 0 ) { return(1); } /* Set an event filter that discards everything but QUIT */ SDL_SetEventFilter(FilterEvents); /* Ignore key up events, they don't even get filtered */ SDL_EventState(SDL_KEYUP, SDL_IGNORE); /* Loop, waiting for QUIT */ while ( SDL_WaitEvent(&event) ) { switch (event.type) { case SDL_VIDEORESIZE: printf("Got a resize event: %dx%d\n", event.resize.w, event.resize.h); SetVideoMode(event.resize.w, event.resize.h); break; case SDL_USEREVENT: printf("Handling internal quit request\n"); /* Fall through to the quit handler */ case SDL_QUIT: printf("Bye bye..\n"); return(0); default: /* This should never happen */ printf("Warning: Event %d wasn't filtered\n", event.type); break; } } printf("SDL_WaitEvent() error: %s\n", SDL_GetError()); return(255); }