src/video/photon/SDL_ph_modes.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 23 Mar 2002 20:19:44 +0000
changeset 315 3333b6e68289
parent 309 2de77f7b7a28
child 571 8e3ce997621c
permissions -rw-r--r--
Date: Sat, 23 Mar 2002 13:53:37 +0200
From: "Mike Gorchak" <mike@malva.ua>
Subject: Big QNX patch again.

Added 8bit palette emulation code for window mode with bpp>=15.
Added store/restore original palette for 8bit modes.
Added more information about photon API call fails.
Rewroten change palette code, slow but works.
Fixed bug with set caption before window was inited.
Fixed bugs with some initial state of variables.
Fixed bug with storing old video mode settings.
Fixed bug with switching to fullscreen mode and back.
Fixed few double SEGFAULTS during parachute mode.
Removed compilation warning with no PgWaitHWIdle prototype.
Removed pack of dead unusable code.
Cleanups SDL_PrivateVideoData structure, some headers.
Some code formatting.
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@297
     3
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@0
     6
    modify it under the terms of the GNU Library General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@0
     8
    version 2 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@0
    13
    Library General Public License for more details.
slouken@0
    14
slouken@0
    15
    You should have received a copy of the GNU Library General Public
slouken@0
    16
    License along with this library; if not, write to the Free
slouken@0
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@0
    22
slouken@0
    23
#ifdef SAVE_RCSID
slouken@0
    24
static char rcsid =
slouken@0
    25
 "@(#) $Id$";
slouken@0
    26
#endif
slouken@0
    27
slouken@0
    28
#include "SDL_ph_modes_c.h"
slouken@0
    29
slouken@0
    30
static unsigned long key1, key2;
slouken@0
    31
static PgVideoModeInfo_t mode_info;
slouken@0
    32
static PgVideoModes_t mode_list;
slouken@266
    33
slouken@0
    34
  /* The current list of available video modes */
slouken@266
    35
SDL_Rect  SDL_modelist[PH_MAX_VIDEOMODES];
slouken@266
    36
SDL_Rect* SDL_modearray[PH_MAX_VIDEOMODES];
slouken@0
    37
slouken@0
    38
static int compare_modes_by_res(const void* mode1, const void* mode2)
slouken@0
    39
{
slouken@0
    40
slouken@0
    41
	if (PgGetVideoModeInfo(*(unsigned short*)mode1, &mode_info) < 0)
slouken@0
    42
	{
slouken@0
    43
	    fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n",
slouken@0
    44
        	    *(unsigned short*)mode1);
slouken@266
    45
    	    return 0;
slouken@0
    46
	}
slouken@0
    47
	key1 = mode_info.width * mode_info.height;
slouken@0
    48
slouken@0
    49
	if (PgGetVideoModeInfo(*(unsigned short*)mode2, &mode_info) < 0)
slouken@0
    50
	{
slouken@266
    51
    	    fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n",
slouken@0
    52
	            *(unsigned short*)mode2);
slouken@0
    53
	    return 0;
slouken@0
    54
	}
slouken@266
    55
        key2 = mode_info.width * mode_info.height;
slouken@0
    56
slouken@0
    57
	if (key1 > key2)
slouken@0
    58
		return 1;
slouken@0
    59
	else if (key1 == key2)
slouken@0
    60
		return 0;
slouken@0
    61
	else
slouken@0
    62
		return -1;
slouken@0
    63
}
slouken@0
    64
slouken@266
    65
