src/video/photon/SDL_ph_image.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 28 May 2002 19:31:32 +0000
changeset 380 bce7171e7a85
parent 370 ba72f259bc88
child 571 8e3ce997621c
permissions -rw-r--r--
Date: Wed, 22 May 2002 22:30:58 +0300
From: "Mike Gorchak" <mike@malva.com.ua>
Subject: One more QNX patch

Hi !

- Fixed graywin test application. Added properly support for
window size not equal to 640x480.
- Added support for not aligned pitch of image in SDL_SWSURFACE
and SDL_HWSURFACE. Using Photon builtin alignes.
- Added memory clear after each malloc to avoid problems in the
future :)
- Removed unused variables and static variables, fixed some warnings.
- Updated readme.QNX file.
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 <stdlib.h>
slouken@0
    29
#include <Ph.h>
slouken@0
    30
#include <photon/Pg.h>
slouken@0
    31
slouken@0
    32
#include "SDL_error.h"
slouken@0
    33
#include "SDL_endian.h"
slouken@0
    34
#include "SDL_ph_image_c.h"
slouken@0
    35
slouken@315
    36
/* remove this line, if photon headers updates */
slouken@315
    37
int PgWaitHWIdle(void);
slouken@315
    38
slouken@0
    39
int ph_SetupImage(_THIS, SDL_Surface *screen)
slouken@0
    40
{
slouken@380
    41
    PgColor_t* palette=NULL;
slouken@315
    42
    int type=0;
slouken@380
    43
    int bpp;
slouken@380
    44
    
slouken@380
    45
    bpp=screen->format->BitsPerPixel;
slouken@0
    46
slouken@291
    47
    /* Determine image type */
slouken@380
    48
    switch(bpp)
slouken@291
    49
    {
slouken@291
    50
        case 8:{
slouken@291
    51
            type = Pg_IMAGE_PALETTE_BYTE;
slouken@291
    52
        }
slouken@291
    53
        break;
slouken@291
    54
        case 15:{
slouken@291
    55
            type = Pg_IMAGE_DIRECT_555; 
slouken@291
    56
        }
slouken@291
    57
        break;
slouken@291
    58
        case 16:{
slouken@291
    59
            type = Pg_IMAGE_DIRECT_565; 
slouken@291
    60
        }
slouken@291
    61
        break;
slouken@291
    62
        case 24:{
slouken@291
    63
            type = Pg_IMAGE_DIRECT_888;
slouken@291
    64
        }
slouken@291
    65
        break;
slouken@291
    66
        case 32:{
slouken@291
    67
            type = Pg_IMAGE_DIRECT_8888;
slouken@291
    68
        }
slouken@291
    69
        break;
slouken@291
    70
        default:{
slouken@380
    71
            fprintf(stderr,"ph_SetupImage(): unsupported bbp = %d\n", bpp);
slouken@291
    72
            return -1;
slouken@291
    73
        }
slouken@291
    74
        break;
slouken@291
    75
    }
slouken@0
    76
slouken@315
    77
    /* palette emulation code */
slouken@380
    78
    if ((bpp==8) && (desktoppal==SDLPH_PAL_EMULATE))
slouken@291
    79
    {
slouken@315
    80
        /* creating image palette */
slouken@315
    81
        palette=malloc(_Pg_MAX_PALETTE*sizeof(PgColor_t));
slouken@315
    82
        PgGetPalette(palette);
slouken@315
    83
slouken@315
    84
        /* using shared memory for speed (set last param to 1) */
slouken@315
    85
        if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, palette, _Pg_MAX_PALETTE, 1)) == NULL)
slouken@315
    86
        {
slouken@380
    87
            fprintf(stderr,"ph_SetupImage(): PhCreateImage failed for bpp=8.\n");
slouken@315
    88
            return -1;
slouken@315
    89
        }
slouken@315
    90
    }
slouken@315
    91
    else
slouken@315
    92
    {
slouken@315
    93
        /* using shared memory for speed (set last param to 1) */
slouken@315
    94
        if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, NULL, 0, 1)) == NULL)
slouken@315
    95
        {
slouken@315
    96
            fprintf(stderr,"ph_SetupImage: PhCreateImage failed.\n");
slouken@315
    97
            return -1;
slouken@315
    98
        }
slouken@291
    99
    }
slouken@380
   100
    
slouken@291
   101
    screen->pixels = SDL_Image->image;
