test/testoverlay2.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 10 Dec 2003 12:35:56 +0000
changeset 753 b14fdadd8311
parent 673 63419da96d13
child 886 05c551e5bc64
permissions -rw-r--r--
Date: Thu, 4 Dec 2003 07:48:40 +0200
From: "Mike Gorchak"
Subject: SDL/QNX6 new patch

Here in attachment my patch for the SDL/QNX6 again :) It contain non-crtitical/cosmetic fixes:

1. Fixed window centering at other than the first consoles.
2. Fixed window centering algorithm in case when window height or width are greater than the desktop resolution.
3. Fixed window positioning on other than the first consoles.
4. Fixed occasional input focus lost when switching to fullscreen.
5. Removed the Photon's default chroma color for the overlays, added RGB(12, 6, 12) color instead (very dark pink).
6. Added more checks to the YUV overlay code (fixed crashes during resolution mode switches).
7. Added support for Enter/Backspace keys in unicode mode (used by Maelstrom and by other games).
8. Fixed window restore/maximize function. It works, finally.
     1 /********************************************************************************
     2  *                                                                              *
     3  * Test of the overlay used for moved pictures, test more closed to real life.  *
     4  * Running trojan moose :) Coded by Mike Gorchak.                               *
     5  *                                                                              *
     6  ********************************************************************************/
     7 
     8 #include "SDL.h"
     9 
    10 #define MOOSEPIC_W 64
    11 #define MOOSEPIC_H 88
    12 
    13 #define MOOSEFRAME_SIZE (MOOSEPIC_W * MOOSEPIC_H)
    14 #define MOOSEFRAMES_COUNT 10
    15 
    16 SDL_Color MooseColors[84]={
    17     { 49,  49,  49}, { 66,  24,   0}, { 66,  33,   0}, { 66,  66,  66},
    18     { 66, 115,  49}, { 74,  33,   0}, { 74,  41,  16}, { 82,  33,   8},
    19     { 82,  41,   8}, { 82,  49,  16}, { 82,  82,  82}, { 90,  41,   8},
    20     { 90,  41,  16}, { 90,  57,  24}, { 99,  49,  16}, { 99,  66,  24},
    21     { 99,  66,  33}, { 99,  74,  33}, {107,  57,  24}, {107,  82,  41},
    22     {115,  57,  33}, {115,  66,  33}, {115,  66,  41}, {115,  74,   0},
    23     {115,  90,  49}, {115, 115, 115}, {123,  82,   0}, {123,  99,  57},
    24     {132,  66,  41}, {132,  74,  41}, {132,  90,   8}, {132,  99,  33},
    25     {132,  99,  66}, {132, 107,  66}, {140,  74,  49}, {140,  99,  16},
    26     {140, 107,  74}, {140, 115,  74}, {148, 107,  24}, {148, 115,  82},
    27     {148, 123,  74}, {148, 123,  90}, {156, 115,  33}, {156, 115,  90},
    28     {156, 123,  82}, {156, 132,  82}, {156, 132,  99}, {156, 156, 156},
    29     {165, 123,  49}, {165, 123,  90}, {165, 132,  82}, {165, 132,  90},
    30     {165, 132,  99}, {165, 140,  90}, {173, 132,  57}, {173, 132,  99},
    31     {173, 140, 107}, {173, 140, 115}, {173, 148,  99}, {173, 173, 173},
    32     {181, 140,  74}, {181, 148, 115}, {181, 148, 123}, {181, 156, 107},
    33     {189, 148, 123}, {189, 156,  82}, {189, 156, 123}, {189, 156, 132},
    34     {189, 189, 189}, {198, 156, 123}, {198, 165, 132}, {206, 165,  99},
    35     {206, 165, 132}, {206, 173, 140}, {206, 206, 206}, {214, 173, 115},
    36     {214, 173, 140}, {222, 181, 148}, {222, 189, 132}, {222, 189, 156},
    37     {222, 222, 222}, {231, 198, 165}, {231, 231, 231}, {239, 206, 173}
    38 };
    39 
    40 /* All RGB2YUV conversion code and some other parts of code has been taken from testoverlay.c */
    41 
    42 /* NOTE: These RGB conversion functions are not intended for speed,
    43          only as examples.
    44 */
    45 
    46 void RGBtoYUV(Uint8 *rgb, int *yuv, int monochrome, int luminance)
    47 {
    48     int i;
    49 
    50     if (monochrome)
    51     {
    52 #if 1 /* these are the two formulas that I found on the FourCC site... */
    53         yuv[0] = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2];
    54         yuv[1] = 128;
    55         yuv[2] = 128;
    56 #else
    57         yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
    58         yuv[1] = 128;
    59         yuv[2] = 128;
    60 #endif
    61     }
    62     else
    63     {
    64 #if 1 /* these are the two formulas that I found on the FourCC site... */
    65         yuv[0] = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2];
    66         yuv[1] = (rgb[2]-yuv[0])*0.565 + 128;
    67         yuv[2] = (rgb[0]-yuv[0])*0.713 + 128;
    68 #else
    69         yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
    70         yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]);
    71         yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]);
    72 #endif
    73     }
    74 
    75     if (luminance!=100)
    76     {
    77         yuv[0]=yuv[0]*luminance/100;
    78         if (yuv[0]>255)
    79             yuv[0]=255;
    80     }
    81 }
    82 
    83 ConvertRGBtoYV12(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
    84 {
    85 	int x,y;
    86 	int yuv[3];
    87 	Uint8 *p,*op[3];
    88 
    89 	SDL_LockSurface(s);
    90 	SDL_LockYUVOverlay(o);
    91 
    92 	/* Convert */
    93 	for(y=0; y<s->h && y<o->h; y++)
    94 	{
    95 		p=((Uint8 *) s->pixels)+s->pitch*y;
    96 		op[0]=o->pixels[0]+o->pitches[0]*y;
    97 		op[1]=o->pixels[1]+o->pitches[1]*(y/2);
    98 		op[2]=o->pixels[2]+o->pitches[2]*(y/2);
    99 		for(x=0; x<s->w && x<o->w; x++)
   100 		{
   101 			RGBtoYUV(p, yuv, monochrome, luminance);
   102 			*(op[0]++)=yuv[0];
   103 			if(x%2==0 && y%2==0)
   104 			{
   105 				*(op[1]++)=yuv[2];
   106 				*(op[2]++)=yuv[1];
   107 			}
   108 			p+=s->format->BytesPerPixel;
   109 		}
   110 	}
   111 
   112 	SDL_UnlockYUVOverlay(o);
   113 	SDL_UnlockSurface(s);
   114 }
   115 
   116 ConvertRGBtoIYUV(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
   117 {
   118 	int x,y;
   119 	int yuv[3];
   120 	Uint8 *p,*op[3];
   121 
   122 	SDL_LockSurface(s);
   123 	SDL_LockYUVOverlay(o);
   124 
   125 	/* Convert */
   126 	for(y=0; y<s->h && y<o->h; y++)
   127 	{
   128 		p=((Uint8 *) s->pixels)+s->pitch*y;
   129 		op[0]=o->pixels[0]+o->pitches[0]*y;
   130 		op[1]=o->pixels[1]+o->pitches[1]*(y/2);
   131 		op[2]=o->pixels[2]+o->pitches[2]*(y/2);
   132 		for(x=0; x<s->w && x<o->w; x++)
   133 		{
   134 			RGBtoYUV(p,yuv, monochrome, luminance);
   135 			*(op[0]++)=yuv[0];
   136 			if(x%2==0 && y%2==0)
   137 			{
   138 				*(op[1]++)=yuv[1];
   139 				*(op[2]++)=yuv[2];
   140 			}
   141 			p+=s->format->BytesPerPixel;
   142 		}
   143 	}
   144 
   145 	SDL_UnlockYUVOverlay(o);
   146 	SDL_UnlockSurface(s);
   147 }
   148 
   149 ConvertRGBtoUYVY(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
   150 {
   151 	int x,y;
   152 	int yuv[3];
   153 	Uint8 *p,*op;
   154 
   155 	SDL_LockSurface(s);
   156 	SDL_LockYUVOverlay(o);
   157 
   158 	for(y=0; y<s->h && y<o->h; y++)
   159 	{
   160 		p=((Uint8 *) s->pixels)+s->pitch*y;
   161 		op=o->pixels[0]+o->pitches[0]*y;
   162 		for(x=0; x<s->w && x<o->w; x++)
   163 		{
   164 			RGBtoYUV(p, yuv, monochrome, luminance);
   165 			if(x%2==0)
   166 			{
   167 				*(op++)=yuv[1];
   168 				*(op++)=yuv[0];
   169 				*(op++)=yuv[2];
   170 			}
   171 			else
   172 				*(op++)=yuv[0];
   173 
   174 			p+=s->format->BytesPerPixel;
   175 		}
   176 	}
   177 
   178 	SDL_UnlockYUVOverlay(o);
   179 	SDL_UnlockSurface(s);
   180 }
   181 
   182 ConvertRGBtoYVYU(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
   183 {
   184 	int x,y;
   185 	int yuv[3];
   186 	Uint8 *p,*op;
   187 
   188 	SDL_LockSurface(s);
   189 	SDL_LockYUVOverlay(o);
   190 
   191 	for(y=0; y<s->h && y<o->h; y++)
   192 	{
   193 		p=((Uint8 *) s->pixels)+s->pitch*y;
   194 		op=o->pixels[0]+o->pitches[0]*y;
   195 		for(x=0; x<s->w && x<o->w; x++)
   196 		{
   197 			RGBtoYUV(p,yuv, monochrome, luminance);
   198 			if(x%2==0)
   199 			{
   200 				*(op++)=yuv[0];
   201 				*(op++)=yuv[2];
   202 				op[1]=yuv[1];
   203 			}
   204 			else
   205 			{
   206 				*op=yuv[0];
   207 				op+=2;
   208 			}
   209 
   210 			p+=s->format->BytesPerPixel;
   211 		}
   212 	}
   213 
   214 	SDL_UnlockYUVOverlay(o);
   215 	SDL_UnlockSurface(s);
   216 }
   217 
   218 ConvertRGBtoYUY2(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
   219 {
   220 	int x,y;
   221 	int yuv[3];
   222 	Uint8 *p,*op;
   223 
   224 	SDL_LockSurface(s);
   225 	SDL_LockYUVOverlay(o);
   226         
   227 	for(y=0; y<s->h && y<o->h; y++)
   228 	{
   229 		p=((Uint8 *) s->pixels)+s->pitch*y;
   230 		op=o->pixels[0]+o->pitches[0]*y;
   231 		for(x=0; x<s->w && x<o->w; x++)
   232 		{
   233 			RGBtoYUV(p,yuv, monochrome, luminance);
   234 			if(x%2==0)
   235 			{
   236 				*(op++)=yuv[0];
   237 				*(op++)=yuv[1];
   238 				op[1]=yuv[2];
   239 			}
   240 			else
   241 			{
   242 				*op=yuv[0];
   243 				op+=2;
   244 			}
   245 
   246 			p+=s->format->BytesPerPixel;
   247 		}
   248 	}
   249 
   250 	SDL_UnlockYUVOverlay(o);
   251 	SDL_UnlockSurface(s);
   252 }
   253 
   254 static void PrintUsage(char *argv0)
   255 {
   256     fprintf(stderr, "Usage: %s [arg] [arg] [arg] ...\n", argv0);
   257     fprintf(stderr, "Where 'arg' is one of:\n");
   258     fprintf(stderr, "	-fps <frames per second>\n");
   259     fprintf(stderr, "	-format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n");
   260     fprintf(stderr, "	-scale <scale factor> (initial scale of the overlay)\n");
   261     fprintf(stderr, "	-help (shows this help)\n");
   262     fprintf(stderr, "\n");
   263     fprintf(stderr, "	Press ESC to exit, or SPACE to freeze the movie while application running.\n");
   264     fprintf(stderr, "\n");
   265 }
   266 
   267 int main(int argc, char **argv)
   268 {
   269     Uint8* RawMooseData;
   270     SDL_RWops* handle;
   271     SDL_Surface* screen;
   272     SDL_Surface* MooseFrame[MOOSEFRAMES_COUNT];
   273     SDL_Overlay* overlay;
   274     SDL_Rect overlayrect;
   275     SDL_Event event;
   276     Uint32 lastftick;
   277     int paused=0;
   278     int resized=0;
   279     int i;
   280     int fps=12;
   281     int fpsdelay;
   282     int overlay_format=SDL_YUY2_OVERLAY;
   283     int scale=5;
   284 
   285     while ( argc > 1 )
   286     {
   287         if (strcmp(argv[1], "-fps")== 0)
   288         {
   289             if (argv[2])
   290             {
   291                 fps = atoi(argv[2]);
   292                 if (fps==0)
   293                 {
   294                     fprintf(stderr, "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
   295                     return -1;
   296                 }
   297                 if ((fps<0) || (fps>1000))
   298                 {
   299                     fprintf(stderr, "The -fps option must be in range from 1 to 1000, default is 12.\n");
   300                     return -1;
   301                 }
   302                 argv += 2;
   303                 argc -= 2;
   304             }
   305             else
   306             {
   307                 fprintf(stderr, "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
   308                 return -1;
   309             }
   310         } else
   311         if (strcmp(argv[1], "-format") == 0)
   312         {
   313             if (argv[2])
   314             {
   315                 if (!strcmp(argv[2],"YV12"))
   316                     overlay_format = SDL_YV12_OVERLAY;
   317                 else if(!strcmp(argv[2],"IYUV"))
   318                     overlay_format = SDL_IYUV_OVERLAY;
   319                 else if(!strcmp(argv[2],"YUY2"))
   320                     overlay_format = SDL_YUY2_OVERLAY;
   321                 else if(!strcmp(argv[2],"UYVY"))
   322                     overlay_format = SDL_UYVY_OVERLAY;
   323                 else if(!strcmp(argv[2],"YVYU"))
   324                     overlay_format = SDL_YVYU_OVERLAY;
   325                 else
   326                 {
   327                     fprintf(stderr, "The -format option %s is not recognized, see help for info.\n", argv[2]);
   328                     return -1;
   329                 }
   330                 argv += 2;
   331                 argc -= 2;
   332             }
   333             else
   334             {
   335                 fprintf(stderr, "The -format option requires an argument, default is YUY2.\n");
   336                 return -1;
   337             }
   338         } else
   339         if (strcmp(argv[1], "-scale") == 0)
   340         {
   341             if (argv[2])
   342             {
   343                 scale = atoi(argv[2]);
   344                 if (scale==0)
   345                 {
   346                     fprintf(stderr, "The -scale option requires an argument [from 1 to 50], default is 5.\n");
   347                     return -1;
   348                 }
   349                 if ((scale<0) || (scale>50))
   350                 {
   351                     fprintf(stderr, "The -scale option must be in range from 1 to 50, default is 5.\n");
   352                     return -1;
   353                 }
   354                 argv += 2;
   355                 argc -= 2;
   356             }
   357             else
   358             {
   359                 fprintf(stderr, "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
   360                 return -1;
   361             }
   362         } else
   363         if ((strcmp(argv[1], "-help") == 0 ) || (strcmp(argv[1], "-h") == 0))
   364         {
   365             PrintUsage(argv[0]);
   366             return 0;
   367         } else
   368         {
   369             fprintf(stderr, "Unrecognized option: %s.\n", argv[1]);
   370             return -1;
   371         }
   372         break;
   373     }
   374    
   375     RawMooseData=(Uint8*)malloc(MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT);
   376     if (RawMooseData==NULL)
   377     {
   378         fprintf(stderr, "Can't allocate memory for movie !\n");
   379         free(RawMooseData);
   380         return 1;
   381     }
   382 
   383     /* load the trojan moose images */
   384     handle=SDL_RWFromFile("moose.dat", "rb");
   385     if (handle==NULL)
   386     {
   387         fprintf(stderr, "Can't find the file moose.dat !\n");
   388         free(RawMooseData);
   389         return 2;
   390     }
   391    
   392     SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT);
   393 
   394     SDL_RWclose(handle);
   395 
   396     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0)
   397     {
   398         fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
   399         free(RawMooseData);
   400         return 3;
   401     }
   402     atexit(SDL_Quit);
   403 
   404     /* Set video mode */
   405     if ( (screen=SDL_SetVideoMode(MOOSEPIC_W*scale, MOOSEPIC_H*scale, 0, SDL_RESIZABLE | SDL_SWSURFACE)) == NULL )
   406     {
   407         fprintf(stderr, "Couldn't set video mode: %s\n", 0, SDL_GetError());
   408         free(RawMooseData);
   409         return 4;
   410     }
   411 
   412     /* Set the window manager title bar */
   413     SDL_WM_SetCaption("SDL test overlay: running moose", "testoverlay2");
   414 
   415     for (i=0; i<MOOSEFRAMES_COUNT; i++)
   416     {
   417         MooseFrame[i]=SDL_CreateRGBSurfaceFrom(RawMooseData+i*MOOSEFRAME_SIZE, MOOSEPIC_W,
   418                                                MOOSEPIC_H, 8, MOOSEPIC_W, 0, 0, 0, 0);
   419         if (MooseFrame[i]==NULL)
   420         {
   421             fprintf(stderr, "Couldn't create SDL_Surfaces:%s\n", 0, SDL_GetError());
   422             free(RawMooseData);
   423             return 5;
   424         }
   425         SDL_SetColors(MooseFrame[i], MooseColors, 0, 84);
   426 
   427 	{
   428 		SDL_Surface *newsurf;
   429 		SDL_PixelFormat format;
   430 
   431 		format.palette=NULL;
   432 		format.BitsPerPixel=32;
   433 		format.BytesPerPixel=4;
   434 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
   435 		format.Rshift=0;
   436 		format.Gshift=8;
   437 		format.Bshift=16;
   438 #else
   439 		format.Rshift=24;
   440 		format.Gshift=16;
   441 		format.Bshift=8;
   442 #endif
   443 		format.Ashift=0;
   444 		format.Rmask=0xff<<format.Rshift;
   445 		format.Gmask=0xff<<format.Gshift;
   446 		format.Bmask=0xff<<format.Bshift;
   447 		format.Amask=0;
   448 		format.Rloss=0;
   449 		format.Gloss=0;
   450 		format.Bloss=0;
   451 		format.Aloss=8;
   452 		format.colorkey=0;
   453 		format.alpha=0;
   454 
   455 		newsurf=SDL_ConvertSurface(MooseFrame[i], &format, SDL_SWSURFACE);
   456 		if(!newsurf)
   457 		{
   458                     fprintf(stderr, "Couldn't convert picture to 32bits RGB: %s\n", SDL_GetError());
   459                     return 6;
   460 		}
   461 		SDL_FreeSurface(MooseFrame[i]);
   462 		MooseFrame[i]=newsurf;
   463 	}
   464     }
   465 
   466     free(RawMooseData);
   467 
   468     overlay=SDL_CreateYUVOverlay(MOOSEPIC_W, MOOSEPIC_H, overlay_format, screen);
   469 
   470     printf("Created %dx%dx%d %s %s overlay\n",overlay->w,overlay->h,overlay->planes,
   471            overlay->hw_overlay?"hardware":"software",
   472            overlay->format==SDL_YV12_OVERLAY?"YV12":
   473            overlay->format==SDL_IYUV_OVERLAY?"IYUV":
   474            overlay->format==SDL_YUY2_OVERLAY?"YUY2":
   475            overlay->format==SDL_UYVY_OVERLAY?"UYVY":
   476            overlay->format==SDL_YVYU_OVERLAY?"YVYU":
   477            "Unknown");
   478 
   479     for(i=0; i<overlay->planes; i++)
   480     {
   481         printf("  plane %d: pitch=%d\n", i, overlay->pitches[i]);
   482     }
   483 
   484     overlayrect.x=0;
   485     overlayrect.y=0;
   486     overlayrect.w=MOOSEPIC_W*scale;
   487     overlayrect.h=MOOSEPIC_H*scale;
   488 
   489     /* set the start frame */
   490     i=0;
   491     fpsdelay=1000/fps;
   492 
   493     /* Ignore key up events, they don't even get filtered */
   494     SDL_EventState(SDL_KEYUP, SDL_IGNORE);
   495 
   496     lastftick=SDL_GetTicks();
   497 
   498     /* Loop, waiting for QUIT or RESIZE */
   499     while (1)
   500     {
   501         if (SDL_PollEvent(&event))
   502         {
   503             switch (event.type)
   504             {
   505                 case SDL_VIDEORESIZE:
   506                      screen=SDL_SetVideoMode(event.resize.w, event.resize.h, 0, SDL_RESIZABLE | SDL_SWSURFACE);
   507                      overlayrect.w=event.resize.w;
   508                      overlayrect.h=event.resize.h;
   509                      if (paused)
   510                      {
   511                          resized=1;
   512                      }
   513                      break;
   514                 case SDL_KEYDOWN:
   515                      if (event.key.keysym.sym == SDLK_SPACE)
   516                      {
   517                          paused=!paused;
   518                          break;
   519                      }
   520                      if (event.key.keysym.sym != SDLK_ESCAPE)
   521                      {
   522                          break;
   523                      }
   524                 case SDL_QUIT:
   525                      SDL_FreeYUVOverlay(overlay);
   526                      for (i=0; i<MOOSEFRAMES_COUNT; i++)
   527                      {
   528                          SDL_FreeSurface(MooseFrame[i]);
   529                      }
   530                      return 0;
   531             }
   532         }
   533 
   534         if ((!paused)||(resized))
   535         {
   536             if (((SDL_GetTicks()-lastftick)>fpsdelay)||(resized))
   537             {
   538                 lastftick=SDL_GetTicks();
   539 
   540                 switch (overlay_format)
   541                 {
   542                     case SDL_YUY2_OVERLAY:
   543                          ConvertRGBtoYUY2(MooseFrame[i], overlay, 0, 100);
   544                          break;
   545                     case SDL_YV12_OVERLAY:
   546                          ConvertRGBtoYV12(MooseFrame[i], overlay, 0, 100);
   547                          break;
   548                     case SDL_UYVY_OVERLAY:
   549                          ConvertRGBtoUYVY(MooseFrame[i], overlay, 0, 100);
   550                          break;
   551                     case SDL_YVYU_OVERLAY:
   552                          ConvertRGBtoYVYU(MooseFrame[i], overlay, 0, 100);
   553                          break;
   554                     case SDL_IYUV_OVERLAY:
   555                          ConvertRGBtoIYUV(MooseFrame[i], overlay, 0, 100);
   556                          break;
   557                 }
   558 
   559                 SDL_DisplayYUVOverlay(overlay, &overlayrect);
   560                 if (!resized)
   561                 {
   562                     i++;
   563                     if (i==10)
   564                     {
   565                         i=0;
   566                     }
   567                 }
   568                 else
   569                 {
   570                     resized=0;
   571                 }
   572             }
   573         }
   574         /* kind of timeslice to OS */
   575         SDL_Delay(1);
   576     }
   577 
   578     return 0;
   579 }
   580