Home | History | Annotate | Download | only in photon
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2012 Sam Lantinga
      4 
      5     This library is free software; you can redistribute it and/or
      6     modify it under the terms of the GNU Lesser General Public
      7     License as published by the Free Software Foundation; either
      8     version 2.1 of the License, or (at your option) any later version.
      9 
     10     This library is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13     Lesser General Public License for more details.
     14 
     15     You should have received a copy of the GNU Lesser General Public
     16     License along with this library; if not, write to the Free Software
     17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     18 
     19     Sam Lantinga
     20     slouken (at) libsdl.org
     21 */
     22 #include "SDL_config.h"
     23 
     24 #include <Ph.h>
     25 #include <photon/Pg.h>
     26 
     27 #include "SDL_endian.h"
     28 #include "SDL_video.h"
     29 #include "../SDL_pixels_c.h"
     30 #include "SDL_ph_video.h"
     31 #include "SDL_ph_image_c.h"
     32 #include "SDL_ph_modes_c.h"
     33 #include "SDL_ph_gl.h"
     34 
     35 int ph_SetupImage(_THIS, SDL_Surface *screen)
     36 {
     37     PgColor_t* palette=NULL;
     38     int type=0;
     39     int bpp;
     40 
     41     bpp=screen->format->BitsPerPixel;
     42 
     43     /* Determine image type */
     44     switch(bpp)
     45     {
     46         case 8:{
     47             type = Pg_IMAGE_PALETTE_BYTE;
     48         }
     49         break;
     50         case 15:{
     51             type = Pg_IMAGE_DIRECT_555;
     52         }
     53         break;
     54         case 16:{
     55             type = Pg_IMAGE_DIRECT_565;
     56         }
     57         break;
     58         case 24:{
     59             type = Pg_IMAGE_DIRECT_888;
     60         }
     61         break;
     62         case 32:{
     63             type = Pg_IMAGE_DIRECT_8888;
     64         }
     65         break;
     66         default:{
     67             SDL_SetError("ph_SetupImage(): unsupported bpp=%d !\n", bpp);
     68             return -1;
     69         }
     70         break;
     71     }
     72 
     73     /* palette emulation code */
     74     if ((bpp==8) && (desktoppal==SDLPH_PAL_EMULATE))
     75     {
     76         /* creating image palette */
     77         palette=SDL_malloc(_Pg_MAX_PALETTE*sizeof(PgColor_t));
     78         if (palette==NULL)
     79         {
     80             SDL_SetError("ph_SetupImage(): can't allocate memory for palette !\n");
     81             return -1;
     82         }
     83         PgGetPalette(palette);
     84 
     85         /* using shared memory for speed (set last param to 1) */
     86         if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, palette, _Pg_MAX_PALETTE, 1)) == NULL)
     87         {
     88             SDL_SetError("ph_SetupImage(): PhCreateImage() failed for bpp=8 !\n");
     89             SDL_free(palette);
     90             return -1;
     91         }
     92     }
     93     else
     94     {
     95         /* using shared memory for speed (set last param to 1) */
     96         if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, NULL, 0, 1)) == NULL)
     97         {
     98             SDL_SetError("ph_SetupImage(): PhCreateImage() failed for bpp=%d !\n", bpp);
     99             return -1;
    100         }
    101     }
    102 
    103     screen->pixels = SDL_Image->image;
    104     screen->pitch = SDL_Image->bpl;
    105 
    106     this->UpdateRects = ph_NormalUpdate;
    107 
    108     return 0;
    109 }
    110 
    111 int ph_SetupOCImage(_THIS, SDL_Surface *screen)
    112 {
    113     int type = 0;
    114     int bpp;
    115 
    116     OCImage.flags = screen->flags;
    117 
    118     bpp=screen->format->BitsPerPixel;
    119 
    120     /* Determine image type */
    121     switch(bpp)
    122     {
    123         case 8: {
    124                     type = Pg_IMAGE_PALETTE_BYTE;
    125                 }
    126                 break;
    127         case 15:{
    128                     type = Pg_IMAGE_DIRECT_555;
    129 		}
    130 		break;
    131         case 16:{
    132                     type = Pg_IMAGE_DIRECT_565;
    133                 }
    134                 break;
    135         case 24:{
    136                     type = Pg_IMAGE_DIRECT_888;
    137                 }
    138                 break;
    139         case 32:{
    140                     type = Pg_IMAGE_DIRECT_8888;
    141                 }
    142                 break;
    143         default:{
    144                     SDL_SetError("ph_SetupOCImage(): unsupported bpp=%d !\n", bpp);
    145                     return -1;
    146                 }
    147                 break;
    148     }
    149 
    150     /* Currently offscreen contexts with the same bit depth as display bpp only can be created */
    151     OCImage.offscreen_context = PdCreateOffscreenContext(0, screen->w, screen->h, Pg_OSC_MEM_PAGE_ALIGN);
    152 
    153     if (OCImage.offscreen_context == NULL)
    154     {
    155         SDL_SetError("ph_SetupOCImage(): PdCreateOffscreenContext() function failed !\n");
    156         return -1;
    157     }
    158 
    159     screen->pitch = OCImage.offscreen_context->pitch;
    160 
    161     OCImage.dc_ptr = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context);
    162 
    163     if (OCImage.dc_ptr == NULL)
    164     {
    165         SDL_SetError("ph_SetupOCImage(): PdGetOffscreenContextPtr function failed !\n");
    166         PhDCRelease(OCImage.offscreen_context);
    167         return -1;
    168     }
    169 
    170     OCImage.FrameData0 = OCImage.dc_ptr;
    171     OCImage.CurrentFrameData = OCImage.FrameData0;
    172     OCImage.current = 0;
    173 
    174     PhDCSetCurrent(OCImage.offscreen_context);
    175 
    176     screen->pixels = OCImage.CurrentFrameData;
    177 
    178     this->UpdateRects = ph_OCUpdate;
    179 
    180     return 0;
    181 }
    182 
    183 int ph_SetupFullScreenImage(_THIS, SDL_Surface* screen)
    184 {
    185     OCImage.flags = screen->flags;
    186 
    187     /* Begin direct and fullscreen mode */
    188     if (!ph_EnterFullScreen(this, screen, PH_ENTER_DIRECTMODE))
    189     {
    190         return -1;
    191     }
    192 
    193     /* store palette for fullscreen */
    194     if ((screen->format->BitsPerPixel==8) && (desktopbpp!=8))
    195     {
    196         PgGetPalette(savedpal);
    197         PgGetPalette(syspalph);
    198     }
    199 
    200     OCImage.offscreen_context = PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY | Pg_OSC_MEM_PAGE_ALIGN | Pg_OSC_CRTC_SAFE);
    201     if (OCImage.offscreen_context == NULL)
    202     {
    203         SDL_SetError("ph_SetupFullScreenImage(): PdCreateOffscreenContext() function failed !\n");
    204         return -1;
    205     }
    206 
    207     if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
    208     {
    209         OCImage.offscreen_backcontext = PdDupOffscreenContext(OCImage.offscreen_context, Pg_OSC_MEM_PAGE_ALIGN | Pg_OSC_CRTC_SAFE);
    210         if (OCImage.offscreen_backcontext == NULL)
    211         {
    212             SDL_SetError("ph_SetupFullScreenImage(): PdCreateOffscreenContext(back) function failed !\n");
    213             return -1;
    214         }
    215     }
    216 
    217     OCImage.FrameData0 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context);
    218     if (OCImage.FrameData0 == NULL)
    219     {
    220         SDL_SetError("ph_SetupFullScreenImage(): PdGetOffscreenContextPtr() function failed !\n");
    221         ph_DestroyImage(this, screen);
    222         return -1;
    223     }
    224 
    225     if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
    226     {
    227         OCImage.FrameData1 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_backcontext);
    228         if (OCImage.FrameData1 == NULL)
    229         {
    230             SDL_SetError("ph_SetupFullScreenImage(back): PdGetOffscreenContextPtr() function failed !\n");
    231             ph_DestroyImage(this, screen);
    232             return -1;
    233         }
    234     }
    235 
    236     /* wait for the hardware */
    237     PgFlush();
    238     PgWaitHWIdle();
    239 
    240     if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
    241     {
    242         OCImage.current = 0;
    243         PhDCSetCurrent(OCImage.offscreen_context);
    244         screen->pitch = OCImage.offscreen_context->pitch;
    245         screen->pixels = OCImage.FrameData0;
    246 
    247         /* emulate 640x400 videomode */
    248         if (videomode_emulatemode==1)
    249         {
    250            int i;
    251 
    252            for (i=0; i<40; i++)
    253            {
    254               SDL_memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch);
    255            }
    256            for (i=440; i<480; i++)
    257            {
    258               SDL_memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch);
    259            }
    260            screen->pixels+=screen->pitch*40;
    261         }
    262         PgSwapDisplay(OCImage.offscreen_backcontext, 0);
    263     }
    264     else
    265     {
    266         OCImage.current = 0;
    267         PhDCSetCurrent(OCImage.offscreen_context);
    268         screen->pitch = OCImage.offscreen_context->pitch;
    269         screen->pixels = OCImage.FrameData0;
    270 
    271         /* emulate 640x400 videomode */
    272         if (videomode_emulatemode==1)
    273         {
    274            int i;
    275 
    276            for (i=0; i<40; i++)
    277            {
    278               SDL_memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch);
    279            }
    280            for (i=440; i<480; i++)
    281            {
    282               SDL_memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch);
    283            }
    284            screen->pixels+=screen->pitch*40;
    285         }
    286     }
    287 
    288     this->UpdateRects = ph_OCDCUpdate;
    289 
    290     /* wait for the hardware */
    291     PgFlush();
    292     PgWaitHWIdle();
    293 
    294     return 0;
    295 }
    296 
    297 #if SDL_VIDEO_OPENGL
    298 
    299 int ph_SetupOpenGLImage(_THIS, SDL_Surface* screen)
    300 {
    301     this->UpdateRects = ph_OpenGLUpdate;
    302     screen->pixels=NULL;
    303     screen->pitch=NULL;
    304 
    305     #if (_NTO_VERSION >= 630)
    306         if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
    307         {
    308             if (!ph_EnterFullScreen(this, screen, PH_IGNORE_DIRECTMODE))
    309             {
    310                 screen->flags &= ~SDL_FULLSCREEN;
    311                 return -1;
    312             }
    313         }
    314     #endif /* 6.3.0 */
    315 
    316     if (ph_SetupOpenGLContext(this, screen->w, screen->h, screen->format->BitsPerPixel, screen->flags)!=0)
    317     {
    318         screen->flags &= ~SDL_OPENGL;
    319         return -1;
    320     }
    321 
    322     return 0;
    323 }
    324 
    325 #endif /* SDL_VIDEO_OPENGL */
    326 
    327 void ph_DestroyImage(_THIS, SDL_Surface* screen)
    328 {
    329 
    330 #if SDL_VIDEO_OPENGL
    331     if ((screen->flags & SDL_OPENGL)==SDL_OPENGL)
    332     {
    333         if (oglctx)
    334         {
    335             #if (_NTO_VERSION < 630)
    336                 PhDCSetCurrent(NULL);
    337                 PhDCRelease(oglctx);
    338             #else
    339                 qnxgl_context_destroy(oglctx);
    340                 qnxgl_buffers_destroy(oglbuffers);
    341                 qnxgl_finish();
    342             #endif /* 6.3.0 */
    343             oglctx=NULL;
    344             oglbuffers=NULL;
    345             oglflags=0;
    346             oglbpp=0;
    347         }
    348 
    349         #if (_NTO_VERSION >= 630)
    350             if (currently_fullscreen)
    351             {
    352                 ph_LeaveFullScreen(this);
    353             }
    354         #endif /* 6.3.0 */
    355 
    356         return;
    357     }
    358 #endif /* SDL_VIDEO_OPENGL */
    359 
    360     if (currently_fullscreen)
    361     {
    362         /* if we right now in 8bpp fullscreen we must release palette */
    363         if ((screen->format->BitsPerPixel==8) && (desktopbpp!=8))
    364         {
    365             PgSetPalette(syspalph, 0, -1, 0, 0, 0);
    366             PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0);
    367             PgFlush();
    368         }
    369         ph_LeaveFullScreen(this);
    370     }
    371 
    372     if (OCImage.offscreen_context != NULL)
    373     {
    374         PhDCRelease(OCImage.offscreen_context);
    375         OCImage.offscreen_context = NULL;
    376         OCImage.FrameData0 = NULL;
    377     }
    378     if (OCImage.offscreen_backcontext != NULL)
    379     {
    380         PhDCRelease(OCImage.offscreen_backcontext);
    381         OCImage.offscreen_backcontext = NULL;
    382         OCImage.FrameData1 = NULL;
    383     }
    384     OCImage.CurrentFrameData = NULL;
    385 
    386     if (SDL_Image)
    387     {
    388         /* if palette allocated, free it */
    389         if (SDL_Image->palette)
    390         {
    391             SDL_free(SDL_Image->palette);
    392         }
    393         PgShmemDestroy(SDL_Image->image);
    394         SDL_free(SDL_Image);
    395     }
    396 
    397     /* Must be zeroed everytime */
    398     SDL_Image = NULL;
    399 
    400     if (screen)
    401     {
    402         screen->pixels = NULL;
    403     }
    404 }
    405 
    406 int ph_UpdateHWInfo(_THIS)
    407 {
    408     PgVideoModeInfo_t vmode;
    409     PgHWCaps_t hwcaps;
    410 
    411     /* Update video ram amount */
    412     if (PgGetGraphicsHWCaps(&hwcaps) < 0)
    413     {
    414         SDL_SetError("ph_UpdateHWInfo(): GetGraphicsHWCaps() function failed !\n");
    415         return -1;
    416     }
    417     this->info.video_mem=hwcaps.currently_available_video_ram/1024;
    418 
    419     /* obtain current mode capabilities */
    420     if (PgGetVideoModeInfo(hwcaps.current_video_mode, &vmode) < 0)
    421     {
    422         SDL_SetError("ph_UpdateHWInfo(): GetVideoModeInfo() function failed !\n");
    423         return -1;
    424     }
    425 
    426     if ((vmode.mode_capabilities1 & PgVM_MODE_CAP1_OFFSCREEN) == PgVM_MODE_CAP1_OFFSCREEN)
    427     {
    428         /* this is a special test for drivers which tries to lie about offscreen capability */
    429         if (hwcaps.currently_available_video_ram!=0)
    430         {
    431            this->info.hw_available = 1;
    432         }
    433         else
    434         {
    435            this->info.hw_available = 0;
    436         }
    437     }
    438     else
    439     {
    440         this->info.hw_available = 0;
    441     }
    442 
    443     if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_RECTANGLE) == PgVM_MODE_CAP2_RECTANGLE)
    444     {
    445         this->info.blit_fill = 1;
    446     }
    447     else
    448     {
    449         this->info.blit_fill = 0;
    450     }
    451 
    452     if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_BITBLT) == PgVM_MODE_CAP2_BITBLT)
    453     {
    454         this->info.blit_hw = 1;
    455     }
    456     else
    457     {
    458         this->info.blit_hw = 0;
    459     }
    460 
    461     if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_ALPHA_BLEND) == PgVM_MODE_CAP2_ALPHA_BLEND)
    462     {
    463         this->info.blit_hw_A = 1;
    464     }
    465     else
    466     {
    467         this->info.blit_hw_A = 0;
    468     }
    469 
    470     if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_CHROMA) == PgVM_MODE_CAP2_CHROMA)
    471     {
    472         this->info.blit_hw_CC = 1;
    473     }
    474     else
    475     {
    476         this->info.blit_hw_CC = 0;
    477     }
    478 
    479     return 0;
    480 }
    481 
    482 int ph_SetupUpdateFunction(_THIS, SDL_Surface* screen, Uint32 flags)
    483 {
    484     int setupresult=-1;
    485 
    486     ph_DestroyImage(this, screen);
    487 
    488 #if SDL_VIDEO_OPENGL
    489     if ((flags & SDL_OPENGL)==SDL_OPENGL)
    490     {
    491         setupresult=ph_SetupOpenGLImage(this, screen);
    492     }
    493     else
    494     {
    495 #endif
    496        if ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN)
    497        {
    498            setupresult=ph_SetupFullScreenImage(this, screen);
    499        }
    500        else
    501        {
    502           if ((flags & SDL_HWSURFACE)==SDL_HWSURFACE)
    503           {
    504               setupresult=ph_SetupOCImage(this, screen);
    505           }
    506           else
    507           {
    508               setupresult=ph_SetupImage(this, screen);
    509           }
    510        }
    511 #if SDL_VIDEO_OPENGL
    512     }
    513 #endif
    514     if (setupresult!=-1)
    515     {
    516        ph_UpdateHWInfo(this);
    517     }
    518 
    519     return setupresult;
    520 }
    521 
    522 int ph_AllocHWSurface(_THIS, SDL_Surface* surface)
    523 {
    524     PgHWCaps_t hwcaps;
    525 
    526     if (surface->hwdata!=NULL)
    527     {
    528        SDL_SetError("ph_AllocHWSurface(): hwdata already exists!\n");
    529        return -1;
    530     }
    531     surface->hwdata=SDL_malloc(sizeof(struct private_hwdata));
    532     SDL_memset(surface->hwdata, 0x00, sizeof(struct private_hwdata));
    533     surface->hwdata->offscreenctx=PdCreateOffscreenContext(0, surface->w, surface->h, Pg_OSC_MEM_PAGE_ALIGN);
    534     if (surface->hwdata->offscreenctx == NULL)
    535     {
    536         SDL_SetError("ph_AllocHWSurface(): PdCreateOffscreenContext() function failed !\n");
    537         return -1;
    538     }
    539     surface->pixels=PdGetOffscreenContextPtr(surface->hwdata->offscreenctx);
    540     if (surface->pixels==NULL)
    541     {
    542         PhDCRelease(surface->hwdata->offscreenctx);
    543         SDL_SetError("ph_AllocHWSurface(): PdGetOffscreenContextPtr() function failed !\n");
    544         return -1;
    545     }
    546     surface->pitch=surface->hwdata->offscreenctx->pitch;
    547     surface->flags|=SDL_HWSURFACE;
    548     surface->flags|=SDL_PREALLOC;
    549 
    550 #if 0 /* FIXME */
    551     /* create simple offscreen lock */
    552     surface->hwdata->crlockparam.flags=0;
    553     if (PdCreateOffscreenLock(surface->hwdata->offscreenctx, &surface->hwdata->crlockparam)!=EOK)
    554     {
    555         PhDCRelease(surface->hwdata->offscreenctx);
    556         SDL_SetError("ph_AllocHWSurface(): Can't create offscreen lock !\n");
    557         return -1;
    558     }
    559 #endif /* 0 */
    560 
    561     /* Update video ram amount */
    562     if (PgGetGraphicsHWCaps(&hwcaps) < 0)
    563     {
    564         PdDestroyOffscreenLock(surface->hwdata->offscreenctx);
    565         PhDCRelease(surface->hwdata->offscreenctx);
    566         SDL_SetError("ph_AllocHWSurface(): GetGraphicsHWCaps() function failed !\n");
    567         return -1;
    568     }
    569     this->info.video_mem=hwcaps.currently_available_video_ram/1024;
    570 
    571     return 0;
    572 }
    573 
    574 void ph_FreeHWSurface(_THIS, SDL_Surface* surface)
    575 {
    576     PgHWCaps_t hwcaps;
    577 
    578     if (surface->hwdata==NULL)
    579     {
    580        SDL_SetError("ph_FreeHWSurface(): no hwdata!\n");
    581        return;
    582     }
    583     if (surface->hwdata->offscreenctx == NULL)
    584     {
    585        SDL_SetError("ph_FreeHWSurface(): no offscreen context to delete!\n");
    586        return;
    587     }
    588 
    589 #if 0 /* FIXME */
    590     /* unlock the offscreen context if it has been locked before destroy it */
    591     if (PdIsOffscreenLocked(surface->hwdata->offscreenctx)==Pg_OSC_LOCKED)
    592     {
    593        PdUnlockOffscreen(surface->hwdata->offscreenctx);
    594     }
    595 
    596     PdDestroyOffscreenLock(surface->hwdata->offscreenctx);
    597 #endif /* 0 */
    598 
    599     PhDCRelease(surface->hwdata->offscreenctx);
    600 
    601     SDL_free(surface->hwdata);
    602     surface->hwdata=NULL;
    603 
    604     /* Update video ram amount */
    605     if (PgGetGraphicsHWCaps(&hwcaps) < 0)
    606     {
    607         SDL_SetError("ph_FreeHWSurface(): GetGraphicsHWCaps() function failed !\n");
    608         return;
    609     }
    610     this->info.video_mem=hwcaps.currently_available_video_ram/1024;
    611 
    612     return;
    613 }
    614 
    615 int ph_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
    616 {
    617    if ((src->hwdata==NULL) && (src != this->screen))
    618    {
    619       SDL_SetError("ph_CheckHWBlit(): Source surface haven't hardware specific data.\n");
    620       src->flags&=~SDL_HWACCEL;
    621       return -1;
    622    }
    623    if ((src->flags & SDL_HWSURFACE) != SDL_HWSURFACE)
    624    {
    625       SDL_SetError("ph_CheckHWBlit(): Source surface isn't a hardware surface.\n");
    626       src->flags&=~SDL_HWACCEL;
    627       return -1;
    628    }
    629 
    630    if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY)
    631    {
    632        if (this->info.blit_hw_CC!=1)
    633        {
    634            src->flags&=~SDL_HWACCEL;
    635            src->map->hw_blit=NULL;
    636            return -1;
    637        }
    638    }
    639 
    640    if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA)
    641    {
    642        if (this->info.blit_hw_A!=1)
    643        {
    644            src->flags&=~SDL_HWACCEL;
    645            src->map->hw_blit=NULL;
    646            return -1;
    647        }
    648    }
    649 
    650    src->flags|=SDL_HWACCEL;
    651    src->map->hw_blit = ph_HWAccelBlit;
    652 
    653    return 1;
    654 }
    655 
    656 PgColor_t ph_ExpandColor(_THIS, SDL_Surface* surface, Uint32 color)
    657 {
    658     Uint32 truecolor;
    659 
    660     /* Photon API accepts true colors only during hw filling operations */
    661     switch(surface->format->BitsPerPixel)
    662     {
    663        case 8:
    664             {
    665                 if ((surface->format->palette) && (color<=surface->format->palette->ncolors))
    666                 {
    667                     truecolor=PgRGB(surface->format->palette->colors[color].r,
    668                                     surface->format->palette->colors[color].g,
    669                                     surface->format->palette->colors[color].b);
    670                 }
    671                 else
    672                 {
    673                     SDL_SetError("ph_ExpandColor(): Color out of range for the 8bpp mode !\n");
    674                     return 0xFFFFFFFFUL;
    675                 }
    676             }
    677             break;
    678        case 15:
    679             {
    680                 truecolor = ((color & 0x00007C00UL) << 9) |   /* R */
    681                             ((color & 0x000003E0UL) << 6) |   /* G */
    682                             ((color & 0x0000001FUL) << 3) |   /* B */
    683                             ((color & 0x00007000UL) << 4) |   /* R compensation */
    684                             ((color & 0x00000380UL) << 1) |   /* G compensation */
    685                             ((color & 0x0000001CUL) >> 2);    /* B compensation */
    686             }
    687             break;
    688        case 16:
    689             {
    690                 truecolor = ((color & 0x0000F800UL) << 8) |   /* R */
    691                             ((color & 0x000007E0UL) << 5) |   /* G */
    692                             ((color & 0x0000001FUL) << 3) |   /* B */
    693                             ((color & 0x0000E000UL) << 3) |   /* R compensation */
    694                             ((color & 0x00000600UL) >> 1) |   /* G compensation */
    695                             ((color & 0x0000001CUL) >> 2);    /* B compensation */
    696 
    697             }
    698             break;
    699        case 24:
    700             {
    701                 truecolor=color & 0x00FFFFFFUL;
    702             }
    703             break;
    704        case 32:
    705             {
    706                 truecolor=color;
    707             }
    708             break;
    709        default:
    710             {
    711                 SDL_SetError("ph_ExpandColor(): Unsupported depth for the hardware operations !\n");
    712                 return 0xFFFFFFFFUL;
    713             }
    714     }
    715 
    716     return truecolor;
    717 }
    718 
    719 int ph_FillHWRect(_THIS, SDL_Surface* surface, SDL_Rect* rect, Uint32 color)
    720 {
    721     PgColor_t oldcolor;
    722     Uint32 truecolor;
    723     int ydisp=0;
    724 
    725     if (this->info.blit_fill!=1)
    726     {
    727        return -1;
    728     }
    729 
    730     truecolor=ph_ExpandColor(this, surface, color);
    731     if (truecolor==0xFFFFFFFFUL)
    732     {
    733         return -1;
    734     }
    735 
    736     oldcolor=PgSetFillColor(truecolor);
    737 
    738     /* 640x400 videomode emulation */
    739     if (videomode_emulatemode==1)
    740     {
    741         ydisp+=40;
    742     }
    743 
    744     PgDrawIRect(rect->x, rect->y+ydisp, rect->w+rect->x-1, rect->h+rect->y+ydisp-1, Pg_DRAW_FILL);
    745     PgSetFillColor(oldcolor);
    746     PgFlush();
    747     PgWaitHWIdle();
    748 
    749     return 0;
    750 }
    751 
    752 int ph_FlipHWSurface(_THIS, SDL_Surface* screen)
    753 {
    754     PhArea_t farea;
    755 
    756     if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
    757     {
    758         /* flush all drawing ops before blitting */
    759         PgFlush();
    760         PgWaitHWIdle();
    761 
    762         farea.pos.x=0;
    763         farea.pos.y=0;
    764         farea.size.w=screen->w;
    765         farea.size.h=screen->h;
    766 
    767         /* emulate 640x400 videomode */
    768         if (videomode_emulatemode==1)
    769         {
    770             farea.pos.y+=40;
    771         }
    772 
    773         PgContextBlitArea(OCImage.offscreen_context, &farea, OCImage.offscreen_backcontext, &farea);
    774 
    775         /* flush the blitting */
    776         PgFlush();
    777         PgWaitHWIdle();
    778     }
    779     return 0;
    780 }
    781 
    782 int ph_LockHWSurface(_THIS, SDL_Surface* surface)
    783 {
    784 
    785 #if 0 /* FIXME */
    786     int lockresult;
    787 
    788     if (surface->hwdata == NULL)
    789     {
    790         return;
    791     }
    792 
    793     surface->hwdata->lockparam.flags=0;
    794     surface->hwdata->lockparam.time_out=NULL;
    795     lockresult=PdLockOffscreen(surface->hwdata->offscreenctx, &surface->hwdata->lockparam);
    796 
    797     switch (lockresult)
    798     {
    799        case EOK:
    800                  break;
    801        case Pg_OSC_LOCK_DEADLOCK:
    802                  SDL_SetError("ph_LockHWSurface(): Deadlock detected !\n");
    803                  return -1;
    804        case Pg_OSC_LOCK_INVALID:
    805                  SDL_SetError("ph_LockHWSurface(): Lock invalid !\n");
    806                  return -1;
    807        default:
    808                  SDL_SetError("ph_LockHWSurface(): Can't lock the surface !\n");
    809                  return -1;
    810     }
    811 #endif /* 0 */
    812 
    813     return 0;
    814 }
    815 
    816 void ph_UnlockHWSurface(_THIS, SDL_Surface* surface)
    817 {
    818 
    819 #if 0 /* FIXME */
    820     int unlockresult;
    821 
    822     if ((surface == NULL) || (surface->hwdata == NULL))
    823     {
    824         return;
    825     }
    826 
    827     if (PdIsOffscreenLocked(surface->hwdata->offscreenctx)==Pg_OSC_LOCKED)
    828     {
    829         unlockresult=PdUnlockOffscreen(surface->hwdata->offscreenctx);
    830     }
    831 #endif /* 0 */
    832 
    833     return;
    834 }
    835 
    836 int ph_HWAccelBlit(SDL_Surface* src, SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect)
    837 {
    838     SDL_VideoDevice* this=current_video;
    839     PhArea_t srcarea;
    840     PhArea_t dstarea;
    841     int ydisp=0;
    842 
    843     /* 640x400 videomode emulation */
    844     if (videomode_emulatemode==1)
    845     {
    846        ydisp+=40;
    847     }
    848 
    849     srcarea.pos.x=srcrect->x;
    850     srcarea.pos.y=srcrect->y;
    851     srcarea.size.w=srcrect->w;
    852     srcarea.size.h=srcrect->h;
    853 
    854     dstarea.pos.x=dstrect->x;
    855     dstarea.pos.y=dstrect->y;
    856     dstarea.size.w=dstrect->w;
    857     dstarea.size.h=dstrect->h;
    858 
    859     if (((src == this->screen) || (src->hwdata!=NULL)) && ((dst == this->screen) || (dst->hwdata!=NULL)))
    860     {
    861         if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY)
    862         {
    863             ph_SetHWColorKey(this, src, src->format->colorkey);
    864             PgChromaOn();
    865         }
    866 
    867         if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA)
    868         {
    869             ph_SetHWAlpha(this, src, src->format->alpha);
    870             PgAlphaOn();
    871         }
    872 
    873         if (dst == this->screen)
    874         {
    875             if (src == this->screen)
    876             {
    877                 /* blitting from main screen to main screen */
    878                 dstarea.pos.y+=ydisp;
    879                 srcarea.pos.y+=ydisp;
    880                 PgContextBlitArea(OCImage.offscreen_context, &srcarea, OCImage.offscreen_context, &dstarea);
    881             }
    882             else
    883             {
    884                 /* blitting from offscreen to main screen */
    885                 dstarea.pos.y+=ydisp;
    886                 PgContextBlitArea(src->hwdata->offscreenctx, &srcarea, OCImage.offscreen_context, &dstarea);
    887             }
    888         }
    889         else
    890         {
    891             if (src == this->screen)
    892             {
    893                 /* blitting from main screen to offscreen */
    894                 srcarea.pos.y+=ydisp;
    895                 PgContextBlitArea(OCImage.offscreen_context, &srcarea, dst->hwdata->offscreenctx, &dstarea);
    896             }
    897             else
    898             {
    899                 /* blitting offscreen to offscreen */
    900                 PgContextBlitArea(src->hwdata->offscreenctx, &srcarea, dst->hwdata->offscreenctx, &dstarea);
    901             }
    902         }
    903 
    904         if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA)
    905         {
    906             PgAlphaOff();
    907         }
    908 
    909         if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY)
    910         {
    911             PgChromaOff();
    912         }
    913     }
    914     else
    915     {
    916         SDL_SetError("ph_HWAccelBlit(): Source or target surface is not a hardware surface !\n");
    917         return -1;
    918     }
    919 
    920     PgFlush();
    921     PgWaitHWIdle();
    922 
    923     return 0;
    924 }
    925 
    926 int ph_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
    927 {
    928     if (this->info.blit_hw_CC!=1)
    929     {
    930        return -1;
    931     }
    932 
    933     if (surface->hwdata!=NULL)
    934     {
    935         surface->hwdata->colorkey=ph_ExpandColor(this, surface, key);
    936         if (surface->hwdata->colorkey==0xFFFFFFFFUL)
    937         {
    938             return -1;
    939         }
    940     }
    941     PgSetChroma(surface->hwdata->colorkey, Pg_CHROMA_SRC_MATCH | Pg_CHROMA_NODRAW);
    942 
    943     return 0;
    944 }
    945 
    946 int ph_SetHWAlpha(_THIS, SDL_Surface* surface, Uint8 alpha)
    947 {
    948     if (this->info.blit_hw_A!=1)
    949     {
    950        return -1;
    951     }
    952 
    953     PgSetAlphaBlend(NULL, alpha);
    954 
    955     return 0;
    956 }
    957 
    958 #if SDL_VIDEO_OPENGL
    959 void ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect* rects)
    960 {
    961    this->GL_SwapBuffers(this);
    962 
    963    return;
    964 }
    965 #endif /* SDL_VIDEO_OPENGL */
    966 
    967 void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
    968 {
    969     PhPoint_t ph_pos;
    970     PhRect_t ph_rect;
    971     int i;
    972 
    973     for (i=0; i<numrects; ++i)
    974     {
    975     	if (rects[i].w==0) /* Clipped? dunno why but this occurs sometime. */
    976         {
    977             continue;
    978         }
    979 
    980     	if (rects[i].h==0) /* Clipped? dunno why but this occurs sometime. */
    981         {
    982             continue;
    983         }
    984 
    985         ph_pos.x = rects[i].x;
    986         ph_pos.y = rects[i].y;
    987         ph_rect.ul.x = rects[i].x;
    988         ph_rect.ul.y = rects[i].y;
    989         ph_rect.lr.x = rects[i].x + rects[i].w;
    990         ph_rect.lr.y = rects[i].y + rects[i].h;
    991 
    992         if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0)
    993         {
    994             SDL_SetError("ph_NormalUpdate(): PgDrawPhImageRectmx failed!\n");
    995             return;
    996         }
    997     }
    998 
    999     if (PgFlush() < 0)
   1000     {
   1001     	SDL_SetError("ph_NormalUpdate(): PgFlush() function failed!\n");
   1002     }
   1003 }
   1004 
   1005 void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects)
   1006 {
   1007     int i;
   1008 
   1009     PhPoint_t zero = {0, 0};
   1010     PhArea_t src_rect;
   1011     PhArea_t dest_rect;
   1012 
   1013     PgSetTranslation(&zero, 0);
   1014     PgSetRegion(PtWidgetRid(window));
   1015     PgSetClipping(0, NULL);
   1016 
   1017     PgFlush();
   1018     PgWaitHWIdle();
   1019 
   1020     for (i=0; i<numrects; ++i)
   1021     {
   1022         if (rects[i].w == 0)  /* Clipped? */
   1023         {
   1024             continue;
   1025         }
   1026 
   1027         if (rects[i].h == 0)  /* Clipped? */
   1028         {
   1029             continue;
   1030         }
   1031 
   1032         src_rect.pos.x=rects[i].x;
   1033         src_rect.pos.y=rects[i].y;
   1034         dest_rect.pos.x=rects[i].x;
   1035         dest_rect.pos.y=rects[i].y;
   1036 
   1037         src_rect.size.w=rects[i].w;
   1038         src_rect.size.h=rects[i].h;
   1039         dest_rect.size.w=rects[i].w;
   1040         dest_rect.size.h=rects[i].h;
   1041 
   1042         PgContextBlitArea(OCImage.offscreen_context, &src_rect, NULL, &dest_rect);
   1043     }
   1044 
   1045     if (PgFlush() < 0)
   1046     {
   1047         SDL_SetError("ph_OCUpdate(): PgFlush failed.\n");
   1048     }
   1049 }
   1050 
   1051 void ph_OCDCUpdate(_THIS, int numrects, SDL_Rect *rects)
   1052 {
   1053     PgWaitHWIdle();
   1054 
   1055     if (PgFlush() < 0)
   1056     {
   1057         SDL_SetError("ph_OCDCUpdate(): PgFlush failed.\n");
   1058     }
   1059 }
   1060