slouken@380
   102
    screen->pitch = SDL_Image->bpl; /* Recalculated pitch, created by PhCreateImage */
slouken@0
   103
slouken@291
   104
    this->UpdateRects = ph_NormalUpdate;
slouken@0
   105
slouken@291
   106
    return 0;
slouken@0
   107
}
slouken@0
   108
slouken@315
   109
int ph_SetupOCImage(_THIS, SDL_Surface *screen)
slouken@0
   110
{
slouken@370
   111
    int type = 0;
slouken@380
   112
    int bpp;
slouken@380
   113
    
slouken@380
   114
    bpp=screen->format->BitsPerPixel;
slouken@0
   115
slouken@370
   116
    /* Determine image type */
slouken@380
   117
    switch(bpp)
slouken@370
   118
    {
slouken@370
   119
        case 8: {
slouken@370
   120
                    type = Pg_IMAGE_PALETTE_BYTE;
slouken@370
   121
                }
slouken@370
   122
                break;
slouken@370
   123
        case 15:{
slouken@370
   124
                    type = Pg_IMAGE_DIRECT_555; 
slouken@0
   125
		}
slouken@0
   126
		break;
slouken@370
   127
        case 16:{
slouken@370
   128
                    type = Pg_IMAGE_DIRECT_565; 
slouken@370
   129
                }
slouken@370
   130
                break;
slouken@370
   131
        case 24:{
slouken@370
   132
                    type = Pg_IMAGE_DIRECT_888;
slouken@370
   133
                }
slouken@370
   134
                break;
slouken@370
   135
        case 32:{
slouken@370
   136
                    type = Pg_IMAGE_DIRECT_8888;
slouken@370
   137
                }
slouken@370
   138
                break;
slouken@370
   139
        default:{
slouken@380
   140
                    fprintf(stderr,"ph_SetupOCImage(): unsupported bpp = %d\n", bpp);
slouken@370
   141
                    return -1;
slouken@370
   142
                }
slouken@370
   143
                break;
slouken@370
   144
    }
slouken@0
   145
slouken@370
   146
    OCImage.FrameData0 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA)));
slouken@370
   147
    OCImage.FrameData1 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA)));
slouken@380
   148
    memset(OCImage.FrameData0, 0x00, (size_t)(sizeof(FRAMEDATA)));
slouken@380
   149
    memset(OCImage.FrameData1, 0x00, (size_t)(sizeof(FRAMEDATA)));
slouken@0
   150
slouken@370
   151
    if(OCImage.direct_context == NULL)
slouken@370
   152
    {
slouken@370
   153
        OCImage.direct_context = PdCreateDirectContext();
slouken@370
   154
    }
slouken@0
   155
slouken@370
   156
    OCImage.offscreen_context = PdCreateOffscreenContext(0, screen->w, screen->h, Pg_OSC_MEM_PAGE_ALIGN);
slouken@0
   157
slouken@370
   158
    if (OCImage.offscreen_context == NULL)
slouken@370
   159
    {
slouken@370
   160
        fprintf(stderr, "ph_SetupOCImage(): PdCreateOffscreenContext failed !\n");
slouken@370
   161
        return -1;
slouken@370
   162
    }
slouken@0
   163
slouken@380
   164
    screen->pitch = OCImage.offscreen_context->pitch; /* Recalculated pitch */
slouken@0
   165
slouken@370
   166
    if (OCImage.flags & SDL_DOUBLEBUF)
slouken@370
   167
    {
slouken@370
   168
        fprintf(stderr, "ph_SetupOCImage(): Hardware flag for doublebuf offscreen context\n");
slouken@370
   169
    }
slouken@0
   170
slouken@370
   171
    OCImage.dc_ptr.ptr8 = (unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context);
slouken@0
   172
slouken@370
   173
    if (OCImage.dc_ptr.ptr8 == NULL)
slouken@370
   174
    {
slouken@370
   175
        fprintf(stderr, "ph_SetupOCImage(): PdGetOffscreenContextPtr failed !\n");
slouken@370
   176
        return -1;
slouken@370
   177
    }
slouken@0
   178
slouken@370
   179
    OCImage.CurrentFrameData = OCImage.FrameData0;
slouken@370
   180
    OCImage.CurrentFrameData->Y = OCImage.dc_ptr.ptr8;
slouken@370
   181
    OCImage.CurrentFrameData->U = NULL;
slouken@370
   182
    OCImage.CurrentFrameData->V = NULL;