SDL_Rect **ph_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
slouken@0
    66
{
slouken@309
    67
    int i = 0;
slouken@309
    68
    int j = 0;
slouken@309
    69
    SDL_Rect Amodelist[PH_MAX_VIDEOMODES];
slouken@0
    70
slouken@309
    71
    for (i=0; i<PH_MAX_VIDEOMODES; i++)
slouken@309
    72
    {
slouken@309
    73
        SDL_modearray[i]=&SDL_modelist[i];
slouken@309
    74
    }
slouken@309
    75
slouken@309
    76
    if (PgGetVideoModeList( &mode_list ) < 0)
slouken@309
    77
    {
slouken@309
    78
       fprintf(stderr,"error: PgGetVideoModeList failed\n");
slouken@309
    79
       return NULL;
slouken@309
    80
    }
slouken@309
    81
slouken@309
    82
    mode_info.bits_per_pixel = 0;
slouken@309
    83
slouken@309
    84
    for (i=0; i < mode_list.num_modes; i++) 
slouken@309
    85
    {
slouken@309
    86
        if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
slouken@266
    87
        {
slouken@309
    88
            fprintf(stderr,"error: PgGetVideoModeInfo failed on mode: 0x%x\n", mode_list.modes[i]);
slouken@309
    89
            return NULL;
slouken@266
    90
        }
slouken@309
    91
        if(mode_info.bits_per_pixel == format->BitsPerPixel)
slouken@309
    92
        {
slouken@309
    93
            Amodelist[j].w = mode_info.width;
slouken@309
    94
            Amodelist[j].h = mode_info.height;
slouken@309
    95
            Amodelist[j].x = 0;
slouken@309
    96
            Amodelist[j].y = 0;
slouken@309
    97
            j++;	
slouken@309
    98
        }
slouken@309
    99
    }
slouken@309
   100
	
slouken@309
   101
    /* reorder biggest for smallest, assume width dominates */
slouken@0
   102
slouken@309
   103
    for(i=0; i<j; i++)
slouken@309
   104
    {
slouken@309
   105
        SDL_modelist[i].w = Amodelist[j - i -1].w;
slouken@309
   106
        SDL_modelist[i].h = Amodelist[j - i -1].h;
slouken@309
   107
        SDL_modelist[i].x = Amodelist[j - i -1].x;
slouken@309
   108
        SDL_modelist[i].y = Amodelist[j - i -1].y;
slouken@309
   109
    }
slouken@309
   110
    SDL_modearray[j]=NULL;
slouken@0
   111
	
slouken@309
   112
    return SDL_modearray;
slouken@0
   113
}
slouken@0
   114
slouken@0
   115
void ph_FreeVideoModes(_THIS)
slouken@0
   116
{
slouken@266
   117
   return;
slouken@0
   118
}
slouken@0
   119
slouken@315
   120
#if 0
slouken@0
   121
