Mercurial > sdl-ios-xcode
view docs/html/guidevideoexamples.html @ 664:abfdc08eb289
Date: Sun, 3 Aug 2003 22:07:57 +0200
From: Max Horn
Subject: SDL OSX fullscreen FIX
the attached patch fixes the fullscreen problems on SDL/OSX. The cause
was that click events are bounded by winRect. Now, winRect is set to
the size of the video surface. But if you e.g. request a 640x420
surface, you might get a 640x480 "real" surface. Still,
SDL_VideoSurface->h will be set to 420! Thus, the upper 60 pixels in my
example received no mouse down events.
My fix simply disables this clipping when in full screen mode - after
all, all clicks then should be inside the screen surface. Higher SDL
functions ensure that the coordinates then are clipped to 640x420. It
works fine in all my tests here. I don't know if it's the right thing
to do in multi screen scenarios, though.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 04 Aug 2003 01:00:30 +0000 |
parents | 55f1f1b3e27d |
children |
line wrap: on
line source
<HTML ><HEAD ><TITLE >Video Examples</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.64 "><LINK REL="HOME" TITLE="SDL Library Documentation" HREF="index.html"><LINK REL="UP" TITLE="Examples" HREF="guideexamples.html"><LINK REL="PREVIOUS" TITLE="Examples" HREF="guideexamples.html"><LINK REL="NEXT" TITLE="Event Examples" HREF="guideeventexamples.html"></HEAD ><BODY CLASS="SECT1" BGCOLOR="#FFF8DC" TEXT="#000000" LINK="#0000ee" VLINK="#551a8b" ALINK="#ff0000" ><DIV CLASS="NAVHEADER" ><TABLE WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="3" ALIGN="center" >SDL Library Documentation</TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A HREF="guideexamples.html" >Prev</A ></TD ><TD WIDTH="80%" ALIGN="center" VALIGN="bottom" >Chapter 4. Examples</TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A HREF="guideeventexamples.html" >Next</A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><DIV CLASS="SECT1" ><H1 CLASS="SECT1" ><A NAME="GUIDEVIDEOEXAMPLES" >Video Examples</A ></H1 ><P ></P ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="AEN375" >Initializing the video display</A ></H2 ><P ><PRE CLASS="PROGRAMLISTING" > SDL_Surface *screen; /* Initialize the SDL library */ if( SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); exit(1); } /* Clean up on exit */ atexit(SDL_Quit); /* Initialize the display in a 640x480 8-bit palettized mode */ screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n", SDL_GetError()); exit(1); }</PRE ></P ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="AEN379" >Initializing the best video mode</A ></H2 ><P ><PRE CLASS="PROGRAMLISTING" > /* Have a preference for 8-bit, but accept any depth */ screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE|SDL_ANYFORMAT); if ( screen == NULL ) { fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n", SDL_GetError()); exit(1); } printf("Set 640x480 at %d bits-per-pixel mode\n", screen->format->BitsPerPixel);</PRE ></P ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="AEN383" >Loading and displaying a BMP file</A ></H2 ><P ><PRE CLASS="PROGRAMLISTING" > SDL_Surface *image; SDL_Rect dest; int ncolors, i; SDL_Color *colors; /* Load the BMP file into a surface */ image = SDL_LoadBMP("sample.bmp"); if ( image == NULL ) { fprintf(stderr, "Couldn't load sample.bmp: %s\n", SDL_GetError()); return; } /* Set the display colors -- SDL_SetColors() only does something on palettized displays, but it doesn't hurt anything on HiColor or TrueColor displays. If the display colors have already been set, this step can be skipped, and the library will automatically map the image to the current display colors. */ if ( image->format->palette ) { ncolors = image->format->palette->ncolors; colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color)); memcpy(colors, image->format->palette->colors, ncolors); } else { int r, g, b; /* Allocate 256 color palette */ ncolors = 256; colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color)); /* Set a 3,3,2 color cube */ for ( r=0; r<8; ++r ) { for ( g=0; g<8; ++g ) { for ( b=0; b<4; ++b ) { i = ((r<<5)|(g<<2)|b); colors[i].r = r<<5; colors[i].g = g<<5; colors[i].b = b<<6; } } } /* Note: A better way of allocating the palette might be to calculate the frequency of colors in the image and create a palette based on that information. */ } /* Set colormap, try for all the colors, but don't worry about it */ SDL_SetColors(screen, colors, 0, ncolors); free(colors); /* Blit onto the screen surface */ dest.x = 0; dest.y = 0; dest.w = image->w; dest.h = image->h; SDL_BlitSurface(image, NULL, screen, &dest); SDL_UpdateRects(screen, 1, &dest); /* Free the allocated BMP surface */ SDL_FreeSurface(image); return;</PRE ></P ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="AEN387" >Drawing directly to the display</A ></H2 ><P ><PRE CLASS="PROGRAMLISTING" > /* Code to set a yellow pixel at the center of the screen */ Sint32 X, Y; Uint32 pixel; Uint8 *bits, bpp; /* Map the color yellow to this display (R=0xFF, G=0xFF, B=0x00) Note: If the display is palettized, you must set the palette first. */ pixel = SDL_MapRGB(screen->format, 0xFF, 0xFF, 0x00); /* Calculate the framebuffer offset of the center of the screen */ if ( SDL_MUSTLOCK(screen) ) { if ( SDL_LockSurface(screen) < 0 ) return; } bpp = screen->format->BytesPerPixel; X = screen->w/2; Y = screen->h/2; bits = ((Uint8 *)screen->pixels)+Y*screen->pitch+X*bpp; /* Set the pixel */ switch(bpp) { case 1: *((Uint8 *)(bits)) = (Uint8)pixel; break; case 2: *((Uint16 *)(bits)) = (Uint16)pixel; break; case 3: { /* Format/endian independent */ Uint8 r, g, b; r = (pixel>>screen->format->Rshift)&0xFF; g = (pixel>>screen->format->Gshift)&0xFF; b = (pixel>>screen->format->Bshift)&0xFF; *((bits)+screen->format->Rshift/8) = r; *((bits)+screen->format->Gshift/8) = g; *((bits)+screen->format->Bshift/8) = b; } break; case 4: *((Uint32 *)(bits)) = (Uint32)pixel; break; } /* Update the display */ if ( SDL_MUSTLOCK(screen) ) { SDL_UnlockSurface(screen); } SDL_UpdateRect(screen, X, Y, 1, 1); return;</PRE ></P ></DIV ><DIV CLASS="SECT2" ><H2 CLASS="SECT2" ><A NAME="AEN391" >Fastest possible surface blit</A ></H2 ><P >There are three different ways you can draw an image to the screen: <P ></P ><TABLE BORDER="0" ><TBODY ><TR ><TD >1.Create a surface and use <A HREF="sdlblitsurface.html" ><TT CLASS="FUNCTION" >SDL_BlitSurface</TT ></A > to blit it to the screen</TD ></TR ><TR ><TD >2.Create the video surface in system memory and call <A HREF="sdlupdaterect.html" ><TT CLASS="FUNCTION" >SDL_UpdateRect</TT ></A ></TD ></TR ><TR ><TD >3.Create the video surface in video memory and call <A HREF="sdllocksurface.html" ><TT CLASS="FUNCTION" >SDL_LockSurface</TT ></A ></TD ></TR ></TBODY ></TABLE ><P ></P > The best way to do this is to combine methods: <PRE CLASS="PROGRAMLISTING" >#include <stdio.h> #include <stdlib.h> #include "SDL.h" #include "SDL_timer.h" void ComplainAndExit(void) { fprintf(stderr, "Problem: %s\n", SDL_GetError()); exit(1); } int main(int argc, char *argv[]) { SDL_PixelFormat fmt; SDL_Surface *screen, *locked; SDL_Surface *imagebmp, *image; SDL_Rect dstrect; int i; Uint8 *buffer; /* Initialize SDL */ if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { ComplainAndExit(); } atexit(SDL_Quit); /* Load a BMP image into a surface */ imagebmp = SDL_LoadBMP("image.bmp"); if ( imagebmp == NULL ) { ComplainAndExit(); } /* Set the video mode (640x480 at native depth) */ screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE|SDL_FULLSCREEN); if ( screen == NULL ) { ComplainAndExit(); } /* Set the video colormap */ if ( imagebmp->format->palette != NULL ) { SDL_SetColors(screen, imagebmp->format->palette->colors, 0, imagebmp->format->palette->ncolors); } /* Convert the image to the video format (maps colors) */ image = SDL_DisplayFormat(imagebmp); SDL_FreeSurface(imagebmp); if ( image == NULL ) { ComplainAndExit(); } /* Draw bands of color on the raw surface */ if ( SDL_MUSTLOCK(screen) ) { if ( SDL_LockSurface(screen) < 0 ) ComplainAndExit(); } 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; } if ( SDL_MUSTLOCK(screen) ) { SDL_UnlockSurface(screen); } /* Blit the image to the center of the screen */ dstrect.x = (screen->w-image->w)/2; dstrect.y = (screen->h-image->h)/2; dstrect.w = image->w; dstrect.h = image->h; if ( SDL_BlitSurface(image, NULL, screen, &dstrect) < 0 ) { SDL_FreeSurface(image); ComplainAndExit(); } SDL_FreeSurface(image); /* Update the screen */ SDL_UpdateRects(screen, 1, &dstrect); SDL_Delay(5000); /* Wait 5 seconds */ exit(0); }</PRE ></P ></DIV ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="guideexamples.html" >Prev</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="index.html" >Home</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="guideeventexamples.html" >Next</A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Examples</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="guideexamples.html" >Up</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >Event Examples</TD ></TR ></TABLE ></DIV ></BODY ></HTML >