slouken@370
   183
    OCImage.current = 0;
slouken@370
   184
slouken@370
   185
    PhDCSetCurrent(OCImage.offscreen_context);
slouken@370
   186
slouken@370
   187
    screen->pixels = OCImage.CurrentFrameData->Y;
slouken@370
   188
slouken@370
   189
    this->UpdateRects = ph_OCUpdate;
slouken@370
   190
slouken@370
   191
    return 0;
slouken@0
   192
}
slouken@0
   193
slouken@291
   194
int ph_SetupOpenGLImage(_THIS, SDL_Surface* screen)
slouken@291
   195
{
slouken@291
   196
   this->UpdateRects = ph_OpenGLUpdate;
slouken@291
   197
   
slouken@291
   198
   return 0;
slouken@291
   199
}
slouken@0
   200
slouken@0
   201
void ph_DestroyImage(_THIS, SDL_Surface *screen)
slouken@0
   202
{
slouken@291
   203
    if (OCImage.offscreen_context != NULL)
slouken@291
   204
    {
slouken@291
   205
        PhDCRelease(OCImage.offscreen_context);
slouken@291
   206
        OCImage.offscreen_context = NULL;
slouken@291
   207
        free(OCImage.FrameData0);
slouken@291
   208
        OCImage.FrameData0 = NULL;
slouken@291
   209
        free(OCImage.FrameData1);
slouken@291
   210
        OCImage.FrameData1 = NULL;
slouken@291
   211
    }
slouken@0
   212
slouken@291
   213
    if (SDL_Image)
slouken@291
   214
    {
slouken@315
   215
        /* if palette allocated, free it */
slouken@315
   216
        if (SDL_Image->palette)
slouken@315
   217
        {
slouken@315
   218
            free(SDL_Image->palette);
slouken@315
   219
        }
slouken@291
   220
        PgShmemDestroy(SDL_Image->image);
slouken@291
   221
        free(SDL_Image);
slouken@291
   222
    }
slouken@0
   223
slouken@315
   224
    /* Must be zeroed everytime */
slouken@315
   225
    SDL_Image = NULL;
slouken@315
   226
slouken@291
   227
    if (screen)
slouken@291
   228
    {
slouken@291
   229
        screen->pixels = NULL;
slouken@291
   230
    }
slouken@0
   231
}
slouken@0
   232
slouken@0
   233
int ph_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags)
slouken@0
   234
{
slouken@0
   235
    ph_DestroyImage(this, screen);
slouken@0
   236
    
slouken@315
   237
    if (flags & SDL_HWSURFACE)
slouken@0
   238
    {
slouken@291
   239
        OCImage.flags = flags;  /* needed for SDL_DOUBLEBUF check */
slouken@291
   240
        return ph_SetupOCImage(this, screen);
slouken@0
   241
    }
slouken@315
   242
    else if (flags & SDL_OPENGL)
slouken@0
   243
    {
slouken@315
   244
        return ph_SetupOpenGLImage(this, screen);
slouken@0
   245
    } 
slouken@0
   246
    else
slouken@0
   247
    {
slouken@0
   248
        return ph_SetupImage(this, screen);
slouken@0
   249
    }      
slouken@0
   250
}
slouken@0
   251
int ph_AllocHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   252
{
slouken@315
   253
    return(-1);
slouken@0
   254
}
slouken@0
   255
slouken@0
   256
void ph_FreeHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   257
{
slouken@315
   258
    return;
slouken@0
   259
}
slouken@0
   260
slouken@0
   261
int ph_FlipHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   262
{
slouken@315
   263
    return(0);
slouken@0
   264
}
slouken@0
   265
slouken@0
   266
int ph_LockHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   267
{
slouken@315
   268
    if ((surface == SDL_VideoSurface) && blit_queued) {
slouken@315
   269
	PgFlush();
slouken@315
   270
        blit_queued = 0;
slouken@315
   271
    }
slouken@315
   272
slouken@315
   273
    return(0);
slouken@0
   274
}
slouken@0
   275
slouken@0
   276
void ph_UnlockHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   277
{
slouken@315
   278
    return;
slouken@0
   279
}
slouken@0
   280
slouken@291
   281
void ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect* rects)
slouken@291
   282
{
slouken@291
   283
   this->GL_SwapBuffers(this);
slouken@291
   284
   
slouken@291
   285
   return;
slouken@291
   286
}
slouken@291
   287