static void set_best_resolution(_THIS, int width, int height)
slouken@0
   122
{
slouken@315
   123
    /* warning ! dead variable use_vidmode ! */
slouken@0
   124
    if ( use_vidmode ) {
slouken@0
   125
		PgDisplaySettings_t 	settings;
slouken@0
   126
		PgVideoModeInfo_t		current_mode_info;
slouken@204
   127
		PgHWCaps_t my_hwcaps;
slouken@0
   128
		unsigned short			current_bpp;
slouken@0
   129
        int i;
slouken@204
   130
	/*
slouken@0
   131
		if (PgGetVideoMode( &settings ) < 0)
slouken@0
   132
		{
slouken@0
   133
			fprintf(stderr,"error: PgGetVideoMode failed\n");
slouken@0
   134
			return;
slouken@0
   135
		}
slouken@0
   136
		if (PgGetVideoModeInfo( settings.mode, &current_mode_info ) < 0)
slouken@0
   137
		{
slouken@0
   138
			fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
slouken@0
   139
			return;
slouken@0
   140
		}
slouken@204
   141
		*/
slouken@204
   142
		//lu_zero 
slouken@204
   143
         if (PgGetGraphicsHWCaps(&my_hwcaps) < 0)
slouken@204
   144
         	{
slouken@204
   145
                fprintf(stderr,"set_best_resolution:  GetGraphicsHWCaps failed!! \n");
slouken@204
   146
      			//that HAVE to work
slouken@204
   147
            }
slouken@204
   148
         if (PgGetVideoModeInfo(my_hwcaps.current_video_mode, &current_mode_info) < 0)
slouken@204
   149
            {
slouken@204
   150
                fprintf(stderr,"set_best_resolution:  PgGetVideoModeInfo failed\n");
slouken@204
   151
            }
slouken@0
   152
		current_bpp = current_mode_info.bits_per_pixel;
slouken@0
   153
slouken@0
   154
        if (PgGetVideoModeList(&mode_list) >= 0)
slouken@0
   155
		{
slouken@0
   156
			qsort(mode_list.modes, mode_list.num_modes, sizeof(unsigned short), compare_modes_by_res);
slouken@0
   157
#ifdef PH_DEBUG
slouken@0
   158
  			printf("Available modes:\n");
slouken@0
   159
  			for ( i = 0; i < mode_list.num_modes; ++i ) 
slouken@0
   160
			{
slouken@0
   161
				PgGetVideoModeInfo(mode_list.modes[i], &mode_info);
slouken@0
   162
    			printf("Mode %d: %dx%d\n", i, mode_info.width, mode_info.height);
slouken@0
   163
  			}
slouken@0
   164
#endif
slouken@0
   165
            for ( i = mode_list.num_modes-1; i >= 0 ; --i ) 
slouken@0
   166
			{
slouken@0
   167
				if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
slouken@0
   168
				{
slouken@0
   169
					fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
slouken@0
   170
				}
slouken@0
   171
                if ( (mode_info.width >= width) &&
slouken@0
   172
                     (mode_info.height >= height) &&
slouken@0
   173
					 (mode_info.bits_per_pixel == current_bpp) )
slouken@0
   174
                    break;
slouken@0
   175
            }
slouken@0
   176
			if (i >= 0)
slouken@0
   177
			{
slouken@0
   178
                if ( (mode_info.width != current_mode_info.width) ||
slouken@0
   179
                     (mode_info.height != current_mode_info.height) ) 
slouken@0
   180
				{
slouken@0
   181
					settings.mode = mode_list.modes[i];
slouken@0
   182
					if(PgSetVideoMode( &settings ) < 0)	
slouken@0
   183
					{
slouken@0
   184
						fprintf(stderr,"error: PgSetVideoMode failed\n");
slouken@0
   185
					}
slouken@0
   186
                }
slouken@0
   187
            }
slouken@0
   188
        }
slouken@0
   189
    }
slouken@0
   190
}
slouken@0
   191
slouken@0
   192
int ph_ResizeFullScreen(_THIS)
slouken@0
   193
{
slouken@315
   194
    if (currently_fullscreen)
slouken@315
   195
    {
slouken@0
   196
        set_best_resolution(this, current_w, current_h);
slouken@0
   197
    }
slouken@315
   198
slouken@309
   199
    return (1);
slouken@0
   200
}
slouken@315
   201
#endif /* 0 */
slouken@0
   202
slouken@309
   203
/* return the mode associated with width, height and bpp */
slouken@309
   204
/* if there is no mode then zero is returned             */
slouken@0
   205
int get_mode(int width, int height, int bpp)
slouken@0
   206
{
slouken@309
   207
    int i;
slouken@0
   208
slouken@309
   209
    if(width<640)
slouken@309
   210
    {
slouken@309
   211
        width=640;
slouken@309
   212
    }
slouken@309
   213
    if(height<480)
slouken@309
   214
    {
slouken@309
   215
        height=480;
slouken@309
   216
    }
slouken@0
   217
slouken@309
   218
    if (PgGetVideoModeList(&mode_list) < 0)
slouken@309
   219
    {
slouken@309
   220
        fprintf(stderr,"error: PgGetVideoModeList failed\n");
slouken@309
   221
        return -1;
slouken@309
   222
    }
slouken@0
   223
slouken@309
   224
    /* search list for exact match */
slouken@309
   225
    for (i=0;i<mode_list.num_modes;i++)
slouken@309
   226
    {
slouken@309
   227
        if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
slouken@309
   228
        {
slouken@309
   229
            fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
slouken@309
   230
            return 0;
slouken@309
   231
        }
slouken@0
   232
slouken@309
   233
        if ((mode_info.width == width) && 
slouken@309
   234
            (mode_info.height == height) && 
slouken@309
   235
            (mode_info.bits_per_pixel == bpp))
slouken@309
   236
        {
slouken@309
   237
            return mode_list.modes[i];
slouken@309
   238
        }
slouken@309
   239
    }
slouken@0
   240
slouken@309
   241
    return (i == mode_list.num_modes) ? 0 : mode_list.modes[i];
slouken@0
   242
}
slouken@0
   243