slouken@0
   288
void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
slouken@0
   289
{
slouken@380
   290
    PhPoint_t ph_pos;
slouken@380
   291
    PhRect_t ph_rect;
slouken@380
   292
    int i;
slouken@380
   293
slouken@380
   294
    for (i=0; i<numrects; ++i) 
slouken@315
   295
    {
slouken@315
   296
    	if (rects[i].w==0) /* Clipped? */
slouken@315
   297
        { 
slouken@315
   298
            continue;
slouken@0
   299
        }
slouken@0
   300
slouken@315
   301
        ph_pos.x = rects[i].x;
slouken@315
   302
        ph_pos.y = rects[i].y;
slouken@315
   303
        ph_rect.ul.x = rects[i].x;
slouken@315
   304
        ph_rect.ul.y = rects[i].y;
slouken@315
   305
        ph_rect.lr.x = rects[i].x + rects[i].w;
slouken@315
   306
        ph_rect.lr.y = rects[i].y + rects[i].h;
slouken@0
   307
slouken@315
   308
        if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0)
slouken@315
   309
        {
slouken@370
   310
            fprintf(stderr,"ph_NormalUpdate(): PgDrawPhImageRectmx failed.\n");
slouken@315
   311
        }
slouken@315
   312
    }
slouken@315
   313
slouken@0
   314
    if (PgFlush() < 0)
slouken@266
   315
    {
slouken@370
   316
    	fprintf(stderr,"ph_NormalUpdate(): PgFlush failed.\n");
slouken@0
   317
    }
slouken@0
   318
}
slouken@370
   319
slouken@0
   320
void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects)
slouken@0
   321
{
slouken@380
   322
    int i;
slouken@380
   323
slouken@315
   324
    PhPoint_t zero = {0};
slouken@370
   325
    PhArea_t src_rect;
slouken@370
   326
    PhArea_t dest_rect;
slouken@0
   327
slouken@315
   328
    if(OCImage.direct_context == NULL)
slouken@315
   329
    {
slouken@315
   330
        return;
slouken@315
   331
    }
slouken@0
   332
slouken@315
   333
    PgSetRegion(PtWidgetRid(window));
slouken@370
   334
    PgSetClipping(0, NULL);
slouken@315
   335
    PgWaitHWIdle();
slouken@315
   336
slouken@315
   337
    for (i=0; i<numrects; ++i)
slouken@315
   338
    {
slouken@315
   339
        if (rects[i].w == 0)  /* Clipped? */
slouken@315
   340
        {
slouken@315
   341
            continue;
slouken@0
   342
        }
slouken@0
   343
slouken@370
   344
        src_rect.pos.x=rects[i].x;
slouken@370
   345
        src_rect.pos.y=rects[i].y;
slouken@370
   346
        dest_rect.pos.x=rects[i].x;
slouken@370
   347
        dest_rect.pos.y=rects[i].y;
slouken@315
   348
slouken@370
   349
        src_rect.size.w=rects[i].w;
slouken@370
   350
        src_rect.size.h=rects[i].h;
slouken@370
   351
        dest_rect.size.w=rects[i].w;
slouken@370
   352
        dest_rect.size.h=rects[i].h;
slouken@315
   353
slouken@370
   354
        zero.x = 0;
slouken@370
   355
        zero.y = 0;
slouken@370
   356
        PgSetTranslation(&zero, 0);
slouken@315
   357
        PgSetRegion(PtWidgetRid(window));
slouken@370
   358
        PgSetClipping(0, NULL);
slouken@370
   359
        PgContextBlitArea(OCImage.offscreen_context, &src_rect, NULL, &dest_rect);
slouken@370
   360
    }
slouken@315
   361
slouken@0
   362
    if (PgFlush() < 0)
slouken@266
   363
    {
slouken@370
   364
        fprintf(stderr,"ph_OCUpdate(): PgFlush failed.\n");
slouken@0
   365
    }
slouken@0
   366
    
slouken@315
   367
    /* later used to toggling double buffer */
slouken@315
   368
    if (OCImage.current == 0)
slouken@315
   369
    {
slouken@315
   370
        OCImage.CurrentFrameData = OCImage.FrameData0;
slouken@315
   371
    }
slouken@315
   372
    else
slouken@315
   373
    {
slouken@315
   374
        OCImage.CurrentFrameData = OCImage.FrameData1;
slouken@315
   375
    }
slouken@0
   376
}