slouken@0
   244
int get_mode_any_format(int width, int height, int bpp)
slouken@0
   245
/* return the mode associated with width, height and bpp */
slouken@0
   246
/* if requested bpp is not found the mode with closest bpp is returned */
slouken@0
   247
{
slouken@0
   248
    int i, closest, delta, min_delta;
slouken@0
   249
slouken@0
   250
	if (PgGetVideoModeList( &mode_list ) < 0)
slouken@0
   251
	{
slouken@0
   252
	    fprintf(stderr,"error: PgGetVideoModeList failed\n");
slouken@0
   253
	    return -1;
slouken@0
   254
	}
slouken@0
   255
slouken@0
   256
	qsort(mode_list.modes, mode_list.num_modes, sizeof(unsigned short), compare_modes_by_res);
slouken@0
   257
	for(i=0;i<mode_list.num_modes;i++)
slouken@0
   258
	{
slouken@0
   259
       if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
slouken@0
   260
       {
slouken@0
   261
           fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
slouken@0
   262
           return 0;
slouken@0
   263
       }
slouken@0
   264
       if ((mode_info.width == width) &&
slouken@0
   265
           (mode_info.height == height))
slouken@0
   266
           break;
slouken@0
   267
	}
slouken@0
   268
	if (i<mode_list.num_modes)
slouken@0
   269
	{
slouken@315
   270
		/* get closest bpp */
slouken@0
   271
		closest = i++;
slouken@0
   272
		if (mode_info.bits_per_pixel == bpp)
slouken@0
   273
			return mode_list.modes[ closest ];
slouken@0
   274
slouken@0
   275
		min_delta = abs(mode_info.bits_per_pixel - bpp);
slouken@0
   276
		while(1)
slouken@0
   277
		{
slouken@0
   278
			if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
slouken@0
   279
			{
slouken@0
   280
			    fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
slouken@0
   281
			    return 0;
slouken@0
   282
			}
slouken@0
   283
slouken@0
   284
			if ((mode_info.width != width) ||
slouken@0
   285
				(mode_info.height != height))
slouken@0
   286
				break;
slouken@0
   287
			else if (mode_info.bits_per_pixel == bpp)
slouken@0
   288
			{
slouken@0
   289
				closest = i;
slouken@0
   290
				break;
slouken@0
   291
			}
slouken@0
   292
			else
slouken@0
   293
			{
slouken@0
   294
				delta = abs(mode_info.bits_per_pixel - bpp);
slouken@0
   295
				if (delta < min_delta)
slouken@0
   296
				{
slouken@0
   297
					closest = i;
slouken@0
   298
					min_delta = delta;
slouken@0
   299
				}
slouken@0
   300
				i++;
slouken@0
   301
			}
slouken@0
   302
		}
slouken@0
   303
		return mode_list.modes[ closest ];
slouken@0
   304
	}
slouken@0
   305
	else
slouken@309
   306
    return 0;
slouken@0
   307
}
slouken@0
   308
slouken@0
   309
void ph_WaitMapped(_THIS);
slouken@0
   310
void ph_WaitUnmapped(_THIS);
slouken@0
   311
void ph_QueueEnterFullScreen(_THIS);
slouken@0
   312
slouken@0
   313
int ph_ToggleFullScreen(_THIS, int on)
slouken@0
   314
{
slouken@309
   315
    if (currently_fullscreen)
slouken@309
   316
    {
slouken@309
   317
        return ph_LeaveFullScreen(this);
slouken@309
   318
    }
slouken@309
   319
    else
slouken@309
   320
    {
slouken@309
   321
        return ph_EnterFullScreen(this);
slouken@309
   322
    }
slouken@0
   323
      
slouken@309
   324
    return 0;     
slouken@0
   325
}
slouken@0
   326
slouken@0
   327
int ph_EnterFullScreen(_THIS)
slouken@0
   328
{
slouken@309
   329
    if (!currently_fullscreen)
slouken@309
   330
    {
slouken@315
   331
        if (this->screen)
slouken@309
   332
        {
slouken@315
   333
            if ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL)
slouken@315
   334
            {
slouken@309
   335
#ifdef HAVE_OPENGL
slouken@309
   336
#endif /* HAVE_OPENGL */
slouken@315
   337
                return 0;
slouken@315
   338
            }
slouken@309
   339
        }
slouken@315
   340
slouken@315
   341
        if (OCImage.direct_context == NULL)
slouken@309
   342
        {
slouken@315
   343
            OCImage.direct_context=(PdDirectContext_t*)PdCreateDirectContext();
slouken@315
   344
        }
slouken@0
   345
slouken@315
   346
        if (!OCImage.direct_context)
slouken@315
   347
        {
slouken@315
   348
            fprintf(stderr, "ph_EnterFullScreen: Can't create direct context\n" );
slouken@315
   349
        }
slouken@0
   350
slouken@315
   351
        PdDirectStart(OCImage.direct_context);
slouken@0
   352
slouken@315
   353
        currently_fullscreen = 1;
slouken@309
   354
    }
slouken@0
   355
slouken@309
   356
    return 1;
slouken@0
   357
}
slouken@0
   358
slouken@315
   359
int ph_LeaveFullScreen(_THIS)
slouken@0
   360
{
slouken@309
   361
    PgDisplaySettings_t mymode_settings;
slouken@0
   362
       
slouken@309
   363
    if (currently_fullscreen)
slouken@309
   364
    {
slouken@309
   365
        if ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL)
slouken@309
   366
        {
slouken@309
   367
#ifdef HAVE_OPENGL
slouken@309
   368
#endif /* HAVE_OPENGL */
slouken@309
   369
           return 0;
slouken@309
   370
        }
slouken@309
   371
        else
slouken@309
   372
        {
slouken@309
   373
            PdDirectStop(OCImage.direct_context);
slouken@309
   374
            PdReleaseDirectContext(OCImage.direct_context);
slouken@315
   375
            
slouken@315
   376
            currently_fullscreen=0;
slouken@0
   377
slouken@309
   378
            /* Restore old video mode */
slouken@309
   379
            if (old_video_mode != -1)
slouken@309
   380
            {
slouken@309
   381
                mymode_settings.mode= (unsigned short) old_video_mode;
slouken@309
   382
                mymode_settings.refresh= (unsigned short) old_refresh_rate;
slouken@315
   383
                mymode_settings.flags= 0;
slouken@315
   384
                
slouken@309
   385
                if (PgSetVideoMode(&mymode_settings) < 0)
slouken@309
   386
                {
slouken@309
   387
                    fprintf(stderr,"error: PgSetVideoMode failed\n");
slouken@309
   388
                }
slouken@309
   389
            }
slouken@309
   390
slouken@309
   391
            old_video_mode=-1;
slouken@315
   392
            old_refresh_rate=-1;
slouken@309
   393
        }
slouken@309
   394
slouken@309
   395
    }
slouken@309
   396
    return 1;
slouken@0
   397
}